@noego/wood 0.4.10 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (382) hide show
  1. package/README.md +118 -42
  2. package/dist/bridge/backend_bridge.cjs.map +1 -1
  3. package/dist/bridge/backend_bridge.js.map +1 -1
  4. package/dist/client/index.cjs +78 -21
  5. package/dist/client/index.cjs.map +1 -1
  6. package/dist/client/index.d.cts +18 -3
  7. package/dist/client/index.d.ts +18 -3
  8. package/dist/client/index.js +80 -22
  9. package/dist/client/index.js.map +1 -1
  10. package/dist/client/renderer_log_transport.cjs +151 -0
  11. package/dist/client/renderer_log_transport.cjs.map +1 -0
  12. package/dist/client/renderer_log_transport.d.cts +54 -0
  13. package/dist/client/renderer_log_transport.d.ts +54 -0
  14. package/dist/client/renderer_log_transport.js +123 -0
  15. package/dist/client/renderer_log_transport.js.map +1 -0
  16. package/dist/codegen/controller_registration_generator.cjs +13 -2
  17. package/dist/codegen/controller_registration_generator.cjs.map +1 -1
  18. package/dist/codegen/controller_registration_generator.d.cts +12 -1
  19. package/dist/codegen/controller_registration_generator.d.ts +12 -1
  20. package/dist/codegen/controller_registration_generator.js +10 -1
  21. package/dist/codegen/controller_registration_generator.js.map +1 -1
  22. package/dist/codegen/index.d.cts +1 -0
  23. package/dist/codegen/index.d.ts +1 -0
  24. package/dist/codegen/preload_generator.cjs +13 -6
  25. package/dist/codegen/preload_generator.cjs.map +1 -1
  26. package/dist/codegen/preload_generator.d.cts +11 -2
  27. package/dist/codegen/preload_generator.d.ts +11 -2
  28. package/dist/codegen/preload_generator.js +13 -6
  29. package/dist/codegen/preload_generator.js.map +1 -1
  30. package/dist/codegen/renderer_app_generator.cjs +78 -42
  31. package/dist/codegen/renderer_app_generator.cjs.map +1 -1
  32. package/dist/codegen/renderer_app_generator.js +78 -42
  33. package/dist/codegen/renderer_app_generator.js.map +1 -1
  34. package/dist/codegen/type_generator.cjs +1 -0
  35. package/dist/codegen/type_generator.cjs.map +1 -1
  36. package/dist/codegen/type_generator.js +1 -0
  37. package/dist/codegen/type_generator.js.map +1 -1
  38. package/dist/config/config_parser.cjs +95 -4
  39. package/dist/config/config_parser.cjs.map +1 -1
  40. package/dist/config/config_parser.d.cts +10 -2
  41. package/dist/config/config_parser.d.ts +10 -2
  42. package/dist/config/config_parser.js +92 -3
  43. package/dist/config/config_parser.js.map +1 -1
  44. package/dist/config/index.cjs +6 -2
  45. package/dist/config/index.cjs.map +1 -1
  46. package/dist/config/index.d.cts +2 -2
  47. package/dist/config/index.d.ts +2 -2
  48. package/dist/config/index.js +8 -2
  49. package/dist/config/index.js.map +1 -1
  50. package/dist/controller/controller_resolver.cjs +51 -3
  51. package/dist/controller/controller_resolver.cjs.map +1 -1
  52. package/dist/controller/controller_resolver.d.cts +27 -4
  53. package/dist/controller/controller_resolver.d.ts +27 -4
  54. package/dist/controller/controller_resolver.js +48 -2
  55. package/dist/controller/controller_resolver.js.map +1 -1
  56. package/dist/controller/index.cjs +6 -2
  57. package/dist/controller/index.cjs.map +1 -1
  58. package/dist/controller/index.d.cts +1 -1
  59. package/dist/controller/index.d.ts +1 -1
  60. package/dist/controller/index.js +4 -2
  61. package/dist/controller/index.js.map +1 -1
  62. package/dist/dev/wood_dev_server.cjs +4 -1
  63. package/dist/dev/wood_dev_server.cjs.map +1 -1
  64. package/dist/dev/wood_dev_server.js +5 -2
  65. package/dist/dev/wood_dev_server.js.map +1 -1
  66. package/dist/dev/yaml_watcher.cjs +1 -1
  67. package/dist/dev/yaml_watcher.cjs.map +1 -1
  68. package/dist/dev/yaml_watcher.d.cts +4 -0
  69. package/dist/dev/yaml_watcher.d.ts +4 -0
  70. package/dist/dev/yaml_watcher.js +1 -1
  71. package/dist/dev/yaml_watcher.js.map +1 -1
  72. package/dist/frontend/frontend_lifecycle.cjs +74 -0
  73. package/dist/frontend/frontend_lifecycle.cjs.map +1 -0
  74. package/dist/frontend/frontend_lifecycle.d.cts +50 -0
  75. package/dist/frontend/frontend_lifecycle.d.ts +50 -0
  76. package/dist/frontend/frontend_lifecycle.js +50 -0
  77. package/dist/frontend/frontend_lifecycle.js.map +1 -0
  78. package/dist/frontend/frontend_page.cjs +122 -0
  79. package/dist/frontend/frontend_page.cjs.map +1 -0
  80. package/dist/frontend/frontend_page.d.cts +62 -0
  81. package/dist/frontend/frontend_page.d.ts +62 -0
  82. package/dist/frontend/frontend_page.js +98 -0
  83. package/dist/frontend/frontend_page.js.map +1 -0
  84. package/dist/frontend/frontend_surface.cjs +249 -0
  85. package/dist/frontend/frontend_surface.cjs.map +1 -0
  86. package/dist/frontend/frontend_surface.d.cts +64 -0
  87. package/dist/frontend/frontend_surface.d.ts +64 -0
  88. package/dist/frontend/frontend_surface.js +224 -0
  89. package/dist/frontend/frontend_surface.js.map +1 -0
  90. package/dist/frontend/index.cjs +52 -0
  91. package/dist/frontend/index.cjs.map +1 -0
  92. package/dist/frontend/index.d.cts +10 -0
  93. package/dist/frontend/index.d.ts +10 -0
  94. package/dist/frontend/index.js +19 -0
  95. package/dist/frontend/index.js.map +1 -0
  96. package/dist/frontend/page_catalog.cjs +135 -0
  97. package/dist/frontend/page_catalog.cjs.map +1 -0
  98. package/dist/frontend/page_catalog.d.cts +56 -0
  99. package/dist/frontend/page_catalog.d.ts +56 -0
  100. package/dist/frontend/page_catalog.js +108 -0
  101. package/dist/frontend/page_catalog.js.map +1 -0
  102. package/dist/frontend/tracked_transport.cjs +55 -0
  103. package/dist/frontend/tracked_transport.cjs.map +1 -0
  104. package/dist/frontend/tracked_transport.d.cts +36 -0
  105. package/dist/frontend/tracked_transport.d.ts +36 -0
  106. package/dist/frontend/tracked_transport.js +31 -0
  107. package/dist/frontend/tracked_transport.js.map +1 -0
  108. package/dist/frontend/work_registry.cjs +153 -0
  109. package/dist/frontend/work_registry.cjs.map +1 -0
  110. package/dist/frontend/work_registry.d.cts +70 -0
  111. package/dist/frontend/work_registry.d.ts +70 -0
  112. package/dist/frontend/work_registry.js +128 -0
  113. package/dist/frontend/work_registry.js.map +1 -0
  114. package/dist/index.cjs +24 -0
  115. package/dist/index.cjs.map +1 -1
  116. package/dist/index.d.cts +10 -7
  117. package/dist/index.d.ts +10 -7
  118. package/dist/index.js +27 -4
  119. package/dist/index.js.map +1 -1
  120. package/dist/main/index.cjs +10 -0
  121. package/dist/main/index.cjs.map +1 -1
  122. package/dist/main/index.d.cts +14 -2
  123. package/dist/main/index.d.ts +14 -2
  124. package/dist/main/index.js +16 -0
  125. package/dist/main/index.js.map +1 -1
  126. package/dist/middleware/middleware_resolver.cjs +22 -1
  127. package/dist/middleware/middleware_resolver.cjs.map +1 -1
  128. package/dist/middleware/middleware_resolver.d.cts +13 -1
  129. package/dist/middleware/middleware_resolver.d.ts +13 -1
  130. package/dist/middleware/middleware_resolver.js +22 -1
  131. package/dist/middleware/middleware_resolver.js.map +1 -1
  132. package/dist/navigation/index.cjs +3 -0
  133. package/dist/navigation/index.cjs.map +1 -1
  134. package/dist/navigation/index.d.cts +25 -1
  135. package/dist/navigation/index.d.ts +25 -1
  136. package/dist/navigation/index.js +2 -0
  137. package/dist/navigation/index.js.map +1 -1
  138. package/dist/{middleware/__fixtures__/middleware/auth.cjs → navigation/layout_preservation.cjs} +18 -20
  139. package/dist/navigation/layout_preservation.cjs.map +1 -0
  140. package/dist/navigation/layout_preservation.d.cts +2 -0
  141. package/dist/navigation/layout_preservation.d.ts +2 -0
  142. package/dist/navigation/layout_preservation.js +18 -0
  143. package/dist/navigation/layout_preservation.js.map +1 -0
  144. package/dist/parser/index.cjs +2 -0
  145. package/dist/parser/index.cjs.map +1 -1
  146. package/dist/parser/index.d.cts +1 -1
  147. package/dist/parser/index.d.ts +1 -1
  148. package/dist/parser/index.js +2 -1
  149. package/dist/parser/index.js.map +1 -1
  150. package/dist/parser/operations_parser.cjs +6 -0
  151. package/dist/parser/operations_parser.cjs.map +1 -1
  152. package/dist/parser/operations_parser.d.cts +9 -2
  153. package/dist/parser/operations_parser.d.ts +9 -2
  154. package/dist/parser/operations_parser.js +5 -0
  155. package/dist/parser/operations_parser.js.map +1 -1
  156. package/dist/parser/views_parser.cjs.map +1 -1
  157. package/dist/parser/views_parser.js.map +1 -1
  158. package/dist/router/index.d.cts +1 -0
  159. package/dist/router/index.d.ts +1 -0
  160. package/dist/router/wood_router.cjs +35 -3
  161. package/dist/router/wood_router.cjs.map +1 -1
  162. package/dist/router/wood_router.d.cts +15 -0
  163. package/dist/router/wood_router.d.ts +15 -0
  164. package/dist/router/wood_router.js +36 -4
  165. package/dist/router/wood_router.js.map +1 -1
  166. package/dist/runtime/get_container.cjs +9 -34
  167. package/dist/runtime/get_container.cjs.map +1 -1
  168. package/dist/runtime/get_container.d.cts +24 -4
  169. package/dist/runtime/get_container.d.ts +24 -4
  170. package/dist/runtime/get_container.js +8 -23
  171. package/dist/runtime/get_container.js.map +1 -1
  172. package/dist/runtime/index.cjs +9 -0
  173. package/dist/runtime/index.cjs.map +1 -1
  174. package/dist/runtime/index.d.cts +5 -2
  175. package/dist/runtime/index.d.ts +5 -2
  176. package/dist/runtime/index.js +10 -1
  177. package/dist/runtime/index.js.map +1 -1
  178. package/dist/runtime/renderer_config_extension.cjs +50 -0
  179. package/dist/runtime/renderer_config_extension.cjs.map +1 -0
  180. package/dist/runtime/renderer_config_extension.d.cts +19 -0
  181. package/dist/runtime/renderer_config_extension.d.ts +19 -0
  182. package/dist/runtime/renderer_config_extension.js +24 -0
  183. package/dist/runtime/renderer_config_extension.js.map +1 -0
  184. package/dist/runtime/renderer_log_batch_receiver.cjs +73 -0
  185. package/dist/runtime/renderer_log_batch_receiver.cjs.map +1 -0
  186. package/dist/runtime/renderer_log_batch_receiver.d.cts +29 -0
  187. package/dist/runtime/renderer_log_batch_receiver.d.ts +29 -0
  188. package/dist/runtime/renderer_log_batch_receiver.js +48 -0
  189. package/dist/runtime/renderer_log_batch_receiver.js.map +1 -0
  190. package/dist/runtime/renderer_trace_batch_receiver_registry.d.cts +1 -1
  191. package/dist/runtime/renderer_trace_batch_receiver_registry.d.ts +1 -1
  192. package/dist/runtime/runtime.cjs +14 -0
  193. package/dist/runtime/runtime.cjs.map +1 -1
  194. package/dist/runtime/runtime.d.cts +2 -1
  195. package/dist/runtime/runtime.d.ts +2 -1
  196. package/dist/runtime/runtime.js +14 -0
  197. package/dist/runtime/runtime.js.map +1 -1
  198. package/dist/stick/index.cjs.map +1 -1
  199. package/dist/stick/index.js.map +1 -1
  200. package/dist/testing/browser.cjs +104 -23
  201. package/dist/testing/browser.cjs.map +1 -1
  202. package/dist/testing/browser.d.cts +8 -3
  203. package/dist/testing/browser.d.ts +8 -3
  204. package/dist/testing/browser.js +102 -22
  205. package/dist/testing/browser.js.map +1 -1
  206. package/dist/testing/create_controller_harness.cjs +28 -8
  207. package/dist/testing/create_controller_harness.cjs.map +1 -1
  208. package/dist/testing/create_controller_harness.d.cts +17 -2
  209. package/dist/testing/create_controller_harness.d.ts +17 -2
  210. package/dist/testing/create_controller_harness.js +28 -8
  211. package/dist/testing/create_controller_harness.js.map +1 -1
  212. package/dist/testing/create_router_bridge.d.cts +1 -0
  213. package/dist/testing/create_router_bridge.d.ts +1 -0
  214. package/dist/testing/create_test_router.d.cts +1 -0
  215. package/dist/testing/create_test_router.d.ts +1 -0
  216. package/dist/testing/index.cjs +31 -0
  217. package/dist/testing/index.cjs.map +1 -1
  218. package/dist/testing/index.d.cts +20 -5
  219. package/dist/testing/index.d.ts +20 -5
  220. package/dist/testing/index.js +19 -1
  221. package/dist/testing/index.js.map +1 -1
  222. package/dist/{controller/__fixtures__/controllers/not_a_class.cjs → testing/test_wood.cjs} +15 -7
  223. package/dist/testing/test_wood.cjs.map +1 -0
  224. package/dist/testing/test_wood.d.cts +16 -0
  225. package/dist/testing/test_wood.d.ts +16 -0
  226. package/dist/testing/test_wood.js +12 -0
  227. package/dist/testing/test_wood.js.map +1 -0
  228. package/dist/testing/test_wood_config.cjs +272 -0
  229. package/dist/testing/test_wood_config.cjs.map +1 -0
  230. package/dist/testing/test_wood_config.d.cts +111 -0
  231. package/dist/testing/test_wood_config.d.ts +111 -0
  232. package/dist/testing/test_wood_config.js +247 -0
  233. package/dist/testing/test_wood_config.js.map +1 -0
  234. package/dist/testing/wood_config_source.cjs +146 -0
  235. package/dist/testing/wood_config_source.cjs.map +1 -0
  236. package/dist/testing/wood_config_source.d.cts +36 -0
  237. package/dist/testing/wood_config_source.d.ts +36 -0
  238. package/dist/testing/wood_config_source.js +112 -0
  239. package/dist/testing/wood_config_source.js.map +1 -0
  240. package/dist/testing/wood_env_renderer.cjs +210 -0
  241. package/dist/testing/wood_env_renderer.cjs.map +1 -0
  242. package/dist/testing/wood_env_renderer.d.cts +74 -0
  243. package/dist/testing/wood_env_renderer.d.ts +74 -0
  244. package/dist/testing/wood_env_renderer.js +188 -0
  245. package/dist/testing/wood_env_renderer.js.map +1 -0
  246. package/dist/testing/wood_test_selection.cjs +94 -0
  247. package/dist/testing/wood_test_selection.cjs.map +1 -0
  248. package/dist/testing/wood_test_selection.d.cts +39 -0
  249. package/dist/testing/wood_test_selection.d.ts +39 -0
  250. package/dist/testing/wood_test_selection.js +68 -0
  251. package/dist/testing/wood_test_selection.js.map +1 -0
  252. package/dist/trace-testing/index.d.cts +1 -2
  253. package/dist/trace-testing/index.d.ts +1 -2
  254. package/dist/trace-testing/trace_recorder.cjs +1 -1
  255. package/dist/trace-testing/trace_recorder.cjs.map +1 -1
  256. package/dist/trace-testing/trace_recorder.d.cts +1 -2
  257. package/dist/trace-testing/trace_recorder.d.ts +1 -2
  258. package/dist/trace-testing/trace_recorder.js +1 -1
  259. package/dist/trace-testing/trace_recorder.js.map +1 -1
  260. package/dist/trace-transport/index.d.cts +1 -1
  261. package/dist/trace-transport/index.d.ts +1 -1
  262. package/dist/{trace_hub-Cob54qRx.d.cts → trace_hub-Cpo_nVze.d.cts} +21 -1
  263. package/dist/{trace_hub-Cob54qRx.d.ts → trace_hub-Cpo_nVze.d.ts} +21 -1
  264. package/dist/tracing/index.cjs +9 -2
  265. package/dist/tracing/index.cjs.map +1 -1
  266. package/dist/tracing/index.d.cts +3 -2
  267. package/dist/tracing/index.d.ts +3 -2
  268. package/dist/tracing/index.js +7 -1
  269. package/dist/tracing/index.js.map +1 -1
  270. package/dist/tracing/renderer_trace_batch_host.d.cts +1 -1
  271. package/dist/tracing/renderer_trace_batch_host.d.ts +1 -1
  272. package/dist/tracing/renderer_trace_batch_transport.cjs +48 -6
  273. package/dist/tracing/renderer_trace_batch_transport.cjs.map +1 -1
  274. package/dist/tracing/renderer_trace_batch_transport.d.cts +17 -1
  275. package/dist/tracing/renderer_trace_batch_transport.d.ts +17 -1
  276. package/dist/tracing/renderer_trace_batch_transport.js +48 -6
  277. package/dist/tracing/renderer_trace_batch_transport.js.map +1 -1
  278. package/dist/tracing/trace_batch_adapter.cjs +110 -0
  279. package/dist/tracing/trace_batch_adapter.cjs.map +1 -0
  280. package/dist/tracing/trace_batch_adapter.d.cts +36 -0
  281. package/dist/tracing/trace_batch_adapter.d.ts +36 -0
  282. package/dist/tracing/trace_batch_adapter.js +86 -0
  283. package/dist/tracing/trace_batch_adapter.js.map +1 -0
  284. package/dist/tracing/trace_commit_writer.d.cts +1 -1
  285. package/dist/tracing/trace_commit_writer.d.ts +1 -1
  286. package/dist/tracing/trace_hub.cjs +87 -20
  287. package/dist/tracing/trace_hub.cjs.map +1 -1
  288. package/dist/tracing/trace_hub.d.cts +1 -1
  289. package/dist/tracing/trace_hub.d.ts +1 -1
  290. package/dist/tracing/trace_hub.js +85 -20
  291. package/dist/tracing/trace_hub.js.map +1 -1
  292. package/dist/tracing/trace_provider.cjs +21 -6
  293. package/dist/tracing/trace_provider.cjs.map +1 -1
  294. package/dist/tracing/trace_provider.d.cts +13 -4
  295. package/dist/tracing/trace_provider.d.ts +13 -4
  296. package/dist/tracing/trace_provider.js +22 -7
  297. package/dist/tracing/trace_provider.js.map +1 -1
  298. package/dist/tracing/types/wood_trace_batch.types.cjs.map +1 -1
  299. package/dist/tracing/types/wood_trace_batch.types.d.cts +15 -1
  300. package/dist/tracing/types/wood_trace_batch.types.d.ts +15 -1
  301. package/dist/tracing/types/wood_trace_sink.types.d.cts +1 -1
  302. package/dist/tracing/types/wood_trace_sink.types.d.ts +1 -1
  303. package/dist/tracing/wood_trace_batch_contract.cjs +2 -0
  304. package/dist/tracing/wood_trace_batch_contract.cjs.map +1 -1
  305. package/dist/tracing/wood_trace_batch_contract.d.cts +1 -1
  306. package/dist/tracing/wood_trace_batch_contract.d.ts +1 -1
  307. package/dist/tracing/wood_trace_batch_contract.js +2 -0
  308. package/dist/tracing/wood_trace_batch_contract.js.map +1 -1
  309. package/dist/transport/build_transport_bridge.cjs +4 -2
  310. package/dist/transport/build_transport_bridge.cjs.map +1 -1
  311. package/dist/transport/build_transport_bridge.d.cts +7 -1
  312. package/dist/transport/build_transport_bridge.d.ts +7 -1
  313. package/dist/transport/build_transport_bridge.js +2 -1
  314. package/dist/transport/build_transport_bridge.js.map +1 -1
  315. package/dist/transport/in_process_router_transport.d.cts +1 -0
  316. package/dist/transport/in_process_router_transport.d.ts +1 -0
  317. package/dist/transport/index.d.cts +1 -0
  318. package/dist/transport/index.d.ts +1 -0
  319. package/dist/types/config.cjs.map +1 -1
  320. package/dist/types/config.d.cts +47 -1
  321. package/dist/types/config.d.ts +47 -1
  322. package/dist/types/context.cjs +12 -0
  323. package/dist/types/context.cjs.map +1 -1
  324. package/dist/types/context.d.cts +27 -1
  325. package/dist/types/context.d.ts +27 -1
  326. package/dist/types/context.js +4 -0
  327. package/dist/types/context.js.map +1 -1
  328. package/dist/types/index.d.cts +2 -2
  329. package/dist/types/index.d.ts +2 -2
  330. package/dist/types/operations.cjs.map +1 -1
  331. package/dist/types/operations.d.cts +2 -0
  332. package/dist/types/operations.d.ts +2 -0
  333. package/docs/axe.md +706 -0
  334. package/package.json +13 -5
  335. package/src/components/NavigationShell.scopes.browser.test.ts +363 -0
  336. package/src/components/NavigationShell.svelte +126 -49
  337. package/dist/controller/__fixtures__/controllers/chat.cjs +0 -32
  338. package/dist/controller/__fixtures__/controllers/chat.cjs.map +0 -1
  339. package/dist/controller/__fixtures__/controllers/chat.d.cts +0 -11
  340. package/dist/controller/__fixtures__/controllers/chat.d.ts +0 -11
  341. package/dist/controller/__fixtures__/controllers/chat.js +0 -12
  342. package/dist/controller/__fixtures__/controllers/chat.js.map +0 -1
  343. package/dist/controller/__fixtures__/controllers/not_a_class.cjs.map +0 -1
  344. package/dist/controller/__fixtures__/controllers/not_a_class.d.cts +0 -3
  345. package/dist/controller/__fixtures__/controllers/not_a_class.d.ts +0 -3
  346. package/dist/controller/__fixtures__/controllers/not_a_class.js +0 -5
  347. package/dist/controller/__fixtures__/controllers/not_a_class.js.map +0 -1
  348. package/dist/controller/__fixtures__/controllers/settings.controller.cjs +0 -32
  349. package/dist/controller/__fixtures__/controllers/settings.controller.cjs.map +0 -1
  350. package/dist/controller/__fixtures__/controllers/settings.controller.d.cts +0 -12
  351. package/dist/controller/__fixtures__/controllers/settings.controller.d.ts +0 -12
  352. package/dist/controller/__fixtures__/controllers/settings.controller.js +0 -12
  353. package/dist/controller/__fixtures__/controllers/settings.controller.js.map +0 -1
  354. package/dist/controller/__fixtures__/controllers/test.cjs +0 -29
  355. package/dist/controller/__fixtures__/controllers/test.cjs.map +0 -1
  356. package/dist/controller/__fixtures__/controllers/test.d.cts +0 -7
  357. package/dist/controller/__fixtures__/controllers/test.d.ts +0 -7
  358. package/dist/controller/__fixtures__/controllers/test.js +0 -9
  359. package/dist/controller/__fixtures__/controllers/test.js.map +0 -1
  360. package/dist/loader/__fixtures__/layouts/app.load.cjs +0 -27
  361. package/dist/loader/__fixtures__/layouts/app.load.cjs.map +0 -1
  362. package/dist/loader/__fixtures__/layouts/app.load.d.cts +0 -5
  363. package/dist/loader/__fixtures__/layouts/app.load.d.ts +0 -5
  364. package/dist/loader/__fixtures__/layouts/app.load.js +0 -7
  365. package/dist/loader/__fixtures__/layouts/app.load.js.map +0 -1
  366. package/dist/loader/__fixtures__/views/test/page.load.cjs +0 -27
  367. package/dist/loader/__fixtures__/views/test/page.load.cjs.map +0 -1
  368. package/dist/loader/__fixtures__/views/test/page.load.d.cts +0 -6
  369. package/dist/loader/__fixtures__/views/test/page.load.d.ts +0 -6
  370. package/dist/loader/__fixtures__/views/test/page.load.js +0 -7
  371. package/dist/loader/__fixtures__/views/test/page.load.js.map +0 -1
  372. package/dist/middleware/__fixtures__/middleware/auth.cjs.map +0 -1
  373. package/dist/middleware/__fixtures__/middleware/auth.d.cts +0 -6
  374. package/dist/middleware/__fixtures__/middleware/auth.d.ts +0 -6
  375. package/dist/middleware/__fixtures__/middleware/auth.js +0 -19
  376. package/dist/middleware/__fixtures__/middleware/auth.js.map +0 -1
  377. package/dist/middleware/__fixtures__/middleware/sequence.cjs +0 -47
  378. package/dist/middleware/__fixtures__/middleware/sequence.cjs.map +0 -1
  379. package/dist/middleware/__fixtures__/middleware/sequence.d.cts +0 -7
  380. package/dist/middleware/__fixtures__/middleware/sequence.d.ts +0 -7
  381. package/dist/middleware/__fixtures__/middleware/sequence.js +0 -21
  382. package/dist/middleware/__fixtures__/middleware/sequence.js.map +0 -1
