@powerhousedao/reactor 6.2.3-dev.49 → 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.
Files changed (28) hide show
  1. package/dist/{document-indexer-Dc_Sv6yi.js → document-indexer-DwAMDVRI.js} +2 -2
  2. package/dist/{document-indexer-Dc_Sv6yi.js.map → document-indexer-DwAMDVRI.js.map} +1 -1
  3. package/dist/{drive-container-types-D380mcB3.js → drive-container-types-Ci1pdv4X.js} +9 -9
  4. package/dist/{drive-container-types-D380mcB3.js.map → drive-container-types-Ci1pdv4X.js.map} +1 -1
  5. package/dist/entry.js +3 -2
  6. package/dist/entry.js.map +1 -1
  7. package/dist/{load-spec-D9lnje-H.js → forwarding-logger-ByfBFgMS.js} +9 -248
  8. package/dist/forwarding-logger-ByfBFgMS.js.map +1 -0
  9. package/dist/{index-Dq2f7oAC.d.ts → index-CNhT69De.d.ts} +34 -5
  10. package/dist/index-CNhT69De.d.ts.map +1 -0
  11. package/dist/index.d.ts +126 -26
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +1065 -157
  14. package/dist/index.js.map +1 -1
  15. package/dist/load-spec-ZLjuyhxz.js +246 -0
  16. package/dist/load-spec-ZLjuyhxz.js.map +1 -0
  17. package/dist/projection-entry.js +3 -2
  18. package/dist/projection-entry.js.map +1 -1
  19. package/dist/{projection-shard-manager-MRJ9BjVM.js → projection-shard-manager-CQ5FwQmv.js} +2 -2
  20. package/dist/{projection-shard-manager-MRJ9BjVM.js.map → projection-shard-manager-CQ5FwQmv.js.map} +1 -1
  21. package/dist/rpc.d.ts +2 -2
  22. package/dist/rpc.js +3 -2
  23. package/dist/rpc.js.map +1 -1
  24. package/dist/{worker-handle-B48V1hDm.js → worker-handle-CN2-oRv-.js} +2 -2
  25. package/dist/{worker-handle-B48V1hDm.js.map → worker-handle-CN2-oRv-.js.map} +1 -1
  26. package/package.json +13 -13
  27. package/dist/index-Dq2f7oAC.d.ts.map +0 -1
  28. package/dist/load-spec-D9lnje-H.js.map +0 -1
