@thi.ng/router 3.2.61 → 3.3.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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2024-03-07T20:40:47Z
3
+ - **Last updated**: 2024-03-09T16:05:59Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,12 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [3.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/router@3.3.0) (2024-03-09)
13
+
14
+ #### 🚀 Features
15
+
16
+ - sort & validate routes, add tests ([9243c01](https://github.com/thi-ng/umbrella/commit/9243c01))
17
+
12
18
  ### [3.2.39](https://github.com/thi-ng/umbrella/tree/@thi.ng/router@3.2.39) (2023-11-09)
13
19
 
14
20
  #### ♻️ Refactoring
package/README.md CHANGED
@@ -72,7 +72,7 @@ For Node.js REPL:
72
72
  const router = await import("@thi.ng/router");
73
73
  ```
74
74
 
75
- Package sizes (brotli'd, pre-treeshake): ESM: 1.57 KB
75
+ Package sizes (brotli'd, pre-treeshake): ESM: 1.66 KB
76
76
 
77
77
  ## Dependencies
78
78
 
@@ -96,7 +96,7 @@ directory is using this package:
96
96
 
97
97
  [Generated API docs](https://docs.thi.ng/umbrella/router/)
98
98
 
99
- ```ts
99
+ ```ts tangle:export/readme.ts
100
100
  import { HTMLRouter, EVENT_ROUTE_CHANGED } from "@thi.ng/router";
101
101
 
102
102
  // router configuration
@@ -120,9 +120,8 @@ const config = {
120
120
  prefix: "#/",
121
121
 
122
122
  // actual route defs
123
- // these are checked in given order
124
- // IMPORTANT: rules with common prefixes MUST be specified in
125
- // order of highest precision / longest path
123
+ // An array of route specs which route input strings will be matched
124
+ // against. Routes will be sorted from longest to shortest.
126
125
  routes: [
127
126
  {
128
127
  // each route MUST have an ID
package/api.d.ts CHANGED
@@ -92,8 +92,8 @@ export interface RouteMatch extends IID<string> {
92
92
  */
93
93
  export interface RouterConfig {
94
94
  /**
95
- * An array of route specs, which are being attempted to be matched in order
96
- * of appearance.
95
+ * An array of route specs which route input strings will be matched
96
+ * against. Routes will be sorted from longest to shortest.
97
97
  */
98
98
  routes: Route[];
99
99
  /**
package/basic.d.ts CHANGED
@@ -9,6 +9,7 @@ export declare class BasicRouter implements INotify<RouterEventType> {
9
9
  removeListener(id: RouterEventType, fn: Listener<RouterEventType>, scope?: any): boolean;
10
10
  notify(event: Event<RouterEventType>): boolean;
11
11
  start(): void;
12
+ addRoutes(route: Route[]): void;
12
13
  /**
13
14
  * Main router function. Attempts to match given input string against all
14
15
  * configured routes. Before returning, triggers {@link EVENT_ROUTE_CHANGED}
@@ -30,6 +31,7 @@ export declare class BasicRouter implements INotify<RouterEventType> {
30
31
  format(id: string, params?: any): string;
31
32
  format(match: Partial<RouteMatch>): string;
32
33
  routeForID(id: string): Route | undefined;
34
+ protected updateRoutes(): void;
33
35
  protected matchRoutes(src: string): RouteMatch | undefined;
34
36
  protected matchRoute(curr: string[], route: Route): RouteMatch | undefined;
35
37
  protected validateRouteParams(params: any, validators: IObjectOf<Partial<RouteParamValidator>>): boolean;
package/basic.js CHANGED
@@ -35,6 +35,7 @@ let BasicRouter = class {
35
35
  removeTrailingSlash: true,
36
36
  ...config
37
37
  };
38
+ this.updateRoutes();
38
39
  this.routeIndex = this.config.routes.reduce(
39
40
  (acc, r) => (acc[r.id] = r, acc),
40
41
  {}
@@ -73,6 +74,10 @@ let BasicRouter = class {
73
74
  this.notify({ id: EVENT_ROUTE_CHANGED, value: this.current });
74
75
  }
75
76
  }
77
+ addRoutes(route) {
78
+ this.config.routes.push(...route);
79
+ this.updateRoutes();
80
+ }
76
81
  /**
77
82
  * Main router function. Attempts to match given input string against all
78
83
  * configured routes. Before returning, triggers {@link EVENT_ROUTE_CHANGED}
@@ -135,6 +140,17 @@ let BasicRouter = class {
135
140
  routeForID(id) {
136
141
  return this.routeIndex[id];
137
142
  }
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})`);
149
+ }
150
+ acc[fmt] = true;
151
+ return acc;
152
+ }, {});
153
+ }
138
154
  matchRoutes(src) {
139
155
  const routes = this.config.routes;
140
156
  const curr = src.split(this.config.separator);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/router",
3
- "version": "3.2.61",
3
+ "version": "3.3.0",
4
4
  "description": "Generic router for browser & non-browser based applications",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -36,7 +36,7 @@
36
36
  "tool:tangle": "../../node_modules/.bin/tangle src/**/*.ts"
37
37
  },
38
38
  "dependencies": {
39
- "@thi.ng/api": "^8.9.28",
39
+ "@thi.ng/api": "^8.9.29",
40
40
  "@thi.ng/checks": "^3.5.2",
41
41
  "@thi.ng/equiv": "^2.1.51",
42
42
  "@thi.ng/errors": "^2.4.20",
@@ -92,5 +92,5 @@
92
92
  ],
93
93
  "year": 2014
94
94
  },
95
- "gitHead": "a421058a65ba76608d94129ac29451bfedaf201c\n"
95
+ "gitHead": "940dfa3d8157860608e7ee5d1230bd11d3630866\n"
96
96
  }