UNPKG

@signaldb/core

Version:

SignalDB is a client-side database that provides a simple MongoDB-like interface to the data with first-class typescript support to achieve an optimistic UI. Data persistence can be achieved by using storage providers that store the data through a JSON in

99 lines (98 loc) 4.59 kB
import createSignal from "./index16.mjs"; import Collection from "./index23.mjs"; import createPersistenceAdapter from "./index24.mjs"; import combinePersistenceAdapters from "./index25.mjs"; //#region src/ReplicatedCollection.ts /** * Creates a persistence adapter for replicating a collection, enabling pull and push * operations for synchronizing with a remote source. Supports optional remote change registration. * @template T - The type of the items being replicated. * @template I - The type of the unique identifier for the items. * @param options - The options for configuring the replication adapter. * @param options.pull - A function to fetch data from the remote source. * @param options.push - An optional function to send changes and items to the remote source. * @param options.registerRemoteChange - An optional function to register a listener for remote changes. * @returns A persistence adapter configured for replication. */ function createReplicationAdapter(options) { return createPersistenceAdapter({ async register(onChange) { if (!options.registerRemoteChange) return; await options.registerRemoteChange(onChange); }, load: () => options.pull(), save: (items, changes) => { if (!options.push) throw new Error("Pushing is not configured for this collection. Try to pass a `push` function to the collection options."); return options.push(changes, items); } }); } /** * Extends the `Collection` class to support replication with remote sources. * Handles pull and push operations, remote change registration, and enhanced loading states. * @template T - The type of the items in the collection. * @template I - The type of the unique identifier for the items. * @template U - The transformed item type after applying transformations (default is T). */ var ReplicatedCollection = class extends Collection { isPullingRemoteSignal; isPushingRemoteSignal; /** * Creates a new instance of the `ReplicatedCollection` class. * Sets up the replication adapter, combining it with an optional persistence adapter, and * initializes signals for tracking remote pull and push operations. * @param options - The configuration options for the replicated collection. * @param options.pull - A function to fetch data from the remote source. * @param options.push - An optional function to send changes and items to the remote source. * @param options.registerRemoteChange - An optional function to register a listener for remote changes. * @param options.persistence - An optional persistence adapter to combine with replication. * @param options.reactivity - A reactivity adapter for observing changes in the collection. * @param options.transform - A transformation function to apply to items when retrieving them. * @param options.indices - An array of index providers for optimized querying. * @param options.enableDebugMode - A boolean to enable or disable debug mode. */ constructor(options) { const replicationAdapter = createReplicationAdapter({ registerRemoteChange: options.registerRemoteChange, pull: async () => { this.isPullingRemoteSignal.set(true); try { return await options.pull(); } finally { this.isPullingRemoteSignal.set(false); } }, push: options.push ? async (changes, items) => { if (!options.push) throw new Error("Pushing is not configured for this collection. Try to pass a `push` function to the collection options."); this.isPushingRemoteSignal.set(true); try { await options.push(changes, items); } finally { this.isPushingRemoteSignal.set(false); } } : void 0 }); const persistenceAdapter = options?.persistence ? combinePersistenceAdapters(replicationAdapter, options.persistence) : replicationAdapter; super({ ...options, persistence: persistenceAdapter }); this.isPullingRemoteSignal = createSignal(options.reactivity, false); this.isPushingRemoteSignal = createSignal(options.reactivity, false); } /** * Checks whether the collection is currently performing any loading operation, * including pulling or pushing data from/to the remote source, or standard * persistence adapter operations. * ⚡️ this function is reactive! * @returns A boolean indicating if the collection is currently loading or synchronizing. */ isLoading() { const isPullingRemote = this.isPullingRemoteSignal.get(); const isPushingRemote = this.isPushingRemoteSignal.get(); const isLoading = super.isLoading(); return isPullingRemote || isPushingRemote || isLoading; } }; //#endregion export { ReplicatedCollection as default };