@fuzdev/fuz_app 0.1.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 (457) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -0
  3. package/dist/actions/action_bridge.d.ts +65 -0
  4. package/dist/actions/action_bridge.d.ts.map +1 -0
  5. package/dist/actions/action_bridge.js +76 -0
  6. package/dist/actions/action_codegen.d.ts +97 -0
  7. package/dist/actions/action_codegen.d.ts.map +1 -0
  8. package/dist/actions/action_codegen.js +280 -0
  9. package/dist/actions/action_registry.d.ts +35 -0
  10. package/dist/actions/action_registry.d.ts.map +1 -0
  11. package/dist/actions/action_registry.js +83 -0
  12. package/dist/actions/action_spec.d.ts +169 -0
  13. package/dist/actions/action_spec.d.ts.map +1 -0
  14. package/dist/actions/action_spec.js +76 -0
  15. package/dist/auth/account_queries.d.ts +96 -0
  16. package/dist/auth/account_queries.d.ts.map +1 -0
  17. package/dist/auth/account_queries.js +172 -0
  18. package/dist/auth/account_routes.d.ts +86 -0
  19. package/dist/auth/account_routes.d.ts.map +1 -0
  20. package/dist/auth/account_routes.js +406 -0
  21. package/dist/auth/account_schema.d.ts +192 -0
  22. package/dist/auth/account_schema.d.ts.map +1 -0
  23. package/dist/auth/account_schema.js +105 -0
  24. package/dist/auth/admin_routes.d.ts +29 -0
  25. package/dist/auth/admin_routes.d.ts.map +1 -0
  26. package/dist/auth/admin_routes.js +193 -0
  27. package/dist/auth/api_token.d.ts +33 -0
  28. package/dist/auth/api_token.d.ts.map +1 -0
  29. package/dist/auth/api_token.js +36 -0
  30. package/dist/auth/api_token_queries.d.ts +80 -0
  31. package/dist/auth/api_token_queries.d.ts.map +1 -0
  32. package/dist/auth/api_token_queries.js +116 -0
  33. package/dist/auth/app_settings_queries.d.ts +33 -0
  34. package/dist/auth/app_settings_queries.d.ts.map +1 -0
  35. package/dist/auth/app_settings_queries.js +51 -0
  36. package/dist/auth/app_settings_routes.d.ts +27 -0
  37. package/dist/auth/app_settings_routes.d.ts.map +1 -0
  38. package/dist/auth/app_settings_routes.js +66 -0
  39. package/dist/auth/app_settings_schema.d.ts +35 -0
  40. package/dist/auth/app_settings_schema.d.ts.map +1 -0
  41. package/dist/auth/app_settings_schema.js +22 -0
  42. package/dist/auth/audit_log_queries.d.ts +90 -0
  43. package/dist/auth/audit_log_queries.d.ts.map +1 -0
  44. package/dist/auth/audit_log_queries.js +205 -0
  45. package/dist/auth/audit_log_routes.d.ts +33 -0
  46. package/dist/auth/audit_log_routes.d.ts.map +1 -0
  47. package/dist/auth/audit_log_routes.js +106 -0
  48. package/dist/auth/audit_log_schema.d.ts +259 -0
  49. package/dist/auth/audit_log_schema.d.ts.map +1 -0
  50. package/dist/auth/audit_log_schema.js +123 -0
  51. package/dist/auth/bearer_auth.d.ts +32 -0
  52. package/dist/auth/bearer_auth.d.ts.map +1 -0
  53. package/dist/auth/bearer_auth.js +90 -0
  54. package/dist/auth/bootstrap_account.d.ts +82 -0
  55. package/dist/auth/bootstrap_account.d.ts.map +1 -0
  56. package/dist/auth/bootstrap_account.js +97 -0
  57. package/dist/auth/bootstrap_routes.d.ts +74 -0
  58. package/dist/auth/bootstrap_routes.d.ts.map +1 -0
  59. package/dist/auth/bootstrap_routes.js +154 -0
  60. package/dist/auth/daemon_token.d.ts +49 -0
  61. package/dist/auth/daemon_token.d.ts.map +1 -0
  62. package/dist/auth/daemon_token.js +49 -0
  63. package/dist/auth/daemon_token_middleware.d.ts +93 -0
  64. package/dist/auth/daemon_token_middleware.d.ts.map +1 -0
  65. package/dist/auth/daemon_token_middleware.js +167 -0
  66. package/dist/auth/ddl.d.ts +27 -0
  67. package/dist/auth/ddl.d.ts.map +1 -0
  68. package/dist/auth/ddl.js +111 -0
  69. package/dist/auth/deps.d.ts +52 -0
  70. package/dist/auth/deps.d.ts.map +1 -0
  71. package/dist/auth/deps.js +10 -0
  72. package/dist/auth/invite_queries.d.ts +68 -0
  73. package/dist/auth/invite_queries.d.ts.map +1 -0
  74. package/dist/auth/invite_queries.js +105 -0
  75. package/dist/auth/invite_routes.d.ts +18 -0
  76. package/dist/auth/invite_routes.d.ts.map +1 -0
  77. package/dist/auth/invite_routes.js +129 -0
  78. package/dist/auth/invite_schema.d.ts +51 -0
  79. package/dist/auth/invite_schema.d.ts.map +1 -0
  80. package/dist/auth/invite_schema.js +25 -0
  81. package/dist/auth/keyring.d.ts +87 -0
  82. package/dist/auth/keyring.d.ts.map +1 -0
  83. package/dist/auth/keyring.js +142 -0
  84. package/dist/auth/middleware.d.ts +40 -0
  85. package/dist/auth/middleware.d.ts.map +1 -0
  86. package/dist/auth/middleware.js +64 -0
  87. package/dist/auth/migrations.d.ts +42 -0
  88. package/dist/auth/migrations.d.ts.map +1 -0
  89. package/dist/auth/migrations.js +79 -0
  90. package/dist/auth/password.d.ts +39 -0
  91. package/dist/auth/password.d.ts.map +1 -0
  92. package/dist/auth/password.js +25 -0
  93. package/dist/auth/password_argon2.d.ts +43 -0
  94. package/dist/auth/password_argon2.d.ts.map +1 -0
  95. package/dist/auth/password_argon2.js +76 -0
  96. package/dist/auth/permit_queries.d.ts +72 -0
  97. package/dist/auth/permit_queries.d.ts.map +1 -0
  98. package/dist/auth/permit_queries.js +116 -0
  99. package/dist/auth/request_context.d.ts +114 -0
  100. package/dist/auth/request_context.d.ts.map +1 -0
  101. package/dist/auth/request_context.js +176 -0
  102. package/dist/auth/require_keeper.d.ts +20 -0
  103. package/dist/auth/require_keeper.d.ts.map +1 -0
  104. package/dist/auth/require_keeper.js +35 -0
  105. package/dist/auth/role_schema.d.ts +69 -0
  106. package/dist/auth/role_schema.d.ts.map +1 -0
  107. package/dist/auth/role_schema.js +70 -0
  108. package/dist/auth/route_guards.d.ts +21 -0
  109. package/dist/auth/route_guards.d.ts.map +1 -0
  110. package/dist/auth/route_guards.js +32 -0
  111. package/dist/auth/session_cookie.d.ts +158 -0
  112. package/dist/auth/session_cookie.d.ts.map +1 -0
  113. package/dist/auth/session_cookie.js +135 -0
  114. package/dist/auth/session_lifecycle.d.ts +35 -0
  115. package/dist/auth/session_lifecycle.d.ts.map +1 -0
  116. package/dist/auth/session_lifecycle.js +27 -0
  117. package/dist/auth/session_middleware.d.ts +33 -0
  118. package/dist/auth/session_middleware.d.ts.map +1 -0
  119. package/dist/auth/session_middleware.js +62 -0
  120. package/dist/auth/session_queries.d.ts +135 -0
  121. package/dist/auth/session_queries.d.ts.map +1 -0
  122. package/dist/auth/session_queries.js +186 -0
  123. package/dist/auth/signup_routes.d.ts +32 -0
  124. package/dist/auth/signup_routes.d.ts.map +1 -0
  125. package/dist/auth/signup_routes.js +150 -0
  126. package/dist/cli/args.d.ts +48 -0
  127. package/dist/cli/args.d.ts.map +1 -0
  128. package/dist/cli/args.js +76 -0
  129. package/dist/cli/config.d.ts +48 -0
  130. package/dist/cli/config.d.ts.map +1 -0
  131. package/dist/cli/config.js +77 -0
  132. package/dist/cli/daemon.d.ts +82 -0
  133. package/dist/cli/daemon.d.ts.map +1 -0
  134. package/dist/cli/daemon.js +149 -0
  135. package/dist/cli/help.d.ts +85 -0
  136. package/dist/cli/help.d.ts.map +1 -0
  137. package/dist/cli/help.js +138 -0
  138. package/dist/cli/logger.d.ts +46 -0
  139. package/dist/cli/logger.d.ts.map +1 -0
  140. package/dist/cli/logger.js +48 -0
  141. package/dist/cli/util.d.ts +36 -0
  142. package/dist/cli/util.d.ts.map +1 -0
  143. package/dist/cli/util.js +50 -0
  144. package/dist/crypto.d.ts +13 -0
  145. package/dist/crypto.d.ts.map +1 -0
  146. package/dist/crypto.js +19 -0
  147. package/dist/db/assert_row.d.ts +18 -0
  148. package/dist/db/assert_row.d.ts.map +1 -0
  149. package/dist/db/assert_row.js +24 -0
  150. package/dist/db/create_db.d.ts +38 -0
  151. package/dist/db/create_db.d.ts.map +1 -0
  152. package/dist/db/create_db.js +57 -0
  153. package/dist/db/db.d.ts +97 -0
  154. package/dist/db/db.d.ts.map +1 -0
  155. package/dist/db/db.js +76 -0
  156. package/dist/db/db_pg.d.ts +21 -0
  157. package/dist/db/db_pg.d.ts.map +1 -0
  158. package/dist/db/db_pg.js +45 -0
  159. package/dist/db/db_pglite.d.ts +21 -0
  160. package/dist/db/db_pglite.d.ts.map +1 -0
  161. package/dist/db/db_pglite.js +28 -0
  162. package/dist/db/migrate.d.ts +67 -0
  163. package/dist/db/migrate.d.ts.map +1 -0
  164. package/dist/db/migrate.js +118 -0
  165. package/dist/db/pg_error.d.ts +16 -0
  166. package/dist/db/pg_error.d.ts.map +1 -0
  167. package/dist/db/pg_error.js +15 -0
  168. package/dist/db/query_deps.d.ts +14 -0
  169. package/dist/db/query_deps.d.ts.map +1 -0
  170. package/dist/db/query_deps.js +9 -0
  171. package/dist/db/sql_identifier.d.ts +27 -0
  172. package/dist/db/sql_identifier.d.ts.map +1 -0
  173. package/dist/db/sql_identifier.js +31 -0
  174. package/dist/db/status.d.ts +62 -0
  175. package/dist/db/status.d.ts.map +1 -0
  176. package/dist/db/status.js +116 -0
  177. package/dist/dev/setup.d.ts +159 -0
  178. package/dist/dev/setup.d.ts.map +1 -0
  179. package/dist/dev/setup.js +265 -0
  180. package/dist/env/dotenv.d.ts +25 -0
  181. package/dist/env/dotenv.d.ts.map +1 -0
  182. package/dist/env/dotenv.js +52 -0
  183. package/dist/env/load.d.ts +52 -0
  184. package/dist/env/load.d.ts.map +1 -0
  185. package/dist/env/load.js +79 -0
  186. package/dist/env/mask.d.ts +19 -0
  187. package/dist/env/mask.d.ts.map +1 -0
  188. package/dist/env/mask.js +26 -0
  189. package/dist/env/resolve.d.ts +126 -0
  190. package/dist/env/resolve.d.ts.map +1 -0
  191. package/dist/env/resolve.js +200 -0
  192. package/dist/hono_context.d.ts +48 -0
  193. package/dist/hono_context.d.ts.map +1 -0
  194. package/dist/hono_context.js +22 -0
  195. package/dist/http/common_routes.d.ts +52 -0
  196. package/dist/http/common_routes.d.ts.map +1 -0
  197. package/dist/http/common_routes.js +65 -0
  198. package/dist/http/db_routes.d.ts +57 -0
  199. package/dist/http/db_routes.d.ts.map +1 -0
  200. package/dist/http/db_routes.js +176 -0
  201. package/dist/http/error_schemas.d.ts +169 -0
  202. package/dist/http/error_schemas.d.ts.map +1 -0
  203. package/dist/http/error_schemas.js +178 -0
  204. package/dist/http/middleware_spec.d.ts +19 -0
  205. package/dist/http/middleware_spec.d.ts.map +1 -0
  206. package/dist/http/middleware_spec.js +9 -0
  207. package/dist/http/origin.d.ts +57 -0
  208. package/dist/http/origin.d.ts.map +1 -0
  209. package/dist/http/origin.js +207 -0
  210. package/dist/http/proxy.d.ts +112 -0
  211. package/dist/http/proxy.d.ts.map +1 -0
  212. package/dist/http/proxy.js +240 -0
  213. package/dist/http/route_spec.d.ts +197 -0
  214. package/dist/http/route_spec.d.ts.map +1 -0
  215. package/dist/http/route_spec.js +243 -0
  216. package/dist/http/schema_helpers.d.ts +64 -0
  217. package/dist/http/schema_helpers.d.ts.map +1 -0
  218. package/dist/http/schema_helpers.js +90 -0
  219. package/dist/http/surface.d.ts +132 -0
  220. package/dist/http/surface.d.ts.map +1 -0
  221. package/dist/http/surface.js +156 -0
  222. package/dist/http/surface_query.d.ts +77 -0
  223. package/dist/http/surface_query.d.ts.map +1 -0
  224. package/dist/http/surface_query.js +86 -0
  225. package/dist/rate_limiter.d.ts +94 -0
  226. package/dist/rate_limiter.d.ts.map +1 -0
  227. package/dist/rate_limiter.js +156 -0
  228. package/dist/realtime/sse.d.ts +80 -0
  229. package/dist/realtime/sse.d.ts.map +1 -0
  230. package/dist/realtime/sse.js +109 -0
  231. package/dist/realtime/sse_auth_guard.d.ts +93 -0
  232. package/dist/realtime/sse_auth_guard.d.ts.map +1 -0
  233. package/dist/realtime/sse_auth_guard.js +111 -0
  234. package/dist/realtime/subscriber_registry.d.ts +85 -0
  235. package/dist/realtime/subscriber_registry.d.ts.map +1 -0
  236. package/dist/realtime/subscriber_registry.js +108 -0
  237. package/dist/runtime/deno.d.ts +21 -0
  238. package/dist/runtime/deno.d.ts.map +1 -0
  239. package/dist/runtime/deno.js +83 -0
  240. package/dist/runtime/deps.d.ts +113 -0
  241. package/dist/runtime/deps.d.ts.map +1 -0
  242. package/dist/runtime/deps.js +10 -0
  243. package/dist/runtime/fs.d.ts +15 -0
  244. package/dist/runtime/fs.d.ts.map +1 -0
  245. package/dist/runtime/fs.js +17 -0
  246. package/dist/runtime/mock.d.ts +81 -0
  247. package/dist/runtime/mock.d.ts.map +1 -0
  248. package/dist/runtime/mock.js +195 -0
  249. package/dist/runtime/node.d.ts +17 -0
  250. package/dist/runtime/node.d.ts.map +1 -0
  251. package/dist/runtime/node.js +117 -0
  252. package/dist/schema_meta.d.ts +16 -0
  253. package/dist/schema_meta.d.ts.map +1 -0
  254. package/dist/schema_meta.js +9 -0
  255. package/dist/sensitivity.d.ts +15 -0
  256. package/dist/sensitivity.d.ts.map +1 -0
  257. package/dist/sensitivity.js +9 -0
  258. package/dist/server/app_backend.d.ts +74 -0
  259. package/dist/server/app_backend.d.ts.map +1 -0
  260. package/dist/server/app_backend.js +39 -0
  261. package/dist/server/app_server.d.ts +201 -0
  262. package/dist/server/app_server.d.ts.map +1 -0
  263. package/dist/server/app_server.js +266 -0
  264. package/dist/server/env.d.ts +68 -0
  265. package/dist/server/env.d.ts.map +1 -0
  266. package/dist/server/env.js +95 -0
  267. package/dist/server/startup.d.ts +22 -0
  268. package/dist/server/startup.d.ts.map +1 -0
  269. package/dist/server/startup.js +48 -0
  270. package/dist/server/static.d.ts +39 -0
  271. package/dist/server/static.d.ts.map +1 -0
  272. package/dist/server/static.js +38 -0
  273. package/dist/server/validate_nginx.d.ts +34 -0
  274. package/dist/server/validate_nginx.d.ts.map +1 -0
  275. package/dist/server/validate_nginx.js +118 -0
  276. package/dist/testing/CLAUDE.md +3 -0
  277. package/dist/testing/admin_integration.d.ts +45 -0
  278. package/dist/testing/admin_integration.d.ts.map +1 -0
  279. package/dist/testing/admin_integration.js +840 -0
  280. package/dist/testing/adversarial_404.d.ts +15 -0
  281. package/dist/testing/adversarial_404.d.ts.map +1 -0
  282. package/dist/testing/adversarial_404.js +118 -0
  283. package/dist/testing/adversarial_headers.d.ts +36 -0
  284. package/dist/testing/adversarial_headers.d.ts.map +1 -0
  285. package/dist/testing/adversarial_headers.js +128 -0
  286. package/dist/testing/adversarial_input.d.ts +56 -0
  287. package/dist/testing/adversarial_input.d.ts.map +1 -0
  288. package/dist/testing/adversarial_input.js +494 -0
  289. package/dist/testing/app_server.d.ts +169 -0
  290. package/dist/testing/app_server.d.ts.map +1 -0
  291. package/dist/testing/app_server.js +240 -0
  292. package/dist/testing/assert_dev_env.d.ts +10 -0
  293. package/dist/testing/assert_dev_env.d.ts.map +1 -0
  294. package/dist/testing/assert_dev_env.js +13 -0
  295. package/dist/testing/assertions.d.ts +61 -0
  296. package/dist/testing/assertions.d.ts.map +1 -0
  297. package/dist/testing/assertions.js +96 -0
  298. package/dist/testing/attack_surface.d.ts +63 -0
  299. package/dist/testing/attack_surface.d.ts.map +1 -0
  300. package/dist/testing/attack_surface.js +224 -0
  301. package/dist/testing/audit_completeness.d.ts +29 -0
  302. package/dist/testing/audit_completeness.d.ts.map +1 -0
  303. package/dist/testing/audit_completeness.js +410 -0
  304. package/dist/testing/auth_apps.d.ts +55 -0
  305. package/dist/testing/auth_apps.d.ts.map +1 -0
  306. package/dist/testing/auth_apps.js +122 -0
  307. package/dist/testing/data_exposure.d.ts +62 -0
  308. package/dist/testing/data_exposure.d.ts.map +1 -0
  309. package/dist/testing/data_exposure.js +297 -0
  310. package/dist/testing/db.d.ts +111 -0
  311. package/dist/testing/db.d.ts.map +1 -0
  312. package/dist/testing/db.js +258 -0
  313. package/dist/testing/entities.d.ts +21 -0
  314. package/dist/testing/entities.d.ts.map +1 -0
  315. package/dist/testing/entities.js +42 -0
  316. package/dist/testing/error_coverage.d.ts +78 -0
  317. package/dist/testing/error_coverage.d.ts.map +1 -0
  318. package/dist/testing/error_coverage.js +135 -0
  319. package/dist/testing/integration.d.ts +37 -0
  320. package/dist/testing/integration.d.ts.map +1 -0
  321. package/dist/testing/integration.js +1139 -0
  322. package/dist/testing/integration_helpers.d.ts +107 -0
  323. package/dist/testing/integration_helpers.d.ts.map +1 -0
  324. package/dist/testing/integration_helpers.js +246 -0
  325. package/dist/testing/middleware.d.ts +125 -0
  326. package/dist/testing/middleware.d.ts.map +1 -0
  327. package/dist/testing/middleware.js +210 -0
  328. package/dist/testing/rate_limiting.d.ts +43 -0
  329. package/dist/testing/rate_limiting.d.ts.map +1 -0
  330. package/dist/testing/rate_limiting.js +216 -0
  331. package/dist/testing/round_trip.d.ts +37 -0
  332. package/dist/testing/round_trip.d.ts.map +1 -0
  333. package/dist/testing/round_trip.js +128 -0
  334. package/dist/testing/schema_generators.d.ts +33 -0
  335. package/dist/testing/schema_generators.d.ts.map +1 -0
  336. package/dist/testing/schema_generators.js +137 -0
  337. package/dist/testing/standard.d.ts +49 -0
  338. package/dist/testing/standard.d.ts.map +1 -0
  339. package/dist/testing/standard.js +16 -0
  340. package/dist/testing/stubs.d.ts +96 -0
  341. package/dist/testing/stubs.d.ts.map +1 -0
  342. package/dist/testing/stubs.js +192 -0
  343. package/dist/testing/surface_invariants.d.ts +189 -0
  344. package/dist/testing/surface_invariants.d.ts.map +1 -0
  345. package/dist/testing/surface_invariants.js +450 -0
  346. package/dist/ui/AccountSessions.svelte +75 -0
  347. package/dist/ui/AccountSessions.svelte.d.ts +19 -0
  348. package/dist/ui/AccountSessions.svelte.d.ts.map +1 -0
  349. package/dist/ui/AdminAccounts.svelte +107 -0
  350. package/dist/ui/AdminAccounts.svelte.d.ts +19 -0
  351. package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -0
  352. package/dist/ui/AdminAuditLog.svelte +144 -0
  353. package/dist/ui/AdminAuditLog.svelte.d.ts +4 -0
  354. package/dist/ui/AdminAuditLog.svelte.d.ts.map +1 -0
  355. package/dist/ui/AdminInvites.svelte +142 -0
  356. package/dist/ui/AdminInvites.svelte.d.ts +4 -0
  357. package/dist/ui/AdminInvites.svelte.d.ts.map +1 -0
  358. package/dist/ui/AdminOverview.svelte +337 -0
  359. package/dist/ui/AdminOverview.svelte.d.ts +4 -0
  360. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -0
  361. package/dist/ui/AdminPermitHistory.svelte +61 -0
  362. package/dist/ui/AdminPermitHistory.svelte.d.ts +19 -0
  363. package/dist/ui/AdminPermitHistory.svelte.d.ts.map +1 -0
  364. package/dist/ui/AdminSessions.svelte +85 -0
  365. package/dist/ui/AdminSessions.svelte.d.ts +19 -0
  366. package/dist/ui/AdminSessions.svelte.d.ts.map +1 -0
  367. package/dist/ui/AdminSettings.svelte +32 -0
  368. package/dist/ui/AdminSettings.svelte.d.ts +19 -0
  369. package/dist/ui/AdminSettings.svelte.d.ts.map +1 -0
  370. package/dist/ui/AdminSurface.svelte +42 -0
  371. package/dist/ui/AdminSurface.svelte.d.ts +4 -0
  372. package/dist/ui/AdminSurface.svelte.d.ts.map +1 -0
  373. package/dist/ui/AppShell.svelte +93 -0
  374. package/dist/ui/AppShell.svelte.d.ts +20 -0
  375. package/dist/ui/AppShell.svelte.d.ts.map +1 -0
  376. package/dist/ui/BootstrapForm.svelte +105 -0
  377. package/dist/ui/BootstrapForm.svelte.d.ts +4 -0
  378. package/dist/ui/BootstrapForm.svelte.d.ts.map +1 -0
  379. package/dist/ui/ColumnLayout.svelte +46 -0
  380. package/dist/ui/ColumnLayout.svelte.d.ts +11 -0
  381. package/dist/ui/ColumnLayout.svelte.d.ts.map +1 -0
  382. package/dist/ui/ConfirmButton.svelte +125 -0
  383. package/dist/ui/ConfirmButton.svelte.d.ts +54 -0
  384. package/dist/ui/ConfirmButton.svelte.d.ts.map +1 -0
  385. package/dist/ui/Datatable.svelte +185 -0
  386. package/dist/ui/Datatable.svelte.d.ts +35 -0
  387. package/dist/ui/Datatable.svelte.d.ts.map +1 -0
  388. package/dist/ui/LoginForm.svelte +82 -0
  389. package/dist/ui/LoginForm.svelte.d.ts +8 -0
  390. package/dist/ui/LoginForm.svelte.d.ts.map +1 -0
  391. package/dist/ui/LogoutButton.svelte +36 -0
  392. package/dist/ui/LogoutButton.svelte.d.ts +10 -0
  393. package/dist/ui/LogoutButton.svelte.d.ts.map +1 -0
  394. package/dist/ui/MenuLink.svelte +35 -0
  395. package/dist/ui/MenuLink.svelte.d.ts +12 -0
  396. package/dist/ui/MenuLink.svelte.d.ts.map +1 -0
  397. package/dist/ui/OpenSignupToggle.svelte +36 -0
  398. package/dist/ui/OpenSignupToggle.svelte.d.ts +19 -0
  399. package/dist/ui/OpenSignupToggle.svelte.d.ts.map +1 -0
  400. package/dist/ui/PopoverButton.svelte +136 -0
  401. package/dist/ui/PopoverButton.svelte.d.ts +63 -0
  402. package/dist/ui/PopoverButton.svelte.d.ts.map +1 -0
  403. package/dist/ui/SignupForm.svelte +117 -0
  404. package/dist/ui/SignupForm.svelte.d.ts +7 -0
  405. package/dist/ui/SignupForm.svelte.d.ts.map +1 -0
  406. package/dist/ui/SurfaceExplorer.svelte +287 -0
  407. package/dist/ui/SurfaceExplorer.svelte.d.ts +8 -0
  408. package/dist/ui/SurfaceExplorer.svelte.d.ts.map +1 -0
  409. package/dist/ui/account_sessions_state.svelte.d.ts +15 -0
  410. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -0
  411. package/dist/ui/account_sessions_state.svelte.js +45 -0
  412. package/dist/ui/admin_accounts_state.svelte.d.ts +19 -0
  413. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -0
  414. package/dist/ui/admin_accounts_state.svelte.js +65 -0
  415. package/dist/ui/admin_invites_state.svelte.d.ts +19 -0
  416. package/dist/ui/admin_invites_state.svelte.d.ts.map +1 -0
  417. package/dist/ui/admin_invites_state.svelte.js +71 -0
  418. package/dist/ui/admin_sessions_state.svelte.d.ts +18 -0
  419. package/dist/ui/admin_sessions_state.svelte.d.ts.map +1 -0
  420. package/dist/ui/admin_sessions_state.svelte.js +62 -0
  421. package/dist/ui/app_settings_state.svelte.d.ts +14 -0
  422. package/dist/ui/app_settings_state.svelte.d.ts.map +1 -0
  423. package/dist/ui/app_settings_state.svelte.js +44 -0
  424. package/dist/ui/audit_log_state.svelte.d.ts +40 -0
  425. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -0
  426. package/dist/ui/audit_log_state.svelte.js +153 -0
  427. package/dist/ui/auth_state.svelte.d.ts +85 -0
  428. package/dist/ui/auth_state.svelte.d.ts.map +1 -0
  429. package/dist/ui/auth_state.svelte.js +238 -0
  430. package/dist/ui/datatable.d.ts +25 -0
  431. package/dist/ui/datatable.d.ts.map +1 -0
  432. package/dist/ui/datatable.js +9 -0
  433. package/dist/ui/enter_advance.d.ts +13 -0
  434. package/dist/ui/enter_advance.d.ts.map +1 -0
  435. package/dist/ui/enter_advance.js +30 -0
  436. package/dist/ui/loadable.svelte.d.ts +55 -0
  437. package/dist/ui/loadable.svelte.d.ts.map +1 -0
  438. package/dist/ui/loadable.svelte.js +75 -0
  439. package/dist/ui/popover.svelte.d.ts +137 -0
  440. package/dist/ui/popover.svelte.d.ts.map +1 -0
  441. package/dist/ui/popover.svelte.js +288 -0
  442. package/dist/ui/position_helpers.d.ts +27 -0
  443. package/dist/ui/position_helpers.d.ts.map +1 -0
  444. package/dist/ui/position_helpers.js +81 -0
  445. package/dist/ui/sidebar_state.svelte.d.ts +30 -0
  446. package/dist/ui/sidebar_state.svelte.d.ts.map +1 -0
  447. package/dist/ui/sidebar_state.svelte.js +39 -0
  448. package/dist/ui/table_state.svelte.d.ts +63 -0
  449. package/dist/ui/table_state.svelte.d.ts.map +1 -0
  450. package/dist/ui/table_state.svelte.js +117 -0
  451. package/dist/ui/ui_fetch.d.ts +29 -0
  452. package/dist/ui/ui_fetch.d.ts.map +1 -0
  453. package/dist/ui/ui_fetch.js +37 -0
  454. package/dist/ui/ui_format.d.ts +63 -0
  455. package/dist/ui/ui_format.d.ts.map +1 -0
  456. package/dist/ui/ui_format.js +196 -0
  457. package/package.json +121 -0
