@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
282 lines (281 loc) • 14.3 kB
TypeScript
import type MemoryAdapter from '../types/MemoryAdapter';
import type ReactivityAdapter from '../types/ReactivityAdapter';
import type PersistenceAdapter from '../types/PersistenceAdapter';
import EventEmitter from '../utils/EventEmitter';
import type Selector from '../types/Selector';
import type Modifier from '../types/Modifier';
import type IndexProvider from '../types/IndexProvider';
import Cursor from './Cursor';
import type { BaseItem, FindOptions, Transform } from './types';
export type { BaseItem, Transform, SortSpecifier, FieldSpecifier, FindOptions } from './types';
export type { CursorOptions } from './Cursor';
export type { ObserveCallbacks } from './Observer';
export { default as createIndex } from './createIndex';
export interface CollectionOptions<T extends BaseItem<I>, I, U = T> {
name?: string;
memory?: MemoryAdapter;
reactivity?: ReactivityAdapter;
transform?: Transform<T, U>;
persistence?: PersistenceAdapter<T, I>;
indices?: IndexProvider<T, I>[];
enableDebugMode?: boolean;
fieldTracking?: boolean;
}
interface CollectionEvents<T extends BaseItem, U = T> {
'added': (item: T) => void;
'changed': (item: T, modifier: Modifier<T>) => void;
'removed': (item: T) => void;
'persistence.init': () => void;
'persistence.error': (error: Error) => void;
'persistence.transmitted': () => void;
'persistence.received': () => void;
'persistence.pullStarted': () => void;
'persistence.pullCompleted': () => void;
'persistence.pushStarted': () => void;
'persistence.pushCompleted': () => void;
'observer.created': <O extends FindOptions<T>>(selector?: Selector<T>, options?: O) => void;
'observer.disposed': <O extends FindOptions<T>>(selector?: Selector<T>, options?: O) => void;
'getItems': (selector: Selector<T> | undefined) => void;
'find': <O extends FindOptions<T>>(selector: Selector<T> | undefined, options: O | undefined, cursor: Cursor<T, U>) => void;
'findOne': <O extends FindOptions<T>>(selector: Selector<T>, options: O | undefined, item: U | undefined) => void;
'insert': (item: Omit<T, 'id'> & Partial<Pick<T, 'id'>>) => void;
'updateOne': (selector: Selector<T>, modifier: Modifier<T>) => void;
'updateMany': (selector: Selector<T>, modifier: Modifier<T>) => void;
'replaceOne': (selector: Selector<T>, item: Omit<T, 'id'> & Partial<Pick<T, 'id'>>) => void;
'removeOne': (selector: Selector<T>) => void;
'removeMany': (selector: Selector<T>) => void;
'validate': (item: T) => void;
'_debug.getItems': (callstack: string, selector: Selector<T> | undefined, measuredTime: number) => void;
'_debug.find': <O extends FindOptions<T>>(callstack: string, selector: Selector<T> | undefined, options: O | undefined, cursor: Cursor<T, U>) => void;
'_debug.findOne': <O extends FindOptions<T>>(callstack: string, selector: Selector<T>, options: O | undefined, item: U | undefined) => void;
'_debug.insert': (callstack: string, item: Omit<T, 'id'> & Partial<Pick<T, 'id'>>) => void;
'_debug.updateOne': (callstack: string, selector: Selector<T>, modifier: Modifier<T>) => void;
'_debug.updateMany': (callstack: string, selector: Selector<T>, modifier: Modifier<T>) => void;
'_debug.replaceOne': (callstack: string, selector: Selector<T>, item: Omit<T, 'id'> & Partial<Pick<T, 'id'>>) => void;
'_debug.removeOne': (callstack: string, selector: Selector<T>) => void;
'_debug.removeMany': (callstack: string, selector: Selector<T>) => void;
}
/**
* Represents a collection of data items with support for in-memory operations,
* persistence, reactivity, and event-based notifications. The collection provides
* CRUD operations, observer patterns, and batch operations.
* @template T - The type of the items stored 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).
*/
export default class Collection<T extends BaseItem<I> = BaseItem, I = any, U = T> extends EventEmitter<CollectionEvents<T, U>> {
private static collections;
private static debugMode;
private static batchOperationInProgress;
private static fieldTracking;
private static onCreationCallbacks;
private static onDisposeCallbacks;
static getCollections(): Collection<any, any, any>[];
static onCreation(callback: (collection: Collection<any>) => void): void;
static onDispose(callback: (collection: Collection<any>) => void): void;
/**
* Enables debug mode for all collections.
*/
static enableDebugMode: () => void;
/**
* Enables field tracking for all collections.
* @param enable - A boolean indicating whether to enable field tracking.
*/
static setFieldTracking: (enable: boolean) => void;
/**
* Executes a batch operation, allowing multiple modifications to the collection
* while deferring index rebuilding until all operations in the batch are completed.
* This improves performance by avoiding repetitive index recalculations and
* provides atomicity for the batch of operations.
* @param callback - The batch operation to execute.
*/
static batch(callback: () => void): void;
readonly name: string;
private options;
private persistenceAdapter;
private isPullingSignal;
private isPushingSignal;
private indexProviders;
private indicesOutdated;
private idIndex;
private debugMode;
private batchOperationInProgress;
private isDisposed;
private postBatchCallbacks;
private fieldTracking;
private persistenceReadyPromise;
/**
* Initializes a new instance of the `Collection` class with optional configuration.
* Sets up memory, persistence, reactivity, and indices as specified in the options.
* @template T - The type of the items stored 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).
* @param options - Optional configuration for the collection.
* @param options.name - An optional name for the collection.
* @param options.memory - The in-memory adapter for storing items.
* @param options.reactivity - The reactivity adapter for observing changes in the collection.
* @param options.transform - A transformation function to apply to items when retrieving them.
* @param options.persistence - The persistence adapter for saving and loading items.
* @param options.indices - An array of index providers for optimized querying.
* @param options.enableDebugMode - A boolean to enable or disable debug mode.
* @param options.fieldTracking - A boolean to enable or disable field tracking by default.
*/
constructor(options?: CollectionOptions<T, I, U>);
/**
* Checks whether the collection is currently performing a pull operation
* ⚡️ this function is reactive!
* (loading data from the persistence adapter).
* @returns A boolean indicating if the collection is in the process of pulling data.
*/
isPulling(): boolean;
/**
* Checks whether the collection is currently performing a push operation
* ⚡️ this function is reactive!
* (saving data to the persistence adapter).
* @returns A boolean indicating if the collection is in the process of pushing data.
*/
isPushing(): boolean;
/**
* Checks whether the collection is currently performing either a pull or push operation,
* ⚡️ this function is reactive!
* indicating that it is loading or saving data.
* @returns A boolean indicating if the collection is in the process of loading or saving data.
*/
isLoading(): boolean;
/**
* Retrieves the current debug mode status of the collection.
* @returns A boolean indicating whether debug mode is enabled for the collection.
*/
getDebugMode(): boolean;
/**
* Enables or disables debug mode for the collection.
* When debug mode is enabled, additional debugging information and events are emitted.
* @param enable - A boolean indicating whether to enable (`true`) or disable (`false`) debug mode.
*/
setDebugMode(enable: boolean): void;
/**
* Enables or disables field tracking for the collection.
* @param enable - A boolean indicating whether to enable (`true`) or disable (`false`) field tracking.
*/
setFieldTracking(enable: boolean): void;
/**
* Resolves when the persistence adapter finished initializing
* and the collection is ready to be used.
* @returns A promise that resolves when the collection is ready.
* @example
* ```ts
* const collection = new Collection({
* persistence: // ...
* })
* await collection.isReady()
*
* collection.insert({ name: 'Item 1' })
*/
isReady(): Promise<void>;
private profile;
private executeInDebugMode;
private rebuildIndices;
private rebuildAllIndices;
private getIndexInfo;
private getItemAndIndex;
private deleteFromIdIndex;
private memory;
private memoryArray;
private transform;
private getItems;
/**
* Disposes the collection, unregisters persistence adapters, clears memory, and
* cleans up all resources used by the collection.
* @returns A promise that resolves when the collection is disposed.
*/
dispose(): Promise<void>;
/**
* Finds multiple items in the collection based on a selector and optional options.
* Returns a cursor for reactive data queries.
* @template O - The options type for the find operation.
* @param [selector] - The criteria to select items.
* @param [options] - Options for the find operation, such as limit and sort.
* @returns A cursor to fetch and observe the matching items.
*/
find<O extends FindOptions<T>>(selector?: Selector<T>, options?: O): Cursor<T, U>;
/**
* Finds a single item in the collection based on a selector and optional options.
* ⚡️ this function is reactive!
* Returns the found item or undefined if no item matches.
* @template O - The options type for the find operation.
* @param selector - The criteria to select the item.
* @param [options] - Options for the find operation, such as projection.
* @returns The found item or `undefined`.
*/
findOne<O extends Omit<FindOptions<T>, 'limit'>>(selector: Selector<T>, options?: O): NonNullable<U> | undefined;
/**
* Performs a batch operation, deferring index rebuilds and allowing multiple
* modifications to be made atomically. Executes any post-batch callbacks afterwards.
* @param callback - The batch operation to execute.
*/
batch(callback: () => void): void;
/**
* Inserts a single item into the collection. Generates a unique ID if not provided.
* @param item - The item to insert.
* @returns The ID of the inserted item.
* @throws {Error} If the collection is disposed or the item has an invalid ID.
*/
insert(item: Omit<T, 'id'> & Partial<Pick<T, 'id'>>): I;
/**
* Inserts multiple items into the collection. Generates unique IDs for items if not provided.
* @param items - The items to insert.
* @returns An array of IDs of the inserted items.
* @throws {Error} If the collection is disposed or the items are invalid.
*/
insertMany(items: Array<Omit<T, 'id'> & Partial<Pick<T, 'id'>>>): I[];
/**
* Updates a single item in the collection that matches the given selector.
* @param selector - The criteria to select the item to update.
* @param modifier - The modifications to apply to the item.
* @param [options] - Optional settings for the update operation.
* @param [options.upsert] - If `true`, creates a new item if no item matches the selector.
* @returns The number of items updated (0 or 1).
* @throws {Error} If the collection is disposed or invalid arguments are provided.
*/
updateOne(selector: Selector<T>, modifier: Modifier<T>, options?: {
upsert?: boolean;
}): 0 | 1;
/**
* Updates multiple items in the collection that match the given selector.
* @param selector - The criteria to select the items to update.
* @param modifier - The modifications to apply to the items.
* @param [options] - Optional settings for the update operation.
* @param [options.upsert] - If `true`, creates new items if no items match the selector.
* @returns The number of items updated.
* @throws {Error} If the collection is disposed or invalid arguments are provided.
*/
updateMany(selector: Selector<T>, modifier: Modifier<T>, options?: {
upsert?: boolean;
}): number;
/**
* Replaces a single item in the collection that matches the given selector.
* @param selector - The criteria to select the item to replace.
* @param replacement - The item to replace the selected item with.
* @param [options] - Optional settings for the replace operation.
* @param [options.upsert] - If `true`, creates a new item if no item matches the selector.
* @returns The number of items replaced (0 or 1).
* @throws {Error} If the collection is disposed or invalid arguments are provided.
*/
replaceOne(selector: Selector<T>, replacement: Omit<T, 'id'> & Partial<Pick<T, 'id'>>, options?: {
upsert?: boolean;
}): 0 | 1;
/**
* Removes a single item from the collection that matches the given selector.
* @param selector - The criteria to select the item to remove.
* @returns The number of items removed (0 or 1).
* @throws {Error} If the collection is disposed or invalid arguments are provided.
*/
removeOne(selector: Selector<T>): 0 | 1;
/**
* Removes multiple items from the collection that match the given selector.
* @param selector - The criteria to select the items to remove.
* @returns The number of items removed.
* @throws {Error} If the collection is disposed or invalid arguments are provided.
*/
removeMany(selector: Selector<T>): number;
}