@furystack/shades 13.2.2 → 15.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 (146) hide show
  1. package/CHANGELOG.md +157 -0
  2. package/esm/component-factory.spec.d.ts.map +1 -1
  3. package/esm/component-factory.spec.js +2 -2
  4. package/esm/component-factory.spec.js.map +1 -1
  5. package/esm/components/define-nested-routes.d.ts +27 -0
  6. package/esm/components/define-nested-routes.d.ts.map +1 -0
  7. package/esm/components/define-nested-routes.js +26 -0
  8. package/esm/components/define-nested-routes.js.map +1 -0
  9. package/esm/components/define-nested-routes.spec.d.ts +2 -0
  10. package/esm/components/define-nested-routes.spec.d.ts.map +1 -0
  11. package/esm/components/define-nested-routes.spec.js +81 -0
  12. package/esm/components/define-nested-routes.spec.js.map +1 -0
  13. package/esm/components/index.d.ts +3 -3
  14. package/esm/components/index.d.ts.map +1 -1
  15. package/esm/components/index.js +3 -3
  16. package/esm/components/index.js.map +1 -1
  17. package/esm/components/nested-hooks.d.ts +62 -0
  18. package/esm/components/nested-hooks.d.ts.map +1 -0
  19. package/esm/components/nested-hooks.js +73 -0
  20. package/esm/components/nested-hooks.js.map +1 -0
  21. package/esm/components/nested-hooks.spec.d.ts +2 -0
  22. package/esm/components/nested-hooks.spec.d.ts.map +1 -0
  23. package/esm/components/nested-hooks.spec.js +211 -0
  24. package/esm/components/nested-hooks.spec.js.map +1 -0
  25. package/esm/components/nested-navigate.d.ts +52 -21
  26. package/esm/components/nested-navigate.d.ts.map +1 -1
  27. package/esm/components/nested-navigate.js +32 -17
  28. package/esm/components/nested-navigate.js.map +1 -1
  29. package/esm/components/nested-navigate.spec.js +109 -19
  30. package/esm/components/nested-navigate.spec.js.map +1 -1
  31. package/esm/components/nested-replace.d.ts +36 -0
  32. package/esm/components/nested-replace.d.ts.map +1 -0
  33. package/esm/components/nested-replace.js +38 -0
  34. package/esm/components/nested-replace.js.map +1 -0
  35. package/esm/components/nested-replace.spec.d.ts +2 -0
  36. package/esm/components/nested-replace.spec.d.ts.map +1 -0
  37. package/esm/components/nested-replace.spec.js +59 -0
  38. package/esm/components/nested-replace.spec.js.map +1 -0
  39. package/esm/components/nested-route-link.d.ts +36 -26
  40. package/esm/components/nested-route-link.d.ts.map +1 -1
  41. package/esm/components/nested-route-link.js +18 -20
  42. package/esm/components/nested-route-link.js.map +1 -1
  43. package/esm/components/nested-route-link.spec.js +67 -17
  44. package/esm/components/nested-route-link.spec.js.map +1 -1
  45. package/esm/components/nested-route-types.d.ts +79 -2
  46. package/esm/components/nested-route-types.d.ts.map +1 -1
  47. package/esm/components/nested-router.d.ts +77 -7
  48. package/esm/components/nested-router.d.ts.map +1 -1
  49. package/esm/components/nested-router.js +139 -13
  50. package/esm/components/nested-router.js.map +1 -1
  51. package/esm/components/nested-router.spec.js +283 -52
  52. package/esm/components/nested-router.spec.js.map +1 -1
  53. package/esm/services/location-service.d.ts +39 -42
  54. package/esm/services/location-service.d.ts.map +1 -1
  55. package/esm/services/location-service.js +115 -134
  56. package/esm/services/location-service.js.map +1 -1
  57. package/esm/services/location-service.spec.js +59 -24
  58. package/esm/services/location-service.spec.js.map +1 -1
  59. package/esm/services/route-match-service.d.ts +3 -2
  60. package/esm/services/route-match-service.d.ts.map +1 -1
  61. package/esm/services/route-match-service.js +13 -22
  62. package/esm/services/route-match-service.js.map +1 -1
  63. package/esm/services/route-match-service.spec.js +42 -49
  64. package/esm/services/route-match-service.spec.js.map +1 -1
  65. package/esm/services/route-meta-utils.d.ts +28 -6
  66. package/esm/services/route-meta-utils.d.ts.map +1 -1
  67. package/esm/services/route-meta-utils.js +18 -4
  68. package/esm/services/route-meta-utils.js.map +1 -1
  69. package/esm/services/route-meta-utils.spec.js +60 -5
  70. package/esm/services/route-meta-utils.spec.js.map +1 -1
  71. package/esm/services/screen-service.d.ts +13 -72
  72. package/esm/services/screen-service.d.ts.map +1 -1
  73. package/esm/services/screen-service.js +45 -137
  74. package/esm/services/screen-service.js.map +1 -1
  75. package/esm/services/screen-service.spec.js +19 -18
  76. package/esm/services/screen-service.spec.js.map +1 -1
  77. package/esm/services/spatial-navigation-service.d.ts +17 -39
  78. package/esm/services/spatial-navigation-service.d.ts.map +1 -1
  79. package/esm/services/spatial-navigation-service.js +280 -313
  80. package/esm/services/spatial-navigation-service.js.map +1 -1
  81. package/esm/services/spatial-navigation-service.spec.js +163 -158
  82. package/esm/services/spatial-navigation-service.spec.js.map +1 -1
  83. package/esm/shade.d.ts +1 -1
  84. package/esm/shade.d.ts.map +1 -1
  85. package/esm/shade.js +10 -7
  86. package/esm/shade.js.map +1 -1
  87. package/esm/vnode.d.ts +1 -1
  88. package/esm/vnode.js +1 -1
  89. package/package.json +5 -4
  90. package/src/component-factory.spec.tsx +3 -2
  91. package/src/components/define-nested-routes.spec.ts +91 -0
  92. package/src/components/define-nested-routes.ts +27 -0
  93. package/src/components/index.ts +3 -3
  94. package/src/components/nested-hooks.spec.ts +254 -0
  95. package/src/components/nested-hooks.ts +109 -0
  96. package/src/components/nested-navigate.spec.ts +136 -32
  97. package/src/components/nested-navigate.ts +75 -26
  98. package/src/components/nested-replace.spec.ts +89 -0
  99. package/src/components/nested-replace.ts +46 -0
  100. package/src/components/nested-route-link.spec.tsx +90 -22
  101. package/src/components/nested-route-link.tsx +54 -29
  102. package/src/components/nested-route-types.ts +82 -2
  103. package/src/components/nested-router.spec.tsx +334 -51
  104. package/src/components/nested-router.tsx +184 -24
  105. package/src/services/location-service.spec.ts +68 -25
  106. package/src/services/location-service.tsx +156 -122
  107. package/src/services/route-match-service.spec.ts +41 -28
  108. package/src/services/route-match-service.ts +17 -8
  109. package/src/services/route-meta-utils.spec.ts +78 -10
  110. package/src/services/route-meta-utils.ts +44 -15
  111. package/src/services/screen-service.spec.ts +19 -18
  112. package/src/services/screen-service.ts +65 -110
  113. package/src/services/spatial-navigation-service.spec.ts +165 -160
  114. package/src/services/spatial-navigation-service.ts +299 -287
  115. package/src/shade.ts +11 -8
  116. package/src/vnode.ts +1 -1
  117. package/esm/components/link-to-route.d.ts +0 -10
  118. package/esm/components/link-to-route.d.ts.map +0 -1
  119. package/esm/components/link-to-route.js +0 -16
  120. package/esm/components/link-to-route.js.map +0 -1
  121. package/esm/components/link-to-route.spec.d.ts +0 -2
  122. package/esm/components/link-to-route.spec.d.ts.map +0 -1
  123. package/esm/components/link-to-route.spec.js +0 -30
  124. package/esm/components/link-to-route.spec.js.map +0 -1
  125. package/esm/components/route-link.d.ts +0 -10
  126. package/esm/components/route-link.d.ts.map +0 -1
  127. package/esm/components/route-link.js +0 -25
  128. package/esm/components/route-link.js.map +0 -1
  129. package/esm/components/route-link.spec.d.ts +0 -2
  130. package/esm/components/route-link.spec.d.ts.map +0 -1
  131. package/esm/components/route-link.spec.js +0 -34
  132. package/esm/components/route-link.spec.js.map +0 -1
  133. package/esm/components/router.d.ts +0 -44
  134. package/esm/components/router.d.ts.map +0 -1
  135. package/esm/components/router.js +0 -66
  136. package/esm/components/router.js.map +0 -1
  137. package/esm/components/router.spec.d.ts +0 -2
  138. package/esm/components/router.spec.d.ts.map +0 -1
  139. package/esm/components/router.spec.js +0 -161
  140. package/esm/components/router.spec.js.map +0 -1
  141. package/src/components/link-to-route.spec.tsx +0 -45
  142. package/src/components/link-to-route.tsx +0 -26
  143. package/src/components/route-link.spec.tsx +0 -44
  144. package/src/components/route-link.tsx +0 -29
  145. package/src/components/router.spec.tsx +0 -217
  146. package/src/components/router.tsx +0 -103
