@fuzdev/fuz_app 0.49.0 → 0.51.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.
Files changed (97) hide show
  1. package/dist/actions/CLAUDE.md +56 -21
  2. package/dist/actions/action_codegen.d.ts +60 -34
  3. package/dist/actions/action_codegen.d.ts.map +1 -1
  4. package/dist/actions/action_codegen.js +80 -46
  5. package/dist/actions/action_registry.d.ts +1 -1
  6. package/dist/actions/action_registry.js +1 -1
  7. package/dist/actions/action_spec.d.ts +1 -1
  8. package/dist/actions/action_spec.js +1 -1
  9. package/dist/actions/action_types.d.ts +4 -4
  10. package/dist/actions/action_types.js +4 -4
  11. package/dist/actions/cancel.d.ts +13 -11
  12. package/dist/actions/cancel.d.ts.map +1 -1
  13. package/dist/actions/cancel.js +13 -11
  14. package/dist/actions/frontend_rpc_client.d.ts +9 -0
  15. package/dist/actions/frontend_rpc_client.d.ts.map +1 -1
  16. package/dist/actions/heartbeat.d.ts +11 -8
  17. package/dist/actions/heartbeat.d.ts.map +1 -1
  18. package/dist/actions/heartbeat.js +11 -8
  19. package/dist/actions/protocol.d.ts +47 -0
  20. package/dist/actions/protocol.d.ts.map +1 -0
  21. package/dist/actions/protocol.js +46 -0
  22. package/dist/actions/register_action_ws.d.ts +5 -4
  23. package/dist/actions/register_action_ws.d.ts.map +1 -1
  24. package/dist/actions/register_action_ws.js +2 -2
  25. package/dist/auth/account_action_specs.d.ts +1 -1
  26. package/dist/auth/account_action_specs.js +1 -1
  27. package/dist/auth/account_actions.d.ts +2 -2
  28. package/dist/auth/account_actions.js +2 -2
  29. package/dist/auth/account_routes.d.ts +3 -3
  30. package/dist/auth/account_routes.js +3 -3
  31. package/dist/auth/account_schema.d.ts +1 -1
  32. package/dist/auth/account_schema.js +1 -1
  33. package/dist/auth/admin_action_specs.d.ts +1 -1
  34. package/dist/auth/admin_action_specs.js +1 -1
  35. package/dist/auth/admin_actions.d.ts +2 -2
  36. package/dist/auth/admin_actions.js +2 -2
  37. package/dist/auth/api_token.d.ts +1 -1
  38. package/dist/auth/api_token.js +1 -1
  39. package/dist/auth/audit_log_routes.d.ts +1 -1
  40. package/dist/auth/audit_log_routes.js +1 -1
  41. package/dist/auth/audit_log_schema.d.ts +1 -1
  42. package/dist/auth/daemon_token.d.ts +1 -1
  43. package/dist/auth/daemon_token.js +1 -1
  44. package/dist/auth/daemon_token_middleware.d.ts +1 -1
  45. package/dist/auth/daemon_token_middleware.js +1 -1
  46. package/dist/auth/ddl.d.ts +1 -1
  47. package/dist/auth/ddl.js +1 -1
  48. package/dist/auth/password.d.ts +1 -1
  49. package/dist/auth/password.js +1 -1
  50. package/dist/auth/permit_offer_action_specs.d.ts +1 -1
  51. package/dist/auth/permit_offer_action_specs.js +1 -1
  52. package/dist/auth/permit_offer_actions.d.ts +1 -1
  53. package/dist/auth/permit_offer_actions.js +1 -1
  54. package/dist/auth/route_guards.d.ts +1 -1
  55. package/dist/auth/route_guards.js +1 -1
  56. package/dist/auth/self_service_role_action_specs.d.ts +1 -1
  57. package/dist/auth/self_service_role_action_specs.js +1 -1
  58. package/dist/auth/self_service_role_actions.d.ts +1 -1
  59. package/dist/auth/self_service_role_actions.js +1 -1
  60. package/dist/auth/session_queries.d.ts +1 -1
  61. package/dist/auth/session_queries.js +1 -1
  62. package/dist/auth/signup_routes.d.ts +1 -1
  63. package/dist/auth/signup_routes.js +1 -1
  64. package/dist/auth/standard_action_specs.d.ts +1 -1
  65. package/dist/auth/standard_action_specs.js +1 -1
  66. package/dist/cli/util.d.ts +1 -1
  67. package/dist/cli/util.js +1 -1
  68. package/dist/db/create_db.d.ts +2 -2
  69. package/dist/db/create_db.js +2 -2
  70. package/dist/db/db.d.ts +3 -3
  71. package/dist/db/db.js +3 -3
  72. package/dist/hono_context.d.ts +1 -1
  73. package/dist/hono_context.js +1 -1
  74. package/dist/http/jsonrpc_errors.d.ts +2 -2
  75. package/dist/http/jsonrpc_errors.js +2 -2
  76. package/dist/http/jsonrpc_helpers.d.ts +2 -2
  77. package/dist/http/jsonrpc_helpers.js +2 -2
  78. package/dist/http/middleware_spec.d.ts +1 -1
  79. package/dist/http/middleware_spec.js +1 -1
  80. package/dist/http/origin.d.ts +1 -1
  81. package/dist/http/origin.js +1 -1
  82. package/dist/http/schema_helpers.d.ts +1 -1
  83. package/dist/http/schema_helpers.js +1 -1
  84. package/dist/http/surface.d.ts +1 -1
  85. package/dist/http/surface.js +1 -1
  86. package/dist/runtime/deno.d.ts +1 -1
  87. package/dist/runtime/deno.js +1 -1
  88. package/dist/runtime/node.d.ts +1 -1
  89. package/dist/runtime/node.js +1 -1
  90. package/dist/testing/rpc_attack_surface.js +1 -1
  91. package/dist/testing/rpc_helpers.js +1 -1
  92. package/dist/testing/ws_round_trip.js +1 -1
  93. package/dist/ui/account_sessions_state.svelte.d.ts +2 -2
  94. package/dist/ui/account_sessions_state.svelte.js +1 -1
  95. package/dist/ui/admin_rpc_adapters.d.ts +1 -1
  96. package/dist/ui/admin_rpc_adapters.js +1 -1
  97. package/package.json +1 -1
