@asaidimu/utils-database 1.1.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -3
- package/index.d.mts +191 -13
- package/index.d.ts +191 -13
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ A flexible, schema-driven document database layer for browser and Node.js with b
|
|
|
16
16
|
- [Basic CRUD](#basic-crud)
|
|
17
17
|
- [Transactions](#transactions)
|
|
18
18
|
- [Migrations](#migrations)
|
|
19
|
-
- [Events & Telemetry](#events
|
|
19
|
+
- [Events & Telemetry](#events-telemetry)
|
|
20
20
|
- [Pagination & Filtering](#pagination--filtering)
|
|
21
21
|
- [Project Architecture](#project-architecture)
|
|
22
22
|
- [Development & Contributing](#development--contributing)
|
|
@@ -60,7 +60,7 @@ npm install @asaidimu/utils-database
|
|
|
60
60
|
This package has the following peer dependencies – you need to install them manually:
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
-
npm install @asaidimu/anansi
|
|
63
|
+
npm install @asaidimu/anansi
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
### Basic Configuration
|
|
@@ -356,7 +356,6 @@ This project is licensed under the **MIT License**. See the [LICENSE](https://gi
|
|
|
356
356
|
|
|
357
357
|
Built with ❤️ using:
|
|
358
358
|
- [`@asaidimu/anansi`](https://github.com/asaidimu/anansi) – schema validation and migrations.
|
|
359
|
-
- [`@asaidimu/events`](https://github.com/asaidimu/events) – type‑safe event bus.
|
|
360
359
|
- [`@standard-schema/spec`](https://github.com/standard-schema/standard-schema) – Standard Schema interoperability.
|
|
361
360
|
- [`uuid`](https://github.com/uuidjs/uuid) – for v7 UUIDs.
|
|
362
361
|
- [`fake-indexeddb`](https://github.com/dumbmatter/fakeIndexedDB) – testing support.
|
package/index.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { QueryFilter, PaginationOptions } from '@asaidimu/query';
|
|
2
2
|
import { IndexDefinition, SchemaDefinition, SchemaChange, DataTransform, PredicateMap } from '@asaidimu/anansi';
|
|
3
|
-
import { EventBus } from '@asaidimu/events';
|
|
4
3
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
5
4
|
|
|
6
5
|
/**
|
|
@@ -279,6 +278,16 @@ interface Collection<T> {
|
|
|
279
278
|
* @param tx - Optional transaction to buffer the write into.
|
|
280
279
|
*/
|
|
281
280
|
create: (initial: T, tx?: TransactionContext) => Promise<Document<T>>;
|
|
281
|
+
/**
|
|
282
|
+
* Updates all documents matching the query with the provided partial data.
|
|
283
|
+
* Returns the number of documents updated.
|
|
284
|
+
*/
|
|
285
|
+
update: (query: QueryFilter<T>, data: Partial<T>, tx?: TransactionContext) => Promise<number>;
|
|
286
|
+
/**
|
|
287
|
+
* Deletes all documents matching the query.
|
|
288
|
+
* Returns the number of documents deleted.
|
|
289
|
+
*/
|
|
290
|
+
delete: (query: QueryFilter<T>, tx?: TransactionContext) => Promise<number>;
|
|
282
291
|
/**
|
|
283
292
|
* Subscribes to collection-level events.
|
|
284
293
|
*/
|
|
@@ -367,19 +376,22 @@ type DatabaseEvent = {
|
|
|
367
376
|
schema?: SchemaDefinition | Partial<SchemaDefinition>;
|
|
368
377
|
timestamp: number;
|
|
369
378
|
};
|
|
370
|
-
type
|
|
371
|
-
readonly [K in keyof T]: T[K];
|
|
372
|
-
} & {
|
|
379
|
+
type DocumentMetadata = {
|
|
373
380
|
$id?: string;
|
|
374
381
|
$created?: string | Date;
|
|
375
382
|
$updated?: string | Date;
|
|
376
383
|
$version?: number;
|
|
384
|
+
};
|
|
385
|
+
type Document<T> = {
|
|
386
|
+
readonly [K in keyof T]: T[K];
|
|
387
|
+
} & DocumentMetadata & {
|
|
377
388
|
read: () => Promise<boolean>;
|
|
378
389
|
save: (tx?: TransactionContext) => Promise<boolean>;
|
|
379
390
|
update: (props: Partial<T>, tx?: TransactionContext) => Promise<boolean>;
|
|
380
391
|
delete: (tx?: TransactionContext) => Promise<boolean>;
|
|
381
392
|
subscribe: (event: DocumentEventType | TelemetryEventType, callback: (event: DocumentEvent<T> | TelemetryEvent) => void) => () => void;
|
|
382
393
|
state(): T;
|
|
394
|
+
$metadata(): DocumentMetadata;
|
|
383
395
|
};
|
|
384
396
|
type DocumentEventType = "document:create" | "document:write" | "document:update" | "document:delete" | "document:read";
|
|
385
397
|
type DocumentEvent<T> = {
|
|
@@ -728,6 +740,126 @@ declare const createIndexedDbStore: <T extends Record<string, any>>(config: Stor
|
|
|
728
740
|
|
|
729
741
|
declare function DatabaseConnection(config: Omit<DatabaseConfig, "keyPath">, createStore: <T extends Record<string, any>>(config: StoreConfig, indexes: IndexDefinition[]) => Store<T>): Promise<Database>;
|
|
730
742
|
|
|
743
|
+
interface MutexOptions {
|
|
744
|
+
/**
|
|
745
|
+
* Maximum number of pending requests allowed in the queue.
|
|
746
|
+
* If exceeded, tryLock/lock will fail.
|
|
747
|
+
* @default Infinity
|
|
748
|
+
*/
|
|
749
|
+
capacity?: number;
|
|
750
|
+
/**
|
|
751
|
+
* Controls how lock handoff is scheduled when a waiter is unblocked.
|
|
752
|
+
*
|
|
753
|
+
* - `"macrotask"` (default): Uses setTimeout(fn, 0) to yield to the event
|
|
754
|
+
* loop between handoffs. Prevents microtask starvation under heavy
|
|
755
|
+
* contention — I/O, rendering, and other macrotasks can run between
|
|
756
|
+
* lock acquisitions. Use for Serializer and other coarse-grained
|
|
757
|
+
* serializers.
|
|
758
|
+
*
|
|
759
|
+
* - `"microtask"`: Uses queueMicrotask(fn) for handoff. Near-zero latency
|
|
760
|
+
* between acquisitions — no macrotask delay. Safe when you need
|
|
761
|
+
* back-to-back operations to complete as fast as possible and starvation
|
|
762
|
+
* is not a concern (e.g. Once, Semaphore where builds are infrequent
|
|
763
|
+
* and latency matters more than fairness).
|
|
764
|
+
*/
|
|
765
|
+
yieldMode?: "macrotask" | "microtask";
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* A mutual exclusion lock.
|
|
769
|
+
* Allows only one execution context to access a resource at a time.
|
|
770
|
+
*
|
|
771
|
+
* Yield mode is configurable per instance:
|
|
772
|
+
* - "macrotask" (default): yields between handoffs, preventing microtask starvation.
|
|
773
|
+
* - "microtask": zero-delay handoff for latency-sensitive paths.
|
|
774
|
+
*/
|
|
775
|
+
declare class Mutex {
|
|
776
|
+
private _locked;
|
|
777
|
+
private _capacity;
|
|
778
|
+
private _yieldMode;
|
|
779
|
+
private waiters;
|
|
780
|
+
constructor(options?: MutexOptions);
|
|
781
|
+
/**
|
|
782
|
+
* Acquires the lock. If already held, waits until released or timeout reached.
|
|
783
|
+
*
|
|
784
|
+
* @param timeout - Optional maximum wait time in milliseconds.
|
|
785
|
+
* @throws {TimeoutError} If the lock cannot be acquired within the timeout.
|
|
786
|
+
* @throws {Error} If the wait queue is full (backpressure).
|
|
787
|
+
*/
|
|
788
|
+
lock(timeout?: number): Promise<void>;
|
|
789
|
+
/**
|
|
790
|
+
* Attempts to acquire the lock without waiting.
|
|
791
|
+
* @returns `true` if the lock was acquired, `false` otherwise.
|
|
792
|
+
*/
|
|
793
|
+
tryLock(): boolean;
|
|
794
|
+
/**
|
|
795
|
+
* Releases the lock, scheduling the next waiter according to yieldMode.
|
|
796
|
+
*
|
|
797
|
+
* When a waiter exists, `_locked` intentionally remains `true` — ownership
|
|
798
|
+
* transfers directly to the next waiter without ever clearing the flag.
|
|
799
|
+
* Only when the queue is empty is `_locked` set to false.
|
|
800
|
+
*
|
|
801
|
+
* @throws {Error} If the mutex is not currently locked.
|
|
802
|
+
*/
|
|
803
|
+
unlock(): void;
|
|
804
|
+
/** Returns true if the mutex is currently locked. */
|
|
805
|
+
locked(): boolean;
|
|
806
|
+
/** Returns the number of operations waiting for the lock. */
|
|
807
|
+
pending(): number;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* Interface defining the shape of the EventBus.
|
|
812
|
+
* @template TEventMap - A record mapping event names to their respective payload types.
|
|
813
|
+
*/
|
|
814
|
+
interface EventBus<TEventMap extends Record<string, any>> {
|
|
815
|
+
/**
|
|
816
|
+
* Subscribes to a specific event by name.
|
|
817
|
+
* @param eventName - The name of the event to subscribe to.
|
|
818
|
+
* @param callback - The function to call when the event is emitted.
|
|
819
|
+
* @returns A function to unsubscribe from the event.
|
|
820
|
+
*/
|
|
821
|
+
subscribe: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
822
|
+
/**
|
|
823
|
+
* Subscribes to an event and automatically unsubscribes after it fires once.
|
|
824
|
+
* @param eventName - The name of the event to subscribe to.
|
|
825
|
+
* @param callback - The function to call when the event is emitted.
|
|
826
|
+
* @returns A function to cancel the one-shot subscription before it fires.
|
|
827
|
+
*/
|
|
828
|
+
once: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
829
|
+
/**
|
|
830
|
+
* Emits an event with a payload to all subscribed listeners.
|
|
831
|
+
* @param event - An object containing the event name and payload.
|
|
832
|
+
*/
|
|
833
|
+
emit: <TEventName extends keyof TEventMap>(event: {
|
|
834
|
+
name: TEventName;
|
|
835
|
+
payload: TEventMap[TEventName];
|
|
836
|
+
}) => void;
|
|
837
|
+
/**
|
|
838
|
+
* Retrieves metrics about event bus usage.
|
|
839
|
+
* @returns An object containing various metrics.
|
|
840
|
+
*/
|
|
841
|
+
metrics: () => EventMetrics;
|
|
842
|
+
/**
|
|
843
|
+
* Clears all subscriptions and resets metrics.
|
|
844
|
+
* After calling clear(), the bus is fully reset and can be reused —
|
|
845
|
+
* cross-tab communication is re-established if it was previously enabled.
|
|
846
|
+
*/
|
|
847
|
+
clear: () => void;
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Interface defining the metrics tracked by the EventBus.
|
|
851
|
+
*/
|
|
852
|
+
interface EventMetrics {
|
|
853
|
+
/** Total number of events emitted (both sync and deferred paths). */
|
|
854
|
+
totalEvents: number;
|
|
855
|
+
/** Number of active subscriptions across all event names. */
|
|
856
|
+
activeSubscriptions: number;
|
|
857
|
+
/** Map of event names to their emission counts. */
|
|
858
|
+
eventCounts: Map<string, number>;
|
|
859
|
+
/** Average duration of event dispatch in milliseconds. */
|
|
860
|
+
averageEmitDuration: number;
|
|
861
|
+
}
|
|
862
|
+
|
|
731
863
|
interface MiddlewareContext {
|
|
732
864
|
collection?: string;
|
|
733
865
|
documentId?: string;
|
|
@@ -745,13 +877,6 @@ declare class Pipeline {
|
|
|
745
877
|
wrap<T extends object>(target: T, baseContext: Partial<MiddlewareContext>): T;
|
|
746
878
|
}
|
|
747
879
|
|
|
748
|
-
declare class Mutex {
|
|
749
|
-
private queue;
|
|
750
|
-
private locked;
|
|
751
|
-
acquire(): Promise<() => void>;
|
|
752
|
-
private release;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
880
|
interface DocumentOptions<T extends Record<string, any>> {
|
|
756
881
|
/**
|
|
757
882
|
* The already-persisted initial state of the document.
|
|
@@ -760,6 +885,7 @@ interface DocumentOptions<T extends Record<string, any>> {
|
|
|
760
885
|
*/
|
|
761
886
|
initial: Partial<T>;
|
|
762
887
|
collection: string;
|
|
888
|
+
schema: SchemaDefinition;
|
|
763
889
|
validator?: StandardSchemaV1;
|
|
764
890
|
store: Store<T>;
|
|
765
891
|
bus: EventBus<Record<DocumentEventType | TelemetryEventType, DocumentEvent<T> | TelemetryEvent>>;
|
|
@@ -780,13 +906,65 @@ interface DocumentOptions<T extends Record<string, any>> {
|
|
|
780
906
|
declare function createDocument<T extends Record<string, any>>(opts: DocumentOptions<T>): Promise<Document<T & {
|
|
781
907
|
$id: string | number;
|
|
782
908
|
}>>;
|
|
783
|
-
declare function openCollection<T extends Record<string, any>>({ collection:
|
|
909
|
+
declare function openCollection<T extends Record<string, any>>({ collection: schemaName, validator, bus, store, pipeline, validate, schema: schemaDefinition, }: {
|
|
784
910
|
store: Store<T>;
|
|
785
911
|
collection: string;
|
|
786
912
|
validator: StandardSchemaV1;
|
|
787
913
|
bus: EventBus<any>;
|
|
788
914
|
pipeline: Pipeline;
|
|
789
915
|
validate: boolean;
|
|
916
|
+
schema: SchemaDefinition;
|
|
790
917
|
}): Promise<Collection<T>>;
|
|
791
918
|
|
|
792
|
-
|
|
919
|
+
/**
|
|
920
|
+
* Error types for Database operations.
|
|
921
|
+
*/
|
|
922
|
+
declare enum DatabaseErrorType {
|
|
923
|
+
/** The schema does not exist. */
|
|
924
|
+
SCHEMA_NOT_FOUND = "SCHEMA_NOT_FOUND",
|
|
925
|
+
/** The schema already exists. */
|
|
926
|
+
SCHEMA_ALREADY_EXISTS = "SCHEMA_ALREADY_EXISTS",
|
|
927
|
+
/** The schema name is invalid. */
|
|
928
|
+
INVALID_SCHEMA_NAME = "INVALID_SCHEMA_NAME",
|
|
929
|
+
/** The schema definition is invalid. */
|
|
930
|
+
INVALID_SCHEMA_DEFINITION = "INVALID_SCHEMA_DEFINITION",
|
|
931
|
+
/** The database subscription failed. */
|
|
932
|
+
SUBSCRIPTION_FAILED = "SUBSCRIPTION_FAILED",
|
|
933
|
+
/** The database operation failed due to an internal error. */
|
|
934
|
+
INTERNAL_ERROR = "INTERNAL_ERROR",
|
|
935
|
+
/** Data being entered into a collection does not satisfy its schema definition. */
|
|
936
|
+
INVALID_DATA = "INVALID_DATA",
|
|
937
|
+
/** Optimistic Concurrency Control version mismatches */
|
|
938
|
+
CONFLICT = "CONFLICT",
|
|
939
|
+
/** For retryable store locks */
|
|
940
|
+
TRANSIENT_ERROR = "TRANSIENT_ERROR",
|
|
941
|
+
TRANSACTION_FAILED = "TRANSACTION_FAILED",
|
|
942
|
+
CONNECTION_FAILED = "CONNECTION_FAILED",
|
|
943
|
+
INVALID_OPERATION = "INVALID_OPERATION"
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
946
|
+
* Error class for Database operations.
|
|
947
|
+
*/
|
|
948
|
+
declare class DatabaseError extends Error {
|
|
949
|
+
/**
|
|
950
|
+
* The type of error that occurred.
|
|
951
|
+
*/
|
|
952
|
+
type: DatabaseErrorType;
|
|
953
|
+
/**
|
|
954
|
+
* The schema associated with the error, if applicable.
|
|
955
|
+
*/
|
|
956
|
+
schema?: SchemaDefinition;
|
|
957
|
+
/**
|
|
958
|
+
* Issues associated with the error
|
|
959
|
+
*/
|
|
960
|
+
issues?: any[];
|
|
961
|
+
/**
|
|
962
|
+
* Constructs a new DatabaseErrorClass instance.
|
|
963
|
+
* @param type - The type of error that occurred.
|
|
964
|
+
* @param message - A human-readable message describing the error.
|
|
965
|
+
* @param schema - The schema associated with the error, if applicable.
|
|
966
|
+
*/
|
|
967
|
+
constructor(type: DatabaseErrorType, message: string, schema?: SchemaDefinition, cause?: unknown, issues?: any);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
export { type BufferedOperation, type Collection, type CollectionEvent, type CollectionEventType, type CollectionMigrationOptions, ConnectionManager, type CursorCallback, type CursorCallbackResult, type CursorPaginationOptions, DEFAULT_KEYPATH, type Database, type DatabaseConfig, DatabaseConnection, DatabaseError, DatabaseErrorType, type DatabaseEvent, type DatabaseEventType, type Document, type DocumentEvent, type DocumentEventType, type DocumentMetadata, IndexedDBStore, type Store, type StoreConfig, type StoreKeyRange, type TelemetryEvent, type TelemetryEventType, createDocument, createEphemeralStore, createIndexedDbStore, openCollection };
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { QueryFilter, PaginationOptions } from '@asaidimu/query';
|
|
2
2
|
import { IndexDefinition, SchemaDefinition, SchemaChange, DataTransform, PredicateMap } from '@asaidimu/anansi';
|
|
3
|
-
import { EventBus } from '@asaidimu/events';
|
|
4
3
|
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
5
4
|
|
|
6
5
|
/**
|
|
@@ -279,6 +278,16 @@ interface Collection<T> {
|
|
|
279
278
|
* @param tx - Optional transaction to buffer the write into.
|
|
280
279
|
*/
|
|
281
280
|
create: (initial: T, tx?: TransactionContext) => Promise<Document<T>>;
|
|
281
|
+
/**
|
|
282
|
+
* Updates all documents matching the query with the provided partial data.
|
|
283
|
+
* Returns the number of documents updated.
|
|
284
|
+
*/
|
|
285
|
+
update: (query: QueryFilter<T>, data: Partial<T>, tx?: TransactionContext) => Promise<number>;
|
|
286
|
+
/**
|
|
287
|
+
* Deletes all documents matching the query.
|
|
288
|
+
* Returns the number of documents deleted.
|
|
289
|
+
*/
|
|
290
|
+
delete: (query: QueryFilter<T>, tx?: TransactionContext) => Promise<number>;
|
|
282
291
|
/**
|
|
283
292
|
* Subscribes to collection-level events.
|
|
284
293
|
*/
|
|
@@ -367,19 +376,22 @@ type DatabaseEvent = {
|
|
|
367
376
|
schema?: SchemaDefinition | Partial<SchemaDefinition>;
|
|
368
377
|
timestamp: number;
|
|
369
378
|
};
|
|
370
|
-
type
|
|
371
|
-
readonly [K in keyof T]: T[K];
|
|
372
|
-
} & {
|
|
379
|
+
type DocumentMetadata = {
|
|
373
380
|
$id?: string;
|
|
374
381
|
$created?: string | Date;
|
|
375
382
|
$updated?: string | Date;
|
|
376
383
|
$version?: number;
|
|
384
|
+
};
|
|
385
|
+
type Document<T> = {
|
|
386
|
+
readonly [K in keyof T]: T[K];
|
|
387
|
+
} & DocumentMetadata & {
|
|
377
388
|
read: () => Promise<boolean>;
|
|
378
389
|
save: (tx?: TransactionContext) => Promise<boolean>;
|
|
379
390
|
update: (props: Partial<T>, tx?: TransactionContext) => Promise<boolean>;
|
|
380
391
|
delete: (tx?: TransactionContext) => Promise<boolean>;
|
|
381
392
|
subscribe: (event: DocumentEventType | TelemetryEventType, callback: (event: DocumentEvent<T> | TelemetryEvent) => void) => () => void;
|
|
382
393
|
state(): T;
|
|
394
|
+
$metadata(): DocumentMetadata;
|
|
383
395
|
};
|
|
384
396
|
type DocumentEventType = "document:create" | "document:write" | "document:update" | "document:delete" | "document:read";
|
|
385
397
|
type DocumentEvent<T> = {
|
|
@@ -728,6 +740,126 @@ declare const createIndexedDbStore: <T extends Record<string, any>>(config: Stor
|
|
|
728
740
|
|
|
729
741
|
declare function DatabaseConnection(config: Omit<DatabaseConfig, "keyPath">, createStore: <T extends Record<string, any>>(config: StoreConfig, indexes: IndexDefinition[]) => Store<T>): Promise<Database>;
|
|
730
742
|
|
|
743
|
+
interface MutexOptions {
|
|
744
|
+
/**
|
|
745
|
+
* Maximum number of pending requests allowed in the queue.
|
|
746
|
+
* If exceeded, tryLock/lock will fail.
|
|
747
|
+
* @default Infinity
|
|
748
|
+
*/
|
|
749
|
+
capacity?: number;
|
|
750
|
+
/**
|
|
751
|
+
* Controls how lock handoff is scheduled when a waiter is unblocked.
|
|
752
|
+
*
|
|
753
|
+
* - `"macrotask"` (default): Uses setTimeout(fn, 0) to yield to the event
|
|
754
|
+
* loop between handoffs. Prevents microtask starvation under heavy
|
|
755
|
+
* contention — I/O, rendering, and other macrotasks can run between
|
|
756
|
+
* lock acquisitions. Use for Serializer and other coarse-grained
|
|
757
|
+
* serializers.
|
|
758
|
+
*
|
|
759
|
+
* - `"microtask"`: Uses queueMicrotask(fn) for handoff. Near-zero latency
|
|
760
|
+
* between acquisitions — no macrotask delay. Safe when you need
|
|
761
|
+
* back-to-back operations to complete as fast as possible and starvation
|
|
762
|
+
* is not a concern (e.g. Once, Semaphore where builds are infrequent
|
|
763
|
+
* and latency matters more than fairness).
|
|
764
|
+
*/
|
|
765
|
+
yieldMode?: "macrotask" | "microtask";
|
|
766
|
+
}
|
|
767
|
+
/**
|
|
768
|
+
* A mutual exclusion lock.
|
|
769
|
+
* Allows only one execution context to access a resource at a time.
|
|
770
|
+
*
|
|
771
|
+
* Yield mode is configurable per instance:
|
|
772
|
+
* - "macrotask" (default): yields between handoffs, preventing microtask starvation.
|
|
773
|
+
* - "microtask": zero-delay handoff for latency-sensitive paths.
|
|
774
|
+
*/
|
|
775
|
+
declare class Mutex {
|
|
776
|
+
private _locked;
|
|
777
|
+
private _capacity;
|
|
778
|
+
private _yieldMode;
|
|
779
|
+
private waiters;
|
|
780
|
+
constructor(options?: MutexOptions);
|
|
781
|
+
/**
|
|
782
|
+
* Acquires the lock. If already held, waits until released or timeout reached.
|
|
783
|
+
*
|
|
784
|
+
* @param timeout - Optional maximum wait time in milliseconds.
|
|
785
|
+
* @throws {TimeoutError} If the lock cannot be acquired within the timeout.
|
|
786
|
+
* @throws {Error} If the wait queue is full (backpressure).
|
|
787
|
+
*/
|
|
788
|
+
lock(timeout?: number): Promise<void>;
|
|
789
|
+
/**
|
|
790
|
+
* Attempts to acquire the lock without waiting.
|
|
791
|
+
* @returns `true` if the lock was acquired, `false` otherwise.
|
|
792
|
+
*/
|
|
793
|
+
tryLock(): boolean;
|
|
794
|
+
/**
|
|
795
|
+
* Releases the lock, scheduling the next waiter according to yieldMode.
|
|
796
|
+
*
|
|
797
|
+
* When a waiter exists, `_locked` intentionally remains `true` — ownership
|
|
798
|
+
* transfers directly to the next waiter without ever clearing the flag.
|
|
799
|
+
* Only when the queue is empty is `_locked` set to false.
|
|
800
|
+
*
|
|
801
|
+
* @throws {Error} If the mutex is not currently locked.
|
|
802
|
+
*/
|
|
803
|
+
unlock(): void;
|
|
804
|
+
/** Returns true if the mutex is currently locked. */
|
|
805
|
+
locked(): boolean;
|
|
806
|
+
/** Returns the number of operations waiting for the lock. */
|
|
807
|
+
pending(): number;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* Interface defining the shape of the EventBus.
|
|
812
|
+
* @template TEventMap - A record mapping event names to their respective payload types.
|
|
813
|
+
*/
|
|
814
|
+
interface EventBus<TEventMap extends Record<string, any>> {
|
|
815
|
+
/**
|
|
816
|
+
* Subscribes to a specific event by name.
|
|
817
|
+
* @param eventName - The name of the event to subscribe to.
|
|
818
|
+
* @param callback - The function to call when the event is emitted.
|
|
819
|
+
* @returns A function to unsubscribe from the event.
|
|
820
|
+
*/
|
|
821
|
+
subscribe: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
822
|
+
/**
|
|
823
|
+
* Subscribes to an event and automatically unsubscribes after it fires once.
|
|
824
|
+
* @param eventName - The name of the event to subscribe to.
|
|
825
|
+
* @param callback - The function to call when the event is emitted.
|
|
826
|
+
* @returns A function to cancel the one-shot subscription before it fires.
|
|
827
|
+
*/
|
|
828
|
+
once: <TEventName extends keyof TEventMap>(eventName: TEventName, callback: (payload: TEventMap[TEventName]) => void) => () => void;
|
|
829
|
+
/**
|
|
830
|
+
* Emits an event with a payload to all subscribed listeners.
|
|
831
|
+
* @param event - An object containing the event name and payload.
|
|
832
|
+
*/
|
|
833
|
+
emit: <TEventName extends keyof TEventMap>(event: {
|
|
834
|
+
name: TEventName;
|
|
835
|
+
payload: TEventMap[TEventName];
|
|
836
|
+
}) => void;
|
|
837
|
+
/**
|
|
838
|
+
* Retrieves metrics about event bus usage.
|
|
839
|
+
* @returns An object containing various metrics.
|
|
840
|
+
*/
|
|
841
|
+
metrics: () => EventMetrics;
|
|
842
|
+
/**
|
|
843
|
+
* Clears all subscriptions and resets metrics.
|
|
844
|
+
* After calling clear(), the bus is fully reset and can be reused —
|
|
845
|
+
* cross-tab communication is re-established if it was previously enabled.
|
|
846
|
+
*/
|
|
847
|
+
clear: () => void;
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Interface defining the metrics tracked by the EventBus.
|
|
851
|
+
*/
|
|
852
|
+
interface EventMetrics {
|
|
853
|
+
/** Total number of events emitted (both sync and deferred paths). */
|
|
854
|
+
totalEvents: number;
|
|
855
|
+
/** Number of active subscriptions across all event names. */
|
|
856
|
+
activeSubscriptions: number;
|
|
857
|
+
/** Map of event names to their emission counts. */
|
|
858
|
+
eventCounts: Map<string, number>;
|
|
859
|
+
/** Average duration of event dispatch in milliseconds. */
|
|
860
|
+
averageEmitDuration: number;
|
|
861
|
+
}
|
|
862
|
+
|
|
731
863
|
interface MiddlewareContext {
|
|
732
864
|
collection?: string;
|
|
733
865
|
documentId?: string;
|
|
@@ -745,13 +877,6 @@ declare class Pipeline {
|
|
|
745
877
|
wrap<T extends object>(target: T, baseContext: Partial<MiddlewareContext>): T;
|
|
746
878
|
}
|
|
747
879
|
|
|
748
|
-
declare class Mutex {
|
|
749
|
-
private queue;
|
|
750
|
-
private locked;
|
|
751
|
-
acquire(): Promise<() => void>;
|
|
752
|
-
private release;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
880
|
interface DocumentOptions<T extends Record<string, any>> {
|
|
756
881
|
/**
|
|
757
882
|
* The already-persisted initial state of the document.
|
|
@@ -760,6 +885,7 @@ interface DocumentOptions<T extends Record<string, any>> {
|
|
|
760
885
|
*/
|
|
761
886
|
initial: Partial<T>;
|
|
762
887
|
collection: string;
|
|
888
|
+
schema: SchemaDefinition;
|
|
763
889
|
validator?: StandardSchemaV1;
|
|
764
890
|
store: Store<T>;
|
|
765
891
|
bus: EventBus<Record<DocumentEventType | TelemetryEventType, DocumentEvent<T> | TelemetryEvent>>;
|
|
@@ -780,13 +906,65 @@ interface DocumentOptions<T extends Record<string, any>> {
|
|
|
780
906
|
declare function createDocument<T extends Record<string, any>>(opts: DocumentOptions<T>): Promise<Document<T & {
|
|
781
907
|
$id: string | number;
|
|
782
908
|
}>>;
|
|
783
|
-
declare function openCollection<T extends Record<string, any>>({ collection:
|
|
909
|
+
declare function openCollection<T extends Record<string, any>>({ collection: schemaName, validator, bus, store, pipeline, validate, schema: schemaDefinition, }: {
|
|
784
910
|
store: Store<T>;
|
|
785
911
|
collection: string;
|
|
786
912
|
validator: StandardSchemaV1;
|
|
787
913
|
bus: EventBus<any>;
|
|
788
914
|
pipeline: Pipeline;
|
|
789
915
|
validate: boolean;
|
|
916
|
+
schema: SchemaDefinition;
|
|
790
917
|
}): Promise<Collection<T>>;
|
|
791
918
|
|
|
792
|
-
|
|
919
|
+
/**
|
|
920
|
+
* Error types for Database operations.
|
|
921
|
+
*/
|
|
922
|
+
declare enum DatabaseErrorType {
|
|
923
|
+
/** The schema does not exist. */
|
|
924
|
+
SCHEMA_NOT_FOUND = "SCHEMA_NOT_FOUND",
|
|
925
|
+
/** The schema already exists. */
|
|
926
|
+
SCHEMA_ALREADY_EXISTS = "SCHEMA_ALREADY_EXISTS",
|
|
927
|
+
/** The schema name is invalid. */
|
|
928
|
+
INVALID_SCHEMA_NAME = "INVALID_SCHEMA_NAME",
|
|
929
|
+
/** The schema definition is invalid. */
|
|
930
|
+
INVALID_SCHEMA_DEFINITION = "INVALID_SCHEMA_DEFINITION",
|
|
931
|
+
/** The database subscription failed. */
|
|
932
|
+
SUBSCRIPTION_FAILED = "SUBSCRIPTION_FAILED",
|
|
933
|
+
/** The database operation failed due to an internal error. */
|
|
934
|
+
INTERNAL_ERROR = "INTERNAL_ERROR",
|
|
935
|
+
/** Data being entered into a collection does not satisfy its schema definition. */
|
|
936
|
+
INVALID_DATA = "INVALID_DATA",
|
|
937
|
+
/** Optimistic Concurrency Control version mismatches */
|
|
938
|
+
CONFLICT = "CONFLICT",
|
|
939
|
+
/** For retryable store locks */
|
|
940
|
+
TRANSIENT_ERROR = "TRANSIENT_ERROR",
|
|
941
|
+
TRANSACTION_FAILED = "TRANSACTION_FAILED",
|
|
942
|
+
CONNECTION_FAILED = "CONNECTION_FAILED",
|
|
943
|
+
INVALID_OPERATION = "INVALID_OPERATION"
|
|
944
|
+
}
|
|
945
|
+
/**
|
|
946
|
+
* Error class for Database operations.
|
|
947
|
+
*/
|
|
948
|
+
declare class DatabaseError extends Error {
|
|
949
|
+
/**
|
|
950
|
+
* The type of error that occurred.
|
|
951
|
+
*/
|
|
952
|
+
type: DatabaseErrorType;
|
|
953
|
+
/**
|
|
954
|
+
* The schema associated with the error, if applicable.
|
|
955
|
+
*/
|
|
956
|
+
schema?: SchemaDefinition;
|
|
957
|
+
/**
|
|
958
|
+
* Issues associated with the error
|
|
959
|
+
*/
|
|
960
|
+
issues?: any[];
|
|
961
|
+
/**
|
|
962
|
+
* Constructs a new DatabaseErrorClass instance.
|
|
963
|
+
* @param type - The type of error that occurred.
|
|
964
|
+
* @param message - A human-readable message describing the error.
|
|
965
|
+
* @param schema - The schema associated with the error, if applicable.
|
|
966
|
+
*/
|
|
967
|
+
constructor(type: DatabaseErrorType, message: string, schema?: SchemaDefinition, cause?: unknown, issues?: any);
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
export { type BufferedOperation, type Collection, type CollectionEvent, type CollectionEventType, type CollectionMigrationOptions, ConnectionManager, type CursorCallback, type CursorCallbackResult, type CursorPaginationOptions, DEFAULT_KEYPATH, type Database, type DatabaseConfig, DatabaseConnection, DatabaseError, DatabaseErrorType, type DatabaseEvent, type DatabaseEventType, type Document, type DocumentEvent, type DocumentEventType, type DocumentMetadata, IndexedDBStore, type Store, type StoreConfig, type StoreKeyRange, type TelemetryEvent, type TelemetryEventType, createDocument, createEphemeralStore, createIndexedDbStore, openCollection };
|