@fuzdev/fuz_app 0.30.0 → 0.31.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 (207) hide show
  1. package/dist/actions/CLAUDE.md +630 -0
  2. package/dist/actions/action_rpc.d.ts +29 -0
  3. package/dist/actions/action_rpc.d.ts.map +1 -1
  4. package/dist/actions/action_rpc.js +42 -6
  5. package/dist/actions/action_types.d.ts +2 -2
  6. package/dist/actions/cancel.d.ts +12 -13
  7. package/dist/actions/cancel.d.ts.map +1 -1
  8. package/dist/actions/cancel.js +10 -13
  9. package/dist/actions/heartbeat.d.ts +8 -13
  10. package/dist/actions/heartbeat.d.ts.map +1 -1
  11. package/dist/actions/heartbeat.js +5 -8
  12. package/dist/actions/register_action_ws.d.ts +3 -3
  13. package/dist/actions/register_action_ws.js +2 -2
  14. package/dist/actions/register_ws_endpoint.d.ts +4 -4
  15. package/dist/actions/register_ws_endpoint.d.ts.map +1 -1
  16. package/dist/actions/register_ws_endpoint.js +3 -3
  17. package/dist/actions/socket.svelte.d.ts +16 -16
  18. package/dist/actions/socket.svelte.d.ts.map +1 -1
  19. package/dist/actions/socket.svelte.js +15 -15
  20. package/dist/actions/transports_ws_auth_guard.d.ts.map +1 -1
  21. package/dist/auth/CLAUDE.md +923 -0
  22. package/dist/auth/account_action_specs.d.ts +216 -0
  23. package/dist/auth/account_action_specs.d.ts.map +1 -0
  24. package/dist/auth/account_action_specs.js +159 -0
  25. package/dist/auth/account_actions.d.ts +51 -0
  26. package/dist/auth/account_actions.d.ts.map +1 -0
  27. package/dist/auth/account_actions.js +119 -0
  28. package/dist/auth/account_queries.d.ts +6 -2
  29. package/dist/auth/account_queries.d.ts.map +1 -1
  30. package/dist/auth/account_queries.js +40 -4
  31. package/dist/auth/account_routes.d.ts +94 -16
  32. package/dist/auth/account_routes.d.ts.map +1 -1
  33. package/dist/auth/account_routes.js +108 -180
  34. package/dist/auth/account_schema.d.ts +85 -30
  35. package/dist/auth/account_schema.d.ts.map +1 -1
  36. package/dist/auth/account_schema.js +40 -8
  37. package/dist/auth/admin_action_specs.d.ts +674 -0
  38. package/dist/auth/admin_action_specs.d.ts.map +1 -0
  39. package/dist/auth/admin_action_specs.js +287 -0
  40. package/dist/auth/admin_actions.d.ts +69 -0
  41. package/dist/auth/admin_actions.d.ts.map +1 -0
  42. package/dist/auth/admin_actions.js +256 -0
  43. package/dist/auth/api_token.d.ts +10 -0
  44. package/dist/auth/api_token.d.ts.map +1 -1
  45. package/dist/auth/api_token.js +9 -0
  46. package/dist/auth/api_token_queries.d.ts +3 -3
  47. package/dist/auth/api_token_queries.js +3 -3
  48. package/dist/auth/app_settings_schema.d.ts +4 -3
  49. package/dist/auth/app_settings_schema.d.ts.map +1 -1
  50. package/dist/auth/app_settings_schema.js +2 -1
  51. package/dist/auth/audit_log_routes.d.ts +14 -6
  52. package/dist/auth/audit_log_routes.d.ts.map +1 -1
  53. package/dist/auth/audit_log_routes.js +22 -79
  54. package/dist/auth/audit_log_schema.d.ts +100 -29
  55. package/dist/auth/audit_log_schema.d.ts.map +1 -1
  56. package/dist/auth/audit_log_schema.js +83 -11
  57. package/dist/auth/bootstrap_routes.d.ts +14 -0
  58. package/dist/auth/bootstrap_routes.d.ts.map +1 -1
  59. package/dist/auth/bootstrap_routes.js +10 -3
  60. package/dist/auth/cleanup.d.ts +63 -0
  61. package/dist/auth/cleanup.d.ts.map +1 -0
  62. package/dist/auth/cleanup.js +80 -0
  63. package/dist/auth/invite_schema.d.ts +11 -10
  64. package/dist/auth/invite_schema.d.ts.map +1 -1
  65. package/dist/auth/invite_schema.js +4 -3
  66. package/dist/auth/migrations.d.ts +6 -0
  67. package/dist/auth/migrations.d.ts.map +1 -1
  68. package/dist/auth/migrations.js +28 -0
  69. package/dist/auth/permit_offer_action_specs.d.ts +364 -0
  70. package/dist/auth/permit_offer_action_specs.d.ts.map +1 -0
  71. package/dist/auth/permit_offer_action_specs.js +216 -0
  72. package/dist/auth/permit_offer_actions.d.ts +96 -0
  73. package/dist/auth/permit_offer_actions.d.ts.map +1 -0
  74. package/dist/auth/permit_offer_actions.js +428 -0
  75. package/dist/auth/permit_offer_notifications.d.ts +361 -0
  76. package/dist/auth/permit_offer_notifications.d.ts.map +1 -0
  77. package/dist/auth/permit_offer_notifications.js +179 -0
  78. package/dist/auth/permit_offer_queries.d.ts +165 -0
  79. package/dist/auth/permit_offer_queries.d.ts.map +1 -0
  80. package/dist/auth/permit_offer_queries.js +390 -0
  81. package/dist/auth/permit_offer_schema.d.ts +103 -0
  82. package/dist/auth/permit_offer_schema.d.ts.map +1 -0
  83. package/dist/auth/permit_offer_schema.js +142 -0
  84. package/dist/auth/permit_queries.d.ts +77 -14
  85. package/dist/auth/permit_queries.d.ts.map +1 -1
  86. package/dist/auth/permit_queries.js +119 -24
  87. package/dist/auth/session_queries.d.ts +4 -2
  88. package/dist/auth/session_queries.d.ts.map +1 -1
  89. package/dist/auth/session_queries.js +4 -2
  90. package/dist/auth/signup_routes.d.ts +13 -0
  91. package/dist/auth/signup_routes.d.ts.map +1 -1
  92. package/dist/auth/signup_routes.js +14 -7
  93. package/dist/http/CLAUDE.md +584 -0
  94. package/dist/http/pending_effects.d.ts +29 -0
  95. package/dist/http/pending_effects.d.ts.map +1 -0
  96. package/dist/http/pending_effects.js +31 -0
  97. package/dist/http/route_spec.d.ts.map +1 -1
  98. package/dist/http/route_spec.js +4 -3
  99. package/dist/rate_limiter.d.ts +30 -0
  100. package/dist/rate_limiter.d.ts.map +1 -1
  101. package/dist/rate_limiter.js +25 -2
  102. package/dist/realtime/sse_auth_guard.d.ts +2 -0
  103. package/dist/realtime/sse_auth_guard.d.ts.map +1 -1
  104. package/dist/realtime/sse_auth_guard.js +5 -3
  105. package/dist/testing/CLAUDE.md +668 -1
  106. package/dist/testing/admin_integration.d.ts +10 -7
  107. package/dist/testing/admin_integration.d.ts.map +1 -1
  108. package/dist/testing/admin_integration.js +382 -482
  109. package/dist/testing/app_server.d.ts +7 -6
  110. package/dist/testing/app_server.d.ts.map +1 -1
  111. package/dist/testing/attack_surface.d.ts +9 -3
  112. package/dist/testing/attack_surface.d.ts.map +1 -1
  113. package/dist/testing/attack_surface.js +4 -4
  114. package/dist/testing/audit_completeness.d.ts +6 -0
  115. package/dist/testing/audit_completeness.d.ts.map +1 -1
  116. package/dist/testing/audit_completeness.js +158 -134
  117. package/dist/testing/auth_apps.d.ts.map +1 -1
  118. package/dist/testing/auth_apps.js +4 -33
  119. package/dist/testing/db.d.ts +1 -1
  120. package/dist/testing/db.d.ts.map +1 -1
  121. package/dist/testing/db.js +2 -0
  122. package/dist/testing/entities.d.ts +35 -13
  123. package/dist/testing/entities.d.ts.map +1 -1
  124. package/dist/testing/entities.js +17 -0
  125. package/dist/testing/integration.d.ts +10 -0
  126. package/dist/testing/integration.d.ts.map +1 -1
  127. package/dist/testing/integration.js +352 -340
  128. package/dist/testing/integration_helpers.d.ts +16 -5
  129. package/dist/testing/integration_helpers.d.ts.map +1 -1
  130. package/dist/testing/integration_helpers.js +24 -4
  131. package/dist/testing/rate_limiting.d.ts +7 -0
  132. package/dist/testing/rate_limiting.d.ts.map +1 -1
  133. package/dist/testing/rate_limiting.js +41 -10
  134. package/dist/testing/rpc_helpers.d.ts +153 -1
  135. package/dist/testing/rpc_helpers.d.ts.map +1 -1
  136. package/dist/testing/rpc_helpers.js +184 -8
  137. package/dist/testing/sse_round_trip.d.ts +8 -0
  138. package/dist/testing/sse_round_trip.d.ts.map +1 -1
  139. package/dist/testing/sse_round_trip.js +10 -3
  140. package/dist/testing/standard.d.ts +9 -1
  141. package/dist/testing/standard.d.ts.map +1 -1
  142. package/dist/testing/standard.js +6 -2
  143. package/dist/testing/surface_invariants.d.ts +7 -3
  144. package/dist/testing/surface_invariants.d.ts.map +1 -1
  145. package/dist/testing/surface_invariants.js +5 -4
  146. package/dist/testing/ws_round_trip.d.ts.map +1 -1
  147. package/dist/testing/ws_round_trip.js +9 -38
  148. package/dist/ui/AccountSessions.svelte +8 -4
  149. package/dist/ui/AccountSessions.svelte.d.ts.map +1 -1
  150. package/dist/ui/AdminAccounts.svelte +61 -33
  151. package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -1
  152. package/dist/ui/AdminAuditLog.svelte +3 -2
  153. package/dist/ui/AdminAuditLog.svelte.d.ts.map +1 -1
  154. package/dist/ui/AdminInvites.svelte +3 -2
  155. package/dist/ui/AdminInvites.svelte.d.ts.map +1 -1
  156. package/dist/ui/AdminOverview.svelte +14 -9
  157. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
  158. package/dist/ui/AdminPermitHistory.svelte +3 -2
  159. package/dist/ui/AdminPermitHistory.svelte.d.ts.map +1 -1
  160. package/dist/ui/AdminSessions.svelte +29 -25
  161. package/dist/ui/AdminSessions.svelte.d.ts.map +1 -1
  162. package/dist/ui/CLAUDE.md +351 -0
  163. package/dist/ui/OpenSignupToggle.svelte +6 -3
  164. package/dist/ui/OpenSignupToggle.svelte.d.ts.map +1 -1
  165. package/dist/ui/PermitOfferForm.svelte +141 -0
  166. package/dist/ui/PermitOfferForm.svelte.d.ts +14 -0
  167. package/dist/ui/PermitOfferForm.svelte.d.ts.map +1 -0
  168. package/dist/ui/PermitOfferHistory.svelte +109 -0
  169. package/dist/ui/PermitOfferHistory.svelte.d.ts +11 -0
  170. package/dist/ui/PermitOfferHistory.svelte.d.ts.map +1 -0
  171. package/dist/ui/PermitOfferInbox.svelte +121 -0
  172. package/dist/ui/PermitOfferInbox.svelte.d.ts +12 -0
  173. package/dist/ui/PermitOfferInbox.svelte.d.ts.map +1 -0
  174. package/dist/ui/account_sessions_state.svelte.d.ts +53 -3
  175. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
  176. package/dist/ui/account_sessions_state.svelte.js +39 -16
  177. package/dist/ui/admin_accounts_state.svelte.d.ts +118 -2
  178. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
  179. package/dist/ui/admin_accounts_state.svelte.js +99 -23
  180. package/dist/ui/admin_invites_state.svelte.d.ts +47 -1
  181. package/dist/ui/admin_invites_state.svelte.d.ts.map +1 -1
  182. package/dist/ui/admin_invites_state.svelte.js +38 -26
  183. package/dist/ui/admin_sessions_state.svelte.d.ts +26 -0
  184. package/dist/ui/admin_sessions_state.svelte.d.ts.map +1 -1
  185. package/dist/ui/admin_sessions_state.svelte.js +35 -21
  186. package/dist/ui/app_settings_state.svelte.d.ts +39 -0
  187. package/dist/ui/app_settings_state.svelte.d.ts.map +1 -1
  188. package/dist/ui/app_settings_state.svelte.js +34 -18
  189. package/dist/ui/audit_log_state.svelte.d.ts +40 -3
  190. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
  191. package/dist/ui/audit_log_state.svelte.js +36 -42
  192. package/dist/ui/auth_state.svelte.d.ts +4 -3
  193. package/dist/ui/auth_state.svelte.d.ts.map +1 -1
  194. package/dist/ui/auth_state.svelte.js +4 -1
  195. package/dist/ui/permit_offers_state.svelte.d.ts +125 -0
  196. package/dist/ui/permit_offers_state.svelte.d.ts.map +1 -0
  197. package/dist/ui/permit_offers_state.svelte.js +197 -0
  198. package/package.json +3 -3
  199. package/dist/auth/admin_routes.d.ts +0 -29
  200. package/dist/auth/admin_routes.d.ts.map +0 -1
  201. package/dist/auth/admin_routes.js +0 -226
  202. package/dist/auth/app_settings_routes.d.ts +0 -27
  203. package/dist/auth/app_settings_routes.d.ts.map +0 -1
  204. package/dist/auth/app_settings_routes.js +0 -66
  205. package/dist/auth/invite_routes.d.ts +0 -18
  206. package/dist/auth/invite_routes.d.ts.map +0 -1
  207. package/dist/auth/invite_routes.js +0 -129
