Giter Club home page Giter Club logo

maxnowack / signaldb Goto Github PK

View Code? Open in Web Editor NEW
226.0 5.0 6.0 3.74 MB

SignalDB is a local JavaScript database with a MongoDB-like interface and TypeScript support, enabling optimistic UI with signal-based reactivity across multiple frameworks. It integrates easily with libraries like Angular, Solid.js, Preact, and Vue, simplifying data management with schema-less design, in-memory storage, and fast queries.

Home Page: https://signaldb.js.org/

License: MIT License

JavaScript 2.18% TypeScript 97.82%
client client-database database local-database meteor minimongo mongodb offline-first reactive reactive-programming

signaldb's Introduction

JavaScript Database

Current Version Status Checks TypeScript Coverage License Stargazers npm

SignalDB: Client-Side JavaScript Database with TypeScript Support and Reactive Interfaces

SignalDB is a client-side database optimized for modern web applications, offering a MongoDB-like interface with robust TypeScript support to improve development speed and ensure type safety. SignalDB supports creating an optimistic UI for responsive, dynamic interfaces and offers versatile local data persistence with various storage providers. SignalDB is also able to gather data from multiple sources, enabling real-time updates and synchronization (see examples for AppWrite, Firebase, Supabase, RxDB and HTTP). Designed for efficiency in applications requiring quick data handling and real-time interactions, SignalDB provides instant data access, minimizing latency typical of server-side databases. Its lightweight architecture is framework-agnostic, making it suitable for both small and large-scale projects that require flexible, intuitive data management solutions. SignalDB provides adapters for popular reactive libraries including Angular, React (through 3rd party signal libraries), Solid.js, Vue.js and many more.

Installation

  $ npm install signaldb

Usage

import { Collection } from 'signaldb'

const posts = new Collection()
const postId = posts.insert({ title: 'Foo', text: 'Lorem ipsum …' })
const cursor = collection.find({})
console.log(cursor.fetch()) // returns an array with all documents in the collection

Reactivity

In theory, every signal library is supported. SignalDB currently have pre-build reactivity adapters for these libraries:

More information in the reactivity section of the documentation.

import { effect } from '@preact/signals-core'
// OR
import { effect } from '@angular/core'
// OR
import { autorun as effect } from 'mobx'
// OR
import { createEffect as effect } from 'solid-js'
// OR
import { watchEffect as effect } from 'vue'
// ...

const posts = new Collection({
  reactivity: /* ... */ // see https://signaldb.js.org/reactivity/ for reactivity adapters for your favorite library,
})

effect(() => { // will be executed everytime the query result changes
  const cursor = posts.find({ author: 'John' })
  console.log(cursor.count())
})

Please also take a look at the documentation

Architecture

Reactivity

SignalDB harnesses the power of signal-based reactivity to offer a dynamic and responsive user experience. Our architecture integrates seamlessly with various signal libraries, ensuring compatibility and flexibility across different JavaScript frameworks. Whether you're using Angular, React, Vue.js, or others, SignalDB adapts to your preferred environment, enhancing the reactivity of your web applications.

Collections & Queries

At the heart of SignalDB lies its advanced handling of collections and queries. Our in-memory data storage approach ensures blazing-fast query performance, perfect for applications requiring real-time data manipulation and retrieval. This setup allows for a synchronous API, eliminating the complexity of asynchronous operations and making data handling straightforward and efficient.

Data Persistance

SignalDB's data persistence layer is designed for scalability and flexibility. It offers various strategies for persisting data, from simple localStorage implementations to more complex external systems. This versatility allows for customization based on your application's needs, ensuring data is stored efficiently and securely. Our architecture supports the evolution of your application, providing a solid foundation for growth and expansion.

Replication

Looking ahead, SignalDB plans to implement a cutting-edge data replication engine, drawing inspiration from established protocols like the RxDB replication protocol (more info). Initially, we'll offer data replication through a persistence interface for RxDB, with further expansions to follow. Our commitment to extensibility means that we're continually evolving, adding new features and capabilities to meet the ever-changing demands of modern web development.

License

Licensed under MIT license. Copyright (c) 2024 Max Nowack

Contributions

