lit-navigation-router 0.4.0 → 0.6.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.
@@ -23,50 +23,53 @@ export interface PathRouteConfig extends BaseRouteConfig {
23
23
  path: string;
24
24
  }
25
25
  /**
26
- * A RouteConfig that matches against a given [`URLPattern`](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern)
26
+ * A RouteConfig that matches against a given [`URLPattern`](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern).
27
27
  *
28
- * While `URLPattern` can match against protocols, hostnames, and ports,
29
- * routes will only be checked for matches if they're part of the current
30
- * origin. This means that the pattern is limited to checking `pathname` and
31
- * `search`.
28
+ * Routes are only checked within the current origin, so only `pathname`,
29
+ * `search` and `hash` are matched.
32
30
  */
33
31
  export interface URLPatternRouteConfig extends BaseRouteConfig {
34
32
  pattern: URLPatternLike;
35
33
  }
36
34
  /**
37
- * The part of `URLPattern` this router uses.
38
- *
39
- * Declared structurally rather than referencing the global so the emitted
40
- * `.d.ts` is self-contained: the `/// <reference types="urlpattern-polyfill" />`
41
- * above is not carried into declaration output, and `URLPattern` is not in
42
- * TypeScript's bundled `lib.dom`, so a published package typed against the
43
- * global fails a consumer build with `TS2304: Cannot find name 'URLPattern'`.
44
- * A real `URLPattern` satisfies this, so passing one still type-checks.
35
+ * The part of `URLPattern` this router uses. Structural, not a reference to the
36
+ * global: `URLPattern` is not in TypeScript's `lib.dom`, so typing against it
37
+ * fails a consumer build with `TS2304`.
45
38
  */
