@fuzdev/fuz_app 0.97.0 → 0.98.1
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 +57 -23
- package/dist/actions/action_bridge.d.ts.map +1 -1
- package/dist/actions/action_codegen.d.ts +17 -1
- package/dist/actions/action_codegen.d.ts.map +1 -1
- package/dist/actions/action_codegen.js +38 -14
- package/dist/actions/{action_peer.d.ts → action_dispatcher.d.ts} +12 -12
- package/dist/actions/action_dispatcher.d.ts.map +1 -0
- package/dist/actions/{action_peer.js → action_dispatcher.js} +2 -2
- package/dist/actions/action_event.d.ts.map +1 -1
- package/dist/actions/action_rpc.d.ts +9 -0
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/broadcast_api.d.ts +2 -2
- package/dist/actions/broadcast_api.d.ts.map +1 -1
- package/dist/actions/compile_action_registry.d.ts.map +1 -1
- package/dist/actions/frontend_rpc_client.d.ts +3 -3
- package/dist/actions/frontend_rpc_client.d.ts.map +1 -1
- package/dist/actions/frontend_rpc_client.js +3 -3
- package/dist/actions/peer_ping.d.ts +147 -0
- package/dist/actions/peer_ping.d.ts.map +1 -0
- package/dist/actions/peer_ping.js +189 -0
- package/dist/actions/peer_request.d.ts +158 -0
- package/dist/actions/peer_request.d.ts.map +1 -0
- package/dist/actions/peer_request.js +167 -0
- package/dist/actions/perform_action.d.ts +8 -0
- package/dist/actions/perform_action.d.ts.map +1 -1
- package/dist/actions/perform_action.js +2 -1
- package/dist/actions/protocol.d.ts +3 -3
- package/dist/actions/protocol.d.ts.map +1 -1
- package/dist/actions/protocol.js +9 -4
- package/dist/actions/register_action_ws.d.ts.map +1 -1
- package/dist/actions/register_action_ws.js +28 -1
- package/dist/actions/rpc_client.d.ts +4 -4
- package/dist/actions/rpc_client.d.ts.map +1 -1
- package/dist/actions/socket.svelte.d.ts.map +1 -1
- package/dist/actions/transports.d.ts +1 -1
- package/dist/actions/transports_http.d.ts.map +1 -1
- package/dist/actions/transports_ws.d.ts +12 -5
- package/dist/actions/transports_ws.d.ts.map +1 -1
- package/dist/actions/transports_ws.js +36 -6
- package/dist/actions/transports_ws_backend.d.ts +34 -1
- package/dist/actions/transports_ws_backend.d.ts.map +1 -1
- package/dist/actions/transports_ws_backend.js +62 -5
- package/dist/auth/CLAUDE.md +12 -12
- package/dist/auth/actor_lookup_action_specs.d.ts.map +1 -1
- package/dist/auth/actor_search_action_specs.d.ts.map +1 -1
- package/dist/auth/admin_action_specs.d.ts.map +1 -1
- package/dist/auth/admin_actions.d.ts.map +1 -1
- package/dist/auth/audit_log_queries.d.ts.map +1 -1
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/bootstrap_routes.d.ts.map +1 -1
- package/dist/auth/role_grant_queries.d.ts +31 -12
- package/dist/auth/role_grant_queries.d.ts.map +1 -1
- package/dist/auth/role_grant_queries.js +36 -12
- package/dist/auth/role_schema.d.ts.map +1 -1
- package/dist/auth/self_service_role_actions.d.ts.map +1 -1
- package/dist/db/create_db.d.ts.map +1 -1
- package/dist/db/fact_store.d.ts.map +1 -1
- package/dist/db/status.d.ts.map +1 -1
- package/dist/http/auth_shape.d.ts.map +1 -1
- package/dist/http/db_routes.d.ts.map +1 -1
- package/dist/http/jsonrpc_helpers.d.ts +1 -1
- package/dist/http/jsonrpc_helpers.js +1 -1
- package/dist/rate_limiter.d.ts.map +1 -1
- package/dist/rate_limiter.js +11 -0
- package/dist/server/app_backend.d.ts.map +1 -1
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/serve_fact_route.d.ts.map +1 -1
- package/dist/server/serve_fact_route.js +7 -4
- package/dist/testing/CLAUDE.md +18 -15
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/adversarial_input.d.ts.map +1 -1
- package/dist/testing/adversarial_input.js +3 -1
- package/dist/testing/attack_surface.d.ts.map +1 -1
- package/dist/testing/audit_completeness.d.ts.map +1 -1
- package/dist/testing/cross_backend/action_manifest.d.ts +7 -7
- package/dist/testing/cross_backend/action_manifest.js +7 -7
- package/dist/testing/cross_backend/action_manifest_parity.d.ts.map +1 -1
- package/dist/testing/cross_backend/capabilities.d.ts +15 -12
- package/dist/testing/cross_backend/capabilities.d.ts.map +1 -1
- package/dist/testing/cross_backend/capabilities.js +4 -4
- package/dist/testing/cross_backend/cell_cross_helpers.d.ts.map +1 -1
- package/dist/testing/cross_backend/conformance_case.d.ts +2 -0
- package/dist/testing/cross_backend/conformance_case.d.ts.map +1 -1
- package/dist/testing/cross_backend/conformance_case.js +13 -0
- package/dist/testing/cross_backend/conformance_table.d.ts.map +1 -1
- package/dist/testing/cross_backend/conformance_table.js +32 -3
- package/dist/testing/cross_backend/cookie_attributes.d.ts +20 -0
- package/dist/testing/cross_backend/cookie_attributes.d.ts.map +1 -0
- package/dist/testing/cross_backend/cookie_attributes.js +158 -0
- package/dist/testing/cross_backend/credential_header_robustness.d.ts +12 -0
- package/dist/testing/cross_backend/credential_header_robustness.d.ts.map +1 -0
- package/dist/testing/cross_backend/credential_header_robustness.js +179 -0
- package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_backend_configs.js +5 -3
- package/dist/testing/cross_backend/full_spine_mount.d.ts.map +1 -1
- package/dist/testing/cross_backend/full_spine_mount.js +7 -0
- package/dist/testing/cross_backend/identity_parity.d.ts.map +1 -1
- package/dist/testing/cross_backend/login_security.d.ts.map +1 -1
- package/dist/testing/cross_backend/method_coverage.d.ts +3 -7
- package/dist/testing/cross_backend/method_coverage.d.ts.map +1 -1
- package/dist/testing/cross_backend/method_coverage.js +1 -2
- package/dist/testing/cross_backend/peer_ping_ws.js +1 -1
- package/dist/testing/cross_backend/role_grant_offer_enumeration.d.ts +26 -0
- package/dist/testing/cross_backend/role_grant_offer_enumeration.d.ts.map +1 -0
- package/dist/testing/cross_backend/role_grant_offer_enumeration.js +108 -0
- package/dist/testing/cross_backend/rust_spine_stub_backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/setup.d.ts.map +1 -1
- package/dist/testing/cross_backend/setup.js +2 -4
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +0 -13
- package/dist/testing/cross_backend/testing_reset_actions.d.ts.map +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.js +12 -4
- package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
- package/dist/testing/cross_backend/ts_spine_backend_config.js +9 -3
- package/dist/testing/data_exposure.d.ts.map +1 -1
- package/dist/testing/db.d.ts.map +1 -1
- package/dist/testing/db_entities.d.ts +15 -0
- package/dist/testing/db_entities.d.ts.map +1 -1
- package/dist/testing/db_entities.js +16 -1
- package/dist/testing/error_coverage.d.ts.map +1 -1
- package/dist/testing/error_coverage.js +1 -2
- package/dist/testing/integration_helpers.d.ts.map +1 -1
- package/dist/testing/rate_limiting.d.ts.map +1 -1
- package/dist/testing/round_trip.d.ts.map +1 -1
- package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
- package/dist/testing/rpc_helpers.d.ts.map +1 -1
- package/dist/testing/rpc_round_trip.d.ts.map +1 -1
- package/dist/testing/schema_generators.d.ts.map +1 -1
- package/dist/testing/schema_generators.js +3 -1
- package/dist/testing/schema_parity.d.ts.map +1 -1
- package/dist/testing/sse_round_trip.d.ts.map +1 -1
- package/dist/testing/surface_invariants.d.ts.map +1 -1
- package/dist/testing/transports/bootstrap.d.ts.map +1 -1
- package/dist/testing/transports/ws_client.d.ts +1 -1
- package/dist/testing/transports/ws_transport.d.ts +1 -1
- package/dist/testing/ws_round_trip.d.ts +1 -1
- package/dist/testing/ws_round_trip.d.ts.map +1 -1
- package/dist/testing/ws_round_trip.js +3 -3
- package/dist/ui/CLAUDE.md +6 -3
- package/dist/ui/auth_state.svelte.d.ts.map +1 -1
- package/dist/ui/form_state.svelte.d.ts.map +1 -1
- package/dist/ui/role_grant_offers_state.svelte.d.ts +1 -1
- package/dist/ui/role_grant_offers_state.svelte.js +1 -1
- package/dist/ui/ui_format.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/actions/action_peer.d.ts.map +0 -1
package/dist/actions/CLAUDE.md
CHANGED
|
@@ -91,7 +91,7 @@ registry-only.
|
|
|
91
91
|
**Symmetric design — universal calling abstraction.** SAES is one spec
|
|
92
92
|
shape driving dispatch across (a) network boundaries (frontend ⇄ backend
|
|
93
93
|
over HTTP / WS) and (b) within the same runtime (`local_call` actions).
|
|
94
|
-
`
|
|
94
|
+
`ActionDispatcher` is symmetric on both sides (`send` + `receive`). Typed
|
|
95
95
|
surfaces are paired: `FrontendActionsApi` is "what the frontend can call"
|
|
96
96
|
(typed Proxy from `create_rpc_client`); `BackendActionsApi` is "what the
|
|
97
97
|
backend can call" (typed object from `create_broadcast_api` today;
|
|
@@ -138,9 +138,9 @@ and options on each function's TSDoc.
|
|
|
138
138
|
- `compose_gen_file` — wrapper: banner + `imports.build()` + blocks join.
|
|
139
139
|
- `create_namespace_qualifier(sources, imports)` — multi-source consumer helper; registers `import * as ns` per source.
|
|
140
140
|
|
|
141
|
-
Shared defaults: `DEFAULT_COLLECTIONS_PATH = './action_collections.
|
|
142
|
-
`DEFAULT_SPECS_MODULE = './action_specs.
|
|
143
|
-
`DEFAULT_METATYPES_PATH = './action_metatypes.
|
|
141
|
+
Shared defaults: `DEFAULT_COLLECTIONS_PATH = './action_collections.ts'`,
|
|
142
|
+
`DEFAULT_SPECS_MODULE = './action_specs.ts'`,
|
|
143
|
+
`DEFAULT_METATYPES_PATH = './action_metatypes.ts'`,
|
|
144
144
|
`resolve_spec_qualifier` (the default-vs-callback resolver every
|
|
145
145
|
multi-source-aware helper uses).
|
|
146
146
|
|
|
@@ -148,7 +148,7 @@ multi-source-aware helper uses).
|
|
|
148
148
|
|
|
149
149
|
**Protocol actions filtered by default.** Every spec-iterating helper
|
|
150
150
|
accepts `{include_protocol_actions?: boolean}` (default `false`) and drops
|
|
151
|
-
`heartbeat` / `cancel`. Protocol actions ship from fuz_app and spread into
|
|
151
|
+
`heartbeat` / `cancel` / `peer/ping`. Protocol actions ship from fuz_app and spread into
|
|
152
152
|
each consumer's `actions` array at registration time (via
|
|
153
153
|
`protocol_actions` from `actions/protocol.ts`); they should not appear in
|
|
154
154
|
consumer-owned typed surfaces. Pass `include_protocol_actions: true` only
|
|
@@ -220,6 +220,7 @@ interface ActionContext {
|
|
|
220
220
|
auth: RequestContext | null; // null for public actions
|
|
221
221
|
request_id: JsonrpcRequestId;
|
|
222
222
|
connection_id?: Uuid; // populated on WS, undefined on HTTP
|
|
223
|
+
request_client?: RequestClient; // WS only: initiate a server→client request + await the reply (ActionPeer); undefined on HTTP
|
|
223
224
|
db: Db; // transaction for mutations, pool for reads
|
|
224
225
|
pending_effects: Array<Promise<void>>; // eager — see http/CLAUDE.md §Pending Effects
|
|
225
226
|
post_commit_effects: Array<() => void | Promise<void>>; // deferred — push via `emit_after_commit`
|
|
@@ -320,7 +321,7 @@ and optional `dispose()`. All transports share `TransportSendOptions`:
|
|
|
320
321
|
`Transports` registry holds multiple transports with a `current` selection
|
|
321
322
|
and `allow_fallback: boolean` (default `true`). Explicit
|
|
322
323
|
`transport_for_method` (on `rpc_client`) or
|
|
323
|
-
`default_send_options.transport_name` (on `
|
|
324
|
+
`default_send_options.transport_name` (on `ActionDispatcher`) takes precedence.
|
|
324
325
|
|
|
325
326
|
### WS close codes (`actions/transports.ts`)
|
|
326
327
|
|
|
@@ -331,8 +332,8 @@ and `allow_fallback: boolean` (default `true`). Explicit
|
|
|
331
332
|
### Transport modules
|
|
332
333
|
|
|
333
334
|
- `actions/transports_http.ts` — `frontend_http_rpc`; thin `fetch` adapter, POST default, GET on `has_side_effects(method) === false`.
|
|
334
|
-
- `actions/transports_ws.ts` — `frontend_websocket_rpc`; thin adapter over `WebsocketRpcConnection` (default impl: `FrontendWebsocketClient`).
|
|
335
|
-
- `actions/transports_ws_backend.ts` — `backend_websocket_rpc`; server-side WS with session tracking; satisfies `FilterableBroadcastTransport`.
|
|
335
|
+
- `actions/transports_ws.ts` — `frontend_websocket_rpc`; thin adapter over `WebsocketRpcConnection` (default impl: `FrontendWebsocketClient`). Answers inbound server→client requests: a built-in `peer_ping_responder` for `peer/ping` (zero-wiring liveness), any other request routed through `peer.receive` with the response sent back over the socket (the frontend half of the ActionPeer receive loop).
|
|
336
|
+
- `actions/transports_ws_backend.ts` — `backend_websocket_rpc`; server-side WS with session tracking; satisfies `FilterableBroadcastTransport`. Server→client requests via `request_connection` (correlation registry in `actions/peer_request.ts`).
|
|
336
337
|
|
|
337
338
|
`FrontendHttpTransport` synthesizes a JSON-RPC error envelope via
|
|
338
339
|
`http_status_to_jsonrpc_error_code` on non-OK HTTP; DEV warns on drift
|
|
@@ -362,7 +363,28 @@ Fan-out: `send(notification)` broadcasts to every connection;
|
|
|
362
363
|
`broadcast_filtered(message, predicate)` runs per-connection ACL predicate
|
|
363
364
|
over `ConnectionIdentity`; `send_to_account` wraps `broadcast_filtered` and
|
|
364
365
|
structurally satisfies `NotificationSender` (see `auth/CLAUDE.md` §WS
|
|
365
|
-
notifications).
|
|
366
|
+
notifications). `send(request)` is a misuse (a request has no single
|
|
367
|
+
broadcast target) and returns an error envelope.
|
|
368
|
+
|
|
369
|
+
Server→client request/response (ActionPeer): `request_connection(connection_id,
|
|
370
|
+
method, params, {timeout_ms?})` sends a `{jsonrpc, method, params, id}` frame to
|
|
371
|
+
exactly one socket and awaits the reply, returning a `PeerRequestOutcome`
|
|
372
|
+
(`{ok: true, value}` | `{ok: false, error: PeerRequestError}` —
|
|
373
|
+
`timeout`/`connection_gone`/`too_many_in_flight`/`client_error`). The transport
|
|
374
|
+
owns the socket + the send; the correlation registry — id allocation, the pending
|
|
375
|
+
map (nested `connection_id → s{n}` id, the nesting being the per-connection
|
|
376
|
+
isolation guarantee), deadlines, and the in-flight cap — is `PendingPeerRequests`
|
|
377
|
+
in **`actions/peer_request.ts`** (also home to the peer types/constants +
|
|
378
|
+
`audit_unmatched_peer_response`), composed as `#pending` and unit-tested without a
|
|
379
|
+
socket. `register_action_ws` routes inbound responses back via
|
|
380
|
+
`resolve_peer_response` (→ `#pending.resolve`); connection close drains pending as
|
|
381
|
+
`connection_gone`. Defaults: `DEFAULT_PEER_REQUEST_TIMEOUT` (10s),
|
|
382
|
+
`MAX_IN_FLIGHT_PEER_REQUESTS_PER_CONNECTION` (256). Threaded to handlers as
|
|
383
|
+
`ActionContext.request_client` (WS only; `undefined` on HTTP RPC). The `peer/ping`
|
|
384
|
+
protocol action drives it; see `actions/peer_ping.ts`. An inbound reply matching
|
|
385
|
+
no pending entry (unsolicited / cross-connection / late) is dropped + audited via
|
|
386
|
+
`audit_unmatched_peer_response` (sampled warn — first 8, then 1/256; twin of the
|
|
387
|
+
Rust `audit_unmatched_response`).
|
|
366
388
|
|
|
367
389
|
Return values are bookkeeping, not delivery receipts — `0` means no live
|
|
368
390
|
sockets, non-zero means `ws.send` did not throw. Durable delivery requires
|
|
@@ -531,9 +553,10 @@ Two abort signals composed via `AbortSignal.any`:
|
|
|
531
553
|
|
|
532
554
|
## Protocol actions (`actions/protocol.ts`)
|
|
533
555
|
|
|
534
|
-
|
|
535
|
-
sides' `actions` arrays — disconnect detection
|
|
536
|
-
work identically across every repo
|
|
556
|
+
Three shared `{spec, handler}` tuples that every consumer spreads into both
|
|
557
|
+
sides' `actions` arrays — disconnect detection, per-request cancel, and the
|
|
558
|
+
server→client `peer/ping` round-trip work identically across every repo
|
|
559
|
+
without per-consumer ping plumbing.
|
|
537
560
|
|
|
538
561
|
The category is wire-protocol concerns shipped by fuz_app, not consumer
|
|
539
562
|
domain logic. Protocol vs domain: a future clock-skew probe or
|
|
@@ -544,9 +567,12 @@ Two const arrays:
|
|
|
544
567
|
- `protocol_actions: ReadonlyArray<Action>` — for the server's `register_action_ws` `actions`. Spread before consumer-owned actions.
|
|
545
568
|
- `protocol_action_specs: ReadonlyArray<ActionSpecUnion>` — derived via `.map(a => a.spec)` so the two arrays cannot drift. For the frontend `ActionRegistry`.
|
|
546
569
|
|
|
547
|
-
Asymmetry intentional — server runs handlers (heartbeat echo
|
|
548
|
-
stub), frontend registry only stores specs. Both
|
|
549
|
-
`include_protocol_actions: false` default form a
|
|
570
|
+
Asymmetry intentional — server runs handlers (heartbeat echo, cancel
|
|
571
|
+
stub, peer/ping round-trip), frontend registry only stores specs. Both
|
|
572
|
+
bundles plus the codegen `include_protocol_actions: false` default form a
|
|
573
|
+
three-leg contract; `PROTOCOL_ACTION_METHODS` (in `actions/action_codegen.ts`)
|
|
574
|
+
is the method-name set that drives both the codegen filter and the action-manifest
|
|
575
|
+
exclusion.
|
|
550
576
|
|
|
551
577
|
**Not auto-spread by `create_frontend_rpc_client` or `register_ws_endpoint`** —
|
|
552
578
|
bundled helpers stay pure factories so the dispatch surface stays
|
|
@@ -557,11 +583,12 @@ individual protocol actions without an opt-out flag.
|
|
|
557
583
|
|
|
558
584
|
- **`heartbeat_action`** — `request_response`, `initiator: 'frontend'`, `auth: 'authenticated'`, `side_effects: false`, nullary input/output (`z.strictObject({})`). Handler is a stateless no-op echo. Client's activity-aware heartbeat timer fires this whenever idle past `DEFAULT_HEARTBEAT_INTERVAL`; server's `register_action_ws` heartbeat tracker counts the incoming message as activity.
|
|
559
585
|
- **`cancel_action`** — `remote_notification`, `initiator: 'frontend'`, `auth: null`, `side_effects: true`. Params: `CancelNotificationParams = z.strictObject({request_id: JsonrpcRequestId})`. **Handler is an empty stub** — cancel semantics are dispatcher-owned (`register_action_ws` has the `{request_id → AbortController}` map). Wire format is snake_case `cancel` + `{request_id}`, not MCP's `$/cancelRequest` + `{requestId}` — MCP adoption would happen at an MCP adapter's translation layer, not in the base transport.
|
|
586
|
+
- **`peer_ping_action`** — `request_response`, `initiator: 'both'`, `auth: public`, `side_effects: false`. Input `PingActionInput = {nonce?, timeout_ms?}` (`.default({})`); output `PingResponse = {nonce, protocol_version}`. The client→server invocation drives the **server→client** direction: the handler calls `ctx.request_client('peer/ping', {nonce})`, awaits the echo, validates it against `PingResponse` + checks the nonce, and returns it. Over HTTP RPC (`ctx.request_client` absent) it refuses with `peer_no_transport`, so it's mounted on both the WS endpoint (via this bundle) and the HTTP RPC endpoint (the spine full mount). `timeout_ms` is clamped shorten-only. `data.reason` codes (`peer_timeout` / `peer_connection_gone` / `peer_no_transport` / `peer_too_many_in_flight` / `peer_ping_invalid_reply` / `peer_ping_nonce_mismatch`) + the `PingResponse` shape (whose `protocol_version` is `PEER_PROTOCOL_VERSION`) are the cross-impl wire contract (twins of the Rust `REASON_PEER_*`). The frontend half — `peer_ping_responder` (the echo a client sends back, wired into `FrontendWebsocketTransport`) — lives here too. `peer_ping_action` is a plain `RpcAction` literal (not `rpc_action(...)`), so the module stays free of the runtime `action_rpc.ts` import and `protocol_action_specs` doesn't drag the dispatch core into frontend bundles — same discipline as `heartbeat`/`cancel`. See `actions/peer_ping.ts`.
|
|
560
587
|
|
|
561
588
|
## Event state machine
|
|
562
589
|
|
|
563
590
|
Five modules (`action_event_types.ts`, `action_event_data.ts`,
|
|
564
|
-
`action_event_helpers.ts`, `action_event.ts`, `
|
|
591
|
+
`action_event_helpers.ts`, `action_event.ts`, `action_dispatcher.ts`) define a
|
|
565
592
|
discriminated-union-based state machine used by the reactive client to
|
|
566
593
|
track an action through its lifecycle. Per-symbol semantics on TSDoc;
|
|
567
594
|
high-level shapes that span modules:
|
|
@@ -572,11 +599,18 @@ high-level shapes that span modules:
|
|
|
572
599
|
- **`ActionEvent.parse()`** — `initial → parsed` via `spec.input.safeParse`. Input validation failures **fail immediately** without routing through an error phase (client-side programming errors, not runtime conditions with handlers). Handler errors DO route through `send_error` / `receive_error`. On `receive_response` with error response, transitions to `receive_error` instead of failing.
|
|
573
600
|
- **Protocol message creation is automatic** — transitioning `parsed → handling` on `send_request` materializes the outgoing `JsonrpcRequest` with a fresh `create_uuid()` id; on `send` (notification) it materializes the `JsonrpcNotification`.
|
|
574
601
|
|
|
575
|
-
`
|
|
576
|
-
`ActionEventEnvironment`. `default_send_options`
|
|
577
|
-
deliberately — a shared signal would abort every subsequent
|
|
578
|
-
first trip. `transport_name` and `queue` can be defaulted here
|
|
579
|
-
flip the
|
|
602
|
+
`ActionDispatcher` (`actions/action_dispatcher.ts`) is symmetric send + receive
|
|
603
|
+
over a `Transports` registry and `ActionEventEnvironment`. `default_send_options`
|
|
604
|
+
excludes `signal` deliberately — a shared signal would abort every subsequent
|
|
605
|
+
call after the first trip. `transport_name` and `queue` can be defaulted here
|
|
606
|
+
once to flip the dispatcher into client-authoritative mode.
|
|
607
|
+
|
|
608
|
+
**Naming.** `ActionDispatcher` is the (frontend) send/receive coordinator class.
|
|
609
|
+
"ActionPeer" — unbackticked throughout the peer/ping + `request_client` docs — is
|
|
610
|
+
the _capability_ it participates in: the bidirectional peer request/response
|
|
611
|
+
feature. It's a concept, not a symbol. The server→client half of that capability
|
|
612
|
+
is `BackendWebsocketTransport.request_connection` + `PendingPeerRequests` (see
|
|
613
|
+
`actions/peer_request.ts`), not this class.
|
|
580
614
|
|
|
581
615
|
## Reactive frontend client
|
|
582
616
|
|
|
@@ -622,7 +656,7 @@ returns a Proxy-based typed API. Per-kind dispatch:
|
|
|
622
656
|
- **`request_response`** — builds `ActionEvent`, runs `parse().handle_async()` to produce the request, calls `peer.send(request, {transport_name, signal, queue})`, transitions to `receive_response`, wires the response, parses (may transition to `receive_error`), runs handler, extracts `Result`.
|
|
623
657
|
- **`remote_notification`** — builds event, creates notification, `peer.send(notification, {transport_name, signal, queue})`. Returns `Result<{value: void}, {error}>`.
|
|
624
658
|
|
|
625
|
-
`RpcClientCallOptions extends
|
|
659
|
+
`RpcClientCallOptions extends ActionDispatcherSendOptions` — `{signal?, queue?, transport_name?}`.
|
|
626
660
|
`transport_for_method: (method) => TransportName | undefined` for per-method
|
|
627
661
|
selection. `on_action_event(event)` fires once per dispatched action with
|
|
628
662
|
the live `ActionEvent` (zzz wires reactive history here).
|
|
@@ -659,7 +693,7 @@ doesn't get probed as a thenable by `await`.
|
|
|
659
693
|
### Frontend factory (`actions/frontend_rpc_client.ts`)
|
|
660
694
|
|
|
661
695
|
`create_frontend_rpc_client<TApi>({specs, path?, transports?, transport_for_method?, on_action_event?})`
|
|
662
|
-
bundles `ActionRegistry + ActionEventEnvironment + Transports +
|
|
696
|
+
bundles `ActionRegistry + ActionEventEnvironment + Transports + ActionDispatcher +
|
|
663
697
|
create_rpc_client + create_throwing_api` boilerplate every consumer
|
|
664
698
|
repeats — plus the `lookup_action_handler: () => undefined` stub (frontend
|
|
665
699
|
never registers `request_response` handlers; every method dispatches over
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action_bridge.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAE3B,OAAO,KAAK,EAAC,UAAU,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AACpE,OAAO,KAAK,EAAC,SAAS,EAAE,WAAW,EAAE,YAAY,EAAC,MAAM,uBAAuB,CAAC;AAChF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEhE,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,uGAAuG;IACvG,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,mFAAmF;IACnF,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,8GAA8G;IAC9G,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B;AAED,gEAAgE;AAChE,MAAM,WAAW,kBAAkB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,GAAI,cAAc,iBAAiB,KAAG,WAEpE,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,wBAAwB,GACpC,MAAM,UAAU,EAChB,SAAS,kBAAkB,KACzB,
|
|
1
|
+
{"version":3,"file":"action_bridge.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAE3B,OAAO,KAAK,EAAC,UAAU,EAAE,iBAAiB,EAAC,MAAM,kBAAkB,CAAC;AACpE,OAAO,KAAK,EAAC,SAAS,EAAE,WAAW,EAAE,YAAY,EAAC,MAAM,uBAAuB,CAAC;AAChF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAEhE,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,uGAAuG;IACvG,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,mFAAmF;IACnF,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,8GAA8G;IAC9G,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B;AAED,gEAAgE;AAChE,MAAM,WAAW,kBAAkB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,GAAI,cAAc,iBAAiB,KAAG,WAEpE,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,wBAAwB,GACpC,MAAM,UAAU,EAChB,SAAS,kBAAkB,KACzB,SAqBF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,GACpC,MAAM,UAAU,EAChB,UAAU,kBAAkB,KAC1B,SAcF,CAAC"}
|
|
@@ -7,7 +7,7 @@ import type { ActionSpecUnion, ActionEventPhase } from './action_spec.js';
|
|
|
7
7
|
* `BackendRequestResponseMethod` / handler maps. Pairs with `protocol_actions`
|
|
8
8
|
* / `protocol_action_specs` from `actions/protocol.ts` (the runtime bundles).
|
|
9
9
|
*/
|
|
10
|
-
export declare const PROTOCOL_ACTION_METHODS: readonly ["heartbeat", "cancel"];
|
|
10
|
+
export declare const PROTOCOL_ACTION_METHODS: readonly ["heartbeat", "cancel", "peer/ping"];
|
|
11
11
|
/** Methods that ship from fuz_app, kept out of consumer-owned method enums + handler maps. */
|
|
12
12
|
export type ProtocolActionMethod = (typeof PROTOCOL_ACTION_METHODS)[number];
|
|
13
13
|
/**
|
|
@@ -125,9 +125,25 @@ export declare const generate_phase_handlers: (spec: ActionSpecUnion, executor:
|
|
|
125
125
|
}) => string;
|
|
126
126
|
/** "DO NOT EDIT" banner naming the gen producer. */
|
|
127
127
|
export declare const create_banner: (origin_path: string) => string;
|
|
128
|
+
/**
|
|
129
|
+
* Derive the exported spec identifier for a method. Method names that aren't
|
|
130
|
+
* legal JS identifiers — e.g. the `/` in the `peer/ping` protocol action — have
|
|
131
|
+
* each run of illegal characters collapsed to a single `_`, so `peer/ping`
|
|
132
|
+
* resolves to `peer_ping_action_spec` (the export in `actions/peer_ping.ts`).
|
|
133
|
+
* Already-valid names pass through unchanged.
|
|
134
|
+
*/
|
|
128
135
|
export declare const to_action_spec_identifier: (method: string) => string;
|
|
129
136
|
export declare const to_action_spec_input_identifier: (method: string) => string;
|
|
130
137
|
export declare const to_action_spec_output_identifier: (method: string) => string;
|
|
138
|
+
/**
|
|
139
|
+
* Render a method name as an object/interface property key — bare when it's a
|
|
140
|
+
* valid JS identifier, single-quoted otherwise. Method names like `peer/ping`
|
|
141
|
+
* aren't legal as bare keys, so quoting keeps the emitted `ActionSpecs` /
|
|
142
|
+
* `ActionInputs` / `FrontendActionsApi` members valid TypeScript. Pairs with
|
|
143
|
+
* the bracketed indexed-access form (`ActionInputs['peer/ping']`) used for
|
|
144
|
+
* value/type lookups, which already accepts the raw method string.
|
|
145
|
+
*/
|
|
146
|
+
export declare const to_action_property_key: (method: string) => string;
|
|
131
147
|
/**
|
|
132
148
|
* Generates one method line of the typed `FrontendActionsApi` interface for a
|
|
133
149
|
* single spec. Encapsulates the input/options/return-type signature shape so
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action_codegen.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_codegen.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,eAAe,EAAE,gBAAgB,EAAC,MAAM,kBAAkB,CAAC;AAGxE;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,
|
|
1
|
+
{"version":3,"file":"action_codegen.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_codegen.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ import { ActionRegistry } from './action_registry.js';
|
|
|
9
9
|
* `BackendRequestResponseMethod` / handler maps. Pairs with `protocol_actions`
|
|
10
10
|
* / `protocol_action_specs` from `actions/protocol.ts` (the runtime bundles).
|
|
11
11
|
*/
|
|
12
|
-
export const PROTOCOL_ACTION_METHODS = ['heartbeat', 'cancel'];
|
|
12
|
+
export const PROTOCOL_ACTION_METHODS = ['heartbeat', 'cancel', 'peer/ping'];
|
|
13
13
|
const PROTOCOL_METHOD_SET = new Set(PROTOCOL_ACTION_METHODS);
|
|
14
14
|
/**
|
|
15
15
|
* Type predicate for filtering protocol-action methods out of a typed
|
|
@@ -296,14 +296,30 @@ export const generate_phase_handlers = (spec, executor, imports, options) => {
|
|
|
296
296
|
) => ${return_type}`;
|
|
297
297
|
})
|
|
298
298
|
.join(';\n\t\t');
|
|
299
|
-
return `${method}?: {\n\t\t${phase_handlers};\n\t}`;
|
|
299
|
+
return `${to_action_property_key(method)}?: {\n\t\t${phase_handlers};\n\t}`;
|
|
300
300
|
};
|
|
301
301
|
/** "DO NOT EDIT" banner naming the gen producer. */
|
|
302
302
|
export const create_banner = (origin_path) => `generated by ${origin_path} - DO NOT EDIT OR RISK LOST DATA`;
|
|
303
303
|
// TODO rethink these, see also zzz `codegen.ts`
|
|
304
|
-
|
|
304
|
+
/**
|
|
305
|
+
* Derive the exported spec identifier for a method. Method names that aren't
|
|
306
|
+
* legal JS identifiers — e.g. the `/` in the `peer/ping` protocol action — have
|
|
307
|
+
* each run of illegal characters collapsed to a single `_`, so `peer/ping`
|
|
308
|
+
* resolves to `peer_ping_action_spec` (the export in `actions/peer_ping.ts`).
|
|
309
|
+
* Already-valid names pass through unchanged.
|
|
310
|
+
*/
|
|
311
|
+
export const to_action_spec_identifier = (method) => `${method.replace(/[^A-Za-z0-9_$]+/g, '_')}_action_spec`;
|
|
305
312
|
export const to_action_spec_input_identifier = (method) => `${to_action_spec_identifier(method)}.input`;
|
|
306
313
|
export const to_action_spec_output_identifier = (method) => `${to_action_spec_identifier(method)}.output`;
|
|
314
|
+
/**
|
|
315
|
+
* Render a method name as an object/interface property key — bare when it's a
|
|
316
|
+
* valid JS identifier, single-quoted otherwise. Method names like `peer/ping`
|
|
317
|
+
* aren't legal as bare keys, so quoting keeps the emitted `ActionSpecs` /
|
|
318
|
+
* `ActionInputs` / `FrontendActionsApi` members valid TypeScript. Pairs with
|
|
319
|
+
* the bracketed indexed-access form (`ActionInputs['peer/ping']`) used for
|
|
320
|
+
* value/type lookups, which already accepts the raw method string.
|
|
321
|
+
*/
|
|
322
|
+
export const to_action_property_key = (method) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(method) ? method : `'${method}'`;
|
|
307
323
|
/**
|
|
308
324
|
* Generates one method line of the typed `FrontendActionsApi` interface for a
|
|
309
325
|
* single spec. Encapsulates the input/options/return-type signature shape so
|
|
@@ -379,7 +395,7 @@ export const generate_actions_api_method_signature = (spec, imports, options) =>
|
|
|
379
395
|
imports.add_type('@fuzdev/fuz_util/result.ts', 'Result');
|
|
380
396
|
imports.add_type('@fuzdev/fuz_app/http/jsonrpc.ts', 'JsonrpcErrorObject');
|
|
381
397
|
}
|
|
382
|
-
return `${spec.method}: (${input_param}${options_param}) => ${return_type};`;
|
|
398
|
+
return `${to_action_property_key(spec.method)}: (${input_param}${options_param}) => ${return_type};`;
|
|
383
399
|
};
|
|
384
400
|
// --------------------------------------------------------------------------
|
|
385
401
|
// High-level codegen helpers — compose the lower-level primitives above into
|
|
@@ -456,7 +472,7 @@ export const resolve_spec_qualifier = (imports, options) => {
|
|
|
456
472
|
return options.qualify_spec;
|
|
457
473
|
const specs_module = options?.specs_module ?? DEFAULT_SPECS_MODULE;
|
|
458
474
|
imports.add(specs_module, '* as specs');
|
|
459
|
-
return (s) => `specs.${s.method}
|
|
475
|
+
return (s) => `specs.${to_action_spec_identifier(s.method)}`;
|
|
460
476
|
};
|
|
461
477
|
/**
|
|
462
478
|
* Emit one or more `z.enum([...])` declarations for action method names —
|
|
@@ -592,8 +608,12 @@ export interface ActionSpecs {}
|
|
|
592
608
|
export const action_specs: Array<ActionSpecUnion> = Object.values(ActionSpecs);`;
|
|
593
609
|
}
|
|
594
610
|
const qualify = resolve_spec_qualifier(imports, options);
|
|
595
|
-
const value_lines = filtered
|
|
596
|
-
|
|
611
|
+
const value_lines = filtered
|
|
612
|
+
.map((s) => `\t${to_action_property_key(s.method)}: ${qualify(s)},`)
|
|
613
|
+
.join('\n');
|
|
614
|
+
const type_lines = filtered
|
|
615
|
+
.map((s) => `\t${to_action_property_key(s.method)}: typeof ${qualify(s)};`)
|
|
616
|
+
.join('\n');
|
|
597
617
|
return `/**
|
|
598
618
|
* Action specifications indexed by method name.
|
|
599
619
|
* These represent the complete action spec definitions.
|
|
@@ -643,13 +663,17 @@ export interface ActionOutputs {}`;
|
|
|
643
663
|
}
|
|
644
664
|
imports.add('zod', 'z');
|
|
645
665
|
const qualify = resolve_spec_qualifier(imports, options);
|
|
646
|
-
const inputs_value = filtered
|
|
666
|
+
const inputs_value = filtered
|
|
667
|
+
.map((s) => `\t${to_action_property_key(s.method)}: ${qualify(s)}.input,`)
|
|
668
|
+
.join('\n');
|
|
647
669
|
const inputs_type = filtered
|
|
648
|
-
.map((s) => `\t${s.method}: z.infer<typeof ${qualify(s)}.input>;`)
|
|
670
|
+
.map((s) => `\t${to_action_property_key(s.method)}: z.infer<typeof ${qualify(s)}.input>;`)
|
|
671
|
+
.join('\n');
|
|
672
|
+
const outputs_value = filtered
|
|
673
|
+
.map((s) => `\t${to_action_property_key(s.method)}: ${qualify(s)}.output,`)
|
|
649
674
|
.join('\n');
|
|
650
|
-
const outputs_value = filtered.map((s) => `\t${s.method}: ${qualify(s)}.output,`).join('\n');
|
|
651
675
|
const outputs_type = filtered
|
|
652
|
-
.map((s) => `\t${s.method}: z.infer<typeof ${qualify(s)}.output>;`)
|
|
676
|
+
.map((s) => `\t${to_action_property_key(s.method)}: z.infer<typeof ${qualify(s)}.output>;`)
|
|
653
677
|
.join('\n');
|
|
654
678
|
return `/**
|
|
655
679
|
* Action parameter schemas indexed by method name.
|
|
@@ -722,7 +746,7 @@ export interface ActionEventDatas {}`;
|
|
|
722
746
|
const type_args = spec.kind === 'remote_notification'
|
|
723
747
|
? `<'${spec.method}', ActionInputs['${spec.method}']>`
|
|
724
748
|
: `<'${spec.method}', ActionInputs['${spec.method}'], ActionOutputs['${spec.method}']>`;
|
|
725
|
-
return `\t${spec.method}: ${data_type}${type_args};`;
|
|
749
|
+
return `\t${to_action_property_key(spec.method)}: ${data_type}${type_args};`;
|
|
726
750
|
});
|
|
727
751
|
return `/**
|
|
728
752
|
* Action event data types indexed by method name.
|
|
@@ -873,7 +897,7 @@ export const broadcast_action_specs: ReadonlyArray<ActionSpecUnion> = [];`;
|
|
|
873
897
|
const qualify = resolve_spec_qualifier(imports, options);
|
|
874
898
|
const interface_body = '\n' +
|
|
875
899
|
broadcast
|
|
876
|
-
.map((s) => `\t${s.method}: (input: ActionInputs['${s.method}']) => Promise<void>;`)
|
|
900
|
+
.map((s) => `\t${to_action_property_key(s.method)}: (input: ActionInputs['${s.method}']) => Promise<void>;`)
|
|
877
901
|
.join('\n') +
|
|
878
902
|
'\n';
|
|
879
903
|
const array_body = '\n' + broadcast.map((s) => `\t${qualify(s)},`).join('\n') + '\n';
|
|
@@ -979,7 +1003,7 @@ export const create_namespace_qualifier = (sources, imports) => {
|
|
|
979
1003
|
if (!ns) {
|
|
980
1004
|
throw new Error(`unknown action method passed to qualify_spec: ${spec.method} — not in any registered source`);
|
|
981
1005
|
}
|
|
982
|
-
return `${ns}.${spec.method}
|
|
1006
|
+
return `${ns}.${to_action_spec_identifier(spec.method)}`;
|
|
983
1007
|
};
|
|
984
1008
|
return { qualify_spec, all_specs };
|
|
985
1009
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ActionDispatcher — symmetric send/receive for JSON-RPC actions.
|
|
3
3
|
*
|
|
4
4
|
* Wraps a `Transports` registry and `ActionEventEnvironment` to provide
|
|
5
5
|
* bidirectional action dispatch via JSON-RPC 2.0.
|
|
@@ -10,27 +10,27 @@ import { JsonrpcMessageFromServerToClient, JsonrpcNotification, JsonrpcRequest,
|
|
|
10
10
|
import { Transports, type TransportName, type TransportSendOptions } from './transports.js';
|
|
11
11
|
import type { ActionEventEnvironment } from './action_event_types.js';
|
|
12
12
|
/**
|
|
13
|
-
* Per-call options for `
|
|
13
|
+
* Per-call options for `ActionDispatcher.send`. Extends `TransportSendOptions`
|
|
14
14
|
* with `transport_name` for per-call transport selection. The peer-wide
|
|
15
|
-
* default for any field lives on `
|
|
15
|
+
* default for any field lives on `ActionDispatcherOptions.default_send_options` —
|
|
16
16
|
* set `queue: true` there once for client-authoritative peers and override
|
|
17
17
|
* per-call for exceptions (e.g. high-frequency position sync where stale
|
|
18
18
|
* replays are wrong).
|
|
19
19
|
*/
|
|
20
|
-
export interface
|
|
20
|
+
export interface ActionDispatcherSendOptions extends TransportSendOptions {
|
|
21
21
|
transport_name?: TransportName;
|
|
22
22
|
}
|
|
23
|
-
export interface
|
|
23
|
+
export interface ActionDispatcherOptions {
|
|
24
24
|
environment: ActionEventEnvironment;
|
|
25
25
|
transports?: Transports;
|
|
26
|
-
default_send_options?: Omit<
|
|
26
|
+
default_send_options?: Omit<ActionDispatcherSendOptions, 'signal'>;
|
|
27
27
|
}
|
|
28
|
-
export declare class
|
|
28
|
+
export declare class ActionDispatcher {
|
|
29
29
|
#private;
|
|
30
30
|
readonly environment: ActionEventEnvironment;
|
|
31
31
|
readonly transports: Transports;
|
|
32
|
-
default_send_options: Omit<
|
|
33
|
-
constructor(options:
|
|
32
|
+
default_send_options: Omit<ActionDispatcherSendOptions, 'signal'>;
|
|
33
|
+
constructor(options: ActionDispatcherOptions);
|
|
34
34
|
/**
|
|
35
35
|
* Resolve a transport (per-call name → default name → registry default)
|
|
36
36
|
* and forward the message. Catches unexpected throws and converts them
|
|
@@ -40,8 +40,8 @@ export declare class ActionPeer {
|
|
|
40
40
|
* notifications (`JsonrpcErrorResponse` if the notification's transport
|
|
41
41
|
* send failed)
|
|
42
42
|
*/
|
|
43
|
-
send(message: JsonrpcRequest, options?:
|
|
44
|
-
send(message: JsonrpcNotification, options?:
|
|
43
|
+
send(message: JsonrpcRequest, options?: ActionDispatcherSendOptions): Promise<JsonrpcResponseOrError>;
|
|
44
|
+
send(message: JsonrpcNotification, options?: ActionDispatcherSendOptions): Promise<JsonrpcErrorResponse | null>;
|
|
45
45
|
/**
|
|
46
46
|
* Dispatch an inbound JSON-RPC message — request, notification, or
|
|
47
47
|
* malformed envelope. Never throws; unexpected failures become
|
|
@@ -52,4 +52,4 @@ export declare class ActionPeer {
|
|
|
52
52
|
*/
|
|
53
53
|
receive(message: unknown): Promise<JsonrpcMessageFromServerToClient | null>;
|
|
54
54
|
}
|
|
55
|
-
//# sourceMappingURL=
|
|
55
|
+
//# sourceMappingURL=action_dispatcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action_dispatcher.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEN,gCAAgC,EAChC,mBAAmB,EACnB,cAAc,EACd,sBAAsB,EACtB,oBAAoB,EACpB,MAAM,oBAAoB,CAAC;AAU5B,OAAO,EAAC,UAAU,EAAE,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAC,MAAM,iBAAiB,CAAC;AAC1F,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,yBAAyB,CAAC;AAOpE;;;;;;;GAOG;AACH,MAAM,WAAW,2BAA4B,SAAQ,oBAAoB;IACxE,cAAc,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,MAAM,WAAW,uBAAuB;IACvC,WAAW,EAAE,sBAAsB,CAAC;IAGpC,UAAU,CAAC,EAAE,UAAU,CAAC;IAKxB,oBAAoB,CAAC,EAAE,IAAI,CAAC,2BAA2B,EAAE,QAAQ,CAAC,CAAC;CACnE;AAED,qBAAa,gBAAgB;;IAC5B,QAAQ,CAAC,WAAW,EAAE,sBAAsB,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAMhC,oBAAoB,EAAE,IAAI,CAAC,2BAA2B,EAAE,QAAQ,CAAC,CAAC;gBAEtD,OAAO,EAAE,uBAAuB;IAM5C;;;;;;;;OAQG;IAEG,IAAI,CACT,OAAO,EAAE,cAAc,EACvB,OAAO,CAAC,EAAE,2BAA2B,GACnC,OAAO,CAAC,sBAAsB,CAAC;IAC5B,IAAI,CACT,OAAO,EAAE,mBAAmB,EAC5B,OAAO,CAAC,EAAE,2BAA2B,GACnC,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC;IA8CvC;;;;;;;OAOG;IACG,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,gCAAgC,GAAG,IAAI,CAAC;CAgIjF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ActionDispatcher — symmetric send/receive for JSON-RPC actions.
|
|
3
3
|
*
|
|
4
4
|
* Wraps a `Transports` registry and `ActionEventEnvironment` to provide
|
|
5
5
|
* bidirectional action dispatch via JSON-RPC 2.0.
|
|
@@ -11,7 +11,7 @@ import { create_jsonrpc_error_response, create_jsonrpc_error_response_from_throw
|
|
|
11
11
|
import { jsonrpc_error_messages } from '../http/jsonrpc_errors.js';
|
|
12
12
|
import { create_action_event } from './action_event.js';
|
|
13
13
|
import { Transports } from './transports.js';
|
|
14
|
-
export class
|
|
14
|
+
export class ActionDispatcher {
|
|
15
15
|
environment;
|
|
16
16
|
transports;
|
|
17
17
|
// TODO maybe expand the pattern of using `transports` in send, so what's used in receive?
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action_event.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_event.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAC,gBAAgB,EAAc,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAWpF,OAAO,KAAK,EACX,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EAEnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,sBAAsB,EAAE,eAAe,EAAC,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAkB,KAAK,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AAclF,MAAM,MAAM,yBAAyB,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM,IAAI,CACxE,QAAQ,EAAE,oBAAoB,CAAC,OAAO,CAAC,EACvC,QAAQ,EAAE,oBAAoB,CAAC,OAAO,CAAC,EACvC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,KACvB,IAAI,CAAC;AAEV;;GAEG;AACH,qBAAa,WAAW,CACvB,OAAO,SAAS,MAAM,GAAG,MAAM,EAC/B,MAAM,SAAS,gBAAgB,GAAG,gBAAgB,EAClD,KAAK,SAAS,eAAe,GAAG,eAAe;;IAK/C,QAAQ,CAAC,WAAW,EAAE,sBAAsB,CAAC;IAC7C;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG;QAAC,MAAM,EAAE,OAAO,CAAA;KAAC,CAAC;IAEnD,IAAI,IAAI,IAAI,oBAAoB,CAAC,OAAO,CAAC,GAAG;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,KAAK,CAAA;KAAC,CAEvE;gBAGA,WAAW,EAAE,sBAAsB,EACnC,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,oBAAoB,CAAC,OAAO,CAAC;IAOpC,MAAM,IAAI,oBAAoB,CAAC,OAAO,CAAC;IAMvC;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,EAAE,yBAAyB,CAAC,OAAO,CAAC,GAAG,MAAM,IAAI;IAKjE;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC,OAAO,CAAC,GAAG,IAAI;IAUvD;;;;;;;OAOG;IACH,KAAK,IAAI,IAAI;IA8Cb;;;;;;;;;;OAUG;IAGG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA0CnC;;;;;;;OAOG;IACH,WAAW,IAAI,IAAI;IAkCnB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAezC,WAAW,IAAI,OAAO;IAItB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAIxC,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAQ1C,YAAY,CAAC,QAAQ,EAAE,sBAAsB,GAAG,IAAI;IAUpD,gBAAgB,CAAC,YAAY,EAAE,mBAAmB,GAAG,IAAI;CAyKzD;AAGD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,SAAS,MAAM,GAAG,MAAM,EAClE,aAAa,sBAAsB,EACnC,MAAM,eAAe,EACrB,OAAO,OAAO,EACd,gBAAgB,gBAAgB,KAC9B,WAAW,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"action_event.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_event.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAC,gBAAgB,EAAc,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAWpF,OAAO,KAAK,EACX,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EAEnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,sBAAsB,EAAE,eAAe,EAAC,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAkB,KAAK,oBAAoB,EAAC,MAAM,wBAAwB,CAAC;AAclF,MAAM,MAAM,yBAAyB,CAAC,OAAO,SAAS,MAAM,GAAG,MAAM,IAAI,CACxE,QAAQ,EAAE,oBAAoB,CAAC,OAAO,CAAC,EACvC,QAAQ,EAAE,oBAAoB,CAAC,OAAO,CAAC,EACvC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,KACvB,IAAI,CAAC;AAEV;;GAEG;AACH,qBAAa,WAAW,CACvB,OAAO,SAAS,MAAM,GAAG,MAAM,EAC/B,MAAM,SAAS,gBAAgB,GAAG,gBAAgB,EAClD,KAAK,SAAS,eAAe,GAAG,eAAe;;IAK/C,QAAQ,CAAC,WAAW,EAAE,sBAAsB,CAAC;IAC7C;;;;;;OAMG;IACH,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG;QAAC,MAAM,EAAE,OAAO,CAAA;KAAC,CAAC;IAEnD,IAAI,IAAI,IAAI,oBAAoB,CAAC,OAAO,CAAC,GAAG;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,KAAK,CAAA;KAAC,CAEvE;gBAGA,WAAW,EAAE,sBAAsB,EACnC,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,oBAAoB,CAAC,OAAO,CAAC;IAOpC,MAAM,IAAI,oBAAoB,CAAC,OAAO,CAAC;IAMvC;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,EAAE,yBAAyB,CAAC,OAAO,CAAC,GAAG,MAAM,IAAI;IAKjE;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC,OAAO,CAAC,GAAG,IAAI;IAUvD;;;;;;;OAOG;IACH,KAAK,IAAI,IAAI;IA8Cb;;;;;;;;;;OAUG;IAGG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA0CnC;;;;;;;OAOG;IACH,WAAW,IAAI,IAAI;IAkCnB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IAezC,WAAW,IAAI,OAAO;IAItB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAIxC,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAQ1C,YAAY,CAAC,QAAQ,EAAE,sBAAsB,GAAG,IAAI;IAUpD,gBAAgB,CAAC,YAAY,EAAE,mBAAmB,GAAG,IAAI;CAyKzD;AAGD;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,OAAO,SAAS,MAAM,GAAG,MAAM,EAClE,aAAa,sBAAsB,EACnC,MAAM,eAAe,EACrB,OAAO,OAAO,EACd,gBAAgB,gBAAgB,KAC9B,WAAW,CAAC,OAAO,CAmBrB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,GAAI,OAAO,SAAS,MAAM,GAAG,MAAM,EAC5E,MAAM,oBAAoB,CAAC,OAAO,CAAC,EACnC,aAAa,sBAAsB,KACjC,WAAW,CAAC,OAAO,CAOrB,CAAC;AAIF,eAAO,MAAM,kBAAkB,GAC9B,UAAU,OAAO,EACjB,aAAa,sBAAsB,KACjC,WAGF,CAAC"}
|
|
@@ -19,6 +19,7 @@ import { type RouteSpec } from '../http/route_spec.js';
|
|
|
19
19
|
import { type RequestActorContext, type RequestContext } from '../auth/request_context.js';
|
|
20
20
|
import { type CredentialType } from '../hono_context.js';
|
|
21
21
|
import type { Db } from '../db/db.js';
|
|
22
|
+
import type { RequestClient } from './peer_request.js';
|
|
22
23
|
import { type JsonrpcRequestId } from '../http/jsonrpc.js';
|
|
23
24
|
import type { RateLimiter } from '../rate_limiter.js';
|
|
24
25
|
/**
|
|
@@ -43,6 +44,14 @@ export interface ActionContext {
|
|
|
43
44
|
* directly; HTTP handlers ignore it.
|
|
44
45
|
*/
|
|
45
46
|
connection_id?: Uuid;
|
|
47
|
+
/**
|
|
48
|
+
* Initiate a JSON-RPC request to the originating client and await its typed
|
|
49
|
+
* reply — the server→client direction of ActionPeer. Present only on the
|
|
50
|
+
* WebSocket transport (it targets the originating socket); `undefined` on
|
|
51
|
+
* HTTP RPC, where there is no return socket. Handlers that depend on it
|
|
52
|
+
* must handle its absence — e.g. `peer/ping` surfaces `peer_no_transport`.
|
|
53
|
+
*/
|
|
54
|
+
request_client?: RequestClient;
|
|
46
55
|
/**
|
|
47
56
|
* Transaction-scoped when `spec.side_effects` is true (the dispatcher
|
|
48
57
|
* wraps in `db.transaction`); pool-level otherwise. Handlers that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action_rpc.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAEjD,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAExE,OAAO,EAEN,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAIN,KAAK,cAAc,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"action_rpc.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_rpc.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* @module
|
|
19
19
|
*/
|
|
20
20
|
import { type Logger as LoggerType } from '@fuzdev/fuz_util/log.ts';
|
|
21
|
-
import type {
|
|
21
|
+
import type { ActionDispatcher } from './action_dispatcher.js';
|
|
22
22
|
import type { ActionSpecUnion } from './action_spec.js';
|
|
23
23
|
import { type ConnectionIdentity } from './transports_ws_backend.js';
|
|
24
24
|
/**
|
|
@@ -34,7 +34,7 @@ export type ShouldDeliverFn = (connection: ConnectionIdentity, method: string, i
|
|
|
34
34
|
/** Options for `create_broadcast_api`. */
|
|
35
35
|
export interface CreateBroadcastApiOptions {
|
|
36
36
|
/** The peer holding the transport registry used for sends. */
|
|
37
|
-
peer:
|
|
37
|
+
peer: ActionDispatcher;
|
|
38
38
|
/**
|
|
39
39
|
* Notification specs to expose as broadcast methods. Typically the
|
|
40
40
|
* `remote_notification` specs whose initiator is `backend` (or `both`).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broadcast_api.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/broadcast_api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAS,KAAK,MAAM,IAAI,UAAU,EAAC,MAAM,yBAAyB,CAAC;AAG1E,OAAO,KAAK,EAAC,
|
|
1
|
+
{"version":3,"file":"broadcast_api.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/broadcast_api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAS,KAAK,MAAM,IAAI,UAAU,EAAC,MAAM,yBAAyB,CAAC;AAG1E,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAEN,KAAK,kBAAkB,EACvB,MAAM,4BAA4B,CAAC;AAEpC;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,CAC7B,UAAU,EAAE,kBAAkB,EAC9B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,KACV,OAAO,CAAC;AAEb,0CAA0C;AAC1C,MAAM,WAAW,yBAAyB;IACzC,8DAA8D;IAC9D,IAAI,EAAE,gBAAgB,CAAC;IACvB;;;;;OAKG;IACH,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IACtC,gFAAgF;IAChF,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB;;;;;;;;;OASG;IACH,cAAc,CAAC,EAAE,eAAe,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AAE3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,oBAAoB,GAAI,IAAI,SAAS,MAAM,EACvD,SAAS,yBAAyB,KAChC,IAsDF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compile_action_registry.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/compile_action_registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAI/C,oDAAoD;AACpD,MAAM,WAAW,2BAA2B;IAC3C;;;;;OAKG;IACH,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GACnC,SAAS,aAAa,CAAC,MAAM,CAAC,EAC9B,WAAW,MAAM,KACf,
|
|
1
|
+
{"version":3,"file":"compile_action_registry.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/compile_action_registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAI/C,oDAAoD;AACpD,MAAM,WAAW,2BAA2B;IAC3C;;;;;OAKG;IACH,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GACnC,SAAS,aAAa,CAAC,MAAM,CAAC,EAC9B,WAAW,MAAM,KACf,2BAwCF,CAAC"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Frontend-only typed RPC client factory.
|
|
3
3
|
*
|
|
4
4
|
* Bundles the `ActionRegistry + ActionEventEnvironment + Transports +
|
|
5
|
-
*
|
|
5
|
+
* ActionDispatcher + create_rpc_client + create_throwing_api` boilerplate every
|
|
6
6
|
* consumer repeats. `lookup_action_handler` defaults to `() => undefined`
|
|
7
7
|
* (HTTP-only frontends rarely need handlers); pass `options.lookup_action_handler`
|
|
8
8
|
* to wire WS-pushed `remote_notification` dispatch or a `receive_error` /
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
*
|
|
46
46
|
* @module
|
|
47
47
|
*/
|
|
48
|
-
import {
|
|
48
|
+
import { ActionDispatcher } from './action_dispatcher.js';
|
|
49
49
|
import { type Transport } from './transports.js';
|
|
50
50
|
import { type ThrowingApi, type TransportForMethod } from './rpc_client.js';
|
|
51
51
|
import type { ActionEvent } from './action_event.js';
|
|
@@ -138,7 +138,7 @@ export interface FrontendRpcClient<TApi> {
|
|
|
138
138
|
*/
|
|
139
139
|
api_result: TApi;
|
|
140
140
|
/** Underlying peer — exposed for consumers that need to register more transports or send raw messages. */
|
|
141
|
-
peer:
|
|
141
|
+
peer: ActionDispatcher;
|
|
142
142
|
/** Action environment — exposed for consumers that need to share it (e.g. attach a notification handler registry). */
|
|
143
143
|
environment: ActionEventEnvironment;
|
|
144
144
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frontend_rpc_client.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/frontend_rpc_client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"frontend_rpc_client.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/frontend_rpc_client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,EAAC,gBAAgB,EAAC,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAa,KAAK,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAE3D,OAAO,EAGN,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,yBAAyB,CAAC;AACpE,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAEtD,gDAAgD;AAChD,MAAM,WAAW,8BAA8B,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;IAC3E;;;;;;;;;;;;;;OAcG;IACH,KAAK,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IACtC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACtC;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAC1C;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IACpE;;;;;;;;;;;;;;;;OAgBG;IACH,qBAAqB,CAAC,EAAE,sBAAsB,CAAC,uBAAuB,CAAC,CAAC;CACxE;AAED,uDAAuD;AACvD,MAAM,WAAW,iBAAiB,CAAC,IAAI;IACtC;;;;OAIG;IACH,GAAG,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;IACvB;;;;;OAKG;IACH,UAAU,EAAE,IAAI,CAAC;IACjB,0GAA0G;IAC1G,IAAI,EAAE,gBAAgB,CAAC;IACvB,sHAAsH;IACtH,WAAW,EAAE,sBAAsB,CAAC;CACpC;AAED,sFAAsF;AACtF,eAAO,MAAM,0BAA0B,GAAI,IAAI,SAAS,MAAM,EAC7D,SAAS,8BAA8B,CAAC,IAAI,CAAC,KAC3C,iBAAiB,CAAC,IAAI,CAsBxB,CAAC"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Frontend-only typed RPC client factory.
|
|
3
3
|
*
|
|
4
4
|
* Bundles the `ActionRegistry + ActionEventEnvironment + Transports +
|
|
5
|
-
*
|
|
5
|
+
* ActionDispatcher + create_rpc_client + create_throwing_api` boilerplate every
|
|
6
6
|
* consumer repeats. `lookup_action_handler` defaults to `() => undefined`
|
|
7
7
|
* (HTTP-only frontends rarely need handlers); pass `options.lookup_action_handler`
|
|
8
8
|
* to wire WS-pushed `remote_notification` dispatch or a `receive_error` /
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
* @module
|
|
47
47
|
*/
|
|
48
48
|
import { ActionRegistry } from './action_registry.js';
|
|
49
|
-
import {
|
|
49
|
+
import { ActionDispatcher } from './action_dispatcher.js';
|
|
50
50
|
import { Transports } from './transports.js';
|
|
51
51
|
import { FrontendHttpTransport } from './transports_http.js';
|
|
52
52
|
import { create_rpc_client, create_throwing_api, } from './rpc_client.js';
|
|
@@ -66,7 +66,7 @@ export const create_frontend_rpc_client = (options) => {
|
|
|
66
66
|
else {
|
|
67
67
|
transports.register_transport(new FrontendHttpTransport(options.path ?? '/api/rpc'));
|
|
68
68
|
}
|
|
69
|
-
const peer = new
|
|
69
|
+
const peer = new ActionDispatcher({ environment, transports });
|
|
70
70
|
const api_result = create_rpc_client({
|
|
71
71
|
peer,
|
|
72
72
|
environment,
|