Contributions are welcome. Please open issues and/or file Pull Requests.

Maintainers

signaldb's People

Contributors

deardreamweb avatar gotgameio avatar jamesgibson14 avatar maxnowack avatar michaelkrog avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

signaldb's Issues

Query Profiler

The integration of a query profiler in SignalDB is proposed to enhance the database's performance analysis capabilities. This profiler would enable developers to monitor and evaluate the performance of various queries executed within SignalDB. It should provide detailed insights such as execution time, memory usage, and frequency of query calls, enabling developers to identify and optimize performance bottlenecks effectively. The profiler would also support tracking the impact of queries on the overall application performance, helping in fine-tuning the data retrieval and manipulation processes. Additionally, the query profiler should be designed to be minimally invasive, ensuring that its operation does not significantly impact the performance it is meant to measure. This feature is crucial for developers who need to ensure optimal performance and efficiency of their applications, particularly those with complex data handling requirements.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

github-actions
.github/workflows/checks.yaml
  • actions/checkout v4
  • actions/setup-node v3
  • actions/cache v3
  • actions/checkout v4
  • actions/setup-node v3
  • actions/cache v3
  • actions/checkout v4
  • actions/setup-node v3
  • actions/cache v3
  • actions/checkout v4
  • actions/setup-node v3
  • actions/cache v3
  • codecov/codecov-action v3
  • actions/checkout v4
  • actions/setup-node v3
  • actions/cache v3
  • actions/checkout v4
  • actions/setup-node v3
  • actions/cache v3
.github/workflows/deploy-docs.yaml
  • actions/checkout v4
  • actions/setup-node v3
  • actions/cache v3
  • actions/upload-pages-artifact v2
  • actions/deploy-pages v2
.github/workflows/release.yaml
  • maxnowack/action-release-generator v1.4.0
npm
example/package.json
  • @maverick-js/signals ^5.11.2
  • @types/node 20.8.3
  • @types/react 18.2.25
  • @types/react-dom 18.2.11
  • next 13.5.4
  • react 18.2.0
  • react-dom 18.2.0
  • rxdb ^14.14.2
  • rxjs ^7.8.1
  • signaldb 0.4.0
  • typescript 5.2.2
  • sass ^1.63.6
package.json
  • fast-sort ^3.4.0
  • mingo ^6.4.4
  • mobx ^6.10.2
  • @commitlint/cli 17.7.2
  • @commitlint/config-conventional 17.7.0
  • @maverick-js/signals 5.11.4
  • @preact/signals-core 1.5.0
  • @reactively/core 0.0.8
  • @rollup/plugin-typescript 11.1.5
  • @typescript-eslint/eslint-plugin 6.7.4
  • @typescript-eslint/parser 6.7.4
  • @vitest/coverage-istanbul ^0.34.4
  • eslint 8.51.0
  • eslint-config-airbnb-base 15.0.0
  • eslint-import-resolver-typescript 3.6.1
  • eslint-plugin-import 2.28.1
  • eslint-plugin-prefer-object-spread 1.2.1
  • eslint-plugin-vitest 0.3.2
  • happy-dom 12.9.0
  • husky 8.0.3
  • meteor-ts-tracker 2.0.2
  • oby 14.3.4
  • rimraf 5.0.5
  • rollup-plugin-typescript-paths 1.4.0
  • s-js 0.4.9
  • sinuous 0.32.1
  • sitemap-ts 1.4.0
  • solid-js 1.7.12
  • ts-node 10.9.1
  • tslib 2.6.2
  • typescript 5.2.2
  • usignal 0.9.0
  • vite 4.4.11
  • vite-plugin-dts 3.6.0
  • vite-plugin-node-polyfills 0.15.0
  • vite-tsconfig-paths 4.2.1
  • vitepress 1.0.0-rc.20
  • vitest 0.34.6
  • vitest-github-actions-reporter 0.10.0
  • vue ^3.3.4

  • Check this box to trigger a request for Renovate to run again on this repository

How do I access the posts.json file

ts export const posts = new Collection({ persistence: createFilesystemAdapter('./collections/posts.json'), reactivity: reactivityAdapter, });
I'm using solidjs and I don't know if I can access the file or not.

