@noego/wood 0.0.1

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 (499) hide show
  1. package/README.md +107 -0
  2. package/bin/axe.js +202 -0
  3. package/bin/stick.js +96 -0
  4. package/bin/wood.js +572 -0
  5. package/dist/bridge/backend_bridge.cjs +186 -0
  6. package/dist/bridge/backend_bridge.cjs.map +1 -0
  7. package/dist/bridge/backend_bridge.d.cts +32 -0
  8. package/dist/bridge/backend_bridge.d.ts +32 -0
  9. package/dist/bridge/backend_bridge.js +152 -0
  10. package/dist/bridge/backend_bridge.js.map +1 -0
  11. package/dist/bridge/backend_entry.cjs +64 -0
  12. package/dist/bridge/backend_entry.cjs.map +1 -0
  13. package/dist/bridge/backend_entry.d.cts +14 -0
  14. package/dist/bridge/backend_entry.d.ts +14 -0
  15. package/dist/bridge/backend_entry.js +39 -0
  16. package/dist/bridge/backend_entry.js.map +1 -0
  17. package/dist/bridge/index.cjs +34 -0
  18. package/dist/bridge/index.cjs.map +1 -0
  19. package/dist/bridge/index.d.cts +2 -0
  20. package/dist/bridge/index.d.ts +2 -0
  21. package/dist/bridge/index.js +8 -0
  22. package/dist/bridge/index.js.map +1 -0
  23. package/dist/client/controller_contract.cjs +17 -0
  24. package/dist/client/controller_contract.cjs.map +1 -0
  25. package/dist/client/controller_contract.d.cts +15 -0
  26. package/dist/client/controller_contract.d.ts +15 -0
  27. package/dist/client/controller_contract.js +1 -0
  28. package/dist/client/controller_contract.js.map +1 -0
  29. package/dist/client/global_polyfill.cjs +6 -0
  30. package/dist/client/global_polyfill.cjs.map +1 -0
  31. package/dist/client/global_polyfill.d.cts +2 -0
  32. package/dist/client/global_polyfill.d.ts +2 -0
  33. package/dist/client/global_polyfill.js +5 -0
  34. package/dist/client/global_polyfill.js.map +1 -0
  35. package/dist/client/index.cjs +451 -0
  36. package/dist/client/index.cjs.map +1 -0
  37. package/dist/client/index.d.cts +75 -0
  38. package/dist/client/index.d.ts +75 -0
  39. package/dist/client/index.js +414 -0
  40. package/dist/client/index.js.map +1 -0
  41. package/dist/client/wood_controller.svelte.cjs +110 -0
  42. package/dist/client/wood_controller.svelte.cjs.map +1 -0
  43. package/dist/client/wood_controller.svelte.d.cts +30 -0
  44. package/dist/client/wood_controller.svelte.d.ts +30 -0
  45. package/dist/client/wood_controller.svelte.js +86 -0
  46. package/dist/client/wood_controller.svelte.js.map +1 -0
  47. package/dist/codegen/controller_registration_generator.cjs +138 -0
  48. package/dist/codegen/controller_registration_generator.cjs.map +1 -0
  49. package/dist/codegen/controller_registration_generator.d.cts +18 -0
  50. package/dist/codegen/controller_registration_generator.d.ts +18 -0
  51. package/dist/codegen/controller_registration_generator.js +104 -0
  52. package/dist/codegen/controller_registration_generator.js.map +1 -0
  53. package/dist/codegen/index.cjs +50 -0
  54. package/dist/codegen/index.cjs.map +1 -0
  55. package/dist/codegen/index.d.cts +10 -0
  56. package/dist/codegen/index.d.ts +10 -0
  57. package/dist/codegen/index.js +19 -0
  58. package/dist/codegen/index.js.map +1 -0
  59. package/dist/codegen/preload_generator.cjs +151 -0
  60. package/dist/codegen/preload_generator.cjs.map +1 -0
  61. package/dist/codegen/preload_generator.d.cts +8 -0
  62. package/dist/codegen/preload_generator.d.ts +8 -0
  63. package/dist/codegen/preload_generator.js +127 -0
  64. package/dist/codegen/preload_generator.js.map +1 -0
  65. package/dist/codegen/renderer_app_generator.cjs +397 -0
  66. package/dist/codegen/renderer_app_generator.cjs.map +1 -0
  67. package/dist/codegen/renderer_app_generator.d.cts +13 -0
  68. package/dist/codegen/renderer_app_generator.d.ts +13 -0
  69. package/dist/codegen/renderer_app_generator.js +363 -0
  70. package/dist/codegen/renderer_app_generator.js.map +1 -0
  71. package/dist/codegen/renderer_controller_registration_generator.cjs +122 -0
  72. package/dist/codegen/renderer_controller_registration_generator.cjs.map +1 -0
  73. package/dist/codegen/renderer_controller_registration_generator.d.cts +9 -0
  74. package/dist/codegen/renderer_controller_registration_generator.d.ts +9 -0
  75. package/dist/codegen/renderer_controller_registration_generator.js +88 -0
  76. package/dist/codegen/renderer_controller_registration_generator.js.map +1 -0
  77. package/dist/codegen/renderer_view_manifest_generator.cjs +126 -0
  78. package/dist/codegen/renderer_view_manifest_generator.cjs.map +1 -0
  79. package/dist/codegen/renderer_view_manifest_generator.d.cts +11 -0
  80. package/dist/codegen/renderer_view_manifest_generator.d.ts +11 -0
  81. package/dist/codegen/renderer_view_manifest_generator.js +92 -0
  82. package/dist/codegen/renderer_view_manifest_generator.js.map +1 -0
  83. package/dist/codegen/runtime_generator.cjs +156 -0
  84. package/dist/codegen/runtime_generator.cjs.map +1 -0
  85. package/dist/codegen/runtime_generator.d.cts +14 -0
  86. package/dist/codegen/runtime_generator.d.ts +14 -0
  87. package/dist/codegen/runtime_generator.js +122 -0
  88. package/dist/codegen/runtime_generator.js.map +1 -0
  89. package/dist/codegen/test_mock_generator.cjs +98 -0
  90. package/dist/codegen/test_mock_generator.cjs.map +1 -0
  91. package/dist/codegen/test_mock_generator.d.cts +5 -0
  92. package/dist/codegen/test_mock_generator.d.ts +5 -0
  93. package/dist/codegen/test_mock_generator.js +74 -0
  94. package/dist/codegen/test_mock_generator.js.map +1 -0
  95. package/dist/codegen/type_generator.cjs +203 -0
  96. package/dist/codegen/type_generator.cjs.map +1 -0
  97. package/dist/codegen/type_generator.d.cts +5 -0
  98. package/dist/codegen/type_generator.d.ts +5 -0
  99. package/dist/codegen/type_generator.js +179 -0
  100. package/dist/codegen/type_generator.js.map +1 -0
  101. package/dist/components/contextMenu.cjs +163 -0
  102. package/dist/components/contextMenu.cjs.map +1 -0
  103. package/dist/components/contextMenu.d.cts +43 -0
  104. package/dist/components/contextMenu.d.ts +43 -0
  105. package/dist/components/contextMenu.js +138 -0
  106. package/dist/components/contextMenu.js.map +1 -0
  107. package/dist/config/config_parser.cjs +176 -0
  108. package/dist/config/config_parser.cjs.map +1 -0
  109. package/dist/config/config_parser.d.cts +9 -0
  110. package/dist/config/config_parser.d.ts +9 -0
  111. package/dist/config/config_parser.js +142 -0
  112. package/dist/config/config_parser.js.map +1 -0
  113. package/dist/config/index.cjs +29 -0
  114. package/dist/config/index.cjs.map +1 -0
  115. package/dist/config/index.d.cts +2 -0
  116. package/dist/config/index.d.ts +2 -0
  117. package/dist/config/index.js +5 -0
  118. package/dist/config/index.js.map +1 -0
  119. package/dist/controller/__fixtures__/controllers/chat.cjs +32 -0
  120. package/dist/controller/__fixtures__/controllers/chat.cjs.map +1 -0
  121. package/dist/controller/__fixtures__/controllers/chat.d.cts +11 -0
  122. package/dist/controller/__fixtures__/controllers/chat.d.ts +11 -0
  123. package/dist/controller/__fixtures__/controllers/chat.js +12 -0
  124. package/dist/controller/__fixtures__/controllers/chat.js.map +1 -0
  125. package/dist/controller/__fixtures__/controllers/not_a_class.cjs +29 -0
  126. package/dist/controller/__fixtures__/controllers/not_a_class.cjs.map +1 -0
  127. package/dist/controller/__fixtures__/controllers/not_a_class.d.cts +3 -0
  128. package/dist/controller/__fixtures__/controllers/not_a_class.d.ts +3 -0
  129. package/dist/controller/__fixtures__/controllers/not_a_class.js +5 -0
  130. package/dist/controller/__fixtures__/controllers/not_a_class.js.map +1 -0
  131. package/dist/controller/__fixtures__/controllers/settings.controller.cjs +32 -0
  132. package/dist/controller/__fixtures__/controllers/settings.controller.cjs.map +1 -0
  133. package/dist/controller/__fixtures__/controllers/settings.controller.d.cts +12 -0
  134. package/dist/controller/__fixtures__/controllers/settings.controller.d.ts +12 -0
  135. package/dist/controller/__fixtures__/controllers/settings.controller.js +12 -0
  136. package/dist/controller/__fixtures__/controllers/settings.controller.js.map +1 -0
  137. package/dist/controller/__fixtures__/controllers/test.cjs +29 -0
  138. package/dist/controller/__fixtures__/controllers/test.cjs.map +1 -0
  139. package/dist/controller/__fixtures__/controllers/test.d.cts +7 -0
  140. package/dist/controller/__fixtures__/controllers/test.d.ts +7 -0
  141. package/dist/controller/__fixtures__/controllers/test.js +9 -0
  142. package/dist/controller/__fixtures__/controllers/test.js.map +1 -0
  143. package/dist/controller/controller_resolver.cjs +180 -0
  144. package/dist/controller/controller_resolver.cjs.map +1 -0
  145. package/dist/controller/controller_resolver.d.cts +51 -0
  146. package/dist/controller/controller_resolver.d.ts +51 -0
  147. package/dist/controller/controller_resolver.js +145 -0
  148. package/dist/controller/controller_resolver.js.map +1 -0
  149. package/dist/controller/index.cjs +31 -0
  150. package/dist/controller/index.cjs.map +1 -0
  151. package/dist/controller/index.d.cts +2 -0
  152. package/dist/controller/index.d.ts +2 -0
  153. package/dist/controller/index.js +6 -0
  154. package/dist/controller/index.js.map +1 -0
  155. package/dist/dev/backend_watcher.cjs +108 -0
  156. package/dist/dev/backend_watcher.cjs.map +1 -0
  157. package/dist/dev/backend_watcher.d.cts +22 -0
  158. package/dist/dev/backend_watcher.d.ts +22 -0
  159. package/dist/dev/backend_watcher.js +84 -0
  160. package/dist/dev/backend_watcher.js.map +1 -0
  161. package/dist/dev/dev_metadata.cjs +94 -0
  162. package/dist/dev/dev_metadata.cjs.map +1 -0
  163. package/dist/dev/dev_metadata.d.cts +20 -0
  164. package/dist/dev/dev_metadata.d.ts +20 -0
  165. package/dist/dev/dev_metadata.js +52 -0
  166. package/dist/dev/dev_metadata.js.map +1 -0
  167. package/dist/dev/esbuild_backend.cjs +124 -0
  168. package/dist/dev/esbuild_backend.cjs.map +1 -0
  169. package/dist/dev/esbuild_backend.d.cts +30 -0
  170. package/dist/dev/esbuild_backend.d.ts +30 -0
  171. package/dist/dev/esbuild_backend.js +90 -0
  172. package/dist/dev/esbuild_backend.js.map +1 -0
  173. package/dist/dev/index.cjs +57 -0
  174. package/dist/dev/index.cjs.map +1 -0
  175. package/dist/dev/index.d.cts +8 -0
  176. package/dist/dev/index.d.ts +8 -0
  177. package/dist/dev/index.js +31 -0
  178. package/dist/dev/index.js.map +1 -0
  179. package/dist/dev/wood_dev_server.cjs +220 -0
  180. package/dist/dev/wood_dev_server.cjs.map +1 -0
  181. package/dist/dev/wood_dev_server.d.cts +39 -0
  182. package/dist/dev/wood_dev_server.d.ts +39 -0
  183. package/dist/dev/wood_dev_server.js +186 -0
  184. package/dist/dev/wood_dev_server.js.map +1 -0
  185. package/dist/dev/yaml_watcher.cjs +142 -0
  186. package/dist/dev/yaml_watcher.cjs.map +1 -0
  187. package/dist/dev/yaml_watcher.d.cts +22 -0
  188. package/dist/dev/yaml_watcher.d.ts +22 -0
  189. package/dist/dev/yaml_watcher.js +108 -0
  190. package/dist/dev/yaml_watcher.js.map +1 -0
  191. package/dist/electron/index.cjs +176 -0
  192. package/dist/electron/index.cjs.map +1 -0
  193. package/dist/electron/index.d.cts +29 -0
  194. package/dist/electron/index.d.ts +29 -0
  195. package/dist/electron/index.js +140 -0
  196. package/dist/electron/index.js.map +1 -0
  197. package/dist/index.cjs +178 -0
  198. package/dist/index.cjs.map +1 -0
  199. package/dist/index.d.cts +41 -0
  200. package/dist/index.d.ts +41 -0
  201. package/dist/index.js +122 -0
  202. package/dist/index.js.map +1 -0
  203. package/dist/ipc/index.cjs +80 -0
  204. package/dist/ipc/index.cjs.map +1 -0
  205. package/dist/ipc/index.d.cts +12 -0
  206. package/dist/ipc/index.d.ts +12 -0
  207. package/dist/ipc/index.js +57 -0
  208. package/dist/ipc/index.js.map +1 -0
  209. package/dist/ipc/shared.cjs +50 -0
  210. package/dist/ipc/shared.cjs.map +1 -0
  211. package/dist/ipc/shared.d.cts +10 -0
  212. package/dist/ipc/shared.d.ts +10 -0
  213. package/dist/ipc/shared.js +23 -0
  214. package/dist/ipc/shared.js.map +1 -0
  215. package/dist/loader/__fixtures__/layouts/app.load.cjs +27 -0
  216. package/dist/loader/__fixtures__/layouts/app.load.cjs.map +1 -0
  217. package/dist/loader/__fixtures__/layouts/app.load.d.cts +5 -0
  218. package/dist/loader/__fixtures__/layouts/app.load.d.ts +5 -0
  219. package/dist/loader/__fixtures__/layouts/app.load.js +7 -0
  220. package/dist/loader/__fixtures__/layouts/app.load.js.map +1 -0
  221. package/dist/loader/__fixtures__/views/test/page.load.cjs +27 -0
  222. package/dist/loader/__fixtures__/views/test/page.load.cjs.map +1 -0
  223. package/dist/loader/__fixtures__/views/test/page.load.d.cts +6 -0
  224. package/dist/loader/__fixtures__/views/test/page.load.d.ts +6 -0
  225. package/dist/loader/__fixtures__/views/test/page.load.js +7 -0
  226. package/dist/loader/__fixtures__/views/test/page.load.js.map +1 -0
  227. package/dist/loader/index.cjs +29 -0
  228. package/dist/loader/index.cjs.map +1 -0
  229. package/dist/loader/index.d.cts +3 -0
  230. package/dist/loader/index.d.ts +3 -0
  231. package/dist/loader/index.js +5 -0
  232. package/dist/loader/index.js.map +1 -0
  233. package/dist/loader/loader_runner.cjs +109 -0
  234. package/dist/loader/loader_runner.cjs.map +1 -0
  235. package/dist/loader/loader_runner.d.cts +27 -0
  236. package/dist/loader/loader_runner.d.ts +27 -0
  237. package/dist/loader/loader_runner.js +75 -0
  238. package/dist/loader/loader_runner.js.map +1 -0
  239. package/dist/main/index.cjs +500 -0
  240. package/dist/main/index.cjs.map +1 -0
  241. package/dist/main/index.d.cts +98 -0
  242. package/dist/main/index.d.ts +98 -0
  243. package/dist/main/index.js +475 -0
  244. package/dist/main/index.js.map +1 -0
  245. package/dist/middleware/__fixtures__/middleware/auth.cjs +44 -0
  246. package/dist/middleware/__fixtures__/middleware/auth.cjs.map +1 -0
  247. package/dist/middleware/__fixtures__/middleware/auth.d.cts +6 -0
  248. package/dist/middleware/__fixtures__/middleware/auth.d.ts +6 -0
  249. package/dist/middleware/__fixtures__/middleware/auth.js +19 -0
  250. package/dist/middleware/__fixtures__/middleware/auth.js.map +1 -0
  251. package/dist/middleware/__fixtures__/middleware/sequence.cjs +47 -0
  252. package/dist/middleware/__fixtures__/middleware/sequence.cjs.map +1 -0
  253. package/dist/middleware/__fixtures__/middleware/sequence.d.cts +7 -0
  254. package/dist/middleware/__fixtures__/middleware/sequence.d.ts +7 -0
  255. package/dist/middleware/__fixtures__/middleware/sequence.js +21 -0
  256. package/dist/middleware/__fixtures__/middleware/sequence.js.map +1 -0
  257. package/dist/middleware/index.cjs +34 -0
  258. package/dist/middleware/index.cjs.map +1 -0
  259. package/dist/middleware/index.d.cts +3 -0
  260. package/dist/middleware/index.d.ts +3 -0
  261. package/dist/middleware/index.js +8 -0
  262. package/dist/middleware/index.js.map +1 -0
  263. package/dist/middleware/middleware_pipeline.cjs +55 -0
  264. package/dist/middleware/middleware_pipeline.cjs.map +1 -0
  265. package/dist/middleware/middleware_pipeline.d.cts +13 -0
  266. package/dist/middleware/middleware_pipeline.d.ts +13 -0
  267. package/dist/middleware/middleware_pipeline.js +30 -0
  268. package/dist/middleware/middleware_pipeline.js.map +1 -0
  269. package/dist/middleware/middleware_resolver.cjs +91 -0
  270. package/dist/middleware/middleware_resolver.cjs.map +1 -0
  271. package/dist/middleware/middleware_resolver.d.cts +19 -0
  272. package/dist/middleware/middleware_resolver.d.ts +19 -0
  273. package/dist/middleware/middleware_resolver.js +57 -0
  274. package/dist/middleware/middleware_resolver.js.map +1 -0
  275. package/dist/navigation/index.cjs +205 -0
  276. package/dist/navigation/index.cjs.map +1 -0
  277. package/dist/navigation/index.d.cts +34 -0
  278. package/dist/navigation/index.d.ts +34 -0
  279. package/dist/navigation/index.js +176 -0
  280. package/dist/navigation/index.js.map +1 -0
  281. package/dist/parser/index.cjs +36 -0
  282. package/dist/parser/index.cjs.map +1 -0
  283. package/dist/parser/index.d.cts +4 -0
  284. package/dist/parser/index.d.ts +4 -0
  285. package/dist/parser/index.js +9 -0
  286. package/dist/parser/index.js.map +1 -0
  287. package/dist/parser/operations_parser.cjs +94 -0
  288. package/dist/parser/operations_parser.cjs.map +1 -0
  289. package/dist/parser/operations_parser.d.cts +7 -0
  290. package/dist/parser/operations_parser.d.ts +7 -0
  291. package/dist/parser/operations_parser.js +59 -0
  292. package/dist/parser/operations_parser.js.map +1 -0
  293. package/dist/parser/views_parser.cjs +153 -0
  294. package/dist/parser/views_parser.cjs.map +1 -0
  295. package/dist/parser/views_parser.d.cts +11 -0
  296. package/dist/parser/views_parser.d.ts +11 -0
  297. package/dist/parser/views_parser.js +118 -0
  298. package/dist/parser/views_parser.js.map +1 -0
  299. package/dist/router/index.cjs +31 -0
  300. package/dist/router/index.cjs.map +1 -0
  301. package/dist/router/index.d.cts +2 -0
  302. package/dist/router/index.d.ts +2 -0
  303. package/dist/router/index.js +6 -0
  304. package/dist/router/index.js.map +1 -0
  305. package/dist/router/wood_router.cjs +246 -0
  306. package/dist/router/wood_router.cjs.map +1 -0
  307. package/dist/router/wood_router.d.cts +70 -0
  308. package/dist/router/wood_router.d.ts +70 -0
  309. package/dist/router/wood_router.js +221 -0
  310. package/dist/router/wood_router.js.map +1 -0
  311. package/dist/runtime/application_root.cjs +98 -0
  312. package/dist/runtime/application_root.cjs.map +1 -0
  313. package/dist/runtime/application_root.d.cts +5 -0
  314. package/dist/runtime/application_root.d.ts +5 -0
  315. package/dist/runtime/application_root.js +61 -0
  316. package/dist/runtime/application_root.js.map +1 -0
  317. package/dist/runtime/get_container.cjs +96 -0
  318. package/dist/runtime/get_container.cjs.map +1 -0
  319. package/dist/runtime/get_container.d.cts +16 -0
  320. package/dist/runtime/get_container.d.ts +16 -0
  321. package/dist/runtime/get_container.js +60 -0
  322. package/dist/runtime/get_container.js.map +1 -0
  323. package/dist/runtime/index.cjs +49 -0
  324. package/dist/runtime/index.cjs.map +1 -0
  325. package/dist/runtime/index.d.cts +8 -0
  326. package/dist/runtime/index.d.ts +8 -0
  327. package/dist/runtime/index.js +24 -0
  328. package/dist/runtime/index.js.map +1 -0
  329. package/dist/runtime/renderer_log_dispatcher.cjs +79 -0
  330. package/dist/runtime/renderer_log_dispatcher.cjs.map +1 -0
  331. package/dist/runtime/renderer_log_dispatcher.d.cts +27 -0
  332. package/dist/runtime/renderer_log_dispatcher.d.ts +27 -0
  333. package/dist/runtime/renderer_log_dispatcher.js +54 -0
  334. package/dist/runtime/renderer_log_dispatcher.js.map +1 -0
  335. package/dist/runtime/runtime.cjs +158 -0
  336. package/dist/runtime/runtime.cjs.map +1 -0
  337. package/dist/runtime/runtime.d.cts +35 -0
  338. package/dist/runtime/runtime.d.ts +35 -0
  339. package/dist/runtime/runtime.js +136 -0
  340. package/dist/runtime/runtime.js.map +1 -0
  341. package/dist/stick/allow_cli.cjs +39 -0
  342. package/dist/stick/allow_cli.cjs.map +1 -0
  343. package/dist/stick/allow_cli.d.cts +6 -0
  344. package/dist/stick/allow_cli.d.ts +6 -0
  345. package/dist/stick/allow_cli.js +15 -0
  346. package/dist/stick/allow_cli.js.map +1 -0
  347. package/dist/stick/index.cjs +276 -0
  348. package/dist/stick/index.cjs.map +1 -0
  349. package/dist/stick/index.d.cts +111 -0
  350. package/dist/stick/index.d.ts +111 -0
  351. package/dist/stick/index.js +237 -0
  352. package/dist/stick/index.js.map +1 -0
  353. package/dist/stick/static_renderer.cjs +144 -0
  354. package/dist/stick/static_renderer.cjs.map +1 -0
  355. package/dist/stick/static_renderer.d.cts +51 -0
  356. package/dist/stick/static_renderer.d.ts +51 -0
  357. package/dist/stick/static_renderer.js +119 -0
  358. package/dist/stick/static_renderer.js.map +1 -0
  359. package/dist/stick/template_resolver.cjs +156 -0
  360. package/dist/stick/template_resolver.cjs.map +1 -0
  361. package/dist/stick/template_resolver.d.cts +7 -0
  362. package/dist/stick/template_resolver.d.ts +7 -0
  363. package/dist/stick/template_resolver.js +122 -0
  364. package/dist/stick/template_resolver.js.map +1 -0
  365. package/dist/testing/create_controller_harness.cjs +175 -0
  366. package/dist/testing/create_controller_harness.cjs.map +1 -0
  367. package/dist/testing/create_controller_harness.d.cts +37 -0
  368. package/dist/testing/create_controller_harness.d.ts +37 -0
  369. package/dist/testing/create_controller_harness.js +162 -0
  370. package/dist/testing/create_controller_harness.js.map +1 -0
  371. package/dist/testing/create_router_bridge.cjs +103 -0
  372. package/dist/testing/create_router_bridge.cjs.map +1 -0
  373. package/dist/testing/create_router_bridge.d.cts +71 -0
  374. package/dist/testing/create_router_bridge.d.ts +71 -0
  375. package/dist/testing/create_router_bridge.js +78 -0
  376. package/dist/testing/create_router_bridge.js.map +1 -0
  377. package/dist/testing/create_test_container.cjs +72 -0
  378. package/dist/testing/create_test_container.cjs.map +1 -0
  379. package/dist/testing/create_test_container.d.cts +14 -0
  380. package/dist/testing/create_test_container.d.ts +14 -0
  381. package/dist/testing/create_test_container.js +48 -0
  382. package/dist/testing/create_test_container.js.map +1 -0
  383. package/dist/testing/create_test_router.cjs +57 -0
  384. package/dist/testing/create_test_router.cjs.map +1 -0
  385. package/dist/testing/create_test_router.d.cts +19 -0
  386. package/dist/testing/create_test_router.d.ts +19 -0
  387. package/dist/testing/create_test_router.js +33 -0
  388. package/dist/testing/create_test_router.js.map +1 -0
  389. package/dist/testing/index.cjs +48 -0
  390. package/dist/testing/index.cjs.map +1 -0
  391. package/dist/testing/index.d.cts +12 -0
  392. package/dist/testing/index.d.ts +12 -0
  393. package/dist/testing/index.js +22 -0
  394. package/dist/testing/index.js.map +1 -0
  395. package/dist/testing/mock_electron.cjs +100 -0
  396. package/dist/testing/mock_electron.cjs.map +1 -0
  397. package/dist/testing/mock_electron.d.cts +12 -0
  398. package/dist/testing/mock_electron.d.ts +12 -0
  399. package/dist/testing/mock_electron.js +75 -0
  400. package/dist/testing/mock_electron.js.map +1 -0
  401. package/dist/tracing/index.cjs +56 -0
  402. package/dist/tracing/index.cjs.map +1 -0
  403. package/dist/tracing/index.d.cts +4 -0
  404. package/dist/tracing/index.d.ts +4 -0
  405. package/dist/tracing/index.js +35 -0
  406. package/dist/tracing/index.js.map +1 -0
  407. package/dist/tracing/trace_hub.cjs +213 -0
  408. package/dist/tracing/trace_hub.cjs.map +1 -0
  409. package/dist/tracing/trace_hub.d.cts +47 -0
  410. package/dist/tracing/trace_hub.d.ts +47 -0
  411. package/dist/tracing/trace_hub.js +172 -0
  412. package/dist/tracing/trace_hub.js.map +1 -0
  413. package/dist/tracing/trace_provider.cjs +200 -0
  414. package/dist/tracing/trace_provider.cjs.map +1 -0
  415. package/dist/tracing/trace_provider.d.cts +69 -0
  416. package/dist/tracing/trace_provider.d.ts +69 -0
  417. package/dist/tracing/trace_provider.js +179 -0
  418. package/dist/tracing/trace_provider.js.map +1 -0
  419. package/dist/types/bridge.cjs +51 -0
  420. package/dist/types/bridge.cjs.map +1 -0
  421. package/dist/types/bridge.d.cts +56 -0
  422. package/dist/types/bridge.d.ts +56 -0
  423. package/dist/types/bridge.js +25 -0
  424. package/dist/types/bridge.js.map +1 -0
  425. package/dist/types/config.cjs +17 -0
  426. package/dist/types/config.cjs.map +1 -0
  427. package/dist/types/config.d.cts +74 -0
  428. package/dist/types/config.d.ts +74 -0
  429. package/dist/types/config.js +1 -0
  430. package/dist/types/config.js.map +1 -0
  431. package/dist/types/context.cjs +17 -0
  432. package/dist/types/context.cjs.map +1 -0
  433. package/dist/types/context.d.cts +61 -0
  434. package/dist/types/context.d.ts +61 -0
  435. package/dist/types/context.js +1 -0
  436. package/dist/types/context.js.map +1 -0
  437. package/dist/types/context_menu.cjs +17 -0
  438. package/dist/types/context_menu.cjs.map +1 -0
  439. package/dist/types/context_menu.d.cts +30 -0
  440. package/dist/types/context_menu.d.ts +30 -0
  441. package/dist/types/context_menu.js +1 -0
  442. package/dist/types/context_menu.js.map +1 -0
  443. package/dist/types/index.cjs +33 -0
  444. package/dist/types/index.cjs.map +1 -0
  445. package/dist/types/index.d.cts +6 -0
  446. package/dist/types/index.d.ts +6 -0
  447. package/dist/types/index.js +7 -0
  448. package/dist/types/index.js.map +1 -0
  449. package/dist/types/operations.cjs +17 -0
  450. package/dist/types/operations.cjs.map +1 -0
  451. package/dist/types/operations.d.cts +39 -0
  452. package/dist/types/operations.d.ts +39 -0
  453. package/dist/types/operations.js +1 -0
  454. package/dist/types/operations.js.map +1 -0
  455. package/dist/types/views.cjs +17 -0
  456. package/dist/types/views.cjs.map +1 -0
  457. package/dist/types/views.d.cts +44 -0
  458. package/dist/types/views.d.ts +44 -0
  459. package/dist/types/views.js +1 -0
  460. package/dist/types/views.js.map +1 -0
  461. package/dist/validation/index.cjs +29 -0
  462. package/dist/validation/index.cjs.map +1 -0
  463. package/dist/validation/index.d.cts +1 -0
  464. package/dist/validation/index.d.ts +1 -0
  465. package/dist/validation/index.js +5 -0
  466. package/dist/validation/index.js.map +1 -0
  467. package/dist/validation/schema_validator.cjs +86 -0
  468. package/dist/validation/schema_validator.cjs.map +1 -0
  469. package/dist/validation/schema_validator.d.cts +24 -0
  470. package/dist/validation/schema_validator.d.ts +24 -0
  471. package/dist/validation/schema_validator.js +52 -0
  472. package/dist/validation/schema_validator.js.map +1 -0
  473. package/dist/window/index.cjs +32 -0
  474. package/dist/window/index.cjs.map +1 -0
  475. package/dist/window/index.d.cts +4 -0
  476. package/dist/window/index.d.ts +4 -0
  477. package/dist/window/index.js +7 -0
  478. package/dist/window/index.js.map +1 -0
  479. package/dist/window/window_manager.cjs +354 -0
  480. package/dist/window/window_manager.cjs.map +1 -0
  481. package/dist/window/window_manager.d.cts +172 -0
  482. package/dist/window/window_manager.d.ts +172 -0
  483. package/dist/window/window_manager.js +330 -0
  484. package/dist/window/window_manager.js.map +1 -0
  485. package/dist/window/window_state_store.cjs +129 -0
  486. package/dist/window/window_state_store.cjs.map +1 -0
  487. package/dist/window/window_state_store.d.cts +39 -0
  488. package/dist/window/window_state_store.d.ts +39 -0
  489. package/dist/window/window_state_store.js +105 -0
  490. package/dist/window/window_state_store.js.map +1 -0
  491. package/loaders/loader.mjs +46 -0
  492. package/package.json +119 -0
  493. package/src/components/ContextMenuProvider.svelte +145 -0
  494. package/src/components/NavigationShell.svelte +204 -0
  495. package/src/components/WoodRecursiveRender.svelte +91 -0
  496. package/src/components/contextMenu.ts +228 -0
  497. package/src/components/index.d.ts +14 -0
  498. package/src/components/index.js +2 -0
  499. package/src/stick/WoodRecursiveRender.svelte +74 -0
