@furystack/shades 13.2.1 → 14.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/CHANGELOG.md +150 -0
  2. package/esm/components/define-nested-routes.d.ts +27 -0
  3. package/esm/components/define-nested-routes.d.ts.map +1 -0
  4. package/esm/components/define-nested-routes.js +26 -0
  5. package/esm/components/define-nested-routes.js.map +1 -0
  6. package/esm/components/define-nested-routes.spec.d.ts +2 -0
  7. package/esm/components/define-nested-routes.spec.d.ts.map +1 -0
  8. package/esm/components/define-nested-routes.spec.js +81 -0
  9. package/esm/components/define-nested-routes.spec.js.map +1 -0
  10. package/esm/components/index.d.ts +3 -3
  11. package/esm/components/index.d.ts.map +1 -1
  12. package/esm/components/index.js +3 -3
  13. package/esm/components/index.js.map +1 -1
  14. package/esm/components/nested-hooks.d.ts +62 -0
  15. package/esm/components/nested-hooks.d.ts.map +1 -0
  16. package/esm/components/nested-hooks.js +73 -0
  17. package/esm/components/nested-hooks.js.map +1 -0
  18. package/esm/components/nested-hooks.spec.d.ts +2 -0
  19. package/esm/components/nested-hooks.spec.d.ts.map +1 -0
  20. package/esm/components/nested-hooks.spec.js +211 -0
  21. package/esm/components/nested-hooks.spec.js.map +1 -0
  22. package/esm/components/nested-navigate.d.ts +52 -21
  23. package/esm/components/nested-navigate.d.ts.map +1 -1
  24. package/esm/components/nested-navigate.js +32 -17
  25. package/esm/components/nested-navigate.js.map +1 -1
  26. package/esm/components/nested-navigate.spec.js +102 -12
  27. package/esm/components/nested-navigate.spec.js.map +1 -1
  28. package/esm/components/nested-replace.d.ts +36 -0
  29. package/esm/components/nested-replace.d.ts.map +1 -0
  30. package/esm/components/nested-replace.js +38 -0
  31. package/esm/components/nested-replace.js.map +1 -0
  32. package/esm/components/nested-replace.spec.d.ts +2 -0
  33. package/esm/components/nested-replace.spec.d.ts.map +1 -0
  34. package/esm/components/nested-replace.spec.js +59 -0
  35. package/esm/components/nested-replace.spec.js.map +1 -0
  36. package/esm/components/nested-route-link.d.ts +36 -26
  37. package/esm/components/nested-route-link.d.ts.map +1 -1
  38. package/esm/components/nested-route-link.js +17 -19
  39. package/esm/components/nested-route-link.js.map +1 -1
  40. package/esm/components/nested-route-link.spec.js +61 -11
  41. package/esm/components/nested-route-link.spec.js.map +1 -1
  42. package/esm/components/nested-route-types.d.ts +79 -2
  43. package/esm/components/nested-route-types.d.ts.map +1 -1
  44. package/esm/components/nested-router.d.ts +77 -7
  45. package/esm/components/nested-router.d.ts.map +1 -1
  46. package/esm/components/nested-router.js +137 -11
  47. package/esm/components/nested-router.js.map +1 -1
  48. package/esm/components/nested-router.spec.js +265 -34
  49. package/esm/components/nested-router.spec.js.map +1 -1
  50. package/esm/services/location-service.spec.js +33 -0
  51. package/esm/services/location-service.spec.js.map +1 -1
  52. package/esm/services/route-match-service.spec.js +4 -0
  53. package/esm/services/route-match-service.spec.js.map +1 -1
  54. package/esm/services/route-meta-utils.d.ts +28 -6
  55. package/esm/services/route-meta-utils.d.ts.map +1 -1
  56. package/esm/services/route-meta-utils.js +18 -4
  57. package/esm/services/route-meta-utils.js.map +1 -1
  58. package/esm/services/route-meta-utils.spec.js +57 -2
  59. package/esm/services/route-meta-utils.spec.js.map +1 -1
  60. package/esm/vnode.d.ts +1 -1
  61. package/esm/vnode.js +1 -1
  62. package/package.json +9 -9
  63. package/src/components/define-nested-routes.spec.ts +91 -0
  64. package/src/components/define-nested-routes.ts +27 -0
  65. package/src/components/index.ts +3 -3
  66. package/src/components/nested-hooks.spec.ts +254 -0
  67. package/src/components/nested-hooks.ts +109 -0
  68. package/src/components/nested-navigate.spec.ts +128 -25
  69. package/src/components/nested-navigate.ts +75 -26
  70. package/src/components/nested-replace.spec.ts +88 -0
  71. package/src/components/nested-replace.ts +46 -0
  72. package/src/components/nested-route-link.spec.tsx +84 -16
  73. package/src/components/nested-route-link.tsx +53 -28
  74. package/src/components/nested-route-types.ts +82 -2
  75. package/src/components/nested-router.spec.tsx +316 -33
  76. package/src/components/nested-router.tsx +182 -22
  77. package/src/services/location-service.spec.ts +39 -0
  78. package/src/services/route-match-service.spec.ts +4 -0
  79. package/src/services/route-meta-utils.spec.ts +75 -7
  80. package/src/services/route-meta-utils.ts +44 -15
  81. package/src/vnode.ts +1 -1
  82. package/esm/components/link-to-route.d.ts +0 -10
  83. package/esm/components/link-to-route.d.ts.map +0 -1
  84. package/esm/components/link-to-route.js +0 -16
  85. package/esm/components/link-to-route.js.map +0 -1
  86. package/esm/components/link-to-route.spec.d.ts +0 -2
  87. package/esm/components/link-to-route.spec.d.ts.map +0 -1
  88. package/esm/components/link-to-route.spec.js +0 -30
  89. package/esm/components/link-to-route.spec.js.map +0 -1
  90. package/esm/components/route-link.d.ts +0 -10
  91. package/esm/components/route-link.d.ts.map +0 -1
  92. package/esm/components/route-link.js +0 -25
  93. package/esm/components/route-link.js.map +0 -1
  94. package/esm/components/route-link.spec.d.ts +0 -2
  95. package/esm/components/route-link.spec.d.ts.map +0 -1
  96. package/esm/components/route-link.spec.js +0 -34
  97. package/esm/components/route-link.spec.js.map +0 -1
  98. package/esm/components/router.d.ts +0 -44
  99. package/esm/components/router.d.ts.map +0 -1
  100. package/esm/components/router.js +0 -66
  101. package/esm/components/router.js.map +0 -1
  102. package/esm/components/router.spec.d.ts +0 -2
  103. package/esm/components/router.spec.d.ts.map +0 -1
  104. package/esm/components/router.spec.js +0 -161
  105. package/esm/components/router.spec.js.map +0 -1
  106. package/src/components/link-to-route.spec.tsx +0 -45
  107. package/src/components/link-to-route.tsx +0 -26
  108. package/src/components/route-link.spec.tsx +0 -44
  109. package/src/components/route-link.tsx +0 -29
  110. package/src/components/router.spec.tsx +0 -217
  111. package/src/components/router.tsx +0 -103
