@fuzdev/fuz_app 0.51.0 → 0.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/CLAUDE.md +43 -10
- package/dist/actions/action_bridge.d.ts +3 -1
- package/dist/actions/action_bridge.d.ts.map +1 -1
- package/dist/actions/action_bridge.js +3 -1
- package/dist/actions/action_codegen.d.ts +28 -43
- package/dist/actions/action_codegen.d.ts.map +1 -1
- package/dist/actions/action_codegen.js +31 -50
- package/dist/actions/action_event.d.ts +44 -1
- package/dist/actions/action_event.d.ts.map +1 -1
- package/dist/actions/action_event.js +44 -1
- package/dist/actions/action_event_helpers.d.ts +26 -0
- package/dist/actions/action_event_helpers.d.ts.map +1 -1
- package/dist/actions/action_event_helpers.js +26 -1
- package/dist/actions/action_peer.d.ts +17 -0
- package/dist/actions/action_peer.d.ts.map +1 -1
- package/dist/actions/action_peer.js +8 -9
- package/dist/actions/action_registry.d.ts +1 -5
- package/dist/actions/action_registry.d.ts.map +1 -1
- package/dist/actions/action_registry.js +5 -11
- package/dist/actions/action_rpc.d.ts +20 -0
- package/dist/actions/action_rpc.d.ts.map +1 -1
- package/dist/actions/action_rpc.js +45 -20
- package/dist/actions/action_spec.d.ts +75 -6
- package/dist/actions/action_spec.d.ts.map +1 -1
- package/dist/actions/action_spec.js +36 -6
- package/dist/actions/frontend_rpc_client.d.ts +1 -9
- package/dist/actions/frontend_rpc_client.d.ts.map +1 -1
- package/dist/actions/frontend_rpc_client.js +1 -9
- package/dist/actions/register_action_ws.d.ts +19 -0
- package/dist/actions/register_action_ws.d.ts.map +1 -1
- package/dist/actions/register_action_ws.js +44 -1
- package/dist/actions/register_ws_endpoint.d.ts +3 -0
- package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
- package/dist/actions/register_ws_endpoint.js +3 -0
- package/dist/actions/request_tracker.svelte.d.ts +24 -16
- package/dist/actions/request_tracker.svelte.d.ts.map +1 -1
- package/dist/actions/request_tracker.svelte.js +24 -16
- package/dist/actions/rpc_client.d.ts +0 -1
- package/dist/actions/rpc_client.d.ts.map +1 -1
- package/dist/actions/rpc_client.js +3 -17
- package/dist/actions/socket.svelte.d.ts +35 -16
- package/dist/actions/socket.svelte.d.ts.map +1 -1
- package/dist/actions/socket.svelte.js +33 -14
- package/dist/actions/transports.d.ts +15 -5
- package/dist/actions/transports.d.ts.map +1 -1
- package/dist/actions/transports.js +15 -15
- package/dist/actions/transports_http.d.ts +7 -0
- package/dist/actions/transports_http.d.ts.map +1 -1
- package/dist/actions/transports_http.js +7 -0
- package/dist/actions/transports_ws.d.ts +13 -0
- package/dist/actions/transports_ws.d.ts.map +1 -1
- package/dist/actions/transports_ws.js +13 -0
- package/dist/actions/transports_ws_auth_guard.d.ts +6 -4
- package/dist/actions/transports_ws_auth_guard.d.ts.map +1 -1
- package/dist/actions/transports_ws_auth_guard.js +6 -4
- package/dist/actions/transports_ws_backend.d.ts +14 -1
- package/dist/actions/transports_ws_backend.d.ts.map +1 -1
- package/dist/actions/transports_ws_backend.js +14 -10
- package/dist/auth/CLAUDE.md +64 -18
- package/dist/auth/account_queries.d.ts +7 -0
- package/dist/auth/account_queries.d.ts.map +1 -1
- package/dist/auth/account_queries.js +7 -0
- package/dist/auth/admin_action_specs.d.ts +5 -0
- package/dist/auth/admin_action_specs.d.ts.map +1 -1
- package/dist/auth/admin_action_specs.js +5 -0
- package/dist/auth/admin_actions.d.ts +1 -0
- package/dist/auth/admin_actions.d.ts.map +1 -1
- package/dist/auth/admin_actions.js +1 -0
- package/dist/auth/api_token_queries.d.ts +6 -0
- package/dist/auth/api_token_queries.d.ts.map +1 -1
- package/dist/auth/api_token_queries.js +6 -0
- package/dist/auth/app_settings_queries.d.ts +4 -0
- package/dist/auth/app_settings_queries.d.ts.map +1 -1
- package/dist/auth/app_settings_queries.js +4 -0
- package/dist/auth/audit_log_queries.d.ts +5 -0
- package/dist/auth/audit_log_queries.d.ts.map +1 -1
- package/dist/auth/audit_log_queries.js +5 -0
- package/dist/auth/audit_log_routes.d.ts +2 -2
- package/dist/auth/audit_log_routes.js +2 -2
- package/dist/auth/audit_log_schema.d.ts +2 -0
- package/dist/auth/audit_log_schema.d.ts.map +1 -1
- package/dist/auth/audit_log_schema.js +134 -55
- package/dist/auth/bearer_auth.d.ts +2 -0
- package/dist/auth/bearer_auth.d.ts.map +1 -1
- package/dist/auth/bearer_auth.js +2 -0
- package/dist/auth/bootstrap_account.d.ts +3 -0
- package/dist/auth/bootstrap_account.d.ts.map +1 -1
- package/dist/auth/bootstrap_account.js +3 -0
- package/dist/auth/cleanup.d.ts +6 -0
- package/dist/auth/cleanup.d.ts.map +1 -1
- package/dist/auth/cleanup.js +6 -0
- package/dist/auth/daemon_token_middleware.d.ts +4 -0
- package/dist/auth/daemon_token_middleware.d.ts.map +1 -1
- package/dist/auth/daemon_token_middleware.js +4 -0
- package/dist/auth/invite_queries.d.ts +3 -0
- package/dist/auth/invite_queries.d.ts.map +1 -1
- package/dist/auth/invite_queries.js +3 -0
- package/dist/auth/permit_offer_action_specs.d.ts +6 -0
- package/dist/auth/permit_offer_action_specs.d.ts.map +1 -1
- package/dist/auth/permit_offer_action_specs.js +11 -0
- package/dist/auth/permit_offer_queries.d.ts +18 -0
- package/dist/auth/permit_offer_queries.d.ts.map +1 -1
- package/dist/auth/permit_offer_queries.js +18 -0
- package/dist/auth/permit_queries.d.ts +7 -0
- package/dist/auth/permit_queries.d.ts.map +1 -1
- package/dist/auth/permit_queries.js +7 -0
- package/dist/auth/request_context.d.ts +1 -0
- package/dist/auth/request_context.d.ts.map +1 -1
- package/dist/auth/request_context.js +1 -0
- package/dist/auth/role_schema.d.ts +2 -0
- package/dist/auth/role_schema.d.ts.map +1 -1
- package/dist/auth/role_schema.js +2 -0
- package/dist/auth/self_service_role_actions.d.ts +1 -0
- package/dist/auth/self_service_role_actions.d.ts.map +1 -1
- package/dist/auth/self_service_role_actions.js +1 -0
- package/dist/auth/session_lifecycle.d.ts +2 -0
- package/dist/auth/session_lifecycle.d.ts.map +1 -1
- package/dist/auth/session_lifecycle.js +2 -0
- package/dist/auth/session_middleware.d.ts +1 -0
- package/dist/auth/session_middleware.d.ts.map +1 -1
- package/dist/auth/session_middleware.js +1 -0
- package/dist/auth/session_queries.d.ts +9 -0
- package/dist/auth/session_queries.d.ts.map +1 -1
- package/dist/auth/session_queries.js +9 -0
- package/dist/cli/config.d.ts +1 -2
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +1 -2
- package/dist/cli/daemon.d.ts +6 -1
- package/dist/cli/daemon.d.ts.map +1 -1
- package/dist/cli/daemon.js +6 -1
- package/dist/db/assert_row.d.ts +2 -1
- package/dist/db/assert_row.d.ts.map +1 -1
- package/dist/db/assert_row.js +2 -1
- package/dist/db/create_db.d.ts +3 -1
- package/dist/db/create_db.d.ts.map +1 -1
- package/dist/db/create_db.js +3 -1
- package/dist/db/db.d.ts +15 -4
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +14 -3
- package/dist/db/db_pg.d.ts +4 -3
- package/dist/db/db_pg.d.ts.map +1 -1
- package/dist/db/db_pg.js +7 -5
- package/dist/db/db_pglite.d.ts +4 -4
- package/dist/db/db_pglite.js +4 -4
- package/dist/db/migrate.d.ts +7 -4
- package/dist/db/migrate.d.ts.map +1 -1
- package/dist/db/migrate.js +5 -2
- package/dist/db/sql_identifier.d.ts +2 -1
- package/dist/db/sql_identifier.d.ts.map +1 -1
- package/dist/db/sql_identifier.js +2 -1
- package/dist/db/status.d.ts +4 -1
- package/dist/db/status.d.ts.map +1 -1
- package/dist/db/status.js +5 -2
- package/dist/dev/setup.d.ts +15 -2
- package/dist/dev/setup.d.ts.map +1 -1
- package/dist/dev/setup.js +15 -2
- package/dist/env/dotenv.d.ts +2 -1
- package/dist/env/dotenv.d.ts.map +1 -1
- package/dist/env/dotenv.js +2 -1
- package/dist/env/load.d.ts +1 -3
- package/dist/env/load.d.ts.map +1 -1
- package/dist/env/load.js +1 -3
- package/dist/env/resolve.d.ts +1 -1
- package/dist/env/resolve.js +1 -1
- package/dist/env/update_env_variable.d.ts +2 -0
- package/dist/env/update_env_variable.d.ts.map +1 -1
- package/dist/env/update_env_variable.js +2 -0
- package/dist/hono_context.d.ts +2 -5
- package/dist/hono_context.d.ts.map +1 -1
- package/dist/hono_context.js +2 -5
- package/dist/http/common_routes.d.ts +0 -8
- package/dist/http/common_routes.d.ts.map +1 -1
- package/dist/http/common_routes.js +0 -8
- package/dist/http/db_routes.d.ts +0 -3
- package/dist/http/db_routes.d.ts.map +1 -1
- package/dist/http/db_routes.js +0 -3
- package/dist/http/error_schemas.d.ts +12 -11
- package/dist/http/error_schemas.d.ts.map +1 -1
- package/dist/http/error_schemas.js +11 -7
- package/dist/http/jsonrpc_errors.d.ts +0 -6
- package/dist/http/jsonrpc_errors.d.ts.map +1 -1
- package/dist/http/jsonrpc_errors.js +0 -6
- package/dist/http/origin.d.ts +6 -13
- package/dist/http/origin.d.ts.map +1 -1
- package/dist/http/origin.js +7 -14
- package/dist/http/pending_effects.d.ts +4 -0
- package/dist/http/pending_effects.d.ts.map +1 -1
- package/dist/http/pending_effects.js +4 -0
- package/dist/http/proxy.d.ts +3 -6
- package/dist/http/proxy.d.ts.map +1 -1
- package/dist/http/proxy.js +3 -6
- package/dist/http/route_spec.d.ts +14 -35
- package/dist/http/route_spec.d.ts.map +1 -1
- package/dist/http/route_spec.js +17 -22
- package/dist/http/schema_helpers.d.ts +0 -4
- package/dist/http/schema_helpers.d.ts.map +1 -1
- package/dist/http/schema_helpers.js +0 -4
- package/dist/http/surface.d.ts +2 -12
- package/dist/http/surface.d.ts.map +1 -1
- package/dist/http/surface.js +1 -12
- package/dist/rate_limiter.d.ts +30 -1
- package/dist/rate_limiter.d.ts.map +1 -1
- package/dist/rate_limiter.js +40 -1
- package/dist/realtime/sse.d.ts +7 -2
- package/dist/realtime/sse.d.ts.map +1 -1
- package/dist/realtime/sse.js +3 -2
- package/dist/realtime/sse_auth_guard.d.ts +21 -21
- package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
- package/dist/realtime/sse_auth_guard.js +24 -24
- package/dist/realtime/subscriber_registry.d.ts +4 -5
- package/dist/realtime/subscriber_registry.d.ts.map +1 -1
- package/dist/realtime/subscriber_registry.js +4 -5
- package/dist/runtime/fs.d.ts +5 -3
- package/dist/runtime/fs.d.ts.map +1 -1
- package/dist/runtime/fs.js +5 -3
- package/dist/runtime/mock.d.ts +6 -3
- package/dist/runtime/mock.d.ts.map +1 -1
- package/dist/runtime/mock.js +6 -3
- package/dist/server/app_backend.d.ts +1 -0
- package/dist/server/app_backend.d.ts.map +1 -1
- package/dist/server/app_backend.js +1 -0
- package/dist/server/app_server.d.ts +31 -5
- package/dist/server/app_server.d.ts.map +1 -1
- package/dist/server/app_server.js +23 -7
- package/dist/server/startup.d.ts +0 -2
- package/dist/server/startup.d.ts.map +1 -1
- package/dist/server/startup.js +0 -2
- package/dist/server/static.d.ts +0 -1
- package/dist/server/static.d.ts.map +1 -1
- package/dist/server/static.js +0 -1
- package/dist/server/validate_nginx.d.ts +3 -3
- package/dist/server/validate_nginx.d.ts.map +1 -1
- package/dist/server/validate_nginx.js +0 -3
- package/dist/testing/CLAUDE.md +1 -1
- package/dist/testing/admin_integration.d.ts +5 -1
- package/dist/testing/admin_integration.d.ts.map +1 -1
- package/dist/testing/admin_integration.js +8 -6
- package/dist/testing/adversarial_404.d.ts +0 -2
- package/dist/testing/adversarial_404.d.ts.map +1 -1
- package/dist/testing/adversarial_404.js +0 -2
- package/dist/testing/adversarial_headers.d.ts +5 -4
- package/dist/testing/adversarial_headers.d.ts.map +1 -1
- package/dist/testing/adversarial_headers.js +5 -4
- package/dist/testing/adversarial_input.d.ts +4 -2
- package/dist/testing/adversarial_input.d.ts.map +1 -1
- package/dist/testing/adversarial_input.js +4 -2
- package/dist/testing/app_server.d.ts +25 -0
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +11 -2
- package/dist/testing/assertions.d.ts +23 -11
- package/dist/testing/assertions.d.ts.map +1 -1
- package/dist/testing/assertions.js +23 -11
- package/dist/testing/attack_surface.d.ts +0 -4
- package/dist/testing/attack_surface.d.ts.map +1 -1
- package/dist/testing/attack_surface.js +0 -4
- package/dist/testing/audit_completeness.d.ts +4 -1
- package/dist/testing/audit_completeness.d.ts.map +1 -1
- package/dist/testing/audit_completeness.js +4 -1
- package/dist/testing/auth_apps.d.ts +5 -10
- package/dist/testing/auth_apps.d.ts.map +1 -1
- package/dist/testing/auth_apps.js +5 -10
- package/dist/testing/data_exposure.d.ts +0 -11
- package/dist/testing/data_exposure.d.ts.map +1 -1
- package/dist/testing/data_exposure.js +0 -11
- package/dist/testing/db.d.ts +9 -7
- package/dist/testing/db.d.ts.map +1 -1
- package/dist/testing/db.js +9 -7
- package/dist/testing/error_coverage.d.ts +9 -14
- package/dist/testing/error_coverage.d.ts.map +1 -1
- package/dist/testing/error_coverage.js +9 -14
- package/dist/testing/integration.d.ts +4 -1
- package/dist/testing/integration.d.ts.map +1 -1
- package/dist/testing/integration.js +4 -1
- package/dist/testing/integration_helpers.d.ts +5 -34
- package/dist/testing/integration_helpers.d.ts.map +1 -1
- package/dist/testing/integration_helpers.js +5 -41
- package/dist/testing/middleware.d.ts +5 -10
- package/dist/testing/middleware.d.ts.map +1 -1
- package/dist/testing/middleware.js +5 -10
- package/dist/testing/mock_fs.d.ts +0 -2
- package/dist/testing/mock_fs.d.ts.map +1 -1
- package/dist/testing/mock_fs.js +0 -2
- package/dist/testing/rate_limiting.d.ts +3 -1
- package/dist/testing/rate_limiting.d.ts.map +1 -1
- package/dist/testing/rate_limiting.js +3 -1
- package/dist/testing/round_trip.d.ts +0 -2
- package/dist/testing/round_trip.d.ts.map +1 -1
- package/dist/testing/round_trip.js +0 -2
- package/dist/testing/rpc_attack_surface.d.ts +0 -2
- package/dist/testing/rpc_attack_surface.d.ts.map +1 -1
- package/dist/testing/rpc_attack_surface.js +0 -2
- package/dist/testing/rpc_helpers.d.ts +21 -14
- package/dist/testing/rpc_helpers.d.ts.map +1 -1
- package/dist/testing/rpc_helpers.js +21 -14
- package/dist/testing/rpc_round_trip.d.ts +0 -2
- package/dist/testing/rpc_round_trip.d.ts.map +1 -1
- package/dist/testing/rpc_round_trip.js +0 -2
- package/dist/testing/schema_generators.d.ts +5 -3
- package/dist/testing/schema_generators.d.ts.map +1 -1
- package/dist/testing/schema_generators.js +22 -3
- package/dist/testing/sse_round_trip.d.ts +3 -1
- package/dist/testing/sse_round_trip.d.ts.map +1 -1
- package/dist/testing/sse_round_trip.js +3 -1
- package/dist/testing/standard.d.ts +0 -2
- package/dist/testing/standard.d.ts.map +1 -1
- package/dist/testing/standard.js +0 -2
- package/dist/testing/stubs.d.ts +8 -3
- package/dist/testing/stubs.d.ts.map +1 -1
- package/dist/testing/stubs.js +10 -3
- package/dist/testing/surface_invariants.d.ts +14 -3
- package/dist/testing/surface_invariants.d.ts.map +1 -1
- package/dist/testing/surface_invariants.js +14 -3
- package/dist/testing/ws_round_trip.d.ts +13 -1
- package/dist/testing/ws_round_trip.d.ts.map +1 -1
- package/dist/ui/AccountSessions.svelte +9 -0
- package/dist/ui/AccountSessions.svelte.d.ts.map +1 -1
- package/dist/ui/AdminAccounts.svelte +10 -0
- package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -1
- package/dist/ui/AdminAuditLog.svelte +10 -0
- package/dist/ui/AdminAuditLog.svelte.d.ts.map +1 -1
- package/dist/ui/AdminInvites.svelte +9 -0
- package/dist/ui/AdminInvites.svelte.d.ts.map +1 -1
- package/dist/ui/AdminOverview.svelte +10 -0
- package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
- package/dist/ui/AdminPermitHistory.svelte +9 -0
- package/dist/ui/AdminPermitHistory.svelte.d.ts.map +1 -1
- package/dist/ui/AdminSessions.svelte +10 -0
- package/dist/ui/AdminSessions.svelte.d.ts.map +1 -1
- package/dist/ui/AdminSettings.svelte +9 -0
- package/dist/ui/AdminSettings.svelte.d.ts.map +1 -1
- package/dist/ui/AdminSurface.svelte +9 -0
- package/dist/ui/AdminSurface.svelte.d.ts.map +1 -1
- package/dist/ui/AppShell.svelte +24 -0
- package/dist/ui/AppShell.svelte.d.ts +23 -0
- package/dist/ui/AppShell.svelte.d.ts.map +1 -1
- package/dist/ui/BootstrapForm.svelte +17 -0
- package/dist/ui/BootstrapForm.svelte.d.ts +4 -0
- package/dist/ui/BootstrapForm.svelte.d.ts.map +1 -1
- package/dist/ui/CLAUDE.md +1 -1
- package/dist/ui/ColumnLayout.svelte +11 -0
- package/dist/ui/ColumnLayout.svelte.d.ts +10 -0
- package/dist/ui/ColumnLayout.svelte.d.ts.map +1 -1
- package/dist/ui/Datatable.svelte +18 -0
- package/dist/ui/Datatable.svelte.d.ts +17 -0
- package/dist/ui/Datatable.svelte.d.ts.map +1 -1
- package/dist/ui/LoginForm.svelte +18 -0
- package/dist/ui/LoginForm.svelte.d.ts +9 -0
- package/dist/ui/LoginForm.svelte.d.ts.map +1 -1
- package/dist/ui/LogoutButton.svelte +9 -0
- package/dist/ui/LogoutButton.svelte.d.ts +8 -0
- package/dist/ui/LogoutButton.svelte.d.ts.map +1 -1
- package/dist/ui/MenuLink.svelte +10 -0
- package/dist/ui/MenuLink.svelte.d.ts +9 -0
- package/dist/ui/MenuLink.svelte.d.ts.map +1 -1
- package/dist/ui/OpenSignupToggle.svelte +9 -0
- package/dist/ui/OpenSignupToggle.svelte.d.ts.map +1 -1
- package/dist/ui/SignupForm.svelte +16 -0
- package/dist/ui/SignupForm.svelte.d.ts +4 -0
- package/dist/ui/SignupForm.svelte.d.ts.map +1 -1
- package/dist/ui/SurfaceExplorer.svelte +9 -0
- package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -1
- package/dist/ui/audit_log_state.svelte.d.ts +6 -1
- package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
- package/dist/ui/audit_log_state.svelte.js +7 -2
- package/dist/ui/auth_state.svelte.d.ts +16 -4
- package/dist/ui/auth_state.svelte.d.ts.map +1 -1
- package/dist/ui/auth_state.svelte.js +16 -4
- package/dist/ui/form_state.svelte.d.ts +9 -0
- package/dist/ui/form_state.svelte.d.ts.map +1 -1
- package/dist/ui/form_state.svelte.js +9 -0
- package/dist/ui/loadable.svelte.d.ts +6 -1
- package/dist/ui/loadable.svelte.d.ts.map +1 -1
- package/dist/ui/loadable.svelte.js +6 -1
- package/dist/ui/permit_offers_state.svelte.d.ts +2 -0
- package/dist/ui/permit_offers_state.svelte.d.ts.map +1 -1
- package/dist/ui/permit_offers_state.svelte.js +2 -0
- package/dist/ui/popover.svelte.d.ts +17 -4
- package/dist/ui/popover.svelte.d.ts.map +1 -1
- package/dist/ui/popover.svelte.js +17 -4
- package/dist/ui/position_helpers.d.ts +1 -3
- package/dist/ui/position_helpers.d.ts.map +1 -1
- package/dist/ui/position_helpers.js +1 -3
- package/dist/ui/sidebar_state.svelte.d.ts +21 -9
- package/dist/ui/sidebar_state.svelte.d.ts.map +1 -1
- package/dist/ui/sidebar_state.svelte.js +16 -2
- package/dist/ui/table_state.svelte.d.ts +14 -0
- package/dist/ui/table_state.svelte.d.ts.map +1 -1
- package/dist/ui/table_state.svelte.js +14 -0
- package/dist/ui/ui_fetch.d.ts +1 -7
- package/dist/ui/ui_fetch.d.ts.map +1 -1
- package/dist/ui/ui_fetch.js +1 -7
- package/dist/ui/ui_format.d.ts +2 -14
- package/dist/ui/ui_format.d.ts.map +1 -1
- package/dist/ui/ui_format.js +2 -14
- package/package.json +2 -2
|
@@ -5,10 +5,8 @@
|
|
|
5
5
|
* auth, side effects, and input/output schemas. Bridge functions in
|
|
6
6
|
* `actions/action_bridge.ts` derive `RouteSpec` and `EventSpec` from them.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Current state: bridge is stable, registry and codegen are partially stub API.
|
|
11
|
-
* Search for `@action-system-review` across the actions/ and routes/ modules.
|
|
8
|
+
* @see `actions/action_rpc.ts` for the JSON-RPC dispatcher
|
|
9
|
+
* @see `actions/register_action_ws.ts` for the WebSocket dispatcher
|
|
12
10
|
*
|
|
13
11
|
* @module
|
|
14
12
|
*/
|
|
@@ -59,6 +57,40 @@ export declare const ActionSpec: z.ZodObject<{
|
|
|
59
57
|
* consumer-side concern.
|
|
60
58
|
*/
|
|
61
59
|
streams: z.ZodOptional<z.ZodString>;
|
|
60
|
+
/**
|
|
61
|
+
* Error reason codes this action may surface via `error.data.reason` on
|
|
62
|
+
* failure. Declarative metadata mirroring the `streams` precedent —
|
|
63
|
+
* codegen, UI form-state matching, and docs read it off the spec instead
|
|
64
|
+
* of scanning handler implementations. Reuses the same `as const` string
|
|
65
|
+
* constants the handler throws (e.g. `ERROR_OFFER_*`) so call sites can
|
|
66
|
+
* import either side. Optional — actions that surface only standard
|
|
67
|
+
* transport errors leave it unset.
|
|
68
|
+
*/
|
|
69
|
+
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
70
|
+
/**
|
|
71
|
+
* Rate limit key the RPC dispatcher consults for this action. Optional —
|
|
72
|
+
* actions without it skip the rate-limit hook entirely.
|
|
73
|
+
*
|
|
74
|
+
* - `'ip'` — keyed on the resolved client IP (`get_client_ip(c)`).
|
|
75
|
+
* - `'account'` — keyed on the post-auth actor id (`request_context.actor.id`).
|
|
76
|
+
* Registration-time error if paired with `auth: 'public'` (no actor).
|
|
77
|
+
* - `'both'` — both checks run; either can block.
|
|
78
|
+
*
|
|
79
|
+
* Throttle-requests semantics — every invocation records, regardless of
|
|
80
|
+
* outcome (different from REST login's throttle-failures, which resets
|
|
81
|
+
* on success). Suits admin mutation oracles (`invite_create` account-
|
|
82
|
+
* existence probe) where the *successful* invocation is the threat.
|
|
83
|
+
*
|
|
84
|
+
* Today only `RequestResponseActionSpec` is consulted by the RPC
|
|
85
|
+
* dispatcher. The field is on the base for shape symmetry with
|
|
86
|
+
* `streams` and `error_reasons`; remote_notification / local_call
|
|
87
|
+
* dispatchers don't read it.
|
|
88
|
+
*/
|
|
89
|
+
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
90
|
+
account: "account";
|
|
91
|
+
ip: "ip";
|
|
92
|
+
both: "both";
|
|
93
|
+
}>>;
|
|
62
94
|
}, z.core.$strict>;
|
|
63
95
|
export type ActionSpec = z.infer<typeof ActionSpec>;
|
|
64
96
|
export declare const RequestResponseActionSpec: z.ZodObject<{
|
|
@@ -73,6 +105,12 @@ export declare const RequestResponseActionSpec: z.ZodObject<{
|
|
|
73
105
|
output: z.ZodCustom<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
|
|
74
106
|
description: z.ZodString;
|
|
75
107
|
streams: z.ZodOptional<z.ZodString>;
|
|
108
|
+
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
109
|
+
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
110
|
+
account: "account";
|
|
111
|
+
ip: "ip";
|
|
112
|
+
both: "both";
|
|
113
|
+
}>>;
|
|
76
114
|
kind: z.ZodDefault<z.ZodLiteral<"request_response">>;
|
|
77
115
|
auth: z.ZodUnion<readonly [z.ZodLiteral<"public">, z.ZodLiteral<"authenticated">, z.ZodLiteral<"keeper">, z.ZodObject<{
|
|
78
116
|
role: z.ZodString;
|
|
@@ -90,6 +128,12 @@ export declare const RemoteNotificationActionSpec: z.ZodObject<{
|
|
|
90
128
|
input: z.ZodCustom<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
|
|
91
129
|
description: z.ZodString;
|
|
92
130
|
streams: z.ZodOptional<z.ZodString>;
|
|
131
|
+
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
132
|
+
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
133
|
+
account: "account";
|
|
134
|
+
ip: "ip";
|
|
135
|
+
both: "both";
|
|
136
|
+
}>>;
|
|
93
137
|
kind: z.ZodDefault<z.ZodLiteral<"remote_notification">>;
|
|
94
138
|
auth: z.ZodDefault<z.ZodNull>;
|
|
95
139
|
side_effects: z.ZodDefault<z.ZodLiteral<true>>;
|
|
@@ -98,8 +142,8 @@ export declare const RemoteNotificationActionSpec: z.ZodObject<{
|
|
|
98
142
|
}, z.core.$strict>;
|
|
99
143
|
export type RemoteNotificationActionSpec = z.infer<typeof RemoteNotificationActionSpec>;
|
|
100
144
|
/**
|
|
101
|
-
* Local calls can wrap synchronous or asynchronous actions,
|
|
102
|
-
*
|
|
145
|
+
* Local calls can wrap synchronous or asynchronous actions, and are the
|
|
146
|
+
* escape hatch for remote APIs that do not support SAES.
|
|
103
147
|
*/
|
|
104
148
|
export declare const LocalCallActionSpec: z.ZodObject<{
|
|
105
149
|
method: z.ZodString;
|
|
@@ -114,6 +158,12 @@ export declare const LocalCallActionSpec: z.ZodObject<{
|
|
|
114
158
|
async: z.ZodBoolean;
|
|
115
159
|
description: z.ZodString;
|
|
116
160
|
streams: z.ZodOptional<z.ZodString>;
|
|
161
|
+
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
162
|
+
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
163
|
+
account: "account";
|
|
164
|
+
ip: "ip";
|
|
165
|
+
both: "both";
|
|
166
|
+
}>>;
|
|
117
167
|
kind: z.ZodDefault<z.ZodLiteral<"local_call">>;
|
|
118
168
|
auth: z.ZodDefault<z.ZodNull>;
|
|
119
169
|
}, z.core.$strict>;
|
|
@@ -130,6 +180,12 @@ export declare const ActionSpecUnion: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
130
180
|
output: z.ZodCustom<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
|
|
131
181
|
description: z.ZodString;
|
|
132
182
|
streams: z.ZodOptional<z.ZodString>;
|
|
183
|
+
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
184
|
+
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
185
|
+
account: "account";
|
|
186
|
+
ip: "ip";
|
|
187
|
+
both: "both";
|
|
188
|
+
}>>;
|
|
133
189
|
kind: z.ZodDefault<z.ZodLiteral<"request_response">>;
|
|
134
190
|
auth: z.ZodUnion<readonly [z.ZodLiteral<"public">, z.ZodLiteral<"authenticated">, z.ZodLiteral<"keeper">, z.ZodObject<{
|
|
135
191
|
role: z.ZodString;
|
|
@@ -145,6 +201,12 @@ export declare const ActionSpecUnion: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
145
201
|
input: z.ZodCustom<z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>, z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
|
|
146
202
|
description: z.ZodString;
|
|
147
203
|
streams: z.ZodOptional<z.ZodString>;
|
|
204
|
+
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
205
|
+
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
206
|
+
account: "account";
|
|
207
|
+
ip: "ip";
|
|
208
|
+
both: "both";
|
|
209
|
+
}>>;
|
|
148
210
|
kind: z.ZodDefault<z.ZodLiteral<"remote_notification">>;
|
|
149
211
|
auth: z.ZodDefault<z.ZodNull>;
|
|
150
212
|
side_effects: z.ZodDefault<z.ZodLiteral<true>>;
|
|
@@ -163,10 +225,17 @@ export declare const ActionSpecUnion: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
163
225
|
async: z.ZodBoolean;
|
|
164
226
|
description: z.ZodString;
|
|
165
227
|
streams: z.ZodOptional<z.ZodString>;
|
|
228
|
+
error_reasons: z.ZodOptional<z.ZodReadonly<z.ZodArray<z.ZodString>>>;
|
|
229
|
+
rate_limit: z.ZodOptional<z.ZodEnum<{
|
|
230
|
+
account: "account";
|
|
231
|
+
ip: "ip";
|
|
232
|
+
both: "both";
|
|
233
|
+
}>>;
|
|
166
234
|
kind: z.ZodDefault<z.ZodLiteral<"local_call">>;
|
|
167
235
|
auth: z.ZodDefault<z.ZodNull>;
|
|
168
236
|
}, z.core.$strict>]>;
|
|
169
237
|
export type ActionSpecUnion = z.infer<typeof ActionSpecUnion>;
|
|
238
|
+
/** Structural type guard for any `ActionSpecUnion` variant — checks `kind` is one of the three known values. */
|
|
170
239
|
export declare const is_action_spec: (value: unknown) => value is ActionSpecUnion;
|
|
171
240
|
export declare const ActionEventPhase: z.ZodEnum<{
|
|
172
241
|
send_request: "send_request";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action_spec.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_spec.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"action_spec.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAItB,eAAO,MAAM,UAAU;;;;EAAoE,CAAC;AAC5F,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD,eAAO,MAAM,eAAe;;;;EAA0C,CAAC;AACvE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,eAAO,MAAM,UAAU;;oBAKrB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAC7C,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;IAUtB;;;;;;OAMG;;IAEH;;;;;;;;OAQG;;IAEH;;;;;;;;;;;;;;;;;;OAkBG;;;;;;kBAEF,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAEpD,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;kBAIpC,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAElF,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;kBAMvC,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAExF;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;kBAG9B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEtE,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAI1B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9D,gHAAgH;AAChH,eAAO,MAAM,cAAc,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,eAKoB,CAAC;AAE9E,eAAO,MAAM,gBAAgB;;;;;;;;;;EAU3B,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
|
|
@@ -5,14 +5,13 @@
|
|
|
5
5
|
* auth, side effects, and input/output schemas. Bridge functions in
|
|
6
6
|
* `actions/action_bridge.ts` derive `RouteSpec` and `EventSpec` from them.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Current state: bridge is stable, registry and codegen are partially stub API.
|
|
11
|
-
* Search for `@action-system-review` across the actions/ and routes/ modules.
|
|
8
|
+
* @see `actions/action_rpc.ts` for the JSON-RPC dispatcher
|
|
9
|
+
* @see `actions/register_action_ws.ts` for the WebSocket dispatcher
|
|
12
10
|
*
|
|
13
11
|
* @module
|
|
14
12
|
*/
|
|
15
13
|
import { z } from 'zod';
|
|
14
|
+
import { RateLimitKey } from '../http/error_schemas.js';
|
|
16
15
|
export const ActionKind = z.enum(['request_response', 'remote_notification', 'local_call']);
|
|
17
16
|
export const ActionInitiator = z.enum(['frontend', 'backend', 'both']);
|
|
18
17
|
export const ActionAuth = z.union([
|
|
@@ -40,6 +39,36 @@ export const ActionSpec = z.strictObject({
|
|
|
40
39
|
* consumer-side concern.
|
|
41
40
|
*/
|
|
42
41
|
streams: z.string().optional(),
|
|
42
|
+
/**
|
|
43
|
+
* Error reason codes this action may surface via `error.data.reason` on
|
|
44
|
+
* failure. Declarative metadata mirroring the `streams` precedent —
|
|
45
|
+
* codegen, UI form-state matching, and docs read it off the spec instead
|
|
46
|
+
* of scanning handler implementations. Reuses the same `as const` string
|
|
47
|
+
* constants the handler throws (e.g. `ERROR_OFFER_*`) so call sites can
|
|
48
|
+
* import either side. Optional — actions that surface only standard
|
|
49
|
+
* transport errors leave it unset.
|
|
50
|
+
*/
|
|
51
|
+
error_reasons: z.array(z.string()).readonly().optional(),
|
|
52
|
+
/**
|
|
53
|
+
* Rate limit key the RPC dispatcher consults for this action. Optional —
|
|
54
|
+
* actions without it skip the rate-limit hook entirely.
|
|
55
|
+
*
|
|
56
|
+
* - `'ip'` — keyed on the resolved client IP (`get_client_ip(c)`).
|
|
57
|
+
* - `'account'` — keyed on the post-auth actor id (`request_context.actor.id`).
|
|
58
|
+
* Registration-time error if paired with `auth: 'public'` (no actor).
|
|
59
|
+
* - `'both'` — both checks run; either can block.
|
|
60
|
+
*
|
|
61
|
+
* Throttle-requests semantics — every invocation records, regardless of
|
|
62
|
+
* outcome (different from REST login's throttle-failures, which resets
|
|
63
|
+
* on success). Suits admin mutation oracles (`invite_create` account-
|
|
64
|
+
* existence probe) where the *successful* invocation is the threat.
|
|
65
|
+
*
|
|
66
|
+
* Today only `RequestResponseActionSpec` is consulted by the RPC
|
|
67
|
+
* dispatcher. The field is on the base for shape symmetry with
|
|
68
|
+
* `streams` and `error_reasons`; remote_notification / local_call
|
|
69
|
+
* dispatchers don't read it.
|
|
70
|
+
*/
|
|
71
|
+
rate_limit: RateLimitKey.optional(),
|
|
43
72
|
});
|
|
44
73
|
export const RequestResponseActionSpec = ActionSpec.extend({
|
|
45
74
|
kind: z.literal('request_response').default('request_response'),
|
|
@@ -54,8 +83,8 @@ export const RemoteNotificationActionSpec = ActionSpec.extend({
|
|
|
54
83
|
async: z.literal(true).default(true),
|
|
55
84
|
});
|
|
56
85
|
/**
|
|
57
|
-
* Local calls can wrap synchronous or asynchronous actions,
|
|
58
|
-
*
|
|
86
|
+
* Local calls can wrap synchronous or asynchronous actions, and are the
|
|
87
|
+
* escape hatch for remote APIs that do not support SAES.
|
|
59
88
|
*/
|
|
60
89
|
export const LocalCallActionSpec = ActionSpec.extend({
|
|
61
90
|
kind: z.literal('local_call').default('local_call'),
|
|
@@ -66,6 +95,7 @@ export const ActionSpecUnion = z.union([
|
|
|
66
95
|
RemoteNotificationActionSpec,
|
|
67
96
|
LocalCallActionSpec,
|
|
68
97
|
]);
|
|
98
|
+
/** Structural type guard for any `ActionSpecUnion` variant — checks `kind` is one of the three known values. */
|
|
69
99
|
export const is_action_spec = (value) => value !== null &&
|
|
70
100
|
typeof value === 'object' &&
|
|
71
101
|
'method' in value &&
|
|
@@ -142,14 +142,6 @@ export interface FrontendRpcClient<TApi> {
|
|
|
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
|
}
|
|
145
|
-
/**
|
|
146
|
-
* Build a frontend-only typed RPC client.
|
|
147
|
-
*
|
|
148
|
-
* @param options - `specs` (required), optional `path` / `transports` /
|
|
149
|
-
* `transport_for_method` / `on_action_event`
|
|
150
|
-
* @returns `{api, api_result, peer, environment}` — both Proxy shapes plus
|
|
151
|
-
* the underlying primitives. `api` throws on `{ok: false}`; `api_result`
|
|
152
|
-
* returns the Result.
|
|
153
|
-
*/
|
|
145
|
+
/** Build a frontend-only typed RPC client. See module doc for the bundle's design. */
|
|
154
146
|
export declare const create_frontend_rpc_client: <TApi extends object>(options: CreateFrontendRpcClientOptions<TApi>) => FrontendRpcClient<TApi>;
|
|
155
147
|
//# sourceMappingURL=frontend_rpc_client.d.ts.map
|
|
@@ -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,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAC5C,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,UAAU,CAAC;IACjB,sHAAsH;IACtH,WAAW,EAAE,sBAAsB,CAAC;CACpC;AAED
|
|
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,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAC5C,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,UAAU,CAAC;IACjB,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"}
|
|
@@ -50,15 +50,7 @@ import { ActionPeer } from './action_peer.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';
|
|
53
|
-
/**
|
|
54
|
-
* Build a frontend-only typed RPC client.
|
|
55
|
-
*
|
|
56
|
-
* @param options - `specs` (required), optional `path` / `transports` /
|
|
57
|
-
* `transport_for_method` / `on_action_event`
|
|
58
|
-
* @returns `{api, api_result, peer, environment}` — both Proxy shapes plus
|
|
59
|
-
* the underlying primitives. `api` throws on `{ok: false}`; `api_result`
|
|
60
|
-
* returns the Result.
|
|
61
|
-
*/
|
|
53
|
+
/** Build a frontend-only typed RPC client. See module doc for the bundle's design. */
|
|
62
54
|
export const create_frontend_rpc_client = (options) => {
|
|
63
55
|
const registry = new ActionRegistry([...options.specs]);
|
|
64
56
|
const environment = {
|
|
@@ -32,6 +32,7 @@ import type { Context, Hono } from 'hono';
|
|
|
32
32
|
import type { UpgradeWebSocket, WSContext } from 'hono/ws';
|
|
33
33
|
import { type Logger as LoggerType } from '@fuzdev/fuz_util/log.js';
|
|
34
34
|
import type { Uuid } from '@fuzdev/fuz_util/id.js';
|
|
35
|
+
import type { RateLimiter } from '../rate_limiter.js';
|
|
35
36
|
import { type Action, type BaseHandlerContext, type WsActionHandler } from './action_types.js';
|
|
36
37
|
import { BackendWebsocketTransport, type ConnectionIdentity } from './transports_ws_backend.js';
|
|
37
38
|
export type { Action, BaseHandlerContext, WsActionHandler };
|
|
@@ -140,6 +141,21 @@ export interface RegisterActionWsOptions<TCtx extends BaseHandlerContext> {
|
|
|
140
141
|
* down the transport's internal state. Errors are logged and swallowed.
|
|
141
142
|
*/
|
|
142
143
|
on_socket_close?: (ctx: SocketCloseContext) => void | Promise<void>;
|
|
144
|
+
/**
|
|
145
|
+
* Per-IP rate limiter consulted for actions whose spec declares
|
|
146
|
+
* `rate_limit: 'ip'` or `'both'`. `null` (or omitted) disables the
|
|
147
|
+
* IP check. Same limiter is shared with the HTTP RPC dispatcher so
|
|
148
|
+
* one budget covers both transports per action. Resolved at upgrade
|
|
149
|
+
* time and reused for every message on the socket.
|
|
150
|
+
*/
|
|
151
|
+
action_ip_rate_limiter?: RateLimiter | null;
|
|
152
|
+
/**
|
|
153
|
+
* Per-actor rate limiter consulted for actions whose spec declares
|
|
154
|
+
* `rate_limit: 'account'` or `'both'`. Keyed on
|
|
155
|
+
* `request_context.actor.id`. `null` (or omitted) disables the
|
|
156
|
+
* account check. Same limiter is shared with the HTTP RPC dispatcher.
|
|
157
|
+
*/
|
|
158
|
+
action_account_rate_limiter?: RateLimiter | null;
|
|
143
159
|
}
|
|
144
160
|
/** Result of `register_action_ws`. */
|
|
145
161
|
export interface RegisterActionWsResult {
|
|
@@ -163,6 +179,9 @@ export interface RegisterActionWsResult {
|
|
|
163
179
|
*
|
|
164
180
|
* @returns the transport (supplied or freshly created) — retain it to wire
|
|
165
181
|
* `create_ws_auth_guard` or broadcast on audit events.
|
|
182
|
+
* @mutates options.app - registers a `GET path` route via `upgradeWebSocket`
|
|
183
|
+
* @mutates options.transport - on every message, adds/removes connections
|
|
184
|
+
* in the transport's internal maps via `add_connection` / `remove_connection`
|
|
166
185
|
*/
|
|
167
186
|
export declare const register_action_ws: <TCtx extends BaseHandlerContext>(options: RegisterActionWsOptions<TCtx>) => RegisterActionWsResult;
|
|
168
187
|
//# sourceMappingURL=register_action_ws.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register_action_ws.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/register_action_ws.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,KAAK,EAAC,OAAO,EAAE,IAAI,EAAC,MAAM,MAAM,CAAC;AACxC,OAAO,KAAK,EAAC,gBAAgB,EAAE,SAAS,EAAC,MAAM,SAAS,CAAC;AAEzD,OAAO,EAAS,KAAK,MAAM,IAAI,UAAU,EAAC,MAAM,yBAAyB,CAAC;AAC1E,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"register_action_ws.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/register_action_ws.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,KAAK,EAAC,OAAO,EAAE,IAAI,EAAC,MAAM,MAAM,CAAC;AACxC,OAAO,KAAK,EAAC,gBAAgB,EAAE,SAAS,EAAC,MAAM,SAAS,CAAC;AAEzD,OAAO,EAAS,KAAK,MAAM,IAAI,UAAU,EAAC,MAAM,yBAAyB,CAAC;AAC1E,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,wBAAwB,CAAC;AAMjD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAapD,OAAO,EAAC,KAAK,MAAM,EAAE,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAG7F,OAAO,EAAC,yBAAyB,EAAE,KAAK,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AAE9F,YAAY,EAAC,MAAM,EAAE,kBAAkB,EAAE,eAAe,EAAC,CAAC;AAE1D,0EAA0E;AAC1E,eAAO,MAAM,gCAAgC,QAAS,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IACjC,qFAAqF;IACrF,EAAE,EAAE,SAAS,CAAC;IACd,4EAA4E;IAC5E,aAAa,EAAE,IAAI,CAAC;IACpB,oDAAoD;IACpD,QAAQ,EAAE,kBAAkB,CAAC;IAC7B;;;OAGG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD,wFAAwF;IACxF,MAAM,EAAE,WAAW,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IAClC,+CAA+C;IAC/C,EAAE,EAAE,SAAS,CAAC;IACd,2CAA2C;IAC3C,aAAa,EAAE,IAAI,CAAC;IACpB,kGAAkG;IAClG,QAAQ,EAAE,kBAAkB,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAsB;IACtC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wCAAwC;AACxC,MAAM,WAAW,uBAAuB,CAAC,IAAI,SAAS,kBAAkB;IACvE,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,GAAG,EAAE,IAAI,CAAC;IACV,iEAAiE;IACjE,gBAAgB,EAAE,gBAAgB,CAAC;IACnC;;;;;;;OAOG;IACH,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACrC;;;;;OAKG;IACH,cAAc,EAAE,CAAC,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/D;;;;OAIG;IACH,SAAS,CAAC,EAAE,yBAAyB,CAAC;IACtC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,sBAAsB,CAAC;IAC7C,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qDAAqD;IACrD,GAAG,CAAC,EAAE,UAAU,CAAC;IACjB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE;;;;;OAKG;IACH,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE;;;;;;OAMG;IACH,sBAAsB,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5C;;;;;OAKG;IACH,2BAA2B,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CACjD;AAED,sCAAsC;AACtC,MAAM,WAAW,sBAAsB;IACtC,yEAAyE;IACzE,SAAS,EAAE,yBAAyB,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,kBAAkB,GAAI,IAAI,SAAS,kBAAkB,EACjE,SAAS,uBAAuB,CAAC,IAAI,CAAC,KACpC,sBAmaF,CAAC"}
|
|
@@ -34,6 +34,7 @@ import { Logger } from '@fuzdev/fuz_util/log.js';
|
|
|
34
34
|
import { get_request_context, has_role } from '../auth/request_context.js';
|
|
35
35
|
import { hash_session_token } from '../auth/session_queries.js';
|
|
36
36
|
import { ROLE_KEEPER } from '../auth/role_schema.js';
|
|
37
|
+
import { get_client_ip } from '../http/proxy.js';
|
|
37
38
|
import { JSONRPC_VERSION } from '../http/jsonrpc.js';
|
|
38
39
|
import { jsonrpc_error_messages, ThrownJsonrpcError } from '../http/jsonrpc_errors.js';
|
|
39
40
|
import { create_jsonrpc_error_response, create_jsonrpc_error_response_from_thrown, create_jsonrpc_notification, to_jsonrpc_message_id, to_jsonrpc_params, is_jsonrpc_request, } from '../http/jsonrpc_helpers.js';
|
|
@@ -61,9 +62,12 @@ export const DEFAULT_SERVER_HEARTBEAT_TIMEOUT = 60_000;
|
|
|
61
62
|
*
|
|
62
63
|
* @returns the transport (supplied or freshly created) — retain it to wire
|
|
63
64
|
* `create_ws_auth_guard` or broadcast on audit events.
|
|
65
|
+
* @mutates options.app - registers a `GET path` route via `upgradeWebSocket`
|
|
66
|
+
* @mutates options.transport - on every message, adds/removes connections
|
|
67
|
+
* in the transport's internal maps via `add_connection` / `remove_connection`
|
|
64
68
|
*/
|
|
65
69
|
export const register_action_ws = (options) => {
|
|
66
|
-
const { path, app, upgradeWebSocket, actions, extend_context, transport = new BackendWebsocketTransport(), heartbeat = true, artificial_delay = 0, log = new Logger('[ws]'), on_socket_open, on_socket_close, } = options;
|
|
70
|
+
const { path, app, upgradeWebSocket, actions, extend_context, transport = new BackendWebsocketTransport(), heartbeat = true, artificial_delay = 0, log = new Logger('[ws]'), on_socket_open, on_socket_close, action_ip_rate_limiter = null, action_account_rate_limiter = null, } = options;
|
|
67
71
|
// Fan the unified actions array into the two lookups the dispatcher
|
|
68
72
|
// consults at message time. Keeping them internal means the composable
|
|
69
73
|
// `{spec, handler}` tuple remains the only shape consumers name.
|
|
@@ -73,6 +77,12 @@ export const register_action_ws = (options) => {
|
|
|
73
77
|
spec_by_method.set(action.spec.method, action.spec);
|
|
74
78
|
if (action.handler)
|
|
75
79
|
handlers[action.spec.method] = action.handler;
|
|
80
|
+
// Reject account-keyed rate limiting on public actions — the dispatcher
|
|
81
|
+
// has no actor to key on. Mirrors the HTTP RPC registration check.
|
|
82
|
+
if ((action.spec.rate_limit === 'account' || action.spec.rate_limit === 'both') &&
|
|
83
|
+
action.spec.auth === 'public') {
|
|
84
|
+
throw new Error(`WS action "${action.spec.method}" declares rate_limit: '${action.spec.rate_limit}' but auth: 'public' — no actor available for account-keyed limiting. Use 'ip' or change auth.`);
|
|
85
|
+
}
|
|
76
86
|
}
|
|
77
87
|
const heartbeat_enabled = heartbeat !== false;
|
|
78
88
|
const heartbeat_config = typeof heartbeat === 'object' ? heartbeat : {};
|
|
@@ -87,6 +97,10 @@ export const register_action_ws = (options) => {
|
|
|
87
97
|
// non-null by the time we get here.
|
|
88
98
|
const request_context = get_request_context(c);
|
|
89
99
|
const account_id = request_context.account.id;
|
|
100
|
+
// Resolved at upgrade — every message on this socket shares the
|
|
101
|
+
// same client IP, so we capture once and reuse for rate-limit
|
|
102
|
+
// keying. `'unknown'` if the proxy middleware wasn't in the stack.
|
|
103
|
+
const client_ip = get_client_ip(c);
|
|
90
104
|
const credential_type = c.get(CREDENTIAL_TYPE_KEY);
|
|
91
105
|
// Session-based connections have a token hash for targeted revocation.
|
|
92
106
|
// Bearer/daemon connections pass null — still reachable via
|
|
@@ -245,6 +259,35 @@ export const register_action_ws = (options) => {
|
|
|
245
259
|
return;
|
|
246
260
|
}
|
|
247
261
|
}
|
|
262
|
+
// Rate limit — throttle-requests semantics, mirrors the HTTP RPC
|
|
263
|
+
// dispatcher. Same limiters are shared across transports so an
|
|
264
|
+
// attacker can't bypass the budget by switching from RPC to WS.
|
|
265
|
+
const rate_limit = spec.rate_limit;
|
|
266
|
+
if (rate_limit) {
|
|
267
|
+
const ip_check = action_ip_rate_limiter && (rate_limit === 'ip' || rate_limit === 'both');
|
|
268
|
+
const account_check = action_account_rate_limiter && (rate_limit === 'account' || rate_limit === 'both');
|
|
269
|
+
const send_rate_limited = (retry_after) => {
|
|
270
|
+
ws.send(JSON.stringify(create_jsonrpc_error_response(id, jsonrpc_error_messages.rate_limited('rate limited', { retry_after }))));
|
|
271
|
+
};
|
|
272
|
+
if (ip_check) {
|
|
273
|
+
const result = action_ip_rate_limiter.check(client_ip);
|
|
274
|
+
if (!result.allowed) {
|
|
275
|
+
send_rate_limited(result.retry_after);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
if (account_check) {
|
|
280
|
+
const result = action_account_rate_limiter.check(request_context.actor.id);
|
|
281
|
+
if (!result.allowed) {
|
|
282
|
+
send_rate_limited(result.retry_after);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (ip_check)
|
|
287
|
+
action_ip_rate_limiter.record(client_ip);
|
|
288
|
+
if (account_check)
|
|
289
|
+
action_account_rate_limiter.record(request_context.actor.id);
|
|
290
|
+
}
|
|
248
291
|
// Look up handler — method is validated against spec_by_method above.
|
|
249
292
|
const handler = handlers[method];
|
|
250
293
|
if (!handler) {
|
|
@@ -41,6 +41,9 @@ export interface RegisterWsEndpointOptions<TCtx extends BaseHandlerContext> exte
|
|
|
41
41
|
* Returns the `BackendWebsocketTransport` (supplied or freshly
|
|
42
42
|
* created), same as `register_action_ws` — retain it to wire
|
|
43
43
|
* `create_ws_auth_guard` on `on_audit_event` or to broadcast.
|
|
44
|
+
*
|
|
45
|
+
* @mutates options.app - applies origin/auth/role middleware via `app.use`,
|
|
46
|
+
* then registers the `GET path` route via the inner `register_action_ws`
|
|
44
47
|
*/
|
|
45
48
|
export declare const register_ws_endpoint: <TCtx extends BaseHandlerContext>(options: RegisterWsEndpointOptions<TCtx>) => RegisterActionWsResult;
|
|
46
49
|
//# sourceMappingURL=register_ws_endpoint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register_ws_endpoint.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/register_ws_endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAEN,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,mBAAmB,CAAC;AAE1D,0CAA0C;AAC1C,MAAM,WAAW,yBAAyB,CACzC,IAAI,SAAS,kBAAkB,CAC9B,SAAQ,uBAAuB,CAAC,IAAI,CAAC;IACtC;;;;OAIG;IACH,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,QAAQ,CAAC;CACzB;AAED
|
|
1
|
+
{"version":3,"file":"register_ws_endpoint.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/register_ws_endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAEN,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,mBAAmB,CAAC;AAE1D,0CAA0C;AAC1C,MAAM,WAAW,yBAAyB,CACzC,IAAI,SAAS,kBAAkB,CAC9B,SAAQ,uBAAuB,CAAC,IAAI,CAAC;IACtC;;;;OAIG;IACH,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,QAAQ,CAAC;CACzB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,GAAI,IAAI,SAAS,kBAAkB,EACnE,SAAS,yBAAyB,CAAC,IAAI,CAAC,KACtC,sBAUF,CAAC"}
|
|
@@ -26,6 +26,9 @@ import { register_action_ws, } from './register_action_ws.js';
|
|
|
26
26
|
* Returns the `BackendWebsocketTransport` (supplied or freshly
|
|
27
27
|
* created), same as `register_action_ws` — retain it to wire
|
|
28
28
|
* `create_ws_auth_guard` on `on_audit_event` or to broadcast.
|
|
29
|
+
*
|
|
30
|
+
* @mutates options.app - applies origin/auth/role middleware via `app.use`,
|
|
31
|
+
* then registers the `GET path` route via the inner `register_action_ws`
|
|
29
32
|
*/
|
|
30
33
|
export const register_ws_endpoint = (options) => {
|
|
31
34
|
const { app, path, allowed_origins, required_role, log = new Logger('[ws]'), ...rest } = options;
|
|
@@ -12,9 +12,6 @@ import { type JsonrpcErrorResponse, type JsonrpcRequestId, type JsonrpcResponseO
|
|
|
12
12
|
type Datetime = string & {
|
|
13
13
|
readonly __brand: 'Datetime';
|
|
14
14
|
};
|
|
15
|
-
/**
|
|
16
|
-
* Represents a pending request with its associated state.
|
|
17
|
-
*/
|
|
18
15
|
export declare class RequestTrackerItem {
|
|
19
16
|
readonly id: JsonrpcRequestId;
|
|
20
17
|
readonly deferred: Deferred<JsonrpcResponseOrError>;
|
|
@@ -24,29 +21,35 @@ export declare class RequestTrackerItem {
|
|
|
24
21
|
constructor(id: JsonrpcRequestId, deferred: Deferred<JsonrpcResponseOrError>, created: Datetime, status: AsyncStatus, timeout: NodeJS.Timeout | undefined);
|
|
25
22
|
}
|
|
26
23
|
/**
|
|
27
|
-
*
|
|
28
|
-
*
|
|
24
|
+
* Reactive pending-request store with per-request timeouts. Used by transports
|
|
25
|
+
* that don't delegate request/response correlation to a `WebsocketRpcConnection`.
|
|
29
26
|
*/
|
|
30
27
|
export declare class RequestTracker {
|
|
31
28
|
readonly pending_requests: SvelteMap<JsonrpcRequestId, RequestTrackerItem>;
|
|
32
29
|
readonly request_timeout_ms: number;
|
|
33
30
|
constructor(request_timeout_ms?: number);
|
|
34
31
|
/**
|
|
35
|
-
* Track a new request
|
|
36
|
-
*
|
|
37
|
-
* @returns
|
|
32
|
+
* Track a new request keyed by `id`.
|
|
33
|
+
*
|
|
34
|
+
* @returns deferred resolved on response, or rejected via the timeout
|
|
35
|
+
* @mutates this - inserts a `RequestTrackerItem` into `pending_requests`
|
|
36
|
+
* and arms a timeout that auto-rejects after `request_timeout_ms`;
|
|
37
|
+
* clears any prior timeout for the same id
|
|
38
38
|
*/
|
|
39
39
|
track_request(id: JsonrpcRequestId): Deferred<JsonrpcResponseOrError>;
|
|
40
40
|
/**
|
|
41
|
-
* Resolve a pending request with
|
|
42
|
-
*
|
|
43
|
-
* @
|
|
41
|
+
* Resolve a pending request with its response.
|
|
42
|
+
*
|
|
43
|
+
* @mutates this - clears the timeout, marks status `'success'`,
|
|
44
|
+
* resolves the deferred, and removes the entry from `pending_requests`
|
|
44
45
|
*/
|
|
45
46
|
resolve_request(id: JsonrpcRequestId, response: JsonrpcResponseOrError): void;
|
|
46
47
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* @
|
|
48
|
+
* Reject a pending request with `error_message`.
|
|
49
|
+
*
|
|
50
|
+
* @mutates this - clears the timeout, marks status `'failure'`,
|
|
51
|
+
* rejects the deferred with a `ThrownJsonrpcError`, and removes the
|
|
52
|
+
* entry from `pending_requests`
|
|
50
53
|
*/
|
|
51
54
|
reject_request(id: JsonrpcRequestId, error_message: JsonrpcErrorResponse): void;
|
|
52
55
|
/**
|
|
@@ -55,13 +58,18 @@ export declare class RequestTracker {
|
|
|
55
58
|
*/
|
|
56
59
|
handle_message(message: any): void;
|
|
57
60
|
/**
|
|
58
|
-
* Cancel a pending request
|
|
59
|
-
*
|
|
61
|
+
* Cancel a pending request without rejecting its deferred — just
|
|
62
|
+
* cleanup. The caller's promise stays unsettled; pair with an external
|
|
63
|
+
* resolution if needed.
|
|
64
|
+
*
|
|
65
|
+
* @mutates this - clears the timeout and removes the entry from `pending_requests`
|
|
60
66
|
*/
|
|
61
67
|
cancel_request(id: JsonrpcRequestId): void;
|
|
62
68
|
/**
|
|
63
69
|
* Cancel all pending requests.
|
|
64
70
|
* @param reason - optional reason to include in rejection
|
|
71
|
+
* @mutates this - clears every timeout, marks each status `'failure'`,
|
|
72
|
+
* rejects each deferred with `internal_error`, and empties `pending_requests`
|
|
65
73
|
*/
|
|
66
74
|
cancel_all_requests(reason?: string): void;
|
|
67
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request_tracker.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/request_tracker.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAkB,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAC,MAAM,2BAA2B,CAAC;AAC3F,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAEN,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,MAAM,oBAAoB,CAAC;AAG5B,2DAA2D;AAC3D,KAAK,QAAQ,GAAG,MAAM,GAAG;IAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;CAAC,CAAC;AAMxD
|
|
1
|
+
{"version":3,"file":"request_tracker.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/request_tracker.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAkB,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAC,MAAM,2BAA2B,CAAC;AAC3F,OAAO,EAAC,SAAS,EAAC,MAAM,mBAAmB,CAAC;AAE5C,OAAO,EAEN,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,MAAM,oBAAoB,CAAC;AAG5B,2DAA2D;AAC3D,KAAK,QAAQ,GAAG,MAAM,GAAG;IAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAA;CAAC,CAAC;AAMxD,qBAAa,kBAAkB;IAC9B,QAAQ,CAAC,EAAE,EAAE,gBAAgB,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC;IACpD,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC;IAC3B,MAAM,EAAE,WAAW,CAAiB;IACpC,OAAO,EAAE,MAAM,CAAC,OAAO,GAAG,SAAS,CAAgB;gBAGlD,EAAE,EAAE,gBAAgB,EACpB,QAAQ,EAAE,QAAQ,CAAC,sBAAsB,CAAC,EAC1C,OAAO,EAAE,QAAQ,EACjB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,MAAM,CAAC,OAAO,GAAG,SAAS;CAQpC;AAED;;;GAGG;AACH,qBAAa,cAAc;IAC1B,QAAQ,CAAC,gBAAgB,EAAE,SAAS,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAmB;IAC7F,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;gBAExB,kBAAkB,SAAU;IAIxC;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,EAAE,gBAAgB,GAAG,QAAQ,CAAC,sBAAsB,CAAC;IA6BrE;;;;;OAKG;IACH,eAAe,CAAC,EAAE,EAAE,gBAAgB,EAAE,QAAQ,EAAE,sBAAsB,GAAG,IAAI;IAkB7E;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,EAAE,gBAAgB,EAAE,aAAa,EAAE,oBAAoB,GAAG,IAAI;IAuB/E;;;OAGG;IACH,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI;IAiBlC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,EAAE,gBAAgB,GAAG,IAAI;IAe1C;;;;;OAKG;IACH,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;CAiB1C"}
|
|
@@ -12,9 +12,6 @@ import { ThrownJsonrpcError, JSONRPC_ERROR_CODES } from '../http/jsonrpc_errors.
|
|
|
12
12
|
const get_datetime_now = () => new Date().toISOString();
|
|
13
13
|
// TODO what if this uses a tracker id param that's an opaque UUID but can be used for action association?
|
|
14
14
|
// TODO name, like `TrackedRequest`? or is this implicit namespacing and generic name preferred
|
|
15
|
-
/**
|
|
16
|
-
* Represents a pending request with its associated state.
|
|
17
|
-
*/
|
|
18
15
|
export class RequestTrackerItem {
|
|
19
16
|
id;
|
|
20
17
|
deferred;
|
|
@@ -30,8 +27,8 @@ export class RequestTrackerItem {
|
|
|
30
27
|
}
|
|
31
28
|
}
|
|
32
29
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
30
|
+
* Reactive pending-request store with per-request timeouts. Used by transports
|
|
31
|
+
* that don't delegate request/response correlation to a `WebsocketRpcConnection`.
|
|
35
32
|
*/
|
|
36
33
|
export class RequestTracker {
|
|
37
34
|
pending_requests = new SvelteMap();
|
|
@@ -40,9 +37,12 @@ export class RequestTracker {
|
|
|
40
37
|
this.request_timeout_ms = request_timeout_ms;
|
|
41
38
|
}
|
|
42
39
|
/**
|
|
43
|
-
* Track a new request
|
|
44
|
-
*
|
|
45
|
-
* @returns
|
|
40
|
+
* Track a new request keyed by `id`.
|
|
41
|
+
*
|
|
42
|
+
* @returns deferred resolved on response, or rejected via the timeout
|
|
43
|
+
* @mutates this - inserts a `RequestTrackerItem` into `pending_requests`
|
|
44
|
+
* and arms a timeout that auto-rejects after `request_timeout_ms`;
|
|
45
|
+
* clears any prior timeout for the same id
|
|
46
46
|
*/
|
|
47
47
|
track_request(id) {
|
|
48
48
|
const deferred = create_deferred();
|
|
@@ -66,9 +66,10 @@ export class RequestTracker {
|
|
|
66
66
|
return deferred;
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
|
-
* Resolve a pending request with
|
|
70
|
-
*
|
|
71
|
-
* @
|
|
69
|
+
* Resolve a pending request with its response.
|
|
70
|
+
*
|
|
71
|
+
* @mutates this - clears the timeout, marks status `'success'`,
|
|
72
|
+
* resolves the deferred, and removes the entry from `pending_requests`
|
|
72
73
|
*/
|
|
73
74
|
resolve_request(id, response) {
|
|
74
75
|
const request = this.pending_requests.get(id);
|
|
@@ -86,9 +87,11 @@ export class RequestTracker {
|
|
|
86
87
|
this.pending_requests.delete(id);
|
|
87
88
|
}
|
|
88
89
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
* @
|
|
90
|
+
* Reject a pending request with `error_message`.
|
|
91
|
+
*
|
|
92
|
+
* @mutates this - clears the timeout, marks status `'failure'`,
|
|
93
|
+
* rejects the deferred with a `ThrownJsonrpcError`, and removes the
|
|
94
|
+
* entry from `pending_requests`
|
|
92
95
|
*/
|
|
93
96
|
reject_request(id, error_message) {
|
|
94
97
|
const request = this.pending_requests.get(id);
|
|
@@ -127,8 +130,11 @@ export class RequestTracker {
|
|
|
127
130
|
// ignore other messages
|
|
128
131
|
}
|
|
129
132
|
/**
|
|
130
|
-
* Cancel a pending request
|
|
131
|
-
*
|
|
133
|
+
* Cancel a pending request without rejecting its deferred — just
|
|
134
|
+
* cleanup. The caller's promise stays unsettled; pair with an external
|
|
135
|
+
* resolution if needed.
|
|
136
|
+
*
|
|
137
|
+
* @mutates this - clears the timeout and removes the entry from `pending_requests`
|
|
132
138
|
*/
|
|
133
139
|
cancel_request(id) {
|
|
134
140
|
const request = this.pending_requests.get(id);
|
|
@@ -145,6 +151,8 @@ export class RequestTracker {
|
|
|
145
151
|
/**
|
|
146
152
|
* Cancel all pending requests.
|
|
147
153
|
* @param reason - optional reason to include in rejection
|
|
154
|
+
* @mutates this - clears every timeout, marks each status `'failure'`,
|
|
155
|
+
* rejects each deferred with `internal_error`, and empties `pending_requests`
|
|
148
156
|
*/
|
|
149
157
|
cancel_all_requests(reason) {
|
|
150
158
|
for (const [id, request] of this.pending_requests.entries()) {
|
|
@@ -68,7 +68,6 @@ export interface CreateRpcClientOptions<TApi extends object = object> {
|
|
|
68
68
|
* const api_result = create_rpc_client<MyActionsApi>({peer, environment});
|
|
69
69
|
* ```
|
|
70
70
|
*
|
|
71
|
-
* @param options - client options (peer, environment, optional callbacks)
|
|
72
71
|
* @returns a Proxy typed as `TApi` that responds to any method name found in the environment's specs
|
|
73
72
|
*/
|
|
74
73
|
export declare const create_rpc_client: <TApi extends object>(options: CreateRpcClientOptions<TApi>) => TApi;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpc_client.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/rpc_client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,4BAA4B,CAAC;AAQvD,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAsB,KAAK,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAMxE,OAAO,KAAK,EAAC,UAAU,EAAE,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAEnD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;AAM/E,uCAAuC;AACvC,MAAM,WAAW,sBAAsB,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;IACnE,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,sBAAsB,CAAC;IACpC;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IACpE;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;CAC1C;AAED
|
|
1
|
+
{"version":3,"file":"rpc_client.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/rpc_client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,4BAA4B,CAAC;AAQvD,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAsB,KAAK,WAAW,EAAC,MAAM,mBAAmB,CAAC;AAMxE,OAAO,KAAK,EAAC,UAAU,EAAE,qBAAqB,EAAC,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAEnD,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC;AAM/E,uCAAuC;AACvC,MAAM,WAAW,sBAAsB,CAAC,IAAI,SAAS,MAAM,GAAG,MAAM;IACnE,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,sBAAsB,CAAC;IACpC;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IACpE;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;CAC1C;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,iBAAiB,GAAI,IAAI,SAAS,MAAM,EACpD,SAAS,sBAAsB,CAAC,IAAI,CAAC,KACnC,IA4BF,CAAC;AAuDF;;;;;GAKG;AACH,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB;CAAG;AA6GtE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,WAAW,CAAC,IAAI,IAAI;KAC9B,CAAC,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAClC,GAAG,IAAI,EAAE,MAAM,KAAK,KAChB,OAAO,CAAC,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,MAAM,CAAA;KAAC,EAAE;QAAC,KAAK,EAAE,kBAAkB,CAAA;KAAC,CAAC,CAAC,GACrE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,MAAM,CAAC,GACnC,IAAI,CAAC,CAAC,CAAC;CACV,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,mBAAmB,GAAI,IAAI,SAAS,MAAM,EAAE,YAAY,IAAI,KAAG,WAAW,CAAC,IAAI,CA8B3F,CAAC"}
|