@powerhousedao/reactor 6.2.2-dev.49 → 6.2.2-dev.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2065,157 +2065,6 @@ interface IReactorClient {
2065
2065
  subscribe(search: SearchFilter, callback: (event: DocumentChangeEvent) => void, view?: ViewFilter): () => void;
2066
2066
  }
2067
2067
  //#endregion
2068
- //#region src/client/reactor-client.d.ts
2069
- /**
2070
- * ReactorClient implementation that wraps lower-level APIs to provide
2071
- * a simpler interface for document operations.
2072
- *
2073
- * Features:
2074
- * - Wraps Jobs with Promises for easier async handling
2075
- * - Manages signing of submitted Action objects
2076
- * - Provides quality-of-life functions for common tasks
2077
- * - Wraps subscription interface with ViewFilters
2078
- */
2079
- declare class ReactorClient implements IReactorClient {
2080
- private logger;
2081
- private reactor;
2082
- private signer;
2083
- private subscriptionManager;
2084
- private jobAwaiter;
2085
- private documentIndexer;
2086
- private documentView;
2087
- readonly drives: IDriveClient;
2088
- constructor(logger: ILogger, reactor: IReactor, signer: ISigner, subscriptionManager: IReactorSubscriptionManager, jobAwaiter: IJobAwaiter, documentIndexer: IDocumentIndexer, documentView: IDocumentView);
2089
- private readSubject;
2090
- /**
2091
- * Retrieves a list of document model modules.
2092
- */
2093
- getDocumentModelModules(namespace?: string, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<DocumentModelModule>>;
2094
- /**
2095
- * Retrieves a specific document model module by document type.
2096
- *
2097
- * @param documentType - The document type identifier
2098
- * @returns The document model module
2099
- */
2100
- getDocumentModelModule(documentType: string): Promise<DocumentModelModule<any>>;
2101
- /**
2102
- * Retrieves the document model module matching the version the document is
2103
- * stamped with, so not-yet-upgraded documents get the reducer their
2104
- * history was written with rather than the latest.
2105
- */
2106
- getDocumentModelModuleForDocument(document: PHDocument): Promise<DocumentModelModule<any>>;
2107
- /**
2108
- * Retrieves a specific PHDocument
2109
- */
2110
- get<TDocument extends PHDocument>(identifier: string, view?: ViewFilter, signal?: AbortSignal): Promise<TDocument>;
2111
- /**
2112
- * Resolves an identifier (id or slug) to the canonical document id, using the
2113
- * same lookup as the data path. Resolves against the "main" branch. Throws if
2114
- * the identifier cannot be resolved or is ambiguous.
2115
- */
2116
- resolveIdOrSlug(identifier: string, view?: ViewFilter, signal?: AbortSignal): Promise<string>;
2117
- /**
2118
- * Retrieves operations for a document
2119
- */
2120
- getOperations(documentIdentifier: string, view?: ViewFilter, filter?: OperationFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<Operation>>;
2121
- private getOperationsWithCompositeCursor;
2122
- /**
2123
- * Retrieves outgoing relationships of a given type from a source document.
2124
- */
2125
- getOutgoingRelationships(sourceIdentifier: string, relationshipType: string, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
2126
- /**
2127
- * Retrieves incoming relationships of a given type to a target document.
2128
- */
2129
- getIncomingRelationships(targetIdentifier: string, relationshipType: string, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
2130
- /**
2131
- * Filters documents by criteria and returns a list of them
2132
- */
2133
- find(search: SearchFilter, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
2134
- /**
2135
- * Creates a document and waits for completion
2136
- */
2137
- create<TDocument extends PHDocument = PHDocument>(document: PHDocument, parentIdentifier?: string, signal?: AbortSignal): Promise<TDocument>;
2138
- /**
2139
- * Creates an empty document and waits for completion
2140
- */
2141
- createEmpty<TDocument extends PHDocument>(documentModelType: string, options?: CreateDocumentOptions, signal?: AbortSignal): Promise<TDocument>;
2142
- /**
2143
- * Upgrades a document to a newer document model version by dispatching an
2144
- * UPGRADE_DOCUMENT action. When toVersion is omitted, upgrades to the
2145
- * latest registered module version for the document's type. Returns the
2146
- * document unchanged when it is already at the target version.
2147
- *
2148
- * The executor validates the action's version and revision snapshot against
2149
- * the state the migration actually runs on. When a concurrent edit
2150
- * invalidates the snapshot, the upgrade is rebuilt from a fresh read and
2151
- * retried up to maxConflictRetries times before the conflict is surfaced.
2152
- */
2153
- upgradeDocument<TDocument extends PHDocument = PHDocument>(documentIdentifier: string, toVersion?: number, options?: UpgradeDocumentOptions, signal?: AbortSignal): Promise<TDocument>;
2154
- /**
2155
- * Creates an empty document in a drive as a single batched operation.
2156
- * Delegates to {@link IDriveClient.addFile}.
2157
- *
2158
- * @deprecated Use `client.drives.addFile` instead. This method will be
2159
- * removed in a future release.
2160
- */
2161
- createDocumentInDrive<TDocument extends PHDocument>(driveId: string, document: PHDocument, parentFolder?: string, signal?: AbortSignal): Promise<TDocument>;
2162
- /**
2163
- * Applies a list of actions to a document and waits for completion
2164
- */
2165
- execute<TDocument extends PHDocument>(documentIdentifier: string, branch: string, actions: Action[], signal?: AbortSignal): Promise<TDocument>;
2166
- /**
2167
- * Submits a list of actions to a document
2168
- */
2169
- executeAsync(documentIdentifier: string, branch: string, actions: Action[], signal?: AbortSignal): Promise<JobInfo>;
2170
- executeBatch(request: BatchExecutionRequest, signal?: AbortSignal): Promise<BatchExecutionResult>;
2171
- /**
2172
- * Renames a document and waits for completion
2173
- */
2174
- rename(documentIdentifier: string, name: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
2175
- /**
2176
- * Updates the preferred editor recorded in the document header meta.
2177
- * Pass `null` to clear it.
2178
- */
2179
- setPreferredEditor(documentIdentifier: string, preferredEditor: string | null, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
2180
- /**
2181
- * Adds multiple documents as children to another and waits for completion
2182
- */
2183
- addRelationship(sourceIdentifier: string, targetIdentifier: string, relationshipType: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
2184
- /**
2185
- * Removes a relationship between two documents and waits for completion.
2186
- */
2187
- removeRelationship(sourceIdentifier: string, targetIdentifier: string, relationshipType: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
2188
- /**
2189
- * Moves a relationship from one source document to another and waits for completion.
2190
- */
2191
- moveRelationship(sourceParentIdentifier: string, targetParentIdentifier: string, targetIdentifier: string, relationshipType: string, branch?: string, signal?: AbortSignal): Promise<{
2192
- source: PHDocument;
2193
- target: PHDocument;
2194
- }>;
2195
- loadBatch(request: BatchLoadRequest, signal?: AbortSignal): Promise<BatchLoadResult>;
2196
- /**
2197
- * Deletes a document and waits for completion
2198
- */
2199
- deleteDocument(identifier: string, propagate?: PropagationMode, signal?: AbortSignal): Promise<void>;
2200
- /**
2201
- * Deletes documents and waits for completion
2202
- */
2203
- deleteDocuments(identifiers: string[], propagate?: PropagationMode, signal?: AbortSignal): Promise<void>;
2204
- /**
2205
- * Retrieves the status of a job
2206
- */
2207
- getJobStatus(jobId: string, signal?: AbortSignal): Promise<JobInfo>;
2208
- /**
2209
- * Waits for a job to complete
2210
- */
2211
- waitForJob(jobId: string | JobInfo, signal?: AbortSignal): Promise<JobInfo>;
2212
- /**
2213
- * Subscribes to changes for documents matching specified filters
2214
- */
2215
- subscribe(search: SearchFilter, callback: (event: DocumentChangeEvent) => void, view?: ViewFilter): () => void;
2216
- private removeAllIncomingRelationships;
2217
- }
2218
- //#endregion
2219
2068
  //#region src/cache/collection-membership-cache.d.ts
2220
2069
  interface ICollectionMembershipCache {
2221
2070
  getCollectionsForDocuments(documentIds: string[]): Promise<Record<string, string[]>>;
@@ -3264,112 +3113,557 @@ type JobResult = {
3264
3113
  error?: Error; /** The operations generated from the actions (if successful) */
3265
3114
  operations?: Operation[];
3266
3115
  /**
3267
- * Operations with context (includes ephemeral resultingState).
3268
- * Used for emitting to IDocumentView via event bus.
3116
+ * Operations with context (includes ephemeral resultingState).
3117
+ * Used for emitting to IDocumentView via event bus.
3118
+ */
3119
+ operationsWithContext?: OperationWithContext$1[]; /** Timestamp when the job execution completed */
3120
+ completedAt?: string; /** Duration of job execution in milliseconds */
3121
+ duration?: number; /** Any additional metadata from the execution */
3122
+ metadata?: Record<string, any>;
3123
+ };
3124
+ /**
3125
+ * Enforcement the reactor performs, each off by default.
3126
+ *
3127
+ * An evaluation made while replaying is part of the document's history, so two
3128
+ * reactors that share documents and disagree on these diverge. A flag is turned
3129
+ * on for a set of reactors that sync with each other, not for one node.
3130
+ */
3131
+ type ReactorFeatureFlags = {
3132
+ /**
3133
+ * Decide whether an operation may be admitted by building a decision model
3134
+ * over the document stream, rather than reading the deleted flag from the
3135
+ * document meta cache. Deletion then takes effect from the deleting
3136
+ * operation's position rather than for the whole document.
3137
+ */
3138
+ documentDecisions: boolean;
3139
+ /**
3140
+ * Evaluate the auth policy by reading the auth scope as a second projection.
3141
+ * Requires documentDecisions.
3142
+ */
3143
+ authEnforcement: boolean;
3144
+ /**
3145
+ * Match { group } principals by folding the referenced PHGroup documents as
3146
+ * derived projections. Requires authEnforcement.
3147
+ */
3148
+ authGroups: boolean;
3149
+ /**
3150
+ * Evaluate `where` clauses and { match } principals against the executing
3151
+ * scope's state, the subject, and the action input. Requires authGroups.
3152
+ */
3153
+ authConditions: boolean;
3154
+ };
3155
+ /**
3156
+ * Configuration options for the job executor
3157
+ */
3158
+ type JobExecutorConfig = {
3159
+ /** Feature flags; anything unset is off. */featureFlags?: Partial<ReactorFeatureFlags>; /** Maximum number of conflicting operations to skip when reshuffling. */
3160
+ maxSkipThreshold?: number; /** Maximum number of concurrent jobs to execute */
3161
+ maxConcurrency?: number; /** Maximum time in milliseconds a job can run before being considered timed out */
3162
+ jobTimeoutMs?: number; /** Base delay in milliseconds for exponential backoff retries */
3163
+ retryBaseDelayMs?: number; /** Maximum delay in milliseconds for exponential backoff retries */
3164
+ retryMaxDelayMs?: number;
3165
+ /** Maximum elapsed milliseconds before yielding to the main thread between actions.
3166
+ * Keeps the UI responsive when processing large batches. */
3167
+ yieldDeadlineMs?: number;
3168
+ };
3169
+ /**
3170
+ * Event types for the job executor
3171
+ */
3172
+ declare const JobExecutorEventTypes: {
3173
+ readonly JOB_STARTED: 20000;
3174
+ readonly JOB_COMPLETED: 20001;
3175
+ readonly JOB_FAILED: 20002;
3176
+ readonly EXECUTOR_STARTED: 20003;
3177
+ readonly EXECUTOR_STOPPED: 20004;
3178
+ };
3179
+ /**
3180
+ * Event data for job execution events
3181
+ */
3182
+ type JobStartedEvent = {
3183
+ job: Job;
3184
+ startedAt: string;
3185
+ /**
3186
+ * Identifier of the executor that took the job. For the worker pool this is
3187
+ * the thread-worker id (e.g. "reactor-worker-3"); for the in-process simple
3188
+ * manager it is "in-process-<index>". Optional for backwards compatibility
3189
+ * with consumers built before the field was added.
3190
+ */
3191
+ workerId?: string;
3192
+ };
3193
+ type JobCompletedEvent = {
3194
+ job: Job;
3195
+ result: JobResult; /** See {@link JobStartedEvent.workerId}. */
3196
+ workerId?: string;
3197
+ };
3198
+ type JobFailedEvent = {
3199
+ job: Job;
3200
+ error: string;
3201
+ willRetry: boolean;
3202
+ retryCount: number; /** See {@link JobStartedEvent.workerId}. */
3203
+ workerId?: string;
3204
+ };
3205
+ type ExecutorStartedEvent = {
3206
+ config: JobExecutorConfig;
3207
+ startedAt: string;
3208
+ };
3209
+ type ExecutorStoppedEvent = {
3210
+ stoppedAt: string;
3211
+ graceful: boolean;
3212
+ };
3213
+ /**
3214
+ * Status information for the job executor manager
3215
+ */
3216
+ type ExecutorManagerStatus = {
3217
+ /** Whether the manager is currently running */isRunning: boolean; /** Number of executor instances managed */
3218
+ numExecutors: number; /** Number of jobs currently being processed */
3219
+ activeJobs: number; /** Total number of jobs processed since start */
3220
+ totalJobsProcessed: number;
3221
+ };
3222
+ //#endregion
3223
+ //#region src/decision/types.d.ts
3224
+ /** One operation stream. */
3225
+ type StreamQuery = {
3226
+ documentId: string;
3227
+ branch: string;
3228
+ scope: string;
3229
+ };
3230
+ /**
3231
+ * What building a decision model reads a stream's state through.
3232
+ *
3233
+ * `IWriteCache` satisfies this and is what the write paths pass. The read path
3234
+ * cannot: the write cache is a write-side projection invalidated by the process
3235
+ * that runs the executor, so a reactor whose executors live in worker processes
3236
+ * holds state in its parent that no commit ever invalidates. A read there would
3237
+ * decide against a policy arbitrarily far behind the one the write paths
3238
+ * enforce. Reads therefore pass a reader backed by the read side.
3239
+ */
3240
+ interface IStreamStateReader {
3241
+ getState(documentId: string, scope: string, branch: string, targetRevision?: number, signal?: AbortSignal): Promise<PHDocument>;
3242
+ }
3243
+ /** The document and branch a decision model is built for. */
3244
+ type DecisionTarget = {
3245
+ documentId: string;
3246
+ branch: string;
3247
+ };
3248
+ /**
3249
+ * What a decision's conditions may read beyond the projections: the executing
3250
+ * scope's own state and the attempted action's input. Populated only while
3251
+ * authConditions is on; otherwise both stay undefined and conditional grants
3252
+ * never apply.
3253
+ */
3254
+ type DecisionContext = {
3255
+ scopeState: unknown;
3256
+ actionInput?: unknown;
3257
+ };
3258
+ /** A statically-queried stream's operations, named after its projection. */
3259
+ type StreamHistory = {
3260
+ name: string;
3261
+ operations: Operation[];
3262
+ };
3263
+ /**
3264
+ * A named stream whose value in the model is that scope's state from the
3265
+ * document rebuild the reactor already performs. A derived query may read
3266
+ * only statically-queried projections, so composition is one layer deep.
3267
+ */
3268
+ type Projection<M> = {
3269
+ query: StreamQuery | ((model: Partial<M>) => StreamQuery[]);
3270
+ /**
3271
+ * For a derived projection, the streams it may read anywhere in an
3272
+ * evaluated range, derived from the statically-queried streams' operations
3273
+ * (including the operations under evaluation). A positional walk cannot use
3274
+ * `query`, because the folded state it depends on changes over the range;
3275
+ * this over-approximates by design, since a stream referenced at any
3276
+ * position stays readable when the earlier range is re-evaluated even if a
3277
+ * later operation removes the reference. Ignored on static projections.
3278
+ */
3279
+ queryOverHistory?: (reads: StreamHistory[]) => StreamQuery[];
3280
+ /**
3281
+ * Action types in this stream that can change an evaluation. Reads of the stream
3282
+ * are filtered to these, so anything left out is invisible to a decision.
3283
+ */
3284
+ decidingActions: string[]; /** Applies one of this stream's operations while deciding. */
3285
+ apply: (document: PHDocument, operation: Operation) => PHDocument;
3286
+ };
3287
+ /**
3288
+ * The outcome of evaluating one operation. A refusal carries the reason it is
3289
+ * recorded with, because a model has more than one way to refuse.
3290
+ */
3291
+ type Evaluation = {
3292
+ decision: "allow";
3293
+ } | {
3294
+ decision: "deny";
3295
+ reason: string;
3296
+ };
3297
+ /** Projections plus a decision function over the built model. */
3298
+ type DecisionModel<M> = {
3299
+ projections: { [K in keyof M]: Projection<M> };
3300
+ /**
3301
+ * Present when decide reads the executing scope's state through the
3302
+ * decision context. A positional walk then folds the evaluated stream with
3303
+ * this, from its base state through every effective operation, so
3304
+ * conditions read the state as it stood at each operation's position
3305
+ * rather than at the head.
3306
+ */
3307
+ foldEvaluatedScope?: (document: PHDocument, operation: Operation) => PHDocument;
3308
+ /**
3309
+ * Whether or not this model decides about operations in a given scope. That
3310
+ * is, a scope it reads is not necessarily one it evaluates, and vise-versa.
3311
+ */
3312
+ evaluatesScope(scope: string): boolean;
3313
+ decide(model: M, subject: AuthSubject, request: AuthRequest, ctx: DecisionContext): Evaluation;
3314
+ };
3315
+ /** A built model plus the read-set condition recording what the build read. */
3316
+ type BuiltDecisionModel<M> = {
3317
+ model: M;
3318
+ appendCondition: AppendCondition;
3319
+ };
3320
+ //#endregion
3321
+ //#region src/decision/document-decision-model.d.ts
3322
+ /** What the document decision model reads: the target's document scope. */
3323
+ type DocumentDecisionModel = {
3324
+ document: PHDocumentState;
3325
+ };
3326
+ /**
3327
+ * The simplest decision model: one projection over the document scope, which
3328
+ * rejects on a deleted document.
3329
+ */
3330
+ declare function documentDecisionModel(target: DecisionTarget): DecisionModel<DocumentDecisionModel>;
3331
+ //#endregion
3332
+ //#region src/decision/registered-model.d.ts
3333
+ /**
3334
+ * A model this reactor can register. Every one carries the document projection,
3335
+ * because admission reads the version and the deletion timestamp off it; a model
3336
+ * with more projections than that is still assignable here.
3337
+ */
3338
+ type RegisteredDecisionModel = (target: DecisionTarget) => DecisionModel<DocumentDecisionModel>;
3339
+ /** What admission needs out of a model built at the stream heads. */
3340
+ type AdmissionDecision = {
3341
+ evaluation: Evaluation;
3342
+ appendCondition: AppendCondition;
3343
+ documentVersion: number;
3344
+ deletedAtUtcIso: string | null;
3345
+ };
3346
+ /**
3347
+ * What decideAtHead resolves a condition context from: the action's input,
3348
+ * with the executing scope's state read at the head. Supplied only while
3349
+ * authConditions is on.
3350
+ */
3351
+ type AdmissionConditions = {
3352
+ actionInput?: unknown;
3353
+ };
3354
+ /**
3355
+ * Builds the model at the stream heads and decides one request against it. The
3356
+ * append condition it returns is the read-set the store enforces at write time.
3357
+ *
3358
+ * With `conditions` supplied, the executing scope's state is read at the head
3359
+ * for `doc.<scope>.*` paths. That read carries no append-condition entry of
3360
+ * its own: the written stream's expected-revision check already refuses a
3361
+ * write whose scope grew between the read and the append.
3362
+ */
3363
+ declare function decideAtHead(model: RegisteredDecisionModel, cache: IWriteCache, target: DecisionTarget, subject: AuthSubject, request: AuthRequest, signal?: AbortSignal, conditions?: AdmissionConditions): Promise<AdmissionDecision>;
3364
+ /**
3365
+ * The model this reactor enforces. With `authEnforcement` off the auth scope is
3366
+ * absent from every append condition and no load walks it; with `authGroups`
3367
+ * on, the group documents the grant list names join the read-set and the
3368
+ * registry supplies the reducer that folds them.
3369
+ */
3370
+ declare function selectDecisionModel(flags: ReactorFeatureFlags, registry: IDocumentModelRegistry): RegisteredDecisionModel;
3371
+ //#endregion
3372
+ //#region src/decision/read-gate.d.ts
3373
+ /**
3374
+ * Scopes every holder of a document may read, whatever the grants say. Denying
3375
+ * the policy itself would let a replica sync a document without it, read the
3376
+ * auth scope as uninitialized, and allow every operation it holds, so replicas
3377
+ * would diverge permanently. The document scope carries the metadata the same
3378
+ * argument covers. Grants gate domain-scope reads only.
3379
+ */
3380
+ declare const ALWAYS_READABLE_SCOPES: ReadonlySet<string>;
3381
+ /** Whether a subject may read each scope of one document. */
3382
+ interface IReadGate {
3383
+ /**
3384
+ * Resolves, for one document, which of its scopes the subject may read.
3385
+ *
3386
+ * The predicate is resolved up front rather than asked per scope so that the
3387
+ * filtering itself stays synchronous, and so that a model backing the answer
3388
+ * is built once per document instead of once per scope.
3389
+ */
3390
+ scopePredicate(document: PHDocument, subject: AuthSubject, branch: string, signal?: AbortSignal): Promise<(scope: string) => boolean>;
3391
+ }
3392
+ /**
3393
+ * The model reads enforce. Below `authEnforcement` there is no model to
3394
+ * enforce: the document-only model ignores the auth scope entirely, so reading
3395
+ * through it would serve every domain scope of a policied document to anyone.
3396
+ * Undefined therefore means "evaluate the policy alone", which is what the read
3397
+ * surface did before the model existed.
3398
+ */
3399
+ declare function readDecisionModel(flags: ReactorFeatureFlags, registry: IDocumentModelRegistry): RegisteredDecisionModel | undefined;
3400
+ /**
3401
+ * Evaluates the policy on its own, with no groups map and no condition context.
3402
+ * A `{ group }` or conditional grant therefore never applies: an allow that
3403
+ * does not apply withholds access, so this cannot widen a policy, but a policy
3404
+ * relying on a conditional deny is weaker here than it is written.
3405
+ */
3406
+ declare class BareReadGate implements IReadGate {
3407
+ scopePredicate(document: PHDocument, subject: AuthSubject): Promise<(scope: string) => boolean>;
3408
+ }
3409
+ /**
3410
+ * Evaluates a read against the registered decision model, built at the stream
3411
+ * heads. This is what makes `{ group }` principals and conditional grants apply
3412
+ * to a read: the model supplies the groups map and the scope's own state, the
3413
+ * same two things admission supplies.
3414
+ *
3415
+ * A read has no action, so a condition on `action.input.*` never holds for one.
3416
+ *
3417
+ * State is read through the read side rather than the write cache. The write
3418
+ * cache is invalidated by whichever process runs the executor, so a reactor
3419
+ * running its executors in worker processes would answer reads in the parent
3420
+ * from state no commit ever invalidates.
3421
+ */
3422
+ declare class ModelReadGate implements IReadGate {
3423
+ private readonly model;
3424
+ private readonly documentView;
3425
+ /**
3426
+ * Whether a group a policy names is served to that policy's audience. Only
3427
+ * meaningful with `authGroups`, which is what makes a `{ group }` grant
3428
+ * match at all; below it the grant fails closed, so serving the roster
3429
+ * would publish a member list no read grant can use.
3430
+ */
3431
+ private readonly servesGroups;
3432
+ private readonly operationIndex?;
3433
+ private readonly logger?;
3434
+ constructor(model: RegisteredDecisionModel, documentView: IDocumentView,
3435
+ /**
3436
+ * Whether a group a policy names is served to that policy's audience. Only
3437
+ * meaningful with `authGroups`, which is what makes a `{ group }` grant
3438
+ * match at all; below it the grant fails closed, so serving the roster
3439
+ * would publish a member list no read grant can use.
3440
+ */
3441
+
3442
+ servesGroups: boolean, operationIndex?: IOperationIndex | undefined, logger?: ILogger | undefined);
3443
+ /**
3444
+ * A served group yields its member list and nothing else. What the audience
3445
+ * is owed is the state it must fold to evaluate auth with the group; a
3446
+ * group's other scopes are its own business and stay behind its own grants.
3447
+ */
3448
+ scopePredicate(document: PHDocument, subject: AuthSubject, branch: string, signal?: AbortSignal): Promise<(scope: string) => boolean>;
3449
+ /**
3450
+ * Whether the subject is served this group because a policy names it.
3451
+ *
3452
+ * A replica must fold a group's membership to evaluate auth with it, so a
3453
+ * group a grant names is served to the audience of the document that names
3454
+ * it, whatever the group's own read grants say. Naming a group in a policy
3455
+ * publishes its roster to that policy's audience; a group whose membership
3456
+ * must stay confidential does not belong in a grant.
3457
+ *
3458
+ * The referencing document's own domain scopes are the test. Its `auth` and
3459
+ * `document` scopes are readable by every holder, so testing those would
3460
+ * serve every referenced group to everybody.
3461
+ *
3462
+ * One level only. A referencer that is itself a group is skipped, and a
3463
+ * referencer's own readability is decided from its policy alone, so a
3464
+ * reference cycle terminates. Cycles are reachable: the reference relation
3465
+ * is recorded from an operation's input, including one later stored denied,
3466
+ * so a refused grant naming a group from inside another group leaves a row
3467
+ * behind that validation never saw.
3468
+ *
3469
+ * The referencers are probed a few at a time and the walk stops at the first
3470
+ * that serves, because a subject outside the audience is the case that runs to
3471
+ * the bound, and it is the common one. A probe that failed decides only when
3472
+ * nothing served: serving rests on a real allow, so this cannot widen, and it
3473
+ * stops one unreachable referencer from turning an allow already in hand into
3474
+ * a denial. A read records no operation, so replicas differing over a
3475
+ * transient failure has no consensus consequence.
3476
+ *
3477
+ * The probes are awaited together rather than raced, so none is ever left
3478
+ * running with nobody awaiting it, which is where unhandled rejections come
3479
+ * from.
3480
+ */
3481
+ private servesGroupTo;
3482
+ /**
3483
+ * Whether one referencing document serves the subject any domain scope. A
3484
+ * referencer this replica does not hold serves nothing, which fails closed
3485
+ * the same way a group it does not hold does.
3486
+ */
3487
+ private servesThrough;
3488
+ private servesGroup;
3489
+ /**
3490
+ * What this document's own policy says, with no group serving applied.
3491
+ *
3492
+ * An unpoliced document is readable in full, which is the common case and the
3493
+ * one worth answering without building anything. The test is the one
3494
+ * `evaluate` makes: a legacy `{}` auth scope and version 0 both mean
3495
+ * uninitialized, and "no grants" does not, because a policy with a version and
3496
+ * an empty grant list denies everything.
3497
+ */
3498
+ private ownPolicyPredicate;
3499
+ }
3500
+ //#endregion
3501
+ //#region src/client/reactor-client.d.ts
3502
+ /**
3503
+ * ReactorClient implementation that wraps lower-level APIs to provide
3504
+ * a simpler interface for document operations.
3505
+ *
3506
+ * Features:
3507
+ * - Wraps Jobs with Promises for easier async handling
3508
+ * - Manages signing of submitted Action objects
3509
+ * - Provides quality-of-life functions for common tasks
3510
+ * - Wraps subscription interface with ViewFilters
3511
+ */
3512
+ declare class ReactorClient implements IReactorClient {
3513
+ private logger;
3514
+ private reactor;
3515
+ private signer;
3516
+ private subscriptionManager;
3517
+ private jobAwaiter;
3518
+ private documentIndexer;
3519
+ private documentView;
3520
+ private readGate;
3521
+ readonly drives: IDriveClient;
3522
+ constructor(logger: ILogger, reactor: IReactor, signer: ISigner, subscriptionManager: IReactorSubscriptionManager, jobAwaiter: IJobAwaiter, documentIndexer: IDocumentIndexer, documentView: IDocumentView, readGate?: IReadGate);
3523
+ private readSubject;
3524
+ /**
3525
+ * Which scopes of one document the subject may read. Resolved once per
3526
+ * document, so the gate builds its model once however many scopes are then
3527
+ * tested, and the filtering itself stays synchronous.
3528
+ */
3529
+ private readableScopes;
3530
+ /**
3531
+ * One document, filtered to the scopes the subject may read. Every method
3532
+ * that hands a document back goes through here, including the ones that
3533
+ * follow a write: a document returned from a mutation is a read like any
3534
+ * other, and returning it whole served scopes the same subject would be
3535
+ * refused by `get`. Its author still sees what it wrote, because an allow on
3536
+ * execute confers read of that scope.
3537
+ */
3538
+ private gateDocument;
3539
+ /**
3540
+ * Retrieves a list of document model modules.
3541
+ */
3542
+ getDocumentModelModules(namespace?: string, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<DocumentModelModule>>;
3543
+ /**
3544
+ * Retrieves a specific document model module by document type.
3545
+ *
3546
+ * @param documentType - The document type identifier
3547
+ * @returns The document model module
3548
+ */
3549
+ getDocumentModelModule(documentType: string): Promise<DocumentModelModule<any>>;
3550
+ /**
3551
+ * Retrieves the document model module matching the version the document is
3552
+ * stamped with, so not-yet-upgraded documents get the reducer their
3553
+ * history was written with rather than the latest.
3554
+ */
3555
+ getDocumentModelModuleForDocument(document: PHDocument): Promise<DocumentModelModule<any>>;
3556
+ /**
3557
+ * Retrieves a specific PHDocument
3558
+ */
3559
+ get<TDocument extends PHDocument>(identifier: string, view?: ViewFilter, signal?: AbortSignal): Promise<TDocument>;
3560
+ /**
3561
+ * Resolves an identifier (id or slug) to the canonical document id, using the
3562
+ * same lookup as the data path. Resolves against the "main" branch. Throws if
3563
+ * the identifier cannot be resolved or is ambiguous.
3564
+ */
3565
+ resolveIdOrSlug(identifier: string, view?: ViewFilter, signal?: AbortSignal): Promise<string>;
3566
+ /**
3567
+ * Retrieves operations for a document
3568
+ */
3569
+ getOperations(documentIdentifier: string, view?: ViewFilter, filter?: OperationFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<Operation>>;
3570
+ private getOperationsWithCompositeCursor;
3571
+ /**
3572
+ * Retrieves outgoing relationships of a given type from a source document.
3573
+ */
3574
+ getOutgoingRelationships(sourceIdentifier: string, relationshipType: string, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
3575
+ /**
3576
+ * Retrieves incoming relationships of a given type to a target document.
3577
+ */
3578
+ getIncomingRelationships(targetIdentifier: string, relationshipType: string, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
3579
+ /**
3580
+ * Filters documents by criteria and returns a list of them
3581
+ */
3582
+ find(search: SearchFilter, view?: ViewFilter, paging?: PagingOptions, signal?: AbortSignal): Promise<PagedResults<PHDocument>>;
3583
+ /**
3584
+ * Creates a document and waits for completion
3585
+ */
3586
+ create<TDocument extends PHDocument = PHDocument>(document: PHDocument, parentIdentifier?: string, signal?: AbortSignal): Promise<TDocument>;
3587
+ /**
3588
+ * Creates an empty document and waits for completion
3589
+ */
3590
+ createEmpty<TDocument extends PHDocument>(documentModelType: string, options?: CreateDocumentOptions, signal?: AbortSignal): Promise<TDocument>;
3591
+ /**
3592
+ * Upgrades a document to a newer document model version by dispatching an
3593
+ * UPGRADE_DOCUMENT action. When toVersion is omitted, upgrades to the
3594
+ * latest registered module version for the document's type. Returns the
3595
+ * document unchanged when it is already at the target version.
3596
+ *
3597
+ * The executor validates the action's version and revision snapshot against
3598
+ * the state the migration actually runs on. When a concurrent edit
3599
+ * invalidates the snapshot, the upgrade is rebuilt from a fresh read and
3600
+ * retried up to maxConflictRetries times before the conflict is surfaced.
3601
+ */
3602
+ upgradeDocument<TDocument extends PHDocument = PHDocument>(documentIdentifier: string, toVersion?: number, options?: UpgradeDocumentOptions, signal?: AbortSignal): Promise<TDocument>;
3603
+ /**
3604
+ * Creates an empty document in a drive as a single batched operation.
3605
+ * Delegates to {@link IDriveClient.addFile}.
3606
+ *
3607
+ * @deprecated Use `client.drives.addFile` instead. This method will be
3608
+ * removed in a future release.
3609
+ */
3610
+ createDocumentInDrive<TDocument extends PHDocument>(driveId: string, document: PHDocument, parentFolder?: string, signal?: AbortSignal): Promise<TDocument>;
3611
+ /**
3612
+ * Applies a list of actions to a document and waits for completion
3613
+ */
3614
+ execute<TDocument extends PHDocument>(documentIdentifier: string, branch: string, actions: Action[], signal?: AbortSignal): Promise<TDocument>;
3615
+ /**
3616
+ * Submits a list of actions to a document
3617
+ */
3618
+ executeAsync(documentIdentifier: string, branch: string, actions: Action[], signal?: AbortSignal): Promise<JobInfo>;
3619
+ executeBatch(request: BatchExecutionRequest, signal?: AbortSignal): Promise<BatchExecutionResult>;
3620
+ /**
3621
+ * Renames a document and waits for completion
3622
+ */
3623
+ rename(documentIdentifier: string, name: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
3624
+ /**
3625
+ * Updates the preferred editor recorded in the document header meta.
3626
+ * Pass `null` to clear it.
3627
+ */
3628
+ setPreferredEditor(documentIdentifier: string, preferredEditor: string | null, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
3629
+ /**
3630
+ * Adds multiple documents as children to another and waits for completion
3631
+ */
3632
+ addRelationship(sourceIdentifier: string, targetIdentifier: string, relationshipType: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
3633
+ /**
3634
+ * Removes a relationship between two documents and waits for completion.
3635
+ */
3636
+ removeRelationship(sourceIdentifier: string, targetIdentifier: string, relationshipType: string, branch?: string, signal?: AbortSignal): Promise<PHDocument>;
3637
+ /**
3638
+ * Moves a relationship from one source document to another and waits for completion.
3269
3639
  */
3270
- operationsWithContext?: OperationWithContext$1[]; /** Timestamp when the job execution completed */
3271
- completedAt?: string; /** Duration of job execution in milliseconds */
3272
- duration?: number; /** Any additional metadata from the execution */
3273
- metadata?: Record<string, any>;
3274
- };
3275
- /**
3276
- * Enforcement the reactor performs, each off by default.
3277
- *
3278
- * An evaluation made while replaying is part of the document's history, so two
3279
- * reactors that share documents and disagree on these diverge. A flag is turned
3280
- * on for a set of reactors that sync with each other, not for one node.
3281
- */
3282
- type ReactorFeatureFlags = {
3640
+ moveRelationship(sourceParentIdentifier: string, targetParentIdentifier: string, targetIdentifier: string, relationshipType: string, branch?: string, signal?: AbortSignal): Promise<{
3641
+ source: PHDocument;
3642
+ target: PHDocument;
3643
+ }>;
3644
+ loadBatch(request: BatchLoadRequest, signal?: AbortSignal): Promise<BatchLoadResult>;
3283
3645
  /**
3284
- * Decide whether an operation may be admitted by building a decision model
3285
- * over the document stream, rather than reading the deleted flag from the
3286
- * document meta cache. Deletion then takes effect from the deleting
3287
- * operation's position rather than for the whole document.
3646
+ * Deletes a document and waits for completion
3288
3647
  */
3289
- documentDecisions: boolean;
3648
+ deleteDocument(identifier: string, propagate?: PropagationMode, signal?: AbortSignal): Promise<void>;
3290
3649
  /**
3291
- * Evaluate the auth policy by reading the auth scope as a second projection.
3292
- * Requires documentDecisions.
3650
+ * Deletes documents and waits for completion
3293
3651
  */
3294
- authEnforcement: boolean;
3652
+ deleteDocuments(identifiers: string[], propagate?: PropagationMode, signal?: AbortSignal): Promise<void>;
3295
3653
  /**
3296
- * Match { group } principals by folding the referenced PHGroup documents as
3297
- * derived projections. Requires authEnforcement.
3654
+ * Retrieves the status of a job
3298
3655
  */
3299
- authGroups: boolean;
3656
+ getJobStatus(jobId: string, signal?: AbortSignal): Promise<JobInfo>;
3300
3657
  /**
3301
- * Evaluate `where` clauses and { match } principals against the executing
3302
- * scope's state, the subject, and the action input. Requires authGroups.
3658
+ * Waits for a job to complete
3303
3659
  */
3304
- authConditions: boolean;
3305
- };
3306
- /**
3307
- * Configuration options for the job executor
3308
- */
3309
- type JobExecutorConfig = {
3310
- /** Feature flags; anything unset is off. */featureFlags?: Partial<ReactorFeatureFlags>; /** Maximum number of conflicting operations to skip when reshuffling. */
3311
- maxSkipThreshold?: number; /** Maximum number of concurrent jobs to execute */
3312
- maxConcurrency?: number; /** Maximum time in milliseconds a job can run before being considered timed out */
3313
- jobTimeoutMs?: number; /** Base delay in milliseconds for exponential backoff retries */
3314
- retryBaseDelayMs?: number; /** Maximum delay in milliseconds for exponential backoff retries */
3315
- retryMaxDelayMs?: number;
3316
- /** Maximum elapsed milliseconds before yielding to the main thread between actions.
3317
- * Keeps the UI responsive when processing large batches. */
3318
- yieldDeadlineMs?: number;
3319
- };
3320
- /**
3321
- * Event types for the job executor
3322
- */
3323
- declare const JobExecutorEventTypes: {
3324
- readonly JOB_STARTED: 20000;
3325
- readonly JOB_COMPLETED: 20001;
3326
- readonly JOB_FAILED: 20002;
3327
- readonly EXECUTOR_STARTED: 20003;
3328
- readonly EXECUTOR_STOPPED: 20004;
3329
- };
3330
- /**
3331
- * Event data for job execution events
3332
- */
3333
- type JobStartedEvent = {
3334
- job: Job;
3335
- startedAt: string;
3660
+ waitForJob(jobId: string | JobInfo, signal?: AbortSignal): Promise<JobInfo>;
3336
3661
  /**
3337
- * Identifier of the executor that took the job. For the worker pool this is
3338
- * the thread-worker id (e.g. "reactor-worker-3"); for the in-process simple
3339
- * manager it is "in-process-<index>". Optional for backwards compatibility
3340
- * with consumers built before the field was added.
3662
+ * Subscribes to changes for documents matching specified filters
3341
3663
  */
3342
- workerId?: string;
3343
- };
3344
- type JobCompletedEvent = {
3345
- job: Job;
3346
- result: JobResult; /** See {@link JobStartedEvent.workerId}. */
3347
- workerId?: string;
3348
- };
3349
- type JobFailedEvent = {
3350
- job: Job;
3351
- error: string;
3352
- willRetry: boolean;
3353
- retryCount: number; /** See {@link JobStartedEvent.workerId}. */
3354
- workerId?: string;
3355
- };
3356
- type ExecutorStartedEvent = {
3357
- config: JobExecutorConfig;
3358
- startedAt: string;
3359
- };
3360
- type ExecutorStoppedEvent = {
3361
- stoppedAt: string;
3362
- graceful: boolean;
3363
- };
3364
- /**
3365
- * Status information for the job executor manager
3366
- */
3367
- type ExecutorManagerStatus = {
3368
- /** Whether the manager is currently running */isRunning: boolean; /** Number of executor instances managed */
3369
- numExecutors: number; /** Number of jobs currently being processed */
3370
- activeJobs: number; /** Total number of jobs processed since start */
3371
- totalJobsProcessed: number;
3372
- };
3664
+ subscribe(search: SearchFilter, callback: (event: DocumentChangeEvent) => void, view?: ViewFilter): () => void;
3665
+ private removeAllIncomingRelationships;
3666
+ }
3373
3667
  //#endregion
3374
3668
  //#region src/executor/interfaces.d.ts
3375
3669
  /**
@@ -4437,6 +4731,12 @@ interface ReactorModule {
4437
4731
  * integration scenarios.
4438
4732
  */
4439
4733
  interface InProcessReactorModule extends ReactorModule {
4734
+ /**
4735
+ * The enforcement flags this reactor resolved, as plain booleans. Held on the
4736
+ * module because they select what a read enforces as well as what a write
4737
+ * does, and the read surface is composed outside the reactor.
4738
+ */
4739
+ featureFlags: ReactorFeatureFlags;
4440
4740
  queue: IQueue;
4441
4741
  jobTracker: IJobTracker;
4442
4742
  executorManager: IJobExecutorManager;
@@ -5053,6 +5353,7 @@ declare class ReactorClientBuilder {
5053
5353
  private subscriptionManager?;
5054
5354
  private jobAwaiter?;
5055
5355
  private documentModelLoader?;
5356
+ private readGate?;
5056
5357
  /**
5057
5358
  * Sets the logger for the ReactorClient.
5058
5359
  * @param logger - The logger to use.
@@ -5076,6 +5377,22 @@ declare class ReactorClientBuilder {
5076
5377
  withSubscriptionManager(subscriptionManager: IReactorSubscriptionManager): this;
5077
5378
  withJobAwaiter(jobAwaiter: IJobAwaiter): this;
5078
5379
  withDocumentModelLoader(loader: IDocumentModelLoader): this;
5380
+ /**
5381
+ * Overrides how reads are gated. A client built from a ReactorBuilder derives
5382
+ * this from that reactor's flags; one built from `withReactor` cannot, because
5383
+ * it is handed no flags and no registry, so it gates on the policy alone
5384
+ * unless a gate is supplied here.
5385
+ */
5386
+ withReadGate(readGate: IReadGate): this;
5387
+ /**
5388
+ * The gate this reactor's flags call for. Below authEnforcement there is no
5389
+ * model to enforce -- the registered one ignores the auth scope -- so the
5390
+ * policy is evaluated on its own, which is what reads did before the model
5391
+ * existed. Group serving turns on with authGroups, because below it a
5392
+ * `{ group }` grant does not match, so a served roster is one no grant can
5393
+ * use.
5394
+ */
5395
+ private resolveReadGate;
5079
5396
  build(): Promise<ReactorClient>;
5080
5397
  buildModule(): Promise<InProcessReactorClientModule>;
5081
5398
  }
@@ -5555,99 +5872,14 @@ declare class DocumentModelRegistry implements IDocumentModelRegistry {
5555
5872
  getUpgradeReducer(documentType: string, fromVersion: number, toVersion: number): UpgradeReducer<any, any>;
5556
5873
  }
5557
5874
  //#endregion
5558
- //#region src/decision/types.d.ts
5559
- /** One operation stream. */
5560
- type StreamQuery = {
5561
- documentId: string;
5562
- branch: string;
5563
- scope: string;
5564
- };
5565
- /** The document and branch a decision model is built for. */
5566
- type DecisionTarget = {
5567
- documentId: string;
5568
- branch: string;
5569
- };
5570
- /**
5571
- * What a decision's conditions may read beyond the projections: the executing
5572
- * scope's own state and the attempted action's input. Populated only while
5573
- * authConditions is on; otherwise both stay undefined and conditional grants
5574
- * never apply.
5575
- */
5576
- type DecisionContext = {
5577
- scopeState: unknown;
5578
- actionInput?: unknown;
5579
- };
5580
- /** A statically-queried stream's operations, named after its projection. */
5581
- type StreamHistory = {
5582
- name: string;
5583
- operations: Operation[];
5584
- };
5585
- /**
5586
- * A named stream whose value in the model is that scope's state from the
5587
- * document rebuild the reactor already performs. A derived query may read
5588
- * only statically-queried projections, so composition is one layer deep.
5589
- */
5590
- type Projection<M> = {
5591
- query: StreamQuery | ((model: Partial<M>) => StreamQuery[]);
5592
- /**
5593
- * For a derived projection, the streams it may read anywhere in an
5594
- * evaluated range, derived from the statically-queried streams' operations
5595
- * (including the operations under evaluation). A positional walk cannot use
5596
- * `query`, because the folded state it depends on changes over the range;
5597
- * this over-approximates by design, since a stream referenced at any
5598
- * position stays readable when the earlier range is re-evaluated even if a
5599
- * later operation removes the reference. Ignored on static projections.
5600
- */
5601
- queryOverHistory?: (reads: StreamHistory[]) => StreamQuery[];
5602
- /**
5603
- * Action types in this stream that can change an evaluation. Reads of the stream
5604
- * are filtered to these, so anything left out is invisible to a decision.
5605
- */
5606
- decidingActions: string[]; /** Applies one of this stream's operations while deciding. */
5607
- apply: (document: PHDocument, operation: Operation) => PHDocument;
5608
- };
5609
- /**
5610
- * The outcome of evaluating one operation. A refusal carries the reason it is
5611
- * recorded with, because a model has more than one way to refuse.
5612
- */
5613
- type Evaluation = {
5614
- decision: "allow";
5615
- } | {
5616
- decision: "deny";
5617
- reason: string;
5618
- };
5619
- /** Projections plus a decision function over the built model. */
5620
- type DecisionModel<M> = {
5621
- projections: { [K in keyof M]: Projection<M> };
5622
- /**
5623
- * Present when decide reads the executing scope's state through the
5624
- * decision context. A positional walk then folds the evaluated stream with
5625
- * this, from its base state through every effective operation, so
5626
- * conditions read the state as it stood at each operation's position
5627
- * rather than at the head.
5628
- */
5629
- foldEvaluatedScope?: (document: PHDocument, operation: Operation) => PHDocument;
5630
- /**
5631
- * Whether or not this model decides about operations in a given scope. That
5632
- * is, a scope it reads is not necessarily one it evaluates, and vise-versa.
5633
- */
5634
- evaluatesScope(scope: string): boolean;
5635
- decide(model: M, subject: AuthSubject, request: AuthRequest, ctx: DecisionContext): Evaluation;
5636
- };
5637
- /** A built model plus the read-set condition recording what the build read. */
5638
- type BuiltDecisionModel<M> = {
5639
- model: M;
5640
- appendCondition: AppendCondition;
5641
- };
5642
- //#endregion
5643
5875
  //#region src/decision/build-decision-model.d.ts
5644
5876
  /**
5645
- * Reads each projection's stream through the write cache, recording the
5877
+ * Reads each projection's stream through the supplied reader, recording the
5646
5878
  * revision observed. Static projections resolve first; derived projections
5647
5879
  * see only those and contribute a map from document id to state. Each
5648
5880
  * distinct stream is read once and yields one append condition entry.
5649
5881
  */
5650
- declare function buildDecisionModel<M>(cache: IWriteCache, definition: (target: DecisionTarget) => DecisionModel<M>, target: DecisionTarget, signal?: AbortSignal): Promise<BuiltDecisionModel<M>>;
5882
+ declare function buildDecisionModel<M>(reader: IStreamStateReader, definition: (target: DecisionTarget) => DecisionModel<M>, target: DecisionTarget, signal?: AbortSignal): Promise<BuiltDecisionModel<M>>;
5651
5883
  //#endregion
5652
5884
  //#region src/decision/auth-decision-model.d.ts
5653
5885
  type AuthDecisionModel = {
@@ -5657,57 +5889,6 @@ type AuthDecisionModel = {
5657
5889
  /** This decision model uses both the document and the auth streams. */
5658
5890
  declare function authDecisionModel(target: DecisionTarget): DecisionModel<AuthDecisionModel>;
5659
5891
  //#endregion
5660
- //#region src/decision/document-decision-model.d.ts
5661
- /** What the document decision model reads: the target's document scope. */
5662
- type DocumentDecisionModel = {
5663
- document: PHDocumentState;
5664
- };
5665
- /**
5666
- * The simplest decision model: one projection over the document scope, which
5667
- * rejects on a deleted document.
5668
- */
5669
- declare function documentDecisionModel(target: DecisionTarget): DecisionModel<DocumentDecisionModel>;
5670
- //#endregion
5671
- //#region src/decision/registered-model.d.ts
5672
- /**
5673
- * A model this reactor can register. Every one carries the document projection,
5674
- * because admission reads the version and the deletion timestamp off it; a model
5675
- * with more projections than that is still assignable here.
5676
- */
5677
- type RegisteredDecisionModel = (target: DecisionTarget) => DecisionModel<DocumentDecisionModel>;
5678
- /** What admission needs out of a model built at the stream heads. */
5679
- type AdmissionDecision = {
5680
- evaluation: Evaluation;
5681
- appendCondition: AppendCondition;
5682
- documentVersion: number;
5683
- deletedAtUtcIso: string | null;
5684
- };
5685
- /**
5686
- * What decideAtHead resolves a condition context from: the action's input,
5687
- * with the executing scope's state read at the head. Supplied only while
5688
- * authConditions is on.
5689
- */
5690
- type AdmissionConditions = {
5691
- actionInput?: unknown;
5692
- };
5693
- /**
5694
- * Builds the model at the stream heads and decides one request against it. The
5695
- * append condition it returns is the read-set the store enforces at write time.
5696
- *
5697
- * With `conditions` supplied, the executing scope's state is read at the head
5698
- * for `doc.<scope>.*` paths. That read carries no append-condition entry of
5699
- * its own: the written stream's expected-revision check already refuses a
5700
- * write whose scope grew between the read and the append.
5701
- */
5702
- declare function decideAtHead(model: RegisteredDecisionModel, cache: IWriteCache, target: DecisionTarget, subject: AuthSubject, request: AuthRequest, signal?: AbortSignal, conditions?: AdmissionConditions): Promise<AdmissionDecision>;
5703
- /**
5704
- * The model this reactor enforces. With `authEnforcement` off the auth scope is
5705
- * absent from every append condition and no load walks it; with `authGroups`
5706
- * on, the group documents the grant list names join the read-set and the
5707
- * registry supplies the reducer that folds them.
5708
- */
5709
- declare function selectDecisionModel(flags: ReactorFeatureFlags, registry: IDocumentModelRegistry): RegisteredDecisionModel;
5710
- //#endregion
5711
5892
  //#region src/decision/stream-order.d.ts
5712
5893
  /** Where a stream's stored order contradicts its timestamps. */
5713
5894
  type OutOfOrderPair = {
@@ -6342,5 +6523,5 @@ declare class ProcessorManager extends BaseReadModel implements IProcessorManage
6342
6523
  private deleteProcessorCursors;
6343
6524
  }
6344
6525
  //#endregion
6345
- export { APPEND_CONDITION_FAILED_PREFIX, type AbortMessage, type AdmissionDecision, type AppendCondition, AppendConditionFailedError, type AppendConditionStream, type AtomicTxn, type AttachmentHash, type AttachmentRef, type AuthDecisionModel, BaseReadModel, type BatchExecutionRequest, type BatchExecutionResult, type BatchLoadRequest, type BatchLoadResult, type BuiltDecisionModel, type BuiltInReadModelKind, type CachedSnapshot, type ChannelConfig, ChannelError, ChannelErrorSource, type ChannelHealth, type ChannelMeta, ChannelScheme, type ConnectionState, type ConnectionStateChangeCallback, type ConnectionStateChangedEvent, type ConnectionStateSnapshot, type ConsistencyCoordinate, type ConsistencyKey, type ConsistencyToken, ConsistencyTracker, DEFAULT_DRIVE_CONTAINER_TYPES, DRIVE_AUTH_ERROR_MESSAGES, type Database, type DbConfig, type DeadLetterAddedEvent, type DecisionContext, type DecisionModel, type DecisionTarget, DefaultSubscriptionErrorHandler, type DocumentChangeEvent, DocumentChangeType, type DocumentDecisionModel, type DocumentGraphEdge, type DocumentIndexerDatabase, DocumentIntegrityService, DocumentModelRegistry, DocumentModelResolver, type DocumentModelSource, type DocumentModelSpec, type DocumentRelationship, type DocumentRevisions, type DocumentStreamKey, type DocumentViewDatabase, DriveClient, DriveCollectionId, DuplicateManifestError, DuplicateModuleError, DuplicateOperationError, type Evaluation, EventBus, EventBusAggregateError, type ExecuteMessage, type ExecutionJobPlan, type ExecutorStartedEvent, type ExecutorStoppedEvent, type FactorySpec, type FileModelSource, type GqlChannelConfig, GqlRequestChannel, GqlRequestChannelFactory, GqlResponseChannel, GqlResponseChannelFactory, type HeartbeatMessage, type IChannel, type IChannelFactory, type IConsistencyTracker, type IDocumentGraph, type IDocumentIndexer, type IDocumentIntegrityService, type IDocumentModelLoader, type IDocumentModelRegistry, type IDocumentModelResolver, type IDocumentView, type IDriveClient, type IEventBus, type IJobAwaiter, type IJobExecutor, type IJobExecutorManager, type IJobTracker, type IKeyframeStore, type ILiveReadModelCoordinator, type IMailbox, type IOperationIndex, type IOperationStore, type IPollTimer, type IProcessor, type IProcessorHostModule, type IProcessorManager, type IProjectionTransport, type IQueue, type IReactor, type IReactorClient, type IReactorSubscriptionManager, type IReadModel, type IReadModelCoordinator, type IRelationalDb, type ISubscriptionErrorHandler, type ISyncCursorStorage, type ISyncManager, type ISyncRemoteStorage, type ISyncStatusTracker, type IWriteCache, SimpleJobExecutor as InMemoryJobExecutor, SimpleJobExecutor, InMemoryJobTracker, InMemoryQueue, type InProcessReactorClientModule, type InProcessReactorModule, type InProcessSyncModule, type InitMessage, type InsertableDocumentSnapshot, IntervalPollTimer, InvalidModuleError, type Job, type JobAvailableEvent, JobAwaiter, type JobCompletedEvent, type JobExecutorConfig, JobExecutorEventTypes, type JobExecutorFactory, type JobFailedEvent, type JobInfo, type JobPendingEvent, type JobReadReadyEvent, type JobResult, type JobRunningEvent, type JobStartedEvent, JobStatus, type JobWriteReadyEvent, type JobWriteReadyPayload, type JwtHandler, type KeyframeSnapshot, type KeyframeValidationIssue, KyselyDocumentIndexer, KyselyDocumentView, KyselyKeyframeStore, KyselyOperationStore, KyselySyncCursorStorage, KyselySyncRemoteStorage, KyselyWriteCache, type LoadJobPlan, type LoadModelMessage, type LogMessage, Mailbox, type MetricsMessage, type ModelLoadFailedMessage, type ModelLoadedEvent, type ModelLoadedMessage, type ModelManifestEntry, ModuleNotFoundError, type ModuleRef, NullDocumentModelResolver, type OperationBatch, type OperationContext, type OperationFilter, type OperationIndexEntry, type OperationTable, type OperationWithContext, OptimisticLockError, type OutOfOrderPair, type PackageModelSource, type PagedResults, type PagingOptions, type ParentMessage, type ParsedDriveUrl, type ParsedPaging, PollBehavior, PollingChannelError, type PoolInstrumentation, type PoolStats, type ProcessorApp, type ProcessorFactory, type ProcessorFactoryBuilder, type ProcessorFilter, ProcessorManager, type ProcessorRecord, type ProcessorStatus, type Projection, type ProjectionShardBuilderConfig, type ProjectionShardManagerConfig, type ProjectionWorkerFactory, PropagationMode, QueueEventTypes, REACTOR_SCHEMA, Reactor, ReactorBuilder, ReactorClient, ReactorClientBuilder, type ReactorClientModule, ReactorEventTypes, type ReactorFeatureFlags, type ReactorFeatures, type JobFailedEvent$1 as ReactorJobFailedEvent, type ReactorModule, ReactorSubscriptionManager, type ReadModelBatchCompletedEvent, ReadModelCoordinator, type ReadModelFactory, type ReadModelFactoryDeps, type ReadModelIndexedEvent, type ReadModelIndexingStage, type ReadModelRegistrationStage, type ReadModelStage, type ReadyMessage, type RebuildResult, type RegisteredDecisionModel, RelationalDbProcessor, RelationshipChangeType, type Remote, type RemoteCursor, type RemoteFilter, type RemoteMeta, type RemoteOptions, type RemoteRecord, type RemoteStatus, type ResultMessage, RetryAccounting, RevisionMismatchError, type SanitizedArg, type SearchFilter, type ShutdownMessage, type ShutdownStatus, type SignatureVerificationHandler, type SignatureVerifierSpec, type SignerConfig, SimpleJobExecutorManager, type SnapshotValidationIssue, type Database$1 as StorageDatabase, type StreamOrderIssue, type StreamQuery, type SubscriptionErrorContext, SyncBuilder, type SyncEnvelope, type SyncEnvelopeType, SyncEventTypes, type SyncFailedEvent, type SyncModule, SyncOperation, SyncOperationAggregateError, type SyncOperationErrorType, SyncOperationStatus, type SyncPendingEvent, SyncStatus, type SyncStatusChangeCallback, SyncStatusTracker, type SyncSucceededEvent, type TrackedProcessor, type Unsubscribe, type ValidationResult, type ViewFilter, type ErrorInfo as WorkerErrorInfo, type WorkerMessage, type WorkerPoolConfig, type WorkerPoolOptions, type WriteCacheConfig, addRelationshipAction, authDecisionModel, batchOperationsByDocument, buildDecisionModel, classifyJobFailure, consolidateSyncOperations, createDocumentAction, createForwardingLogger, createMutableShutdownStatus, createRelationalDb, decideAtHead, deleteDocumentAction, documentActions, documentDecisionModel, driveIdFromUrl, envelopesToSyncOperations, errorToInfo, firstOutOfOrderPair, getMigrationStatus, instrumentPgPool, isDriveAuthError, makeConsistencyKey, parseDriveUrl, parsePagingOptions, quarantinesDocument, removeRelationshipAction, runMigrations, sanitizeArg, selectDecisionModel, supportsLiveReadModelRegistration, syncOperationErrorType, trimMailboxFromAckOrdinal, updateRelationshipAction, upgradeDocumentAction, workerEntryPath };
6526
+ export { ALWAYS_READABLE_SCOPES, APPEND_CONDITION_FAILED_PREFIX, type AbortMessage, type AdmissionDecision, type AppendCondition, AppendConditionFailedError, type AppendConditionStream, type AtomicTxn, type AttachmentHash, type AttachmentRef, type AuthDecisionModel, BareReadGate, BaseReadModel, type BatchExecutionRequest, type BatchExecutionResult, type BatchLoadRequest, type BatchLoadResult, type BuiltDecisionModel, type BuiltInReadModelKind, type CachedSnapshot, type ChannelConfig, ChannelError, ChannelErrorSource, type ChannelHealth, type ChannelMeta, ChannelScheme, type ConnectionState, type ConnectionStateChangeCallback, type ConnectionStateChangedEvent, type ConnectionStateSnapshot, type ConsistencyCoordinate, type ConsistencyKey, type ConsistencyToken, ConsistencyTracker, DEFAULT_DRIVE_CONTAINER_TYPES, DRIVE_AUTH_ERROR_MESSAGES, type Database, type DbConfig, type DeadLetterAddedEvent, type DecisionContext, type DecisionModel, type DecisionTarget, DefaultSubscriptionErrorHandler, type DocumentChangeEvent, DocumentChangeType, type DocumentDecisionModel, type DocumentGraphEdge, type DocumentIndexerDatabase, DocumentIntegrityService, DocumentModelRegistry, DocumentModelResolver, type DocumentModelSource, type DocumentModelSpec, type DocumentRelationship, type DocumentRevisions, type DocumentStreamKey, type DocumentViewDatabase, DriveClient, DriveCollectionId, DuplicateManifestError, DuplicateModuleError, DuplicateOperationError, type Evaluation, EventBus, EventBusAggregateError, type ExecuteMessage, type ExecutionJobPlan, type ExecutorStartedEvent, type ExecutorStoppedEvent, type FactorySpec, type FileModelSource, type GqlChannelConfig, GqlRequestChannel, GqlRequestChannelFactory, GqlResponseChannel, GqlResponseChannelFactory, type HeartbeatMessage, type IChannel, type IChannelFactory, type IConsistencyTracker, type IDocumentGraph, type IDocumentIndexer, type IDocumentIntegrityService, type IDocumentModelLoader, type IDocumentModelRegistry, type IDocumentModelResolver, type IDocumentView, type IDriveClient, type IEventBus, type IJobAwaiter, type IJobExecutor, type IJobExecutorManager, type IJobTracker, type IKeyframeStore, type ILiveReadModelCoordinator, type IMailbox, type IOperationIndex, type IOperationStore, type IPollTimer, type IProcessor, type IProcessorHostModule, type IProcessorManager, type IProjectionTransport, type IQueue, type IReactor, type IReactorClient, type IReactorSubscriptionManager, type IReadGate, type IReadModel, type IReadModelCoordinator, type IRelationalDb, type IStreamStateReader, type ISubscriptionErrorHandler, type ISyncCursorStorage, type ISyncManager, type ISyncRemoteStorage, type ISyncStatusTracker, type IWriteCache, SimpleJobExecutor as InMemoryJobExecutor, SimpleJobExecutor, InMemoryJobTracker, InMemoryQueue, type InProcessReactorClientModule, type InProcessReactorModule, type InProcessSyncModule, type InitMessage, type InsertableDocumentSnapshot, IntervalPollTimer, InvalidModuleError, type Job, type JobAvailableEvent, JobAwaiter, type JobCompletedEvent, type JobExecutorConfig, JobExecutorEventTypes, type JobExecutorFactory, type JobFailedEvent, type JobInfo, type JobPendingEvent, type JobReadReadyEvent, type JobResult, type JobRunningEvent, type JobStartedEvent, JobStatus, type JobWriteReadyEvent, type JobWriteReadyPayload, type JwtHandler, type KeyframeSnapshot, type KeyframeValidationIssue, KyselyDocumentIndexer, KyselyDocumentView, KyselyKeyframeStore, KyselyOperationStore, KyselySyncCursorStorage, KyselySyncRemoteStorage, KyselyWriteCache, type LoadJobPlan, type LoadModelMessage, type LogMessage, Mailbox, type MetricsMessage, type ModelLoadFailedMessage, type ModelLoadedEvent, type ModelLoadedMessage, type ModelManifestEntry, ModelReadGate, ModuleNotFoundError, type ModuleRef, NullDocumentModelResolver, type OperationBatch, type OperationContext, type OperationFilter, type OperationIndexEntry, type OperationTable, type OperationWithContext, OptimisticLockError, type OutOfOrderPair, type PackageModelSource, type PagedResults, type PagingOptions, type ParentMessage, type ParsedDriveUrl, type ParsedPaging, PollBehavior, PollingChannelError, type PoolInstrumentation, type PoolStats, type ProcessorApp, type ProcessorFactory, type ProcessorFactoryBuilder, type ProcessorFilter, ProcessorManager, type ProcessorRecord, type ProcessorStatus, type Projection, type ProjectionShardBuilderConfig, type ProjectionShardManagerConfig, type ProjectionWorkerFactory, PropagationMode, QueueEventTypes, REACTOR_SCHEMA, Reactor, ReactorBuilder, ReactorClient, ReactorClientBuilder, type ReactorClientModule, ReactorEventTypes, type ReactorFeatureFlags, type ReactorFeatures, type JobFailedEvent$1 as ReactorJobFailedEvent, type ReactorModule, ReactorSubscriptionManager, type ReadModelBatchCompletedEvent, ReadModelCoordinator, type ReadModelFactory, type ReadModelFactoryDeps, type ReadModelIndexedEvent, type ReadModelIndexingStage, type ReadModelRegistrationStage, type ReadModelStage, type ReadyMessage, type RebuildResult, type RegisteredDecisionModel, RelationalDbProcessor, RelationshipChangeType, type Remote, type RemoteCursor, type RemoteFilter, type RemoteMeta, type RemoteOptions, type RemoteRecord, type RemoteStatus, type ResultMessage, RetryAccounting, RevisionMismatchError, type SanitizedArg, type SearchFilter, type ShutdownMessage, type ShutdownStatus, type SignatureVerificationHandler, type SignatureVerifierSpec, type SignerConfig, SimpleJobExecutorManager, type SnapshotValidationIssue, type Database$1 as StorageDatabase, type StreamOrderIssue, type StreamQuery, type SubscriptionErrorContext, SyncBuilder, type SyncEnvelope, type SyncEnvelopeType, SyncEventTypes, type SyncFailedEvent, type SyncModule, SyncOperation, SyncOperationAggregateError, type SyncOperationErrorType, SyncOperationStatus, type SyncPendingEvent, SyncStatus, type SyncStatusChangeCallback, SyncStatusTracker, type SyncSucceededEvent, type TrackedProcessor, type Unsubscribe, type ValidationResult, type ViewFilter, type ErrorInfo as WorkerErrorInfo, type WorkerMessage, type WorkerPoolConfig, type WorkerPoolOptions, type WriteCacheConfig, addRelationshipAction, authDecisionModel, batchOperationsByDocument, buildDecisionModel, classifyJobFailure, consolidateSyncOperations, createDocumentAction, createForwardingLogger, createMutableShutdownStatus, createRelationalDb, decideAtHead, deleteDocumentAction, documentActions, documentDecisionModel, driveIdFromUrl, envelopesToSyncOperations, errorToInfo, firstOutOfOrderPair, getMigrationStatus, instrumentPgPool, isDriveAuthError, makeConsistencyKey, parseDriveUrl, parsePagingOptions, quarantinesDocument, readDecisionModel, removeRelationshipAction, runMigrations, sanitizeArg, selectDecisionModel, supportsLiveReadModelRegistration, syncOperationErrorType, trimMailboxFromAckOrdinal, updateRelationshipAction, upgradeDocumentAction, workerEntryPath };
6346
6527
  //# sourceMappingURL=index.d.ts.map