@powerhousedao/reactor 6.2.2-dev.42 → 6.2.2-dev.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{build-worker-executor-CAEZD_yJ.js → build-worker-executor-CBWALjgq.js} +2 -2
- package/dist/{build-worker-executor-CAEZD_yJ.js.map → build-worker-executor-CBWALjgq.js.map} +1 -1
- package/dist/{document-indexer-C0GB0b8Q.js → document-indexer-BfdCgjG-.js} +15 -14
- package/dist/document-indexer-BfdCgjG-.js.map +1 -0
- package/dist/{drive-container-types-BJCKXJwH.js → drive-container-types-CU1ZUfD1.js} +178 -26
- package/dist/drive-container-types-CU1ZUfD1.js.map +1 -0
- package/dist/entry.js +2 -2
- package/dist/index.d.ts +104 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +93 -18
- package/dist/index.js.map +1 -1
- package/dist/projection-entry.js +3 -3
- package/dist/{worker-jEJW6_j7.js → worker-CeW6WsVF.js} +2 -2
- package/dist/{worker-jEJW6_j7.js.map → worker-CeW6WsVF.js.map} +1 -1
- package/package.json +4 -4
- package/dist/document-indexer-C0GB0b8Q.js.map +0 -1
- package/dist/drive-container-types-BJCKXJwH.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { A as OptimisticLockError, B as ExcessiveReshuffleError, C as DocumentMetaCache, D as APPEND_CONDITION_FAILED_PREFIX, E as CollectionMembershipCache, F as ModuleNotFoundError, H as
|
|
1
|
+
import { A as OptimisticLockError, B as ExcessiveReshuffleError, C as DocumentMetaCache, D as APPEND_CONDITION_FAILED_PREFIX, E as CollectionMembershipCache, F as ModuleNotFoundError, G as throwIfAborted, H as UpgradePreconditionFailedError, I as AuthTimestampNotMonotonicError, L as AuthorizationDeniedError, M as DuplicateManifestError, N as DuplicateModuleError, O as AppendConditionFailedError, P as InvalidModuleError, R as DocumentDeletedError, S as KyselyOperationIndex, T as createEmptyConsistencyToken, U as matchesScope, V as InvalidOperationTimestampError, W as parsePagingOptions, _ as KyselyExecutionScope, a as createForwardingPoolInstrumentation, b as EventBus, c as KyselyKeyframeStore, d as DriveCollectionId, f as decideAtHead, g as authDecisionModel, h as buildDecisionModel, i as runMigrations, j as RevisionMismatchError, k as DuplicateOperationError, l as DocumentModelRegistry, m as documentDecisionModel, n as REACTOR_SCHEMA, o as instrumentPgPool, p as selectDecisionModel, r as getMigrationStatus, s as KyselyOperationStore, t as DEFAULT_DRIVE_CONTAINER_TYPES, u as SimpleJobExecutor, v as FLAG_PREREQUISITES, w as createConsistencyToken, x as KyselyWriteCache, y as validateFeatureFlags, z as DocumentNotFoundError } from "./drive-container-types-CU1ZUfD1.js";
|
|
2
2
|
import { n as ReactorEventTypes, t as EventBusAggregateError } from "./types-DMKLa0Ok.js";
|
|
3
3
|
import { i as WorkerInitFailedError, r as WorkerExitedError, t as WorkerAbortTimeoutError } from "./errors-D3S6Eysd.js";
|
|
4
|
-
import { a as ReadModelCoordinator, i as KyselyDocumentView, n as ConsistencyTracker, o as BaseReadModel, r as makeConsistencyKey, t as KyselyDocumentIndexer } from "./document-indexer-
|
|
4
|
+
import { a as ReadModelCoordinator, i as KyselyDocumentView, n as ConsistencyTracker, o as BaseReadModel, r as makeConsistencyKey, t as KyselyDocumentIndexer } from "./document-indexer-BfdCgjG-.js";
|
|
5
5
|
import { n as errorToInfo, r as sanitizeArg, t as createForwardingLogger } from "./forwarding-logger-BBkMSxuJ.js";
|
|
6
|
-
import { t as workerEntryPath } from "./worker-
|
|
7
|
-
import { actions, actions as documentActions, createPresignedHeader, decide, garbageCollect, generateId, hashDocumentStateForScope,
|
|
6
|
+
import { t as workerEntryPath } from "./worker-CeW6WsVF.js";
|
|
7
|
+
import { DowngradeNotSupportedError, UnsupportedDocumentModelVersionError, actions, actions as documentActions, createPresignedHeader, decide, garbageCollect, generateId, hashDocumentStateForScope, normalizeDocumentModelVersion, sortOperations } from "@powerhousedao/shared/document-model";
|
|
8
8
|
import { addFile, addFolder, copyNode, deleteNode, driveCreateDocument, generateNodesCopy, getDescendants, handleTargetNameCollisions, isFileNode, isFolderNode, moveNode, updateNode } from "@powerhousedao/shared/document-drive";
|
|
9
9
|
import { v4 } from "uuid";
|
|
10
10
|
import { ConsoleLogger, childLogger } from "document-model";
|
|
@@ -365,7 +365,7 @@ var DriveClient = class {
|
|
|
365
365
|
documentId: document.header.id,
|
|
366
366
|
model: document.header.documentType,
|
|
367
367
|
fromVersion: 0,
|
|
368
|
-
toVersion:
|
|
368
|
+
toVersion: normalizeDocumentModelVersion(document.state.document?.version),
|
|
369
369
|
initialState: document.state
|
|
370
370
|
}),
|
|
371
371
|
addRelationshipAction(driveIdentifier, documentId, "child")
|
|
@@ -470,8 +470,12 @@ var DriveClient = class {
|
|
|
470
470
|
const node = drive.state.global.nodes.find((n) => n.id === entry.srcId);
|
|
471
471
|
if (!node || !isFileNode(node)) continue;
|
|
472
472
|
const srcDoc = await this.client.get(entry.srcId, void 0, signal);
|
|
473
|
-
const
|
|
474
|
-
|
|
473
|
+
const duplicated = {
|
|
474
|
+
...srcDoc,
|
|
475
|
+
header: createPresignedHeader(entry.targetId, srcDoc.header.documentType),
|
|
476
|
+
initialState: srcDoc.state,
|
|
477
|
+
operations: {}
|
|
478
|
+
};
|
|
475
479
|
const resolvedName = resolvedNamesByTargetId.get(entry.targetId);
|
|
476
480
|
if (resolvedName) duplicated.header.name = resolvedName;
|
|
477
481
|
await this.addFile(driveIdentifier, duplicated, entry.targetParentFolder ?? void 0, signal);
|
|
@@ -769,9 +773,37 @@ var ReactorClient = class {
|
|
|
769
773
|
* @returns The document model module
|
|
770
774
|
*/
|
|
771
775
|
async getDocumentModelModule(documentType) {
|
|
772
|
-
const
|
|
773
|
-
|
|
774
|
-
|
|
776
|
+
const modules = await this.reactor.getDocumentModels();
|
|
777
|
+
let latestModule;
|
|
778
|
+
let latestVersion = -1;
|
|
779
|
+
for (const module of modules.results) {
|
|
780
|
+
if (module.documentModel.global.id !== documentType) continue;
|
|
781
|
+
const version = module.version ?? 1;
|
|
782
|
+
if (version > latestVersion) {
|
|
783
|
+
latestVersion = version;
|
|
784
|
+
latestModule = module;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
if (!latestModule) throw new Error(`Document model module not found for type: ${documentType}`);
|
|
788
|
+
return latestModule;
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Retrieves the document model module matching the version the document is
|
|
792
|
+
* stamped with, so not-yet-upgraded documents get the reducer their
|
|
793
|
+
* history was written with rather than the latest.
|
|
794
|
+
*/
|
|
795
|
+
async getDocumentModelModuleForDocument(document) {
|
|
796
|
+
const documentType = document.header.documentType;
|
|
797
|
+
const version = normalizeDocumentModelVersion(document.state.document?.version);
|
|
798
|
+
const modules = await this.reactor.getDocumentModels();
|
|
799
|
+
const availableVersions = [];
|
|
800
|
+
for (const module of modules.results) {
|
|
801
|
+
if (module.documentModel.global.id !== documentType) continue;
|
|
802
|
+
const moduleVersion = normalizeDocumentModelVersion(module.version);
|
|
803
|
+
if (moduleVersion === version) return module;
|
|
804
|
+
availableVersions.push(moduleVersion);
|
|
805
|
+
}
|
|
806
|
+
throw new UnsupportedDocumentModelVersionError(documentType, version, availableVersions.sort((a, b) => a - b));
|
|
775
807
|
}
|
|
776
808
|
/**
|
|
777
809
|
* Retrieves a specific PHDocument
|
|
@@ -925,7 +957,7 @@ var ReactorClient = class {
|
|
|
925
957
|
documentId,
|
|
926
958
|
model: document.header.documentType,
|
|
927
959
|
fromVersion: 0,
|
|
928
|
-
toVersion: document.state.document
|
|
960
|
+
toVersion: normalizeDocumentModelVersion(document.state.document?.version),
|
|
929
961
|
initialState: document.state
|
|
930
962
|
})], this.signer, signal);
|
|
931
963
|
const jobs = [{
|
|
@@ -960,20 +992,61 @@ var ReactorClient = class {
|
|
|
960
992
|
const matchingModules = (await this.reactor.getDocumentModels(void 0, void 0, signal)).results.filter((m) => m.documentModel.global.id === documentModelType);
|
|
961
993
|
let module;
|
|
962
994
|
if (options?.documentModelVersion !== void 0) {
|
|
963
|
-
|
|
995
|
+
const requestedVersion = normalizeDocumentModelVersion(options.documentModelVersion);
|
|
996
|
+
module = matchingModules.find((m) => normalizeDocumentModelVersion(m.version) === requestedVersion);
|
|
964
997
|
if (!module) throw new Error(`Document model not found for type: ${documentModelType} with version: ${options.documentModelVersion}`);
|
|
965
998
|
} else {
|
|
966
999
|
module = matchingModules.reduce((latest, current) => {
|
|
967
1000
|
if (latest === void 0) return current;
|
|
968
|
-
return (current.version
|
|
1001
|
+
return normalizeDocumentModelVersion(current.version) > normalizeDocumentModelVersion(latest.version) ? current : latest;
|
|
969
1002
|
}, void 0);
|
|
970
1003
|
if (!module) throw new Error(`Document model not found for type: ${documentModelType}`);
|
|
971
1004
|
}
|
|
972
1005
|
const document = module.utils.createDocument();
|
|
973
|
-
document.state.document.version = module.version
|
|
1006
|
+
document.state.document.version = normalizeDocumentModelVersion(module.version);
|
|
974
1007
|
return this.create(document, options?.parentIdentifier, signal);
|
|
975
1008
|
}
|
|
976
1009
|
/**
|
|
1010
|
+
* Upgrades a document to a newer document model version by dispatching an
|
|
1011
|
+
* UPGRADE_DOCUMENT action. When toVersion is omitted, upgrades to the
|
|
1012
|
+
* latest registered module version for the document's type. Returns the
|
|
1013
|
+
* document unchanged when it is already at the target version.
|
|
1014
|
+
*
|
|
1015
|
+
* The executor validates the action's version and revision snapshot against
|
|
1016
|
+
* the state the migration actually runs on. When a concurrent edit
|
|
1017
|
+
* invalidates the snapshot, the upgrade is rebuilt from a fresh read and
|
|
1018
|
+
* retried up to maxConflictRetries times before the conflict is surfaced.
|
|
1019
|
+
*/
|
|
1020
|
+
async upgradeDocument(documentIdentifier, toVersion, options, signal) {
|
|
1021
|
+
this.logger.verbose("upgradeDocument(@documentIdentifier, @toVersion)", documentIdentifier, toVersion);
|
|
1022
|
+
const maxConflictRetries = options?.maxConflictRetries ?? 3;
|
|
1023
|
+
let lastConflictMessage = "";
|
|
1024
|
+
for (let attempt = 0; attempt <= maxConflictRetries; attempt++) {
|
|
1025
|
+
const document = await this.reactor.getByIdOrSlug(documentIdentifier, void 0, void 0, signal);
|
|
1026
|
+
const documentId = document.header.id;
|
|
1027
|
+
const documentType = document.header.documentType;
|
|
1028
|
+
const branch = document.header.branch || "main";
|
|
1029
|
+
const fromVersion = normalizeDocumentModelVersion(document.state.document?.version);
|
|
1030
|
+
let targetVersion = toVersion;
|
|
1031
|
+
if (targetVersion === void 0) targetVersion = normalizeDocumentModelVersion((await this.getDocumentModelModule(documentType)).version);
|
|
1032
|
+
if (targetVersion === fromVersion) return document;
|
|
1033
|
+
if (targetVersion < fromVersion) throw new DowngradeNotSupportedError(documentType, fromVersion, targetVersion);
|
|
1034
|
+
const signedActions = await signActions([upgradeDocumentAction({
|
|
1035
|
+
documentId,
|
|
1036
|
+
model: documentType,
|
|
1037
|
+
fromVersion,
|
|
1038
|
+
toVersion: targetVersion,
|
|
1039
|
+
revision: { ...document.header.revision }
|
|
1040
|
+
})], this.signer, signal);
|
|
1041
|
+
const jobInfo = await this.reactor.execute(documentId, branch, signedActions, signal);
|
|
1042
|
+
const completedJob = await this.waitForJob(jobInfo, signal);
|
|
1043
|
+
if (completedJob.status !== JobStatus.FAILED) return await this.reactor.getByIdOrSlug(documentId, { branch }, completedJob.consistencyToken, signal);
|
|
1044
|
+
if (completedJob.error?.name !== "UpgradePreconditionFailedError") throw new Error(completedJob.error?.message);
|
|
1045
|
+
lastConflictMessage = completedJob.error.message;
|
|
1046
|
+
}
|
|
1047
|
+
throw new Error(`Upgrade of document ${documentIdentifier} conflicted with concurrent edits after ${maxConflictRetries + 1} attempts: ${lastConflictMessage}`);
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
977
1050
|
* Creates an empty document in a drive as a single batched operation.
|
|
978
1051
|
* Delegates to {@link IDriveClient.addFile}.
|
|
979
1052
|
*
|
|
@@ -1274,7 +1347,7 @@ var JobResultHandler = class {
|
|
|
1274
1347
|
callbacks.deferJob(handle.job.documentId, handle.job);
|
|
1275
1348
|
return;
|
|
1276
1349
|
}
|
|
1277
|
-
if (result.error && (DocumentDeletedError.isError(result.error) || AuthorizationDeniedError.isError(result.error) || AuthTimestampNotMonotonicError.isError(result.error) || InvalidOperationTimestampError.isError(result.error) || ExcessiveReshuffleError.isError(result.error))) {
|
|
1350
|
+
if (result.error && (DocumentDeletedError.isError(result.error) || AuthorizationDeniedError.isError(result.error) || AuthTimestampNotMonotonicError.isError(result.error) || InvalidOperationTimestampError.isError(result.error) || ExcessiveReshuffleError.isError(result.error) || UpgradePreconditionFailedError.isError(result.error))) {
|
|
1278
1351
|
const errorInfo = toErrorInfo(result.error);
|
|
1279
1352
|
this.jobTracker.markFailed(handle.job.id, errorInfo, handle.job);
|
|
1280
1353
|
this.eventBus.emit(ReactorEventTypes.JOB_FAILED, {
|
|
@@ -2668,9 +2741,11 @@ var InMemoryQueue = class {
|
|
|
2668
2741
|
this.jobIndex.delete(jobId);
|
|
2669
2742
|
this.completedJobs.add(jobId);
|
|
2670
2743
|
await this.remove(jobId);
|
|
2744
|
+
const emittedError = new Error(error?.message ?? "Job failed");
|
|
2745
|
+
if (error?.name) emittedError.name = error.name;
|
|
2671
2746
|
this.eventBus.emit(ReactorEventTypes.JOB_FAILED, {
|
|
2672
2747
|
jobId,
|
|
2673
|
-
error:
|
|
2748
|
+
error: emittedError,
|
|
2674
2749
|
job
|
|
2675
2750
|
}).catch(() => {});
|
|
2676
2751
|
this.checkDrained();
|
|
@@ -6385,7 +6460,7 @@ var Reactor = class {
|
|
|
6385
6460
|
documentId: document.header.id,
|
|
6386
6461
|
model: document.header.documentType,
|
|
6387
6462
|
fromVersion: 0,
|
|
6388
|
-
toVersion: document.state.document
|
|
6463
|
+
toVersion: normalizeDocumentModelVersion(document.state.document?.version),
|
|
6389
6464
|
initialState: document.state
|
|
6390
6465
|
})];
|
|
6391
6466
|
if (signer) actions = await signActions(actions, signer, signal);
|
|
@@ -7162,7 +7237,7 @@ var ReactorBuilder = class {
|
|
|
7162
7237
|
const [{ WorkerHandle }, { createThreadTransport }, { workerEntryPath }] = await Promise.all([
|
|
7163
7238
|
import("./worker-handle-CrERzl8s.js"),
|
|
7164
7239
|
import("./transport-ByGviWdZ.js"),
|
|
7165
|
-
import("./worker-
|
|
7240
|
+
import("./worker-CeW6WsVF.js").then((n) => n.n)
|
|
7166
7241
|
]);
|
|
7167
7242
|
const poolConfig = {
|
|
7168
7243
|
enabled: true,
|