@noego/wood 0.4.5 → 0.4.7

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 (248) hide show
  1. package/bin/wood.js +9 -1
  2. package/dist/client/app_env.cjs +39 -0
  3. package/dist/client/app_env.cjs.map +1 -0
  4. package/dist/client/app_env.d.cts +7 -0
  5. package/dist/client/app_env.d.ts +7 -0
  6. package/dist/client/app_env.js +14 -0
  7. package/dist/client/app_env.js.map +1 -0
  8. package/dist/client/index.cjs +33 -9
  9. package/dist/client/index.cjs.map +1 -1
  10. package/dist/client/index.d.cts +5 -1
  11. package/dist/client/index.d.ts +5 -1
  12. package/dist/client/index.js +32 -9
  13. package/dist/client/index.js.map +1 -1
  14. package/dist/codegen/channel_map_generator.cjs +102 -0
  15. package/dist/codegen/channel_map_generator.cjs.map +1 -0
  16. package/dist/codegen/channel_map_generator.d.cts +6 -0
  17. package/dist/codegen/channel_map_generator.d.ts +6 -0
  18. package/dist/codegen/channel_map_generator.js +78 -0
  19. package/dist/codegen/channel_map_generator.js.map +1 -0
  20. package/dist/codegen/controller_registration_generator.cjs +6 -1
  21. package/dist/codegen/controller_registration_generator.cjs.map +1 -1
  22. package/dist/codegen/controller_registration_generator.js +6 -1
  23. package/dist/codegen/controller_registration_generator.js.map +1 -1
  24. package/dist/codegen/generated_file_notice.cjs +40 -0
  25. package/dist/codegen/generated_file_notice.cjs.map +1 -0
  26. package/dist/codegen/generated_file_notice.d.cts +3 -0
  27. package/dist/codegen/generated_file_notice.d.ts +3 -0
  28. package/dist/codegen/generated_file_notice.js +16 -0
  29. package/dist/codegen/generated_file_notice.js.map +1 -0
  30. package/dist/codegen/index.cjs +3 -0
  31. package/dist/codegen/index.cjs.map +1 -1
  32. package/dist/codegen/index.d.cts +1 -0
  33. package/dist/codegen/index.d.ts +1 -0
  34. package/dist/codegen/index.js +2 -0
  35. package/dist/codegen/index.js.map +1 -1
  36. package/dist/codegen/preload_generator.cjs +97 -1
  37. package/dist/codegen/preload_generator.cjs.map +1 -1
  38. package/dist/codegen/preload_generator.js +97 -1
  39. package/dist/codegen/preload_generator.js.map +1 -1
  40. package/dist/codegen/renderer_app_generator.cjs +6 -1
  41. package/dist/codegen/renderer_app_generator.cjs.map +1 -1
  42. package/dist/codegen/renderer_app_generator.js +6 -1
  43. package/dist/codegen/renderer_app_generator.js.map +1 -1
  44. package/dist/codegen/renderer_controller_registration_generator.cjs +6 -1
  45. package/dist/codegen/renderer_controller_registration_generator.cjs.map +1 -1
  46. package/dist/codegen/renderer_controller_registration_generator.js +6 -1
  47. package/dist/codegen/renderer_controller_registration_generator.js.map +1 -1
  48. package/dist/codegen/renderer_view_manifest_generator.cjs +6 -1
  49. package/dist/codegen/renderer_view_manifest_generator.cjs.map +1 -1
  50. package/dist/codegen/renderer_view_manifest_generator.js +6 -1
  51. package/dist/codegen/renderer_view_manifest_generator.js.map +1 -1
  52. package/dist/codegen/runtime_generator.cjs +6 -1
  53. package/dist/codegen/runtime_generator.cjs.map +1 -1
  54. package/dist/codegen/runtime_generator.js +6 -1
  55. package/dist/codegen/runtime_generator.js.map +1 -1
  56. package/dist/codegen/test_mock_generator.cjs +5 -1
  57. package/dist/codegen/test_mock_generator.cjs.map +1 -1
  58. package/dist/codegen/test_mock_generator.js +5 -1
  59. package/dist/codegen/test_mock_generator.js.map +1 -1
  60. package/dist/codegen/type_generator.cjs +7 -1
  61. package/dist/codegen/type_generator.cjs.map +1 -1
  62. package/dist/codegen/type_generator.js +7 -1
  63. package/dist/codegen/type_generator.js.map +1 -1
  64. package/dist/index.cjs +19 -6
  65. package/dist/index.cjs.map +1 -1
  66. package/dist/index.d.cts +7 -1
  67. package/dist/index.d.ts +7 -1
  68. package/dist/index.js +13 -1
  69. package/dist/index.js.map +1 -1
  70. package/dist/main/index.cjs +287 -62
  71. package/dist/main/index.cjs.map +1 -1
  72. package/dist/main/index.d.cts +57 -3
  73. package/dist/main/index.d.ts +57 -3
  74. package/dist/main/index.js +289 -62
  75. package/dist/main/index.js.map +1 -1
  76. package/dist/main/renderer_trace_drain_coordinator.cjs +127 -0
  77. package/dist/main/renderer_trace_drain_coordinator.cjs.map +1 -0
  78. package/dist/main/renderer_trace_drain_coordinator.d.cts +46 -0
  79. package/dist/main/renderer_trace_drain_coordinator.d.ts +46 -0
  80. package/dist/main/renderer_trace_drain_coordinator.js +101 -0
  81. package/dist/main/renderer_trace_drain_coordinator.js.map +1 -0
  82. package/dist/router/wood_router.cjs +9 -1
  83. package/dist/router/wood_router.cjs.map +1 -1
  84. package/dist/router/wood_router.d.cts +1 -1
  85. package/dist/router/wood_router.d.ts +1 -1
  86. package/dist/router/wood_router.js +9 -1
  87. package/dist/router/wood_router.js.map +1 -1
  88. package/dist/runtime/app_env.cjs +52 -0
  89. package/dist/runtime/app_env.cjs.map +1 -0
  90. package/dist/runtime/app_env.d.cts +10 -0
  91. package/dist/runtime/app_env.d.ts +10 -0
  92. package/dist/runtime/app_env.js +18 -0
  93. package/dist/runtime/app_env.js.map +1 -0
  94. package/dist/runtime/index.cjs +9 -2
  95. package/dist/runtime/index.cjs.map +1 -1
  96. package/dist/runtime/index.d.cts +5 -1
  97. package/dist/runtime/index.d.ts +5 -1
  98. package/dist/runtime/index.js +9 -1
  99. package/dist/runtime/index.js.map +1 -1
  100. package/dist/runtime/renderer_log_dispatcher.cjs.map +1 -1
  101. package/dist/runtime/renderer_log_dispatcher.d.cts +1 -1
  102. package/dist/runtime/renderer_log_dispatcher.d.ts +1 -1
  103. package/dist/runtime/renderer_log_dispatcher.js.map +1 -1
  104. package/dist/runtime/renderer_trace_batch_receiver_registry.cjs +50 -0
  105. package/dist/runtime/renderer_trace_batch_receiver_registry.cjs.map +1 -0
  106. package/dist/runtime/renderer_trace_batch_receiver_registry.d.cts +10 -0
  107. package/dist/runtime/renderer_trace_batch_receiver_registry.d.ts +10 -0
  108. package/dist/runtime/renderer_trace_batch_receiver_registry.js +24 -0
  109. package/dist/runtime/renderer_trace_batch_receiver_registry.js.map +1 -0
  110. package/dist/runtime/runtime.cjs +75 -57
  111. package/dist/runtime/runtime.cjs.map +1 -1
  112. package/dist/runtime/runtime.d.cts +8 -1
  113. package/dist/runtime/runtime.d.ts +8 -1
  114. package/dist/runtime/runtime.js +80 -58
  115. package/dist/runtime/runtime.js.map +1 -1
  116. package/dist/testing/browser.cjs +540 -11
  117. package/dist/testing/browser.cjs.map +1 -1
  118. package/dist/testing/browser.d.cts +219 -3
  119. package/dist/testing/browser.d.ts +219 -3
  120. package/dist/testing/browser.js +540 -11
  121. package/dist/testing/browser.js.map +1 -1
  122. package/dist/testing/create_controller_harness.d.cts +1 -1
  123. package/dist/testing/create_controller_harness.d.ts +1 -1
  124. package/dist/testing/index.cjs +13 -0
  125. package/dist/testing/index.cjs.map +1 -1
  126. package/dist/testing/index.d.cts +7 -2
  127. package/dist/testing/index.d.ts +7 -2
  128. package/dist/testing/index.js +14 -0
  129. package/dist/testing/index.js.map +1 -1
  130. package/dist/trace-testing/index.d.cts +1 -1
  131. package/dist/trace-testing/index.d.ts +1 -1
  132. package/dist/trace-testing/trace_recorder.d.cts +1 -1
  133. package/dist/trace-testing/trace_recorder.d.ts +1 -1
  134. package/dist/trace-transport/index.cjs +32 -0
  135. package/dist/trace-transport/index.cjs.map +1 -0
  136. package/dist/trace-transport/index.d.cts +6 -0
  137. package/dist/trace-transport/index.d.ts +6 -0
  138. package/dist/trace-transport/index.js +7 -0
  139. package/dist/trace-transport/index.js.map +1 -0
  140. package/dist/trace_hub-Cob54qRx.d.cts +56 -0
  141. package/dist/trace_hub-Cob54qRx.d.ts +56 -0
  142. package/dist/tracing/index.cjs +14 -0
  143. package/dist/tracing/index.cjs.map +1 -1
  144. package/dist/tracing/index.d.cts +7 -1
  145. package/dist/tracing/index.d.ts +7 -1
  146. package/dist/tracing/index.js +12 -0
  147. package/dist/tracing/index.js.map +1 -1
  148. package/dist/tracing/renderer_trace_batch_host.cjs +80 -0
  149. package/dist/tracing/renderer_trace_batch_host.cjs.map +1 -0
  150. package/dist/tracing/renderer_trace_batch_host.d.cts +16 -0
  151. package/dist/tracing/renderer_trace_batch_host.d.ts +16 -0
  152. package/dist/tracing/renderer_trace_batch_host.js +56 -0
  153. package/dist/tracing/renderer_trace_batch_host.js.map +1 -0
  154. package/dist/tracing/renderer_trace_batch_transport.cjs +313 -0
  155. package/dist/tracing/renderer_trace_batch_transport.cjs.map +1 -0
  156. package/dist/tracing/renderer_trace_batch_transport.d.cts +53 -0
  157. package/dist/tracing/renderer_trace_batch_transport.d.ts +53 -0
  158. package/dist/tracing/renderer_trace_batch_transport.js +292 -0
  159. package/dist/tracing/renderer_trace_batch_transport.js.map +1 -0
  160. package/dist/tracing/trace_commit_writer.cjs +159 -0
  161. package/dist/tracing/trace_commit_writer.cjs.map +1 -0
  162. package/dist/tracing/trace_commit_writer.d.cts +97 -0
  163. package/dist/tracing/trace_commit_writer.d.ts +97 -0
  164. package/dist/tracing/trace_commit_writer.js +135 -0
  165. package/dist/tracing/trace_commit_writer.js.map +1 -0
  166. package/dist/tracing/trace_hub.cjs +58 -3
  167. package/dist/tracing/trace_hub.cjs.map +1 -1
  168. package/dist/tracing/trace_hub.d.cts +2 -46
  169. package/dist/tracing/trace_hub.d.ts +2 -46
  170. package/dist/tracing/trace_hub.js +56 -3
  171. package/dist/tracing/trace_hub.js.map +1 -1
  172. package/dist/tracing/trace_provider.cjs +42 -12
  173. package/dist/tracing/trace_provider.cjs.map +1 -1
  174. package/dist/tracing/trace_provider.d.cts +15 -1
  175. package/dist/tracing/trace_provider.d.ts +15 -1
  176. package/dist/tracing/trace_provider.js +43 -12
  177. package/dist/tracing/trace_provider.js.map +1 -1
  178. package/dist/tracing/types/wood_trace_batch.types.cjs +17 -0
  179. package/dist/tracing/types/wood_trace_batch.types.cjs.map +1 -0
  180. package/dist/tracing/types/wood_trace_batch.types.d.cts +124 -0
  181. package/dist/tracing/types/wood_trace_batch.types.d.ts +124 -0
  182. package/dist/tracing/types/wood_trace_batch.types.js +1 -0
  183. package/dist/tracing/types/wood_trace_batch.types.js.map +1 -0
  184. package/dist/tracing/types/wood_trace_sink.types.cjs +17 -0
  185. package/dist/tracing/types/wood_trace_sink.types.cjs.map +1 -0
  186. package/dist/tracing/types/wood_trace_sink.types.d.cts +2 -0
  187. package/dist/tracing/types/wood_trace_sink.types.d.ts +2 -0
  188. package/dist/tracing/types/wood_trace_sink.types.js +1 -0
  189. package/dist/tracing/types/wood_trace_sink.types.js.map +1 -0
  190. package/dist/tracing/wood_trace_batch_contract.cjs +229 -0
  191. package/dist/tracing/wood_trace_batch_contract.cjs.map +1 -0
  192. package/dist/tracing/wood_trace_batch_contract.d.cts +23 -0
  193. package/dist/tracing/wood_trace_batch_contract.d.ts +23 -0
  194. package/dist/tracing/wood_trace_batch_contract.js +205 -0
  195. package/dist/tracing/wood_trace_batch_contract.js.map +1 -0
  196. package/dist/transport/build_transport_bridge.cjs +62 -0
  197. package/dist/transport/build_transport_bridge.cjs.map +1 -0
  198. package/dist/transport/build_transport_bridge.d.cts +29 -0
  199. package/dist/transport/build_transport_bridge.d.ts +29 -0
  200. package/dist/transport/build_transport_bridge.js +38 -0
  201. package/dist/transport/build_transport_bridge.js.map +1 -0
  202. package/dist/transport/in_process_router_transport.cjs +41 -0
  203. package/dist/transport/in_process_router_transport.cjs.map +1 -0
  204. package/dist/transport/in_process_router_transport.d.cts +31 -0
  205. package/dist/transport/in_process_router_transport.d.ts +31 -0
  206. package/dist/transport/in_process_router_transport.js +17 -0
  207. package/dist/transport/in_process_router_transport.js.map +1 -0
  208. package/dist/transport/index.cjs +42 -0
  209. package/dist/transport/index.cjs.map +1 -0
  210. package/dist/transport/index.d.cts +8 -0
  211. package/dist/transport/index.d.ts +8 -0
  212. package/dist/transport/index.js +19 -0
  213. package/dist/transport/index.js.map +1 -0
  214. package/dist/transport/loopback_remote_transport.cjs +270 -0
  215. package/dist/transport/loopback_remote_transport.cjs.map +1 -0
  216. package/dist/transport/loopback_remote_transport.d.cts +49 -0
  217. package/dist/transport/loopback_remote_transport.d.ts +49 -0
  218. package/dist/transport/loopback_remote_transport.js +237 -0
  219. package/dist/transport/loopback_remote_transport.js.map +1 -0
  220. package/dist/transport/loopback_serialization.cjs +116 -0
  221. package/dist/transport/loopback_serialization.cjs.map +1 -0
  222. package/dist/transport/loopback_serialization.d.cts +28 -0
  223. package/dist/transport/loopback_serialization.d.ts +28 -0
  224. package/dist/transport/loopback_serialization.js +91 -0
  225. package/dist/transport/loopback_serialization.js.map +1 -0
  226. package/dist/transport/transport_contract_suite.cjs +110 -0
  227. package/dist/transport/transport_contract_suite.cjs.map +1 -0
  228. package/dist/transport/transport_contract_suite.d.cts +23 -0
  229. package/dist/transport/transport_contract_suite.d.ts +23 -0
  230. package/dist/transport/transport_contract_suite.js +85 -0
  231. package/dist/transport/transport_contract_suite.js.map +1 -0
  232. package/dist/transport/wood_rpc_transport.cjs +17 -0
  233. package/dist/transport/wood_rpc_transport.cjs.map +1 -0
  234. package/dist/transport/wood_rpc_transport.d.cts +44 -0
  235. package/dist/transport/wood_rpc_transport.d.ts +44 -0
  236. package/dist/transport/wood_rpc_transport.js +1 -0
  237. package/dist/transport/wood_rpc_transport.js.map +1 -0
  238. package/dist/types/config.cjs.map +1 -1
  239. package/dist/types/config.d.cts +12 -0
  240. package/dist/types/config.d.ts +12 -0
  241. package/dist/window/window_manager.cjs +3 -0
  242. package/dist/window/window_manager.cjs.map +1 -1
  243. package/dist/window/window_manager.js +3 -0
  244. package/dist/window/window_manager.js.map +1 -1
  245. package/docs/browser-testing.md +139 -1
  246. package/package.json +22 -3
  247. package/src/components/NavigationShell.browser.test.ts +236 -0
  248. package/src/components/NavigationShell.svelte +162 -49
