@noego/wood 0.4.9 → 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 (493) hide show
  1. package/README.md +118 -42
  2. package/bin/axe.js +313 -98
  3. package/dist/{loader/__fixtures__/layouts/app.load.cjs → automation/actions.cjs} +3 -13
  4. package/dist/automation/actions.cjs.map +1 -0
  5. package/dist/automation/actions.d.cts +57 -0
  6. package/dist/automation/actions.d.ts +57 -0
  7. package/dist/automation/actions.js +1 -0
  8. package/dist/automation/actions.js.map +1 -0
  9. package/dist/automation/actions_executor.cjs +101 -0
  10. package/dist/automation/actions_executor.cjs.map +1 -0
  11. package/dist/automation/actions_executor.d.cts +16 -0
  12. package/dist/automation/actions_executor.d.ts +16 -0
  13. package/dist/automation/actions_executor.js +76 -0
  14. package/dist/automation/actions_executor.js.map +1 -0
  15. package/dist/automation/connection.cjs +86 -0
  16. package/dist/automation/connection.cjs.map +1 -0
  17. package/dist/automation/connection.d.cts +18 -0
  18. package/dist/automation/connection.d.ts +18 -0
  19. package/dist/automation/connection.js +51 -0
  20. package/dist/automation/connection.js.map +1 -0
  21. package/dist/{middleware/__fixtures__/middleware/sequence.cjs → automation/errors.cjs} +25 -22
  22. package/dist/automation/errors.cjs.map +1 -0
  23. package/dist/automation/errors.d.cts +31 -0
  24. package/dist/automation/errors.d.ts +31 -0
  25. package/dist/automation/errors.js +24 -0
  26. package/dist/automation/errors.js.map +1 -0
  27. package/dist/automation/index.cjs +49 -0
  28. package/dist/automation/index.cjs.map +1 -0
  29. package/dist/automation/index.d.cts +16 -0
  30. package/dist/automation/index.d.ts +16 -0
  31. package/dist/automation/index.js +15 -0
  32. package/dist/automation/index.js.map +1 -0
  33. package/dist/automation/introspection_reader.cjs +75 -0
  34. package/dist/automation/introspection_reader.cjs.map +1 -0
  35. package/dist/automation/introspection_reader.d.cts +20 -0
  36. package/dist/automation/introspection_reader.d.ts +20 -0
  37. package/dist/automation/introspection_reader.js +48 -0
  38. package/dist/automation/introspection_reader.js.map +1 -0
  39. package/dist/automation/locator.cjs +102 -0
  40. package/dist/automation/locator.cjs.map +1 -0
  41. package/dist/automation/locator.d.cts +51 -0
  42. package/dist/automation/locator.d.ts +51 -0
  43. package/dist/automation/locator.js +75 -0
  44. package/dist/automation/locator.js.map +1 -0
  45. package/dist/{loader/__fixtures__/views/test/page.load.cjs → automation/observation.cjs} +3 -13
  46. package/dist/automation/observation.cjs.map +1 -0
  47. package/dist/automation/observation.d.cts +44 -0
  48. package/dist/automation/observation.d.ts +44 -0
  49. package/dist/automation/observation.js +1 -0
  50. package/dist/automation/observation.js.map +1 -0
  51. package/dist/{controller/__fixtures__/controllers/test.cjs → automation/receipts.cjs} +3 -15
  52. package/dist/automation/receipts.cjs.map +1 -0
  53. package/dist/automation/receipts.d.cts +27 -0
  54. package/dist/automation/receipts.d.ts +27 -0
  55. package/dist/automation/receipts.js +1 -0
  56. package/dist/automation/receipts.js.map +1 -0
  57. package/dist/automation/scenario.cjs +696 -0
  58. package/dist/automation/scenario.cjs.map +1 -0
  59. package/dist/automation/scenario.d.cts +89 -0
  60. package/dist/automation/scenario.d.ts +89 -0
  61. package/dist/automation/scenario.js +660 -0
  62. package/dist/automation/scenario.js.map +1 -0
  63. package/dist/automation/scrolling.cjs +17 -0
  64. package/dist/automation/scrolling.cjs.map +1 -0
  65. package/dist/automation/scrolling.d.cts +51 -0
  66. package/dist/automation/scrolling.d.ts +51 -0
  67. package/dist/automation/scrolling.js +1 -0
  68. package/dist/automation/scrolling.js.map +1 -0
  69. package/dist/automation/scrolling_executor.cjs +109 -0
  70. package/dist/automation/scrolling_executor.cjs.map +1 -0
  71. package/dist/automation/scrolling_executor.d.cts +13 -0
  72. package/dist/automation/scrolling_executor.d.ts +13 -0
  73. package/dist/automation/scrolling_executor.js +84 -0
  74. package/dist/automation/scrolling_executor.js.map +1 -0
  75. package/dist/automation/target_identity.cjs +17 -0
  76. package/dist/automation/target_identity.cjs.map +1 -0
  77. package/dist/automation/target_identity.d.cts +28 -0
  78. package/dist/automation/target_identity.d.ts +28 -0
  79. package/dist/automation/target_identity.js +1 -0
  80. package/dist/automation/target_identity.js.map +1 -0
  81. package/dist/automation/target_registry.cjs +148 -0
  82. package/dist/automation/target_registry.cjs.map +1 -0
  83. package/dist/automation/target_registry.d.cts +32 -0
  84. package/dist/automation/target_registry.d.ts +32 -0
  85. package/dist/automation/target_registry.js +122 -0
  86. package/dist/automation/target_registry.js.map +1 -0
  87. package/dist/automation/waits.cjs +17 -0
  88. package/dist/automation/waits.cjs.map +1 -0
  89. package/dist/automation/waits.d.cts +44 -0
  90. package/dist/automation/waits.d.ts +44 -0
  91. package/dist/automation/waits.js +1 -0
  92. package/dist/automation/waits.js.map +1 -0
  93. package/dist/automation/waits_executor.cjs +104 -0
  94. package/dist/automation/waits_executor.cjs.map +1 -0
  95. package/dist/automation/waits_executor.d.cts +14 -0
  96. package/dist/automation/waits_executor.d.ts +14 -0
  97. package/dist/automation/waits_executor.js +79 -0
  98. package/dist/automation/waits_executor.js.map +1 -0
  99. package/dist/bridge/backend_bridge.cjs.map +1 -1
  100. package/dist/bridge/backend_bridge.js.map +1 -1
  101. package/dist/client/index.cjs +78 -21
  102. package/dist/client/index.cjs.map +1 -1
  103. package/dist/client/index.d.cts +19 -3
  104. package/dist/client/index.d.ts +19 -3
  105. package/dist/client/index.js +80 -22
  106. package/dist/client/index.js.map +1 -1
  107. package/dist/client/renderer_log_transport.cjs +151 -0
  108. package/dist/client/renderer_log_transport.cjs.map +1 -0
  109. package/dist/client/renderer_log_transport.d.cts +54 -0
  110. package/dist/client/renderer_log_transport.d.ts +54 -0
  111. package/dist/client/renderer_log_transport.js +123 -0
  112. package/dist/client/renderer_log_transport.js.map +1 -0
  113. package/dist/codegen/controller_registration_generator.cjs +13 -2
  114. package/dist/codegen/controller_registration_generator.cjs.map +1 -1
  115. package/dist/codegen/controller_registration_generator.d.cts +12 -1
  116. package/dist/codegen/controller_registration_generator.d.ts +12 -1
  117. package/dist/codegen/controller_registration_generator.js +10 -1
  118. package/dist/codegen/controller_registration_generator.js.map +1 -1
  119. package/dist/codegen/index.d.cts +1 -0
  120. package/dist/codegen/index.d.ts +1 -0
  121. package/dist/codegen/preload_generator.cjs +13 -6
  122. package/dist/codegen/preload_generator.cjs.map +1 -1
  123. package/dist/codegen/preload_generator.d.cts +11 -2
  124. package/dist/codegen/preload_generator.d.ts +11 -2
  125. package/dist/codegen/preload_generator.js +13 -6
  126. package/dist/codegen/preload_generator.js.map +1 -1
  127. package/dist/codegen/renderer_app_generator.cjs +95 -44
  128. package/dist/codegen/renderer_app_generator.cjs.map +1 -1
  129. package/dist/codegen/renderer_app_generator.js +95 -44
  130. package/dist/codegen/renderer_app_generator.js.map +1 -1
  131. package/dist/codegen/type_generator.cjs +1 -0
  132. package/dist/codegen/type_generator.cjs.map +1 -1
  133. package/dist/codegen/type_generator.js +1 -0
  134. package/dist/codegen/type_generator.js.map +1 -1
  135. package/dist/config/config_parser.cjs +95 -4
  136. package/dist/config/config_parser.cjs.map +1 -1
  137. package/dist/config/config_parser.d.cts +10 -2
  138. package/dist/config/config_parser.d.ts +10 -2
  139. package/dist/config/config_parser.js +92 -3
  140. package/dist/config/config_parser.js.map +1 -1
  141. package/dist/config/index.cjs +6 -2
  142. package/dist/config/index.cjs.map +1 -1
  143. package/dist/config/index.d.cts +2 -2
  144. package/dist/config/index.d.ts +2 -2
  145. package/dist/config/index.js +8 -2
  146. package/dist/config/index.js.map +1 -1
  147. package/dist/controller/controller_resolver.cjs +51 -3
  148. package/dist/controller/controller_resolver.cjs.map +1 -1
  149. package/dist/controller/controller_resolver.d.cts +27 -4
  150. package/dist/controller/controller_resolver.d.ts +27 -4
  151. package/dist/controller/controller_resolver.js +48 -2
  152. package/dist/controller/controller_resolver.js.map +1 -1
  153. package/dist/controller/index.cjs +6 -2
  154. package/dist/controller/index.cjs.map +1 -1
  155. package/dist/controller/index.d.cts +1 -1
  156. package/dist/controller/index.d.ts +1 -1
  157. package/dist/controller/index.js +4 -2
  158. package/dist/controller/index.js.map +1 -1
  159. package/dist/dev/wood_dev_server.cjs +4 -1
  160. package/dist/dev/wood_dev_server.cjs.map +1 -1
  161. package/dist/dev/wood_dev_server.js +5 -2
  162. package/dist/dev/wood_dev_server.js.map +1 -1
  163. package/dist/dev/yaml_watcher.cjs +1 -1
  164. package/dist/dev/yaml_watcher.cjs.map +1 -1
  165. package/dist/dev/yaml_watcher.d.cts +4 -0
  166. package/dist/dev/yaml_watcher.d.ts +4 -0
  167. package/dist/dev/yaml_watcher.js +1 -1
  168. package/dist/dev/yaml_watcher.js.map +1 -1
  169. package/dist/frontend/frontend_lifecycle.cjs +74 -0
  170. package/dist/frontend/frontend_lifecycle.cjs.map +1 -0
  171. package/dist/frontend/frontend_lifecycle.d.cts +50 -0
  172. package/dist/frontend/frontend_lifecycle.d.ts +50 -0
  173. package/dist/frontend/frontend_lifecycle.js +50 -0
  174. package/dist/frontend/frontend_lifecycle.js.map +1 -0
  175. package/dist/frontend/frontend_page.cjs +122 -0
  176. package/dist/frontend/frontend_page.cjs.map +1 -0
  177. package/dist/frontend/frontend_page.d.cts +62 -0
  178. package/dist/frontend/frontend_page.d.ts +62 -0
  179. package/dist/frontend/frontend_page.js +98 -0
  180. package/dist/frontend/frontend_page.js.map +1 -0
  181. package/dist/frontend/frontend_surface.cjs +249 -0
  182. package/dist/frontend/frontend_surface.cjs.map +1 -0
  183. package/dist/frontend/frontend_surface.d.cts +64 -0
  184. package/dist/frontend/frontend_surface.d.ts +64 -0
  185. package/dist/frontend/frontend_surface.js +224 -0
  186. package/dist/frontend/frontend_surface.js.map +1 -0
  187. package/dist/frontend/index.cjs +52 -0
  188. package/dist/frontend/index.cjs.map +1 -0
  189. package/dist/frontend/index.d.cts +10 -0
  190. package/dist/frontend/index.d.ts +10 -0
  191. package/dist/frontend/index.js +19 -0
  192. package/dist/frontend/index.js.map +1 -0
  193. package/dist/frontend/page_catalog.cjs +135 -0
  194. package/dist/frontend/page_catalog.cjs.map +1 -0
  195. package/dist/frontend/page_catalog.d.cts +56 -0
  196. package/dist/frontend/page_catalog.d.ts +56 -0
  197. package/dist/frontend/page_catalog.js +108 -0
  198. package/dist/frontend/page_catalog.js.map +1 -0
  199. package/dist/frontend/tracked_transport.cjs +55 -0
  200. package/dist/frontend/tracked_transport.cjs.map +1 -0
  201. package/dist/frontend/tracked_transport.d.cts +36 -0
  202. package/dist/frontend/tracked_transport.d.ts +36 -0
  203. package/dist/frontend/tracked_transport.js +31 -0
  204. package/dist/frontend/tracked_transport.js.map +1 -0
  205. package/dist/frontend/work_registry.cjs +153 -0
  206. package/dist/frontend/work_registry.cjs.map +1 -0
  207. package/dist/frontend/work_registry.d.cts +70 -0
  208. package/dist/frontend/work_registry.d.ts +70 -0
  209. package/dist/frontend/work_registry.js +128 -0
  210. package/dist/frontend/work_registry.js.map +1 -0
  211. package/dist/index.cjs +24 -0
  212. package/dist/index.cjs.map +1 -1
  213. package/dist/index.d.cts +11 -7
  214. package/dist/index.d.ts +11 -7
  215. package/dist/index.js +27 -4
  216. package/dist/index.js.map +1 -1
  217. package/dist/main/index.cjs +10 -0
  218. package/dist/main/index.cjs.map +1 -1
  219. package/dist/main/index.d.cts +14 -2
  220. package/dist/main/index.d.ts +14 -2
  221. package/dist/main/index.js +16 -0
  222. package/dist/main/index.js.map +1 -1
  223. package/dist/middleware/middleware_resolver.cjs +22 -1
  224. package/dist/middleware/middleware_resolver.cjs.map +1 -1
  225. package/dist/middleware/middleware_resolver.d.cts +13 -1
  226. package/dist/middleware/middleware_resolver.d.ts +13 -1
  227. package/dist/middleware/middleware_resolver.js +22 -1
  228. package/dist/middleware/middleware_resolver.js.map +1 -1
  229. package/dist/navigation/automation_introspection.cjs +110 -0
  230. package/dist/navigation/automation_introspection.cjs.map +1 -0
  231. package/dist/navigation/automation_introspection.d.cts +60 -0
  232. package/dist/navigation/automation_introspection.d.ts +60 -0
  233. package/dist/navigation/automation_introspection.js +85 -0
  234. package/dist/navigation/automation_introspection.js.map +1 -0
  235. package/dist/navigation/index.cjs +10 -2
  236. package/dist/navigation/index.cjs.map +1 -1
  237. package/dist/navigation/index.d.cts +27 -1
  238. package/dist/navigation/index.d.ts +27 -1
  239. package/dist/navigation/index.js +6 -1
  240. package/dist/navigation/index.js.map +1 -1
  241. package/dist/{middleware/__fixtures__/middleware/auth.cjs → navigation/layout_preservation.cjs} +18 -20
  242. package/dist/navigation/layout_preservation.cjs.map +1 -0
  243. package/dist/navigation/layout_preservation.d.cts +2 -0
  244. package/dist/navigation/layout_preservation.d.ts +2 -0
  245. package/dist/navigation/layout_preservation.js +18 -0
  246. package/dist/navigation/layout_preservation.js.map +1 -0
  247. package/dist/parser/index.cjs +2 -0
  248. package/dist/parser/index.cjs.map +1 -1
  249. package/dist/parser/index.d.cts +1 -1
  250. package/dist/parser/index.d.ts +1 -1
  251. package/dist/parser/index.js +2 -1
  252. package/dist/parser/index.js.map +1 -1
  253. package/dist/parser/operations_parser.cjs +6 -0
  254. package/dist/parser/operations_parser.cjs.map +1 -1
  255. package/dist/parser/operations_parser.d.cts +9 -2
  256. package/dist/parser/operations_parser.d.ts +9 -2
  257. package/dist/parser/operations_parser.js +5 -0
  258. package/dist/parser/operations_parser.js.map +1 -1
  259. package/dist/parser/views_parser.cjs.map +1 -1
  260. package/dist/parser/views_parser.js.map +1 -1
  261. package/dist/router/index.d.cts +1 -0
  262. package/dist/router/index.d.ts +1 -0
  263. package/dist/router/wood_router.cjs +35 -3
  264. package/dist/router/wood_router.cjs.map +1 -1
  265. package/dist/router/wood_router.d.cts +15 -0
  266. package/dist/router/wood_router.d.ts +15 -0
  267. package/dist/router/wood_router.js +36 -4
  268. package/dist/router/wood_router.js.map +1 -1
  269. package/dist/runtime/get_container.cjs +9 -34
  270. package/dist/runtime/get_container.cjs.map +1 -1
  271. package/dist/runtime/get_container.d.cts +24 -4
  272. package/dist/runtime/get_container.d.ts +24 -4
  273. package/dist/runtime/get_container.js +8 -23
  274. package/dist/runtime/get_container.js.map +1 -1
  275. package/dist/runtime/index.cjs +9 -0
  276. package/dist/runtime/index.cjs.map +1 -1
  277. package/dist/runtime/index.d.cts +5 -2
  278. package/dist/runtime/index.d.ts +5 -2
  279. package/dist/runtime/index.js +10 -1
  280. package/dist/runtime/index.js.map +1 -1
  281. package/dist/runtime/renderer_config_extension.cjs +50 -0
  282. package/dist/runtime/renderer_config_extension.cjs.map +1 -0
  283. package/dist/runtime/renderer_config_extension.d.cts +19 -0
  284. package/dist/runtime/renderer_config_extension.d.ts +19 -0
  285. package/dist/runtime/renderer_config_extension.js +24 -0
  286. package/dist/runtime/renderer_config_extension.js.map +1 -0
  287. package/dist/runtime/renderer_log_batch_receiver.cjs +73 -0
  288. package/dist/runtime/renderer_log_batch_receiver.cjs.map +1 -0
  289. package/dist/runtime/renderer_log_batch_receiver.d.cts +29 -0
  290. package/dist/runtime/renderer_log_batch_receiver.d.ts +29 -0
  291. package/dist/runtime/renderer_log_batch_receiver.js +48 -0
  292. package/dist/runtime/renderer_log_batch_receiver.js.map +1 -0
  293. package/dist/runtime/renderer_trace_batch_receiver_registry.d.cts +1 -1
  294. package/dist/runtime/renderer_trace_batch_receiver_registry.d.ts +1 -1
  295. package/dist/runtime/runtime.cjs +14 -0
  296. package/dist/runtime/runtime.cjs.map +1 -1
  297. package/dist/runtime/runtime.d.cts +2 -1
  298. package/dist/runtime/runtime.d.ts +2 -1
  299. package/dist/runtime/runtime.js +14 -0
  300. package/dist/runtime/runtime.js.map +1 -1
  301. package/dist/stick/index.cjs.map +1 -1
  302. package/dist/stick/index.js.map +1 -1
  303. package/dist/testing/automation_assertions.cjs +417 -0
  304. package/dist/testing/automation_assertions.cjs.map +1 -0
  305. package/dist/testing/automation_assertions.d.cts +44 -0
  306. package/dist/testing/automation_assertions.d.ts +44 -0
  307. package/dist/testing/automation_assertions.js +385 -0
  308. package/dist/testing/automation_assertions.js.map +1 -0
  309. package/dist/testing/browser.cjs +130 -57
  310. package/dist/testing/browser.cjs.map +1 -1
  311. package/dist/testing/browser.d.cts +10 -4
  312. package/dist/testing/browser.d.ts +10 -4
  313. package/dist/testing/browser.js +132 -53
  314. package/dist/testing/browser.js.map +1 -1
  315. package/dist/testing/create_controller_harness.cjs +28 -8
  316. package/dist/testing/create_controller_harness.cjs.map +1 -1
  317. package/dist/testing/create_controller_harness.d.cts +18 -2
  318. package/dist/testing/create_controller_harness.d.ts +18 -2
  319. package/dist/testing/create_controller_harness.js +28 -8
  320. package/dist/testing/create_controller_harness.js.map +1 -1
  321. package/dist/testing/create_router_bridge.d.cts +1 -0
  322. package/dist/testing/create_router_bridge.d.ts +1 -0
  323. package/dist/testing/create_test_router.d.cts +1 -0
  324. package/dist/testing/create_test_router.d.ts +1 -0
  325. package/dist/testing/geometry.cjs +109 -0
  326. package/dist/testing/geometry.cjs.map +1 -0
  327. package/dist/testing/geometry.d.cts +45 -0
  328. package/dist/testing/geometry.d.ts +45 -0
  329. package/dist/testing/geometry.js +79 -0
  330. package/dist/testing/geometry.js.map +1 -0
  331. package/dist/testing/index.cjs +62 -2
  332. package/dist/testing/index.cjs.map +1 -1
  333. package/dist/testing/index.d.cts +23 -4
  334. package/dist/testing/index.d.ts +23 -4
  335. package/dist/testing/index.js +50 -2
  336. package/dist/testing/index.js.map +1 -1
  337. package/dist/{controller/__fixtures__/controllers/not_a_class.cjs → testing/test_wood.cjs} +15 -7
  338. package/dist/testing/test_wood.cjs.map +1 -0
  339. package/dist/testing/test_wood.d.cts +16 -0
  340. package/dist/testing/test_wood.d.ts +16 -0
  341. package/dist/testing/test_wood.js +12 -0
  342. package/dist/testing/test_wood.js.map +1 -0
  343. package/dist/testing/test_wood_config.cjs +272 -0
  344. package/dist/testing/test_wood_config.cjs.map +1 -0
  345. package/dist/testing/test_wood_config.d.cts +111 -0
  346. package/dist/testing/test_wood_config.d.ts +111 -0
  347. package/dist/testing/test_wood_config.js +247 -0
  348. package/dist/testing/test_wood_config.js.map +1 -0
  349. package/dist/testing/wood_config_source.cjs +146 -0
  350. package/dist/testing/wood_config_source.cjs.map +1 -0
  351. package/dist/testing/wood_config_source.d.cts +36 -0
  352. package/dist/testing/wood_config_source.d.ts +36 -0
  353. package/dist/testing/wood_config_source.js +112 -0
  354. package/dist/testing/wood_config_source.js.map +1 -0
  355. package/dist/testing/wood_env_renderer.cjs +210 -0
  356. package/dist/testing/wood_env_renderer.cjs.map +1 -0
  357. package/dist/testing/wood_env_renderer.d.cts +74 -0
  358. package/dist/testing/wood_env_renderer.d.ts +74 -0
  359. package/dist/testing/wood_env_renderer.js +188 -0
  360. package/dist/testing/wood_env_renderer.js.map +1 -0
  361. package/dist/testing/wood_test_selection.cjs +94 -0
  362. package/dist/testing/wood_test_selection.cjs.map +1 -0
  363. package/dist/testing/wood_test_selection.d.cts +39 -0
  364. package/dist/testing/wood_test_selection.d.ts +39 -0
  365. package/dist/testing/wood_test_selection.js +68 -0
  366. package/dist/testing/wood_test_selection.js.map +1 -0
  367. package/dist/trace-testing/index.d.cts +1 -2
  368. package/dist/trace-testing/index.d.ts +1 -2
  369. package/dist/trace-testing/trace_recorder.cjs +1 -1
  370. package/dist/trace-testing/trace_recorder.cjs.map +1 -1
  371. package/dist/trace-testing/trace_recorder.d.cts +1 -2
  372. package/dist/trace-testing/trace_recorder.d.ts +1 -2
  373. package/dist/trace-testing/trace_recorder.js +1 -1
  374. package/dist/trace-testing/trace_recorder.js.map +1 -1
  375. package/dist/trace-transport/index.d.cts +1 -1
  376. package/dist/trace-transport/index.d.ts +1 -1
  377. package/dist/{trace_hub-Cob54qRx.d.cts → trace_hub-Cpo_nVze.d.cts} +21 -1
  378. package/dist/{trace_hub-Cob54qRx.d.ts → trace_hub-Cpo_nVze.d.ts} +21 -1
  379. package/dist/tracing/index.cjs +9 -2
  380. package/dist/tracing/index.cjs.map +1 -1
  381. package/dist/tracing/index.d.cts +3 -2
  382. package/dist/tracing/index.d.ts +3 -2
  383. package/dist/tracing/index.js +7 -1
  384. package/dist/tracing/index.js.map +1 -1
  385. package/dist/tracing/renderer_trace_batch_host.d.cts +1 -1
  386. package/dist/tracing/renderer_trace_batch_host.d.ts +1 -1
  387. package/dist/tracing/renderer_trace_batch_transport.cjs +48 -6
  388. package/dist/tracing/renderer_trace_batch_transport.cjs.map +1 -1
  389. package/dist/tracing/renderer_trace_batch_transport.d.cts +17 -1
  390. package/dist/tracing/renderer_trace_batch_transport.d.ts +17 -1
  391. package/dist/tracing/renderer_trace_batch_transport.js +48 -6
  392. package/dist/tracing/renderer_trace_batch_transport.js.map +1 -1
  393. package/dist/tracing/trace_batch_adapter.cjs +110 -0
  394. package/dist/tracing/trace_batch_adapter.cjs.map +1 -0
  395. package/dist/tracing/trace_batch_adapter.d.cts +36 -0
  396. package/dist/tracing/trace_batch_adapter.d.ts +36 -0
  397. package/dist/tracing/trace_batch_adapter.js +86 -0
  398. package/dist/tracing/trace_batch_adapter.js.map +1 -0
  399. package/dist/tracing/trace_commit_writer.d.cts +1 -1
  400. package/dist/tracing/trace_commit_writer.d.ts +1 -1
  401. package/dist/tracing/trace_hub.cjs +87 -20
  402. package/dist/tracing/trace_hub.cjs.map +1 -1
  403. package/dist/tracing/trace_hub.d.cts +1 -1
  404. package/dist/tracing/trace_hub.d.ts +1 -1
  405. package/dist/tracing/trace_hub.js +85 -20
  406. package/dist/tracing/trace_hub.js.map +1 -1
  407. package/dist/tracing/trace_provider.cjs +21 -6
  408. package/dist/tracing/trace_provider.cjs.map +1 -1
  409. package/dist/tracing/trace_provider.d.cts +13 -4
  410. package/dist/tracing/trace_provider.d.ts +13 -4
  411. package/dist/tracing/trace_provider.js +22 -7
  412. package/dist/tracing/trace_provider.js.map +1 -1
  413. package/dist/tracing/types/wood_trace_batch.types.cjs.map +1 -1
  414. package/dist/tracing/types/wood_trace_batch.types.d.cts +15 -1
  415. package/dist/tracing/types/wood_trace_batch.types.d.ts +15 -1
  416. package/dist/tracing/types/wood_trace_sink.types.d.cts +1 -1
  417. package/dist/tracing/types/wood_trace_sink.types.d.ts +1 -1
  418. package/dist/tracing/wood_trace_batch_contract.cjs +2 -0
  419. package/dist/tracing/wood_trace_batch_contract.cjs.map +1 -1
  420. package/dist/tracing/wood_trace_batch_contract.d.cts +1 -1
  421. package/dist/tracing/wood_trace_batch_contract.d.ts +1 -1
  422. package/dist/tracing/wood_trace_batch_contract.js +2 -0
  423. package/dist/tracing/wood_trace_batch_contract.js.map +1 -1
  424. package/dist/transport/build_transport_bridge.cjs +4 -2
  425. package/dist/transport/build_transport_bridge.cjs.map +1 -1
  426. package/dist/transport/build_transport_bridge.d.cts +7 -1
  427. package/dist/transport/build_transport_bridge.d.ts +7 -1
  428. package/dist/transport/build_transport_bridge.js +2 -1
  429. package/dist/transport/build_transport_bridge.js.map +1 -1
  430. package/dist/transport/in_process_router_transport.d.cts +1 -0
  431. package/dist/transport/in_process_router_transport.d.ts +1 -0
  432. package/dist/transport/index.d.cts +1 -0
  433. package/dist/transport/index.d.ts +1 -0
  434. package/dist/types/config.cjs.map +1 -1
  435. package/dist/types/config.d.cts +47 -1
  436. package/dist/types/config.d.ts +47 -1
  437. package/dist/types/context.cjs +12 -0
  438. package/dist/types/context.cjs.map +1 -1
  439. package/dist/types/context.d.cts +27 -1
  440. package/dist/types/context.d.ts +27 -1
  441. package/dist/types/context.js +4 -0
  442. package/dist/types/context.js.map +1 -1
  443. package/dist/types/index.d.cts +2 -2
  444. package/dist/types/index.d.ts +2 -2
  445. package/dist/types/operations.cjs.map +1 -1
  446. package/dist/types/operations.d.cts +2 -0
  447. package/dist/types/operations.d.ts +2 -0
  448. package/docs/axe.md +706 -0
  449. package/package.json +19 -5
  450. package/src/components/NavigationShell.scopes.browser.test.ts +363 -0
  451. package/src/components/NavigationShell.svelte +126 -49
  452. package/dist/controller/__fixtures__/controllers/chat.cjs +0 -32
  453. package/dist/controller/__fixtures__/controllers/chat.cjs.map +0 -1
  454. package/dist/controller/__fixtures__/controllers/chat.d.cts +0 -11
  455. package/dist/controller/__fixtures__/controllers/chat.d.ts +0 -11
  456. package/dist/controller/__fixtures__/controllers/chat.js +0 -12
  457. package/dist/controller/__fixtures__/controllers/chat.js.map +0 -1
  458. package/dist/controller/__fixtures__/controllers/not_a_class.cjs.map +0 -1
  459. package/dist/controller/__fixtures__/controllers/not_a_class.d.cts +0 -3
  460. package/dist/controller/__fixtures__/controllers/not_a_class.d.ts +0 -3
  461. package/dist/controller/__fixtures__/controllers/not_a_class.js +0 -5
  462. package/dist/controller/__fixtures__/controllers/not_a_class.js.map +0 -1
  463. package/dist/controller/__fixtures__/controllers/settings.controller.cjs +0 -32
  464. package/dist/controller/__fixtures__/controllers/settings.controller.cjs.map +0 -1
  465. package/dist/controller/__fixtures__/controllers/settings.controller.d.cts +0 -12
  466. package/dist/controller/__fixtures__/controllers/settings.controller.d.ts +0 -12
  467. package/dist/controller/__fixtures__/controllers/settings.controller.js +0 -12
  468. package/dist/controller/__fixtures__/controllers/settings.controller.js.map +0 -1
  469. package/dist/controller/__fixtures__/controllers/test.cjs.map +0 -1
  470. package/dist/controller/__fixtures__/controllers/test.d.cts +0 -7
  471. package/dist/controller/__fixtures__/controllers/test.d.ts +0 -7
  472. package/dist/controller/__fixtures__/controllers/test.js +0 -9
  473. package/dist/controller/__fixtures__/controllers/test.js.map +0 -1
  474. package/dist/loader/__fixtures__/layouts/app.load.cjs.map +0 -1
  475. package/dist/loader/__fixtures__/layouts/app.load.d.cts +0 -5
  476. package/dist/loader/__fixtures__/layouts/app.load.d.ts +0 -5
  477. package/dist/loader/__fixtures__/layouts/app.load.js +0 -7
  478. package/dist/loader/__fixtures__/layouts/app.load.js.map +0 -1
  479. package/dist/loader/__fixtures__/views/test/page.load.cjs.map +0 -1
  480. package/dist/loader/__fixtures__/views/test/page.load.d.cts +0 -6
  481. package/dist/loader/__fixtures__/views/test/page.load.d.ts +0 -6
  482. package/dist/loader/__fixtures__/views/test/page.load.js +0 -7
  483. package/dist/loader/__fixtures__/views/test/page.load.js.map +0 -1
  484. package/dist/middleware/__fixtures__/middleware/auth.cjs.map +0 -1
  485. package/dist/middleware/__fixtures__/middleware/auth.d.cts +0 -6
  486. package/dist/middleware/__fixtures__/middleware/auth.d.ts +0 -6
  487. package/dist/middleware/__fixtures__/middleware/auth.js +0 -19
  488. package/dist/middleware/__fixtures__/middleware/auth.js.map +0 -1
  489. package/dist/middleware/__fixtures__/middleware/sequence.cjs.map +0 -1
  490. package/dist/middleware/__fixtures__/middleware/sequence.d.cts +0 -7
  491. package/dist/middleware/__fixtures__/middleware/sequence.d.ts +0 -7
  492. package/dist/middleware/__fixtures__/middleware/sequence.js +0 -21
  493. package/dist/middleware/__fixtures__/middleware/sequence.js.map +0 -1
