@noego/wood 0.4.6 → 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 (241) hide show
  1. package/bin/wood.js +6 -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 +6 -1
  61. package/dist/codegen/type_generator.cjs.map +1 -1
  62. package/dist/codegen/type_generator.js +6 -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 +133 -55
  71. package/dist/main/index.cjs.map +1 -1
  72. package/dist/main/index.d.cts +30 -2
  73. package/dist/main/index.d.ts +30 -2
  74. package/dist/main/index.js +134 -55
  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/docs/browser-testing.md +139 -1
  239. package/package.json +22 -3
  240. package/src/components/NavigationShell.browser.test.ts +236 -0
  241. package/src/components/NavigationShell.svelte +162 -49
@@ -1,9 +1,10 @@
1
1
  <script lang="ts">
2
2
  import { setContext, onDestroy } from 'svelte';
3
- import { getNavigation } from '@noego/wood/navigation';
3
+ import { getNavigation, type NavigationEntry } from '@noego/wood/navigation';
4
4
  import { disposeControllerLifecycle } from '../controller/controller_lifecycle';
5
5
  import { createNavigationMountKey } from '../navigation/navigation_identity';
6
6
  import WoodRecursiveRender from './WoodRecursiveRender.svelte';
7
+ import { getWoodAppEnv } from '../client/app_env';
7
8
 
8
9
  type ViewManifestEntry = {
9
10
  key: string;
@@ -74,6 +75,8 @@
74
75
  createLayoutMountKey(getInitialEntry(), index, activePageKey),
75
76
  ),
76
77
  );
78
+ let navigationTransitionQueue: Promise<void> = Promise.resolve();
79
+ let destroyed = false;
77
80
 
78
81
  let activePage = $derived({
79
82
  key: activeEntry.key,
@@ -84,6 +87,7 @@
84
87
  });
85
88
 
86
89
  const navigation = getNavigation();
90
+ const appEnv = getWoodAppEnv();
87
91
 
