@furystack/shades 11.1.0 → 12.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/CHANGELOG.md +312 -0
  2. package/README.md +13 -13
  3. package/esm/component-factory.spec.js +13 -5
  4. package/esm/component-factory.spec.js.map +1 -1
  5. package/esm/components/index.d.ts +4 -1
  6. package/esm/components/index.d.ts.map +1 -1
  7. package/esm/components/index.js +4 -1
  8. package/esm/components/index.js.map +1 -1
  9. package/esm/components/lazy-load.d.ts +2 -4
  10. package/esm/components/lazy-load.d.ts.map +1 -1
  11. package/esm/components/lazy-load.js +40 -24
  12. package/esm/components/lazy-load.js.map +1 -1
  13. package/esm/components/lazy-load.spec.js +57 -50
  14. package/esm/components/lazy-load.spec.js.map +1 -1
  15. package/esm/components/link-to-route.d.ts +2 -0
  16. package/esm/components/link-to-route.d.ts.map +1 -1
  17. package/esm/components/link-to-route.js +3 -2
  18. package/esm/components/link-to-route.js.map +1 -1
  19. package/esm/components/link-to-route.spec.js +13 -9
  20. package/esm/components/link-to-route.spec.js.map +1 -1
  21. package/esm/components/nested-route-link.d.ts +62 -0
  22. package/esm/components/nested-route-link.d.ts.map +1 -0
  23. package/esm/components/nested-route-link.js +66 -0
  24. package/esm/components/nested-route-link.js.map +1 -0
  25. package/esm/components/nested-route-link.spec.d.ts +2 -0
  26. package/esm/components/nested-route-link.spec.d.ts.map +1 -0
  27. package/esm/components/nested-route-link.spec.js +179 -0
  28. package/esm/components/nested-route-link.spec.js.map +1 -0
  29. package/esm/components/nested-route-types.d.ts +37 -0
  30. package/esm/components/nested-route-types.d.ts.map +1 -0
  31. package/esm/components/nested-route-types.js +2 -0
  32. package/esm/components/nested-route-types.js.map +1 -0
  33. package/esm/components/nested-router.d.ts +103 -0
  34. package/esm/components/nested-router.d.ts.map +1 -0
  35. package/esm/components/nested-router.js +183 -0
  36. package/esm/components/nested-router.js.map +1 -0
  37. package/esm/components/nested-router.spec.d.ts +2 -0
  38. package/esm/components/nested-router.spec.d.ts.map +1 -0
  39. package/esm/components/nested-router.spec.js +737 -0
  40. package/esm/components/nested-router.spec.js.map +1 -0
  41. package/esm/components/route-link.d.ts +4 -0
  42. package/esm/components/route-link.d.ts.map +1 -1
  43. package/esm/components/route-link.js +5 -5
  44. package/esm/components/route-link.js.map +1 -1
  45. package/esm/components/route-link.spec.js +16 -12
  46. package/esm/components/route-link.spec.js.map +1 -1
  47. package/esm/components/router.d.ts +20 -2
  48. package/esm/components/router.d.ts.map +1 -1
  49. package/esm/components/router.js +12 -7
  50. package/esm/components/router.js.map +1 -1
  51. package/esm/components/router.spec.js +141 -74
  52. package/esm/components/router.spec.js.map +1 -1
  53. package/esm/initialize.d.ts +11 -0
  54. package/esm/initialize.d.ts.map +1 -1
  55. package/esm/initialize.js +5 -0
  56. package/esm/initialize.js.map +1 -1
  57. package/esm/jsx.d.ts +83 -2
  58. package/esm/jsx.d.ts.map +1 -1
  59. package/esm/models/children-list.d.ts +5 -1
  60. package/esm/models/children-list.d.ts.map +1 -1
  61. package/esm/models/partial-element.d.ts +12 -2
  62. package/esm/models/partial-element.d.ts.map +1 -1
  63. package/esm/models/render-options.d.ts +89 -3
  64. package/esm/models/render-options.d.ts.map +1 -1
  65. package/esm/models/selection-state.d.ts +4 -0
  66. package/esm/models/selection-state.d.ts.map +1 -1
  67. package/esm/services/location-service.d.ts +11 -0
  68. package/esm/services/location-service.d.ts.map +1 -1
  69. package/esm/services/location-service.js +11 -0
  70. package/esm/services/location-service.js.map +1 -1
  71. package/esm/services/resource-manager.d.ts +24 -0
  72. package/esm/services/resource-manager.d.ts.map +1 -1
  73. package/esm/services/resource-manager.js +36 -1
  74. package/esm/services/resource-manager.js.map +1 -1
  75. package/esm/services/resource-manager.spec.js +102 -0
  76. package/esm/services/resource-manager.spec.js.map +1 -1
  77. package/esm/services/screen-service.d.ts +81 -4
  78. package/esm/services/screen-service.d.ts.map +1 -1
  79. package/esm/services/screen-service.js +75 -4
  80. package/esm/services/screen-service.js.map +1 -1
  81. package/esm/services/screen-service.spec.js +91 -7
  82. package/esm/services/screen-service.spec.js.map +1 -1
  83. package/esm/shade-component.d.ts +17 -4
  84. package/esm/shade-component.d.ts.map +1 -1
  85. package/esm/shade-component.js +67 -5
  86. package/esm/shade-component.js.map +1 -1
  87. package/esm/shade-host-props-ref.integration.spec.d.ts +2 -0
  88. package/esm/shade-host-props-ref.integration.spec.d.ts.map +1 -0
  89. package/esm/shade-host-props-ref.integration.spec.js +381 -0
  90. package/esm/shade-host-props-ref.integration.spec.js.map +1 -0
  91. package/esm/shade-resources.integration.spec.js +208 -39
  92. package/esm/shade-resources.integration.spec.js.map +1 -1
  93. package/esm/shade.d.ts +20 -17
  94. package/esm/shade.d.ts.map +1 -1
  95. package/esm/shade.js +172 -33
  96. package/esm/shade.js.map +1 -1
  97. package/esm/shade.spec.js +31 -30
  98. package/esm/shade.spec.js.map +1 -1
  99. package/esm/shades.integration.spec.js +135 -72
  100. package/esm/shades.integration.spec.js.map +1 -1
  101. package/esm/style-manager.d.ts +2 -2
  102. package/esm/style-manager.js +2 -2
  103. package/esm/svg-types.d.ts +389 -0
  104. package/esm/svg-types.d.ts.map +1 -0
  105. package/esm/svg-types.js +9 -0
  106. package/esm/svg-types.js.map +1 -0
  107. package/esm/svg.d.ts +15 -0
  108. package/esm/svg.d.ts.map +1 -0
  109. package/esm/svg.js +76 -0
  110. package/esm/svg.js.map +1 -0
  111. package/esm/svg.spec.d.ts +2 -0
  112. package/esm/svg.spec.d.ts.map +1 -0
  113. package/esm/svg.spec.js +80 -0
  114. package/esm/svg.spec.js.map +1 -0
  115. package/esm/vnode.d.ts +103 -0
  116. package/esm/vnode.d.ts.map +1 -0
  117. package/esm/vnode.integration.spec.d.ts +2 -0
  118. package/esm/vnode.integration.spec.d.ts.map +1 -0
  119. package/esm/vnode.integration.spec.js +494 -0
  120. package/esm/vnode.integration.spec.js.map +1 -0
  121. package/esm/vnode.js +453 -0
  122. package/esm/vnode.js.map +1 -0
  123. package/esm/vnode.spec.d.ts +2 -0
  124. package/esm/vnode.spec.d.ts.map +1 -0
  125. package/esm/vnode.spec.js +473 -0
  126. package/esm/vnode.spec.js.map +1 -0
  127. package/package.json +8 -9
  128. package/src/component-factory.spec.tsx +18 -5
  129. package/src/components/index.ts +4 -1
  130. package/src/components/lazy-load.spec.tsx +82 -75
  131. package/src/components/lazy-load.tsx +49 -27
  132. package/src/components/link-to-route.spec.tsx +25 -21
  133. package/src/components/link-to-route.tsx +4 -2
  134. package/src/components/nested-route-link.spec.tsx +303 -0
  135. package/src/components/nested-route-link.tsx +100 -0
  136. package/src/components/nested-route-types.ts +42 -0
  137. package/src/components/nested-router.spec.tsx +918 -0
  138. package/src/components/nested-router.tsx +260 -0
  139. package/src/components/route-link.spec.tsx +22 -18
  140. package/src/components/route-link.tsx +6 -5
  141. package/src/components/router.spec.tsx +196 -108
  142. package/src/components/router.tsx +21 -8
  143. package/src/initialize.ts +12 -0
  144. package/src/jsx.ts +129 -2
  145. package/src/models/children-list.ts +7 -1
  146. package/src/models/partial-element.ts +13 -2
  147. package/src/models/render-options.ts +90 -3
  148. package/src/models/selection-state.ts +4 -0
  149. package/src/services/location-service.tsx +11 -0
  150. package/src/services/resource-manager.spec.ts +128 -0
  151. package/src/services/resource-manager.ts +36 -1
  152. package/src/services/screen-service.spec.ts +109 -7
  153. package/src/services/screen-service.ts +81 -4
  154. package/src/shade-component.ts +72 -6
  155. package/src/shade-host-props-ref.integration.spec.tsx +460 -0
  156. package/src/shade-resources.integration.spec.tsx +276 -52
  157. package/src/shade.spec.tsx +40 -39
  158. package/src/shade.ts +186 -58
  159. package/src/shades.integration.spec.tsx +154 -80
  160. package/src/style-manager.ts +2 -2
  161. package/src/svg-types.ts +437 -0
  162. package/src/svg.spec.ts +89 -0
  163. package/src/svg.ts +78 -0
  164. package/src/vnode.integration.spec.tsx +657 -0
  165. package/src/vnode.spec.ts +579 -0
  166. package/src/vnode.ts +508 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nested-route-types.js","sourceRoot":"","sources":["../../src/components/nested-route-types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,103 @@