@@ -0,0 +1,188 @@
1
+ import { ExecutionContext, LoadAs } from "@noego/ioc";
2
+ import { InProcessRouterTransport } from "../transport/in_process_router_transport.js";
3
+ import { buildTransportBridge } from "../transport/build_transport_bridge.js";
4
+ import { RouterBridgeEvents } from "./create_router_bridge.js";
5
+ import { Navigation } from "../navigation/index.js";
6
+ import { createWoodRoot } from "../runtime/get_container.js";
7
+ import { WorkRegistry } from "../frontend/work_registry.js";
8
+ import { TrackedTransport } from "../frontend/tracked_transport.js";
9
+ import {
10
+ createFrontendSurface
11
+ } from "../frontend/frontend_surface.js";
12
+ import { TestWoodError, WOOD_FRONTEND_BRIDGE } from "./test_wood.js";
13
+ import { importDefaultExport } from "./wood_config_source.js";
14
+ function controllerLoader(source, importer) {
15
+ const cache = /* @__PURE__ */ new Map();
16
+ return (identity) => {
17
+ let pending = cache.get(identity);
18
+ if (!pending) {
19
+ pending = importDefaultExport(
20
+ importer,
21
+ source.rendererControllerFile(identity),
22
+ `renderer controller "${identity}"`
23
+ );
24
+ cache.set(identity, pending);
25
+ }
26
+ return pending;
27
+ };
28
+ }
29
+ async function loadPageHost(source, importer, dom) {
30
+ if (dom === "chromium") {
31
+ throw new TestWoodError("select({ dom: 'chromium' }) is not available yet; use 'happy-dom'");
32
+ }
33
+ if (typeof document === "undefined") {
34
+ throw new TestWoodError(
35
+ "select({ dom: 'happy-dom' }) requires a DOM environment (// @vitest-environment happy-dom)"
36
+ );
37
+ }
38
+ const hostPath = source.hookModule(source.config.renderer.testing?.host);
39
+ if (!hostPath) {
40
+ throw new TestWoodError(
41
+ "select({ dom }) requires renderer.testing.host in wood.config.yml (a module whose default export mounts a page)"
42
+ );
43
+ }
44
+ return importDefaultExport(importer, hostPath, "renderer.testing.host");
45
+ }
46
+ class MountKeeper {
47
+ constructor(host) {
48
+ this.host = host;
49
+ this.mounted = null;
50
+ this.mountedFor = null;
51
+ }
52
+ get target() {
53
+ if (!this.mounted) throw new TestWoodError("no page is mounted; open(page) first");
54
+ return this.mounted.target;
55
+ }
56
+ async flush() {
57
+ await this.mounted?.flush?.();
58
+ }
59
+ sync(current) {
60
+ if (current === this.mountedFor) return;
61
+ this.unmount();
62
+ if (!current) return;
63
+ const target = document.createElement("div");
64
+ document.body.appendChild(target);
65
+ this.mounted = this.host(current.identity, current, target);
66
+ this.mountedFor = current;
67
+ }
68
+ unmount() {
69
+ this.mounted?.unmount();
70
+ this.mounted?.target.remove();
71
+ this.mounted = null;
72
+ this.mountedFor = null;
73
+ }
74
+ }
75
+ function domDriver(keeper) {
76
+ const find = (selector) => {
77
+ const found = keeper.target.querySelector(selector);
78
+ if (!found) throw new TestWoodError(`no element matches "${selector}"`);
79
+ return found;
80
+ };
81
+ return {
82
+ get target() {
83
+ return keeper.target;
84
+ },
85
+ async click(selector) {
86
+ find(selector).click();
87
+ await keeper.flush();
88
+ },
89
+ async type(selector, text) {
90
+ const input = find(selector);
91
+ input.focus();
92
+ input.value = text;
93
+ input.dispatchEvent(new Event("input", { bubbles: true }));
94
+ await keeper.flush();
95
+ },
96
+ async submit(selector) {
97
+ find(selector).dispatchEvent(new Event("submit", { bubbles: true, cancelable: true }));
98
+ await keeper.flush();
99
+ },
100
+ async text(selector) {
101
+ return keeper.target.querySelector(selector)?.textContent ?? "";
102
+ },
103
+ async exists(selector) {
104
+ return keeper.target.querySelector(selector) !== null;
105
+ }
106
+ };
107
+ }
108
+ async function buildRendererTier(options) {
109
+ const { source, router, catalog, operations, importer, hooks, dom } = options;
110
+ const keeper = dom ? new MountKeeper(await loadPageHost(source, importer, dom)) : null;
111
+ const rendererRoot = createWoodRoot();
112
+ await hooks?.configureRendererRoot?.(rendererRoot);
113
+ const registry = new WorkRegistry();
114
+ const navigation = new Navigation();
115
+ const innerTransport = new InProcessRouterTransport(router, hooks?.events ?? new RouterBridgeEvents());
116
+ let currentOwner = () => "application";
117
+ const transport = new TrackedTransport(innerTransport, registry, () => currentOwner());
118
+ const { bridge } = buildTransportBridge(operations, transport);
119
+ const registrable = rendererRoot;
120
+ registrable.registerFunction(Navigation, () => navigation, { loadAs: LoadAs.Singleton });
121
+ registrable.registerFunction(WOOD_FRONTEND_BRIDGE, () => bridge, { loadAs: LoadAs.Singleton });
122
+ const loadController = controllerLoader(source, importer);
123
+ const frontend = createFrontendSurface({
124
+ catalog,
125
+ rendererRoot,
126
+ registry,
127
+ navigation,
128
+ resolveController: (identity) => loadController(identity),
129
+ ...hooks?.configurePageScope ? { configurePageScope: (scope, view, context) => hooks.configurePageScope(scope, view, context) } : {}
130
+ });
131
+ currentOwner = () => {
132
+ const current = frontend.current();
133
+ return current ? `page ${current.identity}` : "application";
134
+ };
135
+ const syncMount = async () => {
136
+ if (!keeper) return;
137
+ keeper.sync(frontend.current());
138
+ await keeper.flush();
139
+ };
140
+ const settle = async () => {
141
+ await frontend.settle();
142
+ if (!keeper) return;
143
+ await syncMount();
144
+ await new Promise((resolve) => setTimeout(resolve, 0));
145
+ await keeper.flush();
146
+ };
147
+ return {
148
+ frontend,
149
+ events: innerTransport.events,
150
+ rendererRoot,
151
+ async open(page, params, query) {
152
+ const opened = await frontend.open({
153
+ page,
154
+ ...params ? { params } : {},
155
+ ...query ? { query } : {}
156
+ });
157
+ await syncMount();
158
+ return opened;
159
+ },
160
+ async navigate(page, params, query) {
161
+ if (!frontend.current()) throw new TestWoodError("navigate() needs an open page; call open(page) first");
162
+ await frontend.act(() => navigation.go(page, params, query));
163
+ await syncMount();
164
+ const current = frontend.current();
165
+ if (!current) throw new TestWoodError(`navigate("${page}") left no page open`);
166
+ return current;
167
+ },
168
+ current: () => frontend.current(),
169
+ settle,
170
+ pendingWork: () => registry.pending(),
171
+ dom: keeper ? domDriver(keeper) : null,
172
+ async dispose() {
173
+ keeper?.unmount();
174
+ await ExecutionContext.run(rendererRoot, async () => {
175
+ await frontend.settle().catch(() => {
176
+ });
177
+ await frontend.dispose();
178
+ await frontend.settle().catch(() => {
179
+ });
180
+ await rendererRoot.dispose();
181
+ });
182
+ }
183
+ };
184
+ }
185
+ export {
186
+ buildRendererTier
187
+ };
188
+ //# sourceMappingURL=wood_env_renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/testing/wood_env_renderer.ts"],"sourcesContent":["/**\n * The renderer tier of a `testWood(configPath)` environment: a fresh renderer\n * root (mirroring the production process split), an environment-local\n * Navigation, the generated bridge client over an in-process transport into\n * the main router, and the frontend application surface over the selected\n * page catalog. With a DOM mode, the page's real component is mounted by the\n * app's host module and driven through a selector-based surface.\n */\nimport type { IContainer } from '@noego/ioc';\nimport { ExecutionContext, LoadAs } from '@noego/ioc';\nimport type { WoodRouter } from '../router/wood_router.js';\nimport { InProcessRouterTransport } from '../transport/in_process_router_transport.js';\nimport { buildTransportBridge } from '../transport/build_transport_bridge.js';\nimport { RouterBridgeEvents } from './create_router_bridge.js';\nimport type { OperationDef, ViewDef } from '../types/index.js';\nimport { Navigation } from '../navigation/index.js';\nimport { createWoodRoot } from '../runtime/get_container.js';\nimport type { PageCatalog } from '../frontend/page_catalog.js';\nimport { WorkRegistry } from '../frontend/work_registry.js';\nimport { TrackedTransport } from '../frontend/tracked_transport.js';\nimport {\n createFrontendSurface,\n type FrontendApplicationSurface,\n type PageScopeContext,\n} from '../frontend/frontend_surface.js';\nimport type { FrontendPage } from '../frontend/frontend_page.js';\nimport { TestWoodError, WOOD_FRONTEND_BRIDGE } from './test_wood.js';\nimport { importDefaultExport, type ModuleImporter, type WoodConfigSource } from './wood_config_source.js';\nimport type { WoodDomMode } from './wood_test_selection.js';\n\n/** What the app's `main.testing.compose` module may hand back for the renderer side. */\nexport interface WoodRendererHooks {\n /** Backend push emitter feeding renderer subscriptions (default: transport-owned). */\n events?: RouterBridgeEvents;\n /** Register app-owned renderer composition on the fresh renderer root. */\n configureRendererRoot?(root: IContainer): void | Promise<void>;\n /** Register per-scope renderer builtins on a new page/layout scope. */\n configurePageScope?(scope: IContainer, view: ViewDef, context: PageScopeContext): void | Promise<void>;\n}\n\n/** A page's real component mounted under a DOM driver (`renderer.testing.host`). */\nexport interface WoodMountedPage {\n readonly target: Element;\n flush?(): void | Promise<void>;\n unmount(): void;\n}\n\nexport type WoodPageHost = (identity: string, page: FrontendPage, target: Element) => WoodMountedPage;\n\nexport interface RendererTierOptions {\n source: WoodConfigSource;\n router: WoodRouter;\n catalog: PageCatalog;\n operations: Map<string, OperationDef>;\n importer: ModuleImporter;\n hooks: WoodRendererHooks | null;\n dom: WoodDomMode | null;\n}\n\nexport interface WoodDomDriver {\n readonly target: Element;\n click(selector: string): Promise<void>;\n type(selector: string, text: string): Promise<void>;\n submit(selector: string): Promise<void>;\n text(selector: string): Promise<string>;\n exists(selector: string): Promise<boolean>;\n}\n\nexport interface RendererTier {\n readonly frontend: FrontendApplicationSurface;\n readonly events: RouterBridgeEvents;\n readonly rendererRoot: IContainer;\n open(page: string, params?: Record<string, string>, query?: Record<string, string>): Promise<FrontendPage>;\n navigate(page: string, params?: Record<string, string>, query?: Record<string, string>): Promise<FrontendPage>;\n current(): FrontendPage | null;\n settle(): Promise<void>;\n pendingWork(): ReturnType<WorkRegistry['pending']>;\n dom: WoodDomDriver | null;\n dispose(): Promise<void>;\n}\n\ntype ControllerClass = new (...args: never[]) => unknown;\n\nfunction controllerLoader(source: WoodConfigSource, importer: ModuleImporter) {\n const cache = new Map<string, Promise<ControllerClass>>();\n return (identity: string): Promise<ControllerClass> => {\n let pending = cache.get(identity);\n if (!pending) {\n pending = importDefaultExport<ControllerClass>(\n importer,\n source.rendererControllerFile(identity),\n `renderer controller \"${identity}\"`,\n );\n cache.set(identity, pending);\n }\n return pending;\n };\n}\n\nasync function loadPageHost(\n source: WoodConfigSource,\n importer: ModuleImporter,\n dom: WoodDomMode,\n): Promise<WoodPageHost> {\n if (dom === 'chromium') {\n throw new TestWoodError(\"select({ dom: 'chromium' }) is not available yet; use 'happy-dom'\");\n }\n if (typeof document === 'undefined') {\n throw new TestWoodError(\n \"select({ dom: 'happy-dom' }) requires a DOM environment (// @vitest-environment happy-dom)\",\n );\n }\n const hostPath = source.hookModule(source.config.renderer.testing?.host);\n if (!hostPath) {\n throw new TestWoodError(\n 'select({ dom }) requires renderer.testing.host in wood.config.yml (a module whose default export mounts a page)',\n );\n }\n return importDefaultExport<WoodPageHost>(importer, hostPath, 'renderer.testing.host');\n}\n\n/** Keeps the mounted component in step with the surface's current page. */\nclass MountKeeper {\n private mounted: WoodMountedPage | null = null;\n private mountedFor: FrontendPage | null = null;\n\n constructor(private readonly host: WoodPageHost) {}\n\n get target(): Element {\n if (!this.mounted) throw new TestWoodError('no page is mounted; open(page) first');\n return this.mounted.target;\n }\n\n async flush(): Promise<void> {\n await this.mounted?.flush?.();\n }\n\n sync(current: FrontendPage | null): void {\n if (current === this.mountedFor) return;\n this.unmount();\n if (!current) return;\n const target = document.createElement('div');\n document.body.appendChild(target);\n this.mounted = this.host(current.identity, current, target);\n this.mountedFor = current;\n }\n\n unmount(): void {\n this.mounted?.unmount();\n this.mounted?.target.remove();\n this.mounted = null;\n this.mountedFor = null;\n }\n}\n\nfunction domDriver(keeper: MountKeeper): WoodDomDriver {\n const find = (selector: string): Element => {\n const found = keeper.target.querySelector(selector);\n if (!found) throw new TestWoodError(`no element matches \"${selector}\"`);\n return found;\n };\n return {\n get target() {\n return keeper.target;\n },\n async click(selector) {\n (find(selector) as HTMLElement).click();\n await keeper.flush();\n },\n async type(selector, text) {\n const input = find(selector) as HTMLInputElement;\n input.focus();\n input.value = text;\n input.dispatchEvent(new Event('input', { bubbles: true }));\n await keeper.flush();\n },\n async submit(selector) {\n find(selector).dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }));\n await keeper.flush();\n },\n async text(selector) {\n return keeper.target.querySelector(selector)?.textContent ?? '';\n },\n async exists(selector) {\n return keeper.target.querySelector(selector) !== null;\n },\n };\n}\n\nexport async function buildRendererTier(options: RendererTierOptions): Promise<RendererTier> {\n const { source, router, catalog, operations, importer, hooks, dom } = options;\n const keeper = dom ? new MountKeeper(await loadPageHost(source, importer, dom)) : null;\n\n const rendererRoot = createWoodRoot();\n await hooks?.configureRendererRoot?.(rendererRoot);\n\n const registry = new WorkRegistry();\n const navigation = new Navigation();\n const innerTransport = new InProcessRouterTransport(router, hooks?.events ?? new RouterBridgeEvents());\n let currentOwner: () => string = () => 'application';\n const transport = new TrackedTransport(innerTransport, registry, () => currentOwner());\n const { bridge } = buildTransportBridge(operations, transport);\n\n const registrable = rendererRoot as unknown as {\n registerFunction(token: unknown, factory: () => unknown, options: { loadAs: LoadAs }): void;\n };\n registrable.registerFunction(Navigation, () => navigation, { loadAs: LoadAs.Singleton });\n registrable.registerFunction(WOOD_FRONTEND_BRIDGE, () => bridge, { loadAs: LoadAs.Singleton });\n\n const loadController = controllerLoader(source, importer);\n const frontend = createFrontendSurface({\n catalog,\n rendererRoot: rendererRoot as never,\n registry,\n navigation,\n resolveController: (identity) => loadController(identity),\n ...(hooks?.configurePageScope\n ? { configurePageScope: (scope, view, context) => hooks.configurePageScope!(scope as IContainer, view, context) }\n : {}),\n });\n currentOwner = () => {\n const current = frontend.current();\n return current ? `page ${current.identity}` : 'application';\n };\n\n const syncMount = async (): Promise<void> => {\n if (!keeper) return;\n keeper.sync(frontend.current());\n await keeper.flush();\n };\n const settle = async (): Promise<void> => {\n await frontend.settle();\n if (!keeper) return;\n await syncMount();\n await new Promise<void>((resolve) => setTimeout(resolve, 0));\n await keeper.flush();\n };\n\n return {\n frontend,\n events: innerTransport.events,\n rendererRoot,\n async open(page, params, query) {\n const opened = await frontend.open({\n page,\n ...(params ? { params } : {}),\n ...(query ? { query } : {}),\n });\n await syncMount();\n return opened;\n },\n async navigate(page, params, query) {\n if (!frontend.current()) throw new TestWoodError('navigate() needs an open page; call open(page) first');\n await frontend.act(() => navigation.go(page, params, query));\n await syncMount();\n const current = frontend.current();\n if (!current) throw new TestWoodError(`navigate(\"${page}\") left no page open`);\n return current;\n },\n current: () => frontend.current(),\n settle,\n pendingWork: () => registry.pending(),\n dom: keeper ? domDriver(keeper) : null,\n async dispose() {\n keeper?.unmount();\n await ExecutionContext.run(rendererRoot as never, async () => {\n // Drain owned work while the transport still reaches a live main\n // root, end the pages, then drain the teardown's own deliveries.\n await frontend.settle().catch(() => {});\n await frontend.dispose();\n await frontend.settle().catch(() => {});\n await rendererRoot.dispose();\n });\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var wood_test_selection_exports = {};
20
+ __export(wood_test_selection_exports, {
21
+ resolveSelection: () => resolveSelection,
22
+ selectCatalog: () => selectCatalog,
23
+ selectOperations: () => selectOperations
24
+ });
25
+ module.exports = __toCommonJS(wood_test_selection_exports);
26
+ var import_page_catalog = require("../frontend/page_catalog.js");
27
+ var import_test_wood = require("./test_wood.cjs");
28
+ const DOM_MODES = ["happy-dom", "chromium"];
29
+ function isMainSelection(value) {
30
+ if (value === true) return true;
31
+ if (!value || typeof value !== "object") return false;
32
+ const candidate = value;
33
+ const hasOperation = typeof candidate.operation === "string" && candidate.operation.length > 0;
34
+ const hasModule = typeof candidate.module === "string" && candidate.module.length > 0;
35
+ return hasOperation !== hasModule;
36
+ }
37
+ function isPagesSelection(value) {
38
+ if (value === true) return true;
39
+ return Array.isArray(value) && value.length > 0 && value.every((entry) => typeof entry === "string" && entry.length > 0);
40
+ }
41
+ function resolveSelection(selection) {
42
+ if (!selection || typeof selection !== "object") {
43
+ throw new import_test_wood.TestWoodError("select() requires { main }, { pages }, or both (plus optional dom)");
44
+ }
45
+ const { main, pages, dom } = selection;
46
+ if (main !== void 0 && !isMainSelection(main)) {
47
+ throw new import_test_wood.TestWoodError("select({ main }) must be true, { operation: string } or { module: string }");
48
+ }
49
+ if (pages !== void 0 && !isPagesSelection(pages)) {
50
+ throw new import_test_wood.TestWoodError("select({ pages }) must be true or a non-empty list of page identities");
51
+ }
52
+ if (dom !== void 0 && !DOM_MODES.includes(dom)) {
53
+ throw new import_test_wood.TestWoodError(`select({ dom }) must be one of: ${DOM_MODES.join(", ")}`);
54
+ }
55
+ if (dom !== void 0 && pages === void 0) {
56
+ throw new import_test_wood.TestWoodError("select({ dom }) requires { pages }: a component needs a page to mount");
57
+ }
58
+ if (main === void 0 && pages === void 0) {
59
+ throw new import_test_wood.TestWoodError("select() built nothing: add { main } and/or { pages }");
60
+ }
61
+ return { main: main ?? true, pages: pages ?? null, dom: dom ?? null };
62
+ }
63
+ function operationIdentities(operations) {
64
+ if (!operations.size) return "the config defines no operations";
65
+ return `available operations:
66
+ ${[...operations.keys()].join("\n ")}`;
67
+ }
68
+ function selectOperations(all, main) {
69
+ if (main === true) return new Map(all);
70
+ if ("module" in main) {
71
+ const matched = new Map([...all].filter(([, operation]) => operation.module === main.module));
72
+ if (matched.size) return matched;
73
+ const modules = [...new Set([...all.values()].map((operation) => operation.module).filter(Boolean))];
74
+ throw new import_test_wood.TestWoodError(
75
+ `unknown module "${main.module}"; ` + (modules.length ? `available modules: ${modules.join(", ")}` : "the config defines no modules")
76
+ );
77
+ }
78
+ const match = all.get(main.operation);
79
+ if (!match) {
80
+ throw new import_test_wood.TestWoodError(`no operation matches "${main.operation}"; ${operationIdentities(all)}`);
81
+ }
82
+ return /* @__PURE__ */ new Map([[main.operation, match]]);
83
+ }
84
+ function selectCatalog(views, pages) {
85
+ const catalog = new import_page_catalog.PageCatalog(views);
86
+ return pages === true ? catalog : catalog.select({ pages });
87
+ }
88
+ // Annotate the CommonJS export names for ESM import in node:
89
+ 0 && (module.exports = {
90
+ resolveSelection,
91
+ selectCatalog,
92
+ selectOperations
93
+ });
94
+ //# sourceMappingURL=wood_test_selection.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/testing/wood_test_selection.ts"],"sourcesContent":["/**\n * `testWood(configPath).select({...})` — one declarative object says which\n * tiers exist and how they are observed:\n *\n * main true | { operation } | { module } the router + real controllers\n * pages true | [identity, ...] the renderer page catalog\n * dom 'happy-dom' | 'chromium' the page's real component\n *\n * A key that is absent is not built. `pages` implies `main: true`; `dom`\n * requires `pages`. Nothing opens at build — tests drive `open()`.\n */\nimport type { OperationDef, ViewDef } from '../types/index.cjs';\nimport { PageCatalog } from '../frontend/page_catalog.js';\nimport { TestWoodError } from './test_wood.cjs';\n\nexport type WoodMainSelection = true | { operation: string } | { module: string };\nexport type WoodDomMode = 'happy-dom' | 'chromium';\n\nexport interface WoodTestSelection {\n main?: WoodMainSelection;\n pages?: true | string[];\n dom?: WoodDomMode;\n}\n\nexport interface ResolvedWoodSelection {\n readonly main: WoodMainSelection;\n readonly pages: true | string[] | null;\n readonly dom: WoodDomMode | null;\n}\n\nconst DOM_MODES: readonly WoodDomMode[] = ['happy-dom', 'chromium'];\n\nfunction isMainSelection(value: unknown): value is WoodMainSelection {\n if (value === true) return true;\n if (!value || typeof value !== 'object') return false;\n const candidate = value as { operation?: unknown; module?: unknown };\n const hasOperation = typeof candidate.operation === 'string' && candidate.operation.length > 0;\n const hasModule = typeof candidate.module === 'string' && candidate.module.length > 0;\n return hasOperation !== hasModule;\n}\n\nfunction isPagesSelection(value: unknown): value is true | string[] {\n if (value === true) return true;\n return Array.isArray(value)\n && value.length > 0\n && value.every((entry) => typeof entry === 'string' && entry.length > 0);\n}\n\nexport function resolveSelection(selection: WoodTestSelection | null): ResolvedWoodSelection {\n if (!selection || typeof selection !== 'object') {\n throw new TestWoodError('select() requires { main }, { pages }, or both (plus optional dom)');\n }\n const { main, pages, dom } = selection;\n if (main !== undefined && !isMainSelection(main)) {\n throw new TestWoodError('select({ main }) must be true, { operation: string } or { module: string }');\n }\n if (pages !== undefined && !isPagesSelection(pages)) {\n throw new TestWoodError('select({ pages }) must be true or a non-empty list of page identities');\n }\n if (dom !== undefined && !DOM_MODES.includes(dom)) {\n throw new TestWoodError(`select({ dom }) must be one of: ${DOM_MODES.join(', ')}`);\n }\n if (dom !== undefined && pages === undefined) {\n throw new TestWoodError('select({ dom }) requires { pages }: a component needs a page to mount');\n }\n if (main === undefined && pages === undefined) {\n throw new TestWoodError('select() built nothing: add { main } and/or { pages }');\n }\n return { main: main ?? true, pages: pages ?? null, dom: dom ?? null };\n}\n\nfunction operationIdentities(operations: Map<string, OperationDef>): string {\n if (!operations.size) return 'the config defines no operations';\n return `available operations:\\n ${[...operations.keys()].join('\\n ')}`;\n}\n\n/** Narrow the production operations to the selected main aperture. */\nexport function selectOperations(\n all: Map<string, OperationDef>,\n main: WoodMainSelection,\n): Map<string, OperationDef> {\n if (main === true) return new Map(all);\n if ('module' in main) {\n const matched = new Map([...all].filter(([, operation]) => operation.module === main.module));\n if (matched.size) return matched;\n const modules = [...new Set([...all.values()].map((operation) => operation.module).filter(Boolean))];\n throw new TestWoodError(\n `unknown module \"${main.module}\"; ` +\n (modules.length ? `available modules: ${modules.join(', ')}` : 'the config defines no modules'),\n );\n }\n const match = all.get(main.operation);\n if (!match) {\n throw new TestWoodError(`no operation matches \"${main.operation}\"; ${operationIdentities(all)}`);\n }\n return new Map([[main.operation, match]]);\n}\n\n/** The renderer aperture: every production page, or exactly the named ones. */\nexport function selectCatalog(views: ViewDef[], pages: true | string[]): PageCatalog {\n const catalog = new PageCatalog(views);\n return pages === true ? catalog : catalog.select({ pages });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYA,0BAA4B;AAC5B,uBAA8B;AAiB9B,MAAM,YAAoC,CAAC,aAAa,UAAU;AAElE,SAAS,gBAAgB,OAA4C;AACnE,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,YAAY;AAClB,QAAM,eAAe,OAAO,UAAU,cAAc,YAAY,UAAU,UAAU,SAAS;AAC7F,QAAM,YAAY,OAAO,UAAU,WAAW,YAAY,UAAU,OAAO,SAAS;AACpF,SAAO,iBAAiB;AAC1B;AAEA,SAAS,iBAAiB,OAA0C;AAClE,MAAI,UAAU,KAAM,QAAO;AAC3B,SAAO,MAAM,QAAQ,KAAK,KACrB,MAAM,SAAS,KACf,MAAM,MAAM,CAAC,UAAU,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC;AAC3E;AAEO,SAAS,iBAAiB,WAA4D;AAC3F,MAAI,CAAC,aAAa,OAAO,cAAc,UAAU;AAC/C,UAAM,IAAI,+BAAc,oEAAoE;AAAA,EAC9F;AACA,QAAM,EAAE,MAAM,OAAO,IAAI,IAAI;AAC7B,MAAI,SAAS,UAAa,CAAC,gBAAgB,IAAI,GAAG;AAChD,UAAM,IAAI,+BAAc,4EAA4E;AAAA,EACtG;AACA,MAAI,UAAU,UAAa,CAAC,iBAAiB,KAAK,GAAG;AACnD,UAAM,IAAI,+BAAc,uEAAuE;AAAA,EACjG;AACA,MAAI,QAAQ,UAAa,CAAC,UAAU,SAAS,GAAG,GAAG;AACjD,UAAM,IAAI,+BAAc,mCAAmC,UAAU,KAAK,IAAI,CAAC,EAAE;AAAA,EACnF;AACA,MAAI,QAAQ,UAAa,UAAU,QAAW;AAC5C,UAAM,IAAI,+BAAc,uEAAuE;AAAA,EACjG;AACA,MAAI,SAAS,UAAa,UAAU,QAAW;AAC7C,UAAM,IAAI,+BAAc,uDAAuD;AAAA,EACjF;AACA,SAAO,EAAE,MAAM,QAAQ,MAAM,OAAO,SAAS,MAAM,KAAK,OAAO,KAAK;AACtE;AAEA,SAAS,oBAAoB,YAA+C;AAC1E,MAAI,CAAC,WAAW,KAAM,QAAO;AAC7B,SAAO;AAAA,IAA4B,CAAC,GAAG,WAAW,KAAK,CAAC,EAAE,KAAK,MAAM,CAAC;AACxE;AAGO,SAAS,iBACd,KACA,MAC2B;AAC3B,MAAI,SAAS,KAAM,QAAO,IAAI,IAAI,GAAG;AACrC,MAAI,YAAY,MAAM;AACpB,UAAM,UAAU,IAAI,IAAI,CAAC,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS,MAAM,UAAU,WAAW,KAAK,MAAM,CAAC;AAC5F,QAAI,QAAQ,KAAM,QAAO;AACzB,UAAM,UAAU,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,UAAU,MAAM,EAAE,OAAO,OAAO,CAAC,CAAC;AACnG,UAAM,IAAI;AAAA,MACR,mBAAmB,KAAK,MAAM,SAC7B,QAAQ,SAAS,sBAAsB,QAAQ,KAAK,IAAI,CAAC,KAAK;AAAA,IACjE;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,IAAI,KAAK,SAAS;AACpC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,+BAAc,yBAAyB,KAAK,SAAS,MAAM,oBAAoB,GAAG,CAAC,EAAE;AAAA,EACjG;AACA,SAAO,oBAAI,IAAI,CAAC,CAAC,KAAK,WAAW,KAAK,CAAC,CAAC;AAC1C;AAGO,SAAS,cAAc,OAAkB,OAAqC;AACnF,QAAM,UAAU,IAAI,gCAAY,KAAK;AACrC,SAAO,UAAU,OAAO,UAAU,QAAQ,OAAO,EAAE,MAAM,CAAC;AAC5D;","names":[]}
@@ -0,0 +1,39 @@
1
+ import { OperationDef } from '../types/operations.cjs';
2
+ import { ViewDef } from '../types/views.cjs';
3
+ import { PageCatalog } from '../frontend/page_catalog.cjs';
4
+
5
+ /**
6
+ * `testWood(configPath).select({...})` — one declarative object says which
7
+ * tiers exist and how they are observed:
8
+ *
9
+ * main true | { operation } | { module } the router + real controllers
10
+ * pages true | [identity, ...] the renderer page catalog
11
+ * dom 'happy-dom' | 'chromium' the page's real component
12
+ *
13
+ * A key that is absent is not built. `pages` implies `main: true`; `dom`
14
+ * requires `pages`. Nothing opens at build — tests drive `open()`.
15
+ */
16
+
17
+ type WoodMainSelection = true | {
18
+ operation: string;
19
+ } | {
20
+ module: string;
21
+ };
22
+ type WoodDomMode = 'happy-dom' | 'chromium';
23
+ interface WoodTestSelection {
24
+ main?: WoodMainSelection;
25
+ pages?: true | string[];
26
+ dom?: WoodDomMode;
27
+ }
28
+ interface ResolvedWoodSelection {
29
+ readonly main: WoodMainSelection;
30
+ readonly pages: true | string[] | null;
31
+ readonly dom: WoodDomMode | null;
32
+ }
33
+ declare function resolveSelection(selection: WoodTestSelection | null): ResolvedWoodSelection;
34
+ /** Narrow the production operations to the selected main aperture. */
35
+ declare function selectOperations(all: Map<string, OperationDef>, main: WoodMainSelection): Map<string, OperationDef>;
36
+ /** The renderer aperture: every production page, or exactly the named ones. */
37
+ declare function selectCatalog(views: ViewDef[], pages: true | string[]): PageCatalog;
38
+
39
+ export { type ResolvedWoodSelection, type WoodDomMode, type WoodMainSelection, type WoodTestSelection, resolveSelection, selectCatalog, selectOperations };
@@ -0,0 +1,39 @@
1
+ import { OperationDef } from '../types/operations.js';
2
+ import { ViewDef } from '../types/views.js';
3
+ import { PageCatalog } from '../frontend/page_catalog.js';
4
+
5
+ /**
6
+ * `testWood(configPath).select({...})` — one declarative object says which
7
+ * tiers exist and how they are observed:
8
+ *
9
+ * main true | { operation } | { module } the router + real controllers
10
+ * pages true | [identity, ...] the renderer page catalog
11
+ * dom 'happy-dom' | 'chromium' the page's real component
12
+ *
13
+ * A key that is absent is not built. `pages` implies `main: true`; `dom`
14
+ * requires `pages`. Nothing opens at build — tests drive `open()`.
15
+ */
16
+
17
+ type WoodMainSelection = true | {
18
+ operation: string;
19
+ } | {
20
+ module: string;
21
+ };
22
+ type WoodDomMode = 'happy-dom' | 'chromium';
23
+ interface WoodTestSelection {
24
+ main?: WoodMainSelection;
25
+ pages?: true | string[];
26
+ dom?: WoodDomMode;
27
+ }
28
+ interface ResolvedWoodSelection {
29
+ readonly main: WoodMainSelection;
30
+ readonly pages: true | string[] | null;
31
+ readonly dom: WoodDomMode | null;
32
+ }
33
+ declare function resolveSelection(selection: WoodTestSelection | null): ResolvedWoodSelection;
34
+ /** Narrow the production operations to the selected main aperture. */
35
+ declare function selectOperations(all: Map<string, OperationDef>, main: WoodMainSelection): Map<string, OperationDef>;
36
+ /** The renderer aperture: every production page, or exactly the named ones. */
37
+ declare function selectCatalog(views: ViewDef[], pages: true | string[]): PageCatalog;
38
+
39
+ export { type ResolvedWoodSelection, type WoodDomMode, type WoodMainSelection, type WoodTestSelection, resolveSelection, selectCatalog, selectOperations };
@@ -0,0 +1,68 @@
1
+ import { PageCatalog } from "../frontend/page_catalog.js";
2
+ import { TestWoodError } from "./test_wood.js";
3
+ const DOM_MODES = ["happy-dom", "chromium"];
4
+ function isMainSelection(value) {
5
+ if (value === true) return true;
6
+ if (!value || typeof value !== "object") return false;
7
+ const candidate = value;
8
+ const hasOperation = typeof candidate.operation === "string" && candidate.operation.length > 0;
9
+ const hasModule = typeof candidate.module === "string" && candidate.module.length > 0;
10
+ return hasOperation !== hasModule;
11
+ }
12
+ function isPagesSelection(value) {
13
+ if (value === true) return true;
14
+ return Array.isArray(value) && value.length > 0 && value.every((entry) => typeof entry === "string" && entry.length > 0);
15
+ }
16
+ function resolveSelection(selection) {
17
+ if (!selection || typeof selection !== "object") {
18
+ throw new TestWoodError("select() requires { main }, { pages }, or both (plus optional dom)");
19
+ }
20
+ const { main, pages, dom } = selection;
21
+ if (main !== void 0 && !isMainSelection(main)) {
22
+ throw new TestWoodError("select({ main }) must be true, { operation: string } or { module: string }");
23
+ }
24
+ if (pages !== void 0 && !isPagesSelection(pages)) {
25
+ throw new TestWoodError("select({ pages }) must be true or a non-empty list of page identities");
26
+ }
27
+ if (dom !== void 0 && !DOM_MODES.includes(dom)) {
28
+ throw new TestWoodError(`select({ dom }) must be one of: ${DOM_MODES.join(", ")}`);
29
+ }
30
+ if (dom !== void 0 && pages === void 0) {
31
+ throw new TestWoodError("select({ dom }) requires { pages }: a component needs a page to mount");
32
+ }
33
+ if (main === void 0 && pages === void 0) {
34
+ throw new TestWoodError("select() built nothing: add { main } and/or { pages }");
35
+ }
36
+ return { main: main ?? true, pages: pages ?? null, dom: dom ?? null };
37
+ }
38
+ function operationIdentities(operations) {
39
+ if (!operations.size) return "the config defines no operations";
40
+ return `available operations:
41
+ ${[...operations.keys()].join("\n ")}`;
42
+ }
43
+ function selectOperations(all, main) {
44
+ if (main === true) return new Map(all);
45
+ if ("module" in main) {
46
+ const matched = new Map([...all].filter(([, operation]) => operation.module === main.module));
47
+ if (matched.size) return matched;
48
+ const modules = [...new Set([...all.values()].map((operation) => operation.module).filter(Boolean))];
49
+ throw new TestWoodError(
50
+ `unknown module "${main.module}"; ` + (modules.length ? `available modules: ${modules.join(", ")}` : "the config defines no modules")
51
+ );
52
+ }
53
+ const match = all.get(main.operation);
54
+ if (!match) {
55
+ throw new TestWoodError(`no operation matches "${main.operation}"; ${operationIdentities(all)}`);
56
+ }
57
+ return /* @__PURE__ */ new Map([[main.operation, match]]);
58
+ }
59
+ function selectCatalog(views, pages) {
60
+ const catalog = new PageCatalog(views);
61
+ return pages === true ? catalog : catalog.select({ pages });
62
+ }
63
+ export {
64
+ resolveSelection,
65
+ selectCatalog,
66
+ selectOperations
67
+ };
68
+ //# sourceMappingURL=wood_test_selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/testing/wood_test_selection.ts"],"sourcesContent":["/**\n * `testWood(configPath).select({...})` — one declarative object says which\n * tiers exist and how they are observed:\n *\n * main true | { operation } | { module } the router + real controllers\n * pages true | [identity, ...] the renderer page catalog\n * dom 'happy-dom' | 'chromium' the page's real component\n *\n * A key that is absent is not built. `pages` implies `main: true`; `dom`\n * requires `pages`. Nothing opens at build — tests drive `open()`.\n */\nimport type { OperationDef, ViewDef } from '../types/index.js';\nimport { PageCatalog } from '../frontend/page_catalog.js';\nimport { TestWoodError } from './test_wood.js';\n\nexport type WoodMainSelection = true | { operation: string } | { module: string };\nexport type WoodDomMode = 'happy-dom' | 'chromium';\n\nexport interface WoodTestSelection {\n main?: WoodMainSelection;\n pages?: true | string[];\n dom?: WoodDomMode;\n}\n\nexport interface ResolvedWoodSelection {\n readonly main: WoodMainSelection;\n readonly pages: true | string[] | null;\n readonly dom: WoodDomMode | null;\n}\n\nconst DOM_MODES: readonly WoodDomMode[] = ['happy-dom', 'chromium'];\n\nfunction isMainSelection(value: unknown): value is WoodMainSelection {\n if (value === true) return true;\n if (!value || typeof value !== 'object') return false;\n const candidate = value as { operation?: unknown; module?: unknown };\n const hasOperation = typeof candidate.operation === 'string' && candidate.operation.length > 0;\n const hasModule = typeof candidate.module === 'string' && candidate.module.length > 0;\n return hasOperation !== hasModule;\n}\n\nfunction isPagesSelection(value: unknown): value is true | string[] {\n if (value === true) return true;\n return Array.isArray(value)\n && value.length > 0\n && value.every((entry) => typeof entry === 'string' && entry.length > 0);\n}\n\nexport function resolveSelection(selection: WoodTestSelection | null): ResolvedWoodSelection {\n if (!selection || typeof selection !== 'object') {\n throw new TestWoodError('select() requires { main }, { pages }, or both (plus optional dom)');\n }\n const { main, pages, dom } = selection;\n if (main !== undefined && !isMainSelection(main)) {\n throw new TestWoodError('select({ main }) must be true, { operation: string } or { module: string }');\n }\n if (pages !== undefined && !isPagesSelection(pages)) {\n throw new TestWoodError('select({ pages }) must be true or a non-empty list of page identities');\n }\n if (dom !== undefined && !DOM_MODES.includes(dom)) {\n throw new TestWoodError(`select({ dom }) must be one of: ${DOM_MODES.join(', ')}`);\n }\n if (dom !== undefined && pages === undefined) {\n throw new TestWoodError('select({ dom }) requires { pages }: a component needs a page to mount');\n }\n if (main === undefined && pages === undefined) {\n throw new TestWoodError('select() built nothing: add { main } and/or { pages }');\n }\n return { main: main ?? true, pages: pages ?? null, dom: dom ?? null };\n}\n\nfunction operationIdentities(operations: Map<string, OperationDef>): string {\n if (!operations.size) return 'the config defines no operations';\n return `available operations:\\n ${[...operations.keys()].join('\\n ')}`;\n}\n\n/** Narrow the production operations to the selected main aperture. */\nexport function selectOperations(\n all: Map<string, OperationDef>,\n main: WoodMainSelection,\n): Map<string, OperationDef> {\n if (main === true) return new Map(all);\n if ('module' in main) {\n const matched = new Map([...all].filter(([, operation]) => operation.module === main.module));\n if (matched.size) return matched;\n const modules = [...new Set([...all.values()].map((operation) => operation.module).filter(Boolean))];\n throw new TestWoodError(\n `unknown module \"${main.module}\"; ` +\n (modules.length ? `available modules: ${modules.join(', ')}` : 'the config defines no modules'),\n );\n }\n const match = all.get(main.operation);\n if (!match) {\n throw new TestWoodError(`no operation matches \"${main.operation}\"; ${operationIdentities(all)}`);\n }\n return new Map([[main.operation, match]]);\n}\n\n/** The renderer aperture: every production page, or exactly the named ones. */\nexport function selectCatalog(views: ViewDef[], pages: true | string[]): PageCatalog {\n const catalog = new PageCatalog(views);\n return pages === true ? catalog : catalog.select({ pages });\n}\n"],"mappings":"AAYA,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAiB9B,MAAM,YAAoC,CAAC,aAAa,UAAU;AAElE,SAAS,gBAAgB,OAA4C;AACnE,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,YAAY;AAClB,QAAM,eAAe,OAAO,UAAU,cAAc,YAAY,UAAU,UAAU,SAAS;AAC7F,QAAM,YAAY,OAAO,UAAU,WAAW,YAAY,UAAU,OAAO,SAAS;AACpF,SAAO,iBAAiB;AAC1B;AAEA,SAAS,iBAAiB,OAA0C;AAClE,MAAI,UAAU,KAAM,QAAO;AAC3B,SAAO,MAAM,QAAQ,KAAK,KACrB,MAAM,SAAS,KACf,MAAM,MAAM,CAAC,UAAU,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC;AAC3E;AAEO,SAAS,iBAAiB,WAA4D;AAC3F,MAAI,CAAC,aAAa,OAAO,cAAc,UAAU;AAC/C,UAAM,IAAI,cAAc,oEAAoE;AAAA,EAC9F;AACA,QAAM,EAAE,MAAM,OAAO,IAAI,IAAI;AAC7B,MAAI,SAAS,UAAa,CAAC,gBAAgB,IAAI,GAAG;AAChD,UAAM,IAAI,cAAc,4EAA4E;AAAA,EACtG;AACA,MAAI,UAAU,UAAa,CAAC,iBAAiB,KAAK,GAAG;AACnD,UAAM,IAAI,cAAc,uEAAuE;AAAA,EACjG;AACA,MAAI,QAAQ,UAAa,CAAC,UAAU,SAAS,GAAG,GAAG;AACjD,UAAM,IAAI,cAAc,mCAAmC,UAAU,KAAK,IAAI,CAAC,EAAE;AAAA,EACnF;AACA,MAAI,QAAQ,UAAa,UAAU,QAAW;AAC5C,UAAM,IAAI,cAAc,uEAAuE;AAAA,EACjG;AACA,MAAI,SAAS,UAAa,UAAU,QAAW;AAC7C,UAAM,IAAI,cAAc,uDAAuD;AAAA,EACjF;AACA,SAAO,EAAE,MAAM,QAAQ,MAAM,OAAO,SAAS,MAAM,KAAK,OAAO,KAAK;AACtE;AAEA,SAAS,oBAAoB,YAA+C;AAC1E,MAAI,CAAC,WAAW,KAAM,QAAO;AAC7B,SAAO;AAAA,IAA4B,CAAC,GAAG,WAAW,KAAK,CAAC,EAAE,KAAK,MAAM,CAAC;AACxE;AAGO,SAAS,iBACd,KACA,MAC2B;AAC3B,MAAI,SAAS,KAAM,QAAO,IAAI,IAAI,GAAG;AACrC,MAAI,YAAY,MAAM;AACpB,UAAM,UAAU,IAAI,IAAI,CAAC,GAAG,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS,MAAM,UAAU,WAAW,KAAK,MAAM,CAAC;AAC5F,QAAI,QAAQ,KAAM,QAAO;AACzB,UAAM,UAAU,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,EAAE,IAAI,CAAC,cAAc,UAAU,MAAM,EAAE,OAAO,OAAO,CAAC,CAAC;AACnG,UAAM,IAAI;AAAA,MACR,mBAAmB,KAAK,MAAM,SAC7B,QAAQ,SAAS,sBAAsB,QAAQ,KAAK,IAAI,CAAC,KAAK;AAAA,IACjE;AAAA,EACF;AACA,QAAM,QAAQ,IAAI,IAAI,KAAK,SAAS;AACpC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,cAAc,yBAAyB,KAAK,SAAS,MAAM,oBAAoB,GAAG,CAAC,EAAE;AAAA,EACjG;AACA,SAAO,oBAAI,IAAI,CAAC,CAAC,KAAK,WAAW,KAAK,CAAC,CAAC;AAC1C;AAGO,SAAS,cAAc,OAAkB,OAAqC;AACnF,QAAM,UAAU,IAAI,YAAY,KAAK;AACrC,SAAO,UAAU,OAAO,UAAU,QAAQ,OAAO,EAAE,MAAM,CAAC;AAC5D;","names":[]}
@@ -1,6 +1,5 @@
1
1
  export { TraceAssertions, TraceCountSummary, TraceFilter, TraceQuery, TraceRecorderEnableOptions, createTraceAssertions, createTraceQuery, matchesTrace, readPath } from '@noego/trace/testing';
