@powerhousedao/powerhouse-vetra-packages 6.2.3-dev.5 → 6.2.3-dev.50
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/browser/assets/{entry-5_Eh4a2Z.js → entry-E7pSm84X.js} +111 -7
- package/dist/browser/assets/{projection-entry-5PVbP10h.js → projection-entry-UE4mfnXc.js} +99 -21
- package/dist/browser/document-models/index.js +2 -1
- package/dist/browser/{documents-J_l59mSV.js → documents-CRzouuNR.js} +631 -752
- package/dist/browser/documents-CRzouuNR.js.map +1 -0
- package/dist/browser/editor-C7KBR_ar.js +4676 -0
- package/dist/browser/editor-C7KBR_ar.js.map +1 -0
- package/dist/browser/{editor-Cbl_EDjI.js → editor-CiR6XQBO.js} +4 -5
- package/dist/browser/{editor-Cbl_EDjI.js.map → editor-CiR6XQBO.js.map} +1 -1
- package/dist/browser/editors/document-model-editor/module.js +1 -1
- package/dist/browser/editors/document-model-editor/module.js.map +1 -1
- package/dist/browser/editors/generic-drive-explorer/index.js +81 -65
- package/dist/browser/editors/generic-drive-explorer/index.js.map +1 -1
- package/dist/browser/editors/generic-drive-explorer/module.js +1 -1
- package/dist/browser/editors/generic-drive-explorer/module.js.map +1 -1
- package/dist/browser/folder-view-DSgXN79D.js +4409 -0
- package/dist/browser/folder-view-DSgXN79D.js.map +1 -0
- package/dist/browser/{graphql-editor-BcL3-Zha.js → graphql-editor-Cgi5UOrF.js} +98 -88
- package/dist/browser/graphql-editor-Cgi5UOrF.js.map +1 -0
- package/dist/{node/hooks-D0DcS3MV.mjs → browser/hooks-eQxBX7g4.js} +824 -444
- package/dist/browser/{hooks-KKcNp2X0.js.map → hooks-eQxBX7g4.js.map} +1 -1
- package/dist/browser/index.js +137 -34
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/{json-editor-DHXQRIN5.js → json-editor-DfRD-pfk.js} +8 -9
- package/dist/browser/{json-editor-DHXQRIN5.js.map → json-editor-DfRD-pfk.js.map} +1 -1
- package/dist/browser/{parser-CkF6Qt8V.js → parser-DtbeHA3H.js} +7 -6
- package/dist/browser/{parser-CkF6Qt8V.js.map → parser-DtbeHA3H.js.map} +1 -1
- package/dist/browser/rolldown-runtime-DC62tzP2.js +33 -0
- package/dist/browser/src-CrUksCLW-B2dkRdgq.js +5254 -0
- package/dist/browser/src-CrUksCLW-B2dkRdgq.js.map +1 -0
- package/dist/browser/state-schemas-B5Bk_l1s.js +696 -0
- package/dist/browser/state-schemas-B5Bk_l1s.js.map +1 -0
- package/dist/browser/tslib.es6-Cno80yFJ.js +32 -0
- package/dist/browser/tslib.es6-Cno80yFJ.js.map +1 -0
- package/dist/node/document-models/index.mjs +2 -1
- package/dist/node/documents-D70S9PZL.mjs +17 -0
- package/dist/node/documents-D70S9PZL.mjs.map +1 -0
- package/dist/node/editor-96sMeumV.mjs +4597 -0
- package/dist/node/editor-96sMeumV.mjs.map +1 -0
- package/dist/node/{editor-DG1q4Y55.mjs → editor-wqvKwcO5.mjs} +4 -5
- package/dist/node/{editor-DG1q4Y55.mjs.map → editor-wqvKwcO5.mjs.map} +1 -1
- package/dist/node/editors/document-model-editor/module.mjs +1 -1
- package/dist/node/editors/document-model-editor/module.mjs.map +1 -1
- package/dist/node/editors/generic-drive-explorer/index.mjs +26 -21
- package/dist/node/editors/generic-drive-explorer/index.mjs.map +1 -1
- package/dist/node/editors/generic-drive-explorer/module.mjs +1 -1
- package/dist/node/editors/generic-drive-explorer/module.mjs.map +1 -1
- package/dist/node/folder-view-ktfv2Cvw.mjs +4409 -0
- package/dist/node/folder-view-ktfv2Cvw.mjs.map +1 -0
- package/dist/node/{graphql-BfAoPeWM.mjs → graphql-Dp4j7rmx.mjs} +50 -49
- package/dist/node/{graphql-BfAoPeWM.mjs.map → graphql-Dp4j7rmx.mjs.map} +1 -1
- package/dist/node/{graphql-editor-B-XIb6az.mjs → graphql-editor-CBJXEY_C.mjs} +77 -63
- package/dist/node/graphql-editor-CBJXEY_C.mjs.map +1 -0
- package/dist/{browser/hooks-KKcNp2X0.js → node/hooks-C2b46djt.mjs} +824 -444
- package/dist/node/{hooks-D0DcS3MV.mjs.map → hooks-C2b46djt.mjs.map} +1 -1
- package/dist/node/index.mjs +158 -35
- package/dist/node/index.mjs.map +1 -1
- package/dist/node/{json-editor-DB0vi6tV.mjs → json-editor-DaqHARBD.mjs} +8 -9
- package/dist/node/{json-editor-DB0vi6tV.mjs.map → json-editor-DaqHARBD.mjs.map} +1 -1
- package/dist/node/{schema-context-DL8jhi_d.mjs → schema-context-CojjnSE6.mjs} +6 -5
- package/dist/node/schema-context-CojjnSE6.mjs.map +1 -0
- package/dist/node/src-CrUksCLW-TvF37aMo.mjs +5935 -0
- package/dist/node/src-CrUksCLW-TvF37aMo.mjs.map +1 -0
- package/dist/node/state-schemas-BHuo0GPl.mjs +698 -0
- package/dist/node/state-schemas-BHuo0GPl.mjs.map +1 -0
- package/dist/node/{main-B1tRsYOp.mjs → tslib.es6-VORZjfk3.mjs} +40 -202
- package/dist/node/tslib.es6-VORZjfk3.mjs.map +1 -0
- package/package.json +12 -11
- package/dist/browser/button-CuO8Gh3v.js +0 -696
- package/dist/browser/button-CuO8Gh3v.js.map +0 -1
- package/dist/browser/connect-BtHSAuSc.js +0 -14328
- package/dist/browser/connect-BtHSAuSc.js.map +0 -1
- package/dist/browser/dist-B4FWbuEM.js +0 -4148
- package/dist/browser/dist-B4FWbuEM.js.map +0 -1
- package/dist/browser/dist-BAJ5nRDl.js +0 -2711
- package/dist/browser/dist-BAJ5nRDl.js.map +0 -1
- package/dist/browser/dist-D69hfRZN.js +0 -4641
- package/dist/browser/dist-D69hfRZN.js.map +0 -1
- package/dist/browser/document-drive-BEXJ-rHp.js +0 -8277
- package/dist/browser/document-drive-BEXJ-rHp.js.map +0 -1
- package/dist/browser/documents-J_l59mSV.js.map +0 -1
- package/dist/browser/editor-mNThkZOv.js +0 -1809
- package/dist/browser/editor-mNThkZOv.js.map +0 -1
- package/dist/browser/folder-view-D8AkN1Oj.js +0 -232
- package/dist/browser/folder-view-D8AkN1Oj.js.map +0 -1
- package/dist/browser/graphql-editor-BcL3-Zha.js.map +0 -1
- package/dist/browser/lib-ewnRj2dJ.js +0 -209
- package/dist/browser/lib-ewnRj2dJ.js.map +0 -1
- package/dist/browser/printer-CEYr4JOg.js +0 -604
- package/dist/browser/printer-CEYr4JOg.js.map +0 -1
- package/dist/browser/schema-context-ZyeclQwy.js +0 -69
- package/dist/browser/schema-context-ZyeclQwy.js.map +0 -1
- package/dist/browser/state-schemas-C4F8lReN.js +0 -298
- package/dist/browser/state-schemas-C4F8lReN.js.map +0 -1
- package/dist/node/button-Da7CxMn7.mjs +0 -678
- package/dist/node/button-Da7CxMn7.mjs.map +0 -1
- package/dist/node/connect-B6IQsY6u.mjs +0 -15022
- package/dist/node/connect-B6IQsY6u.mjs.map +0 -1
- package/dist/node/dist-CzYOpeXN.mjs +0 -2711
- package/dist/node/dist-CzYOpeXN.mjs.map +0 -1
- package/dist/node/dist-DT7jI9ol.mjs +0 -4148
- package/dist/node/dist-DT7jI9ol.mjs.map +0 -1
- package/dist/node/dist-hd-KLWy7.mjs +0 -4649
- package/dist/node/dist-hd-KLWy7.mjs.map +0 -1
- package/dist/node/document-drive-CkV9NvD7.mjs +0 -8294
- package/dist/node/document-drive-CkV9NvD7.mjs.map +0 -1
- package/dist/node/documents-DCf53bzO.mjs +0 -747
- package/dist/node/documents-DCf53bzO.mjs.map +0 -1
- package/dist/node/editor-C93fdI28.mjs +0 -1809
- package/dist/node/editor-C93fdI28.mjs.map +0 -1
- package/dist/node/folder-view-BGabHV7H.mjs +0 -232
- package/dist/node/folder-view-BGabHV7H.mjs.map +0 -1
- package/dist/node/graphql-editor-B-XIb6az.mjs.map +0 -1
- package/dist/node/main-B1tRsYOp.mjs.map +0 -1
- package/dist/node/schema-context-DL8jhi_d.mjs.map +0 -1
- package/dist/node/state-schemas-BGsgtEG1.mjs +0 -299
- package/dist/node/state-schemas-BGsgtEG1.mjs.map +0 -1
|
@@ -1,8 +1,103 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as
|
|
3
|
-
import { n as
|
|
1
|
+
import { D as CollectionMembershipCache, E as DocumentMetaCache, St as ReactorEventTypes, a as REACTOR_SCHEMA, d as KyselyKeyframeStore, f as EventBus, l as instrumentPgPool, m as KyselyOperationIndex, n as errorToInfo, p as KyselyWriteCache, t as createForwardingLogger, u as KyselyOperationStore } from "./forwarding-logger-ByfBFgMS.js";
|
|
2
|
+
import { a as KyselyExecutionScope, n as SimpleJobExecutor, t as DEFAULT_DRIVE_CONTAINER_TYPES } from "./drive-container-types-Ci1pdv4X.js";
|
|
3
|
+
import { n as loadDocumentModelSpec, r as DocumentModelRegistry, t as defaultLoadFactory } from "./load-spec-ZLjuyhxz.js";
|
|
4
4
|
import { ConsoleLogger } from "document-model";
|
|
5
5
|
import { isMainThread, parentPort } from "node:worker_threads";
|
|
6
|
+
//#region src/executor/worker/build-worker-executor.ts
|
|
7
|
+
async function loadModelManifest(entries, loadFactory, registry, logger) {
|
|
8
|
+
for (const entry of entries) {
|
|
9
|
+
let module;
|
|
10
|
+
try {
|
|
11
|
+
module = await loadFactory(entry.spec);
|
|
12
|
+
} catch (error) {
|
|
13
|
+
logger.error("worker failed to load document model: @entry @error", entry, error);
|
|
14
|
+
throw error;
|
|
15
|
+
}
|
|
16
|
+
const [result] = registry.registerModules(module);
|
|
17
|
+
if (result.status === "error") {
|
|
18
|
+
logger.error("worker failed to register document model: @entry @error", entry, result.error);
|
|
19
|
+
throw result.error;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Assembles the in-worker storage stack plus a {@link SimpleJobExecutor}
|
|
25
|
+
* bound to a pre-built Kysely instance. The parent owns the wire protocol
|
|
26
|
+
* and routing; the worker owns everything below `SimpleJobExecutor`.
|
|
27
|
+
*
|
|
28
|
+
* The local event bus exists only to satisfy the executor's contract: its
|
|
29
|
+
* JOB_WRITE_READY emissions are captured here and shipped to the parent
|
|
30
|
+
* via {@link WorkerExecutorStack.takeLastWriteReady}.
|
|
31
|
+
*/
|
|
32
|
+
async function buildWorkerExecutor(options) {
|
|
33
|
+
const { init, database: baseDatabase, logger } = options;
|
|
34
|
+
const driveContainerTypes = options.driveContainerTypes ?? DEFAULT_DRIVE_CONTAINER_TYPES;
|
|
35
|
+
const loadFactory = options.loadFactory ?? defaultLoadFactory;
|
|
36
|
+
const registry = new DocumentModelRegistry();
|
|
37
|
+
await loadModelManifest(init.models, loadFactory, registry, logger);
|
|
38
|
+
let signer;
|
|
39
|
+
if (init.signer) try {
|
|
40
|
+
signer = await loadFactory(init.signer);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
logger.error("worker failed to load signer: @spec @error", init.signer.module, error);
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
let trustPolicy;
|
|
46
|
+
if (init.trustPolicy) try {
|
|
47
|
+
trustPolicy = await loadFactory(init.trustPolicy);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
logger.error("worker failed to load trust policy: @spec @error", init.trustPolicy.module, error);
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
const database = baseDatabase.withSchema(REACTOR_SCHEMA);
|
|
53
|
+
const operationStore = new KyselyOperationStore(database);
|
|
54
|
+
const keyframeStore = new KyselyKeyframeStore(database);
|
|
55
|
+
const writeCache = new KyselyWriteCache(keyframeStore, operationStore, registry, {
|
|
56
|
+
maxDocuments: 100,
|
|
57
|
+
ringBufferSize: 10,
|
|
58
|
+
keyframeInterval: 10
|
|
59
|
+
});
|
|
60
|
+
await writeCache.startup();
|
|
61
|
+
const operationIndex = new KyselyOperationIndex(database);
|
|
62
|
+
const documentMetaCache = new DocumentMetaCache(operationStore, { maxDocuments: 1e3 });
|
|
63
|
+
await documentMetaCache.startup();
|
|
64
|
+
const collectionMembershipCache = new CollectionMembershipCache(operationIndex);
|
|
65
|
+
const executionScope = new KyselyExecutionScope(database, operationStore, operationIndex, keyframeStore, writeCache, documentMetaCache, collectionMembershipCache);
|
|
66
|
+
const eventBus = new EventBus();
|
|
67
|
+
let lastWriteReady = null;
|
|
68
|
+
eventBus.subscribe(ReactorEventTypes.JOB_WRITE_READY, (_t, event) => {
|
|
69
|
+
lastWriteReady = {
|
|
70
|
+
operations: event.operations,
|
|
71
|
+
jobMeta: event.jobMeta
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
let signatureRefusals = [];
|
|
75
|
+
eventBus.subscribe(ReactorEventTypes.SIGNATURE_REFUSED, (_t, event) => {
|
|
76
|
+
signatureRefusals.push(event);
|
|
77
|
+
});
|
|
78
|
+
const executorConfig = options.executorConfig ?? {};
|
|
79
|
+
return {
|
|
80
|
+
executor: new SimpleJobExecutor(logger, registry, operationStore, eventBus, writeCache, operationIndex, documentMetaCache, collectionMembershipCache, driveContainerTypes, executorConfig, executionScope, signer, trustPolicy),
|
|
81
|
+
registry,
|
|
82
|
+
takeLastWriteReady() {
|
|
83
|
+
const captured = lastWriteReady;
|
|
84
|
+
lastWriteReady = null;
|
|
85
|
+
return captured;
|
|
86
|
+
},
|
|
87
|
+
takeSignatureRefusals() {
|
|
88
|
+
const captured = signatureRefusals;
|
|
89
|
+
signatureRefusals = [];
|
|
90
|
+
return captured;
|
|
91
|
+
},
|
|
92
|
+
evictPurged(documentIds) {
|
|
93
|
+
for (const documentId of documentIds) {
|
|
94
|
+
writeCache.invalidate(documentId);
|
|
95
|
+
documentMetaCache.invalidate(documentId);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
6
101
|
//#region src/executor/worker/run-worker.ts
|
|
7
102
|
const POOL_SAMPLE_INTERVAL_MS = 1e3;
|
|
8
103
|
async function defaultCreateDatabase(config, workerId) {
|
|
@@ -38,7 +133,7 @@ async function defaultCreateDatabase(config, workerId) {
|
|
|
38
133
|
/**
|
|
39
134
|
* Drives the worker's message loop. Owns lifecycle of the database handle
|
|
40
135
|
* and executor stack. The default factories build a real Postgres pool and
|
|
41
|
-
* use dynamic `import()` for model/
|
|
136
|
+
* use dynamic `import()` for model/signer specs; tests inject overrides
|
|
42
137
|
* for an in-process PGlite path.
|
|
43
138
|
*/
|
|
44
139
|
function runWorker(parentPort, overrides = {}) {
|
|
@@ -51,6 +146,7 @@ function runWorker(parentPort, overrides = {}) {
|
|
|
51
146
|
let pendingPoolSamples = [];
|
|
52
147
|
let detachPoolListener = null;
|
|
53
148
|
const activeLoadFactory = overrides.loadFactory ?? defaultLoadFactory;
|
|
149
|
+
const loadModelSpec = overrides.loadFactory ? async (spec) => await activeLoadFactory(spec) : loadDocumentModelSpec;
|
|
54
150
|
function post(msg) {
|
|
55
151
|
parentPort.postMessage(msg);
|
|
56
152
|
}
|
|
@@ -146,11 +242,16 @@ function runWorker(parentPort, overrides = {}) {
|
|
|
146
242
|
return;
|
|
147
243
|
}
|
|
148
244
|
try {
|
|
245
|
+
const result = await executorStack.executor.executeJob(job);
|
|
246
|
+
const writeReady = executorStack.takeLastWriteReady();
|
|
247
|
+
const signatureRefusals = executorStack.takeSignatureRefusals();
|
|
149
248
|
post({
|
|
150
249
|
type: "result",
|
|
151
250
|
correlationId,
|
|
152
|
-
result
|
|
153
|
-
writeReady:
|
|
251
|
+
result,
|
|
252
|
+
writeReady: writeReady ?? void 0,
|
|
253
|
+
signatureRefusals: signatureRefusals.length > 0 ? signatureRefusals : void 0,
|
|
254
|
+
error: !result.success && result.error ? errorToInfo(result.error) : void 0
|
|
154
255
|
});
|
|
155
256
|
} catch (error) {
|
|
156
257
|
post({
|
|
@@ -178,7 +279,7 @@ function runWorker(parentPort, overrides = {}) {
|
|
|
178
279
|
}
|
|
179
280
|
let module;
|
|
180
281
|
try {
|
|
181
|
-
module = await
|
|
282
|
+
module = await loadModelSpec(msg.model.spec);
|
|
182
283
|
} catch (error) {
|
|
183
284
|
post({
|
|
184
285
|
type: "model-load-failed",
|
|
@@ -277,6 +378,9 @@ function runWorker(parentPort, overrides = {}) {
|
|
|
277
378
|
});
|
|
278
379
|
});
|
|
279
380
|
break;
|
|
381
|
+
case "evict-purged":
|
|
382
|
+
executorStack?.evictPurged(msg.documentIds);
|
|
383
|
+
break;
|
|
280
384
|
default: {
|
|
281
385
|
const raw = msg;
|
|
282
386
|
if (raw["type"] === "__test_throw") {
|
|
@@ -1,11 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { n as defaultLoadFactory } from "./build-worker-executor-DnU3ZU4H.js";
|
|
1
|
+
import { D as CollectionMembershipCache, E as DocumentMetaCache, S as createKyselyWatermarkProbe, St as ReactorEventTypes, a as REACTOR_SCHEMA, d as KyselyKeyframeStore, f as EventBus, l as instrumentPgPool, m as KyselyOperationIndex, n as errorToInfo, p as KyselyWriteCache, t as createForwardingLogger, u as KyselyOperationStore, v as findPurged, x as SettledWatermark } from "./forwarding-logger-ByfBFgMS.js";
|
|
2
|
+
import { r as DocumentModelRegistry, t as defaultLoadFactory } from "./load-spec-ZLjuyhxz.js";
|
|
3
|
+
import { a as KyselyDocumentView, c as ReadModelCoordinator, f as BaseReadModel, n as ConsistencyTracker, t as KyselyDocumentIndexer, y as CatchUpScheduler } from "./document-indexer-DwAMDVRI.js";
|
|
4
|
+
import { isPurgeMarker } from "@powerhousedao/shared/document-model";
|
|
6
5
|
import { ConsoleLogger } from "document-model";
|
|
7
6
|
import { isMainThread, parentPort } from "node:worker_threads";
|
|
8
7
|
//#region src/projection/projection-worker/build-projection-stack.ts
|
|
8
|
+
/**
|
|
9
|
+
* In-worker projection stack builder.
|
|
10
|
+
*
|
|
11
|
+
* Mirrors {@link buildWorkerExecutor} but for the projection-side
|
|
12
|
+
* read models. The worker owns one full copy of the storage stack — read
|
|
13
|
+
* cache, operation index, document-meta cache — bound to its own
|
|
14
|
+
* pg.Pool/Kysely, plus an in-process `ReadModelCoordinator` that
|
|
15
|
+
* subscribes to a local `EventBus`.
|
|
16
|
+
*
|
|
17
|
+
* The host relays JOB_WRITE_READY into the local bus by calling
|
|
18
|
+
* `relayWriteReady`, and forwards the local bus's JOB_READ_READY plus
|
|
19
|
+
* READMODEL_* events back to the host bus via the IPC bridge.
|
|
20
|
+
*/
|
|
9
21
|
async function loadModelManifest(entries, loadFactory, registry, logger) {
|
|
10
22
|
for (const entry of entries) {
|
|
11
23
|
let module;
|
|
@@ -22,14 +34,11 @@ async function loadModelManifest(entries, loadFactory, registry, logger) {
|
|
|
22
34
|
}
|
|
23
35
|
}
|
|
24
36
|
}
|
|
25
|
-
function instantiateReadModel(kind, database, operationStore, operationIndex, writeCache) {
|
|
37
|
+
function instantiateReadModel(kind, database, operationStore, operationIndex, writeCache, indexing) {
|
|
26
38
|
switch (kind) {
|
|
27
|
-
case "document-view": return new KyselyDocumentView(database, operationStore, operationIndex, writeCache, new ConsistencyTracker(),
|
|
28
|
-
case "document-indexer": return new KyselyDocumentIndexer(database, operationIndex, writeCache, new ConsistencyTracker());
|
|
29
|
-
default: {
|
|
30
|
-
const exhaustive = kind;
|
|
31
|
-
throw new Error(`unknown built-in read model kind: ${String(exhaustive)}`);
|
|
32
|
-
}
|
|
39
|
+
case "document-view": return new KyselyDocumentView(database, operationStore, operationIndex, writeCache, new ConsistencyTracker(), "NotFound", indexing);
|
|
40
|
+
case "document-indexer": return new KyselyDocumentIndexer(database, operationIndex, writeCache, new ConsistencyTracker(), indexing);
|
|
41
|
+
default: throw new Error(`unknown built-in read model kind: ${String(kind)}`);
|
|
33
42
|
}
|
|
34
43
|
}
|
|
35
44
|
async function initReadModels(models, logger) {
|
|
@@ -44,6 +53,32 @@ async function initReadModels(models, logger) {
|
|
|
44
53
|
}
|
|
45
54
|
}
|
|
46
55
|
}
|
|
56
|
+
/** Posts what each sweep applied, so the host's tracker for the model advances. */
|
|
57
|
+
function relaySweeps(model, events, onSwept) {
|
|
58
|
+
return {
|
|
59
|
+
get consumerId() {
|
|
60
|
+
return model.consumerId;
|
|
61
|
+
},
|
|
62
|
+
get appliedThrough() {
|
|
63
|
+
return model.appliedThrough;
|
|
64
|
+
},
|
|
65
|
+
get trackedAbove() {
|
|
66
|
+
return model.trackedAbove;
|
|
67
|
+
},
|
|
68
|
+
async sweep(settledThrough, present, signal) {
|
|
69
|
+
const coordinates = [];
|
|
70
|
+
const unsubscribe = model.onSwept((swept) => coordinates.push(...swept));
|
|
71
|
+
try {
|
|
72
|
+
const result = await model.sweep(settledThrough, present, signal);
|
|
73
|
+
if (coordinates.length > 0 || result.to > result.from || result.replayed > 0 || result.blockedAt !== void 0) events.onReadModelSwept(model.name, coordinates, result);
|
|
74
|
+
await onSwept(coordinates);
|
|
75
|
+
return result;
|
|
76
|
+
} finally {
|
|
77
|
+
unsubscribe();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
47
82
|
async function buildProjectionStack(options) {
|
|
48
83
|
const { init, database: baseDatabase, logger, events } = options;
|
|
49
84
|
const loadFactory = options.loadFactory ?? defaultLoadFactory;
|
|
@@ -51,18 +86,44 @@ async function buildProjectionStack(options) {
|
|
|
51
86
|
await loadModelManifest(init.models, loadFactory, registry, logger);
|
|
52
87
|
const database = baseDatabase.withSchema(REACTOR_SCHEMA);
|
|
53
88
|
const operationStore = new KyselyOperationStore(database);
|
|
54
|
-
const
|
|
89
|
+
const keyframeStore = new KyselyKeyframeStore(database);
|
|
90
|
+
const writeCache = new KyselyWriteCache(keyframeStore, operationStore, registry, {
|
|
55
91
|
maxDocuments: 100,
|
|
56
92
|
ringBufferSize: 10,
|
|
57
93
|
keyframeInterval: 10
|
|
58
94
|
});
|
|
59
95
|
await writeCache.startup();
|
|
60
96
|
const operationIndex = new KyselyOperationIndex(database);
|
|
61
|
-
|
|
97
|
+
const documentMetaCache = new DocumentMetaCache(operationStore, { maxDocuments: 1e3 });
|
|
98
|
+
await documentMetaCache.startup();
|
|
62
99
|
new CollectionMembershipCache(operationIndex);
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
100
|
+
const evict = (documentIds) => {
|
|
101
|
+
for (const documentId of documentIds) {
|
|
102
|
+
writeCache.invalidate(documentId);
|
|
103
|
+
documentMetaCache.invalidate(documentId);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
const evictSweptMarkers = async (coordinates) => {
|
|
107
|
+
const candidates = coordinates.filter((c) => c.scope === "document" && c.operationIndex === 0).map((c) => c.documentId);
|
|
108
|
+
if (candidates.length === 0) return;
|
|
109
|
+
let purged;
|
|
110
|
+
try {
|
|
111
|
+
purged = await findPurged(database, candidates);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
logger.error("projection worker purge lookup failed: @error", error);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
evict(purged);
|
|
117
|
+
};
|
|
118
|
+
const preReady = init.preReadyKinds.map((kind) => instantiateReadModel(kind, database, operationStore, operationIndex, writeCache, init.indexing));
|
|
119
|
+
const postReady = init.postReadyKinds.map((kind) => instantiateReadModel(kind, database, operationStore, operationIndex, writeCache, init.indexing));
|
|
120
|
+
const watermark = new SettledWatermark(createKyselyWatermarkProbe(database), logger);
|
|
121
|
+
const catchUp = new CatchUpScheduler(watermark, operationIndex, init.catchUp, logger);
|
|
122
|
+
const models = [...preReady, ...postReady];
|
|
123
|
+
for (const model of models) if (model instanceof BaseReadModel) model.attachCatchUp(watermark, init.catchUp.maxTrackedAboveCursor);
|
|
124
|
+
await initReadModels(models, logger);
|
|
125
|
+
for (const model of models) if (model instanceof BaseReadModel) catchUp.addConsumer(relaySweeps(model, events, evictSweptMarkers), "projection");
|
|
126
|
+
catchUp.start();
|
|
66
127
|
const eventBus = new EventBus();
|
|
67
128
|
const subscriptions = [];
|
|
68
129
|
subscriptions.push(eventBus.subscribe(ReactorEventTypes.JOB_READ_READY, (_t, event) => {
|
|
@@ -80,19 +141,24 @@ async function buildProjectionStack(options) {
|
|
|
80
141
|
registry,
|
|
81
142
|
coordinator,
|
|
82
143
|
eventBus,
|
|
144
|
+
writeCache,
|
|
83
145
|
async relayWriteReady(event) {
|
|
146
|
+
evict(event.operations.filter((item) => isPurgeMarker(item)).map((item) => item.context.documentId));
|
|
84
147
|
await eventBus.emit(ReactorEventTypes.JOB_WRITE_READY, event);
|
|
85
148
|
},
|
|
86
149
|
getChainDepth() {
|
|
87
150
|
return coordinator.getChainDepth();
|
|
88
151
|
},
|
|
152
|
+
catchUpStatus() {
|
|
153
|
+
return catchUp.status();
|
|
154
|
+
},
|
|
89
155
|
async drain() {
|
|
90
156
|
await coordinator.drain();
|
|
91
157
|
},
|
|
92
|
-
shutdown() {
|
|
158
|
+
async shutdown() {
|
|
159
|
+
await catchUp.stop();
|
|
93
160
|
coordinator.stop();
|
|
94
161
|
for (const unsub of subscriptions) unsub();
|
|
95
|
-
return Promise.resolve();
|
|
96
162
|
}
|
|
97
163
|
};
|
|
98
164
|
}
|
|
@@ -213,6 +279,11 @@ function runProjectionWorker(parentPort, overrides = {}) {
|
|
|
213
279
|
if (intervalMs <= 0) return;
|
|
214
280
|
depthTimer = setInterval(() => {
|
|
215
281
|
if (!stack) return;
|
|
282
|
+
post({
|
|
283
|
+
type: "catchup-status",
|
|
284
|
+
shardId,
|
|
285
|
+
status: stack.catchUpStatus()
|
|
286
|
+
});
|
|
216
287
|
const depth = stack.getChainDepth();
|
|
217
288
|
if (depth === lastReportedDepth) return;
|
|
218
289
|
lastReportedDepth = depth;
|
|
@@ -261,6 +332,15 @@ function runProjectionWorker(parentPort, overrides = {}) {
|
|
|
261
332
|
success: event.success
|
|
262
333
|
});
|
|
263
334
|
},
|
|
335
|
+
onReadModelSwept: (readModelName, coordinates, result) => {
|
|
336
|
+
post({
|
|
337
|
+
type: "readmodel-swept",
|
|
338
|
+
shardId,
|
|
339
|
+
readModelName,
|
|
340
|
+
coordinates,
|
|
341
|
+
result
|
|
342
|
+
});
|
|
343
|
+
},
|
|
264
344
|
onBatchCompleted: (event) => {
|
|
265
345
|
post({
|
|
266
346
|
type: "readmodel-batch-completed",
|
|
@@ -380,8 +460,6 @@ function runProjectionWorker(parentPort, overrides = {}) {
|
|
|
380
460
|
});
|
|
381
461
|
process.exit(0);
|
|
382
462
|
});
|
|
383
|
-
break;
|
|
384
|
-
default: break;
|
|
385
463
|
}
|
|
386
464
|
}
|
|
387
465
|
parentPort.on("message", handleParentMessage);
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { documentModelDocumentModelModule } from "document-model";
|
|
2
|
+
import { driveDocumentModelModule } from "@powerhousedao/shared/document-drive";
|
|
2
3
|
export { documentModelDocumentModelModule, driveDocumentModelModule };
|