@sigx/lynx-navigation 0.2.0 → 0.4.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 (193) hide show
  1. package/README.md +128 -8
  2. package/dist/components/EntryScope.d.ts +1 -1
  3. package/dist/components/EntryScope.d.ts.map +1 -1
  4. package/dist/components/Layer.d.ts +34 -0
  5. package/dist/components/Layer.d.ts.map +1 -0
  6. package/dist/components/Link.d.ts +2 -2
  7. package/dist/components/Link.d.ts.map +1 -1
  8. package/dist/components/NavigationRoot.d.ts +2 -2
  9. package/dist/components/NavigationRoot.d.ts.map +1 -1
  10. package/dist/components/Screen.d.ts +6 -6
  11. package/dist/components/Screen.d.ts.map +1 -1
  12. package/dist/components/Stack.d.ts +41 -16
  13. package/dist/components/Stack.d.ts.map +1 -1
  14. package/dist/components/TabBar.d.ts +19 -20
  15. package/dist/components/TabBar.d.ts.map +1 -1
  16. package/dist/components/Tabs.d.ts.map +1 -1
  17. package/dist/define-routes.d.ts +1 -1
  18. package/dist/define-routes.d.ts.map +1 -1
  19. package/dist/hooks/use-linking-nav.d.ts +3 -3
  20. package/dist/hooks/use-linking-nav.d.ts.map +1 -1
  21. package/dist/hooks/use-nav-internal.d.ts +21 -3
  22. package/dist/hooks/use-nav-internal.d.ts.map +1 -1
  23. package/dist/hooks/use-nav-serializer.d.ts +1 -1
  24. package/dist/hooks/use-nav-serializer.d.ts.map +1 -1
  25. package/dist/hooks/use-nav.d.ts +2 -2
  26. package/dist/hooks/use-nav.d.ts.map +1 -1
  27. package/dist/hooks/use-params.d.ts +1 -1
  28. package/dist/hooks/use-params.d.ts.map +1 -1
  29. package/dist/hooks/use-screen-chrome.d.ts +19 -0
  30. package/dist/hooks/use-screen-chrome.d.ts.map +1 -0
  31. package/dist/hooks/use-screen-options.d.ts +1 -1
  32. package/dist/hooks/use-screen-options.d.ts.map +1 -1
  33. package/dist/hooks/use-search.d.ts +1 -1
  34. package/dist/hooks/use-search.d.ts.map +1 -1
  35. package/dist/href.d.ts +2 -2
  36. package/dist/href.d.ts.map +1 -1
  37. package/dist/index.d.ts +33 -31
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +1160 -29
  40. package/dist/index.js.map +1 -1
  41. package/dist/internal/layer-plan.d.ts +69 -0
  42. package/dist/internal/layer-plan.d.ts.map +1 -0
  43. package/dist/internal/screen-registry.d.ts +1 -1
  44. package/dist/internal/screen-registry.d.ts.map +1 -1
  45. package/dist/internal/screen-width.d.ts +9 -7
  46. package/dist/internal/screen-width.d.ts.map +1 -1
  47. package/dist/navigator/core.d.ts +5 -4
  48. package/dist/navigator/core.d.ts.map +1 -1
  49. package/dist/register.d.ts +1 -1
  50. package/dist/register.d.ts.map +1 -1
  51. package/dist/url/index.d.ts +6 -6
  52. package/dist/url/index.d.ts.map +1 -1
  53. package/dist/url/parse.d.ts +1 -1
  54. package/dist/url/parse.d.ts.map +1 -1
  55. package/dist/url/registry.d.ts +2 -2
  56. package/dist/url/registry.d.ts.map +1 -1
  57. package/dist/url/validate.d.ts +1 -1
  58. package/dist/url/validate.d.ts.map +1 -1
  59. package/package.json +11 -10
  60. package/src/components/Drawer.d.ts +55 -0
  61. package/src/components/EdgeBackHandle.d.ts +1 -0
  62. package/src/components/EdgeBackHandle.tsx +2 -2
  63. package/{dist/components/EntryScope.js → src/components/EntryScope.d.ts} +7 -15
  64. package/src/components/EntryScope.tsx +15 -4
  65. package/src/components/Header.d.ts +6 -0
  66. package/src/components/Header.tsx +3 -3
  67. package/src/components/Layer.d.ts +33 -0
  68. package/src/components/Layer.tsx +96 -0
  69. package/src/components/Link.d.ts +60 -0
  70. package/src/components/Link.tsx +4 -4
  71. package/src/components/NavigationRoot.d.ts +36 -0
  72. package/src/components/NavigationRoot.tsx +6 -6
  73. package/src/components/Screen.d.ts +97 -0
  74. package/src/components/Screen.tsx +13 -11
  75. package/src/components/Stack.d.ts +90 -0
  76. package/src/components/Stack.tsx +142 -98
  77. package/src/components/TabBar.d.ts +38 -0
  78. package/src/components/TabBar.tsx +22 -22
  79. package/src/components/Tabs.d.ts +109 -0
  80. package/src/components/Tabs.tsx +15 -1
  81. package/{dist/define-routes.js → src/define-routes.d.ts} +2 -4
  82. package/src/define-routes.ts +1 -1
  83. package/src/hooks/use-focus.d.ts +45 -0
  84. package/src/hooks/use-focus.ts +2 -2
  85. package/src/hooks/use-hardware-back.d.ts +37 -0
  86. package/src/hooks/use-hardware-back.ts +1 -1
  87. package/src/hooks/use-linking-nav.d.ts +91 -0
  88. package/src/hooks/use-linking-nav.ts +4 -4
  89. package/src/hooks/use-nav-internal.d.ts +91 -0
  90. package/src/hooks/use-nav-internal.ts +24 -3
  91. package/src/hooks/use-nav-serializer.d.ts +82 -0
  92. package/src/hooks/use-nav-serializer.ts +3 -3
  93. package/src/hooks/use-nav.d.ts +111 -0
  94. package/src/hooks/use-nav.ts +2 -2
  95. package/{dist/hooks/use-params.js → src/hooks/use-params.d.ts} +2 -6
  96. package/src/hooks/use-params.ts +2 -2
  97. package/src/hooks/use-screen-chrome.d.ts +18 -0
  98. package/src/hooks/use-screen-chrome.ts +122 -0
  99. package/src/hooks/use-screen-options.d.ts +2 -0
  100. package/src/hooks/use-screen-options.ts +3 -3
  101. package/{dist/hooks/use-search.js → src/hooks/use-search.d.ts} +2 -6
  102. package/src/hooks/use-search.ts +2 -2
  103. package/src/href.d.ts +54 -0
  104. package/src/href.ts +6 -6
  105. package/src/index.d.ts +39 -0
  106. package/src/index.ts +33 -31
  107. package/src/internal/layer-plan.d.ts +68 -0
  108. package/src/internal/layer-plan.ts +187 -0
  109. package/{dist/internal/screen-registry.js → src/internal/screen-registry.d.ts} +21 -32
  110. package/src/internal/screen-registry.ts +1 -1
  111. package/src/internal/screen-width.d.ts +17 -0
  112. package/src/internal/screen-width.ts +22 -14
  113. package/src/navigator/core.d.ts +96 -0
  114. package/src/navigator/core.ts +17 -6
  115. package/src/register.d.ts +37 -0
  116. package/src/register.ts +1 -1
  117. package/src/types.d.ts +217 -0
  118. package/src/url/build.d.ts +15 -0
  119. package/src/url/build.ts +2 -2
  120. package/src/url/compile.d.ts +34 -0
  121. package/src/url/format.d.ts +28 -0
  122. package/src/url/index.ts +6 -6
  123. package/src/url/parse.d.ts +20 -0
  124. package/src/url/parse.ts +6 -6
  125. package/{dist/url/registry.js → src/url/registry.d.ts} +12 -28
  126. package/src/url/registry.ts +3 -3
  127. package/src/url/validate.d.ts +23 -0
  128. package/src/url/validate.ts +1 -1
  129. package/dist/components/Drawer.js +0 -74
  130. package/dist/components/Drawer.js.map +0 -1
  131. package/dist/components/EdgeBackHandle.js +0 -144
  132. package/dist/components/EdgeBackHandle.js.map +0 -1
  133. package/dist/components/EntryScope.js.map +0 -1
  134. package/dist/components/Header.js +0 -103
  135. package/dist/components/Header.js.map +0 -1
  136. package/dist/components/Link.js +0 -51
  137. package/dist/components/Link.js.map +0 -1
  138. package/dist/components/NavigationRoot.js +0 -67
  139. package/dist/components/NavigationRoot.js.map +0 -1
  140. package/dist/components/Screen.js +0 -94
  141. package/dist/components/Screen.js.map +0 -1
  142. package/dist/components/ScreenContainer.d.ts +0 -18
  143. package/dist/components/ScreenContainer.d.ts.map +0 -1
  144. package/dist/components/ScreenContainer.js +0 -77
  145. package/dist/components/ScreenContainer.js.map +0 -1
  146. package/dist/components/Stack.js +0 -221
  147. package/dist/components/Stack.js.map +0 -1
  148. package/dist/components/TabBar.js +0 -63
  149. package/dist/components/TabBar.js.map +0 -1
  150. package/dist/components/Tabs.js +0 -154
  151. package/dist/components/Tabs.js.map +0 -1
  152. package/dist/define-routes.js.map +0 -1
  153. package/dist/hooks/use-focus.js +0 -87
  154. package/dist/hooks/use-focus.js.map +0 -1
  155. package/dist/hooks/use-hardware-back.js +0 -84
  156. package/dist/hooks/use-hardware-back.js.map +0 -1
  157. package/dist/hooks/use-linking-nav.js +0 -109
  158. package/dist/hooks/use-linking-nav.js.map +0 -1
  159. package/dist/hooks/use-nav-internal.js +0 -44
  160. package/dist/hooks/use-nav-internal.js.map +0 -1
  161. package/dist/hooks/use-nav-serializer.js +0 -181
  162. package/dist/hooks/use-nav-serializer.js.map +0 -1
  163. package/dist/hooks/use-nav.js +0 -11
  164. package/dist/hooks/use-nav.js.map +0 -1
  165. package/dist/hooks/use-params.js.map +0 -1
  166. package/dist/hooks/use-screen-options.js +0 -43
  167. package/dist/hooks/use-screen-options.js.map +0 -1
  168. package/dist/hooks/use-search.js.map +0 -1
  169. package/dist/href.js +0 -57
  170. package/dist/href.js.map +0 -1
  171. package/dist/internal/screen-registry.js.map +0 -1
  172. package/dist/internal/screen-width.js +0 -30
  173. package/dist/internal/screen-width.js.map +0 -1
  174. package/dist/navigator/core.js +0 -383
  175. package/dist/navigator/core.js.map +0 -1
  176. package/dist/register.js +0 -2
  177. package/dist/register.js.map +0 -1
  178. package/dist/types.js +0 -9
  179. package/dist/types.js.map +0 -1
  180. package/dist/url/build.js +0 -30
  181. package/dist/url/build.js.map +0 -1
  182. package/dist/url/compile.js +0 -83
  183. package/dist/url/compile.js.map +0 -1
  184. package/dist/url/format.js +0 -102
  185. package/dist/url/format.js.map +0 -1
  186. package/dist/url/index.js +0 -13
  187. package/dist/url/index.js.map +0 -1
  188. package/dist/url/parse.js +0 -94
  189. package/dist/url/parse.js.map +0 -1
  190. package/dist/url/registry.js.map +0 -1
  191. package/dist/url/validate.js +0 -37
  192. package/dist/url/validate.js.map +0 -1
  193. package/src/components/ScreenContainer.tsx +0 -114
