mindoodb 0.0.85 → 0.0.86
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-server.md +1 -0
- package/README.md +6 -4
- package/dist/cloudflare/DurableObjectSql.d.ts +56 -0
- package/dist/cloudflare/DurableObjectSql.d.ts.map +1 -0
- package/dist/cloudflare/DurableObjectSql.js +180 -0
- package/dist/cloudflare/DurableObjectSql.js.map +1 -0
- package/dist/cloudflare/MindooDatabaseObject.d.ts +86 -0
- package/dist/cloudflare/MindooDatabaseObject.d.ts.map +1 -0
- package/dist/cloudflare/MindooDatabaseObject.js +614 -0
- package/dist/cloudflare/MindooDatabaseObject.js.map +1 -0
- package/dist/cloudflare/MindooServerObject.d.ts +63 -0
- package/dist/cloudflare/MindooServerObject.d.ts.map +1 -0
- package/dist/cloudflare/MindooServerObject.js +521 -0
- package/dist/cloudflare/MindooServerObject.js.map +1 -0
- package/dist/cloudflare/WorkersCryptoAdapter.d.ts +7 -0
- package/dist/cloudflare/WorkersCryptoAdapter.d.ts.map +1 -0
- package/dist/cloudflare/WorkersCryptoAdapter.js +14 -0
- package/dist/cloudflare/WorkersCryptoAdapter.js.map +1 -0
- package/dist/cloudflare/host.d.ts +49 -0
- package/dist/cloudflare/host.d.ts.map +1 -0
- package/dist/cloudflare/host.js +104 -0
- package/dist/cloudflare/host.js.map +1 -0
- package/dist/cloudflare/http.d.ts +91 -0
- package/dist/cloudflare/http.d.ts.map +1 -0
- package/dist/cloudflare/http.js +266 -0
- package/dist/cloudflare/http.js.map +1 -0
- package/dist/cloudflare/index.d.ts +12 -0
- package/dist/cloudflare/index.d.ts.map +1 -0
- package/dist/cloudflare/index.js +20 -0
- package/dist/cloudflare/index.js.map +1 -0
- package/dist/cloudflare/storeRpc.d.ts +22 -0
- package/dist/cloudflare/storeRpc.d.ts.map +1 -0
- package/dist/cloudflare/storeRpc.js +85 -0
- package/dist/cloudflare/storeRpc.js.map +1 -0
- package/dist/cloudflare/types.d.ts +101 -0
- package/dist/cloudflare/types.d.ts.map +1 -0
- package/dist/cloudflare/types.js +10 -0
- package/dist/cloudflare/types.js.map +1 -0
- package/dist/cloudflare/worker.d.ts +25 -0
- package/dist/cloudflare/worker.d.ts.map +1 -0
- package/dist/cloudflare/worker.js +170 -0
- package/dist/cloudflare/worker.js.map +1 -0
- package/dist/core/BaseMindooDB.d.ts +28 -1
- package/dist/core/BaseMindooDB.d.ts.map +1 -1
- package/dist/core/BaseMindooDB.js +180 -86
- package/dist/core/BaseMindooDB.js.map +1 -1
- package/dist/core/BaseMindooTenant.d.ts +14 -0
- package/dist/core/BaseMindooTenant.d.ts.map +1 -1
- package/dist/core/BaseMindooTenant.js +46 -0
- package/dist/core/BaseMindooTenant.js.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.d.ts +10 -0
- package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.js +79 -8
- package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
- package/dist/core/ChangeDocDraft.d.ts +133 -0
- package/dist/core/ChangeDocDraft.d.ts.map +1 -0
- package/dist/core/ChangeDocDraft.js +492 -0
- package/dist/core/ChangeDocDraft.js.map +1 -0
- package/dist/core/appendonlystores/network/AuthenticationService.d.ts +8 -0
- package/dist/core/appendonlystores/network/AuthenticationService.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/AuthenticationService.js +19 -0
- package/dist/core/appendonlystores/network/AuthenticationService.js.map +1 -1
- package/dist/core/appendonlystores/network/IrohStreamIO.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/IrohStreamIO.js +3 -23
- package/dist/core/appendonlystores/network/IrohStreamIO.js.map +1 -1
- package/dist/core/appendonlystores/rpc/storeRpcCodec.d.ts.map +1 -1
- package/dist/core/appendonlystores/rpc/storeRpcCodec.js +3 -23
- package/dist/core/appendonlystores/rpc/storeRpcCodec.js.map +1 -1
- package/dist/core/appendonlystores/sqlite/SqliteContentAddressedStore.d.ts.map +1 -1
- package/dist/core/appendonlystores/sqlite/SqliteContentAddressedStore.js +21 -30
- package/dist/core/appendonlystores/sqlite/SqliteContentAddressedStore.js.map +1 -1
- package/dist/core/appendonlystores/sqlite/SqliteDriver.d.ts +37 -1
- package/dist/core/appendonlystores/sqlite/SqliteDriver.d.ts.map +1 -1
- package/dist/core/appendonlystores/sqlite/SqliteDriver.js +99 -40
- package/dist/core/appendonlystores/sqlite/SqliteDriver.js.map +1 -1
- package/dist/core/expressions/evaluateExpression.d.ts +8 -0
- package/dist/core/expressions/evaluateExpression.d.ts.map +1 -1
- package/dist/core/expressions/evaluateExpression.js +29 -4
- package/dist/core/expressions/evaluateExpression.js.map +1 -1
- package/dist/core/expressions/metadata.js +4 -4
- package/dist/core/expressions/metadata.js.map +1 -1
- package/dist/core/types.d.ts +61 -2
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/uri/MindooURI.d.ts.map +1 -1
- package/dist/core/uri/MindooURI.js +3 -24
- package/dist/core/uri/MindooURI.js.map +1 -1
- package/dist/core/utils/base64.d.ts +17 -0
- package/dist/core/utils/base64.d.ts.map +1 -0
- package/dist/core/utils/base64.js +54 -0
- package/dist/core/utils/base64.js.map +1 -0
- package/dist/core/utils/idGeneration.d.ts.map +1 -1
- package/dist/core/utils/idGeneration.js +14 -3
- package/dist/core/utils/idGeneration.js.map +1 -1
- package/dist/node/server/FsServerDataStore.d.ts +23 -0
- package/dist/node/server/FsServerDataStore.d.ts.map +1 -0
- package/dist/node/server/FsServerDataStore.js +59 -0
- package/dist/node/server/FsServerDataStore.js.map +1 -0
- package/dist/node/server/IrohServerEndpoint.d.ts +1 -1
- package/dist/node/server/IrohServerEndpoint.d.ts.map +1 -1
- package/dist/node/server/IrohServerRpc.d.ts +5 -5
- package/dist/node/server/IrohServerRpc.d.ts.map +1 -1
- package/dist/node/server/IrohServerRpc.js +1 -1
- package/dist/node/server/IrohServerRpc.js.map +1 -1
- package/dist/node/server/MindooDBServer.d.ts +29 -150
- package/dist/node/server/MindooDBServer.d.ts.map +1 -1
- package/dist/node/server/MindooDBServer.js +160 -1573
- package/dist/node/server/MindooDBServer.js.map +1 -1
- package/dist/node/server/PurgedDocRegistry.d.ts +4 -27
- package/dist/node/server/PurgedDocRegistry.d.ts.map +1 -1
- package/dist/node/server/PurgedDocRegistry.js +6 -83
- package/dist/node/server/PurgedDocRegistry.js.map +1 -1
- package/dist/node/server/StoreFactory.d.ts +1 -1
- package/dist/node/server/StoreFactory.d.ts.map +1 -1
- package/dist/node/server/TenantManager.d.ts +16 -284
- package/dist/node/server/TenantManager.d.ts.map +1 -1
- package/dist/node/server/TenantManager.js +35 -1168
- package/dist/node/server/TenantManager.js.map +1 -1
- package/dist/node/server/add-to-network.js +1 -1
- package/dist/node/server/add-to-network.js.map +1 -1
- package/dist/node/server/config.d.ts +11 -15
- package/dist/node/server/config.d.ts.map +1 -1
- package/dist/node/server/config.js +30 -245
- package/dist/node/server/config.js.map +1 -1
- package/dist/node/server/expressAdapter.d.ts +23 -0
- package/dist/node/server/expressAdapter.d.ts.map +1 -0
- package/dist/node/server/expressAdapter.js +108 -0
- package/dist/node/server/expressAdapter.js.map +1 -0
- package/dist/node/server/nativeIrohStreamIO.d.ts +1 -1
- package/dist/node/server/nativeIrohStreamIO.d.ts.map +1 -1
- package/dist/node/server/peer/FileClusterAuditStorage.d.ts +16 -0
- package/dist/node/server/peer/FileClusterAuditStorage.d.ts.map +1 -0
- package/dist/node/server/peer/FileClusterAuditStorage.js +39 -0
- package/dist/node/server/peer/FileClusterAuditStorage.js.map +1 -0
- package/dist/node/server/peer/IrohPeerLink.d.ts +1 -1
- package/dist/node/server/peer/IrohPeerLink.d.ts.map +1 -1
- package/dist/node/server/peer/routes.d.ts +10 -44
- package/dist/node/server/peer/routes.d.ts.map +1 -1
- package/dist/node/server/peer/routes.js +33 -275
- package/dist/node/server/peer/routes.js.map +1 -1
- package/dist/node/server/resolveServerPassword.js +1 -1
- package/dist/node/server/resolveServerPassword.js.map +1 -1
- package/dist/node/server/server.js +1 -1
- package/dist/node/server/server.js.map +1 -1
- package/dist/node/server/serverinit.js +1 -1
- package/dist/node/server/serverinit.js.map +1 -1
- package/dist/server/CapabilityMatcher.d.ts +60 -0
- package/dist/server/CapabilityMatcher.d.ts.map +1 -0
- package/dist/server/CapabilityMatcher.js +138 -0
- package/dist/server/CapabilityMatcher.js.map +1 -0
- package/dist/server/DeviceDiscoveryService.d.ts +36 -0
- package/dist/server/DeviceDiscoveryService.d.ts.map +1 -0
- package/dist/server/DeviceDiscoveryService.js +165 -0
- package/dist/server/DeviceDiscoveryService.js.map +1 -0
- package/dist/server/PurgedDocRegistry.d.ts +35 -0
- package/dist/server/PurgedDocRegistry.d.ts.map +1 -0
- package/dist/server/PurgedDocRegistry.js +90 -0
- package/dist/server/PurgedDocRegistry.js.map +1 -0
- package/dist/server/ServerDataStore.d.ts +67 -0
- package/dist/server/ServerDataStore.d.ts.map +1 -0
- package/dist/server/ServerDataStore.js +88 -0
- package/dist/server/ServerDataStore.js.map +1 -0
- package/dist/server/SyncEventBus.d.ts +39 -0
- package/dist/server/SyncEventBus.d.ts.map +1 -0
- package/dist/server/SyncEventBus.js +41 -0
- package/dist/server/SyncEventBus.js.map +1 -0
- package/dist/server/SystemAdminAuth.d.ts +82 -0
- package/dist/server/SystemAdminAuth.d.ts.map +1 -0
- package/dist/server/SystemAdminAuth.js +228 -0
- package/dist/server/SystemAdminAuth.js.map +1 -0
- package/dist/server/TenantManager.d.ts +330 -0
- package/dist/server/TenantManager.d.ts.map +1 -0
- package/dist/server/TenantManager.js +1186 -0
- package/dist/server/TenantManager.js.map +1 -0
- package/dist/server/http/MindooDBServerCore.d.ts +313 -0
- package/dist/server/http/MindooDBServerCore.d.ts.map +1 -0
- package/dist/server/http/MindooDBServerCore.js +1403 -0
- package/dist/server/http/MindooDBServerCore.js.map +1 -0
- package/dist/server/http/types.d.ts +89 -0
- package/dist/server/http/types.d.ts.map +1 -0
- package/dist/server/http/types.js +29 -0
- package/dist/server/http/types.js.map +1 -0
- package/dist/server/index.d.ts +32 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +76 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/peer/ClusterAuditLog.d.ts +71 -0
- package/dist/server/peer/ClusterAuditLog.d.ts.map +1 -0
- package/dist/server/peer/ClusterAuditLog.js +81 -0
- package/dist/server/peer/ClusterAuditLog.js.map +1 -0
- package/dist/server/peer/ClusterJobRunner.d.ts +43 -0
- package/dist/server/peer/ClusterJobRunner.d.ts.map +1 -0
- package/dist/server/peer/ClusterJobRunner.js +119 -0
- package/dist/server/peer/ClusterJobRunner.js.map +1 -0
- package/dist/server/peer/ClusterManager.d.ts +149 -0
- package/dist/server/peer/ClusterManager.d.ts.map +1 -0
- package/dist/server/peer/ClusterManager.js +292 -0
- package/dist/server/peer/ClusterManager.js.map +1 -0
- package/dist/server/peer/PeerAuthService.d.ts +69 -0
- package/dist/server/peer/PeerAuthService.d.ts.map +1 -0
- package/dist/server/peer/PeerAuthService.js +208 -0
- package/dist/server/peer/PeerAuthService.js.map +1 -0
- package/dist/server/peer/PeerReplicator.d.ts +303 -0
- package/dist/server/peer/PeerReplicator.d.ts.map +1 -0
- package/dist/server/peer/PeerReplicator.js +1071 -0
- package/dist/server/peer/PeerReplicator.js.map +1 -0
- package/dist/server/peer/clusterHttp.d.ts +113 -0
- package/dist/server/peer/clusterHttp.d.ts.map +1 -0
- package/dist/server/peer/clusterHttp.js +290 -0
- package/dist/server/peer/clusterHttp.js.map +1 -0
- package/dist/server/peer/types.d.ts +244 -0
- package/dist/server/peer/types.d.ts.map +1 -0
- package/dist/server/peer/types.js +189 -0
- package/dist/server/peer/types.js.map +1 -0
- package/dist/server/rateLimits.d.ts +119 -0
- package/dist/server/rateLimits.d.ts.map +1 -0
- package/dist/server/rateLimits.js +159 -0
- package/dist/server/rateLimits.js.map +1 -0
- package/dist/server/serverConfig.d.ts +37 -0
- package/dist/server/serverConfig.d.ts.map +1 -0
- package/dist/server/serverConfig.js +251 -0
- package/dist/server/serverConfig.js.map +1 -0
- package/dist/server/timestampProxy.d.ts +129 -0
- package/dist/server/timestampProxy.d.ts.map +1 -0
- package/dist/server/timestampProxy.js +361 -0
- package/dist/server/timestampProxy.js.map +1 -0
- package/dist/server/types.d.ts +267 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +56 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server/validation.d.ts +43 -0
- package/dist/server/validation.d.ts.map +1 -0
- package/dist/server/validation.js +104 -0
- package/dist/server/validation.js.map +1 -0
- package/package.json +9 -1
package/README-server.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# MindooDB reference server
|
|
2
2
|
|
|
3
3
|
Node.js/Express sources: `src/node/server/`. Docker: `src/node/server/Dockerfile`.
|
|
4
|
+
Serverless on Cloudflare Workers + Durable Objects: `cloudflare/README.md` (same API, same core: `docs/server-hosts.md`).
|
|
4
5
|
|
|
5
6
|
A Node.js/Express server implementing the MindooDB sync API with:
|
|
6
7
|
|
package/README.md
CHANGED
|
@@ -7,8 +7,6 @@ Apps collaborate and sync data without ever giving a server access to the conten
|
|
|
7
7
|
|
|
8
8
|
Data is encrypted on the client before it leaves the device. Even someone with full access to your infrastructure — database dumps, backups, logs — gets nothing but ciphertext. No plaintext on the server, no server-side keys, no trust required.
|
|
9
9
|
|
|
10
|
-
> ⚠️ **Beta software**: This project is in early development and not yet recommended for production use. APIs may change without notice.
|
|
11
|
-
|
|
12
10
|
Use AI to explore this repository:
|
|
13
11
|
|
|
14
12
|
[](https://deepwiki.com/klehmann/MindooDB)
|
|
@@ -71,7 +69,7 @@ Haven is the fastest way to see MindooDB in action, and a real home for day-to-d
|
|
|
71
69
|
- **Multi-tenant by design** — run work, personal, and cross-company tenants side by side, each cryptographically independent, all in one browser.
|
|
72
70
|
- **Installable PWA** — add it to an iPhone, iPad, or Android home screen and launch it in standalone mode; encrypted `.mdbhaven-backup` files move a whole environment between browsers.
|
|
73
71
|
|
|
74
|
-
Haven Community is **free**
|
|
72
|
+
Haven Community is **free** and is the same client the MindooDB team uses in-house. Try it at **[haven.mindoodb.com](https://haven.mindoodb.com)**, read the full [Haven Handbook](./docs/haven-handbook.md), or explore more at [mindoodb.com](https://www.mindoodb.com).
|
|
75
73
|
|
|
76
74
|
> Prefer to build directly on the engine? Keep reading — the Quick Start below is all code.
|
|
77
75
|
|
|
@@ -83,9 +81,11 @@ Haven Community is **free** (in beta) and is the same client the MindooDB team u
|
|
|
83
81
|
pnpm add mindoodb
|
|
84
82
|
```
|
|
85
83
|
|
|
86
|
-
> 📦 **Published regularly on npm.** We ship new versions frequently to [npmjs.com/package/mindoodb](https://www.npmjs.com/package/mindoodb), so pull updates often to stay current with fixes and API changes
|
|
84
|
+
> 📦 **Published regularly on npm.** We ship new versions frequently to [npmjs.com/package/mindoodb](https://www.npmjs.com/package/mindoodb), so pull updates often to stay current with fixes and API changes.
|
|
87
85
|
|
|
88
86
|
> 📱 **React Native / Expo?** See the [React Native setup guide](./docs/reactnative.md) for mobile-specific instructions with native performance.
|
|
87
|
+
>
|
|
88
|
+
> ☕ **Kotlin or Java?** See [MindooDB for Kotlin and Java](./docs/kotlin-jvm.md): a coroutine client that drives the same engine through a Node.js sidecar.
|
|
89
89
|
|
|
90
90
|
### Pick Your Runtime
|
|
91
91
|
|
|
@@ -335,10 +335,12 @@ See: [Use Cases Documentation](./docs/usecases/README.md)
|
|
|
335
335
|
|
|
336
336
|
- [Haven Handbook](./docs/haven-handbook.md) — Complete guide to Haven, the graphical MindooDB collaboration client
|
|
337
337
|
- [Getting Started](./docs/getting-started.md) — Fast setup for Node.js, Web, and React Native
|
|
338
|
+
- [Reading and Writing Documents](./docs/reading-and-writing.md) — `getData()`, nested and list edits in `changeDoc()`, field types (`MindooValue.atomic`/`counter`/`timestamp`, text, rich text), `getFieldType()`, patch APIs and how concurrent edits merge
|
|
338
339
|
- [Best Practices](./docs/best-practices.md) — What append-only storage, local-first replicas, client-side-only querying, and encryption-based read access mean for application design: summary-first querying, patch-sized writes, growth planning, collaboration expectations, and Haven app mappings
|
|
339
340
|
- [Example Snippets](./docs/examples/README.md) — Copy-paste Todo starters for all runtimes
|
|
340
341
|
- [Architecture Specification](./docs/specification.md) — Full technical details
|
|
341
342
|
- [React Native Guide](./docs/reactnative.md) — Native Automerge setup and troubleshooting
|
|
343
|
+
- [Kotlin and Java](./docs/kotlin-jvm.md) — JVM backends via the Kotlin client and the Node.js sidecar
|
|
342
344
|
- [Virtual Views](./docs/virtualview.md) — Aggregations and cross-database views
|
|
343
345
|
- [Ad-hoc Queries & Reactive Updates](./docs/adhoc-queries.md) — Summary buffer, `db.query()`, nested `include` lookups, ephemeral views, live queries and change listeners
|
|
344
346
|
- [Full-Text Search](./docs/fulltext-search.md) — Client-side encrypted full-text index, `db.searchText()`, the query `text` clause, attachment text extraction
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MindooDB stores and server state on a Durable Object's SQLite database.
|
|
3
|
+
*
|
|
4
|
+
* Durable Object SQL is synchronous and commits every write of one event-loop
|
|
5
|
+
* turn atomically; it rejects BEGIN/COMMIT. The store backend therefore runs
|
|
6
|
+
* without explicit transactions (batches are still serialized), and since the
|
|
7
|
+
* executor never awaits real I/O, a whole `putEntries` batch lands in one
|
|
8
|
+
* implicit transaction.
|
|
9
|
+
*/
|
|
10
|
+
import { type ExternalContentStore, type SqliteExecutor, type SqliteStoreBackend } from "../core/appendonlystores/sqlite/SqliteDriver";
|
|
11
|
+
import { SqliteContentAddressedStore } from "../core/appendonlystores/sqlite/SqliteContentAddressedStore";
|
|
12
|
+
import type { StoreKind } from "../core/appendonlystores/types";
|
|
13
|
+
import type { ServerDataStore } from "../server/ServerDataStore";
|
|
14
|
+
import type { R2Bucket, SqlStorage } from "./types";
|
|
15
|
+
/**
|
|
16
|
+
* Durable Object SQLite limits a BLOB, and a row, to 2 MB. Entries above this
|
|
17
|
+
* are refused with a clear error instead of a storage exception mid-batch —
|
|
18
|
+
* unless an R2 bucket takes them (see {@link r2ContentStore}).
|
|
19
|
+
*/
|
|
20
|
+
export declare const MAX_DURABLE_OBJECT_ENTRY_BYTES: number;
|
|
21
|
+
/** {@link SqliteExecutor} over `ctx.storage.sql`. */
|
|
22
|
+
export declare function createDurableObjectSqlExecutor(sql: SqlStorage): SqliteExecutor;
|
|
23
|
+
/** Payloads from this size on go to R2; well below the row limit, rare in practice. */
|
|
24
|
+
export declare const R2_CONTENT_THRESHOLD_BYTES: number;
|
|
25
|
+
/**
|
|
26
|
+
* Payloads of one store in R2, under `<keyPrefix><contentHash>`. The key
|
|
27
|
+
* prefix names the tenant, database and store, so stores never share
|
|
28
|
+
* objects and a database's objects can be removed by prefix.
|
|
29
|
+
*/
|
|
30
|
+
export declare function r2ContentStore(bucket: R2Bucket, keyPrefix: string): ExternalContentStore;
|
|
31
|
+
/** Remove every object under `prefix`. */
|
|
32
|
+
export declare function deleteR2Prefix(bucket: R2Bucket, prefix: string): Promise<void>;
|
|
33
|
+
/** Durable Object SQLite refuses statements with more bound parameters than this. */
|
|
34
|
+
export declare const DURABLE_OBJECT_MAX_BOUND_PARAMETERS = 100;
|
|
35
|
+
export declare function createDurableObjectStoreBackend(sql: SqlStorage, tablePrefix: string, externalContent?: ExternalContentStore): SqliteStoreBackend;
|
|
36
|
+
/** A content-addressed store whose tables carry `tablePrefix` in the object's database. */
|
|
37
|
+
export declare function createDurableObjectStore(sql: SqlStorage, dbId: string, storeKind: StoreKind, tablePrefix: string, externalContent?: ExternalContentStore): SqliteContentAddressedStore;
|
|
38
|
+
/**
|
|
39
|
+
* {@link ServerDataStore} on a key/value table. "Directories" are derived from
|
|
40
|
+
* the `/`-separated keys, as on the file system.
|
|
41
|
+
*/
|
|
42
|
+
export declare class DurableObjectServerDataStore implements ServerDataStore {
|
|
43
|
+
private readonly sql;
|
|
44
|
+
constructor(sql: SqlStorage);
|
|
45
|
+
private static normalize;
|
|
46
|
+
exists(key: string): boolean;
|
|
47
|
+
readBytes(key: string): Uint8Array | null;
|
|
48
|
+
readText(key: string): string | null;
|
|
49
|
+
writeBytes(key: string, value: Uint8Array): void;
|
|
50
|
+
writeText(key: string, value: string): void;
|
|
51
|
+
listDirectories(prefix: string): string[];
|
|
52
|
+
/** Names of the values directly below `prefix` (not the directories). */
|
|
53
|
+
listFiles(prefix: string): string[];
|
|
54
|
+
deleteTree(prefix: string): void;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=DurableObjectSql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DurableObjectSql.d.ts","sourceRoot":"","sources":["../../src/cloudflare/DurableObjectSql.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EAExB,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAAE,2BAA2B,EAAE,MAAM,6DAA6D,CAAC;AAC1G,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,QAA8B,CAAC;AAc1E,qDAAqD;AACrD,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,UAAU,GAAG,cAAc,CAkB9E;AAED,uFAAuF;AACvF,eAAO,MAAM,0BAA0B,QAAc,CAAC;AAEtD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,oBAAoB,CAiBxF;AAED,0CAA0C;AAC1C,wBAAsB,cAAc,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASpF;AAED,qFAAqF;AACrF,eAAO,MAAM,mCAAmC,MAAM,CAAC;AAEvD,wBAAgB,+BAA+B,CAC7C,GAAG,EAAE,UAAU,EACf,WAAW,EAAE,MAAM,EACnB,eAAe,CAAC,EAAE,oBAAoB,GACrC,kBAAkB,CAOpB;AAED,2FAA2F;AAC3F,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,UAAU,EACf,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,MAAM,EACnB,eAAe,CAAC,EAAE,oBAAoB,GACrC,2BAA2B,CAM7B;AAED;;;GAGG;AACH,qBAAa,4BAA6B,YAAW,eAAe;IACtD,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,UAAU;IAM5C,OAAO,CAAC,MAAM,CAAC,SAAS;IAIxB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAc5B,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAUzC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKpC,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI;IAahD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAI3C,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAmBzC,yEAAyE;IACzE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAcnC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAajC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MindooDB stores and server state on a Durable Object's SQLite database.
|
|
4
|
+
*
|
|
5
|
+
* Durable Object SQL is synchronous and commits every write of one event-loop
|
|
6
|
+
* turn atomically; it rejects BEGIN/COMMIT. The store backend therefore runs
|
|
7
|
+
* without explicit transactions (batches are still serialized), and since the
|
|
8
|
+
* executor never awaits real I/O, a whole `putEntries` batch lands in one
|
|
9
|
+
* implicit transaction.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.DurableObjectServerDataStore = exports.DURABLE_OBJECT_MAX_BOUND_PARAMETERS = exports.R2_CONTENT_THRESHOLD_BYTES = exports.MAX_DURABLE_OBJECT_ENTRY_BYTES = void 0;
|
|
13
|
+
exports.createDurableObjectSqlExecutor = createDurableObjectSqlExecutor;
|
|
14
|
+
exports.r2ContentStore = r2ContentStore;
|
|
15
|
+
exports.deleteR2Prefix = deleteR2Prefix;
|
|
16
|
+
exports.createDurableObjectStoreBackend = createDurableObjectStoreBackend;
|
|
17
|
+
exports.createDurableObjectStore = createDurableObjectStore;
|
|
18
|
+
const SqliteDriver_1 = require("../core/appendonlystores/sqlite/SqliteDriver");
|
|
19
|
+
const SqliteContentAddressedStore_1 = require("../core/appendonlystores/sqlite/SqliteContentAddressedStore");
|
|
20
|
+
/**
|
|
21
|
+
* Durable Object SQLite limits a BLOB, and a row, to 2 MB. Entries above this
|
|
22
|
+
* are refused with a clear error instead of a storage exception mid-batch —
|
|
23
|
+
* unless an R2 bucket takes them (see {@link r2ContentStore}).
|
|
24
|
+
*/
|
|
25
|
+
exports.MAX_DURABLE_OBJECT_ENTRY_BYTES = 2 * 1024 * 1024 - 64 * 1024;
|
|
26
|
+
function toBinding(value) {
|
|
27
|
+
if (value instanceof Uint8Array) {
|
|
28
|
+
if (value.byteLength > exports.MAX_DURABLE_OBJECT_ENTRY_BYTES) {
|
|
29
|
+
throw new Error(`Entry of ${value.byteLength} bytes exceeds the ${exports.MAX_DURABLE_OBJECT_ENTRY_BYTES}-byte limit of this server`);
|
|
30
|
+
}
|
|
31
|
+
return value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength);
|
|
32
|
+
}
|
|
33
|
+
return value;
|
|
34
|
+
}
|
|
35
|
+
/** {@link SqliteExecutor} over `ctx.storage.sql`. */
|
|
36
|
+
function createDurableObjectSqlExecutor(sql) {
|
|
37
|
+
return {
|
|
38
|
+
async exec(statement) {
|
|
39
|
+
sql.exec(statement);
|
|
40
|
+
},
|
|
41
|
+
async run(statement, params = []) {
|
|
42
|
+
const cursor = sql.exec(statement, ...params.map(toBinding));
|
|
43
|
+
cursor.toArray();
|
|
44
|
+
return { changes: cursor.rowsWritten };
|
|
45
|
+
},
|
|
46
|
+
async get(statement, params = []) {
|
|
47
|
+
const rows = sql.exec(statement, ...params.map(toBinding)).toArray();
|
|
48
|
+
return rows[0];
|
|
49
|
+
},
|
|
50
|
+
async all(statement, params = []) {
|
|
51
|
+
return sql.exec(statement, ...params.map(toBinding)).toArray();
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** Payloads from this size on go to R2; well below the row limit, rare in practice. */
|
|
56
|
+
exports.R2_CONTENT_THRESHOLD_BYTES = 1024 * 1024;
|
|
57
|
+
/**
|
|
58
|
+
* Payloads of one store in R2, under `<keyPrefix><contentHash>`. The key
|
|
59
|
+
* prefix names the tenant, database and store, so stores never share
|
|
60
|
+
* objects and a database's objects can be removed by prefix.
|
|
61
|
+
*/
|
|
62
|
+
function r2ContentStore(bucket, keyPrefix) {
|
|
63
|
+
return {
|
|
64
|
+
thresholdBytes: exports.R2_CONTENT_THRESHOLD_BYTES,
|
|
65
|
+
async put(contentHash, bytes) {
|
|
66
|
+
await bucket.put(`${keyPrefix}${contentHash}`, bytes);
|
|
67
|
+
},
|
|
68
|
+
async get(contentHash) {
|
|
69
|
+
const object = await bucket.get(`${keyPrefix}${contentHash}`);
|
|
70
|
+
return object ? new Uint8Array(await object.arrayBuffer()) : null;
|
|
71
|
+
},
|
|
72
|
+
async delete(contentHash) {
|
|
73
|
+
await bucket.delete(`${keyPrefix}${contentHash}`);
|
|
74
|
+
},
|
|
75
|
+
async clear() {
|
|
76
|
+
await deleteR2Prefix(bucket, keyPrefix);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/** Remove every object under `prefix`. */
|
|
81
|
+
async function deleteR2Prefix(bucket, prefix) {
|
|
82
|
+
let cursor;
|
|
83
|
+
do {
|
|
84
|
+
const page = await bucket.list({ prefix, cursor, limit: 1000 });
|
|
85
|
+
if (page.objects.length > 0) {
|
|
86
|
+
await bucket.delete(page.objects.map((object) => object.key));
|
|
87
|
+
}
|
|
88
|
+
cursor = page.truncated ? page.cursor : undefined;
|
|
89
|
+
} while (cursor);
|
|
90
|
+
}
|
|
91
|
+
/** Durable Object SQLite refuses statements with more bound parameters than this. */
|
|
92
|
+
exports.DURABLE_OBJECT_MAX_BOUND_PARAMETERS = 100;
|
|
93
|
+
function createDurableObjectStoreBackend(sql, tablePrefix, externalContent) {
|
|
94
|
+
return (0, SqliteDriver_1.createSqlBackend)(createDurableObjectSqlExecutor(sql), {
|
|
95
|
+
tablePrefix,
|
|
96
|
+
explicitTransactions: false,
|
|
97
|
+
externalContent,
|
|
98
|
+
maxBoundParameters: exports.DURABLE_OBJECT_MAX_BOUND_PARAMETERS,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/** A content-addressed store whose tables carry `tablePrefix` in the object's database. */
|
|
102
|
+
function createDurableObjectStore(sql, dbId, storeKind, tablePrefix, externalContent) {
|
|
103
|
+
return new SqliteContentAddressedStore_1.SqliteContentAddressedStore(dbId, storeKind, createDurableObjectStoreBackend(sql, tablePrefix, externalContent));
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* {@link ServerDataStore} on a key/value table. "Directories" are derived from
|
|
107
|
+
* the `/`-separated keys, as on the file system.
|
|
108
|
+
*/
|
|
109
|
+
class DurableObjectServerDataStore {
|
|
110
|
+
constructor(sql) {
|
|
111
|
+
this.sql = sql;
|
|
112
|
+
sql.exec("CREATE TABLE IF NOT EXISTS mindoo_server_kv (key TEXT PRIMARY KEY NOT NULL, value BLOB NOT NULL)");
|
|
113
|
+
}
|
|
114
|
+
static normalize(key) {
|
|
115
|
+
return key.split("/").filter((part) => part.length > 0).join("/");
|
|
116
|
+
}
|
|
117
|
+
exists(key) {
|
|
118
|
+
const normalized = DurableObjectServerDataStore.normalize(key);
|
|
119
|
+
if (normalized === "")
|
|
120
|
+
return true;
|
|
121
|
+
const row = this.sql
|
|
122
|
+
.exec("SELECT 1 AS present FROM mindoo_server_kv WHERE key = ? OR substr(key, 1, ?) = ? LIMIT 1", normalized, normalized.length + 1, `${normalized}/`)
|
|
123
|
+
.toArray();
|
|
124
|
+
return row.length > 0;
|
|
125
|
+
}
|
|
126
|
+
readBytes(key) {
|
|
127
|
+
const rows = this.sql
|
|
128
|
+
.exec("SELECT value FROM mindoo_server_kv WHERE key = ?", DurableObjectServerDataStore.normalize(key))
|
|
129
|
+
.toArray();
|
|
130
|
+
return rows.length > 0 ? new Uint8Array(rows[0].value) : null;
|
|
131
|
+
}
|
|
132
|
+
readText(key) {
|
|
133
|
+
const bytes = this.readBytes(key);
|
|
134
|
+
return bytes === null ? null : new TextDecoder().decode(bytes);
|
|
135
|
+
}
|
|
136
|
+
writeBytes(key, value) {
|
|
137
|
+
if (value.byteLength > exports.MAX_DURABLE_OBJECT_ENTRY_BYTES) {
|
|
138
|
+
throw new Error(`Server state "${key}" is ${value.byteLength} bytes; Durable Object storage holds at most 2 MB per value`);
|
|
139
|
+
}
|
|
140
|
+
this.sql.exec("INSERT INTO mindoo_server_kv(key, value) VALUES(?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value", DurableObjectServerDataStore.normalize(key), value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength));
|
|
141
|
+
}
|
|
142
|
+
writeText(key, value) {
|
|
143
|
+
this.writeBytes(key, new TextEncoder().encode(value));
|
|
144
|
+
}
|
|
145
|
+
listDirectories(prefix) {
|
|
146
|
+
const normalized = DurableObjectServerDataStore.normalize(prefix);
|
|
147
|
+
const base = normalized === "" ? "" : `${normalized}/`;
|
|
148
|
+
const rows = this.sql
|
|
149
|
+
.exec("SELECT key FROM mindoo_server_kv WHERE substr(key, 1, ?) = ?", base.length, base)
|
|
150
|
+
.toArray();
|
|
151
|
+
const names = new Set();
|
|
152
|
+
for (const { key } of rows) {
|
|
153
|
+
const rest = key.substring(base.length);
|
|
154
|
+
const slash = rest.indexOf("/");
|
|
155
|
+
if (slash > 0)
|
|
156
|
+
names.add(rest.substring(0, slash));
|
|
157
|
+
}
|
|
158
|
+
return [...names];
|
|
159
|
+
}
|
|
160
|
+
/** Names of the values directly below `prefix` (not the directories). */
|
|
161
|
+
listFiles(prefix) {
|
|
162
|
+
const normalized = DurableObjectServerDataStore.normalize(prefix);
|
|
163
|
+
const base = normalized === "" ? "" : `${normalized}/`;
|
|
164
|
+
return this.sql
|
|
165
|
+
.exec("SELECT key FROM mindoo_server_kv WHERE substr(key, 1, ?) = ?", base.length, base)
|
|
166
|
+
.toArray()
|
|
167
|
+
.map(({ key }) => key.substring(base.length))
|
|
168
|
+
.filter((rest) => rest.length > 0 && !rest.includes("/"));
|
|
169
|
+
}
|
|
170
|
+
deleteTree(prefix) {
|
|
171
|
+
const normalized = DurableObjectServerDataStore.normalize(prefix);
|
|
172
|
+
if (normalized === "") {
|
|
173
|
+
this.sql.exec("DELETE FROM mindoo_server_kv");
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this.sql.exec("DELETE FROM mindoo_server_kv WHERE key = ? OR substr(key, 1, ?) = ?", normalized, normalized.length + 1, `${normalized}/`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
exports.DurableObjectServerDataStore = DurableObjectServerDataStore;
|
|
180
|
+
//# sourceMappingURL=DurableObjectSql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DurableObjectSql.js","sourceRoot":"","sources":["../../src/cloudflare/DurableObjectSql.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One Durable Object per (tenant, database), named `<tenantId>/<dbId>`.
|
|
3
|
+
*
|
|
4
|
+
* Each object runs the platform-neutral server core for its database: the
|
|
5
|
+
* docs and attachments stores live in the object's SQLite, and access control
|
|
6
|
+
* runs locally with the same code as on Node. For that it needs the tenant's
|
|
7
|
+
* directory, so every object other than `directory` keeps a read-only replica
|
|
8
|
+
* of the directory store and pulls new entries from the tenant's directory
|
|
9
|
+
* object before it serves a request (at most every few seconds, immediately
|
|
10
|
+
* when the directory announces a change, and once more when a request was
|
|
11
|
+
* denied — a grant may just have arrived).
|
|
12
|
+
*
|
|
13
|
+
* The `directory` object is also the tenant's hub: it answers the auth
|
|
14
|
+
* handshake (challenges are kept in memory), proxies RFC 3161 requests, holds
|
|
15
|
+
* the Server-Sent-Events streams and receives the change events of the other
|
|
16
|
+
* databases, and knows which databases the tenant has.
|
|
17
|
+
*/
|
|
18
|
+
import type { DurableObjectState, MindooCloudflareEnv } from "./types";
|
|
19
|
+
export declare class MindooDatabaseObject {
|
|
20
|
+
private readonly ctx;
|
|
21
|
+
private readonly env;
|
|
22
|
+
private readonly settings;
|
|
23
|
+
private readonly cryptoAdapter;
|
|
24
|
+
private dataStore;
|
|
25
|
+
private stores;
|
|
26
|
+
private tenantId;
|
|
27
|
+
private dbId;
|
|
28
|
+
private tenantState;
|
|
29
|
+
private tenantStateLoad;
|
|
30
|
+
private tenantManager;
|
|
31
|
+
private core;
|
|
32
|
+
/** Change events of the whole tenant; only used in the directory object. */
|
|
33
|
+
private readonly eventBus;
|
|
34
|
+
private replicaCheckedAt;
|
|
35
|
+
private replicaRefresh;
|
|
36
|
+
/** Payload buffers of store RPC exchanges with the server object. */
|
|
37
|
+
private readonly rpcBytes;
|
|
38
|
+
/**
|
|
39
|
+
* Requests that carry entry payloads run one at a time: a batch of
|
|
40
|
+
* attachment chunks is up to ~25 MB plus its encrypted copies, and the
|
|
41
|
+
* isolate has 128 MB. Metadata requests are not queued.
|
|
42
|
+
*/
|
|
43
|
+
private payloadQueue;
|
|
44
|
+
private withPayloadSlot;
|
|
45
|
+
constructor(ctx: DurableObjectState, env: MindooCloudflareEnv);
|
|
46
|
+
private openStorage;
|
|
47
|
+
private get isDirectory();
|
|
48
|
+
fetch(request: Request): Promise<Response>;
|
|
49
|
+
/** The object's own stores, and the directory (own or replica). */
|
|
50
|
+
private store;
|
|
51
|
+
/** R2 keys of this object's large entries start with this. */
|
|
52
|
+
private r2Prefix;
|
|
53
|
+
private loadTenantState;
|
|
54
|
+
private fetchTenantState;
|
|
55
|
+
/** Tell the tenant's directory object that this database exists. */
|
|
56
|
+
private registerWithDirectory;
|
|
57
|
+
private createCore;
|
|
58
|
+
private directoryObject;
|
|
59
|
+
/** Let the server object push an accepted write on to the peers. */
|
|
60
|
+
private reportToCluster;
|
|
61
|
+
private forwardEvent;
|
|
62
|
+
private registeredDatabases;
|
|
63
|
+
/** Directory object: let every database pull the directory and run its purges. */
|
|
64
|
+
private notifyDatabasesOfDirectoryChange;
|
|
65
|
+
/**
|
|
66
|
+
* Pull new directory entries into the replica. Returns whether anything
|
|
67
|
+
* arrived. Concurrent callers share one pull.
|
|
68
|
+
*/
|
|
69
|
+
private refreshDirectoryReplica;
|
|
70
|
+
private pullDirectory;
|
|
71
|
+
/** Directory object: one page of directory entries after `cursor`. */
|
|
72
|
+
private directoryChanges;
|
|
73
|
+
private internal;
|
|
74
|
+
/**
|
|
75
|
+
* This object's stores for peer replication in the server object. Pulled
|
|
76
|
+
* entries of purged documents are refused, as on Node.
|
|
77
|
+
*/
|
|
78
|
+
private storeRpc;
|
|
79
|
+
/** Delete everything of a removed tenant (the directory object first wipes the others). */
|
|
80
|
+
private wipe;
|
|
81
|
+
private public;
|
|
82
|
+
private sync;
|
|
83
|
+
/** Server-Sent-Events stream on the tenant's event bus (directory object only). */
|
|
84
|
+
private openEventStream;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=MindooDatabaseObject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MindooDatabaseObject.d.ts","sourceRoot":"","sources":["../../src/cloudflare/MindooDatabaseObject.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AA2DH,OAAO,KAAK,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAyBvE,qBAAa,oBAAoB;IA+B7B,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,GAAG;IA/BtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA8B;IAC5D,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,MAAM,CAAkD;IAChE,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,eAAe,CAAqC;IAC5D,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,IAAI,CAAmC;IAC/C,4EAA4E;IAC5E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,cAAc,CAAiC;IACvD,qEAAqE;IACrE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAChD;;;;OAIG;IACH,OAAO,CAAC,YAAY,CAAuC;IAE3D,OAAO,CAAC,eAAe;gBAOJ,GAAG,EAAE,kBAAkB,EACvB,GAAG,EAAE,mBAAmB;IAM3C,OAAO,CAAC,WAAW;IAMnB,OAAO,KAAK,WAAW,GAEtB;IAEK,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;IA2BhD,mEAAmE;IACnE,OAAO,CAAC,KAAK;IAwBb,8DAA8D;IAC9D,OAAO,CAAC,QAAQ;YAMF,eAAe;YAaf,gBAAgB;IAqD9B,oEAAoE;YACtD,qBAAqB;IAYnC,OAAO,CAAC,UAAU;IAyFlB,OAAO,CAAC,eAAe;IAIvB,oEAAoE;YACtD,eAAe;YAYf,YAAY;IAc1B,OAAO,CAAC,mBAAmB;IAK3B,kFAAkF;IAClF,OAAO,CAAC,gCAAgC;IAaxC;;;OAGG;YACW,uBAAuB;YAUvB,aAAa;IA0C3B,sEAAsE;YACxD,gBAAgB;YAchB,QAAQ;IAuCtB;;;OAGG;YACW,QAAQ;IAsCtB,2FAA2F;YAC7E,IAAI;YA0BJ,MAAM;YAyDN,IAAI;IAyClB,mFAAmF;IACnF,OAAO,CAAC,eAAe;CAoCxB"}
|