@thi.ng/router 3.3.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/basic.js CHANGED
@@ -15,45 +15,37 @@ import { equiv } from "@thi.ng/equiv";
15
15
  import { assert } from "@thi.ng/errors/assert";
16
16
  import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
17
17
  import { illegalArity } from "@thi.ng/errors/illegal-arity";
18
+ import { illegalState } from "@thi.ng/errors/illegal-state";
18
19
  import {
19
20
  EVENT_ROUTE_CHANGED,
20
21
  EVENT_ROUTE_FAILED
21
22
  } from "./api.js";
23
+ import { Trie } from "./trie.js";
22
24
  let BasicRouter = class {
23
- config;
25
+ opts;
24
26
  current;
25
- routeIndex;
27
+ index = {};
28
+ routes = new Trie();
26
29
  constructor(config) {
27
- this.config = {
28
- authenticator: (route, _, params) => ({
29
- id: route.id,
30
- title: route.title,
31
- params
32
- }),
30
+ this.opts = {
31
+ authenticator: (match) => match,
33
32
  prefix: "/",
34
33
  separator: "/",
35
- removeTrailingSlash: true,
34
+ trim: true,
36
35
  ...config
37
36
  };
38
- this.updateRoutes();
39
- this.routeIndex = this.config.routes.reduce(
40
- (acc, r) => (acc[r.id] = r, acc),
41
- {}
42
- );
37
+ this.addRoutes(this.opts.routes);
43
38
  assert(
44
- this.routeForID(this.config.defaultRouteID) !== void 0,
45
- `missing config for default route: '${this.config.defaultRouteID}'`
39
+ this.routeForID(this.opts.default) !== void 0,
40
+ `missing config for default route: '${this.opts.default}'`
46
41
  );
47
- if (config.initialRouteID) {
48
- const route = this.routeForID(config.initialRouteID);
42
+ if (config.initial) {
43
+ const route = this.routeForID(config.initial);
49
44
  assert(
50
45
  route !== void 0,
51
- `missing config for initial route: ${this.config.initialRouteID}`
52
- );
53
- assert(
54
- !isParametricRoute(route),
55
- "initial route MUST not be parametric"
46
+ `missing config for initial route: ${this.opts.initial}`
56
47
  );
48
+ assert(!route.params, "initial route MUST not be parametric");
57
49
  }
58
50
  }
59
51
  // @ts-ignore: arguments
@@ -68,15 +60,24 @@ let BasicRouter = class {
68
60
  notify(event) {
69
61
  }
70
62
  start() {
71
- if (this.config.initialRouteID) {
72
- const route = this.routeForID(this.config.initialRouteID);
73
- this.current = { id: route.id, title: route.title, params: {} };
63
+ if (this.opts.initial) {
64
+ const route = this.routeForID(this.opts.initial);
65
+ this.current = { id: route.id, params: {} };
74
66
  this.notify({ id: EVENT_ROUTE_CHANGED, value: this.current });
75
67
  }
76
68
  }
77
- addRoutes(route) {
78
- this.config.routes.push(...route);
79
- this.updateRoutes();
69
+ addRoutes(routes) {
70
+ for (let r of routes) {
71
+ try {
72
+ const route = this.augmentRoute(r);
73
+ this.routes.set(route.match, route);
74
+ this.index[route.id] = route;
75
+ } catch (e) {
76
+ illegalArgs(
77
+ `error in route "${r.id}": ${e.origMessage}`
78
+ );
79
+ }
80
+ }
80
81
  }
81
82
  /**
82
83
  * Main router function. Attempts to match given input string against all
@@ -85,21 +86,25 @@ let BasicRouter = class {
85
86
  * {@link EVENT_ROUTE_FAILED} and then falls back to configured default
86
87
  * route.
87
88
  *
89
+ * @remarks
90
+ * See {@link RouteAuthenticator} for details about `ctx` handling.
91
+ *
88
92
  * @param src - route path to match
93
+ * @param ctx - arbitrary user context
89
94
  */
90
- route(src) {
91
- if (this.config.removeTrailingSlash && src.charAt(src.length - 1) === this.config.separator) {
95
+ route(src, ctx) {
96
+ if (this.opts.trim && src.charAt(src.length - 1) === this.opts.separator) {
92
97
  src = src.substring(0, src.length - 1);
93
98
  }
94
- src = src.substring(this.config.prefix.length);
95
- let match = this.matchRoutes(src);
99
+ src = src.substring(this.opts.prefix.length);
100
+ let match = this.matchRoutes(src, ctx);
96
101
  if (!match) {
97
102
  this.notify({ id: EVENT_ROUTE_FAILED, value: src });
98
103
  if (!this.handleRouteFailure()) {
99
104
  return;
100
105
  }
101
- const route = this.routeForID(this.config.defaultRouteID);
102
- match = { id: route.id, title: route.title, params: {} };
106
+ const route = this.routeForID(this.opts.default);
107
+ match = { id: route.id, redirect: true };
103
108
  }
104
109
  if (!equiv(match, this.current)) {
105
110
  this.current = match;
@@ -108,9 +113,12 @@ let BasicRouter = class {
108
113
  return match;
109
114
  }
110
115
  format(...args) {
111
- let [id, params] = args;
116
+ let [id, params, rest] = args;
112
117
  let match;
113
118
  switch (args.length) {
119
+ case 3:
120
+ match = { id, params, rest };
121
+ break;
114
122
  case 2:
115
123
  match = { id, params };
116
124
  break;
@@ -122,63 +130,81 @@ let BasicRouter = class {
122
130
  }
123
131
  const route = this.routeForID(match.id);
124
132
  if (route) {
125
- const params2 = match.params || {};
126
- return this.config.prefix + route.match.map((x) => {
133
+ const params2 = match.params;
134
+ let parts = route.match.map((x) => {
127
135
  if (isRouteParam(x)) {
128
136
  const id2 = x.substring(1);
129
- const p = params2[id2];
130
- if (p != null)
131
- return p;
132
- illegalArgs(`missing value for param '${id2}'`);
137
+ const p = params2?.[id2];
138
+ if (p == null) {
139
+ illegalArgs(`missing value for param '${id2}'`);
140
+ }
141
+ return p;
133
142
  }
134
143
  return x;
135
- }).join(this.config.separator);
144
+ });
145
+ if (route.rest >= 0)
146
+ parts = parts.slice(0, route.rest).concat(match.rest || []);
147
+ return this.opts.prefix + parts.join(this.opts.separator);
136
148
  } else {
137
149
  illegalArgs(`invalid route ID: ${match.id}`);
138
150
  }
139
151
  }
140
152
  routeForID(id) {
141
- return this.routeIndex[id];
153
+ return this.index[id];
142
154
  }
143
- updateRoutes() {
144
- this.config.routes.sort((a, b) => b.length - a.length);
145
- this.config.routes.reduce((acc, x) => {
146
- const fmt = x.match.map((y) => isRouteParam(y) ? "*" : y).join("/");
147
- if (acc[fmt]) {
148
- illegalArgs(`duplicate route: ${x.match} (id: ${x.id})`);
155
+ augmentRoute(route) {
156
+ const match = isString(route.match) ? route.match.split(this.opts.separator).filter((x) => !!x) : route.match;
157
+ const existing = this.routes.get(match);
158
+ if (existing) {
159
+ illegalArgs(
160
+ `duplicate route: ${match} (id: ${route.id}, conflicts with: ${existing.id})`
161
+ );
162
+ }
163
+ let hasParams = false;
164
+ const params = match.reduce((acc, x, i) => {
165
+ if (isRouteParam(x)) {
166
+ hasParams = true;
167
+ acc[i] = x.substring(1);
149
168
  }
150
- acc[fmt] = true;
151
169
  return acc;
152
170
  }, {});
171
+ return {
172
+ ...route,
173
+ match,
174
+ params: hasParams ? params : void 0,
175
+ rest: match.indexOf("+")
176
+ };
153
177
  }
154
- matchRoutes(src) {
155
- const routes = this.config.routes;
156
- const curr = src.split(this.config.separator);
157
- for (let i = 0, n = routes.length; i < n; i++) {
158
- const match = this.matchRoute(curr, routes[i]);
159
- if (match) {
160
- return match;
161
- }
178
+ matchRoutes(src, ctx) {
179
+ const curr = src.split(this.opts.separator);
180
+ const route = this.routes.get(curr);
181
+ if (!route)
182
+ return;
183
+ let params;
184
+ if (route.params) {
185
+ params = Object.entries(route.params).reduce(
186
+ (acc, [i, k]) => (acc[k] = curr[+i], acc),
187
+ {}
188
+ );
162
189
  }
163
- }
164
- matchRoute(curr, route) {
165
- const match = route.match;
166
- const n = match.length;
167
- if (curr.length === n) {
168
- const params = {};
169
- for (let i = 0; i < n; i++) {
170
- const m = match[i];
171
- if (isRouteParam(m)) {
172
- params[m.substring(1)] = curr[i];
173
- } else if (curr[i] !== m) {
174
- return;
175
- }
176
- }
177
- if (route.validate && !this.validateRouteParams(params, route.validate)) {
178
- return;
190
+ if (route.validate && !this.validateRouteParams(params, route.validate)) {
191
+ return;
192
+ }
193
+ const rest = route.rest >= 0 ? curr.slice(route.rest) : void 0;
194
+ let match = {
195
+ id: route.id,
196
+ params,
197
+ rest
198
+ };
199
+ if (route.auth) {
200
+ match = this.opts.authenticator(match, route, ctx);
201
+ if (match && !this.index[match.id]) {
202
+ illegalState(
203
+ "auth handler returned invalid route ID: " + match.id
204
+ );
179
205
  }
180
- return route.auth ? this.config.authenticator(route, curr, params) : { id: route.id, title: route.title, params };
181
206
  }
207
+ return match;
182
208
  }
183
209
  validateRouteParams(params, validators) {
184
210
  for (let id in validators) {
@@ -201,7 +227,6 @@ let BasicRouter = class {
201
227
  BasicRouter = __decorateClass([
202
228
  INotifyMixin
203
229
  ], BasicRouter);
204
- const isParametricRoute = (route) => route.match.some(isRouteParam);
205
230
  const isRouteParam = (x) => x[0] === "?";
206
231
  export {
207
232
  BasicRouter
package/history.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { Fn } from "@thi.ng/api";
2
2
  import type { HTMLRouterConfig } from "./api.js";
3
3
  import { BasicRouter } from "./basic.js";
4
- export declare class HTMLRouter extends BasicRouter {
4
+ export declare class HTMLRouter<T = any> extends BasicRouter<T> {
5
5
  protected currentPath: string;
6
6
  protected popHandler: Fn<PopStateEvent, void>;
7
7
  protected hashHandler: EventListener;
@@ -11,16 +11,19 @@ export declare class HTMLRouter extends BasicRouter {
11
11
  start(): void;
12
12
  release(): void;
13
13
  /**
14
- * Like `BasicRouter.route()`, but takes additional arg to control
15
- * if this routing operation should manipulate the browser's `history`.
16
- * If called from userland, this normally is true. However, we want
17
- * to avoid this if called from this router's own event handlers.
14
+ * Like {@link BasicRouter.route}, but takes additional arg to control if
15
+ * this routing operation should manipulate the browser's `history`.
16
+ *
17
+ * @remarks
18
+ * If called from userland, this normally is true (also default). However,
19
+ * we want to avoid this if called from this router's own event handlers.
18
20
  *
19
21
  * @param src -
22
+ * @param ctx -
20
23
  * @param pushState -
21
24
  */
22
- route(src: string, pushState?: boolean): import("./api.js").RouteMatch | undefined;
23
- routeTo(route: string): void;
25
+ route(src: string, ctx?: T, pushState?: boolean): import("./api.js").RouteMatch | undefined;
26
+ routeTo(route: string, ctx?: T): void;
24
27
  protected handlePopChange(): Fn<PopStateEvent, void>;
25
28
  protected handleHashChange(): EventListener;
26
29
  protected handleRouteFailure(): boolean;
package/history.js CHANGED
@@ -16,14 +16,9 @@ class HTMLRouter extends BasicRouter {
16
16
  if (this.useFragment) {
17
17
  window.addEventListener("hashchange", this.handleHashChange());
18
18
  }
19
- if (this.config.initialRouteID) {
20
- const route = this.routeForID(this.config.initialRouteID);
21
- this.route(
22
- this.format({
23
- id: route.id,
24
- title: route.title
25
- })
26
- );
19
+ if (this.opts.initial) {
20
+ const route = this.routeForID(this.opts.initial);
21
+ this.route(this.format({ id: route.id }));
27
22
  } else {
28
23
  this.route(this.useFragment ? location.hash : location.pathname);
29
24
  }
@@ -35,39 +30,39 @@ class HTMLRouter extends BasicRouter {
35
30
  }
36
31
  }
37
32
  /**
38
- * Like `BasicRouter.route()`, but takes additional arg to control
39
- * if this routing operation should manipulate the browser's `history`.
40
- * If called from userland, this normally is true. However, we want
41
- * to avoid this if called from this router's own event handlers.
33
+ * Like {@link BasicRouter.route}, but takes additional arg to control if
34
+ * this routing operation should manipulate the browser's `history`.
35
+ *
36
+ * @remarks
37
+ * If called from userland, this normally is true (also default). However,
38
+ * we want to avoid this if called from this router's own event handlers.
42
39
  *
43
40
  * @param src -
41
+ * @param ctx -
44
42
  * @param pushState -
45
43
  */
46
- route(src, pushState = true) {
44
+ route(src, ctx, pushState = true) {
47
45
  const old = this.current;
48
- const route = super.route(src);
46
+ const route = super.route(src, ctx);
49
47
  if (route && !equiv(route, old)) {
50
48
  this.currentPath = this.format(route);
51
49
  if (pushState) {
52
- history.pushState(
53
- this.currentPath,
54
- route.title || window.document.title || "",
55
- this.currentPath
56
- );
50
+ history.pushState(this.currentPath, "", this.currentPath);
57
51
  }
58
52
  }
59
53
  return route;
60
54
  }
61
- routeTo(route) {
55
+ routeTo(route, ctx) {
62
56
  if (this.useFragment) {
63
57
  location.hash = route;
64
58
  }
65
- this.route(route);
59
+ this.route(route, ctx);
66
60
  }
67
61
  handlePopChange() {
68
62
  return this.popHandler = this.popHandler || ((e) => {
69
63
  this.route(
70
64
  e.state || (this.useFragment ? location.hash : location.pathname),
65
+ void 0,
71
66
  false
72
67
  );
73
68
  }).bind(this);
@@ -77,7 +72,7 @@ class HTMLRouter extends BasicRouter {
77
72
  if (!this.ignoreHashChange) {
78
73
  const hash = e.newURL.substring(e.newURL.indexOf("#"));
79
74
  if (hash !== this.currentPath) {
80
- this.route(hash, false);
75
+ this.route(hash, void 0, false);
81
76
  }
82
77
  }
83
78
  }).bind(this);
@@ -85,7 +80,7 @@ class HTMLRouter extends BasicRouter {
85
80
  handleRouteFailure() {
86
81
  this.ignoreHashChange = true;
87
82
  location.hash = this.format({
88
- id: this.routeForID(this.config.defaultRouteID).id
83
+ id: this.routeForID(this.opts.default).id
89
84
  });
90
85
  this.ignoreHashChange = false;
91
86
  return true;
package/html.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ import type { Fn } from "@thi.ng/api";
2
+ import type { HTMLRouterOpts } from "./api.js";
3
+ import { Router } from "./router.js";
4
+ export declare class HTMLRouter<T = any> extends Router<T> {
5
+ protected currentPath: string;
6
+ protected popHandler: Fn<PopStateEvent, void>;
7
+ protected hashHandler: EventListener;
8
+ protected useFragment: boolean;
9
+ protected ignoreHashChange: boolean;
10
+ constructor(config: HTMLRouterOpts);
11
+ start(): void;
12
+ release(): void;
13
+ /**
14
+ * Like {@link Router.route}, but takes additional arg to control if
15
+ * this routing operation should manipulate the browser's `history`.
16
+ *
17
+ * @remarks
18
+ * If called from userland, this normally is true (also default). However,
19
+ * we want to avoid this if called from this router's own event handlers.
20
+ *
21
+ * @param src -
22
+ * @param ctx -
23
+ * @param pushState -
24
+ */
25
+ route(src: string, ctx?: T, pushState?: boolean): import("./api.js").RouteMatch | undefined;
26
+ routeTo(route: string, ctx?: T): void;
27
+ protected handlePopChange(): Fn<PopStateEvent, void>;
28
+ protected handleHashChange(): EventListener;
29
+ protected handleRouteFailure(): boolean;
30
+ }
31
+ //# sourceMappingURL=html.d.ts.map
package/html.js ADDED
@@ -0,0 +1,91 @@
1
+ import { equiv } from "@thi.ng/equiv";
2
+ import { Router } from "./router.js";
3
+ class HTMLRouter extends Router {
4
+ currentPath;
5
+ popHandler;
6
+ hashHandler;
7
+ useFragment;
8
+ ignoreHashChange;
9
+ constructor(config) {
10
+ super({ prefix: config.useFragment ? "#/" : "/", ...config });
11
+ this.useFragment = config.useFragment !== false;
12
+ this.ignoreHashChange = false;
13
+ }
14
+ start() {
15
+ window.addEventListener("popstate", this.handlePopChange());
16
+ if (this.useFragment) {
17
+ window.addEventListener("hashchange", this.handleHashChange());
18
+ }
19
+ if (this.opts.initial) {
20
+ const route = this.routeForID(this.opts.initial);
21
+ this.route(this.format({ id: route.id }));
22
+ } else {
23
+ this.route(this.useFragment ? location.hash : location.pathname);
24
+ }
25
+ }
26
+ release() {
27
+ window.removeEventListener("popstate", this.popHandler);
28
+ if (this.useFragment) {
29
+ window.removeEventListener("hashchange", this.hashHandler);
30
+ }
31
+ }
32
+ /**
33
+ * Like {@link Router.route}, but takes additional arg to control if
34
+ * this routing operation should manipulate the browser's `history`.
35
+ *
36
+ * @remarks
37
+ * If called from userland, this normally is true (also default). However,
38
+ * we want to avoid this if called from this router's own event handlers.
39
+ *
40
+ * @param src -
41
+ * @param ctx -
42
+ * @param pushState -
43
+ */
44
+ route(src, ctx, pushState = true) {
45
+ const old = this.current;
46
+ const route = super.route(src, ctx);
47
+ if (route && !equiv(route, old)) {
48
+ this.currentPath = this.format(route);
49
+ if (pushState) {
50
+ history.pushState(this.currentPath, "", this.currentPath);
51
+ }
52
+ }
53
+ return route;
54
+ }
55
+ routeTo(route, ctx) {
56
+ if (this.useFragment) {
57
+ location.hash = route;
58
+ }
59
+ this.route(route, ctx);
60
+ }
61
+ handlePopChange() {
62
+ return this.popHandler = this.popHandler || ((e) => {
63
+ this.route(
64
+ e.state || (this.useFragment ? location.hash : location.pathname),
65
+ void 0,
66
+ false
67
+ );
68
+ }).bind(this);
69
+ }
70
+ handleHashChange() {
71
+ return this.hashHandler = this.hashHandler || ((e) => {
72
+ if (!this.ignoreHashChange) {
73
+ const hash = e.newURL.substring(e.newURL.indexOf("#"));
74
+ if (hash !== this.currentPath) {
75
+ this.route(hash, void 0, false);
76
+ }
77
+ }
78
+ }).bind(this);
79
+ }
80
+ handleRouteFailure() {
81
+ this.ignoreHashChange = true;
82
+ location.hash = this.format({
83
+ id: this.routeForID(this.opts.default).id
84
+ });
85
+ this.ignoreHashChange = false;
86
+ return true;
87
+ }
88
+ }
89
+ export {
90
+ HTMLRouter
91
+ };
package/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./api.js";
2
- export * from "./basic.js";
3
- export * from "./history.js";
2
+ export * from "./html.js";
3
+ export * from "./router.js";
4
+ export * from "./trie.js";
4
5
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from "./api.js";
2
- export * from "./basic.js";
3
- export * from "./history.js";
2
+ export * from "./html.js";
3
+ export * from "./router.js";
4
+ export * from "./trie.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@thi.ng/router",
3
- "version": "3.3.0",
4
- "description": "Generic router for browser & non-browser based applications",
3
+ "version": "4.0.0",
4
+ "description": "Generic trie-based router with support for wildcards, route param validation/coercion, auth",
5
5
  "type": "module",
6
6
  "module": "./index.js",
7
7
  "typings": "./index.d.ts",
@@ -36,18 +36,18 @@
36
36
  "tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
37
37
  },
38
38
  "dependencies": {
39
- "@thi.ng/api": "^8.9.29",
40
- "@thi.ng/checks": "^3.5.2",
41
- "@thi.ng/equiv": "^2.1.51",
42
- "@thi.ng/errors": "^2.4.20",
39
+ "@thi.ng/api": "^8.9.30",
40
+ "@thi.ng/checks": "^3.5.3",
41
+ "@thi.ng/equiv": "^2.1.52",
42
+ "@thi.ng/errors": "^2.5.0",
43
43
  "tslib": "^2.6.2"
44
44
  },
45
45
  "devDependencies": {
46
- "@microsoft/api-extractor": "^7.40.1",
47
- "esbuild": "^0.20.0",
46
+ "@microsoft/api-extractor": "^7.42.3",
47
+ "esbuild": "^0.20.1",
48
48
  "rimraf": "^5.0.5",
49
- "typedoc": "^0.25.7",
50
- "typescript": "^5.3.3"
49
+ "typedoc": "^0.25.12",
50
+ "typescript": "^5.4.2"
51
51
  },
52
52
  "keywords": [
53
53
  "browser",
@@ -56,10 +56,13 @@
56
56
  "history",
57
57
  "html",
58
58
  "parametric",
59
+ "pattern",
59
60
  "router",
61
+ "trie",
60
62
  "typescript",
61
63
  "ui",
62
- "validate"
64
+ "validate",
65
+ "wildcards"
63
66
  ],
64
67
  "publishConfig": {
65
68
  "access": "public"
@@ -78,11 +81,14 @@
78
81
  "./api": {
79
82
  "default": "./api.js"
80
83
  },
81
- "./basic": {
82
- "default": "./basic.js"
84
+ "./html": {
85
+ "default": "./html.js"
83
86
  },
84
- "./history": {
85
- "default": "./history.js"
87
+ "./router": {
88
+ "default": "./router.js"
89
+ },
90
+ "./trie": {
91
+ "default": "./trie.js"
86
92
  }
87
93
  },
88
94
  "thi.ng": {
@@ -92,5 +98,5 @@
92
98
  ],
93
99
  "year": 2014
94
100
  },
95
- "gitHead": "940dfa3d8157860608e7ee5d1230bd11d3630866\n"
101
+ "gitHead": "7f3fcbd6c0462b0ce45afa141fe163d1f297fd51\n"
96
102
  }
package/router.d.ts ADDED
@@ -0,0 +1,46 @@
1
+ import type { Event, INotify, IObjectOf, Listener, SomeRequired } from "@thi.ng/api";
2
+ import { type AugmentedRoute, type Route, type RouteMatch, type RouteParamValidator, type RouterEventType, type RouterOpts } from "./api.js";
3
+ import { Trie } from "./trie.js";
4
+ export declare class Router<T = any> implements INotify<RouterEventType> {
5
+ opts: RouterOpts<T>;
6
+ current: RouteMatch | undefined;
7
+ protected index: Record<string, AugmentedRoute>;
8
+ protected routes: Trie<AugmentedRoute>;
9
+ constructor(config: RouterOpts<T>);
10
+ addListener(id: RouterEventType, fn: Listener<RouterEventType>, scope?: any): boolean;
11
+ removeListener(id: RouterEventType, fn: Listener<RouterEventType>, scope?: any): boolean;
12
+ notify(event: Event<RouterEventType>): boolean;
13
+ start(): void;
14
+ addRoutes(routes: Route[]): void;
15
+ /**
16
+ * Main router function. Attempts to match given input string against all
17
+ * configured routes. Before returning, triggers {@link EVENT_ROUTE_CHANGED}
18
+ * with return value as well. If none of the routes matches, emits
19
+ * {@link EVENT_ROUTE_FAILED} and then falls back to configured default
20
+ * route.
21
+ *
22
+ * @remarks
23
+ * See {@link RouteAuthenticator} for details about `ctx` handling.
24
+ *
25
+ * @param src - route path to match
26
+ * @param ctx - arbitrary user context
27
+ */
28
+ route(src: string, ctx?: T): RouteMatch | undefined;
29
+ /**
30
+ * Returns a formatted version of given {@link RouteMatch}, incl. any
31
+ * params, or alternatively a registered route ID (and optional route
32
+ * params). Throws an error if an invalid route `id` is provided.
33
+ *
34
+ * @param id -
35
+ * @param params -
36
+ * @param rest -
37
+ */
38
+ format(id: string, params?: any, rest?: string[]): string;
39
+ format(match: SomeRequired<RouteMatch, "id">): string;
40
+ routeForID(id: string): AugmentedRoute | undefined;
41
+ protected augmentRoute(route: Route): AugmentedRoute;
42
+ protected matchRoutes(src: string, ctx?: T): RouteMatch | undefined;
43
+ protected validateRouteParams(params: any, validators: IObjectOf<Partial<RouteParamValidator>>): boolean;
44
+ protected handleRouteFailure(): boolean;
45
+ }
46
+ //# sourceMappingURL=router.d.ts.map