@powerhousedao/reactor 6.2.3-dev.3 → 6.2.3-dev.30
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/dist/{build-worker-executor-DnU3ZU4H.js → build-worker-executor-Bvoba-AV.js} +24 -8
- package/dist/build-worker-executor-Bvoba-AV.js.map +1 -0
- package/dist/{document-indexer-C5Gsa1B3.js → document-indexer-BVTGbEB0.js} +190 -40
- package/dist/document-indexer-BVTGbEB0.js.map +1 -0
- package/dist/entry.d.ts +2 -1
- package/dist/entry.js +10 -6
- package/dist/entry.js.map +1 -1
- package/dist/{errors-D3S6Eysd.js → errors-BM_ULVWd.js} +9 -1
- package/dist/{errors-D3S6Eysd.js.map → errors-BM_ULVWd.js.map} +1 -1
- package/dist/{drive-container-types-yZrksiJR.js → forwarding-logger-CnuVDVze.js} +1297 -241
- package/dist/forwarding-logger-CnuVDVze.js.map +1 -0
- package/dist/index.d.ts +2707 -2040
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1708 -648
- package/dist/index.js.map +1 -1
- package/dist/projection-entry.d.ts +2 -1
- package/dist/projection-entry.js +11 -17
- package/dist/projection-entry.js.map +1 -1
- package/dist/{projection-shard-manager-CPQc5XHL.js → projection-shard-manager-BpcqDtnQ.js} +4 -4
- package/dist/projection-shard-manager-BpcqDtnQ.js.map +1 -0
- package/dist/{projection-worker-wI4PwcV2.js → projection-worker-D8uNFdwX.js} +1 -1
- package/dist/{projection-worker-wI4PwcV2.js.map → projection-worker-D8uNFdwX.js.map} +1 -1
- package/dist/{transport-CuogVKN_.js → transport-B3G50KVd.js} +1 -1
- package/dist/{transport-CuogVKN_.js.map → transport-B3G50KVd.js.map} +1 -1
- package/dist/{transport-ByGviWdZ.js → transport-CZDHzfvy.js} +1 -1
- package/dist/{transport-ByGviWdZ.js.map → transport-CZDHzfvy.js.map} +1 -1
- package/dist/{worker-handle-CrERzl8s.js → worker-handle-C2rLUHwv.js} +22 -16
- package/dist/worker-handle-C2rLUHwv.js.map +1 -0
- package/package.json +19 -10
- package/dist/build-worker-executor-DnU3ZU4H.js.map +0 -1
- package/dist/document-indexer-C5Gsa1B3.js.map +0 -1
- package/dist/drive-container-types-yZrksiJR.js.map +0 -1
- package/dist/error-info-Cpu4OY3o.js +0 -62
- package/dist/error-info-Cpu4OY3o.js.map +0 -1
- package/dist/forwarding-logger-BBkMSxuJ.js +0 -85
- package/dist/forwarding-logger-BBkMSxuJ.js.map +0 -1
- package/dist/projection-shard-manager-CPQc5XHL.js.map +0 -1
- package/dist/types-DMKLa0Ok.js +0 -33
- package/dist/types-DMKLa0Ok.js.map +0 -1
- package/dist/worker-HPysBfhx.js +0 -22
- package/dist/worker-HPysBfhx.js.map +0 -1
- package/dist/worker-handle-CrERzl8s.js.map +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as ReactorEventTypes } from "./types-DMKLa0Ok.js";
|
|
1
|
+
import { C as DocumentMetaCache, S as KyselyOperationIndex, a as DEFAULT_DRIVE_CONTAINER_TYPES, b as EventBus, d as KyselyOperationStore, f as KyselyKeyframeStore, m as SimpleJobExecutor, o as REACTOR_SCHEMA, ot as ReactorEventTypes, p as DocumentModelRegistry, v as KyselyExecutionScope, w as CollectionMembershipCache, x as KyselyWriteCache } from "./forwarding-logger-CnuVDVze.js";
|
|
3
2
|
//#region src/executor/worker/build-worker-executor.ts
|
|
4
3
|
async function defaultLoadFactory(spec) {
|
|
5
4
|
const ref = spec.module;
|
|
@@ -38,11 +37,18 @@ async function buildWorkerExecutor(options) {
|
|
|
38
37
|
const loadFactory = options.loadFactory ?? defaultLoadFactory;
|
|
39
38
|
const registry = new DocumentModelRegistry();
|
|
40
39
|
await loadModelManifest(init.models, loadFactory, registry, logger);
|
|
41
|
-
let
|
|
42
|
-
if (init.
|
|
43
|
-
|
|
40
|
+
let signer;
|
|
41
|
+
if (init.signer) try {
|
|
42
|
+
signer = await loadFactory(init.signer);
|
|
44
43
|
} catch (error) {
|
|
45
|
-
logger.error("worker failed to load
|
|
44
|
+
logger.error("worker failed to load signer: @spec @error", init.signer.module, error);
|
|
45
|
+
throw error;
|
|
46
|
+
}
|
|
47
|
+
let trustPolicy;
|
|
48
|
+
if (init.trustPolicy) try {
|
|
49
|
+
trustPolicy = await loadFactory(init.trustPolicy);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
logger.error("worker failed to load trust policy: @spec @error", init.trustPolicy.module, error);
|
|
46
52
|
throw error;
|
|
47
53
|
}
|
|
48
54
|
const database = baseDatabase.withSchema(REACTOR_SCHEMA);
|
|
@@ -67,17 +73,27 @@ async function buildWorkerExecutor(options) {
|
|
|
67
73
|
jobMeta: event.jobMeta
|
|
68
74
|
};
|
|
69
75
|
});
|
|
76
|
+
let signatureRefusals = [];
|
|
77
|
+
eventBus.subscribe(ReactorEventTypes.SIGNATURE_REFUSED, (_t, event) => {
|
|
78
|
+
signatureRefusals.push(event);
|
|
79
|
+
});
|
|
80
|
+
const executorConfig = options.executorConfig ?? {};
|
|
70
81
|
return {
|
|
71
|
-
executor: new SimpleJobExecutor(logger, registry, operationStore, eventBus, writeCache, operationIndex, documentMetaCache, collectionMembershipCache, driveContainerTypes,
|
|
82
|
+
executor: new SimpleJobExecutor(logger, registry, operationStore, eventBus, writeCache, operationIndex, documentMetaCache, collectionMembershipCache, driveContainerTypes, executorConfig, executionScope, signer, trustPolicy),
|
|
72
83
|
registry,
|
|
73
84
|
takeLastWriteReady() {
|
|
74
85
|
const captured = lastWriteReady;
|
|
75
86
|
lastWriteReady = null;
|
|
76
87
|
return captured;
|
|
88
|
+
},
|
|
89
|
+
takeSignatureRefusals() {
|
|
90
|
+
const captured = signatureRefusals;
|
|
91
|
+
signatureRefusals = [];
|
|
92
|
+
return captured;
|
|
77
93
|
}
|
|
78
94
|
};
|
|
79
95
|
}
|
|
80
96
|
//#endregion
|
|
81
97
|
export { defaultLoadFactory as n, buildWorkerExecutor as t };
|
|
82
98
|
|
|
83
|
-
//# sourceMappingURL=build-worker-executor-
|
|
99
|
+
//# sourceMappingURL=build-worker-executor-Bvoba-AV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-worker-executor-Bvoba-AV.js","names":[],"sources":["../src/executor/worker/build-worker-executor.ts"],"sourcesContent":["import type {\n DocumentModelModule,\n ISigner,\n OperationWithContext,\n} from \"@powerhousedao/shared/document-model\";\nimport type { ILogger } from \"document-model\";\nimport type { Kysely } from \"kysely\";\nimport { CollectionMembershipCache } from \"../../cache/collection-membership-cache.js\";\nimport { DocumentMetaCache } from \"../../cache/document-meta-cache.js\";\nimport { KyselyOperationIndex } from \"../../cache/kysely-operation-index.js\";\nimport { KyselyWriteCache } from \"../../cache/kysely-write-cache.js\";\nimport type { WriteCacheConfig } from \"../../cache/write-cache-types.js\";\nimport { DEFAULT_DRIVE_CONTAINER_TYPES } from \"../../core/drive-container-types.js\";\nimport type { Database } from \"../../core/types.js\";\nimport { EventBus } from \"../../events/event-bus.js\";\nimport {\n ReactorEventTypes,\n type JobWriteReadyEvent,\n type SignatureRefusedEvent,\n} from \"../../events/types.js\";\nimport { DocumentModelRegistry } from \"../../registry/implementation.js\";\nimport type { JobMeta } from \"../../shared/types.js\";\nimport { KyselyKeyframeStore } from \"../../storage/kysely/keyframe-store.js\";\nimport { KyselyOperationStore } from \"../../storage/kysely/store.js\";\nimport type { Database as StorageDatabase } from \"../../storage/kysely/types.js\";\nimport { REACTOR_SCHEMA } from \"../../storage/migrations/migrator.js\";\nimport { KyselyExecutionScope } from \"../execution-scope.js\";\nimport { SimpleJobExecutor } from \"../simple-job-executor.js\";\nimport type { SignatureTrustPolicy } from \"../../signer/types.js\";\nimport type { JobExecutorConfig } from \"../types.js\";\nimport type {\n FactorySpec,\n InitMessage,\n ModelManifestEntry,\n} from \"./protocol.js\";\n\n/**\n * In-worker capture of the JOB_WRITE_READY event emitted by the executor.\n * The worker forwards `operations` and `jobMeta` back to the parent; the\n * parent re-enriches `collectionMemberships` at emit time.\n */\nexport type WorkerWriteReadyCapture = {\n operations: OperationWithContext[];\n jobMeta: JobMeta;\n};\n\nexport type WorkerExecutorStack = {\n executor: SimpleJobExecutor;\n registry: DocumentModelRegistry;\n /**\n * Synchronously pops the most-recent JOB_WRITE_READY captured on this\n * worker's local event bus and clears it. Returns null if the executor\n * did not produce one for this job.\n */\n takeLastWriteReady(): WorkerWriteReadyCapture | null;\n /** Drains the refusals this worker's executor emitted since the last call. */\n takeSignatureRefusals(): SignatureRefusedEvent[];\n};\n\nexport type BuildWorkerExecutorOptions = {\n init: InitMessage;\n database: Kysely<Database>;\n logger: ILogger;\n executorConfig?: JobExecutorConfig;\n driveContainerTypes?: ReadonlySet<string>;\n /**\n * Override the module loader used to materialize factory specs. Tests\n * can inject a deterministic resolver instead of touching the real\n * Node module loader.\n */\n loadFactory?: (spec: FactorySpec) => Promise<unknown>;\n};\n\nexport async function defaultLoadFactory(spec: FactorySpec): Promise<unknown> {\n const ref = spec.module;\n const specifier =\n \"filePath\" in ref\n ? new URL(`file://${ref.filePath}`).href\n : ref.packageName;\n const mod = (await import(specifier)) as Record<string, unknown>;\n const exported = mod[ref.exportName];\n if (typeof exported === \"function\") {\n return (exported as (args: unknown) => unknown)(spec.initArgs);\n }\n return exported;\n}\n\nasync function loadModelManifest(\n entries: ModelManifestEntry[],\n loadFactory: (spec: FactorySpec) => Promise<unknown>,\n registry: DocumentModelRegistry,\n logger: ILogger,\n): Promise<void> {\n for (const entry of entries) {\n let module: DocumentModelModule;\n try {\n module = (await loadFactory(entry.spec)) as DocumentModelModule;\n } catch (error) {\n logger.error(\n \"worker failed to load document model: @entry @error\",\n entry,\n error,\n );\n throw error;\n }\n const [result] = registry.registerModules(module);\n if (result.status === \"error\") {\n logger.error(\n \"worker failed to register document model: @entry @error\",\n entry,\n result.error,\n );\n throw result.error;\n }\n }\n}\n\n/**\n * Assembles the in-worker storage stack plus a {@link SimpleJobExecutor}\n * bound to a pre-built Kysely instance. The parent owns the wire protocol\n * and routing; the worker owns everything below `SimpleJobExecutor`.\n *\n * The local event bus exists only to satisfy the executor's contract: its\n * JOB_WRITE_READY emissions are captured here and shipped to the parent\n * via {@link WorkerExecutorStack.takeLastWriteReady}.\n */\nexport async function buildWorkerExecutor(\n options: BuildWorkerExecutorOptions,\n): Promise<WorkerExecutorStack> {\n const { init, database: baseDatabase, logger } = options;\n const driveContainerTypes =\n options.driveContainerTypes ?? DEFAULT_DRIVE_CONTAINER_TYPES;\n const loadFactory = options.loadFactory ?? defaultLoadFactory;\n\n const registry = new DocumentModelRegistry();\n await loadModelManifest(init.models, loadFactory, registry, logger);\n\n let signer: ISigner | undefined;\n if (init.signer) {\n try {\n signer = (await loadFactory(init.signer)) as ISigner;\n } catch (error) {\n logger.error(\n \"worker failed to load signer: @spec @error\",\n init.signer.module,\n error,\n );\n throw error;\n }\n }\n\n let trustPolicy: SignatureTrustPolicy | undefined;\n if (init.trustPolicy) {\n try {\n trustPolicy = (await loadFactory(\n init.trustPolicy,\n )) as SignatureTrustPolicy;\n } catch (error) {\n logger.error(\n \"worker failed to load trust policy: @spec @error\",\n init.trustPolicy.module,\n error,\n );\n throw error;\n }\n }\n\n const database = baseDatabase.withSchema(REACTOR_SCHEMA);\n const operationStore = new KyselyOperationStore(\n database as unknown as Kysely<StorageDatabase>,\n );\n const keyframeStore = new KyselyKeyframeStore(\n database as unknown as Kysely<StorageDatabase>,\n );\n\n const cacheConfig: WriteCacheConfig = {\n maxDocuments: 100,\n ringBufferSize: 10,\n keyframeInterval: 10,\n };\n const writeCache = new KyselyWriteCache(\n keyframeStore,\n operationStore,\n registry,\n cacheConfig,\n );\n await writeCache.startup();\n\n const operationIndex = new KyselyOperationIndex(\n database as unknown as Kysely<StorageDatabase>,\n );\n\n const documentMetaCache = new DocumentMetaCache(operationStore, {\n maxDocuments: 1000,\n });\n await documentMetaCache.startup();\n\n const collectionMembershipCache = new CollectionMembershipCache(\n operationIndex,\n );\n\n const executionScope = new KyselyExecutionScope(\n database as unknown as Kysely<StorageDatabase>,\n operationStore,\n operationIndex,\n keyframeStore,\n writeCache,\n documentMetaCache,\n collectionMembershipCache,\n );\n\n const eventBus = new EventBus();\n let lastWriteReady: WorkerWriteReadyCapture | null = null;\n eventBus.subscribe(\n ReactorEventTypes.JOB_WRITE_READY,\n (_t: number, event: JobWriteReadyEvent) => {\n lastWriteReady = {\n operations: event.operations,\n jobMeta: event.jobMeta,\n };\n },\n );\n\n let signatureRefusals: SignatureRefusedEvent[] = [];\n eventBus.subscribe(\n ReactorEventTypes.SIGNATURE_REFUSED,\n (_t: number, event: SignatureRefusedEvent) => {\n signatureRefusals.push(event);\n },\n );\n\n const executorConfig = options.executorConfig ?? {};\n const executor = new SimpleJobExecutor(\n logger,\n registry,\n operationStore,\n eventBus,\n writeCache,\n operationIndex,\n documentMetaCache,\n collectionMembershipCache,\n driveContainerTypes,\n executorConfig,\n executionScope,\n signer,\n trustPolicy,\n );\n\n return {\n executor,\n registry,\n takeLastWriteReady(): WorkerWriteReadyCapture | null {\n const captured = lastWriteReady;\n lastWriteReady = null;\n return captured;\n },\n takeSignatureRefusals(): SignatureRefusedEvent[] {\n const captured = signatureRefusals;\n signatureRefusals = [];\n return captured;\n },\n };\n}\n"],"mappings":";;AAyEA,eAAsB,mBAAmB,MAAqC;CAC5E,MAAM,MAAM,KAAK;CAMjB,MAAM,YAAW,OAJf,cAAc,MAAA,OACV,IAAI,IAAI,UAAU,IAAI,UAAU,CAAC,CAAC,QAAA,OAClC,IAAI,cAAA,CAEW,IAAI;CACzB,IAAI,OAAO,aAAa,YACtB,OAAQ,SAAwC,KAAK,QAAQ;CAE/D,OAAO;AACT;AAEA,eAAe,kBACb,SACA,aACA,UACA,QACe;CACf,KAAK,MAAM,SAAS,SAAS;EAC3B,IAAI;EACJ,IAAI;GACF,SAAU,MAAM,YAAY,MAAM,IAAI;EACxC,SAAS,OAAO;GACd,OAAO,MACL,uDACA,OACA,KACF;GACA,MAAM;EACR;EACA,MAAM,CAAC,UAAU,SAAS,gBAAgB,MAAM;EAChD,IAAI,OAAO,WAAW,SAAS;GAC7B,OAAO,MACL,2DACA,OACA,OAAO,KACT;GACA,MAAM,OAAO;EACf;CACF;AACF;;;;;;;;;;AAWA,eAAsB,oBACpB,SAC8B;CAC9B,MAAM,EAAE,MAAM,UAAU,cAAc,WAAW;CACjD,MAAM,sBACJ,QAAQ,uBAAuB;CACjC,MAAM,cAAc,QAAQ,eAAe;CAE3C,MAAM,WAAW,IAAI,sBAAsB;CAC3C,MAAM,kBAAkB,KAAK,QAAQ,aAAa,UAAU,MAAM;CAElE,IAAI;CACJ,IAAI,KAAK,QACP,IAAI;EACF,SAAU,MAAM,YAAY,KAAK,MAAM;CACzC,SAAS,OAAO;EACd,OAAO,MACL,8CACA,KAAK,OAAO,QACZ,KACF;EACA,MAAM;CACR;CAGF,IAAI;CACJ,IAAI,KAAK,aACP,IAAI;EACF,cAAe,MAAM,YACnB,KAAK,WACP;CACF,SAAS,OAAO;EACd,OAAO,MACL,oDACA,KAAK,YAAY,QACjB,KACF;EACA,MAAM;CACR;CAGF,MAAM,WAAW,aAAa,WAAW,cAAc;CACvD,MAAM,iBAAiB,IAAI,qBACzB,QACF;CACA,MAAM,gBAAgB,IAAI,oBACxB,QACF;CAOA,MAAM,aAAa,IAAI,iBACrB,eACA,gBACA,UACA;EARA,cAAc;EACd,gBAAgB;EAChB,kBAAkB;CAMR,CACZ;CACA,MAAM,WAAW,QAAQ;CAEzB,MAAM,iBAAiB,IAAI,qBACzB,QACF;CAEA,MAAM,oBAAoB,IAAI,kBAAkB,gBAAgB,EAC9D,cAAc,IAChB,CAAC;CACD,MAAM,kBAAkB,QAAQ;CAEhC,MAAM,4BAA4B,IAAI,0BACpC,cACF;CAEA,MAAM,iBAAiB,IAAI,qBACzB,UACA,gBACA,gBACA,eACA,YACA,mBACA,yBACF;CAEA,MAAM,WAAW,IAAI,SAAS;CAC9B,IAAI,iBAAiD;CACrD,SAAS,UACP,kBAAkB,kBACjB,IAAY,UAA8B;EACzC,iBAAiB;GACf,YAAY,MAAM;GAClB,SAAS,MAAM;EACjB;CACF,CACF;CAEA,IAAI,oBAA6C,CAAC;CAClD,SAAS,UACP,kBAAkB,oBACjB,IAAY,UAAiC;EAC5C,kBAAkB,KAAK,KAAK;CAC9B,CACF;CAEA,MAAM,iBAAiB,QAAQ,kBAAkB,CAAC;CAiBlD,OAAO;EACL,UAAA,IAjBmB,kBACnB,QACA,UACA,gBACA,UACA,YACA,gBACA,mBACA,2BACA,qBACA,gBACA,gBACA,QACA,WAIO;EACP;EACA,qBAAqD;GACnD,MAAM,WAAW;GACjB,iBAAiB;GACjB,OAAO;EACT;EACA,wBAAiD;GAC/C,MAAM,WAAW;GACjB,oBAAoB,CAAC;GACrB,OAAO;EACT;CACF;AACF"}
|
|
@@ -1,17 +1,55 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as ReactorEventTypes } from "./types-DMKLa0Ok.js";
|
|
1
|
+
import { ot as ReactorEventTypes, ut as yieldToMain } from "./forwarding-logger-CnuVDVze.js";
|
|
3
2
|
import { createAuthState, isDenied } from "@powerhousedao/shared/document-model";
|
|
4
3
|
import { v4 } from "uuid";
|
|
5
4
|
import { childLogger } from "document-model";
|
|
6
5
|
//#region src/read-models/base-read-model.ts
|
|
6
|
+
/** Small enough that a chunk's transaction rarely outlasts the yield deadline. */
|
|
7
|
+
const DEFAULT_COMMIT_CHUNK_SIZE = 50;
|
|
8
|
+
/** Matches the executor's own default, so both paths yield on the same cadence. */
|
|
9
|
+
const DEFAULT_READ_MODEL_YIELD_DEADLINE_MS = 50;
|
|
10
|
+
const defaultReadModelIndexingConfig = {
|
|
11
|
+
commitChunkSize: 50,
|
|
12
|
+
yieldDeadlineMs: 50
|
|
13
|
+
};
|
|
14
|
+
/** For read models whose callers can observe where a batch was split. */
|
|
15
|
+
const unchunkedReadModelIndexingConfig = {
|
|
16
|
+
commitChunkSize: Number.MAX_SAFE_INTEGER,
|
|
17
|
+
yieldDeadlineMs: 50
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Keeps the chunk size at one operation or more: a chunk of zero or less never
|
|
21
|
+
* advances the indexing loop, so the pass would spin without ever resolving.
|
|
22
|
+
*/
|
|
23
|
+
function normalizeIndexingConfig(config) {
|
|
24
|
+
if (Number.isNaN(config.commitChunkSize)) return {
|
|
25
|
+
...config,
|
|
26
|
+
commitChunkSize: 50
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
...config,
|
|
30
|
+
commitChunkSize: Math.max(1, Math.min(Math.floor(config.commitChunkSize), Number.MAX_SAFE_INTEGER))
|
|
31
|
+
};
|
|
32
|
+
}
|
|
7
33
|
/**
|
|
8
34
|
* Base class for read models that provides catch-up/rewind functionality.
|
|
9
35
|
* Handles initialization, state tracking via ViewState table, and consistency tracking.
|
|
10
36
|
* Subclasses override commitOperations() with their specific domain logic.
|
|
11
37
|
*/
|
|
12
38
|
var BaseReadModel = class {
|
|
39
|
+
db;
|
|
40
|
+
operationIndex;
|
|
41
|
+
writeCache;
|
|
42
|
+
consistencyTracker;
|
|
43
|
+
config;
|
|
13
44
|
lastOrdinal = 0;
|
|
14
45
|
name;
|
|
46
|
+
indexing;
|
|
47
|
+
/**
|
|
48
|
+
* Lowest ordinal this model failed to commit and has not committed since, or
|
|
49
|
+
* zero when there is none. The stored cursor is held below it so replay from
|
|
50
|
+
* the cursor still reaches every operation the failed pass left out.
|
|
51
|
+
*/
|
|
52
|
+
uncommittedOrdinal = 0;
|
|
15
53
|
constructor(db, operationIndex, writeCache, consistencyTracker, config) {
|
|
16
54
|
this.db = db;
|
|
17
55
|
this.operationIndex = operationIndex;
|
|
@@ -19,6 +57,7 @@ var BaseReadModel = class {
|
|
|
19
57
|
this.consistencyTracker = consistencyTracker;
|
|
20
58
|
this.config = config;
|
|
21
59
|
this.name = config.readModelId;
|
|
60
|
+
this.indexing = normalizeIndexingConfig(config.indexing ?? defaultReadModelIndexingConfig);
|
|
22
61
|
}
|
|
23
62
|
/**
|
|
24
63
|
* Initializes the read model by loading state and catching up on missed operations.
|
|
@@ -36,15 +75,33 @@ var BaseReadModel = class {
|
|
|
36
75
|
}
|
|
37
76
|
}
|
|
38
77
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
78
|
+
* Commits the batch in chunks, yielding between them with no transaction
|
|
79
|
+
* open. A chunk that throws leaves the earlier chunks committed, so the pass
|
|
80
|
+
* saves the cursor for that prefix and parks it below the operation it could
|
|
81
|
+
* not commit before rethrowing.
|
|
41
82
|
*/
|
|
42
83
|
async indexOperations(items) {
|
|
43
84
|
if (items.length === 0) return;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
85
|
+
const { commitChunkSize, yieldDeadlineMs } = this.indexing;
|
|
86
|
+
let lastYield = performance.now();
|
|
87
|
+
let committed = 0;
|
|
88
|
+
for (let start = 0; start < items.length; start += commitChunkSize) {
|
|
89
|
+
if (start > 0 && performance.now() - lastYield > yieldDeadlineMs) {
|
|
90
|
+
await yieldToMain();
|
|
91
|
+
lastYield = performance.now();
|
|
92
|
+
}
|
|
93
|
+
const chunk = items.slice(start, start + commitChunkSize);
|
|
94
|
+
try {
|
|
95
|
+
await this.commitOperations(chunk);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
this.park(items, committed);
|
|
98
|
+
await this.recordCommittedPrefix(items.slice(0, committed));
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
101
|
+
committed += chunk.length;
|
|
102
|
+
}
|
|
103
|
+
this.liftParkIfCommitted(items);
|
|
104
|
+
await this.persistCursor(items);
|
|
48
105
|
this.updateConsistencyTracker(items);
|
|
49
106
|
}
|
|
50
107
|
/**
|
|
@@ -96,9 +153,10 @@ var BaseReadModel = class {
|
|
|
96
153
|
async saveState(trx, items) {
|
|
97
154
|
let maxOrdinal = 0;
|
|
98
155
|
for (const item of items) maxOrdinal = Math.max(maxOrdinal, item.context.ordinal);
|
|
99
|
-
this.lastOrdinal
|
|
156
|
+
const next = Math.max(this.lastOrdinal, maxOrdinal);
|
|
157
|
+
this.lastOrdinal = next;
|
|
100
158
|
await trx.updateTable("ViewState").set({
|
|
101
|
-
lastOrdinal:
|
|
159
|
+
lastOrdinal: next,
|
|
102
160
|
lastOperationTimestamp: /* @__PURE__ */ new Date()
|
|
103
161
|
}).where("readModelId", "=", this.config.readModelId).execute();
|
|
104
162
|
}
|
|
@@ -118,6 +176,59 @@ var BaseReadModel = class {
|
|
|
118
176
|
}
|
|
119
177
|
this.consistencyTracker.update(coordinates);
|
|
120
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Saves the cursor for the chunks that did commit before a later chunk threw.
|
|
181
|
+
* A failure here is swallowed: the cursor simply stays where the pass found
|
|
182
|
+
* it, which is equally safe, and the commit error is the one worth raising.
|
|
183
|
+
*/
|
|
184
|
+
async recordCommittedPrefix(prefix) {
|
|
185
|
+
if (prefix.length === 0) return;
|
|
186
|
+
try {
|
|
187
|
+
await this.persistCursor(prefix);
|
|
188
|
+
} catch {
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
this.updateConsistencyTracker(prefix);
|
|
192
|
+
}
|
|
193
|
+
/** Writes the cursor for the given items, never past a parked ordinal. */
|
|
194
|
+
async persistCursor(items) {
|
|
195
|
+
await this.db.transaction().execute(async (trx) => {
|
|
196
|
+
await this.saveState(trx, items);
|
|
197
|
+
await this.clampCursorToPark(trx);
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Holds the cursor written by {@link saveState}, which subclasses may
|
|
202
|
+
* override, below the lowest operation this model failed to commit.
|
|
203
|
+
*/
|
|
204
|
+
async clampCursorToPark(trx) {
|
|
205
|
+
if (this.uncommittedOrdinal === 0) return;
|
|
206
|
+
const ceiling = this.uncommittedOrdinal - 1;
|
|
207
|
+
if (this.lastOrdinal <= ceiling) return;
|
|
208
|
+
this.lastOrdinal = ceiling;
|
|
209
|
+
await trx.updateTable("ViewState").set({
|
|
210
|
+
lastOrdinal: ceiling,
|
|
211
|
+
lastOperationTimestamp: /* @__PURE__ */ new Date()
|
|
212
|
+
}).where("readModelId", "=", this.config.readModelId).execute();
|
|
213
|
+
}
|
|
214
|
+
/** Remembers the lowest ordinal the failed pass left uncommitted. */
|
|
215
|
+
park(items, committed) {
|
|
216
|
+
let lowest = 0;
|
|
217
|
+
for (let i = committed; i < items.length; i++) {
|
|
218
|
+
const ordinal = items[i].context.ordinal;
|
|
219
|
+
if (lowest === 0 || ordinal < lowest) lowest = ordinal;
|
|
220
|
+
}
|
|
221
|
+
if (lowest === 0) return;
|
|
222
|
+
if (this.uncommittedOrdinal === 0 || lowest < this.uncommittedOrdinal) this.uncommittedOrdinal = lowest;
|
|
223
|
+
}
|
|
224
|
+
/** The park lifts once a later pass commits the operation that failed. */
|
|
225
|
+
liftParkIfCommitted(items) {
|
|
226
|
+
if (this.uncommittedOrdinal === 0) return;
|
|
227
|
+
for (const item of items) if (item.context.ordinal === this.uncommittedOrdinal) {
|
|
228
|
+
this.uncommittedOrdinal = 0;
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
121
232
|
};
|
|
122
233
|
//#endregion
|
|
123
234
|
//#region src/read-models/coordinator.ts
|
|
@@ -129,6 +240,9 @@ var BaseReadModel = class {
|
|
|
129
240
|
* implicitly.
|
|
130
241
|
*/
|
|
131
242
|
var ReadModelCoordinator = class {
|
|
243
|
+
eventBus;
|
|
244
|
+
preReady;
|
|
245
|
+
postReady;
|
|
132
246
|
unsubscribe;
|
|
133
247
|
isRunning = false;
|
|
134
248
|
chains = /* @__PURE__ */ new Map();
|
|
@@ -280,15 +394,36 @@ const DOCUMENT_VIEW_READ_MODEL = "document-view";
|
|
|
280
394
|
const DOCUMENT_INDEXER_READ_MODEL = "document-indexer";
|
|
281
395
|
//#endregion
|
|
282
396
|
//#region src/read-models/document-view.ts
|
|
397
|
+
/**
|
|
398
|
+
* What a single-document read of a deleted document returns. A listing omits a
|
|
399
|
+
* deleted document under either value.
|
|
400
|
+
*/
|
|
401
|
+
let DeletedDocumentRead = /* @__PURE__ */ function(DeletedDocumentRead) {
|
|
402
|
+
/**
|
|
403
|
+
* The document reads as missing: `get` throws and `resolveIdOrSlug` does not
|
|
404
|
+
* match its id.
|
|
405
|
+
*/
|
|
406
|
+
DeletedDocumentRead["NotFound"] = "NotFound";
|
|
407
|
+
/**
|
|
408
|
+
* The document's state as of the deletion, with `state.document.isDeleted`
|
|
409
|
+
* telling the caller what it holds. Only meaningful with `documentDecisions`,
|
|
410
|
+
* which is what makes deletion positional.
|
|
411
|
+
*/
|
|
412
|
+
DeletedDocumentRead["StateAtDeletion"] = "StateAtDeletion";
|
|
413
|
+
return DeletedDocumentRead;
|
|
414
|
+
}({});
|
|
283
415
|
var KyselyDocumentView = class extends BaseReadModel {
|
|
416
|
+
operationStore;
|
|
417
|
+
deletedDocumentRead;
|
|
284
418
|
_db;
|
|
285
|
-
constructor(db, operationStore, operationIndex, writeCache, consistencyTracker,
|
|
419
|
+
constructor(db, operationStore, operationIndex, writeCache, consistencyTracker, deletedDocumentRead, indexing = defaultReadModelIndexingConfig) {
|
|
286
420
|
super(db, operationIndex, writeCache, consistencyTracker, {
|
|
287
421
|
readModelId: DOCUMENT_VIEW_READ_MODEL,
|
|
288
|
-
rebuildStateOnInit: true
|
|
422
|
+
rebuildStateOnInit: true,
|
|
423
|
+
indexing
|
|
289
424
|
});
|
|
290
425
|
this.operationStore = operationStore;
|
|
291
|
-
this.
|
|
426
|
+
this.deletedDocumentRead = deletedDocumentRead;
|
|
292
427
|
this._db = db;
|
|
293
428
|
}
|
|
294
429
|
/**
|
|
@@ -300,12 +435,17 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
300
435
|
* without either fall back to header/document/auth, because their sibling
|
|
301
436
|
* echoes may be stale. All other action types index only header and their
|
|
302
437
|
* own scope.
|
|
438
|
+
*
|
|
439
|
+
* The header row is the one row every scope's chain writes, so it accepts a
|
|
440
|
+
* write only from an operation whose global ordinal is at least the one the
|
|
441
|
+
* row already carries. Without that, a chunked pass that started earlier
|
|
442
|
+
* reverts a concurrent rename with the stale echo its later chunks carry.
|
|
303
443
|
*/
|
|
304
444
|
async commitOperations(items) {
|
|
305
445
|
await this._db.transaction().execute(async (trx) => {
|
|
306
446
|
for (const item of items) {
|
|
307
447
|
const { operation, context } = item;
|
|
308
|
-
const { documentId, scope, branch, documentType, resultingState } = context;
|
|
448
|
+
const { documentId, scope, branch, documentType, resultingState, ordinal } = context;
|
|
309
449
|
const { index, hash } = operation;
|
|
310
450
|
if (!resultingState) throw new Error(`Missing resultingState in context for operation ${operation.id || "unknown"}. IDocumentView requires resultingState from upstream - it does not rebuild documents.`);
|
|
311
451
|
let fullState;
|
|
@@ -324,6 +464,7 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
324
464
|
deletedAt: now,
|
|
325
465
|
lastOperationIndex: index,
|
|
326
466
|
lastOperationHash: hash,
|
|
467
|
+
lastOperationOrdinal: ordinal,
|
|
327
468
|
lastUpdatedAt: now
|
|
328
469
|
}).where("documentId", "=", documentId).where("branch", "=", branch).execute();
|
|
329
470
|
const deletedDocumentScope = fullState?.document;
|
|
@@ -345,7 +486,15 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
345
486
|
else scopesToIndex.push([scope, {}]);
|
|
346
487
|
}
|
|
347
488
|
for (const [scopeName, scopeState] of scopesToIndex) {
|
|
348
|
-
const
|
|
489
|
+
const needsExistingContent = scopeName === "header" && preserveHeaderMeta;
|
|
490
|
+
const existingSnapshot = await trx.selectFrom("DocumentSnapshot").select([
|
|
491
|
+
"slug",
|
|
492
|
+
"name",
|
|
493
|
+
"isDeleted",
|
|
494
|
+
"snapshotVersion",
|
|
495
|
+
"lastOperationOrdinal"
|
|
496
|
+
]).$if(needsExistingContent, (qb) => qb.select("content")).where("documentId", "=", documentId).where("scope", "=", scopeName).where("branch", "=", branch).executeTakeFirst();
|
|
497
|
+
if (scopeName === "header" && existingSnapshot !== void 0 && existingSnapshot.lastOperationOrdinal > ordinal) continue;
|
|
349
498
|
const newState = typeof scopeState === "object" && scopeState !== null ? scopeState : {};
|
|
350
499
|
let slug = existingSnapshot?.slug ?? null;
|
|
351
500
|
let name = existingSnapshot?.name ?? null;
|
|
@@ -354,7 +503,7 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
354
503
|
const headerName = newState.name;
|
|
355
504
|
if (typeof headerSlug === "string") slug = headerSlug;
|
|
356
505
|
if (typeof headerName === "string") name = headerName;
|
|
357
|
-
if (
|
|
506
|
+
if (needsExistingContent && existingSnapshot) {
|
|
358
507
|
const existingHeader = existingSnapshot.content;
|
|
359
508
|
if (existingHeader && "meta" in existingHeader) newState.meta = existingHeader.meta;
|
|
360
509
|
}
|
|
@@ -372,12 +521,13 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
372
521
|
if (existingSnapshot) await trx.updateTable("DocumentSnapshot").set({
|
|
373
522
|
lastOperationIndex: index,
|
|
374
523
|
lastOperationHash: hash,
|
|
524
|
+
lastOperationOrdinal: ordinal,
|
|
375
525
|
lastUpdatedAt: /* @__PURE__ */ new Date(),
|
|
376
526
|
snapshotVersion: existingSnapshot.snapshotVersion + 1,
|
|
377
527
|
content: newState,
|
|
378
528
|
slug,
|
|
379
529
|
name
|
|
380
|
-
}).where("documentId", "=", documentId).where("scope", "=", scopeName).where("branch", "=", branch).execute();
|
|
530
|
+
}).where("documentId", "=", documentId).where("scope", "=", scopeName).where("branch", "=", branch).$if(scopeName === "header", (qb) => qb.where("lastOperationOrdinal", "<=", ordinal)).execute();
|
|
381
531
|
else {
|
|
382
532
|
const snapshot = {
|
|
383
533
|
id: v4(),
|
|
@@ -390,6 +540,7 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
390
540
|
documentType,
|
|
391
541
|
lastOperationIndex: index,
|
|
392
542
|
lastOperationHash: hash,
|
|
543
|
+
lastOperationOrdinal: ordinal,
|
|
393
544
|
identifiers: null,
|
|
394
545
|
metadata: null,
|
|
395
546
|
deletedAt: null
|
|
@@ -404,7 +555,7 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
404
555
|
if (consistencyToken) await this.waitForConsistency(consistencyToken, void 0, signal);
|
|
405
556
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
406
557
|
if (documentIds.length === 0) return [];
|
|
407
|
-
const existingIds = existence ===
|
|
558
|
+
const existingIds = existence === "IncludingDeleted" ? await this.idsWithStreams(documentIds, signal) : await this.liveIds(documentIds);
|
|
408
559
|
return documentIds.map((id) => existingIds.has(id));
|
|
409
560
|
}
|
|
410
561
|
async get(documentId, view, consistencyToken, signal) {
|
|
@@ -412,14 +563,14 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
412
563
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
413
564
|
const branch = view?.branch || "main";
|
|
414
565
|
let scopesToQuery;
|
|
415
|
-
if (view?.scopes && view.scopes.length > 0) scopesToQuery = [
|
|
566
|
+
if (view?.scopes && view.scopes.length > 0) scopesToQuery = [.../* @__PURE__ */ new Set([
|
|
416
567
|
"header",
|
|
417
568
|
"document",
|
|
418
569
|
...view.scopes
|
|
419
570
|
])];
|
|
420
571
|
else scopesToQuery = [];
|
|
421
572
|
let query = this._db.selectFrom("DocumentSnapshot").selectAll().where("documentId", "=", documentId).where("branch", "=", branch);
|
|
422
|
-
if (
|
|
573
|
+
if (this.deletedDocumentRead === "NotFound") query = query.where("isDeleted", "=", false);
|
|
423
574
|
if (scopesToQuery.length > 0) query = query.where("scope", "in", scopesToQuery);
|
|
424
575
|
const snapshots = await query.execute();
|
|
425
576
|
if (snapshots.length === 0) throw new Error(`Document not found: ${documentId}`);
|
|
@@ -449,7 +600,7 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
449
600
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
450
601
|
const branch = view?.branch || "main";
|
|
451
602
|
let scopesToQuery;
|
|
452
|
-
if (view?.scopes && view.scopes.length > 0) scopesToQuery = [
|
|
603
|
+
if (view?.scopes && view.scopes.length > 0) scopesToQuery = [.../* @__PURE__ */ new Set([
|
|
453
604
|
"header",
|
|
454
605
|
"document",
|
|
455
606
|
...view.scopes
|
|
@@ -508,17 +659,11 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
508
659
|
const branch = view?.branch || "main";
|
|
509
660
|
const startIndex = paging?.cursor ? parseInt(paging.cursor) : 0;
|
|
510
661
|
const limit = paging?.limit || 100;
|
|
511
|
-
const
|
|
512
|
-
const processedDocumentIds = /* @__PURE__ */ new Set();
|
|
513
|
-
const allDocumentIds = [];
|
|
514
|
-
const snapshots = await this._db.selectFrom("DocumentSnapshot").selectAll().where("documentType", "=", type).where("branch", "=", branch).where("isDeleted", "=", false).orderBy("lastUpdatedAt", "desc").execute();
|
|
662
|
+
const rows = await this._db.selectFrom("DocumentSnapshot").select("documentId").select((eb) => eb.fn.max("lastUpdatedAt").as("lastUpdatedAt")).where("documentType", "=", type).where("branch", "=", branch).where("isDeleted", "=", false).groupBy("documentId").orderBy("lastUpdatedAt", "desc").orderBy("documentId", "asc").offset(startIndex).limit(limit + 1).execute();
|
|
515
663
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
allDocumentIds.push(snapshot.documentId);
|
|
520
|
-
}
|
|
521
|
-
const docsToFetch = allDocumentIds.slice(startIndex, startIndex + limit);
|
|
664
|
+
const hasMore = rows.length > limit;
|
|
665
|
+
const docsToFetch = rows.slice(0, limit).map((row) => row.documentId);
|
|
666
|
+
const documents = [];
|
|
522
667
|
for (const documentId of docsToFetch) {
|
|
523
668
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
524
669
|
try {
|
|
@@ -528,7 +673,6 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
528
673
|
continue;
|
|
529
674
|
}
|
|
530
675
|
}
|
|
531
|
-
const hasMore = allDocumentIds.length > startIndex + limit;
|
|
532
676
|
const nextCursor = hasMore ? String(startIndex + limit) : void 0;
|
|
533
677
|
return {
|
|
534
678
|
results: documents,
|
|
@@ -537,7 +681,6 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
537
681
|
limit: 100
|
|
538
682
|
},
|
|
539
683
|
nextCursor,
|
|
540
|
-
totalCount: allDocumentIds.length,
|
|
541
684
|
next: hasMore ? () => this.findByType(type, view, {
|
|
542
685
|
cursor: nextCursor,
|
|
543
686
|
limit
|
|
@@ -564,7 +707,7 @@ var KyselyDocumentView = class extends BaseReadModel {
|
|
|
564
707
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
565
708
|
const branch = view?.branch || "main";
|
|
566
709
|
let idCheckQuery = this._db.selectFrom("DocumentSnapshot").select("documentId").where("documentId", "=", identifier).where("branch", "=", branch);
|
|
567
|
-
if (
|
|
710
|
+
if (this.deletedDocumentRead === "NotFound") idCheckQuery = idCheckQuery.where("isDeleted", "=", false);
|
|
568
711
|
const idCheckPromise = idCheckQuery.executeTakeFirst();
|
|
569
712
|
const slugCheckPromise = this._db.selectFrom("SlugMapping").select("documentId").where("slug", "=", identifier).where("branch", "=", branch).executeTakeFirst();
|
|
570
713
|
const [idMatch, slugMatch] = await Promise.all([idCheckPromise, slugCheckPromise]);
|
|
@@ -713,18 +856,25 @@ async function collectAllPages(firstPage, signal) {
|
|
|
713
856
|
}
|
|
714
857
|
//#endregion
|
|
715
858
|
//#region src/storage/kysely/document-indexer.ts
|
|
859
|
+
function isRelationshipAction(actionType) {
|
|
860
|
+
return actionType === "ADD_RELATIONSHIP" || actionType === "REMOVE_RELATIONSHIP" || actionType === "UPDATE_RELATIONSHIP";
|
|
861
|
+
}
|
|
716
862
|
var KyselyDocumentIndexer = class extends BaseReadModel {
|
|
717
863
|
_db;
|
|
718
|
-
constructor(db, operationIndex, writeCache, consistencyTracker) {
|
|
864
|
+
constructor(db, operationIndex, writeCache, consistencyTracker, indexing = defaultReadModelIndexingConfig) {
|
|
719
865
|
super(db, operationIndex, writeCache, consistencyTracker, {
|
|
720
866
|
readModelId: DOCUMENT_INDEXER_READ_MODEL,
|
|
721
|
-
rebuildStateOnInit: false
|
|
867
|
+
rebuildStateOnInit: false,
|
|
868
|
+
indexing
|
|
722
869
|
});
|
|
723
870
|
this._db = db;
|
|
724
871
|
}
|
|
872
|
+
/** Opens no transaction for a batch carrying no relationship operation. */
|
|
725
873
|
async commitOperations(items) {
|
|
874
|
+
const relationshipOps = items.filter((item) => isRelationshipAction(item.operation.action.type));
|
|
875
|
+
if (relationshipOps.length === 0) return;
|
|
726
876
|
await this._db.transaction().execute(async (trx) => {
|
|
727
|
-
for (const item of
|
|
877
|
+
for (const item of relationshipOps) {
|
|
728
878
|
const { operation } = item;
|
|
729
879
|
const actionType = operation.action.type;
|
|
730
880
|
if (actionType === "ADD_RELATIONSHIP") await this.handleAddRelationship(trx, operation);
|
|
@@ -896,7 +1046,7 @@ var KyselyDocumentIndexer = class extends BaseReadModel {
|
|
|
896
1046
|
async findAncestors(documentId, types, consistencyToken, signal) {
|
|
897
1047
|
if (consistencyToken) await this.waitForConsistency(consistencyToken, void 0, signal);
|
|
898
1048
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
899
|
-
const nodes = new Set([documentId]);
|
|
1049
|
+
const nodes = /* @__PURE__ */ new Set([documentId]);
|
|
900
1050
|
const edges = [];
|
|
901
1051
|
const queue = [documentId];
|
|
902
1052
|
const visited = /* @__PURE__ */ new Set();
|
|
@@ -953,6 +1103,6 @@ var KyselyDocumentIndexer = class extends BaseReadModel {
|
|
|
953
1103
|
}
|
|
954
1104
|
};
|
|
955
1105
|
//#endregion
|
|
956
|
-
export {
|
|
1106
|
+
export { KyselyDocumentView as a, ReadModelCoordinator as c, DEFAULT_READ_MODEL_YIELD_DEADLINE_MS as d, defaultReadModelIndexingConfig as f, DeletedDocumentRead as i, BaseReadModel as l, ConsistencyTracker as n, DOCUMENT_INDEXER_READ_MODEL as o, unchunkedReadModelIndexingConfig as p, makeConsistencyKey as r, DOCUMENT_VIEW_READ_MODEL as s, KyselyDocumentIndexer as t, DEFAULT_COMMIT_CHUNK_SIZE as u };
|
|
957
1107
|
|
|
958
|
-
//# sourceMappingURL=document-indexer-
|
|
1108
|
+
//# sourceMappingURL=document-indexer-BVTGbEB0.js.map
|