how do I save a collection?

import { uuidv7 } from 'uuidv7'
import { PersistentCollection, Collection, createFilesystemAdapter, createIndex } from 'signaldb'


const users = new Collection({
  persistence: createFilesystemAdapter('./users.json'),
  indices: [createIndex('id')],
})

users.on('persistence.error', (...argv) => {
  console.log('error:', argv)
})

users.on('added', (...argv) => {
  console.log('added:', argv)
})

users.insert({id: uuidv7(), name: 'qwerty', age: 1})
users.insert({id: uuidv7(), name: 'qwerty', age: 2})
users.insert({id: uuidv7(), name: 'qwerty', age: 3})

how do I save a collection?

Modified data before persistence.init event will be discarded

The issue came up in #491
Currently it's necessary to wait until the persistence.init event was emitted on the collection before making any changes to data. Otherwise the modification will be discarded and overwritten by the loaded data of the persistence adapter.
In terms of developer experience, it would be better if the collection would queue up any changes until the persistence.init event was emitted and then apply them.

Wrong import in SignalDB SolidJS Plugin

Seems like there's a mistake here on the import. It should be importing from "solid-js", not "solidj-s/dist/solid"

image

I confirmed that removing the /dist/solid fixes it.

Notice no errors:
image

EventEmitter<T> incorrectly extends interface EventEmitter (0.12.0+)

I have a weird issue after upgrading from 0.11.0. It works fine in 0.11.0, but 0.12.1 and 0.13.0 fails.

When building my angular project I get this:

✖ Compiling with Angular sources in Ivy partial compilation mode.
node_modules/signaldb/dist/types/EventEmitter.d.ts:2:19 - error TS2430: Interface 'EventEmitter<T>' incorrectly extends interface 'EventEmitter'.
  Types of property 'emit' are incompatible.
    Type '<U extends keyof T>(event: U, ...args: Parameters<T[U]>) => boolean' is not assignable to type '(type: string | number, ...args: any[]) => boolean'.
      Types of parameters 'event' and 'type' are incompatible.
        Type 'string | number' is not assignable to type 'keyof T'.
          Type 'number' is not assignable to type 'keyof T'.
            Type 'number' is not assignable to type 'string | symbol'.

