@powerhousedao/reactor 6.2.3-dev.22 → 6.2.3-dev.24
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-DUjyF4NM.js → build-worker-executor-DxmDJ4QQ.js} +24 -8
- package/dist/build-worker-executor-DxmDJ4QQ.js.map +1 -0
- package/dist/{document-indexer-C1oY6CaR.js → document-indexer-Dn9RB0sg.js} +6 -5
- package/dist/document-indexer-Dn9RB0sg.js.map +1 -0
- package/dist/{drive-container-types-CS5IxDiA.js → drive-container-types-Be5-EY9W.js} +843 -144
- package/dist/drive-container-types-Be5-EY9W.js.map +1 -0
- package/dist/entry.js +10 -5
- package/dist/entry.js.map +1 -1
- package/dist/index.d.ts +1985 -1826
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +716 -302
- package/dist/index.js.map +1 -1
- package/dist/projection-entry.js +4 -4
- package/dist/{projection-shard-manager-CUo4bF4O.js → projection-shard-manager-mQhfVipO.js} +2 -2
- package/dist/{projection-shard-manager-CUo4bF4O.js.map → projection-shard-manager-mQhfVipO.js.map} +1 -1
- package/dist/{types-DMKLa0Ok.js → types-DxDCmtId.js} +3 -2
- package/dist/types-DxDCmtId.js.map +1 -0
- package/dist/{worker-g03lNM42.js → worker-BDVzCtuf.js} +2 -2
- package/dist/{worker-g03lNM42.js.map → worker-BDVzCtuf.js.map} +1 -1
- package/dist/{worker-handle-CrERzl8s.js → worker-handle-B3p-nuqG.js} +14 -9
- package/dist/worker-handle-B3p-nuqG.js.map +1 -0
- package/package.json +9 -7
- package/dist/build-worker-executor-DUjyF4NM.js.map +0 -1
- package/dist/document-indexer-C1oY6CaR.js.map +0 -1
- package/dist/drive-container-types-CS5IxDiA.js.map +0 -1
- package/dist/types-DMKLa0Ok.js.map +0 -1
- package/dist/worker-handle-CrERzl8s.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { Action, AuthRequest, AuthSubject, CreateDocumentActionInput, DocumentModelModule, ISigner, Operation, OperationContext, OperationOutcome, OperationWithContext, OperationWithContext as OperationWithContext$1, PHAuthState, PHDocument, PHDocumentState, SignatureVerificationHandler, UpgradeDocumentActionInput, UpgradeManifest, UpgradeReducer, UpgradeTransition, actions as documentActions } from "@powerhousedao/shared/document-model";
|
|
1
|
+
import { Action, ActionSigner, AuthRequest, AuthSubject, CreateDocumentActionInput, DocumentModelModule, ISigner, Operation, OperationContext, OperationOutcome, OperationWithContext, OperationWithContext as OperationWithContext$1, PHAuthState, PHDocument, PHDocumentState, SignaturePolicy, 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";
|
|
5
5
|
import { Generated, Insertable, Kysely, Transaction } from "kysely";
|
|
6
|
-
import { IProcessor, IProcessorHostModuleBase, IProcessorHostModuleBase as IProcessorHostModuleBase$1, IProcessorManager, IProcessorManager as IProcessorManager$1, IRelationalDb, ProcessorApp, ProcessorFactory, ProcessorFactory as ProcessorFactory$1, ProcessorFactoryBuilder, ProcessorFilter, ProcessorRecord, ProcessorStatus, RelationalDbProcessor, TrackedProcessor, TrackedProcessor as TrackedProcessor$1, createRelationalDb } from "@powerhousedao/shared/processors";
|
|
6
|
+
import { IProcessor, IProcessorHostModuleBase, IProcessorHostModuleBase as IProcessorHostModuleBase$1, IProcessorManager, IProcessorManager as IProcessorManager$1, IRelationalDb, ProcessorApp, ProcessorFactory, ProcessorFactory as ProcessorFactory$1, ProcessorFactoryBuilder, ProcessorFilter, ProcessorRecord, ProcessorRecord as ProcessorRecord$1, ProcessorStatus, RelationalDbProcessor, TrackedProcessor, TrackedProcessor as TrackedProcessor$1, createRelationalDb } from "@powerhousedao/shared/processors";
|
|
7
7
|
import { Pool } from "pg";
|
|
8
8
|
|
|
9
9
|
//#region src/attachments/types.d.ts
|
|
@@ -784,6 +784,13 @@ interface IOperationStore {
|
|
|
784
784
|
* timestamp, so a later timestamp can sit behind the last row.
|
|
785
785
|
*/
|
|
786
786
|
getStreamLatestTimestamp(documentId: string, scope: string, branch: string, signal?: AbortSignal): Promise<string | undefined>;
|
|
787
|
+
/**
|
|
788
|
+
* The subset of `opIds` stored anywhere in one stream, retracted rows
|
|
789
|
+
* included.
|
|
790
|
+
*/
|
|
791
|
+
findOperationIds(documentId: string, scope: string, branch: string, opIds: string[], signal?: AbortSignal): Promise<Set<string>>;
|
|
792
|
+
/** The latest row of each of `opIds` stored in one stream. */
|
|
793
|
+
getOperationsByIds(documentId: string, scope: string, branch: string, opIds: string[], signal?: AbortSignal): Promise<Operation[]>;
|
|
787
794
|
}
|
|
788
795
|
/**
|
|
789
796
|
* Stores periodic document snapshots (keyframes) so that document state
|
|
@@ -1332,6 +1339,8 @@ interface IOperationIndex {
|
|
|
1332
1339
|
* reference other groups.
|
|
1333
1340
|
*/
|
|
1334
1341
|
getGroupReferencers(groupId: string, signal?: AbortSignal): Promise<string[]>;
|
|
1342
|
+
/** The latest ordinal of each of `opIds` indexed in one stream. */
|
|
1343
|
+
getOrdinalsByOpIds(documentId: string, scope: string, branch: string, opIds: string[], signal?: AbortSignal): Promise<Map<string, number>>;
|
|
1335
1344
|
}
|
|
1336
1345
|
/**
|
|
1337
1346
|
* Identifies the collection a remote synchronizes. Collections are drive-level
|
|
@@ -1524,2105 +1533,2188 @@ interface IWriteCache {
|
|
|
1524
1533
|
shutdown(): Promise<void>;
|
|
1525
1534
|
}
|
|
1526
1535
|
//#endregion
|
|
1527
|
-
//#region src/
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
type Unsubscribe = () => void;
|
|
1532
|
-
/**
|
|
1533
|
-
* A subscriber is a function that is called when an event is emitted.
|
|
1534
|
-
*
|
|
1535
|
-
* It is passed the event type and the data.
|
|
1536
|
-
* It can return a promise or a value.
|
|
1537
|
-
* If it returns a promise, the event bus will wait for the promise to resolve before calling the next subscriber.
|
|
1538
|
-
* If it throws an error, the event bus will reject with an aggregate error of all errors.
|
|
1539
|
-
*
|
|
1540
|
-
* @param type - The type of event to emit.
|
|
1541
|
-
* @param data - The data to pass to the subscriber.
|
|
1542
|
-
*/
|
|
1543
|
-
type Subscriber = (type: number, data: any) => void | Promise<void>;
|
|
1544
|
-
/**
|
|
1545
|
-
* Custom error class that aggregates multiple errors from event subscribers.
|
|
1546
|
-
*/
|
|
1547
|
-
declare class EventBusAggregateError extends Error {
|
|
1548
|
-
readonly errors: any[];
|
|
1549
|
-
constructor(errors: unknown[]);
|
|
1536
|
+
//#region src/cache/collection-membership-cache.d.ts
|
|
1537
|
+
interface ICollectionMembershipCache {
|
|
1538
|
+
getCollectionsForDocuments(documentIds: string[]): Promise<Record<string, string[]>>;
|
|
1539
|
+
invalidate(documentId: string): void;
|
|
1550
1540
|
}
|
|
1541
|
+
//#endregion
|
|
1542
|
+
//#region src/cache/document-meta-cache-types.d.ts
|
|
1551
1543
|
/**
|
|
1552
|
-
*
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
readonly JOB_WRITE_READY: 10003;
|
|
1558
|
-
readonly JOB_READ_READY: 10004;
|
|
1559
|
-
readonly JOB_FAILED: 10005;
|
|
1560
|
-
readonly READMODEL_BATCH_COMPLETED: 10006;
|
|
1561
|
-
readonly READMODEL_INDEXED: 10007;
|
|
1562
|
-
readonly MODEL_LOADED: 10008;
|
|
1563
|
-
};
|
|
1564
|
-
/**
|
|
1565
|
-
* Stage within ReadModelCoordinator.runChain. Used as a dimension on
|
|
1566
|
-
* stage-attribution events and histograms.
|
|
1567
|
-
*/
|
|
1568
|
-
type ReadModelStage = "pre_ready" | "emit" | "post_ready";
|
|
1569
|
-
/**
|
|
1570
|
-
* Stage in which an individual read model ran. The emit stage does not
|
|
1571
|
-
* involve a read model so it is excluded from this discriminant.
|
|
1572
|
-
*/
|
|
1573
|
-
type ReadModelIndexingStage = "pre_ready" | "post_ready";
|
|
1574
|
-
/**
|
|
1575
|
-
* Emitted after the resolver loads a model on demand, so peers load it too.
|
|
1576
|
-
*/
|
|
1577
|
-
type ModelLoadedEvent = {
|
|
1578
|
-
documentType: string;
|
|
1579
|
-
};
|
|
1580
|
-
/**
|
|
1581
|
-
* Event emitted when a job is registered and waiting to be executed.
|
|
1582
|
-
*/
|
|
1583
|
-
type JobPendingEvent = {
|
|
1584
|
-
jobId: string;
|
|
1585
|
-
jobMeta: JobMeta;
|
|
1586
|
-
};
|
|
1587
|
-
/**
|
|
1588
|
-
* Event emitted when a job starts executing.
|
|
1589
|
-
*/
|
|
1590
|
-
type JobRunningEvent = {
|
|
1591
|
-
jobId: string;
|
|
1592
|
-
jobMeta: JobMeta;
|
|
1593
|
-
};
|
|
1594
|
-
/**
|
|
1595
|
-
* Event emitted when operations are written to IOperationStore.
|
|
1596
|
-
* Contains the operations directly to avoid round-trip queries.
|
|
1544
|
+
* Cached document metadata from the "document" scope.
|
|
1545
|
+
*
|
|
1546
|
+
* This lightweight structure holds essential document information needed by
|
|
1547
|
+
* the job executor without fetching full scope state. It provides an explicit
|
|
1548
|
+
* cross-scope contract for accessing document scope metadata.
|
|
1597
1549
|
*/
|
|
1598
|
-
type
|
|
1599
|
-
jobId: string;
|
|
1600
|
-
operations: OperationWithContext$1[];
|
|
1601
|
-
jobMeta: JobMeta;
|
|
1550
|
+
type CachedDocumentMeta = {
|
|
1602
1551
|
/**
|
|
1603
|
-
* The
|
|
1604
|
-
*
|
|
1605
|
-
* consumer reporting back to the caller needs this to tell the two apart.
|
|
1606
|
-
* Absent on jobs that carry no submitted actions.
|
|
1552
|
+
* The full PHDocumentState from document.state.document.
|
|
1553
|
+
* Contains version, hash, isDeleted, deletedAtUtcIso, etc.
|
|
1607
1554
|
*/
|
|
1608
|
-
|
|
1555
|
+
state: PHDocumentState;
|
|
1609
1556
|
/**
|
|
1610
|
-
*
|
|
1611
|
-
* Used by SyncManager to route operations only to remotes
|
|
1612
|
-
* whose collection contains the document.
|
|
1557
|
+
* The document type (from header), cached for convenience.
|
|
1613
1558
|
*/
|
|
1614
|
-
|
|
1559
|
+
documentType: string; /** From the CREATE_DOCUMENT input, which fixes them for the document's life. */
|
|
1560
|
+
protocolVersions: {
|
|
1561
|
+
[protocol: string]: number;
|
|
1562
|
+
} | undefined;
|
|
1563
|
+
/**
|
|
1564
|
+
* The revision of the document scope when this metadata was captured.
|
|
1565
|
+
* Used for cache invalidation and consistency checks.
|
|
1566
|
+
*/
|
|
1567
|
+
documentScopeRevision: number;
|
|
1615
1568
|
};
|
|
1616
1569
|
/**
|
|
1617
|
-
*
|
|
1618
|
-
* This event fires after JOB_WRITE_READY and guarantees that:
|
|
1619
|
-
* - All read models (DocumentView, DocumentIndexer, etc.) have indexed the operations
|
|
1620
|
-
* - All consistency trackers have been updated with the new operation indices
|
|
1621
|
-
* - Queries without consistency tokens will now see the updated data
|
|
1570
|
+
* Interface for the document metadata cache.
|
|
1622
1571
|
*
|
|
1623
|
-
* This
|
|
1624
|
-
*
|
|
1625
|
-
*
|
|
1626
|
-
*
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
/**
|
|
1633
|
-
* Event emitted when a job fails with an unrecoverable error.
|
|
1634
|
-
* This event allows the JobAwaiter and other subscribers to react to job failures
|
|
1635
|
-
* without polling.
|
|
1636
|
-
*/
|
|
1637
|
-
type JobFailedEvent$1 = {
|
|
1638
|
-
jobId: string;
|
|
1639
|
-
error: Error;
|
|
1640
|
-
job?: Job;
|
|
1641
|
-
};
|
|
1642
|
-
/**
|
|
1643
|
-
* Event emitted once per batch processed by ReadModelCoordinator.runChain,
|
|
1644
|
-
* after all three projection stages complete. Carries per-stage wall times,
|
|
1645
|
-
* the chain wait time, and the batch size so projection cost can be
|
|
1646
|
-
* attributed by an observer.
|
|
1647
|
-
*/
|
|
1648
|
-
type ReadModelBatchCompletedEvent = {
|
|
1649
|
-
jobId: string;
|
|
1650
|
-
batchSize: number;
|
|
1651
|
-
chainWaitDurationMs: number;
|
|
1652
|
-
preReadyDurationMs: number;
|
|
1653
|
-
emitDurationMs: number;
|
|
1654
|
-
postReadyDurationMs: number;
|
|
1655
|
-
};
|
|
1656
|
-
/**
|
|
1657
|
-
* Event emitted once per individual read model per batch and stage, after
|
|
1658
|
-
* that read model's indexOperations call resolves (or rejects). Lets
|
|
1659
|
-
* observers attribute projection cost to a specific read model.
|
|
1660
|
-
*/
|
|
1661
|
-
type ReadModelIndexedEvent = {
|
|
1662
|
-
jobId: string;
|
|
1663
|
-
readModelName: string;
|
|
1664
|
-
stage: ReadModelIndexingStage;
|
|
1665
|
-
durationMs: number;
|
|
1666
|
-
operationCount: number;
|
|
1667
|
-
success: boolean;
|
|
1668
|
-
};
|
|
1669
|
-
//#endregion
|
|
1670
|
-
//#region src/events/interfaces.d.ts
|
|
1671
|
-
/**
|
|
1672
|
-
* Describes an object that manages event subscriptions and emissions.
|
|
1572
|
+
* This cache provides an explicit cross-scope contract for accessing document
|
|
1573
|
+
* scope metadata. It solves the problem where job execution in one scope (e.g.,
|
|
1574
|
+
* "global") needs access to document scope state (version, isDeleted, etc.)
|
|
1575
|
+
* which may be stale in scope-specific caches or keyframes.
|
|
1576
|
+
*
|
|
1577
|
+
* The cache supports:
|
|
1578
|
+
* - Latest metadata retrieval with LRU caching
|
|
1579
|
+
* - Historical metadata reconstruction for reshuffling scenarios
|
|
1580
|
+
* - Eager updates after document scope operations
|
|
1673
1581
|
*/
|
|
1674
|
-
interface
|
|
1582
|
+
interface IDocumentMetaCache {
|
|
1675
1583
|
/**
|
|
1676
|
-
*
|
|
1677
|
-
* Order is preserved by pushing to the end of the per-type array.
|
|
1584
|
+
* Retrieves the LATEST document metadata from cache or rebuilds from operations.
|
|
1678
1585
|
*
|
|
1679
|
-
*
|
|
1680
|
-
*
|
|
1586
|
+
* On cache miss, fetches all document scope operations and reconstructs the
|
|
1587
|
+
* current PHDocumentState by applying UPGRADE_DOCUMENT and DELETE_DOCUMENT
|
|
1588
|
+
* operations.
|
|
1681
1589
|
*
|
|
1682
|
-
* @
|
|
1590
|
+
* @param documentId - The document identifier
|
|
1591
|
+
* @param branch - Branch name
|
|
1592
|
+
* @param signal - Optional abort signal to cancel the operation
|
|
1593
|
+
* @returns The cached or rebuilt document metadata
|
|
1594
|
+
* @throws {Error} "Operation aborted" if signal is aborted
|
|
1595
|
+
* @throws {Error} If document not found (no CREATE_DOCUMENT operation)
|
|
1683
1596
|
*/
|
|
1684
|
-
|
|
1597
|
+
getDocumentMeta(documentId: string, branch: string, signal?: AbortSignal): Promise<CachedDocumentMeta>;
|
|
1685
1598
|
/**
|
|
1686
|
-
*
|
|
1687
|
-
* - Every subscriber present at emit-start is called, in registration order.
|
|
1688
|
-
* - Calls are invoked and settled sequentially.
|
|
1689
|
-
* - If subscribers throw/reject, `emit` rejects with an aggregate error of all errors.
|
|
1599
|
+
* Rebuilds document metadata at a SPECIFIC revision (always rebuilds, no caching).
|
|
1690
1600
|
*
|
|
1691
|
-
*
|
|
1692
|
-
*
|
|
1601
|
+
* Used during reshuffling when operations need to be inserted at a previous
|
|
1602
|
+
* revision and we need the document scope state as of that point in time.
|
|
1603
|
+
*
|
|
1604
|
+
* @param documentId - The document identifier
|
|
1605
|
+
* @param branch - Branch name
|
|
1606
|
+
* @param targetRevision - The document scope revision to reconstruct up to
|
|
1607
|
+
* @param signal - Optional abort signal to cancel the operation
|
|
1608
|
+
* @returns Document metadata as of the target revision
|
|
1609
|
+
* @throws {Error} "Operation aborted" if signal is aborted
|
|
1610
|
+
* @throws {Error} If document not found
|
|
1693
1611
|
*/
|
|
1694
|
-
|
|
1695
|
-
}
|
|
1696
|
-
//#endregion
|
|
1697
|
-
//#region src/shared/awaiter.d.ts
|
|
1698
|
-
interface IJobAwaiter {
|
|
1612
|
+
rebuildAtRevision(documentId: string, branch: string, targetRevision: number, signal?: AbortSignal): Promise<CachedDocumentMeta>;
|
|
1699
1613
|
/**
|
|
1700
|
-
*
|
|
1614
|
+
* Eagerly updates cached metadata after document scope operations.
|
|
1701
1615
|
*
|
|
1702
|
-
*
|
|
1703
|
-
*
|
|
1704
|
-
*
|
|
1616
|
+
* Called by the job executor after CREATE_DOCUMENT, UPGRADE_DOCUMENT, or
|
|
1617
|
+
* DELETE_DOCUMENT operations to keep the cache current.
|
|
1618
|
+
*
|
|
1619
|
+
* @param documentId - The document identifier
|
|
1620
|
+
* @param branch - Branch name
|
|
1621
|
+
* @param meta - The new metadata to cache
|
|
1705
1622
|
*/
|
|
1706
|
-
|
|
1623
|
+
putDocumentMeta(documentId: string, branch: string, meta: CachedDocumentMeta): void;
|
|
1707
1624
|
/**
|
|
1708
|
-
*
|
|
1625
|
+
* Invalidates cached document metadata.
|
|
1626
|
+
*
|
|
1627
|
+
* Call before reshuffling operations that modify the document scope, or
|
|
1628
|
+
* when document state may have changed externally.
|
|
1629
|
+
*
|
|
1630
|
+
* @param documentId - The document identifier
|
|
1631
|
+
* @param branch - Optional branch to narrow invalidation (if omitted, all branches)
|
|
1632
|
+
* @returns Number of entries invalidated
|
|
1709
1633
|
*/
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
shutdown(): void;
|
|
1724
|
-
waitForJob(jobId: string, signal?: AbortSignal): Promise<JobInfo>;
|
|
1725
|
-
private handleWriteReady;
|
|
1726
|
-
private handleReadReady;
|
|
1727
|
-
private handleJobFailed;
|
|
1728
|
-
private checkAndResolveWaiters;
|
|
1634
|
+
invalidate(documentId: string, branch?: string): number;
|
|
1635
|
+
/**
|
|
1636
|
+
* Clears all cached document metadata.
|
|
1637
|
+
*/
|
|
1638
|
+
clear(): void;
|
|
1639
|
+
/**
|
|
1640
|
+
* Performs startup initialization.
|
|
1641
|
+
*/
|
|
1642
|
+
startup(): Promise<void>;
|
|
1643
|
+
/**
|
|
1644
|
+
* Performs graceful shutdown.
|
|
1645
|
+
*/
|
|
1646
|
+
shutdown(): Promise<void>;
|
|
1729
1647
|
}
|
|
1730
1648
|
//#endregion
|
|
1731
|
-
//#region src/
|
|
1649
|
+
//#region src/storage/kysely/types.d.ts
|
|
1650
|
+
interface OperationTable {
|
|
1651
|
+
id: Generated<number>;
|
|
1652
|
+
jobId: string;
|
|
1653
|
+
opId: string;
|
|
1654
|
+
prevOpId: string;
|
|
1655
|
+
writeTimestampUtcMs: Generated<Date>;
|
|
1656
|
+
documentId: string;
|
|
1657
|
+
documentType: string;
|
|
1658
|
+
scope: string;
|
|
1659
|
+
branch: string;
|
|
1660
|
+
timestampUtcMs: Date;
|
|
1661
|
+
index: number;
|
|
1662
|
+
action: unknown;
|
|
1663
|
+
skip: number;
|
|
1664
|
+
error?: string | null;
|
|
1665
|
+
deniedReason?: string | null;
|
|
1666
|
+
hash: string;
|
|
1667
|
+
}
|
|
1668
|
+
interface KeyframeTable {
|
|
1669
|
+
id: Generated<number>;
|
|
1670
|
+
documentId: string;
|
|
1671
|
+
documentType: string;
|
|
1672
|
+
scope: string;
|
|
1673
|
+
branch: string;
|
|
1674
|
+
revision: number;
|
|
1675
|
+
document: unknown;
|
|
1676
|
+
createdAt: Generated<Date>;
|
|
1677
|
+
}
|
|
1678
|
+
interface DocumentCollectionTable {
|
|
1679
|
+
documentId: string;
|
|
1680
|
+
collectionId: string;
|
|
1681
|
+
joinedOrdinal: bigint;
|
|
1682
|
+
leftOrdinal: bigint | null;
|
|
1683
|
+
}
|
|
1684
|
+
interface OperationIndexOperationTable {
|
|
1685
|
+
ordinal: Generated<number>;
|
|
1686
|
+
opId: string;
|
|
1687
|
+
documentId: string;
|
|
1688
|
+
documentType: string;
|
|
1689
|
+
scope: string;
|
|
1690
|
+
branch: string;
|
|
1691
|
+
timestampUtcMs: string;
|
|
1692
|
+
writeTimestampUtcMs: Generated<Date>;
|
|
1693
|
+
index: number;
|
|
1694
|
+
skip: number;
|
|
1695
|
+
hash: string;
|
|
1696
|
+
action: unknown;
|
|
1697
|
+
deniedReason?: string | null;
|
|
1698
|
+
sourceRemote: Generated<string>;
|
|
1699
|
+
}
|
|
1700
|
+
interface SyncRemoteTable {
|
|
1701
|
+
name: string;
|
|
1702
|
+
collection_id: string;
|
|
1703
|
+
channel_type: string;
|
|
1704
|
+
channel_id: string;
|
|
1705
|
+
remote_name: string;
|
|
1706
|
+
channel_parameters: unknown;
|
|
1707
|
+
filter_document_ids: unknown;
|
|
1708
|
+
filter_scopes: unknown;
|
|
1709
|
+
filter_branch: string;
|
|
1710
|
+
push_state: string;
|
|
1711
|
+
push_last_success_utc_ms: string | null;
|
|
1712
|
+
push_last_failure_utc_ms: string | null;
|
|
1713
|
+
push_failure_count: number;
|
|
1714
|
+
pull_state: string;
|
|
1715
|
+
pull_last_success_utc_ms: string | null;
|
|
1716
|
+
pull_last_failure_utc_ms: string | null;
|
|
1717
|
+
pull_failure_count: number;
|
|
1718
|
+
bound_address: string | null;
|
|
1719
|
+
created_at: Generated<Date>;
|
|
1720
|
+
updated_at: Generated<Date>;
|
|
1721
|
+
}
|
|
1722
|
+
interface SyncCursorTable {
|
|
1723
|
+
remote_name: string;
|
|
1724
|
+
cursor_type: string;
|
|
1725
|
+
cursor_ordinal: bigint;
|
|
1726
|
+
last_synced_at_utc_ms: string | null;
|
|
1727
|
+
updated_at: Generated<Date>;
|
|
1728
|
+
}
|
|
1732
1729
|
/**
|
|
1733
|
-
*
|
|
1730
|
+
* Kysely table definition for the `sync_dead_letters` table.
|
|
1734
1731
|
*/
|
|
1735
|
-
interface
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1732
|
+
interface SyncDeadLetterTable {
|
|
1733
|
+
ordinal: Generated<number>;
|
|
1734
|
+
id: string;
|
|
1735
|
+
job_id: string;
|
|
1736
|
+
job_dependencies: unknown;
|
|
1737
|
+
remote_name: string;
|
|
1738
|
+
document_id: string;
|
|
1739
|
+
scopes: unknown;
|
|
1740
|
+
branch: string;
|
|
1741
|
+
operations: unknown;
|
|
1742
|
+
error_source: string;
|
|
1743
|
+
error_message: string;
|
|
1744
|
+
error_type: Generated<string>;
|
|
1745
|
+
created_at: Generated<Date>;
|
|
1742
1746
|
}
|
|
1743
1747
|
/**
|
|
1744
|
-
*
|
|
1748
|
+
* One (document, group) reference ever discovered from an auth operation's
|
|
1749
|
+
* input. Rows are never updated or deleted (see migration 017).
|
|
1745
1750
|
*/
|
|
1746
|
-
interface
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1751
|
+
interface GroupReferenceTable {
|
|
1752
|
+
documentId: string;
|
|
1753
|
+
groupId: string;
|
|
1754
|
+
}
|
|
1755
|
+
interface Database$1 {
|
|
1756
|
+
Operation: OperationTable;
|
|
1757
|
+
Keyframe: KeyframeTable;
|
|
1758
|
+
document_collections: DocumentCollectionTable;
|
|
1759
|
+
operation_index_operations: OperationIndexOperationTable;
|
|
1760
|
+
group_references: GroupReferenceTable;
|
|
1761
|
+
sync_remotes: SyncRemoteTable;
|
|
1762
|
+
sync_cursors: SyncCursorTable;
|
|
1763
|
+
sync_dead_letters: SyncDeadLetterTable;
|
|
1764
|
+
}
|
|
1765
|
+
interface DocumentTable {
|
|
1766
|
+
id: string;
|
|
1767
|
+
createdAt: Generated<Date>;
|
|
1768
|
+
updatedAt: Generated<Date>;
|
|
1769
|
+
}
|
|
1770
|
+
interface DocumentRelationshipTable {
|
|
1771
|
+
id: Generated<string>;
|
|
1772
|
+
sourceId: string;
|
|
1773
|
+
targetId: string;
|
|
1774
|
+
relationshipType: string;
|
|
1775
|
+
metadata: unknown;
|
|
1776
|
+
createdAt: Generated<Date>;
|
|
1777
|
+
updatedAt: Generated<Date>;
|
|
1778
|
+
}
|
|
1779
|
+
interface IndexerStateTable {
|
|
1780
|
+
id: Generated<number>;
|
|
1781
|
+
lastOperationId: number;
|
|
1782
|
+
lastOperationTimestamp: Generated<Date>;
|
|
1783
|
+
}
|
|
1784
|
+
interface DocumentIndexerDatabase {
|
|
1785
|
+
Document: DocumentTable;
|
|
1786
|
+
DocumentRelationship: DocumentRelationshipTable;
|
|
1787
|
+
IndexerState: IndexerStateTable;
|
|
1753
1788
|
}
|
|
1789
|
+
//#endregion
|
|
1790
|
+
//#region src/core/model-sources.d.ts
|
|
1791
|
+
/** An importable file holding one or more document-model exports. */
|
|
1792
|
+
type FileModelSource = {
|
|
1793
|
+
filePath: string;
|
|
1794
|
+
exportName?: string;
|
|
1795
|
+
};
|
|
1796
|
+
/** An importable package specifier holding one or more document-model exports. */
|
|
1797
|
+
type PackageModelSource = {
|
|
1798
|
+
packageName: string;
|
|
1799
|
+
subpath?: string;
|
|
1800
|
+
exportName?: string;
|
|
1801
|
+
};
|
|
1754
1802
|
/**
|
|
1755
|
-
*
|
|
1803
|
+
* A source of document models: a live module, an importable file, or an
|
|
1804
|
+
* importable package. File and package sources can cross a worker-thread
|
|
1805
|
+
* boundary (workers re-import them); a live module cannot.
|
|
1756
1806
|
*/
|
|
1757
|
-
|
|
1807
|
+
type DocumentModelSource = DocumentModelModule<any> | FileModelSource | PackageModelSource;
|
|
1808
|
+
//#endregion
|
|
1809
|
+
//#region src/registry/interfaces.d.ts
|
|
1810
|
+
type RegistrationResult<T> = {
|
|
1811
|
+
status: "success";
|
|
1812
|
+
item: T;
|
|
1813
|
+
} | {
|
|
1814
|
+
status: "error";
|
|
1815
|
+
item: T;
|
|
1816
|
+
error: Error;
|
|
1817
|
+
};
|
|
1818
|
+
/**
|
|
1819
|
+
* Loader that asynchronously resolves a document type to a
|
|
1820
|
+
* {@link DocumentModelSource}. Used by the queue to gate CREATE_DOCUMENT
|
|
1821
|
+
* jobs until the required model is available in the registry.
|
|
1822
|
+
*
|
|
1823
|
+
* Return an importable source ({ filePath } or { packageName }) whenever
|
|
1824
|
+
* possible: the resolver registers the resolved models on the host registry
|
|
1825
|
+
* and broadcasts importable sources to executor workers. A live
|
|
1826
|
+
* DocumentModelModule is also valid but host-only — it cannot cross a
|
|
1827
|
+
* worker-thread boundary, so worker pools will not receive it.
|
|
1828
|
+
*/
|
|
1829
|
+
interface IDocumentModelLoader {
|
|
1830
|
+
load(documentType: string): Promise<DocumentModelSource>;
|
|
1831
|
+
}
|
|
1832
|
+
/**
|
|
1833
|
+
* Registry for managing document model modules.
|
|
1834
|
+
* Provides centralized access to document models' reducers, utils, and specifications.
|
|
1835
|
+
* Supports version-aware module storage and upgrade manifest management.
|
|
1836
|
+
*/
|
|
1837
|
+
interface IDocumentModelRegistry {
|
|
1758
1838
|
/**
|
|
1759
|
-
*
|
|
1839
|
+
* Register multiple modules at once.
|
|
1840
|
+
* Modules without a version field default to version 1.
|
|
1841
|
+
* Invalid or duplicate modules are skipped without breaking registration of the remaining modules.
|
|
1760
1842
|
*
|
|
1761
|
-
* @param
|
|
1762
|
-
* @
|
|
1763
|
-
* @param view - Optional filter containing branch and scopes information
|
|
1764
|
-
* @returns A function that unsubscribes from the events
|
|
1843
|
+
* @param modules Document model modules to register
|
|
1844
|
+
* @returns Array of results, one per module, indicating success or failure
|
|
1765
1845
|
*/
|
|
1766
|
-
|
|
1846
|
+
registerModules(...modules: DocumentModelModule<any>[]): RegistrationResult<DocumentModelModule<any>>[];
|
|
1767
1847
|
/**
|
|
1768
|
-
*
|
|
1848
|
+
* Unregister all versions of the specified document types.
|
|
1769
1849
|
*
|
|
1770
|
-
* @param
|
|
1771
|
-
* @
|
|
1772
|
-
* @returns A function that unsubscribes from the events
|
|
1850
|
+
* @param documentTypes The document types to unregister
|
|
1851
|
+
* @returns true if all modules were unregistered, false if any were not found
|
|
1773
1852
|
*/
|
|
1774
|
-
|
|
1853
|
+
unregisterModules(...documentTypes: string[]): boolean;
|
|
1775
1854
|
/**
|
|
1776
|
-
*
|
|
1855
|
+
* Get a specific document model module by document type and optional version.
|
|
1856
|
+
* If version is not specified, returns the latest version.
|
|
1777
1857
|
*
|
|
1778
|
-
* @param
|
|
1779
|
-
* @param
|
|
1780
|
-
* @
|
|
1781
|
-
* @
|
|
1858
|
+
* @param documentType The document type identifier
|
|
1859
|
+
* @param version Optional version number to retrieve
|
|
1860
|
+
* @returns The document model module
|
|
1861
|
+
* @throws ModuleNotFoundError if the document type or version is not registered
|
|
1782
1862
|
*/
|
|
1783
|
-
|
|
1863
|
+
getModule(documentType: string, version?: number): DocumentModelModule<any>;
|
|
1784
1864
|
/**
|
|
1785
|
-
*
|
|
1865
|
+
* Get all registered document model modules.
|
|
1786
1866
|
*
|
|
1787
|
-
* @
|
|
1788
|
-
* @param search - Optional search filter to limit which documents trigger events
|
|
1789
|
-
* @returns A function that unsubscribes from the events
|
|
1867
|
+
* @returns Array of all registered modules
|
|
1790
1868
|
*/
|
|
1791
|
-
|
|
1792
|
-
}
|
|
1793
|
-
//#endregion
|
|
1794
|
-
//#region src/decision/types.d.ts
|
|
1795
|
-
/** One operation stream. */
|
|
1796
|
-
type StreamQuery = {
|
|
1797
|
-
documentId: string;
|
|
1798
|
-
branch: string;
|
|
1799
|
-
scope: string;
|
|
1800
|
-
};
|
|
1801
|
-
/**
|
|
1802
|
-
* What building a decision model reads a stream's state through.
|
|
1803
|
-
*
|
|
1804
|
-
* `IWriteCache` satisfies this and is what the write paths pass. The read path
|
|
1805
|
-
* cannot: the write cache is a write-side projection invalidated by the process
|
|
1806
|
-
* that runs the executor, so a reactor whose executors live in worker processes
|
|
1807
|
-
* holds state in its parent that no commit ever invalidates. A read there would
|
|
1808
|
-
* decide against a policy arbitrarily far behind the one the write paths
|
|
1809
|
-
* enforce. Reads therefore pass a reader backed by the read side.
|
|
1810
|
-
*/
|
|
1811
|
-
interface IStreamStateReader {
|
|
1812
|
-
getState(documentId: string, scope: string, branch: string, targetRevision?: number, signal?: AbortSignal): Promise<PHDocument>;
|
|
1813
|
-
}
|
|
1814
|
-
/** The document and branch a decision model is built for. */
|
|
1815
|
-
type DecisionTarget = {
|
|
1816
|
-
documentId: string;
|
|
1817
|
-
branch: string;
|
|
1818
|
-
};
|
|
1819
|
-
/**
|
|
1820
|
-
* What a decision's conditions may read beyond the projections: the executing
|
|
1821
|
-
* scope's own state and the attempted action's input. Populated only while
|
|
1822
|
-
* authConditions is on; otherwise both stay undefined and conditional grants
|
|
1823
|
-
* never apply.
|
|
1824
|
-
*/
|
|
1825
|
-
type DecisionContext = {
|
|
1826
|
-
scopeState: unknown;
|
|
1827
|
-
actionInput?: unknown;
|
|
1828
|
-
};
|
|
1829
|
-
/** A statically-queried stream's operations, named after its projection. */
|
|
1830
|
-
type StreamHistory = {
|
|
1831
|
-
name: string;
|
|
1832
|
-
operations: Operation[];
|
|
1833
|
-
};
|
|
1834
|
-
/**
|
|
1835
|
-
* A named stream whose value in the model is that scope's state from the
|
|
1836
|
-
* document rebuild the reactor already performs. A derived query may read
|
|
1837
|
-
* only statically-queried projections, so composition is one layer deep.
|
|
1838
|
-
*/
|
|
1839
|
-
type Projection<M> = {
|
|
1840
|
-
query: StreamQuery | ((model: Partial<M>) => StreamQuery[]);
|
|
1841
|
-
/**
|
|
1842
|
-
* For a derived projection, the streams it may read anywhere in an
|
|
1843
|
-
* evaluated range, derived from the statically-queried streams' operations
|
|
1844
|
-
* (including the operations under evaluation). A positional walk cannot use
|
|
1845
|
-
* `query`, because the folded state it depends on changes over the range;
|
|
1846
|
-
* this over-approximates by design, since a stream referenced at any
|
|
1847
|
-
* position stays readable when the earlier range is re-evaluated even if a
|
|
1848
|
-
* later operation removes the reference. Ignored on static projections.
|
|
1849
|
-
*/
|
|
1850
|
-
queryOverHistory?: (reads: StreamHistory[]) => StreamQuery[];
|
|
1851
|
-
/**
|
|
1852
|
-
* Action types in this stream that can change an evaluation. Reads of the stream
|
|
1853
|
-
* are filtered to these, so anything left out is invisible to a decision.
|
|
1854
|
-
*/
|
|
1855
|
-
decidingActions: string[]; /** Applies one of this stream's operations while deciding. */
|
|
1856
|
-
apply: (document: PHDocument, operation: Operation) => PHDocument;
|
|
1857
|
-
};
|
|
1858
|
-
/**
|
|
1859
|
-
* The outcome of evaluating one operation. A refusal carries the reason it is
|
|
1860
|
-
* recorded with, because a model has more than one way to refuse.
|
|
1861
|
-
*/
|
|
1862
|
-
type Evaluation = {
|
|
1863
|
-
decision: "allow";
|
|
1864
|
-
} | {
|
|
1865
|
-
decision: "deny";
|
|
1866
|
-
reason: string;
|
|
1867
|
-
};
|
|
1868
|
-
/** Projections plus a decision function over the built model. */
|
|
1869
|
-
type DecisionModel<M> = {
|
|
1870
|
-
projections: { [K in keyof M]: Projection<M> };
|
|
1871
|
-
/**
|
|
1872
|
-
* Present when decide reads the executing scope's state through the
|
|
1873
|
-
* decision context. A positional walk then folds the evaluated stream with
|
|
1874
|
-
* this, from its base state through every effective operation, so
|
|
1875
|
-
* conditions read the state as it stood at each operation's position
|
|
1876
|
-
* rather than at the head.
|
|
1877
|
-
*/
|
|
1878
|
-
foldEvaluatedScope?: (document: PHDocument, operation: Operation) => PHDocument;
|
|
1869
|
+
getAllModules(): DocumentModelModule<any>[];
|
|
1879
1870
|
/**
|
|
1880
|
-
*
|
|
1881
|
-
* is, a scope it reads is not necessarily one it evaluates, and vise-versa.
|
|
1871
|
+
* Clear all registered modules and upgrade manifests.
|
|
1882
1872
|
*/
|
|
1883
|
-
|
|
1884
|
-
decide(model: M, subject: AuthSubject, request: AuthRequest, ctx: DecisionContext): Evaluation;
|
|
1885
|
-
};
|
|
1886
|
-
/** A built model plus the read-set condition recording what the build read. */
|
|
1887
|
-
type BuiltDecisionModel<M> = {
|
|
1888
|
-
model: M;
|
|
1889
|
-
appendCondition: AppendCondition;
|
|
1890
|
-
};
|
|
1891
|
-
//#endregion
|
|
1892
|
-
//#region src/client/types.d.ts
|
|
1893
|
-
/**
|
|
1894
|
-
* Describes the types of document changes that can occur.
|
|
1895
|
-
*/
|
|
1896
|
-
declare enum DocumentChangeType {
|
|
1897
|
-
Created = "created",
|
|
1898
|
-
Deleted = "deleted",
|
|
1899
|
-
Updated = "updated",
|
|
1900
|
-
ParentAdded = "parent_added",
|
|
1901
|
-
ParentRemoved = "parent_removed",
|
|
1902
|
-
ChildAdded = "child_added",
|
|
1903
|
-
ChildRemoved = "child_removed"
|
|
1904
|
-
}
|
|
1905
|
-
/**
|
|
1906
|
-
* Represents a change event for documents.
|
|
1907
|
-
*/
|
|
1908
|
-
type DocumentChangeEvent = {
|
|
1909
|
-
type: DocumentChangeType;
|
|
1910
|
-
documents: PHDocument[];
|
|
1911
|
-
context?: {
|
|
1912
|
-
parentId?: string;
|
|
1913
|
-
childId?: string;
|
|
1914
|
-
};
|
|
1915
|
-
};
|
|
1916
|
-
/**
|
|
1917
|
-
* Options for creating an empty document.
|
|
1918
|
-
*/
|
|
1919
|
-
type CreateDocumentOptions = {
|
|
1920
|
-
/** Optional "id" or "slug" of parent document */parentIdentifier?: string; /** Optional version of the document model to use (defaults to latest) */
|
|
1921
|
-
documentModelVersion?: number;
|
|
1922
|
-
};
|
|
1923
|
-
/**
|
|
1924
|
-
* Options for upgrading a document.
|
|
1925
|
-
*/
|
|
1926
|
-
type UpgradeDocumentOptions = {
|
|
1873
|
+
clear(): void;
|
|
1927
1874
|
/**
|
|
1928
|
-
*
|
|
1929
|
-
*
|
|
1930
|
-
*
|
|
1875
|
+
* Get all supported versions for a document type, sorted in ascending order.
|
|
1876
|
+
*
|
|
1877
|
+
* @param documentType The document type identifier
|
|
1878
|
+
* @returns Array of version numbers sorted ascending
|
|
1879
|
+
* @throws ModuleNotFoundError if no modules are registered for the document type
|
|
1931
1880
|
*/
|
|
1932
|
-
|
|
1933
|
-
};
|
|
1934
|
-
/**
|
|
1935
|
-
* Drive-aware operations grouped under `client.drives`.
|
|
1936
|
-
*
|
|
1937
|
-
* These methods orchestrate the multi-action, multi-document choreography
|
|
1938
|
-
* required to keep a drive's `state.global.nodes` array consistent with the
|
|
1939
|
-
* relationship index and the underlying documents. Use the flat
|
|
1940
|
-
* `IReactorClient` primitives (`get`, `execute`, `find`) for everything that
|
|
1941
|
-
* is not drive-aware.
|
|
1942
|
-
*/
|
|
1943
|
-
interface IDriveClient {
|
|
1881
|
+
getSupportedVersions(documentType: string): number[];
|
|
1944
1882
|
/**
|
|
1945
|
-
*
|
|
1883
|
+
* Get the latest (highest) version number for a document type.
|
|
1884
|
+
*
|
|
1885
|
+
* @param documentType The document type identifier
|
|
1886
|
+
* @returns The highest version number registered for this document type
|
|
1887
|
+
* @throws ModuleNotFoundError if no modules are registered for the document type
|
|
1946
1888
|
*/
|
|
1947
|
-
|
|
1889
|
+
getLatestVersion(documentType: string): number;
|
|
1948
1890
|
/**
|
|
1949
|
-
*
|
|
1891
|
+
* Register upgrade manifests that define upgrade paths between versions.
|
|
1892
|
+
* Invalid or duplicate manifests are skipped without breaking registration of the remaining manifests.
|
|
1950
1893
|
*
|
|
1951
|
-
*
|
|
1952
|
-
*
|
|
1894
|
+
* @param manifests Upgrade manifests to register
|
|
1895
|
+
* @returns Array of results, one per manifest, indicating success or failure
|
|
1953
1896
|
*/
|
|
1954
|
-
|
|
1897
|
+
registerUpgradeManifests(...manifests: UpgradeManifest<readonly number[]>[]): RegistrationResult<UpgradeManifest<readonly number[]>>[];
|
|
1955
1898
|
/**
|
|
1956
|
-
*
|
|
1957
|
-
|
|
1958
|
-
|
|
1899
|
+
* Unregister upgrade manifests for the specified document types.
|
|
1900
|
+
* @param documentTypes The document types whose upgrade manifests should be unregistered
|
|
1901
|
+
* @returns true if all modules were unregistered, false if any were not found
|
|
1902
|
+
**/
|
|
1903
|
+
unregisterUpgradeManifests(...documentTypes: string[]): boolean;
|
|
1959
1904
|
/**
|
|
1960
|
-
*
|
|
1961
|
-
*
|
|
1905
|
+
* Get the upgrade manifest for a document type.
|
|
1906
|
+
*
|
|
1907
|
+
* @param documentType The document type identifier
|
|
1908
|
+
* @returns The upgrade manifest
|
|
1909
|
+
* @throws ManifestNotFoundError if no manifest is registered for the document type
|
|
1962
1910
|
*/
|
|
1963
|
-
|
|
1911
|
+
getUpgradeManifest(documentType: string): UpgradeManifest<readonly number[]>;
|
|
1964
1912
|
/**
|
|
1965
|
-
*
|
|
1966
|
-
*
|
|
1913
|
+
* Compute the upgrade path from one version to another.
|
|
1914
|
+
* Returns the sequence of upgrade transitions needed.
|
|
1915
|
+
*
|
|
1916
|
+
* @param documentType The document type identifier
|
|
1917
|
+
* @param fromVersion The starting version
|
|
1918
|
+
* @param toVersion The target version
|
|
1919
|
+
* @returns Array of upgrade transitions in order
|
|
1920
|
+
* @throws DowngradeNotSupportedError if toVersion is less than fromVersion
|
|
1921
|
+
* @throws ManifestNotFoundError if no upgrade manifest is registered
|
|
1922
|
+
* @throws MissingUpgradeTransitionError if any transition in the path is missing
|
|
1967
1923
|
*/
|
|
1968
|
-
|
|
1924
|
+
computeUpgradePath(documentType: string, fromVersion: number, toVersion: number): UpgradeTransition[];
|
|
1969
1925
|
/**
|
|
1970
|
-
*
|
|
1971
|
-
*
|
|
1926
|
+
* Get the upgrade reducer for a single-step version transition.
|
|
1927
|
+
*
|
|
1928
|
+
* @param documentType The document type identifier
|
|
1929
|
+
* @param fromVersion The starting version
|
|
1930
|
+
* @param toVersion The target version (must be fromVersion + 1)
|
|
1931
|
+
* @returns The upgrade reducer function
|
|
1932
|
+
* @throws InvalidUpgradeStepError if toVersion is not fromVersion + 1
|
|
1933
|
+
* @throws ManifestNotFoundError if no upgrade manifest is registered
|
|
1934
|
+
* @throws MissingUpgradeTransitionError if the transition is not found
|
|
1972
1935
|
*/
|
|
1973
|
-
|
|
1936
|
+
getUpgradeReducer(documentType: string, fromVersion: number, toVersion: number): UpgradeReducer<any, any>;
|
|
1937
|
+
}
|
|
1938
|
+
//#endregion
|
|
1939
|
+
//#region src/cache/buffer/ring-buffer.d.ts
|
|
1940
|
+
/**
|
|
1941
|
+
* RingBuffer is a generic circular buffer implementation that stores a fixed number
|
|
1942
|
+
* of items. When the buffer is full, new items overwrite the oldest items.
|
|
1943
|
+
*
|
|
1944
|
+
* This implementation maintains O(1) time complexity for push operations and provides
|
|
1945
|
+
* items in chronological order (oldest to newest) via getAll().
|
|
1946
|
+
*
|
|
1947
|
+
* @template T - The type of items stored in the buffer
|
|
1948
|
+
*/
|
|
1949
|
+
declare class RingBuffer<T> {
|
|
1950
|
+
private buffer;
|
|
1951
|
+
private head;
|
|
1952
|
+
private size;
|
|
1953
|
+
private capacity;
|
|
1954
|
+
constructor(capacity: number);
|
|
1974
1955
|
/**
|
|
1975
|
-
*
|
|
1976
|
-
*
|
|
1956
|
+
* Adds an item to the buffer. If the buffer is full, overwrites the oldest item.
|
|
1957
|
+
*
|
|
1958
|
+
* @param item - The item to add
|
|
1977
1959
|
*/
|
|
1978
|
-
|
|
1960
|
+
push(item: T): void;
|
|
1979
1961
|
/**
|
|
1980
|
-
*
|
|
1981
|
-
*
|
|
1962
|
+
* Returns all items in the buffer in chronological order (oldest to newest).
|
|
1963
|
+
*
|
|
1964
|
+
* @returns Array of items in insertion order
|
|
1982
1965
|
*/
|
|
1983
|
-
|
|
1966
|
+
getAll(): T[];
|
|
1984
1967
|
/**
|
|
1985
|
-
*
|
|
1968
|
+
* Clears all items from the buffer.
|
|
1986
1969
|
*/
|
|
1987
|
-
|
|
1970
|
+
clear(): void;
|
|
1988
1971
|
/**
|
|
1989
|
-
*
|
|
1990
|
-
* - omit `parentFolder` (or pass `undefined`) to list every node in the drive.
|
|
1991
|
-
* - pass `null` to list only root-level nodes.
|
|
1992
|
-
* - pass a folder id to list only the direct children of that folder.
|
|
1993
|
-
*
|
|
1994
|
-
* Returns a paged result so callers can stream through drives with very
|
|
1995
|
-
* large node counts without materialising the whole list in memory.
|
|
1972
|
+
* Gets the current number of items in the buffer.
|
|
1996
1973
|
*/
|
|
1997
|
-
|
|
1974
|
+
get length(): number;
|
|
1998
1975
|
}
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
type ActionCandidate = {
|
|
2005
|
-
scope: string;
|
|
2006
|
-
type: string;
|
|
2007
|
-
input?: unknown;
|
|
1976
|
+
//#endregion
|
|
1977
|
+
//#region src/cache/kysely-write-cache.d.ts
|
|
1978
|
+
type DocumentStream = {
|
|
1979
|
+
key: string;
|
|
1980
|
+
ringBuffer: RingBuffer<CachedSnapshot>;
|
|
2008
1981
|
};
|
|
2009
1982
|
/**
|
|
2010
|
-
*
|
|
2011
|
-
* with the aggregates a UI branches on.
|
|
1983
|
+
* In-memory write cache with keyframe persistence for PHDocuments.
|
|
2012
1984
|
*
|
|
2013
|
-
*
|
|
2014
|
-
*
|
|
2015
|
-
* so that a caller reads the one its question is phrased in rather than
|
|
2016
|
-
* negating another. Over no candidates every aggregate is false: nothing is
|
|
2017
|
-
* allowed and nothing is denied.
|
|
2018
|
-
*/
|
|
2019
|
-
type ActionEvaluations = {
|
|
2020
|
-
evaluations: Evaluation[];
|
|
2021
|
-
allAllowed: boolean;
|
|
2022
|
-
anyAllowed: boolean;
|
|
2023
|
-
allDenied: boolean;
|
|
2024
|
-
anyDenied: boolean;
|
|
2025
|
-
};
|
|
2026
|
-
/**
|
|
2027
|
-
* The ReactorClient interface that wraps lower-level APIs to provide
|
|
2028
|
-
* a simpler interface for document operations.
|
|
1985
|
+
* Caches document snapshots in ring buffers with LRU eviction. On cache miss,
|
|
1986
|
+
* rebuilds documents from nearest keyframe or full operation history.
|
|
2029
1987
|
*
|
|
2030
|
-
*
|
|
2031
|
-
* -
|
|
2032
|
-
* -
|
|
2033
|
-
* -
|
|
2034
|
-
* -
|
|
1988
|
+
* **Performance Characteristics:**
|
|
1989
|
+
* - Cache hit: O(1) lookup in ring buffer
|
|
1990
|
+
* - Cold miss: O(n) where n is total operation count, or O(k) where k is operations since keyframe
|
|
1991
|
+
* - Warm miss: O(m) where m is operations since cached revision
|
|
1992
|
+
* - Eviction: O(1) for LRU tracking and removal
|
|
1993
|
+
*
|
|
1994
|
+
* **Thread Safety:**
|
|
1995
|
+
* Not thread-safe. Designed for single-threaded job executor environment.
|
|
1996
|
+
* External synchronization required for concurrent access across multiple executors.
|
|
1997
|
+
*
|
|
1998
|
+
* **Example:**
|
|
1999
|
+
* ```typescript
|
|
2000
|
+
* const cache = new KyselyWriteCache(
|
|
2001
|
+
* keyframeStore,
|
|
2002
|
+
* operationStore,
|
|
2003
|
+
* registry,
|
|
2004
|
+
* { maxDocuments: 1000, ringBufferSize: 10, keyframeInterval: 10 }
|
|
2005
|
+
* );
|
|
2006
|
+
*
|
|
2007
|
+
* await cache.startup();
|
|
2008
|
+
*
|
|
2009
|
+
* // Retrieve or rebuild document
|
|
2010
|
+
* const doc = await cache.getState(docId, docType, scope, branch, revision);
|
|
2011
|
+
*
|
|
2012
|
+
* // Cache result after job execution
|
|
2013
|
+
* cache.putState(docId, docType, scope, branch, newRevision, updatedDoc);
|
|
2014
|
+
*
|
|
2015
|
+
* await cache.shutdown();
|
|
2016
|
+
* ```
|
|
2035
2017
|
*/
|
|
2036
|
-
|
|
2018
|
+
declare class KyselyWriteCache implements IWriteCache {
|
|
2019
|
+
private streams;
|
|
2020
|
+
private lruTracker;
|
|
2021
|
+
private keyframeStore;
|
|
2022
|
+
private operationStore;
|
|
2023
|
+
private registry;
|
|
2024
|
+
private config;
|
|
2025
|
+
constructor(keyframeStore: IKeyframeStore, operationStore: IOperationStore, registry: IDocumentModelRegistry, config: WriteCacheConfig);
|
|
2026
|
+
withScopedStores(operationStore: IOperationStore, keyframeStore: IKeyframeStore): KyselyWriteCache;
|
|
2037
2027
|
/**
|
|
2038
|
-
*
|
|
2028
|
+
* Initializes the write cache.
|
|
2029
|
+
* Currently a no-op as keyframe store lifecycle is managed externally.
|
|
2039
2030
|
*/
|
|
2040
|
-
|
|
2031
|
+
startup(): Promise<void>;
|
|
2041
2032
|
/**
|
|
2042
|
-
*
|
|
2043
|
-
*
|
|
2044
|
-
* @param namespace - Optional namespace like "powerhouse" or "sky", defaults to ""
|
|
2045
|
-
* @param paging - Optional pagination options
|
|
2046
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2047
|
-
* @returns List of document model modules
|
|
2033
|
+
* Shuts down the write cache.
|
|
2034
|
+
* Currently a no-op as keyframe store lifecycle is managed externally.
|
|
2048
2035
|
*/
|
|
2049
|
-
|
|
2036
|
+
shutdown(): Promise<void>;
|
|
2050
2037
|
/**
|
|
2051
|
-
* Retrieves a specific
|
|
2038
|
+
* Retrieves document state at a specific revision from cache or rebuilds it.
|
|
2052
2039
|
*
|
|
2053
|
-
*
|
|
2054
|
-
* @returns The document model module
|
|
2055
|
-
*/
|
|
2056
|
-
getDocumentModelModule(documentType: string): Promise<DocumentModelModule<any>>;
|
|
2057
|
-
/**
|
|
2058
|
-
* Retrieves a specific document by identifier (either id or slug).
|
|
2040
|
+
* Note: this returns a _shallow_ copy of the document.
|
|
2059
2041
|
*
|
|
2060
|
-
*
|
|
2061
|
-
*
|
|
2062
|
-
*
|
|
2063
|
-
*
|
|
2042
|
+
* Cache hit path: Returns cached snapshot if available (O(1))
|
|
2043
|
+
* Warm miss path: Rebuilds from cached base revision + incremental ops
|
|
2044
|
+
* Cold miss path: Rebuilds from keyframe or from scratch using all operations
|
|
2045
|
+
*
|
|
2046
|
+
* @param documentId - The document identifier
|
|
2047
|
+
* @param scope - The operation scope
|
|
2048
|
+
* @param branch - The operation branch
|
|
2049
|
+
* @param targetRevision - The target revision, or undefined for newest
|
|
2050
|
+
* @param signal - Optional abort signal to cancel the operation
|
|
2051
|
+
* @returns The document at the target revision
|
|
2052
|
+
* @throws {Error} "Operation aborted" if signal is aborted
|
|
2053
|
+
* @throws {ModuleNotFoundError} If document type not registered in registry
|
|
2054
|
+
* @throws {Error} "Failed to rebuild document" if operation store fails
|
|
2055
|
+
* @throws {Error} If reducer throws during operation application
|
|
2056
|
+
* @throws {Error} If document serialization fails
|
|
2064
2057
|
*/
|
|
2065
|
-
|
|
2058
|
+
getState(documentId: string, scope: string, branch: string, targetRevision?: number, signal?: AbortSignal): Promise<PHDocument>;
|
|
2066
2059
|
/**
|
|
2067
|
-
*
|
|
2068
|
-
* id, using the same lookup as the read/operation data paths. Resolves
|
|
2069
|
-
* against the "main" branch. Throws if the identifier cannot be resolved or
|
|
2070
|
-
* is ambiguous.
|
|
2060
|
+
* Stores a document snapshot in the cache at a specific revision.
|
|
2071
2061
|
*
|
|
2072
|
-
*
|
|
2073
|
-
*
|
|
2074
|
-
*
|
|
2062
|
+
* The cached document is a shallow copy of the input with its operation history
|
|
2063
|
+
* truncated to the last operation per scope and its clipboard cleared. This keeps
|
|
2064
|
+
* memory use and copy costs constant regardless of operation count. Consumers of
|
|
2065
|
+
* getState() must not rely on the full operation history being present; the only
|
|
2066
|
+
* guaranteed invariant is that operations[scope].at(-1) reflects the latest
|
|
2067
|
+
* operation index for each scope.
|
|
2068
|
+
*
|
|
2069
|
+
* Updates LRU tracker and may evict least recently used stream if at capacity.
|
|
2070
|
+
* Asynchronously persists keyframes at configured intervals (fire-and-forget).
|
|
2071
|
+
*
|
|
2072
|
+
* @param documentId - The document identifier
|
|
2073
|
+
* @param scope - The operation scope
|
|
2074
|
+
* @param branch - The operation branch
|
|
2075
|
+
* @param revision - The revision number
|
|
2076
|
+
* @param document - The document to cache
|
|
2077
|
+
* @throws {Error} If document serialization fails
|
|
2075
2078
|
*/
|
|
2076
|
-
|
|
2077
|
-
/** True when the id is taken; a soft-deleted document's id is still taken. */
|
|
2078
|
-
isDocumentIdTaken(documentId: string, signal?: AbortSignal): Promise<boolean>;
|
|
2079
|
+
putState(documentId: string, scope: string, branch: string, revision: number, document: PHDocument, position: SnapshotPosition): void;
|
|
2079
2080
|
/**
|
|
2080
|
-
*
|
|
2081
|
-
*
|
|
2082
|
-
*
|
|
2083
|
-
* @param view - Optional filter containing branch and scopes information
|
|
2084
|
-
* @param filter - Optional filter for actionTypes, timestamps, and revision
|
|
2085
|
-
* @param paging - Optional pagination options
|
|
2086
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2087
|
-
* @returns Paginated list of operations
|
|
2081
|
+
* Stores the run's head and mints a keyframe for every interval the run
|
|
2082
|
+
* crossed on its way there. Only the head enters the ring buffer; the
|
|
2083
|
+
* earlier revisions are keyframe candidates and nothing more.
|
|
2088
2084
|
*/
|
|
2089
|
-
|
|
2085
|
+
putRun(documentId: string, scope: string, branch: string, run: readonly {
|
|
2086
|
+
revision: number;
|
|
2087
|
+
document: PHDocument;
|
|
2088
|
+
}[]): void;
|
|
2089
|
+
private store;
|
|
2090
|
+
/** Persists the snapshot if this revision is one the interval falls on. */
|
|
2091
|
+
private persistKeyframe;
|
|
2090
2092
|
/**
|
|
2091
|
-
*
|
|
2093
|
+
* Invalidates cached document streams.
|
|
2092
2094
|
*
|
|
2093
|
-
*
|
|
2094
|
-
*
|
|
2095
|
-
*
|
|
2096
|
-
*
|
|
2097
|
-
*
|
|
2098
|
-
* @
|
|
2095
|
+
* Supports three invalidation scopes:
|
|
2096
|
+
* - Document-level: invalidate(documentId) - removes all streams for document
|
|
2097
|
+
* - Scope-level: invalidate(documentId, scope) - removes all branches for scope
|
|
2098
|
+
* - Stream-level: invalidate(documentId, scope, branch) - removes specific stream
|
|
2099
|
+
*
|
|
2100
|
+
* @param documentId - The document identifier
|
|
2101
|
+
* @param scope - Optional scope to narrow invalidation
|
|
2102
|
+
* @param branch - Optional branch to narrow invalidation (requires scope)
|
|
2103
|
+
* @returns The number of streams evicted
|
|
2099
2104
|
*/
|
|
2100
|
-
|
|
2105
|
+
invalidate(documentId: string, scope?: string, branch?: string): number;
|
|
2101
2106
|
/**
|
|
2102
|
-
*
|
|
2103
|
-
*
|
|
2104
|
-
* @param targetIdentifier - Required, this is either a document "id" field or a "slug"
|
|
2105
|
-
* @param relationshipType - The relationship type to filter by
|
|
2106
|
-
* @param view - Optional filter containing branch and scopes information
|
|
2107
|
-
* @param paging - Optional pagination options
|
|
2108
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2109
|
-
* @returns The source documents and paging cursor
|
|
2107
|
+
* Clears the entire cache, removing all cached document streams.
|
|
2108
|
+
* Resets LRU tracking state. This operation always succeeds.
|
|
2110
2109
|
*/
|
|
2111
|
-
|
|
2110
|
+
clear(): void;
|
|
2112
2111
|
/**
|
|
2113
|
-
* Retrieves
|
|
2114
|
-
*
|
|
2115
|
-
* Unlike {@link IReactorClient.getOutgoingRelationships}, which returns the
|
|
2116
|
-
* documents at the far end, this returns the edges themselves, carrying the
|
|
2117
|
-
* metadata and timestamps recorded against each relationship.
|
|
2112
|
+
* Retrieves a specific stream for a document. Exposed on the implementation
|
|
2113
|
+
* for testing, but not on the interface.
|
|
2118
2114
|
*
|
|
2119
|
-
* @
|
|
2120
|
-
* @param relationshipType - Optional relationship type to filter by
|
|
2121
|
-
* @param view - Optional filter containing branch and scopes information
|
|
2122
|
-
* @param paging - Optional pagination options
|
|
2123
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2124
|
-
* @returns The matching relationship edges and paging cursor
|
|
2115
|
+
* @internal
|
|
2125
2116
|
*/
|
|
2126
|
-
|
|
2117
|
+
getStream(documentId: string, scope: string, branch: string): DocumentStream | undefined;
|
|
2118
|
+
private findNearestKeyframe;
|
|
2127
2119
|
/**
|
|
2128
|
-
*
|
|
2129
|
-
*
|
|
2130
|
-
* Unlike {@link IReactorClient.getIncomingRelationships}, which returns the
|
|
2131
|
-
* documents at the far end, this returns the edges themselves, carrying the
|
|
2132
|
-
* metadata and timestamps recorded against each relationship.
|
|
2120
|
+
* Rebuilds a scope from a keyframe or from the whole operation history.
|
|
2133
2121
|
*
|
|
2134
|
-
*
|
|
2135
|
-
*
|
|
2136
|
-
*
|
|
2137
|
-
*
|
|
2138
|
-
*
|
|
2139
|
-
*
|
|
2122
|
+
* The document scope is always rebuilt first, because it carries the type,
|
|
2123
|
+
* the upgrades and the deletion marker. Its version-changing upgrades are not
|
|
2124
|
+
* applied there though: an upgrade reducer must see the state the requested
|
|
2125
|
+
* scope has reached at that upgrade's boundary, so each one is held back and
|
|
2126
|
+
* applied when the replay below crosses the boundary that
|
|
2127
|
+
* resolveModuleVersionForOp derives from it. Upgrades whose boundary lies past
|
|
2128
|
+
* the last replayed operation are applied at the end. Creation-time 0->N seed
|
|
2129
|
+
* upgrades carry the initial state, so they still apply immediately.
|
|
2140
2130
|
*/
|
|
2141
|
-
|
|
2131
|
+
private coldMissRebuild;
|
|
2142
2132
|
/**
|
|
2143
|
-
*
|
|
2144
|
-
*
|
|
2145
|
-
* @param search - Search filter options (type, parentId, identifiers)
|
|
2146
|
-
* @param view - Optional filter containing branch and scopes information
|
|
2147
|
-
* @param paging - Optional pagination options
|
|
2148
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2149
|
-
* @returns List of documents matching criteria and pagination cursor
|
|
2133
|
+
* Applies and removes every held-back upgrade whose target version is at or
|
|
2134
|
+
* below `throughVersion`, in the order the document scope recorded them.
|
|
2150
2135
|
*/
|
|
2151
|
-
|
|
2136
|
+
private applyPendingUpgrades;
|
|
2152
2137
|
/**
|
|
2153
|
-
*
|
|
2154
|
-
*
|
|
2155
|
-
*
|
|
2156
|
-
*
|
|
2157
|
-
*
|
|
2158
|
-
*
|
|
2159
|
-
*
|
|
2160
|
-
*
|
|
2161
|
-
* policy change landing between this answer and the submit changes the
|
|
2162
|
-
* verdict. The submit path stays the only authority.
|
|
2163
|
-
* - The verdict is evaluated at the stream heads. It is therefore correct for
|
|
2164
|
-
* a candidate that will be stamped at or after every timestamp the
|
|
2165
|
-
* evaluation read, which is the normal case for a control the user is about
|
|
2166
|
-
* to click. A backdated submission is out of contract: the reactor decides
|
|
2167
|
-
* that one by position, against the policy as it stood there.
|
|
2168
|
-
* - A candidate whose input decides the verdict needs that input supplied.
|
|
2169
|
-
* With `authConditions` on, a conditional grant reads `action.input`, so
|
|
2170
|
-
* omitting the input predicts the denial an empty input would earn rather
|
|
2171
|
-
* than the verdict the filled-in form will get.
|
|
2172
|
-
*
|
|
2173
|
-
* Document-scope candidates are decided against the policy of the document
|
|
2174
|
-
* their input names, not the one passed here: delete and upgrade name it in
|
|
2175
|
-
* `input.documentId`, and the relationship actions in `input.sourceId`. This
|
|
2176
|
-
* follows the executor's own gate, which decides against the document
|
|
2177
|
-
* guarding the write. `CREATE_DOCUMENT` follows the gate's exemption: it runs
|
|
2178
|
-
* before its document exists, so the executor never decides it against a
|
|
2179
|
-
* policy and the preflight predicts allow.
|
|
2180
|
-
*
|
|
2181
|
-
* @param documentIdentifier - Document "id" or "slug" the candidates target
|
|
2182
|
-
* @param branch - Branch to evaluate against
|
|
2183
|
-
* @param candidates - Operations to predict a verdict for, each with the scope it would execute in
|
|
2184
|
-
* @param subject - Optional subject to decide for, defaulting to the client's own signer. A plain subject rather than a ViewFilter: the evaluation reads no view, so a filter's branch or scopes would be silently ignored here
|
|
2185
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2186
|
-
* @returns One evaluation per candidate, in the order given, with the aggregates over them
|
|
2187
|
-
* @throws AuthEnforcementDisabledError if the reactor's authEnforcement flag is off, in which case it holds no decision model and the legacy host-table permission system cannot answer for one
|
|
2138
|
+
* Applies the remaining held-back upgrades after the requested scope's
|
|
2139
|
+
* replay has finished. A head read applies them all. A positional read
|
|
2140
|
+
* applies only those whose boundary for this scope lies at or before the
|
|
2141
|
+
* target position: applying a later one would label migrated state with a
|
|
2142
|
+
* pre-upgrade revision, and a keyframe stored from that poisons every
|
|
2143
|
+
* rebuild that resumes from it. Boundaries come from the upgrade's revision
|
|
2144
|
+
* snapshot; an upgrade without one records no position for this scope, and
|
|
2145
|
+
* the replay loop not having crossed it already places it past the target.
|
|
2188
2146
|
*/
|
|
2189
|
-
|
|
2147
|
+
private applyTailPendingUpgrades;
|
|
2190
2148
|
/**
|
|
2191
|
-
*
|
|
2192
|
-
*
|
|
2193
|
-
* @param document - Document with optional id, slug, parent, model type, and initial state
|
|
2194
|
-
* @param parentIdentifier - Optional "id" or "slug" of parent document
|
|
2195
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2196
|
-
* @returns The created document
|
|
2149
|
+
* Applies one held-back upgrade, then re-applies the deletes the document
|
|
2150
|
+
* scope recorded after it so the hold-back cannot invert their order.
|
|
2197
2151
|
*/
|
|
2198
|
-
|
|
2152
|
+
private applyPendingUpgrade;
|
|
2199
2153
|
/**
|
|
2200
|
-
*
|
|
2201
|
-
*
|
|
2202
|
-
* @param documentModelType - Type of document to create
|
|
2203
|
-
* @param options - Optional creation options (parentIdentifier, documentModelVersion)
|
|
2204
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2154
|
+
* Copies the current document revisions onto the document. Overwrites the
|
|
2155
|
+
* requested scope revision with the target revision, if provided.
|
|
2205
2156
|
*/
|
|
2206
|
-
|
|
2157
|
+
private stampRevisions;
|
|
2158
|
+
/** The stored operation at `index`, or undefined if it is no longer there. */
|
|
2159
|
+
private operationAt;
|
|
2207
2160
|
/**
|
|
2208
|
-
*
|
|
2209
|
-
* stamped with. Use this instead of {@link getDocumentModelModule}
|
|
2210
|
-
* whenever a specific document is in hand: the latest-wins lookup feeds
|
|
2211
|
-
* not-yet-upgraded documents the wrong reducer, diverging from replay.
|
|
2161
|
+
* Resolves which module version to use for a given operation in phase 2.
|
|
2212
2162
|
*
|
|
2213
|
-
*
|
|
2214
|
-
*
|
|
2215
|
-
*
|
|
2163
|
+
* Uses the validated-upgrade boundary rules from D7:
|
|
2164
|
+
* - If `input.revision` is present: op.index < revision[scope] → before the upgrade boundary
|
|
2165
|
+
* - Otherwise: timestamp fallback
|
|
2166
|
+
* - Falls back to final module version when neither is decidable
|
|
2216
2167
|
*/
|
|
2217
|
-
|
|
2168
|
+
private resolveModuleVersionForOp;
|
|
2169
|
+
private warmMissRebuild;
|
|
2170
|
+
private findNearestOlderSnapshot;
|
|
2171
|
+
private makeStreamKey;
|
|
2172
|
+
private getOrCreateStream;
|
|
2173
|
+
private isKeyframeRevision;
|
|
2174
|
+
}
|
|
2175
|
+
//#endregion
|
|
2176
|
+
//#region src/storage/kysely/store.d.ts
|
|
2177
|
+
declare class KyselyOperationStore implements IOperationStore {
|
|
2178
|
+
private db;
|
|
2179
|
+
private trx?;
|
|
2180
|
+
constructor(db: Kysely<Database$1>);
|
|
2181
|
+
private get queryExecutor();
|
|
2182
|
+
withTransaction(trx: Transaction<Database$1>): KyselyOperationStore;
|
|
2183
|
+
apply(documentId: string, documentType: string, scope: string, branch: string, revision: number, fn: (txn: AtomicTxn) => void | Promise<void>, signal?: AbortSignal, condition?: AppendCondition): Promise<Operation[]>;
|
|
2184
|
+
private resolveUniqueConstraint;
|
|
2185
|
+
private executeApply;
|
|
2218
2186
|
/**
|
|
2219
|
-
*
|
|
2220
|
-
*
|
|
2221
|
-
*
|
|
2222
|
-
*
|
|
2223
|
-
*
|
|
2224
|
-
* The action carries a snapshot of the document's version and per-scope
|
|
2225
|
-
* revisions, which the executor validates before persisting. When an edit
|
|
2226
|
-
* lands between the read and the upgrade executing, the upgrade is
|
|
2227
|
-
* rejected and retried with a fresh read up to
|
|
2228
|
-
* {@link UpgradeDocumentOptions.maxConflictRetries} times before the
|
|
2229
|
-
* conflict is surfaced.
|
|
2230
|
-
*
|
|
2231
|
-
* @param documentIdentifier - Target document id or slug
|
|
2232
|
-
* @param toVersion - Optional target document model version; defaults to latest
|
|
2233
|
-
* @param options - Optional upgrade options (maxConflictRetries)
|
|
2234
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2235
|
-
* @returns The upgraded document
|
|
2236
|
-
* @throws DowngradeNotSupportedError if toVersion is less than the document's current version
|
|
2187
|
+
* Locks the written stream and every read-set stream, in sorted key order
|
|
2188
|
+
* so that overlapping concurrent appends serialize rather than deadlock.
|
|
2189
|
+
* The locks are still taken one row at a time, so the query preserves that
|
|
2190
|
+
* order. It must stay separate from the guarded insert, which would
|
|
2191
|
+
* otherwise read a snapshot taken before the locks were held.
|
|
2237
2192
|
*/
|
|
2238
|
-
|
|
2193
|
+
private acquireStreamLocks;
|
|
2239
2194
|
/**
|
|
2240
|
-
*
|
|
2241
|
-
*
|
|
2242
|
-
*
|
|
2243
|
-
*
|
|
2244
|
-
* @deprecated Use {@link IDriveClient.addFile} via `client.drives.addFile`
|
|
2245
|
-
* instead. This method will be removed in a future release.
|
|
2246
|
-
* @param driveId - The drive document id or slug
|
|
2247
|
-
* @param document - The document to create
|
|
2248
|
-
* @param parentFolder - Optional folder id within the drive
|
|
2249
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2250
|
-
* @returns The created document
|
|
2195
|
+
* Inserts the staged operations with the condition compiled in as a WHERE
|
|
2196
|
+
* NOT EXISTS guard, making the check and the append one statement. Returns
|
|
2197
|
+
* the rows inserted; zero means the guard failed and nothing was written.
|
|
2251
2198
|
*/
|
|
2252
|
-
|
|
2199
|
+
private insertGuarded;
|
|
2200
|
+
private findIdempotentReplay;
|
|
2201
|
+
/** True when the staged write creates a document rather than appending to one. */
|
|
2202
|
+
private isCreate;
|
|
2253
2203
|
/**
|
|
2254
|
-
*
|
|
2255
|
-
*
|
|
2256
|
-
*
|
|
2257
|
-
*
|
|
2258
|
-
*
|
|
2259
|
-
*
|
|
2260
|
-
* without it the gate would strip the domain scopes of a policied document
|
|
2261
|
-
* and resolve with a husk whose `state.global` is absent — reading as a
|
|
2262
|
-
* rejected write when the write in fact succeeded.
|
|
2263
|
-
*
|
|
2264
|
-
* @param documentIdentifier - Target document id or slug
|
|
2265
|
-
* @param branch - Branch to apply actions to
|
|
2266
|
-
* @param actions - List of actions to apply
|
|
2267
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2268
|
-
* @param subject - Optional read subject for the returned document; defaults
|
|
2269
|
-
* to the client's signer
|
|
2270
|
-
* @returns The updated document
|
|
2204
|
+
* The paging cursor here encodes the index to resume from (one past the
|
|
2205
|
+
* last row returned), not the last row's own index. This keeps "0" an
|
|
2206
|
+
* unambiguous start-of-stream sentinel even when a page ends at index 0
|
|
2207
|
+
* (e.g. `limit: 1` on a fresh stream), which would otherwise make
|
|
2208
|
+
* `nextCursor` equal the start cursor and loop a caller that walks pages
|
|
2209
|
+
* forever.
|
|
2271
2210
|
*/
|
|
2272
|
-
|
|
2211
|
+
getSince(documentId: string, scope: string, branch: string, revision: number, filter?: OperationFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<Operation>>;
|
|
2212
|
+
getSinceId(id: number, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<OperationWithContext$1>>;
|
|
2273
2213
|
/**
|
|
2274
|
-
*
|
|
2275
|
-
*
|
|
2276
|
-
*
|
|
2277
|
-
*
|
|
2278
|
-
* @param actions - List of actions to apply
|
|
2279
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2280
|
-
* @returns The job
|
|
2214
|
+
* The paging cursor here encodes the index to resume from (one past the
|
|
2215
|
+
* last row returned), not the last row's own index, for the same reason as
|
|
2216
|
+
* `getSince`: a page ending at index 0 must not produce a cursor that is
|
|
2217
|
+
* indistinguishable from the start-of-stream sentinel.
|
|
2281
2218
|
*/
|
|
2282
|
-
|
|
2219
|
+
getConflicting(documentId: string, scope: string, branch: string, minTimestamp: string, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<Operation>>;
|
|
2220
|
+
getRevisions(documentId: string, branch: string, signal?: AbortSignal): Promise<DocumentRevisions>;
|
|
2221
|
+
getStreamLatestTimestamp(documentId: string, scope: string, branch: string, signal?: AbortSignal): Promise<string | undefined>;
|
|
2222
|
+
findOperationIds(documentId: string, scope: string, branch: string, opIds: string[], signal?: AbortSignal): Promise<Set<string>>;
|
|
2223
|
+
getOperationsByIds(documentId: string, scope: string, branch: string, opIds: string[], signal?: AbortSignal): Promise<Operation[]>;
|
|
2224
|
+
private rowToOperation;
|
|
2225
|
+
private rowToOperationWithContext;
|
|
2226
|
+
}
|
|
2227
|
+
//#endregion
|
|
2228
|
+
//#region src/storage/kysely/keyframe-store.d.ts
|
|
2229
|
+
declare class KyselyKeyframeStore implements IKeyframeStore {
|
|
2230
|
+
private db;
|
|
2231
|
+
private trx?;
|
|
2232
|
+
constructor(db: Kysely<Database$1>);
|
|
2233
|
+
private get queryExecutor();
|
|
2234
|
+
withTransaction(trx: Transaction<Database$1>): KyselyKeyframeStore;
|
|
2235
|
+
putKeyframe(documentId: string, scope: string, branch: string, revision: number, document: PHDocument, signal?: AbortSignal): Promise<void>;
|
|
2236
|
+
findNearestKeyframe(documentId: string, scope: string, branch: string, targetRevision: number, signal?: AbortSignal): Promise<{
|
|
2237
|
+
revision: number;
|
|
2238
|
+
document: PHDocument;
|
|
2239
|
+
} | undefined>;
|
|
2240
|
+
listKeyframes(documentId: string, scope?: string, branch?: string, signal?: AbortSignal): Promise<Array<{
|
|
2241
|
+
scope: string;
|
|
2242
|
+
branch: string;
|
|
2243
|
+
revision: number;
|
|
2244
|
+
document: PHDocument;
|
|
2245
|
+
}>>;
|
|
2246
|
+
deleteKeyframes(documentId: string, scope?: string, branch?: string, signal?: AbortSignal): Promise<number>;
|
|
2247
|
+
}
|
|
2248
|
+
//#endregion
|
|
2249
|
+
//#region src/executor/execution-scope.d.ts
|
|
2250
|
+
interface ExecutionStores {
|
|
2251
|
+
operationStore: IOperationStore;
|
|
2252
|
+
operationIndex: IOperationIndex;
|
|
2253
|
+
writeCache: IWriteCache;
|
|
2254
|
+
documentMetaCache: IDocumentMetaCache;
|
|
2255
|
+
collectionMembershipCache: ICollectionMembershipCache;
|
|
2256
|
+
}
|
|
2257
|
+
interface IExecutionScope {
|
|
2258
|
+
run<T>(fn: (stores: ExecutionStores) => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
2259
|
+
}
|
|
2260
|
+
//#endregion
|
|
2261
|
+
//#region src/executor/types.d.ts
|
|
2262
|
+
/**
|
|
2263
|
+
* Represents the result of a job execution
|
|
2264
|
+
*/
|
|
2265
|
+
type JobResult = {
|
|
2266
|
+
/** The job that was executed */job: Job; /** Whether the job executed successfully */
|
|
2267
|
+
success: boolean; /** Error if the job failed */
|
|
2268
|
+
error?: Error; /** The operations generated from the actions (if successful) */
|
|
2269
|
+
operations?: Operation[];
|
|
2283
2270
|
/**
|
|
2284
|
-
*
|
|
2285
|
-
*
|
|
2286
|
-
* dispatch. Throws on the first failed job; the others may still execute
|
|
2287
|
-
* because dispatch is fire-and-await-all.
|
|
2288
|
-
*
|
|
2289
|
-
* @param request - Batch mutation request with per-job actions and dependsOn keys
|
|
2290
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2291
|
-
* @returns The completed batch result (job ids keyed by plan key)
|
|
2271
|
+
* Operations with context (includes ephemeral resultingState).
|
|
2272
|
+
* Used for emitting to IDocumentView via event bus.
|
|
2292
2273
|
*/
|
|
2293
|
-
|
|
2274
|
+
operationsWithContext?: OperationWithContext$1[]; /** Timestamp when the job execution completed */
|
|
2275
|
+
completedAt?: string; /** Duration of job execution in milliseconds */
|
|
2276
|
+
duration?: number; /** Any additional metadata from the execution */
|
|
2277
|
+
metadata?: Record<string, any>;
|
|
2278
|
+
};
|
|
2279
|
+
/**
|
|
2280
|
+
* Enforcement the reactor performs, each off by default.
|
|
2281
|
+
*
|
|
2282
|
+
* An evaluation made while replaying is part of the document's history, so two
|
|
2283
|
+
* reactors that share documents and disagree on these diverge. A flag is turned
|
|
2284
|
+
* on for a set of reactors that sync with each other, not for one node.
|
|
2285
|
+
*/
|
|
2286
|
+
type ReactorFeatureFlags = {
|
|
2294
2287
|
/**
|
|
2295
|
-
*
|
|
2296
|
-
*
|
|
2297
|
-
*
|
|
2298
|
-
*
|
|
2299
|
-
* @param branch - Optional branch to rename the document, defaults to "main"
|
|
2300
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2301
|
-
* @returns The updated document.
|
|
2302
|
-
*/
|
|
2303
|
-
rename(documentIdentifier: string, name: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
2304
|
-
/**
|
|
2305
|
-
* Updates the preferred editor in the document header meta and waits for completion.
|
|
2306
|
-
*
|
|
2307
|
-
* @param documentIdentifier - Target document id or slug
|
|
2308
|
-
* @param preferredEditor - The new preferred editor, or `null` to clear it
|
|
2309
|
-
* @param branch - Optional branch, defaults to "main"
|
|
2310
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2311
|
-
* @returns The updated document.
|
|
2312
|
-
*/
|
|
2313
|
-
setPreferredEditor(documentIdentifier: string, preferredEditor: string | null, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
2314
|
-
/**
|
|
2315
|
-
* Adds a relationship between two documents and waits for completion.
|
|
2316
|
-
*
|
|
2317
|
-
* Adding a relationship that already exists is a no-op, metadata included.
|
|
2318
|
-
* Use {@link IReactorClient.updateRelationship} to change an existing edge.
|
|
2319
|
-
*
|
|
2320
|
-
* @param sourceIdentifier - Source document id or slug
|
|
2321
|
-
* @param targetIdentifier - Target document id or slug
|
|
2322
|
-
* @param relationshipType - Relationship type identifier
|
|
2323
|
-
* @param metadata - Optional metadata to attach to the relationship
|
|
2324
|
-
* @param branch - Optional branch to add the relationship to, defaults to "main"
|
|
2325
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2326
|
-
* @returns The updated source document
|
|
2327
|
-
*/
|
|
2328
|
-
addRelationship(sourceIdentifier: string, targetIdentifier: string, relationshipType: string, metadata?: Record<string, unknown>, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
2329
|
-
/**
|
|
2330
|
-
* Replaces the metadata of an existing relationship and waits for completion.
|
|
2331
|
-
* The relationship's createdAt is preserved.
|
|
2332
|
-
*
|
|
2333
|
-
* @param sourceIdentifier - Source document id or slug
|
|
2334
|
-
* @param targetIdentifier - Target document id or slug
|
|
2335
|
-
* @param relationshipType - Relationship type identifier
|
|
2336
|
-
* @param metadata - The metadata to store; null clears it
|
|
2337
|
-
* @param branch - Optional branch holding the relationship, defaults to "main"
|
|
2338
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2339
|
-
* @returns The updated source document
|
|
2340
|
-
*/
|
|
2341
|
-
updateRelationship(sourceIdentifier: string, targetIdentifier: string, relationshipType: string, metadata: Record<string, unknown> | null, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
2342
|
-
/**
|
|
2343
|
-
* Removes a relationship between two documents and waits for completion.
|
|
2344
|
-
*
|
|
2345
|
-
* @param sourceIdentifier - Source document id or slug
|
|
2346
|
-
* @param targetIdentifier - Target document id or slug
|
|
2347
|
-
* @param relationshipType - Relationship type identifier
|
|
2348
|
-
* @param branch - Optional branch to remove the relationship from, defaults to "main"
|
|
2349
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2350
|
-
* @returns The updated source document
|
|
2351
|
-
*/
|
|
2352
|
-
removeRelationship(sourceIdentifier: string, targetIdentifier: string, relationshipType: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
2353
|
-
/**
|
|
2354
|
-
* Moves a relationship from one source document to another and waits for completion.
|
|
2355
|
-
*
|
|
2356
|
-
* @param sourceParentIdentifier - Source parent document id or slug
|
|
2357
|
-
* @param targetParentIdentifier - Target parent document id or slug
|
|
2358
|
-
* @param targetIdentifier - The target document id or slug
|
|
2359
|
-
* @param relationshipType - Relationship type identifier
|
|
2360
|
-
* @param branch - Optional branch to apply the move to, defaults to "main"
|
|
2361
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2362
|
-
* @returns The updated source and target documents
|
|
2288
|
+
* Decide whether an operation may be admitted by building a decision model
|
|
2289
|
+
* over the document stream, rather than reading the deleted flag from the
|
|
2290
|
+
* document meta cache. Deletion then takes effect from the deleting
|
|
2291
|
+
* operation's position rather than for the whole document.
|
|
2363
2292
|
*/
|
|
2364
|
-
|
|
2365
|
-
source: PHDocument;
|
|
2366
|
-
target: PHDocument;
|
|
2367
|
-
}>;
|
|
2293
|
+
documentDecisions: boolean;
|
|
2368
2294
|
/**
|
|
2369
|
-
*
|
|
2370
|
-
*
|
|
2371
|
-
* @param identifier - Document identifier (id or slug)
|
|
2372
|
-
* @param propagate - Optional mode for handling children, CASCADE deletes child documents
|
|
2373
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2374
|
-
* @returns a promise, resolving on deletion confirmation
|
|
2295
|
+
* Evaluate the auth policy by reading the auth scope as a second projection.
|
|
2296
|
+
* Requires documentDecisions.
|
|
2375
2297
|
*/
|
|
2376
|
-
|
|
2298
|
+
authEnforcement: boolean;
|
|
2377
2299
|
/**
|
|
2378
|
-
*
|
|
2379
|
-
*
|
|
2380
|
-
* @param identifiers - Document identifiers (ids or slugs)
|
|
2381
|
-
* @param propagate - Optional mode for handling children, CASCADE deletes child documents
|
|
2382
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2383
|
-
* @returns a promise, resolving on deletion confirmation
|
|
2300
|
+
* Match { group } principals by folding the referenced PHGroup documents as
|
|
2301
|
+
* derived projections. Requires authEnforcement.
|
|
2384
2302
|
*/
|
|
2385
|
-
|
|
2303
|
+
authGroups: boolean;
|
|
2386
2304
|
/**
|
|
2387
|
-
*
|
|
2388
|
-
*
|
|
2389
|
-
*
|
|
2390
|
-
* @param request - Batch load request containing jobs with dependencies
|
|
2391
|
-
* @param signal - Optional abort signal to cancel the request
|
|
2392
|
-
* @returns Map of job keys to completed job information
|
|
2305
|
+
* Evaluate `where` clauses and { match } principals against the executing
|
|
2306
|
+
* scope's state, the subject, and the action input. Requires authGroups.
|
|
2393
2307
|
*/
|
|
2394
|
-
|
|
2308
|
+
authConditions: boolean;
|
|
2309
|
+
};
|
|
2310
|
+
/**
|
|
2311
|
+
* Configuration options for the job executor
|
|
2312
|
+
*/
|
|
2313
|
+
type JobExecutorConfig = {
|
|
2314
|
+
/** Feature flags; anything unset is off. */featureFlags?: Partial<ReactorFeatureFlags>; /** Maximum number of conflicting operations to skip when reshuffling. */
|
|
2315
|
+
maxSkipThreshold?: number; /** Maximum number of concurrent jobs to execute */
|
|
2316
|
+
maxConcurrency?: number; /** Maximum time in milliseconds a job can run before being considered timed out */
|
|
2317
|
+
jobTimeoutMs?: number;
|
|
2318
|
+
/** How long a job whose document is missing waits for it before failing.
|
|
2319
|
+
* Unbounded deferral never resolves the caller awaiting the job. */
|
|
2320
|
+
deferredJobTtlMs?: number; /** Base delay in milliseconds for exponential backoff retries */
|
|
2321
|
+
retryBaseDelayMs?: number; /** Maximum delay in milliseconds for exponential backoff retries */
|
|
2322
|
+
retryMaxDelayMs?: number;
|
|
2323
|
+
/** Maximum elapsed milliseconds before yielding to the main thread between actions.
|
|
2324
|
+
* Keeps the UI responsive when processing large batches. */
|
|
2325
|
+
yieldDeadlineMs?: number;
|
|
2395
2326
|
/**
|
|
2396
|
-
*
|
|
2327
|
+
* Persist a job's writes in one store transaction rather than one each.
|
|
2397
2328
|
*
|
|
2398
|
-
*
|
|
2399
|
-
*
|
|
2400
|
-
*
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
* Waits for a job to complete
|
|
2329
|
+
* On by default. A job's operations are reduced sequentially either way; this
|
|
2330
|
+
* only changes how many apply calls carry them, which is one advisory lock
|
|
2331
|
+
* and one guarded insert per batch instead of per operation. Only runs that
|
|
2332
|
+
* qualify are batched, and the executor falls back per write for the rest, so
|
|
2333
|
+
* this never changes which operations are produced -- only how many
|
|
2334
|
+
* transactions they arrive in.
|
|
2405
2335
|
*
|
|
2406
|
-
*
|
|
2407
|
-
*
|
|
2408
|
-
*
|
|
2336
|
+
* Atomicity is not one of the things it changes. A job either fully applies
|
|
2337
|
+
* or leaves nothing durable behind regardless of this setting, because the
|
|
2338
|
+
* whole job runs inside the execution scope's transaction and a failure
|
|
2339
|
+
* rolls it back.
|
|
2340
|
+
* That guarantee belongs to KyselyExecutionScope, which backs both Postgres
|
|
2341
|
+
* and PGlite; DefaultExecutionScope opens no transaction and is used only by
|
|
2342
|
+
* unit-test harnesses, which therefore see writes survive a failed job.
|
|
2409
2343
|
*/
|
|
2410
|
-
|
|
2344
|
+
batchApplies?: boolean; /** Defaults to `enforce`; `log` counts refusals and admits the write. */
|
|
2345
|
+
signatureVerification?: SignatureVerificationMode;
|
|
2346
|
+
};
|
|
2347
|
+
/**
|
|
2348
|
+
* Event types for the job executor
|
|
2349
|
+
*/
|
|
2350
|
+
declare const JobExecutorEventTypes: {
|
|
2351
|
+
readonly JOB_STARTED: 20000;
|
|
2352
|
+
readonly JOB_COMPLETED: 20001;
|
|
2353
|
+
readonly JOB_FAILED: 20002;
|
|
2354
|
+
readonly EXECUTOR_STARTED: 20003;
|
|
2355
|
+
readonly EXECUTOR_STOPPED: 20004;
|
|
2356
|
+
};
|
|
2357
|
+
/**
|
|
2358
|
+
* Event data for job execution events
|
|
2359
|
+
*/
|
|
2360
|
+
type JobStartedEvent = {
|
|
2361
|
+
job: Job;
|
|
2362
|
+
startedAt: string;
|
|
2411
2363
|
/**
|
|
2412
|
-
*
|
|
2413
|
-
*
|
|
2414
|
-
*
|
|
2415
|
-
*
|
|
2416
|
-
* @param view - Optional filter containing branch and scopes information
|
|
2417
|
-
* @returns A function that unsubscribes from the changes
|
|
2364
|
+
* Identifier of the executor that took the job. For the worker pool this is
|
|
2365
|
+
* the thread-worker id (e.g. "reactor-worker-3"); for the in-process simple
|
|
2366
|
+
* manager it is "in-process-<index>". Optional for backwards compatibility
|
|
2367
|
+
* with consumers built before the field was added.
|
|
2418
2368
|
*/
|
|
2419
|
-
|
|
2420
|
-
}
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2369
|
+
workerId?: string;
|
|
2370
|
+
};
|
|
2371
|
+
type JobCompletedEvent = {
|
|
2372
|
+
job: Job;
|
|
2373
|
+
result: JobResult; /** See {@link JobStartedEvent.workerId}. */
|
|
2374
|
+
workerId?: string;
|
|
2375
|
+
};
|
|
2376
|
+
type JobFailedEvent = {
|
|
2377
|
+
job: Job;
|
|
2378
|
+
error: string;
|
|
2379
|
+
willRetry: boolean;
|
|
2380
|
+
retryCount: number; /** See {@link JobStartedEvent.workerId}. */
|
|
2381
|
+
workerId?: string;
|
|
2382
|
+
};
|
|
2383
|
+
type ExecutorStartedEvent = {
|
|
2384
|
+
config: JobExecutorConfig;
|
|
2385
|
+
startedAt: string;
|
|
2386
|
+
};
|
|
2387
|
+
type ExecutorStoppedEvent = {
|
|
2388
|
+
stoppedAt: string;
|
|
2389
|
+
graceful: boolean;
|
|
2390
|
+
};
|
|
2391
|
+
/**
|
|
2392
|
+
* Status information for the job executor manager
|
|
2393
|
+
*/
|
|
2394
|
+
type ExecutorManagerStatus = {
|
|
2395
|
+
/** Whether the manager is currently running */isRunning: boolean; /** Number of executor instances managed */
|
|
2396
|
+
numExecutors: number; /** Number of jobs currently being processed */
|
|
2397
|
+
activeJobs: number; /** Total number of jobs processed since start */
|
|
2398
|
+
totalJobsProcessed: number;
|
|
2399
|
+
};
|
|
2427
2400
|
//#endregion
|
|
2428
|
-
//#region src/
|
|
2401
|
+
//#region src/executor/worker/protocol.d.ts
|
|
2429
2402
|
/**
|
|
2430
|
-
*
|
|
2403
|
+
* A JSON-clonable value safe to send across the worker IPC boundary.
|
|
2431
2404
|
*
|
|
2432
|
-
*
|
|
2433
|
-
*
|
|
2434
|
-
*
|
|
2405
|
+
* The shape mirrors the structured-clone subset used by the parent's
|
|
2406
|
+
* sanitizer: primitives, arrays, plain objects, plus the explicit
|
|
2407
|
+
* {@link ErrorInfo} shape for marshalled Errors.
|
|
2408
|
+
*
|
|
2409
|
+
* @see Wire Protocol Reference wiki page
|
|
2410
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2435
2411
|
*/
|
|
2436
|
-
type
|
|
2437
|
-
|
|
2438
|
-
* The full PHDocumentState from document.state.document.
|
|
2439
|
-
* Contains version, hash, isDeleted, deletedAtUtcIso, etc.
|
|
2440
|
-
*/
|
|
2441
|
-
state: PHDocumentState;
|
|
2442
|
-
/**
|
|
2443
|
-
* The document type (from header), cached for convenience.
|
|
2444
|
-
*/
|
|
2445
|
-
documentType: string;
|
|
2446
|
-
/**
|
|
2447
|
-
* The revision of the document scope when this metadata was captured.
|
|
2448
|
-
* Used for cache invalidation and consistency checks.
|
|
2449
|
-
*/
|
|
2450
|
-
documentScopeRevision: number;
|
|
2412
|
+
type SanitizedArg = null | boolean | number | string | ErrorInfo | SanitizedArg[] | {
|
|
2413
|
+
[key: string]: SanitizedArg;
|
|
2451
2414
|
};
|
|
2452
2415
|
/**
|
|
2453
|
-
*
|
|
2416
|
+
* Structured representation of an Error for IPC transport.
|
|
2454
2417
|
*
|
|
2455
|
-
*
|
|
2456
|
-
*
|
|
2457
|
-
*
|
|
2458
|
-
* which may be stale in scope-specific caches or keyframes.
|
|
2418
|
+
* Class instances cannot be structured-cloned across worker boundaries,
|
|
2419
|
+
* so Errors are flattened into this shape on the worker side and
|
|
2420
|
+
* reconstructed on the parent side.
|
|
2459
2421
|
*
|
|
2460
|
-
*
|
|
2461
|
-
*
|
|
2462
|
-
* - Historical metadata reconstruction for reshuffling scenarios
|
|
2463
|
-
* - Eager updates after document scope operations
|
|
2422
|
+
* @see Wire Protocol Reference wiki page
|
|
2423
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2464
2424
|
*/
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
/**
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2425
|
+
type ErrorInfo = {
|
|
2426
|
+
name: string;
|
|
2427
|
+
message: string;
|
|
2428
|
+
stack?: string;
|
|
2429
|
+
cause?: ErrorInfo;
|
|
2430
|
+
};
|
|
2431
|
+
/**
|
|
2432
|
+
* Reference to a module that the worker should `import()` at runtime,
|
|
2433
|
+
* along with the named export to pluck out as the factory.
|
|
2434
|
+
*
|
|
2435
|
+
* Exactly one of `packageName` or `filePath` is provided.
|
|
2436
|
+
*
|
|
2437
|
+
* @see Wire Protocol Reference wiki page
|
|
2438
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2439
|
+
*/
|
|
2440
|
+
type ModuleRef = {
|
|
2441
|
+
/** Bare-specifier package name (resolved by the worker's module loader). */packageName: string; /** Named export within the module to invoke as the factory. */
|
|
2442
|
+
exportName: string;
|
|
2443
|
+
} | {
|
|
2444
|
+
/** Absolute or worker-resolvable file path to import. */filePath: string; /** Named export within the module to invoke as the factory. */
|
|
2445
|
+
exportName: string;
|
|
2446
|
+
};
|
|
2447
|
+
/**
|
|
2448
|
+
* Factory specification shared by the signer, trust policy and document
|
|
2449
|
+
* model spec channels. The worker imports `module.exportName` and invokes
|
|
2450
|
+
* it with `initArgs` to obtain the actual instance.
|
|
2451
|
+
*
|
|
2452
|
+
* `initArgs` must be JSON-clonable.
|
|
2453
|
+
*
|
|
2454
|
+
* @see Wire Protocol Reference wiki page
|
|
2455
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2456
|
+
*/
|
|
2457
|
+
type FactorySpec = {
|
|
2458
|
+
module: ModuleRef;
|
|
2459
|
+
initArgs?: SanitizedArg;
|
|
2460
|
+
};
|
|
2461
|
+
/**
|
|
2462
|
+
* Factory spec for a document model module the worker should instantiate.
|
|
2463
|
+
*
|
|
2464
|
+
* Structurally identical to {@link FactorySpec}; the alias exists so call
|
|
2465
|
+
* sites read intent-fully.
|
|
2466
|
+
*
|
|
2467
|
+
* @see Wire Protocol Reference wiki page
|
|
2468
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2469
|
+
*/
|
|
2470
|
+
type DocumentModelSpec = FactorySpec;
|
|
2471
|
+
/**
|
|
2472
|
+
* One entry in the document model manifest the worker materializes on
|
|
2473
|
+
* startup (or extends lazily via `load-model`).
|
|
2474
|
+
*
|
|
2475
|
+
* @see Wire Protocol Reference wiki page
|
|
2476
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2477
|
+
*/
|
|
2478
|
+
type ModelManifestEntry = {
|
|
2479
|
+
/** Document type identifier (e.g. "ph/account"). */documentType: string; /** Document model version this entry registers. */
|
|
2480
|
+
version: string; /** Factory spec the worker imports and invokes to obtain the model. */
|
|
2481
|
+
spec: DocumentModelSpec;
|
|
2482
|
+
};
|
|
2483
|
+
/**
|
|
2484
|
+
* JSON-clonable Postgres connection info passed to the worker so it can
|
|
2485
|
+
* open its own pool. Storage-specific wiring may extend this shape in
|
|
2486
|
+
* later phases.
|
|
2487
|
+
*
|
|
2488
|
+
* @see Wire Protocol Reference wiki page
|
|
2489
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2490
|
+
*/
|
|
2491
|
+
type DbConfig = {
|
|
2492
|
+
host: string;
|
|
2493
|
+
port: number;
|
|
2494
|
+
database: string;
|
|
2495
|
+
user: string;
|
|
2496
|
+
password: string;
|
|
2497
|
+
ssl?: boolean;
|
|
2498
|
+
applicationName?: string;
|
|
2499
|
+
poolSize?: number;
|
|
2522
2500
|
/**
|
|
2523
|
-
*
|
|
2501
|
+
* Maximum time (ms) a caller will wait to acquire a connection from the
|
|
2502
|
+
* pool before pg.Pool throws. When omitted, pg defaults to 0 (unlimited
|
|
2503
|
+
* wait), which hides acquire-starvation as silent latency.
|
|
2524
2504
|
*/
|
|
2525
|
-
|
|
2505
|
+
connectionTimeoutMillis?: number;
|
|
2526
2506
|
/**
|
|
2527
|
-
*
|
|
2507
|
+
* How long (ms) an idle connection stays open before pg closes it. When
|
|
2508
|
+
* omitted, pg defaults to 10000.
|
|
2528
2509
|
*/
|
|
2529
|
-
|
|
2530
|
-
}
|
|
2531
|
-
//#endregion
|
|
2532
|
-
//#region src/storage/kysely/types.d.ts
|
|
2533
|
-
interface OperationTable {
|
|
2534
|
-
id: Generated<number>;
|
|
2535
|
-
jobId: string;
|
|
2536
|
-
opId: string;
|
|
2537
|
-
prevOpId: string;
|
|
2538
|
-
writeTimestampUtcMs: Generated<Date>;
|
|
2539
|
-
documentId: string;
|
|
2540
|
-
documentType: string;
|
|
2541
|
-
scope: string;
|
|
2542
|
-
branch: string;
|
|
2543
|
-
timestampUtcMs: Date;
|
|
2544
|
-
index: number;
|
|
2545
|
-
action: unknown;
|
|
2546
|
-
skip: number;
|
|
2547
|
-
error?: string | null;
|
|
2548
|
-
deniedReason?: string | null;
|
|
2549
|
-
hash: string;
|
|
2550
|
-
}
|
|
2551
|
-
interface KeyframeTable {
|
|
2552
|
-
id: Generated<number>;
|
|
2553
|
-
documentId: string;
|
|
2554
|
-
documentType: string;
|
|
2555
|
-
scope: string;
|
|
2556
|
-
branch: string;
|
|
2557
|
-
revision: number;
|
|
2558
|
-
document: unknown;
|
|
2559
|
-
createdAt: Generated<Date>;
|
|
2560
|
-
}
|
|
2561
|
-
interface DocumentCollectionTable {
|
|
2562
|
-
documentId: string;
|
|
2563
|
-
collectionId: string;
|
|
2564
|
-
joinedOrdinal: bigint;
|
|
2565
|
-
leftOrdinal: bigint | null;
|
|
2566
|
-
}
|
|
2567
|
-
interface OperationIndexOperationTable {
|
|
2568
|
-
ordinal: Generated<number>;
|
|
2569
|
-
opId: string;
|
|
2570
|
-
documentId: string;
|
|
2571
|
-
documentType: string;
|
|
2572
|
-
scope: string;
|
|
2573
|
-
branch: string;
|
|
2574
|
-
timestampUtcMs: string;
|
|
2575
|
-
writeTimestampUtcMs: Generated<Date>;
|
|
2576
|
-
index: number;
|
|
2577
|
-
skip: number;
|
|
2578
|
-
hash: string;
|
|
2579
|
-
action: unknown;
|
|
2580
|
-
deniedReason?: string | null;
|
|
2581
|
-
sourceRemote: Generated<string>;
|
|
2582
|
-
}
|
|
2583
|
-
interface SyncRemoteTable {
|
|
2584
|
-
name: string;
|
|
2585
|
-
collection_id: string;
|
|
2586
|
-
channel_type: string;
|
|
2587
|
-
channel_id: string;
|
|
2588
|
-
remote_name: string;
|
|
2589
|
-
channel_parameters: unknown;
|
|
2590
|
-
filter_document_ids: unknown;
|
|
2591
|
-
filter_scopes: unknown;
|
|
2592
|
-
filter_branch: string;
|
|
2593
|
-
push_state: string;
|
|
2594
|
-
push_last_success_utc_ms: string | null;
|
|
2595
|
-
push_last_failure_utc_ms: string | null;
|
|
2596
|
-
push_failure_count: number;
|
|
2597
|
-
pull_state: string;
|
|
2598
|
-
pull_last_success_utc_ms: string | null;
|
|
2599
|
-
pull_last_failure_utc_ms: string | null;
|
|
2600
|
-
pull_failure_count: number;
|
|
2601
|
-
bound_address: string | null;
|
|
2602
|
-
created_at: Generated<Date>;
|
|
2603
|
-
updated_at: Generated<Date>;
|
|
2604
|
-
}
|
|
2605
|
-
interface SyncCursorTable {
|
|
2606
|
-
remote_name: string;
|
|
2607
|
-
cursor_type: string;
|
|
2608
|
-
cursor_ordinal: bigint;
|
|
2609
|
-
last_synced_at_utc_ms: string | null;
|
|
2610
|
-
updated_at: Generated<Date>;
|
|
2611
|
-
}
|
|
2510
|
+
idleTimeoutMillis?: number;
|
|
2511
|
+
};
|
|
2612
2512
|
/**
|
|
2613
|
-
*
|
|
2513
|
+
* Configuration for the executor worker pool.
|
|
2514
|
+
*
|
|
2515
|
+
* Mirrors the `workerPool` sub-config on {@link JobExecutorConfig};
|
|
2516
|
+
* a later card wires this into the executor config.
|
|
2517
|
+
*
|
|
2518
|
+
* @see Wire Protocol Reference wiki page
|
|
2519
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2614
2520
|
*/
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
scopes: unknown;
|
|
2623
|
-
branch: string;
|
|
2624
|
-
operations: unknown;
|
|
2625
|
-
error_source: string;
|
|
2626
|
-
error_message: string;
|
|
2627
|
-
error_type: Generated<string>;
|
|
2628
|
-
created_at: Generated<Date>;
|
|
2629
|
-
}
|
|
2521
|
+
type WorkerPoolConfig = {
|
|
2522
|
+
/** Whether the worker pool is active; when false the executor runs in-process. */enabled: boolean; /** Number of worker instances to spawn. */
|
|
2523
|
+
numWorkers: number; /** Worker isolation mode. */
|
|
2524
|
+
workerType: "thread" | "process"; /** Optional heartbeat interval in milliseconds. */
|
|
2525
|
+
heartbeatMs?: number; /** Optional per-worker Postgres pool size override. */
|
|
2526
|
+
workerPgPoolSize?: number;
|
|
2527
|
+
};
|
|
2630
2528
|
/**
|
|
2631
|
-
*
|
|
2632
|
-
*
|
|
2529
|
+
* Payload the worker reports back when a job's write phase is complete.
|
|
2530
|
+
*
|
|
2531
|
+
* Parent fills `collectionMemberships` at emission time, so it is
|
|
2532
|
+
* intentionally absent from the worker -> parent message.
|
|
2533
|
+
*
|
|
2534
|
+
* @see Wire Protocol Reference wiki page
|
|
2535
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2633
2536
|
*/
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
}
|
|
2638
|
-
interface Database$1 {
|
|
2639
|
-
Operation: OperationTable;
|
|
2640
|
-
Keyframe: KeyframeTable;
|
|
2641
|
-
document_collections: DocumentCollectionTable;
|
|
2642
|
-
operation_index_operations: OperationIndexOperationTable;
|
|
2643
|
-
group_references: GroupReferenceTable;
|
|
2644
|
-
sync_remotes: SyncRemoteTable;
|
|
2645
|
-
sync_cursors: SyncCursorTable;
|
|
2646
|
-
sync_dead_letters: SyncDeadLetterTable;
|
|
2647
|
-
}
|
|
2648
|
-
interface DocumentTable {
|
|
2649
|
-
id: string;
|
|
2650
|
-
createdAt: Generated<Date>;
|
|
2651
|
-
updatedAt: Generated<Date>;
|
|
2652
|
-
}
|
|
2653
|
-
interface DocumentRelationshipTable {
|
|
2654
|
-
id: Generated<string>;
|
|
2655
|
-
sourceId: string;
|
|
2656
|
-
targetId: string;
|
|
2657
|
-
relationshipType: string;
|
|
2658
|
-
metadata: unknown;
|
|
2659
|
-
createdAt: Generated<Date>;
|
|
2660
|
-
updatedAt: Generated<Date>;
|
|
2661
|
-
}
|
|
2662
|
-
interface IndexerStateTable {
|
|
2663
|
-
id: Generated<number>;
|
|
2664
|
-
lastOperationId: number;
|
|
2665
|
-
lastOperationTimestamp: Generated<Date>;
|
|
2666
|
-
}
|
|
2667
|
-
interface DocumentIndexerDatabase {
|
|
2668
|
-
Document: DocumentTable;
|
|
2669
|
-
DocumentRelationship: DocumentRelationshipTable;
|
|
2670
|
-
IndexerState: IndexerStateTable;
|
|
2671
|
-
}
|
|
2672
|
-
//#endregion
|
|
2673
|
-
//#region src/executor/worker/protocol.d.ts
|
|
2537
|
+
type JobWriteReadyPayload = {
|
|
2538
|
+
operations: OperationWithContext$1[];
|
|
2539
|
+
jobMeta: JobMeta;
|
|
2540
|
+
};
|
|
2674
2541
|
/**
|
|
2675
|
-
*
|
|
2542
|
+
* Initializes a freshly spawned worker with the configuration and
|
|
2543
|
+
* factories it needs to start executing jobs.
|
|
2676
2544
|
*
|
|
2677
|
-
*
|
|
2678
|
-
*
|
|
2679
|
-
|
|
2545
|
+
* @see Wire Protocol Reference wiki page
|
|
2546
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2547
|
+
*/
|
|
2548
|
+
type InitMessage = {
|
|
2549
|
+
type: "init";
|
|
2550
|
+
correlationId: string;
|
|
2551
|
+
workerId: string;
|
|
2552
|
+
poolConfig: WorkerPoolConfig;
|
|
2553
|
+
db: DbConfig;
|
|
2554
|
+
models: ModelManifestEntry[]; /** Omitted = the worker builds its executor with the built-in defaults. */
|
|
2555
|
+
executorConfig?: JobExecutorConfig; /** Builds the `ISigner` for synthesized operations; omitted = unsigned. */
|
|
2556
|
+
signer?: FactorySpec; /** Builds the `SignatureTrustPolicy`; omitted = the default. */
|
|
2557
|
+
trustPolicy?: FactorySpec;
|
|
2558
|
+
};
|
|
2559
|
+
/**
|
|
2560
|
+
* Dispatches a job to the worker for execution.
|
|
2680
2561
|
*
|
|
2681
2562
|
* @see Wire Protocol Reference wiki page
|
|
2682
2563
|
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2683
2564
|
*/
|
|
2684
|
-
type
|
|
2685
|
-
|
|
2565
|
+
type ExecuteMessage = {
|
|
2566
|
+
type: "execute";
|
|
2567
|
+
correlationId: string;
|
|
2568
|
+
job: Job;
|
|
2686
2569
|
};
|
|
2687
2570
|
/**
|
|
2688
|
-
*
|
|
2571
|
+
* Requests cancellation of an in-flight job.
|
|
2689
2572
|
*
|
|
2690
|
-
*
|
|
2691
|
-
*
|
|
2692
|
-
|
|
2573
|
+
* @see Wire Protocol Reference wiki page
|
|
2574
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2575
|
+
*/
|
|
2576
|
+
type AbortMessage = {
|
|
2577
|
+
type: "abort";
|
|
2578
|
+
correlationId: string; /** correlationId of the `execute` message being aborted. */
|
|
2579
|
+
targetCorrelationId: string;
|
|
2580
|
+
reason?: string;
|
|
2581
|
+
};
|
|
2582
|
+
/**
|
|
2583
|
+
* Asks the worker to drain in-flight work and exit.
|
|
2693
2584
|
*
|
|
2694
2585
|
* @see Wire Protocol Reference wiki page
|
|
2695
2586
|
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2696
2587
|
*/
|
|
2697
|
-
type
|
|
2698
|
-
|
|
2588
|
+
type ShutdownMessage = {
|
|
2589
|
+
type: "shutdown";
|
|
2590
|
+
correlationId: string; /** Optional grace period before the parent force-terminates the worker. */
|
|
2591
|
+
graceMs?: number;
|
|
2592
|
+
};
|
|
2593
|
+
/**
|
|
2594
|
+
* Lazily registers an additional document model on a running worker.
|
|
2595
|
+
*
|
|
2596
|
+
* @see Wire Protocol Reference wiki page
|
|
2597
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2598
|
+
*/
|
|
2599
|
+
type LoadModelMessage = {
|
|
2600
|
+
type: "load-model";
|
|
2601
|
+
correlationId: string;
|
|
2602
|
+
model: ModelManifestEntry;
|
|
2603
|
+
};
|
|
2604
|
+
/**
|
|
2605
|
+
* Union of all messages the parent may send to a worker.
|
|
2606
|
+
*
|
|
2607
|
+
* @see Wire Protocol Reference wiki page
|
|
2608
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2609
|
+
*/
|
|
2610
|
+
type ParentMessage = InitMessage | ExecuteMessage | AbortMessage | ShutdownMessage | LoadModelMessage;
|
|
2611
|
+
/**
|
|
2612
|
+
* Announces that the worker has finished `init` and is ready to accept
|
|
2613
|
+
* `execute` messages.
|
|
2614
|
+
*
|
|
2615
|
+
* @see Wire Protocol Reference wiki page
|
|
2616
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2617
|
+
*/
|
|
2618
|
+
type ReadyMessage = {
|
|
2619
|
+
type: "ready"; /** correlationId of the originating `init` message. */
|
|
2620
|
+
correlationId: string;
|
|
2621
|
+
workerId: string;
|
|
2622
|
+
};
|
|
2623
|
+
/**
|
|
2624
|
+
* Final result for an `execute` job.
|
|
2625
|
+
*
|
|
2626
|
+
* On success, `writeReady` carries the operations and job meta the
|
|
2627
|
+
* parent needs to emit `JOB_WRITE_READY`. On failure, `error` is set
|
|
2628
|
+
* and `result.success` is false.
|
|
2629
|
+
*
|
|
2630
|
+
* @see Wire Protocol Reference wiki page
|
|
2631
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2632
|
+
*/
|
|
2633
|
+
type ResultMessage = {
|
|
2634
|
+
type: "result"; /** correlationId of the originating `execute` message. */
|
|
2635
|
+
correlationId: string;
|
|
2636
|
+
result: JobResult;
|
|
2637
|
+
writeReady?: JobWriteReadyPayload; /** Re-emitted on the parent bus, which is where observers subscribe. */
|
|
2638
|
+
signatureRefusals?: SignatureRefusedEvent[];
|
|
2639
|
+
error?: ErrorInfo;
|
|
2640
|
+
};
|
|
2641
|
+
/**
|
|
2642
|
+
* Acknowledges that a `load-model` request succeeded.
|
|
2643
|
+
*
|
|
2644
|
+
* @see Wire Protocol Reference wiki page
|
|
2645
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2646
|
+
*/
|
|
2647
|
+
type ModelLoadedMessage = {
|
|
2648
|
+
type: "model-loaded"; /** correlationId of the originating `load-model` message. */
|
|
2649
|
+
correlationId: string;
|
|
2650
|
+
documentType: string;
|
|
2651
|
+
version: string;
|
|
2652
|
+
};
|
|
2653
|
+
/**
|
|
2654
|
+
* Reports that a `load-model` request failed.
|
|
2655
|
+
*
|
|
2656
|
+
* @see Wire Protocol Reference wiki page
|
|
2657
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2658
|
+
*/
|
|
2659
|
+
type ModelLoadFailedMessage = {
|
|
2660
|
+
type: "model-load-failed"; /** correlationId of the originating `load-model` message. */
|
|
2661
|
+
correlationId: string;
|
|
2662
|
+
documentType: string;
|
|
2663
|
+
version: string;
|
|
2664
|
+
error: ErrorInfo;
|
|
2665
|
+
};
|
|
2666
|
+
/**
|
|
2667
|
+
* Forwarded log line from the worker. `args` is constrained to
|
|
2668
|
+
* {@link SanitizedArg} so callers cannot accidentally ship non-clonable
|
|
2669
|
+
* values across the boundary.
|
|
2670
|
+
*
|
|
2671
|
+
* The sanitizer in `./sanitize.ts` enforces the {@link SanitizedArg}
|
|
2672
|
+
* invariant on the producer side before each message is posted.
|
|
2673
|
+
*
|
|
2674
|
+
* @see Wire Protocol Reference wiki page
|
|
2675
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2676
|
+
*/
|
|
2677
|
+
type LogMessage = {
|
|
2678
|
+
type: "log";
|
|
2679
|
+
level: "debug" | "info" | "warn" | "error";
|
|
2699
2680
|
message: string;
|
|
2700
|
-
|
|
2701
|
-
|
|
2681
|
+
args: SanitizedArg[]; /** Epoch milliseconds at which the worker generated the log line. */
|
|
2682
|
+
timestamp: number;
|
|
2683
|
+
};
|
|
2684
|
+
/**
|
|
2685
|
+
* Periodic liveness signal. Included now to unblock Phase-3 scaffolding;
|
|
2686
|
+
* the wiki marks heartbeats as a Phase-5 future extension.
|
|
2687
|
+
*
|
|
2688
|
+
* @see Wire Protocol Reference wiki page
|
|
2689
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2690
|
+
*/
|
|
2691
|
+
type HeartbeatMessage = {
|
|
2692
|
+
type: "heartbeat";
|
|
2693
|
+
workerId: string; /** Epoch milliseconds the worker generated the heartbeat. */
|
|
2694
|
+
timestamp: number; /** Optional snapshot of in-flight job correlation ids. */
|
|
2695
|
+
inFlightCorrelationIds?: string[];
|
|
2696
|
+
};
|
|
2697
|
+
/**
|
|
2698
|
+
* Periodic counters / gauges the worker reports for observability.
|
|
2699
|
+
*
|
|
2700
|
+
* @see Wire Protocol Reference wiki page
|
|
2701
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2702
|
+
*/
|
|
2703
|
+
type MetricsMessage = {
|
|
2704
|
+
type: "metrics";
|
|
2705
|
+
workerId: string; /** Epoch milliseconds the worker generated the metrics snapshot. */
|
|
2706
|
+
timestamp: number;
|
|
2707
|
+
counters: {
|
|
2708
|
+
[name: string]: number;
|
|
2709
|
+
};
|
|
2710
|
+
gauges: {
|
|
2711
|
+
[name: string]: number;
|
|
2712
|
+
};
|
|
2713
|
+
};
|
|
2714
|
+
/**
|
|
2715
|
+
* Snapshot of one worker pool's acquire-wait samples and pool-stat counters,
|
|
2716
|
+
* forwarded periodically so the host can re-record into the shared
|
|
2717
|
+
* pg.Pool histogram and observable gauges. The worker owns the real
|
|
2718
|
+
* pg.Pool; the host's {@link PoolInstrumentation} is a forwarder driven
|
|
2719
|
+
* by these messages.
|
|
2720
|
+
*/
|
|
2721
|
+
type PoolAcquireSamplesMessage = {
|
|
2722
|
+
type: "pool-acquire-samples";
|
|
2723
|
+
workerId: string; /** Stable identifier matching the host-side instrumentation name (e.g. "worker-0"). */
|
|
2724
|
+
poolName: string; /** Epoch milliseconds the worker generated the batch. */
|
|
2725
|
+
timestamp: number; /** Acquire-wait durations (ms) accumulated since the previous batch. */
|
|
2726
|
+
durations: number[]; /** Most recent pg.Pool counter snapshot at batch send time. */
|
|
2727
|
+
size: number;
|
|
2728
|
+
idle: number;
|
|
2729
|
+
waiting: number;
|
|
2730
|
+
};
|
|
2731
|
+
/**
|
|
2732
|
+
* Union of all messages a worker may send to the parent.
|
|
2733
|
+
*
|
|
2734
|
+
* @see Wire Protocol Reference wiki page
|
|
2735
|
+
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2736
|
+
*/
|
|
2737
|
+
type WorkerMessage = ReadyMessage | ResultMessage | ModelLoadedMessage | ModelLoadFailedMessage | LogMessage | HeartbeatMessage | MetricsMessage | PoolAcquireSamplesMessage;
|
|
2738
|
+
//#endregion
|
|
2739
|
+
//#region src/signer/types.d.ts
|
|
2740
|
+
/** The signer a client signs with and the executor signs synthesized operations with. */
|
|
2741
|
+
type SignerConfig = {
|
|
2742
|
+
/**
|
|
2743
|
+
* The signer used to sign actions before submission.
|
|
2744
|
+
*/
|
|
2745
|
+
signer: ISigner;
|
|
2746
|
+
/**
|
|
2747
|
+
* What a pooled executor worker imports to build the same signer, which
|
|
2748
|
+
* cannot cross the thread boundary itself. Omitted = pooled workers store
|
|
2749
|
+
* synthesized operations unsigned.
|
|
2750
|
+
*/
|
|
2751
|
+
workerSigner?: FactorySpec; /** Decides which keys may sign as which users; see {@link SignatureTrustPolicy}. */
|
|
2752
|
+
trustPolicy?: SignatureTrustPolicy;
|
|
2753
|
+
/**
|
|
2754
|
+
* What a pooled executor worker imports to build the same trust policy.
|
|
2755
|
+
* Omitted = pooled workers apply the default.
|
|
2756
|
+
*/
|
|
2757
|
+
workerTrustPolicy?: FactorySpec;
|
|
2702
2758
|
};
|
|
2703
2759
|
/**
|
|
2704
|
-
*
|
|
2705
|
-
*
|
|
2760
|
+
* The host's answer to whether `key` may sign as `signer.user`. The reactor has
|
|
2761
|
+
* already proven that `key` made the signature over this action in this
|
|
2762
|
+
* document.
|
|
2706
2763
|
*
|
|
2707
|
-
*
|
|
2764
|
+
* Asked once per signed write at admission, never on a re-append, and never for
|
|
2765
|
+
* an unsigned action. `false` refuses the write as `SIGNER_UNAUTHORIZED`. A
|
|
2766
|
+
* throw is a job error: the job is retried and nothing is dropped, so a
|
|
2767
|
+
* transient failure must throw rather than answer `false`.
|
|
2708
2768
|
*
|
|
2709
|
-
*
|
|
2710
|
-
*
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2769
|
+
* The answer may not depend on when it is asked: replicas admit the same write
|
|
2770
|
+
* at different times and must reach the same verdict. Cache an acceptance and
|
|
2771
|
+
* never expire it.
|
|
2772
|
+
*
|
|
2773
|
+
* Key a cache on (`signer.user`, `key`) only. The reactor's own key signing as
|
|
2774
|
+
* its current user is accepted before the policy is asked, read live on every
|
|
2775
|
+
* ask, and never cached. Invalidate nothing when the local identity changes:
|
|
2776
|
+
* other users' verdicts do not depend on it. Without a policy, a signed write
|
|
2777
|
+
* is refused under `authEnforcement` and accepted otherwise.
|
|
2778
|
+
*/
|
|
2779
|
+
type SignatureTrustPolicy = {
|
|
2780
|
+
authorizeSigner(signer: ActionSigner, key: string, documentId: string): Promise<boolean>;
|
|
2781
|
+
};
|
|
2782
|
+
/** `log` counts refusals and admits anyway; `enforce` refuses. */
|
|
2783
|
+
type SignatureVerificationMode = "log" | "enforce";
|
|
2784
|
+
declare const SIGNATURE_REFUSAL_CODES: readonly ["UNSIGNED_REQUIRED", "UNSIGNED_IDENTITY", "KEY_MISMATCH", "MALFORMED_TUPLE", "TIMESTAMP_MISMATCH", "HASH_MISMATCH", "BAD_SIGNATURE", "SCHEME_BELOW_POLICY", "ID_MISMATCH", "DUPLICATE_ACTION", "SIGNER_UNAUTHORIZED"];
|
|
2785
|
+
type SignatureRefusalCode = (typeof SIGNATURE_REFUSAL_CODES)[number];
|
|
2786
|
+
/** Read from the prefix or length of tuple[2]. */
|
|
2787
|
+
type SignatureScheme = "unsigned" | "v2" | "legacy-renown" | "legacy-shared" | "legacy-unknown";
|
|
2788
|
+
/** Where this reactor first stores the write. */
|
|
2789
|
+
type AdmissionPath = "mutation" | "load";
|
|
2790
|
+
type SignatureVerdict = {
|
|
2791
|
+
ok: true;
|
|
2792
|
+
scheme: SignatureScheme;
|
|
2715
2793
|
} | {
|
|
2716
|
-
|
|
2717
|
-
|
|
2794
|
+
ok: false;
|
|
2795
|
+
scheme: SignatureScheme;
|
|
2796
|
+
code: SignatureRefusalCode;
|
|
2797
|
+
reason: string;
|
|
2718
2798
|
};
|
|
2799
|
+
//#endregion
|
|
2800
|
+
//#region src/events/types.d.ts
|
|
2719
2801
|
/**
|
|
2720
|
-
*
|
|
2721
|
-
|
|
2722
|
-
|
|
2802
|
+
* Describes a function to unsubscribe from an event.
|
|
2803
|
+
*/
|
|
2804
|
+
type Unsubscribe = () => void;
|
|
2805
|
+
/**
|
|
2806
|
+
* A subscriber is a function that is called when an event is emitted.
|
|
2723
2807
|
*
|
|
2724
|
-
*
|
|
2808
|
+
* It is passed the event type and the data.
|
|
2809
|
+
* It can return a promise or a value.
|
|
2810
|
+
* If it returns a promise, the event bus will wait for the promise to resolve before calling the next subscriber.
|
|
2811
|
+
* If it throws an error, the event bus will reject with an aggregate error of all errors.
|
|
2725
2812
|
*
|
|
2726
|
-
* @
|
|
2727
|
-
*
|
|
2813
|
+
* @param type - The type of event to emit.
|
|
2814
|
+
* @param data - The data to pass to the subscriber.
|
|
2728
2815
|
*/
|
|
2729
|
-
type
|
|
2730
|
-
|
|
2731
|
-
|
|
2816
|
+
type Subscriber = (type: number, data: any) => void | Promise<void>;
|
|
2817
|
+
/**
|
|
2818
|
+
* Custom error class that aggregates multiple errors from event subscribers.
|
|
2819
|
+
*/
|
|
2820
|
+
declare class EventBusAggregateError extends Error {
|
|
2821
|
+
readonly errors: any[];
|
|
2822
|
+
constructor(errors: unknown[]);
|
|
2823
|
+
}
|
|
2824
|
+
/**
|
|
2825
|
+
* Event types for reactor lifecycle events.
|
|
2826
|
+
*/
|
|
2827
|
+
declare const ReactorEventTypes: {
|
|
2828
|
+
readonly JOB_PENDING: 10001;
|
|
2829
|
+
readonly JOB_RUNNING: 10002;
|
|
2830
|
+
readonly JOB_WRITE_READY: 10003;
|
|
2831
|
+
readonly JOB_READ_READY: 10004;
|
|
2832
|
+
readonly JOB_FAILED: 10005;
|
|
2833
|
+
readonly READMODEL_BATCH_COMPLETED: 10006;
|
|
2834
|
+
readonly READMODEL_INDEXED: 10007;
|
|
2835
|
+
readonly MODEL_LOADED: 10008;
|
|
2836
|
+
readonly SIGNATURE_REFUSED: 10009;
|
|
2732
2837
|
};
|
|
2733
2838
|
/**
|
|
2734
|
-
*
|
|
2735
|
-
*
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
*
|
|
2740
|
-
*
|
|
2839
|
+
* Stage within ReadModelCoordinator.runChain. Used as a dimension on
|
|
2840
|
+
* stage-attribution events and histograms.
|
|
2841
|
+
*/
|
|
2842
|
+
type ReadModelStage = "pre_ready" | "emit" | "post_ready";
|
|
2843
|
+
/**
|
|
2844
|
+
* Stage in which an individual read model ran. The emit stage does not
|
|
2845
|
+
* involve a read model so it is excluded from this discriminant.
|
|
2741
2846
|
*/
|
|
2742
|
-
type
|
|
2847
|
+
type ReadModelIndexingStage = "pre_ready" | "post_ready";
|
|
2743
2848
|
/**
|
|
2744
|
-
*
|
|
2745
|
-
*
|
|
2746
|
-
* Structurally identical to {@link FactorySpec}; the alias exists so call
|
|
2747
|
-
* sites read intent-fully.
|
|
2748
|
-
*
|
|
2749
|
-
* @see Wire Protocol Reference wiki page
|
|
2750
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2849
|
+
* Emitted after the resolver loads a model on demand, so peers load it too.
|
|
2751
2850
|
*/
|
|
2752
|
-
type
|
|
2851
|
+
type ModelLoadedEvent = {
|
|
2852
|
+
documentType: string;
|
|
2853
|
+
};
|
|
2753
2854
|
/**
|
|
2754
|
-
*
|
|
2755
|
-
* startup (or extends lazily via `load-model`).
|
|
2756
|
-
*
|
|
2757
|
-
* @see Wire Protocol Reference wiki page
|
|
2758
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2855
|
+
* Event emitted when a job is registered and waiting to be executed.
|
|
2759
2856
|
*/
|
|
2760
|
-
type
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
spec: DocumentModelSpec;
|
|
2857
|
+
type JobPendingEvent = {
|
|
2858
|
+
jobId: string;
|
|
2859
|
+
jobMeta: JobMeta;
|
|
2764
2860
|
};
|
|
2765
2861
|
/**
|
|
2766
|
-
*
|
|
2767
|
-
* open its own pool. Storage-specific wiring may extend this shape in
|
|
2768
|
-
* later phases.
|
|
2769
|
-
*
|
|
2770
|
-
* @see Wire Protocol Reference wiki page
|
|
2771
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2862
|
+
* Event emitted when a job starts executing.
|
|
2772
2863
|
*/
|
|
2773
|
-
type
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2864
|
+
type JobRunningEvent = {
|
|
2865
|
+
jobId: string;
|
|
2866
|
+
jobMeta: JobMeta;
|
|
2867
|
+
};
|
|
2868
|
+
/**
|
|
2869
|
+
* Event emitted when operations are written to IOperationStore.
|
|
2870
|
+
* Contains the operations directly to avoid round-trip queries.
|
|
2871
|
+
*/
|
|
2872
|
+
type JobWriteReadyEvent = {
|
|
2873
|
+
jobId: string;
|
|
2874
|
+
operations: OperationWithContext$1[];
|
|
2875
|
+
jobMeta: JobMeta;
|
|
2782
2876
|
/**
|
|
2783
|
-
*
|
|
2784
|
-
*
|
|
2785
|
-
*
|
|
2877
|
+
* The ids of the actions the caller submitted with this job. `operations`
|
|
2878
|
+
* can also carry operations the job merely moved into a new position, so a
|
|
2879
|
+
* consumer reporting back to the caller needs this to tell the two apart.
|
|
2880
|
+
* Absent on jobs that carry no submitted actions.
|
|
2786
2881
|
*/
|
|
2787
|
-
|
|
2882
|
+
submittedActionIds?: string[];
|
|
2788
2883
|
/**
|
|
2789
|
-
*
|
|
2790
|
-
*
|
|
2884
|
+
* Maps documentId to the collection IDs it belongs to.
|
|
2885
|
+
* Used by SyncManager to route operations only to remotes
|
|
2886
|
+
* whose collection contains the document.
|
|
2791
2887
|
*/
|
|
2792
|
-
|
|
2888
|
+
collectionMemberships?: Record<string, string[]>;
|
|
2793
2889
|
};
|
|
2794
2890
|
/**
|
|
2795
|
-
*
|
|
2796
|
-
*
|
|
2797
|
-
*
|
|
2798
|
-
*
|
|
2891
|
+
* Event emitted after all read models have finished processing operations.
|
|
2892
|
+
* This event fires after JOB_WRITE_READY and guarantees that:
|
|
2893
|
+
* - All read models (DocumentView, DocumentIndexer, etc.) have indexed the operations
|
|
2894
|
+
* - All consistency trackers have been updated with the new operation indices
|
|
2895
|
+
* - Queries without consistency tokens will now see the updated data
|
|
2799
2896
|
*
|
|
2800
|
-
*
|
|
2801
|
-
*
|
|
2897
|
+
* This event is useful for:
|
|
2898
|
+
* - Test synchronization (knowing when read models are ready)
|
|
2899
|
+
* - Observability (measuring read model latency)
|
|
2900
|
+
* - Event-driven workflows (triggering downstream processes)
|
|
2802
2901
|
*/
|
|
2803
|
-
type
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
workerType: "thread" | "process"; /** Optional heartbeat interval in milliseconds. */
|
|
2807
|
-
heartbeatMs?: number; /** Optional per-worker Postgres pool size override. */
|
|
2808
|
-
workerPgPoolSize?: number;
|
|
2902
|
+
type JobReadReadyEvent = {
|
|
2903
|
+
jobId: string;
|
|
2904
|
+
operations: OperationWithContext$1[];
|
|
2809
2905
|
};
|
|
2810
2906
|
/**
|
|
2811
|
-
*
|
|
2812
|
-
*
|
|
2813
|
-
*
|
|
2814
|
-
* intentionally absent from the worker -> parent message.
|
|
2815
|
-
*
|
|
2816
|
-
* @see Wire Protocol Reference wiki page
|
|
2817
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2907
|
+
* Event emitted when a job fails with an unrecoverable error.
|
|
2908
|
+
* This event allows the JobAwaiter and other subscribers to react to job failures
|
|
2909
|
+
* without polling.
|
|
2818
2910
|
*/
|
|
2819
|
-
type
|
|
2820
|
-
|
|
2821
|
-
|
|
2911
|
+
type JobFailedEvent$1 = {
|
|
2912
|
+
jobId: string;
|
|
2913
|
+
error: Error;
|
|
2914
|
+
job?: Job;
|
|
2822
2915
|
};
|
|
2823
2916
|
/**
|
|
2824
|
-
*
|
|
2825
|
-
*
|
|
2826
|
-
*
|
|
2827
|
-
*
|
|
2828
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2917
|
+
* Event emitted once per batch processed by ReadModelCoordinator.runChain,
|
|
2918
|
+
* after all three projection stages complete. Carries per-stage wall times,
|
|
2919
|
+
* the chain wait time, and the batch size so projection cost can be
|
|
2920
|
+
* attributed by an observer.
|
|
2829
2921
|
*/
|
|
2830
|
-
type
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2922
|
+
type ReadModelBatchCompletedEvent = {
|
|
2923
|
+
jobId: string;
|
|
2924
|
+
batchSize: number;
|
|
2925
|
+
chainWaitDurationMs: number;
|
|
2926
|
+
preReadyDurationMs: number;
|
|
2927
|
+
emitDurationMs: number;
|
|
2928
|
+
postReadyDurationMs: number;
|
|
2929
|
+
};
|
|
2930
|
+
/**
|
|
2931
|
+
* Event emitted once per individual read model per batch and stage, after
|
|
2932
|
+
* that read model's indexOperations call resolves (or rejects). Lets
|
|
2933
|
+
* observers attribute projection cost to a specific read model.
|
|
2934
|
+
*/
|
|
2935
|
+
type ReadModelIndexedEvent = {
|
|
2936
|
+
jobId: string;
|
|
2937
|
+
readModelName: string;
|
|
2938
|
+
stage: ReadModelIndexingStage;
|
|
2939
|
+
durationMs: number;
|
|
2940
|
+
operationCount: number;
|
|
2941
|
+
success: boolean;
|
|
2942
|
+
};
|
|
2943
|
+
/** A write failed admission; `enforced` is false in log mode, which admits it. */
|
|
2944
|
+
type SignatureRefusedEvent = {
|
|
2945
|
+
jobId: string;
|
|
2946
|
+
documentId: string;
|
|
2947
|
+
scope: string;
|
|
2948
|
+
branch: string;
|
|
2949
|
+
actionId: string;
|
|
2950
|
+
code: SignatureRefusalCode;
|
|
2951
|
+
scheme: SignatureScheme;
|
|
2952
|
+
path: AdmissionPath;
|
|
2953
|
+
enforced: boolean;
|
|
2954
|
+
reason: string;
|
|
2839
2955
|
};
|
|
2956
|
+
//#endregion
|
|
2957
|
+
//#region src/events/interfaces.d.ts
|
|
2958
|
+
/**
|
|
2959
|
+
* Describes an object that manages event subscriptions and emissions.
|
|
2960
|
+
*/
|
|
2961
|
+
interface IEventBus {
|
|
2962
|
+
/**
|
|
2963
|
+
* Register a new subscriber.
|
|
2964
|
+
* Order is preserved by pushing to the end of the per-type array.
|
|
2965
|
+
*
|
|
2966
|
+
* @param type - The type of event to subscribe to.
|
|
2967
|
+
* @param subscriber - The subscriber function to call when the event is emitted.
|
|
2968
|
+
*
|
|
2969
|
+
* @returns A function to unsubscribe from the event.
|
|
2970
|
+
*/
|
|
2971
|
+
subscribe<K>(type: number, subscriber: (type: number, event: K) => void | Promise<void>): Unsubscribe;
|
|
2972
|
+
/**
|
|
2973
|
+
* Emits an event and waits until **all** subscribers finish.
|
|
2974
|
+
* - Every subscriber present at emit-start is called, in registration order.
|
|
2975
|
+
* - Calls are invoked and settled sequentially.
|
|
2976
|
+
* - If subscribers throw/reject, `emit` rejects with an aggregate error of all errors.
|
|
2977
|
+
*
|
|
2978
|
+
* @param type - The type of event to emit.
|
|
2979
|
+
* @param data - The data to pass to the subscribers.
|
|
2980
|
+
*/
|
|
2981
|
+
emit(type: number, data: any): Promise<void>;
|
|
2982
|
+
}
|
|
2983
|
+
//#endregion
|
|
2984
|
+
//#region src/shared/awaiter.d.ts
|
|
2985
|
+
interface IJobAwaiter {
|
|
2986
|
+
/**
|
|
2987
|
+
* Waits for a job to complete: turns a job into a promise.
|
|
2988
|
+
*
|
|
2989
|
+
* @param jobId - The job id or job object
|
|
2990
|
+
* @param signal - Optional abort signal to cancel the request
|
|
2991
|
+
* @returns The result of the job
|
|
2992
|
+
*/
|
|
2993
|
+
waitForJob(jobId: string, signal?: AbortSignal): Promise<JobInfo>;
|
|
2994
|
+
/**
|
|
2995
|
+
* Shuts down the job awaiter. This will synchronously reject all pending jobs.
|
|
2996
|
+
*/
|
|
2997
|
+
shutdown(): void;
|
|
2998
|
+
}
|
|
2840
2999
|
/**
|
|
2841
|
-
*
|
|
2842
|
-
*
|
|
2843
|
-
* @see Wire Protocol Reference wiki page
|
|
2844
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
3000
|
+
* Event-driven implementation of IJobAwaiter.
|
|
3001
|
+
* Subscribes to operation events to detect job completion without polling.
|
|
2845
3002
|
*/
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
3003
|
+
declare class JobAwaiter implements IJobAwaiter {
|
|
3004
|
+
private eventBus;
|
|
3005
|
+
private getJobStatus;
|
|
3006
|
+
private pendingJobs;
|
|
3007
|
+
private unsubscribers;
|
|
3008
|
+
constructor(eventBus: IEventBus, getJobStatus: (jobId: string, signal?: AbortSignal) => Promise<JobInfo>);
|
|
3009
|
+
private subscribeToEvents;
|
|
3010
|
+
shutdown(): void;
|
|
3011
|
+
waitForJob(jobId: string, signal?: AbortSignal): Promise<JobInfo>;
|
|
3012
|
+
private handleWriteReady;
|
|
3013
|
+
private handleReadReady;
|
|
3014
|
+
private handleJobFailed;
|
|
3015
|
+
private checkAndResolveWaiters;
|
|
3016
|
+
}
|
|
3017
|
+
//#endregion
|
|
3018
|
+
//#region src/subs/types.d.ts
|
|
2851
3019
|
/**
|
|
2852
|
-
*
|
|
2853
|
-
*
|
|
2854
|
-
* @see Wire Protocol Reference wiki page
|
|
2855
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
3020
|
+
* Error handler for subscription callback errors
|
|
2856
3021
|
*/
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
3022
|
+
interface ISubscriptionErrorHandler {
|
|
3023
|
+
/**
|
|
3024
|
+
* Called when a subscription callback throws an error
|
|
3025
|
+
* @param error - The error that was thrown
|
|
3026
|
+
* @param context - Context about which subscription failed
|
|
3027
|
+
*/
|
|
3028
|
+
handleError(error: unknown, context: SubscriptionErrorContext): void;
|
|
3029
|
+
}
|
|
2863
3030
|
/**
|
|
2864
|
-
*
|
|
2865
|
-
*
|
|
2866
|
-
* @see Wire Protocol Reference wiki page
|
|
2867
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
3031
|
+
* Context information about a subscription error
|
|
2868
3032
|
*/
|
|
2869
|
-
|
|
2870
|
-
type
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
3033
|
+
interface SubscriptionErrorContext {
|
|
3034
|
+
/** The type of event that was being processed */
|
|
3035
|
+
eventType: "created" | "deleted" | "updated" | "relationshipChanged";
|
|
3036
|
+
/** The subscription ID that failed */
|
|
3037
|
+
subscriptionId: string;
|
|
3038
|
+
/** Optional additional data about the event */
|
|
3039
|
+
eventData?: unknown;
|
|
3040
|
+
}
|
|
2874
3041
|
/**
|
|
2875
|
-
*
|
|
2876
|
-
*
|
|
2877
|
-
* @see Wire Protocol Reference wiki page
|
|
2878
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
3042
|
+
* Interface for subscribing to document events in the reactor.
|
|
2879
3043
|
*/
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
3044
|
+
interface IReactorSubscriptionManager {
|
|
3045
|
+
/**
|
|
3046
|
+
* Subscribes to document creation events
|
|
3047
|
+
*
|
|
3048
|
+
* @param callback - Function called when documents are created
|
|
3049
|
+
* @param search - Optional search filter to limit which documents trigger events
|
|
3050
|
+
* @param view - Optional filter containing branch and scopes information
|
|
3051
|
+
* @returns A function that unsubscribes from the events
|
|
3052
|
+
*/
|
|
3053
|
+
onDocumentCreated(callback: (result: PagedResults<string>) => void, search?: SearchFilter): () => void;
|
|
3054
|
+
/**
|
|
3055
|
+
* Subscribes to document deletion events
|
|
3056
|
+
*
|
|
3057
|
+
* @param callback - Function called when documents are deleted
|
|
3058
|
+
* @param search - Optional search filter to limit which documents trigger events
|
|
3059
|
+
* @returns A function that unsubscribes from the events
|
|
3060
|
+
*/
|
|
3061
|
+
onDocumentDeleted(callback: (documentIds: string[]) => void, search?: SearchFilter): () => void;
|
|
3062
|
+
/**
|
|
3063
|
+
* Subscribes to document state updates
|
|
3064
|
+
*
|
|
3065
|
+
* @param callback - Function called when documents are updated
|
|
3066
|
+
* @param search - Optional search filter to limit which documents trigger events
|
|
3067
|
+
* @param view - Optional filter containing branch and scopes information
|
|
3068
|
+
* @returns A function that unsubscribes from the events
|
|
3069
|
+
*/
|
|
3070
|
+
onDocumentStateUpdated(callback: (result: PagedResults<PHDocument>) => void, search?: SearchFilter, view?: ViewFilter): () => void;
|
|
3071
|
+
/**
|
|
3072
|
+
* Subscribes to parent-child relationship change events
|
|
3073
|
+
*
|
|
3074
|
+
* @param callback - Function called when parent-child relationships change
|
|
3075
|
+
* @param search - Optional search filter to limit which documents trigger events
|
|
3076
|
+
* @returns A function that unsubscribes from the events
|
|
3077
|
+
*/
|
|
3078
|
+
onRelationshipChanged(callback: (parentId: string, childId: string, changeType: RelationshipChangeType) => void, search?: SearchFilter): () => void;
|
|
3079
|
+
}
|
|
3080
|
+
//#endregion
|
|
3081
|
+
//#region src/decision/types.d.ts
|
|
3082
|
+
/** One operation stream. */
|
|
3083
|
+
type StreamQuery = {
|
|
3084
|
+
documentId: string;
|
|
3085
|
+
branch: string;
|
|
3086
|
+
scope: string;
|
|
2884
3087
|
};
|
|
2885
3088
|
/**
|
|
2886
|
-
*
|
|
2887
|
-
*
|
|
2888
|
-
* @see Wire Protocol Reference wiki page
|
|
2889
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2890
|
-
*/
|
|
2891
|
-
type ParentMessage = InitMessage | ExecuteMessage | AbortMessage | ShutdownMessage | LoadModelMessage;
|
|
2892
|
-
/**
|
|
2893
|
-
* Announces that the worker has finished `init` and is ready to accept
|
|
2894
|
-
* `execute` messages.
|
|
3089
|
+
* What building a decision model reads a stream's state through.
|
|
2895
3090
|
*
|
|
2896
|
-
*
|
|
2897
|
-
*
|
|
3091
|
+
* `IWriteCache` satisfies this and is what the write paths pass. The read path
|
|
3092
|
+
* cannot: the write cache is a write-side projection invalidated by the process
|
|
3093
|
+
* that runs the executor, so a reactor whose executors live in worker processes
|
|
3094
|
+
* holds state in its parent that no commit ever invalidates. A read there would
|
|
3095
|
+
* decide against a policy arbitrarily far behind the one the write paths
|
|
3096
|
+
* enforce. Reads therefore pass a reader backed by the read side.
|
|
2898
3097
|
*/
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
3098
|
+
interface IStreamStateReader {
|
|
3099
|
+
getState(documentId: string, scope: string, branch: string, targetRevision?: number, signal?: AbortSignal): Promise<PHDocument>;
|
|
3100
|
+
}
|
|
3101
|
+
/** The document and branch a decision model is built for. */
|
|
3102
|
+
type DecisionTarget = {
|
|
3103
|
+
documentId: string;
|
|
3104
|
+
branch: string;
|
|
2903
3105
|
};
|
|
2904
3106
|
/**
|
|
2905
|
-
*
|
|
2906
|
-
*
|
|
2907
|
-
*
|
|
2908
|
-
*
|
|
2909
|
-
* and `result.success` is false.
|
|
2910
|
-
*
|
|
2911
|
-
* @see Wire Protocol Reference wiki page
|
|
2912
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
3107
|
+
* What a decision's conditions may read beyond the projections: the executing
|
|
3108
|
+
* scope's own state and the attempted action's input. Populated only while
|
|
3109
|
+
* authConditions is on; otherwise both stay undefined and conditional grants
|
|
3110
|
+
* never apply.
|
|
2913
3111
|
*/
|
|
2914
|
-
type
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
result: JobResult;
|
|
2918
|
-
writeReady?: JobWriteReadyPayload;
|
|
2919
|
-
error?: ErrorInfo;
|
|
3112
|
+
type DecisionContext = {
|
|
3113
|
+
scopeState: unknown;
|
|
3114
|
+
actionInput?: unknown;
|
|
2920
3115
|
};
|
|
2921
|
-
/**
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2926
|
-
*/
|
|
2927
|
-
type ModelLoadedMessage = {
|
|
2928
|
-
type: "model-loaded"; /** correlationId of the originating `load-model` message. */
|
|
2929
|
-
correlationId: string;
|
|
2930
|
-
documentType: string;
|
|
2931
|
-
version: string;
|
|
3116
|
+
/** A statically-queried stream's operations, named after its projection. */
|
|
3117
|
+
type StreamHistory = {
|
|
3118
|
+
name: string;
|
|
3119
|
+
operations: Operation[];
|
|
2932
3120
|
};
|
|
2933
3121
|
/**
|
|
2934
|
-
*
|
|
2935
|
-
*
|
|
2936
|
-
*
|
|
2937
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
3122
|
+
* A named stream whose value in the model is that scope's state from the
|
|
3123
|
+
* document rebuild the reactor already performs. A derived query may read
|
|
3124
|
+
* only statically-queried projections, so composition is one layer deep.
|
|
2938
3125
|
*/
|
|
2939
|
-
type
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
3126
|
+
type Projection<M> = {
|
|
3127
|
+
query: StreamQuery | ((model: Partial<M>) => StreamQuery[]);
|
|
3128
|
+
/**
|
|
3129
|
+
* For a derived projection, the streams it may read anywhere in an
|
|
3130
|
+
* evaluated range, derived from the statically-queried streams' operations
|
|
3131
|
+
* (including the operations under evaluation). A positional walk cannot use
|
|
3132
|
+
* `query`, because the folded state it depends on changes over the range;
|
|
3133
|
+
* this over-approximates by design, since a stream referenced at any
|
|
3134
|
+
* position stays readable when the earlier range is re-evaluated even if a
|
|
3135
|
+
* later operation removes the reference. Ignored on static projections.
|
|
3136
|
+
*/
|
|
3137
|
+
queryOverHistory?: (reads: StreamHistory[]) => StreamQuery[];
|
|
3138
|
+
/**
|
|
3139
|
+
* Action types in this stream that can change an evaluation. Reads of the stream
|
|
3140
|
+
* are filtered to these, so anything left out is invisible to a decision.
|
|
3141
|
+
*/
|
|
3142
|
+
decidingActions: string[]; /** Applies one of this stream's operations while deciding. */
|
|
3143
|
+
apply: (document: PHDocument, operation: Operation) => PHDocument;
|
|
2945
3144
|
};
|
|
2946
3145
|
/**
|
|
2947
|
-
*
|
|
2948
|
-
*
|
|
2949
|
-
* values across the boundary.
|
|
2950
|
-
*
|
|
2951
|
-
* The sanitizer in `./sanitize.ts` enforces the {@link SanitizedArg}
|
|
2952
|
-
* invariant on the producer side before each message is posted.
|
|
2953
|
-
*
|
|
2954
|
-
* @see Wire Protocol Reference wiki page
|
|
2955
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
3146
|
+
* The outcome of evaluating one operation. A refusal carries the reason it is
|
|
3147
|
+
* recorded with, because a model has more than one way to refuse.
|
|
2956
3148
|
*/
|
|
2957
|
-
type
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
3149
|
+
type Evaluation = {
|
|
3150
|
+
decision: "allow";
|
|
3151
|
+
} | {
|
|
3152
|
+
decision: "deny";
|
|
3153
|
+
reason: string;
|
|
3154
|
+
};
|
|
3155
|
+
/** Projections plus a decision function over the built model. */
|
|
3156
|
+
type DecisionModel<M> = {
|
|
3157
|
+
projections: { [K in keyof M]: Projection<M> };
|
|
3158
|
+
/**
|
|
3159
|
+
* Present when decide reads the executing scope's state through the
|
|
3160
|
+
* decision context. A positional walk then folds the evaluated stream with
|
|
3161
|
+
* this, from its base state through every effective operation, so
|
|
3162
|
+
* conditions read the state as it stood at each operation's position
|
|
3163
|
+
* rather than at the head.
|
|
3164
|
+
*/
|
|
3165
|
+
foldEvaluatedScope?: (document: PHDocument, operation: Operation) => PHDocument;
|
|
3166
|
+
/**
|
|
3167
|
+
* Whether or not this model decides about operations in a given scope. That
|
|
3168
|
+
* is, a scope it reads is not necessarily one it evaluates, and vise-versa.
|
|
3169
|
+
*/
|
|
3170
|
+
evaluatesScope(scope: string): boolean;
|
|
3171
|
+
decide(model: M, subject: AuthSubject, request: AuthRequest, ctx: DecisionContext): Evaluation;
|
|
2963
3172
|
};
|
|
2964
|
-
/**
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
* @see Wire Protocol Reference wiki page
|
|
2969
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
2970
|
-
*/
|
|
2971
|
-
type HeartbeatMessage = {
|
|
2972
|
-
type: "heartbeat";
|
|
2973
|
-
workerId: string; /** Epoch milliseconds the worker generated the heartbeat. */
|
|
2974
|
-
timestamp: number; /** Optional snapshot of in-flight job correlation ids. */
|
|
2975
|
-
inFlightCorrelationIds?: string[];
|
|
3173
|
+
/** A built model plus the read-set condition recording what the build read. */
|
|
3174
|
+
type BuiltDecisionModel<M> = {
|
|
3175
|
+
model: M;
|
|
3176
|
+
appendCondition: AppendCondition;
|
|
2976
3177
|
};
|
|
3178
|
+
//#endregion
|
|
3179
|
+
//#region src/client/types.d.ts
|
|
2977
3180
|
/**
|
|
2978
|
-
*
|
|
2979
|
-
*
|
|
2980
|
-
* @see Wire Protocol Reference wiki page
|
|
2981
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
3181
|
+
* Describes the types of document changes that can occur.
|
|
2982
3182
|
*/
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
};
|
|
2993
|
-
};
|
|
3183
|
+
declare enum DocumentChangeType {
|
|
3184
|
+
Created = "created",
|
|
3185
|
+
Deleted = "deleted",
|
|
3186
|
+
Updated = "updated",
|
|
3187
|
+
ParentAdded = "parent_added",
|
|
3188
|
+
ParentRemoved = "parent_removed",
|
|
3189
|
+
ChildAdded = "child_added",
|
|
3190
|
+
ChildRemoved = "child_removed"
|
|
3191
|
+
}
|
|
2994
3192
|
/**
|
|
2995
|
-
*
|
|
2996
|
-
* forwarded periodically so the host can re-record into the shared
|
|
2997
|
-
* pg.Pool histogram and observable gauges. The worker owns the real
|
|
2998
|
-
* pg.Pool; the host's {@link PoolInstrumentation} is a forwarder driven
|
|
2999
|
-
* by these messages.
|
|
3193
|
+
* Represents a change event for documents.
|
|
3000
3194
|
*/
|
|
3001
|
-
type
|
|
3002
|
-
type:
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
idle: number;
|
|
3009
|
-
waiting: number;
|
|
3195
|
+
type DocumentChangeEvent = {
|
|
3196
|
+
type: DocumentChangeType;
|
|
3197
|
+
documents: PHDocument[];
|
|
3198
|
+
context?: {
|
|
3199
|
+
parentId?: string;
|
|
3200
|
+
childId?: string;
|
|
3201
|
+
};
|
|
3010
3202
|
};
|
|
3011
3203
|
/**
|
|
3012
|
-
*
|
|
3013
|
-
*
|
|
3014
|
-
* @see Wire Protocol Reference wiki page
|
|
3015
|
-
* (Powerhouse board wiki id: 64c03e51-1aa4-4fa9-93d8-daa45642484d)
|
|
3204
|
+
* Options for creating an empty document.
|
|
3016
3205
|
*/
|
|
3017
|
-
type
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
};
|
|
3025
|
-
/** An importable package specifier holding one or more document-model exports. */
|
|
3026
|
-
type PackageModelSource = {
|
|
3027
|
-
packageName: string;
|
|
3028
|
-
subpath?: string;
|
|
3029
|
-
exportName?: string;
|
|
3206
|
+
type CreateDocumentOptions = {
|
|
3207
|
+
/** Optional "id" or "slug" of parent document */parentIdentifier?: string; /** Optional version of the document model to use (defaults to latest) */
|
|
3208
|
+
documentModelVersion?: number; /** Merged over the model's defaults; `signature: 2` makes it v2-required. */
|
|
3209
|
+
protocolVersions?: {
|
|
3210
|
+
[protocol: string]: number;
|
|
3211
|
+
}; /** Overrides the client's creation default for this document. */
|
|
3212
|
+
signaturePolicy?: SignaturePolicy;
|
|
3030
3213
|
};
|
|
3031
3214
|
/**
|
|
3032
|
-
*
|
|
3033
|
-
* importable package. File and package sources can cross a worker-thread
|
|
3034
|
-
* boundary (workers re-import them); a live module cannot.
|
|
3215
|
+
* Options for upgrading a document.
|
|
3035
3216
|
*/
|
|
3036
|
-
type
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
status: "error";
|
|
3044
|
-
item: T;
|
|
3045
|
-
error: Error;
|
|
3217
|
+
type UpgradeDocumentOptions = {
|
|
3218
|
+
/**
|
|
3219
|
+
* How many times to retry with a fresh read when the executor rejects the
|
|
3220
|
+
* upgrade because the document changed after it was read. Defaults to
|
|
3221
|
+
* {@link DEFAULT_UPGRADE_CONFLICT_RETRIES}.
|
|
3222
|
+
*/
|
|
3223
|
+
maxConflictRetries?: number;
|
|
3046
3224
|
};
|
|
3047
3225
|
/**
|
|
3048
|
-
*
|
|
3049
|
-
* {@link DocumentModelSource}. Used by the queue to gate CREATE_DOCUMENT
|
|
3050
|
-
* jobs until the required model is available in the registry.
|
|
3226
|
+
* Drive-aware operations grouped under `client.drives`.
|
|
3051
3227
|
*
|
|
3052
|
-
*
|
|
3053
|
-
*
|
|
3054
|
-
*
|
|
3055
|
-
*
|
|
3056
|
-
*
|
|
3057
|
-
*/
|
|
3058
|
-
interface IDocumentModelLoader {
|
|
3059
|
-
load(documentType: string): Promise<DocumentModelSource>;
|
|
3060
|
-
}
|
|
3061
|
-
/**
|
|
3062
|
-
* Registry for managing document model modules.
|
|
3063
|
-
* Provides centralized access to document models' reducers, utils, and specifications.
|
|
3064
|
-
* Supports version-aware module storage and upgrade manifest management.
|
|
3228
|
+
* These methods orchestrate the multi-action, multi-document choreography
|
|
3229
|
+
* required to keep a drive's `state.global.nodes` array consistent with the
|
|
3230
|
+
* relationship index and the underlying documents. Use the flat
|
|
3231
|
+
* `IReactorClient` primitives (`get`, `execute`, `find`) for everything that
|
|
3232
|
+
* is not drive-aware.
|
|
3065
3233
|
*/
|
|
3066
|
-
interface
|
|
3067
|
-
/**
|
|
3068
|
-
* Register multiple modules at once.
|
|
3069
|
-
* Modules without a version field default to version 1.
|
|
3070
|
-
* Invalid or duplicate modules are skipped without breaking registration of the remaining modules.
|
|
3071
|
-
*
|
|
3072
|
-
* @param modules Document model modules to register
|
|
3073
|
-
* @returns Array of results, one per module, indicating success or failure
|
|
3074
|
-
*/
|
|
3075
|
-
registerModules(...modules: DocumentModelModule<any>[]): RegistrationResult<DocumentModelModule<any>>[];
|
|
3234
|
+
interface IDriveClient {
|
|
3076
3235
|
/**
|
|
3077
|
-
*
|
|
3078
|
-
*
|
|
3079
|
-
* @param documentTypes The document types to unregister
|
|
3080
|
-
* @returns true if all modules were unregistered, false if any were not found
|
|
3236
|
+
* Creates a new drive document and waits for completion.
|
|
3081
3237
|
*/
|
|
3082
|
-
|
|
3238
|
+
create(input: DriveInput, signal?: AbortSignal): Promise<DocumentDriveDocument>;
|
|
3083
3239
|
/**
|
|
3084
|
-
*
|
|
3085
|
-
* If version is not specified, returns the latest version.
|
|
3240
|
+
* Adds a document to a drive as a single batched operation.
|
|
3086
3241
|
*
|
|
3087
|
-
*
|
|
3088
|
-
*
|
|
3089
|
-
* @returns The document model module
|
|
3090
|
-
* @throws ModuleNotFoundError if the document type or version is not registered
|
|
3242
|
+
* Issues CREATE_DOCUMENT, UPGRADE_DOCUMENT, ADD_RELATIONSHIP on the new
|
|
3243
|
+
* document and ADD_FILE on the drive in a single dependent batch.
|
|
3091
3244
|
*/
|
|
3092
|
-
|
|
3245
|
+
addFile<TDocument extends PHDocument = PHDocument>(driveIdentifier: string, document: PHDocument, parentFolder?: string, signal?: AbortSignal): Promise<TDocument>;
|
|
3093
3246
|
/**
|
|
3094
|
-
*
|
|
3095
|
-
*
|
|
3096
|
-
* @returns Array of all registered modules
|
|
3247
|
+
* Adds a folder node to a drive.
|
|
3097
3248
|
*/
|
|
3098
|
-
|
|
3249
|
+
addFolder(driveIdentifier: string, name: string, parentFolder?: string, signal?: AbortSignal): Promise<FolderNode>;
|
|
3099
3250
|
/**
|
|
3100
|
-
*
|
|
3251
|
+
* Removes a node from a drive. Folder nodes cascade: descendant file
|
|
3252
|
+
* documents are deleted first, then the folder node entry itself.
|
|
3101
3253
|
*/
|
|
3102
|
-
|
|
3254
|
+
removeNode(driveIdentifier: string, nodeId: string, signal?: AbortSignal): Promise<void>;
|
|
3103
3255
|
/**
|
|
3104
|
-
*
|
|
3105
|
-
*
|
|
3106
|
-
* @param documentType The document type identifier
|
|
3107
|
-
* @returns Array of version numbers sorted ascending
|
|
3108
|
-
* @throws ModuleNotFoundError if no modules are registered for the document type
|
|
3256
|
+
* Renames a node. Updates both the underlying document header and the
|
|
3257
|
+
* drive's node entry.
|
|
3109
3258
|
*/
|
|
3110
|
-
|
|
3259
|
+
renameNode(driveIdentifier: string, nodeId: string, name: string, signal?: AbortSignal): Promise<Node>;
|
|
3111
3260
|
/**
|
|
3112
|
-
*
|
|
3113
|
-
*
|
|
3114
|
-
* @param documentType The document type identifier
|
|
3115
|
-
* @returns The highest version number registered for this document type
|
|
3116
|
-
* @throws ModuleNotFoundError if no modules are registered for the document type
|
|
3261
|
+
* Updates the preferred editor recorded in the document header meta for
|
|
3262
|
+
* a node. Pass `null` to clear it.
|
|
3117
3263
|
*/
|
|
3118
|
-
|
|
3264
|
+
setPreferredEditorOnNode(nodeId: string, preferredEditor: string | null, signal?: AbortSignal): Promise<PHDocument>;
|
|
3119
3265
|
/**
|
|
3120
|
-
*
|
|
3121
|
-
*
|
|
3122
|
-
*
|
|
3123
|
-
* @param manifests Upgrade manifests to register
|
|
3124
|
-
* @returns Array of results, one per manifest, indicating success or failure
|
|
3266
|
+
* Moves a node to a different parent folder within the same drive.
|
|
3267
|
+
* Pass `undefined` to move the node to the drive root.
|
|
3125
3268
|
*/
|
|
3126
|
-
|
|
3127
|
-
/**
|
|
3128
|
-
* Unregister upgrade manifests for the specified document types.
|
|
3129
|
-
* @param documentTypes The document types whose upgrade manifests should be unregistered
|
|
3130
|
-
* @returns true if all modules were unregistered, false if any were not found
|
|
3131
|
-
**/
|
|
3132
|
-
unregisterUpgradeManifests(...documentTypes: string[]): boolean;
|
|
3269
|
+
moveNode(driveIdentifier: string, srcNodeId: string, targetParentFolderId: string | undefined, signal?: AbortSignal): Promise<DocumentDriveDocument>;
|
|
3133
3270
|
/**
|
|
3134
|
-
*
|
|
3135
|
-
*
|
|
3136
|
-
* @param documentType The document type identifier
|
|
3137
|
-
* @returns The upgrade manifest
|
|
3138
|
-
* @throws ManifestNotFoundError if no manifest is registered for the document type
|
|
3271
|
+
* Copies a node (and its subtree, if it is a folder) within a drive.
|
|
3272
|
+
* Each copied file gets a new id and a duplicated document.
|
|
3139
3273
|
*/
|
|
3140
|
-
|
|
3274
|
+
copyNode(driveIdentifier: string, srcNodeId: string, targetParentFolderId: string | undefined, signal?: AbortSignal): Promise<DocumentDriveDocument>;
|
|
3141
3275
|
/**
|
|
3142
|
-
*
|
|
3143
|
-
* Returns the sequence of upgrade transitions needed.
|
|
3144
|
-
*
|
|
3145
|
-
* @param documentType The document type identifier
|
|
3146
|
-
* @param fromVersion The starting version
|
|
3147
|
-
* @param toVersion The target version
|
|
3148
|
-
* @returns Array of upgrade transitions in order
|
|
3149
|
-
* @throws DowngradeNotSupportedError if toVersion is less than fromVersion
|
|
3150
|
-
* @throws ManifestNotFoundError if no upgrade manifest is registered
|
|
3151
|
-
* @throws MissingUpgradeTransitionError if any transition in the path is missing
|
|
3276
|
+
* Returns a single node from the drive's `state.global.nodes` array.
|
|
3152
3277
|
*/
|
|
3153
|
-
|
|
3278
|
+
getNode(driveIdentifier: string, nodeId: string, signal?: AbortSignal): Promise<Node>;
|
|
3154
3279
|
/**
|
|
3155
|
-
*
|
|
3280
|
+
* Returns nodes in the drive, optionally filtered by parent folder:
|
|
3281
|
+
* - omit `parentFolder` (or pass `undefined`) to list every node in the drive.
|
|
3282
|
+
* - pass `null` to list only root-level nodes.
|
|
3283
|
+
* - pass a folder id to list only the direct children of that folder.
|
|
3156
3284
|
*
|
|
3157
|
-
*
|
|
3158
|
-
*
|
|
3159
|
-
* @param toVersion The target version (must be fromVersion + 1)
|
|
3160
|
-
* @returns The upgrade reducer function
|
|
3161
|
-
* @throws InvalidUpgradeStepError if toVersion is not fromVersion + 1
|
|
3162
|
-
* @throws ManifestNotFoundError if no upgrade manifest is registered
|
|
3163
|
-
* @throws MissingUpgradeTransitionError if the transition is not found
|
|
3285
|
+
* Returns a paged result so callers can stream through drives with very
|
|
3286
|
+
* large node counts without materialising the whole list in memory.
|
|
3164
3287
|
*/
|
|
3165
|
-
|
|
3288
|
+
listNodes(driveIdentifier: string, parentFolder?: string | null, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<Node>>;
|
|
3166
3289
|
}
|
|
3167
|
-
//#endregion
|
|
3168
|
-
//#region src/cache/buffer/ring-buffer.d.ts
|
|
3169
3290
|
/**
|
|
3170
|
-
*
|
|
3171
|
-
*
|
|
3291
|
+
* One operation an authorization preflight predicts a verdict for. The input is
|
|
3292
|
+
* what a conditional grant reads, so a candidate standing for a filled-in form
|
|
3293
|
+
* carries that form's input.
|
|
3294
|
+
*/
|
|
3295
|
+
type ActionCandidate = {
|
|
3296
|
+
scope: string;
|
|
3297
|
+
type: string;
|
|
3298
|
+
input?: unknown;
|
|
3299
|
+
};
|
|
3300
|
+
/**
|
|
3301
|
+
* The predicted verdicts for a set of candidates, in the order they were given,
|
|
3302
|
+
* with the aggregates a UI branches on.
|
|
3172
3303
|
*
|
|
3173
|
-
*
|
|
3174
|
-
*
|
|
3304
|
+
* The aggregates are redundant -- a verdict is binary, so `allDenied` is
|
|
3305
|
+
* `!anyAllowed` and `anyDenied` is `!allAllowed` -- and all four are returned
|
|
3306
|
+
* so that a caller reads the one its question is phrased in rather than
|
|
3307
|
+
* negating another. Over no candidates every aggregate is false: nothing is
|
|
3308
|
+
* allowed and nothing is denied.
|
|
3309
|
+
*/
|
|
3310
|
+
type ActionEvaluations = {
|
|
3311
|
+
evaluations: Evaluation[];
|
|
3312
|
+
allAllowed: boolean;
|
|
3313
|
+
anyAllowed: boolean;
|
|
3314
|
+
allDenied: boolean;
|
|
3315
|
+
anyDenied: boolean;
|
|
3316
|
+
};
|
|
3317
|
+
/**
|
|
3318
|
+
* The ReactorClient interface that wraps lower-level APIs to provide
|
|
3319
|
+
* a simpler interface for document operations.
|
|
3175
3320
|
*
|
|
3176
|
-
*
|
|
3321
|
+
* Features:
|
|
3322
|
+
* - Wraps Jobs with Promises for easier async handling
|
|
3323
|
+
* - Manages signing of submitted Action objects
|
|
3324
|
+
* - Provides quality-of-life functions for common tasks
|
|
3325
|
+
* - Wraps subscription interface with ViewFilters
|
|
3177
3326
|
*/
|
|
3178
|
-
|
|
3179
|
-
private buffer;
|
|
3180
|
-
private head;
|
|
3181
|
-
private size;
|
|
3182
|
-
private capacity;
|
|
3183
|
-
constructor(capacity: number);
|
|
3327
|
+
interface IReactorClient {
|
|
3184
3328
|
/**
|
|
3185
|
-
*
|
|
3329
|
+
* Drive-aware operations. See {@link IDriveClient}.
|
|
3330
|
+
*/
|
|
3331
|
+
readonly drives: IDriveClient;
|
|
3332
|
+
/**
|
|
3333
|
+
* Retrieves a list of document model modules.
|
|
3186
3334
|
*
|
|
3187
|
-
* @param
|
|
3335
|
+
* @param namespace - Optional namespace like "powerhouse" or "sky", defaults to ""
|
|
3336
|
+
* @param paging - Optional pagination options
|
|
3337
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3338
|
+
* @returns List of document model modules
|
|
3188
3339
|
*/
|
|
3189
|
-
|
|
3340
|
+
getDocumentModelModules(namespace?: string, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<DocumentModelModule>>;
|
|
3190
3341
|
/**
|
|
3191
|
-
*
|
|
3342
|
+
* Retrieves a specific document model module by document type.
|
|
3192
3343
|
*
|
|
3193
|
-
* @
|
|
3344
|
+
* @param documentType - The document type identifier
|
|
3345
|
+
* @returns The document model module
|
|
3194
3346
|
*/
|
|
3195
|
-
|
|
3347
|
+
getDocumentModelModule(documentType: string): Promise<DocumentModelModule<any>>;
|
|
3196
3348
|
/**
|
|
3197
|
-
*
|
|
3349
|
+
* Retrieves a specific document by identifier (either id or slug).
|
|
3350
|
+
*
|
|
3351
|
+
* @param identifier - Required, this is the document id or slug
|
|
3352
|
+
* @param view - Optional filter containing branch and scopes information
|
|
3353
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3354
|
+
* @returns The up-to-date PHDocument with scopes and list of child document ids
|
|
3198
3355
|
*/
|
|
3199
|
-
|
|
3356
|
+
get<TDocument extends PHDocument>(identifier: string, view?: ViewFilter, signal?: AbortSignal): Promise<TDocument>;
|
|
3200
3357
|
/**
|
|
3201
|
-
*
|
|
3358
|
+
* Resolves an identifier (either an id or a slug) to the canonical document
|
|
3359
|
+
* id, using the same lookup as the read/operation data paths. Resolves
|
|
3360
|
+
* against the "main" branch. Throws if the identifier cannot be resolved or
|
|
3361
|
+
* is ambiguous.
|
|
3362
|
+
*
|
|
3363
|
+
* @param identifier - Required, this is the document id or slug
|
|
3364
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3365
|
+
* @returns The canonical document id
|
|
3202
3366
|
*/
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
//#region src/cache/kysely-write-cache.d.ts
|
|
3207
|
-
type DocumentStream = {
|
|
3208
|
-
key: string;
|
|
3209
|
-
ringBuffer: RingBuffer<CachedSnapshot>;
|
|
3210
|
-
};
|
|
3211
|
-
/**
|
|
3212
|
-
* In-memory write cache with keyframe persistence for PHDocuments.
|
|
3213
|
-
*
|
|
3214
|
-
* Caches document snapshots in ring buffers with LRU eviction. On cache miss,
|
|
3215
|
-
* rebuilds documents from nearest keyframe or full operation history.
|
|
3216
|
-
*
|
|
3217
|
-
* **Performance Characteristics:**
|
|
3218
|
-
* - Cache hit: O(1) lookup in ring buffer
|
|
3219
|
-
* - Cold miss: O(n) where n is total operation count, or O(k) where k is operations since keyframe
|
|
3220
|
-
* - Warm miss: O(m) where m is operations since cached revision
|
|
3221
|
-
* - Eviction: O(1) for LRU tracking and removal
|
|
3222
|
-
*
|
|
3223
|
-
* **Thread Safety:**
|
|
3224
|
-
* Not thread-safe. Designed for single-threaded job executor environment.
|
|
3225
|
-
* External synchronization required for concurrent access across multiple executors.
|
|
3226
|
-
*
|
|
3227
|
-
* **Example:**
|
|
3228
|
-
* ```typescript
|
|
3229
|
-
* const cache = new KyselyWriteCache(
|
|
3230
|
-
* keyframeStore,
|
|
3231
|
-
* operationStore,
|
|
3232
|
-
* registry,
|
|
3233
|
-
* { maxDocuments: 1000, ringBufferSize: 10, keyframeInterval: 10 }
|
|
3234
|
-
* );
|
|
3235
|
-
*
|
|
3236
|
-
* await cache.startup();
|
|
3237
|
-
*
|
|
3238
|
-
* // Retrieve or rebuild document
|
|
3239
|
-
* const doc = await cache.getState(docId, docType, scope, branch, revision);
|
|
3240
|
-
*
|
|
3241
|
-
* // Cache result after job execution
|
|
3242
|
-
* cache.putState(docId, docType, scope, branch, newRevision, updatedDoc);
|
|
3243
|
-
*
|
|
3244
|
-
* await cache.shutdown();
|
|
3245
|
-
* ```
|
|
3246
|
-
*/
|
|
3247
|
-
declare class KyselyWriteCache implements IWriteCache {
|
|
3248
|
-
private streams;
|
|
3249
|
-
private lruTracker;
|
|
3250
|
-
private keyframeStore;
|
|
3251
|
-
private operationStore;
|
|
3252
|
-
private registry;
|
|
3253
|
-
private config;
|
|
3254
|
-
constructor(keyframeStore: IKeyframeStore, operationStore: IOperationStore, registry: IDocumentModelRegistry, config: WriteCacheConfig);
|
|
3255
|
-
withScopedStores(operationStore: IOperationStore, keyframeStore: IKeyframeStore): KyselyWriteCache;
|
|
3367
|
+
resolveIdOrSlug(identifier: string, view?: ViewFilter, signal?: AbortSignal): Promise<string>;
|
|
3368
|
+
/** True when the id is taken; a soft-deleted document's id is still taken. */
|
|
3369
|
+
isDocumentIdTaken(documentId: string, signal?: AbortSignal): Promise<boolean>;
|
|
3256
3370
|
/**
|
|
3257
|
-
*
|
|
3258
|
-
*
|
|
3371
|
+
* Retrieves operations for a document.
|
|
3372
|
+
*
|
|
3373
|
+
* @param documentIdentifier - Required, this is either a document "id" field or a "slug"
|
|
3374
|
+
* @param view - Optional filter containing branch and scopes information
|
|
3375
|
+
* @param filter - Optional filter for actionTypes, timestamps, and revision
|
|
3376
|
+
* @param paging - Optional pagination options
|
|
3377
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3378
|
+
* @returns Paginated list of operations
|
|
3259
3379
|
*/
|
|
3260
|
-
|
|
3380
|
+
getOperations(documentIdentifier: string, view?: ViewFilter, filter?: OperationFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<Operation>>;
|
|
3261
3381
|
/**
|
|
3262
|
-
*
|
|
3263
|
-
*
|
|
3382
|
+
* Retrieves outgoing relationships of a given type from a source document.
|
|
3383
|
+
*
|
|
3384
|
+
* @param sourceIdentifier - Required, this is either a document "id" field or a "slug"
|
|
3385
|
+
* @param relationshipType - The relationship type to filter by
|
|
3386
|
+
* @param view - Optional filter containing branch and scopes information
|
|
3387
|
+
* @param paging - Optional pagination options
|
|
3388
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3389
|
+
* @returns The target documents and paging cursor
|
|
3264
3390
|
*/
|
|
3265
|
-
|
|
3391
|
+
getOutgoingRelationships(sourceIdentifier: string, relationshipType: string, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
|
|
3266
3392
|
/**
|
|
3267
|
-
* Retrieves
|
|
3393
|
+
* Retrieves incoming relationships of a given type to a target document.
|
|
3268
3394
|
*
|
|
3269
|
-
*
|
|
3395
|
+
* @param targetIdentifier - Required, this is either a document "id" field or a "slug"
|
|
3396
|
+
* @param relationshipType - The relationship type to filter by
|
|
3397
|
+
* @param view - Optional filter containing branch and scopes information
|
|
3398
|
+
* @param paging - Optional pagination options
|
|
3399
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3400
|
+
* @returns The source documents and paging cursor
|
|
3401
|
+
*/
|
|
3402
|
+
getIncomingRelationships(targetIdentifier: string, relationshipType: string, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
|
|
3403
|
+
/**
|
|
3404
|
+
* Retrieves the outgoing relationship edges of a source document.
|
|
3270
3405
|
*
|
|
3271
|
-
*
|
|
3272
|
-
*
|
|
3273
|
-
*
|
|
3406
|
+
* Unlike {@link IReactorClient.getOutgoingRelationships}, which returns the
|
|
3407
|
+
* documents at the far end, this returns the edges themselves, carrying the
|
|
3408
|
+
* metadata and timestamps recorded against each relationship.
|
|
3274
3409
|
*
|
|
3275
|
-
* @param
|
|
3276
|
-
* @param
|
|
3277
|
-
* @param
|
|
3278
|
-
* @param
|
|
3279
|
-
* @param signal - Optional abort signal to cancel the
|
|
3280
|
-
* @returns The
|
|
3281
|
-
* @throws {Error} "Operation aborted" if signal is aborted
|
|
3282
|
-
* @throws {ModuleNotFoundError} If document type not registered in registry
|
|
3283
|
-
* @throws {Error} "Failed to rebuild document" if operation store fails
|
|
3284
|
-
* @throws {Error} If reducer throws during operation application
|
|
3285
|
-
* @throws {Error} If document serialization fails
|
|
3410
|
+
* @param sourceIdentifier - Required, this is either a document "id" field or a "slug"
|
|
3411
|
+
* @param relationshipType - Optional relationship type to filter by
|
|
3412
|
+
* @param view - Optional filter containing branch and scopes information
|
|
3413
|
+
* @param paging - Optional pagination options
|
|
3414
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3415
|
+
* @returns The matching relationship edges and paging cursor
|
|
3286
3416
|
*/
|
|
3287
|
-
|
|
3417
|
+
getOutgoingRelationshipEdges(sourceIdentifier: string, relationshipType?: string, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<DocumentRelationship>>;
|
|
3288
3418
|
/**
|
|
3289
|
-
*
|
|
3290
|
-
*
|
|
3291
|
-
* The cached document is a shallow copy of the input with its operation history
|
|
3292
|
-
* truncated to the last operation per scope and its clipboard cleared. This keeps
|
|
3293
|
-
* memory use and copy costs constant regardless of operation count. Consumers of
|
|
3294
|
-
* getState() must not rely on the full operation history being present; the only
|
|
3295
|
-
* guaranteed invariant is that operations[scope].at(-1) reflects the latest
|
|
3296
|
-
* operation index for each scope.
|
|
3419
|
+
* Retrieves the incoming relationship edges of a target document.
|
|
3297
3420
|
*
|
|
3298
|
-
*
|
|
3299
|
-
*
|
|
3421
|
+
* Unlike {@link IReactorClient.getIncomingRelationships}, which returns the
|
|
3422
|
+
* documents at the far end, this returns the edges themselves, carrying the
|
|
3423
|
+
* metadata and timestamps recorded against each relationship.
|
|
3300
3424
|
*
|
|
3301
|
-
* @param
|
|
3302
|
-
* @param
|
|
3303
|
-
* @param
|
|
3304
|
-
* @param
|
|
3305
|
-
* @param
|
|
3306
|
-
* @
|
|
3425
|
+
* @param targetIdentifier - Required, this is either a document "id" field or a "slug"
|
|
3426
|
+
* @param relationshipType - Optional relationship type to filter by
|
|
3427
|
+
* @param view - Optional filter containing branch and scopes information
|
|
3428
|
+
* @param paging - Optional pagination options
|
|
3429
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3430
|
+
* @returns The matching relationship edges and paging cursor
|
|
3307
3431
|
*/
|
|
3308
|
-
|
|
3432
|
+
getIncomingRelationshipEdges(targetIdentifier: string, relationshipType?: string, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<DocumentRelationship>>;
|
|
3309
3433
|
/**
|
|
3310
|
-
*
|
|
3311
|
-
*
|
|
3312
|
-
*
|
|
3434
|
+
* Filters documents by criteria and returns a list of them
|
|
3435
|
+
*
|
|
3436
|
+
* @param search - Search filter options (type, parentId, identifiers)
|
|
3437
|
+
* @param view - Optional filter containing branch and scopes information
|
|
3438
|
+
* @param paging - Optional pagination options
|
|
3439
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3440
|
+
* @returns List of documents matching criteria and pagination cursor
|
|
3313
3441
|
*/
|
|
3314
|
-
|
|
3315
|
-
revision: number;
|
|
3316
|
-
document: PHDocument;
|
|
3317
|
-
}[]): void;
|
|
3318
|
-
private store;
|
|
3319
|
-
/** Persists the snapshot if this revision is one the interval falls on. */
|
|
3320
|
-
private persistKeyframe;
|
|
3442
|
+
find(search: SearchFilter, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
|
|
3321
3443
|
/**
|
|
3322
|
-
*
|
|
3444
|
+
* Predicts whether the subject would be admitted to execute each of a set of
|
|
3445
|
+
* candidate operations, without submitting any of them. A UI asks this to
|
|
3446
|
+
* disable a control rather than offer an action that fails on submit.
|
|
3447
|
+
*
|
|
3448
|
+
* The answer is a prediction, not a promise. Three caveats hold:
|
|
3449
|
+
*
|
|
3450
|
+
* - Real admission compiles an append condition over everything it read and
|
|
3451
|
+
* the store enforces it at write time. A preflight reads no future, so a
|
|
3452
|
+
* policy change landing between this answer and the submit changes the
|
|
3453
|
+
* verdict. The submit path stays the only authority.
|
|
3454
|
+
* - The verdict is evaluated at the stream heads. It is therefore correct for
|
|
3455
|
+
* a candidate that will be stamped at or after every timestamp the
|
|
3456
|
+
* evaluation read, which is the normal case for a control the user is about
|
|
3457
|
+
* to click. A backdated submission is out of contract: the reactor decides
|
|
3458
|
+
* that one by position, against the policy as it stood there.
|
|
3459
|
+
* - A candidate whose input decides the verdict needs that input supplied.
|
|
3460
|
+
* With `authConditions` on, a conditional grant reads `action.input`, so
|
|
3461
|
+
* omitting the input predicts the denial an empty input would earn rather
|
|
3462
|
+
* than the verdict the filled-in form will get.
|
|
3323
3463
|
*
|
|
3324
|
-
*
|
|
3325
|
-
*
|
|
3326
|
-
*
|
|
3327
|
-
*
|
|
3464
|
+
* Document-scope candidates are decided against the policy of the document
|
|
3465
|
+
* their input names, not the one passed here: delete and upgrade name it in
|
|
3466
|
+
* `input.documentId`, and the relationship actions in `input.sourceId`. This
|
|
3467
|
+
* follows the executor's own gate, which decides against the document
|
|
3468
|
+
* guarding the write. `CREATE_DOCUMENT` follows the gate's exemption: it runs
|
|
3469
|
+
* before its document exists, so the executor never decides it against a
|
|
3470
|
+
* policy and the preflight predicts allow.
|
|
3328
3471
|
*
|
|
3329
|
-
* @param
|
|
3330
|
-
* @param
|
|
3331
|
-
* @param
|
|
3332
|
-
* @
|
|
3472
|
+
* @param documentIdentifier - Document "id" or "slug" the candidates target
|
|
3473
|
+
* @param branch - Branch to evaluate against
|
|
3474
|
+
* @param candidates - Operations to predict a verdict for, each with the scope it would execute in
|
|
3475
|
+
* @param subject - Optional subject to decide for, defaulting to the client's own signer. A plain subject rather than a ViewFilter: the evaluation reads no view, so a filter's branch or scopes would be silently ignored here
|
|
3476
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3477
|
+
* @returns One evaluation per candidate, in the order given, with the aggregates over them
|
|
3478
|
+
* @throws AuthEnforcementDisabledError if the reactor's authEnforcement flag is off, in which case it holds no decision model and the legacy host-table permission system cannot answer for one
|
|
3333
3479
|
*/
|
|
3334
|
-
|
|
3480
|
+
evaluateActions(documentIdentifier: string, branch: string, candidates: ActionCandidate[], subject?: AuthSubject, signal?: AbortSignal): Promise<ActionEvaluations>;
|
|
3335
3481
|
/**
|
|
3336
|
-
*
|
|
3337
|
-
*
|
|
3482
|
+
* The signature policy this client gives the documents it creates when the
|
|
3483
|
+
* caller does not choose one. It never changes an existing document.
|
|
3338
3484
|
*/
|
|
3339
|
-
|
|
3485
|
+
getCreateSignaturePolicy(): Promise<SignaturePolicy>;
|
|
3340
3486
|
/**
|
|
3341
|
-
*
|
|
3342
|
-
*
|
|
3487
|
+
* Creates a document and waits for completion. The document keeps the
|
|
3488
|
+
* signature policy and id its header carries.
|
|
3343
3489
|
*
|
|
3344
|
-
* @
|
|
3490
|
+
* @param document - Document with optional id, slug, parent, model type, and initial state
|
|
3491
|
+
* @param parentIdentifier - Optional "id" or "slug" of parent document
|
|
3492
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3493
|
+
* @returns The created document
|
|
3345
3494
|
*/
|
|
3346
|
-
|
|
3347
|
-
private findNearestKeyframe;
|
|
3495
|
+
create<TDocument extends PHDocument = PHDocument>(document: PHDocument, parentIdentifier?: string, signal?: AbortSignal): Promise<TDocument>;
|
|
3348
3496
|
/**
|
|
3349
|
-
*
|
|
3497
|
+
* Creates an empty document and waits for completion
|
|
3350
3498
|
*
|
|
3351
|
-
*
|
|
3352
|
-
*
|
|
3353
|
-
*
|
|
3354
|
-
* scope has reached at that upgrade's boundary, so each one is held back and
|
|
3355
|
-
* applied when the replay below crosses the boundary that
|
|
3356
|
-
* resolveModuleVersionForOp derives from it. Upgrades whose boundary lies past
|
|
3357
|
-
* the last replayed operation are applied at the end. Creation-time 0->N seed
|
|
3358
|
-
* upgrades carry the initial state, so they still apply immediately.
|
|
3359
|
-
*/
|
|
3360
|
-
private coldMissRebuild;
|
|
3361
|
-
/**
|
|
3362
|
-
* Applies and removes every held-back upgrade whose target version is at or
|
|
3363
|
-
* below `throughVersion`, in the order the document scope recorded them.
|
|
3499
|
+
* @param documentModelType - Type of document to create
|
|
3500
|
+
* @param options - Optional creation options (parentIdentifier, documentModelVersion)
|
|
3501
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3364
3502
|
*/
|
|
3365
|
-
|
|
3503
|
+
createEmpty<TDocument extends PHDocument>(documentModelType: string, options?: CreateDocumentOptions, signal?: AbortSignal): Promise<TDocument>;
|
|
3366
3504
|
/**
|
|
3367
|
-
*
|
|
3368
|
-
*
|
|
3369
|
-
*
|
|
3370
|
-
*
|
|
3371
|
-
*
|
|
3372
|
-
*
|
|
3373
|
-
*
|
|
3374
|
-
*
|
|
3505
|
+
* Retrieves the document model module matching the version a document is
|
|
3506
|
+
* stamped with. Use this instead of {@link getDocumentModelModule}
|
|
3507
|
+
* whenever a specific document is in hand: the latest-wins lookup feeds
|
|
3508
|
+
* not-yet-upgraded documents the wrong reducer, diverging from replay.
|
|
3509
|
+
*
|
|
3510
|
+
* @param document - The document whose stamped version selects the module
|
|
3511
|
+
* @returns The document model module registered for that version
|
|
3512
|
+
* @throws UnsupportedDocumentModelVersionError if no module is registered for the stamped version
|
|
3375
3513
|
*/
|
|
3376
|
-
|
|
3514
|
+
getDocumentModelModuleForDocument(document: PHDocument): Promise<DocumentModelModule<any>>;
|
|
3377
3515
|
/**
|
|
3378
|
-
*
|
|
3379
|
-
*
|
|
3516
|
+
* Upgrades a document to a newer document model version by dispatching an
|
|
3517
|
+
* UPGRADE_DOCUMENT action. When toVersion is omitted, upgrades to the
|
|
3518
|
+
* latest registered module version for the document's type. Returns the
|
|
3519
|
+
* document unchanged when it is already at the target version.
|
|
3520
|
+
*
|
|
3521
|
+
* The action carries a snapshot of the document's version and per-scope
|
|
3522
|
+
* revisions, which the executor validates before persisting. When an edit
|
|
3523
|
+
* lands between the read and the upgrade executing, the upgrade is
|
|
3524
|
+
* rejected and retried with a fresh read up to
|
|
3525
|
+
* {@link UpgradeDocumentOptions.maxConflictRetries} times before the
|
|
3526
|
+
* conflict is surfaced.
|
|
3527
|
+
*
|
|
3528
|
+
* @param documentIdentifier - Target document id or slug
|
|
3529
|
+
* @param toVersion - Optional target document model version; defaults to latest
|
|
3530
|
+
* @param options - Optional upgrade options (maxConflictRetries)
|
|
3531
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3532
|
+
* @returns The upgraded document
|
|
3533
|
+
* @throws DowngradeNotSupportedError if toVersion is less than the document's current version
|
|
3380
3534
|
*/
|
|
3381
|
-
|
|
3535
|
+
upgradeDocument<TDocument extends PHDocument = PHDocument>(documentIdentifier: string, toVersion?: number, options?: UpgradeDocumentOptions, signal?: AbortSignal): Promise<TDocument>;
|
|
3382
3536
|
/**
|
|
3383
|
-
*
|
|
3384
|
-
*
|
|
3537
|
+
* Creates an empty document in a drive as a single batched operation.
|
|
3538
|
+
* This is more efficient than createEmpty + addFile as it batches all
|
|
3539
|
+
* actions into dependent jobs and waits for them to complete together.
|
|
3540
|
+
*
|
|
3541
|
+
* @deprecated Use {@link IDriveClient.addFile} via `client.drives.addFile`
|
|
3542
|
+
* instead. This method will be removed in a future release.
|
|
3543
|
+
* @param driveId - The drive document id or slug
|
|
3544
|
+
* @param document - The document to create
|
|
3545
|
+
* @param parentFolder - Optional folder id within the drive
|
|
3546
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3547
|
+
* @returns The created document
|
|
3385
3548
|
*/
|
|
3386
|
-
|
|
3387
|
-
/** The stored operation at `index`, or undefined if it is no longer there. */
|
|
3388
|
-
private operationAt;
|
|
3549
|
+
createDocumentInDrive<TDocument extends PHDocument>(driveId: string, document: PHDocument, parentFolder?: string, signal?: AbortSignal): Promise<TDocument>;
|
|
3389
3550
|
/**
|
|
3390
|
-
*
|
|
3551
|
+
* Applies a list of actions to a document and waits for completion
|
|
3391
3552
|
*
|
|
3392
|
-
*
|
|
3393
|
-
*
|
|
3394
|
-
*
|
|
3395
|
-
*
|
|
3553
|
+
* The document handed back is a read like any other, so it goes through the
|
|
3554
|
+
* read gate. `subject` names who that read is for, the same way
|
|
3555
|
+
* {@link ViewFilter.subject} does on `get` and `find`; a host that shares one
|
|
3556
|
+
* client across many callers has no meaningful signer to fall back to, and
|
|
3557
|
+
* without it the gate would strip the domain scopes of a policied document
|
|
3558
|
+
* and resolve with a husk whose `state.global` is absent — reading as a
|
|
3559
|
+
* rejected write when the write in fact succeeded.
|
|
3560
|
+
*
|
|
3561
|
+
* @param documentIdentifier - Target document id or slug
|
|
3562
|
+
* @param branch - Branch to apply actions to
|
|
3563
|
+
* @param actions - List of actions to apply
|
|
3564
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3565
|
+
* @param subject - Optional read subject for the returned document; defaults
|
|
3566
|
+
* to the client's signer
|
|
3567
|
+
* @returns The updated document
|
|
3396
3568
|
*/
|
|
3397
|
-
|
|
3398
|
-
private warmMissRebuild;
|
|
3399
|
-
private findNearestOlderSnapshot;
|
|
3400
|
-
private makeStreamKey;
|
|
3401
|
-
private getOrCreateStream;
|
|
3402
|
-
private isKeyframeRevision;
|
|
3403
|
-
}
|
|
3404
|
-
//#endregion
|
|
3405
|
-
//#region src/storage/kysely/store.d.ts
|
|
3406
|
-
declare class KyselyOperationStore implements IOperationStore {
|
|
3407
|
-
private db;
|
|
3408
|
-
private trx?;
|
|
3409
|
-
constructor(db: Kysely<Database$1>);
|
|
3410
|
-
private get queryExecutor();
|
|
3411
|
-
withTransaction(trx: Transaction<Database$1>): KyselyOperationStore;
|
|
3412
|
-
apply(documentId: string, documentType: string, scope: string, branch: string, revision: number, fn: (txn: AtomicTxn) => void | Promise<void>, signal?: AbortSignal, condition?: AppendCondition): Promise<Operation[]>;
|
|
3413
|
-
private resolveUniqueConstraint;
|
|
3414
|
-
private executeApply;
|
|
3569
|
+
execute<TDocument extends PHDocument>(documentIdentifier: string, branch: string, actions: Action[], signal?: AbortSignal, subject?: AuthSubject): Promise<TDocument>;
|
|
3415
3570
|
/**
|
|
3416
|
-
*
|
|
3417
|
-
*
|
|
3418
|
-
*
|
|
3419
|
-
*
|
|
3420
|
-
*
|
|
3571
|
+
* Submits a list of actions to a document
|
|
3572
|
+
*
|
|
3573
|
+
* @param documentIdentifier - Target document id or slug
|
|
3574
|
+
* @param branch - Branch to apply actions to
|
|
3575
|
+
* @param actions - List of actions to apply
|
|
3576
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3577
|
+
* @returns The job
|
|
3421
3578
|
*/
|
|
3422
|
-
|
|
3579
|
+
executeAsync(documentIdentifier: string, branch: string, actions: Action[], signal?: AbortSignal): Promise<JobInfo>;
|
|
3423
3580
|
/**
|
|
3424
|
-
*
|
|
3425
|
-
*
|
|
3426
|
-
*
|
|
3581
|
+
* Applies multiple mutation jobs in dependency order and waits for all to
|
|
3582
|
+
* complete. Actions on each job are signed by the client signer before
|
|
3583
|
+
* dispatch. Throws on the first failed job; the others may still execute
|
|
3584
|
+
* because dispatch is fire-and-await-all.
|
|
3585
|
+
*
|
|
3586
|
+
* @param request - Batch mutation request with per-job actions and dependsOn keys
|
|
3587
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3588
|
+
* @returns The completed batch result (job ids keyed by plan key)
|
|
3427
3589
|
*/
|
|
3428
|
-
|
|
3429
|
-
private findIdempotentReplay;
|
|
3430
|
-
/** True when the staged write creates a document rather than appending to one. */
|
|
3431
|
-
private isCreate;
|
|
3590
|
+
executeBatch(request: BatchExecutionRequest, signal?: AbortSignal): Promise<BatchExecutionResult>;
|
|
3432
3591
|
/**
|
|
3433
|
-
*
|
|
3434
|
-
*
|
|
3435
|
-
*
|
|
3436
|
-
*
|
|
3437
|
-
*
|
|
3438
|
-
*
|
|
3592
|
+
* Renames a document and waits for completion
|
|
3593
|
+
*
|
|
3594
|
+
* @param documentIdentifier - Target document id or slug
|
|
3595
|
+
* @param name - The new name of the document
|
|
3596
|
+
* @param branch - Optional branch to rename the document, defaults to "main"
|
|
3597
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3598
|
+
* @returns The updated document.
|
|
3439
3599
|
*/
|
|
3440
|
-
|
|
3441
|
-
getSinceId(id: number, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<OperationWithContext$1>>;
|
|
3600
|
+
rename(documentIdentifier: string, name: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
3442
3601
|
/**
|
|
3443
|
-
*
|
|
3444
|
-
*
|
|
3445
|
-
*
|
|
3446
|
-
*
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
private rowToOperationWithContext;
|
|
3453
|
-
}
|
|
3454
|
-
//#endregion
|
|
3455
|
-
//#region src/storage/kysely/keyframe-store.d.ts
|
|
3456
|
-
declare class KyselyKeyframeStore implements IKeyframeStore {
|
|
3457
|
-
private db;
|
|
3458
|
-
private trx?;
|
|
3459
|
-
constructor(db: Kysely<Database$1>);
|
|
3460
|
-
private get queryExecutor();
|
|
3461
|
-
withTransaction(trx: Transaction<Database$1>): KyselyKeyframeStore;
|
|
3462
|
-
putKeyframe(documentId: string, scope: string, branch: string, revision: number, document: PHDocument, signal?: AbortSignal): Promise<void>;
|
|
3463
|
-
findNearestKeyframe(documentId: string, scope: string, branch: string, targetRevision: number, signal?: AbortSignal): Promise<{
|
|
3464
|
-
revision: number;
|
|
3465
|
-
document: PHDocument;
|
|
3466
|
-
} | undefined>;
|
|
3467
|
-
listKeyframes(documentId: string, scope?: string, branch?: string, signal?: AbortSignal): Promise<Array<{
|
|
3468
|
-
scope: string;
|
|
3469
|
-
branch: string;
|
|
3470
|
-
revision: number;
|
|
3471
|
-
document: PHDocument;
|
|
3472
|
-
}>>;
|
|
3473
|
-
deleteKeyframes(documentId: string, scope?: string, branch?: string, signal?: AbortSignal): Promise<number>;
|
|
3474
|
-
}
|
|
3475
|
-
//#endregion
|
|
3476
|
-
//#region src/executor/execution-scope.d.ts
|
|
3477
|
-
interface ExecutionStores {
|
|
3478
|
-
operationStore: IOperationStore;
|
|
3479
|
-
operationIndex: IOperationIndex;
|
|
3480
|
-
writeCache: IWriteCache;
|
|
3481
|
-
documentMetaCache: IDocumentMetaCache;
|
|
3482
|
-
collectionMembershipCache: ICollectionMembershipCache;
|
|
3483
|
-
}
|
|
3484
|
-
interface IExecutionScope {
|
|
3485
|
-
run<T>(fn: (stores: ExecutionStores) => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
3486
|
-
}
|
|
3487
|
-
//#endregion
|
|
3488
|
-
//#region src/executor/types.d.ts
|
|
3489
|
-
/**
|
|
3490
|
-
* Represents the result of a job execution
|
|
3491
|
-
*/
|
|
3492
|
-
type JobResult = {
|
|
3493
|
-
/** The job that was executed */job: Job; /** Whether the job executed successfully */
|
|
3494
|
-
success: boolean; /** Error if the job failed */
|
|
3495
|
-
error?: Error; /** The operations generated from the actions (if successful) */
|
|
3496
|
-
operations?: Operation[];
|
|
3602
|
+
* Updates the preferred editor in the document header meta and waits for completion.
|
|
3603
|
+
*
|
|
3604
|
+
* @param documentIdentifier - Target document id or slug
|
|
3605
|
+
* @param preferredEditor - The new preferred editor, or `null` to clear it
|
|
3606
|
+
* @param branch - Optional branch, defaults to "main"
|
|
3607
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3608
|
+
* @returns The updated document.
|
|
3609
|
+
*/
|
|
3610
|
+
setPreferredEditor(documentIdentifier: string, preferredEditor: string | null, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
3497
3611
|
/**
|
|
3498
|
-
*
|
|
3499
|
-
*
|
|
3612
|
+
* Adds a relationship between two documents and waits for completion.
|
|
3613
|
+
*
|
|
3614
|
+
* Adding a relationship that already exists is a no-op, metadata included.
|
|
3615
|
+
* Use {@link IReactorClient.updateRelationship} to change an existing edge.
|
|
3616
|
+
*
|
|
3617
|
+
* @param sourceIdentifier - Source document id or slug
|
|
3618
|
+
* @param targetIdentifier - Target document id or slug
|
|
3619
|
+
* @param relationshipType - Relationship type identifier
|
|
3620
|
+
* @param metadata - Optional metadata to attach to the relationship
|
|
3621
|
+
* @param branch - Optional branch to add the relationship to, defaults to "main"
|
|
3622
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3623
|
+
* @returns The updated source document
|
|
3500
3624
|
*/
|
|
3501
|
-
|
|
3502
|
-
completedAt?: string; /** Duration of job execution in milliseconds */
|
|
3503
|
-
duration?: number; /** Any additional metadata from the execution */
|
|
3504
|
-
metadata?: Record<string, any>;
|
|
3505
|
-
};
|
|
3506
|
-
/**
|
|
3507
|
-
* Enforcement the reactor performs, each off by default.
|
|
3508
|
-
*
|
|
3509
|
-
* An evaluation made while replaying is part of the document's history, so two
|
|
3510
|
-
* reactors that share documents and disagree on these diverge. A flag is turned
|
|
3511
|
-
* on for a set of reactors that sync with each other, not for one node.
|
|
3512
|
-
*/
|
|
3513
|
-
type ReactorFeatureFlags = {
|
|
3625
|
+
addRelationship(sourceIdentifier: string, targetIdentifier: string, relationshipType: string, metadata?: Record<string, unknown>, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
3514
3626
|
/**
|
|
3515
|
-
*
|
|
3516
|
-
*
|
|
3517
|
-
*
|
|
3518
|
-
*
|
|
3627
|
+
* Replaces the metadata of an existing relationship and waits for completion.
|
|
3628
|
+
* The relationship's createdAt is preserved.
|
|
3629
|
+
*
|
|
3630
|
+
* @param sourceIdentifier - Source document id or slug
|
|
3631
|
+
* @param targetIdentifier - Target document id or slug
|
|
3632
|
+
* @param relationshipType - Relationship type identifier
|
|
3633
|
+
* @param metadata - The metadata to store; null clears it
|
|
3634
|
+
* @param branch - Optional branch holding the relationship, defaults to "main"
|
|
3635
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3636
|
+
* @returns The updated source document
|
|
3519
3637
|
*/
|
|
3520
|
-
|
|
3638
|
+
updateRelationship(sourceIdentifier: string, targetIdentifier: string, relationshipType: string, metadata: Record<string, unknown> | null, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
3521
3639
|
/**
|
|
3522
|
-
*
|
|
3523
|
-
*
|
|
3640
|
+
* Removes a relationship between two documents and waits for completion.
|
|
3641
|
+
*
|
|
3642
|
+
* @param sourceIdentifier - Source document id or slug
|
|
3643
|
+
* @param targetIdentifier - Target document id or slug
|
|
3644
|
+
* @param relationshipType - Relationship type identifier
|
|
3645
|
+
* @param branch - Optional branch to remove the relationship from, defaults to "main"
|
|
3646
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3647
|
+
* @returns The updated source document
|
|
3524
3648
|
*/
|
|
3525
|
-
|
|
3649
|
+
removeRelationship(sourceIdentifier: string, targetIdentifier: string, relationshipType: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
|
|
3526
3650
|
/**
|
|
3527
|
-
*
|
|
3528
|
-
*
|
|
3651
|
+
* Moves a relationship from one source document to another and waits for completion.
|
|
3652
|
+
*
|
|
3653
|
+
* @param sourceParentIdentifier - Source parent document id or slug
|
|
3654
|
+
* @param targetParentIdentifier - Target parent document id or slug
|
|
3655
|
+
* @param targetIdentifier - The target document id or slug
|
|
3656
|
+
* @param relationshipType - Relationship type identifier
|
|
3657
|
+
* @param branch - Optional branch to apply the move to, defaults to "main"
|
|
3658
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3659
|
+
* @returns The updated source and target documents
|
|
3529
3660
|
*/
|
|
3530
|
-
|
|
3661
|
+
moveRelationship(sourceParentIdentifier: string, targetParentIdentifier: string, targetIdentifier: string, relationshipType: string, branch?: string, signal?: AbortSignal): Promise<{
|
|
3662
|
+
source: PHDocument;
|
|
3663
|
+
target: PHDocument;
|
|
3664
|
+
}>;
|
|
3531
3665
|
/**
|
|
3532
|
-
*
|
|
3533
|
-
*
|
|
3666
|
+
* Deletes a document and waits for completion
|
|
3667
|
+
*
|
|
3668
|
+
* @param identifier - Document identifier (id or slug)
|
|
3669
|
+
* @param propagate - Optional mode for handling children, CASCADE deletes child documents
|
|
3670
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3671
|
+
* @returns a promise, resolving on deletion confirmation
|
|
3534
3672
|
*/
|
|
3535
|
-
|
|
3536
|
-
};
|
|
3537
|
-
/**
|
|
3538
|
-
* Configuration options for the job executor
|
|
3539
|
-
*/
|
|
3540
|
-
type JobExecutorConfig = {
|
|
3541
|
-
/** Feature flags; anything unset is off. */featureFlags?: Partial<ReactorFeatureFlags>; /** Maximum number of conflicting operations to skip when reshuffling. */
|
|
3542
|
-
maxSkipThreshold?: number; /** Maximum number of concurrent jobs to execute */
|
|
3543
|
-
maxConcurrency?: number; /** Maximum time in milliseconds a job can run before being considered timed out */
|
|
3544
|
-
jobTimeoutMs?: number;
|
|
3545
|
-
/** How long a job whose document is missing waits for it before failing.
|
|
3546
|
-
* Unbounded deferral never resolves the caller awaiting the job. */
|
|
3547
|
-
deferredJobTtlMs?: number; /** Base delay in milliseconds for exponential backoff retries */
|
|
3548
|
-
retryBaseDelayMs?: number; /** Maximum delay in milliseconds for exponential backoff retries */
|
|
3549
|
-
retryMaxDelayMs?: number;
|
|
3550
|
-
/** Maximum elapsed milliseconds before yielding to the main thread between actions.
|
|
3551
|
-
* Keeps the UI responsive when processing large batches. */
|
|
3552
|
-
yieldDeadlineMs?: number;
|
|
3673
|
+
deleteDocument(identifier: string, propagate?: PropagationMode, signal?: AbortSignal): Promise<void>;
|
|
3553
3674
|
/**
|
|
3554
|
-
*
|
|
3675
|
+
* Deletes documents and waits for completion
|
|
3555
3676
|
*
|
|
3556
|
-
*
|
|
3557
|
-
*
|
|
3558
|
-
*
|
|
3559
|
-
*
|
|
3560
|
-
|
|
3561
|
-
|
|
3677
|
+
* @param identifiers - Document identifiers (ids or slugs)
|
|
3678
|
+
* @param propagate - Optional mode for handling children, CASCADE deletes child documents
|
|
3679
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3680
|
+
* @returns a promise, resolving on deletion confirmation
|
|
3681
|
+
*/
|
|
3682
|
+
deleteDocuments(identifiers: string[], propagate?: PropagationMode, signal?: AbortSignal): Promise<void>;
|
|
3683
|
+
/**
|
|
3684
|
+
* Loads multiple batches of pre-existing operations across documents with dependency management.
|
|
3685
|
+
* Waits for all jobs to complete.
|
|
3562
3686
|
*
|
|
3563
|
-
*
|
|
3564
|
-
*
|
|
3565
|
-
*
|
|
3566
|
-
* rolls it back.
|
|
3567
|
-
* That guarantee belongs to KyselyExecutionScope, which backs both Postgres
|
|
3568
|
-
* and PGlite; DefaultExecutionScope opens no transaction and is used only by
|
|
3569
|
-
* unit-test harnesses, which therefore see writes survive a failed job.
|
|
3687
|
+
* @param request - Batch load request containing jobs with dependencies
|
|
3688
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3689
|
+
* @returns Map of job keys to completed job information
|
|
3570
3690
|
*/
|
|
3571
|
-
|
|
3572
|
-
};
|
|
3573
|
-
/**
|
|
3574
|
-
* Event types for the job executor
|
|
3575
|
-
*/
|
|
3576
|
-
declare const JobExecutorEventTypes: {
|
|
3577
|
-
readonly JOB_STARTED: 20000;
|
|
3578
|
-
readonly JOB_COMPLETED: 20001;
|
|
3579
|
-
readonly JOB_FAILED: 20002;
|
|
3580
|
-
readonly EXECUTOR_STARTED: 20003;
|
|
3581
|
-
readonly EXECUTOR_STOPPED: 20004;
|
|
3582
|
-
};
|
|
3583
|
-
/**
|
|
3584
|
-
* Event data for job execution events
|
|
3585
|
-
*/
|
|
3586
|
-
type JobStartedEvent = {
|
|
3587
|
-
job: Job;
|
|
3588
|
-
startedAt: string;
|
|
3691
|
+
loadBatch(request: BatchLoadRequest, signal?: AbortSignal): Promise<BatchLoadResult>;
|
|
3589
3692
|
/**
|
|
3590
|
-
*
|
|
3591
|
-
*
|
|
3592
|
-
*
|
|
3593
|
-
*
|
|
3693
|
+
* Retrieves the status of a job
|
|
3694
|
+
*
|
|
3695
|
+
* @param jobId - The job id
|
|
3696
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3697
|
+
* @returns The job status
|
|
3594
3698
|
*/
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
stoppedAt: string;
|
|
3615
|
-
graceful: boolean;
|
|
3616
|
-
};
|
|
3617
|
-
/**
|
|
3618
|
-
* Status information for the job executor manager
|
|
3619
|
-
*/
|
|
3620
|
-
type ExecutorManagerStatus = {
|
|
3621
|
-
/** Whether the manager is currently running */isRunning: boolean; /** Number of executor instances managed */
|
|
3622
|
-
numExecutors: number; /** Number of jobs currently being processed */
|
|
3623
|
-
activeJobs: number; /** Total number of jobs processed since start */
|
|
3624
|
-
totalJobsProcessed: number;
|
|
3625
|
-
};
|
|
3699
|
+
getJobStatus(jobId: string, signal?: AbortSignal): Promise<JobInfo>;
|
|
3700
|
+
/**
|
|
3701
|
+
* Waits for a job to complete
|
|
3702
|
+
*
|
|
3703
|
+
* @param jobId - The job id or job object
|
|
3704
|
+
* @param signal - Optional abort signal to cancel the request
|
|
3705
|
+
* @returns The result of the job
|
|
3706
|
+
*/
|
|
3707
|
+
waitForJob(jobId: string | JobInfo, signal?: AbortSignal): Promise<JobInfo>;
|
|
3708
|
+
/**
|
|
3709
|
+
* Subscribes to changes for documents matching specified filters
|
|
3710
|
+
*
|
|
3711
|
+
* @param search - Search filter options (type, parentId, identifiers)
|
|
3712
|
+
* @param callback - Function called when documents change with the change event details
|
|
3713
|
+
* @param view - Optional filter containing branch and scopes information
|
|
3714
|
+
* @returns A function that unsubscribes from the changes
|
|
3715
|
+
*/
|
|
3716
|
+
subscribe(search: SearchFilter, callback: (event: DocumentChangeEvent) => void, view?: ViewFilter): () => void;
|
|
3717
|
+
}
|
|
3626
3718
|
//#endregion
|
|
3627
3719
|
//#region src/decision/document-decision-model.d.ts
|
|
3628
3720
|
/** What the document decision model reads: the target's document scope. */
|
|
@@ -3890,8 +3982,9 @@ declare class ReactorClient implements IReactorClient {
|
|
|
3890
3982
|
private documentView;
|
|
3891
3983
|
private readGate;
|
|
3892
3984
|
private actionEvaluation;
|
|
3985
|
+
private readonly createSignaturePolicy;
|
|
3893
3986
|
readonly drives: IDriveClient;
|
|
3894
|
-
constructor(logger: ILogger, reactor: IReactor, signer: ISigner, subscriptionManager: IReactorSubscriptionManager, jobAwaiter: IJobAwaiter, documentIndexer: IDocumentIndexer, documentView: IDocumentView, readGate?: IReadGate, actionEvaluation?: ActionEvaluationConfig);
|
|
3987
|
+
constructor(logger: ILogger, reactor: IReactor, signer: ISigner, subscriptionManager: IReactorSubscriptionManager, jobAwaiter: IJobAwaiter, documentIndexer: IDocumentIndexer, documentView: IDocumentView, readGate?: IReadGate, actionEvaluation?: ActionEvaluationConfig, createSignaturePolicy?: SignaturePolicy);
|
|
3895
3988
|
private readSubject;
|
|
3896
3989
|
/**
|
|
3897
3990
|
* Which scopes of one document the subject may read. Resolved once per
|
|
@@ -4017,6 +4110,7 @@ declare class ReactorClient implements IReactorClient {
|
|
|
4017
4110
|
* is why the answer is a prediction.
|
|
4018
4111
|
*/
|
|
4019
4112
|
private buildEvaluationTarget;
|
|
4113
|
+
getCreateSignaturePolicy(): Promise<SignaturePolicy>;
|
|
4020
4114
|
/**
|
|
4021
4115
|
* Creates a document and waits for completion
|
|
4022
4116
|
*/
|
|
@@ -4056,6 +4150,12 @@ declare class ReactorClient implements IReactorClient {
|
|
|
4056
4150
|
* Submits a list of actions to a document
|
|
4057
4151
|
*/
|
|
4058
4152
|
executeAsync(documentIdentifier: string, branch: string, actions: Action[], signal?: AbortSignal): Promise<JobInfo>;
|
|
4153
|
+
/**
|
|
4154
|
+
* The id a write on `identifier` is stored under, which its signatures bind.
|
|
4155
|
+
* A create names its own id, and an id no slug maps to is taken as given, so
|
|
4156
|
+
* a document still in flight resolves to itself.
|
|
4157
|
+
*/
|
|
4158
|
+
private resolveWriteTarget;
|
|
4059
4159
|
executeBatch(request: BatchExecutionRequest, signal?: AbortSignal): Promise<BatchExecutionResult>;
|
|
4060
4160
|
/**
|
|
4061
4161
|
* Renames a document and waits for completion
|
|
@@ -4128,6 +4228,7 @@ type WorkerInFlightSnapshot = {
|
|
|
4128
4228
|
type WorkerExecutionOutcome = {
|
|
4129
4229
|
result: JobResult;
|
|
4130
4230
|
writeReady?: JobWriteReadyPayload;
|
|
4231
|
+
signatureRefusals?: SignatureRefusedEvent[];
|
|
4131
4232
|
};
|
|
4132
4233
|
/**
|
|
4133
4234
|
* Parent-side handle for a single executor worker.
|
|
@@ -5996,22 +6097,6 @@ declare class HybridProjectionCoordinator implements ILiveReadModelCoordinator {
|
|
|
5996
6097
|
private queueKeyFor;
|
|
5997
6098
|
}
|
|
5998
6099
|
//#endregion
|
|
5999
|
-
//#region src/signer/types.d.ts
|
|
6000
|
-
/**
|
|
6001
|
-
* Configuration for signing and verification.
|
|
6002
|
-
*/
|
|
6003
|
-
type SignerConfig = {
|
|
6004
|
-
/**
|
|
6005
|
-
* The signer used to sign actions before submission.
|
|
6006
|
-
*/
|
|
6007
|
-
signer: ISigner;
|
|
6008
|
-
/**
|
|
6009
|
-
* Optional handler for verifying signatures on incoming operations.
|
|
6010
|
-
* If not provided, signature verification will be skipped.
|
|
6011
|
-
*/
|
|
6012
|
-
verifier?: SignatureVerificationHandler;
|
|
6013
|
-
};
|
|
6014
|
-
//#endregion
|
|
6015
6100
|
//#region src/storage/migrations/types.d.ts
|
|
6016
6101
|
type MigrationStrategy = "auto" | "manual" | "none";
|
|
6017
6102
|
interface MigrationResult {
|
|
@@ -6095,12 +6180,6 @@ interface ReadModelCoordinatorFactoryDeps {
|
|
|
6095
6180
|
type ReadModelCoordinatorFactory = (deps: ReadModelCoordinatorFactoryDeps) => IReadModelCoordinator | Promise<IReadModelCoordinator>;
|
|
6096
6181
|
type WorkerPoolBase = {
|
|
6097
6182
|
/** Number of worker threads to spawn; also the sticky-routing modulus. */numWorkers: number;
|
|
6098
|
-
/**
|
|
6099
|
-
* Factory spec the default transport's workers import to instantiate
|
|
6100
|
-
* their signature verifier. Omitted = no executor-side verification,
|
|
6101
|
-
* parity with the in-process executor's default.
|
|
6102
|
-
*/
|
|
6103
|
-
verifier?: SignatureVerifierSpec;
|
|
6104
6183
|
};
|
|
6105
6184
|
/**
|
|
6106
6185
|
* Executor worker-pool configuration. Either `db` (default thread
|
|
@@ -6165,8 +6244,11 @@ declare class ReactorBuilder {
|
|
|
6165
6244
|
private eventBus?;
|
|
6166
6245
|
private readModelCoordinator?;
|
|
6167
6246
|
private readModelCoordinatorFactory?;
|
|
6168
|
-
private signatureVerifier?;
|
|
6169
6247
|
private kyselyInstance?;
|
|
6248
|
+
private signer?;
|
|
6249
|
+
private workerSigner?;
|
|
6250
|
+
private trustPolicy?;
|
|
6251
|
+
private workerTrustPolicy?;
|
|
6170
6252
|
private signalHandlersEnabled;
|
|
6171
6253
|
private queueInstance?;
|
|
6172
6254
|
private channelScheme?;
|
|
@@ -6214,7 +6296,22 @@ declare class ReactorBuilder {
|
|
|
6214
6296
|
withMigrationStrategy(strategy: MigrationStrategy): this;
|
|
6215
6297
|
withSync(syncBuilder: SyncBuilder): this;
|
|
6216
6298
|
withEventBus(eventBus: IEventBus): this;
|
|
6217
|
-
|
|
6299
|
+
/**
|
|
6300
|
+
* Signs the operations the executor synthesizes: the NOOP an UNDO becomes and
|
|
6301
|
+
* the action a REDO rebuilds. Without one they are stored unsigned. Pooled
|
|
6302
|
+
* workers import `workerSigner` to build the same signer.
|
|
6303
|
+
*/
|
|
6304
|
+
withSigner(signer: ISigner, workerSigner?: FactorySpec): this;
|
|
6305
|
+
/** Whether {@link withSigner} was called. */
|
|
6306
|
+
hasSigner(): boolean;
|
|
6307
|
+
/**
|
|
6308
|
+
* Decides at admission whether a key may sign as the user it claims; see
|
|
6309
|
+
* {@link SignatureTrustPolicy} for the contract and the default. Pooled
|
|
6310
|
+
* workers import `workerTrustPolicy` to build the same policy.
|
|
6311
|
+
*/
|
|
6312
|
+
withTrustPolicy(trustPolicy: SignatureTrustPolicy, workerTrustPolicy?: FactorySpec): this;
|
|
6313
|
+
/** Whether {@link withTrustPolicy} was called. */
|
|
6314
|
+
hasTrustPolicy(): boolean;
|
|
6218
6315
|
withKysely(kysely: Kysely<Database>): this;
|
|
6219
6316
|
/**
|
|
6220
6317
|
* Register an externally-constructed pg.Pool's {@link PoolInstrumentation}
|
|
@@ -6244,8 +6341,7 @@ declare class ReactorBuilder {
|
|
|
6244
6341
|
* this enables the pool — there is no `enabled` flag. Provide `db`
|
|
6245
6342
|
* (each worker opens its own Postgres pool; the parent database is built
|
|
6246
6343
|
* from it too unless {@link withKysely} is set) or a custom `factory`
|
|
6247
|
-
* transport.
|
|
6248
|
-
* omitted = no executor-side signature verification.
|
|
6344
|
+
* transport.
|
|
6249
6345
|
*/
|
|
6250
6346
|
withWorkerPool(options: WorkerPoolOptions): this;
|
|
6251
6347
|
/**
|
|
@@ -6331,7 +6427,10 @@ declare class ReactorClientBuilder {
|
|
|
6331
6427
|
private documentIndexer?;
|
|
6332
6428
|
private documentView?;
|
|
6333
6429
|
private signer?;
|
|
6334
|
-
private
|
|
6430
|
+
private workerSigner?;
|
|
6431
|
+
private trustPolicy?;
|
|
6432
|
+
private workerTrustPolicy?;
|
|
6433
|
+
private createSignaturePolicy;
|
|
6335
6434
|
private subscriptionManager?;
|
|
6336
6435
|
private jobAwaiter?;
|
|
6337
6436
|
private documentModelLoader?;
|
|
@@ -6351,11 +6450,17 @@ declare class ReactorClientBuilder {
|
|
|
6351
6450
|
*/
|
|
6352
6451
|
withReactor(reactor: IReactor, eventBus: IEventBus, documentIndexer: IDocumentIndexer, documentView: IDocumentView): this;
|
|
6353
6452
|
/**
|
|
6354
|
-
*
|
|
6355
|
-
*
|
|
6356
|
-
*
|
|
6453
|
+
* Signs submitted actions, and the operations a reactor built from
|
|
6454
|
+
* `withReactorBuilder` synthesizes unless that builder has its own signer.
|
|
6455
|
+
* A `trustPolicy` reaches that builder unless it has its own.
|
|
6357
6456
|
*/
|
|
6358
6457
|
withSigner(config: ISigner | SignerConfig): this;
|
|
6458
|
+
/**
|
|
6459
|
+
* What the client creates new documents as when a call does not say:
|
|
6460
|
+
* `v2-required` (the default) or `legacy`, for a fleet with peers that
|
|
6461
|
+
* predate v2-required documents. Existing documents keep their policy.
|
|
6462
|
+
*/
|
|
6463
|
+
withCreateSignaturePolicy(policy: SignaturePolicy): this;
|
|
6359
6464
|
withSubscriptionManager(subscriptionManager: IReactorSubscriptionManager): this;
|
|
6360
6465
|
withJobAwaiter(jobAwaiter: IJobAwaiter): this;
|
|
6361
6466
|
withDocumentModelLoader(loader: IDocumentModelLoader): this;
|
|
@@ -6465,6 +6570,14 @@ declare function parseDriveUrl(url: string): ParsedDriveUrl;
|
|
|
6465
6570
|
declare function driveIdFromUrl(url: string): string;
|
|
6466
6571
|
//#endregion
|
|
6467
6572
|
//#region src/shared/errors.d.ts
|
|
6573
|
+
/** The message carries the code: only name and message cross the queue. */
|
|
6574
|
+
declare class InvalidSignatureError extends Error {
|
|
6575
|
+
readonly documentId: string;
|
|
6576
|
+
readonly code: SignatureRefusalCode;
|
|
6577
|
+
readonly reason: string;
|
|
6578
|
+
constructor(documentId: string, code: SignatureRefusalCode, reason: string);
|
|
6579
|
+
static isError(error: unknown): error is InvalidSignatureError;
|
|
6580
|
+
}
|
|
6468
6581
|
/**
|
|
6469
6582
|
* An authorization preflight was asked for while the reactor's decision model
|
|
6470
6583
|
* is off, so there is no model to answer from.
|
|
@@ -6523,6 +6636,20 @@ type ParsedPaging = {
|
|
|
6523
6636
|
*/
|
|
6524
6637
|
declare function parsePagingOptions(paging: PagingOptions | undefined, defaultLimit: number): ParsedPaging;
|
|
6525
6638
|
//#endregion
|
|
6639
|
+
//#region src/signer/verify-action-signature.d.ts
|
|
6640
|
+
type VerificationTarget = {
|
|
6641
|
+
/** The stream the operation is stored in. */documentId: string;
|
|
6642
|
+
branch: string; /** Of the document `documentId` names; legacy when omitted. */
|
|
6643
|
+
policy?: SignaturePolicy;
|
|
6644
|
+
};
|
|
6645
|
+
/**
|
|
6646
|
+
* Integrity only: identity binding and the live-id check sit with the caller.
|
|
6647
|
+
* `operation` is the incoming operation at load admission.
|
|
6648
|
+
*/
|
|
6649
|
+
declare function verifyActionSignature(action: Action, target: VerificationTarget, path: AdmissionPath, operation?: {
|
|
6650
|
+
timestampUtcMs: string;
|
|
6651
|
+
}): Promise<SignatureVerdict>;
|
|
6652
|
+
//#endregion
|
|
6526
6653
|
//#region src/subs/default-error-handler.d.ts
|
|
6527
6654
|
/**
|
|
6528
6655
|
* Default error handler that re-throws subscription errors.
|
|
@@ -6761,10 +6888,15 @@ declare class SimpleJobExecutor implements IJobExecutor {
|
|
|
6761
6888
|
private config;
|
|
6762
6889
|
private featureFlags;
|
|
6763
6890
|
private decisionModel;
|
|
6764
|
-
private
|
|
6891
|
+
private signatureAdmission;
|
|
6765
6892
|
private documentActionHandler;
|
|
6766
6893
|
private executionScope;
|
|
6767
|
-
|
|
6894
|
+
private signer;
|
|
6895
|
+
/**
|
|
6896
|
+
* `signer` signs the operations the reducer synthesizes; unsigned if omitted.
|
|
6897
|
+
* `trustPolicy` decides which keys may sign as which users at admission.
|
|
6898
|
+
*/
|
|
6899
|
+
constructor(logger: ILogger, registry: IDocumentModelRegistry, operationStore: IOperationStore, eventBus: IEventBus, writeCache: IWriteCache, operationIndex: IOperationIndex, documentMetaCache: IDocumentMetaCache, collectionMembershipCache: ICollectionMembershipCache, driveContainerTypes: ReadonlySet<string>, config: JobExecutorConfig, executionScope?: IExecutionScope, signer?: ISigner, trustPolicy?: SignatureTrustPolicy);
|
|
6768
6900
|
/**
|
|
6769
6901
|
* Execute a single job by applying all its actions through the appropriate reducers.
|
|
6770
6902
|
* Actions are processed sequentially in order.
|
|
@@ -6794,6 +6926,18 @@ declare class SimpleJobExecutor implements IJobExecutor {
|
|
|
6794
6926
|
* has not committed yet has nothing to announce.
|
|
6795
6927
|
*/
|
|
6796
6928
|
private executeInScope;
|
|
6929
|
+
/**
|
|
6930
|
+
* A successful mutation's result and the write-ready event it owes, carrying
|
|
6931
|
+
* what earlier attempts committed ahead of what this one wrote.
|
|
6932
|
+
*/
|
|
6933
|
+
private committedOutcome;
|
|
6934
|
+
/**
|
|
6935
|
+
* The stored operations of writes an earlier attempt committed, as a fresh
|
|
6936
|
+
* write would report them. State is rebuilt from the write cache, and left
|
|
6937
|
+
* out when it cannot be.
|
|
6938
|
+
*/
|
|
6939
|
+
private reloadCommitted;
|
|
6940
|
+
private rebuiltState;
|
|
6797
6941
|
/**
|
|
6798
6942
|
* Drops the cached state of every stream a job wrote, after its transaction
|
|
6799
6943
|
* did not commit.
|
|
@@ -6842,7 +6986,7 @@ declare class SimpleJobExecutor implements IJobExecutor {
|
|
|
6842
6986
|
* apply and its own reasons for it.
|
|
6843
6987
|
* - A positional or replayed run carries skips and re-appended operations,
|
|
6844
6988
|
* whose indices are not a simple ascending run from the head.
|
|
6845
|
-
* - UNDO, REDO
|
|
6989
|
+
* - UNDO, REDO and NOOP-with-skip each invalidate the write cache to
|
|
6846
6990
|
* force a full-history rebuild, so they cannot be reduced against state
|
|
6847
6991
|
* threaded from the write before them.
|
|
6848
6992
|
* - The auth scope decides later writes against the policy earlier ones
|
|
@@ -6943,6 +7087,8 @@ declare class SimpleJobExecutor implements IJobExecutor {
|
|
|
6943
7087
|
*/
|
|
6944
7088
|
private executeReevaluationJob;
|
|
6945
7089
|
private executeLoadJob;
|
|
7090
|
+
/** The conflicting window a load opens, and which of its operations are new. */
|
|
7091
|
+
private selectLoadWrites;
|
|
6946
7092
|
private accumulateResultOrReturnError;
|
|
6947
7093
|
}
|
|
6948
7094
|
//#endregion
|
|
@@ -7727,26 +7873,26 @@ declare class DocumentIntegrityService implements IDocumentIntegrityService {
|
|
|
7727
7873
|
}
|
|
7728
7874
|
//#endregion
|
|
7729
7875
|
//#region src/processors/processor-manager.d.ts
|
|
7876
|
+
type PendingSlot = {
|
|
7877
|
+
factoryId: string;
|
|
7878
|
+
driveId: string;
|
|
7879
|
+
reservedAt: number;
|
|
7880
|
+
lowestRoutedOrdinal: number | undefined;
|
|
7881
|
+
settled: Promise<void> | undefined;
|
|
7882
|
+
};
|
|
7883
|
+
type FactoryRun = () => Promise<void>;
|
|
7730
7884
|
type ProcessorManagerOptions = {
|
|
7731
7885
|
legacyProcessorIds?: boolean;
|
|
7732
7886
|
};
|
|
7733
|
-
/**
|
|
7734
|
-
* Manages processor lifecycle based on operations.
|
|
7735
|
-
* Extends BaseReadModel to receive operations from ReadModelCoordinator.
|
|
7736
|
-
*
|
|
7737
|
-
* Responsibilities:
|
|
7738
|
-
* 1. Detect drive creation from CREATE_DOCUMENT operations
|
|
7739
|
-
* 2. Create processors for each drive using registered factories
|
|
7740
|
-
* 3. Route operations to matching processors based on filters
|
|
7741
|
-
* 4. Clean up processors when drives are deleted or factories are unregistered
|
|
7742
|
-
* 5. Track per-processor cursors for failure recovery and backfill
|
|
7743
|
-
*/
|
|
7744
7887
|
declare class ProcessorManager extends BaseReadModel implements IProcessorManager$1 {
|
|
7745
7888
|
private factoryRegistry;
|
|
7746
7889
|
private processorsByDrive;
|
|
7747
|
-
private
|
|
7890
|
+
private pendingSlots;
|
|
7748
7891
|
private knownDrives;
|
|
7892
|
+
private highestRoutedOrdinal;
|
|
7749
7893
|
private cursorCache;
|
|
7894
|
+
private cursorWrites;
|
|
7895
|
+
private draining;
|
|
7750
7896
|
private logger;
|
|
7751
7897
|
private driveContainerTypes;
|
|
7752
7898
|
private legacyProcessorIds;
|
|
@@ -7757,23 +7903,36 @@ declare class ProcessorManager extends BaseReadModel implements IProcessorManage
|
|
|
7757
7903
|
unregisterFactory(identifier: string): Promise<void>;
|
|
7758
7904
|
get(processorId: string): TrackedProcessor$1 | undefined;
|
|
7759
7905
|
getAll(): TrackedProcessor$1[];
|
|
7906
|
+
/** Synchronous: reserves a slot per registered factory for each new drive. */
|
|
7907
|
+
protected detectNewDrives(items: OperationWithContext$1[]): {
|
|
7908
|
+
runs: FactoryRun[];
|
|
7909
|
+
reserved: Set<PendingSlot>;
|
|
7910
|
+
};
|
|
7911
|
+
/** Synchronous: drops a deleted drive's processors from the tables. */
|
|
7912
|
+
protected detectDeletedDrives(items: OperationWithContext$1[]): Promise<void>[];
|
|
7913
|
+
/** Synchronous: puts each processor's share of the batch on its queue. */
|
|
7914
|
+
protected enqueueRouted(items: OperationWithContext$1[], reserved: ReadonlySet<PendingSlot>): Promise<void>[];
|
|
7915
|
+
/** Synchronous: binds records, or discards them if the slot was cancelled. */
|
|
7916
|
+
protected bind(slot: PendingSlot, records: ProcessorRecord$1[] | undefined, creationOrdinal: number, creationItems: OperationWithContext$1[] | undefined): {
|
|
7917
|
+
persisted: Promise<void>;
|
|
7918
|
+
delivered: Promise<void>;
|
|
7919
|
+
};
|
|
7920
|
+
/** Synchronous: removes a factory's slots, processors and cursor rows. */
|
|
7921
|
+
protected removeFactory(identifier: string): Promise<void>[];
|
|
7922
|
+
private reserveSlot;
|
|
7923
|
+
private runFactory;
|
|
7924
|
+
private track;
|
|
7925
|
+
private discard;
|
|
7926
|
+
private highWater;
|
|
7927
|
+
private allBound;
|
|
7760
7928
|
private allTrackedProcessors;
|
|
7761
|
-
private detectAndRegisterNewDrives;
|
|
7762
7929
|
private isDriveCreation;
|
|
7763
|
-
private detectAndCleanupDeletedDrives;
|
|
7764
7930
|
private discoverExistingDrives;
|
|
7765
|
-
private isDeletedDocumentADrive;
|
|
7766
|
-
private createProcessorsForDrive;
|
|
7767
|
-
private backfillProcessor;
|
|
7768
|
-
private retryProcessor;
|
|
7769
|
-
private cleanupDriveProcessors;
|
|
7770
|
-
private safeDisconnect;
|
|
7771
|
-
private routeOperationsToProcessors;
|
|
7772
7931
|
private loadAllCursors;
|
|
7773
|
-
private
|
|
7774
|
-
private
|
|
7775
|
-
private
|
|
7932
|
+
private lane;
|
|
7933
|
+
private writeCursor;
|
|
7934
|
+
private deleteCursors;
|
|
7776
7935
|
}
|
|
7777
7936
|
//#endregion
|
|
7778
|
-
export { ALWAYS_READABLE_SCOPES, APPEND_CONDITION_FAILED_PREFIX, type AbortMessage, type ActionCandidate, type ActionEvaluationConfig, type ActionEvaluations, type AdmissionDecision, type AppendCondition, AppendConditionFailedError, type AppendConditionStream, type AtomicTxn, type AttachmentHash, type AttachmentRef, type AuthDecisionModel, AuthEnforcementDisabledError, BareReadGate, BaseReadModel, type BaseReadModelConfig, 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_COMMIT_CHUNK_SIZE, DEFAULT_DRIVE_CONTAINER_TYPES, DEFAULT_READ_MODEL_YIELD_DEADLINE_MS, DOCUMENT_INDEXER_READ_MODEL, DOCUMENT_VIEW_READ_MODEL, DRIVE_AUTH_ERROR_MESSAGES, type Database, type DbConfig, type DeadLetterAddedEvent, type DecisionContext, type DecisionModel, type DecisionTarget, DefaultSubscriptionErrorHandler, type DegradedComponent, DeletedDocumentRead, DocumentAlreadyExistsError, type DocumentChangeEvent, DocumentChangeType, type DocumentDecisionModel, DocumentExistence, type DocumentGraphEdge, type DocumentIndexerDatabase, DocumentIntegrityService, DocumentModelRegistry, DocumentModelResolver, type DocumentModelSource, type DocumentModelSpec, type DocumentRelationship, type DocumentRevisions, type DocumentStreamKey, type DocumentViewDatabase, DriveClient, DriveCollectionId, DriveRequestError, 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, HybridProjectionCoordinator, type HybridProjectionCoordinatorOptions, type HybridProjectionOptions, 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 IProcessorHostModuleBase, type IProcessorManager, type IProjectionTransport, type IQueue, type IReactor, type IReactorClient, type IReactorProcessorHostModuleBase, 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 JobResultSummary, 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 ProjectionShardHooks, type ProjectionShardManagerConfig, type ProjectionWorkerFactory, PropagationMode, QueueEventTypes, REACTOR_SCHEMA, RECOVERABLE_GRAPHQL_ERROR_CODES, Reactor, ReactorBuilder, ReactorClient, ReactorClientBuilder, type ReactorClientModule, ReactorEventTypes, type ReactorFeatureFlags, type ReactorFeatures, type ReactorHostModuleBaseOptions, type JobFailedEvent$1 as ReactorJobFailedEvent, type ReactorModule, type ReactorReadModels, ReactorSubscriptionManager, type ReadGateOptions, type ReadModelBatchCompletedEvent, ReadModelCoordinator, type ReadModelCoordinatorFactory, type ReadModelCoordinatorFactoryDeps, type ReadModelFactory, type ReadModelFactoryDeps, type ReadModelIndexedEvent, type ReadModelIndexingConfig, type ReadModelIndexingStage, type ReadModelRegistrationStage, type ReadModelStage, type ReadyMessage, type RebuildResult, type RegisteredDecisionModel, RelationalDbProcessor, RelationshipChangeType, RelationshipNotFoundError, type Remote, type RemoteCursor, type RemoteFilter, type RemoteMeta, type RemoteOptions, type RemoteRecord, type RemoteStatus, type ResultMessage, RetryAccounting, RevisionMismatchError, type SanitizedArg, type SearchFilter, SeededStateReader, type ShutdownMessage, type ShutdownStatus, type SignatureVerificationHandler, type
|
|
7937
|
+
export { ALWAYS_READABLE_SCOPES, APPEND_CONDITION_FAILED_PREFIX, type AbortMessage, type ActionCandidate, type ActionEvaluationConfig, type ActionEvaluations, type AdmissionDecision, type AdmissionPath, type AppendCondition, AppendConditionFailedError, type AppendConditionStream, type AtomicTxn, type AttachmentHash, type AttachmentRef, type AuthDecisionModel, AuthEnforcementDisabledError, BareReadGate, BaseReadModel, type BaseReadModelConfig, 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_COMMIT_CHUNK_SIZE, DEFAULT_DRIVE_CONTAINER_TYPES, DEFAULT_READ_MODEL_YIELD_DEADLINE_MS, DOCUMENT_INDEXER_READ_MODEL, DOCUMENT_VIEW_READ_MODEL, DRIVE_AUTH_ERROR_MESSAGES, type Database, type DbConfig, type DeadLetterAddedEvent, type DecisionContext, type DecisionModel, type DecisionTarget, DefaultSubscriptionErrorHandler, type DegradedComponent, DeletedDocumentRead, DocumentAlreadyExistsError, type DocumentChangeEvent, DocumentChangeType, type DocumentDecisionModel, DocumentExistence, type DocumentGraphEdge, type DocumentIndexerDatabase, DocumentIntegrityService, DocumentModelRegistry, DocumentModelResolver, type DocumentModelSource, type DocumentModelSpec, type DocumentRelationship, type DocumentRevisions, type DocumentStreamKey, type DocumentViewDatabase, DriveClient, DriveCollectionId, DriveRequestError, 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, HybridProjectionCoordinator, type HybridProjectionCoordinatorOptions, type HybridProjectionOptions, 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 IProcessorHostModuleBase, type IProcessorManager, type IProjectionTransport, type IQueue, type IReactor, type IReactorClient, type IReactorProcessorHostModuleBase, 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, InvalidSignatureError, type Job, type JobAvailableEvent, JobAwaiter, type JobCompletedEvent, type JobExecutorConfig, JobExecutorEventTypes, type JobExecutorFactory, type JobFailedEvent, type JobInfo, type JobPendingEvent, type JobReadReadyEvent, type JobResult, type JobResultSummary, 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 ProjectionShardHooks, type ProjectionShardManagerConfig, type ProjectionWorkerFactory, PropagationMode, QueueEventTypes, REACTOR_SCHEMA, RECOVERABLE_GRAPHQL_ERROR_CODES, Reactor, ReactorBuilder, ReactorClient, ReactorClientBuilder, type ReactorClientModule, ReactorEventTypes, type ReactorFeatureFlags, type ReactorFeatures, type ReactorHostModuleBaseOptions, type JobFailedEvent$1 as ReactorJobFailedEvent, type ReactorModule, type ReactorReadModels, ReactorSubscriptionManager, type ReadGateOptions, type ReadModelBatchCompletedEvent, ReadModelCoordinator, type ReadModelCoordinatorFactory, type ReadModelCoordinatorFactoryDeps, type ReadModelFactory, type ReadModelFactoryDeps, type ReadModelIndexedEvent, type ReadModelIndexingConfig, type ReadModelIndexingStage, type ReadModelRegistrationStage, type ReadModelStage, type ReadyMessage, type RebuildResult, type RegisteredDecisionModel, RelationalDbProcessor, RelationshipChangeType, RelationshipNotFoundError, type Remote, type RemoteCursor, type RemoteFilter, type RemoteMeta, type RemoteOptions, type RemoteRecord, type RemoteStatus, type ResultMessage, RetryAccounting, RevisionMismatchError, SIGNATURE_REFUSAL_CODES, type SanitizedArg, type SearchFilter, SeededStateReader, type ShutdownMessage, type ShutdownStatus, type SignatureRefusalCode, type SignatureRefusedEvent, type SignatureScheme, type SignatureTrustPolicy, type SignatureVerificationHandler, type SignatureVerificationMode, type SignerConfig, SimpleJobExecutorManager, type SnapshotValidationIssue, type Database$1 as StorageDatabase, type StreamOrderIssue, type StreamQuery, type SubmittedActionResult, type SubscriptionErrorContext, SyncBuilder, type SyncEnvelope, type SyncEnvelopeType, SyncEventTypes, type SyncFailedEvent, type SyncModule, SyncOperation, SyncOperationAggregateError, type SyncOperationErrorType, SyncOperationStatus, type SyncPendingEvent, SyncScopeGate, SyncStatus, type SyncStatusChangeCallback, SyncStatusTracker, type SyncSucceededEvent, type TrackedProcessor, type Unsubscribe, type ValidationResult, type VerificationTarget, type ViewFilter, type ErrorInfo as WorkerErrorInfo, type WorkerMessage, type WorkerPoolConfig, type WorkerPoolOptions, type WriteCacheConfig, addRelationshipAction, authDecisionModel, batchOperationsByDocument, buildDecisionModel, classifyJobFailure, consolidateSyncOperations, createDocumentAction, createForwardingLogger, createHybridProjectionCoordinatorFactory, createMutableShutdownStatus, createReactorHostModuleBase, createRelationalDb, decideAtHead, defaultReadModelIndexingConfig, deleteDocumentAction, documentActions, documentDecisionModel, driveIdFromUrl, envelopesToSyncOperations, errorToInfo, firstOutOfOrderPair, getMigrationStatus, instrumentPgPool, isDriveAuthError, isRecoverableGraphQLError, makeConsistencyKey, parseDriveUrl, parsePagingOptions, quarantinesDocument, readDecisionModel, removeRelationshipAction, runMigrations, sanitizeArg, selectDecisionModel, supportsLiveReadModelRegistration, syncOperationErrorType, trimMailboxFromAckOrdinal, unchunkedReadModelIndexingConfig, updateRelationshipAction, upgradeDocumentAction, verifyActionSignature, workerEntryPath };
|
|
7779
7938
|
//# sourceMappingURL=index.d.ts.map
|