@openelement/url-pattern-list 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.
package/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2025 Justin Fagnani
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # @openelement/url-pattern-list
2
+
3
+ Efficiently match URL paths against a collection of URL patterns using a
4
+ fixed pathname-literal index with conservative fallback.
5
+
6
+ > **Fork note:** this is the OpenElement-maintained fork of
7
+ > [justinfagnani/url-pattern-list](https://github.com/justinfagnani/url-pattern-list)
8
+ > v0.5.0. See [PROVENANCE.md](./PROVENANCE.md) for sources and license, and
9
+ > [DIVERGENCE.md](./DIVERGENCE.md) for what differs and why.
10
+
11
+ ## Overview
12
+
13
+ `url-pattern-list` is a JavaScript library that provides an efficient way to
14
+ match URLs against multiple
15
+ [URLPattern](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern)
16
+ instances. Instead of testing every pattern linearly, `URLPatternList`
17
+ indexes patterns whose pathname is a canonical literal in a fixed prefix
18
+ tree, keeps all other patterns in a conservative list, and merges both by
19
+ registration order at match time — so only patterns that can possibly match
20
+ are exec'd.
21
+
22
+ `URLPatternList` has exactly the same matching semantics as scanning a
23
+ linear list of patterns, and is differentially tested against such a linear
24
+ oracle for both native and polyfill URLPattern constructors. The first
25
+ pattern (in the order patterns were added to the list) whose complete
26
+ `exec()` matches a URL is returned as the match.
27
+
28
+ Patterns are added to the list along with an additional value that is returned
29
+ with the match. This makes it easy to associate a URLPattern with metadata or an
30
+ object like a server route handler.
31
+
32
+ ## Installation
33
+
34
+ ```sh
35
+ npm i @openelement/url-pattern-list
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ```typescript
41
+ import {URLPatternList} from '@openelement/url-pattern-list';
42
+
43
+ // Create a new pattern list
44
+ const routes = new URLPatternList<string>();
45
+
46
+ // Add patterns with associated values
47
+ routes.addPattern(new URLPattern({pathname: '/api/users/:id'}), 'user-detail');
48
+ routes.addPattern(new URLPattern({pathname: '/api/users'}), 'user-list');
49
+ routes.addPattern(new URLPattern({pathname: '/api/posts/:id'}), 'post-detail');
50
+
51
+ // Match against a URL
52
+ const match = routes.match('/api/users/123');
53
+ if (match) {
54
+ console.log('Route:', match.value); // 'user-detail'
55
+ console.log('User ID:', match.result.pathname.groups.id); // '123'
56
+ }
57
+ ```
58
+
59
+ ## Performance
60
+
61
+ Lookup cost is driven by the number of candidate patterns exec'd, not the
62
+ number of patterns registered: static-heavy workloads exec a handful of
63
+ candidates at any scale, while workloads dominated by non-literal patterns
64
+ (regex, groups, wildcards) degrade gracefully to linear scan. Benchmarks
65
+ cover construction, hit, miss and memory against a linear oracle and
66
+ upstream v0.5.0; see [BENCHMARKS.md](./BENCHMARKS.md) for numbers and
67
+ methodology.
68
+
69
+ To run the benchmark on your machine:
70
+
71
+ ```sh
72
+ npm i --prefix .tmp-upstream url-pattern-list@0.5.0 # optional comparison
73
+ npm run benchmark
74
+ ```
75
+
76
+ ## API Reference
77
+
78
+ ### URLPatternList&lt;T&gt;
79
+
80
+ The main class for managing and matching URL patterns.
81
+
82
+ ```ts
83
+ import {URLPatternList} from '@openelement/url-pattern-list';
84
+ ```
85
+
86
+ #### Methods
87
+
88
+ ##### `addPattern(pattern: ListPattern, value: T): void`
89
+
90
+ Add a URL pattern to the collection with an associated value. `ListPattern`
91
+ is any object with a `pathname` getter and the `exec()` method of the
92
+ URLPattern interface — native `URLPattern` and `urlpattern-polyfill`
93
+ instances both work.
94
+
95
+ ```typescript
96
+ const list = new URLPatternList<RouteHandler>();
97
+ list.addPattern(new URLPattern({pathname: '/users/:id'}), handleUserDetail);
98
+ ```
99
+
100
+ ##### `match(url: string | URL, baseUrl?: string): URLPatternListMatch<T> | null`
101
+
102
+ Match a URL against all patterns, returning the first match found. Relative
103
+ string input requires `baseUrl`; invalid input throws a `TypeError`, even
104
+ for an empty list.
105
+
106
+ ```typescript
107
+ const match = list.match('/users/123', 'https://example.com');
108
+ if (match) {
109
+ // match.result contains the URLPatternResult
110
+ // match.value contains your associated value
111
+ }
112
+ ```
113
+
114
+ ##### `candidateCount(url: string | URL, baseUrl?: string): number`
115
+
116
+ Diagnostic upper bound on how many patterns `match()` would exec for the
117
+ given input. Not part of the matching semantics.
118
+
119
+ ### Types
120
+
121
+ #### URLPatternListMatch&lt;T&gt;
122
+
123
+ ```typescript
124
+ interface URLPatternListMatch<T> {
125
+ result: URLPatternResult; // Standard URLPattern match result
126
+ value: T; // Your associated value
127
+ }
128
+ ```
129
+
130
+ ## Browser Support
131
+
132
+ This library works with any
133
+ [URLPattern](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern)
134
+ implementation you supply — native:
135
+
136
+ - Chrome 95+
137
+ - Firefox 142+ (Preview support)
138
+ - Safari 26.0+ (Preview support)
139
+
140
+ — or the [URLPattern
141
+ polyfill](https://github.com/kenchris/urlpattern-polyfill) (patterns built
142
+ from either constructor can be mixed in one list).
143
+
144
+ ## Visualizer
145
+
146
+ The upstream visualizer was removed in 0.6.0 because it rendered the
147
+ internals of the removed per-component prefix tree. See
148
+ [DIVERGENCE.md](./DIVERGENCE.md).
149
+
150
+ ## Contributing
151
+
152
+ Contributions are welcome! Please feel free to submit a Pull Request.
153
+
154
+ ## License
155
+
156
+ MIT License. See [LICENSE](LICENSE) file for details.
157
+
158
+ ## Related
159
+
160
+ - [URLPattern on
161
+ MDN](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern)
162
+ - [URLPattern Specification](https://urlpattern.spec.whatwg.org/)
163
+ - [URLPattern Polyfill](https://github.com/kenchris/urlpattern-polyfill)
package/index.d.ts ADDED
@@ -0,0 +1,77 @@
1
+ /**
2
+ * url-pattern-list - efficiently match URLs against a collection of URL
3
+ * patterns.
4
+ *
5
+ * This implementation is derived from the semantics OpenElement established
6
+ * for its maintained fork: only canonical pathname literals are indexed, every
7
+ * other pattern is matched conservatively, and candidates are merged by
8
+ * registration order before a full `exec()` decides the match. See
9
+ * PROVENANCE.md and DIVERGENCE.md.
10
+ */
11
+ /**
12
+ * The minimal pattern interface stored by a URLPatternList.
13
+ *
14
+ * Any object with a `pathname` getter and the `exec()` method of the
15
+ * URLPattern interface works: native `URLPattern` instances and
16
+ * polyfill (`urlpattern-polyfill`) instances alike. Pattern parsing,
17
+ * compilation and capture semantics belong entirely to the pattern's
18
+ * constructor; this library only stores, indexes and matches patterns in
19
+ * registration order.
20
+ */
21
+ export interface ListPattern {
22
+ readonly pathname: string;
23
+ exec(input: string, baseURL?: string): URLPatternResult | null;
24
+ }
25
+ /**
26
+ * The return type of `URLPatternList.match()`.
27
+ *
28
+ * Includes the result of `pattern.exec()` and the matching pattern's associated
29
+ * metadata value.
30
+ */
31
+ export interface URLPatternListMatch<T> {
32
+ result: URLPatternResult;
33
+ value: T;
34
+ }
35
+ /**
36
+ * A collection of URL patterns and associated values, with methods for adding
37
+ * patterns and matching URLs against those patterns.
38
+ *
39
+ * Patterns with a canonical pathname literal are stored in a fixed prefix tree
40
+ * keyed by that literal; all other patterns are stored in a conservative list.
41
+ * Matching execs the candidates of both collections in registration order and
42
+ * returns the first complete match. This maintains first-match-wins
43
+ * semantics - the result is the same as scanning a linear list of patterns -
44
+ * while only execing the patterns that can possibly match.
45
+ *
46
+ * Pruning is based solely on canonical pathname literal equality, which is a
47
+ * necessary condition for `exec()` to match. Pruning never involves other URL
48
+ * components, so empty URL components never disappear from matching and the
49
+ * final `exec()` sees every pattern that could match.
50
+ */
51
+ export declare class URLPatternList<T> {
52
+ #private;
53
+ /**
54
+ * Add a URL pattern to the collection.
55
+ */
56
+ addPattern(pattern: ListPattern, value: T): void;
57
+ /**
58
+ * Match a URL against the URLPatterns, returning the first match found and
59
+ * its associated value.
60
+ *
61
+ * The input is normalized once with the `URL` constructor and both pruning
62
+ * and `exec()` consume the same normalized URL. Invalid input throws a
63
+ * `TypeError`, including for an empty list; relative string input requires a
64
+ * `baseUrl`.
65
+ *
66
+ * @param url - The URL to match
67
+ * @param baseUrl - Optional base URL for relative path resolution
68
+ */
69
+ match(url: string | URL, baseUrl?: string): URLPatternListMatch<T> | null;
70
+ /**
71
+ * Diagnostic upper bound on the number of patterns that `match()` would
72
+ * exec for the given input. Not part of the matching semantics; no matcher
73
+ * internals are exposed.
74
+ */
75
+ candidateCount(url: string | URL, baseUrl?: string): number;
76
+ }
77
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;CAChE;AAaD;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC;CACV;AAwCD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,cAAc,CAAC,CAAC;;IAK3B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAqChD;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI;IAwCzE;;;;OAIG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM;CAI5D"}
package/index.js ADDED
@@ -0,0 +1,160 @@
1
+ /**
2
+ * url-pattern-list - efficiently match URLs against a collection of URL
3
+ * patterns.
4
+ *
5
+ * This implementation is derived from the semantics OpenElement established
6
+ * for its maintained fork: only canonical pathname literals are indexed, every
7
+ * other pattern is matched conservatively, and candidates are merged by
8
+ * registration order before a full `exec()` decides the match. See
9
+ * PROVENANCE.md and DIVERGENCE.md.
10
+ */
11
+ /**
12
+ * A node in the fixed pathname prefix tree. Each node holds the patterns whose
13
+ * canonical pathname literal ends exactly at this node.
14
+ */
15
+ class FixedPrefixTreeNode {
16
+ children = new Map();
17
+ patterns = [];
18
+ }
19
+ /**
20
+ * Returns the index key for a pattern pathname, or `undefined` if the pathname
21
+ * is not a canonical literal.
22
+ *
23
+ * This is deliberately a small literal alphabet, not a URLPattern grammar
24
+ * parser. These characters have no pattern operators or escapes. Every other
25
+ * spelling remains conservative, including groups, regex, empty paths and
26
+ * Unicode.
27
+ *
28
+ * ASCII case folding over-selects candidates for case-sensitive patterns and
29
+ * admits ignoreCase patterns without relying on a non-standard URLPattern
30
+ * options getter; `exec()` still determines the real case semantics.
31
+ */
32
+ const literalPathnameKey = (pathname) => {
33
+ if (!pathname.startsWith('/')) {
34
+ return undefined;
35
+ }
36
+ for (const char of pathname) {
37
+ if (!'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/_-.%~'.includes(char)) {
38
+ return undefined;
39
+ }
40
+ }
41
+ return pathname.toLowerCase();
42
+ };
43
+ /**
44
+ * A collection of URL patterns and associated values, with methods for adding
45
+ * patterns and matching URLs against those patterns.
46
+ *
47
+ * Patterns with a canonical pathname literal are stored in a fixed prefix tree
48
+ * keyed by that literal; all other patterns are stored in a conservative list.
49
+ * Matching execs the candidates of both collections in registration order and
50
+ * returns the first complete match. This maintains first-match-wins
51
+ * semantics - the result is the same as scanning a linear list of patterns -
52
+ * while only execing the patterns that can possibly match.
53
+ *
54
+ * Pruning is based solely on canonical pathname literal equality, which is a
55
+ * necessary condition for `exec()` to match. Pruning never involves other URL
56
+ * components, so empty URL components never disappear from matching and the
57
+ * final `exec()` sees every pattern that could match.
58
+ */
59
+ export class URLPatternList {
60
+ #root = new FixedPrefixTreeNode();
61
+ #conservative = [];
62
+ #sequenceCounter = 0;
63
+ /**
64
+ * Add a URL pattern to the collection.
65
+ */
66
+ addPattern(pattern, value) {
67
+ const item = {
68
+ sequence: this.#sequenceCounter++,
69
+ pattern,
70
+ value,
71
+ };
72
+ const key = literalPathnameKey(pattern.pathname);
73
+ if (key === undefined) {
74
+ this.#conservative.push(item);
75
+ return;
76
+ }
77
+ let node = this.#root;
78
+ for (const char of key) {
79
+ let child = node.children.get(char);
80
+ if (child === undefined) {
81
+ child = new FixedPrefixTreeNode();
82
+ node.children.set(char, child);
83
+ }
84
+ node = child;
85
+ }
86
+ node.patterns.push(item);
87
+ }
88
+ /**
89
+ * The patterns whose canonical pathname literal equals the URL's pathname.
90
+ */
91
+ #fixedCandidates(url) {
92
+ let node = this.#root;
93
+ for (const char of url.pathname.toLowerCase()) {
94
+ node = node.children.get(char);
95
+ if (node === undefined) {
96
+ return [];
97
+ }
98
+ }
99
+ return node.patterns;
100
+ }
101
+ /**
102
+ * Match a URL against the URLPatterns, returning the first match found and
103
+ * its associated value.
104
+ *
105
+ * The input is normalized once with the `URL` constructor and both pruning
106
+ * and `exec()` consume the same normalized URL. Invalid input throws a
107
+ * `TypeError`, including for an empty list; relative string input requires a
108
+ * `baseUrl`.
109
+ *
110
+ * @param url - The URL to match
111
+ * @param baseUrl - Optional base URL for relative path resolution
112
+ */
113
+ match(url, baseUrl) {
114
+ const normalized = new URL(String(url), baseUrl);
115
+ const fullURL = normalized.href;
116
+ const fixed = this.#fixedCandidates(normalized);
117
+ // Merge the fixed-tree candidates and the conservative candidates by
118
+ // original sequence, so the first complete exec match in registration
119
+ // order wins. Both arrays are already sorted by sequence.
120
+ let fixedIndex = 0;
121
+ let conservativeIndex = 0;
122
+ while (fixedIndex < fixed.length ||
123
+ conservativeIndex < this.#conservative.length) {
124
+ let item;
125
+ if (fixedIndex >= fixed.length) {
126
+ item = this.#conservative[conservativeIndex++];
127
+ }
128
+ else if (conservativeIndex >= this.#conservative.length) {
129
+ item = fixed[fixedIndex++];
130
+ }
131
+ else if (fixed[fixedIndex].sequence <
132
+ this.#conservative[conservativeIndex].sequence) {
133
+ item = fixed[fixedIndex++];
134
+ }
135
+ else {
136
+ item = this.#conservative[conservativeIndex++];
137
+ }
138
+ // Pass baseUrl through to exec like upstream did, so the result's
139
+ // `inputs` reflect the caller's arguments. The normalized URL is
140
+ // absolute, so the base never changes whether exec matches.
141
+ const result = baseUrl === undefined
142
+ ? item.pattern.exec(fullURL)
143
+ : item.pattern.exec(fullURL, baseUrl);
144
+ if (result !== null) {
145
+ return { result, value: item.value };
146
+ }
147
+ }
148
+ return null;
149
+ }
150
+ /**
151
+ * Diagnostic upper bound on the number of patterns that `match()` would
152
+ * exec for the given input. Not part of the matching semantics; no matcher
153
+ * internals are exposed.
154
+ */
155
+ candidateCount(url, baseUrl) {
156
+ const normalized = new URL(String(url), baseUrl);
157
+ return this.#fixedCandidates(normalized).length + this.#conservative.length;
158
+ }
159
+ }
160
+ //# sourceMappingURL=index.js.map
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@openelement/url-pattern-list",
3
+ "version": "0.6.0",
4
+ "description": "Efficiently match URLs against a collection of URL patterns",
5
+ "type": "module",
6
+ "main": "index.js",
7
+ "scripts": {
8
+ "build": "wireit",
9
+ "test": "wireit",
10
+ "benchmark": "wireit",
11
+ "format": "npm run format:fix",
12
+ "format:check": "prettier \"**/*.{cjs,html,js,json,md,ts}\" --check",
13
+ "format:fix": "prettier \"**/*.{cjs,html,js,json,md,ts}\" --write"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/open-element/url-pattern-list.git"
18
+ },
19
+ "keywords": [
20
+ "url",
21
+ "urlpattern",
22
+ "url-pattern"
23
+ ],
24
+ "author": "Justin Fagnani <justin@fagnani.com>",
25
+ "license": "MIT",
26
+ "bugs": {
27
+ "url": "https://github.com/open-element/url-pattern-list/issues"
28
+ },
29
+ "homepage": "https://github.com/open-element/url-pattern-list#readme",
30
+ "devDependencies": {
31
+ "@types/node": "^24.2.0",
32
+ "prettier": "^3.6.2",
33
+ "prettier-plugin-curly": "^0.3.2",
34
+ "typescript": "^5.9.2",
35
+ "urlpattern-polyfill": "^10.1.0",
36
+ "wireit": "^0.14.12"
37
+ },
38
+ "files": [
39
+ "index.js",
40
+ "index.d.ts",
41
+ "index.js.map",
42
+ "index.d.ts.map"
43
+ ],
44
+ "exports": {
45
+ ".": {
46
+ "types": "./index.d.ts",
47
+ "default": "./index.js"
48
+ }
49
+ },
50
+ "wireit": {
51
+ "build": {
52
+ "command": "tsc --build",
53
+ "files": [
54
+ "tsconfig.json",
55
+ "src/**/*.ts"
56
+ ],
57
+ "outputs": [
58
+ "index.{js,d.ts,js.map,d.ts.map}"
59
+ ],
60
+ "clean": "if-file-deleted"
61
+ },
62
+ "test": {
63
+ "command": "node --enable-source-maps --test --test-reporter=spec \"test/**/*_test.js\"",
64
+ "dependencies": [
65
+ "build"
66
+ ],
67
+ "files": [],
68
+ "output": []
69
+ },
70
+ "benchmark": {
71
+ "command": "node --expose-gc --enable-source-maps benchmark/benchmark.js",
72
+ "dependencies": [
73
+ "build"
74
+ ],
75
+ "files": [],
76
+ "output": []
77
+ }
78
+ }
79
+ }