@fuzdev/fuz_app 0.93.0 → 0.95.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/README.md +2 -2
- package/dist/actions/action_codegen.d.ts +18 -18
- package/dist/actions/action_codegen.js +30 -30
- package/dist/actions/action_event.js +1 -1
- package/dist/actions/action_event_helpers.d.ts +1 -1
- package/dist/actions/action_event_types.d.ts +1 -1
- package/dist/actions/action_rpc.d.ts +2 -2
- package/dist/actions/broadcast_api.d.ts +1 -1
- package/dist/actions/broadcast_api.js +1 -1
- package/dist/actions/perform_action.d.ts +2 -2
- package/dist/actions/register_action_ws.d.ts +2 -2
- package/dist/actions/register_action_ws.js +2 -2
- package/dist/actions/register_ws_endpoint.js +1 -1
- package/dist/actions/request_tracker.svelte.d.ts +1 -1
- package/dist/actions/request_tracker.svelte.js +1 -1
- package/dist/actions/rpc_client.d.ts +1 -1
- package/dist/actions/socket.svelte.d.ts +2 -2
- package/dist/actions/transports_ws.js +1 -1
- package/dist/actions/transports_ws_auth_guard.d.ts +1 -1
- package/dist/actions/transports_ws_backend.d.ts +1 -1
- package/dist/actions/transports_ws_backend.js +2 -2
- package/dist/auth/account_action_specs.js +1 -1
- package/dist/auth/account_schema.d.ts +1 -1
- package/dist/auth/account_schema.js +1 -1
- package/dist/auth/actor_lookup_action_specs.js +1 -1
- package/dist/auth/actor_lookup_queries.d.ts +1 -1
- package/dist/auth/actor_search_action_specs.js +1 -1
- package/dist/auth/actor_search_queries.d.ts +1 -1
- package/dist/auth/admin_action_specs.js +1 -1
- package/dist/auth/api_token.js +1 -1
- package/dist/auth/api_token_queries.d.ts +1 -1
- package/dist/auth/app_settings_schema.d.ts +1 -1
- package/dist/auth/app_settings_schema.js +1 -1
- package/dist/auth/audit_emitter.d.ts +2 -2
- package/dist/auth/audit_log_routes.d.ts +1 -1
- package/dist/auth/audit_log_schema.d.ts +1 -1
- package/dist/auth/audit_log_schema.js +2 -2
- package/dist/auth/bearer_auth.d.ts +1 -1
- package/dist/auth/bootstrap_account.d.ts +1 -1
- package/dist/auth/bootstrap_route_schema.js +1 -1
- package/dist/auth/bootstrap_routes.d.ts +1 -1
- package/dist/auth/bootstrap_routes.js +1 -1
- package/dist/auth/cell_action_specs.js +2 -2
- package/dist/auth/cell_audit_action_specs.js +1 -1
- package/dist/auth/cell_audit_metadata.js +1 -1
- package/dist/auth/cell_field_action_specs.js +1 -1
- package/dist/auth/cell_field_audit_metadata.js +1 -1
- package/dist/auth/cell_grant_action_specs.js +1 -1
- package/dist/auth/cell_grant_audit_metadata.js +1 -1
- package/dist/auth/cell_item_action_specs.d.ts +1 -1
- package/dist/auth/cell_item_action_specs.js +3 -3
- package/dist/auth/cell_item_audit_metadata.js +1 -1
- package/dist/auth/cell_relation_visibility.d.ts +1 -1
- package/dist/auth/cleanup.d.ts +1 -1
- package/dist/auth/daemon_token_middleware.d.ts +1 -1
- package/dist/auth/deps.d.ts +2 -2
- package/dist/auth/invite_schema.d.ts +1 -1
- package/dist/auth/invite_schema.js +1 -1
- package/dist/auth/request_context.d.ts +1 -1
- package/dist/auth/role_grant_offer_action_specs.js +1 -1
- package/dist/auth/role_grant_offer_notifications.d.ts +1 -1
- package/dist/auth/role_grant_offer_notifications.js +1 -1
- package/dist/auth/role_grant_offer_queries.d.ts +1 -1
- package/dist/auth/role_grant_offer_schema.d.ts +1 -1
- package/dist/auth/role_grant_offer_schema.js +1 -1
- package/dist/auth/role_grant_queries.d.ts +1 -1
- package/dist/auth/session_queries.d.ts +1 -1
- package/dist/auth/session_queries.js +1 -1
- package/dist/auth/signup_route_schema.js +1 -1
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.js +2 -2
- package/dist/cli/help.d.ts +1 -1
- package/dist/cli/help.js +1 -1
- package/dist/cli/logger.d.ts +1 -1
- package/dist/cli/logger.js +1 -1
- package/dist/db/CLAUDE.md +1 -1
- package/dist/db/cell_audit_queries.d.ts +1 -1
- package/dist/db/cell_field_queries.d.ts +1 -1
- package/dist/db/cell_grant_queries.d.ts +1 -1
- package/dist/db/cell_item_queries.d.ts +1 -1
- package/dist/db/cell_queries.d.ts +3 -3
- package/dist/db/cell_queries.js +1 -1
- package/dist/db/fact_disk_storage.d.ts +2 -2
- package/dist/db/fact_disk_storage.js +4 -4
- package/dist/db/fact_queries.d.ts +1 -1
- package/dist/db/fact_store.d.ts +3 -3
- package/dist/db/fact_store.js +2 -2
- package/dist/db/file_fact_url.d.ts +1 -1
- package/dist/db/file_fact_url.js +1 -1
- package/dist/db/migrate.js +1 -1
- package/dist/db/status.js +1 -1
- package/dist/http/auth_shape.js +2 -2
- package/dist/http/common_routes.d.ts +1 -1
- package/dist/http/db_routes.d.ts +1 -1
- package/dist/http/origin.js +1 -1
- package/dist/http/pending_effects.d.ts +1 -1
- package/dist/http/proxy.d.ts +1 -1
- package/dist/http/route_spec.d.ts +1 -1
- package/dist/rate_limiter.js +1 -1
- package/dist/realtime/sse.d.ts +1 -1
- package/dist/realtime/sse_auth_guard.d.ts +1 -1
- package/dist/runtime/deno.js +1 -1
- package/dist/server/app_backend.d.ts +1 -1
- package/dist/server/app_backend.js +1 -1
- package/dist/server/env.js +1 -1
- package/dist/server/fact_write.d.ts +2 -2
- package/dist/server/fact_write.js +1 -1
- package/dist/server/serve_fact_route.d.ts +1 -1
- package/dist/server/serve_fact_route.js +2 -2
- package/dist/server/startup.d.ts +1 -1
- package/dist/testing/CLAUDE.md +61 -9
- package/dist/testing/adversarial_input.js +1 -1
- package/dist/testing/app_server.d.ts +1 -1
- package/dist/testing/app_server.js +1 -1
- package/dist/testing/auth_apps.js +1 -1
- package/dist/testing/cross_backend/bench/bench_report.d.ts +1 -1
- package/dist/testing/cross_backend/bench/bench_report.js +2 -2
- package/dist/testing/cross_backend/bench/run_cross_impl_bench.d.ts +1 -1
- package/dist/testing/cross_backend/bench/run_cross_impl_bench.js +1 -1
- package/dist/testing/cross_backend/bootstrap_backend.d.ts +1 -1
- package/dist/testing/cross_backend/capabilities.d.ts +25 -4
- package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
- package/dist/testing/cross_backend/capabilities.js +9 -4
- package/dist/testing/cross_backend/cell_relations.js +1 -1
- package/dist/testing/cross_backend/conformance_case.d.ts +4 -0
- package/dist/testing/cross_backend/conformance_case.d.ts.map +1 -1
- package/dist/testing/cross_backend/conformance_case.js +26 -0
- package/dist/testing/cross_backend/conformance_table.d.ts +21 -0
- package/dist/testing/cross_backend/conformance_table.d.ts.map +1 -1
- package/dist/testing/cross_backend/conformance_table.js +109 -7
- package/dist/testing/cross_backend/create_cross_backend_global_setup.d.ts +1 -1
- package/dist/testing/cross_backend/create_dual_spawn_global_setup.d.ts +1 -1
- package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_backend_configs.js +7 -0
- package/dist/testing/cross_backend/default_spine_surface.d.ts +1 -1
- package/dist/testing/cross_backend/fact_serving.js +1 -1
- package/dist/testing/cross_backend/peer_ping_ws.d.ts +23 -0
- package/dist/testing/cross_backend/peer_ping_ws.d.ts.map +1 -0
- package/dist/testing/cross_backend/peer_ping_ws.js +209 -0
- package/dist/testing/cross_backend/setup.d.ts +1 -1
- package/dist/testing/cross_backend/setup.js +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.js +2 -2
- package/dist/testing/cross_backend/testing_server_core.d.ts +1 -1
- package/dist/testing/cross_backend/testing_server_core.js +1 -1
- package/dist/testing/cross_backend/ws_round_trip.js +1 -1
- package/dist/testing/db.js +4 -4
- package/dist/testing/middleware.js +1 -1
- package/dist/testing/role_grant_helpers.d.ts +1 -1
- package/dist/testing/rpc_helpers.d.ts +18 -1
- package/dist/testing/rpc_helpers.d.ts.map +1 -1
- package/dist/testing/rpc_helpers.js +24 -2
- package/dist/testing/schema_generators.d.ts +1 -1
- package/dist/testing/schema_generators.js +1 -1
- package/dist/testing/stubs.js +1 -1
- package/dist/testing/testing_rate_limiter.d.ts +1 -1
- package/dist/testing/testing_rate_limiter.js +1 -1
- package/dist/testing/transports/bootstrap.d.ts +1 -1
- package/dist/testing/transports/bootstrap.js +1 -1
- package/dist/testing/transports/ws_client.d.ts +40 -1
- package/dist/testing/transports/ws_client.d.ts.map +1 -1
- package/dist/testing/transports/ws_client.js +46 -1
- package/dist/testing/transports/ws_transport.d.ts +10 -1
- package/dist/testing/transports/ws_transport.d.ts.map +1 -1
- package/dist/testing/transports/ws_transport.js +6 -10
- package/dist/testing/ws_round_trip.d.ts +13 -3
- package/dist/testing/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/ws_round_trip.js +16 -12
- package/dist/ui/AdminSurface.svelte +1 -1
- package/dist/ui/AppShell.svelte +1 -1
- package/dist/ui/BootstrapForm.svelte +1 -1
- package/dist/ui/CLAUDE.md +1 -1
- package/dist/ui/ConfirmButton.svelte +2 -2
- package/dist/ui/ConfirmButton.svelte.d.ts +1 -1
- package/dist/ui/LoginForm.svelte +1 -1
- package/dist/ui/MenuLink.svelte +1 -1
- package/dist/ui/MenuLink.svelte.d.ts +1 -1
- package/dist/ui/PopoverButton.svelte +1 -1
- package/dist/ui/PopoverButton.svelte.d.ts +1 -1
- package/dist/ui/SignupForm.svelte +1 -1
- package/dist/ui/account_sessions_state.svelte.js +1 -1
- package/dist/ui/admin_accounts_state.svelte.d.ts +1 -1
- package/dist/ui/admin_accounts_state.svelte.js +1 -1
- package/dist/ui/admin_invites_state.svelte.d.ts +1 -1
- package/dist/ui/admin_invites_state.svelte.js +1 -1
- package/dist/ui/admin_sessions_state.svelte.d.ts +1 -1
- package/dist/ui/app_settings_state.svelte.js +1 -1
- package/dist/ui/async_slot.svelte.d.ts +2 -2
- package/dist/ui/async_slot.svelte.js +2 -2
- package/dist/ui/audit_log_state.svelte.js +1 -1
- package/dist/ui/auth_state.svelte.d.ts +1 -1
- package/dist/ui/auth_state.svelte.js +3 -3
- package/dist/ui/format_scope.js +1 -1
- package/dist/ui/popover.svelte.d.ts +1 -1
- package/dist/ui/popover.svelte.js +2 -2
- package/dist/ui/position_helpers.js +1 -1
- package/dist/ui/role_grant_offers_state.svelte.js +1 -1
- package/dist/ui/sidebar_state.svelte.js +1 -1
- package/dist/ui/table_state.svelte.d.ts +1 -1
- package/dist/ui/table_state.svelte.js +2 -2
- package/package.json +2 -2
|
@@ -90,14 +90,29 @@ export type RpcTestTransport = (url: string, init: RequestInit) => Promise<Respo
|
|
|
90
90
|
export declare const http_transport: (app: {
|
|
91
91
|
request: (input: string, init: RequestInit) => Promise<Response> | Response;
|
|
92
92
|
}) => RpcTestTransport;
|
|
93
|
-
/**
|
|
93
|
+
/**
|
|
94
|
+
* Snapshot a `Headers` object into a plain `Record` with lowercased keys
|
|
95
|
+
* (`Headers` iteration normalizes the casing already). Multiple values for one
|
|
96
|
+
* header collapse to the comma-joined form `Headers` exposes; `Set-Cookie` is
|
|
97
|
+
* the lone platform exception these call sites never assert on. Lets a
|
|
98
|
+
* response's headers travel back through `RpcCallResult` for header-level
|
|
99
|
+
* assertions (no-fingerprint, `expect.headers`).
|
|
100
|
+
*/
|
|
101
|
+
export declare const headers_to_record: (headers: Headers) => Record<string, string>;
|
|
102
|
+
/**
|
|
103
|
+
* Discriminated return from `rpc_call`. `status` is the HTTP status; `headers`
|
|
104
|
+
* is the response-headers snapshot (lowercased keys) so callers can assert
|
|
105
|
+
* header-level properties (e.g. no backend-fingerprinting headers).
|
|
106
|
+
*/
|
|
94
107
|
export type RpcCallResult = {
|
|
95
108
|
ok: true;
|
|
96
109
|
status: number;
|
|
110
|
+
headers: Record<string, string>;
|
|
97
111
|
result: unknown;
|
|
98
112
|
} | {
|
|
99
113
|
ok: false;
|
|
100
114
|
status: number;
|
|
115
|
+
headers: Record<string, string>;
|
|
101
116
|
error: {
|
|
102
117
|
code: number;
|
|
103
118
|
message: string;
|
|
@@ -172,10 +187,12 @@ export declare const rpc_call_non_browser: (args: Omit<RpcCallArgs, "suppress_de
|
|
|
172
187
|
export type RpcCallResultForSpec<TSpec extends RequestResponseActionSpec> = {
|
|
173
188
|
ok: true;
|
|
174
189
|
status: number;
|
|
190
|
+
headers: Record<string, string>;
|
|
175
191
|
result: z.infer<TSpec['output']>;
|
|
176
192
|
} | {
|
|
177
193
|
ok: false;
|
|
178
194
|
status: number;
|
|
195
|
+
headers: Record<string, string>;
|
|
179
196
|
error: {
|
|
180
197
|
code: number;
|
|
181
198
|
message: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAa7B,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,EAIN,KAAK,gBAAgB,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,EAAC,qBAAqB,EAAE,mBAAmB,EAAE,eAAe,EAAC,MAAM,oBAAoB,CAAC;AACpG,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAG9D;;;;;;;;;GASG;AACH,MAAM,MAAM,uBAAuB,GAChC,KAAK,CAAC,eAAe,CAAC,GACtB,CAAC,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,+BAA+B,GAC3C,eAAe,uBAAuB,EACtC,iBAAiB,cAAc,CAAC,MAAM,CAAC,KACrC,KAAK,CAAC,eAAe,CAuBvB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAChC,QAAQ,MAAM,EACd,SAAS,OAAO,EAChB,KAAI,MAAM,GAAG,MAAe,KAC1B,WAQF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAC9B,eAAe,MAAM,EACrB,QAAQ,MAAM,EACd,SAAS,OAAO,EAChB,KAAI,MAAM,GAAG,MAAe,KAC1B,MAMF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,GACzC,MAAM,OAAO,EACb,gBAAgB,gBAAgB,KAC9B,IAUF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B,GAAI,MAAM,OAAO,EAAE,gBAAgB,CAAC,CAAC,OAAO,KAAG,IAW1F,CAAC;AAIF;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAErF,2DAA2D;AAC3D,eAAO,MAAM,cAAc,GACzB,KAAK;IACL,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;CAC5E,KAAG,gBAEmB,CAAC;AAEzB,
|
|
1
|
+
{"version":3,"file":"rpc_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rpc_helpers.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAa7B,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,EAIN,KAAK,gBAAgB,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,2BAA2B,CAAC;AACzE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,EAAC,qBAAqB,EAAE,mBAAmB,EAAE,eAAe,EAAC,MAAM,oBAAoB,CAAC;AACpG,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,2BAA2B,CAAC;AAG9D;;;;;;;;;GASG;AACH,MAAM,MAAM,uBAAuB,GAChC,KAAK,CAAC,eAAe,CAAC,GACtB,CAAC,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,+BAA+B,GAC3C,eAAe,uBAAuB,EACtC,iBAAiB,cAAc,CAAC,MAAM,CAAC,KACrC,KAAK,CAAC,eAAe,CAuBvB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,oBAAoB,GAChC,QAAQ,MAAM,EACd,SAAS,OAAO,EAChB,KAAI,MAAM,GAAG,MAAe,KAC1B,WAQF,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAC9B,eAAe,MAAM,EACrB,QAAQ,MAAM,EACd,SAAS,OAAO,EAChB,KAAI,MAAM,GAAG,MAAe,KAC1B,MAMF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,GACzC,MAAM,OAAO,EACb,gBAAgB,gBAAgB,KAC9B,IAUF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,+BAA+B,GAAI,MAAM,OAAO,EAAE,gBAAgB,CAAC,CAAC,OAAO,KAAG,IAW1F,CAAC;AAIF;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAErF,2DAA2D;AAC3D,eAAO,MAAM,cAAc,GACzB,KAAK;IACL,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;CAC5E,KAAG,gBAEmB,CAAC;AAEzB;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAAI,SAAS,OAAO,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAMzE,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACtB;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,GAC5E;IACA,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAC,CAAC;CACtD,CAAC;AAEL;;;;GAIG;AACH,MAAM,MAAM,UAAU,GACnB;IAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAA;CAAC,GAC7E,gBAAgB,CAAC;AAEpB,gCAAgC;AAChC,MAAM,WAAW,WAAW;IAC3B,yDAAyD;IACzD,GAAG,EAAE,UAAU,CAAC;IAChB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,wCAAwC;IACxC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACtB;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAClC;AAcD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ,GAAU,MAAM,WAAW,KAAG,OAAO,CAAC,aAAa,CA4DvE,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAChC,MAAM,IAAI,CAAC,WAAW,EAAE,yBAAyB,CAAC,KAChD,OAAO,CAAC,aAAa,CAAuD,CAAC;AAEhF;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,CAAC,KAAK,SAAS,yBAAyB,IACrE;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;CAAC,GAC7F;IACA,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,KAAK,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAA;KAAC,CAAC;CACtD,CAAC;AAEL,mFAAmF;AACnF,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,yBAAyB,IAAI,IAAI,CAC7E,WAAW,EACX,QAAQ,GAAG,QAAQ,CACnB,GAAG;IACH,2GAA2G;IAC3G,IAAI,EAAE,KAAK,CAAC;IACZ,0CAA0C;IAC1C,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;CAChC,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,iBAAiB,GAAU,KAAK,SAAS,yBAAyB,EAC9E,MAAM,kBAAkB,CAAC,KAAK,CAAC,KAC7B,OAAO,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAkBrC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAU,CAAC,EACrC,MAAM,WAAW,EACjB,eAAe,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KACzB,OAAO,CAAC,CAAC,CAcX,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC3B,eAAe,aAAa,CAAC,eAAe,CAAC,EAC7C,QAAQ,MAAM,KACZ;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAC,GAAG,SAOtC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC3B,eAAe,aAAa,CAAC,qBAAqB,CAAC,EACnD,QAAQ,MAAM,KACZ;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,mBAAmB,CAAA;CAAC,GAAG,SAOrD,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,yBAAyB,GACrC,eAAe,aAAa,CAAC,eAAe,CAAC,KAC3C,MAYF,CAAC"}
|
|
@@ -126,6 +126,21 @@ export const assert_jsonrpc_success_response = (body, output_schema) => {
|
|
|
126
126
|
};
|
|
127
127
|
/** Adapt a `Hono`-style app into an `RpcTestTransport`. */
|
|
128
128
|
export const http_transport = (app) => async (url, init) => app.request(url, init);
|
|
129
|
+
/**
|
|
130
|
+
* Snapshot a `Headers` object into a plain `Record` with lowercased keys
|
|
131
|
+
* (`Headers` iteration normalizes the casing already). Multiple values for one
|
|
132
|
+
* header collapse to the comma-joined form `Headers` exposes; `Set-Cookie` is
|
|
133
|
+
* the lone platform exception these call sites never assert on. Lets a
|
|
134
|
+
* response's headers travel back through `RpcCallResult` for header-level
|
|
135
|
+
* assertions (no-fingerprint, `expect.headers`).
|
|
136
|
+
*/
|
|
137
|
+
export const headers_to_record = (headers) => {
|
|
138
|
+
const record = {};
|
|
139
|
+
headers.forEach((value, key) => {
|
|
140
|
+
record[key] = value;
|
|
141
|
+
});
|
|
142
|
+
return record;
|
|
143
|
+
};
|
|
129
144
|
/** Base default headers merged into every `rpc_call` request. */
|
|
130
145
|
const RPC_CALL_DEFAULT_HEADERS_BASE = {
|
|
131
146
|
host: 'localhost',
|
|
@@ -174,16 +189,18 @@ export const rpc_call = async (args) => {
|
|
|
174
189
|
}
|
|
175
190
|
const res = await (typeof app === 'function' ? app(url, init) : app.request(url, init));
|
|
176
191
|
const status = res.status;
|
|
192
|
+
const response_headers = headers_to_record(res.headers);
|
|
177
193
|
const body = await res.json();
|
|
178
194
|
const success = JsonrpcResponse.safeParse(body);
|
|
179
195
|
if (success.success) {
|
|
180
|
-
return { ok: true, status, result: success.data.result };
|
|
196
|
+
return { ok: true, status, headers: response_headers, result: success.data.result };
|
|
181
197
|
}
|
|
182
198
|
const error = JsonrpcErrorResponse.safeParse(body);
|
|
183
199
|
if (error.success) {
|
|
184
200
|
return {
|
|
185
201
|
ok: false,
|
|
186
202
|
status,
|
|
203
|
+
headers: response_headers,
|
|
187
204
|
error: {
|
|
188
205
|
code: error.data.error.code,
|
|
189
206
|
message: error.data.error.message,
|
|
@@ -226,7 +243,12 @@ export const rpc_call_for_spec = async (args) => {
|
|
|
226
243
|
if (!parsed.success) {
|
|
227
244
|
throw new Error(`rpc_call_for_spec(${spec.method}) result did not match spec.output: ${JSON.stringify(parsed.error.issues)}`);
|
|
228
245
|
}
|
|
229
|
-
return {
|
|
246
|
+
return {
|
|
247
|
+
ok: true,
|
|
248
|
+
status: res.status,
|
|
249
|
+
headers: res.headers,
|
|
250
|
+
result: parsed.data,
|
|
251
|
+
};
|
|
230
252
|
};
|
|
231
253
|
/**
|
|
232
254
|
* Same as `rpc_call` but parses the success `result` through the given
|
|
@@ -9,7 +9,7 @@ import './assert_dev_env.js';
|
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
11
|
import { z } from 'zod';
|
|
12
|
-
import { type ZodFieldInfo } from '@fuzdev/fuz_util/zod.
|
|
12
|
+
import { type ZodFieldInfo } from '@fuzdev/fuz_util/zod.ts';
|
|
13
13
|
/**
|
|
14
14
|
* Detect format constraints on a field by converting to JSON Schema.
|
|
15
15
|
* Returns format string (e.g. 'uuid', 'email') or null.
|
|
@@ -9,7 +9,7 @@ import './assert_dev_env.js';
|
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
11
|
import { z } from 'zod';
|
|
12
|
-
import { zod_unwrap_def, zod_get_base_type, zod_unwrap_to_object, zod_extract_fields, } from '@fuzdev/fuz_util/zod.
|
|
12
|
+
import { zod_unwrap_def, zod_get_base_type, zod_unwrap_to_object, zod_extract_fields, } from '@fuzdev/fuz_util/zod.ts';
|
|
13
13
|
import { is_null_schema } from '../http/schema_helpers.js';
|
|
14
14
|
/**
|
|
15
15
|
* Detect format constraints on a field by converting to JSON Schema.
|
package/dist/testing/stubs.js
CHANGED
|
@@ -7,7 +7,7 @@ import './assert_dev_env.js';
|
|
|
7
7
|
*
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
|
-
import { Logger } from '@fuzdev/fuz_util/log.
|
|
10
|
+
import { Logger } from '@fuzdev/fuz_util/log.ts';
|
|
11
11
|
import { ApiError, RateLimitError } from '../http/error_schemas.js';
|
|
12
12
|
import { Db } from '../db/db.js';
|
|
13
13
|
import { prefix_route_specs } from '../http/route_spec.js';
|
|
@@ -17,7 +17,7 @@ import './assert_dev_env.js';
|
|
|
17
17
|
* Usage in a test binary:
|
|
18
18
|
*
|
|
19
19
|
* ```ts
|
|
20
|
-
* import {TestingRateLimiter} from '@fuzdev/fuz_app/testing/testing_rate_limiter.
|
|
20
|
+
* import {TestingRateLimiter} from '@fuzdev/fuz_app/testing/testing_rate_limiter.ts';
|
|
21
21
|
*
|
|
22
22
|
* const limiter = new TestingRateLimiter(default_login_ip_rate_limit);
|
|
23
23
|
* await create_app_server({backend, ip_rate_limiter: limiter, ...});
|
|
@@ -17,7 +17,7 @@ import './assert_dev_env.js';
|
|
|
17
17
|
* Usage in a test binary:
|
|
18
18
|
*
|
|
19
19
|
* ```ts
|
|
20
|
-
* import {TestingRateLimiter} from '@fuzdev/fuz_app/testing/testing_rate_limiter.
|
|
20
|
+
* import {TestingRateLimiter} from '@fuzdev/fuz_app/testing/testing_rate_limiter.ts';
|
|
21
21
|
*
|
|
22
22
|
* const limiter = new TestingRateLimiter(default_login_ip_rate_limit);
|
|
23
23
|
* await create_app_server({backend, ip_rate_limiter: limiter, ...});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '../assert_dev_env.js';
|
|
2
|
-
import { Uuid } from '@fuzdev/fuz_util/id.
|
|
2
|
+
import { Uuid } from '@fuzdev/fuz_util/id.ts';
|
|
3
3
|
import type { BackendConfig } from '../cross_backend/backend_config.js';
|
|
4
4
|
import type { FetchTransport } from './fetch_transport.js';
|
|
5
5
|
/** Input for `bootstrap()`. */
|
|
@@ -19,7 +19,7 @@ import '../assert_dev_env.js';
|
|
|
19
19
|
* @module
|
|
20
20
|
*/
|
|
21
21
|
import { z } from 'zod';
|
|
22
|
-
import { Uuid } from '@fuzdev/fuz_util/id.
|
|
22
|
+
import { Uuid } from '@fuzdev/fuz_util/id.ts';
|
|
23
23
|
/**
|
|
24
24
|
* The `BootstrapOutput` envelope shape the cross-process bootstrap call
|
|
25
25
|
* cares about. Looser than the full `BootstrapOutput` Zod schema in
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '../assert_dev_env.js';
|
|
2
|
-
import { JSONRPC_VERSION } from '../../http/jsonrpc.js';
|
|
2
|
+
import { JSONRPC_VERSION, type JsonrpcRequest } from '../../http/jsonrpc.js';
|
|
3
3
|
export interface JsonrpcNotificationFrame<P = unknown> {
|
|
4
4
|
jsonrpc: typeof JSONRPC_VERSION;
|
|
5
5
|
method: string;
|
|
@@ -38,6 +38,45 @@ export declare const is_notification: (method: string) => (msg: unknown) => bool
|
|
|
38
38
|
export declare const is_notification_with: <P>(method: string, match: (params: P) => boolean) => (msg: unknown) => msg is JsonrpcNotificationFrame<P>;
|
|
39
39
|
/** Predicate matching a JSON-RPC response frame (success or error) for the given request id. */
|
|
40
40
|
export declare const is_response_for: (id: number | string) => (msg: unknown) => boolean;
|
|
41
|
+
/** A pending `wait_for` entry — predicate + its resolver. */
|
|
42
|
+
export interface WsWaiter {
|
|
43
|
+
predicate: (msg: unknown) => boolean;
|
|
44
|
+
resolve: (msg: unknown) => void;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* What a `WsRequestResponder` returns for a server-initiated
|
|
48
|
+
* request:
|
|
49
|
+
* - `{result}` → reply with a JSON-RPC success
|
|
50
|
+
* - `{error}` → reply with a JSON-RPC error envelope
|
|
51
|
+
* - `undefined` → send nothing (models a never-replying peer — exercises
|
|
52
|
+
* the server-side `Timeout`)
|
|
53
|
+
*/
|
|
54
|
+
export type WsResponderOutcome = {
|
|
55
|
+
result: unknown;
|
|
56
|
+
} | {
|
|
57
|
+
error: JsonrpcErrorResponseFrame['error'];
|
|
58
|
+
} | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Answers a **server-initiated** request (the server→client direction
|
|
61
|
+
* `ActionPeer` adds). Passed at client construction so it's attached
|
|
62
|
+
* before the upgrade completes — otherwise it races a connect-time ping.
|
|
63
|
+
* Receives the parsed request frame and returns the reply outcome (or a
|
|
64
|
+
* promise of it).
|
|
65
|
+
*/
|
|
66
|
+
export type WsRequestResponder = (request: JsonrpcRequest) => WsResponderOutcome | Promise<WsResponderOutcome>;
|
|
67
|
+
/**
|
|
68
|
+
* Deliver one parsed inbound frame to a client's receive sink — the
|
|
69
|
+
* shared parse→(respond|push)→resolve core.
|
|
70
|
+
*
|
|
71
|
+
* A server-initiated **request** (`{method, id}`) is answered by
|
|
72
|
+
* `on_request` when supplied (replying via `reply`) and is **not**
|
|
73
|
+
* surfaced as a normal message; everything else — notifications, replies
|
|
74
|
+
* to the client's own requests, and non-JSON frames — is pushed onto
|
|
75
|
+
* `received` and resolves any matching `waiters`, exactly as before. With
|
|
76
|
+
* no `on_request`, every frame (including a server-initiated request)
|
|
77
|
+
* flows to the sink unchanged, so the seam is purely additive.
|
|
78
|
+
*/
|
|
79
|
+
export declare const deliver_inbound: (parsed: unknown, received: Array<unknown>, waiters: Array<WsWaiter>, on_request: WsRequestResponder | undefined, reply: (message: unknown) => void) => void;
|
|
41
80
|
/**
|
|
42
81
|
* Default wait-for timeout shared across in-process + cross-process
|
|
43
82
|
* impls. Tunable per-call via the `timeout_ms` parameter.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws_client.d.ts","sourceRoot":"../src/lib/","sources":["../../../src/lib/testing/transports/ws_client.ts"],"names":[],"mappings":"AAAA,OAAO,sBAAsB,CAAC;
|
|
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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"}
|
|
@@ -18,7 +18,7 @@ import '../assert_dev_env.js';
|
|
|
18
18
|
*
|
|
19
19
|
* @module
|
|
20
20
|
*/
|
|
21
|
-
import { is_jsonrpc_error_response, is_jsonrpc_notification, is_jsonrpc_response, } from '../../http/jsonrpc_helpers.js';
|
|
21
|
+
import { create_jsonrpc_error_response, create_jsonrpc_response, is_jsonrpc_error_response, is_jsonrpc_notification, is_jsonrpc_request, is_jsonrpc_response, } from '../../http/jsonrpc_helpers.js';
|
|
22
22
|
import { JSONRPC_VERSION } from '../../http/jsonrpc.js';
|
|
23
23
|
// ---------------------------------------------------------------------
|
|
24
24
|
// Predicates — compose with `WsClient.wait_for` and
|
|
@@ -46,6 +46,51 @@ export const is_notification_with = (method, match) => (msg) => is_jsonrpc_notif
|
|
|
46
46
|
match(msg.params);
|
|
47
47
|
/** Predicate matching a JSON-RPC response frame (success or error) for the given request id. */
|
|
48
48
|
export const is_response_for = (id) => (msg) => (is_jsonrpc_response(msg) || is_jsonrpc_error_response(msg)) && msg.id === id;
|
|
49
|
+
/**
|
|
50
|
+
* Deliver one parsed inbound frame to a client's receive sink — the
|
|
51
|
+
* shared parse→(respond|push)→resolve core.
|
|
52
|
+
*
|
|
53
|
+
* A server-initiated **request** (`{method, id}`) is answered by
|
|
54
|
+
* `on_request` when supplied (replying via `reply`) and is **not**
|
|
55
|
+
* surfaced as a normal message; everything else — notifications, replies
|
|
56
|
+
* to the client's own requests, and non-JSON frames — is pushed onto
|
|
57
|
+
* `received` and resolves any matching `waiters`, exactly as before. With
|
|
58
|
+
* no `on_request`, every frame (including a server-initiated request)
|
|
59
|
+
* flows to the sink unchanged, so the seam is purely additive.
|
|
60
|
+
*/
|
|
61
|
+
export const deliver_inbound = (parsed, received, waiters, on_request, reply) => {
|
|
62
|
+
if (on_request && is_jsonrpc_request(parsed)) {
|
|
63
|
+
void answer_request(parsed, on_request, reply);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
received.push(parsed);
|
|
67
|
+
for (let i = waiters.length - 1; i >= 0; i--) {
|
|
68
|
+
const waiter = waiters[i];
|
|
69
|
+
if (waiter.predicate(parsed)) {
|
|
70
|
+
waiter.resolve(parsed);
|
|
71
|
+
waiters.splice(i, 1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const answer_request = async (request, on_request, reply) => {
|
|
76
|
+
let outcome;
|
|
77
|
+
try {
|
|
78
|
+
outcome = await on_request(request);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// A throwing responder models a peer that fails to answer — swallow so
|
|
82
|
+
// the test client surfaces no unhandled rejection; the server then sees
|
|
83
|
+
// a never-reply (→ `Timeout`).
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (outcome === undefined)
|
|
87
|
+
return; // swallow — never-replying peer
|
|
88
|
+
reply('error' in outcome
|
|
89
|
+
? // Test wire-frames keep `code` a plain `number` (not the branded
|
|
90
|
+
// Zod `JsonrpcServerErrorCode`), so cast at the builder boundary.
|
|
91
|
+
create_jsonrpc_error_response(request.id, outcome.error)
|
|
92
|
+
: create_jsonrpc_response(request.id, outcome.result));
|
|
93
|
+
};
|
|
49
94
|
// ---------------------------------------------------------------------
|
|
50
95
|
// WsClient — the test-driver surface every impl implements.
|
|
51
96
|
// ---------------------------------------------------------------------
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import '../assert_dev_env.js';
|
|
2
|
-
import { type WsClient } from './ws_client.js';
|
|
2
|
+
import { type WsClient, type WsRequestResponder } from './ws_client.js';
|
|
3
3
|
/** Construction options for `create_ws_transport`. */
|
|
4
4
|
export interface WsTransportOptions {
|
|
5
5
|
/** Base URL the binary is reachable at — e.g. `http://localhost:8788`. Converted to `ws://` for the upgrade. */
|
|
@@ -25,6 +25,15 @@ export interface WsTransportOptions {
|
|
|
25
25
|
* `WS_CLIENT_DEFAULT_TIMEOUT_MS` if omitted.
|
|
26
26
|
*/
|
|
27
27
|
readonly default_timeout_ms?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Optional responder for **server-initiated** requests (the
|
|
30
|
+
* server→client direction `ActionPeer` adds). Attached before the
|
|
31
|
+
* upgrade so a connect-time or on-demand `peer/ping` is answered as
|
|
32
|
+
* soon as it arrives. Omit for the default observe-only client — a
|
|
33
|
+
* server-initiated request is then surfaced as a normal message (today's
|
|
34
|
+
* behavior).
|
|
35
|
+
*/
|
|
36
|
+
readonly on_request?: WsRequestResponder;
|
|
28
37
|
}
|
|
29
38
|
/**
|
|
30
39
|
* Build a real-upgrade WS client pinned to `options.base_url` + `ws_path`.
|
|
@@ -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,
|
|
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,CA8IvF,CAAC"}
|
|
@@ -18,7 +18,7 @@ import '../assert_dev_env.js';
|
|
|
18
18
|
* @module
|
|
19
19
|
*/
|
|
20
20
|
import { WebSocket } from 'ws';
|
|
21
|
-
import { WS_CLIENT_DEFAULT_TIMEOUT_MS, is_response_for, } from './ws_client.js';
|
|
21
|
+
import { WS_CLIENT_DEFAULT_TIMEOUT_MS, deliver_inbound, is_response_for, } from './ws_client.js';
|
|
22
22
|
import { create_jsonrpc_request } from '../../http/jsonrpc_helpers.js';
|
|
23
23
|
/**
|
|
24
24
|
* Build a real-upgrade WS client pinned to `options.base_url` + `ws_path`.
|
|
@@ -34,7 +34,7 @@ import { create_jsonrpc_request } from '../../http/jsonrpc_helpers.js';
|
|
|
34
34
|
* cause rather than hanging.
|
|
35
35
|
*/
|
|
36
36
|
export const create_ws_transport = async (options) => {
|
|
37
|
-
const { base_url, ws_path, cookies, origin, default_timeout_ms } = options;
|
|
37
|
+
const { base_url, ws_path, cookies, origin, default_timeout_ms, on_request } = options;
|
|
38
38
|
const default_timeout = default_timeout_ms ?? WS_CLIENT_DEFAULT_TIMEOUT_MS;
|
|
39
39
|
const ws_url = `${base_url.replace(/^http/i, 'ws')}${ws_path}`;
|
|
40
40
|
const headers = {};
|
|
@@ -64,14 +64,10 @@ export const create_ws_transport = async (options) => {
|
|
|
64
64
|
// it still see the payload.
|
|
65
65
|
parsed = text;
|
|
66
66
|
}
|
|
67
|
-
received
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
waiter.resolve(parsed);
|
|
72
|
-
waiters.splice(i, 1);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
67
|
+
deliver_inbound(parsed, received, waiters, on_request, (message) => {
|
|
68
|
+
if (socket.readyState === WebSocket.OPEN)
|
|
69
|
+
socket.send(JSON.stringify(message));
|
|
70
|
+
});
|
|
75
71
|
});
|
|
76
72
|
socket.on('close', () => {
|
|
77
73
|
for (const resolve of close_resolvers)
|
|
@@ -39,8 +39,8 @@ import './assert_dev_env.js';
|
|
|
39
39
|
*/
|
|
40
40
|
import type { Context } from 'hono';
|
|
41
41
|
import { WSContext, type UpgradeWebSocket, type WSEvents } from 'hono/ws';
|
|
42
|
-
import { Logger } from '@fuzdev/fuz_util/log.
|
|
43
|
-
import { type Uuid } from '@fuzdev/fuz_util/id.
|
|
42
|
+
import { Logger } from '@fuzdev/fuz_util/log.ts';
|
|
43
|
+
import { type Uuid } from '@fuzdev/fuz_util/id.ts';
|
|
44
44
|
import type { ActionSpecUnion } from '../actions/action_spec.js';
|
|
45
45
|
import type { Action } from '../actions/action_types.js';
|
|
46
46
|
import type { ActionEventEnvironment } from '../actions/action_event_types.js';
|
|
@@ -48,7 +48,7 @@ import { type RegisterActionWsOptions } from '../actions/register_action_ws.js';
|
|
|
48
48
|
import { BackendWebsocketTransport } from '../actions/transports_ws_backend.js';
|
|
49
49
|
import { type RequestContext } from '../auth/request_context.js';
|
|
50
50
|
import { type CredentialType } from '../hono_context.js';
|
|
51
|
-
import { type WsClient } from './transports/ws_client.js';
|
|
51
|
+
import { type WsClient, type WsRequestResponder } from './transports/ws_client.js';
|
|
52
52
|
/**
|
|
53
53
|
* A `WSContext` paired with capture arrays. Use `sends` to assert on
|
|
54
54
|
* outgoing frames; use `closes` to assert on revocation / close.
|
|
@@ -151,6 +151,16 @@ export interface CreateWsTestHarnessOptions {
|
|
|
151
151
|
on_socket_open?: RegisterActionWsOptions['on_socket_open'];
|
|
152
152
|
/** Threaded straight through to `register_action_ws`. */
|
|
153
153
|
on_socket_close?: RegisterActionWsOptions['on_socket_close'];
|
|
154
|
+
/**
|
|
155
|
+
* Optional responder for **server-initiated** requests, applied to every
|
|
156
|
+
* `connect()`. Purely additive (and unexercised until the TS server
|
|
157
|
+
* transport gains server-initiated requests — the deferred
|
|
158
|
+
* `BackendWebsocketTransport.send()` convergence): with it set, an
|
|
159
|
+
* inbound server→client request is answered rather than surfaced as a
|
|
160
|
+
* message; without it, behavior is unchanged. Mirrors the cross-process
|
|
161
|
+
* `create_ws_transport` seam so suite bodies share one shape.
|
|
162
|
+
*/
|
|
163
|
+
on_request?: WsRequestResponder;
|
|
154
164
|
}
|
|
155
165
|
/** A harness instance — transport handle + connection factory. */
|
|
156
166
|
export interface WsTestHarness {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ws_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/ws_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAE7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,KAAK,EAAC,OAAO,EAAO,MAAM,MAAM,CAAC;AACxC,OAAO,EACN,SAAS,EAET,KAAK,gBAAgB,EAErB,KAAK,QAAQ,EACb,MAAM,SAAS,CAAC;AACjB,OAAO,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAc,KAAK,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,4BAA4B,CAAC;AAEvD,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,kCAAkC,CAAC;AAE7E,OAAO,EAAqB,KAAK,uBAAuB,EAAC,MAAM,kCAAkC,CAAC;AAElG,OAAO,EAAC,yBAAyB,EAAC,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAsB,KAAK,cAAc,EAAC,MAAM,4BAA4B,CAAC;AAEpF,OAAO,EAKN,KAAK,cAAc,EACnB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,
|
|
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,7 +1,7 @@
|
|
|
1
1
|
import './assert_dev_env.js';
|
|
2
2
|
import { WSContext, createWSMessageEvent, } from 'hono/ws';
|
|
3
|
-
import { Logger } from '@fuzdev/fuz_util/log.
|
|
4
|
-
import { create_uuid } from '@fuzdev/fuz_util/id.
|
|
3
|
+
import { Logger } from '@fuzdev/fuz_util/log.ts';
|
|
4
|
+
import { create_uuid } from '@fuzdev/fuz_util/id.ts';
|
|
5
5
|
import { ActionPeer } from '../actions/action_peer.js';
|
|
6
6
|
import { create_broadcast_api } from '../actions/broadcast_api.js';
|
|
7
7
|
import { register_action_ws } from '../actions/register_action_ws.js';
|
|
@@ -12,7 +12,7 @@ import { ROLE_KEEPER } from '../auth/role_schema.js';
|
|
|
12
12
|
import { ACCOUNT_ID_KEY, AUTH_API_TOKEN_ID_KEY, CREDENTIAL_TYPE_KEY, TEST_CONTEXT_PRESET_KEY, } from '../hono_context.js';
|
|
13
13
|
import { create_jsonrpc_request } from '../http/jsonrpc_helpers.js';
|
|
14
14
|
import { create_test_account, create_test_actor, create_test_role_grant } from './entities.js';
|
|
15
|
-
import { WS_CLIENT_DEFAULT_TIMEOUT_MS, is_response_for, } from './transports/ws_client.js';
|
|
15
|
+
import { WS_CLIENT_DEFAULT_TIMEOUT_MS, deliver_inbound, is_response_for, } from './transports/ws_client.js';
|
|
16
16
|
/**
|
|
17
17
|
* Build a real `WSContext` backed by in-memory `send`/`close` capture.
|
|
18
18
|
* Parsing of outgoing frames is left to the caller — `sends` holds the
|
|
@@ -169,7 +169,7 @@ const build_simple_request_context = (role) => ({
|
|
|
169
169
|
* `onOpen`/`onMessage`/`onClose` path against a real `WSContext`.
|
|
170
170
|
*/
|
|
171
171
|
export const create_ws_test_harness = (options) => {
|
|
172
|
-
const { actions, transport = new BackendWebsocketTransport(), heartbeat = false, log = new Logger('[ws-test]', { level: 'off' }), on_socket_open, on_socket_close, } = options;
|
|
172
|
+
const { actions, transport = new BackendWebsocketTransport(), heartbeat = false, log = new Logger('[ws-test]', { level: 'off' }), on_socket_open, on_socket_close, on_request, } = options;
|
|
173
173
|
const stub = create_stub_upgrade();
|
|
174
174
|
// Minimal Hono stub — `register_action_ws` only needs `.get(path, handler)`.
|
|
175
175
|
const stub_app = { get: () => stub_app };
|
|
@@ -211,6 +211,12 @@ export const create_ws_test_harness = (options) => {
|
|
|
211
211
|
};
|
|
212
212
|
const received = [];
|
|
213
213
|
const waiters = [];
|
|
214
|
+
// Reply path for a server-initiated request — assigned to the
|
|
215
|
+
// client→server send below once `send_impl` exists. A `let` (not a
|
|
216
|
+
// direct `send_impl` reference) keeps the `WSContext.send` closure
|
|
217
|
+
// TDZ-safe; it stays a no-op until a responder + server-initiated
|
|
218
|
+
// request are both in play (deferred for the in-process TS server).
|
|
219
|
+
let reply_to_server = () => { };
|
|
214
220
|
// Resolvers awaiting a server-initiated close — fired by the
|
|
215
221
|
// `WSContext.close` callback below so `wait_for_close` resolves
|
|
216
222
|
// whether the dispatcher (e.g. an auth-guard revocation) or the
|
|
@@ -228,14 +234,7 @@ export const create_ws_test_harness = (options) => {
|
|
|
228
234
|
if (is_closed)
|
|
229
235
|
return;
|
|
230
236
|
const parsed = typeof data === 'string' ? JSON.parse(data) : data;
|
|
231
|
-
|
|
232
|
-
for (let i = waiters.length - 1; i >= 0; i--) {
|
|
233
|
-
const waiter = waiters[i];
|
|
234
|
-
if (waiter.predicate(parsed)) {
|
|
235
|
-
waiter.resolve(parsed);
|
|
236
|
-
waiters.splice(i, 1);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
237
|
+
deliver_inbound(parsed, received, waiters, on_request, reply_to_server);
|
|
239
238
|
},
|
|
240
239
|
close: (code, reason) => {
|
|
241
240
|
if (is_closed)
|
|
@@ -302,6 +301,11 @@ export const create_ws_test_harness = (options) => {
|
|
|
302
301
|
// handler, send).
|
|
303
302
|
await events.onMessage?.(message_event, ws);
|
|
304
303
|
};
|
|
304
|
+
// A responder's reply to a server-initiated request goes back to the
|
|
305
|
+
// server over the same client→server path as any other send.
|
|
306
|
+
reply_to_server = (message) => {
|
|
307
|
+
void send_impl(message);
|
|
308
|
+
};
|
|
305
309
|
return {
|
|
306
310
|
get messages() {
|
|
307
311
|
return received;
|
package/dist/ui/AppShell.svelte
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import type {Snippet} from 'svelte';
|
|
13
13
|
import type {SvelteHTMLElements} from 'svelte/elements';
|
|
14
|
-
import {is_editable, swallow} from '@fuzdev/fuz_util/dom.
|
|
14
|
+
import {is_editable, swallow} from '@fuzdev/fuz_util/dom.ts';
|
|
15
15
|
|
|
16
16
|
import {SidebarState, sidebar_state_context} from './sidebar_state.svelte.js';
|
|
17
17
|
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import {goto} from '$app/navigation';
|
|
16
16
|
import {resolve} from '$app/paths';
|
|
17
17
|
import PendingButton from '@fuzdev/fuz_ui/PendingButton.svelte';
|
|
18
|
-
import {autofocus} from '@fuzdev/fuz_ui/autofocus.svelte.
|
|
18
|
+
import {autofocus} from '@fuzdev/fuz_ui/autofocus.svelte.ts';
|
|
19
19
|
|
|
20
20
|
import {Username} from '../primitive_schemas.js';
|
|
21
21
|
import {PASSWORD_LENGTH_MIN} from '../auth/password.js';
|
package/dist/ui/CLAUDE.md
CHANGED
|
@@ -68,7 +68,7 @@ their payload shapes are defined in `auth/role_grant_offer_notifications.ts`
|
|
|
68
68
|
### Context over props for shared deps
|
|
69
69
|
|
|
70
70
|
Auth, RPC adapters, sidebar, and role_grant offers all flow through
|
|
71
|
-
`create_context` from `@fuzdev/fuz_ui/context_helpers.
|
|
71
|
+
`create_context` from `@fuzdev/fuz_ui/context_helpers.ts`. Components
|
|
72
72
|
consume with `const x = x_context.get()` (or a `get_rpc`/`$derived`
|
|
73
73
|
pair when the value may change reactively). New shared state joins the
|
|
74
74
|
pattern rather than reintroducing prop-drilling.
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
import {DEV} from 'esm-env';
|
|
50
50
|
import type {SvelteHTMLElements} from 'svelte/elements';
|
|
51
51
|
import type {ComponentProps, Snippet} from 'svelte';
|
|
52
|
-
import type {OmitStrict} from '@fuzdev/fuz_util/types.
|
|
53
|
-
import {icon_remove} from '@fuzdev/fuz_ui/icons.
|
|
52
|
+
import type {OmitStrict} from '@fuzdev/fuz_util/types.ts';
|
|
53
|
+
import {icon_remove} from '@fuzdev/fuz_ui/icons.ts';
|
|
54
54
|
import PendingAnimation from '@fuzdev/fuz_ui/PendingAnimation.svelte';
|
|
55
55
|
import Svg from '@fuzdev/fuz_ui/Svg.svelte';
|
|
56
56
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SvelteHTMLElements } from 'svelte/elements';
|
|
2
2
|
import type { ComponentProps, Snippet } from 'svelte';
|
|
3
|
-
import type { OmitStrict } from '@fuzdev/fuz_util/types.
|
|
3
|
+
import type { OmitStrict } from '@fuzdev/fuz_util/types.ts';
|
|
4
4
|
import PopoverButton from './PopoverButton.svelte';
|
|
5
5
|
import type { Popover } from './popover.svelte.js';
|
|
6
6
|
type $$ComponentProps = OmitStrict<ComponentProps<typeof PopoverButton>, 'popover_content' | 'children'> & OmitStrict<SvelteHTMLElements['button'], 'children'> & {
|
package/dist/ui/LoginForm.svelte
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import {goto} from '$app/navigation';
|
|
12
12
|
import {resolve} from '$app/paths';
|
|
13
13
|
import PendingButton from '@fuzdev/fuz_ui/PendingButton.svelte';
|
|
14
|
-
import {autofocus} from '@fuzdev/fuz_ui/autofocus.svelte.
|
|
14
|
+
import {autofocus} from '@fuzdev/fuz_ui/autofocus.svelte.ts';
|
|
15
15
|
|
|
16
16
|
import {auth_state_context} from './auth_state.svelte.js';
|
|
17
17
|
import {FormState} from './form_state.svelte.js';
|
package/dist/ui/MenuLink.svelte
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
import type {SvelteHTMLElements} from 'svelte/elements';
|
|
23
23
|
import {page} from '$app/state';
|
|
24
24
|
import {resolve} from '$app/paths';
|
|
25
|
-
import type {OmitStrict} from '@fuzdev/fuz_util/types.
|
|
25
|
+
import type {OmitStrict} from '@fuzdev/fuz_util/types.ts';
|
|
26
26
|
|
|
27
27
|
const {
|
|
28
28
|
path,
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import type { Snippet } from 'svelte';
|
|
20
20
|
import type { SvelteHTMLElements } from 'svelte/elements';
|
|
21
|
-
import type { OmitStrict } from '@fuzdev/fuz_util/types.
|
|
21
|
+
import type { OmitStrict } from '@fuzdev/fuz_util/types.ts';
|
|
22
22
|
type $$ComponentProps = OmitStrict<SvelteHTMLElements['a'], 'href' | 'children'> & {
|
|
23
23
|
/** Route path passed to `resolve` from `$app/paths` to compute `href`. */
|
|
24
24
|
path: string;
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
import type {SvelteHTMLElements} from 'svelte/elements';
|
|
47
47
|
import type {Snippet} from 'svelte';
|
|
48
48
|
import {scale} from 'svelte/transition';
|
|
49
|
-
import type {OmitStrict} from '@fuzdev/fuz_util/types.
|
|
49
|
+
import type {OmitStrict} from '@fuzdev/fuz_util/types.ts';
|
|
50
50
|
|
|
51
51
|
import {Popover} from './popover.svelte.js';
|
|
52
52
|
import type {Position, Alignment} from './position_helpers.js';
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
*/
|
|
44
44
|
import type { SvelteHTMLElements } from 'svelte/elements';
|
|
45
45
|
import type { Snippet } from 'svelte';
|
|
46
|
-
import type { OmitStrict } from '@fuzdev/fuz_util/types.
|
|
46
|
+
import type { OmitStrict } from '@fuzdev/fuz_util/types.ts';
|
|
47
47
|
import { Popover } from './popover.svelte.js';
|
|
48
48
|
import type { Position, Alignment } from './position_helpers.js';
|
|
49
49
|
type $$ComponentProps = OmitStrict<SvelteHTMLElements['button'], 'children'> & {
|