@@ -1,383 +0,0 @@
1
- import { runOnMainThread, signal, untrack, } from '@sigx/lynx';
2
- import { isLazyComponent } from '@sigx/lynx';
3
- import { withTiming } from '@sigx/lynx-motion';
4
- /**
5
- * Slide-from-right transition timing. Kept as constants so screen options
6
- * can override per-screen later (Phase 0.5). Duration is in seconds — that's
7
- * what `@sigx/lynx-motion`'s `withTiming` expects (per `with-timing.ts`).
8
- */
9
- const TRANSITION_DURATION_SEC = 0.28;
10
- /**
11
- * Kick off a lazy component's chunk fetch when its route is navigated to.
12
- *
13
- * Lazy routes (`component: lazy(() => import('./Heavy.js'))`) start loading
14
- * the moment `push`/`replace` is called rather than waiting until render
15
- * tries to instantiate them — by the time `<Stack>` swaps screens the chunk
16
- * is usually already resolved, so the user sees the screen instead of the
17
- * `<Suspense fallback>`. Fire-and-forget: errors here surface through
18
- * `<Suspense>` at render time.
19
- */
20
- function preloadRouteComponent(component) {
21
- if (isLazyComponent(component)) {
22
- // eslint-disable-next-line @typescript-eslint/no-empty-function
23
- component.preload().catch(() => { });
24
- }
25
- }
26
- let entryKeyCounter = 0;
27
- function nextEntryKey() {
28
- entryKeyCounter += 1;
29
- return `entry-${entryKeyCounter}-${Math.random().toString(36).slice(2, 8)}`;
30
- }
31
- function makeEntry(name, params, search, options, routes) {
32
- const route = routes[name];
33
- const presentation = options?.presentation ?? route?.presentation ?? 'card';
34
- return {
35
- key: nextEntryKey(),
36
- route: name,
37
- params: (params ?? {}),
38
- search: (search ?? {}),
39
- state: options?.state,
40
- presentation,
41
- };
42
- }
43
- function unpackArgs(name, args, routes) {
44
- const route = routes[name];
45
- const requiresParams = !!route?.params;
46
- if (requiresParams) {
47
- const [params, search, options] = args;
48
- return { params, search, options };
49
- }
50
- const [search, options] = args;
51
- return { params: undefined, search, options };
52
- }
53
- /**
54
- * Create a navigator. Returns the public `nav` handle plus the routes map.
55
- * The transition signal lives on `nav` (via `nav.transition`) so `<Stack>`
56
- * can subscribe to it.
57
- */
58
- export function createNavigatorState(opts) {
59
- const { routes, initial, progress, parent = null } = opts;
60
- const stackSignal = signal([initial]);
61
- const focusedBox = signal({
62
- value: opts.initialLocallyFocused ?? true,
63
- });
64
- const children = new Set();
65
- // `signal(null)` would wrap as a primitive (no `$set`), so wrap in an
66
- // object to get the standard `{ value }`-style API. Reading `.value`
67
- // tracks; writing triggers re-render of `<Stack>`.
68
- const transitionBox = signal({ value: null });
69
- function getStack() {
70
- return stackSignal;
71
- }
72
- function setStack(next) {
73
- stackSignal.$set(next);
74
- }
75
- function setTransition(next) {
76
- transitionBox.value = next;
77
- }
78
- /**
79
- * Whether a transition is currently in flight. Used to no-op concurrent
80
- * navigation calls — keeps the state machine simple. A queued/aborted
81
- * model is a v0.3 polish item.
82
- */
83
- function isTransitioning() {
84
- return transitionBox.value !== null;
85
- }
86
- /**
87
- * Run the slide animation by hopping a worklet onto the main thread that
88
- * resets `progress` to 0 and starts a `withTiming` to the target. Then
89
- * wait the animation duration on BG so we can fire the completion
90
- * callback (clear transition / commit the popped entry) when the visual
91
- * animation is done.
92
- *
93
- * Why the SV reset lives *inside* the worklet (not on BG before the call):
94
- * the BG-side render ops (Stack re-render mounting the two
95
- * `ScreenContainer`s with their `useAnimatedStyle` bindings) and a BG-side
96
- * SV write (`progress.value = 0`) travel different bridge channels. On
97
- * subsequent navigations, MT can register the new bindings before the
98
- * BG-side reset arrives — the bindings snapshot sv at its previous
99
- * end-state (`1`), and `withTiming(sv, 1, ...)` then animates from 1→1
100
- * (no visible motion). Resetting inside the worklet guarantees the order
101
- * `bindings register → sv resets → withTiming starts` happens atomically
102
- * on MT.
103
- *
104
- * Why we don't `await` the worklet's Promise: `withTiming` returns a
105
- * Promise on MT, but Promises don't serialize across the BG/MT bridge —
106
- * `runOnMainThread`'s callback fires the moment the worklet *returns*
107
- * (synchronously, with `undefined` since the Promise can't cross), not
108
- * when the underlying animation finishes. We time the BG-side wait
109
- * against the duration we passed to MT instead.
110
- */
111
- async function animateProgress(target, durationSec) {
112
- if (!progress)
113
- return;
114
- const sv = progress;
115
- const runner = runOnMainThread((t, d) => {
116
- 'main thread';
117
- // MT-side direct write — `sv.value` is a BG-side getter/setter
118
- // that emits a "read-only on BG" warning when set; the actual
119
- // MT field (which `withTiming`'s animate() reads as the start
120
- // value) is `sv.current.value`. See `packages/lynx-runtime/src/
121
- // animated/shared-value.ts:14-44`.
122
- sv.current.value = 0;
123
- withTiming(sv, t, { duration: d });
124
- });
125
- runner(target, durationSec);
126
- await new Promise((resolve) => {
127
- setTimeout(resolve, Math.round(durationSec * 1000));
128
- });
129
- }
130
- const push = ((name, ...args) => {
131
- if (!routes[name]) {
132
- throw new Error(`[lynx-navigation] push('${name}'): route is not registered. ` +
133
- `Known routes: ${Object.keys(routes).join(', ') || '(none)'}`);
134
- }
135
- const { params, search, options } = unpackArgs(name, args, routes);
136
- // Escalate non-card presentations up the parent chain. Modals,
137
- // fullScreen, and transparent-modal routes belong on the root
138
- // navigator so they overlay tab UI and persistent chrome. We resolve
139
- // the presentation the same way `makeEntry` does so the escalation
140
- // decision matches what would actually be shown.
141
- const resolvedPresentation = (options?.presentation ?? routes[name].presentation ?? 'card');
142
- if (resolvedPresentation !== 'card' && parent) {
143
- // Walk straight to the root — every navigator with a parent
144
- // delegates non-card pushes upward, so a chain of any depth
145
- // collapses to a single push on the topmost nav.
146
- // Forward original args verbatim so overloads (`push(name)`,
147
- // `push(name, params)`, `push(name, params, search)`,
148
- // `push(name, params, search, options)`) keep their meaning.
149
- parent.push(name, ...args);
150
- return;
151
- }
152
- if (isTransitioning())
153
- return;
154
- preloadRouteComponent(routes[name].component);
155
- const newEntry = makeEntry(name, params, search, options, routes);
156
- const cur = getStack();
157
- const prevTop = cur[cur.length - 1];
158
- // Append eagerly — UX-wise the user just initiated a forward nav, so
159
- // the new entry should be queryable immediately (`nav.current` =
160
- // newEntry). The slide animation overlays the visual transition.
161
- setStack([...cur, newEntry]);
162
- const animated = options?.animated !== false && !!progress;
163
- if (!animated)
164
- return;
165
- setTransition({
166
- kind: 'push',
167
- topEntry: newEntry,
168
- underneathEntry: prevTop,
169
- progress,
170
- });
171
- animateProgress(1, TRANSITION_DURATION_SEC).then(() => setTransition(null), () => setTransition(null));
172
- });
173
- const replace = ((name, ...args) => {
174
- if (isTransitioning())
175
- return;
176
- const { params, search, options } = unpackArgs(name, args, routes);
177
- if (!routes[name]) {
178
- throw new Error(`[lynx-navigation] replace('${name}'): route is not registered.`);
179
- }
180
- preloadRouteComponent(routes[name].component);
181
- const entry = makeEntry(name, params, search, options, routes);
182
- const cur = getStack();
183
- // Replace doesn't animate in v1 — it's a swap, not a forward/back nav.
184
- // Adding a fade-or-slide variant is a screen-option in Phase 0.5.
185
- setStack([...cur.slice(0, cur.length - 1), entry]);
186
- });
187
- function pop(count = 1, options) {
188
- if (isTransitioning())
189
- return;
190
- const cur = getStack();
191
- const target = Math.max(1, cur.length - Math.max(1, count));
192
- if (target === cur.length)
193
- return;
194
- const animated = options?.animated !== false && !!progress && count === 1 && cur.length >= 2;
195
- if (!animated) {
196
- setStack(cur.slice(0, target));
197
- return;
198
- }
199
- // Single-step animated pop: keep the popped entry on the stack until
200
- // the slide finishes, so `<Stack>` can render both screens during the
201
- // animation. The stack mutation happens on completion.
202
- const popping = cur[cur.length - 1];
203
- const next = cur[cur.length - 2];
204
- setTransition({
205
- kind: 'pop',
206
- topEntry: popping,
207
- underneathEntry: next,
208
- progress,
209
- });
210
- animateProgress(1, TRANSITION_DURATION_SEC).then(() => {
211
- setStack(cur.slice(0, cur.length - 1));
212
- setTransition(null);
213
- }, () => {
214
- // On animation failure, snap to the destination state anyway —
215
- // leaving the popped entry rendered would be more confusing
216
- // than skipping the animation.
217
- setStack(cur.slice(0, cur.length - 1));
218
- setTransition(null);
219
- });
220
- }
221
- function popTo(name) {
222
- if (isTransitioning())
223
- return;
224
- const cur = getStack();
225
- for (let i = cur.length - 1; i >= 0; i--) {
226
- if (cur[i].route === name) {
227
- if (i === cur.length - 1)
228
- return;
229
- setStack(cur.slice(0, i + 1));
230
- return;
231
- }
232
- }
233
- }
234
- function popToRoot() {
235
- if (isTransitioning())
236
- return;
237
- const cur = getStack();
238
- if (cur.length <= 1)
239
- return;
240
- setStack([cur[0]]);
241
- }
242
- function reset(state) {
243
- if (state.stack.length === 0) {
244
- throw new Error('[lynx-navigation] reset() called with empty stack.');
245
- }
246
- setStack([...state.stack]);
247
- setTransition(null);
248
- }
249
- function dismiss() {
250
- if (isTransitioning())
251
- return;
252
- const cur = getStack();
253
- let i = cur.length - 1;
254
- while (i > 0 && cur[i].presentation !== 'card') {
255
- i--;
256
- }
257
- if (i < cur.length - 1) {
258
- setStack(cur.slice(0, i + 1));
259
- }
260
- }
261
- /**
262
- * Set up a gesture-driven pop transition. Same shape as `pop()` sets but
263
- * does NOT call `animateProgress` — the gesture worklet writes the
264
- * progress SV directly per frame, then animates to commit/cancel
265
- * endpoints on release before invoking `commitBackGesture` or
266
- * `cancelBackGesture` via `runOnBackground`.
267
- */
268
- function beginBackGesture() {
269
- if (isTransitioning())
270
- return;
271
- const cur = getStack();
272
- if (cur.length < 2)
273
- return;
274
- const popping = cur[cur.length - 1];
275
- const next = cur[cur.length - 2];
276
- setTransition({
277
- kind: 'pop',
278
- topEntry: popping,
279
- underneathEntry: next,
280
- progress: progress,
281
- });
282
- }
283
- function commitBackGesture() {
284
- const cur = getStack();
285
- if (cur.length >= 2) {
286
- setStack(cur.slice(0, cur.length - 1));
287
- }
288
- setTransition(null);
289
- }
290
- function cancelBackGesture() {
291
- setTransition(null);
292
- }
293
- const nav = {
294
- push,
295
- replace,
296
- pop,
297
- popTo,
298
- popToRoot,
299
- reset,
300
- dismiss,
301
- get current() {
302
- return stackSignal[stackSignal.length - 1];
303
- },
304
- get stack() {
305
- return stackSignal;
306
- },
307
- get canGoBack() {
308
- return stackSignal.length > 1;
309
- },
310
- get parent() {
311
- return parent;
312
- },
313
- get isLocallyFocused() {
314
- return focusedBox.value;
315
- },
316
- get _children() {
317
- return children;
318
- },
319
- get transition() {
320
- return transitionBox.value;
321
- },
322
- };
323
- if (parent) {
324
- // Register with parent so root-level traversals (hardware back,
325
- // future deepest-focused queries) can reach this nav. The matching
326
- // `_children.delete(nav)` happens when the owning `<Stack>` unmounts;
327
- // see Stack.tsx.
328
- parent._children.add(nav);
329
- }
330
- function setLocallyFocused(focused) {
331
- if (focusedBox.value === focused)
332
- return;
333
- focusedBox.value = focused;
334
- }
335
- return {
336
- nav,
337
- routes,
338
- _gesture: { beginBackGesture, commitBackGesture, cancelBackGesture },
339
- _screens: createScreenRegistries(),
340
- _setLocallyFocused: setLocallyFocused,
341
- };
342
- }
343
- /**
344
- * Map-backed `_screens` controller. Pulled out as a tiny factory so test
345
- * tooling can call it directly when asserting registry behaviour without
346
- * standing up an entire navigator.
347
- *
348
- * Not reactive — `<EntryScope>` registers once at setup and unregisters at
349
- * unmount, so reads from the navigator's chrome are point-in-time lookups,
350
- * and the registry's own internal signals carry the reactive payload.
351
- */
352
- function createScreenRegistries() {
353
- const byKey = new Map();
354
- // Reactive version tick — bumped on every register/unregister so consumers
355
- // (HeaderBar's computeds) re-evaluate their lookups when entries come and
356
- // go. `Map.get` itself isn't tracked, so without this a chrome component
357
- // that renders before its target entry mounts would never see the late
358
- // arrival of the registry.
359
- const version = signal({ v: 0 });
360
- return {
361
- register(reg) {
362
- byKey.set(reg.entry.key, reg);
363
- // `register` is called from `<EntryScope>` setup, which itself
364
- // runs inside a tracked scope. Read-then-write on `version`
365
- // would self-loop, so we untrack the bump.
366
- untrack(() => { version.v = version.v + 1; });
367
- },
368
- unregister(key) {
369
- byKey.delete(key);
370
- untrack(() => { version.v = version.v + 1; });
371
- },
372
- get(key) {
373
- // Touch the version signal so the caller's reactive scope
374
- // re-runs on the next register/unregister. The actual returned
375
- // value still comes from the plain Map — registries themselves
376
- // are signal-backed, so once a caller has one in hand they
377
- // track the bits they care about (options/slots) directly.
378
- void version.v;
379
- return byKey.get(key);
380
- },
381
- };
382
- }
383
- //# sourceMappingURL=core.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/navigator/core.ts"],"names":[],"mappings":"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"}
package/dist/register.js DELETED
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=register.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"register.js","sourceRoot":"","sources":["../src/register.ts"],"names":[],"mappings":""}
package/dist/types.js DELETED
@@ -1,9 +0,0 @@
1
- /**
2
- * Core types for @sigx/lynx-navigation.
3
- *
4
- * The type machinery here is the differentiating DX: route names, params, and
5
- * search are all inferred end-to-end from the user's `defineRoutes` call so
6
- * `nav.push('profile', { id: 42 })` is a TS error if `id` is typed as string.
7
- */
8
- export {};
9
- //# sourceMappingURL=types.js.map
package/dist/types.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
package/dist/url/build.js DELETED
@@ -1,30 +0,0 @@
1
- /**
2
- * Typed → URL: build the `url` field of an Href from a route's params/search.
3
- *
4
- * Mirror of parse.ts. Used by `hrefFor()` after schema validation succeeds.
5
- */
6
- import { formatSearch } from './format.js';
7
- import { getCompiledPath, getRouteRegistry } from './registry.js';
8
- /**
9
- * Build the URL form of a route + params + search, or `null` if the route
10
- * declares no `path` template (typed navigation still works — only deep-link
11
- * serialization is unavailable).
12
- *
13
- * Params must already be valid for the route's schema (callers run this after
14
- * `validateSync`). Search values are stringified as-is — schema-validated
15
- * inputs survive round-tripping because `parseHref` re-runs the same schema.
16
- */
17
- export function buildUrl(routeName, params, search) {
18
- const registry = getRouteRegistry();
19
- const compiled = getCompiledPath(registry, routeName);
20
- if (!compiled)
21
- return null;
22
- const formatted = compiled.format(
23
- // The compiler accepts string|number; we widen to unknown and let it
24
- // String()-coerce. Booleans/null get filtered by the missing-param
25
- // check, which is what we want — boolean path params don't exist.
26
- (params ?? {}));
27
- const querystring = formatSearch(search);
28
- return querystring.length > 0 ? `${formatted}?${querystring}` : formatted;
29
- }
30
- //# sourceMappingURL=build.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/url/build.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAElE;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CACpB,SAAiB,EACjB,MAA2C,EAC3C,MAA2C;IAE3C,MAAM,QAAQ,GAAG,gBAAgB,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACtD,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM;IAC7B,qEAAqE;IACrE,mEAAmE;IACnE,kEAAkE;IAClE,CAAC,MAAM,IAAI,EAAE,CAAoC,CACpD,CAAC;IACF,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACzC,OAAO,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9E,CAAC"}
@@ -1,83 +0,0 @@
1
- /**
2
- * Path template compiler.
3
- *
4
- * Turns a route's `path` (e.g. `/users/:id/posts/:postId`) into a compiled
5
- * object that can both match a URL pathname against it and format a typed
6
- * params object back into a URL.
7
- *
8
- * Supported syntax (intentionally minimal for v1):
9
- * - Literal segments: `/users`, `/users/me`
10
- * - Named params: `:id` (matches `[^/]+`)
11
- * - Trailing slashes tolerated on match
12
- *
13
- * Out of scope for v1 (future-compatible — additions won't break v1 paths):
14
- * - Wildcards `*`
15
- * - Optional params `:id?`
16
- * - Typed/constrained params `:id<number>` or `:id(\\d+)`
17
- */
18
- const PARAM_RE = /:([A-Za-z_][A-Za-z0-9_]*)/g;
19
- /**
20
- * Compile a path template. Throws on malformed input (duplicate param names,
21
- * unexpected `:` syntax). Pure — safe to memoize.
22
- */
23
- export function compilePath(template) {
24
- if (typeof template !== 'string') {
25
- throw new TypeError(`compilePath: expected string, got ${typeof template}`);
26
- }
27
- if (template.length === 0) {
28
- throw new Error('compilePath: path template must not be empty');
29
- }
30
- // Normalize: ensure leading `/`. Trailing slashes are tolerated on match,
31
- // but the canonical formatted output preserves the template's trailing
32
- // slash policy.
33
- const normalized = template.startsWith('/') ? template : `/${template}`;
34
- const paramNames = [];
35
- // Build the regex by replacing :name with a capture group. We escape the
36
- // surrounding literal text so paths with regex-special chars (`.`, `+`)
37
- // match literally — only `:name` is treated as a placeholder.
38
- let lastIndex = 0;
39
- let pattern = '';
40
- PARAM_RE.lastIndex = 0;
41
- for (let m = PARAM_RE.exec(normalized); m !== null; m = PARAM_RE.exec(normalized)) {
42
- const name = m[1];
43
- if (paramNames.includes(name)) {
44
- throw new Error(`compilePath: duplicate param name ':${name}' in '${template}'`);
45
- }
46
- paramNames.push(name);
47
- pattern += escapeRegex(normalized.slice(lastIndex, m.index));
48
- pattern += '([^/]+)';
49
- lastIndex = m.index + m[0].length;
50
- }
51
- pattern += escapeRegex(normalized.slice(lastIndex));
52
- // Trim a trailing slash from the pattern so `/users/` and `/users` both
53
- // match `/users/:?`. We keep the formatter's output as-templated.
54
- const matchPattern = pattern.endsWith('/') ? pattern.slice(0, -1) : pattern;
55
- const regex = new RegExp(`^${matchPattern}/?$`);
56
- return {
57
- source: template,
58
- paramNames,
59
- regex,
60
- format(params) {
61
- let out = '';
62
- let i = 0;
63
- PARAM_RE.lastIndex = 0;
64
- for (let m = PARAM_RE.exec(normalized); m !== null; m = PARAM_RE.exec(normalized)) {
65
- const name = m[1];
66
- const value = params[name];
67
- if (value === undefined || value === null) {
68
- throw new Error(`compilePath.format: missing required param ':${name}' for '${template}'`);
69
- }
70
- out += normalized.slice(i, m.index);
71
- out += encodeURIComponent(String(value));
72
- i = m.index + m[0].length;
73
- }
74
- out += normalized.slice(i);
75
- return out;
76
- },
77
- };
78
- }
79
- const REGEX_SPECIALS = /[.*+?^${}()|[\]\\]/g;
80
- function escapeRegex(s) {
81
- return s.replace(REGEX_SPECIALS, '\\$&');
82
- }
83
- //# sourceMappingURL=compile.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../src/url/compile.ts"],"names":[],"mappings":"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"}
@@ -1,102 +0,0 @@
1
- /**
2
- * Format helpers: typed params/search → URL string.
3
- *
4
- * Used by `hrefFor()` to render the `url` field of an Href.
5
- */
6
- /**
7
- * Serialize an object as a `key=value&key=value` querystring.
8
- *
9
- * Keys are sorted to make the output deterministic (useful for tests and
10
- * persistence diffs). `undefined`/`null` values are skipped. Non-primitive
11
- * values are JSON-stringified on the way out — `parseSearch` returns the
12
- * raw string and leaves any JSON decoding to the route's `search` schema
13
- * (e.g. a Zod `transform`), so the round-trip is intentionally one-way at
14
- * this layer.
15
- *
16
- * Returns `''` (empty string) when there are no entries — callers join with
17
- * `?` only when the result is non-empty.
18
- */
19
- export function formatSearch(search) {
20
- if (!search)
21
- return '';
22
- const keys = Object.keys(search).sort();
23
- const parts = [];
24
- for (const key of keys) {
25
- const value = search[key];
26
- if (value === undefined || value === null)
27
- continue;
28
- const encoded = encodeURIComponent(key);
29
- if (Array.isArray(value)) {
30
- for (const item of value) {
31
- if (item === undefined || item === null)
32
- continue;
33
- parts.push(`${encoded}=${encodeURIComponent(serializeScalar(item))}`);
34
- }
35
- }
36
- else {
37
- parts.push(`${encoded}=${encodeURIComponent(serializeScalar(value))}`);
38
- }
39
- }
40
- return parts.join('&');
41
- }
42
- /**
43
- * Parse a `key=value&key=value` querystring into a string-keyed bag. Values
44
- * are decoded but kept as strings — typed coercion happens in the route's
45
- * `search` schema (e.g. Zod's `z.coerce.number()`).
46
- *
47
- * Multiple occurrences of the same key produce an array. Schemas that don't
48
- * expect arrays will reject this — that's the right failure mode.
49
- */
50
- export function parseSearch(query) {
51
- const result = {};
52
- if (!query)
53
- return result;
54
- // Strip leading `?` if present (formatHref doesn't include it but callers
55
- // sometimes pass `?a=1`).
56
- const cleaned = query.startsWith('?') ? query.slice(1) : query;
57
- if (!cleaned)
58
- return result;
59
- for (const pair of cleaned.split('&')) {
60
- if (!pair)
61
- continue;
62
- const eqIdx = pair.indexOf('=');
63
- const rawKey = eqIdx === -1 ? pair : pair.slice(0, eqIdx);
64
- const rawValue = eqIdx === -1 ? '' : pair.slice(eqIdx + 1);
65
- const key = safeDecode(rawKey);
66
- const value = safeDecode(rawValue);
67
- const existing = result[key];
68
- if (existing === undefined) {
69
- result[key] = value;
70
- }
71
- else if (Array.isArray(existing)) {
72
- existing.push(value);
73
- }
74
- else {
75
- result[key] = [existing, value];
76
- }
77
- }
78
- return result;
79
- }
80
- function serializeScalar(v) {
81
- switch (typeof v) {
82
- case 'string': return v;
83
- case 'number':
84
- case 'boolean':
85
- case 'bigint':
86
- return String(v);
87
- default:
88
- // Objects/arrays/etc — JSON. Schemas can decide how to interpret.
89
- return JSON.stringify(v);
90
- }
91
- }
92
- function safeDecode(s) {
93
- try {
94
- return decodeURIComponent(s.replace(/\+/g, ' '));
95
- }
96
- catch {
97
- // Malformed % escape — fall back to the raw text rather than throwing
98
- // from a navigation hot path. The schema will reject if it matters.
99
- return s;
100
- }
101
- }
102
- //# sourceMappingURL=format.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/url/format.ts"],"names":[],"mappings":"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"}