@asaidimu/utils-workspace 2.1.0 → 2.1.1
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/index.d.mts +205 -213
- package/index.d.ts +205 -213
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { QueryFilter, PaginationOptions } from '@asaidimu/query';
|
|
2
|
-
import { SchemaDefinition, SchemaChange, DataTransform } from '@asaidimu/anansi';
|
|
2
|
+
import { IndexDefinition, SchemaDefinition, SchemaChange, DataTransform } from '@asaidimu/anansi';
|
|
3
3
|
|
|
4
4
|
type UUID = string;
|
|
5
5
|
type Timestamp = string;
|
|
@@ -539,14 +539,78 @@ interface TranscriptWindow {
|
|
|
539
539
|
hasMore: boolean;
|
|
540
540
|
}
|
|
541
541
|
|
|
542
|
+
/**
|
|
543
|
+
* Buffers write operations across one or more stores and commits them atomically.
|
|
544
|
+
*
|
|
545
|
+
* ## How atomicity works
|
|
546
|
+
*
|
|
547
|
+
* ### IndexedDB stores (same database)
|
|
548
|
+
* At commit time, TransactionContext collects the names of every IDB store that
|
|
549
|
+
* received operations, then opens a **single** `IDBTransaction` spanning all of
|
|
550
|
+
* them via `ConnectionManager.openTransaction`. Each store's `executeInTransaction`
|
|
551
|
+
* receives that shared transaction object and performs its writes against it
|
|
552
|
+
* without opening a new transaction of its own. IDB commits or aborts the
|
|
553
|
+
* entire multi-store transaction as one unit.
|
|
554
|
+
*
|
|
555
|
+
* ### MemoryStore
|
|
556
|
+
* MemoryStore's `executeInTransaction` receives `null` for the shared transaction.
|
|
557
|
+
* It applies ops against an internal staging map and returns. If a later
|
|
558
|
+
* participant fails, TransactionContext calls `rollbackMemory` on each
|
|
559
|
+
* MemoryStore that already applied its staged ops. MemoryStore restores its
|
|
560
|
+
* pre-transaction snapshot.
|
|
561
|
+
*
|
|
562
|
+
* ### Mixed (IDB + Memory in the same transaction)
|
|
563
|
+
* All IDB stores are committed first as a single atomic IDB transaction, then
|
|
564
|
+
* each MemoryStore is committed. If a MemoryStore fails after IDB has already
|
|
565
|
+
* committed, the IDB side cannot be rolled back — this is an inherent limitation
|
|
566
|
+
* of mixing two different storage engines. In practice the schema store is
|
|
567
|
+
* always MemoryStore-or-IDB consistently, so mixed transactions should not arise
|
|
568
|
+
* in normal usage.
|
|
569
|
+
*/
|
|
542
570
|
declare class TransactionContext {
|
|
543
571
|
readonly id: string;
|
|
544
|
-
|
|
545
|
-
|
|
572
|
+
/**
|
|
573
|
+
* Flat list of every operation staged so far, in the order they were added.
|
|
574
|
+
* We keep the store reference alongside the op so commit() can group them.
|
|
575
|
+
*/
|
|
576
|
+
private staged;
|
|
577
|
+
private done;
|
|
546
578
|
constructor();
|
|
547
|
-
|
|
579
|
+
/**
|
|
580
|
+
* Stages a single write operation against a store.
|
|
581
|
+
* Does NOT touch the store — no I/O happens until commit().
|
|
582
|
+
*/
|
|
583
|
+
addOp<T extends Record<string, any>>(store: Store<T>, type: "put" | "delete" | "add", data: any): Promise<void>;
|
|
584
|
+
/**
|
|
585
|
+
* Commits all staged operations atomically.
|
|
586
|
+
*
|
|
587
|
+
* For IDB stores: opens one shared IDBTransaction across all participating
|
|
588
|
+
* stores, then dispatches ops to each store's executeInTransaction.
|
|
589
|
+
* For MemoryStores: dispatches sequentially; rolls back on failure.
|
|
590
|
+
*/
|
|
548
591
|
commit(): Promise<void>;
|
|
592
|
+
/**
|
|
593
|
+
* Discards all staged operations. No I/O has occurred so there is nothing
|
|
594
|
+
* to undo — we simply clear the buffer.
|
|
595
|
+
*/
|
|
549
596
|
rollback(): void;
|
|
597
|
+
/**
|
|
598
|
+
* Opens ONE IDBTransaction across all participating IDB stores and lets
|
|
599
|
+
* each store execute its ops against the shared transaction handle.
|
|
600
|
+
*
|
|
601
|
+
* We obtain the IDBDatabase from the first store (they all share the same
|
|
602
|
+
* ConnectionManager / database) and open the transaction ourselves so that
|
|
603
|
+
* the commit/abort lifecycle belongs entirely to this method.
|
|
604
|
+
*/
|
|
605
|
+
private commitIDB;
|
|
606
|
+
/**
|
|
607
|
+
* Commits MemoryStore groups sequentially.
|
|
608
|
+
* Maintains a list of stores that have already applied their ops; if any
|
|
609
|
+
* store throws, all previously-applied stores are rolled back via the
|
|
610
|
+
* store-level `_rollbackMemory(snapshot)` escape hatch.
|
|
611
|
+
*/
|
|
612
|
+
private commitMemory;
|
|
613
|
+
completed(): boolean;
|
|
550
614
|
}
|
|
551
615
|
|
|
552
616
|
interface CursorCallbackResult<T> {
|
|
@@ -560,8 +624,9 @@ interface CursorCallbackResult<T> {
|
|
|
560
624
|
* @template T - The type of records stored.
|
|
561
625
|
* @param value - The current record value (cloned, not a live reference).
|
|
562
626
|
* @param key - The key (ID) of the current record.
|
|
563
|
-
* @param cursor - The underlying cursor object (implementation
|
|
564
|
-
* @returns A promise
|
|
627
|
+
* @param cursor - The underlying cursor object (implementation-specific; may be `null` in memory adapters).
|
|
628
|
+
* @returns A promise resolving to an object indicating whether iteration should stop,
|
|
629
|
+
* and an optional offset to advance.
|
|
565
630
|
*/
|
|
566
631
|
type CursorCallback<T> = (value: T, key: string | number, cursor: any) => Promise<CursorCallbackResult<T>>;
|
|
567
632
|
/**
|
|
@@ -573,123 +638,100 @@ interface StoreKeyRange {
|
|
|
573
638
|
lowerOpen?: boolean;
|
|
574
639
|
upperOpen?: boolean;
|
|
575
640
|
}
|
|
641
|
+
/**
|
|
642
|
+
* A single buffered operation staged inside a TransactionContext.
|
|
643
|
+
* Kept intentionally minimal — the context only needs to know what to
|
|
644
|
+
* replay against a store during commit.
|
|
645
|
+
*/
|
|
646
|
+
type BufferedOperation<T> = {
|
|
647
|
+
type: "add" | "put";
|
|
648
|
+
data: T | T[];
|
|
649
|
+
} | {
|
|
650
|
+
type: "delete";
|
|
651
|
+
data: string | number | (string | number)[];
|
|
652
|
+
};
|
|
576
653
|
/**
|
|
577
654
|
* Storage adapter interface for a single object store (collection).
|
|
578
655
|
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
656
|
+
* Stores own their indexes. Index lifecycle (create, drop) and index-aware reads
|
|
657
|
+
* (findByIndex) are part of this contract so that both MemoryStore and IndexedDBStore
|
|
658
|
+
* implement them natively — MemoryStore via in-memory index maps, IndexedDB via its
|
|
659
|
+
* native index mechanism.
|
|
583
660
|
*
|
|
584
|
-
* @template T - The type of objects stored
|
|
661
|
+
* @template T - The type of objects stored. Must include the key path property.
|
|
585
662
|
*/
|
|
586
|
-
interface Store<T
|
|
663
|
+
interface Store<T extends Record<string, any> = Record<string, any>> {
|
|
664
|
+
/**
|
|
665
|
+
* Returns the name of this store (the IDB object store / collection name).
|
|
666
|
+
* Used by TransactionContext to group operations and open a correctly-scoped
|
|
667
|
+
* multi-store IDB transaction at commit time.
|
|
668
|
+
*/
|
|
669
|
+
name(): string;
|
|
670
|
+
/**
|
|
671
|
+
* Opens the store, ensuring underlying storage structures exist.
|
|
672
|
+
*/
|
|
673
|
+
open(): Promise<void>;
|
|
587
674
|
/**
|
|
588
675
|
* Adds one or more records to the store.
|
|
589
|
-
*
|
|
590
676
|
* If a record does not have a value for the store's key path, an automatic
|
|
591
|
-
* key
|
|
592
|
-
* property is then updated on the added record(s).
|
|
593
|
-
*
|
|
594
|
-
* @param data - A single record or an array of records to add.
|
|
595
|
-
* @returns A promise that resolves to:
|
|
596
|
-
* - the key(s) of the added record(s) – a single key if `data` was a single record,
|
|
597
|
-
* or an array of keys if `data` was an array.
|
|
598
|
-
* @throws {Error} If any record lacks the key path property and auto‑keying is not supported,
|
|
599
|
-
* or if a record with the same key already exists.
|
|
677
|
+
* key may be assigned. Throws if a record with the same key already exists.
|
|
600
678
|
*/
|
|
601
679
|
add(data: T | T[]): Promise<string | number | (string | number)[]>;
|
|
602
680
|
/**
|
|
603
|
-
* Removes all records from the store.
|
|
604
|
-
*
|
|
605
|
-
* @returns A promise that resolves when the store is cleared.
|
|
606
|
-
* @throws {Error} If the operation fails (e.g., store is closed).
|
|
681
|
+
* Removes all records from the store without destroying index structures.
|
|
607
682
|
*/
|
|
608
683
|
clear(): Promise<void>;
|
|
609
684
|
/**
|
|
610
685
|
* Returns the total number of records in the store.
|
|
611
|
-
*
|
|
612
|
-
* @returns A promise that resolves to the record count.
|
|
613
|
-
* @throws {Error} If the operation fails.
|
|
614
686
|
*/
|
|
615
687
|
count(): Promise<number>;
|
|
616
688
|
/**
|
|
617
689
|
* Deletes one or more records by their keys.
|
|
618
|
-
*
|
|
619
|
-
* @param id - A single key or an array of keys to delete.
|
|
620
|
-
* @returns A promise that resolves when the records are deleted.
|
|
621
|
-
* @throws {Error} If any key is `undefined` or the operation fails.
|
|
622
690
|
*/
|
|
623
691
|
delete(id: string | number | (string | number)[]): Promise<void>;
|
|
624
692
|
/**
|
|
625
693
|
* Retrieves a single record by its primary key.
|
|
626
|
-
*
|
|
627
|
-
* @param id - The key of the record to retrieve.
|
|
628
|
-
* @returns A promise that resolves to the record (cloned) if found, otherwise `undefined`.
|
|
629
|
-
* @throws {Error} If the key is `undefined` or the operation fails.
|
|
630
694
|
*/
|
|
631
695
|
getById(id: string | number): Promise<T | undefined>;
|
|
632
696
|
/**
|
|
633
|
-
* Retrieves
|
|
697
|
+
* Retrieves the first record matching an exact index key (point lookup).
|
|
698
|
+
* Useful for unique indexes — returns the single matching record or undefined.
|
|
634
699
|
*
|
|
635
|
-
* @param
|
|
636
|
-
* @param key - The exact key value to look up
|
|
637
|
-
* @returns A promise that resolves to the first matching record (cloned), or `undefined` if none.
|
|
638
|
-
* @throws {Error} If the index does not exist, the key is `undefined`, or the operation fails.
|
|
700
|
+
* @param indexName - The name of the index to query.
|
|
701
|
+
* @param key - The exact key value to look up.
|
|
639
702
|
*/
|
|
640
|
-
getByIndex(
|
|
703
|
+
getByIndex(indexName: string, key: any): Promise<T | undefined>;
|
|
641
704
|
/**
|
|
642
|
-
* Retrieves
|
|
705
|
+
* Retrieves all records from a named index, optionally filtered by a key range.
|
|
706
|
+
* Use this for range scans over an index (e.g. all records where age >= 18).
|
|
643
707
|
*
|
|
644
|
-
* @param
|
|
645
|
-
* @param keyRange - Optional
|
|
646
|
-
* @returns A promise that resolves to an array of matching records (each cloned).
|
|
647
|
-
* @throws {Error} If the index does not exist or the operation fails.
|
|
708
|
+
* @param indexName - The name of the index to query.
|
|
709
|
+
* @param keyRange - Optional range to filter results.
|
|
648
710
|
*/
|
|
649
|
-
getByKeyRange(
|
|
711
|
+
getByKeyRange(indexName: string, keyRange?: StoreKeyRange): Promise<T[]>;
|
|
650
712
|
/**
|
|
651
|
-
* Retrieves all records from the store.
|
|
652
|
-
*
|
|
653
|
-
* @returns A promise that resolves to an array of all records (each cloned).
|
|
654
|
-
* @throws {Error} If the operation fails.
|
|
713
|
+
* Retrieves all records from the store without index involvement.
|
|
655
714
|
*/
|
|
656
715
|
getAll(): Promise<T[]>;
|
|
657
716
|
/**
|
|
658
|
-
* Inserts or replaces a record.
|
|
659
|
-
*
|
|
660
|
-
* If a record with the same key already exists, it is replaced.
|
|
661
|
-
* The record must contain the store's key path property.
|
|
662
|
-
*
|
|
663
|
-
* @param data - The record to store.
|
|
664
|
-
* @returns A promise that resolves to the key of the stored record.
|
|
665
|
-
* @throws {Error} If the record lacks the key path property or the operation fails.
|
|
717
|
+
* Inserts or replaces a record. Validates OCC if a record with the same key exists.
|
|
666
718
|
*/
|
|
667
719
|
put(data: T): Promise<string | number>;
|
|
668
720
|
/**
|
|
669
721
|
* Iterates over records using a cursor, allowing early termination and skipping.
|
|
670
722
|
*
|
|
671
|
-
*
|
|
672
|
-
*
|
|
673
|
-
*
|
|
674
|
-
*
|
|
675
|
-
* @param callback - Function called for each record.
|
|
676
|
-
* @param direction - Iteration direction: `"forward"` (ascending keys) or `"backward"` (descending keys).
|
|
677
|
-
* @param keyRange - An optional StoreKeyRange to start from specific points.
|
|
678
|
-
* @returns A promise that resolves to the last record processed (or `null` if none).
|
|
679
|
-
* @throws {Error} If the callback throws or the operation fails.
|
|
723
|
+
* @param callback - Invoked for each record; return `{ done: true }` to stop,
|
|
724
|
+
* `{ offset: n }` to skip ahead n records.
|
|
725
|
+
* @param direction - Iteration order.
|
|
726
|
+
* @param keyRange - Optional range to restrict iteration.
|
|
680
727
|
*/
|
|
681
728
|
cursor(callback: CursorCallback<T>, direction?: "forward" | "backward", keyRange?: StoreKeyRange): Promise<T | null>;
|
|
682
729
|
/**
|
|
683
|
-
* Executes a batch of write operations atomically.
|
|
730
|
+
* Executes a batch of write operations atomically within this store.
|
|
731
|
+
* All operations succeed or fail together.
|
|
684
732
|
*
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
*
|
|
688
|
-
* @param operations - An array of operations. Each operation can be:
|
|
689
|
-
* - `{ type: "add" | "put", data: T | T[] }`
|
|
690
|
-
* - `{ type: "delete", data: string | number | (string | number)[] }`
|
|
691
|
-
* @returns A promise that resolves when the batch is committed.
|
|
692
|
-
* @throws {Error} If any operation fails or the batch cannot be completed.
|
|
733
|
+
* Used for standalone (single-store) atomic writes. For cross-store atomicity,
|
|
734
|
+
* use executeInTransaction instead.
|
|
693
735
|
*/
|
|
694
736
|
batch(operations: Array<{
|
|
695
737
|
type: "add" | "put";
|
|
@@ -698,44 +740,81 @@ interface Store<T = any> {
|
|
|
698
740
|
type: "delete";
|
|
699
741
|
data: string | number | (string | number)[];
|
|
700
742
|
}>): Promise<void>;
|
|
701
|
-
|
|
743
|
+
/**
|
|
744
|
+
* Registers a new index on the store. Idempotent — no-op if the index already exists.
|
|
745
|
+
* For IndexedDB, this triggers a database version upgrade.
|
|
746
|
+
* For MemoryStore, this builds the index map from existing records.
|
|
747
|
+
*
|
|
748
|
+
* @param definition - The full index definition from the schema.
|
|
749
|
+
*/
|
|
750
|
+
createIndex(definition: IndexDefinition): Promise<void>;
|
|
751
|
+
/**
|
|
752
|
+
* Removes a named index from the store.
|
|
753
|
+
* For IndexedDB, this triggers a database version upgrade.
|
|
754
|
+
* For MemoryStore, this drops the in-memory index map.
|
|
755
|
+
*
|
|
756
|
+
* @param name - The index name as declared in IndexDefinition.name.
|
|
757
|
+
*/
|
|
758
|
+
dropIndex(name: string): Promise<void>;
|
|
759
|
+
/**
|
|
760
|
+
* Returns all records matching an exact index key.
|
|
761
|
+
* Unlike getByIndex (which returns only the first match), this returns all matches —
|
|
762
|
+
* essential for non-unique indexes where multiple records share the same indexed value.
|
|
763
|
+
*
|
|
764
|
+
* @param indexName - The name of the index to query.
|
|
765
|
+
* @param value - The exact value to look up.
|
|
766
|
+
*/
|
|
767
|
+
findByIndex(indexName: string, value: any): Promise<T[]>;
|
|
768
|
+
/**
|
|
769
|
+
* Executes a set of buffered operations as part of a cross-store atomic transaction.
|
|
770
|
+
*
|
|
771
|
+
* For IndexedDBStore: `sharedTx` is the single IDBTransaction opened across all
|
|
772
|
+
* participating stores. Operations are applied directly to `sharedTx.objectStore(name)`
|
|
773
|
+
* without opening a new transaction — IDB commits or aborts the whole thing atomically.
|
|
774
|
+
*
|
|
775
|
+
* For MemoryStore: `sharedTx` is null. The store applies ops against its own staging
|
|
776
|
+
* area. The caller (TransactionContext) is responsible for coordinating rollback across
|
|
777
|
+
* all MemoryStores if any participant fails.
|
|
778
|
+
*
|
|
779
|
+
* This method must NOT open, commit, or abort any transaction itself.
|
|
780
|
+
*
|
|
781
|
+
* @param ops - The buffered operations to apply.
|
|
782
|
+
* @param sharedTx - The shared IDBTransaction (IndexedDB only), or null (MemoryStore).
|
|
783
|
+
*/
|
|
784
|
+
executeInTransaction(ops: BufferedOperation<T>[], sharedTx: IDBTransaction | null): Promise<void>;
|
|
702
785
|
}
|
|
703
786
|
interface Collection<T> {
|
|
704
787
|
/**
|
|
705
788
|
* Finds a single document matching the query.
|
|
706
|
-
* @param query - The query to execute.
|
|
707
|
-
* @returns A promise resolving to the matching document or `null` if not found.
|
|
708
789
|
*/
|
|
709
790
|
find: (query: QueryFilter<T>) => Promise<Document<T> | null>;
|
|
710
791
|
/**
|
|
711
|
-
* Lists documents
|
|
712
|
-
*
|
|
713
|
-
* @returns A promise resolving to an array of documents.
|
|
792
|
+
* Lists documents with pagination. Returns an AsyncIterator so consumers can
|
|
793
|
+
* wrap it in their own iteration protocol (e.g. for-await-of via AsyncIterable).
|
|
714
794
|
*/
|
|
715
795
|
list: (query: PaginationOptions) => Promise<AsyncIterator<Document<T>[]>>;
|
|
716
796
|
/**
|
|
717
|
-
* Filters documents
|
|
718
|
-
* @param query - The query to filter documents.
|
|
719
|
-
* @returns A promise resolving to an array of matching documents.
|
|
797
|
+
* Filters all documents matching the query.
|
|
720
798
|
*/
|
|
721
799
|
filter: (query: QueryFilter<T>) => Promise<Document<T>[]>;
|
|
722
800
|
/**
|
|
723
|
-
* Creates a new document in the
|
|
801
|
+
* Creates a new document in the collection.
|
|
802
|
+
*
|
|
803
|
+
* When a TransactionContext is provided the initial store.add is buffered into
|
|
804
|
+
* the transaction rather than written immediately. The document is returned in
|
|
805
|
+
* its fully initialised in-memory state regardless — callers can use it before
|
|
806
|
+
* the transaction commits.
|
|
807
|
+
*
|
|
724
808
|
* @param initial - The initial data for the document.
|
|
725
|
-
* @
|
|
809
|
+
* @param tx - Optional transaction to buffer the write into.
|
|
726
810
|
*/
|
|
727
|
-
create: (initial: T) => Promise<Document<T>>;
|
|
811
|
+
create: (initial: T, tx?: TransactionContext) => Promise<Document<T>>;
|
|
728
812
|
/**
|
|
729
|
-
* Subscribes to
|
|
730
|
-
* @param event - The event type to subscribe to.
|
|
731
|
-
* @param callback - The function to call when the event occurs.
|
|
732
|
-
* @returns A promise resolving to an unsubscribe function.
|
|
813
|
+
* Subscribes to collection-level events.
|
|
733
814
|
*/
|
|
734
|
-
subscribe: (event: CollectionEventType | TelemetryEventType, callback: (event: CollectionEvent<T> | TelemetryEvent) => void) =>
|
|
815
|
+
subscribe: (event: CollectionEventType | TelemetryEventType, callback: (event: CollectionEvent<T> | TelemetryEvent) => void) => () => void;
|
|
735
816
|
/**
|
|
736
|
-
*
|
|
737
|
-
* @param data - The data to validate
|
|
738
|
-
* @returns An object containing validation results
|
|
817
|
+
* Validates data against the collection's schema.
|
|
739
818
|
*/
|
|
740
819
|
validate(data: Record<string, any>): Promise<{
|
|
741
820
|
value?: any;
|
|
@@ -744,9 +823,10 @@ interface Collection<T> {
|
|
|
744
823
|
path: Array<string>;
|
|
745
824
|
}>;
|
|
746
825
|
}>;
|
|
826
|
+
invalidate(): void;
|
|
747
827
|
}
|
|
748
828
|
/**
|
|
749
|
-
* Event payload for
|
|
829
|
+
* Event payload for Collection events.
|
|
750
830
|
*/
|
|
751
831
|
type CollectionEventType = "document:create" | "collection:read" | "migration:start" | "migration:end";
|
|
752
832
|
type CollectionEvent<T> = {
|
|
@@ -759,91 +839,49 @@ type CollectionEvent<T> = {
|
|
|
759
839
|
};
|
|
760
840
|
interface Database {
|
|
761
841
|
/**
|
|
762
|
-
*
|
|
763
|
-
* @param schemaName - The name of the schema to access.
|
|
764
|
-
* @returns A promise resolving to the schema's DocumentCursor.
|
|
765
|
-
* @throws DatabaseError
|
|
842
|
+
* Opens an existing collection by name.
|
|
766
843
|
*/
|
|
767
844
|
collection: <T>(schemaName: string) => Promise<Collection<T>>;
|
|
768
845
|
/**
|
|
769
|
-
* Creates a new schema
|
|
770
|
-
* @param schema - The schema definition.
|
|
771
|
-
* @returns A promise resolving to the created schema's DocumentCursor.
|
|
772
|
-
* @throws DatabaseError
|
|
846
|
+
* Creates a new collection from a schema definition.
|
|
773
847
|
*/
|
|
774
848
|
createCollection: <T>(schema: SchemaDefinition) => Promise<Collection<T>>;
|
|
775
849
|
/**
|
|
776
|
-
* Deletes a schema
|
|
777
|
-
* @param schemaName - The name of the schema to delete.
|
|
778
|
-
* @returns A promise resolving to `true` if successful, or `false` if an error occurs.
|
|
779
|
-
* @throws DatabaseError
|
|
850
|
+
* Deletes a collection and its schema record.
|
|
780
851
|
*/
|
|
781
852
|
deleteCollection: (schemaName: string) => Promise<boolean>;
|
|
782
853
|
/**
|
|
783
|
-
* Updates an existing schema.
|
|
784
|
-
* @param schema - The updated schema definition.
|
|
785
|
-
* @returns A promise resolving to `true` if successful, or `false` if an error occurs.
|
|
786
|
-
* @throws DatabaseError
|
|
854
|
+
* Updates an existing collection's schema record.
|
|
787
855
|
*/
|
|
788
856
|
updateCollection: (schema: SchemaDefinition) => Promise<boolean>;
|
|
789
857
|
/**
|
|
790
|
-
* Migrates an existing collection's data and
|
|
791
|
-
*
|
|
792
|
-
*
|
|
793
|
-
*
|
|
794
|
-
* It will:
|
|
795
|
-
* 1. Verify the target collection exists.
|
|
796
|
-
* 2. Retrieve the collection's current schema definition from a metadata store ($index).
|
|
797
|
-
* 3. Initialize a `MigrationEngine` with this schema.
|
|
798
|
-
* 4. Allow a callback to define specific data transformations using the `MigrationEngine`.
|
|
799
|
-
* 5. **Crucially, it uses `migrationEngine.dryRun()` to get the `newSchema` that results**
|
|
800
|
-
* **from the transformations defined in the callback.**
|
|
801
|
-
* 6. Execute these transformations by streaming data from the collection,
|
|
802
|
-
* through the `MigrationEngine`, and back into the same collection.
|
|
803
|
-
* 7. Finally, update the schema definition for the collection in the `$index` metadata store
|
|
804
|
-
* to reflect this `newSchema`.
|
|
805
|
-
* All these steps for data and metadata updates happen within a single atomic IndexedDB transaction.
|
|
806
|
-
*
|
|
807
|
-
* Note: This function focuses solely on *data transformation* and *metadata updates*.
|
|
808
|
-
* It does NOT handle structural IndexedDB changes like adding/removing physical indexes or object stores,
|
|
809
|
-
* which still require an `onupgradeneeded` event (i.e., a database version upgrade).
|
|
810
|
-
*
|
|
811
|
-
* @param name - The name of the collection (IndexedDB object store) to migrate.
|
|
812
|
-
* @param {Object} opts - Options for the new migration
|
|
813
|
-
* @param {SchemaChange<any>[]} opts.changes - Array of schema changes
|
|
814
|
-
* @param {string} opts.description - Description of the migration
|
|
815
|
-
* @param {SchemaChange<any>[]} [opts.rollback] - Optional rollback changes
|
|
816
|
-
* @param {DataTransform<any, any>} [opts.transform] - Optional data transform
|
|
817
|
-
* @returns A Promise resolving to `true` if the migration completes successfully,
|
|
818
|
-
* @throws {DatabaseError} If the collection does not exist, its schema metadata is missing,
|
|
819
|
-
* or any IndexedDB operation/streaming fails critically.
|
|
858
|
+
* Migrates an existing collection's data and schema definition.
|
|
859
|
+
* Processes data in a streaming fashion to avoid loading the full collection
|
|
860
|
+
* into memory.
|
|
820
861
|
*/
|
|
821
|
-
migrateCollection: (name: string, opts: CollectionMigrationOptions, batchSize?: number) => Promise<
|
|
862
|
+
migrateCollection: <T>(name: string, opts: CollectionMigrationOptions, batchSize?: number) => Promise<Collection<T>>;
|
|
822
863
|
/**
|
|
823
|
-
*
|
|
824
|
-
*
|
|
825
|
-
*
|
|
826
|
-
* @returns A promise resolving to an unsubscribe function.
|
|
864
|
+
* Executes a callback within a TransactionContext.
|
|
865
|
+
* Writes buffered inside the callback are flushed atomically on commit.
|
|
866
|
+
* If the callback throws, the buffer is discarded (no writes are flushed).
|
|
827
867
|
*/
|
|
828
|
-
|
|
868
|
+
transaction: (callback: (tx: TransactionContext) => Promise<void>) => Promise<void>;
|
|
829
869
|
/**
|
|
830
|
-
*
|
|
870
|
+
* Subscribes to database-level events.
|
|
871
|
+
*/
|
|
872
|
+
subscribe: (event: DatabaseEventType | "telemetry", callback: (event: DatabaseEvent | TelemetryEvent) => void) => () => void;
|
|
873
|
+
/**
|
|
874
|
+
* Releases in-memory references and event bus subscriptions.
|
|
875
|
+
* Does not delete any persisted data.
|
|
831
876
|
*/
|
|
832
877
|
close: () => void;
|
|
878
|
+
clear: () => Promise<void>;
|
|
833
879
|
/**
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
* @param schema - The schema definition for the collection.
|
|
837
|
-
* @returns A promise that resolves when the collection exists.
|
|
838
|
-
* @throws {DatabaseError} If validation fails or an unexpected error occurs.
|
|
839
|
-
*/
|
|
880
|
+
* Ensures a collection exists; creates it if it doesn't. Idempotent.
|
|
881
|
+
*/
|
|
840
882
|
ensureCollection: (schema: SchemaDefinition) => Promise<void>;
|
|
841
883
|
/**
|
|
842
|
-
* Ensures multiple collections exist; creates any that don't.
|
|
843
|
-
* Idempotent – safe to call multiple times.
|
|
844
|
-
* @param schemas - An array of schema definitions.
|
|
845
|
-
* @returns A promise that resolves when all collections exist.
|
|
846
|
-
* @throws {DatabaseError} If any schema validation fails or an unexpected error occurs.
|
|
884
|
+
* Ensures multiple collections exist; creates any that don't. Idempotent.
|
|
847
885
|
*/
|
|
848
886
|
setupCollections: (schemas: SchemaDefinition[]) => Promise<void>;
|
|
849
887
|
}
|
|
@@ -853,9 +891,6 @@ type CollectionMigrationOptions = {
|
|
|
853
891
|
rollback?: SchemaChange<any>[];
|
|
854
892
|
transform?: string | DataTransform<any, any>;
|
|
855
893
|
};
|
|
856
|
-
/**
|
|
857
|
-
* Event payload for Database events.
|
|
858
|
-
*/
|
|
859
894
|
type DatabaseEventType = "collection:create" | "collection:delete" | "collection:update" | "collection:read" | "migrate";
|
|
860
895
|
type DatabaseEvent = {
|
|
861
896
|
type: DatabaseEventType;
|
|
@@ -865,60 +900,17 @@ type DatabaseEvent = {
|
|
|
865
900
|
type Document<T> = {
|
|
866
901
|
readonly [K in keyof T]: T[K];
|
|
867
902
|
} & {
|
|
868
|
-
/**
|
|
869
|
-
* Unique identifier for the document (assigned automatically if not provided).
|
|
870
|
-
*/
|
|
871
903
|
$id?: string;
|
|
872
|
-
/**
|
|
873
|
-
* Timestamp of document creation (ISO string or Date).
|
|
874
|
-
*/
|
|
875
904
|
$created?: string | Date;
|
|
876
|
-
/**
|
|
877
|
-
* Timestamp of last document update (ISO string or Date).
|
|
878
|
-
*/
|
|
879
905
|
$updated?: string | Date;
|
|
880
|
-
/**
|
|
881
|
-
* Version number incremented on each change (used for optimistic concurrency control).
|
|
882
|
-
*/
|
|
883
906
|
$version?: number;
|
|
884
|
-
/**
|
|
885
|
-
* Fetches the latest data from the database and updates the document instance.
|
|
886
|
-
* @returns A promise resolving to `true` if successful, or `false` if an error occurs.
|
|
887
|
-
*/
|
|
888
907
|
read: () => Promise<boolean>;
|
|
889
|
-
/**
|
|
890
|
-
* Saves the current document state to the database.
|
|
891
|
-
* Normally called automatically by `update()` or `delete()`, but can be used manually.
|
|
892
|
-
* @returns A promise resolving to `true` if successful, or `false` if an error occurs.
|
|
893
|
-
*/
|
|
894
908
|
save: (tx?: TransactionContext) => Promise<boolean>;
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
* @param props - Partial object containing the fields to update.
|
|
898
|
-
* @returns A promise resolving to `true` if successful, or `false` if an error occurs.
|
|
899
|
-
*/
|
|
900
|
-
update: (props: Partial<T>) => Promise<boolean>;
|
|
901
|
-
/**
|
|
902
|
-
* Deletes the document from the database.
|
|
903
|
-
* @returns A promise resolving to `true` if successful, or `false` if an error occurs.
|
|
904
|
-
*/
|
|
905
|
-
delete: () => Promise<boolean>;
|
|
906
|
-
/**
|
|
907
|
-
* Subscribes to document events (e.g., "update", "delete", "access").
|
|
908
|
-
* @param event - The event type to subscribe to.
|
|
909
|
-
* @param callback - The function to call when the event occurs.
|
|
910
|
-
* @returns An unsubscribe function.
|
|
911
|
-
*/
|
|
909
|
+
update: (props: Partial<T>, tx?: TransactionContext) => Promise<boolean>;
|
|
910
|
+
delete: (tx?: TransactionContext) => Promise<boolean>;
|
|
912
911
|
subscribe: (event: DocumentEventType | TelemetryEventType, callback: (event: DocumentEvent<T> | TelemetryEvent) => void) => () => void;
|
|
913
|
-
/**
|
|
914
|
-
* Returns a plain object containing only the user-defined data (without system fields like $id, $version, etc.).
|
|
915
|
-
* @returns The current user data.
|
|
916
|
-
*/
|
|
917
912
|
state(): T;
|
|
918
913
|
};
|
|
919
|
-
/**
|
|
920
|
-
* Event payload for DocumentModel events.
|
|
921
|
-
*/
|
|
922
914
|
type DocumentEventType = "document:create" | "document:write" | "document:update" | "document:delete" | "document:read";
|
|
923
915
|
type DocumentEvent<T> = {
|
|
924
916
|
type: DocumentEventType;
|
|
@@ -942,7 +934,7 @@ type TelemetryEvent = {
|
|
|
942
934
|
document?: string;
|
|
943
935
|
};
|
|
944
936
|
result?: {
|
|
945
|
-
type:
|
|
937
|
+
type: "array" | string;
|
|
946
938
|
size?: number;
|
|
947
939
|
};
|
|
948
940
|
error: {
|