@@ -1 +1 @@
1
- {"version":3,"file":"route-meta-utils.spec.js","sourceRoot":"","sources":["../../src/services/route-meta-utils.spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"route-meta-utils.spec.js","sourceRoot":"","sources":["../../src/services/route-meta-utils.spec.ts"],"names":[],"mappings":"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"}
package/esm/vnode.d.ts CHANGED
@@ -69,7 +69,7 @@ export declare const shallowEqual: (a: Record<string, unknown>, b: Record<string
69
69
  * VChild array suitable for `patchChildren`.
70
70
  *
71
71
  * Real DOM elements can appear here when component state stores elements created
72
- * outside renderMode (e.g. in async callbacks like Router's `updateUrl`).
72
+ * outside renderMode (e.g. in async callbacks like NestedRouter's `updateUrl`).
73
73
  */
74
74
  export declare const toVChildArray: (renderResult: unknown) => VChild[];
75
75
  /**
package/esm/vnode.js CHANGED
@@ -141,7 +141,7 @@ export const shallowEqual = (a, b) => {
141
141
  * VChild array suitable for `patchChildren`.
142
142
  *
143
143
  * Real DOM elements can appear here when component state stores elements created
144
- * outside renderMode (e.g. in async callbacks like Router's `updateUrl`).
144
+ * outside renderMode (e.g. in async callbacks like NestedRouter's `updateUrl`).
145
145
  */
146
146
  export const toVChildArray = (renderResult) => {
147
147
  if (renderResult === null || renderResult === undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@furystack/shades",
3
- "version": "13.2.1",
3
+ "version": "14.0.0",
4
4
  "description": "A lightweight UI framework for FuryStack with JSX support",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -40,16 +40,16 @@
40
40
  "homepage": "https://github.com/furystack/furystack",
41
41
  "devDependencies": {
42
42
  "@types/jsdom": "^28.0.1",
43
- "@types/node": "^25.5.0",
44
- "jsdom": "^29.0.1",
45
- "typescript": "^6.0.2",
46
- "vitest": "^4.1.2"
43
+ "@types/node": "^25.6.0",
44
+ "jsdom": "^29.0.2",
45
+ "typescript": "^6.0.3",
46
+ "vitest": "^4.1.4"
47
47
  },
48
48
  "dependencies": {
49
- "@furystack/inject": "^12.0.35",
50
- "@furystack/rest": "^8.1.4",
51
- "@furystack/utils": "^8.2.4",
52
- "path-to-regexp": "^8.4.0"
49
+ "@furystack/inject": "^12.0.36",
50
+ "@furystack/rest": "^9.0.0",
51
+ "@furystack/utils": "^8.2.5",
52
+ "path-to-regexp": "^8.4.2"
53
53
  },
54
54
  "engines": {
55
55
  "node": ">=22.0.0"
@@ -0,0 +1,91 @@
1
+ import { describe, expect, expectTypeOf, it } from 'vitest'
2
+ import { defineNestedRoutes } from './define-nested-routes.js'
3
+
4
+ const makeComponent = () => null as unknown as JSX.Element
5
+
6
+ describe('defineNestedRoutes', () => {
7
+ it('Should return the same object reference at runtime', () => {
8
+ const input = {
9
+ '/tabs': {
10
+ component: () => makeComponent(),
11
+ hash: ['a', 'b'] as const,
12
+ },
13
+ }
14
+ const result = defineNestedRoutes(input)
15
+ expect(result).toBe(input)
16
+ })
17
+
18
+ it('Should accept values that satisfy Record<string, NestedRoute<...>>', () => {
19
+ const routes = defineNestedRoutes({
20
+ '/bare': { component: () => makeComponent() },
21
+ '/tabs': {
22
+ component: () => makeComponent(),
23
+ hash: ['a', 'b'] as const,
24
+ query: (raw): { page: number } | null => (typeof raw.page === 'number' ? { page: raw.page } : null),
25
+ },
26
+ })
27
+ expect(Object.keys(routes)).toEqual(['/bare', '/tabs'])
28
+ })
29
+
30
+ describe('Type preservation', () => {
31
+ it('Should preserve `hash` as a readonly tuple of literal values', () => {
32
+ const routes = defineNestedRoutes({
33
+ '/tabs': {
34
+ component: () => makeComponent(),
35
+ hash: ['overview', 'details'] as const,
36
+ },
37
+ })
38
+ expectTypeOf(routes['/tabs'].hash).toEqualTypeOf<readonly ['overview', 'details']>()
39
+ })
40
+
41
+ it('Should preserve the declared return type of a `query` validator', () => {
42
+ const routes = defineNestedRoutes({
43
+ '/list': {
44
+ component: () => makeComponent(),
45
+ query: (raw): { page: number } | null => (typeof raw.page === 'number' ? { page: raw.page } : null),
46
+ },
47
+ })
48
+ type QueryFn = NonNullable<(typeof routes)['/list']['query']>
49
+ expectTypeOf<ReturnType<QueryFn>>().toEqualTypeOf<{ page: number } | null>()
50
+ })
51
+
52
+ it('Should preserve nested children literals', () => {
53
+ const routes = defineNestedRoutes({
54
+ '/navigation': {
55
+ component: () => makeComponent(),
56
+ children: {
57
+ '/tabs': {
58
+ component: () => makeComponent(),
59
+ hash: ['a'] as const,
60
+ },
61
+ },
62
+ },
63
+ })
64
+ type TabsHash = NonNullable<(typeof routes)['/navigation']['children']>['/tabs']['hash']
65
+ expectTypeOf<TabsHash>().toEqualTypeOf<readonly ['a']>()
66
+ })
67
+
68
+ it('Should reject values that do not satisfy the NestedRoute constraint', () => {
69
+ // @ts-expect-error -- `component` is required on every route entry
70
+ defineNestedRoutes({ '/invalid': { hash: ['a'] as const } })
71
+ })
72
+ })
73
+
74
+ describe('Satisfies-collapse regression coverage', () => {
75
+ it('Should keep literal shape intact (unlike a bare `satisfies` assertion)', () => {
76
+ // A plain `satisfies` on `Record<string, NestedRoute<any>>` would widen
77
+ // the per-route `hash` to `readonly any[]` and drop the literal tuple.
78
+ // `defineNestedRoutes` must preserve the narrow tuple so downstream
79
+ // type extractors (`ExtractRouteHash`, `RouteAt`) can recover it.
80
+ const routes = defineNestedRoutes({
81
+ '/tabs': {
82
+ component: () => makeComponent(),
83
+ hash: ['overview'] as const,
84
+ },
85
+ })
86
+ type Hash = (typeof routes)['/tabs']['hash']
87
+ expectTypeOf<Hash>().not.toEqualTypeOf<readonly any[]>()
88
+ expectTypeOf<Hash>().toEqualTypeOf<readonly ['overview']>()
89
+ })
90
+ })
91
+ })
@@ -0,0 +1,27 @@
1
+ import type { NestedRoute } from './nested-router.js'
2
+
3
+ /**
4
+ * Identity helper that preserves the exact inferred literal type of a nested
5
+ * route tree while still applying a structural `Record<string, NestedRoute<...>>`
6
+ * constraint for compile-time validation.
7
+ *
8
+ * Using a plain `satisfies Record<string, NestedRoute<any>>` assertion collapses
9
+ * the per-route `query` / `hash` generics to their defaults, which defeats the
10
+ * type-safe navigation helpers (`createNestedRouteLink`, `createNestedNavigate`,
11
+ * `createNestedHooks`). Declaring route trees through this helper keeps the
12
+ * literal shape intact so downstream extractors can recover each route's
13
+ * declared query validator return type and hash literal tuple.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const routes = defineNestedRoutes({
18
+ * '/users/:id': {
19
+ * component: ({ match, query, hash }) => ...,
20
+ * hash: ['profile', 'settings'] as const,
21
+ * query: (raw): { page: number } | null =>
22
+ * typeof raw.page === 'number' ? { page: raw.page } : null,
23
+ * },
24
+ * })
25
+ * ```
26
+ */
27
+ export const defineNestedRoutes = <T extends Record<string, NestedRoute<any, any, any>>>(routes: T): T => routes
@@ -1,8 +1,8 @@
1
+ export * from './define-nested-routes.js'
1
2
  export * from './lazy-load.js'
2
- export * from './link-to-route.js'
3
+ export * from './nested-hooks.js'
3
4
  export * from './nested-navigate.js'
5
+ export * from './nested-replace.js'
4
6
  export * from './nested-route-link.js'
5
7
  export * from './nested-route-types.js'
6
8
  export * from './nested-router.js'
7
- export * from './route-link.js'
8
- export * from './router.js'
@@ -0,0 +1,254 @@
1
+ import { Injector } from '@furystack/inject'
2
+ import { usingAsync } from '@furystack/utils'
3
+ import { describe, expect, expectTypeOf, it } from 'vitest'
4
+ import { LocationService } from '../services/location-service.js'
5
+ import { createNestedHooks, walkRoute } from './nested-hooks.js'
6
+ import type { NestedRoute } from './nested-router.js'
7
+
8
+ const makeComponent = () => null as unknown as JSX.Element
9
+
10
+ describe('walkRoute', () => {
11
+ it('Should return the route when the pattern matches the path exactly', () => {
12
+ const leaf = { component: () => makeComponent() }
13
+ const routes = { '/users': leaf } satisfies Record<string, NestedRoute<any, any, any>>
14
+ expect(walkRoute(routes, '/users')).toBe(leaf)
15
+ })
16
+
17
+ it('Should return undefined when no pattern matches', () => {
18
+ const routes = { '/users': { component: () => makeComponent() } } satisfies Record<
19
+ string,
20
+ NestedRoute<any, any, any>
21
+ >
22
+ expect(walkRoute(routes, '/nonexistent')).toBeUndefined()
23
+ })
24
+
25
+ it('Should descend through a `/` root pattern transparently', () => {
26
+ const leaf = { component: () => makeComponent() }
27
+ const routes = {
28
+ '/': {
29
+ component: () => makeComponent(),
30
+ children: {
31
+ '/home': leaf,
32
+ },
33
+ },
34
+ } satisfies Record<string, NestedRoute<any, any, any>>
35
+
36
+ expect(walkRoute(routes, '/home')).toBe(leaf)
37
+ })
38
+
39
+ it('Should resolve a deeply nested path by walking children', () => {
40
+ const leaf = { component: () => makeComponent() }
41
+ const routes = {
42
+ '/navigation': {
43
+ component: () => makeComponent(),
44
+ children: {
45
+ '/tabs': leaf,
46
+ },
47
+ },
48
+ } satisfies Record<string, NestedRoute<any, any, any>>
49
+
50
+ expect(walkRoute(routes, '/navigation/tabs')).toBe(leaf)
51
+ })
52
+
53
+ it('Should resolve through two levels of `/` roots', () => {
54
+ const leaf = { component: () => makeComponent() }
55
+ const routes = {
56
+ '/': {
57
+ component: () => makeComponent(),
58
+ children: {
59
+ '/navigation': {
60
+ component: () => makeComponent(),
61
+ children: {
62
+ '/tabs': leaf,
63
+ },
64
+ },
65
+ },
66
+ },
67
+ } satisfies Record<string, NestedRoute<any, any, any>>
68
+
69
+ expect(walkRoute(routes, '/navigation/tabs')).toBe(leaf)
70
+ })
71
+
72
+ it('Should match a parent prefix when the path is exactly the parent pattern', () => {
73
+ const parent = {
74
+ component: () => makeComponent(),
75
+ children: {
76
+ '/child': { component: () => makeComponent() },
77
+ },
78
+ }
79
+ const routes = { '/parent': parent } satisfies Record<string, NestedRoute<any, any, any>>
80
+
81
+ expect(walkRoute(routes, '/parent')).toBe(parent)
82
+ })
83
+
84
+ it('Should not confuse a prefix pattern that is not followed by a `/`', () => {
85
+ const routes = {
86
+ '/users': {
87
+ component: () => makeComponent(),
88
+ children: {
89
+ '/:id': { component: () => makeComponent() },
90
+ },
91
+ },
92
+ } satisfies Record<string, NestedRoute<any, any, any>>
93
+
94
+ expect(walkRoute(routes, '/usersextra')).toBeUndefined()
95
+ })
96
+ })
97
+
98
+ describe('createNestedHooks', () => {
99
+ describe('getTypedQuery', () => {
100
+ it('Should return null when the route has no declared query validator', async () => {
101
+ const routes = {
102
+ '/bare': { component: () => makeComponent() },
103
+ } satisfies Record<string, NestedRoute<any, any, any>>
104
+
105
+ const { getTypedQuery } = createNestedHooks(routes)
106
+
107
+ await usingAsync(new Injector(), async (injector) => {
108
+ expect(getTypedQuery(injector, '/bare')).toBeNull()
109
+ })
110
+ })
111
+
112
+ it('Should return the validated query when the current search matches', async () => {
113
+ const routes = {
114
+ '/list': {
115
+ component: () => makeComponent(),
116
+ query: (raw): { page: number } | null => (typeof raw.page === 'number' ? { page: raw.page } : null),
117
+ },
118
+ } satisfies Record<string, NestedRoute<any, any, any>>
119
+
120
+ const { getTypedQuery } = createNestedHooks(routes)
121
+
122
+ await usingAsync(new Injector(), async (injector) => {
123
+ const locationService = injector.getInstance(LocationService)
124
+ locationService.onDeserializedLocationSearchChanged.setValue({ page: 3 })
125
+ expect(getTypedQuery(injector, '/list')).toEqual({ page: 3 })
126
+ })
127
+ })
128
+
129
+ it('Should return null when the validator rejects the current search', async () => {
130
+ const routes = {
131
+ '/list': {
132
+ component: () => makeComponent(),
133
+ query: (raw): { page: number } | null => (typeof raw.page === 'number' ? { page: raw.page } : null),
134
+ },
135
+ } satisfies Record<string, NestedRoute<any, any, any>>
136
+
137
+ const { getTypedQuery } = createNestedHooks(routes)
138
+
139
+ await usingAsync(new Injector(), async (injector) => {
140
+ const locationService = injector.getInstance(LocationService)
141
+ locationService.onDeserializedLocationSearchChanged.setValue({ page: 'not-a-number' })
142
+ expect(getTypedQuery(injector, '/list')).toBeNull()
143
+ })
144
+ })
145
+ })
146
+
147
+ describe('getTypedHash', () => {
148
+ it('Should return undefined when the route has no declared hash tuple', async () => {
149
+ const routes = {
150
+ '/bare': { component: () => makeComponent() },
151
+ } satisfies Record<string, NestedRoute<any, any, any>>
152
+
153
+ const { getTypedHash } = createNestedHooks(routes)
154
+
155
+ await usingAsync(new Injector(), async (injector) => {
156
+ expect(getTypedHash(injector, '/bare')).toBeUndefined()
157
+ })
158
+ })
159
+
160
+ it('Should return the current hash when it matches a declared literal', async () => {
161
+ const routes = {
162
+ '/tabs': {
163
+ component: () => makeComponent(),
164
+ hash: ['overview', 'details'] as const,
165
+ },
166
+ } satisfies Record<string, NestedRoute<any, any, any>>
167
+
168
+ const { getTypedHash } = createNestedHooks(routes)
169
+
170
+ await usingAsync(new Injector(), async (injector) => {
171
+ const locationService = injector.getInstance(LocationService)
172
+ locationService.onLocationHashChanged.setValue('details')
173
+ expect(getTypedHash(injector, '/tabs')).toBe('details')
174
+ })
175
+ })
176
+
177
+ it('Should return undefined when the current hash is not in the declared tuple', async () => {
178
+ const routes = {
179
+ '/tabs': {
180
+ component: () => makeComponent(),
181
+ hash: ['overview', 'details'] as const,
182
+ },
183
+ } satisfies Record<string, NestedRoute<any, any, any>>
184
+
185
+ const { getTypedHash } = createNestedHooks(routes)
186
+
187
+ await usingAsync(new Injector(), async (injector) => {
188
+ const locationService = injector.getInstance(LocationService)
189
+ locationService.onLocationHashChanged.setValue('something-else')
190
+ expect(getTypedHash(injector, '/tabs')).toBeUndefined()
191
+ })
192
+ })
193
+
194
+ it('Should resolve hashes through nested routes', async () => {
195
+ const routes = {
196
+ '/navigation': {
197
+ component: () => makeComponent(),
198
+ children: {
199
+ '/tabs': {
200
+ component: () => makeComponent(),
201
+ hash: ['ctrl-1', 'ctrl-2'] as const,
202
+ },
203
+ },
204
+ },
205
+ } satisfies Record<string, NestedRoute<any, any, any>>
206
+
207
+ const { getTypedHash } = createNestedHooks(routes)
208
+
209
+ await usingAsync(new Injector(), async (injector) => {
210
+ const locationService = injector.getInstance(LocationService)
211
+ locationService.onLocationHashChanged.setValue('ctrl-1')
212
+ expect(getTypedHash(injector, '/navigation/tabs')).toBe('ctrl-1')
213
+ })
214
+ })
215
+ })
216
+
217
+ describe('Type utilities', () => {
218
+ it('Should narrow getTypedHash against the declared literal tuple', () => {
219
+ const routes = {
220
+ '/tabs': {
221
+ component: () => makeComponent(),
222
+ hash: ['overview', 'details'] as const,
223
+ },
224
+ } satisfies Record<string, NestedRoute<any, any, any>>
225
+
226
+ const { getTypedHash } = createNestedHooks(routes)
227
+ expectTypeOf(getTypedHash<'/tabs'>).returns.toEqualTypeOf<'overview' | 'details' | undefined>()
228
+ })
229
+
230
+ it('Should narrow getTypedQuery against the declared validator return type', () => {
231
+ const routes = {
232
+ '/list': {
233
+ component: () => makeComponent(),
234
+ query: (raw): { page: number } | null => (typeof raw.page === 'number' ? { page: raw.page } : null),
235
+ },
236
+ } satisfies Record<string, NestedRoute<any, any, any>>
237
+
238
+ const { getTypedQuery } = createNestedHooks(routes)
239
+ expectTypeOf(getTypedQuery<'/list'>).returns.toEqualTypeOf<{ page: number } | null>()
240
+ })
241
+
242
+ it('Should reject paths not present in the route tree', () => {
243
+ const routes = {
244
+ '/tabs': {
245
+ component: () => makeComponent(),
246
+ },
247
+ } satisfies Record<string, NestedRoute<any, any, any>>
248
+
249
+ const { getTypedHash } = createNestedHooks(routes)
250
+ // @ts-expect-error -- '/nonexistent' is not a valid route path
251
+ getTypedHash(new Injector(), '/nonexistent')
252
+ })
253
+ })
254
+ })
@@ -0,0 +1,109 @@
1
+ import type { Injector } from '@furystack/inject'
2
+ import { LocationService } from '../services/location-service.js'
3
+ import type { ExtractRouteHash, ExtractRouteQuery, ExtractRoutePaths, RouteAt } from './nested-route-types.js'
4
+ import type { NestedRoute } from './nested-router.js'
5
+
6
+ /**
7
+ * A pair of synchronous read helpers bound to a specific route tree. Use the
8
+ * factory {@link createNestedHooks} to produce one.
9
+ */
10
+ export type NestedHooks<TRoutes extends Record<string, NestedRoute<any, any, any>>> = {
11
+ /**
12
+ * Reads and validates the current URL query string against the declared
13
+ * validator of the route at `path`. Returns the typed query value, or
14
+ * `null` when the route has no validator or the current URL's query does
15
+ * not satisfy it.
16
+ *
17
+ * This is a synchronous snapshot — for reactive use, subscribe to
18
+ * `locationService.onDeserializedLocationSearchChanged` and call this read
19
+ * on each change.
20
+ */
21
+ getTypedQuery: <TPath extends ExtractRoutePaths<TRoutes>>(
22
+ injector: Injector,
23
+ path: TPath,
24
+ ) => ExtractRouteQuery<RouteAt<TRoutes, TPath>> | null
25
+ /**
26
+ * Reads the current URL hash and narrows it against the declared literal
27
+ * tuple of the route at `path`. Returns the hash when it matches one of
28
+ * the route's declared literals, or `undefined` otherwise.
29
+ *
30
+ * This is a synchronous snapshot — for reactive use, subscribe to
31
+ * `locationService.onLocationHashChanged` and call this read on each change.
32
+ */
33
+ getTypedHash: <TPath extends ExtractRoutePaths<TRoutes>>(
34
+ injector: Injector,
35
+ path: TPath,
36
+ ) => ExtractRouteHash<RouteAt<TRoutes, TPath>> | undefined
37
+ }
38
+
39
+ /**
40
+ * Walks a route tree and returns the route value declared at the given path,
41
+ * matching each URL pattern segment-by-segment. The root `/` pattern is
42
+ * transparent: its children are searched with the full path.
43
+ *
44
+ * Exported for unit testing only — consumers should go through
45
+ * {@link createNestedHooks}.
46
+ *
47
+ * @internal
48
+ */
49
+ export const walkRoute = (
50
+ routes: Record<string, NestedRoute<any, any, any>>,
51
+ path: string,
52
+ ): NestedRoute<any, any, any> | undefined => {
53
+ for (const [pattern, route] of Object.entries(routes)) {
54
+ if (pattern === path) return route
55
+ if (pattern === '/' && route.children) {
56
+ const nested = walkRoute(route.children, path)
57
+ if (nested) return nested
58
+ } else if (route.children && path.startsWith(pattern)) {
59
+ const rest = path.slice(pattern.length)
60
+ if (rest.startsWith('/') || rest === '') {
61
+ const nested = walkRoute(route.children, rest || '/')
62
+ if (nested) return nested
63
+ }
64
+ }
65
+ }
66
+ return undefined
67
+ }
68
+
69
+ /**
70
+ * Creates a pair of type-safe synchronous read helpers (`getTypedQuery`,
71
+ * `getTypedHash`) bound to a specific route tree. The returned functions
72
+ * validate the current URL's query and hash against the route declared at
73
+ * the given path, returning typed values or `null`/`undefined` on mismatch.
74
+ *
75
+ * The concrete route tree is captured at factory time, so call sites only
76
+ * pass `(injector, path)`; the type-level narrowing is derived from the
77
+ * inferred tree generic.
78
+ *
79
+ * @typeParam TRoutes - The route tree type (inferred from the `routes` argument)
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * const { getTypedQuery, getTypedHash } = createNestedHooks(appRoutes)
84
+ *
85
+ * const query = getTypedQuery(injector, '/users') // typed
86
+ * const hash = getTypedHash(injector, '/users') // typed
87
+ * ```
88
+ */
89
+ export const createNestedHooks = <TRoutes extends Record<string, NestedRoute<any, any, any>>>(
90
+ routes: TRoutes,
91
+ ): NestedHooks<TRoutes> => {
92
+ return {
93
+ getTypedQuery: (injector, path) => {
94
+ const route = walkRoute(routes, path)
95
+ if (!route?.query) return null
96
+ const locationService = injector.getInstance(LocationService)
97
+ const deserialized = locationService.onDeserializedLocationSearchChanged.getValue()
98
+ return route.query(deserialized) as never
99
+ },
100
+ getTypedHash: (injector, path) => {
101
+ const route = walkRoute(routes, path)
102
+ const declaredHash = route?.hash as readonly string[] | undefined
103
+ if (!declaredHash) return undefined
104
+ const locationService = injector.getInstance(LocationService)
105
+ const currentHash = locationService.onLocationHashChanged.getValue()
106
+ return declaredHash.includes(currentHash) ? (currentHash as never) : undefined
107
+ },
108
+ }
109
+ }