@voltro/protocol 0.51.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 +356 -0
- package/dist/index.d.ts +245 -4
- package/dist/index.js +544 -441
- package/dist/rest.d.ts +99 -3
- package/dist/rest.js +81 -36
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -136,6 +136,8 @@ export declare interface AppliedScopes {
|
|
|
136
136
|
readonly removed: ReadonlyArray<string>;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
export declare const applyRowPatch: (prev: ReadonlyArray<PatchRow>, patch: RowPatch, options?: ApplyRowPatchOptions) => ReadonlyArray<PatchRow>;
|
|
140
|
+
|
|
139
141
|
/**
|
|
140
142
|
* Apply a `RowPatch` to `prev`, producing `next`. Exact inverse of
|
|
141
143
|
* `diffRows`: `applyRowPatch(prev, diffRows(prev, next))` deep-equals
|
|
@@ -149,7 +151,18 @@ export declare interface AppliedScopes {
|
|
|
149
151
|
* an `add`) is skipped rather than throwing, so one dropped frame degrades
|
|
150
152
|
* to a slightly stale set instead of a crash.
|
|
151
153
|
*/
|
|
152
|
-
export declare
|
|
154
|
+
export declare interface ApplyRowPatchOptions {
|
|
155
|
+
/**
|
|
156
|
+
* The CRDT downstream lane's applier half: fold a `mergeCells` update into
|
|
157
|
+
* the held cell value. Injected (the patch layer is CRDT-library-free);
|
|
158
|
+
* `@voltro/local-first` provides the real one. When absent, a `mergeCells`
|
|
159
|
+
* op REPLACES the cell with the update — wrong for a true incremental
|
|
160
|
+
* update, which is why the producer only emits `mergeCells` toward
|
|
161
|
+
* consumers that negotiated it; the fallback keeps an unpaired frame from
|
|
162
|
+
* crashing the applier.
|
|
163
|
+
*/
|
|
164
|
+
readonly mergeCell?: (column: string, prevValue: unknown, update: unknown) => unknown;
|
|
165
|
+
}
|
|
153
166
|
|
|
154
167
|
/**
|
|
155
168
|
* Apply a decision to a Subject, touching nothing but `scopes`.
|
|
@@ -902,6 +915,15 @@ export declare interface ConnectionInfoValue {
|
|
|
902
915
|
* doc comment that claims otherwise.
|
|
903
916
|
*/
|
|
904
917
|
readonly credentialExpiresAt?: number;
|
|
918
|
+
/**
|
|
919
|
+
* The per-CALL `voltro-resume-from` request header, parsed: the last
|
|
920
|
+
* subscription revision the client materialised before it lost the
|
|
921
|
+
* connection. Read by `bindSubscription` to attempt a delta-resume — the
|
|
922
|
+
* server replays only the missed deltas when the retained ring still
|
|
923
|
+
* chains this revision, and falls back to a fresh snapshot otherwise.
|
|
924
|
+
* Absent when the client did not ask to resume (a fresh subscribe).
|
|
925
|
+
*/
|
|
926
|
+
readonly resumeFrom?: number;
|
|
905
927
|
}
|
|
906
928
|
|
|
907
929
|
/** The two credential shapes a connection can hold. `oauth2` = an
|
|
@@ -1623,6 +1645,13 @@ export declare const defineStream: <const Name extends string, Input extends Sch
|
|
|
1623
1645
|
readonly openAccess?: string;
|
|
1624
1646
|
}) => StreamProcedureDescriptor<Name, Input, Element, Error>;
|
|
1625
1647
|
|
|
1648
|
+
/**
|
|
1649
|
+
* Declare a raw WebSocket gateway (`*.ws.ts` default export). Validation at
|
|
1650
|
+
* DEFINITION time — a bad path fails the boot that discovers it, not the
|
|
1651
|
+
* first client.
|
|
1652
|
+
*/
|
|
1653
|
+
export declare const defineWebSocket: (route: WebSocketGatewayRoute) => WebSocketGatewayRoute;
|
|
1654
|
+
|
|
1626
1655
|
export declare interface DeleteTarget<Input = unknown> extends NestedTargetFields<Input> {
|
|
1627
1656
|
readonly table: string;
|
|
1628
1657
|
readonly op: 'delete';
|
|
@@ -1631,6 +1660,8 @@ export declare interface DeleteTarget<Input = unknown> extends NestedTargetField
|
|
|
1631
1660
|
readonly identify?: ((input: Input) => string | ReadonlyArray<string>) | undefined;
|
|
1632
1661
|
}
|
|
1633
1662
|
|
|
1663
|
+
export declare const diffRows: (prev: ReadonlyArray<PatchRow>, next: ReadonlyArray<PatchRow>, options?: DiffRowsOptions) => RowPatch;
|
|
1664
|
+
|
|
1634
1665
|
/**
|
|
1635
1666
|
* Compute the patch that turns `prev` into `next`, keyed by row id.
|
|
1636
1667
|
*
|
|
@@ -1646,7 +1677,22 @@ export declare interface DeleteTarget<Input = unknown> extends NestedTargetField
|
|
|
1646
1677
|
* id-keyed result sets; a result without ids must ship a full snapshot,
|
|
1647
1678
|
* not a patch.
|
|
1648
1679
|
*/
|
|
1649
|
-
export declare
|
|
1680
|
+
export declare interface DiffRowsOptions {
|
|
1681
|
+
/**
|
|
1682
|
+
* The CRDT downstream lane. `columns` names the CRDT-managed columns of
|
|
1683
|
+
* this row set; `incremental(column, prevValue, nextValue)` returns the
|
|
1684
|
+
* SMALL update a holder of prevValue needs to reach nextValue (or
|
|
1685
|
+
* `undefined` to fall back to a plain replace — e.g. a prev the encoder
|
|
1686
|
+
* cannot read). When a changed row's CRDT cells are the only change, the
|
|
1687
|
+
* diff emits ONE `mergeCells` op; when scalars changed too, the `replace`
|
|
1688
|
+
* carries the row WITHOUT its CRDT columns and the `mergeCells` op rides
|
|
1689
|
+
* beside it.
|
|
1690
|
+
*/
|
|
1691
|
+
readonly crdt?: {
|
|
1692
|
+
readonly columns: ReadonlySet<string>;
|
|
1693
|
+
readonly incremental: (column: string, prevValue: unknown, nextValue: unknown) => unknown | undefined;
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1650
1696
|
|
|
1651
1697
|
/**
|
|
1652
1698
|
* The caller's effective scope set — the merged set published by rbac if
|
|
@@ -1996,6 +2042,17 @@ export declare type ExtraErrors = ReadonlyArray<Schema.Schema.All>;
|
|
|
1996
2042
|
/** Release a claim after the handler errored, so a retry can re-process. */
|
|
1997
2043
|
export declare const failIdempotent: (store: IdempotencyStore, scope: string, key: string) => Promise<void>;
|
|
1998
2044
|
|
|
2045
|
+
/**
|
|
2046
|
+
* The field-addressed issues carried by a wire error, or `[]` when the error
|
|
2047
|
+
* is not field-routable. ONE reader for all three shapes — `ValidationError`,
|
|
2048
|
+
* `ValidationErrors`, and a `BusinessRuleViolation` whose rule pinpointed a
|
|
2049
|
+
* `field` — so the form binding, `<AutoForm>`, and any custom widget kit
|
|
2050
|
+
* cannot disagree about which errors belong on a field. A
|
|
2051
|
+
* `BusinessRuleViolation` WITHOUT a field is form-level, not field-level, and
|
|
2052
|
+
* correctly stays in `submitError`.
|
|
2053
|
+
*/
|
|
2054
|
+
export declare const fieldIssuesOf: (error: unknown) => ReadonlyArray<ValidationIssueShape>;
|
|
2055
|
+
|
|
1999
2056
|
/**
|
|
2000
2057
|
* Report descriptors whose `guards:` declare a per-resource check that nothing
|
|
2001
2058
|
* will enforce.
|
|
@@ -2027,6 +2084,11 @@ export declare const finishIdempotent: (store: IdempotencyStore, scope: string,
|
|
|
2027
2084
|
/** A route rendered for humans — logs, the inspect surface, the dashboard. */
|
|
2028
2085
|
export declare const formatEventRoute: (route: string) => string;
|
|
2029
2086
|
|
|
2087
|
+
/** Close code a gateway connection receives when its credential expires —
|
|
2088
|
+
* the same session-expiry contract the rpc socket has (SEC-16), spelled as
|
|
2089
|
+
* an application close code so foreign clients can reauth + reconnect. */
|
|
2090
|
+
export declare const GATEWAY_CREDENTIAL_EXPIRED_CLOSE_CODE = 4001;
|
|
2091
|
+
|
|
2030
2092
|
/** The currently-registered policy-guard resolver, or `undefined`. */
|
|
2031
2093
|
export declare const getPolicyGuardResolver: () => PolicyGuardResolver | undefined;
|
|
2032
2094
|
|
|
@@ -2290,6 +2352,8 @@ export declare const inputLabel: (procedure?: string, guarded?: boolean) => stri
|
|
|
2290
2352
|
export declare interface InsertTarget<Input = unknown, Row = unknown, Item = Record<string, unknown>> extends NestedTargetFields<Input> {
|
|
2291
2353
|
readonly table: string;
|
|
2292
2354
|
readonly op: 'insert';
|
|
2355
|
+
/** Declared junction relations — see {@link TargetRelations}. */
|
|
2356
|
+
readonly relations?: TargetRelations | undefined;
|
|
2293
2357
|
readonly order?: 'prepend' | 'append' | undefined;
|
|
2294
2358
|
/**
|
|
2295
2359
|
* Build the optimistic row from the mutation input. The framework
|
|
@@ -2869,6 +2933,16 @@ export declare interface PluginEnvVar {
|
|
|
2869
2933
|
readonly description?: string;
|
|
2870
2934
|
/** Example value for `.env.example`. Never a real secret. */
|
|
2871
2935
|
readonly example?: string;
|
|
2936
|
+
/**
|
|
2937
|
+
* Set ONLY when the secret is OURS to invent (a signing key, a VAPID scalar)
|
|
2938
|
+
* — `voltro dev` then mints a per-project value into the gitignored
|
|
2939
|
+
* `.env.local`, exactly like an app-declared `envVar.secret({ generate })`.
|
|
2940
|
+
* `p256` mints a base64url raw P-256 private scalar (web push VAPID).
|
|
2941
|
+
* NEVER set it for a third-party credential: an invented value merely looks
|
|
2942
|
+
* right, and the boot failure is the useful outcome. Minting stays dev-only —
|
|
2943
|
+
* in production a missing secret refuses the boot.
|
|
2944
|
+
*/
|
|
2945
|
+
readonly generate?: 'base64url' | 'hex' | 'p256';
|
|
2872
2946
|
}
|
|
2873
2947
|
|
|
2874
2948
|
/**
|
|
@@ -2897,12 +2971,19 @@ export declare interface PluginErrorSchema {
|
|
|
2897
2971
|
|
|
2898
2972
|
/** A public raw-HTTP route a plugin serves on the framework listener. */
|
|
2899
2973
|
export declare interface PluginHttpRoute {
|
|
2900
|
-
/** HTTP method, or `'*'` for any (the handler decides).
|
|
2901
|
-
|
|
2974
|
+
/** HTTP method, or `'*'` for any (the handler decides). PATCH/HEAD/OPTIONS
|
|
2975
|
+
* are first-class — the REST desugar used to mount `'*'` partly BECAUSE
|
|
2976
|
+
* this union lacked PATCH; that reason is gone (the `'*'` mount remains
|
|
2977
|
+
* for its other job: one dispatcher per shared path + a precise 405). */
|
|
2978
|
+
readonly method: '*' | 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
|
|
2902
2979
|
/** Absolute path prefix, e.g. `/_voltro/storage`. Matches the path AND
|
|
2903
2980
|
* any sub-path (`/_voltro/storage/abc123`). */
|
|
2904
2981
|
readonly path: string;
|
|
2905
2982
|
readonly handle: (req: PluginHttpRouteRequest) => Promise<PluginHttpRouteResult>;
|
|
2983
|
+
/** Per-route body cap override (bytes) — wins over the listener's shared
|
|
2984
|
+
* `maxBodyBytes`. NOTE: routes SHARING a path share one body read, so the
|
|
2985
|
+
* widest override on the path's group applies to the whole group. */
|
|
2986
|
+
readonly maxBodyBytes?: number;
|
|
2906
2987
|
/**
|
|
2907
2988
|
* Opt this route's path OUT of the listener's cross-site origin check.
|
|
2908
2989
|
*
|
|
@@ -2941,6 +3022,21 @@ export declare interface PluginHttpRoute {
|
|
|
2941
3022
|
readonly originGuard?: 'exempt';
|
|
2942
3023
|
}
|
|
2943
3024
|
|
|
3025
|
+
/**
|
|
3026
|
+
* A binary streaming body — the download/export shape. The serve layer pipes
|
|
3027
|
+
* the Web ReadableStream to the socket without buffering, so a response
|
|
3028
|
+
* larger than the heap is fine; the LAZY thunk form defers opening the
|
|
3029
|
+
* source (a provider connection, a file handle) until the response actually
|
|
3030
|
+
* streams.
|
|
3031
|
+
*/
|
|
3032
|
+
export declare interface PluginHttpRouteByteStream {
|
|
3033
|
+
readonly stream: ReadableStream<Uint8Array> | (() => ReadableStream<Uint8Array>);
|
|
3034
|
+
/** Declared up front when known — lets the client render progress. */
|
|
3035
|
+
readonly contentLength?: number;
|
|
3036
|
+
/** e.g. `attachment; filename="export.zip"`. */
|
|
3037
|
+
readonly contentDisposition?: string;
|
|
3038
|
+
}
|
|
3039
|
+
|
|
2944
3040
|
export declare interface PluginHttpRouteRequest {
|
|
2945
3041
|
readonly method: string;
|
|
2946
3042
|
/** Path WITHOUT query string. */
|
|
@@ -3052,6 +3148,12 @@ export declare interface PluginHttpRouteResult {
|
|
|
3052
3148
|
/** Stream the response (SSE) instead of sending `body`. See
|
|
3053
3149
|
* {@link PluginHttpRouteStream}. */
|
|
3054
3150
|
readonly stream?: PluginHttpRouteStream;
|
|
3151
|
+
/** Stream a BINARY response (a download, an export) instead of sending
|
|
3152
|
+
* `body` — see {@link PluginHttpRouteByteStream}. Never buffered by the
|
|
3153
|
+
* serve layer; never compressed (flush timing + Content-Length are the
|
|
3154
|
+
* contract). Takes precedence over `body`; do not set both `stream` and
|
|
3155
|
+
* `byteStream`. */
|
|
3156
|
+
readonly byteStream?: PluginHttpRouteByteStream;
|
|
3055
3157
|
}
|
|
3056
3158
|
|
|
3057
3159
|
/**
|
|
@@ -3697,6 +3799,10 @@ export declare const queryToRpc: <Name extends string, Input extends Schema.Sche
|
|
|
3697
3799
|
}>, Schema.Struct<{
|
|
3698
3800
|
op: Schema.Literal<["remove"]>;
|
|
3699
3801
|
path: typeof Schema.String;
|
|
3802
|
+
}>, Schema.Struct<{
|
|
3803
|
+
op: Schema.Literal<["mergeCells"]>;
|
|
3804
|
+
path: typeof Schema.String;
|
|
3805
|
+
value: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
|
|
3700
3806
|
}>]>>;
|
|
3701
3807
|
order: Schema.Array$<Schema.Union<[typeof Schema.String, typeof Schema.Number]>>;
|
|
3702
3808
|
}>;
|
|
@@ -3836,6 +3942,19 @@ export declare type RowPatchOp = {
|
|
|
3836
3942
|
} | {
|
|
3837
3943
|
readonly op: 'remove';
|
|
3838
3944
|
readonly path: string;
|
|
3945
|
+
}
|
|
3946
|
+
/** The CRDT downstream lane (plan 18): cell-level MERGE instead of
|
|
3947
|
+
* replace. `value` maps column → an INCREMENTAL encoded update (what the
|
|
3948
|
+
* subscriber is missing relative to the previous delivery, not the full
|
|
3949
|
+
* document), and the applier folds it into the held cell with the
|
|
3950
|
+
* injected merger. This is what keeps a 1-character edit ≤1KB on the
|
|
3951
|
+
* subscription wire regardless of document size. A `mergeCells` op may
|
|
3952
|
+
* accompany a `replace` on the same row — the replace then carries the
|
|
3953
|
+
* row WITHOUT its CRDT columns. */
|
|
3954
|
+
| {
|
|
3955
|
+
readonly op: 'mergeCells';
|
|
3956
|
+
readonly path: string;
|
|
3957
|
+
readonly value: Readonly<Record<string, unknown>>;
|
|
3839
3958
|
};
|
|
3840
3959
|
|
|
3841
3960
|
export declare const rowPatchOpSchema: Schema.Union<[Schema.Struct<{
|
|
@@ -3865,6 +3984,10 @@ export declare const rowPatchOpSchema: Schema.Union<[Schema.Struct<{
|
|
|
3865
3984
|
}>, Schema.Struct<{
|
|
3866
3985
|
op: Schema.Literal<["remove"]>;
|
|
3867
3986
|
path: typeof Schema.String;
|
|
3987
|
+
}>, Schema.Struct<{
|
|
3988
|
+
op: Schema.Literal<["mergeCells"]>;
|
|
3989
|
+
path: typeof Schema.String;
|
|
3990
|
+
value: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
|
|
3868
3991
|
}>]>;
|
|
3869
3992
|
|
|
3870
3993
|
export declare const rowPatchSchema: Schema.Struct<{
|
|
@@ -3895,6 +4018,10 @@ export declare const rowPatchSchema: Schema.Struct<{
|
|
|
3895
4018
|
}>, Schema.Struct<{
|
|
3896
4019
|
op: Schema.Literal<["remove"]>;
|
|
3897
4020
|
path: typeof Schema.String;
|
|
4021
|
+
}>, Schema.Struct<{
|
|
4022
|
+
op: Schema.Literal<["mergeCells"]>;
|
|
4023
|
+
path: typeof Schema.String;
|
|
4024
|
+
value: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
|
|
3898
4025
|
}>]>>;
|
|
3899
4026
|
order: Schema.Array$<Schema.Union<[typeof Schema.String, typeof Schema.Number]>>;
|
|
3900
4027
|
}>;
|
|
@@ -4483,6 +4610,10 @@ export declare const subscriptionEvent: <D extends Schema.Schema.Any>(data: D) =
|
|
|
4483
4610
|
}>, Schema.Struct<{
|
|
4484
4611
|
op: Schema.Literal<["remove"]>;
|
|
4485
4612
|
path: typeof Schema.String;
|
|
4613
|
+
}>, Schema.Struct<{
|
|
4614
|
+
op: Schema.Literal<["mergeCells"]>;
|
|
4615
|
+
path: typeof Schema.String;
|
|
4616
|
+
value: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
|
|
4486
4617
|
}>]>>;
|
|
4487
4618
|
order: Schema.Array$<Schema.Union<[typeof Schema.String, typeof Schema.Number]>>;
|
|
4488
4619
|
}>;
|
|
@@ -4573,6 +4704,22 @@ declare const TableValidationFailed_base: Schema.TaggedErrorClass<TableValidatio
|
|
|
4573
4704
|
|
|
4574
4705
|
export declare type Target<Input = unknown, Row = unknown> = TargetSpec<Input, Row> | ReadonlyArray<TargetSpec<Input, Row>>;
|
|
4575
4706
|
|
|
4707
|
+
/**
|
|
4708
|
+
* Declared many-to-many RELATIONS of a write target: `{ inputField:
|
|
4709
|
+
* junctionTable }`. After the executor succeeds — inside the SAME
|
|
4710
|
+
* transaction — the framework reconciles the junction's links for the
|
|
4711
|
+
* written row against `input[inputField]` (an array of target ids) via the
|
|
4712
|
+
* diff-based `store.relationLinks`, so a form's multi-reference field saves
|
|
4713
|
+
* in one mutation with no hand-written junction code. The anchor column is
|
|
4714
|
+
* derived from the junction's `reference()` targets (a self-junction is
|
|
4715
|
+
* refused, never guessed).
|
|
4716
|
+
*
|
|
4717
|
+
* An ABSENT input field leaves the links untouched (absent ≠ empty — an
|
|
4718
|
+
* empty array is the explicit "clear them all"). The row id is the
|
|
4719
|
+
* executor's `output.id`, falling back to `input.id`.
|
|
4720
|
+
*/
|
|
4721
|
+
export declare type TargetRelations = Readonly<Record<string, string>>;
|
|
4722
|
+
|
|
4576
4723
|
export declare type TargetSpec<Input = unknown, Row = unknown> = InsertTarget<Input, Row> | UpdateTarget<Input, Row> | DeleteTarget<Input>;
|
|
4577
4724
|
|
|
4578
4725
|
/**
|
|
@@ -4685,6 +4832,10 @@ export declare const toRpc: <Name extends string, Input extends Schema.Schema.An
|
|
|
4685
4832
|
}>, Schema.Struct<{
|
|
4686
4833
|
op: Schema.Literal<["remove"]>;
|
|
4687
4834
|
path: typeof Schema.String;
|
|
4835
|
+
}>, Schema.Struct<{
|
|
4836
|
+
op: Schema.Literal<["mergeCells"]>;
|
|
4837
|
+
path: typeof Schema.String;
|
|
4838
|
+
value: Schema.Record$<typeof Schema.String, typeof Schema.Unknown>;
|
|
4688
4839
|
}>]>>;
|
|
4689
4840
|
order: Schema.Array$<Schema.Union<[typeof Schema.String, typeof Schema.Number]>>;
|
|
4690
4841
|
}>;
|
|
@@ -4836,6 +4987,8 @@ export declare const undoRedoDescriptor: MutationProcedureDescriptor<"__voltro.u
|
|
|
4836
4987
|
export declare interface UpdateTarget<Input = unknown, Row = unknown, Item = Record<string, unknown>> extends NestedTargetFields<Input> {
|
|
4837
4988
|
readonly table: string;
|
|
4838
4989
|
readonly op: 'update';
|
|
4990
|
+
/** Declared junction relations — see {@link TargetRelations}. */
|
|
4991
|
+
readonly relations?: TargetRelations | undefined;
|
|
4839
4992
|
/** Identify the row(s) to patch. Default: `input.id`. Return an ARRAY to patch
|
|
4840
4993
|
* MANY rows/items in one mutation (a bulk edit — where the per-item
|
|
4841
4994
|
* parallel-write race lived). */
|
|
@@ -4848,6 +5001,52 @@ export declare interface UpdateTarget<Input = unknown, Row = unknown, Item = Rec
|
|
|
4848
5001
|
readonly shapeItem?: ((input: Input, current: Item) => Item) | undefined;
|
|
4849
5002
|
}
|
|
4850
5003
|
|
|
5004
|
+
/**
|
|
5005
|
+
* A server-side validation failure pinned to ONE field.
|
|
5006
|
+
*
|
|
5007
|
+
* return yield* ctx.validation.fail('email', 'validation.emailTaken')
|
|
5008
|
+
*
|
|
5009
|
+
* Routed by the form binding to `errors.email`; the mutation's transaction is
|
|
5010
|
+
* rolled back (or, thrown before any write, never opened).
|
|
5011
|
+
*/
|
|
5012
|
+
export declare class ValidationError extends ValidationError_base {
|
|
5013
|
+
}
|
|
5014
|
+
|
|
5015
|
+
declare const ValidationError_base: Schema.TaggedErrorClass<ValidationError, "ValidationError", {
|
|
5016
|
+
readonly _tag: Schema.tag<"ValidationError">;
|
|
5017
|
+
} & {
|
|
5018
|
+
field: typeof Schema.String;
|
|
5019
|
+
message: typeof Schema.String;
|
|
5020
|
+
params: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
|
|
5021
|
+
}>;
|
|
5022
|
+
|
|
5023
|
+
/** Several field-addressed failures at once — one round trip, every field
|
|
5024
|
+
* marked. `issues` is non-empty by construction (`ctx.validation.failAll`
|
|
5025
|
+
* refuses an empty list rather than shipping a failure with nothing to show). */
|
|
5026
|
+
export declare class ValidationErrors extends ValidationErrors_base {
|
|
5027
|
+
}
|
|
5028
|
+
|
|
5029
|
+
declare const ValidationErrors_base: Schema.TaggedErrorClass<ValidationErrors, "ValidationErrors", {
|
|
5030
|
+
readonly _tag: Schema.tag<"ValidationErrors">;
|
|
5031
|
+
} & {
|
|
5032
|
+
issues: Schema.filter<Schema.Array$<Schema.Struct<{
|
|
5033
|
+
field: typeof Schema.String;
|
|
5034
|
+
message: typeof Schema.String;
|
|
5035
|
+
params: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
|
|
5036
|
+
}>>>;
|
|
5037
|
+
}>;
|
|
5038
|
+
|
|
5039
|
+
/** One field-addressed validation issue: `field` is the form path
|
|
5040
|
+
* (`'email'`, `'address.city'`, `'entries.0.startsAt'`), `message` is a
|
|
5041
|
+
* message id (or verbatim text), `params` feed the message template. */
|
|
5042
|
+
export declare const ValidationIssue: Schema.Struct<{
|
|
5043
|
+
field: typeof Schema.String;
|
|
5044
|
+
message: typeof Schema.String;
|
|
5045
|
+
params: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
|
|
5046
|
+
}>;
|
|
5047
|
+
|
|
5048
|
+
export declare type ValidationIssueShape = Schema.Schema.Type<typeof ValidationIssue>;
|
|
5049
|
+
|
|
4851
5050
|
export declare interface VoltroPlugin {
|
|
4852
5051
|
/**
|
|
4853
5052
|
* Plugin identifier — printed in `voltro dev` boot logs + surfaced in
|
|
@@ -5216,6 +5415,48 @@ export declare interface VoltroPlugin {
|
|
|
5216
5415
|
export declare interface VoltroTableNames {
|
|
5217
5416
|
}
|
|
5218
5417
|
|
|
5418
|
+
/** What a gateway's connection handler receives. Transport-agnostic on
|
|
5419
|
+
* purpose — the runtime adapts the platform socket to this. */
|
|
5420
|
+
export declare interface WebSocketGatewayConnection {
|
|
5421
|
+
/** Send a text or binary frame. */
|
|
5422
|
+
readonly send: (data: string | Uint8Array) => void;
|
|
5423
|
+
/** Close the connection (application close codes 4000-4999 are yours). */
|
|
5424
|
+
readonly close: (code?: number, reason?: string) => void;
|
|
5425
|
+
/** Register a message listener (binary-safe; text arrives as bytes). */
|
|
5426
|
+
readonly onMessage: (listener: (data: Uint8Array) => void) => void;
|
|
5427
|
+
/** The authenticated subject — `null` only on an `auth: 'public'` route. */
|
|
5428
|
+
readonly subject: Subject | null;
|
|
5429
|
+
/** Lowercased request headers of the upgrade. */
|
|
5430
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
5431
|
+
/** The mounted path. */
|
|
5432
|
+
readonly path: string;
|
|
5433
|
+
}
|
|
5434
|
+
|
|
5435
|
+
export declare interface WebSocketGatewayRoute {
|
|
5436
|
+
/** Absolute upgrade path (`/gateways/yjs`). Must not collide with the rpc
|
|
5437
|
+
* socket (`/ws` or the configured `transport.wsPath`) or `/rpc`. */
|
|
5438
|
+
readonly path: `/${string}`;
|
|
5439
|
+
/**
|
|
5440
|
+
* REQUIRED, no default: who may connect.
|
|
5441
|
+
* - `'subject'` — the upgrade resolves a Subject through the SAME auth
|
|
5442
|
+
* chain as rpc/SSR (cookie/bearer); an unauthenticated upgrade is a 401
|
|
5443
|
+
* BEFORE any socket exists, and the connection closes with
|
|
5444
|
+
* {@link GATEWAY_CREDENTIAL_EXPIRED_CLOSE_CODE} when the credential
|
|
5445
|
+
* expires.
|
|
5446
|
+
* - `'public'` — deliberately unauthenticated (a device fleet with its own
|
|
5447
|
+
* protocol-level auth). A decision somebody wrote down, not a default.
|
|
5448
|
+
*/
|
|
5449
|
+
readonly auth: 'subject' | 'public';
|
|
5450
|
+
/**
|
|
5451
|
+
* Runs once per accepted connection. The returned function is the
|
|
5452
|
+
* connection's TEARDOWN — taken at construction (the `startOutboxRunner`
|
|
5453
|
+
* rule): it runs on client disconnect, on credential expiry, and on
|
|
5454
|
+
* server shutdown, so whatever the handler opened cannot outlive the
|
|
5455
|
+
* socket.
|
|
5456
|
+
*/
|
|
5457
|
+
readonly onConnection: (connection: WebSocketGatewayConnection) => void | (() => void) | Promise<void | (() => void)>;
|
|
5458
|
+
}
|
|
5459
|
+
|
|
5219
5460
|
/**
|
|
5220
5461
|
* The error union a procedure ACTUALLY puts on the wire — `descriptor.error`
|
|
5221
5462
|
* plus everything the framework can produce for it before or around the
|