88
92
  function getWoodBridge(): WoodBridgeLike | null {
89
93
  if (typeof window === 'undefined') {
@@ -202,20 +206,74 @@
202
206
  return depth;
203
207
  }
204
208
 
209
+ async function disposeControllerSet(
210
+ controller: unknown,
211
+ layoutControllers: Array<unknown>,
212
+ fromLayoutIndex = 0,
213
+ ): Promise<void> {
214
+ await disposeControllerLifecycle(controller);
215
+ for (let index = fromLayoutIndex; index < layoutControllers.length; index += 1) {
216
+ await disposeControllerLifecycle(layoutControllers[index]);
217
+ }
218
+ }
219
+
205
220
  async function disposeActiveControllers(): Promise<void> {
206
- await disposeControllerLifecycle(activeController);
207
- for (const layoutController of activeLayoutControllers) {
221
+ await disposeControllerSet(activeController, activeLayoutControllers);
222
+ }
223
+
224
+ async function disposeLayoutControllers(layoutControllers: Array<unknown>): Promise<void> {
225
+ for (const layoutController of layoutControllers) {
208
226
  await disposeControllerLifecycle(layoutController);
209
227
  }
210
228
  }
211
229
 
212
- async function disposeChangedControllers(fromLayoutIndex: number): Promise<void> {
213
- await disposeControllerLifecycle(activeController);
214
- for (let index = fromLayoutIndex; index < activeLayoutControllers.length; index += 1) {
215
- await disposeControllerLifecycle(activeLayoutControllers[index]);
230
+ function reportNavigationError(context: string, error: unknown): void {
231
+ const message = error instanceof Error ? error.message : String(error);
232
+ console.error(`[wood] ${context}: ${message}`);
233
+ }
234
+
235
+ async function disposeStagedControllers(
236
+ controller: unknown,
237
+ layoutControllers: Array<unknown>,
238
+ ): Promise<void> {
239
+ const cleanupResults = await Promise.allSettled([
240
+ disposeControllerLifecycle(controller),
241
+ disposeLayoutControllers(layoutControllers),
242
+ ]);
243
+ for (const result of cleanupResults) {
244
+ if (result.status === 'rejected') {
245
+ reportNavigationError('navigation transition cleanup failed', result.reason);
246
+ }
216
247
  }
217
248
  }
218
249
 
250
+ async function createTransitionControllers(
251
+ entry: ViewManifestEntry,
252
+ preservedDepth: number,
253
+ ): Promise<{ controller: unknown; layoutControllers: Array<unknown> }> {
254
+ const [controllerResult, layoutControllersResult] = await Promise.allSettled([
255
+ createViewControllerFn(entry),
256
+ createLayoutControllersFn(entry, preservedDepth),
257
+ ]);
258
+
259
+ if (controllerResult.status === 'fulfilled' && layoutControllersResult.status === 'fulfilled') {
260
+ return {
261
+ controller: controllerResult.value,
262
+ layoutControllers: layoutControllersResult.value,
263
+ };
264
+ }
265
+
266
+ await disposeStagedControllers(
267
+ controllerResult.status === 'fulfilled' ? controllerResult.value : undefined,
268
+ layoutControllersResult.status === 'fulfilled' ? layoutControllersResult.value : [],
269
+ );
270
+
271
+ if (controllerResult.status === 'rejected') {
272
+ throw controllerResult.reason;
273
+ }
274
+ throw layoutControllersResult.reason;
275
+ }
276
+
219
277
  function mergeLayoutControllers(
220
278
  preservedDepth: number,
221
279
  createdControllers: Array<unknown>,
@@ -230,14 +288,69 @@
230
288
  return merged;
231
289
  }
232
290
 
291
+ async function applyNavigationEntry(navEntry: NavigationEntry | null): Promise<void> {
292
+ if (destroyed || !navEntry) return;
293
+
294
+ const newKey = navEntry.page;
295
+ const entry = getViewManifestEntryFn(newKey);
296
+ if (!entry) return;
297
+
298
+ const nextPageKey = createNavigationMountKey(newKey, navEntry.params);
299
+
300
+ if (nextPageKey === activePageKey) {
301
+ activeParams = { ...navEntry.params };
302
+ activeQuery = { ...navEntry.query };
303
+ return;
304
+ }
305
+
306
+ const preservedDepth = computePreservedLayoutDepth(
307
+ activeEntry,
308
+ entry,
309
+ navEntry.options ?? {},
310
+ );
311
+ const preservedLayoutKeys = activeLayoutKeys.slice(0, preservedDepth);
312
+ const previousController = activeController;
313
+ const previousLayoutControllers = [...activeLayoutControllers];
314
+ const { controller, layoutControllers } = await createTransitionControllers(entry, preservedDepth);
315
+
316
+ if (destroyed) {
317
+ await disposeStagedControllers(controller, layoutControllers);
318
+ return;
319
+ }
320
+
321
+ const nextLayoutControllers = mergeLayoutControllers(
322
+ preservedDepth,
323
+ layoutControllers,
324
+ entry.layoutPaths.length,
325
+ );
326
+ const nextLayoutKeys = createLayoutMountKeys(entry, nextPageKey, preservedLayoutKeys);
327
+
328
+ activeEntry = entry;
329
+ activeController = controller;
330
+ activeLayoutControllers = nextLayoutControllers;
331
+ activeParams = { ...navEntry.params };
332
+ activeQuery = { ...navEntry.query };
333
+ activePageKey = nextPageKey;
334
+ activeLayoutKeys = nextLayoutKeys;
335
+
336
+ await disposeControllerSet(previousController, previousLayoutControllers, preservedDepth);
337
+ }
338
+
339
+ function enqueueNavigationEntry(navEntry: NavigationEntry | null): void {
340
+ navigationTransitionQueue = navigationTransitionQueue
341
+ .then(() => applyNavigationEntry(navEntry))
342
+ .catch((error: unknown) => {
343
+ reportNavigationError('navigation transition failed', error);
344
+ });
345
+ }
346
+
233
347
  setContext('wood:navigate', (
234
348
  viewKey: string,
235
349
  params?: Record<string, unknown>,
236
350
  options?: { replace?: boolean; preserveLayouts?: boolean },
237
351
  ) => {
238
352
  void navigateWithinCurrentWindow(viewKey, params, options).catch((error) => {
239
- const message = error instanceof Error ? error.message : String(error);
240
- console.error(`[wood] navigation failed: ${message}`);
353
+ reportNavigationError('navigation failed', error);
241
354
  });
242
355
  });
243
356
 
@@ -256,7 +369,7 @@
256
369
 
257
370
  let initialFire = true;
258
371
 
259
- const unsubscribe = navigation.subscribe(async (navEntry) => {
372
+ const unsubscribe = navigation.subscribe((navEntry) => {
260
373
  if (initialFire) {
261
374
  initialFire = false;
262
375
  if (navEntry) {
@@ -268,44 +381,7 @@
268
381
  return;
269
382
  }
270
383
 
271
- if (!navEntry) return;
272
-
273
- const newKey = navEntry.page;
274
- const entry = getViewManifestEntryFn(newKey);
275
- if (!entry) return;
276
-
277
- const nextPageKey = createNavigationMountKey(newKey, navEntry.params);
278
-
279
- if (nextPageKey === activePageKey) {
280
- activeParams = { ...navEntry.params };
281
- activeQuery = { ...navEntry.query };
282
- return;
283
- }
284
-
285
- const preservedDepth = computePreservedLayoutDepth(
286
- activeEntry,
287
- entry,
288
- navEntry.options ?? {},
289
- );
290
- const preservedLayoutKeys = activeLayoutKeys.slice(0, preservedDepth);
291
-
292
- await disposeChangedControllers(preservedDepth);
293
- const [controller, layoutControllers] = await Promise.all([
294
- createViewControllerFn(entry),
295
- createLayoutControllersFn(entry, preservedDepth),
296
- ]);
297
-
298
- activeEntry = entry;
299
- activeController = controller;
300
- activeLayoutControllers = mergeLayoutControllers(
301
- preservedDepth,
302
- layoutControllers,
303
- entry.layoutPaths.length,
304
- );
305
- activeParams = { ...navEntry.params };
306
- activeQuery = { ...navEntry.query };
307
- activePageKey = nextPageKey;
308
- activeLayoutKeys = createLayoutMountKeys(entry, nextPageKey, preservedLayoutKeys);
384
+ enqueueNavigationEntry(navEntry);
309
385
  });
310
386
 
311
387
  const bridge = getWoodBridge();
@@ -328,9 +404,14 @@
328
404
  });
329
405
 
330
406
  onDestroy(() => {
407
+ destroyed = true;
331
408
  unsubscribe();
332
409
  unsubscribeWindowNavigate?.();
333
- void disposeActiveControllers();
410
+ void navigationTransitionQueue
411
+ .then(() => disposeActiveControllers())
412
+ .catch((error: unknown) => {
413
+ reportNavigationError('navigation teardown failed', error);
414
+ });
334
415
  });
335
416
  </script>
336
417
 
@@ -345,3 +426,35 @@
345
426
  query={activeQuery}
346
427
  page={activePage}
347
428
  />
429
+
430
+ {#if appEnv !== 'packaged'}
431
+ <div class="wood-env-ribbon" class:wood-env-ribbon--local={appEnv === 'local'} aria-hidden="true">
432
+ {appEnv === 'dev' ? 'DEBUG' : 'LOCAL'}
433
+ </div>
434
+ {/if}
435
+
436
+ <style>
437
+ .wood-env-ribbon {
438
+ position: absolute;
439
+ top: 22px;
440
+ right: -34px;
441
+ z-index: 2147483647;
442
+ pointer-events: none;
443
+ transform: rotate(45deg);
444
+ width: 140px;
445
+ text-align: center;
446
+ padding: 3px 0;
447
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
448
+ font-size: 11px;
449
+ font-weight: 700;
450
+ letter-spacing: 2px;
451
+ color: #fff;
452
+ background: #b71c1c;
453
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
454
+ user-select: none;
455
+ }
456
+
457
+ .wood-env-ribbon--local {
458
+ background: #1b7f3a;
459
+ }
460
+ </style>