@voltro/runtime 0.86.0 → 0.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5321 -0
- package/README.md +43 -0
- package/THIRD-PARTY-NOTICES.md +860 -221
- package/dist/analyticsSink.js +8 -14
- package/dist/apiKeys.js +82 -78
- package/dist/apiRoleBucketSampler.js +64 -0
- package/dist/apiRoleWorkloadHistory.js +56 -0
- package/dist/apiRoleWorkloadMetrics.js +78 -0
- package/dist/apiRoleWorkloadStorage.js +95 -0
- package/dist/approvals.js +67 -74
- package/dist/authMiddlewareLayer.js +7 -6
- package/dist/bindEvent.js +48 -28
- package/dist/bootListener.js +106 -39
- package/dist/bootStoreCodec.js +38 -37
- package/dist/circuitBreaker.js +1 -72
- package/dist/composeAnalytics.js +31 -10
- package/dist/computedQueryCache.js +231 -0
- package/dist/connectionsFacade.js +32 -30
- package/dist/coordinatedSchedule.js +84 -78
- package/dist/dataStore.js +154 -121
- package/dist/declaredTablesGuard.js +2 -1
- package/dist/dispatcher.js +403 -328
- package/dist/effectStore.js +2 -2
- package/dist/engineClients.js +24 -0
- package/dist/externalizedTasks.js +19 -6
- package/dist/fieldCipher.js +109 -40
- package/dist/fieldKeyRegistry.js +295 -0
- package/dist/fieldKeyRekey.js +286 -0
- package/dist/fieldKeyScan.js +136 -0
- package/dist/fieldKeyring.js +77 -0
- package/dist/hot.d.ts +56 -0
- package/dist/hot.js +3 -0
- package/dist/hotDataStore.js +148 -0
- package/dist/hotDataStoreSnapshot.js +98 -0
- package/dist/hotDataStoreTables.js +18 -0
- package/dist/http-range.d.ts +53 -0
- package/dist/http-range.js +52 -0
- package/dist/httpClientSsrf.js +12 -37
- package/dist/httpClientTracing.js +12 -9
- package/dist/httpCompression.js +17 -17
- package/dist/httpInputStream.js +82 -0
- package/dist/httpRouteMounts.js +1 -0
- package/dist/idempotencyStore.js +92 -52
- package/dist/index.d.ts +1164 -451
- package/dist/index.js +143 -132
- package/dist/kvFacade.js +23 -17
- package/dist/memoryQueryJoins.js +16 -16
- package/dist/memorySetOperations.js +43 -0
- package/dist/metrics.js +38 -24
- package/dist/outbox.js +1 -1
- package/dist/readRecorder.js +35 -34
- package/dist/readScopePredicate.js +12 -0
- package/dist/replicatedDataStore.js +22 -4
- package/dist/rowFilter.js +56 -39
- package/dist/rpcConnections.js +8 -8
- package/dist/rpcServer.js +522 -449
- package/dist/rpcWorkloadAdmission.js +50 -0
- package/dist/rywPositionStore.js +82 -47
- package/dist/scheduler.js +6 -1
- package/dist/servePipeline.js +215 -146
- package/dist/setReadScopes.js +28 -0
- package/dist/snapshotValueCodec.js +46 -0
- package/dist/sourceResolution.js +34 -24
- package/dist/storeMiddleware.js +211 -209
- package/dist/subscriber.js +1 -0
- package/dist/tenantScope.js +8 -20
- package/dist/traceparent.js +8 -19
- package/dist/webSocketGatewayRuntime.js +111 -71
- package/dist/workflowRuntime.js +9 -9
- package/package.json +19 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,31 @@
|
|
|
1
|
+
import { AggregateQuery } from '@voltro/kv/analytics';
|
|
2
|
+
import { AnalyticsBucket } from '@voltro/kv/analytics';
|
|
3
|
+
import { AnalyticsCapabilityNotSupported } from '@voltro/kv/analytics';
|
|
4
|
+
import { AnalyticsError } from '@voltro/kv/analytics';
|
|
5
|
+
import { AnalyticsEvent } from '@voltro/kv/analytics';
|
|
6
|
+
import { AnalyticsFailure } from '@voltro/kv/analytics';
|
|
7
|
+
import { AnalyticsMetric } from '@voltro/kv/analytics';
|
|
8
|
+
import { AnalyticsMirrorImpl } from '@voltro/kv/analytics';
|
|
9
|
+
import { AnalyticsMirrorRemove } from '@voltro/kv/analytics';
|
|
10
|
+
import { AnalyticsMirrorUpsert } from '@voltro/kv/analytics';
|
|
11
|
+
import { AnalyticsSinkImpl } from '@voltro/kv/analytics';
|
|
12
|
+
import { AnalyticsSinkInfo } from '@voltro/kv/analytics';
|
|
13
|
+
import { AnalyticsTopEntry } from '@voltro/kv/analytics';
|
|
1
14
|
import { AnyApprovalPolicy } from '@voltro/protocol';
|
|
2
15
|
import { AnyCheckSpec } from '@voltro/protocol';
|
|
3
16
|
import { AnyGuardSpec } from '@voltro/protocol';
|
|
17
|
+
import { ApiRoleWindowAssessment } from '@voltro/protocol';
|
|
18
|
+
import { ApiWorkload } from '@voltro/protocol';
|
|
4
19
|
import { AuthMiddleware } from '@voltro/protocol';
|
|
5
20
|
import { AuthStrategy } from '@voltro/protocol';
|
|
21
|
+
import { canonicalJson } from '@voltro/protocol';
|
|
6
22
|
import { CaughtUpVerdict } from '@voltro/database';
|
|
7
23
|
import { Cause } from 'effect';
|
|
8
24
|
import { ChangeEvent } from '@voltro/database';
|
|
25
|
+
import { CircuitBreaker } from '@voltro/shared';
|
|
26
|
+
import { CircuitBreakerOptions } from '@voltro/shared';
|
|
27
|
+
import { CircuitOpen } from '@voltro/shared';
|
|
28
|
+
import { CircuitState } from '@voltro/shared';
|
|
9
29
|
import { classifyConstraintViolation } from '@voltro/database';
|
|
10
30
|
import { clearRetentions } from '@voltro/database';
|
|
11
31
|
import { ColumnBuilder } from '@voltro/database';
|
|
@@ -28,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
|
-
}
|
|
603
|
+
export { AnalyticsBucket }
|
|
564
604
|
|
|
565
|
-
|
|
566
|
-
* The sink doesn't implement this capability. PostHog returns this
|
|
567
|
-
* for `aggregate`/`timeseries`/`topN`. Callers typically
|
|
568
|
-
* `Effect.catchTag('AnalyticsCapabilityNotSupported', ...)` to fall
|
|
569
|
-
* back to a different sink or report the missing feature.
|
|
570
|
-
*/
|
|
571
|
-
export declare class AnalyticsCapabilityNotSupported extends AnalyticsCapabilityNotSupported_base {
|
|
572
|
-
}
|
|
605
|
+
export { AnalyticsCapabilityNotSupported }
|
|
573
606
|
|
|
574
|
-
|
|
575
|
-
readonly provider: Schema.String;
|
|
576
|
-
readonly capability: Schema.String;
|
|
577
|
-
}>, YieldableError>;
|
|
607
|
+
export { AnalyticsError }
|
|
578
608
|
|
|
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
|
-
}
|
|
609
|
+
export { AnalyticsEvent }
|
|
585
610
|
|
|
586
|
-
|
|
587
|
-
readonly provider: Schema.String;
|
|
588
|
-
readonly operation: Schema.String;
|
|
589
|
-
readonly cause: Schema.String;
|
|
590
|
-
}>, YieldableError>;
|
|
611
|
+
export { AnalyticsFailure }
|
|
591
612
|
|
|
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
|
-
}
|
|
615
|
-
|
|
616
|
-
export declare type AnalyticsFailure = AnalyticsError | AnalyticsCapabilityNotSupported;
|
|
617
|
-
|
|
618
|
-
/** Metric to compute. `count` = row count, `unique` = distinct subjectId,
|
|
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
|
|
@@ -1820,9 +1747,12 @@ export declare interface BindEventInput {
|
|
|
1820
1747
|
* this bridge must treat it as "no check", not as a guard.
|
|
1821
1748
|
*/
|
|
1822
1749
|
readonly guards?: DeclaredAccess<unknown> | undefined;
|
|
1750
|
+
/** The descriptor requirement and captured app policy must match exactly. */
|
|
1751
|
+
readonly requiredClientPolicy?: string;
|
|
1752
|
+
readonly clientPolicy?: EventClientPolicy;
|
|
1823
1753
|
}
|
|
1824
1754
|
|
|
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?:
|
|
1755
|
+
export declare const bindMutation: <Input, Output, E = never>(execute: (input: Input, context: RuntimeContext) => Output | Promise<Output> | Effect.Effect<Output, E, never>, input: Input, spanName?: string, codec?: MutationCodec<unknown>, idempotency?: IdempotencyBinding,
|
|
1826
1756
|
/**
|
|
1827
1757
|
* This procedure's DECLARED error union (`descriptor.error`).
|
|
1828
1758
|
*
|
|
@@ -1874,7 +1804,12 @@ guards?: ReadonlyArray<unknown> | undefined,
|
|
|
1874
1804
|
* (`{ scope: 'x:read', from: 'id' }`) can see which resource was asked for.
|
|
1875
1805
|
* Passed explicitly rather than read off RuntimeContext, which does not
|
|
1876
1806
|
* carry it. */
|
|
1877
|
-
guardInput?: unknown
|
|
1807
|
+
guardInput?: unknown,
|
|
1808
|
+
/** Plugin admission wraps construction once; element guards remain live. */
|
|
1809
|
+
admission?: {
|
|
1810
|
+
readonly tag: string;
|
|
1811
|
+
readonly interceptor?: ServeRpcInterceptor | undefined;
|
|
1812
|
+
}) => Stream.Stream<Element, Err, SubjectService | ConnectionInfo>;
|
|
1878
1813
|
|
|
1879
1814
|
/**
|
|
1880
1815
|
* Build a `Stream<SubscriptionEvent<T>>` that an effect/rpc streaming
|
|
@@ -1961,6 +1896,16 @@ export declare interface BootListener {
|
|
|
1961
1896
|
* Installed by the boot path when its store exists, which is after the
|
|
1962
1897
|
* bind; an app-declared `health.readiness` replaces the whole check. */
|
|
1963
1898
|
readonly setDependencyPing: (ping: () => Promise<boolean>) => void;
|
|
1899
|
+
/** Required local runtime conditions, independent of app dependency policy.
|
|
1900
|
+
* Checks must be synchronous and cheap. Release removes only this registration. */
|
|
1901
|
+
/** Enable structured API health using captured role/workload identities. */
|
|
1902
|
+
readonly setRoleHealth: (identity: {
|
|
1903
|
+
readonly roles: ReadonlyArray<string>;
|
|
1904
|
+
readonly workloads: ReadonlyArray<string>;
|
|
1905
|
+
}) => void;
|
|
1906
|
+
readonly addReadinessGate: (name: string, check: () => boolean) => () => void;
|
|
1907
|
+
/** Required local progress conditions. App liveness cannot bypass these gates. */
|
|
1908
|
+
readonly addLivenessGate: (name: string, check: () => boolean) => () => void;
|
|
1964
1909
|
/** Close the socket. Resolves once node reports the listener closed. */
|
|
1965
1910
|
readonly close: () => Promise<void>;
|
|
1966
1911
|
}
|
|
@@ -2055,6 +2000,40 @@ export declare const buildTracingLayer: (options?: TracingOptions) => Promise<Tr
|
|
|
2055
2000
|
* hit on every read. `now` injectable for tests. */
|
|
2056
2001
|
export declare const cachedBackend: (backend: SecretsBackend, ttlMs?: number, now?: () => number) => SecretsBackend;
|
|
2057
2002
|
|
|
2003
|
+
export declare const cachedComputedCall: (args: CachedComputedCallArgs) => Effect.Effect<CachedComputedResult, unknown, never>;
|
|
2004
|
+
|
|
2005
|
+
declare interface CachedComputedCallArgs {
|
|
2006
|
+
readonly cache: ComputedQueryCacheDeps;
|
|
2007
|
+
readonly policy: ComputedQueryCachePolicy;
|
|
2008
|
+
readonly key: string;
|
|
2009
|
+
readonly name: string;
|
|
2010
|
+
readonly sources: ReadonlyArray<string>;
|
|
2011
|
+
readonly output: Schema.Top | undefined;
|
|
2012
|
+
readonly subject: object;
|
|
2013
|
+
readonly rowFilter: RowFilterScope | undefined;
|
|
2014
|
+
readonly ctx: object;
|
|
2015
|
+
readonly signal?: AbortSignal;
|
|
2016
|
+
/** Run the handler to a value against the OBSERVED context and subject. */
|
|
2017
|
+
readonly execute: (observedCtx: object, observedSubject: object) => Promise<unknown>;
|
|
2018
|
+
/** The handler returned a descriptor — the snapshot cache owns that query. */
|
|
2019
|
+
readonly onDescriptor: () => void;
|
|
2020
|
+
readonly isDescriptor: (value: unknown) => boolean;
|
|
2021
|
+
readonly unwrap: (value: unknown) => unknown;
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
/**
|
|
2025
|
+
* Serve one computed call through the cache: a hit, or the handler run under
|
|
2026
|
+
* observation and its result kept — or not — by `decideComputedStore`. The
|
|
2027
|
+
* caller authorizes BEFORE and re-authorizes the delivered value AFTER; this
|
|
2028
|
+
* function only decides what the cache does.
|
|
2029
|
+
*/
|
|
2030
|
+
/** A cached call's value, and the tables a live query built from it must also
|
|
2031
|
+
* recompute on (read by the handler, not named in `source:`). */
|
|
2032
|
+
declare interface CachedComputedResult {
|
|
2033
|
+
readonly value: unknown;
|
|
2034
|
+
readonly dependencies: ReadonlyArray<string>;
|
|
2035
|
+
}
|
|
2036
|
+
|
|
2058
2037
|
/** One leak: a query caching ONE entry across every caller while reading a
|
|
2059
2038
|
* table whose rows are scoped per tenant. */
|
|
2060
2039
|
export declare interface CacheScopeLeak {
|
|
@@ -2127,15 +2106,7 @@ export declare interface CandidateShape {
|
|
|
2127
2106
|
export declare const canonicalInputKey: (input: unknown) => string;
|
|
2128
2107
|
|
|
2129
2108
|
/* 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;
|
|
2109
|
+
export { canonicalJson }
|
|
2139
2110
|
|
|
2140
2111
|
export { CaughtUpVerdict }
|
|
2141
2112
|
|
|
@@ -2155,6 +2126,29 @@ export declare interface CdcDelta {
|
|
|
2155
2126
|
readonly new?: Row_3 | null;
|
|
2156
2127
|
}
|
|
2157
2128
|
|
|
2129
|
+
/** What a cell's envelopes can be bound to. */
|
|
2130
|
+
export declare interface CellContext {
|
|
2131
|
+
readonly table: string;
|
|
2132
|
+
readonly column: string;
|
|
2133
|
+
/** The cell's row: its primary key, and every other column (for ids a copy carries). */
|
|
2134
|
+
readonly rowId: unknown;
|
|
2135
|
+
readonly row: Readonly<Record<string, unknown>>;
|
|
2136
|
+
/** Every `.encrypted()` column the app declares, by table. */
|
|
2137
|
+
readonly declared: ReadonlyMap<string, ReadonlySet<string>>;
|
|
2138
|
+
/** Declared renames (`declaredRenames`): the old names a value of this cell may still be bound to. */
|
|
2139
|
+
readonly renames?: ReadonlyMap<string, DeclaredRename>;
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
/** What a cell's re-key did. */
|
|
2143
|
+
export declare interface CellRekey {
|
|
2144
|
+
/** The cell's new text — equal to the input when nothing changed. */
|
|
2145
|
+
readonly text: string;
|
|
2146
|
+
readonly rekeyed: number;
|
|
2147
|
+
readonly current: number;
|
|
2148
|
+
/** Envelopes no candidate address opened — left as they are. */
|
|
2149
|
+
readonly unresolved: number;
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2158
2152
|
export { ChangeEvent }
|
|
2159
2153
|
|
|
2160
2154
|
/** A mutation invocation's full change-set — the unit of undo. */
|
|
@@ -2170,50 +2164,24 @@ export declare interface ChangeSet {
|
|
|
2170
2164
|
readonly crossesAction?: boolean;
|
|
2171
2165
|
}
|
|
2172
2166
|
|
|
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
2167
|
/**
|
|
2203
|
-
*
|
|
2204
|
-
*
|
|
2168
|
+
* The same checks as {@link verifyFieldKeyring}, writing nothing — for a dry
|
|
2169
|
+
* run. Answers which key the database records as active (`undefined` before
|
|
2170
|
+
* the first boot recorded any) and which one would wait for the fleet.
|
|
2205
2171
|
*/
|
|
2206
|
-
export declare
|
|
2207
|
-
|
|
2172
|
+
export declare const checkFieldKeyring: (store: DataStore, keyring: FieldKeyring, tables: Iterable<unknown>) => Promise<{
|
|
2173
|
+
readonly active: string | undefined;
|
|
2174
|
+
readonly requested?: string;
|
|
2175
|
+
readonly notes: ReadonlyArray<string>;
|
|
2176
|
+
}>;
|
|
2208
2177
|
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
}>, Cause.YieldableError>;
|
|
2178
|
+
export { CircuitBreaker }
|
|
2179
|
+
|
|
2180
|
+
export { CircuitBreakerOptions }
|
|
2181
|
+
|
|
2182
|
+
export { CircuitOpen }
|
|
2215
2183
|
|
|
2216
|
-
export
|
|
2184
|
+
export { CircuitState }
|
|
2217
2185
|
|
|
2218
2186
|
/** How many bucket widths of predecessors a won claim leaves behind. */
|
|
2219
2187
|
export declare const CLAIM_RETENTION_BUCKETS = 64;
|
|
@@ -2386,7 +2354,7 @@ export declare interface CompleteOAuthResult {
|
|
|
2386
2354
|
/**
|
|
2387
2355
|
* Combine multiple analytics specs into one composite spec at
|
|
2388
2356
|
* app.config.ts time. The framework's boot path materialises each
|
|
2389
|
-
* child spec
|
|
2357
|
+
* child spec with its declared SQL dependency and wires them through
|
|
2390
2358
|
* `composeAnalyticsSinks` so they behave as one logical sink.
|
|
2391
2359
|
*
|
|
2392
2360
|
* `track()` fans out to every child; reads route to the first child
|
|
@@ -2394,12 +2362,12 @@ export declare interface CompleteOAuthResult {
|
|
|
2394
2362
|
*
|
|
2395
2363
|
* Tables contributed by ANY child get merged. `initialize` effects
|
|
2396
2364
|
* run sequentially in declaration order; `dispose` effects (teardown)
|
|
2397
|
-
*
|
|
2365
|
+
* await each child in reverse order — only present on the
|
|
2398
2366
|
* composite when at least one child does.
|
|
2399
2367
|
*
|
|
2400
2368
|
* analytics: composeAnalytics([
|
|
2401
2369
|
* postgresAnalytics(), // primary: handles reads
|
|
2402
|
-
* posthogAnalytics({ apiKey:
|
|
2370
|
+
* posthogAnalytics({ apiKey: process.env.POSTHOG_API_KEY! }),
|
|
2403
2371
|
* ])
|
|
2404
2372
|
*/
|
|
2405
2373
|
export declare const composeAnalytics: (specs: ReadonlyArray<AnalyticsSinkSpec>) => AnalyticsSinkSpec;
|
|
@@ -2443,6 +2411,44 @@ export declare interface CompressionOptions {
|
|
|
2443
2411
|
readonly minBytes?: number;
|
|
2444
2412
|
}
|
|
2445
2413
|
|
|
2414
|
+
/** Why a call is not looked up at all. */
|
|
2415
|
+
declare type ComputedCacheBypass = 'input-not-encodable' | 'no-tenant' | 'anonymous-subject';
|
|
2416
|
+
|
|
2417
|
+
/**
|
|
2418
|
+
* The entry one call belongs to — or why it has none.
|
|
2419
|
+
*
|
|
2420
|
+
* Every part is something a different answer could hang on: the query and the
|
|
2421
|
+
* build that runs it (a redis cache outlives a deploy, and two releases share
|
|
2422
|
+
* it during a rolling one), the output shape, the ENCODED input (so a `Date`,
|
|
2423
|
+
* a `bigint` or a branded id keys by its wire form, and two spellings of one
|
|
2424
|
+
* input share an entry), the scope's caller part, and the row-filter
|
|
2425
|
+
* visibility the caller's reads of the declared tables resolve to.
|
|
2426
|
+
*/
|
|
2427
|
+
export declare const computedCacheKey: (args: ComputedCacheKeyInput) => {
|
|
2428
|
+
readonly key: string;
|
|
2429
|
+
} | {
|
|
2430
|
+
readonly bypass: ComputedCacheBypass;
|
|
2431
|
+
};
|
|
2432
|
+
|
|
2433
|
+
declare interface ComputedCacheKeyInput {
|
|
2434
|
+
readonly name: string;
|
|
2435
|
+
/** The running build — see `codeIdentity` on the boot side. */
|
|
2436
|
+
readonly codeIdentity: string;
|
|
2437
|
+
readonly output: Schema.Top | undefined;
|
|
2438
|
+
readonly input: Schema.Top | undefined;
|
|
2439
|
+
readonly decodedInput: unknown;
|
|
2440
|
+
readonly scope: ComputedCacheScope;
|
|
2441
|
+
readonly subject: {
|
|
2442
|
+
readonly id?: string | null | undefined;
|
|
2443
|
+
readonly type?: string | undefined;
|
|
2444
|
+
readonly tenantId?: string | null | undefined;
|
|
2445
|
+
};
|
|
2446
|
+
readonly rowFilter: RowFilterScope | undefined;
|
|
2447
|
+
readonly declaredSources: ReadonlyArray<string>;
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
declare type ComputedCacheScope = 'subject' | 'tenant' | 'global';
|
|
2451
|
+
|
|
2446
2452
|
declare interface ComputedQuery {
|
|
2447
2453
|
readonly __voltroComputed: true;
|
|
2448
2454
|
/** The initial computed value — emitted verbatim as the first snapshot. */
|
|
@@ -2456,6 +2462,56 @@ declare interface ComputedQuery {
|
|
|
2456
2462
|
readonly recompute: () => Promise<unknown>;
|
|
2457
2463
|
}
|
|
2458
2464
|
|
|
2465
|
+
/** Is capture on? The request store builder wraps its store when it is. */
|
|
2466
|
+
export declare const computedQueryCacheCaptureInstalled: () => boolean;
|
|
2467
|
+
|
|
2468
|
+
/**
|
|
2469
|
+
* The cache a COMPUTED query's handler invocation is served through. Both boot
|
|
2470
|
+
* paths build it over the app's `Cache` (`wrapDynamic`), and so does
|
|
2471
|
+
* `@voltro/testing`'s `invoke`; absent ⇒ computed queries are never cached.
|
|
2472
|
+
*/
|
|
2473
|
+
export declare interface ComputedQueryCacheDeps {
|
|
2474
|
+
readonly wrapDynamic: <A, E>(key: string, options: {
|
|
2475
|
+
readonly ttlMs: number;
|
|
2476
|
+
readonly swrMs?: number | undefined;
|
|
2477
|
+
readonly leaseMs?: number | undefined;
|
|
2478
|
+
readonly label: string;
|
|
2479
|
+
}, compute: Effect.Effect<{
|
|
2480
|
+
readonly value: A;
|
|
2481
|
+
readonly store?: {
|
|
2482
|
+
readonly stored: unknown;
|
|
2483
|
+
readonly tags: ReadonlyArray<string>;
|
|
2484
|
+
} | undefined;
|
|
2485
|
+
readonly notApplicable?: boolean | undefined;
|
|
2486
|
+
}, E, never>, read: (stored: unknown) => Effect.Effect<Option.Option<A>>) => Effect.Effect<{
|
|
2487
|
+
readonly value: A;
|
|
2488
|
+
readonly served: 'hit' | 'stale' | 'miss';
|
|
2489
|
+
}, E, never>;
|
|
2490
|
+
/** Parse the declared `cache:` (same parser as the descriptor path). */
|
|
2491
|
+
readonly policyFor: (cache: {
|
|
2492
|
+
readonly ttl: number | string;
|
|
2493
|
+
readonly swr?: number | string | undefined;
|
|
2494
|
+
readonly scope: ComputedCacheScope;
|
|
2495
|
+
readonly volatile?: boolean | undefined;
|
|
2496
|
+
}) => ComputedQueryCachePolicy | undefined;
|
|
2497
|
+
/** The running build — part of every key, so a deploy never reads another
|
|
2498
|
+
* release's entries out of a shared cache. */
|
|
2499
|
+
readonly codeIdentity: string;
|
|
2500
|
+
readonly maxEntryBytes: number;
|
|
2501
|
+
/** Cluster single-flight lease, when the backend supports one. */
|
|
2502
|
+
readonly leaseMs?: number | undefined;
|
|
2503
|
+
/** Once-per-(query, reason) notice that a result was not kept. */
|
|
2504
|
+
readonly notice: (query: string, reason: string, message: string) => void;
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
/** A computed query's resolved cache policy — ms, parsed by the boot path. */
|
|
2508
|
+
export declare interface ComputedQueryCachePolicy {
|
|
2509
|
+
readonly ttlMs: number;
|
|
2510
|
+
readonly swrMs: number | undefined;
|
|
2511
|
+
readonly scope: ComputedCacheScope;
|
|
2512
|
+
readonly volatile: boolean;
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2459
2515
|
export declare const CONNECTION_GRANTS_TABLE = "_voltro_connection_grants";
|
|
2460
2516
|
|
|
2461
2517
|
/** What a declaration can learn about the account it just connected. Optional
|
|
@@ -2588,6 +2644,7 @@ export { ConstraintViolation }
|
|
|
2588
2644
|
export declare type CoordinatedEffect = () => void | CoordinatedTickOutcome | Promise<void | CoordinatedTickOutcome>;
|
|
2589
2645
|
|
|
2590
2646
|
export declare interface CoordinatedScheduleDeps {
|
|
2647
|
+
readonly externalTasks?: ExternalizedTaskRegistry;
|
|
2591
2648
|
/** The exactly-once gate. `singleCoordinator` for one-process
|
|
2592
2649
|
* deployments; `makeAdvisoryLockCoordinator(store, replicaId)` for
|
|
2593
2650
|
* multi-instance SQL stores. Injected so this stays testable with a
|
|
@@ -2678,8 +2735,9 @@ export declare interface CoordinatedScheduleDiagnostics {
|
|
|
2678
2735
|
}
|
|
2679
2736
|
|
|
2680
2737
|
export declare interface CoordinatedScheduleHandle {
|
|
2681
|
-
/** Stop the
|
|
2682
|
-
|
|
2738
|
+
/** Stop admission immediately; await the returned completion before releasing
|
|
2739
|
+
* storage. Includes timer and external-trigger claims/effects. Idempotent. */
|
|
2740
|
+
readonly stop: () => void | Promise<void>;
|
|
2683
2741
|
/** The task name (for logging / dedup diagnostics). */
|
|
2684
2742
|
readonly name: string;
|
|
2685
2743
|
/**
|
|
@@ -3381,6 +3439,9 @@ export declare const decideApprovalInvocation: (input: {
|
|
|
3381
3439
|
readonly status: "approved" | "rejected";
|
|
3382
3440
|
}>;
|
|
3383
3441
|
|
|
3442
|
+
/** The app's `.encrypted()` columns, by table. */
|
|
3443
|
+
export declare const declaredEncryptedColumns: (declared: Iterable<unknown>) => ReadonlyMap<string, ReadonlySet<string>>;
|
|
3444
|
+
|
|
3384
3445
|
/**
|
|
3385
3446
|
* `unknown` when the executor's failures are all declared; otherwise a type the
|
|
3386
3447
|
* handler cannot satisfy, whose one property spells out the undeclared tag(s)
|
|
@@ -3393,6 +3454,27 @@ UndeclaredErrorTags<D, R>
|
|
|
3393
3454
|
readonly undeclaredFailure: `'${UndeclaredErrorTags<D, R>}' is not in this procedure's wire union — add it to the descriptor's \`error:\`, register it through a plugin's \`errorSchemas\`, or map it away (Effect.orDie for a defect)`;
|
|
3394
3455
|
};
|
|
3395
3456
|
|
|
3457
|
+
/** A declared rename of a table with sealed columns: the names its values may still be bound to. */
|
|
3458
|
+
export declare interface DeclaredRename {
|
|
3459
|
+
readonly previousTable?: string;
|
|
3460
|
+
/** New column name → the name it was renamed from. */
|
|
3461
|
+
readonly columns: ReadonlyMap<string, string>;
|
|
3462
|
+
}
|
|
3463
|
+
|
|
3464
|
+
/**
|
|
3465
|
+
* The renames the app declares on tables with `.encrypted()` columns —
|
|
3466
|
+
* `table('new').renamedFrom('old')`, a column's `.renamedFrom('old')`. A rename
|
|
3467
|
+
* is catalog-only, so the rows keep values bound to the old names; the re-key
|
|
3468
|
+
* opens them there and seals them under the new ones.
|
|
3469
|
+
*/
|
|
3470
|
+
export declare const declaredRenames: (declared: Iterable<unknown>) => ReadonlyMap<string, DeclaredRename>;
|
|
3471
|
+
|
|
3472
|
+
/** Decode a stored snapshot; `undefined` for anything this version did not
|
|
3473
|
+
* write (an entry from another build reads as a miss). */
|
|
3474
|
+
export declare const decodeSnapshotValue: (stored: unknown) => {
|
|
3475
|
+
readonly value: unknown;
|
|
3476
|
+
} | undefined;
|
|
3477
|
+
|
|
3396
3478
|
/**
|
|
3397
3479
|
* Decrypt a value produced by `encryptField` or by an `.encrypted()` column —
|
|
3398
3480
|
* one encoding, so that sentence is now true in both directions.
|
|
@@ -3958,7 +4040,13 @@ export declare class Dispatcher {
|
|
|
3958
4040
|
private readonly subscriptionRegistry;
|
|
3959
4041
|
private readonly matcher;
|
|
3960
4042
|
private readonly subscriptions;
|
|
3961
|
-
private
|
|
4043
|
+
private unsubscribeChange;
|
|
4044
|
+
private closed;
|
|
4045
|
+
private readonly operations;
|
|
4046
|
+
/** Register synchronously, before user code or the first await can run. */
|
|
4047
|
+
private beginOperation;
|
|
4048
|
+
/** Includes pending initial reads, not only already-visible subscriptions. */
|
|
4049
|
+
private readonly interests;
|
|
3962
4050
|
/**
|
|
3963
4051
|
* Reverse index: tableName → set of subscription ids whose
|
|
3964
4052
|
* dependent-table set INCLUDES that table. A change event on table
|
|
@@ -3984,12 +4072,18 @@ export declare class Dispatcher {
|
|
|
3984
4072
|
/** Query labels already warned about for an undeclared raw read, so a hot
|
|
3985
4073
|
* subscription logs once rather than once per subscriber. */
|
|
3986
4074
|
private readonly rawReadWarned;
|
|
4075
|
+
/** The cache fence each written-through read observed before it started. */
|
|
4076
|
+
private readonly readFences;
|
|
3987
4077
|
private changeEpoch;
|
|
3988
4078
|
private readonly committedReads;
|
|
3989
4079
|
/** The CRDT-managed columns of `table` (empty when it has none) — what a
|
|
3990
4080
|
* subscription's backpressure outbox folds incrementally. */
|
|
3991
4081
|
crdtColumnsFor(table: string): ReadonlySet<string>;
|
|
3992
4082
|
constructor(deps: DispatcherDependencies);
|
|
4083
|
+
private measureLoop;
|
|
4084
|
+
private retainInterest;
|
|
4085
|
+
/** One idempotent terminal path for setup failures, revocation and disconnect. */
|
|
4086
|
+
private removeInterest;
|
|
3993
4087
|
/**
|
|
3994
4088
|
* REL-14 — a raw read that nothing can invalidate, said out loud.
|
|
3995
4089
|
*
|
|
@@ -4091,6 +4185,9 @@ export declare class Dispatcher {
|
|
|
4091
4185
|
onSubscriptionsChange(listener: () => void): () => void;
|
|
4092
4186
|
/** Tear down the change-event listener. Call on server shutdown. */
|
|
4093
4187
|
close(): void;
|
|
4188
|
+
/** Close admission immediately, then join reads and deliveries before the
|
|
4189
|
+
* owner disposes the store. Do not await this from inside a query callback. */
|
|
4190
|
+
closeAndDrain(): Promise<void>;
|
|
4094
4191
|
/**
|
|
4095
4192
|
* Re-run EVERY live subscription, because this replica proved it missed
|
|
4096
4193
|
* changes it can never recover.
|
|
@@ -4116,6 +4213,8 @@ export declare class Dispatcher {
|
|
|
4116
4213
|
}
|
|
4117
4214
|
|
|
4118
4215
|
export declare interface DispatcherDependencies {
|
|
4216
|
+
/** Active synchronous live-change work only; asynchronous reads are not timed. */
|
|
4217
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
4119
4218
|
readonly store: DataStore;
|
|
4120
4219
|
/** CRDT columns per table (schemaRegistry.crdtColumns). Feeds the
|
|
4121
4220
|
* downstream lane: crdt cells diff as incremental mergeCells ops.
|
|
@@ -4161,6 +4260,8 @@ export declare interface DispatcherDependencies {
|
|
|
4161
4260
|
export declare const DORMANCY_WAKEUP_TENANT = "default";
|
|
4162
4261
|
|
|
4163
4262
|
export declare interface DrainDeps<R = never> {
|
|
4263
|
+
/** Active synchronous handler entry only; never await a Promise inside this measurement. */
|
|
4264
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
4164
4265
|
readonly store: Pick<DataStore, 'query' | 'update' | 'updateMany' | 'insert' | 'delete'>;
|
|
4165
4266
|
readonly handlers: ReadonlyMap<string, OutboxHandlerDefinition<R>>;
|
|
4166
4267
|
/** Execute with the application's services. Required by drainOutbox when R
|
|
@@ -4291,7 +4392,7 @@ export declare interface EffectInsertIgnoreOutcomeStore {
|
|
|
4291
4392
|
|
|
4292
4393
|
/** The minimal Effect-store surface `insertManyRowsEffect` needs. */
|
|
4293
4394
|
export declare interface EffectInsertManyStore {
|
|
4294
|
-
readonly insertMany: (table: string, rows: ReadonlyArray<Row
|
|
4395
|
+
readonly insertMany: (table: string, rows: ReadonlyArray<Row>, options?: InsertManyOptions) => Effect.Effect<ReadonlyArray<Row>, StoreError>;
|
|
4295
4396
|
}
|
|
4296
4397
|
|
|
4297
4398
|
/** The minimal Effect-store surface `insertRowEffect` needs. */
|
|
@@ -4315,7 +4416,7 @@ export declare interface EffectStoreOps {
|
|
|
4315
4416
|
* hand-built descriptor. */
|
|
4316
4417
|
readonly query: <R = Row>(descriptor: QueryDescriptor<R>) => Effect.Effect<ReadonlyArray<R>, StoreError>;
|
|
4317
4418
|
readonly insert: (table: string, row: Row) => Effect.Effect<Row, StoreError>;
|
|
4318
|
-
readonly insertMany: (table: string, rows: ReadonlyArray<Row
|
|
4419
|
+
readonly insertMany: (table: string, rows: ReadonlyArray<Row>, options?: InsertManyOptions) => Effect.Effect<ReadonlyArray<Row>, StoreError>;
|
|
4319
4420
|
readonly patchJson: (table: string, primaryKey: string, path: string, value: unknown, additionalPatch?: Readonly<Record<string, unknown>>) => Effect.Effect<Row | null, StoreError>;
|
|
4320
4421
|
readonly update: (table: string, primaryKey: string, patch: Readonly<Record<string, unknown>>) => Effect.Effect<Row | null, StoreError>;
|
|
4321
4422
|
readonly updateMany: (table: string, patch: Readonly<Record<string, unknown>>, options: {
|
|
@@ -4402,6 +4503,10 @@ export declare const emptySchemaRegistry: SchemaRegistry;
|
|
|
4402
4503
|
* should be observed are constructed — `observeStore` decides once, per store. */
|
|
4403
4504
|
export declare const enableGraphObservation: () => void;
|
|
4404
4505
|
|
|
4506
|
+
/** Encode a snapshot for the cache. Throws on a value with no faithful form —
|
|
4507
|
+
* the caller does not store it then. */
|
|
4508
|
+
export declare const encodeSnapshotValue: (value: unknown) => unknown;
|
|
4509
|
+
|
|
4405
4510
|
/**
|
|
4406
4511
|
* Encrypt a value with the registered field cipher, in the SAME encoding an
|
|
4407
4512
|
* `.encrypted()` column uses. Throws if no cipher is registered.
|
|
@@ -4433,6 +4538,20 @@ export declare const enforceApproval: (input: {
|
|
|
4433
4538
|
readonly traceId?: string | undefined;
|
|
4434
4539
|
}) => Promise<void>;
|
|
4435
4540
|
|
|
4541
|
+
/** One connected engine SDK, as it named itself in `x-voltro-sdk`. It proves nothing and grants nothing. */
|
|
4542
|
+
export declare interface EngineClient {
|
|
4543
|
+
readonly id: string;
|
|
4544
|
+
/** `csharp`, `unity`, `godot` or `unreal`. */
|
|
4545
|
+
readonly target: string;
|
|
4546
|
+
readonly version: string;
|
|
4547
|
+
/** SHA-256 of the API surface the SDK was generated from, or null when it did not say. */
|
|
4548
|
+
readonly surface: string | null;
|
|
4549
|
+
readonly connectedAt: number;
|
|
4550
|
+
}
|
|
4551
|
+
|
|
4552
|
+
/** The engine SDKs connected to this process now, oldest first. */
|
|
4553
|
+
export declare const engineClientsSnapshot: () => ReadonlyArray<EngineClient>;
|
|
4554
|
+
|
|
4436
4555
|
export { EnqueueOptions }
|
|
4437
4556
|
|
|
4438
4557
|
/**
|
|
@@ -5407,6 +5526,12 @@ export declare const externalizedTask: (name: string) => ExternalizedTask | unde
|
|
|
5407
5526
|
|
|
5408
5527
|
export declare const externalizedTaskNames: () => ReadonlyArray<string>;
|
|
5409
5528
|
|
|
5529
|
+
export declare interface ExternalizedTaskRegistry {
|
|
5530
|
+
readonly register: (task: ExternalizedTask) => () => void;
|
|
5531
|
+
readonly get: (name: string) => ExternalizedTask | undefined;
|
|
5532
|
+
readonly names: () => ReadonlyArray<string>;
|
|
5533
|
+
}
|
|
5534
|
+
|
|
5410
5535
|
/** Build an Effect `ExternalSpan` parent from a `traceparent` header so
|
|
5411
5536
|
* inbound HTTP work continues the caller's trace. Returns undefined
|
|
5412
5537
|
* when the header is missing/invalid (no parent → a fresh root span). */
|
|
@@ -5470,11 +5595,251 @@ declare type FailureTag<E> = 0 extends (1 & E) ? never : E extends {
|
|
|
5470
5595
|
readonly _tag: infer T;
|
|
5471
5596
|
} ? T extends 'UnknownError' ? never : T extends string ? T : never : never;
|
|
5472
5597
|
|
|
5598
|
+
export declare const FIELD_ENCRYPTION_ACTIVE_ENV = "VOLTRO_FIELD_ENCRYPTION_ACTIVE";
|
|
5599
|
+
|
|
5600
|
+
export declare const FIELD_ENCRYPTION_KEY_ENV = "VOLTRO_FIELD_ENCRYPTION_KEY";
|
|
5601
|
+
|
|
5602
|
+
export declare const FIELD_ENCRYPTION_KEYS_ENV = "VOLTRO_FIELD_ENCRYPTION_KEYS";
|
|
5603
|
+
|
|
5604
|
+
export declare const FIELD_ENCRYPTION_PREVIOUS_KEY_ENV = "VOLTRO_FIELD_ENCRYPTION_KEY_PREVIOUS";
|
|
5605
|
+
|
|
5606
|
+
export declare const FIELD_KEY_HEARTBEAT_MS = 10000;
|
|
5607
|
+
|
|
5608
|
+
/** The table of leases on field-encryption keys. */
|
|
5609
|
+
export declare const FIELD_KEY_HOLDERS_TABLE = "_voltro_field_key_holders";
|
|
5610
|
+
|
|
5611
|
+
export declare const FIELD_KEY_LEASE_MS = 30000;
|
|
5612
|
+
|
|
5613
|
+
/** The table of the last field-key count and re-key. */
|
|
5614
|
+
export declare const FIELD_KEY_REPORTS_TABLE = "_voltro_field_key_reports";
|
|
5615
|
+
|
|
5616
|
+
/** The environment names a keyring is read from, for a resolver that fetches them. */
|
|
5617
|
+
export declare const FIELD_KEYRING_ENV_NAMES: readonly ["VOLTRO_FIELD_ENCRYPTION_KEYS", "VOLTRO_FIELD_ENCRYPTION_ACTIVE", "VOLTRO_FIELD_ENCRYPTION_KEY", "VOLTRO_FIELD_ENCRYPTION_KEY_PREVIOUS"];
|
|
5618
|
+
|
|
5619
|
+
/** The table recording each field-encryption key id's state and canary. */
|
|
5620
|
+
export declare const FIELD_KEYS_TABLE = "_voltro_field_keys";
|
|
5621
|
+
|
|
5473
5622
|
export declare interface FieldChange {
|
|
5474
5623
|
readonly from: unknown;
|
|
5475
5624
|
readonly to: unknown;
|
|
5476
5625
|
}
|
|
5477
5626
|
|
|
5627
|
+
/** What this process opened since it started, per key and location — the Governance panel's view. */
|
|
5628
|
+
export declare const fieldDecryptSnapshot: () => ReadonlyArray<{
|
|
5629
|
+
readonly key: string;
|
|
5630
|
+
readonly location: string;
|
|
5631
|
+
readonly ok: number;
|
|
5632
|
+
readonly failed: number;
|
|
5633
|
+
}>;
|
|
5634
|
+
|
|
5635
|
+
/** The last `voltro secret status`: sealed values per key id, over all and per location. */
|
|
5636
|
+
export declare interface FieldKeyCountReport {
|
|
5637
|
+
readonly totals: Readonly<Record<string, number>>;
|
|
5638
|
+
readonly unnamed: number;
|
|
5639
|
+
readonly plaintext: number;
|
|
5640
|
+
readonly unreadable: number;
|
|
5641
|
+
readonly locations: ReadonlyArray<{
|
|
5642
|
+
readonly table: string;
|
|
5643
|
+
readonly column: string;
|
|
5644
|
+
readonly byKey: Readonly<Record<string, number>>;
|
|
5645
|
+
readonly unnamed: number;
|
|
5646
|
+
readonly plaintext: number;
|
|
5647
|
+
}>;
|
|
5648
|
+
}
|
|
5649
|
+
|
|
5650
|
+
/** One key of a keyring: its id and its secret (a passphrase, or 64 hex). */
|
|
5651
|
+
export declare interface FieldKeyEntry {
|
|
5652
|
+
readonly id: string;
|
|
5653
|
+
readonly secret: string;
|
|
5654
|
+
}
|
|
5655
|
+
|
|
5656
|
+
/** What one heartbeat found. `unheld`: the database's active key is one this
|
|
5657
|
+
* process does not hold — it missed its lease while the fleet moved on. */
|
|
5658
|
+
export declare interface FieldKeyHeartbeat {
|
|
5659
|
+
readonly active: string;
|
|
5660
|
+
readonly activated?: {
|
|
5661
|
+
readonly from: string | undefined;
|
|
5662
|
+
readonly to: string;
|
|
5663
|
+
};
|
|
5664
|
+
readonly waiting?: FieldKeyWaiting;
|
|
5665
|
+
readonly unheld: boolean;
|
|
5666
|
+
}
|
|
5667
|
+
|
|
5668
|
+
/** A process's lease. `now` is for tests; the lease is how long a process that
|
|
5669
|
+
* stopped heartbeating is still waited for. */
|
|
5670
|
+
export declare interface FieldKeyHolder {
|
|
5671
|
+
readonly holderId: string;
|
|
5672
|
+
readonly leaseMs?: number;
|
|
5673
|
+
readonly now?: () => number;
|
|
5674
|
+
}
|
|
5675
|
+
|
|
5676
|
+
export declare interface FieldKeyHolderHandle {
|
|
5677
|
+
/** Stop heartbeating, wait for a beat in flight, and give up the lease. */
|
|
5678
|
+
readonly stop: () => Promise<void>;
|
|
5679
|
+
}
|
|
5680
|
+
|
|
5681
|
+
/** A holder id for this process. */
|
|
5682
|
+
export declare const fieldKeyHolderId: () => string;
|
|
5683
|
+
|
|
5684
|
+
/** One process's lease, as recorded — `expiresAt` in the past means it no longer counts. */
|
|
5685
|
+
export declare interface FieldKeyHolderRecord {
|
|
5686
|
+
readonly holderId: string;
|
|
5687
|
+
readonly keyIds: ReadonlyArray<string>;
|
|
5688
|
+
readonly activeKeyId: string;
|
|
5689
|
+
readonly heartbeatAt: Date;
|
|
5690
|
+
readonly expiresAt: Date;
|
|
5691
|
+
}
|
|
5692
|
+
|
|
5693
|
+
export declare interface FieldKeyHolderRow {
|
|
5694
|
+
readonly holderId: string;
|
|
5695
|
+
readonly keyIds: ReadonlyArray<string>;
|
|
5696
|
+
readonly activeKeyId: string;
|
|
5697
|
+
readonly expiresAt: string;
|
|
5698
|
+
}
|
|
5699
|
+
|
|
5700
|
+
/**
|
|
5701
|
+
* The id a key gets when the operator does not name one: `k` + 10 hex
|
|
5702
|
+
* characters of an HMAC over the derived key. Stable for a given key, short
|
|
5703
|
+
* enough to ride in every envelope, and not the key — the fingerprint is keyed
|
|
5704
|
+
* by the key itself, so it says nothing about it to someone without it.
|
|
5705
|
+
*/
|
|
5706
|
+
export declare const fieldKeyIdOf: (secret: string) => string;
|
|
5707
|
+
|
|
5708
|
+
/** The last `voltro secret rekey` (also run by `rotate`): what moved, what is left, and whether the active key alone opens everything. */
|
|
5709
|
+
export declare interface FieldKeyRekeyReport {
|
|
5710
|
+
readonly active: string;
|
|
5711
|
+
readonly rekeyed: number;
|
|
5712
|
+
readonly left: number;
|
|
5713
|
+
readonly verified: boolean;
|
|
5714
|
+
}
|
|
5715
|
+
|
|
5716
|
+
export declare interface FieldKeyReports {
|
|
5717
|
+
readonly status?: {
|
|
5718
|
+
readonly reportedAt: Date;
|
|
5719
|
+
readonly report: FieldKeyCountReport;
|
|
5720
|
+
};
|
|
5721
|
+
readonly rekey?: {
|
|
5722
|
+
readonly reportedAt: Date;
|
|
5723
|
+
readonly report: FieldKeyRekeyReport;
|
|
5724
|
+
};
|
|
5725
|
+
}
|
|
5726
|
+
|
|
5727
|
+
/** A field cipher over several keys, each with an id — what `makeFieldKeyring` returns. */
|
|
5728
|
+
export declare interface FieldKeyring extends FieldCipher {
|
|
5729
|
+
/** The key new values are sealed under — the configured active key until
|
|
5730
|
+
* {@link FieldKeyring.activate} names another one the keyring holds. */
|
|
5731
|
+
readonly activeKeyId: string;
|
|
5732
|
+
/** The active key the configuration names. The database may keep another
|
|
5733
|
+
* active until every live process holds this one (`verifyFieldKeyring`). */
|
|
5734
|
+
readonly requestedKeyId: string;
|
|
5735
|
+
/** Every id the keyring holds, the configured active key first. */
|
|
5736
|
+
readonly keyIds: ReadonlyArray<string>;
|
|
5737
|
+
/** Each held key's fingerprint ({@link fieldKeyIdOf} — an HMAC of the key, never
|
|
5738
|
+
* the key), by id: what the boot line and the Governance panel show. */
|
|
5739
|
+
readonly fingerprints: Readonly<Record<string, string>>;
|
|
5740
|
+
/** Seal under one named key, whichever is active (a key's canary). */
|
|
5741
|
+
readonly sealWith: (keyId: string, plaintext: string, binding?: FieldBinding) => string;
|
|
5742
|
+
/** Does the named key open this value? `false` for a key the keyring does not hold. */
|
|
5743
|
+
readonly opensWith: (keyId: string, ciphertext: string, binding?: FieldBinding) => boolean;
|
|
5744
|
+
/** Seal new values under another held key — the database, not the
|
|
5745
|
+
* environment, decides which key is active (`verifyFieldKeyring`). */
|
|
5746
|
+
readonly activate: (keyId: string) => void;
|
|
5747
|
+
}
|
|
5748
|
+
|
|
5749
|
+
/** The keys a process holds, and the one new values are sealed under. */
|
|
5750
|
+
export declare interface FieldKeyringConfig {
|
|
5751
|
+
readonly active: string;
|
|
5752
|
+
readonly keys: ReadonlyArray<FieldKeyEntry>;
|
|
5753
|
+
}
|
|
5754
|
+
|
|
5755
|
+
/** A keyring configuration that cannot be used — named, never containing a key. */
|
|
5756
|
+
export declare class FieldKeyringConfigError extends Error {
|
|
5757
|
+
readonly _tag = "FieldKeyringConfigError";
|
|
5758
|
+
constructor(message: string);
|
|
5759
|
+
}
|
|
5760
|
+
|
|
5761
|
+
/** The boot cannot use this keyring with this database — the message names
|
|
5762
|
+
* ids, columns and the way out, never a key. */
|
|
5763
|
+
export declare class FieldKeyringRefusal extends Error {
|
|
5764
|
+
readonly _tag = "FieldKeyringRefusal";
|
|
5765
|
+
constructor(message: string);
|
|
5766
|
+
}
|
|
5767
|
+
|
|
5768
|
+
/** What a boot's check found and recorded. */
|
|
5769
|
+
export declare interface FieldKeyringVerification {
|
|
5770
|
+
/** The key new values are sealed under, as the database records it. */
|
|
5771
|
+
readonly active: string;
|
|
5772
|
+
/** Ids this boot recorded for the first time. */
|
|
5773
|
+
readonly registered: ReadonlyArray<string>;
|
|
5774
|
+
/** Set when this boot made another key active. */
|
|
5775
|
+
readonly activated?: {
|
|
5776
|
+
readonly from: string | undefined;
|
|
5777
|
+
readonly to: string;
|
|
5778
|
+
};
|
|
5779
|
+
/** A requested key that is not active yet, and the live processes that lack it. */
|
|
5780
|
+
readonly waiting?: FieldKeyWaiting;
|
|
5781
|
+
/** Things worth a log line, never a refusal. */
|
|
5782
|
+
readonly notes: ReadonlyArray<string>;
|
|
5783
|
+
}
|
|
5784
|
+
|
|
5785
|
+
/** One recorded key id — its state and canary, never its key. */
|
|
5786
|
+
export declare interface FieldKeyRow {
|
|
5787
|
+
readonly keyId: string;
|
|
5788
|
+
readonly state: FieldKeyState;
|
|
5789
|
+
readonly canary: string;
|
|
5790
|
+
readonly registeredAt: Date | null;
|
|
5791
|
+
readonly activatedAt: Date | null;
|
|
5792
|
+
readonly replacedAt: Date | null;
|
|
5793
|
+
readonly retiredAt: Date | null;
|
|
5794
|
+
readonly requestedAt: Date | null;
|
|
5795
|
+
}
|
|
5796
|
+
|
|
5797
|
+
/** A key's state. `pending`: held, never active. `active`: new values are sealed
|
|
5798
|
+
* under it — exactly one. `decrypt-only`: was active, replaced; values may still
|
|
5799
|
+
* be sealed under it. `retired`: nothing is sealed under it any more. */
|
|
5800
|
+
export declare type FieldKeyState = 'pending' | 'active' | 'decrypt-only' | 'retired';
|
|
5801
|
+
|
|
5802
|
+
export declare interface FieldKeyStateRow {
|
|
5803
|
+
readonly keyId: string;
|
|
5804
|
+
readonly state: string;
|
|
5805
|
+
readonly activatedAt: string | null;
|
|
5806
|
+
readonly requestedAt: string | null;
|
|
5807
|
+
}
|
|
5808
|
+
|
|
5809
|
+
export declare interface FieldKeyStatus {
|
|
5810
|
+
/** The recorded keys and their states — empty before the first boot recorded any. */
|
|
5811
|
+
readonly keys: ReadonlyArray<FieldKeyStateRow>;
|
|
5812
|
+
/** Every process that holds a lease, live or not (`expiresAt` says which). */
|
|
5813
|
+
readonly holders: ReadonlyArray<FieldKeyHolderRow>;
|
|
5814
|
+
readonly locations: ReadonlyArray<SealedLocation>;
|
|
5815
|
+
/** Envelopes per key id, over every location. */
|
|
5816
|
+
readonly totals: Readonly<Record<string, number>>;
|
|
5817
|
+
readonly unnamed: number;
|
|
5818
|
+
readonly plaintext: number;
|
|
5819
|
+
/** Columns that could not be read — listed, never silently left out of the counts. */
|
|
5820
|
+
readonly unreadable: ReadonlyArray<UnreadableColumn>;
|
|
5821
|
+
}
|
|
5822
|
+
|
|
5823
|
+
/**
|
|
5824
|
+
* Count every sealed value in the database by the key it names. `declared` are
|
|
5825
|
+
* the app's tables: their `.encrypted()` columns are always reported (with
|
|
5826
|
+
* plaintext counted), the rest only where envelopes were found.
|
|
5827
|
+
*/
|
|
5828
|
+
export declare const fieldKeyStatus: (dialect: DialectId, declared: Iterable<unknown>) => Effect.Effect<{
|
|
5829
|
+
keys: FieldKeyStateRow[];
|
|
5830
|
+
holders: FieldKeyHolderRow[];
|
|
5831
|
+
locations: SealedLocation[];
|
|
5832
|
+
totals: Record<string, number>;
|
|
5833
|
+
unreadable: UnreadableColumn[];
|
|
5834
|
+
unnamed: number;
|
|
5835
|
+
plaintext: number;
|
|
5836
|
+
}, SqlError, SqlClient.SqlClient>;
|
|
5837
|
+
|
|
5838
|
+
export declare interface FieldKeyWaiting {
|
|
5839
|
+
readonly keyId: string;
|
|
5840
|
+
readonly holders: ReadonlyArray<string>;
|
|
5841
|
+
}
|
|
5842
|
+
|
|
5478
5843
|
/**
|
|
5479
5844
|
* Canonical fingerprint over `(table, predicate, indexHint?)`. The
|
|
5480
5845
|
* optional `indexHint` participates so two subscriptions with the same
|
|
@@ -5851,6 +6216,13 @@ export declare interface HealthConfigInput {
|
|
|
5851
6216
|
readonly readiness?: () => boolean | Promise<boolean>;
|
|
5852
6217
|
}
|
|
5853
6218
|
|
|
6219
|
+
/**
|
|
6220
|
+
* One heartbeat: renew this process's lease, complete a requested activation
|
|
6221
|
+
* once every live holder holds the key, and seal under the database's active
|
|
6222
|
+
* key from now on. Any holder can complete an activation another one requested.
|
|
6223
|
+
*/
|
|
6224
|
+
export declare const heartbeatFieldKeys: (store: DataStore, keyring: FieldKeyring, holder: FieldKeyHolder) => Promise<FieldKeyHeartbeat>;
|
|
6225
|
+
|
|
5854
6226
|
/** Define a histogram. `boundaries` default to the framework duration buckets. */
|
|
5855
6227
|
export declare const histogramMetric: (name: string, boundaries?: ReadonlyArray<number>, description?: string) => Metric.Histogram<number>;
|
|
5856
6228
|
|
|
@@ -5992,9 +6364,10 @@ export declare class InMemoryDataStore implements DataStore {
|
|
|
5992
6364
|
* to tell apart from "no such table".
|
|
5993
6365
|
*/
|
|
5994
6366
|
storedTables(): ReadonlyArray<StoredTableShape>;
|
|
6367
|
+
integrityQuery(descriptor: QueryDescriptor): Promise<ReadonlyArray<Row>>;
|
|
5995
6368
|
query(descriptor: QueryDescriptor): Promise<ReadonlyArray<Row>>;
|
|
5996
6369
|
insert(table: string, row: Row): Promise<Row>;
|
|
5997
|
-
insertMany(table: string, rows: ReadonlyArray<Row
|
|
6370
|
+
insertMany(table: string, rows: ReadonlyArray<Row>, options?: InsertManyOptions): Promise<ReadonlyArray<Row>>;
|
|
5998
6371
|
patchJson(table: string, primaryKey: RowKey, path: string, value: unknown, additionalPatch?: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
5999
6372
|
update(table: string, primaryKey: RowKey, patch: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
6000
6373
|
delete(table: string, primaryKey: RowKey): Promise<boolean>;
|
|
@@ -6026,8 +6399,9 @@ export declare const insertIgnoreRowOutcomeEffect: <T extends AnyWritableTable>(
|
|
|
6026
6399
|
readonly outcome: "inserted" | "ignored";
|
|
6027
6400
|
}, StoreError>;
|
|
6028
6401
|
|
|
6029
|
-
/** `insertRowEffect`'s batch — every element checked against `InferInsertRow<T>`.
|
|
6030
|
-
|
|
6402
|
+
/** `insertRowEffect`'s batch — every element checked against `InferInsertRow<T>`.
|
|
6403
|
+
* `{ returning: 'none' }` resolves to `[]` without reading the rows back. */
|
|
6404
|
+
export declare const insertManyRowsEffect: <T extends AnyWritableTable>(store: EffectInsertManyStore, table: T, rows: ReadonlyArray<InferInsertRow<T>>, options?: InsertManyOptions) => Effect.Effect<ReadonlyArray<InferRow<T>>, StoreError>;
|
|
6031
6405
|
|
|
6032
6406
|
/**
|
|
6033
6407
|
* Insert a row, typed against the table, on the Effect channel.
|
|
@@ -6132,6 +6506,10 @@ export { inspectWorkflow }
|
|
|
6132
6506
|
|
|
6133
6507
|
export declare const installApprovalGate: (gate: ApprovalGateApi) => void;
|
|
6134
6508
|
|
|
6509
|
+
/** Turn on read capture for cached computes — called at boot when any query
|
|
6510
|
+
* declares `cache:`. Until then the request store is not wrapped for it. */
|
|
6511
|
+
export declare const installComputedQueryCacheCapture: () => void;
|
|
6512
|
+
|
|
6135
6513
|
/**
|
|
6136
6514
|
* Install the resolver that answers `guards: [{ action, resourceType }]`.
|
|
6137
6515
|
*
|
|
@@ -6235,6 +6613,9 @@ export declare const isExpectationDefinition: (value: unknown) => value is Expec
|
|
|
6235
6613
|
|
|
6236
6614
|
export declare const isExperimentDefinition: (value: unknown) => value is ExperimentDefinition;
|
|
6237
6615
|
|
|
6616
|
+
/** Is this cipher a keyring (ids, per-key seal and open), not a bare cipher? */
|
|
6617
|
+
export declare const isFieldKeyring: (cipher: FieldCipher | undefined) => cipher is FieldKeyring;
|
|
6618
|
+
|
|
6238
6619
|
export { isForeignKeyViolation }
|
|
6239
6620
|
|
|
6240
6621
|
/**
|
|
@@ -6461,7 +6842,7 @@ export declare interface KvFacade {
|
|
|
6461
6842
|
readonly service: Effect.Success<typeof Kv>;
|
|
6462
6843
|
/** The resolved backend kind — for boot logging. */
|
|
6463
6844
|
readonly backend: 'database' | 'redis' | 'memory';
|
|
6464
|
-
/**
|
|
6845
|
+
/** Release this consumer runtime; an injected registry retains its pools. */
|
|
6465
6846
|
readonly dispose: () => Promise<void>;
|
|
6466
6847
|
}
|
|
6467
6848
|
|
|
@@ -6470,6 +6851,10 @@ export declare interface KvFacadeOptions {
|
|
|
6470
6851
|
readonly store: DataStore;
|
|
6471
6852
|
/** Defaults to `process.env`. */
|
|
6472
6853
|
readonly env?: NodeJS.ProcessEnv;
|
|
6854
|
+
readonly backend?: 'database' | 'redis' | 'memory';
|
|
6855
|
+
readonly connectionName?: string;
|
|
6856
|
+
readonly keyPrefix?: string;
|
|
6857
|
+
readonly connections?: RespConnections;
|
|
6473
6858
|
}
|
|
6474
6859
|
|
|
6475
6860
|
/**
|
|
@@ -6591,6 +6976,27 @@ export declare interface LocalityAwareOptions {
|
|
|
6591
6976
|
*/
|
|
6592
6977
|
export declare const localityAwareSelector: (options: LocalityAwareOptions) => ReplicaSelector;
|
|
6593
6978
|
|
|
6979
|
+
/** One location's outcome. */
|
|
6980
|
+
export declare interface LocationRekey {
|
|
6981
|
+
readonly table: string;
|
|
6982
|
+
readonly column: string;
|
|
6983
|
+
readonly cells: number;
|
|
6984
|
+
readonly rekeyed: number;
|
|
6985
|
+
readonly current: number;
|
|
6986
|
+
readonly unresolved: number;
|
|
6987
|
+
/** Cells the app changed between the read and the write — run again. */
|
|
6988
|
+
readonly changedMeanwhile: number;
|
|
6989
|
+
/** Values that need a re-key in a table with no single-column primary key to address the cell by. */
|
|
6990
|
+
readonly unaddressable: number;
|
|
6991
|
+
}
|
|
6992
|
+
|
|
6993
|
+
/** Read the current key row within its expected tenant under a write fence.
|
|
6994
|
+
* Supply an existing transaction after the application's organization/account
|
|
6995
|
+
* fences and keep it through the protected write. Null matches unassigned
|
|
6996
|
+
* keys only. The internal row uses the normal store codec; never return it in
|
|
6997
|
+
* a public response. This is not bearer verification or an authorization grant. */
|
|
6998
|
+
export declare const lockApiKeyById: (store: DataStore, id: string, tenantId: string | null) => Promise<ApiKeyRow | null>;
|
|
6999
|
+
|
|
6594
7000
|
export declare interface LogTraceContext {
|
|
6595
7001
|
readonly traceId: string;
|
|
6596
7002
|
readonly spanId?: string;
|
|
@@ -6662,7 +7068,7 @@ log?: SchedulerLogger) => Coordinator;
|
|
|
6662
7068
|
* tampered / wrong-key value AND on a bound value read at another address —
|
|
6663
7069
|
* both surface as a read error, never silent corruption.
|
|
6664
7070
|
*/
|
|
6665
|
-
export declare const makeAesCipher: (key: Buffer) => FieldCipher;
|
|
7071
|
+
export declare const makeAesCipher: (key: Buffer, keyId?: string) => FieldCipher;
|
|
6666
7072
|
|
|
6667
7073
|
export declare const makeApiKeyService: (store: ApiKeyStore, opts?: {
|
|
6668
7074
|
prefix?: string;
|
|
@@ -6690,6 +7096,61 @@ export declare const makeApiKeyUsageFlusher: (store: ApiKeyStore) => (id: string
|
|
|
6690
7096
|
readonly lastUsedAt: number;
|
|
6691
7097
|
}) => Promise<void>;
|
|
6692
7098
|
|
|
7099
|
+
/** In-memory, bounded finalized-bucket queue. Current instrumentation is partial;
|
|
7100
|
+
* this collector cannot certify complete workload coverage merely from uptime. */
|
|
7101
|
+
export declare const makeApiRoleBucketSampler: (input: {
|
|
7102
|
+
readonly replicaId: string;
|
|
7103
|
+
readonly startedAt: number;
|
|
7104
|
+
readonly role: string;
|
|
7105
|
+
readonly workloads: ReadonlyArray<ApiWorkload>;
|
|
7106
|
+
readonly epochNow: number;
|
|
7107
|
+
readonly monotonicNow: number;
|
|
7108
|
+
}) => {
|
|
7109
|
+
record(segment: {
|
|
7110
|
+
readonly workload: ApiWorkload;
|
|
7111
|
+
readonly from: number;
|
|
7112
|
+
readonly until: number;
|
|
7113
|
+
}): void;
|
|
7114
|
+
/** Heartbeat every30s. Delays >60s or clock skew >1s conservatively invalidate
|
|
7115
|
+
* affected intervals; never spread elapsed request time across buckets. */
|
|
7116
|
+
advance(monotonicNow: number, epochNow: number): void;
|
|
7117
|
+
pending(): ReadonlyArray<ApiRoleWorkloadBucket>;
|
|
7118
|
+
acknowledge(from: number): void;
|
|
7119
|
+
status: () => {
|
|
7120
|
+
pendingBuckets: number;
|
|
7121
|
+
droppedBuckets: number;
|
|
7122
|
+
rejectedSegments: number;
|
|
7123
|
+
};
|
|
7124
|
+
};
|
|
7125
|
+
|
|
7126
|
+
/** Measures only the synchronous execution of a callback, including throws.
|
|
7127
|
+
* Returning a Promise measures its construction, not its awaited lifetime.
|
|
7128
|
+
* Each resumed async callback must be instrumented separately. No wall-time
|
|
7129
|
+
* request duration may be fed into this counter as a substitute for loop time.
|
|
7130
|
+
* Nested calls on this recorder suspend their parent, so time is exclusive. */
|
|
7131
|
+
export declare const makeApiRoleWorkloadMetrics: (roles: ReadonlyArray<string>, options?: {
|
|
7132
|
+
readonly now?: () => number;
|
|
7133
|
+
readonly onSegment?: (segment: {
|
|
7134
|
+
readonly workload: ApiWorkload;
|
|
7135
|
+
readonly from: number;
|
|
7136
|
+
readonly until: number;
|
|
7137
|
+
}) => void;
|
|
7138
|
+
}) => {
|
|
7139
|
+
role: string;
|
|
7140
|
+
observationErrors: () => number;
|
|
7141
|
+
/** Effect4's tracer context surrounds each synchronous primitive, including
|
|
7142
|
+
* the first, resumed and inherited child work. Preserve the existing tracer;
|
|
7143
|
+
* Promise callbacks outside evaluation still use measureSync explicitly. */
|
|
7144
|
+
observeEffect<A, E, R>(effect: Effect.Effect<A, E, R>, workload: ApiWorkload): Effect.Effect<A, E, R>;
|
|
7145
|
+
measureSync<A>(workload: ApiWorkload, run: () => A): A;
|
|
7146
|
+
/** Local totals, not a 24-hour history or evidence of full instrumentation. */
|
|
7147
|
+
snapshot(): ReadonlyArray<{
|
|
7148
|
+
readonly role: string;
|
|
7149
|
+
readonly workload: ApiWorkload;
|
|
7150
|
+
readonly seconds: number;
|
|
7151
|
+
}>;
|
|
7152
|
+
};
|
|
7153
|
+
|
|
6693
7154
|
/** Build the `ctx.access` slice for a subject. Reads the effective-scope seam
|
|
6694
7155
|
* LIVE (via getters/closures) so a scope rbac resolves after context
|
|
6695
7156
|
* construction is still reflected. Used by the shared AppContext builder AND
|
|
@@ -6713,7 +7174,7 @@ export declare interface MakeApprovalGateOptions {
|
|
|
6713
7174
|
|
|
6714
7175
|
/** Build the `ctx.kv` facade. `KV_BACKEND` picks the backend; unknown values
|
|
6715
7176
|
* fall back to `database`. */
|
|
6716
|
-
export declare const makeAsyncKv: ({ store, env }: KvFacadeOptions) => Promise<KvFacade>;
|
|
7177
|
+
export declare const makeAsyncKv: ({ store, env, backend: configuredBackend, connectionName, keyPrefix, connections }: KvFacadeOptions) => Promise<KvFacade>;
|
|
6717
7178
|
|
|
6718
7179
|
/**
|
|
6719
7180
|
* The `AuthMiddleware` + `ConnectionInfoMiddleware` pair every rpc surface
|
|
@@ -6832,19 +7293,45 @@ export declare const makeEventPublisher: (ctx: EventPublishContext) => EventPubl
|
|
|
6832
7293
|
|
|
6833
7294
|
export declare const makeEventsFacade: (options: EventsFacadeOptions) => EventsAppContext;
|
|
6834
7295
|
|
|
7296
|
+
/** Pass one instance to a host's scheduler factories and trigger route. */
|
|
7297
|
+
export declare const makeExternalizedTaskRegistry: () => ExternalizedTaskRegistry;
|
|
7298
|
+
|
|
6835
7299
|
/**
|
|
6836
7300
|
* Derive a key from a passphrase and build the cipher — with the keys a
|
|
6837
|
-
* ROTATION retires, when there are any.
|
|
7301
|
+
* ROTATION retires, when there are any. Ids are derived from the keys
|
|
7302
|
+
* (`fieldKeyIdOf`); a previous key equal to the current one is skipped.
|
|
6838
7303
|
*
|
|
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.
|
|
7304
|
+
* Writes use the current key; reads open a value by the key it names, or by
|
|
7305
|
+
* trying the current one, then each previous one. GCM authenticates, so a
|
|
7306
|
+
* wrong key fails its tag rather than producing garbage. Without this, a key
|
|
7307
|
+
* change made every value written before it unreadable — measured: every
|
|
7308
|
+
* sleeping or suspended run of an `encrypted: true` workflow failed its replay
|
|
7309
|
+
* with `MalformedMessage`, and every `.encrypted()` column read failed.
|
|
6845
7310
|
*/
|
|
6846
7311
|
export declare const makeFieldCipher: (passphrase: string, previous?: ReadonlyArray<string>) => FieldCipher;
|
|
6847
7312
|
|
|
7313
|
+
/**
|
|
7314
|
+
* A cipher over a keyring: new values are sealed under the active key and name
|
|
7315
|
+
* it; a value is opened by the key it names (a lookup), and one written before
|
|
7316
|
+
* values named their key by trying each key, the active one first.
|
|
7317
|
+
*
|
|
7318
|
+
* A named key that is not in the keyring is a refusal that names it, so an
|
|
7319
|
+
* operator reads "sealed under k2026a, which this process does not hold"
|
|
7320
|
+
* instead of a GCM failure. A named key that does not open the value (an id
|
|
7321
|
+
* that was altered) falls back to trying the others — the id is a hint, GCM is
|
|
7322
|
+
* the authority.
|
|
7323
|
+
*/
|
|
7324
|
+
export declare const makeFieldKeyring: (config: FieldKeyringConfig, options?: {
|
|
7325
|
+
/**
|
|
7326
|
+
* Refuse to seal until {@link FieldKeyring.activate} has run — the boot's
|
|
7327
|
+
* keyring sets this, so nothing is sealed under the configured key before
|
|
7328
|
+
* the database has said which key is active. A value sealed under a key the
|
|
7329
|
+
* fleet has not accepted is one a replica on the previous configuration
|
|
7330
|
+
* cannot read.
|
|
7331
|
+
*/
|
|
7332
|
+
readonly sealOnlyOnceActivated?: boolean;
|
|
7333
|
+
}) => FieldKeyring;
|
|
7334
|
+
|
|
6848
7335
|
/** Build the fluent `select` / `update` / `delete` entry functions over a
|
|
6849
7336
|
* backend + scope. Wired into `wrapStoreWithMixinBehaviour` so they hang
|
|
6850
7337
|
* off `ctx.store` alongside the keyed `query`/`insert`/`update`/`delete`. */
|
|
@@ -6867,12 +7354,18 @@ export declare const makeLazyWorkflowFacade: (resolve: () => WorkflowsAppContext
|
|
|
6867
7354
|
export declare const makeListConnectionsExecutor: (deps: ConnectionBuiltinDeps) => (_input: Record<string, never>, ctx: ConnectionExecutorCtx) => Promise<ReadonlyArray<ConnectionState_2>>;
|
|
6868
7355
|
|
|
6869
7356
|
/**
|
|
6870
|
-
* Build
|
|
6871
|
-
*
|
|
6872
|
-
*
|
|
6873
|
-
* produced, `encodeUnknownSync` never throws. `undefined` schema → no codec.
|
|
7357
|
+
* Build one input/output contract from both declared schemas. Refuse incompatible
|
|
7358
|
+
* values with payload-free errors; never return or log an old raw response
|
|
7359
|
+
* when the current output contract cannot decode it. Input is captured from its schema before keyed acquisition.
|
|
6874
7360
|
*/
|
|
6875
|
-
export declare const
|
|
7361
|
+
export declare const makeMutationCodec: (inputSchema: Schema.Top, outputSchema: Schema.Top, admit: MutationCodec<unknown>["admit"]) => MutationCodec<unknown>;
|
|
7362
|
+
|
|
7363
|
+
/** Current admission for a keyed unary call, including its cached result.
|
|
7364
|
+
* Pure refresher binding is separate from business interceptors/executors. */
|
|
7365
|
+
export declare const makeMutationReplayAdmission: (procedure: MutationLike, kind: "mutation" | "action", options?: {
|
|
7366
|
+
readonly defaultDeny?: boolean;
|
|
7367
|
+
readonly bindReplayAuthority?: RpcReplayAuthorityBinding | undefined;
|
|
7368
|
+
}) => ((input: unknown, request: ServeRequestContext) => Promise<void>);
|
|
6876
7369
|
|
|
6877
7370
|
/**
|
|
6878
7371
|
* Build the shared mutation runner. Used by BOTH the rpc WS handler and
|
|
@@ -6946,7 +7439,7 @@ export declare const makeOutboxFacade: (deps: OutboxFacadeDeps) => OutboxFacade;
|
|
|
6946
7439
|
*/
|
|
6947
7440
|
export declare const makeProcessAdapter: (supervisor: AppSupervisor) => WakeAdapter;
|
|
6948
7441
|
|
|
6949
|
-
export declare const makeQueryDescriptorProducer: <D>(deps: QueryProducerDeps<D
|
|
7442
|
+
export declare const makeQueryDescriptorProducer: <D>(deps: QueryProducerDeps<D>, workloadOverride?: "rpc" | "subscriptions") => (query: MutationLike, input: unknown) => (requestContext: ServeRequestContext) => ComputedQuery | D | Effect.Effect<ComputedQuery | D, unknown, never>;
|
|
6950
7443
|
|
|
6951
7444
|
export declare const makeQueryFinalizer: (options: QueryFinalizeOptions) => ((descriptor: QueryDescriptor, subject: {
|
|
6952
7445
|
readonly tenantId?: string | null;
|
|
@@ -7385,35 +7878,22 @@ export declare const MIN_LEVEL_RESYNC_MS = 30000;
|
|
|
7385
7878
|
/** Mint a fresh service token. `voltro dev` and `voltro secret generate` call this. */
|
|
7386
7879
|
export declare const mintServiceToken: () => string;
|
|
7387
7880
|
|
|
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;
|
|
7881
|
+
export { MirrorVersion }
|
|
7413
7882
|
|
|
7414
7883
|
/** The error `.one()` throws: the factory's, or the framework's `NoRowFound`. */
|
|
7415
7884
|
export declare const missingRowError: (info: NoRowFoundInfo, onMissing: OnMissingRow | undefined) => unknown;
|
|
7416
7885
|
|
|
7886
|
+
/**
|
|
7887
|
+
* Store encoded wire output and decode it against the current output contract.
|
|
7888
|
+
* A failed codec never falls back to an unvalidated raw response.
|
|
7889
|
+
*/
|
|
7890
|
+
export declare interface MutationCodec<Output> {
|
|
7891
|
+
readonly input: Schema.Top;
|
|
7892
|
+
readonly admit: (input: unknown, context: RuntimeContext) => Promise<void>;
|
|
7893
|
+
readonly encode: (output: Output) => unknown;
|
|
7894
|
+
readonly decode: (stored: unknown) => Output;
|
|
7895
|
+
}
|
|
7896
|
+
|
|
7417
7897
|
export declare interface MutationLifecycle {
|
|
7418
7898
|
readonly afterCommit: (work: () => Promise<unknown>) => void;
|
|
7419
7899
|
/** Already selected physical, namespace-bound nontransactional store.
|
|
@@ -7425,8 +7905,16 @@ export declare interface MutationLifecycle {
|
|
|
7425
7905
|
export declare interface MutationLike {
|
|
7426
7906
|
readonly descriptor: {
|
|
7427
7907
|
readonly name: string;
|
|
7908
|
+
readonly undo?: {
|
|
7909
|
+
readonly capture: false;
|
|
7910
|
+
readonly reason: string;
|
|
7911
|
+
} | undefined;
|
|
7428
7912
|
readonly source?: string | ReadonlyArray<string> | undefined;
|
|
7429
7913
|
readonly guards?: ReadonlyArray<AnyCheckSpec> | undefined;
|
|
7914
|
+
/** Query only — read by the computed-query cache (`computedQueryCache.ts`). */
|
|
7915
|
+
readonly cache?: QueryCacheLike | undefined;
|
|
7916
|
+
readonly input?: Schema.Top | undefined;
|
|
7917
|
+
readonly output?: Schema.Top | undefined;
|
|
7430
7918
|
/** The second-human control (mutation/action only). Enforced by
|
|
7431
7919
|
* `enforceApprovalGate`, immediately after `enforceGuards`. */
|
|
7432
7920
|
readonly requiresApproval?: AnyApprovalPolicy | undefined;
|
|
@@ -7441,25 +7929,20 @@ export declare interface MutationLike {
|
|
|
7441
7929
|
executor(input: unknown, ctx: unknown): unknown;
|
|
7442
7930
|
}
|
|
7443
7931
|
|
|
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
7932
|
export declare interface MutationRunnerDeps {
|
|
7933
|
+
/** Measures only the synchronous executor entry, never an awaited result. */
|
|
7934
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
7459
7935
|
readonly outcomeOutbox?: (request: ServeRequestContext) => OutboxEnqueueFacade | undefined;
|
|
7460
7936
|
/** A failure aborts the business transaction; transient contention replays
|
|
7461
7937
|
* executor and hook together. Never perform external I/O here. */
|
|
7462
7938
|
readonly beforeMutationCommit?: ServeMutationCommitHook | undefined;
|
|
7939
|
+
/**
|
|
7940
|
+
* Resolves once the cache invalidations this process started have reached
|
|
7941
|
+
* the cache. Awaited after commit, BEFORE the mutation answers — without it
|
|
7942
|
+
* the writer's next read raced its own invalidation and was served the
|
|
7943
|
+
* pre-write entry. Both boot paths pass `wireCacheInvalidation`'s `settled`.
|
|
7944
|
+
*/
|
|
7945
|
+
readonly settleCacheInvalidations?: () => Promise<void>;
|
|
7463
7946
|
readonly store: TransactionalStore;
|
|
7464
7947
|
/** Select and provision the request's physical store before opening its
|
|
7465
7948
|
* transaction. Resolved once, including across retries and post-commit folds. */
|
|
@@ -7524,6 +8007,19 @@ export declare interface MutationStore extends DataStore {
|
|
|
7524
8007
|
hardDelete(table: string, primaryKey: RowKey): Promise<boolean>;
|
|
7525
8008
|
}
|
|
7526
8009
|
|
|
8010
|
+
/**
|
|
8011
|
+
* The encoding a body of `size` bytes would be compressed with — `undefined`
|
|
8012
|
+
* unless (enabled ∧ type compressible ∧ size ≥ threshold ∧ the client accepts
|
|
8013
|
+
* an encoding). Lets a caller that has not read the body yet (a static file
|
|
8014
|
+
* known only by `stat`) take the same decision `maybeCompress` takes.
|
|
8015
|
+
*/
|
|
8016
|
+
export declare const negotiatedCompression: (input: {
|
|
8017
|
+
readonly size: number;
|
|
8018
|
+
readonly contentType: string | undefined;
|
|
8019
|
+
readonly acceptEncoding: string | undefined;
|
|
8020
|
+
readonly options?: CompressionOptions | undefined;
|
|
8021
|
+
}) => NegotiatedEncoding | undefined;
|
|
8022
|
+
|
|
7527
8023
|
export declare type NegotiatedEncoding = 'br' | 'gzip';
|
|
7528
8024
|
|
|
7529
8025
|
/** Pick the encoding the client accepts — brotli preferred, gzip second,
|
|
@@ -7531,24 +8027,7 @@ export declare type NegotiatedEncoding = 'br' | 'gzip';
|
|
|
7531
8027
|
* (a client sending both accepts both). */
|
|
7532
8028
|
export declare const negotiateEncoding: (acceptEncoding: string | undefined) => NegotiatedEncoding | undefined;
|
|
7533
8029
|
|
|
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;
|
|
8030
|
+
export { newTraceId }
|
|
7552
8031
|
|
|
7553
8032
|
/**
|
|
7554
8033
|
* The backoff curve, extracted so it can be asserted directly — a schedule
|
|
@@ -7665,6 +8144,14 @@ export declare interface NoRowFoundInfo {
|
|
|
7665
8144
|
readonly found: number;
|
|
7666
8145
|
}
|
|
7667
8146
|
|
|
8147
|
+
/** Record a non-table input of the cached compute in flight, if any. Called by
|
|
8148
|
+
* the framework surfaces that reach outside the database. */
|
|
8149
|
+
export declare const noteCacheVolatile: (reason: string) => void;
|
|
8150
|
+
|
|
8151
|
+
/** Note that the query in flight depends on `table` without reading it
|
|
8152
|
+
* through `ctx.store`. */
|
|
8153
|
+
export declare const noteDependency: (table: string) => void;
|
|
8154
|
+
|
|
7668
8155
|
/** Note one read against the in-flight procedure. No scope → nothing happens. */
|
|
7669
8156
|
export declare const noteRead: (descriptor: QueryDescriptor) => void;
|
|
7670
8157
|
|
|
@@ -7694,6 +8181,45 @@ export declare interface Notification {
|
|
|
7694
8181
|
readonly newMatched: boolean;
|
|
7695
8182
|
}
|
|
7696
8183
|
|
|
8184
|
+
/** What a cross-environment restore did to the sealed values it cannot read. */
|
|
8185
|
+
export declare interface NullSealedReport {
|
|
8186
|
+
readonly nulled: ReadonlyArray<{
|
|
8187
|
+
readonly table: string;
|
|
8188
|
+
readonly column: string;
|
|
8189
|
+
readonly count: number;
|
|
8190
|
+
}>;
|
|
8191
|
+
readonly unreadable: ReadonlyArray<{
|
|
8192
|
+
readonly table: string;
|
|
8193
|
+
readonly column: string;
|
|
8194
|
+
readonly count: number;
|
|
8195
|
+
}>;
|
|
8196
|
+
/** Recorded key ids removed: they came with the restored data and this environment does not hold them. */
|
|
8197
|
+
readonly forgottenKeys: ReadonlyArray<string>;
|
|
8198
|
+
readonly unreadableColumns: ReadonlyArray<UnreadableColumn>;
|
|
8199
|
+
}
|
|
8200
|
+
|
|
8201
|
+
/**
|
|
8202
|
+
* After restoring another environment's database: write NULL for every whole
|
|
8203
|
+
* sealed value no configured key opens — the source ciphertext is useless here
|
|
8204
|
+
* and users re-enter it — count the sealed copies inside other values (they
|
|
8205
|
+
* cannot be nulled), and forget the restored key records and leases this
|
|
8206
|
+
* environment does not hold, so the next boot records its own keys.
|
|
8207
|
+
*/
|
|
8208
|
+
export declare const nullUnreadableSealedValues: (dialect: DialectId, keyring: FieldKeyring | undefined, declared: Iterable<unknown>) => Effect.Effect<{
|
|
8209
|
+
nulled: {
|
|
8210
|
+
table: string;
|
|
8211
|
+
column: string;
|
|
8212
|
+
count: number;
|
|
8213
|
+
}[];
|
|
8214
|
+
unreadable: {
|
|
8215
|
+
table: string;
|
|
8216
|
+
column: string;
|
|
8217
|
+
count: number;
|
|
8218
|
+
}[];
|
|
8219
|
+
forgottenKeys: string[];
|
|
8220
|
+
unreadableColumns: UnreadableColumn[];
|
|
8221
|
+
}, SqlError, SqlClient.SqlClient>;
|
|
8222
|
+
|
|
7697
8223
|
export declare interface OAuth2ConnectionDefinition extends ConnectionDefinitionCommon {
|
|
7698
8224
|
readonly kind: 'oauth2';
|
|
7699
8225
|
readonly authorizeUrl: string;
|
|
@@ -7734,6 +8260,17 @@ export declare type OAuthClientCredential = string | (() => string);
|
|
|
7734
8260
|
|
|
7735
8261
|
export declare const oauthCredentialValue: (credential: OAuthClientCredential) => string;
|
|
7736
8262
|
|
|
8263
|
+
/** Preserve the caller's environment, Exit and cancellation. Observation is
|
|
8264
|
+
* installed before the body's first primitive; it creates no detached runtime. */
|
|
8265
|
+
export declare const observeApiRoleEffect: <A, E>(effect: Effect.Effect<A, E, never>, metrics: ReturnType<typeof makeApiRoleWorkloadMetrics>, workload: ApiWorkload) => Effect.Effect<A, E, never>;
|
|
8266
|
+
|
|
8267
|
+
/**
|
|
8268
|
+
* Test seam: a ConnectionInfo layer that hands every request's headers to
|
|
8269
|
+
* `observe` and reports only the client id. It never authenticates and is not a
|
|
8270
|
+
* boot path; it lives here so ConnectionInfo keeps one construction site.
|
|
8271
|
+
*/
|
|
8272
|
+
export declare const observeConnectionHeaders: (observe: (headers: Readonly<Record<string, string | undefined>>, clientId: number) => void) => Layer.Layer<ConnectionInfoMiddleware>;
|
|
8273
|
+
|
|
7737
8274
|
/** One recorded `(procedure → table, op)` edge. */
|
|
7738
8275
|
export declare interface ObservedEdge {
|
|
7739
8276
|
readonly tag: string;
|
|
@@ -7817,6 +8354,16 @@ export declare type OnMissingRow = (info: NoRowFoundInfo) => unknown;
|
|
|
7817
8354
|
*/
|
|
7818
8355
|
export declare const onProcessShutdown: (hook: () => void | Promise<void>) => (() => void);
|
|
7819
8356
|
|
|
8357
|
+
/**
|
|
8358
|
+
* Open every envelope in one cell with `keyring` — each under the address it
|
|
8359
|
+
* was sealed under, found the same way a re-key finds it. A keyring holding the
|
|
8360
|
+
* active key alone answers "does anything still need another key?".
|
|
8361
|
+
*/
|
|
8362
|
+
export declare const openCell: (text: string, keyring: FieldKeyring, context: CellContext) => {
|
|
8363
|
+
readonly opened: number;
|
|
8364
|
+
readonly unopened: number;
|
|
8365
|
+
};
|
|
8366
|
+
|
|
7820
8367
|
/** Thrown by `.expectVersion(n).set(...)` when the optimistic-lock guard
|
|
7821
8368
|
* matched no row (the row was concurrently updated or deleted). */
|
|
7822
8369
|
export declare class OptimisticLockError extends OptimisticLockError_base {
|
|
@@ -8112,6 +8659,9 @@ export declare interface PairInput {
|
|
|
8112
8659
|
*/
|
|
8113
8660
|
export declare const parseApprovalInterval: (spec: string) => number | null;
|
|
8114
8661
|
|
|
8662
|
+
/** `unity/0.1.0; surface=<64 hex>` → its parts; anything else is not an engine SDK. */
|
|
8663
|
+
export declare const parseEngineSdkHeader: (value: string) => Omit<EngineClient, "id" | "connectedAt"> | null;
|
|
8664
|
+
|
|
8115
8665
|
/** Parse a `traceparent` header. Returns null when malformed or when
|
|
8116
8666
|
* the all-zero invalid ids are present (per the spec those are
|
|
8117
8667
|
* treated as "no parent"). */
|
|
@@ -8316,8 +8866,7 @@ export declare type ProbeKind = 'liveness' | 'readiness' | 'startup';
|
|
|
8316
8866
|
* columns, which have no wire representation at all. */
|
|
8317
8867
|
export declare const projectConnectionState: (definition: ConnectionDefinition, row: AnyRow_2 | undefined) => ConnectionState_2;
|
|
8318
8868
|
|
|
8319
|
-
|
|
8320
|
-
export declare type PropertyFilter = Readonly<Record<string, string | number | boolean | null>>;
|
|
8869
|
+
export { PropertyFilter }
|
|
8321
8870
|
|
|
8322
8871
|
export declare interface ProvenanceActor {
|
|
8323
8872
|
readonly id: string | null;
|
|
@@ -8471,8 +9020,25 @@ export declare interface PumpOptions {
|
|
|
8471
9020
|
*/
|
|
8472
9021
|
export declare const pumpOutbox: <T>(outbox: SubscriptionOutbox<T>, sink: OutboxSink<T>, label: string, options?: PumpOptions) => Promise<void>;
|
|
8473
9022
|
|
|
9023
|
+
/** A query's declared `cache:` block, structurally — see `QueryCacheConfig`. */
|
|
9024
|
+
export declare interface QueryCacheLike {
|
|
9025
|
+
readonly ttl: number | string;
|
|
9026
|
+
readonly swr?: number | string | undefined;
|
|
9027
|
+
readonly scope: ComputedCacheScope;
|
|
9028
|
+
readonly volatile?: boolean | undefined;
|
|
9029
|
+
}
|
|
9030
|
+
|
|
9031
|
+
/** A query's declared `cache:`, parsed — `undefined` when the ttl does not
|
|
9032
|
+
* parse (the cache is then off for that query; `voltro doctor` says so). */
|
|
9033
|
+
export declare const queryCachePolicy: (cache: {
|
|
9034
|
+
readonly ttl: number | string;
|
|
9035
|
+
readonly swr?: number | string | undefined;
|
|
9036
|
+
readonly scope: ComputedCacheScope;
|
|
9037
|
+
readonly volatile?: boolean | undefined;
|
|
9038
|
+
}) => ComputedQueryCachePolicy | undefined;
|
|
9039
|
+
|
|
8474
9040
|
/**
|
|
8475
|
-
* The
|
|
9041
|
+
* The read scopes, composed once, for every path that finalises a descriptor.
|
|
8476
9042
|
*
|
|
8477
9043
|
* **The primitives above were extracted so there is "no second copy that could
|
|
8478
9044
|
* drift" — and then the COMPOSITION became the second copy.** `voltro dev`
|
|
@@ -8498,6 +9064,8 @@ export declare const pumpOutbox: <T>(outbox: SubscriptionOutbox<T>, sink: Outbox
|
|
|
8498
9064
|
export declare interface QueryFinalizeOptions {
|
|
8499
9065
|
readonly tenantScopedTables: ReadonlySet<string>;
|
|
8500
9066
|
readonly softDeleteScopedTables: ReadonlySet<string>;
|
|
9067
|
+
/** Tables carrying expires(); hosts derive this set from the schema registry. */
|
|
9068
|
+
readonly expiresScopedTables?: ReadonlySet<string>;
|
|
8501
9069
|
readonly observe?: {
|
|
8502
9070
|
/** Before scoping — sees what the handler asked for. */
|
|
8503
9071
|
readonly beforeScope?: (descriptor: QueryDescriptor, subject: {
|
|
@@ -8515,6 +9083,9 @@ export declare type QueryLike<R = Row_7> = QueryDescriptor<R> | {
|
|
|
8515
9083
|
};
|
|
8516
9084
|
|
|
8517
9085
|
export declare interface QueryProducerDeps<D> {
|
|
9086
|
+
readonly workloadMetrics?: ReturnType<typeof makeApiRoleWorkloadMetrics>;
|
|
9087
|
+
/** See {@link ComputedQueryCacheDeps}. */
|
|
9088
|
+
readonly computedCache?: ComputedQueryCacheDeps;
|
|
8518
9089
|
readonly buildContext: (request: ServeRequestContext) => {
|
|
8519
9090
|
readonly store: unknown;
|
|
8520
9091
|
};
|
|
@@ -8827,6 +9398,19 @@ export declare interface ReactiveSocketTunables {
|
|
|
8827
9398
|
* (unit tests, a bare library use). */
|
|
8828
9399
|
export declare const reactiveSocketTunables: () => ReactiveSocketTunables;
|
|
8829
9400
|
|
|
9401
|
+
/** Bounded exact-incarnation read. Corruption/read failure is raised, never
|
|
9402
|
+
* flattened to no observations. Membership expiry does not delete this history. */
|
|
9403
|
+
export declare const readApiRoleWorkloadWindow: (store: DataStore, input: {
|
|
9404
|
+
readonly now: number;
|
|
9405
|
+
readonly replicaId: string;
|
|
9406
|
+
readonly startedAt: number;
|
|
9407
|
+
readonly role: string;
|
|
9408
|
+
readonly requiredWorkloads: ReadonlyArray<ApiWorkload>;
|
|
9409
|
+
}) => Promise<{
|
|
9410
|
+
buckets: ApiRoleWorkloadBucket[];
|
|
9411
|
+
assessment: ApiRoleWindowAssessment;
|
|
9412
|
+
}>;
|
|
9413
|
+
|
|
8830
9414
|
export declare interface ReadClassification {
|
|
8831
9415
|
/** Tables whose ROWS can reach the caller: the queried table and its joins. */
|
|
8832
9416
|
readonly composed: ReadonlySet<string>;
|
|
@@ -8834,6 +9418,14 @@ export declare interface ReadClassification {
|
|
|
8834
9418
|
readonly restricting: ReadonlySet<string>;
|
|
8835
9419
|
}
|
|
8836
9420
|
|
|
9421
|
+
/** Every recorded lease, live or not. */
|
|
9422
|
+
export declare const readFieldKeyHolders: (store: DataStore) => Promise<ReadonlyArray<FieldKeyHolderRecord>>;
|
|
9423
|
+
|
|
9424
|
+
export declare const readFieldKeyReports: (store: DataStore) => Promise<FieldKeyReports>;
|
|
9425
|
+
|
|
9426
|
+
/** The recorded keys, without decrypting anything. */
|
|
9427
|
+
export declare const readFieldKeys: (store: DataStore) => Promise<ReadonlyArray<FieldKeyRow>>;
|
|
9428
|
+
|
|
8837
9429
|
/** First-or-null for a boot DataStore or a query-only tuple source. It invokes
|
|
8838
9430
|
* the supplied query path, preserving that path's filters and codecs. A raw
|
|
8839
9431
|
* driver remains raw; this helper does not add request scoping. */
|
|
@@ -8973,6 +9565,12 @@ export declare const recordExternalMissed: (name: string, count?: number) => voi
|
|
|
8973
9565
|
|
|
8974
9566
|
export declare const recordExternalTrigger: (name: string, outcome: "accepted" | "duplicate" | "noOccurrence" | "ahead" | "notExternal" | "unknownSchedule") => void;
|
|
8975
9567
|
|
|
9568
|
+
/** One open of a sealed value. `key` opened it (`ok`) or was named by it (`failed`). */
|
|
9569
|
+
export declare const recordFieldDecrypt: (key: string, location: string, outcome: "ok" | "failed") => void;
|
|
9570
|
+
|
|
9571
|
+
/** Record the last count or re-key — one row per kind, replaced each time. */
|
|
9572
|
+
export declare const recordFieldKeyReport: <K extends keyof FieldKeyReports>(store: DataStore, kind: K, report: NonNullable<FieldKeyReports[K]>["report"], at?: Date) => Promise<void>;
|
|
9573
|
+
|
|
8976
9574
|
/**
|
|
8977
9575
|
* Record one emitted event into the identity's ring. Snapshots RESET the ring
|
|
8978
9576
|
* (the snapshot's revision becomes the new replay base — a client holding an
|
|
@@ -9103,76 +9701,32 @@ export declare const redactColumns: <R extends Row>(rows: ReadonlyArray<R>, reda
|
|
|
9103
9701
|
/** Blank sensitive-looking columns. Returns a new object; null passes through. */
|
|
9104
9702
|
export declare const redactRow: (row: Row_2 | null | undefined) => Row_2 | null;
|
|
9105
9703
|
|
|
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
|
-
*/
|
|
9704
|
+
/** Registry-owned command facade and one borrowed Pub/Sub consumer. */
|
|
9113
9705
|
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
|
-
*/
|
|
9706
|
+
readonly client: RespClient;
|
|
9707
|
+
readonly pubsub: RedisPubSub;
|
|
9708
|
+
/** Application/environment namespace. Required; never shared implicitly. */
|
|
9709
|
+
readonly keyPrefix: string;
|
|
9710
|
+
/** Defaults to `${keyPrefix}:bus`; all participating processes must agree. */
|
|
9136
9711
|
readonly channel?: string;
|
|
9137
|
-
/** Clock injection for tests. Defaults to `Date.now`. */
|
|
9138
9712
|
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
|
-
*/
|
|
9713
|
+
/** Local writes survive remote failures. Failed mutations are never replayed. */
|
|
9145
9714
|
readonly onError?: (error: unknown, op: 'set' | 'delete' | 'subscribe' | 'parse') => void;
|
|
9146
9715
|
}
|
|
9147
9716
|
|
|
9717
|
+
export declare interface RedisRywPositionStore extends RywPositionStore {
|
|
9718
|
+
/** Drain accepted writes and release this consumer, leaving shared sockets open. */
|
|
9719
|
+
readonly close: () => Promise<void>;
|
|
9720
|
+
}
|
|
9721
|
+
|
|
9148
9722
|
/**
|
|
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.
|
|
9723
|
+
* Subscribe before returning. Reads consult only the process-local mirror.
|
|
9724
|
+
* Writes update it synchronously, then enqueue PSETEX/DEL followed by PUBLISH.
|
|
9725
|
+
* Pub/Sub is eventual and cannot replay lost messages or rebuild a new mirror.
|
|
9726
|
+
* A missing position still follows replica routing under fallback and wait;
|
|
9727
|
+
* neither policy establishes cross-process read-your-writes before delivery.
|
|
9174
9728
|
*/
|
|
9175
|
-
export declare const redisRywPositionStore: (options: RedisRywOptions) =>
|
|
9729
|
+
export declare const redisRywPositionStore: (options: RedisRywOptions) => Effect.Effect<RedisRywPositionStore, KvError>;
|
|
9176
9730
|
|
|
9177
9731
|
/** `__voltro.undo.redo` — re-apply a previously-undone invocation's forward
|
|
9178
9732
|
* changes. Idempotent if not currently undone. */
|
|
@@ -9226,7 +9780,15 @@ export declare const registerConnectionStream: (clientId: number, interrupt: ()
|
|
|
9226
9780
|
*/
|
|
9227
9781
|
export declare const registerDefaultTupleSource: (source: TupleSource) => boolean;
|
|
9228
9782
|
|
|
9229
|
-
|
|
9783
|
+
/** Process-level callers share the same map even across duplicated modules. */
|
|
9784
|
+
export declare const registerExternalizedTask: (task: ExternalizedTask) => (() => void);
|
|
9785
|
+
|
|
9786
|
+
/**
|
|
9787
|
+
* Record a key ahead of the deploy that brings it, as `pending`, with its
|
|
9788
|
+
* canary — so the first boot that holds it verifies its material, and the
|
|
9789
|
+
* configuration without it still boots (nothing is sealed under a pending key).
|
|
9790
|
+
*/
|
|
9791
|
+
export declare const registerFieldKey: (store: DataStore, keyring: FieldKeyring, keyId: string) => Promise<void>;
|
|
9230
9792
|
|
|
9231
9793
|
export { registerRetention }
|
|
9232
9794
|
|
|
@@ -9323,6 +9885,37 @@ export declare interface RegistryTableLike {
|
|
|
9323
9885
|
* request was. */
|
|
9324
9886
|
export declare const rehydrateGuards: (serialized: ReadonlyArray<SerializedGuard>) => ReadonlyArray<AnyGuardSpec>;
|
|
9325
9887
|
|
|
9888
|
+
/**
|
|
9889
|
+
* Re-seal every envelope in one cell that is not under the active key, or
|
|
9890
|
+
* names no key, under the active key and the address it was sealed under.
|
|
9891
|
+
*/
|
|
9892
|
+
export declare const rekeyCell: (text: string, keyring: FieldKeyring, context: CellContext) => CellRekey;
|
|
9893
|
+
|
|
9894
|
+
export declare interface RekeyReport {
|
|
9895
|
+
readonly active: string;
|
|
9896
|
+
readonly locations: ReadonlyArray<LocationRekey>;
|
|
9897
|
+
readonly unreadable: ReadonlyArray<UnreadableColumn>;
|
|
9898
|
+
}
|
|
9899
|
+
|
|
9900
|
+
/**
|
|
9901
|
+
* Re-key every discovered location under the keyring's active key. With
|
|
9902
|
+
* `dryRun`, count what would change and write nothing.
|
|
9903
|
+
*/
|
|
9904
|
+
export declare const rekeySealedValues: (dialect: DialectId, keyring: FieldKeyring, declared: Iterable<unknown>, options?: {
|
|
9905
|
+
readonly dryRun?: boolean;
|
|
9906
|
+
readonly onProgress?: (location: LocationRekey) => void;
|
|
9907
|
+
/** Runs between reading a cell and writing it back — where another writer may change it. */
|
|
9908
|
+
readonly beforeWrite?: (cell: {
|
|
9909
|
+
readonly table: string;
|
|
9910
|
+
readonly column: string;
|
|
9911
|
+
readonly rowId: unknown;
|
|
9912
|
+
}) => Effect.Effect<void, unknown, SqlClient.SqlClient>;
|
|
9913
|
+
}) => Effect.Effect<{
|
|
9914
|
+
active: string;
|
|
9915
|
+
locations: LocationRekey[];
|
|
9916
|
+
unreadable: UnreadableColumn[];
|
|
9917
|
+
}, SqlError, SqlClient.SqlClient>;
|
|
9918
|
+
|
|
9326
9919
|
/** The store slice `applyDeclaredRelations` needs. `columns` is the junction's
|
|
9327
9920
|
* DERIVED reference pair — the truth the descriptor's declaration is checked
|
|
9328
9921
|
* against before anything is written. */
|
|
@@ -9345,6 +9938,9 @@ export declare interface RelationTuple {
|
|
|
9345
9938
|
readonly resourceId: string;
|
|
9346
9939
|
}
|
|
9347
9940
|
|
|
9941
|
+
/** Give up this process's lease — on shutdown, so nobody waits for it. */
|
|
9942
|
+
export declare const releaseFieldKeyHolder: (store: DataStore, holderId: string) => Promise<void>;
|
|
9943
|
+
|
|
9348
9944
|
/**
|
|
9349
9945
|
* Release a claim back to `pending` (CAS `fired → pending`) — used when
|
|
9350
9946
|
* the wake failed, so the next poll retries it (at-least-once wake). The
|
|
@@ -9435,6 +10031,7 @@ export declare interface ReplicaSelector {
|
|
|
9435
10031
|
}
|
|
9436
10032
|
|
|
9437
10033
|
export declare class ReplicatedDataStore implements DataStore {
|
|
10034
|
+
readonly integrityQuery?: NonNullable<DataStore['integrityQuery']>;
|
|
9438
10035
|
private readonly primary;
|
|
9439
10036
|
private readonly replicas;
|
|
9440
10037
|
private readonly adapter;
|
|
@@ -9446,12 +10043,13 @@ export declare class ReplicatedDataStore implements DataStore {
|
|
|
9446
10043
|
private readonly health;
|
|
9447
10044
|
private readonly recordRouting?;
|
|
9448
10045
|
private readonly now;
|
|
10046
|
+
private closing;
|
|
9449
10047
|
constructor(options: ReplicatedDataStoreOptions);
|
|
9450
10048
|
query(descriptor: QueryDescriptor): Promise<ReadonlyArray<Row>>;
|
|
9451
10049
|
private routeToReplica;
|
|
9452
10050
|
private routeWaitMode;
|
|
9453
10051
|
insert(table: string, row: Row): Promise<Row>;
|
|
9454
|
-
insertMany(table: string, rows: ReadonlyArray<Row
|
|
10052
|
+
insertMany(table: string, rows: ReadonlyArray<Row>, options?: InsertManyOptions): Promise<ReadonlyArray<Row>>;
|
|
9455
10053
|
patchJson(table: string, primaryKey: string, path: string, value: unknown, additionalPatch?: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
9456
10054
|
update(table: string, primaryKey: string, patch: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
9457
10055
|
delete(table: string, primaryKey: string): Promise<boolean>;
|
|
@@ -9476,6 +10074,8 @@ export declare class ReplicatedDataStore implements DataStore {
|
|
|
9476
10074
|
injectExternalChange(event: ChangeEvent): void;
|
|
9477
10075
|
/** Forwarded from the primary — see DataStore.changeScope. */
|
|
9478
10076
|
get changeScope(): 'local' | 'fleet';
|
|
10077
|
+
/** Drain the RYW consumer before closing every SQL pool; repeated close is shared. */
|
|
10078
|
+
close(gracePeriodMs?: number): Promise<void>;
|
|
9479
10079
|
private stampPostWrite;
|
|
9480
10080
|
private emitRouting;
|
|
9481
10081
|
}
|
|
@@ -9557,8 +10157,8 @@ export declare interface ResendOptions {
|
|
|
9557
10157
|
readonly attempts?: number;
|
|
9558
10158
|
}
|
|
9559
10159
|
|
|
9560
|
-
/**
|
|
9561
|
-
export declare const
|
|
10160
|
+
/** Test seam: back to the boot default. */
|
|
10161
|
+
export declare const resetComputedQueryCacheCaptureForTests: () => void;
|
|
9562
10162
|
|
|
9563
10163
|
/** Test/dev-only — clear ALL per-connection state. Don't call from app code. */
|
|
9564
10164
|
export declare const _resetConnectionCredentialsForTest: () => void;
|
|
@@ -9569,6 +10169,9 @@ export declare const resetDetachedForTest: () => void;
|
|
|
9569
10169
|
/** Test seams for the tag-cache guard — the cache is module-private otherwise. */
|
|
9570
10170
|
export declare const resetEventMetricTagCacheForTests: () => void;
|
|
9571
10171
|
|
|
10172
|
+
/** Test seam. */
|
|
10173
|
+
export declare const resetFieldDecryptCountsForTests: () => void;
|
|
10174
|
+
|
|
9572
10175
|
/** Drop everything recorded. For tests; not called by the runtime. */
|
|
9573
10176
|
export declare const resetObservedGraph: () => void;
|
|
9574
10177
|
|
|
@@ -9772,6 +10375,15 @@ export declare interface ResolvedWorkflowCallerContext extends WorkflowCallerCon
|
|
|
9772
10375
|
readonly rowFilter: RowFilterScope;
|
|
9773
10376
|
}
|
|
9774
10377
|
|
|
10378
|
+
/**
|
|
10379
|
+
* The keyring an environment configures, or `undefined` when it configures no
|
|
10380
|
+
* key at all. Refuses (`FieldKeyringConfigError`, never containing key material)
|
|
10381
|
+
* an unknown or missing active id, a duplicate id, one key under two ids,
|
|
10382
|
+
* `KEY` equal to `_PREVIOUS`, and a `KEY`/`_PREVIOUS` set beside `KEYS` that
|
|
10383
|
+
* `KEYS` does not contain.
|
|
10384
|
+
*/
|
|
10385
|
+
export declare const resolveFieldKeyring: (env: Readonly<Record<string, string | undefined>>) => FieldKeyringConfig | undefined;
|
|
10386
|
+
|
|
9775
10387
|
/**
|
|
9776
10388
|
* Resolve the app's health block against the boot path's own readiness flag.
|
|
9777
10389
|
*
|
|
@@ -10042,6 +10654,15 @@ export { RetentionSpec }
|
|
|
10042
10654
|
|
|
10043
10655
|
export { retentionTtlMsFromEnv }
|
|
10044
10656
|
|
|
10657
|
+
/**
|
|
10658
|
+
* Retire a key: nothing may be sealed under it again, and a configuration may
|
|
10659
|
+
* drop it — the boot no longer asks for it. Refused for the active key, a key
|
|
10660
|
+
* nobody recorded, and a key a live process still seals new values under (it
|
|
10661
|
+
* has not adopted the new key yet). Whether VALUES are still sealed under it is
|
|
10662
|
+
* the caller's question to answer first (`voltro secret retire` counts them).
|
|
10663
|
+
*/
|
|
10664
|
+
export declare const retireFieldKey: (store: DataStore, keyId: string, holder?: Pick<FieldKeyHolder, "now">) => Promise<void>;
|
|
10665
|
+
|
|
10045
10666
|
/**
|
|
10046
10667
|
* Drop the ISR cache entries for a path on every `voltro start` replica.
|
|
10047
10668
|
*
|
|
@@ -10349,6 +10970,8 @@ export declare interface RpcConnection {
|
|
|
10349
10970
|
|
|
10350
10971
|
export declare interface RpcServerOptions<Rpcs extends Rpc.Any> {
|
|
10351
10972
|
readonly group: RpcGroup.RpcGroup<Rpcs>;
|
|
10973
|
+
/** Executable RPC surfaces for this replica; omitted retains both transports. */
|
|
10974
|
+
readonly workloadAdmission?: RpcWorkloadAdmission;
|
|
10352
10975
|
readonly handlersLayer: Layer.Layer<Rpc.ToHandler<Rpcs>>;
|
|
10353
10976
|
/** Optional handlers layer dedicated to the one-shot HTTP rpc surface
|
|
10354
10977
|
* (`POST /rpc`, used by SSR web-router loaders). The HTTP JSON protocol
|
|
@@ -10544,6 +11167,14 @@ export declare interface RpcServerOptions<Rpcs extends Rpc.Any> {
|
|
|
10544
11167
|
readonly security?: TransportSecurityOptions;
|
|
10545
11168
|
}
|
|
10546
11169
|
|
|
11170
|
+
export declare interface RpcWorkloadAdmission {
|
|
11171
|
+
readonly rpc: boolean;
|
|
11172
|
+
readonly subscriptions: boolean;
|
|
11173
|
+
/** Event streams are independent of live query subscriptions. */
|
|
11174
|
+
readonly events?: boolean;
|
|
11175
|
+
readonly routes?: ReadonlyArray<string>;
|
|
11176
|
+
}
|
|
11177
|
+
|
|
10547
11178
|
/**
|
|
10548
11179
|
* Rules that apply to one change, or an empty list.
|
|
10549
11180
|
*
|
|
@@ -10628,6 +11259,10 @@ export declare const runSingleNodeOrchestrator: (opts: SingleNodeOrchestratorOpt
|
|
|
10628
11259
|
export declare const RUNTIME_NAME: "framework-runtime";
|
|
10629
11260
|
|
|
10630
11261
|
export declare interface RuntimeContext {
|
|
11262
|
+
/** Effective incoming Cookie header for server-side signature verification.
|
|
11263
|
+
* Unverified private input; never return, log or persist it. Optional for
|
|
11264
|
+
* internal callers and cookie-less requests. */
|
|
11265
|
+
readonly cookieHeader?: string;
|
|
10631
11266
|
/** Subscription / call subject — user, API key, service account, or anonymous. */
|
|
10632
11267
|
readonly subject: Subject;
|
|
10633
11268
|
/** Trace identifier — the active span's W3C trace id (32 hex) when
|
|
@@ -10761,6 +11396,8 @@ export declare interface RywPositionStore {
|
|
|
10761
11396
|
delete(subjectKey: string): void;
|
|
10762
11397
|
/** Approximate size for observability + tests. */
|
|
10763
11398
|
size(): number;
|
|
11399
|
+
/** Release consumer resources when this store owns any. */
|
|
11400
|
+
readonly close?: () => Promise<void>;
|
|
10764
11401
|
}
|
|
10765
11402
|
|
|
10766
11403
|
/**
|
|
@@ -10933,6 +11570,8 @@ export declare type ScheduleHandler = (ctx: ScheduleContext) => void | Promise<v
|
|
|
10933
11570
|
export declare type ScheduleOverlapPolicy = 'skip' | 'queue' | 'parallel';
|
|
10934
11571
|
|
|
10935
11572
|
export declare interface SchedulerDeps {
|
|
11573
|
+
/** Active synchronous handler entry only; never await a Promise inside this measurement. */
|
|
11574
|
+
readonly measureSync?: <A>(run: () => A) => A;
|
|
10936
11575
|
/** App-owned service environment; the signal interrupts Effect work on timeout. */
|
|
10937
11576
|
readonly runEffect?: (effect: Extract<ReturnType<ScheduleHandler>, Effect.Effect<unknown, unknown, unknown>>, signal: AbortSignal) => Promise<unknown>;
|
|
10938
11577
|
readonly store: DataStore;
|
|
@@ -11044,6 +11683,8 @@ export declare interface SchedulerDeps {
|
|
|
11044
11683
|
}
|
|
11045
11684
|
|
|
11046
11685
|
export declare interface SchedulerHandle {
|
|
11686
|
+
/** Completed startup and shutdown has not begun; not a successful-job claim. */
|
|
11687
|
+
isRunning(): boolean;
|
|
11047
11688
|
/** Fire a schedule immediately, bypassing the cron clock + the
|
|
11048
11689
|
* coordinator. Waits for handler completion and returns the recorded run id. */
|
|
11049
11690
|
fireNow(name: string, trigger: ScheduleTrigger | 'manual'): Promise<string | undefined>;
|
|
@@ -11349,6 +11990,22 @@ declare interface ScopeCtx {
|
|
|
11349
11990
|
/** The scope strings a UI shows ("ask someone with …"). */
|
|
11350
11991
|
export declare const scopeStringsOf: (serialized: ReadonlyArray<SerializedGuard>) => ReadonlyArray<string>;
|
|
11351
11992
|
|
|
11993
|
+
/** One column that holds envelopes, and what is under which key in it. */
|
|
11994
|
+
export declare interface SealedLocation {
|
|
11995
|
+
readonly table: string;
|
|
11996
|
+
readonly column: string;
|
|
11997
|
+
/** The app declares it `.encrypted()` (a whole cell is one value), rather than a place found holding envelopes. */
|
|
11998
|
+
readonly declared: boolean;
|
|
11999
|
+
/** Cells holding at least one envelope. */
|
|
12000
|
+
readonly cells: number;
|
|
12001
|
+
/** Envelopes, counted per key id. */
|
|
12002
|
+
readonly byKey: Readonly<Record<string, number>>;
|
|
12003
|
+
/** Envelopes written before envelopes named their key. */
|
|
12004
|
+
readonly unnamed: number;
|
|
12005
|
+
/** Declared `.encrypted()` only: non-null cells that are not an envelope. */
|
|
12006
|
+
readonly plaintext: number;
|
|
12007
|
+
}
|
|
12008
|
+
|
|
11352
12009
|
export declare interface SecretsBackend {
|
|
11353
12010
|
/** Resolve a secret by key. `undefined` when absent. */
|
|
11354
12011
|
readonly get: (key: string) => Promise<string | undefined>;
|
|
@@ -11488,6 +12145,8 @@ export declare type SerializedGuard = {
|
|
|
11488
12145
|
readonly resource: string | null;
|
|
11489
12146
|
} | {
|
|
11490
12147
|
readonly kind: 'authenticated';
|
|
12148
|
+
} | {
|
|
12149
|
+
readonly kind: 'upgraded';
|
|
11491
12150
|
};
|
|
11492
12151
|
|
|
11493
12152
|
/**
|
|
@@ -11507,6 +12166,14 @@ export declare type ServeMutationCommitHook = (context: Parameters<ServeRpcInter
|
|
|
11507
12166
|
}) => Effect.Effect<void, unknown>;
|
|
11508
12167
|
|
|
11509
12168
|
export declare interface ServeRequestContext {
|
|
12169
|
+
/** Listener-owned identity; used only for measurement attribution here. */
|
|
12170
|
+
readonly connection?: {
|
|
12171
|
+
readonly transport: 'http' | 'websocket';
|
|
12172
|
+
};
|
|
12173
|
+
/** Effective incoming Cookie header for server-side signature verification.
|
|
12174
|
+
* Unverified private input; never return, log or persist it. Optional for
|
|
12175
|
+
* internal callers and cookie-less requests. */
|
|
12176
|
+
readonly cookieHeader?: string;
|
|
11510
12177
|
readonly subject: unknown;
|
|
11511
12178
|
readonly traceId: string;
|
|
11512
12179
|
readonly spanId?: string;
|
|
@@ -11565,7 +12232,7 @@ export declare const serverOnlyLeaks: (query: AuditableQuery, serverOnlyByTable:
|
|
|
11565
12232
|
/** A plugin interceptor — wraps the base run Effect (Effect-native chain). */
|
|
11566
12233
|
export declare type ServeRpcInterceptor = (base: Effect.Effect<unknown, unknown, never>, meta: {
|
|
11567
12234
|
readonly tag: string;
|
|
11568
|
-
readonly kind: 'mutation' | 'action' | 'query' | 'workflow';
|
|
12235
|
+
readonly kind: 'mutation' | 'action' | 'query' | 'workflow' | 'stream';
|
|
11569
12236
|
readonly input: unknown;
|
|
11570
12237
|
readonly subject: unknown;
|
|
11571
12238
|
readonly traceId: string;
|
|
@@ -11781,8 +12448,14 @@ export declare interface SingleNodeOrchestratorOptions {
|
|
|
11781
12448
|
export declare interface SnapshotCache {
|
|
11782
12449
|
readonly wrap: (binding: SnapshotCacheBinding, tags: ReadonlyArray<string>, compute: () => Promise<ReadonlyArray<Row>>) => Promise<ReadonlyArray<Row>>;
|
|
11783
12450
|
/** Write-through from the live recompute, so the cache is never staler
|
|
11784
|
-
* than the freshest live subscriber. Fire-and-forget.
|
|
11785
|
-
|
|
12451
|
+
* than the freshest live subscriber. Fire-and-forget. `fence` is the
|
|
12452
|
+
* cache's invalidation position observed BEFORE the rows were read: a
|
|
12453
|
+
* later invalidation of any tag voids the write, so an earlier, slower
|
|
12454
|
+
* read can never overwrite a later one. */
|
|
12455
|
+
readonly put: (binding: SnapshotCacheBinding, tags: ReadonlyArray<string>, rows: ReadonlyArray<Row>, fence: number) => void;
|
|
12456
|
+
/** The cache's invalidation position — observed before a read whose rows
|
|
12457
|
+
* will be written through. */
|
|
12458
|
+
readonly fence: () => Promise<number>;
|
|
11786
12459
|
}
|
|
11787
12460
|
|
|
11788
12461
|
/**
|
|
@@ -11794,6 +12467,8 @@ export declare interface SnapshotCacheBinding {
|
|
|
11794
12467
|
readonly key: string;
|
|
11795
12468
|
readonly ttlMs: number;
|
|
11796
12469
|
readonly swrMs: number | undefined;
|
|
12470
|
+
/** The query name its counters are kept under (`queryStats`, metrics). */
|
|
12471
|
+
readonly label?: string | undefined;
|
|
11797
12472
|
}
|
|
11798
12473
|
|
|
11799
12474
|
/**
|
|
@@ -11805,6 +12480,20 @@ export declare const snapshotCrdt: (store: CrdtHistoryStore, cell: CrdtCellRef &
|
|
|
11805
12480
|
readonly createdBy?: string;
|
|
11806
12481
|
}) => Promise<CrdtVersion | undefined>;
|
|
11807
12482
|
|
|
12483
|
+
/**
|
|
12484
|
+
* The entry a READ belongs to: the rpc layer's scoped key plus the descriptor
|
|
12485
|
+
* actually read.
|
|
12486
|
+
*
|
|
12487
|
+
* The rpc key names the query, its input and the scope (subject / tenant /
|
|
12488
|
+
* global) — but not what the caller may SEE. A registered row filter makes two
|
|
12489
|
+
* colleagues of one tenant read different rows through the same `'tenant'` key,
|
|
12490
|
+
* and keying by the rpc key alone served the first colleague's filtered rows to
|
|
12491
|
+
* the next one. The read descriptor carries every predicate the caller's
|
|
12492
|
+
* visibility added, so two readers share an entry exactly when they read the
|
|
12493
|
+
* same thing.
|
|
12494
|
+
*/
|
|
12495
|
+
export declare const snapshotEntryFor: (binding: SnapshotCacheBinding, read: QueryDescriptor) => SnapshotCacheBinding;
|
|
12496
|
+
|
|
11808
12497
|
/** Snapshot the whole registry, normalized to `MetricSample[]` — plus the
|
|
11809
12498
|
* socket-backpressure counters (`subscriptionSocketMetrics.ts`), appended
|
|
11810
12499
|
* HERE so every reader (Prometheus exporter, inspect Metrics panel) sees
|
|
@@ -11842,32 +12531,23 @@ export declare class SsrfBlockedError extends Error {
|
|
|
11842
12531
|
*/
|
|
11843
12532
|
export declare const ssrfGuardHttpClientLayer: (policy?: SsrfPolicy) => Layer.Layer<HttpClient.HttpClient, never, HttpClient.HttpClient>;
|
|
11844
12533
|
|
|
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
|
-
}
|
|
12534
|
+
export { SsrfPolicy }
|
|
12535
|
+
|
|
12536
|
+
export { ssrfReason }
|
|
11859
12537
|
|
|
11860
12538
|
/**
|
|
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.
|
|
12539
|
+
* Heartbeat every {@link FIELD_KEY_HEARTBEAT_MS} for as long as the process
|
|
12540
|
+
* runs. Logs a transition once — a key that became active, a key still waiting
|
|
12541
|
+
* and for whom, an active key this process does not hold — never every beat.
|
|
11869
12542
|
*/
|
|
11870
|
-
export declare const
|
|
12543
|
+
export declare const startFieldKeyHolder: (store: DataStore, keyring: FieldKeyring, holder: FieldKeyHolder & {
|
|
12544
|
+
readonly intervalMs?: number;
|
|
12545
|
+
readonly log: {
|
|
12546
|
+
readonly info: (message: string) => void;
|
|
12547
|
+
readonly warn: (message: string) => void;
|
|
12548
|
+
readonly error: (message: string) => void;
|
|
12549
|
+
};
|
|
12550
|
+
}) => FieldKeyHolderHandle;
|
|
11871
12551
|
|
|
11872
12552
|
/**
|
|
11873
12553
|
* Start the rpc-based runtime server on Node. Composes:
|
|
@@ -12097,6 +12777,12 @@ export declare interface SubscriberDefinition {
|
|
|
12097
12777
|
readonly table: string;
|
|
12098
12778
|
/** Default `'any'`. */
|
|
12099
12779
|
readonly on?: SubscribeOp | ReadonlyArray<Exclude<SubscribeOp, 'any'>>;
|
|
12780
|
+
/** Bind this invocation's event publisher to the trusted committed row's
|
|
12781
|
+
* tenant. No client input is available here. Omitted keeps system/global
|
|
12782
|
+
* publication. This does not change ctx.store's system identity or turn a
|
|
12783
|
+
* best-effort subscriber into durable delivery. Invalid results refuse the
|
|
12784
|
+
* handler rather than publishing into the global partition. */
|
|
12785
|
+
readonly eventTenant?: (event: SubscribeEvent) => string | null;
|
|
12100
12786
|
/**
|
|
12101
12787
|
* Run the handler ONCE PER CHANGE across the whole fleet, instead of once on
|
|
12102
12788
|
* every replica that sees it.
|
|
@@ -12446,7 +13132,7 @@ export declare const tenantSelectionStore: (getStore: () => DataStore | undefine
|
|
|
12446
13132
|
* a page. */
|
|
12447
13133
|
export declare const TERMINAL_RUN_STATUSES: ReadonlySet<string>;
|
|
12448
13134
|
|
|
12449
|
-
export
|
|
13135
|
+
export { TimeBucket }
|
|
12450
13136
|
|
|
12451
13137
|
export declare interface TimelineEvent {
|
|
12452
13138
|
/** Preserves the store's warning that images are not original commit images. */
|
|
@@ -12512,29 +13198,11 @@ export declare class TimelineRecorder {
|
|
|
12512
13198
|
replay(table: string, asOfSeq: number, currentRows: ReadonlyArray<Row_2>): ReadonlyArray<Row_2>;
|
|
12513
13199
|
}
|
|
12514
13200
|
|
|
12515
|
-
|
|
12516
|
-
export declare interface TimeRange {
|
|
12517
|
-
readonly from: Date;
|
|
12518
|
-
readonly to?: Date;
|
|
12519
|
-
}
|
|
13201
|
+
export { TimeRange }
|
|
12520
13202
|
|
|
12521
|
-
export
|
|
12522
|
-
readonly bucket: TimeBucket;
|
|
12523
|
-
}
|
|
13203
|
+
export { TimeseriesQuery }
|
|
12524
13204
|
|
|
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
|
-
}
|
|
13205
|
+
export { TopNQuery }
|
|
12538
13206
|
|
|
12539
13207
|
/** A row a mutation wrote, carried to rule evaluation. `row` is the POST-WRITE
|
|
12540
13208
|
* state (insert result / update result). */
|
|
@@ -12986,7 +13654,11 @@ export declare class UndoStack<E> {
|
|
|
12986
13654
|
*/
|
|
12987
13655
|
export declare const undoSurfaceEnabled: (env?: Record<string, string | undefined>) => boolean;
|
|
12988
13656
|
|
|
12989
|
-
export declare
|
|
13657
|
+
export declare interface UnreadableColumn {
|
|
13658
|
+
readonly table: string;
|
|
13659
|
+
readonly column: string;
|
|
13660
|
+
readonly reason: string;
|
|
13661
|
+
}
|
|
12990
13662
|
|
|
12991
13663
|
/** One `source:` entry that resolves to no declared table. */
|
|
12992
13664
|
export declare interface UnresolvedSource {
|
|
@@ -12999,6 +13671,8 @@ export declare interface UnresolvedSource {
|
|
|
12999
13671
|
/** True when the name is in the `channel:` namespace: it named a reactivity
|
|
13000
13672
|
* channel nobody declared, which is a different repair from a stale table. */
|
|
13001
13673
|
readonly channel: boolean;
|
|
13674
|
+
/** Intentionally optional integration observation, retained in source. */
|
|
13675
|
+
readonly optional?: true;
|
|
13002
13676
|
}
|
|
13003
13677
|
|
|
13004
13678
|
/**
|
|
@@ -13010,6 +13684,7 @@ export declare interface UnresolvedSource {
|
|
|
13010
13684
|
export declare const unresolvedSources: (procedures: ReadonlyArray<{
|
|
13011
13685
|
readonly name: string;
|
|
13012
13686
|
readonly source: string | ReadonlyArray<string> | undefined;
|
|
13687
|
+
readonly optionalSource?: ReadonlyArray<string>;
|
|
13013
13688
|
}>, declared: ReadonlySet<string>) => ReadonlyArray<UnresolvedSource>;
|
|
13014
13689
|
|
|
13015
13690
|
/** Thrown at boot; the message is the whole point, so it names the path and the
|
|
@@ -13091,6 +13766,27 @@ export declare type VerificationDeclared<T> = T & {
|
|
|
13091
13766
|
readonly [WEBHOOK_VERIFICATION_PROPERTY]: WebhookVerification;
|
|
13092
13767
|
};
|
|
13093
13768
|
|
|
13769
|
+
/**
|
|
13770
|
+
* Check the keyring against the database and record what is new; make the
|
|
13771
|
+
* database's active key the keyring's. Throws {@link FieldKeyringRefusal} when
|
|
13772
|
+
* the keyring cannot read this database's data.
|
|
13773
|
+
*
|
|
13774
|
+
* `tables` are the app's declared tables: a few sealed values per
|
|
13775
|
+
* `.encrypted()` column are opened as a sample, and nothing else is read.
|
|
13776
|
+
*/
|
|
13777
|
+
export declare const verifyFieldKeyring: (store: DataStore, keyring: FieldKeyring, tables: Iterable<unknown>, holder?: FieldKeyHolder) => Promise<FieldKeyringVerification>;
|
|
13778
|
+
|
|
13779
|
+
/** Every location's envelopes, opened with `keyring` — after a re-key, a keyring with the active key alone. */
|
|
13780
|
+
export declare const verifySealedValues: (dialect: DialectId, keyring: FieldKeyring, declared: Iterable<unknown>) => Effect.Effect<{
|
|
13781
|
+
opened: number;
|
|
13782
|
+
unopened: {
|
|
13783
|
+
readonly table: string;
|
|
13784
|
+
readonly column: string;
|
|
13785
|
+
readonly count: number;
|
|
13786
|
+
}[];
|
|
13787
|
+
unreadable: UnreadableColumn[];
|
|
13788
|
+
}, SqlError, SqlClient.SqlClient>;
|
|
13789
|
+
|
|
13094
13790
|
/** The pure core of live revocation: given a subject + action + a row-set,
|
|
13095
13791
|
* return ONLY the rows the subject may still see. The reactive matcher calls
|
|
13096
13792
|
* this on a permission-changing write and diffs against the prior visible set;
|
|
@@ -13168,6 +13864,19 @@ export declare const _voltroConnectionsTable: TableLike;
|
|
|
13168
13864
|
|
|
13169
13865
|
export declare const _voltroCrdtVersionsTable: TableLike;
|
|
13170
13866
|
|
|
13867
|
+
/** The leases: which process holds which keys, and until when it counts —
|
|
13868
|
+
* rewritten by every heartbeat, so not reactive. */
|
|
13869
|
+
export declare const _voltroFieldKeyHoldersTable: TableLike;
|
|
13870
|
+
|
|
13871
|
+
/** The last count and the last re-key `voltro secret status` / `rekey` / `rotate`
|
|
13872
|
+
* ran — what the Governance panel shows as a rotation's progress, since the
|
|
13873
|
+
* app itself never scans every sealed value. Counts and locations, never a value. */
|
|
13874
|
+
export declare const _voltroFieldKeyReportsTable: TableLike;
|
|
13875
|
+
|
|
13876
|
+
/** Each field-encryption key id's state and canary — a framework table, created for every app.
|
|
13877
|
+
* Declared by its literal name: the data-transfer classification guard reads declarations. */
|
|
13878
|
+
export declare const _voltroFieldKeysTable: TableLike;
|
|
13879
|
+
|
|
13171
13880
|
/** `_voltro_rebac_tuples` — the relationship tuples `can()` reads. One row =
|
|
13172
13881
|
* "`subjectId` has `relation` on `<resourceType>:<resourceId>`". Grant by
|
|
13173
13882
|
* inserting; revoke by deleting (a delete is the live-revocation trigger). */
|
|
@@ -13917,7 +14626,7 @@ export declare interface WorkflowsAppContext {
|
|
|
13917
14626
|
* execution, or never to run — read once, without waiting. A queued handle
|
|
13918
14627
|
* is resolved through its durable receipt, so the answer survives the
|
|
13919
14628
|
* process that recorded the handle. */
|
|
13920
|
-
readStart(handle: WorkflowRunHandle, options?:
|
|
14629
|
+
readStart(handle: WorkflowRunHandle, options?: WorkflowRunOptions): Promise<WorkflowStartObservation>;
|
|
13921
14630
|
/**
|
|
13922
14631
|
* Set on the facade a mutation TRANSACTION hands out: every start it records
|
|
13923
14632
|
* is provisional until the transaction commits, so nothing about a start can
|
|
@@ -14100,6 +14809,10 @@ export declare const wrapStoreWithBootCodec: (underlying: DataStore, dialectId:
|
|
|
14100
14809
|
|
|
14101
14810
|
export declare const wrapStoreWithMixinBehaviour: (rawUnderlying: DataStore, ctx: StoreMiddlewareContext) => FluentStore;
|
|
14102
14811
|
|
|
14812
|
+
/** Writer errors propagate to the publisher, which owns retry/logging. A failed
|
|
14813
|
+
* history write must not be mistaken for a successfully recorded zero bucket. */
|
|
14814
|
+
export declare const writeApiRoleWorkloadBucket: (store: DataStore, bucket: ApiRoleWorkloadBucket) => Promise<void>;
|
|
14815
|
+
|
|
14103
14816
|
export declare const writeReplicaObservation: (store: DataStore, kind: ReplicaObservationKind, payload: unknown) => Promise<void>;
|
|
14104
14817
|
|
|
14105
14818
|
export { }
|