@stealthscale/provider-router 0.1.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.
package/dist/index.js CHANGED
@@ -1,41 +1,65 @@
1
- import { n as __reExport, t as __exportAll } from "./rolldown-runtime-BBjsoOtd.js";
2
1
  import { createElement } from "react";
2
+ import { Link, Navigate, Outlet, Outlet as Outlet$1, RouterContextProvider, RouterProvider, createLink, createMemoryHistory, createRootRoute, createRootRouteWithContext, createRoute, createRoute as createRoute$1, createRouter, isNotFound, isRedirect, lazyRouteComponent, notFound, notFound as notFound$1, redirect, trimPath, useChildMatches, useLinkProps, useLocation, useMatches, useMatches as useMatches$1, useNavigate, useRouteContext, useRouteContext as useRouteContext$1, useRouter, useRouterState } from "@tanstack/react-router";
3
3
  import { c } from "react/compiler-runtime";
4
+ import { getRouteSegments, hasMissingPathParams, interpolatePath } from "@tanstack/router-core";
4
5
  import { jsx } from "react/jsx-runtime";
5
- export * from "@tanstack/react-router";
6
- //#region src/tanstack.ts
7
- var tanstack_exports = /* @__PURE__ */ __exportAll({});
8
- import * as import__tanstack_react_router from "@tanstack/react-router";
9
- __reExport(tanstack_exports, import__tanstack_react_router);
6
+ //#region src/basepath.ts
7
+ /**
8
+ * Derives the path a router mounts its routes under from where the documents are served.
9
+ */
10
+ /**
11
+ * Path a router mounts under when the application is served at the root of its origin.
12
+ */
13
+ const ROOT = "/";
14
+ /**
15
+ * Derives the router's base path from the base the bundler was given.
16
+ *
17
+ * @remarks
18
+ * The bundler's base locates the assets: a path under the application's origin for an ordinary
19
+ * deployment, an absolute URL for one whose assets are served from another host. The router's
20
+ * base path locates the documents, which is always a path on the application's origin. A
21
+ * path-only base locates both, so its path becomes the router's without the trailing slash the
22
+ * bundler writes. A base naming a host says nothing about the documents, so the router mounts at
23
+ * the root.
24
+ * @param base - Base the bundler was given, which is `import.meta.env.BASE_URL` in a page.
25
+ * @param documents - Path the documents are served under, for a deployment whose assets are served
26
+ * from another host. Omitted, the base decides.
27
+ * @returns The path the router mounts under, with a leading slash and no trailing slash.
28
+ */
29
+ function basepathOf(base, documents) {
30
+ const trimmed = (documents ?? (base.startsWith("/") ? base : ROOT)).replace(/\/+$/u, "");
31
+ return trimmed === "" ? ROOT : trimmed;
32
+ }
10
33
  //#endregion
11
34
  //#region src/compile.ts
12
35
  /**
13
36
  * Compiles declarations into routes under a parent, without touching the parent.
14
37
  */
15
38
  /**
16
- * Reads the page a declaration draws with, loading it on first navigation where it is lazy.
39
+ * Returns the component of a declaration's page, which loads on the first navigation where the page
40
+ * is lazy.
17
41
  *
18
42
  * @param component - The page, or the importer that resolves to one.
19
- * @returns The component the route draws.
43
+ * @returns The component the route renders.
20
44
  */
21
45
  function pageOf(component) {
22
- return "load" in component ? (0, tanstack_exports.lazyRouteComponent)(component.load, component.export) : component;
46
+ return "load" in component ? lazyRouteComponent(component.load, component.export) : component;
23
47
  }
24
48
  /**
25
- * Draws a layout around whatever the route below it draws.
49
+ * Returns a component that renders a layout around the route below it.
26
50
  *
27
- * @param drawn - The layout component the caller registered.
51
+ * @param layout - The layout component the caller registered.
28
52
  * @param options - The options the declaration stated for this layout.
29
- * @returns A component the pathless route draws.
53
+ * @returns A component the pathless route renders.
30
54
  */
