@incoqnito.io/bajadab 1.2.0 → 1.2.2
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 +43 -0
- package/dist/base.d.ts +56 -0
- package/dist/base.js.map +1 -1
- package/dist/basics.d.ts +26 -1
- package/dist/basics.js +133 -6
- package/dist/basics.js.map +1 -1
- package/dist/fileio.d.ts +3 -1
- package/dist/fileio.js +50 -1
- package/dist/fileio.js.map +1 -1
- package/package.json +1 -1
- package/src/main/base.ts +59 -0
- package/src/main/basics.ts +142 -6
- package/src/main/fileio.ts +207 -154
package/README.md
CHANGED
|
@@ -11,6 +11,8 @@ A lightweight JSON-file-backed database for small, single-machine setups. No ser
|
|
|
11
11
|
- Optional secondary indexes for fast lookup by a derived key.
|
|
12
12
|
- Atomic writes (write-to-temp, then rename) and, on POSIX systems, owner-only file permissions (`0600` files, `0700` directories).
|
|
13
13
|
- In-process concurrency safety per collection and per database.
|
|
14
|
+
- `db.snapshot(targetDir, options?)` to copy the whole database into a new timestamped version folder, optionally pruning older ones.
|
|
15
|
+
- `db.transaction(collectionNames, fn)` to apply reads and writes across several collections as one unit — committed together, or not applied at all.
|
|
14
16
|
|
|
15
17
|
## Install
|
|
16
18
|
|
|
@@ -126,6 +128,47 @@ Collections are addressed by a stable id, not by name, so a handle to a since-re
|
|
|
126
128
|
|
|
127
129
|
Operations on the same collection, and database-level operations (`create`/`get`/`has`/`dropCollection`), are serialized within one process. There is no cross-process locking — multiple processes pointed at the same directory can still race on the underlying files.
|
|
128
130
|
|
|
131
|
+
## Snapshots
|
|
132
|
+
|
|
133
|
+
`db.snapshot(targetDir, options?)` flushes every loaded collection, then copies the whole database directory into a new version folder under `targetDir` (created if it doesn't exist yet). The version folder is named after a sortable timestamp (e.g. `20260904T153012345Z`) and is itself a complete, independent database — open it directly with `getDatabase(versionPath)`.
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
const versionPath = await db.snapshot("./backups");
|
|
137
|
+
// later, e.g. after a bad deploy:
|
|
138
|
+
const restored = await getDatabase(versionPath);
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`targetDir` is a pool that can hold several versions; each call adds one more. Options:
|
|
142
|
+
|
|
143
|
+
| Option | Values | Meaning |
|
|
144
|
+
| --- | --- | --- |
|
|
145
|
+
| `label` | string (optional) | Appended to the version folder's timestamp, e.g. `..._before-deploy`. Letters, digits, `-` and `_` only. |
|
|
146
|
+
| `keepLast` | number (optional) | Older version folders under `targetDir` to keep besides the one just created. `0` keeps only the new one. Omit to keep everything. Negative values reject. |
|
|
147
|
+
|
|
148
|
+
Pruning only ever deletes folders matching bajadab's own naming scheme — anything else you keep in `targetDir` is left alone.
|
|
149
|
+
|
|
150
|
+
`snapshot()` blocks every other operation on the database (same as `dropCollection()`, just across all collections at once) for as long as the copy takes, to guarantee a consistent point-in-time copy. There's no separate `restoreSnapshot()` — restoring means copying a version folder back over the original `basePath` (while nothing has it open), or just pointing `getDatabase()` at the version folder directly.
|
|
151
|
+
|
|
152
|
+
## Transactions
|
|
153
|
+
|
|
154
|
+
`db.transaction(collectionNames, fn)` runs `fn` against isolated, in-memory working copies of the named collections. Reads and writes inside `fn` only see the transaction's own state until it resolves:
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
await db.transaction(["accounts", "orders"], async (tx) => {
|
|
158
|
+
const accounts = await tx.getCollection<Account>("accounts");
|
|
159
|
+
const orders = await tx.getCollection<Order>("orders");
|
|
160
|
+
|
|
161
|
+
await accounts.update(a => a.id === "u1", async a => ({ ...a, balance: a.balance - 10 }));
|
|
162
|
+
await orders.add({ userId: "u1", total: 10 });
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
If `fn` resolves, every declared collection's live state is replaced by its working copy and flushed; `ADD`/`UPDATE`/`DELETE` handlers registered with `on()` fire once per collection, for the net difference between the state before the transaction and the committed state — a value added and later deleted within the same transaction fires nothing, and a value updated twice fires one `UPDATE` carrying the pre-transaction value and the final value. If `fn` throws, nothing is applied, nothing is flushed, and no handler fires — every declared collection stays exactly as it was.
|
|
167
|
+
|
|
168
|
+
`tx.getCollection(name)` only accepts names passed to `transaction()`; anything else throws. It mirrors `IBCollection`'s read/write surface (`get`/`has`/`count`/`getByIndex`/`add`/`update`/`delete`) but not `flush`/`reload`/`unload`/`on` — those don't make sense against a working copy that might still be rolled back.
|
|
169
|
+
|
|
170
|
+
`transaction()` locks every declared collection for its whole duration (like `snapshot()` locks the whole database), so nothing else can read or write them until it resolves. Across collections, disk writes at commit still happen one file at a time — a crash mid-commit can leave a transaction partially applied on disk. There's no cross-process locking here either, same as everywhere else in bajadab.
|
|
171
|
+
|
|
129
172
|
## License
|
|
130
173
|
|
|
131
174
|
See [LICENSE](./LICENSE).
|
package/dist/base.d.ts
CHANGED
|
@@ -72,6 +72,13 @@ export interface IBDatabaseConfig {
|
|
|
72
72
|
/** Used for any collection created without an explicit config. */
|
|
73
73
|
readonly defaultCollectionConfig: IBCollectionConfig;
|
|
74
74
|
}
|
|
75
|
+
/** Options for {@link IBDatabase.snapshot}. */
|
|
76
|
+
export interface IBSnapshotOptions {
|
|
77
|
+
/** Appended to the version folder's timestamp. Letters, digits, `-` and `_` only. */
|
|
78
|
+
label?: string;
|
|
79
|
+
/** Older version folders under `targetDir` to keep besides the one just created. `0` keeps only the new one. Negative values reject. */
|
|
80
|
+
keepLast?: number;
|
|
81
|
+
}
|
|
75
82
|
/** A JSON-file-backed database. Obtain one via `getDatabase()`. */
|
|
76
83
|
export interface IBDatabase {
|
|
77
84
|
readonly config: IBDatabaseConfig;
|
|
@@ -83,6 +90,21 @@ export interface IBDatabase {
|
|
|
83
90
|
hasCollection(collectionName: string): Promise<boolean>;
|
|
84
91
|
/** Deletes a collection and invalidates any handle still held on it. Rejects if it doesn't exist. */
|
|
85
92
|
dropCollection(collectionName: string): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Flushes every loaded collection, then copies the whole database directory into a new, timestamped
|
|
95
|
+
* version folder under `targetDir` (created if needed). Blocks all other database operations for the
|
|
96
|
+
* duration. See {@link IBSnapshotOptions} for pruning older versions. Returns the new version folder's path.
|
|
97
|
+
*/
|
|
98
|
+
snapshot(targetDir: string, options?: IBSnapshotOptions): Promise<string>;
|
|
99
|
+
/**
|
|
100
|
+
* Runs `fn` against isolated, in-memory working copies of `collectionNames`. Reads and writes inside `fn`
|
|
101
|
+
* are visible only within the transaction. If `fn` resolves, every working copy replaces its collection's
|
|
102
|
+
* live state and is flushed, then `ADD`/`UPDATE`/`DELETE` handlers fire once per net change between the
|
|
103
|
+
* state before the transaction and the committed state - a value added and later deleted within the same
|
|
104
|
+
* transaction fires nothing. If `fn` throws, nothing is applied, nothing is flushed, and no handler fires.
|
|
105
|
+
* Only collections named in `collectionNames` can be reached from within `fn`.
|
|
106
|
+
*/
|
|
107
|
+
transaction(collectionNames: string[], fn: (tx: IBTransaction) => Promise<void>): Promise<void>;
|
|
86
108
|
}
|
|
87
109
|
/** What kind of collection mutation a handler subscribes to via {@link IBCollection.on}. */
|
|
88
110
|
export declare enum EBModificationType {
|
|
@@ -146,6 +168,40 @@ export interface IBCollection<T = any> {
|
|
|
146
168
|
/** Evicts the in-memory state (per the dirty-unload strategy if there are unsaved changes). */
|
|
147
169
|
unload(): Promise<void>;
|
|
148
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Transaction-scoped view of a collection, returned by {@link IBTransaction.getCollection}. Deliberately
|
|
173
|
+
* narrower than {@link IBCollection}: no `flush`/`reload`/`unload`/`on` here - flushing would write the
|
|
174
|
+
* transaction's not-yet-committed state to disk, and `on()` would register a handler against a working copy
|
|
175
|
+
* that either gets discarded (rolled back) or replaced (committed), neither of which is what a caller means
|
|
176
|
+
* by "subscribe to this collection".
|
|
177
|
+
*/
|
|
178
|
+
export interface IBTransactionCollection<T = any> {
|
|
179
|
+
readonly collectionName: string;
|
|
180
|
+
readonly collectionID: string;
|
|
181
|
+
/** Same as {@link IBCollection.get}, scoped to this transaction's in-progress state. */
|
|
182
|
+
get(predicate?: (v: T) => boolean): Promise<T[]>;
|
|
183
|
+
/** Same as {@link IBCollection.has}, scoped to this transaction's in-progress state. */
|
|
184
|
+
has(predicate: (v: T) => boolean): Promise<boolean>;
|
|
185
|
+
/** Same as {@link IBCollection.count}, scoped to this transaction's in-progress state. */
|
|
186
|
+
count(predicate?: (v: T) => boolean): Promise<number>;
|
|
187
|
+
/** Same as {@link IBCollection.getByIndex}, scoped to this transaction's in-progress state. */
|
|
188
|
+
getByIndex(indexKey: string, key: string): Promise<T[]>;
|
|
189
|
+
/** Same as {@link IBCollection.add}, applied only within this transaction until it commits. */
|
|
190
|
+
add(...v: T[]): Promise<number>;
|
|
191
|
+
/** Same as {@link IBCollection.update}, applied only within this transaction until it commits. */
|
|
192
|
+
update(predicate: (v: T) => boolean, updater: (v: T) => Promise<T>): Promise<number>;
|
|
193
|
+
/** Same as {@link IBCollection.delete}, applied only within this transaction until it commits. */
|
|
194
|
+
delete(predicate: (v: T) => boolean): Promise<number>;
|
|
195
|
+
}
|
|
196
|
+
/** Passed into {@link IBDatabase.transaction}'s callback; the only way to reach the collections it declared. */
|
|
197
|
+
export interface IBTransaction {
|
|
198
|
+
/**
|
|
199
|
+
* The transaction-scoped view of `collectionName`. Returns the same instance on repeat calls with the
|
|
200
|
+
* same (canonicalized) name within one transaction. Throws if `collectionName` wasn't declared to
|
|
201
|
+
* {@link IBDatabase.transaction}.
|
|
202
|
+
*/
|
|
203
|
+
getCollection<T = any>(collectionName: string): Promise<IBTransactionCollection<T>>;
|
|
204
|
+
}
|
|
149
205
|
/** Resolves the custom id functions referenced by {@link IBCollectionConfig.getID}/`setID`. */
|
|
150
206
|
export interface IBFunctionRegistry {
|
|
151
207
|
/** Returns the function registered under `key`, or `undefined` if there is none. */
|
package/dist/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../src/main/base.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,MAAM,CAAN,IAAY,gBAKX;AALD,WAAY,gBAAgB;IACxB,mCAAmC;IACnC,6CAAyB,CAAA;IACzB,mEAAmE;IACnE,iDAA6B,CAAA;AACjC,CAAC,EALW,gBAAgB,KAAhB,gBAAgB,QAK3B;AAED,uDAAuD;AACvD,MAAM,CAAN,IAAY,oBAMX;AAND,WAAY,oBAAoB;IAC5B,oEAAoE;IACpE,mCAAW,CAAA;IACX,+BAA+B;IAC/B,gDAAgD;IAChD,uCAAe,CAAA;AACnB,CAAC,EANW,oBAAoB,KAApB,oBAAoB,QAM/B;AAED,iFAAiF;AACjF,MAAM,CAAN,IAAY,qBAOX;AAPD,WAAY,qBAAqB;IAC7B,kCAAkC;IAClC,gDAAuB,CAAA;IACvB,6BAA6B;IAC7B,wCAAe,CAAA;IACf,iDAAiD;IACjD,0CAAiB,CAAA;AACrB,CAAC,EAPW,qBAAqB,KAArB,qBAAqB,QAOhC;AAED,wFAAwF;AACxF,MAAM,CAAN,IAAY,uBAKX;AALD,WAAY,uBAAuB;IAC/B,wCAAwC;IACxC,kDAAuB,CAAA;IACvB,2CAA2C;IAC3C,gDAAqB,CAAA;AACzB,CAAC,EALW,uBAAuB,KAAvB,uBAAuB,QAKlC;AAED,6DAA6D;AAC7D,MAAM,CAAN,IAAY,mBAKX;AALD,WAAY,mBAAmB;IAC3B,2DAA2D;IAC3D,sDAA+B,CAAA;IAC/B,2DAA2D;IAC3D,8DAAuC,CAAA;AAC3C,CAAC,EALW,mBAAmB,KAAnB,mBAAmB,QAK9B;AAED,kEAAkE;AAClE,MAAM,CAAN,IAAY,qBAOX;AAPD,WAAY,qBAAqB;IAC7B,yBAAyB;IACzB,wCAAe,CAAA;IACf,gCAAgC;IAChC,wCAAe,CAAA;IACf,4CAA4C;IAC5C,0CAAiB,CAAA;AACrB,CAAC,EAPW,qBAAqB,KAArB,qBAAqB,QAOhC;
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../src/main/base.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,MAAM,CAAN,IAAY,gBAKX;AALD,WAAY,gBAAgB;IACxB,mCAAmC;IACnC,6CAAyB,CAAA;IACzB,mEAAmE;IACnE,iDAA6B,CAAA;AACjC,CAAC,EALW,gBAAgB,KAAhB,gBAAgB,QAK3B;AAED,uDAAuD;AACvD,MAAM,CAAN,IAAY,oBAMX;AAND,WAAY,oBAAoB;IAC5B,oEAAoE;IACpE,mCAAW,CAAA;IACX,+BAA+B;IAC/B,gDAAgD;IAChD,uCAAe,CAAA;AACnB,CAAC,EANW,oBAAoB,KAApB,oBAAoB,QAM/B;AAED,iFAAiF;AACjF,MAAM,CAAN,IAAY,qBAOX;AAPD,WAAY,qBAAqB;IAC7B,kCAAkC;IAClC,gDAAuB,CAAA;IACvB,6BAA6B;IAC7B,wCAAe,CAAA;IACf,iDAAiD;IACjD,0CAAiB,CAAA;AACrB,CAAC,EAPW,qBAAqB,KAArB,qBAAqB,QAOhC;AAED,wFAAwF;AACxF,MAAM,CAAN,IAAY,uBAKX;AALD,WAAY,uBAAuB;IAC/B,wCAAwC;IACxC,kDAAuB,CAAA;IACvB,2CAA2C;IAC3C,gDAAqB,CAAA;AACzB,CAAC,EALW,uBAAuB,KAAvB,uBAAuB,QAKlC;AAED,6DAA6D;AAC7D,MAAM,CAAN,IAAY,mBAKX;AALD,WAAY,mBAAmB;IAC3B,2DAA2D;IAC3D,sDAA+B,CAAA;IAC/B,2DAA2D;IAC3D,8DAAuC,CAAA;AAC3C,CAAC,EALW,mBAAmB,KAAnB,mBAAmB,QAK9B;AAED,kEAAkE;AAClE,MAAM,CAAN,IAAY,qBAOX;AAPD,WAAY,qBAAqB;IAC7B,yBAAyB;IACzB,wCAAe,CAAA;IACf,gCAAgC;IAChC,wCAAe,CAAA;IACf,4CAA4C;IAC5C,0CAAiB,CAAA;AACrB,CAAC,EAPW,qBAAqB,KAArB,qBAAqB,QAOhC;AAqED,4FAA4F;AAC5F,MAAM,CAAN,IAAY,kBAOX;AAPD,WAAY,kBAAkB;IAC1B,uEAAuE;IACvE,iCAAW,CAAA;IACX,0CAA0C;IAC1C,uCAAiB,CAAA;IACjB,yCAAyC;IACzC,uCAAiB,CAAA;AACrB,CAAC,EAPW,kBAAkB,KAAlB,kBAAkB,QAO7B;AAeD,kGAAkG;AAClG,MAAM,CAAN,IAAY,aAKX;AALD,WAAY,aAAa;IACrB,6GAA6G;IAC7G,8BAAa,CAAA;IACb,mEAAmE;IACnE,gCAAe,CAAA;AACnB,CAAC,EALW,aAAa,KAAb,aAAa,QAKxB"}
|
package/dist/basics.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IODatabase } from "./fileio.js";
|
|
2
|
-
import { EBHandlerMode, EBModificationType, IBCollection, IBCollectionConfig, IBDatabase, IBDatabaseConfig, IBFunctionRegistry, IHandlerRegistration, TAddHandler, TDeleteHandler, TGetIDFunction, TSetIDFunction, TUpdateHandler } from "./base.js";
|
|
2
|
+
import { EBHandlerMode, EBModificationType, IBCollection, IBCollectionConfig, IBDatabase, IBDatabaseConfig, IBFunctionRegistry, IBSnapshotOptions, IBTransaction, IHandlerRegistration, TAddHandler, TDeleteHandler, TGetIDFunction, TSetIDFunction, TUpdateHandler } from "./base.js";
|
|
3
3
|
/** Default {@link TGetIDFunction}: reads `v.id`, `undefined` if absent. */
|
|
4
4
|
export declare const DEFAULT_GET_ID: TGetIDFunction;
|
|
5
5
|
/** Default {@link TSetIDFunction}: assigns to `v.id`. */
|
|
@@ -19,6 +19,8 @@ export declare class BDatabase implements IBDatabase {
|
|
|
19
19
|
createCollection<T = any>(collectionName: string, collectionConfig?: IBCollectionConfig): Promise<BCollection<T>>;
|
|
20
20
|
hasCollection(collectionName: string): Promise<boolean>;
|
|
21
21
|
dropCollection(collectionName: string): Promise<void>;
|
|
22
|
+
snapshot(targetDir: string, options?: IBSnapshotOptions): Promise<string>;
|
|
23
|
+
transaction(collectionNames: string[], fn: (tx: IBTransaction) => Promise<void>): Promise<void>;
|
|
22
24
|
}
|
|
23
25
|
export declare class BCollection<T = any> implements IBCollection<T> {
|
|
24
26
|
readonly database: BDatabase;
|
|
@@ -64,6 +66,13 @@ export declare class BCollection<T = any> implements IBCollection<T> {
|
|
|
64
66
|
* value then is a freshly deserialized object the incremental add/update/delete hooks never saw
|
|
65
67
|
*/
|
|
66
68
|
private rebuildIndexRuntime;
|
|
69
|
+
private resolveIDGetter;
|
|
70
|
+
/**
|
|
71
|
+
* id -> value for every stored item, resolved via the plain id getter (no auto-id assignment - every
|
|
72
|
+
* stored item already has one). Used to diff a transaction's working copy against the pre-transaction
|
|
73
|
+
* state in {@link commitTransactionClone}.
|
|
74
|
+
*/
|
|
75
|
+
private idKeyedSnapshot;
|
|
67
76
|
private getID;
|
|
68
77
|
add(...vs: T[]): Promise<number>;
|
|
69
78
|
update(predicate: (v: T) => boolean, updater: (v: T) => Promise<T>): Promise<number>;
|
|
@@ -71,4 +80,20 @@ export declare class BCollection<T = any> implements IBCollection<T> {
|
|
|
71
80
|
flush(): Promise<void>;
|
|
72
81
|
reload(): Promise<void>;
|
|
73
82
|
unload(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Creates a transaction-scoped working copy: same identity/config as this collection, but with
|
|
85
|
+
* independently mutable in-memory state (auto-flush forced off, regardless of this collection's own
|
|
86
|
+
* `autoFlushStrategy`) and no change-event handlers of its own. Call only while already holding this
|
|
87
|
+
* collection's mutex for the whole transaction (see {@link BDatabase.transaction}).
|
|
88
|
+
*/
|
|
89
|
+
cloneForTransaction(): Promise<BCollection<T>>;
|
|
90
|
+
/**
|
|
91
|
+
* Applies a working copy from {@link cloneForTransaction} back onto this collection: replaces the live
|
|
92
|
+
* state, flushes once, then fires `ADD`/`UPDATE`/`DELETE` handlers for the net difference between this
|
|
93
|
+
* collection's state before the transaction and `clone`'s state - not for each intermediate operation the
|
|
94
|
+
* transaction performed. The before/after diff itself (and the id resolution it needs) only runs when at
|
|
95
|
+
* least one handler is registered on this collection - a transaction on a collection nobody listens to
|
|
96
|
+
* skips it entirely. Call only while already holding this collection's mutex for the whole transaction.
|
|
97
|
+
*/
|
|
98
|
+
commitTransactionClone(clone: BCollection<T>): Promise<void>;
|
|
74
99
|
}
|
package/dist/basics.js
CHANGED
|
@@ -79,6 +79,40 @@ export class BDatabase {
|
|
|
79
79
|
}
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
|
+
async snapshot(targetDir, options) {
|
|
83
|
+
const collectionNames = Array.from(this.collections.keys());
|
|
84
|
+
return runMultiReentrantProtected([MutexKeys.DATABASE, ...collectionNames], async () => {
|
|
85
|
+
for (const collection of this.collections.values()) {
|
|
86
|
+
await collection.flush();
|
|
87
|
+
}
|
|
88
|
+
return this.io.snapshot(targetDir, options);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
async transaction(collectionNames, fn) {
|
|
92
|
+
const canonicalNames = Array.from(new Set(collectionNames.map(canonicalName)));
|
|
93
|
+
return runMultiReentrantProtected(canonicalNames, async () => {
|
|
94
|
+
const originals = new Map();
|
|
95
|
+
const clones = new Map();
|
|
96
|
+
for (const name of canonicalNames) {
|
|
97
|
+
const original = await this.getCollection(name);
|
|
98
|
+
originals.set(name, original);
|
|
99
|
+
clones.set(name, await original.cloneForTransaction());
|
|
100
|
+
}
|
|
101
|
+
const tx = {
|
|
102
|
+
getCollection: async (collectionName) => {
|
|
103
|
+
const clone = clones.get(canonicalName(collectionName));
|
|
104
|
+
if (!clone) {
|
|
105
|
+
throw new Error(`collection "${collectionName}" was not declared to this transaction`);
|
|
106
|
+
}
|
|
107
|
+
return clone;
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
await fn(tx);
|
|
111
|
+
for (const name of canonicalNames) {
|
|
112
|
+
await originals.get(name).commitTransactionClone(clones.get(name));
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
82
116
|
}
|
|
83
117
|
export class BCollection {
|
|
84
118
|
database;
|
|
@@ -394,19 +428,40 @@ export class BCollection {
|
|
|
394
428
|
await this.addToIndexes(v);
|
|
395
429
|
}
|
|
396
430
|
}
|
|
397
|
-
|
|
398
|
-
let getter;
|
|
431
|
+
resolveIDGetter() {
|
|
399
432
|
if (this.collectionConfig.getID) {
|
|
400
433
|
const found = this.database.functionRegistry?.fetch(this.collectionConfig.getID);
|
|
401
434
|
if (!found) {
|
|
402
435
|
throw new Error(`getID function "${this.collectionConfig.getID}" is not registered`);
|
|
403
436
|
}
|
|
404
|
-
|
|
437
|
+
return found;
|
|
405
438
|
}
|
|
406
|
-
|
|
407
|
-
|
|
439
|
+
return DEFAULT_GET_ID;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* id -> value for every stored item, resolved via the plain id getter (no auto-id assignment - every
|
|
443
|
+
* stored item already has one). Used to diff a transaction's working copy against the pre-transaction
|
|
444
|
+
* state in {@link commitTransactionClone}.
|
|
445
|
+
*/
|
|
446
|
+
async idKeyedSnapshot() {
|
|
447
|
+
switch (this.collectionConfig.memStorageStrategy) {
|
|
448
|
+
case EBMemStorageStrategy.MAP:
|
|
449
|
+
return new Map(this.mapData);
|
|
450
|
+
default:
|
|
451
|
+
case EBMemStorageStrategy.ARRAY:
|
|
452
|
+
const getter = this.resolveIDGetter();
|
|
453
|
+
const ret = new Map();
|
|
454
|
+
for (const v of this.arrayData) {
|
|
455
|
+
const id = await getter(v);
|
|
456
|
+
if (id) {
|
|
457
|
+
ret.set(id, v);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return ret;
|
|
408
461
|
}
|
|
409
|
-
|
|
462
|
+
}
|
|
463
|
+
async getID(v) {
|
|
464
|
+
let id = await this.resolveIDGetter()(v);
|
|
410
465
|
if (!id) {
|
|
411
466
|
switch (this.collectionConfig.autoIDStrategy) {
|
|
412
467
|
case EBAutoIDStrategy.NO_AUTO_ID:
|
|
@@ -701,5 +756,77 @@ export class BCollection {
|
|
|
701
756
|
this.dirty = false;
|
|
702
757
|
});
|
|
703
758
|
}
|
|
759
|
+
/**
|
|
760
|
+
* Creates a transaction-scoped working copy: same identity/config as this collection, but with
|
|
761
|
+
* independently mutable in-memory state (auto-flush forced off, regardless of this collection's own
|
|
762
|
+
* `autoFlushStrategy`) and no change-event handlers of its own. Call only while already holding this
|
|
763
|
+
* collection's mutex for the whole transaction (see {@link BDatabase.transaction}).
|
|
764
|
+
*/
|
|
765
|
+
async cloneForTransaction() {
|
|
766
|
+
return this.runProtected(async () => {
|
|
767
|
+
await this.checkLoaded();
|
|
768
|
+
const txConfig = { ...this.collectionConfig, autoFlushStrategy: EBAutoFlushStrategy.NO_AUTO_FLUSH };
|
|
769
|
+
const clone = new BCollection(this.database, this.collectionID, this.collectionName, txConfig);
|
|
770
|
+
clone.mapData = new Map(this.mapData);
|
|
771
|
+
clone.arrayData = this.arrayData.slice();
|
|
772
|
+
clone.loaded = true;
|
|
773
|
+
clone.resolveIndexDefinitions();
|
|
774
|
+
await clone.rebuildIndexRuntime();
|
|
775
|
+
return clone;
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Applies a working copy from {@link cloneForTransaction} back onto this collection: replaces the live
|
|
780
|
+
* state, flushes once, then fires `ADD`/`UPDATE`/`DELETE` handlers for the net difference between this
|
|
781
|
+
* collection's state before the transaction and `clone`'s state - not for each intermediate operation the
|
|
782
|
+
* transaction performed. The before/after diff itself (and the id resolution it needs) only runs when at
|
|
783
|
+
* least one handler is registered on this collection - a transaction on a collection nobody listens to
|
|
784
|
+
* skips it entirely. Call only while already holding this collection's mutex for the whole transaction.
|
|
785
|
+
*/
|
|
786
|
+
async commitTransactionClone(clone) {
|
|
787
|
+
return this.runProtected(async () => {
|
|
788
|
+
await this.checkLoaded();
|
|
789
|
+
const added = [];
|
|
790
|
+
const updated = [];
|
|
791
|
+
const deleted = [];
|
|
792
|
+
// the before/after diff only feeds fireAdd()/fireUpdate()/fireDelete() below - skip it
|
|
793
|
+
// entirely (incl. idKeyedSnapshot()'s id-getter calls) when nothing is listening
|
|
794
|
+
const trackChanges = this.addHandlers.length > 0 || this.updateHandlers.length > 0 || this.deleteHandlers.length > 0;
|
|
795
|
+
if (trackChanges) {
|
|
796
|
+
const before = await this.idKeyedSnapshot();
|
|
797
|
+
const after = await clone.idKeyedSnapshot();
|
|
798
|
+
for (const [id, value] of after) {
|
|
799
|
+
if (!before.has(id)) {
|
|
800
|
+
added.push(value);
|
|
801
|
+
}
|
|
802
|
+
else {
|
|
803
|
+
const previous = before.get(id);
|
|
804
|
+
if (JSON.stringify(previous) !== JSON.stringify(value)) {
|
|
805
|
+
updated.push([previous, value]);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
for (const [id, value] of before) {
|
|
810
|
+
if (!after.has(id)) {
|
|
811
|
+
deleted.push(value);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
this.mapData = clone.mapData;
|
|
816
|
+
this.arrayData = clone.arrayData;
|
|
817
|
+
this.indexRuntime = clone.indexRuntime;
|
|
818
|
+
this.dirty = true;
|
|
819
|
+
await this.flush();
|
|
820
|
+
if (added.length > 0) {
|
|
821
|
+
await this.fireAdd(added);
|
|
822
|
+
}
|
|
823
|
+
if (updated.length > 0) {
|
|
824
|
+
await this.fireUpdate(updated);
|
|
825
|
+
}
|
|
826
|
+
if (deleted.length > 0) {
|
|
827
|
+
await this.fireDelete(deleted);
|
|
828
|
+
}
|
|
829
|
+
});
|
|
830
|
+
}
|
|
704
831
|
}
|
|
705
832
|
//# sourceMappingURL=basics.js.map
|
package/dist/basics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"basics.js","sourceRoot":"","sources":["../src/main/basics.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"basics.js","sourceRoot":"","sources":["../src/main/basics.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,SAAS,CAAC;AAE7B,OAAO,EAAE,MAAM,GAAG,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAI7F,OAAO,EACH,uBAAuB,EACvB,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,aAAa,EACb,oBAAoB,EACpB,kBAAkB,GAgBrB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,2EAA2E;AAC3E,MAAM,CAAC,MAAM,cAAc,GAAmB,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACzF,yDAAyD;AACzD,MAAM,CAAC,MAAM,cAAc,GAAmB,KAAK,EAAE,CAAM,EAAE,EAAU,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;AAE3F,IAAW,SAGV;AAHD,WAAW,SAAS;IAChB,uGAAuG;IACvG,oCAAuB,CAAA;AAC3B,CAAC,EAHU,SAAS,KAAT,SAAS,QAGnB;AAED,4FAA4F;AAC5F,MAAM,CAAC,MAAM,yBAAyB,GAAuB;IACzD,qBAAqB,EAAE,uBAAuB,CAAC,QAAQ;IACvD,cAAc,EAAE,gBAAgB,CAAC,YAAY;IAC7C,mBAAmB,EAAE,qBAAqB,CAAC,SAAS;IACpD,kBAAkB,EAAE,oBAAoB,CAAC,GAAG;IAC5C,mBAAmB,EAAE,qBAAqB,CAAC,KAAK;IAChD,iBAAiB,EAAE,mBAAmB,CAAC,iBAAiB;CAC3D,CAAC;AAEF,mFAAmF;AACnF,MAAM,CAAC,MAAM,uBAAuB,GAAqB;IACrD,uBAAuB,EAAE,yBAAyB;CACrD,CAAC;AAEF,MAAM,OAAO,SAAS;IACF,MAAM,CAAmB;IACjC,WAAW,GAA6B,IAAI,GAAG,EAAE,CAAC;IACjD,EAAE,CAAa;IACf,gBAAgB,CAAsB;IAE/C,YAAmB,EAAc,EAAE,MAAyB,EAAE,gBAAqC;QAC/F,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,uBAAuB,CAAC;QAChD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC7C,CAAC;IAEM,aAAa,CAAC,UAAuB;QACxC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IAChE,CAAC;IAEM,KAAK,CAAC,aAAa,CAAI,cAAsB,EAAE,gBAAqC;QACvF,OAAO,qBAAqB,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,KAAK,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;YAC5C,IAAI,GAAG,GAA+B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAClE,IAAI,CAAC,GAAG,EAAE,CAAC;gBACP,GAAG,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;YACxE,CAAC;YACD,OAAO,GAAG,CAAC;QACf,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,gBAAgB,CAAU,cAAsB,EAAE,gBAAqC;QAChG,OAAO,qBAAqB,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,KAAK,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;YAC5C,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,6CAA6C,cAAc,EAAE,CAAC,CAAC;YACnF,CAAC;YACD,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;YACpB,MAAM,GAAG,GAAmB,IAAI,WAAW,CAAI,IAAI,EAAE,EAAE,EAAE,cAAc,EAAE,gBAAgB,IAAI,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;YAClI,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YACxB,OAAO,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAI,GAAG,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,aAAa,CAAC,cAAsB;QAC7C,OAAO,qBAAqB,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YACxD,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,cAAsB;QAC9C,MAAM,KAAK,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;QAC5C,OAAO,0BAA0B,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,KAAK,IAAI,EAAE;YACtE,MAAM,IAAI,GAAgB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAgB,CAAC;YACrE,IAAI,IAAI,EAAE,CAAC;gBACP,IAAI,CAAC,WAAW,EAAE,CAAC;gBACnB,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC/B,OAAO,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAC3C,CAAC;iBACI,CAAC;gBACF,MAAM,IAAI,KAAK,CAAC,sBAAsB,cAAc,EAAE,CAAC,CAAC;YAC5D,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,QAAQ,CAAC,SAAiB,EAAE,OAA2B;QAChE,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5D,OAAO,0BAA0B,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,IAAI,EAAE;YACnF,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC;gBACjD,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;YAC7B,CAAC;YACD,OAAO,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,WAAW,CAAC,eAAyB,EAAE,EAAwC;QACxF,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QAC/E,OAAO,0BAA0B,CAAC,cAAc,EAAE,KAAK,IAAI,EAAE;YACzD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAuB,CAAC;YACjD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;YAC9C,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;gBAChC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAgB,CAAC;gBAC/D,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;gBAC9B,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,QAAQ,CAAC,mBAAmB,EAAE,CAAC,CAAC;YAC3D,CAAC;YACD,MAAM,EAAE,GAAkB;gBACtB,aAAa,EAAE,KAAK,EAAK,cAAsB,EAAuC,EAAE;oBACpF,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC;oBACxD,IAAI,CAAC,KAAK,EAAE,CAAC;wBACT,MAAM,IAAI,KAAK,CAAC,eAAe,cAAc,wCAAwC,CAAC,CAAC;oBAC3F,CAAC;oBACD,OAAO,KAAmC,CAAC;gBAC/C,CAAC;aACJ,CAAC;YACF,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;YACb,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;gBAChC,MAAM,SAAS,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,CAAC;YACzE,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;CAEJ;AAED,MAAM,OAAO,WAAW;IACX,QAAQ,CAAY;IACpB,gBAAgB,CAAqB;IACrC,cAAc,CAAS;IACvB,YAAY,CAAS;IAEtB,OAAO,GAAmB,IAAI,GAAG,EAAE,CAAC;IACpC,SAAS,GAAa,EAAE,CAAC;IACzB,MAAM,GAAY,KAAK,CAAC;IACxB,KAAK,GAAY,KAAK,CAAC;IACvB,OAAO,GAAY,KAAK,CAAC;IAEzB,WAAW,GAA4D,EAAE,CAAC;IAC1E,cAAc,GAA+D,EAAE,CAAC;IAChF,cAAc,GAA+D,EAAE,CAAC;IAEhF,gBAAgB,GAAsC,IAAI,GAAG,EAAE,CAAC;IAChE,YAAY,GAAkC,IAAI,GAAG,EAAE,CAAC;IAEhE,YAAmB,QAAmB,EAAE,YAAoB,EAAE,cAAsB,EAAE,gBAAoC;QACtH,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;QACpD,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,QAAQ,gBAAgB,CAAC,kBAAkB,EAAE,CAAC;YAC1C,KAAK,oBAAoB,CAAC,GAAG;gBACzB,4DAA4D;gBAC5D,kFAAkF;gBAClF,IAAI;gBACJ,MAAM;YACV,QAAQ;YACR,KAAK,oBAAoB,CAAC,KAAK;gBAC3B,MAAM;QACd,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,WAAW;QACrB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QACxB,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,YAAY,CAAI,EAAoB;QAC9C,OAAO,qBAAqB,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC;IAEO,KAAK,CAAC,YAAY,CAAI,EAAoB;QAC9C,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,CAAC,cAAc,oBAAoB,CAAC,CAAC;YAC5E,CAAC;YACD,OAAO,EAAE,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACI,WAAW;QACd,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACxB,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,SAA6B;QAC1C,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,QAAQ,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,CAAC;gBAC/C,KAAK,oBAAoB,CAAC,GAAG;oBACzB,OAAO,CAAC,SAAS,CAAC,CAAC;wBACf,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;wBACjC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;gBAC1D,QAAQ;gBACR,KAAK,oBAAoB,CAAC,KAAK;oBAC3B,OAAO,CAAC,SAAS,CAAC,CAAC;wBACf,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;wBACxB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YAC7C,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,KAAK,CAAC,SAA6B;QAC5C,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,QAAQ,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,CAAC;gBAC/C,KAAK,oBAAoB,CAAC,GAAG;oBACzB,OAAO,CAAC,SAAS,CAAC,CAAC;wBACf,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;wBACnB,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;gBACxE,QAAQ;gBACR,KAAK,oBAAoB,CAAC,KAAK;oBAC3B,OAAO,CAAC,SAAS,CAAC,CAAC;wBACf,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;wBACvB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;YACpD,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,GAAW;QACjD,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC9C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,MAAM,IAAI,KAAK,CAAC,UAAU,QAAQ,qBAAqB,CAAC,CAAC;YAC7D,CAAC;YACD,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzC,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,EAA8B,EAAE,gBAAoC;QAC5F,IAAI,CAAC;YACD,MAAM,EAAE,EAAE,CAAC;QACf,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,KAAK,CAAC,wBAAwB,IAAI,CAAC,cAAc,KAAK,gBAAgB,iBAAiB,EAAE,KAAK,CAAC,CAAC;QAC3G,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,KAAU;QAC5B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACpB,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,GAAG,CAAC,CAAC;gBAC1E,IAAI,IAAI,KAAK,aAAa,CAAC,IAAI,EAAE,CAAC;oBAC9B,MAAM,IAAI,CAAC;gBACf,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,KAAoB;QACzC,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC;YACtC,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBAClD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;gBAC7F,IAAI,IAAI,KAAK,aAAa,CAAC,IAAI,EAAE,CAAC;oBAC9B,MAAM,IAAI,CAAC;gBACf,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,OAAY;QACjC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACtB,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBAClD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;gBAC7E,IAAI,IAAI,KAAK,aAAa,CAAC,IAAI,EAAE,CAAC;oBAC9B,MAAM,IAAI,CAAC;gBACf,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAKM,KAAK,CAAC,EAAE,CAAC,gBAAoC,EAAE,OAA+D,EAAE,IAAI,GAAkB,aAAa,CAAC,IAAI;QAC3J,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,QAAQ,gBAAgB,EAAE,CAAC;gBACvB,KAAK,kBAAkB,CAAC,GAAG,EAAE,CAAC;oBAC1B,MAAM,CAAC,GAAG,OAAyB,CAAC;oBACpC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC5C,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxI,CAAC;gBACD,KAAK,kBAAkB,CAAC,MAAM,EAAE,CAAC;oBAC7B,MAAM,CAAC,GAAG,OAA4B,CAAC;oBACvC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC/C,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE,GAAG,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9I,CAAC;gBACD,KAAK,kBAAkB,CAAC,MAAM,EAAE,CAAC;oBAC7B,MAAM,CAAC,GAAG,OAA4B,CAAC;oBACvC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC/C,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE,GAAG,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9I,CAAC;gBACD;oBACI,MAAM,IAAI,KAAK,CAAC,6BAA6B,gBAAgB,EAAE,CAAC,CAAC;YACzE,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,SAA4B;QAC5C,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;YACpD,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,CAAC;YACpD,MAAM,OAAO,GAAQ,EAAE,CAAC;YACxB,QAAQ,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,CAAC;gBAC/C,KAAK,oBAAoB,CAAC,GAAG;oBACzB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;wBACtC,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;4BACnB,GAAG,EAAE,CAAC;4BACN,IAAI,YAAY,EAAE,CAAC;gCACf,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;4BACxC,CAAC;4BACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;4BACzB,IAAI,YAAY,EAAE,CAAC;gCACf,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;4BACxB,CAAC;wBACL,CAAC;oBACL,CAAC;oBACD,MAAM;gBACV,QAAQ;gBACR,KAAK,oBAAoB,CAAC,KAAK;oBAC3B,QAAQ,IAAI,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,CAAC;wBAClD,KAAK,uBAAuB,CAAC,QAAQ;4BACjC,IAAI,UAAU,GAAG,CAAC,CAAC;4BACnB,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC;gCACrE,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;gCACvC,IAAI,CAAC,SAAS,CAAC,IAAK,CAAC,EAAE,CAAC;oCACpB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,IAAK,CAAC;oCACnC,UAAU,EAAE,CAAC;gCACjB,CAAC;qCACI,CAAC;oCACF,GAAG,EAAE,CAAC;oCACN,IAAI,YAAY,EAAE,CAAC;wCACf,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAK,CAAC,CAAC;oCACxC,CAAC;oCACD,IAAI,YAAY,EAAE,CAAC;wCACf,OAAO,CAAC,IAAI,CAAC,IAAK,CAAC,CAAC;oCACxB,CAAC;gCACL,CAAC;4BACL,CAAC;4BACD,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,UAAU,CAAC;4BACnC,MAAM;wBACV,QAAQ;wBACR,KAAK,uBAAuB,CAAC,SAAS;4BAClC,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;4BACjC,IAAI,YAAY,IAAI,YAAY,EAAE,CAAC;gCAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gCACjD,IAAI,YAAY,EAAE,CAAC;oCACf,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;gCAC7B,CAAC;gCACD,IAAI,YAAY,EAAE,CAAC;oCACf,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;wCACtB,MAAM,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;oCACpC,CAAC;gCACL,CAAC;4BACL,CAAC;4BACD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;4BAC3D,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;4BACpC,MAAM;oBACd,CAAC;oBACD,MAAM;YACd,CAAC;YACD,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;gBACV,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YAC3B,CAAC;YACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;YACD,OAAO,GAAG,CAAC;QACf,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,SAA4B;QACzC,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,QAAQ,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,CAAC;gBAC/C,KAAK,oBAAoB,CAAC,GAAG;oBACzB,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC;gBAC/D,QAAQ;gBACR,KAAK,oBAAoB,CAAC,KAAK;oBAC3B,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,SAAS,CAAC;YAC5D,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,uBAAuB;QAC3B,IAAI,CAAC,gBAAgB,GAAG,IAAI,GAAG,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;YACjC,OAAO;QACX,CAAC;QACD,KAAK,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC;YAClF,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,KAAK,CAAC,WAAW,CAAqC,CAAC;YACzG,IAAI,CAAC,SAAS,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,uBAAuB,WAAW,qBAAqB,CAAC,CAAC;YAC7E,CAAC;YACD,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,CAAI;QAC3B,MAAM,MAAM,GAA8B,EAAE,CAAC;QAC7C,KAAK,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxD,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC;YACrC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC1B,SAAS;YACb,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,CAAI;QAC3B,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC;YAC/C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACrB,IAAI,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;oBACV,MAAM,GAAG,EAAE,CAAC;oBACZ,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC3B,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACnB,CAAC;QACL,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,CAAI;QAChC,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC;YAC/C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACrB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;oBACV,SAAS;gBACb,CAAC;gBACD,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC7B,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;oBACZ,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;gBACzB,CAAC;gBACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACtB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACtB,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,mBAAmB;QAC7B,iFAAiF;QACjF,qFAAqF;QACrF,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3G,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO;QACX,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,KAAK,oBAAoB,CAAC,GAAG,CAAC,CAAC;YAClF,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;QAChD,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;IACL,CAAC;IAEO,eAAe;QACnB,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAA+B,CAAC;YAC/G,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,gBAAgB,CAAC,KAAK,qBAAqB,CAAC,CAAC;YACzF,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,cAAc,CAAC;IAC1B,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,eAAe;QACzB,QAAQ,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,CAAC;YAC/C,KAAK,oBAAoB,CAAC,GAAG;gBACzB,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACjC,QAAQ;YACR,KAAK,oBAAoB,CAAC,KAAK;gBAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;gBACtC,MAAM,GAAG,GAAG,IAAI,GAAG,EAAa,CAAC;gBACjC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBAC7B,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;oBAC3B,IAAI,EAAE,EAAE,CAAC;wBACL,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;oBACnB,CAAC;gBACL,CAAC;gBACD,OAAO,GAAG,CAAC;QACnB,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,KAAK,CAAC,CAAI;QACpB,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,EAAE,EAAE,CAAC;YACN,QAAQ,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC;gBAC3C,KAAK,gBAAgB,CAAC,UAAU;oBAC5B,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;gBACzF,QAAQ;gBACR,KAAK,gBAAgB,CAAC,YAAY;oBAC9B,EAAE,GAAG,MAAM,EAAE,CAAC;oBACd,IAAI,MAAsB,CAAC;oBAC3B,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC;wBAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAA+B,CAAC;wBAC/G,IAAI,CAAC,KAAK,EAAE,CAAC;4BACT,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,CAAC,gBAAgB,CAAC,KAAK,qBAAqB,CAAC,CAAC;wBACzF,CAAC;wBACD,MAAM,GAAG,KAAK,CAAC;oBACnB,CAAC;yBACI,CAAC;wBACF,MAAM,GAAG,cAAc,CAAC;oBAC5B,CAAC;oBACD,MAAM,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACpB,MAAM;YACd,CAAC;QACL,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAO;QACvB,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,QAAQ,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,CAAC;gBAC/C,KAAK,oBAAoB,CAAC,GAAG;oBACzB,IAAI,GAAG,GAAG,CAAC,CAAC;oBACZ,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;oBACjD,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,CAAC;oBACpD,MAAM,QAAQ,GAAQ,EAAE,CAAC;oBACzB,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;wBACjB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;wBAC/B,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;4BACvB,QAAQ,IAAI,CAAC,gBAAgB,CAAC,mBAAmB,EAAE,CAAC;gCAChD,KAAK,qBAAqB,CAAC,KAAK;oCAC5B,MAAM,IAAI,KAAK,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;gCAC1C,KAAK,qBAAqB,CAAC,MAAM;oCAC7B,uBAAuB;oCACvB,MAAM;gCACV,QAAQ;gCACR,KAAK,qBAAqB,CAAC,SAAS;oCAChC,wBAAwB;oCACxB,GAAG,EAAE,CAAC;oCACN,IAAI,YAAY,EAAE,CAAC;wCACf,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,CAAC;oCACxD,CAAC;oCACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;oCACxB,IAAI,YAAY,EAAE,CAAC;wCACf,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oCAC/B,CAAC;oCACD,IAAI,YAAY,EAAE,CAAC;wCACf,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oCACrB,CAAC;oCACD,MAAM;4BACd,CAAC;wBACL,CAAC;6BACI,CAAC;4BACF,GAAG,EAAE,CAAC;4BACN,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;4BACxB,IAAI,YAAY,EAAE,CAAC;gCACf,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;4BAC/B,CAAC;4BACD,IAAI,YAAY,EAAE,CAAC;gCACf,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;4BACrB,CAAC;wBACL,CAAC;oBACL,CAAC;oBACD,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;wBACV,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;oBAC3B,CAAC;oBACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACtB,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;oBACjC,CAAC;oBACD,OAAO,GAAG,CAAC;gBACf,QAAQ;gBACR,KAAK,oBAAoB,CAAC,KAAK;oBAC3B,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;oBACnD,MAAM,cAAc,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,CAAC;oBACtD,MAAM,UAAU,GAAQ,EAAE,CAAC;oBAC3B,QAAQ,IAAI,CAAC,gBAAgB,CAAC,mBAAmB,EAAE,CAAC;wBAChD,KAAK,qBAAqB,CAAC,KAAK;4BAC5B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;4BAClC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gCAC7B,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;4BACrC,CAAC;4BACD,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gCACjB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gCAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oCAClB,MAAM,IAAI,KAAK,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC;gCAC1C,CAAC;gCACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gCAChB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gCACvB,IAAI,cAAc,EAAE,CAAC;oCACjB,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;gCAC/B,CAAC;gCACD,IAAI,cAAc,EAAE,CAAC;oCACjB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gCACvB,CAAC;4BACL,CAAC;4BACD,MAAM;wBACV,KAAK,qBAAqB,CAAC,MAAM;4BAC7B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;4BAClC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gCAC7B,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;4BACrC,CAAC;4BACD,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gCACjB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gCAC/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oCACnB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oCAChB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oCACvB,IAAI,cAAc,EAAE,CAAC;wCACjB,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oCAC/B,CAAC;oCACD,IAAI,cAAc,EAAE,CAAC;wCACjB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oCACvB,CAAC;gCACL,CAAC;4BACL,CAAC;4BACD,MAAM;wBACV,QAAQ;wBACR,KAAK,qBAAqB,CAAC,SAAS;4BAChC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAC;4BACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gCAC7C,QAAQ,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC,CAAC,CAAC;4BAC1D,CAAC;4BACD,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gCACjB,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gCAC/B,MAAM,aAAa,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gCAEvC,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;oCAC9B,IAAI,cAAc,EAAE,CAAC;wCACjB,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAE,CAAC,CAAC;oCACjE,CAAC;oCACD,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;gCACtC,CAAC;qCACI,CAAC;oCACF,kEAAkE;oCAClE,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;oCACxC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gCAC3B,CAAC;gCACD,IAAI,cAAc,EAAE,CAAC;oCACjB,MAAM,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;gCAC/B,CAAC;gCACD,IAAI,cAAc,EAAE,CAAC;oCACjB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gCACvB,CAAC;4BACL,CAAC;4BACD,MAAM;oBACd,CAAC;oBACD,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAChB,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;oBAC3B,CAAC;oBACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACxB,MAAM,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;oBACnC,CAAC;oBACD,OAAO,EAAE,CAAC,MAAM,CAAC;YACzB,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,SAA4B,EAAE,OAA6B;QAC3E,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,IAAI,GAAG,GAAG,CAAC,CAAC;YACZ,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;YACpD,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,CAAC;YACpD,MAAM,OAAO,GAAkB,EAAE,CAAC;YAClC,QAAQ,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,CAAC;gBAC/C,KAAK,oBAAoB,CAAC,GAAG;oBACzB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;wBACtC,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;4BACnB,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;4BACzC,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gCAC5B,GAAG,EAAE,CAAC;gCACN,IAAI,YAAY,EAAE,CAAC;oCACf,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;gCACxC,CAAC;gCACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;gCACnC,IAAI,YAAY,EAAE,CAAC;oCACf,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;gCACzC,CAAC;gCACD,IAAI,YAAY,EAAE,CAAC;oCACf,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;gCACvC,CAAC;4BACL,CAAC;iCACI,CAAC;gCACF,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;4BAC9C,CAAC;wBACL,CAAC;oBACL,CAAC;oBACD,MAAM;gBACV,QAAQ;gBACR,KAAK,oBAAoB,CAAC,KAAK;oBAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC7C,IAAI,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,EAAE,CAAC;4BAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC;4BACpC,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;4BAC5C,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gCAC5B,GAAG,EAAE,CAAC;gCACN,IAAI,YAAY,EAAE,CAAC;oCACf,MAAM,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;gCAC3C,CAAC;gCACD,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;gCAChC,IAAI,YAAY,EAAE,CAAC;oCACf,MAAM,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;gCACzC,CAAC;gCACD,IAAI,YAAY,EAAE,CAAC;oCACf,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC;gCAC1C,CAAC;4BACL,CAAC;iCACI,CAAC;gCACF,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;4BAC9C,CAAC;wBACL,CAAC;oBACL,CAAC;oBACD,MAAM;YACd,CAAC;YACD,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;gBACV,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YAC3B,CAAC;YACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;YACD,OAAO,GAAG,CAAC;QACf,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,KAAK,CAAC,SAAS;QACnB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,IAAI,mBAAmB,CAAC,iBAAiB,EAAE,CAAC;YACnF,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;IACL,CAAC;IAEM,KAAK,CAAC,KAAK;QACd,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBACd,QAAQ,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,CAAC;oBAC/C,KAAK,oBAAoB,CAAC,GAAG;wBACzB,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;wBACrE,MAAM;oBACV,QAAQ;oBACR,KAAK,oBAAoB,CAAC,KAAK;wBAC3B,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;wBACzE,MAAM;gBACd,CAAC;gBACD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACvB,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,MAAM;QACf,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,QAAQ,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,CAAC;gBAC/C,KAAK,oBAAoB,CAAC,GAAG;oBACzB,IAAI,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,CAAI,IAAI,CAAC,YAAY,CAAC,CAAC;oBACxE,MAAM;gBACV,QAAQ;gBACR,KAAK,oBAAoB,CAAC,KAAK;oBAC3B,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,aAAa,CAAI,IAAI,CAAC,YAAY,CAAC,CAAC;oBAC5E,MAAM;YACd,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACrC,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,KAAK,CAAC,MAAM;QACf,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACb,QAAQ,IAAI,CAAC,gBAAgB,CAAC,mBAAmB,EAAE,CAAC;oBAChD,KAAK,qBAAqB,CAAC,KAAK;wBAC5B,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;wBACnB,MAAM;oBACV,KAAK,qBAAqB,CAAC,KAAK;wBAC5B,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;oBAC1D,QAAQ;oBACR,KAAK,qBAAqB,CAAC,MAAM;wBAC7B,aAAa;wBACb,MAAM;gBAEd,CAAC;YACL,CAAC;YACD,QAAQ,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,CAAC;gBAC/C,KAAK,oBAAoB,CAAC,GAAG;oBACzB,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;oBACzB,MAAM;gBACV,QAAQ;gBACR,KAAK,oBAAoB,CAAC,KAAK;oBAC3B,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC;oBACpB,MAAM;YACd,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YACpB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACvB,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,mBAAmB;QAC5B,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAuB,EAAE,GAAG,IAAI,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,mBAAmB,CAAC,aAAa,EAAE,CAAC;YACxH,MAAM,KAAK,GAAG,IAAI,WAAW,CAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;YAClG,KAAK,CAAC,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACtC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACzC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;YACpB,KAAK,CAAC,uBAAuB,EAAE,CAAC;YAChC,MAAM,KAAK,CAAC,mBAAmB,EAAE,CAAC;YAClC,OAAO,KAAK,CAAC;QACjB,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;;;;;OAOG;IACI,KAAK,CAAC,sBAAsB,CAAC,KAAqB;QACrD,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;YAChC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YACzB,MAAM,KAAK,GAAQ,EAAE,CAAC;YACtB,MAAM,OAAO,GAAkB,EAAE,CAAC;YAClC,MAAM,OAAO,GAAQ,EAAE,CAAC;YACxB,uFAAuF;YACvF,iFAAiF;YACjF,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;YACrH,IAAI,YAAY,EAAE,CAAC;gBACf,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC5C,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE,CAAC;gBAC5C,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;oBAC9B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;wBAClB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACtB,CAAC;yBACI,CAAC;wBACF,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAM,CAAC;wBACrC,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;4BACrD,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;wBACpC,CAAC;oBACL,CAAC;gBACL,CAAC;gBACD,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;oBAC/B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;wBACjB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACxB,CAAC;gBACL,CAAC;YACL,CAAC;YACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;YAC7B,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;YACjC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;YACvC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YACnB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACnB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9B,CAAC;YACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;YACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;CAEJ"}
|
package/dist/fileio.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IBDatabase, IBDatabaseConfig, IBFunctionRegistry } from "./base.js";
|
|
1
|
+
import { IBDatabase, IBDatabaseConfig, IBFunctionRegistry, IBSnapshotOptions } from "./base.js";
|
|
2
2
|
import { BCollection, BDatabase } from "./basics.js";
|
|
3
3
|
export declare class IODatabase {
|
|
4
4
|
readonly basePath: string;
|
|
@@ -16,6 +16,8 @@ export declare class IODatabase {
|
|
|
16
16
|
private writeData;
|
|
17
17
|
writeArrayData<T = any>(collectionID: string, arrayData: T[]): Promise<void>;
|
|
18
18
|
writeMapData<T = any>(collectionID: string, mapData: Map<string, T>): Promise<void>;
|
|
19
|
+
snapshot(targetDir: string, options?: IBSnapshotOptions): Promise<string>;
|
|
20
|
+
private pruneSnapshots;
|
|
19
21
|
}
|
|
20
22
|
/**
|
|
21
23
|
* Opens the database at `basePath`, creating it if it doesn't exist yet.
|
package/dist/fileio.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BCollection, BDatabase, DEFAULT_DATABASE_CONFIG, } from "./basics.js";
|
|
2
2
|
import { uuidv7 } from "uuidv7";
|
|
3
|
-
import { access, constants, mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { access, chmod, constants, cp, mkdir, readdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
const DB_META_FILE_NAME = "dbmeta.json";
|
|
6
6
|
const DB_COLLECTION_FOLDER_SUFFIX = "_data";
|
|
@@ -8,6 +8,23 @@ const DB_COLLECTION_META_FILE_SUFFIX = ".json";
|
|
|
8
8
|
const DB_COLLECTION_DATA_FILE = "data.json";
|
|
9
9
|
const RESTRICTED_FILE_MODE = 0o600;
|
|
10
10
|
const RESTRICTED_DIR_MODE = 0o700;
|
|
11
|
+
const SNAPSHOT_VERSION_PATTERN = /^\d{8}T\d{9}Z(_[A-Za-z0-9_-]+)?$/;
|
|
12
|
+
const SNAPSHOT_LABEL_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
13
|
+
function snapshotVersionName(label) {
|
|
14
|
+
const timestamp = new Date().toISOString().replace(/[-:.]/g, "");
|
|
15
|
+
return label ? `${timestamp}_${label}` : timestamp;
|
|
16
|
+
}
|
|
17
|
+
// re-applies the restricted mode explicitly rather than relying on fs.cp() to have preserved it
|
|
18
|
+
async function restrictPermissions(path) {
|
|
19
|
+
const info = await stat(path);
|
|
20
|
+
if (info.isDirectory()) {
|
|
21
|
+
await chmod(path, RESTRICTED_DIR_MODE);
|
|
22
|
+
await Promise.all((await readdir(path)).map(entry => restrictPermissions(join(path, entry))));
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
await chmod(path, RESTRICTED_FILE_MODE);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
11
28
|
async function atomicWriteFile(targetPath, data) {
|
|
12
29
|
const tempPath = `${targetPath}.${uuidv7()}.tmp`;
|
|
13
30
|
await writeFile(tempPath, data, { encoding: "utf-8", mode: RESTRICTED_FILE_MODE });
|
|
@@ -114,6 +131,38 @@ export class IODatabase {
|
|
|
114
131
|
async writeMapData(collectionID, mapData) {
|
|
115
132
|
return this.writeData(collectionID, Object.fromEntries(mapData));
|
|
116
133
|
}
|
|
134
|
+
async snapshot(targetDir, options) {
|
|
135
|
+
if (options?.keepLast !== undefined && options.keepLast < 0) {
|
|
136
|
+
throw new Error(`keepLast must not be negative, got ${options.keepLast}`);
|
|
137
|
+
}
|
|
138
|
+
if (options?.label !== undefined && !SNAPSHOT_LABEL_PATTERN.test(options.label)) {
|
|
139
|
+
throw new Error(`snapshot label "${options.label}" must only contain letters, digits, "-" or "_"`);
|
|
140
|
+
}
|
|
141
|
+
await mkdir(targetDir, { recursive: true, mode: RESTRICTED_DIR_MODE });
|
|
142
|
+
const versionPath = join(targetDir, snapshotVersionName(options?.label));
|
|
143
|
+
try {
|
|
144
|
+
await cp(this.basePath, versionPath, { recursive: true });
|
|
145
|
+
await restrictPermissions(versionPath);
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
await rm(versionPath, { recursive: true, force: true });
|
|
149
|
+
throw err;
|
|
150
|
+
}
|
|
151
|
+
if (options?.keepLast !== undefined) {
|
|
152
|
+
await this.pruneSnapshots(targetDir, options.keepLast);
|
|
153
|
+
}
|
|
154
|
+
return versionPath;
|
|
155
|
+
}
|
|
156
|
+
// only ever deletes folders matching our own naming scheme, never anything else the caller keeps in targetDir
|
|
157
|
+
async pruneSnapshots(targetDir, keepLast) {
|
|
158
|
+
const entries = await readdir(targetDir, { withFileTypes: true });
|
|
159
|
+
const versions = entries
|
|
160
|
+
.filter(e => e.isDirectory() && SNAPSHOT_VERSION_PATTERN.test(e.name))
|
|
161
|
+
.map(e => e.name)
|
|
162
|
+
.sort();
|
|
163
|
+
const toDelete = versions.slice(0, Math.max(0, versions.length - (keepLast + 1)));
|
|
164
|
+
await Promise.all(toDelete.map(name => rm(join(targetDir, name), { recursive: true, force: true })));
|
|
165
|
+
}
|
|
117
166
|
}
|
|
118
167
|
/**
|
|
119
168
|
* Opens the database at `basePath`, creating it if it doesn't exist yet.
|
package/dist/fileio.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileio.js","sourceRoot":"","sources":["../src/main/fileio.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,uBAAuB,GAAG,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"fileio.js","sourceRoot":"","sources":["../src/main/fileio.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/main/base.ts
CHANGED
|
@@ -82,6 +82,14 @@ export interface IBDatabaseConfig {
|
|
|
82
82
|
readonly defaultCollectionConfig: IBCollectionConfig;
|
|
83
83
|
}
|
|
84
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
|
+
|
|
85
93
|
/** A JSON-file-backed database. Obtain one via `getDatabase()`. */
|
|
86
94
|
export interface IBDatabase {
|
|
87
95
|
readonly config: IBDatabaseConfig;
|
|
@@ -93,6 +101,21 @@ export interface IBDatabase {
|
|
|
93
101
|
hasCollection(collectionName: string): Promise<boolean>;
|
|
94
102
|
/** Deletes a collection and invalidates any handle still held on it. Rejects if it doesn't exist. */
|
|
95
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>;
|
|
96
119
|
}
|
|
97
120
|
|
|
98
121
|
/** What kind of collection mutation a handler subscribes to via {@link IBCollection.on}. */
|
|
@@ -165,6 +188,42 @@ export interface IBCollection<T = any> {
|
|
|
165
188
|
|
|
166
189
|
}
|
|
167
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
|
+
|
|
168
227
|
/** Resolves the custom id functions referenced by {@link IBCollectionConfig.getID}/`setID`. */
|
|
169
228
|
export interface IBFunctionRegistry {
|
|
170
229
|
/** Returns the function registered under `key`, or `undefined` if there is none. */
|
package/src/main/basics.ts
CHANGED
|
@@ -19,6 +19,9 @@ import {
|
|
|
19
19
|
IBDatabase,
|
|
20
20
|
IBDatabaseConfig,
|
|
21
21
|
IBFunctionRegistry,
|
|
22
|
+
IBSnapshotOptions,
|
|
23
|
+
IBTransaction,
|
|
24
|
+
IBTransactionCollection,
|
|
22
25
|
IHandlerRegistration,
|
|
23
26
|
TAddHandler,
|
|
24
27
|
TDeleteHandler,
|
|
@@ -115,6 +118,42 @@ export class BDatabase implements IBDatabase {
|
|
|
115
118
|
});
|
|
116
119
|
}
|
|
117
120
|
|
|
121
|
+
public async snapshot(targetDir: string, options?: IBSnapshotOptions): Promise<string> {
|
|
122
|
+
const collectionNames = Array.from(this.collections.keys());
|
|
123
|
+
return runMultiReentrantProtected([MutexKeys.DATABASE, ...collectionNames], async () => {
|
|
124
|
+
for (const collection of this.collections.values()) {
|
|
125
|
+
await collection.flush();
|
|
126
|
+
}
|
|
127
|
+
return this.io.snapshot(targetDir, options);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public async transaction(collectionNames: string[], fn: (tx: IBTransaction) => Promise<void>): Promise<void> {
|
|
132
|
+
const canonicalNames = Array.from(new Set(collectionNames.map(canonicalName)));
|
|
133
|
+
return runMultiReentrantProtected(canonicalNames, async () => {
|
|
134
|
+
const originals = new Map<string, BCollection>();
|
|
135
|
+
const clones = new Map<string, BCollection>();
|
|
136
|
+
for (const name of canonicalNames) {
|
|
137
|
+
const original = await this.getCollection(name) as BCollection;
|
|
138
|
+
originals.set(name, original);
|
|
139
|
+
clones.set(name, await original.cloneForTransaction());
|
|
140
|
+
}
|
|
141
|
+
const tx: IBTransaction = {
|
|
142
|
+
getCollection: async <T>(collectionName: string): Promise<IBTransactionCollection<T>> => {
|
|
143
|
+
const clone = clones.get(canonicalName(collectionName));
|
|
144
|
+
if (!clone) {
|
|
145
|
+
throw new Error(`collection "${collectionName}" was not declared to this transaction`);
|
|
146
|
+
}
|
|
147
|
+
return clone as IBTransactionCollection<T>;
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
await fn(tx);
|
|
151
|
+
for (const name of canonicalNames) {
|
|
152
|
+
await originals.get(name)!.commitTransactionClone(clones.get(name)!);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
118
157
|
}
|
|
119
158
|
|
|
120
159
|
export class BCollection<T = any> implements IBCollection<T> {
|
|
@@ -458,19 +497,42 @@ export class BCollection<T = any> implements IBCollection<T> {
|
|
|
458
497
|
}
|
|
459
498
|
}
|
|
460
499
|
|
|
461
|
-
private
|
|
462
|
-
let getter: TGetIDFunction;
|
|
500
|
+
private resolveIDGetter(): TGetIDFunction {
|
|
463
501
|
if (this.collectionConfig.getID) {
|
|
464
502
|
const found = this.database.functionRegistry?.fetch(this.collectionConfig.getID) as TGetIDFunction | undefined;
|
|
465
503
|
if (!found) {
|
|
466
504
|
throw new Error(`getID function "${this.collectionConfig.getID}" is not registered`);
|
|
467
505
|
}
|
|
468
|
-
|
|
506
|
+
return found;
|
|
469
507
|
}
|
|
470
|
-
|
|
471
|
-
|
|
508
|
+
return DEFAULT_GET_ID;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* id -> value for every stored item, resolved via the plain id getter (no auto-id assignment - every
|
|
513
|
+
* stored item already has one). Used to diff a transaction's working copy against the pre-transaction
|
|
514
|
+
* state in {@link commitTransactionClone}.
|
|
515
|
+
*/
|
|
516
|
+
private async idKeyedSnapshot(): Promise<Map<string, T>> {
|
|
517
|
+
switch (this.collectionConfig.memStorageStrategy) {
|
|
518
|
+
case EBMemStorageStrategy.MAP:
|
|
519
|
+
return new Map(this.mapData);
|
|
520
|
+
default:
|
|
521
|
+
case EBMemStorageStrategy.ARRAY:
|
|
522
|
+
const getter = this.resolveIDGetter();
|
|
523
|
+
const ret = new Map<string, T>();
|
|
524
|
+
for (const v of this.arrayData) {
|
|
525
|
+
const id = await getter(v);
|
|
526
|
+
if (id) {
|
|
527
|
+
ret.set(id, v);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return ret;
|
|
472
531
|
}
|
|
473
|
-
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
private async getID(v: T): Promise<string> {
|
|
535
|
+
let id = await this.resolveIDGetter()(v);
|
|
474
536
|
if (!id) {
|
|
475
537
|
switch (this.collectionConfig.autoIDStrategy) {
|
|
476
538
|
case EBAutoIDStrategy.NO_AUTO_ID:
|
|
@@ -774,4 +836,78 @@ export class BCollection<T = any> implements IBCollection<T> {
|
|
|
774
836
|
});
|
|
775
837
|
}
|
|
776
838
|
|
|
839
|
+
/**
|
|
840
|
+
* Creates a transaction-scoped working copy: same identity/config as this collection, but with
|
|
841
|
+
* independently mutable in-memory state (auto-flush forced off, regardless of this collection's own
|
|
842
|
+
* `autoFlushStrategy`) and no change-event handlers of its own. Call only while already holding this
|
|
843
|
+
* collection's mutex for the whole transaction (see {@link BDatabase.transaction}).
|
|
844
|
+
*/
|
|
845
|
+
public async cloneForTransaction(): Promise<BCollection<T>> {
|
|
846
|
+
return this.runProtected(async () => {
|
|
847
|
+
await this.checkLoaded();
|
|
848
|
+
const txConfig: IBCollectionConfig = { ...this.collectionConfig, autoFlushStrategy: EBAutoFlushStrategy.NO_AUTO_FLUSH };
|
|
849
|
+
const clone = new BCollection<T>(this.database, this.collectionID, this.collectionName, txConfig);
|
|
850
|
+
clone.mapData = new Map(this.mapData);
|
|
851
|
+
clone.arrayData = this.arrayData.slice();
|
|
852
|
+
clone.loaded = true;
|
|
853
|
+
clone.resolveIndexDefinitions();
|
|
854
|
+
await clone.rebuildIndexRuntime();
|
|
855
|
+
return clone;
|
|
856
|
+
});
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* Applies a working copy from {@link cloneForTransaction} back onto this collection: replaces the live
|
|
861
|
+
* state, flushes once, then fires `ADD`/`UPDATE`/`DELETE` handlers for the net difference between this
|
|
862
|
+
* collection's state before the transaction and `clone`'s state - not for each intermediate operation the
|
|
863
|
+
* transaction performed. The before/after diff itself (and the id resolution it needs) only runs when at
|
|
864
|
+
* least one handler is registered on this collection - a transaction on a collection nobody listens to
|
|
865
|
+
* skips it entirely. Call only while already holding this collection's mutex for the whole transaction.
|
|
866
|
+
*/
|
|
867
|
+
public async commitTransactionClone(clone: BCollection<T>): Promise<void> {
|
|
868
|
+
return this.runProtected(async () => {
|
|
869
|
+
await this.checkLoaded();
|
|
870
|
+
const added: T[] = [];
|
|
871
|
+
const updated: Array<[T, T]> = [];
|
|
872
|
+
const deleted: T[] = [];
|
|
873
|
+
// the before/after diff only feeds fireAdd()/fireUpdate()/fireDelete() below - skip it
|
|
874
|
+
// entirely (incl. idKeyedSnapshot()'s id-getter calls) when nothing is listening
|
|
875
|
+
const trackChanges = this.addHandlers.length > 0 || this.updateHandlers.length > 0 || this.deleteHandlers.length > 0;
|
|
876
|
+
if (trackChanges) {
|
|
877
|
+
const before = await this.idKeyedSnapshot();
|
|
878
|
+
const after = await clone.idKeyedSnapshot();
|
|
879
|
+
for (const [id, value] of after) {
|
|
880
|
+
if (!before.has(id)) {
|
|
881
|
+
added.push(value);
|
|
882
|
+
}
|
|
883
|
+
else {
|
|
884
|
+
const previous = before.get(id) as T;
|
|
885
|
+
if (JSON.stringify(previous) !== JSON.stringify(value)) {
|
|
886
|
+
updated.push([previous, value]);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
for (const [id, value] of before) {
|
|
891
|
+
if (!after.has(id)) {
|
|
892
|
+
deleted.push(value);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
this.mapData = clone.mapData;
|
|
897
|
+
this.arrayData = clone.arrayData;
|
|
898
|
+
this.indexRuntime = clone.indexRuntime;
|
|
899
|
+
this.dirty = true;
|
|
900
|
+
await this.flush();
|
|
901
|
+
if (added.length > 0) {
|
|
902
|
+
await this.fireAdd(added);
|
|
903
|
+
}
|
|
904
|
+
if (updated.length > 0) {
|
|
905
|
+
await this.fireUpdate(updated);
|
|
906
|
+
}
|
|
907
|
+
if (deleted.length > 0) {
|
|
908
|
+
await this.fireDelete(deleted);
|
|
909
|
+
}
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
|
|
777
913
|
}
|
package/src/main/fileio.ts
CHANGED
|
@@ -1,154 +1,207 @@
|
|
|
1
|
-
import { IBCollectionConfig, IBDatabase, IBDatabaseConfig, IBFunctionRegistry, } from "./base.js";
|
|
2
|
-
import { BCollection, BDatabase, DEFAULT_DATABASE_CONFIG, } from "./basics.js";
|
|
3
|
-
import { uuidv7 } from "uuidv7";
|
|
4
|
-
import { access, constants, mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
5
|
-
import { join } from "node:path";
|
|
6
|
-
|
|
7
|
-
interface IStoredDatabase {
|
|
8
|
-
config: IBDatabaseConfig;
|
|
9
|
-
nameIDMap: { [k: string]: string; };
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
interface IStoredCollection<T> {
|
|
13
|
-
collectionID: string;
|
|
14
|
-
collectionName: string;
|
|
15
|
-
collectionConfig: IBCollectionConfig;
|
|
16
|
-
path: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const DB_META_FILE_NAME = "dbmeta.json";
|
|
20
|
-
const DB_COLLECTION_FOLDER_SUFFIX = "_data";
|
|
21
|
-
const DB_COLLECTION_META_FILE_SUFFIX = ".json";
|
|
22
|
-
const DB_COLLECTION_DATA_FILE = "data.json";
|
|
23
|
-
const RESTRICTED_FILE_MODE = 0o600;
|
|
24
|
-
const RESTRICTED_DIR_MODE = 0o700;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
1
|
+
import { IBCollectionConfig, IBDatabase, IBDatabaseConfig, IBFunctionRegistry, IBSnapshotOptions, } from "./base.js";
|
|
2
|
+
import { BCollection, BDatabase, DEFAULT_DATABASE_CONFIG, } from "./basics.js";
|
|
3
|
+
import { uuidv7 } from "uuidv7";
|
|
4
|
+
import { access, chmod, constants, cp, mkdir, readdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
|
|
7
|
+
interface IStoredDatabase {
|
|
8
|
+
config: IBDatabaseConfig;
|
|
9
|
+
nameIDMap: { [k: string]: string; };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface IStoredCollection<T> {
|
|
13
|
+
collectionID: string;
|
|
14
|
+
collectionName: string;
|
|
15
|
+
collectionConfig: IBCollectionConfig;
|
|
16
|
+
path: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const DB_META_FILE_NAME = "dbmeta.json";
|
|
20
|
+
const DB_COLLECTION_FOLDER_SUFFIX = "_data";
|
|
21
|
+
const DB_COLLECTION_META_FILE_SUFFIX = ".json";
|
|
22
|
+
const DB_COLLECTION_DATA_FILE = "data.json";
|
|
23
|
+
const RESTRICTED_FILE_MODE = 0o600;
|
|
24
|
+
const RESTRICTED_DIR_MODE = 0o700;
|
|
25
|
+
const SNAPSHOT_VERSION_PATTERN = /^\d{8}T\d{9}Z(_[A-Za-z0-9_-]+)?$/;
|
|
26
|
+
const SNAPSHOT_LABEL_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
27
|
+
|
|
28
|
+
function snapshotVersionName(label?: string): string {
|
|
29
|
+
const timestamp = new Date().toISOString().replace(/[-:.]/g, "");
|
|
30
|
+
return label ? `${timestamp}_${label}` : timestamp;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// re-applies the restricted mode explicitly rather than relying on fs.cp() to have preserved it
|
|
34
|
+
async function restrictPermissions(path: string): Promise<void> {
|
|
35
|
+
const info = await stat(path);
|
|
36
|
+
if (info.isDirectory()) {
|
|
37
|
+
await chmod(path, RESTRICTED_DIR_MODE);
|
|
38
|
+
await Promise.all((await readdir(path)).map(entry => restrictPermissions(join(path, entry))));
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
await chmod(path, RESTRICTED_FILE_MODE);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function atomicWriteFile(targetPath: string, data: string): Promise<void> {
|
|
46
|
+
const tempPath = `${targetPath}.${uuidv7()}.tmp`;
|
|
47
|
+
await writeFile(tempPath, data, { encoding: "utf-8", mode: RESTRICTED_FILE_MODE });
|
|
48
|
+
await rename(tempPath, targetPath);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export class IODatabase {
|
|
52
|
+
readonly basePath: string;
|
|
53
|
+
private readonly nameIDMap: Map<string, string>;
|
|
54
|
+
private databaseConfig: IBDatabaseConfig;
|
|
55
|
+
|
|
56
|
+
public constructor(basePath: string, databaseConfig: IBDatabaseConfig, nameIDMap?: Map<string, string>) {
|
|
57
|
+
this.basePath = basePath;
|
|
58
|
+
this.databaseConfig = databaseConfig;
|
|
59
|
+
this.nameIDMap = nameIDMap ?? new Map();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private async loadCollectionMeta(id: string, database: BDatabase): Promise<BCollection> {
|
|
63
|
+
const meta: IStoredCollection<any> = JSON.parse(await readFile(join(this.basePath, id + DB_COLLECTION_META_FILE_SUFFIX), { encoding: "utf-8" }));
|
|
64
|
+
return new BCollection(database, id, meta.collectionName, meta.collectionConfig);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public static async createOrLoad(basePath: string, functionRegistry?: IBFunctionRegistry): Promise<BDatabase> {
|
|
68
|
+
const metaPath = join(basePath, DB_META_FILE_NAME);
|
|
69
|
+
let data: string;
|
|
70
|
+
try {
|
|
71
|
+
await access(metaPath, constants.F_OK);
|
|
72
|
+
data = await readFile(metaPath, { encoding: "utf-8" })
|
|
73
|
+
}
|
|
74
|
+
catch (err: any) {
|
|
75
|
+
if (err.code === 'ENOENT') {
|
|
76
|
+
const iodb = new IODatabase(basePath, DEFAULT_DATABASE_CONFIG);
|
|
77
|
+
return new BDatabase(iodb, DEFAULT_DATABASE_CONFIG, functionRegistry);
|
|
78
|
+
}
|
|
79
|
+
throw err;
|
|
80
|
+
}
|
|
81
|
+
const meta: IStoredDatabase = JSON.parse(data);
|
|
82
|
+
const nameIDMap = new Map(Object.entries(meta.nameIDMap));
|
|
83
|
+
const iodb = new IODatabase(basePath, meta.config, nameIDMap);
|
|
84
|
+
const database = new BDatabase(iodb, meta.config, functionRegistry);
|
|
85
|
+
const collections = await Promise.all(
|
|
86
|
+
nameIDMap.values()
|
|
87
|
+
.map(id => iodb.loadCollectionMeta(id, database))
|
|
88
|
+
.toArray());
|
|
89
|
+
collections.forEach(c => database.addCollection(c));
|
|
90
|
+
return database;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public async flush(): Promise<void> {
|
|
94
|
+
const meta: IStoredDatabase = {
|
|
95
|
+
config: this.databaseConfig,
|
|
96
|
+
nameIDMap: Object.fromEntries(this.nameIDMap),
|
|
97
|
+
};
|
|
98
|
+
const data = JSON.stringify(meta);
|
|
99
|
+
await atomicWriteFile(join(this.basePath, DB_META_FILE_NAME), data);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public async createCollection<T = any>(collection: BCollection<T>): Promise<BCollection<T>> {
|
|
103
|
+
const id = collection.collectionID;
|
|
104
|
+
const collectionPath = join(this.basePath, id + DB_COLLECTION_FOLDER_SUFFIX);
|
|
105
|
+
await mkdir(collectionPath, { recursive: true, mode: RESTRICTED_DIR_MODE });
|
|
106
|
+
const meta: IStoredCollection<T> = {
|
|
107
|
+
collectionConfig: collection.collectionConfig,
|
|
108
|
+
collectionName: collection.collectionName,
|
|
109
|
+
collectionID: id,
|
|
110
|
+
path: collectionPath,
|
|
111
|
+
};
|
|
112
|
+
const data = JSON.stringify(meta);
|
|
113
|
+
await atomicWriteFile(join(this.basePath, id + DB_COLLECTION_META_FILE_SUFFIX), data);
|
|
114
|
+
this.nameIDMap.set(collection.collectionName, id);
|
|
115
|
+
await this.flush();
|
|
116
|
+
return collection;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public async deleteCollection(collectionName: string): Promise<void> {
|
|
120
|
+
const id = this.nameIDMap.get(collectionName);
|
|
121
|
+
if (!id) {
|
|
122
|
+
throw new Error(`no such database ${collectionName}`);
|
|
123
|
+
}
|
|
124
|
+
const collectionPath = join(this.basePath, id + DB_COLLECTION_FOLDER_SUFFIX);
|
|
125
|
+
await rm(collectionPath, { recursive: true, force: true });
|
|
126
|
+
const metaPath = join(this.basePath, id + DB_COLLECTION_META_FILE_SUFFIX);
|
|
127
|
+
await rm(metaPath, { force: true });
|
|
128
|
+
this.nameIDMap.delete(collectionName);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private async loadData(collectionID: string): Promise<any> {
|
|
132
|
+
try {
|
|
133
|
+
const data = await readFile(join(this.basePath, collectionID + DB_COLLECTION_FOLDER_SUFFIX, DB_COLLECTION_DATA_FILE), { encoding: "utf-8" });
|
|
134
|
+
return JSON.parse(data);
|
|
135
|
+
}
|
|
136
|
+
catch (err: any) {
|
|
137
|
+
if (err.code === 'ENOENT') {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
throw err;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public async loadArrayData<T>(collectionID: string): Promise<T[]> {
|
|
145
|
+
const data = await this.loadData(collectionID);
|
|
146
|
+
return data || [];
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
public async loadMapData<T>(collectionID: string): Promise<Map<string, T>> {
|
|
150
|
+
const data = await this.loadData(collectionID);
|
|
151
|
+
return data ? new Map(Object.entries(data)) : new Map();
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private async writeData(collectionID: string, data: any): Promise<void> {
|
|
155
|
+
return atomicWriteFile(join(this.basePath, collectionID + DB_COLLECTION_FOLDER_SUFFIX, DB_COLLECTION_DATA_FILE), JSON.stringify(data));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
public async writeArrayData<T = any>(collectionID: string, arrayData: T[]): Promise<void> {
|
|
159
|
+
return this.writeData(collectionID, arrayData);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
public async writeMapData<T = any>(collectionID: string, mapData: Map<string, T>): Promise<void> {
|
|
163
|
+
return this.writeData(collectionID, Object.fromEntries(mapData));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
public async snapshot(targetDir: string, options?: IBSnapshotOptions): Promise<string> {
|
|
167
|
+
if (options?.keepLast !== undefined && options.keepLast < 0) {
|
|
168
|
+
throw new Error(`keepLast must not be negative, got ${options.keepLast}`);
|
|
169
|
+
}
|
|
170
|
+
if (options?.label !== undefined && !SNAPSHOT_LABEL_PATTERN.test(options.label)) {
|
|
171
|
+
throw new Error(`snapshot label "${options.label}" must only contain letters, digits, "-" or "_"`);
|
|
172
|
+
}
|
|
173
|
+
await mkdir(targetDir, { recursive: true, mode: RESTRICTED_DIR_MODE });
|
|
174
|
+
const versionPath = join(targetDir, snapshotVersionName(options?.label));
|
|
175
|
+
try {
|
|
176
|
+
await cp(this.basePath, versionPath, { recursive: true });
|
|
177
|
+
await restrictPermissions(versionPath);
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
await rm(versionPath, { recursive: true, force: true });
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
183
|
+
if (options?.keepLast !== undefined) {
|
|
184
|
+
await this.pruneSnapshots(targetDir, options.keepLast);
|
|
185
|
+
}
|
|
186
|
+
return versionPath;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// only ever deletes folders matching our own naming scheme, never anything else the caller keeps in targetDir
|
|
190
|
+
private async pruneSnapshots(targetDir: string, keepLast: number): Promise<void> {
|
|
191
|
+
const entries = await readdir(targetDir, { withFileTypes: true });
|
|
192
|
+
const versions = entries
|
|
193
|
+
.filter(e => e.isDirectory() && SNAPSHOT_VERSION_PATTERN.test(e.name))
|
|
194
|
+
.map(e => e.name)
|
|
195
|
+
.sort();
|
|
196
|
+
const toDelete = versions.slice(0, Math.max(0, versions.length - (keepLast + 1)));
|
|
197
|
+
await Promise.all(toDelete.map(name => rm(join(targetDir, name), { recursive: true, force: true })));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Opens the database at `basePath`, creating it if it doesn't exist yet.
|
|
203
|
+
* `functionRegistry` resolves any {@link IBCollectionConfig.getID}/`setID` keys used by its collections.
|
|
204
|
+
*/
|
|
205
|
+
export async function getDatabase(basePath: string, functionRegistry?: IBFunctionRegistry): Promise<IBDatabase> {
|
|
206
|
+
return IODatabase.createOrLoad(basePath, functionRegistry);
|
|
207
|
+
}
|