2
2
  export { TraceRecorder } from './trace_recorder.cjs';
3
- import '../trace_hub-Cob54qRx.cjs';
3
+ import '../trace_hub-Cpo_nVze.cjs';
4
4
  import 'rxjs';
5
5
  import '../tracing/trace_provider.cjs';
6
- import '@noego/ioc';
@@ -1,6 +1,5 @@
1
1
  export { TraceAssertions, TraceCountSummary, TraceFilter, TraceQuery, TraceRecorderEnableOptions, createTraceAssertions, createTraceQuery, matchesTrace, readPath } from '@noego/trace/testing';
2
2
  export { TraceRecorder } from './trace_recorder.js';
3
- import '../trace_hub-Cob54qRx.js';
3
+ import '../trace_hub-Cpo_nVze.js';
4
4
  import 'rxjs';
5
5
  import '../tracing/trace_provider.js';
6
- import '@noego/ioc';
@@ -40,7 +40,7 @@ let TraceRecorder = class extends import_testing.TraceRecorder {
40
40
  }
41
41
  };
42
42
  TraceRecorder = __decorateClass([
43
- (0, import_ioc.Component)({ scope: import_ioc.LoadAs.Singleton }),
43
+ (0, import_ioc.Component)({ scope: import_ioc.LoadAs.Scoped }),
44
44
  __decorateParam(0, (0, import_ioc.Inject)(import_tracing.TraceProvider))
45
45
  ], TraceRecorder);