31
- function framed(drawn, options) {
55
+ function framed(layout, options) {
32
56
  /**
33
- * Draws the layout around the route below it.
57
+ * Renders the layout around the route below it.
34
58
  *
35
- * @returns The frame, holding the outlet.
59
+ * @returns The layout, with the outlet inside it.
36
60
  */
37
61
  return function Layout() {
38
- return createElement(drawn, { options }, createElement(tanstack_exports.Outlet));
62
+ return createElement(layout, { options }, createElement(Outlet$1));
39
63
  };
40
64
  }
41
65
  /**
@@ -86,15 +110,15 @@ function freeId(building, under, name) {
86
110
  * @param under - The route the outermost layout hangs under.
87
111
  * @returns The route the declaration's own route hangs under.
88
112
  * @throws {@link Error} Where a layout nothing provides is named, or where one a route above
89
- * already draws is named again.
113
+ * already renders is named again.
90
114
  */
91
115
  function framing(building, declaration, under) {
92
116
  const names = [...building.applied.get(under) ?? []];
93
117
  let current = under;
94
118
  for (const name of declaration.layout ?? []) {
95
- const drawn = building.options.layouts?.[name];
96
- if (drawn === void 0) throw new Error(`The route ${declaration.id} names the layout ${name}, which is absent.`);
97
- if (names.includes(name)) throw new Error(`The route ${declaration.id} names the layout ${name}, which a route above it already draws.`);
119
+ const layout = building.options.layouts?.[name];
120
+ if (layout === void 0) throw new Error(`The route ${declaration.id} names the layout ${name}, which is absent.`);
121
+ if (names.includes(name)) throw new Error(`The route ${declaration.id} names the layout ${name}, which a route above it already renders.`);
98
122
  names.push(name);
99
123
  const key = JSON.stringify([names, declaration.layoutOptions ?? null]);
100
124
  const built = building.frames.get(current) ?? /* @__PURE__ */ new Map();
@@ -102,8 +126,8 @@ function framing(building, declaration, under) {
102
126
  const existing = built.get(key);
103
127
  const above = current;
104
128
  if (existing === void 0) {
105
- const frame = (0, tanstack_exports.createRoute)({
106
- component: framed(drawn, declaration.layoutOptions),
129
+ const frame = createRoute$1({
130
+ component: framed(layout, declaration.layoutOptions),
107
131
  getParentRoute: () => above,
108
132
  id: freeId(building, above, name)
109
133
  });
@@ -116,17 +140,38 @@ function framing(building, declaration, under) {
116
140
  return current;
117
141
  }
118
142
  /**
143
+ * Builds the loader options of a route whose declaration states a loader.
144
+ *
145
+ * @remarks
146
+ * The search is the loader's dependencies, so the router runs the loader again when the search
147
+ * changes, and keeps one result per search.
148
+ * @param loader - The loader the declaration stated.
149
+ * @returns The options to spread into the route.
150
+ */
151
+ function loading(loader) {
152
+ return {
153
+ loader: ({ abortController, context, deps, params, preload }) => loader({
154
+ context,
155
+ params,
156
+ preload,
157
+ search: deps.search,
158
+ signal: abortController.signal
159
+ }),
160
+ loaderDeps: ({ search }) => ({ search })
161
+ };
162
+ }
163
+ /**
119
164
  * Builds the route one declaration compiles to.
120
165
  *
121
166
  * @param building - The state this compilation has built up.
122
167
  * @param declaration - The route being compiled.
123
168
  * @param under - The route it hangs under, frames included.
124
- * @returns The route, drawing the declaration's page under the frames it named.
169
+ * @returns The route, which renders the declaration's page inside the frames it named.
125
170
  */
126
171
  function routeOf(building, declaration, under) {
127
- const { errorComponent } = building.options;
128
- const { id, navigation, when } = declaration;
129
- return (0, tanstack_exports.createRoute)({
172
+ const { errorComponent, notFoundComponent } = building.options;
173
+ const { id, loader, navigation, when } = declaration;
174
+ return createRoute$1({
130
175
  component: pageOf(declaration.component),
131
176
  getParentRoute: () => under,
132
177
  path: declaration.path,
@@ -135,27 +180,29 @@ function routeOf(building, declaration, under) {
135
180
  ...navigation === void 0 ? {} : { navigation }
136
181
  } },
137
182
  ...errorComponent === void 0 ? {} : { errorComponent: errorComponent(declaration) },
183
+ ...notFoundComponent === void 0 ? {} : { notFoundComponent },
138
184
  ...declaration.search === void 0 ? {} : { validateSearch: declaration.search },
139
- ...when === void 0 ? {} : { beforeLoad: gate(building, declaration, when) }
185
+ ...when === void 0 ? {} : { beforeLoad: gate(building, declaration, when) },
186
+ ...loader === void 0 ? {} : loading(loader)
140
187
  });
141
188
  }
142
189
  /**
143
190
  * Builds the check a route runs before it is entered.
144
191
  *
145
192
  * @remarks
146
- * The evaluator is read once here rather than inside the check, so a declaration stating a
147
- * condition with no evaluator is refused while the tree is built rather than on a navigation.
193
+ * The evaluator is read once, when the route is built, so the compiler refuses a declaration that
194
+ * states a condition without an evaluator before any navigation.
148
195
  * @param building - The state this compilation has built up.
149
196
  * @param declaration - The route being compiled.
150
197
  * @param when - The condition the declaration stated.
151
- * @returns The check, which the route runs before it loads.
198
+ * @returns The check, which the route runs with its context before it loads.
152
199
  * @throws {@link Error} Where no evaluator was given.
153
200
  */
154
201
  function gate(building, declaration, when) {
155
202
  const { evaluate } = building.options;
156
203
  if (evaluate === void 0) throw new Error(`The route ${declaration.id} states a condition and no evaluator was given.`);
157
- return () => {
158
- if (!evaluate(when)) throw (0, tanstack_exports.notFound)();
204
+ return ({ context, location }) => {
205
+ if (!evaluate(when, context, location)) throw notFound$1();
159
206
  };
160
207
  }
161
208
  /**
@@ -189,14 +236,14 @@ function compiledFor(building, declaration, seen) {
189
236
  * Refuses a declaration this package cannot honour, before any of them is compiled.
190
237
  *
191
238
  * @remarks
192
- * A screen maps to a route and a route decides the whole screen, so a page drawn beside another
193
- * as a pane has no route to be. The library agrees: `Outlet` takes no name, one route matches per
194
- * level, and two outlets in one component draw the same child twice.
239
+ * A matched route renders the whole screen, so a page rendered beside another as a pane has no
240
+ * route of its own. The library has no named outlet: `Outlet` takes no name, one route matches
241
+ * per level, and two outlets in one component render the same child twice.
195
242
  * @param declarations - The routes to compile.
196
243
  * @throws {@link Error} Where one states an outlet.
197
244
  */
198
245
  function refuse(declarations) {
199
- for (const declaration of declarations) if (declaration.outlet !== void 0) throw new Error(`The route ${declaration.id} states the outlet ${declaration.outlet}. A screen is whatever its route draws, so there is no pane to draw a second page in.`);
246
+ for (const declaration of declarations) if (declaration.outlet !== void 0) throw new Error(`The route ${declaration.id} states the outlet ${declaration.outlet}. A route renders the whole screen, so no pane exists to render a second page in.`);
200
247
  }
201
248
  /**
202
249
  * Indexes declarations by id, refusing a second one that claims an id already taken.
@@ -217,17 +264,18 @@ function indexed(declarations) {
217
264
  * Compiles declarations into routes under the parent a caller states.
218
265
  *
219
266
  * @remarks
220
- * Pure with respect to the caller. It creates routes and never mutates the parent, so a second
221
- * call returns a second set of routes sharing no object with the first. That is what keeps two
222
- * routers in one process from reading each other's tree through the library's process-wide cache.
223
- * Compile every contributor's declarations in one call. Two calls under one parent cannot see
224
- * each other's paths, and `routeMap` reports the collision once the tree is assembled.
267
+ * The compiler creates routes and never mutates the parent, so a second call returns a second set
268
+ * of routes that shares no object with the first. Two routers in one process therefore never read
269
+ * each other's tree through the library's process-wide cache. Compile every contributor's
270
+ * declarations in one call: two calls under one parent cannot see each other's paths, and
271
+ * `routeMap` reports the collision once the tree is assembled.
225
272
  * @param declarations - The routes to compile, in any order.
226
273
  * @param options - The parent, and what the declarations may name.
227
274
  * @returns The routes to place in the parent's own `addChildren` call.
228
275
  * @throws {@link Error} Where two declarations share an id, where one names a parent or a layout
229
- * nothing provides, where one names a layout a route above it already draws, where parents form a
230
- * cycle, where one states a condition and no evaluator was given, or where one states an outlet.
276
+ * nothing provides, where one names a layout a route above it already renders, where parents form
277
+ * a cycle, where one states a condition and no evaluator was given, or where one states an
278
+ * outlet.
231
279
  */
232
280
  function compileRoutes(declarations, options) {
233
281
  refuse(declarations);
@@ -248,7 +296,7 @@ function compileRoutes(declarations, options) {
248
296
  //#endregion
249
297
  //#region src/reference.ts
250
298
  /**
251
- * Reads the id a target names.
299
+ * Reads the id of a target.
252
300
  *
253
301
  * @param to - A reference, or the bare id.
254
302
  * @returns The full id the route was declared under.
@@ -259,17 +307,20 @@ function idOf(to) {
259
307
  //#endregion
260
308
  //#region src/declared.ts
261
309
  /**
262
- * Reads the id and the menu entry a matched route carries, or nothing where it carries neither.
310
+ * Reads the declaration a matched route was compiled from.
311
+ */
312
+ /**
313
+ * Reads the id and the menu entry a matched route stores, or nothing where it stores neither.
263
314
  *
264
315
  * @remarks
265
- * A route carries its id in `staticData`, which is where the library keeps whatever a route wants
266
- * to carry. The compiler writes it for a route built from a declaration and `namedRoute` writes
267
- * it for one written in code, so a menu, a breadcrumb or a telemetry hook reads what it needs off
268
- * the match either way. The shape is checked rather than trusted, because `staticData` is untyped
269
- * by design and a route may carry anything under the same name. The checked object itself is
270
- * returned, so every read of one route gives one reference.
316
+ * A route stores its id in `staticData`, the library's place for data a route is created with.
317
+ * The compiler writes it for a route built from a declaration, and `namedRoute` writes it for one
318
+ * written in code, so a menu, a breadcrumb or a telemetry hook reads the id from the match either
319
+ * way. The function checks the shape, because `staticData` is untyped and a route may store
320
+ * anything under the same name. It returns the checked object itself, so every read of one route
321
+ * returns one reference.
271
322
  * @param match - A match, as `useMatches` returns one.
272
- * @returns The id and the menu entry it carries, or nothing.
323
+ * @returns The id and the menu entry, or nothing.
273
324
  */
274
325
  function declaredOf(match) {
275
326
  const { staticData } = match;
@@ -279,99 +330,147 @@ function declaredOf(match) {
279
330
  return data;
280
331
  }
281
332
  /**
282
- * Reads the name the deepest named route the page is on goes by.
333
+ * Reads the id of the deepest named route the page is on.
283
334
  *
284
335
  * @remarks
285
- * The deepest match rather than the first, because a named route nested under another is the page
286
- * a person is looking at. A page drawn entirely from unnamed routes returns nothing.
287
- * The selector returns the object the route carries rather than a copy of it. A route's static
288
- * data is fixed once the tree is built, so the reference is the same one until a different route
289
- * matches, and a navigation that left the page alone re-renders nothing.
290
- * @returns The id and the menu entry, or nothing where no matched route carries either.
336
+ * The hook reads the deepest match, because a named route nested under another is the page a
337
+ * person is looking at. A page rendered from unnamed routes alone returns nothing. The selector
338
+ * returns the object the route stores, not a copy. A route's static data is fixed once the tree
339
+ * is built, so the reference changes only when a different route matches, and a navigation that
340
+ * keeps the page does not render it again.
341
+ * @returns The id and the menu entry, or nothing where no matched route has an id.
291
342
  */
292
343
  function useDeclaredRoute() {
293
- const $ = c(2);
294
- if ($[0] !== "c34505ba38c7bb5d21152f0227a85b702acb84f4f34b78cbac48bf4ade5e9158") {
295
- for (let $i = 0; $i < 2; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
296
- $[0] = "c34505ba38c7bb5d21152f0227a85b702acb84f4f34b78cbac48bf4ade5e9158";
297
- }
344
+ const $ = c(1);
298
345
  let t0;
299
- if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
346
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
300
347
  t0 = { select: _temp };
301
- $[1] = t0;
302
- } else t0 = $[1];
303
- return (0, tanstack_exports.useMatches)(t0);
348
+ $[0] = t0;
349
+ } else t0 = $[0];
350
+ return useMatches$1(t0);
351
+ }
352
+ function _temp(matches) {
353
+ return deepestIn(matches)?.declared;
304
354
  }
305
355
  /**
306
- * Reads the parameters of the page being drawn, typed by the reference the caller holds.
356
+ * Reads the parameters of the page being rendered, typed by the reference the caller passes.
307
357
  *
308
358
  * @remarks
309
- * A compiled route is outside the tree an application registered, so `useParams` types against a
310
- * tree the route is not in. The parameters are read off the match instead, and the reference
311
- * carries their names. This checks at run time that the page really is the route the reference
312
- * names before it makes the claim.
313
- * The selector returns the id and the parameters alone, which are strings. Structural sharing
314
- * compares them, so a navigation that changed neither re-renders nothing.
315
- * @param to - A reference to the route the calling component draws.
316
- * @returns The parameters the route's path named.
317
- * @throws {@link Error} Where the page being drawn is not the route the reference names.
359
+ * A compiled route is outside the tree an application registered, so `useParams` types the
360
+ * parameters against a tree the route is not in. The hook reads them from the match instead, and
361
+ * the reference types them. It checks at run time that the page is the route of the reference,
362
+ * and throws where it is not. The selector returns the id and the parameters alone, which are
363
+ * strings. Structural sharing compares them, so a navigation that changes neither does not render
364
+ * the page again.
365
+ * @param to - A reference to the route the calling component renders.
366
+ * @returns The parameters of the route's path.
367
+ * @throws {@link Error} Where the page being rendered is not the route of the reference.
318
368
  */
319
- function _temp(matches) {
320
- return declaredIn(matches);
321
- }
322
369
  function useRouteParams(to) {
323
- const $ = c(2);
324
- if ($[0] !== "c34505ba38c7bb5d21152f0227a85b702acb84f4f34b78cbac48bf4ade5e9158") {
325
- for (let $i = 0; $i < 2; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
326
- $[0] = "c34505ba38c7bb5d21152f0227a85b702acb84f4f34b78cbac48bf4ade5e9158";
327
- }
370
+ const $ = c(1);
328
371
  let t0;
329
- if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
372
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
330
373
  t0 = {
331
374
  select: _temp2,
332
375
  structuralSharing: true
333
376
  };
334
- $[1] = t0;
335
- } else t0 = $[1];
336
- const drawn = (0, tanstack_exports.useMatches)(t0);
337
- const wanted = idOf(to);
338
- if (drawn.id !== wanted) throw new Error(`The page being drawn is not ${wanted}, so its parameters are not that route's.`);
339
- return drawn.params;
377
+ $[0] = t0;
378
+ } else t0 = $[0];
379
+ const current = useMatches$1(t0);
380
+ if (current === void 0 || current.id !== idOf(to)) throw refused(to, "parameters");
381
+ return current.params;
382
+ }
383
+ function _temp2(matches) {
384
+ return paramsIn(matches);
340
385
  }
341
386
  /**
342
- * Reads the name the deepest matched route that carries one goes by.
387
+ * Reads the search of the page being rendered, typed by the reference the caller passes.
343
388
  *
344
- * @param matches - Every matched route, outermost first.
345
- * @returns The id and the menu entry it carries, or nothing where no match carries an id.
346
- */
347
- function _temp2(matches) {
348
- return drawnIn(matches);
389
+ * @remarks
390
+ * A compiled route is outside the tree an application registered, so `useSearch` types the search
391
+ * against a tree the route is not in. The hook reads it from the match instead, and the reference
392
+ * types it. It checks at run time that the page is the route of the reference, and throws where
393
+ * it is not. The value is the match's `_strictSearch`: what the validators of the route and the
394
+ * routes above it returned. The hook leaves out the keys of the address that the validators left
395
+ * out, so the page never receives a value the validator refused under the validator's type.
396
+ * Structural sharing compares the search, so the page does not render again after a navigation
397
+ * that left it equal.
398
+ * @param to - A reference to the route the calling component renders.
399
+ * @returns The search the route's validator returned.
400
+ * @throws {@link Error} Where the page being rendered is not the route of the reference.
401
+ */
402
+ function useRouteSearch(to) {
403
+ const $ = c(1);
404
+ const declared = useDeclaredRoute();
405
+ let t0;
406
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
407
+ t0 = {
408
+ select: _temp3,
409
+ structuralSharing: true
410
+ };
411
+ $[0] = t0;
412
+ } else t0 = $[0];
413
+ const search = useMatches$1(t0);
414
+ if (declared?.id !== idOf(to)) throw refused(to, "search");
415
+ return search;
349
416
  }
350
- function declaredIn(matches) {
351
- let deepest;
352
- for (const match of matches) {
353
- const declared = declaredOf(match);
354
- if (declared !== void 0) deepest = declared;
355
- }
356
- return deepest;
417
+ function _temp3(matches) {
418
+ return searchIn(matches);
357
419
  }
358
420
  /**
359
- * Reads the id and the parameters of the deepest matched route that carries an id.
421
+ * Builds the error a hook throws when the page being rendered is not the route of a reference.
422
+ *
423
+ * @param to - The reference the caller passed.
424
+ * @param what - The value the hook was asked for, which the message mentions.
425
+ * @returns The error.
426
+ */
427
+ function refused(to, what) {
428
+ return /* @__PURE__ */ new Error(`The page being rendered is not ${idOf(to)}, so it cannot return that route's ${what}.`);
429
+ }
430
+ /**
431
+ * Returns the deepest matched route that has an id, with its declaration.
360
432
  *
361
433
  * @param matches - Every matched route, outermost first.
362
- * @returns The id and the parameters, with no id where none of them carries one.
434
+ * @returns The deepest declared match, or nothing where no match has an id.
363
435
  */
364
- function drawnIn(matches) {
365
- let deepest = { params: {} };
436
+ function deepestIn(matches) {
437
+ let deepest;
366
438
  for (const match of matches) {
367
439
  const declared = declaredOf(match);
368
440
  if (declared !== void 0) deepest = {
369
- id: declared.id,
370
- params: match.params
441
+ declared,
442
+ match
371
443
  };
372
444
  }
373
445
  return deepest;
374
446
  }
447
+ /**
448
+ * Reads the id and the parameters of the deepest declared match.
449
+ *
450
+ * @param matches - Every matched route, outermost first.
451
+ * @returns The id and the parameters, or nothing where no match has an id.
452
+ */
453
+ function paramsIn(matches) {
454
+ const deepest = deepestIn(matches);
455
+ return deepest === void 0 ? deepest : {
456
+ id: deepest.declared.id,
457
+ params: deepest.match.params
458
+ };
459
+ }
460
+ /**
461
+ * Reads the validated search of the deepest declared match.
462
+ *
463
+ * @remarks
464
+ * The library's structural sharing compares plain objects and arrays deeply and any other value
465
+ * by reference, so it shares a search of any values. Its types accept only a selection whose type
466
+ * excludes functions. The type of a search of unknown values does not, so the function types the
467
+ * search as strings.
468
+ * @param matches - Every matched route, outermost first.
469
+ * @returns The search, or nothing where no match has an id.
470
+ */
471
+ function searchIn(matches) {
472
+ return deepestIn(matches)?.match._strictSearch;
473
+ }
375
474
  //#endregion
376
475
  //#region src/defaults.ts
377
476
  /**
@@ -388,21 +487,188 @@ function drawnIn(matches) {
388
487
  * already replaced.
389
488
  * Scroll position is restored on the way back, because a person returning to a list expects to be
390
489
  * where they left it rather than at the top.
490
+ * The window is moved in one step, on the way back and to the top of a new page alike. The
491
+ * library moves it with the page's own scroll behaviour by default, and the foundation sets that
492
+ * to smooth for a link into the page, so a page opened from a scrolled one glided in from above.
391
493
  */
392
494
  const routerDefaults = {
393
495
  defaultPreload: "intent",
394
496
  defaultPreloadStaleTime: 0,
395
- scrollRestoration: true
497
+ scrollRestoration: true,
498
+ scrollRestorationBehavior: "instant"
396
499
  };
397
500
  //#endregion
501
+ //#region src/href.ts
502
+ /**
503
+ * Resolves a declared route id to the path a link navigates to.
504
+ */
505
+ /**
506
+ * Resolves a target to a path, with the parameters of the path filled in, for the functions of
507
+ * this package that type their parameters by the target.
508
+ *
509
+ * @remarks
510
+ * Throwing is deliberate in all three cases. Interpolation otherwise writes `undefined` where a
511
+ * parameter was not given, and a route that no router has processed has no path at all. A link
512
+ * that navigates somewhere wrong is worse than one that fails where somebody wrote it. The router
513
+ * parses a path with parameters into segments, and a path without parameters is its own href.
514
+ * @param map - The map every route is named in.
515
+ * @param to - A reference to the route, or the bare id of one.
516
+ * @param params - The parameters of the path.
517
+ * @returns The path, ready to navigate to.
518
+ * @throws {@link Error} Where the map contains no such id, where no router has processed the tree
519
+ * the route was placed in, or where a parameter of the path is missing.
520
+ */
521
+ function resolveHref(map, to, params) {
522
+ const id = idOf(to);
523
+ const route = map.get(id);
524
+ if (route === void 0) throw new Error(`No route is declared with the id ${id}.`);
525
+ if (route.fullPath === void 0) throw new Error(`The route ${id} has no path yet, because no router has processed the tree it was placed in.`);
526
+ const path = route.fullPath;
527
+ const segments = getRouteSegments(route);
528
+ if (segments === void 0) return path;
529
+ const given = params ?? {};
530
+ if (hasMissingPathParams(segments, given)) throw new Error(`The route ${id} names a parameter that was not given.`);
531
+ return interpolatePath(path, segments, given);
532
+ }
533
+ /**
534
+ * Resolves a declared id to a path, with the parameters of the path filled in.
535
+ *
536
+ * @remarks
537
+ * The parameters are required where a typed reference's path has a required one, so the compiler
538
+ * refuses such a call without them. A bare id takes them at will, and the call throws where one
539
+ * is missing.
540
+ * @param map - The map every route is named in.
541
+ * @param to - A reference to the route, or the bare id of one.
542
+ * @param params - The parameters of the path, typed by the reference where one was given.
543
+ * @returns The path, ready to navigate to.
544
+ * @throws {@link Error} Where the map contains no such id, where no router has processed the tree
545
+ * the route was placed in, or where a parameter of the path is missing.
546
+ */
547
+ function routeHref(map, to, ...params) {
548
+ return resolveHref(map, to, params[0]);
549
+ }
550
+ /**
551
+ * Reads the map every route is named in, from the router's own context.
552
+ *
553
+ * @remarks
554
+ * The router's own context passes the map to a component, so an application mounts no provider
555
+ * of this package's own to make a link by id work. Where the route is chosen after the render,
556
+ * pass the map to `routeHref` inside the event handler, because a hook cannot run there.
557
+ * @returns Every id the router knows, against the route that serves it.
558
+ * @throws {@link Error} Where the router was built without one.
559
+ */
560
+ function useRouteMap() {
561
+ const $ = c(1);
562
+ let t0;
563
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
564
+ t0 = { strict: false };
565
+ $[0] = t0;
566
+ } else t0 = $[0];
567
+ const context = useRouteContext$1(t0);
568
+ if (context.routes === void 0) throw new Error("The router context contains no route map, so no id can be resolved. Pass one to routerOptions.");
569
+ return context.routes;
570
+ }
571
+ /**
572
+ * Resolves a reference to a path, through the map in the router context.
573
+ *
574
+ * @remarks
575
+ * A hook, so the route has to be known while the component renders. Use `useRouteMap` where the
576
+ * route is chosen later, such as in the handler of a row a person clicked. The parameters are
577
+ * required as `routeHref` requires them.
578
+ * @param to - A reference to the route, or the bare id of one.
579
+ * @param params - The parameters of the path, typed by the reference where one was given.
580
+ * @returns The path, ready to navigate to.
581
+ * @throws {@link Error} Where no map is in the router context, where the map contains no such id,
582
+ * or where a parameter of the path is missing.
583
+ */
584
+ function useRouteHref(to, ...t0) {
585
+ const $ = c(4);
586
+ const params = t0;
587
+ const t1 = useRouteMap();
588
+ let t2;
589
+ if ($[0] !== params[0] || $[1] !== t1 || $[2] !== to) {
590
+ t2 = resolveHref(t1, to, params[0]);
591
+ $[0] = params[0];
592
+ $[1] = t1;
593
+ $[2] = to;
594
+ $[3] = t2;
595
+ } else t2 = $[3];
596
+ return t2;
597
+ }
598
+ //#endregion
599
+ //#region src/link.tsx
600
+ /**
601
+ * Links to a route by the id a manifest declared it under.
602
+ *
603
+ * @remarks
604
+ * A declared route is outside the tree an application registered, so `Link` refuses its path at
605
+ * compile time. This resolves the id at run time and passes the library a plain string, which is
606
+ * the one place in this package where the compiler does not check a path. The search passes to
607
+ * the library's `Link` beside the path.
608
+ * @param props - The declared id, its parameters, its search, and whatever else the library's
609
+ * `Link` takes.
610
+ * @returns An anchor to the resolved path.
611
+ */
612
+ function RouteLink(props) {
613
+ const $ = c(15);
614
+ let params;
615
+ let rest;
616
+ let search;
617
+ let to;
618
+ if ($[0] !== props) {
619
+ ({params, search, to, ...rest} = props);
620
+ $[0] = props;
621
+ $[1] = params;
622
+ $[2] = rest;
623
+ $[3] = search;
624
+ $[4] = to;
625
+ } else {
626
+ params = $[1];
627
+ rest = $[2];
628
+ search = $[3];
629
+ to = $[4];
630
+ }
631
+ let t0;
632
+ if ($[5] !== search) {
633
+ t0 = search === void 0 ? {} : { search };
634
+ $[5] = search;
635
+ $[6] = t0;
636
+ } else t0 = $[6];
637
+ const t1 = useRouteMap();
638
+ let t2;
639
+ if ($[7] !== params || $[8] !== t1 || $[9] !== to) {
640
+ t2 = resolveHref(t1, to, params);
641
+ $[7] = params;
642
+ $[8] = t1;
643
+ $[9] = to;
644
+ $[10] = t2;
645
+ } else t2 = $[10];
646
+ let t3;
647
+ if ($[11] !== rest || $[12] !== t0 || $[13] !== t2) {
648
+ t3 = /* @__PURE__ */ jsx(Link, {
649
+ ...rest,
650
+ ...t0,
651
+ to: t2
652
+ });
653
+ $[11] = rest;
654
+ $[12] = t0;
655
+ $[13] = t2;
656
+ $[14] = t3;
657
+ } else t3 = $[14];
658
+ return t3;
659
+ }
660
+ //#endregion
398
661
  //#region src/map.ts
399
662
  /**
400
- * Gives a route written in code the id everything else links to it by.
663
+ * Reads the routes of a tree, whoever built them.
664
+ */
665
+ /**
666
+ * Gives a route written in code the id that everything else links to it by.
401
667
  *
402
668
  * @remarks
403
- * A route carries its id in `staticData`, which is where the compiler writes the id of a route
404
- * built from a declaration. One mechanism names both, so a link does not need to know which of
405
- * the two it is pointing at.
669
+ * A route keeps its id in `staticData`, where the compiler writes the id of a route built from a
670
+ * declaration. The same field identifies both kinds, so a link does not need to know which kind
671
+ * it points at.
406
672
  * @param id - The id to name the route under.
407
673
  * @returns The static data to spread into `createRoute`.
408
674
  */
@@ -410,16 +676,16 @@ function namedRoute(id) {
410
676
  return { staticData: { declared: { id } } };
411
677
  }
412
678
  /**
413
- * Reads every id a tree names, against the route that draws it.
679
+ * Reads every id of a tree, against the route that renders it.
414
680
  *
415
681
  * @remarks
416
- * Derived from the tree rather than collected beside it, so a route written in code and a route
417
- * built from a declaration reach the map the same way. The walk also reports two routes that
418
- * serve one URL, which a development build reports as a duplicate route and a production build
419
- * resolves by keeping the first and dropping the rest in silence.
682
+ * The map derives from the tree and is not collected beside it, so a route written in code and a
683
+ * route built from a declaration enter the map the same way. The walk also reports two routes
684
+ * that serve one URL. A development build reports them as a duplicate route, and a production
685
+ * build keeps the first and drops the rest without a report.
420
686
  * @param tree - The assembled tree, as `createRouter` takes it.
421
687
  * @returns Every id, against its route.
422
- * @throws {@link Error} Where two routes carry one id, or where two serve one path under a shared
688
+ * @throws {@link Error} Where two routes have one id, or where two serve one path under a shared
423
689
  * parent.
424
690
  */
425
691
  function routeMap(tree) {
@@ -428,11 +694,11 @@ function routeMap(tree) {
428
694
  return named;
429
695
  }
430
696
  /**
431
- * Walks a route's descendants, naming each one and refusing a repeated path.
697
+ * Walks a route's descendants, records the id of each one and refuses a repeated path.
432
698
  *
433
699
  * @param route - The route whose children are read.
434
700
  * @param named - The map built so far.
435
- * @throws {@link Error} Where two routes carry one id, or where two serve one path here.
701
+ * @throws {@link Error} Where two routes have one id, or where two serve one path at this level.
436
702
  */
437
703
  function collect(route, named) {
438
704
  const claimed = /* @__PURE__ */ new Set();
@@ -446,11 +712,11 @@ function collect(route, named) {
446
712
  }
447
713
  }
448
714
  /**
449
- * Records the id a route carries, where it carries one.
715
+ * Records the id of a route that has one.
450
716
  *
451
717
  * @param route - The route to read.
452
718
  * @param named - The map built so far.
453
- * @throws {@link Error} Where another route already carries the same id.
719
+ * @throws {@link Error} Where another route has the same id already.
454
720
  */
455
721
  function identify(route, named) {
456
722
  const options = route.options;
@@ -469,17 +735,16 @@ function identify(route, named) {
469
735
  * `/home`.
470
736
  */
471
737
  function normalised(path) {
472
- const trimmed = (0, tanstack_exports.trimPath)(path);
738
+ const trimmed = trimPath(path);
473
739
  return trimmed === "/" ? trimmed : `/${trimmed}`;
474
740
  }
475
741
  /**
476
- * Lists the paths a route's descendants serve at its own level, each written the one way the
742
+ * Lists the paths that a route's descendants serve at its own level, each written the one way the
477
743
  * library reads it.
478
744
  *
479
745
  * @remarks
480
- * A pathless route consumes no segment of a URL, so whatever sits below one is served at the
481
- * level of the route above it. The walk goes through a pathless route rather than stopping at
482
- * it.
746
+ * A pathless route consumes no segment of a URL, so the routes below one are served at the level
747
+ * of the route above it. The walk goes through a pathless route and does not stop at it.
483
748
  * @param route - The route whose level is being read.
484
749
  * @returns One path per descendant served at this level.
485
750
  */
@@ -494,13 +759,13 @@ function pathsUnder(route) {
494
759
  return paths;
495
760
  }
496
761
  /**
497
- * Reads the children a route holds.
762
+ * Reads the children of a route.
498
763
  *
499
764
  * @remarks
500
- * The library types a route's children as `any`, because a typed tree names each one. Nothing
501
- * here reads more than the options every route carries.
765
+ * The library types a route's children as `any`, because a typed tree types each one. The walk
766
+ * reads only the options that every route has.
502
767
  * @param route - The route to read.
503
- * @returns Its children, or none where it holds none.
768
+ * @returns Its children, or an empty list where it has none.
504
769
  */
505
770
  function childrenOf(route) {
506
771
  return route.children ?? [];
@@ -528,138 +793,12 @@ function routerOptions(context) {
528
793
  };
529
794
  }
530
795
  //#endregion
531
- //#region src/href.ts
532
- /**
533
- * Resolves a declared id to a path, with the parameters the path names filled in.
534
- *
535
- * @remarks
536
- * Throwing is deliberate in all three cases. Interpolation otherwise returns a path with a
537
- * literal `$id` still in it, and a route the library has not worked a full path out for yet
538
- * returns the site root. A link that navigates somewhere wrong is worse than one that fails where
539
- * somebody wrote it.
540
- * @param map - The map every route is named in.
541
- * @param to - A reference to the route, or the bare id one carries.
542
- * @param params - The parameters the path names, typed by the reference where one was given.
543
- * @returns The path, ready to navigate to.
544
- * @throws {@link Error} Where the map holds no such id, where no router has processed the tree the
545
- * route was placed in, or where a parameter the path names is missing.
546
- */
547
- function routeHref(map, to, params) {
548
- const id = idOf(to);
549
- const route = map.get(id);
550
- if (route === void 0) throw new Error(`No route is declared with the id ${id}.`);
551
- if (route.fullPath === void 0) throw new Error(`The route ${id} has no path yet, because no router has processed the tree it was placed in.`);
552
- const { interpolatedPath, isMissingParams } = (0, tanstack_exports.interpolatePath)({
553
- params: params ?? {},
554
- path: route.fullPath
555
- });
556
- if (isMissingParams) throw new Error(`The route ${id} names a parameter that was not given.`);
557
- return interpolatedPath;
558
- }
559
- /**
560
- * Reads the map every route is named in, from the router's own context.
561
- *
562
- * @remarks
563
- * The map reaches a component through the router's own context rather than a provider of this
564
- * package's own, so an application mounts nothing extra to make a link by id work.
565
- * Take the map rather than a resolved path where the route is chosen after the render: a hook
566
- * cannot run inside an event handler, and `routeHref` can.
567
- * @returns Every id the router knows, against the route that serves it.
568
- * @throws {@link Error} Where the router was built without one.
569
- */
570
- function useRouteMap() {
571
- const $ = c(2);
572
- if ($[0] !== "f9b02b582b5a25eab6d75eb5816b5bc3afae5d65206cbae9cdf2983138656269") {
573
- for (let $i = 0; $i < 2; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
574
- $[0] = "f9b02b582b5a25eab6d75eb5816b5bc3afae5d65206cbae9cdf2983138656269";
575
- }
576
- let t0;
577
- if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
578
- t0 = { strict: false };
579
- $[1] = t0;
580
- } else t0 = $[1];
581
- const context = (0, tanstack_exports.useRouteContext)(t0);
582
- if (context.routes === void 0) throw new Error("The router context holds no route map, so no id can be resolved. Pass one to routerOptions.");
583
- return context.routes;
584
- }
585
- /**
586
- * Resolves a reference to a path, through the map the router context holds.
587
- *
588
- * @remarks
589
- * A hook, so the route has to be known while the component renders. Use `useRouteMap` where the
590
- * route is chosen later, such as in the handler of a row a person clicked.
591
- * @param to - A reference to the route, or the bare id one carries.
592
- * @param params - The parameters the path names, typed by the reference where one was given.
593
- * @returns The path, ready to navigate to.
594
- * @throws {@link Error} Where no map is in the router context, where it holds no such id, or where
595
- * a parameter the path names is missing.
596
- */
597
- function useRouteHref(to, params) {
598
- const $ = c(5);
599
- if ($[0] !== "f9b02b582b5a25eab6d75eb5816b5bc3afae5d65206cbae9cdf2983138656269") {
600
- for (let $i = 0; $i < 5; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
601
- $[0] = "f9b02b582b5a25eab6d75eb5816b5bc3afae5d65206cbae9cdf2983138656269";
602
- }
603
- const t0 = useRouteMap();
604
- let t1;
605
- if ($[1] !== params || $[2] !== t0 || $[3] !== to) {
606
- t1 = routeHref(t0, to, params);
607
- $[1] = params;
608
- $[2] = t0;
609
- $[3] = to;
610
- $[4] = t1;
611
- } else t1 = $[4];
612
- return t1;
613
- }
614
- //#endregion
615
- //#region src/link.tsx
796
+ //#region src/root.ts
616
797
  /**
617
- * Links to a route by the id a manifest declared it under.
618
- *
619
- * @remarks
620
- * A declared route is outside the tree an application registered, so `Link` refuses its path at
621
- * compile time. This resolves the id at run time and hands the library a plain string, which is
622
- * the one place in this package where a path is not checked by the compiler.
623
- * @param props - The declared id, its parameters, and whatever else the library's `Link` takes.
624
- * @returns An anchor to the resolved path.
798
+ * Builds the root route an application's tree starts from, typed for this design system's context.
625
799
  */
626
- function RouteLink(t0) {
627
- const $ = c(8);
628
- if ($[0] !== "3b765330fa72187c6e8334d53589d37c8de26d61a15e49011148486e2debe539") {
629
- for (let $i = 0; $i < 8; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
630
- $[0] = "3b765330fa72187c6e8334d53589d37c8de26d61a15e49011148486e2debe539";
631
- }
632
- let params;
633
- let rest;
634
- let to;
635
- if ($[1] !== t0) {
636
- ({params, to, ...rest} = t0);
637
- $[1] = t0;
638
- $[2] = params;
639
- $[3] = rest;
640
- $[4] = to;
641
- } else {
642
- params = $[2];
643
- rest = $[3];
644
- to = $[4];
645
- }
646
- const t1 = useRouteHref(to, params);
647
- let t2;
648
- if ($[5] !== rest || $[6] !== t1) {
649
- t2 = /* @__PURE__ */ jsx(tanstack_exports.Link, {
650
- ...rest,
651
- to: t1
652
- });
653
- $[5] = rest;
654
- $[6] = t1;
655
- $[7] = t2;
656
- } else t2 = $[7];
657
- return t2;
658
- }
659
- //#endregion
660
- //#region src/root.ts
661
800
  /**
662
- * Builds a root route whose context holds whatever the application states and the route map.
801
+ * Builds a root route whose context contains whatever the application states and the route map.
663
802
  *
664
803
  * @remarks
665
804
  * Calling the library's `createRootRoute` instead leaves the context typed as empty, and the
@@ -668,22 +807,7 @@ function RouteLink(t0) {
668
807
  * @returns The root route factory, to call with the route's own options.
669
808
  */
670
809
  function createAppRootRoute() {
671
- return (0, tanstack_exports.createRootRouteWithContext)();
672
- }
673
- __reExport(/* @__PURE__ */ __exportAll({
674
- RouteLink: () => RouteLink,
675
- compileRoutes: () => compileRoutes,
676
- createAppRootRoute: () => createAppRootRoute,
677
- declaredOf: () => declaredOf,
678
- namedRoute: () => namedRoute,
679
- routeHref: () => routeHref,
680
- routeMap: () => routeMap,
681
- routerDefaults: () => routerDefaults,
682
- routerOptions: () => routerOptions,
683
- useDeclaredRoute: () => useDeclaredRoute,
684
- useRouteHref: () => useRouteHref,
685
- useRouteMap: () => useRouteMap,
686
- useRouteParams: () => useRouteParams
687
- }), tanstack_exports);
810
+ return createRootRouteWithContext();
811
+ }
688
812
  //#endregion
689
- export { RouteLink, compileRoutes, createAppRootRoute, declaredOf, namedRoute, routeHref, routeMap, routerDefaults, routerOptions, useDeclaredRoute, useRouteHref, useRouteMap, useRouteParams };
813
+ export { Navigate, Outlet, RouteLink, RouterContextProvider, RouterProvider, basepathOf, compileRoutes, createAppRootRoute, createLink, createMemoryHistory, createRootRoute, createRoute, createRouter, declaredOf, isNotFound, isRedirect, namedRoute, notFound, redirect, routeHref, routeMap, routerDefaults, routerOptions, useChildMatches, useDeclaredRoute, useLinkProps, useLocation, useMatches, useNavigate, useRouteContext, useRouteHref, useRouteMap, useRouteParams, useRouteSearch, useRouter, useRouterState };