@tanstack/router-core 1.136.3 → 1.136.5
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/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +2 -0
- package/dist/cjs/index.cjs +0 -5
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -4
- package/dist/cjs/lru-cache.cjs +5 -0
- package/dist/cjs/lru-cache.cjs.map +1 -1
- package/dist/cjs/lru-cache.d.cts +1 -0
- package/dist/cjs/new-process-route-tree.cjs +655 -0
- package/dist/cjs/new-process-route-tree.cjs.map +1 -0
- package/dist/cjs/new-process-route-tree.d.cts +177 -0
- package/dist/cjs/path.cjs +133 -434
- package/dist/cjs/path.cjs.map +1 -1
- package/dist/cjs/path.d.cts +3 -39
- package/dist/cjs/router.cjs +47 -98
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +7 -11
- package/dist/cjs/ssr/constants.cjs.map +1 -1
- package/dist/cjs/ssr/constants.d.cts +1 -0
- package/dist/cjs/ssr/ssr-client.cjs +2 -0
- package/dist/cjs/ssr/ssr-client.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-client.d.cts +4 -1
- package/dist/cjs/ssr/ssr-server.cjs +64 -12
- package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
- package/dist/cjs/ssr/tsrScript.cjs +1 -1
- package/dist/cjs/ssr/tsrScript.cjs.map +1 -1
- package/dist/esm/Matches.d.ts +2 -0
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/index.d.ts +1 -4
- package/dist/esm/index.js +1 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lru-cache.d.ts +1 -0
- package/dist/esm/lru-cache.js +5 -0
- package/dist/esm/lru-cache.js.map +1 -1
- package/dist/esm/new-process-route-tree.d.ts +177 -0
- package/dist/esm/new-process-route-tree.js +655 -0
- package/dist/esm/new-process-route-tree.js.map +1 -0
- package/dist/esm/path.d.ts +3 -39
- package/dist/esm/path.js +133 -434
- package/dist/esm/path.js.map +1 -1
- package/dist/esm/router.d.ts +7 -11
- package/dist/esm/router.js +48 -99
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/ssr/constants.d.ts +1 -0
- package/dist/esm/ssr/constants.js.map +1 -1
- package/dist/esm/ssr/ssr-client.d.ts +4 -1
- package/dist/esm/ssr/ssr-client.js +2 -0
- package/dist/esm/ssr/ssr-client.js.map +1 -1
- package/dist/esm/ssr/ssr-server.js +64 -12
- package/dist/esm/ssr/ssr-server.js.map +1 -1
- package/dist/esm/ssr/tsrScript.js +1 -1
- package/dist/esm/ssr/tsrScript.js.map +1 -1
- package/package.json +1 -1
- package/src/Matches.ts +2 -0
- package/src/index.ts +0 -6
- package/src/lru-cache.ts +6 -0
- package/src/new-process-route-tree.ts +1036 -0
- package/src/path.ts +168 -639
- package/src/router.ts +58 -126
- package/src/ssr/constants.ts +1 -0
- package/src/ssr/ssr-client.ts +10 -1
- package/src/ssr/ssr-server.ts +69 -12
- package/src/ssr/tsrScript.ts +4 -0
- package/dist/cjs/process-route-tree.cjs +0 -144
- package/dist/cjs/process-route-tree.cjs.map +0 -1
- package/dist/cjs/process-route-tree.d.cts +0 -18
- package/dist/esm/process-route-tree.d.ts +0 -18
- package/dist/esm/process-route-tree.js +0 -144
- package/dist/esm/process-route-tree.js.map +0 -1
- package/src/process-route-tree.ts +0 -241
|
@@ -0,0 +1,655 @@
|
|
|
1
|
+
import invariant from "tiny-invariant";
|
|
2
|
+
import { createLRUCache } from "./lru-cache.js";
|
|
3
|
+
import { last } from "./utils.js";
|
|
4
|
+
const SEGMENT_TYPE_PATHNAME = 0;
|
|
5
|
+
const SEGMENT_TYPE_PARAM = 1;
|
|
6
|
+
const SEGMENT_TYPE_WILDCARD = 2;
|
|
7
|
+
const SEGMENT_TYPE_OPTIONAL_PARAM = 3;
|
|
8
|
+
const PARAM_W_CURLY_BRACES_RE = /^([^{]*)\{\$([a-zA-Z_$][a-zA-Z0-9_$]*)\}([^}]*)$/;
|
|
9
|
+
const OPTIONAL_PARAM_W_CURLY_BRACES_RE = /^([^{]*)\{-\$([a-zA-Z_$][a-zA-Z0-9_$]*)\}([^}]*)$/;
|
|
10
|
+
const WILDCARD_W_CURLY_BRACES_RE = /^([^{]*)\{\$\}([^}]*)$/;
|
|
11
|
+
function parseSegment(path, start, output = new Uint16Array(6)) {
|
|
12
|
+
const next = path.indexOf("/", start);
|
|
13
|
+
const end = next === -1 ? path.length : next;
|
|
14
|
+
const part = path.substring(start, end);
|
|
15
|
+
if (!part || !part.includes("$")) {
|
|
16
|
+
output[0] = SEGMENT_TYPE_PATHNAME;
|
|
17
|
+
output[1] = start;
|
|
18
|
+
output[2] = start;
|
|
19
|
+
output[3] = end;
|
|
20
|
+
output[4] = end;
|
|
21
|
+
output[5] = end;
|
|
22
|
+
return output;
|
|
23
|
+
}
|
|
24
|
+
if (part === "$") {
|
|
25
|
+
const total = path.length;
|
|
26
|
+
output[0] = SEGMENT_TYPE_WILDCARD;
|
|
27
|
+
output[1] = start;
|
|
28
|
+
output[2] = start;
|
|
29
|
+
output[3] = total;
|
|
30
|
+
output[4] = total;
|
|
31
|
+
output[5] = total;
|
|
32
|
+
return output;
|
|
33
|
+
}
|
|
34
|
+
if (part.charCodeAt(0) === 36) {
|
|
35
|
+
output[0] = SEGMENT_TYPE_PARAM;
|
|
36
|
+
output[1] = start;
|
|
37
|
+
output[2] = start + 1;
|
|
38
|
+
output[3] = end;
|
|
39
|
+
output[4] = end;
|
|
40
|
+
output[5] = end;
|
|
41
|
+
return output;
|
|
42
|
+
}
|
|
43
|
+
const wildcardBracesMatch = part.match(WILDCARD_W_CURLY_BRACES_RE);
|
|
44
|
+
if (wildcardBracesMatch) {
|
|
45
|
+
const prefix = wildcardBracesMatch[1];
|
|
46
|
+
const pLength = prefix.length;
|
|
47
|
+
output[0] = SEGMENT_TYPE_WILDCARD;
|
|
48
|
+
output[1] = start + pLength;
|
|
49
|
+
output[2] = start + pLength + 1;
|
|
50
|
+
output[3] = start + pLength + 2;
|
|
51
|
+
output[4] = start + pLength + 3;
|
|
52
|
+
output[5] = path.length;
|
|
53
|
+
return output;
|
|
54
|
+
}
|
|
55
|
+
const optionalParamBracesMatch = part.match(OPTIONAL_PARAM_W_CURLY_BRACES_RE);
|
|
56
|
+
if (optionalParamBracesMatch) {
|
|
57
|
+
const prefix = optionalParamBracesMatch[1];
|
|
58
|
+
const paramName = optionalParamBracesMatch[2];
|
|
59
|
+
const suffix = optionalParamBracesMatch[3];
|
|
60
|
+
const pLength = prefix.length;
|
|
61
|
+
output[0] = SEGMENT_TYPE_OPTIONAL_PARAM;
|
|
62
|
+
output[1] = start + pLength;
|
|
63
|
+
output[2] = start + pLength + 3;
|
|
64
|
+
output[3] = start + pLength + 3 + paramName.length;
|
|
65
|
+
output[4] = end - suffix.length;
|
|
66
|
+
output[5] = end;
|
|
67
|
+
return output;
|
|
68
|
+
}
|
|
69
|
+
const paramBracesMatch = part.match(PARAM_W_CURLY_BRACES_RE);
|
|
70
|
+
if (paramBracesMatch) {
|
|
71
|
+
const prefix = paramBracesMatch[1];
|
|
72
|
+
const paramName = paramBracesMatch[2];
|
|
73
|
+
const suffix = paramBracesMatch[3];
|
|
74
|
+
const pLength = prefix.length;
|
|
75
|
+
output[0] = SEGMENT_TYPE_PARAM;
|
|
76
|
+
output[1] = start + pLength;
|
|
77
|
+
output[2] = start + pLength + 2;
|
|
78
|
+
output[3] = start + pLength + 2 + paramName.length;
|
|
79
|
+
output[4] = end - suffix.length;
|
|
80
|
+
output[5] = end;
|
|
81
|
+
return output;
|
|
82
|
+
}
|
|
83
|
+
output[0] = SEGMENT_TYPE_PATHNAME;
|
|
84
|
+
output[1] = start;
|
|
85
|
+
output[2] = start;
|
|
86
|
+
output[3] = end;
|
|
87
|
+
output[4] = end;
|
|
88
|
+
output[5] = end;
|
|
89
|
+
return output;
|
|
90
|
+
}
|
|
91
|
+
function parseSegments(defaultCaseSensitive, data, route, start, node, depth, onRoute) {
|
|
92
|
+
onRoute?.(route);
|
|
93
|
+
let cursor = start;
|
|
94
|
+
{
|
|
95
|
+
const path = route.fullPath ?? route.from;
|
|
96
|
+
const length = path.length;
|
|
97
|
+
const caseSensitive = route.options?.caseSensitive ?? defaultCaseSensitive;
|
|
98
|
+
while (cursor < length) {
|
|
99
|
+
const segment = parseSegment(path, cursor, data);
|
|
100
|
+
let nextNode;
|
|
101
|
+
const start2 = cursor;
|
|
102
|
+
const end = segment[5];
|
|
103
|
+
cursor = end + 1;
|
|
104
|
+
depth++;
|
|
105
|
+
const kind = segment[0];
|
|
106
|
+
switch (kind) {
|
|
107
|
+
case SEGMENT_TYPE_PATHNAME: {
|
|
108
|
+
const value = path.substring(segment[2], segment[3]);
|
|
109
|
+
if (caseSensitive) {
|
|
110
|
+
const existingNode = node.static?.get(value);
|
|
111
|
+
if (existingNode) {
|
|
112
|
+
nextNode = existingNode;
|
|
113
|
+
} else {
|
|
114
|
+
node.static ??= /* @__PURE__ */ new Map();
|
|
115
|
+
const next = createStaticNode(
|
|
116
|
+
route.fullPath ?? route.from
|
|
117
|
+
);
|
|
118
|
+
next.parent = node;
|
|
119
|
+
next.depth = depth;
|
|
120
|
+
nextNode = next;
|
|
121
|
+
node.static.set(value, next);
|
|
122
|
+
}
|
|
123
|
+
} else {
|
|
124
|
+
const name = value.toLowerCase();
|
|
125
|
+
const existingNode = node.staticInsensitive?.get(name);
|
|
126
|
+
if (existingNode) {
|
|
127
|
+
nextNode = existingNode;
|
|
128
|
+
} else {
|
|
129
|
+
node.staticInsensitive ??= /* @__PURE__ */ new Map();
|
|
130
|
+
const next = createStaticNode(
|
|
131
|
+
route.fullPath ?? route.from
|
|
132
|
+
);
|
|
133
|
+
next.parent = node;
|
|
134
|
+
next.depth = depth;
|
|
135
|
+
nextNode = next;
|
|
136
|
+
node.staticInsensitive.set(name, next);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
case SEGMENT_TYPE_PARAM: {
|
|
142
|
+
const prefix_raw = path.substring(start2, segment[1]);
|
|
143
|
+
const suffix_raw = path.substring(segment[4], end);
|
|
144
|
+
const actuallyCaseSensitive = caseSensitive && !!(prefix_raw || suffix_raw);
|
|
145
|
+
const prefix = !prefix_raw ? void 0 : actuallyCaseSensitive ? prefix_raw : prefix_raw.toLowerCase();
|
|
146
|
+
const suffix = !suffix_raw ? void 0 : actuallyCaseSensitive ? suffix_raw : suffix_raw.toLowerCase();
|
|
147
|
+
const existingNode = node.dynamic?.find(
|
|
148
|
+
(s) => s.caseSensitive === actuallyCaseSensitive && s.prefix === prefix && s.suffix === suffix
|
|
149
|
+
);
|
|
150
|
+
if (existingNode) {
|
|
151
|
+
nextNode = existingNode;
|
|
152
|
+
} else {
|
|
153
|
+
const next = createDynamicNode(
|
|
154
|
+
SEGMENT_TYPE_PARAM,
|
|
155
|
+
route.fullPath ?? route.from,
|
|
156
|
+
actuallyCaseSensitive,
|
|
157
|
+
prefix,
|
|
158
|
+
suffix
|
|
159
|
+
);
|
|
160
|
+
nextNode = next;
|
|
161
|
+
next.depth = depth;
|
|
162
|
+
next.parent = node;
|
|
163
|
+
node.dynamic ??= [];
|
|
164
|
+
node.dynamic.push(next);
|
|
165
|
+
}
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
case SEGMENT_TYPE_OPTIONAL_PARAM: {
|
|
169
|
+
const prefix_raw = path.substring(start2, segment[1]);
|
|
170
|
+
const suffix_raw = path.substring(segment[4], end);
|
|
171
|
+
const actuallyCaseSensitive = caseSensitive && !!(prefix_raw || suffix_raw);
|
|
172
|
+
const prefix = !prefix_raw ? void 0 : actuallyCaseSensitive ? prefix_raw : prefix_raw.toLowerCase();
|
|
173
|
+
const suffix = !suffix_raw ? void 0 : actuallyCaseSensitive ? suffix_raw : suffix_raw.toLowerCase();
|
|
174
|
+
const existingNode = node.optional?.find(
|
|
175
|
+
(s) => s.caseSensitive === actuallyCaseSensitive && s.prefix === prefix && s.suffix === suffix
|
|
176
|
+
);
|
|
177
|
+
if (existingNode) {
|
|
178
|
+
nextNode = existingNode;
|
|
179
|
+
} else {
|
|
180
|
+
const next = createDynamicNode(
|
|
181
|
+
SEGMENT_TYPE_OPTIONAL_PARAM,
|
|
182
|
+
route.fullPath ?? route.from,
|
|
183
|
+
actuallyCaseSensitive,
|
|
184
|
+
prefix,
|
|
185
|
+
suffix
|
|
186
|
+
);
|
|
187
|
+
nextNode = next;
|
|
188
|
+
next.parent = node;
|
|
189
|
+
next.depth = depth;
|
|
190
|
+
node.optional ??= [];
|
|
191
|
+
node.optional.push(next);
|
|
192
|
+
}
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
case SEGMENT_TYPE_WILDCARD: {
|
|
196
|
+
const prefix_raw = path.substring(start2, segment[1]);
|
|
197
|
+
const suffix_raw = path.substring(segment[4], end);
|
|
198
|
+
const actuallyCaseSensitive = caseSensitive && !!(prefix_raw || suffix_raw);
|
|
199
|
+
const prefix = !prefix_raw ? void 0 : actuallyCaseSensitive ? prefix_raw : prefix_raw.toLowerCase();
|
|
200
|
+
const suffix = !suffix_raw ? void 0 : actuallyCaseSensitive ? suffix_raw : suffix_raw.toLowerCase();
|
|
201
|
+
const next = createDynamicNode(
|
|
202
|
+
SEGMENT_TYPE_WILDCARD,
|
|
203
|
+
route.fullPath ?? route.from,
|
|
204
|
+
actuallyCaseSensitive,
|
|
205
|
+
prefix,
|
|
206
|
+
suffix
|
|
207
|
+
);
|
|
208
|
+
nextNode = next;
|
|
209
|
+
next.parent = node;
|
|
210
|
+
next.depth = depth;
|
|
211
|
+
node.wildcard ??= [];
|
|
212
|
+
node.wildcard.push(next);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
node = nextNode;
|
|
216
|
+
}
|
|
217
|
+
if ((route.path || !route.children) && !route.isRoot) {
|
|
218
|
+
const isIndex = path.endsWith("/");
|
|
219
|
+
if (!isIndex) node.notFound = route;
|
|
220
|
+
if (!node.route || !node.isIndex && isIndex) node.route = route;
|
|
221
|
+
node.isIndex ||= isIndex;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (route.children)
|
|
225
|
+
for (const child of route.children) {
|
|
226
|
+
parseSegments(
|
|
227
|
+
defaultCaseSensitive,
|
|
228
|
+
data,
|
|
229
|
+
child,
|
|
230
|
+
cursor,
|
|
231
|
+
node,
|
|
232
|
+
depth,
|
|
233
|
+
onRoute
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function sortDynamic(a, b) {
|
|
238
|
+
if (a.prefix && b.prefix && a.prefix !== b.prefix) {
|
|
239
|
+
if (a.prefix.startsWith(b.prefix)) return -1;
|
|
240
|
+
if (b.prefix.startsWith(a.prefix)) return 1;
|
|
241
|
+
}
|
|
242
|
+
if (a.suffix && b.suffix && a.suffix !== b.suffix) {
|
|
243
|
+
if (a.suffix.endsWith(b.suffix)) return -1;
|
|
244
|
+
if (b.suffix.endsWith(a.suffix)) return 1;
|
|
245
|
+
}
|
|
246
|
+
if (a.prefix && !b.prefix) return -1;
|
|
247
|
+
if (!a.prefix && b.prefix) return 1;
|
|
248
|
+
if (a.suffix && !b.suffix) return -1;
|
|
249
|
+
if (!a.suffix && b.suffix) return 1;
|
|
250
|
+
if (a.caseSensitive && !b.caseSensitive) return -1;
|
|
251
|
+
if (!a.caseSensitive && b.caseSensitive) return 1;
|
|
252
|
+
return 0;
|
|
253
|
+
}
|
|
254
|
+
function sortTreeNodes(node) {
|
|
255
|
+
if (node.static) {
|
|
256
|
+
for (const child of node.static.values()) {
|
|
257
|
+
sortTreeNodes(child);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (node.staticInsensitive) {
|
|
261
|
+
for (const child of node.staticInsensitive.values()) {
|
|
262
|
+
sortTreeNodes(child);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (node.dynamic?.length) {
|
|
266
|
+
node.dynamic.sort(sortDynamic);
|
|
267
|
+
for (const child of node.dynamic) {
|
|
268
|
+
sortTreeNodes(child);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (node.optional?.length) {
|
|
272
|
+
node.optional.sort(sortDynamic);
|
|
273
|
+
for (const child of node.optional) {
|
|
274
|
+
sortTreeNodes(child);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (node.wildcard?.length) {
|
|
278
|
+
node.wildcard.sort(sortDynamic);
|
|
279
|
+
for (const child of node.wildcard) {
|
|
280
|
+
sortTreeNodes(child);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function createStaticNode(fullPath) {
|
|
285
|
+
return {
|
|
286
|
+
kind: SEGMENT_TYPE_PATHNAME,
|
|
287
|
+
depth: 0,
|
|
288
|
+
static: null,
|
|
289
|
+
staticInsensitive: null,
|
|
290
|
+
dynamic: null,
|
|
291
|
+
optional: null,
|
|
292
|
+
wildcard: null,
|
|
293
|
+
route: null,
|
|
294
|
+
fullPath,
|
|
295
|
+
parent: null,
|
|
296
|
+
isIndex: false,
|
|
297
|
+
notFound: null
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
function createDynamicNode(kind, fullPath, caseSensitive, prefix, suffix) {
|
|
301
|
+
return {
|
|
302
|
+
kind,
|
|
303
|
+
depth: 0,
|
|
304
|
+
static: null,
|
|
305
|
+
staticInsensitive: null,
|
|
306
|
+
dynamic: null,
|
|
307
|
+
optional: null,
|
|
308
|
+
wildcard: null,
|
|
309
|
+
route: null,
|
|
310
|
+
fullPath,
|
|
311
|
+
parent: null,
|
|
312
|
+
isIndex: false,
|
|
313
|
+
notFound: null,
|
|
314
|
+
caseSensitive,
|
|
315
|
+
prefix,
|
|
316
|
+
suffix
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
function processRouteMasks(routeList, processedTree) {
|
|
320
|
+
const segmentTree = createStaticNode("/");
|
|
321
|
+
const data = new Uint16Array(6);
|
|
322
|
+
for (const route of routeList) {
|
|
323
|
+
parseSegments(false, data, route, 1, segmentTree, 0);
|
|
324
|
+
}
|
|
325
|
+
sortTreeNodes(segmentTree);
|
|
326
|
+
processedTree.masksTree = segmentTree;
|
|
327
|
+
processedTree.flatCache = createLRUCache(1e3);
|
|
328
|
+
}
|
|
329
|
+
function findFlatMatch(path, processedTree) {
|
|
330
|
+
path ||= "/";
|
|
331
|
+
const cached = processedTree.flatCache.get(path);
|
|
332
|
+
if (cached) return cached;
|
|
333
|
+
const result = findMatch(path, processedTree.masksTree);
|
|
334
|
+
processedTree.flatCache.set(path, result);
|
|
335
|
+
return result;
|
|
336
|
+
}
|
|
337
|
+
function findSingleMatch(from, caseSensitive, fuzzy, path, processedTree) {
|
|
338
|
+
from ||= "/";
|
|
339
|
+
path ||= "/";
|
|
340
|
+
const key = caseSensitive ? `case\0${from}` : from;
|
|
341
|
+
let tree = processedTree.singleCache.get(key);
|
|
342
|
+
if (!tree) {
|
|
343
|
+
tree = createStaticNode("/");
|
|
344
|
+
const data = new Uint16Array(6);
|
|
345
|
+
parseSegments(caseSensitive, data, { from }, 1, tree, 0);
|
|
346
|
+
processedTree.singleCache.set(key, tree);
|
|
347
|
+
}
|
|
348
|
+
return findMatch(path, tree, fuzzy);
|
|
349
|
+
}
|
|
350
|
+
function findRouteMatch(path, processedTree, fuzzy = false) {
|
|
351
|
+
const key = fuzzy ? `fuzzy\0${path}` : path;
|
|
352
|
+
const cached = processedTree.matchCache.get(key);
|
|
353
|
+
if (cached) return cached;
|
|
354
|
+
path ||= "/";
|
|
355
|
+
const result = findMatch(path, processedTree.segmentTree, fuzzy);
|
|
356
|
+
processedTree.matchCache.set(key, result);
|
|
357
|
+
return result;
|
|
358
|
+
}
|
|
359
|
+
function trimPathRight(path) {
|
|
360
|
+
return path === "/" ? path : path.replace(/\/{1,}$/, "");
|
|
361
|
+
}
|
|
362
|
+
function processRouteTree(routeTree, caseSensitive = false, initRoute) {
|
|
363
|
+
const segmentTree = createStaticNode(routeTree.fullPath);
|
|
364
|
+
const data = new Uint16Array(6);
|
|
365
|
+
const routesById = {};
|
|
366
|
+
const routesByPath = {};
|
|
367
|
+
let index = 0;
|
|
368
|
+
parseSegments(caseSensitive, data, routeTree, 1, segmentTree, 0, (route) => {
|
|
369
|
+
initRoute?.(route, index);
|
|
370
|
+
invariant(
|
|
371
|
+
!(route.id in routesById),
|
|
372
|
+
`Duplicate routes found with id: ${String(route.id)}`
|
|
373
|
+
);
|
|
374
|
+
routesById[route.id] = route;
|
|
375
|
+
if (index !== 0 && route.path) {
|
|
376
|
+
const trimmedFullPath = trimPathRight(route.fullPath);
|
|
377
|
+
if (!routesByPath[trimmedFullPath] || route.fullPath.endsWith("/")) {
|
|
378
|
+
routesByPath[trimmedFullPath] = route;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
index++;
|
|
382
|
+
});
|
|
383
|
+
sortTreeNodes(segmentTree);
|
|
384
|
+
const processedTree = {
|
|
385
|
+
segmentTree,
|
|
386
|
+
singleCache: /* @__PURE__ */ new Map(),
|
|
387
|
+
matchCache: createLRUCache(1e3),
|
|
388
|
+
flatCache: null,
|
|
389
|
+
masksTree: null
|
|
390
|
+
};
|
|
391
|
+
return {
|
|
392
|
+
processedTree,
|
|
393
|
+
routesById,
|
|
394
|
+
routesByPath
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
function findMatch(path, segmentTree, fuzzy = false) {
|
|
398
|
+
const parts = path.split("/");
|
|
399
|
+
const leaf = getNodeMatch(path, parts, segmentTree, fuzzy);
|
|
400
|
+
if (!leaf) return null;
|
|
401
|
+
const params = extractParams(path, parts, leaf);
|
|
402
|
+
const isFuzzyMatch = "**" in leaf;
|
|
403
|
+
if (isFuzzyMatch) params["**"] = leaf["**"];
|
|
404
|
+
const route = isFuzzyMatch ? leaf.node.notFound ?? leaf.node.route : leaf.node.route;
|
|
405
|
+
return {
|
|
406
|
+
route,
|
|
407
|
+
params
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
function extractParams(path, parts, leaf) {
|
|
411
|
+
const list = buildBranch(leaf.node);
|
|
412
|
+
let nodeParts = null;
|
|
413
|
+
const params = {};
|
|
414
|
+
for (let partIndex = 0, nodeIndex = 0, pathIndex = 0; nodeIndex < list.length; partIndex++, nodeIndex++, pathIndex++) {
|
|
415
|
+
const node = list[nodeIndex];
|
|
416
|
+
const part = parts[partIndex];
|
|
417
|
+
const currentPathIndex = pathIndex;
|
|
418
|
+
if (part) pathIndex += part.length;
|
|
419
|
+
if (node.kind === SEGMENT_TYPE_PARAM) {
|
|
420
|
+
nodeParts ??= leaf.node.fullPath.split("/");
|
|
421
|
+
const nodePart = nodeParts[nodeIndex];
|
|
422
|
+
const preLength = node.prefix?.length ?? 0;
|
|
423
|
+
const isCurlyBraced = nodePart.charCodeAt(preLength) === 123;
|
|
424
|
+
if (isCurlyBraced) {
|
|
425
|
+
const sufLength = node.suffix?.length ?? 0;
|
|
426
|
+
const name = nodePart.substring(
|
|
427
|
+
preLength + 2,
|
|
428
|
+
nodePart.length - sufLength - 1
|
|
429
|
+
);
|
|
430
|
+
const value = part.substring(preLength, part.length - sufLength);
|
|
431
|
+
params[name] = decodeURIComponent(value);
|
|
432
|
+
} else {
|
|
433
|
+
const name = nodePart.substring(1);
|
|
434
|
+
params[name] = decodeURIComponent(part);
|
|
435
|
+
}
|
|
436
|
+
} else if (node.kind === SEGMENT_TYPE_OPTIONAL_PARAM) {
|
|
437
|
+
if (leaf.skipped & 1 << nodeIndex) {
|
|
438
|
+
partIndex--;
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
nodeParts ??= leaf.node.fullPath.split("/");
|
|
442
|
+
const nodePart = nodeParts[nodeIndex];
|
|
443
|
+
const preLength = node.prefix?.length ?? 0;
|
|
444
|
+
const sufLength = node.suffix?.length ?? 0;
|
|
445
|
+
const name = nodePart.substring(
|
|
446
|
+
preLength + 3,
|
|
447
|
+
nodePart.length - sufLength - 1
|
|
448
|
+
);
|
|
449
|
+
const value = node.suffix || node.prefix ? part.substring(preLength, part.length - sufLength) : part;
|
|
450
|
+
if (value) params[name] = decodeURIComponent(value);
|
|
451
|
+
} else if (node.kind === SEGMENT_TYPE_WILDCARD) {
|
|
452
|
+
const n = node;
|
|
453
|
+
const value = path.substring(
|
|
454
|
+
currentPathIndex + (n.prefix?.length ?? 0),
|
|
455
|
+
path.length - (n.suffix?.length ?? 0)
|
|
456
|
+
);
|
|
457
|
+
const splat = decodeURIComponent(value);
|
|
458
|
+
params["*"] = splat;
|
|
459
|
+
params._splat = splat;
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return params;
|
|
464
|
+
}
|
|
465
|
+
function buildBranch(node) {
|
|
466
|
+
const list = Array(node.depth + 1);
|
|
467
|
+
do {
|
|
468
|
+
list[node.depth] = node;
|
|
469
|
+
node = node.parent;
|
|
470
|
+
} while (node);
|
|
471
|
+
return list;
|
|
472
|
+
}
|
|
473
|
+
function getNodeMatch(path, parts, segmentTree, fuzzy) {
|
|
474
|
+
const trailingSlash = !last(parts);
|
|
475
|
+
const pathIsIndex = trailingSlash && path !== "/";
|
|
476
|
+
const partsLength = parts.length - (trailingSlash ? 1 : 0);
|
|
477
|
+
const stack = [
|
|
478
|
+
{
|
|
479
|
+
node: segmentTree,
|
|
480
|
+
index: 1,
|
|
481
|
+
skipped: 0,
|
|
482
|
+
depth: 1,
|
|
483
|
+
statics: 1,
|
|
484
|
+
dynamics: 0,
|
|
485
|
+
optionals: 0
|
|
486
|
+
}
|
|
487
|
+
];
|
|
488
|
+
let wildcardMatch = null;
|
|
489
|
+
let bestFuzzy = null;
|
|
490
|
+
let bestMatch = null;
|
|
491
|
+
while (stack.length) {
|
|
492
|
+
const frame = stack.pop();
|
|
493
|
+
let { node, index, skipped, depth, statics, dynamics, optionals } = frame;
|
|
494
|
+
if (fuzzy && node.notFound && isFrameMoreSpecific(bestFuzzy, frame)) {
|
|
495
|
+
bestFuzzy = frame;
|
|
496
|
+
}
|
|
497
|
+
const isBeyondPath = index === partsLength;
|
|
498
|
+
if (isBeyondPath) {
|
|
499
|
+
if (node.route && (!pathIsIndex || node.isIndex)) {
|
|
500
|
+
if (isFrameMoreSpecific(bestMatch, frame)) {
|
|
501
|
+
bestMatch = frame;
|
|
502
|
+
}
|
|
503
|
+
if (statics === partsLength) return bestMatch;
|
|
504
|
+
}
|
|
505
|
+
if (!node.optional && !node.wildcard) continue;
|
|
506
|
+
}
|
|
507
|
+
const part = isBeyondPath ? void 0 : parts[index];
|
|
508
|
+
let lowerPart;
|
|
509
|
+
if (node.wildcard && isFrameMoreSpecific(wildcardMatch, frame)) {
|
|
510
|
+
for (const segment of node.wildcard) {
|
|
511
|
+
const { prefix, suffix } = segment;
|
|
512
|
+
if (prefix) {
|
|
513
|
+
if (isBeyondPath) continue;
|
|
514
|
+
const casePart = segment.caseSensitive ? part : lowerPart ??= part.toLowerCase();
|
|
515
|
+
if (!casePart.startsWith(prefix)) continue;
|
|
516
|
+
}
|
|
517
|
+
if (suffix) {
|
|
518
|
+
if (isBeyondPath) continue;
|
|
519
|
+
const end = parts.slice(index).join("/").slice(-suffix.length);
|
|
520
|
+
const casePart = segment.caseSensitive ? end : end.toLowerCase();
|
|
521
|
+
if (casePart !== suffix) continue;
|
|
522
|
+
}
|
|
523
|
+
wildcardMatch = {
|
|
524
|
+
node: segment,
|
|
525
|
+
index,
|
|
526
|
+
skipped,
|
|
527
|
+
depth,
|
|
528
|
+
statics,
|
|
529
|
+
dynamics,
|
|
530
|
+
optionals
|
|
531
|
+
};
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
if (node.optional) {
|
|
536
|
+
const nextSkipped = skipped | 1 << depth;
|
|
537
|
+
const nextDepth = depth + 1;
|
|
538
|
+
for (let i = node.optional.length - 1; i >= 0; i--) {
|
|
539
|
+
const segment = node.optional[i];
|
|
540
|
+
stack.push({
|
|
541
|
+
node: segment,
|
|
542
|
+
index,
|
|
543
|
+
skipped: nextSkipped,
|
|
544
|
+
depth: nextDepth,
|
|
545
|
+
statics,
|
|
546
|
+
dynamics,
|
|
547
|
+
optionals
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
if (!isBeyondPath) {
|
|
551
|
+
for (let i = node.optional.length - 1; i >= 0; i--) {
|
|
552
|
+
const segment = node.optional[i];
|
|
553
|
+
const { prefix, suffix } = segment;
|
|
554
|
+
if (prefix || suffix) {
|
|
555
|
+
const casePart = segment.caseSensitive ? part : lowerPart ??= part.toLowerCase();
|
|
556
|
+
if (prefix && !casePart.startsWith(prefix)) continue;
|
|
557
|
+
if (suffix && !casePart.endsWith(suffix)) continue;
|
|
558
|
+
}
|
|
559
|
+
stack.push({
|
|
560
|
+
node: segment,
|
|
561
|
+
index: index + 1,
|
|
562
|
+
skipped,
|
|
563
|
+
depth: nextDepth,
|
|
564
|
+
statics,
|
|
565
|
+
dynamics,
|
|
566
|
+
optionals: optionals + 1
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
if (!isBeyondPath && node.dynamic && part) {
|
|
572
|
+
for (let i = node.dynamic.length - 1; i >= 0; i--) {
|
|
573
|
+
const segment = node.dynamic[i];
|
|
574
|
+
const { prefix, suffix } = segment;
|
|
575
|
+
if (prefix || suffix) {
|
|
576
|
+
const casePart = segment.caseSensitive ? part : lowerPart ??= part.toLowerCase();
|
|
577
|
+
if (prefix && !casePart.startsWith(prefix)) continue;
|
|
578
|
+
if (suffix && !casePart.endsWith(suffix)) continue;
|
|
579
|
+
}
|
|
580
|
+
stack.push({
|
|
581
|
+
node: segment,
|
|
582
|
+
index: index + 1,
|
|
583
|
+
skipped,
|
|
584
|
+
depth: depth + 1,
|
|
585
|
+
statics,
|
|
586
|
+
dynamics: dynamics + 1,
|
|
587
|
+
optionals
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
if (!isBeyondPath && node.staticInsensitive) {
|
|
592
|
+
const match = node.staticInsensitive.get(
|
|
593
|
+
lowerPart ??= part.toLowerCase()
|
|
594
|
+
);
|
|
595
|
+
if (match) {
|
|
596
|
+
stack.push({
|
|
597
|
+
node: match,
|
|
598
|
+
index: index + 1,
|
|
599
|
+
skipped,
|
|
600
|
+
depth: depth + 1,
|
|
601
|
+
statics: statics + 1,
|
|
602
|
+
dynamics,
|
|
603
|
+
optionals
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
if (!isBeyondPath && node.static) {
|
|
608
|
+
const match = node.static.get(part);
|
|
609
|
+
if (match) {
|
|
610
|
+
stack.push({
|
|
611
|
+
node: match,
|
|
612
|
+
index: index + 1,
|
|
613
|
+
skipped,
|
|
614
|
+
depth: depth + 1,
|
|
615
|
+
statics: statics + 1,
|
|
616
|
+
dynamics,
|
|
617
|
+
optionals
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
if (bestMatch) return bestMatch;
|
|
623
|
+
if (wildcardMatch) return wildcardMatch;
|
|
624
|
+
if (fuzzy && bestFuzzy) {
|
|
625
|
+
let sliceIndex = bestFuzzy.index;
|
|
626
|
+
for (let i = 0; i < bestFuzzy.index; i++) {
|
|
627
|
+
sliceIndex += parts[i].length;
|
|
628
|
+
}
|
|
629
|
+
const splat = sliceIndex === path.length ? "/" : path.slice(sliceIndex);
|
|
630
|
+
return {
|
|
631
|
+
node: bestFuzzy.node,
|
|
632
|
+
skipped: bestFuzzy.skipped,
|
|
633
|
+
"**": decodeURIComponent(splat)
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
return null;
|
|
637
|
+
}
|
|
638
|
+
function isFrameMoreSpecific(prev, next) {
|
|
639
|
+
if (!prev) return true;
|
|
640
|
+
return next.statics > prev.statics || next.statics === prev.statics && (next.dynamics > prev.dynamics || next.dynamics === prev.dynamics && next.optionals > prev.optionals);
|
|
641
|
+
}
|
|
642
|
+
export {
|
|
643
|
+
SEGMENT_TYPE_OPTIONAL_PARAM,
|
|
644
|
+
SEGMENT_TYPE_PARAM,
|
|
645
|
+
SEGMENT_TYPE_PATHNAME,
|
|
646
|
+
SEGMENT_TYPE_WILDCARD,
|
|
647
|
+
findFlatMatch,
|
|
648
|
+
findRouteMatch,
|
|
649
|
+
findSingleMatch,
|
|
650
|
+
parseSegment,
|
|
651
|
+
processRouteMasks,
|
|
652
|
+
processRouteTree,
|
|
653
|
+
trimPathRight
|
|
654
|
+
};
|
|
655
|
+
//# sourceMappingURL=new-process-route-tree.js.map
|