@incoqnito.io/bajadab 1.2.2 → 1.4.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/src/main/base.ts CHANGED
@@ -1,231 +1,236 @@
1
- /** How a missing id is handled on {@link IBCollection.add}. */
2
- export enum EBAutoIDStrategy {
3
- /** Reject values without an id. */
4
- NO_AUTO_ID = "NO_AUTO_ID",
5
- /** Generate a `uuidv7` and assign it via the configured setter. */
6
- AUTO_ID_UUID = "AUTO_ID_UUID",
7
- }
8
-
9
- /** In-memory representation of a collection's data. */
10
- export enum EBMemStorageStrategy {
11
- /** Keyed by id; `add()` looks up existing entries by id in O(1). */
12
- MAP = "MAP",
13
- // LINKED_LIST = "LINKED_LIST",
14
- /** Plain list; insertion order is preserved. */
15
- ARRAY = "ARRAY",
16
- }
17
-
18
- /** What happens on {@link IBCollection.add} when a value's id already exists. */
19
- export enum EBDuplicateIDStrategy {
20
- /** Replace the existing value. */
21
- OVERWRITE = "OVERWRITE",
22
- /** Reject the whole call. */
23
- ERROR = "ERROR",
24
- /** Keep the existing value, drop the new one. */
25
- IGNORE = "IGNORE",
26
- }
27
-
28
- /** How {@link IBCollection.delete} removes matched items from an `ARRAY` collection. */
29
- export enum EBArrayDeletionStrategy {
30
- /** Build a new array via `filter()`. */
31
- NEW_ARRAY = "NEW_ARRAY",
32
- /** Compact the existing array in place. */
33
- IN_PLACE = "IN_PLACE",
34
- }
35
-
36
- /** When a collection is written to disk after a mutation. */
37
- export enum EBAutoFlushStrategy {
38
- /** Only on an explicit {@link IBCollection.flush} call. */
39
- NO_AUTO_FLUSH = "NO_AUTO_FLUSH",
40
- /** After every mutating call (`add`/`update`/`delete`). */
41
- ALWAYS_AUTO_FLUSH = "ALWAYS_AUTO_FLUSH",
42
- }
43
-
44
- /** What {@link IBCollection.unload} does with unsaved changes. */
45
- export enum EBDirtyUnloadStrategy {
46
- /** Reject the unload. */
47
- ERROR = "ERROR",
48
- /** Flush first, then unload. */
49
- FLUSH = "FLUSH",
50
- /** Discard the unsaved changes silently. */
51
- IGNORE = "IGNORE",
52
- }
53
-
54
- /** Resolves the id of a value; `undefined` means "no id yet". */
55
- export type TGetIDFunction = (v: any) => Promise<string | undefined>;
56
-
57
- /** Assigns an id onto a value. */
58
- export type TSetIDFunction = (v: any, id: string) => Promise<void>;
59
-
60
- /** Extracts an index key (or several, for a multi-valued index) from a value; `undefined` means "not indexed". */
61
- export type TIndexKeyFunction<T = any> = (v: T) => Promise<string | string[] | undefined>;
62
-
63
- /** Per-collection behavior. Passed to {@link IBDatabase.createCollection}/{@link IBDatabase.getCollection}. */
64
- export interface IBCollectionConfig {
65
- autoIDStrategy: EBAutoIDStrategy;
66
- duplicateIDStrategy: EBDuplicateIDStrategy;
67
- memStorageStrategy: EBMemStorageStrategy;
68
- arrayDeletionStrategy: EBArrayDeletionStrategy;
69
- dirtyUnloadStrategy: EBDirtyUnloadStrategy;
70
- autoFlushStrategy: EBAutoFlushStrategy;
71
- /** Registry key for a custom {@link TGetIDFunction}. Omit to use the default (reads `.id`). */
72
- getID?: string;
73
- /** Registry key for a custom {@link TSetIDFunction}. Omit to use the default (sets `.id`). */
74
- setID?: string;
75
- /** Index name → registry key of a {@link TIndexKeyFunction} for that index. Omit for no indexes. */
76
- indexes?: { [indexKey: string]: string };
77
- }
78
-
79
- /** Database-wide configuration. */
80
- export interface IBDatabaseConfig {
81
- /** Used for any collection created without an explicit config. */
82
- readonly defaultCollectionConfig: IBCollectionConfig;
83
- }
84
-
85
- /** Options for {@link IBDatabase.snapshot}. */
86
- export interface IBSnapshotOptions {
87
- /** Appended to the version folder's timestamp. Letters, digits, `-` and `_` only. */
88
- label?: string;
89
- /** Older version folders under `targetDir` to keep besides the one just created. `0` keeps only the new one. Negative values reject. */
90
- keepLast?: number;
91
- }
92
-
93
- /** A JSON-file-backed database. Obtain one via `getDatabase()`. */
94
- export interface IBDatabase {
95
- readonly config: IBDatabaseConfig;
96
- /** Creates a new collection. Rejects if one with the same (canonicalized) name already exists. */
97
- createCollection<T>(collectionName: string, collectionConfig?: IBCollectionConfig): Promise<IBCollection<T>>;
98
- /** Returns the named collection, creating it with `collectionConfig` (or the database default) if it doesn't exist yet. */
99
- getCollection<T>(collectionName: string, collectionConfig?: IBCollectionConfig): Promise<IBCollection<T>>;
100
- /** Whether a collection with this (canonicalized) name exists. */
101
- hasCollection(collectionName: string): Promise<boolean>;
102
- /** Deletes a collection and invalidates any handle still held on it. Rejects if it doesn't exist. */
103
- dropCollection(collectionName: string): Promise<void>;
104
- /**
105
- * Flushes every loaded collection, then copies the whole database directory into a new, timestamped
106
- * version folder under `targetDir` (created if needed). Blocks all other database operations for the
107
- * duration. See {@link IBSnapshotOptions} for pruning older versions. Returns the new version folder's path.
108
- */
109
- snapshot(targetDir: string, options?: IBSnapshotOptions): Promise<string>;
110
- /**
111
- * Runs `fn` against isolated, in-memory working copies of `collectionNames`. Reads and writes inside `fn`
112
- * are visible only within the transaction. If `fn` resolves, every working copy replaces its collection's
113
- * live state and is flushed, then `ADD`/`UPDATE`/`DELETE` handlers fire once per net change between the
114
- * state before the transaction and the committed state - a value added and later deleted within the same
115
- * transaction fires nothing. If `fn` throws, nothing is applied, nothing is flushed, and no handler fires.
116
- * Only collections named in `collectionNames` can be reached from within `fn`.
117
- */
118
- transaction(collectionNames: string[], fn: (tx: IBTransaction) => Promise<void>): Promise<void>;
119
- }
120
-
121
- /** What kind of collection mutation a handler subscribes to via {@link IBCollection.on}. */
122
- export enum EBModificationType {
123
- /** A value was stored by `add()` (including an id-based overwrite). */
124
- ADD = "ADD",
125
- /** A value was replaced by `update()`. */
126
- UPDATE = "UPDATE",
127
- /** A value was removed by `delete()`. */
128
- DELETE = "DELETE",
129
- }
130
-
131
- /** Handler for {@link EBModificationType.ADD}: called with each value stored by `add()`. */
132
- export type TAddHandler<T> = (added: T) => void | Promise<void>;
133
- /** Handler for {@link EBModificationType.UPDATE}: called with the previous and the replacement value. */
134
- export type TUpdateHandler<T> = (previous: T, updated: T) => void | Promise<void>;
135
- /** Handler for {@link EBModificationType.DELETE}: called with each value removed by `delete()`. */
136
- export type TDeleteHandler<T> = (deleted: T) => void | Promise<void>;
137
-
138
- /** Handle returned by {@link IBCollection.on}. */
139
- export interface IHandlerRegistration {
140
- /** Unsubscribes the handler. Idempotent. */
141
- cancel(): Promise<void>;
142
- }
143
-
144
- /** Whether a handler registered via {@link IBCollection.on} blocks the call that triggered it. */
145
- export enum EBHandlerMode {
146
- /** The triggering `add()`/`update()`/`delete()` call doesn't resolve until this handler has run. Default. */
147
- SYNC = "SYNC",
148
- /** The handler runs without the triggering call waiting for it. */
149
- ASYNC = "ASYNC",
150
- }
151
-
152
- /** A single collection of values of type `T`. Obtain one via {@link IBDatabase}. */
153
- export interface IBCollection<T = any> {
154
- readonly database: IBDatabase;
155
- readonly collectionConfig: IBCollectionConfig;
156
- /** Canonicalized (trimmed, lowercased) name. */
157
- readonly collectionName: string;
158
- /** Stable identity used to address this collection's storage, independent of its name. */
159
- readonly collectionID: string;
160
-
161
- /** All items, or only those matching `predicate`. Always a defensive copy, never the live storage. */
162
- get(predicate?: (v: T) => boolean): Promise<T[]>;
163
- /** Deletes matching items. Returns the number removed. */
164
- delete(predicate: (v: T) => boolean): Promise<number>;
165
- /** Whether any item matches `predicate`. */
166
- has(predicate: (v: T) => boolean): Promise<boolean>;
167
- /** Adds values, resolving/assigning ids per the collection's id strategies. Returns the number added. */
168
- add(...v: T[]): Promise<number>;
169
- /** Replaces each item matching `predicate` with the (defined) result of `updater`. Returns the number updated. */
170
- update(predicate: (v: T) => boolean, updater: (v: T) => Promise<T>): Promise<number>;
171
- /** Number of items, or only those matching `predicate`. */
172
- count(predicate?: (v: T) => boolean): Promise<number>;
173
- /** Items whose {@link IBCollectionConfig.indexes}-configured `indexKey` extracts `key`. Always a defensive copy. Throws if `indexKey` isn't configured. */
174
- getByIndex(indexKey: string, key: string): Promise<T[]>;
175
- /** Subscribes to `add()` mutations. Fires after the value is stored, including any auto-flush to disk. `mode` defaults to {@link EBHandlerMode.SYNC}. A handler's own errors never fail the triggering call; they're logged only. */
176
- on(modificationType: EBModificationType.ADD, handler: TAddHandler<T>, mode?: EBHandlerMode): Promise<IHandlerRegistration>;
177
- /** Subscribes to `update()` mutations. Fires after the value is replaced, including any auto-flush to disk. `mode` defaults to {@link EBHandlerMode.SYNC}. A handler's own errors never fail the triggering call; they're logged only. */
178
- on(modificationType: EBModificationType.UPDATE, handler: TUpdateHandler<T>, mode?: EBHandlerMode): Promise<IHandlerRegistration>;
179
- /** Subscribes to `delete()` mutations. Fires after the value is removed, including any auto-flush to disk. `mode` defaults to {@link EBHandlerMode.SYNC}. A handler's own errors never fail the triggering call; they're logged only. */
180
- on(modificationType: EBModificationType.DELETE, handler: TDeleteHandler<T>, mode?: EBHandlerMode): Promise<IHandlerRegistration>;
181
-
182
- /** Writes the current in-memory state to disk. */
183
- flush(): Promise<void>;
184
- /** Discards in-memory state and re-reads it from disk. */
185
- reload(): Promise<void>;
186
- /** Evicts the in-memory state (per the dirty-unload strategy if there are unsaved changes). */
187
- unload(): Promise<void>;
188
-
189
- }
190
-
191
- /**
192
- * Transaction-scoped view of a collection, returned by {@link IBTransaction.getCollection}. Deliberately
193
- * narrower than {@link IBCollection}: no `flush`/`reload`/`unload`/`on` here - flushing would write the
194
- * transaction's not-yet-committed state to disk, and `on()` would register a handler against a working copy
195
- * that either gets discarded (rolled back) or replaced (committed), neither of which is what a caller means
196
- * by "subscribe to this collection".
197
- */
198
- export interface IBTransactionCollection<T = any> {
199
- readonly collectionName: string;
200
- readonly collectionID: string;
201
- /** Same as {@link IBCollection.get}, scoped to this transaction's in-progress state. */
202
- get(predicate?: (v: T) => boolean): Promise<T[]>;
203
- /** Same as {@link IBCollection.has}, scoped to this transaction's in-progress state. */
204
- has(predicate: (v: T) => boolean): Promise<boolean>;
205
- /** Same as {@link IBCollection.count}, scoped to this transaction's in-progress state. */
206
- count(predicate?: (v: T) => boolean): Promise<number>;
207
- /** Same as {@link IBCollection.getByIndex}, scoped to this transaction's in-progress state. */
208
- getByIndex(indexKey: string, key: string): Promise<T[]>;
209
- /** Same as {@link IBCollection.add}, applied only within this transaction until it commits. */
210
- add(...v: T[]): Promise<number>;
211
- /** Same as {@link IBCollection.update}, applied only within this transaction until it commits. */
212
- update(predicate: (v: T) => boolean, updater: (v: T) => Promise<T>): Promise<number>;
213
- /** Same as {@link IBCollection.delete}, applied only within this transaction until it commits. */
214
- delete(predicate: (v: T) => boolean): Promise<number>;
215
- }
216
-
217
- /** Passed into {@link IBDatabase.transaction}'s callback; the only way to reach the collections it declared. */
218
- export interface IBTransaction {
219
- /**
220
- * The transaction-scoped view of `collectionName`. Returns the same instance on repeat calls with the
221
- * same (canonicalized) name within one transaction. Throws if `collectionName` wasn't declared to
222
- * {@link IBDatabase.transaction}.
223
- */
224
- getCollection<T = any>(collectionName: string): Promise<IBTransactionCollection<T>>;
225
- }
226
-
227
- /** Resolves the custom id functions referenced by {@link IBCollectionConfig.getID}/`setID`. */
228
- export interface IBFunctionRegistry {
229
- /** Returns the function registered under `key`, or `undefined` if there is none. */
230
- fetch(key?: string): Function | undefined;
231
- }
1
+ /** How a missing id is handled on {@link IBCollection.add}. */
2
+ export enum EBAutoIDStrategy {
3
+ /** Reject values without an id. */
4
+ NO_AUTO_ID = "NO_AUTO_ID",
5
+ /** Generate a `uuidv7` and assign it via the configured setter. */
6
+ AUTO_ID_UUID = "AUTO_ID_UUID",
7
+ }
8
+
9
+ /** In-memory representation of a collection's data. */
10
+ export enum EBMemStorageStrategy {
11
+ /** Keyed by id; `add()` looks up existing entries by id in O(1). */
12
+ MAP = "MAP",
13
+ // LINKED_LIST = "LINKED_LIST",
14
+ /** Plain list; insertion order is preserved. */
15
+ ARRAY = "ARRAY",
16
+ }
17
+
18
+ /** What happens on {@link IBCollection.add} when a value's id already exists. */
19
+ export enum EBDuplicateIDStrategy {
20
+ /** Replace the existing value. */
21
+ OVERWRITE = "OVERWRITE",
22
+ /** Reject the whole call. */
23
+ ERROR = "ERROR",
24
+ /** Keep the existing value, drop the new one. */
25
+ IGNORE = "IGNORE",
26
+ }
27
+
28
+ /** How {@link IBCollection.delete} removes matched items from an `ARRAY` collection. */
29
+ export enum EBArrayDeletionStrategy {
30
+ /** Build a new array via `filter()`. */
31
+ NEW_ARRAY = "NEW_ARRAY",
32
+ /** Compact the existing array in place. */
33
+ IN_PLACE = "IN_PLACE",
34
+ }
35
+
36
+ /** When a collection is written to disk after a mutation. */
37
+ export enum EBAutoFlushStrategy {
38
+ /** Only on an explicit {@link IBCollection.flush} call. */
39
+ NO_AUTO_FLUSH = "NO_AUTO_FLUSH",
40
+ /** After every mutating call (`add`/`update`/`delete`). If that write fails, the call rejects, but its change stays applied in memory (written by the next flush) and its handlers don't fire. */
41
+ ALWAYS_AUTO_FLUSH = "ALWAYS_AUTO_FLUSH",
42
+ }
43
+
44
+ /** What {@link IBCollection.unload} does with unsaved changes. */
45
+ export enum EBDirtyUnloadStrategy {
46
+ /** Reject the unload. */
47
+ ERROR = "ERROR",
48
+ /** Flush first, then unload. */
49
+ FLUSH = "FLUSH",
50
+ /** Discard the unsaved changes silently. */
51
+ IGNORE = "IGNORE",
52
+ }
53
+
54
+ /** Resolves the id of a value; `undefined` means "no id yet". */
55
+ export type TGetIDFunction = (v: any) => Promise<string | undefined>;
56
+
57
+ /** Assigns an id onto a value. */
58
+ export type TSetIDFunction = (v: any, id: string) => Promise<void>;
59
+
60
+ /** Extracts an index key (or several, for a multi-valued index) from a value; `undefined` means "not indexed". */
61
+ export type TIndexKeyFunction<T = any> = (v: T) => Promise<string | string[] | undefined>;
62
+
63
+ /** Per-collection behavior. Passed to {@link IBDatabase.createCollection}/{@link IBDatabase.getCollection}. */
64
+ export interface IBCollectionConfig {
65
+ autoIDStrategy: EBAutoIDStrategy;
66
+ duplicateIDStrategy: EBDuplicateIDStrategy;
67
+ memStorageStrategy: EBMemStorageStrategy;
68
+ arrayDeletionStrategy: EBArrayDeletionStrategy;
69
+ dirtyUnloadStrategy: EBDirtyUnloadStrategy;
70
+ autoFlushStrategy: EBAutoFlushStrategy;
71
+ /** Registry key for a custom {@link TGetIDFunction}. Omit to use the default (reads `.id`). */
72
+ getID?: string;
73
+ /** Registry key for a custom {@link TSetIDFunction}. Omit to use the default (sets `.id`). */
74
+ setID?: string;
75
+ /** Index name → registry key of a {@link TIndexKeyFunction} for that index. Omit for no indexes. */
76
+ indexes?: { [indexKey: string]: string };
77
+ }
78
+
79
+ /** Database-wide configuration. */
80
+ export interface IBDatabaseConfig {
81
+ /** Used for any collection created without an explicit config. */
82
+ readonly defaultCollectionConfig: IBCollectionConfig;
83
+ }
84
+
85
+ /** Options for {@link IBDatabase.snapshot}. */
86
+ export interface IBSnapshotOptions {
87
+ /** Appended to the version folder's timestamp. Letters, digits, `-` and `_` only. */
88
+ label?: string;
89
+ /** Older version folders under `targetDir` to keep besides the one just created. `0` keeps only the new one. Negative values reject. */
90
+ keepLast?: number;
91
+ }
92
+
93
+ /** A JSON-file-backed database. Obtain one via `getDatabase()`. */
94
+ export interface IBDatabase {
95
+ readonly config: IBDatabaseConfig;
96
+ /** Creates a new collection. Rejects if one with the same (canonicalized) name already exists. */
97
+ createCollection<T>(collectionName: string, collectionConfig?: IBCollectionConfig): Promise<IBCollection<T>>;
98
+ /** Returns the named collection, creating it with `collectionConfig` (or the database default) if it doesn't exist yet. */
99
+ getCollection<T>(collectionName: string, collectionConfig?: IBCollectionConfig): Promise<IBCollection<T>>;
100
+ /** Whether a collection with this (canonicalized) name exists. */
101
+ hasCollection(collectionName: string): Promise<boolean>;
102
+ /** Deletes a collection and invalidates any handle still held on it. Rejects if it doesn't exist. */
103
+ dropCollection(collectionName: string): Promise<void>;
104
+ /**
105
+ * Flushes every loaded collection, then copies the whole database directory into a new, timestamped
106
+ * version folder under `targetDir` (created if needed; must not be inside the database directory). Blocks all other database operations for the
107
+ * duration. See {@link IBSnapshotOptions} for pruning older versions. Returns the new version folder's path.
108
+ */
109
+ snapshot(targetDir: string, options?: IBSnapshotOptions): Promise<string>;
110
+ /**
111
+ * Runs `fn` against isolated, in-memory working copies of `collectionNames`, which must all exist. Reads and
112
+ * writes inside `fn` are visible only within the transaction. If `fn` resolves, every working copy is written
113
+ * to a temp file first - if any of those writes fails, nothing is applied - then all of them replace their
114
+ * files and their collections' live state, and only then do `ADD`/`UPDATE`/`DELETE` handlers fire: once per
115
+ * id the transaction touched, typed by the last operation on it, same as outside a transaction - a value
116
+ * added and later deleted within the same transaction fires nothing. If `fn` throws, nothing is applied,
117
+ * nothing is flushed, and no handler fires.
118
+ * Only collections named in `collectionNames` can be reached from within `fn`; writing to one of them through
119
+ * its regular {@link IBCollection} handle inside `fn` rejects, as does registering a handler on it via `on()`
120
+ * and a nested `transaction()` call.
121
+ * Values mutated in place are shared with the live collection and are neither isolated nor reverted.
122
+ */
123
+ transaction(collectionNames: string[], fn: (tx: IBTransaction) => Promise<void>): Promise<void>;
124
+ }
125
+
126
+ /** What kind of collection mutation a handler subscribes to via {@link IBCollection.on}. */
127
+ export enum EBModificationType {
128
+ /** A value was stored by `add()` (including an id-based overwrite). */
129
+ ADD = "ADD",
130
+ /** A value was replaced by `update()`. */
131
+ UPDATE = "UPDATE",
132
+ /** A value was removed by `delete()`. */
133
+ DELETE = "DELETE",
134
+ }
135
+
136
+ /** Handler for {@link EBModificationType.ADD}: called with each value stored by `add()`. */
137
+ export type TAddHandler<T> = (added: T) => void | Promise<void>;
138
+ /** Handler for {@link EBModificationType.UPDATE}: called with the previous and the replacement value. */
139
+ export type TUpdateHandler<T> = (previous: T, updated: T) => void | Promise<void>;
140
+ /** Handler for {@link EBModificationType.DELETE}: called with each value removed by `delete()`. */
141
+ export type TDeleteHandler<T> = (deleted: T) => void | Promise<void>;
142
+
143
+ /** Handle returned by {@link IBCollection.on}. */
144
+ export interface IHandlerRegistration {
145
+ /** Unsubscribes the handler. Idempotent. */
146
+ cancel(): Promise<void>;
147
+ }
148
+
149
+ /** Whether a handler registered via {@link IBCollection.on} blocks the call that triggered it. */
150
+ export enum EBHandlerMode {
151
+ /** The triggering `add()`/`update()`/`delete()` call doesn't resolve until this handler has run. Default. */
152
+ SYNC = "SYNC",
153
+ /** The handler runs without the triggering call waiting for it, once the database operation that triggered it has finished. */
154
+ ASYNC = "ASYNC",
155
+ }
156
+
157
+ /** A single collection of values of type `T`. Obtain one via {@link IBDatabase}. */
158
+ export interface IBCollection<T = any> {
159
+ readonly database: IBDatabase;
160
+ readonly collectionConfig: IBCollectionConfig;
161
+ /** Canonicalized (trimmed, lowercased) name. */
162
+ readonly collectionName: string;
163
+ /** Stable identity used to address this collection's storage, independent of its name. */
164
+ readonly collectionID: string;
165
+
166
+ /** All items, or only those matching `predicate`. A new array, but holding the stored objects themselves - don't mutate them in place. */
167
+ get(predicate?: (v: T) => boolean): Promise<T[]>;
168
+ /** Deletes matching items. Returns the number removed. */
169
+ delete(predicate: (v: T) => boolean): Promise<number>;
170
+ /** Whether any item matches `predicate`. */
171
+ has(predicate: (v: T) => boolean): Promise<boolean>;
172
+ /** Adds values, resolving/assigning ids per the collection's id strategies. Returns the number added. */
173
+ add(...v: T[]): Promise<number>;
174
+ /** Replaces each item matching `predicate` with the (defined) result of `updater`; all-or-nothing if `updater` throws or returns `undefined`. `updater` receives the stored object - return a new one rather than mutating it, and never change its id. Returns the number updated. */
175
+ update(predicate: (v: T) => boolean, updater: (v: T) => Promise<T>): Promise<number>;
176
+ /** Number of items, or only those matching `predicate`. */
177
+ count(predicate?: (v: T) => boolean): Promise<number>;
178
+ /** Items whose {@link IBCollectionConfig.indexes}-configured `indexKey` extracts `key`. A new array, but holding the stored objects themselves. Throws if `indexKey` isn't configured. */
179
+ getByIndex(indexKey: string, key: string): Promise<T[]>;
180
+ /** Subscribes to `add()` mutations. Fires after the value is stored, including any auto-flush to disk. `mode` defaults to {@link EBHandlerMode.SYNC}. A handler's own errors never fail the triggering call; they're logged only. */
181
+ on(modificationType: EBModificationType.ADD, handler: TAddHandler<T>, mode?: EBHandlerMode): Promise<IHandlerRegistration>;
182
+ /** Subscribes to `update()` mutations. Fires after the value is replaced, including any auto-flush to disk. `mode` defaults to {@link EBHandlerMode.SYNC}. A handler's own errors never fail the triggering call; they're logged only. */
183
+ on(modificationType: EBModificationType.UPDATE, handler: TUpdateHandler<T>, mode?: EBHandlerMode): Promise<IHandlerRegistration>;
184
+ /** Subscribes to `delete()` mutations. Fires after the value is removed, including any auto-flush to disk. `mode` defaults to {@link EBHandlerMode.SYNC}. A handler's own errors never fail the triggering call; they're logged only. */
185
+ on(modificationType: EBModificationType.DELETE, handler: TDeleteHandler<T>, mode?: EBHandlerMode): Promise<IHandlerRegistration>;
186
+
187
+ /** Writes the current in-memory state to disk. */
188
+ flush(): Promise<void>;
189
+ /** Discards in-memory state and re-reads it from disk. */
190
+ reload(): Promise<void>;
191
+ /** Evicts the in-memory state (per the dirty-unload strategy if there are unsaved changes). */
192
+ unload(): Promise<void>;
193
+
194
+ }
195
+
196
+ /**
197
+ * Transaction-scoped view of a collection, returned by {@link IBTransaction.getCollection}. Deliberately
198
+ * narrower than {@link IBCollection}: no `flush`/`reload`/`unload`/`on` here - flushing would write the
199
+ * transaction's not-yet-committed state to disk, and `on()` would register a handler against a working copy
200
+ * that either gets discarded (rolled back) or replaced (committed), neither of which is what a caller means
201
+ * by "subscribe to this collection".
202
+ */
203
+ export interface IBTransactionCollection<T = any> {
204
+ readonly collectionName: string;
205
+ readonly collectionID: string;
206
+ /** Same as {@link IBCollection.get}, scoped to this transaction's in-progress state. */
207
+ get(predicate?: (v: T) => boolean): Promise<T[]>;
208
+ /** Same as {@link IBCollection.has}, scoped to this transaction's in-progress state. */
209
+ has(predicate: (v: T) => boolean): Promise<boolean>;
210
+ /** Same as {@link IBCollection.count}, scoped to this transaction's in-progress state. */
211
+ count(predicate?: (v: T) => boolean): Promise<number>;
212
+ /** Same as {@link IBCollection.getByIndex}, scoped to this transaction's in-progress state. */
213
+ getByIndex(indexKey: string, key: string): Promise<T[]>;
214
+ /** Same as {@link IBCollection.add}, applied only within this transaction until it commits. */
215
+ add(...v: T[]): Promise<number>;
216
+ /** Same as {@link IBCollection.update}, applied only within this transaction until it commits. */
217
+ update(predicate: (v: T) => boolean, updater: (v: T) => Promise<T>): Promise<number>;
218
+ /** Same as {@link IBCollection.delete}, applied only within this transaction until it commits. */
219
+ delete(predicate: (v: T) => boolean): Promise<number>;
220
+ }
221
+
222
+ /** Passed into {@link IBDatabase.transaction}'s callback; the only way to reach the collections it declared. */
223
+ export interface IBTransaction {
224
+ /**
225
+ * The transaction-scoped view of `collectionName`. Returns the same instance on repeat calls with the
226
+ * same (canonicalized) name within one transaction. Throws if `collectionName` wasn't declared to
227
+ * {@link IBDatabase.transaction}. The returned view rejects every call once the transaction has ended.
228
+ */
229
+ getCollection<T = any>(collectionName: string): Promise<IBTransactionCollection<T>>;
230
+ }
231
+
232
+ /** Resolves the custom id functions referenced by {@link IBCollectionConfig.getID}/`setID`. */
233
+ export interface IBFunctionRegistry {
234
+ /** Returns the function registered under `key`, or `undefined` if there is none. */
235
+ fetch(key?: string): Function | undefined;
236
+ }