@voltro/runtime 0.86.0 → 0.88.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 +5484 -0
- package/README.md +43 -0
- package/THIRD-PARTY-NOTICES.md +1511 -276
- package/dist/aggregate.js +1 -2
- package/dist/aggregateExtrema.js +1 -2
- package/dist/aggregateIvm.js +1 -2
- package/dist/analyticsMirror.js +1 -2
- package/dist/analyticsSink.js +9 -16
- package/dist/apiKeyUsage.js +1 -2
- package/dist/apiKeys.js +83 -80
- package/dist/apiKeysWiring.js +1 -2
- package/dist/apiRoleBucketSampler.js +63 -0
- package/dist/apiRoleWorkloadHistory.js +55 -0
- package/dist/apiRoleWorkloadMetrics.js +77 -0
- package/dist/apiRoleWorkloadStorage.js +94 -0
- package/dist/approvalBuiltins.js +1 -2
- package/dist/approvals.js +68 -76
- package/dist/authMiddlewareLayer.js +8 -8
- package/dist/bindEvent.js +49 -30
- package/dist/boot-refusal.d.ts +10 -0
- package/dist/{bootRefusal.js → boot-refusal.js} +1 -2
- package/dist/bootListener.js +203 -47
- package/dist/bootStoreCodec.js +39 -39
- package/dist/businessRules.js +1 -2
- package/dist/changeClaimsTable.js +1 -2
- package/dist/circuitBreaker.js +1 -72
- package/dist/columnOnUpdate.js +1 -2
- package/dist/composeAnalytics.js +32 -12
- package/dist/computedQuery.js +1 -2
- package/dist/computedQueryCache.js +289 -0
- package/dist/connectionBuiltins.js +1 -2
- package/dist/connectionCredentials.js +1 -2
- package/dist/connectionState.js +1 -2
- package/dist/connectionVault.js +1 -2
- package/dist/connectionsFacade.js +33 -32
- package/dist/coordinatedSchedule.js +85 -80
- package/dist/crdtHistory.js +1 -2
- package/dist/crdtMerge.js +1 -2
- package/dist/crdtVersionsTable.js +1 -2
- package/dist/credentialBound.js +1 -2
- package/dist/crud.js +1 -2
- package/dist/dataStore.js +155 -123
- package/dist/dataloader.js +1 -2
- package/dist/declaredTablesGuard.js +3 -3
- package/dist/defineExecutor.js +1 -2
- package/dist/dependencyGraph.js +1 -2
- package/dist/devices.js +1 -2
- package/dist/devicesWiring.js +1 -2
- package/dist/dialectReplicationAdapter.js +1 -2
- package/dist/dispatcher.js +404 -330
- package/dist/effectStore.js +3 -4
- package/dist/engineClients.js +23 -0
- package/dist/eventBus.js +1 -2
- package/dist/eventPublish.js +1 -2
- package/dist/events.js +1 -2
- package/dist/expectation.js +1 -2
- package/dist/expectationEvaluator.js +2 -3
- package/dist/experiment.js +1 -2
- package/dist/experimentEvaluator.js +1 -2
- package/dist/externalizedTasks.js +20 -8
- package/dist/fieldCipher.js +110 -42
- package/dist/fieldKeyRegistry.js +294 -0
- package/dist/fieldKeyRekey.js +285 -0
- package/dist/fieldKeyScan.js +135 -0
- package/dist/fieldKeyring.js +76 -0
- package/dist/fingerprint.js +1 -2
- package/dist/finops.js +1 -2
- package/dist/finopsAccountant.js +1 -2
- package/dist/handlerBody.js +1 -2
- package/dist/healthProbes.js +1 -2
- package/dist/hot.d.ts +56 -0
- package/dist/hot.js +3 -0
- package/dist/hotDataStore.js +147 -0
- package/dist/hotDataStoreSnapshot.js +97 -0
- package/dist/hotDataStoreTables.js +17 -0
- package/dist/http-range.d.ts +53 -0
- package/dist/http-range.js +51 -0
- package/dist/httpClientSsrf.js +13 -39
- package/dist/httpClientTracing.js +13 -11
- package/dist/httpCompression.js +18 -19
- package/dist/httpInputStream.js +81 -0
- package/dist/httpKeepAlive.js +1 -2
- package/dist/httpRouteMounts.js +2 -2
- package/dist/idempotencyStore.js +93 -54
- package/dist/idleDetector.js +1 -2
- package/dist/index.d.ts +1185 -452
- package/dist/index.js +144 -134
- package/dist/insertRequiredColumns.js +1 -2
- package/dist/instanceMembership.js +1 -2
- package/dist/ivm.js +1 -2
- package/dist/kvDataStore.js +1 -2
- package/dist/kvFacade.js +24 -19
- package/dist/matcher.js +1 -2
- package/dist/memoryColumnDefaults.js +1 -2
- package/dist/memoryQueryJoins.js +17 -18
- package/dist/memorySetOperations.js +42 -0
- package/dist/metrics.js +39 -26
- package/dist/observability.js +2 -3
- package/dist/observedGraph.js +1 -2
- package/dist/originGuard.js +1 -2
- package/dist/outbox.js +2 -3
- package/dist/pluginRefRules.js +1 -2
- package/dist/policyGuardResolver.js +1 -2
- package/dist/preview.js +1 -2
- package/dist/projectedRows.js +1 -2
- package/dist/provenance.js +1 -2
- package/dist/rangeIndex.js +1 -2
- package/dist/rawReadScope.js +2 -3
- package/dist/reaction.js +1 -2
- package/dist/reactiveConfig.js +1 -2
- package/dist/readClassification.js +1 -2
- package/dist/readRecorder.js +36 -36
- package/dist/readScopePredicate.js +11 -0
- package/dist/rebac.js +1 -2
- package/dist/rebacInterceptor.js +1 -2
- package/dist/registry.js +1 -2
- package/dist/relevantFields.js +1 -2
- package/dist/replicaHealth.js +1 -2
- package/dist/replicaLocality.js +1 -2
- package/dist/replicaObservations.js +1 -2
- package/dist/replicaSelection.js +1 -2
- package/dist/replicatedDataStore.js +23 -6
- package/dist/requestLoader.js +1 -2
- package/dist/resumeCensus.js +1 -2
- package/dist/revalidation.js +1 -2
- package/dist/rowFilter.js +57 -41
- package/dist/rowStateBytes.js +1 -2
- package/dist/rpcBodyCap.js +1 -2
- package/dist/rpcConnections.js +9 -10
- package/dist/rpcDefectDiagnostics.js +1 -2
- package/dist/rpcServer.js +523 -451
- package/dist/rpcWorkloadAdmission.js +49 -0
- package/dist/runAsSystem.js +1 -2
- package/dist/rywPositionStore.js +83 -49
- package/dist/schedule.js +1 -2
- package/dist/scheduleBackfillRequests.js +1 -2
- package/dist/scheduleClaimsTable.js +1 -2
- package/dist/scheduleRunsTable.js +1 -2
- package/dist/scheduler.js +7 -3
- package/dist/schemaRegistry.js +1 -2
- package/dist/secretsResolver.js +1 -2
- package/dist/securityHeaders.js +1 -2
- package/dist/servePipeline.js +238 -154
- package/dist/serverOnlyAudit.js +1 -2
- package/dist/serverTracer.js +1 -2
- package/dist/serviceCredentials.js +1 -2
- package/dist/setReadScopes.js +27 -0
- package/dist/singleNodeOrchestrator.js +1 -2
- package/dist/snapshotValueCodec.js +45 -0
- package/dist/sourceResolution.js +35 -26
- package/dist/storeMiddleware.js +213 -212
- package/dist/storeQuery.js +1 -2
- package/dist/storeRead.js +1 -2
- package/dist/subscriber.js +2 -2
- package/dist/subscriptionOutbox.js +1 -2
- package/dist/subscriptionRegistry.js +1 -2
- package/dist/subscriptionResume.js +1 -2
- package/dist/subscriptionSocketMetrics.js +1 -2
- package/dist/systemSubject.js +1 -2
- package/dist/tenantScope.js +9 -22
- package/dist/tenantSelection.js +1 -2
- package/dist/timeline.js +1 -2
- package/dist/traceContext.js +1 -2
- package/dist/traceSink.js +1 -2
- package/dist/traceSpansTable.js +1 -2
- package/dist/traceparent.js +9 -21
- package/dist/transactionSubject.js +1 -2
- package/dist/trustedProxy.js +2 -3
- package/dist/undo.js +1 -2
- package/dist/undoBuiltins.js +1 -2
- package/dist/undoCapture.js +1 -2
- package/dist/undoLogTable.js +1 -2
- package/dist/upsertBinding.js +1 -2
- package/dist/wakeOrchestrator.js +1 -2
- package/dist/wakeRegistry.js +1 -2
- package/dist/wakeRouter.js +1 -2
- package/dist/wakeSupervisor.js +1 -2
- package/dist/wakeupsTable.js +1 -2
- package/dist/webSocketGatewayRuntime.js +112 -73
- package/dist/webhookVerification.js +1 -2
- package/dist/wireColumnStrip.js +1 -2
- package/dist/workflowReadBuiltins.js +1 -2
- package/dist/workflowRuntime.js +10 -11
- package/package.json +36 -17
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,9 +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';
|
|
33
52
|
import { EnqueueOptions } from '@voltro/protocol';
|
|
53
|
+
import { EventClientPolicy } from '@voltro/protocol';
|
|
34
54
|
import { EventDeliverySemantics } from '@voltro/protocol';
|
|
35
55
|
import { EventDescriptor } from '@voltro/protocol';
|
|
36
56
|
import { EventKeyInvalid } from '@voltro/protocol';
|
|
@@ -55,6 +75,7 @@ import { InferRow } from '@voltro/database';
|
|
|
55
75
|
import { InMemoryMetricExporter } from '@opentelemetry/sdk-metrics';
|
|
56
76
|
import { InMemorySpanExporter } from '@opentelemetry/sdk-trace-base';
|
|
57
77
|
import { InsertIgnoreResult } from '@voltro/database';
|
|
78
|
+
import { InsertManyOptions } from '@voltro/database';
|
|
58
79
|
import { InspectedStep } from '@voltro/workflow';
|
|
59
80
|
import { InspectedWorkflow } from '@voltro/workflow';
|
|
60
81
|
import { InspectStore } from '@voltro/workflow';
|
|
@@ -62,6 +83,7 @@ import { inspectWorkflow } from '@voltro/workflow';
|
|
|
62
83
|
import { isForeignKeyViolation } from '@voltro/database';
|
|
63
84
|
import { isQueryTimeout } from '@voltro/database';
|
|
64
85
|
import { Kv } from '@voltro/kv';
|
|
86
|
+
import { KvError } from '@voltro/kv';
|
|
65
87
|
import { KvStoreShape } from '@voltro/kv';
|
|
66
88
|
import { Layer } from 'effect';
|
|
67
89
|
import { listRetentionConflicts } from '@voltro/database';
|
|
@@ -69,9 +91,12 @@ import { listRetentions } from '@voltro/database';
|
|
|
69
91
|
import { Membership } from '@voltro/protocol';
|
|
70
92
|
import { Metric } from 'effect';
|
|
71
93
|
import { MetricReader } from '@opentelemetry/sdk-metrics';
|
|
94
|
+
import { MirrorVersion } from '@voltro/kv/analytics';
|
|
72
95
|
import { MutationIdempotencyScope } from '@voltro/protocol';
|
|
96
|
+
import { newTraceId } from '@voltro/shared';
|
|
73
97
|
import { NoRowFound } from '@voltro/protocol';
|
|
74
98
|
import { NoSuchResource } from '@voltro/protocol';
|
|
99
|
+
import { Option } from 'effect';
|
|
75
100
|
import { OutboxEnqueueFacade } from '@voltro/protocol';
|
|
76
101
|
import { OutboxHandlerContext } from '@voltro/protocol';
|
|
77
102
|
import { OutboxHandlerDefinition } from '@voltro/protocol';
|
|
@@ -81,13 +106,16 @@ import { PluginHttpRouteByteStream } from '@voltro/protocol';
|
|
|
81
106
|
import { PluginRefOrphanPolicy } from '@voltro/database';
|
|
82
107
|
import { Predicate } from '@voltro/database';
|
|
83
108
|
import { ProcedureWireError } from '@voltro/protocol';
|
|
109
|
+
import { PropertyFilter } from '@voltro/kv/analytics';
|
|
84
110
|
import { PublicApiSpec } from '@voltro/protocol';
|
|
85
111
|
import { Query } from '@voltro/database';
|
|
86
112
|
import { QueryDescriptor } from '@voltro/database';
|
|
87
|
-
import {
|
|
113
|
+
import { RedisPubSub } from '@voltro/kv/connection';
|
|
88
114
|
import { registerRetention } from '@voltro/database';
|
|
89
115
|
import { RequestedTenantRefused } from '@voltro/protocol';
|
|
90
116
|
import { ResourceMissing } from '@voltro/protocol';
|
|
117
|
+
import { RespClient } from '@voltro/kv/connection';
|
|
118
|
+
import { RespConnections } from '@voltro/kv/connection';
|
|
91
119
|
import { RestRouteDescriptor } from '@voltro/protocol/rest';
|
|
92
120
|
import { RetentionConflict } from '@voltro/database';
|
|
93
121
|
import { RetentionSource } from '@voltro/database';
|
|
@@ -99,6 +127,7 @@ import { RowPatch } from '@voltro/protocol';
|
|
|
99
127
|
import { Rpc } from 'effect/rpc';
|
|
100
128
|
import { RpcGroup } from 'effect/rpc';
|
|
101
129
|
import { RpcInterceptor } from '@voltro/protocol';
|
|
130
|
+
import { RpcReplayAuthorityBinding } from '@voltro/protocol';
|
|
102
131
|
import { RuleReadStore } from '@voltro/database';
|
|
103
132
|
import { Sampler } from '@opentelemetry/sdk-trace-base';
|
|
104
133
|
import { Schedule } from 'effect';
|
|
@@ -110,6 +139,9 @@ import { ServerResponse } from 'node:http';
|
|
|
110
139
|
import { SpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
111
140
|
import { spawn } from 'node:child_process';
|
|
112
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';
|
|
113
145
|
import { StoredTableShape } from '@voltro/database';
|
|
114
146
|
import { StoreError } from '@voltro/protocol';
|
|
115
147
|
import { StoreOperationFailed } from '@voltro/protocol';
|
|
@@ -130,6 +162,10 @@ import { TenantRowNotFound } from '@voltro/protocol';
|
|
|
130
162
|
import { TenantScopeViolation } from '@voltro/protocol';
|
|
131
163
|
import { tenantSelectionId } from '@voltro/database';
|
|
132
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';
|
|
133
169
|
import { Tracer } from 'effect';
|
|
134
170
|
import { Unauthenticated } from '@voltro/protocol';
|
|
135
171
|
import { UpsertOptions } from '@voltro/database';
|
|
@@ -172,6 +208,8 @@ declare const AccessDenied_base: Schema.Class<AccessDenied, Schema.TaggedStruct<
|
|
|
172
208
|
export declare const actingUserId: (subject: StoreMiddlewareContext["subject"]) => string | null;
|
|
173
209
|
|
|
174
210
|
export declare interface ActionRunnerDeps {
|
|
211
|
+
/** Measures only the synchronous executor entry, never an awaited result. */
|
|
212
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
175
213
|
readonly outcomeOutbox?: MutationRunnerDeps['outcomeOutbox'];
|
|
176
214
|
/** Build the per-call `AppContext` — NO transactional tx (actions do
|
|
177
215
|
* external I/O and run outside a txn deliberately). */
|
|
@@ -183,8 +221,23 @@ export declare interface ActionRunnerDeps {
|
|
|
183
221
|
readonly recordMetric?: MutationRunnerDeps['recordMetric'];
|
|
184
222
|
/** See {@link MutationRunnerDeps.defaultDeny} — same flag, same refusal. */
|
|
185
223
|
readonly defaultDeny?: boolean;
|
|
224
|
+
/** See {@link MutationRunnerDeps.settleCacheInvalidations} — an action's
|
|
225
|
+
* writes are the writer's too. */
|
|
226
|
+
readonly settleCacheInvalidations?: () => Promise<void>;
|
|
186
227
|
}
|
|
187
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
|
+
|
|
188
241
|
/**
|
|
189
242
|
* Live activity counters the runtime exposes to the idle detector. All
|
|
190
243
|
* return the CURRENT count (0 = quiescent on that axis).
|
|
@@ -455,20 +508,7 @@ declare const AggregateNotFound_base: Schema.Class<AggregateNotFound, Schema.Tag
|
|
|
455
508
|
readonly name: Schema.String;
|
|
456
509
|
}>, YieldableError>;
|
|
457
510
|
|
|
458
|
-
export
|
|
459
|
-
readonly event: string;
|
|
460
|
-
readonly filter?: PropertyFilter;
|
|
461
|
-
readonly metric: AnalyticsMetric;
|
|
462
|
-
readonly range: TimeRange;
|
|
463
|
-
/**
|
|
464
|
-
* Restrict the read to one tenant's events. `useAnalytics()` injects the
|
|
465
|
-
* caller's `subject.tenantId` automatically, so handler code never sets
|
|
466
|
-
* this; a sink that honours it (e.g. analytics-postgres) then AND-filters
|
|
467
|
-
* by tenant so a query can't read across tenants. `null`/absent = unscoped
|
|
468
|
-
* (system/cross-tenant read).
|
|
469
|
-
*/
|
|
470
|
-
readonly tenantId?: string | null;
|
|
471
|
-
}
|
|
511
|
+
export { AggregateQuery }
|
|
472
512
|
|
|
473
513
|
export declare interface AggregateReadOptions {
|
|
474
514
|
/**
|
|
@@ -477,11 +517,14 @@ export declare interface AggregateReadOptions {
|
|
|
477
517
|
* Without it an aggregate can only ever be "the one global roll-up", so every
|
|
478
518
|
* tenant-/team-/year-scoped roll-up (most real ones) has to stay client-side.
|
|
479
519
|
* A row matches when EVERY entry matches: a scalar compares by strict
|
|
480
|
-
* 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).
|
|
481
523
|
*
|
|
482
524
|
* ```ts
|
|
483
525
|
* yield* handle.read({ where: { teamId, year: 2026 } })
|
|
484
526
|
* yield* handle.read({ where: { status: ['open', 'blocked'] } })
|
|
527
|
+
* yield* handle.read({ where: { teamId, day: { gte: from, lte: to } } })
|
|
485
528
|
* ```
|
|
486
529
|
*
|
|
487
530
|
* Deliberately DATA, not a predicate function: it stays serializable, so the
|
|
@@ -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
|
-
}
|
|
564
|
-
|
|
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>;
|
|
603
|
+
export { AnalyticsBucket }
|
|
578
604
|
|
|
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
|
|
@@ -1510,6 +1425,18 @@ export declare const assertWebhookRoutesDeclareVerification: (routes: ReadonlyMa
|
|
|
1510
1425
|
readonly handle: unknown;
|
|
1511
1426
|
}> | undefined) => void;
|
|
1512
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
|
+
|
|
1513
1440
|
/**
|
|
1514
1441
|
* Assign a subject to a variant — STABLE (same subject ⇒ same variant, always)
|
|
1515
1442
|
* and BALANCED (proportions converge to the weights over many subjects). The
|
|
@@ -1760,6 +1687,13 @@ export declare interface BindBootListenerOptions {
|
|
|
1760
1687
|
readonly host?: string;
|
|
1761
1688
|
/** The app's `health` block — the prefix and the app's own answers. */
|
|
1762
1689
|
readonly health?: HealthConfigInput;
|
|
1690
|
+
/** How long a request that arrives while booting waits for the app before
|
|
1691
|
+
* it is answered 503. Absent → `VOLTRO_BOOT_HOLD_MS` (default 30 s); `0`
|
|
1692
|
+
* answers 503 at once. */
|
|
1693
|
+
readonly holdMs?: number;
|
|
1694
|
+
/** How many requests may wait at once; the next one is answered 503.
|
|
1695
|
+
* Absent → `MAX_HELD`. */
|
|
1696
|
+
readonly maxHeld?: number;
|
|
1763
1697
|
/** Deterministic "now" for `elapsedMs`; tests inject. */
|
|
1764
1698
|
readonly now?: () => number;
|
|
1765
1699
|
readonly log?: {
|
|
@@ -1820,9 +1754,12 @@ export declare interface BindEventInput {
|
|
|
1820
1754
|
* this bridge must treat it as "no check", not as a guard.
|
|
1821
1755
|
*/
|
|
1822
1756
|
readonly guards?: DeclaredAccess<unknown> | undefined;
|
|
1757
|
+
/** The descriptor requirement and captured app policy must match exactly. */
|
|
1758
|
+
readonly requiredClientPolicy?: string;
|
|
1759
|
+
readonly clientPolicy?: EventClientPolicy;
|
|
1823
1760
|
}
|
|
1824
1761
|
|
|
1825
|
-
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?:
|
|
1762
|
+
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,
|
|
1826
1763
|
/**
|
|
1827
1764
|
* This procedure's DECLARED error union (`descriptor.error`).
|
|
1828
1765
|
*
|
|
@@ -1874,7 +1811,12 @@ guards?: ReadonlyArray<unknown> | undefined,
|
|
|
1874
1811
|
* (`{ scope: 'x:read', from: 'id' }`) can see which resource was asked for.
|
|
1875
1812
|
* Passed explicitly rather than read off RuntimeContext, which does not
|
|
1876
1813
|
* carry it. */
|
|
1877
|
-
guardInput?: unknown
|
|
1814
|
+
guardInput?: unknown,
|
|
1815
|
+
/** Plugin admission wraps construction once; element guards remain live. */
|
|
1816
|
+
admission?: {
|
|
1817
|
+
readonly tag: string;
|
|
1818
|
+
readonly interceptor?: ServeRpcInterceptor | undefined;
|
|
1819
|
+
}) => Stream.Stream<Element, Err, SubjectService | ConnectionInfo>;
|
|
1878
1820
|
|
|
1879
1821
|
/**
|
|
1880
1822
|
* Build a `Stream<SubscriptionEvent<T>>` that an effect/rpc streaming
|
|
@@ -1944,6 +1886,14 @@ export declare const bindSubscriptionUntyped: (descriptor: QueryDescriptor, disp
|
|
|
1944
1886
|
|
|
1945
1887
|
export declare const BOOT_REFUSAL_NAME = "VoltroBootRefusal";
|
|
1946
1888
|
|
|
1889
|
+
/**
|
|
1890
|
+
* The hold window, from `VOLTRO_BOOT_HOLD_MS` (milliseconds), clamped to
|
|
1891
|
+
* `[0, 5 min]`. `0` turns the hold off — every request that arrives while
|
|
1892
|
+
* booting is answered 503 at once. A non-numeric or negative value falls back
|
|
1893
|
+
* to the default rather than silently disabling the hold.
|
|
1894
|
+
*/
|
|
1895
|
+
export declare const bootHoldMsFromEnv: () => number;
|
|
1896
|
+
|
|
1947
1897
|
export declare interface BootListener {
|
|
1948
1898
|
/** The bound server — the ONE socket this process serves on. */
|
|
1949
1899
|
readonly server: Server;
|
|
@@ -1954,13 +1904,26 @@ export declare interface BootListener {
|
|
|
1954
1904
|
readonly set: (patch: Partial<Omit<BootState, 'startedAt'>>) => void;
|
|
1955
1905
|
/** Boot complete — the phase alone, never the dependency ping. */
|
|
1956
1906
|
readonly isReady: () => boolean;
|
|
1907
|
+
/** Requests waiting for the app right now (also `held` on the startup probe). */
|
|
1908
|
+
readonly held: number;
|
|
1957
1909
|
/** Hand over the real handlers. Consulted only once the phase is `ready`
|
|
1958
|
-
* (or `draining`); until then every non-probe request
|
|
1910
|
+
* (or `draining`); until then every non-probe request is held, and the
|
|
1911
|
+
* held ones reach these handlers in arrival order once both are true. */
|
|
1959
1912
|
readonly delegate: (to: BootListenerDelegate) => void;
|
|
1960
1913
|
/** The dependency probe readiness consults once ready — a DB `SELECT 1`.
|
|
1961
1914
|
* Installed by the boot path when its store exists, which is after the
|
|
1962
1915
|
* bind; an app-declared `health.readiness` replaces the whole check. */
|
|
1963
1916
|
readonly setDependencyPing: (ping: () => Promise<boolean>) => void;
|
|
1917
|
+
/** Required local runtime conditions, independent of app dependency policy.
|
|
1918
|
+
* Checks must be synchronous and cheap. Release removes only this registration. */
|
|
1919
|
+
/** Enable structured API health using captured role/workload identities. */
|
|
1920
|
+
readonly setRoleHealth: (identity: {
|
|
1921
|
+
readonly roles: ReadonlyArray<string>;
|
|
1922
|
+
readonly workloads: ReadonlyArray<string>;
|
|
1923
|
+
}) => void;
|
|
1924
|
+
readonly addReadinessGate: (name: string, check: () => boolean) => () => void;
|
|
1925
|
+
/** Required local progress conditions. App liveness cannot bypass these gates. */
|
|
1926
|
+
readonly addLivenessGate: (name: string, check: () => boolean) => () => void;
|
|
1964
1927
|
/** Close the socket. Resolves once node reports the listener closed. */
|
|
1965
1928
|
readonly close: () => Promise<void>;
|
|
1966
1929
|
}
|
|
@@ -2055,6 +2018,40 @@ export declare const buildTracingLayer: (options?: TracingOptions) => Promise<Tr
|
|
|
2055
2018
|
* hit on every read. `now` injectable for tests. */
|
|
2056
2019
|
export declare const cachedBackend: (backend: SecretsBackend, ttlMs?: number, now?: () => number) => SecretsBackend;
|
|
2057
2020
|
|
|
2021
|
+
export declare const cachedComputedCall: (args: CachedComputedCallArgs) => Effect.Effect<CachedComputedResult, unknown, never>;
|
|
2022
|
+
|
|
2023
|
+
declare interface CachedComputedCallArgs {
|
|
2024
|
+
readonly cache: ComputedQueryCacheDeps;
|
|
2025
|
+
readonly policy: ComputedQueryCachePolicy;
|
|
2026
|
+
readonly key: string;
|
|
2027
|
+
readonly name: string;
|
|
2028
|
+
readonly sources: ReadonlyArray<string>;
|
|
2029
|
+
readonly output: Schema.Top | undefined;
|
|
2030
|
+
readonly subject: object;
|
|
2031
|
+
readonly rowFilter: RowFilterScope | undefined;
|
|
2032
|
+
readonly ctx: object;
|
|
2033
|
+
readonly signal?: AbortSignal;
|
|
2034
|
+
/** Run the handler to a value against the OBSERVED context and subject. */
|
|
2035
|
+
readonly execute: (observedCtx: object, observedSubject: object) => Promise<unknown>;
|
|
2036
|
+
/** The handler returned a descriptor — the snapshot cache owns that query. */
|
|
2037
|
+
readonly onDescriptor: () => void;
|
|
2038
|
+
readonly isDescriptor: (value: unknown) => boolean;
|
|
2039
|
+
readonly unwrap: (value: unknown) => unknown;
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
/**
|
|
2043
|
+
* Serve one computed call through the cache: a hit, or the handler run under
|
|
2044
|
+
* observation and its result kept — or not — by `decideComputedStore`. The
|
|
2045
|
+
* caller authorizes BEFORE and re-authorizes the delivered value AFTER; this
|
|
2046
|
+
* function only decides what the cache does.
|
|
2047
|
+
*/
|
|
2048
|
+
/** A cached call's value, and the tables a live query built from it must also
|
|
2049
|
+
* recompute on (read by the handler, not named in `source:`). */
|
|
2050
|
+
declare interface CachedComputedResult {
|
|
2051
|
+
readonly value: unknown;
|
|
2052
|
+
readonly dependencies: ReadonlyArray<string>;
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2058
2055
|
/** One leak: a query caching ONE entry across every caller while reading a
|
|
2059
2056
|
* table whose rows are scoped per tenant. */
|
|
2060
2057
|
export declare interface CacheScopeLeak {
|
|
@@ -2127,15 +2124,7 @@ export declare interface CandidateShape {
|
|
|
2127
2124
|
export declare const canonicalInputKey: (input: unknown) => string;
|
|
2128
2125
|
|
|
2129
2126
|
/* Excluded from this release type: canonicalize */
|
|
2130
|
-
|
|
2131
|
-
/**
|
|
2132
|
-
* Canonical JSON — object keys sorted recursively, so two structurally equal
|
|
2133
|
-
* inputs that differ only in key order digest identically. A retry from a
|
|
2134
|
-
* different client build must not mint a second approval.
|
|
2135
|
-
* Preserve own JSON fields such as `__proto__`; a prototype setter must never
|
|
2136
|
-
* discard part of the content that an approval identity binds.
|
|
2137
|
-
*/
|
|
2138
|
-
export declare const canonicalJson: (value: unknown) => string;
|
|
2127
|
+
export { canonicalJson }
|
|
2139
2128
|
|
|
2140
2129
|
export { CaughtUpVerdict }
|
|
2141
2130
|
|
|
@@ -2155,6 +2144,29 @@ export declare interface CdcDelta {
|
|
|
2155
2144
|
readonly new?: Row_3 | null;
|
|
2156
2145
|
}
|
|
2157
2146
|
|
|
2147
|
+
/** What a cell's envelopes can be bound to. */
|
|
2148
|
+
export declare interface CellContext {
|
|
2149
|
+
readonly table: string;
|
|
2150
|
+
readonly column: string;
|
|
2151
|
+
/** The cell's row: its primary key, and every other column (for ids a copy carries). */
|
|
2152
|
+
readonly rowId: unknown;
|
|
2153
|
+
readonly row: Readonly<Record<string, unknown>>;
|
|
2154
|
+
/** Every `.encrypted()` column the app declares, by table. */
|
|
2155
|
+
readonly declared: ReadonlyMap<string, ReadonlySet<string>>;
|
|
2156
|
+
/** Declared renames (`declaredRenames`): the old names a value of this cell may still be bound to. */
|
|
2157
|
+
readonly renames?: ReadonlyMap<string, DeclaredRename>;
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
/** What a cell's re-key did. */
|
|
2161
|
+
export declare interface CellRekey {
|
|
2162
|
+
/** The cell's new text — equal to the input when nothing changed. */
|
|
2163
|
+
readonly text: string;
|
|
2164
|
+
readonly rekeyed: number;
|
|
2165
|
+
readonly current: number;
|
|
2166
|
+
/** Envelopes no candidate address opened — left as they are. */
|
|
2167
|
+
readonly unresolved: number;
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2158
2170
|
export { ChangeEvent }
|
|
2159
2171
|
|
|
2160
2172
|
/** A mutation invocation's full change-set — the unit of undo. */
|
|
@@ -2170,50 +2182,24 @@ export declare interface ChangeSet {
|
|
|
2170
2182
|
readonly crossesAction?: boolean;
|
|
2171
2183
|
}
|
|
2172
2184
|
|
|
2173
|
-
export declare interface CircuitBreaker {
|
|
2174
|
-
/** Run an effect through the breaker. OPEN ⇒ fails fast with CircuitOpen. */
|
|
2175
|
-
<A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E | CircuitOpen, R>;
|
|
2176
|
-
/** Current state — reads the Ref. */
|
|
2177
|
-
readonly state: Effect.Effect<CircuitState>;
|
|
2178
|
-
/** Force the breaker back to closed (clears counters). */
|
|
2179
|
-
readonly reset: Effect.Effect<void>;
|
|
2180
|
-
}
|
|
2181
|
-
|
|
2182
|
-
export declare const CircuitBreaker: {
|
|
2183
|
-
/** Construct a breaker. Effect-returning because it allocates a Ref. */
|
|
2184
|
-
readonly make: (options: CircuitBreakerOptions) => Effect.Effect<CircuitBreaker>;
|
|
2185
|
-
};
|
|
2186
|
-
|
|
2187
|
-
export declare interface CircuitBreakerOptions {
|
|
2188
|
-
/** Consecutive failures before the breaker opens. */
|
|
2189
|
-
readonly failureThreshold: number;
|
|
2190
|
-
/** Wait before transitioning open → half-open (Duration or string). */
|
|
2191
|
-
readonly resetTimeout: Duration.Input;
|
|
2192
|
-
/** Successes required in half-open before closing again. Default 1. */
|
|
2193
|
-
readonly halfOpenSuccessThreshold?: number;
|
|
2194
|
-
/** Predicate: does this error count toward the threshold? Default: all
|
|
2195
|
-
* typed failures count. Interruptions NEVER count (they're not a
|
|
2196
|
-
* downstream failure — the caller went away). */
|
|
2197
|
-
readonly isFailure?: (error: unknown) => boolean;
|
|
2198
|
-
/** Optional name for inspect / metrics + dashboard surfacing. */
|
|
2199
|
-
readonly name?: string;
|
|
2200
|
-
}
|
|
2201
|
-
|
|
2202
2185
|
/**
|
|
2203
|
-
*
|
|
2204
|
-
*
|
|
2186
|
+
* The same checks as {@link verifyFieldKeyring}, writing nothing — for a dry
|
|
2187
|
+
* run. Answers which key the database records as active (`undefined` before
|
|
2188
|
+
* the first boot recorded any) and which one would wait for the fleet.
|
|
2205
2189
|
*/
|
|
2206
|
-
export declare
|
|
2207
|
-
|
|
2190
|
+
export declare const checkFieldKeyring: (store: DataStore, keyring: FieldKeyring, tables: Iterable<unknown>) => Promise<{
|
|
2191
|
+
readonly active: string | undefined;
|
|
2192
|
+
readonly requested?: string;
|
|
2193
|
+
readonly notes: ReadonlyArray<string>;
|
|
2194
|
+
}>;
|
|
2208
2195
|
|
|
2209
|
-
|
|
2210
|
-
/** Breaker name (the `name` option, or `'circuit'` when unnamed). */
|
|
2211
|
-
readonly name: Schema.String;
|
|
2212
|
-
/** Best-effort ms until the breaker next admits a probe call. */
|
|
2213
|
-
readonly retryAfterMs: Schema.Number;
|
|
2214
|
-
}>, Cause.YieldableError>;
|
|
2196
|
+
export { CircuitBreaker }
|
|
2215
2197
|
|
|
2216
|
-
export
|
|
2198
|
+
export { CircuitBreakerOptions }
|
|
2199
|
+
|
|
2200
|
+
export { CircuitOpen }
|
|
2201
|
+
|
|
2202
|
+
export { CircuitState }
|
|
2217
2203
|
|
|
2218
2204
|
/** How many bucket widths of predecessors a won claim leaves behind. */
|
|
2219
2205
|
export declare const CLAIM_RETENTION_BUCKETS = 64;
|
|
@@ -2386,7 +2372,7 @@ export declare interface CompleteOAuthResult {
|
|
|
2386
2372
|
/**
|
|
2387
2373
|
* Combine multiple analytics specs into one composite spec at
|
|
2388
2374
|
* app.config.ts time. The framework's boot path materialises each
|
|
2389
|
-
* child spec
|
|
2375
|
+
* child spec with its declared SQL dependency and wires them through
|
|
2390
2376
|
* `composeAnalyticsSinks` so they behave as one logical sink.
|
|
2391
2377
|
*
|
|
2392
2378
|
* `track()` fans out to every child; reads route to the first child
|
|
@@ -2394,12 +2380,12 @@ export declare interface CompleteOAuthResult {
|
|
|
2394
2380
|
*
|
|
2395
2381
|
* Tables contributed by ANY child get merged. `initialize` effects
|
|
2396
2382
|
* run sequentially in declaration order; `dispose` effects (teardown)
|
|
2397
|
-
*
|
|
2383
|
+
* await each child in reverse order — only present on the
|
|
2398
2384
|
* composite when at least one child does.
|
|
2399
2385
|
*
|
|
2400
2386
|
* analytics: composeAnalytics([
|
|
2401
2387
|
* postgresAnalytics(), // primary: handles reads
|
|
2402
|
-
* posthogAnalytics({ apiKey:
|
|
2388
|
+
* posthogAnalytics({ apiKey: process.env.POSTHOG_API_KEY! }),
|
|
2403
2389
|
* ])
|
|
2404
2390
|
*/
|
|
2405
2391
|
export declare const composeAnalytics: (specs: ReadonlyArray<AnalyticsSinkSpec>) => AnalyticsSinkSpec;
|
|
@@ -2443,6 +2429,44 @@ export declare interface CompressionOptions {
|
|
|
2443
2429
|
readonly minBytes?: number;
|
|
2444
2430
|
}
|
|
2445
2431
|
|
|
2432
|
+
/** Why a call is not looked up at all. */
|
|
2433
|
+
declare type ComputedCacheBypass = 'input-not-encodable' | 'no-tenant' | 'anonymous-subject' | 'subject-not-encodable';
|
|
2434
|
+
|
|
2435
|
+
/**
|
|
2436
|
+
* The entry one call belongs to — or why it has none.
|
|
2437
|
+
*
|
|
2438
|
+
* Every part is something a different answer could hang on: the query and the
|
|
2439
|
+
* build that runs it (a redis cache outlives a deploy, and two releases share
|
|
2440
|
+
* it during a rolling one), the output shape, the ENCODED input (so a `Date`,
|
|
2441
|
+
* a `bigint` or a branded id keys by its wire form, and two spellings of one
|
|
2442
|
+
* input share an entry), the scope's caller part, and the row-filter
|
|
2443
|
+
* visibility the caller's reads of the declared tables resolve to.
|
|
2444
|
+
*/
|
|
2445
|
+
export declare const computedCacheKey: (args: ComputedCacheKeyInput) => {
|
|
2446
|
+
readonly key: string;
|
|
2447
|
+
} | {
|
|
2448
|
+
readonly bypass: ComputedCacheBypass;
|
|
2449
|
+
};
|
|
2450
|
+
|
|
2451
|
+
declare interface ComputedCacheKeyInput {
|
|
2452
|
+
readonly name: string;
|
|
2453
|
+
/** The running build — see `codeIdentity` on the boot side. */
|
|
2454
|
+
readonly codeIdentity: string;
|
|
2455
|
+
readonly output: Schema.Top | undefined;
|
|
2456
|
+
readonly input: Schema.Top | undefined;
|
|
2457
|
+
readonly decodedInput: unknown;
|
|
2458
|
+
readonly scope: ComputedCacheScope;
|
|
2459
|
+
readonly subject: {
|
|
2460
|
+
readonly id?: string | null | undefined;
|
|
2461
|
+
readonly type?: string | undefined;
|
|
2462
|
+
readonly tenantId?: string | null | undefined;
|
|
2463
|
+
};
|
|
2464
|
+
readonly rowFilter: RowFilterScope | undefined;
|
|
2465
|
+
readonly declaredSources: ReadonlyArray<string>;
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
declare type ComputedCacheScope = 'subject' | 'tenant' | 'global';
|
|
2469
|
+
|
|
2446
2470
|
declare interface ComputedQuery {
|
|
2447
2471
|
readonly __voltroComputed: true;
|
|
2448
2472
|
/** The initial computed value — emitted verbatim as the first snapshot. */
|
|
@@ -2456,6 +2480,56 @@ declare interface ComputedQuery {
|
|
|
2456
2480
|
readonly recompute: () => Promise<unknown>;
|
|
2457
2481
|
}
|
|
2458
2482
|
|
|
2483
|
+
/** Is capture on? The request store builder wraps its store when it is. */
|
|
2484
|
+
export declare const computedQueryCacheCaptureInstalled: () => boolean;
|
|
2485
|
+
|
|
2486
|
+
/**
|
|
2487
|
+
* The cache a COMPUTED query's handler invocation is served through. Both boot
|
|
2488
|
+
* paths build it over the app's `Cache` (`wrapDynamic`), and so does
|
|
2489
|
+
* `@voltro/testing`'s `invoke`; absent ⇒ computed queries are never cached.
|
|
2490
|
+
*/
|
|
2491
|
+
export declare interface ComputedQueryCacheDeps {
|
|
2492
|
+
readonly wrapDynamic: <A, E>(key: string, options: {
|
|
2493
|
+
readonly ttlMs: number;
|
|
2494
|
+
readonly swrMs?: number | undefined;
|
|
2495
|
+
readonly leaseMs?: number | undefined;
|
|
2496
|
+
readonly label: string;
|
|
2497
|
+
}, compute: Effect.Effect<{
|
|
2498
|
+
readonly value: A;
|
|
2499
|
+
readonly store?: {
|
|
2500
|
+
readonly stored: unknown;
|
|
2501
|
+
readonly tags: ReadonlyArray<string>;
|
|
2502
|
+
} | undefined;
|
|
2503
|
+
readonly notApplicable?: boolean | undefined;
|
|
2504
|
+
}, E, never>, read: (stored: unknown) => Effect.Effect<Option.Option<A>>) => Effect.Effect<{
|
|
2505
|
+
readonly value: A;
|
|
2506
|
+
readonly served: 'hit' | 'stale' | 'miss';
|
|
2507
|
+
}, E, never>;
|
|
2508
|
+
/** Parse the declared `cache:` (same parser as the descriptor path). */
|
|
2509
|
+
readonly policyFor: (cache: {
|
|
2510
|
+
readonly ttl: number | string;
|
|
2511
|
+
readonly swr?: number | string | undefined;
|
|
2512
|
+
readonly scope: ComputedCacheScope;
|
|
2513
|
+
readonly volatile?: boolean | undefined;
|
|
2514
|
+
}) => ComputedQueryCachePolicy | undefined;
|
|
2515
|
+
/** The running build — part of every key, so a deploy never reads another
|
|
2516
|
+
* release's entries out of a shared cache. */
|
|
2517
|
+
readonly codeIdentity: string;
|
|
2518
|
+
readonly maxEntryBytes: number;
|
|
2519
|
+
/** Cluster single-flight lease, when the backend supports one. */
|
|
2520
|
+
readonly leaseMs?: number | undefined;
|
|
2521
|
+
/** Once-per-(query, reason) notice that a result was not kept. */
|
|
2522
|
+
readonly notice: (query: string, reason: string, message: string) => void;
|
|
2523
|
+
}
|
|
2524
|
+
|
|
2525
|
+
/** A computed query's resolved cache policy — ms, parsed by the boot path. */
|
|
2526
|
+
export declare interface ComputedQueryCachePolicy {
|
|
2527
|
+
readonly ttlMs: number;
|
|
2528
|
+
readonly swrMs: number | undefined;
|
|
2529
|
+
readonly scope: ComputedCacheScope;
|
|
2530
|
+
readonly volatile: boolean;
|
|
2531
|
+
}
|
|
2532
|
+
|
|
2459
2533
|
export declare const CONNECTION_GRANTS_TABLE = "_voltro_connection_grants";
|
|
2460
2534
|
|
|
2461
2535
|
/** What a declaration can learn about the account it just connected. Optional
|
|
@@ -2588,6 +2662,7 @@ export { ConstraintViolation }
|
|
|
2588
2662
|
export declare type CoordinatedEffect = () => void | CoordinatedTickOutcome | Promise<void | CoordinatedTickOutcome>;
|
|
2589
2663
|
|
|
2590
2664
|
export declare interface CoordinatedScheduleDeps {
|
|
2665
|
+
readonly externalTasks?: ExternalizedTaskRegistry;
|
|
2591
2666
|
/** The exactly-once gate. `singleCoordinator` for one-process
|
|
2592
2667
|
* deployments; `makeAdvisoryLockCoordinator(store, replicaId)` for
|
|
2593
2668
|
* multi-instance SQL stores. Injected so this stays testable with a
|
|
@@ -2678,8 +2753,9 @@ export declare interface CoordinatedScheduleDiagnostics {
|
|
|
2678
2753
|
}
|
|
2679
2754
|
|
|
2680
2755
|
export declare interface CoordinatedScheduleHandle {
|
|
2681
|
-
/** Stop the
|
|
2682
|
-
|
|
2756
|
+
/** Stop admission immediately; await the returned completion before releasing
|
|
2757
|
+
* storage. Includes timer and external-trigger claims/effects. Idempotent. */
|
|
2758
|
+
readonly stop: () => void | Promise<void>;
|
|
2683
2759
|
/** The task name (for logging / dedup diagnostics). */
|
|
2684
2760
|
readonly name: string;
|
|
2685
2761
|
/**
|
|
@@ -3381,6 +3457,9 @@ export declare const decideApprovalInvocation: (input: {
|
|
|
3381
3457
|
readonly status: "approved" | "rejected";
|
|
3382
3458
|
}>;
|
|
3383
3459
|
|
|
3460
|
+
/** The app's `.encrypted()` columns, by table. */
|
|
3461
|
+
export declare const declaredEncryptedColumns: (declared: Iterable<unknown>) => ReadonlyMap<string, ReadonlySet<string>>;
|
|
3462
|
+
|
|
3384
3463
|
/**
|
|
3385
3464
|
* `unknown` when the executor's failures are all declared; otherwise a type the
|
|
3386
3465
|
* handler cannot satisfy, whose one property spells out the undeclared tag(s)
|
|
@@ -3393,6 +3472,27 @@ UndeclaredErrorTags<D, R>
|
|
|
3393
3472
|
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)`;
|
|
3394
3473
|
};
|
|
3395
3474
|
|
|
3475
|
+
/** A declared rename of a table with sealed columns: the names its values may still be bound to. */
|
|
3476
|
+
export declare interface DeclaredRename {
|
|
3477
|
+
readonly previousTable?: string;
|
|
3478
|
+
/** New column name → the name it was renamed from. */
|
|
3479
|
+
readonly columns: ReadonlyMap<string, string>;
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3482
|
+
/**
|
|
3483
|
+
* The renames the app declares on tables with `.encrypted()` columns —
|
|
3484
|
+
* `table('new').renamedFrom('old')`, a column's `.renamedFrom('old')`. A rename
|
|
3485
|
+
* is catalog-only, so the rows keep values bound to the old names; the re-key
|
|
3486
|
+
* opens them there and seals them under the new ones.
|
|
3487
|
+
*/
|
|
3488
|
+
export declare const declaredRenames: (declared: Iterable<unknown>) => ReadonlyMap<string, DeclaredRename>;
|
|
3489
|
+
|
|
3490
|
+
/** Decode a stored snapshot; `undefined` for anything this version did not
|
|
3491
|
+
* write (an entry from another build reads as a miss). */
|
|
3492
|
+
export declare const decodeSnapshotValue: (stored: unknown) => {
|
|
3493
|
+
readonly value: unknown;
|
|
3494
|
+
} | undefined;
|
|
3495
|
+
|
|
3396
3496
|
/**
|
|
3397
3497
|
* Decrypt a value produced by `encryptField` or by an `.encrypted()` column —
|
|
3398
3498
|
* one encoding, so that sentence is now true in both directions.
|
|
@@ -3958,7 +4058,13 @@ export declare class Dispatcher {
|
|
|
3958
4058
|
private readonly subscriptionRegistry;
|
|
3959
4059
|
private readonly matcher;
|
|
3960
4060
|
private readonly subscriptions;
|
|
3961
|
-
private
|
|
4061
|
+
private unsubscribeChange;
|
|
4062
|
+
private closed;
|
|
4063
|
+
private readonly operations;
|
|
4064
|
+
/** Register synchronously, before user code or the first await can run. */
|
|
4065
|
+
private beginOperation;
|
|
4066
|
+
/** Includes pending initial reads, not only already-visible subscriptions. */
|
|
4067
|
+
private readonly interests;
|
|
3962
4068
|
/**
|
|
3963
4069
|
* Reverse index: tableName → set of subscription ids whose
|
|
3964
4070
|
* dependent-table set INCLUDES that table. A change event on table
|
|
@@ -3984,12 +4090,18 @@ export declare class Dispatcher {
|
|
|
3984
4090
|
/** Query labels already warned about for an undeclared raw read, so a hot
|
|
3985
4091
|
* subscription logs once rather than once per subscriber. */
|
|
3986
4092
|
private readonly rawReadWarned;
|
|
4093
|
+
/** The cache fence each written-through read observed before it started. */
|
|
4094
|
+
private readonly readFences;
|
|
3987
4095
|
private changeEpoch;
|
|
3988
4096
|
private readonly committedReads;
|
|
3989
4097
|
/** The CRDT-managed columns of `table` (empty when it has none) — what a
|
|
3990
4098
|
* subscription's backpressure outbox folds incrementally. */
|
|
3991
4099
|
crdtColumnsFor(table: string): ReadonlySet<string>;
|
|
3992
4100
|
constructor(deps: DispatcherDependencies);
|
|
4101
|
+
private measureLoop;
|
|
4102
|
+
private retainInterest;
|
|
4103
|
+
/** One idempotent terminal path for setup failures, revocation and disconnect. */
|
|
4104
|
+
private removeInterest;
|
|
3993
4105
|
/**
|
|
3994
4106
|
* REL-14 — a raw read that nothing can invalidate, said out loud.
|
|
3995
4107
|
*
|
|
@@ -4091,6 +4203,9 @@ export declare class Dispatcher {
|
|
|
4091
4203
|
onSubscriptionsChange(listener: () => void): () => void;
|
|
4092
4204
|
/** Tear down the change-event listener. Call on server shutdown. */
|
|
4093
4205
|
close(): void;
|
|
4206
|
+
/** Close admission immediately, then join reads and deliveries before the
|
|
4207
|
+
* owner disposes the store. Do not await this from inside a query callback. */
|
|
4208
|
+
closeAndDrain(): Promise<void>;
|
|
4094
4209
|
/**
|
|
4095
4210
|
* Re-run EVERY live subscription, because this replica proved it missed
|
|
4096
4211
|
* changes it can never recover.
|
|
@@ -4116,6 +4231,8 @@ export declare class Dispatcher {
|
|
|
4116
4231
|
}
|
|
4117
4232
|
|
|
4118
4233
|
export declare interface DispatcherDependencies {
|
|
4234
|
+
/** Active synchronous live-change work only; asynchronous reads are not timed. */
|
|
4235
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
4119
4236
|
readonly store: DataStore;
|
|
4120
4237
|
/** CRDT columns per table (schemaRegistry.crdtColumns). Feeds the
|
|
4121
4238
|
* downstream lane: crdt cells diff as incremental mergeCells ops.
|
|
@@ -4161,6 +4278,8 @@ export declare interface DispatcherDependencies {
|
|
|
4161
4278
|
export declare const DORMANCY_WAKEUP_TENANT = "default";
|
|
4162
4279
|
|
|
4163
4280
|
export declare interface DrainDeps<R = never> {
|
|
4281
|
+
/** Active synchronous handler entry only; never await a Promise inside this measurement. */
|
|
4282
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
4164
4283
|
readonly store: Pick<DataStore, 'query' | 'update' | 'updateMany' | 'insert' | 'delete'>;
|
|
4165
4284
|
readonly handlers: ReadonlyMap<string, OutboxHandlerDefinition<R>>;
|
|
4166
4285
|
/** Execute with the application's services. Required by drainOutbox when R
|
|
@@ -4291,7 +4410,7 @@ export declare interface EffectInsertIgnoreOutcomeStore {
|
|
|
4291
4410
|
|
|
4292
4411
|
/** The minimal Effect-store surface `insertManyRowsEffect` needs. */
|
|
4293
4412
|
export declare interface EffectInsertManyStore {
|
|
4294
|
-
readonly insertMany: (table: string, rows: ReadonlyArray<Row
|
|
4413
|
+
readonly insertMany: (table: string, rows: ReadonlyArray<Row>, options?: InsertManyOptions) => Effect.Effect<ReadonlyArray<Row>, StoreError>;
|
|
4295
4414
|
}
|
|
4296
4415
|
|
|
4297
4416
|
/** The minimal Effect-store surface `insertRowEffect` needs. */
|
|
@@ -4315,7 +4434,7 @@ export declare interface EffectStoreOps {
|
|
|
4315
4434
|
* hand-built descriptor. */
|
|
4316
4435
|
readonly query: <R = Row>(descriptor: QueryDescriptor<R>) => Effect.Effect<ReadonlyArray<R>, StoreError>;
|
|
4317
4436
|
readonly insert: (table: string, row: Row) => Effect.Effect<Row, StoreError>;
|
|
4318
|
-
readonly insertMany: (table: string, rows: ReadonlyArray<Row
|
|
4437
|
+
readonly insertMany: (table: string, rows: ReadonlyArray<Row>, options?: InsertManyOptions) => Effect.Effect<ReadonlyArray<Row>, StoreError>;
|
|
4319
4438
|
readonly patchJson: (table: string, primaryKey: string, path: string, value: unknown, additionalPatch?: Readonly<Record<string, unknown>>) => Effect.Effect<Row | null, StoreError>;
|
|
4320
4439
|
readonly update: (table: string, primaryKey: string, patch: Readonly<Record<string, unknown>>) => Effect.Effect<Row | null, StoreError>;
|
|
4321
4440
|
readonly updateMany: (table: string, patch: Readonly<Record<string, unknown>>, options: {
|
|
@@ -4402,6 +4521,10 @@ export declare const emptySchemaRegistry: SchemaRegistry;
|
|
|
4402
4521
|
* should be observed are constructed — `observeStore` decides once, per store. */
|
|
4403
4522
|
export declare const enableGraphObservation: () => void;
|
|
4404
4523
|
|
|
4524
|
+
/** Encode a snapshot for the cache. Throws on a value with no faithful form —
|
|
4525
|
+
* the caller does not store it then. */
|
|
4526
|
+
export declare const encodeSnapshotValue: (value: unknown) => unknown;
|
|
4527
|
+
|
|
4405
4528
|
/**
|
|
4406
4529
|
* Encrypt a value with the registered field cipher, in the SAME encoding an
|
|
4407
4530
|
* `.encrypted()` column uses. Throws if no cipher is registered.
|
|
@@ -4433,6 +4556,20 @@ export declare const enforceApproval: (input: {
|
|
|
4433
4556
|
readonly traceId?: string | undefined;
|
|
4434
4557
|
}) => Promise<void>;
|
|
4435
4558
|
|
|
4559
|
+
/** One connected engine SDK, as it named itself in `x-voltro-sdk`. It proves nothing and grants nothing. */
|
|
4560
|
+
export declare interface EngineClient {
|
|
4561
|
+
readonly id: string;
|
|
4562
|
+
/** `csharp`, `unity`, `godot` or `unreal`. */
|
|
4563
|
+
readonly target: string;
|
|
4564
|
+
readonly version: string;
|
|
4565
|
+
/** SHA-256 of the API surface the SDK was generated from, or null when it did not say. */
|
|
4566
|
+
readonly surface: string | null;
|
|
4567
|
+
readonly connectedAt: number;
|
|
4568
|
+
}
|
|
4569
|
+
|
|
4570
|
+
/** The engine SDKs connected to this process now, oldest first. */
|
|
4571
|
+
export declare const engineClientsSnapshot: () => ReadonlyArray<EngineClient>;
|
|
4572
|
+
|
|
4436
4573
|
export { EnqueueOptions }
|
|
4437
4574
|
|
|
4438
4575
|
/**
|
|
@@ -5407,6 +5544,12 @@ export declare const externalizedTask: (name: string) => ExternalizedTask | unde
|
|
|
5407
5544
|
|
|
5408
5545
|
export declare const externalizedTaskNames: () => ReadonlyArray<string>;
|
|
5409
5546
|
|
|
5547
|
+
export declare interface ExternalizedTaskRegistry {
|
|
5548
|
+
readonly register: (task: ExternalizedTask) => () => void;
|
|
5549
|
+
readonly get: (name: string) => ExternalizedTask | undefined;
|
|
5550
|
+
readonly names: () => ReadonlyArray<string>;
|
|
5551
|
+
}
|
|
5552
|
+
|
|
5410
5553
|
/** Build an Effect `ExternalSpan` parent from a `traceparent` header so
|
|
5411
5554
|
* inbound HTTP work continues the caller's trace. Returns undefined
|
|
5412
5555
|
* when the header is missing/invalid (no parent → a fresh root span). */
|
|
@@ -5470,11 +5613,251 @@ declare type FailureTag<E> = 0 extends (1 & E) ? never : E extends {
|
|
|
5470
5613
|
readonly _tag: infer T;
|
|
5471
5614
|
} ? T extends 'UnknownError' ? never : T extends string ? T : never : never;
|
|
5472
5615
|
|
|
5616
|
+
export declare const FIELD_ENCRYPTION_ACTIVE_ENV = "VOLTRO_FIELD_ENCRYPTION_ACTIVE";
|
|
5617
|
+
|
|
5618
|
+
export declare const FIELD_ENCRYPTION_KEY_ENV = "VOLTRO_FIELD_ENCRYPTION_KEY";
|
|
5619
|
+
|
|
5620
|
+
export declare const FIELD_ENCRYPTION_KEYS_ENV = "VOLTRO_FIELD_ENCRYPTION_KEYS";
|
|
5621
|
+
|
|
5622
|
+
export declare const FIELD_ENCRYPTION_PREVIOUS_KEY_ENV = "VOLTRO_FIELD_ENCRYPTION_KEY_PREVIOUS";
|
|
5623
|
+
|
|
5624
|
+
export declare const FIELD_KEY_HEARTBEAT_MS = 10000;
|
|
5625
|
+
|
|
5626
|
+
/** The table of leases on field-encryption keys. */
|
|
5627
|
+
export declare const FIELD_KEY_HOLDERS_TABLE = "_voltro_field_key_holders";
|
|
5628
|
+
|
|
5629
|
+
export declare const FIELD_KEY_LEASE_MS = 30000;
|
|
5630
|
+
|
|
5631
|
+
/** The table of the last field-key count and re-key. */
|
|
5632
|
+
export declare const FIELD_KEY_REPORTS_TABLE = "_voltro_field_key_reports";
|
|
5633
|
+
|
|
5634
|
+
/** The environment names a keyring is read from, for a resolver that fetches them. */
|
|
5635
|
+
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"];
|
|
5636
|
+
|
|
5637
|
+
/** The table recording each field-encryption key id's state and canary. */
|
|
5638
|
+
export declare const FIELD_KEYS_TABLE = "_voltro_field_keys";
|
|
5639
|
+
|
|
5473
5640
|
export declare interface FieldChange {
|
|
5474
5641
|
readonly from: unknown;
|
|
5475
5642
|
readonly to: unknown;
|
|
5476
5643
|
}
|
|
5477
5644
|
|
|
5645
|
+
/** What this process opened since it started, per key and location — the Governance panel's view. */
|
|
5646
|
+
export declare const fieldDecryptSnapshot: () => ReadonlyArray<{
|
|
5647
|
+
readonly key: string;
|
|
5648
|
+
readonly location: string;
|
|
5649
|
+
readonly ok: number;
|
|
5650
|
+
readonly failed: number;
|
|
5651
|
+
}>;
|
|
5652
|
+
|
|
5653
|
+
/** The last `voltro secret status`: sealed values per key id, over all and per location. */
|
|
5654
|
+
export declare interface FieldKeyCountReport {
|
|
5655
|
+
readonly totals: Readonly<Record<string, number>>;
|
|
5656
|
+
readonly unnamed: number;
|
|
5657
|
+
readonly plaintext: number;
|
|
5658
|
+
readonly unreadable: number;
|
|
5659
|
+
readonly locations: ReadonlyArray<{
|
|
5660
|
+
readonly table: string;
|
|
5661
|
+
readonly column: string;
|
|
5662
|
+
readonly byKey: Readonly<Record<string, number>>;
|
|
5663
|
+
readonly unnamed: number;
|
|
5664
|
+
readonly plaintext: number;
|
|
5665
|
+
}>;
|
|
5666
|
+
}
|
|
5667
|
+
|
|
5668
|
+
/** One key of a keyring: its id and its secret (a passphrase, or 64 hex). */
|
|
5669
|
+
export declare interface FieldKeyEntry {
|
|
5670
|
+
readonly id: string;
|
|
5671
|
+
readonly secret: string;
|
|
5672
|
+
}
|
|
5673
|
+
|
|
5674
|
+
/** What one heartbeat found. `unheld`: the database's active key is one this
|
|
5675
|
+
* process does not hold — it missed its lease while the fleet moved on. */
|
|
5676
|
+
export declare interface FieldKeyHeartbeat {
|
|
5677
|
+
readonly active: string;
|
|
5678
|
+
readonly activated?: {
|
|
5679
|
+
readonly from: string | undefined;
|
|
5680
|
+
readonly to: string;
|
|
5681
|
+
};
|
|
5682
|
+
readonly waiting?: FieldKeyWaiting;
|
|
5683
|
+
readonly unheld: boolean;
|
|
5684
|
+
}
|
|
5685
|
+
|
|
5686
|
+
/** A process's lease. `now` is for tests; the lease is how long a process that
|
|
5687
|
+
* stopped heartbeating is still waited for. */
|
|
5688
|
+
export declare interface FieldKeyHolder {
|
|
5689
|
+
readonly holderId: string;
|
|
5690
|
+
readonly leaseMs?: number;
|
|
5691
|
+
readonly now?: () => number;
|
|
5692
|
+
}
|
|
5693
|
+
|
|
5694
|
+
export declare interface FieldKeyHolderHandle {
|
|
5695
|
+
/** Stop heartbeating, wait for a beat in flight, and give up the lease. */
|
|
5696
|
+
readonly stop: () => Promise<void>;
|
|
5697
|
+
}
|
|
5698
|
+
|
|
5699
|
+
/** A holder id for this process. */
|
|
5700
|
+
export declare const fieldKeyHolderId: () => string;
|
|
5701
|
+
|
|
5702
|
+
/** One process's lease, as recorded — `expiresAt` in the past means it no longer counts. */
|
|
5703
|
+
export declare interface FieldKeyHolderRecord {
|
|
5704
|
+
readonly holderId: string;
|
|
5705
|
+
readonly keyIds: ReadonlyArray<string>;
|
|
5706
|
+
readonly activeKeyId: string;
|
|
5707
|
+
readonly heartbeatAt: Date;
|
|
5708
|
+
readonly expiresAt: Date;
|
|
5709
|
+
}
|
|
5710
|
+
|
|
5711
|
+
export declare interface FieldKeyHolderRow {
|
|
5712
|
+
readonly holderId: string;
|
|
5713
|
+
readonly keyIds: ReadonlyArray<string>;
|
|
5714
|
+
readonly activeKeyId: string;
|
|
5715
|
+
readonly expiresAt: string;
|
|
5716
|
+
}
|
|
5717
|
+
|
|
5718
|
+
/**
|
|
5719
|
+
* The id a key gets when the operator does not name one: `k` + 10 hex
|
|
5720
|
+
* characters of an HMAC over the derived key. Stable for a given key, short
|
|
5721
|
+
* enough to ride in every envelope, and not the key — the fingerprint is keyed
|
|
5722
|
+
* by the key itself, so it says nothing about it to someone without it.
|
|
5723
|
+
*/
|
|
5724
|
+
export declare const fieldKeyIdOf: (secret: string) => string;
|
|
5725
|
+
|
|
5726
|
+
/** The last `voltro secret rekey` (also run by `rotate`): what moved, what is left, and whether the active key alone opens everything. */
|
|
5727
|
+
export declare interface FieldKeyRekeyReport {
|
|
5728
|
+
readonly active: string;
|
|
5729
|
+
readonly rekeyed: number;
|
|
5730
|
+
readonly left: number;
|
|
5731
|
+
readonly verified: boolean;
|
|
5732
|
+
}
|
|
5733
|
+
|
|
5734
|
+
export declare interface FieldKeyReports {
|
|
5735
|
+
readonly status?: {
|
|
5736
|
+
readonly reportedAt: Date;
|
|
5737
|
+
readonly report: FieldKeyCountReport;
|
|
5738
|
+
};
|
|
5739
|
+
readonly rekey?: {
|
|
5740
|
+
readonly reportedAt: Date;
|
|
5741
|
+
readonly report: FieldKeyRekeyReport;
|
|
5742
|
+
};
|
|
5743
|
+
}
|
|
5744
|
+
|
|
5745
|
+
/** A field cipher over several keys, each with an id — what `makeFieldKeyring` returns. */
|
|
5746
|
+
export declare interface FieldKeyring extends FieldCipher {
|
|
5747
|
+
/** The key new values are sealed under — the configured active key until
|
|
5748
|
+
* {@link FieldKeyring.activate} names another one the keyring holds. */
|
|
5749
|
+
readonly activeKeyId: string;
|
|
5750
|
+
/** The active key the configuration names. The database may keep another
|
|
5751
|
+
* active until every live process holds this one (`verifyFieldKeyring`). */
|
|
5752
|
+
readonly requestedKeyId: string;
|
|
5753
|
+
/** Every id the keyring holds, the configured active key first. */
|
|
5754
|
+
readonly keyIds: ReadonlyArray<string>;
|
|
5755
|
+
/** Each held key's fingerprint ({@link fieldKeyIdOf} — an HMAC of the key, never
|
|
5756
|
+
* the key), by id: what the boot line and the Governance panel show. */
|
|
5757
|
+
readonly fingerprints: Readonly<Record<string, string>>;
|
|
5758
|
+
/** Seal under one named key, whichever is active (a key's canary). */
|
|
5759
|
+
readonly sealWith: (keyId: string, plaintext: string, binding?: FieldBinding) => string;
|
|
5760
|
+
/** Does the named key open this value? `false` for a key the keyring does not hold. */
|
|
5761
|
+
readonly opensWith: (keyId: string, ciphertext: string, binding?: FieldBinding) => boolean;
|
|
5762
|
+
/** Seal new values under another held key — the database, not the
|
|
5763
|
+
* environment, decides which key is active (`verifyFieldKeyring`). */
|
|
5764
|
+
readonly activate: (keyId: string) => void;
|
|
5765
|
+
}
|
|
5766
|
+
|
|
5767
|
+
/** The keys a process holds, and the one new values are sealed under. */
|
|
5768
|
+
export declare interface FieldKeyringConfig {
|
|
5769
|
+
readonly active: string;
|
|
5770
|
+
readonly keys: ReadonlyArray<FieldKeyEntry>;
|
|
5771
|
+
}
|
|
5772
|
+
|
|
5773
|
+
/** A keyring configuration that cannot be used — named, never containing a key. */
|
|
5774
|
+
export declare class FieldKeyringConfigError extends Error {
|
|
5775
|
+
readonly _tag = "FieldKeyringConfigError";
|
|
5776
|
+
constructor(message: string);
|
|
5777
|
+
}
|
|
5778
|
+
|
|
5779
|
+
/** The boot cannot use this keyring with this database — the message names
|
|
5780
|
+
* ids, columns and the way out, never a key. */
|
|
5781
|
+
export declare class FieldKeyringRefusal extends Error {
|
|
5782
|
+
readonly _tag = "FieldKeyringRefusal";
|
|
5783
|
+
constructor(message: string);
|
|
5784
|
+
}
|
|
5785
|
+
|
|
5786
|
+
/** What a boot's check found and recorded. */
|
|
5787
|
+
export declare interface FieldKeyringVerification {
|
|
5788
|
+
/** The key new values are sealed under, as the database records it. */
|
|
5789
|
+
readonly active: string;
|
|
5790
|
+
/** Ids this boot recorded for the first time. */
|
|
5791
|
+
readonly registered: ReadonlyArray<string>;
|
|
5792
|
+
/** Set when this boot made another key active. */
|
|
5793
|
+
readonly activated?: {
|
|
5794
|
+
readonly from: string | undefined;
|
|
5795
|
+
readonly to: string;
|
|
5796
|
+
};
|
|
5797
|
+
/** A requested key that is not active yet, and the live processes that lack it. */
|
|
5798
|
+
readonly waiting?: FieldKeyWaiting;
|
|
5799
|
+
/** Things worth a log line, never a refusal. */
|
|
5800
|
+
readonly notes: ReadonlyArray<string>;
|
|
5801
|
+
}
|
|
5802
|
+
|
|
5803
|
+
/** One recorded key id — its state and canary, never its key. */
|
|
5804
|
+
export declare interface FieldKeyRow {
|
|
5805
|
+
readonly keyId: string;
|
|
5806
|
+
readonly state: FieldKeyState;
|
|
5807
|
+
readonly canary: string;
|
|
5808
|
+
readonly registeredAt: Date | null;
|
|
5809
|
+
readonly activatedAt: Date | null;
|
|
5810
|
+
readonly replacedAt: Date | null;
|
|
5811
|
+
readonly retiredAt: Date | null;
|
|
5812
|
+
readonly requestedAt: Date | null;
|
|
5813
|
+
}
|
|
5814
|
+
|
|
5815
|
+
/** A key's state. `pending`: held, never active. `active`: new values are sealed
|
|
5816
|
+
* under it — exactly one. `decrypt-only`: was active, replaced; values may still
|
|
5817
|
+
* be sealed under it. `retired`: nothing is sealed under it any more. */
|
|
5818
|
+
export declare type FieldKeyState = 'pending' | 'active' | 'decrypt-only' | 'retired';
|
|
5819
|
+
|
|
5820
|
+
export declare interface FieldKeyStateRow {
|
|
5821
|
+
readonly keyId: string;
|
|
5822
|
+
readonly state: string;
|
|
5823
|
+
readonly activatedAt: string | null;
|
|
5824
|
+
readonly requestedAt: string | null;
|
|
5825
|
+
}
|
|
5826
|
+
|
|
5827
|
+
export declare interface FieldKeyStatus {
|
|
5828
|
+
/** The recorded keys and their states — empty before the first boot recorded any. */
|
|
5829
|
+
readonly keys: ReadonlyArray<FieldKeyStateRow>;
|
|
5830
|
+
/** Every process that holds a lease, live or not (`expiresAt` says which). */
|
|
5831
|
+
readonly holders: ReadonlyArray<FieldKeyHolderRow>;
|
|
5832
|
+
readonly locations: ReadonlyArray<SealedLocation>;
|
|
5833
|
+
/** Envelopes per key id, over every location. */
|
|
5834
|
+
readonly totals: Readonly<Record<string, number>>;
|
|
5835
|
+
readonly unnamed: number;
|
|
5836
|
+
readonly plaintext: number;
|
|
5837
|
+
/** Columns that could not be read — listed, never silently left out of the counts. */
|
|
5838
|
+
readonly unreadable: ReadonlyArray<UnreadableColumn>;
|
|
5839
|
+
}
|
|
5840
|
+
|
|
5841
|
+
/**
|
|
5842
|
+
* Count every sealed value in the database by the key it names. `declared` are
|
|
5843
|
+
* the app's tables: their `.encrypted()` columns are always reported (with
|
|
5844
|
+
* plaintext counted), the rest only where envelopes were found.
|
|
5845
|
+
*/
|
|
5846
|
+
export declare const fieldKeyStatus: (dialect: DialectId, declared: Iterable<unknown>) => Effect.Effect<{
|
|
5847
|
+
keys: FieldKeyStateRow[];
|
|
5848
|
+
holders: FieldKeyHolderRow[];
|
|
5849
|
+
locations: SealedLocation[];
|
|
5850
|
+
totals: Record<string, number>;
|
|
5851
|
+
unreadable: UnreadableColumn[];
|
|
5852
|
+
unnamed: number;
|
|
5853
|
+
plaintext: number;
|
|
5854
|
+
}, SqlError, SqlClient.SqlClient>;
|
|
5855
|
+
|
|
5856
|
+
export declare interface FieldKeyWaiting {
|
|
5857
|
+
readonly keyId: string;
|
|
5858
|
+
readonly holders: ReadonlyArray<string>;
|
|
5859
|
+
}
|
|
5860
|
+
|
|
5478
5861
|
/**
|
|
5479
5862
|
* Canonical fingerprint over `(table, predicate, indexHint?)`. The
|
|
5480
5863
|
* optional `indexHint` participates so two subscriptions with the same
|
|
@@ -5851,6 +6234,13 @@ export declare interface HealthConfigInput {
|
|
|
5851
6234
|
readonly readiness?: () => boolean | Promise<boolean>;
|
|
5852
6235
|
}
|
|
5853
6236
|
|
|
6237
|
+
/**
|
|
6238
|
+
* One heartbeat: renew this process's lease, complete a requested activation
|
|
6239
|
+
* once every live holder holds the key, and seal under the database's active
|
|
6240
|
+
* key from now on. Any holder can complete an activation another one requested.
|
|
6241
|
+
*/
|
|
6242
|
+
export declare const heartbeatFieldKeys: (store: DataStore, keyring: FieldKeyring, holder: FieldKeyHolder) => Promise<FieldKeyHeartbeat>;
|
|
6243
|
+
|
|
5854
6244
|
/** Define a histogram. `boundaries` default to the framework duration buckets. */
|
|
5855
6245
|
export declare const histogramMetric: (name: string, boundaries?: ReadonlyArray<number>, description?: string) => Metric.Histogram<number>;
|
|
5856
6246
|
|
|
@@ -5992,9 +6382,10 @@ export declare class InMemoryDataStore implements DataStore {
|
|
|
5992
6382
|
* to tell apart from "no such table".
|
|
5993
6383
|
*/
|
|
5994
6384
|
storedTables(): ReadonlyArray<StoredTableShape>;
|
|
6385
|
+
integrityQuery(descriptor: QueryDescriptor): Promise<ReadonlyArray<Row>>;
|
|
5995
6386
|
query(descriptor: QueryDescriptor): Promise<ReadonlyArray<Row>>;
|
|
5996
6387
|
insert(table: string, row: Row): Promise<Row>;
|
|
5997
|
-
insertMany(table: string, rows: ReadonlyArray<Row
|
|
6388
|
+
insertMany(table: string, rows: ReadonlyArray<Row>, options?: InsertManyOptions): Promise<ReadonlyArray<Row>>;
|
|
5998
6389
|
patchJson(table: string, primaryKey: RowKey, path: string, value: unknown, additionalPatch?: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
5999
6390
|
update(table: string, primaryKey: RowKey, patch: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
6000
6391
|
delete(table: string, primaryKey: RowKey): Promise<boolean>;
|
|
@@ -6026,8 +6417,9 @@ export declare const insertIgnoreRowOutcomeEffect: <T extends AnyWritableTable>(
|
|
|
6026
6417
|
readonly outcome: "inserted" | "ignored";
|
|
6027
6418
|
}, StoreError>;
|
|
6028
6419
|
|
|
6029
|
-
/** `insertRowEffect`'s batch — every element checked against `InferInsertRow<T>`.
|
|
6030
|
-
|
|
6420
|
+
/** `insertRowEffect`'s batch — every element checked against `InferInsertRow<T>`.
|
|
6421
|
+
* `{ returning: 'none' }` resolves to `[]` without reading the rows back. */
|
|
6422
|
+
export declare const insertManyRowsEffect: <T extends AnyWritableTable>(store: EffectInsertManyStore, table: T, rows: ReadonlyArray<InferInsertRow<T>>, options?: InsertManyOptions) => Effect.Effect<ReadonlyArray<InferRow<T>>, StoreError>;
|
|
6031
6423
|
|
|
6032
6424
|
/**
|
|
6033
6425
|
* Insert a row, typed against the table, on the Effect channel.
|
|
@@ -6132,6 +6524,10 @@ export { inspectWorkflow }
|
|
|
6132
6524
|
|
|
6133
6525
|
export declare const installApprovalGate: (gate: ApprovalGateApi) => void;
|
|
6134
6526
|
|
|
6527
|
+
/** Turn on read capture for cached computes — called at boot when any query
|
|
6528
|
+
* declares `cache:`. Until then the request store is not wrapped for it. */
|
|
6529
|
+
export declare const installComputedQueryCacheCapture: () => void;
|
|
6530
|
+
|
|
6135
6531
|
/**
|
|
6136
6532
|
* Install the resolver that answers `guards: [{ action, resourceType }]`.
|
|
6137
6533
|
*
|
|
@@ -6235,6 +6631,9 @@ export declare const isExpectationDefinition: (value: unknown) => value is Expec
|
|
|
6235
6631
|
|
|
6236
6632
|
export declare const isExperimentDefinition: (value: unknown) => value is ExperimentDefinition;
|
|
6237
6633
|
|
|
6634
|
+
/** Is this cipher a keyring (ids, per-key seal and open), not a bare cipher? */
|
|
6635
|
+
export declare const isFieldKeyring: (cipher: FieldCipher | undefined) => cipher is FieldKeyring;
|
|
6636
|
+
|
|
6238
6637
|
export { isForeignKeyViolation }
|
|
6239
6638
|
|
|
6240
6639
|
/**
|
|
@@ -6461,7 +6860,7 @@ export declare interface KvFacade {
|
|
|
6461
6860
|
readonly service: Effect.Success<typeof Kv>;
|
|
6462
6861
|
/** The resolved backend kind — for boot logging. */
|
|
6463
6862
|
readonly backend: 'database' | 'redis' | 'memory';
|
|
6464
|
-
/**
|
|
6863
|
+
/** Release this consumer runtime; an injected registry retains its pools. */
|
|
6465
6864
|
readonly dispose: () => Promise<void>;
|
|
6466
6865
|
}
|
|
6467
6866
|
|
|
@@ -6470,6 +6869,10 @@ export declare interface KvFacadeOptions {
|
|
|
6470
6869
|
readonly store: DataStore;
|
|
6471
6870
|
/** Defaults to `process.env`. */
|
|
6472
6871
|
readonly env?: NodeJS.ProcessEnv;
|
|
6872
|
+
readonly backend?: 'database' | 'redis' | 'memory';
|
|
6873
|
+
readonly connectionName?: string;
|
|
6874
|
+
readonly keyPrefix?: string;
|
|
6875
|
+
readonly connections?: RespConnections;
|
|
6473
6876
|
}
|
|
6474
6877
|
|
|
6475
6878
|
/**
|
|
@@ -6591,6 +6994,27 @@ export declare interface LocalityAwareOptions {
|
|
|
6591
6994
|
*/
|
|
6592
6995
|
export declare const localityAwareSelector: (options: LocalityAwareOptions) => ReplicaSelector;
|
|
6593
6996
|
|
|
6997
|
+
/** One location's outcome. */
|
|
6998
|
+
export declare interface LocationRekey {
|
|
6999
|
+
readonly table: string;
|
|
7000
|
+
readonly column: string;
|
|
7001
|
+
readonly cells: number;
|
|
7002
|
+
readonly rekeyed: number;
|
|
7003
|
+
readonly current: number;
|
|
7004
|
+
readonly unresolved: number;
|
|
7005
|
+
/** Cells the app changed between the read and the write — run again. */
|
|
7006
|
+
readonly changedMeanwhile: number;
|
|
7007
|
+
/** Values that need a re-key in a table with no single-column primary key to address the cell by. */
|
|
7008
|
+
readonly unaddressable: number;
|
|
7009
|
+
}
|
|
7010
|
+
|
|
7011
|
+
/** Read the current key row within its expected tenant under a write fence.
|
|
7012
|
+
* Supply an existing transaction after the application's organization/account
|
|
7013
|
+
* fences and keep it through the protected write. Null matches unassigned
|
|
7014
|
+
* keys only. The internal row uses the normal store codec; never return it in
|
|
7015
|
+
* a public response. This is not bearer verification or an authorization grant. */
|
|
7016
|
+
export declare const lockApiKeyById: (store: DataStore, id: string, tenantId: string | null) => Promise<ApiKeyRow | null>;
|
|
7017
|
+
|
|
6594
7018
|
export declare interface LogTraceContext {
|
|
6595
7019
|
readonly traceId: string;
|
|
6596
7020
|
readonly spanId?: string;
|
|
@@ -6662,7 +7086,7 @@ log?: SchedulerLogger) => Coordinator;
|
|
|
6662
7086
|
* tampered / wrong-key value AND on a bound value read at another address —
|
|
6663
7087
|
* both surface as a read error, never silent corruption.
|
|
6664
7088
|
*/
|
|
6665
|
-
export declare const makeAesCipher: (key: Buffer) => FieldCipher;
|
|
7089
|
+
export declare const makeAesCipher: (key: Buffer, keyId?: string) => FieldCipher;
|
|
6666
7090
|
|
|
6667
7091
|
export declare const makeApiKeyService: (store: ApiKeyStore, opts?: {
|
|
6668
7092
|
prefix?: string;
|
|
@@ -6690,6 +7114,61 @@ export declare const makeApiKeyUsageFlusher: (store: ApiKeyStore) => (id: string
|
|
|
6690
7114
|
readonly lastUsedAt: number;
|
|
6691
7115
|
}) => Promise<void>;
|
|
6692
7116
|
|
|
7117
|
+
/** In-memory, bounded finalized-bucket queue. Current instrumentation is partial;
|
|
7118
|
+
* this collector cannot certify complete workload coverage merely from uptime. */
|
|
7119
|
+
export declare const makeApiRoleBucketSampler: (input: {
|
|
7120
|
+
readonly replicaId: string;
|
|
7121
|
+
readonly startedAt: number;
|
|
7122
|
+
readonly role: string;
|
|
7123
|
+
readonly workloads: ReadonlyArray<ApiWorkload>;
|
|
7124
|
+
readonly epochNow: number;
|
|
7125
|
+
readonly monotonicNow: number;
|
|
7126
|
+
}) => {
|
|
7127
|
+
record(segment: {
|
|
7128
|
+
readonly workload: ApiWorkload;
|
|
7129
|
+
readonly from: number;
|
|
7130
|
+
readonly until: number;
|
|
7131
|
+
}): void;
|
|
7132
|
+
/** Heartbeat every30s. Delays >60s or clock skew >1s conservatively invalidate
|
|
7133
|
+
* affected intervals; never spread elapsed request time across buckets. */
|
|
7134
|
+
advance(monotonicNow: number, epochNow: number): void;
|
|
7135
|
+
pending(): ReadonlyArray<ApiRoleWorkloadBucket>;
|
|
7136
|
+
acknowledge(from: number): void;
|
|
7137
|
+
status: () => {
|
|
7138
|
+
pendingBuckets: number;
|
|
7139
|
+
droppedBuckets: number;
|
|
7140
|
+
rejectedSegments: number;
|
|
7141
|
+
};
|
|
7142
|
+
};
|
|
7143
|
+
|
|
7144
|
+
/** Measures only the synchronous execution of a callback, including throws.
|
|
7145
|
+
* Returning a Promise measures its construction, not its awaited lifetime.
|
|
7146
|
+
* Each resumed async callback must be instrumented separately. No wall-time
|
|
7147
|
+
* request duration may be fed into this counter as a substitute for loop time.
|
|
7148
|
+
* Nested calls on this recorder suspend their parent, so time is exclusive. */
|
|
7149
|
+
export declare const makeApiRoleWorkloadMetrics: (roles: ReadonlyArray<string>, options?: {
|
|
7150
|
+
readonly now?: () => number;
|
|
7151
|
+
readonly onSegment?: (segment: {
|
|
7152
|
+
readonly workload: ApiWorkload;
|
|
7153
|
+
readonly from: number;
|
|
7154
|
+
readonly until: number;
|
|
7155
|
+
}) => void;
|
|
7156
|
+
}) => {
|
|
7157
|
+
role: string;
|
|
7158
|
+
observationErrors: () => number;
|
|
7159
|
+
/** Effect4's tracer context surrounds each synchronous primitive, including
|
|
7160
|
+
* the first, resumed and inherited child work. Preserve the existing tracer;
|
|
7161
|
+
* Promise callbacks outside evaluation still use measureSync explicitly. */
|
|
7162
|
+
observeEffect<A, E, R>(effect: Effect.Effect<A, E, R>, workload: ApiWorkload): Effect.Effect<A, E, R>;
|
|
7163
|
+
measureSync<A>(workload: ApiWorkload, run: () => A): A;
|
|
7164
|
+
/** Local totals, not a 24-hour history or evidence of full instrumentation. */
|
|
7165
|
+
snapshot(): ReadonlyArray<{
|
|
7166
|
+
readonly role: string;
|
|
7167
|
+
readonly workload: ApiWorkload;
|
|
7168
|
+
readonly seconds: number;
|
|
7169
|
+
}>;
|
|
7170
|
+
};
|
|
7171
|
+
|
|
6693
7172
|
/** Build the `ctx.access` slice for a subject. Reads the effective-scope seam
|
|
6694
7173
|
* LIVE (via getters/closures) so a scope rbac resolves after context
|
|
6695
7174
|
* construction is still reflected. Used by the shared AppContext builder AND
|
|
@@ -6713,7 +7192,7 @@ export declare interface MakeApprovalGateOptions {
|
|
|
6713
7192
|
|
|
6714
7193
|
/** Build the `ctx.kv` facade. `KV_BACKEND` picks the backend; unknown values
|
|
6715
7194
|
* fall back to `database`. */
|
|
6716
|
-
export declare const makeAsyncKv: ({ store, env }: KvFacadeOptions) => Promise<KvFacade>;
|
|
7195
|
+
export declare const makeAsyncKv: ({ store, env, backend: configuredBackend, connectionName, keyPrefix, connections }: KvFacadeOptions) => Promise<KvFacade>;
|
|
6717
7196
|
|
|
6718
7197
|
/**
|
|
6719
7198
|
* The `AuthMiddleware` + `ConnectionInfoMiddleware` pair every rpc surface
|
|
@@ -6832,19 +7311,45 @@ export declare const makeEventPublisher: (ctx: EventPublishContext) => EventPubl
|
|
|
6832
7311
|
|
|
6833
7312
|
export declare const makeEventsFacade: (options: EventsFacadeOptions) => EventsAppContext;
|
|
6834
7313
|
|
|
7314
|
+
/** Pass one instance to a host's scheduler factories and trigger route. */
|
|
7315
|
+
export declare const makeExternalizedTaskRegistry: () => ExternalizedTaskRegistry;
|
|
7316
|
+
|
|
6835
7317
|
/**
|
|
6836
7318
|
* Derive a key from a passphrase and build the cipher — with the keys a
|
|
6837
|
-
* ROTATION retires, when there are any.
|
|
7319
|
+
* ROTATION retires, when there are any. Ids are derived from the keys
|
|
7320
|
+
* (`fieldKeyIdOf`); a previous key equal to the current one is skipped.
|
|
6838
7321
|
*
|
|
6839
|
-
* Writes use the current key; reads
|
|
6840
|
-
* one. GCM authenticates, so a
|
|
6841
|
-
*
|
|
6842
|
-
* every value written before it unreadable — measured: every
|
|
6843
|
-
* suspended run of an `encrypted: true` workflow failed its replay
|
|
6844
|
-
* `MalformedMessage`, and every `.encrypted()` column read failed.
|
|
7322
|
+
* Writes use the current key; reads open a value by the key it names, or by
|
|
7323
|
+
* trying the current one, then each previous one. GCM authenticates, so a
|
|
7324
|
+
* wrong key fails its tag rather than producing garbage. Without this, a key
|
|
7325
|
+
* change made every value written before it unreadable — measured: every
|
|
7326
|
+
* sleeping or suspended run of an `encrypted: true` workflow failed its replay
|
|
7327
|
+
* with `MalformedMessage`, and every `.encrypted()` column read failed.
|
|
6845
7328
|
*/
|
|
6846
7329
|
export declare const makeFieldCipher: (passphrase: string, previous?: ReadonlyArray<string>) => FieldCipher;
|
|
6847
7330
|
|
|
7331
|
+
/**
|
|
7332
|
+
* A cipher over a keyring: new values are sealed under the active key and name
|
|
7333
|
+
* it; a value is opened by the key it names (a lookup), and one written before
|
|
7334
|
+
* values named their key by trying each key, the active one first.
|
|
7335
|
+
*
|
|
7336
|
+
* A named key that is not in the keyring is a refusal that names it, so an
|
|
7337
|
+
* operator reads "sealed under k2026a, which this process does not hold"
|
|
7338
|
+
* instead of a GCM failure. A named key that does not open the value (an id
|
|
7339
|
+
* that was altered) falls back to trying the others — the id is a hint, GCM is
|
|
7340
|
+
* the authority.
|
|
7341
|
+
*/
|
|
7342
|
+
export declare const makeFieldKeyring: (config: FieldKeyringConfig, options?: {
|
|
7343
|
+
/**
|
|
7344
|
+
* Refuse to seal until {@link FieldKeyring.activate} has run — the boot's
|
|
7345
|
+
* keyring sets this, so nothing is sealed under the configured key before
|
|
7346
|
+
* the database has said which key is active. A value sealed under a key the
|
|
7347
|
+
* fleet has not accepted is one a replica on the previous configuration
|
|
7348
|
+
* cannot read.
|
|
7349
|
+
*/
|
|
7350
|
+
readonly sealOnlyOnceActivated?: boolean;
|
|
7351
|
+
}) => FieldKeyring;
|
|
7352
|
+
|
|
6848
7353
|
/** Build the fluent `select` / `update` / `delete` entry functions over a
|
|
6849
7354
|
* backend + scope. Wired into `wrapStoreWithMixinBehaviour` so they hang
|
|
6850
7355
|
* off `ctx.store` alongside the keyed `query`/`insert`/`update`/`delete`. */
|
|
@@ -6867,12 +7372,18 @@ export declare const makeLazyWorkflowFacade: (resolve: () => WorkflowsAppContext
|
|
|
6867
7372
|
export declare const makeListConnectionsExecutor: (deps: ConnectionBuiltinDeps) => (_input: Record<string, never>, ctx: ConnectionExecutorCtx) => Promise<ReadonlyArray<ConnectionState_2>>;
|
|
6868
7373
|
|
|
6869
7374
|
/**
|
|
6870
|
-
* Build
|
|
6871
|
-
*
|
|
6872
|
-
*
|
|
6873
|
-
* produced, `encodeUnknownSync` never throws. `undefined` schema → no codec.
|
|
7375
|
+
* Build one input/output contract from both declared schemas. Refuse incompatible
|
|
7376
|
+
* values with payload-free errors; never return or log an old raw response
|
|
7377
|
+
* when the current output contract cannot decode it. Input is captured from its schema before keyed acquisition.
|
|
6874
7378
|
*/
|
|
6875
|
-
export declare const
|
|
7379
|
+
export declare const makeMutationCodec: (inputSchema: Schema.Top, outputSchema: Schema.Top, admit: MutationCodec<unknown>["admit"]) => MutationCodec<unknown>;
|
|
7380
|
+
|
|
7381
|
+
/** Current admission for a keyed unary call, including its cached result.
|
|
7382
|
+
* Pure refresher binding is separate from business interceptors/executors. */
|
|
7383
|
+
export declare const makeMutationReplayAdmission: (procedure: MutationLike, kind: "mutation" | "action", options?: {
|
|
7384
|
+
readonly defaultDeny?: boolean;
|
|
7385
|
+
readonly bindReplayAuthority?: RpcReplayAuthorityBinding | undefined;
|
|
7386
|
+
}) => ((input: unknown, request: ServeRequestContext) => Promise<void>);
|
|
6876
7387
|
|
|
6877
7388
|
/**
|
|
6878
7389
|
* Build the shared mutation runner. Used by BOTH the rpc WS handler and
|
|
@@ -6946,7 +7457,7 @@ export declare const makeOutboxFacade: (deps: OutboxFacadeDeps) => OutboxFacade;
|
|
|
6946
7457
|
*/
|
|
6947
7458
|
export declare const makeProcessAdapter: (supervisor: AppSupervisor) => WakeAdapter;
|
|
6948
7459
|
|
|
6949
|
-
export declare const makeQueryDescriptorProducer: <D>(deps: QueryProducerDeps<D
|
|
7460
|
+
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>;
|
|
6950
7461
|
|
|
6951
7462
|
export declare const makeQueryFinalizer: (options: QueryFinalizeOptions) => ((descriptor: QueryDescriptor, subject: {
|
|
6952
7463
|
readonly tenantId?: string | null;
|
|
@@ -7385,35 +7896,22 @@ export declare const MIN_LEVEL_RESYNC_MS = 30000;
|
|
|
7385
7896
|
/** Mint a fresh service token. `voltro dev` and `voltro secret generate` call this. */
|
|
7386
7897
|
export declare const mintServiceToken: () => string;
|
|
7387
7898
|
|
|
7388
|
-
|
|
7389
|
-
* Ordering token for one mirrored write.
|
|
7390
|
-
*
|
|
7391
|
-
* **The sink MUST persist this and MUST NOT invent its own.** It is
|
|
7392
|
-
* assigned by the framework at the moment the change leaves the store's
|
|
7393
|
-
* change channel — i.e. in COMMIT order — so a write with a lower
|
|
7394
|
-
* version is, by construction, an older image of that row. Stamping a
|
|
7395
|
-
* version at sink-call time instead (a `Date.now()` inside `upsert`)
|
|
7396
|
-
* makes a late-arriving STALE image outrank the fresh one and win
|
|
7397
|
-
* permanently; that is the bug this type exists to make unrepresentable.
|
|
7398
|
-
*
|
|
7399
|
-
* How the number is derived depends on the store's `changeScope`:
|
|
7400
|
-
*
|
|
7401
|
-
* - `'local'` (one process observes each change): a hybrid clock —
|
|
7402
|
-
* wall-clock microseconds forced strictly upward, so it orders within
|
|
7403
|
-
* a millisecond and keeps increasing across a restart.
|
|
7404
|
-
* - `'fleet'` (every replica observes every change): derived from the
|
|
7405
|
-
* CHANGE, not from the receiving process — the warehouse's own max
|
|
7406
|
-
* version for the key (read once via {@link AnalyticsMirrorImpl.maxVersion})
|
|
7407
|
-
* plus the change's per-key position in the totally-ordered fleet
|
|
7408
|
-
* stream. N replicas mirroring the same change therefore stamp the
|
|
7409
|
-
* SAME number, and the sink's version guard dedupes the N duplicate
|
|
7410
|
-
* writes for free — no leader, no clock, no skew hazard.
|
|
7411
|
-
*/
|
|
7412
|
-
export declare type MirrorVersion = number;
|
|
7899
|
+
export { MirrorVersion }
|
|
7413
7900
|
|
|
7414
7901
|
/** The error `.one()` throws: the factory's, or the framework's `NoRowFound`. */
|
|
7415
7902
|
export declare const missingRowError: (info: NoRowFoundInfo, onMissing: OnMissingRow | undefined) => unknown;
|
|
7416
7903
|
|
|
7904
|
+
/**
|
|
7905
|
+
* Store encoded wire output and decode it against the current output contract.
|
|
7906
|
+
* A failed codec never falls back to an unvalidated raw response.
|
|
7907
|
+
*/
|
|
7908
|
+
export declare interface MutationCodec<Output> {
|
|
7909
|
+
readonly input: Schema.Top;
|
|
7910
|
+
readonly admit: (input: unknown, context: RuntimeContext) => Promise<void>;
|
|
7911
|
+
readonly encode: (output: Output) => unknown;
|
|
7912
|
+
readonly decode: (stored: unknown) => Output;
|
|
7913
|
+
}
|
|
7914
|
+
|
|
7417
7915
|
export declare interface MutationLifecycle {
|
|
7418
7916
|
readonly afterCommit: (work: () => Promise<unknown>) => void;
|
|
7419
7917
|
/** Already selected physical, namespace-bound nontransactional store.
|
|
@@ -7425,8 +7923,16 @@ export declare interface MutationLifecycle {
|
|
|
7425
7923
|
export declare interface MutationLike {
|
|
7426
7924
|
readonly descriptor: {
|
|
7427
7925
|
readonly name: string;
|
|
7926
|
+
readonly undo?: {
|
|
7927
|
+
readonly capture: false;
|
|
7928
|
+
readonly reason: string;
|
|
7929
|
+
} | undefined;
|
|
7428
7930
|
readonly source?: string | ReadonlyArray<string> | undefined;
|
|
7429
7931
|
readonly guards?: ReadonlyArray<AnyCheckSpec> | undefined;
|
|
7932
|
+
/** Query only — read by the computed-query cache (`computedQueryCache.ts`). */
|
|
7933
|
+
readonly cache?: QueryCacheLike | undefined;
|
|
7934
|
+
readonly input?: Schema.Top | undefined;
|
|
7935
|
+
readonly output?: Schema.Top | undefined;
|
|
7430
7936
|
/** The second-human control (mutation/action only). Enforced by
|
|
7431
7937
|
* `enforceApprovalGate`, immediately after `enforceGuards`. */
|
|
7432
7938
|
readonly requiresApproval?: AnyApprovalPolicy | undefined;
|
|
@@ -7441,25 +7947,20 @@ export declare interface MutationLike {
|
|
|
7441
7947
|
executor(input: unknown, ctx: unknown): unknown;
|
|
7442
7948
|
}
|
|
7443
7949
|
|
|
7444
|
-
/**
|
|
7445
|
-
* Encode/decode a mutation's output for idempotent replay. On a FRESH call the
|
|
7446
|
-
* WIRE form (`encode`) is stored, so a later replay `decode`s it back to the exact
|
|
7447
|
-
* Output the handler would have returned and the rpc layer re-encodes it
|
|
7448
|
-
* identically. Storing the DECODED Output directly would corrupt `Date`/etc.
|
|
7449
|
-
* fields through the store's JSON round-trip (encode there expects a `Date`, not
|
|
7450
|
-
* the ISO string a round-trip produced). Built from `descriptor.output` at the
|
|
7451
|
-
* call site; both fns fall back to the raw value if the Schema can't round-trip.
|
|
7452
|
-
*/
|
|
7453
|
-
export declare interface MutationOutputCodec<Output> {
|
|
7454
|
-
readonly encode: (output: Output) => unknown;
|
|
7455
|
-
readonly decode: (stored: unknown) => Output;
|
|
7456
|
-
}
|
|
7457
|
-
|
|
7458
7950
|
export declare interface MutationRunnerDeps {
|
|
7951
|
+
/** Measures only the synchronous executor entry, never an awaited result. */
|
|
7952
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
7459
7953
|
readonly outcomeOutbox?: (request: ServeRequestContext) => OutboxEnqueueFacade | undefined;
|
|
7460
7954
|
/** A failure aborts the business transaction; transient contention replays
|
|
7461
7955
|
* executor and hook together. Never perform external I/O here. */
|
|
7462
7956
|
readonly beforeMutationCommit?: ServeMutationCommitHook | undefined;
|
|
7957
|
+
/**
|
|
7958
|
+
* Resolves once the cache invalidations this process started have reached
|
|
7959
|
+
* the cache. Awaited after commit, BEFORE the mutation answers — without it
|
|
7960
|
+
* the writer's next read raced its own invalidation and was served the
|
|
7961
|
+
* pre-write entry. Both boot paths pass `wireCacheInvalidation`'s `settled`.
|
|
7962
|
+
*/
|
|
7963
|
+
readonly settleCacheInvalidations?: () => Promise<void>;
|
|
7463
7964
|
readonly store: TransactionalStore;
|
|
7464
7965
|
/** Select and provision the request's physical store before opening its
|
|
7465
7966
|
* transaction. Resolved once, including across retries and post-commit folds. */
|
|
@@ -7524,6 +8025,19 @@ export declare interface MutationStore extends DataStore {
|
|
|
7524
8025
|
hardDelete(table: string, primaryKey: RowKey): Promise<boolean>;
|
|
7525
8026
|
}
|
|
7526
8027
|
|
|
8028
|
+
/**
|
|
8029
|
+
* The encoding a body of `size` bytes would be compressed with — `undefined`
|
|
8030
|
+
* unless (enabled ∧ type compressible ∧ size ≥ threshold ∧ the client accepts
|
|
8031
|
+
* an encoding). Lets a caller that has not read the body yet (a static file
|
|
8032
|
+
* known only by `stat`) take the same decision `maybeCompress` takes.
|
|
8033
|
+
*/
|
|
8034
|
+
export declare const negotiatedCompression: (input: {
|
|
8035
|
+
readonly size: number;
|
|
8036
|
+
readonly contentType: string | undefined;
|
|
8037
|
+
readonly acceptEncoding: string | undefined;
|
|
8038
|
+
readonly options?: CompressionOptions | undefined;
|
|
8039
|
+
}) => NegotiatedEncoding | undefined;
|
|
8040
|
+
|
|
7527
8041
|
export declare type NegotiatedEncoding = 'br' | 'gzip';
|
|
7528
8042
|
|
|
7529
8043
|
/** Pick the encoding the client accepts — brotli preferred, gzip second,
|
|
@@ -7531,24 +8045,7 @@ export declare type NegotiatedEncoding = 'br' | 'gzip';
|
|
|
7531
8045
|
* (a client sending both accepts both). */
|
|
7532
8046
|
export declare const negotiateEncoding: (acceptEncoding: string | undefined) => NegotiatedEncoding | undefined;
|
|
7533
8047
|
|
|
7534
|
-
|
|
7535
|
-
* A fresh trace id for work that has NO incoming span to continue — a webhook
|
|
7536
|
-
* delivery, a schedule firing, a devtools invoke, a REST or gRPC entry point.
|
|
7537
|
-
*
|
|
7538
|
-
* 128 random bits as 32 lowercase hex, the shape `TRACEPARENT_RE` above accepts
|
|
7539
|
-
* and the shape a collector, a log pipeline or `voltro traces` can join on.
|
|
7540
|
-
*
|
|
7541
|
-
* The reason this exists as ONE function: every entry point that minted its own
|
|
7542
|
-
* had drifted somewhere different, and three of the shapes were not ids at all.
|
|
7543
|
-
* `incoming:<webhookId>`, `reaction:<workflow>` and the literal
|
|
7544
|
-
* `'webhooks:trigger'` are CONSTANTS — they were the caller's `source` label
|
|
7545
|
-
* copied into the id field, so every delivery a process ever handled shared one
|
|
7546
|
-
* trace and the waterfall merged unrelated work. `public-`/`grpc-`/`rest-` plus
|
|
7547
|
-
* eight base36 characters carried ~41 bits, which collides long before a busy
|
|
7548
|
-
* day is over. The entry-point kind is not lost by fixing this: it lives in the
|
|
7549
|
-
* `source` field beside the id, which is where it was already being written.
|
|
7550
|
-
*/
|
|
7551
|
-
export declare const newTraceId: () => string;
|
|
8048
|
+
export { newTraceId }
|
|
7552
8049
|
|
|
7553
8050
|
/**
|
|
7554
8051
|
* The backoff curve, extracted so it can be asserted directly — a schedule
|
|
@@ -7665,6 +8162,14 @@ export declare interface NoRowFoundInfo {
|
|
|
7665
8162
|
readonly found: number;
|
|
7666
8163
|
}
|
|
7667
8164
|
|
|
8165
|
+
/** Record a non-table input of the cached compute in flight, if any. Called by
|
|
8166
|
+
* the framework surfaces that reach outside the database. */
|
|
8167
|
+
export declare const noteCacheVolatile: (reason: string) => void;
|
|
8168
|
+
|
|
8169
|
+
/** Note that the query in flight depends on `table` without reading it
|
|
8170
|
+
* through `ctx.store`. */
|
|
8171
|
+
export declare const noteDependency: (table: string) => void;
|
|
8172
|
+
|
|
7668
8173
|
/** Note one read against the in-flight procedure. No scope → nothing happens. */
|
|
7669
8174
|
export declare const noteRead: (descriptor: QueryDescriptor) => void;
|
|
7670
8175
|
|
|
@@ -7694,6 +8199,45 @@ export declare interface Notification {
|
|
|
7694
8199
|
readonly newMatched: boolean;
|
|
7695
8200
|
}
|
|
7696
8201
|
|
|
8202
|
+
/** What a cross-environment restore did to the sealed values it cannot read. */
|
|
8203
|
+
export declare interface NullSealedReport {
|
|
8204
|
+
readonly nulled: ReadonlyArray<{
|
|
8205
|
+
readonly table: string;
|
|
8206
|
+
readonly column: string;
|
|
8207
|
+
readonly count: number;
|
|
8208
|
+
}>;
|
|
8209
|
+
readonly unreadable: ReadonlyArray<{
|
|
8210
|
+
readonly table: string;
|
|
8211
|
+
readonly column: string;
|
|
8212
|
+
readonly count: number;
|
|
8213
|
+
}>;
|
|
8214
|
+
/** Recorded key ids removed: they came with the restored data and this environment does not hold them. */
|
|
8215
|
+
readonly forgottenKeys: ReadonlyArray<string>;
|
|
8216
|
+
readonly unreadableColumns: ReadonlyArray<UnreadableColumn>;
|
|
8217
|
+
}
|
|
8218
|
+
|
|
8219
|
+
/**
|
|
8220
|
+
* After restoring another environment's database: write NULL for every whole
|
|
8221
|
+
* sealed value no configured key opens — the source ciphertext is useless here
|
|
8222
|
+
* and users re-enter it — count the sealed copies inside other values (they
|
|
8223
|
+
* cannot be nulled), and forget the restored key records and leases this
|
|
8224
|
+
* environment does not hold, so the next boot records its own keys.
|
|
8225
|
+
*/
|
|
8226
|
+
export declare const nullUnreadableSealedValues: (dialect: DialectId, keyring: FieldKeyring | undefined, declared: Iterable<unknown>) => Effect.Effect<{
|
|
8227
|
+
nulled: {
|
|
8228
|
+
table: string;
|
|
8229
|
+
column: string;
|
|
8230
|
+
count: number;
|
|
8231
|
+
}[];
|
|
8232
|
+
unreadable: {
|
|
8233
|
+
table: string;
|
|
8234
|
+
column: string;
|
|
8235
|
+
count: number;
|
|
8236
|
+
}[];
|
|
8237
|
+
forgottenKeys: string[];
|
|
8238
|
+
unreadableColumns: UnreadableColumn[];
|
|
8239
|
+
}, SqlError, SqlClient.SqlClient>;
|
|
8240
|
+
|
|
7697
8241
|
export declare interface OAuth2ConnectionDefinition extends ConnectionDefinitionCommon {
|
|
7698
8242
|
readonly kind: 'oauth2';
|
|
7699
8243
|
readonly authorizeUrl: string;
|
|
@@ -7734,6 +8278,17 @@ export declare type OAuthClientCredential = string | (() => string);
|
|
|
7734
8278
|
|
|
7735
8279
|
export declare const oauthCredentialValue: (credential: OAuthClientCredential) => string;
|
|
7736
8280
|
|
|
8281
|
+
/** Preserve the caller's environment, Exit and cancellation. Observation is
|
|
8282
|
+
* installed before the body's first primitive; it creates no detached runtime. */
|
|
8283
|
+
export declare const observeApiRoleEffect: <A, E>(effect: Effect.Effect<A, E, never>, metrics: ReturnType<typeof makeApiRoleWorkloadMetrics>, workload: ApiWorkload) => Effect.Effect<A, E, never>;
|
|
8284
|
+
|
|
8285
|
+
/**
|
|
8286
|
+
* Test seam: a ConnectionInfo layer that hands every request's headers to
|
|
8287
|
+
* `observe` and reports only the client id. It never authenticates and is not a
|
|
8288
|
+
* boot path; it lives here so ConnectionInfo keeps one construction site.
|
|
8289
|
+
*/
|
|
8290
|
+
export declare const observeConnectionHeaders: (observe: (headers: Readonly<Record<string, string | undefined>>, clientId: number) => void) => Layer.Layer<ConnectionInfoMiddleware>;
|
|
8291
|
+
|
|
7737
8292
|
/** One recorded `(procedure → table, op)` edge. */
|
|
7738
8293
|
export declare interface ObservedEdge {
|
|
7739
8294
|
readonly tag: string;
|
|
@@ -7817,6 +8372,16 @@ export declare type OnMissingRow = (info: NoRowFoundInfo) => unknown;
|
|
|
7817
8372
|
*/
|
|
7818
8373
|
export declare const onProcessShutdown: (hook: () => void | Promise<void>) => (() => void);
|
|
7819
8374
|
|
|
8375
|
+
/**
|
|
8376
|
+
* Open every envelope in one cell with `keyring` — each under the address it
|
|
8377
|
+
* was sealed under, found the same way a re-key finds it. A keyring holding the
|
|
8378
|
+
* active key alone answers "does anything still need another key?".
|
|
8379
|
+
*/
|
|
8380
|
+
export declare const openCell: (text: string, keyring: FieldKeyring, context: CellContext) => {
|
|
8381
|
+
readonly opened: number;
|
|
8382
|
+
readonly unopened: number;
|
|
8383
|
+
};
|
|
8384
|
+
|
|
7820
8385
|
/** Thrown by `.expectVersion(n).set(...)` when the optimistic-lock guard
|
|
7821
8386
|
* matched no row (the row was concurrently updated or deleted). */
|
|
7822
8387
|
export declare class OptimisticLockError extends OptimisticLockError_base {
|
|
@@ -8112,6 +8677,9 @@ export declare interface PairInput {
|
|
|
8112
8677
|
*/
|
|
8113
8678
|
export declare const parseApprovalInterval: (spec: string) => number | null;
|
|
8114
8679
|
|
|
8680
|
+
/** `unity/0.1.0; surface=<64 hex>` → its parts; anything else is not an engine SDK. */
|
|
8681
|
+
export declare const parseEngineSdkHeader: (value: string) => Omit<EngineClient, "id" | "connectedAt"> | null;
|
|
8682
|
+
|
|
8115
8683
|
/** Parse a `traceparent` header. Returns null when malformed or when
|
|
8116
8684
|
* the all-zero invalid ids are present (per the spec those are
|
|
8117
8685
|
* treated as "no parent"). */
|
|
@@ -8316,8 +8884,7 @@ export declare type ProbeKind = 'liveness' | 'readiness' | 'startup';
|
|
|
8316
8884
|
* columns, which have no wire representation at all. */
|
|
8317
8885
|
export declare const projectConnectionState: (definition: ConnectionDefinition, row: AnyRow_2 | undefined) => ConnectionState_2;
|
|
8318
8886
|
|
|
8319
|
-
|
|
8320
|
-
export declare type PropertyFilter = Readonly<Record<string, string | number | boolean | null>>;
|
|
8887
|
+
export { PropertyFilter }
|
|
8321
8888
|
|
|
8322
8889
|
export declare interface ProvenanceActor {
|
|
8323
8890
|
readonly id: string | null;
|
|
@@ -8471,8 +9038,25 @@ export declare interface PumpOptions {
|
|
|
8471
9038
|
*/
|
|
8472
9039
|
export declare const pumpOutbox: <T>(outbox: SubscriptionOutbox<T>, sink: OutboxSink<T>, label: string, options?: PumpOptions) => Promise<void>;
|
|
8473
9040
|
|
|
9041
|
+
/** A query's declared `cache:` block, structurally — see `QueryCacheConfig`. */
|
|
9042
|
+
export declare interface QueryCacheLike {
|
|
9043
|
+
readonly ttl: number | string;
|
|
9044
|
+
readonly swr?: number | string | undefined;
|
|
9045
|
+
readonly scope: ComputedCacheScope;
|
|
9046
|
+
readonly volatile?: boolean | undefined;
|
|
9047
|
+
}
|
|
9048
|
+
|
|
9049
|
+
/** A query's declared `cache:`, parsed — `undefined` when the ttl does not
|
|
9050
|
+
* parse (the cache is then off for that query; `voltro doctor` says so). */
|
|
9051
|
+
export declare const queryCachePolicy: (cache: {
|
|
9052
|
+
readonly ttl: number | string;
|
|
9053
|
+
readonly swr?: number | string | undefined;
|
|
9054
|
+
readonly scope: ComputedCacheScope;
|
|
9055
|
+
readonly volatile?: boolean | undefined;
|
|
9056
|
+
}) => ComputedQueryCachePolicy | undefined;
|
|
9057
|
+
|
|
8474
9058
|
/**
|
|
8475
|
-
* The
|
|
9059
|
+
* The read scopes, composed once, for every path that finalises a descriptor.
|
|
8476
9060
|
*
|
|
8477
9061
|
* **The primitives above were extracted so there is "no second copy that could
|
|
8478
9062
|
* drift" — and then the COMPOSITION became the second copy.** `voltro dev`
|
|
@@ -8498,6 +9082,8 @@ export declare const pumpOutbox: <T>(outbox: SubscriptionOutbox<T>, sink: Outbox
|
|
|
8498
9082
|
export declare interface QueryFinalizeOptions {
|
|
8499
9083
|
readonly tenantScopedTables: ReadonlySet<string>;
|
|
8500
9084
|
readonly softDeleteScopedTables: ReadonlySet<string>;
|
|
9085
|
+
/** Tables carrying expires(); hosts derive this set from the schema registry. */
|
|
9086
|
+
readonly expiresScopedTables?: ReadonlySet<string>;
|
|
8501
9087
|
readonly observe?: {
|
|
8502
9088
|
/** Before scoping — sees what the handler asked for. */
|
|
8503
9089
|
readonly beforeScope?: (descriptor: QueryDescriptor, subject: {
|
|
@@ -8515,6 +9101,9 @@ export declare type QueryLike<R = Row_7> = QueryDescriptor<R> | {
|
|
|
8515
9101
|
};
|
|
8516
9102
|
|
|
8517
9103
|
export declare interface QueryProducerDeps<D> {
|
|
9104
|
+
readonly workloadMetrics?: ReturnType<typeof makeApiRoleWorkloadMetrics>;
|
|
9105
|
+
/** See {@link ComputedQueryCacheDeps}. */
|
|
9106
|
+
readonly computedCache?: ComputedQueryCacheDeps;
|
|
8518
9107
|
readonly buildContext: (request: ServeRequestContext) => {
|
|
8519
9108
|
readonly store: unknown;
|
|
8520
9109
|
};
|
|
@@ -8827,6 +9416,19 @@ export declare interface ReactiveSocketTunables {
|
|
|
8827
9416
|
* (unit tests, a bare library use). */
|
|
8828
9417
|
export declare const reactiveSocketTunables: () => ReactiveSocketTunables;
|
|
8829
9418
|
|
|
9419
|
+
/** Bounded exact-incarnation read. Corruption/read failure is raised, never
|
|
9420
|
+
* flattened to no observations. Membership expiry does not delete this history. */
|
|
9421
|
+
export declare const readApiRoleWorkloadWindow: (store: DataStore, input: {
|
|
9422
|
+
readonly now: number;
|
|
9423
|
+
readonly replicaId: string;
|
|
9424
|
+
readonly startedAt: number;
|
|
9425
|
+
readonly role: string;
|
|
9426
|
+
readonly requiredWorkloads: ReadonlyArray<ApiWorkload>;
|
|
9427
|
+
}) => Promise<{
|
|
9428
|
+
buckets: ApiRoleWorkloadBucket[];
|
|
9429
|
+
assessment: ApiRoleWindowAssessment;
|
|
9430
|
+
}>;
|
|
9431
|
+
|
|
8830
9432
|
export declare interface ReadClassification {
|
|
8831
9433
|
/** Tables whose ROWS can reach the caller: the queried table and its joins. */
|
|
8832
9434
|
readonly composed: ReadonlySet<string>;
|
|
@@ -8834,6 +9436,14 @@ export declare interface ReadClassification {
|
|
|
8834
9436
|
readonly restricting: ReadonlySet<string>;
|
|
8835
9437
|
}
|
|
8836
9438
|
|
|
9439
|
+
/** Every recorded lease, live or not. */
|
|
9440
|
+
export declare const readFieldKeyHolders: (store: DataStore) => Promise<ReadonlyArray<FieldKeyHolderRecord>>;
|
|
9441
|
+
|
|
9442
|
+
export declare const readFieldKeyReports: (store: DataStore) => Promise<FieldKeyReports>;
|
|
9443
|
+
|
|
9444
|
+
/** The recorded keys, without decrypting anything. */
|
|
9445
|
+
export declare const readFieldKeys: (store: DataStore) => Promise<ReadonlyArray<FieldKeyRow>>;
|
|
9446
|
+
|
|
8837
9447
|
/** First-or-null for a boot DataStore or a query-only tuple source. It invokes
|
|
8838
9448
|
* the supplied query path, preserving that path's filters and codecs. A raw
|
|
8839
9449
|
* driver remains raw; this helper does not add request scoping. */
|
|
@@ -8973,6 +9583,12 @@ export declare const recordExternalMissed: (name: string, count?: number) => voi
|
|
|
8973
9583
|
|
|
8974
9584
|
export declare const recordExternalTrigger: (name: string, outcome: "accepted" | "duplicate" | "noOccurrence" | "ahead" | "notExternal" | "unknownSchedule") => void;
|
|
8975
9585
|
|
|
9586
|
+
/** One open of a sealed value. `key` opened it (`ok`) or was named by it (`failed`). */
|
|
9587
|
+
export declare const recordFieldDecrypt: (key: string, location: string, outcome: "ok" | "failed") => void;
|
|
9588
|
+
|
|
9589
|
+
/** Record the last count or re-key — one row per kind, replaced each time. */
|
|
9590
|
+
export declare const recordFieldKeyReport: <K extends keyof FieldKeyReports>(store: DataStore, kind: K, report: NonNullable<FieldKeyReports[K]>["report"], at?: Date) => Promise<void>;
|
|
9591
|
+
|
|
8976
9592
|
/**
|
|
8977
9593
|
* Record one emitted event into the identity's ring. Snapshots RESET the ring
|
|
8978
9594
|
* (the snapshot's revision becomes the new replay base — a client holding an
|
|
@@ -9103,76 +9719,32 @@ export declare const redactColumns: <R extends Row>(rows: ReadonlyArray<R>, reda
|
|
|
9103
9719
|
/** Blank sensitive-looking columns. Returns a new object; null passes through. */
|
|
9104
9720
|
export declare const redactRow: (row: Row_2 | null | undefined) => Row_2 | null;
|
|
9105
9721
|
|
|
9106
|
-
/**
|
|
9107
|
-
* Options for `redisRywPositionStore`. The store needs TWO Redis
|
|
9108
|
-
* connections because `SUBSCRIBE` puts a client in a mode where only
|
|
9109
|
-
* (P)SUB / UNSUB / PING / QUIT are valid — sharing one client across
|
|
9110
|
-
* writes and the subscribe loop would deadlock. Pass the same client
|
|
9111
|
-
* for both unless you've separated them yourself.
|
|
9112
|
-
*/
|
|
9722
|
+
/** Registry-owned command facade and one borrowed Pub/Sub consumer. */
|
|
9113
9723
|
export declare interface RedisRywOptions {
|
|
9114
|
-
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
/**
|
|
9120
|
-
* Separate connection dedicated to the SUBSCRIBE loop. Pass a fresh
|
|
9121
|
-
* `client.duplicate()` of the main connection; the store does NOT
|
|
9122
|
-
* duplicate internally because callers may want to manage the
|
|
9123
|
-
* subscription connection's lifecycle separately.
|
|
9124
|
-
*/
|
|
9125
|
-
readonly subscriber: Redis;
|
|
9126
|
-
/**
|
|
9127
|
-
* Redis key prefix — every entry stores under `${keyPrefix}:<subjectKey>`.
|
|
9128
|
-
* Defaults to `'voltro:ryw'`. Override to namespace per-app when
|
|
9129
|
-
* multiple deployments share a Redis.
|
|
9130
|
-
*/
|
|
9131
|
-
readonly keyPrefix?: string;
|
|
9132
|
-
/**
|
|
9133
|
-
* Pub/sub channel name. Defaults to `${keyPrefix}:bus`. All nodes
|
|
9134
|
-
* sharing an RYW state MUST agree on this name.
|
|
9135
|
-
*/
|
|
9724
|
+
readonly client: RespClient;
|
|
9725
|
+
readonly pubsub: RedisPubSub;
|
|
9726
|
+
/** Application/environment namespace. Required; never shared implicitly. */
|
|
9727
|
+
readonly keyPrefix: string;
|
|
9728
|
+
/** Defaults to `${keyPrefix}:bus`; all participating processes must agree. */
|
|
9136
9729
|
readonly channel?: string;
|
|
9137
|
-
/** Clock injection for tests. Defaults to `Date.now`. */
|
|
9138
9730
|
readonly now?: () => number;
|
|
9139
|
-
/**
|
|
9140
|
-
* Called when a Redis-side error occurs (publish/setex/subscribe
|
|
9141
|
-
* failure). RYW degrades gracefully — local writes still succeed,
|
|
9142
|
-
* other instances just won't see this node's writes until the next
|
|
9143
|
-
* one. Hook for observability; default is a console.warn.
|
|
9144
|
-
*/
|
|
9731
|
+
/** Local writes survive remote failures. Failed mutations are never replayed. */
|
|
9145
9732
|
readonly onError?: (error: unknown, op: 'set' | 'delete' | 'subscribe' | 'parse') => void;
|
|
9146
9733
|
}
|
|
9147
9734
|
|
|
9735
|
+
export declare interface RedisRywPositionStore extends RywPositionStore {
|
|
9736
|
+
/** Drain accepted writes and release this consumer, leaving shared sockets open. */
|
|
9737
|
+
readonly close: () => Promise<void>;
|
|
9738
|
+
}
|
|
9739
|
+
|
|
9148
9740
|
/**
|
|
9149
|
-
*
|
|
9150
|
-
*
|
|
9151
|
-
*
|
|
9152
|
-
*
|
|
9153
|
-
*
|
|
9154
|
-
* 1. write to local map (immediate, sync)
|
|
9155
|
-
* 2. fire-and-forget SETEX in Redis with millisecond TTL
|
|
9156
|
-
* 3. fire-and-forget PUBLISH on the channel — peers update
|
|
9157
|
-
* their local mirror without round-tripping Redis again
|
|
9158
|
-
* - on `delete(key)`:
|
|
9159
|
-
* 1. remove from local map
|
|
9160
|
-
* 2. fire-and-forget DEL + PUBLISH
|
|
9161
|
-
* - on `get(key)`:
|
|
9162
|
-
* 1. read from local map; lazy-evict if expired
|
|
9163
|
-
*
|
|
9164
|
-
* The SUBSCRIBE loop receives self-publishes (Redis sends them back
|
|
9165
|
-
* to the sender). Each entry carries a `senderId`; the local node
|
|
9166
|
-
* filters out its own broadcasts so we don't double-apply.
|
|
9167
|
-
*
|
|
9168
|
-
* On boot the local mirror is EMPTY. A read for a subject whose write
|
|
9169
|
-
* happened on a peer node before this node started will miss the
|
|
9170
|
-
* mirror — but `ReplicatedDataStore` falls back to primary on
|
|
9171
|
-
* "no position", so the worst-case is "one extra primary read on the
|
|
9172
|
-
* very first request that touches a peer-written subject". After that
|
|
9173
|
-
* read, this node's own writes propagate normally.
|
|
9741
|
+
* Subscribe before returning. Reads consult only the process-local mirror.
|
|
9742
|
+
* Writes update it synchronously, then enqueue PSETEX/DEL followed by PUBLISH.
|
|
9743
|
+
* Pub/Sub is eventual and cannot replay lost messages or rebuild a new mirror.
|
|
9744
|
+
* A missing position still follows replica routing under fallback and wait;
|
|
9745
|
+
* neither policy establishes cross-process read-your-writes before delivery.
|
|
9174
9746
|
*/
|
|
9175
|
-
export declare const redisRywPositionStore: (options: RedisRywOptions) =>
|
|
9747
|
+
export declare const redisRywPositionStore: (options: RedisRywOptions) => Effect.Effect<RedisRywPositionStore, KvError>;
|
|
9176
9748
|
|
|
9177
9749
|
/** `__voltro.undo.redo` — re-apply a previously-undone invocation's forward
|
|
9178
9750
|
* changes. Idempotent if not currently undone. */
|
|
@@ -9226,7 +9798,15 @@ export declare const registerConnectionStream: (clientId: number, interrupt: ()
|
|
|
9226
9798
|
*/
|
|
9227
9799
|
export declare const registerDefaultTupleSource: (source: TupleSource) => boolean;
|
|
9228
9800
|
|
|
9229
|
-
|
|
9801
|
+
/** Process-level callers share the same map even across duplicated modules. */
|
|
9802
|
+
export declare const registerExternalizedTask: (task: ExternalizedTask) => (() => void);
|
|
9803
|
+
|
|
9804
|
+
/**
|
|
9805
|
+
* Record a key ahead of the deploy that brings it, as `pending`, with its
|
|
9806
|
+
* canary — so the first boot that holds it verifies its material, and the
|
|
9807
|
+
* configuration without it still boots (nothing is sealed under a pending key).
|
|
9808
|
+
*/
|
|
9809
|
+
export declare const registerFieldKey: (store: DataStore, keyring: FieldKeyring, keyId: string) => Promise<void>;
|
|
9230
9810
|
|
|
9231
9811
|
export { registerRetention }
|
|
9232
9812
|
|
|
@@ -9323,6 +9903,37 @@ export declare interface RegistryTableLike {
|
|
|
9323
9903
|
* request was. */
|
|
9324
9904
|
export declare const rehydrateGuards: (serialized: ReadonlyArray<SerializedGuard>) => ReadonlyArray<AnyGuardSpec>;
|
|
9325
9905
|
|
|
9906
|
+
/**
|
|
9907
|
+
* Re-seal every envelope in one cell that is not under the active key, or
|
|
9908
|
+
* names no key, under the active key and the address it was sealed under.
|
|
9909
|
+
*/
|
|
9910
|
+
export declare const rekeyCell: (text: string, keyring: FieldKeyring, context: CellContext) => CellRekey;
|
|
9911
|
+
|
|
9912
|
+
export declare interface RekeyReport {
|
|
9913
|
+
readonly active: string;
|
|
9914
|
+
readonly locations: ReadonlyArray<LocationRekey>;
|
|
9915
|
+
readonly unreadable: ReadonlyArray<UnreadableColumn>;
|
|
9916
|
+
}
|
|
9917
|
+
|
|
9918
|
+
/**
|
|
9919
|
+
* Re-key every discovered location under the keyring's active key. With
|
|
9920
|
+
* `dryRun`, count what would change and write nothing.
|
|
9921
|
+
*/
|
|
9922
|
+
export declare const rekeySealedValues: (dialect: DialectId, keyring: FieldKeyring, declared: Iterable<unknown>, options?: {
|
|
9923
|
+
readonly dryRun?: boolean;
|
|
9924
|
+
readonly onProgress?: (location: LocationRekey) => void;
|
|
9925
|
+
/** Runs between reading a cell and writing it back — where another writer may change it. */
|
|
9926
|
+
readonly beforeWrite?: (cell: {
|
|
9927
|
+
readonly table: string;
|
|
9928
|
+
readonly column: string;
|
|
9929
|
+
readonly rowId: unknown;
|
|
9930
|
+
}) => Effect.Effect<void, unknown, SqlClient.SqlClient>;
|
|
9931
|
+
}) => Effect.Effect<{
|
|
9932
|
+
active: string;
|
|
9933
|
+
locations: LocationRekey[];
|
|
9934
|
+
unreadable: UnreadableColumn[];
|
|
9935
|
+
}, SqlError, SqlClient.SqlClient>;
|
|
9936
|
+
|
|
9326
9937
|
/** The store slice `applyDeclaredRelations` needs. `columns` is the junction's
|
|
9327
9938
|
* DERIVED reference pair — the truth the descriptor's declaration is checked
|
|
9328
9939
|
* against before anything is written. */
|
|
@@ -9345,6 +9956,9 @@ export declare interface RelationTuple {
|
|
|
9345
9956
|
readonly resourceId: string;
|
|
9346
9957
|
}
|
|
9347
9958
|
|
|
9959
|
+
/** Give up this process's lease — on shutdown, so nobody waits for it. */
|
|
9960
|
+
export declare const releaseFieldKeyHolder: (store: DataStore, holderId: string) => Promise<void>;
|
|
9961
|
+
|
|
9348
9962
|
/**
|
|
9349
9963
|
* Release a claim back to `pending` (CAS `fired → pending`) — used when
|
|
9350
9964
|
* the wake failed, so the next poll retries it (at-least-once wake). The
|
|
@@ -9435,6 +10049,7 @@ export declare interface ReplicaSelector {
|
|
|
9435
10049
|
}
|
|
9436
10050
|
|
|
9437
10051
|
export declare class ReplicatedDataStore implements DataStore {
|
|
10052
|
+
readonly integrityQuery?: NonNullable<DataStore['integrityQuery']>;
|
|
9438
10053
|
private readonly primary;
|
|
9439
10054
|
private readonly replicas;
|
|
9440
10055
|
private readonly adapter;
|
|
@@ -9446,12 +10061,13 @@ export declare class ReplicatedDataStore implements DataStore {
|
|
|
9446
10061
|
private readonly health;
|
|
9447
10062
|
private readonly recordRouting?;
|
|
9448
10063
|
private readonly now;
|
|
10064
|
+
private closing;
|
|
9449
10065
|
constructor(options: ReplicatedDataStoreOptions);
|
|
9450
10066
|
query(descriptor: QueryDescriptor): Promise<ReadonlyArray<Row>>;
|
|
9451
10067
|
private routeToReplica;
|
|
9452
10068
|
private routeWaitMode;
|
|
9453
10069
|
insert(table: string, row: Row): Promise<Row>;
|
|
9454
|
-
insertMany(table: string, rows: ReadonlyArray<Row
|
|
10070
|
+
insertMany(table: string, rows: ReadonlyArray<Row>, options?: InsertManyOptions): Promise<ReadonlyArray<Row>>;
|
|
9455
10071
|
patchJson(table: string, primaryKey: string, path: string, value: unknown, additionalPatch?: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
9456
10072
|
update(table: string, primaryKey: string, patch: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
9457
10073
|
delete(table: string, primaryKey: string): Promise<boolean>;
|
|
@@ -9476,6 +10092,8 @@ export declare class ReplicatedDataStore implements DataStore {
|
|
|
9476
10092
|
injectExternalChange(event: ChangeEvent): void;
|
|
9477
10093
|
/** Forwarded from the primary — see DataStore.changeScope. */
|
|
9478
10094
|
get changeScope(): 'local' | 'fleet';
|
|
10095
|
+
/** Drain the RYW consumer before closing every SQL pool; repeated close is shared. */
|
|
10096
|
+
close(gracePeriodMs?: number): Promise<void>;
|
|
9479
10097
|
private stampPostWrite;
|
|
9480
10098
|
private emitRouting;
|
|
9481
10099
|
}
|
|
@@ -9557,8 +10175,8 @@ export declare interface ResendOptions {
|
|
|
9557
10175
|
readonly attempts?: number;
|
|
9558
10176
|
}
|
|
9559
10177
|
|
|
9560
|
-
/**
|
|
9561
|
-
export declare const
|
|
10178
|
+
/** Test seam: back to the boot default. */
|
|
10179
|
+
export declare const resetComputedQueryCacheCaptureForTests: () => void;
|
|
9562
10180
|
|
|
9563
10181
|
/** Test/dev-only — clear ALL per-connection state. Don't call from app code. */
|
|
9564
10182
|
export declare const _resetConnectionCredentialsForTest: () => void;
|
|
@@ -9569,6 +10187,9 @@ export declare const resetDetachedForTest: () => void;
|
|
|
9569
10187
|
/** Test seams for the tag-cache guard — the cache is module-private otherwise. */
|
|
9570
10188
|
export declare const resetEventMetricTagCacheForTests: () => void;
|
|
9571
10189
|
|
|
10190
|
+
/** Test seam. */
|
|
10191
|
+
export declare const resetFieldDecryptCountsForTests: () => void;
|
|
10192
|
+
|
|
9572
10193
|
/** Drop everything recorded. For tests; not called by the runtime. */
|
|
9573
10194
|
export declare const resetObservedGraph: () => void;
|
|
9574
10195
|
|
|
@@ -9772,6 +10393,15 @@ export declare interface ResolvedWorkflowCallerContext extends WorkflowCallerCon
|
|
|
9772
10393
|
readonly rowFilter: RowFilterScope;
|
|
9773
10394
|
}
|
|
9774
10395
|
|
|
10396
|
+
/**
|
|
10397
|
+
* The keyring an environment configures, or `undefined` when it configures no
|
|
10398
|
+
* key at all. Refuses (`FieldKeyringConfigError`, never containing key material)
|
|
10399
|
+
* an unknown or missing active id, a duplicate id, one key under two ids,
|
|
10400
|
+
* `KEY` equal to `_PREVIOUS`, and a `KEY`/`_PREVIOUS` set beside `KEYS` that
|
|
10401
|
+
* `KEYS` does not contain.
|
|
10402
|
+
*/
|
|
10403
|
+
export declare const resolveFieldKeyring: (env: Readonly<Record<string, string | undefined>>) => FieldKeyringConfig | undefined;
|
|
10404
|
+
|
|
9775
10405
|
/**
|
|
9776
10406
|
* Resolve the app's health block against the boot path's own readiness flag.
|
|
9777
10407
|
*
|
|
@@ -10042,6 +10672,15 @@ export { RetentionSpec }
|
|
|
10042
10672
|
|
|
10043
10673
|
export { retentionTtlMsFromEnv }
|
|
10044
10674
|
|
|
10675
|
+
/**
|
|
10676
|
+
* Retire a key: nothing may be sealed under it again, and a configuration may
|
|
10677
|
+
* drop it — the boot no longer asks for it. Refused for the active key, a key
|
|
10678
|
+
* nobody recorded, and a key a live process still seals new values under (it
|
|
10679
|
+
* has not adopted the new key yet). Whether VALUES are still sealed under it is
|
|
10680
|
+
* the caller's question to answer first (`voltro secret retire` counts them).
|
|
10681
|
+
*/
|
|
10682
|
+
export declare const retireFieldKey: (store: DataStore, keyId: string, holder?: Pick<FieldKeyHolder, "now">) => Promise<void>;
|
|
10683
|
+
|
|
10045
10684
|
/**
|
|
10046
10685
|
* Drop the ISR cache entries for a path on every `voltro start` replica.
|
|
10047
10686
|
*
|
|
@@ -10349,6 +10988,8 @@ export declare interface RpcConnection {
|
|
|
10349
10988
|
|
|
10350
10989
|
export declare interface RpcServerOptions<Rpcs extends Rpc.Any> {
|
|
10351
10990
|
readonly group: RpcGroup.RpcGroup<Rpcs>;
|
|
10991
|
+
/** Executable RPC surfaces for this replica; omitted retains both transports. */
|
|
10992
|
+
readonly workloadAdmission?: RpcWorkloadAdmission;
|
|
10352
10993
|
readonly handlersLayer: Layer.Layer<Rpc.ToHandler<Rpcs>>;
|
|
10353
10994
|
/** Optional handlers layer dedicated to the one-shot HTTP rpc surface
|
|
10354
10995
|
* (`POST /rpc`, used by SSR web-router loaders). The HTTP JSON protocol
|
|
@@ -10544,6 +11185,14 @@ export declare interface RpcServerOptions<Rpcs extends Rpc.Any> {
|
|
|
10544
11185
|
readonly security?: TransportSecurityOptions;
|
|
10545
11186
|
}
|
|
10546
11187
|
|
|
11188
|
+
export declare interface RpcWorkloadAdmission {
|
|
11189
|
+
readonly rpc: boolean;
|
|
11190
|
+
readonly subscriptions: boolean;
|
|
11191
|
+
/** Event streams are independent of live query subscriptions. */
|
|
11192
|
+
readonly events?: boolean;
|
|
11193
|
+
readonly routes?: ReadonlyArray<string>;
|
|
11194
|
+
}
|
|
11195
|
+
|
|
10547
11196
|
/**
|
|
10548
11197
|
* Rules that apply to one change, or an empty list.
|
|
10549
11198
|
*
|
|
@@ -10628,6 +11277,10 @@ export declare const runSingleNodeOrchestrator: (opts: SingleNodeOrchestratorOpt
|
|
|
10628
11277
|
export declare const RUNTIME_NAME: "framework-runtime";
|
|
10629
11278
|
|
|
10630
11279
|
export declare interface RuntimeContext {
|
|
11280
|
+
/** Effective incoming Cookie header for server-side signature verification.
|
|
11281
|
+
* Unverified private input; never return, log or persist it. Optional for
|
|
11282
|
+
* internal callers and cookie-less requests. */
|
|
11283
|
+
readonly cookieHeader?: string;
|
|
10631
11284
|
/** Subscription / call subject — user, API key, service account, or anonymous. */
|
|
10632
11285
|
readonly subject: Subject;
|
|
10633
11286
|
/** Trace identifier — the active span's W3C trace id (32 hex) when
|
|
@@ -10761,6 +11414,8 @@ export declare interface RywPositionStore {
|
|
|
10761
11414
|
delete(subjectKey: string): void;
|
|
10762
11415
|
/** Approximate size for observability + tests. */
|
|
10763
11416
|
size(): number;
|
|
11417
|
+
/** Release consumer resources when this store owns any. */
|
|
11418
|
+
readonly close?: () => Promise<void>;
|
|
10764
11419
|
}
|
|
10765
11420
|
|
|
10766
11421
|
/**
|
|
@@ -10933,6 +11588,8 @@ export declare type ScheduleHandler = (ctx: ScheduleContext) => void | Promise<v
|
|
|
10933
11588
|
export declare type ScheduleOverlapPolicy = 'skip' | 'queue' | 'parallel';
|
|
10934
11589
|
|
|
10935
11590
|
export declare interface SchedulerDeps {
|
|
11591
|
+
/** Active synchronous handler entry only; never await a Promise inside this measurement. */
|
|
11592
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
10936
11593
|
/** App-owned service environment; the signal interrupts Effect work on timeout. */
|
|
10937
11594
|
readonly runEffect?: (effect: Extract<ReturnType<ScheduleHandler>, Effect.Effect<unknown, unknown, unknown>>, signal: AbortSignal) => Promise<unknown>;
|
|
10938
11595
|
readonly store: DataStore;
|
|
@@ -11044,6 +11701,8 @@ export declare interface SchedulerDeps {
|
|
|
11044
11701
|
}
|
|
11045
11702
|
|
|
11046
11703
|
export declare interface SchedulerHandle {
|
|
11704
|
+
/** Completed startup and shutdown has not begun; not a successful-job claim. */
|
|
11705
|
+
isRunning(): boolean;
|
|
11047
11706
|
/** Fire a schedule immediately, bypassing the cron clock + the
|
|
11048
11707
|
* coordinator. Waits for handler completion and returns the recorded run id. */
|
|
11049
11708
|
fireNow(name: string, trigger: ScheduleTrigger | 'manual'): Promise<string | undefined>;
|
|
@@ -11349,6 +12008,22 @@ declare interface ScopeCtx {
|
|
|
11349
12008
|
/** The scope strings a UI shows ("ask someone with …"). */
|
|
11350
12009
|
export declare const scopeStringsOf: (serialized: ReadonlyArray<SerializedGuard>) => ReadonlyArray<string>;
|
|
11351
12010
|
|
|
12011
|
+
/** One column that holds envelopes, and what is under which key in it. */
|
|
12012
|
+
export declare interface SealedLocation {
|
|
12013
|
+
readonly table: string;
|
|
12014
|
+
readonly column: string;
|
|
12015
|
+
/** The app declares it `.encrypted()` (a whole cell is one value), rather than a place found holding envelopes. */
|
|
12016
|
+
readonly declared: boolean;
|
|
12017
|
+
/** Cells holding at least one envelope. */
|
|
12018
|
+
readonly cells: number;
|
|
12019
|
+
/** Envelopes, counted per key id. */
|
|
12020
|
+
readonly byKey: Readonly<Record<string, number>>;
|
|
12021
|
+
/** Envelopes written before envelopes named their key. */
|
|
12022
|
+
readonly unnamed: number;
|
|
12023
|
+
/** Declared `.encrypted()` only: non-null cells that are not an envelope. */
|
|
12024
|
+
readonly plaintext: number;
|
|
12025
|
+
}
|
|
12026
|
+
|
|
11352
12027
|
export declare interface SecretsBackend {
|
|
11353
12028
|
/** Resolve a secret by key. `undefined` when absent. */
|
|
11354
12029
|
readonly get: (key: string) => Promise<string | undefined>;
|
|
@@ -11488,6 +12163,8 @@ export declare type SerializedGuard = {
|
|
|
11488
12163
|
readonly resource: string | null;
|
|
11489
12164
|
} | {
|
|
11490
12165
|
readonly kind: 'authenticated';
|
|
12166
|
+
} | {
|
|
12167
|
+
readonly kind: 'upgraded';
|
|
11491
12168
|
};
|
|
11492
12169
|
|
|
11493
12170
|
/**
|
|
@@ -11507,6 +12184,14 @@ export declare type ServeMutationCommitHook = (context: Parameters<ServeRpcInter
|
|
|
11507
12184
|
}) => Effect.Effect<void, unknown>;
|
|
11508
12185
|
|
|
11509
12186
|
export declare interface ServeRequestContext {
|
|
12187
|
+
/** Listener-owned identity; used only for measurement attribution here. */
|
|
12188
|
+
readonly connection?: {
|
|
12189
|
+
readonly transport: 'http' | 'websocket';
|
|
12190
|
+
};
|
|
12191
|
+
/** Effective incoming Cookie header for server-side signature verification.
|
|
12192
|
+
* Unverified private input; never return, log or persist it. Optional for
|
|
12193
|
+
* internal callers and cookie-less requests. */
|
|
12194
|
+
readonly cookieHeader?: string;
|
|
11510
12195
|
readonly subject: unknown;
|
|
11511
12196
|
readonly traceId: string;
|
|
11512
12197
|
readonly spanId?: string;
|
|
@@ -11565,7 +12250,7 @@ export declare const serverOnlyLeaks: (query: AuditableQuery, serverOnlyByTable:
|
|
|
11565
12250
|
/** A plugin interceptor — wraps the base run Effect (Effect-native chain). */
|
|
11566
12251
|
export declare type ServeRpcInterceptor = (base: Effect.Effect<unknown, unknown, never>, meta: {
|
|
11567
12252
|
readonly tag: string;
|
|
11568
|
-
readonly kind: 'mutation' | 'action' | 'query' | 'workflow';
|
|
12253
|
+
readonly kind: 'mutation' | 'action' | 'query' | 'workflow' | 'stream';
|
|
11569
12254
|
readonly input: unknown;
|
|
11570
12255
|
readonly subject: unknown;
|
|
11571
12256
|
readonly traceId: string;
|
|
@@ -11781,8 +12466,14 @@ export declare interface SingleNodeOrchestratorOptions {
|
|
|
11781
12466
|
export declare interface SnapshotCache {
|
|
11782
12467
|
readonly wrap: (binding: SnapshotCacheBinding, tags: ReadonlyArray<string>, compute: () => Promise<ReadonlyArray<Row>>) => Promise<ReadonlyArray<Row>>;
|
|
11783
12468
|
/** Write-through from the live recompute, so the cache is never staler
|
|
11784
|
-
* than the freshest live subscriber. Fire-and-forget.
|
|
11785
|
-
|
|
12469
|
+
* than the freshest live subscriber. Fire-and-forget. `fence` is the
|
|
12470
|
+
* cache's invalidation position observed BEFORE the rows were read: a
|
|
12471
|
+
* later invalidation of any tag voids the write, so an earlier, slower
|
|
12472
|
+
* read can never overwrite a later one. */
|
|
12473
|
+
readonly put: (binding: SnapshotCacheBinding, tags: ReadonlyArray<string>, rows: ReadonlyArray<Row>, fence: number) => void;
|
|
12474
|
+
/** The cache's invalidation position — observed before a read whose rows
|
|
12475
|
+
* will be written through. */
|
|
12476
|
+
readonly fence: () => Promise<number>;
|
|
11786
12477
|
}
|
|
11787
12478
|
|
|
11788
12479
|
/**
|
|
@@ -11794,6 +12485,8 @@ export declare interface SnapshotCacheBinding {
|
|
|
11794
12485
|
readonly key: string;
|
|
11795
12486
|
readonly ttlMs: number;
|
|
11796
12487
|
readonly swrMs: number | undefined;
|
|
12488
|
+
/** The query name its counters are kept under (`queryStats`, metrics). */
|
|
12489
|
+
readonly label?: string | undefined;
|
|
11797
12490
|
}
|
|
11798
12491
|
|
|
11799
12492
|
/**
|
|
@@ -11805,6 +12498,20 @@ export declare const snapshotCrdt: (store: CrdtHistoryStore, cell: CrdtCellRef &
|
|
|
11805
12498
|
readonly createdBy?: string;
|
|
11806
12499
|
}) => Promise<CrdtVersion | undefined>;
|
|
11807
12500
|
|
|
12501
|
+
/**
|
|
12502
|
+
* The entry a READ belongs to: the rpc layer's scoped key plus the descriptor
|
|
12503
|
+
* actually read.
|
|
12504
|
+
*
|
|
12505
|
+
* The rpc key names the query, its input and the scope (subject / tenant /
|
|
12506
|
+
* global) — but not what the caller may SEE. A registered row filter makes two
|
|
12507
|
+
* colleagues of one tenant read different rows through the same `'tenant'` key,
|
|
12508
|
+
* and keying by the rpc key alone served the first colleague's filtered rows to
|
|
12509
|
+
* the next one. The read descriptor carries every predicate the caller's
|
|
12510
|
+
* visibility added, so two readers share an entry exactly when they read the
|
|
12511
|
+
* same thing.
|
|
12512
|
+
*/
|
|
12513
|
+
export declare const snapshotEntryFor: (binding: SnapshotCacheBinding, read: QueryDescriptor) => SnapshotCacheBinding;
|
|
12514
|
+
|
|
11808
12515
|
/** Snapshot the whole registry, normalized to `MetricSample[]` — plus the
|
|
11809
12516
|
* socket-backpressure counters (`subscriptionSocketMetrics.ts`), appended
|
|
11810
12517
|
* HERE so every reader (Prometheus exporter, inspect Metrics panel) sees
|
|
@@ -11842,32 +12549,23 @@ export declare class SsrfBlockedError extends Error {
|
|
|
11842
12549
|
*/
|
|
11843
12550
|
export declare const ssrfGuardHttpClientLayer: (policy?: SsrfPolicy) => Layer.Layer<HttpClient.HttpClient, never, HttpClient.HttpClient>;
|
|
11844
12551
|
|
|
11845
|
-
export
|
|
11846
|
-
|
|
11847
|
-
|
|
11848
|
-
* (`billing.internal`), a suffix wildcard (`*.svc.cluster.local`), or a
|
|
11849
|
-
* host:port (`127.0.0.1:8787`) when only one port should be reachable.
|
|
11850
|
-
*
|
|
11851
|
-
* This is the one escape hatch, and it is deliberately per-HOST rather than a
|
|
11852
|
-
* boolean: "we call one internal service" and "we do not check URLs" are very
|
|
11853
|
-
* different postures, and a boolean cannot tell them apart six months later.
|
|
11854
|
-
*/
|
|
11855
|
-
readonly allowHosts?: ReadonlyArray<string>;
|
|
11856
|
-
/** Max redirect hops to follow. Each one is revalidated. Default 5. */
|
|
11857
|
-
readonly maxRedirects?: number;
|
|
11858
|
-
}
|
|
12552
|
+
export { SsrfPolicy }
|
|
12553
|
+
|
|
12554
|
+
export { ssrfReason }
|
|
11859
12555
|
|
|
11860
12556
|
/**
|
|
11861
|
-
*
|
|
11862
|
-
*
|
|
11863
|
-
*
|
|
11864
|
-
* DNS is deliberately NOT resolved — this is a synchronous check on the literal
|
|
11865
|
-
* target, so a hostname that RESOLVES to a private address (DNS rebinding) is not
|
|
11866
|
-
* caught here. Blocking the direct-IP vector is the high-severity, cheap half;
|
|
11867
|
-
* rebinding needs network-layer egress control and is called out in the docs
|
|
11868
|
-
* rather than silently implied.
|
|
12557
|
+
* Heartbeat every {@link FIELD_KEY_HEARTBEAT_MS} for as long as the process
|
|
12558
|
+
* runs. Logs a transition once — a key that became active, a key still waiting
|
|
12559
|
+
* and for whom, an active key this process does not hold — never every beat.
|
|
11869
12560
|
*/
|
|
11870
|
-
export declare const
|
|
12561
|
+
export declare const startFieldKeyHolder: (store: DataStore, keyring: FieldKeyring, holder: FieldKeyHolder & {
|
|
12562
|
+
readonly intervalMs?: number;
|
|
12563
|
+
readonly log: {
|
|
12564
|
+
readonly info: (message: string) => void;
|
|
12565
|
+
readonly warn: (message: string) => void;
|
|
12566
|
+
readonly error: (message: string) => void;
|
|
12567
|
+
};
|
|
12568
|
+
}) => FieldKeyHolderHandle;
|
|
11871
12569
|
|
|
11872
12570
|
/**
|
|
11873
12571
|
* Start the rpc-based runtime server on Node. Composes:
|
|
@@ -11922,6 +12620,8 @@ export declare interface StartupSnapshot {
|
|
|
11922
12620
|
readonly elapsedMs: number;
|
|
11923
12621
|
readonly tablesTotal?: number;
|
|
11924
12622
|
readonly error?: string;
|
|
12623
|
+
/** Requests waiting for the boot to finish — present only while some do. */
|
|
12624
|
+
readonly held?: number;
|
|
11925
12625
|
}
|
|
11926
12626
|
|
|
11927
12627
|
/**
|
|
@@ -12097,6 +12797,12 @@ export declare interface SubscriberDefinition {
|
|
|
12097
12797
|
readonly table: string;
|
|
12098
12798
|
/** Default `'any'`. */
|
|
12099
12799
|
readonly on?: SubscribeOp | ReadonlyArray<Exclude<SubscribeOp, 'any'>>;
|
|
12800
|
+
/** Bind this invocation's event publisher to the trusted committed row's
|
|
12801
|
+
* tenant. No client input is available here. Omitted keeps system/global
|
|
12802
|
+
* publication. This does not change ctx.store's system identity or turn a
|
|
12803
|
+
* best-effort subscriber into durable delivery. Invalid results refuse the
|
|
12804
|
+
* handler rather than publishing into the global partition. */
|
|
12805
|
+
readonly eventTenant?: (event: SubscribeEvent) => string | null;
|
|
12100
12806
|
/**
|
|
12101
12807
|
* Run the handler ONCE PER CHANGE across the whole fleet, instead of once on
|
|
12102
12808
|
* every replica that sees it.
|
|
@@ -12446,7 +13152,7 @@ export declare const tenantSelectionStore: (getStore: () => DataStore | undefine
|
|
|
12446
13152
|
* a page. */
|
|
12447
13153
|
export declare const TERMINAL_RUN_STATUSES: ReadonlySet<string>;
|
|
12448
13154
|
|
|
12449
|
-
export
|
|
13155
|
+
export { TimeBucket }
|
|
12450
13156
|
|
|
12451
13157
|
export declare interface TimelineEvent {
|
|
12452
13158
|
/** Preserves the store's warning that images are not original commit images. */
|
|
@@ -12512,29 +13218,11 @@ export declare class TimelineRecorder {
|
|
|
12512
13218
|
replay(table: string, asOfSeq: number, currentRows: ReadonlyArray<Row_2>): ReadonlyArray<Row_2>;
|
|
12513
13219
|
}
|
|
12514
13220
|
|
|
12515
|
-
|
|
12516
|
-
export declare interface TimeRange {
|
|
12517
|
-
readonly from: Date;
|
|
12518
|
-
readonly to?: Date;
|
|
12519
|
-
}
|
|
13221
|
+
export { TimeRange }
|
|
12520
13222
|
|
|
12521
|
-
export
|
|
12522
|
-
readonly bucket: TimeBucket;
|
|
12523
|
-
}
|
|
13223
|
+
export { TimeseriesQuery }
|
|
12524
13224
|
|
|
12525
|
-
export
|
|
12526
|
-
readonly event: string;
|
|
12527
|
-
/** Property to group by (must be a string-valued property). */
|
|
12528
|
-
readonly groupBy: string;
|
|
12529
|
-
readonly metric: 'count' | {
|
|
12530
|
-
readonly sum: string;
|
|
12531
|
-
};
|
|
12532
|
-
readonly n: number;
|
|
12533
|
-
readonly range: TimeRange;
|
|
12534
|
-
readonly filter?: PropertyFilter;
|
|
12535
|
-
/** Tenant scope — injected by `useAnalytics()`; see {@link AggregateQuery.tenantId}. */
|
|
12536
|
-
readonly tenantId?: string | null;
|
|
12537
|
-
}
|
|
13225
|
+
export { TopNQuery }
|
|
12538
13226
|
|
|
12539
13227
|
/** A row a mutation wrote, carried to rule evaluation. `row` is the POST-WRITE
|
|
12540
13228
|
* state (insert result / update result). */
|
|
@@ -12986,7 +13674,11 @@ export declare class UndoStack<E> {
|
|
|
12986
13674
|
*/
|
|
12987
13675
|
export declare const undoSurfaceEnabled: (env?: Record<string, string | undefined>) => boolean;
|
|
12988
13676
|
|
|
12989
|
-
export declare
|
|
13677
|
+
export declare interface UnreadableColumn {
|
|
13678
|
+
readonly table: string;
|
|
13679
|
+
readonly column: string;
|
|
13680
|
+
readonly reason: string;
|
|
13681
|
+
}
|
|
12990
13682
|
|
|
12991
13683
|
/** One `source:` entry that resolves to no declared table. */
|
|
12992
13684
|
export declare interface UnresolvedSource {
|
|
@@ -12999,6 +13691,8 @@ export declare interface UnresolvedSource {
|
|
|
12999
13691
|
/** True when the name is in the `channel:` namespace: it named a reactivity
|
|
13000
13692
|
* channel nobody declared, which is a different repair from a stale table. */
|
|
13001
13693
|
readonly channel: boolean;
|
|
13694
|
+
/** Intentionally optional integration observation, retained in source. */
|
|
13695
|
+
readonly optional?: true;
|
|
13002
13696
|
}
|
|
13003
13697
|
|
|
13004
13698
|
/**
|
|
@@ -13010,6 +13704,7 @@ export declare interface UnresolvedSource {
|
|
|
13010
13704
|
export declare const unresolvedSources: (procedures: ReadonlyArray<{
|
|
13011
13705
|
readonly name: string;
|
|
13012
13706
|
readonly source: string | ReadonlyArray<string> | undefined;
|
|
13707
|
+
readonly optionalSource?: ReadonlyArray<string>;
|
|
13013
13708
|
}>, declared: ReadonlySet<string>) => ReadonlyArray<UnresolvedSource>;
|
|
13014
13709
|
|
|
13015
13710
|
/** Thrown at boot; the message is the whole point, so it names the path and the
|
|
@@ -13091,6 +13786,27 @@ export declare type VerificationDeclared<T> = T & {
|
|
|
13091
13786
|
readonly [WEBHOOK_VERIFICATION_PROPERTY]: WebhookVerification;
|
|
13092
13787
|
};
|
|
13093
13788
|
|
|
13789
|
+
/**
|
|
13790
|
+
* Check the keyring against the database and record what is new; make the
|
|
13791
|
+
* database's active key the keyring's. Throws {@link FieldKeyringRefusal} when
|
|
13792
|
+
* the keyring cannot read this database's data.
|
|
13793
|
+
*
|
|
13794
|
+
* `tables` are the app's declared tables: a few sealed values per
|
|
13795
|
+
* `.encrypted()` column are opened as a sample, and nothing else is read.
|
|
13796
|
+
*/
|
|
13797
|
+
export declare const verifyFieldKeyring: (store: DataStore, keyring: FieldKeyring, tables: Iterable<unknown>, holder?: FieldKeyHolder) => Promise<FieldKeyringVerification>;
|
|
13798
|
+
|
|
13799
|
+
/** Every location's envelopes, opened with `keyring` — after a re-key, a keyring with the active key alone. */
|
|
13800
|
+
export declare const verifySealedValues: (dialect: DialectId, keyring: FieldKeyring, declared: Iterable<unknown>) => Effect.Effect<{
|
|
13801
|
+
opened: number;
|
|
13802
|
+
unopened: {
|
|
13803
|
+
readonly table: string;
|
|
13804
|
+
readonly column: string;
|
|
13805
|
+
readonly count: number;
|
|
13806
|
+
}[];
|
|
13807
|
+
unreadable: UnreadableColumn[];
|
|
13808
|
+
}, SqlError, SqlClient.SqlClient>;
|
|
13809
|
+
|
|
13094
13810
|
/** The pure core of live revocation: given a subject + action + a row-set,
|
|
13095
13811
|
* return ONLY the rows the subject may still see. The reactive matcher calls
|
|
13096
13812
|
* this on a permission-changing write and diffs against the prior visible set;
|
|
@@ -13168,6 +13884,19 @@ export declare const _voltroConnectionsTable: TableLike;
|
|
|
13168
13884
|
|
|
13169
13885
|
export declare const _voltroCrdtVersionsTable: TableLike;
|
|
13170
13886
|
|
|
13887
|
+
/** The leases: which process holds which keys, and until when it counts —
|
|
13888
|
+
* rewritten by every heartbeat, so not reactive. */
|
|
13889
|
+
export declare const _voltroFieldKeyHoldersTable: TableLike;
|
|
13890
|
+
|
|
13891
|
+
/** The last count and the last re-key `voltro secret status` / `rekey` / `rotate`
|
|
13892
|
+
* ran — what the Governance panel shows as a rotation's progress, since the
|
|
13893
|
+
* app itself never scans every sealed value. Counts and locations, never a value. */
|
|
13894
|
+
export declare const _voltroFieldKeyReportsTable: TableLike;
|
|
13895
|
+
|
|
13896
|
+
/** Each field-encryption key id's state and canary — a framework table, created for every app.
|
|
13897
|
+
* Declared by its literal name: the data-transfer classification guard reads declarations. */
|
|
13898
|
+
export declare const _voltroFieldKeysTable: TableLike;
|
|
13899
|
+
|
|
13171
13900
|
/** `_voltro_rebac_tuples` — the relationship tuples `can()` reads. One row =
|
|
13172
13901
|
* "`subjectId` has `relation` on `<resourceType>:<resourceId>`". Grant by
|
|
13173
13902
|
* inserting; revoke by deleting (a delete is the live-revocation trigger). */
|
|
@@ -13917,7 +14646,7 @@ export declare interface WorkflowsAppContext {
|
|
|
13917
14646
|
* execution, or never to run — read once, without waiting. A queued handle
|
|
13918
14647
|
* is resolved through its durable receipt, so the answer survives the
|
|
13919
14648
|
* process that recorded the handle. */
|
|
13920
|
-
readStart(handle: WorkflowRunHandle, options?:
|
|
14649
|
+
readStart(handle: WorkflowRunHandle, options?: WorkflowRunOptions): Promise<WorkflowStartObservation>;
|
|
13921
14650
|
/**
|
|
13922
14651
|
* Set on the facade a mutation TRANSACTION hands out: every start it records
|
|
13923
14652
|
* is provisional until the transaction commits, so nothing about a start can
|
|
@@ -14100,6 +14829,10 @@ export declare const wrapStoreWithBootCodec: (underlying: DataStore, dialectId:
|
|
|
14100
14829
|
|
|
14101
14830
|
export declare const wrapStoreWithMixinBehaviour: (rawUnderlying: DataStore, ctx: StoreMiddlewareContext) => FluentStore;
|
|
14102
14831
|
|
|
14832
|
+
/** Writer errors propagate to the publisher, which owns retry/logging. A failed
|
|
14833
|
+
* history write must not be mistaken for a successfully recorded zero bucket. */
|
|
14834
|
+
export declare const writeApiRoleWorkloadBucket: (store: DataStore, bucket: ApiRoleWorkloadBucket) => Promise<void>;
|
|
14835
|
+
|
|
14103
14836
|
export declare const writeReplicaObservation: (store: DataStore, kind: ReplicaObservationKind, payload: unknown) => Promise<void>;
|
|
14104
14837
|
|
|
14105
14838
|
export { }
|