@voltro/runtime 0.52.0 → 0.53.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 +229 -0
- package/THIRD-PARTY-NOTICES.md +29 -1
- package/dist/index.d.ts +332 -22
- package/dist/index.js +2586 -2097
- package/package.json +7 -7
package/dist/index.d.ts
CHANGED
|
@@ -69,6 +69,7 @@ import { RetentionSource } from '@voltro/database';
|
|
|
69
69
|
import { RetentionSpec } from '@voltro/database';
|
|
70
70
|
import { retentionTtlMsFromEnv } from '@voltro/database';
|
|
71
71
|
import { Row } from '@voltro/database';
|
|
72
|
+
import { RowPatch } from '@voltro/protocol';
|
|
72
73
|
import { Rpc } from '@effect/rpc';
|
|
73
74
|
import { RpcGroup } from '@effect/rpc';
|
|
74
75
|
import { RpcInterceptor } from '@voltro/protocol';
|
|
@@ -97,6 +98,8 @@ import { TenantRowNotFound } from '@voltro/protocol';
|
|
|
97
98
|
import { TenantScopeViolation } from '@voltro/protocol';
|
|
98
99
|
import { Tracer } from 'effect';
|
|
99
100
|
import { Unauthenticated } from '@voltro/protocol';
|
|
101
|
+
import { ValidationError } from '@voltro/protocol';
|
|
102
|
+
import { ValidationErrors } from '@voltro/protocol';
|
|
100
103
|
import { WebSocketGatewayRoute } from '@voltro/protocol';
|
|
101
104
|
import { WorkflowParentClosePolicy } from '@voltro/protocol';
|
|
102
105
|
import { WorkflowRunHandle } from '@voltro/protocol';
|
|
@@ -151,6 +154,28 @@ export declare interface ActivitySignals {
|
|
|
151
154
|
readonly activeWorkflowExecutions: () => number;
|
|
152
155
|
}
|
|
153
156
|
|
|
157
|
+
/**
|
|
158
|
+
* Adopt a detached subscription for a resuming client at `fromRevision`.
|
|
159
|
+
* Undefined — identity unknown, entry dead (an error/revocation while
|
|
160
|
+
* offline), or the revision does not chain — means: subscribe fresh, send a
|
|
161
|
+
* snapshot. A failed adoption EXPIRES the entry: its ring cannot serve this
|
|
162
|
+
* client and keeping a half-dead entry around only risks a second caller
|
|
163
|
+
* adopting state the first one invalidated.
|
|
164
|
+
*/
|
|
165
|
+
export declare const adoptDetached: (identity: ResumeIdentity, fromRevision: number, now?: number, tunables?: ResumeTunables) => AdoptedSubscription | undefined;
|
|
166
|
+
|
|
167
|
+
export declare interface AdoptedSubscription {
|
|
168
|
+
/** The deltas the client missed, in order — replay before going live. */
|
|
169
|
+
readonly deltas: ReadonlyArray<{
|
|
170
|
+
readonly revision: number;
|
|
171
|
+
readonly emittedAt: number;
|
|
172
|
+
readonly patch: RowPatch;
|
|
173
|
+
}>;
|
|
174
|
+
/** Redirect this to the new stream to go live on the SAME revision line. */
|
|
175
|
+
readonly sink: ResumeSink;
|
|
176
|
+
readonly unsubscribe: () => void;
|
|
177
|
+
}
|
|
178
|
+
|
|
154
179
|
export declare interface AggregateContext {
|
|
155
180
|
/** Read-side store for source queries. Note: the build function
|
|
156
181
|
* runs OUTSIDE any per-request subject, so the auto-stamping a
|
|
@@ -808,6 +833,15 @@ export declare interface AnalyticsTopEntry {
|
|
|
808
833
|
readonly value: number;
|
|
809
834
|
}
|
|
810
835
|
|
|
836
|
+
/**
|
|
837
|
+
* Answer a `resumeFrom` for this identity. `fromRevision` is the last
|
|
838
|
+
* revision the CLIENT materialised. Only revisions inside
|
|
839
|
+
* [baseRevision, headRevision] chain; everything else — unknown key, aged
|
|
840
|
+
* ring, a revision the ring no longer covers, a revision AHEAD of the head
|
|
841
|
+
* (a client from a different life) — is a snapshot.
|
|
842
|
+
*/
|
|
843
|
+
export declare const answerResume: (identity: ResumeIdentity, fromRevision: number, now?: number, tunables?: ResumeTunables) => ResumeAnswer;
|
|
844
|
+
|
|
811
845
|
declare type AnyRow = Record<string, unknown>;
|
|
812
846
|
|
|
813
847
|
declare type AnyRow_2 = Record<string, unknown>;
|
|
@@ -990,6 +1024,10 @@ export declare interface AppContext {
|
|
|
990
1024
|
* `ctx.access.has(scope)` / `yield* ctx.access.require(scope)` instead of
|
|
991
1025
|
* reaching into `ctx.request.subject.scopes`. Always present. */
|
|
992
1026
|
readonly access: AppAccess;
|
|
1027
|
+
/** Typed server-side field validation — `yield* ctx.validation.fail('email',
|
|
1028
|
+
* 'validation.emailTaken')` routes to the form field that submitted it.
|
|
1029
|
+
* Always present. */
|
|
1030
|
+
readonly validation: AppValidation;
|
|
993
1031
|
/** Cache — always present (memory backend by default). Use
|
|
994
1032
|
* `ctx.cache.wrap(key, { ttlMs, tags }, () => expensive())` to cache
|
|
995
1033
|
* derived work; tagged entries auto-invalidate when a mutation writes a
|
|
@@ -1074,6 +1112,28 @@ export declare interface AppContext {
|
|
|
1074
1112
|
*/
|
|
1075
1113
|
export declare const applyConnectionCredential: (clientId: number, headers: Record<string, string | undefined>) => Record<string, string | undefined>;
|
|
1076
1114
|
|
|
1115
|
+
/**
|
|
1116
|
+
* Reconcile a mutation target's declared junction `relations:` against the
|
|
1117
|
+
* input — INSIDE the mutation's transaction, through `ctx.store`, so the
|
|
1118
|
+
* links ride the same undo capture, rule evaluation and rollback as the
|
|
1119
|
+
* mutation's own writes.
|
|
1120
|
+
*
|
|
1121
|
+
* Semantics that must not drift:
|
|
1122
|
+
* - an ABSENT input field touches nothing (absent ≠ empty);
|
|
1123
|
+
* - an empty array is the explicit clear;
|
|
1124
|
+
* - a non-array value is a refusal naming the field — silently ignoring it
|
|
1125
|
+
* would read as "saved" while the links stayed stale;
|
|
1126
|
+
* - the row id is `output.id`, else `input.id`; with neither the declaration
|
|
1127
|
+
* is unusable and says so.
|
|
1128
|
+
*/
|
|
1129
|
+
export declare const applyDeclaredRelations: (params: {
|
|
1130
|
+
readonly store: RelationLinksStore;
|
|
1131
|
+
readonly target: MutationLike["descriptor"]["target"];
|
|
1132
|
+
readonly procedure: string;
|
|
1133
|
+
readonly input: unknown;
|
|
1134
|
+
readonly output: unknown;
|
|
1135
|
+
}) => Promise<void>;
|
|
1136
|
+
|
|
1077
1137
|
/**
|
|
1078
1138
|
* Pure helper backing `ctx.store.applyDefined`. Picks the listed keys from
|
|
1079
1139
|
* `input` whose value is not `undefined`, so a PATCH sets exactly the fields
|
|
@@ -1220,6 +1280,35 @@ export declare interface AppSupervisor {
|
|
|
1220
1280
|
stop: () => Promise<void>;
|
|
1221
1281
|
}
|
|
1222
1282
|
|
|
1283
|
+
/** Typed server-side FIELD validation — the executor half of form error
|
|
1284
|
+
* routing. Each helper fails the procedure with a wire `ValidationError`
|
|
1285
|
+
* (auto-merged into every mutation's and action's error union), which the
|
|
1286
|
+
* form binding routes to `errors[field]` instead of `submitError`. */
|
|
1287
|
+
export declare interface AppValidation {
|
|
1288
|
+
/** Fail with ONE field error. `message` is a message id
|
|
1289
|
+
* (`'validation.emailTaken'`) resolved by the client's validation catalog.
|
|
1290
|
+
*
|
|
1291
|
+
* if (await emailTaken(input.email)) {
|
|
1292
|
+
* return yield* ctx.validation.fail('email', 'validation.emailTaken')
|
|
1293
|
+
* }
|
|
1294
|
+
*/
|
|
1295
|
+
readonly fail: (field: string, message: string, params?: Record<string, unknown>) => Effect.Effect<never, ValidationError>;
|
|
1296
|
+
/** Fail with several field errors in one round trip. Refuses an empty
|
|
1297
|
+
* list — a failure with nothing to show is a bug at the call site. */
|
|
1298
|
+
readonly failAll: (issues: ReadonlyArray<{
|
|
1299
|
+
readonly field: string;
|
|
1300
|
+
readonly message: string;
|
|
1301
|
+
readonly params?: Record<string, unknown>;
|
|
1302
|
+
}>) => Effect.Effect<never, ValidationErrors>;
|
|
1303
|
+
/** Guard form: succeed when `condition` holds, else fail the field. */
|
|
1304
|
+
readonly require: (condition: boolean, field: string, message: string, params?: Record<string, unknown>) => Effect.Effect<void, ValidationError>;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
/** The ONE `ctx.validation` value. Pure and subject-free, so a single shared
|
|
1308
|
+
* instance serves every context — request, schedule, workflow, test — and
|
|
1309
|
+
* the builders cannot each assemble a drifting copy. */
|
|
1310
|
+
export declare const appValidation: AppValidation;
|
|
1311
|
+
|
|
1223
1312
|
/** Effect-style guard for handlers — throws the typed {@link AccessDenied} on a
|
|
1224
1313
|
* deny so it surfaces to the client typed. */
|
|
1225
1314
|
export declare const assertCan: (subject: RebacSubject, action: string, resource: RebacResource, deps: CanDeps) => void;
|
|
@@ -1623,7 +1712,14 @@ reauthorize?: (subject: Subject) => () => Promise<unknown>,
|
|
|
1623
1712
|
*/
|
|
1624
1713
|
refilter?: (subject: Subject) => () => Promise<RowFilterScope>) => Stream.Stream<SubscriptionEvent<T>, never, SubjectService | ConnectionInfo>;
|
|
1625
1714
|
|
|
1626
|
-
export declare const bindSubscriptionUntyped: (descriptor: QueryDescriptor, dispatcher: Dispatcher, context: RuntimeContext, indexHint: MatcherIndexHint | undefined, label: string, cacheBinding: SnapshotCacheBinding | undefined, reauthorize: (() => Promise<unknown>) | undefined, refilter?: (() => Promise<RowFilterScope>) | undefined
|
|
1715
|
+
export declare const bindSubscriptionUntyped: (descriptor: QueryDescriptor, dispatcher: Dispatcher, context: RuntimeContext, indexHint: MatcherIndexHint | undefined, label: string, cacheBinding: SnapshotCacheBinding | undefined, reauthorize: (() => Promise<unknown>) | undefined, refilter?: (() => Promise<RowFilterScope>) | undefined, backpressure?: {
|
|
1716
|
+
readonly maxBufferedBytes: number;
|
|
1717
|
+
readonly overrunAfterMs: number;
|
|
1718
|
+
readonly oversizedEventBytes: number;
|
|
1719
|
+
}, resume?: {
|
|
1720
|
+
readonly input: unknown;
|
|
1721
|
+
readonly fromRevision?: number;
|
|
1722
|
+
}) => Stream.Stream<SubscriptionEvent<ReadonlyArray<Row>>, never, never>;
|
|
1627
1723
|
|
|
1628
1724
|
export declare interface BrandedScheduleDefinition extends ScheduleDefinition {
|
|
1629
1725
|
readonly [SCHEDULE_BRAND]: true;
|
|
@@ -1760,6 +1856,8 @@ export declare interface CandidateShape {
|
|
|
1760
1856
|
readonly windowed?: boolean;
|
|
1761
1857
|
}
|
|
1762
1858
|
|
|
1859
|
+
export declare const canonicalInputKey: (input: unknown) => string;
|
|
1860
|
+
|
|
1763
1861
|
/* Excluded from this release type: canonicalize */
|
|
1764
1862
|
|
|
1765
1863
|
/**
|
|
@@ -2857,6 +2955,10 @@ export declare const DEFAULT_RAW_READ_TRACKING_LIMIT = 32;
|
|
|
2857
2955
|
|
|
2858
2956
|
export declare const DEFAULT_REFRESH_SKEW_MS = 60000;
|
|
2859
2957
|
|
|
2958
|
+
export declare const DEFAULT_RESUME_MAX_DELTAS = 256;
|
|
2959
|
+
|
|
2960
|
+
export declare const DEFAULT_RESUME_WINDOW_MS = 60000;
|
|
2961
|
+
|
|
2860
2962
|
/**
|
|
2861
2963
|
* Retry policy applied to `load` when a filter does not specify one: three
|
|
2862
2964
|
* attempts total (the initial call plus two retries), backing off exponentially
|
|
@@ -2869,6 +2971,14 @@ export declare const DEFAULT_REFRESH_SKEW_MS = 60000;
|
|
|
2869
2971
|
*/
|
|
2870
2972
|
export declare const DEFAULT_ROW_FILTER_RETRY: Schedule.Schedule<unknown, unknown>;
|
|
2871
2973
|
|
|
2974
|
+
/** Defaults, overridable via `app.config.ts` `reactive.socket.*` (+ env) —
|
|
2975
|
+
* resolved by the boot paths' tunables resolver. */
|
|
2976
|
+
export declare const DEFAULT_SOCKET_MAX_BUFFERED_BYTES = 1048576;
|
|
2977
|
+
|
|
2978
|
+
export declare const DEFAULT_SOCKET_OVERRUN_AFTER_MS = 10000;
|
|
2979
|
+
|
|
2980
|
+
export declare const DEFAULT_SOCKET_OVERSIZED_EVENT_BYTES = 262144;
|
|
2981
|
+
|
|
2872
2982
|
/**
|
|
2873
2983
|
* The message of an UNDECLARED throw, bounded, with nothing else attached.
|
|
2874
2984
|
*
|
|
@@ -3074,6 +3184,17 @@ export declare const deliveredRowCount: (value: unknown) => number;
|
|
|
3074
3184
|
*/
|
|
3075
3185
|
export declare const deriveKey: (passphrase: string) => Buffer;
|
|
3076
3186
|
|
|
3187
|
+
/**
|
|
3188
|
+
* Detach a live subscription for possible resume. The sink is redirected to
|
|
3189
|
+
* ring-recording only; after the window the subscription is truly
|
|
3190
|
+
* unsubscribed. If an entry already sits under this identity (an older
|
|
3191
|
+
* incarnation), it is expired first — one identity, one detached entry.
|
|
3192
|
+
*/
|
|
3193
|
+
export declare const detachForResume: (identity: ResumeIdentity, handle: {
|
|
3194
|
+
readonly sink: ResumeSink;
|
|
3195
|
+
readonly unsubscribe: () => void;
|
|
3196
|
+
}, tunables?: ResumeTunables, now?: () => number) => void;
|
|
3197
|
+
|
|
3077
3198
|
export { DialectReplicationAdapter }
|
|
3078
3199
|
|
|
3079
3200
|
/** Field-level diff for one change. Insert → every field `undefined→value`;
|
|
@@ -3254,6 +3375,10 @@ export declare class Dispatcher {
|
|
|
3254
3375
|
|
|
3255
3376
|
export declare interface DispatcherDependencies {
|
|
3256
3377
|
readonly store: DataStore;
|
|
3378
|
+
/** CRDT columns per table (schemaRegistry.crdtColumns). Feeds the
|
|
3379
|
+
* downstream lane: crdt cells diff as incremental mergeCells ops.
|
|
3380
|
+
* Absent → no crdt tables (tests, embedders) — plain full-value diffs. */
|
|
3381
|
+
readonly crdtColumnsOf?: (table: string) => ReadonlySet<string>;
|
|
3257
3382
|
/** Optional sink for per-delivery timing. `voltro dev` wires this into
|
|
3258
3383
|
* the trace buffer so the dashboards show each data transfer's latency.
|
|
3259
3384
|
* No-op when absent (tests, embedders that don't trace). */
|
|
@@ -3489,6 +3614,8 @@ export declare const evaluateTouchedRules: (params: {
|
|
|
3489
3614
|
readonly subject: unknown;
|
|
3490
3615
|
}) => Promise<void>;
|
|
3491
3616
|
|
|
3617
|
+
declare type Event_2 = SubscriptionEvent<ReadonlyArray<Row>>;
|
|
3618
|
+
|
|
3492
3619
|
/**
|
|
3493
3620
|
* How many deliveries one client may fall behind before the oldest are dropped.
|
|
3494
3621
|
*
|
|
@@ -4411,6 +4538,14 @@ export declare interface FluentStore extends Omit<MutationStore, 'update' | 'del
|
|
|
4411
4538
|
* await ctx.store.links('post_tags', { postId: post.id }).set(tagIds)
|
|
4412
4539
|
*/
|
|
4413
4540
|
links(junctionTable: string, anchor: Readonly<Record<string, string>>): JunctionLinks;
|
|
4541
|
+
/**
|
|
4542
|
+
* `links(...)` with the anchor COLUMN derived from the anchored TABLE: the
|
|
4543
|
+
* junction's reference column that points at `anchorTable` becomes the
|
|
4544
|
+
* source. Exactly one column may qualify — a self-junction (both columns
|
|
4545
|
+
* referencing the same table) is refused with the fix, never guessed.
|
|
4546
|
+
* This is what a mutation target's declared `relations:` resolves through.
|
|
4547
|
+
*/
|
|
4548
|
+
relationLinks(junctionTable: string, anchorTable: string, anchorId: string): JunctionLinks;
|
|
4414
4549
|
/**
|
|
4415
4550
|
* Execute a query descriptor and return the matching rows — TYPED.
|
|
4416
4551
|
*
|
|
@@ -5626,6 +5761,8 @@ export declare const makeSubmitTokenExecutor: (deps: ConnectionBuiltinDeps) => (
|
|
|
5626
5761
|
readonly ok: boolean;
|
|
5627
5762
|
}>;
|
|
5628
5763
|
|
|
5764
|
+
export declare const makeSubscriptionOutbox: (options: SubscriptionBackpressureOptions) => SubscriptionOutbox;
|
|
5765
|
+
|
|
5629
5766
|
/**
|
|
5630
5767
|
* The factory the serve entrypoints inject into `makeMutationRunner`'s
|
|
5631
5768
|
* `undoCapture` dep. Collects changes from the wrapped tx; `persist` writes ONE
|
|
@@ -5633,7 +5770,7 @@ export declare const makeSubmitTokenExecutor: (deps: ConnectionBuiltinDeps) => (
|
|
|
5633
5770
|
* mutation's transaction. The changes are JSON-serialized into a TEXT column —
|
|
5634
5771
|
* dialect-uniform, no json codec on the path.
|
|
5635
5772
|
*/
|
|
5636
|
-
export declare const makeUndoCapture: (rawTx: DataStore) => {
|
|
5773
|
+
export declare const makeUndoCapture: (rawTx: DataStore, crdtColumnsOf?: (table: string) => ReadonlySet<string>) => {
|
|
5637
5774
|
tx: DataStore;
|
|
5638
5775
|
persist: (store: unknown, meta: {
|
|
5639
5776
|
readonly tag: string;
|
|
@@ -5922,8 +6059,10 @@ export declare interface MutationLike {
|
|
|
5922
6059
|
readonly requiresApproval?: AnyApprovalPolicy | undefined;
|
|
5923
6060
|
readonly target?: {
|
|
5924
6061
|
readonly table: string;
|
|
6062
|
+
readonly relations?: Readonly<Record<string, string>> | undefined;
|
|
5925
6063
|
} | ReadonlyArray<{
|
|
5926
6064
|
readonly table: string;
|
|
6065
|
+
readonly relations?: Readonly<Record<string, string>> | undefined;
|
|
5927
6066
|
}> | undefined;
|
|
5928
6067
|
};
|
|
5929
6068
|
executor(input: unknown, ctx: unknown): unknown;
|
|
@@ -6869,6 +7008,25 @@ export declare interface ReactiveConfigInput {
|
|
|
6869
7008
|
* warning to name a later one.
|
|
6870
7009
|
*/
|
|
6871
7010
|
readonly rawReadTrackingLimit?: number;
|
|
7011
|
+
/**
|
|
7012
|
+
* Subscription socket backpressure (plan 01 P1). A slow or dead consumer no
|
|
7013
|
+
* longer retains every event: updates COALESCE onto the newest state while
|
|
7014
|
+
* the socket is blocked, and a consumer persistently over the buffer
|
|
7015
|
+
* threshold is closed with a typed `SubscriptionOverrun` (it re-subscribes
|
|
7016
|
+
* for a fresh snapshot). Resolved by the CLI's `reactiveTunables.ts`; env
|
|
7017
|
+
* overrides win: `VOLTRO_REACTIVE_MAX_BUFFERED_BYTES` /
|
|
7018
|
+
* `VOLTRO_REACTIVE_OVERRUN_AFTER_MS` / `VOLTRO_REACTIVE_OVERSIZED_EVENT_BYTES`.
|
|
7019
|
+
*/
|
|
7020
|
+
readonly socket?: {
|
|
7021
|
+
/** Estimated pending bytes per subscription above which a persistently
|
|
7022
|
+
* blocked consumer is overrun-closed. Default 1 MiB. */
|
|
7023
|
+
readonly maxBufferedBytes?: number;
|
|
7024
|
+
/** How long the pending state must stay over the threshold before the
|
|
7025
|
+
* terminal close. Default 10_000 ms. */
|
|
7026
|
+
readonly overrunAfterMs?: number;
|
|
7027
|
+
/** Per-event WARN threshold (telemetry, NOT a cap). Default 256 KiB. */
|
|
7028
|
+
readonly oversizedEventBytes?: number;
|
|
7029
|
+
};
|
|
6872
7030
|
}
|
|
6873
7031
|
|
|
6874
7032
|
export declare interface ReactiveEnv {
|
|
@@ -6884,6 +7042,16 @@ export declare type ReactiveReturn<D extends ExecutorDescriptor> = D extends {
|
|
|
6884
7042
|
readonly descriptor: QueryDescriptor;
|
|
6885
7043
|
} : never;
|
|
6886
7044
|
|
|
7045
|
+
export declare interface ReactiveSocketTunables {
|
|
7046
|
+
readonly maxBufferedBytes: number;
|
|
7047
|
+
readonly overrunAfterMs: number;
|
|
7048
|
+
readonly oversizedEventBytes: number;
|
|
7049
|
+
}
|
|
7050
|
+
|
|
7051
|
+
/** The resolved tunables, or the defaults when no boot path has set any
|
|
7052
|
+
* (unit tests, a bare library use). */
|
|
7053
|
+
export declare const reactiveSocketTunables: () => ReactiveSocketTunables;
|
|
7054
|
+
|
|
6887
7055
|
export declare interface ReadClassification {
|
|
6888
7056
|
/** Tables whose ROWS can reach the caller: the queried table and its joins. */
|
|
6889
7057
|
readonly composed: ReadonlySet<string>;
|
|
@@ -6970,6 +7138,8 @@ export declare interface RebacSubject {
|
|
|
6970
7138
|
readonly scopes?: ReadonlyArray<string>;
|
|
6971
7139
|
}
|
|
6972
7140
|
|
|
7141
|
+
export declare const recordCoalesced: (label: string, collapsed: number) => void;
|
|
7142
|
+
|
|
6973
7143
|
export declare const recordCredentialExpiry: (clientId: number, exp: number | undefined) => void;
|
|
6974
7144
|
|
|
6975
7145
|
/** What the framework emit-seams (servePipeline / rpcServer / plugin wrappers)
|
|
@@ -6996,6 +7166,15 @@ export declare const recordEventPublished: (event: string) => void;
|
|
|
6996
7166
|
/** Subscriber attached (+1) or detached (-1). */
|
|
6997
7167
|
export declare const recordEventSubscribers: (event: string, delta: number) => void;
|
|
6998
7168
|
|
|
7169
|
+
/**
|
|
7170
|
+
* Record one emitted event into the identity's ring. Snapshots RESET the ring
|
|
7171
|
+
* (the snapshot's revision becomes the new replay base — a client holding an
|
|
7172
|
+
* older revision is outside the chain); deltas append. An error event drops
|
|
7173
|
+
* the ring: whatever state the client holds, the safe answer after an error
|
|
7174
|
+
* is a fresh snapshot.
|
|
7175
|
+
*/
|
|
7176
|
+
export declare const recordForResume: (identity: ResumeIdentity, event: SubscriptionEvent<unknown>, now?: number, tunables?: ResumeTunables) => void;
|
|
7177
|
+
|
|
6999
7178
|
/**
|
|
7000
7179
|
* A store that notes every read and changes nothing else.
|
|
7001
7180
|
*
|
|
@@ -7006,6 +7185,10 @@ export declare const recordEventSubscribers: (event: string, delta: number) => v
|
|
|
7006
7185
|
*/
|
|
7007
7186
|
export declare const recordingStore: (store: DataStore) => DataStore;
|
|
7008
7187
|
|
|
7188
|
+
export declare const recordOverrun: (label: string) => void;
|
|
7189
|
+
|
|
7190
|
+
export declare const recordOversized: (label: string) => void;
|
|
7191
|
+
|
|
7009
7192
|
/**
|
|
7010
7193
|
* Record a raw read, opening a scope for the rest of this execution context if
|
|
7011
7194
|
* none is open yet.
|
|
@@ -7296,6 +7479,13 @@ export declare interface RegistryTableLike {
|
|
|
7296
7479
|
* request was. */
|
|
7297
7480
|
export declare const rehydrateGuards: (serialized: ReadonlyArray<SerializedGuard>) => ReadonlyArray<AnyGuardSpec>;
|
|
7298
7481
|
|
|
7482
|
+
/** The store slice `applyDeclaredRelations` needs. */
|
|
7483
|
+
declare interface RelationLinksStore {
|
|
7484
|
+
relationLinks(junctionTable: string, anchorTable: string, anchorId: string): {
|
|
7485
|
+
set(targetIds: ReadonlyArray<string>): Promise<unknown>;
|
|
7486
|
+
};
|
|
7487
|
+
}
|
|
7488
|
+
|
|
7299
7489
|
/** A relationship tuple — `subjectId` has `relation` on `<resourceType>:<resourceId>`.
|
|
7300
7490
|
* In practice these are rows in a relation table; the engine takes them as data. */
|
|
7301
7491
|
export declare interface RelationTuple {
|
|
@@ -7481,15 +7671,24 @@ export declare const resetComputedQueryCacheWarnings: () => void;
|
|
|
7481
7671
|
/** Test/dev-only — clear ALL per-connection state. Don't call from app code. */
|
|
7482
7672
|
export declare const _resetConnectionCredentialsForTest: () => void;
|
|
7483
7673
|
|
|
7674
|
+
/** Test seam — expire everything immediately. */
|
|
7675
|
+
export declare const resetDetachedForTest: () => void;
|
|
7676
|
+
|
|
7484
7677
|
/** Test seams for the tag-cache guard — the cache is module-private otherwise. */
|
|
7485
7678
|
export declare const resetEventMetricTagCacheForTests: () => void;
|
|
7486
7679
|
|
|
7487
7680
|
/** Drop everything recorded. For tests; not called by the runtime. */
|
|
7488
7681
|
export declare const resetObservedGraph: () => void;
|
|
7489
7682
|
|
|
7683
|
+
/** Test seam. */
|
|
7684
|
+
export declare const resetResumeRingsForTest: () => void;
|
|
7685
|
+
|
|
7490
7686
|
/** Reset to the env default (tests). */
|
|
7491
7687
|
export declare const resetSecretsBackend: () => void;
|
|
7492
7688
|
|
|
7689
|
+
/** Test seam. */
|
|
7690
|
+
export declare const resetSubscriptionSocketMetrics: () => void;
|
|
7691
|
+
|
|
7493
7692
|
/**
|
|
7494
7693
|
* The client address to rate-limit, geo-block and audit by.
|
|
7495
7694
|
*
|
|
@@ -7808,6 +8007,46 @@ export declare const restrictingReadsEffect: <A, E, R>(effect: Effect.Effect<A,
|
|
|
7808
8007
|
/** The full ordered list of result variants for a definition, holdout last. */
|
|
7809
8008
|
export declare const resultVariantNames: (def: ExperimentDefinition) => ReadonlyArray<string>;
|
|
7810
8009
|
|
|
8010
|
+
export declare type ResumeAnswer =
|
|
8011
|
+
/** The client's revision chains: replay these deltas in order. */
|
|
8012
|
+
{
|
|
8013
|
+
readonly kind: 'deltas';
|
|
8014
|
+
readonly deltas: ReadonlyArray<RingDelta>;
|
|
8015
|
+
}
|
|
8016
|
+
/** Outside the window / unknown identity / gap — send a snapshot,
|
|
8017
|
+
* `resumed: false`. */
|
|
8018
|
+
| {
|
|
8019
|
+
readonly kind: 'snapshot';
|
|
8020
|
+
};
|
|
8021
|
+
|
|
8022
|
+
/**
|
|
8023
|
+
* The identity a ring is recorded under — and the identity a resume must
|
|
8024
|
+
* present to read it back. `subjectId`/`tenantId` are part of the KEY, so a
|
|
8025
|
+
* login/logout/tenant-switch between disconnect and resume simply misses the
|
|
8026
|
+
* ring and falls back to a snapshot (`resumed: false`) — the blank-on-auth
|
|
8027
|
+
* doctrine, enforced structurally rather than checked.
|
|
8028
|
+
*/
|
|
8029
|
+
export declare interface ResumeIdentity {
|
|
8030
|
+
readonly label: string;
|
|
8031
|
+
/** Canonicalised query input (JSON with sorted keys). */
|
|
8032
|
+
readonly inputKey: string;
|
|
8033
|
+
readonly subjectId: string;
|
|
8034
|
+
readonly tenantId: string;
|
|
8035
|
+
}
|
|
8036
|
+
|
|
8037
|
+
export declare const resumeKeyOf: (identity: ResumeIdentity) => string;
|
|
8038
|
+
|
|
8039
|
+
export declare interface ResumeSink {
|
|
8040
|
+
current: (event: SubscriptionEvent<unknown>) => void;
|
|
8041
|
+
}
|
|
8042
|
+
|
|
8043
|
+
export declare interface ResumeTunables {
|
|
8044
|
+
readonly windowMs: number;
|
|
8045
|
+
readonly maxDeltas: number;
|
|
8046
|
+
}
|
|
8047
|
+
|
|
8048
|
+
export declare const resumeTunables: () => ResumeTunables;
|
|
8049
|
+
|
|
7811
8050
|
export { RetentionConflict }
|
|
7812
8051
|
|
|
7813
8052
|
export { RetentionSource }
|
|
@@ -7882,6 +8121,12 @@ export declare const revokedIds: (before: ReadonlyArray<{
|
|
|
7882
8121
|
readonly id: string;
|
|
7883
8122
|
}>) => ReadonlyArray<string>;
|
|
7884
8123
|
|
|
8124
|
+
declare interface RingDelta {
|
|
8125
|
+
readonly revision: number;
|
|
8126
|
+
readonly emittedAt: number;
|
|
8127
|
+
readonly patch: RowPatch;
|
|
8128
|
+
}
|
|
8129
|
+
|
|
7885
8130
|
/**
|
|
7886
8131
|
* Live traffic the router fronts — read by idle detection (the orchestrator
|
|
7887
8132
|
* can't see the app's HTTP/WS load directly when it's scaled to zero, but
|
|
@@ -8968,6 +9213,12 @@ export declare interface ServeRequestContext {
|
|
|
8968
9213
|
readonly subject: unknown;
|
|
8969
9214
|
readonly traceId: string;
|
|
8970
9215
|
readonly spanId?: string;
|
|
9216
|
+
/**
|
|
9217
|
+
* Caller-side cancellation (the gRPC deadline / client-cancel path).
|
|
9218
|
+
* Honoured at the ONE place the executor effect runs to a promise, so an
|
|
9219
|
+
* exceeded deadline INTERRUPTS the server work — not merely the response.
|
|
9220
|
+
*/
|
|
9221
|
+
readonly signal?: AbortSignal;
|
|
8971
9222
|
/**
|
|
8972
9223
|
* Row-level visibility for this request, resolved by `withRowFilter` and read
|
|
8973
9224
|
* by the context builder when it wraps the store.
|
|
@@ -9025,6 +9276,8 @@ export declare type ServeRpcInterceptor = (base: Effect.Effect<unknown, unknown,
|
|
|
9025
9276
|
readonly target?: ReadonlyArray<string>;
|
|
9026
9277
|
}) => Effect.Effect<unknown, unknown, never>;
|
|
9027
9278
|
|
|
9279
|
+
export declare const setBufferedBytes: (label: string, bytes: number) => void;
|
|
9280
|
+
|
|
9028
9281
|
/** Register the process-wide connection resolver (or clear with `undefined`).
|
|
9029
9282
|
* Called by the CLI at boot; tests call it directly. */
|
|
9030
9283
|
export declare const setConnectionResolver: (resolver: ConnectionResolver | undefined) => void;
|
|
@@ -9032,6 +9285,10 @@ export declare const setConnectionResolver: (resolver: ConnectionResolver | unde
|
|
|
9032
9285
|
/** Register the field cipher (or clear with `undefined`). */
|
|
9033
9286
|
export declare const setFieldCipher: (cipher: FieldCipher | undefined) => void;
|
|
9034
9287
|
|
|
9288
|
+
export declare const setReactiveSocketTunables: (tunables: ReactiveSocketTunables | null) => void;
|
|
9289
|
+
|
|
9290
|
+
export declare const setResumeTunables: (tunables: ResumeTunables | null) => void;
|
|
9291
|
+
|
|
9035
9292
|
/**
|
|
9036
9293
|
* Boot-path wiring. `null` clears (shutdown). Registering `null` vs never
|
|
9037
9294
|
* registering are deliberately the SAME state — a call before boot wiring and
|
|
@@ -9160,7 +9417,10 @@ export declare interface SnapshotCacheBinding {
|
|
|
9160
9417
|
readonly swrMs: number | undefined;
|
|
9161
9418
|
}
|
|
9162
9419
|
|
|
9163
|
-
/** Snapshot the whole registry, normalized to `MetricSample[]
|
|
9420
|
+
/** Snapshot the whole registry, normalized to `MetricSample[]` — plus the
|
|
9421
|
+
* socket-backpressure counters (`subscriptionSocketMetrics.ts`), appended
|
|
9422
|
+
* HERE so every reader (Prometheus exporter, inspect Metrics panel) sees
|
|
9423
|
+
* one derivation and the two cannot diverge. */
|
|
9164
9424
|
export declare const snapshotMetrics: Effect.Effect<ReadonlyArray<MetricSample>>;
|
|
9165
9425
|
|
|
9166
9426
|
/** Eager snapshot for sync callers (the inspect endpoint). */
|
|
@@ -9425,6 +9685,22 @@ export declare interface SubscriberDefinition {
|
|
|
9425
9685
|
readonly handler: SubscribeHandler;
|
|
9426
9686
|
}
|
|
9427
9687
|
|
|
9688
|
+
export declare interface SubscriptionBackpressureOptions {
|
|
9689
|
+
/** Estimated pending bytes above which a persistently-blocked consumer is
|
|
9690
|
+
* overrun-closed. `reactive.socket.maxBufferedBytes` / env override. */
|
|
9691
|
+
readonly maxBufferedBytes: number;
|
|
9692
|
+
/** How long the pending state must stay over the threshold (with the pump
|
|
9693
|
+
* blocked) before the terminal close. */
|
|
9694
|
+
readonly overrunAfterMs: number;
|
|
9695
|
+
/** Per-event WARN threshold — telemetry for oversized snapshots/deltas.
|
|
9696
|
+
* Deliberately NOT a cap: measurability is the goal. */
|
|
9697
|
+
readonly oversizedEventBytes: number;
|
|
9698
|
+
/** Query tag for logs + metrics. */
|
|
9699
|
+
readonly label: string;
|
|
9700
|
+
readonly now?: () => number;
|
|
9701
|
+
readonly warn?: (message: string, fields: Record<string, unknown>) => void;
|
|
9702
|
+
}
|
|
9703
|
+
|
|
9428
9704
|
/**
|
|
9429
9705
|
* Timing of ONE subscription delivery (the initial snapshot, or a delta
|
|
9430
9706
|
* pushed on a change). The duration is the real produce→push latency:
|
|
@@ -9460,6 +9736,29 @@ export declare interface SubscriptionDeliveryRecord {
|
|
|
9460
9736
|
readonly rowCount: number;
|
|
9461
9737
|
}
|
|
9462
9738
|
|
|
9739
|
+
export declare interface SubscriptionOutbox {
|
|
9740
|
+
/** SYNC push from the dispatcher's emit callback. */
|
|
9741
|
+
readonly push: (event: Event_2) => void;
|
|
9742
|
+
/** Pump side: resolves with the next event to hand into the stream —
|
|
9743
|
+
* coalesced when more than one push landed since the last take — or null
|
|
9744
|
+
* once the outbox is closed and drained. */
|
|
9745
|
+
readonly take: () => Promise<Event_2 | null>;
|
|
9746
|
+
/** True once the overrun policy fired (the error event has been queued;
|
|
9747
|
+
* the stream ends after it drains). */
|
|
9748
|
+
readonly overrun: () => boolean;
|
|
9749
|
+
readonly close: () => void;
|
|
9750
|
+
}
|
|
9751
|
+
|
|
9752
|
+
/** The wire shape of the terminal overrun error — documented in
|
|
9753
|
+
* wire-protocol.md. The client surfaces it as the entry's `error` and
|
|
9754
|
+
* re-subscribes for a fresh snapshot. */
|
|
9755
|
+
export declare interface SubscriptionOverrunError {
|
|
9756
|
+
readonly _tag: 'SubscriptionOverrun';
|
|
9757
|
+
readonly message: string;
|
|
9758
|
+
readonly bufferedBytes: number;
|
|
9759
|
+
readonly maxBufferedBytes: number;
|
|
9760
|
+
}
|
|
9761
|
+
|
|
9463
9762
|
export declare type SubscriptionRecord = {
|
|
9464
9763
|
readonly id: string;
|
|
9465
9764
|
readonly table: string;
|
|
@@ -9520,6 +9819,35 @@ export declare interface SubscriptionSnapshot {
|
|
|
9520
9819
|
readonly subscriberCount: number;
|
|
9521
9820
|
}
|
|
9522
9821
|
|
|
9822
|
+
/**
|
|
9823
|
+
* The counters as `MetricSample`s — appended by `snapshotMetrics`
|
|
9824
|
+
* (metrics.ts), which is the ONE derivation both the Prometheus exporter and
|
|
9825
|
+
* the inspect Metrics panel read. Same input → the two cannot diverge.
|
|
9826
|
+
*/
|
|
9827
|
+
export declare const subscriptionSocketMetricSamples: () => ReadonlyArray< MetricSample>;
|
|
9828
|
+
|
|
9829
|
+
export declare interface SubscriptionSocketMetricsSnapshot {
|
|
9830
|
+
/** Sum + per-label current pending bytes across live subscriptions. */
|
|
9831
|
+
readonly bufferedBytes: {
|
|
9832
|
+
readonly total: number;
|
|
9833
|
+
readonly byLabel: Readonly<Record<string, number>>;
|
|
9834
|
+
};
|
|
9835
|
+
readonly coalescedTotal: {
|
|
9836
|
+
readonly total: number;
|
|
9837
|
+
readonly byLabel: Readonly<Record<string, number>>;
|
|
9838
|
+
};
|
|
9839
|
+
readonly overrunTotal: {
|
|
9840
|
+
readonly total: number;
|
|
9841
|
+
readonly byLabel: Readonly<Record<string, number>>;
|
|
9842
|
+
};
|
|
9843
|
+
readonly oversizedTotal: {
|
|
9844
|
+
readonly total: number;
|
|
9845
|
+
readonly byLabel: Readonly<Record<string, number>>;
|
|
9846
|
+
};
|
|
9847
|
+
}
|
|
9848
|
+
|
|
9849
|
+
export declare const subscriptionSocketMetricsSnapshot: () => SubscriptionSocketMetricsSnapshot;
|
|
9850
|
+
|
|
9523
9851
|
/** Drop handshake grants past their TTL. Wired into the boot retention sweep;
|
|
9524
9852
|
* a grant is worthless the moment it expires and keeping them turns a hot
|
|
9525
9853
|
* table into an audit liability. */
|
|
@@ -10390,24 +10718,6 @@ export declare const webhookVerificationOf: (handle: unknown) => WebhookVerifica
|
|
|
10390
10718
|
*/
|
|
10391
10719
|
export declare type WhereOp = '=' | '!=' | '<>' | '>' | '>=' | '<' | '<=' | 'in' | 'contains' | 'startsWith' | 'fts';
|
|
10392
10720
|
|
|
10393
|
-
/**
|
|
10394
|
-
* Resolve this request's row-filter scope. A no-op (same object back) when the
|
|
10395
|
-
* app registered no filter, so an app that uses none pays nothing.
|
|
10396
|
-
*
|
|
10397
|
-
* Every runner calls this before building a context. A read path that skipped
|
|
10398
|
-
* it would have no row-level security and would look exactly like one that
|
|
10399
|
-
* does — which is why it lives in the shared spine rather than in each
|
|
10400
|
-
* entrypoint.
|
|
10401
|
-
*
|
|
10402
|
-
* REJECTS with the raw `RowFilterUnavailable` (via `runProvidedEffect`, not
|
|
10403
|
-
* `Effect.runPromise`) when the filter's `onLoadError` is the default `'fail'`
|
|
10404
|
-
* and `load` failed every retry. Raw, so the rpc encoder matches it against the
|
|
10405
|
-
* descriptor's `error:` schema and the client gets the tag instead of an opaque
|
|
10406
|
-
* defect — the same treatment `enforceGuards` gives a `ScopeError`. Proceeding
|
|
10407
|
-
* with an unresolved filter is not an option here: the context builder would
|
|
10408
|
-
* receive `rowFilter: undefined`, which means "this app registered no filter"
|
|
10409
|
-
* and would silently serve the request UNFILTERED.
|
|
10410
|
-
*/
|
|
10411
10721
|
export declare const withRowFilter: <R extends ServeRequestContext>(request: R) => Promise<R>;
|
|
10412
10722
|
|
|
10413
10723
|
/**
|
|
@@ -10937,7 +11247,7 @@ export declare interface WorkflowWaitOptions {
|
|
|
10937
11247
|
* calls (incl. multi-table within one mutation) are. A mutation that writes via
|
|
10938
11248
|
* a bulk helper simply produces no undo entry (documented).
|
|
10939
11249
|
*/
|
|
10940
|
-
export declare const wrapCaptureStore: (tx: DataStore, collect: (c: ForwardChange) => void) => DataStore;
|
|
11250
|
+
export declare const wrapCaptureStore: (tx: DataStore, collect: (c: ForwardChange) => void, crdtColumnsOf?: (table: string) => ReadonlySet<string>) => DataStore;
|
|
10941
11251
|
|
|
10942
11252
|
/**
|
|
10943
11253
|
* Wrap a raw `DataStore` with the storage codec only — `.encrypted()` columns
|