@powerhousedao/reactor 6.0.0-dev.243 → 6.0.0-dev.245
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/index.d.ts +24 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +283 -248
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -409,6 +409,10 @@ var DriveClient = class {
|
|
|
409
409
|
if (!node) throw new Error("Node missing from drive after rename");
|
|
410
410
|
return node;
|
|
411
411
|
}
|
|
412
|
+
async setPreferredEditorOnNode(nodeId, preferredEditor, signal) {
|
|
413
|
+
this.logger.verbose("drives.setPreferredEditorOnNode(@nodeId, @preferredEditor)", nodeId, preferredEditor);
|
|
414
|
+
return this.client.setPreferredEditor(nodeId, preferredEditor, "main", signal);
|
|
415
|
+
}
|
|
412
416
|
async moveNode(driveIdentifier, srcNodeId, targetParentFolderId, signal) {
|
|
413
417
|
this.logger.verbose("drives.moveNode(@driveIdentifier, @srcNodeId, @targetParentFolderId)", driveIdentifier, srcNodeId, targetParentFolderId);
|
|
414
418
|
return this.client.execute(driveIdentifier, "main", [moveNode({
|
|
@@ -928,6 +932,14 @@ var ReactorClient = class {
|
|
|
928
932
|
return this.execute(documentIdentifier, branch, [actions.setName(name)], signal);
|
|
929
933
|
}
|
|
930
934
|
/**
|
|
935
|
+
* Updates the preferred editor recorded in the document header meta.
|
|
936
|
+
* Pass `null` to clear it.
|
|
937
|
+
*/
|
|
938
|
+
async setPreferredEditor(documentIdentifier, preferredEditor, branch = "main", signal) {
|
|
939
|
+
this.logger.verbose("setPreferredEditor(@documentIdentifier, @preferredEditor, @branch)", documentIdentifier, preferredEditor, branch);
|
|
940
|
+
return this.execute(documentIdentifier, branch, [actions.setPreferredEditor(preferredEditor)], signal);
|
|
941
|
+
}
|
|
942
|
+
/**
|
|
931
943
|
* Adds multiple documents as children to another and waits for completion
|
|
932
944
|
*/
|
|
933
945
|
async addRelationship(sourceIdentifier, targetIdentifier, relationshipType, branch = "main", signal) {
|
|
@@ -2368,7 +2380,7 @@ let JobQueueState = /* @__PURE__ */ function(JobQueueState) {
|
|
|
2368
2380
|
*/
|
|
2369
2381
|
const QueueEventTypes = { JOB_AVAILABLE: 1e4 };
|
|
2370
2382
|
//#endregion
|
|
2371
|
-
//#region src/registry/
|
|
2383
|
+
//#region src/registry/errors.ts
|
|
2372
2384
|
/**
|
|
2373
2385
|
* Error thrown when a document model module is not found in the registry.
|
|
2374
2386
|
*/
|
|
@@ -2456,140 +2468,6 @@ var InvalidUpgradeStepError = class extends Error {
|
|
|
2456
2468
|
this.name = "InvalidUpgradeStepError";
|
|
2457
2469
|
}
|
|
2458
2470
|
};
|
|
2459
|
-
/**
|
|
2460
|
-
* In-memory implementation of the IDocumentModelRegistry interface.
|
|
2461
|
-
* Manages document model modules with version-aware storage and upgrade manifest support.
|
|
2462
|
-
*/
|
|
2463
|
-
var DocumentModelRegistry = class {
|
|
2464
|
-
modules = [];
|
|
2465
|
-
manifests = [];
|
|
2466
|
-
registerModules(...modules) {
|
|
2467
|
-
return modules.map((module) => {
|
|
2468
|
-
try {
|
|
2469
|
-
const documentType = module.documentModel.global.id;
|
|
2470
|
-
const version = module.version ?? 1;
|
|
2471
|
-
for (let i = 0; i < this.modules.length; i++) {
|
|
2472
|
-
const existing = this.modules[i];
|
|
2473
|
-
const existingType = existing.documentModel.global.id;
|
|
2474
|
-
const existingVersion = existing.version ?? 1;
|
|
2475
|
-
if (existingType === documentType && existingVersion === version) throw new DuplicateModuleError(documentType, version);
|
|
2476
|
-
}
|
|
2477
|
-
this.modules.push(module);
|
|
2478
|
-
return {
|
|
2479
|
-
status: "success",
|
|
2480
|
-
item: module
|
|
2481
|
-
};
|
|
2482
|
-
} catch (error) {
|
|
2483
|
-
return {
|
|
2484
|
-
status: "error",
|
|
2485
|
-
item: module,
|
|
2486
|
-
error: error instanceof Error ? error : new Error(String(error))
|
|
2487
|
-
};
|
|
2488
|
-
}
|
|
2489
|
-
});
|
|
2490
|
-
}
|
|
2491
|
-
unregisterModules(...documentTypes) {
|
|
2492
|
-
let allFound = true;
|
|
2493
|
-
for (const documentType of documentTypes) {
|
|
2494
|
-
if (!this.modules.some((m) => m.documentModel.global.id === documentType)) allFound = false;
|
|
2495
|
-
this.modules = this.modules.filter((m) => m.documentModel.global.id !== documentType);
|
|
2496
|
-
}
|
|
2497
|
-
return allFound;
|
|
2498
|
-
}
|
|
2499
|
-
getModule(documentType, version) {
|
|
2500
|
-
let latestModule;
|
|
2501
|
-
let latestVersion = -1;
|
|
2502
|
-
for (let i = 0; i < this.modules.length; i++) {
|
|
2503
|
-
const module = this.modules[i];
|
|
2504
|
-
const moduleType = module.documentModel.global.id;
|
|
2505
|
-
const moduleVersion = module.version ?? 1;
|
|
2506
|
-
if (moduleType === documentType) {
|
|
2507
|
-
if (version !== void 0 && moduleVersion === version) return module;
|
|
2508
|
-
if (moduleVersion > latestVersion) {
|
|
2509
|
-
latestModule = module;
|
|
2510
|
-
latestVersion = moduleVersion;
|
|
2511
|
-
}
|
|
2512
|
-
}
|
|
2513
|
-
}
|
|
2514
|
-
if (version === void 0 && latestModule !== void 0) return latestModule;
|
|
2515
|
-
throw new ModuleNotFoundError(documentType, version);
|
|
2516
|
-
}
|
|
2517
|
-
getAllModules() {
|
|
2518
|
-
return [...this.modules];
|
|
2519
|
-
}
|
|
2520
|
-
clear() {
|
|
2521
|
-
this.modules = [];
|
|
2522
|
-
this.manifests = [];
|
|
2523
|
-
}
|
|
2524
|
-
getSupportedVersions(documentType) {
|
|
2525
|
-
const versions = [];
|
|
2526
|
-
for (const module of this.modules) if (module.documentModel.global.id === documentType) versions.push(module.version ?? 1);
|
|
2527
|
-
if (versions.length === 0) throw new ModuleNotFoundError(documentType);
|
|
2528
|
-
return versions.sort((a, b) => a - b);
|
|
2529
|
-
}
|
|
2530
|
-
getLatestVersion(documentType) {
|
|
2531
|
-
let latest = -1;
|
|
2532
|
-
let found = false;
|
|
2533
|
-
for (const module of this.modules) if (module.documentModel.global.id === documentType) {
|
|
2534
|
-
found = true;
|
|
2535
|
-
const version = module.version ?? 1;
|
|
2536
|
-
if (version > latest) latest = version;
|
|
2537
|
-
}
|
|
2538
|
-
if (!found) throw new ModuleNotFoundError(documentType);
|
|
2539
|
-
return latest;
|
|
2540
|
-
}
|
|
2541
|
-
registerUpgradeManifests(...manifestsToRegister) {
|
|
2542
|
-
return manifestsToRegister.map((manifestToRegister) => {
|
|
2543
|
-
try {
|
|
2544
|
-
if (!manifestToRegister.documentType) throw new Error("Upgrade manifest is missing a documentType");
|
|
2545
|
-
for (const registeredManifest of this.manifests) if (registeredManifest.documentType === manifestToRegister.documentType) throw new DuplicateManifestError(manifestToRegister.documentType);
|
|
2546
|
-
this.manifests.push(manifestToRegister);
|
|
2547
|
-
return {
|
|
2548
|
-
status: "success",
|
|
2549
|
-
item: manifestToRegister
|
|
2550
|
-
};
|
|
2551
|
-
} catch (error) {
|
|
2552
|
-
return {
|
|
2553
|
-
status: "error",
|
|
2554
|
-
item: manifestToRegister,
|
|
2555
|
-
error: error instanceof Error ? error : new Error(String(error))
|
|
2556
|
-
};
|
|
2557
|
-
}
|
|
2558
|
-
});
|
|
2559
|
-
}
|
|
2560
|
-
unregisterUpgradeManifests(...documentTypes) {
|
|
2561
|
-
let allFound = true;
|
|
2562
|
-
for (const documentType of documentTypes) {
|
|
2563
|
-
if (!this.manifests.some((m) => m.documentType === documentType)) allFound = false;
|
|
2564
|
-
this.manifests = this.manifests.filter((m) => m.documentType !== documentType);
|
|
2565
|
-
}
|
|
2566
|
-
return allFound;
|
|
2567
|
-
}
|
|
2568
|
-
getUpgradeManifest(documentType) {
|
|
2569
|
-
for (let i = 0; i < this.manifests.length; i++) if (this.manifests[i].documentType === documentType) return this.manifests[i];
|
|
2570
|
-
throw new ManifestNotFoundError(documentType);
|
|
2571
|
-
}
|
|
2572
|
-
computeUpgradePath(documentType, fromVersion, toVersion) {
|
|
2573
|
-
if (fromVersion === toVersion) return [];
|
|
2574
|
-
if (toVersion < fromVersion) throw new DowngradeNotSupportedError(documentType, fromVersion, toVersion);
|
|
2575
|
-
const manifest = this.getUpgradeManifest(documentType);
|
|
2576
|
-
const path = [];
|
|
2577
|
-
for (let v = fromVersion + 1; v <= toVersion; v++) {
|
|
2578
|
-
const key = `v${v}`;
|
|
2579
|
-
if (!(key in manifest.upgrades)) throw new MissingUpgradeTransitionError(documentType, v - 1, v);
|
|
2580
|
-
const transition = manifest.upgrades[key];
|
|
2581
|
-
path.push(transition);
|
|
2582
|
-
}
|
|
2583
|
-
return path;
|
|
2584
|
-
}
|
|
2585
|
-
getUpgradeReducer(documentType, fromVersion, toVersion) {
|
|
2586
|
-
if (toVersion !== fromVersion + 1) throw new InvalidUpgradeStepError(documentType, fromVersion, toVersion);
|
|
2587
|
-
const manifest = this.getUpgradeManifest(documentType);
|
|
2588
|
-
const key = `v${toVersion}`;
|
|
2589
|
-
if (!(key in manifest.upgrades)) throw new MissingUpgradeTransitionError(documentType, fromVersion, toVersion);
|
|
2590
|
-
return manifest.upgrades[key].upgradeReducer;
|
|
2591
|
-
}
|
|
2592
|
-
};
|
|
2593
2471
|
//#endregion
|
|
2594
2472
|
//#region src/executor/simple-job-executor-manager.ts
|
|
2595
2473
|
/**
|
|
@@ -2854,6 +2732,10 @@ function yieldToMain() {
|
|
|
2854
2732
|
if (s?.yield) return s.yield();
|
|
2855
2733
|
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
2856
2734
|
}
|
|
2735
|
+
const defaultAbortError = () => /* @__PURE__ */ new Error("Operation aborted");
|
|
2736
|
+
function throwIfAborted(signal, makeError = defaultAbortError) {
|
|
2737
|
+
if (signal?.aborted) throw makeError();
|
|
2738
|
+
}
|
|
2857
2739
|
//#endregion
|
|
2858
2740
|
//#region src/utils/reshuffle.ts
|
|
2859
2741
|
const STRICT_ORDER_ACTION_TYPES = new Set([
|
|
@@ -4995,6 +4877,142 @@ var NullDocumentModelResolver = class {
|
|
|
4995
4877
|
}
|
|
4996
4878
|
};
|
|
4997
4879
|
//#endregion
|
|
4880
|
+
//#region src/registry/implementation.ts
|
|
4881
|
+
/**
|
|
4882
|
+
* In-memory implementation of the IDocumentModelRegistry interface.
|
|
4883
|
+
* Manages document model modules with version-aware storage and upgrade manifest support.
|
|
4884
|
+
*/
|
|
4885
|
+
var DocumentModelRegistry = class {
|
|
4886
|
+
modules = [];
|
|
4887
|
+
manifests = [];
|
|
4888
|
+
registerModules(...modules) {
|
|
4889
|
+
return modules.map((module) => {
|
|
4890
|
+
try {
|
|
4891
|
+
const documentType = module.documentModel.global.id;
|
|
4892
|
+
const version = module.version ?? 1;
|
|
4893
|
+
for (let i = 0; i < this.modules.length; i++) {
|
|
4894
|
+
const existing = this.modules[i];
|
|
4895
|
+
const existingType = existing.documentModel.global.id;
|
|
4896
|
+
const existingVersion = existing.version ?? 1;
|
|
4897
|
+
if (existingType === documentType && existingVersion === version) throw new DuplicateModuleError(documentType, version);
|
|
4898
|
+
}
|
|
4899
|
+
this.modules.push(module);
|
|
4900
|
+
return {
|
|
4901
|
+
status: "success",
|
|
4902
|
+
item: module
|
|
4903
|
+
};
|
|
4904
|
+
} catch (error) {
|
|
4905
|
+
return {
|
|
4906
|
+
status: "error",
|
|
4907
|
+
item: module,
|
|
4908
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
4909
|
+
};
|
|
4910
|
+
}
|
|
4911
|
+
});
|
|
4912
|
+
}
|
|
4913
|
+
unregisterModules(...documentTypes) {
|
|
4914
|
+
let allFound = true;
|
|
4915
|
+
for (const documentType of documentTypes) {
|
|
4916
|
+
if (!this.modules.some((m) => m.documentModel.global.id === documentType)) allFound = false;
|
|
4917
|
+
this.modules = this.modules.filter((m) => m.documentModel.global.id !== documentType);
|
|
4918
|
+
}
|
|
4919
|
+
return allFound;
|
|
4920
|
+
}
|
|
4921
|
+
getModule(documentType, version) {
|
|
4922
|
+
let latestModule;
|
|
4923
|
+
let latestVersion = -1;
|
|
4924
|
+
for (let i = 0; i < this.modules.length; i++) {
|
|
4925
|
+
const module = this.modules[i];
|
|
4926
|
+
const moduleType = module.documentModel.global.id;
|
|
4927
|
+
const moduleVersion = module.version ?? 1;
|
|
4928
|
+
if (moduleType === documentType) {
|
|
4929
|
+
if (version !== void 0 && moduleVersion === version) return module;
|
|
4930
|
+
if (moduleVersion > latestVersion) {
|
|
4931
|
+
latestModule = module;
|
|
4932
|
+
latestVersion = moduleVersion;
|
|
4933
|
+
}
|
|
4934
|
+
}
|
|
4935
|
+
}
|
|
4936
|
+
if (version === void 0 && latestModule !== void 0) return latestModule;
|
|
4937
|
+
throw new ModuleNotFoundError(documentType, version);
|
|
4938
|
+
}
|
|
4939
|
+
getAllModules() {
|
|
4940
|
+
return [...this.modules];
|
|
4941
|
+
}
|
|
4942
|
+
clear() {
|
|
4943
|
+
this.modules = [];
|
|
4944
|
+
this.manifests = [];
|
|
4945
|
+
}
|
|
4946
|
+
getSupportedVersions(documentType) {
|
|
4947
|
+
const versions = [];
|
|
4948
|
+
for (const module of this.modules) if (module.documentModel.global.id === documentType) versions.push(module.version ?? 1);
|
|
4949
|
+
if (versions.length === 0) throw new ModuleNotFoundError(documentType);
|
|
4950
|
+
return versions.sort((a, b) => a - b);
|
|
4951
|
+
}
|
|
4952
|
+
getLatestVersion(documentType) {
|
|
4953
|
+
let latest = -1;
|
|
4954
|
+
let found = false;
|
|
4955
|
+
for (const module of this.modules) if (module.documentModel.global.id === documentType) {
|
|
4956
|
+
found = true;
|
|
4957
|
+
const version = module.version ?? 1;
|
|
4958
|
+
if (version > latest) latest = version;
|
|
4959
|
+
}
|
|
4960
|
+
if (!found) throw new ModuleNotFoundError(documentType);
|
|
4961
|
+
return latest;
|
|
4962
|
+
}
|
|
4963
|
+
registerUpgradeManifests(...manifestsToRegister) {
|
|
4964
|
+
return manifestsToRegister.map((manifestToRegister) => {
|
|
4965
|
+
try {
|
|
4966
|
+
if (!manifestToRegister.documentType) throw new Error("Upgrade manifest is missing a documentType");
|
|
4967
|
+
for (const registeredManifest of this.manifests) if (registeredManifest.documentType === manifestToRegister.documentType) throw new DuplicateManifestError(manifestToRegister.documentType);
|
|
4968
|
+
this.manifests.push(manifestToRegister);
|
|
4969
|
+
return {
|
|
4970
|
+
status: "success",
|
|
4971
|
+
item: manifestToRegister
|
|
4972
|
+
};
|
|
4973
|
+
} catch (error) {
|
|
4974
|
+
return {
|
|
4975
|
+
status: "error",
|
|
4976
|
+
item: manifestToRegister,
|
|
4977
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
4978
|
+
};
|
|
4979
|
+
}
|
|
4980
|
+
});
|
|
4981
|
+
}
|
|
4982
|
+
unregisterUpgradeManifests(...documentTypes) {
|
|
4983
|
+
let allFound = true;
|
|
4984
|
+
for (const documentType of documentTypes) {
|
|
4985
|
+
if (!this.manifests.some((m) => m.documentType === documentType)) allFound = false;
|
|
4986
|
+
this.manifests = this.manifests.filter((m) => m.documentType !== documentType);
|
|
4987
|
+
}
|
|
4988
|
+
return allFound;
|
|
4989
|
+
}
|
|
4990
|
+
getUpgradeManifest(documentType) {
|
|
4991
|
+
for (let i = 0; i < this.manifests.length; i++) if (this.manifests[i].documentType === documentType) return this.manifests[i];
|
|
4992
|
+
throw new ManifestNotFoundError(documentType);
|
|
4993
|
+
}
|
|
4994
|
+
computeUpgradePath(documentType, fromVersion, toVersion) {
|
|
4995
|
+
if (fromVersion === toVersion) return [];
|
|
4996
|
+
if (toVersion < fromVersion) throw new DowngradeNotSupportedError(documentType, fromVersion, toVersion);
|
|
4997
|
+
const manifest = this.getUpgradeManifest(documentType);
|
|
4998
|
+
const path = [];
|
|
4999
|
+
for (let v = fromVersion + 1; v <= toVersion; v++) {
|
|
5000
|
+
const key = `v${v}`;
|
|
5001
|
+
if (!(key in manifest.upgrades)) throw new MissingUpgradeTransitionError(documentType, v - 1, v);
|
|
5002
|
+
const transition = manifest.upgrades[key];
|
|
5003
|
+
path.push(transition);
|
|
5004
|
+
}
|
|
5005
|
+
return path;
|
|
5006
|
+
}
|
|
5007
|
+
getUpgradeReducer(documentType, fromVersion, toVersion) {
|
|
5008
|
+
if (toVersion !== fromVersion + 1) throw new InvalidUpgradeStepError(documentType, fromVersion, toVersion);
|
|
5009
|
+
const manifest = this.getUpgradeManifest(documentType);
|
|
5010
|
+
const key = `v${toVersion}`;
|
|
5011
|
+
if (!(key in manifest.upgrades)) throw new MissingUpgradeTransitionError(documentType, fromVersion, toVersion);
|
|
5012
|
+
return manifest.upgrades[key].upgradeReducer;
|
|
5013
|
+
}
|
|
5014
|
+
};
|
|
5015
|
+
//#endregion
|
|
4998
5016
|
//#region src/shared/consistency-tracker.ts
|
|
4999
5017
|
/**
|
|
5000
5018
|
* Creates a consistency key from documentId, scope, and branch.
|
|
@@ -5403,6 +5421,29 @@ var KyselyKeyframeStore = class KyselyKeyframeStore {
|
|
|
5403
5421
|
}
|
|
5404
5422
|
};
|
|
5405
5423
|
//#endregion
|
|
5424
|
+
//#region src/storage/kysely/pagination.ts
|
|
5425
|
+
const DEFAULT_LIMIT = 100;
|
|
5426
|
+
function paginateRows(rows, paging, cursorOf, toItem, refetch) {
|
|
5427
|
+
let hasMore = false;
|
|
5428
|
+
let items = rows;
|
|
5429
|
+
if (paging?.limit && rows.length > paging.limit) {
|
|
5430
|
+
hasMore = true;
|
|
5431
|
+
items = rows.slice(0, paging.limit);
|
|
5432
|
+
}
|
|
5433
|
+
const nextCursor = hasMore && items.length > 0 ? cursorOf(items[items.length - 1]).toString() : void 0;
|
|
5434
|
+
const cursor = paging?.cursor || "0";
|
|
5435
|
+
const limit = paging?.limit || DEFAULT_LIMIT;
|
|
5436
|
+
return {
|
|
5437
|
+
results: items.map(toItem),
|
|
5438
|
+
options: {
|
|
5439
|
+
cursor,
|
|
5440
|
+
limit
|
|
5441
|
+
},
|
|
5442
|
+
nextCursor,
|
|
5443
|
+
next: hasMore ? () => refetch(nextCursor, limit) : void 0
|
|
5444
|
+
};
|
|
5445
|
+
}
|
|
5446
|
+
//#endregion
|
|
5406
5447
|
//#region src/storage/interfaces.ts
|
|
5407
5448
|
/**
|
|
5408
5449
|
* Thrown when an operation with the same identity already exists in the store.
|
|
@@ -5486,7 +5527,7 @@ var KyselyOperationStore = class KyselyOperationStore {
|
|
|
5486
5527
|
});
|
|
5487
5528
|
}
|
|
5488
5529
|
async executeApply(trx, documentId, documentType, scope, branch, revision, fn, signal) {
|
|
5489
|
-
|
|
5530
|
+
throwIfAborted(signal);
|
|
5490
5531
|
const latestOp = await trx.selectFrom("Operation").selectAll().where("documentId", "=", documentId).where("scope", "=", scope).where("branch", "=", branch).orderBy("index", "desc").limit(1).executeTakeFirst();
|
|
5491
5532
|
const currentRevision = latestOp ? latestOp.index : -1;
|
|
5492
5533
|
if (currentRevision !== revision - 1) throw new RevisionMismatchError(currentRevision + 1, revision);
|
|
@@ -5514,7 +5555,7 @@ var KyselyOperationStore = class KyselyOperationStore {
|
|
|
5514
5555
|
}
|
|
5515
5556
|
}
|
|
5516
5557
|
async getSince(documentId, scope, branch, revision, filter, paging, signal) {
|
|
5517
|
-
|
|
5558
|
+
throwIfAborted(signal);
|
|
5518
5559
|
let query = this.queryExecutor.selectFrom("Operation").selectAll().where("documentId", "=", documentId).where("scope", "=", scope).where("branch", "=", branch).where("index", ">", revision).orderBy("index", "asc");
|
|
5519
5560
|
if (filter) {
|
|
5520
5561
|
if (filter.actionTypes && filter.actionTypes.length > 0) {
|
|
@@ -5530,93 +5571,39 @@ var KyselyOperationStore = class KyselyOperationStore {
|
|
|
5530
5571
|
if (cursorValue > 0) query = query.where("index", ">", cursorValue);
|
|
5531
5572
|
if (paging.limit) query = query.limit(paging.limit + 1);
|
|
5532
5573
|
}
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
hasMore = true;
|
|
5538
|
-
items = rows.slice(0, paging.limit);
|
|
5539
|
-
}
|
|
5540
|
-
const nextCursor = hasMore && items.length > 0 ? items[items.length - 1].index.toString() : void 0;
|
|
5541
|
-
const cursor = paging?.cursor || "0";
|
|
5542
|
-
const limit = paging?.limit || 100;
|
|
5543
|
-
return {
|
|
5544
|
-
results: items.map((row) => this.rowToOperation(row)),
|
|
5545
|
-
options: {
|
|
5546
|
-
cursor,
|
|
5547
|
-
limit
|
|
5548
|
-
},
|
|
5549
|
-
nextCursor,
|
|
5550
|
-
next: hasMore ? () => this.getSince(documentId, scope, branch, revision, filter, {
|
|
5551
|
-
cursor: nextCursor,
|
|
5552
|
-
limit
|
|
5553
|
-
}, signal) : void 0
|
|
5554
|
-
};
|
|
5574
|
+
return paginateRows(await query.execute(), paging, (row) => row.index, (row) => this.rowToOperation(row), (cursor, limit) => this.getSince(documentId, scope, branch, revision, filter, {
|
|
5575
|
+
cursor,
|
|
5576
|
+
limit
|
|
5577
|
+
}, signal));
|
|
5555
5578
|
}
|
|
5556
5579
|
async getSinceId(id, paging, signal) {
|
|
5557
|
-
|
|
5580
|
+
throwIfAborted(signal);
|
|
5558
5581
|
let query = this.queryExecutor.selectFrom("Operation").selectAll().where("id", ">", id).orderBy("id", "asc");
|
|
5559
5582
|
if (paging) {
|
|
5560
5583
|
const cursorValue = Number.parseInt(paging.cursor, 10);
|
|
5561
5584
|
if (cursorValue > 0) query = query.where("id", ">", cursorValue);
|
|
5562
5585
|
if (paging.limit) query = query.limit(paging.limit + 1);
|
|
5563
5586
|
}
|
|
5564
|
-
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
hasMore = true;
|
|
5569
|
-
items = rows.slice(0, paging.limit);
|
|
5570
|
-
}
|
|
5571
|
-
const nextCursor = hasMore && items.length > 0 ? items[items.length - 1].id.toString() : void 0;
|
|
5572
|
-
const cursor = paging?.cursor || "0";
|
|
5573
|
-
const limit = paging?.limit || 100;
|
|
5574
|
-
return {
|
|
5575
|
-
results: items.map((row) => this.rowToOperationWithContext(row)),
|
|
5576
|
-
options: {
|
|
5577
|
-
cursor,
|
|
5578
|
-
limit
|
|
5579
|
-
},
|
|
5580
|
-
nextCursor,
|
|
5581
|
-
next: hasMore ? () => this.getSinceId(id, {
|
|
5582
|
-
cursor: nextCursor,
|
|
5583
|
-
limit
|
|
5584
|
-
}, signal) : void 0
|
|
5585
|
-
};
|
|
5587
|
+
return paginateRows(await query.execute(), paging, (row) => row.id, (row) => this.rowToOperationWithContext(row), (cursor, limit) => this.getSinceId(id, {
|
|
5588
|
+
cursor,
|
|
5589
|
+
limit
|
|
5590
|
+
}, signal));
|
|
5586
5591
|
}
|
|
5587
5592
|
async getConflicting(documentId, scope, branch, minTimestamp, paging, signal) {
|
|
5588
|
-
|
|
5593
|
+
throwIfAborted(signal);
|
|
5589
5594
|
let query = this.queryExecutor.selectFrom("Operation").selectAll().where("documentId", "=", documentId).where("scope", "=", scope).where("branch", "=", branch).where("timestampUtcMs", ">=", new Date(minTimestamp)).orderBy("index", "asc");
|
|
5590
5595
|
if (paging) {
|
|
5591
5596
|
const cursorValue = Number.parseInt(paging.cursor, 10);
|
|
5592
5597
|
if (cursorValue > 0) query = query.where("index", ">", cursorValue);
|
|
5593
5598
|
if (paging.limit) query = query.limit(paging.limit + 1);
|
|
5594
5599
|
}
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
hasMore = true;
|
|
5600
|
-
items = rows.slice(0, paging.limit);
|
|
5601
|
-
}
|
|
5602
|
-
const nextCursor = hasMore && items.length > 0 ? items[items.length - 1].index.toString() : void 0;
|
|
5603
|
-
const cursor = paging?.cursor || "0";
|
|
5604
|
-
const limit = paging?.limit || 100;
|
|
5605
|
-
return {
|
|
5606
|
-
results: items.map((row) => this.rowToOperation(row)),
|
|
5607
|
-
options: {
|
|
5608
|
-
cursor,
|
|
5609
|
-
limit
|
|
5610
|
-
},
|
|
5611
|
-
nextCursor,
|
|
5612
|
-
next: hasMore ? () => this.getConflicting(documentId, scope, branch, minTimestamp, {
|
|
5613
|
-
cursor: nextCursor,
|
|
5614
|
-
limit
|
|
5615
|
-
}, signal) : void 0
|
|
5616
|
-
};
|
|
5600
|
+
return paginateRows(await query.execute(), paging, (row) => row.index, (row) => this.rowToOperation(row), (cursor, limit) => this.getConflicting(documentId, scope, branch, minTimestamp, {
|
|
5601
|
+
cursor,
|
|
5602
|
+
limit
|
|
5603
|
+
}, signal));
|
|
5617
5604
|
}
|
|
5618
5605
|
async getRevisions(documentId, branch, signal) {
|
|
5619
|
-
|
|
5606
|
+
throwIfAborted(signal);
|
|
5620
5607
|
const scopeRevisions = await this.queryExecutor.selectFrom("Operation as o1").select([
|
|
5621
5608
|
"o1.scope",
|
|
5622
5609
|
"o1.index",
|
|
@@ -6610,6 +6597,38 @@ function batchOperationsByDocument(operations) {
|
|
|
6610
6597
|
flushBatch();
|
|
6611
6598
|
return batches;
|
|
6612
6599
|
}
|
|
6600
|
+
/**
|
|
6601
|
+
* Splits a sorted page of operations into a safe-to-emit prefix and a
|
|
6602
|
+
* deferred tail containing the trailing run that shares the same
|
|
6603
|
+
* (documentId, branch, scope, timestampUtcMs) as the last operation.
|
|
6604
|
+
*
|
|
6605
|
+
* The page is assumed to be sorted by (documentId, scope, ordinal), so a
|
|
6606
|
+
* same-(docId, scope, ts) run is contiguous and lives at the end of any
|
|
6607
|
+
* page that contains its last member. Holding that tail back lets callers
|
|
6608
|
+
* prepend it to the next page so a single producer-side execute() call
|
|
6609
|
+
* never gets split across two outbound envelopes.
|
|
6610
|
+
*/
|
|
6611
|
+
function splitTrailingSameTimestampRun(operations) {
|
|
6612
|
+
if (operations.length === 0) return {
|
|
6613
|
+
emit: [],
|
|
6614
|
+
carry: []
|
|
6615
|
+
};
|
|
6616
|
+
const last = operations[operations.length - 1];
|
|
6617
|
+
const lastDocId = last.context.documentId;
|
|
6618
|
+
const lastBranch = last.context.branch;
|
|
6619
|
+
const lastScope = last.context.scope;
|
|
6620
|
+
const lastTs = last.operation.timestampUtcMs;
|
|
6621
|
+
let carryStart = operations.length;
|
|
6622
|
+
for (let i = operations.length - 1; i >= 0; i--) {
|
|
6623
|
+
const op = operations[i];
|
|
6624
|
+
if (op.context.documentId === lastDocId && op.context.branch === lastBranch && op.context.scope === lastScope && op.operation.timestampUtcMs === lastTs) carryStart = i;
|
|
6625
|
+
else break;
|
|
6626
|
+
}
|
|
6627
|
+
return {
|
|
6628
|
+
emit: operations.slice(0, carryStart),
|
|
6629
|
+
carry: operations.slice(carryStart)
|
|
6630
|
+
};
|
|
6631
|
+
}
|
|
6613
6632
|
function toOperationWithContext(entry) {
|
|
6614
6633
|
return {
|
|
6615
6634
|
operation: {
|
|
@@ -8744,8 +8763,8 @@ var SyncManager = class {
|
|
|
8744
8763
|
}
|
|
8745
8764
|
if (this.isShutdown) return;
|
|
8746
8765
|
for (const plan of jobs) {
|
|
8766
|
+
if (!(plan.key in result.jobs)) continue;
|
|
8747
8767
|
const info = result.jobs[plan.key];
|
|
8748
|
-
if (!info) continue;
|
|
8749
8768
|
this.recordPlanKeyMapping(plan.key, info.id);
|
|
8750
8769
|
const fifoKey = `${plan.documentId}:${plan.scope}:${plan.branch}`;
|
|
8751
8770
|
this.lastEnqueuedJobIdByKey.set(fifoKey, info.id);
|
|
@@ -8785,41 +8804,55 @@ var SyncManager = class {
|
|
|
8785
8804
|
const composedSignal = signal ? AbortSignal.any([signal, this.abortController.signal]) : this.abortController.signal;
|
|
8786
8805
|
let maxOrdinal = ackOrdinal;
|
|
8787
8806
|
const lastJobByDoc = /* @__PURE__ */ new Map();
|
|
8807
|
+
let prevChainJobId;
|
|
8788
8808
|
const sinceTimestamp = remote.options.sinceTimestampUtcMs;
|
|
8809
|
+
const emitBatches = (operations) => {
|
|
8810
|
+
if (operations.length === 0) return;
|
|
8811
|
+
const batches = batchOperationsByDocument(operations);
|
|
8812
|
+
const syncOps = [];
|
|
8813
|
+
for (const batch of batches) {
|
|
8814
|
+
const jobId = crypto.randomUUID();
|
|
8815
|
+
const prevJobId = lastJobByDoc.get(batch.documentId);
|
|
8816
|
+
const deps = [];
|
|
8817
|
+
if (prevJobId) deps.push(prevJobId);
|
|
8818
|
+
if (mode === OutboxMode.BatchTriggered && prevChainJobId && prevChainJobId !== prevJobId) deps.push(prevChainJobId);
|
|
8819
|
+
const syncOp = new SyncOperation(crypto.randomUUID(), jobId, deps, remote.name, batch.documentId, [batch.scope], batch.branch, batch.operations);
|
|
8820
|
+
syncOps.push(syncOp);
|
|
8821
|
+
lastJobByDoc.set(batch.documentId, jobId);
|
|
8822
|
+
if (mode === OutboxMode.BatchTriggered) prevChainJobId = jobId;
|
|
8823
|
+
}
|
|
8824
|
+
remote.channel.outbox.add(...syncOps);
|
|
8825
|
+
};
|
|
8789
8826
|
let page = await this.operationIndex.find(remote.collectionId, ackOrdinal, { excludeSourceRemote: remote.name }, void 0, composedSignal);
|
|
8827
|
+
let carry = [];
|
|
8790
8828
|
let hasMore;
|
|
8791
8829
|
do {
|
|
8792
8830
|
if (composedSignal.aborted) return;
|
|
8793
8831
|
for (const entry of page.results) maxOrdinal = Math.max(maxOrdinal, entry.ordinal ?? 0);
|
|
8794
8832
|
let operations = page.results.map((entry) => toOperationWithContext(entry));
|
|
8833
|
+
if (carry.length > 0) {
|
|
8834
|
+
operations = [...carry, ...operations];
|
|
8835
|
+
carry = [];
|
|
8836
|
+
}
|
|
8795
8837
|
if (sinceTimestamp && sinceTimestamp !== "0") operations = operations.filter((op) => op.operation.timestampUtcMs >= sinceTimestamp);
|
|
8796
8838
|
operations = filterOperations(operations, remote.filter);
|
|
8797
8839
|
operations = operations.filter((op) => !this.quarantinedDocumentIds.has(op.context.documentId));
|
|
8840
|
+
hasMore = !!page.next;
|
|
8798
8841
|
if (operations.length > 0) {
|
|
8799
8842
|
operations.sort((a, b) => {
|
|
8800
8843
|
if (a.context.documentId !== b.context.documentId) return a.context.documentId < b.context.documentId ? -1 : 1;
|
|
8801
8844
|
if (a.context.scope !== b.context.scope) return a.context.scope < b.context.scope ? -1 : 1;
|
|
8802
8845
|
return a.context.ordinal - b.context.ordinal;
|
|
8803
8846
|
});
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
|
|
8809
|
-
const prevJobId = lastJobByDoc.get(batch.documentId);
|
|
8810
|
-
const deps = [];
|
|
8811
|
-
if (prevJobId) deps.push(prevJobId);
|
|
8812
|
-
if (mode === OutboxMode.BatchTriggered && prevChainJobId && prevChainJobId !== prevJobId) deps.push(prevChainJobId);
|
|
8813
|
-
const syncOp = new SyncOperation(crypto.randomUUID(), jobId, deps, remote.name, batch.documentId, [batch.scope], batch.branch, batch.operations);
|
|
8814
|
-
syncOps.push(syncOp);
|
|
8815
|
-
lastJobByDoc.set(batch.documentId, jobId);
|
|
8816
|
-
if (mode === OutboxMode.BatchTriggered) prevChainJobId = jobId;
|
|
8817
|
-
}
|
|
8818
|
-
remote.channel.outbox.add(...syncOps);
|
|
8847
|
+
if (hasMore) {
|
|
8848
|
+
const split = splitTrailingSameTimestampRun(operations);
|
|
8849
|
+
carry = split.carry;
|
|
8850
|
+
emitBatches(split.emit);
|
|
8851
|
+
} else emitBatches(operations);
|
|
8819
8852
|
}
|
|
8820
|
-
hasMore = !!page.next;
|
|
8821
8853
|
if (hasMore) page = await page.next();
|
|
8822
8854
|
} while (hasMore);
|
|
8855
|
+
if (carry.length > 0) emitBatches(carry);
|
|
8823
8856
|
remote.channel.outbox.advanceOrdinal(maxOrdinal);
|
|
8824
8857
|
}
|
|
8825
8858
|
};
|
|
@@ -8976,7 +9009,7 @@ var Reactor = class {
|
|
|
8976
9009
|
}
|
|
8977
9010
|
getDocumentModels(namespace, paging, signal) {
|
|
8978
9011
|
this.logger.verbose("getDocumentModels(@namespace, @paging)", namespace, paging);
|
|
8979
|
-
|
|
9012
|
+
throwIfAborted(signal, () => new AbortError());
|
|
8980
9013
|
const filteredModels = this.documentModelRegistry.getAllModules().filter((module) => !namespace || module.documentModel.global.id.startsWith(namespace));
|
|
8981
9014
|
const startIndex = paging ? parseInt(paging.cursor) || 0 : 0;
|
|
8982
9015
|
const limit = paging?.limit || filteredModels.length;
|
|
@@ -9012,24 +9045,24 @@ var Reactor = class {
|
|
|
9012
9045
|
}
|
|
9013
9046
|
async getOutgoingRelationships(sourceId, relationshipType, consistencyToken, signal) {
|
|
9014
9047
|
const relationships = await this.documentIndexer.getOutgoing(sourceId, [relationshipType], void 0, consistencyToken, signal);
|
|
9015
|
-
|
|
9048
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9016
9049
|
return relationships.results.map((rel) => rel.targetId);
|
|
9017
9050
|
}
|
|
9018
9051
|
async getIncomingRelationships(targetId, relationshipType, consistencyToken, signal) {
|
|
9019
9052
|
const relationships = await this.documentIndexer.getIncoming(targetId, [relationshipType], void 0, consistencyToken, signal);
|
|
9020
|
-
|
|
9053
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9021
9054
|
return relationships.results.map((rel) => rel.sourceId);
|
|
9022
9055
|
}
|
|
9023
9056
|
async getOperations(documentId, view, filter, paging, consistencyToken, signal) {
|
|
9024
9057
|
this.logger.verbose("getOperations(@documentId, @view, @filter, @paging)", documentId, view, filter, paging);
|
|
9025
9058
|
const branch = view?.branch || "main";
|
|
9026
9059
|
const revisions = await this.operationStore.getRevisions(documentId, branch, signal);
|
|
9027
|
-
|
|
9060
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9028
9061
|
const allScopes = Object.keys(revisions.revision);
|
|
9029
9062
|
const result = {};
|
|
9030
9063
|
for (const scope of allScopes) {
|
|
9031
9064
|
if (!matchesScope(view, scope)) continue;
|
|
9032
|
-
|
|
9065
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9033
9066
|
const scopeResult = await this.operationStore.getSince(documentId, scope, branch, -1, filter, paging, signal);
|
|
9034
9067
|
result[scope] = {
|
|
9035
9068
|
results: scopeResult.results,
|
|
@@ -9060,13 +9093,13 @@ var Reactor = class {
|
|
|
9060
9093
|
if (search.type) results = filterByType(results, search.type);
|
|
9061
9094
|
} else if (search.type) results = await this.findByType(search.type, view, paging, consistencyToken, signal);
|
|
9062
9095
|
else throw new Error("No search criteria provided");
|
|
9063
|
-
|
|
9096
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9064
9097
|
return results;
|
|
9065
9098
|
}
|
|
9066
9099
|
async create(document, signer, signal, meta) {
|
|
9067
9100
|
this.logger.verbose("create(@id, @type, @slug)", document.header.id, document.header.documentType, document.header.slug);
|
|
9068
9101
|
const createdAtUtcIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
9069
|
-
|
|
9102
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9070
9103
|
let actions = [createDocumentAction({
|
|
9071
9104
|
model: document.header.documentType,
|
|
9072
9105
|
version: 0,
|
|
@@ -9126,7 +9159,7 @@ var Reactor = class {
|
|
|
9126
9159
|
async deleteDocument(id, signer, signal, meta) {
|
|
9127
9160
|
this.logger.verbose("deleteDocument(@id)", id);
|
|
9128
9161
|
const createdAtUtcIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
9129
|
-
|
|
9162
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9130
9163
|
let action = deleteDocumentAction(id);
|
|
9131
9164
|
if (signer) action = await signAction(action, signer, signal);
|
|
9132
9165
|
const jobId = v4();
|
|
@@ -9163,7 +9196,7 @@ var Reactor = class {
|
|
|
9163
9196
|
}
|
|
9164
9197
|
async execute(docId, branch, actions, signal, meta) {
|
|
9165
9198
|
this.logger.verbose("execute(@docId, @branch, @actions)", docId, branch, actions);
|
|
9166
|
-
|
|
9199
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9167
9200
|
const createdAtUtcIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
9168
9201
|
const scope = getSharedActionScope(actions);
|
|
9169
9202
|
const jobId = v4();
|
|
@@ -9196,12 +9229,12 @@ var Reactor = class {
|
|
|
9196
9229
|
this.jobTracker.registerJob(jobInfo);
|
|
9197
9230
|
this.emitJobPending(jobInfo.id, jobMeta);
|
|
9198
9231
|
await this.queue.enqueue(job);
|
|
9199
|
-
|
|
9232
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9200
9233
|
return jobInfo;
|
|
9201
9234
|
}
|
|
9202
9235
|
async load(docId, branch, operations, signal, meta) {
|
|
9203
9236
|
this.logger.verbose("load(@docId, @branch, @count, @operations)", docId, branch, operations.length, operations);
|
|
9204
|
-
|
|
9237
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9205
9238
|
if (operations.length === 0) throw new Error("load requires at least one operation");
|
|
9206
9239
|
const scope = getSharedOperationScope(operations);
|
|
9207
9240
|
const createdAtUtcIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -9235,12 +9268,12 @@ var Reactor = class {
|
|
|
9235
9268
|
this.jobTracker.registerJob(jobInfo);
|
|
9236
9269
|
this.emitJobPending(jobInfo.id, jobMeta);
|
|
9237
9270
|
await this.queue.enqueue(job);
|
|
9238
|
-
|
|
9271
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9239
9272
|
return jobInfo;
|
|
9240
9273
|
}
|
|
9241
9274
|
async executeBatch(request, signal, meta) {
|
|
9242
9275
|
this.logger.verbose("executeBatch(@count jobs)", request.jobs.length);
|
|
9243
|
-
|
|
9276
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9244
9277
|
validateBatchRequest(request.jobs);
|
|
9245
9278
|
for (const jobPlan of request.jobs) validateActionScopes(jobPlan);
|
|
9246
9279
|
const createdAtUtcIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -9274,7 +9307,7 @@ var Reactor = class {
|
|
|
9274
9307
|
const enqueuedKeys = [];
|
|
9275
9308
|
try {
|
|
9276
9309
|
for (const key of sortedKeys) {
|
|
9277
|
-
|
|
9310
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9278
9311
|
const jobPlan = request.jobs.find((j) => j.key === key);
|
|
9279
9312
|
const jobId = planKeyToJobId.get(key);
|
|
9280
9313
|
const queueHint = jobPlan.dependsOn.map((depKey) => planKeyToJobId.get(depKey));
|
|
@@ -9309,7 +9342,7 @@ var Reactor = class {
|
|
|
9309
9342
|
}
|
|
9310
9343
|
async loadBatch(request, signal, meta) {
|
|
9311
9344
|
this.logger.verbose("loadBatch(@count jobs)", request.jobs.length);
|
|
9312
|
-
|
|
9345
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9313
9346
|
validateBatchLoadRequest(request.jobs);
|
|
9314
9347
|
for (const jobPlan of request.jobs) validateOperationScopes(jobPlan);
|
|
9315
9348
|
const createdAtUtcIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -9343,7 +9376,7 @@ var Reactor = class {
|
|
|
9343
9376
|
const enqueuedKeys = [];
|
|
9344
9377
|
try {
|
|
9345
9378
|
for (const key of sortedKeys) {
|
|
9346
|
-
|
|
9379
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9347
9380
|
const jobPlan = request.jobs.find((j) => j.key === key);
|
|
9348
9381
|
const jobId = planKeyToJobId.get(key);
|
|
9349
9382
|
const queueHint = [...jobPlan.dependsOn.map((depKey) => planKeyToJobId.get(depKey)), ...jobPlan.externalDeps];
|
|
@@ -9378,21 +9411,21 @@ var Reactor = class {
|
|
|
9378
9411
|
}
|
|
9379
9412
|
async addRelationship(sourceId, targetId, relationshipType, branch = "main", signer, signal) {
|
|
9380
9413
|
this.logger.verbose("addRelationship(@sourceId, @targetId, @relationshipType, @branch)", sourceId, targetId, relationshipType, branch);
|
|
9381
|
-
|
|
9414
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9382
9415
|
let actions = [addRelationshipAction(sourceId, targetId, relationshipType)];
|
|
9383
9416
|
if (signer) actions = await signActions(actions, signer, signal);
|
|
9384
9417
|
return await this.execute(sourceId, branch, actions, signal);
|
|
9385
9418
|
}
|
|
9386
9419
|
async removeRelationship(sourceId, targetId, relationshipType, branch = "main", signer, signal) {
|
|
9387
9420
|
this.logger.verbose("removeRelationship(@sourceId, @targetId, @relationshipType, @branch)", sourceId, targetId, relationshipType, branch);
|
|
9388
|
-
|
|
9421
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9389
9422
|
let actions = [removeRelationshipAction(sourceId, targetId, relationshipType)];
|
|
9390
9423
|
if (signer) actions = await signActions(actions, signer, signal);
|
|
9391
9424
|
return await this.execute(sourceId, branch, actions, signal);
|
|
9392
9425
|
}
|
|
9393
9426
|
getJobStatus(jobId, signal) {
|
|
9394
9427
|
this.logger.verbose("getJobStatus(@jobId)", jobId);
|
|
9395
|
-
|
|
9428
|
+
throwIfAborted(signal, () => new AbortError());
|
|
9396
9429
|
const jobInfo = this.jobTracker.getJobStatus(jobId);
|
|
9397
9430
|
if (!jobInfo) {
|
|
9398
9431
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -9890,13 +9923,15 @@ const JobExecutorEventTypes = {
|
|
|
9890
9923
|
EXECUTOR_STOPPED: 20004
|
|
9891
9924
|
};
|
|
9892
9925
|
//#endregion
|
|
9893
|
-
//#region src/admin/
|
|
9894
|
-
const
|
|
9926
|
+
//#region src/admin/passthrough-keyframe-store.ts
|
|
9927
|
+
const passthroughKeyframeStore = {
|
|
9895
9928
|
putKeyframe: () => Promise.resolve(),
|
|
9896
9929
|
findNearestKeyframe: () => Promise.resolve(void 0),
|
|
9897
9930
|
listKeyframes: () => Promise.resolve([]),
|
|
9898
9931
|
deleteKeyframes: () => Promise.resolve(0)
|
|
9899
9932
|
};
|
|
9933
|
+
//#endregion
|
|
9934
|
+
//#region src/admin/document-integrity-service.ts
|
|
9900
9935
|
var DocumentIntegrityService = class {
|
|
9901
9936
|
keyframeStore;
|
|
9902
9937
|
operationStore;
|
|
@@ -9913,14 +9948,14 @@ var DocumentIntegrityService = class {
|
|
|
9913
9948
|
async validateDocument(documentId, branch = "main", signal) {
|
|
9914
9949
|
const keyframeIssues = [];
|
|
9915
9950
|
const snapshotIssues = [];
|
|
9916
|
-
const replayCache = new KyselyWriteCache(
|
|
9951
|
+
const replayCache = new KyselyWriteCache(passthroughKeyframeStore, this.operationStore, this.documentModelRegistry, {
|
|
9917
9952
|
maxDocuments: 1,
|
|
9918
9953
|
ringBufferSize: 1,
|
|
9919
9954
|
keyframeInterval: Number.MAX_SAFE_INTEGER
|
|
9920
9955
|
});
|
|
9921
9956
|
const keyframes = await this.keyframeStore.listKeyframes(documentId, void 0, branch, signal);
|
|
9922
9957
|
for (const keyframe of keyframes) {
|
|
9923
|
-
|
|
9958
|
+
throwIfAborted(signal);
|
|
9924
9959
|
replayCache.invalidate(documentId, keyframe.scope, branch);
|
|
9925
9960
|
const replayedDoc = await replayCache.getState(documentId, keyframe.scope, branch, keyframe.revision, signal);
|
|
9926
9961
|
const kfHash = hashDocumentStateForScope(keyframe.document, keyframe.scope);
|
|
@@ -9953,7 +9988,7 @@ var DocumentIntegrityService = class {
|
|
|
9953
9988
|
try {
|
|
9954
9989
|
replayedDoc = await replayCache.getState(documentId, scope, branch, void 0, signal);
|
|
9955
9990
|
} catch {
|
|
9956
|
-
|
|
9991
|
+
throwIfAborted(signal);
|
|
9957
9992
|
continue;
|
|
9958
9993
|
}
|
|
9959
9994
|
const snapshotHash = hashDocumentStateForScope(currentDoc, scope);
|
|
@@ -9982,7 +10017,7 @@ var DocumentIntegrityService = class {
|
|
|
9982
10017
|
async rebuildSnapshots(documentId, branch = "main", signal) {
|
|
9983
10018
|
const scopes = await this.discoverScopes(documentId, branch, signal);
|
|
9984
10019
|
for (const scope of scopes) {
|
|
9985
|
-
|
|
10020
|
+
throwIfAborted(signal);
|
|
9986
10021
|
this.writeCache.invalidate(documentId, scope, branch);
|
|
9987
10022
|
}
|
|
9988
10023
|
return {
|