@fuzdev/fuz_app 0.113.0 → 0.114.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/dist/actions/CLAUDE.md +46 -20
- package/dist/actions/action_dispatcher.d.ts +1 -1
- package/dist/actions/action_dispatcher.d.ts.map +1 -1
- package/dist/actions/action_dispatcher.js +22 -16
- package/dist/actions/action_event.d.ts +18 -2
- package/dist/actions/action_event.d.ts.map +1 -1
- package/dist/actions/action_event.js +63 -19
- package/dist/actions/action_event_types.d.ts +22 -0
- package/dist/actions/action_event_types.d.ts.map +1 -1
- package/dist/actions/action_event_types.js +19 -0
- package/dist/actions/compile_action_registry.d.ts +4 -2
- package/dist/actions/compile_action_registry.d.ts.map +1 -1
- package/dist/actions/compile_action_registry.js +8 -3
- package/dist/actions/frontend_rpc_client.d.ts +6 -0
- package/dist/actions/frontend_rpc_client.d.ts.map +1 -1
- package/dist/actions/frontend_rpc_client.js +2 -1
- package/dist/actions/heartbeat.d.ts +8 -4
- package/dist/actions/heartbeat.d.ts.map +1 -1
- package/dist/actions/heartbeat.js +8 -4
- package/dist/actions/peer_ping.d.ts.map +1 -1
- package/dist/actions/peer_ping.js +3 -1
- package/dist/actions/perform_action.d.ts +1 -1
- package/dist/actions/perform_action.d.ts.map +1 -1
- package/dist/actions/perform_action.js +6 -4
- package/dist/actions/register_action_ws.d.ts +13 -0
- package/dist/actions/register_action_ws.d.ts.map +1 -1
- package/dist/actions/register_action_ws.js +23 -2
- package/dist/actions/rpc_client.d.ts +1 -1
- package/dist/actions/rpc_client.d.ts.map +1 -1
- package/dist/actions/rpc_client.js +2 -1
- package/dist/actions/socket.svelte.d.ts +53 -10
- package/dist/actions/socket.svelte.d.ts.map +1 -1
- package/dist/actions/socket.svelte.js +84 -23
- package/dist/actions/transports.d.ts +24 -0
- package/dist/actions/transports.d.ts.map +1 -1
- package/dist/actions/transports.js +30 -0
- package/dist/actions/transports_http.d.ts +11 -4
- package/dist/actions/transports_http.d.ts.map +1 -1
- package/dist/actions/transports_http.js +63 -18
- package/dist/actions/transports_ws.d.ts +28 -3
- package/dist/actions/transports_ws.d.ts.map +1 -1
- package/dist/actions/transports_ws.js +33 -4
- package/dist/actions/ws_endpoint_spec.d.ts +7 -0
- package/dist/actions/ws_endpoint_spec.d.ts.map +1 -1
- package/dist/http/CLAUDE.md +7 -3
- package/dist/http/jsonrpc_helpers.d.ts +0 -5
- package/dist/http/jsonrpc_helpers.d.ts.map +1 -1
- package/dist/http/jsonrpc_helpers.js +0 -13
- package/dist/http/schema_helpers.d.ts +56 -0
- package/dist/http/schema_helpers.d.ts.map +1 -1
- package/dist/http/schema_helpers.js +91 -0
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/app_server.js +1 -0
- package/dist/testing/CLAUDE.md +17 -12
- package/dist/testing/cross_backend/peer_ping_ws.d.ts.map +1 -1
- package/dist/testing/cross_backend/peer_ping_ws.js +18 -0
- package/dist/testing/cross_backend/ws_round_trip.d.ts +11 -3
- package/dist/testing/cross_backend/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/cross_backend/ws_round_trip.js +74 -12
- package/dist/testing/transports/ws_client.d.ts +6 -0
- package/dist/testing/transports/ws_client.d.ts.map +1 -1
- package/dist/testing/transports/ws_transport.d.ts.map +1 -1
- package/dist/testing/transports/ws_transport.js +6 -1
- package/dist/testing/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/ws_round_trip.js +5 -0
- package/dist/ui/form_state.svelte.d.ts +9 -4
- package/dist/ui/form_state.svelte.d.ts.map +1 -1
- package/dist/ui/form_state.svelte.js +28 -8
- package/package.json +2 -2
- package/dist/actions/request_tracker.svelte.d.ts +0 -77
- package/dist/actions/request_tracker.svelte.d.ts.map +0 -1
- package/dist/actions/request_tracker.svelte.js +0 -169
package/dist/http/CLAUDE.md
CHANGED
|
@@ -17,7 +17,7 @@ effects, see ../../../docs/architecture.md.
|
|
|
17
17
|
- `http/route_spec.ts` — `RouteSpec` + `apply_route_specs`, validation pipeline, transactions.
|
|
18
18
|
- `http/auth_shape.ts` — canonical `RouteAuth` Zod schema + cross-axis invariants + predicates.
|
|
19
19
|
- `http/error_schemas.ts` — `ERROR_*` constants, standard error shapes, `derive_error_schemas`.
|
|
20
|
-
- `http/schema_helpers.ts` — shared Zod introspection (null/strict/surface/merge/middleware-applies)
|
|
20
|
+
- `http/schema_helpers.ts` — shared Zod introspection (null/void/strict/surface/merge/middleware-applies) + `to_void_params` / `to_input_params` / `safe_parse_dropping_unknown_keys`.
|
|
21
21
|
- `http/middleware_spec.ts` — `MiddlewareSpec` interface.
|
|
22
22
|
- `http/surface.ts` — `AppSurface`, `AppSurfaceSpec`, `generate_app_surface`, diagnostics.
|
|
23
23
|
- `http/surface_query.ts` — pure filters/groupings over `AppSurface`.
|
|
@@ -220,7 +220,7 @@ confirmation.
|
|
|
220
220
|
— extracted to break a circular dependency between `http/route_spec.ts`
|
|
221
221
|
(input validation) and `http/surface.ts` (surface generation).
|
|
222
222
|
|
|
223
|
-
**Import `is_null_schema`, `is_strict_object_schema`, `schema_to_surface`,
|
|
223
|
+
**Import `is_null_schema`, `is_void_schema`, `to_void_params`, `to_input_params`, `is_strict_object_schema`, `schema_to_surface`,
|
|
224
224
|
`middleware_applies`, and `merge_error_schemas` from `http/schema_helpers.ts`,
|
|
225
225
|
not from `http/surface.ts`.** The helpers were moved; `http/surface.ts`
|
|
226
226
|
only imports and re-uses them for generation logic.
|
|
@@ -228,6 +228,10 @@ only imports and re-uses them for generation logic.
|
|
|
228
228
|
Key helpers:
|
|
229
229
|
|
|
230
230
|
- `is_null_schema(schema)` — `instanceof z.ZodNull` (not parse-null, to avoid false positives from `z.nullable(z.string())`)
|
|
231
|
+
- `is_void_schema(schema)` — `instanceof z.ZodVoid`; a `z.void()` input declares a parameterless RPC method
|
|
232
|
+
- `to_void_params(raw_params)` — reads absent, `null`, and `{}` params of a `z.void()` input as the no-arg call (`undefined`), passing any other shape through for `z.void()` to refuse — the twin of the Rust spine's `require_void_params`
|
|
233
|
+
- `to_input_params(input, raw_params)` — the one params normalizer every receiving end runs before `input.safeParse`: `to_void_params` for a `z.void()` input, else absent/`null` → `{}`; used by both the server dispatch core (`perform_action`) and the peer receive path (`ActionDispatcher`)
|
|
234
|
+
- `safe_parse_dropping_unknown_keys(schema, value)` — the forward-compatible read of a remote-authored payload: when every issue is an unrecognized key, strips those keys from a copy and reparses; any other issue still fails. Used for response `result`s (`ActionEvent`) and peer replies (`peer/ping`); matches serde's ignore-unknown-fields default on the Rust spine
|
|
231
235
|
- `is_strict_object_schema(schema)` — detects `z.strictObject()` by checking `schema.def.catchall instanceof z.ZodNever`
|
|
232
236
|
- `schema_to_surface(schema)` — Zod → JSON Schema, with `$schema` and `default` keys stripped recursively (defaults may be non-deterministic; `$schema` is snapshot noise)
|
|
233
237
|
- `middleware_applies(mw_path, route_path)` — Hono pattern matching: `'*'`, exact, `'/api/*'` prefix (handles `prefix.slice(0, -1)` so `/api/*` also matches the bare `/api`)
|
|
@@ -401,7 +405,7 @@ to a JSON-RPC code.
|
|
|
401
405
|
- Envelope schemas in `http/jsonrpc.ts`: `JsonrpcRequest`, `JsonrpcNotification`, `JsonrpcResponse`, `JsonrpcErrorResponse`, `JsonrpcResponseOrError`, `JsonrpcMessage`, `JsonrpcMessageFromClientToServer`, `JsonrpcMessageFromServerToClient`. Also `JsonrpcRequestId`, `JsonrpcMethod`, `JsonrpcProgressToken`, `JsonrpcMcpMeta`, `JsonrpcRequestParamsMeta`
|
|
402
406
|
- Builders in `http/jsonrpc_helpers.ts`: `create_jsonrpc_request`, `create_jsonrpc_notification`, `create_jsonrpc_response`, `create_jsonrpc_error_response`, `create_jsonrpc_error_response_from_thrown` (preserves code/message/data on `ThrownJsonrpcError`; plain `Error` → `internal_error` with `{stack}` in DEV)
|
|
403
407
|
- Type guards: `is_jsonrpc_request_id` (rejects NaN/Infinity), `is_jsonrpc_object`, `is_jsonrpc_message`, `is_jsonrpc_request` / `_notification` / `_response` / `_error_response`
|
|
404
|
-
- Converters: `to_jsonrpc_message_id`, `to_jsonrpc_params` (normalizes primitives to `{value}`)
|
|
408
|
+
- Converters: `to_jsonrpc_message_id`, `to_jsonrpc_params` (normalizes primitives to `{value}`)
|
|
405
409
|
|
|
406
410
|
Handlers can `throw jsonrpc_errors.*` — `apply_route_specs`' error-catch
|
|
407
411
|
layer converts to `{error: JsonrpcErrorObject}` at the correct HTTP status.
|
|
@@ -61,9 +61,4 @@ export declare const to_jsonrpc_envelope_id: (frame: unknown) => JsonrpcRequestI
|
|
|
61
61
|
* Returns `undefined` for null/undefined, wraps primitives in `{value}`.
|
|
62
62
|
*/
|
|
63
63
|
export declare const to_jsonrpc_params: (input: unknown) => Record<string, any> | undefined;
|
|
64
|
-
/**
|
|
65
|
-
* Normalizes output to JSON-RPC result format.
|
|
66
|
-
* Returns empty object for null/undefined, wraps primitives in `{value}`.
|
|
67
|
-
*/
|
|
68
|
-
export declare const to_jsonrpc_result: (output: unknown) => Record<string, any>;
|
|
69
64
|
//# sourceMappingURL=jsonrpc_helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonrpc_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/jsonrpc_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,EAEnB,eAAe,EACf,MAAM,cAAc,CAAC;AAKtB,0CAA0C;AAC1C,eAAO,MAAM,sBAAsB,GAClC,QAAQ,aAAa,EACrB,QAAQ,oBAAoB,GAAG,SAAS,EACxC,IAAI,gBAAgB,KAClB,cAUF,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,uBAAuB,GACnC,IAAI,gBAAgB,EACpB,QAAQ,aAAa,KACnB,eAID,CAAC;AAEH,6EAA6E;AAC7E,eAAO,MAAM,2BAA2B,GACvC,QAAQ,aAAa,EACrB,QAAQ,yBAAyB,GAAG,SAAS,KAC3C,mBASF,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,6BAA6B,GACzC,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAC9B,OAAO,oBAAoB,CAAC,OAAO,CAAC,KAClC,oBAID,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,yCAAyC,GACrD,IAAI,gBAAgB,GAAG,IAAI,EAC3B,OAAO,OAAO,KACZ,oBAyBF,CAAC;AAIF,kFAAkF;AAClF,eAAO,MAAM,qBAAqB,GAAI,IAAI,OAAO,KAAG,EAAE,IAAI,gBAGzD,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,GAC7B,SAAS,OAAO,KACd,OAAO,IAAI;IAAE,OAAO,EAAE,OAAO,eAAe,CAAA;CAIF,CAAC;AAE9C,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,GAC9B,SAAS,OAAO,KACd,OAAO,IAAI,cAAc,GAAG,KAAK,CAAC,cAAc,CAGrB,CAAC;AAE/B,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,GAAI,SAAS,OAAO,KAAG,OAAO,IAAI,cACI,CAAC;AAEtE,wEAAwE;AACxE,eAAO,MAAM,uBAAuB,GAAI,SAAS,OAAO,KAAG,OAAO,IAAI,mBACE,CAAC;AAEzE,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,GAAI,SAAS,OAAO,KAAG,OAAO,IAAI,eACG,CAAC;AAEtE,uEAAuE;AACvE,eAAO,MAAM,yBAAyB,GAAI,SAAS,OAAO,KAAG,OAAO,IAAI,oBACJ,CAAC;AAIrE;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,eAAe,OAAO,KAAG,gBAAgB,GAAG,IAOjF,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,KAAG,gBAAgB,GAAG,IACX,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAQxE,CAAC
|
|
1
|
+
{"version":3,"file":"jsonrpc_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/jsonrpc_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,cAAc,EAEnB,eAAe,EACf,MAAM,cAAc,CAAC;AAKtB,0CAA0C;AAC1C,eAAO,MAAM,sBAAsB,GAClC,QAAQ,aAAa,EACrB,QAAQ,oBAAoB,GAAG,SAAS,EACxC,IAAI,gBAAgB,KAClB,cAUF,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,uBAAuB,GACnC,IAAI,gBAAgB,EACpB,QAAQ,aAAa,KACnB,eAID,CAAC;AAEH,6EAA6E;AAC7E,eAAO,MAAM,2BAA2B,GACvC,QAAQ,aAAa,EACrB,QAAQ,yBAAyB,GAAG,SAAS,KAC3C,mBASF,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,6BAA6B,GACzC,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAC9B,OAAO,oBAAoB,CAAC,OAAO,CAAC,KAClC,oBAID,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,yCAAyC,GACrD,IAAI,gBAAgB,GAAG,IAAI,EAC3B,OAAO,OAAO,KACZ,oBAyBF,CAAC;AAIF,kFAAkF;AAClF,eAAO,MAAM,qBAAqB,GAAI,IAAI,OAAO,KAAG,EAAE,IAAI,gBAGzD,CAAC;AAEF,qEAAqE;AACrE,eAAO,MAAM,iBAAiB,GAC7B,SAAS,OAAO,KACd,OAAO,IAAI;IAAE,OAAO,EAAE,OAAO,eAAe,CAAA;CAIF,CAAC;AAE9C,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,GAC9B,SAAS,OAAO,KACd,OAAO,IAAI,cAAc,GAAG,KAAK,CAAC,cAAc,CAGrB,CAAC;AAE/B,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,GAAI,SAAS,OAAO,KAAG,OAAO,IAAI,cACI,CAAC;AAEtE,wEAAwE;AACxE,eAAO,MAAM,uBAAuB,GAAI,SAAS,OAAO,KAAG,OAAO,IAAI,mBACE,CAAC;AAEzE,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,GAAI,SAAS,OAAO,KAAG,OAAO,IAAI,eACG,CAAC;AAEtE,uEAAuE;AACvE,eAAO,MAAM,yBAAyB,GAAI,SAAS,OAAO,KAAG,OAAO,IAAI,oBACJ,CAAC;AAIrE;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAAI,eAAe,OAAO,KAAG,gBAAgB,GAAG,IAOjF,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,KAAG,gBAAgB,GAAG,IACX,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAQxE,CAAC"}
|
|
@@ -136,16 +136,3 @@ export const to_jsonrpc_params = (input) => {
|
|
|
136
136
|
}
|
|
137
137
|
return { value: input };
|
|
138
138
|
};
|
|
139
|
-
/**
|
|
140
|
-
* Normalizes output to JSON-RPC result format.
|
|
141
|
-
* Returns empty object for null/undefined, wraps primitives in `{value}`.
|
|
142
|
-
*/
|
|
143
|
-
export const to_jsonrpc_result = (output) => {
|
|
144
|
-
if (output === null || output === undefined) {
|
|
145
|
-
return {};
|
|
146
|
-
}
|
|
147
|
-
if (typeof output === 'object' && !Array.isArray(output)) {
|
|
148
|
-
return output;
|
|
149
|
-
}
|
|
150
|
-
return { value: output };
|
|
151
|
-
};
|
|
@@ -27,6 +27,62 @@ export declare const is_null_schema: (schema: z.ZodType) => boolean;
|
|
|
27
27
|
* and the dispatcher maps absent params to `undefined` for these specs.
|
|
28
28
|
*/
|
|
29
29
|
export declare const is_void_schema: (schema: z.ZodType) => boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Normalize the raw `params` of a `z.void()` input: an absent `params`, an
|
|
32
|
+
* empty object, and the `null` a GET `?params=null` parses to are all the
|
|
33
|
+
* no-arg call (`undefined`); anything else passes through for `z.void()` to
|
|
34
|
+
* refuse.
|
|
35
|
+
*
|
|
36
|
+
* JSON-RPC 2.0 lets a parameterless call omit `params`, and an empty by-name
|
|
37
|
+
* structure carries no parameters, so refusing `{}` would only break clients
|
|
38
|
+
* that send it for a parameterless call. Arrays — `[]` included — are not
|
|
39
|
+
* normalized: RPC params are by-name only. The Rust spine's
|
|
40
|
+
* `require_void_params` accepts the same shapes. Receiving ends reach it
|
|
41
|
+
* through `to_input_params`.
|
|
42
|
+
*
|
|
43
|
+
* @param raw_params - the request's `params` as parsed off the wire
|
|
44
|
+
* @returns `undefined` for an empty shape, else `raw_params` unchanged
|
|
45
|
+
*/
|
|
46
|
+
export declare const to_void_params: (raw_params: unknown) => unknown;
|
|
47
|
+
/**
|
|
48
|
+
* Normalize the raw `params` of an RPC call for `input` to validate: for a
|
|
49
|
+
* `z.void()` input, `to_void_params`; for any other input, an absent or
|
|
50
|
+
* `null` `params` reads as `{}`, so an all-optional object input accepts a
|
|
51
|
+
* call that omits them. Every receiving end — the server dispatch
|
|
52
|
+
* (`perform_action`) and a peer receiving a request or notification
|
|
53
|
+
* (`ActionDispatcher`) — reads params through this, so a peer is never
|
|
54
|
+
* stricter than the server.
|
|
55
|
+
*
|
|
56
|
+
* @param input - the action's input schema
|
|
57
|
+
* @param raw_params - the call's `params` as parsed off the wire
|
|
58
|
+
* @returns the value to run `input.safeParse` on
|
|
59
|
+
*/
|
|
60
|
+
export declare const to_input_params: (input: z.ZodType, raw_params: unknown) => unknown;
|
|
61
|
+
/**
|
|
62
|
+
* `schema.safeParse(value)`, except that keys the schema doesn't declare are
|
|
63
|
+
* dropped rather than refused — the forward-compatible read of a payload a
|
|
64
|
+
* remote authored.
|
|
65
|
+
*
|
|
66
|
+
* Output schemas are strict so the server's DEV output validation catches a
|
|
67
|
+
* handler leaking fields it shouldn't. The receiving side, though, is often
|
|
68
|
+
* older than the remote it talks to — a deploy lands before open tabs reload
|
|
69
|
+
* — and a remote that adds a field is making a compatible change. So when
|
|
70
|
+
* every issue is an unrecognized key, those keys are stripped from a copy of
|
|
71
|
+
* `value` and it's parsed again; any other issue (a wrong type, a missing
|
|
72
|
+
* field, `null` where a value is required) still fails. `value` itself is
|
|
73
|
+
* never mutated. This matches serde's default on the Rust spine, which
|
|
74
|
+
* ignores unknown fields. Keys nested in a `z.union` branch surface as a
|
|
75
|
+
* union issue and aren't stripped; a `z.discriminatedUnion` reports its
|
|
76
|
+
* matched branch's issues directly, so those are.
|
|
77
|
+
*
|
|
78
|
+
* Used for a response's `result` (`ActionEvent`) and for a peer's reply to a
|
|
79
|
+
* server-initiated request (`peer/ping`).
|
|
80
|
+
*
|
|
81
|
+
* @param schema - the declared shape
|
|
82
|
+
* @param value - the remote-authored payload
|
|
83
|
+
* @returns the parse result, with undeclared keys dropped on success
|
|
84
|
+
*/
|
|
85
|
+
export declare const safe_parse_dropping_unknown_keys: <T extends z.ZodType>(schema: T, value: unknown) => z.ZodSafeParseResult<z.output<T>>;
|
|
30
86
|
/**
|
|
31
87
|
* Check if a schema is a strict object (`z.strictObject()`).
|
|
32
88
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/schema_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OACe,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAQrD,CAAC;AAoBF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,KAAG,OAQxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM;IACL,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B,EACD,oBAAoB,iBAAiB,GAAG,IAAI,KAC1C,iBAAiB,GAAG,IAUtB,CAAC"}
|
|
1
|
+
{"version":3,"file":"schema_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/schema_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAEN,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,MAAM,oBAAoB,CAAC;AAE5B;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,GAAI,YAAY,OAAO,KAAG,OAUpD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,CAAC,CAAC,OAAO,EAAE,YAAY,OAAO,KAAG,OACA,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,gCAAgC,GAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EACnE,QAAQ,CAAC,EACT,OAAO,OAAO,KACZ,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAclC,CAAC;AAWF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OACe,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAQrD,CAAC;AAoBF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,KAAG,OAQxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM;IACL,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B,EACD,oBAAoB,iBAAiB,GAAG,IAAI,KAC1C,iBAAiB,GAAG,IAUtB,CAAC"}
|
|
@@ -26,6 +26,97 @@ export const is_null_schema = (schema) => schema instanceof z.ZodNull;
|
|
|
26
26
|
* and the dispatcher maps absent params to `undefined` for these specs.
|
|
27
27
|
*/
|
|
28
28
|
export const is_void_schema = (schema) => schema instanceof z.ZodVoid;
|
|
29
|
+
/**
|
|
30
|
+
* Normalize the raw `params` of a `z.void()` input: an absent `params`, an
|
|
31
|
+
* empty object, and the `null` a GET `?params=null` parses to are all the
|
|
32
|
+
* no-arg call (`undefined`); anything else passes through for `z.void()` to
|
|
33
|
+
* refuse.
|
|
34
|
+
*
|
|
35
|
+
* JSON-RPC 2.0 lets a parameterless call omit `params`, and an empty by-name
|
|
36
|
+
* structure carries no parameters, so refusing `{}` would only break clients
|
|
37
|
+
* that send it for a parameterless call. Arrays — `[]` included — are not
|
|
38
|
+
* normalized: RPC params are by-name only. The Rust spine's
|
|
39
|
+
* `require_void_params` accepts the same shapes. Receiving ends reach it
|
|
40
|
+
* through `to_input_params`.
|
|
41
|
+
*
|
|
42
|
+
* @param raw_params - the request's `params` as parsed off the wire
|
|
43
|
+
* @returns `undefined` for an empty shape, else `raw_params` unchanged
|
|
44
|
+
*/
|
|
45
|
+
export const to_void_params = (raw_params) => {
|
|
46
|
+
if (raw_params === undefined || raw_params === null)
|
|
47
|
+
return undefined;
|
|
48
|
+
if (typeof raw_params === 'object' &&
|
|
49
|
+
!Array.isArray(raw_params) &&
|
|
50
|
+
Object.keys(raw_params).length === 0) {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
return raw_params;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Normalize the raw `params` of an RPC call for `input` to validate: for a
|
|
57
|
+
* `z.void()` input, `to_void_params`; for any other input, an absent or
|
|
58
|
+
* `null` `params` reads as `{}`, so an all-optional object input accepts a
|
|
59
|
+
* call that omits them. Every receiving end — the server dispatch
|
|
60
|
+
* (`perform_action`) and a peer receiving a request or notification
|
|
61
|
+
* (`ActionDispatcher`) — reads params through this, so a peer is never
|
|
62
|
+
* stricter than the server.
|
|
63
|
+
*
|
|
64
|
+
* @param input - the action's input schema
|
|
65
|
+
* @param raw_params - the call's `params` as parsed off the wire
|
|
66
|
+
* @returns the value to run `input.safeParse` on
|
|
67
|
+
*/
|
|
68
|
+
export const to_input_params = (input, raw_params) => is_void_schema(input) ? to_void_params(raw_params) : (raw_params ?? {});
|
|
69
|
+
/**
|
|
70
|
+
* `schema.safeParse(value)`, except that keys the schema doesn't declare are
|
|
71
|
+
* dropped rather than refused — the forward-compatible read of a payload a
|
|
72
|
+
* remote authored.
|
|
73
|
+
*
|
|
74
|
+
* Output schemas are strict so the server's DEV output validation catches a
|
|
75
|
+
* handler leaking fields it shouldn't. The receiving side, though, is often
|
|
76
|
+
* older than the remote it talks to — a deploy lands before open tabs reload
|
|
77
|
+
* — and a remote that adds a field is making a compatible change. So when
|
|
78
|
+
* every issue is an unrecognized key, those keys are stripped from a copy of
|
|
79
|
+
* `value` and it's parsed again; any other issue (a wrong type, a missing
|
|
80
|
+
* field, `null` where a value is required) still fails. `value` itself is
|
|
81
|
+
* never mutated. This matches serde's default on the Rust spine, which
|
|
82
|
+
* ignores unknown fields. Keys nested in a `z.union` branch surface as a
|
|
83
|
+
* union issue and aren't stripped; a `z.discriminatedUnion` reports its
|
|
84
|
+
* matched branch's issues directly, so those are.
|
|
85
|
+
*
|
|
86
|
+
* Used for a response's `result` (`ActionEvent`) and for a peer's reply to a
|
|
87
|
+
* server-initiated request (`peer/ping`).
|
|
88
|
+
*
|
|
89
|
+
* @param schema - the declared shape
|
|
90
|
+
* @param value - the remote-authored payload
|
|
91
|
+
* @returns the parse result, with undeclared keys dropped on success
|
|
92
|
+
*/
|
|
93
|
+
export const safe_parse_dropping_unknown_keys = (schema, value) => {
|
|
94
|
+
const parsed = schema.safeParse(value);
|
|
95
|
+
if (parsed.success)
|
|
96
|
+
return parsed;
|
|
97
|
+
const { issues } = parsed.error;
|
|
98
|
+
if (!issues.every((issue) => issue.code === 'unrecognized_keys'))
|
|
99
|
+
return parsed;
|
|
100
|
+
const stripped = structuredClone(value);
|
|
101
|
+
for (const issue of issues) {
|
|
102
|
+
const target = get_at_path(stripped, issue.path);
|
|
103
|
+
if (typeof target !== 'object' || target === null)
|
|
104
|
+
return parsed;
|
|
105
|
+
for (const key of issue.keys) {
|
|
106
|
+
Reflect.deleteProperty(target, key);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return schema.safeParse(stripped);
|
|
110
|
+
};
|
|
111
|
+
const get_at_path = (value, path) => {
|
|
112
|
+
let current = value;
|
|
113
|
+
for (const segment of path) {
|
|
114
|
+
if (typeof current !== 'object' || current === null)
|
|
115
|
+
return undefined;
|
|
116
|
+
current = current[segment];
|
|
117
|
+
}
|
|
118
|
+
return current;
|
|
119
|
+
};
|
|
29
120
|
/**
|
|
30
121
|
* Check if a schema is a strict object (`z.strictObject()`).
|
|
31
122
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_server.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"app_server.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,EAAE,KAAK,OAAO,EAAE,MAAM,MAAM,CAAC;AAG1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAEN,KAAK,cAAc,EAEnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAGN,KAAK,WAAW,EAChB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAKN,KAAK,WAAW,EAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,oBAAoB,CAAC;AAE5B,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEhF,OAAO,EAEN,KAAK,cAAc,EAEnB,KAAK,eAAe,EACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAGN,KAAK,eAAe,EACpB,MAAM,6BAA6B,CAAC;AASrC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAKrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,sBAAsB,GACjC,wBAAwB,GAAG,2BAA2B,GAAG,oBAAoB,CAAC;AAE/E,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,UAAU,CAAC;CACjB;AAED,MAAM,WAAW,2BAA2B;IAC3C,IAAI,EAAE,cAAc,CAAC;IACrB,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAChC,2DAA2D;IAC3D,OAAO,EAAE,UAAU,CAAC;IACpB,6CAA6C;IAC7C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,sCAAsC;IACtC,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAE/B,6BAA6B;IAC7B,KAAK,EAAE;QACN,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC/B,iBAAiB,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,GAAG,SAAS,CAAC;KACtD,CAAC;IAEF;;;;;;;;;;;;OAYG;IACH,qBAAqB,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3C;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5C;;;;;;OAMG;IACH,yBAAyB,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC/C;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAChD;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjD;;;;;;;;OAQG;IACH,sBAAsB,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5C;;;;;;;;OAQG;IACH,2BAA2B,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IACjD;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,2DAA2D;IAC3D,kBAAkB,CAAC,EAAE,gBAAgB,CAAC;IAEtC,yEAAyE;IACzE,SAAS,CAAC,EAAE,sBAAsB,CAAC;IAEnC;;;OAGG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC;IAEtB;;;OAGG;IACH,kBAAkB,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAEpE,4DAA4D;IAC5D,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,cAAc,CAAC,KAAK,KAAK,CAAC,cAAc,CAAC,CAAC;IAE/E;;;;;;;;;;;;;;OAcG;IACH,aAAa,CAAC,EAAE,IAAI,GAAG;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAEzC,gFAAgF;IAChF,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAE/B;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;IAEjG;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAEpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,YAAY,CAAC,EACZ,aAAa,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC;IAEhG;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IAEzB,mFAAmF;IACnF,qBAAqB,CAAC,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IAE9C,6DAA6D;IAC7D,cAAc,CAAC,EAAE;QAChB,YAAY,EAAE,kBAAkB,CAAC;QACjC,4DAA4D;QAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,gEAAgE;QAChE,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB;;;;WAIG;QACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;KACzC,CAAC;IAEF;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAExE,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAED,uCAAuC;AACvC,MAAM,WAAW,SAAS;IACzB,GAAG,EAAE,IAAI,CAAC;IACV,wEAAwE;IACxE,YAAY,EAAE,cAAc,CAAC;IAC7B,gBAAgB,EAAE,eAAe,CAAC;IAClC,oGAAoG;IACpG,iBAAiB,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAClD;;;;OAIG;IACH,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B;;;;;;;;;;;OAWG;IACH,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAClE,mEAAmE;IACnE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ;IAAE,SAAS,EAAE,WAAW,GAAG,IAAI,CAAA;CAAE,KAAG,WAO7E,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,qBAAqB,QAAc,CAAC;AAEjD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,GAAU,SAAS,gBAAgB,KAAG,OAAO,CAAC,SAAS,CAqYpF,CAAC"}
|
|
@@ -375,6 +375,7 @@ export const create_app_server = async (options) => {
|
|
|
375
375
|
transport: endpoint_transport,
|
|
376
376
|
heartbeat: endpoint.heartbeat,
|
|
377
377
|
artificial_delay: endpoint.artificial_delay,
|
|
378
|
+
max_message_bytes: endpoint.max_message_bytes,
|
|
378
379
|
on_socket_open: endpoint.on_socket_open,
|
|
379
380
|
on_socket_close: endpoint.on_socket_close,
|
|
380
381
|
log,
|
package/dist/testing/CLAUDE.md
CHANGED
|
@@ -544,16 +544,17 @@ Three layers:
|
|
|
544
544
|
3. **Round-trip helpers** — predicates + wire-frame types live in `transports/ws_client.ts` (shared with the cross-process `ws_transport.ts` impl): `is_notification(method)`, `is_notification_with<P>(method, match)` (type-guard combinator — narrows `wait_for` return type), `is_response_for(id)`, `JsonrpcNotificationFrame<P>` / `JsonrpcSuccessResponseFrame<R>` / `JsonrpcErrorResponseFrame<D>` (typed wire-frame shapes distinct from the runtime Zod schemas in `http/jsonrpc.ts` — generic over `params` / `result` / `data` so tests narrow without casts). `build_broadcast_api<TApi>({harness, specs})` (in `ws_round_trip.ts`) wires a typed broadcast API against the harness transport.
|
|
545
545
|
|
|
546
546
|
`WsClient` (in `transports/ws_client.ts`):
|
|
547
|
-
`{send, request<R>, close, messages, wait_for, wait_for_close}`.
|
|
548
|
-
harness's `connect()` returns this shape; the cross-process
|
|
547
|
+
`{send, request<R>, close, messages, wait_for, wait_for_close, close_code}`.
|
|
548
|
+
The harness's `connect()` returns this shape; the cross-process
|
|
549
549
|
`create_ws_transport` in `transports/ws_transport.ts` implements the same
|
|
550
550
|
interface so assertion helpers and suite bodies work against either impl.
|
|
551
551
|
`wait_for_close(timeout_ms?)` resolves `true` if the server closes the
|
|
552
552
|
socket within the timeout, `false` on timeout (and `true` immediately when
|
|
553
553
|
already closed) — the signal for server-initiated close (e.g. an auth-guard
|
|
554
554
|
revocation), distinct from client-initiated `close()`. Mirrors the SSE frame
|
|
555
|
-
reader's `wait_for_close`. `
|
|
556
|
-
|
|
555
|
+
reader's `wait_for_close`. `close_code` is the connection's close code once
|
|
556
|
+
closed (`1006` for a drop without a close frame), `null` while open.
|
|
557
|
+
`request` throws with code + message + data on error frames (so asserting `result.foo` on a
|
|
557
558
|
failed request surfaces the real cause, not a `Cannot read property 'foo'
|
|
558
559
|
of undefined`). `wait_for(predicate, timeout_ms?)` checks already-received
|
|
559
560
|
messages first, then waits for new arrivals (default 1000ms); drops the
|
|
@@ -1079,10 +1080,13 @@ call (not folded into `describe_standard_cross_process_tests`) because it
|
|
|
1079
1080
|
needs raw `base_url` / `ws_path` the standard bundle doesn't carry, mirroring
|
|
1080
1081
|
how `describe_ws_round_trip_tests` sits beside `describe_standard_tests`
|
|
1081
1082
|
in-process. `describe_cross_process_ws_tests({setup_test, capabilities,
|
|
1082
|
-
base_url, ws_path, origin?, rpc_path?})` opens a live
|
|
1083
|
-
`create_ws_transport` (the `ws` npm package) and asserts
|
|
1084
|
-
against the upgrade stack `register_ws_endpoint` wires (origin →
|
|
1083
|
+
base_url, ws_path, origin?, rpc_path?, max_message_bytes?})` opens a live
|
|
1084
|
+
`WebSocket` via `create_ws_transport` (the `ws` npm package) and asserts
|
|
1085
|
+
cases against the upgrade stack `register_ws_endpoint` wires (origin →
|
|
1085
1086
|
`require_auth` → dispatch): authed upgrade round-trips `heartbeat`,
|
|
1087
|
+
`heartbeat` admits only the parameterless shapes (a declared param →
|
|
1088
|
+
`invalid_params`), a message past `max_message_bytes` (default
|
|
1089
|
+
`DEFAULT_WS_MAX_MESSAGE_BYTES`) closes with `WS_CLOSE_MESSAGE_TOO_BIG`,
|
|
1086
1090
|
anonymous upgrade refused, disallowed-origin upgrade refused, and — gated on
|
|
1087
1091
|
`rpc_path` — a live socket drops when the account's sessions are revoked
|
|
1088
1092
|
mid-connection (`account_session_revoke_all` over the keeper session channel
|
|
@@ -1144,11 +1148,12 @@ drives the whole round-trip and every outcome (success / `Timeout` / wrong-shape
|
|
|
1144
1148
|
`on_request` responder **at construction** (the `create_ws_transport` seam) so
|
|
1145
1149
|
the inbound server-initiated request is answered as soon as it arrives; the
|
|
1146
1150
|
security negatives use the raw `WsClient.send` to inject unsolicited /
|
|
1147
|
-
cross-connection frames.
|
|
1151
|
+
cross-connection frames. Cases: the positive round-trip plus
|
|
1148
1152
|
unsolicited-response rejection, per-connection id isolation, never-reply
|
|
1149
|
-
`Timeout`, wrong-shape rejection,
|
|
1150
|
-
|
|
1151
|
-
|
|
1153
|
+
`Timeout`, wrong-shape rejection, an undeclared reply key accepted and dropped
|
|
1154
|
+
(both spines read the reply forward-compatibly), client-error forwarding, and
|
|
1155
|
+
the HTTP no-transport path. Gated on `capabilities.peer_request` — `true` on
|
|
1156
|
+
both the Rust spine and the TS spine (the `BackendWebsocketTransport.request_connection`
|
|
1152
1157
|
path + `register_action_ws` response correlation); `peer/ping` is a protocol
|
|
1153
1158
|
action (manifest-excluded), so parity is behavioral here, not via the manifest
|
|
1154
1159
|
gate. Cross-process only; fuz_app's own wiring is
|
|
@@ -1284,7 +1289,7 @@ are `src/test/auth/cell_crud_parity.db.test.ts`
|
|
|
1284
1289
|
transport carries the keeper session cookie in its jar after this call
|
|
1285
1290
|
resolves.
|
|
1286
1291
|
- `testing/transports/ws_client.ts` — shared `WsClient` interface (`send` /
|
|
1287
|
-
`request` / `close` / `messages` / `wait_for` / `wait_for_close`),
|
|
1292
|
+
`request` / `close` / `messages` / `wait_for` / `wait_for_close` / `close_code`),
|
|
1288
1293
|
wire-frame types, and
|
|
1289
1294
|
predicates (`is_notification`, `is_response_for`, ...). Both in-process
|
|
1290
1295
|
(`ws_round_trip.ts`) and cross-process (`ws_transport.ts`) impls satisfy
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"peer_ping_ws.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/peer_ping_ws.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAkD9B,OAAO,EAAE,KAAK,mBAAmB,EAAW,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAuB5C,6DAA6D;AAC7D,MAAM,WAAW,qBAAqB;IACrC,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,iFAAiF;IACjF,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,GAAI,SAAS,qBAAqB,KAAG,
|
|
1
|
+
{"version":3,"file":"peer_ping_ws.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/peer_ping_ws.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAkD9B,OAAO,EAAE,KAAK,mBAAmB,EAAW,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAuB5C,6DAA6D;AAC7D,MAAM,WAAW,qBAAqB;IACrC,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,iFAAiF;IACjF,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,GAAI,SAAS,qBAAqB,KAAG,IA8O5E,CAAC"}
|
|
@@ -136,6 +136,24 @@ export const describe_peer_ping_ws_tests = (options) => {
|
|
|
136
136
|
await ws.close();
|
|
137
137
|
}
|
|
138
138
|
});
|
|
139
|
+
// A newer client may add reply fields: both spines read the reply
|
|
140
|
+
// forward-compatibly (serde's default / `safe_parse_dropping_unknown_keys`)
|
|
141
|
+
// and return only the declared shape.
|
|
142
|
+
test_if(capabilities.peer_request, 'a reply with an undeclared key is accepted and the key is dropped', async () => {
|
|
143
|
+
const fixture = await setup_test();
|
|
144
|
+
const ws = await open_ws(fixture.create_session_headers().cookie, (req) => {
|
|
145
|
+
const nonce = req.params?.nonce ?? 0;
|
|
146
|
+
return { result: { ...valid_reply(nonce), added_later: true } };
|
|
147
|
+
});
|
|
148
|
+
try {
|
|
149
|
+
const frame = await ping_raw(ws, 6, { nonce: 5, timeout_ms: 2000 });
|
|
150
|
+
assert.ok('result' in frame, `expected success, got ${JSON.stringify(frame)}`);
|
|
151
|
+
assert.deepStrictEqual(frame.result, valid_reply(5));
|
|
152
|
+
}
|
|
153
|
+
finally {
|
|
154
|
+
await ws.close();
|
|
155
|
+
}
|
|
156
|
+
});
|
|
139
157
|
test_if(capabilities.peer_request, 'a client JSON-RPC error reply surfaces as the action error (ClientError forwarded)', async () => {
|
|
140
158
|
const fixture = await setup_test();
|
|
141
159
|
const ws = await open_ws(fixture.create_session_headers().cookie, () => ({
|
|
@@ -24,11 +24,19 @@ export interface CrossProcessWsTestOptions {
|
|
|
24
24
|
* actions being mounted on the RPC endpoint.
|
|
25
25
|
*/
|
|
26
26
|
readonly rpc_path?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The backend's inbound WebSocket message cap, in bytes — the
|
|
29
|
+
* oversized-message case sends a message just past it. Defaults to
|
|
30
|
+
* `DEFAULT_WS_MAX_MESSAGE_BYTES`; pass the consumer's value when it raises
|
|
31
|
+
* the server cap.
|
|
32
|
+
*/
|
|
33
|
+
readonly max_message_bytes?: number;
|
|
27
34
|
}
|
|
28
35
|
/**
|
|
29
|
-
* Register the cross-process WS round-trip suite
|
|
30
|
-
*
|
|
31
|
-
*
|
|
36
|
+
* Register the cross-process WS round-trip suite over a real upgrade: authed
|
|
37
|
+
* `heartbeat` round-trip, `heartbeat`'s parameterless-shape contract, an
|
|
38
|
+
* oversized message closing with `WS_CLOSE_MESSAGE_TOO_BIG`, anonymous-upgrade
|
|
39
|
+
* refusal, disallowed-origin refusal, and — when `rpc_path` is supplied —
|
|
32
40
|
* session-revocation closing the live socket.
|
|
33
41
|
*/
|
|
34
42
|
export declare const describe_cross_process_ws_tests: (options: CrossProcessWsTestOptions) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/ws_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"ws_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/cross_backend/ws_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAoE9B,OAAO,EAAE,KAAK,mBAAmB,EAAW,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAK5C,iEAAiE;AACjE,MAAM,WAAW,yBAAyB;IACzC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAC;IAC3C,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oEAAoE;IACpE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,GAAI,SAAS,yBAAyB,KAAG,IAwIpF,CAAC"}
|
|
@@ -24,7 +24,13 @@ import '../assert_dev_env.js';
|
|
|
24
24
|
* upgrade time (not per message), so the negative cases assert the upgrade
|
|
25
25
|
* itself rejects rather than a per-message error frame.
|
|
26
26
|
*
|
|
27
|
-
*
|
|
27
|
+
* Two spine-parity cases follow: `heartbeat` answers the parameterless shapes
|
|
28
|
+
* (absent, `{}`) and refuses a declared param with `invalid_params`, and a
|
|
29
|
+
* message over the backend's cap (`max_message_bytes`, default
|
|
30
|
+
* `DEFAULT_WS_MAX_MESSAGE_BYTES`) closes the socket with
|
|
31
|
+
* `WS_CLOSE_MESSAGE_TOO_BIG`.
|
|
32
|
+
*
|
|
33
|
+
* A final case (gated on `rpc_path`) covers server-initiated close: an
|
|
28
34
|
* authenticated socket is dropped when the account's sessions are revoked
|
|
29
35
|
* mid-connection. Per-message dispatch never re-checks credential validity,
|
|
30
36
|
* so the live socket survives on the audit-fed `create_ws_auth_guard` seam —
|
|
@@ -43,29 +49,31 @@ import '../assert_dev_env.js';
|
|
|
43
49
|
import { assert, describe } from 'vitest';
|
|
44
50
|
import { assert_rejects } from '@fuzdev/fuz_util/testing.ts';
|
|
45
51
|
import { heartbeat_action_spec } from '../../actions/heartbeat.js';
|
|
52
|
+
import { DEFAULT_WS_MAX_MESSAGE_BYTES, WS_CLOSE_MESSAGE_TOO_BIG } from '../../actions/transports.js';
|
|
46
53
|
import { account_session_revoke_all_action_spec } from '../../auth/account_action_specs.js';
|
|
54
|
+
import { JSONRPC_ERROR_CODES } from '../../http/jsonrpc_errors.js';
|
|
55
|
+
import { is_response_for } from '../transports/ws_client.js';
|
|
47
56
|
import { create_ws_transport } from '../transports/ws_transport.js';
|
|
48
57
|
import { create_rpc_post_init } from '../rpc_helpers.js';
|
|
49
58
|
import { test_if } from './capabilities.js';
|
|
50
59
|
/** Origin guaranteed to fail the `http://localhost:*` allowlist the test backends run with. */
|
|
51
60
|
const DISALLOWED_ORIGIN = 'http://disallowed.example';
|
|
52
61
|
/**
|
|
53
|
-
* Register the cross-process WS round-trip suite
|
|
54
|
-
*
|
|
55
|
-
*
|
|
62
|
+
* Register the cross-process WS round-trip suite over a real upgrade: authed
|
|
63
|
+
* `heartbeat` round-trip, `heartbeat`'s parameterless-shape contract, an
|
|
64
|
+
* oversized message closing with `WS_CLOSE_MESSAGE_TOO_BIG`, anonymous-upgrade
|
|
65
|
+
* refusal, disallowed-origin refusal, and — when `rpc_path` is supplied —
|
|
56
66
|
* session-revocation closing the live socket.
|
|
57
67
|
*/
|
|
58
68
|
export const describe_cross_process_ws_tests = (options) => {
|
|
59
|
-
const { setup_test, capabilities, base_url, ws_path, origin, rpc_path } = options;
|
|
69
|
+
const { setup_test, capabilities, base_url, ws_path, origin, rpc_path, max_message_bytes = DEFAULT_WS_MAX_MESSAGE_BYTES } = options;
|
|
70
|
+
const open_authed = async () => {
|
|
71
|
+
const fixture = await setup_test();
|
|
72
|
+
return create_ws_transport({ base_url, ws_path, cookies: fixture.transport.cookies(), origin });
|
|
73
|
+
};
|
|
60
74
|
describe('cross-process websocket', () => {
|
|
61
75
|
test_if(capabilities.ws, 'authenticated upgrade round-trips heartbeat', async () => {
|
|
62
|
-
const
|
|
63
|
-
const client = await create_ws_transport({
|
|
64
|
-
base_url,
|
|
65
|
-
ws_path,
|
|
66
|
-
cookies: fixture.transport.cookies(),
|
|
67
|
-
origin
|
|
68
|
-
});
|
|
76
|
+
const client = await open_authed();
|
|
69
77
|
try {
|
|
70
78
|
const result = await client.request(1, heartbeat_action_spec.method, {});
|
|
71
79
|
assert.deepStrictEqual(result, {}, 'heartbeat returns an empty result over the wire');
|
|
@@ -74,6 +82,60 @@ export const describe_cross_process_ws_tests = (options) => {
|
|
|
74
82
|
await client.close();
|
|
75
83
|
}
|
|
76
84
|
});
|
|
85
|
+
// `heartbeat` is parameterless on both spines (`z.void()` /
|
|
86
|
+
// `require_void_params`): the empty shapes are the no-arg call, and a
|
|
87
|
+
// declared param is `invalid_params`, not ignored.
|
|
88
|
+
test_if(capabilities.ws, 'heartbeat admits only the parameterless shapes', async () => {
|
|
89
|
+
const client = await open_authed();
|
|
90
|
+
try {
|
|
91
|
+
const cases = [
|
|
92
|
+
[1, {}, true],
|
|
93
|
+
[2, { params: {} }, true],
|
|
94
|
+
[3, { params: { stray: 1 } }, false]
|
|
95
|
+
];
|
|
96
|
+
for (const [id, params, ok] of cases) {
|
|
97
|
+
await client.send({
|
|
98
|
+
jsonrpc: '2.0',
|
|
99
|
+
id,
|
|
100
|
+
method: heartbeat_action_spec.method,
|
|
101
|
+
...params
|
|
102
|
+
});
|
|
103
|
+
const frame = await client.wait_for(is_response_for(id));
|
|
104
|
+
const label = JSON.stringify(params);
|
|
105
|
+
if (ok) {
|
|
106
|
+
assert.ok('result' in frame, `${label}: ${JSON.stringify(frame)}`);
|
|
107
|
+
assert.deepStrictEqual(frame.result, {}, label);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
assert.ok('error' in frame, `${label}: ${JSON.stringify(frame)}`);
|
|
111
|
+
assert.strictEqual(frame.error.code, JSONRPC_ERROR_CODES.invalid_params, label);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
finally {
|
|
116
|
+
await client.close();
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
// Both spines cap an inbound message (`DEFAULT_WS_MAX_MESSAGE_BYTES` by
|
|
120
|
+
// default) and close the socket on a larger one rather than replying.
|
|
121
|
+
test_if(capabilities.ws, 'an oversized message closes the socket with WS_CLOSE_MESSAGE_TOO_BIG', async () => {
|
|
122
|
+
const client = await open_authed();
|
|
123
|
+
try {
|
|
124
|
+
await client.send({
|
|
125
|
+
jsonrpc: '2.0',
|
|
126
|
+
id: 1,
|
|
127
|
+
method: heartbeat_action_spec.method,
|
|
128
|
+
params: { pad: 'x'.repeat(max_message_bytes) }
|
|
129
|
+
});
|
|
130
|
+
const closed = await client.wait_for_close(5000);
|
|
131
|
+
assert.ok(closed, 'socket did not close within 5s of an oversized message');
|
|
132
|
+
assert.strictEqual(client.close_code, WS_CLOSE_MESSAGE_TOO_BIG);
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
// the server may reset the connection under the unread tail
|
|
136
|
+
await client.close().catch(() => { });
|
|
137
|
+
}
|
|
138
|
+
});
|
|
77
139
|
// Per-connection auth fires at upgrade time (`require_auth`), so an
|
|
78
140
|
// anonymous socket never opens — the upgrade is refused outright.
|
|
79
141
|
test_if(capabilities.ws, 'anonymous upgrade is refused', async () => {
|
|
@@ -124,6 +124,12 @@ export interface WsClient {
|
|
|
124
124
|
* in `testing/sse_round_trip.ts`.
|
|
125
125
|
*/
|
|
126
126
|
wait_for_close: (timeout_ms?: number) => Promise<boolean>;
|
|
127
|
+
/**
|
|
128
|
+
* The close code of the connection once it has closed — the server's
|
|
129
|
+
* (e.g. `WS_CLOSE_MESSAGE_TOO_BIG`), the test's own, or `1006` when the
|
|
130
|
+
* connection dropped without a close frame. `null` while open.
|
|
131
|
+
*/
|
|
132
|
+
readonly close_code: number | null;
|
|
127
133
|
/** Every message the server has sent, in arrival order. */
|
|
128
134
|
readonly messages: ReadonlyArray<unknown>;
|
|
129
135
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws_client.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/transports/ws_client.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ws_client.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/transports/ws_client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws_transport.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/transports/ws_transport.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAuB9B,OAAO,EAMN,KAAK,QAAQ,EACb,KAAK,kBAAkB,EAEvB,MAAM,gBAAgB,CAAC;AAGxB,sDAAsD;AACtD,MAAM,WAAW,kBAAkB;IAClC,gHAAgH;IAChH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,GAAU,SAAS,kBAAkB,KAAG,OAAO,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"ws_transport.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/transports/ws_transport.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;AAuB9B,OAAO,EAMN,KAAK,QAAQ,EACb,KAAK,kBAAkB,EAEvB,MAAM,gBAAgB,CAAC;AAGxB,sDAAsD;AACtD,MAAM,WAAW,kBAAkB;IAClC,gHAAgH;IAChH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,8DAA8D;IAC9D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,GAAU,SAAS,kBAAkB,KAAG,OAAO,CAAC,QAAQ,CAmJvF,CAAC"}
|
|
@@ -69,7 +69,9 @@ export const create_ws_transport = async (options) => {
|
|
|
69
69
|
socket.send(JSON.stringify(message));
|
|
70
70
|
});
|
|
71
71
|
});
|
|
72
|
-
|
|
72
|
+
let close_code = null;
|
|
73
|
+
socket.on('close', (code) => {
|
|
74
|
+
close_code = code;
|
|
73
75
|
for (const resolve of close_resolvers)
|
|
74
76
|
resolve();
|
|
75
77
|
close_resolvers = [];
|
|
@@ -140,6 +142,9 @@ export const create_ws_transport = async (options) => {
|
|
|
140
142
|
get messages() {
|
|
141
143
|
return received;
|
|
142
144
|
},
|
|
145
|
+
get close_code() {
|
|
146
|
+
return close_code;
|
|
147
|
+
},
|
|
143
148
|
send: send_impl,
|
|
144
149
|
async request(id, method, params, timeout_ms) {
|
|
145
150
|
await send_impl(create_jsonrpc_request(method, params, id));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/ws_round_trip.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ws_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/ws_round_trip.ts"],"names":[],"mappings":"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"}
|