@@ -12,10 +12,10 @@ export type ConcatPaths<Parent extends string, Child extends string> = Parent ex
12
12
  * Recursively extracts all valid full URL paths from a nested route tree.
13
13
  * @typeParam T - A record of route patterns to NestedRoute definitions
14
14
  */
15
- export type ExtractRoutePaths<T extends Record<string, NestedRoute<any>>> = {
15
+ export type ExtractRoutePaths<T extends Record<string, NestedRoute<any, any, any>>> = {
16
16
  [K in keyof T & string]:
17
17
  | K
18
- | (T[K] extends { children: infer C extends Record<string, NestedRoute<any>> }
18
+ | (T[K] extends { children: infer C extends Record<string, NestedRoute<any, any, any>> }
19
19
  ? ConcatPaths<K, ExtractRoutePaths<C> & string>
20
20
  : never)
21
21
  }[keyof T & string]
@@ -40,3 +40,83 @@ export type ExtractRouteParams<T extends string> = T extends `${string}:${infer
40
40
  export type UrlTree<TPaths extends string> = {
41
41
  [key: string]: TPaths | UrlTree<TPaths>
42
42
  }
43
+
44
+ /**
45
+ * A query string validator function for a nested route. Receives the deserialized
46
+ * query string object and returns either the typed query value or `null` when
47
+ * the URL's query does not match the route's expected shape.
48
+ * @typeParam TQuery - The typed query shape the route expects
49
+ */
50
+ export type QueryValidator<TQuery> = (raw: Record<string, unknown>) => TQuery | null
51
+
52
+ /**
53
+ * A readonly tuple of string literals describing the allowed URL hash values
54
+ * for a nested route.
55
+ */
56
+ export type HashLiterals = readonly string[]
57
+
58
+ /**
59
+ * Extracts the typed query shape declared by a {@link NestedRoute}'s `query` validator.
60
+ * Resolves to `never` when the route has no `query` validator.
61
+ * @typeParam R - A NestedRoute value type
62
+ */
63
+ export type ExtractRouteQuery<R> = R extends { query: QueryValidator<infer Q> } ? Q : never
64
+
65
+ /**
66
+ * Extracts the typed hash literal union declared by a {@link NestedRoute}'s `hash` tuple.
67
+ * Resolves to `never` when the route has no `hash` declaration.
68
+ * @typeParam R - A NestedRoute value type
69
+ */
70
+ export type ExtractRouteHash<R> = R extends { hash: infer H extends HashLiterals } ? H[number] : never
71
+
72
+ /**
73
+ * Walks a nested route tree and resolves the route value at the given composed path.
74
+ * Used to surface per-route `query` / `hash` metadata to call-site helpers.
75
+ * @typeParam TRoutes - The route tree
76
+ * @typeParam TPath - A full composed route path (as produced by {@link ExtractRoutePaths})
77
+ */
78
+ export type RouteAt<TRoutes extends Record<string, NestedRoute<any, any, any>>, TPath extends string> = {
79
+ [K in keyof TRoutes & string]: TPath extends K
80
+ ? TRoutes[K]
81
+ : K extends '/'
82
+ ? TRoutes[K] extends { children: infer C extends Record<string, NestedRoute<any, any, any>> }
83
+ ? RouteAt<C, TPath>
84
+ : never
85
+ : TPath extends `${K}${infer Rest}`
86
+ ? TRoutes[K] extends { children: infer C extends Record<string, NestedRoute<any, any, any>> }
87
+ ? RouteAt<C, Rest>
88
+ : never
89
+ : never
90
+ }[keyof TRoutes & string]
91
+
92
+ /**
93
+ * Builds the `params` portion of a typed navigation / link argument.
94
+ * Resolves to `{ params?: Record<string, string> }` when the path has no `:param`
95
+ * segments and `{ params: {...} }` when at least one is required.
96
+ * @typeParam TPath - A URL pattern string
97
+ */
98
+ export type TypedParamsArg<TPath extends string> = string extends keyof ExtractRouteParams<TPath>
99
+ ? { params?: Record<string, string> }
100
+ : { params: ExtractRouteParams<TPath> }
101
+
102
+ /**
103
+ * Builds the `query` portion of a typed navigation / link argument.
104
+ * - `never` (route declared no schema) → property is forbidden.
105
+ * - All-optional schema → property itself is optional.
106
+ * - Any required key → property is required.
107
+ * @typeParam TQuery - The route's typed query shape
108
+ */
109
+ export type TypedQueryArg<TQuery> = [TQuery] extends [never]
110
+ ? { query?: never }
111
+ : // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- `{} extends T` is the idiomatic way to detect "all keys optional" on an arbitrary object shape.
112
+ {} extends TQuery
113
+ ? { query?: TQuery }
114
+ : { query: TQuery }
115
+
116
+ /**
117
+ * Builds the `hash` portion of a typed navigation / link argument.
118
+ * Hash is always optional at the call site (URL fragments are never required
119
+ * for correctness of navigation).
120
+ * @typeParam THash - The route's hash literal union
121
+ */
122
+ export type TypedHashArg<THash> = [THash] extends [never] ? { hash?: never } : { hash?: THash }