@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.
- package/dist/actions/CLAUDE.md +56 -21
- package/dist/actions/action_codegen.d.ts +60 -34
- package/dist/actions/action_codegen.d.ts.map +1 -1
- package/dist/actions/action_codegen.js +80 -46
- package/dist/actions/action_registry.d.ts +1 -1
- package/dist/actions/action_registry.js +1 -1
- package/dist/actions/action_spec.d.ts +1 -1
- package/dist/actions/action_spec.js +1 -1
- package/dist/actions/action_types.d.ts +4 -4
- package/dist/actions/action_types.js +4 -4
- package/dist/actions/cancel.d.ts +13 -11
- package/dist/actions/cancel.d.ts.map +1 -1
- package/dist/actions/cancel.js +13 -11
- package/dist/actions/frontend_rpc_client.d.ts +9 -0
- package/dist/actions/frontend_rpc_client.d.ts.map +1 -1
- package/dist/actions/heartbeat.d.ts +11 -8
- package/dist/actions/heartbeat.d.ts.map +1 -1
- package/dist/actions/heartbeat.js +11 -8
- package/dist/actions/protocol.d.ts +47 -0
- package/dist/actions/protocol.d.ts.map +1 -0
- package/dist/actions/protocol.js +46 -0
- package/dist/actions/register_action_ws.d.ts +5 -4
- package/dist/actions/register_action_ws.d.ts.map +1 -1
- package/dist/actions/register_action_ws.js +2 -2
- package/dist/auth/account_action_specs.d.ts +1 -1
- package/dist/auth/account_action_specs.js +1 -1
- package/dist/auth/account_actions.d.ts +2 -2
- package/dist/auth/account_actions.js +2 -2
- package/dist/auth/account_routes.d.ts +3 -3
- package/dist/auth/account_routes.js +3 -3
- package/dist/auth/account_schema.d.ts +1 -1
- package/dist/auth/account_schema.js +1 -1
- package/dist/auth/admin_action_specs.d.ts +1 -1
- package/dist/auth/admin_action_specs.js +1 -1
- package/dist/auth/admin_actions.d.ts +2 -2
- package/dist/auth/admin_actions.js +2 -2
- package/dist/auth/api_token.d.ts +1 -1
- package/dist/auth/api_token.js +1 -1
- package/dist/auth/audit_log_routes.d.ts +1 -1
- package/dist/auth/audit_log_routes.js +1 -1
- package/dist/auth/audit_log_schema.d.ts +1 -1
- package/dist/auth/daemon_token.d.ts +1 -1
- package/dist/auth/daemon_token.js +1 -1
- package/dist/auth/daemon_token_middleware.d.ts +1 -1
- package/dist/auth/daemon_token_middleware.js +1 -1
- package/dist/auth/ddl.d.ts +1 -1
- package/dist/auth/ddl.js +1 -1
- package/dist/auth/password.d.ts +1 -1
- package/dist/auth/password.js +1 -1
- package/dist/auth/permit_offer_action_specs.d.ts +1 -1
- package/dist/auth/permit_offer_action_specs.js +1 -1
- package/dist/auth/permit_offer_actions.d.ts +1 -1
- package/dist/auth/permit_offer_actions.js +1 -1
- package/dist/auth/route_guards.d.ts +1 -1
- package/dist/auth/route_guards.js +1 -1
- package/dist/auth/self_service_role_action_specs.d.ts +1 -1
- package/dist/auth/self_service_role_action_specs.js +1 -1
- package/dist/auth/self_service_role_actions.d.ts +1 -1
- package/dist/auth/self_service_role_actions.js +1 -1
- package/dist/auth/session_queries.d.ts +1 -1
- package/dist/auth/session_queries.js +1 -1
- package/dist/auth/signup_routes.d.ts +1 -1
- package/dist/auth/signup_routes.js +1 -1
- package/dist/auth/standard_action_specs.d.ts +1 -1
- package/dist/auth/standard_action_specs.js +1 -1
- package/dist/cli/util.d.ts +1 -1
- package/dist/cli/util.js +1 -1
- package/dist/db/create_db.d.ts +2 -2
- package/dist/db/create_db.js +2 -2
- package/dist/db/db.d.ts +3 -3
- package/dist/db/db.js +3 -3
- package/dist/hono_context.d.ts +1 -1
- package/dist/hono_context.js +1 -1
- package/dist/http/jsonrpc_errors.d.ts +2 -2
- package/dist/http/jsonrpc_errors.js +2 -2
- package/dist/http/jsonrpc_helpers.d.ts +2 -2
- package/dist/http/jsonrpc_helpers.js +2 -2
- package/dist/http/middleware_spec.d.ts +1 -1
- package/dist/http/middleware_spec.js +1 -1
- package/dist/http/origin.d.ts +1 -1
- package/dist/http/origin.js +1 -1
- package/dist/http/schema_helpers.d.ts +1 -1
- package/dist/http/schema_helpers.js +1 -1
- package/dist/http/surface.d.ts +1 -1
- package/dist/http/surface.js +1 -1
- package/dist/runtime/deno.d.ts +1 -1
- package/dist/runtime/deno.js +1 -1
- package/dist/runtime/node.d.ts +1 -1
- package/dist/runtime/node.js +1 -1
- package/dist/testing/rpc_attack_surface.js +1 -1
- package/dist/testing/rpc_helpers.js +1 -1
- package/dist/testing/ws_round_trip.js +1 -1
- package/dist/ui/account_sessions_state.svelte.d.ts +2 -2
- package/dist/ui/account_sessions_state.svelte.js +1 -1
- package/dist/ui/admin_rpc_adapters.d.ts +1 -1
- package/dist/ui/admin_rpc_adapters.js +1 -1
- 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
|
|
6
|
-
*
|
|
7
|
-
* this list when filtering backend request_response methods so the
|
|
8
|
-
*
|
|
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
|
|
11
|
-
const
|
|
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
|
|
14
|
-
* `method_filter`. Avoids the `(... as never)` cast
|
|
15
|
-
* `Array.prototype.includes` on the readonly tuple at narrow
|
|
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) => !
|
|
22
|
+
* method_filter: (s) => !is_protocol_action_method(s.method),
|
|
20
23
|
* });
|
|
21
24
|
*/
|
|
22
|
-
export const
|
|
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
|
|
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
|
-
*
|
|
332
|
-
* `
|
|
333
|
-
*
|
|
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
|
-
*
|
|
408
|
-
* array at registration time
|
|
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
|
|
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
|
-
*
|
|
438
|
-
* pass `
|
|
439
|
-
* their typed surface. Empty kinds are skipped so the helper
|
|
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.
|
|
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 =
|
|
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:
|
|
492
|
-
* empty subsets return `''` (skip rather than emit `z.enum([])`),
|
|
493
|
-
* import registered idempotently only when at least one method
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
740
|
+
* (e.g. omit additional methods alongside the default protocol-action
|
|
741
|
+
* filter) via `method_filter`.
|
|
707
742
|
*
|
|
708
|
-
*
|
|
709
|
-
*
|
|
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
|
|
756
|
+
const protocol_filtered = filter_protocol_actions(specs, options?.include_protocol_actions);
|
|
719
757
|
const filter = options?.method_filter;
|
|
720
|
-
const filtered = filter ?
|
|
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 =
|
|
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
|
|
819
|
-
const registry = new ActionRegistry([...
|
|
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
|
|
7
|
-
*
|
|
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
|
|
7
|
-
*
|
|
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
|
*/
|
package/dist/actions/cancel.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared cancel action —
|
|
3
|
-
*
|
|
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
|
|
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`
|
|
17
|
-
* `
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
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
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
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
|
|
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"}
|
package/dist/actions/cancel.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared cancel action —
|
|
3
|
-
*
|
|
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
|
|
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`
|
|
17
|
-
* `
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
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
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
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
|
|
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 —
|
|
3
|
-
*
|
|
4
|
-
* `
|
|
5
|
-
* array so disconnect detection works identically across every
|
|
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
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
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
|
|
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 —
|
|
3
|
-
*
|
|
4
|
-
* `
|
|
5
|
-
* array so disconnect detection works identically across every
|
|
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
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
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"}
|