@@ -2,24 +2,27 @@ import { UnreachableError } from '@fuzdev/fuz_util/error.js';
2
2
  import { zod_get_base_type } from '@fuzdev/fuz_util/zod.js';
3
3
  import { ActionRegistry } from './action_registry.js';
4
4
  /**
5
- * Method names of composable actions exported from fuz_app — `heartbeat` (auth-aware
6
- * client liveness probe) and `cancel` (request-scoped abort signal). Consumers spread
7
- * this list when filtering backend request_response methods so the dispatcher-owned
8
- * composables don't show up in `BackendRequestResponseMethod` / handler maps.
5
+ * Method names of fuz_app's protocol actions — `heartbeat` (auth-aware client
6
+ * liveness probe) and `cancel` (request-scoped abort signal). Consumers spread
7
+ * this list when filtering backend request_response methods so the
8
+ * dispatcher-owned protocol actions don't show up in
9
+ * `BackendRequestResponseMethod` / handler maps. Pairs with `protocol_actions`
10
+ * / `protocol_action_specs` from `actions/protocol.ts` (the runtime bundles).
9
11
  */
10
- export const COMPOSABLE_ACTION_METHODS = ['heartbeat', 'cancel'];
11
- const COMPOSABLE_METHOD_SET = new Set(COMPOSABLE_ACTION_METHODS);
12
+ export const PROTOCOL_ACTION_METHODS = ['heartbeat', 'cancel'];
13
+ const PROTOCOL_METHOD_SET = new Set(PROTOCOL_ACTION_METHODS);
12
14
  /**
13
- * Type predicate for filtering composable methods out of a typed `FrontendActionsApi`
14
- * `method_filter`. Avoids the `(... as never)` cast required to call
15
- * `Array.prototype.includes` on the readonly tuple at narrow string types.
15
+ * Type predicate for filtering protocol-action methods out of a typed
16
+ * `FrontendActionsApi` `method_filter`. Avoids the `(... as never)` cast
17
+ * required to call `Array.prototype.includes` on the readonly tuple at narrow
18
+ * string types.
16
19
  *
17
20
  * @example
18
21
  * generate_frontend_actions_api(specs, imports, {
19
- * method_filter: (s) => !is_composable_action_method(s.method),
22
+ * method_filter: (s) => !is_protocol_action_method(s.method),
20
23
  * });
21
24
  */
22
- export const is_composable_action_method = (method) => COMPOSABLE_METHOD_SET.has(method);
25
+ export const is_protocol_action_method = (method) => PROTOCOL_METHOD_SET.has(method);
23
26
  /**
24
27
  * Manages imports for generated code, building them on demand.
25
28
  * Automatically optimizes type-only imports to use `import type` syntax.
@@ -275,6 +278,15 @@ export const get_handler_return_type = (spec, phase, imports, collections_path =
275
278
  * Generates the phase handlers for an action spec using the unified ActionEvent type
276
279
  * with the new phase/step type parameters.
277
280
  *
281
+ * Returns `''` when the spec contributes no phases on the given executor side
282
+ * (e.g. a backend-only `local_call` asked for `'frontend'`). Upstream wrappers
283
+ * compose blocks with `.filter(Boolean)` so empty entries are dropped from the
284
+ * generated handler map. The earlier shape was `${method}?: never`, which read
285
+ * as "calling this here is a type error" but in practice produced useless rows
286
+ * on `FrontendActionHandlers` for methods that don't belong on this side at
287
+ * all — drop the row instead so the typed surface only carries methods the
288
+ * executor actually handles.
289
+ *
278
290
  * @param options.action_event_type - custom type name to use instead of `ActionEvent`
279
291
  * (consumers can define a narrowed type that carries typed input/output via their codegen maps)
280
292
  * @param options.collections_path - import path the side-effect `ActionOutputs` import
@@ -284,7 +296,7 @@ export const generate_phase_handlers = (spec, executor, imports, options) => {
284
296
  const { method } = spec;
285
297
  const phases = get_executor_phases(spec, executor);
286
298
  if (phases.length === 0) {
287
- return `${method}?: never`;
299
+ return '';
288
300
  }
289
301
  const action_event_type = options?.action_event_type ?? 'ActionEvent';
290
302
  const collections_path = options?.collections_path ?? DEFAULT_COLLECTIONS_PATH;
@@ -328,32 +340,52 @@ export const to_action_spec_output_identifier = (method) => `${to_action_spec_id
328
340
  * failure). Earlier emit shapes declared notifications as `=> void` —
329
341
  * regenerate consumer typed clients to pick up the corrected return.
330
342
  *
331
- * Consumers must import `ActionInputs`, `ActionOutputs`, `Result`,
332
- * `JsonrpcErrorObject`, and (for async) `RpcClientCallOptions` into the
333
- * generated module — the helper only emits the type references.
343
+ * Registers exactly the imports the emitted line references on `imports`:
344
+ * `ActionInputs` (when the spec has input), `ActionOutputs` (always),
345
+ * `RpcClientCallOptions` (async only), and `Result` + `JsonrpcErrorObject`
346
+ * (any return shape that wraps the value in `Result<{value}, {error}>` —
347
+ * every async method, plus sync `local_call` when `sync_returns_value:
348
+ * false`). Mirrors the leaf-level pattern `get_handler_return_type` already
349
+ * follows so wrappers no longer pre-register imports a per-spec emit might
350
+ * not actually use.
334
351
  *
335
352
  * @param spec - the action spec to emit
353
+ * @param imports - import builder to register references on
336
354
  * @param options.sync_returns_value - when true (default), sync local_call
337
355
  * methods return the output value directly; when false they're wrapped in
338
356
  * `Result<{value, error}>` like async methods. Set to `false` if your
339
357
  * FrontendActionsApi treats every method uniformly.
358
+ * @param options.collections_path - import path that `ActionInputs` /
359
+ * `ActionOutputs` resolve to. Defaults to `'./action_collections.js'`.
340
360
  * @returns one line like `foo: (input: ActionInputs['foo'], options?: RpcClientCallOptions) => Promise<Result<...>>;`
341
361
  */
