@noego/wood 0.4.10 → 0.5.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 (382) hide show
  1. package/README.md +118 -42
  2. package/dist/bridge/backend_bridge.cjs.map +1 -1
  3. package/dist/bridge/backend_bridge.js.map +1 -1
  4. package/dist/client/index.cjs +78 -21
  5. package/dist/client/index.cjs.map +1 -1
  6. package/dist/client/index.d.cts +18 -3
  7. package/dist/client/index.d.ts +18 -3
  8. package/dist/client/index.js +80 -22
  9. package/dist/client/index.js.map +1 -1
  10. package/dist/client/renderer_log_transport.cjs +151 -0
  11. package/dist/client/renderer_log_transport.cjs.map +1 -0
  12. package/dist/client/renderer_log_transport.d.cts +54 -0
  13. package/dist/client/renderer_log_transport.d.ts +54 -0
  14. package/dist/client/renderer_log_transport.js +123 -0
  15. package/dist/client/renderer_log_transport.js.map +1 -0
  16. package/dist/codegen/controller_registration_generator.cjs +13 -2
  17. package/dist/codegen/controller_registration_generator.cjs.map +1 -1
  18. package/dist/codegen/controller_registration_generator.d.cts +12 -1
  19. package/dist/codegen/controller_registration_generator.d.ts +12 -1
  20. package/dist/codegen/controller_registration_generator.js +10 -1
  21. package/dist/codegen/controller_registration_generator.js.map +1 -1
  22. package/dist/codegen/index.d.cts +1 -0
  23. package/dist/codegen/index.d.ts +1 -0
  24. package/dist/codegen/preload_generator.cjs +13 -6
  25. package/dist/codegen/preload_generator.cjs.map +1 -1
  26. package/dist/codegen/preload_generator.d.cts +11 -2
  27. package/dist/codegen/preload_generator.d.ts +11 -2
  28. package/dist/codegen/preload_generator.js +13 -6
  29. package/dist/codegen/preload_generator.js.map +1 -1
  30. package/dist/codegen/renderer_app_generator.cjs +78 -42
  31. package/dist/codegen/renderer_app_generator.cjs.map +1 -1
  32. package/dist/codegen/renderer_app_generator.js +78 -42
  33. package/dist/codegen/renderer_app_generator.js.map +1 -1
  34. package/dist/codegen/type_generator.cjs +1 -0
  35. package/dist/codegen/type_generator.cjs.map +1 -1
  36. package/dist/codegen/type_generator.js +1 -0
  37. package/dist/codegen/type_generator.js.map +1 -1
  38. package/dist/config/config_parser.cjs +95 -4
  39. package/dist/config/config_parser.cjs.map +1 -1
  40. package/dist/config/config_parser.d.cts +10 -2
  41. package/dist/config/config_parser.d.ts +10 -2
  42. package/dist/config/config_parser.js +92 -3
  43. package/dist/config/config_parser.js.map +1 -1
  44. package/dist/config/index.cjs +6 -2
  45. package/dist/config/index.cjs.map +1 -1
  46. package/dist/config/index.d.cts +2 -2
  47. package/dist/config/index.d.ts +2 -2
  48. package/dist/config/index.js +8 -2
  49. package/dist/config/index.js.map +1 -1
  50. package/dist/controller/controller_resolver.cjs +51 -3
  51. package/dist/controller/controller_resolver.cjs.map +1 -1
  52. package/dist/controller/controller_resolver.d.cts +27 -4
  53. package/dist/controller/controller_resolver.d.ts +27 -4
  54. package/dist/controller/controller_resolver.js +48 -2
  55. package/dist/controller/controller_resolver.js.map +1 -1
  56. package/dist/controller/index.cjs +6 -2
  57. package/dist/controller/index.cjs.map +1 -1
  58. package/dist/controller/index.d.cts +1 -1
  59. package/dist/controller/index.d.ts +1 -1
  60. package/dist/controller/index.js +4 -2
  61. package/dist/controller/index.js.map +1 -1
  62. package/dist/dev/wood_dev_server.cjs +4 -1
  63. package/dist/dev/wood_dev_server.cjs.map +1 -1
  64. package/dist/dev/wood_dev_server.js +5 -2
  65. package/dist/dev/wood_dev_server.js.map +1 -1
  66. package/dist/dev/yaml_watcher.cjs +1 -1
  67. package/dist/dev/yaml_watcher.cjs.map +1 -1
  68. package/dist/dev/yaml_watcher.d.cts +4 -0
  69. package/dist/dev/yaml_watcher.d.ts +4 -0
  70. package/dist/dev/yaml_watcher.js +1 -1
  71. package/dist/dev/yaml_watcher.js.map +1 -1
  72. package/dist/frontend/frontend_lifecycle.cjs +74 -0
  73. package/dist/frontend/frontend_lifecycle.cjs.map +1 -0
  74. package/dist/frontend/frontend_lifecycle.d.cts +50 -0
  75. package/dist/frontend/frontend_lifecycle.d.ts +50 -0
  76. package/dist/frontend/frontend_lifecycle.js +50 -0
  77. package/dist/frontend/frontend_lifecycle.js.map +1 -0
  78. package/dist/frontend/frontend_page.cjs +122 -0
  79. package/dist/frontend/frontend_page.cjs.map +1 -0
  80. package/dist/frontend/frontend_page.d.cts +62 -0
  81. package/dist/frontend/frontend_page.d.ts +62 -0
  82. package/dist/frontend/frontend_page.js +98 -0
  83. package/dist/frontend/frontend_page.js.map +1 -0
  84. package/dist/frontend/frontend_surface.cjs +249 -0
  85. package/dist/frontend/frontend_surface.cjs.map +1 -0
  86. package/dist/frontend/frontend_surface.d.cts +64 -0
  87. package/dist/frontend/frontend_surface.d.ts +64 -0
  88. package/dist/frontend/frontend_surface.js +224 -0
  89. package/dist/frontend/frontend_surface.js.map +1 -0
  90. package/dist/frontend/index.cjs +52 -0
  91. package/dist/frontend/index.cjs.map +1 -0
  92. package/dist/frontend/index.d.cts +10 -0
  93. package/dist/frontend/index.d.ts +10 -0
  94. package/dist/frontend/index.js +19 -0
  95. package/dist/frontend/index.js.map +1 -0
  96. package/dist/frontend/page_catalog.cjs +135 -0
  97. package/dist/frontend/page_catalog.cjs.map +1 -0
  98. package/dist/frontend/page_catalog.d.cts +56 -0
  99. package/dist/frontend/page_catalog.d.ts +56 -0
  100. package/dist/frontend/page_catalog.js +108 -0
  101. package/dist/frontend/page_catalog.js.map +1 -0
  102. package/dist/frontend/tracked_transport.cjs +55 -0
  103. package/dist/frontend/tracked_transport.cjs.map +1 -0
  104. package/dist/frontend/tracked_transport.d.cts +36 -0
  105. package/dist/frontend/tracked_transport.d.ts +36 -0
  106. package/dist/frontend/tracked_transport.js +31 -0
  107. package/dist/frontend/tracked_transport.js.map +1 -0
  108. package/dist/frontend/work_registry.cjs +153 -0
  109. package/dist/frontend/work_registry.cjs.map +1 -0
  110. package/dist/frontend/work_registry.d.cts +70 -0
  111. package/dist/frontend/work_registry.d.ts +70 -0
  112. package/dist/frontend/work_registry.js +128 -0
  113. package/dist/frontend/work_registry.js.map +1 -0
  114. package/dist/index.cjs +24 -0
  115. package/dist/index.cjs.map +1 -1
  116. package/dist/index.d.cts +10 -7
  117. package/dist/index.d.ts +10 -7
  118. package/dist/index.js +27 -4
  119. package/dist/index.js.map +1 -1
  120. package/dist/main/index.cjs +10 -0
  121. package/dist/main/index.cjs.map +1 -1
  122. package/dist/main/index.d.cts +14 -2
  123. package/dist/main/index.d.ts +14 -2
  124. package/dist/main/index.js +16 -0
  125. package/dist/main/index.js.map +1 -1
  126. package/dist/middleware/middleware_resolver.cjs +22 -1
  127. package/dist/middleware/middleware_resolver.cjs.map +1 -1
  128. package/dist/middleware/middleware_resolver.d.cts +13 -1
  129. package/dist/middleware/middleware_resolver.d.ts +13 -1
  130. package/dist/middleware/middleware_resolver.js +22 -1
  131. package/dist/middleware/middleware_resolver.js.map +1 -1
  132. package/dist/navigation/index.cjs +3 -0
  133. package/dist/navigation/index.cjs.map +1 -1
  134. package/dist/navigation/index.d.cts +25 -1
  135. package/dist/navigation/index.d.ts +25 -1
  136. package/dist/navigation/index.js +2 -0
  137. package/dist/navigation/index.js.map +1 -1
  138. package/dist/{middleware/__fixtures__/middleware/auth.cjs → navigation/layout_preservation.cjs} +18 -20
  139. package/dist/navigation/layout_preservation.cjs.map +1 -0
  140. package/dist/navigation/layout_preservation.d.cts +2 -0
  141. package/dist/navigation/layout_preservation.d.ts +2 -0
  142. package/dist/navigation/layout_preservation.js +18 -0
  143. package/dist/navigation/layout_preservation.js.map +1 -0
  144. package/dist/parser/index.cjs +2 -0
  145. package/dist/parser/index.cjs.map +1 -1
  146. package/dist/parser/index.d.cts +1 -1
  147. package/dist/parser/index.d.ts +1 -1
  148. package/dist/parser/index.js +2 -1
  149. package/dist/parser/index.js.map +1 -1
  150. package/dist/parser/operations_parser.cjs +6 -0
  151. package/dist/parser/operations_parser.cjs.map +1 -1
  152. package/dist/parser/operations_parser.d.cts +9 -2
  153. package/dist/parser/operations_parser.d.ts +9 -2
  154. package/dist/parser/operations_parser.js +5 -0
  155. package/dist/parser/operations_parser.js.map +1 -1
  156. package/dist/parser/views_parser.cjs.map +1 -1
  157. package/dist/parser/views_parser.js.map +1 -1
  158. package/dist/router/index.d.cts +1 -0
  159. package/dist/router/index.d.ts +1 -0
  160. package/dist/router/wood_router.cjs +35 -3
  161. package/dist/router/wood_router.cjs.map +1 -1
  162. package/dist/router/wood_router.d.cts +15 -0
  163. package/dist/router/wood_router.d.ts +15 -0
  164. package/dist/router/wood_router.js +36 -4
  165. package/dist/router/wood_router.js.map +1 -1
  166. package/dist/runtime/get_container.cjs +9 -34
  167. package/dist/runtime/get_container.cjs.map +1 -1
  168. package/dist/runtime/get_container.d.cts +24 -4
  169. package/dist/runtime/get_container.d.ts +24 -4
  170. package/dist/runtime/get_container.js +8 -23
  171. package/dist/runtime/get_container.js.map +1 -1
  172. package/dist/runtime/index.cjs +9 -0
  173. package/dist/runtime/index.cjs.map +1 -1
  174. package/dist/runtime/index.d.cts +5 -2
  175. package/dist/runtime/index.d.ts +5 -2
  176. package/dist/runtime/index.js +10 -1
  177. package/dist/runtime/index.js.map +1 -1
  178. package/dist/runtime/renderer_config_extension.cjs +50 -0
  179. package/dist/runtime/renderer_config_extension.cjs.map +1 -0
  180. package/dist/runtime/renderer_config_extension.d.cts +19 -0
  181. package/dist/runtime/renderer_config_extension.d.ts +19 -0
  182. package/dist/runtime/renderer_config_extension.js +24 -0
  183. package/dist/runtime/renderer_config_extension.js.map +1 -0
  184. package/dist/runtime/renderer_log_batch_receiver.cjs +73 -0
  185. package/dist/runtime/renderer_log_batch_receiver.cjs.map +1 -0
  186. package/dist/runtime/renderer_log_batch_receiver.d.cts +29 -0
  187. package/dist/runtime/renderer_log_batch_receiver.d.ts +29 -0
  188. package/dist/runtime/renderer_log_batch_receiver.js +48 -0
  189. package/dist/runtime/renderer_log_batch_receiver.js.map +1 -0
  190. package/dist/runtime/renderer_trace_batch_receiver_registry.d.cts +1 -1
  191. package/dist/runtime/renderer_trace_batch_receiver_registry.d.ts +1 -1
  192. package/dist/runtime/runtime.cjs +14 -0
  193. package/dist/runtime/runtime.cjs.map +1 -1
  194. package/dist/runtime/runtime.d.cts +2 -1
  195. package/dist/runtime/runtime.d.ts +2 -1
  196. package/dist/runtime/runtime.js +14 -0
  197. package/dist/runtime/runtime.js.map +1 -1
  198. package/dist/stick/index.cjs.map +1 -1
  199. package/dist/stick/index.js.map +1 -1
  200. package/dist/testing/browser.cjs +104 -23
  201. package/dist/testing/browser.cjs.map +1 -1
  202. package/dist/testing/browser.d.cts +8 -3
  203. package/dist/testing/browser.d.ts +8 -3
  204. package/dist/testing/browser.js +102 -22
  205. package/dist/testing/browser.js.map +1 -1
  206. package/dist/testing/create_controller_harness.cjs +28 -8
  207. package/dist/testing/create_controller_harness.cjs.map +1 -1
  208. package/dist/testing/create_controller_harness.d.cts +17 -2
  209. package/dist/testing/create_controller_harness.d.ts +17 -2
  210. package/dist/testing/create_controller_harness.js +28 -8
  211. package/dist/testing/create_controller_harness.js.map +1 -1
  212. package/dist/testing/create_router_bridge.d.cts +1 -0
  213. package/dist/testing/create_router_bridge.d.ts +1 -0
  214. package/dist/testing/create_test_router.d.cts +1 -0
  215. package/dist/testing/create_test_router.d.ts +1 -0
  216. package/dist/testing/index.cjs +31 -0
  217. package/dist/testing/index.cjs.map +1 -1
  218. package/dist/testing/index.d.cts +20 -5
  219. package/dist/testing/index.d.ts +20 -5
  220. package/dist/testing/index.js +19 -1
  221. package/dist/testing/index.js.map +1 -1
  222. package/dist/{controller/__fixtures__/controllers/not_a_class.cjs → testing/test_wood.cjs} +15 -7
  223. package/dist/testing/test_wood.cjs.map +1 -0
  224. package/dist/testing/test_wood.d.cts +16 -0
  225. package/dist/testing/test_wood.d.ts +16 -0
  226. package/dist/testing/test_wood.js +12 -0
  227. package/dist/testing/test_wood.js.map +1 -0
  228. package/dist/testing/test_wood_config.cjs +272 -0
  229. package/dist/testing/test_wood_config.cjs.map +1 -0
  230. package/dist/testing/test_wood_config.d.cts +111 -0
  231. package/dist/testing/test_wood_config.d.ts +111 -0
  232. package/dist/testing/test_wood_config.js +247 -0
  233. package/dist/testing/test_wood_config.js.map +1 -0
  234. package/dist/testing/wood_config_source.cjs +146 -0
  235. package/dist/testing/wood_config_source.cjs.map +1 -0
  236. package/dist/testing/wood_config_source.d.cts +36 -0
  237. package/dist/testing/wood_config_source.d.ts +36 -0
  238. package/dist/testing/wood_config_source.js +112 -0
  239. package/dist/testing/wood_config_source.js.map +1 -0
  240. package/dist/testing/wood_env_renderer.cjs +210 -0
  241. package/dist/testing/wood_env_renderer.cjs.map +1 -0
  242. package/dist/testing/wood_env_renderer.d.cts +74 -0
  243. package/dist/testing/wood_env_renderer.d.ts +74 -0
  244. package/dist/testing/wood_env_renderer.js +188 -0
  245. package/dist/testing/wood_env_renderer.js.map +1 -0
  246. package/dist/testing/wood_test_selection.cjs +94 -0
  247. package/dist/testing/wood_test_selection.cjs.map +1 -0
  248. package/dist/testing/wood_test_selection.d.cts +39 -0
  249. package/dist/testing/wood_test_selection.d.ts +39 -0
  250. package/dist/testing/wood_test_selection.js +68 -0
  251. package/dist/testing/wood_test_selection.js.map +1 -0
  252. package/dist/trace-testing/index.d.cts +1 -2
  253. package/dist/trace-testing/index.d.ts +1 -2
  254. package/dist/trace-testing/trace_recorder.cjs +1 -1
  255. package/dist/trace-testing/trace_recorder.cjs.map +1 -1
  256. package/dist/trace-testing/trace_recorder.d.cts +1 -2
  257. package/dist/trace-testing/trace_recorder.d.ts +1 -2
  258. package/dist/trace-testing/trace_recorder.js +1 -1
  259. package/dist/trace-testing/trace_recorder.js.map +1 -1
  260. package/dist/trace-transport/index.d.cts +1 -1
  261. package/dist/trace-transport/index.d.ts +1 -1
  262. package/dist/{trace_hub-Cob54qRx.d.cts → trace_hub-Cpo_nVze.d.cts} +21 -1
  263. package/dist/{trace_hub-Cob54qRx.d.ts → trace_hub-Cpo_nVze.d.ts} +21 -1
  264. package/dist/tracing/index.cjs +9 -2
  265. package/dist/tracing/index.cjs.map +1 -1
  266. package/dist/tracing/index.d.cts +3 -2
  267. package/dist/tracing/index.d.ts +3 -2
  268. package/dist/tracing/index.js +7 -1
  269. package/dist/tracing/index.js.map +1 -1
  270. package/dist/tracing/renderer_trace_batch_host.d.cts +1 -1
  271. package/dist/tracing/renderer_trace_batch_host.d.ts +1 -1
  272. package/dist/tracing/renderer_trace_batch_transport.cjs +48 -6
  273. package/dist/tracing/renderer_trace_batch_transport.cjs.map +1 -1
  274. package/dist/tracing/renderer_trace_batch_transport.d.cts +17 -1
  275. package/dist/tracing/renderer_trace_batch_transport.d.ts +17 -1
  276. package/dist/tracing/renderer_trace_batch_transport.js +48 -6
  277. package/dist/tracing/renderer_trace_batch_transport.js.map +1 -1
  278. package/dist/tracing/trace_batch_adapter.cjs +110 -0
  279. package/dist/tracing/trace_batch_adapter.cjs.map +1 -0
  280. package/dist/tracing/trace_batch_adapter.d.cts +36 -0
  281. package/dist/tracing/trace_batch_adapter.d.ts +36 -0
  282. package/dist/tracing/trace_batch_adapter.js +86 -0
  283. package/dist/tracing/trace_batch_adapter.js.map +1 -0
  284. package/dist/tracing/trace_commit_writer.d.cts +1 -1
  285. package/dist/tracing/trace_commit_writer.d.ts +1 -1
  286. package/dist/tracing/trace_hub.cjs +87 -20
  287. package/dist/tracing/trace_hub.cjs.map +1 -1
  288. package/dist/tracing/trace_hub.d.cts +1 -1
  289. package/dist/tracing/trace_hub.d.ts +1 -1
  290. package/dist/tracing/trace_hub.js +85 -20
  291. package/dist/tracing/trace_hub.js.map +1 -1
  292. package/dist/tracing/trace_provider.cjs +21 -6
  293. package/dist/tracing/trace_provider.cjs.map +1 -1
  294. package/dist/tracing/trace_provider.d.cts +13 -4
  295. package/dist/tracing/trace_provider.d.ts +13 -4
  296. package/dist/tracing/trace_provider.js +22 -7
  297. package/dist/tracing/trace_provider.js.map +1 -1
  298. package/dist/tracing/types/wood_trace_batch.types.cjs.map +1 -1
  299. package/dist/tracing/types/wood_trace_batch.types.d.cts +15 -1
  300. package/dist/tracing/types/wood_trace_batch.types.d.ts +15 -1
  301. package/dist/tracing/types/wood_trace_sink.types.d.cts +1 -1
  302. package/dist/tracing/types/wood_trace_sink.types.d.ts +1 -1
  303. package/dist/tracing/wood_trace_batch_contract.cjs +2 -0
  304. package/dist/tracing/wood_trace_batch_contract.cjs.map +1 -1
  305. package/dist/tracing/wood_trace_batch_contract.d.cts +1 -1
  306. package/dist/tracing/wood_trace_batch_contract.d.ts +1 -1
  307. package/dist/tracing/wood_trace_batch_contract.js +2 -0
  308. package/dist/tracing/wood_trace_batch_contract.js.map +1 -1
  309. package/dist/transport/build_transport_bridge.cjs +4 -2
  310. package/dist/transport/build_transport_bridge.cjs.map +1 -1
  311. package/dist/transport/build_transport_bridge.d.cts +7 -1
  312. package/dist/transport/build_transport_bridge.d.ts +7 -1
  313. package/dist/transport/build_transport_bridge.js +2 -1
  314. package/dist/transport/build_transport_bridge.js.map +1 -1
  315. package/dist/transport/in_process_router_transport.d.cts +1 -0
  316. package/dist/transport/in_process_router_transport.d.ts +1 -0
  317. package/dist/transport/index.d.cts +1 -0
  318. package/dist/transport/index.d.ts +1 -0
  319. package/dist/types/config.cjs.map +1 -1
  320. package/dist/types/config.d.cts +47 -1
  321. package/dist/types/config.d.ts +47 -1
  322. package/dist/types/context.cjs +12 -0
  323. package/dist/types/context.cjs.map +1 -1
  324. package/dist/types/context.d.cts +27 -1
  325. package/dist/types/context.d.ts +27 -1
  326. package/dist/types/context.js +4 -0
  327. package/dist/types/context.js.map +1 -1
  328. package/dist/types/index.d.cts +2 -2
  329. package/dist/types/index.d.ts +2 -2
  330. package/dist/types/operations.cjs.map +1 -1
  331. package/dist/types/operations.d.cts +2 -0
  332. package/dist/types/operations.d.ts +2 -0
  333. package/docs/axe.md +706 -0
  334. package/package.json +13 -5
  335. package/src/components/NavigationShell.scopes.browser.test.ts +363 -0
  336. package/src/components/NavigationShell.svelte +126 -49
  337. package/dist/controller/__fixtures__/controllers/chat.cjs +0 -32
  338. package/dist/controller/__fixtures__/controllers/chat.cjs.map +0 -1
  339. package/dist/controller/__fixtures__/controllers/chat.d.cts +0 -11
  340. package/dist/controller/__fixtures__/controllers/chat.d.ts +0 -11
  341. package/dist/controller/__fixtures__/controllers/chat.js +0 -12
  342. package/dist/controller/__fixtures__/controllers/chat.js.map +0 -1
  343. package/dist/controller/__fixtures__/controllers/not_a_class.cjs.map +0 -1
  344. package/dist/controller/__fixtures__/controllers/not_a_class.d.cts +0 -3
  345. package/dist/controller/__fixtures__/controllers/not_a_class.d.ts +0 -3
  346. package/dist/controller/__fixtures__/controllers/not_a_class.js +0 -5
  347. package/dist/controller/__fixtures__/controllers/not_a_class.js.map +0 -1
  348. package/dist/controller/__fixtures__/controllers/settings.controller.cjs +0 -32
  349. package/dist/controller/__fixtures__/controllers/settings.controller.cjs.map +0 -1
  350. package/dist/controller/__fixtures__/controllers/settings.controller.d.cts +0 -12
  351. package/dist/controller/__fixtures__/controllers/settings.controller.d.ts +0 -12
  352. package/dist/controller/__fixtures__/controllers/settings.controller.js +0 -12
  353. package/dist/controller/__fixtures__/controllers/settings.controller.js.map +0 -1
  354. package/dist/controller/__fixtures__/controllers/test.cjs +0 -29
  355. package/dist/controller/__fixtures__/controllers/test.cjs.map +0 -1
  356. package/dist/controller/__fixtures__/controllers/test.d.cts +0 -7
  357. package/dist/controller/__fixtures__/controllers/test.d.ts +0 -7
  358. package/dist/controller/__fixtures__/controllers/test.js +0 -9
  359. package/dist/controller/__fixtures__/controllers/test.js.map +0 -1
  360. package/dist/loader/__fixtures__/layouts/app.load.cjs +0 -27
  361. package/dist/loader/__fixtures__/layouts/app.load.cjs.map +0 -1
  362. package/dist/loader/__fixtures__/layouts/app.load.d.cts +0 -5
  363. package/dist/loader/__fixtures__/layouts/app.load.d.ts +0 -5
  364. package/dist/loader/__fixtures__/layouts/app.load.js +0 -7
  365. package/dist/loader/__fixtures__/layouts/app.load.js.map +0 -1
  366. package/dist/loader/__fixtures__/views/test/page.load.cjs +0 -27
  367. package/dist/loader/__fixtures__/views/test/page.load.cjs.map +0 -1
  368. package/dist/loader/__fixtures__/views/test/page.load.d.cts +0 -6
  369. package/dist/loader/__fixtures__/views/test/page.load.d.ts +0 -6
  370. package/dist/loader/__fixtures__/views/test/page.load.js +0 -7
  371. package/dist/loader/__fixtures__/views/test/page.load.js.map +0 -1
  372. package/dist/middleware/__fixtures__/middleware/auth.cjs.map +0 -1
  373. package/dist/middleware/__fixtures__/middleware/auth.d.cts +0 -6
  374. package/dist/middleware/__fixtures__/middleware/auth.d.ts +0 -6
  375. package/dist/middleware/__fixtures__/middleware/auth.js +0 -19
  376. package/dist/middleware/__fixtures__/middleware/auth.js.map +0 -1
  377. package/dist/middleware/__fixtures__/middleware/sequence.cjs +0 -47
  378. package/dist/middleware/__fixtures__/middleware/sequence.cjs.map +0 -1
  379. package/dist/middleware/__fixtures__/middleware/sequence.d.cts +0 -7
  380. package/dist/middleware/__fixtures__/middleware/sequence.d.ts +0 -7
  381. package/dist/middleware/__fixtures__/middleware/sequence.js +0 -21
  382. package/dist/middleware/__fixtures__/middleware/sequence.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tracing/renderer_trace_batch_transport.ts"],"sourcesContent":["import {\n BoundedMetadataSnapshotter,\n DEFAULT_METADATA_SNAPSHOT_LIMITS,\n type TelemetryJsonObject,\n type TelemetryJsonValue,\n} from '@noego/telemetry/core';\nimport { WoodTraceBatchContract } from './wood_trace_batch_contract.js';\nimport type {\n WoodRendererTraceEvent,\n WoodRendererTraceInput,\n WoodTraceBatch,\n WoodTraceBatchAdmissionResult,\n WoodTraceBatchPort,\n WoodTraceBatchTransportOptions,\n WoodTraceBatchTransportStatus,\n} from './types/wood_trace_batch.types.js';\n\ntype QueuedTraceEvent = Readonly<{\n sequence: number;\n event: WoodRendererTraceEvent;\n}>;\n\ntype InFlightTraceBatch = {\n batch: WoodTraceBatch;\n attempts: number;\n awaitingAcknowledgement: boolean;\n retryReady: boolean;\n retryGeneration: number;\n};\n\nexport class RendererTraceBatchTransport {\n private readonly contract = new WoodTraceBatchContract();\n private readonly metadataSnapshotter: BoundedMetadataSnapshotter;\n private readonly queue: QueuedTraceEvent[] = [];\n private state: 'accepting' | 'draining' | 'stopped' = 'accepting';\n private port: WoodTraceBatchPort | null = null;\n private unsubscribePort: (() => void) | null = null;\n private inFlight: InFlightTraceBatch | null = null;\n private nextSequence = 0;\n private drainScheduled = false;\n private droppedCapacity = 0;\n private droppedClosed = 0;\n private droppedRejected = 0;\n private droppedRetryExhausted = 0;\n private committedBatches = 0;\n private retryAttempts = 0;\n private metadataTruncatedValues = 0;\n private metadataRedactedValues = 0;\n private metadataSerializationFailures = 0;\n\n constructor(private readonly options: WoodTraceBatchTransportOptions) {\n this.validateOptions();\n this.metadataSnapshotter = new BoundedMetadataSnapshotter(\n options.metadataSnapshotLimits ?? DEFAULT_METADATA_SNAPSHOT_LIMITS,\n );\n }\n\n admit(event: WoodRendererTraceInput): WoodTraceBatchAdmissionResult {\n const sequence = this.nextSequence;\n this.nextSequence += 1;\n if (this.state !== 'accepting') {\n this.droppedClosed += 1;\n return { kind: 'dropped', sequence, reason: 'closed' };\n }\n\n const retainedEvents = this.queue.length + (this.inFlight?.batch.events.length ?? 0);\n if (retainedEvents >= this.options.maxQueuedEvents) {\n this.droppedCapacity += 1;\n return { kind: 'dropped', sequence, reason: 'capacity' };\n }\n\n this.queue.push(Object.freeze({ sequence, event: this.snapshotEvent(event, sequence) }));\n this.scheduleDrain();\n return { kind: 'admitted', sequence };\n }\n\n attachPort(port: WoodTraceBatchPort): void {\n this.detachPort();\n this.port = port;\n this.unsubscribePort = port.subscribe((message) => this.handleAcknowledgement(message));\n if (this.inFlight) {\n this.inFlight.awaitingAcknowledgement = false;\n this.inFlight.retryReady = true;\n this.inFlight.retryGeneration += 1;\n }\n this.scheduleDrain();\n }\n\n status(): WoodTraceBatchTransportStatus {\n return Object.freeze({\n state: this.state,\n producerId: this.options.producerId,\n nextSequence: this.nextSequence,\n queuedEvents: this.queue.length,\n inFlightBatchId: this.inFlight?.batch.batchId ?? null,\n droppedCapacity: this.droppedCapacity,\n droppedClosed: this.droppedClosed,\n droppedRejected: this.droppedRejected,\n droppedRetryExhausted: this.droppedRetryExhausted,\n metadataTruncatedValues: this.metadataTruncatedValues,\n metadataRedactedValues: this.metadataRedactedValues,\n metadataSerializationFailures: this.metadataSerializationFailures,\n committedBatches: this.committedBatches,\n retryAttempts: this.retryAttempts,\n });\n }\n\n async flush(deadlineMs: number): Promise<void> {\n this.scheduleDrain();\n while (this.hasPendingEvents() && this.options.now() < deadlineMs) {\n await this.options.delay(1);\n this.scheduleDrain();\n }\n }\n\n async close(deadlineMs: number): Promise<void> {\n if (this.state === 'stopped') {\n return;\n }\n this.state = 'draining';\n await this.flush(deadlineMs);\n const abandonedEvents = this.queue.length + (this.inFlight?.batch.events.length ?? 0);\n this.droppedClosed += abandonedEvents;\n this.queue.length = 0;\n this.inFlight = null;\n this.detachPort();\n this.state = 'stopped';\n }\n\n private abandonRetryExhausted(): void {\n if (!this.inFlight) {\n return;\n }\n this.droppedRetryExhausted += this.inFlight.batch.events.length;\n this.inFlight = null;\n this.scheduleDrain();\n }\n\n private createInFlightBatch(): void {\n if (this.inFlight || this.queue.length === 0 || !this.port) {\n return;\n }\n const entries = this.queue.splice(0, this.options.maxBatchEvents);\n const first = entries[0];\n if (!first) {\n return;\n }\n this.inFlight = {\n batch: this.contract.create(\n this.options.producerId,\n first.sequence,\n entries.map((entry) => entry.event),\n ),\n attempts: 0,\n awaitingAcknowledgement: false,\n retryReady: true,\n retryGeneration: 0,\n };\n }\n\n private detachPort(): void {\n this.unsubscribePort?.();\n this.unsubscribePort = null;\n this.port?.close();\n this.port = null;\n }\n\n private drain(): void {\n this.createInFlightBatch();\n this.sendInFlightBatch();\n }\n\n private handleAcknowledgement(message: unknown): void {\n const parsed = this.contract.parseAcknowledgement(message);\n if (!parsed.ok || !this.inFlight) {\n return;\n }\n const acknowledgement = parsed.acknowledgement;\n if (acknowledgement.batchId !== this.inFlight.batch.batchId) {\n return;\n }\n\n this.inFlight.retryGeneration += 1;\n this.inFlight.awaitingAcknowledgement = false;\n if (acknowledgement.kind === 'committed') {\n if (acknowledgement.acceptedEvents !== this.inFlight.batch.events.length) {\n this.scheduleRetry(0);\n return;\n }\n this.committedBatches += 1;\n this.inFlight = null;\n this.scheduleDrain();\n return;\n }\n if (acknowledgement.kind === 'rejected') {\n this.droppedRejected += this.inFlight.batch.events.length;\n this.inFlight = null;\n this.scheduleDrain();\n return;\n }\n this.scheduleRetry(acknowledgement.retryAfterMs);\n }\n\n private handleAcknowledgementTimeout(batchId: string, attempt: number): void {\n if (!this.inFlight\n || this.inFlight.batch.batchId !== batchId\n || this.inFlight.attempts !== attempt\n || !this.inFlight.awaitingAcknowledgement) {\n return;\n }\n this.inFlight.awaitingAcknowledgement = false;\n this.scheduleRetry(this.retryDelay(attempt));\n }\n\n private hasPendingEvents(): boolean {\n return this.queue.length > 0 || this.inFlight !== null;\n }\n\n private retryDelay(attempt: number): number {\n return this.options.retryBaseDelayMs * (2 ** Math.max(0, attempt - 1));\n }\n\n private scheduleDrain(): void {\n if (this.drainScheduled) {\n return;\n }\n this.drainScheduled = true;\n this.options.schedule(() => {\n this.drainScheduled = false;\n this.drain();\n });\n }\n\n private scheduleRetry(requestedDelayMs: number): void {\n if (!this.inFlight) {\n return;\n }\n if (this.inFlight.attempts > this.options.retryLimit) {\n this.abandonRetryExhausted();\n return;\n }\n\n this.inFlight.retryReady = false;\n const generation = this.inFlight.retryGeneration + 1;\n this.inFlight.retryGeneration = generation;\n const delayMs = Math.max(requestedDelayMs, this.retryDelay(this.inFlight.attempts));\n void this.options.delay(delayMs).then(() => {\n if (!this.inFlight || this.inFlight.retryGeneration !== generation) {\n return;\n }\n this.inFlight.retryReady = true;\n this.scheduleDrain();\n });\n }\n\n private sendInFlightBatch(): void {\n const current = this.inFlight;\n const port = this.port;\n if (!current || !port || current.awaitingAcknowledgement || !current.retryReady) {\n return;\n }\n if (current.attempts > this.options.retryLimit) {\n this.abandonRetryExhausted();\n return;\n }\n\n current.attempts += 1;\n if (current.attempts > 1) {\n this.retryAttempts += 1;\n }\n current.awaitingAcknowledgement = true;\n current.retryReady = false;\n const attempt = current.attempts;\n try {\n port.postMessage(current.batch);\n } catch {\n current.awaitingAcknowledgement = false;\n this.detachPort();\n return;\n }\n\n void this.options.delay(this.options.acknowledgementTimeoutMs).then(() => {\n this.handleAcknowledgementTimeout(current.batch.batchId, attempt);\n });\n }\n\n private snapshotEvent(\n event: WoodRendererTraceInput,\n sequence: number,\n ): WoodRendererTraceEvent {\n const snapshot = this.metadataSnapshotter.snapshot(event);\n this.metadataTruncatedValues += snapshot.stats.truncatedValues;\n this.metadataRedactedValues += snapshot.stats.redactedValues;\n this.metadataSerializationFailures += snapshot.stats.serializationFailures;\n const input = snapshot.metadata;\n const occurredAt = new Date(this.options.now());\n const timestamp = Number.isNaN(occurredAt.getTime())\n ? new Date(0).toISOString()\n : occurredAt.toISOString();\n return Object.freeze({\n source: this.snapshotString(input.source, 'unknown'),\n type: this.snapshotString(input.type, 'unknown'),\n level: this.snapshotString(input.level, 'info'),\n process: 'renderer',\n timestamp,\n traceSeq: sequence + 1,\n ...this.snapshotOptionalString('message', input.message),\n ...this.snapshotConversationId(input.conversationId),\n ...this.snapshotPayload(input.payload),\n ...this.snapshotOptionalString('windowId', input.windowId),\n ...this.snapshotOptionalNumber('webContentsId', input.webContentsId),\n ...this.snapshotOptionalString('routeKey', input.routeKey),\n ...this.snapshotOptionalString('harnessId', input.harnessId),\n });\n }\n\n private snapshotConversationId(\n value: TelemetryJsonValue | undefined,\n ): Pick<WoodRendererTraceEvent, 'conversationId'> | Record<string, never> {\n return typeof value === 'string' || typeof value === 'number'\n ? { conversationId: value }\n : {};\n }\n\n private snapshotOptionalNumber<Key extends 'webContentsId'>(\n key: Key,\n value: TelemetryJsonValue | undefined,\n ): Partial<Pick<WoodRendererTraceEvent, Key>> {\n return typeof value === 'number' && Number.isFinite(value)\n ? { [key]: value } as Pick<WoodRendererTraceEvent, Key>\n : {};\n }\n\n private snapshotOptionalString<Key extends 'message' | 'windowId' | 'routeKey' | 'harnessId'>(\n key: Key,\n value: TelemetryJsonValue | undefined,\n ): Partial<Pick<WoodRendererTraceEvent, Key>> {\n return typeof value === 'string'\n ? { [key]: value } as Pick<WoodRendererTraceEvent, Key>\n : {};\n }\n\n private snapshotPayload(\n value: TelemetryJsonValue | undefined,\n ): Pick<WoodRendererTraceEvent, 'payload'> | Record<string, never> {\n if (value === undefined) {\n return {};\n }\n const payload: TelemetryJsonObject = this.isJsonObject(value)\n ? value\n : Object.freeze({ __telemetry: value });\n return { payload };\n }\n\n private snapshotString(value: TelemetryJsonValue | undefined, fallback: string): string {\n return typeof value === 'string' && value.trim().length > 0 ? value : fallback;\n }\n\n private isJsonObject(value: TelemetryJsonValue): value is TelemetryJsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n }\n\n private validateOptions(): void {\n const validCapacity = Number.isSafeInteger(this.options.maxQueuedEvents)\n && this.options.maxQueuedEvents > 0\n && Number.isSafeInteger(this.options.maxBatchEvents)\n && this.options.maxBatchEvents > 0\n && this.options.maxBatchEvents <= this.options.maxQueuedEvents;\n const validRetry = Number.isSafeInteger(this.options.retryLimit)\n && this.options.retryLimit >= 0\n && Number.isFinite(this.options.retryBaseDelayMs)\n && this.options.retryBaseDelayMs >= 0\n && Number.isFinite(this.options.acknowledgementTimeoutMs)\n && this.options.acknowledgementTimeoutMs > 0;\n if (!this.options.producerId.trim() || !validCapacity || !validRetry) {\n throw new Error('Renderer trace batch transport options are invalid');\n }\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/tracing/renderer_trace_batch_transport.ts"],"sourcesContent":["import {\n BoundedMetadataSnapshotter,\n DEFAULT_METADATA_SNAPSHOT_LIMITS,\n type TelemetryJsonObject,\n type TelemetryJsonValue,\n} from '@noego/telemetry/core';\nimport { WoodTraceBatchContract } from './wood_trace_batch_contract.js';\nimport type {\n WoodRendererTraceEvent,\n WoodRendererTraceInput,\n WoodTraceBatch,\n WoodTraceBatchAdmissionResult,\n WoodTraceBatchPort,\n WoodTraceBatchTransportOptions,\n WoodTraceBatchTransportStatus,\n} from './types/wood_trace_batch.types.js';\n\ntype QueuedTraceEvent = Readonly<{\n sequence: number;\n event: WoodRendererTraceEvent;\n}>;\n\ntype InFlightTraceBatch = {\n batch: WoodTraceBatch;\n attempts: number;\n awaitingAcknowledgement: boolean;\n retryReady: boolean;\n retryGeneration: number;\n};\n\nexport class RendererTraceBatchTransport {\n private readonly contract = new WoodTraceBatchContract();\n private readonly metadataSnapshotter: BoundedMetadataSnapshotter;\n private readonly queue: QueuedTraceEvent[] = [];\n private state: 'accepting' | 'draining' | 'stopped' = 'accepting';\n private port: WoodTraceBatchPort | null = null;\n private unsubscribePort: (() => void) | null = null;\n private inFlight: InFlightTraceBatch | null = null;\n private nextSequence = 0;\n private drainScheduled = false;\n private droppedCapacity = 0;\n private droppedClosed = 0;\n private droppedRejected = 0;\n private droppedRetryExhausted = 0;\n private identityRestamped = 0;\n private committedBatches = 0;\n private retryAttempts = 0;\n private metadataTruncatedValues = 0;\n private metadataRedactedValues = 0;\n private metadataSerializationFailures = 0;\n\n constructor(private readonly options: WoodTraceBatchTransportOptions) {\n this.validateOptions();\n this.metadataSnapshotter = new BoundedMetadataSnapshotter(\n options.metadataSnapshotLimits ?? DEFAULT_METADATA_SNAPSHOT_LIMITS,\n );\n }\n\n admit(event: WoodRendererTraceInput): WoodTraceBatchAdmissionResult {\n const identity = this.resolveIdentity(event);\n const sequence = identity.sequence;\n if (this.state !== 'accepting') {\n this.droppedClosed += 1;\n return { kind: 'dropped', sequence, reason: 'closed' };\n }\n\n const retainedEvents = this.queue.length + (this.inFlight?.batch.events.length ?? 0);\n if (retainedEvents >= this.options.maxQueuedEvents) {\n this.droppedCapacity += 1;\n return { kind: 'dropped', sequence, reason: 'capacity' };\n }\n\n this.queue.push(Object.freeze({ sequence, event: this.snapshotEvent(event, sequence, identity) }));\n this.scheduleDrain();\n return { kind: 'admitted', sequence };\n }\n\n /**\n * Resolves the queue sequence and preserved identity for an incoming event,\n * reading identity fields from the raw input BEFORE metadata snapshotting so\n * truncation/redaction can never alter identity.\n *\n * A hub-admitted event (valid timestamp + traceSeq) keeps its identity and\n * its queue sequence is derived as traceSeq - 1 so the batch sequence range\n * stays aligned with hub identity. A stamped event whose traceSeq regresses\n * against the already-assigned sequence stream is restamped as legacy (its\n * occurrence timestamp is still preserved, its producerId is dropped so a\n * reassigned sequence cannot masquerade under the durable identity key) and\n * counted in identityRestamped. Legacy events without identity are stamped\n * exactly as before.\n */\n private resolveIdentity(event: WoodRendererTraceInput): {\n sequence: number;\n timestamp?: string;\n producerId?: string;\n } {\n const rawTimestamp = typeof event.timestamp === 'string'\n && Number.isFinite(Date.parse(event.timestamp))\n ? event.timestamp\n : undefined;\n const rawSeq = typeof event.traceSeq === 'number'\n && Number.isSafeInteger(event.traceSeq)\n && event.traceSeq >= 1\n ? event.traceSeq\n : undefined;\n const producerId = typeof event.producerId === 'string' && event.producerId.trim().length > 0\n ? event.producerId\n : undefined;\n\n if (rawTimestamp !== undefined && rawSeq !== undefined && rawSeq - 1 >= this.nextSequence) {\n this.nextSequence = rawSeq;\n return {\n sequence: rawSeq - 1,\n timestamp: rawTimestamp,\n ...(producerId !== undefined ? { producerId } : {}),\n };\n }\n\n if (rawTimestamp !== undefined && rawSeq !== undefined) {\n // Stamped but non-monotonic against this transport's sequence stream:\n // protocol survival wins, durable sequence identity is sacrificed loudly.\n this.identityRestamped += 1;\n }\n\n const sequence = this.nextSequence;\n this.nextSequence += 1;\n return {\n sequence,\n ...(rawTimestamp !== undefined ? { timestamp: rawTimestamp } : {}),\n };\n }\n\n attachPort(port: WoodTraceBatchPort): void {\n this.detachPort();\n this.port = port;\n this.unsubscribePort = port.subscribe((message) => this.handleAcknowledgement(message));\n if (this.inFlight) {\n this.inFlight.awaitingAcknowledgement = false;\n this.inFlight.retryReady = true;\n this.inFlight.retryGeneration += 1;\n }\n this.scheduleDrain();\n }\n\n status(): WoodTraceBatchTransportStatus {\n return Object.freeze({\n state: this.state,\n producerId: this.options.producerId,\n nextSequence: this.nextSequence,\n queuedEvents: this.queue.length,\n inFlightBatchId: this.inFlight?.batch.batchId ?? null,\n droppedCapacity: this.droppedCapacity,\n droppedClosed: this.droppedClosed,\n droppedRejected: this.droppedRejected,\n droppedRetryExhausted: this.droppedRetryExhausted,\n identityRestamped: this.identityRestamped,\n metadataTruncatedValues: this.metadataTruncatedValues,\n metadataRedactedValues: this.metadataRedactedValues,\n metadataSerializationFailures: this.metadataSerializationFailures,\n committedBatches: this.committedBatches,\n retryAttempts: this.retryAttempts,\n });\n }\n\n async flush(deadlineMs: number): Promise<void> {\n this.scheduleDrain();\n while (this.hasPendingEvents() && this.options.now() < deadlineMs) {\n await this.options.delay(1);\n this.scheduleDrain();\n }\n }\n\n async close(deadlineMs: number): Promise<void> {\n if (this.state === 'stopped') {\n return;\n }\n this.state = 'draining';\n await this.flush(deadlineMs);\n const abandonedEvents = this.queue.length + (this.inFlight?.batch.events.length ?? 0);\n this.droppedClosed += abandonedEvents;\n this.queue.length = 0;\n this.inFlight = null;\n this.detachPort();\n this.state = 'stopped';\n }\n\n private abandonRetryExhausted(): void {\n if (!this.inFlight) {\n return;\n }\n this.droppedRetryExhausted += this.inFlight.batch.events.length;\n this.inFlight = null;\n this.scheduleDrain();\n }\n\n private createInFlightBatch(): void {\n if (this.inFlight || this.queue.length === 0 || !this.port) {\n return;\n }\n const entries = this.queue.splice(0, this.options.maxBatchEvents);\n const first = entries[0];\n if (!first) {\n return;\n }\n this.inFlight = {\n batch: this.contract.create(\n this.options.producerId,\n first.sequence,\n entries.map((entry) => entry.event),\n ),\n attempts: 0,\n awaitingAcknowledgement: false,\n retryReady: true,\n retryGeneration: 0,\n };\n }\n\n private detachPort(): void {\n this.unsubscribePort?.();\n this.unsubscribePort = null;\n this.port?.close();\n this.port = null;\n }\n\n private drain(): void {\n this.createInFlightBatch();\n this.sendInFlightBatch();\n }\n\n private handleAcknowledgement(message: unknown): void {\n const parsed = this.contract.parseAcknowledgement(message);\n if (!parsed.ok || !this.inFlight) {\n return;\n }\n const acknowledgement = parsed.acknowledgement;\n if (acknowledgement.batchId !== this.inFlight.batch.batchId) {\n return;\n }\n\n this.inFlight.retryGeneration += 1;\n this.inFlight.awaitingAcknowledgement = false;\n if (acknowledgement.kind === 'committed') {\n if (acknowledgement.acceptedEvents !== this.inFlight.batch.events.length) {\n this.scheduleRetry(0);\n return;\n }\n this.committedBatches += 1;\n this.inFlight = null;\n this.scheduleDrain();\n return;\n }\n if (acknowledgement.kind === 'rejected') {\n this.droppedRejected += this.inFlight.batch.events.length;\n this.inFlight = null;\n this.scheduleDrain();\n return;\n }\n this.scheduleRetry(acknowledgement.retryAfterMs);\n }\n\n private handleAcknowledgementTimeout(batchId: string, attempt: number): void {\n if (!this.inFlight\n || this.inFlight.batch.batchId !== batchId\n || this.inFlight.attempts !== attempt\n || !this.inFlight.awaitingAcknowledgement) {\n return;\n }\n this.inFlight.awaitingAcknowledgement = false;\n this.scheduleRetry(this.retryDelay(attempt));\n }\n\n private hasPendingEvents(): boolean {\n return this.queue.length > 0 || this.inFlight !== null;\n }\n\n private retryDelay(attempt: number): number {\n return this.options.retryBaseDelayMs * (2 ** Math.max(0, attempt - 1));\n }\n\n private scheduleDrain(): void {\n if (this.drainScheduled) {\n return;\n }\n this.drainScheduled = true;\n this.options.schedule(() => {\n this.drainScheduled = false;\n this.drain();\n });\n }\n\n private scheduleRetry(requestedDelayMs: number): void {\n if (!this.inFlight) {\n return;\n }\n if (this.inFlight.attempts > this.options.retryLimit) {\n this.abandonRetryExhausted();\n return;\n }\n\n this.inFlight.retryReady = false;\n const generation = this.inFlight.retryGeneration + 1;\n this.inFlight.retryGeneration = generation;\n const delayMs = Math.max(requestedDelayMs, this.retryDelay(this.inFlight.attempts));\n void this.options.delay(delayMs).then(() => {\n if (!this.inFlight || this.inFlight.retryGeneration !== generation) {\n return;\n }\n this.inFlight.retryReady = true;\n this.scheduleDrain();\n });\n }\n\n private sendInFlightBatch(): void {\n const current = this.inFlight;\n const port = this.port;\n if (!current || !port || current.awaitingAcknowledgement || !current.retryReady) {\n return;\n }\n if (current.attempts > this.options.retryLimit) {\n this.abandonRetryExhausted();\n return;\n }\n\n current.attempts += 1;\n if (current.attempts > 1) {\n this.retryAttempts += 1;\n }\n current.awaitingAcknowledgement = true;\n current.retryReady = false;\n const attempt = current.attempts;\n try {\n port.postMessage(current.batch);\n } catch {\n current.awaitingAcknowledgement = false;\n this.detachPort();\n return;\n }\n\n void this.options.delay(this.options.acknowledgementTimeoutMs).then(() => {\n this.handleAcknowledgementTimeout(current.batch.batchId, attempt);\n });\n }\n\n private snapshotEvent(\n event: WoodRendererTraceInput,\n sequence: number,\n identity: { timestamp?: string; producerId?: string },\n ): WoodRendererTraceEvent {\n const snapshot = this.metadataSnapshotter.snapshot(event);\n this.metadataTruncatedValues += snapshot.stats.truncatedValues;\n this.metadataRedactedValues += snapshot.stats.redactedValues;\n this.metadataSerializationFailures += snapshot.stats.serializationFailures;\n const input = snapshot.metadata;\n // A hub-preserved occurrence timestamp is authoritative; only legacy\n // unstamped events receive a transport-stamped time.\n let timestamp = identity.timestamp;\n if (timestamp === undefined) {\n const occurredAt = new Date(this.options.now());\n timestamp = Number.isNaN(occurredAt.getTime())\n ? new Date(0).toISOString()\n : occurredAt.toISOString();\n }\n return Object.freeze({\n source: this.snapshotString(input.source, 'unknown'),\n type: this.snapshotString(input.type, 'unknown'),\n level: this.snapshotString(input.level, 'info'),\n process: 'renderer',\n timestamp,\n traceSeq: sequence + 1,\n ...(identity.producerId !== undefined ? { producerId: identity.producerId } : {}),\n ...this.snapshotOptionalString('message', input.message),\n ...this.snapshotConversationId(input.conversationId),\n ...this.snapshotPayload(input.payload),\n ...this.snapshotOptionalString('windowId', input.windowId),\n ...this.snapshotOptionalNumber('webContentsId', input.webContentsId),\n ...this.snapshotOptionalString('routeKey', input.routeKey),\n ...this.snapshotOptionalString('harnessId', input.harnessId),\n });\n }\n\n private snapshotConversationId(\n value: TelemetryJsonValue | undefined,\n ): Pick<WoodRendererTraceEvent, 'conversationId'> | Record<string, never> {\n return typeof value === 'string' || typeof value === 'number'\n ? { conversationId: value }\n : {};\n }\n\n private snapshotOptionalNumber<Key extends 'webContentsId'>(\n key: Key,\n value: TelemetryJsonValue | undefined,\n ): Partial<Pick<WoodRendererTraceEvent, Key>> {\n return typeof value === 'number' && Number.isFinite(value)\n ? { [key]: value } as Pick<WoodRendererTraceEvent, Key>\n : {};\n }\n\n private snapshotOptionalString<Key extends 'message' | 'windowId' | 'routeKey' | 'harnessId'>(\n key: Key,\n value: TelemetryJsonValue | undefined,\n ): Partial<Pick<WoodRendererTraceEvent, Key>> {\n return typeof value === 'string'\n ? { [key]: value } as Pick<WoodRendererTraceEvent, Key>\n : {};\n }\n\n private snapshotPayload(\n value: TelemetryJsonValue | undefined,\n ): Pick<WoodRendererTraceEvent, 'payload'> | Record<string, never> {\n if (value === undefined) {\n return {};\n }\n const payload: TelemetryJsonObject = this.isJsonObject(value)\n ? value\n : Object.freeze({ __telemetry: value });\n return { payload };\n }\n\n private snapshotString(value: TelemetryJsonValue | undefined, fallback: string): string {\n return typeof value === 'string' && value.trim().length > 0 ? value : fallback;\n }\n\n private isJsonObject(value: TelemetryJsonValue): value is TelemetryJsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n }\n\n private validateOptions(): void {\n const validCapacity = Number.isSafeInteger(this.options.maxQueuedEvents)\n && this.options.maxQueuedEvents > 0\n && Number.isSafeInteger(this.options.maxBatchEvents)\n && this.options.maxBatchEvents > 0\n && this.options.maxBatchEvents <= this.options.maxQueuedEvents;\n const validRetry = Number.isSafeInteger(this.options.retryLimit)\n && this.options.retryLimit >= 0\n && Number.isFinite(this.options.retryBaseDelayMs)\n && this.options.retryBaseDelayMs >= 0\n && Number.isFinite(this.options.acknowledgementTimeoutMs)\n && this.options.acknowledgementTimeoutMs > 0;\n if (!this.options.producerId.trim() || !validCapacity || !validRetry) {\n throw new Error('Renderer trace batch transport options are invalid');\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var trace_batch_adapter_exports = {};
20
+ __export(trace_batch_adapter_exports, {
21
+ woodBatchToTraceBatch: () => woodBatchToTraceBatch
22
+ });
23
+ module.exports = __toCommonJS(trace_batch_adapter_exports);
24
+ var import_trace = require("@noego/trace");
25
+ function woodBatchToTraceBatch(batch, context = {}, options = {}) {
26
+ if (batch.events.length === 0) {
27
+ return { ok: false, reason: "Wood trace batch is empty" };
28
+ }
29
+ const producerId = resolveUniformProducerId(batch);
30
+ const records = [];
31
+ let previousSequence = 0;
32
+ for (const event of batch.events) {
33
+ const occurredAtMs = Date.parse(event.timestamp);
34
+ if (!Number.isFinite(occurredAtMs)) {
35
+ return { ok: false, reason: `Wood trace event timestamp is invalid: '${event.timestamp}'` };
36
+ }
37
+ if (!Number.isSafeInteger(event.traceSeq) || event.traceSeq < 1) {
38
+ return { ok: false, reason: `Wood trace event sequence is invalid: ${event.traceSeq}` };
39
+ }
40
+ if (event.traceSeq <= previousSequence) {
41
+ return { ok: false, reason: "Wood trace event sequences are not strictly increasing" };
42
+ }
43
+ previousSequence = event.traceSeq;
44
+ records.push(convertEvent(event, producerId, occurredAtMs, context));
45
+ }
46
+ const first = records[0];
47
+ const last = records[records.length - 1];
48
+ if (!first || !last) {
49
+ return { ok: false, reason: "Wood trace batch is empty" };
50
+ }
51
+ return {
52
+ ok: true,
53
+ batch: Object.freeze({
54
+ schemaVersion: 1,
55
+ batchId: batch.batchId,
56
+ producerId,
57
+ sequenceStart: first.sequence,
58
+ sequenceEnd: last.sequence,
59
+ createdAtMs: options.createdAtMs ?? Date.now(),
60
+ records: Object.freeze(records)
61
+ })
62
+ };
63
+ }
64
+ function resolveUniformProducerId(batch) {
65
+ const first = batch.events[0]?.producerId;
66
+ if (typeof first === "string" && first.trim().length > 0) {
67
+ const uniform = batch.events.every((event) => event.producerId === first);
68
+ if (uniform) {
69
+ return first;
70
+ }
71
+ }
72
+ return `wood:${batch.producerId}`;
73
+ }
74
+ function convertEvent(event, producerId, occurredAtMs, context) {
75
+ const extras = {
76
+ ...event.payload ?? {}
77
+ };
78
+ const merged = { ...pickRuntimeContext(event), ...context };
79
+ if (merged.windowId !== void 0) extras.windowId = merged.windowId;
80
+ if (merged.webContentsId !== void 0) extras.webContentsId = merged.webContentsId;
81
+ if (merged.routeKey !== void 0) extras.routeKey = merged.routeKey;
82
+ if (merged.harnessId !== void 0) extras.harnessId = merged.harnessId;
83
+ return Object.freeze({
84
+ id: `${producerId}:${event.traceSeq}`,
85
+ occurredAtMs,
86
+ timestamp: occurredAtMs,
87
+ producerId,
88
+ sequence: event.traceSeq,
89
+ source: event.source,
90
+ event: event.type,
91
+ level: (0, import_trace.parseTraceLevel)(event.level),
92
+ process: event.process,
93
+ ...event.conversationId !== void 0 ? { conversationId: event.conversationId } : {},
94
+ ...typeof event.message === "string" ? { message: event.message } : {},
95
+ ...Object.keys(extras).length > 0 ? { context: Object.freeze(extras) } : {}
96
+ });
97
+ }
98
+ function pickRuntimeContext(event) {
99
+ return {
100
+ ...event.windowId !== void 0 ? { windowId: event.windowId } : {},
101
+ ...event.webContentsId !== void 0 ? { webContentsId: event.webContentsId } : {},
102
+ ...event.routeKey !== void 0 ? { routeKey: event.routeKey } : {},
103
+ ...event.harnessId !== void 0 ? { harnessId: event.harnessId } : {}
104
+ };
105
+ }
106
+ // Annotate the CommonJS export names for ESM import in node:
107
+ 0 && (module.exports = {
108
+ woodBatchToTraceBatch
109
+ });
110
+ //# sourceMappingURL=trace_batch_adapter.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/tracing/trace_batch_adapter.ts"],"sourcesContent":["import type { AdmittedTraceEvent, TraceBatch } from '@noego/trace';\nimport { parseTraceLevel } from '@noego/trace';\nimport type {\n WoodRendererTraceEvent,\n WoodTraceBatch,\n WoodTraceBatchRuntimeContext,\n} from './types/wood_trace_batch.types.js';\n\nexport type WoodTraceBatchConversion =\n | { ok: true; batch: TraceBatch }\n | { ok: false; reason: string };\n\n/**\n * Converts a validated Wood renderer trace batch into the @noego/trace\n * TraceBatch contract for the SQLite batch receiver.\n *\n * Identity is preserved, never regenerated:\n * - occurredAtMs = the event's producer-assigned ISO timestamp, parsed;\n * - sequence = the event's hub traceSeq (Wood batch ranges are queue\n * sequences, i.e. traceSeq - 1, so the converted range shifts by +1);\n * - producerId = the hub producerId when every event carries the same one,\n * else a 'wood:<preload-session>' fallback uniformly for the whole batch\n * (the TraceBatch contract requires one producer per batch);\n * - id = '<producerId>:<sequence>' — deterministic, stable across retries;\n * - batchId is reused verbatim so receiver-side duplicate detection keys on\n * the same delivery identity the renderer retries with.\n *\n * Runtime context (windowId/webContentsId/routeKey/harnessId) merges into the\n * event context without touching identity fields.\n */\nexport function woodBatchToTraceBatch(\n batch: WoodTraceBatch,\n context: WoodTraceBatchRuntimeContext = {},\n options: { createdAtMs?: number } = {},\n): WoodTraceBatchConversion {\n if (batch.events.length === 0) {\n return { ok: false, reason: 'Wood trace batch is empty' };\n }\n\n const producerId = resolveUniformProducerId(batch);\n\n const records: AdmittedTraceEvent[] = [];\n let previousSequence = 0;\n for (const event of batch.events) {\n const occurredAtMs = Date.parse(event.timestamp);\n if (!Number.isFinite(occurredAtMs)) {\n return { ok: false, reason: `Wood trace event timestamp is invalid: '${event.timestamp}'` };\n }\n if (!Number.isSafeInteger(event.traceSeq) || event.traceSeq < 1) {\n return { ok: false, reason: `Wood trace event sequence is invalid: ${event.traceSeq}` };\n }\n if (event.traceSeq <= previousSequence) {\n return { ok: false, reason: 'Wood trace event sequences are not strictly increasing' };\n }\n previousSequence = event.traceSeq;\n records.push(convertEvent(event, producerId, occurredAtMs, context));\n }\n\n const first = records[0];\n const last = records[records.length - 1];\n if (!first || !last) {\n return { ok: false, reason: 'Wood trace batch is empty' };\n }\n\n return {\n ok: true,\n batch: Object.freeze({\n schemaVersion: 1,\n batchId: batch.batchId,\n producerId,\n sequenceStart: first.sequence,\n sequenceEnd: last.sequence,\n createdAtMs: options.createdAtMs ?? Date.now(),\n records: Object.freeze(records),\n }),\n };\n}\n\nfunction resolveUniformProducerId(batch: WoodTraceBatch): string {\n const first = batch.events[0]?.producerId;\n if (typeof first === 'string' && first.trim().length > 0) {\n const uniform = batch.events.every((event) => event.producerId === first);\n if (uniform) {\n return first;\n }\n }\n return `wood:${batch.producerId}`;\n}\n\nfunction convertEvent(\n event: WoodRendererTraceEvent,\n producerId: string,\n occurredAtMs: number,\n context: WoodTraceBatchRuntimeContext,\n): AdmittedTraceEvent {\n const extras: Record<string, unknown> = {\n ...(event.payload ?? {}),\n };\n const merged: WoodTraceBatchRuntimeContext = { ...pickRuntimeContext(event), ...context };\n if (merged.windowId !== undefined) extras.windowId = merged.windowId;\n if (merged.webContentsId !== undefined) extras.webContentsId = merged.webContentsId;\n if (merged.routeKey !== undefined) extras.routeKey = merged.routeKey;\n if (merged.harnessId !== undefined) extras.harnessId = merged.harnessId;\n\n return Object.freeze({\n id: `${producerId}:${event.traceSeq}`,\n occurredAtMs,\n timestamp: occurredAtMs,\n producerId,\n sequence: event.traceSeq,\n source: event.source,\n event: event.type,\n level: parseTraceLevel(event.level),\n process: event.process,\n ...(event.conversationId !== undefined ? { conversationId: event.conversationId } : {}),\n ...(typeof event.message === 'string' ? { message: event.message } : {}),\n ...(Object.keys(extras).length > 0 ? { context: Object.freeze(extras) } : {}),\n }) as AdmittedTraceEvent;\n}\n\nfunction pickRuntimeContext(event: WoodRendererTraceEvent): WoodTraceBatchRuntimeContext {\n return {\n ...(event.windowId !== undefined ? { windowId: event.windowId } : {}),\n ...(event.webContentsId !== undefined ? { webContentsId: event.webContentsId } : {}),\n ...(event.routeKey !== undefined ? { routeKey: event.routeKey } : {}),\n ...(event.harnessId !== undefined ? { harnessId: event.harnessId } : {}),\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,36 @@
1
+ import { TraceBatch } from '@noego/trace';
2
+ import { WoodTraceBatch, WoodTraceBatchRuntimeContext } from './types/wood_trace_batch.types.cjs';
3
+ import '@noego/telemetry/core';
4
+ import '../trace_hub-Cpo_nVze.cjs';
5
+ import 'rxjs';
6
+
7
+ type WoodTraceBatchConversion = {
8
+ ok: true;
9
+ batch: TraceBatch;
10
+ } | {
11
+ ok: false;
12
+ reason: string;
13
+ };
14
+ /**
15
+ * Converts a validated Wood renderer trace batch into the @noego/trace
16
+ * TraceBatch contract for the SQLite batch receiver.
17
+ *
18
+ * Identity is preserved, never regenerated:
19
+ * - occurredAtMs = the event's producer-assigned ISO timestamp, parsed;
20
+ * - sequence = the event's hub traceSeq (Wood batch ranges are queue
21
+ * sequences, i.e. traceSeq - 1, so the converted range shifts by +1);
22
+ * - producerId = the hub producerId when every event carries the same one,
23
+ * else a 'wood:<preload-session>' fallback uniformly for the whole batch
24
+ * (the TraceBatch contract requires one producer per batch);
25
+ * - id = '<producerId>:<sequence>' — deterministic, stable across retries;
26
+ * - batchId is reused verbatim so receiver-side duplicate detection keys on
27
+ * the same delivery identity the renderer retries with.
28
+ *
29
+ * Runtime context (windowId/webContentsId/routeKey/harnessId) merges into the
30
+ * event context without touching identity fields.
31
+ */
32
+ declare function woodBatchToTraceBatch(batch: WoodTraceBatch, context?: WoodTraceBatchRuntimeContext, options?: {
33
+ createdAtMs?: number;
34
+ }): WoodTraceBatchConversion;
35
+
36
+ export { type WoodTraceBatchConversion, woodBatchToTraceBatch };
@@ -0,0 +1,36 @@
1
+ import { TraceBatch } from '@noego/trace';
2
+ import { WoodTraceBatch, WoodTraceBatchRuntimeContext } from './types/wood_trace_batch.types.js';
3
+ import '@noego/telemetry/core';
4
+ import '../trace_hub-Cpo_nVze.js';
5
+ import 'rxjs';
6
+
7
+ type WoodTraceBatchConversion = {
8
+ ok: true;
9
+ batch: TraceBatch;
10
+ } | {
11
+ ok: false;
12
+ reason: string;
13
+ };
14
+ /**
15
+ * Converts a validated Wood renderer trace batch into the @noego/trace
16
+ * TraceBatch contract for the SQLite batch receiver.
17
+ *
18
+ * Identity is preserved, never regenerated:
19
+ * - occurredAtMs = the event's producer-assigned ISO timestamp, parsed;
20
+ * - sequence = the event's hub traceSeq (Wood batch ranges are queue
21
+ * sequences, i.e. traceSeq - 1, so the converted range shifts by +1);
22
+ * - producerId = the hub producerId when every event carries the same one,
23
+ * else a 'wood:<preload-session>' fallback uniformly for the whole batch
24
+ * (the TraceBatch contract requires one producer per batch);
25
+ * - id = '<producerId>:<sequence>' — deterministic, stable across retries;
26
+ * - batchId is reused verbatim so receiver-side duplicate detection keys on
27
+ * the same delivery identity the renderer retries with.
28
+ *
29
+ * Runtime context (windowId/webContentsId/routeKey/harnessId) merges into the
30
+ * event context without touching identity fields.
31
+ */
32
+ declare function woodBatchToTraceBatch(batch: WoodTraceBatch, context?: WoodTraceBatchRuntimeContext, options?: {
33
+ createdAtMs?: number;
34
+ }): WoodTraceBatchConversion;
35
+
36
+ export { type WoodTraceBatchConversion, woodBatchToTraceBatch };
@@ -0,0 +1,86 @@
1
+ import { parseTraceLevel } from "@noego/trace";
2
+ function woodBatchToTraceBatch(batch, context = {}, options = {}) {
3
+ if (batch.events.length === 0) {
4
+ return { ok: false, reason: "Wood trace batch is empty" };
5
+ }
6
+ const producerId = resolveUniformProducerId(batch);
7
+ const records = [];
8
+ let previousSequence = 0;
9
+ for (const event of batch.events) {
10
+ const occurredAtMs = Date.parse(event.timestamp);
11
+ if (!Number.isFinite(occurredAtMs)) {
12
+ return { ok: false, reason: `Wood trace event timestamp is invalid: '${event.timestamp}'` };
13
+ }
14
+ if (!Number.isSafeInteger(event.traceSeq) || event.traceSeq < 1) {
15
+ return { ok: false, reason: `Wood trace event sequence is invalid: ${event.traceSeq}` };
16
+ }
17
+ if (event.traceSeq <= previousSequence) {
18
+ return { ok: false, reason: "Wood trace event sequences are not strictly increasing" };
19
+ }
20
+ previousSequence = event.traceSeq;
21
+ records.push(convertEvent(event, producerId, occurredAtMs, context));
22
+ }
23
+ const first = records[0];
24
+ const last = records[records.length - 1];
25
+ if (!first || !last) {
26
+ return { ok: false, reason: "Wood trace batch is empty" };
27
+ }
28
+ return {
29
+ ok: true,
30
+ batch: Object.freeze({
31
+ schemaVersion: 1,
32
+ batchId: batch.batchId,
33
+ producerId,
34
+ sequenceStart: first.sequence,
35
+ sequenceEnd: last.sequence,
36
+ createdAtMs: options.createdAtMs ?? Date.now(),
37
+ records: Object.freeze(records)
38
+ })
39
+ };
40
+ }
41
+ function resolveUniformProducerId(batch) {
42
+ const first = batch.events[0]?.producerId;
43
+ if (typeof first === "string" && first.trim().length > 0) {
44
+ const uniform = batch.events.every((event) => event.producerId === first);
45
+ if (uniform) {
46
+ return first;
47
+ }
48
+ }
49
+ return `wood:${batch.producerId}`;
50
+ }
51
+ function convertEvent(event, producerId, occurredAtMs, context) {
52
+ const extras = {
53
+ ...event.payload ?? {}
54
+ };
55
+ const merged = { ...pickRuntimeContext(event), ...context };
56
+ if (merged.windowId !== void 0) extras.windowId = merged.windowId;
57
+ if (merged.webContentsId !== void 0) extras.webContentsId = merged.webContentsId;
58
+ if (merged.routeKey !== void 0) extras.routeKey = merged.routeKey;
59
+ if (merged.harnessId !== void 0) extras.harnessId = merged.harnessId;
60
+ return Object.freeze({
61
+ id: `${producerId}:${event.traceSeq}`,
62
+ occurredAtMs,
63
+ timestamp: occurredAtMs,
64
+ producerId,
65
+ sequence: event.traceSeq,
66
+ source: event.source,
67
+ event: event.type,
68
+ level: parseTraceLevel(event.level),
69
+ process: event.process,
70
+ ...event.conversationId !== void 0 ? { conversationId: event.conversationId } : {},
71
+ ...typeof event.message === "string" ? { message: event.message } : {},
72
+ ...Object.keys(extras).length > 0 ? { context: Object.freeze(extras) } : {}
73
+ });
74
+ }
75
+ function pickRuntimeContext(event) {
76
+ return {
77
+ ...event.windowId !== void 0 ? { windowId: event.windowId } : {},
78
+ ...event.webContentsId !== void 0 ? { webContentsId: event.webContentsId } : {},
79
+ ...event.routeKey !== void 0 ? { routeKey: event.routeKey } : {},
80
+ ...event.harnessId !== void 0 ? { harnessId: event.harnessId } : {}
81
+ };
82
+ }
83
+ export {
84
+ woodBatchToTraceBatch
85
+ };
86
+ //# sourceMappingURL=trace_batch_adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/tracing/trace_batch_adapter.ts"],"sourcesContent":["import type { AdmittedTraceEvent, TraceBatch } from '@noego/trace';\nimport { parseTraceLevel } from '@noego/trace';\nimport type {\n WoodRendererTraceEvent,\n WoodTraceBatch,\n WoodTraceBatchRuntimeContext,\n} from './types/wood_trace_batch.types.js';\n\nexport type WoodTraceBatchConversion =\n | { ok: true; batch: TraceBatch }\n | { ok: false; reason: string };\n\n/**\n * Converts a validated Wood renderer trace batch into the @noego/trace\n * TraceBatch contract for the SQLite batch receiver.\n *\n * Identity is preserved, never regenerated:\n * - occurredAtMs = the event's producer-assigned ISO timestamp, parsed;\n * - sequence = the event's hub traceSeq (Wood batch ranges are queue\n * sequences, i.e. traceSeq - 1, so the converted range shifts by +1);\n * - producerId = the hub producerId when every event carries the same one,\n * else a 'wood:<preload-session>' fallback uniformly for the whole batch\n * (the TraceBatch contract requires one producer per batch);\n * - id = '<producerId>:<sequence>' — deterministic, stable across retries;\n * - batchId is reused verbatim so receiver-side duplicate detection keys on\n * the same delivery identity the renderer retries with.\n *\n * Runtime context (windowId/webContentsId/routeKey/harnessId) merges into the\n * event context without touching identity fields.\n */\nexport function woodBatchToTraceBatch(\n batch: WoodTraceBatch,\n context: WoodTraceBatchRuntimeContext = {},\n options: { createdAtMs?: number } = {},\n): WoodTraceBatchConversion {\n if (batch.events.length === 0) {\n return { ok: false, reason: 'Wood trace batch is empty' };\n }\n\n const producerId = resolveUniformProducerId(batch);\n\n const records: AdmittedTraceEvent[] = [];\n let previousSequence = 0;\n for (const event of batch.events) {\n const occurredAtMs = Date.parse(event.timestamp);\n if (!Number.isFinite(occurredAtMs)) {\n return { ok: false, reason: `Wood trace event timestamp is invalid: '${event.timestamp}'` };\n }\n if (!Number.isSafeInteger(event.traceSeq) || event.traceSeq < 1) {\n return { ok: false, reason: `Wood trace event sequence is invalid: ${event.traceSeq}` };\n }\n if (event.traceSeq <= previousSequence) {\n return { ok: false, reason: 'Wood trace event sequences are not strictly increasing' };\n }\n previousSequence = event.traceSeq;\n records.push(convertEvent(event, producerId, occurredAtMs, context));\n }\n\n const first = records[0];\n const last = records[records.length - 1];\n if (!first || !last) {\n return { ok: false, reason: 'Wood trace batch is empty' };\n }\n\n return {\n ok: true,\n batch: Object.freeze({\n schemaVersion: 1,\n batchId: batch.batchId,\n producerId,\n sequenceStart: first.sequence,\n sequenceEnd: last.sequence,\n createdAtMs: options.createdAtMs ?? Date.now(),\n records: Object.freeze(records),\n }),\n };\n}\n\nfunction resolveUniformProducerId(batch: WoodTraceBatch): string {\n const first = batch.events[0]?.producerId;\n if (typeof first === 'string' && first.trim().length > 0) {\n const uniform = batch.events.every((event) => event.producerId === first);\n if (uniform) {\n return first;\n }\n }\n return `wood:${batch.producerId}`;\n}\n\nfunction convertEvent(\n event: WoodRendererTraceEvent,\n producerId: string,\n occurredAtMs: number,\n context: WoodTraceBatchRuntimeContext,\n): AdmittedTraceEvent {\n const extras: Record<string, unknown> = {\n ...(event.payload ?? {}),\n };\n const merged: WoodTraceBatchRuntimeContext = { ...pickRuntimeContext(event), ...context };\n if (merged.windowId !== undefined) extras.windowId = merged.windowId;\n if (merged.webContentsId !== undefined) extras.webContentsId = merged.webContentsId;\n if (merged.routeKey !== undefined) extras.routeKey = merged.routeKey;\n if (merged.harnessId !== undefined) extras.harnessId = merged.harnessId;\n\n return Object.freeze({\n id: `${producerId}:${event.traceSeq}`,\n occurredAtMs,\n timestamp: occurredAtMs,\n producerId,\n sequence: event.traceSeq,\n source: event.source,\n event: event.type,\n level: parseTraceLevel(event.level),\n process: event.process,\n ...(event.conversationId !== undefined ? { conversationId: event.conversationId } : {}),\n ...(typeof event.message === 'string' ? { message: event.message } : {}),\n ...(Object.keys(extras).length > 0 ? { context: Object.freeze(extras) } : {}),\n }) as AdmittedTraceEvent;\n}\n\nfunction pickRuntimeContext(event: WoodRendererTraceEvent): WoodTraceBatchRuntimeContext {\n return {\n ...(event.windowId !== undefined ? { windowId: event.windowId } : {}),\n ...(event.webContentsId !== undefined ? { webContentsId: event.webContentsId } : {}),\n ...(event.routeKey !== undefined ? { routeKey: event.routeKey } : {}),\n ...(event.harnessId !== undefined ? { harnessId: event.harnessId } : {}),\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,4 +1,4 @@
1
- import { d as TraceProcess, c as TraceLevel, g as WoodTraceEventSnapshot } from '../trace_hub-Cob54qRx.cjs';
1
+ import { d as TraceProcess, c as TraceLevel, g as WoodTraceEventSnapshot } from '../trace_hub-Cpo_nVze.cjs';
2
2
  import 'rxjs';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { d as TraceProcess, c as TraceLevel, g as WoodTraceEventSnapshot } from '../trace_hub-Cob54qRx.js';
1
+ import { d as TraceProcess, c as TraceLevel, g as WoodTraceEventSnapshot } from '../trace_hub-Cpo_nVze.js';
2
2
  import 'rxjs';
3
3
 
4
4
  /**
@@ -22,6 +22,8 @@ __export(trace_hub_exports, {
22
22
  dispatchRendererTracePayload: () => dispatchRendererTracePayload,
23
23
  emitRendererTrace: () => emitRendererTrace,
24
24
  getTraceEvents$: () => getTraceEvents$,
25
+ getTraceProducerId: () => getTraceProducerId,
26
+ ingestRemoteTraceEvent: () => ingestRemoteTraceEvent,
25
27
  normalizeTraceLevel: () => normalizeTraceLevel,
26
28
  publishMainTrace: () => publishMainTrace,
27
29
  publishTestTrace: () => publishTestTrace,
@@ -55,6 +57,24 @@ function traceLevelOrder(level) {
55
57
  let rendererMinLevel = "debug";
56
58
  let rendererEnabled = false;
57
59
  let customRendererTraceTransport = null;
60
+ let traceProducerId = null;
61
+ function randomIdSuffix() {
62
+ const c = globalThis.crypto;
63
+ if (c && typeof c.randomUUID === "function") {
64
+ return c.randomUUID();
65
+ }
66
+ return `${Date.now().toString(36)}-${Math.random().toString(16).slice(2)}`;
67
+ }
68
+ function getTraceProducerId() {
69
+ if (traceProducerId === null) {
70
+ const processTag = typeof process !== "undefined" && process?.versions?.electron ? process.type === "renderer" ? "renderer" : "main" : typeof window !== "undefined" ? "renderer" : "main";
71
+ traceProducerId = `${processTag}:${randomIdSuffix()}`;
72
+ }
73
+ return traceProducerId;
74
+ }
75
+ function hasValidRemoteIdentity(event) {
76
+ return typeof event.timestamp === "string" && Number.isFinite(Date.parse(event.timestamp)) && typeof event.traceSeq === "number" && Number.isSafeInteger(event.traceSeq) && event.traceSeq >= 1;
77
+ }
58
78
  function normalizeTraceInput(raw) {
59
79
  const input = raw ?? {};
60
80
  const source = typeof input.source === "string" && input.source.trim().length > 0 ? input.source : "unknown";
@@ -113,8 +133,8 @@ class TraceHub {
113
133
  get events$() {
114
134
  return this.shared$;
115
135
  }
116
- setMinLevel(process, level) {
117
- this.minLevels[process] = level;
136
+ setMinLevel(process2, level) {
137
+ this.minLevels[process2] = level;
118
138
  }
119
139
  registerSink(sink) {
120
140
  this.sinks.add(sink);
@@ -122,36 +142,61 @@ class TraceHub {
122
142
  this.sinks.delete(sink);
123
143
  };
124
144
  }
125
- publish(process, level, input) {
145
+ publish(process2, level, input) {
126
146
  const normalized = normalizeTraceInput(input);
127
147
  const event = {
128
148
  ...normalized,
129
149
  level,
130
- process,
150
+ process: process2,
131
151
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
132
- traceSeq: this.nextTraceSeq++
152
+ traceSeq: this.nextTraceSeq++,
153
+ producerId: getTraceProducerId()
133
154
  };
134
- if (traceLevelOrder(level) >= traceLevelOrder(this.minLevels[process])) {
155
+ if (traceLevelOrder(level) >= traceLevelOrder(this.minLevels[process2])) {
135
156
  this.publishToSinks(event);
136
157
  this.subject.next(event);
137
158
  }
138
159
  return event;
139
160
  }
140
- publishRendererToSinks(level, input) {
141
- if (this.sinks.size === 0) {
142
- return;
143
- }
144
- if (traceLevelOrder(level) < traceLevelOrder(this.minLevels.renderer)) {
145
- return;
146
- }
161
+ /**
162
+ * Single renderer admission point: assigns timestamp, traceSeq, and
163
+ * producerId exactly once, then delivers the same event to sinks and
164
+ * events$ subscribers. The returned event is what the renderer transport
165
+ * must forward — no downstream stage may regenerate its identity.
166
+ *
167
+ * Callers gate on rendererEnabled/level BEFORE calling, so gated-out events
168
+ * consume no traceSeq.
169
+ */
170
+ admitRenderer(level, input) {
147
171
  const event = {
148
172
  ...input,
149
173
  level,
150
174
  process: "renderer",
151
175
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
152
- traceSeq: this.nextTraceSeq++
176
+ traceSeq: this.nextTraceSeq++,
177
+ producerId: getTraceProducerId()
153
178
  };
154
179
  this.publishToSinks(event);
180
+ this.subject.next(event);
181
+ return event;
182
+ }
183
+ /**
184
+ * Delivers an event admitted by a remote producer (e.g. a renderer event
185
+ * received over IPC) to this hub's sinks and events$ subscribers without
186
+ * reassigning identity or advancing this hub's own traceSeq counter.
187
+ * The min-level gate for the event's process still applies — delivery
188
+ * filtering is not identity assignment.
189
+ */
190
+ ingest(event) {
191
+ if (event.producerId !== void 0 && event.producerId === getTraceProducerId()) {
192
+ return;
193
+ }
194
+ const gate = this.minLevels[event.process] ?? this.minLevels.renderer;
195
+ if (traceLevelOrder(event.level) < traceLevelOrder(gate)) {
196
+ return;
197
+ }
198
+ this.publishToSinks(event);
199
+ this.subject.next(event);
155
200
  }
156
201
  publishToSinks(event) {
157
202
  if (this.sinks.size === 0) {
@@ -195,18 +240,38 @@ function setRendererTraceEnabled(enabled) {
195
240
  function publishMainTrace(level, input) {
196
241
  return getGlobalTraceHub().publish("main", level, input);
197
242
  }
198
- function publishTestTrace(process, level, input) {
199
- return getGlobalTraceHub().publish(process, level, input);
243
+ function publishTestTrace(process2, level, input) {
244
+ return getGlobalTraceHub().publish(process2, level, input);
200
245
  }
201
246
  function dispatchRendererTracePayload(rawPayload, context) {
202
247
  const payload = rawPayload ?? {};
203
248
  const level = normalizeTraceLevel(payload.level);
249
+ if (hasValidRemoteIdentity(payload)) {
250
+ const merged = mergeTraceRuntimeContext(payload, context);
251
+ getGlobalTraceHub().ingest({
252
+ ...merged,
253
+ level,
254
+ process: "renderer",
255
+ timestamp: payload.timestamp,
256
+ traceSeq: payload.traceSeq,
257
+ ...typeof payload.producerId === "string" && payload.producerId.trim().length > 0 ? { producerId: payload.producerId } : {}
258
+ });
259
+ return { ok: true, forwarded: true };
260
+ }
204
261
  getGlobalTraceHub().publish("renderer", level, mergeTraceRuntimeContext(payload, context));
205
262
  return {
206
263
  ok: true,
207
264
  forwarded: true
208
265
  };
209
266
  }
267
+ function ingestRemoteTraceEvent(event, context) {
268
+ if (!hasValidRemoteIdentity(event)) {
269
+ return false;
270
+ }
271
+ const merged = context ? { ...mergeTraceRuntimeContext(event, context), level: event.level, process: event.process, timestamp: event.timestamp, traceSeq: event.traceSeq, ...event.producerId ? { producerId: event.producerId } : {} } : event;
272
+ getGlobalTraceHub().ingest(merged);
273
+ return true;
274
+ }
210
275
  function setRendererTraceTransport(fn) {
211
276
  customRendererTraceTransport = fn;
212
277
  }
@@ -217,11 +282,10 @@ function emitRendererTrace(level, input) {
217
282
  if (traceLevelOrder(level) < traceLevelOrder(rendererMinLevel)) {
218
283
  return;
219
284
  }
220
- const normalized = { ...normalizeTraceInput(input), level };
221
- getGlobalTraceHub().publishRendererToSinks(level, normalized);
285
+ const event = getGlobalTraceHub().admitRenderer(level, normalizeTraceInput(input));
222
286
  if (customRendererTraceTransport) {
223
287
  try {
224
- customRendererTraceTransport(normalized);
288
+ customRendererTraceTransport(event);
225
289
  return;
226
290
  } catch {
227
291
  }
@@ -231,7 +295,7 @@ function emitRendererTrace(level, input) {
231
295
  return;
232
296
  }
233
297
  try {
234
- bridge.__trace(normalized);
298
+ bridge.__trace(event);
235
299
  } catch {
236
300
  }
237
301
  }
@@ -241,6 +305,7 @@ function clearTraceHubForTests() {
241
305
  rendererMinLevel = "debug";
242
306
  rendererEnabled = false;
243
307
  customRendererTraceTransport = null;
308
+ traceProducerId = null;
244
309
  }
245
310
  // Annotate the CommonJS export names for ESM import in node:
246
311
  0 && (module.exports = {
@@ -248,6 +313,8 @@ function clearTraceHubForTests() {
248
313
  dispatchRendererTracePayload,
249
314
  emitRendererTrace,
250
315
  getTraceEvents$,
316
+ getTraceProducerId,
317
+ ingestRemoteTraceEvent,
251
318
  normalizeTraceLevel,
252
319
  publishMainTrace,
253
320
  publishTestTrace,