@voltro/runtime 0.85.0 → 0.87.0
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/CHANGELOG.md +5987 -0
- package/README.md +43 -0
- package/THIRD-PARTY-NOTICES.md +864 -253
- package/dist/aggregate.js +42 -0
- package/dist/aggregateExtrema.js +80 -0
- package/dist/aggregateIvm.js +115 -0
- package/dist/analyticsMirror.js +228 -0
- package/dist/analyticsSink.js +32 -0
- package/dist/apiKeyUsage.js +33 -0
- package/dist/apiKeys.js +227 -0
- package/dist/apiKeysWiring.js +114 -0
- package/dist/apiRoleBucketSampler.js +64 -0
- package/dist/apiRoleWorkloadHistory.js +56 -0
- package/dist/apiRoleWorkloadMetrics.js +78 -0
- package/dist/apiRoleWorkloadStorage.js +95 -0
- package/dist/approvalBuiltins.js +10 -0
- package/dist/approvals.js +262 -0
- package/dist/authMiddlewareLayer.js +48 -0
- package/dist/bindEvent.js +92 -0
- package/dist/bootListener.js +143 -0
- package/dist/bootRefusal.js +7 -0
- package/dist/bootStoreCodec.js +71 -0
- package/dist/businessRules.js +67 -0
- package/dist/changeClaimsTable.js +12 -0
- package/dist/circuitBreaker.js +1 -0
- package/dist/columnOnUpdate.js +23 -0
- package/dist/composeAnalytics.js +129 -0
- package/dist/computedQuery.js +4 -0
- package/dist/computedQueryCache.js +231 -0
- package/dist/connectionBuiltins.js +81 -0
- package/dist/connectionCredentials.js +66 -0
- package/dist/connectionState.js +34 -0
- package/dist/connectionVault.js +410 -0
- package/dist/connectionsFacade.js +56 -0
- package/dist/coordinatedSchedule.js +145 -0
- package/dist/crdtHistory.js +138 -0
- package/dist/crdtMerge.js +179 -0
- package/dist/crdtVersionsTable.js +25 -0
- package/dist/credentialBound.js +12 -0
- package/dist/crud.js +72 -0
- package/dist/dataStore.js +712 -0
- package/dist/dataloader.js +61 -0
- package/dist/declaredTablesGuard.js +49 -0
- package/dist/defineExecutor.js +4 -0
- package/dist/dependencyGraph.js +32 -0
- package/dist/devices.js +228 -0
- package/dist/devicesWiring.js +168 -0
- package/dist/dialectReplicationAdapter.js +29 -0
- package/dist/dispatcher.js +522 -0
- package/dist/effectStore.js +71 -0
- package/dist/engineClients.js +24 -0
- package/dist/eventBus.js +260 -0
- package/dist/eventPublish.js +49 -0
- package/dist/events.js +193 -0
- package/dist/expectation.js +52 -0
- package/dist/expectationEvaluator.js +308 -0
- package/dist/experiment.js +96 -0
- package/dist/experimentEvaluator.js +245 -0
- package/dist/externalizedTasks.js +38 -0
- package/dist/fieldCipher.js +130 -0
- package/dist/fieldKeyRegistry.js +295 -0
- package/dist/fieldKeyRekey.js +286 -0
- package/dist/fieldKeyScan.js +136 -0
- package/dist/fieldKeyring.js +77 -0
- package/dist/fingerprint.js +21 -0
- package/dist/finops.js +42 -0
- package/dist/finopsAccountant.js +216 -0
- package/dist/handlerBody.js +8 -0
- package/dist/healthProbes.js +55 -0
- package/dist/hot.d.ts +56 -0
- package/dist/hot.js +3 -0
- package/dist/hotDataStore.js +148 -0
- package/dist/hotDataStoreSnapshot.js +98 -0
- package/dist/hotDataStoreTables.js +18 -0
- package/dist/http-range.d.ts +53 -0
- package/dist/http-range.js +52 -0
- package/dist/httpClientSsrf.js +24 -0
- package/dist/httpClientTracing.js +14 -0
- package/dist/httpCompression.js +76 -0
- package/dist/httpInputStream.js +82 -0
- package/dist/httpKeepAlive.js +12 -0
- package/dist/httpRouteMounts.js +48 -0
- package/dist/idempotencyStore.js +110 -0
- package/dist/idleDetector.js +21 -0
- package/dist/index.d.ts +1249 -517
- package/dist/index.js +155 -15292
- package/dist/insertRequiredColumns.js +19 -0
- package/dist/inspectWorkflow.js +1 -0
- package/dist/instanceMembership.js +98 -0
- package/dist/ivm.js +125 -0
- package/dist/kvDataStore.js +86 -0
- package/dist/kvFacade.js +38 -0
- package/dist/matcher.js +304 -0
- package/dist/memoryColumnDefaults.js +11 -0
- package/dist/memoryQueryJoins.js +114 -0
- package/dist/memorySetOperations.js +43 -0
- package/dist/metrics.js +175 -0
- package/dist/observability.js +123 -0
- package/dist/observedGraph.js +52 -0
- package/dist/originGuard.js +116 -0
- package/dist/outbox.js +352 -0
- package/dist/pluginRefRules.js +65 -0
- package/dist/policyGuardResolver.js +55 -0
- package/dist/preview.js +62 -0
- package/dist/projectedRows.js +12 -0
- package/dist/provenance.js +63 -0
- package/dist/rangeIndex.js +89 -0
- package/dist/rawReadScope.js +17 -0
- package/dist/reaction.js +85 -0
- package/dist/reactiveConfig.js +11 -0
- package/dist/readClassification.js +57 -0
- package/dist/readRecorder.js +67 -0
- package/dist/readScopePredicate.js +12 -0
- package/dist/rebac.js +104 -0
- package/dist/rebacInterceptor.js +81 -0
- package/dist/registry.js +29 -0
- package/dist/relevantFields.js +65 -0
- package/dist/replicaHealth.js +42 -0
- package/dist/replicaLocality.js +44 -0
- package/dist/replicaObservations.js +121 -0
- package/dist/replicaSelection.js +32 -0
- package/dist/replicatedDataStore.js +257 -0
- package/dist/requestLoader.js +7 -0
- package/dist/resumeCensus.js +28 -0
- package/dist/revalidation.js +22 -0
- package/dist/rowFilter.js +82 -0
- package/dist/rowStateBytes.js +45 -0
- package/dist/rpcBodyCap.js +63 -0
- package/dist/rpcConnections.js +83 -0
- package/dist/rpcDefectDiagnostics.js +15 -0
- package/dist/rpcServer.js +1065 -0
- package/dist/rpcWorkloadAdmission.js +50 -0
- package/dist/runAsSystem.js +23 -0
- package/dist/rywPositionStore.js +119 -0
- package/dist/schedule.js +23 -0
- package/dist/scheduleBackfillRequests.js +151 -0
- package/dist/scheduleClaimsTable.js +11 -0
- package/dist/scheduleRunsTable.js +37 -0
- package/dist/scheduler.js +840 -0
- package/dist/schemaRegistry.js +65 -0
- package/dist/secretsResolver.js +35 -0
- package/dist/securityHeaders.js +33 -0
- package/dist/servePipeline.js +374 -0
- package/dist/serverOnlyAudit.js +66 -0
- package/dist/serverTracer.js +15 -0
- package/dist/serviceCredentials.js +40 -0
- package/dist/setReadScopes.js +28 -0
- package/dist/singleNodeOrchestrator.js +91 -0
- package/dist/snapshotValueCodec.js +46 -0
- package/dist/sourceResolution.js +52 -0
- package/dist/storeMiddleware.js +882 -0
- package/dist/storeQuery.js +204 -0
- package/dist/storeRead.js +10 -0
- package/dist/subscriber.js +8 -0
- package/dist/subscriptionOutbox.js +139 -0
- package/dist/subscriptionRegistry.js +82 -0
- package/dist/subscriptionResume.js +132 -0
- package/dist/subscriptionSocketMetrics.js +65 -0
- package/dist/systemSubject.js +5 -0
- package/dist/tenantScope.js +11 -0
- package/dist/tenantSelection.js +27 -0
- package/dist/timeline.js +105 -0
- package/dist/traceContext.js +5 -0
- package/dist/traceSink.js +63 -0
- package/dist/traceSpansTable.js +29 -0
- package/dist/traceparent.js +23 -0
- package/dist/transactionSubject.js +12 -0
- package/dist/trustedProxy.js +155 -0
- package/dist/undo.js +129 -0
- package/dist/undoBuiltins.js +69 -0
- package/dist/undoCapture.js +74 -0
- package/dist/undoLogTable.js +16 -0
- package/dist/upsertBinding.js +20 -0
- package/dist/wakeOrchestrator.js +34 -0
- package/dist/wakeRegistry.js +71 -0
- package/dist/wakeRouter.js +63 -0
- package/dist/wakeSupervisor.js +62 -0
- package/dist/wakeupsTable.js +12 -0
- package/dist/webSocketGatewayRuntime.js +154 -0
- package/dist/webhookVerification.js +18 -0
- package/dist/wireColumnStrip.js +84 -0
- package/dist/workflowReadBuiltins.js +87 -0
- package/dist/workflowRuntime.js +708 -0
- package/package.json +19 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,31 @@
|
|
|
1
|
+
import { AggregateQuery } from '@voltro/kv/analytics';
|
|
2
|
+
import { AnalyticsBucket } from '@voltro/kv/analytics';
|
|
3
|
+
import { AnalyticsCapabilityNotSupported } from '@voltro/kv/analytics';
|
|
4
|
+
import { AnalyticsError } from '@voltro/kv/analytics';
|
|
5
|
+
import { AnalyticsEvent } from '@voltro/kv/analytics';
|
|
6
|
+
import { AnalyticsFailure } from '@voltro/kv/analytics';
|
|
7
|
+
import { AnalyticsMetric } from '@voltro/kv/analytics';
|
|
8
|
+
import { AnalyticsMirrorImpl } from '@voltro/kv/analytics';
|
|
9
|
+
import { AnalyticsMirrorRemove } from '@voltro/kv/analytics';
|
|
10
|
+
import { AnalyticsMirrorUpsert } from '@voltro/kv/analytics';
|
|
11
|
+
import { AnalyticsSinkImpl } from '@voltro/kv/analytics';
|
|
12
|
+
import { AnalyticsSinkInfo } from '@voltro/kv/analytics';
|
|
13
|
+
import { AnalyticsTopEntry } from '@voltro/kv/analytics';
|
|
1
14
|
import { AnyApprovalPolicy } from '@voltro/protocol';
|
|
2
15
|
import { AnyCheckSpec } from '@voltro/protocol';
|
|
3
16
|
import { AnyGuardSpec } from '@voltro/protocol';
|
|
17
|
+
import { ApiRoleWindowAssessment } from '@voltro/protocol';
|
|
18
|
+
import { ApiWorkload } from '@voltro/protocol';
|
|
4
19
|
import { AuthMiddleware } from '@voltro/protocol';
|
|
5
20
|
import { AuthStrategy } from '@voltro/protocol';
|
|
21
|
+
import { canonicalJson } from '@voltro/protocol';
|
|
6
22
|
import { CaughtUpVerdict } from '@voltro/database';
|
|
7
23
|
import { Cause } from 'effect';
|
|
8
24
|
import { ChangeEvent } from '@voltro/database';
|
|
25
|
+
import { CircuitBreaker } from '@voltro/shared';
|
|
26
|
+
import { CircuitBreakerOptions } from '@voltro/shared';
|
|
27
|
+
import { CircuitOpen } from '@voltro/shared';
|
|
28
|
+
import { CircuitState } from '@voltro/shared';
|
|
9
29
|
import { classifyConstraintViolation } from '@voltro/database';
|
|
10
30
|
import { clearRetentions } from '@voltro/database';
|
|
11
31
|
import { ColumnBuilder } from '@voltro/database';
|
|
@@ -28,8 +48,9 @@ import { DeclaredAccess } from '@voltro/protocol';
|
|
|
28
48
|
import { DialectId } from '@voltro/database';
|
|
29
49
|
import { DialectReplicationAdapter } from '@voltro/database';
|
|
30
50
|
import { Duplex } from 'node:stream';
|
|
31
|
-
import { Duration } from 'effect';
|
|
32
51
|
import { Effect } from 'effect';
|
|
52
|
+
import { EnqueueOptions } from '@voltro/protocol';
|
|
53
|
+
import { EventClientPolicy } from '@voltro/protocol';
|
|
33
54
|
import { EventDeliverySemantics } from '@voltro/protocol';
|
|
34
55
|
import { EventDescriptor } from '@voltro/protocol';
|
|
35
56
|
import { EventKeyInvalid } from '@voltro/protocol';
|
|
@@ -54,6 +75,7 @@ import { InferRow } from '@voltro/database';
|
|
|
54
75
|
import { InMemoryMetricExporter } from '@opentelemetry/sdk-metrics';
|
|
55
76
|
import { InMemorySpanExporter } from '@opentelemetry/sdk-trace-base';
|
|
56
77
|
import { InsertIgnoreResult } from '@voltro/database';
|
|
78
|
+
import { InsertManyOptions } from '@voltro/database';
|
|
57
79
|
import { InspectedStep } from '@voltro/workflow';
|
|
58
80
|
import { InspectedWorkflow } from '@voltro/workflow';
|
|
59
81
|
import { InspectStore } from '@voltro/workflow';
|
|
@@ -61,6 +83,7 @@ import { inspectWorkflow } from '@voltro/workflow';
|
|
|
61
83
|
import { isForeignKeyViolation } from '@voltro/database';
|
|
62
84
|
import { isQueryTimeout } from '@voltro/database';
|
|
63
85
|
import { Kv } from '@voltro/kv';
|
|
86
|
+
import { KvError } from '@voltro/kv';
|
|
64
87
|
import { KvStoreShape } from '@voltro/kv';
|
|
65
88
|
import { Layer } from 'effect';
|
|
66
89
|
import { listRetentionConflicts } from '@voltro/database';
|
|
@@ -68,21 +91,31 @@ import { listRetentions } from '@voltro/database';
|
|
|
68
91
|
import { Membership } from '@voltro/protocol';
|
|
69
92
|
import { Metric } from 'effect';
|
|
70
93
|
import { MetricReader } from '@opentelemetry/sdk-metrics';
|
|
94
|
+
import { MirrorVersion } from '@voltro/kv/analytics';
|
|
71
95
|
import { MutationIdempotencyScope } from '@voltro/protocol';
|
|
96
|
+
import { newTraceId } from '@voltro/shared';
|
|
72
97
|
import { NoRowFound } from '@voltro/protocol';
|
|
73
98
|
import { NoSuchResource } from '@voltro/protocol';
|
|
99
|
+
import { Option } from 'effect';
|
|
100
|
+
import { OutboxEnqueueFacade } from '@voltro/protocol';
|
|
101
|
+
import { OutboxHandlerContext } from '@voltro/protocol';
|
|
102
|
+
import { OutboxHandlerDefinition } from '@voltro/protocol';
|
|
74
103
|
import { PendingApproval } from '@voltro/protocol';
|
|
75
104
|
import { PluginHttpRoute } from '@voltro/protocol';
|
|
76
105
|
import { PluginHttpRouteByteStream } from '@voltro/protocol';
|
|
77
106
|
import { PluginRefOrphanPolicy } from '@voltro/database';
|
|
78
107
|
import { Predicate } from '@voltro/database';
|
|
79
108
|
import { ProcedureWireError } from '@voltro/protocol';
|
|
109
|
+
import { PropertyFilter } from '@voltro/kv/analytics';
|
|
80
110
|
import { PublicApiSpec } from '@voltro/protocol';
|
|
81
111
|
import { Query } from '@voltro/database';
|
|
82
112
|
import { QueryDescriptor } from '@voltro/database';
|
|
83
|
-
import {
|
|
113
|
+
import { RedisPubSub } from '@voltro/kv/connection';
|
|
84
114
|
import { registerRetention } from '@voltro/database';
|
|
115
|
+
import { RequestedTenantRefused } from '@voltro/protocol';
|
|
85
116
|
import { ResourceMissing } from '@voltro/protocol';
|
|
117
|
+
import { RespClient } from '@voltro/kv/connection';
|
|
118
|
+
import { RespConnections } from '@voltro/kv/connection';
|
|
86
119
|
import { RestRouteDescriptor } from '@voltro/protocol/rest';
|
|
87
120
|
import { RetentionConflict } from '@voltro/database';
|
|
88
121
|
import { RetentionSource } from '@voltro/database';
|
|
@@ -94,6 +127,7 @@ import { RowPatch } from '@voltro/protocol';
|
|
|
94
127
|
import { Rpc } from 'effect/rpc';
|
|
95
128
|
import { RpcGroup } from 'effect/rpc';
|
|
96
129
|
import { RpcInterceptor } from '@voltro/protocol';
|
|
130
|
+
import { RpcReplayAuthorityBinding } from '@voltro/protocol';
|
|
97
131
|
import { RuleReadStore } from '@voltro/database';
|
|
98
132
|
import { Sampler } from '@opentelemetry/sdk-trace-base';
|
|
99
133
|
import { Schedule } from 'effect';
|
|
@@ -105,6 +139,9 @@ import { ServerResponse } from 'node:http';
|
|
|
105
139
|
import { SpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
106
140
|
import { spawn } from 'node:child_process';
|
|
107
141
|
import { SqlClient } from 'effect/sql';
|
|
142
|
+
import { SqlError } from 'effect/sql/SqlError';
|
|
143
|
+
import { SsrfPolicy } from '@voltro/protocol';
|
|
144
|
+
import { ssrfReason } from '@voltro/protocol';
|
|
108
145
|
import { StoredTableShape } from '@voltro/database';
|
|
109
146
|
import { StoreError } from '@voltro/protocol';
|
|
110
147
|
import { StoreOperationFailed } from '@voltro/protocol';
|
|
@@ -125,6 +162,10 @@ import { TenantRowNotFound } from '@voltro/protocol';
|
|
|
125
162
|
import { TenantScopeViolation } from '@voltro/protocol';
|
|
126
163
|
import { tenantSelectionId } from '@voltro/database';
|
|
127
164
|
import { TenantSelectionStore } from '@voltro/protocol';
|
|
165
|
+
import { TimeBucket } from '@voltro/kv/analytics';
|
|
166
|
+
import { TimeRange } from '@voltro/kv/analytics';
|
|
167
|
+
import { TimeseriesQuery } from '@voltro/kv/analytics';
|
|
168
|
+
import { TopNQuery } from '@voltro/kv/analytics';
|
|
128
169
|
import { Tracer } from 'effect';
|
|
129
170
|
import { Unauthenticated } from '@voltro/protocol';
|
|
130
171
|
import { UpsertOptions } from '@voltro/database';
|
|
@@ -167,6 +208,9 @@ declare const AccessDenied_base: Schema.Class<AccessDenied, Schema.TaggedStruct<
|
|
|
167
208
|
export declare const actingUserId: (subject: StoreMiddlewareContext["subject"]) => string | null;
|
|
168
209
|
|
|
169
210
|
export declare interface ActionRunnerDeps {
|
|
211
|
+
/** Measures only the synchronous executor entry, never an awaited result. */
|
|
212
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
213
|
+
readonly outcomeOutbox?: MutationRunnerDeps['outcomeOutbox'];
|
|
170
214
|
/** Build the per-call `AppContext` — NO transactional tx (actions do
|
|
171
215
|
* external I/O and run outside a txn deliberately). */
|
|
172
216
|
readonly buildContext: (request: ServeRequestContext) => {
|
|
@@ -177,8 +221,23 @@ export declare interface ActionRunnerDeps {
|
|
|
177
221
|
readonly recordMetric?: MutationRunnerDeps['recordMetric'];
|
|
178
222
|
/** See {@link MutationRunnerDeps.defaultDeny} — same flag, same refusal. */
|
|
179
223
|
readonly defaultDeny?: boolean;
|
|
224
|
+
/** See {@link MutationRunnerDeps.settleCacheInvalidations} — an action's
|
|
225
|
+
* writes are the writer's too. */
|
|
226
|
+
readonly settleCacheInvalidations?: () => Promise<void>;
|
|
180
227
|
}
|
|
181
228
|
|
|
229
|
+
/**
|
|
230
|
+
* Make a key active NOW, without waiting for every live process to hold it —
|
|
231
|
+
* for a key replacing a leaked one, where waiting is the larger risk. The
|
|
232
|
+
* processes that lack it are returned: they cannot read what is sealed under
|
|
233
|
+
* it until they are redeployed with it, and each says so on its heartbeat.
|
|
234
|
+
*/
|
|
235
|
+
export declare const activateFieldKeyNow: (store: DataStore, keyId: string, holder?: Pick<FieldKeyHolder, "now">) => Promise<{
|
|
236
|
+
readonly from: string | undefined;
|
|
237
|
+
readonly to: string;
|
|
238
|
+
readonly lacking: ReadonlyArray<string>;
|
|
239
|
+
}>;
|
|
240
|
+
|
|
182
241
|
/**
|
|
183
242
|
* Live activity counters the runtime exposes to the idle detector. All
|
|
184
243
|
* return the CURRENT count (0 = quiescent on that axis).
|
|
@@ -449,20 +508,7 @@ declare const AggregateNotFound_base: Schema.Class<AggregateNotFound, Schema.Tag
|
|
|
449
508
|
readonly name: Schema.String;
|
|
450
509
|
}>, YieldableError>;
|
|
451
510
|
|
|
452
|
-
export
|
|
453
|
-
readonly event: string;
|
|
454
|
-
readonly filter?: PropertyFilter;
|
|
455
|
-
readonly metric: AnalyticsMetric;
|
|
456
|
-
readonly range: TimeRange;
|
|
457
|
-
/**
|
|
458
|
-
* Restrict the read to one tenant's events. `useAnalytics()` injects the
|
|
459
|
-
* caller's `subject.tenantId` automatically, so handler code never sets
|
|
460
|
-
* this; a sink that honours it (e.g. analytics-postgres) then AND-filters
|
|
461
|
-
* by tenant so a query can't read across tenants. `null`/absent = unscoped
|
|
462
|
-
* (system/cross-tenant read).
|
|
463
|
-
*/
|
|
464
|
-
readonly tenantId?: string | null;
|
|
465
|
-
}
|
|
511
|
+
export { AggregateQuery }
|
|
466
512
|
|
|
467
513
|
export declare interface AggregateReadOptions {
|
|
468
514
|
/**
|
|
@@ -471,11 +517,14 @@ export declare interface AggregateReadOptions {
|
|
|
471
517
|
* Without it an aggregate can only ever be "the one global roll-up", so every
|
|
472
518
|
* tenant-/team-/year-scoped roll-up (most real ones) has to stay client-side.
|
|
473
519
|
* A row matches when EVERY entry matches: a scalar compares by strict
|
|
474
|
-
* equality, an array means "one of" (an IN set)
|
|
520
|
+
* equality, an array means "one of" (an IN set), and an object of `gte` /
|
|
521
|
+
* `gt` / `lte` / `lt` is a range on that column (a `Date` bound compares
|
|
522
|
+
* with `Date` and ISO-string values by instant; `null` never matches).
|
|
475
523
|
*
|
|
476
524
|
* ```ts
|
|
477
525
|
* yield* handle.read({ where: { teamId, year: 2026 } })
|
|
478
526
|
* yield* handle.read({ where: { status: ['open', 'blocked'] } })
|
|
527
|
+
* yield* handle.read({ where: { teamId, day: { gte: from, lte: to } } })
|
|
479
528
|
* ```
|
|
480
529
|
*
|
|
481
530
|
* Deliberately DATA, not a predicate function: it stays serializable, so the
|
|
@@ -500,15 +549,9 @@ export declare interface AggregateReadOptions {
|
|
|
500
549
|
* - Interval string (`'5m'`, `'1h'`, `'24h'`): the canonical
|
|
501
550
|
* simple case.
|
|
502
551
|
* - Cron expression `{ cron: '0 2 * * *', timezone: 'UTC' }`: for
|
|
503
|
-
* business-hours / off-peak refresh windows
|
|
504
|
-
* emitted from the spec but not yet honoured by the runner.
|
|
552
|
+
* business-hours / off-peak refresh windows, in the specified timezone.
|
|
505
553
|
* - On-change debounced `{ interval: '1h', onChange: ['matches'],
|
|
506
|
-
* debounceMs: 30_000 }`: near-realtime, source-table-driven.
|
|
507
|
-
* to v2** — same status.
|
|
508
|
-
*
|
|
509
|
-
* v1 supports interval only. The other shapes are accepted so consumers
|
|
510
|
-
* can declare them today + see them honoured when v2 lands without
|
|
511
|
-
* touching the spec.
|
|
554
|
+
* debounceMs: 30_000 }`: near-realtime, source-table-driven.
|
|
512
555
|
*/
|
|
513
556
|
export declare type AggregateRefreshPolicy = string | {
|
|
514
557
|
readonly interval?: string;
|
|
@@ -557,71 +600,17 @@ declare const AggregateStale_base: Schema.Class<AggregateStale, Schema.TaggedStr
|
|
|
557
600
|
readonly maxAgeMs: Schema.Number;
|
|
558
601
|
}>, YieldableError>;
|
|
559
602
|
|
|
560
|
-
export
|
|
561
|
-
readonly bucketStart: Date;
|
|
562
|
-
readonly value: number;
|
|
563
|
-
}
|
|
603
|
+
export { AnalyticsBucket }
|
|
564
604
|
|
|
565
|
-
|
|
566
|
-
* The sink doesn't implement this capability. PostHog returns this
|
|
567
|
-
* for `aggregate`/`timeseries`/`topN`. Callers typically
|
|
568
|
-
* `Effect.catchTag('AnalyticsCapabilityNotSupported', ...)` to fall
|
|
569
|
-
* back to a different sink or report the missing feature.
|
|
570
|
-
*/
|
|
571
|
-
export declare class AnalyticsCapabilityNotSupported extends AnalyticsCapabilityNotSupported_base {
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
declare const AnalyticsCapabilityNotSupported_base: Schema.Class<AnalyticsCapabilityNotSupported, Schema.TaggedStruct<"AnalyticsCapabilityNotSupported", {
|
|
575
|
-
readonly provider: Schema.String;
|
|
576
|
-
readonly capability: Schema.String;
|
|
577
|
-
}>, YieldableError>;
|
|
578
|
-
|
|
579
|
-
/**
|
|
580
|
-
* The underlying sink raised an error. `cause` is stringified for
|
|
581
|
-
* round-trip safety across the rpc boundary.
|
|
582
|
-
*/
|
|
583
|
-
export declare class AnalyticsError extends AnalyticsError_base {
|
|
584
|
-
}
|
|
605
|
+
export { AnalyticsCapabilityNotSupported }
|
|
585
606
|
|
|
586
|
-
|
|
587
|
-
readonly provider: Schema.String;
|
|
588
|
-
readonly operation: Schema.String;
|
|
589
|
-
readonly cause: Schema.String;
|
|
590
|
-
}>, YieldableError>;
|
|
607
|
+
export { AnalyticsError }
|
|
591
608
|
|
|
592
|
-
|
|
593
|
-
* One analytics event. `properties` must be JSON-serialisable —
|
|
594
|
-
* individual sinks validate at write time (Postgres stores as JSONB;
|
|
595
|
-
* ClickHouse encodes as a JSON string; PostHog forwards verbatim).
|
|
596
|
-
*/
|
|
597
|
-
export declare interface AnalyticsEvent {
|
|
598
|
-
/** Event name (e.g. `'match_completed'`, `'page_viewed'`). */
|
|
599
|
-
readonly name: string;
|
|
600
|
-
/** Subject id (typically `ctx.request.subject.id`) — anonymous when null. */
|
|
601
|
-
readonly subjectId?: string | null;
|
|
602
|
-
/**
|
|
603
|
-
* Owning tenant. Normally you DON'T set this by hand — `useAnalytics()`
|
|
604
|
-
* stamps it from the caller's `subject.tenantId` so every event is
|
|
605
|
-
* tenant-attributable + every read is tenant-scoped (the multi-tenant
|
|
606
|
-
* isolation default). Set it explicitly only for a cross-tenant system
|
|
607
|
-
* write. `null` = no tenant (system/anonymous).
|
|
608
|
-
*/
|
|
609
|
-
readonly tenantId?: string | null;
|
|
610
|
-
/** Property bag. Values must be JSON-serialisable. */
|
|
611
|
-
readonly properties: Readonly<Record<string, unknown>>;
|
|
612
|
-
/** When the event occurred. Defaults to server-now when omitted. */
|
|
613
|
-
readonly occurredAt?: Date;
|
|
614
|
-
}
|
|
609
|
+
export { AnalyticsEvent }
|
|
615
610
|
|
|
616
|
-
export
|
|
611
|
+
export { AnalyticsFailure }
|
|
617
612
|
|
|
618
|
-
|
|
619
|
-
* `sum` / `avg` = numeric aggregation on a property field. */
|
|
620
|
-
export declare type AnalyticsMetric = 'count' | 'unique' | {
|
|
621
|
-
readonly sum: string;
|
|
622
|
-
} | {
|
|
623
|
-
readonly avg: string;
|
|
624
|
-
};
|
|
613
|
+
export { AnalyticsMetric }
|
|
625
614
|
|
|
626
615
|
export declare interface AnalyticsMirrorHandle {
|
|
627
616
|
/** Tables actually being mirrored (the sink's `mirror.tables`). Empty
|
|
@@ -643,68 +632,9 @@ export declare interface AnalyticsMirrorHandle {
|
|
|
643
632
|
readonly stats: () => AnalyticsMirrorStats;
|
|
644
633
|
}
|
|
645
634
|
|
|
646
|
-
|
|
647
|
-
* Optional CDC-mirror capability. A sink that declares `mirror` opts in
|
|
648
|
-
* to receiving the main DataStore's reactive-table changes, so
|
|
649
|
-
* analytical queries can JOIN warehouse events against live user data
|
|
650
|
-
* (`SELECT … FROM voltro_events e JOIN users u ON …`).
|
|
651
|
-
*
|
|
652
|
-
* The framework subscribes to `DataStore.onChange` once at boot, filters
|
|
653
|
-
* to the tables the sink lists in `tables`, and routes each change here.
|
|
654
|
-
* Inserts/updates `upsert` by primary key; deletes `remove`. Every call
|
|
655
|
-
* MUST be idempotent — the same change may be re-delivered after a
|
|
656
|
-
* reconnect, and the upsert is keyed on `primaryKey` so re-applying a
|
|
657
|
-
* row is a no-op-equivalent overwrite.
|
|
658
|
-
*
|
|
659
|
-
* Idempotent is not enough on its own: re-delivery can also arrive OUT
|
|
660
|
-
* OF ORDER, so both methods additionally receive a {@link MirrorVersion}
|
|
661
|
-
* and MUST ignore a write whose version is not greater than the version
|
|
662
|
-
* already stored for that key (ClickHouse gets this from
|
|
663
|
-
* `ReplacingMergeTree(version)`; DuckDB from an `ON CONFLICT … WHERE
|
|
664
|
-
* excluded.version > version` guard).
|
|
665
|
-
*/
|
|
666
|
-
export declare interface AnalyticsMirrorImpl {
|
|
667
|
-
/** Reactive tables this sink mirrors. The framework only forwards
|
|
668
|
-
* changes whose `table` is in this set. */
|
|
669
|
-
readonly tables: ReadonlyArray<string>;
|
|
670
|
-
/** Primary-key column the sink upserts/deletes by. Defaults to `'id'`
|
|
671
|
-
* when omitted. */
|
|
672
|
-
readonly primaryKey?: string;
|
|
673
|
-
/** Apply an insert/update. Idempotent upsert keyed on `primaryKey`,
|
|
674
|
-
* version-guarded by `write.version`. */
|
|
675
|
-
readonly upsert: (write: AnalyticsMirrorUpsert) => Effect.Effect<void, AnalyticsFailure>;
|
|
676
|
-
/** Apply a delete. Idempotent — removing an absent key is a no-op —
|
|
677
|
-
* and version-guarded by `write.version`. */
|
|
678
|
-
readonly remove: (write: AnalyticsMirrorRemove) => Effect.Effect<void, AnalyticsFailure>;
|
|
679
|
-
/**
|
|
680
|
-
* The highest version this sink has PERSISTED for one key — `null` when
|
|
681
|
-
* the key has never been written (a tombstoned key still reports its
|
|
682
|
-
* tombstone's version; both warehouse sinks keep tombstones for exactly
|
|
683
|
-
* this reason).
|
|
684
|
-
*
|
|
685
|
-
* This is the fleet-scope seed read: a replica that joins mid-stream has
|
|
686
|
-
* no per-key history of its own, so before its first write to a key it
|
|
687
|
-
* asks the warehouse where the fleet already is and continues from
|
|
688
|
-
* there. Without it a joiner would restart the key's versions low and
|
|
689
|
-
* every write it produced would be silently rejected by the sink's own
|
|
690
|
-
* `version >` guard. Called at most once per key per process (off the
|
|
691
|
-
* commit path, inside the per-key drain worker), never per change.
|
|
692
|
-
*/
|
|
693
|
-
readonly maxVersion: (input: {
|
|
694
|
-
readonly table: string;
|
|
695
|
-
readonly primaryKeyValue: unknown;
|
|
696
|
-
}) => Effect.Effect<MirrorVersion | null, AnalyticsFailure>;
|
|
697
|
-
}
|
|
635
|
+
export { AnalyticsMirrorImpl }
|
|
698
636
|
|
|
699
|
-
|
|
700
|
-
export declare interface AnalyticsMirrorRemove {
|
|
701
|
-
readonly table: string;
|
|
702
|
-
/** Primary-key value of the removed row. */
|
|
703
|
-
readonly primaryKeyValue: unknown;
|
|
704
|
-
/** See {@link MirrorVersion}. A delete is ordered against upserts of
|
|
705
|
-
* the same key by exactly this number. */
|
|
706
|
-
readonly version: MirrorVersion;
|
|
707
|
-
}
|
|
637
|
+
export { AnalyticsMirrorRemove }
|
|
708
638
|
|
|
709
639
|
/** Counters a caller (boot log, inspect endpoint, test) can read. */
|
|
710
640
|
export declare interface AnalyticsMirrorStats {
|
|
@@ -765,15 +695,7 @@ export declare interface AnalyticsMirrorTunables {
|
|
|
765
695
|
readonly versionStateLimit: number;
|
|
766
696
|
}
|
|
767
697
|
|
|
768
|
-
|
|
769
|
-
export declare interface AnalyticsMirrorUpsert {
|
|
770
|
-
readonly table: string;
|
|
771
|
-
/** Post-image of the changed row. */
|
|
772
|
-
readonly row: Readonly<Record<string, unknown>>;
|
|
773
|
-
/** See {@link MirrorVersion} — persist it, compare against it, never
|
|
774
|
-
* replace it with a local clock reading. */
|
|
775
|
-
readonly version: MirrorVersion;
|
|
776
|
-
}
|
|
698
|
+
export { AnalyticsMirrorUpsert }
|
|
777
699
|
|
|
778
700
|
/**
|
|
779
701
|
* Context.Tag the framework provides at runtime. Handlers grab it via
|
|
@@ -787,50 +709,14 @@ export declare class AnalyticsSink extends AnalyticsSink_base {
|
|
|
787
709
|
|
|
788
710
|
declare const AnalyticsSink_base: Context.ServiceClass<AnalyticsSink, "@voltro/AnalyticsSink", AnalyticsSinkImpl>;
|
|
789
711
|
|
|
790
|
-
|
|
791
|
-
* The runtime contract every analytics provider implements. Plugins
|
|
792
|
-
* build a value of this shape inside their factory function and the
|
|
793
|
-
* framework wires it under `AnalyticsSink` for handler code to consume.
|
|
794
|
-
*/
|
|
795
|
-
export declare interface AnalyticsSinkImpl {
|
|
796
|
-
readonly info: AnalyticsSinkInfo;
|
|
797
|
-
readonly track: (event: AnalyticsEvent) => Effect.Effect<void, AnalyticsFailure>;
|
|
798
|
-
readonly aggregate: (query: AggregateQuery) => Effect.Effect<number, AnalyticsFailure>;
|
|
799
|
-
readonly timeseries: (query: TimeseriesQuery) => Effect.Effect<ReadonlyArray<AnalyticsBucket>, AnalyticsFailure>;
|
|
800
|
-
readonly topN: (query: TopNQuery) => Effect.Effect<ReadonlyArray<AnalyticsTopEntry>, AnalyticsFailure>;
|
|
801
|
-
/**
|
|
802
|
-
* Present when the sink mirrors reactive tables (opt-in via the
|
|
803
|
-
* plugin's `mirrorTables` config). Absent → no mirroring; the
|
|
804
|
-
* framework skips wiring `DataStore.onChange` for this sink.
|
|
805
|
-
*/
|
|
806
|
-
readonly mirror?: AnalyticsMirrorImpl;
|
|
807
|
-
}
|
|
712
|
+
export { AnalyticsSinkImpl }
|
|
808
713
|
|
|
809
|
-
|
|
810
|
-
* Per-sink metadata surfaced via the manifest endpoint + dashboard.
|
|
811
|
-
* Lets the operator see at a glance which provider is wired + what
|
|
812
|
-
* it supports without grepping app.config.ts.
|
|
813
|
-
*/
|
|
814
|
-
export declare interface AnalyticsSinkInfo {
|
|
815
|
-
readonly provider: string;
|
|
816
|
-
readonly capabilities: {
|
|
817
|
-
readonly track: boolean;
|
|
818
|
-
readonly aggregate: boolean;
|
|
819
|
-
readonly timeseries: boolean;
|
|
820
|
-
readonly topN: boolean;
|
|
821
|
-
/** True when the sink mirrors reactive tables into the warehouse so
|
|
822
|
-
* analytical queries can JOIN events against live user data. */
|
|
823
|
-
readonly mirror: boolean;
|
|
824
|
-
};
|
|
825
|
-
/** Optional plugin-supplied detail (`{ ingestBufferDepth: 42 }`,
|
|
826
|
-
* `{ url: 'https://eu.posthog.com' }`, etc.) — surfaced verbatim. */
|
|
827
|
-
readonly detail?: Readonly<Record<string, unknown>>;
|
|
828
|
-
}
|
|
714
|
+
export { AnalyticsSinkInfo }
|
|
829
715
|
|
|
830
716
|
/**
|
|
831
717
|
* What a plugin factory returns at app.config.ts time. The framework
|
|
832
718
|
* boot path reads `apiConfig.analytics` (an `AnalyticsSinkSpec`), calls
|
|
833
|
-
* `spec.build
|
|
719
|
+
* the dependency-specific `spec.build` to materialise the `AnalyticsSinkImpl`, and
|
|
834
720
|
* provides it under the `AnalyticsSink` Tag.
|
|
835
721
|
*
|
|
836
722
|
* Specs can declare `tables` to merge into the framework's schema
|
|
@@ -839,16 +725,10 @@ export declare interface AnalyticsSinkInfo {
|
|
|
839
725
|
* sink is wired but BEFORE rpc routes open (handshakes, dependency
|
|
840
726
|
* pings, batch-buffer warmups).
|
|
841
727
|
*/
|
|
842
|
-
|
|
728
|
+
declare interface AnalyticsSinkLifecycle {
|
|
843
729
|
/** Discriminator surfaced in boot logs + inspect ('postgres-analytics',
|
|
844
730
|
* 'duckdb', 'clickhouse', 'tinybird', 'posthog', 'compose', 'noop'). */
|
|
845
731
|
readonly kind: string;
|
|
846
|
-
/**
|
|
847
|
-
* Materialise the sink at boot. Receives the framework's SqlClient
|
|
848
|
-
* (bound to the main DataStore by default). Plugins that don't need
|
|
849
|
-
* SqlClient ignore the argument.
|
|
850
|
-
*/
|
|
851
|
-
readonly build: (sqlClient: SqlClient.SqlClient) => AnalyticsSinkImpl;
|
|
852
732
|
/** Optional schema tables the framework should create on first boot.
|
|
853
733
|
* Erased to `unknown` — the framework only forwards them to the
|
|
854
734
|
* schema applier, which accepts opaque table descriptors. */
|
|
@@ -871,10 +751,16 @@ export declare interface AnalyticsSinkSpec {
|
|
|
871
751
|
readonly dispose?: (impl: AnalyticsSinkImpl) => Effect.Effect<void, never>;
|
|
872
752
|
}
|
|
873
753
|
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
readonly
|
|
877
|
-
|
|
754
|
+
/** Explicit SQL dependency: independent sinks boot without an application SQL store. */
|
|
755
|
+
export declare type AnalyticsSinkSpec = AnalyticsSinkLifecycle & ({
|
|
756
|
+
readonly sql: 'required';
|
|
757
|
+
readonly build: (sqlClient: SqlClient.SqlClient) => AnalyticsSinkImpl;
|
|
758
|
+
} | {
|
|
759
|
+
readonly sql: 'none';
|
|
760
|
+
readonly build: () => AnalyticsSinkImpl;
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
export { AnalyticsTopEntry }
|
|
878
764
|
|
|
879
765
|
/**
|
|
880
766
|
* Answer one probe.
|
|
@@ -914,6 +800,12 @@ export declare const API_CSP = "default-src 'none'; frame-ancestors 'none'; base
|
|
|
914
800
|
|
|
915
801
|
export declare const API_KEYS_TABLE = "_voltro_api_keys";
|
|
916
802
|
|
|
803
|
+
export declare const API_ROLE_BUCKET_MS: number;
|
|
804
|
+
|
|
805
|
+
export declare const API_ROLE_WINDOW_MS: number;
|
|
806
|
+
|
|
807
|
+
export declare const API_ROLE_WORKLOAD_BUCKETS_TABLE = "_voltro_api_role_workload_buckets";
|
|
808
|
+
|
|
917
809
|
/** Caller side: the token this app presents to the api it binds as `name`. */
|
|
918
810
|
export declare const apiBindingTokenEnv: (name: string) => string;
|
|
919
811
|
|
|
@@ -1097,6 +989,29 @@ export declare interface ApiKeyUsageDelta {
|
|
|
1097
989
|
readonly lastUsedAt: number;
|
|
1098
990
|
}
|
|
1099
991
|
|
|
992
|
+
/** A process can select multiple roles. Attribute once to the canonical role set,
|
|
993
|
+
* never once per role (which would multiply the observed loop time). */
|
|
994
|
+
export declare const apiRoleMetricLabel: (roles: ReadonlyArray<string>) => string;
|
|
995
|
+
|
|
996
|
+
export { ApiRoleWindowAssessment }
|
|
997
|
+
|
|
998
|
+
/** Persist one finalized five-minute interval per process incarnation. Seconds
|
|
999
|
+
* are exclusive active-loop increments, NOT cumulative counter snapshots. */
|
|
1000
|
+
export declare interface ApiRoleWorkloadBucket {
|
|
1001
|
+
readonly replicaId: string;
|
|
1002
|
+
readonly startedAt: number;
|
|
1003
|
+
readonly role: string;
|
|
1004
|
+
readonly from: number;
|
|
1005
|
+
readonly until: number;
|
|
1006
|
+
/** Only actual continuous observation can set this true. */
|
|
1007
|
+
readonly continuous: boolean;
|
|
1008
|
+
/** Each required workload must have explicit complete coverage and a value. */
|
|
1009
|
+
readonly workloads: Readonly<Partial<Record<ApiWorkload, {
|
|
1010
|
+
readonly coverage: 'partial' | 'complete';
|
|
1011
|
+
readonly seconds: number;
|
|
1012
|
+
}>>>;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1100
1015
|
/**
|
|
1101
1016
|
* Typed authorization slice on `ctx.access` — the ergonomic, cast-free face of
|
|
1102
1017
|
* the caller's EFFECTIVE scope set (raw subject scopes ∪ rbac role-derived
|
|
@@ -1112,7 +1027,9 @@ export declare interface AppAccess {
|
|
|
1112
1027
|
readonly hasAny: (scopes: ReadonlyArray<string>) => boolean;
|
|
1113
1028
|
/** Effect guard — fails with a typed `ScopeError` when the caller lacks
|
|
1114
1029
|
* `scope`. `yield* ctx.access.require('notes:write')` at the top of a
|
|
1115
|
-
* handler mirrors a descriptor `guards:` entry for in-body branching.
|
|
1030
|
+
* handler mirrors a descriptor `guards:` entry for in-body branching.
|
|
1031
|
+
* Reauthenticates bound authority when the Effect executes. Authentication
|
|
1032
|
+
* or authority-source failures abort rather than becoming scope decisions. */
|
|
1116
1033
|
readonly require: (scope: string) => Effect.Effect<void, ScopeError>;
|
|
1117
1034
|
/** The caller's effective scope set (live — reflects rbac resolution). */
|
|
1118
1035
|
readonly scopes: ReadonlyArray<string>;
|
|
@@ -1508,6 +1425,18 @@ export declare const assertWebhookRoutesDeclareVerification: (routes: ReadonlyMa
|
|
|
1508
1425
|
readonly handle: unknown;
|
|
1509
1426
|
}> | undefined) => void;
|
|
1510
1427
|
|
|
1428
|
+
/** Last 24 COMPLETED hours in five-minute buckets (at most five minutes behind
|
|
1429
|
+
* now). Never interpolate a partial boundary bucket or merge process restarts.
|
|
1430
|
+
* Doctor and panels consume this same decision; unknown work is never zero. */
|
|
1431
|
+
export declare const assessApiRoleWorkloadWindow: (input: {
|
|
1432
|
+
readonly now: number;
|
|
1433
|
+
readonly replicaId: string;
|
|
1434
|
+
readonly startedAt: number;
|
|
1435
|
+
readonly role: string;
|
|
1436
|
+
readonly requiredWorkloads: ReadonlyArray<ApiWorkload>;
|
|
1437
|
+
readonly buckets: ReadonlyArray<ApiRoleWorkloadBucket>;
|
|
1438
|
+
}) => ApiRoleWindowAssessment;
|
|
1439
|
+
|
|
1511
1440
|
/**
|
|
1512
1441
|
* Assign a subject to a variant — STABLE (same subject ⇒ same variant, always)
|
|
1513
1442
|
* and BALANCED (proportions converge to the weights over many subjects). The
|
|
@@ -1798,7 +1727,7 @@ export declare const bindConnectionCredential: (clientId: number, credential: Co
|
|
|
1798
1727
|
* interrupt registry subscriptions use — so one reconnect policy, one devtools
|
|
1799
1728
|
* view, one connection lifecycle for both primitives.
|
|
1800
1729
|
*/
|
|
1801
|
-
export declare const bindEvent: (input: BindEventInput) => Stream.Stream<EventStreamEvent<unknown>, ScopeError | Unauthenticated | NoSuchResource, SubjectService | ConnectionInfo>;
|
|
1730
|
+
export declare const bindEvent: (input: BindEventInput) => Stream.Stream<EventStreamEvent<unknown>, ScopeError | Unauthenticated | RequestedTenantRefused | NoSuchResource, SubjectService | ConnectionInfo>;
|
|
1802
1731
|
|
|
1803
1732
|
export declare interface BindEventInput {
|
|
1804
1733
|
readonly bus: EventBus;
|
|
@@ -1818,9 +1747,12 @@ export declare interface BindEventInput {
|
|
|
1818
1747
|
* this bridge must treat it as "no check", not as a guard.
|
|
1819
1748
|
*/
|
|
1820
1749
|
readonly guards?: DeclaredAccess<unknown> | undefined;
|
|
1750
|
+
/** The descriptor requirement and captured app policy must match exactly. */
|
|
1751
|
+
readonly requiredClientPolicy?: string;
|
|
1752
|
+
readonly clientPolicy?: EventClientPolicy;
|
|
1821
1753
|
}
|
|
1822
1754
|
|
|
1823
|
-
export declare const bindMutation: <Input, Output, E = never>(execute: (input: Input, context: RuntimeContext) => Output | Promise<Output> | Effect.Effect<Output, E, never>, input: Input, spanName?: string, codec?:
|
|
1755
|
+
export declare const bindMutation: <Input, Output, E = never>(execute: (input: Input, context: RuntimeContext) => Output | Promise<Output> | Effect.Effect<Output, E, never>, input: Input, spanName?: string, codec?: MutationCodec<unknown>, idempotency?: IdempotencyBinding,
|
|
1824
1756
|
/**
|
|
1825
1757
|
* This procedure's DECLARED error union (`descriptor.error`).
|
|
1826
1758
|
*
|
|
@@ -1872,7 +1804,12 @@ guards?: ReadonlyArray<unknown> | undefined,
|
|
|
1872
1804
|
* (`{ scope: 'x:read', from: 'id' }`) can see which resource was asked for.
|
|
1873
1805
|
* Passed explicitly rather than read off RuntimeContext, which does not
|
|
1874
1806
|
* carry it. */
|
|
1875
|
-
guardInput?: unknown
|
|
1807
|
+
guardInput?: unknown,
|
|
1808
|
+
/** Plugin admission wraps construction once; element guards remain live. */
|
|
1809
|
+
admission?: {
|
|
1810
|
+
readonly tag: string;
|
|
1811
|
+
readonly interceptor?: ServeRpcInterceptor | undefined;
|
|
1812
|
+
}) => Stream.Stream<Element, Err, SubjectService | ConnectionInfo>;
|
|
1876
1813
|
|
|
1877
1814
|
/**
|
|
1878
1815
|
* Build a `Stream<SubscriptionEvent<T>>` that an effect/rpc streaming
|
|
@@ -1959,6 +1896,16 @@ export declare interface BootListener {
|
|
|
1959
1896
|
* Installed by the boot path when its store exists, which is after the
|
|
1960
1897
|
* bind; an app-declared `health.readiness` replaces the whole check. */
|
|
1961
1898
|
readonly setDependencyPing: (ping: () => Promise<boolean>) => void;
|
|
1899
|
+
/** Required local runtime conditions, independent of app dependency policy.
|
|
1900
|
+
* Checks must be synchronous and cheap. Release removes only this registration. */
|
|
1901
|
+
/** Enable structured API health using captured role/workload identities. */
|
|
1902
|
+
readonly setRoleHealth: (identity: {
|
|
1903
|
+
readonly roles: ReadonlyArray<string>;
|
|
1904
|
+
readonly workloads: ReadonlyArray<string>;
|
|
1905
|
+
}) => void;
|
|
1906
|
+
readonly addReadinessGate: (name: string, check: () => boolean) => () => void;
|
|
1907
|
+
/** Required local progress conditions. App liveness cannot bypass these gates. */
|
|
1908
|
+
readonly addLivenessGate: (name: string, check: () => boolean) => () => void;
|
|
1962
1909
|
/** Close the socket. Resolves once node reports the listener closed. */
|
|
1963
1910
|
readonly close: () => Promise<void>;
|
|
1964
1911
|
}
|
|
@@ -2053,6 +2000,40 @@ export declare const buildTracingLayer: (options?: TracingOptions) => Promise<Tr
|
|
|
2053
2000
|
* hit on every read. `now` injectable for tests. */
|
|
2054
2001
|
export declare const cachedBackend: (backend: SecretsBackend, ttlMs?: number, now?: () => number) => SecretsBackend;
|
|
2055
2002
|
|
|
2003
|
+
export declare const cachedComputedCall: (args: CachedComputedCallArgs) => Effect.Effect<CachedComputedResult, unknown, never>;
|
|
2004
|
+
|
|
2005
|
+
declare interface CachedComputedCallArgs {
|
|
2006
|
+
readonly cache: ComputedQueryCacheDeps;
|
|
2007
|
+
readonly policy: ComputedQueryCachePolicy;
|
|
2008
|
+
readonly key: string;
|
|
2009
|
+
readonly name: string;
|
|
2010
|
+
readonly sources: ReadonlyArray<string>;
|
|
2011
|
+
readonly output: Schema.Top | undefined;
|
|
2012
|
+
readonly subject: object;
|
|
2013
|
+
readonly rowFilter: RowFilterScope | undefined;
|
|
2014
|
+
readonly ctx: object;
|
|
2015
|
+
readonly signal?: AbortSignal;
|
|
2016
|
+
/** Run the handler to a value against the OBSERVED context and subject. */
|
|
2017
|
+
readonly execute: (observedCtx: object, observedSubject: object) => Promise<unknown>;
|
|
2018
|
+
/** The handler returned a descriptor — the snapshot cache owns that query. */
|
|
2019
|
+
readonly onDescriptor: () => void;
|
|
2020
|
+
readonly isDescriptor: (value: unknown) => boolean;
|
|
2021
|
+
readonly unwrap: (value: unknown) => unknown;
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
/**
|
|
2025
|
+
* Serve one computed call through the cache: a hit, or the handler run under
|
|
2026
|
+
* observation and its result kept — or not — by `decideComputedStore`. The
|
|
2027
|
+
* caller authorizes BEFORE and re-authorizes the delivered value AFTER; this
|
|
2028
|
+
* function only decides what the cache does.
|
|
2029
|
+
*/
|
|
2030
|
+
/** A cached call's value, and the tables a live query built from it must also
|
|
2031
|
+
* recompute on (read by the handler, not named in `source:`). */
|
|
2032
|
+
declare interface CachedComputedResult {
|
|
2033
|
+
readonly value: unknown;
|
|
2034
|
+
readonly dependencies: ReadonlyArray<string>;
|
|
2035
|
+
}
|
|
2036
|
+
|
|
2056
2037
|
/** One leak: a query caching ONE entry across every caller while reading a
|
|
2057
2038
|
* table whose rows are scoped per tenant. */
|
|
2058
2039
|
export declare interface CacheScopeLeak {
|
|
@@ -2125,13 +2106,7 @@ export declare interface CandidateShape {
|
|
|
2125
2106
|
export declare const canonicalInputKey: (input: unknown) => string;
|
|
2126
2107
|
|
|
2127
2108
|
/* Excluded from this release type: canonicalize */
|
|
2128
|
-
|
|
2129
|
-
/**
|
|
2130
|
-
* Canonical JSON — object keys sorted recursively, so two structurally equal
|
|
2131
|
-
* inputs that differ only in key order digest identically. A retry from a
|
|
2132
|
-
* different client build must not mint a second approval.
|
|
2133
|
-
*/
|
|
2134
|
-
export declare const canonicalJson: (value: unknown) => string;
|
|
2109
|
+
export { canonicalJson }
|
|
2135
2110
|
|
|
2136
2111
|
export { CaughtUpVerdict }
|
|
2137
2112
|
|
|
@@ -2151,6 +2126,29 @@ export declare interface CdcDelta {
|
|
|
2151
2126
|
readonly new?: Row_3 | null;
|
|
2152
2127
|
}
|
|
2153
2128
|
|
|
2129
|
+
/** What a cell's envelopes can be bound to. */
|
|
2130
|
+
export declare interface CellContext {
|
|
2131
|
+
readonly table: string;
|
|
2132
|
+
readonly column: string;
|
|
2133
|
+
/** The cell's row: its primary key, and every other column (for ids a copy carries). */
|
|
2134
|
+
readonly rowId: unknown;
|
|
2135
|
+
readonly row: Readonly<Record<string, unknown>>;
|
|
2136
|
+
/** Every `.encrypted()` column the app declares, by table. */
|
|
2137
|
+
readonly declared: ReadonlyMap<string, ReadonlySet<string>>;
|
|
2138
|
+
/** Declared renames (`declaredRenames`): the old names a value of this cell may still be bound to. */
|
|
2139
|
+
readonly renames?: ReadonlyMap<string, DeclaredRename>;
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
/** What a cell's re-key did. */
|
|
2143
|
+
export declare interface CellRekey {
|
|
2144
|
+
/** The cell's new text — equal to the input when nothing changed. */
|
|
2145
|
+
readonly text: string;
|
|
2146
|
+
readonly rekeyed: number;
|
|
2147
|
+
readonly current: number;
|
|
2148
|
+
/** Envelopes no candidate address opened — left as they are. */
|
|
2149
|
+
readonly unresolved: number;
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2154
2152
|
export { ChangeEvent }
|
|
2155
2153
|
|
|
2156
2154
|
/** A mutation invocation's full change-set — the unit of undo. */
|
|
@@ -2166,50 +2164,24 @@ export declare interface ChangeSet {
|
|
|
2166
2164
|
readonly crossesAction?: boolean;
|
|
2167
2165
|
}
|
|
2168
2166
|
|
|
2169
|
-
export declare interface CircuitBreaker {
|
|
2170
|
-
/** Run an effect through the breaker. OPEN ⇒ fails fast with CircuitOpen. */
|
|
2171
|
-
<A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E | CircuitOpen, R>;
|
|
2172
|
-
/** Current state — reads the Ref. */
|
|
2173
|
-
readonly state: Effect.Effect<CircuitState>;
|
|
2174
|
-
/** Force the breaker back to closed (clears counters). */
|
|
2175
|
-
readonly reset: Effect.Effect<void>;
|
|
2176
|
-
}
|
|
2177
|
-
|
|
2178
|
-
export declare const CircuitBreaker: {
|
|
2179
|
-
/** Construct a breaker. Effect-returning because it allocates a Ref. */
|
|
2180
|
-
readonly make: (options: CircuitBreakerOptions) => Effect.Effect<CircuitBreaker>;
|
|
2181
|
-
};
|
|
2182
|
-
|
|
2183
|
-
export declare interface CircuitBreakerOptions {
|
|
2184
|
-
/** Consecutive failures before the breaker opens. */
|
|
2185
|
-
readonly failureThreshold: number;
|
|
2186
|
-
/** Wait before transitioning open → half-open (Duration or string). */
|
|
2187
|
-
readonly resetTimeout: Duration.Input;
|
|
2188
|
-
/** Successes required in half-open before closing again. Default 1. */
|
|
2189
|
-
readonly halfOpenSuccessThreshold?: number;
|
|
2190
|
-
/** Predicate: does this error count toward the threshold? Default: all
|
|
2191
|
-
* typed failures count. Interruptions NEVER count (they're not a
|
|
2192
|
-
* downstream failure — the caller went away). */
|
|
2193
|
-
readonly isFailure?: (error: unknown) => boolean;
|
|
2194
|
-
/** Optional name for inspect / metrics + dashboard surfacing. */
|
|
2195
|
-
readonly name?: string;
|
|
2196
|
-
}
|
|
2197
|
-
|
|
2198
2167
|
/**
|
|
2199
|
-
*
|
|
2200
|
-
*
|
|
2168
|
+
* The same checks as {@link verifyFieldKeyring}, writing nothing — for a dry
|
|
2169
|
+
* run. Answers which key the database records as active (`undefined` before
|
|
2170
|
+
* the first boot recorded any) and which one would wait for the fleet.
|
|
2201
2171
|
*/
|
|
2202
|
-
export declare
|
|
2203
|
-
|
|
2172
|
+
export declare const checkFieldKeyring: (store: DataStore, keyring: FieldKeyring, tables: Iterable<unknown>) => Promise<{
|
|
2173
|
+
readonly active: string | undefined;
|
|
2174
|
+
readonly requested?: string;
|
|
2175
|
+
readonly notes: ReadonlyArray<string>;
|
|
2176
|
+
}>;
|
|
2204
2177
|
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
}>, Cause.YieldableError>;
|
|
2178
|
+
export { CircuitBreaker }
|
|
2179
|
+
|
|
2180
|
+
export { CircuitBreakerOptions }
|
|
2181
|
+
|
|
2182
|
+
export { CircuitOpen }
|
|
2211
2183
|
|
|
2212
|
-
export
|
|
2184
|
+
export { CircuitState }
|
|
2213
2185
|
|
|
2214
2186
|
/** How many bucket widths of predecessors a won claim leaves behind. */
|
|
2215
2187
|
export declare const CLAIM_RETENTION_BUCKETS = 64;
|
|
@@ -2382,7 +2354,7 @@ export declare interface CompleteOAuthResult {
|
|
|
2382
2354
|
/**
|
|
2383
2355
|
* Combine multiple analytics specs into one composite spec at
|
|
2384
2356
|
* app.config.ts time. The framework's boot path materialises each
|
|
2385
|
-
* child spec
|
|
2357
|
+
* child spec with its declared SQL dependency and wires them through
|
|
2386
2358
|
* `composeAnalyticsSinks` so they behave as one logical sink.
|
|
2387
2359
|
*
|
|
2388
2360
|
* `track()` fans out to every child; reads route to the first child
|
|
@@ -2390,12 +2362,12 @@ export declare interface CompleteOAuthResult {
|
|
|
2390
2362
|
*
|
|
2391
2363
|
* Tables contributed by ANY child get merged. `initialize` effects
|
|
2392
2364
|
* run sequentially in declaration order; `dispose` effects (teardown)
|
|
2393
|
-
*
|
|
2365
|
+
* await each child in reverse order — only present on the
|
|
2394
2366
|
* composite when at least one child does.
|
|
2395
2367
|
*
|
|
2396
2368
|
* analytics: composeAnalytics([
|
|
2397
2369
|
* postgresAnalytics(), // primary: handles reads
|
|
2398
|
-
* posthogAnalytics({ apiKey:
|
|
2370
|
+
* posthogAnalytics({ apiKey: process.env.POSTHOG_API_KEY! }),
|
|
2399
2371
|
* ])
|
|
2400
2372
|
*/
|
|
2401
2373
|
export declare const composeAnalytics: (specs: ReadonlyArray<AnalyticsSinkSpec>) => AnalyticsSinkSpec;
|
|
@@ -2439,6 +2411,44 @@ export declare interface CompressionOptions {
|
|
|
2439
2411
|
readonly minBytes?: number;
|
|
2440
2412
|
}
|
|
2441
2413
|
|
|
2414
|
+
/** Why a call is not looked up at all. */
|
|
2415
|
+
declare type ComputedCacheBypass = 'input-not-encodable' | 'no-tenant' | 'anonymous-subject';
|
|
2416
|
+
|
|
2417
|
+
/**
|
|
2418
|
+
* The entry one call belongs to — or why it has none.
|
|
2419
|
+
*
|
|
2420
|
+
* Every part is something a different answer could hang on: the query and the
|
|
2421
|
+
* build that runs it (a redis cache outlives a deploy, and two releases share
|
|
2422
|
+
* it during a rolling one), the output shape, the ENCODED input (so a `Date`,
|
|
2423
|
+
* a `bigint` or a branded id keys by its wire form, and two spellings of one
|
|
2424
|
+
* input share an entry), the scope's caller part, and the row-filter
|
|
2425
|
+
* visibility the caller's reads of the declared tables resolve to.
|
|
2426
|
+
*/
|
|
2427
|
+
export declare const computedCacheKey: (args: ComputedCacheKeyInput) => {
|
|
2428
|
+
readonly key: string;
|
|
2429
|
+
} | {
|
|
2430
|
+
readonly bypass: ComputedCacheBypass;
|
|
2431
|
+
};
|
|
2432
|
+
|
|
2433
|
+
declare interface ComputedCacheKeyInput {
|
|
2434
|
+
readonly name: string;
|
|
2435
|
+
/** The running build — see `codeIdentity` on the boot side. */
|
|
2436
|
+
readonly codeIdentity: string;
|
|
2437
|
+
readonly output: Schema.Top | undefined;
|
|
2438
|
+
readonly input: Schema.Top | undefined;
|
|
2439
|
+
readonly decodedInput: unknown;
|
|
2440
|
+
readonly scope: ComputedCacheScope;
|
|
2441
|
+
readonly subject: {
|
|
2442
|
+
readonly id?: string | null | undefined;
|
|
2443
|
+
readonly type?: string | undefined;
|
|
2444
|
+
readonly tenantId?: string | null | undefined;
|
|
2445
|
+
};
|
|
2446
|
+
readonly rowFilter: RowFilterScope | undefined;
|
|
2447
|
+
readonly declaredSources: ReadonlyArray<string>;
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
declare type ComputedCacheScope = 'subject' | 'tenant' | 'global';
|
|
2451
|
+
|
|
2442
2452
|
declare interface ComputedQuery {
|
|
2443
2453
|
readonly __voltroComputed: true;
|
|
2444
2454
|
/** The initial computed value — emitted verbatim as the first snapshot. */
|
|
@@ -2452,6 +2462,56 @@ declare interface ComputedQuery {
|
|
|
2452
2462
|
readonly recompute: () => Promise<unknown>;
|
|
2453
2463
|
}
|
|
2454
2464
|
|
|
2465
|
+
/** Is capture on? The request store builder wraps its store when it is. */
|
|
2466
|
+
export declare const computedQueryCacheCaptureInstalled: () => boolean;
|
|
2467
|
+
|
|
2468
|
+
/**
|
|
2469
|
+
* The cache a COMPUTED query's handler invocation is served through. Both boot
|
|
2470
|
+
* paths build it over the app's `Cache` (`wrapDynamic`), and so does
|
|
2471
|
+
* `@voltro/testing`'s `invoke`; absent ⇒ computed queries are never cached.
|
|
2472
|
+
*/
|
|
2473
|
+
export declare interface ComputedQueryCacheDeps {
|
|
2474
|
+
readonly wrapDynamic: <A, E>(key: string, options: {
|
|
2475
|
+
readonly ttlMs: number;
|
|
2476
|
+
readonly swrMs?: number | undefined;
|
|
2477
|
+
readonly leaseMs?: number | undefined;
|
|
2478
|
+
readonly label: string;
|
|
2479
|
+
}, compute: Effect.Effect<{
|
|
2480
|
+
readonly value: A;
|
|
2481
|
+
readonly store?: {
|
|
2482
|
+
readonly stored: unknown;
|
|
2483
|
+
readonly tags: ReadonlyArray<string>;
|
|
2484
|
+
} | undefined;
|
|
2485
|
+
readonly notApplicable?: boolean | undefined;
|
|
2486
|
+
}, E, never>, read: (stored: unknown) => Effect.Effect<Option.Option<A>>) => Effect.Effect<{
|
|
2487
|
+
readonly value: A;
|
|
2488
|
+
readonly served: 'hit' | 'stale' | 'miss';
|
|
2489
|
+
}, E, never>;
|
|
2490
|
+
/** Parse the declared `cache:` (same parser as the descriptor path). */
|
|
2491
|
+
readonly policyFor: (cache: {
|
|
2492
|
+
readonly ttl: number | string;
|
|
2493
|
+
readonly swr?: number | string | undefined;
|
|
2494
|
+
readonly scope: ComputedCacheScope;
|
|
2495
|
+
readonly volatile?: boolean | undefined;
|
|
2496
|
+
}) => ComputedQueryCachePolicy | undefined;
|
|
2497
|
+
/** The running build — part of every key, so a deploy never reads another
|
|
2498
|
+
* release's entries out of a shared cache. */
|
|
2499
|
+
readonly codeIdentity: string;
|
|
2500
|
+
readonly maxEntryBytes: number;
|
|
2501
|
+
/** Cluster single-flight lease, when the backend supports one. */
|
|
2502
|
+
readonly leaseMs?: number | undefined;
|
|
2503
|
+
/** Once-per-(query, reason) notice that a result was not kept. */
|
|
2504
|
+
readonly notice: (query: string, reason: string, message: string) => void;
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
/** A computed query's resolved cache policy — ms, parsed by the boot path. */
|
|
2508
|
+
export declare interface ComputedQueryCachePolicy {
|
|
2509
|
+
readonly ttlMs: number;
|
|
2510
|
+
readonly swrMs: number | undefined;
|
|
2511
|
+
readonly scope: ComputedCacheScope;
|
|
2512
|
+
readonly volatile: boolean;
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2455
2515
|
export declare const CONNECTION_GRANTS_TABLE = "_voltro_connection_grants";
|
|
2456
2516
|
|
|
2457
2517
|
/** What a declaration can learn about the account it just connected. Optional
|
|
@@ -2584,6 +2644,7 @@ export { ConstraintViolation }
|
|
|
2584
2644
|
export declare type CoordinatedEffect = () => void | CoordinatedTickOutcome | Promise<void | CoordinatedTickOutcome>;
|
|
2585
2645
|
|
|
2586
2646
|
export declare interface CoordinatedScheduleDeps {
|
|
2647
|
+
readonly externalTasks?: ExternalizedTaskRegistry;
|
|
2587
2648
|
/** The exactly-once gate. `singleCoordinator` for one-process
|
|
2588
2649
|
* deployments; `makeAdvisoryLockCoordinator(store, replicaId)` for
|
|
2589
2650
|
* multi-instance SQL stores. Injected so this stays testable with a
|
|
@@ -2674,8 +2735,9 @@ export declare interface CoordinatedScheduleDiagnostics {
|
|
|
2674
2735
|
}
|
|
2675
2736
|
|
|
2676
2737
|
export declare interface CoordinatedScheduleHandle {
|
|
2677
|
-
/** Stop the
|
|
2678
|
-
|
|
2738
|
+
/** Stop admission immediately; await the returned completion before releasing
|
|
2739
|
+
* storage. Includes timer and external-trigger claims/effects. Idempotent. */
|
|
2740
|
+
readonly stop: () => void | Promise<void>;
|
|
2679
2741
|
/** The task name (for logging / dedup diagnostics). */
|
|
2680
2742
|
readonly name: string;
|
|
2681
2743
|
/**
|
|
@@ -3377,6 +3439,9 @@ export declare const decideApprovalInvocation: (input: {
|
|
|
3377
3439
|
readonly status: "approved" | "rejected";
|
|
3378
3440
|
}>;
|
|
3379
3441
|
|
|
3442
|
+
/** The app's `.encrypted()` columns, by table. */
|
|
3443
|
+
export declare const declaredEncryptedColumns: (declared: Iterable<unknown>) => ReadonlyMap<string, ReadonlySet<string>>;
|
|
3444
|
+
|
|
3380
3445
|
/**
|
|
3381
3446
|
* `unknown` when the executor's failures are all declared; otherwise a type the
|
|
3382
3447
|
* handler cannot satisfy, whose one property spells out the undeclared tag(s)
|
|
@@ -3389,6 +3454,27 @@ UndeclaredErrorTags<D, R>
|
|
|
3389
3454
|
readonly undeclaredFailure: `'${UndeclaredErrorTags<D, R>}' is not in this procedure's wire union — add it to the descriptor's \`error:\`, register it through a plugin's \`errorSchemas\`, or map it away (Effect.orDie for a defect)`;
|
|
3390
3455
|
};
|
|
3391
3456
|
|
|
3457
|
+
/** A declared rename of a table with sealed columns: the names its values may still be bound to. */
|
|
3458
|
+
export declare interface DeclaredRename {
|
|
3459
|
+
readonly previousTable?: string;
|
|
3460
|
+
/** New column name → the name it was renamed from. */
|
|
3461
|
+
readonly columns: ReadonlyMap<string, string>;
|
|
3462
|
+
}
|
|
3463
|
+
|
|
3464
|
+
/**
|
|
3465
|
+
* The renames the app declares on tables with `.encrypted()` columns —
|
|
3466
|
+
* `table('new').renamedFrom('old')`, a column's `.renamedFrom('old')`. A rename
|
|
3467
|
+
* is catalog-only, so the rows keep values bound to the old names; the re-key
|
|
3468
|
+
* opens them there and seals them under the new ones.
|
|
3469
|
+
*/
|
|
3470
|
+
export declare const declaredRenames: (declared: Iterable<unknown>) => ReadonlyMap<string, DeclaredRename>;
|
|
3471
|
+
|
|
3472
|
+
/** Decode a stored snapshot; `undefined` for anything this version did not
|
|
3473
|
+
* write (an entry from another build reads as a miss). */
|
|
3474
|
+
export declare const decodeSnapshotValue: (stored: unknown) => {
|
|
3475
|
+
readonly value: unknown;
|
|
3476
|
+
} | undefined;
|
|
3477
|
+
|
|
3392
3478
|
/**
|
|
3393
3479
|
* Decrypt a value produced by `encryptField` or by an `.encrypted()` column —
|
|
3394
3480
|
* one encoding, so that sentence is now true in both directions.
|
|
@@ -3954,7 +4040,13 @@ export declare class Dispatcher {
|
|
|
3954
4040
|
private readonly subscriptionRegistry;
|
|
3955
4041
|
private readonly matcher;
|
|
3956
4042
|
private readonly subscriptions;
|
|
3957
|
-
private
|
|
4043
|
+
private unsubscribeChange;
|
|
4044
|
+
private closed;
|
|
4045
|
+
private readonly operations;
|
|
4046
|
+
/** Register synchronously, before user code or the first await can run. */
|
|
4047
|
+
private beginOperation;
|
|
4048
|
+
/** Includes pending initial reads, not only already-visible subscriptions. */
|
|
4049
|
+
private readonly interests;
|
|
3958
4050
|
/**
|
|
3959
4051
|
* Reverse index: tableName → set of subscription ids whose
|
|
3960
4052
|
* dependent-table set INCLUDES that table. A change event on table
|
|
@@ -3980,12 +4072,18 @@ export declare class Dispatcher {
|
|
|
3980
4072
|
/** Query labels already warned about for an undeclared raw read, so a hot
|
|
3981
4073
|
* subscription logs once rather than once per subscriber. */
|
|
3982
4074
|
private readonly rawReadWarned;
|
|
4075
|
+
/** The cache fence each written-through read observed before it started. */
|
|
4076
|
+
private readonly readFences;
|
|
3983
4077
|
private changeEpoch;
|
|
3984
4078
|
private readonly committedReads;
|
|
3985
4079
|
/** The CRDT-managed columns of `table` (empty when it has none) — what a
|
|
3986
4080
|
* subscription's backpressure outbox folds incrementally. */
|
|
3987
4081
|
crdtColumnsFor(table: string): ReadonlySet<string>;
|
|
3988
4082
|
constructor(deps: DispatcherDependencies);
|
|
4083
|
+
private measureLoop;
|
|
4084
|
+
private retainInterest;
|
|
4085
|
+
/** One idempotent terminal path for setup failures, revocation and disconnect. */
|
|
4086
|
+
private removeInterest;
|
|
3989
4087
|
/**
|
|
3990
4088
|
* REL-14 — a raw read that nothing can invalidate, said out loud.
|
|
3991
4089
|
*
|
|
@@ -4056,6 +4154,9 @@ export declare class Dispatcher {
|
|
|
4056
4154
|
* grant comes back.
|
|
4057
4155
|
*/
|
|
4058
4156
|
private revokeSubscription;
|
|
4157
|
+
/** Remove once, including a pending retry and its active metric. In-flight
|
|
4158
|
+
* async reads check identity again before emitting or scheduling anything. */
|
|
4159
|
+
private removeComputed;
|
|
4059
4160
|
/** `revokeSubscription` for the computed path. Same reasoning. */
|
|
4060
4161
|
private revokeComputed;
|
|
4061
4162
|
/**
|
|
@@ -4066,13 +4167,10 @@ export declare class Dispatcher {
|
|
|
4066
4167
|
* Returns an `unsubscribe` the caller MUST invoke on teardown.
|
|
4067
4168
|
*/
|
|
4068
4169
|
subscribeComputed(computed: ComputedQuery, emit: (event: SubscriptionEvent<unknown>) => void, context: RuntimeContext, label?: string): Promise<() => void>;
|
|
4069
|
-
/**
|
|
4070
|
-
*
|
|
4071
|
-
*
|
|
4072
|
-
*
|
|
4073
|
-
* the client materialises as a wholesale base replacement. Best-effort:
|
|
4074
|
-
* a recompute throw is logged, not propagated, so one failing query
|
|
4075
|
-
* can't wedge the change stream. */
|
|
4170
|
+
/** Serialize computed reads. A source change during a pending read asks for
|
|
4171
|
+
* one more read before delivery; an older result cannot overtake newer data.
|
|
4172
|
+
* Ordinary failures are visible in-band and retry independently of changes.
|
|
4173
|
+
* Access withdrawal stays terminal and never enters the retry lane. */
|
|
4076
4174
|
private recomputeComputed;
|
|
4077
4175
|
/** Live snapshot of all fingerprinted subscriptions — used by the
|
|
4078
4176
|
* `/_voltro/inspect/subscriptions` endpoint and DevTools. */
|
|
@@ -4087,6 +4185,9 @@ export declare class Dispatcher {
|
|
|
4087
4185
|
onSubscriptionsChange(listener: () => void): () => void;
|
|
4088
4186
|
/** Tear down the change-event listener. Call on server shutdown. */
|
|
4089
4187
|
close(): void;
|
|
4188
|
+
/** Close admission immediately, then join reads and deliveries before the
|
|
4189
|
+
* owner disposes the store. Do not await this from inside a query callback. */
|
|
4190
|
+
closeAndDrain(): Promise<void>;
|
|
4090
4191
|
/**
|
|
4091
4192
|
* Re-run EVERY live subscription, because this replica proved it missed
|
|
4092
4193
|
* changes it can never recover.
|
|
@@ -4112,6 +4213,8 @@ export declare class Dispatcher {
|
|
|
4112
4213
|
}
|
|
4113
4214
|
|
|
4114
4215
|
export declare interface DispatcherDependencies {
|
|
4216
|
+
/** Active synchronous live-change work only; asynchronous reads are not timed. */
|
|
4217
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
4115
4218
|
readonly store: DataStore;
|
|
4116
4219
|
/** CRDT columns per table (schemaRegistry.crdtColumns). Feeds the
|
|
4117
4220
|
* downstream lane: crdt cells diff as incremental mergeCells ops.
|
|
@@ -4157,6 +4260,8 @@ export declare interface DispatcherDependencies {
|
|
|
4157
4260
|
export declare const DORMANCY_WAKEUP_TENANT = "default";
|
|
4158
4261
|
|
|
4159
4262
|
export declare interface DrainDeps<R = never> {
|
|
4263
|
+
/** Active synchronous handler entry only; never await a Promise inside this measurement. */
|
|
4264
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
4160
4265
|
readonly store: Pick<DataStore, 'query' | 'update' | 'updateMany' | 'insert' | 'delete'>;
|
|
4161
4266
|
readonly handlers: ReadonlyMap<string, OutboxHandlerDefinition<R>>;
|
|
4162
4267
|
/** Execute with the application's services. Required by drainOutbox when R
|
|
@@ -4235,7 +4340,7 @@ export declare interface DrainResult {
|
|
|
4235
4340
|
readonly dead: number;
|
|
4236
4341
|
readonly skipped: number;
|
|
4237
4342
|
/**
|
|
4238
|
-
* How many rows this pass had to look at. `0` means the queue is EMPTY, which
|
|
4343
|
+
* How many rows this pass had to look at. `0` means the eligible queue is EMPTY, which
|
|
4239
4344
|
* a caller cannot otherwise tell from "everything delivered" — both leave
|
|
4240
4345
|
* `delivered` at whatever it was, and only one of them means the poll has
|
|
4241
4346
|
* nothing left to do.
|
|
@@ -4287,7 +4392,7 @@ export declare interface EffectInsertIgnoreOutcomeStore {
|
|
|
4287
4392
|
|
|
4288
4393
|
/** The minimal Effect-store surface `insertManyRowsEffect` needs. */
|
|
4289
4394
|
export declare interface EffectInsertManyStore {
|
|
4290
|
-
readonly insertMany: (table: string, rows: ReadonlyArray<Row
|
|
4395
|
+
readonly insertMany: (table: string, rows: ReadonlyArray<Row>, options?: InsertManyOptions) => Effect.Effect<ReadonlyArray<Row>, StoreError>;
|
|
4291
4396
|
}
|
|
4292
4397
|
|
|
4293
4398
|
/** The minimal Effect-store surface `insertRowEffect` needs. */
|
|
@@ -4311,7 +4416,7 @@ export declare interface EffectStoreOps {
|
|
|
4311
4416
|
* hand-built descriptor. */
|
|
4312
4417
|
readonly query: <R = Row>(descriptor: QueryDescriptor<R>) => Effect.Effect<ReadonlyArray<R>, StoreError>;
|
|
4313
4418
|
readonly insert: (table: string, row: Row) => Effect.Effect<Row, StoreError>;
|
|
4314
|
-
readonly insertMany: (table: string, rows: ReadonlyArray<Row
|
|
4419
|
+
readonly insertMany: (table: string, rows: ReadonlyArray<Row>, options?: InsertManyOptions) => Effect.Effect<ReadonlyArray<Row>, StoreError>;
|
|
4315
4420
|
readonly patchJson: (table: string, primaryKey: string, path: string, value: unknown, additionalPatch?: Readonly<Record<string, unknown>>) => Effect.Effect<Row | null, StoreError>;
|
|
4316
4421
|
readonly update: (table: string, primaryKey: string, patch: Readonly<Record<string, unknown>>) => Effect.Effect<Row | null, StoreError>;
|
|
4317
4422
|
readonly updateMany: (table: string, patch: Readonly<Record<string, unknown>>, options: {
|
|
@@ -4398,6 +4503,10 @@ export declare const emptySchemaRegistry: SchemaRegistry;
|
|
|
4398
4503
|
* should be observed are constructed — `observeStore` decides once, per store. */
|
|
4399
4504
|
export declare const enableGraphObservation: () => void;
|
|
4400
4505
|
|
|
4506
|
+
/** Encode a snapshot for the cache. Throws on a value with no faithful form —
|
|
4507
|
+
* the caller does not store it then. */
|
|
4508
|
+
export declare const encodeSnapshotValue: (value: unknown) => unknown;
|
|
4509
|
+
|
|
4401
4510
|
/**
|
|
4402
4511
|
* Encrypt a value with the registered field cipher, in the SAME encoding an
|
|
4403
4512
|
* `.encrypted()` column uses. Throws if no cipher is registered.
|
|
@@ -4429,15 +4538,22 @@ export declare const enforceApproval: (input: {
|
|
|
4429
4538
|
readonly traceId?: string | undefined;
|
|
4430
4539
|
}) => Promise<void>;
|
|
4431
4540
|
|
|
4432
|
-
|
|
4433
|
-
|
|
4434
|
-
readonly
|
|
4435
|
-
/**
|
|
4436
|
-
readonly
|
|
4437
|
-
|
|
4438
|
-
|
|
4541
|
+
/** One connected engine SDK, as it named itself in `x-voltro-sdk`. It proves nothing and grants nothing. */
|
|
4542
|
+
export declare interface EngineClient {
|
|
4543
|
+
readonly id: string;
|
|
4544
|
+
/** `csharp`, `unity`, `godot` or `unreal`. */
|
|
4545
|
+
readonly target: string;
|
|
4546
|
+
readonly version: string;
|
|
4547
|
+
/** SHA-256 of the API surface the SDK was generated from, or null when it did not say. */
|
|
4548
|
+
readonly surface: string | null;
|
|
4549
|
+
readonly connectedAt: number;
|
|
4439
4550
|
}
|
|
4440
4551
|
|
|
4552
|
+
/** The engine SDKs connected to this process now, oldest first. */
|
|
4553
|
+
export declare const engineClientsSnapshot: () => ReadonlyArray<EngineClient>;
|
|
4554
|
+
|
|
4555
|
+
export { EnqueueOptions }
|
|
4556
|
+
|
|
4441
4557
|
/**
|
|
4442
4558
|
* Attribute the reads that FOLLOW, in this execution context, to `procedure`.
|
|
4443
4559
|
*
|
|
@@ -5410,6 +5526,12 @@ export declare const externalizedTask: (name: string) => ExternalizedTask | unde
|
|
|
5410
5526
|
|
|
5411
5527
|
export declare const externalizedTaskNames: () => ReadonlyArray<string>;
|
|
5412
5528
|
|
|
5529
|
+
export declare interface ExternalizedTaskRegistry {
|
|
5530
|
+
readonly register: (task: ExternalizedTask) => () => void;
|
|
5531
|
+
readonly get: (name: string) => ExternalizedTask | undefined;
|
|
5532
|
+
readonly names: () => ReadonlyArray<string>;
|
|
5533
|
+
}
|
|
5534
|
+
|
|
5413
5535
|
/** Build an Effect `ExternalSpan` parent from a `traceparent` header so
|
|
5414
5536
|
* inbound HTTP work continues the caller's trace. Returns undefined
|
|
5415
5537
|
* when the header is missing/invalid (no parent → a fresh root span). */
|
|
@@ -5473,11 +5595,251 @@ declare type FailureTag<E> = 0 extends (1 & E) ? never : E extends {
|
|
|
5473
5595
|
readonly _tag: infer T;
|
|
5474
5596
|
} ? T extends 'UnknownError' ? never : T extends string ? T : never : never;
|
|
5475
5597
|
|
|
5598
|
+
export declare const FIELD_ENCRYPTION_ACTIVE_ENV = "VOLTRO_FIELD_ENCRYPTION_ACTIVE";
|
|
5599
|
+
|
|
5600
|
+
export declare const FIELD_ENCRYPTION_KEY_ENV = "VOLTRO_FIELD_ENCRYPTION_KEY";
|
|
5601
|
+
|
|
5602
|
+
export declare const FIELD_ENCRYPTION_KEYS_ENV = "VOLTRO_FIELD_ENCRYPTION_KEYS";
|
|
5603
|
+
|
|
5604
|
+
export declare const FIELD_ENCRYPTION_PREVIOUS_KEY_ENV = "VOLTRO_FIELD_ENCRYPTION_KEY_PREVIOUS";
|
|
5605
|
+
|
|
5606
|
+
export declare const FIELD_KEY_HEARTBEAT_MS = 10000;
|
|
5607
|
+
|
|
5608
|
+
/** The table of leases on field-encryption keys. */
|
|
5609
|
+
export declare const FIELD_KEY_HOLDERS_TABLE = "_voltro_field_key_holders";
|
|
5610
|
+
|
|
5611
|
+
export declare const FIELD_KEY_LEASE_MS = 30000;
|
|
5612
|
+
|
|
5613
|
+
/** The table of the last field-key count and re-key. */
|
|
5614
|
+
export declare const FIELD_KEY_REPORTS_TABLE = "_voltro_field_key_reports";
|
|
5615
|
+
|
|
5616
|
+
/** The environment names a keyring is read from, for a resolver that fetches them. */
|
|
5617
|
+
export declare const FIELD_KEYRING_ENV_NAMES: readonly ["VOLTRO_FIELD_ENCRYPTION_KEYS", "VOLTRO_FIELD_ENCRYPTION_ACTIVE", "VOLTRO_FIELD_ENCRYPTION_KEY", "VOLTRO_FIELD_ENCRYPTION_KEY_PREVIOUS"];
|
|
5618
|
+
|
|
5619
|
+
/** The table recording each field-encryption key id's state and canary. */
|
|
5620
|
+
export declare const FIELD_KEYS_TABLE = "_voltro_field_keys";
|
|
5621
|
+
|
|
5476
5622
|
export declare interface FieldChange {
|
|
5477
5623
|
readonly from: unknown;
|
|
5478
5624
|
readonly to: unknown;
|
|
5479
5625
|
}
|
|
5480
5626
|
|
|
5627
|
+
/** What this process opened since it started, per key and location — the Governance panel's view. */
|
|
5628
|
+
export declare const fieldDecryptSnapshot: () => ReadonlyArray<{
|
|
5629
|
+
readonly key: string;
|
|
5630
|
+
readonly location: string;
|
|
5631
|
+
readonly ok: number;
|
|
5632
|
+
readonly failed: number;
|
|
5633
|
+
}>;
|
|
5634
|
+
|
|
5635
|
+
/** The last `voltro secret status`: sealed values per key id, over all and per location. */
|
|
5636
|
+
export declare interface FieldKeyCountReport {
|
|
5637
|
+
readonly totals: Readonly<Record<string, number>>;
|
|
5638
|
+
readonly unnamed: number;
|
|
5639
|
+
readonly plaintext: number;
|
|
5640
|
+
readonly unreadable: number;
|
|
5641
|
+
readonly locations: ReadonlyArray<{
|
|
5642
|
+
readonly table: string;
|
|
5643
|
+
readonly column: string;
|
|
5644
|
+
readonly byKey: Readonly<Record<string, number>>;
|
|
5645
|
+
readonly unnamed: number;
|
|
5646
|
+
readonly plaintext: number;
|
|
5647
|
+
}>;
|
|
5648
|
+
}
|
|
5649
|
+
|
|
5650
|
+
/** One key of a keyring: its id and its secret (a passphrase, or 64 hex). */
|
|
5651
|
+
export declare interface FieldKeyEntry {
|
|
5652
|
+
readonly id: string;
|
|
5653
|
+
readonly secret: string;
|
|
5654
|
+
}
|
|
5655
|
+
|
|
5656
|
+
/** What one heartbeat found. `unheld`: the database's active key is one this
|
|
5657
|
+
* process does not hold — it missed its lease while the fleet moved on. */
|
|
5658
|
+
export declare interface FieldKeyHeartbeat {
|
|
5659
|
+
readonly active: string;
|
|
5660
|
+
readonly activated?: {
|
|
5661
|
+
readonly from: string | undefined;
|
|
5662
|
+
readonly to: string;
|
|
5663
|
+
};
|
|
5664
|
+
readonly waiting?: FieldKeyWaiting;
|
|
5665
|
+
readonly unheld: boolean;
|
|
5666
|
+
}
|
|
5667
|
+
|
|
5668
|
+
/** A process's lease. `now` is for tests; the lease is how long a process that
|
|
5669
|
+
* stopped heartbeating is still waited for. */
|
|
5670
|
+
export declare interface FieldKeyHolder {
|
|
5671
|
+
readonly holderId: string;
|
|
5672
|
+
readonly leaseMs?: number;
|
|
5673
|
+
readonly now?: () => number;
|
|
5674
|
+
}
|
|
5675
|
+
|
|
5676
|
+
export declare interface FieldKeyHolderHandle {
|
|
5677
|
+
/** Stop heartbeating, wait for a beat in flight, and give up the lease. */
|
|
5678
|
+
readonly stop: () => Promise<void>;
|
|
5679
|
+
}
|
|
5680
|
+
|
|
5681
|
+
/** A holder id for this process. */
|
|
5682
|
+
export declare const fieldKeyHolderId: () => string;
|
|
5683
|
+
|
|
5684
|
+
/** One process's lease, as recorded — `expiresAt` in the past means it no longer counts. */
|
|
5685
|
+
export declare interface FieldKeyHolderRecord {
|
|
5686
|
+
readonly holderId: string;
|
|
5687
|
+
readonly keyIds: ReadonlyArray<string>;
|
|
5688
|
+
readonly activeKeyId: string;
|
|
5689
|
+
readonly heartbeatAt: Date;
|
|
5690
|
+
readonly expiresAt: Date;
|
|
5691
|
+
}
|
|
5692
|
+
|
|
5693
|
+
export declare interface FieldKeyHolderRow {
|
|
5694
|
+
readonly holderId: string;
|
|
5695
|
+
readonly keyIds: ReadonlyArray<string>;
|
|
5696
|
+
readonly activeKeyId: string;
|
|
5697
|
+
readonly expiresAt: string;
|
|
5698
|
+
}
|
|
5699
|
+
|
|
5700
|
+
/**
|
|
5701
|
+
* The id a key gets when the operator does not name one: `k` + 10 hex
|
|
5702
|
+
* characters of an HMAC over the derived key. Stable for a given key, short
|
|
5703
|
+
* enough to ride in every envelope, and not the key — the fingerprint is keyed
|
|
5704
|
+
* by the key itself, so it says nothing about it to someone without it.
|
|
5705
|
+
*/
|
|
5706
|
+
export declare const fieldKeyIdOf: (secret: string) => string;
|
|
5707
|
+
|
|
5708
|
+
/** The last `voltro secret rekey` (also run by `rotate`): what moved, what is left, and whether the active key alone opens everything. */
|
|
5709
|
+
export declare interface FieldKeyRekeyReport {
|
|
5710
|
+
readonly active: string;
|
|
5711
|
+
readonly rekeyed: number;
|
|
5712
|
+
readonly left: number;
|
|
5713
|
+
readonly verified: boolean;
|
|
5714
|
+
}
|
|
5715
|
+
|
|
5716
|
+
export declare interface FieldKeyReports {
|
|
5717
|
+
readonly status?: {
|
|
5718
|
+
readonly reportedAt: Date;
|
|
5719
|
+
readonly report: FieldKeyCountReport;
|
|
5720
|
+
};
|
|
5721
|
+
readonly rekey?: {
|
|
5722
|
+
readonly reportedAt: Date;
|
|
5723
|
+
readonly report: FieldKeyRekeyReport;
|
|
5724
|
+
};
|
|
5725
|
+
}
|
|
5726
|
+
|
|
5727
|
+
/** A field cipher over several keys, each with an id — what `makeFieldKeyring` returns. */
|
|
5728
|
+
export declare interface FieldKeyring extends FieldCipher {
|
|
5729
|
+
/** The key new values are sealed under — the configured active key until
|
|
5730
|
+
* {@link FieldKeyring.activate} names another one the keyring holds. */
|
|
5731
|
+
readonly activeKeyId: string;
|
|
5732
|
+
/** The active key the configuration names. The database may keep another
|
|
5733
|
+
* active until every live process holds this one (`verifyFieldKeyring`). */
|
|
5734
|
+
readonly requestedKeyId: string;
|
|
5735
|
+
/** Every id the keyring holds, the configured active key first. */
|
|
5736
|
+
readonly keyIds: ReadonlyArray<string>;
|
|
5737
|
+
/** Each held key's fingerprint ({@link fieldKeyIdOf} — an HMAC of the key, never
|
|
5738
|
+
* the key), by id: what the boot line and the Governance panel show. */
|
|
5739
|
+
readonly fingerprints: Readonly<Record<string, string>>;
|
|
5740
|
+
/** Seal under one named key, whichever is active (a key's canary). */
|
|
5741
|
+
readonly sealWith: (keyId: string, plaintext: string, binding?: FieldBinding) => string;
|
|
5742
|
+
/** Does the named key open this value? `false` for a key the keyring does not hold. */
|
|
5743
|
+
readonly opensWith: (keyId: string, ciphertext: string, binding?: FieldBinding) => boolean;
|
|
5744
|
+
/** Seal new values under another held key — the database, not the
|
|
5745
|
+
* environment, decides which key is active (`verifyFieldKeyring`). */
|
|
5746
|
+
readonly activate: (keyId: string) => void;
|
|
5747
|
+
}
|
|
5748
|
+
|
|
5749
|
+
/** The keys a process holds, and the one new values are sealed under. */
|
|
5750
|
+
export declare interface FieldKeyringConfig {
|
|
5751
|
+
readonly active: string;
|
|
5752
|
+
readonly keys: ReadonlyArray<FieldKeyEntry>;
|
|
5753
|
+
}
|
|
5754
|
+
|
|
5755
|
+
/** A keyring configuration that cannot be used — named, never containing a key. */
|
|
5756
|
+
export declare class FieldKeyringConfigError extends Error {
|
|
5757
|
+
readonly _tag = "FieldKeyringConfigError";
|
|
5758
|
+
constructor(message: string);
|
|
5759
|
+
}
|
|
5760
|
+
|
|
5761
|
+
/** The boot cannot use this keyring with this database — the message names
|
|
5762
|
+
* ids, columns and the way out, never a key. */
|
|
5763
|
+
export declare class FieldKeyringRefusal extends Error {
|
|
5764
|
+
readonly _tag = "FieldKeyringRefusal";
|
|
5765
|
+
constructor(message: string);
|
|
5766
|
+
}
|
|
5767
|
+
|
|
5768
|
+
/** What a boot's check found and recorded. */
|
|
5769
|
+
export declare interface FieldKeyringVerification {
|
|
5770
|
+
/** The key new values are sealed under, as the database records it. */
|
|
5771
|
+
readonly active: string;
|
|
5772
|
+
/** Ids this boot recorded for the first time. */
|
|
5773
|
+
readonly registered: ReadonlyArray<string>;
|
|
5774
|
+
/** Set when this boot made another key active. */
|
|
5775
|
+
readonly activated?: {
|
|
5776
|
+
readonly from: string | undefined;
|
|
5777
|
+
readonly to: string;
|
|
5778
|
+
};
|
|
5779
|
+
/** A requested key that is not active yet, and the live processes that lack it. */
|
|
5780
|
+
readonly waiting?: FieldKeyWaiting;
|
|
5781
|
+
/** Things worth a log line, never a refusal. */
|
|
5782
|
+
readonly notes: ReadonlyArray<string>;
|
|
5783
|
+
}
|
|
5784
|
+
|
|
5785
|
+
/** One recorded key id — its state and canary, never its key. */
|
|
5786
|
+
export declare interface FieldKeyRow {
|
|
5787
|
+
readonly keyId: string;
|
|
5788
|
+
readonly state: FieldKeyState;
|
|
5789
|
+
readonly canary: string;
|
|
5790
|
+
readonly registeredAt: Date | null;
|
|
5791
|
+
readonly activatedAt: Date | null;
|
|
5792
|
+
readonly replacedAt: Date | null;
|
|
5793
|
+
readonly retiredAt: Date | null;
|
|
5794
|
+
readonly requestedAt: Date | null;
|
|
5795
|
+
}
|
|
5796
|
+
|
|
5797
|
+
/** A key's state. `pending`: held, never active. `active`: new values are sealed
|
|
5798
|
+
* under it — exactly one. `decrypt-only`: was active, replaced; values may still
|
|
5799
|
+
* be sealed under it. `retired`: nothing is sealed under it any more. */
|
|
5800
|
+
export declare type FieldKeyState = 'pending' | 'active' | 'decrypt-only' | 'retired';
|
|
5801
|
+
|
|
5802
|
+
export declare interface FieldKeyStateRow {
|
|
5803
|
+
readonly keyId: string;
|
|
5804
|
+
readonly state: string;
|
|
5805
|
+
readonly activatedAt: string | null;
|
|
5806
|
+
readonly requestedAt: string | null;
|
|
5807
|
+
}
|
|
5808
|
+
|
|
5809
|
+
export declare interface FieldKeyStatus {
|
|
5810
|
+
/** The recorded keys and their states — empty before the first boot recorded any. */
|
|
5811
|
+
readonly keys: ReadonlyArray<FieldKeyStateRow>;
|
|
5812
|
+
/** Every process that holds a lease, live or not (`expiresAt` says which). */
|
|
5813
|
+
readonly holders: ReadonlyArray<FieldKeyHolderRow>;
|
|
5814
|
+
readonly locations: ReadonlyArray<SealedLocation>;
|
|
5815
|
+
/** Envelopes per key id, over every location. */
|
|
5816
|
+
readonly totals: Readonly<Record<string, number>>;
|
|
5817
|
+
readonly unnamed: number;
|
|
5818
|
+
readonly plaintext: number;
|
|
5819
|
+
/** Columns that could not be read — listed, never silently left out of the counts. */
|
|
5820
|
+
readonly unreadable: ReadonlyArray<UnreadableColumn>;
|
|
5821
|
+
}
|
|
5822
|
+
|
|
5823
|
+
/**
|
|
5824
|
+
* Count every sealed value in the database by the key it names. `declared` are
|
|
5825
|
+
* the app's tables: their `.encrypted()` columns are always reported (with
|
|
5826
|
+
* plaintext counted), the rest only where envelopes were found.
|
|
5827
|
+
*/
|
|
5828
|
+
export declare const fieldKeyStatus: (dialect: DialectId, declared: Iterable<unknown>) => Effect.Effect<{
|
|
5829
|
+
keys: FieldKeyStateRow[];
|
|
5830
|
+
holders: FieldKeyHolderRow[];
|
|
5831
|
+
locations: SealedLocation[];
|
|
5832
|
+
totals: Record<string, number>;
|
|
5833
|
+
unreadable: UnreadableColumn[];
|
|
5834
|
+
unnamed: number;
|
|
5835
|
+
plaintext: number;
|
|
5836
|
+
}, SqlError, SqlClient.SqlClient>;
|
|
5837
|
+
|
|
5838
|
+
export declare interface FieldKeyWaiting {
|
|
5839
|
+
readonly keyId: string;
|
|
5840
|
+
readonly holders: ReadonlyArray<string>;
|
|
5841
|
+
}
|
|
5842
|
+
|
|
5481
5843
|
/**
|
|
5482
5844
|
* Canonical fingerprint over `(table, predicate, indexHint?)`. The
|
|
5483
5845
|
* optional `indexHint` participates so two subscriptions with the same
|
|
@@ -5854,6 +6216,13 @@ export declare interface HealthConfigInput {
|
|
|
5854
6216
|
readonly readiness?: () => boolean | Promise<boolean>;
|
|
5855
6217
|
}
|
|
5856
6218
|
|
|
6219
|
+
/**
|
|
6220
|
+
* One heartbeat: renew this process's lease, complete a requested activation
|
|
6221
|
+
* once every live holder holds the key, and seal under the database's active
|
|
6222
|
+
* key from now on. Any holder can complete an activation another one requested.
|
|
6223
|
+
*/
|
|
6224
|
+
export declare const heartbeatFieldKeys: (store: DataStore, keyring: FieldKeyring, holder: FieldKeyHolder) => Promise<FieldKeyHeartbeat>;
|
|
6225
|
+
|
|
5857
6226
|
/** Define a histogram. `boundaries` default to the framework duration buckets. */
|
|
5858
6227
|
export declare const histogramMetric: (name: string, boundaries?: ReadonlyArray<number>, description?: string) => Metric.Histogram<number>;
|
|
5859
6228
|
|
|
@@ -5995,9 +6364,10 @@ export declare class InMemoryDataStore implements DataStore {
|
|
|
5995
6364
|
* to tell apart from "no such table".
|
|
5996
6365
|
*/
|
|
5997
6366
|
storedTables(): ReadonlyArray<StoredTableShape>;
|
|
6367
|
+
integrityQuery(descriptor: QueryDescriptor): Promise<ReadonlyArray<Row>>;
|
|
5998
6368
|
query(descriptor: QueryDescriptor): Promise<ReadonlyArray<Row>>;
|
|
5999
6369
|
insert(table: string, row: Row): Promise<Row>;
|
|
6000
|
-
insertMany(table: string, rows: ReadonlyArray<Row
|
|
6370
|
+
insertMany(table: string, rows: ReadonlyArray<Row>, options?: InsertManyOptions): Promise<ReadonlyArray<Row>>;
|
|
6001
6371
|
patchJson(table: string, primaryKey: RowKey, path: string, value: unknown, additionalPatch?: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
6002
6372
|
update(table: string, primaryKey: RowKey, patch: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
6003
6373
|
delete(table: string, primaryKey: RowKey): Promise<boolean>;
|
|
@@ -6029,8 +6399,9 @@ export declare const insertIgnoreRowOutcomeEffect: <T extends AnyWritableTable>(
|
|
|
6029
6399
|
readonly outcome: "inserted" | "ignored";
|
|
6030
6400
|
}, StoreError>;
|
|
6031
6401
|
|
|
6032
|
-
/** `insertRowEffect`'s batch — every element checked against `InferInsertRow<T>`.
|
|
6033
|
-
|
|
6402
|
+
/** `insertRowEffect`'s batch — every element checked against `InferInsertRow<T>`.
|
|
6403
|
+
* `{ returning: 'none' }` resolves to `[]` without reading the rows back. */
|
|
6404
|
+
export declare const insertManyRowsEffect: <T extends AnyWritableTable>(store: EffectInsertManyStore, table: T, rows: ReadonlyArray<InferInsertRow<T>>, options?: InsertManyOptions) => Effect.Effect<ReadonlyArray<InferRow<T>>, StoreError>;
|
|
6034
6405
|
|
|
6035
6406
|
/**
|
|
6036
6407
|
* Insert a row, typed against the table, on the Effect channel.
|
|
@@ -6135,6 +6506,10 @@ export { inspectWorkflow }
|
|
|
6135
6506
|
|
|
6136
6507
|
export declare const installApprovalGate: (gate: ApprovalGateApi) => void;
|
|
6137
6508
|
|
|
6509
|
+
/** Turn on read capture for cached computes — called at boot when any query
|
|
6510
|
+
* declares `cache:`. Until then the request store is not wrapped for it. */
|
|
6511
|
+
export declare const installComputedQueryCacheCapture: () => void;
|
|
6512
|
+
|
|
6138
6513
|
/**
|
|
6139
6514
|
* Install the resolver that answers `guards: [{ action, resourceType }]`.
|
|
6140
6515
|
*
|
|
@@ -6238,6 +6613,9 @@ export declare const isExpectationDefinition: (value: unknown) => value is Expec
|
|
|
6238
6613
|
|
|
6239
6614
|
export declare const isExperimentDefinition: (value: unknown) => value is ExperimentDefinition;
|
|
6240
6615
|
|
|
6616
|
+
/** Is this cipher a keyring (ids, per-key seal and open), not a bare cipher? */
|
|
6617
|
+
export declare const isFieldKeyring: (cipher: FieldCipher | undefined) => cipher is FieldKeyring;
|
|
6618
|
+
|
|
6241
6619
|
export { isForeignKeyViolation }
|
|
6242
6620
|
|
|
6243
6621
|
/**
|
|
@@ -6464,7 +6842,7 @@ export declare interface KvFacade {
|
|
|
6464
6842
|
readonly service: Effect.Success<typeof Kv>;
|
|
6465
6843
|
/** The resolved backend kind — for boot logging. */
|
|
6466
6844
|
readonly backend: 'database' | 'redis' | 'memory';
|
|
6467
|
-
/**
|
|
6845
|
+
/** Release this consumer runtime; an injected registry retains its pools. */
|
|
6468
6846
|
readonly dispose: () => Promise<void>;
|
|
6469
6847
|
}
|
|
6470
6848
|
|
|
@@ -6473,6 +6851,10 @@ export declare interface KvFacadeOptions {
|
|
|
6473
6851
|
readonly store: DataStore;
|
|
6474
6852
|
/** Defaults to `process.env`. */
|
|
6475
6853
|
readonly env?: NodeJS.ProcessEnv;
|
|
6854
|
+
readonly backend?: 'database' | 'redis' | 'memory';
|
|
6855
|
+
readonly connectionName?: string;
|
|
6856
|
+
readonly keyPrefix?: string;
|
|
6857
|
+
readonly connections?: RespConnections;
|
|
6476
6858
|
}
|
|
6477
6859
|
|
|
6478
6860
|
/**
|
|
@@ -6594,6 +6976,27 @@ export declare interface LocalityAwareOptions {
|
|
|
6594
6976
|
*/
|
|
6595
6977
|
export declare const localityAwareSelector: (options: LocalityAwareOptions) => ReplicaSelector;
|
|
6596
6978
|
|
|
6979
|
+
/** One location's outcome. */
|
|
6980
|
+
export declare interface LocationRekey {
|
|
6981
|
+
readonly table: string;
|
|
6982
|
+
readonly column: string;
|
|
6983
|
+
readonly cells: number;
|
|
6984
|
+
readonly rekeyed: number;
|
|
6985
|
+
readonly current: number;
|
|
6986
|
+
readonly unresolved: number;
|
|
6987
|
+
/** Cells the app changed between the read and the write — run again. */
|
|
6988
|
+
readonly changedMeanwhile: number;
|
|
6989
|
+
/** Values that need a re-key in a table with no single-column primary key to address the cell by. */
|
|
6990
|
+
readonly unaddressable: number;
|
|
6991
|
+
}
|
|
6992
|
+
|
|
6993
|
+
/** Read the current key row within its expected tenant under a write fence.
|
|
6994
|
+
* Supply an existing transaction after the application's organization/account
|
|
6995
|
+
* fences and keep it through the protected write. Null matches unassigned
|
|
6996
|
+
* keys only. The internal row uses the normal store codec; never return it in
|
|
6997
|
+
* a public response. This is not bearer verification or an authorization grant. */
|
|
6998
|
+
export declare const lockApiKeyById: (store: DataStore, id: string, tenantId: string | null) => Promise<ApiKeyRow | null>;
|
|
6999
|
+
|
|
6597
7000
|
export declare interface LogTraceContext {
|
|
6598
7001
|
readonly traceId: string;
|
|
6599
7002
|
readonly spanId?: string;
|
|
@@ -6665,7 +7068,7 @@ log?: SchedulerLogger) => Coordinator;
|
|
|
6665
7068
|
* tampered / wrong-key value AND on a bound value read at another address —
|
|
6666
7069
|
* both surface as a read error, never silent corruption.
|
|
6667
7070
|
*/
|
|
6668
|
-
export declare const makeAesCipher: (key: Buffer) => FieldCipher;
|
|
7071
|
+
export declare const makeAesCipher: (key: Buffer, keyId?: string) => FieldCipher;
|
|
6669
7072
|
|
|
6670
7073
|
export declare const makeApiKeyService: (store: ApiKeyStore, opts?: {
|
|
6671
7074
|
prefix?: string;
|
|
@@ -6693,6 +7096,61 @@ export declare const makeApiKeyUsageFlusher: (store: ApiKeyStore) => (id: string
|
|
|
6693
7096
|
readonly lastUsedAt: number;
|
|
6694
7097
|
}) => Promise<void>;
|
|
6695
7098
|
|
|
7099
|
+
/** In-memory, bounded finalized-bucket queue. Current instrumentation is partial;
|
|
7100
|
+
* this collector cannot certify complete workload coverage merely from uptime. */
|
|
7101
|
+
export declare const makeApiRoleBucketSampler: (input: {
|
|
7102
|
+
readonly replicaId: string;
|
|
7103
|
+
readonly startedAt: number;
|
|
7104
|
+
readonly role: string;
|
|
7105
|
+
readonly workloads: ReadonlyArray<ApiWorkload>;
|
|
7106
|
+
readonly epochNow: number;
|
|
7107
|
+
readonly monotonicNow: number;
|
|
7108
|
+
}) => {
|
|
7109
|
+
record(segment: {
|
|
7110
|
+
readonly workload: ApiWorkload;
|
|
7111
|
+
readonly from: number;
|
|
7112
|
+
readonly until: number;
|
|
7113
|
+
}): void;
|
|
7114
|
+
/** Heartbeat every30s. Delays >60s or clock skew >1s conservatively invalidate
|
|
7115
|
+
* affected intervals; never spread elapsed request time across buckets. */
|
|
7116
|
+
advance(monotonicNow: number, epochNow: number): void;
|
|
7117
|
+
pending(): ReadonlyArray<ApiRoleWorkloadBucket>;
|
|
7118
|
+
acknowledge(from: number): void;
|
|
7119
|
+
status: () => {
|
|
7120
|
+
pendingBuckets: number;
|
|
7121
|
+
droppedBuckets: number;
|
|
7122
|
+
rejectedSegments: number;
|
|
7123
|
+
};
|
|
7124
|
+
};
|
|
7125
|
+
|
|
7126
|
+
/** Measures only the synchronous execution of a callback, including throws.
|
|
7127
|
+
* Returning a Promise measures its construction, not its awaited lifetime.
|
|
7128
|
+
* Each resumed async callback must be instrumented separately. No wall-time
|
|
7129
|
+
* request duration may be fed into this counter as a substitute for loop time.
|
|
7130
|
+
* Nested calls on this recorder suspend their parent, so time is exclusive. */
|
|
7131
|
+
export declare const makeApiRoleWorkloadMetrics: (roles: ReadonlyArray<string>, options?: {
|
|
7132
|
+
readonly now?: () => number;
|
|
7133
|
+
readonly onSegment?: (segment: {
|
|
7134
|
+
readonly workload: ApiWorkload;
|
|
7135
|
+
readonly from: number;
|
|
7136
|
+
readonly until: number;
|
|
7137
|
+
}) => void;
|
|
7138
|
+
}) => {
|
|
7139
|
+
role: string;
|
|
7140
|
+
observationErrors: () => number;
|
|
7141
|
+
/** Effect4's tracer context surrounds each synchronous primitive, including
|
|
7142
|
+
* the first, resumed and inherited child work. Preserve the existing tracer;
|
|
7143
|
+
* Promise callbacks outside evaluation still use measureSync explicitly. */
|
|
7144
|
+
observeEffect<A, E, R>(effect: Effect.Effect<A, E, R>, workload: ApiWorkload): Effect.Effect<A, E, R>;
|
|
7145
|
+
measureSync<A>(workload: ApiWorkload, run: () => A): A;
|
|
7146
|
+
/** Local totals, not a 24-hour history or evidence of full instrumentation. */
|
|
7147
|
+
snapshot(): ReadonlyArray<{
|
|
7148
|
+
readonly role: string;
|
|
7149
|
+
readonly workload: ApiWorkload;
|
|
7150
|
+
readonly seconds: number;
|
|
7151
|
+
}>;
|
|
7152
|
+
};
|
|
7153
|
+
|
|
6696
7154
|
/** Build the `ctx.access` slice for a subject. Reads the effective-scope seam
|
|
6697
7155
|
* LIVE (via getters/closures) so a scope rbac resolves after context
|
|
6698
7156
|
* construction is still reflected. Used by the shared AppContext builder AND
|
|
@@ -6716,7 +7174,7 @@ export declare interface MakeApprovalGateOptions {
|
|
|
6716
7174
|
|
|
6717
7175
|
/** Build the `ctx.kv` facade. `KV_BACKEND` picks the backend; unknown values
|
|
6718
7176
|
* fall back to `database`. */
|
|
6719
|
-
export declare const makeAsyncKv: ({ store, env }: KvFacadeOptions) => Promise<KvFacade>;
|
|
7177
|
+
export declare const makeAsyncKv: ({ store, env, backend: configuredBackend, connectionName, keyPrefix, connections }: KvFacadeOptions) => Promise<KvFacade>;
|
|
6720
7178
|
|
|
6721
7179
|
/**
|
|
6722
7180
|
* The `AuthMiddleware` + `ConnectionInfoMiddleware` pair every rpc surface
|
|
@@ -6728,9 +7186,9 @@ export declare const makeAsyncKv: ({ store, env }: KvFacadeOptions) => Promise<K
|
|
|
6728
7186
|
* (a no-op for a connection that never re-authenticated);
|
|
6729
7187
|
* 2. run the FULL chain on the result — strategies, session revocation,
|
|
6730
7188
|
* `resolveScopes`, the scope cache;
|
|
6731
|
-
* 3.
|
|
6732
|
-
*
|
|
6733
|
-
*
|
|
7189
|
+
* 3. pass the verified lifetime through call-local Effect context, so parallel
|
|
7190
|
+
* calls and explicitly unbounded credentials cannot inherit another call's
|
|
7191
|
+
* expiry. Compose the group's pair with `withRpcAuthMiddleware`.
|
|
6734
7192
|
*
|
|
6735
7193
|
* Step 1 is the only thing a re-authenticated connection gets. It changes WHICH
|
|
6736
7194
|
* credential is presented and nothing about how it is judged.
|
|
@@ -6835,19 +7293,45 @@ export declare const makeEventPublisher: (ctx: EventPublishContext) => EventPubl
|
|
|
6835
7293
|
|
|
6836
7294
|
export declare const makeEventsFacade: (options: EventsFacadeOptions) => EventsAppContext;
|
|
6837
7295
|
|
|
7296
|
+
/** Pass one instance to a host's scheduler factories and trigger route. */
|
|
7297
|
+
export declare const makeExternalizedTaskRegistry: () => ExternalizedTaskRegistry;
|
|
7298
|
+
|
|
6838
7299
|
/**
|
|
6839
7300
|
* Derive a key from a passphrase and build the cipher — with the keys a
|
|
6840
|
-
* ROTATION retires, when there are any.
|
|
7301
|
+
* ROTATION retires, when there are any. Ids are derived from the keys
|
|
7302
|
+
* (`fieldKeyIdOf`); a previous key equal to the current one is skipped.
|
|
6841
7303
|
*
|
|
6842
|
-
* Writes use the current key; reads
|
|
6843
|
-
* one. GCM authenticates, so a
|
|
6844
|
-
*
|
|
6845
|
-
* every value written before it unreadable — measured: every
|
|
6846
|
-
* suspended run of an `encrypted: true` workflow failed its replay
|
|
6847
|
-
* `MalformedMessage`, and every `.encrypted()` column read failed.
|
|
7304
|
+
* Writes use the current key; reads open a value by the key it names, or by
|
|
7305
|
+
* trying the current one, then each previous one. GCM authenticates, so a
|
|
7306
|
+
* wrong key fails its tag rather than producing garbage. Without this, a key
|
|
7307
|
+
* change made every value written before it unreadable — measured: every
|
|
7308
|
+
* sleeping or suspended run of an `encrypted: true` workflow failed its replay
|
|
7309
|
+
* with `MalformedMessage`, and every `.encrypted()` column read failed.
|
|
6848
7310
|
*/
|
|
6849
7311
|
export declare const makeFieldCipher: (passphrase: string, previous?: ReadonlyArray<string>) => FieldCipher;
|
|
6850
7312
|
|
|
7313
|
+
/**
|
|
7314
|
+
* A cipher over a keyring: new values are sealed under the active key and name
|
|
7315
|
+
* it; a value is opened by the key it names (a lookup), and one written before
|
|
7316
|
+
* values named their key by trying each key, the active one first.
|
|
7317
|
+
*
|
|
7318
|
+
* A named key that is not in the keyring is a refusal that names it, so an
|
|
7319
|
+
* operator reads "sealed under k2026a, which this process does not hold"
|
|
7320
|
+
* instead of a GCM failure. A named key that does not open the value (an id
|
|
7321
|
+
* that was altered) falls back to trying the others — the id is a hint, GCM is
|
|
7322
|
+
* the authority.
|
|
7323
|
+
*/
|
|
7324
|
+
export declare const makeFieldKeyring: (config: FieldKeyringConfig, options?: {
|
|
7325
|
+
/**
|
|
7326
|
+
* Refuse to seal until {@link FieldKeyring.activate} has run — the boot's
|
|
7327
|
+
* keyring sets this, so nothing is sealed under the configured key before
|
|
7328
|
+
* the database has said which key is active. A value sealed under a key the
|
|
7329
|
+
* fleet has not accepted is one a replica on the previous configuration
|
|
7330
|
+
* cannot read.
|
|
7331
|
+
*/
|
|
7332
|
+
readonly sealOnlyOnceActivated?: boolean;
|
|
7333
|
+
}) => FieldKeyring;
|
|
7334
|
+
|
|
6851
7335
|
/** Build the fluent `select` / `update` / `delete` entry functions over a
|
|
6852
7336
|
* backend + scope. Wired into `wrapStoreWithMixinBehaviour` so they hang
|
|
6853
7337
|
* off `ctx.store` alongside the keyed `query`/`insert`/`update`/`delete`. */
|
|
@@ -6870,12 +7354,18 @@ export declare const makeLazyWorkflowFacade: (resolve: () => WorkflowsAppContext
|
|
|
6870
7354
|
export declare const makeListConnectionsExecutor: (deps: ConnectionBuiltinDeps) => (_input: Record<string, never>, ctx: ConnectionExecutorCtx) => Promise<ReadonlyArray<ConnectionState_2>>;
|
|
6871
7355
|
|
|
6872
7356
|
/**
|
|
6873
|
-
* Build
|
|
6874
|
-
*
|
|
6875
|
-
*
|
|
6876
|
-
* produced, `encodeUnknownSync` never throws. `undefined` schema → no codec.
|
|
7357
|
+
* Build one input/output contract from both declared schemas. Refuse incompatible
|
|
7358
|
+
* values with payload-free errors; never return or log an old raw response
|
|
7359
|
+
* when the current output contract cannot decode it. Input is captured from its schema before keyed acquisition.
|
|
6877
7360
|
*/
|
|
6878
|
-
export declare const
|
|
7361
|
+
export declare const makeMutationCodec: (inputSchema: Schema.Top, outputSchema: Schema.Top, admit: MutationCodec<unknown>["admit"]) => MutationCodec<unknown>;
|
|
7362
|
+
|
|
7363
|
+
/** Current admission for a keyed unary call, including its cached result.
|
|
7364
|
+
* Pure refresher binding is separate from business interceptors/executors. */
|
|
7365
|
+
export declare const makeMutationReplayAdmission: (procedure: MutationLike, kind: "mutation" | "action", options?: {
|
|
7366
|
+
readonly defaultDeny?: boolean;
|
|
7367
|
+
readonly bindReplayAuthority?: RpcReplayAuthorityBinding | undefined;
|
|
7368
|
+
}) => ((input: unknown, request: ServeRequestContext) => Promise<void>);
|
|
6879
7369
|
|
|
6880
7370
|
/**
|
|
6881
7371
|
* Build the shared mutation runner. Used by BOTH the rpc WS handler and
|
|
@@ -6949,7 +7439,7 @@ export declare const makeOutboxFacade: (deps: OutboxFacadeDeps) => OutboxFacade;
|
|
|
6949
7439
|
*/
|
|
6950
7440
|
export declare const makeProcessAdapter: (supervisor: AppSupervisor) => WakeAdapter;
|
|
6951
7441
|
|
|
6952
|
-
export declare const makeQueryDescriptorProducer: <D>(deps: QueryProducerDeps<D
|
|
7442
|
+
export declare const makeQueryDescriptorProducer: <D>(deps: QueryProducerDeps<D>, workloadOverride?: "rpc" | "subscriptions") => (query: MutationLike, input: unknown) => (requestContext: ServeRequestContext) => ComputedQuery | D | Effect.Effect<ComputedQuery | D, unknown, never>;
|
|
6953
7443
|
|
|
6954
7444
|
export declare const makeQueryFinalizer: (options: QueryFinalizeOptions) => ((descriptor: QueryDescriptor, subject: {
|
|
6955
7445
|
readonly tenantId?: string | null;
|
|
@@ -6965,16 +7455,13 @@ export declare const makeQueryFinalizer: (options: QueryFinalizeOptions) => ((de
|
|
|
6965
7455
|
* the socket keeps delivering rows the subject may no longer read until
|
|
6966
7456
|
* the client happens to disconnect.
|
|
6967
7457
|
*
|
|
6968
|
-
*
|
|
6969
|
-
*
|
|
6970
|
-
*
|
|
6971
|
-
*
|
|
6972
|
-
*
|
|
6973
|
-
*
|
|
6974
|
-
*
|
|
6975
|
-
* unguarded query pays only a resolved promise. Under `defaultDeny` an
|
|
6976
|
-
* UNDECIDED descriptor resolves the same typed refusal on every delivery —
|
|
6977
|
-
* fail closed on the re-check too, not only at subscribe.
|
|
7458
|
+
* Each delivery refreshes the original authentication chain, subject guards,
|
|
7459
|
+
* dynamic role grants, and resource guards before emitting data. Configured
|
|
7460
|
+
* authentication/scope caches retain their documented invalidation windows.
|
|
7461
|
+
* A revoked credential or grant ends the subscription with a typed refusal.
|
|
7462
|
+
* The original principal and tenant remain fixed; changing either requires a
|
|
7463
|
+
* new subscription. Even unguarded descriptors refresh authentication, while
|
|
7464
|
+
* default-deny keeps rejecting descriptors without a declared access policy.
|
|
6978
7465
|
*/
|
|
6979
7466
|
export declare const makeQueryReauthorizer: (query: MutationLike, input: unknown, defaultDeny?: boolean) => (subject: Subject) => () => Promise<unknown>;
|
|
6980
7467
|
|
|
@@ -7391,35 +7878,22 @@ export declare const MIN_LEVEL_RESYNC_MS = 30000;
|
|
|
7391
7878
|
/** Mint a fresh service token. `voltro dev` and `voltro secret generate` call this. */
|
|
7392
7879
|
export declare const mintServiceToken: () => string;
|
|
7393
7880
|
|
|
7394
|
-
|
|
7395
|
-
* Ordering token for one mirrored write.
|
|
7396
|
-
*
|
|
7397
|
-
* **The sink MUST persist this and MUST NOT invent its own.** It is
|
|
7398
|
-
* assigned by the framework at the moment the change leaves the store's
|
|
7399
|
-
* change channel — i.e. in COMMIT order — so a write with a lower
|
|
7400
|
-
* version is, by construction, an older image of that row. Stamping a
|
|
7401
|
-
* version at sink-call time instead (a `Date.now()` inside `upsert`)
|
|
7402
|
-
* makes a late-arriving STALE image outrank the fresh one and win
|
|
7403
|
-
* permanently; that is the bug this type exists to make unrepresentable.
|
|
7404
|
-
*
|
|
7405
|
-
* How the number is derived depends on the store's `changeScope`:
|
|
7406
|
-
*
|
|
7407
|
-
* - `'local'` (one process observes each change): a hybrid clock —
|
|
7408
|
-
* wall-clock microseconds forced strictly upward, so it orders within
|
|
7409
|
-
* a millisecond and keeps increasing across a restart.
|
|
7410
|
-
* - `'fleet'` (every replica observes every change): derived from the
|
|
7411
|
-
* CHANGE, not from the receiving process — the warehouse's own max
|
|
7412
|
-
* version for the key (read once via {@link AnalyticsMirrorImpl.maxVersion})
|
|
7413
|
-
* plus the change's per-key position in the totally-ordered fleet
|
|
7414
|
-
* stream. N replicas mirroring the same change therefore stamp the
|
|
7415
|
-
* SAME number, and the sink's version guard dedupes the N duplicate
|
|
7416
|
-
* writes for free — no leader, no clock, no skew hazard.
|
|
7417
|
-
*/
|
|
7418
|
-
export declare type MirrorVersion = number;
|
|
7881
|
+
export { MirrorVersion }
|
|
7419
7882
|
|
|
7420
7883
|
/** The error `.one()` throws: the factory's, or the framework's `NoRowFound`. */
|
|
7421
7884
|
export declare const missingRowError: (info: NoRowFoundInfo, onMissing: OnMissingRow | undefined) => unknown;
|
|
7422
7885
|
|
|
7886
|
+
/**
|
|
7887
|
+
* Store encoded wire output and decode it against the current output contract.
|
|
7888
|
+
* A failed codec never falls back to an unvalidated raw response.
|
|
7889
|
+
*/
|
|
7890
|
+
export declare interface MutationCodec<Output> {
|
|
7891
|
+
readonly input: Schema.Top;
|
|
7892
|
+
readonly admit: (input: unknown, context: RuntimeContext) => Promise<void>;
|
|
7893
|
+
readonly encode: (output: Output) => unknown;
|
|
7894
|
+
readonly decode: (stored: unknown) => Output;
|
|
7895
|
+
}
|
|
7896
|
+
|
|
7423
7897
|
export declare interface MutationLifecycle {
|
|
7424
7898
|
readonly afterCommit: (work: () => Promise<unknown>) => void;
|
|
7425
7899
|
/** Already selected physical, namespace-bound nontransactional store.
|
|
@@ -7431,8 +7905,16 @@ export declare interface MutationLifecycle {
|
|
|
7431
7905
|
export declare interface MutationLike {
|
|
7432
7906
|
readonly descriptor: {
|
|
7433
7907
|
readonly name: string;
|
|
7908
|
+
readonly undo?: {
|
|
7909
|
+
readonly capture: false;
|
|
7910
|
+
readonly reason: string;
|
|
7911
|
+
} | undefined;
|
|
7434
7912
|
readonly source?: string | ReadonlyArray<string> | undefined;
|
|
7435
7913
|
readonly guards?: ReadonlyArray<AnyCheckSpec> | undefined;
|
|
7914
|
+
/** Query only — read by the computed-query cache (`computedQueryCache.ts`). */
|
|
7915
|
+
readonly cache?: QueryCacheLike | undefined;
|
|
7916
|
+
readonly input?: Schema.Top | undefined;
|
|
7917
|
+
readonly output?: Schema.Top | undefined;
|
|
7436
7918
|
/** The second-human control (mutation/action only). Enforced by
|
|
7437
7919
|
* `enforceApprovalGate`, immediately after `enforceGuards`. */
|
|
7438
7920
|
readonly requiresApproval?: AnyApprovalPolicy | undefined;
|
|
@@ -7447,21 +7929,20 @@ export declare interface MutationLike {
|
|
|
7447
7929
|
executor(input: unknown, ctx: unknown): unknown;
|
|
7448
7930
|
}
|
|
7449
7931
|
|
|
7450
|
-
/**
|
|
7451
|
-
* Encode/decode a mutation's output for idempotent replay. On a FRESH call the
|
|
7452
|
-
* WIRE form (`encode`) is stored, so a later replay `decode`s it back to the exact
|
|
7453
|
-
* Output the handler would have returned and the rpc layer re-encodes it
|
|
7454
|
-
* identically. Storing the DECODED Output directly would corrupt `Date`/etc.
|
|
7455
|
-
* fields through the store's JSON round-trip (encode there expects a `Date`, not
|
|
7456
|
-
* the ISO string a round-trip produced). Built from `descriptor.output` at the
|
|
7457
|
-
* call site; both fns fall back to the raw value if the Schema can't round-trip.
|
|
7458
|
-
*/
|
|
7459
|
-
export declare interface MutationOutputCodec<Output> {
|
|
7460
|
-
readonly encode: (output: Output) => unknown;
|
|
7461
|
-
readonly decode: (stored: unknown) => Output;
|
|
7462
|
-
}
|
|
7463
|
-
|
|
7464
7932
|
export declare interface MutationRunnerDeps {
|
|
7933
|
+
/** Measures only the synchronous executor entry, never an awaited result. */
|
|
7934
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
7935
|
+
readonly outcomeOutbox?: (request: ServeRequestContext) => OutboxEnqueueFacade | undefined;
|
|
7936
|
+
/** A failure aborts the business transaction; transient contention replays
|
|
7937
|
+
* executor and hook together. Never perform external I/O here. */
|
|
7938
|
+
readonly beforeMutationCommit?: ServeMutationCommitHook | undefined;
|
|
7939
|
+
/**
|
|
7940
|
+
* Resolves once the cache invalidations this process started have reached
|
|
7941
|
+
* the cache. Awaited after commit, BEFORE the mutation answers — without it
|
|
7942
|
+
* the writer's next read raced its own invalidation and was served the
|
|
7943
|
+
* pre-write entry. Both boot paths pass `wireCacheInvalidation`'s `settled`.
|
|
7944
|
+
*/
|
|
7945
|
+
readonly settleCacheInvalidations?: () => Promise<void>;
|
|
7465
7946
|
readonly store: TransactionalStore;
|
|
7466
7947
|
/** Select and provision the request's physical store before opening its
|
|
7467
7948
|
* transaction. Resolved once, including across retries and post-commit folds. */
|
|
@@ -7484,6 +7965,7 @@ export declare interface MutationRunnerDeps {
|
|
|
7484
7965
|
/** Build the per-call `AppContext` bound to the transactional `tx`. */
|
|
7485
7966
|
readonly buildContext: (request: ServeRequestContext, tx: unknown, lifecycle?: MutationLifecycle) => {
|
|
7486
7967
|
readonly store: unknown;
|
|
7968
|
+
readonly outbox?: OutboxEnqueueFacade;
|
|
7487
7969
|
};
|
|
7488
7970
|
/** Run an Effect-returning executor with the per-request store layer. */
|
|
7489
7971
|
readonly runEffect: (effect: Effect.Effect<unknown, unknown, never>, store: unknown) => Promise<unknown>;
|
|
@@ -7525,6 +8007,19 @@ export declare interface MutationStore extends DataStore {
|
|
|
7525
8007
|
hardDelete(table: string, primaryKey: RowKey): Promise<boolean>;
|
|
7526
8008
|
}
|
|
7527
8009
|
|
|
8010
|
+
/**
|
|
8011
|
+
* The encoding a body of `size` bytes would be compressed with — `undefined`
|
|
8012
|
+
* unless (enabled ∧ type compressible ∧ size ≥ threshold ∧ the client accepts
|
|
8013
|
+
* an encoding). Lets a caller that has not read the body yet (a static file
|
|
8014
|
+
* known only by `stat`) take the same decision `maybeCompress` takes.
|
|
8015
|
+
*/
|
|
8016
|
+
export declare const negotiatedCompression: (input: {
|
|
8017
|
+
readonly size: number;
|
|
8018
|
+
readonly contentType: string | undefined;
|
|
8019
|
+
readonly acceptEncoding: string | undefined;
|
|
8020
|
+
readonly options?: CompressionOptions | undefined;
|
|
8021
|
+
}) => NegotiatedEncoding | undefined;
|
|
8022
|
+
|
|
7528
8023
|
export declare type NegotiatedEncoding = 'br' | 'gzip';
|
|
7529
8024
|
|
|
7530
8025
|
/** Pick the encoding the client accepts — brotli preferred, gzip second,
|
|
@@ -7532,24 +8027,7 @@ export declare type NegotiatedEncoding = 'br' | 'gzip';
|
|
|
7532
8027
|
* (a client sending both accepts both). */
|
|
7533
8028
|
export declare const negotiateEncoding: (acceptEncoding: string | undefined) => NegotiatedEncoding | undefined;
|
|
7534
8029
|
|
|
7535
|
-
|
|
7536
|
-
* A fresh trace id for work that has NO incoming span to continue — a webhook
|
|
7537
|
-
* delivery, a schedule firing, a devtools invoke, a REST or gRPC entry point.
|
|
7538
|
-
*
|
|
7539
|
-
* 128 random bits as 32 lowercase hex, the shape `TRACEPARENT_RE` above accepts
|
|
7540
|
-
* and the shape a collector, a log pipeline or `voltro traces` can join on.
|
|
7541
|
-
*
|
|
7542
|
-
* The reason this exists as ONE function: every entry point that minted its own
|
|
7543
|
-
* had drifted somewhere different, and three of the shapes were not ids at all.
|
|
7544
|
-
* `incoming:<webhookId>`, `reaction:<workflow>` and the literal
|
|
7545
|
-
* `'webhooks:trigger'` are CONSTANTS — they were the caller's `source` label
|
|
7546
|
-
* copied into the id field, so every delivery a process ever handled shared one
|
|
7547
|
-
* trace and the waterfall merged unrelated work. `public-`/`grpc-`/`rest-` plus
|
|
7548
|
-
* eight base36 characters carried ~41 bits, which collides long before a busy
|
|
7549
|
-
* day is over. The entry-point kind is not lost by fixing this: it lives in the
|
|
7550
|
-
* `source` field beside the id, which is where it was already being written.
|
|
7551
|
-
*/
|
|
7552
|
-
export declare const newTraceId: () => string;
|
|
8030
|
+
export { newTraceId }
|
|
7553
8031
|
|
|
7554
8032
|
/**
|
|
7555
8033
|
* The backoff curve, extracted so it can be asserted directly — a schedule
|
|
@@ -7666,6 +8144,14 @@ export declare interface NoRowFoundInfo {
|
|
|
7666
8144
|
readonly found: number;
|
|
7667
8145
|
}
|
|
7668
8146
|
|
|
8147
|
+
/** Record a non-table input of the cached compute in flight, if any. Called by
|
|
8148
|
+
* the framework surfaces that reach outside the database. */
|
|
8149
|
+
export declare const noteCacheVolatile: (reason: string) => void;
|
|
8150
|
+
|
|
8151
|
+
/** Note that the query in flight depends on `table` without reading it
|
|
8152
|
+
* through `ctx.store`. */
|
|
8153
|
+
export declare const noteDependency: (table: string) => void;
|
|
8154
|
+
|
|
7669
8155
|
/** Note one read against the in-flight procedure. No scope → nothing happens. */
|
|
7670
8156
|
export declare const noteRead: (descriptor: QueryDescriptor) => void;
|
|
7671
8157
|
|
|
@@ -7695,6 +8181,45 @@ export declare interface Notification {
|
|
|
7695
8181
|
readonly newMatched: boolean;
|
|
7696
8182
|
}
|
|
7697
8183
|
|
|
8184
|
+
/** What a cross-environment restore did to the sealed values it cannot read. */
|
|
8185
|
+
export declare interface NullSealedReport {
|
|
8186
|
+
readonly nulled: ReadonlyArray<{
|
|
8187
|
+
readonly table: string;
|
|
8188
|
+
readonly column: string;
|
|
8189
|
+
readonly count: number;
|
|
8190
|
+
}>;
|
|
8191
|
+
readonly unreadable: ReadonlyArray<{
|
|
8192
|
+
readonly table: string;
|
|
8193
|
+
readonly column: string;
|
|
8194
|
+
readonly count: number;
|
|
8195
|
+
}>;
|
|
8196
|
+
/** Recorded key ids removed: they came with the restored data and this environment does not hold them. */
|
|
8197
|
+
readonly forgottenKeys: ReadonlyArray<string>;
|
|
8198
|
+
readonly unreadableColumns: ReadonlyArray<UnreadableColumn>;
|
|
8199
|
+
}
|
|
8200
|
+
|
|
8201
|
+
/**
|
|
8202
|
+
* After restoring another environment's database: write NULL for every whole
|
|
8203
|
+
* sealed value no configured key opens — the source ciphertext is useless here
|
|
8204
|
+
* and users re-enter it — count the sealed copies inside other values (they
|
|
8205
|
+
* cannot be nulled), and forget the restored key records and leases this
|
|
8206
|
+
* environment does not hold, so the next boot records its own keys.
|
|
8207
|
+
*/
|
|
8208
|
+
export declare const nullUnreadableSealedValues: (dialect: DialectId, keyring: FieldKeyring | undefined, declared: Iterable<unknown>) => Effect.Effect<{
|
|
8209
|
+
nulled: {
|
|
8210
|
+
table: string;
|
|
8211
|
+
column: string;
|
|
8212
|
+
count: number;
|
|
8213
|
+
}[];
|
|
8214
|
+
unreadable: {
|
|
8215
|
+
table: string;
|
|
8216
|
+
column: string;
|
|
8217
|
+
count: number;
|
|
8218
|
+
}[];
|
|
8219
|
+
forgottenKeys: string[];
|
|
8220
|
+
unreadableColumns: UnreadableColumn[];
|
|
8221
|
+
}, SqlError, SqlClient.SqlClient>;
|
|
8222
|
+
|
|
7698
8223
|
export declare interface OAuth2ConnectionDefinition extends ConnectionDefinitionCommon {
|
|
7699
8224
|
readonly kind: 'oauth2';
|
|
7700
8225
|
readonly authorizeUrl: string;
|
|
@@ -7735,6 +8260,17 @@ export declare type OAuthClientCredential = string | (() => string);
|
|
|
7735
8260
|
|
|
7736
8261
|
export declare const oauthCredentialValue: (credential: OAuthClientCredential) => string;
|
|
7737
8262
|
|
|
8263
|
+
/** Preserve the caller's environment, Exit and cancellation. Observation is
|
|
8264
|
+
* installed before the body's first primitive; it creates no detached runtime. */
|
|
8265
|
+
export declare const observeApiRoleEffect: <A, E>(effect: Effect.Effect<A, E, never>, metrics: ReturnType<typeof makeApiRoleWorkloadMetrics>, workload: ApiWorkload) => Effect.Effect<A, E, never>;
|
|
8266
|
+
|
|
8267
|
+
/**
|
|
8268
|
+
* Test seam: a ConnectionInfo layer that hands every request's headers to
|
|
8269
|
+
* `observe` and reports only the client id. It never authenticates and is not a
|
|
8270
|
+
* boot path; it lives here so ConnectionInfo keeps one construction site.
|
|
8271
|
+
*/
|
|
8272
|
+
export declare const observeConnectionHeaders: (observe: (headers: Readonly<Record<string, string | undefined>>, clientId: number) => void) => Layer.Layer<ConnectionInfoMiddleware>;
|
|
8273
|
+
|
|
7738
8274
|
/** One recorded `(procedure → table, op)` edge. */
|
|
7739
8275
|
export declare interface ObservedEdge {
|
|
7740
8276
|
readonly tag: string;
|
|
@@ -7818,6 +8354,16 @@ export declare type OnMissingRow = (info: NoRowFoundInfo) => unknown;
|
|
|
7818
8354
|
*/
|
|
7819
8355
|
export declare const onProcessShutdown: (hook: () => void | Promise<void>) => (() => void);
|
|
7820
8356
|
|
|
8357
|
+
/**
|
|
8358
|
+
* Open every envelope in one cell with `keyring` — each under the address it
|
|
8359
|
+
* was sealed under, found the same way a re-key finds it. A keyring holding the
|
|
8360
|
+
* active key alone answers "does anything still need another key?".
|
|
8361
|
+
*/
|
|
8362
|
+
export declare const openCell: (text: string, keyring: FieldKeyring, context: CellContext) => {
|
|
8363
|
+
readonly opened: number;
|
|
8364
|
+
readonly unopened: number;
|
|
8365
|
+
};
|
|
8366
|
+
|
|
7821
8367
|
/** Thrown by `.expectVersion(n).set(...)` when the optimistic-lock guard
|
|
7822
8368
|
* matched no row (the row was concurrently updated or deleted). */
|
|
7823
8369
|
export declare class OptimisticLockError extends OptimisticLockError_base {
|
|
@@ -8013,14 +8559,14 @@ export declare const outboxAttemptsTable: TableLike;
|
|
|
8013
8559
|
* twice because of us or because of them" becomes unanswerable. */
|
|
8014
8560
|
export declare type OutboxAttemptTrigger = 'automatic' | 'manual';
|
|
8015
8561
|
|
|
8016
|
-
|
|
8017
|
-
|
|
8018
|
-
|
|
8019
|
-
|
|
8020
|
-
|
|
8021
|
-
|
|
8022
|
-
|
|
8023
|
-
|
|
8562
|
+
/** Declared-event publication for an outbox attempt, scoped to its queued tenant.
|
|
8563
|
+
* This service provides no request subject or store access. */
|
|
8564
|
+
export declare class OutboxEventPublisher extends OutboxEventPublisher_base {
|
|
8565
|
+
}
|
|
8566
|
+
|
|
8567
|
+
declare const OutboxEventPublisher_base: Context.ServiceClass<OutboxEventPublisher, "@voltro/OutboxEventPublisher", EventPublisher>;
|
|
8568
|
+
|
|
8569
|
+
export declare interface OutboxFacade extends OutboxEnqueueFacade {
|
|
8024
8570
|
/**
|
|
8025
8571
|
* Re-arm one entry for delivery NOW, on purpose, attributed to the caller.
|
|
8026
8572
|
*
|
|
@@ -8065,25 +8611,9 @@ export declare interface OutboxFacadeDeps {
|
|
|
8065
8611
|
readonly now?: () => Date;
|
|
8066
8612
|
}
|
|
8067
8613
|
|
|
8068
|
-
export
|
|
8069
|
-
/** Stable identity of this delivery intent, preserved across retries. */
|
|
8070
|
-
readonly outboxId: string;
|
|
8071
|
-
/** Caller-supplied enqueue key, or null. Unlike outboxId this can be reused
|
|
8072
|
-
* for a distinct intent after an earlier intent has been delivered. */
|
|
8073
|
-
readonly idempotencyKey: string | null;
|
|
8074
|
-
readonly payload: Record<string, unknown>;
|
|
8075
|
-
readonly attempt: number;
|
|
8076
|
-
readonly subjectId: string | null;
|
|
8077
|
-
readonly tenantId: string | null;
|
|
8078
|
-
readonly traceId: string | null;
|
|
8079
|
-
}
|
|
8614
|
+
export { OutboxHandlerContext }
|
|
8080
8615
|
|
|
8081
|
-
export
|
|
8082
|
-
readonly effect: string;
|
|
8083
|
-
readonly handler: (ctx: OutboxHandlerContext) => Promise<unknown> | Effect.Effect<unknown, unknown, R>;
|
|
8084
|
-
/** Give up after this many attempts, then dead-letter. Default 8. */
|
|
8085
|
-
readonly maxAttempts?: number;
|
|
8086
|
-
}
|
|
8616
|
+
export { OutboxHandlerDefinition }
|
|
8087
8617
|
|
|
8088
8618
|
/** What the pump hands events to — the `emit` of a `Stream.asyncScoped`. */
|
|
8089
8619
|
export declare interface OutboxSink<T> {
|
|
@@ -8129,6 +8659,9 @@ export declare interface PairInput {
|
|
|
8129
8659
|
*/
|
|
8130
8660
|
export declare const parseApprovalInterval: (spec: string) => number | null;
|
|
8131
8661
|
|
|
8662
|
+
/** `unity/0.1.0; surface=<64 hex>` → its parts; anything else is not an engine SDK. */
|
|
8663
|
+
export declare const parseEngineSdkHeader: (value: string) => Omit<EngineClient, "id" | "connectedAt"> | null;
|
|
8664
|
+
|
|
8132
8665
|
/** Parse a `traceparent` header. Returns null when malformed or when
|
|
8133
8666
|
* the all-zero invalid ids are present (per the spec those are
|
|
8134
8667
|
* treated as "no parent"). */
|
|
@@ -8333,8 +8866,7 @@ export declare type ProbeKind = 'liveness' | 'readiness' | 'startup';
|
|
|
8333
8866
|
* columns, which have no wire representation at all. */
|
|
8334
8867
|
export declare const projectConnectionState: (definition: ConnectionDefinition, row: AnyRow_2 | undefined) => ConnectionState_2;
|
|
8335
8868
|
|
|
8336
|
-
|
|
8337
|
-
export declare type PropertyFilter = Readonly<Record<string, string | number | boolean | null>>;
|
|
8869
|
+
export { PropertyFilter }
|
|
8338
8870
|
|
|
8339
8871
|
export declare interface ProvenanceActor {
|
|
8340
8872
|
readonly id: string | null;
|
|
@@ -8488,8 +9020,25 @@ export declare interface PumpOptions {
|
|
|
8488
9020
|
*/
|
|
8489
9021
|
export declare const pumpOutbox: <T>(outbox: SubscriptionOutbox<T>, sink: OutboxSink<T>, label: string, options?: PumpOptions) => Promise<void>;
|
|
8490
9022
|
|
|
9023
|
+
/** A query's declared `cache:` block, structurally — see `QueryCacheConfig`. */
|
|
9024
|
+
export declare interface QueryCacheLike {
|
|
9025
|
+
readonly ttl: number | string;
|
|
9026
|
+
readonly swr?: number | string | undefined;
|
|
9027
|
+
readonly scope: ComputedCacheScope;
|
|
9028
|
+
readonly volatile?: boolean | undefined;
|
|
9029
|
+
}
|
|
9030
|
+
|
|
9031
|
+
/** A query's declared `cache:`, parsed — `undefined` when the ttl does not
|
|
9032
|
+
* parse (the cache is then off for that query; `voltro doctor` says so). */
|
|
9033
|
+
export declare const queryCachePolicy: (cache: {
|
|
9034
|
+
readonly ttl: number | string;
|
|
9035
|
+
readonly swr?: number | string | undefined;
|
|
9036
|
+
readonly scope: ComputedCacheScope;
|
|
9037
|
+
readonly volatile?: boolean | undefined;
|
|
9038
|
+
}) => ComputedQueryCachePolicy | undefined;
|
|
9039
|
+
|
|
8491
9040
|
/**
|
|
8492
|
-
* The
|
|
9041
|
+
* The read scopes, composed once, for every path that finalises a descriptor.
|
|
8493
9042
|
*
|
|
8494
9043
|
* **The primitives above were extracted so there is "no second copy that could
|
|
8495
9044
|
* drift" — and then the COMPOSITION became the second copy.** `voltro dev`
|
|
@@ -8515,6 +9064,8 @@ export declare const pumpOutbox: <T>(outbox: SubscriptionOutbox<T>, sink: Outbox
|
|
|
8515
9064
|
export declare interface QueryFinalizeOptions {
|
|
8516
9065
|
readonly tenantScopedTables: ReadonlySet<string>;
|
|
8517
9066
|
readonly softDeleteScopedTables: ReadonlySet<string>;
|
|
9067
|
+
/** Tables carrying expires(); hosts derive this set from the schema registry. */
|
|
9068
|
+
readonly expiresScopedTables?: ReadonlySet<string>;
|
|
8518
9069
|
readonly observe?: {
|
|
8519
9070
|
/** Before scoping — sees what the handler asked for. */
|
|
8520
9071
|
readonly beforeScope?: (descriptor: QueryDescriptor, subject: {
|
|
@@ -8532,6 +9083,9 @@ export declare type QueryLike<R = Row_7> = QueryDescriptor<R> | {
|
|
|
8532
9083
|
};
|
|
8533
9084
|
|
|
8534
9085
|
export declare interface QueryProducerDeps<D> {
|
|
9086
|
+
readonly workloadMetrics?: ReturnType<typeof makeApiRoleWorkloadMetrics>;
|
|
9087
|
+
/** See {@link ComputedQueryCacheDeps}. */
|
|
9088
|
+
readonly computedCache?: ComputedQueryCacheDeps;
|
|
8535
9089
|
readonly buildContext: (request: ServeRequestContext) => {
|
|
8536
9090
|
readonly store: unknown;
|
|
8537
9091
|
};
|
|
@@ -8844,6 +9398,19 @@ export declare interface ReactiveSocketTunables {
|
|
|
8844
9398
|
* (unit tests, a bare library use). */
|
|
8845
9399
|
export declare const reactiveSocketTunables: () => ReactiveSocketTunables;
|
|
8846
9400
|
|
|
9401
|
+
/** Bounded exact-incarnation read. Corruption/read failure is raised, never
|
|
9402
|
+
* flattened to no observations. Membership expiry does not delete this history. */
|
|
9403
|
+
export declare const readApiRoleWorkloadWindow: (store: DataStore, input: {
|
|
9404
|
+
readonly now: number;
|
|
9405
|
+
readonly replicaId: string;
|
|
9406
|
+
readonly startedAt: number;
|
|
9407
|
+
readonly role: string;
|
|
9408
|
+
readonly requiredWorkloads: ReadonlyArray<ApiWorkload>;
|
|
9409
|
+
}) => Promise<{
|
|
9410
|
+
buckets: ApiRoleWorkloadBucket[];
|
|
9411
|
+
assessment: ApiRoleWindowAssessment;
|
|
9412
|
+
}>;
|
|
9413
|
+
|
|
8847
9414
|
export declare interface ReadClassification {
|
|
8848
9415
|
/** Tables whose ROWS can reach the caller: the queried table and its joins. */
|
|
8849
9416
|
readonly composed: ReadonlySet<string>;
|
|
@@ -8851,6 +9418,14 @@ export declare interface ReadClassification {
|
|
|
8851
9418
|
readonly restricting: ReadonlySet<string>;
|
|
8852
9419
|
}
|
|
8853
9420
|
|
|
9421
|
+
/** Every recorded lease, live or not. */
|
|
9422
|
+
export declare const readFieldKeyHolders: (store: DataStore) => Promise<ReadonlyArray<FieldKeyHolderRecord>>;
|
|
9423
|
+
|
|
9424
|
+
export declare const readFieldKeyReports: (store: DataStore) => Promise<FieldKeyReports>;
|
|
9425
|
+
|
|
9426
|
+
/** The recorded keys, without decrypting anything. */
|
|
9427
|
+
export declare const readFieldKeys: (store: DataStore) => Promise<ReadonlyArray<FieldKeyRow>>;
|
|
9428
|
+
|
|
8854
9429
|
/** First-or-null for a boot DataStore or a query-only tuple source. It invokes
|
|
8855
9430
|
* the supplied query path, preserving that path's filters and codecs. A raw
|
|
8856
9431
|
* driver remains raw; this helper does not add request scoping. */
|
|
@@ -8990,6 +9565,12 @@ export declare const recordExternalMissed: (name: string, count?: number) => voi
|
|
|
8990
9565
|
|
|
8991
9566
|
export declare const recordExternalTrigger: (name: string, outcome: "accepted" | "duplicate" | "noOccurrence" | "ahead" | "notExternal" | "unknownSchedule") => void;
|
|
8992
9567
|
|
|
9568
|
+
/** One open of a sealed value. `key` opened it (`ok`) or was named by it (`failed`). */
|
|
9569
|
+
export declare const recordFieldDecrypt: (key: string, location: string, outcome: "ok" | "failed") => void;
|
|
9570
|
+
|
|
9571
|
+
/** Record the last count or re-key — one row per kind, replaced each time. */
|
|
9572
|
+
export declare const recordFieldKeyReport: <K extends keyof FieldKeyReports>(store: DataStore, kind: K, report: NonNullable<FieldKeyReports[K]>["report"], at?: Date) => Promise<void>;
|
|
9573
|
+
|
|
8993
9574
|
/**
|
|
8994
9575
|
* Record one emitted event into the identity's ring. Snapshots RESET the ring
|
|
8995
9576
|
* (the snapshot's revision becomes the new replay base — a client holding an
|
|
@@ -9120,76 +9701,32 @@ export declare const redactColumns: <R extends Row>(rows: ReadonlyArray<R>, reda
|
|
|
9120
9701
|
/** Blank sensitive-looking columns. Returns a new object; null passes through. */
|
|
9121
9702
|
export declare const redactRow: (row: Row_2 | null | undefined) => Row_2 | null;
|
|
9122
9703
|
|
|
9123
|
-
/**
|
|
9124
|
-
* Options for `redisRywPositionStore`. The store needs TWO Redis
|
|
9125
|
-
* connections because `SUBSCRIBE` puts a client in a mode where only
|
|
9126
|
-
* (P)SUB / UNSUB / PING / QUIT are valid — sharing one client across
|
|
9127
|
-
* writes and the subscribe loop would deadlock. Pass the same client
|
|
9128
|
-
* for both unless you've separated them yourself.
|
|
9129
|
-
*/
|
|
9704
|
+
/** Registry-owned command facade and one borrowed Pub/Sub consumer. */
|
|
9130
9705
|
export declare interface RedisRywOptions {
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
|
|
9134
|
-
|
|
9135
|
-
|
|
9136
|
-
/**
|
|
9137
|
-
* Separate connection dedicated to the SUBSCRIBE loop. Pass a fresh
|
|
9138
|
-
* `client.duplicate()` of the main connection; the store does NOT
|
|
9139
|
-
* duplicate internally because callers may want to manage the
|
|
9140
|
-
* subscription connection's lifecycle separately.
|
|
9141
|
-
*/
|
|
9142
|
-
readonly subscriber: Redis;
|
|
9143
|
-
/**
|
|
9144
|
-
* Redis key prefix — every entry stores under `${keyPrefix}:<subjectKey>`.
|
|
9145
|
-
* Defaults to `'voltro:ryw'`. Override to namespace per-app when
|
|
9146
|
-
* multiple deployments share a Redis.
|
|
9147
|
-
*/
|
|
9148
|
-
readonly keyPrefix?: string;
|
|
9149
|
-
/**
|
|
9150
|
-
* Pub/sub channel name. Defaults to `${keyPrefix}:bus`. All nodes
|
|
9151
|
-
* sharing an RYW state MUST agree on this name.
|
|
9152
|
-
*/
|
|
9706
|
+
readonly client: RespClient;
|
|
9707
|
+
readonly pubsub: RedisPubSub;
|
|
9708
|
+
/** Application/environment namespace. Required; never shared implicitly. */
|
|
9709
|
+
readonly keyPrefix: string;
|
|
9710
|
+
/** Defaults to `${keyPrefix}:bus`; all participating processes must agree. */
|
|
9153
9711
|
readonly channel?: string;
|
|
9154
|
-
/** Clock injection for tests. Defaults to `Date.now`. */
|
|
9155
9712
|
readonly now?: () => number;
|
|
9156
|
-
/**
|
|
9157
|
-
* Called when a Redis-side error occurs (publish/setex/subscribe
|
|
9158
|
-
* failure). RYW degrades gracefully — local writes still succeed,
|
|
9159
|
-
* other instances just won't see this node's writes until the next
|
|
9160
|
-
* one. Hook for observability; default is a console.warn.
|
|
9161
|
-
*/
|
|
9713
|
+
/** Local writes survive remote failures. Failed mutations are never replayed. */
|
|
9162
9714
|
readonly onError?: (error: unknown, op: 'set' | 'delete' | 'subscribe' | 'parse') => void;
|
|
9163
9715
|
}
|
|
9164
9716
|
|
|
9717
|
+
export declare interface RedisRywPositionStore extends RywPositionStore {
|
|
9718
|
+
/** Drain accepted writes and release this consumer, leaving shared sockets open. */
|
|
9719
|
+
readonly close: () => Promise<void>;
|
|
9720
|
+
}
|
|
9721
|
+
|
|
9165
9722
|
/**
|
|
9166
|
-
*
|
|
9167
|
-
*
|
|
9168
|
-
*
|
|
9169
|
-
*
|
|
9170
|
-
*
|
|
9171
|
-
* 1. write to local map (immediate, sync)
|
|
9172
|
-
* 2. fire-and-forget SETEX in Redis with millisecond TTL
|
|
9173
|
-
* 3. fire-and-forget PUBLISH on the channel — peers update
|
|
9174
|
-
* their local mirror without round-tripping Redis again
|
|
9175
|
-
* - on `delete(key)`:
|
|
9176
|
-
* 1. remove from local map
|
|
9177
|
-
* 2. fire-and-forget DEL + PUBLISH
|
|
9178
|
-
* - on `get(key)`:
|
|
9179
|
-
* 1. read from local map; lazy-evict if expired
|
|
9180
|
-
*
|
|
9181
|
-
* The SUBSCRIBE loop receives self-publishes (Redis sends them back
|
|
9182
|
-
* to the sender). Each entry carries a `senderId`; the local node
|
|
9183
|
-
* filters out its own broadcasts so we don't double-apply.
|
|
9184
|
-
*
|
|
9185
|
-
* On boot the local mirror is EMPTY. A read for a subject whose write
|
|
9186
|
-
* happened on a peer node before this node started will miss the
|
|
9187
|
-
* mirror — but `ReplicatedDataStore` falls back to primary on
|
|
9188
|
-
* "no position", so the worst-case is "one extra primary read on the
|
|
9189
|
-
* very first request that touches a peer-written subject". After that
|
|
9190
|
-
* read, this node's own writes propagate normally.
|
|
9723
|
+
* Subscribe before returning. Reads consult only the process-local mirror.
|
|
9724
|
+
* Writes update it synchronously, then enqueue PSETEX/DEL followed by PUBLISH.
|
|
9725
|
+
* Pub/Sub is eventual and cannot replay lost messages or rebuild a new mirror.
|
|
9726
|
+
* A missing position still follows replica routing under fallback and wait;
|
|
9727
|
+
* neither policy establishes cross-process read-your-writes before delivery.
|
|
9191
9728
|
*/
|
|
9192
|
-
export declare const redisRywPositionStore: (options: RedisRywOptions) =>
|
|
9729
|
+
export declare const redisRywPositionStore: (options: RedisRywOptions) => Effect.Effect<RedisRywPositionStore, KvError>;
|
|
9193
9730
|
|
|
9194
9731
|
/** `__voltro.undo.redo` — re-apply a previously-undone invocation's forward
|
|
9195
9732
|
* changes. Idempotent if not currently undone. */
|
|
@@ -9243,7 +9780,15 @@ export declare const registerConnectionStream: (clientId: number, interrupt: ()
|
|
|
9243
9780
|
*/
|
|
9244
9781
|
export declare const registerDefaultTupleSource: (source: TupleSource) => boolean;
|
|
9245
9782
|
|
|
9246
|
-
|
|
9783
|
+
/** Process-level callers share the same map even across duplicated modules. */
|
|
9784
|
+
export declare const registerExternalizedTask: (task: ExternalizedTask) => (() => void);
|
|
9785
|
+
|
|
9786
|
+
/**
|
|
9787
|
+
* Record a key ahead of the deploy that brings it, as `pending`, with its
|
|
9788
|
+
* canary — so the first boot that holds it verifies its material, and the
|
|
9789
|
+
* configuration without it still boots (nothing is sealed under a pending key).
|
|
9790
|
+
*/
|
|
9791
|
+
export declare const registerFieldKey: (store: DataStore, keyring: FieldKeyring, keyId: string) => Promise<void>;
|
|
9247
9792
|
|
|
9248
9793
|
export { registerRetention }
|
|
9249
9794
|
|
|
@@ -9340,6 +9885,37 @@ export declare interface RegistryTableLike {
|
|
|
9340
9885
|
* request was. */
|
|
9341
9886
|
export declare const rehydrateGuards: (serialized: ReadonlyArray<SerializedGuard>) => ReadonlyArray<AnyGuardSpec>;
|
|
9342
9887
|
|
|
9888
|
+
/**
|
|
9889
|
+
* Re-seal every envelope in one cell that is not under the active key, or
|
|
9890
|
+
* names no key, under the active key and the address it was sealed under.
|
|
9891
|
+
*/
|
|
9892
|
+
export declare const rekeyCell: (text: string, keyring: FieldKeyring, context: CellContext) => CellRekey;
|
|
9893
|
+
|
|
9894
|
+
export declare interface RekeyReport {
|
|
9895
|
+
readonly active: string;
|
|
9896
|
+
readonly locations: ReadonlyArray<LocationRekey>;
|
|
9897
|
+
readonly unreadable: ReadonlyArray<UnreadableColumn>;
|
|
9898
|
+
}
|
|
9899
|
+
|
|
9900
|
+
/**
|
|
9901
|
+
* Re-key every discovered location under the keyring's active key. With
|
|
9902
|
+
* `dryRun`, count what would change and write nothing.
|
|
9903
|
+
*/
|
|
9904
|
+
export declare const rekeySealedValues: (dialect: DialectId, keyring: FieldKeyring, declared: Iterable<unknown>, options?: {
|
|
9905
|
+
readonly dryRun?: boolean;
|
|
9906
|
+
readonly onProgress?: (location: LocationRekey) => void;
|
|
9907
|
+
/** Runs between reading a cell and writing it back — where another writer may change it. */
|
|
9908
|
+
readonly beforeWrite?: (cell: {
|
|
9909
|
+
readonly table: string;
|
|
9910
|
+
readonly column: string;
|
|
9911
|
+
readonly rowId: unknown;
|
|
9912
|
+
}) => Effect.Effect<void, unknown, SqlClient.SqlClient>;
|
|
9913
|
+
}) => Effect.Effect<{
|
|
9914
|
+
active: string;
|
|
9915
|
+
locations: LocationRekey[];
|
|
9916
|
+
unreadable: UnreadableColumn[];
|
|
9917
|
+
}, SqlError, SqlClient.SqlClient>;
|
|
9918
|
+
|
|
9343
9919
|
/** The store slice `applyDeclaredRelations` needs. `columns` is the junction's
|
|
9344
9920
|
* DERIVED reference pair — the truth the descriptor's declaration is checked
|
|
9345
9921
|
* against before anything is written. */
|
|
@@ -9362,6 +9938,9 @@ export declare interface RelationTuple {
|
|
|
9362
9938
|
readonly resourceId: string;
|
|
9363
9939
|
}
|
|
9364
9940
|
|
|
9941
|
+
/** Give up this process's lease — on shutdown, so nobody waits for it. */
|
|
9942
|
+
export declare const releaseFieldKeyHolder: (store: DataStore, holderId: string) => Promise<void>;
|
|
9943
|
+
|
|
9365
9944
|
/**
|
|
9366
9945
|
* Release a claim back to `pending` (CAS `fired → pending`) — used when
|
|
9367
9946
|
* the wake failed, so the next poll retries it (at-least-once wake). The
|
|
@@ -9452,6 +10031,7 @@ export declare interface ReplicaSelector {
|
|
|
9452
10031
|
}
|
|
9453
10032
|
|
|
9454
10033
|
export declare class ReplicatedDataStore implements DataStore {
|
|
10034
|
+
readonly integrityQuery?: NonNullable<DataStore['integrityQuery']>;
|
|
9455
10035
|
private readonly primary;
|
|
9456
10036
|
private readonly replicas;
|
|
9457
10037
|
private readonly adapter;
|
|
@@ -9463,12 +10043,13 @@ export declare class ReplicatedDataStore implements DataStore {
|
|
|
9463
10043
|
private readonly health;
|
|
9464
10044
|
private readonly recordRouting?;
|
|
9465
10045
|
private readonly now;
|
|
10046
|
+
private closing;
|
|
9466
10047
|
constructor(options: ReplicatedDataStoreOptions);
|
|
9467
10048
|
query(descriptor: QueryDescriptor): Promise<ReadonlyArray<Row>>;
|
|
9468
10049
|
private routeToReplica;
|
|
9469
10050
|
private routeWaitMode;
|
|
9470
10051
|
insert(table: string, row: Row): Promise<Row>;
|
|
9471
|
-
insertMany(table: string, rows: ReadonlyArray<Row
|
|
10052
|
+
insertMany(table: string, rows: ReadonlyArray<Row>, options?: InsertManyOptions): Promise<ReadonlyArray<Row>>;
|
|
9472
10053
|
patchJson(table: string, primaryKey: string, path: string, value: unknown, additionalPatch?: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
9473
10054
|
update(table: string, primaryKey: string, patch: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
9474
10055
|
delete(table: string, primaryKey: string): Promise<boolean>;
|
|
@@ -9493,6 +10074,8 @@ export declare class ReplicatedDataStore implements DataStore {
|
|
|
9493
10074
|
injectExternalChange(event: ChangeEvent): void;
|
|
9494
10075
|
/** Forwarded from the primary — see DataStore.changeScope. */
|
|
9495
10076
|
get changeScope(): 'local' | 'fleet';
|
|
10077
|
+
/** Drain the RYW consumer before closing every SQL pool; repeated close is shared. */
|
|
10078
|
+
close(gracePeriodMs?: number): Promise<void>;
|
|
9496
10079
|
private stampPostWrite;
|
|
9497
10080
|
private emitRouting;
|
|
9498
10081
|
}
|
|
@@ -9574,8 +10157,8 @@ export declare interface ResendOptions {
|
|
|
9574
10157
|
readonly attempts?: number;
|
|
9575
10158
|
}
|
|
9576
10159
|
|
|
9577
|
-
/**
|
|
9578
|
-
export declare const
|
|
10160
|
+
/** Test seam: back to the boot default. */
|
|
10161
|
+
export declare const resetComputedQueryCacheCaptureForTests: () => void;
|
|
9579
10162
|
|
|
9580
10163
|
/** Test/dev-only — clear ALL per-connection state. Don't call from app code. */
|
|
9581
10164
|
export declare const _resetConnectionCredentialsForTest: () => void;
|
|
@@ -9586,6 +10169,9 @@ export declare const resetDetachedForTest: () => void;
|
|
|
9586
10169
|
/** Test seams for the tag-cache guard — the cache is module-private otherwise. */
|
|
9587
10170
|
export declare const resetEventMetricTagCacheForTests: () => void;
|
|
9588
10171
|
|
|
10172
|
+
/** Test seam. */
|
|
10173
|
+
export declare const resetFieldDecryptCountsForTests: () => void;
|
|
10174
|
+
|
|
9589
10175
|
/** Drop everything recorded. For tests; not called by the runtime. */
|
|
9590
10176
|
export declare const resetObservedGraph: () => void;
|
|
9591
10177
|
|
|
@@ -9720,7 +10306,9 @@ export declare interface ResolvedDevice {
|
|
|
9720
10306
|
* Walk a query descriptor's eager-load tree and return the FULL set
|
|
9721
10307
|
* of tables whose changes could affect the resolved snapshot.
|
|
9722
10308
|
*
|
|
9723
|
-
* -
|
|
10309
|
+
* - Includes explicitly declared invalidation sources (`dependentTables`),
|
|
10310
|
+
* independently of SQL predicates and projections.
|
|
10311
|
+
* - A plain query with no additional sources returns `{ descriptor.table }`.
|
|
9724
10312
|
* - For each one()/many() relation, adds the target table.
|
|
9725
10313
|
* - For each manyToMany() relation, adds the through-table AND the
|
|
9726
10314
|
* target table (writes to either can shift the resolved set).
|
|
@@ -9787,6 +10375,15 @@ export declare interface ResolvedWorkflowCallerContext extends WorkflowCallerCon
|
|
|
9787
10375
|
readonly rowFilter: RowFilterScope;
|
|
9788
10376
|
}
|
|
9789
10377
|
|
|
10378
|
+
/**
|
|
10379
|
+
* The keyring an environment configures, or `undefined` when it configures no
|
|
10380
|
+
* key at all. Refuses (`FieldKeyringConfigError`, never containing key material)
|
|
10381
|
+
* an unknown or missing active id, a duplicate id, one key under two ids,
|
|
10382
|
+
* `KEY` equal to `_PREVIOUS`, and a `KEY`/`_PREVIOUS` set beside `KEYS` that
|
|
10383
|
+
* `KEYS` does not contain.
|
|
10384
|
+
*/
|
|
10385
|
+
export declare const resolveFieldKeyring: (env: Readonly<Record<string, string | undefined>>) => FieldKeyringConfig | undefined;
|
|
10386
|
+
|
|
9790
10387
|
/**
|
|
9791
10388
|
* Resolve the app's health block against the boot path's own readiness flag.
|
|
9792
10389
|
*
|
|
@@ -10057,6 +10654,15 @@ export { RetentionSpec }
|
|
|
10057
10654
|
|
|
10058
10655
|
export { retentionTtlMsFromEnv }
|
|
10059
10656
|
|
|
10657
|
+
/**
|
|
10658
|
+
* Retire a key: nothing may be sealed under it again, and a configuration may
|
|
10659
|
+
* drop it — the boot no longer asks for it. Refused for the active key, a key
|
|
10660
|
+
* nobody recorded, and a key a live process still seals new values under (it
|
|
10661
|
+
* has not adopted the new key yet). Whether VALUES are still sealed under it is
|
|
10662
|
+
* the caller's question to answer first (`voltro secret retire` counts them).
|
|
10663
|
+
*/
|
|
10664
|
+
export declare const retireFieldKey: (store: DataStore, keyId: string, holder?: Pick<FieldKeyHolder, "now">) => Promise<void>;
|
|
10665
|
+
|
|
10060
10666
|
/**
|
|
10061
10667
|
* Drop the ISR cache entries for a path on every `voltro start` replica.
|
|
10062
10668
|
*
|
|
@@ -10364,6 +10970,8 @@ export declare interface RpcConnection {
|
|
|
10364
10970
|
|
|
10365
10971
|
export declare interface RpcServerOptions<Rpcs extends Rpc.Any> {
|
|
10366
10972
|
readonly group: RpcGroup.RpcGroup<Rpcs>;
|
|
10973
|
+
/** Executable RPC surfaces for this replica; omitted retains both transports. */
|
|
10974
|
+
readonly workloadAdmission?: RpcWorkloadAdmission;
|
|
10367
10975
|
readonly handlersLayer: Layer.Layer<Rpc.ToHandler<Rpcs>>;
|
|
10368
10976
|
/** Optional handlers layer dedicated to the one-shot HTTP rpc surface
|
|
10369
10977
|
* (`POST /rpc`, used by SSR web-router loaders). The HTTP JSON protocol
|
|
@@ -10559,6 +11167,14 @@ export declare interface RpcServerOptions<Rpcs extends Rpc.Any> {
|
|
|
10559
11167
|
readonly security?: TransportSecurityOptions;
|
|
10560
11168
|
}
|
|
10561
11169
|
|
|
11170
|
+
export declare interface RpcWorkloadAdmission {
|
|
11171
|
+
readonly rpc: boolean;
|
|
11172
|
+
readonly subscriptions: boolean;
|
|
11173
|
+
/** Event streams are independent of live query subscriptions. */
|
|
11174
|
+
readonly events?: boolean;
|
|
11175
|
+
readonly routes?: ReadonlyArray<string>;
|
|
11176
|
+
}
|
|
11177
|
+
|
|
10562
11178
|
/**
|
|
10563
11179
|
* Rules that apply to one change, or an empty list.
|
|
10564
11180
|
*
|
|
@@ -10643,6 +11259,10 @@ export declare const runSingleNodeOrchestrator: (opts: SingleNodeOrchestratorOpt
|
|
|
10643
11259
|
export declare const RUNTIME_NAME: "framework-runtime";
|
|
10644
11260
|
|
|
10645
11261
|
export declare interface RuntimeContext {
|
|
11262
|
+
/** Effective incoming Cookie header for server-side signature verification.
|
|
11263
|
+
* Unverified private input; never return, log or persist it. Optional for
|
|
11264
|
+
* internal callers and cookie-less requests. */
|
|
11265
|
+
readonly cookieHeader?: string;
|
|
10646
11266
|
/** Subscription / call subject — user, API key, service account, or anonymous. */
|
|
10647
11267
|
readonly subject: Subject;
|
|
10648
11268
|
/** Trace identifier — the active span's W3C trace id (32 hex) when
|
|
@@ -10776,6 +11396,8 @@ export declare interface RywPositionStore {
|
|
|
10776
11396
|
delete(subjectKey: string): void;
|
|
10777
11397
|
/** Approximate size for observability + tests. */
|
|
10778
11398
|
size(): number;
|
|
11399
|
+
/** Release consumer resources when this store owns any. */
|
|
11400
|
+
readonly close?: () => Promise<void>;
|
|
10779
11401
|
}
|
|
10780
11402
|
|
|
10781
11403
|
/**
|
|
@@ -10948,6 +11570,8 @@ export declare type ScheduleHandler = (ctx: ScheduleContext) => void | Promise<v
|
|
|
10948
11570
|
export declare type ScheduleOverlapPolicy = 'skip' | 'queue' | 'parallel';
|
|
10949
11571
|
|
|
10950
11572
|
export declare interface SchedulerDeps {
|
|
11573
|
+
/** Active synchronous handler entry only; never await a Promise inside this measurement. */
|
|
11574
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
10951
11575
|
/** App-owned service environment; the signal interrupts Effect work on timeout. */
|
|
10952
11576
|
readonly runEffect?: (effect: Extract<ReturnType<ScheduleHandler>, Effect.Effect<unknown, unknown, unknown>>, signal: AbortSignal) => Promise<unknown>;
|
|
10953
11577
|
readonly store: DataStore;
|
|
@@ -11059,6 +11683,8 @@ export declare interface SchedulerDeps {
|
|
|
11059
11683
|
}
|
|
11060
11684
|
|
|
11061
11685
|
export declare interface SchedulerHandle {
|
|
11686
|
+
/** Completed startup and shutdown has not begun; not a successful-job claim. */
|
|
11687
|
+
isRunning(): boolean;
|
|
11062
11688
|
/** Fire a schedule immediately, bypassing the cron clock + the
|
|
11063
11689
|
* coordinator. Waits for handler completion and returns the recorded run id. */
|
|
11064
11690
|
fireNow(name: string, trigger: ScheduleTrigger | 'manual'): Promise<string | undefined>;
|
|
@@ -11364,6 +11990,22 @@ declare interface ScopeCtx {
|
|
|
11364
11990
|
/** The scope strings a UI shows ("ask someone with …"). */
|
|
11365
11991
|
export declare const scopeStringsOf: (serialized: ReadonlyArray<SerializedGuard>) => ReadonlyArray<string>;
|
|
11366
11992
|
|
|
11993
|
+
/** One column that holds envelopes, and what is under which key in it. */
|
|
11994
|
+
export declare interface SealedLocation {
|
|
11995
|
+
readonly table: string;
|
|
11996
|
+
readonly column: string;
|
|
11997
|
+
/** The app declares it `.encrypted()` (a whole cell is one value), rather than a place found holding envelopes. */
|
|
11998
|
+
readonly declared: boolean;
|
|
11999
|
+
/** Cells holding at least one envelope. */
|
|
12000
|
+
readonly cells: number;
|
|
12001
|
+
/** Envelopes, counted per key id. */
|
|
12002
|
+
readonly byKey: Readonly<Record<string, number>>;
|
|
12003
|
+
/** Envelopes written before envelopes named their key. */
|
|
12004
|
+
readonly unnamed: number;
|
|
12005
|
+
/** Declared `.encrypted()` only: non-null cells that are not an envelope. */
|
|
12006
|
+
readonly plaintext: number;
|
|
12007
|
+
}
|
|
12008
|
+
|
|
11367
12009
|
export declare interface SecretsBackend {
|
|
11368
12010
|
/** Resolve a secret by key. `undefined` when absent. */
|
|
11369
12011
|
readonly get: (key: string) => Promise<string | undefined>;
|
|
@@ -11503,6 +12145,8 @@ export declare type SerializedGuard = {
|
|
|
11503
12145
|
readonly resource: string | null;
|
|
11504
12146
|
} | {
|
|
11505
12147
|
readonly kind: 'authenticated';
|
|
12148
|
+
} | {
|
|
12149
|
+
readonly kind: 'upgraded';
|
|
11506
12150
|
};
|
|
11507
12151
|
|
|
11508
12152
|
/**
|
|
@@ -11511,7 +12155,25 @@ export declare type SerializedGuard = {
|
|
|
11511
12155
|
*/
|
|
11512
12156
|
export declare const serializeGuards: (guards: ReadonlyArray<AnyGuardSpec>, input: unknown) => ReadonlyArray<SerializedGuard>;
|
|
11513
12157
|
|
|
12158
|
+
/** Required plugin work executed on the actual transaction connection. */
|
|
12159
|
+
export declare type ServeMutationCommitHook = (context: Parameters<ServeRpcInterceptor>[1] & {
|
|
12160
|
+
readonly kind: 'mutation';
|
|
12161
|
+
readonly store: DataStore;
|
|
12162
|
+
readonly output: unknown;
|
|
12163
|
+
readonly outbox?: OutboxEnqueueFacade;
|
|
12164
|
+
readonly startedAt?: number;
|
|
12165
|
+
readonly durationMs?: number;
|
|
12166
|
+
}) => Effect.Effect<void, unknown>;
|
|
12167
|
+
|
|
11514
12168
|
export declare interface ServeRequestContext {
|
|
12169
|
+
/** Listener-owned identity; used only for measurement attribution here. */
|
|
12170
|
+
readonly connection?: {
|
|
12171
|
+
readonly transport: 'http' | 'websocket';
|
|
12172
|
+
};
|
|
12173
|
+
/** Effective incoming Cookie header for server-side signature verification.
|
|
12174
|
+
* Unverified private input; never return, log or persist it. Optional for
|
|
12175
|
+
* internal callers and cookie-less requests. */
|
|
12176
|
+
readonly cookieHeader?: string;
|
|
11515
12177
|
readonly subject: unknown;
|
|
11516
12178
|
readonly traceId: string;
|
|
11517
12179
|
readonly spanId?: string;
|
|
@@ -11570,10 +12232,11 @@ export declare const serverOnlyLeaks: (query: AuditableQuery, serverOnlyByTable:
|
|
|
11570
12232
|
/** A plugin interceptor — wraps the base run Effect (Effect-native chain). */
|
|
11571
12233
|
export declare type ServeRpcInterceptor = (base: Effect.Effect<unknown, unknown, never>, meta: {
|
|
11572
12234
|
readonly tag: string;
|
|
11573
|
-
readonly kind: 'mutation' | 'action' | 'query' | 'workflow';
|
|
12235
|
+
readonly kind: 'mutation' | 'action' | 'query' | 'workflow' | 'stream';
|
|
11574
12236
|
readonly input: unknown;
|
|
11575
12237
|
readonly subject: unknown;
|
|
11576
12238
|
readonly traceId: string;
|
|
12239
|
+
readonly enqueueOutcome?: OutboxEnqueueFacade['enqueue'];
|
|
11577
12240
|
readonly spanId?: string;
|
|
11578
12241
|
/**
|
|
11579
12242
|
* The declared write-target TABLE names of this mutation/action, derived
|
|
@@ -11785,8 +12448,14 @@ export declare interface SingleNodeOrchestratorOptions {
|
|
|
11785
12448
|
export declare interface SnapshotCache {
|
|
11786
12449
|
readonly wrap: (binding: SnapshotCacheBinding, tags: ReadonlyArray<string>, compute: () => Promise<ReadonlyArray<Row>>) => Promise<ReadonlyArray<Row>>;
|
|
11787
12450
|
/** Write-through from the live recompute, so the cache is never staler
|
|
11788
|
-
* than the freshest live subscriber. Fire-and-forget.
|
|
11789
|
-
|
|
12451
|
+
* than the freshest live subscriber. Fire-and-forget. `fence` is the
|
|
12452
|
+
* cache's invalidation position observed BEFORE the rows were read: a
|
|
12453
|
+
* later invalidation of any tag voids the write, so an earlier, slower
|
|
12454
|
+
* read can never overwrite a later one. */
|
|
12455
|
+
readonly put: (binding: SnapshotCacheBinding, tags: ReadonlyArray<string>, rows: ReadonlyArray<Row>, fence: number) => void;
|
|
12456
|
+
/** The cache's invalidation position — observed before a read whose rows
|
|
12457
|
+
* will be written through. */
|
|
12458
|
+
readonly fence: () => Promise<number>;
|
|
11790
12459
|
}
|
|
11791
12460
|
|
|
11792
12461
|
/**
|
|
@@ -11798,6 +12467,8 @@ export declare interface SnapshotCacheBinding {
|
|
|
11798
12467
|
readonly key: string;
|
|
11799
12468
|
readonly ttlMs: number;
|
|
11800
12469
|
readonly swrMs: number | undefined;
|
|
12470
|
+
/** The query name its counters are kept under (`queryStats`, metrics). */
|
|
12471
|
+
readonly label?: string | undefined;
|
|
11801
12472
|
}
|
|
11802
12473
|
|
|
11803
12474
|
/**
|
|
@@ -11809,6 +12480,20 @@ export declare const snapshotCrdt: (store: CrdtHistoryStore, cell: CrdtCellRef &
|
|
|
11809
12480
|
readonly createdBy?: string;
|
|
11810
12481
|
}) => Promise<CrdtVersion | undefined>;
|
|
11811
12482
|
|
|
12483
|
+
/**
|
|
12484
|
+
* The entry a READ belongs to: the rpc layer's scoped key plus the descriptor
|
|
12485
|
+
* actually read.
|
|
12486
|
+
*
|
|
12487
|
+
* The rpc key names the query, its input and the scope (subject / tenant /
|
|
12488
|
+
* global) — but not what the caller may SEE. A registered row filter makes two
|
|
12489
|
+
* colleagues of one tenant read different rows through the same `'tenant'` key,
|
|
12490
|
+
* and keying by the rpc key alone served the first colleague's filtered rows to
|
|
12491
|
+
* the next one. The read descriptor carries every predicate the caller's
|
|
12492
|
+
* visibility added, so two readers share an entry exactly when they read the
|
|
12493
|
+
* same thing.
|
|
12494
|
+
*/
|
|
12495
|
+
export declare const snapshotEntryFor: (binding: SnapshotCacheBinding, read: QueryDescriptor) => SnapshotCacheBinding;
|
|
12496
|
+
|
|
11812
12497
|
/** Snapshot the whole registry, normalized to `MetricSample[]` — plus the
|
|
11813
12498
|
* socket-backpressure counters (`subscriptionSocketMetrics.ts`), appended
|
|
11814
12499
|
* HERE so every reader (Prometheus exporter, inspect Metrics panel) sees
|
|
@@ -11846,32 +12531,23 @@ export declare class SsrfBlockedError extends Error {
|
|
|
11846
12531
|
*/
|
|
11847
12532
|
export declare const ssrfGuardHttpClientLayer: (policy?: SsrfPolicy) => Layer.Layer<HttpClient.HttpClient, never, HttpClient.HttpClient>;
|
|
11848
12533
|
|
|
11849
|
-
export
|
|
11850
|
-
|
|
11851
|
-
|
|
11852
|
-
* (`billing.internal`), a suffix wildcard (`*.svc.cluster.local`), or a
|
|
11853
|
-
* host:port (`127.0.0.1:8787`) when only one port should be reachable.
|
|
11854
|
-
*
|
|
11855
|
-
* This is the one escape hatch, and it is deliberately per-HOST rather than a
|
|
11856
|
-
* boolean: "we call one internal service" and "we do not check URLs" are very
|
|
11857
|
-
* different postures, and a boolean cannot tell them apart six months later.
|
|
11858
|
-
*/
|
|
11859
|
-
readonly allowHosts?: ReadonlyArray<string>;
|
|
11860
|
-
/** Max redirect hops to follow. Each one is revalidated. Default 5. */
|
|
11861
|
-
readonly maxRedirects?: number;
|
|
11862
|
-
}
|
|
12534
|
+
export { SsrfPolicy }
|
|
12535
|
+
|
|
12536
|
+
export { ssrfReason }
|
|
11863
12537
|
|
|
11864
12538
|
/**
|
|
11865
|
-
*
|
|
11866
|
-
*
|
|
11867
|
-
*
|
|
11868
|
-
* DNS is deliberately NOT resolved — this is a synchronous check on the literal
|
|
11869
|
-
* target, so a hostname that RESOLVES to a private address (DNS rebinding) is not
|
|
11870
|
-
* caught here. Blocking the direct-IP vector is the high-severity, cheap half;
|
|
11871
|
-
* rebinding needs network-layer egress control and is called out in the docs
|
|
11872
|
-
* rather than silently implied.
|
|
12539
|
+
* Heartbeat every {@link FIELD_KEY_HEARTBEAT_MS} for as long as the process
|
|
12540
|
+
* runs. Logs a transition once — a key that became active, a key still waiting
|
|
12541
|
+
* and for whom, an active key this process does not hold — never every beat.
|
|
11873
12542
|
*/
|
|
11874
|
-
export declare const
|
|
12543
|
+
export declare const startFieldKeyHolder: (store: DataStore, keyring: FieldKeyring, holder: FieldKeyHolder & {
|
|
12544
|
+
readonly intervalMs?: number;
|
|
12545
|
+
readonly log: {
|
|
12546
|
+
readonly info: (message: string) => void;
|
|
12547
|
+
readonly warn: (message: string) => void;
|
|
12548
|
+
readonly error: (message: string) => void;
|
|
12549
|
+
};
|
|
12550
|
+
}) => FieldKeyHolderHandle;
|
|
11875
12551
|
|
|
11876
12552
|
/**
|
|
11877
12553
|
* Start the rpc-based runtime server on Node. Composes:
|
|
@@ -12101,6 +12777,12 @@ export declare interface SubscriberDefinition {
|
|
|
12101
12777
|
readonly table: string;
|
|
12102
12778
|
/** Default `'any'`. */
|
|
12103
12779
|
readonly on?: SubscribeOp | ReadonlyArray<Exclude<SubscribeOp, 'any'>>;
|
|
12780
|
+
/** Bind this invocation's event publisher to the trusted committed row's
|
|
12781
|
+
* tenant. No client input is available here. Omitted keeps system/global
|
|
12782
|
+
* publication. This does not change ctx.store's system identity or turn a
|
|
12783
|
+
* best-effort subscriber into durable delivery. Invalid results refuse the
|
|
12784
|
+
* handler rather than publishing into the global partition. */
|
|
12785
|
+
readonly eventTenant?: (event: SubscribeEvent) => string | null;
|
|
12104
12786
|
/**
|
|
12105
12787
|
* Run the handler ONCE PER CHANGE across the whole fleet, instead of once on
|
|
12106
12788
|
* every replica that sees it.
|
|
@@ -12450,7 +13132,7 @@ export declare const tenantSelectionStore: (getStore: () => DataStore | undefine
|
|
|
12450
13132
|
* a page. */
|
|
12451
13133
|
export declare const TERMINAL_RUN_STATUSES: ReadonlySet<string>;
|
|
12452
13134
|
|
|
12453
|
-
export
|
|
13135
|
+
export { TimeBucket }
|
|
12454
13136
|
|
|
12455
13137
|
export declare interface TimelineEvent {
|
|
12456
13138
|
/** Preserves the store's warning that images are not original commit images. */
|
|
@@ -12516,29 +13198,11 @@ export declare class TimelineRecorder {
|
|
|
12516
13198
|
replay(table: string, asOfSeq: number, currentRows: ReadonlyArray<Row_2>): ReadonlyArray<Row_2>;
|
|
12517
13199
|
}
|
|
12518
13200
|
|
|
12519
|
-
|
|
12520
|
-
export declare interface TimeRange {
|
|
12521
|
-
readonly from: Date;
|
|
12522
|
-
readonly to?: Date;
|
|
12523
|
-
}
|
|
13201
|
+
export { TimeRange }
|
|
12524
13202
|
|
|
12525
|
-
export
|
|
12526
|
-
readonly bucket: TimeBucket;
|
|
12527
|
-
}
|
|
13203
|
+
export { TimeseriesQuery }
|
|
12528
13204
|
|
|
12529
|
-
export
|
|
12530
|
-
readonly event: string;
|
|
12531
|
-
/** Property to group by (must be a string-valued property). */
|
|
12532
|
-
readonly groupBy: string;
|
|
12533
|
-
readonly metric: 'count' | {
|
|
12534
|
-
readonly sum: string;
|
|
12535
|
-
};
|
|
12536
|
-
readonly n: number;
|
|
12537
|
-
readonly range: TimeRange;
|
|
12538
|
-
readonly filter?: PropertyFilter;
|
|
12539
|
-
/** Tenant scope — injected by `useAnalytics()`; see {@link AggregateQuery.tenantId}. */
|
|
12540
|
-
readonly tenantId?: string | null;
|
|
12541
|
-
}
|
|
13205
|
+
export { TopNQuery }
|
|
12542
13206
|
|
|
12543
13207
|
/** A row a mutation wrote, carried to rule evaluation. `row` is the POST-WRITE
|
|
12544
13208
|
* state (insert result / update result). */
|
|
@@ -12990,7 +13654,11 @@ export declare class UndoStack<E> {
|
|
|
12990
13654
|
*/
|
|
12991
13655
|
export declare const undoSurfaceEnabled: (env?: Record<string, string | undefined>) => boolean;
|
|
12992
13656
|
|
|
12993
|
-
export declare
|
|
13657
|
+
export declare interface UnreadableColumn {
|
|
13658
|
+
readonly table: string;
|
|
13659
|
+
readonly column: string;
|
|
13660
|
+
readonly reason: string;
|
|
13661
|
+
}
|
|
12994
13662
|
|
|
12995
13663
|
/** One `source:` entry that resolves to no declared table. */
|
|
12996
13664
|
export declare interface UnresolvedSource {
|
|
@@ -13003,6 +13671,8 @@ export declare interface UnresolvedSource {
|
|
|
13003
13671
|
/** True when the name is in the `channel:` namespace: it named a reactivity
|
|
13004
13672
|
* channel nobody declared, which is a different repair from a stale table. */
|
|
13005
13673
|
readonly channel: boolean;
|
|
13674
|
+
/** Intentionally optional integration observation, retained in source. */
|
|
13675
|
+
readonly optional?: true;
|
|
13006
13676
|
}
|
|
13007
13677
|
|
|
13008
13678
|
/**
|
|
@@ -13014,6 +13684,7 @@ export declare interface UnresolvedSource {
|
|
|
13014
13684
|
export declare const unresolvedSources: (procedures: ReadonlyArray<{
|
|
13015
13685
|
readonly name: string;
|
|
13016
13686
|
readonly source: string | ReadonlyArray<string> | undefined;
|
|
13687
|
+
readonly optionalSource?: ReadonlyArray<string>;
|
|
13017
13688
|
}>, declared: ReadonlySet<string>) => ReadonlyArray<UnresolvedSource>;
|
|
13018
13689
|
|
|
13019
13690
|
/** Thrown at boot; the message is the whole point, so it names the path and the
|
|
@@ -13095,6 +13766,27 @@ export declare type VerificationDeclared<T> = T & {
|
|
|
13095
13766
|
readonly [WEBHOOK_VERIFICATION_PROPERTY]: WebhookVerification;
|
|
13096
13767
|
};
|
|
13097
13768
|
|
|
13769
|
+
/**
|
|
13770
|
+
* Check the keyring against the database and record what is new; make the
|
|
13771
|
+
* database's active key the keyring's. Throws {@link FieldKeyringRefusal} when
|
|
13772
|
+
* the keyring cannot read this database's data.
|
|
13773
|
+
*
|
|
13774
|
+
* `tables` are the app's declared tables: a few sealed values per
|
|
13775
|
+
* `.encrypted()` column are opened as a sample, and nothing else is read.
|
|
13776
|
+
*/
|
|
13777
|
+
export declare const verifyFieldKeyring: (store: DataStore, keyring: FieldKeyring, tables: Iterable<unknown>, holder?: FieldKeyHolder) => Promise<FieldKeyringVerification>;
|
|
13778
|
+
|
|
13779
|
+
/** Every location's envelopes, opened with `keyring` — after a re-key, a keyring with the active key alone. */
|
|
13780
|
+
export declare const verifySealedValues: (dialect: DialectId, keyring: FieldKeyring, declared: Iterable<unknown>) => Effect.Effect<{
|
|
13781
|
+
opened: number;
|
|
13782
|
+
unopened: {
|
|
13783
|
+
readonly table: string;
|
|
13784
|
+
readonly column: string;
|
|
13785
|
+
readonly count: number;
|
|
13786
|
+
}[];
|
|
13787
|
+
unreadable: UnreadableColumn[];
|
|
13788
|
+
}, SqlError, SqlClient.SqlClient>;
|
|
13789
|
+
|
|
13098
13790
|
/** The pure core of live revocation: given a subject + action + a row-set,
|
|
13099
13791
|
* return ONLY the rows the subject may still see. The reactive matcher calls
|
|
13100
13792
|
* this on a permission-changing write and diffs against the prior visible set;
|
|
@@ -13172,6 +13864,19 @@ export declare const _voltroConnectionsTable: TableLike;
|
|
|
13172
13864
|
|
|
13173
13865
|
export declare const _voltroCrdtVersionsTable: TableLike;
|
|
13174
13866
|
|
|
13867
|
+
/** The leases: which process holds which keys, and until when it counts —
|
|
13868
|
+
* rewritten by every heartbeat, so not reactive. */
|
|
13869
|
+
export declare const _voltroFieldKeyHoldersTable: TableLike;
|
|
13870
|
+
|
|
13871
|
+
/** The last count and the last re-key `voltro secret status` / `rekey` / `rotate`
|
|
13872
|
+
* ran — what the Governance panel shows as a rotation's progress, since the
|
|
13873
|
+
* app itself never scans every sealed value. Counts and locations, never a value. */
|
|
13874
|
+
export declare const _voltroFieldKeyReportsTable: TableLike;
|
|
13875
|
+
|
|
13876
|
+
/** Each field-encryption key id's state and canary — a framework table, created for every app.
|
|
13877
|
+
* Declared by its literal name: the data-transfer classification guard reads declarations. */
|
|
13878
|
+
export declare const _voltroFieldKeysTable: TableLike;
|
|
13879
|
+
|
|
13175
13880
|
/** `_voltro_rebac_tuples` — the relationship tuples `can()` reads. One row =
|
|
13176
13881
|
* "`subjectId` has `relation` on `<resourceType>:<resourceId>`". Grant by
|
|
13177
13882
|
* inserting; revoke by deleting (a delete is the live-revocation trigger). */
|
|
@@ -13341,6 +14046,14 @@ export declare type WhereOp = '=' | '!=' | '<>' | '>' | '>=' | '<' | '<=' | 'in'
|
|
|
13341
14046
|
|
|
13342
14047
|
export declare const withRowFilter: <R extends ServeRequestContext>(request: R) => Promise<R>;
|
|
13343
14048
|
|
|
14049
|
+
/**
|
|
14050
|
+
* Add the shared RPC auth pair once to an undecorated group. Authentication
|
|
14051
|
+
* runs before ConnectionInfo captures this call's verified credential lifetime.
|
|
14052
|
+
* Groups already carrying either middleware are refused: Effect preserves Set
|
|
14053
|
+
* insertion order, so appending a duplicate cannot repair an existing order.
|
|
14054
|
+
*/
|
|
14055
|
+
export declare const withRpcAuthMiddleware: <R extends Rpc.Any>(group: RpcGroup.RpcGroup<R>) => RpcGroup.RpcGroup<Rpc.AddMiddleware<Rpc.AddMiddleware<R, typeof ConnectionInfoMiddleware>, typeof AuthMiddleware>>;
|
|
14056
|
+
|
|
13344
14057
|
/**
|
|
13345
14058
|
* Run `body` against a request that carries a resolved row-filter scope.
|
|
13346
14059
|
*
|
|
@@ -13511,6 +14224,15 @@ export declare interface WorkflowEventTriggerResult {
|
|
|
13511
14224
|
readonly reason?: string;
|
|
13512
14225
|
}
|
|
13513
14226
|
|
|
14227
|
+
export declare interface WorkflowExecutionRefusal {
|
|
14228
|
+
readonly workflowName: string;
|
|
14229
|
+
readonly executionId: string;
|
|
14230
|
+
readonly payload: unknown;
|
|
14231
|
+
readonly cause: Cause.Cause<unknown>;
|
|
14232
|
+
/** Restored identity and host-owned placement; no resolved permissions. */
|
|
14233
|
+
readonly callerContext: WorkflowCallerContext;
|
|
14234
|
+
}
|
|
14235
|
+
|
|
13514
14236
|
export declare interface WorkflowFacadeOptions {
|
|
13515
14237
|
readonly cancelQueued?: (input: WorkflowQueuedControlTarget & {
|
|
13516
14238
|
readonly callerContext: WorkflowCallerContext | undefined;
|
|
@@ -13652,13 +14374,18 @@ export declare interface WorkflowLayerOptions<Context> {
|
|
|
13652
14374
|
* whose business logic said no.
|
|
13653
14375
|
*/
|
|
13654
14376
|
readonly resolveAuthority?: (identity: unknown) => Promise<unknown>;
|
|
14377
|
+
/** Record a known caller's refusal through the host's ordinary resident run
|
|
14378
|
+
* recorder. Called before application context/body construction. The failed
|
|
14379
|
+
* attempt stays failed, even if this hook completes successfully. Missing
|
|
14380
|
+
* caller identity cannot fabricate a tenant or a first-run record. */
|
|
14381
|
+
readonly onExecutionRefusal?: (refusal: WorkflowExecutionRefusal) => Effect.Effect<unknown, unknown, unknown>;
|
|
13655
14382
|
/**
|
|
13656
14383
|
* Told when an execution is refused BEFORE its body — the start context
|
|
13657
14384
|
* could not be resolved, the identity was missing, the authority or row
|
|
13658
14385
|
* filter resolver rejected. The engine already fails the attempt; what a
|
|
13659
|
-
* discarded start does NOT do is tell anyone
|
|
13660
|
-
* row yet
|
|
13661
|
-
* resident context was filed under another id died with a debug-level
|
|
14386
|
+
* discarded start does NOT do is tell anyone. A first start may have no
|
|
14387
|
+
* row yet; a resumed run may still have a running row. Measured: an
|
|
14388
|
+
* acknowledged start whose resident context was filed under another id died with a debug-level
|
|
13662
14389
|
* "Fiber terminated" and nothing else. Hosts wire this to an error log.
|
|
13663
14390
|
*/
|
|
13664
14391
|
readonly reportExecutionRefusal?: (refusal: {
|
|
@@ -13899,7 +14626,7 @@ export declare interface WorkflowsAppContext {
|
|
|
13899
14626
|
* execution, or never to run — read once, without waiting. A queued handle
|
|
13900
14627
|
* is resolved through its durable receipt, so the answer survives the
|
|
13901
14628
|
* process that recorded the handle. */
|
|
13902
|
-
readStart(handle: WorkflowRunHandle, options?:
|
|
14629
|
+
readStart(handle: WorkflowRunHandle, options?: WorkflowRunOptions): Promise<WorkflowStartObservation>;
|
|
13903
14630
|
/**
|
|
13904
14631
|
* Set on the facade a mutation TRANSACTION hands out: every start it records
|
|
13905
14632
|
* is provisional until the transaction commits, so nothing about a start can
|
|
@@ -14037,6 +14764,7 @@ export declare interface WorkflowStartOptions {
|
|
|
14037
14764
|
}
|
|
14038
14765
|
|
|
14039
14766
|
export declare interface WorkflowStartRunnerDeps {
|
|
14767
|
+
readonly outcomeOutbox?: MutationRunnerDeps['outcomeOutbox'];
|
|
14040
14768
|
/** Composed plugin workflow-interceptor (`interceptWorkflow`). */
|
|
14041
14769
|
readonly interceptor?: ServeRpcInterceptor;
|
|
14042
14770
|
readonly recordMetric?: MutationRunnerDeps['recordMetric'];
|
|
@@ -14081,6 +14809,10 @@ export declare const wrapStoreWithBootCodec: (underlying: DataStore, dialectId:
|
|
|
14081
14809
|
|
|
14082
14810
|
export declare const wrapStoreWithMixinBehaviour: (rawUnderlying: DataStore, ctx: StoreMiddlewareContext) => FluentStore;
|
|
14083
14811
|
|
|
14812
|
+
/** Writer errors propagate to the publisher, which owns retry/logging. A failed
|
|
14813
|
+
* history write must not be mistaken for a successfully recorded zero bucket. */
|
|
14814
|
+
export declare const writeApiRoleWorkloadBucket: (store: DataStore, bucket: ApiRoleWorkloadBucket) => Promise<void>;
|
|
14815
|
+
|
|
14084
14816
|
export declare const writeReplicaObservation: (store: DataStore, kind: ReplicaObservationKind, payload: unknown) => Promise<void>;
|
|
14085
14817
|
|
|
14086
14818
|
export { }
|