@@ -0,0 +1,246 @@
1
+ import { DowngradeNotSupportedError } from "@powerhousedao/shared/document-model/errors";
2
+ //#region src/registry/errors.ts
3
+ /**
4
+ * Error thrown when a document model module is not found in the registry.
5
+ */
6
+ var ModuleNotFoundError = class extends Error {
7
+ documentType;
8
+ requestedVersion;
9
+ constructor(documentType, version) {
10
+ const versionSuffix = version !== void 0 ? ` version ${version}` : "";
11
+ super(`Document model module not found for type: ${documentType}${versionSuffix}`);
12
+ this.name = "ModuleNotFoundError";
13
+ this.documentType = documentType;
14
+ this.requestedVersion = version;
15
+ }
16
+ static isError(error) {
17
+ return Error.isError(error) && error.name === "ModuleNotFoundError";
18
+ }
19
+ };
20
+ /** The host has the model only as a live module, which workers cannot import. */
21
+ var ModelNotWorkerImportableError = class extends Error {
22
+ documentType;
23
+ constructor(documentType, version) {
24
+ const versionSuffix = version !== void 0 ? ` version ${version}` : "";
25
+ super(`Document model ${documentType}${versionSuffix} is registered on the host only as a live module, so executor workers cannot load it. Register it from a { filePath } or { packageName } source.`);
26
+ this.name = "ModelNotWorkerImportableError";
27
+ this.documentType = documentType;
28
+ }
29
+ static isError(error) {
30
+ return Error.isError(error) && error.name === "ModelNotWorkerImportableError";
31
+ }
32
+ };
33
+ /**
34
+ * Error thrown when attempting to register a module that already exists.
35
+ */
36
+ var DuplicateModuleError = class extends Error {
37
+ constructor(documentType, version) {
38
+ const versionSuffix = version !== void 0 ? ` (version ${version})` : "";
39
+ super(`Document model module already registered for type: ${documentType}${versionSuffix}`);
40
+ this.name = "DuplicateModuleError";
41
+ }
42
+ static isError(error) {
43
+ return Error.isError(error) && error.name === "DuplicateModuleError";
44
+ }
45
+ };
46
+ /**
47
+ * Error thrown when a module is invalid or malformed.
48
+ */
49
+ var InvalidModuleError = class extends Error {
50
+ constructor(message) {
51
+ super(`Invalid document model module: ${message}`);
52
+ this.name = "InvalidModuleError";
53
+ }
54
+ };
55
+ /**
56
+ * Error thrown when attempting to register an upgrade manifest that already exists.
57
+ */
58
+ var DuplicateManifestError = class extends Error {
59
+ constructor(documentType) {
60
+ super(`Upgrade manifest already registered for type: ${documentType}`);
61
+ this.name = "DuplicateManifestError";
62
+ }
63
+ static isError(error) {
64
+ return Error.isError(error) && error.name === "DuplicateManifestError";
65
+ }
66
+ };
67
+ /**
68
+ * Error thrown when an upgrade manifest is not found.
69
+ */
70
+ var ManifestNotFoundError = class extends Error {
71
+ constructor(documentType) {
72
+ super(`Upgrade manifest not found for type: ${documentType}`);
73
+ this.name = "ManifestNotFoundError";
74
+ }
75
+ };
76
+ /**
77
+ * Error thrown when a required upgrade transition is missing from the manifest.
78
+ */
79
+ var MissingUpgradeTransitionError = class extends Error {
80
+ constructor(documentType, fromVersion, toVersion) {
81
+ super(`Missing upgrade transition for ${documentType}: v${fromVersion} to v${toVersion}`);
82
+ this.name = "MissingUpgradeTransitionError";
83
+ }
84
+ };
85
+ /**
86
+ * Error thrown when getUpgradeReducer is called with a non-single-step version increment.
87
+ */
88
+ var InvalidUpgradeStepError = class extends Error {
89
+ constructor(documentType, fromVersion, toVersion) {
90
+ super(`Invalid upgrade step for ${documentType}: must be single version increment, got v${fromVersion} to v${toVersion}`);
91
+ this.name = "InvalidUpgradeStepError";
92
+ }
93
+ };
94
+ //#endregion
95
+ //#region src/registry/implementation.ts
96
+ /**
97
+ * In-memory implementation of the IDocumentModelRegistry interface.
98
+ * Manages document model modules with version-aware storage and upgrade manifest support.
99
+ */
100
+ var DocumentModelRegistry = class {
101
+ modules = [];
102
+ manifests = [];
103
+ registerModules(...modules) {
104
+ return modules.map((module) => {
105
+ try {
106
+ const documentType = module.documentModel.global.id;
107
+ const version = module.version ?? 1;
108
+ for (let i = 0; i < this.modules.length; i++) {
109
+ const existing = this.modules[i];
110
+ const existingType = existing.documentModel.global.id;
111
+ const existingVersion = existing.version ?? 1;
112
+ if (existingType === documentType && existingVersion === version) throw new DuplicateModuleError(documentType, version);
113
+ }
114
+ this.modules.push(module);
115
+ return {
116
+ status: "success",
117
+ item: module
118
+ };
119
+ } catch (error) {
120
+ return {
121
+ status: "error",
122
+ item: module,
123
+ error: error instanceof Error ? error : new Error(String(error))
124
+ };
125
+ }
126
+ });
127
+ }
128
+ unregisterModules(...documentTypes) {
129
+ let allFound = true;
130
+ for (const documentType of documentTypes) {
131
+ if (!this.modules.some((m) => m.documentModel.global.id === documentType)) allFound = false;
132
+ this.modules = this.modules.filter((m) => m.documentModel.global.id !== documentType);
133
+ }
134
+ return allFound;
135
+ }
136
+ getModule(documentType, version) {
137
+ let latestModule;
138
+ let latestVersion = -1;
139
+ for (let i = 0; i < this.modules.length; i++) {
140
+ const module = this.modules[i];
141
+ const moduleType = module.documentModel.global.id;
142
+ const moduleVersion = module.version ?? 1;
143
+ if (moduleType === documentType) {
144
+ if (version !== void 0 && moduleVersion === version) return module;
145
+ if (moduleVersion > latestVersion) {
146
+ latestModule = module;
147
+ latestVersion = moduleVersion;
148
+ }
149
+ }
150
+ }
151
+ if (version === void 0 && latestModule !== void 0) return latestModule;
152
+ throw new ModuleNotFoundError(documentType, version);
153
+ }
154
+ getAllModules() {
155
+ return [...this.modules];
156
+ }
157
+ clear() {
158
+ this.modules = [];
159
+ this.manifests = [];
160
+ }
161
+ getSupportedVersions(documentType) {
162
+ const versions = [];
163
+ for (const module of this.modules) if (module.documentModel.global.id === documentType) versions.push(module.version ?? 1);
164
+ if (versions.length === 0) throw new ModuleNotFoundError(documentType);
165
+ return versions.sort((a, b) => a - b);
166
+ }
167
+ getLatestVersion(documentType) {
168
+ let latest = -1;
169
+ let found = false;
170
+ for (const module of this.modules) if (module.documentModel.global.id === documentType) {
171
+ found = true;
172
+ const version = module.version ?? 1;
173
+ if (version > latest) latest = version;
174
+ }
175
+ if (!found) throw new ModuleNotFoundError(documentType);
176
+ return latest;
177
+ }
178
+ registerUpgradeManifests(...manifestsToRegister) {
179
+ return manifestsToRegister.map((manifestToRegister) => {
180
+ try {
181
+ if (!manifestToRegister.documentType) throw new Error("Upgrade manifest is missing a documentType");
182
+ for (const registeredManifest of this.manifests) if (registeredManifest.documentType === manifestToRegister.documentType) throw new DuplicateManifestError(manifestToRegister.documentType);
183
+ this.manifests.push(manifestToRegister);
184
+ return {
185
+ status: "success",
186
+ item: manifestToRegister
187
+ };
188
+ } catch (error) {
189
+ return {
190
+ status: "error",
191
+ item: manifestToRegister,
192
+ error: error instanceof Error ? error : new Error(String(error))
193
+ };
194
+ }
195
+ });
196
+ }
197
+ unregisterUpgradeManifests(...documentTypes) {
198
+ let allFound = true;
199
+ for (const documentType of documentTypes) {
200
+ if (!this.manifests.some((m) => m.documentType === documentType)) allFound = false;
201
+ this.manifests = this.manifests.filter((m) => m.documentType !== documentType);
202
+ }
203
+ return allFound;
204
+ }
205
+ getUpgradeManifest(documentType) {
206
+ for (let i = 0; i < this.manifests.length; i++) if (this.manifests[i].documentType === documentType) return this.manifests[i];
207
+ throw new ManifestNotFoundError(documentType);
208
+ }
209
+ computeUpgradePath(documentType, fromVersion, toVersion) {
210
+ if (fromVersion === toVersion) return [];
211
+ if (toVersion < fromVersion) throw new DowngradeNotSupportedError(documentType, fromVersion, toVersion);
212
+ const manifest = this.getUpgradeManifest(documentType);
213
+ const path = [];
214
+ for (let v = fromVersion + 1; v <= toVersion; v++) {
215
+ const key = `v${v}`;
216
+ if (!(key in manifest.upgrades)) throw new MissingUpgradeTransitionError(documentType, v - 1, v);
217
+ const transition = manifest.upgrades[key];
218
+ path.push(transition);
219
+ }
220
+ return path;
221
+ }
222
+ getUpgradeReducer(documentType, fromVersion, toVersion) {
223
+ if (toVersion !== fromVersion + 1) throw new InvalidUpgradeStepError(documentType, fromVersion, toVersion);
224
+ const manifest = this.getUpgradeManifest(documentType);
225
+ const key = `v${toVersion}`;
226
+ if (!(key in manifest.upgrades)) throw new MissingUpgradeTransitionError(documentType, fromVersion, toVersion);
227
+ return manifest.upgrades[key].upgradeReducer;
228
+ }
229
+ };
230
+ //#endregion
231
+ //#region src/executor/worker/load-spec.ts
232
+ /** Imports `spec.module` and calls the export with `spec.initArgs`, or returns it if not a function. */
233
+ async function defaultLoadFactory(spec) {
234
+ const ref = spec.module;
235
+ const exported = (await ("filePath" in ref ? import(new URL(`file://${ref.filePath}`).href) : import(ref.packageName)))[ref.exportName];
236
+ if (typeof exported === "function") return exported(spec.initArgs);
237
+ return exported;
238
+ }
239
+ /** Loads the document model module a manifest entry's spec names. */
240
+ async function loadDocumentModelSpec(spec) {
241
+ return await defaultLoadFactory(spec);
242
+ }
243
+ //#endregion
244
+ export { DuplicateModuleError as a, ModuleNotFoundError as c, DuplicateManifestError as i, loadDocumentModelSpec as n, InvalidModuleError as o, DocumentModelRegistry as r, ModelNotWorkerImportableError as s, defaultLoadFactory as t };
245
+
246
+ //# sourceMappingURL=load-spec-ZLjuyhxz.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-spec-ZLjuyhxz.js","names":[],"sources":["../src/registry/errors.ts","../src/registry/implementation.ts","../src/executor/worker/load-spec.ts"],"sourcesContent":["/**\n * Error thrown when a document model module is not found in the registry.\n */\nexport class ModuleNotFoundError extends Error {\n readonly documentType: string;\n readonly requestedVersion: number | undefined;\n\n constructor(documentType: string, version?: number) {\n const versionSuffix = version !== undefined ? ` version ${version}` : \"\";\n super(\n `Document model module not found for type: ${documentType}${versionSuffix}`,\n );\n this.name = \"ModuleNotFoundError\";\n this.documentType = documentType;\n this.requestedVersion = version;\n }\n\n static isError(error: unknown): error is ModuleNotFoundError {\n return Error.isError(error) && error.name === \"ModuleNotFoundError\";\n }\n}\n\n/** The host has the model only as a live module, which workers cannot import. */\nexport class ModelNotWorkerImportableError extends Error {\n readonly documentType: string;\n\n constructor(documentType: string, version?: number) {\n const versionSuffix = version !== undefined ? ` version ${version}` : \"\";\n super(\n `Document model ${documentType}${versionSuffix} is registered on the host only as a live module, so executor workers cannot load it. Register it from a { filePath } or { packageName } source.`,\n );\n this.name = \"ModelNotWorkerImportableError\";\n this.documentType = documentType;\n }\n\n static isError(error: unknown): error is ModelNotWorkerImportableError {\n return (\n Error.isError(error) && error.name === \"ModelNotWorkerImportableError\"\n );\n }\n}\n\n/**\n * Error thrown when attempting to register a module that already exists.\n */\nexport class DuplicateModuleError extends Error {\n constructor(documentType: string, version?: number) {\n const versionSuffix = version !== undefined ? ` (version ${version})` : \"\";\n super(\n `Document model module already registered for type: ${documentType}${versionSuffix}`,\n );\n this.name = \"DuplicateModuleError\";\n }\n\n static isError(error: unknown): error is DuplicateModuleError {\n return Error.isError(error) && error.name === \"DuplicateModuleError\";\n }\n}\n\n/**\n * Error thrown when a module is invalid or malformed.\n */\nexport class InvalidModuleError extends Error {\n constructor(message: string) {\n super(`Invalid document model module: ${message}`);\n this.name = \"InvalidModuleError\";\n }\n}\n\n/**\n * Error thrown when attempting to register an upgrade manifest that already exists.\n */\nexport class DuplicateManifestError extends Error {\n constructor(documentType: string) {\n super(`Upgrade manifest already registered for type: ${documentType}`);\n this.name = \"DuplicateManifestError\";\n }\n\n static isError(error: unknown): error is DuplicateManifestError {\n return Error.isError(error) && error.name === \"DuplicateManifestError\";\n }\n}\n\n/**\n * Error thrown when an upgrade manifest is not found.\n */\nexport class ManifestNotFoundError extends Error {\n constructor(documentType: string) {\n super(`Upgrade manifest not found for type: ${documentType}`);\n this.name = \"ManifestNotFoundError\";\n }\n}\n\nexport { DowngradeNotSupportedError } from \"@powerhousedao/shared/document-model/errors\";\n\n/**\n * Error thrown when a required upgrade transition is missing from the manifest.\n */\nexport class MissingUpgradeTransitionError extends Error {\n constructor(documentType: string, fromVersion: number, toVersion: number) {\n super(\n `Missing upgrade transition for ${documentType}: v${fromVersion} to v${toVersion}`,\n );\n this.name = \"MissingUpgradeTransitionError\";\n }\n}\n\n/**\n * Error thrown when getUpgradeReducer is called with a non-single-step version increment.\n */\nexport class InvalidUpgradeStepError extends Error {\n constructor(documentType: string, fromVersion: number, toVersion: number) {\n super(\n `Invalid upgrade step for ${documentType}: must be single version increment, got v${fromVersion} to v${toVersion}`,\n );\n this.name = \"InvalidUpgradeStepError\";\n }\n}\n","import type {\n DocumentModelModule,\n UpgradeManifest,\n UpgradeReducer,\n UpgradeTransition,\n} from \"@powerhousedao/shared/document-model\";\nimport {\n DowngradeNotSupportedError,\n DuplicateManifestError,\n DuplicateModuleError,\n InvalidUpgradeStepError,\n ManifestNotFoundError,\n MissingUpgradeTransitionError,\n ModuleNotFoundError,\n} from \"./errors.js\";\nimport type {\n IDocumentModelRegistry,\n RegistrationResult,\n} from \"./interfaces.js\";\n\n/**\n * In-memory implementation of the IDocumentModelRegistry interface.\n * Manages document model modules with version-aware storage and upgrade manifest support.\n */\nexport class DocumentModelRegistry implements IDocumentModelRegistry {\n private modules: DocumentModelModule<any>[] = [];\n private manifests: UpgradeManifest<readonly number[]>[] = [];\n\n registerModules(\n ...modules: DocumentModelModule<any>[]\n ): RegistrationResult<DocumentModelModule<any>>[] {\n return modules.map((module) => {\n try {\n const documentType = module.documentModel.global.id;\n const version = module.version ?? 1;\n\n for (let i = 0; i < this.modules.length; i++) {\n const existing = this.modules[i];\n const existingType = existing.documentModel.global.id;\n const existingVersion = existing.version ?? 1;\n\n if (existingType === documentType && existingVersion === version) {\n throw new DuplicateModuleError(documentType, version);\n }\n }\n\n this.modules.push(module);\n return { status: \"success\" as const, item: module };\n } catch (error) {\n return {\n status: \"error\" as const,\n item: module,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n });\n }\n\n unregisterModules(...documentTypes: string[]): boolean {\n let allFound = true;\n\n for (const documentType of documentTypes) {\n const hasModule = this.modules.some(\n (m) => m.documentModel.global.id === documentType,\n );\n\n if (!hasModule) {\n allFound = false;\n }\n\n this.modules = this.modules.filter(\n (m) => m.documentModel.global.id !== documentType,\n );\n }\n\n return allFound;\n }\n\n getModule(documentType: string, version?: number): DocumentModelModule<any> {\n let latestModule: DocumentModelModule<any> | undefined;\n let latestVersion = -1;\n\n for (let i = 0; i < this.modules.length; i++) {\n const module = this.modules[i];\n const moduleType = module.documentModel.global.id;\n const moduleVersion = module.version ?? 1;\n\n if (moduleType === documentType) {\n if (version !== undefined && moduleVersion === version) {\n return module;\n }\n\n if (moduleVersion > latestVersion) {\n latestModule = module;\n latestVersion = moduleVersion;\n }\n }\n }\n\n if (version === undefined && latestModule !== undefined) {\n return latestModule;\n }\n\n throw new ModuleNotFoundError(documentType, version);\n }\n\n getAllModules(): DocumentModelModule<any>[] {\n return [...this.modules];\n }\n\n clear(): void {\n this.modules = [];\n this.manifests = [];\n }\n\n getSupportedVersions(documentType: string): number[] {\n const versions: number[] = [];\n\n for (const module of this.modules) {\n if (module.documentModel.global.id === documentType) {\n versions.push(module.version ?? 1);\n }\n }\n\n if (versions.length === 0) {\n throw new ModuleNotFoundError(documentType);\n }\n\n return versions.sort((a, b) => a - b);\n }\n\n getLatestVersion(documentType: string): number {\n let latest = -1;\n let found = false;\n\n for (const module of this.modules) {\n if (module.documentModel.global.id === documentType) {\n found = true;\n const version = module.version ?? 1;\n if (version > latest) {\n latest = version;\n }\n }\n }\n\n if (!found) {\n throw new ModuleNotFoundError(documentType);\n }\n\n return latest;\n }\n\n registerUpgradeManifests(\n ...manifestsToRegister: UpgradeManifest<readonly number[]>[]\n ): RegistrationResult<UpgradeManifest<readonly number[]>>[] {\n return manifestsToRegister.map((manifestToRegister) => {\n try {\n if (!manifestToRegister.documentType) {\n throw new Error(\"Upgrade manifest is missing a documentType\");\n }\n\n for (const registeredManifest of this.manifests) {\n if (\n registeredManifest.documentType === manifestToRegister.documentType\n ) {\n throw new DuplicateManifestError(manifestToRegister.documentType);\n }\n }\n\n this.manifests.push(manifestToRegister);\n return { status: \"success\" as const, item: manifestToRegister };\n } catch (error) {\n return {\n status: \"error\" as const,\n item: manifestToRegister,\n error: error instanceof Error ? error : new Error(String(error)),\n };\n }\n });\n }\n\n unregisterUpgradeManifests(...documentTypes: string[]): boolean {\n let allFound = true;\n\n for (const documentType of documentTypes) {\n const hasManifest = this.manifests.some(\n (m) => m.documentType === documentType,\n );\n\n if (!hasManifest) {\n allFound = false;\n }\n\n this.manifests = this.manifests.filter(\n (m) => m.documentType !== documentType,\n );\n }\n\n return allFound;\n }\n\n getUpgradeManifest(documentType: string): UpgradeManifest<readonly number[]> {\n for (let i = 0; i < this.manifests.length; i++) {\n if (this.manifests[i].documentType === documentType) {\n return this.manifests[i];\n }\n }\n throw new ManifestNotFoundError(documentType);\n }\n\n computeUpgradePath(\n documentType: string,\n fromVersion: number,\n toVersion: number,\n ): UpgradeTransition[] {\n if (fromVersion === toVersion) {\n return [];\n }\n\n if (toVersion < fromVersion) {\n throw new DowngradeNotSupportedError(\n documentType,\n fromVersion,\n toVersion,\n );\n }\n\n const manifest = this.getUpgradeManifest(documentType);\n\n const path: UpgradeTransition[] = [];\n for (let v = fromVersion + 1; v <= toVersion; v++) {\n const key = `v${v}`;\n\n if (!(key in manifest.upgrades)) {\n throw new MissingUpgradeTransitionError(documentType, v - 1, v);\n }\n\n const transition =\n manifest.upgrades[key as keyof typeof manifest.upgrades];\n path.push(transition);\n }\n\n return path;\n }\n\n getUpgradeReducer(\n documentType: string,\n fromVersion: number,\n toVersion: number,\n ): UpgradeReducer<any, any> {\n if (toVersion !== fromVersion + 1) {\n throw new InvalidUpgradeStepError(documentType, fromVersion, toVersion);\n }\n\n const manifest = this.getUpgradeManifest(documentType);\n\n const key = `v${toVersion}`;\n\n if (!(key in manifest.upgrades)) {\n throw new MissingUpgradeTransitionError(\n documentType,\n fromVersion,\n toVersion,\n );\n }\n\n const transition = manifest.upgrades[key as keyof typeof manifest.upgrades];\n return transition.upgradeReducer;\n }\n}\n","import type { DocumentModelModule } from \"@powerhousedao/shared/document-model\";\nimport type { DocumentModelSpec, FactorySpec } from \"./protocol.js\";\n\n/** Imports `spec.module` and calls the export with `spec.initArgs`, or returns it if not a function. */\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\n/** Loads the document model module a manifest entry's spec names. */\nexport async function loadDocumentModelSpec(\n spec: DocumentModelSpec,\n): Promise<DocumentModelModule> {\n return (await defaultLoadFactory(spec)) as DocumentModelModule;\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
- import { A as CollectionMembershipCache, At as ReactorEventTypes, T as createKyselyWatermarkProbe, _ as KyselyOperationIndex, d as instrumentPgPool, f as KyselyOperationStore, g as KyselyWriteCache, h as EventBus, i as errorToInfo, k as DocumentMetaCache, m as DocumentModelRegistry, p as KyselyKeyframeStore, r as createForwardingLogger, s as REACTOR_SCHEMA, t as defaultLoadFactory, w as SettledWatermark, x as findPurged } from "./load-spec-D9lnje-H.js";
2
- import { a as KyselyDocumentView, c as ReadModelCoordinator, f as BaseReadModel, n as ConsistencyTracker, t as KyselyDocumentIndexer, y as CatchUpScheduler } from "./document-indexer-Dc_Sv6yi.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";
3
4
  import { isPurgeMarker } from "@powerhousedao/shared/document-model";
