@noego/wood 0.6.2 → 0.7.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 (242) hide show
  1. package/README.md +7 -0
  2. package/dist/browser-test-setup.cjs +29 -0
  3. package/dist/browser-test-setup.cjs.map +1 -0
  4. package/dist/browser-test-setup.d.cts +8 -0
  5. package/dist/browser-test-setup.d.ts +8 -0
  6. package/dist/browser-test-setup.js +9 -0
  7. package/dist/browser-test-setup.js.map +1 -0
  8. package/dist/client/global_polyfill.d.cts +1 -0
  9. package/dist/client/global_polyfill.d.ts +1 -0
  10. package/dist/client/index.cjs +7 -0
  11. package/dist/client/index.cjs.map +1 -1
  12. package/dist/client/index.d.cts +7 -4
  13. package/dist/client/index.d.ts +7 -4
  14. package/dist/client/index.js +6 -1
  15. package/dist/client/index.js.map +1 -1
  16. package/dist/codegen/renderer_app_generator.cjs +97 -24
  17. package/dist/codegen/renderer_app_generator.cjs.map +1 -1
  18. package/dist/codegen/renderer_app_generator.js +97 -24
  19. package/dist/codegen/renderer_app_generator.js.map +1 -1
  20. package/dist/codegen/type_generator.cjs +9 -0
  21. package/dist/codegen/type_generator.cjs.map +1 -1
  22. package/dist/codegen/type_generator.js +9 -0
  23. package/dist/codegen/type_generator.js.map +1 -1
  24. package/dist/config/config_parser.cjs +10 -0
  25. package/dist/config/config_parser.cjs.map +1 -1
  26. package/dist/config/config_parser.js +10 -0
  27. package/dist/config/config_parser.js.map +1 -1
  28. package/dist/fetch.cjs +38 -0
  29. package/dist/fetch.cjs.map +1 -0
  30. package/dist/fetch.d.cts +7 -0
  31. package/dist/fetch.d.ts +7 -0
  32. package/dist/fetch.js +12 -0
  33. package/dist/fetch.js.map +1 -0
  34. package/dist/frontend/frontend_page.cjs +3 -3
  35. package/dist/frontend/frontend_page.cjs.map +1 -1
  36. package/dist/frontend/frontend_page.d.cts +1 -1
  37. package/dist/frontend/frontend_page.d.ts +1 -1
  38. package/dist/frontend/frontend_page.js +3 -3
  39. package/dist/frontend/frontend_page.js.map +1 -1
  40. package/dist/frontend/frontend_surface.cjs +31 -17
  41. package/dist/frontend/frontend_surface.cjs.map +1 -1
  42. package/dist/frontend/frontend_surface.d.cts +12 -2
  43. package/dist/frontend/frontend_surface.d.ts +12 -2
  44. package/dist/frontend/frontend_surface.js +37 -17
  45. package/dist/frontend/frontend_surface.js.map +1 -1
  46. package/dist/frontend/index.d.cts +2 -0
  47. package/dist/frontend/index.d.ts +2 -0
  48. package/dist/index.cjs +5 -0
  49. package/dist/index.cjs.map +1 -1
  50. package/dist/index.d.cts +25 -0
  51. package/dist/index.d.ts +25 -0
  52. package/dist/index.js +3 -0
  53. package/dist/index.js.map +1 -1
  54. package/dist/loader/index.cjs +19 -2
  55. package/dist/loader/index.cjs.map +1 -1
  56. package/dist/loader/index.d.cts +1 -0
  57. package/dist/loader/index.d.ts +1 -0
  58. package/dist/loader/index.js +19 -1
  59. package/dist/loader/index.js.map +1 -1
  60. package/dist/loader/loader_orchestration.cjs +82 -0
  61. package/dist/loader/loader_orchestration.cjs.map +1 -0
  62. package/dist/loader/loader_orchestration.d.cts +66 -0
  63. package/dist/loader/loader_orchestration.d.ts +66 -0
  64. package/dist/loader/loader_orchestration.js +51 -0
  65. package/dist/loader/loader_orchestration.js.map +1 -0
  66. package/dist/loader/loader_runner.cjs +46 -41
  67. package/dist/loader/loader_runner.cjs.map +1 -1
  68. package/dist/loader/loader_runner.d.cts +12 -6
  69. package/dist/loader/loader_runner.d.ts +12 -6
  70. package/dist/loader/loader_runner.js +50 -41
  71. package/dist/loader/loader_runner.js.map +1 -1
  72. package/dist/native_browser.types-BY2daUOS.d.ts +189 -0
  73. package/dist/native_browser.types-vWXtE4rM.d.cts +189 -0
  74. package/dist/navigation/index.cjs +15 -2
  75. package/dist/navigation/index.cjs.map +1 -1
  76. package/dist/navigation/index.d.cts +2 -0
  77. package/dist/navigation/index.d.ts +2 -0
  78. package/dist/navigation/index.js +8 -1
  79. package/dist/navigation/index.js.map +1 -1
  80. package/dist/runtime/get_container.cjs +2 -0
  81. package/dist/runtime/get_container.cjs.map +1 -1
  82. package/dist/runtime/get_container.js +2 -0
  83. package/dist/runtime/get_container.js.map +1 -1
  84. package/dist/runtime/index.cjs +5 -0
  85. package/dist/runtime/index.cjs.map +1 -1
  86. package/dist/runtime/index.d.cts +2 -0
  87. package/dist/runtime/index.d.ts +2 -0
  88. package/dist/runtime/index.js +3 -0
  89. package/dist/runtime/index.js.map +1 -1
  90. package/dist/runtime/runtime_capabilities.cjs +35 -0
  91. package/dist/runtime/runtime_capabilities.cjs.map +1 -0
  92. package/dist/runtime/runtime_capabilities.d.cts +6 -0
  93. package/dist/runtime/runtime_capabilities.d.ts +6 -0
  94. package/dist/runtime/runtime_capabilities.js +11 -0
  95. package/dist/runtime/runtime_capabilities.js.map +1 -0
  96. package/dist/runtime/runtime_module.cjs +2 -0
  97. package/dist/runtime/runtime_module.cjs.map +1 -1
  98. package/dist/runtime/runtime_module.js +2 -0
  99. package/dist/runtime/runtime_module.js.map +1 -1
  100. package/dist/test-wood.cjs +150 -0
  101. package/dist/test-wood.cjs.map +1 -0
  102. package/dist/test-wood.d.cts +62 -0
  103. package/dist/test-wood.d.ts +62 -0
  104. package/dist/test-wood.js +115 -0
  105. package/dist/test-wood.js.map +1 -0
  106. package/dist/testing/browser.cjs +92 -163
  107. package/dist/testing/browser.cjs.map +1 -1
  108. package/dist/testing/browser.d.cts +14 -13
  109. package/dist/testing/browser.d.ts +14 -13
  110. package/dist/testing/browser.js +88 -162
  111. package/dist/testing/browser.js.map +1 -1
  112. package/dist/testing/create_controller_harness.d.cts +2 -1
  113. package/dist/testing/create_controller_harness.d.ts +2 -1
  114. package/dist/testing/create_router_bridge.cjs +19 -15
  115. package/dist/testing/create_router_bridge.cjs.map +1 -1
  116. package/dist/testing/create_router_bridge.d.cts +8 -1
  117. package/dist/testing/create_router_bridge.d.ts +8 -1
  118. package/dist/testing/create_router_bridge.js +18 -15
  119. package/dist/testing/create_router_bridge.js.map +1 -1
  120. package/dist/testing/index.cjs +12 -4
  121. package/dist/testing/index.cjs.map +1 -1
  122. package/dist/testing/index.d.cts +11 -5
  123. package/dist/testing/index.d.ts +11 -5
  124. package/dist/testing/index.js +9 -3
  125. package/dist/testing/index.js.map +1 -1
  126. package/dist/testing/native_browser/browser_pool.cjs +31 -0
  127. package/dist/testing/native_browser/browser_pool.cjs.map +1 -0
  128. package/dist/testing/native_browser/browser_pool.d.cts +1 -0
  129. package/dist/testing/native_browser/browser_pool.d.ts +1 -0
  130. package/dist/testing/native_browser/browser_pool.js +6 -0
  131. package/dist/testing/native_browser/browser_pool.js.map +1 -0
  132. package/dist/testing/native_browser/happy_dom_tab.cjs +107 -0
  133. package/dist/testing/native_browser/happy_dom_tab.cjs.map +1 -0
  134. package/dist/testing/native_browser/happy_dom_tab.d.cts +35 -0
  135. package/dist/testing/native_browser/happy_dom_tab.d.ts +35 -0
  136. package/dist/testing/native_browser/happy_dom_tab.js +73 -0
  137. package/dist/testing/native_browser/happy_dom_tab.js.map +1 -0
  138. package/dist/testing/native_browser/happy_dom_transfer.cjs +29 -0
  139. package/dist/testing/native_browser/happy_dom_transfer.cjs.map +1 -0
  140. package/dist/testing/native_browser/happy_dom_transfer.d.cts +1 -0
  141. package/dist/testing/native_browser/happy_dom_transfer.d.ts +1 -0
  142. package/dist/testing/native_browser/happy_dom_transfer.js +5 -0
  143. package/dist/testing/native_browser/happy_dom_transfer.js.map +1 -0
  144. package/dist/testing/native_browser/host_transport.cjs +89 -0
  145. package/dist/testing/native_browser/host_transport.cjs.map +1 -0
  146. package/dist/testing/native_browser/host_transport.d.cts +44 -0
  147. package/dist/testing/native_browser/host_transport.d.ts +44 -0
  148. package/dist/testing/native_browser/host_transport.js +65 -0
  149. package/dist/testing/native_browser/host_transport.js.map +1 -0
  150. package/dist/testing/native_browser/native_browser.types.cjs +17 -0
  151. package/dist/testing/native_browser/native_browser.types.cjs.map +1 -0
  152. package/dist/testing/native_browser/native_browser.types.d.cts +31 -0
  153. package/dist/testing/native_browser/native_browser.types.d.ts +31 -0
  154. package/dist/testing/native_browser/native_browser.types.js +1 -0
  155. package/dist/testing/native_browser/native_browser.types.js.map +1 -0
  156. package/dist/testing/native_browser/native_browser_environment.cjs +143 -0
  157. package/dist/testing/native_browser/native_browser_environment.cjs.map +1 -0
  158. package/dist/testing/native_browser/native_browser_environment.d.cts +36 -0
  159. package/dist/testing/native_browser/native_browser_environment.d.ts +36 -0
  160. package/dist/testing/native_browser/native_browser_environment.js +109 -0
  161. package/dist/testing/native_browser/native_browser_environment.js.map +1 -0
  162. package/dist/testing/native_browser/native_browser_lifecycle.cjs +31 -0
  163. package/dist/testing/native_browser/native_browser_lifecycle.cjs.map +1 -0
  164. package/dist/testing/native_browser/native_browser_lifecycle.d.cts +1 -0
  165. package/dist/testing/native_browser/native_browser_lifecycle.d.ts +1 -0
  166. package/dist/testing/native_browser/native_browser_lifecycle.js +6 -0
  167. package/dist/testing/native_browser/native_browser_lifecycle.js.map +1 -0
  168. package/dist/testing/native_browser/playwright_tab.cjs +124 -0
  169. package/dist/testing/native_browser/playwright_tab.cjs.map +1 -0
  170. package/dist/testing/native_browser/playwright_tab.d.cts +35 -0
  171. package/dist/testing/native_browser/playwright_tab.d.ts +35 -0
  172. package/dist/testing/native_browser/playwright_tab.js +100 -0
  173. package/dist/testing/native_browser/playwright_tab.js.map +1 -0
  174. package/dist/testing/native_browser/renderer_compilation.cjs +149 -0
  175. package/dist/testing/native_browser/renderer_compilation.cjs.map +1 -0
  176. package/dist/testing/native_browser/renderer_compilation.d.cts +35 -0
  177. package/dist/testing/native_browser/renderer_compilation.d.ts +35 -0
  178. package/dist/testing/native_browser/renderer_compilation.js +115 -0
  179. package/dist/testing/native_browser/renderer_compilation.js.map +1 -0
  180. package/dist/testing/native_browser/renderer_entry.cjs +148 -0
  181. package/dist/testing/native_browser/renderer_entry.cjs.map +1 -0
  182. package/dist/testing/native_browser/renderer_entry.d.cts +13 -0
  183. package/dist/testing/native_browser/renderer_entry.d.ts +13 -0
  184. package/dist/testing/native_browser/renderer_entry.js +114 -0
  185. package/dist/testing/native_browser/renderer_entry.js.map +1 -0
  186. package/dist/testing/registration_only_root.cjs +61 -5
  187. package/dist/testing/registration_only_root.cjs.map +1 -1
  188. package/dist/testing/registration_only_root.d.cts +25 -4
  189. package/dist/testing/registration_only_root.d.ts +25 -4
  190. package/dist/testing/registration_only_root.js +60 -5
  191. package/dist/testing/registration_only_root.js.map +1 -1
  192. package/dist/testing/runner_importer.cjs +75 -0
  193. package/dist/testing/runner_importer.cjs.map +1 -0
  194. package/dist/testing/runner_importer.d.cts +8 -0
  195. package/dist/testing/runner_importer.d.ts +8 -0
  196. package/dist/testing/runner_importer.js +41 -0
  197. package/dist/testing/runner_importer.js.map +1 -0
  198. package/dist/testing/test_wood_config.cjs +387 -272
  199. package/dist/testing/test_wood_config.cjs.map +1 -1
  200. package/dist/testing/test_wood_config.d.cts +18 -123
  201. package/dist/testing/test_wood_config.d.ts +18 -123
  202. package/dist/testing/test_wood_config.js +396 -270
  203. package/dist/testing/test_wood_config.js.map +1 -1
  204. package/dist/testing/wood_config_source.cjs +12 -0
  205. package/dist/testing/wood_config_source.cjs.map +1 -1
  206. package/dist/testing/wood_config_source.d.cts +10 -0
  207. package/dist/testing/wood_config_source.d.ts +10 -0
  208. package/dist/testing/wood_config_source.js +12 -0
  209. package/dist/testing/wood_config_source.js.map +1 -1
  210. package/dist/testing/wood_env_renderer.cjs +28 -3
  211. package/dist/testing/wood_env_renderer.cjs.map +1 -1
  212. package/dist/testing/wood_env_renderer.d.cts +12 -1
  213. package/dist/testing/wood_env_renderer.d.ts +12 -1
  214. package/dist/testing/wood_env_renderer.js +28 -3
  215. package/dist/testing/wood_env_renderer.js.map +1 -1
  216. package/dist/testing/wood_lazy_runtime.cjs +109 -0
  217. package/dist/testing/wood_lazy_runtime.cjs.map +1 -0
  218. package/dist/testing/wood_lazy_runtime.d.cts +36 -0
  219. package/dist/testing/wood_lazy_runtime.d.ts +36 -0
  220. package/dist/testing/wood_lazy_runtime.js +84 -0
  221. package/dist/testing/wood_lazy_runtime.js.map +1 -0
  222. package/dist/testing/wood_test_selection.cjs +34 -55
  223. package/dist/testing/wood_test_selection.cjs.map +1 -1
  224. package/dist/testing/wood_test_selection.d.cts +18 -24
  225. package/dist/testing/wood_test_selection.d.ts +18 -24
  226. package/dist/testing/wood_test_selection.js +30 -54
  227. package/dist/testing/wood_test_selection.js.map +1 -1
  228. package/dist/testing-api.cjs +17 -0
  229. package/dist/testing-api.cjs.map +1 -0
  230. package/dist/testing-api.d.cts +18 -0
  231. package/dist/testing-api.d.ts +18 -0
  232. package/dist/testing-api.js +1 -0
  233. package/dist/testing-api.js.map +1 -0
  234. package/dist/types/config.cjs.map +1 -1
  235. package/dist/types/config.d.cts +4 -0
  236. package/dist/types/config.d.ts +4 -0
  237. package/docs/native-browser-testing.md +164 -0
  238. package/package.json +31 -5
  239. package/src/components/NavigationShell.browser.test.ts +10 -10
  240. package/src/components/NavigationShell.cleanup.browser.test.ts +57 -0
  241. package/src/components/NavigationShell.scopes.browser.test.ts +5 -5
  242. package/src/components/NavigationShell.svelte +50 -24
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var happy_dom_tab_exports = {};
30
+ __export(happy_dom_tab_exports, {
31
+ openHappyDomTab: () => openHappyDomTab
32
+ });
33
+ module.exports = __toCommonJS(happy_dom_tab_exports);
34
+ var import_browser = require("@noego/testing/browser");
35
+ var import_happy_dom_transfer = require("./happy_dom_transfer.js");
36
+ var import_host_transport = require("./host_transport.js");
37
+ var import_native_browser_lifecycle = require("./native_browser_lifecycle.js");
38
+ async function openHappyDomTab(inputs, bundle, route) {
39
+ const { Window } = await import("happy-dom");
40
+ const windowConfig = inputs.source.config.windows[route.page.split(".")[0]];
41
+ const window = new Window({
42
+ url: `https://wood.test/${encodeURIComponent(route.page)}`,
43
+ width: windowConfig?.width ?? 1024,
44
+ height: windowConfig?.height ?? 768,
45
+ settings: { enableJavaScriptEvaluation: true }
46
+ });
47
+ const networkHost = (0, import_browser.installHappyDomFetch)(window, (request) => inputs.network.dispatch(request));
48
+ const intoWindow = (0, import_happy_dom_transfer.createHappyDomTransfer)(window);
49
+ const globals = window;
50
+ const transport = (0, import_host_transport.nativeHostTransport)(inputs, async (channel, payload) => {
51
+ globals.__woodNativeEmit(channel, intoWindow(payload));
52
+ });
53
+ Object.assign(window, {
54
+ global: window,
55
+ __woodNativeRoute: intoWindow(route),
56
+ __woodNativeInvoke: async (channel, payload) => {
57
+ try {
58
+ return intoWindow(await transport.invoke(channel, structuredClone(payload)));
59
+ } catch (error) {
60
+ const nativeError = new window.Error(error instanceof Error ? error.message : String(error));
61
+ if (error instanceof Error) nativeError.name = error.name;
62
+ throw nativeError;
63
+ }
64
+ },
65
+ __woodNativeSubscribe: transport.subscribe,
66
+ __woodNativeTrace: (payload) => transport.trace(structuredClone(payload)),
67
+ __woodNativeLog: (payload) => transport.log(structuredClone(payload))
68
+ });
69
+ let closing = null;
70
+ const dispose = () => closing ?? (closing = (0, import_native_browser_lifecycle.disposeNativeResources)("Wood happy-dom window cleanup failed", [
71
+ () => (0, import_native_browser_lifecycle.hostDeadline)(Promise.resolve(globals.__woodNativeDispose?.()), "renderer teardown"),
72
+ () => transport.dispose(),
73
+ () => (0, import_native_browser_lifecycle.hostDeadline)(transport.flush(), "event drain"),
74
+ () => networkHost.dispose(),
75
+ () => window.happyDOM.close()
76
+ ]));
77
+ try {
78
+ window.document.body.innerHTML = '<div id="app"></div>';
79
+ if (bundle.css) {
80
+ const style = window.document.createElement("style");
81
+ style.textContent = bundle.css;
82
+ window.document.head.appendChild(style);
83
+ }
84
+ window.eval(bundle.code);
85
+ await (0, import_native_browser_lifecycle.hostDeadline)(Promise.resolve(globals.__woodNativeReady), "initial mount");
86
+ return {
87
+ native: window,
88
+ async flush() {
89
+ await (0, import_native_browser_lifecycle.hostDeadline)(networkHost.settle(), "external fetch drain");
90
+ await (0, import_native_browser_lifecycle.hostDeadline)(Promise.resolve(globals.__woodNativeFlush()), "renderer flush");
91
+ await (0, import_native_browser_lifecycle.hostDeadline)(transport.flush(), "event flush");
92
+ await globals.__woodNativeFlush();
93
+ },
94
+ dispose
95
+ };
96
+ } catch (error) {
97
+ await (0, import_native_browser_lifecycle.disposeNativeResources)("Wood happy-dom open failed", [() => {
98
+ throw error;
99
+ }, dispose]);
100
+ throw error;
101
+ }
102
+ }
103
+ // Annotate the CommonJS export names for ESM import in node:
104
+ 0 && (module.exports = {
105
+ openHappyDomTab
106
+ });
107
+ //# sourceMappingURL=happy_dom_tab.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/testing/native_browser/happy_dom_tab.ts"],"sourcesContent":["import { installHappyDomFetch } from '@noego/testing/browser';\nimport { createHappyDomTransfer } from './happy_dom_transfer.js';\nimport type { NativeBrowserInputs, NativeBrowserTab, NativeRendererBundle, NativeRendererRoute } from './native_browser.types.js';\nimport { nativeHostTransport } from './host_transport.js';\nimport { disposeNativeResources, hostDeadline } from './native_browser_lifecycle.js';\n\nexport async function openHappyDomTab(\n inputs: NativeBrowserInputs, bundle: NativeRendererBundle, route: NativeRendererRoute,\n): Promise<NativeBrowserTab> {\n const { Window } = await import('happy-dom');\n const windowConfig = inputs.source.config.windows[route.page.split('.')[0]!];\n const window = new Window({\n url: `https://wood.test/${encodeURIComponent(route.page)}`,\n width: windowConfig?.width ?? 1024, height: windowConfig?.height ?? 768,\n settings: {enableJavaScriptEvaluation: true},\n });\n // The Window owns its VM, timers, DOM and storage. Never install it on Node\n // globalThis or replace Vitest's globals; simultaneous cases remain isolated.\n const networkHost = installHappyDomFetch(window, request => inputs.network.dispatch(request));\n const intoWindow = createHappyDomTransfer(window);\n const globals = window as unknown as Record<string, any>;\n const transport = nativeHostTransport(inputs, async (channel, payload) => {\n globals.__woodNativeEmit(channel, intoWindow(payload));\n });\n Object.assign(window, {\n global: window,\n __woodNativeRoute: intoWindow(route),\n __woodNativeInvoke: async (channel: string, payload: unknown) => {\n try { return intoWindow(await transport.invoke(channel, structuredClone(payload))); }\n catch (error) {\n const nativeError = new window.Error(error instanceof Error ? error.message : String(error));\n if (error instanceof Error) nativeError.name = error.name;\n throw nativeError;\n }\n },\n __woodNativeSubscribe: transport.subscribe,\n __woodNativeTrace: (payload: unknown) => transport.trace(structuredClone(payload)),\n __woodNativeLog: (payload: unknown) => transport.log(structuredClone(payload)),\n });\n let closing: Promise<void> | null = null;\n const dispose = () => closing ??= disposeNativeResources('Wood happy-dom window cleanup failed', [\n () => hostDeadline(Promise.resolve(globals.__woodNativeDispose?.()), 'renderer teardown'),\n () => transport.dispose(),\n () => hostDeadline(transport.flush(), 'event drain'),\n () => networkHost.dispose(),\n () => window.happyDOM.close(),\n ]);\n try {\n window.document.body.innerHTML = '<div id=\"app\"></div>';\n if (bundle.css) {\n const style = window.document.createElement('style');\n style.textContent = bundle.css;\n window.document.head.appendChild(style);\n }\n window.eval(bundle.code);\n await hostDeadline(Promise.resolve(globals.__woodNativeReady), 'initial mount');\n return {\n native: window,\n async flush() {\n await hostDeadline(networkHost.settle(), 'external fetch drain');\n await hostDeadline(Promise.resolve(globals.__woodNativeFlush()), 'renderer flush');\n await hostDeadline(transport.flush(), 'event flush');\n await globals.__woodNativeFlush();\n },\n dispose,\n };\n } catch (error) {\n await disposeNativeResources('Wood happy-dom open failed', [() => {throw error;}, dispose]);\n throw error;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAqC;AACrC,gCAAuC;AAEvC,4BAAoC;AACpC,sCAAqD;AAErD,eAAsB,gBACpB,QAA6B,QAA8B,OAChC;AAC3B,QAAM,EAAE,OAAO,IAAI,MAAM,OAAO,WAAW;AAC3C,QAAM,eAAe,OAAO,OAAO,OAAO,QAAQ,MAAM,KAAK,MAAM,GAAG,EAAE,CAAC,CAAE;AAC3E,QAAM,SAAS,IAAI,OAAO;AAAA,IACxB,KAAK,qBAAqB,mBAAmB,MAAM,IAAI,CAAC;AAAA,IACxD,OAAO,cAAc,SAAS;AAAA,IAAM,QAAQ,cAAc,UAAU;AAAA,IACpE,UAAU,EAAC,4BAA4B,KAAI;AAAA,EAC7C,CAAC;AAGD,QAAM,kBAAc,qCAAqB,QAAQ,aAAW,OAAO,QAAQ,SAAS,OAAO,CAAC;AAC5F,QAAM,iBAAa,kDAAuB,MAAM;AAChD,QAAM,UAAU;AAChB,QAAM,gBAAY,2CAAoB,QAAQ,OAAO,SAAS,YAAY;AACxE,YAAQ,iBAAiB,SAAS,WAAW,OAAO,CAAC;AAAA,EACvD,CAAC;AACD,SAAO,OAAO,QAAQ;AAAA,IACpB,QAAQ;AAAA,IACR,mBAAmB,WAAW,KAAK;AAAA,IACnC,oBAAoB,OAAO,SAAiB,YAAqB;AAC/D,UAAI;AAAE,eAAO,WAAW,MAAM,UAAU,OAAO,SAAS,gBAAgB,OAAO,CAAC,CAAC;AAAA,MAAG,SAC7E,OAAO;AACZ,cAAM,cAAc,IAAI,OAAO,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAC3F,YAAI,iBAAiB,MAAO,aAAY,OAAO,MAAM;AACrD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,uBAAuB,UAAU;AAAA,IACjC,mBAAmB,CAAC,YAAqB,UAAU,MAAM,gBAAgB,OAAO,CAAC;AAAA,IACjF,iBAAiB,CAAC,YAAqB,UAAU,IAAI,gBAAgB,OAAO,CAAC;AAAA,EAC/E,CAAC;AACD,MAAI,UAAgC;AACpC,QAAM,UAAU,MAAM,0BAAY,wDAAuB,wCAAwC;AAAA,IAC/F,UAAM,8CAAa,QAAQ,QAAQ,QAAQ,sBAAsB,CAAC,GAAG,mBAAmB;AAAA,IACxF,MAAM,UAAU,QAAQ;AAAA,IACxB,UAAM,8CAAa,UAAU,MAAM,GAAG,aAAa;AAAA,IACnD,MAAM,YAAY,QAAQ;AAAA,IAC1B,MAAM,OAAO,SAAS,MAAM;AAAA,EAC9B,CAAC;AACD,MAAI;AACF,WAAO,SAAS,KAAK,YAAY;AACjC,QAAI,OAAO,KAAK;AACd,YAAM,QAAQ,OAAO,SAAS,cAAc,OAAO;AACnD,YAAM,cAAc,OAAO;AAC3B,aAAO,SAAS,KAAK,YAAY,KAAK;AAAA,IACxC;AACA,WAAO,KAAK,OAAO,IAAI;AACvB,cAAM,8CAAa,QAAQ,QAAQ,QAAQ,iBAAiB,GAAG,eAAe;AAC9E,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,QAAQ;AACZ,kBAAM,8CAAa,YAAY,OAAO,GAAG,sBAAsB;AAC/D,kBAAM,8CAAa,QAAQ,QAAQ,QAAQ,kBAAkB,CAAC,GAAG,gBAAgB;AACjF,kBAAM,8CAAa,UAAU,MAAM,GAAG,aAAa;AACnD,cAAM,QAAQ,kBAAkB;AAAA,MAClC;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,cAAM,wDAAuB,8BAA8B,CAAC,MAAM;AAAC,YAAM;AAAA,IAAM,GAAG,OAAO,CAAC;AAC1F,UAAM;AAAA,EACR;AACF;","names":[]}
@@ -0,0 +1,35 @@
1
+ import { h as NativeBrowserInputs, i as NativeRendererBundle, j as NativeRendererRoute, k as NativeBrowserTab } from '../../native_browser.types-vWXtE4rM.cjs';
2
+ import '@noego/testing/fetch';
3
+ import 'playwright';
4
+ import 'happy-dom';
5
+ import '../wood_config_source.cjs';
6
+ import '../../types/config.cjs';
7
+ import '../../types/operations.cjs';
8
+ import '../../types/views.cjs';
9
+ import '../create_router_bridge.cjs';
10
+ import '../../router/wood_router.cjs';
11
+ import '../../types/context.cjs';
12
+ import '../../validation/schema_validator.cjs';
13
+ import '../../middleware/middleware_resolver.cjs';
14
+ import '../../controller/controller_resolver.cjs';
15
+ import '../../testing-api.cjs';
16
+ import '@noego/ioc';
17
+ import '@noego/testing';
18
+ import '../../frontend/frontend_surface.cjs';
19
+ import '../../navigation/index.cjs';
20
+ import '../../navigation/layout_preservation.cjs';
21
+ import '../../navigation/automation_introspection.cjs';
22
+ import '../../loader/loader_orchestration.cjs';
23
+ import '../../frontend/page_catalog.cjs';
24
+ import '../../frontend/work_registry.cjs';
25
+ import '../../frontend/frontend_lifecycle.cjs';
26
+ import '../../frontend/frontend_page.cjs';
27
+ import '../wood_test_selection.cjs';
28
+ import '../wood_env_renderer.cjs';
29
+ import '../wood_dom_animation.cjs';
30
+ import '../registration_only_root.cjs';
31
+ import '../test_wood.cjs';
32
+
33
+ declare function openHappyDomTab(inputs: NativeBrowserInputs, bundle: NativeRendererBundle, route: NativeRendererRoute): Promise<NativeBrowserTab>;
34
+
35
+ export { openHappyDomTab };
@@ -0,0 +1,35 @@
1
+ import { h as NativeBrowserInputs, i as NativeRendererBundle, j as NativeRendererRoute, k as NativeBrowserTab } from '../../native_browser.types-BY2daUOS.js';
2
+ import '@noego/testing/fetch';
3
+ import 'playwright';
4
+ import 'happy-dom';
5
+ import '../wood_config_source.js';
6
+ import '../../types/config.js';
7
+ import '../../types/operations.js';
8
+ import '../../types/views.js';
9
+ import '../create_router_bridge.js';
10
+ import '../../router/wood_router.js';
11
+ import '../../types/context.js';
12
+ import '../../validation/schema_validator.js';
13
+ import '../../middleware/middleware_resolver.js';
14
+ import '../../controller/controller_resolver.js';
15
+ import '../../testing-api.js';
16
+ import '@noego/ioc';
17
+ import '@noego/testing';
18
+ import '../../frontend/frontend_surface.js';
19
+ import '../../navigation/index.js';
20
+ import '../../navigation/layout_preservation.js';
21
+ import '../../navigation/automation_introspection.js';
22
+ import '../../loader/loader_orchestration.js';
23
+ import '../../frontend/page_catalog.js';
24
+ import '../../frontend/work_registry.js';
25
+ import '../../frontend/frontend_lifecycle.js';
26
+ import '../../frontend/frontend_page.js';
27
+ import '../wood_test_selection.js';
28
+ import '../wood_env_renderer.js';
29
+ import '../wood_dom_animation.js';
30
+ import '../registration_only_root.js';
31
+ import '../test_wood.js';
32
+
33
+ declare function openHappyDomTab(inputs: NativeBrowserInputs, bundle: NativeRendererBundle, route: NativeRendererRoute): Promise<NativeBrowserTab>;
34
+
35
+ export { openHappyDomTab };
@@ -0,0 +1,73 @@
1
+ import { installHappyDomFetch } from "@noego/testing/browser";
2
+ import { createHappyDomTransfer } from "./happy_dom_transfer.js";
3
+ import { nativeHostTransport } from "./host_transport.js";
4
+ import { disposeNativeResources, hostDeadline } from "./native_browser_lifecycle.js";
5
+ async function openHappyDomTab(inputs, bundle, route) {
6
+ const { Window } = await import("happy-dom");
7
+ const windowConfig = inputs.source.config.windows[route.page.split(".")[0]];
8
+ const window = new Window({
9
+ url: `https://wood.test/${encodeURIComponent(route.page)}`,
10
+ width: windowConfig?.width ?? 1024,
11
+ height: windowConfig?.height ?? 768,
12
+ settings: { enableJavaScriptEvaluation: true }
13
+ });
14
+ const networkHost = installHappyDomFetch(window, (request) => inputs.network.dispatch(request));
15
+ const intoWindow = createHappyDomTransfer(window);
16
+ const globals = window;
17
+ const transport = nativeHostTransport(inputs, async (channel, payload) => {
18
+ globals.__woodNativeEmit(channel, intoWindow(payload));
19
+ });
20
+ Object.assign(window, {
21
+ global: window,
22
+ __woodNativeRoute: intoWindow(route),
23
+ __woodNativeInvoke: async (channel, payload) => {
24
+ try {
25
+ return intoWindow(await transport.invoke(channel, structuredClone(payload)));
26
+ } catch (error) {
27
+ const nativeError = new window.Error(error instanceof Error ? error.message : String(error));
28
+ if (error instanceof Error) nativeError.name = error.name;
29
+ throw nativeError;
30
+ }
31
+ },
32
+ __woodNativeSubscribe: transport.subscribe,
33
+ __woodNativeTrace: (payload) => transport.trace(structuredClone(payload)),
34
+ __woodNativeLog: (payload) => transport.log(structuredClone(payload))
35
+ });
36
+ let closing = null;
37
+ const dispose = () => closing ?? (closing = disposeNativeResources("Wood happy-dom window cleanup failed", [
38
+ () => hostDeadline(Promise.resolve(globals.__woodNativeDispose?.()), "renderer teardown"),
39
+ () => transport.dispose(),
40
+ () => hostDeadline(transport.flush(), "event drain"),
41
+ () => networkHost.dispose(),
42
+ () => window.happyDOM.close()
43
+ ]));
44
+ try {
45
+ window.document.body.innerHTML = '<div id="app"></div>';
46
+ if (bundle.css) {
47
+ const style = window.document.createElement("style");
48
+ style.textContent = bundle.css;
49
+ window.document.head.appendChild(style);
50
+ }
51
+ window.eval(bundle.code);
52
+ await hostDeadline(Promise.resolve(globals.__woodNativeReady), "initial mount");
53
+ return {
54
+ native: window,
55
+ async flush() {
56
+ await hostDeadline(networkHost.settle(), "external fetch drain");
57
+ await hostDeadline(Promise.resolve(globals.__woodNativeFlush()), "renderer flush");
58
+ await hostDeadline(transport.flush(), "event flush");
59
+ await globals.__woodNativeFlush();
60
+ },
61
+ dispose
62
+ };
63
+ } catch (error) {
64
+ await disposeNativeResources("Wood happy-dom open failed", [() => {
65
+ throw error;
66
+ }, dispose]);
67
+ throw error;
68
+ }
69
+ }
70
+ export {
71
+ openHappyDomTab
72
+ };
73
+ //# sourceMappingURL=happy_dom_tab.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/testing/native_browser/happy_dom_tab.ts"],"sourcesContent":["import { installHappyDomFetch } from '@noego/testing/browser';\nimport { createHappyDomTransfer } from './happy_dom_transfer.js';\nimport type { NativeBrowserInputs, NativeBrowserTab, NativeRendererBundle, NativeRendererRoute } from './native_browser.types.js';\nimport { nativeHostTransport } from './host_transport.js';\nimport { disposeNativeResources, hostDeadline } from './native_browser_lifecycle.js';\n\nexport async function openHappyDomTab(\n inputs: NativeBrowserInputs, bundle: NativeRendererBundle, route: NativeRendererRoute,\n): Promise<NativeBrowserTab> {\n const { Window } = await import('happy-dom');\n const windowConfig = inputs.source.config.windows[route.page.split('.')[0]!];\n const window = new Window({\n url: `https://wood.test/${encodeURIComponent(route.page)}`,\n width: windowConfig?.width ?? 1024, height: windowConfig?.height ?? 768,\n settings: {enableJavaScriptEvaluation: true},\n });\n // The Window owns its VM, timers, DOM and storage. Never install it on Node\n // globalThis or replace Vitest's globals; simultaneous cases remain isolated.\n const networkHost = installHappyDomFetch(window, request => inputs.network.dispatch(request));\n const intoWindow = createHappyDomTransfer(window);\n const globals = window as unknown as Record<string, any>;\n const transport = nativeHostTransport(inputs, async (channel, payload) => {\n globals.__woodNativeEmit(channel, intoWindow(payload));\n });\n Object.assign(window, {\n global: window,\n __woodNativeRoute: intoWindow(route),\n __woodNativeInvoke: async (channel: string, payload: unknown) => {\n try { return intoWindow(await transport.invoke(channel, structuredClone(payload))); }\n catch (error) {\n const nativeError = new window.Error(error instanceof Error ? error.message : String(error));\n if (error instanceof Error) nativeError.name = error.name;\n throw nativeError;\n }\n },\n __woodNativeSubscribe: transport.subscribe,\n __woodNativeTrace: (payload: unknown) => transport.trace(structuredClone(payload)),\n __woodNativeLog: (payload: unknown) => transport.log(structuredClone(payload)),\n });\n let closing: Promise<void> | null = null;\n const dispose = () => closing ??= disposeNativeResources('Wood happy-dom window cleanup failed', [\n () => hostDeadline(Promise.resolve(globals.__woodNativeDispose?.()), 'renderer teardown'),\n () => transport.dispose(),\n () => hostDeadline(transport.flush(), 'event drain'),\n () => networkHost.dispose(),\n () => window.happyDOM.close(),\n ]);\n try {\n window.document.body.innerHTML = '<div id=\"app\"></div>';\n if (bundle.css) {\n const style = window.document.createElement('style');\n style.textContent = bundle.css;\n window.document.head.appendChild(style);\n }\n window.eval(bundle.code);\n await hostDeadline(Promise.resolve(globals.__woodNativeReady), 'initial mount');\n return {\n native: window,\n async flush() {\n await hostDeadline(networkHost.settle(), 'external fetch drain');\n await hostDeadline(Promise.resolve(globals.__woodNativeFlush()), 'renderer flush');\n await hostDeadline(transport.flush(), 'event flush');\n await globals.__woodNativeFlush();\n },\n dispose,\n };\n } catch (error) {\n await disposeNativeResources('Wood happy-dom open failed', [() => {throw error;}, dispose]);\n throw error;\n }\n}\n"],"mappings":"AAAA,SAAS,4BAA4B;AACrC,SAAS,8BAA8B;AAEvC,SAAS,2BAA2B;AACpC,SAAS,wBAAwB,oBAAoB;AAErD,eAAsB,gBACpB,QAA6B,QAA8B,OAChC;AAC3B,QAAM,EAAE,OAAO,IAAI,MAAM,OAAO,WAAW;AAC3C,QAAM,eAAe,OAAO,OAAO,OAAO,QAAQ,MAAM,KAAK,MAAM,GAAG,EAAE,CAAC,CAAE;AAC3E,QAAM,SAAS,IAAI,OAAO;AAAA,IACxB,KAAK,qBAAqB,mBAAmB,MAAM,IAAI,CAAC;AAAA,IACxD,OAAO,cAAc,SAAS;AAAA,IAAM,QAAQ,cAAc,UAAU;AAAA,IACpE,UAAU,EAAC,4BAA4B,KAAI;AAAA,EAC7C,CAAC;AAGD,QAAM,cAAc,qBAAqB,QAAQ,aAAW,OAAO,QAAQ,SAAS,OAAO,CAAC;AAC5F,QAAM,aAAa,uBAAuB,MAAM;AAChD,QAAM,UAAU;AAChB,QAAM,YAAY,oBAAoB,QAAQ,OAAO,SAAS,YAAY;AACxE,YAAQ,iBAAiB,SAAS,WAAW,OAAO,CAAC;AAAA,EACvD,CAAC;AACD,SAAO,OAAO,QAAQ;AAAA,IACpB,QAAQ;AAAA,IACR,mBAAmB,WAAW,KAAK;AAAA,IACnC,oBAAoB,OAAO,SAAiB,YAAqB;AAC/D,UAAI;AAAE,eAAO,WAAW,MAAM,UAAU,OAAO,SAAS,gBAAgB,OAAO,CAAC,CAAC;AAAA,MAAG,SAC7E,OAAO;AACZ,cAAM,cAAc,IAAI,OAAO,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAC3F,YAAI,iBAAiB,MAAO,aAAY,OAAO,MAAM;AACrD,cAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,uBAAuB,UAAU;AAAA,IACjC,mBAAmB,CAAC,YAAqB,UAAU,MAAM,gBAAgB,OAAO,CAAC;AAAA,IACjF,iBAAiB,CAAC,YAAqB,UAAU,IAAI,gBAAgB,OAAO,CAAC;AAAA,EAC/E,CAAC;AACD,MAAI,UAAgC;AACpC,QAAM,UAAU,MAAM,sBAAY,uBAAuB,wCAAwC;AAAA,IAC/F,MAAM,aAAa,QAAQ,QAAQ,QAAQ,sBAAsB,CAAC,GAAG,mBAAmB;AAAA,IACxF,MAAM,UAAU,QAAQ;AAAA,IACxB,MAAM,aAAa,UAAU,MAAM,GAAG,aAAa;AAAA,IACnD,MAAM,YAAY,QAAQ;AAAA,IAC1B,MAAM,OAAO,SAAS,MAAM;AAAA,EAC9B,CAAC;AACD,MAAI;AACF,WAAO,SAAS,KAAK,YAAY;AACjC,QAAI,OAAO,KAAK;AACd,YAAM,QAAQ,OAAO,SAAS,cAAc,OAAO;AACnD,YAAM,cAAc,OAAO;AAC3B,aAAO,SAAS,KAAK,YAAY,KAAK;AAAA,IACxC;AACA,WAAO,KAAK,OAAO,IAAI;AACvB,UAAM,aAAa,QAAQ,QAAQ,QAAQ,iBAAiB,GAAG,eAAe;AAC9E,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,MAAM,QAAQ;AACZ,cAAM,aAAa,YAAY,OAAO,GAAG,sBAAsB;AAC/D,cAAM,aAAa,QAAQ,QAAQ,QAAQ,kBAAkB,CAAC,GAAG,gBAAgB;AACjF,cAAM,aAAa,UAAU,MAAM,GAAG,aAAa;AACnD,cAAM,QAAQ,kBAAkB;AAAA,MAClC;AAAA,MACA;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,uBAAuB,8BAA8B,CAAC,MAAM;AAAC,YAAM;AAAA,IAAM,GAAG,OAAO,CAAC;AAC1F,UAAM;AAAA,EACR;AACF;","names":[]}
@@ -0,0 +1,29 @@
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 happy_dom_transfer_exports = {};
20
+ __export(happy_dom_transfer_exports, {
21
+ createHappyDomTransfer: () => import_browser.createHappyDomTransfer
22
+ });
23
+ module.exports = __toCommonJS(happy_dom_transfer_exports);
24
+ var import_browser = require("@noego/testing/browser");
25
+ // Annotate the CommonJS export names for ESM import in node:
26
+ 0 && (module.exports = {
27
+ createHappyDomTransfer
28
+ });
29
+ //# sourceMappingURL=happy_dom_transfer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/testing/native_browser/happy_dom_transfer.ts"],"sourcesContent":["export { createHappyDomTransfer } from '@noego/testing/browser';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAuC;","names":[]}
@@ -0,0 +1 @@
1
+ export { createHappyDomTransfer } from '@noego/testing/browser';
@@ -0,0 +1 @@
1
+ export { createHappyDomTransfer } from '@noego/testing/browser';
@@ -0,0 +1,5 @@
1
+ import { createHappyDomTransfer } from "@noego/testing/browser";
2
+ export {
3
+ createHappyDomTransfer
4
+ };
5
+ //# sourceMappingURL=happy_dom_transfer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/testing/native_browser/happy_dom_transfer.ts"],"sourcesContent":["export { createHappyDomTransfer } from '@noego/testing/browser';\n"],"mappings":"AAAA,SAAS,8BAA8B;","names":[]}
@@ -0,0 +1,89 @@
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 host_transport_exports = {};
20
+ __export(host_transport_exports, {
21
+ nativeHostTransport: () => nativeHostTransport
22
+ });
23
+ module.exports = __toCommonJS(host_transport_exports);
24
+ var import_renderer_log_batch_receiver = require("../../runtime/renderer_log_batch_receiver.js");
25
+ var import_ioc = require("@noego/ioc");
26
+ var import_tracing = require("../../tracing/index.js");
27
+ function nativeHostTransport(inputs, emit) {
28
+ const subscriptions = /* @__PURE__ */ new Map();
29
+ const deliveries = /* @__PURE__ */ new Set();
30
+ const failures = [];
31
+ let closed = false;
32
+ const assertOpen = () => {
33
+ if (closed) throw new Error("Wood native tab is disposed");
34
+ };
35
+ return {
36
+ invoke(channel, payload) {
37
+ assertOpen();
38
+ if (typeof channel !== "string") return Promise.reject(new TypeError("Wood operation channel must be a string"));
39
+ return inputs.environment.call(channel, payload);
40
+ },
41
+ subscribe(channel, enabled) {
42
+ assertOpen();
43
+ if (typeof channel !== "string" || typeof enabled !== "boolean") throw new TypeError("Invalid Wood subscription");
44
+ if (!enabled) {
45
+ subscriptions.get(channel)?.();
46
+ subscriptions.delete(channel);
47
+ return;
48
+ }
49
+ if (subscriptions.has(channel)) return;
50
+ subscriptions.set(channel, inputs.events().on(channel, (payload) => {
51
+ if (closed) return;
52
+ const task = emit(channel, payload);
53
+ deliveries.add(task);
54
+ task.then(() => deliveries.delete(task), (error) => {
55
+ deliveries.delete(task);
56
+ failures.push(error);
57
+ });
58
+ }));
59
+ },
60
+ log(payload) {
61
+ assertOpen();
62
+ const result = import_ioc.ExecutionContext.run(inputs.environment.root, () => (0, import_renderer_log_batch_receiver.dispatchRendererLogBatch)(payload));
63
+ if (!result.ok) throw new Error(`Wood renderer log batch rejected: ${result.reason}`);
64
+ },
65
+ trace(payload) {
66
+ assertOpen();
67
+ import_ioc.ExecutionContext.run(inputs.environment.root, () => (0, import_tracing.dispatchRendererTracePayload)(payload));
68
+ },
69
+ async flush() {
70
+ while (deliveries.size) await Promise.all([...deliveries]);
71
+ if (failures.length) throw Object.assign(new Error("Wood native event delivery failed"), { errors: failures.splice(0) });
72
+ },
73
+ resetSubscriptions() {
74
+ for (const unsubscribe of subscriptions.values()) unsubscribe();
75
+ subscriptions.clear();
76
+ },
77
+ dispose() {
78
+ if (closed) return;
79
+ closed = true;
80
+ for (const unsubscribe of subscriptions.values()) unsubscribe();
81
+ subscriptions.clear();
82
+ }
83
+ };
84
+ }
85
+ // Annotate the CommonJS export names for ESM import in node:
86
+ 0 && (module.exports = {
87
+ nativeHostTransport
88
+ });
89
+ //# sourceMappingURL=host_transport.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/testing/native_browser/host_transport.ts"],"sourcesContent":["import { dispatchRendererLogBatch } from '../../runtime/renderer_log_batch_receiver.js';\nimport { ExecutionContext } from '@noego/ioc';\nimport { dispatchRendererTracePayload } from '../../tracing/index.js';\nimport type { NativeBrowserInputs } from './native_browser.types.js';\n\n/** Per-tab subscriptions and in-flight host deliveries; never a process singleton. */\nexport function nativeHostTransport(inputs: NativeBrowserInputs, emit: (channel: string, payload: unknown) => Promise<void>) {\n const subscriptions = new Map<string, () => void>();\n const deliveries = new Set<Promise<void>>();\n const failures: unknown[] = [];\n let closed = false;\n const assertOpen = () => { if (closed) throw new Error('Wood native tab is disposed'); };\n return {\n invoke(channel: string, payload: unknown): Promise<unknown> {\n assertOpen();\n if (typeof channel !== 'string') return Promise.reject(new TypeError('Wood operation channel must be a string'));\n // Includes aperture checks, lazy startup, ExecutionContext and the real router.\n return inputs.environment.call(channel, payload);\n },\n subscribe(channel: string, enabled: boolean): void {\n assertOpen();\n if (typeof channel !== 'string' || typeof enabled !== 'boolean') throw new TypeError('Invalid Wood subscription');\n if (!enabled) { subscriptions.get(channel)?.(); subscriptions.delete(channel); return; }\n if (subscriptions.has(channel)) return;\n subscriptions.set(channel, inputs.events().on(channel, (payload: unknown) => {\n if (closed) return;\n const task = emit(channel, payload);\n deliveries.add(task);\n task.then(() => deliveries.delete(task), error => {deliveries.delete(task); failures.push(error);});\n }));\n },\n log(payload: unknown): void {\n assertOpen();\n const result = ExecutionContext.run(inputs.environment.root as never, () => dispatchRendererLogBatch(payload));\n if (!result.ok) throw new Error(`Wood renderer log batch rejected: ${result.reason}`);\n },\n trace(payload: unknown): void {\n assertOpen();\n ExecutionContext.run(inputs.environment.root as never, () => dispatchRendererTracePayload(payload));\n },\n async flush(): Promise<void> {\n while (deliveries.size) await Promise.all([...deliveries]);\n if (failures.length) throw Object.assign(new Error('Wood native event delivery failed'), {errors: failures.splice(0)});\n },\n resetSubscriptions(): void {\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n },\n dispose(): void {\n if (closed) return;\n closed = true;\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yCAAyC;AACzC,iBAAiC;AACjC,qBAA6C;AAItC,SAAS,oBAAoB,QAA6B,MAA4D;AAC3H,QAAM,gBAAgB,oBAAI,IAAwB;AAClD,QAAM,aAAa,oBAAI,IAAmB;AAC1C,QAAM,WAAsB,CAAC;AAC7B,MAAI,SAAS;AACb,QAAM,aAAa,MAAM;AAAE,QAAI,OAAQ,OAAM,IAAI,MAAM,6BAA6B;AAAA,EAAG;AACvF,SAAO;AAAA,IACL,OAAO,SAAiB,SAAoC;AAC1D,iBAAW;AACX,UAAI,OAAO,YAAY,SAAU,QAAO,QAAQ,OAAO,IAAI,UAAU,yCAAyC,CAAC;AAE/G,aAAO,OAAO,YAAY,KAAK,SAAS,OAAO;AAAA,IACjD;AAAA,IACA,UAAU,SAAiB,SAAwB;AACjD,iBAAW;AACX,UAAI,OAAO,YAAY,YAAY,OAAO,YAAY,UAAW,OAAM,IAAI,UAAU,2BAA2B;AAChH,UAAI,CAAC,SAAS;AAAE,sBAAc,IAAI,OAAO,IAAI;AAAG,sBAAc,OAAO,OAAO;AAAG;AAAA,MAAQ;AACvF,UAAI,cAAc,IAAI,OAAO,EAAG;AAChC,oBAAc,IAAI,SAAS,OAAO,OAAO,EAAE,GAAG,SAAS,CAAC,YAAqB;AAC3E,YAAI,OAAQ;AACZ,cAAM,OAAO,KAAK,SAAS,OAAO;AAClC,mBAAW,IAAI,IAAI;AACnB,aAAK,KAAK,MAAM,WAAW,OAAO,IAAI,GAAG,WAAS;AAAC,qBAAW,OAAO,IAAI;AAAG,mBAAS,KAAK,KAAK;AAAA,QAAE,CAAC;AAAA,MACpG,CAAC,CAAC;AAAA,IACJ;AAAA,IACA,IAAI,SAAwB;AAC1B,iBAAW;AACX,YAAM,SAAS,4BAAiB,IAAI,OAAO,YAAY,MAAe,UAAM,6DAAyB,OAAO,CAAC;AAC7G,UAAI,CAAC,OAAO,GAAI,OAAM,IAAI,MAAM,qCAAqC,OAAO,MAAM,EAAE;AAAA,IACtF;AAAA,IACA,MAAM,SAAwB;AAC5B,iBAAW;AACX,kCAAiB,IAAI,OAAO,YAAY,MAAe,UAAM,6CAA6B,OAAO,CAAC;AAAA,IACpG;AAAA,IACA,MAAM,QAAuB;AAC3B,aAAO,WAAW,KAAM,OAAM,QAAQ,IAAI,CAAC,GAAG,UAAU,CAAC;AACzD,UAAI,SAAS,OAAQ,OAAM,OAAO,OAAO,IAAI,MAAM,mCAAmC,GAAG,EAAC,QAAQ,SAAS,OAAO,CAAC,EAAC,CAAC;AAAA,IACvH;AAAA,IACA,qBAA2B;AACzB,iBAAW,eAAe,cAAc,OAAO,EAAG,aAAY;AAC9D,oBAAc,MAAM;AAAA,IACtB;AAAA,IACA,UAAgB;AACd,UAAI,OAAQ;AACZ,eAAS;AACT,iBAAW,eAAe,cAAc,OAAO,EAAG,aAAY;AAC9D,oBAAc,MAAM;AAAA,IACtB;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,44 @@
1
+ import { h as NativeBrowserInputs } from '../../native_browser.types-vWXtE4rM.cjs';
2
+ import '@noego/testing/fetch';
3
+ import 'playwright';
4
+ import 'happy-dom';
5
+ import '../wood_config_source.cjs';
6
+ import '../../types/config.cjs';
7
+ import '../../types/operations.cjs';
8
+ import '../../types/views.cjs';
9
+ import '../create_router_bridge.cjs';
10
+ import '../../router/wood_router.cjs';
11
+ import '../../types/context.cjs';
12
+ import '../../validation/schema_validator.cjs';
13
+ import '../../middleware/middleware_resolver.cjs';
14
+ import '../../controller/controller_resolver.cjs';
15
+ import '../../testing-api.cjs';
16
+ import '@noego/ioc';
17
+ import '@noego/testing';
18
+ import '../../frontend/frontend_surface.cjs';
19
+ import '../../navigation/index.cjs';
20
+ import '../../navigation/layout_preservation.cjs';
21
+ import '../../navigation/automation_introspection.cjs';
22
+ import '../../loader/loader_orchestration.cjs';
23
+ import '../../frontend/page_catalog.cjs';
24
+ import '../../frontend/work_registry.cjs';
25
+ import '../../frontend/frontend_lifecycle.cjs';
26
+ import '../../frontend/frontend_page.cjs';
27
+ import '../wood_test_selection.cjs';
28
+ import '../wood_env_renderer.cjs';
29
+ import '../wood_dom_animation.cjs';
30
+ import '../registration_only_root.cjs';
31
+ import '../test_wood.cjs';
32
+
33
+ /** Per-tab subscriptions and in-flight host deliveries; never a process singleton. */
34
+ declare function nativeHostTransport(inputs: NativeBrowserInputs, emit: (channel: string, payload: unknown) => Promise<void>): {
35
+ invoke(channel: string, payload: unknown): Promise<unknown>;
36
+ subscribe(channel: string, enabled: boolean): void;
37
+ log(payload: unknown): void;
38
+ trace(payload: unknown): void;
39
+ flush(): Promise<void>;
40
+ resetSubscriptions(): void;
41
+ dispose(): void;
42
+ };
43
+
44
+ export { nativeHostTransport };
@@ -0,0 +1,44 @@
1
+ import { h as NativeBrowserInputs } from '../../native_browser.types-BY2daUOS.js';
2
+ import '@noego/testing/fetch';
3
+ import 'playwright';
4
+ import 'happy-dom';
5
+ import '../wood_config_source.js';
6
+ import '../../types/config.js';
7
+ import '../../types/operations.js';
8
+ import '../../types/views.js';
9
+ import '../create_router_bridge.js';
10
+ import '../../router/wood_router.js';
11
+ import '../../types/context.js';
12
+ import '../../validation/schema_validator.js';
13
+ import '../../middleware/middleware_resolver.js';
14
+ import '../../controller/controller_resolver.js';
15
+ import '../../testing-api.js';
16
+ import '@noego/ioc';
17
+ import '@noego/testing';
18
+ import '../../frontend/frontend_surface.js';
19
+ import '../../navigation/index.js';
20
+ import '../../navigation/layout_preservation.js';
21
+ import '../../navigation/automation_introspection.js';
22
+ import '../../loader/loader_orchestration.js';
23
+ import '../../frontend/page_catalog.js';
24
+ import '../../frontend/work_registry.js';
25
+ import '../../frontend/frontend_lifecycle.js';
26
+ import '../../frontend/frontend_page.js';
27
+ import '../wood_test_selection.js';
28
+ import '../wood_env_renderer.js';
29
+ import '../wood_dom_animation.js';
30
+ import '../registration_only_root.js';
31
+ import '../test_wood.js';
32
+
33
+ /** Per-tab subscriptions and in-flight host deliveries; never a process singleton. */
34
+ declare function nativeHostTransport(inputs: NativeBrowserInputs, emit: (channel: string, payload: unknown) => Promise<void>): {
35
+ invoke(channel: string, payload: unknown): Promise<unknown>;
36
+ subscribe(channel: string, enabled: boolean): void;
37
+ log(payload: unknown): void;
38
+ trace(payload: unknown): void;
39
+ flush(): Promise<void>;
40
+ resetSubscriptions(): void;
41
+ dispose(): void;
42
+ };
43
+
44
+ export { nativeHostTransport };
@@ -0,0 +1,65 @@
1
+ import { dispatchRendererLogBatch } from "../../runtime/renderer_log_batch_receiver.js";
2
+ import { ExecutionContext } from "@noego/ioc";
3
+ import { dispatchRendererTracePayload } from "../../tracing/index.js";
4
+ function nativeHostTransport(inputs, emit) {
5
+ const subscriptions = /* @__PURE__ */ new Map();
6
+ const deliveries = /* @__PURE__ */ new Set();
7
+ const failures = [];
8
+ let closed = false;
9
+ const assertOpen = () => {
10
+ if (closed) throw new Error("Wood native tab is disposed");
11
+ };
12
+ return {
13
+ invoke(channel, payload) {
14
+ assertOpen();
15
+ if (typeof channel !== "string") return Promise.reject(new TypeError("Wood operation channel must be a string"));
16
+ return inputs.environment.call(channel, payload);
17
+ },
18
+ subscribe(channel, enabled) {
19
+ assertOpen();
20
+ if (typeof channel !== "string" || typeof enabled !== "boolean") throw new TypeError("Invalid Wood subscription");
21
+ if (!enabled) {
22
+ subscriptions.get(channel)?.();
23
+ subscriptions.delete(channel);
24
+ return;
25
+ }
26
+ if (subscriptions.has(channel)) return;
27
+ subscriptions.set(channel, inputs.events().on(channel, (payload) => {
28
+ if (closed) return;
29
+ const task = emit(channel, payload);
30
+ deliveries.add(task);
31
+ task.then(() => deliveries.delete(task), (error) => {
32
+ deliveries.delete(task);
33
+ failures.push(error);
34
+ });
35
+ }));
36
+ },
37
+ log(payload) {
38
+ assertOpen();
39
+ const result = ExecutionContext.run(inputs.environment.root, () => dispatchRendererLogBatch(payload));
40
+ if (!result.ok) throw new Error(`Wood renderer log batch rejected: ${result.reason}`);
41
+ },
42
+ trace(payload) {
43
+ assertOpen();
44
+ ExecutionContext.run(inputs.environment.root, () => dispatchRendererTracePayload(payload));
45
+ },
46
+ async flush() {
47
+ while (deliveries.size) await Promise.all([...deliveries]);
48
+ if (failures.length) throw Object.assign(new Error("Wood native event delivery failed"), { errors: failures.splice(0) });
49
+ },
50
+ resetSubscriptions() {
51
+ for (const unsubscribe of subscriptions.values()) unsubscribe();
52
+ subscriptions.clear();
53
+ },
54
+ dispose() {
55
+ if (closed) return;
56
+ closed = true;
57
+ for (const unsubscribe of subscriptions.values()) unsubscribe();
58
+ subscriptions.clear();
59
+ }
60
+ };
61
+ }
62
+ export {
63
+ nativeHostTransport
64
+ };
65
+ //# sourceMappingURL=host_transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/testing/native_browser/host_transport.ts"],"sourcesContent":["import { dispatchRendererLogBatch } from '../../runtime/renderer_log_batch_receiver.js';\nimport { ExecutionContext } from '@noego/ioc';\nimport { dispatchRendererTracePayload } from '../../tracing/index.js';\nimport type { NativeBrowserInputs } from './native_browser.types.js';\n\n/** Per-tab subscriptions and in-flight host deliveries; never a process singleton. */\nexport function nativeHostTransport(inputs: NativeBrowserInputs, emit: (channel: string, payload: unknown) => Promise<void>) {\n const subscriptions = new Map<string, () => void>();\n const deliveries = new Set<Promise<void>>();\n const failures: unknown[] = [];\n let closed = false;\n const assertOpen = () => { if (closed) throw new Error('Wood native tab is disposed'); };\n return {\n invoke(channel: string, payload: unknown): Promise<unknown> {\n assertOpen();\n if (typeof channel !== 'string') return Promise.reject(new TypeError('Wood operation channel must be a string'));\n // Includes aperture checks, lazy startup, ExecutionContext and the real router.\n return inputs.environment.call(channel, payload);\n },\n subscribe(channel: string, enabled: boolean): void {\n assertOpen();\n if (typeof channel !== 'string' || typeof enabled !== 'boolean') throw new TypeError('Invalid Wood subscription');\n if (!enabled) { subscriptions.get(channel)?.(); subscriptions.delete(channel); return; }\n if (subscriptions.has(channel)) return;\n subscriptions.set(channel, inputs.events().on(channel, (payload: unknown) => {\n if (closed) return;\n const task = emit(channel, payload);\n deliveries.add(task);\n task.then(() => deliveries.delete(task), error => {deliveries.delete(task); failures.push(error);});\n }));\n },\n log(payload: unknown): void {\n assertOpen();\n const result = ExecutionContext.run(inputs.environment.root as never, () => dispatchRendererLogBatch(payload));\n if (!result.ok) throw new Error(`Wood renderer log batch rejected: ${result.reason}`);\n },\n trace(payload: unknown): void {\n assertOpen();\n ExecutionContext.run(inputs.environment.root as never, () => dispatchRendererTracePayload(payload));\n },\n async flush(): Promise<void> {\n while (deliveries.size) await Promise.all([...deliveries]);\n if (failures.length) throw Object.assign(new Error('Wood native event delivery failed'), {errors: failures.splice(0)});\n },\n resetSubscriptions(): void {\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n },\n dispose(): void {\n if (closed) return;\n closed = true;\n for (const unsubscribe of subscriptions.values()) unsubscribe();\n subscriptions.clear();\n },\n };\n}\n"],"mappings":"AAAA,SAAS,gCAAgC;AACzC,SAAS,wBAAwB;AACjC,SAAS,oCAAoC;AAItC,SAAS,oBAAoB,QAA6B,MAA4D;AAC3H,QAAM,gBAAgB,oBAAI,IAAwB;AAClD,QAAM,aAAa,oBAAI,IAAmB;AAC1C,QAAM,WAAsB,CAAC;AAC7B,MAAI,SAAS;AACb,QAAM,aAAa,MAAM;AAAE,QAAI,OAAQ,OAAM,IAAI,MAAM,6BAA6B;AAAA,EAAG;AACvF,SAAO;AAAA,IACL,OAAO,SAAiB,SAAoC;AAC1D,iBAAW;AACX,UAAI,OAAO,YAAY,SAAU,QAAO,QAAQ,OAAO,IAAI,UAAU,yCAAyC,CAAC;AAE/G,aAAO,OAAO,YAAY,KAAK,SAAS,OAAO;AAAA,IACjD;AAAA,IACA,UAAU,SAAiB,SAAwB;AACjD,iBAAW;AACX,UAAI,OAAO,YAAY,YAAY,OAAO,YAAY,UAAW,OAAM,IAAI,UAAU,2BAA2B;AAChH,UAAI,CAAC,SAAS;AAAE,sBAAc,IAAI,OAAO,IAAI;AAAG,sBAAc,OAAO,OAAO;AAAG;AAAA,MAAQ;AACvF,UAAI,cAAc,IAAI,OAAO,EAAG;AAChC,oBAAc,IAAI,SAAS,OAAO,OAAO,EAAE,GAAG,SAAS,CAAC,YAAqB;AAC3E,YAAI,OAAQ;AACZ,cAAM,OAAO,KAAK,SAAS,OAAO;AAClC,mBAAW,IAAI,IAAI;AACnB,aAAK,KAAK,MAAM,WAAW,OAAO,IAAI,GAAG,WAAS;AAAC,qBAAW,OAAO,IAAI;AAAG,mBAAS,KAAK,KAAK;AAAA,QAAE,CAAC;AAAA,MACpG,CAAC,CAAC;AAAA,IACJ;AAAA,IACA,IAAI,SAAwB;AAC1B,iBAAW;AACX,YAAM,SAAS,iBAAiB,IAAI,OAAO,YAAY,MAAe,MAAM,yBAAyB,OAAO,CAAC;AAC7G,UAAI,CAAC,OAAO,GAAI,OAAM,IAAI,MAAM,qCAAqC,OAAO,MAAM,EAAE;AAAA,IACtF;AAAA,IACA,MAAM,SAAwB;AAC5B,iBAAW;AACX,uBAAiB,IAAI,OAAO,YAAY,MAAe,MAAM,6BAA6B,OAAO,CAAC;AAAA,IACpG;AAAA,IACA,MAAM,QAAuB;AAC3B,aAAO,WAAW,KAAM,OAAM,QAAQ,IAAI,CAAC,GAAG,UAAU,CAAC;AACzD,UAAI,SAAS,OAAQ,OAAM,OAAO,OAAO,IAAI,MAAM,mCAAmC,GAAG,EAAC,QAAQ,SAAS,OAAO,CAAC,EAAC,CAAC;AAAA,IACvH;AAAA,IACA,qBAA2B;AACzB,iBAAW,eAAe,cAAc,OAAO,EAAG,aAAY;AAC9D,oBAAc,MAAM;AAAA,IACtB;AAAA,IACA,UAAgB;AACd,UAAI,OAAQ;AACZ,eAAS;AACT,iBAAW,eAAe,cAAc,OAAO,EAAG,aAAY;AAC9D,oBAAc,MAAM;AAAA,IACtB;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,17 @@
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 __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+ var native_browser_types_exports = {};
16
+ module.exports = __toCommonJS(native_browser_types_exports);
17
+ //# sourceMappingURL=native_browser.types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/testing/native_browser/native_browser.types.ts"],"sourcesContent":["import type { TestFetchRuntime } from '@noego/testing/fetch';\nimport type { Page } from 'playwright';\nimport type { Window } from 'happy-dom';\nimport type { TestWoodEnvironment } from '../test_wood_config.js';\nimport type { WoodConfigSource } from '../wood_config_source.js';\nimport type { ViewDef } from '../../types/views.js';\nimport type { RouterBridgeEvents } from '../create_router_bridge.js';\n\nexport type WoodBrowserHost = 'playwright' | 'happy_dom';\nexport type NativeWoodPage<H extends WoodBrowserHost> = H extends 'happy_dom' ? Window : Page;\n\n/** Route data, not a second browser-driver API. */\nexport interface WoodBrowserOpenOptions {\n readonly params?: Readonly<Record<string, string>>;\n readonly query?: Readonly<Record<string, string>>;\n}\n\n/** Native hosts expose application composition, NOT Wood's legacy DOM wrappers. */\nexport type NativeWoodTestEnvironment<H extends WoodBrowserHost> = Pick<TestWoodEnvironment,\n 'root' | 'router' | 'operations' | 'api' | 'rawApi' | 'get' | 'controller' | 'events' |\n 'verify' | 'settle' | 'dispose'\n> & {\n readonly browserHost: H;\n /** Each open is a new tab/window. Tabs in one env share its isolated browser context. */\n open(page: string, options?: WoodBrowserOpenOptions): Promise<NativeWoodPage<H>>;\n};\n\nexport type WoodTestEnvironmentFor<H extends WoodBrowserHost | null> =\n H extends WoodBrowserHost ? NativeWoodTestEnvironment<H> : TestWoodEnvironment;\n\nexport interface NativeBrowserInputs {\n readonly network: TestFetchRuntime;\n readonly source: WoodConfigSource;\n readonly views: readonly ViewDef[];\n readonly environment: TestWoodEnvironment;\n /** Read after main startup; a compose hook may select its event source in start(). */\n readonly events: () => RouterBridgeEvents;\n}\n\n/** Framework-owned resource record. Its native object is returned without a wrapper. */\nexport interface NativeBrowserTab {\n readonly native: Page | Window;\n flush(): Promise<void>;\n dispose(): Promise<void>;\n}\n\nexport interface NativeRendererAsset {\n readonly fileName: string;\n readonly source: Uint8Array;\n}\n\nexport interface NativeRendererBundle {\n readonly code: string;\n readonly css: string;\n /** Vite-emitted worker/wasm/image/etc. files served from the tab's synthetic origin. */\n readonly assets: ReadonlyMap<string, NativeRendererAsset>;\n}\n\nexport interface NativeRendererRoute {\n readonly page: string;\n readonly params: Readonly<Record<string, string>>;\n readonly query: Readonly<Record<string, string>>;\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}