package/dist/index.d.cts CHANGED
@@ -15,6 +15,7 @@ export { ControllerResolver, buildControllerArgs } from './controller/controller
15
15
  export { ControllerLifecycle, disposeControllerLifecycle } from './controller/controller_lifecycle.cjs';
16
16
  export { generatePreload } from './codegen/preload_generator.cjs';
17
17
  export { generateTypes } from './codegen/type_generator.cjs';
18
+ export { generateChannelMap } from './codegen/channel_map_generator.cjs';
18
19
  export { generateTestMock } from './codegen/test_mock_generator.cjs';
19
20
  export { ControllerRegistrationOptions, generateControllerRegistration } from './codegen/controller_registration_generator.cjs';
20
21
  export { RuntimeGeneratorOptions, generateRuntime } from './codegen/runtime_generator.cjs';
@@ -30,10 +31,15 @@ export { DEFAULT_WOOD_REMOTE_DEBUGGING_PORT, WOOD_DEV_DIRECTORY, WOOD_DEV_METADA
30
31
  export { GetContainerOptions, clearContainerRegistryForTests, getContainer } from './runtime/get_container.cjs';
31
32
  export { clearApplicationRootForTests, getApplicationRoot, setApplicationRoot } from './runtime/application_root.cjs';
32
33
  export { RegisterRuntimeRouter, RuntimeOptions, RuntimeResult, runtime } from './runtime/runtime.cjs';
33
- export { TraceDispatchResult, TraceEvent, TraceInput, TraceLevel, TraceProcess, TraceRuntimeContext, TraceWaitOptions, clearTraceHubForTests, getTraceEvents$, setRendererTraceEnabled, setRendererTraceTransport } from './tracing/trace_hub.cjs';
34
+ export { clearRendererTraceBatchReceiverForTests, getRendererTraceBatchReceiver, setRendererTraceBatchReceiver } from './runtime/renderer_trace_batch_receiver_registry.cjs';
35
+ export { T as TraceDispatchResult, a as TraceEvent, b as TraceInput, c as TraceLevel, d as TraceProcess, e as TraceRuntimeContext, f as TraceWaitOptions, W as WoodTraceEventSink, g as WoodTraceEventSnapshot, h as WoodTraceSinkDisposer, i as clearTraceHubForTests, j as getTraceEvents$, r as registerTraceSink, s as setRendererTraceEnabled, k as setRendererTraceTransport } from './trace_hub-Cob54qRx.cjs';
36
+ export { WoodRendererTraceEvent, WoodRendererTraceInput, WoodTraceBatch, WoodTraceBatchAcknowledgement, WoodTraceBatchReceiver, WoodTraceBatchRuntimeContext } from './tracing/types/wood_trace_batch.types.cjs';
37
+ export { TraceCommitRow, TraceCommitWriter, TraceCommitWriterOptions, TraceFlushOptions, TraceFlushResult, WoodTracePersistencePort } from './tracing/trace_commit_writer.cjs';
34
38
  export { FrameworkTracer, MainTracer, RendererTracer, TestTracer, TraceProvider, TraceProviderConfiguration, TraceProviderMode, TraceRuntime } from './tracing/trace_provider.cjs';
35
39
  export { Navigation, NavigationEntry, NavigationOptions, getNavigation, go, goback, goto } from './navigation/index.cjs';
36
40
  export { Ipc, getIpc } from './ipc/index.cjs';
37
41
  export { IpcPushOptions } from './ipc/shared.cjs';
42
+ import './runtime/app_env.cjs';
38
43
  import 'rxjs';
44
+ import '@noego/telemetry/core';
39
45
  import '@noego/ioc';
package/dist/index.d.ts CHANGED
@@ -15,6 +15,7 @@ export { ControllerResolver, buildControllerArgs } from './controller/controller
15
15
  export { ControllerLifecycle, disposeControllerLifecycle } from './controller/controller_lifecycle.js';
16
16
  export { generatePreload } from './codegen/preload_generator.js';
17
17
  export { generateTypes } from './codegen/type_generator.js';
18
+ export { generateChannelMap } from './codegen/channel_map_generator.js';
18
19
  export { generateTestMock } from './codegen/test_mock_generator.js';
19
20
  export { ControllerRegistrationOptions, generateControllerRegistration } from './codegen/controller_registration_generator.js';
20
21
  export { RuntimeGeneratorOptions, generateRuntime } from './codegen/runtime_generator.js';
@@ -30,10 +31,15 @@ export { DEFAULT_WOOD_REMOTE_DEBUGGING_PORT, WOOD_DEV_DIRECTORY, WOOD_DEV_METADA
30
31
  export { GetContainerOptions, clearContainerRegistryForTests, getContainer } from './runtime/get_container.js';
31
32
  export { clearApplicationRootForTests, getApplicationRoot, setApplicationRoot } from './runtime/application_root.js';
32
33
  export { RegisterRuntimeRouter, RuntimeOptions, RuntimeResult, runtime } from './runtime/runtime.js';
33
- export { TraceDispatchResult, TraceEvent, TraceInput, TraceLevel, TraceProcess, TraceRuntimeContext, TraceWaitOptions, clearTraceHubForTests, getTraceEvents$, setRendererTraceEnabled, setRendererTraceTransport } from './tracing/trace_hub.js';
34
+ export { clearRendererTraceBatchReceiverForTests, getRendererTraceBatchReceiver, setRendererTraceBatchReceiver } from './runtime/renderer_trace_batch_receiver_registry.js';
35
+ export { T as TraceDispatchResult, a as TraceEvent, b as TraceInput, c as TraceLevel, d as TraceProcess, e as TraceRuntimeContext, f as TraceWaitOptions, W as WoodTraceEventSink, g as WoodTraceEventSnapshot, h as WoodTraceSinkDisposer, i as clearTraceHubForTests, j as getTraceEvents$, r as registerTraceSink, s as setRendererTraceEnabled, k as setRendererTraceTransport } from './trace_hub-Cob54qRx.js';
36
+ export { WoodRendererTraceEvent, WoodRendererTraceInput, WoodTraceBatch, WoodTraceBatchAcknowledgement, WoodTraceBatchReceiver, WoodTraceBatchRuntimeContext } from './tracing/types/wood_trace_batch.types.js';
37
+ export { TraceCommitRow, TraceCommitWriter, TraceCommitWriterOptions, TraceFlushOptions, TraceFlushResult, WoodTracePersistencePort } from './tracing/trace_commit_writer.js';
34
38
  export { FrameworkTracer, MainTracer, RendererTracer, TestTracer, TraceProvider, TraceProviderConfiguration, TraceProviderMode, TraceRuntime } from './tracing/trace_provider.js';
35
39
  export { Navigation, NavigationEntry, NavigationOptions, getNavigation, go, goback, goto } from './navigation/index.js';
36
40
  export { Ipc, getIpc } from './ipc/index.js';
37
41
  export { IpcPushOptions } from './ipc/shared.js';
42
+ import './runtime/app_env.js';
38
43
  import 'rxjs';
44
+ import '@noego/telemetry/core';
39
45
  import '@noego/ioc';
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ import { MiddlewareResolver, buildMiddlewareContext, executeMiddleware } from ".
8
8
  import { ControllerResolver, buildControllerArgs, disposeControllerLifecycle } from "./controller/index.js";
9
9
  import { generatePreload } from "./codegen/index.js";
10
10
  import { generateTypes } from "./codegen/index.js";
11
+ import { generateChannelMap } from "./codegen/index.js";
11
12
  import { generateTestMock } from "./codegen/index.js";
12
13
  import { generateControllerRegistration } from "./codegen/index.js";
13
14
  import { generateRuntime } from "./codegen/index.js";
@@ -34,7 +35,10 @@ import {
34
35
  getApplicationRoot,
35
36
  setApplicationRoot,
36
37
  clearApplicationRootForTests,
37
- runtime
38
+ clearRendererTraceBatchReceiverForTests,
39
+ getRendererTraceBatchReceiver,
40
+ runtime,
41
+ setRendererTraceBatchReceiver
38
42
  } from "./runtime/index.js";
39
43
  import { Navigation, getNavigation, go, goto, goback } from "./navigation/index.js";
40
44
  import { Ipc, getIpc } from "./ipc/index.js";
@@ -45,8 +49,10 @@ import {
45
49
  TestTracer,
46
50
  TraceProvider,
47
51
  TraceProviderConfiguration,
52
+ TraceCommitWriter,
48
53
  clearTraceHubForTests,
49
54
  getTraceEvents$,
55
+ registerTraceSink,
50
56
  setRendererTraceEnabled,
51
57
  setRendererTraceTransport
52
58
  } from "./tracing/index.js";
@@ -64,6 +70,7 @@ export {
64
70
  RendererTracer,
65
71
  SchemaValidator,
66
72
  TestTracer,
73
+ TraceCommitWriter,
67
74
  TraceProvider,
68
75
  TraceProviderConfiguration,
69
76
  WOOD_DEV_DIRECTORY,
@@ -77,9 +84,11 @@ export {
77
84
  buildMiddlewareContext,
78
85
  clearApplicationRootForTests,
79
86
  clearContainerRegistryForTests,
87
+ clearRendererTraceBatchReceiverForTests,
80
88
  clearTraceHubForTests,
81
89
  disposeControllerLifecycle,
82
90
  executeMiddleware,
91
+ generateChannelMap,
83
92
  generateControllerRegistration,
84
93
  generatePreload,
85
94
  generateRendererApp,
@@ -92,6 +101,7 @@ export {
92
101
  getContainer,
93
102
  getIpc,
94
103
  getNavigation,
104
+ getRendererTraceBatchReceiver,
95
105
  getTraceEvents$,
96
106
  go,
97
107
  goback,
@@ -103,12 +113,14 @@ export {
103
113
  parseViewsFile,
104
114
  pushEvent,
105
115
  readWoodDevMetadata,
116
+ registerTraceSink,
106
117
  removeWoodDevMetadata,
107
118
  resolveWoodDevDirectory,
108
119
  resolveWoodDevMetadataPath,
109
120
  resolveWoodRemoteDebuggingPort,
110
121
  runtime,
111
122
  setApplicationRoot,
123
+ setRendererTraceBatchReceiver,
112
124
  setRendererTraceEnabled,
113
125
  setRendererTraceTransport,
114
126
  startBackendLoop,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @noego/wood — Declarative Electron desktop apps using the noego ecosystem\n\n// Types\nexport type {\n WoodConfig,\n WindowDef,\n DevConfig,\n ElectronBuilderConfig,\n OperationDef,\n RawOperationsDocument,\n RawModuleDef,\n RawOperationEntry,\n RawModuleOperationEntry,\n ViewDef,\n RawViewsDocument,\n RawViewEntry,\n ParameterDef,\n IpcContext,\n WoodMiddlewareContext,\n WoodMiddlewareFn,\n RequestData,\n ControllerArgs,\n LoaderResult,\n BridgeMessage,\n BridgeRequest,\n BridgeResponse,\n BridgeReady,\n BridgePush,\n BridgeElectronApi,\n SerializedError,\n ContextMenuContext,\n ContextMenuItem,\n ContextMenuEvent,\n} from './types';\n\n// Errors\nexport { WoodAuthError, WoodValidationError, BackendRestartingError } from './types/index.js';\n\n// Config\nexport { parseConfig } from './config/index.js';\n\n// Parsers\nexport { parseOperations, parseOperationsFile } from './parser/index.js';\nexport { parseViews, parseViewsFile } from './parser/index.js';\n\n// Router\nexport { WoodRouter } from './router/index.js';\n\n// Validation\nexport { SchemaValidator } from './validation/index.js';\n\n// Middleware\nexport { MiddlewareResolver, buildMiddlewareContext, executeMiddleware } from './middleware/index.js';\n\n// Controller\nexport { ControllerResolver, buildControllerArgs, disposeControllerLifecycle } from './controller/index.js';\nexport type { ControllerLifecycle } from './controller/index.js';\n\n// Codegen\nexport { generatePreload } from './codegen/index.js';\nexport { generateTypes } from './codegen/index.js';\nexport { generateTestMock } from './codegen/index.js';\nexport { generateControllerRegistration } from './codegen/index.js';\nexport type { ControllerRegistrationOptions } from './codegen/index.js';\nexport { generateRuntime } from './codegen/index.js';\nexport type { RuntimeGeneratorOptions } from './codegen/index.js';\nexport { generateRendererViewManifest } from './codegen/index.js';\nexport type { RendererViewManifestGeneratorOptions } from './codegen/index.js';\nexport { generateRendererControllerRegistration } from './codegen/index.js';\nexport type { RendererControllerRegistrationOptions } from './codegen/index.js';\nexport { generateRendererApp } from './codegen/index.js';\nexport type { RendererAppGeneratorOptions } from './codegen/index.js';\n\n// Window\nexport { WindowManager, WindowStateStore } from './window/index.js';\nexport type { ScreenLike, WindowBounds } from './window/index.js';\n\n// Loader\nexport { LoaderRunner } from './loader/index.js';\n\n// Bridge\nexport { BackendBridge, startBackendLoop, pushEvent } from './bridge/index.js';\n\n// Dev metadata (lightweight; safe at runtime)\n// Heavy dev tooling (WoodDevServer, BackendWatcher, YamlWatcher,\n// EsbuildBackend) is available via the '@noego/wood/dev' subpath only,\n// so production consumers never load esbuild/chokidar.\nexport {\n DEFAULT_WOOD_REMOTE_DEBUGGING_PORT,\n WOOD_DEV_DIRECTORY,\n WOOD_DEV_METADATA_BASENAME,\n resolveWoodRemoteDebuggingPort,\n resolveWoodDevDirectory,\n resolveWoodDevMetadataPath,\n writeWoodDevMetadata,\n readWoodDevMetadata,\n removeWoodDevMetadata,\n} from './dev/dev_metadata.js';\nexport type { WoodDevMetadata } from './dev/dev_metadata.js';\n\n// Runtime\nexport {\n getContainer,\n clearContainerRegistryForTests,\n getApplicationRoot,\n setApplicationRoot,\n clearApplicationRootForTests,\n runtime,\n} from './runtime/index.js';\nexport type {\n GetContainerOptions,\n RuntimeOptions,\n RuntimeResult,\n RegisterRuntimeRouter,\n} from './runtime';\n\n// Navigation\nexport { Navigation, getNavigation, go, goto, goback } from './navigation/index.js';\nexport type { NavigationEntry, NavigationOptions } from './navigation/index.js';\n\n// Isomorphic IPC API\nexport { Ipc, getIpc } from './ipc/index.js';\nexport type { IpcPushOptions } from './ipc/index.js';\n\n// Tracing\nexport {\n FrameworkTracer,\n MainTracer,\n RendererTracer,\n TestTracer,\n TraceProvider,\n TraceProviderConfiguration,\n clearTraceHubForTests,\n getTraceEvents$,\n setRendererTraceEnabled,\n setRendererTraceTransport,\n} from './tracing/index.js';\nexport type {\n TraceDispatchResult,\n TraceEvent,\n TraceInput,\n TraceLevel,\n TraceProcess,\n TraceProviderMode,\n TraceRuntimeContext,\n TraceRuntime,\n TraceWaitOptions,\n} from './tracing/index.js';\n\n// Testing — available via '@noego/wood/testing' subpath export.\n// Not re-exported here to avoid pulling vitest into production builds.\n"],"mappings":"AAoCA,SAAS,eAAe,qBAAqB,8BAA8B;AAG3E,SAAS,mBAAmB;AAG5B,SAAS,iBAAiB,2BAA2B;AACrD,SAAS,YAAY,sBAAsB;AAG3C,SAAS,kBAAkB;AAG3B,SAAS,uBAAuB;AAGhC,SAAS,oBAAoB,wBAAwB,yBAAyB;AAG9E,SAAS,oBAAoB,qBAAqB,kCAAkC;AAIpF,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,wBAAwB;AACjC,SAAS,sCAAsC;AAE/C,SAAS,uBAAuB;AAEhC,SAAS,oCAAoC;AAE7C,SAAS,8CAA8C;AAEvD,SAAS,2BAA2B;AAIpC,SAAS,eAAe,wBAAwB;AAIhD,SAAS,oBAAoB;AAG7B,SAAS,eAAe,kBAAkB,iBAAiB;AAM3D;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASP,SAAS,YAAY,eAAe,IAAI,MAAM,cAAc;AAI5D,SAAS,KAAK,cAAc;AAI5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @noego/wood — Declarative Electron desktop apps using the noego ecosystem\n\n// Types\nexport type {\n WoodConfig,\n WindowDef,\n DevConfig,\n ElectronBuilderConfig,\n OperationDef,\n RawOperationsDocument,\n RawModuleDef,\n RawOperationEntry,\n RawModuleOperationEntry,\n ViewDef,\n RawViewsDocument,\n RawViewEntry,\n ParameterDef,\n IpcContext,\n WoodMiddlewareContext,\n WoodMiddlewareFn,\n RequestData,\n ControllerArgs,\n LoaderResult,\n BridgeMessage,\n BridgeRequest,\n BridgeResponse,\n BridgeReady,\n BridgePush,\n BridgeElectronApi,\n SerializedError,\n ContextMenuContext,\n ContextMenuItem,\n ContextMenuEvent,\n} from './types';\n\n// Errors\nexport { WoodAuthError, WoodValidationError, BackendRestartingError } from './types/index.js';\n\n// Config\nexport { parseConfig } from './config/index.js';\n\n// Parsers\nexport { parseOperations, parseOperationsFile } from './parser/index.js';\nexport { parseViews, parseViewsFile } from './parser/index.js';\n\n// Router\nexport { WoodRouter } from './router/index.js';\n\n// Validation\nexport { SchemaValidator } from './validation/index.js';\n\n// Middleware\nexport { MiddlewareResolver, buildMiddlewareContext, executeMiddleware } from './middleware/index.js';\n\n// Controller\nexport { ControllerResolver, buildControllerArgs, disposeControllerLifecycle } from './controller/index.js';\nexport type { ControllerLifecycle } from './controller/index.js';\n\n// Codegen\nexport { generatePreload } from './codegen/index.js';\nexport { generateTypes } from './codegen/index.js';\nexport { generateChannelMap } from './codegen/index.js';\nexport { generateTestMock } from './codegen/index.js';\nexport { generateControllerRegistration } from './codegen/index.js';\nexport type { ControllerRegistrationOptions } from './codegen/index.js';\nexport { generateRuntime } from './codegen/index.js';\nexport type { RuntimeGeneratorOptions } from './codegen/index.js';\nexport { generateRendererViewManifest } from './codegen/index.js';\nexport type { RendererViewManifestGeneratorOptions } from './codegen/index.js';\nexport { generateRendererControllerRegistration } from './codegen/index.js';\nexport type { RendererControllerRegistrationOptions } from './codegen/index.js';\nexport { generateRendererApp } from './codegen/index.js';\nexport type { RendererAppGeneratorOptions } from './codegen/index.js';\n\n// Window\nexport { WindowManager, WindowStateStore } from './window/index.js';\nexport type { ScreenLike, WindowBounds } from './window/index.js';\n\n// Loader\nexport { LoaderRunner } from './loader/index.js';\n\n// Bridge\nexport { BackendBridge, startBackendLoop, pushEvent } from './bridge/index.js';\n\n// Dev metadata (lightweight; safe at runtime)\n// Heavy dev tooling (WoodDevServer, BackendWatcher, YamlWatcher,\n// EsbuildBackend) is available via the '@noego/wood/dev' subpath only,\n// so production consumers never load esbuild/chokidar.\nexport {\n DEFAULT_WOOD_REMOTE_DEBUGGING_PORT,\n WOOD_DEV_DIRECTORY,\n WOOD_DEV_METADATA_BASENAME,\n resolveWoodRemoteDebuggingPort,\n resolveWoodDevDirectory,\n resolveWoodDevMetadataPath,\n writeWoodDevMetadata,\n readWoodDevMetadata,\n removeWoodDevMetadata,\n} from './dev/dev_metadata.js';\nexport type { WoodDevMetadata } from './dev/dev_metadata.js';\n\n// Runtime\nexport {\n getContainer,\n clearContainerRegistryForTests,\n getApplicationRoot,\n setApplicationRoot,\n clearApplicationRootForTests,\n clearRendererTraceBatchReceiverForTests,\n getRendererTraceBatchReceiver,\n runtime,\n setRendererTraceBatchReceiver,\n} from './runtime/index.js';\nexport type {\n GetContainerOptions,\n RuntimeOptions,\n RuntimeResult,\n RegisterRuntimeRouter,\n} from './runtime';\n\n// Navigation\nexport { Navigation, getNavigation, go, goto, goback } from './navigation/index.js';\nexport type { NavigationEntry, NavigationOptions } from './navigation/index.js';\n\n// Isomorphic IPC API\nexport { Ipc, getIpc } from './ipc/index.js';\nexport type { IpcPushOptions } from './ipc/index.js';\n\n// Tracing\nexport {\n FrameworkTracer,\n MainTracer,\n RendererTracer,\n TestTracer,\n TraceProvider,\n TraceProviderConfiguration,\n TraceCommitWriter,\n clearTraceHubForTests,\n getTraceEvents$,\n registerTraceSink,\n setRendererTraceEnabled,\n setRendererTraceTransport,\n} from './tracing/index.js';\nexport type {\n TraceCommitRow,\n TraceCommitWriterOptions,\n TraceFlushOptions,\n TraceFlushResult,\n WoodTracePersistencePort,\n TraceDispatchResult,\n TraceEvent,\n TraceInput,\n TraceLevel,\n TraceProcess,\n TraceProviderMode,\n TraceRuntimeContext,\n TraceRuntime,\n TraceWaitOptions,\n WoodRendererTraceEvent,\n WoodRendererTraceInput,\n WoodTraceBatch,\n WoodTraceBatchAcknowledgement,\n WoodTraceBatchReceiver,\n WoodTraceBatchRuntimeContext,\n WoodTraceEventSink,\n WoodTraceEventSnapshot,\n WoodTraceSinkDisposer,\n} from './tracing/index.js';\n\n// Testing — available via '@noego/wood/testing' subpath export.\n// Not re-exported here to avoid pulling vitest into production builds.\n"],"mappings":"AAoCA,SAAS,eAAe,qBAAqB,8BAA8B;AAG3E,SAAS,mBAAmB;AAG5B,SAAS,iBAAiB,2BAA2B;AACrD,SAAS,YAAY,sBAAsB;AAG3C,SAAS,kBAAkB;AAG3B,SAAS,uBAAuB;AAGhC,SAAS,oBAAoB,wBAAwB,yBAAyB;AAG9E,SAAS,oBAAoB,qBAAqB,kCAAkC;AAIpF,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAC9B,SAAS,0BAA0B;AACnC,SAAS,wBAAwB;AACjC,SAAS,sCAAsC;AAE/C,SAAS,uBAAuB;AAEhC,SAAS,oCAAoC;AAE7C,SAAS,8CAA8C;AAEvD,SAAS,2BAA2B;AAIpC,SAAS,eAAe,wBAAwB;AAIhD,SAAS,oBAAoB;AAG7B,SAAS,eAAe,kBAAkB,iBAAiB;AAM3D;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAIP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASP,SAAS,YAAY,eAAe,IAAI,MAAM,cAAc;AAI5D,SAAS,KAAK,cAAc;AAI5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
@@ -28,7 +28,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var main_exports = {};
30
30
  __export(main_exports, {
31
+ BootstrapActivationGate: () => BootstrapActivationGate,
31
32
  resolveWoodDebugMetadataConfiguration: () => resolveWoodDebugMetadataConfiguration,
33
+ shouldDeferLastWindowCloseForCleanup: () => shouldDeferLastWindowCloseForCleanup,
32
34
  startWoodMain: () => startWoodMain
33
35
  });
34
36
  module.exports = __toCommonJS(main_exports);
@@ -43,6 +45,37 @@ var import_application_root = require("../runtime/application_root.js");
43
45
  var import_renderer_log_dispatcher = require("../runtime/renderer_log_dispatcher.js");
44
46
  var import_ipc = require("../ipc/index.js");
45
47
  var import_shared = require("../ipc/shared.js");
48
+ var import_renderer_trace_drain_coordinator = require("./renderer_trace_drain_coordinator.js");
49
+ class BootstrapActivationGate {
50
+ constructor(hasWindow, createMainWindow) {
51
+ this.hasWindow = hasWindow;
52
+ this.createMainWindow = createMainWindow;
53
+ this.currentState = "pending";
54
+ }
55
+ get state() {
56
+ return this.currentState;
57
+ }
58
+ activate() {
59
+ if (this.currentState === "ready" && !this.hasWindow()) {
60
+ this.createMainWindow();
61
+ }
62
+ }
63
+ ready() {
64
+ if (this.currentState !== "pending") {
65
+ return;
66
+ }
67
+ this.createMainWindow();
68
+ this.currentState = "ready";
69
+ }
70
+ failed() {
71
+ if (this.currentState === "pending") {
72
+ this.currentState = "failed";
73
+ }
74
+ }
75
+ }
76
+ function shouldDeferLastWindowCloseForCleanup(trackedWindowCount, cleanupComplete) {
77
+ return trackedWindowCount === 1 && !cleanupComplete;
78
+ }
46
79
  const DEFAULT_WOOD_REMOTE_DEBUGGING_PORT = 9333;
47
80
  function resolveWoodDebugMetadataConfiguration(env = process.env) {
48
81
  const isDevelopment = env.WOOD_MODE === "development";
@@ -83,11 +116,15 @@ function startWoodMain(options) {
83
116
  const debugConfig = resolveWoodDebugMetadataConfiguration();
84
117
  const windowState = new import_window_state_store.WindowStateStore();
85
118
  const windows = /* @__PURE__ */ new Map();
119
+ const rendererHealth = /* @__PURE__ */ new Map();
86
120
  let mainWindow = null;
87
121
  let beforeQuitCleanupComplete = false;
88
122
  let beforeQuitCleanupPromise = null;
89
123
  let runtimeContext = null;
90
124
  let mainBootCleanup;
125
+ let nativeQuitFallbackInstalled = false;
126
+ const rendererTraceDrain = new import_renderer_trace_drain_coordinator.RendererTraceDrainCoordinator(import_electron.ipcMain);
127
+ rendererTraceDrain.start();
91
128
  for (const stream of [process.stdout, process.stderr]) {
92
129
  stream.on("error", (error) => {
93
130
  if (error.code === "EPIPE") {
@@ -112,11 +149,12 @@ function startWoodMain(options) {
112
149
  protocol: import_electron.protocol,
113
150
  net: import_electron.net,
114
151
  shell: import_electron.shell,
115
- screen: import_electron.screen
152
+ screen: import_electron.screen,
153
+ Menu: import_electron.Menu
116
154
  },
117
155
  logger
118
156
  };
119
- void (async () => {
157
+ const initializeRuntime = async () => {
120
158
  const appBootResult = options.appBoot ? await options.appBoot(bootContext) : void 0;
121
159
  const bootOverrides = appBootResult ?? {};
122
160
  const scope = bootOverrides.scope ?? options.scope ?? process.cwd();
@@ -163,6 +201,129 @@ function startWoodMain(options) {
163
201
  }
164
202
  return null;
165
203
  };
204
+ const getRendererHealthState = (windowId) => {
205
+ return rendererHealth.get(windowId) ?? null;
206
+ };
207
+ const notifyRendererHealthChanged = (event) => {
208
+ if (!options.onRendererHealthChanged) {
209
+ return;
210
+ }
211
+ if (!runtimeContext) {
212
+ runtimeLogger.warn("renderer health hook skipped before runtime context", {
213
+ windowId: event.windowId,
214
+ state: event.state
215
+ });
216
+ return;
217
+ }
218
+ Promise.resolve(options.onRendererHealthChanged(event, runtimeContext)).catch((error) => {
219
+ runtimeLogger.warn("renderer health hook failed", {
220
+ windowId: event.windowId,
221
+ state: event.state,
222
+ error: toErrorMessage(error)
223
+ });
224
+ });
225
+ };
226
+ const setRendererHealth = (windowId, state, details = {}) => {
227
+ const previousState = rendererHealth.get(windowId) ?? null;
228
+ rendererHealth.set(windowId, state);
229
+ notifyRendererHealthChanged({
230
+ windowId,
231
+ state,
232
+ previousState,
233
+ ...details
234
+ });
235
+ };
236
+ const attachRendererHealth = (windowId, win) => {
237
+ const healthLogger = (0, import_logger.getLogger)("wood:main").named(`renderer-health:${windowId}`);
238
+ const webContentsId = win.webContents.id;
239
+ setRendererHealth(windowId, "loading", { webContentsId });
240
+ win.webContents.on("did-start-loading", () => {
241
+ setRendererHealth(windowId, "loading", { webContentsId });
242
+ healthLogger.info("renderer loading", { windowId, webContentsId });
243
+ });
244
+ win.webContents.on("did-finish-load", () => {
245
+ setRendererHealth(windowId, "ready", { webContentsId });
246
+ healthLogger.info("renderer ready", { windowId, webContentsId });
247
+ });
248
+ win.webContents.on("unresponsive", () => {
249
+ setRendererHealth(windowId, "unresponsive", { webContentsId });
250
+ healthLogger.error("renderer unresponsive", { windowId, webContentsId });
251
+ });
252
+ win.webContents.on("responsive", () => {
253
+ setRendererHealth(windowId, "ready", { webContentsId });
254
+ healthLogger.info("renderer responsive", { windowId, webContentsId });
255
+ });
256
+ win.webContents.on("render-process-gone", (_event, details) => {
257
+ setRendererHealth(windowId, "gone", {
258
+ webContentsId,
259
+ reason: details.reason,
260
+ exitCode: details.exitCode
261
+ });
262
+ healthLogger.error("renderer process gone", {
263
+ windowId,
264
+ webContentsId,
265
+ reason: details.reason,
266
+ exitCode: details.exitCode
267
+ });
268
+ });
269
+ win.webContents.on("destroyed", () => {
270
+ setRendererHealth(windowId, "destroyed");
271
+ healthLogger.warn("renderer destroyed", { windowId, webContentsId });
272
+ });
273
+ win.on("closed", () => {
274
+ setRendererHealth(windowId, "destroyed");
275
+ rendererHealth.delete(windowId);
276
+ });
277
+ };
278
+ const canSendToWindow = (win) => {
279
+ if (win.isDestroyed()) {
280
+ return false;
281
+ }
282
+ if (win.webContents.isDestroyed()) {
283
+ return false;
284
+ }
285
+ if (typeof win.webContents.isCrashed === "function" && win.webContents.isCrashed()) {
286
+ return false;
287
+ }
288
+ return true;
289
+ };
290
+ const safeSend = (windowId, win, channel, data) => {
291
+ if (!canSendToWindow(win)) {
292
+ runtimeLogger.warn("skipping send to unhealthy renderer", {
293
+ windowId,
294
+ channel,
295
+ rendererHealth: getRendererHealthState(windowId)
296
+ });
297
+ return false;
298
+ }
299
+ try {
300
+ win.webContents.send(channel, data);
301
+ return true;
302
+ } catch (error) {
303
+ runtimeLogger.warn("send to renderer failed", {
304
+ windowId,
305
+ channel,
306
+ rendererHealth: getRendererHealthState(windowId),
307
+ error: toErrorMessage(error)
308
+ });
309
+ return false;
310
+ }
311
+ };
312
+ const installNativeQuitFallback = () => {
313
+ if (nativeQuitFallbackInstalled) {
314
+ return;
315
+ }
316
+ import_electron.Menu.setApplicationMenu(import_electron.Menu.buildFromTemplate([
317
+ {
318
+ label: import_electron.app.name,
319
+ submenu: [
320
+ { role: "quit" }
321
+ ]
322
+ }
323
+ ]));
324
+ nativeQuitFallbackInstalled = true;
325
+ logger.info("native quit fallback installed");
326
+ };
166
327
  const waitForWindowReady = async (win) => {
167
328
  const webContents = win.webContents;
168
329
  const isLoading = typeof webContents.isLoadingMainFrame === "function" ? webContents.isLoadingMainFrame() : webContents.isLoading();
@@ -185,7 +346,8 @@ function startWoodMain(options) {
185
346
  title: win.getTitle(),
186
347
  webContentsId: win.webContents.id,
187
348
  url: win.webContents.getURL(),
188
- focused: win.isFocused()
349
+ focused: win.isFocused(),
350
+ rendererHealth: getRendererHealthState(windowId) ?? void 0
189
351
  });
190
352
  }
191
353
  return {
@@ -206,6 +368,9 @@ function startWoodMain(options) {
206
368
  const windowDef = resolveWindowDef(options.windowDefs, windowId);
207
369
  const defaultShow = windowDef.show ?? true;
208
370
  const parentWindow = windowDef.parent ? getWindow(windowDef.parent) : null;
371
+ if (windowDef.nativeQuitFallback === true) {
372
+ installNativeQuitFallback();
373
+ }
209
374
  windowState.setScreen(import_electron.screen);
210
375
  const savedBounds = windowDef.rememberBounds ? windowState.getBounds(windowId) : null;
211
376
  const windowOptions = {
@@ -232,6 +397,12 @@ function startWoodMain(options) {
232
397
  backgroundMaterial: windowDef.backgroundMaterial
233
398
  } : {},
234
399
  ...typeof windowDef.acceptFirstMouse === "boolean" ? { acceptFirstMouse: windowDef.acceptFirstMouse } : {},
400
+ // Hidden title bar with native window controls: macOS draws the
401
+ // traffic lights (positionable), Windows draws min/max/close via the
402
+ // Window Controls Overlay (always top-right; styled via titleBarOverlay).
403
+ ...typeof windowDef.titleBarStyle === "string" ? { titleBarStyle: windowDef.titleBarStyle } : {},
404
+ ...process.platform === "darwin" && windowDef.trafficLightPosition ? { trafficLightPosition: windowDef.trafficLightPosition } : {},
405
+ ...process.platform === "win32" && windowDef.titleBarOverlay != null ? { titleBarOverlay: windowDef.titleBarOverlay } : {},
235
406
  show: savedBounds ? false : defaultShow,
236
407
  webPreferences: {
237
408
  preload: preloadPath,
@@ -241,6 +412,7 @@ function startWoodMain(options) {
241
412
  };
242
413
  const win = new import_electron.BrowserWindow(windowOptions);
243
414
  windows.set(windowId, win);
415
+ attachRendererHealth(windowId, win);
244
416
  if (windowId === "main") {
245
417
  mainWindow = win;
246
418
  }
@@ -328,6 +500,7 @@ function startWoodMain(options) {
328
500
  }
329
501
  win.on("closed", () => {
330
502
  windows.delete(windowId);
503
+ rendererHealth.delete(windowId);
331
504
  if (windowId === "main") {
332
505
  mainWindow = null;
333
506
  }
@@ -335,13 +508,27 @@ function startWoodMain(options) {
335
508
  import_electron.app.quit();
336
509
  }
337
510
  });
511
+ if (options.onWindowCreated) {
512
+ Promise.resolve(options.onWindowCreated(windowId, win, runtimeContext)).catch((error) => {
513
+ runtimeLogger.warn("window created hook failed", {
514
+ windowId,
515
+ error: toErrorMessage(error)
516
+ });
517
+ });
518
+ }
338
519
  logger.info("window created", { windowId });
339
520
  return win;
340
521
  };
522
+ const bootstrapActivationGate = new BootstrapActivationGate(
523
+ () => import_electron.BrowserWindow.getAllWindows().length > 0,
524
+ () => {
525
+ createWindow("main");
526
+ }
527
+ );
341
528
  const navigateWindow = async (windowId, route) => {
342
529
  const win = createWindow(windowId);
343
530
  await waitForWindowReady(win);
344
- win.webContents.send("__event:__navigate", { route });
531
+ safeSend(windowId, win, "__event:__navigate", { route });
345
532
  win.show();
346
533
  win.focus();
347
534
  };
@@ -349,8 +536,8 @@ function startWoodMain(options) {
349
536
  const eventChannel = channel.startsWith("__event:") ? channel : `__event:${channel}`;
350
537
  if (options2?.windowId) {
351
538
  const target = getWindow(options2.windowId);
352
- if (target && !target.isDestroyed()) {
353
- target.webContents.send(eventChannel, data);
539
+ if (target) {
540
+ safeSend(options2.windowId, target, eventChannel, data);
354
541
  }
355
542
  return;
356
543
  }
@@ -359,7 +546,7 @@ function startWoodMain(options) {
359
546
  windows.delete(windowId);
360
547
  continue;
361
548
  }
362
- win.webContents.send(eventChannel, data);
549
+ safeSend(windowId, win, eventChannel, data);
363
550
  }
364
551
  };
365
552
  (0, import_shared.setIpcPushSender)(dispatchPushEvent);
@@ -369,7 +556,7 @@ function startWoodMain(options) {
369
556
  windows.delete(windowId);
370
557
  continue;
371
558
  }
372
- win.webContents.send(channel, data);
559
+ safeSend(windowId, win, channel, data);
373
560
  }
374
561
  };
375
562
  runtimeContext = {
@@ -380,11 +567,16 @@ function startWoodMain(options) {
380
567
  createWindow,
381
568
  navigateWindow,
382
569
  broadcast,
570
+ getRendererHealthState,
383
571
  setRendererLogCallback: (callback) => {
384
572
  (0, import_renderer_log_dispatcher.getRendererLogDispatcher)().setCallback(callback);
385
573
  },
386
574
  getRendererLogCallback: () => (0, import_renderer_log_dispatcher.getRendererLogDispatcher)().getCallback(),
387
- getDebugMetadata
575
+ getDebugMetadata,
576
+ // Late-bound after bootRuntime constructs the router (see bootstrap).
577
+ dispatch: async () => {
578
+ throw new Error("WoodMainRuntimeContext.dispatch called before the runtime router was constructed.");
579
+ }
388
580
  };
389
581
  const bootstrap = async () => {
390
582
  logger.info("bootstrap starting");
@@ -397,7 +589,7 @@ function startWoodMain(options) {
397
589
  mainBootCleanup = bootResult;
398
590
  }
399
591
  }
400
- await (0, import_runtime.runtime)({
592
+ const { router: runtimeRouter } = await (0, import_runtime.runtime)({
401
593
  container,
402
594
  ipcMain: import_electron.ipcMain,
403
595
  registerRuntime: options.registerRuntime,
@@ -493,67 +685,98 @@ function startWoodMain(options) {
493
685
  };
494
686
  }
495
687
  });
496
- createWindow("main");
688
+ runtimeContext.dispatch = (channel, payload) => runtimeRouter.dispatch(channel, payload ?? {});
689
+ bootstrapActivationGate.ready();
497
690
  logger.info("bootstrap complete");
498
691
  };
499
- void import_electron.app.whenReady().then(bootstrap).catch((error) => {
692
+ const handleBootstrapFailure = (error) => {
693
+ bootstrapActivationGate.failed();
500
694
  logger.error("bootstrap failed", {
501
695
  message: toErrorMessage(error),
502
696
  stack: error instanceof Error ? error.stack : void 0
503
697
  });
504
- });
505
- const destroyWindowsForQuit = () => {
506
- for (const [id, win] of windows) {
507
- if (!win.isDestroyed()) {
508
- win.destroy();
509
- logger.debug("destroyed window on quit", { windowId: id });
510
- }
511
- }
512
- windows.clear();
513
698
  };
514
- const runBeforeQuitCleanup = async () => {
515
- (0, import_shared.clearIpcPushSender)();
516
- if (mainBootCleanup) {
517
- await mainBootCleanup();
518
- }
519
- if (options.onBeforeQuit) {
520
- await options.onBeforeQuit(runtimeContext);
521
- }
522
- };
523
- import_electron.app.on("before-quit", (event) => {
524
- if (!runtimeContext) {
525
- return;
526
- }
527
- if (beforeQuitCleanupComplete) {
528
- destroyWindowsForQuit();
529
- return;
530
- }
531
- event.preventDefault();
532
- if (beforeQuitCleanupPromise) {
533
- return;
534
- }
535
- beforeQuitCleanupPromise = (async () => {
536
- try {
537
- await runBeforeQuitCleanup();
538
- } catch (error) {
539
- logger.warn("before-quit handler failed", { error: toErrorMessage(error) });
540
- } finally {
541
- beforeQuitCleanupComplete = true;
542
- beforeQuitCleanupPromise = null;
699
+ void import_electron.app.whenReady().then(bootstrap).catch(handleBootstrapFailure);
700
+ const registerApplicationLifecycle = () => {
701
+ import_electron.app.on(
702
+ "browser-window-created",
703
+ (_event, window) => {
704
+ window.on("close", (event) => {
705
+ const isTrackedWindow = [...windows.values()].includes(window);
706
+ if (!isTrackedWindow || !shouldDeferLastWindowCloseForCleanup(
707
+ windows.size,
708
+ beforeQuitCleanupComplete
709
+ )) {
710
+ return;
711
+ }
712
+ event.preventDefault();
713
+ if (!beforeQuitCleanupPromise) {
714
+ logger.debug("deferring last window close for renderer trace drain");
715
+ import_electron.app.quit();
716
+ }
717
+ });
543
718
  }
544
- destroyWindowsForQuit();
719
+ );
720
+ const destroyWindowsForQuit = () => {
721
+ for (const [id, win] of windows) {
722
+ if (!win.isDestroyed()) {
723
+ win.destroy();
724
+ logger.debug("destroyed window on quit", { windowId: id });
725
+ }
726
+ }
727
+ windows.clear();
728
+ };
729
+ const runBeforeQuitCleanup = async () => {
730
+ await (0, import_renderer_trace_drain_coordinator.drainRendererTracesBeforeQuit)(
731
+ rendererTraceDrain,
732
+ windows.values(),
733
+ logger,
734
+ Date.now() + 1e3
735
+ );
736
+ (0, import_shared.clearIpcPushSender)();
737
+ if (mainBootCleanup) {
738
+ await mainBootCleanup();
739
+ }
740
+ if (options.onBeforeQuit) {
741
+ await options.onBeforeQuit(runtimeContext);
742
+ }
743
+ };
744
+ import_electron.app.on("before-quit", (event) => {
745
+ if (!runtimeContext) {
746
+ return;
747
+ }
748
+ if (beforeQuitCleanupComplete) {
749
+ destroyWindowsForQuit();
750
+ return;
751
+ }
752
+ event.preventDefault();
753
+ if (beforeQuitCleanupPromise) {
754
+ return;
755
+ }
756
+ beforeQuitCleanupPromise = (async () => {
757
+ try {
758
+ await runBeforeQuitCleanup();
759
+ } catch (error) {
760
+ logger.warn("before-quit handler failed", { error: toErrorMessage(error) });
761
+ } finally {
762
+ beforeQuitCleanupComplete = true;
763
+ beforeQuitCleanupPromise = null;
764
+ }
765
+ destroyWindowsForQuit();
766
+ import_electron.app.quit();
767
+ })();
768
+ });
769
+ import_electron.app.on("window-all-closed", () => {
545
770
  import_electron.app.quit();
546
- })();
547
- });
548
- import_electron.app.on("window-all-closed", () => {
549
- import_electron.app.quit();
550
- });
551
- import_electron.app.on("activate", () => {
552
- if (import_electron.BrowserWindow.getAllWindows().length === 0) {
553
- createWindow("main");
554
- }
555
- });
556
- })().catch((error) => {
771
+ });
772
+ import_electron.app.on("activate", () => {
773
+ bootstrapActivationGate.activate();
774
+ });
775
+ };
776
+ registerApplicationLifecycle();
777
+ };
778
+ void initializeRuntime().catch((error) => {
779
+ rendererTraceDrain.stop();
557
780
  logger.error("startup failed before ready", {
558
781
  message: toErrorMessage(error),
559
782
  stack: error instanceof Error ? error.stack : void 0
@@ -562,7 +785,9 @@ function startWoodMain(options) {
562
785
  }
563
786
  // Annotate the CommonJS export names for ESM import in node:
564
787
  0 && (module.exports = {
788
+ BootstrapActivationGate,
565
789
  resolveWoodDebugMetadataConfiguration,
790
+ shouldDeferLastWindowCloseForCleanup,
566
791
  startWoodMain
567
792
  });
568
793
  //# sourceMappingURL=index.cjs.map