4
5
  import { ConsoleLogger } from "document-model";
5
6
  import { isMainThread, parentPort } from "node:worker_threads";
@@ -1 +1 @@
1
- {"version":3,"file":"projection-entry.js","names":["exhaustive"],"sources":["../src/projection/projection-worker/build-projection-stack.ts","../src/projection/projection-worker/run-projection-worker.ts","../src/projection/projection-worker/projection-entry.ts"],"sourcesContent":["/**\n * In-worker projection stack builder.\n *\n * Mirrors {@link buildWorkerExecutor} but for the projection-side\n * read models. The worker owns one full copy of the storage stack — read\n * cache, operation index, document-meta cache — bound to its own\n * pg.Pool/Kysely, plus an in-process `ReadModelCoordinator` that\n * subscribes to a local `EventBus`.\n *\n * The host relays JOB_WRITE_READY into the local bus by calling\n * `relayWriteReady`, and forwards the local bus's JOB_READ_READY plus\n * READMODEL_* events back to the host bus via the IPC bridge.\n */\n\nimport {\n isPurgeMarker,\n type DocumentModelModule,\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 { CatchUpScheduler } from \"../../catch-up/scheduler.js\";\nimport {\n createKyselyWatermarkProbe,\n SettledWatermark,\n} from \"../../catch-up/settled-watermark.js\";\nimport type {\n CatchUpStatus,\n ICatchUpConsumer,\n SweepResult,\n} from \"../../catch-up/types.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 type { Database } from \"../../core/types.js\";\nimport { EventBus } from \"../../events/event-bus.js\";\nimport {\n ReactorEventTypes,\n type JobReadReadyEvent,\n type JobWriteReadyEvent,\n type ReadModelBatchCompletedEvent,\n type ReadModelIndexedEvent,\n type Unsubscribe,\n} from \"../../events/types.js\";\nimport type { BuildWorkerExecutorOptions } from \"../../executor/worker/build-worker-executor.js\";\nimport { defaultLoadFactory } from \"../../executor/worker/load-spec.js\";\nimport type {\n FactorySpec,\n ModelManifestEntry,\n} from \"../../executor/worker/protocol.js\";\nimport {\n BaseReadModel,\n type ReadModelIndexingConfig,\n} from \"../../read-models/base-read-model.js\";\nimport { ReadModelCoordinator } from \"../../read-models/coordinator.js\";\nimport {\n DeletedDocumentRead,\n KyselyDocumentView,\n} from \"../../read-models/document-view.js\";\nimport type { IReadModel } from \"../../read-models/interfaces.js\";\nimport { DocumentModelRegistry } from \"../../registry/implementation.js\";\nimport { ConsistencyTracker } from \"../../shared/consistency-tracker.js\";\nimport type { ConsistencyCoordinate } from \"../../shared/types.js\";\nimport {\n KyselyDocumentIndexer,\n type IndexerDatabase,\n} from \"../../storage/kysely/document-indexer.js\";\nimport { findPurged } from \"../../storage/kysely/document-purges.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 type {\n BuiltInReadModelKind,\n ProjectionInitMessage,\n} from \"../protocol.js\";\n\nexport type ProjectionStackEvents = {\n onReadReady: (event: JobReadReadyEvent) => void;\n onReadModelIndexed: (event: ReadModelIndexedEvent) => void;\n onBatchCompleted: (event: ReadModelBatchCompletedEvent) => void;\n onReadModelSwept: (\n readModelName: string,\n coordinates: ConsistencyCoordinate[],\n result: SweepResult,\n ) => void;\n};\n\nexport type ProjectionStack = {\n registry: DocumentModelRegistry;\n coordinator: ReadModelCoordinator;\n eventBus: EventBus;\n writeCache: KyselyWriteCache;\n relayWriteReady(event: JobWriteReadyEvent): Promise<void>;\n getChainDepth(): number;\n catchUpStatus(): CatchUpStatus;\n drain(): Promise<void>;\n shutdown(): Promise<void>;\n};\n\nexport type BuildProjectionStackOptions = {\n init: ProjectionInitMessage;\n database: Kysely<Database>;\n logger: ILogger;\n events: ProjectionStackEvents;\n loadFactory?: BuildWorkerExecutorOptions[\"loadFactory\"];\n driveContainerTypes?: ReadonlySet<string>;\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 \"projection 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 \"projection worker failed to register document model: @entry @error\",\n entry,\n result.error,\n );\n throw result.error;\n }\n }\n}\n\nfunction instantiateReadModel(\n kind: BuiltInReadModelKind,\n database: Kysely<Database>,\n operationStore: KyselyOperationStore,\n operationIndex: KyselyOperationIndex,\n writeCache: KyselyWriteCache,\n indexing: ReadModelIndexingConfig,\n): IReadModel {\n switch (kind) {\n case \"document-view\": {\n return new KyselyDocumentView(\n // @ts-expect-error - Database superset\n database,\n operationStore,\n operationIndex,\n writeCache,\n new ConsistencyTracker(),\n // Read-side only, so it cannot diverge state.\n DeletedDocumentRead.NotFound,\n indexing,\n );\n }\n case \"document-indexer\": {\n return new KyselyDocumentIndexer(\n database as unknown as Kysely<IndexerDatabase>,\n operationIndex,\n writeCache,\n new ConsistencyTracker(),\n indexing,\n );\n }\n default: {\n const exhaustive: never = kind;\n throw new Error(\n `unknown built-in read model kind: ${String(exhaustive)}`,\n );\n }\n }\n}\n\nasync function initReadModels(\n models: IReadModel[],\n logger: ILogger,\n): Promise<void> {\n for (const model of models) {\n const maybeInit = model as IReadModel & { init?: () => Promise<void> };\n if (typeof maybeInit.init !== \"function\") {\n continue;\n }\n try {\n await maybeInit.init();\n } catch (error) {\n logger.error(\n \"projection worker read model init failed: @name @error\",\n model.name,\n error,\n );\n throw error;\n }\n }\n}\n\n/** Posts what each sweep applied, so the host's tracker for the model advances. */\nfunction relaySweeps(\n model: BaseReadModel,\n events: ProjectionStackEvents,\n onSwept: (coordinates: ConsistencyCoordinate[]) => Promise<void>,\n): ICatchUpConsumer {\n return {\n get consumerId() {\n return model.consumerId;\n },\n get appliedThrough() {\n return model.appliedThrough;\n },\n get trackedAbove() {\n return model.trackedAbove;\n },\n async sweep(settledThrough, present, signal) {\n const coordinates: ConsistencyCoordinate[] = [];\n const unsubscribe = model.onSwept((swept) => coordinates.push(...swept));\n try {\n const result = await model.sweep(settledThrough, present, signal);\n if (\n coordinates.length > 0 ||\n result.to > result.from ||\n result.replayed > 0 ||\n result.blockedAt !== undefined\n ) {\n events.onReadModelSwept(model.name, coordinates, result);\n }\n await onSwept(coordinates);\n return result;\n } finally {\n unsubscribe();\n }\n },\n };\n}\n\nexport async function buildProjectionStack(\n options: BuildProjectionStackOptions,\n): Promise<ProjectionStack> {\n const { init, database: baseDatabase, logger, events } = options;\n const loadFactory = options.loadFactory ?? defaultLoadFactory;\n\n const registry = new DocumentModelRegistry();\n await loadModelManifest(init.models, loadFactory, registry, logger);\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 void collectionMembershipCache;\n\n // This thread's caches are its own; a marker it applies evicts the id here.\n const evict = (documentIds: Iterable<string>): void => {\n for (const documentId of documentIds) {\n writeCache.invalidate(documentId);\n documentMetaCache.invalidate(documentId);\n }\n };\n\n // A sweep reports coordinates only; a marker is index 0 of document scope.\n const evictSweptMarkers = async (\n coordinates: ConsistencyCoordinate[],\n ): Promise<void> => {\n const candidates = coordinates\n .filter((c) => c.scope === \"document\" && c.operationIndex === 0)\n .map((c) => c.documentId);\n if (candidates.length === 0) return;\n let purged: Set<string>;\n try {\n purged = await findPurged(database, candidates);\n } catch (error) {\n logger.error(\"projection worker purge lookup failed: @error\", error);\n return;\n }\n evict(purged);\n };\n\n const preReady = init.preReadyKinds.map((kind) =>\n instantiateReadModel(\n kind,\n database,\n operationStore,\n operationIndex,\n writeCache,\n init.indexing,\n ),\n );\n const postReady = init.postReadyKinds.map((kind) =>\n instantiateReadModel(\n kind,\n database,\n operationStore,\n operationIndex,\n writeCache,\n init.indexing,\n ),\n );\n\n const watermark = new SettledWatermark(\n createKyselyWatermarkProbe(database as unknown as Kysely<StorageDatabase>),\n logger,\n );\n const catchUp = new CatchUpScheduler(\n watermark,\n operationIndex,\n init.catchUp,\n logger,\n );\n const models = [...preReady, ...postReady];\n for (const model of models) {\n if (model instanceof BaseReadModel) {\n model.attachCatchUp(watermark, init.catchUp.maxTrackedAboveCursor);\n }\n }\n\n await initReadModels(models, logger);\n\n for (const model of models) {\n if (model instanceof BaseReadModel) {\n catchUp.addConsumer(\n relaySweeps(model, events, evictSweptMarkers),\n \"projection\",\n );\n }\n }\n catchUp.start();\n\n const eventBus = new EventBus();\n const subscriptions: Unsubscribe[] = [];\n\n subscriptions.push(\n eventBus.subscribe(\n ReactorEventTypes.JOB_READ_READY,\n (_t: number, event: JobReadReadyEvent) => {\n events.onReadReady(event);\n },\n ),\n );\n subscriptions.push(\n eventBus.subscribe(\n ReactorEventTypes.READMODEL_INDEXED,\n (_t: number, event: ReadModelIndexedEvent) => {\n events.onReadModelIndexed(event);\n },\n ),\n );\n subscriptions.push(\n eventBus.subscribe(\n ReactorEventTypes.READMODEL_BATCH_COMPLETED,\n (_t: number, event: ReadModelBatchCompletedEvent) => {\n events.onBatchCompleted(event);\n },\n ),\n );\n\n const coordinator = new ReadModelCoordinator(eventBus, preReady, postReady);\n coordinator.start();\n\n return {\n registry,\n coordinator,\n eventBus,\n writeCache,\n async relayWriteReady(event: JobWriteReadyEvent): Promise<void> {\n evict(\n event.operations\n .filter((item) => isPurgeMarker(item))\n .map((item) => item.context.documentId),\n );\n await eventBus.emit(ReactorEventTypes.JOB_WRITE_READY, event);\n },\n getChainDepth(): number {\n return coordinator.getChainDepth();\n },\n catchUpStatus(): CatchUpStatus {\n return catchUp.status();\n },\n async drain(): Promise<void> {\n await coordinator.drain();\n },\n async shutdown(): Promise<void> {\n await catchUp.stop();\n coordinator.stop();\n for (const unsub of subscriptions) {\n unsub();\n }\n },\n };\n}\n","import { ConsoleLogger } from \"document-model\";\nimport type { Kysely } from \"kysely\";\nimport type { MessagePort } from \"node:worker_threads\";\nimport type { Database } from \"../../core/types.js\";\nimport { createForwardingLogger } from \"../../executor/worker/forwarding-logger.js\";\nimport type { DbConfig } from \"../../executor/worker/protocol.js\";\nimport { errorToInfo } from \"../../executor/worker/sanitize.js\";\nimport type {\n JobReadReadyEvent,\n JobWriteReadyEvent,\n ReadModelBatchCompletedEvent,\n ReadModelIndexedEvent,\n} from \"../../events/types.js\";\nimport {\n instrumentPgPool,\n type PoolInstrumentation,\n} from \"../../storage/pool-instrumentation.js\";\nimport type {\n ProjectionInitMessage,\n ProjectionParentMessage,\n ProjectionWorkerMessage,\n} from \"../protocol.js\";\nimport {\n buildProjectionStack,\n type ProjectionStack,\n} from \"./build-projection-stack.js\";\n\nconst POOL_SAMPLE_INTERVAL_MS = 1_000;\n\n/**\n * Closeable handle around the worker's Postgres pool. Decoupled from the\n * default factory so tests can swap in PGlite via `RunProjectionWorkerOverrides`.\n *\n * When the worker owns a real pg.Pool, the handle exposes a\n * {@link PoolInstrumentation} so the run loop can forward acquire-wait\n * samples to the host. Tests that swap in PGlite leave this undefined.\n */\nexport type ProjectionWorkerDatabaseHandle = {\n kysely: Kysely<Database>;\n poolInstrumentation?: PoolInstrumentation;\n shutdown(): Promise<void>;\n};\n\nexport type RunProjectionWorkerOverrides = {\n createDatabase?: (\n config: DbConfig,\n shardId: string,\n ) => Promise<ProjectionWorkerDatabaseHandle>;\n loadFactory?: Parameters<typeof buildProjectionStack>[0][\"loadFactory\"];\n beforeBuildStack?: (db: Kysely<Database>) => Promise<void>;\n};\n\nasync function defaultCreateDatabase(\n config: DbConfig,\n shardId: string,\n): Promise<ProjectionWorkerDatabaseHandle> {\n const { Kysely, PostgresDialect } = await import(\"kysely\");\n const pgModule = await import(\"pg\");\n const Pool = pgModule.default.Pool;\n const pool = new Pool({\n host: config.host,\n port: config.port,\n database: config.database,\n user: config.user,\n password: config.password,\n ssl: config.ssl ? { rejectUnauthorized: false } : undefined,\n application_name: config.applicationName ?? shardId,\n max: config.poolSize,\n connectionTimeoutMillis: config.connectionTimeoutMillis,\n idleTimeoutMillis: config.idleTimeoutMillis,\n });\n const poolInstrumentation = instrumentPgPool(pool, shardId);\n const kysely = new Kysely<Database>({\n dialect: new PostgresDialect({ pool }),\n });\n return {\n kysely,\n poolInstrumentation,\n async shutdown(): Promise<void> {\n try {\n await kysely.destroy();\n } catch {\n // best-effort\n }\n try {\n await pool.end();\n } catch {\n // best-effort\n }\n },\n };\n}\n\n/**\n * Drives the projection worker's message loop. Owns lifecycle of the\n * database handle and the projection stack. The default factory builds a\n * real Postgres pool; tests inject overrides for an in-process PGlite path.\n */\nexport function runProjectionWorker(\n parentPort: MessagePort,\n overrides: RunProjectionWorkerOverrides = {},\n): void {\n let shardId = \"\";\n let initCompleted = false;\n let stack: ProjectionStack | null = null;\n let database: ProjectionWorkerDatabaseHandle | null = null;\n let depthTimer: NodeJS.Timeout | null = null;\n let lastReportedDepth = -1;\n let poolSampleTimer: NodeJS.Timeout | null = null;\n let pendingPoolSamples: number[] = [];\n let detachPoolListener: (() => void) | null = null;\n\n function post(msg: ProjectionWorkerMessage): void {\n parentPort.postMessage(msg);\n }\n\n function startPoolReporter(instrumentation: PoolInstrumentation): void {\n detachPoolListener = instrumentation.onAcquire((durationMs) => {\n pendingPoolSamples.push(durationMs);\n });\n poolSampleTimer = setInterval(() => {\n if (pendingPoolSamples.length === 0) {\n return;\n }\n const durations = pendingPoolSamples;\n pendingPoolSamples = [];\n const stats = instrumentation.getStats();\n post({\n type: \"pool-acquire-samples\",\n shardId,\n poolName: instrumentation.name,\n timestamp: Date.now(),\n durations,\n size: stats.size,\n idle: stats.idle,\n waiting: stats.waiting,\n });\n }, POOL_SAMPLE_INTERVAL_MS);\n poolSampleTimer.unref();\n }\n\n function stopPoolReporter(): void {\n if (detachPoolListener) {\n detachPoolListener();\n detachPoolListener = null;\n }\n if (poolSampleTimer) {\n clearInterval(poolSampleTimer);\n poolSampleTimer = null;\n }\n pendingPoolSamples = [];\n }\n\n const logger = createForwardingLogger((msg) => post({ ...msg, shardId }));\n\n process.on(\"uncaughtException\", (err: unknown) => {\n try {\n post({\n type: \"log\",\n shardId,\n level: \"error\",\n message: \"projection worker uncaughtException\",\n args: [errorToInfo(err)],\n timestamp: Date.now(),\n });\n } catch {\n // nothing left to do\n }\n throw err;\n });\n\n process.on(\"unhandledRejection\", (reason: unknown) => {\n try {\n post({\n type: \"log\",\n shardId,\n level: \"error\",\n message: \"projection worker unhandledRejection\",\n args: [errorToInfo(reason)],\n timestamp: Date.now(),\n });\n } catch {\n // nothing left to do\n }\n });\n\n function startDepthReporter(intervalMs: number): void {\n if (intervalMs <= 0) {\n return;\n }\n depthTimer = setInterval(() => {\n if (!stack) {\n return;\n }\n post({\n type: \"catchup-status\",\n shardId,\n status: stack.catchUpStatus(),\n });\n const depth = stack.getChainDepth();\n if (depth === lastReportedDepth) {\n return;\n }\n lastReportedDepth = depth;\n post({\n type: \"chain-depth\",\n shardId,\n depth,\n timestamp: Date.now(),\n });\n }, intervalMs);\n depthTimer.unref();\n }\n\n function stopDepthReporter(): void {\n if (depthTimer) {\n clearInterval(depthTimer);\n depthTimer = null;\n }\n }\n\n async function handleInit(msg: ProjectionInitMessage): Promise<void> {\n shardId = msg.shardId;\n const createDb = overrides.createDatabase ?? defaultCreateDatabase;\n database = await createDb(msg.db, msg.shardId);\n if (overrides.beforeBuildStack) {\n await overrides.beforeBuildStack(database.kysely);\n }\n stack = await buildProjectionStack({\n init: msg,\n database: database.kysely,\n logger: new ConsoleLogger([`projection-shard:${msg.shardId}`]),\n loadFactory: overrides.loadFactory,\n events: {\n onReadReady: (event: JobReadReadyEvent) => {\n post({\n type: \"read-ready\",\n shardId,\n jobId: event.jobId,\n operations: event.operations,\n });\n },\n onReadModelIndexed: (event: ReadModelIndexedEvent) => {\n post({\n type: \"readmodel-indexed\",\n shardId,\n jobId: event.jobId,\n readModelName: event.readModelName,\n stage: event.stage,\n durationMs: event.durationMs,\n operationCount: event.operationCount,\n success: event.success,\n });\n },\n onReadModelSwept: (readModelName, coordinates, result) => {\n post({\n type: \"readmodel-swept\",\n shardId,\n readModelName,\n coordinates,\n result,\n });\n },\n onBatchCompleted: (event: ReadModelBatchCompletedEvent) => {\n post({\n type: \"readmodel-batch-completed\",\n shardId,\n jobId: event.jobId,\n batchSize: event.batchSize,\n chainWaitDurationMs: event.chainWaitDurationMs,\n preReadyDurationMs: event.preReadyDurationMs,\n emitDurationMs: event.emitDurationMs,\n postReadyDurationMs: event.postReadyDurationMs,\n });\n },\n },\n });\n initCompleted = true;\n startDepthReporter(msg.chainDepthReportIntervalMs);\n if (database.poolInstrumentation) {\n startPoolReporter(database.poolInstrumentation);\n }\n logger.info(\"projection worker initialized: @shardId\", msg.shardId);\n post({ type: \"ready\", correlationId: msg.correlationId, shardId });\n }\n\n async function handleWriteReady(\n msg: Extract<ProjectionParentMessage, { type: \"write-ready\" }>,\n ): Promise<void> {\n if (!stack) {\n logger.warn(\n \"write-ready received before init on shard @shardId\",\n shardId,\n );\n return;\n }\n const event: JobWriteReadyEvent = {\n jobId: msg.jobId,\n operations: msg.operations,\n jobMeta: msg.jobMeta,\n collectionMemberships: msg.collectionMemberships,\n };\n await stack.relayWriteReady(event);\n }\n\n async function handleDrain(correlationId: string): Promise<void> {\n if (stack) {\n await stack.drain();\n }\n post({ type: \"drained\", correlationId, shardId });\n }\n\n async function shutdownStack(): Promise<void> {\n stopDepthReporter();\n stopPoolReporter();\n if (stack) {\n try {\n await stack.drain();\n } catch (error) {\n logger.warn(\n \"projection worker drain failed during shutdown: @error\",\n error,\n );\n }\n try {\n await stack.shutdown();\n } catch (error) {\n logger.warn(\"projection worker stack shutdown failed: @error\", error);\n }\n stack = null;\n }\n if (database) {\n await database.shutdown();\n database = null;\n }\n }\n\n function handleParentMessage(msg: ProjectionParentMessage): void {\n switch (msg.type) {\n case \"init\": {\n // Terminal: the worker has no stack, so it can project nothing. The\n // parent rejects startup on this message and terminates the thread;\n // exiting here would race the message and lose the cause.\n handleInit(msg).catch((err: unknown) => {\n post({\n type: \"init-failed\",\n correlationId: msg.correlationId,\n shardId,\n error: errorToInfo(err),\n });\n });\n break;\n }\n case \"write-ready\": {\n if (!initCompleted) {\n logger.warn(\n \"write-ready received before init on shard @shardId\",\n shardId,\n );\n break;\n }\n handleWriteReady(msg).catch((err: unknown) => {\n post({\n type: \"log\",\n shardId,\n level: \"error\",\n message: \"projection worker write-ready failed\",\n args: [errorToInfo(err)],\n timestamp: Date.now(),\n });\n });\n break;\n }\n case \"drain\": {\n handleDrain(msg.correlationId).catch((err: unknown) => {\n post({\n type: \"log\",\n shardId,\n level: \"error\",\n message: \"projection worker drain failed\",\n args: [errorToInfo(err)],\n timestamp: Date.now(),\n });\n });\n break;\n }\n case \"shutdown\": {\n logger.info(\"projection worker shutting down: @shardId\", shardId);\n void shutdownStack().finally(() => {\n post({\n type: \"log\",\n shardId,\n level: \"info\",\n message: \"projection worker shutdown\",\n args: [],\n timestamp: Date.now(),\n });\n process.exit(0);\n });\n break;\n }\n default: {\n const exhaustive: never = msg;\n void exhaustive;\n break;\n }\n }\n }\n\n parentPort.on(\"message\", handleParentMessage);\n\n const harness = {\n handleParentMessage,\n get initCompleted(): boolean {\n return initCompleted;\n },\n get shardId(): string {\n return shardId;\n },\n };\n (\n parentPort as unknown as { __reactorProjectionWorkerHarness?: unknown }\n ).__reactorProjectionWorkerHarness = harness;\n}\n","import { isMainThread, parentPort } from \"node:worker_threads\";\nimport { runProjectionWorker } from \"./run-projection-worker.js\";\n\nif (isMainThread || parentPort === null) {\n throw new Error(\"projection-worker entry.ts must be run as a worker thread\");\n}\n\nrunProjectionWorker(parentPort);\n"],"mappings":"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"}
1
+ {"version":3,"file":"projection-entry.js","names":["exhaustive"],"sources":["../src/projection/projection-worker/build-projection-stack.ts","../src/projection/projection-worker/run-projection-worker.ts","../src/projection/projection-worker/projection-entry.ts"],"sourcesContent":["/**\n * In-worker projection stack builder.\n *\n * Mirrors {@link buildWorkerExecutor} but for the projection-side\n * read models. The worker owns one full copy of the storage stack — read\n * cache, operation index, document-meta cache — bound to its own\n * pg.Pool/Kysely, plus an in-process `ReadModelCoordinator` that\n * subscribes to a local `EventBus`.\n *\n * The host relays JOB_WRITE_READY into the local bus by calling\n * `relayWriteReady`, and forwards the local bus's JOB_READ_READY plus\n * READMODEL_* events back to the host bus via the IPC bridge.\n */\n\nimport {\n isPurgeMarker,\n type DocumentModelModule,\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 { CatchUpScheduler } from \"../../catch-up/scheduler.js\";\nimport {\n createKyselyWatermarkProbe,\n SettledWatermark,\n} from \"../../catch-up/settled-watermark.js\";\nimport type {\n CatchUpStatus,\n ICatchUpConsumer,\n SweepResult,\n} from \"../../catch-up/types.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 type { Database } from \"../../core/types.js\";\nimport { EventBus } from \"../../events/event-bus.js\";\nimport {\n ReactorEventTypes,\n type JobReadReadyEvent,\n type JobWriteReadyEvent,\n type ReadModelBatchCompletedEvent,\n type ReadModelIndexedEvent,\n type Unsubscribe,\n} from \"../../events/types.js\";\nimport type { BuildWorkerExecutorOptions } from \"../../executor/worker/build-worker-executor.js\";\nimport { defaultLoadFactory } from \"../../executor/worker/load-spec.js\";\nimport type {\n FactorySpec,\n ModelManifestEntry,\n} from \"../../executor/worker/protocol.js\";\nimport {\n BaseReadModel,\n type ReadModelIndexingConfig,\n} from \"../../read-models/base-read-model.js\";\nimport { ReadModelCoordinator } from \"../../read-models/coordinator.js\";\nimport {\n DeletedDocumentRead,\n KyselyDocumentView,\n} from \"../../read-models/document-view.js\";\nimport type { IReadModel } from \"../../read-models/interfaces.js\";\nimport { DocumentModelRegistry } from \"../../registry/implementation.js\";\nimport { ConsistencyTracker } from \"../../shared/consistency-tracker.js\";\nimport type { ConsistencyCoordinate } from \"../../shared/types.js\";\nimport {\n KyselyDocumentIndexer,\n type IndexerDatabase,\n} from \"../../storage/kysely/document-indexer.js\";\nimport { findPurged } from \"../../storage/kysely/document-purges.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 type {\n BuiltInReadModelKind,\n ProjectionInitMessage,\n} from \"../protocol.js\";\n\nexport type ProjectionStackEvents = {\n onReadReady: (event: JobReadReadyEvent) => void;\n onReadModelIndexed: (event: ReadModelIndexedEvent) => void;\n onBatchCompleted: (event: ReadModelBatchCompletedEvent) => void;\n onReadModelSwept: (\n readModelName: string,\n coordinates: ConsistencyCoordinate[],\n result: SweepResult,\n ) => void;\n};\n\nexport type ProjectionStack = {\n registry: DocumentModelRegistry;\n coordinator: ReadModelCoordinator;\n eventBus: EventBus;\n writeCache: KyselyWriteCache;\n relayWriteReady(event: JobWriteReadyEvent): Promise<void>;\n getChainDepth(): number;\n catchUpStatus(): CatchUpStatus;\n drain(): Promise<void>;\n shutdown(): Promise<void>;\n};\n\nexport type BuildProjectionStackOptions = {\n init: ProjectionInitMessage;\n database: Kysely<Database>;\n logger: ILogger;\n events: ProjectionStackEvents;\n loadFactory?: BuildWorkerExecutorOptions[\"loadFactory\"];\n driveContainerTypes?: ReadonlySet<string>;\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 \"projection 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 \"projection worker failed to register document model: @entry @error\",\n entry,\n result.error,\n );\n throw result.error;\n }\n }\n}\n\nfunction instantiateReadModel(\n kind: BuiltInReadModelKind,\n database: Kysely<Database>,\n operationStore: KyselyOperationStore,\n operationIndex: KyselyOperationIndex,\n writeCache: KyselyWriteCache,\n indexing: ReadModelIndexingConfig,\n): IReadModel {\n switch (kind) {\n case \"document-view\": {\n return new KyselyDocumentView(\n // @ts-expect-error - Database superset\n database,\n operationStore,\n operationIndex,\n writeCache,\n new ConsistencyTracker(),\n // Read-side only, so it cannot diverge state.\n DeletedDocumentRead.NotFound,\n indexing,\n );\n }\n case \"document-indexer\": {\n return new KyselyDocumentIndexer(\n database as unknown as Kysely<IndexerDatabase>,\n operationIndex,\n writeCache,\n new ConsistencyTracker(),\n indexing,\n );\n }\n default: {\n const exhaustive: never = kind;\n throw new Error(\n `unknown built-in read model kind: ${String(exhaustive)}`,\n );\n }\n }\n}\n\nasync function initReadModels(\n models: IReadModel[],\n logger: ILogger,\n): Promise<void> {\n for (const model of models) {\n const maybeInit = model as IReadModel & { init?: () => Promise<void> };\n if (typeof maybeInit.init !== \"function\") {\n continue;\n }\n try {\n await maybeInit.init();\n } catch (error) {\n logger.error(\n \"projection worker read model init failed: @name @error\",\n model.name,\n error,\n );\n throw error;\n }\n }\n}\n\n/** Posts what each sweep applied, so the host's tracker for the model advances. */\nfunction relaySweeps(\n model: BaseReadModel,\n events: ProjectionStackEvents,\n onSwept: (coordinates: ConsistencyCoordinate[]) => Promise<void>,\n): ICatchUpConsumer {\n return {\n get consumerId() {\n return model.consumerId;\n },\n get appliedThrough() {\n return model.appliedThrough;\n },\n get trackedAbove() {\n return model.trackedAbove;\n },\n async sweep(settledThrough, present, signal) {\n const coordinates: ConsistencyCoordinate[] = [];\n const unsubscribe = model.onSwept((swept) => coordinates.push(...swept));\n try {\n const result = await model.sweep(settledThrough, present, signal);\n if (\n coordinates.length > 0 ||\n result.to > result.from ||\n result.replayed > 0 ||\n result.blockedAt !== undefined\n ) {\n events.onReadModelSwept(model.name, coordinates, result);\n }\n await onSwept(coordinates);\n return result;\n } finally {\n unsubscribe();\n }\n },\n };\n}\n\nexport async function buildProjectionStack(\n options: BuildProjectionStackOptions,\n): Promise<ProjectionStack> {\n const { init, database: baseDatabase, logger, events } = options;\n const loadFactory = options.loadFactory ?? defaultLoadFactory;\n\n const registry = new DocumentModelRegistry();\n await loadModelManifest(init.models, loadFactory, registry, logger);\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 void collectionMembershipCache;\n\n // This thread's caches are its own; a marker it applies evicts the id here.\n const evict = (documentIds: Iterable<string>): void => {\n for (const documentId of documentIds) {\n writeCache.invalidate(documentId);\n documentMetaCache.invalidate(documentId);\n }\n };\n\n // A sweep reports coordinates only; a marker is index 0 of document scope.\n const evictSweptMarkers = async (\n coordinates: ConsistencyCoordinate[],\n ): Promise<void> => {\n const candidates = coordinates\n .filter((c) => c.scope === \"document\" && c.operationIndex === 0)\n .map((c) => c.documentId);\n if (candidates.length === 0) return;\n let purged: Set<string>;\n try {\n purged = await findPurged(database, candidates);\n } catch (error) {\n logger.error(\"projection worker purge lookup failed: @error\", error);\n return;\n }\n evict(purged);\n };\n\n const preReady = init.preReadyKinds.map((kind) =>\n instantiateReadModel(\n kind,\n database,\n operationStore,\n operationIndex,\n writeCache,\n init.indexing,\n ),\n );\n const postReady = init.postReadyKinds.map((kind) =>\n instantiateReadModel(\n kind,\n database,\n operationStore,\n operationIndex,\n writeCache,\n init.indexing,\n ),\n );\n\n const watermark = new SettledWatermark(\n createKyselyWatermarkProbe(database as unknown as Kysely<StorageDatabase>),\n logger,\n );\n const catchUp = new CatchUpScheduler(\n watermark,\n operationIndex,\n init.catchUp,\n logger,\n );\n const models = [...preReady, ...postReady];\n for (const model of models) {\n if (model instanceof BaseReadModel) {\n model.attachCatchUp(watermark, init.catchUp.maxTrackedAboveCursor);\n }\n }\n\n await initReadModels(models, logger);\n\n for (const model of models) {\n if (model instanceof BaseReadModel) {\n catchUp.addConsumer(\n relaySweeps(model, events, evictSweptMarkers),\n \"projection\",\n );\n }\n }\n catchUp.start();\n\n const eventBus = new EventBus();\n const subscriptions: Unsubscribe[] = [];\n\n subscriptions.push(\n eventBus.subscribe(\n ReactorEventTypes.JOB_READ_READY,\n (_t: number, event: JobReadReadyEvent) => {\n events.onReadReady(event);\n },\n ),\n );\n subscriptions.push(\n eventBus.subscribe(\n ReactorEventTypes.READMODEL_INDEXED,\n (_t: number, event: ReadModelIndexedEvent) => {\n events.onReadModelIndexed(event);\n },\n ),\n );\n subscriptions.push(\n eventBus.subscribe(\n ReactorEventTypes.READMODEL_BATCH_COMPLETED,\n (_t: number, event: ReadModelBatchCompletedEvent) => {\n events.onBatchCompleted(event);\n },\n ),\n );\n\n const coordinator = new ReadModelCoordinator(eventBus, preReady, postReady);\n coordinator.start();\n\n return {\n registry,\n coordinator,\n eventBus,\n writeCache,\n async relayWriteReady(event: JobWriteReadyEvent): Promise<void> {\n evict(\n event.operations\n .filter((item) => isPurgeMarker(item))\n .map((item) => item.context.documentId),\n );\n await eventBus.emit(ReactorEventTypes.JOB_WRITE_READY, event);\n },\n getChainDepth(): number {\n return coordinator.getChainDepth();\n },\n catchUpStatus(): CatchUpStatus {\n return catchUp.status();\n },\n async drain(): Promise<void> {\n await coordinator.drain();\n },\n async shutdown(): Promise<void> {\n await catchUp.stop();\n coordinator.stop();\n for (const unsub of subscriptions) {\n unsub();\n }\n },\n };\n}\n","import { ConsoleLogger } from \"document-model\";\nimport type { Kysely } from \"kysely\";\nimport type { MessagePort } from \"node:worker_threads\";\nimport type { Database } from \"../../core/types.js\";\nimport { createForwardingLogger } from \"../../executor/worker/forwarding-logger.js\";\nimport type { DbConfig } from \"../../executor/worker/protocol.js\";\nimport { errorToInfo } from \"../../executor/worker/sanitize.js\";\nimport type {\n JobReadReadyEvent,\n JobWriteReadyEvent,\n ReadModelBatchCompletedEvent,\n ReadModelIndexedEvent,\n} from \"../../events/types.js\";\nimport {\n instrumentPgPool,\n type PoolInstrumentation,\n} from \"../../storage/pool-instrumentation.js\";\nimport type {\n ProjectionInitMessage,\n ProjectionParentMessage,\n ProjectionWorkerMessage,\n} from \"../protocol.js\";\nimport {\n buildProjectionStack,\n type ProjectionStack,\n} from \"./build-projection-stack.js\";\n\nconst POOL_SAMPLE_INTERVAL_MS = 1_000;\n\n/**\n * Closeable handle around the worker's Postgres pool. Decoupled from the\n * default factory so tests can swap in PGlite via `RunProjectionWorkerOverrides`.\n *\n * When the worker owns a real pg.Pool, the handle exposes a\n * {@link PoolInstrumentation} so the run loop can forward acquire-wait\n * samples to the host. Tests that swap in PGlite leave this undefined.\n */\nexport type ProjectionWorkerDatabaseHandle = {\n kysely: Kysely<Database>;\n poolInstrumentation?: PoolInstrumentation;\n shutdown(): Promise<void>;\n};\n\nexport type RunProjectionWorkerOverrides = {\n createDatabase?: (\n config: DbConfig,\n shardId: string,\n ) => Promise<ProjectionWorkerDatabaseHandle>;\n loadFactory?: Parameters<typeof buildProjectionStack>[0][\"loadFactory\"];\n beforeBuildStack?: (db: Kysely<Database>) => Promise<void>;\n};\n\nasync function defaultCreateDatabase(\n config: DbConfig,\n shardId: string,\n): Promise<ProjectionWorkerDatabaseHandle> {\n const { Kysely, PostgresDialect } = await import(\"kysely\");\n const pgModule = await import(\"pg\");\n const Pool = pgModule.default.Pool;\n const pool = new Pool({\n host: config.host,\n port: config.port,\n database: config.database,\n user: config.user,\n password: config.password,\n ssl: config.ssl ? { rejectUnauthorized: false } : undefined,\n application_name: config.applicationName ?? shardId,\n max: config.poolSize,\n connectionTimeoutMillis: config.connectionTimeoutMillis,\n idleTimeoutMillis: config.idleTimeoutMillis,\n });\n const poolInstrumentation = instrumentPgPool(pool, shardId);\n const kysely = new Kysely<Database>({\n dialect: new PostgresDialect({ pool }),\n });\n return {\n kysely,\n poolInstrumentation,\n async shutdown(): Promise<void> {\n try {\n await kysely.destroy();\n } catch {\n // best-effort\n }\n try {\n await pool.end();\n } catch {\n // best-effort\n }\n },\n };\n}\n\n/**\n * Drives the projection worker's message loop. Owns lifecycle of the\n * database handle and the projection stack. The default factory builds a\n * real Postgres pool; tests inject overrides for an in-process PGlite path.\n */\nexport function runProjectionWorker(\n parentPort: MessagePort,\n overrides: RunProjectionWorkerOverrides = {},\n): void {\n let shardId = \"\";\n let initCompleted = false;\n let stack: ProjectionStack | null = null;\n let database: ProjectionWorkerDatabaseHandle | null = null;\n let depthTimer: NodeJS.Timeout | null = null;\n let lastReportedDepth = -1;\n let poolSampleTimer: NodeJS.Timeout | null = null;\n let pendingPoolSamples: number[] = [];\n let detachPoolListener: (() => void) | null = null;\n\n function post(msg: ProjectionWorkerMessage): void {\n parentPort.postMessage(msg);\n }\n\n function startPoolReporter(instrumentation: PoolInstrumentation): void {\n detachPoolListener = instrumentation.onAcquire((durationMs) => {\n pendingPoolSamples.push(durationMs);\n });\n poolSampleTimer = setInterval(() => {\n if (pendingPoolSamples.length === 0) {\n return;\n }\n const durations = pendingPoolSamples;\n pendingPoolSamples = [];\n const stats = instrumentation.getStats();\n post({\n type: \"pool-acquire-samples\",\n shardId,\n poolName: instrumentation.name,\n timestamp: Date.now(),\n durations,\n size: stats.size,\n idle: stats.idle,\n waiting: stats.waiting,\n });\n }, POOL_SAMPLE_INTERVAL_MS);\n poolSampleTimer.unref();\n }\n\n function stopPoolReporter(): void {\n if (detachPoolListener) {\n detachPoolListener();\n detachPoolListener = null;\n }\n if (poolSampleTimer) {\n clearInterval(poolSampleTimer);\n poolSampleTimer = null;\n }\n pendingPoolSamples = [];\n }\n\n const logger = createForwardingLogger((msg) => post({ ...msg, shardId }));\n\n process.on(\"uncaughtException\", (err: unknown) => {\n try {\n post({\n type: \"log\",\n shardId,\n level: \"error\",\n message: \"projection worker uncaughtException\",\n args: [errorToInfo(err)],\n timestamp: Date.now(),\n });\n } catch {\n // nothing left to do\n }\n throw err;\n });\n\n process.on(\"unhandledRejection\", (reason: unknown) => {\n try {\n post({\n type: \"log\",\n shardId,\n level: \"error\",\n message: \"projection worker unhandledRejection\",\n args: [errorToInfo(reason)],\n timestamp: Date.now(),\n });\n } catch {\n // nothing left to do\n }\n });\n\n function startDepthReporter(intervalMs: number): void {\n if (intervalMs <= 0) {\n return;\n }\n depthTimer = setInterval(() => {\n if (!stack) {\n return;\n }\n post({\n type: \"catchup-status\",\n shardId,\n status: stack.catchUpStatus(),\n });\n const depth = stack.getChainDepth();\n if (depth === lastReportedDepth) {\n return;\n }\n lastReportedDepth = depth;\n post({\n type: \"chain-depth\",\n shardId,\n depth,\n timestamp: Date.now(),\n });\n }, intervalMs);\n depthTimer.unref();\n }\n\n function stopDepthReporter(): void {\n if (depthTimer) {\n clearInterval(depthTimer);\n depthTimer = null;\n }\n }\n\n async function handleInit(msg: ProjectionInitMessage): Promise<void> {\n shardId = msg.shardId;\n const createDb = overrides.createDatabase ?? defaultCreateDatabase;\n database = await createDb(msg.db, msg.shardId);\n if (overrides.beforeBuildStack) {\n await overrides.beforeBuildStack(database.kysely);\n }\n stack = await buildProjectionStack({\n init: msg,\n database: database.kysely,\n logger: new ConsoleLogger([`projection-shard:${msg.shardId}`]),\n loadFactory: overrides.loadFactory,\n events: {\n onReadReady: (event: JobReadReadyEvent) => {\n post({\n type: \"read-ready\",\n shardId,\n jobId: event.jobId,\n operations: event.operations,\n });\n },\n onReadModelIndexed: (event: ReadModelIndexedEvent) => {\n post({\n type: \"readmodel-indexed\",\n shardId,\n jobId: event.jobId,\n readModelName: event.readModelName,\n stage: event.stage,\n durationMs: event.durationMs,\n operationCount: event.operationCount,\n success: event.success,\n });\n },\n onReadModelSwept: (readModelName, coordinates, result) => {\n post({\n type: \"readmodel-swept\",\n shardId,\n readModelName,\n coordinates,\n result,\n });\n },\n onBatchCompleted: (event: ReadModelBatchCompletedEvent) => {\n post({\n type: \"readmodel-batch-completed\",\n shardId,\n jobId: event.jobId,\n batchSize: event.batchSize,\n chainWaitDurationMs: event.chainWaitDurationMs,\n preReadyDurationMs: event.preReadyDurationMs,\n emitDurationMs: event.emitDurationMs,\n postReadyDurationMs: event.postReadyDurationMs,\n });\n },\n },\n });\n initCompleted = true;\n startDepthReporter(msg.chainDepthReportIntervalMs);\n if (database.poolInstrumentation) {\n startPoolReporter(database.poolInstrumentation);\n }\n logger.info(\"projection worker initialized: @shardId\", msg.shardId);\n post({ type: \"ready\", correlationId: msg.correlationId, shardId });\n }\n\n async function handleWriteReady(\n msg: Extract<ProjectionParentMessage, { type: \"write-ready\" }>,\n ): Promise<void> {\n if (!stack) {\n logger.warn(\n \"write-ready received before init on shard @shardId\",\n shardId,\n );\n return;\n }\n const event: JobWriteReadyEvent = {\n jobId: msg.jobId,\n operations: msg.operations,\n jobMeta: msg.jobMeta,\n collectionMemberships: msg.collectionMemberships,\n };\n await stack.relayWriteReady(event);\n }\n\n async function handleDrain(correlationId: string): Promise<void> {\n if (stack) {\n await stack.drain();\n }\n post({ type: \"drained\", correlationId, shardId });\n }\n\n async function shutdownStack(): Promise<void> {\n stopDepthReporter();\n stopPoolReporter();\n if (stack) {\n try {\n await stack.drain();\n } catch (error) {\n logger.warn(\n \"projection worker drain failed during shutdown: @error\",\n error,\n );\n }\n try {\n await stack.shutdown();\n } catch (error) {\n logger.warn(\"projection worker stack shutdown failed: @error\", error);\n }\n stack = null;\n }\n if (database) {\n await database.shutdown();\n database = null;\n }\n }\n\n function handleParentMessage(msg: ProjectionParentMessage): void {\n switch (msg.type) {\n case \"init\": {\n // Terminal: the worker has no stack, so it can project nothing. The\n // parent rejects startup on this message and terminates the thread;\n // exiting here would race the message and lose the cause.\n handleInit(msg).catch((err: unknown) => {\n post({\n type: \"init-failed\",\n correlationId: msg.correlationId,\n shardId,\n error: errorToInfo(err),\n });\n });\n break;\n }\n case \"write-ready\": {\n if (!initCompleted) {\n logger.warn(\n \"write-ready received before init on shard @shardId\",\n shardId,\n );\n break;\n }\n handleWriteReady(msg).catch((err: unknown) => {\n post({\n type: \"log\",\n shardId,\n level: \"error\",\n message: \"projection worker write-ready failed\",\n args: [errorToInfo(err)],\n timestamp: Date.now(),\n });\n });\n break;\n }\n case \"drain\": {\n handleDrain(msg.correlationId).catch((err: unknown) => {\n post({\n type: \"log\",\n shardId,\n level: \"error\",\n message: \"projection worker drain failed\",\n args: [errorToInfo(err)],\n timestamp: Date.now(),\n });\n });\n break;\n }\n case \"shutdown\": {\n logger.info(\"projection worker shutting down: @shardId\", shardId);\n void shutdownStack().finally(() => {\n post({\n type: \"log\",\n shardId,\n level: \"info\",\n message: \"projection worker shutdown\",\n args: [],\n timestamp: Date.now(),\n });\n process.exit(0);\n });\n break;\n }\n default: {\n const exhaustive: never = msg;\n void exhaustive;\n break;\n }\n }\n }\n\n parentPort.on(\"message\", handleParentMessage);\n\n const harness = {\n handleParentMessage,\n get initCompleted(): boolean {\n return initCompleted;\n },\n get shardId(): string {\n return shardId;\n },\n };\n (\n parentPort as unknown as { __reactorProjectionWorkerHarness?: unknown }\n ).__reactorProjectionWorkerHarness = harness;\n}\n","import { isMainThread, parentPort } from \"node:worker_threads\";\nimport { runProjectionWorker } from \"./run-projection-worker.js\";\n\nif (isMainThread || parentPort === null) {\n throw new Error(\"projection-worker entry.ts must be run as a worker thread\");\n}\n\nrunProjectionWorker(parentPort);\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { At as ReactorEventTypes, o as fromErrorInfo } from "./load-spec-D9lnje-H.js";
1
+ import { St as ReactorEventTypes, i as fromErrorInfo } from "./forwarding-logger-ByfBFgMS.js";
2
2
  import { childLogger } from "document-model";
3
3
  import { randomUUID } from "node:crypto";
4
4
  //#region src/projection/projection-shard-manager.ts
@@ -457,4 +457,4 @@ var ProjectionShardManager = class {
457
457
  //#endregion
458
458
  export { ProjectionShardManager };
459
459
 
460
- //# sourceMappingURL=projection-shard-manager-MRJ9BjVM.js.map
460
+ //# sourceMappingURL=projection-shard-manager-CQ5FwQmv.js.map