@thi.ng/router 3.2.62 → 3.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/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-10T13:28:34Z
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,22 @@ 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.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/router@3.4.0) (2024-03-10)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add defMatch() helper ([12134b6](https://github.com/thi-ng/umbrella/commit/12134b6))
17
+
18
+ #### 🩹 Bug fixes
19
+
20
+ - rebuild index in updateRoutes() ([deb494e](https://github.com/thi-ng/umbrella/commit/deb494e))
21
+
22
+ ## [3.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/router@3.3.0) (2024-03-09)
23
+
24
+ #### 🚀 Features
25
+
26
+ - sort & validate routes, add tests ([9243c01](https://github.com/thi-ng/umbrella/commit/9243c01))
27
+
12
28
  ### [3.2.39](https://github.com/thi-ng/umbrella/tree/@thi.ng/router@3.2.39) (2023-11-09)
13
29
 
14
30
  #### ♻️ 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,9 +31,27 @@ 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;
36
38
  protected handleRouteFailure(): boolean;
37
39
  }
40
+ /**
41
+ * Helper function to define a {@link Route.match} array from a string pattern.
42
+ *
43
+ * @example
44
+ * ```ts tangle:../export/def-match.ts
45
+ * import { defMatch } from "@thi.ng/router";
46
+ *
47
+ * console.log(
48
+ * defMatch("/contacts/?id/friends")
49
+ * );
50
+ * // ["contacts", "?id", "friends"]
51
+ * ```
52
+ *
53
+ * @param pattern
54
+ * @param sep
55
+ */
56
+ export declare const defMatch: (pattern: string, sep?: string) => string[];
38
57
  //# sourceMappingURL=basic.d.ts.map
package/basic.js CHANGED
@@ -35,10 +35,7 @@ let BasicRouter = class {
35
35
  removeTrailingSlash: true,
36
36
  ...config
37
37
  };
38
- this.routeIndex = this.config.routes.reduce(
39
- (acc, r) => (acc[r.id] = r, acc),
40
- {}
41
- );
38
+ this.updateRoutes();
42
39
  assert(
43
40
  this.routeForID(this.config.defaultRouteID) !== void 0,
44
41
  `missing config for default route: '${this.config.defaultRouteID}'`
@@ -73,6 +70,10 @@ let BasicRouter = class {
73
70
  this.notify({ id: EVENT_ROUTE_CHANGED, value: this.current });
74
71
  }
75
72
  }
73
+ addRoutes(route) {
74
+ this.config.routes.push(...route);
75
+ this.updateRoutes();
76
+ }
76
77
  /**
77
78
  * Main router function. Attempts to match given input string against all
78
79
  * configured routes. Before returning, triggers {@link EVENT_ROUTE_CHANGED}
@@ -135,6 +136,21 @@ let BasicRouter = class {
135
136
  routeForID(id) {
136
137
  return this.routeIndex[id];
137
138
  }
139
+ updateRoutes() {
140
+ this.config.routes.sort((a, b) => b.length - a.length);
141
+ this.config.routes.reduce((acc, x) => {
142
+ const fmt = x.match.map((y) => isRouteParam(y) ? "*" : y).join("/");
143
+ if (acc[fmt]) {
144
+ illegalArgs(`duplicate route: ${x.match} (id: ${x.id})`);
145
+ }
146
+ acc[fmt] = true;
147
+ return acc;
148
+ }, {});
149
+ this.routeIndex = this.config.routes.reduce(
150
+ (acc, r) => (acc[r.id] = r, acc),
151
+ {}
152
+ );
153
+ }
138
154
  matchRoutes(src) {
139
155
  const routes = this.config.routes;
140
156
  const curr = src.split(this.config.separator);
@@ -187,6 +203,8 @@ BasicRouter = __decorateClass([
187
203
  ], BasicRouter);
188
204
  const isParametricRoute = (route) => route.match.some(isRouteParam);
189
205
  const isRouteParam = (x) => x[0] === "?";
206
+ const defMatch = (pattern, sep = "/") => pattern.split(sep).filter((x) => !!x);
190
207
  export {
191
- BasicRouter
208
+ BasicRouter,
209
+ defMatch
192
210
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/router",
3
- "version": "3.2.62",
3
+ "version": "3.4.0",
4
4
  "description": "Generic router for browser & non-browser based applications",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -92,5 +92,5 @@
92
92
  ],
93
93
  "year": 2014
94
94
  },
95
- "gitHead": "69100942474942f7446ac645d59d91e7dfc352f9\n"
95
+ "gitHead": "c93ab989dd2013dce1a7f7434f42ef3a270b950f\n"
96
96
  }