342
- export const generate_actions_api_method_signature = (spec, options) => {
362
+ export const generate_actions_api_method_signature = (spec, imports, options) => {
343
363
  const sync_returns_value = options?.sync_returns_value ?? true;
364
+ const collections_path = options?.collections_path ?? DEFAULT_COLLECTIONS_PATH;
344
365
  const innermost_type_name = zod_get_base_type(spec.input);
345
366
  const has_input = innermost_type_name !== 'null' && innermost_type_name !== 'void';
346
367
  const input_param = has_input
347
368
  ? `input${spec.input.safeParse(undefined).success ? '?' : ''}: ActionInputs['${spec.method}']`
348
369
  : 'input?: void';
370
+ if (has_input)
371
+ imports.add_type(collections_path, 'ActionInputs');
372
+ imports.add_type(collections_path, 'ActionOutputs');
349
373
  const is_async = spec.kind === 'request_response' || spec.kind === 'remote_notification' || spec.async;
350
374
  const options_param = is_async ? ', options?: RpcClientCallOptions' : '';
375
+ if (is_async) {
376
+ imports.add_type('@fuzdev/fuz_app/actions/rpc_client.js', 'RpcClientCallOptions');
377
+ }
351
378
  const result_return = `Result<{value: ActionOutputs['${spec.method}']}, {error: JsonrpcErrorObject}>`;
352
379
  const return_type = is_async
353
380
  ? `Promise<${result_return}>`
354
381
  : sync_returns_value
355
382
  ? `ActionOutputs['${spec.method}']`
356
383
  : result_return;
384
+ const wraps_in_result = is_async || !sync_returns_value;
385
+ if (wraps_in_result) {
386
+ imports.add_type('@fuzdev/fuz_util/result.js', 'Result');
387
+ imports.add_type('@fuzdev/fuz_app/http/jsonrpc.js', 'JsonrpcErrorObject');
388
+ }
357
389
  return `${spec.method}: (${input_param}${options_param}) => ${return_type};`;
358
390
  };
359
391
  // --------------------------------------------------------------------------
@@ -404,12 +436,13 @@ export const ACTION_METHOD_ENUM_KINDS_ALL = new Set([
404
436
  ]);
405
437
  /**
406
438
  * Filter `heartbeat` / `cancel` out of `specs` unless the consumer opts back in.
407
- * Composables ship from fuz_app and are spread into every consumer's `actions`
408
- * array at registration time they should not appear in consumer-owned typed
439
+ * Protocol actions ship from fuz_app and are spread into every consumer's
440
+ * `actions` array at registration time (via `protocol_actions` from
441
+ * `actions/protocol.ts`) — they should not appear in consumer-owned typed
409
442
  * surfaces (`ActionMethod`, `FrontendActionsApi`, `ActionInputs`, etc.) by
410
443
  * default.
411
444
  */
412
- const filter_composables = (specs, include_composables) => include_composables ? specs : specs.filter((s) => !is_composable_action_method(s.method));
445
+ const filter_protocol_actions = (specs, include_protocol_actions) => include_protocol_actions ? specs : specs.filter((s) => !is_protocol_action_method(s.method));
413
446
  /**
414
447
  * Resolve the per-spec identifier qualifier used by the multi-source helpers
415
448
  * (`generate_action_specs_record`, `generate_action_inputs_outputs`,
@@ -434,10 +467,10 @@ const resolve_spec_qualifier = (imports, options) => {
434
467
  * `BroadcastActionMethod`. Pairs each runtime const with a `z.infer` type
435
468
  * alias under the same identifier.
436
469
  *
437
- * Composable methods (`heartbeat`, `cancel`) are filtered out by default —
438
- * pass `include_composables: true` if a consumer genuinely wants them on
439
- * their typed surface. Empty kinds are skipped so the helper never emits
440
- * `z.enum([])` (zod runtime-throws on that).
470
+ * Protocol-action methods (`heartbeat`, `cancel`) are filtered out by
471
+ * default — pass `include_protocol_actions: true` if a consumer genuinely
472
+ * wants them on their typed surface. Empty kinds are skipped so the helper
473
+ * never emits `z.enum([])` (zod runtime-throws on that).
441
474
  *
442
475
  * Adds `import {z} from 'zod';` to `imports` only when at least one block
443
476
  * is emitted (idempotent).
@@ -447,12 +480,12 @@ const resolve_spec_qualifier = (imports, options) => {
447
480
  * and jsdoc.
448
481
  *
449
482
  * @param options.emit - subset of enums to emit; defaults to all nine.
450
- * @param options.include_composables - when true, retains `heartbeat` /
483
+ * @param options.include_protocol_actions - when true, retains `heartbeat` /
451
484
  * `cancel` in the emitted enums. Default `false`.
452
485
  */
453
486
  export const generate_action_method_enums = (specs, imports, options) => {
454
487
  const emit = options?.emit ?? ACTION_METHOD_ENUM_KINDS_ALL;
455
- const filtered = filter_composables(specs, options?.include_composables);
488
+ const filtered = filter_protocol_actions(specs, options?.include_protocol_actions);
456
489
  const registry = new ActionRegistry([...filtered]);
457
490
  const blocks = [];
458
491
  const emit_block = (kind, name, methods, jsdoc) => {
@@ -488,16 +521,17 @@ export const generate_action_method_enums = (specs, imports, options) => {
488
521
  * for cross-product or domain-specific enums the built-in discriminator
489
522
  * doesn't cover.
490
523
  *
491
- * Mirrors the built-in helper's contract: composables filtered by default,
492
- * empty subsets return `''` (skip rather than emit `z.enum([])`), `zod`
493
- * import registered idempotently only when at least one method qualifies.
524
+ * Mirrors the built-in helper's contract: protocol actions filtered by
525
+ * default, empty subsets return `''` (skip rather than emit `z.enum([])`),
526
+ * `zod` import registered idempotently only when at least one method
527
+ * qualifies.
494
528
  *
495
529
  * The cross-product space is open-ended; rather than grow the
496
530
  * `ActionMethodEnumKind` discriminator one cross-product at a time, callers
497
531
  * own the subset shape — name, jsdoc, predicate.
498
532
  */
499
533
  export const generate_action_method_enum_block = (specs, imports, options) => {
500
- const filtered = filter_composables(specs, options.include_composables);
534
+ const filtered = filter_protocol_actions(specs, options.include_protocol_actions);
501
535
  const methods = filtered.filter(options.predicate).map((s) => s.method);
502
536
  if (methods.length === 0)
503
537
  return '';
@@ -544,7 +578,7 @@ type TypedActionEvent<
544
578
  * is ignored when `qualify_spec` is set. Single-source consumers omit it.
545
579
  */
546
580
  export const generate_action_specs_record = (specs, imports, options) => {
547
- const filtered = filter_composables(specs, options?.include_composables);
581
+ const filtered = filter_protocol_actions(specs, options?.include_protocol_actions);
548
582
  imports.add_type('@fuzdev/fuz_app/actions/action_spec.js', 'ActionSpecUnion');
549
583
  if (filtered.length === 0) {
550
584
  // Empty spec list — emit minimal valid output and skip the `* as specs`
@@ -588,7 +622,7 @@ export const action_specs: Array<ActionSpecUnion> = Object.values(ActionSpecs);`
588
622
  * and `specs_module` is ignored. Single-source consumers omit it.
589
623
  */
590
624
  export const generate_action_inputs_outputs = (specs, imports, options) => {
591
- const filtered = filter_composables(specs, options?.include_composables);
625
+ const filtered = filter_protocol_actions(specs, options?.include_protocol_actions);
592
626
  if (filtered.length === 0) {
593
627
  // Empty spec list — emit minimal valid output and skip the `zod` /
594
628
  // `* as specs` imports that would have nothing to reference.
@@ -663,7 +697,7 @@ ${outputs_type}
663
697
  * path the import resolves to.
664
698
  */
665
699
  export const generate_action_event_datas = (specs, imports, options) => {
666
- const filtered = filter_composables(specs, options?.include_composables);
700
+ const filtered = filter_protocol_actions(specs, options?.include_protocol_actions);
667
701
  if (filtered.length === 0) {
668
702
  // Empty spec list — emit `interface ActionEventDatas {}` and skip
669
703
  // the optional collections-path import that would be unused.
@@ -703,10 +737,14 @@ ${lines.join('\n')}
703
737
  /**
704
738
  * Emit the `FrontendActionsApi` interface — one method signature per spec via
705
739
  * `generate_actions_api_method_signature`. Optionally filter the spec set
706
- * (e.g. omit composable methods) via `method_filter`.
740
+ * (e.g. omit additional methods alongside the default protocol-action
741
+ * filter) via `method_filter`.
707
742
  *
708
- * Adds the `Result`, `JsonrpcErrorObject`, and `RpcClientCallOptions` type
709
- * imports plus `ActionInputs` / `ActionOutputs` (sourced from `collections_path`).
743
+ * Imports are registered by the leaf `generate_actions_api_method_signature`
744
+ * per emitted line only what the spec set actually references shows up on
745
+ * `imports`. A spec set with no async methods skips `RpcClientCallOptions`;
746
+ * one with no inputs skips `ActionInputs`; sync `local_call` methods with
747
+ * `sync_returns_value: true` (the default) skip `Result` / `JsonrpcErrorObject`.
710
748
  *
711
749
  * The interface name is fixed at `FrontendActionsApi` — the symmetric counterpart
712
750
  * of `BackendActionsApi`. Earlier consumer-named variants (`MyActionsApi`,
@@ -715,9 +753,9 @@ ${lines.join('\n')}
715
753
  * hand-roll the interface (the helper's job is the standard symmetric shape).
716
754
  */
717
755
  export const generate_frontend_actions_api = (specs, imports, options) => {
718
- const composable_filtered = filter_composables(specs, options?.include_composables);
756
+ const protocol_filtered = filter_protocol_actions(specs, options?.include_protocol_actions);
719
757
  const filter = options?.method_filter;
720
- const filtered = filter ? composable_filtered.filter((s) => filter(s)) : composable_filtered;
758
+ const filtered = filter ? protocol_filtered.filter((s) => filter(s)) : protocol_filtered;
721
759
  const interface_doc = `/**
722
760
  * Typed dispatch surface for the frontend's RPC client. Symmetric counterpart
723
761
  * of \`BackendActionsApi\`. Async methods (request_response, remote_notification,
@@ -732,14 +770,10 @@ export const generate_frontend_actions_api = (specs, imports, options) => {
732
770
  return `${interface_doc}
733
771
  export interface FrontendActionsApi {}`;
734
772
  }
735
- const collections_path = options?.collections_path ?? DEFAULT_COLLECTIONS_PATH;
736
- imports.add_type('@fuzdev/fuz_util/result.js', 'Result');
737
- imports.add_type('@fuzdev/fuz_app/http/jsonrpc.js', 'JsonrpcErrorObject');
738
- imports.add_type('@fuzdev/fuz_app/actions/rpc_client.js', 'RpcClientCallOptions');
739
- imports.add_types(collections_path, 'ActionInputs', 'ActionOutputs');
740
773
  const lines = filtered
741
- .map((spec) => generate_actions_api_method_signature(spec, {
774
+ .map((spec) => generate_actions_api_method_signature(spec, imports, {
742
775
  sync_returns_value: options?.sync_returns_value,
776
+ collections_path: options?.collections_path,
743
777
  }))
744
778
  .map((line) => `\t${line}`)
745
779
  .join('\n');
@@ -755,7 +789,7 @@ ${lines}
755
789
  * matching `TypedActionEvent` alias) — call both in the same gen producer.
756
790
  */
757
791
  export const generate_frontend_action_handlers = (specs, imports, options) => {
758
- const filtered = filter_composables(specs, options?.include_composables);
792
+ const filtered = filter_protocol_actions(specs, options?.include_protocol_actions);
759
793
  const interface_doc = `/**
760
794
  * Frontend action handlers organized by method and phase.
761
795
  * Generated using spec.initiator to determine valid phases:
@@ -815,8 +849,8 @@ ${lines};
815
849
  * Single-source consumers omit it.
816
850
  */
817
851
  export const generate_backend_actions_api = (specs, imports, options) => {
818
- const composable_filtered = filter_composables(specs, options?.include_composables);
819
- const registry = new ActionRegistry([...composable_filtered]);
852
+ const protocol_filtered = filter_protocol_actions(specs, options?.include_protocol_actions);
853
+ const registry = new ActionRegistry([...protocol_filtered]);
820
854
  const broadcast = registry.broadcast_specs;
821
855
  imports.add_type('@fuzdev/fuz_app/actions/action_spec.js', 'ActionSpecUnion');
822
856
  const interface_doc = `/**
@@ -17,7 +17,7 @@
17
17
  *
18
18
  * Cache discipline: `spec_by_method` (Map) and the internal streams-target
19
19
  * set lazy-memoize because the Map is consulted per-RPC dispatch
20
- * (`frontend_rpc_client.ts` wires it into `lookup_action_spec`) and the
20
+ * (`actions/frontend_rpc_client.ts` wires it into `lookup_action_spec`) and the
21
21
  * streams set is rebuilt by two public getters. Array-returning getters
22
22
  * recompute on each call so callers can mutate the result freely
23
23
  * (`.sort()`, `.push(injected)` on a copy, etc.) without affecting the
@@ -17,7 +17,7 @@
17
17
  *
18
18
  * Cache discipline: `spec_by_method` (Map) and the internal streams-target
19
19
  * set lazy-memoize because the Map is consulted per-RPC dispatch
20
- * (`frontend_rpc_client.ts` wires it into `lookup_action_spec`) and the
20
+ * (`actions/frontend_rpc_client.ts` wires it into `lookup_action_spec`) and the
21
21
  * streams set is rebuilt by two public getters. Array-returning getters
22
22
  * recompute on each call so callers can mutate the result freely
23
23
  * (`.sort()`, `.push(injected)` on a copy, etc.) without affecting the
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Extracted from zzz's action system. Action specs define method, kind,
5
5
  * auth, side effects, and input/output schemas. Bridge functions in
6
- * `action_bridge.ts` derive `RouteSpec` and `EventSpec` from them.
6
+ * `actions/action_bridge.ts` derive `RouteSpec` and `EventSpec` from them.
7
7
  *
8
8
  * TODO @action-system-review The action system (action_spec, action_registry,
9
9
  * action_codegen, action_bridge) will evolve significantly as RPC patterns settle.
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Extracted from zzz's action system. Action specs define method, kind,
5
5
  * auth, side effects, and input/output schemas. Bridge functions in
6
- * `action_bridge.ts` derive `RouteSpec` and `EventSpec` from them.
6
+ * `actions/action_bridge.ts` derive `RouteSpec` and `EventSpec` from them.
7
7
  *
8
8
  * TODO @action-system-review The action system (action_spec, action_registry,
9
9
  * action_codegen, action_bridge) will evolve significantly as RPC patterns settle.
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Shared type surface for the action system — context, handler, composable Action tuple.
3
3
  *
4
- * These types sit above `action_spec.ts` (pure Zod schemas) and below the
5
- * dispatchers (`register_action_ws.ts`, `action_rpc.ts`). Extracted so the
6
- * shared composable fuz_app actions (e.g. `heartbeat_action`) can name them
7
- * without pulling in server-only modules.
4
+ * These types sit above `actions/action_spec.ts` (pure Zod schemas) and below the
5
+ * dispatchers (`actions/register_action_ws.ts`, `actions/action_rpc.ts`). Extracted so the
6
+ * shared protocol actions (e.g. `heartbeat_action`) can name them without
7
+ * pulling in server-only modules.
8
8
  *
9
9
  * @module
10
10
  */
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Shared type surface for the action system — context, handler, composable Action tuple.
3
3
  *
4
- * These types sit above `action_spec.ts` (pure Zod schemas) and below the
5
- * dispatchers (`register_action_ws.ts`, `action_rpc.ts`). Extracted so the
6
- * shared composable fuz_app actions (e.g. `heartbeat_action`) can name them
7
- * without pulling in server-only modules.
4
+ * These types sit above `actions/action_spec.ts` (pure Zod schemas) and below the
5
+ * dispatchers (`actions/register_action_ws.ts`, `actions/action_rpc.ts`). Extracted so the
6
+ * shared protocol actions (e.g. `heartbeat_action`) can name them without
7
+ * pulling in server-only modules.
8
8
  *
9
9
  * @module
10
10
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Shared cancel action — the second composable fuz_app primitive, validating
3
- * the spec+handler tuple pattern on a notification-kind action.
2
+ * Shared cancel action — a fuz_app protocol action validating the
3
+ * spec+handler tuple pattern on a notification-kind action.
4
4
  *
5
5
  * Semantics: the client sends `{jsonrpc, method: 'cancel', params:
6
6
  * {request_id}}` to abort an in-flight request on the same socket.
@@ -11,13 +11,14 @@
11
11
  *
12
12
  * The handler field is an empty stub: cancel semantics are dispatcher-owned
13
13
  * (the dispatcher has the `{request_id → AbortController}` map, not the
14
- * handler). The handler exists for symmetry with other composable primitives
14
+ * handler). The handler exists for symmetry with other protocol actions
15
15
  * like `heartbeat_action`; the dispatcher never calls it. Consumers
16
- * spread `cancel_action` into their server's `actions` array so
17
- * `spec_by_method` knows about it (enabling input validation on incoming
18
- * cancels) and so `create_rpc_client` codegen produces `app.api.cancel()`
19
- * when desired though `FrontendWebsocketClient.request({signal})` sends
20
- * the cancel on abort without needing the typed API.
16
+ * spread `cancel_action` (or the `protocol_actions` bundle from
17
+ * `actions/protocol.ts`) into their server's `actions` array so `spec_by_method`
18
+ * knows about it (enabling input validation on incoming cancels) and so
19
+ * `create_rpc_client` codegen produces `app.api.cancel()` when desired —
20
+ * though `FrontendWebsocketClient.request({signal})` sends the cancel on
21
+ * abort without needing the typed API.
21
22
  *
22
23
  * Wire format is snake_case `cancel` with `{request_id}`, not MCP's
23
24
  * `$/cancelRequest` with `{requestId}` — fuz_app's WS transport isn't MCP,
@@ -67,9 +68,10 @@ export declare const cancel_action_spec: {
67
68
  */
68
69
  export declare const cancel_handler: () => void;
69
70
  /**
70
- * Composable tuple — spread into the server's `actions` array so the
71
- * dispatcher registers the spec for input validation and so `create_rpc_client`
72
- * codegen sees the method. The client doesn't need to call it directly;
71
+ * Protocol-action tuple — spread into the server's `actions` array (or via
72
+ * `protocol_actions` from `actions/protocol.ts`) so the dispatcher registers the
73
+ * spec for input validation and so `create_rpc_client` codegen sees the
74
+ * method. The client doesn't need to call it directly;
73
75
  * `FrontendWebsocketClient.request({signal})` sends the cancel notification
74
76
  * automatically when the signal fires.
75
77
  */
@@ -1 +1 @@
1
- {"version":3,"file":"cancel.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/cancel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAItB,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAE9C;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;;kBAEnC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEhF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;CAWS,CAAC;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,cAAc,QAAO,IAAU,CAAC;AAE7C;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,EAAE,MAG3B,CAAC"}
1
+ {"version":3,"file":"cancel.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/cancel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAItB,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAE9C;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;;kBAEnC,CAAC;AACH,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAEhF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;CAWS,CAAC;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,cAAc,QAAO,IAAU,CAAC;AAE7C;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE,MAG3B,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Shared cancel action — the second composable fuz_app primitive, validating
3
- * the spec+handler tuple pattern on a notification-kind action.
2
+ * Shared cancel action — a fuz_app protocol action validating the
3
+ * spec+handler tuple pattern on a notification-kind action.
4
4
  *
5
5
  * Semantics: the client sends `{jsonrpc, method: 'cancel', params:
6
6
  * {request_id}}` to abort an in-flight request on the same socket.
@@ -11,13 +11,14 @@
11
11
  *
12
12
  * The handler field is an empty stub: cancel semantics are dispatcher-owned
13
13
  * (the dispatcher has the `{request_id → AbortController}` map, not the
14
- * handler). The handler exists for symmetry with other composable primitives
14
+ * handler). The handler exists for symmetry with other protocol actions
15
15
  * like `heartbeat_action`; the dispatcher never calls it. Consumers
16
- * spread `cancel_action` into their server's `actions` array so
17
- * `spec_by_method` knows about it (enabling input validation on incoming
18
- * cancels) and so `create_rpc_client` codegen produces `app.api.cancel()`
19
- * when desired though `FrontendWebsocketClient.request({signal})` sends
20
- * the cancel on abort without needing the typed API.
16
+ * spread `cancel_action` (or the `protocol_actions` bundle from
17
+ * `actions/protocol.ts`) into their server's `actions` array so `spec_by_method`
18
+ * knows about it (enabling input validation on incoming cancels) and so
19
+ * `create_rpc_client` codegen produces `app.api.cancel()` when desired —
20
+ * though `FrontendWebsocketClient.request({signal})` sends the cancel on
21
+ * abort without needing the typed API.
21
22
  *
22
23
  * Wire format is snake_case `cancel` with `{request_id}`, not MCP's
23
24
  * `$/cancelRequest` with `{requestId}` — fuz_app's WS transport isn't MCP,
@@ -64,9 +65,10 @@ export const cancel_action_spec = {
64
65
  */
65
66
  export const cancel_handler = () => { }; // eslint-disable-line @typescript-eslint/no-empty-function
66
67
  /**
67
- * Composable tuple — spread into the server's `actions` array so the
68
- * dispatcher registers the spec for input validation and so `create_rpc_client`
69
- * codegen sees the method. The client doesn't need to call it directly;
68
+ * Protocol-action tuple — spread into the server's `actions` array (or via
69
+ * `protocol_actions` from `actions/protocol.ts`) so the dispatcher registers the
70
+ * spec for input validation and so `create_rpc_client` codegen sees the
71
+ * method. The client doesn't need to call it directly;
70
72
  * `FrontendWebsocketClient.request({signal})` sends the cancel notification
71
73
  * automatically when the signal fires.
72
74
  */
@@ -58,6 +58,15 @@ export interface CreateFrontendRpcClientOptions<TApi extends object = object> {
58
58
  * list silently return `undefined` from the Proxy — the generic `TApi`
59
59
  * cannot constrain runtime membership, so consumers must keep this list
60
60
  * in sync with the typed surface (codegen recommended).
61
+ *
62
+ * Protocol actions (`heartbeat`, `cancel`) are **not** auto-spread —
63
+ * they're filtered out of generated `action_specs` by codegen's
64
+ * `include_protocol_actions: false` default and consumers spread them
65
+ * in explicitly so the contract stays visible at every registration
66
+ * site. For WS-using consumers, spread `protocol_action_specs` from
67
+ * `actions/protocol.ts` here:
68
+ * `specs: [...protocol_action_specs, ...action_specs]`. HTTP-only
69
+ * consumers can omit them.
61
70
  */
62
71
  specs: ReadonlyArray<ActionSpecUnion>;
63
72
  /**
@@ -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;;;;;OAKG;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;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,GAAI,IAAI,SAAS,MAAM,EAC7D,SAAS,8BAA8B,CAAC,IAAI,CAAC,KAC3C,iBAAiB,CAAC,IAAI,CAsBxB,CAAC"}
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;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,GAAI,IAAI,SAAS,MAAM,EAC7D,SAAS,8BAA8B,CAAC,IAAI,CAAC,KAC3C,iBAAiB,CAAC,IAAI,CAsBxB,CAAC"}
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Shared heartbeat action — the first composable fuz_app primitive carrying
3
- * both a spec and a handler in one tuple. Consumers spread
4
- * `heartbeat_action` into both the server's and the client's `actions`
5
- * array so disconnect detection works identically across every repo without
6
- * per-consumer ping plumbing.
2
+ * Shared heartbeat action — a fuz_app protocol action carrying both a spec
3
+ * and a handler in one tuple. Consumers spread `heartbeat_action` (or the
4
+ * `protocol_actions` bundle from `actions/protocol.ts`) into the server's
5
+ * `actions` array so disconnect detection works identically across every
6
+ * repo without per-consumer ping plumbing.
7
7
  *
8
8
  * The client's activity-aware heartbeat timer (in
9
9
  * `FrontendWebsocketClient`) issues a `heartbeat` request whenever the
@@ -38,9 +38,12 @@ export declare const heartbeat_action_spec: {
38
38
  /** Handler — nullary echo. Stateless, suitable for high-frequency pings. */
39
39
  export declare const heartbeat_handler: () => Record<string, never>;
40
40
  /**
41
- * Composable tuple — spread into the server's `actions` array for dispatch
42
- * and into the client's `actions` array so `create_rpc_client` types
43
- * `app.api.heartbeat()` against the shared spec.
41
+ * Protocol-action tuple — spread into the server's `actions` array for
42
+ * dispatch (or via `protocol_actions` from `actions/protocol.ts`) so the
43
+ * dispatcher resolves the heartbeat handler. The frontend-side spread
44
+ * happens via `protocol_action_specs` — the client doesn't run the echo
45
+ * handler, but the spec must be in `ActionRegistry` so `create_rpc_client`
46
+ * types `app.api.heartbeat()` against the shared spec.
44
47
  */
45
48
  export declare const heartbeat_action: Action;
46
49
  //# sourceMappingURL=heartbeat.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"heartbeat.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/heartbeat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAGtB,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAE9C;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;CAUG,CAAC;AAEtC,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,QAAO,MAAM,CAAC,MAAM,EAAE,KAAK,CAAS,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAG9B,CAAC"}
1
+ {"version":3,"file":"heartbeat.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/heartbeat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAGtB,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAE9C;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;CAUG,CAAC;AAEtC,4EAA4E;AAC5E,eAAO,MAAM,iBAAiB,QAAO,MAAM,CAAC,MAAM,EAAE,KAAK,CAAS,CAAC;AAEnE;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAG9B,CAAC"}
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Shared heartbeat action — the first composable fuz_app primitive carrying
3
- * both a spec and a handler in one tuple. Consumers spread
4
- * `heartbeat_action` into both the server's and the client's `actions`
5
- * array so disconnect detection works identically across every repo without
6
- * per-consumer ping plumbing.
2
+ * Shared heartbeat action — a fuz_app protocol action carrying both a spec
3
+ * and a handler in one tuple. Consumers spread `heartbeat_action` (or the
4
+ * `protocol_actions` bundle from `actions/protocol.ts`) into the server's
5
+ * `actions` array so disconnect detection works identically across every
6
+ * repo without per-consumer ping plumbing.
7
7
  *
8
8
  * The client's activity-aware heartbeat timer (in
9
9
  * `FrontendWebsocketClient`) issues a `heartbeat` request whenever the
@@ -37,9 +37,12 @@ export const heartbeat_action_spec = {
37
37
  /** Handler — nullary echo. Stateless, suitable for high-frequency pings. */
38
38
  export const heartbeat_handler = () => ({});
39
39
  /**
40
- * Composable tuple — spread into the server's `actions` array for dispatch
41
- * and into the client's `actions` array so `create_rpc_client` types
42
- * `app.api.heartbeat()` against the shared spec.
40
+ * Protocol-action tuple — spread into the server's `actions` array for
41
+ * dispatch (or via `protocol_actions` from `actions/protocol.ts`) so the
42
+ * dispatcher resolves the heartbeat handler. The frontend-side spread
43
+ * happens via `protocol_action_specs` — the client doesn't run the echo
44
+ * handler, but the spec must be in `ActionRegistry` so `create_rpc_client`
45
+ * types `app.api.heartbeat()` against the shared spec.
43
46
  */
44
47
  export const heartbeat_action = {
45
48
  spec: heartbeat_action_spec,
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Canonical bundles of fuz_app's protocol actions — `heartbeat` and
3
+ * `cancel`. Spread these into consumer registrations on both sides of the
4
+ * wire so the registries stay symmetric without per-consumer plumbing.
5
+ *
6
+ * Protocol actions are wire-protocol concerns (liveness, abort) shipped by
7
+ * fuz_app, not consumer domain logic. The split is intentional: the server
8
+ * needs `{spec, handler}` tuples to drive dispatch; the frontend
9
+ * `ActionRegistry` only stores specs. The codegen
10
+ * `include_protocol_actions: false` default (in `actions/action_codegen.ts`) is the
11
+ * third leg of this contract — protocol actions are excluded from
12
+ * generated typed surfaces because consumers spread them in at
13
+ * registration time.
14
+ *
15
+ * Adding a future protocol action (e.g. clock-skew probe, reconnect-resume
16
+ * token) means appending to these arrays in one place; no consumer
17
+ * migration required.
18
+ *
19
+ * @module
20
+ */
21
+ import type { ActionSpecUnion } from './action_spec.js';
22
+ import type { Action } from './action_types.js';
23
+ /**
24
+ * Canonical protocol `{spec, handler}` tuples for the server's
25
+ * `register_action_ws` `actions` array. Spread before consumer-owned actions
26
+ * so disconnect detection and per-request cancel work uniformly:
27
+ *
28
+ * ```ts
29
+ * register_action_ws({actions: [...protocol_actions, ...consumer_actions], ...})
30
+ * ```
31
+ */
32
+ export declare const protocol_actions: ReadonlyArray<Action>;
33
+ /**
34
+ * Canonical protocol specs for `ActionRegistry` construction on the
35
+ * frontend. Spread before consumer-owned specs so dispatcher-owned methods
36
+ * are present in the lookup map even though codegen excludes them from the
37
+ * generated `action_specs` array:
38
+ *
39
+ * ```ts
40
+ * new ActionRegistry([...protocol_action_specs, ...action_specs])
41
+ * ```
42
+ *
43
+ * Derived from `protocol_actions` so a future protocol action lands in one
44
+ * place — the two arrays cannot drift.
45
+ */
46
+ export declare const protocol_action_specs: ReadonlyArray<ActionSpecUnion>;
47
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,mBAAmB,CAAC;AAI9C;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAAC,MAAM,CAAqC,CAAC;AAEzF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,EAAE,aAAa,CAAC,eAAe,CAEhE,CAAC"}