@powerhousedao/reactor 6.2.2-dev.5 → 6.2.2-dev.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{build-worker-executor--nhFRF47.js → build-worker-executor-CkuJGUlJ.js} +2 -2
- package/dist/{build-worker-executor--nhFRF47.js.map → build-worker-executor-CkuJGUlJ.js.map} +1 -1
- package/dist/{document-indexer-FGJmRAdX.js → document-indexer-DlpJB8AK.js} +37 -22
- package/dist/document-indexer-DlpJB8AK.js.map +1 -0
- package/dist/{drive-container-types-DpJp2AmE.js → drive-container-types-BoY5t12r.js} +2057 -215
- package/dist/drive-container-types-BoY5t12r.js.map +1 -0
- package/dist/entry.js +3 -2
- package/dist/entry.js.map +1 -1
- package/dist/index.d.ts +2077 -1261
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +835 -100
- package/dist/index.js.map +1 -1
- package/dist/projection-entry.js +4 -4
- package/dist/projection-entry.js.map +1 -1
- package/dist/{worker-DBJOv8Gp.js → worker-BCMw-hBw.js} +2 -2
- package/dist/{worker-DBJOv8Gp.js.map → worker-BCMw-hBw.js.map} +1 -1
- package/dist/{worker-handle-B1w03nRA.js → worker-handle-CrERzl8s.js} +3 -2
- package/dist/worker-handle-CrERzl8s.js.map +1 -0
- package/package.json +5 -4
- package/dist/document-indexer-FGJmRAdX.js.map +0 -1
- package/dist/drive-container-types-DpJp2AmE.js.map +0 -1
- package/dist/worker-handle-B1w03nRA.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Action, CreateDocumentActionInput, DocumentModelModule, ISigner, Operation, OperationContext, OperationWithContext, OperationWithContext as OperationWithContext$1, PHDocument, PHDocumentState, SignatureVerificationHandler, UpgradeDocumentActionInput, UpgradeManifest, UpgradeReducer, UpgradeTransition, actions as documentActions } from "@powerhousedao/shared/document-model";
|
|
1
|
+
import { Action, AuthRequest, AuthSubject, CreateDocumentActionInput, DocumentModelModule, ISigner, Operation, OperationContext, OperationWithContext, OperationWithContext as OperationWithContext$1, PHAuthState, PHDocument, PHDocumentState, SignatureVerificationHandler, UpgradeDocumentActionInput, UpgradeManifest, UpgradeReducer, UpgradeTransition, actions as documentActions } from "@powerhousedao/shared/document-model";
|
|
2
2
|
import { DocumentDriveDocument, DriveInput, FolderNode, Node } from "@powerhousedao/shared/document-drive";
|
|
3
3
|
import { ILogger } from "document-model";
|
|
4
4
|
import * as kysely from "kysely";
|
|
@@ -57,7 +57,14 @@ declare function updateRelationshipAction(sourceId: string, targetId: string, re
|
|
|
57
57
|
declare function removeRelationshipAction(sourceId: string, targetId: string, relationshipType?: string): Action;
|
|
58
58
|
//#endregion
|
|
59
59
|
//#region src/queue/types.d.ts
|
|
60
|
-
|
|
60
|
+
/**
|
|
61
|
+
* What a job carries: a mutation applies actions, a load imports synced
|
|
62
|
+
* operations, and a reevaluation re-judges a document's stored operations
|
|
63
|
+
* because a read-set stream elsewhere (a group document) changed. A
|
|
64
|
+
* reevaluation job carries no actions or operations; its work is derived
|
|
65
|
+
* from what is already stored.
|
|
66
|
+
*/
|
|
67
|
+
type JobKind = "mutation" | "load" | "reevaluation";
|
|
61
68
|
/**
|
|
62
69
|
* State of a job in the queue
|
|
63
70
|
*/
|
|
@@ -69,6 +76,17 @@ declare enum JobQueueState {
|
|
|
69
76
|
RUNNING = 3,
|
|
70
77
|
RESOLVED = 4
|
|
71
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* How a retry is accounted against the job's retry limit.
|
|
81
|
+
* - `CountAgainstLimit` (default): a fault; the job eventually exhausts its
|
|
82
|
+
* retries and fails terminally.
|
|
83
|
+
* - `ExemptFromLimit`: not a fault, so the attempt is not charged to the job.
|
|
84
|
+
* Used for concurrency conflicts, where the retry does new work.
|
|
85
|
+
*/
|
|
86
|
+
declare enum RetryAccounting {
|
|
87
|
+
CountAgainstLimit = "count-against-limit",
|
|
88
|
+
ExemptFromLimit = "exempt-from-limit"
|
|
89
|
+
}
|
|
72
90
|
/**
|
|
73
91
|
* Interface for a job execution handle
|
|
74
92
|
*/
|
|
@@ -127,9 +145,14 @@ type JobAvailableEvent = {
|
|
|
127
145
|
//#endregion
|
|
128
146
|
//#region src/shared/types.d.ts
|
|
129
147
|
/**
|
|
130
|
-
* Information about an error including message and stack trace.
|
|
148
|
+
* Information about an error including its name, message and stack trace.
|
|
149
|
+
*
|
|
150
|
+
* The name is what survives the crossing out of the executor: a consumer that
|
|
151
|
+
* has to tell a terminal failure from a retryable one, or classify a dead
|
|
152
|
+
* letter, only ever sees this record rather than the thrown error.
|
|
131
153
|
*/
|
|
132
154
|
type ErrorInfo$1 = {
|
|
155
|
+
name: string;
|
|
133
156
|
message: string;
|
|
134
157
|
stack: string;
|
|
135
158
|
};
|
|
@@ -230,6 +253,11 @@ type ViewFilter = {
|
|
|
230
253
|
branch?: string;
|
|
231
254
|
scopes?: string[];
|
|
232
255
|
revision?: number;
|
|
256
|
+
/**
|
|
257
|
+
* Read subject for the IReactorClient read gate; defaults to the client's
|
|
258
|
+
* signer. Set per request when serving many principals. Ignored by IReactor.
|
|
259
|
+
*/
|
|
260
|
+
subject?: AuthSubject;
|
|
233
261
|
};
|
|
234
262
|
/**
|
|
235
263
|
* Describes filter options for searching documents.
|
|
@@ -328,6 +356,16 @@ interface IReadModelCoordinator {
|
|
|
328
356
|
*/
|
|
329
357
|
getChainDepth(): number;
|
|
330
358
|
}
|
|
359
|
+
type ReadModelRegistrationStage = "pre_ready" | "post_ready";
|
|
360
|
+
/**
|
|
361
|
+
* Optional capability exposed by coordinators that support adding read models
|
|
362
|
+
* after construction. Custom and remote coordinators are not required to
|
|
363
|
+
* implement it.
|
|
364
|
+
*/
|
|
365
|
+
interface ILiveReadModelCoordinator extends IReadModelCoordinator {
|
|
366
|
+
addReadModel(readModel: IReadModel, stage: ReadModelRegistrationStage): void;
|
|
367
|
+
}
|
|
368
|
+
declare function supportsLiveReadModelRegistration(coordinator: IReadModelCoordinator): coordinator is ILiveReadModelCoordinator;
|
|
331
369
|
//#endregion
|
|
332
370
|
//#region src/sync/types.d.ts
|
|
333
371
|
declare enum ChannelScheme {
|
|
@@ -398,7 +436,13 @@ declare enum ChannelErrorSource {
|
|
|
398
436
|
Inbox = "inbox",
|
|
399
437
|
Outbox = "outbox"
|
|
400
438
|
}
|
|
401
|
-
type SyncOperationErrorType = "SIGNATURE_INVALID" | "HASH_MISMATCH" | "LIBRARY_ERROR" | "MISSING_OPERATIONS" | "EXCESSIVE_SHUFFLE" | "GRACEFUL_ABORT"
|
|
439
|
+
type SyncOperationErrorType = "SIGNATURE_INVALID" | "HASH_MISMATCH" | "LIBRARY_ERROR" | "MISSING_OPERATIONS" | "EXCESSIVE_SHUFFLE" | "GRACEFUL_ABORT"
|
|
440
|
+
/**
|
|
441
|
+
* An arriving auth operation did not exceed the local auth head. Exempt from
|
|
442
|
+
* quarantine, because reconciling the two policies needs the traffic a
|
|
443
|
+
* quarantine would stop.
|
|
444
|
+
*/
|
|
445
|
+
| "AUTH_TIMESTAMP_NOT_MONOTONIC" /** An arriving operation carried a timestamp that is not an ISO-8601 instant. */ | "INVALID_TIMESTAMP" /** No classification applies, including rows written before the field. */ | "UNCLASSIFIED";
|
|
402
446
|
type ChannelHealth = {
|
|
403
447
|
state: "idle" | "running" | "error";
|
|
404
448
|
lastSuccessUtcMs?: number;
|
|
@@ -491,6 +535,7 @@ type DeadLetterAddedEvent = {
|
|
|
491
535
|
remoteName: string;
|
|
492
536
|
documentId: string;
|
|
493
537
|
errorSource: ChannelErrorSource;
|
|
538
|
+
errorType: SyncOperationErrorType;
|
|
494
539
|
};
|
|
495
540
|
/**
|
|
496
541
|
* Status of a sync operation result.
|
|
@@ -537,6 +582,36 @@ declare class OptimisticLockError extends Error {
|
|
|
537
582
|
declare class RevisionMismatchError extends Error {
|
|
538
583
|
constructor(expected: number, actual: number);
|
|
539
584
|
}
|
|
585
|
+
/**
|
|
586
|
+
* One read-set stream and the highest operation index observed on it, or -1
|
|
587
|
+
* if it was observed empty.
|
|
588
|
+
*/
|
|
589
|
+
type AppendConditionStream = {
|
|
590
|
+
documentId: string;
|
|
591
|
+
scope: string;
|
|
592
|
+
branch: string;
|
|
593
|
+
revision: number;
|
|
594
|
+
};
|
|
595
|
+
/**
|
|
596
|
+
* A read-set enforced by {@link IOperationStore.apply}: the append fails if
|
|
597
|
+
* any stream has operations past its recorded revision.
|
|
598
|
+
*/
|
|
599
|
+
type AppendCondition = {
|
|
600
|
+
streams: AppendConditionStream[];
|
|
601
|
+
};
|
|
602
|
+
/** Error history keeps messages, not classes, so failures match by prefix. */
|
|
603
|
+
declare const APPEND_CONDITION_FAILED_PREFIX = "Append condition failed: ";
|
|
604
|
+
/**
|
|
605
|
+
* A read-set stream grew before the append committed. A concurrency
|
|
606
|
+
* conflict, not a fault: the caller retries against the new stream heads.
|
|
607
|
+
*/
|
|
608
|
+
declare class AppendConditionFailedError extends Error {
|
|
609
|
+
readonly condition: AppendCondition;
|
|
610
|
+
constructor(condition: AppendCondition);
|
|
611
|
+
static isError(error: unknown): error is AppendConditionFailedError;
|
|
612
|
+
/** True when a recorded error message is an append-condition failure. */
|
|
613
|
+
static isFailureMessage(message: string): boolean;
|
|
614
|
+
}
|
|
540
615
|
/**
|
|
541
616
|
* A write transaction passed to {@link IOperationStore.apply}. Accumulates
|
|
542
617
|
* operations that are committed atomically when the callback returns.
|
|
@@ -550,7 +625,7 @@ interface AtomicTxn {
|
|
|
550
625
|
* revision field and lastModified timestamp.
|
|
551
626
|
*/
|
|
552
627
|
type DocumentRevisions = {
|
|
553
|
-
/** Map of scope to operation index for that scope */revision: Record<string, number>; /**
|
|
628
|
+
/** Map of scope to operation index for that scope */revision: Record<string, number>; /** The largest operation timestamp in the document, across every scope. */
|
|
554
629
|
latestTimestamp: string;
|
|
555
630
|
};
|
|
556
631
|
/**
|
|
@@ -571,6 +646,12 @@ interface IOperationStore {
|
|
|
571
646
|
* returned instead of throwing. If no matching stored row is found, the
|
|
572
647
|
* original error is propagated unchanged.
|
|
573
648
|
*
|
|
649
|
+
* With an {@link AppendCondition}, the append additionally fails with
|
|
650
|
+
* {@link AppendConditionFailedError} — writing nothing — if any read-set
|
|
651
|
+
* stream has operations past its recorded revision. The written and
|
|
652
|
+
* read-set streams are advisory-locked in sorted key order, so concurrent
|
|
653
|
+
* conditional appends on overlapping streams serialize.
|
|
654
|
+
*
|
|
574
655
|
* @param documentId - The document id
|
|
575
656
|
* @param documentType - The document type identifier
|
|
576
657
|
* @param scope - The operation scope (e.g. "global", "local")
|
|
@@ -578,9 +659,10 @@ interface IOperationStore {
|
|
|
578
659
|
* @param revision - Expected current revision (optimistic lock)
|
|
579
660
|
* @param fn - Callback that stages operations via {@link AtomicTxn}
|
|
580
661
|
* @param signal - Optional abort signal to cancel the request
|
|
662
|
+
* @param condition - Optional read-set to enforce at write time
|
|
581
663
|
* @returns The stored operations; empty array when no operations were staged
|
|
582
664
|
*/
|
|
583
|
-
apply(documentId: string, documentType: string, scope: string, branch: string, revision: number, fn: (txn: AtomicTxn) => void | Promise<void>, signal?: AbortSignal): Promise<Operation[]>;
|
|
665
|
+
apply(documentId: string, documentType: string, scope: string, branch: string, revision: number, fn: (txn: AtomicTxn) => void | Promise<void>, signal?: AbortSignal, condition?: AppendCondition): Promise<Operation[]>;
|
|
584
666
|
/**
|
|
585
667
|
* Returns operations for a document/scope/branch whose index is greater
|
|
586
668
|
* than the given revision.
|
|
@@ -627,6 +709,16 @@ interface IOperationStore {
|
|
|
627
709
|
* @returns Object containing revision map and latest timestamp
|
|
628
710
|
*/
|
|
629
711
|
getRevisions(documentId: string, branch: string, signal?: AbortSignal): Promise<DocumentRevisions>;
|
|
712
|
+
/**
|
|
713
|
+
* The largest operation timestamp in one stream, or undefined when it is empty.
|
|
714
|
+
* Distinct from {@link DocumentRevisions.latestTimestamp}, which maxes over
|
|
715
|
+
* every scope.
|
|
716
|
+
*
|
|
717
|
+
* Must be a real maximum, not the last-indexed operation's timestamp: a
|
|
718
|
+
* re-evaluation pass re-appends at a fresh index while keeping the original
|
|
719
|
+
* timestamp, so a later timestamp can sit behind the last row.
|
|
720
|
+
*/
|
|
721
|
+
getStreamLatestTimestamp(documentId: string, scope: string, branch: string, signal?: AbortSignal): Promise<string | undefined>;
|
|
630
722
|
}
|
|
631
723
|
/**
|
|
632
724
|
* Stores periodic document snapshots (keyframes) so that document state
|
|
@@ -1045,7 +1137,8 @@ type DeadLetterRecord = {
|
|
|
1045
1137
|
branch: string;
|
|
1046
1138
|
operations: OperationWithContext$1[];
|
|
1047
1139
|
errorSource: ChannelErrorSource;
|
|
1048
|
-
errorMessage: string;
|
|
1140
|
+
errorMessage: string; /** Why it failed, in the closed set sync classifies failures into. */
|
|
1141
|
+
errorType: SyncOperationErrorType;
|
|
1049
1142
|
};
|
|
1050
1143
|
/**
|
|
1051
1144
|
* Persists dead-lettered sync operations so they survive reactor restarts.
|
|
@@ -1103,6 +1196,15 @@ interface IOperationIndexTxn {
|
|
|
1103
1196
|
createCollection(collectionId: string): void;
|
|
1104
1197
|
addToCollection(collectionId: string, documentId: string): void;
|
|
1105
1198
|
removeFromCollection(collectionId: string, documentId: string): void;
|
|
1199
|
+
/**
|
|
1200
|
+
* Records the group documents an auth operation's input names, tied to the
|
|
1201
|
+
* last written operation like addToCollection. At commit each reference is
|
|
1202
|
+
* remembered permanently and the group joins every collection the
|
|
1203
|
+
* referencing document belongs to, keeping the earliest join and reopening
|
|
1204
|
+
* a closed membership, so sync serves the group's history to every remote
|
|
1205
|
+
* that can observe the referencing grant.
|
|
1206
|
+
*/
|
|
1207
|
+
recordGroupReferences(documentId: string, groupIds: string[]): void;
|
|
1106
1208
|
write(operations: OperationIndexEntry[]): void;
|
|
1107
1209
|
}
|
|
1108
1210
|
/**
|
|
@@ -1124,6 +1226,13 @@ interface IOperationIndex {
|
|
|
1124
1226
|
* Returns a map of documentId to array of collection IDs.
|
|
1125
1227
|
*/
|
|
1126
1228
|
getCollectionsForDocuments(documentIds: string[]): Promise<Record<string, string[]>>;
|
|
1229
|
+
/**
|
|
1230
|
+
* The documents whose auth history has ever referenced the group, from the
|
|
1231
|
+
* group-reference relation. This is the set a group-stream change owes a
|
|
1232
|
+
* re-evaluation pass to; it is complete because a group's auth scope cannot
|
|
1233
|
+
* reference other groups.
|
|
1234
|
+
*/
|
|
1235
|
+
getGroupReferencers(groupId: string, signal?: AbortSignal): Promise<string[]>;
|
|
1127
1236
|
}
|
|
1128
1237
|
/**
|
|
1129
1238
|
* Identifies the collection a remote synchronizes. Collections are drive-level
|
|
@@ -1152,6 +1261,51 @@ declare class DriveCollectionId {
|
|
|
1152
1261
|
equals(other: DriveCollectionId): boolean;
|
|
1153
1262
|
}
|
|
1154
1263
|
//#endregion
|
|
1264
|
+
//#region src/cache/write-cache-types.d.ts
|
|
1265
|
+
/**
|
|
1266
|
+
* Configuration options for the write cache
|
|
1267
|
+
*/
|
|
1268
|
+
type WriteCacheConfig = {
|
|
1269
|
+
/** Maximum number of document streams to cache (LRU eviction). Default: 1000 */maxDocuments: number; /** Number of snapshots to keep in each document's ring buffer. Default: 10 */
|
|
1270
|
+
ringBufferSize: number; /** Persist a keyframe snapshot every N revisions. Default: 10 */
|
|
1271
|
+
keyframeInterval: number;
|
|
1272
|
+
};
|
|
1273
|
+
/**
|
|
1274
|
+
* Unique identifier for a document stream
|
|
1275
|
+
*/
|
|
1276
|
+
type DocumentStreamKey = {
|
|
1277
|
+
/** Document identifier */documentId: string; /** Operation scope */
|
|
1278
|
+
scope: string; /** Branch name */
|
|
1279
|
+
branch: string;
|
|
1280
|
+
};
|
|
1281
|
+
/**
|
|
1282
|
+
* Where a snapshot sits in its stream.
|
|
1283
|
+
*
|
|
1284
|
+
* - `Head`: the newest revision of the stream when it was stored. Only these
|
|
1285
|
+
* can answer a read that asks for the head.
|
|
1286
|
+
* - `Historical`: state at an earlier revision. Usable as a starting point to
|
|
1287
|
+
* replay forward from, and as an answer to a read for that same revision.
|
|
1288
|
+
*/
|
|
1289
|
+
declare enum SnapshotPosition {
|
|
1290
|
+
Head = "head",
|
|
1291
|
+
Historical = "historical"
|
|
1292
|
+
}
|
|
1293
|
+
/**
|
|
1294
|
+
* A cached document snapshot at a specific revision
|
|
1295
|
+
*/
|
|
1296
|
+
type CachedSnapshot = {
|
|
1297
|
+
/** The revision number of this snapshot */revision: number; /** The document state at this revision */
|
|
1298
|
+
document: PHDocument; /** Where this snapshot sat in the stream when it was stored */
|
|
1299
|
+
position: SnapshotPosition;
|
|
1300
|
+
};
|
|
1301
|
+
/**
|
|
1302
|
+
* Serialized keyframe snapshot for K/V store persistence
|
|
1303
|
+
*/
|
|
1304
|
+
type KeyframeSnapshot = {
|
|
1305
|
+
/** The revision number of this keyframe */revision: number; /** Serialized document state */
|
|
1306
|
+
document: string;
|
|
1307
|
+
};
|
|
1308
|
+
//#endregion
|
|
1155
1309
|
//#region src/cache/write/interfaces.d.ts
|
|
1156
1310
|
/**
|
|
1157
1311
|
* IWriteCache is a write-side projection that optimizes document state retrieval
|
|
@@ -1166,7 +1320,8 @@ interface IWriteCache {
|
|
|
1166
1320
|
* @param documentId - The document identifier
|
|
1167
1321
|
* @param scope - Operation scope
|
|
1168
1322
|
* @param branch - Branch name
|
|
1169
|
-
* @param targetRevision -
|
|
1323
|
+
* @param targetRevision - Index of the last operation to apply, defaulting
|
|
1324
|
+
* to latest. An operation index, never `header.revision[scope]`.
|
|
1170
1325
|
* @param signal - Optional abort signal to cancel the operation
|
|
1171
1326
|
* @returns The complete document at the specified revision
|
|
1172
1327
|
*
|
|
@@ -1192,15 +1347,19 @@ interface IWriteCache {
|
|
|
1192
1347
|
* @param documentId - The document identifier
|
|
1193
1348
|
* @param scope - Operation scope
|
|
1194
1349
|
* @param branch - Branch name
|
|
1195
|
-
* @param revision -
|
|
1350
|
+
* @param revision - Index of the last operation this document reflects, so
|
|
1351
|
+
* `header.revision[scope]` is one greater. -1 for an empty scope.
|
|
1196
1352
|
* @param document - The document to cache
|
|
1353
|
+
* @param position - Whether `revision` is the stream's head. Nothing checks
|
|
1354
|
+
* it: claiming `Head` for an earlier revision makes a getState() with no
|
|
1355
|
+
* target return stale state.
|
|
1197
1356
|
*
|
|
1198
1357
|
* @example
|
|
1199
1358
|
* ```typescript
|
|
1200
|
-
* cache.putState(docId, 'global', 'main', 42, document);
|
|
1359
|
+
* cache.putState(docId, 'global', 'main', 42, document, SnapshotPosition.Head);
|
|
1201
1360
|
* ```
|
|
1202
1361
|
*/
|
|
1203
|
-
putState(documentId: string, scope: string, branch: string, revision: number, document: PHDocument): void;
|
|
1362
|
+
putState(documentId: string, scope: string, branch: string, revision: number, document: PHDocument, position: SnapshotPosition): void;
|
|
1204
1363
|
/**
|
|
1205
1364
|
* Invalidates (removes) cached entries for a document stream.
|
|
1206
1365
|
*
|
|
@@ -1531,6 +1690,17 @@ type CreateDocumentOptions = {
|
|
|
1531
1690
|
/** Optional "id" or "slug" of parent document */parentIdentifier?: string; /** Optional version of the document model to use (defaults to latest) */
|
|
1532
1691
|
documentModelVersion?: number;
|
|
1533
1692
|
};
|
|
1693
|
+
/**
|
|
1694
|
+
* Options for upgrading a document.
|
|
1695
|
+
*/
|
|
1696
|
+
type UpgradeDocumentOptions = {
|
|
1697
|
+
/**
|
|
1698
|
+
* How many times to retry with a fresh read when the executor rejects the
|
|
1699
|
+
* upgrade because the document changed after it was read. Defaults to
|
|
1700
|
+
* {@link DEFAULT_UPGRADE_CONFLICT_RETRIES}.
|
|
1701
|
+
*/
|
|
1702
|
+
maxConflictRetries?: number;
|
|
1703
|
+
};
|
|
1534
1704
|
/**
|
|
1535
1705
|
* Drive-aware operations grouped under `client.drives`.
|
|
1536
1706
|
*
|
|
@@ -1646,7 +1816,7 @@ interface IReactorClient {
|
|
|
1646
1816
|
* @param signal - Optional abort signal to cancel the request
|
|
1647
1817
|
* @returns The canonical document id
|
|
1648
1818
|
*/
|
|
1649
|
-
resolveIdOrSlug(identifier: string, signal?: AbortSignal): Promise<string>;
|
|
1819
|
+
resolveIdOrSlug(identifier: string, view?: ViewFilter, signal?: AbortSignal): Promise<string>;
|
|
1650
1820
|
/**
|
|
1651
1821
|
* Retrieves operations for a document.
|
|
1652
1822
|
*
|
|
@@ -1707,6 +1877,38 @@ interface IReactorClient {
|
|
|
1707
1877
|
* @param signal - Optional abort signal to cancel the request
|
|
1708
1878
|
*/
|
|
1709
1879
|
createEmpty<TDocument extends PHDocument>(documentModelType: string, options?: CreateDocumentOptions, signal?: AbortSignal): Promise<TDocument>;
|
|
1880
|
+
/**
|
|
1881
|
+
* Retrieves the document model module matching the version a document is
|
|
1882
|
+
* stamped with. Use this instead of {@link getDocumentModelModule}
|
|
1883
|
+
* whenever a specific document is in hand: the latest-wins lookup feeds
|
|
1884
|
+
* not-yet-upgraded documents the wrong reducer, diverging from replay.
|
|
1885
|
+
*
|
|
1886
|
+
* @param document - The document whose stamped version selects the module
|
|
1887
|
+
* @returns The document model module registered for that version
|
|
1888
|
+
* @throws UnsupportedDocumentModelVersionError if no module is registered for the stamped version
|
|
1889
|
+
*/
|
|
1890
|
+
getDocumentModelModuleForDocument(document: PHDocument): Promise<DocumentModelModule<any>>;
|
|
1891
|
+
/**
|
|
1892
|
+
* Upgrades a document to a newer document model version by dispatching an
|
|
1893
|
+
* UPGRADE_DOCUMENT action. When toVersion is omitted, upgrades to the
|
|
1894
|
+
* latest registered module version for the document's type. Returns the
|
|
1895
|
+
* document unchanged when it is already at the target version.
|
|
1896
|
+
*
|
|
1897
|
+
* The action carries a snapshot of the document's version and per-scope
|
|
1898
|
+
* revisions, which the executor validates before persisting. When an edit
|
|
1899
|
+
* lands between the read and the upgrade executing, the upgrade is
|
|
1900
|
+
* rejected and retried with a fresh read up to
|
|
1901
|
+
* {@link UpgradeDocumentOptions.maxConflictRetries} times before the
|
|
1902
|
+
* conflict is surfaced.
|
|
1903
|
+
*
|
|
1904
|
+
* @param documentIdentifier - Target document id or slug
|
|
1905
|
+
* @param toVersion - Optional target document model version; defaults to latest
|
|
1906
|
+
* @param options - Optional upgrade options (maxConflictRetries)
|
|
1907
|
+
* @param signal - Optional abort signal to cancel the request
|
|
1908
|
+
* @returns The upgraded document
|
|
1909
|
+
* @throws DowngradeNotSupportedError if toVersion is less than the document's current version
|
|
1910
|
+
*/
|
|
1911
|
+
upgradeDocument<TDocument extends PHDocument = PHDocument>(documentIdentifier: string, toVersion?: number, options?: UpgradeDocumentOptions, signal?: AbortSignal): Promise<TDocument>;
|
|
1710
1912
|
/**
|
|
1711
1913
|
* Creates an empty document in a drive as a single batched operation.
|
|
1712
1914
|
* This is more efficient than createEmpty + addFile as it batches all
|
|
@@ -1863,222 +2065,255 @@ interface IReactorClient {
|
|
|
1863
2065
|
subscribe(search: SearchFilter, callback: (event: DocumentChangeEvent) => void, view?: ViewFilter): () => void;
|
|
1864
2066
|
}
|
|
1865
2067
|
//#endregion
|
|
1866
|
-
//#region src/
|
|
2068
|
+
//#region src/cache/collection-membership-cache.d.ts
|
|
2069
|
+
interface ICollectionMembershipCache {
|
|
2070
|
+
getCollectionsForDocuments(documentIds: string[]): Promise<Record<string, string[]>>;
|
|
2071
|
+
invalidate(documentId: string): void;
|
|
2072
|
+
}
|
|
2073
|
+
//#endregion
|
|
2074
|
+
//#region src/cache/document-meta-cache-types.d.ts
|
|
1867
2075
|
/**
|
|
1868
|
-
*
|
|
1869
|
-
* a simpler interface for document operations.
|
|
2076
|
+
* Cached document metadata from the "document" scope.
|
|
1870
2077
|
*
|
|
1871
|
-
*
|
|
1872
|
-
*
|
|
1873
|
-
* -
|
|
1874
|
-
* - Provides quality-of-life functions for common tasks
|
|
1875
|
-
* - Wraps subscription interface with ViewFilters
|
|
2078
|
+
* This lightweight structure holds essential document information needed by
|
|
2079
|
+
* the job executor without fetching full scope state. It provides an explicit
|
|
2080
|
+
* cross-scope contract for accessing document scope metadata.
|
|
1876
2081
|
*/
|
|
1877
|
-
|
|
1878
|
-
private logger;
|
|
1879
|
-
private reactor;
|
|
1880
|
-
private signer;
|
|
1881
|
-
private subscriptionManager;
|
|
1882
|
-
private jobAwaiter;
|
|
1883
|
-
private documentIndexer;
|
|
1884
|
-
private documentView;
|
|
1885
|
-
readonly drives: IDriveClient;
|
|
1886
|
-
constructor(logger: ILogger, reactor: IReactor, signer: ISigner, subscriptionManager: IReactorSubscriptionManager, jobAwaiter: IJobAwaiter, documentIndexer: IDocumentIndexer, documentView: IDocumentView);
|
|
1887
|
-
/**
|
|
1888
|
-
* Retrieves a list of document model modules.
|
|
1889
|
-
*/
|
|
1890
|
-
getDocumentModelModules(namespace?: string, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<DocumentModelModule>>;
|
|
1891
|
-
/**
|
|
1892
|
-
* Retrieves a specific document model module by document type.
|
|
1893
|
-
*
|
|
1894
|
-
* @param documentType - The document type identifier
|
|
1895
|
-
* @returns The document model module
|
|
1896
|
-
*/
|
|
1897
|
-
getDocumentModelModule(documentType: string): Promise<DocumentModelModule<any>>;
|
|
1898
|
-
/**
|
|
1899
|
-
* Retrieves a specific PHDocument
|
|
1900
|
-
*/
|
|
1901
|
-
get<TDocument extends PHDocument>(identifier: string, view?: ViewFilter, signal?: AbortSignal): Promise<TDocument>;
|
|
1902
|
-
/**
|
|
1903
|
-
* Resolves an identifier (id or slug) to the canonical document id, using the
|
|
1904
|
-
* same lookup as the data path. Resolves against the "main" branch. Throws if
|
|
1905
|
-
* the identifier cannot be resolved or is ambiguous.
|
|
1906
|
-
*/
|
|
1907
|
-
resolveIdOrSlug(identifier: string, signal?: AbortSignal): Promise<string>;
|
|
1908
|
-
/**
|
|
1909
|
-
* Retrieves operations for a document
|
|
1910
|
-
*/
|
|
1911
|
-
getOperations(documentIdentifier: string, view?: ViewFilter, filter?: OperationFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<Operation>>;
|
|
1912
|
-
private getOperationsWithCompositeCursor;
|
|
1913
|
-
/**
|
|
1914
|
-
* Retrieves outgoing relationships of a given type from a source document.
|
|
1915
|
-
*/
|
|
1916
|
-
getOutgoingRelationships(sourceIdentifier: string, relationshipType: string, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
|
|
1917
|
-
/**
|
|
1918
|
-
* Retrieves incoming relationships of a given type to a target document.
|
|
1919
|
-
*/
|
|
1920
|
-
getIncomingRelationships(targetIdentifier: string, relationshipType: string, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
|
|
2082
|
+
type CachedDocumentMeta = {
|
|
1921
2083
|
/**
|
|
1922
|
-
*
|
|
2084
|
+
* The full PHDocumentState from document.state.document.
|
|
2085
|
+
* Contains version, hash, isDeleted, deletedAtUtcIso, etc.
|
|
1923
2086
|
*/
|
|
1924
|
-
|
|
2087
|
+
state: PHDocumentState;
|
|
1925
2088
|
/**
|
|
1926
|
-
*
|
|
2089
|
+
* The document type (from header), cached for convenience.
|
|
1927
2090
|
*/
|
|
1928
|
-
|
|
2091
|
+
documentType: string;
|
|
1929
2092
|
/**
|
|
1930
|
-
*
|
|
2093
|
+
* The revision of the document scope when this metadata was captured.
|
|
2094
|
+
* Used for cache invalidation and consistency checks.
|
|
1931
2095
|
*/
|
|
1932
|
-
|
|
2096
|
+
documentScopeRevision: number;
|
|
2097
|
+
};
|
|
2098
|
+
/**
|
|
2099
|
+
* Interface for the document metadata cache.
|
|
2100
|
+
*
|
|
2101
|
+
* This cache provides an explicit cross-scope contract for accessing document
|
|
2102
|
+
* scope metadata. It solves the problem where job execution in one scope (e.g.,
|
|
2103
|
+
* "global") needs access to document scope state (version, isDeleted, etc.)
|
|
2104
|
+
* which may be stale in scope-specific caches or keyframes.
|
|
2105
|
+
*
|
|
2106
|
+
* The cache supports:
|
|
2107
|
+
* - Latest metadata retrieval with LRU caching
|
|
2108
|
+
* - Historical metadata reconstruction for reshuffling scenarios
|
|
2109
|
+
* - Eager updates after document scope operations
|
|
2110
|
+
*/
|
|
2111
|
+
interface IDocumentMetaCache {
|
|
1933
2112
|
/**
|
|
1934
|
-
*
|
|
1935
|
-
* Delegates to {@link IDriveClient.addFile}.
|
|
2113
|
+
* Retrieves the LATEST document metadata from cache or rebuilds from operations.
|
|
1936
2114
|
*
|
|
1937
|
-
*
|
|
1938
|
-
*
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
*
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
*
|
|
2115
|
+
* On cache miss, fetches all document scope operations and reconstructs the
|
|
2116
|
+
* current PHDocumentState by applying UPGRADE_DOCUMENT and DELETE_DOCUMENT
|
|
2117
|
+
* operations.
|
|
2118
|
+
*
|
|
2119
|
+
* @param documentId - The document identifier
|
|
2120
|
+
* @param branch - Branch name
|
|
2121
|
+
* @param signal - Optional abort signal to cancel the operation
|
|
2122
|
+
* @returns The cached or rebuilt document metadata
|
|
2123
|
+
* @throws {Error} "Operation aborted" if signal is aborted
|
|
2124
|
+
* @throws {Error} If document not found (no CREATE_DOCUMENT operation)
|
|
1947
2125
|
*/
|
|
1948
|
-
|
|
1949
|
-
executeBatch(request: BatchExecutionRequest, signal?: AbortSignal): Promise<BatchExecutionResult>;
|
|
2126
|
+
getDocumentMeta(documentId: string, branch: string, signal?: AbortSignal): Promise<CachedDocumentMeta>;
|
|
1950
2127
|
/**
|
|
1951
|
-
*
|
|
2128
|
+
* Rebuilds document metadata at a SPECIFIC revision (always rebuilds, no caching).
|
|
2129
|
+
*
|
|
2130
|
+
* Used during reshuffling when operations need to be inserted at a previous
|
|
2131
|
+
* revision and we need the document scope state as of that point in time.
|
|
2132
|
+
*
|
|
2133
|
+
* @param documentId - The document identifier
|
|
2134
|
+
* @param branch - Branch name
|
|
2135
|
+
* @param targetRevision - The document scope revision to reconstruct up to
|
|
2136
|
+
* @param signal - Optional abort signal to cancel the operation
|
|
2137
|
+
* @returns Document metadata as of the target revision
|
|
2138
|
+
* @throws {Error} "Operation aborted" if signal is aborted
|
|
2139
|
+
* @throws {Error} If document not found
|
|
1952
2140
|
*/
|
|
1953
|
-
|
|
2141
|
+
rebuildAtRevision(documentId: string, branch: string, targetRevision: number, signal?: AbortSignal): Promise<CachedDocumentMeta>;
|
|
1954
2142
|
/**
|
|
1955
|
-
*
|
|
1956
|
-
*
|
|
2143
|
+
* Eagerly updates cached metadata after document scope operations.
|
|
2144
|
+
*
|
|
2145
|
+
* Called by the job executor after CREATE_DOCUMENT, UPGRADE_DOCUMENT, or
|
|
2146
|
+
* DELETE_DOCUMENT operations to keep the cache current.
|
|
2147
|
+
*
|
|
2148
|
+
* @param documentId - The document identifier
|
|
2149
|
+
* @param branch - Branch name
|
|
2150
|
+
* @param meta - The new metadata to cache
|
|
1957
2151
|
*/
|
|
1958
|
-
|
|
2152
|
+
putDocumentMeta(documentId: string, branch: string, meta: CachedDocumentMeta): void;
|
|
1959
2153
|
/**
|
|
1960
|
-
*
|
|
2154
|
+
* Invalidates cached document metadata.
|
|
2155
|
+
*
|
|
2156
|
+
* Call before reshuffling operations that modify the document scope, or
|
|
2157
|
+
* when document state may have changed externally.
|
|
2158
|
+
*
|
|
2159
|
+
* @param documentId - The document identifier
|
|
2160
|
+
* @param branch - Optional branch to narrow invalidation (if omitted, all branches)
|
|
2161
|
+
* @returns Number of entries invalidated
|
|
1961
2162
|
*/
|
|
1962
|
-
|
|
2163
|
+
invalidate(documentId: string, branch?: string): number;
|
|
1963
2164
|
/**
|
|
1964
|
-
*
|
|
2165
|
+
* Clears all cached document metadata.
|
|
1965
2166
|
*/
|
|
1966
|
-
|
|
2167
|
+
clear(): void;
|
|
1967
2168
|
/**
|
|
1968
|
-
*
|
|
2169
|
+
* Performs startup initialization.
|
|
1969
2170
|
*/
|
|
1970
|
-
|
|
1971
|
-
source: PHDocument;
|
|
1972
|
-
target: PHDocument;
|
|
1973
|
-
}>;
|
|
1974
|
-
loadBatch(request: BatchLoadRequest, signal?: AbortSignal): Promise<BatchLoadResult>;
|
|
2171
|
+
startup(): Promise<void>;
|
|
1975
2172
|
/**
|
|
1976
|
-
*
|
|
2173
|
+
* Performs graceful shutdown.
|
|
1977
2174
|
*/
|
|
1978
|
-
|
|
1979
|
-
/**
|
|
1980
|
-
* Deletes documents and waits for completion
|
|
1981
|
-
*/
|
|
1982
|
-
deleteDocuments(identifiers: string[], propagate?: PropagationMode, signal?: AbortSignal): Promise<void>;
|
|
1983
|
-
/**
|
|
1984
|
-
* Retrieves the status of a job
|
|
1985
|
-
*/
|
|
1986
|
-
getJobStatus(jobId: string, signal?: AbortSignal): Promise<JobInfo>;
|
|
1987
|
-
/**
|
|
1988
|
-
* Waits for a job to complete
|
|
1989
|
-
*/
|
|
1990
|
-
waitForJob(jobId: string | JobInfo, signal?: AbortSignal): Promise<JobInfo>;
|
|
1991
|
-
/**
|
|
1992
|
-
* Subscribes to changes for documents matching specified filters
|
|
1993
|
-
*/
|
|
1994
|
-
subscribe(search: SearchFilter, callback: (event: DocumentChangeEvent) => void, view?: ViewFilter): () => void;
|
|
1995
|
-
private removeAllIncomingRelationships;
|
|
2175
|
+
shutdown(): Promise<void>;
|
|
1996
2176
|
}
|
|
1997
2177
|
//#endregion
|
|
1998
|
-
//#region src/
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2178
|
+
//#region src/storage/kysely/types.d.ts
|
|
2179
|
+
interface OperationTable {
|
|
2180
|
+
id: Generated<number>;
|
|
2181
|
+
jobId: string;
|
|
2182
|
+
opId: string;
|
|
2183
|
+
prevOpId: string;
|
|
2184
|
+
writeTimestampUtcMs: Generated<Date>;
|
|
2185
|
+
documentId: string;
|
|
2186
|
+
documentType: string;
|
|
2187
|
+
scope: string;
|
|
2188
|
+
branch: string;
|
|
2189
|
+
timestampUtcMs: Date;
|
|
2190
|
+
index: number;
|
|
2191
|
+
action: unknown;
|
|
2192
|
+
skip: number;
|
|
2193
|
+
error?: string | null;
|
|
2194
|
+
deniedReason?: string | null;
|
|
2195
|
+
hash: string;
|
|
2196
|
+
}
|
|
2197
|
+
interface KeyframeTable {
|
|
2198
|
+
id: Generated<number>;
|
|
2199
|
+
documentId: string;
|
|
2200
|
+
documentType: string;
|
|
2201
|
+
scope: string;
|
|
2202
|
+
branch: string;
|
|
2203
|
+
revision: number;
|
|
2204
|
+
document: unknown;
|
|
2205
|
+
createdAt: Generated<Date>;
|
|
2206
|
+
}
|
|
2207
|
+
interface DocumentCollectionTable {
|
|
2208
|
+
documentId: string;
|
|
2209
|
+
collectionId: string;
|
|
2210
|
+
joinedOrdinal: bigint;
|
|
2211
|
+
leftOrdinal: bigint | null;
|
|
2212
|
+
}
|
|
2213
|
+
interface OperationIndexOperationTable {
|
|
2214
|
+
ordinal: Generated<number>;
|
|
2215
|
+
opId: string;
|
|
2216
|
+
documentId: string;
|
|
2217
|
+
documentType: string;
|
|
2218
|
+
scope: string;
|
|
2219
|
+
branch: string;
|
|
2220
|
+
timestampUtcMs: string;
|
|
2221
|
+
writeTimestampUtcMs: Generated<Date>;
|
|
2222
|
+
index: number;
|
|
2223
|
+
skip: number;
|
|
2224
|
+
hash: string;
|
|
2225
|
+
action: unknown;
|
|
2226
|
+
deniedReason?: string | null;
|
|
2227
|
+
sourceRemote: Generated<string>;
|
|
2228
|
+
}
|
|
2229
|
+
interface SyncRemoteTable {
|
|
2230
|
+
name: string;
|
|
2231
|
+
collection_id: string;
|
|
2232
|
+
channel_type: string;
|
|
2233
|
+
channel_id: string;
|
|
2234
|
+
remote_name: string;
|
|
2235
|
+
channel_parameters: unknown;
|
|
2236
|
+
filter_document_ids: unknown;
|
|
2237
|
+
filter_scopes: unknown;
|
|
2238
|
+
filter_branch: string;
|
|
2239
|
+
push_state: string;
|
|
2240
|
+
push_last_success_utc_ms: string | null;
|
|
2241
|
+
push_last_failure_utc_ms: string | null;
|
|
2242
|
+
push_failure_count: number;
|
|
2243
|
+
pull_state: string;
|
|
2244
|
+
pull_last_success_utc_ms: string | null;
|
|
2245
|
+
pull_last_failure_utc_ms: string | null;
|
|
2246
|
+
pull_failure_count: number;
|
|
2247
|
+
created_at: Generated<Date>;
|
|
2248
|
+
updated_at: Generated<Date>;
|
|
2249
|
+
}
|
|
2250
|
+
interface SyncCursorTable {
|
|
2251
|
+
remote_name: string;
|
|
2252
|
+
cursor_type: string;
|
|
2253
|
+
cursor_ordinal: bigint;
|
|
2254
|
+
last_synced_at_utc_ms: string | null;
|
|
2255
|
+
updated_at: Generated<Date>;
|
|
2256
|
+
}
|
|
2039
2257
|
/**
|
|
2040
|
-
*
|
|
2258
|
+
* Kysely table definition for the `sync_dead_letters` table.
|
|
2041
2259
|
*/
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
};
|
|
2058
|
-
type JobFailedEvent = {
|
|
2059
|
-
job: Job;
|
|
2060
|
-
error: string;
|
|
2061
|
-
willRetry: boolean;
|
|
2062
|
-
retryCount: number; /** See {@link JobStartedEvent.workerId}. */
|
|
2063
|
-
workerId?: string;
|
|
2064
|
-
};
|
|
2065
|
-
type ExecutorStartedEvent = {
|
|
2066
|
-
config: JobExecutorConfig;
|
|
2067
|
-
startedAt: string;
|
|
2068
|
-
};
|
|
2069
|
-
type ExecutorStoppedEvent = {
|
|
2070
|
-
stoppedAt: string;
|
|
2071
|
-
graceful: boolean;
|
|
2072
|
-
};
|
|
2260
|
+
interface SyncDeadLetterTable {
|
|
2261
|
+
ordinal: Generated<number>;
|
|
2262
|
+
id: string;
|
|
2263
|
+
job_id: string;
|
|
2264
|
+
job_dependencies: unknown;
|
|
2265
|
+
remote_name: string;
|
|
2266
|
+
document_id: string;
|
|
2267
|
+
scopes: unknown;
|
|
2268
|
+
branch: string;
|
|
2269
|
+
operations: unknown;
|
|
2270
|
+
error_source: string;
|
|
2271
|
+
error_message: string;
|
|
2272
|
+
error_type: Generated<string>;
|
|
2273
|
+
created_at: Generated<Date>;
|
|
2274
|
+
}
|
|
2073
2275
|
/**
|
|
2074
|
-
*
|
|
2276
|
+
* One (document, group) reference ever discovered from an auth operation's
|
|
2277
|
+
* input. Rows are never updated or deleted (see migration 017).
|
|
2075
2278
|
*/
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2279
|
+
interface GroupReferenceTable {
|
|
2280
|
+
documentId: string;
|
|
2281
|
+
groupId: string;
|
|
2282
|
+
}
|
|
2283
|
+
interface Database$1 {
|
|
2284
|
+
Operation: OperationTable;
|
|
2285
|
+
Keyframe: KeyframeTable;
|
|
2286
|
+
document_collections: DocumentCollectionTable;
|
|
2287
|
+
operation_index_operations: OperationIndexOperationTable;
|
|
2288
|
+
group_references: GroupReferenceTable;
|
|
2289
|
+
sync_remotes: SyncRemoteTable;
|
|
2290
|
+
sync_cursors: SyncCursorTable;
|
|
2291
|
+
sync_dead_letters: SyncDeadLetterTable;
|
|
2292
|
+
}
|
|
2293
|
+
interface DocumentTable {
|
|
2294
|
+
id: string;
|
|
2295
|
+
createdAt: Generated<Date>;
|
|
2296
|
+
updatedAt: Generated<Date>;
|
|
2297
|
+
}
|
|
2298
|
+
interface DocumentRelationshipTable {
|
|
2299
|
+
id: Generated<string>;
|
|
2300
|
+
sourceId: string;
|
|
2301
|
+
targetId: string;
|
|
2302
|
+
relationshipType: string;
|
|
2303
|
+
metadata: unknown;
|
|
2304
|
+
createdAt: Generated<Date>;
|
|
2305
|
+
updatedAt: Generated<Date>;
|
|
2306
|
+
}
|
|
2307
|
+
interface IndexerStateTable {
|
|
2308
|
+
id: Generated<number>;
|
|
2309
|
+
lastOperationId: number;
|
|
2310
|
+
lastOperationTimestamp: Generated<Date>;
|
|
2311
|
+
}
|
|
2312
|
+
interface DocumentIndexerDatabase {
|
|
2313
|
+
Document: DocumentTable;
|
|
2314
|
+
DocumentRelationship: DocumentRelationshipTable;
|
|
2315
|
+
IndexerState: IndexerStateTable;
|
|
2316
|
+
}
|
|
2082
2317
|
//#endregion
|
|
2083
2318
|
//#region src/executor/worker/protocol.d.ts
|
|
2084
2319
|
/**
|
|
@@ -2244,7 +2479,8 @@ type InitMessage = {
|
|
|
2244
2479
|
poolConfig: WorkerPoolConfig;
|
|
2245
2480
|
db: DbConfig; /** Omitted = the worker performs no executor-side signature verification. */
|
|
2246
2481
|
signatureVerifier?: SignatureVerifierSpec;
|
|
2247
|
-
models: ModelManifestEntry[];
|
|
2482
|
+
models: ModelManifestEntry[]; /** Omitted = the worker builds its executor with the built-in defaults. */
|
|
2483
|
+
executorConfig?: JobExecutorConfig;
|
|
2248
2484
|
};
|
|
2249
2485
|
/**
|
|
2250
2486
|
* Dispatches a job to the worker for execution.
|
|
@@ -2425,209 +2661,1213 @@ type PoolAcquireSamplesMessage = {
|
|
|
2425
2661
|
*/
|
|
2426
2662
|
type WorkerMessage = ReadyMessage | ResultMessage | ModelLoadedMessage | ModelLoadFailedMessage | LogMessage | HeartbeatMessage | MetricsMessage | PoolAcquireSamplesMessage;
|
|
2427
2663
|
//#endregion
|
|
2428
|
-
//#region src/
|
|
2664
|
+
//#region src/core/model-sources.d.ts
|
|
2665
|
+
/** An importable file holding one or more document-model exports. */
|
|
2666
|
+
type FileModelSource = {
|
|
2667
|
+
filePath: string;
|
|
2668
|
+
exportName?: string;
|
|
2669
|
+
};
|
|
2670
|
+
/** An importable package specifier holding one or more document-model exports. */
|
|
2671
|
+
type PackageModelSource = {
|
|
2672
|
+
packageName: string;
|
|
2673
|
+
subpath?: string;
|
|
2674
|
+
exportName?: string;
|
|
2675
|
+
};
|
|
2429
2676
|
/**
|
|
2430
|
-
*
|
|
2677
|
+
* A source of document models: a live module, an importable file, or an
|
|
2678
|
+
* importable package. File and package sources can cross a worker-thread
|
|
2679
|
+
* boundary (workers re-import them); a live module cannot.
|
|
2431
2680
|
*/
|
|
2432
|
-
type
|
|
2433
|
-
|
|
2434
|
-
|
|
2681
|
+
type DocumentModelSource = DocumentModelModule<any> | FileModelSource | PackageModelSource;
|
|
2682
|
+
//#endregion
|
|
2683
|
+
//#region src/registry/interfaces.d.ts
|
|
2684
|
+
type RegistrationResult<T> = {
|
|
2685
|
+
status: "success";
|
|
2686
|
+
item: T;
|
|
2687
|
+
} | {
|
|
2688
|
+
status: "error";
|
|
2689
|
+
item: T;
|
|
2690
|
+
error: Error;
|
|
2435
2691
|
};
|
|
2436
2692
|
/**
|
|
2437
|
-
*
|
|
2438
|
-
*
|
|
2439
|
-
*
|
|
2440
|
-
* the operations + jobMeta the parent needs to emit `JOB_WRITE_READY`, and is
|
|
2441
|
-
* present only when the worker produced operations. It is absent on failure
|
|
2442
|
-
* and on success-with-no-operations.
|
|
2443
|
-
*/
|
|
2444
|
-
type WorkerExecutionOutcome = {
|
|
2445
|
-
result: JobResult;
|
|
2446
|
-
writeReady?: JobWriteReadyPayload;
|
|
2447
|
-
};
|
|
2448
|
-
/**
|
|
2449
|
-
* Parent-side handle for a single executor worker.
|
|
2693
|
+
* Loader that asynchronously resolves a document type to a
|
|
2694
|
+
* {@link DocumentModelSource}. Used by the queue to gate CREATE_DOCUMENT
|
|
2695
|
+
* jobs until the required model is available in the registry.
|
|
2450
2696
|
*
|
|
2451
|
-
*
|
|
2452
|
-
*
|
|
2453
|
-
*
|
|
2454
|
-
*
|
|
2455
|
-
*
|
|
2456
|
-
* concurrent dispatches would race its caches.
|
|
2697
|
+
* Return an importable source ({ filePath } or { packageName }) whenever
|
|
2698
|
+
* possible: the resolver registers the resolved models on the host registry
|
|
2699
|
+
* and broadcasts importable sources to executor workers. A live
|
|
2700
|
+
* DocumentModelModule is also valid but host-only — it cannot cross a
|
|
2701
|
+
* worker-thread boundary, so worker pools will not receive it.
|
|
2457
2702
|
*/
|
|
2458
|
-
interface
|
|
2459
|
-
|
|
2460
|
-
readonly workerId: string;
|
|
2461
|
-
/** Zero-based index within the pool, used for sticky routing. */
|
|
2462
|
-
readonly index: number;
|
|
2463
|
-
/**
|
|
2464
|
-
* Spawn the worker (if not already started), send the `init` payload and
|
|
2465
|
-
* resolve when the worker replies with `ready`.
|
|
2466
|
-
*/
|
|
2467
|
-
start(): Promise<void>;
|
|
2468
|
-
/**
|
|
2469
|
-
* Dispatch a job to the worker and resolve with its outcome — the
|
|
2470
|
-
* `JobResult` and, on success-with-operations, a `writeReady` payload
|
|
2471
|
-
* the parent will enrich and re-emit. Rejects with a transport-level
|
|
2472
|
-
* error if the worker exits, aborts, or times out before producing a
|
|
2473
|
-
* result.
|
|
2474
|
-
*/
|
|
2475
|
-
execute(job: Job, signal?: AbortSignal): Promise<WorkerExecutionOutcome>;
|
|
2476
|
-
/**
|
|
2477
|
-
* Request cancellation of the in-flight job (if any). The handle posts an
|
|
2478
|
-
* `abort` message; if the worker fails to reply within its grace window it
|
|
2479
|
-
* is force-terminated.
|
|
2480
|
-
*/
|
|
2481
|
-
abort(correlationId: string, reason?: string): void;
|
|
2482
|
-
/**
|
|
2483
|
-
* Stop the worker. When `graceful` is true the handle waits for the
|
|
2484
|
-
* in-flight job to settle (up to `graceMs`) before terminating; otherwise
|
|
2485
|
-
* the worker is terminated immediately.
|
|
2486
|
-
*/
|
|
2487
|
-
shutdown(graceful: boolean, graceMs?: number): Promise<void>;
|
|
2488
|
-
/**
|
|
2489
|
-
* Register an additional document model on the running worker. Resolves
|
|
2490
|
-
* when the worker replies with `model-loaded`; rejects when it replies
|
|
2491
|
-
* with `model-load-failed` or the worker exits before answering.
|
|
2492
|
-
*/
|
|
2493
|
-
loadModel(entry: ModelManifestEntry, signal?: AbortSignal): Promise<void>;
|
|
2494
|
-
/** True when no job is currently in flight. */
|
|
2495
|
-
isIdle(): boolean;
|
|
2496
|
-
/** Snapshot of the in-flight slot, or null when idle. */
|
|
2497
|
-
getInFlight(): WorkerInFlightSnapshot | null;
|
|
2703
|
+
interface IDocumentModelLoader {
|
|
2704
|
+
load(documentType: string): Promise<DocumentModelSource>;
|
|
2498
2705
|
}
|
|
2499
2706
|
/**
|
|
2500
|
-
*
|
|
2501
|
-
*
|
|
2707
|
+
* Registry for managing document model modules.
|
|
2708
|
+
* Provides centralized access to document models' reducers, utils, and specifications.
|
|
2709
|
+
* Supports version-aware module storage and upgrade manifest management.
|
|
2502
2710
|
*/
|
|
2503
|
-
interface
|
|
2711
|
+
interface IDocumentModelRegistry {
|
|
2504
2712
|
/**
|
|
2505
|
-
*
|
|
2506
|
-
*
|
|
2507
|
-
*
|
|
2713
|
+
* Register multiple modules at once.
|
|
2714
|
+
* Modules without a version field default to version 1.
|
|
2715
|
+
* Invalid or duplicate modules are skipped without breaking registration of the remaining modules.
|
|
2716
|
+
*
|
|
2717
|
+
* @param modules Document model modules to register
|
|
2718
|
+
* @returns Array of results, one per module, indicating success or failure
|
|
2508
2719
|
*/
|
|
2509
|
-
|
|
2510
|
-
}
|
|
2511
|
-
/**
|
|
2512
|
-
* Interface for managing multiple job executors.
|
|
2513
|
-
* Listens for 'jobAvailable' events from the event bus, pulls jobs from the queue,
|
|
2514
|
-
* and coordinates the distribution of jobs across multiple executor instances.
|
|
2515
|
-
*/
|
|
2516
|
-
interface IJobExecutorManager {
|
|
2720
|
+
registerModules(...modules: DocumentModelModule<any>[]): RegistrationResult<DocumentModelModule<any>>[];
|
|
2517
2721
|
/**
|
|
2518
|
-
*
|
|
2519
|
-
* Begins listening for 'jobAvailable' events and dispatching to executors.
|
|
2722
|
+
* Unregister all versions of the specified document types.
|
|
2520
2723
|
*
|
|
2521
|
-
* @param
|
|
2522
|
-
* @returns
|
|
2724
|
+
* @param documentTypes The document types to unregister
|
|
2725
|
+
* @returns true if all modules were unregistered, false if any were not found
|
|
2523
2726
|
*/
|
|
2524
|
-
|
|
2727
|
+
unregisterModules(...documentTypes: string[]): boolean;
|
|
2525
2728
|
/**
|
|
2526
|
-
*
|
|
2729
|
+
* Get a specific document model module by document type and optional version.
|
|
2730
|
+
* If version is not specified, returns the latest version.
|
|
2527
2731
|
*
|
|
2528
|
-
* @param
|
|
2529
|
-
* @
|
|
2732
|
+
* @param documentType The document type identifier
|
|
2733
|
+
* @param version Optional version number to retrieve
|
|
2734
|
+
* @returns The document model module
|
|
2735
|
+
* @throws ModuleNotFoundError if the document type or version is not registered
|
|
2530
2736
|
*/
|
|
2531
|
-
|
|
2737
|
+
getModule(documentType: string, version?: number): DocumentModelModule<any>;
|
|
2532
2738
|
/**
|
|
2533
|
-
* Get all
|
|
2739
|
+
* Get all registered document model modules.
|
|
2534
2740
|
*
|
|
2535
|
-
* @returns Array of
|
|
2741
|
+
* @returns Array of all registered modules
|
|
2536
2742
|
*/
|
|
2537
|
-
|
|
2743
|
+
getAllModules(): DocumentModelModule<any>[];
|
|
2538
2744
|
/**
|
|
2539
|
-
*
|
|
2745
|
+
* Clear all registered modules and upgrade manifests.
|
|
2746
|
+
*/
|
|
2747
|
+
clear(): void;
|
|
2748
|
+
/**
|
|
2749
|
+
* Get all supported versions for a document type, sorted in ascending order.
|
|
2540
2750
|
*
|
|
2541
|
-
* @
|
|
2751
|
+
* @param documentType The document type identifier
|
|
2752
|
+
* @returns Array of version numbers sorted ascending
|
|
2753
|
+
* @throws ModuleNotFoundError if no modules are registered for the document type
|
|
2542
2754
|
*/
|
|
2543
|
-
|
|
2544
|
-
}
|
|
2545
|
-
//#endregion
|
|
2546
|
-
//#region src/job-tracker/interfaces.d.ts
|
|
2547
|
-
/**
|
|
2548
|
-
* Interface for tracking job lifecycle status.
|
|
2549
|
-
* Maintains job state throughout execution: PENDING → RUNNING → COMPLETED/FAILED.
|
|
2550
|
-
*/
|
|
2551
|
-
interface IJobTracker {
|
|
2755
|
+
getSupportedVersions(documentType: string): number[];
|
|
2552
2756
|
/**
|
|
2553
|
-
*
|
|
2757
|
+
* Get the latest (highest) version number for a document type.
|
|
2554
2758
|
*
|
|
2555
|
-
* @param
|
|
2759
|
+
* @param documentType The document type identifier
|
|
2760
|
+
* @returns The highest version number registered for this document type
|
|
2761
|
+
* @throws ModuleNotFoundError if no modules are registered for the document type
|
|
2556
2762
|
*/
|
|
2557
|
-
|
|
2763
|
+
getLatestVersion(documentType: string): number;
|
|
2558
2764
|
/**
|
|
2559
|
-
*
|
|
2765
|
+
* Register upgrade manifests that define upgrade paths between versions.
|
|
2766
|
+
* Invalid or duplicate manifests are skipped without breaking registration of the remaining manifests.
|
|
2560
2767
|
*
|
|
2561
|
-
* @param
|
|
2768
|
+
* @param manifests Upgrade manifests to register
|
|
2769
|
+
* @returns Array of results, one per manifest, indicating success or failure
|
|
2562
2770
|
*/
|
|
2563
|
-
|
|
2771
|
+
registerUpgradeManifests(...manifests: UpgradeManifest<readonly number[]>[]): RegistrationResult<UpgradeManifest<readonly number[]>>[];
|
|
2564
2772
|
/**
|
|
2565
|
-
*
|
|
2773
|
+
* Unregister upgrade manifests for the specified document types.
|
|
2774
|
+
* @param documentTypes The document types whose upgrade manifests should be unregistered
|
|
2775
|
+
* @returns true if all modules were unregistered, false if any were not found
|
|
2776
|
+
**/
|
|
2777
|
+
unregisterUpgradeManifests(...documentTypes: string[]): boolean;
|
|
2778
|
+
/**
|
|
2779
|
+
* Get the upgrade manifest for a document type.
|
|
2566
2780
|
*
|
|
2567
|
-
* @param
|
|
2568
|
-
* @
|
|
2569
|
-
* @
|
|
2781
|
+
* @param documentType The document type identifier
|
|
2782
|
+
* @returns The upgrade manifest
|
|
2783
|
+
* @throws ManifestNotFoundError if no manifest is registered for the document type
|
|
2570
2784
|
*/
|
|
2571
|
-
|
|
2785
|
+
getUpgradeManifest(documentType: string): UpgradeManifest<readonly number[]>;
|
|
2572
2786
|
/**
|
|
2573
|
-
*
|
|
2787
|
+
* Compute the upgrade path from one version to another.
|
|
2788
|
+
* Returns the sequence of upgrade transitions needed.
|
|
2574
2789
|
*
|
|
2575
|
-
* @param
|
|
2576
|
-
* @
|
|
2790
|
+
* @param documentType The document type identifier
|
|
2791
|
+
* @param fromVersion The starting version
|
|
2792
|
+
* @param toVersion The target version
|
|
2793
|
+
* @returns Array of upgrade transitions in order
|
|
2794
|
+
* @throws DowngradeNotSupportedError if toVersion is less than fromVersion
|
|
2795
|
+
* @throws ManifestNotFoundError if no upgrade manifest is registered
|
|
2796
|
+
* @throws MissingUpgradeTransitionError if any transition in the path is missing
|
|
2577
2797
|
*/
|
|
2578
|
-
|
|
2798
|
+
computeUpgradePath(documentType: string, fromVersion: number, toVersion: number): UpgradeTransition[];
|
|
2579
2799
|
/**
|
|
2580
|
-
*
|
|
2581
|
-
*
|
|
2800
|
+
* Get the upgrade reducer for a single-step version transition.
|
|
2801
|
+
*
|
|
2802
|
+
* @param documentType The document type identifier
|
|
2803
|
+
* @param fromVersion The starting version
|
|
2804
|
+
* @param toVersion The target version (must be fromVersion + 1)
|
|
2805
|
+
* @returns The upgrade reducer function
|
|
2806
|
+
* @throws InvalidUpgradeStepError if toVersion is not fromVersion + 1
|
|
2807
|
+
* @throws ManifestNotFoundError if no upgrade manifest is registered
|
|
2808
|
+
* @throws MissingUpgradeTransitionError if the transition is not found
|
|
2582
2809
|
*/
|
|
2583
|
-
|
|
2810
|
+
getUpgradeReducer(documentType: string, fromVersion: number, toVersion: number): UpgradeReducer<any, any>;
|
|
2584
2811
|
}
|
|
2585
2812
|
//#endregion
|
|
2586
|
-
//#region src/
|
|
2813
|
+
//#region src/cache/buffer/ring-buffer.d.ts
|
|
2587
2814
|
/**
|
|
2588
|
-
*
|
|
2589
|
-
*
|
|
2590
|
-
*
|
|
2815
|
+
* RingBuffer is a generic circular buffer implementation that stores a fixed number
|
|
2816
|
+
* of items. When the buffer is full, new items overwrite the oldest items.
|
|
2817
|
+
*
|
|
2818
|
+
* This implementation maintains O(1) time complexity for push operations and provides
|
|
2819
|
+
* items in chronological order (oldest to newest) via getAll().
|
|
2820
|
+
*
|
|
2821
|
+
* @template T - The type of items stored in the buffer
|
|
2591
2822
|
*/
|
|
2592
|
-
|
|
2823
|
+
declare class RingBuffer<T> {
|
|
2824
|
+
private buffer;
|
|
2825
|
+
private head;
|
|
2826
|
+
private size;
|
|
2827
|
+
private capacity;
|
|
2828
|
+
constructor(capacity: number);
|
|
2593
2829
|
/**
|
|
2594
|
-
*
|
|
2595
|
-
*
|
|
2596
|
-
*
|
|
2597
|
-
* @param job - The job to add to the queue
|
|
2598
|
-
* @returns Promise that resolves when the job is queued
|
|
2830
|
+
* Adds an item to the buffer. If the buffer is full, overwrites the oldest item.
|
|
2831
|
+
*
|
|
2832
|
+
* @param item - The item to add
|
|
2599
2833
|
*/
|
|
2600
|
-
|
|
2834
|
+
push(item: T): void;
|
|
2601
2835
|
/**
|
|
2602
|
-
*
|
|
2603
|
-
*
|
|
2604
|
-
* @
|
|
2605
|
-
* @param branch - The branch to get jobs for
|
|
2606
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2607
|
-
* @returns Promise that resolves to the next job execution handle or null if no jobs available
|
|
2836
|
+
* Returns all items in the buffer in chronological order (oldest to newest).
|
|
2837
|
+
*
|
|
2838
|
+
* @returns Array of items in insertion order
|
|
2608
2839
|
*/
|
|
2609
|
-
|
|
2840
|
+
getAll(): T[];
|
|
2610
2841
|
/**
|
|
2611
|
-
*
|
|
2612
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2613
|
-
* @returns Promise that resolves to the next job execution handle or null if no jobs available
|
|
2842
|
+
* Clears all items from the buffer.
|
|
2614
2843
|
*/
|
|
2615
|
-
|
|
2844
|
+
clear(): void;
|
|
2616
2845
|
/**
|
|
2617
|
-
*
|
|
2618
|
-
* Walks ready sub-queue heads in queue insertion order, skips heads whose document
|
|
2619
|
-
* is currently executing (same isDocumentExecuting gate as dequeueNext), and returns
|
|
2620
|
-
* the first head for which predicate returns true.
|
|
2621
|
-
* Returns null when paused, when nothing matches, or when the queue is empty.
|
|
2622
|
-
* Rejects if signal is already aborted.
|
|
2623
|
-
* @param predicate - Filter applied to JobRoutingMeta of each candidate head
|
|
2624
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2625
|
-
* @returns Promise that resolves to the first matching job execution handle or null
|
|
2846
|
+
* Gets the current number of items in the buffer.
|
|
2626
2847
|
*/
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2848
|
+
get length(): number;
|
|
2849
|
+
}
|
|
2850
|
+
//#endregion
|
|
2851
|
+
//#region src/cache/kysely-write-cache.d.ts
|
|
2852
|
+
type DocumentStream = {
|
|
2853
|
+
key: string;
|
|
2854
|
+
ringBuffer: RingBuffer<CachedSnapshot>;
|
|
2855
|
+
};
|
|
2856
|
+
/**
|
|
2857
|
+
* In-memory write cache with keyframe persistence for PHDocuments.
|
|
2858
|
+
*
|
|
2859
|
+
* Caches document snapshots in ring buffers with LRU eviction. On cache miss,
|
|
2860
|
+
* rebuilds documents from nearest keyframe or full operation history.
|
|
2861
|
+
*
|
|
2862
|
+
* **Performance Characteristics:**
|
|
2863
|
+
* - Cache hit: O(1) lookup in ring buffer
|
|
2864
|
+
* - Cold miss: O(n) where n is total operation count, or O(k) where k is operations since keyframe
|
|
2865
|
+
* - Warm miss: O(m) where m is operations since cached revision
|
|
2866
|
+
* - Eviction: O(1) for LRU tracking and removal
|
|
2867
|
+
*
|
|
2868
|
+
* **Thread Safety:**
|
|
2869
|
+
* Not thread-safe. Designed for single-threaded job executor environment.
|
|
2870
|
+
* External synchronization required for concurrent access across multiple executors.
|
|
2871
|
+
*
|
|
2872
|
+
* **Example:**
|
|
2873
|
+
* ```typescript
|
|
2874
|
+
* const cache = new KyselyWriteCache(
|
|
2875
|
+
* keyframeStore,
|
|
2876
|
+
* operationStore,
|
|
2877
|
+
* registry,
|
|
2878
|
+
* { maxDocuments: 1000, ringBufferSize: 10, keyframeInterval: 10 }
|
|
2879
|
+
* );
|
|
2880
|
+
*
|
|
2881
|
+
* await cache.startup();
|
|
2882
|
+
*
|
|
2883
|
+
* // Retrieve or rebuild document
|
|
2884
|
+
* const doc = await cache.getState(docId, docType, scope, branch, revision);
|
|
2885
|
+
*
|
|
2886
|
+
* // Cache result after job execution
|
|
2887
|
+
* cache.putState(docId, docType, scope, branch, newRevision, updatedDoc);
|
|
2888
|
+
*
|
|
2889
|
+
* await cache.shutdown();
|
|
2890
|
+
* ```
|
|
2891
|
+
*/
|
|
2892
|
+
declare class KyselyWriteCache implements IWriteCache {
|
|
2893
|
+
private streams;
|
|
2894
|
+
private lruTracker;
|
|
2895
|
+
private keyframeStore;
|
|
2896
|
+
private operationStore;
|
|
2897
|
+
private registry;
|
|
2898
|
+
private config;
|
|
2899
|
+
constructor(keyframeStore: IKeyframeStore, operationStore: IOperationStore, registry: IDocumentModelRegistry, config: WriteCacheConfig);
|
|
2900
|
+
withScopedStores(operationStore: IOperationStore, keyframeStore: IKeyframeStore): KyselyWriteCache;
|
|
2901
|
+
/**
|
|
2902
|
+
* Initializes the write cache.
|
|
2903
|
+
* Currently a no-op as keyframe store lifecycle is managed externally.
|
|
2904
|
+
*/
|
|
2905
|
+
startup(): Promise<void>;
|
|
2906
|
+
/**
|
|
2907
|
+
* Shuts down the write cache.
|
|
2908
|
+
* Currently a no-op as keyframe store lifecycle is managed externally.
|
|
2909
|
+
*/
|
|
2910
|
+
shutdown(): Promise<void>;
|
|
2911
|
+
/**
|
|
2912
|
+
* Retrieves document state at a specific revision from cache or rebuilds it.
|
|
2913
|
+
*
|
|
2914
|
+
* Note: this returns a _shallow_ copy of the document.
|
|
2915
|
+
*
|
|
2916
|
+
* Cache hit path: Returns cached snapshot if available (O(1))
|
|
2917
|
+
* Warm miss path: Rebuilds from cached base revision + incremental ops
|
|
2918
|
+
* Cold miss path: Rebuilds from keyframe or from scratch using all operations
|
|
2919
|
+
*
|
|
2920
|
+
* @param documentId - The document identifier
|
|
2921
|
+
* @param scope - The operation scope
|
|
2922
|
+
* @param branch - The operation branch
|
|
2923
|
+
* @param targetRevision - The target revision, or undefined for newest
|
|
2924
|
+
* @param signal - Optional abort signal to cancel the operation
|
|
2925
|
+
* @returns The document at the target revision
|
|
2926
|
+
* @throws {Error} "Operation aborted" if signal is aborted
|
|
2927
|
+
* @throws {ModuleNotFoundError} If document type not registered in registry
|
|
2928
|
+
* @throws {Error} "Failed to rebuild document" if operation store fails
|
|
2929
|
+
* @throws {Error} If reducer throws during operation application
|
|
2930
|
+
* @throws {Error} If document serialization fails
|
|
2931
|
+
*/
|
|
2932
|
+
getState(documentId: string, scope: string, branch: string, targetRevision?: number, signal?: AbortSignal): Promise<PHDocument>;
|
|
2933
|
+
/**
|
|
2934
|
+
* Stores a document snapshot in the cache at a specific revision.
|
|
2935
|
+
*
|
|
2936
|
+
* The cached document is a shallow copy of the input with its operation history
|
|
2937
|
+
* truncated to the last operation per scope and its clipboard cleared. This keeps
|
|
2938
|
+
* memory use and copy costs constant regardless of operation count. Consumers of
|
|
2939
|
+
* getState() must not rely on the full operation history being present; the only
|
|
2940
|
+
* guaranteed invariant is that operations[scope].at(-1) reflects the latest
|
|
2941
|
+
* operation index for each scope.
|
|
2942
|
+
*
|
|
2943
|
+
* Updates LRU tracker and may evict least recently used stream if at capacity.
|
|
2944
|
+
* Asynchronously persists keyframes at configured intervals (fire-and-forget).
|
|
2945
|
+
*
|
|
2946
|
+
* @param documentId - The document identifier
|
|
2947
|
+
* @param scope - The operation scope
|
|
2948
|
+
* @param branch - The operation branch
|
|
2949
|
+
* @param revision - The revision number
|
|
2950
|
+
* @param document - The document to cache
|
|
2951
|
+
* @throws {Error} If document serialization fails
|
|
2952
|
+
*/
|
|
2953
|
+
putState(documentId: string, scope: string, branch: string, revision: number, document: PHDocument, position: SnapshotPosition): void;
|
|
2954
|
+
private store;
|
|
2955
|
+
/**
|
|
2956
|
+
* Invalidates cached document streams.
|
|
2957
|
+
*
|
|
2958
|
+
* Supports three invalidation scopes:
|
|
2959
|
+
* - Document-level: invalidate(documentId) - removes all streams for document
|
|
2960
|
+
* - Scope-level: invalidate(documentId, scope) - removes all branches for scope
|
|
2961
|
+
* - Stream-level: invalidate(documentId, scope, branch) - removes specific stream
|
|
2962
|
+
*
|
|
2963
|
+
* @param documentId - The document identifier
|
|
2964
|
+
* @param scope - Optional scope to narrow invalidation
|
|
2965
|
+
* @param branch - Optional branch to narrow invalidation (requires scope)
|
|
2966
|
+
* @returns The number of streams evicted
|
|
2967
|
+
*/
|
|
2968
|
+
invalidate(documentId: string, scope?: string, branch?: string): number;
|
|
2969
|
+
/**
|
|
2970
|
+
* Clears the entire cache, removing all cached document streams.
|
|
2971
|
+
* Resets LRU tracking state. This operation always succeeds.
|
|
2972
|
+
*/
|
|
2973
|
+
clear(): void;
|
|
2974
|
+
/**
|
|
2975
|
+
* Retrieves a specific stream for a document. Exposed on the implementation
|
|
2976
|
+
* for testing, but not on the interface.
|
|
2977
|
+
*
|
|
2978
|
+
* @internal
|
|
2979
|
+
*/
|
|
2980
|
+
getStream(documentId: string, scope: string, branch: string): DocumentStream | undefined;
|
|
2981
|
+
private findNearestKeyframe;
|
|
2982
|
+
/**
|
|
2983
|
+
* Rebuilds a scope from a keyframe or from the whole operation history.
|
|
2984
|
+
*
|
|
2985
|
+
* The document scope is always rebuilt first, because it carries the type,
|
|
2986
|
+
* the upgrades and the deletion marker. Its version-changing upgrades are not
|
|
2987
|
+
* applied there though: an upgrade reducer must see the state the requested
|
|
2988
|
+
* scope has reached at that upgrade's boundary, so each one is held back and
|
|
2989
|
+
* applied when the replay below crosses the boundary that
|
|
2990
|
+
* resolveModuleVersionForOp derives from it. Upgrades whose boundary lies past
|
|
2991
|
+
* the last replayed operation are applied at the end. Creation-time 0->N seed
|
|
2992
|
+
* upgrades carry the initial state, so they still apply immediately.
|
|
2993
|
+
*/
|
|
2994
|
+
private coldMissRebuild;
|
|
2995
|
+
/**
|
|
2996
|
+
* Applies and removes every held-back upgrade whose target version is at or
|
|
2997
|
+
* below `throughVersion`, in the order the document scope recorded them.
|
|
2998
|
+
*/
|
|
2999
|
+
private applyPendingUpgrades;
|
|
3000
|
+
/**
|
|
3001
|
+
* Applies the remaining held-back upgrades after the requested scope's
|
|
3002
|
+
* replay has finished. A head read applies them all. A positional read
|
|
3003
|
+
* applies only those whose boundary for this scope lies at or before the
|
|
3004
|
+
* target position: applying a later one would label migrated state with a
|
|
3005
|
+
* pre-upgrade revision, and a keyframe stored from that poisons every
|
|
3006
|
+
* rebuild that resumes from it. Boundaries come from the upgrade's revision
|
|
3007
|
+
* snapshot; an upgrade without one records no position for this scope, and
|
|
3008
|
+
* the replay loop not having crossed it already places it past the target.
|
|
3009
|
+
*/
|
|
3010
|
+
private applyTailPendingUpgrades;
|
|
3011
|
+
/**
|
|
3012
|
+
* Applies one held-back upgrade, then re-applies the deletes the document
|
|
3013
|
+
* scope recorded after it so the hold-back cannot invert their order.
|
|
3014
|
+
*/
|
|
3015
|
+
private applyPendingUpgrade;
|
|
3016
|
+
/**
|
|
3017
|
+
* Copies the current document revisions onto the document. Overwrites the
|
|
3018
|
+
* requested scope revision with the target revision, if provided.
|
|
3019
|
+
*/
|
|
3020
|
+
private stampRevisions;
|
|
3021
|
+
/** The stored operation at `index`, or undefined if it is no longer there. */
|
|
3022
|
+
private operationAt;
|
|
3023
|
+
/**
|
|
3024
|
+
* Resolves which module version to use for a given operation in phase 2.
|
|
3025
|
+
*
|
|
3026
|
+
* Uses the validated-upgrade boundary rules from D7:
|
|
3027
|
+
* - If `input.revision` is present: op.index < revision[scope] → before the upgrade boundary
|
|
3028
|
+
* - Otherwise: timestamp fallback
|
|
3029
|
+
* - Falls back to final module version when neither is decidable
|
|
3030
|
+
*/
|
|
3031
|
+
private resolveModuleVersionForOp;
|
|
3032
|
+
private warmMissRebuild;
|
|
3033
|
+
private findNearestOlderSnapshot;
|
|
3034
|
+
private makeStreamKey;
|
|
3035
|
+
private getOrCreateStream;
|
|
3036
|
+
private isKeyframeRevision;
|
|
3037
|
+
}
|
|
3038
|
+
//#endregion
|
|
3039
|
+
//#region src/storage/kysely/store.d.ts
|
|
3040
|
+
declare class KyselyOperationStore implements IOperationStore {
|
|
3041
|
+
private db;
|
|
3042
|
+
private trx?;
|
|
3043
|
+
constructor(db: Kysely<Database$1>);
|
|
3044
|
+
private get queryExecutor();
|
|
3045
|
+
withTransaction(trx: Transaction<Database$1>): KyselyOperationStore;
|
|
3046
|
+
apply(documentId: string, documentType: string, scope: string, branch: string, revision: number, fn: (txn: AtomicTxn) => void | Promise<void>, signal?: AbortSignal, condition?: AppendCondition): Promise<Operation[]>;
|
|
3047
|
+
private resolveUniqueConstraint;
|
|
3048
|
+
private executeApply;
|
|
3049
|
+
/**
|
|
3050
|
+
* Locks the written stream and every read-set stream, in sorted key order
|
|
3051
|
+
* so that overlapping concurrent appends serialize rather than deadlock.
|
|
3052
|
+
* The locks are still taken one row at a time, so the query preserves that
|
|
3053
|
+
* order. It must stay separate from the guarded insert, which would
|
|
3054
|
+
* otherwise read a snapshot taken before the locks were held.
|
|
3055
|
+
*/
|
|
3056
|
+
private acquireStreamLocks;
|
|
3057
|
+
/**
|
|
3058
|
+
* Inserts the staged operations with the condition compiled in as a WHERE
|
|
3059
|
+
* NOT EXISTS guard, making the check and the append one statement. Returns
|
|
3060
|
+
* the rows inserted; zero means the guard failed and nothing was written.
|
|
3061
|
+
*/
|
|
3062
|
+
private insertGuarded;
|
|
3063
|
+
private findIdempotentReplay;
|
|
3064
|
+
getSince(documentId: string, scope: string, branch: string, revision: number, filter?: OperationFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<Operation>>;
|
|
3065
|
+
getSinceId(id: number, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<OperationWithContext$1>>;
|
|
3066
|
+
getConflicting(documentId: string, scope: string, branch: string, minTimestamp: string, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<Operation>>;
|
|
3067
|
+
getRevisions(documentId: string, branch: string, signal?: AbortSignal): Promise<DocumentRevisions>;
|
|
3068
|
+
getStreamLatestTimestamp(documentId: string, scope: string, branch: string, signal?: AbortSignal): Promise<string | undefined>;
|
|
3069
|
+
private rowToOperation;
|
|
3070
|
+
private rowToOperationWithContext;
|
|
3071
|
+
}
|
|
3072
|
+
//#endregion
|
|
3073
|
+
//#region src/storage/kysely/keyframe-store.d.ts
|
|
3074
|
+
declare class KyselyKeyframeStore implements IKeyframeStore {
|
|
3075
|
+
private db;
|
|
3076
|
+
private trx?;
|
|
3077
|
+
constructor(db: Kysely<Database$1>);
|
|
3078
|
+
private get queryExecutor();
|
|
3079
|
+
withTransaction(trx: Transaction<Database$1>): KyselyKeyframeStore;
|
|
3080
|
+
putKeyframe(documentId: string, scope: string, branch: string, revision: number, document: PHDocument, signal?: AbortSignal): Promise<void>;
|
|
3081
|
+
findNearestKeyframe(documentId: string, scope: string, branch: string, targetRevision: number, signal?: AbortSignal): Promise<{
|
|
3082
|
+
revision: number;
|
|
3083
|
+
document: PHDocument;
|
|
3084
|
+
} | undefined>;
|
|
3085
|
+
listKeyframes(documentId: string, scope?: string, branch?: string, signal?: AbortSignal): Promise<Array<{
|
|
3086
|
+
scope: string;
|
|
3087
|
+
branch: string;
|
|
3088
|
+
revision: number;
|
|
3089
|
+
document: PHDocument;
|
|
3090
|
+
}>>;
|
|
3091
|
+
deleteKeyframes(documentId: string, scope?: string, branch?: string, signal?: AbortSignal): Promise<number>;
|
|
3092
|
+
}
|
|
3093
|
+
//#endregion
|
|
3094
|
+
//#region src/executor/execution-scope.d.ts
|
|
3095
|
+
interface ExecutionStores {
|
|
3096
|
+
operationStore: IOperationStore;
|
|
3097
|
+
operationIndex: IOperationIndex;
|
|
3098
|
+
writeCache: IWriteCache;
|
|
3099
|
+
documentMetaCache: IDocumentMetaCache;
|
|
3100
|
+
collectionMembershipCache: ICollectionMembershipCache;
|
|
3101
|
+
}
|
|
3102
|
+
interface IExecutionScope {
|
|
3103
|
+
run<T>(fn: (stores: ExecutionStores) => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
3104
|
+
}
|
|
3105
|
+
//#endregion
|
|
3106
|
+
//#region src/executor/types.d.ts
|
|
3107
|
+
/**
|
|
3108
|
+
* Represents the result of a job execution
|
|
3109
|
+
*/
|
|
3110
|
+
type JobResult = {
|
|
3111
|
+
/** The job that was executed */job: Job; /** Whether the job executed successfully */
|
|
3112
|
+
success: boolean; /** Error if the job failed */
|
|
3113
|
+
error?: Error; /** The operations generated from the actions (if successful) */
|
|
3114
|
+
operations?: Operation[];
|
|
3115
|
+
/**
|
|
3116
|
+
* Operations with context (includes ephemeral resultingState).
|
|
3117
|
+
* Used for emitting to IDocumentView via event bus.
|
|
3118
|
+
*/
|
|
3119
|
+
operationsWithContext?: OperationWithContext$1[]; /** Timestamp when the job execution completed */
|
|
3120
|
+
completedAt?: string; /** Duration of job execution in milliseconds */
|
|
3121
|
+
duration?: number; /** Any additional metadata from the execution */
|
|
3122
|
+
metadata?: Record<string, any>;
|
|
3123
|
+
};
|
|
3124
|
+
/**
|
|
3125
|
+
* Enforcement the reactor performs, each off by default.
|
|
3126
|
+
*
|
|
3127
|
+
* An evaluation made while replaying is part of the document's history, so two
|
|
3128
|
+
* reactors that share documents and disagree on these diverge. A flag is turned
|
|
3129
|
+
* on for a set of reactors that sync with each other, not for one node.
|
|
3130
|
+
*/
|
|
3131
|
+
type ReactorFeatureFlags = {
|
|
3132
|
+
/**
|
|
3133
|
+
* Decide whether an operation may be admitted by building a decision model
|
|
3134
|
+
* over the document stream, rather than reading the deleted flag from the
|
|
3135
|
+
* document meta cache. Deletion then takes effect from the deleting
|
|
3136
|
+
* operation's position rather than for the whole document.
|
|
3137
|
+
*/
|
|
3138
|
+
documentDecisions: boolean;
|
|
3139
|
+
/**
|
|
3140
|
+
* Evaluate the auth policy by reading the auth scope as a second projection.
|
|
3141
|
+
* Requires documentDecisions.
|
|
3142
|
+
*/
|
|
3143
|
+
authEnforcement: boolean;
|
|
3144
|
+
/**
|
|
3145
|
+
* Match { group } principals by folding the referenced PHGroup documents as
|
|
3146
|
+
* derived projections. Requires authEnforcement.
|
|
3147
|
+
*/
|
|
3148
|
+
authGroups: boolean;
|
|
3149
|
+
/**
|
|
3150
|
+
* Evaluate `where` clauses and { match } principals against the executing
|
|
3151
|
+
* scope's state, the subject, and the action input. Requires authGroups.
|
|
3152
|
+
*/
|
|
3153
|
+
authConditions: boolean;
|
|
3154
|
+
};
|
|
3155
|
+
/**
|
|
3156
|
+
* Configuration options for the job executor
|
|
3157
|
+
*/
|
|
3158
|
+
type JobExecutorConfig = {
|
|
3159
|
+
/** Feature flags; anything unset is off. */featureFlags?: Partial<ReactorFeatureFlags>; /** Maximum number of conflicting operations to skip when reshuffling. */
|
|
3160
|
+
maxSkipThreshold?: number; /** Maximum number of concurrent jobs to execute */
|
|
3161
|
+
maxConcurrency?: number; /** Maximum time in milliseconds a job can run before being considered timed out */
|
|
3162
|
+
jobTimeoutMs?: number; /** Base delay in milliseconds for exponential backoff retries */
|
|
3163
|
+
retryBaseDelayMs?: number; /** Maximum delay in milliseconds for exponential backoff retries */
|
|
3164
|
+
retryMaxDelayMs?: number;
|
|
3165
|
+
/** Maximum elapsed milliseconds before yielding to the main thread between actions.
|
|
3166
|
+
* Keeps the UI responsive when processing large batches. */
|
|
3167
|
+
yieldDeadlineMs?: number;
|
|
3168
|
+
};
|
|
3169
|
+
/**
|
|
3170
|
+
* Event types for the job executor
|
|
3171
|
+
*/
|
|
3172
|
+
declare const JobExecutorEventTypes: {
|
|
3173
|
+
readonly JOB_STARTED: 20000;
|
|
3174
|
+
readonly JOB_COMPLETED: 20001;
|
|
3175
|
+
readonly JOB_FAILED: 20002;
|
|
3176
|
+
readonly EXECUTOR_STARTED: 20003;
|
|
3177
|
+
readonly EXECUTOR_STOPPED: 20004;
|
|
3178
|
+
};
|
|
3179
|
+
/**
|
|
3180
|
+
* Event data for job execution events
|
|
3181
|
+
*/
|
|
3182
|
+
type JobStartedEvent = {
|
|
3183
|
+
job: Job;
|
|
3184
|
+
startedAt: string;
|
|
3185
|
+
/**
|
|
3186
|
+
* Identifier of the executor that took the job. For the worker pool this is
|
|
3187
|
+
* the thread-worker id (e.g. "reactor-worker-3"); for the in-process simple
|
|
3188
|
+
* manager it is "in-process-<index>". Optional for backwards compatibility
|
|
3189
|
+
* with consumers built before the field was added.
|
|
3190
|
+
*/
|
|
3191
|
+
workerId?: string;
|
|
3192
|
+
};
|
|
3193
|
+
type JobCompletedEvent = {
|
|
3194
|
+
job: Job;
|
|
3195
|
+
result: JobResult; /** See {@link JobStartedEvent.workerId}. */
|
|
3196
|
+
workerId?: string;
|
|
3197
|
+
};
|
|
3198
|
+
type JobFailedEvent = {
|
|
3199
|
+
job: Job;
|
|
3200
|
+
error: string;
|
|
3201
|
+
willRetry: boolean;
|
|
3202
|
+
retryCount: number; /** See {@link JobStartedEvent.workerId}. */
|
|
3203
|
+
workerId?: string;
|
|
3204
|
+
};
|
|
3205
|
+
type ExecutorStartedEvent = {
|
|
3206
|
+
config: JobExecutorConfig;
|
|
3207
|
+
startedAt: string;
|
|
3208
|
+
};
|
|
3209
|
+
type ExecutorStoppedEvent = {
|
|
3210
|
+
stoppedAt: string;
|
|
3211
|
+
graceful: boolean;
|
|
3212
|
+
};
|
|
3213
|
+
/**
|
|
3214
|
+
* Status information for the job executor manager
|
|
3215
|
+
*/
|
|
3216
|
+
type ExecutorManagerStatus = {
|
|
3217
|
+
/** Whether the manager is currently running */isRunning: boolean; /** Number of executor instances managed */
|
|
3218
|
+
numExecutors: number; /** Number of jobs currently being processed */
|
|
3219
|
+
activeJobs: number; /** Total number of jobs processed since start */
|
|
3220
|
+
totalJobsProcessed: number;
|
|
3221
|
+
};
|
|
3222
|
+
//#endregion
|
|
3223
|
+
//#region src/decision/types.d.ts
|
|
3224
|
+
/** One operation stream. */
|
|
3225
|
+
type StreamQuery = {
|
|
3226
|
+
documentId: string;
|
|
3227
|
+
branch: string;
|
|
3228
|
+
scope: string;
|
|
3229
|
+
};
|
|
3230
|
+
/**
|
|
3231
|
+
* What building a decision model reads a stream's state through.
|
|
3232
|
+
*
|
|
3233
|
+
* `IWriteCache` satisfies this and is what the write paths pass. The read path
|
|
3234
|
+
* cannot: the write cache is a write-side projection invalidated by the process
|
|
3235
|
+
* that runs the executor, so a reactor whose executors live in worker processes
|
|
3236
|
+
* holds state in its parent that no commit ever invalidates. A read there would
|
|
3237
|
+
* decide against a policy arbitrarily far behind the one the write paths
|
|
3238
|
+
* enforce. Reads therefore pass a reader backed by the read side.
|
|
3239
|
+
*/
|
|
3240
|
+
interface IStreamStateReader {
|
|
3241
|
+
getState(documentId: string, scope: string, branch: string, targetRevision?: number, signal?: AbortSignal): Promise<PHDocument>;
|
|
3242
|
+
}
|
|
3243
|
+
/** The document and branch a decision model is built for. */
|
|
3244
|
+
type DecisionTarget = {
|
|
3245
|
+
documentId: string;
|
|
3246
|
+
branch: string;
|
|
3247
|
+
};
|
|
3248
|
+
/**
|
|
3249
|
+
* What a decision's conditions may read beyond the projections: the executing
|
|
3250
|
+
* scope's own state and the attempted action's input. Populated only while
|
|
3251
|
+
* authConditions is on; otherwise both stay undefined and conditional grants
|
|
3252
|
+
* never apply.
|
|
3253
|
+
*/
|
|
3254
|
+
type DecisionContext = {
|
|
3255
|
+
scopeState: unknown;
|
|
3256
|
+
actionInput?: unknown;
|
|
3257
|
+
};
|
|
3258
|
+
/** A statically-queried stream's operations, named after its projection. */
|
|
3259
|
+
type StreamHistory = {
|
|
3260
|
+
name: string;
|
|
3261
|
+
operations: Operation[];
|
|
3262
|
+
};
|
|
3263
|
+
/**
|
|
3264
|
+
* A named stream whose value in the model is that scope's state from the
|
|
3265
|
+
* document rebuild the reactor already performs. A derived query may read
|
|
3266
|
+
* only statically-queried projections, so composition is one layer deep.
|
|
3267
|
+
*/
|
|
3268
|
+
type Projection<M> = {
|
|
3269
|
+
query: StreamQuery | ((model: Partial<M>) => StreamQuery[]);
|
|
3270
|
+
/**
|
|
3271
|
+
* For a derived projection, the streams it may read anywhere in an
|
|
3272
|
+
* evaluated range, derived from the statically-queried streams' operations
|
|
3273
|
+
* (including the operations under evaluation). A positional walk cannot use
|
|
3274
|
+
* `query`, because the folded state it depends on changes over the range;
|
|
3275
|
+
* this over-approximates by design, since a stream referenced at any
|
|
3276
|
+
* position stays readable when the earlier range is re-evaluated even if a
|
|
3277
|
+
* later operation removes the reference. Ignored on static projections.
|
|
3278
|
+
*/
|
|
3279
|
+
queryOverHistory?: (reads: StreamHistory[]) => StreamQuery[];
|
|
3280
|
+
/**
|
|
3281
|
+
* Action types in this stream that can change an evaluation. Reads of the stream
|
|
3282
|
+
* are filtered to these, so anything left out is invisible to a decision.
|
|
3283
|
+
*/
|
|
3284
|
+
decidingActions: string[]; /** Applies one of this stream's operations while deciding. */
|
|
3285
|
+
apply: (document: PHDocument, operation: Operation) => PHDocument;
|
|
3286
|
+
};
|
|
3287
|
+
/**
|
|
3288
|
+
* The outcome of evaluating one operation. A refusal carries the reason it is
|
|
3289
|
+
* recorded with, because a model has more than one way to refuse.
|
|
3290
|
+
*/
|
|
3291
|
+
type Evaluation = {
|
|
3292
|
+
decision: "allow";
|
|
3293
|
+
} | {
|
|
3294
|
+
decision: "deny";
|
|
3295
|
+
reason: string;
|
|
3296
|
+
};
|
|
3297
|
+
/** Projections plus a decision function over the built model. */
|
|
3298
|
+
type DecisionModel<M> = {
|
|
3299
|
+
projections: { [K in keyof M]: Projection<M> };
|
|
3300
|
+
/**
|
|
3301
|
+
* Present when decide reads the executing scope's state through the
|
|
3302
|
+
* decision context. A positional walk then folds the evaluated stream with
|
|
3303
|
+
* this, from its base state through every effective operation, so
|
|
3304
|
+
* conditions read the state as it stood at each operation's position
|
|
3305
|
+
* rather than at the head.
|
|
3306
|
+
*/
|
|
3307
|
+
foldEvaluatedScope?: (document: PHDocument, operation: Operation) => PHDocument;
|
|
3308
|
+
/**
|
|
3309
|
+
* Whether or not this model decides about operations in a given scope. That
|
|
3310
|
+
* is, a scope it reads is not necessarily one it evaluates, and vise-versa.
|
|
3311
|
+
*/
|
|
3312
|
+
evaluatesScope(scope: string): boolean;
|
|
3313
|
+
decide(model: M, subject: AuthSubject, request: AuthRequest, ctx: DecisionContext): Evaluation;
|
|
3314
|
+
};
|
|
3315
|
+
/** A built model plus the read-set condition recording what the build read. */
|
|
3316
|
+
type BuiltDecisionModel<M> = {
|
|
3317
|
+
model: M;
|
|
3318
|
+
appendCondition: AppendCondition;
|
|
3319
|
+
};
|
|
3320
|
+
//#endregion
|
|
3321
|
+
//#region src/decision/document-decision-model.d.ts
|
|
3322
|
+
/** What the document decision model reads: the target's document scope. */
|
|
3323
|
+
type DocumentDecisionModel = {
|
|
3324
|
+
document: PHDocumentState;
|
|
3325
|
+
};
|
|
3326
|
+
/**
|
|
3327
|
+
* The simplest decision model: one projection over the document scope, which
|
|
3328
|
+
* rejects on a deleted document.
|
|
3329
|
+
*/
|
|
3330
|
+
declare function documentDecisionModel(target: DecisionTarget): DecisionModel<DocumentDecisionModel>;
|
|
3331
|
+
//#endregion
|
|
3332
|
+
//#region src/decision/registered-model.d.ts
|
|
3333
|
+
/**
|
|
3334
|
+
* A model this reactor can register. Every one carries the document projection,
|
|
3335
|
+
* because admission reads the version and the deletion timestamp off it; a model
|
|
3336
|
+
* with more projections than that is still assignable here.
|
|
3337
|
+
*/
|
|
3338
|
+
type RegisteredDecisionModel = (target: DecisionTarget) => DecisionModel<DocumentDecisionModel>;
|
|
3339
|
+
/** What admission needs out of a model built at the stream heads. */
|
|
3340
|
+
type AdmissionDecision = {
|
|
3341
|
+
evaluation: Evaluation;
|
|
3342
|
+
appendCondition: AppendCondition;
|
|
3343
|
+
documentVersion: number;
|
|
3344
|
+
deletedAtUtcIso: string | null;
|
|
3345
|
+
};
|
|
3346
|
+
/**
|
|
3347
|
+
* What decideAtHead resolves a condition context from: the action's input,
|
|
3348
|
+
* with the executing scope's state read at the head. Supplied only while
|
|
3349
|
+
* authConditions is on.
|
|
3350
|
+
*/
|
|
3351
|
+
type AdmissionConditions = {
|
|
3352
|
+
actionInput?: unknown;
|
|
3353
|
+
};
|
|
3354
|
+
/**
|
|
3355
|
+
* Builds the model at the stream heads and decides one request against it. The
|
|
3356
|
+
* append condition it returns is the read-set the store enforces at write time.
|
|
3357
|
+
*
|
|
3358
|
+
* With `conditions` supplied, the executing scope's state is read at the head
|
|
3359
|
+
* for `doc.<scope>.*` paths. That read carries no append-condition entry of
|
|
3360
|
+
* its own: the written stream's expected-revision check already refuses a
|
|
3361
|
+
* write whose scope grew between the read and the append.
|
|
3362
|
+
*/
|
|
3363
|
+
declare function decideAtHead(model: RegisteredDecisionModel, cache: IWriteCache, target: DecisionTarget, subject: AuthSubject, request: AuthRequest, signal?: AbortSignal, conditions?: AdmissionConditions): Promise<AdmissionDecision>;
|
|
3364
|
+
/**
|
|
3365
|
+
* The model this reactor enforces. With `authEnforcement` off the auth scope is
|
|
3366
|
+
* absent from every append condition and no load walks it; with `authGroups`
|
|
3367
|
+
* on, the group documents the grant list names join the read-set and the
|
|
3368
|
+
* registry supplies the reducer that folds them.
|
|
3369
|
+
*/
|
|
3370
|
+
declare function selectDecisionModel(flags: ReactorFeatureFlags, registry: IDocumentModelRegistry): RegisteredDecisionModel;
|
|
3371
|
+
//#endregion
|
|
3372
|
+
//#region src/decision/read-gate.d.ts
|
|
3373
|
+
/**
|
|
3374
|
+
* Scopes every holder of a document may read, whatever the grants say. Denying
|
|
3375
|
+
* the policy itself would let a replica sync a document without it, read the
|
|
3376
|
+
* auth scope as uninitialized, and allow every operation it holds, so replicas
|
|
3377
|
+
* would diverge permanently. The document scope carries the metadata the same
|
|
3378
|
+
* argument covers. Grants gate domain-scope reads only.
|
|
3379
|
+
*/
|
|
3380
|
+
declare const ALWAYS_READABLE_SCOPES: ReadonlySet<string>;
|
|
3381
|
+
/** Whether a subject may read each scope of one document. */
|
|
3382
|
+
interface IReadGate {
|
|
3383
|
+
/**
|
|
3384
|
+
* Resolves, for one document, which of its scopes the subject may read.
|
|
3385
|
+
*
|
|
3386
|
+
* The predicate is resolved up front rather than asked per scope so that the
|
|
3387
|
+
* filtering itself stays synchronous, and so that a model backing the answer
|
|
3388
|
+
* is built once per document instead of once per scope.
|
|
3389
|
+
*/
|
|
3390
|
+
scopePredicate(document: PHDocument, subject: AuthSubject, branch: string, signal?: AbortSignal): Promise<(scope: string) => boolean>;
|
|
3391
|
+
}
|
|
3392
|
+
/**
|
|
3393
|
+
* The model reads enforce. Below `authEnforcement` there is no model to
|
|
3394
|
+
* enforce: the document-only model ignores the auth scope entirely, so reading
|
|
3395
|
+
* through it would serve every domain scope of a policied document to anyone.
|
|
3396
|
+
* Undefined therefore means "evaluate the policy alone", which is what the read
|
|
3397
|
+
* surface did before the model existed.
|
|
3398
|
+
*/
|
|
3399
|
+
declare function readDecisionModel(flags: ReactorFeatureFlags, registry: IDocumentModelRegistry): RegisteredDecisionModel | undefined;
|
|
3400
|
+
/**
|
|
3401
|
+
* Evaluates the policy on its own, with no groups map and no condition context.
|
|
3402
|
+
* A `{ group }` or conditional grant therefore never applies: an allow that
|
|
3403
|
+
* does not apply withholds access, so this cannot widen a policy, but a policy
|
|
3404
|
+
* relying on a conditional deny is weaker here than it is written.
|
|
3405
|
+
*/
|
|
3406
|
+
declare class BareReadGate implements IReadGate {
|
|
3407
|
+
scopePredicate(document: PHDocument, subject: AuthSubject): Promise<(scope: string) => boolean>;
|
|
3408
|
+
}
|
|
3409
|
+
/**
|
|
3410
|
+
* Evaluates a read against the registered decision model, built at the stream
|
|
3411
|
+
* heads. This is what makes `{ group }` principals and conditional grants apply
|
|
3412
|
+
* to a read: the model supplies the groups map and the scope's own state, the
|
|
3413
|
+
* same two things admission supplies.
|
|
3414
|
+
*
|
|
3415
|
+
* A read has no action, so a condition on `action.input.*` never holds for one.
|
|
3416
|
+
*
|
|
3417
|
+
* State is read through the read side rather than the write cache. The write
|
|
3418
|
+
* cache is invalidated by whichever process runs the executor, so a reactor
|
|
3419
|
+
* running its executors in worker processes would answer reads in the parent
|
|
3420
|
+
* from state no commit ever invalidates.
|
|
3421
|
+
*/
|
|
3422
|
+
declare class ModelReadGate implements IReadGate {
|
|
3423
|
+
private readonly model;
|
|
3424
|
+
private readonly documentView;
|
|
3425
|
+
/**
|
|
3426
|
+
* Whether a group a policy names is served to that policy's audience. Only
|
|
3427
|
+
* meaningful with `authGroups`, which is what makes a `{ group }` grant
|
|
3428
|
+
* match at all; below it the grant fails closed, so serving the roster
|
|
3429
|
+
* would publish a member list no read grant can use.
|
|
3430
|
+
*/
|
|
3431
|
+
private readonly servesGroups;
|
|
3432
|
+
private readonly operationIndex?;
|
|
3433
|
+
private readonly logger?;
|
|
3434
|
+
constructor(model: RegisteredDecisionModel, documentView: IDocumentView,
|
|
3435
|
+
/**
|
|
3436
|
+
* Whether a group a policy names is served to that policy's audience. Only
|
|
3437
|
+
* meaningful with `authGroups`, which is what makes a `{ group }` grant
|
|
3438
|
+
* match at all; below it the grant fails closed, so serving the roster
|
|
3439
|
+
* would publish a member list no read grant can use.
|
|
3440
|
+
*/
|
|
3441
|
+
|
|
3442
|
+
servesGroups: boolean, operationIndex?: IOperationIndex | undefined, logger?: ILogger | undefined);
|
|
3443
|
+
/**
|
|
3444
|
+
* A served group yields its member list and nothing else. What the audience
|
|
3445
|
+
* is owed is the state it must fold to evaluate auth with the group; a
|
|
3446
|
+
* group's other scopes are its own business and stay behind its own grants.
|
|
3447
|
+
*/
|
|
3448
|
+
scopePredicate(document: PHDocument, subject: AuthSubject, branch: string, signal?: AbortSignal): Promise<(scope: string) => boolean>;
|
|
3449
|
+
/**
|
|
3450
|
+
* Whether the subject is served this group because a policy names it.
|
|
3451
|
+
*
|
|
3452
|
+
* A replica must fold a group's membership to evaluate auth with it, so a
|
|
3453
|
+
* group a grant names is served to the audience of the document that names
|
|
3454
|
+
* it, whatever the group's own read grants say. Naming a group in a policy
|
|
3455
|
+
* publishes its roster to that policy's audience; a group whose membership
|
|
3456
|
+
* must stay confidential does not belong in a grant.
|
|
3457
|
+
*
|
|
3458
|
+
* The referencing document's own domain scopes are the test. Its `auth` and
|
|
3459
|
+
* `document` scopes are readable by every holder, so testing those would
|
|
3460
|
+
* serve every referenced group to everybody.
|
|
3461
|
+
*
|
|
3462
|
+
* One level only. A referencer that is itself a group is skipped, and a
|
|
3463
|
+
* referencer's own readability is decided from its policy alone, so a
|
|
3464
|
+
* reference cycle terminates. Cycles are reachable: the reference relation
|
|
3465
|
+
* is recorded from an operation's input, including one later stored denied,
|
|
3466
|
+
* so a refused grant naming a group from inside another group leaves a row
|
|
3467
|
+
* behind that validation never saw.
|
|
3468
|
+
*
|
|
3469
|
+
* The referencers are probed a few at a time and the walk stops at the first
|
|
3470
|
+
* that serves, because a subject outside the audience is the case that runs to
|
|
3471
|
+
* the bound, and it is the common one. A probe that failed decides only when
|
|
3472
|
+
* nothing served: serving rests on a real allow, so this cannot widen, and it
|
|
3473
|
+
* stops one unreachable referencer from turning an allow already in hand into
|
|
3474
|
+
* a denial. A read records no operation, so replicas differing over a
|
|
3475
|
+
* transient failure has no consensus consequence.
|
|
3476
|
+
*
|
|
3477
|
+
* The probes are awaited together rather than raced, so none is ever left
|
|
3478
|
+
* running with nobody awaiting it, which is where unhandled rejections come
|
|
3479
|
+
* from.
|
|
3480
|
+
*/
|
|
3481
|
+
private servesGroupTo;
|
|
3482
|
+
/**
|
|
3483
|
+
* Whether one referencing document serves the subject any domain scope. A
|
|
3484
|
+
* referencer this replica does not hold serves nothing, which fails closed
|
|
3485
|
+
* the same way a group it does not hold does.
|
|
3486
|
+
*/
|
|
3487
|
+
private servesThrough;
|
|
3488
|
+
private servesGroup;
|
|
3489
|
+
/**
|
|
3490
|
+
* What this document's own policy says, with no group serving applied.
|
|
3491
|
+
*
|
|
3492
|
+
* An unpoliced document is readable in full, which is the common case and the
|
|
3493
|
+
* one worth answering without building anything. The test is the one
|
|
3494
|
+
* `evaluate` makes: a legacy `{}` auth scope and version 0 both mean
|
|
3495
|
+
* uninitialized, and "no grants" does not, because a policy with a version and
|
|
3496
|
+
* an empty grant list denies everything.
|
|
3497
|
+
*/
|
|
3498
|
+
private ownPolicyPredicate;
|
|
3499
|
+
}
|
|
3500
|
+
//#endregion
|
|
3501
|
+
//#region src/client/reactor-client.d.ts
|
|
3502
|
+
/**
|
|
3503
|
+
* ReactorClient implementation that wraps lower-level APIs to provide
|
|
3504
|
+
* a simpler interface for document operations.
|
|
3505
|
+
*
|
|
3506
|
+
* Features:
|
|
3507
|
+
* - Wraps Jobs with Promises for easier async handling
|
|
3508
|
+
* - Manages signing of submitted Action objects
|
|
3509
|
+
* - Provides quality-of-life functions for common tasks
|
|
3510
|
+
* - Wraps subscription interface with ViewFilters
|
|
3511
|
+
*/
|
|
3512
|
+
declare class ReactorClient implements IReactorClient {
|
|
3513
|
+
private logger;
|
|
3514
|
+
private reactor;
|
|
3515
|
+
private signer;
|
|
3516
|
+
private subscriptionManager;
|
|
3517
|
+
private jobAwaiter;
|
|
3518
|
+
private documentIndexer;
|
|
3519
|
+
private documentView;
|
|
3520
|
+
private readGate;
|
|
3521
|
+
readonly drives: IDriveClient;
|
|
3522
|
+
constructor(logger: ILogger, reactor: IReactor, signer: ISigner, subscriptionManager: IReactorSubscriptionManager, jobAwaiter: IJobAwaiter, documentIndexer: IDocumentIndexer, documentView: IDocumentView, readGate?: IReadGate);
|
|
3523
|
+
private readSubject;
|
|
3524
|
+
/**
|
|
3525
|
+
* Which scopes of one document the subject may read. Resolved once per
|
|
3526
|
+
* document, so the gate builds its model once however many scopes are then
|
|
3527
|
+
* tested, and the filtering itself stays synchronous.
|
|
3528
|
+
*/
|
|
3529
|
+
private readableScopes;
|
|
3530
|
+
/**
|
|
3531
|
+
* One document, filtered to the scopes the subject may read. Every method
|
|
3532
|
+
* that hands a document back goes through here, including the ones that
|
|
3533
|
+
* follow a write: a document returned from a mutation is a read like any
|
|
3534
|
+
* other, and returning it whole served scopes the same subject would be
|
|
3535
|
+
* refused by `get`. Its author still sees what it wrote, because an allow on
|
|
3536
|
+
* execute confers read of that scope.
|
|
3537
|
+
*/
|
|
3538
|
+
private gateDocument;
|
|
3539
|
+
/**
|
|
3540
|
+
* Retrieves a list of document model modules.
|
|
3541
|
+
*/
|
|
3542
|
+
getDocumentModelModules(namespace?: string, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<DocumentModelModule>>;
|
|
3543
|
+
/**
|
|
3544
|
+
* Retrieves a specific document model module by document type.
|
|
3545
|
+
*
|
|
3546
|
+
* @param documentType - The document type identifier
|
|
3547
|
+
* @returns The document model module
|
|
3548
|
+
*/
|
|
3549
|
+
getDocumentModelModule(documentType: string): Promise<DocumentModelModule<any>>;
|
|
3550
|
+
/**
|
|
3551
|
+
* Retrieves the document model module matching the version the document is
|
|
3552
|
+
* stamped with, so not-yet-upgraded documents get the reducer their
|
|
3553
|
+
* history was written with rather than the latest.
|
|
3554
|
+
*/
|
|
3555
|
+
getDocumentModelModuleForDocument(document: PHDocument): Promise<DocumentModelModule<any>>;
|
|
3556
|
+
/**
|
|
3557
|
+
* Retrieves a specific PHDocument
|
|
3558
|
+
*/
|
|
3559
|
+
get<TDocument extends PHDocument>(identifier: string, view?: ViewFilter, signal?: AbortSignal): Promise<TDocument>;
|
|
3560
|
+
/**
|
|
3561
|
+
* Resolves an identifier (id or slug) to the canonical document id, using the
|
|
3562
|
+
* same lookup as the data path. Resolves against the "main" branch. Throws if
|
|
3563
|
+
* the identifier cannot be resolved or is ambiguous.
|
|
3564
|
+
*/
|
|
3565
|
+
resolveIdOrSlug(identifier: string, view?: ViewFilter, signal?: AbortSignal): Promise<string>;
|
|
3566
|
+
/**
|
|
3567
|
+
* Retrieves operations for a document
|
|
3568
|
+
*/
|
|
3569
|
+
getOperations(documentIdentifier: string, view?: ViewFilter, filter?: OperationFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<Operation>>;
|
|
3570
|
+
private getOperationsWithCompositeCursor;
|
|
3571
|
+
/**
|
|
3572
|
+
* Retrieves outgoing relationships of a given type from a source document.
|
|
3573
|
+
*/
|
|
3574
|
+
getOutgoingRelationships(sourceIdentifier: string, relationshipType: string, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
|
|
3575
|
+
/**
|
|
3576
|
+
* Retrieves incoming relationships of a given type to a target document.
|
|
3577
|
+
*/
|
|
3578
|
+
getIncomingRelationships(targetIdentifier: string, relationshipType: string, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
|
|
3579
|
+
/**
|
|
3580
|
+
* Filters documents by criteria and returns a list of them
|
|
3581
|
+
*/
|
|
3582
|
+
find(search: SearchFilter, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
|
|
3583
|
+
/**
|
|
3584
|
+
* Creates a document and waits for completion
|
|
3585
|
+
*/
|
|
3586
|
+
create<TDocument extends PHDocument = PHDocument>(document: PHDocument, parentIdentifier?: string, signal?: AbortSignal): Promise<TDocument>;
|
|
3587
|
+
/**
|
|
3588
|
+
* Creates an empty document and waits for completion
|
|
3589
|
+
*/
|
|
3590
|
+
createEmpty<TDocument extends PHDocument>(documentModelType: string, options?: CreateDocumentOptions, signal?: AbortSignal): Promise<TDocument>;
|
|
3591
|
+
/**
|
|
3592
|
+
* Upgrades a document to a newer document model version by dispatching an
|
|
3593
|
+
* UPGRADE_DOCUMENT action. When toVersion is omitted, upgrades to the
|
|
3594
|
+
* latest registered module version for the document's type. Returns the
|
|
3595
|
+
* document unchanged when it is already at the target version.
|
|
3596
|
+
*
|
|
3597
|
+
* The executor validates the action's version and revision snapshot against
|
|
3598
|
+
* the state the migration actually runs on. When a concurrent edit
|
|
3599
|
+
* invalidates the snapshot, the upgrade is rebuilt from a fresh read and
|
|
3600
|
+
* retried up to maxConflictRetries times before the conflict is surfaced.
|
|
3601
|
+
*/
|
|
3602
|
+
upgradeDocument<TDocument extends PHDocument = PHDocument>(documentIdentifier: string, toVersion?: number, options?: UpgradeDocumentOptions, signal?: AbortSignal): Promise<TDocument>;
|
|
3603
|
+
/**
|
|
3604
|
+
* Creates an empty document in a drive as a single batched operation.
|
|
3605
|
+
* Delegates to {@link IDriveClient.addFile}.
|
|
3606
|
+
*
|
|
3607
|
+
* @deprecated Use `client.drives.addFile` instead. This method will be
|
|
3608
|
+
* removed in a future release.
|
|
3609
|
+
*/
|
|
3610
|
+
createDocumentInDrive<TDocument extends PHDocument>(driveId: string, document: PHDocument, parentFolder?: string, signal?: AbortSignal): Promise<TDocument>;
|
|
3611
|
+
/**
|
|
3612
|
+
* Applies a list of actions to a document and waits for completion
|
|
3613
|
+
*/
|
|
3614
|
+
execute<TDocument extends PHDocument>(documentIdentifier: string, branch: string, actions: Action[], signal?: AbortSignal): Promise<TDocument>;
|
|
3615
|
+
/**
|
|
3616
|
+
* Submits a list of actions to a document
|
|
3617
|
+
*/
|
|
3618
|
+
executeAsync(documentIdentifier: string, branch: string, actions: Action[], signal?: AbortSignal): Promise<JobInfo>;
|
|
3619
|
+
executeBatch(request: BatchExecutionRequest, signal?: AbortSignal): Promise<BatchExecutionResult>;
|
|
3620
|
+
/**
|
|
3621
|
+
* Renames a document and waits for completion
|
|
3622
|
+
*/
|
|
3623
|
+
rename(documentIdentifier: string, name: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
3624
|
+
/**
|
|
3625
|
+
* Updates the preferred editor recorded in the document header meta.
|
|
3626
|
+
* Pass `null` to clear it.
|
|
3627
|
+
*/
|
|
3628
|
+
setPreferredEditor(documentIdentifier: string, preferredEditor: string | null, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
3629
|
+
/**
|
|
3630
|
+
* Adds multiple documents as children to another and waits for completion
|
|
3631
|
+
*/
|
|
3632
|
+
addRelationship(sourceIdentifier: string, targetIdentifier: string, relationshipType: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
3633
|
+
/**
|
|
3634
|
+
* Removes a relationship between two documents and waits for completion.
|
|
3635
|
+
*/
|
|
3636
|
+
removeRelationship(sourceIdentifier: string, targetIdentifier: string, relationshipType: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
3637
|
+
/**
|
|
3638
|
+
* Moves a relationship from one source document to another and waits for completion.
|
|
3639
|
+
*/
|
|
3640
|
+
moveRelationship(sourceParentIdentifier: string, targetParentIdentifier: string, targetIdentifier: string, relationshipType: string, branch?: string, signal?: AbortSignal): Promise<{
|
|
3641
|
+
source: PHDocument;
|
|
3642
|
+
target: PHDocument;
|
|
3643
|
+
}>;
|
|
3644
|
+
loadBatch(request: BatchLoadRequest, signal?: AbortSignal): Promise<BatchLoadResult>;
|
|
3645
|
+
/**
|
|
3646
|
+
* Deletes a document and waits for completion
|
|
3647
|
+
*/
|
|
3648
|
+
deleteDocument(identifier: string, propagate?: PropagationMode, signal?: AbortSignal): Promise<void>;
|
|
3649
|
+
/**
|
|
3650
|
+
* Deletes documents and waits for completion
|
|
3651
|
+
*/
|
|
3652
|
+
deleteDocuments(identifiers: string[], propagate?: PropagationMode, signal?: AbortSignal): Promise<void>;
|
|
3653
|
+
/**
|
|
3654
|
+
* Retrieves the status of a job
|
|
3655
|
+
*/
|
|
3656
|
+
getJobStatus(jobId: string, signal?: AbortSignal): Promise<JobInfo>;
|
|
3657
|
+
/**
|
|
3658
|
+
* Waits for a job to complete
|
|
3659
|
+
*/
|
|
3660
|
+
waitForJob(jobId: string | JobInfo, signal?: AbortSignal): Promise<JobInfo>;
|
|
3661
|
+
/**
|
|
3662
|
+
* Subscribes to changes for documents matching specified filters
|
|
3663
|
+
*/
|
|
3664
|
+
subscribe(search: SearchFilter, callback: (event: DocumentChangeEvent) => void, view?: ViewFilter): () => void;
|
|
3665
|
+
private removeAllIncomingRelationships;
|
|
3666
|
+
}
|
|
3667
|
+
//#endregion
|
|
3668
|
+
//#region src/executor/interfaces.d.ts
|
|
3669
|
+
/**
|
|
3670
|
+
* Snapshot of the single in-flight slot maintained by an {@link IExecutorWorker}.
|
|
3671
|
+
*/
|
|
3672
|
+
type WorkerInFlightSnapshot = {
|
|
3673
|
+
correlationId: string;
|
|
3674
|
+
jobId: string;
|
|
3675
|
+
};
|
|
3676
|
+
/**
|
|
3677
|
+
* Outcome of a worker-side job execution.
|
|
3678
|
+
*
|
|
3679
|
+
* `result` mirrors the in-process `JobResult` exactly. `writeReady` carries
|
|
3680
|
+
* the operations + jobMeta the parent needs to emit `JOB_WRITE_READY`, and is
|
|
3681
|
+
* present only when the worker produced operations. It is absent on failure
|
|
3682
|
+
* and on success-with-no-operations.
|
|
3683
|
+
*/
|
|
3684
|
+
type WorkerExecutionOutcome = {
|
|
3685
|
+
result: JobResult;
|
|
3686
|
+
writeReady?: JobWriteReadyPayload;
|
|
3687
|
+
};
|
|
3688
|
+
/**
|
|
3689
|
+
* Parent-side handle for a single executor worker.
|
|
3690
|
+
*
|
|
3691
|
+
* Implementations wrap an IPC transport (worker_threads, child_process, or a
|
|
3692
|
+
* test fake) and expose a transport-agnostic surface that the worker-pool
|
|
3693
|
+
* manager uses to dispatch jobs. The handle owns one worker's lifecycle
|
|
3694
|
+
* (`start` -> `execute`* -> `shutdown`) and bounds its in-flight map to a
|
|
3695
|
+
* single entry; `SimpleJobExecutor` is single-threaded inside the worker, so
|
|
3696
|
+
* concurrent dispatches would race its caches.
|
|
3697
|
+
*/
|
|
3698
|
+
interface IExecutorWorker {
|
|
3699
|
+
/** Stable identifier of the worker (mirrors `InitMessage.workerId`). */
|
|
3700
|
+
readonly workerId: string;
|
|
3701
|
+
/** Zero-based index within the pool, used for sticky routing. */
|
|
3702
|
+
readonly index: number;
|
|
3703
|
+
/**
|
|
3704
|
+
* Spawn the worker (if not already started), send the `init` payload and
|
|
3705
|
+
* resolve when the worker replies with `ready`.
|
|
3706
|
+
*/
|
|
3707
|
+
start(): Promise<void>;
|
|
3708
|
+
/**
|
|
3709
|
+
* Dispatch a job to the worker and resolve with its outcome — the
|
|
3710
|
+
* `JobResult` and, on success-with-operations, a `writeReady` payload
|
|
3711
|
+
* the parent will enrich and re-emit. Rejects with a transport-level
|
|
3712
|
+
* error if the worker exits, aborts, or times out before producing a
|
|
3713
|
+
* result.
|
|
3714
|
+
*/
|
|
3715
|
+
execute(job: Job, signal?: AbortSignal): Promise<WorkerExecutionOutcome>;
|
|
3716
|
+
/**
|
|
3717
|
+
* Request cancellation of the in-flight job (if any). The handle posts an
|
|
3718
|
+
* `abort` message; if the worker fails to reply within its grace window it
|
|
3719
|
+
* is force-terminated.
|
|
3720
|
+
*/
|
|
3721
|
+
abort(correlationId: string, reason?: string): void;
|
|
3722
|
+
/**
|
|
3723
|
+
* Stop the worker. When `graceful` is true the handle waits for the
|
|
3724
|
+
* in-flight job to settle (up to `graceMs`) before terminating; otherwise
|
|
3725
|
+
* the worker is terminated immediately.
|
|
3726
|
+
*/
|
|
3727
|
+
shutdown(graceful: boolean, graceMs?: number): Promise<void>;
|
|
3728
|
+
/**
|
|
3729
|
+
* Register an additional document model on the running worker. Resolves
|
|
3730
|
+
* when the worker replies with `model-loaded`; rejects when it replies
|
|
3731
|
+
* with `model-load-failed` or the worker exits before answering.
|
|
3732
|
+
*/
|
|
3733
|
+
loadModel(entry: ModelManifestEntry, signal?: AbortSignal): Promise<void>;
|
|
3734
|
+
/** True when no job is currently in flight. */
|
|
3735
|
+
isIdle(): boolean;
|
|
3736
|
+
/** Snapshot of the in-flight slot, or null when idle. */
|
|
3737
|
+
getInFlight(): WorkerInFlightSnapshot | null;
|
|
3738
|
+
}
|
|
3739
|
+
/**
|
|
3740
|
+
* Simple interface for executing a job.
|
|
3741
|
+
* A JobExecutor simply takes a job and executes it - nothing more.
|
|
3742
|
+
*/
|
|
3743
|
+
interface IJobExecutor {
|
|
3744
|
+
/**
|
|
3745
|
+
* Execute a single job.
|
|
3746
|
+
* @param job - The job to execute
|
|
3747
|
+
* @returns Promise that resolves to the job result
|
|
3748
|
+
*/
|
|
3749
|
+
executeJob(job: Job, signal?: AbortSignal): Promise<JobResult>;
|
|
3750
|
+
}
|
|
3751
|
+
/**
|
|
3752
|
+
* Interface for managing multiple job executors.
|
|
3753
|
+
* Listens for 'jobAvailable' events from the event bus, pulls jobs from the queue,
|
|
3754
|
+
* and coordinates the distribution of jobs across multiple executor instances.
|
|
3755
|
+
*/
|
|
3756
|
+
interface IJobExecutorManager {
|
|
3757
|
+
/**
|
|
3758
|
+
* Start the executor manager.
|
|
3759
|
+
* Begins listening for 'jobAvailable' events and dispatching to executors.
|
|
3760
|
+
*
|
|
3761
|
+
* @param numExecutors - Number of executor instances to create
|
|
3762
|
+
* @returns Promise that resolves when the manager is started
|
|
3763
|
+
*/
|
|
3764
|
+
start(numExecutors: number): Promise<void>;
|
|
3765
|
+
/**
|
|
3766
|
+
* Stop the executor manager.
|
|
3767
|
+
*
|
|
3768
|
+
* @param graceful - Whether to wait for current jobs to complete
|
|
3769
|
+
* @returns Promise that resolves when the manager is stopped
|
|
3770
|
+
*/
|
|
3771
|
+
stop(graceful?: boolean): Promise<void>;
|
|
3772
|
+
/**
|
|
3773
|
+
* Get all managed executor instances.
|
|
3774
|
+
*
|
|
3775
|
+
* @returns Array of executor instances
|
|
3776
|
+
*/
|
|
3777
|
+
getExecutors(): IJobExecutor[];
|
|
3778
|
+
/**
|
|
3779
|
+
* Get the current status of the manager.
|
|
3780
|
+
*
|
|
3781
|
+
* @returns The current manager status
|
|
3782
|
+
*/
|
|
3783
|
+
getStatus(): ExecutorManagerStatus;
|
|
3784
|
+
}
|
|
3785
|
+
//#endregion
|
|
3786
|
+
//#region src/job-tracker/interfaces.d.ts
|
|
3787
|
+
/**
|
|
3788
|
+
* Interface for tracking job lifecycle status.
|
|
3789
|
+
* Maintains job state throughout execution: PENDING → RUNNING → COMPLETED/FAILED.
|
|
3790
|
+
*/
|
|
3791
|
+
interface IJobTracker {
|
|
3792
|
+
/**
|
|
3793
|
+
* Register a new job with PENDING status.
|
|
3794
|
+
*
|
|
3795
|
+
* @param jobInfo - The job information to register
|
|
3796
|
+
*/
|
|
3797
|
+
registerJob(jobInfo: JobInfo): void;
|
|
3798
|
+
/**
|
|
3799
|
+
* Update a job's status to RUNNING.
|
|
3800
|
+
*
|
|
3801
|
+
* @param jobId - The job ID to mark as running
|
|
3802
|
+
*/
|
|
3803
|
+
markRunning(jobId: string): void;
|
|
3804
|
+
/**
|
|
3805
|
+
* Mark a job as failed.
|
|
3806
|
+
*
|
|
3807
|
+
* @param jobId - The job ID to mark as failed
|
|
3808
|
+
* @param error - Error information including message and stack trace
|
|
3809
|
+
* @param job - Optional full job object for debugging purposes
|
|
3810
|
+
*/
|
|
3811
|
+
markFailed(jobId: string, error: ErrorInfo$1, job?: Job): void;
|
|
3812
|
+
/**
|
|
3813
|
+
* Retrieve the current status of a job.
|
|
3814
|
+
*
|
|
3815
|
+
* @param jobId - The job ID to query
|
|
3816
|
+
* @returns The job information, or null if the job is not found
|
|
3817
|
+
*/
|
|
3818
|
+
getJobStatus(jobId: string): JobInfo | null;
|
|
3819
|
+
/**
|
|
3820
|
+
* Shutdown the job tracker and clean up resources.
|
|
3821
|
+
* Unsubscribes from all event bus subscriptions.
|
|
3822
|
+
*/
|
|
3823
|
+
shutdown(): void;
|
|
3824
|
+
}
|
|
3825
|
+
//#endregion
|
|
3826
|
+
//#region src/queue/interfaces.d.ts
|
|
3827
|
+
/**
|
|
3828
|
+
* Interface for a job queue that manages write operations.
|
|
3829
|
+
* Internally organizes jobs by documentId, scope, and branch to ensure proper ordering.
|
|
3830
|
+
* Emits events to the event bus when new jobs are available for consumption.
|
|
3831
|
+
*/
|
|
3832
|
+
interface IQueue {
|
|
3833
|
+
/**
|
|
3834
|
+
* Add a new job to the queue.
|
|
3835
|
+
* Jobs are automatically organized by documentId, scope, and branch internally.
|
|
3836
|
+
* Emits a 'jobAvailable' event to the event bus when the job is queued.
|
|
3837
|
+
* @param job - The job to add to the queue
|
|
3838
|
+
* @returns Promise that resolves when the job is queued
|
|
3839
|
+
*/
|
|
3840
|
+
enqueue(job: Job): Promise<void>;
|
|
3841
|
+
/**
|
|
3842
|
+
* Get the next job to execute for a specific document/scope/branch combination.
|
|
3843
|
+
* @param documentId - The document ID to get jobs for
|
|
3844
|
+
* @param scope - The scope to get jobs for
|
|
3845
|
+
* @param branch - The branch to get jobs for
|
|
3846
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3847
|
+
* @returns Promise that resolves to the next job execution handle or null if no jobs available
|
|
3848
|
+
*/
|
|
3849
|
+
dequeue(documentId: string, scope: string, branch: string, signal?: AbortSignal): Promise<IJobExecutionHandle | null>;
|
|
3850
|
+
/**
|
|
3851
|
+
* Get the next available job from any queue.
|
|
3852
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3853
|
+
* @returns Promise that resolves to the next job execution handle or null if no jobs available
|
|
3854
|
+
*/
|
|
3855
|
+
dequeueNext(signal?: AbortSignal): Promise<IJobExecutionHandle | null>;
|
|
3856
|
+
/**
|
|
3857
|
+
* Get the next available job whose routing metadata satisfies the predicate.
|
|
3858
|
+
* Walks ready sub-queue heads in queue insertion order, skips heads whose document
|
|
3859
|
+
* is currently executing (same isDocumentExecuting gate as dequeueNext), and returns
|
|
3860
|
+
* the first head for which predicate returns true.
|
|
3861
|
+
* Returns null when paused, when nothing matches, or when the queue is empty.
|
|
3862
|
+
* Rejects if signal is already aborted.
|
|
3863
|
+
* @param predicate - Filter applied to JobRoutingMeta of each candidate head
|
|
3864
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3865
|
+
* @returns Promise that resolves to the first matching job execution handle or null
|
|
3866
|
+
*/
|
|
3867
|
+
dequeueNextMatching(predicate: (meta: JobRoutingMeta) => boolean, signal?: AbortSignal): Promise<IJobExecutionHandle | null>;
|
|
3868
|
+
/**
|
|
3869
|
+
* Get the current size of the queue for a specific document/scope/branch.
|
|
3870
|
+
* @param documentId - The document ID
|
|
2631
3871
|
* @param scope - The scope
|
|
2632
3872
|
* @param branch - The branch
|
|
2633
3873
|
* @returns Promise that resolves to the number of jobs in the queue
|
|
@@ -2679,9 +3919,11 @@ interface IQueue {
|
|
|
2679
3919
|
* Retry a failed job.
|
|
2680
3920
|
* @param jobId - The ID of the job to retry
|
|
2681
3921
|
* @param error - Optional error information from the failure
|
|
3922
|
+
* @param accounting - Whether the attempt counts against the job's retry
|
|
3923
|
+
* limit; defaults to {@link RetryAccounting.CountAgainstLimit}
|
|
2682
3924
|
* @returns Promise that resolves when the job is requeued for retry
|
|
2683
3925
|
*/
|
|
2684
|
-
retryJob(jobId: string, error?: ErrorInfo$1): Promise<void>;
|
|
3926
|
+
retryJob(jobId: string, error?: ErrorInfo$1, accounting?: RetryAccounting): Promise<void>;
|
|
2685
3927
|
/**
|
|
2686
3928
|
* Returns true if and only if all jobs have been resolved.
|
|
2687
3929
|
*/
|
|
@@ -2690,213 +3932,88 @@ interface IQueue {
|
|
|
2690
3932
|
* Blocks the queue from accepting new jobs.
|
|
2691
3933
|
* @param onDrained - Optional callback to call when the queue is drained
|
|
2692
3934
|
*/
|
|
2693
|
-
block(onDrained?: () => void): void;
|
|
2694
|
-
/**
|
|
2695
|
-
* Unblocks the queue from accepting new jobs.
|
|
2696
|
-
*/
|
|
2697
|
-
unblock(): void;
|
|
2698
|
-
}
|
|
2699
|
-
//#endregion
|
|
2700
|
-
//#region src/read-models/types.d.ts
|
|
2701
|
-
interface ViewStateTable {
|
|
2702
|
-
readModelId: string;
|
|
2703
|
-
lastOrdinal: number;
|
|
2704
|
-
lastOperationTimestamp: Generated<Date>;
|
|
2705
|
-
}
|
|
2706
|
-
interface DocumentSnapshotTable {
|
|
2707
|
-
id: Generated<string>;
|
|
2708
|
-
documentId: string;
|
|
2709
|
-
slug: string | null;
|
|
2710
|
-
name: string | null;
|
|
2711
|
-
scope: string;
|
|
2712
|
-
branch: string;
|
|
2713
|
-
content: unknown;
|
|
2714
|
-
documentType: string;
|
|
2715
|
-
lastOperationIndex: number;
|
|
2716
|
-
lastOperationHash: string;
|
|
2717
|
-
lastUpdatedAt: Generated<Date>;
|
|
2718
|
-
snapshotVersion: Generated<number>;
|
|
2719
|
-
identifiers: unknown;
|
|
2720
|
-
metadata: unknown;
|
|
2721
|
-
isDeleted: Generated<boolean>;
|
|
2722
|
-
deletedAt: Date | null;
|
|
2723
|
-
}
|
|
2724
|
-
interface SlugMappingTable {
|
|
2725
|
-
slug: string;
|
|
2726
|
-
documentId: string;
|
|
2727
|
-
scope: string;
|
|
2728
|
-
branch: string;
|
|
2729
|
-
createdAt: Generated<Date>;
|
|
2730
|
-
updatedAt: Generated<Date>;
|
|
2731
|
-
}
|
|
2732
|
-
interface ProcessorCursorTable {
|
|
2733
|
-
processorId: string;
|
|
2734
|
-
factoryId: string;
|
|
2735
|
-
driveId: string;
|
|
2736
|
-
processorIndex: number;
|
|
2737
|
-
lastOrdinal: Generated<number>;
|
|
2738
|
-
status: Generated<string>;
|
|
2739
|
-
lastError: string | null;
|
|
2740
|
-
lastErrorTimestamp: Date | null;
|
|
2741
|
-
createdAt: Generated<Date>;
|
|
2742
|
-
updatedAt: Generated<Date>;
|
|
2743
|
-
}
|
|
2744
|
-
interface DocumentViewDatabase {
|
|
2745
|
-
ViewState: ViewStateTable;
|
|
2746
|
-
DocumentSnapshot: DocumentSnapshotTable;
|
|
2747
|
-
SlugMapping: SlugMappingTable;
|
|
2748
|
-
ProcessorCursor: ProcessorCursorTable;
|
|
2749
|
-
}
|
|
2750
|
-
type InsertableDocumentSnapshot = Insertable<DocumentSnapshotTable>;
|
|
2751
|
-
//#endregion
|
|
2752
|
-
//#region src/core/model-sources.d.ts
|
|
2753
|
-
/** An importable file holding one or more document-model exports. */
|
|
2754
|
-
type FileModelSource = {
|
|
2755
|
-
filePath: string;
|
|
2756
|
-
exportName?: string;
|
|
2757
|
-
};
|
|
2758
|
-
/** An importable package specifier holding one or more document-model exports. */
|
|
2759
|
-
type PackageModelSource = {
|
|
2760
|
-
packageName: string;
|
|
2761
|
-
subpath?: string;
|
|
2762
|
-
exportName?: string;
|
|
2763
|
-
};
|
|
2764
|
-
/**
|
|
2765
|
-
* A source of document models: a live module, an importable file, or an
|
|
2766
|
-
* importable package. File and package sources can cross a worker-thread
|
|
2767
|
-
* boundary (workers re-import them); a live module cannot.
|
|
2768
|
-
*/
|
|
2769
|
-
type DocumentModelSource = DocumentModelModule<any> | FileModelSource | PackageModelSource;
|
|
2770
|
-
//#endregion
|
|
2771
|
-
//#region src/registry/interfaces.d.ts
|
|
2772
|
-
type RegistrationResult<T> = {
|
|
2773
|
-
status: "success";
|
|
2774
|
-
item: T;
|
|
2775
|
-
} | {
|
|
2776
|
-
status: "error";
|
|
2777
|
-
item: T;
|
|
2778
|
-
error: Error;
|
|
2779
|
-
};
|
|
2780
|
-
/**
|
|
2781
|
-
* Loader that asynchronously resolves a document type to a
|
|
2782
|
-
* {@link DocumentModelSource}. Used by the queue to gate CREATE_DOCUMENT
|
|
2783
|
-
* jobs until the required model is available in the registry.
|
|
2784
|
-
*
|
|
2785
|
-
* Return an importable source ({ filePath } or { packageName }) whenever
|
|
2786
|
-
* possible: the resolver registers the resolved models on the host registry
|
|
2787
|
-
* and broadcasts importable sources to executor workers. A live
|
|
2788
|
-
* DocumentModelModule is also valid but host-only — it cannot cross a
|
|
2789
|
-
* worker-thread boundary, so worker pools will not receive it.
|
|
2790
|
-
*/
|
|
2791
|
-
interface IDocumentModelLoader {
|
|
2792
|
-
load(documentType: string): Promise<DocumentModelSource>;
|
|
2793
|
-
}
|
|
2794
|
-
/**
|
|
2795
|
-
* Registry for managing document model modules.
|
|
2796
|
-
* Provides centralized access to document models' reducers, utils, and specifications.
|
|
2797
|
-
* Supports version-aware module storage and upgrade manifest management.
|
|
2798
|
-
*/
|
|
2799
|
-
interface IDocumentModelRegistry {
|
|
2800
|
-
/**
|
|
2801
|
-
* Register multiple modules at once.
|
|
2802
|
-
* Modules without a version field default to version 1.
|
|
2803
|
-
* Invalid or duplicate modules are skipped without breaking registration of the remaining modules.
|
|
2804
|
-
*
|
|
2805
|
-
* @param modules Document model modules to register
|
|
2806
|
-
* @returns Array of results, one per module, indicating success or failure
|
|
2807
|
-
*/
|
|
2808
|
-
registerModules(...modules: DocumentModelModule<any>[]): RegistrationResult<DocumentModelModule<any>>[];
|
|
2809
|
-
/**
|
|
2810
|
-
* Unregister all versions of the specified document types.
|
|
2811
|
-
*
|
|
2812
|
-
* @param documentTypes The document types to unregister
|
|
2813
|
-
* @returns true if all modules were unregistered, false if any were not found
|
|
2814
|
-
*/
|
|
2815
|
-
unregisterModules(...documentTypes: string[]): boolean;
|
|
2816
|
-
/**
|
|
2817
|
-
* Get a specific document model module by document type and optional version.
|
|
2818
|
-
* If version is not specified, returns the latest version.
|
|
2819
|
-
*
|
|
2820
|
-
* @param documentType The document type identifier
|
|
2821
|
-
* @param version Optional version number to retrieve
|
|
2822
|
-
* @returns The document model module
|
|
2823
|
-
* @throws ModuleNotFoundError if the document type or version is not registered
|
|
2824
|
-
*/
|
|
2825
|
-
getModule(documentType: string, version?: number): DocumentModelModule<any>;
|
|
2826
|
-
/**
|
|
2827
|
-
* Get all registered document model modules.
|
|
2828
|
-
*
|
|
2829
|
-
* @returns Array of all registered modules
|
|
2830
|
-
*/
|
|
2831
|
-
getAllModules(): DocumentModelModule<any>[];
|
|
2832
|
-
/**
|
|
2833
|
-
* Clear all registered modules and upgrade manifests.
|
|
2834
|
-
*/
|
|
2835
|
-
clear(): void;
|
|
2836
|
-
/**
|
|
2837
|
-
* Get all supported versions for a document type, sorted in ascending order.
|
|
2838
|
-
*
|
|
2839
|
-
* @param documentType The document type identifier
|
|
2840
|
-
* @returns Array of version numbers sorted ascending
|
|
2841
|
-
* @throws ModuleNotFoundError if no modules are registered for the document type
|
|
2842
|
-
*/
|
|
2843
|
-
getSupportedVersions(documentType: string): number[];
|
|
2844
|
-
/**
|
|
2845
|
-
* Get the latest (highest) version number for a document type.
|
|
2846
|
-
*
|
|
2847
|
-
* @param documentType The document type identifier
|
|
2848
|
-
* @returns The highest version number registered for this document type
|
|
2849
|
-
* @throws ModuleNotFoundError if no modules are registered for the document type
|
|
2850
|
-
*/
|
|
2851
|
-
getLatestVersion(documentType: string): number;
|
|
2852
|
-
/**
|
|
2853
|
-
* Register upgrade manifests that define upgrade paths between versions.
|
|
2854
|
-
* Invalid or duplicate manifests are skipped without breaking registration of the remaining manifests.
|
|
2855
|
-
*
|
|
2856
|
-
* @param manifests Upgrade manifests to register
|
|
2857
|
-
* @returns Array of results, one per manifest, indicating success or failure
|
|
2858
|
-
*/
|
|
2859
|
-
registerUpgradeManifests(...manifests: UpgradeManifest<readonly number[]>[]): RegistrationResult<UpgradeManifest<readonly number[]>>[];
|
|
2860
|
-
/**
|
|
2861
|
-
* Unregister upgrade manifests for the specified document types.
|
|
2862
|
-
* @param documentTypes The document types whose upgrade manifests should be unregistered
|
|
2863
|
-
* @returns true if all modules were unregistered, false if any were not found
|
|
2864
|
-
**/
|
|
2865
|
-
unregisterUpgradeManifests(...documentTypes: string[]): boolean;
|
|
2866
|
-
/**
|
|
2867
|
-
* Get the upgrade manifest for a document type.
|
|
2868
|
-
*
|
|
2869
|
-
* @param documentType The document type identifier
|
|
2870
|
-
* @returns The upgrade manifest
|
|
2871
|
-
* @throws ManifestNotFoundError if no manifest is registered for the document type
|
|
2872
|
-
*/
|
|
2873
|
-
getUpgradeManifest(documentType: string): UpgradeManifest<readonly number[]>;
|
|
2874
|
-
/**
|
|
2875
|
-
* Compute the upgrade path from one version to another.
|
|
2876
|
-
* Returns the sequence of upgrade transitions needed.
|
|
2877
|
-
*
|
|
2878
|
-
* @param documentType The document type identifier
|
|
2879
|
-
* @param fromVersion The starting version
|
|
2880
|
-
* @param toVersion The target version
|
|
2881
|
-
* @returns Array of upgrade transitions in order
|
|
2882
|
-
* @throws DowngradeNotSupportedError if toVersion is less than fromVersion
|
|
2883
|
-
* @throws ManifestNotFoundError if no upgrade manifest is registered
|
|
2884
|
-
* @throws MissingUpgradeTransitionError if any transition in the path is missing
|
|
2885
|
-
*/
|
|
2886
|
-
computeUpgradePath(documentType: string, fromVersion: number, toVersion: number): UpgradeTransition[];
|
|
3935
|
+
block(onDrained?: () => void): void;
|
|
2887
3936
|
/**
|
|
2888
|
-
*
|
|
2889
|
-
*
|
|
2890
|
-
* @param documentType The document type identifier
|
|
2891
|
-
* @param fromVersion The starting version
|
|
2892
|
-
* @param toVersion The target version (must be fromVersion + 1)
|
|
2893
|
-
* @returns The upgrade reducer function
|
|
2894
|
-
* @throws InvalidUpgradeStepError if toVersion is not fromVersion + 1
|
|
2895
|
-
* @throws ManifestNotFoundError if no upgrade manifest is registered
|
|
2896
|
-
* @throws MissingUpgradeTransitionError if the transition is not found
|
|
3937
|
+
* Unblocks the queue from accepting new jobs.
|
|
2897
3938
|
*/
|
|
2898
|
-
|
|
3939
|
+
unblock(): void;
|
|
3940
|
+
}
|
|
3941
|
+
//#endregion
|
|
3942
|
+
//#region src/core/group-reevaluation-trigger.d.ts
|
|
3943
|
+
/**
|
|
3944
|
+
* Watches committed writes for group membership changes and enqueues a
|
|
3945
|
+
* re-evaluation job for every document whose auth history references the
|
|
3946
|
+
* changed group, found through the reverse direction of the group-reference
|
|
3947
|
+
* relation. Each affected document is re-judged in its own job, so the work
|
|
3948
|
+
* runs under that document's execution slot rather than the group's.
|
|
3949
|
+
*
|
|
3950
|
+
* The job carries the earliest changed membership timestamp; the executor
|
|
3951
|
+
* skips the pass when everything the document holds sorts before it, which
|
|
3952
|
+
* keeps the common case (a membership write later than all history) free.
|
|
3953
|
+
*/
|
|
3954
|
+
declare class GroupReevaluationTrigger {
|
|
3955
|
+
private logger;
|
|
3956
|
+
private eventBus;
|
|
3957
|
+
private queue;
|
|
3958
|
+
private operationIndex;
|
|
3959
|
+
private unsubscribe?;
|
|
3960
|
+
constructor(logger: ILogger, eventBus: IEventBus, queue: IQueue, operationIndex: IOperationIndex);
|
|
3961
|
+
startup(): void;
|
|
3962
|
+
shutdown(): void;
|
|
3963
|
+
private onWriteReady;
|
|
3964
|
+
}
|
|
3965
|
+
//#endregion
|
|
3966
|
+
//#region src/read-models/types.d.ts
|
|
3967
|
+
interface ViewStateTable {
|
|
3968
|
+
readModelId: string;
|
|
3969
|
+
lastOrdinal: number;
|
|
3970
|
+
lastOperationTimestamp: Generated<Date>;
|
|
3971
|
+
}
|
|
3972
|
+
interface DocumentSnapshotTable {
|
|
3973
|
+
id: Generated<string>;
|
|
3974
|
+
documentId: string;
|
|
3975
|
+
slug: string | null;
|
|
3976
|
+
name: string | null;
|
|
3977
|
+
scope: string;
|
|
3978
|
+
branch: string;
|
|
3979
|
+
content: unknown;
|
|
3980
|
+
documentType: string;
|
|
3981
|
+
lastOperationIndex: number;
|
|
3982
|
+
lastOperationHash: string;
|
|
3983
|
+
lastUpdatedAt: Generated<Date>;
|
|
3984
|
+
snapshotVersion: Generated<number>;
|
|
3985
|
+
identifiers: unknown;
|
|
3986
|
+
metadata: unknown;
|
|
3987
|
+
isDeleted: Generated<boolean>;
|
|
3988
|
+
deletedAt: Date | null;
|
|
3989
|
+
}
|
|
3990
|
+
interface SlugMappingTable {
|
|
3991
|
+
slug: string;
|
|
3992
|
+
documentId: string;
|
|
3993
|
+
scope: string;
|
|
3994
|
+
branch: string;
|
|
3995
|
+
createdAt: Generated<Date>;
|
|
3996
|
+
updatedAt: Generated<Date>;
|
|
3997
|
+
}
|
|
3998
|
+
interface ProcessorCursorTable {
|
|
3999
|
+
processorId: string;
|
|
4000
|
+
factoryId: string;
|
|
4001
|
+
driveId: string;
|
|
4002
|
+
processorIndex: number;
|
|
4003
|
+
lastOrdinal: Generated<number>;
|
|
4004
|
+
status: Generated<string>;
|
|
4005
|
+
lastError: string | null;
|
|
4006
|
+
lastErrorTimestamp: Date | null;
|
|
4007
|
+
createdAt: Generated<Date>;
|
|
4008
|
+
updatedAt: Generated<Date>;
|
|
4009
|
+
}
|
|
4010
|
+
interface DocumentViewDatabase {
|
|
4011
|
+
ViewState: ViewStateTable;
|
|
4012
|
+
DocumentSnapshot: DocumentSnapshotTable;
|
|
4013
|
+
SlugMapping: SlugMappingTable;
|
|
4014
|
+
ProcessorCursor: ProcessorCursorTable;
|
|
2899
4015
|
}
|
|
4016
|
+
type InsertableDocumentSnapshot = Insertable<DocumentSnapshotTable>;
|
|
2900
4017
|
//#endregion
|
|
2901
4018
|
//#region src/shared/consistency-tracker.d.ts
|
|
2902
4019
|
interface IConsistencyTracker {
|
|
@@ -2946,134 +4063,6 @@ declare class ConsistencyTracker implements IConsistencyTracker {
|
|
|
2946
4063
|
private removeWaiter;
|
|
2947
4064
|
}
|
|
2948
4065
|
//#endregion
|
|
2949
|
-
//#region src/storage/kysely/types.d.ts
|
|
2950
|
-
interface OperationTable {
|
|
2951
|
-
id: Generated<number>;
|
|
2952
|
-
jobId: string;
|
|
2953
|
-
opId: string;
|
|
2954
|
-
prevOpId: string;
|
|
2955
|
-
writeTimestampUtcMs: Generated<Date>;
|
|
2956
|
-
documentId: string;
|
|
2957
|
-
documentType: string;
|
|
2958
|
-
scope: string;
|
|
2959
|
-
branch: string;
|
|
2960
|
-
timestampUtcMs: Date;
|
|
2961
|
-
index: number;
|
|
2962
|
-
action: unknown;
|
|
2963
|
-
skip: number;
|
|
2964
|
-
error?: string | null;
|
|
2965
|
-
hash: string;
|
|
2966
|
-
}
|
|
2967
|
-
interface KeyframeTable {
|
|
2968
|
-
id: Generated<number>;
|
|
2969
|
-
documentId: string;
|
|
2970
|
-
documentType: string;
|
|
2971
|
-
scope: string;
|
|
2972
|
-
branch: string;
|
|
2973
|
-
revision: number;
|
|
2974
|
-
document: unknown;
|
|
2975
|
-
createdAt: Generated<Date>;
|
|
2976
|
-
}
|
|
2977
|
-
interface DocumentCollectionTable {
|
|
2978
|
-
documentId: string;
|
|
2979
|
-
collectionId: string;
|
|
2980
|
-
joinedOrdinal: bigint;
|
|
2981
|
-
leftOrdinal: bigint | null;
|
|
2982
|
-
}
|
|
2983
|
-
interface OperationIndexOperationTable {
|
|
2984
|
-
ordinal: Generated<number>;
|
|
2985
|
-
opId: string;
|
|
2986
|
-
documentId: string;
|
|
2987
|
-
documentType: string;
|
|
2988
|
-
scope: string;
|
|
2989
|
-
branch: string;
|
|
2990
|
-
timestampUtcMs: string;
|
|
2991
|
-
writeTimestampUtcMs: Generated<Date>;
|
|
2992
|
-
index: number;
|
|
2993
|
-
skip: number;
|
|
2994
|
-
hash: string;
|
|
2995
|
-
action: unknown;
|
|
2996
|
-
sourceRemote: Generated<string>;
|
|
2997
|
-
}
|
|
2998
|
-
interface SyncRemoteTable {
|
|
2999
|
-
name: string;
|
|
3000
|
-
collection_id: string;
|
|
3001
|
-
channel_type: string;
|
|
3002
|
-
channel_id: string;
|
|
3003
|
-
remote_name: string;
|
|
3004
|
-
channel_parameters: unknown;
|
|
3005
|
-
filter_document_ids: unknown;
|
|
3006
|
-
filter_scopes: unknown;
|
|
3007
|
-
filter_branch: string;
|
|
3008
|
-
push_state: string;
|
|
3009
|
-
push_last_success_utc_ms: string | null;
|
|
3010
|
-
push_last_failure_utc_ms: string | null;
|
|
3011
|
-
push_failure_count: number;
|
|
3012
|
-
pull_state: string;
|
|
3013
|
-
pull_last_success_utc_ms: string | null;
|
|
3014
|
-
pull_last_failure_utc_ms: string | null;
|
|
3015
|
-
pull_failure_count: number;
|
|
3016
|
-
created_at: Generated<Date>;
|
|
3017
|
-
updated_at: Generated<Date>;
|
|
3018
|
-
}
|
|
3019
|
-
interface SyncCursorTable {
|
|
3020
|
-
remote_name: string;
|
|
3021
|
-
cursor_type: string;
|
|
3022
|
-
cursor_ordinal: bigint;
|
|
3023
|
-
last_synced_at_utc_ms: string | null;
|
|
3024
|
-
updated_at: Generated<Date>;
|
|
3025
|
-
}
|
|
3026
|
-
/**
|
|
3027
|
-
* Kysely table definition for the `sync_dead_letters` table.
|
|
3028
|
-
*/
|
|
3029
|
-
interface SyncDeadLetterTable {
|
|
3030
|
-
ordinal: Generated<number>;
|
|
3031
|
-
id: string;
|
|
3032
|
-
job_id: string;
|
|
3033
|
-
job_dependencies: unknown;
|
|
3034
|
-
remote_name: string;
|
|
3035
|
-
document_id: string;
|
|
3036
|
-
scopes: unknown;
|
|
3037
|
-
branch: string;
|
|
3038
|
-
operations: unknown;
|
|
3039
|
-
error_source: string;
|
|
3040
|
-
error_message: string;
|
|
3041
|
-
created_at: Generated<Date>;
|
|
3042
|
-
}
|
|
3043
|
-
interface Database$1 {
|
|
3044
|
-
Operation: OperationTable;
|
|
3045
|
-
Keyframe: KeyframeTable;
|
|
3046
|
-
document_collections: DocumentCollectionTable;
|
|
3047
|
-
operation_index_operations: OperationIndexOperationTable;
|
|
3048
|
-
sync_remotes: SyncRemoteTable;
|
|
3049
|
-
sync_cursors: SyncCursorTable;
|
|
3050
|
-
sync_dead_letters: SyncDeadLetterTable;
|
|
3051
|
-
}
|
|
3052
|
-
interface DocumentTable {
|
|
3053
|
-
id: string;
|
|
3054
|
-
createdAt: Generated<Date>;
|
|
3055
|
-
updatedAt: Generated<Date>;
|
|
3056
|
-
}
|
|
3057
|
-
interface DocumentRelationshipTable {
|
|
3058
|
-
id: Generated<string>;
|
|
3059
|
-
sourceId: string;
|
|
3060
|
-
targetId: string;
|
|
3061
|
-
relationshipType: string;
|
|
3062
|
-
metadata: unknown;
|
|
3063
|
-
createdAt: Generated<Date>;
|
|
3064
|
-
updatedAt: Generated<Date>;
|
|
3065
|
-
}
|
|
3066
|
-
interface IndexerStateTable {
|
|
3067
|
-
id: Generated<number>;
|
|
3068
|
-
lastOperationId: number;
|
|
3069
|
-
lastOperationTimestamp: Generated<Date>;
|
|
3070
|
-
}
|
|
3071
|
-
interface DocumentIndexerDatabase {
|
|
3072
|
-
Document: DocumentTable;
|
|
3073
|
-
DocumentRelationship: DocumentRelationshipTable;
|
|
3074
|
-
IndexerState: IndexerStateTable;
|
|
3075
|
-
}
|
|
3076
|
-
//#endregion
|
|
3077
4066
|
//#region src/storage/pool-instrumentation.d.ts
|
|
3078
4067
|
/**
|
|
3079
4068
|
* Snapshot of a pg.Pool's internal counters at a point in time.
|
|
@@ -3137,7 +4126,13 @@ declare class PollingChannelError extends Error {
|
|
|
3137
4126
|
declare class ChannelError extends Error {
|
|
3138
4127
|
source: ChannelErrorSource;
|
|
3139
4128
|
error: Error;
|
|
3140
|
-
|
|
4129
|
+
/**
|
|
4130
|
+
* The classification when something other than the error carries it. Absent
|
|
4131
|
+
* means derive it from `error.name`; a dead letter mirrored from a peer sets it,
|
|
4132
|
+
* because only the message crosses the wire.
|
|
4133
|
+
*/
|
|
4134
|
+
readonly errorType?: SyncOperationErrorType;
|
|
4135
|
+
constructor(source: ChannelErrorSource, error: Error, errorType?: SyncOperationErrorType);
|
|
3141
4136
|
}
|
|
3142
4137
|
//#endregion
|
|
3143
4138
|
//#region src/sync/sync-operation.d.ts
|
|
@@ -3736,6 +4731,12 @@ interface ReactorModule {
|
|
|
3736
4731
|
* integration scenarios.
|
|
3737
4732
|
*/
|
|
3738
4733
|
interface InProcessReactorModule extends ReactorModule {
|
|
4734
|
+
/**
|
|
4735
|
+
* The enforcement flags this reactor resolved, as plain booleans. Held on the
|
|
4736
|
+
* module because they select what a read enforces as well as what a write
|
|
4737
|
+
* does, and the read surface is composed outside the reactor.
|
|
4738
|
+
*/
|
|
4739
|
+
featureFlags: ReactorFeatureFlags;
|
|
3739
4740
|
queue: IQueue;
|
|
3740
4741
|
jobTracker: IJobTracker;
|
|
3741
4742
|
executorManager: IJobExecutorManager;
|
|
@@ -3754,6 +4755,12 @@ interface InProcessReactorModule extends ReactorModule {
|
|
|
3754
4755
|
processorManagerConsistencyTracker: IConsistencyTracker;
|
|
3755
4756
|
reactor: IReactor;
|
|
3756
4757
|
syncModule: InProcessSyncModule | undefined;
|
|
4758
|
+
/**
|
|
4759
|
+
* Present when authGroups is on: enqueues re-evaluation jobs for the
|
|
4760
|
+
* documents a group membership change affects. Started by the builder;
|
|
4761
|
+
* hosts shut it down alongside the sync manager.
|
|
4762
|
+
*/
|
|
4763
|
+
groupReevaluationTrigger: GroupReevaluationTrigger | undefined;
|
|
3757
4764
|
/**
|
|
3758
4765
|
* Instrumented pg.Pool handles registered with the builder, either by
|
|
3759
4766
|
* createPostgresDatabase or by withInstrumentedPool. Empty when no pg
|
|
@@ -3815,12 +4822,6 @@ declare class DriveClient implements IDriveClient {
|
|
|
3815
4822
|
private removeFileNode;
|
|
3816
4823
|
}
|
|
3817
4824
|
//#endregion
|
|
3818
|
-
//#region src/cache/collection-membership-cache.d.ts
|
|
3819
|
-
interface ICollectionMembershipCache {
|
|
3820
|
-
getCollectionsForDocuments(documentIds: string[]): Promise<Record<string, string[]>>;
|
|
3821
|
-
invalidate(documentId: string): void;
|
|
3822
|
-
}
|
|
3823
|
-
//#endregion
|
|
3824
4825
|
//#region src/registry/document-model-resolver.d.ts
|
|
3825
4826
|
interface IDocumentModelResolver {
|
|
3826
4827
|
ensureModelLoaded(documentType: string): Promise<void>;
|
|
@@ -3857,60 +4858,28 @@ declare class DocumentModelResolver implements IDocumentModelResolver {
|
|
|
3857
4858
|
* peers (tabs) can load the same type via the event bus.
|
|
3858
4859
|
*/
|
|
3859
4860
|
setModelLoadedHook(hook: (documentType: string) => Promise<void>): void;
|
|
3860
|
-
ensureModelLoaded(documentType: string): Promise<void>;
|
|
3861
|
-
private loadRegisterAndBroadcast;
|
|
3862
|
-
private notifyPeersModelLoaded;
|
|
3863
|
-
}
|
|
3864
|
-
/**
|
|
3865
|
-
* No-op resolver used when no document model loader is configured.
|
|
3866
|
-
* Checks the registry for the model and returns if found; throws if not.
|
|
3867
|
-
* Since there is no loader, missing models cannot be recovered.
|
|
3868
|
-
*/
|
|
3869
|
-
declare class NullDocumentModelResolver implements IDocumentModelResolver {
|
|
3870
|
-
private registry?;
|
|
3871
|
-
constructor(registry?: IDocumentModelRegistry | undefined);
|
|
3872
|
-
ensureModelLoaded(documentType: string): Promise<void>;
|
|
3873
|
-
}
|
|
3874
|
-
//#endregion
|
|
3875
|
-
//#region src/executor/worker-pool-job-executor-manager.d.ts
|
|
3876
|
-
/**
|
|
3877
|
-
* Factory invoked once per worker at `start()` time. The index is the
|
|
3878
|
-
* worker's position in the pool and the same value the manager will use
|
|
3879
|
-
* for sticky routing (`bucketFor(documentId) === index`).
|
|
3880
|
-
*/
|
|
3881
|
-
type WorkerFactory = (index: number) => IExecutorWorker;
|
|
3882
|
-
//#endregion
|
|
3883
|
-
//#region src/cache/write-cache-types.d.ts
|
|
3884
|
-
/**
|
|
3885
|
-
* Configuration options for the write cache
|
|
3886
|
-
*/
|
|
3887
|
-
type WriteCacheConfig = {
|
|
3888
|
-
/** Maximum number of document streams to cache (LRU eviction). Default: 1000 */maxDocuments: number; /** Number of snapshots to keep in each document's ring buffer. Default: 10 */
|
|
3889
|
-
ringBufferSize: number; /** Persist a keyframe snapshot every N revisions. Default: 10 */
|
|
3890
|
-
keyframeInterval: number;
|
|
3891
|
-
};
|
|
3892
|
-
/**
|
|
3893
|
-
* Unique identifier for a document stream
|
|
3894
|
-
*/
|
|
3895
|
-
type DocumentStreamKey = {
|
|
3896
|
-
/** Document identifier */documentId: string; /** Operation scope */
|
|
3897
|
-
scope: string; /** Branch name */
|
|
3898
|
-
branch: string;
|
|
3899
|
-
};
|
|
4861
|
+
ensureModelLoaded(documentType: string): Promise<void>;
|
|
4862
|
+
private loadRegisterAndBroadcast;
|
|
4863
|
+
private notifyPeersModelLoaded;
|
|
4864
|
+
}
|
|
3900
4865
|
/**
|
|
3901
|
-
*
|
|
4866
|
+
* No-op resolver used when no document model loader is configured.
|
|
4867
|
+
* Checks the registry for the model and returns if found; throws if not.
|
|
4868
|
+
* Since there is no loader, missing models cannot be recovered.
|
|
3902
4869
|
*/
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
4870
|
+
declare class NullDocumentModelResolver implements IDocumentModelResolver {
|
|
4871
|
+
private registry?;
|
|
4872
|
+
constructor(registry?: IDocumentModelRegistry | undefined);
|
|
4873
|
+
ensureModelLoaded(documentType: string): Promise<void>;
|
|
4874
|
+
}
|
|
4875
|
+
//#endregion
|
|
4876
|
+
//#region src/executor/worker-pool-job-executor-manager.d.ts
|
|
3907
4877
|
/**
|
|
3908
|
-
*
|
|
4878
|
+
* Factory invoked once per worker at `start()` time. The index is the
|
|
4879
|
+
* worker's position in the pool and the same value the manager will use
|
|
4880
|
+
* for sticky routing (`bucketFor(documentId) === index`).
|
|
3909
4881
|
*/
|
|
3910
|
-
type
|
|
3911
|
-
/** The revision number of this keyframe */revision: number; /** Serialized document state */
|
|
3912
|
-
document: string;
|
|
3913
|
-
};
|
|
4882
|
+
type WorkerFactory = (index: number) => IExecutorWorker;
|
|
3914
4883
|
//#endregion
|
|
3915
4884
|
//#region src/projection/protocol.d.ts
|
|
3916
4885
|
/**
|
|
@@ -4162,6 +5131,7 @@ declare class SyncBuilder {
|
|
|
4162
5131
|
* them (`BaseReadModel` subclasses, in particular).
|
|
4163
5132
|
*/
|
|
4164
5133
|
interface ReadModelFactoryDeps {
|
|
5134
|
+
documentModelRegistry: IDocumentModelRegistry;
|
|
4165
5135
|
operationIndex: IOperationIndex;
|
|
4166
5136
|
writeCache: IWriteCache;
|
|
4167
5137
|
processorManagerConsistencyTracker: IConsistencyTracker;
|
|
@@ -4383,6 +5353,7 @@ declare class ReactorClientBuilder {
|
|
|
4383
5353
|
private subscriptionManager?;
|
|
4384
5354
|
private jobAwaiter?;
|
|
4385
5355
|
private documentModelLoader?;
|
|
5356
|
+
private readGate?;
|
|
4386
5357
|
/**
|
|
4387
5358
|
* Sets the logger for the ReactorClient.
|
|
4388
5359
|
* @param logger - The logger to use.
|
|
@@ -4406,6 +5377,22 @@ declare class ReactorClientBuilder {
|
|
|
4406
5377
|
withSubscriptionManager(subscriptionManager: IReactorSubscriptionManager): this;
|
|
4407
5378
|
withJobAwaiter(jobAwaiter: IJobAwaiter): this;
|
|
4408
5379
|
withDocumentModelLoader(loader: IDocumentModelLoader): this;
|
|
5380
|
+
/**
|
|
5381
|
+
* Overrides how reads are gated. A client built from a ReactorBuilder derives
|
|
5382
|
+
* this from that reactor's flags; one built from `withReactor` cannot, because
|
|
5383
|
+
* it is handed no flags and no registry, so it gates on the policy alone
|
|
5384
|
+
* unless a gate is supplied here.
|
|
5385
|
+
*/
|
|
5386
|
+
withReadGate(readGate: IReadGate): this;
|
|
5387
|
+
/**
|
|
5388
|
+
* The gate this reactor's flags call for. Below authEnforcement there is no
|
|
5389
|
+
* model to enforce -- the registered one ignores the auth scope -- so the
|
|
5390
|
+
* policy is evaluated on its own, which is what reads did before the model
|
|
5391
|
+
* existed. Group serving turns on with authGroups, because below it a
|
|
5392
|
+
* `{ group }` grant does not match, so a served roster is one no grant can
|
|
5393
|
+
* use.
|
|
5394
|
+
*/
|
|
5395
|
+
private resolveReadGate;
|
|
4409
5396
|
build(): Promise<ReactorClient>;
|
|
4410
5397
|
buildModule(): Promise<InProcessReactorClientModule>;
|
|
4411
5398
|
}
|
|
@@ -4500,568 +5487,229 @@ type ParsedPaging = {
|
|
|
4500
5487
|
*/
|
|
4501
5488
|
declare function parsePagingOptions(paging: PagingOptions | undefined, defaultLimit: number): ParsedPaging;
|
|
4502
5489
|
//#endregion
|
|
4503
|
-
//#region src/subs/default-error-handler.d.ts
|
|
4504
|
-
/**
|
|
4505
|
-
* Default error handler that re-throws subscription errors.
|
|
4506
|
-
* This ensures that errors are not silently swallowed.
|
|
4507
|
-
*/
|
|
4508
|
-
declare class DefaultSubscriptionErrorHandler implements ISubscriptionErrorHandler {
|
|
4509
|
-
handleError(error: unknown, context: SubscriptionErrorContext): void;
|
|
4510
|
-
}
|
|
4511
|
-
//#endregion
|
|
4512
|
-
//#region src/subs/react-subscription-manager.d.ts
|
|
4513
|
-
type DocumentCreatedCallback = (result: PagedResults<string>) => void;
|
|
4514
|
-
type DocumentDeletedCallback = (documentIds: string[]) => void;
|
|
4515
|
-
type DocumentStateUpdatedCallback = (result: PagedResults<PHDocument>) => void;
|
|
4516
|
-
type RelationshipChangedCallback = (parentId: string, childId: string, changeType: RelationshipChangeType) => void;
|
|
4517
|
-
declare class ReactorSubscriptionManager implements IReactorSubscriptionManager {
|
|
4518
|
-
private createdSubscriptions;
|
|
4519
|
-
private deletedSubscriptions;
|
|
4520
|
-
private updatedSubscriptions;
|
|
4521
|
-
private relationshipSubscriptions;
|
|
4522
|
-
private subscriptionCounter;
|
|
4523
|
-
private errorHandler;
|
|
4524
|
-
constructor(errorHandler: ISubscriptionErrorHandler);
|
|
4525
|
-
onDocumentCreated(callback: DocumentCreatedCallback, search?: SearchFilter): () => void;
|
|
4526
|
-
onDocumentDeleted(callback: DocumentDeletedCallback, search?: SearchFilter): () => void;
|
|
4527
|
-
onDocumentStateUpdated(callback: DocumentStateUpdatedCallback, search?: SearchFilter, view?: ViewFilter): () => void;
|
|
4528
|
-
onRelationshipChanged(callback: RelationshipChangedCallback, search?: SearchFilter): () => void;
|
|
4529
|
-
/**
|
|
4530
|
-
* Notify subscribers about created documents
|
|
4531
|
-
*/
|
|
4532
|
-
notifyDocumentsCreated(documentIds: string[], documentTypes?: Map<string, string>, parentIds?: Map<string, string | null>): void;
|
|
4533
|
-
/**
|
|
4534
|
-
* Notify subscribers about deleted documents
|
|
4535
|
-
*/
|
|
4536
|
-
notifyDocumentsDeleted(documentIds: string[], documentTypes?: Map<string, string>, parentIds?: Map<string, string | null>): void;
|
|
4537
|
-
/**
|
|
4538
|
-
* Notify subscribers about updated documents
|
|
4539
|
-
*/
|
|
4540
|
-
notifyDocumentsUpdated(documents: PHDocument[]): void;
|
|
4541
|
-
/**
|
|
4542
|
-
* Notify subscribers about relationship changes
|
|
4543
|
-
*/
|
|
4544
|
-
notifyRelationshipChanged(parentId: string, childId: string, changeType: RelationshipChangeType, childType?: string): void;
|
|
4545
|
-
/**
|
|
4546
|
-
* Clear all subscriptions
|
|
4547
|
-
*/
|
|
4548
|
-
clearAll(): void;
|
|
4549
|
-
private filterDocumentIds;
|
|
4550
|
-
private filterDocuments;
|
|
4551
|
-
private matchesRelationshipFilter;
|
|
4552
|
-
}
|
|
4553
|
-
//#endregion
|
|
4554
|
-
//#region src/events/event-bus.d.ts
|
|
4555
|
-
declare class EventBus implements IEventBus {
|
|
4556
|
-
readonly eventTypeToSubscribers: Map<number, Subscriber[]>;
|
|
4557
|
-
subscribe<K>(type: number, subscriber: (type: number, event: K) => void | Promise<void>): Unsubscribe;
|
|
4558
|
-
emit(type: number, data: any): Promise<void>;
|
|
4559
|
-
}
|
|
4560
|
-
//#endregion
|
|
4561
|
-
//#region src/queue/queue.d.ts
|
|
4562
|
-
/**
|
|
4563
|
-
* In-memory implementation of the IQueue interface.
|
|
4564
|
-
* Organizes jobs by documentId, scope, and branch to ensure proper ordering.
|
|
4565
|
-
* Ensures serial execution per document by tracking executing jobs.
|
|
4566
|
-
* Implements dependency management through queue hints.
|
|
4567
|
-
*/
|
|
4568
|
-
declare class InMemoryQueue implements IQueue {
|
|
4569
|
-
private eventBus;
|
|
4570
|
-
private resolver;
|
|
4571
|
-
private queues;
|
|
4572
|
-
private jobIdToQueueKey;
|
|
4573
|
-
private docIdToJobId;
|
|
4574
|
-
private jobIdToDocId;
|
|
4575
|
-
private completedJobs;
|
|
4576
|
-
private jobIndex;
|
|
4577
|
-
private isBlocked;
|
|
4578
|
-
private onDrainedCallback?;
|
|
4579
|
-
private isPausedFlag;
|
|
4580
|
-
constructor(eventBus: IEventBus, resolver: IDocumentModelResolver);
|
|
4581
|
-
private toErrorInfo;
|
|
4582
|
-
/**
|
|
4583
|
-
* Creates a unique key for a document/scope/branch combination
|
|
4584
|
-
*/
|
|
4585
|
-
private createQueueKey;
|
|
4586
|
-
/**
|
|
4587
|
-
* Gets or creates a queue for the given key
|
|
4588
|
-
*/
|
|
4589
|
-
private getQueue;
|
|
4590
|
-
/**
|
|
4591
|
-
* Check if a document has any jobs currently executing
|
|
4592
|
-
*/
|
|
4593
|
-
private isDocumentExecuting;
|
|
4594
|
-
/**
|
|
4595
|
-
* Mark a job as executing for its document
|
|
4596
|
-
*/
|
|
4597
|
-
private markJobExecuting;
|
|
4598
|
-
/**
|
|
4599
|
-
* Mark a job as no longer executing for its document
|
|
4600
|
-
*/
|
|
4601
|
-
private markJobComplete;
|
|
4602
|
-
/**
|
|
4603
|
-
* Check if all dependencies for a job have been completed
|
|
4604
|
-
*/
|
|
4605
|
-
private areDependenciesMet;
|
|
4606
|
-
/**
|
|
4607
|
-
* Returns the head of the sub-queue if its dependencies are met, or null.
|
|
4608
|
-
*
|
|
4609
|
-
* The dispatcher only ever considers the head — a dep-blocked head holds
|
|
4610
|
-
* the rest of its sub-queue. This preserves per-(documentId, scope, branch)
|
|
4611
|
-
* FIFO regardless of how dependencies are authored, and makes the queue's
|
|
4612
|
-
* documented "serialized per document" invariant hold even when callers
|
|
4613
|
-
* omit queueHint dependencies on jobs that share a sub-queue.
|
|
4614
|
-
*/
|
|
4615
|
-
private getNextJobWithMetDependencies;
|
|
4616
|
-
private getCreateDocumentType;
|
|
4617
|
-
enqueue(job: Job): Promise<void>;
|
|
4618
|
-
dequeue(documentId: string, scope: string, branch: string, signal?: AbortSignal): Promise<IJobExecutionHandle | null>;
|
|
4619
|
-
dequeueNext(signal?: AbortSignal): Promise<IJobExecutionHandle | null>;
|
|
4620
|
-
dequeueNextMatching(predicate: (meta: JobRoutingMeta) => boolean, signal?: AbortSignal): Promise<IJobExecutionHandle | null>;
|
|
4621
|
-
size(documentId: string, scope: string, branch: string): Promise<number>;
|
|
4622
|
-
totalSize(): Promise<number>;
|
|
4623
|
-
remove(jobId: string): Promise<boolean>;
|
|
4624
|
-
clear(documentId: string, scope: string, branch: string): Promise<void>;
|
|
4625
|
-
clearAll(): Promise<void>;
|
|
4626
|
-
hasJobs(): Promise<boolean>;
|
|
4627
|
-
completeJob(jobId: string): Promise<void>;
|
|
4628
|
-
failJob(jobId: string, error?: ErrorInfo$1): Promise<void>;
|
|
4629
|
-
deferJob(jobId: string): void;
|
|
4630
|
-
retryJob(jobId: string, error?: ErrorInfo$1): Promise<void>;
|
|
4631
|
-
/**
|
|
4632
|
-
* Check if the queue is drained and call the callback if it is
|
|
4633
|
-
*/
|
|
4634
|
-
private checkDrained;
|
|
4635
|
-
/**
|
|
4636
|
-
* Returns true if and only if all jobs have been resolved.
|
|
4637
|
-
*/
|
|
4638
|
-
get isDrained(): boolean;
|
|
4639
|
-
/**
|
|
4640
|
-
* Blocks the queue from accepting new jobs.
|
|
4641
|
-
* @param onDrained - Optional callback to call when the queue is drained
|
|
4642
|
-
*/
|
|
4643
|
-
block(onDrained?: () => void): void;
|
|
4644
|
-
/**
|
|
4645
|
-
* Unblocks the queue from accepting new jobs.
|
|
4646
|
-
*/
|
|
4647
|
-
unblock(): void;
|
|
4648
|
-
/**
|
|
4649
|
-
* Pauses job dequeuing. Jobs can still be enqueued but dequeueNext() will return null.
|
|
4650
|
-
*/
|
|
4651
|
-
pause(): void;
|
|
4652
|
-
/**
|
|
4653
|
-
* Resumes job dequeuing and emits JOB_AVAILABLE events for pending jobs to wake up executors.
|
|
4654
|
-
*/
|
|
4655
|
-
resume(): Promise<void>;
|
|
4656
|
-
/**
|
|
4657
|
-
* Returns whether job dequeuing is paused.
|
|
4658
|
-
*/
|
|
4659
|
-
get paused(): boolean;
|
|
4660
|
-
/**
|
|
4661
|
-
* Returns all pending jobs across all queues.
|
|
4662
|
-
*/
|
|
4663
|
-
getPendingJobs(): Job[];
|
|
4664
|
-
/**
|
|
4665
|
-
* Returns a map of document IDs to sets of executing job IDs.
|
|
4666
|
-
*/
|
|
4667
|
-
getExecutingJobIds(): Map<string, Set<string>>;
|
|
4668
|
-
/**
|
|
4669
|
-
* Returns a job by ID from the job index.
|
|
4670
|
-
*/
|
|
4671
|
-
getJob(jobId: string): Job | undefined;
|
|
4672
|
-
}
|
|
4673
|
-
//#endregion
|
|
4674
|
-
//#region src/job-tracker/in-memory-job-tracker.d.ts
|
|
4675
|
-
/**
|
|
4676
|
-
* In-memory implementation of IJobTracker.
|
|
4677
|
-
* Maintains job status in a Map for synchronous access.
|
|
4678
|
-
* Subscribes to operation events to update job states.
|
|
4679
|
-
*/
|
|
4680
|
-
declare class InMemoryJobTracker implements IJobTracker {
|
|
4681
|
-
private eventBus;
|
|
4682
|
-
private jobs;
|
|
4683
|
-
private unsubscribers;
|
|
4684
|
-
constructor(eventBus: IEventBus);
|
|
4685
|
-
private subscribeToEvents;
|
|
4686
|
-
private handleWriteReady;
|
|
4687
|
-
private handleReadReady;
|
|
4688
|
-
private handleJobFailed;
|
|
4689
|
-
shutdown(): void;
|
|
4690
|
-
registerJob(jobInfo: JobInfo): void;
|
|
4691
|
-
markRunning(jobId: string): void;
|
|
4692
|
-
markFailed(jobId: string, error: ErrorInfo$1, job?: Job): void;
|
|
4693
|
-
getJobStatus(jobId: string): JobInfo | null;
|
|
4694
|
-
}
|
|
4695
|
-
//#endregion
|
|
4696
|
-
//#region src/executor/simple-job-executor-manager.d.ts
|
|
4697
|
-
type JobExecutorFactory = () => IJobExecutor;
|
|
4698
|
-
/**
|
|
4699
|
-
* Manages multiple job executors and coordinates job distribution.
|
|
4700
|
-
* Listens for job available events and dispatches jobs to executors.
|
|
4701
|
-
*/
|
|
4702
|
-
declare class SimpleJobExecutorManager implements IJobExecutorManager {
|
|
4703
|
-
private executorFactory;
|
|
4704
|
-
private eventBus;
|
|
4705
|
-
private queue;
|
|
4706
|
-
private jobTracker;
|
|
4707
|
-
private logger;
|
|
4708
|
-
private resolver;
|
|
4709
|
-
private executors;
|
|
4710
|
-
private isRunning;
|
|
4711
|
-
private activeJobs;
|
|
4712
|
-
private totalJobsProcessed;
|
|
4713
|
-
private unsubscribe?;
|
|
4714
|
-
private deferredJobs;
|
|
4715
|
-
private resultHandler;
|
|
4716
|
-
private jobTimeoutMs;
|
|
4717
|
-
constructor(executorFactory: JobExecutorFactory, eventBus: IEventBus, queue: IQueue, jobTracker: IJobTracker, logger: ILogger, resolver: IDocumentModelResolver, jobTimeoutMs?: number);
|
|
4718
|
-
start(numExecutors: number): Promise<void>;
|
|
4719
|
-
stop(graceful?: boolean): Promise<void>;
|
|
4720
|
-
getExecutors(): IJobExecutor[];
|
|
4721
|
-
getStatus(): ExecutorManagerStatus;
|
|
4722
|
-
private processNextJob;
|
|
4723
|
-
private checkForMoreJobs;
|
|
4724
|
-
private processExistingJobs;
|
|
4725
|
-
private flushDeferredJobs;
|
|
4726
|
-
}
|
|
4727
|
-
//#endregion
|
|
4728
|
-
//#region src/cache/document-meta-cache-types.d.ts
|
|
5490
|
+
//#region src/subs/default-error-handler.d.ts
|
|
4729
5491
|
/**
|
|
4730
|
-
*
|
|
4731
|
-
*
|
|
4732
|
-
* This lightweight structure holds essential document information needed by
|
|
4733
|
-
* the job executor without fetching full scope state. It provides an explicit
|
|
4734
|
-
* cross-scope contract for accessing document scope metadata.
|
|
5492
|
+
* Default error handler that re-throws subscription errors.
|
|
5493
|
+
* This ensures that errors are not silently swallowed.
|
|
4735
5494
|
*/
|
|
4736
|
-
|
|
5495
|
+
declare class DefaultSubscriptionErrorHandler implements ISubscriptionErrorHandler {
|
|
5496
|
+
handleError(error: unknown, context: SubscriptionErrorContext): void;
|
|
5497
|
+
}
|
|
5498
|
+
//#endregion
|
|
5499
|
+
//#region src/subs/react-subscription-manager.d.ts
|
|
5500
|
+
type DocumentCreatedCallback = (result: PagedResults<string>) => void;
|
|
5501
|
+
type DocumentDeletedCallback = (documentIds: string[]) => void;
|
|
5502
|
+
type DocumentStateUpdatedCallback = (result: PagedResults<PHDocument>) => void;
|
|
5503
|
+
type RelationshipChangedCallback = (parentId: string, childId: string, changeType: RelationshipChangeType) => void;
|
|
5504
|
+
declare class ReactorSubscriptionManager implements IReactorSubscriptionManager {
|
|
5505
|
+
private createdSubscriptions;
|
|
5506
|
+
private deletedSubscriptions;
|
|
5507
|
+
private updatedSubscriptions;
|
|
5508
|
+
private relationshipSubscriptions;
|
|
5509
|
+
private subscriptionCounter;
|
|
5510
|
+
private errorHandler;
|
|
5511
|
+
constructor(errorHandler: ISubscriptionErrorHandler);
|
|
5512
|
+
onDocumentCreated(callback: DocumentCreatedCallback, search?: SearchFilter): () => void;
|
|
5513
|
+
onDocumentDeleted(callback: DocumentDeletedCallback, search?: SearchFilter): () => void;
|
|
5514
|
+
onDocumentStateUpdated(callback: DocumentStateUpdatedCallback, search?: SearchFilter, view?: ViewFilter): () => void;
|
|
5515
|
+
onRelationshipChanged(callback: RelationshipChangedCallback, search?: SearchFilter): () => void;
|
|
4737
5516
|
/**
|
|
4738
|
-
*
|
|
4739
|
-
* Contains version, hash, isDeleted, deletedAtUtcIso, etc.
|
|
5517
|
+
* Notify subscribers about created documents
|
|
4740
5518
|
*/
|
|
4741
|
-
|
|
5519
|
+
notifyDocumentsCreated(documentIds: string[], documentTypes?: Map<string, string>, parentIds?: Map<string, string | null>): void;
|
|
4742
5520
|
/**
|
|
4743
|
-
*
|
|
5521
|
+
* Notify subscribers about deleted documents
|
|
4744
5522
|
*/
|
|
4745
|
-
|
|
5523
|
+
notifyDocumentsDeleted(documentIds: string[], documentTypes?: Map<string, string>, parentIds?: Map<string, string | null>): void;
|
|
4746
5524
|
/**
|
|
4747
|
-
*
|
|
4748
|
-
* Used for cache invalidation and consistency checks.
|
|
5525
|
+
* Notify subscribers about updated documents
|
|
4749
5526
|
*/
|
|
4750
|
-
|
|
4751
|
-
};
|
|
4752
|
-
/**
|
|
4753
|
-
* Interface for the document metadata cache.
|
|
4754
|
-
*
|
|
4755
|
-
* This cache provides an explicit cross-scope contract for accessing document
|
|
4756
|
-
* scope metadata. It solves the problem where job execution in one scope (e.g.,
|
|
4757
|
-
* "global") needs access to document scope state (version, isDeleted, etc.)
|
|
4758
|
-
* which may be stale in scope-specific caches or keyframes.
|
|
4759
|
-
*
|
|
4760
|
-
* The cache supports:
|
|
4761
|
-
* - Latest metadata retrieval with LRU caching
|
|
4762
|
-
* - Historical metadata reconstruction for reshuffling scenarios
|
|
4763
|
-
* - Eager updates after document scope operations
|
|
4764
|
-
*/
|
|
4765
|
-
interface IDocumentMetaCache {
|
|
5527
|
+
notifyDocumentsUpdated(documents: PHDocument[]): void;
|
|
4766
5528
|
/**
|
|
4767
|
-
*
|
|
4768
|
-
*
|
|
4769
|
-
* On cache miss, fetches all document scope operations and reconstructs the
|
|
4770
|
-
* current PHDocumentState by applying UPGRADE_DOCUMENT and DELETE_DOCUMENT
|
|
4771
|
-
* operations.
|
|
4772
|
-
*
|
|
4773
|
-
* @param documentId - The document identifier
|
|
4774
|
-
* @param branch - Branch name
|
|
4775
|
-
* @param signal - Optional abort signal to cancel the operation
|
|
4776
|
-
* @returns The cached or rebuilt document metadata
|
|
4777
|
-
* @throws {Error} "Operation aborted" if signal is aborted
|
|
4778
|
-
* @throws {Error} If document not found (no CREATE_DOCUMENT operation)
|
|
5529
|
+
* Notify subscribers about relationship changes
|
|
4779
5530
|
*/
|
|
4780
|
-
|
|
5531
|
+
notifyRelationshipChanged(parentId: string, childId: string, changeType: RelationshipChangeType, childType?: string): void;
|
|
4781
5532
|
/**
|
|
4782
|
-
*
|
|
4783
|
-
*
|
|
4784
|
-
* Used during reshuffling when operations need to be inserted at a previous
|
|
4785
|
-
* revision and we need the document scope state as of that point in time.
|
|
4786
|
-
*
|
|
4787
|
-
* @param documentId - The document identifier
|
|
4788
|
-
* @param branch - Branch name
|
|
4789
|
-
* @param targetRevision - The document scope revision to reconstruct up to
|
|
4790
|
-
* @param signal - Optional abort signal to cancel the operation
|
|
4791
|
-
* @returns Document metadata as of the target revision
|
|
4792
|
-
* @throws {Error} "Operation aborted" if signal is aborted
|
|
4793
|
-
* @throws {Error} If document not found
|
|
5533
|
+
* Clear all subscriptions
|
|
4794
5534
|
*/
|
|
4795
|
-
|
|
5535
|
+
clearAll(): void;
|
|
5536
|
+
private filterDocumentIds;
|
|
5537
|
+
private filterDocuments;
|
|
5538
|
+
private matchesRelationshipFilter;
|
|
5539
|
+
}
|
|
5540
|
+
//#endregion
|
|
5541
|
+
//#region src/events/event-bus.d.ts
|
|
5542
|
+
declare class EventBus implements IEventBus {
|
|
5543
|
+
readonly eventTypeToSubscribers: Map<number, Subscriber[]>;
|
|
5544
|
+
subscribe<K>(type: number, subscriber: (type: number, event: K) => void | Promise<void>): Unsubscribe;
|
|
5545
|
+
emit(type: number, data: any): Promise<void>;
|
|
5546
|
+
}
|
|
5547
|
+
//#endregion
|
|
5548
|
+
//#region src/queue/queue.d.ts
|
|
5549
|
+
/**
|
|
5550
|
+
* In-memory implementation of the IQueue interface.
|
|
5551
|
+
* Organizes jobs by documentId, scope, and branch to ensure proper ordering.
|
|
5552
|
+
* Ensures serial execution per document by tracking executing jobs.
|
|
5553
|
+
* Implements dependency management through queue hints.
|
|
5554
|
+
*/
|
|
5555
|
+
declare class InMemoryQueue implements IQueue {
|
|
5556
|
+
private eventBus;
|
|
5557
|
+
private resolver;
|
|
5558
|
+
private queues;
|
|
5559
|
+
private jobIdToQueueKey;
|
|
5560
|
+
private docIdToJobId;
|
|
5561
|
+
private jobIdToDocId;
|
|
5562
|
+
private completedJobs;
|
|
5563
|
+
private jobIndex;
|
|
5564
|
+
private isBlocked;
|
|
5565
|
+
private onDrainedCallback?;
|
|
5566
|
+
private isPausedFlag;
|
|
5567
|
+
constructor(eventBus: IEventBus, resolver: IDocumentModelResolver);
|
|
5568
|
+
private toErrorInfo;
|
|
4796
5569
|
/**
|
|
4797
|
-
*
|
|
4798
|
-
*
|
|
4799
|
-
* Called by the job executor after CREATE_DOCUMENT, UPGRADE_DOCUMENT, or
|
|
4800
|
-
* DELETE_DOCUMENT operations to keep the cache current.
|
|
4801
|
-
*
|
|
4802
|
-
* @param documentId - The document identifier
|
|
4803
|
-
* @param branch - Branch name
|
|
4804
|
-
* @param meta - The new metadata to cache
|
|
5570
|
+
* Creates a unique key for a document/scope/branch combination
|
|
4805
5571
|
*/
|
|
4806
|
-
|
|
5572
|
+
private createQueueKey;
|
|
4807
5573
|
/**
|
|
4808
|
-
*
|
|
4809
|
-
*
|
|
4810
|
-
* Call before reshuffling operations that modify the document scope, or
|
|
4811
|
-
* when document state may have changed externally.
|
|
4812
|
-
*
|
|
4813
|
-
* @param documentId - The document identifier
|
|
4814
|
-
* @param branch - Optional branch to narrow invalidation (if omitted, all branches)
|
|
4815
|
-
* @returns Number of entries invalidated
|
|
5574
|
+
* Gets or creates a queue for the given key
|
|
4816
5575
|
*/
|
|
4817
|
-
|
|
5576
|
+
private getQueue;
|
|
4818
5577
|
/**
|
|
4819
|
-
*
|
|
5578
|
+
* Check if a document has any jobs currently executing
|
|
4820
5579
|
*/
|
|
4821
|
-
|
|
5580
|
+
private isDocumentExecuting;
|
|
4822
5581
|
/**
|
|
4823
|
-
*
|
|
5582
|
+
* Mark a job as executing for its document
|
|
4824
5583
|
*/
|
|
4825
|
-
|
|
5584
|
+
private markJobExecuting;
|
|
4826
5585
|
/**
|
|
4827
|
-
*
|
|
5586
|
+
* Mark a job as no longer executing for its document
|
|
4828
5587
|
*/
|
|
4829
|
-
|
|
4830
|
-
}
|
|
4831
|
-
//#endregion
|
|
4832
|
-
//#region src/cache/buffer/ring-buffer.d.ts
|
|
4833
|
-
/**
|
|
4834
|
-
* RingBuffer is a generic circular buffer implementation that stores a fixed number
|
|
4835
|
-
* of items. When the buffer is full, new items overwrite the oldest items.
|
|
4836
|
-
*
|
|
4837
|
-
* This implementation maintains O(1) time complexity for push operations and provides
|
|
4838
|
-
* items in chronological order (oldest to newest) via getAll().
|
|
4839
|
-
*
|
|
4840
|
-
* @template T - The type of items stored in the buffer
|
|
4841
|
-
*/
|
|
4842
|
-
declare class RingBuffer<T> {
|
|
4843
|
-
private buffer;
|
|
4844
|
-
private head;
|
|
4845
|
-
private size;
|
|
4846
|
-
private capacity;
|
|
4847
|
-
constructor(capacity: number);
|
|
5588
|
+
private markJobComplete;
|
|
4848
5589
|
/**
|
|
4849
|
-
*
|
|
4850
|
-
*
|
|
4851
|
-
* @param item - The item to add
|
|
5590
|
+
* Check if all dependencies for a job have been completed
|
|
4852
5591
|
*/
|
|
4853
|
-
|
|
5592
|
+
private areDependenciesMet;
|
|
4854
5593
|
/**
|
|
4855
|
-
* Returns
|
|
5594
|
+
* Returns the head of the sub-queue if its dependencies are met, or null.
|
|
4856
5595
|
*
|
|
4857
|
-
*
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
*
|
|
4862
|
-
*/
|
|
4863
|
-
clear(): void;
|
|
4864
|
-
/**
|
|
4865
|
-
* Gets the current number of items in the buffer.
|
|
5596
|
+
* The dispatcher only ever considers the head — a dep-blocked head holds
|
|
5597
|
+
* the rest of its sub-queue. This preserves per-(documentId, scope, branch)
|
|
5598
|
+
* FIFO regardless of how dependencies are authored, and makes the queue's
|
|
5599
|
+
* documented "serialized per document" invariant hold even when callers
|
|
5600
|
+
* omit queueHint dependencies on jobs that share a sub-queue.
|
|
4866
5601
|
*/
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
* - Cold miss: O(n) where n is total operation count, or O(k) where k is operations since keyframe
|
|
4884
|
-
* - Warm miss: O(m) where m is operations since cached revision
|
|
4885
|
-
* - Eviction: O(1) for LRU tracking and removal
|
|
4886
|
-
*
|
|
4887
|
-
* **Thread Safety:**
|
|
4888
|
-
* Not thread-safe. Designed for single-threaded job executor environment.
|
|
4889
|
-
* External synchronization required for concurrent access across multiple executors.
|
|
4890
|
-
*
|
|
4891
|
-
* **Example:**
|
|
4892
|
-
* ```typescript
|
|
4893
|
-
* const cache = new KyselyWriteCache(
|
|
4894
|
-
* keyframeStore,
|
|
4895
|
-
* operationStore,
|
|
4896
|
-
* registry,
|
|
4897
|
-
* { maxDocuments: 1000, ringBufferSize: 10, keyframeInterval: 10 }
|
|
4898
|
-
* );
|
|
4899
|
-
*
|
|
4900
|
-
* await cache.startup();
|
|
4901
|
-
*
|
|
4902
|
-
* // Retrieve or rebuild document
|
|
4903
|
-
* const doc = await cache.getState(docId, docType, scope, branch, revision);
|
|
4904
|
-
*
|
|
4905
|
-
* // Cache result after job execution
|
|
4906
|
-
* cache.putState(docId, docType, scope, branch, newRevision, updatedDoc);
|
|
4907
|
-
*
|
|
4908
|
-
* await cache.shutdown();
|
|
4909
|
-
* ```
|
|
4910
|
-
*/
|
|
4911
|
-
declare class KyselyWriteCache implements IWriteCache {
|
|
4912
|
-
private streams;
|
|
4913
|
-
private lruTracker;
|
|
4914
|
-
private keyframeStore;
|
|
4915
|
-
private operationStore;
|
|
4916
|
-
private registry;
|
|
4917
|
-
private config;
|
|
4918
|
-
constructor(keyframeStore: IKeyframeStore, operationStore: IOperationStore, registry: IDocumentModelRegistry, config: WriteCacheConfig);
|
|
4919
|
-
withScopedStores(operationStore: IOperationStore, keyframeStore: IKeyframeStore): KyselyWriteCache;
|
|
5602
|
+
private getNextJobWithMetDependencies;
|
|
5603
|
+
private getCreateDocumentType;
|
|
5604
|
+
enqueue(job: Job): Promise<void>;
|
|
5605
|
+
dequeue(documentId: string, scope: string, branch: string, signal?: AbortSignal): Promise<IJobExecutionHandle | null>;
|
|
5606
|
+
dequeueNext(signal?: AbortSignal): Promise<IJobExecutionHandle | null>;
|
|
5607
|
+
dequeueNextMatching(predicate: (meta: JobRoutingMeta) => boolean, signal?: AbortSignal): Promise<IJobExecutionHandle | null>;
|
|
5608
|
+
size(documentId: string, scope: string, branch: string): Promise<number>;
|
|
5609
|
+
totalSize(): Promise<number>;
|
|
5610
|
+
remove(jobId: string): Promise<boolean>;
|
|
5611
|
+
clear(documentId: string, scope: string, branch: string): Promise<void>;
|
|
5612
|
+
clearAll(): Promise<void>;
|
|
5613
|
+
hasJobs(): Promise<boolean>;
|
|
5614
|
+
completeJob(jobId: string): Promise<void>;
|
|
5615
|
+
failJob(jobId: string, error?: ErrorInfo$1): Promise<void>;
|
|
5616
|
+
deferJob(jobId: string): void;
|
|
5617
|
+
retryJob(jobId: string, error?: ErrorInfo$1, accounting?: RetryAccounting): Promise<void>;
|
|
4920
5618
|
/**
|
|
4921
|
-
*
|
|
4922
|
-
* Currently a no-op as keyframe store lifecycle is managed externally.
|
|
5619
|
+
* Check if the queue is drained and call the callback if it is
|
|
4923
5620
|
*/
|
|
4924
|
-
|
|
5621
|
+
private checkDrained;
|
|
4925
5622
|
/**
|
|
4926
|
-
*
|
|
4927
|
-
* Currently a no-op as keyframe store lifecycle is managed externally.
|
|
5623
|
+
* Returns true if and only if all jobs have been resolved.
|
|
4928
5624
|
*/
|
|
4929
|
-
|
|
5625
|
+
get isDrained(): boolean;
|
|
4930
5626
|
/**
|
|
4931
|
-
*
|
|
4932
|
-
*
|
|
4933
|
-
* Cache hit path: Returns cached snapshot if available (O(1))
|
|
4934
|
-
* Warm miss path: Rebuilds from cached base revision + incremental ops
|
|
4935
|
-
* Cold miss path: Rebuilds from keyframe or from scratch using all operations
|
|
4936
|
-
*
|
|
4937
|
-
* @param documentId - The document identifier
|
|
4938
|
-
* @param scope - The operation scope
|
|
4939
|
-
* @param branch - The operation branch
|
|
4940
|
-
* @param targetRevision - The target revision, or undefined for newest
|
|
4941
|
-
* @param signal - Optional abort signal to cancel the operation
|
|
4942
|
-
* @returns The document at the target revision
|
|
4943
|
-
* @throws {Error} "Operation aborted" if signal is aborted
|
|
4944
|
-
* @throws {ModuleNotFoundError} If document type not registered in registry
|
|
4945
|
-
* @throws {Error} "Failed to rebuild document" if operation store fails
|
|
4946
|
-
* @throws {Error} If reducer throws during operation application
|
|
4947
|
-
* @throws {Error} If document serialization fails
|
|
5627
|
+
* Blocks the queue from accepting new jobs.
|
|
5628
|
+
* @param onDrained - Optional callback to call when the queue is drained
|
|
4948
5629
|
*/
|
|
4949
|
-
|
|
5630
|
+
block(onDrained?: () => void): void;
|
|
4950
5631
|
/**
|
|
4951
|
-
*
|
|
4952
|
-
*
|
|
4953
|
-
* The cached document is a shallow copy of the input with its operation history
|
|
4954
|
-
* truncated to the last operation per scope and its clipboard cleared. This keeps
|
|
4955
|
-
* memory use and copy costs constant regardless of operation count. Consumers of
|
|
4956
|
-
* getState() must not rely on the full operation history being present; the only
|
|
4957
|
-
* guaranteed invariant is that operations[scope].at(-1) reflects the latest
|
|
4958
|
-
* operation index for each scope.
|
|
4959
|
-
*
|
|
4960
|
-
* Updates LRU tracker and may evict least recently used stream if at capacity.
|
|
4961
|
-
* Asynchronously persists keyframes at configured intervals (fire-and-forget).
|
|
4962
|
-
*
|
|
4963
|
-
* @param documentId - The document identifier
|
|
4964
|
-
* @param scope - The operation scope
|
|
4965
|
-
* @param branch - The operation branch
|
|
4966
|
-
* @param revision - The revision number
|
|
4967
|
-
* @param document - The document to cache
|
|
4968
|
-
* @throws {Error} If document serialization fails
|
|
5632
|
+
* Unblocks the queue from accepting new jobs.
|
|
4969
5633
|
*/
|
|
4970
|
-
|
|
5634
|
+
unblock(): void;
|
|
4971
5635
|
/**
|
|
4972
|
-
*
|
|
4973
|
-
*
|
|
4974
|
-
* Supports three invalidation scopes:
|
|
4975
|
-
* - Document-level: invalidate(documentId) - removes all streams for document
|
|
4976
|
-
* - Scope-level: invalidate(documentId, scope) - removes all branches for scope
|
|
4977
|
-
* - Stream-level: invalidate(documentId, scope, branch) - removes specific stream
|
|
4978
|
-
*
|
|
4979
|
-
* @param documentId - The document identifier
|
|
4980
|
-
* @param scope - Optional scope to narrow invalidation
|
|
4981
|
-
* @param branch - Optional branch to narrow invalidation (requires scope)
|
|
4982
|
-
* @returns The number of streams evicted
|
|
5636
|
+
* Pauses job dequeuing. Jobs can still be enqueued but dequeueNext() will return null.
|
|
4983
5637
|
*/
|
|
4984
|
-
|
|
5638
|
+
pause(): void;
|
|
4985
5639
|
/**
|
|
4986
|
-
*
|
|
4987
|
-
* Resets LRU tracking state. This operation always succeeds.
|
|
5640
|
+
* Resumes job dequeuing and emits JOB_AVAILABLE events for pending jobs to wake up executors.
|
|
4988
5641
|
*/
|
|
4989
|
-
|
|
5642
|
+
resume(): Promise<void>;
|
|
4990
5643
|
/**
|
|
4991
|
-
*
|
|
4992
|
-
* for testing, but not on the interface.
|
|
4993
|
-
*
|
|
4994
|
-
* @internal
|
|
5644
|
+
* Returns whether job dequeuing is paused.
|
|
4995
5645
|
*/
|
|
4996
|
-
|
|
4997
|
-
private findNearestKeyframe;
|
|
4998
|
-
private coldMissRebuild;
|
|
5646
|
+
get paused(): boolean;
|
|
4999
5647
|
/**
|
|
5000
|
-
*
|
|
5001
|
-
*
|
|
5002
|
-
* Uses the validated-upgrade boundary rules from D7:
|
|
5003
|
-
* - If `input.revision` is present: op.index < revision[scope] → before the upgrade boundary
|
|
5004
|
-
* - Otherwise: timestamp fallback
|
|
5005
|
-
* - Falls back to final module version when neither is decidable
|
|
5648
|
+
* Returns all pending jobs across all queues.
|
|
5006
5649
|
*/
|
|
5007
|
-
|
|
5008
|
-
|
|
5009
|
-
|
|
5010
|
-
|
|
5011
|
-
|
|
5012
|
-
|
|
5013
|
-
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
declare class KyselyOperationStore implements IOperationStore {
|
|
5017
|
-
private db;
|
|
5018
|
-
private trx?;
|
|
5019
|
-
constructor(db: Kysely<Database$1>);
|
|
5020
|
-
private get queryExecutor();
|
|
5021
|
-
withTransaction(trx: Transaction<Database$1>): KyselyOperationStore;
|
|
5022
|
-
apply(documentId: string, documentType: string, scope: string, branch: string, revision: number, fn: (txn: AtomicTxn) => void | Promise<void>, signal?: AbortSignal): Promise<Operation[]>;
|
|
5023
|
-
private resolveUniqueConstraint;
|
|
5024
|
-
private executeApply;
|
|
5025
|
-
private findIdempotentReplay;
|
|
5026
|
-
getSince(documentId: string, scope: string, branch: string, revision: number, filter?: OperationFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<Operation>>;
|
|
5027
|
-
getSinceId(id: number, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<OperationWithContext$1>>;
|
|
5028
|
-
getConflicting(documentId: string, scope: string, branch: string, minTimestamp: string, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<Operation>>;
|
|
5029
|
-
getRevisions(documentId: string, branch: string, signal?: AbortSignal): Promise<DocumentRevisions>;
|
|
5030
|
-
private rowToOperation;
|
|
5031
|
-
private rowToOperationWithContext;
|
|
5650
|
+
getPendingJobs(): Job[];
|
|
5651
|
+
/**
|
|
5652
|
+
* Returns a map of document IDs to sets of executing job IDs.
|
|
5653
|
+
*/
|
|
5654
|
+
getExecutingJobIds(): Map<string, Set<string>>;
|
|
5655
|
+
/**
|
|
5656
|
+
* Returns a job by ID from the job index.
|
|
5657
|
+
*/
|
|
5658
|
+
getJob(jobId: string): Job | undefined;
|
|
5032
5659
|
}
|
|
5033
5660
|
//#endregion
|
|
5034
|
-
//#region src/
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5661
|
+
//#region src/job-tracker/in-memory-job-tracker.d.ts
|
|
5662
|
+
/**
|
|
5663
|
+
* In-memory implementation of IJobTracker.
|
|
5664
|
+
* Maintains job status in a Map for synchronous access.
|
|
5665
|
+
* Subscribes to operation events to update job states.
|
|
5666
|
+
*/
|
|
5667
|
+
declare class InMemoryJobTracker implements IJobTracker {
|
|
5668
|
+
private eventBus;
|
|
5669
|
+
private jobs;
|
|
5670
|
+
private unsubscribers;
|
|
5671
|
+
constructor(eventBus: IEventBus);
|
|
5672
|
+
private subscribeToEvents;
|
|
5673
|
+
private handleWriteReady;
|
|
5674
|
+
private handleReadReady;
|
|
5675
|
+
private handleJobFailed;
|
|
5676
|
+
shutdown(): void;
|
|
5677
|
+
registerJob(jobInfo: JobInfo): void;
|
|
5678
|
+
markRunning(jobId: string): void;
|
|
5679
|
+
markFailed(jobId: string, error: ErrorInfo$1, job?: Job): void;
|
|
5680
|
+
getJobStatus(jobId: string): JobInfo | null;
|
|
5053
5681
|
}
|
|
5054
5682
|
//#endregion
|
|
5055
|
-
//#region src/executor/
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5683
|
+
//#region src/executor/simple-job-executor-manager.d.ts
|
|
5684
|
+
type JobExecutorFactory = () => IJobExecutor;
|
|
5685
|
+
/**
|
|
5686
|
+
* Manages multiple job executors and coordinates job distribution.
|
|
5687
|
+
* Listens for job available events and dispatches jobs to executors.
|
|
5688
|
+
*/
|
|
5689
|
+
declare class SimpleJobExecutorManager implements IJobExecutorManager {
|
|
5690
|
+
private executorFactory;
|
|
5691
|
+
private eventBus;
|
|
5692
|
+
private queue;
|
|
5693
|
+
private jobTracker;
|
|
5694
|
+
private logger;
|
|
5695
|
+
private resolver;
|
|
5696
|
+
private executors;
|
|
5697
|
+
private isRunning;
|
|
5698
|
+
private activeJobs;
|
|
5699
|
+
private totalJobsProcessed;
|
|
5700
|
+
private unsubscribe?;
|
|
5701
|
+
private deferredJobs;
|
|
5702
|
+
private resultHandler;
|
|
5703
|
+
private jobTimeoutMs;
|
|
5704
|
+
constructor(executorFactory: JobExecutorFactory, eventBus: IEventBus, queue: IQueue, jobTracker: IJobTracker, logger: ILogger, resolver: IDocumentModelResolver, jobTimeoutMs?: number);
|
|
5705
|
+
start(numExecutors: number): Promise<void>;
|
|
5706
|
+
stop(graceful?: boolean): Promise<void>;
|
|
5707
|
+
getExecutors(): IJobExecutor[];
|
|
5708
|
+
getStatus(): ExecutorManagerStatus;
|
|
5709
|
+
private processNextJob;
|
|
5710
|
+
private checkForMoreJobs;
|
|
5711
|
+
private processExistingJobs;
|
|
5712
|
+
private flushDeferredJobs;
|
|
5065
5713
|
}
|
|
5066
5714
|
//#endregion
|
|
5067
5715
|
//#region src/executor/simple-job-executor.d.ts
|
|
@@ -5079,6 +5727,8 @@ declare class SimpleJobExecutor implements IJobExecutor {
|
|
|
5079
5727
|
private collectionMembershipCache;
|
|
5080
5728
|
private driveContainerTypes;
|
|
5081
5729
|
private config;
|
|
5730
|
+
private featureFlags;
|
|
5731
|
+
private decisionModel;
|
|
5082
5732
|
private signatureVerifierModule;
|
|
5083
5733
|
private documentActionHandler;
|
|
5084
5734
|
private executionScope;
|
|
@@ -5091,6 +5741,69 @@ declare class SimpleJobExecutor implements IJobExecutor {
|
|
|
5091
5741
|
private getCollectionMembershipsForOperations;
|
|
5092
5742
|
private processActions;
|
|
5093
5743
|
private executeRegularAction;
|
|
5744
|
+
/**
|
|
5745
|
+
* Orders a write by timestamp and decides it where it lands. The caller
|
|
5746
|
+
* supplies the timestamp, so a write can belong before operations already
|
|
5747
|
+
* stored; those are re-appended alongside it, the way a load reshuffles.
|
|
5748
|
+
*
|
|
5749
|
+
* Deciding a backdated write at the stream heads instead of at its position
|
|
5750
|
+
* would overwrite the verdict every other replica computes for it.
|
|
5751
|
+
*/
|
|
5752
|
+
private positionByTimestamp;
|
|
5753
|
+
/**
|
|
5754
|
+
* Decides each operation where it lands and carries the verdict on it. A
|
|
5755
|
+
* refused submitted action is reported to the caller and nothing is stored; a
|
|
5756
|
+
* refused operation the reshuffle merely moved keeps its verdict, because it
|
|
5757
|
+
* already holds a position.
|
|
5758
|
+
*
|
|
5759
|
+
* The operations carry the indexes and skips they will be stored at, because
|
|
5760
|
+
* the walk resolves skips before it orders them.
|
|
5761
|
+
*/
|
|
5762
|
+
private evaluatePositioned;
|
|
5763
|
+
/**
|
|
5764
|
+
* The scopes a re-evaluation pass visits, in a fixed order.
|
|
5765
|
+
*
|
|
5766
|
+
* The revisions map comes from a query with no ORDER BY, and the order is
|
|
5767
|
+
* load-bearing: each scope's pass re-reads the auth stream, and the walk skips
|
|
5768
|
+
* an operation by its stored denial, so a denial this pass just wrote is
|
|
5769
|
+
* visible to a later-visited scope and invisible to an earlier one. The model's
|
|
5770
|
+
* own projection order leads, then the rest sorted, so the pass is reproducible
|
|
5771
|
+
* across replicas and across runs.
|
|
5772
|
+
*/
|
|
5773
|
+
private evaluationOrder;
|
|
5774
|
+
/**
|
|
5775
|
+
* The first timestamp in the batch that does not strictly exceed everything
|
|
5776
|
+
* ahead of it, or undefined when the whole batch is monotonic.
|
|
5777
|
+
*
|
|
5778
|
+
* The bound is carried forward rather than compared against one stored maximum,
|
|
5779
|
+
* because a single execute can carry several auth actions stamped in the same
|
|
5780
|
+
* millisecond. Letting a tie through would store a stream the position walk
|
|
5781
|
+
* then refuses to read, with no repair path.
|
|
5782
|
+
*/
|
|
5783
|
+
private firstNonMonotonicTimestamp;
|
|
5784
|
+
/** The operations a batch of submitted actions appends at the scope's tail. */
|
|
5785
|
+
private appendedOperations;
|
|
5786
|
+
/**
|
|
5787
|
+
* Re-evaluates the document when a write meets both criteria: it was written
|
|
5788
|
+
* to a stream the model reads, and it is timestamped before an operation
|
|
5789
|
+
* already stored. The caller supplies the timestamp and the reactor does not replace
|
|
5790
|
+
* it, so a mutation job can write such an operation just as a load job can,
|
|
5791
|
+
* which is why both executeJob and executeLoadJob call this.
|
|
5792
|
+
*/
|
|
5793
|
+
private reevaluateIfCriteriaMet;
|
|
5794
|
+
/**
|
|
5795
|
+
* Re-evaluates every scope the model evaluates. Where an operation's
|
|
5796
|
+
* evaluation differs from what is stored, the tail from that operation is
|
|
5797
|
+
* re-appended, carrying a skip that spans the indices it supersedes.
|
|
5798
|
+
*/
|
|
5799
|
+
private reevaluateDocument;
|
|
5800
|
+
/**
|
|
5801
|
+
* Re-judges a document's stored operations because a read-set stream in
|
|
5802
|
+
* another document (a group) gained an operation. The trigger timestamp
|
|
5803
|
+
* bounds the work: an operation later than everything this document holds
|
|
5804
|
+
* cannot change any evaluation, so the pass is skipped.
|
|
5805
|
+
*/
|
|
5806
|
+
private executeReevaluationJob;
|
|
5094
5807
|
private executeLoadJob;
|
|
5095
5808
|
private accumulateResultOrReturnError;
|
|
5096
5809
|
}
|
|
@@ -5159,6 +5872,49 @@ declare class DocumentModelRegistry implements IDocumentModelRegistry {
|
|
|
5159
5872
|
getUpgradeReducer(documentType: string, fromVersion: number, toVersion: number): UpgradeReducer<any, any>;
|
|
5160
5873
|
}
|
|
5161
5874
|
//#endregion
|
|
5875
|
+
//#region src/decision/build-decision-model.d.ts
|
|
5876
|
+
/**
|
|
5877
|
+
* Reads each projection's stream through the supplied reader, recording the
|
|
5878
|
+
* revision observed. Static projections resolve first; derived projections
|
|
5879
|
+
* see only those and contribute a map from document id to state. Each
|
|
5880
|
+
* distinct stream is read once and yields one append condition entry.
|
|
5881
|
+
*/
|
|
5882
|
+
declare function buildDecisionModel<M>(reader: IStreamStateReader, definition: (target: DecisionTarget) => DecisionModel<M>, target: DecisionTarget, signal?: AbortSignal): Promise<BuiltDecisionModel<M>>;
|
|
5883
|
+
//#endregion
|
|
5884
|
+
//#region src/decision/auth-decision-model.d.ts
|
|
5885
|
+
type AuthDecisionModel = {
|
|
5886
|
+
document: PHDocumentState;
|
|
5887
|
+
auth: PHAuthState;
|
|
5888
|
+
};
|
|
5889
|
+
/** This decision model uses both the document and the auth streams. */
|
|
5890
|
+
declare function authDecisionModel(target: DecisionTarget): DecisionModel<AuthDecisionModel>;
|
|
5891
|
+
//#endregion
|
|
5892
|
+
//#region src/decision/stream-order.d.ts
|
|
5893
|
+
/** Where a stream's stored order contradicts its timestamps. */
|
|
5894
|
+
type OutOfOrderPair = {
|
|
5895
|
+
previous: Operation;
|
|
5896
|
+
current: Operation;
|
|
5897
|
+
/**
|
|
5898
|
+
* `descending` cannot be walked at all. `tied` walks fine — the intra-stream
|
|
5899
|
+
* rule breaks the tie by index — but violates the monotonic auth rule, so a
|
|
5900
|
+
* stream holding one can never be replicated to a peer that lacks it.
|
|
5901
|
+
*/
|
|
5902
|
+
kind: "descending" | "tied";
|
|
5903
|
+
};
|
|
5904
|
+
/**
|
|
5905
|
+
* The first pair of effective operations whose stored order contradicts their
|
|
5906
|
+
* timestamps, or undefined when the stream is in position order.
|
|
5907
|
+
*
|
|
5908
|
+
* Such a stream cannot be walked, and the auth stream is never reshuffled once
|
|
5909
|
+
* the monotonic rule is on, so run this before enabling enforcement on a fleet.
|
|
5910
|
+
*
|
|
5911
|
+
* `requireStrict` additionally rejects a tie, which is what the auth stream's
|
|
5912
|
+
* monotonic rule requires and what the walk alone does not care about.
|
|
5913
|
+
*/
|
|
5914
|
+
declare function firstOutOfOrderPair(operations: Operation[], options?: {
|
|
5915
|
+
requireStrict?: boolean;
|
|
5916
|
+
}): OutOfOrderPair | undefined;
|
|
5917
|
+
//#endregion
|
|
5162
5918
|
//#region src/read-models/base-read-model.d.ts
|
|
5163
5919
|
type BaseReadModelConfig = {
|
|
5164
5920
|
readModelId: string;
|
|
@@ -5243,7 +5999,7 @@ declare class KyselyDocumentIndexer extends BaseReadModel implements IDocumentIn
|
|
|
5243
5999
|
* serialized so the executor can return to dispatch without holding ordering
|
|
5244
6000
|
* implicitly.
|
|
5245
6001
|
*/
|
|
5246
|
-
declare class ReadModelCoordinator implements
|
|
6002
|
+
declare class ReadModelCoordinator implements ILiveReadModelCoordinator {
|
|
5247
6003
|
private eventBus;
|
|
5248
6004
|
readonly preReady: IReadModel[];
|
|
5249
6005
|
readonly postReady: IReadModel[];
|
|
@@ -5262,6 +6018,7 @@ declare class ReadModelCoordinator implements IReadModelCoordinator {
|
|
|
5262
6018
|
*/
|
|
5263
6019
|
drain(): Promise<void>;
|
|
5264
6020
|
getChainDepth(): number;
|
|
6021
|
+
addReadModel(readModel: IReadModel, stage: ReadModelRegistrationStage): void;
|
|
5265
6022
|
private handleWriteReady;
|
|
5266
6023
|
private emitEmptyReadReady;
|
|
5267
6024
|
private runChain;
|
|
@@ -5275,8 +6032,31 @@ declare class ReadModelCoordinator implements IReadModelCoordinator {
|
|
|
5275
6032
|
type Database$2 = Database$1 & DocumentViewDatabase;
|
|
5276
6033
|
declare class KyselyDocumentView extends BaseReadModel implements IDocumentView {
|
|
5277
6034
|
private operationStore;
|
|
6035
|
+
/**
|
|
6036
|
+
* Whether a single-document read serves a deleted document's state as of the
|
|
6037
|
+
* deletion rather than hiding it. Only meaningful with `documentDecisions`,
|
|
6038
|
+
* which is what makes deletion positional. Listings omit it either way.
|
|
6039
|
+
*/
|
|
6040
|
+
private readonly servesDeletionBoundary;
|
|
5278
6041
|
private _db;
|
|
5279
|
-
constructor(db: Kysely<Database$2>, operationStore: IOperationStore, operationIndex: IOperationIndex, writeCache: IWriteCache, consistencyTracker: IConsistencyTracker
|
|
6042
|
+
constructor(db: Kysely<Database$2>, operationStore: IOperationStore, operationIndex: IOperationIndex, writeCache: IWriteCache, consistencyTracker: IConsistencyTracker,
|
|
6043
|
+
/**
|
|
6044
|
+
* Whether a single-document read serves a deleted document's state as of the
|
|
6045
|
+
* deletion rather than hiding it. Only meaningful with `documentDecisions`,
|
|
6046
|
+
* which is what makes deletion positional. Listings omit it either way.
|
|
6047
|
+
*/
|
|
6048
|
+
|
|
6049
|
+
servesDeletionBoundary: boolean);
|
|
6050
|
+
/**
|
|
6051
|
+
* Indexes committed operations into DocumentSnapshot rows. CREATE_DOCUMENT
|
|
6052
|
+
* only seeds header/document/auth. UPGRADE_DOCUMENT reindexes every scope
|
|
6053
|
+
* present in resultingState when the operation vouches for them — a seed
|
|
6054
|
+
* carrying initialState or a migration stamped with the __migrated marker
|
|
6055
|
+
* — since the upgrade reducer may have reshaped any of them; upgrades
|
|
6056
|
+
* without either fall back to header/document/auth, because their sibling
|
|
6057
|
+
* echoes may be stale. All other action types index only header and their
|
|
6058
|
+
* own scope.
|
|
6059
|
+
*/
|
|
5280
6060
|
protected commitOperations(items: OperationWithContext$1[]): Promise<void>;
|
|
5281
6061
|
exists(documentIds: string[], consistencyToken?: ConsistencyToken, signal?: AbortSignal): Promise<boolean[]>;
|
|
5282
6062
|
get<TDocument extends PHDocument>(documentId: string, view?: ViewFilter$1, consistencyToken?: ConsistencyToken, signal?: AbortSignal): Promise<TDocument>;
|
|
@@ -5408,6 +6188,8 @@ declare class GqlRequestChannel implements IChannel {
|
|
|
5408
6188
|
private isPushing;
|
|
5409
6189
|
private pendingDrain;
|
|
5410
6190
|
private receivingPages;
|
|
6191
|
+
/** Cleared for good the first time the remote rejects {@link DECISION_FIELDS}. */
|
|
6192
|
+
private peerServesDecisionFields;
|
|
5411
6193
|
private isRecovering;
|
|
5412
6194
|
private connectionState;
|
|
5413
6195
|
/** Latest unrecoverable error was an auth rejection; cleared on connect. */
|
|
@@ -5454,6 +6236,18 @@ declare class GqlRequestChannel implements IChannel {
|
|
|
5454
6236
|
* Queries the remote GraphQL endpoint for sync envelopes.
|
|
5455
6237
|
*/
|
|
5456
6238
|
private pollSyncEnvelopes;
|
|
6239
|
+
/**
|
|
6240
|
+
* True when the remote rejected the query for naming a field it does not
|
|
6241
|
+
* have. Selecting an unknown field fails validation for the whole query, so
|
|
6242
|
+
* an unhandled one takes the channel's polling down until the process
|
|
6243
|
+
* restarts rather than degrading.
|
|
6244
|
+
*/
|
|
6245
|
+
private rejectsDecisionFields;
|
|
6246
|
+
/**
|
|
6247
|
+
* The poll query. `withDecisionFields` selects the two fields added with the
|
|
6248
|
+
* auth projection; a remote on the previous schema is polled without them.
|
|
6249
|
+
*/
|
|
6250
|
+
private pollQuery;
|
|
5457
6251
|
/**
|
|
5458
6252
|
* Registers or updates this channel on the remote server via GraphQL mutation.
|
|
5459
6253
|
* Returns the remote's ack ordinal so the client can trim its outbox.
|
|
@@ -5616,6 +6410,18 @@ declare function batchOperationsByDocument(operations: OperationWithContext$1[])
|
|
|
5616
6410
|
* jobId; all other jobIds are remapped so external dependencies still resolve.
|
|
5617
6411
|
*/
|
|
5618
6412
|
declare function consolidateSyncOperations(syncOps: SyncOperation[]): SyncOperation[];
|
|
6413
|
+
/**
|
|
6414
|
+
* Classifies a failure by error name rather than `instanceof`, because a failure
|
|
6415
|
+
* that crossed the pooled-worker boundary arrives as plain data.
|
|
6416
|
+
*/
|
|
6417
|
+
declare function classifyJobFailure(errorName: string): SyncOperationErrorType;
|
|
6418
|
+
/** The explicit type when something else carried it, else derived by name. */
|
|
6419
|
+
declare function syncOperationErrorType(error: ChannelError | undefined): SyncOperationErrorType;
|
|
6420
|
+
/**
|
|
6421
|
+
* A held auth operation must not quarantine: reconciling the two policies needs
|
|
6422
|
+
* the traffic a quarantine would stop.
|
|
6423
|
+
*/
|
|
6424
|
+
declare function quarantinesDocument(errorType: SyncOperationErrorType): boolean;
|
|
5619
6425
|
//#endregion
|
|
5620
6426
|
//#region src/admin/types.d.ts
|
|
5621
6427
|
type KeyframeValidationIssue = {
|
|
@@ -5631,11 +6437,20 @@ type SnapshotValidationIssue = {
|
|
|
5631
6437
|
snapshotHash: string;
|
|
5632
6438
|
replayedHash: string;
|
|
5633
6439
|
};
|
|
6440
|
+
/** Effective operations whose stored order contradicts their timestamps. */
|
|
6441
|
+
type StreamOrderIssue = {
|
|
6442
|
+
scope: string;
|
|
6443
|
+
branch: string;
|
|
6444
|
+
previous: Operation;
|
|
6445
|
+
current: Operation;
|
|
6446
|
+
kind: OutOfOrderPair["kind"];
|
|
6447
|
+
};
|
|
5634
6448
|
type ValidationResult = {
|
|
5635
6449
|
documentId: string;
|
|
5636
6450
|
isConsistent: boolean;
|
|
5637
6451
|
keyframeIssues: KeyframeValidationIssue[];
|
|
5638
6452
|
snapshotIssues: SnapshotValidationIssue[];
|
|
6453
|
+
streamOrderIssues: StreamOrderIssue[];
|
|
5639
6454
|
};
|
|
5640
6455
|
type RebuildResult = {
|
|
5641
6456
|
documentId: string;
|
|
@@ -5659,6 +6474,7 @@ declare class DocumentIntegrityService implements IDocumentIntegrityService {
|
|
|
5659
6474
|
validateDocument(documentId: string, branch?: string, signal?: AbortSignal): Promise<ValidationResult>;
|
|
5660
6475
|
rebuildKeyframes(documentId: string, branch?: string, signal?: AbortSignal): Promise<RebuildResult>;
|
|
5661
6476
|
rebuildSnapshots(documentId: string, branch?: string, signal?: AbortSignal): Promise<RebuildResult>;
|
|
6477
|
+
private findStreamOrderIssues;
|
|
5662
6478
|
private discoverScopes;
|
|
5663
6479
|
}
|
|
5664
6480
|
//#endregion
|
|
@@ -5707,5 +6523,5 @@ declare class ProcessorManager extends BaseReadModel implements IProcessorManage
|
|
|
5707
6523
|
private deleteProcessorCursors;
|
|
5708
6524
|
}
|
|
5709
6525
|
//#endregion
|
|
5710
|
-
export { type AbortMessage, type AtomicTxn, type AttachmentHash, type AttachmentRef, BaseReadModel, type BatchExecutionRequest, type BatchExecutionResult, type BatchLoadRequest, type BatchLoadResult, type BuiltInReadModelKind, type CachedSnapshot, type ChannelConfig, ChannelError, ChannelErrorSource, type ChannelHealth, type ChannelMeta, ChannelScheme, type ConnectionState, type ConnectionStateChangeCallback, type ConnectionStateChangedEvent, type ConnectionStateSnapshot, type ConsistencyCoordinate, type ConsistencyKey, type ConsistencyToken, ConsistencyTracker, DEFAULT_DRIVE_CONTAINER_TYPES, DRIVE_AUTH_ERROR_MESSAGES, type Database, type DbConfig, type DeadLetterAddedEvent, DefaultSubscriptionErrorHandler, type DocumentChangeEvent, DocumentChangeType, type DocumentGraphEdge, type DocumentIndexerDatabase, DocumentIntegrityService, DocumentModelRegistry, DocumentModelResolver, type DocumentModelSource, type DocumentModelSpec, type DocumentRelationship, type DocumentRevisions, type DocumentStreamKey, type DocumentViewDatabase, DriveClient, DriveCollectionId, DuplicateManifestError, DuplicateModuleError, DuplicateOperationError, EventBus, EventBusAggregateError, type ExecuteMessage, type ExecutionJobPlan, type ExecutorStartedEvent, type ExecutorStoppedEvent, type FactorySpec, type FileModelSource, type GqlChannelConfig, GqlRequestChannel, GqlRequestChannelFactory, GqlResponseChannel, GqlResponseChannelFactory, type HeartbeatMessage, type IChannel, type IChannelFactory, type IConsistencyTracker, type IDocumentGraph, type IDocumentIndexer, type IDocumentIntegrityService, type IDocumentModelLoader, type IDocumentModelRegistry, type IDocumentModelResolver, type IDocumentView, type IDriveClient, type IEventBus, type IJobAwaiter, type IJobExecutor, type IJobExecutorManager, type IJobTracker, type IKeyframeStore, type IMailbox, type IOperationIndex, type IOperationStore, type IPollTimer, type IProcessor, type IProcessorHostModule, type IProcessorManager, type IProjectionTransport, type IQueue, type IReactor, type IReactorClient, type IReactorSubscriptionManager, type IReadModel, type IReadModelCoordinator, type IRelationalDb, type ISubscriptionErrorHandler, type ISyncCursorStorage, type ISyncManager, type ISyncRemoteStorage, type ISyncStatusTracker, type IWriteCache, SimpleJobExecutor as InMemoryJobExecutor, SimpleJobExecutor, InMemoryJobTracker, InMemoryQueue, type InProcessReactorClientModule, type InProcessReactorModule, type InProcessSyncModule, type InitMessage, type InsertableDocumentSnapshot, IntervalPollTimer, InvalidModuleError, type Job, type JobAvailableEvent, JobAwaiter, type JobCompletedEvent, type JobExecutorConfig, JobExecutorEventTypes, type JobExecutorFactory, type JobFailedEvent, type JobInfo, type JobPendingEvent, type JobReadReadyEvent, type JobResult, type JobRunningEvent, type JobStartedEvent, JobStatus, type JobWriteReadyEvent, type JobWriteReadyPayload, type JwtHandler, type KeyframeSnapshot, type KeyframeValidationIssue, KyselyDocumentIndexer, KyselyDocumentView, KyselyKeyframeStore, KyselyOperationStore, KyselySyncCursorStorage, KyselySyncRemoteStorage, KyselyWriteCache, type LoadJobPlan, type LoadModelMessage, type LogMessage, Mailbox, type MetricsMessage, type ModelLoadFailedMessage, type ModelLoadedEvent, type ModelLoadedMessage, type ModelManifestEntry, ModuleNotFoundError, type ModuleRef, NullDocumentModelResolver, type OperationBatch, type OperationContext, type OperationFilter, type OperationIndexEntry, type OperationTable, type OperationWithContext, OptimisticLockError, type PackageModelSource, type PagedResults, type PagingOptions, type ParentMessage, type ParsedDriveUrl, type ParsedPaging, PollBehavior, PollingChannelError, type PoolInstrumentation, type PoolStats, type ProcessorApp, type ProcessorFactory, type ProcessorFactoryBuilder, type ProcessorFilter, ProcessorManager, type ProcessorRecord, type ProcessorStatus, type ProjectionShardBuilderConfig, type ProjectionShardManagerConfig, type ProjectionWorkerFactory, PropagationMode, QueueEventTypes, REACTOR_SCHEMA, Reactor, ReactorBuilder, ReactorClient, ReactorClientBuilder, type ReactorClientModule, ReactorEventTypes, type ReactorFeatures, type JobFailedEvent$1 as ReactorJobFailedEvent, type ReactorModule, ReactorSubscriptionManager, type ReadModelBatchCompletedEvent, ReadModelCoordinator, type ReadModelFactory, type ReadModelFactoryDeps, type ReadModelIndexedEvent, type ReadModelIndexingStage, type ReadModelStage, type ReadyMessage, type RebuildResult, RelationalDbProcessor, RelationshipChangeType, type Remote, type RemoteCursor, type RemoteFilter, type RemoteMeta, type RemoteOptions, type RemoteRecord, type RemoteStatus, type ResultMessage, RevisionMismatchError, type SanitizedArg, type SearchFilter, type ShutdownMessage, type ShutdownStatus, type SignatureVerificationHandler, type SignatureVerifierSpec, type SignerConfig, SimpleJobExecutorManager, type SnapshotValidationIssue, type Database$1 as StorageDatabase, type SubscriptionErrorContext, SyncBuilder, type SyncEnvelope, type SyncEnvelopeType, SyncEventTypes, type SyncFailedEvent, type SyncModule, SyncOperation, SyncOperationAggregateError, type SyncOperationErrorType, SyncOperationStatus, type SyncPendingEvent, SyncStatus, type SyncStatusChangeCallback, SyncStatusTracker, type SyncSucceededEvent, type TrackedProcessor, type Unsubscribe, type ValidationResult, type ViewFilter, type ErrorInfo as WorkerErrorInfo, type WorkerMessage, type WorkerPoolConfig, type WorkerPoolOptions, type WriteCacheConfig, addRelationshipAction, batchOperationsByDocument, consolidateSyncOperations, createDocumentAction, createForwardingLogger, createMutableShutdownStatus, createRelationalDb, deleteDocumentAction, documentActions, driveIdFromUrl, envelopesToSyncOperations, errorToInfo, getMigrationStatus, instrumentPgPool, isDriveAuthError, makeConsistencyKey, parseDriveUrl, parsePagingOptions, removeRelationshipAction, runMigrations, sanitizeArg, trimMailboxFromAckOrdinal, updateRelationshipAction, upgradeDocumentAction, workerEntryPath };
|
|
6526
|
+
export { ALWAYS_READABLE_SCOPES, APPEND_CONDITION_FAILED_PREFIX, type AbortMessage, type AdmissionDecision, type AppendCondition, AppendConditionFailedError, type AppendConditionStream, type AtomicTxn, type AttachmentHash, type AttachmentRef, type AuthDecisionModel, BareReadGate, BaseReadModel, type BatchExecutionRequest, type BatchExecutionResult, type BatchLoadRequest, type BatchLoadResult, type BuiltDecisionModel, type BuiltInReadModelKind, type CachedSnapshot, type ChannelConfig, ChannelError, ChannelErrorSource, type ChannelHealth, type ChannelMeta, ChannelScheme, type ConnectionState, type ConnectionStateChangeCallback, type ConnectionStateChangedEvent, type ConnectionStateSnapshot, type ConsistencyCoordinate, type ConsistencyKey, type ConsistencyToken, ConsistencyTracker, DEFAULT_DRIVE_CONTAINER_TYPES, DRIVE_AUTH_ERROR_MESSAGES, type Database, type DbConfig, type DeadLetterAddedEvent, type DecisionContext, type DecisionModel, type DecisionTarget, DefaultSubscriptionErrorHandler, type DocumentChangeEvent, DocumentChangeType, type DocumentDecisionModel, type DocumentGraphEdge, type DocumentIndexerDatabase, DocumentIntegrityService, DocumentModelRegistry, DocumentModelResolver, type DocumentModelSource, type DocumentModelSpec, type DocumentRelationship, type DocumentRevisions, type DocumentStreamKey, type DocumentViewDatabase, DriveClient, DriveCollectionId, DuplicateManifestError, DuplicateModuleError, DuplicateOperationError, type Evaluation, EventBus, EventBusAggregateError, type ExecuteMessage, type ExecutionJobPlan, type ExecutorStartedEvent, type ExecutorStoppedEvent, type FactorySpec, type FileModelSource, type GqlChannelConfig, GqlRequestChannel, GqlRequestChannelFactory, GqlResponseChannel, GqlResponseChannelFactory, type HeartbeatMessage, type IChannel, type IChannelFactory, type IConsistencyTracker, type IDocumentGraph, type IDocumentIndexer, type IDocumentIntegrityService, type IDocumentModelLoader, type IDocumentModelRegistry, type IDocumentModelResolver, type IDocumentView, type IDriveClient, type IEventBus, type IJobAwaiter, type IJobExecutor, type IJobExecutorManager, type IJobTracker, type IKeyframeStore, type ILiveReadModelCoordinator, type IMailbox, type IOperationIndex, type IOperationStore, type IPollTimer, type IProcessor, type IProcessorHostModule, type IProcessorManager, type IProjectionTransport, type IQueue, type IReactor, type IReactorClient, type IReactorSubscriptionManager, type IReadGate, type IReadModel, type IReadModelCoordinator, type IRelationalDb, type IStreamStateReader, type ISubscriptionErrorHandler, type ISyncCursorStorage, type ISyncManager, type ISyncRemoteStorage, type ISyncStatusTracker, type IWriteCache, SimpleJobExecutor as InMemoryJobExecutor, SimpleJobExecutor, InMemoryJobTracker, InMemoryQueue, type InProcessReactorClientModule, type InProcessReactorModule, type InProcessSyncModule, type InitMessage, type InsertableDocumentSnapshot, IntervalPollTimer, InvalidModuleError, type Job, type JobAvailableEvent, JobAwaiter, type JobCompletedEvent, type JobExecutorConfig, JobExecutorEventTypes, type JobExecutorFactory, type JobFailedEvent, type JobInfo, type JobPendingEvent, type JobReadReadyEvent, type JobResult, type JobRunningEvent, type JobStartedEvent, JobStatus, type JobWriteReadyEvent, type JobWriteReadyPayload, type JwtHandler, type KeyframeSnapshot, type KeyframeValidationIssue, KyselyDocumentIndexer, KyselyDocumentView, KyselyKeyframeStore, KyselyOperationStore, KyselySyncCursorStorage, KyselySyncRemoteStorage, KyselyWriteCache, type LoadJobPlan, type LoadModelMessage, type LogMessage, Mailbox, type MetricsMessage, type ModelLoadFailedMessage, type ModelLoadedEvent, type ModelLoadedMessage, type ModelManifestEntry, ModelReadGate, ModuleNotFoundError, type ModuleRef, NullDocumentModelResolver, type OperationBatch, type OperationContext, type OperationFilter, type OperationIndexEntry, type OperationTable, type OperationWithContext, OptimisticLockError, type OutOfOrderPair, type PackageModelSource, type PagedResults, type PagingOptions, type ParentMessage, type ParsedDriveUrl, type ParsedPaging, PollBehavior, PollingChannelError, type PoolInstrumentation, type PoolStats, type ProcessorApp, type ProcessorFactory, type ProcessorFactoryBuilder, type ProcessorFilter, ProcessorManager, type ProcessorRecord, type ProcessorStatus, type Projection, type ProjectionShardBuilderConfig, type ProjectionShardManagerConfig, type ProjectionWorkerFactory, PropagationMode, QueueEventTypes, REACTOR_SCHEMA, Reactor, ReactorBuilder, ReactorClient, ReactorClientBuilder, type ReactorClientModule, ReactorEventTypes, type ReactorFeatureFlags, type ReactorFeatures, type JobFailedEvent$1 as ReactorJobFailedEvent, type ReactorModule, ReactorSubscriptionManager, type ReadModelBatchCompletedEvent, ReadModelCoordinator, type ReadModelFactory, type ReadModelFactoryDeps, type ReadModelIndexedEvent, type ReadModelIndexingStage, type ReadModelRegistrationStage, type ReadModelStage, type ReadyMessage, type RebuildResult, type RegisteredDecisionModel, RelationalDbProcessor, RelationshipChangeType, type Remote, type RemoteCursor, type RemoteFilter, type RemoteMeta, type RemoteOptions, type RemoteRecord, type RemoteStatus, type ResultMessage, RetryAccounting, RevisionMismatchError, type SanitizedArg, type SearchFilter, type ShutdownMessage, type ShutdownStatus, type SignatureVerificationHandler, type SignatureVerifierSpec, type SignerConfig, SimpleJobExecutorManager, type SnapshotValidationIssue, type Database$1 as StorageDatabase, type StreamOrderIssue, type StreamQuery, type SubscriptionErrorContext, SyncBuilder, type SyncEnvelope, type SyncEnvelopeType, SyncEventTypes, type SyncFailedEvent, type SyncModule, SyncOperation, SyncOperationAggregateError, type SyncOperationErrorType, SyncOperationStatus, type SyncPendingEvent, SyncStatus, type SyncStatusChangeCallback, SyncStatusTracker, type SyncSucceededEvent, type TrackedProcessor, type Unsubscribe, type ValidationResult, type ViewFilter, type ErrorInfo as WorkerErrorInfo, type WorkerMessage, type WorkerPoolConfig, type WorkerPoolOptions, type WriteCacheConfig, addRelationshipAction, authDecisionModel, batchOperationsByDocument, buildDecisionModel, classifyJobFailure, consolidateSyncOperations, createDocumentAction, createForwardingLogger, createMutableShutdownStatus, createRelationalDb, decideAtHead, deleteDocumentAction, documentActions, documentDecisionModel, driveIdFromUrl, envelopesToSyncOperations, errorToInfo, firstOutOfOrderPair, getMigrationStatus, instrumentPgPool, isDriveAuthError, makeConsistencyKey, parseDriveUrl, parsePagingOptions, quarantinesDocument, readDecisionModel, removeRelationshipAction, runMigrations, sanitizeArg, selectDecisionModel, supportsLiveReadModelRegistration, syncOperationErrorType, trimMailboxFromAckOrdinal, updateRelationshipAction, upgradeDocumentAction, workerEntryPath };
|
|
5711
6527
|
//# sourceMappingURL=index.d.ts.map
|