2 declare interface EventEmitter<T extends Record<string | symbol, any>> {
                    ~~~~~~~~~~~~
node_modules/signaldb/dist/types/EventEmitter.d.ts:6:15 - error TS2415: Class 'EventEmitter<T>' incorrectly extends base class 'EventEmitter'.

6 declare class EventEmitter<T> extends BaseEventEmitter {
                ~~~~~~~~~~~~

I have been trying to figure out why it occurs, because to me it seems there have been no changes to that file (signaldb/dist/types/EventEmitter.d.ts) since 0.11.0.

Auto Fetching

The implementation of auto fetching in SignalDB is proposed to enhance its data handling capabilities. This feature involves registering queries when they are executed and unregistering them once they leave the reactive context. When a query is registered, a callback function will be invoked, allowing data to be loaded from an external system into SignalDB's in-memory database. After the data loading is complete, the reactive context will re-execute, and the query will return the newly fetched data. Additionally, a reactive function on the collection, such as isPreloading(), will be implemented to indicate the loading state. This feature aims to optimize data retrieval processes, particularly in scenarios requiring dynamic data loading from external sources, while maintaining the reactivity and performance efficiency of web applications using SignalDB.

Data Replication

The development of a data replication protocol for SignalDB is aimed at achieving efficient, reliable, and speedy data synchronization over http and websockts. Key features of this protocol should include a streamlined replication process, supporting concurrent push and pull operations, and a changestream mechanism for continuous and incremental data updates. Additionally, client-side conflict resolution is essential for decentralizing the process, thereby simplifying backend requirements and enhancing the database's autonomy. The protocol must be robust and fault-tolerant, capable of handling intermittent connectivity and large datasets with high-frequency updates. It should support offline operations with seamless re-syncing once connectivity is restored. Furthermore, the architecture should be extensible, allowing for future enhancements such as accommodating complex data types or integrating with various backend systems. Overall, this protocol will focus on ensuring that SignalDB offers a highly efficient, reliable, and user-friendly replication mechanism for modern client-side applications.

Inspiration:

Allow to pass LoadResponse directly to onChange callback in PersistenceAdapter

Discussed in #765

Originally posted by jamesgibson14 June 27, 2024
Currently onChange just triggers a this.persistenceAdapter.load(). Could we pass a changeSet to onChange -> loadPersistentData so that it could just load the partial changes instead of doing a full load/pull? Something like:

async register(onChange) {
      websock.onMessage({items, changes} => {
        void onChange({items, changes})
      }
    },

if loadPersistentData receives a changeSet then it just uses that instead of calling load

Appwrite Persistence Adapter

The implementation of an Appwrite persistence adapter is crucial for integrating SignalDB with Appwrite's backend services. This adapter will enable SignalDB to interface directly with Appwrite's server-side database, offering developers the flexibility to use SignalDB's client-side features while leveraging Appwrite's robust data storage, user authentication, and management capabilities. The goal is to create a seamless connection that allows for efficient data synchronization and manipulation between SignalDB and Appwrite. This integration is particularly valuable for applications that require secure, scalable, and easily manageable data storage solutions, making the most of both SignalDB's client-side efficiency and Appwrite's server-side robustness.

Changeset issue causes collection to be emptied when using ReplicatedCollection (CombinePersistenceAdapter)

When using ReplicatedCollection with LocalStorageAdapter for persistence I am experiencing what I what describe as a timing issue. For the most part it work, but now and then the collection just empties itself.

I have tried to add a lot of logging to get to the bottom of it. Here is how it looks when it works fine.
Skærmbillede 2024-08-07 kl  13 27 58

You'll see that I am saving a new entity. Before I put it in the Collection I log the number of entities already in the collection. There are also log statements for when persistence.pullCompleted occurs, together with the current number of entities in the collection.

This is an example for when it breaks.
Skærmbillede 2024-08-07 kl  13 30 24

Notice that persistence.pullCompleted happens twice, even if my pull method is only called once. Also in the last example the number of entities is 0, on the first persistence.pullCompleted event - before my pull method has returned a LoadResponse.

Supabase Persistence Adapter

The development of a Supabase persistence adapter for SignalDB is proposed to extend SignalDB's compatibility with Supabase as a backend service. This adapter will enable developers to leverage Supabase's real-time database capabilities, including its robust authentication, authorization, and real-time synchronization features, in conjunction with SignalDB's client-side functionalities. The integration aims to provide a seamless bridge between SignalDB's client-side operations and Supabase's cloud-hosted database, facilitating a more efficient and scalable data handling experience. This enhancement will particularly benefit applications requiring real-time data updates and those utilizing Supabase for their backend infrastructure

How to replace a newly created row?

I'm dealing with a situation where I insert a skeleton row into a ReplicatedCollection. A skeleton row is a bare minimum that the server needs like an id and a name. The collection calls its push hook and the skeleton row gets sent to the server. The server then notifies all clients that a new row was created. This new row includes other fields added by the server like createdAt, updatedAt, and createdBy. The collection's onChange gets called with { added: [newCompleteRow], modified: [], removed: [] }. My issue happens because the complete row added by onChange does not replace the initial skeleton row, and I end up with 2 rows with the same id.

There are a few possible solutions to my problem.

First, I could figure out if the current client is the one that initially inserted the skeleton row and swap the row (with modified) instead of simply adding it. I would rather not meddle with the backend.

The second option is that when onChange gets called with added rows, they should be upserted into the collection by the row's id. If a row is truly new it gets inserted otherwise it swaps the skeleton row.

A third option is to let the persistence adapter/replicated collection's push hook have access to the collection object so I can manually findOne by id and swap the row if it already exists.

Any idea how to go about this?

Restructure Documentation

Before v1.0.0 can be released it would be good to restructure the documentation, to make it more clear and structured, so that users can easily find what they're searching and make the initial setup faster.

I will collected my ideas in this issue. Feel free to recommend additional approaches.

ToDo:

  • Add an API reference with all exported classes/functions
  • Add guides for other frameworks (svelte, solid, vue, angular, etc.)
  • The getting started page should link to the guides
  • Add usage of replication possibilities to the getting started page

Reactivity in React.

I am using signal db with react, I have one collection defined as follows -

import { PersistentCollection } from 'signaldb'

export const collectionChats = new PersistentCollection('collection-chats')

I am consuming this collection in a nested route, in my application and I have a delete chats button on the main route, when I delete the chats in the main route, my nested route component is not re-rendering here is the code for my main route -

return (
    <div className="w-full p-9 pb-0 flex flex-col gap-4 h-full">
      <div className="flex justify-between">
        <Tabs defaultValue="account" className="w-[400px]">
          <TabsList className="grid w-full grid-cols-2">
            <NavLink to="videos">
              Videos
            </NavLink>
            <NavLink to="videos/chat">
              Chat
            </NavLink>
          </TabsList>
        </Tabs>
        <Button
          onClick={() => {
            collectionChats.updateOne(
              { id: params.collectionId },
              {
                $set: { chats: [] },
              }
            );
          }}
          variant="destructive"
        >
          <Trash2Icon className="h-[1.2rem] mr-2 w-[1.2rem] dark:-bg-white bg-dark" /> Delete Chat
        </Button>
      </div>

      <div className="w-full h-full pb-4 overflow-hidden">
        <Outlet />
      </div>
    </div>
  );

I am consuming the collectionChats inside the chat route which is a nested route -

const chatMessages = collectionChats.findOne({ id: params.collectionId });

I am expecting that when I click on the delete button and set the chats array to empty for a particular collectionId, my chat route should re-render and all the chats should disappear.

Item with same id already exists

if you insert new document with custom id, then delete this document, then try to add new document with this id again you will get error:

Item with same id already exists

const document = { id: 'test', text: 'Hello' }
DB.insert(document);
DB.removeOne({ id: document.id })
DB.insert(document); // <- error

private idIndex = new Map<string, Set<number>>()

Looks like when removing item the idIndex isn't cleared for this id, but with custom identifiers i think this should happen cause in my scenario i use some id from other source to use it as id in signaldb and cant remove/add this id twice, actually after page refresh idIndex doesn't contain any index and this is more like bug.

signaldb 0.8.6

Issue in routing to the example page installation page

image
Fig 1

image
Fig 2

Hi Maxnowack , I can across signaldb yesterday when researching on client side database and I must say you have done a great work here.
Why going through the documentation, I discovered that the link to Fig1 from Fig 2 is broken. I wish to contribute to this project and I will appreciate it if I can start from fixing the broken link.

Firebase Persistence Adapter

The creation of a Firebase persistence adapter for SignalDB is essential to integrate SignalDB with Firebase's cloud-based database and services. This adapter will enable developers to connect SignalDB's client-side database functionalities with Firebase's scalable backend, including its real-time database, authentication, and storage services. The integration is designed to facilitate seamless data synchronization and storage between the client and Firebase, offering a robust solution for applications that demand real-time data updates and cloud-based data persistence. This Firebase adapter aims to simplify backend operations for developers using SignalDB, making it easier to build dynamic, responsive web applications with efficient data handling and synchronization capabilities.

createFilesystemAdapter does not work

var cs = null, us = cs;
const W = /* @__PURE__ */ Zt(us);
function as(t) {
  let e = null;
  return {
    async register(n) {
      if (typeof window < "u")
        throw new Error("Filesystem adapter is not supported in the browser");
      await W.promises.access(t).then(() => !0).catch(() => !1) || await W.promises.writeFile(t, "[]"), W.watch(t, { encoding: "utf8" }, () => {
        n();
      });
    },

W.promises.access
Explain how this can bring back the promise

esm import

Import to esm does not work
Rename it index.es.js to index.es.mjs and "import": "./dist/index.es.mjs" in package.json

solid-js reactivity not working

I was testing signaldb in my solid-js project, but I noticed that adding an element to the collection triggered the effect.

import { Collection } from 'signaldb';
import solidReactivityAdapter from 'signaldb-plugin-solid'
import { createEffect } from 'solid-js';


const posts = new Collection({
  reactivity: solidReactivityAdapter,
});

createEffect(() => {
  console.log(posts.find({ author: 'John' }).count());
});

// ---------------------- INSERTS ---------------------------

(async () => {
  await posts.insert({ id: crypto.randomUUID(), author: 'John' });
  await new Promise((r) => setTimeout(r, 1000));
  await posts.insert({ id: crypto.randomUUID(), author: 'Kevin' });
  await new Promise((r) => setTimeout(r, 1000));
  await posts.insert({ id: crypto.randomUUID(), author: 'David' });
  console.log('Finish inserts');
})();

Testing the same example but with vue and @maverick-js/signals works as expected.

Then check in the documentation to make a custom adapter and add some console.log. It turns out that it never calls the “create” function.

import { Collection } from 'signaldb';
//import solidReactivityAdapter from 'signaldb-plugin-solid'
import { createEffect } from 'solid-js';

const solidReactivityAdapter = createReactivityAdapter({
  create: () => {
    console.log('Create');
    const [depend, rerun] = createSignal(0);
    return {
      depend: () => {
        console.log('Depend');
        depend();
      },
      notify: () => {
        console.log('Notify');
        rerun(depend() + 1);
      },
    };
  },
  isInScope: undefined,
  onDispose: (callback) => {
    onCleanup(callback);
  },
});

const posts = new Collection({
  reactivity: solidReactivityAdapter,
});

createEffect(() => {
  console.log(posts.find({ author: 'John' }).count());
});

// ---------------------- INSERTS ---------------------------

(async () => {
  await posts.insert({ id: crypto.randomUUID(), author: 'John' });
  await new Promise((r) => setTimeout(r, 1000));
  await posts.insert({ id: crypto.randomUUID(), author: 'Kevin' });
  await new Promise((r) => setTimeout(r, 1000));
  await posts.insert({ id: crypto.randomUUID(), author: 'David' });
  console.log('Finish inserts');
})();

I don't know what could be happening, I also leave a link to stackblitz you can try to replicate my experience.

Add support for reviving Dates

If objects in collections contains date objects, then they change to strings when read from a persistence adapter.

This is true for Opfs, Localstorage and Filesystem. All of them uses plain JSON.stringify and JSON.parse, which will convert Dates to strings.

A simple solution could be to add a reviver function to JSON.parse:

function dateReviver(key, value) {
   // handle dates
}

// Parse the JSON string with the reviver function
const parsedObj = JSON.parse(jsonString, dateReviver);

Better maybe even encapsulate it in a new class, that all persistence adapters can use.

Suggested solution

I suggest that serializing dates to json, should be resolve in an object like this:

{
  "createdAt": {
    "$type": "Date",
    "data": "2024-08-01T12:00:00Z"
  }
}

Doing that requires a replacer method for JSON.stringify, and a reviver for JSON.parse. Here follows a pseudo example.

stringify

function dateReplacer(key, value) {
  if (this[key] instanceof Date) {
    return { $type: 'Date', data: this[key].toISOString() };
  }
  return value;
}

const obj = {
  createdAt: new Date('1990-01-01')
};

const jsonString = JSON.stringify(obj, dateReplacer);

parse

function dateReviver(key, value) {
  if (value && typeof value === 'object' && value.$type === 'Date') {
    return new Date(value.data);
  }
  return value;
}

const parsedObj = JSON.parse(jsonString, dateReviver);

Async Collections

The development of Async Collections in SignalDB is aimed at enhancing the database's flexibility and performance, particularly in scenarios where data persistence without in-memory storage is essential. These Async Collections would enable SignalDB to interact with asynchronous storage mechanisms like IndexedDB more efficiently, allowing for data operations without necessarily storing data in the client's memory. This feature is especially relevant for applications that handle large datasets or require extended data persistence beyond the session scope. Furthermore, Async Collections could facilitate the outsourcing of query execution to Web Workers, thereby offloading intensive data processing tasks from the main thread. This approach would significantly improve the application's responsiveness and overall performance, especially in web applications with complex data processing requirements. The introduction of Async Collections in SignalDB aims to provide developers with more options for data management, catering to a broader range of application architectures and performance needs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.