46
46
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/trace-testing/trace_recorder.ts"],"sourcesContent":["import { Component, Inject, LoadAs } from '@noego/ioc';\nimport {\n TraceRecorder as BaseTraceRecorder,\n type TraceObservableSource,\n type TraceRecorderEnableOptions,\n type TraceRecorderSource,\n type TraceWaitOptions,\n} from '@noego/trace/testing';\nimport {\n TraceProvider,\n type FrameworkTracer,\n type TraceEvent,\n} from '../tracing/index.js';\nimport { getTraceEvents$ } from '../tracing/trace_hub.js';\n\n@Component({ scope: LoadAs.Singleton })\nexport class TraceRecorder extends BaseTraceRecorder<TraceEvent> {\n constructor(\n @Inject(TraceProvider) traceProvider?: FrameworkTracer,\n ) {\n super(traceProvider ?? getTraceEvents$());\n }\n}\n\nexport type {\n TraceObservableSource,\n TraceRecorderEnableOptions,\n TraceRecorderSource,\n TraceWaitOptions,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA0C;AAC1C,qBAMO;AACP,qBAIO;AACP,uBAAgC;AAGzB,IAAM,gBAAN,cAA4B,eAAAA,cAA8B;AAAA,EAC/D,YACyB,eACvB;AACA,UAAM,qBAAiB,kCAAgB,CAAC;AAAA,EAC1C;AACF;AANa,gBAAN;AAAA,MADN,sBAAU,EAAE,OAAO,kBAAO,UAAU,CAAC;AAAA,EAGjC,0CAAO,4BAAa;AAAA,GAFZ;","names":["BaseTraceRecorder"]}
1
+ {"version":3,"sources":["../../src/trace-testing/trace_recorder.ts"],"sourcesContent":["import { Component, Inject, LoadAs } from '@noego/ioc';\nimport {\n TraceRecorder as BaseTraceRecorder,\n type TraceObservableSource,\n type TraceRecorderEnableOptions,\n type TraceRecorderSource,\n type TraceWaitOptions,\n} from '@noego/trace/testing';\nimport {\n TraceProvider,\n type FrameworkTracer,\n type TraceEvent,\n} from '../tracing/index.js';\nimport { getTraceEvents$ } from '../tracing/trace_hub.js';\n\n// Scoped, not Singleton: TraceProvider injects SCOPED_CONTAINER and is\n// scope-bound, so a recorder capturing it must share that lifetime (a\n// Singleton capturing it silently promoted the provider before ioc 0.5's\n// captive-lifetime validation made the invariant explicit).\n@Component({ scope: LoadAs.Scoped })\nexport class TraceRecorder extends BaseTraceRecorder<TraceEvent> {\n constructor(\n @Inject(TraceProvider) traceProvider?: FrameworkTracer,\n ) {\n super(traceProvider ?? getTraceEvents$());\n }\n}\n\nexport type {\n TraceObservableSource,\n TraceRecorderEnableOptions,\n TraceRecorderSource,\n TraceWaitOptions,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAA0C;AAC1C,qBAMO;AACP,qBAIO;AACP,uBAAgC;AAOzB,IAAM,gBAAN,cAA4B,eAAAA,cAA8B;AAAA,EAC/D,YACyB,eACvB;AACA,UAAM,qBAAiB,kCAAgB,CAAC;AAAA,EAC1C;AACF;AANa,gBAAN;AAAA,MADN,sBAAU,EAAE,OAAO,kBAAO,OAAO,CAAC;AAAA,EAG9B,0CAAO,4BAAa;AAAA,GAFZ;","names":["BaseTraceRecorder"]}
@@ -1,9 +1,8 @@
1
1
  import { TraceRecorder as TraceRecorder$1 } from '@noego/trace/testing';
2
2
  export { TraceObservableSource, TraceRecorderEnableOptions, TraceRecorderSource, TraceWaitOptions } from '@noego/trace/testing';
3
- import { a as TraceEvent } from '../trace_hub-Cob54qRx.cjs';
3
+ import { a as TraceEvent } from '../trace_hub-Cpo_nVze.cjs';
4
4
  import { FrameworkTracer } from '../tracing/trace_provider.cjs';
5
5
  import 'rxjs';
6
- import '@noego/ioc';
7
6
 
8
7
  declare class TraceRecorder extends TraceRecorder$1<TraceEvent> {
9
8
  constructor(traceProvider?: FrameworkTracer);
@@ -1,9 +1,8 @@
1
1
  import { TraceRecorder as TraceRecorder$1 } from '@noego/trace/testing';
2
2
  export { TraceObservableSource, TraceRecorderEnableOptions, TraceRecorderSource, TraceWaitOptions } from '@noego/trace/testing';
3
- import { a as TraceEvent } from '../trace_hub-Cob54qRx.js';
3
+ import { a as TraceEvent } from '../trace_hub-Cpo_nVze.js';
4
4
  import { FrameworkTracer } from '../tracing/trace_provider.js';
5
5
  import 'rxjs';
6
- import '@noego/ioc';
7
6
 
8
7
  declare class TraceRecorder extends TraceRecorder$1<TraceEvent> {
9
8
  constructor(traceProvider?: FrameworkTracer);
@@ -23,7 +23,7 @@ let TraceRecorder = class extends BaseTraceRecorder {
23
23
  }
24
24
  };
25
25
  TraceRecorder = __decorateClass([
26
- Component({ scope: LoadAs.Singleton }),
26
+ Component({ scope: LoadAs.Scoped }),
27
27
  __decorateParam(0, Inject(TraceProvider))
28
28
  ], TraceRecorder);
29
29
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/trace-testing/trace_recorder.ts"],"sourcesContent":["import { Component, Inject, LoadAs } from '@noego/ioc';\nimport {\n TraceRecorder as BaseTraceRecorder,\n type TraceObservableSource,\n type TraceRecorderEnableOptions,\n type TraceRecorderSource,\n type TraceWaitOptions,\n} from '@noego/trace/testing';\nimport {\n TraceProvider,\n type FrameworkTracer,\n type TraceEvent,\n} from '../tracing/index.js';\nimport { getTraceEvents$ } from '../tracing/trace_hub.js';\n\n@Component({ scope: LoadAs.Singleton })\nexport class TraceRecorder extends BaseTraceRecorder<TraceEvent> {\n constructor(\n @Inject(TraceProvider) traceProvider?: FrameworkTracer,\n ) {\n super(traceProvider ?? getTraceEvents$());\n }\n}\n\nexport type {\n TraceObservableSource,\n TraceRecorderEnableOptions,\n TraceRecorderSource,\n TraceWaitOptions,\n};\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,WAAW,QAAQ,cAAc;AAC1C;AAAA,EACE,iBAAiB;AAAA,OAKZ;AACP;AAAA,EACE;AAAA,OAGK;AACP,SAAS,uBAAuB;AAGzB,IAAM,gBAAN,cAA4B,kBAA8B;AAAA,EAC/D,YACyB,eACvB;AACA,UAAM,iBAAiB,gBAAgB,CAAC;AAAA,EAC1C;AACF;AANa,gBAAN;AAAA,EADN,UAAU,EAAE,OAAO,OAAO,UAAU,CAAC;AAAA,EAGjC,0BAAO,aAAa;AAAA,GAFZ;","names":[]}
1
+ {"version":3,"sources":["../../src/trace-testing/trace_recorder.ts"],"sourcesContent":["import { Component, Inject, LoadAs } from '@noego/ioc';\nimport {\n TraceRecorder as BaseTraceRecorder,\n type TraceObservableSource,\n type TraceRecorderEnableOptions,\n type TraceRecorderSource,\n type TraceWaitOptions,\n} from '@noego/trace/testing';\nimport {\n TraceProvider,\n type FrameworkTracer,\n type TraceEvent,\n} from '../tracing/index.js';\nimport { getTraceEvents$ } from '../tracing/trace_hub.js';\n\n// Scoped, not Singleton: TraceProvider injects SCOPED_CONTAINER and is\n// scope-bound, so a recorder capturing it must share that lifetime (a\n// Singleton capturing it silently promoted the provider before ioc 0.5's\n// captive-lifetime validation made the invariant explicit).\n@Component({ scope: LoadAs.Scoped })\nexport class TraceRecorder extends BaseTraceRecorder<TraceEvent> {\n constructor(\n @Inject(TraceProvider) traceProvider?: FrameworkTracer,\n ) {\n super(traceProvider ?? getTraceEvents$());\n }\n}\n\nexport type {\n TraceObservableSource,\n TraceRecorderEnableOptions,\n TraceRecorderSource,\n TraceWaitOptions,\n};\n"],"mappings":";;;;;;;;;;;AAAA,SAAS,WAAW,QAAQ,cAAc;AAC1C;AAAA,EACE,iBAAiB;AAAA,OAKZ;AACP;AAAA,EACE;AAAA,OAGK;AACP,SAAS,uBAAuB;AAOzB,IAAM,gBAAN,cAA4B,kBAA8B;AAAA,EAC/D,YACyB,eACvB;AACA,UAAM,iBAAiB,gBAAgB,CAAC;AAAA,EAC1C;AACF;AANa,gBAAN;AAAA,EADN,UAAU,EAAE,OAAO,OAAO,OAAO,CAAC;AAAA,EAG9B,0BAAO,aAAa;AAAA,GAFZ;","names":[]}
@@ -2,5 +2,5 @@ export { RendererTraceBatchTransport } from '../tracing/renderer_trace_batch_tra
2
2
  export { WoodTraceBatchContract } from '../tracing/wood_trace_batch_contract.cjs';
3
3
  export { WoodRendererTraceEvent, WoodRendererTraceInput, WoodTraceBatch, WoodTraceBatchAcknowledgement, WoodTraceBatchAdmissionResult, WoodTraceBatchPort, WoodTraceBatchTransportOptions, WoodTraceBatchTransportStatus } from '../tracing/types/wood_trace_batch.types.cjs';
4
4
  import '@noego/telemetry/core';
5
- import '../trace_hub-Cob54qRx.cjs';
5
+ import '../trace_hub-Cpo_nVze.cjs';
6
6
  import 'rxjs';
@@ -2,5 +2,5 @@ export { RendererTraceBatchTransport } from '../tracing/renderer_trace_batch_tra
2
2
  export { WoodTraceBatchContract } from '../tracing/wood_trace_batch_contract.js';
3
3
  export { WoodRendererTraceEvent, WoodRendererTraceInput, WoodTraceBatch, WoodTraceBatchAcknowledgement, WoodTraceBatchAdmissionResult, WoodTraceBatchPort, WoodTraceBatchTransportOptions, WoodTraceBatchTransportStatus } from '../tracing/types/wood_trace_batch.types.js';
4
4
  import '@noego/telemetry/core';
5
- import '../trace_hub-Cob54qRx.js';
5
+ import '../trace_hub-Cpo_nVze.js';
6
6
  import 'rxjs';