@@ -0,0 +1,109 @@
1
+ /**
2
+ * SSE (Server-Sent Events) streaming utilities for Hono.
3
+ *
4
+ * Provides generic helpers for creating SSE response streams
5
+ * and a notification type aligned with JSON-RPC 2.0.
6
+ *
7
+ * @module
8
+ */
9
+ import { streamSSE } from 'hono/streaming';
10
+ import { z } from 'zod';
11
+ import { DEV } from 'esm-env';
12
+ /**
13
+ * Create an SSE response for a Hono context.
14
+ *
15
+ * Wraps Hono's `streamSSE` to provide a `{response, stream}` API
16
+ * compatible with `SubscriberRegistry` push-based broadcasting.
17
+ * The callback suspends via a promise that resolves on client disconnect
18
+ * or explicit `close()`, keeping the stream alive for external sends.
19
+ *
20
+ * Uses `hono_stream.write()` directly (not `writeSSE`) to avoid
21
+ * Hono's HTML callback resolution — keeps the same `data: JSON\n\n` format.
22
+ *
23
+ * @param c - Hono context
24
+ * @returns object with response and stream controller
25
+ */
26
+ export const create_sse_response = (c, log) => {
27
+ const { promise, resolve } = Promise.withResolvers();
28
+ const close_listeners = [];
29
+ let resolved = false;
30
+ const do_close = () => {
31
+ if (resolved)
32
+ return;
33
+ resolved = true;
34
+ resolve();
35
+ for (const fn of close_listeners) {
36
+ try {
37
+ fn();
38
+ }
39
+ catch (e) {
40
+ log.error('on_close listener threw:', e);
41
+ }
42
+ }
43
+ };
44
+ let sse_stream;
45
+ const response = streamSSE(c, async (hono_stream) => {
46
+ sse_stream = {
47
+ send(data) {
48
+ if (resolved || hono_stream.aborted)
49
+ return;
50
+ try {
51
+ // JSON.stringify (no space arg) never produces literal newlines,
52
+ // so single-line `data:` framing is safe per the SSE spec.
53
+ void hono_stream.write(`data: ${JSON.stringify(data)}\n\n`);
54
+ }
55
+ catch (e) {
56
+ log.error('send failed to serialize data:', e);
57
+ }
58
+ },
59
+ comment(text) {
60
+ if (resolved || hono_stream.aborted)
61
+ return;
62
+ void hono_stream.write(`: ${text}\n`);
63
+ },
64
+ close: do_close,
65
+ on_close(fn) {
66
+ close_listeners.push(fn);
67
+ },
68
+ };
69
+ hono_stream.onAbort(do_close);
70
+ // flush an SSE comment to push headers through proxies (Vite, nginx),
71
+ // ensuring EventSource fires onopen without waiting for the first data event
72
+ void hono_stream.write(SSE_CONNECTED_COMMENT);
73
+ await promise;
74
+ });
75
+ return { response, stream: sse_stream };
76
+ };
77
+ /** SSE comment sent on connect to flush headers through proxies. Exported for test assertions. */
78
+ export const SSE_CONNECTED_COMMENT = `: connected\n\n`;
79
+ /**
80
+ * Create a broadcaster that validates events in DEV mode.
81
+ *
82
+ * In DEV: warns on unknown methods and invalid params.
83
+ * In production: passes through with zero overhead.
84
+ *
85
+ * @param broadcaster - duck-typed broadcaster (e.g. `SubscriberRegistry`)
86
+ * @param event_specs - event specs to validate against
87
+ * @returns validated broadcaster wrapper (passthrough in production)
88
+ */
89
+ export const create_validated_broadcaster = (broadcaster, event_specs, log) => {
90
+ if (!DEV) {
91
+ return broadcaster;
92
+ }
93
+ const spec_map = new Map(event_specs.map((s) => [s.method, s]));
94
+ return {
95
+ broadcast: (channel, data) => {
96
+ const spec = spec_map.get(data.method);
97
+ if (!spec) {
98
+ log.warn(`Unknown event method: '${data.method}'`);
99
+ }
100
+ else {
101
+ const result = spec.params.safeParse(data.params);
102
+ if (!result.success) {
103
+ log.warn(`Params mismatch for '${data.method}':`, result.error.issues);
104
+ }
105
+ }
106
+ broadcaster.broadcast(channel, data);
107
+ },
108
+ };
109
+ };
@@ -0,0 +1,93 @@
1
+ /**
2
+ * SSE auth guard and convenience factory for audit log SSE.
3
+ *
4
+ * `create_sse_auth_guard` bridges audit events to `SubscriberRegistry.close_by_identity()`,
5
+ * closing SSE streams when a subscriber's access is revoked (role revocation or
6
+ * session invalidation).
7
+ *
8
+ * `create_audit_log_sse` is a convenience factory that combines the registry,
9
+ * guard, and broadcaster — making the secure path the easy path for consumers.
10
+ *
11
+ * @module
12
+ */
13
+ import type { Logger } from '@fuzdev/fuz_util/log.js';
14
+ import { type AuditLogEvent } from '../auth/audit_log_schema.js';
15
+ import { SubscriberRegistry } from './subscriber_registry.js';
16
+ import type { SseStream, SseNotification, SseEventSpec } from './sse.js';
17
+ /**
18
+ * Audit event types that trigger SSE stream disconnection.
19
+ *
20
+ * `permit_revoke` requires the revoked role to match the guard's `required_role`.
21
+ * `session_revoke_all` and `password_change` close unconditionally for the target account.
22
+ */
23
+ export declare const DISCONNECT_EVENT_TYPES: ReadonlySet<string>;
24
+ /**
25
+ * Create an audit event handler that closes SSE streams on auth changes.
26
+ *
27
+ * Closes streams when:
28
+ * - `permit_revoke` fires for the `required_role` targeting a connected subscriber
29
+ * - `session_revoke_all` targets a connected subscriber (consistent invalidation)
30
+ * - `password_change` targets a connected subscriber (sessions revoked implicitly)
31
+ *
32
+ * The registry must use `account_id` as the identity key when subscribing
33
+ * (passed as the third argument to `registry.subscribe()`).
34
+ *
35
+ * @param registry - the subscriber registry to guard
36
+ * @param required_role - the role that grants access to the SSE endpoint
37
+ * @param log - logger for disconnect events
38
+ * @returns an `on_audit_event` callback
39
+ */
40
+ export declare const create_sse_auth_guard: <T>(registry: SubscriberRegistry<T>, required_role: string, log: Logger) => ((event: AuditLogEvent) => void);
41
+ /**
42
+ * Convenience factory result for audit log SSE.
43
+ *
44
+ * Satisfies `AuditLogRouteOptions['stream']` and provides the combined
45
+ * `on_audit_event` callback (broadcast + guard).
46
+ */
47
+ export interface AuditLogSse {
48
+ /** Subscribe function — pass as part of `stream` option to `create_audit_log_route_specs`. */
49
+ subscribe: (stream: SseStream<SseNotification>, channels?: Array<string>, identity?: string) => () => void;
50
+ /** Logger — pass as part of `stream` option to `create_audit_log_route_specs`. */
51
+ log: Logger;
52
+ /** Combined broadcast + guard callback. Pass as `on_audit_event` on `CreateAppBackendOptions`. */
53
+ on_audit_event: (event: AuditLogEvent) => void;
54
+ /** The underlying registry — exposed for subscriber count monitoring. */
55
+ registry: SubscriberRegistry<SseNotification>;
56
+ }
57
+ /**
58
+ * Create a complete audit log SSE setup with broadcasting and auth guard.
59
+ *
60
+ * Combines `SubscriberRegistry`, `create_sse_auth_guard`, and the broadcast
61
+ * call into a single object. The result satisfies `AuditLogRouteOptions['stream']`
62
+ * and provides the `on_audit_event` callback for `CreateAppBackendOptions`.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * const audit_sse = create_audit_log_sse({log});
67
+ *
68
+ * // In create_app_backend options:
69
+ * on_audit_event: audit_sse.on_audit_event,
70
+ *
71
+ * // In create_route_specs:
72
+ * create_audit_log_route_specs({stream: audit_sse});
73
+ *
74
+ * // In create_app_server options:
75
+ * event_specs: AUDIT_LOG_EVENT_SPECS,
76
+ * ```
77
+ *
78
+ * @param options - factory options
79
+ * @returns audit log SSE setup (stream options + on_audit_event + registry)
80
+ */
81
+ /**
82
+ * SSE event specs for audit log events.
83
+ *
84
+ * One spec per `AUDIT_EVENT_TYPES` entry, all sharing the `AuditLogEventJson` params schema.
85
+ * Pass to `create_app_server`'s `event_specs` for surface generation and DEV validation.
86
+ */
87
+ export declare const AUDIT_LOG_EVENT_SPECS: Array<SseEventSpec>;
88
+ export declare const create_audit_log_sse: (options: {
89
+ /** Role required to access the SSE endpoint. Default `'admin'`. */
90
+ role?: string;
91
+ log: Logger;
92
+ }) => AuditLogSse;
93
+ //# sourceMappingURL=sse_auth_guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse_auth_guard.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/realtime/sse_auth_guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAGN,KAAK,aAAa,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAC,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAC,SAAS,EAAE,eAAe,EAAE,YAAY,EAAC,MAAM,UAAU,CAAC;AAEvE;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,WAAW,CAAC,MAAM,CAIrD,CAAC;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,EACtC,UAAU,kBAAkB,CAAC,CAAC,CAAC,EAC/B,eAAe,MAAM,EACrB,KAAK,MAAM,KACT,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAqBjC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B,8FAA8F;IAC9F,SAAS,EAAE,CACV,MAAM,EAAE,SAAS,CAAC,eAAe,CAAC,EAClC,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,EACxB,QAAQ,CAAC,EAAE,MAAM,KACb,MAAM,IAAI,CAAC;IAChB,kFAAkF;IAClF,GAAG,EAAE,MAAM,CAAC;IACZ,kGAAkG;IAClG,cAAc,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,yEAAyE;IACzE,QAAQ,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;CAC9C;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,YAAY,CAOrD,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAAI,SAAS;IAC7C,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACZ,KAAG,WAcH,CAAC"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * SSE auth guard and convenience factory for audit log SSE.
3
+ *
4
+ * `create_sse_auth_guard` bridges audit events to `SubscriberRegistry.close_by_identity()`,
5
+ * closing SSE streams when a subscriber's access is revoked (role revocation or
6
+ * session invalidation).
7
+ *
8
+ * `create_audit_log_sse` is a convenience factory that combines the registry,
9
+ * guard, and broadcaster — making the secure path the easy path for consumers.
10
+ *
11
+ * @module
12
+ */
13
+ import { AUDIT_EVENT_TYPES, AuditLogEventJson, } from '../auth/audit_log_schema.js';
14
+ import { SubscriberRegistry } from './subscriber_registry.js';
15
+ /**
16
+ * Audit event types that trigger SSE stream disconnection.
17
+ *
18
+ * `permit_revoke` requires the revoked role to match the guard's `required_role`.
19
+ * `session_revoke_all` and `password_change` close unconditionally for the target account.
20
+ */
21
+ export const DISCONNECT_EVENT_TYPES = new Set([
22
+ 'permit_revoke', // role revoked — user lost access
23
+ 'session_revoke_all', // all sessions invalidated — user should be kicked
24
+ 'password_change', // password changed — all sessions revoked implicitly
25
+ ]);
26
+ /**
27
+ * Create an audit event handler that closes SSE streams on auth changes.
28
+ *
29
+ * Closes streams when:
30
+ * - `permit_revoke` fires for the `required_role` targeting a connected subscriber
31
+ * - `session_revoke_all` targets a connected subscriber (consistent invalidation)
32
+ * - `password_change` targets a connected subscriber (sessions revoked implicitly)
33
+ *
34
+ * The registry must use `account_id` as the identity key when subscribing
35
+ * (passed as the third argument to `registry.subscribe()`).
36
+ *
37
+ * @param registry - the subscriber registry to guard
38
+ * @param required_role - the role that grants access to the SSE endpoint
39
+ * @param log - logger for disconnect events
40
+ * @returns an `on_audit_event` callback
41
+ */
42
+ export const create_sse_auth_guard = (registry, required_role, log) => {
43
+ return (event) => {
44
+ if (!DISCONNECT_EVENT_TYPES.has(event.event_type))
45
+ return;
46
+ // permit_revoke requires matching the specific role
47
+ if (event.event_type === 'permit_revoke') {
48
+ if (event.metadata?.role !== required_role)
49
+ return;
50
+ }
51
+ // resolve the affected account — admin actions set target_account_id,
52
+ // self-service actions (password_change, own session_revoke_all) only set account_id
53
+ const target = event.target_account_id ?? event.account_id;
54
+ if (!target)
55
+ return;
56
+ const closed = registry.close_by_identity(target);
57
+ if (closed > 0) {
58
+ log.info(`SSE auth guard: closed ${closed} stream(s) for account ${target} (${event.event_type})`);
59
+ }
60
+ };
61
+ };
62
+ /**
63
+ * Create a complete audit log SSE setup with broadcasting and auth guard.
64
+ *
65
+ * Combines `SubscriberRegistry`, `create_sse_auth_guard`, and the broadcast
66
+ * call into a single object. The result satisfies `AuditLogRouteOptions['stream']`
67
+ * and provides the `on_audit_event` callback for `CreateAppBackendOptions`.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * const audit_sse = create_audit_log_sse({log});
72
+ *
73
+ * // In create_app_backend options:
74
+ * on_audit_event: audit_sse.on_audit_event,
75
+ *
76
+ * // In create_route_specs:
77
+ * create_audit_log_route_specs({stream: audit_sse});
78
+ *
79
+ * // In create_app_server options:
80
+ * event_specs: AUDIT_LOG_EVENT_SPECS,
81
+ * ```
82
+ *
83
+ * @param options - factory options
84
+ * @returns audit log SSE setup (stream options + on_audit_event + registry)
85
+ */
86
+ /**
87
+ * SSE event specs for audit log events.
88
+ *
89
+ * One spec per `AUDIT_EVENT_TYPES` entry, all sharing the `AuditLogEventJson` params schema.
90
+ * Pass to `create_app_server`'s `event_specs` for surface generation and DEV validation.
91
+ */
92
+ export const AUDIT_LOG_EVENT_SPECS = AUDIT_EVENT_TYPES.map((event_type) => ({
93
+ method: event_type,
94
+ params: AuditLogEventJson,
95
+ description: `Audit log: ${event_type.replaceAll('_', ' ')}`,
96
+ channel: 'audit_log',
97
+ }));
98
+ export const create_audit_log_sse = (options) => {
99
+ const role = options.role ?? 'admin';
100
+ const registry = new SubscriberRegistry();
101
+ const guard = create_sse_auth_guard(registry, role, options.log);
102
+ return {
103
+ subscribe: registry.subscribe.bind(registry),
104
+ log: options.log,
105
+ on_audit_event: (event) => {
106
+ registry.broadcast('audit_log', { method: event.event_type, params: event });
107
+ guard(event);
108
+ },
109
+ registry,
110
+ };
111
+ };
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Generic subscriber registry for broadcasting to SSE clients.
3
+ *
4
+ * Supports channel-based filtering — subscribers connect with optional
5
+ * channel filters, and broadcasts reach only matching subscribers.
6
+ * Optional identity keys enable force-closing subscribers by identity
7
+ * (e.g., close all streams for a specific account when their permissions change).
8
+ *
9
+ * @module
10
+ */
11
+ import type { SseStream } from './sse.js';
12
+ export interface Subscriber<T> {
13
+ stream: SseStream<T>;
14
+ /** Channels this subscriber listens to. `null` means all channels. */
15
+ channels: Set<string> | null;
16
+ /** Optional identity key for targeted disconnection (e.g., account_id). */
17
+ identity: string | null;
18
+ }
19
+ /**
20
+ * Generic subscriber registry with channel-based filtering and identity-keyed disconnection.
21
+ *
22
+ * Subscribers connect with optional channel filters and an optional identity key.
23
+ * Broadcasts go to a specific channel and reach only matching subscribers.
24
+ * `close_by_identity` force-closes all subscribers with a given identity —
25
+ * use for auth revocation (close streams when a user's permissions change).
26
+ *
27
+ * @example
28
+ * ```ts
29
+ * const registry = new SubscriberRegistry<SseNotification>();
30
+ *
31
+ * // subscriber connects (from SSE endpoint)
32
+ * const unsubscribe = registry.subscribe(stream, ['runs']);
33
+ *
34
+ * // when a run changes
35
+ * registry.broadcast('runs', {method: 'run_created', params: {run}});
36
+ *
37
+ * // subscriber disconnects
38
+ * unsubscribe();
39
+ * ```
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * // identity-keyed subscription for auth revocation
44
+ * const unsubscribe = registry.subscribe(stream, ['audit_log'], account_id);
45
+ *
46
+ * // when admin revokes the user's role — close their streams
47
+ * registry.close_by_identity(account_id);
48
+ * ```
49
+ */
50
+ export declare class SubscriberRegistry<T> {
51
+ #private;
52
+ /** Number of active subscribers. */
53
+ get count(): number;
54
+ /**
55
+ * Add a subscriber.
56
+ *
57
+ * @param stream - SSE stream to send data to
58
+ * @param channels - channels to subscribe to (`undefined` or empty = all channels)
59
+ * @param identity - optional identity key for targeted disconnection
60
+ * @returns unsubscribe function
61
+ */
62
+ subscribe(stream: SseStream<T>, channels?: Array<string>, identity?: string): () => void;
63
+ /**
64
+ * Broadcast data to all subscribers on a channel.
65
+ *
66
+ * Subscribers with no channel filter receive all broadcasts.
67
+ * Subscribers with a channel filter only receive matching broadcasts.
68
+ *
69
+ * @param channel - the channel to broadcast on
70
+ * @param data - the data to send
71
+ */
72
+ broadcast(channel: string, data: T): void;
73
+ /**
74
+ * Force-close all subscribers with the given identity.
75
+ *
76
+ * Closes each matching stream and removes the subscriber from the registry.
77
+ * Use for auth revocation — when a user's permissions change, close their
78
+ * SSE connections so they must reconnect and re-authenticate.
79
+ *
80
+ * @param identity - the identity key to match
81
+ * @returns the number of subscribers closed
82
+ */
83
+ close_by_identity(identity: string): number;
84
+ }
85
+ //# sourceMappingURL=subscriber_registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscriber_registry.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/realtime/subscriber_registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,UAAU,CAAC;AAExC,MAAM,WAAW,UAAU,CAAC,CAAC;IAC5B,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACrB,sEAAsE;IACtE,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAC7B,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,kBAAkB,CAAC,CAAC;;IAGhC,oCAAoC;IACpC,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;;;;;;OAOG;IACH,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI;IAYxF;;;;;;;;OAQG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI;IAQzC;;;;;;;;;OASG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAe3C"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Generic subscriber registry for broadcasting to SSE clients.
3
+ *
4
+ * Supports channel-based filtering — subscribers connect with optional
5
+ * channel filters, and broadcasts reach only matching subscribers.
6
+ * Optional identity keys enable force-closing subscribers by identity
7
+ * (e.g., close all streams for a specific account when their permissions change).
8
+ *
9
+ * @module
10
+ */
11
+ /**
12
+ * Generic subscriber registry with channel-based filtering and identity-keyed disconnection.
13
+ *
14
+ * Subscribers connect with optional channel filters and an optional identity key.
15
+ * Broadcasts go to a specific channel and reach only matching subscribers.
16
+ * `close_by_identity` force-closes all subscribers with a given identity —
17
+ * use for auth revocation (close streams when a user's permissions change).
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * const registry = new SubscriberRegistry<SseNotification>();
22
+ *
23
+ * // subscriber connects (from SSE endpoint)
24
+ * const unsubscribe = registry.subscribe(stream, ['runs']);
25
+ *
26
+ * // when a run changes
27
+ * registry.broadcast('runs', {method: 'run_created', params: {run}});
28
+ *
29
+ * // subscriber disconnects
30
+ * unsubscribe();
31
+ * ```
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * // identity-keyed subscription for auth revocation
36
+ * const unsubscribe = registry.subscribe(stream, ['audit_log'], account_id);
37
+ *
38
+ * // when admin revokes the user's role — close their streams
39
+ * registry.close_by_identity(account_id);
40
+ * ```
41
+ */
42
+ export class SubscriberRegistry {
43
+ #subscribers = new Set();
44
+ /** Number of active subscribers. */
45
+ get count() {
46
+ return this.#subscribers.size;
47
+ }
48
+ /**
49
+ * Add a subscriber.
50
+ *
51
+ * @param stream - SSE stream to send data to
52
+ * @param channels - channels to subscribe to (`undefined` or empty = all channels)
53
+ * @param identity - optional identity key for targeted disconnection
54
+ * @returns unsubscribe function
55
+ */
56
+ subscribe(stream, channels, identity) {
57
+ const subscriber = {
58
+ stream,
59
+ channels: channels && channels.length > 0 ? new Set(channels) : null,
60
+ identity: identity ?? null,
61
+ };
62
+ this.#subscribers.add(subscriber);
63
+ return () => {
64
+ this.#subscribers.delete(subscriber);
65
+ };
66
+ }
67
+ /**
68
+ * Broadcast data to all subscribers on a channel.
69
+ *
70
+ * Subscribers with no channel filter receive all broadcasts.
71
+ * Subscribers with a channel filter only receive matching broadcasts.
72
+ *
73
+ * @param channel - the channel to broadcast on
74
+ * @param data - the data to send
75
+ */
76
+ broadcast(channel, data) {
77
+ for (const subscriber of this.#subscribers) {
78
+ if (subscriber.channels === null || subscriber.channels.has(channel)) {
79
+ subscriber.stream.send(data);
80
+ }
81
+ }
82
+ }
83
+ /**
84
+ * Force-close all subscribers with the given identity.
85
+ *
86
+ * Closes each matching stream and removes the subscriber from the registry.
87
+ * Use for auth revocation — when a user's permissions change, close their
88
+ * SSE connections so they must reconnect and re-authenticate.
89
+ *
90
+ * @param identity - the identity key to match
91
+ * @returns the number of subscribers closed
92
+ */
93
+ close_by_identity(identity) {
94
+ // collect first, then close — avoids mutating the Set during iteration
95
+ // (stream.close() fires on_close listeners which may call unsubscribe)
96
+ const to_close = [];
97
+ for (const subscriber of this.#subscribers) {
98
+ if (subscriber.identity === identity) {
99
+ to_close.push(subscriber);
100
+ }
101
+ }
102
+ for (const subscriber of to_close) {
103
+ subscriber.stream.close();
104
+ this.#subscribers.delete(subscriber);
105
+ }
106
+ return to_close.length;
107
+ }
108
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Deno implementation of `RuntimeDeps`.
3
+ *
4
+ * Provides `create_deno_runtime(args)` — a factory returning a `RuntimeDeps`
5
+ * backed by Deno APIs. Only imported by Deno entry points (compiled binaries
6
+ * for tx, zzz, etc.).
7
+ *
8
+ * @module
9
+ */
10
+ import type { RuntimeDeps } from './deps.js';
11
+ /**
12
+ * Create a runtime backed by Deno APIs.
13
+ *
14
+ * Returns an object satisfying all `*Deps` interfaces from `deps.ts`.
15
+ * Pass to shared functions that accept `EnvDeps`, `FsReadDeps`, etc.
16
+ *
17
+ * @param args - CLI arguments (typically `Deno.args`)
18
+ * @returns runtime implementation using Deno APIs
19
+ */
20
+ export declare const create_deno_runtime: (args: ReadonlyArray<string>) => RuntimeDeps;
21
+ //# sourceMappingURL=deno.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deno.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/runtime/deno.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAC,WAAW,EAA4B,MAAM,WAAW,CAAC;AAoCtE;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM,aAAa,CAAC,MAAM,CAAC,KAAG,WAmEhE,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Deno implementation of `RuntimeDeps`.
3
+ *
4
+ * Provides `create_deno_runtime(args)` — a factory returning a `RuntimeDeps`
5
+ * backed by Deno APIs. Only imported by Deno entry points (compiled binaries
6
+ * for tx, zzz, etc.).
7
+ *
8
+ * @module
9
+ */
10
+ /**
11
+ * Create a runtime backed by Deno APIs.
12
+ *
13
+ * Returns an object satisfying all `*Deps` interfaces from `deps.ts`.
14
+ * Pass to shared functions that accept `EnvDeps`, `FsReadDeps`, etc.
15
+ *
16
+ * @param args - CLI arguments (typically `Deno.args`)
17
+ * @returns runtime implementation using Deno APIs
18
+ */
19
+ export const create_deno_runtime = (args) => ({
20
+ // === Environment ===
21
+ env_get: (name) => Deno.env.get(name),
22
+ env_set: (name, value) => Deno.env.set(name, value),
23
+ env_all: () => Deno.env.toObject(),
24
+ // === Process ===
25
+ args,
26
+ cwd: () => Deno.cwd(),
27
+ exit: (code) => Deno.exit(code),
28
+ // === Local File System ===
29
+ stat: async (path) => {
30
+ try {
31
+ const s = await Deno.stat(path);
32
+ return { is_file: s.isFile, is_directory: s.isDirectory };
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ },
38
+ mkdir: (path, options) => Deno.mkdir(path, options),
39
+ read_file: (path) => Deno.readTextFile(path),
40
+ write_file: (path, content) => Deno.writeTextFile(path, content),
41
+ rename: (old_path, new_path) => Deno.rename(old_path, new_path),
42
+ remove: (path, options) => Deno.remove(path, options),
43
+ // === Local Commands ===
44
+ run_command: async (cmd, args) => {
45
+ try {
46
+ const proc = new Deno.Command(cmd, {
47
+ args,
48
+ stdout: 'piped',
49
+ stderr: 'piped',
50
+ });
51
+ const result = await proc.output();
52
+ return {
53
+ success: result.code === 0,
54
+ code: result.code,
55
+ stdout: new TextDecoder().decode(result.stdout),
56
+ stderr: new TextDecoder().decode(result.stderr),
57
+ };
58
+ }
59
+ catch (error) {
60
+ const message = error instanceof Error ? error.message : String(error);
61
+ return {
62
+ success: false,
63
+ code: 1,
64
+ stdout: '',
65
+ stderr: `Failed to execute command: ${message}`,
66
+ };
67
+ }
68
+ },
69
+ run_command_inherit: async (cmd, args) => {
70
+ const proc = new Deno.Command(cmd, {
71
+ args,
72
+ stdout: 'inherit',
73
+ stderr: 'inherit',
74
+ });
75
+ const result = await proc.output();
76
+ return result.code;
77
+ },
78
+ // === Terminal I/O ===
79
+ stdout_write: (data) => Deno.stdout.write(data),
80
+ stdin_read: (buffer) => Deno.stdin.read(buffer),
81
+ // === Logging ===
82
+ warn: (...args) => console.warn(...args),
83
+ });