@tanstack/router-core 1.136.4 → 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.
Files changed (48) hide show
  1. package/dist/cjs/Matches.cjs.map +1 -1
  2. package/dist/cjs/Matches.d.cts +2 -0
  3. package/dist/cjs/index.cjs +0 -5
  4. package/dist/cjs/index.cjs.map +1 -1
  5. package/dist/cjs/index.d.cts +1 -4
  6. package/dist/cjs/lru-cache.cjs +5 -0
  7. package/dist/cjs/lru-cache.cjs.map +1 -1
  8. package/dist/cjs/lru-cache.d.cts +1 -0
  9. package/dist/cjs/new-process-route-tree.cjs +655 -0
  10. package/dist/cjs/new-process-route-tree.cjs.map +1 -0
  11. package/dist/cjs/new-process-route-tree.d.cts +177 -0
  12. package/dist/cjs/path.cjs +133 -434
  13. package/dist/cjs/path.cjs.map +1 -1
  14. package/dist/cjs/path.d.cts +3 -39
  15. package/dist/cjs/router.cjs +47 -98
  16. package/dist/cjs/router.cjs.map +1 -1
  17. package/dist/cjs/router.d.cts +6 -11
  18. package/dist/esm/Matches.d.ts +2 -0
  19. package/dist/esm/Matches.js.map +1 -1
  20. package/dist/esm/index.d.ts +1 -4
  21. package/dist/esm/index.js +1 -6
  22. package/dist/esm/index.js.map +1 -1
  23. package/dist/esm/lru-cache.d.ts +1 -0
  24. package/dist/esm/lru-cache.js +5 -0
  25. package/dist/esm/lru-cache.js.map +1 -1
  26. package/dist/esm/new-process-route-tree.d.ts +177 -0
  27. package/dist/esm/new-process-route-tree.js +655 -0
  28. package/dist/esm/new-process-route-tree.js.map +1 -0
  29. package/dist/esm/path.d.ts +3 -39
  30. package/dist/esm/path.js +133 -434
  31. package/dist/esm/path.js.map +1 -1
  32. package/dist/esm/router.d.ts +6 -11
  33. package/dist/esm/router.js +48 -99
  34. package/dist/esm/router.js.map +1 -1
  35. package/package.json +1 -1
  36. package/src/Matches.ts +2 -0
  37. package/src/index.ts +0 -6
  38. package/src/lru-cache.ts +6 -0
  39. package/src/new-process-route-tree.ts +1036 -0
  40. package/src/path.ts +168 -639
  41. package/src/router.ts +57 -126
  42. package/dist/cjs/process-route-tree.cjs +0 -144
  43. package/dist/cjs/process-route-tree.cjs.map +0 -1
  44. package/dist/cjs/process-route-tree.d.cts +0 -18
  45. package/dist/esm/process-route-tree.d.ts +0 -18
  46. package/dist/esm/process-route-tree.js +0 -144
  47. package/dist/esm/process-route-tree.js.map +0 -1
  48. 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