1
+ import type { MatchOptions, MatchResult } from 'path-to-regexp';
2
+ import type { RenderOptions } from '../models/render-options.js';
3
+ /**
4
+ * A single route entry in a NestedRouter configuration.
5
+ * Unlike flat `Route`, the URL is the Record key (not a field), and the
6
+ * `component` receives an `outlet` for rendering matched child content.
7
+ * @typeParam TMatchResult - The type of matched URL parameters
8
+ */
9
+ export type NestedRoute<TMatchResult = unknown> = {
10
+ component: (options: {
11
+ currentUrl: string;
12
+ match: MatchResult<TMatchResult extends object ? TMatchResult : object>;
13
+ outlet?: JSX.Element;
14
+ }) => JSX.Element;
15
+ routingOptions?: MatchOptions;
16
+ onVisit?: (options: RenderOptions<unknown> & {
17
+ element: JSX.Element;
18
+ }) => Promise<void>;
19
+ onLeave?: (options: RenderOptions<unknown> & {
20
+ element: JSX.Element;
21
+ }) => Promise<void>;
22
+ children?: Record<string, NestedRoute<any>>;
23
+ };
24
+ /**
25
+ * Props for the NestedRouter component.
26
+ * Routes are defined as a Record where keys are URL patterns.
27
+ */
28
+ export type NestedRouterProps = {
29
+ routes: Record<string, NestedRoute<any>>;
30
+ notFound?: JSX.Element;
31
+ };
32
+ /**
33
+ * A single entry in a match chain, pairing a matched route with its match result.
34
+ */
35
+ export type MatchChainEntry = {
36
+ route: NestedRoute<unknown>;
37
+ match: MatchResult<object>;
38
+ };
39
+ /**
40
+ * Internal state for the NestedRouter component.
41
+ * `matchChain` is `null` when a notFound fallback has been rendered,
42
+ * distinguishing it from the initial empty array (not yet processed).
43
+ */
44
+ export type NestedRouterState = {
45
+ matchChain: MatchChainEntry[] | null;
46
+ jsx: JSX.Element;
47
+ chainElements: JSX.Element[];
48
+ };
49
+ /**
50
+ * Recursively builds a match chain from outermost to innermost matched route.
51
+ *
52
+ * For routes with children, a prefix match (`end: false`) is attempted first.
53
+ * If a child matches the remaining URL, the parent and child chain are combined.
54
+ * If no child matches, an exact match on the parent alone is attempted.
55
+ *
56
+ * For leaf routes (no children), only exact matching is used.
57
+ *
58
+ * @param routes - The route definitions to match against
59
+ * @param currentUrl - The URL path to match
60
+ * @returns An array of matched chain entries from outermost to innermost, or null if no match
61
+ */
62
+ export declare const buildMatchChain: (routes: Record<string, NestedRoute<any>>, currentUrl: string) => MatchChainEntry[] | null;
63
+ /**
64
+ * Finds the first index where two match chains diverge.
65
+ * Returns the length of the shorter chain if one is a prefix of the other.
66
+ */
67
+ export declare const findDivergenceIndex: (oldChain: MatchChainEntry[], newChain: MatchChainEntry[]) => number;
68
+ /**
69
+ * The result of rendering a match chain, containing both the fully composed
70
+ * JSX tree and per-entry elements for scoped lifecycle animations.
71
+ */
72
+ export type RenderMatchChainResult = {
73
+ jsx: JSX.Element;
74
+ chainElements: JSX.Element[];
75
+ };
76
+ /**
77
+ * Renders a match chain inside-out: starts with the innermost (leaf) route
78
+ * rendered with `outlet: undefined`, then passes its JSX as `outlet` to
79
+ * each successive parent up the chain.
80
+ *
81
+ * Returns per-entry elements so that lifecycle hooks (`onLeave`/`onVisit`)
82
+ * receive only the element for their own route level, not the full tree.
83
+ *
84
+ * @param chain - The match chain from outermost to innermost
85
+ * @param currentUrl - The current URL path
86
+ * @returns The fully composed JSX element and per-entry rendered elements
87
+ */
88
+ export declare const renderMatchChain: (chain: MatchChainEntry[], currentUrl: string) => RenderMatchChainResult;
89
+ /**
90
+ * A nested router component that supports hierarchical route definitions
91
+ * with parent/child relationships. Parent routes receive an `outlet` prop
92
+ * containing the rendered child route, enabling layout composition.
93
+ *
94
+ * Routes are defined as a Record where keys are URL patterns (following the
95
+ * RestApi pattern). The matching algorithm builds a chain from outermost to
96
+ * innermost route, then renders inside-out so each parent wraps its child.
97
+ */
98
+ export declare const NestedRouter: (props: NestedRouterProps & Omit<Partial<HTMLElement>, "style"> & {
99
+ style?: Partial<CSSStyleDeclaration>;
100
+ } & {
101
+ ref?: import("../models/render-options.js").RefObject<Element>;
102
+ }, children?: import("../index.js").ChildrenList) => JSX.Element;
103
+ //# sourceMappingURL=nested-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nested-router.d.ts","sourceRoot":"","sources":["../../src/components/nested-router.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAE/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAKhE;;;;;GAKG;AACH,MAAM,MAAM,WAAW,CAAC,YAAY,GAAG,OAAO,IAAI;IAChD,SAAS,EAAE,CAAC,OAAO,EAAE;QACnB,UAAU,EAAE,MAAM,CAAA;QAClB,KAAK,EAAE,WAAW,CAAC,YAAY,SAAS,MAAM,GAAG,YAAY,GAAG,MAAM,CAAC,CAAA;QACvE,MAAM,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;KACrB,KAAK,GAAG,CAAC,OAAO,CAAA;IACjB,cAAc,CAAC,EAAE,YAAY,CAAA;IAC7B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG;QAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvF,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG;QAAE,OAAO,EAAE,GAAG,CAAC,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACvF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAA;CAC5C,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,CAAA;IACxC,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CACvB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,CAAA;IAC3B,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAC3B,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,EAAE,eAAe,EAAE,GAAG,IAAI,CAAA;IACpC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAA;IAChB,aAAa,EAAE,GAAG,CAAC,OAAO,EAAE,CAAA;CAC7B,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,GAC1B,QAAQ,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,EACxC,YAAY,MAAM,KACjB,eAAe,EAAE,GAAG,IAuCtB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,eAAe,EAAE,EAAE,UAAU,eAAe,EAAE,KAAG,MAW9F,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAA;IAChB,aAAa,EAAE,GAAG,CAAC,OAAO,EAAE,CAAA;CAC7B,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,eAAe,EAAE,EAAE,YAAY,MAAM,KAAG,sBAe/E,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY;;;;gEAoFvB,CAAA"}
@@ -0,0 +1,183 @@
1
+ import { ObservableAlreadyDisposedError } from '@furystack/utils';
2
+ import { match } from 'path-to-regexp';
3
+ import { LocationService } from '../services/location-service.js';
4
+ import { createComponent, setRenderMode } from '../shade-component.js';
5
+ import { Shade } from '../shade.js';
6
+ /**
7
+ * Recursively builds a match chain from outermost to innermost matched route.
8
+ *
9
+ * For routes with children, a prefix match (`end: false`) is attempted first.
10
+ * If a child matches the remaining URL, the parent and child chain are combined.
11
+ * If no child matches, an exact match on the parent alone is attempted.
12
+ *
13
+ * For leaf routes (no children), only exact matching is used.
14
+ *
15
+ * @param routes - The route definitions to match against
16
+ * @param currentUrl - The URL path to match
17
+ * @returns An array of matched chain entries from outermost to innermost, or null if no match
18
+ */
19
+ export const buildMatchChain = (routes, currentUrl) => {
20
+ for (const [pattern, route] of Object.entries(routes)) {
21
+ if (route.children) {
22
+ const prefixMatchFn = match(pattern, { ...route.routingOptions, end: false });
23
+ let prefixResult = prefixMatchFn(currentUrl);
24
+ // In path-to-regexp v8, match('/', { end: false }) only matches exact '/'.
25
+ // For the root pattern, any URL is logically under '/', so force a prefix match.
26
+ if (!prefixResult && pattern === '/') {
27
+ prefixResult = { path: '/', params: {} };
28
+ }
29
+ if (prefixResult) {
30
+ let remainingUrl = currentUrl.slice(prefixResult.path.length);
31
+ if (!remainingUrl.startsWith('/')) {
32
+ remainingUrl = `/${remainingUrl}`;
33
+ }
34
+ const childChain = buildMatchChain(route.children, remainingUrl);
35
+ if (childChain) {
36
+ return [{ route, match: prefixResult }, ...childChain];
37
+ }
38
+ }
39
+ const exactMatchFn = match(pattern, route.routingOptions);
40
+ const exactResult = exactMatchFn(currentUrl);
41
+ if (exactResult) {
42
+ return [{ route, match: exactResult }];
43
+ }
44
+ }
45
+ else {
46
+ const matchFn = match(pattern, route.routingOptions);
47
+ const matchResult = matchFn(currentUrl);
48
+ if (matchResult) {
49
+ return [{ route, match: matchResult }];
50
+ }
51
+ }
52
+ }
53
+ return null;
54
+ };
55
+ /**
56
+ * Finds the first index where two match chains diverge.
57
+ * Returns the length of the shorter chain if one is a prefix of the other.
58
+ */
59
+ export const findDivergenceIndex = (oldChain, newChain) => {
60
+ const minLength = Math.min(oldChain.length, newChain.length);
61
+ for (let i = 0; i < minLength; i++) {
62
+ if (oldChain[i].route !== newChain[i].route ||
63
+ JSON.stringify(oldChain[i].match.params) !== JSON.stringify(newChain[i].match.params)) {
64
+ return i;
65
+ }
66
+ }
67
+ return minLength;
68
+ };
69
+ /**
70
+ * Renders a match chain inside-out: starts with the innermost (leaf) route
71
+ * rendered with `outlet: undefined`, then passes its JSX as `outlet` to
72
+ * each successive parent up the chain.
73
+ *
74
+ * Returns per-entry elements so that lifecycle hooks (`onLeave`/`onVisit`)
75
+ * receive only the element for their own route level, not the full tree.
76
+ *
77
+ * @param chain - The match chain from outermost to innermost
78
+ * @param currentUrl - The current URL path
79
+ * @returns The fully composed JSX element and per-entry rendered elements
80
+ */
81
+ export const renderMatchChain = (chain, currentUrl) => {
82
+ let outlet;
83
+ const chainElements = new Array(chain.length);
84
+ for (let i = chain.length - 1; i >= 0; i--) {
85
+ const entry = chain[i];
86
+ outlet = entry.route.component({
87
+ currentUrl,
88
+ match: entry.match,
89
+ outlet,
90
+ });
91
+ chainElements[i] = outlet;
92
+ }
93
+ return { jsx: outlet, chainElements };
94
+ };
95
+ /**
96
+ * A nested router component that supports hierarchical route definitions
97
+ * with parent/child relationships. Parent routes receive an `outlet` prop
98
+ * containing the rendered child route, enabling layout composition.
99
+ *
100
+ * Routes are defined as a Record where keys are URL patterns (following the
101
+ * RestApi pattern). The matching algorithm builds a chain from outermost to
102
+ * innermost route, then renders inside-out so each parent wraps its child.
103
+ */
104
+ export const NestedRouter = Shade({
105
+ shadowDomName: 'shade-nested-router',
106
+ render: (options) => {
107
+ const { useState, useObservable, injector } = options;
108
+ const [versionRef] = useState('navVersion', { current: 0 });
109
+ const [state, setState] = useState('routerState', {
110
+ matchChain: [],
111
+ jsx: createComponent("div", null),
112
+ chainElements: [],
113
+ });
114
+ const updateUrl = async (currentUrl) => {
115
+ const [lastState] = useState('routerState', state);
116
+ const { matchChain: lastChain, chainElements: lastChainElements } = lastState;
117
+ try {
118
+ const newChain = buildMatchChain(options.props.routes, currentUrl);
119
+ if (newChain) {
120
+ const lastChainEntries = lastChain ?? [];
121
+ const divergeIndex = findDivergenceIndex(lastChainEntries, newChain);
122
+ const hasChanged = divergeIndex < lastChainEntries.length ||
123
+ divergeIndex < newChain.length ||
124
+ lastChainEntries.length !== newChain.length;
125
+ if (hasChanged) {
126
+ const version = ++versionRef.current;
127
+ // Call onLeave for routes that are being left (from divergence point to end of old chain)
128
+ for (let i = lastChainEntries.length - 1; i >= divergeIndex; i--) {
129
+ await lastChainEntries[i].route.onLeave?.({ ...options, element: lastChainElements[i] });
130
+ if (version !== versionRef.current)
131
+ return;
132
+ }
133
+ let newResult;
134
+ setRenderMode(true);
135
+ try {
136
+ newResult = renderMatchChain(newChain, currentUrl);
137
+ }
138
+ finally {
139
+ setRenderMode(false);
140
+ }
141
+ if (version !== versionRef.current)
142
+ return;
143
+ setState({ matchChain: newChain, jsx: newResult.jsx, chainElements: newResult.chainElements });
144
+ // Call onVisit for routes that are being entered (from divergence point to end of new chain)
145
+ for (let i = divergeIndex; i < newChain.length; i++) {
146
+ await newChain[i].route.onVisit?.({ ...options, element: newResult.chainElements[i] });
147
+ if (version !== versionRef.current)
148
+ return;
149
+ }
150
+ }
151
+ }
152
+ else if (lastChain !== null) {
153
+ const version = ++versionRef.current;
154
+ // No match found — call onLeave for all active routes and show notFound.
155
+ // The null sentinel prevents re-entering this block on re-render.
156
+ for (let i = (lastChain?.length ?? 0) - 1; i >= 0; i--) {
157
+ await lastChain[i].route.onLeave?.({ ...options, element: lastChainElements[i] });
158
+ if (version !== versionRef.current)
159
+ return;
160
+ }
161
+ setState({
162
+ matchChain: null,
163
+ jsx: options.props.notFound || createComponent("div", null),
164
+ chainElements: [],
165
+ });
166
+ }
167
+ }
168
+ catch (e) {
169
+ if (!(e instanceof ObservableAlreadyDisposedError)) {
170
+ throw e;
171
+ }
172
+ }
173
+ };
174
+ const [locationPath] = useObservable('locationPathChanged', injector.getInstance(LocationService).onLocationPathChanged, {
175
+ onChange: (newValue) => {
176
+ void updateUrl(newValue);
177
+ },
178
+ });
179
+ void updateUrl(locationPath);
180
+ return state.jsx;
181
+ },
182
+ });
183
+ //# sourceMappingURL=nested-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nested-router.js","sourceRoot":"","sources":["../../src/components/nested-router.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=nested-router.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nested-router.spec.d.ts","sourceRoot":"","sources":["../../src/components/nested-router.spec.tsx"],"names":[],"mappings":""}