@@ -11,6 +11,7 @@
11
11
  *
12
12
  * @module
13
13
  */
14
+ import { z } from 'zod';
14
15
  import type { Logger } from '@fuzdev/fuz_util/log.js';
15
16
  import type { RequestResponseActionSpec } from './action_spec.js';
16
17
  import { type RouteSpec } from '../http/route_spec.js';
@@ -35,6 +36,15 @@ export interface ActionContext {
35
36
  background_db: Db;
36
37
  /** Fire-and-forget side effects — push here for post-response flushing. */
37
38
  pending_effects: Array<Promise<void>>;
39
+ /**
40
+ * Resolved client IP from the trusted-proxy middleware — `'unknown'` if the
41
+ * middleware wasn't in the stack (e.g. WS dispatch) or couldn't resolve.
42
+ * Thread into `audit_log_fire_and_forget` as `ip: ctx.client_ip` for every
43
+ * user-initiated action so RPC audit rows match the REST convention. Pass
44
+ * `null` only for rows written outside a request (e.g. the
45
+ * `permit_offer_expire` cleanup sweep in `auth/cleanup.ts`).
46
+ */
47
+ client_ip: string;
38
48
  /** Logger instance. */
39
49
  log: Logger;
40
50
  /**
@@ -71,6 +81,25 @@ export interface RpcAction {
71
81
  spec: RequestResponseActionSpec;
72
82
  handler: ActionHandler;
73
83
  }
84
+ /**
85
+ * Pair a spec with a handler while preserving per-method input/output types.
86
+ *
87
+ * Constructing `{spec, handler}` literals widens `handler` to
88
+ * `ActionHandler<any, any>`, so spec/handler drift (renamed Zod schema,
89
+ * output field removal, input shape change) slips past the typechecker.
90
+ * `rpc_action(spec, handler)` binds the handler signature to
91
+ * `(input: z.infer<spec.input>, ctx) => z.infer<spec.output>` via the
92
+ * generic spec parameter — drift surfaces at the call site.
93
+ *
94
+ * Fits fuz_app's factory-closure pattern (handlers close over
95
+ * `grantable_roles`, `app_settings` ref, `notification_sender`, etc.).
96
+ * zzz uses a different shape — a codegen-keyed `Record<Method, Handler>`
97
+ * map typed via generated `ActionInputs`/`ActionOutputs` — which works when
98
+ * handlers are pure (no closure state) and specs are codegen-enumerated.
99
+ * fuz_app's admin + permit-offer actions have neither, so per-pair typing
100
+ * at the registration site is the right fit.
101
+ */
102
+ export declare const rpc_action: <TSpec extends RequestResponseActionSpec>(spec: TSpec, handler: ActionHandler<z.infer<TSpec["input"]>, z.infer<TSpec["output"]>>) => RpcAction;
74
103
  /** Options for `create_rpc_endpoint`. */
75
104
  export interface CreateRpcEndpointOptions {
76
105
  /** Mount path for the endpoint (e.g., `/api/rpc`). */
@@ -1 +1 @@
1
- {"version":3,"file":"action_rpc.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAgC,KAAK,cAAc,EAAC,MAAM,4BAA4B,CAAC;AAE9F,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAEpC,OAAO,EAGN,KAAK,gBAAgB,EAGrB,MAAM,oBAAoB,CAAC;AAO5B;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B,+DAA+D;IAC/D,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,iDAAiD;IACjD,UAAU,EAAE,gBAAgB,CAAC;IAC7B,8DAA8D;IAC9D,EAAE,EAAE,EAAE,CAAC;IACP,oFAAoF;IACpF,aAAa,EAAE,EAAE,CAAC;IAClB,2EAA2E;IAC3E,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;OAQG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD;;;;OAIG;IACH,MAAM,EAAE,WAAW,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,CACxD,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,aAAa,KACd,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,EAAE,aAAa,CAAC;CACvB;AAED,yCAAyC;AACzC,MAAM,WAAW,wBAAwB;IACxC,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC1B,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;CACZ;AAkDD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,wBAAwB,KAAG,KAAK,CAAC,SAAS,CAqPtF,CAAC"}
1
+ {"version":3,"file":"action_rpc.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/action_rpc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAoB,KAAK,SAAS,EAAC,MAAM,uBAAuB,CAAC;AAExE,OAAO,EAAgC,KAAK,cAAc,EAAC,MAAM,4BAA4B,CAAC;AAE9F,OAAO,KAAK,EAAC,EAAE,EAAC,MAAM,aAAa,CAAC;AAEpC,OAAO,EAGN,KAAK,gBAAgB,EAGrB,MAAM,oBAAoB,CAAC;AAW5B;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B,+DAA+D;IAC/D,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,iDAAiD;IACjD,UAAU,EAAE,gBAAgB,CAAC;IAC7B,8DAA8D;IAC9D,EAAE,EAAE,EAAE,CAAC;IACP,oFAAoF;IACpF,aAAa,EAAE,EAAE,CAAC;IAClB,2EAA2E;IAC3E,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;;OAQG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClD;;;;OAIG;IACH,MAAM,EAAE,WAAW,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,CACxD,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,aAAa,KACd,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,yBAAyB,CAAC;IAChC,OAAO,EAAE,aAAa,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,UAAU,GAAI,KAAK,SAAS,yBAAyB,EACjE,MAAM,KAAK,EACX,SAAS,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,KACvE,SAGD,CAAC;AAEH,yCAAyC;AACzC,MAAM,WAAW,wBAAwB;IACxC,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC1B,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;CACZ;AA4DD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,wBAAwB,KAAG,KAAK,CAAC,SAAS,CAwPtF,CAAC"}
@@ -14,11 +14,35 @@
14
14
  import { z } from 'zod';
15
15
  import { DEV } from 'esm-env';
16
16
  import {} from '../http/route_spec.js';
17
+ import { get_client_ip } from '../http/proxy.js';
17
18
  import { get_request_context, has_role } from '../auth/request_context.js';
18
19
  import { CREDENTIAL_TYPE_KEY } from '../hono_context.js';
19
20
  import { is_null_schema } from '../http/schema_helpers.js';
20
21
  import { JSONRPC_VERSION, JsonrpcRequest, } from '../http/jsonrpc.js';
21
22
  import { jsonrpc_error_messages, jsonrpc_error_code_to_http_status, JSONRPC_ERROR_CODES, } from '../http/jsonrpc_errors.js';
23
+ import { ERROR_INSUFFICIENT_PERMISSIONS, ERROR_KEEPER_REQUIRES_DAEMON_TOKEN, } from '../http/error_schemas.js';
24
+ /**
25
+ * Pair a spec with a handler while preserving per-method input/output types.
26
+ *
27
+ * Constructing `{spec, handler}` literals widens `handler` to
28
+ * `ActionHandler<any, any>`, so spec/handler drift (renamed Zod schema,
29
+ * output field removal, input shape change) slips past the typechecker.
30
+ * `rpc_action(spec, handler)` binds the handler signature to
31
+ * `(input: z.infer<spec.input>, ctx) => z.infer<spec.output>` via the
32
+ * generic spec parameter — drift surfaces at the call site.
33
+ *
34
+ * Fits fuz_app's factory-closure pattern (handlers close over
35
+ * `grantable_roles`, `app_settings` ref, `notification_sender`, etc.).
36
+ * zzz uses a different shape — a codegen-keyed `Record<Method, Handler>`
37
+ * map typed via generated `ActionInputs`/`ActionOutputs` — which works when
38
+ * handlers are pure (no closure state) and specs are codegen-enumerated.
39
+ * fuz_app's admin + permit-offer actions have neither, so per-pair typing
40
+ * at the registration site is the right fit.
41
+ */
42
+ export const rpc_action = (spec, handler) => ({
43
+ spec,
44
+ handler: handler,
45
+ });
22
46
  /**
23
47
  * Format a JSON-RPC error response.
24
48
  *
@@ -49,15 +73,25 @@ const check_action_auth = (auth, request_context, credential_type) => {
49
73
  if (auth === 'keeper') {
50
74
  // keeper requires daemon_token credential type AND the keeper role.
51
75
  // API tokens and session cookies cannot access keeper actions even
52
- // if the account has the keeper permit.
76
+ // if the account has the keeper permit. Attach the credential type
77
+ // under `data` so clients can distinguish "wrong credential shape"
78
+ // from "missing keeper role" — mirrors REST 403 semantics.
53
79
  if (credential_type !== 'daemon_token' || !has_role(request_context, 'keeper')) {
54
- return jsonrpc_error_messages.forbidden();
80
+ return jsonrpc_error_messages.forbidden('forbidden', {
81
+ reason: ERROR_KEEPER_REQUIRES_DAEMON_TOKEN,
82
+ credential_type,
83
+ });
55
84
  }
56
85
  return null;
57
86
  }
58
- // role check
87
+ // role check — attach `required_role` under `data.required_role` so
88
+ // clients can render targeted copy (matches the former REST `PermissionError`
89
+ // shape that exposed `required_role` as a top-level field).
59
90
  if (!has_role(request_context, auth.role)) {
60
- return jsonrpc_error_messages.forbidden(`requires role: ${auth.role}`);
91
+ return jsonrpc_error_messages.forbidden(`requires role: ${auth.role}`, {
92
+ reason: ERROR_INSUFFICIENT_PERMISSIONS,
93
+ required_role: auth.role,
94
+ });
61
95
  }
62
96
  return null;
63
97
  };
@@ -145,6 +179,7 @@ export const create_rpc_endpoint = (options) => {
145
179
  }
146
180
  };
147
181
  const signal = c.req.raw.signal;
182
+ const client_ip = get_client_ip(c);
148
183
  const execute = async (db) => {
149
184
  const action_context = {
150
185
  auth: request_context,
@@ -152,16 +187,17 @@ export const create_rpc_endpoint = (options) => {
152
187
  db,
153
188
  background_db: route.background_db,
154
189
  pending_effects: route.pending_effects,
190
+ client_ip,
155
191
  log,
156
192
  notify,
157
193
  signal,
158
194
  };
159
195
  const output = await action.handler(parse_result.data, action_context);
160
- // DEV-only output validation
196
+ // DEV-only output validation — logs an error on mismatch, does not throw.
161
197
  if (DEV) {
162
198
  const output_result = action.spec.output.safeParse(output);
163
199
  if (!output_result.success) {
164
- log.warn(`RPC output schema mismatch: ${method_name}`, output_result.error.issues);
200
+ log.error(`RPC output schema mismatch: ${method_name}`, output_result.error.issues);
165
201
  }
166
202
  }
167
203
  return c.json({ jsonrpc: JSONRPC_VERSION, id, result: output });
@@ -54,8 +54,8 @@ export interface BaseHandlerContext {
54
54
  export type WsActionHandler<TCtx extends BaseHandlerContext = BaseHandlerContext> = (input: unknown, ctx: TCtx) => unknown;
55
55
  /**
56
56
  * A spec paired with its optional handler — the composable unit passed to
57
- * {@link register_action_ws} and {@link create_rpc_client}. The server uses
58
- * both fields; the client reads only {@link spec} (the {@link handler} is
57
+ * `register_action_ws` and `create_rpc_client`. The server uses
58
+ * both fields; the client reads only `spec` (the `handler` is
59
59
  * ignored, harmless). Shared fuz_app primitives (e.g. `heartbeat_action`)
60
60
  * export a complete tuple so consumers spread them into both sides'
61
61
  * `actions` array without inventing per-repo ping plumbing.
@@ -4,7 +4,7 @@
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.
7
- * {@link register_action_ws} intercepts this notification and aborts the
7
+ * `register_action_ws` intercepts this notification and aborts the
8
8
  * matching pending request's `ctx.signal`. Unknown ids are no-ops by design —
9
9
  * races between response arrival and cancel delivery are safe without extra
10
10
  * coordination.
@@ -12,8 +12,8 @@
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
14
  * handler). The handler exists for symmetry with other composable primitives
15
- * like {@link heartbeat_action}; the dispatcher never calls it. Consumers
16
- * spread {@link cancel_action} into their server's `actions` array so
15
+ * like `heartbeat_action`; the dispatcher never calls it. Consumers
16
+ * spread `cancel_action` into their server's `actions` array so
17
17
  * `spec_by_method` knows about it (enabling input validation on incoming
18
18
  * cancels) and so `create_rpc_client` codegen produces `app.api.cancel()`
19
19
  * when desired — though `FrontendWebsocketClient.request({signal})` sends
@@ -29,11 +29,9 @@
29
29
  */
30
30
  import { z } from 'zod';
31
31
  import type { Action } from './action_types.js';
32
- /** Method name on the wire — shared across every fuz_app consumer. */
33
- export declare const CANCEL_METHOD = "cancel";
34
32
  /**
35
- * Params for a {@link CANCEL_METHOD} notification. `request_id` is the id of
36
- * the pending request to abort. Must match the id of a request sent on the
33
+ * Params for the `cancel` notification. `request_id` is the id of the
34
+ * pending request to abort. Must match the id of a request sent on the
37
35
  * same socket; cancels from other sockets (or for unknown ids) are ignored.
38
36
  */
39
37
  export declare const CancelNotificationParams: z.ZodObject<{
@@ -50,19 +48,20 @@ export type CancelNotificationParams = z.infer<typeof CancelNotificationParams>;
50
48
  */
51
49
  export declare const cancel_action_spec: {
52
50
  method: string;
53
- initiator: "both" | "frontend" | "backend";
54
- input: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
55
- description: string;
56
51
  kind: "remote_notification";
52
+ initiator: "frontend";
57
53
  auth: null;
58
54
  side_effects: true;
55
+ input: z.ZodObject<{
56
+ request_id: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
57
+ }, z.core.$strict>;
59
58
  output: z.ZodVoid;
60
59
  async: true;
61
- streams?: string | undefined;
60
+ description: string;
62
61
  };
63
62
  /**
64
- * Placeholder handler — cancel semantics are owned by {@link register_action_ws},
65
- * not invoked per-handler. Exported for symmetry with the {@link Action}
63
+ * Placeholder handler — cancel semantics are owned by `register_action_ws`,
64
+ * not invoked per-handler. Exported for symmetry with the `Action`
66
65
  * tuple shape; the dispatcher short-circuits cancel notifications before any
67
66
  * handler lookup happens.
68
67
  */
@@ -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,sEAAsE;AACtE,eAAO,MAAM,aAAa,WAAW,CAAC;AAEtC;;;;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;;;;;;;;;;;CAW7B,CAAC;AAEH;;;;;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;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
@@ -4,7 +4,7 @@
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.
7
- * {@link register_action_ws} intercepts this notification and aborts the
7
+ * `register_action_ws` intercepts this notification and aborts the
8
8
  * matching pending request's `ctx.signal`. Unknown ids are no-ops by design —
9
9
  * races between response arrival and cancel delivery are safe without extra
10
10
  * coordination.
@@ -12,8 +12,8 @@
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
14
  * handler). The handler exists for symmetry with other composable primitives
15
- * like {@link heartbeat_action}; the dispatcher never calls it. Consumers
16
- * spread {@link cancel_action} into their server's `actions` array so
15
+ * like `heartbeat_action`; the dispatcher never calls it. Consumers
16
+ * spread `cancel_action` into their server's `actions` array so
17
17
  * `spec_by_method` knows about it (enabling input validation on incoming
18
18
  * cancels) and so `create_rpc_client` codegen produces `app.api.cancel()`
19
19
  * when desired — though `FrontendWebsocketClient.request({signal})` sends
@@ -29,12 +29,9 @@
29
29
  */
30
30
  import { z } from 'zod';
31
31
  import { JsonrpcRequestId } from '../http/jsonrpc.js';
32
- import { RemoteNotificationActionSpec } from './action_spec.js';
33
- /** Method name on the wire — shared across every fuz_app consumer. */
34
- export const CANCEL_METHOD = 'cancel';
35
32
  /**
36
- * Params for a {@link CANCEL_METHOD} notification. `request_id` is the id of
37
- * the pending request to abort. Must match the id of a request sent on the
33
+ * Params for the `cancel` notification. `request_id` is the id of the
34
+ * pending request to abort. Must match the id of a request sent on the
38
35
  * same socket; cancels from other sockets (or for unknown ids) are ignored.
39
36
  */
40
37
  export const CancelNotificationParams = z.strictObject({
@@ -48,8 +45,8 @@ export const CancelNotificationParams = z.strictObject({
48
45
  * ownership naturally: a different socket's cancel for the same id misses
49
46
  * in its own map.
50
47
  */
51
- export const cancel_action_spec = RemoteNotificationActionSpec.parse({
52
- method: CANCEL_METHOD,
48
+ export const cancel_action_spec = {
49
+ method: 'cancel',
53
50
  kind: 'remote_notification',
54
51
  initiator: 'frontend',
55
52
  auth: null,
@@ -58,10 +55,10 @@ export const cancel_action_spec = RemoteNotificationActionSpec.parse({
58
55
  output: z.void(),
59
56
  async: true,
60
57
  description: 'Client-initiated cancellation of an in-flight request by id. Dispatcher-handled: aborts the ctx.signal of the matching pending request on the same socket. Unknown or completed ids no-op.',
61
- });
58
+ };
62
59
  /**
63
- * Placeholder handler — cancel semantics are owned by {@link register_action_ws},
64
- * not invoked per-handler. Exported for symmetry with the {@link Action}
60
+ * Placeholder handler — cancel semantics are owned by `register_action_ws`,
61
+ * not invoked per-handler. Exported for symmetry with the `Action`
65
62
  * tuple shape; the dispatcher short-circuits cancel notifications before any
66
63
  * handler lookup happens.
67
64
  */
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Shared heartbeat action — the first composable fuz_app primitive carrying
3
3
  * both a spec and a handler in one tuple. Consumers spread
4
- * {@link heartbeat_action} into both the server's and the client's `actions`
4
+ * `heartbeat_action` into both the server's and the client's `actions`
5
5
  * array so disconnect detection works identically across every repo without
6
6
  * per-consumer ping plumbing.
7
7
  *
@@ -12,15 +12,13 @@
12
12
  * alive without any handler-level state.
13
13
  *
14
14
  * Nullary input/output today. `{client_ts, server_ts}` fields can be added
15
- * later if clock-skew telemetry ever matters — the {@link Action} container
15
+ * later if clock-skew telemetry ever matters — the `Action` container
16
16
  * is open for additions without churning consumer call sites.
17
17
  *
18
18
  * @module
19
19
  */
20
20
  import { z } from 'zod';
21
21
  import type { Action } from './action_types.js';
22
- /** Method name on the wire — shared across every fuz_app consumer. */
23
- export declare const HEARTBEAT_METHOD = "heartbeat";
24
22
  /**
25
23
  * `ActionSpec` for the shared heartbeat. `authenticated` auth — upgrade-time
26
24
  * auth has already admitted the socket; heartbeats don't need role gating.
@@ -28,17 +26,14 @@ export declare const HEARTBEAT_METHOD = "heartbeat";
28
26
  */
29
27
  export declare const heartbeat_action_spec: {
30
28
  method: string;
31
- initiator: "both" | "frontend" | "backend";
32
- side_effects: boolean;
33
- input: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
34
- output: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
35
- description: string;
36
29
  kind: "request_response";
37
- auth: "authenticated" | "keeper" | "public" | {
38
- role: string;
39
- };
30
+ initiator: "frontend";
31
+ auth: "authenticated";
32
+ side_effects: false;
33
+ input: z.ZodObject<{}, z.core.$strict>;
34
+ output: z.ZodObject<{}, z.core.$strict>;
40
35
  async: true;
41
- streams?: string | undefined;
36
+ description: string;
42
37
  };
43
38
  /** Handler — nullary echo. Stateless, suitable for high-frequency pings. */
44
39
  export declare const heartbeat_handler: () => Record<string, never>;
@@ -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,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,cAAc,CAAC;AAE5C;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;CAUhC,CAAC;AAEH,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;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAG9B,CAAC"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Shared heartbeat action — the first composable fuz_app primitive carrying
3
3
  * both a spec and a handler in one tuple. Consumers spread
4
- * {@link heartbeat_action} into both the server's and the client's `actions`
4
+ * `heartbeat_action` into both the server's and the client's `actions`
5
5
  * array so disconnect detection works identically across every repo without
6
6
  * per-consumer ping plumbing.
7
7
  *
@@ -12,22 +12,19 @@
12
12
  * alive without any handler-level state.
13
13
  *
14
14
  * Nullary input/output today. `{client_ts, server_ts}` fields can be added
15
- * later if clock-skew telemetry ever matters — the {@link Action} container
15
+ * later if clock-skew telemetry ever matters — the `Action` container
16
16
  * is open for additions without churning consumer call sites.
17
17
  *
18
18
  * @module
19
19
  */
20
20
  import { z } from 'zod';
21
- import { RequestResponseActionSpec } from './action_spec.js';
22
- /** Method name on the wire — shared across every fuz_app consumer. */
23
- export const HEARTBEAT_METHOD = 'heartbeat';
24
21
  /**
25
22
  * `ActionSpec` for the shared heartbeat. `authenticated` auth — upgrade-time
26
23
  * auth has already admitted the socket; heartbeats don't need role gating.
27
24
  * `side_effects: false` keeps it orthogonal to state changes.
28
25
  */
29
- export const heartbeat_action_spec = RequestResponseActionSpec.parse({
30
- method: HEARTBEAT_METHOD,
26
+ export const heartbeat_action_spec = {
27
+ method: 'heartbeat',
31
28
  kind: 'request_response',
32
29
  initiator: 'frontend',
33
30
  auth: 'authenticated',
@@ -36,7 +33,7 @@ export const heartbeat_action_spec = RequestResponseActionSpec.parse({
36
33
  output: z.strictObject({}),
37
34
  async: true,
38
35
  description: 'Shared activity ping — keeps the socket alive and exercises the dispatch path.',
39
- });
36
+ };
40
37
  /** Handler — nullary echo. Stateless, suitable for high-frequency pings. */
41
38
  export const heartbeat_handler = () => ({});
42
39
  /**
@@ -79,8 +79,8 @@ export interface SocketCloseContext {
79
79
  export interface ServerHeartbeatOptions {
80
80
  /**
81
81
  * Receive-silence (ms) past which the server closes the socket with
82
- * {@link WS_CLOSE_SERVER_HEARTBEAT_TIMEOUT}. Any incoming message resets
83
- * the counter — chatty clients never trip it. First {@link timeout}
82
+ * `WS_CLOSE_SERVER_HEARTBEAT_TIMEOUT`. Any incoming message resets
83
+ * the counter — chatty clients never trip it. First `timeout`
84
84
  * window after socket open is exempt (cold-start grace).
85
85
  */
86
86
  timeout?: number;
@@ -97,7 +97,7 @@ export interface RegisterActionWsOptions<TCtx extends BaseHandlerContext> {
97
97
  * The actions registered on this endpoint — each carries a spec (drives
98
98
  * method lookup, per-action auth, input/output validation) and an
99
99
  * optional handler (omit for client-only specs like inbound
100
- * notifications). Include the shared {@link heartbeat_action} here to
100
+ * notifications). Include the shared `heartbeat_action` here to
101
101
  * complete the disconnect-detection pairing with the frontend client.
102
102
  */
103
103
  actions: ReadonlyArray<Action<TCtx>>;
@@ -39,7 +39,7 @@ import { jsonrpc_error_messages, ThrownJsonrpcError } from '../http/jsonrpc_erro
39
39
  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';
40
40
  import { CREDENTIAL_TYPE_KEY, AUTH_API_TOKEN_ID_KEY } from '../hono_context.js';
41
41
  import {} from './action_types.js';
42
- import { CANCEL_METHOD, CancelNotificationParams } from './cancel.js';
42
+ import { cancel_action_spec, CancelNotificationParams } from './cancel.js';
43
43
  import { WS_CLOSE_SERVER_HEARTBEAT_TIMEOUT } from './transports.js';
44
44
  import { BackendWebsocketTransport } from './transports_ws_backend.js';
45
45
  /** Default inactivity window before the server closes a silent socket. */
@@ -206,7 +206,7 @@ export const register_action_ws = (options) => {
206
206
  // are not a feature yet).
207
207
  if (!is_jsonrpc_request(json)) {
208
208
  if (typeof json === 'object' && json !== null && 'method' in json && !('id' in json)) {
209
- if (json.method === CANCEL_METHOD) {
209
+ if (json.method === cancel_action_spec.method) {
210
210
  const parsed = CancelNotificationParams.safeParse(json.params);
211
211
  if (!parsed.success) {
212
212
  log.debug('cancel: invalid params, ignoring', parsed.error.issues);
@@ -10,7 +10,7 @@
10
10
  * 3. Optional `require_role(required_role)` — for endpoints gated to a
11
11
  * specific role.
12
12
  *
13
- * Then delegates to {@link register_action_ws} for per-message JSON-RPC
13
+ * Then delegates to `register_action_ws` for per-message JSON-RPC
14
14
  * dispatch.
15
15
  *
16
16
  * @module
@@ -18,7 +18,7 @@
18
18
  import type { RoleName } from '../auth/role_schema.js';
19
19
  import { type RegisterActionWsOptions, type RegisterActionWsResult } from './register_action_ws.js';
20
20
  import type { BaseHandlerContext } from './action_types.js';
21
- /** Options for {@link register_ws_endpoint}. */
21
+ /** Options for `register_ws_endpoint`. */
22
22
  export interface RegisterWsEndpointOptions<TCtx extends BaseHandlerContext> extends RegisterActionWsOptions<TCtx> {
23
23
  /**
24
24
  * Origin allowlist regexes — typically parsed from the `ALLOWED_ORIGINS`
@@ -38,8 +38,8 @@ export interface RegisterWsEndpointOptions<TCtx extends BaseHandlerContext> exte
38
38
  * Mount a WebSocket endpoint with the standard upgrade stack (origin check
39
39
  * + auth + optional role) and JSON-RPC dispatch.
40
40
  *
41
- * Returns the {@link BackendWebsocketTransport} (supplied or freshly
42
- * created), same as {@link register_action_ws} — retain it to wire
41
+ * Returns the `BackendWebsocketTransport` (supplied or freshly
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
44
  */
45
45
  export declare const register_ws_endpoint: <TCtx extends BaseHandlerContext>(options: RegisterWsEndpointOptions<TCtx>) => RegisterActionWsResult;
@@ -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,gDAAgD;AAChD,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;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAI,IAAI,SAAS,kBAAkB,EACnE,SAAS,yBAAyB,CAAC,IAAI,CAAC,KACtC,sBAUF,CAAC"}
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;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAI,IAAI,SAAS,kBAAkB,EACnE,SAAS,yBAAyB,CAAC,IAAI,CAAC,KACtC,sBAUF,CAAC"}
@@ -10,7 +10,7 @@
10
10
  * 3. Optional `require_role(required_role)` — for endpoints gated to a
11
11
  * specific role.
12
12
  *
13
- * Then delegates to {@link register_action_ws} for per-message JSON-RPC
13
+ * Then delegates to `register_action_ws` for per-message JSON-RPC
14
14
  * dispatch.
15
15
  *
16
16
  * @module
@@ -23,8 +23,8 @@ import { register_action_ws, } from './register_action_ws.js';
23
23
  * Mount a WebSocket endpoint with the standard upgrade stack (origin check
24
24
  * + auth + optional role) and JSON-RPC dispatch.
25
25
  *
26
- * Returns the {@link BackendWebsocketTransport} (supplied or freshly
27
- * created), same as {@link register_action_ws} — retain it to wire
26
+ * Returns the `BackendWebsocketTransport` (supplied or freshly
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
29
  */
30
30
  export const register_ws_endpoint = (options) => {
@@ -13,12 +13,12 @@
13
13
  * message path so request/response correlation is transport-level rather
14
14
  * than re-invented per consumer.
15
15
  * - **Durable queue** — `request()` calls made while disconnected buffer up
16
- * to {@link DEFAULT_QUEUE_MAX_SIZE} requests and flush on reopen. Overflow
16
+ * to `DEFAULT_QUEUE_MAX_SIZE` requests and flush on reopen. Overflow
17
17
  * rejects with `queue_overflow`. Raw {@link FrontendWebsocketClient.send}
18
18
  * is drop-on-disconnect (fire-and-forget notifications want that).
19
19
  * - **Activity-aware heartbeat** — idles fire a shared `heartbeat` request;
20
- * receive-silence past {@link DEFAULT_HEARTBEAT_RECEIVE_TIMEOUT} closes
21
- * with {@link WS_CLOSE_CLIENT_HEARTBEAT_TIMEOUT} and lets auto-reconnect
20
+ * receive-silence past `DEFAULT_HEARTBEAT_RECEIVE_TIMEOUT` closes
21
+ * with `WS_CLOSE_CLIENT_HEARTBEAT_TIMEOUT` and lets auto-reconnect
22
22
  * pick back up.
23
23
  *
24
24
  * @module
@@ -37,7 +37,7 @@ export declare const DEFAULT_RECONNECT_DELAY_MAX = 10000;
37
37
  export declare const DEFAULT_BACKOFF_FACTOR = 1.5;
38
38
  /** Idle interval before sending a heartbeat (ms). */
39
39
  export declare const DEFAULT_HEARTBEAT_INTERVAL = 30000;
40
- /** Max receive silence before closing with {@link WS_CLOSE_CLIENT_HEARTBEAT_TIMEOUT} (ms). */
40
+ /** Max receive silence before closing with `WS_CLOSE_CLIENT_HEARTBEAT_TIMEOUT` (ms). */
41
41
  export declare const DEFAULT_HEARTBEAT_RECEIVE_TIMEOUT = 60000;
42
42
  /** Default bound on buffered requests while disconnected. Overflow rejects. */
43
43
  export declare const DEFAULT_QUEUE_MAX_SIZE = 100;
@@ -66,14 +66,14 @@ export interface FrontendWebsocketHeartbeatOptions {
66
66
  /**
67
67
  * Idle duration (ms) after which a heartbeat is sent. Reset by any send or
68
68
  * receive — chatty clients never emit extras. Defaults to
69
- * {@link DEFAULT_HEARTBEAT_INTERVAL}.
69
+ * `DEFAULT_HEARTBEAT_INTERVAL`.
70
70
  */
71
71
  interval?: number;
72
72
  /**
73
73
  * Receive-silence (ms) after which the client closes the socket with
74
- * {@link WS_CLOSE_CLIENT_HEARTBEAT_TIMEOUT}, letting auto-reconnect kick
75
- * in. Should be a comfortable multiple of {@link interval}. Defaults to
76
- * {@link DEFAULT_HEARTBEAT_RECEIVE_TIMEOUT}.
74
+ * `WS_CLOSE_CLIENT_HEARTBEAT_TIMEOUT`, letting auto-reconnect kick
75
+ * in. Should be a comfortable multiple of `interval`. Defaults to
76
+ * `DEFAULT_HEARTBEAT_RECEIVE_TIMEOUT`.
77
77
  */
78
78
  receive_timeout?: number;
79
79
  }
@@ -81,7 +81,7 @@ export interface FrontendWebsocketQueueOptions {
81
81
  /**
82
82
  * Maximum number of requests held while the socket is disconnected.
83
83
  * Enqueue past this rejects the new call with a `queue_overflow` error.
84
- * Defaults to {@link DEFAULT_QUEUE_MAX_SIZE}.
84
+ * Defaults to `DEFAULT_QUEUE_MAX_SIZE`.
85
85
  */
86
86
  max_size?: number;
87
87
  }
@@ -138,7 +138,7 @@ export declare class FrontendWebsocketClient implements WebsocketConnection, Dis
138
138
  * when the underlying `ws.send` throws (e.g., buffer full, serialization
139
139
  * error); reset to `null` on the next successful send. Not touched when
140
140
  * `send()` short-circuits because the socket is not connected — consult
141
- * {@link connected} for that case. Wrappers surfacing per-message failure
141
+ * `connected` for that case. Wrappers surfacing per-message failure
142
142
  * reasons can read this after a `false` return from `send()`.
143
143
  */
144
144
  last_send_error: Error | null;
@@ -170,7 +170,7 @@ export declare class FrontendWebsocketClient implements WebsocketConnection, Dis
170
170
  * `null`/omitted restores the defaults, or a config object customizes
171
171
  * specific fields (missing fields fall back to defaults, not "keep
172
172
  * current" — each call defines the whole policy atomically, same as the
173
- * constructor and {@link set_reconnect}).
173
+ * constructor and `set_reconnect`).
174
174
  *
175
175
  * When connected, the live timer is restarted immediately so the new
176
176
  * `interval` / `receive_timeout` take effect without a reconnect; when
@@ -185,10 +185,10 @@ export declare class FrontendWebsocketClient implements WebsocketConnection, Dis
185
185
  * pending.
186
186
  *
187
187
  * Use this when UI state asks "stop trying for now" without the finality
188
- * of {@link disconnect} (which also rejects pending/queued requests and
188
+ * of `disconnect` (which also rejects pending/queued requests and
189
189
  * clears heartbeat) or the policy change of `set_reconnect(false)`
190
190
  * (which disables future reconnects). The queue stays intact so that
191
- * calling {@link connect} later flushes buffered work.
191
+ * calling `connect` later flushes buffered work.
192
192
  */
193
193
  cancel_reconnect(): void;
194
194
  get url(): string;
@@ -233,7 +233,7 @@ export declare class FrontendWebsocketClient implements WebsocketConnection, Dis
233
233
  * disconnect-detection slot.
234
234
  *
235
235
  * On `AbortSignal` fire: rejects the local promise *and* sends the shared
236
- * `cancel` notification ({@link CANCEL_METHOD}) so the server-side
236
+ * `cancel` notification (`cancel_action_spec.method`) so the server-side
237
237
  * dispatcher can abort the matching handler's `ctx.signal`. Suppressed
238
238
  * for queued-but-never-sent (server doesn't know about it) and
239
239
  * response-beat-cancel races.
@@ -259,14 +259,14 @@ export declare class FrontendWebsocketClient implements WebsocketConnection, Dis
259
259
  add_error_handler(handler: SocketErrorHandler): () => void;
260
260
  }
261
261
  /**
262
- * Project {@link SocketStatus} onto fuz_util's {@link AsyncStatus} — the
262
+ * Project `SocketStatus` onto fuz_util's `AsyncStatus` — the
263
263
  * 5-way → 4-way mapping every consumer re-derives to surface connection state
264
264
  * to UI (loading indicators, retry banners). Collapses `reconnecting` into
265
265
  * `failure` (UI shows "lost, retrying") and splits `closed` by `revoked` so
266
266
  * a terminal session-revocation read as `failure` while a clean client-
267
267
  * initiated close reads as `initial` (the "not connected, not trying" state).
268
268
  *
269
- * @param status - the socket's current {@link SocketStatus}
269
+ * @param status - the socket's current `SocketStatus`
270
270
  * @param revoked - whether the session has been permanently revoked
271
271
  * (typically `FrontendWebsocketClient.revoked`)
272
272
  */
@@ -1 +1 @@
1
- {"version":3,"file":"socket.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/socket.svelte.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"socket.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/actions/socket.svelte.ts"],"names":[],"mappings":"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"}