@@ -1,10 +1,18 @@
1
1
  import { MetadataSnapshotLimits } from '@noego/telemetry/core';
2
- import { a as TraceEvent, b as TraceInput, c as TraceLevel } from '../../trace_hub-Cob54qRx.cjs';
2
+ import { a as TraceEvent, b as TraceInput, c as TraceLevel } from '../../trace_hub-Cpo_nVze.cjs';
3
3
  import 'rxjs';
4
4
 
5
5
  type WoodRendererTraceInput = Readonly<Omit<TraceInput, 'payload'> & {
6
6
  readonly level: TraceLevel;
7
7
  readonly payload?: Readonly<Record<string, unknown>>;
8
+ /**
9
+ * Hub-admitted identity, present when the renderer TraceHub admitted the
10
+ * event before it reached the transport. The transport preserves these
11
+ * exactly; it stamps its own only for legacy senders that omit them.
12
+ */
13
+ readonly timestamp?: string;
14
+ readonly traceSeq?: number;
15
+ readonly producerId?: string;
8
16
  }>;
9
17
  type WoodRendererTraceEvent = Readonly<Omit<TraceEvent, 'payload'> & {
10
18
  readonly payload?: Readonly<Record<string, unknown>>;
@@ -60,6 +68,12 @@ type WoodTraceBatchTransportStatus = Readonly<{
60
68
  droppedClosed: number;
61
69
  droppedRejected: number;
62
70
  droppedRetryExhausted: number;
71
+ /**
72
+ * Count of stamped events whose traceSeq regressed against this transport's
73
+ * sequence stream and were restamped as legacy. Nonzero means more than one
74
+ * admission source is feeding one transport — the invariant is broken.
75
+ */
76
+ identityRestamped: number;
63
77
  metadataTruncatedValues: number;
64
78
  metadataRedactedValues: number;
65
79
  metadataSerializationFailures: number;
@@ -1,10 +1,18 @@
1
1
  import { MetadataSnapshotLimits } from '@noego/telemetry/core';
2
- import { a as TraceEvent, b as TraceInput, c as TraceLevel } from '../../trace_hub-Cob54qRx.js';
2
+ import { a as TraceEvent, b as TraceInput, c as TraceLevel } from '../../trace_hub-Cpo_nVze.js';
3
3
  import 'rxjs';
4
4
 
5
5
  type WoodRendererTraceInput = Readonly<Omit<TraceInput, 'payload'> & {
6
6
  readonly level: TraceLevel;
7
7
  readonly payload?: Readonly<Record<string, unknown>>;
8
+ /**
9
+ * Hub-admitted identity, present when the renderer TraceHub admitted the
10
+ * event before it reached the transport. The transport preserves these
11
+ * exactly; it stamps its own only for legacy senders that omit them.
12
+ */
13
+ readonly timestamp?: string;
14
+ readonly traceSeq?: number;
15
+ readonly producerId?: string;
8
16
  }>;
9
17
  type WoodRendererTraceEvent = Readonly<Omit<TraceEvent, 'payload'> & {
10
18
  readonly payload?: Readonly<Record<string, unknown>>;
@@ -60,6 +68,12 @@ type WoodTraceBatchTransportStatus = Readonly<{
60
68
  droppedClosed: number;
61
69
  droppedRejected: number;
62
70
  droppedRetryExhausted: number;
71
+ /**
72
+ * Count of stamped events whose traceSeq regressed against this transport's
73
+ * sequence stream and were restamped as legacy. Nonzero means more than one
74
+ * admission source is feeding one transport — the invariant is broken.
75
+ */
76
+ identityRestamped: number;
63
77
  metadataTruncatedValues: number;
64
78
  metadataRedactedValues: number;
65
79
  metadataSerializationFailures: number;
@@ -1,2 +1,2 @@
1
- export { W as WoodTraceEventSink, g as WoodTraceEventSnapshot, h as WoodTraceSinkDisposer } from '../../trace_hub-Cob54qRx.cjs';
1
+ export { W as WoodTraceEventSink, g as WoodTraceEventSnapshot, h as WoodTraceSinkDisposer } from '../../trace_hub-Cpo_nVze.cjs';
2
2
  import 'rxjs';
@@ -1,2 +1,2 @@
1
- export { W as WoodTraceEventSink, g as WoodTraceEventSnapshot, h as WoodTraceSinkDisposer } from '../../trace_hub-Cob54qRx.js';
1
+ export { W as WoodTraceEventSink, g as WoodTraceEventSnapshot, h as WoodTraceSinkDisposer } from '../../trace_hub-Cpo_nVze.js';
2
2
  import 'rxjs';
@@ -153,6 +153,8 @@ class WoodTraceBatchContract {
153
153
  process: "renderer",
154
154
  timestamp: input.timestamp,
155
155
  traceSeq: input.traceSeq,
156
+ // Durable identity passthrough: never a validation failure when absent.
157
+ ...typeof input.producerId === "string" && input.producerId.trim().length > 0 ? { producerId: input.producerId } : {},
156
158
  ...typeof input.message === "string" ? { message: input.message } : {},
157
159
  ...this.isConversationId(input.conversationId) ? { conversationId: input.conversationId } : {},
158
160
  ...input.payload ? { payload: input.payload } : {},
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tracing/wood_trace_batch_contract.ts"],"sourcesContent":["import type {\n WoodRendererTraceEvent,\n WoodTraceAcknowledgementParseResult,\n WoodTraceBatch,\n WoodTraceBatchAcknowledgement,\n WoodTraceBatchParseResult,\n WoodTraceEventParseResult,\n WoodTraceEventsParseResult,\n WoodTraceIdentityValidationResult,\n} from './types/wood_trace_batch.types.js';\n\nconst MAX_BATCH_EVENTS = 256;\n\nexport class WoodTraceBatchContract {\n create(\n producerId: string,\n sequenceStart: number,\n events: readonly WoodRendererTraceEvent[],\n ): WoodTraceBatch {\n const snapshots = events.map((event) => this.snapshotEvent(event));\n const last = snapshots[snapshots.length - 1];\n const sequenceEnd = last ? last.traceSeq - 1 : sequenceStart - 1;\n return Object.freeze({\n kind: 'wood.trace.batch',\n protocolVersion: 1,\n producerId,\n batchId: `wtb1:${producerId}:${sequenceStart}-${sequenceEnd}`,\n sequenceStart,\n sequenceEnd,\n events: Object.freeze(snapshots),\n });\n }\n\n parse(input: unknown): WoodTraceBatchParseResult {\n if (!this.isRecord(input) || input.kind !== 'wood.trace.batch') {\n return { kind: 'not-batch' };\n }\n\n const batchId = typeof input.batchId === 'string' ? input.batchId : null;\n const identity = this.validateIdentity(input);\n if (identity.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: identity.reason };\n }\n const producerId = input.producerId;\n if (typeof producerId !== 'string') {\n return { kind: 'invalid', batchId, reason: 'Trace batch producer identity is invalid' };\n }\n\n const parsedEvents = this.parseEvents(input.events);\n if (parsedEvents.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: parsedEvents.reason };\n }\n const events = parsedEvents.events;\n\n const parsedSequenceRange = this.parseSequenceRange(input, events);\n if (parsedSequenceRange.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: parsedSequenceRange.reason };\n }\n const { sequenceStart, sequenceEnd } = parsedSequenceRange;\n const hasTraceSequenceMismatch = events.some((event, index) => {\n const previous = events[index - 1];\n return previous !== undefined && event.traceSeq <= previous.traceSeq;\n });\n if (hasTraceSequenceMismatch) {\n return { kind: 'invalid', batchId, reason: 'Trace event sequences are not strictly increasing' };\n }\n const expectedBatchId = `wtb1:${producerId}:${sequenceStart}-${sequenceEnd}`;\n if (input.batchId !== expectedBatchId) {\n return { kind: 'invalid', batchId, reason: 'Trace batch identity does not match its sequence range' };\n }\n\n return {\n kind: 'valid',\n batch: this.create(producerId, sequenceStart, events),\n };\n }\n\n parseAcknowledgement(input: unknown): WoodTraceAcknowledgementParseResult {\n if (!this.isRecord(input) || typeof input.kind !== 'string' || typeof input.batchId !== 'string') {\n return { ok: false, reason: 'Trace batch acknowledgement framing is invalid' };\n }\n\n if (input.kind === 'committed') {\n return this.parseCommittedAcknowledgement(input);\n }\n if (input.kind === 'retryable') {\n return this.parseRetryableAcknowledgement(input);\n }\n if (input.kind === 'rejected' && typeof input.reason === 'string') {\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'rejected',\n batchId: input.batchId,\n reason: input.reason,\n }),\n };\n }\n return { ok: false, reason: 'Trace batch acknowledgement kind is invalid' };\n }\n\n private parseCommittedAcknowledgement(\n input: Record<string, unknown>,\n ): WoodTraceAcknowledgementParseResult {\n const batchId = input.batchId;\n const committedAtMs = input.committedAtMs;\n const acceptedEvents = input.acceptedEvents;\n const validNumbers = typeof batchId === 'string'\n && typeof committedAtMs === 'number'\n && Number.isFinite(committedAtMs)\n && typeof acceptedEvents === 'number'\n && Number.isSafeInteger(acceptedEvents)\n && acceptedEvents >= 0;\n if (!validNumbers) {\n return { ok: false, reason: 'Committed trace acknowledgement is invalid' };\n }\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'committed',\n batchId,\n committedAtMs,\n acceptedEvents,\n }),\n };\n }\n\n private parseRetryableAcknowledgement(\n input: Record<string, unknown>,\n ): WoodTraceAcknowledgementParseResult {\n const batchId = input.batchId;\n const retryAfterMs = input.retryAfterMs;\n if (typeof batchId !== 'string'\n || typeof input.reason !== 'string'\n || typeof retryAfterMs !== 'number'\n || !Number.isFinite(retryAfterMs)\n || retryAfterMs < 0) {\n return { ok: false, reason: 'Retryable trace acknowledgement is invalid' };\n }\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'retryable',\n batchId,\n reason: input.reason,\n retryAfterMs,\n }),\n };\n }\n\n private parseEvent(input: unknown): WoodTraceEventParseResult {\n if (!this.isRecord(input)) {\n return { kind: 'invalid', reason: 'Trace event is not an object' };\n }\n const hasValidIdentity = this.hasValidEventIdentity(input);\n const hasValidTiming = this.hasValidEventTiming(input);\n if (!hasValidIdentity || !hasValidTiming) {\n return { kind: 'invalid', reason: 'Trace event identity or timing is invalid' };\n }\n if (input.payload !== undefined && !this.isRecord(input.payload)) {\n return { kind: 'invalid', reason: 'Trace event payload is invalid' };\n }\n return {\n kind: 'valid',\n event: this.snapshotEvent({\n source: input.source,\n type: input.type,\n level: input.level,\n process: 'renderer',\n timestamp: input.timestamp,\n traceSeq: input.traceSeq,\n ...(typeof input.message === 'string' ? { message: input.message } : {}),\n ...(this.isConversationId(input.conversationId) ? { conversationId: input.conversationId } : {}),\n ...(input.payload ? { payload: input.payload } : {}),\n ...(typeof input.windowId === 'string' ? { windowId: input.windowId } : {}),\n ...(typeof input.webContentsId === 'number' && Number.isFinite(input.webContentsId)\n ? { webContentsId: input.webContentsId }\n : {}),\n ...(typeof input.routeKey === 'string' ? { routeKey: input.routeKey } : {}),\n ...(typeof input.harnessId === 'string' ? { harnessId: input.harnessId } : {}),\n }),\n };\n }\n\n private hasValidEventIdentity(input: Record<string, unknown>): input is Record<string, unknown> & {\n source: string;\n type: string;\n level: string;\n process: 'renderer';\n } {\n return typeof input.source === 'string'\n && input.source.trim().length > 0\n && typeof input.type === 'string'\n && input.type.trim().length > 0\n && typeof input.level === 'string'\n && input.level.trim().length > 0\n && input.process === 'renderer';\n }\n\n private hasValidEventTiming(input: Record<string, unknown>): input is Record<string, unknown> & {\n timestamp: string;\n traceSeq: number;\n } {\n return typeof input.timestamp === 'string'\n && Number.isFinite(Date.parse(input.timestamp))\n && typeof input.traceSeq === 'number'\n && Number.isSafeInteger(input.traceSeq)\n && input.traceSeq >= 1;\n }\n\n private parseEvents(input: unknown): WoodTraceEventsParseResult {\n if (!Array.isArray(input) || input.length === 0 || input.length > MAX_BATCH_EVENTS) {\n return { kind: 'invalid', reason: 'Trace batch events are invalid' };\n }\n const events: WoodRendererTraceEvent[] = [];\n for (const rawEvent of input) {\n const parsedEvent = this.parseEvent(rawEvent);\n if (parsedEvent.kind === 'invalid') {\n return parsedEvent;\n }\n events.push(parsedEvent.event);\n }\n return { kind: 'valid', events: Object.freeze(events) };\n }\n\n private parseSequenceRange(\n input: Record<string, unknown>,\n events: readonly WoodRendererTraceEvent[],\n ): { kind: 'invalid'; reason: string } | { kind: 'valid'; sequenceStart: number; sequenceEnd: number } {\n const sequenceStart = input.sequenceStart;\n const sequenceEnd = input.sequenceEnd;\n if (typeof sequenceStart !== 'number' || typeof sequenceEnd !== 'number') {\n return { kind: 'invalid', reason: 'Trace batch sequence range is invalid' };\n }\n const firstEvent = events[0];\n const lastEvent = events[events.length - 1];\n const hasInvalidRange = !Number.isSafeInteger(sequenceStart)\n || sequenceStart < 0\n || !Number.isSafeInteger(sequenceEnd)\n || !firstEvent\n || !lastEvent\n || firstEvent.traceSeq !== sequenceStart + 1\n || lastEvent.traceSeq !== sequenceEnd + 1;\n if (hasInvalidRange) {\n return { kind: 'invalid', reason: 'Trace batch sequence range does not match its events' };\n }\n return { kind: 'valid', sequenceStart, sequenceEnd };\n }\n\n private snapshotEvent(event: WoodRendererTraceEvent): WoodRendererTraceEvent {\n return Object.freeze({\n ...event,\n ...(event.payload ? { payload: Object.freeze({ ...event.payload }) } : {}),\n });\n }\n\n private validateIdentity(input: Record<string, unknown>): WoodTraceIdentityValidationResult {\n if (input.protocolVersion !== 1) {\n return { kind: 'invalid', reason: 'Trace batch protocol version is unsupported' };\n }\n if (typeof input.producerId !== 'string' || input.producerId.trim().length === 0) {\n return { kind: 'invalid', reason: 'Trace batch producer identity is invalid' };\n }\n if (typeof input.batchId !== 'string' || input.batchId.trim().length === 0) {\n return { kind: 'invalid', reason: 'Trace batch identity is invalid' };\n }\n return { kind: 'valid' };\n }\n\n private isConversationId(value: unknown): value is string | number {\n return typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value));\n }\n\n private isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/tracing/wood_trace_batch_contract.ts"],"sourcesContent":["import type {\n WoodRendererTraceEvent,\n WoodTraceAcknowledgementParseResult,\n WoodTraceBatch,\n WoodTraceBatchAcknowledgement,\n WoodTraceBatchParseResult,\n WoodTraceEventParseResult,\n WoodTraceEventsParseResult,\n WoodTraceIdentityValidationResult,\n} from './types/wood_trace_batch.types.js';\n\nconst MAX_BATCH_EVENTS = 256;\n\nexport class WoodTraceBatchContract {\n create(\n producerId: string,\n sequenceStart: number,\n events: readonly WoodRendererTraceEvent[],\n ): WoodTraceBatch {\n const snapshots = events.map((event) => this.snapshotEvent(event));\n const last = snapshots[snapshots.length - 1];\n const sequenceEnd = last ? last.traceSeq - 1 : sequenceStart - 1;\n return Object.freeze({\n kind: 'wood.trace.batch',\n protocolVersion: 1,\n producerId,\n batchId: `wtb1:${producerId}:${sequenceStart}-${sequenceEnd}`,\n sequenceStart,\n sequenceEnd,\n events: Object.freeze(snapshots),\n });\n }\n\n parse(input: unknown): WoodTraceBatchParseResult {\n if (!this.isRecord(input) || input.kind !== 'wood.trace.batch') {\n return { kind: 'not-batch' };\n }\n\n const batchId = typeof input.batchId === 'string' ? input.batchId : null;\n const identity = this.validateIdentity(input);\n if (identity.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: identity.reason };\n }\n const producerId = input.producerId;\n if (typeof producerId !== 'string') {\n return { kind: 'invalid', batchId, reason: 'Trace batch producer identity is invalid' };\n }\n\n const parsedEvents = this.parseEvents(input.events);\n if (parsedEvents.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: parsedEvents.reason };\n }\n const events = parsedEvents.events;\n\n const parsedSequenceRange = this.parseSequenceRange(input, events);\n if (parsedSequenceRange.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: parsedSequenceRange.reason };\n }\n const { sequenceStart, sequenceEnd } = parsedSequenceRange;\n const hasTraceSequenceMismatch = events.some((event, index) => {\n const previous = events[index - 1];\n return previous !== undefined && event.traceSeq <= previous.traceSeq;\n });\n if (hasTraceSequenceMismatch) {\n return { kind: 'invalid', batchId, reason: 'Trace event sequences are not strictly increasing' };\n }\n const expectedBatchId = `wtb1:${producerId}:${sequenceStart}-${sequenceEnd}`;\n if (input.batchId !== expectedBatchId) {\n return { kind: 'invalid', batchId, reason: 'Trace batch identity does not match its sequence range' };\n }\n\n return {\n kind: 'valid',\n batch: this.create(producerId, sequenceStart, events),\n };\n }\n\n parseAcknowledgement(input: unknown): WoodTraceAcknowledgementParseResult {\n if (!this.isRecord(input) || typeof input.kind !== 'string' || typeof input.batchId !== 'string') {\n return { ok: false, reason: 'Trace batch acknowledgement framing is invalid' };\n }\n\n if (input.kind === 'committed') {\n return this.parseCommittedAcknowledgement(input);\n }\n if (input.kind === 'retryable') {\n return this.parseRetryableAcknowledgement(input);\n }\n if (input.kind === 'rejected' && typeof input.reason === 'string') {\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'rejected',\n batchId: input.batchId,\n reason: input.reason,\n }),\n };\n }\n return { ok: false, reason: 'Trace batch acknowledgement kind is invalid' };\n }\n\n private parseCommittedAcknowledgement(\n input: Record<string, unknown>,\n ): WoodTraceAcknowledgementParseResult {\n const batchId = input.batchId;\n const committedAtMs = input.committedAtMs;\n const acceptedEvents = input.acceptedEvents;\n const validNumbers = typeof batchId === 'string'\n && typeof committedAtMs === 'number'\n && Number.isFinite(committedAtMs)\n && typeof acceptedEvents === 'number'\n && Number.isSafeInteger(acceptedEvents)\n && acceptedEvents >= 0;\n if (!validNumbers) {\n return { ok: false, reason: 'Committed trace acknowledgement is invalid' };\n }\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'committed',\n batchId,\n committedAtMs,\n acceptedEvents,\n }),\n };\n }\n\n private parseRetryableAcknowledgement(\n input: Record<string, unknown>,\n ): WoodTraceAcknowledgementParseResult {\n const batchId = input.batchId;\n const retryAfterMs = input.retryAfterMs;\n if (typeof batchId !== 'string'\n || typeof input.reason !== 'string'\n || typeof retryAfterMs !== 'number'\n || !Number.isFinite(retryAfterMs)\n || retryAfterMs < 0) {\n return { ok: false, reason: 'Retryable trace acknowledgement is invalid' };\n }\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'retryable',\n batchId,\n reason: input.reason,\n retryAfterMs,\n }),\n };\n }\n\n private parseEvent(input: unknown): WoodTraceEventParseResult {\n if (!this.isRecord(input)) {\n return { kind: 'invalid', reason: 'Trace event is not an object' };\n }\n const hasValidIdentity = this.hasValidEventIdentity(input);\n const hasValidTiming = this.hasValidEventTiming(input);\n if (!hasValidIdentity || !hasValidTiming) {\n return { kind: 'invalid', reason: 'Trace event identity or timing is invalid' };\n }\n if (input.payload !== undefined && !this.isRecord(input.payload)) {\n return { kind: 'invalid', reason: 'Trace event payload is invalid' };\n }\n return {\n kind: 'valid',\n event: this.snapshotEvent({\n source: input.source,\n type: input.type,\n level: input.level,\n process: 'renderer',\n timestamp: input.timestamp,\n traceSeq: input.traceSeq,\n // Durable identity passthrough: never a validation failure when absent.\n ...(typeof input.producerId === 'string' && input.producerId.trim().length > 0\n ? { producerId: input.producerId }\n : {}),\n ...(typeof input.message === 'string' ? { message: input.message } : {}),\n ...(this.isConversationId(input.conversationId) ? { conversationId: input.conversationId } : {}),\n ...(input.payload ? { payload: input.payload } : {}),\n ...(typeof input.windowId === 'string' ? { windowId: input.windowId } : {}),\n ...(typeof input.webContentsId === 'number' && Number.isFinite(input.webContentsId)\n ? { webContentsId: input.webContentsId }\n : {}),\n ...(typeof input.routeKey === 'string' ? { routeKey: input.routeKey } : {}),\n ...(typeof input.harnessId === 'string' ? { harnessId: input.harnessId } : {}),\n }),\n };\n }\n\n private hasValidEventIdentity(input: Record<string, unknown>): input is Record<string, unknown> & {\n source: string;\n type: string;\n level: string;\n process: 'renderer';\n } {\n return typeof input.source === 'string'\n && input.source.trim().length > 0\n && typeof input.type === 'string'\n && input.type.trim().length > 0\n && typeof input.level === 'string'\n && input.level.trim().length > 0\n && input.process === 'renderer';\n }\n\n private hasValidEventTiming(input: Record<string, unknown>): input is Record<string, unknown> & {\n timestamp: string;\n traceSeq: number;\n } {\n return typeof input.timestamp === 'string'\n && Number.isFinite(Date.parse(input.timestamp))\n && typeof input.traceSeq === 'number'\n && Number.isSafeInteger(input.traceSeq)\n && input.traceSeq >= 1;\n }\n\n private parseEvents(input: unknown): WoodTraceEventsParseResult {\n if (!Array.isArray(input) || input.length === 0 || input.length > MAX_BATCH_EVENTS) {\n return { kind: 'invalid', reason: 'Trace batch events are invalid' };\n }\n const events: WoodRendererTraceEvent[] = [];\n for (const rawEvent of input) {\n const parsedEvent = this.parseEvent(rawEvent);\n if (parsedEvent.kind === 'invalid') {\n return parsedEvent;\n }\n events.push(parsedEvent.event);\n }\n return { kind: 'valid', events: Object.freeze(events) };\n }\n\n private parseSequenceRange(\n input: Record<string, unknown>,\n events: readonly WoodRendererTraceEvent[],\n ): { kind: 'invalid'; reason: string } | { kind: 'valid'; sequenceStart: number; sequenceEnd: number } {\n const sequenceStart = input.sequenceStart;\n const sequenceEnd = input.sequenceEnd;\n if (typeof sequenceStart !== 'number' || typeof sequenceEnd !== 'number') {\n return { kind: 'invalid', reason: 'Trace batch sequence range is invalid' };\n }\n const firstEvent = events[0];\n const lastEvent = events[events.length - 1];\n const hasInvalidRange = !Number.isSafeInteger(sequenceStart)\n || sequenceStart < 0\n || !Number.isSafeInteger(sequenceEnd)\n || !firstEvent\n || !lastEvent\n || firstEvent.traceSeq !== sequenceStart + 1\n || lastEvent.traceSeq !== sequenceEnd + 1;\n if (hasInvalidRange) {\n return { kind: 'invalid', reason: 'Trace batch sequence range does not match its events' };\n }\n return { kind: 'valid', sequenceStart, sequenceEnd };\n }\n\n private snapshotEvent(event: WoodRendererTraceEvent): WoodRendererTraceEvent {\n return Object.freeze({\n ...event,\n ...(event.payload ? { payload: Object.freeze({ ...event.payload }) } : {}),\n });\n }\n\n private validateIdentity(input: Record<string, unknown>): WoodTraceIdentityValidationResult {\n if (input.protocolVersion !== 1) {\n return { kind: 'invalid', reason: 'Trace batch protocol version is unsupported' };\n }\n if (typeof input.producerId !== 'string' || input.producerId.trim().length === 0) {\n return { kind: 'invalid', reason: 'Trace batch producer identity is invalid' };\n }\n if (typeof input.batchId !== 'string' || input.batchId.trim().length === 0) {\n return { kind: 'invalid', reason: 'Trace batch identity is invalid' };\n }\n return { kind: 'valid' };\n }\n\n private isConversationId(value: unknown): value is string | number {\n return typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value));\n }\n\n private isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import { WoodRendererTraceEvent, WoodTraceBatch, WoodTraceBatchParseResult, WoodTraceAcknowledgementParseResult } from './types/wood_trace_batch.types.cjs';
2
2
  import '@noego/telemetry/core';
3
- import '../trace_hub-Cob54qRx.cjs';
3
+ import '../trace_hub-Cpo_nVze.cjs';
4
4
  import 'rxjs';
5
5
 
6
6
  declare class WoodTraceBatchContract {
@@ -1,6 +1,6 @@
1
1
  import { WoodRendererTraceEvent, WoodTraceBatch, WoodTraceBatchParseResult, WoodTraceAcknowledgementParseResult } from './types/wood_trace_batch.types.js';
2
2
  import '@noego/telemetry/core';
3
- import '../trace_hub-Cob54qRx.js';
3
+ import '../trace_hub-Cpo_nVze.js';
4
4
  import 'rxjs';
5
5
 
6
6
  declare class WoodTraceBatchContract {
@@ -130,6 +130,8 @@ class WoodTraceBatchContract {
130
130
  process: "renderer",
131
131
  timestamp: input.timestamp,
132
132
  traceSeq: input.traceSeq,
133
+ // Durable identity passthrough: never a validation failure when absent.
134
+ ...typeof input.producerId === "string" && input.producerId.trim().length > 0 ? { producerId: input.producerId } : {},
133
135
  ...typeof input.message === "string" ? { message: input.message } : {},
134
136
  ...this.isConversationId(input.conversationId) ? { conversationId: input.conversationId } : {},
135
137
  ...input.payload ? { payload: input.payload } : {},
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/tracing/wood_trace_batch_contract.ts"],"sourcesContent":["import type {\n WoodRendererTraceEvent,\n WoodTraceAcknowledgementParseResult,\n WoodTraceBatch,\n WoodTraceBatchAcknowledgement,\n WoodTraceBatchParseResult,\n WoodTraceEventParseResult,\n WoodTraceEventsParseResult,\n WoodTraceIdentityValidationResult,\n} from './types/wood_trace_batch.types.js';\n\nconst MAX_BATCH_EVENTS = 256;\n\nexport class WoodTraceBatchContract {\n create(\n producerId: string,\n sequenceStart: number,\n events: readonly WoodRendererTraceEvent[],\n ): WoodTraceBatch {\n const snapshots = events.map((event) => this.snapshotEvent(event));\n const last = snapshots[snapshots.length - 1];\n const sequenceEnd = last ? last.traceSeq - 1 : sequenceStart - 1;\n return Object.freeze({\n kind: 'wood.trace.batch',\n protocolVersion: 1,\n producerId,\n batchId: `wtb1:${producerId}:${sequenceStart}-${sequenceEnd}`,\n sequenceStart,\n sequenceEnd,\n events: Object.freeze(snapshots),\n });\n }\n\n parse(input: unknown): WoodTraceBatchParseResult {\n if (!this.isRecord(input) || input.kind !== 'wood.trace.batch') {\n return { kind: 'not-batch' };\n }\n\n const batchId = typeof input.batchId === 'string' ? input.batchId : null;\n const identity = this.validateIdentity(input);\n if (identity.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: identity.reason };\n }\n const producerId = input.producerId;\n if (typeof producerId !== 'string') {\n return { kind: 'invalid', batchId, reason: 'Trace batch producer identity is invalid' };\n }\n\n const parsedEvents = this.parseEvents(input.events);\n if (parsedEvents.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: parsedEvents.reason };\n }\n const events = parsedEvents.events;\n\n const parsedSequenceRange = this.parseSequenceRange(input, events);\n if (parsedSequenceRange.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: parsedSequenceRange.reason };\n }\n const { sequenceStart, sequenceEnd } = parsedSequenceRange;\n const hasTraceSequenceMismatch = events.some((event, index) => {\n const previous = events[index - 1];\n return previous !== undefined && event.traceSeq <= previous.traceSeq;\n });\n if (hasTraceSequenceMismatch) {\n return { kind: 'invalid', batchId, reason: 'Trace event sequences are not strictly increasing' };\n }\n const expectedBatchId = `wtb1:${producerId}:${sequenceStart}-${sequenceEnd}`;\n if (input.batchId !== expectedBatchId) {\n return { kind: 'invalid', batchId, reason: 'Trace batch identity does not match its sequence range' };\n }\n\n return {\n kind: 'valid',\n batch: this.create(producerId, sequenceStart, events),\n };\n }\n\n parseAcknowledgement(input: unknown): WoodTraceAcknowledgementParseResult {\n if (!this.isRecord(input) || typeof input.kind !== 'string' || typeof input.batchId !== 'string') {\n return { ok: false, reason: 'Trace batch acknowledgement framing is invalid' };\n }\n\n if (input.kind === 'committed') {\n return this.parseCommittedAcknowledgement(input);\n }\n if (input.kind === 'retryable') {\n return this.parseRetryableAcknowledgement(input);\n }\n if (input.kind === 'rejected' && typeof input.reason === 'string') {\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'rejected',\n batchId: input.batchId,\n reason: input.reason,\n }),\n };\n }\n return { ok: false, reason: 'Trace batch acknowledgement kind is invalid' };\n }\n\n private parseCommittedAcknowledgement(\n input: Record<string, unknown>,\n ): WoodTraceAcknowledgementParseResult {\n const batchId = input.batchId;\n const committedAtMs = input.committedAtMs;\n const acceptedEvents = input.acceptedEvents;\n const validNumbers = typeof batchId === 'string'\n && typeof committedAtMs === 'number'\n && Number.isFinite(committedAtMs)\n && typeof acceptedEvents === 'number'\n && Number.isSafeInteger(acceptedEvents)\n && acceptedEvents >= 0;\n if (!validNumbers) {\n return { ok: false, reason: 'Committed trace acknowledgement is invalid' };\n }\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'committed',\n batchId,\n committedAtMs,\n acceptedEvents,\n }),\n };\n }\n\n private parseRetryableAcknowledgement(\n input: Record<string, unknown>,\n ): WoodTraceAcknowledgementParseResult {\n const batchId = input.batchId;\n const retryAfterMs = input.retryAfterMs;\n if (typeof batchId !== 'string'\n || typeof input.reason !== 'string'\n || typeof retryAfterMs !== 'number'\n || !Number.isFinite(retryAfterMs)\n || retryAfterMs < 0) {\n return { ok: false, reason: 'Retryable trace acknowledgement is invalid' };\n }\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'retryable',\n batchId,\n reason: input.reason,\n retryAfterMs,\n }),\n };\n }\n\n private parseEvent(input: unknown): WoodTraceEventParseResult {\n if (!this.isRecord(input)) {\n return { kind: 'invalid', reason: 'Trace event is not an object' };\n }\n const hasValidIdentity = this.hasValidEventIdentity(input);\n const hasValidTiming = this.hasValidEventTiming(input);\n if (!hasValidIdentity || !hasValidTiming) {\n return { kind: 'invalid', reason: 'Trace event identity or timing is invalid' };\n }\n if (input.payload !== undefined && !this.isRecord(input.payload)) {\n return { kind: 'invalid', reason: 'Trace event payload is invalid' };\n }\n return {\n kind: 'valid',\n event: this.snapshotEvent({\n source: input.source,\n type: input.type,\n level: input.level,\n process: 'renderer',\n timestamp: input.timestamp,\n traceSeq: input.traceSeq,\n ...(typeof input.message === 'string' ? { message: input.message } : {}),\n ...(this.isConversationId(input.conversationId) ? { conversationId: input.conversationId } : {}),\n ...(input.payload ? { payload: input.payload } : {}),\n ...(typeof input.windowId === 'string' ? { windowId: input.windowId } : {}),\n ...(typeof input.webContentsId === 'number' && Number.isFinite(input.webContentsId)\n ? { webContentsId: input.webContentsId }\n : {}),\n ...(typeof input.routeKey === 'string' ? { routeKey: input.routeKey } : {}),\n ...(typeof input.harnessId === 'string' ? { harnessId: input.harnessId } : {}),\n }),\n };\n }\n\n private hasValidEventIdentity(input: Record<string, unknown>): input is Record<string, unknown> & {\n source: string;\n type: string;\n level: string;\n process: 'renderer';\n } {\n return typeof input.source === 'string'\n && input.source.trim().length > 0\n && typeof input.type === 'string'\n && input.type.trim().length > 0\n && typeof input.level === 'string'\n && input.level.trim().length > 0\n && input.process === 'renderer';\n }\n\n private hasValidEventTiming(input: Record<string, unknown>): input is Record<string, unknown> & {\n timestamp: string;\n traceSeq: number;\n } {\n return typeof input.timestamp === 'string'\n && Number.isFinite(Date.parse(input.timestamp))\n && typeof input.traceSeq === 'number'\n && Number.isSafeInteger(input.traceSeq)\n && input.traceSeq >= 1;\n }\n\n private parseEvents(input: unknown): WoodTraceEventsParseResult {\n if (!Array.isArray(input) || input.length === 0 || input.length > MAX_BATCH_EVENTS) {\n return { kind: 'invalid', reason: 'Trace batch events are invalid' };\n }\n const events: WoodRendererTraceEvent[] = [];\n for (const rawEvent of input) {\n const parsedEvent = this.parseEvent(rawEvent);\n if (parsedEvent.kind === 'invalid') {\n return parsedEvent;\n }\n events.push(parsedEvent.event);\n }\n return { kind: 'valid', events: Object.freeze(events) };\n }\n\n private parseSequenceRange(\n input: Record<string, unknown>,\n events: readonly WoodRendererTraceEvent[],\n ): { kind: 'invalid'; reason: string } | { kind: 'valid'; sequenceStart: number; sequenceEnd: number } {\n const sequenceStart = input.sequenceStart;\n const sequenceEnd = input.sequenceEnd;\n if (typeof sequenceStart !== 'number' || typeof sequenceEnd !== 'number') {\n return { kind: 'invalid', reason: 'Trace batch sequence range is invalid' };\n }\n const firstEvent = events[0];\n const lastEvent = events[events.length - 1];\n const hasInvalidRange = !Number.isSafeInteger(sequenceStart)\n || sequenceStart < 0\n || !Number.isSafeInteger(sequenceEnd)\n || !firstEvent\n || !lastEvent\n || firstEvent.traceSeq !== sequenceStart + 1\n || lastEvent.traceSeq !== sequenceEnd + 1;\n if (hasInvalidRange) {\n return { kind: 'invalid', reason: 'Trace batch sequence range does not match its events' };\n }\n return { kind: 'valid', sequenceStart, sequenceEnd };\n }\n\n private snapshotEvent(event: WoodRendererTraceEvent): WoodRendererTraceEvent {\n return Object.freeze({\n ...event,\n ...(event.payload ? { payload: Object.freeze({ ...event.payload }) } : {}),\n });\n }\n\n private validateIdentity(input: Record<string, unknown>): WoodTraceIdentityValidationResult {\n if (input.protocolVersion !== 1) {\n return { kind: 'invalid', reason: 'Trace batch protocol version is unsupported' };\n }\n if (typeof input.producerId !== 'string' || input.producerId.trim().length === 0) {\n return { kind: 'invalid', reason: 'Trace batch producer identity is invalid' };\n }\n if (typeof input.batchId !== 'string' || input.batchId.trim().length === 0) {\n return { kind: 'invalid', reason: 'Trace batch identity is invalid' };\n }\n return { kind: 'valid' };\n }\n\n private isConversationId(value: unknown): value is string | number {\n return typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value));\n }\n\n private isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n }\n}\n"],"mappings":"AAWA,MAAM,mBAAmB;AAElB,MAAM,uBAAuB;AAAA,EAClC,OACE,YACA,eACA,QACgB;AAChB,UAAM,YAAY,OAAO,IAAI,CAAC,UAAU,KAAK,cAAc,KAAK,CAAC;AACjE,UAAM,OAAO,UAAU,UAAU,SAAS,CAAC;AAC3C,UAAM,cAAc,OAAO,KAAK,WAAW,IAAI,gBAAgB;AAC/D,WAAO,OAAO,OAAO;AAAA,MACnB,MAAM;AAAA,MACN,iBAAiB;AAAA,MACjB;AAAA,MACA,SAAS,QAAQ,UAAU,IAAI,aAAa,IAAI,WAAW;AAAA,MAC3D;AAAA,MACA;AAAA,MACA,QAAQ,OAAO,OAAO,SAAS;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAA2C;AAC/C,QAAI,CAAC,KAAK,SAAS,KAAK,KAAK,MAAM,SAAS,oBAAoB;AAC9D,aAAO,EAAE,MAAM,YAAY;AAAA,IAC7B;AAEA,UAAM,UAAU,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU;AACpE,UAAM,WAAW,KAAK,iBAAiB,KAAK;AAC5C,QAAI,SAAS,SAAS,WAAW;AAC/B,aAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,SAAS,OAAO;AAAA,IAC7D;AACA,UAAM,aAAa,MAAM;AACzB,QAAI,OAAO,eAAe,UAAU;AAClC,aAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,2CAA2C;AAAA,IACxF;AAEA,UAAM,eAAe,KAAK,YAAY,MAAM,MAAM;AAClD,QAAI,aAAa,SAAS,WAAW;AACnC,aAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,aAAa,OAAO;AAAA,IACjE;AACA,UAAM,SAAS,aAAa;AAE5B,UAAM,sBAAsB,KAAK,mBAAmB,OAAO,MAAM;AACjE,QAAI,oBAAoB,SAAS,WAAW;AAC1C,aAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,oBAAoB,OAAO;AAAA,IACxE;AACA,UAAM,EAAE,eAAe,YAAY,IAAI;AACvC,UAAM,2BAA2B,OAAO,KAAK,CAAC,OAAO,UAAU;AAC7D,YAAM,WAAW,OAAO,QAAQ,CAAC;AACjC,aAAO,aAAa,UAAa,MAAM,YAAY,SAAS;AAAA,IAC9D,CAAC;AACD,QAAI,0BAA0B;AAC5B,aAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,oDAAoD;AAAA,IACjG;AACA,UAAM,kBAAkB,QAAQ,UAAU,IAAI,aAAa,IAAI,WAAW;AAC1E,QAAI,MAAM,YAAY,iBAAiB;AACrC,aAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,yDAAyD;AAAA,IACtG;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,KAAK,OAAO,YAAY,eAAe,MAAM;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,qBAAqB,OAAqD;AACxE,QAAI,CAAC,KAAK,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS,YAAY,OAAO,MAAM,YAAY,UAAU;AAChG,aAAO,EAAE,IAAI,OAAO,QAAQ,iDAAiD;AAAA,IAC/E;AAEA,QAAI,MAAM,SAAS,aAAa;AAC9B,aAAO,KAAK,8BAA8B,KAAK;AAAA,IACjD;AACA,QAAI,MAAM,SAAS,aAAa;AAC9B,aAAO,KAAK,8BAA8B,KAAK;AAAA,IACjD;AACA,QAAI,MAAM,SAAS,cAAc,OAAO,MAAM,WAAW,UAAU;AACjE,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,iBAAiB,OAAO,OAAO;AAAA,UAC7B,MAAM;AAAA,UACN,SAAS,MAAM;AAAA,UACf,QAAQ,MAAM;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO,EAAE,IAAI,OAAO,QAAQ,8CAA8C;AAAA,EAC5E;AAAA,EAEQ,8BACN,OACqC;AACrC,UAAM,UAAU,MAAM;AACtB,UAAM,gBAAgB,MAAM;AAC5B,UAAM,iBAAiB,MAAM;AAC7B,UAAM,eAAe,OAAO,YAAY,YACnC,OAAO,kBAAkB,YACzB,OAAO,SAAS,aAAa,KAC7B,OAAO,mBAAmB,YAC1B,OAAO,cAAc,cAAc,KACnC,kBAAkB;AACvB,QAAI,CAAC,cAAc;AACjB,aAAO,EAAE,IAAI,OAAO,QAAQ,6CAA6C;AAAA,IAC3E;AACA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,iBAAiB,OAAO,OAAO;AAAA,QAC7B,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,8BACN,OACqC;AACrC,UAAM,UAAU,MAAM;AACtB,UAAM,eAAe,MAAM;AAC3B,QAAI,OAAO,YAAY,YAClB,OAAO,MAAM,WAAW,YACxB,OAAO,iBAAiB,YACxB,CAAC,OAAO,SAAS,YAAY,KAC7B,eAAe,GAAG;AACrB,aAAO,EAAE,IAAI,OAAO,QAAQ,6CAA6C;AAAA,IAC3E;AACA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,iBAAiB,OAAO,OAAO;AAAA,QAC7B,MAAM;AAAA,QACN;AAAA,QACA,QAAQ,MAAM;AAAA,QACd;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,WAAW,OAA2C;AAC5D,QAAI,CAAC,KAAK,SAAS,KAAK,GAAG;AACzB,aAAO,EAAE,MAAM,WAAW,QAAQ,+BAA+B;AAAA,IACnE;AACA,UAAM,mBAAmB,KAAK,sBAAsB,KAAK;AACzD,UAAM,iBAAiB,KAAK,oBAAoB,KAAK;AACrD,QAAI,CAAC,oBAAoB,CAAC,gBAAgB;AACxC,aAAO,EAAE,MAAM,WAAW,QAAQ,4CAA4C;AAAA,IAChF;AACA,QAAI,MAAM,YAAY,UAAa,CAAC,KAAK,SAAS,MAAM,OAAO,GAAG;AAChE,aAAO,EAAE,MAAM,WAAW,QAAQ,iCAAiC;AAAA,IACrE;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,KAAK,cAAc;AAAA,QACxB,QAAQ,MAAM;AAAA,QACd,MAAM,MAAM;AAAA,QACZ,OAAO,MAAM;AAAA,QACb,SAAS;AAAA,QACT,WAAW,MAAM;AAAA,QACjB,UAAU,MAAM;AAAA,QAChB,GAAI,OAAO,MAAM,YAAY,WAAW,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,QACtE,GAAI,KAAK,iBAAiB,MAAM,cAAc,IAAI,EAAE,gBAAgB,MAAM,eAAe,IAAI,CAAC;AAAA,QAC9F,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,QAClD,GAAI,OAAO,MAAM,aAAa,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,QACzE,GAAI,OAAO,MAAM,kBAAkB,YAAY,OAAO,SAAS,MAAM,aAAa,IAC9E,EAAE,eAAe,MAAM,cAAc,IACrC,CAAC;AAAA,QACL,GAAI,OAAO,MAAM,aAAa,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,QACzE,GAAI,OAAO,MAAM,cAAc,WAAW,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,MAC9E,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,sBAAsB,OAK5B;AACA,WAAO,OAAO,MAAM,WAAW,YAC1B,MAAM,OAAO,KAAK,EAAE,SAAS,KAC7B,OAAO,MAAM,SAAS,YACtB,MAAM,KAAK,KAAK,EAAE,SAAS,KAC3B,OAAO,MAAM,UAAU,YACvB,MAAM,MAAM,KAAK,EAAE,SAAS,KAC5B,MAAM,YAAY;AAAA,EACzB;AAAA,EAEQ,oBAAoB,OAG1B;AACA,WAAO,OAAO,MAAM,cAAc,YAC7B,OAAO,SAAS,KAAK,MAAM,MAAM,SAAS,CAAC,KAC3C,OAAO,MAAM,aAAa,YAC1B,OAAO,cAAc,MAAM,QAAQ,KACnC,MAAM,YAAY;AAAA,EACzB;AAAA,EAEQ,YAAY,OAA4C;AAC9D,QAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,KAAK,MAAM,SAAS,kBAAkB;AAClF,aAAO,EAAE,MAAM,WAAW,QAAQ,iCAAiC;AAAA,IACrE;AACA,UAAM,SAAmC,CAAC;AAC1C,eAAW,YAAY,OAAO;AAC5B,YAAM,cAAc,KAAK,WAAW,QAAQ;AAC5C,UAAI,YAAY,SAAS,WAAW;AAClC,eAAO;AAAA,MACT;AACA,aAAO,KAAK,YAAY,KAAK;AAAA,IAC/B;AACA,WAAO,EAAE,MAAM,SAAS,QAAQ,OAAO,OAAO,MAAM,EAAE;AAAA,EACxD;AAAA,EAEQ,mBACN,OACA,QACqG;AACrG,UAAM,gBAAgB,MAAM;AAC5B,UAAM,cAAc,MAAM;AAC1B,QAAI,OAAO,kBAAkB,YAAY,OAAO,gBAAgB,UAAU;AACxE,aAAO,EAAE,MAAM,WAAW,QAAQ,wCAAwC;AAAA,IAC5E;AACA,UAAM,aAAa,OAAO,CAAC;AAC3B,UAAM,YAAY,OAAO,OAAO,SAAS,CAAC;AAC1C,UAAM,kBAAkB,CAAC,OAAO,cAAc,aAAa,KACtD,gBAAgB,KAChB,CAAC,OAAO,cAAc,WAAW,KACjC,CAAC,cACD,CAAC,aACD,WAAW,aAAa,gBAAgB,KACxC,UAAU,aAAa,cAAc;AAC1C,QAAI,iBAAiB;AACnB,aAAO,EAAE,MAAM,WAAW,QAAQ,uDAAuD;AAAA,IAC3F;AACA,WAAO,EAAE,MAAM,SAAS,eAAe,YAAY;AAAA,EACrD;AAAA,EAEQ,cAAc,OAAuD;AAC3E,WAAO,OAAO,OAAO;AAAA,MACnB,GAAG;AAAA,MACH,GAAI,MAAM,UAAU,EAAE,SAAS,OAAO,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,EAAE,IAAI,CAAC;AAAA,IAC1E,CAAC;AAAA,EACH;AAAA,EAEQ,iBAAiB,OAAmE;AAC1F,QAAI,MAAM,oBAAoB,GAAG;AAC/B,aAAO,EAAE,MAAM,WAAW,QAAQ,8CAA8C;AAAA,IAClF;AACA,QAAI,OAAO,MAAM,eAAe,YAAY,MAAM,WAAW,KAAK,EAAE,WAAW,GAAG;AAChF,aAAO,EAAE,MAAM,WAAW,QAAQ,2CAA2C;AAAA,IAC/E;AACA,QAAI,OAAO,MAAM,YAAY,YAAY,MAAM,QAAQ,KAAK,EAAE,WAAW,GAAG;AAC1E,aAAO,EAAE,MAAM,WAAW,QAAQ,kCAAkC;AAAA,IACtE;AACA,WAAO,EAAE,MAAM,QAAQ;AAAA,EACzB;AAAA,EAEQ,iBAAiB,OAA0C;AACjE,WAAO,OAAO,UAAU,YAAa,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAAA,EACzF;AAAA,EAEQ,SAAS,OAAkD;AACjE,WAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA,EAC5E;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/tracing/wood_trace_batch_contract.ts"],"sourcesContent":["import type {\n WoodRendererTraceEvent,\n WoodTraceAcknowledgementParseResult,\n WoodTraceBatch,\n WoodTraceBatchAcknowledgement,\n WoodTraceBatchParseResult,\n WoodTraceEventParseResult,\n WoodTraceEventsParseResult,\n WoodTraceIdentityValidationResult,\n} from './types/wood_trace_batch.types.js';\n\nconst MAX_BATCH_EVENTS = 256;\n\nexport class WoodTraceBatchContract {\n create(\n producerId: string,\n sequenceStart: number,\n events: readonly WoodRendererTraceEvent[],\n ): WoodTraceBatch {\n const snapshots = events.map((event) => this.snapshotEvent(event));\n const last = snapshots[snapshots.length - 1];\n const sequenceEnd = last ? last.traceSeq - 1 : sequenceStart - 1;\n return Object.freeze({\n kind: 'wood.trace.batch',\n protocolVersion: 1,\n producerId,\n batchId: `wtb1:${producerId}:${sequenceStart}-${sequenceEnd}`,\n sequenceStart,\n sequenceEnd,\n events: Object.freeze(snapshots),\n });\n }\n\n parse(input: unknown): WoodTraceBatchParseResult {\n if (!this.isRecord(input) || input.kind !== 'wood.trace.batch') {\n return { kind: 'not-batch' };\n }\n\n const batchId = typeof input.batchId === 'string' ? input.batchId : null;\n const identity = this.validateIdentity(input);\n if (identity.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: identity.reason };\n }\n const producerId = input.producerId;\n if (typeof producerId !== 'string') {\n return { kind: 'invalid', batchId, reason: 'Trace batch producer identity is invalid' };\n }\n\n const parsedEvents = this.parseEvents(input.events);\n if (parsedEvents.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: parsedEvents.reason };\n }\n const events = parsedEvents.events;\n\n const parsedSequenceRange = this.parseSequenceRange(input, events);\n if (parsedSequenceRange.kind === 'invalid') {\n return { kind: 'invalid', batchId, reason: parsedSequenceRange.reason };\n }\n const { sequenceStart, sequenceEnd } = parsedSequenceRange;\n const hasTraceSequenceMismatch = events.some((event, index) => {\n const previous = events[index - 1];\n return previous !== undefined && event.traceSeq <= previous.traceSeq;\n });\n if (hasTraceSequenceMismatch) {\n return { kind: 'invalid', batchId, reason: 'Trace event sequences are not strictly increasing' };\n }\n const expectedBatchId = `wtb1:${producerId}:${sequenceStart}-${sequenceEnd}`;\n if (input.batchId !== expectedBatchId) {\n return { kind: 'invalid', batchId, reason: 'Trace batch identity does not match its sequence range' };\n }\n\n return {\n kind: 'valid',\n batch: this.create(producerId, sequenceStart, events),\n };\n }\n\n parseAcknowledgement(input: unknown): WoodTraceAcknowledgementParseResult {\n if (!this.isRecord(input) || typeof input.kind !== 'string' || typeof input.batchId !== 'string') {\n return { ok: false, reason: 'Trace batch acknowledgement framing is invalid' };\n }\n\n if (input.kind === 'committed') {\n return this.parseCommittedAcknowledgement(input);\n }\n if (input.kind === 'retryable') {\n return this.parseRetryableAcknowledgement(input);\n }\n if (input.kind === 'rejected' && typeof input.reason === 'string') {\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'rejected',\n batchId: input.batchId,\n reason: input.reason,\n }),\n };\n }\n return { ok: false, reason: 'Trace batch acknowledgement kind is invalid' };\n }\n\n private parseCommittedAcknowledgement(\n input: Record<string, unknown>,\n ): WoodTraceAcknowledgementParseResult {\n const batchId = input.batchId;\n const committedAtMs = input.committedAtMs;\n const acceptedEvents = input.acceptedEvents;\n const validNumbers = typeof batchId === 'string'\n && typeof committedAtMs === 'number'\n && Number.isFinite(committedAtMs)\n && typeof acceptedEvents === 'number'\n && Number.isSafeInteger(acceptedEvents)\n && acceptedEvents >= 0;\n if (!validNumbers) {\n return { ok: false, reason: 'Committed trace acknowledgement is invalid' };\n }\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'committed',\n batchId,\n committedAtMs,\n acceptedEvents,\n }),\n };\n }\n\n private parseRetryableAcknowledgement(\n input: Record<string, unknown>,\n ): WoodTraceAcknowledgementParseResult {\n const batchId = input.batchId;\n const retryAfterMs = input.retryAfterMs;\n if (typeof batchId !== 'string'\n || typeof input.reason !== 'string'\n || typeof retryAfterMs !== 'number'\n || !Number.isFinite(retryAfterMs)\n || retryAfterMs < 0) {\n return { ok: false, reason: 'Retryable trace acknowledgement is invalid' };\n }\n return {\n ok: true,\n acknowledgement: Object.freeze({\n kind: 'retryable',\n batchId,\n reason: input.reason,\n retryAfterMs,\n }),\n };\n }\n\n private parseEvent(input: unknown): WoodTraceEventParseResult {\n if (!this.isRecord(input)) {\n return { kind: 'invalid', reason: 'Trace event is not an object' };\n }\n const hasValidIdentity = this.hasValidEventIdentity(input);\n const hasValidTiming = this.hasValidEventTiming(input);\n if (!hasValidIdentity || !hasValidTiming) {\n return { kind: 'invalid', reason: 'Trace event identity or timing is invalid' };\n }\n if (input.payload !== undefined && !this.isRecord(input.payload)) {\n return { kind: 'invalid', reason: 'Trace event payload is invalid' };\n }\n return {\n kind: 'valid',\n event: this.snapshotEvent({\n source: input.source,\n type: input.type,\n level: input.level,\n process: 'renderer',\n timestamp: input.timestamp,\n traceSeq: input.traceSeq,\n // Durable identity passthrough: never a validation failure when absent.\n ...(typeof input.producerId === 'string' && input.producerId.trim().length > 0\n ? { producerId: input.producerId }\n : {}),\n ...(typeof input.message === 'string' ? { message: input.message } : {}),\n ...(this.isConversationId(input.conversationId) ? { conversationId: input.conversationId } : {}),\n ...(input.payload ? { payload: input.payload } : {}),\n ...(typeof input.windowId === 'string' ? { windowId: input.windowId } : {}),\n ...(typeof input.webContentsId === 'number' && Number.isFinite(input.webContentsId)\n ? { webContentsId: input.webContentsId }\n : {}),\n ...(typeof input.routeKey === 'string' ? { routeKey: input.routeKey } : {}),\n ...(typeof input.harnessId === 'string' ? { harnessId: input.harnessId } : {}),\n }),\n };\n }\n\n private hasValidEventIdentity(input: Record<string, unknown>): input is Record<string, unknown> & {\n source: string;\n type: string;\n level: string;\n process: 'renderer';\n } {\n return typeof input.source === 'string'\n && input.source.trim().length > 0\n && typeof input.type === 'string'\n && input.type.trim().length > 0\n && typeof input.level === 'string'\n && input.level.trim().length > 0\n && input.process === 'renderer';\n }\n\n private hasValidEventTiming(input: Record<string, unknown>): input is Record<string, unknown> & {\n timestamp: string;\n traceSeq: number;\n } {\n return typeof input.timestamp === 'string'\n && Number.isFinite(Date.parse(input.timestamp))\n && typeof input.traceSeq === 'number'\n && Number.isSafeInteger(input.traceSeq)\n && input.traceSeq >= 1;\n }\n\n private parseEvents(input: unknown): WoodTraceEventsParseResult {\n if (!Array.isArray(input) || input.length === 0 || input.length > MAX_BATCH_EVENTS) {\n return { kind: 'invalid', reason: 'Trace batch events are invalid' };\n }\n const events: WoodRendererTraceEvent[] = [];\n for (const rawEvent of input) {\n const parsedEvent = this.parseEvent(rawEvent);\n if (parsedEvent.kind === 'invalid') {\n return parsedEvent;\n }\n events.push(parsedEvent.event);\n }\n return { kind: 'valid', events: Object.freeze(events) };\n }\n\n private parseSequenceRange(\n input: Record<string, unknown>,\n events: readonly WoodRendererTraceEvent[],\n ): { kind: 'invalid'; reason: string } | { kind: 'valid'; sequenceStart: number; sequenceEnd: number } {\n const sequenceStart = input.sequenceStart;\n const sequenceEnd = input.sequenceEnd;\n if (typeof sequenceStart !== 'number' || typeof sequenceEnd !== 'number') {\n return { kind: 'invalid', reason: 'Trace batch sequence range is invalid' };\n }\n const firstEvent = events[0];\n const lastEvent = events[events.length - 1];\n const hasInvalidRange = !Number.isSafeInteger(sequenceStart)\n || sequenceStart < 0\n || !Number.isSafeInteger(sequenceEnd)\n || !firstEvent\n || !lastEvent\n || firstEvent.traceSeq !== sequenceStart + 1\n || lastEvent.traceSeq !== sequenceEnd + 1;\n if (hasInvalidRange) {\n return { kind: 'invalid', reason: 'Trace batch sequence range does not match its events' };\n }\n return { kind: 'valid', sequenceStart, sequenceEnd };\n }\n\n private snapshotEvent(event: WoodRendererTraceEvent): WoodRendererTraceEvent {\n return Object.freeze({\n ...event,\n ...(event.payload ? { payload: Object.freeze({ ...event.payload }) } : {}),\n });\n }\n\n private validateIdentity(input: Record<string, unknown>): WoodTraceIdentityValidationResult {\n if (input.protocolVersion !== 1) {\n return { kind: 'invalid', reason: 'Trace batch protocol version is unsupported' };\n }\n if (typeof input.producerId !== 'string' || input.producerId.trim().length === 0) {\n return { kind: 'invalid', reason: 'Trace batch producer identity is invalid' };\n }\n if (typeof input.batchId !== 'string' || input.batchId.trim().length === 0) {\n return { kind: 'invalid', reason: 'Trace batch identity is invalid' };\n }\n return { kind: 'valid' };\n }\n\n private isConversationId(value: unknown): value is string | number {\n return typeof value === 'string' || (typeof value === 'number' && Number.isFinite(value));\n }\n\n private isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n }\n}\n"],"mappings":"AAWA,MAAM,mBAAmB;AAElB,MAAM,uBAAuB;AAAA,EAClC,OACE,YACA,eACA,QACgB;AAChB,UAAM,YAAY,OAAO,IAAI,CAAC,UAAU,KAAK,cAAc,KAAK,CAAC;AACjE,UAAM,OAAO,UAAU,UAAU,SAAS,CAAC;AAC3C,UAAM,cAAc,OAAO,KAAK,WAAW,IAAI,gBAAgB;AAC/D,WAAO,OAAO,OAAO;AAAA,MACnB,MAAM;AAAA,MACN,iBAAiB;AAAA,MACjB;AAAA,MACA,SAAS,QAAQ,UAAU,IAAI,aAAa,IAAI,WAAW;AAAA,MAC3D;AAAA,MACA;AAAA,MACA,QAAQ,OAAO,OAAO,SAAS;AAAA,IACjC,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,OAA2C;AAC/C,QAAI,CAAC,KAAK,SAAS,KAAK,KAAK,MAAM,SAAS,oBAAoB;AAC9D,aAAO,EAAE,MAAM,YAAY;AAAA,IAC7B;AAEA,UAAM,UAAU,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU;AACpE,UAAM,WAAW,KAAK,iBAAiB,KAAK;AAC5C,QAAI,SAAS,SAAS,WAAW;AAC/B,aAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,SAAS,OAAO;AAAA,IAC7D;AACA,UAAM,aAAa,MAAM;AACzB,QAAI,OAAO,eAAe,UAAU;AAClC,aAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,2CAA2C;AAAA,IACxF;AAEA,UAAM,eAAe,KAAK,YAAY,MAAM,MAAM;AAClD,QAAI,aAAa,SAAS,WAAW;AACnC,aAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,aAAa,OAAO;AAAA,IACjE;AACA,UAAM,SAAS,aAAa;AAE5B,UAAM,sBAAsB,KAAK,mBAAmB,OAAO,MAAM;AACjE,QAAI,oBAAoB,SAAS,WAAW;AAC1C,aAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,oBAAoB,OAAO;AAAA,IACxE;AACA,UAAM,EAAE,eAAe,YAAY,IAAI;AACvC,UAAM,2BAA2B,OAAO,KAAK,CAAC,OAAO,UAAU;AAC7D,YAAM,WAAW,OAAO,QAAQ,CAAC;AACjC,aAAO,aAAa,UAAa,MAAM,YAAY,SAAS;AAAA,IAC9D,CAAC;AACD,QAAI,0BAA0B;AAC5B,aAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,oDAAoD;AAAA,IACjG;AACA,UAAM,kBAAkB,QAAQ,UAAU,IAAI,aAAa,IAAI,WAAW;AAC1E,QAAI,MAAM,YAAY,iBAAiB;AACrC,aAAO,EAAE,MAAM,WAAW,SAAS,QAAQ,yDAAyD;AAAA,IACtG;AAEA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,KAAK,OAAO,YAAY,eAAe,MAAM;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,qBAAqB,OAAqD;AACxE,QAAI,CAAC,KAAK,SAAS,KAAK,KAAK,OAAO,MAAM,SAAS,YAAY,OAAO,MAAM,YAAY,UAAU;AAChG,aAAO,EAAE,IAAI,OAAO,QAAQ,iDAAiD;AAAA,IAC/E;AAEA,QAAI,MAAM,SAAS,aAAa;AAC9B,aAAO,KAAK,8BAA8B,KAAK;AAAA,IACjD;AACA,QAAI,MAAM,SAAS,aAAa;AAC9B,aAAO,KAAK,8BAA8B,KAAK;AAAA,IACjD;AACA,QAAI,MAAM,SAAS,cAAc,OAAO,MAAM,WAAW,UAAU;AACjE,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,iBAAiB,OAAO,OAAO;AAAA,UAC7B,MAAM;AAAA,UACN,SAAS,MAAM;AAAA,UACf,QAAQ,MAAM;AAAA,QAChB,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO,EAAE,IAAI,OAAO,QAAQ,8CAA8C;AAAA,EAC5E;AAAA,EAEQ,8BACN,OACqC;AACrC,UAAM,UAAU,MAAM;AACtB,UAAM,gBAAgB,MAAM;AAC5B,UAAM,iBAAiB,MAAM;AAC7B,UAAM,eAAe,OAAO,YAAY,YACnC,OAAO,kBAAkB,YACzB,OAAO,SAAS,aAAa,KAC7B,OAAO,mBAAmB,YAC1B,OAAO,cAAc,cAAc,KACnC,kBAAkB;AACvB,QAAI,CAAC,cAAc;AACjB,aAAO,EAAE,IAAI,OAAO,QAAQ,6CAA6C;AAAA,IAC3E;AACA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,iBAAiB,OAAO,OAAO;AAAA,QAC7B,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,8BACN,OACqC;AACrC,UAAM,UAAU,MAAM;AACtB,UAAM,eAAe,MAAM;AAC3B,QAAI,OAAO,YAAY,YAClB,OAAO,MAAM,WAAW,YACxB,OAAO,iBAAiB,YACxB,CAAC,OAAO,SAAS,YAAY,KAC7B,eAAe,GAAG;AACrB,aAAO,EAAE,IAAI,OAAO,QAAQ,6CAA6C;AAAA,IAC3E;AACA,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,iBAAiB,OAAO,OAAO;AAAA,QAC7B,MAAM;AAAA,QACN;AAAA,QACA,QAAQ,MAAM;AAAA,QACd;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,WAAW,OAA2C;AAC5D,QAAI,CAAC,KAAK,SAAS,KAAK,GAAG;AACzB,aAAO,EAAE,MAAM,WAAW,QAAQ,+BAA+B;AAAA,IACnE;AACA,UAAM,mBAAmB,KAAK,sBAAsB,KAAK;AACzD,UAAM,iBAAiB,KAAK,oBAAoB,KAAK;AACrD,QAAI,CAAC,oBAAoB,CAAC,gBAAgB;AACxC,aAAO,EAAE,MAAM,WAAW,QAAQ,4CAA4C;AAAA,IAChF;AACA,QAAI,MAAM,YAAY,UAAa,CAAC,KAAK,SAAS,MAAM,OAAO,GAAG;AAChE,aAAO,EAAE,MAAM,WAAW,QAAQ,iCAAiC;AAAA,IACrE;AACA,WAAO;AAAA,MACL,MAAM;AAAA,MACN,OAAO,KAAK,cAAc;AAAA,QACxB,QAAQ,MAAM;AAAA,QACd,MAAM,MAAM;AAAA,QACZ,OAAO,MAAM;AAAA,QACb,SAAS;AAAA,QACT,WAAW,MAAM;AAAA,QACjB,UAAU,MAAM;AAAA;AAAA,QAEhB,GAAI,OAAO,MAAM,eAAe,YAAY,MAAM,WAAW,KAAK,EAAE,SAAS,IACzE,EAAE,YAAY,MAAM,WAAW,IAC/B,CAAC;AAAA,QACL,GAAI,OAAO,MAAM,YAAY,WAAW,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,QACtE,GAAI,KAAK,iBAAiB,MAAM,cAAc,IAAI,EAAE,gBAAgB,MAAM,eAAe,IAAI,CAAC;AAAA,QAC9F,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,QAClD,GAAI,OAAO,MAAM,aAAa,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,QACzE,GAAI,OAAO,MAAM,kBAAkB,YAAY,OAAO,SAAS,MAAM,aAAa,IAC9E,EAAE,eAAe,MAAM,cAAc,IACrC,CAAC;AAAA,QACL,GAAI,OAAO,MAAM,aAAa,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,QACzE,GAAI,OAAO,MAAM,cAAc,WAAW,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,MAC9E,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,sBAAsB,OAK5B;AACA,WAAO,OAAO,MAAM,WAAW,YAC1B,MAAM,OAAO,KAAK,EAAE,SAAS,KAC7B,OAAO,MAAM,SAAS,YACtB,MAAM,KAAK,KAAK,EAAE,SAAS,KAC3B,OAAO,MAAM,UAAU,YACvB,MAAM,MAAM,KAAK,EAAE,SAAS,KAC5B,MAAM,YAAY;AAAA,EACzB;AAAA,EAEQ,oBAAoB,OAG1B;AACA,WAAO,OAAO,MAAM,cAAc,YAC7B,OAAO,SAAS,KAAK,MAAM,MAAM,SAAS,CAAC,KAC3C,OAAO,MAAM,aAAa,YAC1B,OAAO,cAAc,MAAM,QAAQ,KACnC,MAAM,YAAY;AAAA,EACzB;AAAA,EAEQ,YAAY,OAA4C;AAC9D,QAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,KAAK,MAAM,SAAS,kBAAkB;AAClF,aAAO,EAAE,MAAM,WAAW,QAAQ,iCAAiC;AAAA,IACrE;AACA,UAAM,SAAmC,CAAC;AAC1C,eAAW,YAAY,OAAO;AAC5B,YAAM,cAAc,KAAK,WAAW,QAAQ;AAC5C,UAAI,YAAY,SAAS,WAAW;AAClC,eAAO;AAAA,MACT;AACA,aAAO,KAAK,YAAY,KAAK;AAAA,IAC/B;AACA,WAAO,EAAE,MAAM,SAAS,QAAQ,OAAO,OAAO,MAAM,EAAE;AAAA,EACxD;AAAA,EAEQ,mBACN,OACA,QACqG;AACrG,UAAM,gBAAgB,MAAM;AAC5B,UAAM,cAAc,MAAM;AAC1B,QAAI,OAAO,kBAAkB,YAAY,OAAO,gBAAgB,UAAU;AACxE,aAAO,EAAE,MAAM,WAAW,QAAQ,wCAAwC;AAAA,IAC5E;AACA,UAAM,aAAa,OAAO,CAAC;AAC3B,UAAM,YAAY,OAAO,OAAO,SAAS,CAAC;AAC1C,UAAM,kBAAkB,CAAC,OAAO,cAAc,aAAa,KACtD,gBAAgB,KAChB,CAAC,OAAO,cAAc,WAAW,KACjC,CAAC,cACD,CAAC,aACD,WAAW,aAAa,gBAAgB,KACxC,UAAU,aAAa,cAAc;AAC1C,QAAI,iBAAiB;AACnB,aAAO,EAAE,MAAM,WAAW,QAAQ,uDAAuD;AAAA,IAC3F;AACA,WAAO,EAAE,MAAM,SAAS,eAAe,YAAY;AAAA,EACrD;AAAA,EAEQ,cAAc,OAAuD;AAC3E,WAAO,OAAO,OAAO;AAAA,MACnB,GAAG;AAAA,MACH,GAAI,MAAM,UAAU,EAAE,SAAS,OAAO,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,EAAE,IAAI,CAAC;AAAA,IAC1E,CAAC;AAAA,EACH;AAAA,EAEQ,iBAAiB,OAAmE;AAC1F,QAAI,MAAM,oBAAoB,GAAG;AAC/B,aAAO,EAAE,MAAM,WAAW,QAAQ,8CAA8C;AAAA,IAClF;AACA,QAAI,OAAO,MAAM,eAAe,YAAY,MAAM,WAAW,KAAK,EAAE,WAAW,GAAG;AAChF,aAAO,EAAE,MAAM,WAAW,QAAQ,2CAA2C;AAAA,IAC/E;AACA,QAAI,OAAO,MAAM,YAAY,YAAY,MAAM,QAAQ,KAAK,EAAE,WAAW,GAAG;AAC1E,aAAO,EAAE,MAAM,WAAW,QAAQ,kCAAkC;AAAA,IACtE;AACA,WAAO,EAAE,MAAM,QAAQ;AAAA,EACzB;AAAA,EAEQ,iBAAiB,OAA0C;AACjE,WAAO,OAAO,UAAU,YAAa,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK;AAAA,EACzF;AAAA,EAEQ,SAAS,OAAkD;AACjE,WAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA,EAC5E;AACF;","names":[]}
@@ -18,7 +18,8 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var build_transport_bridge_exports = {};
20
20
  __export(build_transport_bridge_exports, {
21
- buildTransportBridge: () => buildTransportBridge
21
+ buildTransportBridge: () => buildTransportBridge,
22
+ operationHasInput: () => operationHasInput
22
23
  });
23
24
  module.exports = __toCommonJS(build_transport_bridge_exports);
24
25
  function operationHasInput(op) {
@@ -57,6 +58,7 @@ function buildTransportBridge(operations, transport) {
57
58
  }
58
59
  // Annotate the CommonJS export names for ESM import in node:
59
60
  0 && (module.exports = {
60
- buildTransportBridge
61
+ buildTransportBridge,
62
+ operationHasInput
61
63
  });
62
64
  //# sourceMappingURL=build_transport_bridge.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/transport/build_transport_bridge.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.cjs';\nimport type { WoodRpcManifestEntry } from '../client/index.js';\nimport type { WoodRpcTransport } from './wood_rpc_transport.js';\n\n/**\n * Build a `WoodBridge`-shaped object (the global `__NOEGO_WOOD_BRIDGE__` shape)\n * backed by a `WoodRpcTransport` instead of Electron's `ipcRenderer`.\n *\n * Every operation channel (e.g. `chat.messages.send`) becomes a nested method\n * on the returned bridge that calls `transport.invoke(channel, data)`. `on()`\n * is backed by `transport.subscribe`, and `__rpcManifest` is derived from the\n * same operations map used by codegen — so the existing `getApp()` renderer\n * client can be pointed at this bridge with zero changes.\n *\n * The production Electron preload path is untouched: it still exposes its own\n * `ipcRenderer`-backed bridge. This function is the test-mode equivalent that\n * any `WoodRpcTransport` (in-process or loopback) plugs into.\n */\nexport interface TransportBridgeResult {\n bridge: Record<string, any>;\n}\n\nfunction operationHasInput(op: OperationDef): boolean {\n return Boolean(\n op.inputSchema &&\n (op.inputSchema as Record<string, unknown>).type === 'object' &&\n Object.keys(\n (op.inputSchema as Record<string, Record<string, unknown>>).properties ?? {},\n ).length > 0,\n );\n}\n\nfunction buildManifest(operations: Map<string, OperationDef>): WoodRpcManifestEntry[] {\n return Array.from(operations.values()).map((op) => ({\n channel: op.channel,\n controller: op.controller,\n action: op.action,\n path: op.channel.split('.'),\n hasInput: operationHasInput(op),\n }));\n}\n\n/**\n * Build the nested bridge tree from the operations' dot-path channels.\n * Mirrors the nesting used by the preload generator and router bridge:\n * intermediate segments become namespace objects, leaf segments become\n * transport-backed invoke functions.\n */\nexport function buildTransportBridge(\n operations: Map<string, OperationDef>,\n transport: WoodRpcTransport,\n): TransportBridgeResult {\n const tree: Record<string, any> = {};\n\n for (const channel of operations.keys()) {\n const parts = channel.split('.');\n let current = tree;\n\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) {\n current[parts[i]] = {};\n }\n current = current[parts[i]];\n }\n\n const leaf = parts[parts.length - 1];\n current[leaf] = (data?: unknown) => transport.invoke(channel, data);\n }\n\n tree.on = (channel: string, callback: (...args: unknown[]) => void) =>\n transport.subscribe(channel, (payload) => callback(payload));\n\n tree.__rpcManifest = buildManifest(operations);\n\n return { bridge: tree };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAsBA,SAAS,kBAAkB,IAA2B;AACpD,SAAO;AAAA,IACL,GAAG,eACA,GAAG,YAAwC,SAAS,YACrD,OAAO;AAAA,MACJ,GAAG,YAAwD,cAAc,CAAC;AAAA,IAC7E,EAAE,SAAS;AAAA,EACf;AACF;AAEA,SAAS,cAAc,YAA+D;AACpF,SAAO,MAAM,KAAK,WAAW,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ;AAAA,IAClD,SAAS,GAAG;AAAA,IACZ,YAAY,GAAG;AAAA,IACf,QAAQ,GAAG;AAAA,IACX,MAAM,GAAG,QAAQ,MAAM,GAAG;AAAA,IAC1B,UAAU,kBAAkB,EAAE;AAAA,EAChC,EAAE;AACJ;AAQO,SAAS,qBACd,YACA,WACuB;AACvB,QAAM,OAA4B,CAAC;AAEnC,aAAW,WAAW,WAAW,KAAK,GAAG;AACvC,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAU;AAEd,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,GAAG;AACtB,gBAAQ,MAAM,CAAC,CAAC,IAAI,CAAC;AAAA,MACvB;AACA,gBAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC5B;AAEA,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,YAAQ,IAAI,IAAI,CAAC,SAAmB,UAAU,OAAO,SAAS,IAAI;AAAA,EACpE;AAEA,OAAK,KAAK,CAAC,SAAiB,aAC1B,UAAU,UAAU,SAAS,CAAC,YAAY,SAAS,OAAO,CAAC;AAE7D,OAAK,gBAAgB,cAAc,UAAU;AAE7C,SAAO,EAAE,QAAQ,KAAK;AACxB;","names":[]}
1
+ {"version":3,"sources":["../../src/transport/build_transport_bridge.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.cjs';\nimport type { WoodRpcManifestEntry } from '../client/index.js';\nimport type { WoodRpcTransport } from './wood_rpc_transport.js';\n\n/**\n * Build a `WoodBridge`-shaped object (the global `__NOEGO_WOOD_BRIDGE__` shape)\n * backed by a `WoodRpcTransport` instead of Electron's `ipcRenderer`.\n *\n * Every operation channel (e.g. `chat.messages.send`) becomes a nested method\n * on the returned bridge that calls `transport.invoke(channel, data)`. `on()`\n * is backed by `transport.subscribe`, and `__rpcManifest` is derived from the\n * same operations map used by codegen — so the existing `getApp()` renderer\n * client can be pointed at this bridge with zero changes.\n *\n * The production Electron preload path is untouched: it still exposes its own\n * `ipcRenderer`-backed bridge. This function is the test-mode equivalent that\n * any `WoodRpcTransport` (in-process or loopback) plugs into.\n */\nexport interface TransportBridgeResult {\n bridge: Record<string, any>;\n}\n\n/**\n * The ONE definition of \"this operation takes an input argument\": a\n * non-empty object schema. The preload generator, transport bridge, and\n * test harnesses must agree, or renderer arity enforcement drifts.\n */\nexport function operationHasInput(op: OperationDef): boolean {\n return Boolean(\n op.inputSchema &&\n (op.inputSchema as Record<string, unknown>).type === 'object' &&\n Object.keys(\n (op.inputSchema as Record<string, Record<string, unknown>>).properties ?? {},\n ).length > 0,\n );\n}\n\nfunction buildManifest(operations: Map<string, OperationDef>): WoodRpcManifestEntry[] {\n return Array.from(operations.values()).map((op) => ({\n channel: op.channel,\n controller: op.controller,\n action: op.action,\n path: op.channel.split('.'),\n hasInput: operationHasInput(op),\n }));\n}\n\n/**\n * Build the nested bridge tree from the operations' dot-path channels.\n * Mirrors the nesting used by the preload generator and router bridge:\n * intermediate segments become namespace objects, leaf segments become\n * transport-backed invoke functions.\n */\nexport function buildTransportBridge(\n operations: Map<string, OperationDef>,\n transport: WoodRpcTransport,\n): TransportBridgeResult {\n const tree: Record<string, any> = {};\n\n for (const channel of operations.keys()) {\n const parts = channel.split('.');\n let current = tree;\n\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) {\n current[parts[i]] = {};\n }\n current = current[parts[i]];\n }\n\n const leaf = parts[parts.length - 1];\n current[leaf] = (data?: unknown) => transport.invoke(channel, data);\n }\n\n tree.on = (channel: string, callback: (...args: unknown[]) => void) =>\n transport.subscribe(channel, (payload) => callback(payload));\n\n tree.__rpcManifest = buildManifest(operations);\n\n return { bridge: tree };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BO,SAAS,kBAAkB,IAA2B;AAC3D,SAAO;AAAA,IACL,GAAG,eACA,GAAG,YAAwC,SAAS,YACrD,OAAO;AAAA,MACJ,GAAG,YAAwD,cAAc,CAAC;AAAA,IAC7E,EAAE,SAAS;AAAA,EACf;AACF;AAEA,SAAS,cAAc,YAA+D;AACpF,SAAO,MAAM,KAAK,WAAW,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ;AAAA,IAClD,SAAS,GAAG;AAAA,IACZ,YAAY,GAAG;AAAA,IACf,QAAQ,GAAG;AAAA,IACX,MAAM,GAAG,QAAQ,MAAM,GAAG;AAAA,IAC1B,UAAU,kBAAkB,EAAE;AAAA,EAChC,EAAE;AACJ;AAQO,SAAS,qBACd,YACA,WACuB;AACvB,QAAM,OAA4B,CAAC;AAEnC,aAAW,WAAW,WAAW,KAAK,GAAG;AACvC,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAU;AAEd,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,GAAG;AACtB,gBAAQ,MAAM,CAAC,CAAC,IAAI,CAAC;AAAA,MACvB;AACA,gBAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC5B;AAEA,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,YAAQ,IAAI,IAAI,CAAC,SAAmB,UAAU,OAAO,SAAS,IAAI;AAAA,EACpE;AAEA,OAAK,KAAK,CAAC,SAAiB,aAC1B,UAAU,UAAU,SAAS,CAAC,YAAY,SAAS,OAAO,CAAC;AAE7D,OAAK,gBAAgB,cAAc,UAAU;AAE7C,SAAO,EAAE,QAAQ,KAAK;AACxB;","names":[]}
@@ -18,6 +18,12 @@ import { WoodRpcTransport } from './wood_rpc_transport.cjs';
18
18
  interface TransportBridgeResult {
19
19
  bridge: Record<string, any>;
20
20
  }
21
+ /**
22
+ * The ONE definition of "this operation takes an input argument": a
23
+ * non-empty object schema. The preload generator, transport bridge, and
24
+ * test harnesses must agree, or renderer arity enforcement drifts.
25
+ */
26
+ declare function operationHasInput(op: OperationDef): boolean;
21
27
  /**
22
28
  * Build the nested bridge tree from the operations' dot-path channels.
23
29
  * Mirrors the nesting used by the preload generator and router bridge:
@@ -26,4 +32,4 @@ interface TransportBridgeResult {
26
32
  */
27
33
  declare function buildTransportBridge(operations: Map<string, OperationDef>, transport: WoodRpcTransport): TransportBridgeResult;
28
34
 
29
- export { type TransportBridgeResult, buildTransportBridge };
35
+ export { type TransportBridgeResult, buildTransportBridge, operationHasInput };
@@ -18,6 +18,12 @@ import { WoodRpcTransport } from './wood_rpc_transport.js';
18
18
  interface TransportBridgeResult {
19
19
  bridge: Record<string, any>;
20
20
  }
21
+ /**
22
+ * The ONE definition of "this operation takes an input argument": a
23
+ * non-empty object schema. The preload generator, transport bridge, and
24
+ * test harnesses must agree, or renderer arity enforcement drifts.
25
+ */
26
+ declare function operationHasInput(op: OperationDef): boolean;
21
27
  /**
22
28
  * Build the nested bridge tree from the operations' dot-path channels.
23
29
  * Mirrors the nesting used by the preload generator and router bridge:
@@ -26,4 +32,4 @@ interface TransportBridgeResult {
26
32
  */
27
33
  declare function buildTransportBridge(operations: Map<string, OperationDef>, transport: WoodRpcTransport): TransportBridgeResult;
28
34
 
29
- export { type TransportBridgeResult, buildTransportBridge };
35
+ export { type TransportBridgeResult, buildTransportBridge, operationHasInput };
@@ -33,6 +33,7 @@ function buildTransportBridge(operations, transport) {
33
33
  return { bridge: tree };
34
34
  }
35
35
  export {
36
- buildTransportBridge
36
+ buildTransportBridge,
37
+ operationHasInput
37
38
  };
38
39
  //# sourceMappingURL=build_transport_bridge.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/transport/build_transport_bridge.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.js';\nimport type { WoodRpcManifestEntry } from '../client/index.js';\nimport type { WoodRpcTransport } from './wood_rpc_transport.js';\n\n/**\n * Build a `WoodBridge`-shaped object (the global `__NOEGO_WOOD_BRIDGE__` shape)\n * backed by a `WoodRpcTransport` instead of Electron's `ipcRenderer`.\n *\n * Every operation channel (e.g. `chat.messages.send`) becomes a nested method\n * on the returned bridge that calls `transport.invoke(channel, data)`. `on()`\n * is backed by `transport.subscribe`, and `__rpcManifest` is derived from the\n * same operations map used by codegen — so the existing `getApp()` renderer\n * client can be pointed at this bridge with zero changes.\n *\n * The production Electron preload path is untouched: it still exposes its own\n * `ipcRenderer`-backed bridge. This function is the test-mode equivalent that\n * any `WoodRpcTransport` (in-process or loopback) plugs into.\n */\nexport interface TransportBridgeResult {\n bridge: Record<string, any>;\n}\n\nfunction operationHasInput(op: OperationDef): boolean {\n return Boolean(\n op.inputSchema &&\n (op.inputSchema as Record<string, unknown>).type === 'object' &&\n Object.keys(\n (op.inputSchema as Record<string, Record<string, unknown>>).properties ?? {},\n ).length > 0,\n );\n}\n\nfunction buildManifest(operations: Map<string, OperationDef>): WoodRpcManifestEntry[] {\n return Array.from(operations.values()).map((op) => ({\n channel: op.channel,\n controller: op.controller,\n action: op.action,\n path: op.channel.split('.'),\n hasInput: operationHasInput(op),\n }));\n}\n\n/**\n * Build the nested bridge tree from the operations' dot-path channels.\n * Mirrors the nesting used by the preload generator and router bridge:\n * intermediate segments become namespace objects, leaf segments become\n * transport-backed invoke functions.\n */\nexport function buildTransportBridge(\n operations: Map<string, OperationDef>,\n transport: WoodRpcTransport,\n): TransportBridgeResult {\n const tree: Record<string, any> = {};\n\n for (const channel of operations.keys()) {\n const parts = channel.split('.');\n let current = tree;\n\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) {\n current[parts[i]] = {};\n }\n current = current[parts[i]];\n }\n\n const leaf = parts[parts.length - 1];\n current[leaf] = (data?: unknown) => transport.invoke(channel, data);\n }\n\n tree.on = (channel: string, callback: (...args: unknown[]) => void) =>\n transport.subscribe(channel, (payload) => callback(payload));\n\n tree.__rpcManifest = buildManifest(operations);\n\n return { bridge: tree };\n}\n"],"mappings":"AAsBA,SAAS,kBAAkB,IAA2B;AACpD,SAAO;AAAA,IACL,GAAG,eACA,GAAG,YAAwC,SAAS,YACrD,OAAO;AAAA,MACJ,GAAG,YAAwD,cAAc,CAAC;AAAA,IAC7E,EAAE,SAAS;AAAA,EACf;AACF;AAEA,SAAS,cAAc,YAA+D;AACpF,SAAO,MAAM,KAAK,WAAW,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ;AAAA,IAClD,SAAS,GAAG;AAAA,IACZ,YAAY,GAAG;AAAA,IACf,QAAQ,GAAG;AAAA,IACX,MAAM,GAAG,QAAQ,MAAM,GAAG;AAAA,IAC1B,UAAU,kBAAkB,EAAE;AAAA,EAChC,EAAE;AACJ;AAQO,SAAS,qBACd,YACA,WACuB;AACvB,QAAM,OAA4B,CAAC;AAEnC,aAAW,WAAW,WAAW,KAAK,GAAG;AACvC,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAU;AAEd,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,GAAG;AACtB,gBAAQ,MAAM,CAAC,CAAC,IAAI,CAAC;AAAA,MACvB;AACA,gBAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC5B;AAEA,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,YAAQ,IAAI,IAAI,CAAC,SAAmB,UAAU,OAAO,SAAS,IAAI;AAAA,EACpE;AAEA,OAAK,KAAK,CAAC,SAAiB,aAC1B,UAAU,UAAU,SAAS,CAAC,YAAY,SAAS,OAAO,CAAC;AAE7D,OAAK,gBAAgB,cAAc,UAAU;AAE7C,SAAO,EAAE,QAAQ,KAAK;AACxB;","names":[]}
1
+ {"version":3,"sources":["../../src/transport/build_transport_bridge.ts"],"sourcesContent":["import type { OperationDef } from '../types/index.js';\nimport type { WoodRpcManifestEntry } from '../client/index.js';\nimport type { WoodRpcTransport } from './wood_rpc_transport.js';\n\n/**\n * Build a `WoodBridge`-shaped object (the global `__NOEGO_WOOD_BRIDGE__` shape)\n * backed by a `WoodRpcTransport` instead of Electron's `ipcRenderer`.\n *\n * Every operation channel (e.g. `chat.messages.send`) becomes a nested method\n * on the returned bridge that calls `transport.invoke(channel, data)`. `on()`\n * is backed by `transport.subscribe`, and `__rpcManifest` is derived from the\n * same operations map used by codegen — so the existing `getApp()` renderer\n * client can be pointed at this bridge with zero changes.\n *\n * The production Electron preload path is untouched: it still exposes its own\n * `ipcRenderer`-backed bridge. This function is the test-mode equivalent that\n * any `WoodRpcTransport` (in-process or loopback) plugs into.\n */\nexport interface TransportBridgeResult {\n bridge: Record<string, any>;\n}\n\n/**\n * The ONE definition of \"this operation takes an input argument\": a\n * non-empty object schema. The preload generator, transport bridge, and\n * test harnesses must agree, or renderer arity enforcement drifts.\n */\nexport function operationHasInput(op: OperationDef): boolean {\n return Boolean(\n op.inputSchema &&\n (op.inputSchema as Record<string, unknown>).type === 'object' &&\n Object.keys(\n (op.inputSchema as Record<string, Record<string, unknown>>).properties ?? {},\n ).length > 0,\n );\n}\n\nfunction buildManifest(operations: Map<string, OperationDef>): WoodRpcManifestEntry[] {\n return Array.from(operations.values()).map((op) => ({\n channel: op.channel,\n controller: op.controller,\n action: op.action,\n path: op.channel.split('.'),\n hasInput: operationHasInput(op),\n }));\n}\n\n/**\n * Build the nested bridge tree from the operations' dot-path channels.\n * Mirrors the nesting used by the preload generator and router bridge:\n * intermediate segments become namespace objects, leaf segments become\n * transport-backed invoke functions.\n */\nexport function buildTransportBridge(\n operations: Map<string, OperationDef>,\n transport: WoodRpcTransport,\n): TransportBridgeResult {\n const tree: Record<string, any> = {};\n\n for (const channel of operations.keys()) {\n const parts = channel.split('.');\n let current = tree;\n\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) {\n current[parts[i]] = {};\n }\n current = current[parts[i]];\n }\n\n const leaf = parts[parts.length - 1];\n current[leaf] = (data?: unknown) => transport.invoke(channel, data);\n }\n\n tree.on = (channel: string, callback: (...args: unknown[]) => void) =>\n transport.subscribe(channel, (payload) => callback(payload));\n\n tree.__rpcManifest = buildManifest(operations);\n\n return { bridge: tree };\n}\n"],"mappings":"AA2BO,SAAS,kBAAkB,IAA2B;AAC3D,SAAO;AAAA,IACL,GAAG,eACA,GAAG,YAAwC,SAAS,YACrD,OAAO;AAAA,MACJ,GAAG,YAAwD,cAAc,CAAC;AAAA,IAC7E,EAAE,SAAS;AAAA,EACf;AACF;AAEA,SAAS,cAAc,YAA+D;AACpF,SAAO,MAAM,KAAK,WAAW,OAAO,CAAC,EAAE,IAAI,CAAC,QAAQ;AAAA,IAClD,SAAS,GAAG;AAAA,IACZ,YAAY,GAAG;AAAA,IACf,QAAQ,GAAG;AAAA,IACX,MAAM,GAAG,QAAQ,MAAM,GAAG;AAAA,IAC1B,UAAU,kBAAkB,EAAE;AAAA,EAChC,EAAE;AACJ;AAQO,SAAS,qBACd,YACA,WACuB;AACvB,QAAM,OAA4B,CAAC;AAEnC,aAAW,WAAW,WAAW,KAAK,GAAG;AACvC,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAU;AAEd,aAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAI,CAAC,QAAQ,MAAM,CAAC,CAAC,GAAG;AACtB,gBAAQ,MAAM,CAAC,CAAC,IAAI,CAAC;AAAA,MACvB;AACA,gBAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,IAC5B;AAEA,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,YAAQ,IAAI,IAAI,CAAC,SAAmB,UAAU,OAAO,SAAS,IAAI;AAAA,EACpE;AAEA,OAAK,KAAK,CAAC,SAAiB,aAC1B,UAAU,UAAU,SAAS,CAAC,YAAY,SAAS,OAAO,CAAC;AAE7D,OAAK,gBAAgB,cAAc,UAAU;AAE7C,SAAO,EAAE,QAAQ,KAAK;AACxB;","names":[]}
@@ -2,6 +2,7 @@ import { WoodRouter } from '../router/wood_router.cjs';
2
2
  import { RouterBridgeEvents } from '../testing/create_router_bridge.cjs';
3
3
  import { WoodRpcTransport } from './wood_rpc_transport.cjs';
4
4
  import '../types/operations.cjs';
5
+ import '../types/context.cjs';
5
6
 
6
7
  /**
7
8
  * A `WoodRpcTransport` that dispatches straight through a real `WoodRouter`
@@ -2,6 +2,7 @@ import { WoodRouter } from '../router/wood_router.js';
2
2
  import { RouterBridgeEvents } from '../testing/create_router_bridge.js';
3
3
  import { WoodRpcTransport } from './wood_rpc_transport.js';
4
4
  import '../types/operations.js';
5
+ import '../types/context.js';
5
6
 
6
7
  /**
7
8
  * A `WoodRpcTransport` that dispatches straight through a real `WoodRouter`
@@ -5,4 +5,5 @@ export { LoopbackSerializationError, assertLoopbackSerializable } from './loopba
5
5
  export { TransportBridgeResult, buildTransportBridge } from './build_transport_bridge.cjs';
6
6
  import '../router/wood_router.cjs';
7
7
  import '../types/operations.cjs';
8
+ import '../types/context.cjs';
8
9
  import '../testing/create_router_bridge.cjs';
@@ -5,4 +5,5 @@ export { LoopbackSerializationError, assertLoopbackSerializable } from './loopba
5
5
  export { TransportBridgeResult, buildTransportBridge } from './build_transport_bridge.js';
6
6
  import '../router/wood_router.js';
7
7
  import '../types/operations.js';
8
+ import '../types/context.js';
8
9
  import '../testing/create_router_bridge.js';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/config.ts"],"sourcesContent":["/** Configuration types for wood.config.yml */\n\n/** Top-level Wood configuration parsed from wood.config.yml */\nexport interface WoodConfig {\n root: string;\n outDir: string;\n app: {\n boot: string;\n watch: string[];\n };\n main: {\n entry: string;\n controllers: string;\n middleware: string;\n openapi: string;\n watch: string[];\n };\n renderer: {\n openapi: string;\n componentDir: string;\n controllers: string;\n entry?: string;\n watch?: string[];\n };\n windows: Record<string, WindowDef>;\n database?: {\n path: string;\n migrations?: string;\n };\n assets?: string[];\n dev?: DevConfig;\n build?: ElectronBuilderConfig;\n}\n\n/** BrowserWindow definition from the `windows` section of wood.config.yml */\nexport interface WindowDef {\n title: string;\n width: number;\n height: number;\n defaultRoute: string;\n frame?: boolean;\n transparent?: boolean;\n resizable?: boolean;\n alwaysOnTop?: boolean;\n minWidth?: number;\n minHeight?: number;\n maxWidth?: number;\n maxHeight?: number;\n show?: boolean;\n parent?: string;\n modal?: boolean;\n vibrancy?: string;\n backgroundMaterial?: string;\n rememberBounds?: boolean;\n contextMenu?: 'native' | 'custom';\n acceptFirstMouse?: boolean;\n nativeQuitFallback?: boolean;\n titleBarStyle?: 'default' | 'hidden' | 'hiddenInset' | 'customButtonsOnHover';\n trafficLightPosition?: { x: number; y: number };\n titleBarOverlay?: boolean | { color?: string; symbolColor?: string; height?: number };\n}\n\n/** Dev-mode settings from the `dev` section of wood.config.yml */\nexport interface DevConfig {\n port?: number;\n watch?: boolean;\n splitServe?: boolean;\n electronArgs?: string[];\n inspectPort?: number;\n backendInspectPort?: number;\n}\n\n/** Electron-builder packaging configuration from the `build` section */\nexport interface ElectronBuilderConfig {\n appId: string;\n productName: string;\n mac?: Record<string, unknown>;\n win?: Record<string, unknown>;\n linux?: Record<string, unknown>;\n [key: string]: unknown;\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../src/types/config.ts"],"sourcesContent":["/** Configuration types for wood.config.yml */\n\n/** Top-level Wood configuration parsed from wood.config.yml */\nexport interface WoodConfig {\n root: string;\n outDir: string;\n app: {\n boot: string;\n watch: string[];\n };\n main: {\n entry: string;\n controllers: string;\n middleware: string;\n openapi: string;\n watch: string[];\n testing?: MainTestingConfig;\n };\n renderer: {\n openapi: string;\n componentDir: string;\n controllers: string;\n entry?: string;\n watch?: string[];\n testing?: RendererTestingConfig;\n };\n windows: Record<string, WindowDef>;\n database?: {\n path: string;\n migrations?: string;\n };\n assets?: string[];\n dev?: DevConfig;\n build?: ElectronBuilderConfig;\n observability?: ObservabilityConfig;\n}\n\n/**\n * Test-composition hooks for the main process (`main.testing`). Only the\n * application can know how its backend composes on a fresh IoC root; the\n * config names the module so `@noego/wood/testing`'s `testWood(configPath)`\n * finds it without any test-site wiring.\n */\nexport interface MainTestingConfig {\n /**\n * Module (config-relative path) whose default export composes the app's\n * backend on the root the test builder hands it. See `WoodComposeMain`\n * in `@noego/wood/testing`.\n */\n compose?: string;\n}\n\n/** Test-composition hooks for the renderer (`renderer.testing`). */\nexport interface RendererTestingConfig {\n /**\n * Module (config-relative path) whose default export mounts a page's real\n * component for a controller under a DOM driver. See `WoodPageHost` in\n * `@noego/wood/testing`.\n */\n host?: string;\n}\n\n/**\n * Renderer→main IPC trace batching policy. Owned here (wood.config.yml) per\n * the NoEgo observability architecture: the generated preload embeds the\n * resolved values but is not the configuration owner, and changing this policy\n * never changes instrumentation call sites or record semantics.\n */\nexport interface RendererTraceBatchingConfig {\n maxQueuedEvents: number;\n maxBatchEvents: number;\n acknowledgementTimeoutMs: number;\n retryLimit: number;\n retryBaseDelayMs: number;\n}\n\nexport interface ObservabilityConfig {\n trace?: {\n rendererToMain?: {\n batching?: RendererTraceBatchingConfig;\n };\n };\n}\n\n/** BrowserWindow definition from the `windows` section of wood.config.yml */\nexport interface WindowDef {\n title: string;\n width: number;\n height: number;\n defaultRoute: string;\n frame?: boolean;\n transparent?: boolean;\n resizable?: boolean;\n alwaysOnTop?: boolean;\n minWidth?: number;\n minHeight?: number;\n maxWidth?: number;\n maxHeight?: number;\n show?: boolean;\n parent?: string;\n modal?: boolean;\n vibrancy?: string;\n backgroundMaterial?: string;\n rememberBounds?: boolean;\n contextMenu?: 'native' | 'custom';\n acceptFirstMouse?: boolean;\n nativeQuitFallback?: boolean;\n titleBarStyle?: 'default' | 'hidden' | 'hiddenInset' | 'customButtonsOnHover';\n trafficLightPosition?: { x: number; y: number };\n titleBarOverlay?: boolean | { color?: string; symbolColor?: string; height?: number };\n}\n\n/** Dev-mode settings from the `dev` section of wood.config.yml */\nexport interface DevConfig {\n port?: number;\n watch?: boolean;\n splitServe?: boolean;\n electronArgs?: string[];\n inspectPort?: number;\n backendInspectPort?: number;\n}\n\n/** Electron-builder packaging configuration from the `build` section */\nexport interface ElectronBuilderConfig {\n appId: string;\n productName: string;\n mac?: Record<string, unknown>;\n win?: Record<string, unknown>;\n linux?: Record<string, unknown>;\n [key: string]: unknown;\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -13,6 +13,7 @@ interface WoodConfig {
13
13
  middleware: string;
14
14
  openapi: string;
15
15
  watch: string[];
16
+ testing?: MainTestingConfig;
16
17
  };
17
18
  renderer: {
18
19
  openapi: string;
@@ -20,6 +21,7 @@ interface WoodConfig {
20
21
  controllers: string;
21
22
  entry?: string;
22
23
  watch?: string[];
24
+ testing?: RendererTestingConfig;
23
25
  };
24
26
  windows: Record<string, WindowDef>;
25
27
  database?: {
@@ -29,6 +31,50 @@ interface WoodConfig {
29
31
  assets?: string[];
30
32
  dev?: DevConfig;
31
33
  build?: ElectronBuilderConfig;
34
+ observability?: ObservabilityConfig;
35
+ }
36
+ /**
37
+ * Test-composition hooks for the main process (`main.testing`). Only the
38
+ * application can know how its backend composes on a fresh IoC root; the
39
+ * config names the module so `@noego/wood/testing`'s `testWood(configPath)`
40
+ * finds it without any test-site wiring.
41
+ */
42
+ interface MainTestingConfig {
43
+ /**
44
+ * Module (config-relative path) whose default export composes the app's
45
+ * backend on the root the test builder hands it. See `WoodComposeMain`
46
+ * in `@noego/wood/testing`.
47
+ */
48
+ compose?: string;
49
+ }
50
+ /** Test-composition hooks for the renderer (`renderer.testing`). */
51
+ interface RendererTestingConfig {
52
+ /**
53
+ * Module (config-relative path) whose default export mounts a page's real
54
+ * component for a controller under a DOM driver. See `WoodPageHost` in
55
+ * `@noego/wood/testing`.
56
+ */
57
+ host?: string;
58
+ }
59
+ /**
60
+ * Renderer→main IPC trace batching policy. Owned here (wood.config.yml) per
61
+ * the NoEgo observability architecture: the generated preload embeds the
62
+ * resolved values but is not the configuration owner, and changing this policy
63
+ * never changes instrumentation call sites or record semantics.
64
+ */
65
+ interface RendererTraceBatchingConfig {
66
+ maxQueuedEvents: number;
67
+ maxBatchEvents: number;
68
+ acknowledgementTimeoutMs: number;
69
+ retryLimit: number;
70
+ retryBaseDelayMs: number;
71
+ }
72
+ interface ObservabilityConfig {
73
+ trace?: {
74
+ rendererToMain?: {
75
+ batching?: RendererTraceBatchingConfig;
76
+ };
77
+ };
32
78
  }
33
79
  /** BrowserWindow definition from the `windows` section of wood.config.yml */
34
80
  interface WindowDef {
@@ -83,4 +129,4 @@ interface ElectronBuilderConfig {
83
129
  [key: string]: unknown;
84
130
  }
85
131
 
86
- export type { DevConfig, ElectronBuilderConfig, WindowDef, WoodConfig };
132
+ export type { DevConfig, ElectronBuilderConfig, MainTestingConfig, ObservabilityConfig, RendererTestingConfig, RendererTraceBatchingConfig, WindowDef, WoodConfig };
@@ -13,6 +13,7 @@ interface WoodConfig {
13
13
  middleware: string;
14
14
  openapi: string;
15
15
  watch: string[];
16
+ testing?: MainTestingConfig;
16
17
  };
17
18
  renderer: {
18
19
  openapi: string;
@@ -20,6 +21,7 @@ interface WoodConfig {
20
21
  controllers: string;
21
22
  entry?: string;
22
23
  watch?: string[];
24
+ testing?: RendererTestingConfig;
23
25
  };
24
26
  windows: Record<string, WindowDef>;
25
27
  database?: {
@@ -29,6 +31,50 @@ interface WoodConfig {
29
31
  assets?: string[];
30
32
  dev?: DevConfig;
31
33
  build?: ElectronBuilderConfig;
34
+ observability?: ObservabilityConfig;
35
+ }
36
+ /**
37
+ * Test-composition hooks for the main process (`main.testing`). Only the
38
+ * application can know how its backend composes on a fresh IoC root; the
39
+ * config names the module so `@noego/wood/testing`'s `testWood(configPath)`
40
+ * finds it without any test-site wiring.
41
+ */
42
+ interface MainTestingConfig {
43
+ /**
44
+ * Module (config-relative path) whose default export composes the app's
45
+ * backend on the root the test builder hands it. See `WoodComposeMain`
46
+ * in `@noego/wood/testing`.
47
+ */
48
+ compose?: string;
49
+ }
50
+ /** Test-composition hooks for the renderer (`renderer.testing`). */
51
+ interface RendererTestingConfig {
52
+ /**
53
+ * Module (config-relative path) whose default export mounts a page's real
54
+ * component for a controller under a DOM driver. See `WoodPageHost` in
55
+ * `@noego/wood/testing`.
56
+ */
57
+ host?: string;
58
+ }
59
+ /**
60
+ * Renderer→main IPC trace batching policy. Owned here (wood.config.yml) per
61
+ * the NoEgo observability architecture: the generated preload embeds the
62
+ * resolved values but is not the configuration owner, and changing this policy
63
+ * never changes instrumentation call sites or record semantics.
64
+ */
65
+ interface RendererTraceBatchingConfig {
66
+ maxQueuedEvents: number;
67
+ maxBatchEvents: number;
68
+ acknowledgementTimeoutMs: number;
69
+ retryLimit: number;
70
+ retryBaseDelayMs: number;
71
+ }
72
+ interface ObservabilityConfig {
73
+ trace?: {
74
+ rendererToMain?: {
75
+ batching?: RendererTraceBatchingConfig;
76
+ };
77
+ };
32
78
  }
33
79
  /** BrowserWindow definition from the `windows` section of wood.config.yml */
34
80
  interface WindowDef {
@@ -83,4 +129,4 @@ interface ElectronBuilderConfig {
83
129
  [key: string]: unknown;
84
130
  }
85
131
 
86
- export type { DevConfig, ElectronBuilderConfig, WindowDef, WoodConfig };
132
+ export type { DevConfig, ElectronBuilderConfig, MainTestingConfig, ObservabilityConfig, RendererTestingConfig, RendererTraceBatchingConfig, WindowDef, WoodConfig };
@@ -3,6 +3,10 @@ var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
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
+ };
6
10
  var __copyProps = (to, from, except, desc) => {
7
11
  if (from && typeof from === "object" || typeof from === "function") {
8
12
  for (let key of __getOwnPropNames(from))
@@ -13,5 +17,13 @@ var __copyProps = (to, from, except, desc) => {
13
17
  };
14
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
19
  var context_exports = {};
20
+ __export(context_exports, {
21
+ WOOD_CONTEXT_OPERATION: () => WOOD_CONTEXT_OPERATION
22
+ });
16
23
  module.exports = __toCommonJS(context_exports);
24
+ const WOOD_CONTEXT_OPERATION = "operation";
25
+ // Annotate the CommonJS export names for ESM import in node:
26
+ 0 && (module.exports = {
27
+ WOOD_CONTEXT_OPERATION
28
+ });
17
29
  //# sourceMappingURL=context.cjs.map