46
39
  export interface URLPatternLike {
47
- /**
48
- * The pathname pattern string, as `URLPattern.prototype.pathname` returns
49
- * it. Read to tell a trailing wildcard from any other positional group —
50
- * the groups object alone cannot (see `tailOf`).
51
- */
40
+ /** Read by `tailOf`, which the groups object alone cannot answer. */
52
41
  readonly pathname: string;
53
- test(input: {
54
- pathname: string;
55
- }): boolean;
56
- exec(input: {
57
- pathname: string;
58
- }): {
42
+ /** `'*'` means unconstrained. `Router` gates hash interception on this. */
43
+ readonly hash: string;
44
+ test(input: RouteLocation): boolean;
45
+ exec(input: RouteLocation): {
59
46
  pathname: {
60
47
  groups: {
61
48
  [key: string]: string | undefined;
62
49
  };
63
50
  };
51
+ search: {
52
+ groups: {
53
+ [key: string]: string | undefined;
54
+ };
55
+ };
56
+ hash: {
57
+ groups: {
58
+ [key: string]: string | undefined;
59
+ };
60
+ };
64
61
  } | null;
65
62
  }
66
63
  /**
67
- * A description of a route, which path or pattern to match against, and a
68
- * render() callback used to render a match to the outlet.
64
+ * The parts of a location this router matches against. `search` and `hash`
65
+ * carry no leading `?` or `#`: a real `URLPattern` canonicalises either form
66
+ * away, but `URLPatternLike` admits implementations that do not.
69
67
  */
68
+ export interface RouteLocation {
69
+ pathname: string;
70
+ search: string;
71
+ hash: string;
72
+ }
70
73
  export type RouteConfig = PathRouteConfig | URLPatternRouteConfig;
71
74
  /**
72
75
  * A reactive controller that performs location-based routing using a
@@ -74,13 +77,14 @@ export type RouteConfig = PathRouteConfig | URLPatternRouteConfig;
74
77
  */
75
78
  export declare class Routes implements ReactiveController {
76
79
  private readonly _host;
80
+ /**
81
+ * The installed routes, in precedence order. Mutable, but mutating it starts
82
+ * no route transition; call `goto()` if a different route now matches.
83
+ */
77
84
  routes: Array<RouteConfig>;
78
85
  /**
79
- * A default fallback route which will always be matched if none of the
80
- * {@link routes} match. Behaves like a `/*` route: `params[0]` is the whole
81
- * pathname minus its leading slash, and is handed to child controllers as
82
- * their tail. A nested controller's own pathname is a tail, with no leading
83
- * slash; the fallback accepts that too.
86
+ * Matched when no route in {@link routes} does. Behaves like `/*`, so
87
+ * `params[0]` is the whole pathname minus any leading slash.
84
88
  */
85
89
  fallback?: BaseRouteConfig;
86
90
  private readonly _childRoutes;
@@ -89,14 +93,13 @@ export declare class Routes implements ReactiveController {
89
93
  private _gotoSeq;
90
94
  private _currentPathname;
91
95
  private _currentTail;
96
+ /** Ambient, not tailed: only the pathname nests. */
97
+ private _currentSearch;
98
+ private _currentHash;
92
99
  private _currentRoute;
93
100
  private _currentParams;
94
- /**
95
- * Callback to call when this controller is disconnected.
96
- *
97
- * It's critical to call this immediately in hostDisconnected so that this
98
- * controller instance doesn't receive a tail match meant for another route.
99
- */
101
+ /** Must run in hostDisconnected, or this controller can receive another
102
+ * route's tail match. */
100
103
  private _onDisconnect;
101
104
  constructor(host: ReactiveControllerHost & HTMLElement, routes: Array<RouteConfig>, options?: {
102
105
  fallback?: BaseRouteConfig;
@@ -107,19 +110,32 @@ export declare class Routes implements ReactiveController {
107
110
  */
108
111
  link(pathname?: string): string;
109
112
  /**
110
- * Navigates this routes controller to `pathname`.
113
+ * A URL for the route named `name`, with `params` substituted into its
114
+ * pattern.
115
+ *
116
+ * Lets a component say which route it means instead of where that route
117
+ * currently lives, so moving a route subtree does not silently break every
118
+ * hardcoded link inside it.
111
119
  *
112
- * This does not navigate parent routes, so it isn't (yet) a general page
113
- * navigation API. It does navigate child routes if pathname matches a
114
- * pattern with a tail wildcard pattern (`/*`).
120
+ * Resolution covers the mounted controller tree: this controller, its
121
+ * ancestors, and any descendant that has rendered. A route in a branch that
122
+ * has not mounted yet is not addressable, because the mapping from a parent
123
+ * route to its child controller only exists once that parent has rendered.
124
+ * An unknown or ambiguous name throws rather than producing a wrong URL.
125
+ */
126
+ linkTo(name: string, params?: {
127
+ [key: string]: string | undefined;
128
+ }): string;
129
+ /**
130
+ * Navigates this controller to `path`, which may carry a search and hash.
131
+ * Navigates child routes but not parent ones, so it is not yet a general page
132
+ * navigation API.
115
133
  *
116
- * Pass `options.signal` to make the navigation abandonable. `enter()` is
117
- * awaited, so a second `goto()` can start — and finish — while the first is
118
- * still resolving its route; without a signal the slower one commits last
119
- * and the outlet ends up on a route the URL has already left. `Router`
120
- * threads `NavigateEvent.signal` through for exactly this reason.
134
+ * `options.signal` makes the navigation abandonable. `enter()` is awaited, so
135
+ * a second `goto()` can finish while the first is still resolving; without a
136
+ * signal the slower one commits last onto a route the URL has left.
121
137
  */
122
- goto(pathname: string, options?: {
138
+ goto(path: string, options?: {
123
139
  signal?: AbortSignal;
124
140
  }): Promise<void>;
125
141
  /**
@@ -133,60 +149,38 @@ export declare class Routes implements ReactiveController {
133
149
  [key: string]: string | undefined;
134
150
  };
135
151
  /**
136
- * Hands a tail match to a child controller. Shared by the propagation loop in
137
- * `goto()` and the late-mount path in `_onRoutesConnected`, so that identical
138
- * input cannot be silent on one and an uncaught global throw on the other.
152
+ * Hands a tail match to a child. Shared by `goto()`'s propagation loop and the
153
+ * late-mount path, so identical input behaves identically on both.
139
154
  *
140
- * A child with no route for the new tail is the expected case, not an error —
141
- * the outgoing branch mid-swap, or a deep link to a path the child cannot
142
- * render. Filtered structurally rather than by swallowing every rejection, so
143
- * a genuine `enter()` rejection still surfaces the way it does upstream.
144
- * Skipping must still supersede: `goto()` is where the counter is bumped, so
145
- * returning without it would leave an in-flight child navigation current,
146
- * free to commit over a URL that has moved on. A parent route with no tail
147
- * at all is the same case: nothing to route, but still something to stand
148
- * down.
149
- *
150
- * No abort signal is threaded through, and the goto is deliberately not
151
- * awaited. The parent commits its own state before children run, so a child
152
- * handed an already-aborted signal stands down with no newer goto() arriving
153
- * to correct it, leaving the nested outlet stuck — reachable, because a
154
- * hash-only navigation aborts the outstanding one without producing a
155
- * replacement. Supersession is the counter's job.
155
+ * A child with no route for the tail is expected, not an error: the outgoing
156
+ * branch mid-swap, or a deep link it cannot render. Filtered structurally so
157
+ * a genuine `enter()` rejection still surfaces. Skipping must still supersede.
156
158
  */
157
159
  private _routeChild;
160
+ /** Invalidate any in-flight `goto()` here without starting a new one. */
161
+ private _supersede;
158
162
  /**
159
- * Invalidate any in-flight `goto()` on this controller without starting a
160
- * new one. Same-class access, so `_gotoSeq` stays private to `Routes`.
163
+ * True when this controller or any below it constrains the hash. `Router`
164
+ * gates fragment-only interception on this, so a pathname-only app keeps
165
+ * native scrolling. Walks children because only the root sees the event.
161
166
  */
162
- private _supersede;
167
+ protected _constrainsHash(seen?: Set<Routes>): boolean;
163
168
  /**
164
- * True when this controller can render `pathname` — i.e. a route matches, or
165
- * a fallback is configured.
166
- *
167
- * `Router` gates interception on this: intercepting a path we cannot render
168
- * commits the URL and then throws out of `goto()`, leaving the address bar
169
- * moved and the outlet stale. Letting the browser handle it instead means a
170
- * server-rendered page, an export endpoint, or a GET form still works.
169
+ * True when this controller can render `path`. `Router` gates interception on
170
+ * this: intercepting what we cannot render commits the URL and then throws,
171
+ * leaving the address bar moved and the outlet stale.
171
172
  */
172
- hasRouteFor(pathname: string): boolean;
173
+ hasRouteFor(path: string): boolean;
173
174
  /**
174
- * Matches `pathname` against the installed routes and returns the first match
175
- * with its parsed parameters, or the fallback's match if one is configured.
176
- *
177
- * One `exec()` per candidate rather than `test()` to select and `exec()` to
178
- * extract: that ran the winning pattern twice, and every caller that wants a
179
- * route wants its params too.
175
+ * The first route matching `location`, or the fallback's match. One `exec()`
176
+ * per candidate; selecting with `test()` first ran the winner twice.
180
177
  */
181
178
  private _match;
182
179
  hostConnected(): void;
183
180
  hostDisconnected(): void;
184
181
  private _onRoutesConnected;
185
182
  }
186
- /**
187
- * This event is fired from Routes controllers when their host is connected to
188
- * announce the child route and potentially connect to a parent routes controller.
189
- */
183
+ /** Announces a Routes controller to its parent when the host connects. */
190
184
  export declare class RoutesConnectedEvent extends Event {
191
185
  static readonly eventName = "lit-routes-connected";
192
186
  readonly routes: Routes;
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"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"}