@@ -0,0 +1,162 @@
1
+ import { readFileSync } from "node:fs";
2
+ import {
3
+ App,
4
+ clearClientAppForTests,
5
+ clearClientContainerForTests,
6
+ clearClientLoggersForTests,
7
+ clearClientNavigationForTests,
8
+ clearClientWindowControlsForTests,
9
+ getApp,
10
+ getWindowControls,
11
+ Ipc,
12
+ WOOD_INTERNAL_BRIDGE_KEY
13
+ } from "../client/index.js";
14
+ import { getIpc } from "../ipc/index.js";
15
+ import { Navigation, getNavigation } from "../navigation/index.js";
16
+ import { TraceProvider, TraceProviderConfiguration } from "../tracing/index.js";
17
+ import { parseOperations } from "../parser/operations_parser.js";
18
+ import { createRouterBridge } from "./create_router_bridge.js";
19
+ import { createTestRouter } from "./create_test_router.js";
20
+ function readOperations(input) {
21
+ if (input.includes("\n") || input.includes(":")) {
22
+ return parseOperations(input);
23
+ }
24
+ return parseOperations(readFileSync(input, "utf-8"));
25
+ }
26
+ function mergeOperations(inputs) {
27
+ const merged = /* @__PURE__ */ new Map();
28
+ for (const input of Array.isArray(inputs) ? inputs : [inputs]) {
29
+ for (const [channel, operation] of readOperations(input)) {
30
+ merged.set(channel, operation);
31
+ }
32
+ }
33
+ return merged;
34
+ }
35
+ function createRpcManifest(operations) {
36
+ return Array.from(operations.values()).map((operation) => ({
37
+ channel: operation.channel,
38
+ controller: operation.controller,
39
+ action: operation.action,
40
+ path: operation.channel.split("."),
41
+ hasInput: !!operation.inputSchema
42
+ }));
43
+ }
44
+ function registerClientBuiltins(container) {
45
+ if (typeof container.registerFunction !== "function") {
46
+ return;
47
+ }
48
+ const traceConfiguration = new TraceProviderConfiguration();
49
+ traceConfiguration.configureMode("test");
50
+ traceConfiguration.configureRuntime("renderer");
51
+ container.registerFunction(Navigation, () => getNavigation());
52
+ container.registerFunction(App, () => getApp());
53
+ container.registerFunction(Ipc, () => getIpc());
54
+ container.registerFunction(WindowControls, () => getWindowControls());
55
+ container.registerFunction(TraceProviderConfiguration, () => traceConfiguration);
56
+ }
57
+ class WindowControls {
58
+ async open(_windowId, _options) {
59
+ }
60
+ async close(_windowId) {
61
+ }
62
+ async focus(_windowId) {
63
+ }
64
+ async minimize(_windowId) {
65
+ }
66
+ async maximize(_windowId) {
67
+ }
68
+ }
69
+ async function createControllerHarness(options) {
70
+ await options.configureContainer?.(options.container);
71
+ if (typeof options.container.instance === "function") {
72
+ const rootTraceConfiguration = await options.container.instance(TraceProviderConfiguration);
73
+ rootTraceConfiguration.configureMode("test");
74
+ rootTraceConfiguration.configureRuntime("main");
75
+ }
76
+ const operations = mergeOperations(options.operations);
77
+ const { router } = createTestRouter("", {
78
+ container: options.container,
79
+ controllersDir: options.controllersDir,
80
+ middlewareDir: options.middlewareDir
81
+ });
82
+ router.loadOperations(operations);
83
+ await options.configureRouter?.(router);
84
+ const { bridge, events } = createRouterBridge(router);
85
+ const harnessBridge = Object.assign(bridge, {
86
+ __rpcManifest: createRpcManifest(operations)
87
+ });
88
+ const globalObj = globalThis;
89
+ const previousInternalBridge = globalObj[WOOD_INTERNAL_BRIDGE_KEY];
90
+ const previousWoodBridge = globalObj.wood;
91
+ globalObj[WOOD_INTERNAL_BRIDGE_KEY] = harnessBridge;
92
+ globalObj.wood = harnessBridge;
93
+ clearClientContainerForTests();
94
+ clearClientAppForTests();
95
+ clearClientNavigationForTests();
96
+ clearClientWindowControlsForTests();
97
+ clearClientLoggersForTests();
98
+ const scopedContainer = options.container.extend();
99
+ registerClientBuiltins(scopedContainer);
100
+ if (typeof scopedContainer.registerClass === "function") {
101
+ scopedContainer.registerClass(options.controllerClass);
102
+ }
103
+ const navigation = getNavigation();
104
+ await options.prepareClient?.({
105
+ bridge: harnessBridge,
106
+ events,
107
+ navigation,
108
+ container: scopedContainer
109
+ });
110
+ const controller = await scopedContainer.instance(options.controllerClass);
111
+ const trace = await scopedContainer.instance(TraceProvider);
112
+ if (options.initialize && typeof controller.initialize === "function") {
113
+ await Promise.resolve(
114
+ controller.initialize()
115
+ );
116
+ }
117
+ trace.info({
118
+ source: "wood.testing.controller-harness",
119
+ type: "harness.created",
120
+ payload: {
121
+ controllerClass: options.controllerClass.name
122
+ }
123
+ });
124
+ return {
125
+ controller,
126
+ bridge: harnessBridge,
127
+ events,
128
+ router,
129
+ container: scopedContainer,
130
+ navigation,
131
+ trace,
132
+ destroy: () => {
133
+ trace.info({
134
+ source: "wood.testing.controller-harness",
135
+ type: "harness.destroyed"
136
+ });
137
+ if (typeof controller.destroy === "function") {
138
+ controller.destroy();
139
+ }
140
+ events.clear();
141
+ clearClientContainerForTests();
142
+ clearClientAppForTests();
143
+ clearClientNavigationForTests();
144
+ clearClientWindowControlsForTests();
145
+ clearClientLoggersForTests();
146
+ if (previousInternalBridge === void 0) {
147
+ delete globalObj[WOOD_INTERNAL_BRIDGE_KEY];
148
+ } else {
149
+ globalObj[WOOD_INTERNAL_BRIDGE_KEY] = previousInternalBridge;
150
+ }
151
+ if (previousWoodBridge === void 0) {
152
+ delete globalObj.wood;
153
+ } else {
154
+ globalObj.wood = previousWoodBridge;
155
+ }
156
+ }
157
+ };
158
+ }
159
+ export {
160
+ createControllerHarness
161
+ };
162
+ //# sourceMappingURL=create_controller_harness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/testing/create_controller_harness.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport {\n App,\n clearClientAppForTests,\n clearClientContainerForTests,\n clearClientLoggersForTests,\n clearClientNavigationForTests,\n clearClientWindowControlsForTests,\n getApp,\n getWindowControls,\n Ipc,\n WOOD_INTERNAL_BRIDGE_KEY,\n} from '../client/index.js';\nimport { getIpc } from '../ipc/index.js';\nimport { Navigation, getNavigation } from '../navigation/index.js';\nimport { TraceProvider, TraceProviderConfiguration } from '../tracing/index.js';\nimport { parseOperations } from '../parser/operations_parser.js';\nimport type { OperationDef } from '../types/operations.js';\nimport { createRouterBridge, type RouterBridgeResult } from './create_router_bridge.js';\nimport { createTestRouter } from './create_test_router.js';\n\nexport interface CreateControllerHarnessOptions<T> {\n controllerClass: new (...args: any[]) => T;\n container: any;\n operations: string | string[];\n controllersDir: string;\n middlewareDir?: string;\n configureContainer?: (container: any) => void | Promise<void>;\n configureRouter?: (router: ReturnType<typeof createTestRouter>['router']) => void | Promise<void>;\n prepareClient?: (context: {\n bridge: Record<string, any>;\n events: RouterBridgeResult['events'];\n navigation: Navigation;\n container: any;\n }) => void | Promise<void>;\n initialize?: boolean;\n}\n\nexport interface ControllerHarnessResult<T> extends RouterBridgeResult {\n controller: T;\n container: any;\n router: ReturnType<typeof createTestRouter>['router'];\n navigation: Navigation;\n trace: TraceProvider;\n destroy: () => void;\n}\n\ntype MutableGlobal = typeof globalThis & {\n [WOOD_INTERNAL_BRIDGE_KEY]?: unknown;\n wood?: unknown;\n};\n\nfunction readOperations(input: string): Map<string, OperationDef> {\n if (input.includes('\\n') || input.includes(':')) {\n return parseOperations(input);\n }\n\n return parseOperations(readFileSync(input, 'utf-8'));\n}\n\nfunction mergeOperations(inputs: string | string[]): Map<string, OperationDef> {\n const merged = new Map<string, OperationDef>();\n\n for (const input of Array.isArray(inputs) ? inputs : [inputs]) {\n for (const [channel, operation] of readOperations(input)) {\n merged.set(channel, operation);\n }\n }\n\n return merged;\n}\n\nfunction createRpcManifest(operations: Map<string, OperationDef>) {\n return Array.from(operations.values()).map((operation) => ({\n channel: operation.channel,\n controller: operation.controller,\n action: operation.action,\n path: operation.channel.split('.'),\n hasInput: !!operation.inputSchema,\n }));\n}\n\nfunction registerClientBuiltins(container: any): void {\n if (typeof container.registerFunction !== 'function') {\n return;\n }\n\n const traceConfiguration = new TraceProviderConfiguration();\n traceConfiguration.configureMode('test');\n traceConfiguration.configureRuntime('renderer');\n\n container.registerFunction(Navigation, () => getNavigation());\n container.registerFunction(App, () => getApp());\n container.registerFunction(Ipc, () => getIpc());\n container.registerFunction(WindowControls, () => getWindowControls());\n container.registerFunction(TraceProviderConfiguration, () => traceConfiguration);\n}\n\nclass WindowControls {\n async open(_windowId: string, _options?: Record<string, unknown>): Promise<void> {}\n async close(_windowId?: string): Promise<void> {}\n async focus(_windowId: string): Promise<void> {}\n async minimize(_windowId?: string): Promise<void> {}\n async maximize(_windowId?: string): Promise<void> {}\n}\n\nexport async function createControllerHarness<T>(\n options: CreateControllerHarnessOptions<T>,\n): Promise<ControllerHarnessResult<T>> {\n await options.configureContainer?.(options.container);\n\n if (typeof options.container.instance === 'function') {\n const rootTraceConfiguration = await options.container.instance(TraceProviderConfiguration);\n rootTraceConfiguration.configureMode('test');\n rootTraceConfiguration.configureRuntime('main');\n }\n\n const operations = mergeOperations(options.operations);\n const { router } = createTestRouter('', {\n container: options.container,\n controllersDir: options.controllersDir,\n middlewareDir: options.middlewareDir,\n });\n router.loadOperations(operations);\n await options.configureRouter?.(router);\n\n const { bridge, events } = createRouterBridge(router);\n const harnessBridge = Object.assign(bridge, {\n __rpcManifest: createRpcManifest(operations),\n });\n\n const globalObj = globalThis as MutableGlobal;\n const previousInternalBridge = globalObj[WOOD_INTERNAL_BRIDGE_KEY];\n const previousWoodBridge = globalObj.wood;\n globalObj[WOOD_INTERNAL_BRIDGE_KEY] = harnessBridge;\n globalObj.wood = harnessBridge;\n\n clearClientContainerForTests();\n clearClientAppForTests();\n clearClientNavigationForTests();\n clearClientWindowControlsForTests();\n clearClientLoggersForTests();\n\n const scopedContainer = options.container.extend();\n registerClientBuiltins(scopedContainer);\n if (typeof scopedContainer.registerClass === 'function') {\n scopedContainer.registerClass(options.controllerClass);\n }\n const navigation = getNavigation();\n await options.prepareClient?.({\n bridge: harnessBridge,\n events,\n navigation,\n container: scopedContainer,\n });\n\n const controller = await scopedContainer.instance(options.controllerClass);\n const trace = await scopedContainer.instance(TraceProvider);\n if (options.initialize && typeof (controller as { initialize?: () => void }).initialize === 'function') {\n await Promise.resolve(\n (controller as { initialize: () => void | Promise<void> }).initialize(),\n );\n }\n\n trace.info({\n source: 'wood.testing.controller-harness',\n type: 'harness.created',\n payload: {\n controllerClass: options.controllerClass.name,\n },\n });\n\n return {\n controller,\n bridge: harnessBridge,\n events,\n router,\n container: scopedContainer,\n navigation,\n trace,\n destroy: () => {\n trace.info({\n source: 'wood.testing.controller-harness',\n type: 'harness.destroyed',\n });\n if (typeof (controller as { destroy?: () => void }).destroy === 'function') {\n (controller as { destroy: () => void }).destroy();\n }\n events.clear();\n clearClientContainerForTests();\n clearClientAppForTests();\n clearClientNavigationForTests();\n clearClientWindowControlsForTests();\n clearClientLoggersForTests();\n\n if (previousInternalBridge === undefined) {\n delete globalObj[WOOD_INTERNAL_BRIDGE_KEY];\n } else {\n globalObj[WOOD_INTERNAL_BRIDGE_KEY] = previousInternalBridge;\n }\n\n if (previousWoodBridge === undefined) {\n delete globalObj.wood;\n } else {\n globalObj.wood = previousWoodBridge;\n }\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,103 @@
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 create_router_bridge_exports = {};
20
+ __export(create_router_bridge_exports, {
21
+ RouterBridgeEvents: () => RouterBridgeEvents,
22
+ createRouterBridge: () => createRouterBridge
23
+ });
24
+ module.exports = __toCommonJS(create_router_bridge_exports);
25
+ var import_tracing = require("../tracing/index.js");
26
+ class RouterBridgeEvents {
27
+ constructor() {
28
+ this.listeners = /* @__PURE__ */ new Map();
29
+ }
30
+ /**
31
+ * Subscribe to a channel. Returns an unsubscribe function.
32
+ * This is exposed as bridge.on() — matching the WoodBridge contract.
33
+ */
34
+ on(channel, callback) {
35
+ if (!this.listeners.has(channel)) {
36
+ this.listeners.set(channel, /* @__PURE__ */ new Set());
37
+ }
38
+ this.listeners.get(channel).add(callback);
39
+ return () => {
40
+ this.listeners.get(channel)?.delete(callback);
41
+ };
42
+ }
43
+ /**
44
+ * Deliver an event to subscribers. Called by the WindowEventService sender.
45
+ * Strips the `__event:` prefix that WindowEventService always prepends.
46
+ */
47
+ emit(channel, data) {
48
+ const stripped = channel.startsWith("__event:") ? channel.slice("__event:".length) : channel;
49
+ const handlers = this.listeners.get(stripped);
50
+ if (handlers) {
51
+ for (const cb of handlers) {
52
+ cb(data);
53
+ }
54
+ }
55
+ }
56
+ /** Remove all listeners (for cleanup in afterEach). */
57
+ clear() {
58
+ this.listeners.clear();
59
+ }
60
+ listenerCount(channel) {
61
+ if (channel) {
62
+ return this.listeners.get(channel)?.size ?? 0;
63
+ }
64
+ let total = 0;
65
+ for (const handlers of this.listeners.values()) {
66
+ total += handlers.size;
67
+ }
68
+ return total;
69
+ }
70
+ }
71
+ function createRouterBridge(router) {
72
+ const events = new RouterBridgeEvents();
73
+ const bridge = buildBridgeTree(router, events);
74
+ return { bridge, events };
75
+ }
76
+ function buildBridgeTree(router, events) {
77
+ const tree = {};
78
+ for (const channel of router.getChannels()) {
79
+ const parts = channel.split(".");
80
+ let current = tree;
81
+ for (let i = 0; i < parts.length - 1; i++) {
82
+ if (!current[parts[i]]) {
83
+ current[parts[i]] = {};
84
+ }
85
+ current = current[parts[i]];
86
+ }
87
+ const leaf = parts[parts.length - 1];
88
+ current[leaf] = (data) => router.dispatch(channel, data ?? {});
89
+ }
90
+ tree.on = (channel, callback) => {
91
+ return events.on(channel, callback);
92
+ };
93
+ tree.__trace = async (payload) => {
94
+ return (0, import_tracing.dispatchRendererTracePayload)(payload);
95
+ };
96
+ return tree;
97
+ }
98
+ // Annotate the CommonJS export names for ESM import in node:
99
+ 0 && (module.exports = {
100
+ RouterBridgeEvents,
101
+ createRouterBridge
102
+ });
103
+ //# sourceMappingURL=create_router_bridge.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/testing/create_router_bridge.ts"],"sourcesContent":["import type { WoodRouter } from '../router/wood_router.cjs';\nimport { dispatchRendererTracePayload } from '../tracing/index.js';\n\n/**\n * An in-process event emitter that replaces Electron's\n * `webContents.send('__event:channel', data)` / `ipcRenderer.on('__event:channel', cb)`.\n *\n * The server side calls `WindowEventService.send(channel, data)` which prepends\n * `__event:` and calls the configured sender. In production that sender is\n * `mainWindow.webContents.send`. In tests we wire it to `RouterBridgeEvents.emit`\n * which strips the prefix and delivers to subscribers registered via `on()`.\n */\nexport class RouterBridgeEvents {\n private listeners = new Map<string, Set<(...args: unknown[]) => void>>();\n\n /**\n * Subscribe to a channel. Returns an unsubscribe function.\n * This is exposed as bridge.on() — matching the WoodBridge contract.\n */\n on(channel: string, callback: (...args: unknown[]) => void): () => void {\n if (!this.listeners.has(channel)) {\n this.listeners.set(channel, new Set());\n }\n this.listeners.get(channel)!.add(callback);\n return () => {\n this.listeners.get(channel)?.delete(callback);\n };\n }\n\n /**\n * Deliver an event to subscribers. Called by the WindowEventService sender.\n * Strips the `__event:` prefix that WindowEventService always prepends.\n */\n emit(channel: string, data: unknown): void {\n const stripped = channel.startsWith('__event:')\n ? channel.slice('__event:'.length)\n : channel;\n\n const handlers = this.listeners.get(stripped);\n if (handlers) {\n for (const cb of handlers) {\n cb(data);\n }\n }\n }\n\n /** Remove all listeners (for cleanup in afterEach). */\n clear(): void {\n this.listeners.clear();\n }\n\n listenerCount(channel?: string): number {\n if (channel) {\n return this.listeners.get(channel)?.size ?? 0;\n }\n\n let total = 0;\n for (const handlers of this.listeners.values()) {\n total += handlers.size;\n }\n return total;\n }\n}\n\nexport interface RouterBridgeResult {\n /**\n * A WoodBridge-shaped object where every operation method calls\n * `router.dispatch(channel, data)` — with real validation, scoped\n * containers, and middleware. The `on()` method delivers events\n * from the in-process event emitter.\n *\n * Wire this to your UI controllers as the WoodBridge dependency.\n */\n bridge: Record<string, any>;\n\n /**\n * The event emitter backing bridge.on().\n * Wire `WindowEventService.configure((ch, data) => events.emit(ch, data))`\n * to close the server→UI event loop.\n */\n events: RouterBridgeEvents;\n}\n\n/**\n * Build a WoodBridge-shaped object backed by `router.dispatch()`.\n *\n * Every operation channel (e.g. `chat.messages.send`) becomes a nested\n * method on the returned bridge that calls `router.dispatch(channel, data)`.\n * This means every call goes through the full WoodRouter pipeline:\n * input validation, scoped container, middleware, controller resolution.\n *\n * The bridge also includes an `on(channel, callback)` method backed by\n * an in-process event emitter. Connect `WindowEventService.configure()`\n * to `events.emit` to complete the server→UI push loop.\n *\n * Usage:\n * const { router } = createTestRouter(...);\n * const { bridge, events } = createRouterBridge(router);\n *\n * // Wire server→UI events\n * const windowEvents = await container.get(WindowEventService);\n * windowEvents.configure((ch, data) => events.emit(ch, data));\n *\n * // Use bridge as WoodBridge\n * const controller = new ConversationController(bridge, ...);\n */\nexport function createRouterBridge(router: WoodRouter): RouterBridgeResult {\n const events = new RouterBridgeEvents();\n const bridge = buildBridgeTree(router, events);\n\n return { bridge, events };\n}\n\n/**\n * Build the nested bridge object from the router's registered channels.\n *\n * Channels like `chat.messages.send` become `bridge.chat.messages.send(data)`.\n * The nesting algorithm is identical to the one used by the preload generator\n * and test mock generator in @noego/wood codegen — split on `.`, intermediate\n * segments become namespace objects, leaf segments become dispatch functions.\n */\nfunction buildBridgeTree(router: WoodRouter, events: RouterBridgeEvents): Record<string, any> {\n const tree: Record<string, any> = {};\n\n for (const channel of router.getChannels()) {\n const parts = channel.split('.');\n let current = tree;\n\n // Create/traverse intermediate namespace objects\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 // Leaf: function that dispatches through the router\n const leaf = parts[parts.length - 1];\n current[leaf] = (data?: unknown) => router.dispatch(channel, data ?? {});\n }\n\n // Attach the event subscription method (matches WoodBridge.on)\n tree.on = (channel: string, callback: (...args: unknown[]) => void) => {\n return events.on(channel, callback);\n };\n tree.__trace = async (payload: unknown) => {\n return dispatchRendererTracePayload(payload);\n };\n\n return tree;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,qBAA6C;AAWtC,MAAM,mBAAmB;AAAA,EAAzB;AACL,SAAQ,YAAY,oBAAI,IAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvE,GAAG,SAAiB,UAAoD;AACtE,QAAI,CAAC,KAAK,UAAU,IAAI,OAAO,GAAG;AAChC,WAAK,UAAU,IAAI,SAAS,oBAAI,IAAI,CAAC;AAAA,IACvC;AACA,SAAK,UAAU,IAAI,OAAO,EAAG,IAAI,QAAQ;AACzC,WAAO,MAAM;AACX,WAAK,UAAU,IAAI,OAAO,GAAG,OAAO,QAAQ;AAAA,IAC9C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,SAAiB,MAAqB;AACzC,UAAM,WAAW,QAAQ,WAAW,UAAU,IAC1C,QAAQ,MAAM,WAAW,MAAM,IAC/B;AAEJ,UAAM,WAAW,KAAK,UAAU,IAAI,QAAQ;AAC5C,QAAI,UAAU;AACZ,iBAAW,MAAM,UAAU;AACzB,WAAG,IAAI;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA,EAEA,cAAc,SAA0B;AACtC,QAAI,SAAS;AACX,aAAO,KAAK,UAAU,IAAI,OAAO,GAAG,QAAQ;AAAA,IAC9C;AAEA,QAAI,QAAQ;AACZ,eAAW,YAAY,KAAK,UAAU,OAAO,GAAG;AAC9C,eAAS,SAAS;AAAA,IACpB;AACA,WAAO;AAAA,EACT;AACF;AA4CO,SAAS,mBAAmB,QAAwC;AACzE,QAAM,SAAS,IAAI,mBAAmB;AACtC,QAAM,SAAS,gBAAgB,QAAQ,MAAM;AAE7C,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAUA,SAAS,gBAAgB,QAAoB,QAAiD;AAC5F,QAAM,OAA4B,CAAC;AAEnC,aAAW,WAAW,OAAO,YAAY,GAAG;AAC1C,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAU;AAGd,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;AAGA,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,YAAQ,IAAI,IAAI,CAAC,SAAmB,OAAO,SAAS,SAAS,QAAQ,CAAC,CAAC;AAAA,EACzE;AAGA,OAAK,KAAK,CAAC,SAAiB,aAA2C;AACrE,WAAO,OAAO,GAAG,SAAS,QAAQ;AAAA,EACpC;AACA,OAAK,UAAU,OAAO,YAAqB;AACzC,eAAO,6CAA6B,OAAO;AAAA,EAC7C;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,71 @@
1
+ import { WoodRouter } from '../router/wood_router.cjs';
2
+ import '../types/operations.cjs';
3
+
4
+ /**
5
+ * An in-process event emitter that replaces Electron's
6
+ * `webContents.send('__event:channel', data)` / `ipcRenderer.on('__event:channel', cb)`.
7
+ *
8
+ * The server side calls `WindowEventService.send(channel, data)` which prepends
9
+ * `__event:` and calls the configured sender. In production that sender is
10
+ * `mainWindow.webContents.send`. In tests we wire it to `RouterBridgeEvents.emit`
11
+ * which strips the prefix and delivers to subscribers registered via `on()`.
12
+ */
13
+ declare class RouterBridgeEvents {
14
+ private listeners;
15
+ /**
16
+ * Subscribe to a channel. Returns an unsubscribe function.
17
+ * This is exposed as bridge.on() — matching the WoodBridge contract.
18
+ */
19
+ on(channel: string, callback: (...args: unknown[]) => void): () => void;
20
+ /**
21
+ * Deliver an event to subscribers. Called by the WindowEventService sender.
22
+ * Strips the `__event:` prefix that WindowEventService always prepends.
23
+ */
24
+ emit(channel: string, data: unknown): void;
25
+ /** Remove all listeners (for cleanup in afterEach). */
26
+ clear(): void;
27
+ listenerCount(channel?: string): number;
28
+ }
29
+ interface RouterBridgeResult {
30
+ /**
31
+ * A WoodBridge-shaped object where every operation method calls
32
+ * `router.dispatch(channel, data)` — with real validation, scoped
33
+ * containers, and middleware. The `on()` method delivers events
34
+ * from the in-process event emitter.
35
+ *
36
+ * Wire this to your UI controllers as the WoodBridge dependency.
37
+ */
38
+ bridge: Record<string, any>;
39
+ /**
40
+ * The event emitter backing bridge.on().
41
+ * Wire `WindowEventService.configure((ch, data) => events.emit(ch, data))`
42
+ * to close the server→UI event loop.
43
+ */
44
+ events: RouterBridgeEvents;
45
+ }
46
+ /**
47
+ * Build a WoodBridge-shaped object backed by `router.dispatch()`.
48
+ *
49
+ * Every operation channel (e.g. `chat.messages.send`) becomes a nested
50
+ * method on the returned bridge that calls `router.dispatch(channel, data)`.
51
+ * This means every call goes through the full WoodRouter pipeline:
52
+ * input validation, scoped container, middleware, controller resolution.
53
+ *
54
+ * The bridge also includes an `on(channel, callback)` method backed by
55
+ * an in-process event emitter. Connect `WindowEventService.configure()`
56
+ * to `events.emit` to complete the server→UI push loop.
57
+ *
58
+ * Usage:
59
+ * const { router } = createTestRouter(...);
60
+ * const { bridge, events } = createRouterBridge(router);
61
+ *
62
+ * // Wire server→UI events
63
+ * const windowEvents = await container.get(WindowEventService);
64
+ * windowEvents.configure((ch, data) => events.emit(ch, data));
65
+ *
66
+ * // Use bridge as WoodBridge
67
+ * const controller = new ConversationController(bridge, ...);
68
+ */
69
+ declare function createRouterBridge(router: WoodRouter): RouterBridgeResult;
70
+
71
+ export { RouterBridgeEvents, type RouterBridgeResult, createRouterBridge };
@@ -0,0 +1,71 @@
1
+ import { WoodRouter } from '../router/wood_router.js';
2
+ import '../types/operations.js';
3
+
4
+ /**
5
+ * An in-process event emitter that replaces Electron's
6
+ * `webContents.send('__event:channel', data)` / `ipcRenderer.on('__event:channel', cb)`.
7
+ *
8
+ * The server side calls `WindowEventService.send(channel, data)` which prepends
9
+ * `__event:` and calls the configured sender. In production that sender is
10
+ * `mainWindow.webContents.send`. In tests we wire it to `RouterBridgeEvents.emit`
11
+ * which strips the prefix and delivers to subscribers registered via `on()`.
12
+ */
13
+ declare class RouterBridgeEvents {
14
+ private listeners;
15
+ /**
16
+ * Subscribe to a channel. Returns an unsubscribe function.
17
+ * This is exposed as bridge.on() — matching the WoodBridge contract.
18
+ */
19
+ on(channel: string, callback: (...args: unknown[]) => void): () => void;
20
+ /**
21
+ * Deliver an event to subscribers. Called by the WindowEventService sender.
22
+ * Strips the `__event:` prefix that WindowEventService always prepends.
23
+ */
24
+ emit(channel: string, data: unknown): void;
25
+ /** Remove all listeners (for cleanup in afterEach). */
26
+ clear(): void;
27
+ listenerCount(channel?: string): number;
28
+ }
29
+ interface RouterBridgeResult {
30
+ /**
31
+ * A WoodBridge-shaped object where every operation method calls
32
+ * `router.dispatch(channel, data)` — with real validation, scoped
33
+ * containers, and middleware. The `on()` method delivers events
34
+ * from the in-process event emitter.
35
+ *
36
+ * Wire this to your UI controllers as the WoodBridge dependency.
37
+ */
38
+ bridge: Record<string, any>;
39
+ /**
40
+ * The event emitter backing bridge.on().
41
+ * Wire `WindowEventService.configure((ch, data) => events.emit(ch, data))`
42
+ * to close the server→UI event loop.
43
+ */
44
+ events: RouterBridgeEvents;
45
+ }
46
+ /**
47
+ * Build a WoodBridge-shaped object backed by `router.dispatch()`.
48
+ *
49
+ * Every operation channel (e.g. `chat.messages.send`) becomes a nested
50
+ * method on the returned bridge that calls `router.dispatch(channel, data)`.
51
+ * This means every call goes through the full WoodRouter pipeline:
52
+ * input validation, scoped container, middleware, controller resolution.
53
+ *
54
+ * The bridge also includes an `on(channel, callback)` method backed by
55
+ * an in-process event emitter. Connect `WindowEventService.configure()`
56
+ * to `events.emit` to complete the server→UI push loop.
57
+ *
58
+ * Usage:
59
+ * const { router } = createTestRouter(...);
60
+ * const { bridge, events } = createRouterBridge(router);
61
+ *
62
+ * // Wire server→UI events
63
+ * const windowEvents = await container.get(WindowEventService);
64
+ * windowEvents.configure((ch, data) => events.emit(ch, data));
65
+ *
66
+ * // Use bridge as WoodBridge
67
+ * const controller = new ConversationController(bridge, ...);
68
+ */
69
+ declare function createRouterBridge(router: WoodRouter): RouterBridgeResult;
70
+
71
+ export { RouterBridgeEvents, type RouterBridgeResult, createRouterBridge };
@@ -0,0 +1,78 @@
1
+ import { dispatchRendererTracePayload } from "../tracing/index.js";
2
+ class RouterBridgeEvents {
3
+ constructor() {
4
+ this.listeners = /* @__PURE__ */ new Map();
5
+ }
6
+ /**
7
+ * Subscribe to a channel. Returns an unsubscribe function.
8
+ * This is exposed as bridge.on() — matching the WoodBridge contract.
9
+ */
10
+ on(channel, callback) {
11
+ if (!this.listeners.has(channel)) {
12
+ this.listeners.set(channel, /* @__PURE__ */ new Set());
13
+ }
14
+ this.listeners.get(channel).add(callback);
15
+ return () => {
16
+ this.listeners.get(channel)?.delete(callback);
17
+ };
18
+ }
19
+ /**
20
+ * Deliver an event to subscribers. Called by the WindowEventService sender.
21
+ * Strips the `__event:` prefix that WindowEventService always prepends.
22
+ */
23
+ emit(channel, data) {
24
+ const stripped = channel.startsWith("__event:") ? channel.slice("__event:".length) : channel;
25
+ const handlers = this.listeners.get(stripped);
26
+ if (handlers) {
27
+ for (const cb of handlers) {
28
+ cb(data);
29
+ }
30
+ }
31
+ }
32
+ /** Remove all listeners (for cleanup in afterEach). */
33
+ clear() {
34
+ this.listeners.clear();
35
+ }
36
+ listenerCount(channel) {
37
+ if (channel) {
38
+ return this.listeners.get(channel)?.size ?? 0;
39
+ }
40
+ let total = 0;
41
+ for (const handlers of this.listeners.values()) {
42
+ total += handlers.size;
43
+ }
44
+ return total;
45
+ }
46
+ }
47
+ function createRouterBridge(router) {
48
+ const events = new RouterBridgeEvents();
49
+ const bridge = buildBridgeTree(router, events);
50
+ return { bridge, events };
51
+ }
52
+ function buildBridgeTree(router, events) {
53
+ const tree = {};
54
+ for (const channel of router.getChannels()) {
55
+ const parts = channel.split(".");
56
+ let current = tree;
57
+ for (let i = 0; i < parts.length - 1; i++) {
58
+ if (!current[parts[i]]) {
59
+ current[parts[i]] = {};
60
+ }
61
+ current = current[parts[i]];
62
+ }
63
+ const leaf = parts[parts.length - 1];
64
+ current[leaf] = (data) => router.dispatch(channel, data ?? {});
65
+ }
66
+ tree.on = (channel, callback) => {
67
+ return events.on(channel, callback);
68
+ };
69
+ tree.__trace = async (payload) => {
70
+ return dispatchRendererTracePayload(payload);
71
+ };
72
+ return tree;
73
+ }
74
+ export {
75
+ RouterBridgeEvents,
76
+ createRouterBridge
77
+ };
78
+ //# sourceMappingURL=create_router_bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/testing/create_router_bridge.ts"],"sourcesContent":["import type { WoodRouter } from '../router/wood_router.js';\nimport { dispatchRendererTracePayload } from '../tracing/index.js';\n\n/**\n * An in-process event emitter that replaces Electron's\n * `webContents.send('__event:channel', data)` / `ipcRenderer.on('__event:channel', cb)`.\n *\n * The server side calls `WindowEventService.send(channel, data)` which prepends\n * `__event:` and calls the configured sender. In production that sender is\n * `mainWindow.webContents.send`. In tests we wire it to `RouterBridgeEvents.emit`\n * which strips the prefix and delivers to subscribers registered via `on()`.\n */\nexport class RouterBridgeEvents {\n private listeners = new Map<string, Set<(...args: unknown[]) => void>>();\n\n /**\n * Subscribe to a channel. Returns an unsubscribe function.\n * This is exposed as bridge.on() — matching the WoodBridge contract.\n */\n on(channel: string, callback: (...args: unknown[]) => void): () => void {\n if (!this.listeners.has(channel)) {\n this.listeners.set(channel, new Set());\n }\n this.listeners.get(channel)!.add(callback);\n return () => {\n this.listeners.get(channel)?.delete(callback);\n };\n }\n\n /**\n * Deliver an event to subscribers. Called by the WindowEventService sender.\n * Strips the `__event:` prefix that WindowEventService always prepends.\n */\n emit(channel: string, data: unknown): void {\n const stripped = channel.startsWith('__event:')\n ? channel.slice('__event:'.length)\n : channel;\n\n const handlers = this.listeners.get(stripped);\n if (handlers) {\n for (const cb of handlers) {\n cb(data);\n }\n }\n }\n\n /** Remove all listeners (for cleanup in afterEach). */\n clear(): void {\n this.listeners.clear();\n }\n\n listenerCount(channel?: string): number {\n if (channel) {\n return this.listeners.get(channel)?.size ?? 0;\n }\n\n let total = 0;\n for (const handlers of this.listeners.values()) {\n total += handlers.size;\n }\n return total;\n }\n}\n\nexport interface RouterBridgeResult {\n /**\n * A WoodBridge-shaped object where every operation method calls\n * `router.dispatch(channel, data)` — with real validation, scoped\n * containers, and middleware. The `on()` method delivers events\n * from the in-process event emitter.\n *\n * Wire this to your UI controllers as the WoodBridge dependency.\n */\n bridge: Record<string, any>;\n\n /**\n * The event emitter backing bridge.on().\n * Wire `WindowEventService.configure((ch, data) => events.emit(ch, data))`\n * to close the server→UI event loop.\n */\n events: RouterBridgeEvents;\n}\n\n/**\n * Build a WoodBridge-shaped object backed by `router.dispatch()`.\n *\n * Every operation channel (e.g. `chat.messages.send`) becomes a nested\n * method on the returned bridge that calls `router.dispatch(channel, data)`.\n * This means every call goes through the full WoodRouter pipeline:\n * input validation, scoped container, middleware, controller resolution.\n *\n * The bridge also includes an `on(channel, callback)` method backed by\n * an in-process event emitter. Connect `WindowEventService.configure()`\n * to `events.emit` to complete the server→UI push loop.\n *\n * Usage:\n * const { router } = createTestRouter(...);\n * const { bridge, events } = createRouterBridge(router);\n *\n * // Wire server→UI events\n * const windowEvents = await container.get(WindowEventService);\n * windowEvents.configure((ch, data) => events.emit(ch, data));\n *\n * // Use bridge as WoodBridge\n * const controller = new ConversationController(bridge, ...);\n */\nexport function createRouterBridge(router: WoodRouter): RouterBridgeResult {\n const events = new RouterBridgeEvents();\n const bridge = buildBridgeTree(router, events);\n\n return { bridge, events };\n}\n\n/**\n * Build the nested bridge object from the router's registered channels.\n *\n * Channels like `chat.messages.send` become `bridge.chat.messages.send(data)`.\n * The nesting algorithm is identical to the one used by the preload generator\n * and test mock generator in @noego/wood codegen — split on `.`, intermediate\n * segments become namespace objects, leaf segments become dispatch functions.\n */\nfunction buildBridgeTree(router: WoodRouter, events: RouterBridgeEvents): Record<string, any> {\n const tree: Record<string, any> = {};\n\n for (const channel of router.getChannels()) {\n const parts = channel.split('.');\n let current = tree;\n\n // Create/traverse intermediate namespace objects\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 // Leaf: function that dispatches through the router\n const leaf = parts[parts.length - 1];\n current[leaf] = (data?: unknown) => router.dispatch(channel, data ?? {});\n }\n\n // Attach the event subscription method (matches WoodBridge.on)\n tree.on = (channel: string, callback: (...args: unknown[]) => void) => {\n return events.on(channel, callback);\n };\n tree.__trace = async (payload: unknown) => {\n return dispatchRendererTracePayload(payload);\n };\n\n return tree;\n}\n"],"mappings":"AACA,SAAS,oCAAoC;AAWtC,MAAM,mBAAmB;AAAA,EAAzB;AACL,SAAQ,YAAY,oBAAI,IAA+C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvE,GAAG,SAAiB,UAAoD;AACtE,QAAI,CAAC,KAAK,UAAU,IAAI,OAAO,GAAG;AAChC,WAAK,UAAU,IAAI,SAAS,oBAAI,IAAI,CAAC;AAAA,IACvC;AACA,SAAK,UAAU,IAAI,OAAO,EAAG,IAAI,QAAQ;AACzC,WAAO,MAAM;AACX,WAAK,UAAU,IAAI,OAAO,GAAG,OAAO,QAAQ;AAAA,IAC9C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,SAAiB,MAAqB;AACzC,UAAM,WAAW,QAAQ,WAAW,UAAU,IAC1C,QAAQ,MAAM,WAAW,MAAM,IAC/B;AAEJ,UAAM,WAAW,KAAK,UAAU,IAAI,QAAQ;AAC5C,QAAI,UAAU;AACZ,iBAAW,MAAM,UAAU;AACzB,WAAG,IAAI;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,QAAc;AACZ,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA,EAEA,cAAc,SAA0B;AACtC,QAAI,SAAS;AACX,aAAO,KAAK,UAAU,IAAI,OAAO,GAAG,QAAQ;AAAA,IAC9C;AAEA,QAAI,QAAQ;AACZ,eAAW,YAAY,KAAK,UAAU,OAAO,GAAG;AAC9C,eAAS,SAAS;AAAA,IACpB;AACA,WAAO;AAAA,EACT;AACF;AA4CO,SAAS,mBAAmB,QAAwC;AACzE,QAAM,SAAS,IAAI,mBAAmB;AACtC,QAAM,SAAS,gBAAgB,QAAQ,MAAM;AAE7C,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAUA,SAAS,gBAAgB,QAAoB,QAAiD;AAC5F,QAAM,OAA4B,CAAC;AAEnC,aAAW,WAAW,OAAO,YAAY,GAAG;AAC1C,UAAM,QAAQ,QAAQ,MAAM,GAAG;AAC/B,QAAI,UAAU;AAGd,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;AAGA,UAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AACnC,YAAQ,IAAI,IAAI,CAAC,SAAmB,OAAO,SAAS,SAAS,QAAQ,CAAC,CAAC;AAAA,EACzE;AAGA,OAAK,KAAK,CAAC,SAAiB,aAA2C;AACrE,WAAO,OAAO,GAAG,SAAS,QAAQ;AAAA,EACpC;AACA,OAAK,UAAU,OAAO,YAAqB;AACzC,WAAO,6BAA6B,OAAO;AAAA,EAC7C;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,72 @@
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 create_test_container_exports = {};
20
+ __export(create_test_container_exports, {
21
+ createTestContainer: () => createTestContainer
22
+ });
23
+ module.exports = __toCommonJS(create_test_container_exports);
24
+ function createTestContainer(options) {
25
+ if (options?.useRealIoc) {
26
+ try {
27
+ const { createContainer } = require("@noego/ioc");
28
+ return createContainer();
29
+ } catch {
30
+ }
31
+ }
32
+ return createMockContainer();
33
+ }
34
+ function createMockContainer() {
35
+ const registry = /* @__PURE__ */ new Map();
36
+ return {
37
+ register: (token, factory) => {
38
+ registry.set(token, factory);
39
+ },
40
+ registerFunction: (token, factory) => {
41
+ registry.set(token, factory);
42
+ },
43
+ registerClass: (cls) => {
44
+ registry.set(cls, cls);
45
+ },
46
+ get: async (token) => {
47
+ const entry = registry.get(token);
48
+ if (typeof entry === "function" && !entry.prototype) {
49
+ return entry();
50
+ }
51
+ if (entry) return new entry();
52
+ throw new Error(`No binding for ${token}`);
53
+ },
54
+ instance: async (cls) => {
55
+ const entry = registry.get(cls);
56
+ if (entry) return new entry();
57
+ return new cls();
58
+ },
59
+ extend: () => {
60
+ const child = createMockContainer();
61
+ for (const [k, v] of registry) {
62
+ child.register(k, v);
63
+ }
64
+ return child;
65
+ }
66
+ };
67
+ }
68
+ // Annotate the CommonJS export names for ESM import in node:
69
+ 0 && (module.exports = {
70
+ createTestContainer
71
+ });
72
+ //# sourceMappingURL=create_test_container.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/testing/create_test_container.ts"],"sourcesContent":["/**\n * Create an IoC container pre-configured for testing.\n * Returns a minimal mock container that instantiates classes via `new`\n * without requiring explicit registration. This makes integration tests\n * work out of the box with any controller class.\n *\n * Pass `{ useRealIoc: true }` to get a real @noego/ioc container instead\n * (requires classes to be registered before resolution).\n */\nexport function createTestContainer(options?: { useRealIoc?: boolean }): any {\n if (options?.useRealIoc) {\n try {\n const { createContainer } = require('@noego/ioc');\n return createContainer();\n } catch {\n // Fall through to mock container\n }\n }\n\n return createMockContainer();\n}\n\nfunction createMockContainer(): any {\n const registry = new Map<any, any>();\n return {\n register: (token: any, factory: any) => {\n registry.set(token, factory);\n },\n registerFunction: (token: any, factory: any) => {\n registry.set(token, factory);\n },\n registerClass: (cls: any) => {\n registry.set(cls, cls);\n },\n get: async (token: any) => {\n const entry = registry.get(token);\n if (typeof entry === 'function' && !entry.prototype) {\n return entry();\n }\n if (entry) return new entry();\n throw new Error(`No binding for ${token}`);\n },\n instance: async (cls: any) => {\n const entry = registry.get(cls);\n if (entry) return new entry();\n return new cls();\n },\n extend: () => {\n const child = createMockContainer();\n for (const [k, v] of registry) {\n child.register(k, v);\n }\n return child;\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AASO,SAAS,oBAAoB,SAAyC;AAC3E,MAAI,SAAS,YAAY;AACvB,QAAI;AACF,YAAM,EAAE,gBAAgB,IAAI,QAAQ,YAAY;AAChD,aAAO,gBAAgB;AAAA,IACzB,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO,oBAAoB;AAC7B;AAEA,SAAS,sBAA2B;AAClC,QAAM,WAAW,oBAAI,IAAc;AACnC,SAAO;AAAA,IACL,UAAU,CAAC,OAAY,YAAiB;AACtC,eAAS,IAAI,OAAO,OAAO;AAAA,IAC7B;AAAA,IACA,kBAAkB,CAAC,OAAY,YAAiB;AAC9C,eAAS,IAAI,OAAO,OAAO;AAAA,IAC7B;AAAA,IACA,eAAe,CAAC,QAAa;AAC3B,eAAS,IAAI,KAAK,GAAG;AAAA,IACvB;AAAA,IACA,KAAK,OAAO,UAAe;AACzB,YAAM,QAAQ,SAAS,IAAI,KAAK;AAChC,UAAI,OAAO,UAAU,cAAc,CAAC,MAAM,WAAW;AACnD,eAAO,MAAM;AAAA,MACf;AACA,UAAI,MAAO,QAAO,IAAI,MAAM;AAC5B,YAAM,IAAI,MAAM,kBAAkB,KAAK,EAAE;AAAA,IAC3C;AAAA,IACA,UAAU,OAAO,QAAa;AAC5B,YAAM,QAAQ,SAAS,IAAI,GAAG;AAC9B,UAAI,MAAO,QAAO,IAAI,MAAM;AAC5B,aAAO,IAAI,IAAI;AAAA,IACjB;AAAA,IACA,QAAQ,MAAM;AACZ,YAAM,QAAQ,oBAAoB;AAClC,iBAAW,CAAC,GAAG,CAAC,KAAK,UAAU;AAC7B,cAAM,SAAS,GAAG,CAAC;AAAA,MACrB;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Create an IoC container pre-configured for testing.
3
+ * Returns a minimal mock container that instantiates classes via `new`
4
+ * without requiring explicit registration. This makes integration tests
5
+ * work out of the box with any controller class.
6
+ *
7
+ * Pass `{ useRealIoc: true }` to get a real @noego/ioc container instead
8
+ * (requires classes to be registered before resolution).
9
+ */
10
+ declare function createTestContainer(options?: {
11
+ useRealIoc?: boolean;
12
+ }): any;
13
+
14
+ export { createTestContainer };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Create an IoC container pre-configured for testing.
3
+ * Returns a minimal mock container that instantiates classes via `new`
4
+ * without requiring explicit registration. This makes integration tests
5
+ * work out of the box with any controller class.
6
+ *
7
+ * Pass `{ useRealIoc: true }` to get a real @noego/ioc container instead
8
+ * (requires classes to be registered before resolution).
9
+ */
10
+ declare function createTestContainer(options?: {
11
+ useRealIoc?: boolean;
12
+ }): any;
13
+
14
+ export { createTestContainer };