astro-md-editor 0.0.1

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 (87) hide show
  1. package/.output/nitro.json +17 -0
  2. package/.output/public/assets/index-Cc7yKB0o.js +19 -0
  3. package/.output/public/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  4. package/.output/public/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  5. package/.output/public/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  6. package/.output/public/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  7. package/.output/public/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  8. package/.output/public/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  9. package/.output/public/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  10. package/.output/public/assets/main-DDBjVFnt.js +17 -0
  11. package/.output/public/assets/styles-ggfdUHMo.css +1 -0
  12. package/.output/public/favicon.ico +0 -0
  13. package/.output/public/logo192.png +0 -0
  14. package/.output/public/logo512.png +0 -0
  15. package/.output/public/manifest.json +25 -0
  16. package/.output/public/robots.txt +3 -0
  17. package/.output/server/__root-C09LBXMv.mjs +40 -0
  18. package/.output/server/_chunks/ssr-renderer.mjs +21 -0
  19. package/.output/server/_libs/ajv-formats.mjs +330 -0
  20. package/.output/server/_libs/ajv.mjs +5484 -0
  21. package/.output/server/_libs/base-ui__react.mjs +8712 -0
  22. package/.output/server/_libs/base-ui__utils.mjs +980 -0
  23. package/.output/server/_libs/class-variance-authority.mjs +44 -0
  24. package/.output/server/_libs/clsx.mjs +16 -0
  25. package/.output/server/_libs/cookie-es.mjs +58 -0
  26. package/.output/server/_libs/croner.mjs +1 -0
  27. package/.output/server/_libs/crossws.mjs +1 -0
  28. package/.output/server/_libs/date-fns.mjs +1716 -0
  29. package/.output/server/_libs/date-fns__tz.mjs +217 -0
  30. package/.output/server/_libs/extend-shallow.mjs +35 -0
  31. package/.output/server/_libs/fast-deep-equal.mjs +38 -0
  32. package/.output/server/_libs/fast-uri.mjs +725 -0
  33. package/.output/server/_libs/floating-ui__core.mjs +663 -0
  34. package/.output/server/_libs/floating-ui__dom.mjs +624 -0
  35. package/.output/server/_libs/floating-ui__react-dom.mjs +279 -0
  36. package/.output/server/_libs/floating-ui__utils.mjs +322 -0
  37. package/.output/server/_libs/gray-matter.mjs +393 -0
  38. package/.output/server/_libs/h3-v2.mjs +276 -0
  39. package/.output/server/_libs/h3.mjs +400 -0
  40. package/.output/server/_libs/hookable.mjs +1 -0
  41. package/.output/server/_libs/is-extendable.mjs +13 -0
  42. package/.output/server/_libs/isbot.mjs +20 -0
  43. package/.output/server/_libs/js-yaml.mjs +2822 -0
  44. package/.output/server/_libs/json-schema-traverse.mjs +91 -0
  45. package/.output/server/_libs/kind-of.mjs +125 -0
  46. package/.output/server/_libs/lucide-react.mjs +177 -0
  47. package/.output/server/_libs/ohash.mjs +1 -0
  48. package/.output/server/_libs/react-day-picker.mjs +2216 -0
  49. package/.output/server/_libs/react-dom.mjs +10779 -0
  50. package/.output/server/_libs/react-resizable-panels.mjs +2024 -0
  51. package/.output/server/_libs/react.mjs +513 -0
  52. package/.output/server/_libs/reselect.mjs +326 -0
  53. package/.output/server/_libs/rou3.mjs +8 -0
  54. package/.output/server/_libs/section-matter.mjs +112 -0
  55. package/.output/server/_libs/seroval-plugins.mjs +58 -0
  56. package/.output/server/_libs/seroval.mjs +1765 -0
  57. package/.output/server/_libs/srvx.mjs +736 -0
  58. package/.output/server/_libs/strip-bom-string.mjs +16 -0
  59. package/.output/server/_libs/tabbable.mjs +342 -0
  60. package/.output/server/_libs/tailwind-merge.mjs +3175 -0
  61. package/.output/server/_libs/tanstack__history.mjs +217 -0
  62. package/.output/server/_libs/tanstack__react-router.mjs +1464 -0
  63. package/.output/server/_libs/tanstack__react-store.mjs +1 -0
  64. package/.output/server/_libs/tanstack__router-core.mjs +4912 -0
  65. package/.output/server/_libs/tanstack__store.mjs +1 -0
  66. package/.output/server/_libs/tiny-invariant.mjs +12 -0
  67. package/.output/server/_libs/tiny-warning.mjs +5 -0
  68. package/.output/server/_libs/ufo.mjs +54 -0
  69. package/.output/server/_libs/unctx.mjs +1 -0
  70. package/.output/server/_libs/unstorage.mjs +1 -0
  71. package/.output/server/_libs/use-sync-external-store.mjs +139 -0
  72. package/.output/server/_libs/zod.mjs +3634 -0
  73. package/.output/server/_libs/zustand.mjs +43 -0
  74. package/.output/server/_ssr/RightSidebar-RSY9M7XF.mjs +218 -0
  75. package/.output/server/_ssr/collections.server-D6U2tEsT.mjs +120 -0
  76. package/.output/server/_ssr/createServerRpc-29xaFZcb.mjs +12 -0
  77. package/.output/server/_ssr/index-BaqV4cZC.mjs +2083 -0
  78. package/.output/server/_ssr/index-sQBM6rwN.mjs +115 -0
  79. package/.output/server/_ssr/index.mjs +1448 -0
  80. package/.output/server/_ssr/router-D4G1DGr3.mjs +155 -0
  81. package/.output/server/_ssr/start-HYkvq4Ni.mjs +4 -0
  82. package/.output/server/_tanstack-start-manifest_v-CYEHh_qB.mjs +4 -0
  83. package/.output/server/index.mjs +451 -0
  84. package/README.md +118 -0
  85. package/index.mjs +21 -0
  86. package/package.json +86 -0
  87. package/scripts/bootstrap-collections.mjs +1201 -0
@@ -0,0 +1,4912 @@
1
+ import { s as splitSetCookieString } from "./cookie-es.mjs";
2
+ import { p as parseHref } from "./tanstack__history.mjs";
3
+ import { i as invariant } from "./tiny-invariant.mjs";
4
+ import { n as ni, t as te, c as cn, m as mn } from "./seroval.mjs";
5
+ import { p } from "./seroval-plugins.mjs";
6
+ import { ReadableStream as ReadableStream$1 } from "node:stream/web";
7
+ import { Readable } from "node:stream";
8
+ function toHeadersInstance(init) {
9
+ if (init instanceof Headers) {
10
+ return init;
11
+ } else if (Array.isArray(init)) {
12
+ return new Headers(init);
13
+ } else if (typeof init === "object") {
14
+ return new Headers(init);
15
+ } else {
16
+ return null;
17
+ }
18
+ }
19
+ function mergeHeaders(...headers) {
20
+ return headers.reduce((acc, header) => {
21
+ const headersInstance = toHeadersInstance(header);
22
+ if (!headersInstance) return acc;
23
+ for (const [key, value] of headersInstance.entries()) {
24
+ if (key === "set-cookie") {
25
+ const splitCookies = splitSetCookieString(value);
26
+ splitCookies.forEach((cookie) => acc.append("set-cookie", cookie));
27
+ } else {
28
+ acc.set(key, value);
29
+ }
30
+ }
31
+ return acc;
32
+ }, new Headers());
33
+ }
34
+ const isServer = true;
35
+ function batch(fn) {
36
+ {
37
+ return fn();
38
+ }
39
+ }
40
+ function isNotFound(obj) {
41
+ return !!obj?.isNotFound;
42
+ }
43
+ function last(arr) {
44
+ return arr[arr.length - 1];
45
+ }
46
+ function isFunction(d) {
47
+ return typeof d === "function";
48
+ }
49
+ function functionalUpdate(updater, previous) {
50
+ if (isFunction(updater)) {
51
+ return updater(previous);
52
+ }
53
+ return updater;
54
+ }
55
+ function replaceEqualDeep(prev, _next, _depth = 0) {
56
+ {
57
+ return _next;
58
+ }
59
+ }
60
+ function isPlainObject(o) {
61
+ if (!hasObjectPrototype(o)) {
62
+ return false;
63
+ }
64
+ const ctor = o.constructor;
65
+ if (typeof ctor === "undefined") {
66
+ return true;
67
+ }
68
+ const prot = ctor.prototype;
69
+ if (!hasObjectPrototype(prot)) {
70
+ return false;
71
+ }
72
+ if (!prot.hasOwnProperty("isPrototypeOf")) {
73
+ return false;
74
+ }
75
+ return true;
76
+ }
77
+ function hasObjectPrototype(o) {
78
+ return Object.prototype.toString.call(o) === "[object Object]";
79
+ }
80
+ function deepEqual(a, b, opts) {
81
+ if (a === b) {
82
+ return true;
83
+ }
84
+ if (typeof a !== typeof b) {
85
+ return false;
86
+ }
87
+ if (Array.isArray(a) && Array.isArray(b)) {
88
+ if (a.length !== b.length) return false;
89
+ for (let i = 0, l = a.length; i < l; i++) {
90
+ if (!deepEqual(a[i], b[i], opts)) return false;
91
+ }
92
+ return true;
93
+ }
94
+ if (isPlainObject(a) && isPlainObject(b)) {
95
+ const ignoreUndefined = opts?.ignoreUndefined ?? true;
96
+ if (opts?.partial) {
97
+ for (const k in b) {
98
+ if (!ignoreUndefined || b[k] !== void 0) {
99
+ if (!deepEqual(a[k], b[k], opts)) return false;
100
+ }
101
+ }
102
+ return true;
103
+ }
104
+ let aCount = 0;
105
+ if (!ignoreUndefined) {
106
+ aCount = Object.keys(a).length;
107
+ } else {
108
+ for (const k in a) {
109
+ if (a[k] !== void 0) aCount++;
110
+ }
111
+ }
112
+ let bCount = 0;
113
+ for (const k in b) {
114
+ if (!ignoreUndefined || b[k] !== void 0) {
115
+ bCount++;
116
+ if (bCount > aCount || !deepEqual(a[k], b[k], opts)) return false;
117
+ }
118
+ }
119
+ return aCount === bCount;
120
+ }
121
+ return false;
122
+ }
123
+ function createControlledPromise(onResolve) {
124
+ let resolveLoadPromise;
125
+ let rejectLoadPromise;
126
+ const controlledPromise = new Promise((resolve, reject) => {
127
+ resolveLoadPromise = resolve;
128
+ rejectLoadPromise = reject;
129
+ });
130
+ controlledPromise.status = "pending";
131
+ controlledPromise.resolve = (value) => {
132
+ controlledPromise.status = "resolved";
133
+ controlledPromise.value = value;
134
+ resolveLoadPromise(value);
135
+ onResolve?.(value);
136
+ };
137
+ controlledPromise.reject = (e) => {
138
+ controlledPromise.status = "rejected";
139
+ rejectLoadPromise(e);
140
+ };
141
+ return controlledPromise;
142
+ }
143
+ function isModuleNotFoundError(error) {
144
+ if (typeof error?.message !== "string") return false;
145
+ return error.message.startsWith("Failed to fetch dynamically imported module") || error.message.startsWith("error loading dynamically imported module") || error.message.startsWith("Importing a module script failed");
146
+ }
147
+ function isPromise(value) {
148
+ return Boolean(
149
+ value && typeof value === "object" && typeof value.then === "function"
150
+ );
151
+ }
152
+ function sanitizePathSegment(segment) {
153
+ return segment.replace(/[\x00-\x1f\x7f]/g, "");
154
+ }
155
+ function decodeSegment(segment) {
156
+ let decoded;
157
+ try {
158
+ decoded = decodeURI(segment);
159
+ } catch {
160
+ decoded = segment.replaceAll(/%[0-9A-F]{2}/gi, (match) => {
161
+ try {
162
+ return decodeURI(match);
163
+ } catch {
164
+ return match;
165
+ }
166
+ });
167
+ }
168
+ return sanitizePathSegment(decoded);
169
+ }
170
+ const DEFAULT_PROTOCOL_ALLOWLIST = [
171
+ // Standard web navigation
172
+ "http:",
173
+ "https:",
174
+ // Common browser-safe actions
175
+ "mailto:",
176
+ "tel:"
177
+ ];
178
+ function isDangerousProtocol(url, allowlist) {
179
+ if (!url) return false;
180
+ try {
181
+ const parsed = new URL(url);
182
+ return !allowlist.has(parsed.protocol);
183
+ } catch {
184
+ return false;
185
+ }
186
+ }
187
+ const HTML_ESCAPE_LOOKUP = {
188
+ "&": "\\u0026",
189
+ ">": "\\u003e",
190
+ "<": "\\u003c",
191
+ "\u2028": "\\u2028",
192
+ "\u2029": "\\u2029"
193
+ };
194
+ const HTML_ESCAPE_REGEX = /[&><\u2028\u2029]/g;
195
+ function escapeHtml(str) {
196
+ return str.replace(HTML_ESCAPE_REGEX, (match) => HTML_ESCAPE_LOOKUP[match]);
197
+ }
198
+ function decodePath(path) {
199
+ if (!path) return { path, handledProtocolRelativeURL: false };
200
+ if (!/[%\\\x00-\x1f\x7f]/.test(path) && !path.startsWith("//")) {
201
+ return { path, handledProtocolRelativeURL: false };
202
+ }
203
+ const re = /%25|%5C/gi;
204
+ let cursor = 0;
205
+ let result = "";
206
+ let match;
207
+ while (null !== (match = re.exec(path))) {
208
+ result += decodeSegment(path.slice(cursor, match.index)) + match[0];
209
+ cursor = re.lastIndex;
210
+ }
211
+ result = result + decodeSegment(cursor ? path.slice(cursor) : path);
212
+ let handledProtocolRelativeURL = false;
213
+ if (result.startsWith("//")) {
214
+ handledProtocolRelativeURL = true;
215
+ result = "/" + result.replace(/^\/+/, "");
216
+ }
217
+ return { path: result, handledProtocolRelativeURL };
218
+ }
219
+ function encodePathLikeUrl(path) {
220
+ if (!/\s|[^\u0000-\u007F]/.test(path)) return path;
221
+ return path.replace(/\s|[^\u0000-\u007F]/gu, encodeURIComponent);
222
+ }
223
+ function dehydrateSsrMatchId(id) {
224
+ return id.replaceAll("/", "\0");
225
+ }
226
+ function createLRUCache(max) {
227
+ const cache = /* @__PURE__ */ new Map();
228
+ let oldest;
229
+ let newest;
230
+ const touch = (entry) => {
231
+ if (!entry.next) return;
232
+ if (!entry.prev) {
233
+ entry.next.prev = void 0;
234
+ oldest = entry.next;
235
+ entry.next = void 0;
236
+ if (newest) {
237
+ entry.prev = newest;
238
+ newest.next = entry;
239
+ }
240
+ } else {
241
+ entry.prev.next = entry.next;
242
+ entry.next.prev = entry.prev;
243
+ entry.next = void 0;
244
+ if (newest) {
245
+ newest.next = entry;
246
+ entry.prev = newest;
247
+ }
248
+ }
249
+ newest = entry;
250
+ };
251
+ return {
252
+ get(key) {
253
+ const entry = cache.get(key);
254
+ if (!entry) return void 0;
255
+ touch(entry);
256
+ return entry.value;
257
+ },
258
+ set(key, value) {
259
+ if (cache.size >= max && oldest) {
260
+ const toDelete = oldest;
261
+ cache.delete(toDelete.key);
262
+ if (toDelete.next) {
263
+ oldest = toDelete.next;
264
+ toDelete.next.prev = void 0;
265
+ }
266
+ if (toDelete === newest) {
267
+ newest = void 0;
268
+ }
269
+ }
270
+ const existing = cache.get(key);
271
+ if (existing) {
272
+ existing.value = value;
273
+ touch(existing);
274
+ } else {
275
+ const entry = { key, value, prev: newest };
276
+ if (newest) newest.next = entry;
277
+ newest = entry;
278
+ if (!oldest) oldest = entry;
279
+ cache.set(key, entry);
280
+ }
281
+ },
282
+ clear() {
283
+ cache.clear();
284
+ oldest = void 0;
285
+ newest = void 0;
286
+ }
287
+ };
288
+ }
289
+ const SEGMENT_TYPE_PATHNAME = 0;
290
+ const SEGMENT_TYPE_PARAM = 1;
291
+ const SEGMENT_TYPE_WILDCARD = 2;
292
+ const SEGMENT_TYPE_OPTIONAL_PARAM = 3;
293
+ const SEGMENT_TYPE_INDEX = 4;
294
+ const SEGMENT_TYPE_PATHLESS = 5;
295
+ function getOpenAndCloseBraces(part) {
296
+ const openBrace = part.indexOf("{");
297
+ if (openBrace === -1) return null;
298
+ const closeBrace = part.indexOf("}", openBrace);
299
+ if (closeBrace === -1) return null;
300
+ const afterOpen = openBrace + 1;
301
+ if (afterOpen >= part.length) return null;
302
+ return [openBrace, closeBrace];
303
+ }
304
+ function parseSegment(path, start, output = new Uint16Array(6)) {
305
+ const next = path.indexOf("/", start);
306
+ const end = next === -1 ? path.length : next;
307
+ const part = path.substring(start, end);
308
+ if (!part || !part.includes("$")) {
309
+ output[0] = SEGMENT_TYPE_PATHNAME;
310
+ output[1] = start;
311
+ output[2] = start;
312
+ output[3] = end;
313
+ output[4] = end;
314
+ output[5] = end;
315
+ return output;
316
+ }
317
+ if (part === "$") {
318
+ const total = path.length;
319
+ output[0] = SEGMENT_TYPE_WILDCARD;
320
+ output[1] = start;
321
+ output[2] = start;
322
+ output[3] = total;
323
+ output[4] = total;
324
+ output[5] = total;
325
+ return output;
326
+ }
327
+ if (part.charCodeAt(0) === 36) {
328
+ output[0] = SEGMENT_TYPE_PARAM;
329
+ output[1] = start;
330
+ output[2] = start + 1;
331
+ output[3] = end;
332
+ output[4] = end;
333
+ output[5] = end;
334
+ return output;
335
+ }
336
+ const braces = getOpenAndCloseBraces(part);
337
+ if (braces) {
338
+ const [openBrace, closeBrace] = braces;
339
+ const firstChar = part.charCodeAt(openBrace + 1);
340
+ if (firstChar === 45) {
341
+ if (openBrace + 2 < part.length && part.charCodeAt(openBrace + 2) === 36) {
342
+ const paramStart = openBrace + 3;
343
+ const paramEnd = closeBrace;
344
+ if (paramStart < paramEnd) {
345
+ output[0] = SEGMENT_TYPE_OPTIONAL_PARAM;
346
+ output[1] = start + openBrace;
347
+ output[2] = start + paramStart;
348
+ output[3] = start + paramEnd;
349
+ output[4] = start + closeBrace + 1;
350
+ output[5] = end;
351
+ return output;
352
+ }
353
+ }
354
+ } else if (firstChar === 36) {
355
+ const dollarPos = openBrace + 1;
356
+ const afterDollar = openBrace + 2;
357
+ if (afterDollar === closeBrace) {
358
+ output[0] = SEGMENT_TYPE_WILDCARD;
359
+ output[1] = start + openBrace;
360
+ output[2] = start + dollarPos;
361
+ output[3] = start + afterDollar;
362
+ output[4] = start + closeBrace + 1;
363
+ output[5] = path.length;
364
+ return output;
365
+ }
366
+ output[0] = SEGMENT_TYPE_PARAM;
367
+ output[1] = start + openBrace;
368
+ output[2] = start + afterDollar;
369
+ output[3] = start + closeBrace;
370
+ output[4] = start + closeBrace + 1;
371
+ output[5] = end;
372
+ return output;
373
+ }
374
+ }
375
+ output[0] = SEGMENT_TYPE_PATHNAME;
376
+ output[1] = start;
377
+ output[2] = start;
378
+ output[3] = end;
379
+ output[4] = end;
380
+ output[5] = end;
381
+ return output;
382
+ }
383
+ function parseSegments(defaultCaseSensitive, data, route, start, node, depth, onRoute) {
384
+ onRoute?.(route);
385
+ let cursor = start;
386
+ {
387
+ const path = route.fullPath ?? route.from;
388
+ const length = path.length;
389
+ const caseSensitive = route.options?.caseSensitive ?? defaultCaseSensitive;
390
+ const skipOnParamError = !!(route.options?.params?.parse && route.options?.skipRouteOnParseError?.params);
391
+ while (cursor < length) {
392
+ const segment = parseSegment(path, cursor, data);
393
+ let nextNode;
394
+ const start2 = cursor;
395
+ const end = segment[5];
396
+ cursor = end + 1;
397
+ depth++;
398
+ const kind = segment[0];
399
+ switch (kind) {
400
+ case SEGMENT_TYPE_PATHNAME: {
401
+ const value = path.substring(segment[2], segment[3]);
402
+ if (caseSensitive) {
403
+ const existingNode = node.static?.get(value);
404
+ if (existingNode) {
405
+ nextNode = existingNode;
406
+ } else {
407
+ node.static ??= /* @__PURE__ */ new Map();
408
+ const next = createStaticNode(
409
+ route.fullPath ?? route.from
410
+ );
411
+ next.parent = node;
412
+ next.depth = depth;
413
+ nextNode = next;
414
+ node.static.set(value, next);
415
+ }
416
+ } else {
417
+ const name = value.toLowerCase();
418
+ const existingNode = node.staticInsensitive?.get(name);
419
+ if (existingNode) {
420
+ nextNode = existingNode;
421
+ } else {
422
+ node.staticInsensitive ??= /* @__PURE__ */ new Map();
423
+ const next = createStaticNode(
424
+ route.fullPath ?? route.from
425
+ );
426
+ next.parent = node;
427
+ next.depth = depth;
428
+ nextNode = next;
429
+ node.staticInsensitive.set(name, next);
430
+ }
431
+ }
432
+ break;
433
+ }
434
+ case SEGMENT_TYPE_PARAM: {
435
+ const prefix_raw = path.substring(start2, segment[1]);
436
+ const suffix_raw = path.substring(segment[4], end);
437
+ const actuallyCaseSensitive = caseSensitive && !!(prefix_raw || suffix_raw);
438
+ const prefix = !prefix_raw ? void 0 : actuallyCaseSensitive ? prefix_raw : prefix_raw.toLowerCase();
439
+ const suffix = !suffix_raw ? void 0 : actuallyCaseSensitive ? suffix_raw : suffix_raw.toLowerCase();
440
+ const existingNode = !skipOnParamError && node.dynamic?.find(
441
+ (s) => !s.skipOnParamError && s.caseSensitive === actuallyCaseSensitive && s.prefix === prefix && s.suffix === suffix
442
+ );
443
+ if (existingNode) {
444
+ nextNode = existingNode;
445
+ } else {
446
+ const next = createDynamicNode(
447
+ SEGMENT_TYPE_PARAM,
448
+ route.fullPath ?? route.from,
449
+ actuallyCaseSensitive,
450
+ prefix,
451
+ suffix
452
+ );
453
+ nextNode = next;
454
+ next.depth = depth;
455
+ next.parent = node;
456
+ node.dynamic ??= [];
457
+ node.dynamic.push(next);
458
+ }
459
+ break;
460
+ }
461
+ case SEGMENT_TYPE_OPTIONAL_PARAM: {
462
+ const prefix_raw = path.substring(start2, segment[1]);
463
+ const suffix_raw = path.substring(segment[4], end);
464
+ const actuallyCaseSensitive = caseSensitive && !!(prefix_raw || suffix_raw);
465
+ const prefix = !prefix_raw ? void 0 : actuallyCaseSensitive ? prefix_raw : prefix_raw.toLowerCase();
466
+ const suffix = !suffix_raw ? void 0 : actuallyCaseSensitive ? suffix_raw : suffix_raw.toLowerCase();
467
+ const existingNode = !skipOnParamError && node.optional?.find(
468
+ (s) => !s.skipOnParamError && s.caseSensitive === actuallyCaseSensitive && s.prefix === prefix && s.suffix === suffix
469
+ );
470
+ if (existingNode) {
471
+ nextNode = existingNode;
472
+ } else {
473
+ const next = createDynamicNode(
474
+ SEGMENT_TYPE_OPTIONAL_PARAM,
475
+ route.fullPath ?? route.from,
476
+ actuallyCaseSensitive,
477
+ prefix,
478
+ suffix
479
+ );
480
+ nextNode = next;
481
+ next.parent = node;
482
+ next.depth = depth;
483
+ node.optional ??= [];
484
+ node.optional.push(next);
485
+ }
486
+ break;
487
+ }
488
+ case SEGMENT_TYPE_WILDCARD: {
489
+ const prefix_raw = path.substring(start2, segment[1]);
490
+ const suffix_raw = path.substring(segment[4], end);
491
+ const actuallyCaseSensitive = caseSensitive && !!(prefix_raw || suffix_raw);
492
+ const prefix = !prefix_raw ? void 0 : actuallyCaseSensitive ? prefix_raw : prefix_raw.toLowerCase();
493
+ const suffix = !suffix_raw ? void 0 : actuallyCaseSensitive ? suffix_raw : suffix_raw.toLowerCase();
494
+ const next = createDynamicNode(
495
+ SEGMENT_TYPE_WILDCARD,
496
+ route.fullPath ?? route.from,
497
+ actuallyCaseSensitive,
498
+ prefix,
499
+ suffix
500
+ );
501
+ nextNode = next;
502
+ next.parent = node;
503
+ next.depth = depth;
504
+ node.wildcard ??= [];
505
+ node.wildcard.push(next);
506
+ }
507
+ }
508
+ node = nextNode;
509
+ }
510
+ if (skipOnParamError && route.children && !route.isRoot && route.id && route.id.charCodeAt(route.id.lastIndexOf("/") + 1) === 95) {
511
+ const pathlessNode = createStaticNode(
512
+ route.fullPath ?? route.from
513
+ );
514
+ pathlessNode.kind = SEGMENT_TYPE_PATHLESS;
515
+ pathlessNode.parent = node;
516
+ depth++;
517
+ pathlessNode.depth = depth;
518
+ node.pathless ??= [];
519
+ node.pathless.push(pathlessNode);
520
+ node = pathlessNode;
521
+ }
522
+ const isLeaf = (route.path || !route.children) && !route.isRoot;
523
+ if (isLeaf && path.endsWith("/")) {
524
+ const indexNode = createStaticNode(
525
+ route.fullPath ?? route.from
526
+ );
527
+ indexNode.kind = SEGMENT_TYPE_INDEX;
528
+ indexNode.parent = node;
529
+ depth++;
530
+ indexNode.depth = depth;
531
+ node.index = indexNode;
532
+ node = indexNode;
533
+ }
534
+ node.parse = route.options?.params?.parse ?? null;
535
+ node.skipOnParamError = skipOnParamError;
536
+ node.parsingPriority = route.options?.skipRouteOnParseError?.priority ?? 0;
537
+ if (isLeaf && !node.route) {
538
+ node.route = route;
539
+ node.fullPath = route.fullPath ?? route.from;
540
+ }
541
+ }
542
+ if (route.children)
543
+ for (const child of route.children) {
544
+ parseSegments(
545
+ defaultCaseSensitive,
546
+ data,
547
+ child,
548
+ cursor,
549
+ node,
550
+ depth,
551
+ onRoute
552
+ );
553
+ }
554
+ }
555
+ function sortDynamic(a, b) {
556
+ if (a.skipOnParamError && !b.skipOnParamError) return -1;
557
+ if (!a.skipOnParamError && b.skipOnParamError) return 1;
558
+ if (a.skipOnParamError && b.skipOnParamError && (a.parsingPriority || b.parsingPriority))
559
+ return b.parsingPriority - a.parsingPriority;
560
+ if (a.prefix && b.prefix && a.prefix !== b.prefix) {
561
+ if (a.prefix.startsWith(b.prefix)) return -1;
562
+ if (b.prefix.startsWith(a.prefix)) return 1;
563
+ }
564
+ if (a.suffix && b.suffix && a.suffix !== b.suffix) {
565
+ if (a.suffix.endsWith(b.suffix)) return -1;
566
+ if (b.suffix.endsWith(a.suffix)) return 1;
567
+ }
568
+ if (a.prefix && !b.prefix) return -1;
569
+ if (!a.prefix && b.prefix) return 1;
570
+ if (a.suffix && !b.suffix) return -1;
571
+ if (!a.suffix && b.suffix) return 1;
572
+ if (a.caseSensitive && !b.caseSensitive) return -1;
573
+ if (!a.caseSensitive && b.caseSensitive) return 1;
574
+ return 0;
575
+ }
576
+ function sortTreeNodes(node) {
577
+ if (node.pathless) {
578
+ for (const child of node.pathless) {
579
+ sortTreeNodes(child);
580
+ }
581
+ }
582
+ if (node.static) {
583
+ for (const child of node.static.values()) {
584
+ sortTreeNodes(child);
585
+ }
586
+ }
587
+ if (node.staticInsensitive) {
588
+ for (const child of node.staticInsensitive.values()) {
589
+ sortTreeNodes(child);
590
+ }
591
+ }
592
+ if (node.dynamic?.length) {
593
+ node.dynamic.sort(sortDynamic);
594
+ for (const child of node.dynamic) {
595
+ sortTreeNodes(child);
596
+ }
597
+ }
598
+ if (node.optional?.length) {
599
+ node.optional.sort(sortDynamic);
600
+ for (const child of node.optional) {
601
+ sortTreeNodes(child);
602
+ }
603
+ }
604
+ if (node.wildcard?.length) {
605
+ node.wildcard.sort(sortDynamic);
606
+ for (const child of node.wildcard) {
607
+ sortTreeNodes(child);
608
+ }
609
+ }
610
+ }
611
+ function createStaticNode(fullPath) {
612
+ return {
613
+ kind: SEGMENT_TYPE_PATHNAME,
614
+ depth: 0,
615
+ pathless: null,
616
+ index: null,
617
+ static: null,
618
+ staticInsensitive: null,
619
+ dynamic: null,
620
+ optional: null,
621
+ wildcard: null,
622
+ route: null,
623
+ fullPath,
624
+ parent: null,
625
+ parse: null,
626
+ skipOnParamError: false,
627
+ parsingPriority: 0
628
+ };
629
+ }
630
+ function createDynamicNode(kind, fullPath, caseSensitive, prefix, suffix) {
631
+ return {
632
+ kind,
633
+ depth: 0,
634
+ pathless: null,
635
+ index: null,
636
+ static: null,
637
+ staticInsensitive: null,
638
+ dynamic: null,
639
+ optional: null,
640
+ wildcard: null,
641
+ route: null,
642
+ fullPath,
643
+ parent: null,
644
+ parse: null,
645
+ skipOnParamError: false,
646
+ parsingPriority: 0,
647
+ caseSensitive,
648
+ prefix,
649
+ suffix
650
+ };
651
+ }
652
+ function processRouteMasks(routeList, processedTree) {
653
+ const segmentTree = createStaticNode("/");
654
+ const data = new Uint16Array(6);
655
+ for (const route of routeList) {
656
+ parseSegments(false, data, route, 1, segmentTree, 0);
657
+ }
658
+ sortTreeNodes(segmentTree);
659
+ processedTree.masksTree = segmentTree;
660
+ processedTree.flatCache = createLRUCache(1e3);
661
+ }
662
+ function findFlatMatch(path, processedTree) {
663
+ path ||= "/";
664
+ const cached = processedTree.flatCache.get(path);
665
+ if (cached) return cached;
666
+ const result = findMatch(path, processedTree.masksTree);
667
+ processedTree.flatCache.set(path, result);
668
+ return result;
669
+ }
670
+ function findSingleMatch(from, caseSensitive, fuzzy, path, processedTree) {
671
+ from ||= "/";
672
+ path ||= "/";
673
+ const key = caseSensitive ? `case\0${from}` : from;
674
+ let tree = processedTree.singleCache.get(key);
675
+ if (!tree) {
676
+ tree = createStaticNode("/");
677
+ const data = new Uint16Array(6);
678
+ parseSegments(caseSensitive, data, { from }, 1, tree, 0);
679
+ processedTree.singleCache.set(key, tree);
680
+ }
681
+ return findMatch(path, tree, fuzzy);
682
+ }
683
+ function findRouteMatch(path, processedTree, fuzzy = false) {
684
+ const key = fuzzy ? path : `nofuzz\0${path}`;
685
+ const cached = processedTree.matchCache.get(key);
686
+ if (cached !== void 0) return cached;
687
+ path ||= "/";
688
+ let result;
689
+ try {
690
+ result = findMatch(
691
+ path,
692
+ processedTree.segmentTree,
693
+ fuzzy
694
+ );
695
+ } catch (err) {
696
+ if (err instanceof URIError) {
697
+ result = null;
698
+ } else {
699
+ throw err;
700
+ }
701
+ }
702
+ if (result) result.branch = buildRouteBranch(result.route);
703
+ processedTree.matchCache.set(key, result);
704
+ return result;
705
+ }
706
+ function trimPathRight$1(path) {
707
+ return path === "/" ? path : path.replace(/\/{1,}$/, "");
708
+ }
709
+ function processRouteTree(routeTree, caseSensitive = false, initRoute) {
710
+ const segmentTree = createStaticNode(routeTree.fullPath);
711
+ const data = new Uint16Array(6);
712
+ const routesById = {};
713
+ const routesByPath = {};
714
+ let index = 0;
715
+ parseSegments(caseSensitive, data, routeTree, 1, segmentTree, 0, (route) => {
716
+ initRoute?.(route, index);
717
+ invariant(
718
+ !(route.id in routesById),
719
+ `Duplicate routes found with id: ${String(route.id)}`
720
+ );
721
+ routesById[route.id] = route;
722
+ if (index !== 0 && route.path) {
723
+ const trimmedFullPath = trimPathRight$1(route.fullPath);
724
+ if (!routesByPath[trimmedFullPath] || route.fullPath.endsWith("/")) {
725
+ routesByPath[trimmedFullPath] = route;
726
+ }
727
+ }
728
+ index++;
729
+ });
730
+ sortTreeNodes(segmentTree);
731
+ const processedTree = {
732
+ segmentTree,
733
+ singleCache: createLRUCache(1e3),
734
+ matchCache: createLRUCache(1e3),
735
+ flatCache: null,
736
+ masksTree: null
737
+ };
738
+ return {
739
+ processedTree,
740
+ routesById,
741
+ routesByPath
742
+ };
743
+ }
744
+ function findMatch(path, segmentTree, fuzzy = false) {
745
+ const parts = path.split("/");
746
+ const leaf = getNodeMatch(path, parts, segmentTree, fuzzy);
747
+ if (!leaf) return null;
748
+ const [rawParams] = extractParams(path, parts, leaf);
749
+ return {
750
+ route: leaf.node.route,
751
+ rawParams,
752
+ parsedParams: leaf.parsedParams
753
+ };
754
+ }
755
+ function extractParams(path, parts, leaf) {
756
+ const list = buildBranch(leaf.node);
757
+ let nodeParts = null;
758
+ const rawParams = {};
759
+ let partIndex = leaf.extract?.part ?? 0;
760
+ let nodeIndex = leaf.extract?.node ?? 0;
761
+ let pathIndex = leaf.extract?.path ?? 0;
762
+ let segmentCount = leaf.extract?.segment ?? 0;
763
+ for (; nodeIndex < list.length; partIndex++, nodeIndex++, pathIndex++, segmentCount++) {
764
+ const node = list[nodeIndex];
765
+ if (node.kind === SEGMENT_TYPE_INDEX) break;
766
+ if (node.kind === SEGMENT_TYPE_PATHLESS) {
767
+ segmentCount--;
768
+ partIndex--;
769
+ pathIndex--;
770
+ continue;
771
+ }
772
+ const part = parts[partIndex];
773
+ const currentPathIndex = pathIndex;
774
+ if (part) pathIndex += part.length;
775
+ if (node.kind === SEGMENT_TYPE_PARAM) {
776
+ nodeParts ??= leaf.node.fullPath.split("/");
777
+ const nodePart = nodeParts[segmentCount];
778
+ const preLength = node.prefix?.length ?? 0;
779
+ const isCurlyBraced = nodePart.charCodeAt(preLength) === 123;
780
+ if (isCurlyBraced) {
781
+ const sufLength = node.suffix?.length ?? 0;
782
+ const name = nodePart.substring(
783
+ preLength + 2,
784
+ nodePart.length - sufLength - 1
785
+ );
786
+ const value = part.substring(preLength, part.length - sufLength);
787
+ rawParams[name] = decodeURIComponent(value);
788
+ } else {
789
+ const name = nodePart.substring(1);
790
+ rawParams[name] = decodeURIComponent(part);
791
+ }
792
+ } else if (node.kind === SEGMENT_TYPE_OPTIONAL_PARAM) {
793
+ if (leaf.skipped & 1 << nodeIndex) {
794
+ partIndex--;
795
+ pathIndex = currentPathIndex - 1;
796
+ continue;
797
+ }
798
+ nodeParts ??= leaf.node.fullPath.split("/");
799
+ const nodePart = nodeParts[segmentCount];
800
+ const preLength = node.prefix?.length ?? 0;
801
+ const sufLength = node.suffix?.length ?? 0;
802
+ const name = nodePart.substring(
803
+ preLength + 3,
804
+ nodePart.length - sufLength - 1
805
+ );
806
+ const value = node.suffix || node.prefix ? part.substring(preLength, part.length - sufLength) : part;
807
+ if (value) rawParams[name] = decodeURIComponent(value);
808
+ } else if (node.kind === SEGMENT_TYPE_WILDCARD) {
809
+ const n = node;
810
+ const value = path.substring(
811
+ currentPathIndex + (n.prefix?.length ?? 0),
812
+ path.length - (n.suffix?.length ?? 0)
813
+ );
814
+ const splat = decodeURIComponent(value);
815
+ rawParams["*"] = splat;
816
+ rawParams._splat = splat;
817
+ break;
818
+ }
819
+ }
820
+ if (leaf.rawParams) Object.assign(rawParams, leaf.rawParams);
821
+ return [
822
+ rawParams,
823
+ {
824
+ part: partIndex,
825
+ node: nodeIndex,
826
+ path: pathIndex,
827
+ segment: segmentCount
828
+ }
829
+ ];
830
+ }
831
+ function buildRouteBranch(route) {
832
+ const list = [route];
833
+ while (route.parentRoute) {
834
+ route = route.parentRoute;
835
+ list.push(route);
836
+ }
837
+ list.reverse();
838
+ return list;
839
+ }
840
+ function buildBranch(node) {
841
+ const list = Array(node.depth + 1);
842
+ do {
843
+ list[node.depth] = node;
844
+ node = node.parent;
845
+ } while (node);
846
+ return list;
847
+ }
848
+ function getNodeMatch(path, parts, segmentTree, fuzzy) {
849
+ if (path === "/" && segmentTree.index)
850
+ return { node: segmentTree.index, skipped: 0 };
851
+ const trailingSlash = !last(parts);
852
+ const pathIsIndex = trailingSlash && path !== "/";
853
+ const partsLength = parts.length - (trailingSlash ? 1 : 0);
854
+ const stack = [
855
+ {
856
+ node: segmentTree,
857
+ index: 1,
858
+ skipped: 0,
859
+ depth: 1,
860
+ statics: 1,
861
+ dynamics: 0,
862
+ optionals: 0
863
+ }
864
+ ];
865
+ let wildcardMatch = null;
866
+ let bestFuzzy = null;
867
+ let bestMatch = null;
868
+ while (stack.length) {
869
+ const frame = stack.pop();
870
+ const { node, index, skipped, depth, statics, dynamics, optionals } = frame;
871
+ let { extract, rawParams, parsedParams } = frame;
872
+ if (node.skipOnParamError) {
873
+ const result = validateMatchParams(path, parts, frame);
874
+ if (!result) continue;
875
+ rawParams = frame.rawParams;
876
+ extract = frame.extract;
877
+ parsedParams = frame.parsedParams;
878
+ }
879
+ if (fuzzy && node.route && node.kind !== SEGMENT_TYPE_INDEX && isFrameMoreSpecific(bestFuzzy, frame)) {
880
+ bestFuzzy = frame;
881
+ }
882
+ const isBeyondPath = index === partsLength;
883
+ if (isBeyondPath) {
884
+ if (node.route && !pathIsIndex && isFrameMoreSpecific(bestMatch, frame)) {
885
+ bestMatch = frame;
886
+ }
887
+ if (!node.optional && !node.wildcard && !node.index && !node.pathless)
888
+ continue;
889
+ }
890
+ const part = isBeyondPath ? void 0 : parts[index];
891
+ let lowerPart;
892
+ if (isBeyondPath && node.index) {
893
+ const indexFrame = {
894
+ node: node.index,
895
+ index,
896
+ skipped,
897
+ depth: depth + 1,
898
+ statics,
899
+ dynamics,
900
+ optionals,
901
+ extract,
902
+ rawParams,
903
+ parsedParams
904
+ };
905
+ let indexValid = true;
906
+ if (node.index.skipOnParamError) {
907
+ const result = validateMatchParams(path, parts, indexFrame);
908
+ if (!result) indexValid = false;
909
+ }
910
+ if (indexValid) {
911
+ if (statics === partsLength && !dynamics && !optionals && !skipped) {
912
+ return indexFrame;
913
+ }
914
+ if (isFrameMoreSpecific(bestMatch, indexFrame)) {
915
+ bestMatch = indexFrame;
916
+ }
917
+ }
918
+ }
919
+ if (node.wildcard && isFrameMoreSpecific(wildcardMatch, frame)) {
920
+ for (const segment of node.wildcard) {
921
+ const { prefix, suffix } = segment;
922
+ if (prefix) {
923
+ if (isBeyondPath) continue;
924
+ const casePart = segment.caseSensitive ? part : lowerPart ??= part.toLowerCase();
925
+ if (!casePart.startsWith(prefix)) continue;
926
+ }
927
+ if (suffix) {
928
+ if (isBeyondPath) continue;
929
+ const end = parts.slice(index).join("/").slice(-suffix.length);
930
+ const casePart = segment.caseSensitive ? end : end.toLowerCase();
931
+ if (casePart !== suffix) continue;
932
+ }
933
+ const frame2 = {
934
+ node: segment,
935
+ index: partsLength,
936
+ skipped,
937
+ depth,
938
+ statics,
939
+ dynamics,
940
+ optionals,
941
+ extract,
942
+ rawParams,
943
+ parsedParams
944
+ };
945
+ if (segment.skipOnParamError) {
946
+ const result = validateMatchParams(path, parts, frame2);
947
+ if (!result) continue;
948
+ }
949
+ wildcardMatch = frame2;
950
+ break;
951
+ }
952
+ }
953
+ if (node.optional) {
954
+ const nextSkipped = skipped | 1 << depth;
955
+ const nextDepth = depth + 1;
956
+ for (let i = node.optional.length - 1; i >= 0; i--) {
957
+ const segment = node.optional[i];
958
+ stack.push({
959
+ node: segment,
960
+ index,
961
+ skipped: nextSkipped,
962
+ depth: nextDepth,
963
+ statics,
964
+ dynamics,
965
+ optionals,
966
+ extract,
967
+ rawParams,
968
+ parsedParams
969
+ });
970
+ }
971
+ if (!isBeyondPath) {
972
+ for (let i = node.optional.length - 1; i >= 0; i--) {
973
+ const segment = node.optional[i];
974
+ const { prefix, suffix } = segment;
975
+ if (prefix || suffix) {
976
+ const casePart = segment.caseSensitive ? part : lowerPart ??= part.toLowerCase();
977
+ if (prefix && !casePart.startsWith(prefix)) continue;
978
+ if (suffix && !casePart.endsWith(suffix)) continue;
979
+ }
980
+ stack.push({
981
+ node: segment,
982
+ index: index + 1,
983
+ skipped,
984
+ depth: nextDepth,
985
+ statics,
986
+ dynamics,
987
+ optionals: optionals + 1,
988
+ extract,
989
+ rawParams,
990
+ parsedParams
991
+ });
992
+ }
993
+ }
994
+ }
995
+ if (!isBeyondPath && node.dynamic && part) {
996
+ for (let i = node.dynamic.length - 1; i >= 0; i--) {
997
+ const segment = node.dynamic[i];
998
+ const { prefix, suffix } = segment;
999
+ if (prefix || suffix) {
1000
+ const casePart = segment.caseSensitive ? part : lowerPart ??= part.toLowerCase();
1001
+ if (prefix && !casePart.startsWith(prefix)) continue;
1002
+ if (suffix && !casePart.endsWith(suffix)) continue;
1003
+ }
1004
+ stack.push({
1005
+ node: segment,
1006
+ index: index + 1,
1007
+ skipped,
1008
+ depth: depth + 1,
1009
+ statics,
1010
+ dynamics: dynamics + 1,
1011
+ optionals,
1012
+ extract,
1013
+ rawParams,
1014
+ parsedParams
1015
+ });
1016
+ }
1017
+ }
1018
+ if (!isBeyondPath && node.staticInsensitive) {
1019
+ const match = node.staticInsensitive.get(
1020
+ lowerPart ??= part.toLowerCase()
1021
+ );
1022
+ if (match) {
1023
+ stack.push({
1024
+ node: match,
1025
+ index: index + 1,
1026
+ skipped,
1027
+ depth: depth + 1,
1028
+ statics: statics + 1,
1029
+ dynamics,
1030
+ optionals,
1031
+ extract,
1032
+ rawParams,
1033
+ parsedParams
1034
+ });
1035
+ }
1036
+ }
1037
+ if (!isBeyondPath && node.static) {
1038
+ const match = node.static.get(part);
1039
+ if (match) {
1040
+ stack.push({
1041
+ node: match,
1042
+ index: index + 1,
1043
+ skipped,
1044
+ depth: depth + 1,
1045
+ statics: statics + 1,
1046
+ dynamics,
1047
+ optionals,
1048
+ extract,
1049
+ rawParams,
1050
+ parsedParams
1051
+ });
1052
+ }
1053
+ }
1054
+ if (node.pathless) {
1055
+ const nextDepth = depth + 1;
1056
+ for (let i = node.pathless.length - 1; i >= 0; i--) {
1057
+ const segment = node.pathless[i];
1058
+ stack.push({
1059
+ node: segment,
1060
+ index,
1061
+ skipped,
1062
+ depth: nextDepth,
1063
+ statics,
1064
+ dynamics,
1065
+ optionals,
1066
+ extract,
1067
+ rawParams,
1068
+ parsedParams
1069
+ });
1070
+ }
1071
+ }
1072
+ }
1073
+ if (bestMatch && wildcardMatch) {
1074
+ return isFrameMoreSpecific(wildcardMatch, bestMatch) ? bestMatch : wildcardMatch;
1075
+ }
1076
+ if (bestMatch) return bestMatch;
1077
+ if (wildcardMatch) return wildcardMatch;
1078
+ if (fuzzy && bestFuzzy) {
1079
+ let sliceIndex = bestFuzzy.index;
1080
+ for (let i = 0; i < bestFuzzy.index; i++) {
1081
+ sliceIndex += parts[i].length;
1082
+ }
1083
+ const splat = sliceIndex === path.length ? "/" : path.slice(sliceIndex);
1084
+ bestFuzzy.rawParams ??= {};
1085
+ bestFuzzy.rawParams["**"] = decodeURIComponent(splat);
1086
+ return bestFuzzy;
1087
+ }
1088
+ return null;
1089
+ }
1090
+ function validateMatchParams(path, parts, frame) {
1091
+ try {
1092
+ const [rawParams, state] = extractParams(path, parts, frame);
1093
+ frame.rawParams = rawParams;
1094
+ frame.extract = state;
1095
+ const parsed = frame.node.parse(rawParams);
1096
+ frame.parsedParams = Object.assign({}, frame.parsedParams, parsed);
1097
+ return true;
1098
+ } catch {
1099
+ return null;
1100
+ }
1101
+ }
1102
+ function isFrameMoreSpecific(prev, next) {
1103
+ if (!prev) return true;
1104
+ return next.statics > prev.statics || next.statics === prev.statics && (next.dynamics > prev.dynamics || next.dynamics === prev.dynamics && (next.optionals > prev.optionals || next.optionals === prev.optionals && ((next.node.kind === SEGMENT_TYPE_INDEX) > (prev.node.kind === SEGMENT_TYPE_INDEX) || next.node.kind === SEGMENT_TYPE_INDEX === (prev.node.kind === SEGMENT_TYPE_INDEX) && next.depth > prev.depth)));
1105
+ }
1106
+ function joinPaths(paths) {
1107
+ return cleanPath(
1108
+ paths.filter((val) => {
1109
+ return val !== void 0;
1110
+ }).join("/")
1111
+ );
1112
+ }
1113
+ function cleanPath(path) {
1114
+ return path.replace(/\/{2,}/g, "/");
1115
+ }
1116
+ function trimPathLeft(path) {
1117
+ return path === "/" ? path : path.replace(/^\/{1,}/, "");
1118
+ }
1119
+ function trimPathRight(path) {
1120
+ const len = path.length;
1121
+ return len > 1 && path[len - 1] === "/" ? path.replace(/\/{1,}$/, "") : path;
1122
+ }
1123
+ function trimPath(path) {
1124
+ return trimPathRight(trimPathLeft(path));
1125
+ }
1126
+ function removeTrailingSlash(value, basepath) {
1127
+ if (value?.endsWith("/") && value !== "/" && value !== `${basepath}/`) {
1128
+ return value.slice(0, -1);
1129
+ }
1130
+ return value;
1131
+ }
1132
+ function exactPathTest(pathName1, pathName2, basepath) {
1133
+ return removeTrailingSlash(pathName1, basepath) === removeTrailingSlash(pathName2, basepath);
1134
+ }
1135
+ function resolvePath({
1136
+ base,
1137
+ to,
1138
+ trailingSlash = "never",
1139
+ cache
1140
+ }) {
1141
+ const isAbsolute = to.startsWith("/");
1142
+ const isBase = !isAbsolute && to === ".";
1143
+ let key;
1144
+ if (cache) {
1145
+ key = isAbsolute ? to : isBase ? base : base + "\0" + to;
1146
+ const cached = cache.get(key);
1147
+ if (cached) return cached;
1148
+ }
1149
+ let baseSegments;
1150
+ if (isBase) {
1151
+ baseSegments = base.split("/");
1152
+ } else if (isAbsolute) {
1153
+ baseSegments = to.split("/");
1154
+ } else {
1155
+ baseSegments = base.split("/");
1156
+ while (baseSegments.length > 1 && last(baseSegments) === "") {
1157
+ baseSegments.pop();
1158
+ }
1159
+ const toSegments = to.split("/");
1160
+ for (let index = 0, length = toSegments.length; index < length; index++) {
1161
+ const value = toSegments[index];
1162
+ if (value === "") {
1163
+ if (!index) {
1164
+ baseSegments = [value];
1165
+ } else if (index === length - 1) {
1166
+ baseSegments.push(value);
1167
+ } else ;
1168
+ } else if (value === "..") {
1169
+ baseSegments.pop();
1170
+ } else if (value === ".") ;
1171
+ else {
1172
+ baseSegments.push(value);
1173
+ }
1174
+ }
1175
+ }
1176
+ if (baseSegments.length > 1) {
1177
+ if (last(baseSegments) === "") {
1178
+ if (trailingSlash === "never") {
1179
+ baseSegments.pop();
1180
+ }
1181
+ } else if (trailingSlash === "always") {
1182
+ baseSegments.push("");
1183
+ }
1184
+ }
1185
+ let segment;
1186
+ let joined = "";
1187
+ for (let i = 0; i < baseSegments.length; i++) {
1188
+ if (i > 0) joined += "/";
1189
+ const part = baseSegments[i];
1190
+ if (!part) continue;
1191
+ segment = parseSegment(part, 0, segment);
1192
+ const kind = segment[0];
1193
+ if (kind === SEGMENT_TYPE_PATHNAME) {
1194
+ joined += part;
1195
+ continue;
1196
+ }
1197
+ const end = segment[5];
1198
+ const prefix = part.substring(0, segment[1]);
1199
+ const suffix = part.substring(segment[4], end);
1200
+ const value = part.substring(segment[2], segment[3]);
1201
+ if (kind === SEGMENT_TYPE_PARAM) {
1202
+ joined += prefix || suffix ? `${prefix}{$${value}}${suffix}` : `$${value}`;
1203
+ } else if (kind === SEGMENT_TYPE_WILDCARD) {
1204
+ joined += prefix || suffix ? `${prefix}{$}${suffix}` : "$";
1205
+ } else {
1206
+ joined += `${prefix}{-$${value}}${suffix}`;
1207
+ }
1208
+ }
1209
+ joined = cleanPath(joined);
1210
+ const result = joined || "/";
1211
+ if (key && cache) cache.set(key, result);
1212
+ return result;
1213
+ }
1214
+ function compileDecodeCharMap(pathParamsAllowedCharacters) {
1215
+ const charMap = new Map(
1216
+ pathParamsAllowedCharacters.map((char) => [encodeURIComponent(char), char])
1217
+ );
1218
+ const pattern = Array.from(charMap.keys()).map((key) => key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
1219
+ const regex = new RegExp(pattern, "g");
1220
+ return (encoded) => encoded.replace(regex, (match) => charMap.get(match) ?? match);
1221
+ }
1222
+ function encodeParam(key, params, decoder) {
1223
+ const value = params[key];
1224
+ if (typeof value !== "string") return value;
1225
+ if (key === "_splat") {
1226
+ if (/^[a-zA-Z0-9\-._~!/]*$/.test(value)) return value;
1227
+ return value.split("/").map((segment) => encodePathParam(segment, decoder)).join("/");
1228
+ } else {
1229
+ return encodePathParam(value, decoder);
1230
+ }
1231
+ }
1232
+ function interpolatePath({
1233
+ path,
1234
+ params,
1235
+ decoder,
1236
+ // `server` is marked @internal and stripped from .d.ts by `stripInternal`.
1237
+ // We avoid destructuring it in the function signature so the emitted
1238
+ // declaration doesn't reference a property that no longer exists.
1239
+ ...rest
1240
+ }) {
1241
+ let isMissingParams = false;
1242
+ const usedParams = {};
1243
+ if (!path || path === "/")
1244
+ return { interpolatedPath: "/", usedParams, isMissingParams };
1245
+ if (!path.includes("$"))
1246
+ return { interpolatedPath: path, usedParams, isMissingParams };
1247
+ {
1248
+ if (path.indexOf("{") === -1) {
1249
+ const length2 = path.length;
1250
+ let cursor2 = 0;
1251
+ let joined2 = "";
1252
+ while (cursor2 < length2) {
1253
+ while (cursor2 < length2 && path.charCodeAt(cursor2) === 47) cursor2++;
1254
+ if (cursor2 >= length2) break;
1255
+ const start = cursor2;
1256
+ let end = path.indexOf("/", cursor2);
1257
+ if (end === -1) end = length2;
1258
+ cursor2 = end;
1259
+ const part = path.substring(start, end);
1260
+ if (!part) continue;
1261
+ if (part.charCodeAt(0) === 36) {
1262
+ if (part.length === 1) {
1263
+ const splat = params._splat;
1264
+ usedParams._splat = splat;
1265
+ usedParams["*"] = splat;
1266
+ if (!splat) {
1267
+ isMissingParams = true;
1268
+ continue;
1269
+ }
1270
+ const value = encodeParam("_splat", params, decoder);
1271
+ joined2 += "/" + value;
1272
+ } else {
1273
+ const key = part.substring(1);
1274
+ if (!isMissingParams && !(key in params)) {
1275
+ isMissingParams = true;
1276
+ }
1277
+ usedParams[key] = params[key];
1278
+ const value = encodeParam(key, params, decoder) ?? "undefined";
1279
+ joined2 += "/" + value;
1280
+ }
1281
+ } else {
1282
+ joined2 += "/" + part;
1283
+ }
1284
+ }
1285
+ if (path.endsWith("/")) joined2 += "/";
1286
+ const interpolatedPath2 = joined2 || "/";
1287
+ return { usedParams, interpolatedPath: interpolatedPath2, isMissingParams };
1288
+ }
1289
+ }
1290
+ const length = path.length;
1291
+ let cursor = 0;
1292
+ let segment;
1293
+ let joined = "";
1294
+ while (cursor < length) {
1295
+ const start = cursor;
1296
+ segment = parseSegment(path, start, segment);
1297
+ const end = segment[5];
1298
+ cursor = end + 1;
1299
+ if (start === end) continue;
1300
+ const kind = segment[0];
1301
+ if (kind === SEGMENT_TYPE_PATHNAME) {
1302
+ joined += "/" + path.substring(start, end);
1303
+ continue;
1304
+ }
1305
+ if (kind === SEGMENT_TYPE_WILDCARD) {
1306
+ const splat = params._splat;
1307
+ usedParams._splat = splat;
1308
+ usedParams["*"] = splat;
1309
+ const prefix = path.substring(start, segment[1]);
1310
+ const suffix = path.substring(segment[4], end);
1311
+ if (!splat) {
1312
+ isMissingParams = true;
1313
+ if (prefix || suffix) {
1314
+ joined += "/" + prefix + suffix;
1315
+ }
1316
+ continue;
1317
+ }
1318
+ const value = encodeParam("_splat", params, decoder);
1319
+ joined += "/" + prefix + value + suffix;
1320
+ continue;
1321
+ }
1322
+ if (kind === SEGMENT_TYPE_PARAM) {
1323
+ const key = path.substring(segment[2], segment[3]);
1324
+ if (!isMissingParams && !(key in params)) {
1325
+ isMissingParams = true;
1326
+ }
1327
+ usedParams[key] = params[key];
1328
+ const prefix = path.substring(start, segment[1]);
1329
+ const suffix = path.substring(segment[4], end);
1330
+ const value = encodeParam(key, params, decoder) ?? "undefined";
1331
+ joined += "/" + prefix + value + suffix;
1332
+ continue;
1333
+ }
1334
+ if (kind === SEGMENT_TYPE_OPTIONAL_PARAM) {
1335
+ const key = path.substring(segment[2], segment[3]);
1336
+ const valueRaw = params[key];
1337
+ if (valueRaw == null) continue;
1338
+ usedParams[key] = valueRaw;
1339
+ const prefix = path.substring(start, segment[1]);
1340
+ const suffix = path.substring(segment[4], end);
1341
+ const value = encodeParam(key, params, decoder) ?? "";
1342
+ joined += "/" + prefix + value + suffix;
1343
+ continue;
1344
+ }
1345
+ }
1346
+ if (path.endsWith("/")) joined += "/";
1347
+ const interpolatedPath = joined || "/";
1348
+ return { usedParams, interpolatedPath, isMissingParams };
1349
+ }
1350
+ function encodePathParam(value, decoder) {
1351
+ const encoded = encodeURIComponent(value);
1352
+ return decoder?.(encoded) ?? encoded;
1353
+ }
1354
+ function getSafeSessionStorage() {
1355
+ try {
1356
+ if (typeof window !== "undefined" && typeof window.sessionStorage === "object") {
1357
+ return window.sessionStorage;
1358
+ }
1359
+ } catch {
1360
+ }
1361
+ return void 0;
1362
+ }
1363
+ const storageKey = "tsr-scroll-restoration-v1_3";
1364
+ function createScrollRestorationCache() {
1365
+ const safeSessionStorage = getSafeSessionStorage();
1366
+ if (!safeSessionStorage) {
1367
+ return null;
1368
+ }
1369
+ const persistedState = safeSessionStorage.getItem(storageKey);
1370
+ let state = persistedState ? JSON.parse(persistedState) : {};
1371
+ return {
1372
+ state,
1373
+ // This setter is simply to make sure that we set the sessionStorage right
1374
+ // after the state is updated. It doesn't necessarily need to be a functional
1375
+ // update.
1376
+ set: (updater) => {
1377
+ state = functionalUpdate(updater, state) || state;
1378
+ try {
1379
+ safeSessionStorage.setItem(storageKey, JSON.stringify(state));
1380
+ } catch {
1381
+ console.warn(
1382
+ "[ts-router] Could not persist scroll restoration state to sessionStorage."
1383
+ );
1384
+ }
1385
+ }
1386
+ };
1387
+ }
1388
+ createScrollRestorationCache();
1389
+ const defaultGetScrollRestorationKey = (location) => {
1390
+ return location.state.__TSR_key || location.href;
1391
+ };
1392
+ function restoreScroll({
1393
+ storageKey: storageKey2,
1394
+ key,
1395
+ behavior,
1396
+ shouldScrollRestoration,
1397
+ scrollToTopSelectors,
1398
+ location
1399
+ }) {
1400
+ let byKey;
1401
+ try {
1402
+ byKey = JSON.parse(sessionStorage.getItem(storageKey2) || "{}");
1403
+ } catch (error) {
1404
+ console.error(error);
1405
+ return;
1406
+ }
1407
+ const resolvedKey = key || window.history.state?.__TSR_key;
1408
+ const elementEntries = byKey[resolvedKey];
1409
+ scroll: {
1410
+ if (shouldScrollRestoration && elementEntries && Object.keys(elementEntries).length > 0) {
1411
+ for (const elementSelector in elementEntries) {
1412
+ const entry = elementEntries[elementSelector];
1413
+ if (elementSelector === "window") {
1414
+ window.scrollTo({
1415
+ top: entry.scrollY,
1416
+ left: entry.scrollX,
1417
+ behavior
1418
+ });
1419
+ } else if (elementSelector) {
1420
+ const element = document.querySelector(elementSelector);
1421
+ if (element) {
1422
+ element.scrollLeft = entry.scrollX;
1423
+ element.scrollTop = entry.scrollY;
1424
+ }
1425
+ }
1426
+ }
1427
+ break scroll;
1428
+ }
1429
+ const hash = (location ?? window.location).hash.split("#", 2)[1];
1430
+ if (hash) {
1431
+ const hashScrollIntoViewOptions = window.history.state?.__hashScrollIntoViewOptions ?? true;
1432
+ if (hashScrollIntoViewOptions) {
1433
+ const el = document.getElementById(hash);
1434
+ if (el) {
1435
+ el.scrollIntoView(hashScrollIntoViewOptions);
1436
+ }
1437
+ }
1438
+ break scroll;
1439
+ }
1440
+ const scrollOptions = { top: 0, left: 0, behavior };
1441
+ window.scrollTo(scrollOptions);
1442
+ if (scrollToTopSelectors) {
1443
+ for (const selector of scrollToTopSelectors) {
1444
+ if (selector === "window") continue;
1445
+ const element = typeof selector === "function" ? selector() : document.querySelector(selector);
1446
+ if (element) element.scrollTo(scrollOptions);
1447
+ }
1448
+ }
1449
+ }
1450
+ }
1451
+ function encode(obj, stringify = String) {
1452
+ const result = new URLSearchParams();
1453
+ for (const key in obj) {
1454
+ const val = obj[key];
1455
+ if (val !== void 0) {
1456
+ result.set(key, stringify(val));
1457
+ }
1458
+ }
1459
+ return result.toString();
1460
+ }
1461
+ function toValue(str) {
1462
+ if (!str) return "";
1463
+ if (str === "false") return false;
1464
+ if (str === "true") return true;
1465
+ return +str * 0 === 0 && +str + "" === str ? +str : str;
1466
+ }
1467
+ function decode(str) {
1468
+ const searchParams = new URLSearchParams(str);
1469
+ const result = {};
1470
+ for (const [key, value] of searchParams.entries()) {
1471
+ const previousValue = result[key];
1472
+ if (previousValue == null) {
1473
+ result[key] = toValue(value);
1474
+ } else if (Array.isArray(previousValue)) {
1475
+ previousValue.push(toValue(value));
1476
+ } else {
1477
+ result[key] = [previousValue, toValue(value)];
1478
+ }
1479
+ }
1480
+ return result;
1481
+ }
1482
+ const defaultParseSearch = parseSearchWith(JSON.parse);
1483
+ const defaultStringifySearch = stringifySearchWith(
1484
+ JSON.stringify,
1485
+ JSON.parse
1486
+ );
1487
+ function parseSearchWith(parser) {
1488
+ return (searchStr) => {
1489
+ if (searchStr[0] === "?") {
1490
+ searchStr = searchStr.substring(1);
1491
+ }
1492
+ const query = decode(searchStr);
1493
+ for (const key in query) {
1494
+ const value = query[key];
1495
+ if (typeof value === "string") {
1496
+ try {
1497
+ query[key] = parser(value);
1498
+ } catch (_err) {
1499
+ }
1500
+ }
1501
+ }
1502
+ return query;
1503
+ };
1504
+ }
1505
+ function stringifySearchWith(stringify, parser) {
1506
+ const hasParser = typeof parser === "function";
1507
+ function stringifyValue(val) {
1508
+ if (typeof val === "object" && val !== null) {
1509
+ try {
1510
+ return stringify(val);
1511
+ } catch (_err) {
1512
+ }
1513
+ } else if (hasParser && typeof val === "string") {
1514
+ try {
1515
+ parser(val);
1516
+ return stringify(val);
1517
+ } catch (_err) {
1518
+ }
1519
+ }
1520
+ return val;
1521
+ }
1522
+ return (search) => {
1523
+ const searchStr = encode(search, stringifyValue);
1524
+ return searchStr ? `?${searchStr}` : "";
1525
+ };
1526
+ }
1527
+ const rootRouteId = "__root__";
1528
+ function redirect(opts) {
1529
+ opts.statusCode = opts.statusCode || opts.code || 307;
1530
+ if (!opts._builtLocation && !opts.reloadDocument && typeof opts.href === "string") {
1531
+ try {
1532
+ new URL(opts.href);
1533
+ opts.reloadDocument = true;
1534
+ } catch {
1535
+ }
1536
+ }
1537
+ const headers = new Headers(opts.headers);
1538
+ if (opts.href && headers.get("Location") === null) {
1539
+ headers.set("Location", opts.href);
1540
+ }
1541
+ const response = new Response(null, {
1542
+ status: opts.statusCode,
1543
+ headers
1544
+ });
1545
+ response.options = opts;
1546
+ if (opts.throw) {
1547
+ throw response;
1548
+ }
1549
+ return response;
1550
+ }
1551
+ function isRedirect(obj) {
1552
+ return obj instanceof Response && !!obj.options;
1553
+ }
1554
+ function isResolvedRedirect(obj) {
1555
+ return isRedirect(obj) && !!obj.options.href;
1556
+ }
1557
+ function parseRedirect(obj) {
1558
+ if (obj !== null && typeof obj === "object" && obj.isSerializedRedirect) {
1559
+ return redirect(obj);
1560
+ }
1561
+ return void 0;
1562
+ }
1563
+ const triggerOnReady = (inner) => {
1564
+ if (!inner.rendered) {
1565
+ inner.rendered = true;
1566
+ return inner.onReady?.();
1567
+ }
1568
+ };
1569
+ const resolvePreload = (inner, matchId) => {
1570
+ return !!(inner.preload && !inner.router.state.matches.some((d) => d.id === matchId));
1571
+ };
1572
+ const buildMatchContext = (inner, index, includeCurrentMatch = true) => {
1573
+ const context = {
1574
+ ...inner.router.options.context ?? {}
1575
+ };
1576
+ const end = includeCurrentMatch ? index : index - 1;
1577
+ for (let i = 0; i <= end; i++) {
1578
+ const innerMatch = inner.matches[i];
1579
+ if (!innerMatch) continue;
1580
+ const m = inner.router.getMatch(innerMatch.id);
1581
+ if (!m) continue;
1582
+ Object.assign(context, m.__routeContext, m.__beforeLoadContext);
1583
+ }
1584
+ return context;
1585
+ };
1586
+ const getNotFoundBoundaryIndex = (inner, err) => {
1587
+ if (!inner.matches.length) {
1588
+ return void 0;
1589
+ }
1590
+ const requestedRouteId = err.routeId;
1591
+ const matchedRootIndex = inner.matches.findIndex(
1592
+ (m) => m.routeId === inner.router.routeTree.id
1593
+ );
1594
+ const rootIndex = matchedRootIndex >= 0 ? matchedRootIndex : 0;
1595
+ let startIndex = requestedRouteId ? inner.matches.findIndex((match) => match.routeId === requestedRouteId) : inner.firstBadMatchIndex ?? inner.matches.length - 1;
1596
+ if (startIndex < 0) {
1597
+ startIndex = rootIndex;
1598
+ }
1599
+ for (let i = startIndex; i >= 0; i--) {
1600
+ const match = inner.matches[i];
1601
+ const route = inner.router.looseRoutesById[match.routeId];
1602
+ if (route.options.notFoundComponent) {
1603
+ return i;
1604
+ }
1605
+ }
1606
+ return requestedRouteId ? startIndex : rootIndex;
1607
+ };
1608
+ const handleRedirectAndNotFound = (inner, match, err) => {
1609
+ if (!isRedirect(err) && !isNotFound(err)) return;
1610
+ if (isRedirect(err) && err.redirectHandled && !err.options.reloadDocument) {
1611
+ throw err;
1612
+ }
1613
+ if (match) {
1614
+ match._nonReactive.beforeLoadPromise?.resolve();
1615
+ match._nonReactive.loaderPromise?.resolve();
1616
+ match._nonReactive.beforeLoadPromise = void 0;
1617
+ match._nonReactive.loaderPromise = void 0;
1618
+ match._nonReactive.error = err;
1619
+ inner.updateMatch(match.id, (prev) => ({
1620
+ ...prev,
1621
+ status: isRedirect(err) ? "redirected" : prev.status === "pending" ? "success" : prev.status,
1622
+ context: buildMatchContext(inner, match.index),
1623
+ isFetching: false,
1624
+ error: err
1625
+ }));
1626
+ if (isNotFound(err) && !err.routeId) {
1627
+ err.routeId = match.routeId;
1628
+ }
1629
+ match._nonReactive.loadPromise?.resolve();
1630
+ }
1631
+ if (isRedirect(err)) {
1632
+ inner.rendered = true;
1633
+ err.options._fromLocation = inner.location;
1634
+ err.redirectHandled = true;
1635
+ err = inner.router.resolveRedirect(err);
1636
+ }
1637
+ throw err;
1638
+ };
1639
+ const shouldSkipLoader = (inner, matchId) => {
1640
+ const match = inner.router.getMatch(matchId);
1641
+ if (match.ssr === false) {
1642
+ return true;
1643
+ }
1644
+ return false;
1645
+ };
1646
+ const handleSerialError = (inner, index, err, routerCode) => {
1647
+ const { id: matchId, routeId } = inner.matches[index];
1648
+ const route = inner.router.looseRoutesById[routeId];
1649
+ if (err instanceof Promise) {
1650
+ throw err;
1651
+ }
1652
+ err.routerCode = routerCode;
1653
+ inner.firstBadMatchIndex ??= index;
1654
+ handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), err);
1655
+ try {
1656
+ route.options.onError?.(err);
1657
+ } catch (errorHandlerErr) {
1658
+ err = errorHandlerErr;
1659
+ handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), err);
1660
+ }
1661
+ inner.updateMatch(matchId, (prev) => {
1662
+ prev._nonReactive.beforeLoadPromise?.resolve();
1663
+ prev._nonReactive.beforeLoadPromise = void 0;
1664
+ prev._nonReactive.loadPromise?.resolve();
1665
+ return {
1666
+ ...prev,
1667
+ error: err,
1668
+ status: "error",
1669
+ isFetching: false,
1670
+ updatedAt: Date.now(),
1671
+ abortController: new AbortController()
1672
+ };
1673
+ });
1674
+ if (!inner.preload && !isRedirect(err) && !isNotFound(err)) {
1675
+ inner.serialError ??= err;
1676
+ }
1677
+ };
1678
+ const isBeforeLoadSsr = (inner, matchId, index, route) => {
1679
+ const existingMatch = inner.router.getMatch(matchId);
1680
+ const parentMatchId = inner.matches[index - 1]?.id;
1681
+ const parentMatch = parentMatchId ? inner.router.getMatch(parentMatchId) : void 0;
1682
+ if (inner.router.isShell()) {
1683
+ existingMatch.ssr = route.id === rootRouteId;
1684
+ return;
1685
+ }
1686
+ if (parentMatch?.ssr === false) {
1687
+ existingMatch.ssr = false;
1688
+ return;
1689
+ }
1690
+ const parentOverride = (tempSsr2) => {
1691
+ if (tempSsr2 === true && parentMatch?.ssr === "data-only") {
1692
+ return "data-only";
1693
+ }
1694
+ return tempSsr2;
1695
+ };
1696
+ const defaultSsr = inner.router.options.defaultSsr ?? true;
1697
+ if (route.options.ssr === void 0) {
1698
+ existingMatch.ssr = parentOverride(defaultSsr);
1699
+ return;
1700
+ }
1701
+ if (typeof route.options.ssr !== "function") {
1702
+ existingMatch.ssr = parentOverride(route.options.ssr);
1703
+ return;
1704
+ }
1705
+ const { search, params } = existingMatch;
1706
+ const ssrFnContext = {
1707
+ search: makeMaybe(search, existingMatch.searchError),
1708
+ params: makeMaybe(params, existingMatch.paramsError),
1709
+ location: inner.location,
1710
+ matches: inner.matches.map((match) => ({
1711
+ index: match.index,
1712
+ pathname: match.pathname,
1713
+ fullPath: match.fullPath,
1714
+ staticData: match.staticData,
1715
+ id: match.id,
1716
+ routeId: match.routeId,
1717
+ search: makeMaybe(match.search, match.searchError),
1718
+ params: makeMaybe(match.params, match.paramsError),
1719
+ ssr: match.ssr
1720
+ }))
1721
+ };
1722
+ const tempSsr = route.options.ssr(ssrFnContext);
1723
+ if (isPromise(tempSsr)) {
1724
+ return tempSsr.then((ssr) => {
1725
+ existingMatch.ssr = parentOverride(ssr ?? defaultSsr);
1726
+ });
1727
+ }
1728
+ existingMatch.ssr = parentOverride(tempSsr ?? defaultSsr);
1729
+ return;
1730
+ };
1731
+ const setupPendingTimeout = (inner, matchId, route, match) => {
1732
+ if (match._nonReactive.pendingTimeout !== void 0) return;
1733
+ const pendingMs = route.options.pendingMs ?? inner.router.options.defaultPendingMs;
1734
+ const shouldPending = !!(inner.onReady && false);
1735
+ if (shouldPending) {
1736
+ const pendingTimeout = setTimeout(() => {
1737
+ triggerOnReady(inner);
1738
+ }, pendingMs);
1739
+ match._nonReactive.pendingTimeout = pendingTimeout;
1740
+ }
1741
+ };
1742
+ const preBeforeLoadSetup = (inner, matchId, route) => {
1743
+ const existingMatch = inner.router.getMatch(matchId);
1744
+ if (!existingMatch._nonReactive.beforeLoadPromise && !existingMatch._nonReactive.loaderPromise)
1745
+ return;
1746
+ setupPendingTimeout(inner, matchId, route, existingMatch);
1747
+ const then = () => {
1748
+ const match = inner.router.getMatch(matchId);
1749
+ if (match.preload && (match.status === "redirected" || match.status === "notFound")) {
1750
+ handleRedirectAndNotFound(inner, match, match.error);
1751
+ }
1752
+ };
1753
+ return existingMatch._nonReactive.beforeLoadPromise ? existingMatch._nonReactive.beforeLoadPromise.then(then) : then();
1754
+ };
1755
+ const executeBeforeLoad = (inner, matchId, index, route) => {
1756
+ const match = inner.router.getMatch(matchId);
1757
+ const prevLoadPromise = match._nonReactive.loadPromise;
1758
+ match._nonReactive.loadPromise = createControlledPromise(() => {
1759
+ prevLoadPromise?.resolve();
1760
+ });
1761
+ const { paramsError, searchError } = match;
1762
+ if (paramsError) {
1763
+ handleSerialError(inner, index, paramsError, "PARSE_PARAMS");
1764
+ }
1765
+ if (searchError) {
1766
+ handleSerialError(inner, index, searchError, "VALIDATE_SEARCH");
1767
+ }
1768
+ setupPendingTimeout(inner, matchId, route, match);
1769
+ const abortController = new AbortController();
1770
+ let isPending = false;
1771
+ const pending = () => {
1772
+ if (isPending) return;
1773
+ isPending = true;
1774
+ inner.updateMatch(matchId, (prev) => ({
1775
+ ...prev,
1776
+ isFetching: "beforeLoad",
1777
+ fetchCount: prev.fetchCount + 1,
1778
+ abortController
1779
+ // Note: We intentionally don't update context here.
1780
+ // Context should only be updated after beforeLoad resolves to avoid
1781
+ // components seeing incomplete context during async beforeLoad execution.
1782
+ }));
1783
+ };
1784
+ const resolve = () => {
1785
+ match._nonReactive.beforeLoadPromise?.resolve();
1786
+ match._nonReactive.beforeLoadPromise = void 0;
1787
+ inner.updateMatch(matchId, (prev) => ({
1788
+ ...prev,
1789
+ isFetching: false
1790
+ }));
1791
+ };
1792
+ if (!route.options.beforeLoad) {
1793
+ batch(() => {
1794
+ pending();
1795
+ resolve();
1796
+ });
1797
+ return;
1798
+ }
1799
+ match._nonReactive.beforeLoadPromise = createControlledPromise();
1800
+ const context = {
1801
+ ...buildMatchContext(inner, index, false),
1802
+ ...match.__routeContext
1803
+ };
1804
+ const { search, params, cause } = match;
1805
+ const preload = resolvePreload(inner, matchId);
1806
+ const beforeLoadFnContext = {
1807
+ search,
1808
+ abortController,
1809
+ params,
1810
+ preload,
1811
+ context,
1812
+ location: inner.location,
1813
+ navigate: (opts) => inner.router.navigate({
1814
+ ...opts,
1815
+ _fromLocation: inner.location
1816
+ }),
1817
+ buildLocation: inner.router.buildLocation,
1818
+ cause: preload ? "preload" : cause,
1819
+ matches: inner.matches,
1820
+ routeId: route.id,
1821
+ ...inner.router.options.additionalContext
1822
+ };
1823
+ const updateContext = (beforeLoadContext2) => {
1824
+ if (beforeLoadContext2 === void 0) {
1825
+ batch(() => {
1826
+ pending();
1827
+ resolve();
1828
+ });
1829
+ return;
1830
+ }
1831
+ if (isRedirect(beforeLoadContext2) || isNotFound(beforeLoadContext2)) {
1832
+ pending();
1833
+ handleSerialError(inner, index, beforeLoadContext2, "BEFORE_LOAD");
1834
+ }
1835
+ batch(() => {
1836
+ pending();
1837
+ inner.updateMatch(matchId, (prev) => ({
1838
+ ...prev,
1839
+ __beforeLoadContext: beforeLoadContext2
1840
+ }));
1841
+ resolve();
1842
+ });
1843
+ };
1844
+ let beforeLoadContext;
1845
+ try {
1846
+ beforeLoadContext = route.options.beforeLoad(beforeLoadFnContext);
1847
+ if (isPromise(beforeLoadContext)) {
1848
+ pending();
1849
+ return beforeLoadContext.catch((err) => {
1850
+ handleSerialError(inner, index, err, "BEFORE_LOAD");
1851
+ }).then(updateContext);
1852
+ }
1853
+ } catch (err) {
1854
+ pending();
1855
+ handleSerialError(inner, index, err, "BEFORE_LOAD");
1856
+ }
1857
+ updateContext(beforeLoadContext);
1858
+ return;
1859
+ };
1860
+ const handleBeforeLoad = (inner, index) => {
1861
+ const { id: matchId, routeId } = inner.matches[index];
1862
+ const route = inner.router.looseRoutesById[routeId];
1863
+ const serverSsr = () => {
1864
+ {
1865
+ const maybePromise = isBeforeLoadSsr(inner, matchId, index, route);
1866
+ if (isPromise(maybePromise)) return maybePromise.then(queueExecution);
1867
+ }
1868
+ return queueExecution();
1869
+ };
1870
+ const execute = () => executeBeforeLoad(inner, matchId, index, route);
1871
+ const queueExecution = () => {
1872
+ if (shouldSkipLoader(inner, matchId)) return;
1873
+ const result = preBeforeLoadSetup(inner, matchId, route);
1874
+ return isPromise(result) ? result.then(execute) : execute();
1875
+ };
1876
+ return serverSsr();
1877
+ };
1878
+ const executeHead = (inner, matchId, route) => {
1879
+ const match = inner.router.getMatch(matchId);
1880
+ if (!match) {
1881
+ return;
1882
+ }
1883
+ if (!route.options.head && !route.options.scripts && !route.options.headers) {
1884
+ return;
1885
+ }
1886
+ const assetContext = {
1887
+ ssr: inner.router.options.ssr,
1888
+ matches: inner.matches,
1889
+ match,
1890
+ params: match.params,
1891
+ loaderData: match.loaderData
1892
+ };
1893
+ return Promise.all([
1894
+ route.options.head?.(assetContext),
1895
+ route.options.scripts?.(assetContext),
1896
+ route.options.headers?.(assetContext)
1897
+ ]).then(([headFnContent, scripts, headers]) => {
1898
+ const meta = headFnContent?.meta;
1899
+ const links = headFnContent?.links;
1900
+ const headScripts = headFnContent?.scripts;
1901
+ const styles = headFnContent?.styles;
1902
+ return {
1903
+ meta,
1904
+ links,
1905
+ headScripts,
1906
+ headers,
1907
+ scripts,
1908
+ styles
1909
+ };
1910
+ });
1911
+ };
1912
+ const getLoaderContext = (inner, matchPromises, matchId, index, route) => {
1913
+ const parentMatchPromise = matchPromises[index - 1];
1914
+ const { params, loaderDeps, abortController, cause } = inner.router.getMatch(matchId);
1915
+ const context = buildMatchContext(inner, index);
1916
+ const preload = resolvePreload(inner, matchId);
1917
+ return {
1918
+ params,
1919
+ deps: loaderDeps,
1920
+ preload: !!preload,
1921
+ parentMatchPromise,
1922
+ abortController,
1923
+ context,
1924
+ location: inner.location,
1925
+ navigate: (opts) => inner.router.navigate({
1926
+ ...opts,
1927
+ _fromLocation: inner.location
1928
+ }),
1929
+ cause: preload ? "preload" : cause,
1930
+ route,
1931
+ ...inner.router.options.additionalContext
1932
+ };
1933
+ };
1934
+ const runLoader = async (inner, matchPromises, matchId, index, route) => {
1935
+ try {
1936
+ const match = inner.router.getMatch(matchId);
1937
+ try {
1938
+ if (!(isServer ?? inner.router.isServer) || match.ssr === true) {
1939
+ loadRouteChunk(route);
1940
+ }
1941
+ const loaderResult = route.options.loader?.(
1942
+ getLoaderContext(inner, matchPromises, matchId, index, route)
1943
+ );
1944
+ const loaderResultIsPromise = route.options.loader && isPromise(loaderResult);
1945
+ const willLoadSomething = !!(loaderResultIsPromise || route._lazyPromise || route._componentsPromise || route.options.head || route.options.scripts || route.options.headers || match._nonReactive.minPendingPromise);
1946
+ if (willLoadSomething) {
1947
+ inner.updateMatch(matchId, (prev) => ({
1948
+ ...prev,
1949
+ isFetching: "loader"
1950
+ }));
1951
+ }
1952
+ if (route.options.loader) {
1953
+ const loaderData = loaderResultIsPromise ? await loaderResult : loaderResult;
1954
+ handleRedirectAndNotFound(
1955
+ inner,
1956
+ inner.router.getMatch(matchId),
1957
+ loaderData
1958
+ );
1959
+ if (loaderData !== void 0) {
1960
+ inner.updateMatch(matchId, (prev) => ({
1961
+ ...prev,
1962
+ loaderData
1963
+ }));
1964
+ }
1965
+ }
1966
+ if (route._lazyPromise) await route._lazyPromise;
1967
+ const pendingPromise = match._nonReactive.minPendingPromise;
1968
+ if (pendingPromise) await pendingPromise;
1969
+ if (route._componentsPromise) await route._componentsPromise;
1970
+ inner.updateMatch(matchId, (prev) => ({
1971
+ ...prev,
1972
+ error: void 0,
1973
+ context: buildMatchContext(inner, index),
1974
+ status: "success",
1975
+ isFetching: false,
1976
+ updatedAt: Date.now()
1977
+ }));
1978
+ } catch (e) {
1979
+ let error = e;
1980
+ if (error?.name === "AbortError") {
1981
+ if (match.abortController.signal.aborted) {
1982
+ match._nonReactive.loaderPromise?.resolve();
1983
+ match._nonReactive.loaderPromise = void 0;
1984
+ return;
1985
+ }
1986
+ inner.updateMatch(matchId, (prev) => ({
1987
+ ...prev,
1988
+ status: prev.status === "pending" ? "success" : prev.status,
1989
+ isFetching: false,
1990
+ context: buildMatchContext(inner, index)
1991
+ }));
1992
+ return;
1993
+ }
1994
+ const pendingPromise = match._nonReactive.minPendingPromise;
1995
+ if (pendingPromise) await pendingPromise;
1996
+ if (isNotFound(e)) {
1997
+ await route.options.notFoundComponent?.preload?.();
1998
+ }
1999
+ handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), e);
2000
+ try {
2001
+ route.options.onError?.(e);
2002
+ } catch (onErrorError) {
2003
+ error = onErrorError;
2004
+ handleRedirectAndNotFound(
2005
+ inner,
2006
+ inner.router.getMatch(matchId),
2007
+ onErrorError
2008
+ );
2009
+ }
2010
+ inner.updateMatch(matchId, (prev) => ({
2011
+ ...prev,
2012
+ error,
2013
+ context: buildMatchContext(inner, index),
2014
+ status: "error",
2015
+ isFetching: false
2016
+ }));
2017
+ }
2018
+ } catch (err) {
2019
+ const match = inner.router.getMatch(matchId);
2020
+ if (match) {
2021
+ match._nonReactive.loaderPromise = void 0;
2022
+ }
2023
+ handleRedirectAndNotFound(inner, match, err);
2024
+ }
2025
+ };
2026
+ const loadRouteMatch = async (inner, matchPromises, index) => {
2027
+ async function handleLoader(preload, prevMatch, match2, route2) {
2028
+ const age = Date.now() - prevMatch.updatedAt;
2029
+ const staleAge = preload ? route2.options.preloadStaleTime ?? inner.router.options.defaultPreloadStaleTime ?? 3e4 : route2.options.staleTime ?? inner.router.options.defaultStaleTime ?? 0;
2030
+ const shouldReloadOption = route2.options.shouldReload;
2031
+ const shouldReload = typeof shouldReloadOption === "function" ? shouldReloadOption(
2032
+ getLoaderContext(inner, matchPromises, matchId, index, route2)
2033
+ ) : shouldReloadOption;
2034
+ const { status, invalid } = match2;
2035
+ loaderShouldRunAsync = status === "success" && (invalid || (shouldReload ?? age > staleAge));
2036
+ if (preload && route2.options.preload === false) ;
2037
+ else if (loaderShouldRunAsync && !inner.sync) {
2038
+ loaderIsRunningAsync = true;
2039
+ (async () => {
2040
+ try {
2041
+ await runLoader(inner, matchPromises, matchId, index, route2);
2042
+ const match3 = inner.router.getMatch(matchId);
2043
+ match3._nonReactive.loaderPromise?.resolve();
2044
+ match3._nonReactive.loadPromise?.resolve();
2045
+ match3._nonReactive.loaderPromise = void 0;
2046
+ } catch (err) {
2047
+ if (isRedirect(err)) {
2048
+ await inner.router.navigate(err.options);
2049
+ }
2050
+ }
2051
+ })();
2052
+ } else if (status !== "success" || loaderShouldRunAsync && inner.sync) {
2053
+ await runLoader(inner, matchPromises, matchId, index, route2);
2054
+ }
2055
+ }
2056
+ const { id: matchId, routeId } = inner.matches[index];
2057
+ let loaderShouldRunAsync = false;
2058
+ let loaderIsRunningAsync = false;
2059
+ const route = inner.router.looseRoutesById[routeId];
2060
+ if (shouldSkipLoader(inner, matchId)) {
2061
+ {
2062
+ return inner.router.getMatch(matchId);
2063
+ }
2064
+ } else {
2065
+ const prevMatch = inner.router.getMatch(matchId);
2066
+ const preload = resolvePreload(inner, matchId);
2067
+ if (prevMatch._nonReactive.loaderPromise) {
2068
+ if (prevMatch.status === "success" && !inner.sync && !prevMatch.preload) {
2069
+ return prevMatch;
2070
+ }
2071
+ await prevMatch._nonReactive.loaderPromise;
2072
+ const match2 = inner.router.getMatch(matchId);
2073
+ const error = match2._nonReactive.error || match2.error;
2074
+ if (error) {
2075
+ handleRedirectAndNotFound(inner, match2, error);
2076
+ }
2077
+ if (match2.status === "pending") {
2078
+ await handleLoader(preload, prevMatch, match2, route);
2079
+ }
2080
+ } else {
2081
+ const nextPreload = preload && !inner.router.state.matches.some((d) => d.id === matchId);
2082
+ const match2 = inner.router.getMatch(matchId);
2083
+ match2._nonReactive.loaderPromise = createControlledPromise();
2084
+ if (nextPreload !== match2.preload) {
2085
+ inner.updateMatch(matchId, (prev) => ({
2086
+ ...prev,
2087
+ preload: nextPreload
2088
+ }));
2089
+ }
2090
+ await handleLoader(preload, prevMatch, match2, route);
2091
+ }
2092
+ }
2093
+ const match = inner.router.getMatch(matchId);
2094
+ if (!loaderIsRunningAsync) {
2095
+ match._nonReactive.loaderPromise?.resolve();
2096
+ match._nonReactive.loadPromise?.resolve();
2097
+ }
2098
+ clearTimeout(match._nonReactive.pendingTimeout);
2099
+ match._nonReactive.pendingTimeout = void 0;
2100
+ if (!loaderIsRunningAsync) match._nonReactive.loaderPromise = void 0;
2101
+ match._nonReactive.dehydrated = void 0;
2102
+ const nextIsFetching = loaderIsRunningAsync ? match.isFetching : false;
2103
+ if (nextIsFetching !== match.isFetching || match.invalid !== false) {
2104
+ inner.updateMatch(matchId, (prev) => ({
2105
+ ...prev,
2106
+ isFetching: nextIsFetching,
2107
+ invalid: false
2108
+ }));
2109
+ return inner.router.getMatch(matchId);
2110
+ } else {
2111
+ return match;
2112
+ }
2113
+ };
2114
+ async function loadMatches(arg) {
2115
+ const inner = arg;
2116
+ const matchPromises = [];
2117
+ let beforeLoadNotFound;
2118
+ for (let i = 0; i < inner.matches.length; i++) {
2119
+ try {
2120
+ const beforeLoad = handleBeforeLoad(inner, i);
2121
+ if (isPromise(beforeLoad)) await beforeLoad;
2122
+ } catch (err) {
2123
+ if (isRedirect(err)) {
2124
+ throw err;
2125
+ }
2126
+ if (isNotFound(err)) {
2127
+ beforeLoadNotFound = err;
2128
+ } else {
2129
+ if (!inner.preload) throw err;
2130
+ }
2131
+ break;
2132
+ }
2133
+ if (inner.serialError) {
2134
+ break;
2135
+ }
2136
+ }
2137
+ const baseMaxIndexExclusive = inner.firstBadMatchIndex ?? inner.matches.length;
2138
+ const boundaryIndex = beforeLoadNotFound && !inner.preload ? getNotFoundBoundaryIndex(inner, beforeLoadNotFound) : void 0;
2139
+ const maxIndexExclusive = beforeLoadNotFound && inner.preload ? 0 : boundaryIndex !== void 0 ? Math.min(boundaryIndex + 1, baseMaxIndexExclusive) : baseMaxIndexExclusive;
2140
+ let firstNotFound;
2141
+ let firstUnhandledRejection;
2142
+ for (let i = 0; i < maxIndexExclusive; i++) {
2143
+ matchPromises.push(loadRouteMatch(inner, matchPromises, i));
2144
+ }
2145
+ try {
2146
+ await Promise.all(matchPromises);
2147
+ } catch {
2148
+ const settled = await Promise.allSettled(matchPromises);
2149
+ for (const result of settled) {
2150
+ if (result.status !== "rejected") continue;
2151
+ const reason = result.reason;
2152
+ if (isRedirect(reason)) {
2153
+ throw reason;
2154
+ }
2155
+ if (isNotFound(reason)) {
2156
+ firstNotFound ??= reason;
2157
+ } else {
2158
+ firstUnhandledRejection ??= reason;
2159
+ }
2160
+ }
2161
+ if (firstUnhandledRejection !== void 0) {
2162
+ throw firstUnhandledRejection;
2163
+ }
2164
+ }
2165
+ const notFoundToThrow = firstNotFound ?? (beforeLoadNotFound && !inner.preload ? beforeLoadNotFound : void 0);
2166
+ let headMaxIndex = inner.serialError ? inner.firstBadMatchIndex ?? 0 : inner.matches.length - 1;
2167
+ if (!notFoundToThrow && beforeLoadNotFound && inner.preload) {
2168
+ return inner.matches;
2169
+ }
2170
+ if (notFoundToThrow) {
2171
+ const renderedBoundaryIndex = getNotFoundBoundaryIndex(
2172
+ inner,
2173
+ notFoundToThrow
2174
+ );
2175
+ invariant(
2176
+ renderedBoundaryIndex !== void 0
2177
+ );
2178
+ const boundaryMatch = inner.matches[renderedBoundaryIndex];
2179
+ const boundaryRoute = inner.router.looseRoutesById[boundaryMatch.routeId];
2180
+ const defaultNotFoundComponent = inner.router.options?.defaultNotFoundComponent;
2181
+ if (!boundaryRoute.options.notFoundComponent && defaultNotFoundComponent) {
2182
+ boundaryRoute.options.notFoundComponent = defaultNotFoundComponent;
2183
+ }
2184
+ notFoundToThrow.routeId = boundaryMatch.routeId;
2185
+ const boundaryIsRoot = boundaryMatch.routeId === inner.router.routeTree.id;
2186
+ inner.updateMatch(boundaryMatch.id, (prev) => ({
2187
+ ...prev,
2188
+ ...boundaryIsRoot ? (
2189
+ // For root boundary, use globalNotFound so the root component's
2190
+ // shell still renders and <Outlet> handles the not-found display,
2191
+ // instead of replacing the entire root shell via status='notFound'.
2192
+ { status: "success", globalNotFound: true, error: void 0 }
2193
+ ) : (
2194
+ // For non-root boundaries, set status:'notFound' so MatchInner
2195
+ // renders the notFoundComponent directly.
2196
+ { status: "notFound", error: notFoundToThrow }
2197
+ ),
2198
+ isFetching: false
2199
+ }));
2200
+ headMaxIndex = renderedBoundaryIndex;
2201
+ await loadRouteChunk(boundaryRoute);
2202
+ } else if (!inner.preload) {
2203
+ const rootMatch = inner.matches[0];
2204
+ if (!rootMatch.globalNotFound) {
2205
+ const currentRootMatch = inner.router.getMatch(rootMatch.id);
2206
+ if (currentRootMatch?.globalNotFound) {
2207
+ inner.updateMatch(rootMatch.id, (prev) => ({
2208
+ ...prev,
2209
+ globalNotFound: false,
2210
+ error: void 0
2211
+ }));
2212
+ }
2213
+ }
2214
+ }
2215
+ if (inner.serialError && inner.firstBadMatchIndex !== void 0) {
2216
+ const errorRoute = inner.router.looseRoutesById[inner.matches[inner.firstBadMatchIndex].routeId];
2217
+ await loadRouteChunk(errorRoute);
2218
+ }
2219
+ for (let i = 0; i <= headMaxIndex; i++) {
2220
+ const match = inner.matches[i];
2221
+ const { id: matchId, routeId } = match;
2222
+ const route = inner.router.looseRoutesById[routeId];
2223
+ try {
2224
+ const headResult = executeHead(inner, matchId, route);
2225
+ if (headResult) {
2226
+ const head = await headResult;
2227
+ inner.updateMatch(matchId, (prev) => ({
2228
+ ...prev,
2229
+ ...head
2230
+ }));
2231
+ }
2232
+ } catch (err) {
2233
+ console.error(`Error executing head for route ${routeId}:`, err);
2234
+ }
2235
+ }
2236
+ const readyPromise = triggerOnReady(inner);
2237
+ if (isPromise(readyPromise)) {
2238
+ await readyPromise;
2239
+ }
2240
+ if (notFoundToThrow) {
2241
+ throw notFoundToThrow;
2242
+ }
2243
+ if (inner.serialError && !inner.preload && !inner.onReady) {
2244
+ throw inner.serialError;
2245
+ }
2246
+ return inner.matches;
2247
+ }
2248
+ async function loadRouteChunk(route) {
2249
+ if (!route._lazyLoaded && route._lazyPromise === void 0) {
2250
+ if (route.lazyFn) {
2251
+ route._lazyPromise = route.lazyFn().then((lazyRoute) => {
2252
+ const { id: _id, ...options } = lazyRoute.options;
2253
+ Object.assign(route.options, options);
2254
+ route._lazyLoaded = true;
2255
+ route._lazyPromise = void 0;
2256
+ });
2257
+ } else {
2258
+ route._lazyLoaded = true;
2259
+ }
2260
+ }
2261
+ if (!route._componentsLoaded && route._componentsPromise === void 0) {
2262
+ const loadComponents = () => {
2263
+ const preloads = [];
2264
+ for (const type of componentTypes) {
2265
+ const preload = route.options[type]?.preload;
2266
+ if (preload) preloads.push(preload());
2267
+ }
2268
+ if (preloads.length)
2269
+ return Promise.all(preloads).then(() => {
2270
+ route._componentsLoaded = true;
2271
+ route._componentsPromise = void 0;
2272
+ });
2273
+ route._componentsLoaded = true;
2274
+ route._componentsPromise = void 0;
2275
+ return;
2276
+ };
2277
+ route._componentsPromise = route._lazyPromise ? route._lazyPromise.then(loadComponents) : loadComponents();
2278
+ }
2279
+ return route._componentsPromise;
2280
+ }
2281
+ function makeMaybe(value, error) {
2282
+ if (error) {
2283
+ return { status: "error", error };
2284
+ }
2285
+ return { status: "success", value };
2286
+ }
2287
+ function routeNeedsPreload(route) {
2288
+ for (const componentType of componentTypes) {
2289
+ if (route.options[componentType]?.preload) {
2290
+ return true;
2291
+ }
2292
+ }
2293
+ return false;
2294
+ }
2295
+ const componentTypes = [
2296
+ "component",
2297
+ "errorComponent",
2298
+ "pendingComponent",
2299
+ "notFoundComponent"
2300
+ ];
2301
+ function composeRewrites(rewrites) {
2302
+ return {
2303
+ input: ({ url }) => {
2304
+ for (const rewrite of rewrites) {
2305
+ url = executeRewriteInput(rewrite, url);
2306
+ }
2307
+ return url;
2308
+ },
2309
+ output: ({ url }) => {
2310
+ for (let i = rewrites.length - 1; i >= 0; i--) {
2311
+ url = executeRewriteOutput(rewrites[i], url);
2312
+ }
2313
+ return url;
2314
+ }
2315
+ };
2316
+ }
2317
+ function rewriteBasepath(opts) {
2318
+ const trimmedBasepath = trimPath(opts.basepath);
2319
+ const normalizedBasepath = `/${trimmedBasepath}`;
2320
+ const normalizedBasepathWithSlash = `${normalizedBasepath}/`;
2321
+ const checkBasepath = opts.caseSensitive ? normalizedBasepath : normalizedBasepath.toLowerCase();
2322
+ const checkBasepathWithSlash = opts.caseSensitive ? normalizedBasepathWithSlash : normalizedBasepathWithSlash.toLowerCase();
2323
+ return {
2324
+ input: ({ url }) => {
2325
+ const pathname = opts.caseSensitive ? url.pathname : url.pathname.toLowerCase();
2326
+ if (pathname === checkBasepath) {
2327
+ url.pathname = "/";
2328
+ } else if (pathname.startsWith(checkBasepathWithSlash)) {
2329
+ url.pathname = url.pathname.slice(normalizedBasepath.length);
2330
+ }
2331
+ return url;
2332
+ },
2333
+ output: ({ url }) => {
2334
+ url.pathname = joinPaths(["/", trimmedBasepath, url.pathname]);
2335
+ return url;
2336
+ }
2337
+ };
2338
+ }
2339
+ function executeRewriteInput(rewrite, url) {
2340
+ const res = rewrite?.input?.({ url });
2341
+ if (res) {
2342
+ if (typeof res === "string") {
2343
+ return new URL(res);
2344
+ } else if (res instanceof URL) {
2345
+ return res;
2346
+ }
2347
+ }
2348
+ return url;
2349
+ }
2350
+ function executeRewriteOutput(rewrite, url) {
2351
+ const res = rewrite?.output?.({ url });
2352
+ if (res) {
2353
+ if (typeof res === "string") {
2354
+ return new URL(res);
2355
+ } else if (res instanceof URL) {
2356
+ return res;
2357
+ }
2358
+ }
2359
+ return url;
2360
+ }
2361
+ function getLocationChangeInfo(routerState) {
2362
+ const fromLocation = routerState.resolvedLocation;
2363
+ const toLocation = routerState.location;
2364
+ const pathChanged = fromLocation?.pathname !== toLocation.pathname;
2365
+ const hrefChanged = fromLocation?.href !== toLocation.href;
2366
+ const hashChanged = fromLocation?.hash !== toLocation.hash;
2367
+ return { fromLocation, toLocation, pathChanged, hrefChanged, hashChanged };
2368
+ }
2369
+ function filterRedirectedCachedMatches(matches) {
2370
+ const filtered = matches.filter((d) => d.status !== "redirected");
2371
+ return filtered.length === matches.length ? matches : filtered;
2372
+ }
2373
+ function createServerStore(initialState) {
2374
+ const store = {
2375
+ state: initialState,
2376
+ setState: (updater) => {
2377
+ store.state = updater(store.state);
2378
+ }
2379
+ };
2380
+ return store;
2381
+ }
2382
+ class RouterCore {
2383
+ /**
2384
+ * @deprecated Use the `createRouter` function instead
2385
+ */
2386
+ constructor(options) {
2387
+ this.tempLocationKey = `${Math.round(
2388
+ Math.random() * 1e7
2389
+ )}`;
2390
+ this.resetNextScroll = true;
2391
+ this.shouldViewTransition = void 0;
2392
+ this.isViewTransitionTypesSupported = void 0;
2393
+ this.subscribers = /* @__PURE__ */ new Set();
2394
+ this.isScrollRestoring = false;
2395
+ this.isScrollRestorationSetup = false;
2396
+ this.startTransition = (fn) => fn();
2397
+ this.update = (newOptions) => {
2398
+ const prevOptions = this.options;
2399
+ const prevBasepath = this.basepath ?? prevOptions?.basepath ?? "/";
2400
+ const basepathWasUnset = this.basepath === void 0;
2401
+ const prevRewriteOption = prevOptions?.rewrite;
2402
+ this.options = {
2403
+ ...prevOptions,
2404
+ ...newOptions
2405
+ };
2406
+ this.isServer = this.options.isServer ?? typeof document === "undefined";
2407
+ this.protocolAllowlist = new Set(this.options.protocolAllowlist);
2408
+ if (this.options.pathParamsAllowedCharacters)
2409
+ this.pathParamsDecoder = compileDecodeCharMap(
2410
+ this.options.pathParamsAllowedCharacters
2411
+ );
2412
+ if (!this.history || this.options.history && this.options.history !== this.history) {
2413
+ if (!this.options.history) ;
2414
+ else {
2415
+ this.history = this.options.history;
2416
+ }
2417
+ }
2418
+ this.origin = this.options.origin;
2419
+ if (!this.origin) {
2420
+ {
2421
+ this.origin = "http://localhost";
2422
+ }
2423
+ }
2424
+ if (this.history) {
2425
+ this.updateLatestLocation();
2426
+ }
2427
+ if (this.options.routeTree !== this.routeTree) {
2428
+ this.routeTree = this.options.routeTree;
2429
+ let processRouteTreeResult;
2430
+ if (globalThis.__TSR_CACHE__ && globalThis.__TSR_CACHE__.routeTree === this.routeTree) {
2431
+ const cached = globalThis.__TSR_CACHE__;
2432
+ this.resolvePathCache = cached.resolvePathCache;
2433
+ processRouteTreeResult = cached.processRouteTreeResult;
2434
+ } else {
2435
+ this.resolvePathCache = createLRUCache(1e3);
2436
+ processRouteTreeResult = this.buildRouteTree();
2437
+ if (globalThis.__TSR_CACHE__ === void 0) {
2438
+ globalThis.__TSR_CACHE__ = {
2439
+ routeTree: this.routeTree,
2440
+ processRouteTreeResult,
2441
+ resolvePathCache: this.resolvePathCache
2442
+ };
2443
+ }
2444
+ }
2445
+ this.setRoutes(processRouteTreeResult);
2446
+ }
2447
+ if (!this.__store && this.latestLocation) {
2448
+ {
2449
+ this.__store = createServerStore(
2450
+ getInitialRouterState(this.latestLocation)
2451
+ );
2452
+ }
2453
+ }
2454
+ let needsLocationUpdate = false;
2455
+ const nextBasepath = this.options.basepath ?? "/";
2456
+ const nextRewriteOption = this.options.rewrite;
2457
+ const basepathChanged = basepathWasUnset || prevBasepath !== nextBasepath;
2458
+ const rewriteChanged = prevRewriteOption !== nextRewriteOption;
2459
+ if (basepathChanged || rewriteChanged) {
2460
+ this.basepath = nextBasepath;
2461
+ const rewrites = [];
2462
+ const trimmed = trimPath(nextBasepath);
2463
+ if (trimmed && trimmed !== "/") {
2464
+ rewrites.push(
2465
+ rewriteBasepath({
2466
+ basepath: nextBasepath
2467
+ })
2468
+ );
2469
+ }
2470
+ if (nextRewriteOption) {
2471
+ rewrites.push(nextRewriteOption);
2472
+ }
2473
+ this.rewrite = rewrites.length === 0 ? void 0 : rewrites.length === 1 ? rewrites[0] : composeRewrites(rewrites);
2474
+ if (this.history) {
2475
+ this.updateLatestLocation();
2476
+ }
2477
+ needsLocationUpdate = true;
2478
+ }
2479
+ if (needsLocationUpdate && this.__store) {
2480
+ this.__store.setState((s) => ({
2481
+ ...s,
2482
+ location: this.latestLocation
2483
+ }));
2484
+ }
2485
+ if (typeof window !== "undefined" && "CSS" in window && typeof window.CSS?.supports === "function") {
2486
+ this.isViewTransitionTypesSupported = window.CSS.supports(
2487
+ "selector(:active-view-transition-type(a)"
2488
+ );
2489
+ }
2490
+ };
2491
+ this.updateLatestLocation = () => {
2492
+ this.latestLocation = this.parseLocation(
2493
+ this.history.location,
2494
+ this.latestLocation
2495
+ );
2496
+ };
2497
+ this.buildRouteTree = () => {
2498
+ const result = processRouteTree(
2499
+ this.routeTree,
2500
+ this.options.caseSensitive,
2501
+ (route, i) => {
2502
+ route.init({
2503
+ originalIndex: i
2504
+ });
2505
+ }
2506
+ );
2507
+ if (this.options.routeMasks) {
2508
+ processRouteMasks(this.options.routeMasks, result.processedTree);
2509
+ }
2510
+ return result;
2511
+ };
2512
+ this.subscribe = (eventType, fn) => {
2513
+ const listener = {
2514
+ eventType,
2515
+ fn
2516
+ };
2517
+ this.subscribers.add(listener);
2518
+ return () => {
2519
+ this.subscribers.delete(listener);
2520
+ };
2521
+ };
2522
+ this.emit = (routerEvent) => {
2523
+ this.subscribers.forEach((listener) => {
2524
+ if (listener.eventType === routerEvent.type) {
2525
+ listener.fn(routerEvent);
2526
+ }
2527
+ });
2528
+ };
2529
+ this.parseLocation = (locationToParse, previousLocation) => {
2530
+ const parse = ({
2531
+ pathname,
2532
+ search,
2533
+ hash,
2534
+ href,
2535
+ state
2536
+ }) => {
2537
+ if (!this.rewrite && !/[ \x00-\x1f\x7f\u0080-\uffff]/.test(pathname)) {
2538
+ const parsedSearch2 = this.options.parseSearch(search);
2539
+ const searchStr2 = this.options.stringifySearch(parsedSearch2);
2540
+ return {
2541
+ href: pathname + searchStr2 + hash,
2542
+ publicHref: href,
2543
+ pathname: decodePath(pathname).path,
2544
+ external: false,
2545
+ searchStr: searchStr2,
2546
+ search: replaceEqualDeep(
2547
+ previousLocation?.search,
2548
+ parsedSearch2
2549
+ ),
2550
+ hash: decodePath(hash.slice(1)).path,
2551
+ state: replaceEqualDeep(previousLocation?.state, state)
2552
+ };
2553
+ }
2554
+ const fullUrl = new URL(href, this.origin);
2555
+ const url = executeRewriteInput(this.rewrite, fullUrl);
2556
+ const parsedSearch = this.options.parseSearch(url.search);
2557
+ const searchStr = this.options.stringifySearch(parsedSearch);
2558
+ url.search = searchStr;
2559
+ const fullPath = url.href.replace(url.origin, "");
2560
+ return {
2561
+ href: fullPath,
2562
+ publicHref: href,
2563
+ pathname: decodePath(url.pathname).path,
2564
+ external: !!this.rewrite && url.origin !== this.origin,
2565
+ searchStr,
2566
+ search: replaceEqualDeep(previousLocation?.search, parsedSearch),
2567
+ hash: decodePath(url.hash.slice(1)).path,
2568
+ state: replaceEqualDeep(previousLocation?.state, state)
2569
+ };
2570
+ };
2571
+ const location = parse(locationToParse);
2572
+ const { __tempLocation, __tempKey } = location.state;
2573
+ if (__tempLocation && (!__tempKey || __tempKey === this.tempLocationKey)) {
2574
+ const parsedTempLocation = parse(__tempLocation);
2575
+ parsedTempLocation.state.key = location.state.key;
2576
+ parsedTempLocation.state.__TSR_key = location.state.__TSR_key;
2577
+ delete parsedTempLocation.state.__tempLocation;
2578
+ return {
2579
+ ...parsedTempLocation,
2580
+ maskedLocation: location
2581
+ };
2582
+ }
2583
+ return location;
2584
+ };
2585
+ this.resolvePathWithBase = (from, path) => {
2586
+ const resolvedPath = resolvePath({
2587
+ base: from,
2588
+ to: cleanPath(path),
2589
+ trailingSlash: this.options.trailingSlash,
2590
+ cache: this.resolvePathCache
2591
+ });
2592
+ return resolvedPath;
2593
+ };
2594
+ this.matchRoutes = (pathnameOrNext, locationSearchOrOpts, opts) => {
2595
+ if (typeof pathnameOrNext === "string") {
2596
+ return this.matchRoutesInternal(
2597
+ {
2598
+ pathname: pathnameOrNext,
2599
+ search: locationSearchOrOpts
2600
+ },
2601
+ opts
2602
+ );
2603
+ }
2604
+ return this.matchRoutesInternal(pathnameOrNext, locationSearchOrOpts);
2605
+ };
2606
+ this.getMatchedRoutes = (pathname) => {
2607
+ return getMatchedRoutes({
2608
+ pathname,
2609
+ routesById: this.routesById,
2610
+ processedTree: this.processedTree
2611
+ });
2612
+ };
2613
+ this.cancelMatch = (id) => {
2614
+ const match = this.getMatch(id);
2615
+ if (!match) return;
2616
+ match.abortController.abort();
2617
+ clearTimeout(match._nonReactive.pendingTimeout);
2618
+ match._nonReactive.pendingTimeout = void 0;
2619
+ };
2620
+ this.cancelMatches = () => {
2621
+ const currentPendingMatches = this.state.matches.filter(
2622
+ (match) => match.status === "pending"
2623
+ );
2624
+ const currentLoadingMatches = this.state.matches.filter(
2625
+ (match) => match.isFetching === "loader"
2626
+ );
2627
+ const matchesToCancelArray = /* @__PURE__ */ new Set([
2628
+ ...this.state.pendingMatches ?? [],
2629
+ ...currentPendingMatches,
2630
+ ...currentLoadingMatches
2631
+ ]);
2632
+ matchesToCancelArray.forEach((match) => {
2633
+ this.cancelMatch(match.id);
2634
+ });
2635
+ };
2636
+ this.buildLocation = (opts) => {
2637
+ const build = (dest = {}) => {
2638
+ const currentLocation = dest._fromLocation || this.pendingBuiltLocation || this.latestLocation;
2639
+ const lightweightResult = this.matchRoutesLightweight(currentLocation);
2640
+ if (dest.from && false) ;
2641
+ const defaultedFromPath = dest.unsafeRelative === "path" ? currentLocation.pathname : dest.from ?? lightweightResult.fullPath;
2642
+ const fromPath = this.resolvePathWithBase(defaultedFromPath, ".");
2643
+ const fromSearch = lightweightResult.search;
2644
+ const fromParams = { ...lightweightResult.params };
2645
+ const nextTo = dest.to ? this.resolvePathWithBase(fromPath, `${dest.to}`) : this.resolvePathWithBase(fromPath, ".");
2646
+ const nextParams = dest.params === false || dest.params === null ? {} : (dest.params ?? true) === true ? fromParams : Object.assign(
2647
+ fromParams,
2648
+ functionalUpdate(dest.params, fromParams)
2649
+ );
2650
+ const destMatchResult = this.getMatchedRoutes(nextTo);
2651
+ let destRoutes = destMatchResult.matchedRoutes;
2652
+ const isGlobalNotFound = !destMatchResult.foundRoute || destMatchResult.foundRoute.path !== "/" && destMatchResult.routeParams["**"];
2653
+ if (isGlobalNotFound && this.options.notFoundRoute) {
2654
+ destRoutes = [...destRoutes, this.options.notFoundRoute];
2655
+ }
2656
+ if (Object.keys(nextParams).length > 0) {
2657
+ for (const route of destRoutes) {
2658
+ const fn = route.options.params?.stringify ?? route.options.stringifyParams;
2659
+ if (fn) {
2660
+ try {
2661
+ Object.assign(nextParams, fn(nextParams));
2662
+ } catch {
2663
+ }
2664
+ }
2665
+ }
2666
+ }
2667
+ const nextPathname = opts.leaveParams ? (
2668
+ // Use the original template path for interpolation
2669
+ // This preserves the original parameter syntax including optional parameters
2670
+ nextTo
2671
+ ) : decodePath(
2672
+ interpolatePath({
2673
+ path: nextTo,
2674
+ params: nextParams,
2675
+ decoder: this.pathParamsDecoder,
2676
+ server: this.isServer
2677
+ }).interpolatedPath
2678
+ ).path;
2679
+ let nextSearch = fromSearch;
2680
+ if (opts._includeValidateSearch && this.options.search?.strict) {
2681
+ const validatedSearch = {};
2682
+ destRoutes.forEach((route) => {
2683
+ if (route.options.validateSearch) {
2684
+ try {
2685
+ Object.assign(
2686
+ validatedSearch,
2687
+ validateSearch(route.options.validateSearch, {
2688
+ ...validatedSearch,
2689
+ ...nextSearch
2690
+ })
2691
+ );
2692
+ } catch {
2693
+ }
2694
+ }
2695
+ });
2696
+ nextSearch = validatedSearch;
2697
+ }
2698
+ nextSearch = applySearchMiddleware({
2699
+ search: nextSearch,
2700
+ dest,
2701
+ destRoutes,
2702
+ _includeValidateSearch: opts._includeValidateSearch
2703
+ });
2704
+ nextSearch = replaceEqualDeep(fromSearch, nextSearch);
2705
+ const searchStr = this.options.stringifySearch(nextSearch);
2706
+ const hash = dest.hash === true ? currentLocation.hash : dest.hash ? functionalUpdate(dest.hash, currentLocation.hash) : void 0;
2707
+ const hashStr = hash ? `#${hash}` : "";
2708
+ let nextState = dest.state === true ? currentLocation.state : dest.state ? functionalUpdate(dest.state, currentLocation.state) : {};
2709
+ nextState = replaceEqualDeep(currentLocation.state, nextState);
2710
+ const fullPath = `${nextPathname}${searchStr}${hashStr}`;
2711
+ let href;
2712
+ let publicHref;
2713
+ let external = false;
2714
+ if (this.rewrite) {
2715
+ const url = new URL(fullPath, this.origin);
2716
+ const rewrittenUrl = executeRewriteOutput(this.rewrite, url);
2717
+ href = url.href.replace(url.origin, "");
2718
+ if (rewrittenUrl.origin !== this.origin) {
2719
+ publicHref = rewrittenUrl.href;
2720
+ external = true;
2721
+ } else {
2722
+ publicHref = rewrittenUrl.pathname + rewrittenUrl.search + rewrittenUrl.hash;
2723
+ }
2724
+ } else {
2725
+ href = encodePathLikeUrl(fullPath);
2726
+ publicHref = href;
2727
+ }
2728
+ return {
2729
+ publicHref,
2730
+ href,
2731
+ pathname: nextPathname,
2732
+ search: nextSearch,
2733
+ searchStr,
2734
+ state: nextState,
2735
+ hash: hash ?? "",
2736
+ external,
2737
+ unmaskOnReload: dest.unmaskOnReload
2738
+ };
2739
+ };
2740
+ const buildWithMatches = (dest = {}, maskedDest) => {
2741
+ const next = build(dest);
2742
+ let maskedNext = maskedDest ? build(maskedDest) : void 0;
2743
+ if (!maskedNext) {
2744
+ const params = {};
2745
+ if (this.options.routeMasks) {
2746
+ const match = findFlatMatch(
2747
+ next.pathname,
2748
+ this.processedTree
2749
+ );
2750
+ if (match) {
2751
+ Object.assign(params, match.rawParams);
2752
+ const {
2753
+ from: _from,
2754
+ params: maskParams,
2755
+ ...maskProps
2756
+ } = match.route;
2757
+ const nextParams = maskParams === false || maskParams === null ? {} : (maskParams ?? true) === true ? params : Object.assign(params, functionalUpdate(maskParams, params));
2758
+ maskedDest = {
2759
+ from: opts.from,
2760
+ ...maskProps,
2761
+ params: nextParams
2762
+ };
2763
+ maskedNext = build(maskedDest);
2764
+ }
2765
+ }
2766
+ }
2767
+ if (maskedNext) {
2768
+ next.maskedLocation = maskedNext;
2769
+ }
2770
+ return next;
2771
+ };
2772
+ if (opts.mask) {
2773
+ return buildWithMatches(opts, {
2774
+ from: opts.from,
2775
+ ...opts.mask
2776
+ });
2777
+ }
2778
+ return buildWithMatches(opts);
2779
+ };
2780
+ this.commitLocation = async ({
2781
+ viewTransition,
2782
+ ignoreBlocker,
2783
+ ...next
2784
+ }) => {
2785
+ const isSameState = () => {
2786
+ const ignoredProps = [
2787
+ "key",
2788
+ // TODO: Remove in v2 - use __TSR_key instead
2789
+ "__TSR_key",
2790
+ "__TSR_index",
2791
+ "__hashScrollIntoViewOptions"
2792
+ ];
2793
+ ignoredProps.forEach((prop) => {
2794
+ next.state[prop] = this.latestLocation.state[prop];
2795
+ });
2796
+ const isEqual = deepEqual(next.state, this.latestLocation.state);
2797
+ ignoredProps.forEach((prop) => {
2798
+ delete next.state[prop];
2799
+ });
2800
+ return isEqual;
2801
+ };
2802
+ const isSameUrl = trimPathRight(this.latestLocation.href) === trimPathRight(next.href);
2803
+ const previousCommitPromise = this.commitLocationPromise;
2804
+ this.commitLocationPromise = createControlledPromise(() => {
2805
+ previousCommitPromise?.resolve();
2806
+ });
2807
+ if (isSameUrl && isSameState()) {
2808
+ this.load();
2809
+ } else {
2810
+ let {
2811
+ // eslint-disable-next-line prefer-const
2812
+ maskedLocation,
2813
+ // eslint-disable-next-line prefer-const
2814
+ hashScrollIntoView,
2815
+ ...nextHistory
2816
+ } = next;
2817
+ if (maskedLocation) {
2818
+ nextHistory = {
2819
+ ...maskedLocation,
2820
+ state: {
2821
+ ...maskedLocation.state,
2822
+ __tempKey: void 0,
2823
+ __tempLocation: {
2824
+ ...nextHistory,
2825
+ search: nextHistory.searchStr,
2826
+ state: {
2827
+ ...nextHistory.state,
2828
+ __tempKey: void 0,
2829
+ __tempLocation: void 0,
2830
+ __TSR_key: void 0,
2831
+ key: void 0
2832
+ // TODO: Remove in v2 - use __TSR_key instead
2833
+ }
2834
+ }
2835
+ }
2836
+ };
2837
+ if (nextHistory.unmaskOnReload ?? this.options.unmaskOnReload ?? false) {
2838
+ nextHistory.state.__tempKey = this.tempLocationKey;
2839
+ }
2840
+ }
2841
+ nextHistory.state.__hashScrollIntoViewOptions = hashScrollIntoView ?? this.options.defaultHashScrollIntoView ?? true;
2842
+ this.shouldViewTransition = viewTransition;
2843
+ this.history[next.replace ? "replace" : "push"](
2844
+ nextHistory.publicHref,
2845
+ nextHistory.state,
2846
+ { ignoreBlocker }
2847
+ );
2848
+ }
2849
+ this.resetNextScroll = next.resetScroll ?? true;
2850
+ if (!this.history.subscribers.size) {
2851
+ this.load();
2852
+ }
2853
+ return this.commitLocationPromise;
2854
+ };
2855
+ this.buildAndCommitLocation = ({
2856
+ replace,
2857
+ resetScroll,
2858
+ hashScrollIntoView,
2859
+ viewTransition,
2860
+ ignoreBlocker,
2861
+ href,
2862
+ ...rest
2863
+ } = {}) => {
2864
+ if (href) {
2865
+ const currentIndex = this.history.location.state.__TSR_index;
2866
+ const parsed = parseHref(href, {
2867
+ __TSR_index: replace ? currentIndex : currentIndex + 1
2868
+ });
2869
+ const hrefUrl = new URL(parsed.pathname, this.origin);
2870
+ const rewrittenUrl = executeRewriteInput(this.rewrite, hrefUrl);
2871
+ rest.to = rewrittenUrl.pathname;
2872
+ rest.search = this.options.parseSearch(parsed.search);
2873
+ rest.hash = parsed.hash.slice(1);
2874
+ }
2875
+ const location = this.buildLocation({
2876
+ ...rest,
2877
+ _includeValidateSearch: true
2878
+ });
2879
+ this.pendingBuiltLocation = location;
2880
+ const commitPromise = this.commitLocation({
2881
+ ...location,
2882
+ viewTransition,
2883
+ replace,
2884
+ resetScroll,
2885
+ hashScrollIntoView,
2886
+ ignoreBlocker
2887
+ });
2888
+ Promise.resolve().then(() => {
2889
+ if (this.pendingBuiltLocation === location) {
2890
+ this.pendingBuiltLocation = void 0;
2891
+ }
2892
+ });
2893
+ return commitPromise;
2894
+ };
2895
+ this.navigate = async ({
2896
+ to,
2897
+ reloadDocument,
2898
+ href,
2899
+ publicHref,
2900
+ ...rest
2901
+ }) => {
2902
+ let hrefIsUrl = false;
2903
+ if (href) {
2904
+ try {
2905
+ new URL(`${href}`);
2906
+ hrefIsUrl = true;
2907
+ } catch {
2908
+ }
2909
+ }
2910
+ if (hrefIsUrl && !reloadDocument) {
2911
+ reloadDocument = true;
2912
+ }
2913
+ if (reloadDocument) {
2914
+ if (to !== void 0 || !href) {
2915
+ const location = this.buildLocation({ to, ...rest });
2916
+ href = href ?? location.publicHref;
2917
+ publicHref = publicHref ?? location.publicHref;
2918
+ }
2919
+ const reloadHref = !hrefIsUrl && publicHref ? publicHref : href;
2920
+ if (isDangerousProtocol(reloadHref, this.protocolAllowlist)) {
2921
+ return Promise.resolve();
2922
+ }
2923
+ if (!rest.ignoreBlocker) {
2924
+ const historyWithBlockers = this.history;
2925
+ const blockers = historyWithBlockers.getBlockers?.() ?? [];
2926
+ for (const blocker of blockers) {
2927
+ if (blocker?.blockerFn) {
2928
+ const shouldBlock = await blocker.blockerFn({
2929
+ currentLocation: this.latestLocation,
2930
+ nextLocation: this.latestLocation,
2931
+ // External URLs don't have a next location in our router
2932
+ action: "PUSH"
2933
+ });
2934
+ if (shouldBlock) {
2935
+ return Promise.resolve();
2936
+ }
2937
+ }
2938
+ }
2939
+ }
2940
+ if (rest.replace) {
2941
+ window.location.replace(reloadHref);
2942
+ } else {
2943
+ window.location.href = reloadHref;
2944
+ }
2945
+ return Promise.resolve();
2946
+ }
2947
+ return this.buildAndCommitLocation({
2948
+ ...rest,
2949
+ href,
2950
+ to,
2951
+ _isNavigate: true
2952
+ });
2953
+ };
2954
+ this.beforeLoad = () => {
2955
+ this.cancelMatches();
2956
+ this.updateLatestLocation();
2957
+ {
2958
+ const nextLocation = this.buildLocation({
2959
+ to: this.latestLocation.pathname,
2960
+ search: true,
2961
+ params: true,
2962
+ hash: true,
2963
+ state: true,
2964
+ _includeValidateSearch: true
2965
+ });
2966
+ if (this.latestLocation.publicHref !== nextLocation.publicHref) {
2967
+ const href = this.getParsedLocationHref(nextLocation);
2968
+ if (nextLocation.external) {
2969
+ throw redirect({ href });
2970
+ } else {
2971
+ throw redirect({ href, _builtLocation: nextLocation });
2972
+ }
2973
+ }
2974
+ }
2975
+ const pendingMatches = this.matchRoutes(this.latestLocation);
2976
+ this.__store.setState((s) => ({
2977
+ ...s,
2978
+ status: "pending",
2979
+ statusCode: 200,
2980
+ isLoading: true,
2981
+ location: this.latestLocation,
2982
+ pendingMatches,
2983
+ // If a cached moved to pendingMatches, remove it from cachedMatches
2984
+ cachedMatches: s.cachedMatches.filter(
2985
+ (d) => !pendingMatches.some((e) => e.id === d.id)
2986
+ )
2987
+ }));
2988
+ };
2989
+ this.load = async (opts) => {
2990
+ let redirect2;
2991
+ let notFound;
2992
+ let loadPromise;
2993
+ loadPromise = new Promise((resolve) => {
2994
+ this.startTransition(async () => {
2995
+ try {
2996
+ this.beforeLoad();
2997
+ const next = this.latestLocation;
2998
+ const prevLocation = this.state.resolvedLocation;
2999
+ if (!this.state.redirect) {
3000
+ this.emit({
3001
+ type: "onBeforeNavigate",
3002
+ ...getLocationChangeInfo({
3003
+ resolvedLocation: prevLocation,
3004
+ location: next
3005
+ })
3006
+ });
3007
+ }
3008
+ this.emit({
3009
+ type: "onBeforeLoad",
3010
+ ...getLocationChangeInfo({
3011
+ resolvedLocation: prevLocation,
3012
+ location: next
3013
+ })
3014
+ });
3015
+ await loadMatches({
3016
+ router: this,
3017
+ sync: opts?.sync,
3018
+ matches: this.state.pendingMatches,
3019
+ location: next,
3020
+ updateMatch: this.updateMatch,
3021
+ // eslint-disable-next-line @typescript-eslint/require-await
3022
+ onReady: async () => {
3023
+ this.startTransition(() => {
3024
+ this.startViewTransition(async () => {
3025
+ let exitingMatches = [];
3026
+ let hookExitingMatches = [];
3027
+ let hookEnteringMatches = [];
3028
+ let hookStayingMatches = [];
3029
+ batch(() => {
3030
+ this.__store.setState((s) => {
3031
+ const previousMatches = s.matches;
3032
+ const newMatches = s.pendingMatches || s.matches;
3033
+ exitingMatches = previousMatches.filter(
3034
+ (match) => !newMatches.some((d) => d.id === match.id)
3035
+ );
3036
+ hookExitingMatches = previousMatches.filter(
3037
+ (match) => !newMatches.some((d) => d.routeId === match.routeId)
3038
+ );
3039
+ hookEnteringMatches = newMatches.filter(
3040
+ (match) => !previousMatches.some(
3041
+ (d) => d.routeId === match.routeId
3042
+ )
3043
+ );
3044
+ hookStayingMatches = newMatches.filter(
3045
+ (match) => previousMatches.some(
3046
+ (d) => d.routeId === match.routeId
3047
+ )
3048
+ );
3049
+ return {
3050
+ ...s,
3051
+ isLoading: false,
3052
+ loadedAt: Date.now(),
3053
+ matches: newMatches,
3054
+ pendingMatches: void 0,
3055
+ /**
3056
+ * When committing new matches, cache any exiting matches that are still usable.
3057
+ * Routes that resolved with `status: 'error'` or `status: 'notFound'` are
3058
+ * deliberately excluded from `cachedMatches` so that subsequent invalidations
3059
+ * or reloads re-run their loaders instead of reusing the failed/not-found data.
3060
+ */
3061
+ cachedMatches: [
3062
+ ...s.cachedMatches,
3063
+ ...exitingMatches.filter(
3064
+ (d) => d.status !== "error" && d.status !== "notFound" && d.status !== "redirected"
3065
+ )
3066
+ ]
3067
+ };
3068
+ });
3069
+ this.clearExpiredCache();
3070
+ });
3071
+ [
3072
+ [hookExitingMatches, "onLeave"],
3073
+ [hookEnteringMatches, "onEnter"],
3074
+ [hookStayingMatches, "onStay"]
3075
+ ].forEach(([matches, hook]) => {
3076
+ matches.forEach((match) => {
3077
+ this.looseRoutesById[match.routeId].options[hook]?.(
3078
+ match
3079
+ );
3080
+ });
3081
+ });
3082
+ });
3083
+ });
3084
+ }
3085
+ });
3086
+ } catch (err) {
3087
+ if (isRedirect(err)) {
3088
+ redirect2 = err;
3089
+ } else if (isNotFound(err)) {
3090
+ notFound = err;
3091
+ }
3092
+ this.__store.setState((s) => ({
3093
+ ...s,
3094
+ statusCode: redirect2 ? redirect2.status : notFound ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200,
3095
+ redirect: redirect2
3096
+ }));
3097
+ }
3098
+ if (this.latestLoadPromise === loadPromise) {
3099
+ this.commitLocationPromise?.resolve();
3100
+ this.latestLoadPromise = void 0;
3101
+ this.commitLocationPromise = void 0;
3102
+ }
3103
+ resolve();
3104
+ });
3105
+ });
3106
+ this.latestLoadPromise = loadPromise;
3107
+ await loadPromise;
3108
+ while (this.latestLoadPromise && loadPromise !== this.latestLoadPromise) {
3109
+ await this.latestLoadPromise;
3110
+ }
3111
+ let newStatusCode = void 0;
3112
+ if (this.hasNotFoundMatch()) {
3113
+ newStatusCode = 404;
3114
+ } else if (this.__store.state.matches.some((d) => d.status === "error")) {
3115
+ newStatusCode = 500;
3116
+ }
3117
+ if (newStatusCode !== void 0) {
3118
+ this.__store.setState((s) => ({
3119
+ ...s,
3120
+ statusCode: newStatusCode
3121
+ }));
3122
+ }
3123
+ };
3124
+ this.startViewTransition = (fn) => {
3125
+ const shouldViewTransition = this.shouldViewTransition ?? this.options.defaultViewTransition;
3126
+ this.shouldViewTransition = void 0;
3127
+ if (shouldViewTransition && typeof document !== "undefined" && "startViewTransition" in document && typeof document.startViewTransition === "function") {
3128
+ let startViewTransitionParams;
3129
+ if (typeof shouldViewTransition === "object" && this.isViewTransitionTypesSupported) {
3130
+ const next = this.latestLocation;
3131
+ const prevLocation = this.state.resolvedLocation;
3132
+ const resolvedViewTransitionTypes = typeof shouldViewTransition.types === "function" ? shouldViewTransition.types(
3133
+ getLocationChangeInfo({
3134
+ resolvedLocation: prevLocation,
3135
+ location: next
3136
+ })
3137
+ ) : shouldViewTransition.types;
3138
+ if (resolvedViewTransitionTypes === false) {
3139
+ fn();
3140
+ return;
3141
+ }
3142
+ startViewTransitionParams = {
3143
+ update: fn,
3144
+ types: resolvedViewTransitionTypes
3145
+ };
3146
+ } else {
3147
+ startViewTransitionParams = fn;
3148
+ }
3149
+ document.startViewTransition(startViewTransitionParams);
3150
+ } else {
3151
+ fn();
3152
+ }
3153
+ };
3154
+ this.updateMatch = (id, updater) => {
3155
+ this.startTransition(() => {
3156
+ const matchesKey = this.state.pendingMatches?.some((d) => d.id === id) ? "pendingMatches" : this.state.matches.some((d) => d.id === id) ? "matches" : this.state.cachedMatches.some((d) => d.id === id) ? "cachedMatches" : "";
3157
+ if (matchesKey) {
3158
+ if (matchesKey === "cachedMatches") {
3159
+ this.__store.setState((s) => ({
3160
+ ...s,
3161
+ cachedMatches: filterRedirectedCachedMatches(
3162
+ s.cachedMatches.map((d) => d.id === id ? updater(d) : d)
3163
+ )
3164
+ }));
3165
+ } else {
3166
+ this.__store.setState((s) => ({
3167
+ ...s,
3168
+ [matchesKey]: s[matchesKey]?.map(
3169
+ (d) => d.id === id ? updater(d) : d
3170
+ )
3171
+ }));
3172
+ }
3173
+ }
3174
+ });
3175
+ };
3176
+ this.getMatch = (matchId) => {
3177
+ const findFn = (d) => d.id === matchId;
3178
+ return this.state.cachedMatches.find(findFn) ?? this.state.pendingMatches?.find(findFn) ?? this.state.matches.find(findFn);
3179
+ };
3180
+ this.invalidate = (opts) => {
3181
+ const invalidate = (d) => {
3182
+ if (opts?.filter?.(d) ?? true) {
3183
+ return {
3184
+ ...d,
3185
+ invalid: true,
3186
+ ...opts?.forcePending || d.status === "error" || d.status === "notFound" ? { status: "pending", error: void 0 } : void 0
3187
+ };
3188
+ }
3189
+ return d;
3190
+ };
3191
+ this.__store.setState((s) => ({
3192
+ ...s,
3193
+ matches: s.matches.map(invalidate),
3194
+ cachedMatches: s.cachedMatches.map(invalidate),
3195
+ pendingMatches: s.pendingMatches?.map(invalidate)
3196
+ }));
3197
+ this.shouldViewTransition = false;
3198
+ return this.load({ sync: opts?.sync });
3199
+ };
3200
+ this.getParsedLocationHref = (location) => {
3201
+ return location.publicHref || "/";
3202
+ };
3203
+ this.resolveRedirect = (redirect2) => {
3204
+ const locationHeader = redirect2.headers.get("Location");
3205
+ if (!redirect2.options.href || redirect2.options._builtLocation) {
3206
+ const location = redirect2.options._builtLocation ?? this.buildLocation(redirect2.options);
3207
+ const href = this.getParsedLocationHref(location);
3208
+ redirect2.options.href = href;
3209
+ redirect2.headers.set("Location", href);
3210
+ } else if (locationHeader) {
3211
+ try {
3212
+ const url = new URL(locationHeader);
3213
+ if (this.origin && url.origin === this.origin) {
3214
+ const href = url.pathname + url.search + url.hash;
3215
+ redirect2.options.href = href;
3216
+ redirect2.headers.set("Location", href);
3217
+ }
3218
+ } catch {
3219
+ }
3220
+ }
3221
+ if (redirect2.options.href && !redirect2.options._builtLocation && // Check for dangerous protocols before processing the redirect
3222
+ isDangerousProtocol(redirect2.options.href, this.protocolAllowlist)) {
3223
+ throw new Error(
3224
+ "Redirect blocked: unsafe protocol"
3225
+ );
3226
+ }
3227
+ if (!redirect2.headers.get("Location")) {
3228
+ redirect2.headers.set("Location", redirect2.options.href);
3229
+ }
3230
+ return redirect2;
3231
+ };
3232
+ this.clearCache = (opts) => {
3233
+ const filter = opts?.filter;
3234
+ if (filter !== void 0) {
3235
+ this.__store.setState((s) => {
3236
+ return {
3237
+ ...s,
3238
+ cachedMatches: s.cachedMatches.filter(
3239
+ (m) => !filter(m)
3240
+ )
3241
+ };
3242
+ });
3243
+ } else {
3244
+ this.__store.setState((s) => {
3245
+ return {
3246
+ ...s,
3247
+ cachedMatches: []
3248
+ };
3249
+ });
3250
+ }
3251
+ };
3252
+ this.clearExpiredCache = () => {
3253
+ const filter = (d) => {
3254
+ const route = this.looseRoutesById[d.routeId];
3255
+ if (!route.options.loader) {
3256
+ return true;
3257
+ }
3258
+ const gcTime = (d.preload ? route.options.preloadGcTime ?? this.options.defaultPreloadGcTime : route.options.gcTime ?? this.options.defaultGcTime) ?? 5 * 60 * 1e3;
3259
+ const isError = d.status === "error";
3260
+ if (isError) return true;
3261
+ const gcEligible = Date.now() - d.updatedAt >= gcTime;
3262
+ return gcEligible;
3263
+ };
3264
+ this.clearCache({ filter });
3265
+ };
3266
+ this.loadRouteChunk = loadRouteChunk;
3267
+ this.preloadRoute = async (opts) => {
3268
+ const next = opts._builtLocation ?? this.buildLocation(opts);
3269
+ let matches = this.matchRoutes(next, {
3270
+ throwOnError: true,
3271
+ preload: true,
3272
+ dest: opts
3273
+ });
3274
+ const activeMatchIds = new Set(
3275
+ [...this.state.matches, ...this.state.pendingMatches ?? []].map(
3276
+ (d) => d.id
3277
+ )
3278
+ );
3279
+ const loadedMatchIds = /* @__PURE__ */ new Set([
3280
+ ...activeMatchIds,
3281
+ ...this.state.cachedMatches.map((d) => d.id)
3282
+ ]);
3283
+ batch(() => {
3284
+ matches.forEach((match) => {
3285
+ if (!loadedMatchIds.has(match.id)) {
3286
+ this.__store.setState((s) => ({
3287
+ ...s,
3288
+ cachedMatches: [...s.cachedMatches, match]
3289
+ }));
3290
+ }
3291
+ });
3292
+ });
3293
+ try {
3294
+ matches = await loadMatches({
3295
+ router: this,
3296
+ matches,
3297
+ location: next,
3298
+ preload: true,
3299
+ updateMatch: (id, updater) => {
3300
+ if (activeMatchIds.has(id)) {
3301
+ matches = matches.map((d) => d.id === id ? updater(d) : d);
3302
+ } else {
3303
+ this.updateMatch(id, updater);
3304
+ }
3305
+ }
3306
+ });
3307
+ return matches;
3308
+ } catch (err) {
3309
+ if (isRedirect(err)) {
3310
+ if (err.options.reloadDocument) {
3311
+ return void 0;
3312
+ }
3313
+ return await this.preloadRoute({
3314
+ ...err.options,
3315
+ _fromLocation: next
3316
+ });
3317
+ }
3318
+ if (!isNotFound(err)) {
3319
+ console.error(err);
3320
+ }
3321
+ return void 0;
3322
+ }
3323
+ };
3324
+ this.matchRoute = (location, opts) => {
3325
+ const matchLocation = {
3326
+ ...location,
3327
+ to: location.to ? this.resolvePathWithBase(location.from || "", location.to) : void 0,
3328
+ params: location.params || {},
3329
+ leaveParams: true
3330
+ };
3331
+ const next = this.buildLocation(matchLocation);
3332
+ if (opts?.pending && this.state.status !== "pending") {
3333
+ return false;
3334
+ }
3335
+ const pending = opts?.pending === void 0 ? !this.state.isLoading : opts.pending;
3336
+ const baseLocation = pending ? this.latestLocation : this.state.resolvedLocation || this.state.location;
3337
+ const match = findSingleMatch(
3338
+ next.pathname,
3339
+ opts?.caseSensitive ?? false,
3340
+ opts?.fuzzy ?? false,
3341
+ baseLocation.pathname,
3342
+ this.processedTree
3343
+ );
3344
+ if (!match) {
3345
+ return false;
3346
+ }
3347
+ if (location.params) {
3348
+ if (!deepEqual(match.rawParams, location.params, { partial: true })) {
3349
+ return false;
3350
+ }
3351
+ }
3352
+ if (opts?.includeSearch ?? true) {
3353
+ return deepEqual(baseLocation.search, next.search, { partial: true }) ? match.rawParams : false;
3354
+ }
3355
+ return match.rawParams;
3356
+ };
3357
+ this.hasNotFoundMatch = () => {
3358
+ return this.__store.state.matches.some(
3359
+ (d) => d.status === "notFound" || d.globalNotFound
3360
+ );
3361
+ };
3362
+ this.update({
3363
+ defaultPreloadDelay: 50,
3364
+ defaultPendingMs: 1e3,
3365
+ defaultPendingMinMs: 500,
3366
+ context: void 0,
3367
+ ...options,
3368
+ caseSensitive: options.caseSensitive ?? false,
3369
+ notFoundMode: options.notFoundMode ?? "fuzzy",
3370
+ stringifySearch: options.stringifySearch ?? defaultStringifySearch,
3371
+ parseSearch: options.parseSearch ?? defaultParseSearch,
3372
+ protocolAllowlist: options.protocolAllowlist ?? DEFAULT_PROTOCOL_ALLOWLIST
3373
+ });
3374
+ if (typeof document !== "undefined") {
3375
+ self.__TSR_ROUTER__ = this;
3376
+ }
3377
+ }
3378
+ isShell() {
3379
+ return !!this.options.isShell;
3380
+ }
3381
+ isPrerendering() {
3382
+ return !!this.options.isPrerendering;
3383
+ }
3384
+ get state() {
3385
+ return this.__store.state;
3386
+ }
3387
+ setRoutes({
3388
+ routesById,
3389
+ routesByPath,
3390
+ processedTree
3391
+ }) {
3392
+ this.routesById = routesById;
3393
+ this.routesByPath = routesByPath;
3394
+ this.processedTree = processedTree;
3395
+ const notFoundRoute = this.options.notFoundRoute;
3396
+ if (notFoundRoute) {
3397
+ notFoundRoute.init({
3398
+ originalIndex: 99999999999
3399
+ });
3400
+ this.routesById[notFoundRoute.id] = notFoundRoute;
3401
+ }
3402
+ }
3403
+ get looseRoutesById() {
3404
+ return this.routesById;
3405
+ }
3406
+ getParentContext(parentMatch) {
3407
+ const parentMatchId = parentMatch?.id;
3408
+ const parentContext = !parentMatchId ? this.options.context ?? void 0 : parentMatch.context ?? this.options.context ?? void 0;
3409
+ return parentContext;
3410
+ }
3411
+ matchRoutesInternal(next, opts) {
3412
+ const matchedRoutesResult = this.getMatchedRoutes(next.pathname);
3413
+ const { foundRoute, routeParams, parsedParams } = matchedRoutesResult;
3414
+ let { matchedRoutes } = matchedRoutesResult;
3415
+ let isGlobalNotFound = false;
3416
+ if (
3417
+ // If we found a route, and it's not an index route and we have left over path
3418
+ foundRoute ? foundRoute.path !== "/" && routeParams["**"] : (
3419
+ // Or if we didn't find a route and we have left over path
3420
+ trimPathRight(next.pathname)
3421
+ )
3422
+ ) {
3423
+ if (this.options.notFoundRoute) {
3424
+ matchedRoutes = [...matchedRoutes, this.options.notFoundRoute];
3425
+ } else {
3426
+ isGlobalNotFound = true;
3427
+ }
3428
+ }
3429
+ const globalNotFoundRouteId = isGlobalNotFound ? findGlobalNotFoundRouteId(this.options.notFoundMode, matchedRoutes) : void 0;
3430
+ const matches = new Array(matchedRoutes.length);
3431
+ const previousMatchesByRouteId = new Map(
3432
+ this.state.matches.map((match) => [match.routeId, match])
3433
+ );
3434
+ for (let index = 0; index < matchedRoutes.length; index++) {
3435
+ const route = matchedRoutes[index];
3436
+ const parentMatch = matches[index - 1];
3437
+ let preMatchSearch;
3438
+ let strictMatchSearch;
3439
+ let searchError;
3440
+ {
3441
+ const parentSearch = parentMatch?.search ?? next.search;
3442
+ const parentStrictSearch = parentMatch?._strictSearch ?? void 0;
3443
+ try {
3444
+ const strictSearch = validateSearch(route.options.validateSearch, { ...parentSearch }) ?? void 0;
3445
+ preMatchSearch = {
3446
+ ...parentSearch,
3447
+ ...strictSearch
3448
+ };
3449
+ strictMatchSearch = { ...parentStrictSearch, ...strictSearch };
3450
+ searchError = void 0;
3451
+ } catch (err) {
3452
+ let searchParamError = err;
3453
+ if (!(err instanceof SearchParamError)) {
3454
+ searchParamError = new SearchParamError(err.message, {
3455
+ cause: err
3456
+ });
3457
+ }
3458
+ if (opts?.throwOnError) {
3459
+ throw searchParamError;
3460
+ }
3461
+ preMatchSearch = parentSearch;
3462
+ strictMatchSearch = {};
3463
+ searchError = searchParamError;
3464
+ }
3465
+ }
3466
+ const loaderDeps = route.options.loaderDeps?.({
3467
+ search: preMatchSearch
3468
+ }) ?? "";
3469
+ const loaderDepsHash = loaderDeps ? JSON.stringify(loaderDeps) : "";
3470
+ const { interpolatedPath, usedParams } = interpolatePath({
3471
+ path: route.fullPath,
3472
+ params: routeParams,
3473
+ decoder: this.pathParamsDecoder,
3474
+ server: this.isServer
3475
+ });
3476
+ const matchId = (
3477
+ // route.id for disambiguation
3478
+ route.id + // interpolatedPath for param changes
3479
+ interpolatedPath + // explicit deps
3480
+ loaderDepsHash
3481
+ );
3482
+ const existingMatch = this.getMatch(matchId);
3483
+ const previousMatch = previousMatchesByRouteId.get(route.id);
3484
+ const strictParams = existingMatch?._strictParams ?? usedParams;
3485
+ let paramsError = void 0;
3486
+ if (!existingMatch) {
3487
+ try {
3488
+ extractStrictParams(route, usedParams, parsedParams, strictParams);
3489
+ } catch (err) {
3490
+ if (isNotFound(err) || isRedirect(err)) {
3491
+ paramsError = err;
3492
+ } else {
3493
+ paramsError = new PathParamError(err.message, {
3494
+ cause: err
3495
+ });
3496
+ }
3497
+ if (opts?.throwOnError) {
3498
+ throw paramsError;
3499
+ }
3500
+ }
3501
+ }
3502
+ Object.assign(routeParams, strictParams);
3503
+ const cause = previousMatch ? "stay" : "enter";
3504
+ let match;
3505
+ if (existingMatch) {
3506
+ match = {
3507
+ ...existingMatch,
3508
+ cause,
3509
+ params: previousMatch?.params ?? routeParams,
3510
+ _strictParams: strictParams,
3511
+ search: previousMatch ? replaceEqualDeep(previousMatch.search, preMatchSearch) : replaceEqualDeep(existingMatch.search, preMatchSearch),
3512
+ _strictSearch: strictMatchSearch
3513
+ };
3514
+ } else {
3515
+ const status = route.options.loader || route.options.beforeLoad || route.lazyFn || routeNeedsPreload(route) ? "pending" : "success";
3516
+ match = {
3517
+ id: matchId,
3518
+ ssr: void 0,
3519
+ index,
3520
+ routeId: route.id,
3521
+ params: previousMatch?.params ?? routeParams,
3522
+ _strictParams: strictParams,
3523
+ pathname: interpolatedPath,
3524
+ updatedAt: Date.now(),
3525
+ search: previousMatch ? replaceEqualDeep(previousMatch.search, preMatchSearch) : preMatchSearch,
3526
+ _strictSearch: strictMatchSearch,
3527
+ searchError: void 0,
3528
+ status,
3529
+ isFetching: false,
3530
+ error: void 0,
3531
+ paramsError,
3532
+ __routeContext: void 0,
3533
+ _nonReactive: {
3534
+ loadPromise: createControlledPromise()
3535
+ },
3536
+ __beforeLoadContext: void 0,
3537
+ context: {},
3538
+ abortController: new AbortController(),
3539
+ fetchCount: 0,
3540
+ cause,
3541
+ loaderDeps: previousMatch ? replaceEqualDeep(previousMatch.loaderDeps, loaderDeps) : loaderDeps,
3542
+ invalid: false,
3543
+ preload: false,
3544
+ links: void 0,
3545
+ scripts: void 0,
3546
+ headScripts: void 0,
3547
+ meta: void 0,
3548
+ staticData: route.options.staticData || {},
3549
+ fullPath: route.fullPath
3550
+ };
3551
+ }
3552
+ if (!opts?.preload) {
3553
+ match.globalNotFound = globalNotFoundRouteId === route.id;
3554
+ }
3555
+ match.searchError = searchError;
3556
+ const parentContext = this.getParentContext(parentMatch);
3557
+ match.context = {
3558
+ ...parentContext,
3559
+ ...match.__routeContext,
3560
+ ...match.__beforeLoadContext
3561
+ };
3562
+ matches[index] = match;
3563
+ }
3564
+ for (let index = 0; index < matches.length; index++) {
3565
+ const match = matches[index];
3566
+ const route = this.looseRoutesById[match.routeId];
3567
+ const existingMatch = this.getMatch(match.id);
3568
+ const previousMatch = previousMatchesByRouteId.get(match.routeId);
3569
+ match.params = previousMatch ? replaceEqualDeep(previousMatch.params, routeParams) : routeParams;
3570
+ if (!existingMatch) {
3571
+ const parentMatch = matches[index - 1];
3572
+ const parentContext = this.getParentContext(parentMatch);
3573
+ if (route.options.context) {
3574
+ const contextFnContext = {
3575
+ deps: match.loaderDeps,
3576
+ params: match.params,
3577
+ context: parentContext ?? {},
3578
+ location: next,
3579
+ navigate: (opts2) => this.navigate({ ...opts2, _fromLocation: next }),
3580
+ buildLocation: this.buildLocation,
3581
+ cause: match.cause,
3582
+ abortController: match.abortController,
3583
+ preload: !!match.preload,
3584
+ matches,
3585
+ routeId: route.id
3586
+ };
3587
+ match.__routeContext = route.options.context(contextFnContext) ?? void 0;
3588
+ }
3589
+ match.context = {
3590
+ ...parentContext,
3591
+ ...match.__routeContext,
3592
+ ...match.__beforeLoadContext
3593
+ };
3594
+ }
3595
+ }
3596
+ return matches;
3597
+ }
3598
+ /**
3599
+ * Lightweight route matching for buildLocation.
3600
+ * Only computes fullPath, accumulated search, and params - skipping expensive
3601
+ * operations like AbortController, ControlledPromise, loaderDeps, and full match objects.
3602
+ */
3603
+ matchRoutesLightweight(location) {
3604
+ const { matchedRoutes, routeParams, parsedParams } = this.getMatchedRoutes(
3605
+ location.pathname
3606
+ );
3607
+ const lastRoute = last(matchedRoutes);
3608
+ const accumulatedSearch = { ...location.search };
3609
+ for (const route of matchedRoutes) {
3610
+ try {
3611
+ Object.assign(
3612
+ accumulatedSearch,
3613
+ validateSearch(route.options.validateSearch, accumulatedSearch)
3614
+ );
3615
+ } catch {
3616
+ }
3617
+ }
3618
+ const lastStateMatch = last(this.state.matches);
3619
+ const canReuseParams = lastStateMatch && lastStateMatch.routeId === lastRoute.id && location.pathname === this.state.location.pathname;
3620
+ let params;
3621
+ if (canReuseParams) {
3622
+ params = lastStateMatch.params;
3623
+ } else {
3624
+ const strictParams = { ...routeParams };
3625
+ for (const route of matchedRoutes) {
3626
+ try {
3627
+ extractStrictParams(
3628
+ route,
3629
+ routeParams,
3630
+ parsedParams ?? {},
3631
+ strictParams
3632
+ );
3633
+ } catch {
3634
+ }
3635
+ }
3636
+ params = strictParams;
3637
+ }
3638
+ return {
3639
+ matchedRoutes,
3640
+ fullPath: lastRoute.fullPath,
3641
+ search: accumulatedSearch,
3642
+ params
3643
+ };
3644
+ }
3645
+ }
3646
+ class SearchParamError extends Error {
3647
+ }
3648
+ class PathParamError extends Error {
3649
+ }
3650
+ function getInitialRouterState(location) {
3651
+ return {
3652
+ loadedAt: 0,
3653
+ isLoading: false,
3654
+ isTransitioning: false,
3655
+ status: "idle",
3656
+ resolvedLocation: void 0,
3657
+ location,
3658
+ matches: [],
3659
+ pendingMatches: [],
3660
+ cachedMatches: [],
3661
+ statusCode: 200
3662
+ };
3663
+ }
3664
+ function validateSearch(validateSearch2, input) {
3665
+ if (validateSearch2 == null) return {};
3666
+ if ("~standard" in validateSearch2) {
3667
+ const result = validateSearch2["~standard"].validate(input);
3668
+ if (result instanceof Promise)
3669
+ throw new SearchParamError("Async validation not supported");
3670
+ if (result.issues)
3671
+ throw new SearchParamError(JSON.stringify(result.issues, void 0, 2), {
3672
+ cause: result
3673
+ });
3674
+ return result.value;
3675
+ }
3676
+ if ("parse" in validateSearch2) {
3677
+ return validateSearch2.parse(input);
3678
+ }
3679
+ if (typeof validateSearch2 === "function") {
3680
+ return validateSearch2(input);
3681
+ }
3682
+ return {};
3683
+ }
3684
+ function getMatchedRoutes({
3685
+ pathname,
3686
+ routesById,
3687
+ processedTree
3688
+ }) {
3689
+ const routeParams = {};
3690
+ const trimmedPath = trimPathRight(pathname);
3691
+ let foundRoute = void 0;
3692
+ let parsedParams = void 0;
3693
+ const match = findRouteMatch(trimmedPath, processedTree, true);
3694
+ if (match) {
3695
+ foundRoute = match.route;
3696
+ Object.assign(routeParams, match.rawParams);
3697
+ parsedParams = Object.assign({}, match.parsedParams);
3698
+ }
3699
+ const matchedRoutes = match?.branch || [routesById[rootRouteId]];
3700
+ return { matchedRoutes, routeParams, foundRoute, parsedParams };
3701
+ }
3702
+ function applySearchMiddleware({
3703
+ search,
3704
+ dest,
3705
+ destRoutes,
3706
+ _includeValidateSearch
3707
+ }) {
3708
+ const middleware = buildMiddlewareChain(destRoutes);
3709
+ return middleware(search, dest, _includeValidateSearch ?? false);
3710
+ }
3711
+ function buildMiddlewareChain(destRoutes) {
3712
+ const context = {
3713
+ dest: null,
3714
+ _includeValidateSearch: false,
3715
+ middlewares: []
3716
+ };
3717
+ for (const route of destRoutes) {
3718
+ if ("search" in route.options) {
3719
+ if (route.options.search?.middlewares) {
3720
+ context.middlewares.push(...route.options.search.middlewares);
3721
+ }
3722
+ } else if (route.options.preSearchFilters || route.options.postSearchFilters) {
3723
+ const legacyMiddleware = ({ search, next }) => {
3724
+ let nextSearch = search;
3725
+ if ("preSearchFilters" in route.options && route.options.preSearchFilters) {
3726
+ nextSearch = route.options.preSearchFilters.reduce(
3727
+ (prev, next2) => next2(prev),
3728
+ search
3729
+ );
3730
+ }
3731
+ const result = next(nextSearch);
3732
+ if ("postSearchFilters" in route.options && route.options.postSearchFilters) {
3733
+ return route.options.postSearchFilters.reduce(
3734
+ (prev, next2) => next2(prev),
3735
+ result
3736
+ );
3737
+ }
3738
+ return result;
3739
+ };
3740
+ context.middlewares.push(legacyMiddleware);
3741
+ }
3742
+ if (route.options.validateSearch) {
3743
+ const validate = ({ search, next }) => {
3744
+ const result = next(search);
3745
+ if (!context._includeValidateSearch) return result;
3746
+ try {
3747
+ const validatedSearch = {
3748
+ ...result,
3749
+ ...validateSearch(route.options.validateSearch, result) ?? void 0
3750
+ };
3751
+ return validatedSearch;
3752
+ } catch {
3753
+ return result;
3754
+ }
3755
+ };
3756
+ context.middlewares.push(validate);
3757
+ }
3758
+ }
3759
+ const final = ({ search }) => {
3760
+ const dest = context.dest;
3761
+ if (!dest.search) {
3762
+ return {};
3763
+ }
3764
+ if (dest.search === true) {
3765
+ return search;
3766
+ }
3767
+ return functionalUpdate(dest.search, search);
3768
+ };
3769
+ context.middlewares.push(final);
3770
+ const applyNext = (index, currentSearch, middlewares) => {
3771
+ if (index >= middlewares.length) {
3772
+ return currentSearch;
3773
+ }
3774
+ const middleware = middlewares[index];
3775
+ const next = (newSearch) => {
3776
+ return applyNext(index + 1, newSearch, middlewares);
3777
+ };
3778
+ return middleware({ search: currentSearch, next });
3779
+ };
3780
+ return function middleware(search, dest, _includeValidateSearch) {
3781
+ context.dest = dest;
3782
+ context._includeValidateSearch = _includeValidateSearch;
3783
+ return applyNext(0, search, context.middlewares);
3784
+ };
3785
+ }
3786
+ function findGlobalNotFoundRouteId(notFoundMode, routes) {
3787
+ if (notFoundMode !== "root") {
3788
+ for (let i = routes.length - 1; i >= 0; i--) {
3789
+ const route = routes[i];
3790
+ if (route.children) {
3791
+ return route.id;
3792
+ }
3793
+ }
3794
+ }
3795
+ return rootRouteId;
3796
+ }
3797
+ function extractStrictParams(route, referenceParams, parsedParams, accumulatedParams) {
3798
+ const parseParams = route.options.params?.parse ?? route.options.parseParams;
3799
+ if (parseParams) {
3800
+ if (route.options.skipRouteOnParseError) {
3801
+ for (const key in referenceParams) {
3802
+ if (key in parsedParams) {
3803
+ accumulatedParams[key] = parsedParams[key];
3804
+ }
3805
+ }
3806
+ } else {
3807
+ const result = parseParams(accumulatedParams);
3808
+ Object.assign(accumulatedParams, result);
3809
+ }
3810
+ }
3811
+ }
3812
+ class BaseRoute {
3813
+ constructor(options) {
3814
+ this.init = (opts) => {
3815
+ this.originalIndex = opts.originalIndex;
3816
+ const options2 = this.options;
3817
+ const isRoot = !options2?.path && !options2?.id;
3818
+ this.parentRoute = this.options.getParentRoute?.();
3819
+ if (isRoot) {
3820
+ this._path = rootRouteId;
3821
+ } else if (!this.parentRoute) {
3822
+ invariant(
3823
+ false
3824
+ );
3825
+ }
3826
+ let path = isRoot ? rootRouteId : options2?.path;
3827
+ if (path && path !== "/") {
3828
+ path = trimPathLeft(path);
3829
+ }
3830
+ const customId = options2?.id || path;
3831
+ let id = isRoot ? rootRouteId : joinPaths([
3832
+ this.parentRoute.id === rootRouteId ? "" : this.parentRoute.id,
3833
+ customId
3834
+ ]);
3835
+ if (path === rootRouteId) {
3836
+ path = "/";
3837
+ }
3838
+ if (id !== rootRouteId) {
3839
+ id = joinPaths(["/", id]);
3840
+ }
3841
+ const fullPath = id === rootRouteId ? "/" : joinPaths([this.parentRoute.fullPath, path]);
3842
+ this._path = path;
3843
+ this._id = id;
3844
+ this._fullPath = fullPath;
3845
+ this._to = trimPathRight(fullPath);
3846
+ };
3847
+ this.addChildren = (children) => {
3848
+ return this._addFileChildren(children);
3849
+ };
3850
+ this._addFileChildren = (children) => {
3851
+ if (Array.isArray(children)) {
3852
+ this.children = children;
3853
+ }
3854
+ if (typeof children === "object" && children !== null) {
3855
+ this.children = Object.values(children);
3856
+ }
3857
+ return this;
3858
+ };
3859
+ this._addFileTypes = () => {
3860
+ return this;
3861
+ };
3862
+ this.updateLoader = (options2) => {
3863
+ Object.assign(this.options, options2);
3864
+ return this;
3865
+ };
3866
+ this.update = (options2) => {
3867
+ Object.assign(this.options, options2);
3868
+ return this;
3869
+ };
3870
+ this.lazy = (lazyFn) => {
3871
+ this.lazyFn = lazyFn;
3872
+ return this;
3873
+ };
3874
+ this.redirect = (opts) => redirect({ from: this.fullPath, ...opts });
3875
+ this.options = options || {};
3876
+ this.isRoot = !options?.getParentRoute;
3877
+ if (options?.id && options?.path) {
3878
+ throw new Error(`Route cannot have both an 'id' and a 'path' option.`);
3879
+ }
3880
+ }
3881
+ get to() {
3882
+ return this._to;
3883
+ }
3884
+ get id() {
3885
+ return this._id;
3886
+ }
3887
+ get path() {
3888
+ return this._path;
3889
+ }
3890
+ get fullPath() {
3891
+ return this._fullPath;
3892
+ }
3893
+ }
3894
+ class BaseRootRoute extends BaseRoute {
3895
+ constructor(options) {
3896
+ super(options);
3897
+ }
3898
+ }
3899
+ const GLOBAL_TSR = "$_TSR";
3900
+ const TSR_SCRIPT_BARRIER_ID = "$tsr-stream-barrier";
3901
+ function createSerializationAdapter(opts) {
3902
+ return opts;
3903
+ }
3904
+ function makeSsrSerovalPlugin(serializationAdapter, options) {
3905
+ return ni({
3906
+ tag: "$TSR/t/" + serializationAdapter.key,
3907
+ test: serializationAdapter.test,
3908
+ parse: {
3909
+ stream(value, ctx) {
3910
+ return ctx.parse(serializationAdapter.toSerializable(value));
3911
+ }
3912
+ },
3913
+ serialize(node, ctx) {
3914
+ options.didRun = true;
3915
+ return GLOBAL_TSR + '.t.get("' + serializationAdapter.key + '")(' + ctx.serialize(node) + ")";
3916
+ },
3917
+ // we never deserialize on the server during SSR
3918
+ deserialize: void 0
3919
+ });
3920
+ }
3921
+ function makeSerovalPlugin(serializationAdapter) {
3922
+ return ni({
3923
+ tag: "$TSR/t/" + serializationAdapter.key,
3924
+ test: serializationAdapter.test,
3925
+ parse: {
3926
+ sync(value, ctx) {
3927
+ return ctx.parse(serializationAdapter.toSerializable(value));
3928
+ },
3929
+ async async(value, ctx) {
3930
+ return await ctx.parse(serializationAdapter.toSerializable(value));
3931
+ },
3932
+ stream(value, ctx) {
3933
+ return ctx.parse(serializationAdapter.toSerializable(value));
3934
+ }
3935
+ },
3936
+ // we don't generate JS code outside of SSR (for now)
3937
+ serialize: void 0,
3938
+ deserialize(node, ctx) {
3939
+ return serializationAdapter.fromSerializable(ctx.deserialize(node));
3940
+ }
3941
+ });
3942
+ }
3943
+ const ShallowErrorPlugin = /* @__PURE__ */ ni({
3944
+ tag: "$TSR/Error",
3945
+ test(value) {
3946
+ return value instanceof Error;
3947
+ },
3948
+ parse: {
3949
+ sync(value, ctx) {
3950
+ return {
3951
+ message: ctx.parse(value.message)
3952
+ };
3953
+ },
3954
+ async async(value, ctx) {
3955
+ return {
3956
+ message: await ctx.parse(value.message)
3957
+ };
3958
+ },
3959
+ stream(value, ctx) {
3960
+ return {
3961
+ message: ctx.parse(value.message)
3962
+ };
3963
+ }
3964
+ },
3965
+ serialize(node, ctx) {
3966
+ return "new Error(" + ctx.serialize(node.message) + ")";
3967
+ },
3968
+ deserialize(node, ctx) {
3969
+ return new Error(ctx.deserialize(node.message));
3970
+ }
3971
+ });
3972
+ class RawStream {
3973
+ constructor(stream, options) {
3974
+ this.stream = stream;
3975
+ this.hint = options?.hint ?? "binary";
3976
+ }
3977
+ }
3978
+ const BufferCtor = globalThis.Buffer;
3979
+ const hasNodeBuffer = !!BufferCtor && typeof BufferCtor.from === "function";
3980
+ function uint8ArrayToBase64(bytes) {
3981
+ if (bytes.length === 0) return "";
3982
+ if (hasNodeBuffer) {
3983
+ return BufferCtor.from(bytes).toString("base64");
3984
+ }
3985
+ const CHUNK_SIZE = 32768;
3986
+ const chunks = [];
3987
+ for (let i = 0; i < bytes.length; i += CHUNK_SIZE) {
3988
+ const chunk = bytes.subarray(i, i + CHUNK_SIZE);
3989
+ chunks.push(String.fromCharCode.apply(null, chunk));
3990
+ }
3991
+ return btoa(chunks.join(""));
3992
+ }
3993
+ function base64ToUint8Array(base64) {
3994
+ if (base64.length === 0) return new Uint8Array(0);
3995
+ if (hasNodeBuffer) {
3996
+ const buf = BufferCtor.from(base64, "base64");
3997
+ return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
3998
+ }
3999
+ const binary = atob(base64);
4000
+ const bytes = new Uint8Array(binary.length);
4001
+ for (let i = 0; i < binary.length; i++) {
4002
+ bytes[i] = binary.charCodeAt(i);
4003
+ }
4004
+ return bytes;
4005
+ }
4006
+ const RAW_STREAM_FACTORY_BINARY = /* @__PURE__ */ Object.create(null);
4007
+ const RAW_STREAM_FACTORY_TEXT = /* @__PURE__ */ Object.create(null);
4008
+ const RAW_STREAM_FACTORY_CONSTRUCTOR_BINARY = (stream) => new ReadableStream({
4009
+ start(controller) {
4010
+ stream.on({
4011
+ next(base64) {
4012
+ try {
4013
+ controller.enqueue(base64ToUint8Array(base64));
4014
+ } catch {
4015
+ }
4016
+ },
4017
+ throw(error) {
4018
+ controller.error(error);
4019
+ },
4020
+ return() {
4021
+ try {
4022
+ controller.close();
4023
+ } catch {
4024
+ }
4025
+ }
4026
+ });
4027
+ }
4028
+ });
4029
+ const textEncoderForFactory = new TextEncoder();
4030
+ const RAW_STREAM_FACTORY_CONSTRUCTOR_TEXT = (stream) => {
4031
+ return new ReadableStream({
4032
+ start(controller) {
4033
+ stream.on({
4034
+ next(value) {
4035
+ try {
4036
+ if (typeof value === "string") {
4037
+ controller.enqueue(textEncoderForFactory.encode(value));
4038
+ } else {
4039
+ controller.enqueue(base64ToUint8Array(value.$b64));
4040
+ }
4041
+ } catch {
4042
+ }
4043
+ },
4044
+ throw(error) {
4045
+ controller.error(error);
4046
+ },
4047
+ return() {
4048
+ try {
4049
+ controller.close();
4050
+ } catch {
4051
+ }
4052
+ }
4053
+ });
4054
+ }
4055
+ });
4056
+ };
4057
+ const FACTORY_BINARY = `(s=>new ReadableStream({start(c){s.on({next(b){try{const d=atob(b),a=new Uint8Array(d.length);for(let i=0;i<d.length;i++)a[i]=d.charCodeAt(i);c.enqueue(a)}catch(_){}},throw(e){c.error(e)},return(){try{c.close()}catch(_){}}})}}))`;
4058
+ const FACTORY_TEXT = `(s=>{const e=new TextEncoder();return new ReadableStream({start(c){s.on({next(v){try{if(typeof v==='string'){c.enqueue(e.encode(v))}else{const d=atob(v.$b64),a=new Uint8Array(d.length);for(let i=0;i<d.length;i++)a[i]=d.charCodeAt(i);c.enqueue(a)}}catch(_){}},throw(x){c.error(x)},return(){try{c.close()}catch(_){}}})}})})`;
4059
+ function toBinaryStream(readable) {
4060
+ const stream = te();
4061
+ const reader = readable.getReader();
4062
+ (async () => {
4063
+ try {
4064
+ while (true) {
4065
+ const { done, value } = await reader.read();
4066
+ if (done) {
4067
+ stream.return(void 0);
4068
+ break;
4069
+ }
4070
+ stream.next(uint8ArrayToBase64(value));
4071
+ }
4072
+ } catch (error) {
4073
+ stream.throw(error);
4074
+ } finally {
4075
+ reader.releaseLock();
4076
+ }
4077
+ })();
4078
+ return stream;
4079
+ }
4080
+ function toTextStream(readable) {
4081
+ const stream = te();
4082
+ const reader = readable.getReader();
4083
+ const decoder = new TextDecoder("utf-8", { fatal: true });
4084
+ (async () => {
4085
+ try {
4086
+ while (true) {
4087
+ const { done, value } = await reader.read();
4088
+ if (done) {
4089
+ try {
4090
+ const remaining = decoder.decode();
4091
+ if (remaining.length > 0) {
4092
+ stream.next(remaining);
4093
+ }
4094
+ } catch {
4095
+ }
4096
+ stream.return(void 0);
4097
+ break;
4098
+ }
4099
+ try {
4100
+ const text = decoder.decode(value, { stream: true });
4101
+ if (text.length > 0) {
4102
+ stream.next(text);
4103
+ }
4104
+ } catch {
4105
+ stream.next({ $b64: uint8ArrayToBase64(value) });
4106
+ }
4107
+ }
4108
+ } catch (error) {
4109
+ stream.throw(error);
4110
+ } finally {
4111
+ reader.releaseLock();
4112
+ }
4113
+ })();
4114
+ return stream;
4115
+ }
4116
+ const RawStreamFactoryBinaryPlugin = ni({
4117
+ tag: "tss/RawStreamFactory",
4118
+ test(value) {
4119
+ return value === RAW_STREAM_FACTORY_BINARY;
4120
+ },
4121
+ parse: {
4122
+ sync() {
4123
+ return void 0;
4124
+ },
4125
+ async() {
4126
+ return Promise.resolve(void 0);
4127
+ },
4128
+ stream() {
4129
+ return void 0;
4130
+ }
4131
+ },
4132
+ serialize() {
4133
+ return FACTORY_BINARY;
4134
+ },
4135
+ deserialize() {
4136
+ return RAW_STREAM_FACTORY_BINARY;
4137
+ }
4138
+ });
4139
+ const RawStreamFactoryTextPlugin = ni({
4140
+ tag: "tss/RawStreamFactoryText",
4141
+ test(value) {
4142
+ return value === RAW_STREAM_FACTORY_TEXT;
4143
+ },
4144
+ parse: {
4145
+ sync() {
4146
+ return void 0;
4147
+ },
4148
+ async() {
4149
+ return Promise.resolve(void 0);
4150
+ },
4151
+ stream() {
4152
+ return void 0;
4153
+ }
4154
+ },
4155
+ serialize() {
4156
+ return FACTORY_TEXT;
4157
+ },
4158
+ deserialize() {
4159
+ return RAW_STREAM_FACTORY_TEXT;
4160
+ }
4161
+ });
4162
+ const RawStreamSSRPlugin = ni({
4163
+ tag: "tss/RawStream",
4164
+ extends: [RawStreamFactoryBinaryPlugin, RawStreamFactoryTextPlugin],
4165
+ test(value) {
4166
+ return value instanceof RawStream;
4167
+ },
4168
+ parse: {
4169
+ sync(value, ctx) {
4170
+ const factory = value.hint === "text" ? RAW_STREAM_FACTORY_TEXT : RAW_STREAM_FACTORY_BINARY;
4171
+ return {
4172
+ hint: value.hint,
4173
+ factory: ctx.parse(factory),
4174
+ stream: ctx.parse(te())
4175
+ };
4176
+ },
4177
+ async async(value, ctx) {
4178
+ const factory = value.hint === "text" ? RAW_STREAM_FACTORY_TEXT : RAW_STREAM_FACTORY_BINARY;
4179
+ const encodedStream = value.hint === "text" ? toTextStream(value.stream) : toBinaryStream(value.stream);
4180
+ return {
4181
+ hint: value.hint,
4182
+ factory: await ctx.parse(factory),
4183
+ stream: await ctx.parse(encodedStream)
4184
+ };
4185
+ },
4186
+ stream(value, ctx) {
4187
+ const factory = value.hint === "text" ? RAW_STREAM_FACTORY_TEXT : RAW_STREAM_FACTORY_BINARY;
4188
+ const encodedStream = value.hint === "text" ? toTextStream(value.stream) : toBinaryStream(value.stream);
4189
+ return {
4190
+ hint: value.hint,
4191
+ factory: ctx.parse(factory),
4192
+ stream: ctx.parse(encodedStream)
4193
+ };
4194
+ }
4195
+ },
4196
+ serialize(node, ctx) {
4197
+ return "(" + ctx.serialize(node.factory) + ")(" + ctx.serialize(node.stream) + ")";
4198
+ },
4199
+ deserialize(node, ctx) {
4200
+ const stream = ctx.deserialize(node.stream);
4201
+ return node.hint === "text" ? RAW_STREAM_FACTORY_CONSTRUCTOR_TEXT(stream) : RAW_STREAM_FACTORY_CONSTRUCTOR_BINARY(stream);
4202
+ }
4203
+ });
4204
+ function createRawStreamRPCPlugin(onRawStream) {
4205
+ let nextStreamId = 1;
4206
+ return ni({
4207
+ tag: "tss/RawStream",
4208
+ test(value) {
4209
+ return value instanceof RawStream;
4210
+ },
4211
+ parse: {
4212
+ async(value) {
4213
+ const streamId = nextStreamId++;
4214
+ onRawStream(streamId, value.stream);
4215
+ return Promise.resolve({ streamId });
4216
+ },
4217
+ stream(value) {
4218
+ const streamId = nextStreamId++;
4219
+ onRawStream(streamId, value.stream);
4220
+ return { streamId };
4221
+ }
4222
+ },
4223
+ serialize() {
4224
+ throw new Error(
4225
+ "RawStreamRPCPlugin.serialize should not be called. RPC uses JSON serialization, not JS code generation."
4226
+ );
4227
+ },
4228
+ deserialize() {
4229
+ throw new Error(
4230
+ "RawStreamRPCPlugin.deserialize should not be called. Use createRawStreamDeserializePlugin on client."
4231
+ );
4232
+ }
4233
+ });
4234
+ }
4235
+ const defaultSerovalPlugins = [
4236
+ ShallowErrorPlugin,
4237
+ // RawStreamSSRPlugin must come before ReadableStreamPlugin to match first
4238
+ RawStreamSSRPlugin,
4239
+ // ReadableStreamNode is not exported by seroval
4240
+ p
4241
+ ];
4242
+ const minifiedTsrBootStrapScript = "self.$_TSR={h(){this.hydrated=!0,this.c()},e(){this.streamEnded=!0,this.c()},c(){this.hydrated&&this.streamEnded&&(delete self.$_TSR,delete self.$R.tsr)},p(e){this.initialized?e():this.buffer.push(e)},buffer:[]};\n";
4243
+ const SCOPE_ID = "tsr";
4244
+ const TSR_PREFIX = GLOBAL_TSR + ".router=";
4245
+ const P_PREFIX = GLOBAL_TSR + ".p(()=>";
4246
+ const P_SUFFIX = ")";
4247
+ function dehydrateMatch(match) {
4248
+ const dehydratedMatch = {
4249
+ i: dehydrateSsrMatchId(match.id),
4250
+ u: match.updatedAt,
4251
+ s: match.status
4252
+ };
4253
+ const properties = [
4254
+ ["__beforeLoadContext", "b"],
4255
+ ["loaderData", "l"],
4256
+ ["error", "e"],
4257
+ ["ssr", "ssr"]
4258
+ ];
4259
+ for (const [key, shorthand] of properties) {
4260
+ if (match[key] !== void 0) {
4261
+ dehydratedMatch[shorthand] = match[key];
4262
+ }
4263
+ }
4264
+ if (match.globalNotFound) {
4265
+ dehydratedMatch.g = true;
4266
+ }
4267
+ return dehydratedMatch;
4268
+ }
4269
+ const INITIAL_SCRIPTS = [
4270
+ mn(SCOPE_ID),
4271
+ minifiedTsrBootStrapScript
4272
+ ];
4273
+ class ScriptBuffer {
4274
+ constructor(router) {
4275
+ this._scriptBarrierLifted = false;
4276
+ this._cleanedUp = false;
4277
+ this._pendingMicrotask = false;
4278
+ this.router = router;
4279
+ this._queue = INITIAL_SCRIPTS.slice();
4280
+ }
4281
+ enqueue(script) {
4282
+ if (this._cleanedUp) return;
4283
+ this._queue.push(script);
4284
+ if (this._scriptBarrierLifted && !this._pendingMicrotask) {
4285
+ this._pendingMicrotask = true;
4286
+ queueMicrotask(() => {
4287
+ this._pendingMicrotask = false;
4288
+ this.injectBufferedScripts();
4289
+ });
4290
+ }
4291
+ }
4292
+ liftBarrier() {
4293
+ if (this._scriptBarrierLifted || this._cleanedUp) return;
4294
+ this._scriptBarrierLifted = true;
4295
+ if (this._queue.length > 0 && !this._pendingMicrotask) {
4296
+ this._pendingMicrotask = true;
4297
+ queueMicrotask(() => {
4298
+ this._pendingMicrotask = false;
4299
+ this.injectBufferedScripts();
4300
+ });
4301
+ }
4302
+ }
4303
+ /**
4304
+ * Flushes any pending scripts synchronously.
4305
+ * Call this before emitting onSerializationFinished to ensure all scripts are injected.
4306
+ *
4307
+ * IMPORTANT: Only injects if the barrier has been lifted. Before the barrier is lifted,
4308
+ * scripts should remain in the queue so takeBufferedScripts() can retrieve them
4309
+ */
4310
+ flush() {
4311
+ if (!this._scriptBarrierLifted) return;
4312
+ if (this._cleanedUp) return;
4313
+ this._pendingMicrotask = false;
4314
+ const scriptsToInject = this.takeAll();
4315
+ if (scriptsToInject && this.router?.serverSsr) {
4316
+ this.router.serverSsr.injectScript(scriptsToInject);
4317
+ }
4318
+ }
4319
+ takeAll() {
4320
+ const bufferedScripts = this._queue;
4321
+ this._queue = [];
4322
+ if (bufferedScripts.length === 0) {
4323
+ return void 0;
4324
+ }
4325
+ if (bufferedScripts.length === 1) {
4326
+ return bufferedScripts[0] + ";document.currentScript.remove()";
4327
+ }
4328
+ return bufferedScripts.join(";") + ";document.currentScript.remove()";
4329
+ }
4330
+ injectBufferedScripts() {
4331
+ if (this._cleanedUp) return;
4332
+ if (this._queue.length === 0) return;
4333
+ const scriptsToInject = this.takeAll();
4334
+ if (scriptsToInject && this.router?.serverSsr) {
4335
+ this.router.serverSsr.injectScript(scriptsToInject);
4336
+ }
4337
+ }
4338
+ cleanup() {
4339
+ this._cleanedUp = true;
4340
+ this._queue = [];
4341
+ this.router = void 0;
4342
+ }
4343
+ }
4344
+ const MANIFEST_CACHE_SIZE = 100;
4345
+ const manifestCaches = /* @__PURE__ */ new WeakMap();
4346
+ function getManifestCache(manifest) {
4347
+ const cache = manifestCaches.get(manifest);
4348
+ if (cache) return cache;
4349
+ const newCache = createLRUCache(MANIFEST_CACHE_SIZE);
4350
+ manifestCaches.set(manifest, newCache);
4351
+ return newCache;
4352
+ }
4353
+ function attachRouterServerSsrUtils({
4354
+ router,
4355
+ manifest
4356
+ }) {
4357
+ router.ssr = {
4358
+ manifest
4359
+ };
4360
+ let _dehydrated = false;
4361
+ let _serializationFinished = false;
4362
+ const renderFinishedListeners = [];
4363
+ const serializationFinishedListeners = [];
4364
+ const scriptBuffer = new ScriptBuffer(router);
4365
+ let injectedHtmlBuffer = "";
4366
+ router.serverSsr = {
4367
+ injectHtml: (html) => {
4368
+ if (!html) return;
4369
+ injectedHtmlBuffer += html;
4370
+ router.emit({
4371
+ type: "onInjectedHtml"
4372
+ });
4373
+ },
4374
+ injectScript: (script) => {
4375
+ if (!script) return;
4376
+ const html = `<script${router.options.ssr?.nonce ? ` nonce='${router.options.ssr.nonce}'` : ""}>${script}<\/script>`;
4377
+ router.serverSsr.injectHtml(html);
4378
+ },
4379
+ dehydrate: async () => {
4380
+ invariant(!_dehydrated);
4381
+ let matchesToDehydrate = router.state.matches;
4382
+ if (router.isShell()) {
4383
+ matchesToDehydrate = matchesToDehydrate.slice(0, 1);
4384
+ }
4385
+ const matches = matchesToDehydrate.map(dehydrateMatch);
4386
+ let manifestToDehydrate = void 0;
4387
+ if (manifest) {
4388
+ const currentRouteIdsList = matchesToDehydrate.map((m) => m.routeId);
4389
+ const manifestCacheKey = currentRouteIdsList.join("\0");
4390
+ let filteredRoutes;
4391
+ {
4392
+ filteredRoutes = getManifestCache(manifest).get(manifestCacheKey);
4393
+ }
4394
+ if (!filteredRoutes) {
4395
+ const currentRouteIds = new Set(currentRouteIdsList);
4396
+ const nextFilteredRoutes = {};
4397
+ for (const routeId in manifest.routes) {
4398
+ const routeManifest = manifest.routes[routeId];
4399
+ if (currentRouteIds.has(routeId)) {
4400
+ nextFilteredRoutes[routeId] = routeManifest;
4401
+ } else if (routeManifest.assets && routeManifest.assets.length > 0) {
4402
+ nextFilteredRoutes[routeId] = {
4403
+ assets: routeManifest.assets
4404
+ };
4405
+ }
4406
+ }
4407
+ {
4408
+ getManifestCache(manifest).set(manifestCacheKey, nextFilteredRoutes);
4409
+ }
4410
+ filteredRoutes = nextFilteredRoutes;
4411
+ }
4412
+ manifestToDehydrate = {
4413
+ routes: filteredRoutes
4414
+ };
4415
+ }
4416
+ const dehydratedRouter = {
4417
+ manifest: manifestToDehydrate,
4418
+ matches
4419
+ };
4420
+ const lastMatchId = matchesToDehydrate[matchesToDehydrate.length - 1]?.id;
4421
+ if (lastMatchId) {
4422
+ dehydratedRouter.lastMatchId = dehydrateSsrMatchId(lastMatchId);
4423
+ }
4424
+ const dehydratedData = await router.options.dehydrate?.();
4425
+ if (dehydratedData) {
4426
+ dehydratedRouter.dehydratedData = dehydratedData;
4427
+ }
4428
+ _dehydrated = true;
4429
+ const trackPlugins = { didRun: false };
4430
+ const serializationAdapters = router.options.serializationAdapters;
4431
+ const plugins = serializationAdapters ? serializationAdapters.map((t) => makeSsrSerovalPlugin(t, trackPlugins)).concat(defaultSerovalPlugins) : defaultSerovalPlugins;
4432
+ const signalSerializationComplete = () => {
4433
+ _serializationFinished = true;
4434
+ try {
4435
+ serializationFinishedListeners.forEach((l) => l());
4436
+ router.emit({ type: "onSerializationFinished" });
4437
+ } catch (err) {
4438
+ console.error("Serialization listener error:", err);
4439
+ } finally {
4440
+ serializationFinishedListeners.length = 0;
4441
+ renderFinishedListeners.length = 0;
4442
+ }
4443
+ };
4444
+ cn(dehydratedRouter, {
4445
+ refs: /* @__PURE__ */ new Map(),
4446
+ plugins,
4447
+ onSerialize: (data, initial) => {
4448
+ let serialized = initial ? TSR_PREFIX + data : data;
4449
+ if (trackPlugins.didRun) {
4450
+ serialized = P_PREFIX + serialized + P_SUFFIX;
4451
+ }
4452
+ scriptBuffer.enqueue(serialized);
4453
+ },
4454
+ scopeId: SCOPE_ID,
4455
+ onDone: () => {
4456
+ scriptBuffer.enqueue(GLOBAL_TSR + ".e()");
4457
+ scriptBuffer.flush();
4458
+ signalSerializationComplete();
4459
+ },
4460
+ onError: (err) => {
4461
+ console.error("Serialization error:", err);
4462
+ signalSerializationComplete();
4463
+ }
4464
+ });
4465
+ },
4466
+ isDehydrated() {
4467
+ return _dehydrated;
4468
+ },
4469
+ isSerializationFinished() {
4470
+ return _serializationFinished;
4471
+ },
4472
+ onRenderFinished: (listener) => renderFinishedListeners.push(listener),
4473
+ onSerializationFinished: (listener) => serializationFinishedListeners.push(listener),
4474
+ setRenderFinished: () => {
4475
+ try {
4476
+ renderFinishedListeners.forEach((l) => l());
4477
+ } catch (err) {
4478
+ console.error("Error in render finished listener:", err);
4479
+ } finally {
4480
+ renderFinishedListeners.length = 0;
4481
+ }
4482
+ scriptBuffer.liftBarrier();
4483
+ },
4484
+ takeBufferedScripts() {
4485
+ const scripts = scriptBuffer.takeAll();
4486
+ const serverBufferedScript = {
4487
+ tag: "script",
4488
+ attrs: {
4489
+ nonce: router.options.ssr?.nonce,
4490
+ className: "$tsr",
4491
+ id: TSR_SCRIPT_BARRIER_ID
4492
+ },
4493
+ children: scripts
4494
+ };
4495
+ return serverBufferedScript;
4496
+ },
4497
+ liftScriptBarrier() {
4498
+ scriptBuffer.liftBarrier();
4499
+ },
4500
+ takeBufferedHtml() {
4501
+ if (!injectedHtmlBuffer) {
4502
+ return void 0;
4503
+ }
4504
+ const buffered = injectedHtmlBuffer;
4505
+ injectedHtmlBuffer = "";
4506
+ return buffered;
4507
+ },
4508
+ cleanup() {
4509
+ if (!router.serverSsr) return;
4510
+ renderFinishedListeners.length = 0;
4511
+ serializationFinishedListeners.length = 0;
4512
+ injectedHtmlBuffer = "";
4513
+ scriptBuffer.cleanup();
4514
+ router.serverSsr = void 0;
4515
+ }
4516
+ };
4517
+ }
4518
+ function getOrigin(request) {
4519
+ try {
4520
+ return new URL(request.url).origin;
4521
+ } catch {
4522
+ }
4523
+ return "http://localhost";
4524
+ }
4525
+ function getNormalizedURL(url, base) {
4526
+ if (typeof url === "string") url = url.replace("\\", "%5C");
4527
+ const rawUrl = new URL(url, base);
4528
+ const { path: decodedPathname, handledProtocolRelativeURL } = decodePath(
4529
+ rawUrl.pathname
4530
+ );
4531
+ const searchParams = new URLSearchParams(rawUrl.search);
4532
+ const normalizedHref = decodedPathname + (searchParams.size > 0 ? "?" : "") + searchParams.toString() + rawUrl.hash;
4533
+ return {
4534
+ url: new URL(normalizedHref, rawUrl.origin),
4535
+ handledProtocolRelativeURL
4536
+ };
4537
+ }
4538
+ function defineHandlerCallback(handler) {
4539
+ return handler;
4540
+ }
4541
+ function transformReadableStreamWithRouter(router, routerStream) {
4542
+ return transformStreamWithRouter(router, routerStream);
4543
+ }
4544
+ function transformPipeableStreamWithRouter(router, routerStream) {
4545
+ return Readable.fromWeb(
4546
+ transformStreamWithRouter(router, Readable.toWeb(routerStream))
4547
+ );
4548
+ }
4549
+ const BODY_END_TAG = "</body>";
4550
+ const HTML_END_TAG = "</html>";
4551
+ const MIN_CLOSING_TAG_LENGTH = 4;
4552
+ const DEFAULT_SERIALIZATION_TIMEOUT_MS = 6e4;
4553
+ const DEFAULT_LIFETIME_TIMEOUT_MS = 6e4;
4554
+ const textEncoder = new TextEncoder();
4555
+ function findLastClosingTagEnd(str) {
4556
+ const len = str.length;
4557
+ if (len < MIN_CLOSING_TAG_LENGTH) return -1;
4558
+ let i = len - 1;
4559
+ while (i >= MIN_CLOSING_TAG_LENGTH - 1) {
4560
+ if (str.charCodeAt(i) === 62) {
4561
+ let j = i - 1;
4562
+ while (j >= 1) {
4563
+ const code = str.charCodeAt(j);
4564
+ if (code >= 97 && code <= 122 || // a-z
4565
+ code >= 65 && code <= 90 || // A-Z
4566
+ code >= 48 && code <= 57 || // 0-9
4567
+ code === 95 || // _
4568
+ code === 58 || // :
4569
+ code === 46 || // .
4570
+ code === 45) {
4571
+ j--;
4572
+ } else {
4573
+ break;
4574
+ }
4575
+ }
4576
+ const tagNameStart = j + 1;
4577
+ if (tagNameStart < i) {
4578
+ const startCode = str.charCodeAt(tagNameStart);
4579
+ if (startCode >= 97 && startCode <= 122 || startCode >= 65 && startCode <= 90) {
4580
+ if (j >= 1 && str.charCodeAt(j) === 47 && str.charCodeAt(j - 1) === 60) {
4581
+ return i + 1;
4582
+ }
4583
+ }
4584
+ }
4585
+ }
4586
+ i--;
4587
+ }
4588
+ return -1;
4589
+ }
4590
+ function transformStreamWithRouter(router, appStream, opts) {
4591
+ const serializationAlreadyFinished = router.serverSsr?.isSerializationFinished() ?? false;
4592
+ const initialBufferedHtml = router.serverSsr?.takeBufferedHtml();
4593
+ if (serializationAlreadyFinished && !initialBufferedHtml) {
4594
+ let cleanedUp2 = false;
4595
+ let controller2;
4596
+ let isStreamClosed2 = false;
4597
+ let lifetimeTimeoutHandle2;
4598
+ const cleanup2 = () => {
4599
+ if (cleanedUp2) return;
4600
+ cleanedUp2 = true;
4601
+ if (lifetimeTimeoutHandle2 !== void 0) {
4602
+ clearTimeout(lifetimeTimeoutHandle2);
4603
+ lifetimeTimeoutHandle2 = void 0;
4604
+ }
4605
+ router.serverSsr?.cleanup();
4606
+ };
4607
+ const safeClose2 = () => {
4608
+ if (isStreamClosed2) return;
4609
+ isStreamClosed2 = true;
4610
+ try {
4611
+ controller2?.close();
4612
+ } catch {
4613
+ }
4614
+ };
4615
+ const safeError2 = (error) => {
4616
+ if (isStreamClosed2) return;
4617
+ isStreamClosed2 = true;
4618
+ try {
4619
+ controller2?.error(error);
4620
+ } catch {
4621
+ }
4622
+ };
4623
+ const lifetimeMs2 = DEFAULT_LIFETIME_TIMEOUT_MS;
4624
+ lifetimeTimeoutHandle2 = setTimeout(() => {
4625
+ if (!cleanedUp2 && !isStreamClosed2) {
4626
+ console.warn(
4627
+ `SSR stream transform exceeded maximum lifetime (${lifetimeMs2}ms), forcing cleanup`
4628
+ );
4629
+ safeError2(new Error("Stream lifetime exceeded"));
4630
+ cleanup2();
4631
+ }
4632
+ }, lifetimeMs2);
4633
+ const stream2 = new ReadableStream$1({
4634
+ start(c) {
4635
+ controller2 = c;
4636
+ },
4637
+ cancel() {
4638
+ isStreamClosed2 = true;
4639
+ cleanup2();
4640
+ }
4641
+ });
4642
+ (async () => {
4643
+ const reader = appStream.getReader();
4644
+ try {
4645
+ while (true) {
4646
+ const { done, value } = await reader.read();
4647
+ if (done) break;
4648
+ if (cleanedUp2 || isStreamClosed2) return;
4649
+ controller2?.enqueue(value);
4650
+ }
4651
+ if (cleanedUp2 || isStreamClosed2) return;
4652
+ router.serverSsr?.setRenderFinished();
4653
+ safeClose2();
4654
+ cleanup2();
4655
+ } catch (error) {
4656
+ if (cleanedUp2) return;
4657
+ console.error("Error reading appStream:", error);
4658
+ router.serverSsr?.setRenderFinished();
4659
+ safeError2(error);
4660
+ cleanup2();
4661
+ } finally {
4662
+ reader.releaseLock();
4663
+ }
4664
+ })().catch((error) => {
4665
+ if (cleanedUp2) return;
4666
+ console.error("Error in stream transform:", error);
4667
+ safeError2(error);
4668
+ cleanup2();
4669
+ });
4670
+ return stream2;
4671
+ }
4672
+ let stopListeningToInjectedHtml;
4673
+ let stopListeningToSerializationFinished;
4674
+ let serializationTimeoutHandle;
4675
+ let lifetimeTimeoutHandle;
4676
+ let cleanedUp = false;
4677
+ let controller;
4678
+ let isStreamClosed = false;
4679
+ const textDecoder = new TextDecoder();
4680
+ let pendingRouterHtml = initialBufferedHtml ?? "";
4681
+ let leftover = "";
4682
+ let pendingClosingTags = "";
4683
+ const MAX_LEFTOVER_CHARS = 2048;
4684
+ let isAppRendering = true;
4685
+ let streamBarrierLifted = false;
4686
+ let serializationFinished = serializationAlreadyFinished;
4687
+ function safeEnqueue(chunk) {
4688
+ if (isStreamClosed) return;
4689
+ if (typeof chunk === "string") {
4690
+ controller.enqueue(textEncoder.encode(chunk));
4691
+ } else {
4692
+ controller.enqueue(chunk);
4693
+ }
4694
+ }
4695
+ function safeClose() {
4696
+ if (isStreamClosed) return;
4697
+ isStreamClosed = true;
4698
+ try {
4699
+ controller.close();
4700
+ } catch {
4701
+ }
4702
+ }
4703
+ function safeError(error) {
4704
+ if (isStreamClosed) return;
4705
+ isStreamClosed = true;
4706
+ try {
4707
+ controller.error(error);
4708
+ } catch {
4709
+ }
4710
+ }
4711
+ function cleanup() {
4712
+ if (cleanedUp) return;
4713
+ cleanedUp = true;
4714
+ try {
4715
+ stopListeningToInjectedHtml?.();
4716
+ stopListeningToSerializationFinished?.();
4717
+ } catch {
4718
+ }
4719
+ stopListeningToInjectedHtml = void 0;
4720
+ stopListeningToSerializationFinished = void 0;
4721
+ if (serializationTimeoutHandle !== void 0) {
4722
+ clearTimeout(serializationTimeoutHandle);
4723
+ serializationTimeoutHandle = void 0;
4724
+ }
4725
+ if (lifetimeTimeoutHandle !== void 0) {
4726
+ clearTimeout(lifetimeTimeoutHandle);
4727
+ lifetimeTimeoutHandle = void 0;
4728
+ }
4729
+ pendingRouterHtml = "";
4730
+ leftover = "";
4731
+ pendingClosingTags = "";
4732
+ router.serverSsr?.cleanup();
4733
+ }
4734
+ const stream = new ReadableStream$1({
4735
+ start(c) {
4736
+ controller = c;
4737
+ },
4738
+ cancel() {
4739
+ isStreamClosed = true;
4740
+ cleanup();
4741
+ }
4742
+ });
4743
+ function flushPendingRouterHtml() {
4744
+ if (!pendingRouterHtml) return;
4745
+ safeEnqueue(pendingRouterHtml);
4746
+ pendingRouterHtml = "";
4747
+ }
4748
+ function appendRouterHtml(html) {
4749
+ if (!html) return;
4750
+ pendingRouterHtml += html;
4751
+ }
4752
+ function tryFinish() {
4753
+ if (isAppRendering || !serializationFinished) return;
4754
+ if (cleanedUp || isStreamClosed) return;
4755
+ if (serializationTimeoutHandle !== void 0) {
4756
+ clearTimeout(serializationTimeoutHandle);
4757
+ serializationTimeoutHandle = void 0;
4758
+ }
4759
+ const decoderRemainder = textDecoder.decode();
4760
+ if (leftover) safeEnqueue(leftover);
4761
+ if (decoderRemainder) safeEnqueue(decoderRemainder);
4762
+ flushPendingRouterHtml();
4763
+ if (pendingClosingTags) safeEnqueue(pendingClosingTags);
4764
+ safeClose();
4765
+ cleanup();
4766
+ }
4767
+ const lifetimeMs = DEFAULT_LIFETIME_TIMEOUT_MS;
4768
+ lifetimeTimeoutHandle = setTimeout(() => {
4769
+ if (!cleanedUp && !isStreamClosed) {
4770
+ console.warn(
4771
+ `SSR stream transform exceeded maximum lifetime (${lifetimeMs}ms), forcing cleanup`
4772
+ );
4773
+ safeError(new Error("Stream lifetime exceeded"));
4774
+ cleanup();
4775
+ }
4776
+ }, lifetimeMs);
4777
+ if (!serializationAlreadyFinished) {
4778
+ stopListeningToInjectedHtml = router.subscribe("onInjectedHtml", () => {
4779
+ if (cleanedUp || isStreamClosed) return;
4780
+ const html = router.serverSsr?.takeBufferedHtml();
4781
+ if (!html) return;
4782
+ if (isAppRendering || leftover || pendingClosingTags) {
4783
+ appendRouterHtml(html);
4784
+ } else {
4785
+ safeEnqueue(html);
4786
+ }
4787
+ });
4788
+ stopListeningToSerializationFinished = router.subscribe(
4789
+ "onSerializationFinished",
4790
+ () => {
4791
+ serializationFinished = true;
4792
+ tryFinish();
4793
+ }
4794
+ );
4795
+ }
4796
+ (async () => {
4797
+ const reader = appStream.getReader();
4798
+ try {
4799
+ while (true) {
4800
+ const { done, value } = await reader.read();
4801
+ if (done) break;
4802
+ if (cleanedUp || isStreamClosed) return;
4803
+ const text = value instanceof Uint8Array ? textDecoder.decode(value, { stream: true }) : String(value);
4804
+ const chunkString = leftover ? leftover + text : text;
4805
+ if (!streamBarrierLifted) {
4806
+ if (chunkString.includes(TSR_SCRIPT_BARRIER_ID)) {
4807
+ streamBarrierLifted = true;
4808
+ router.serverSsr?.liftScriptBarrier();
4809
+ }
4810
+ }
4811
+ if (pendingClosingTags) {
4812
+ pendingClosingTags += chunkString;
4813
+ leftover = "";
4814
+ continue;
4815
+ }
4816
+ const bodyEndIndex = chunkString.indexOf(BODY_END_TAG);
4817
+ const htmlEndIndex = chunkString.indexOf(HTML_END_TAG);
4818
+ if (bodyEndIndex !== -1 && htmlEndIndex !== -1 && bodyEndIndex < htmlEndIndex) {
4819
+ pendingClosingTags = chunkString.slice(bodyEndIndex);
4820
+ safeEnqueue(chunkString.slice(0, bodyEndIndex));
4821
+ flushPendingRouterHtml();
4822
+ leftover = "";
4823
+ continue;
4824
+ }
4825
+ const lastClosingTagEnd = findLastClosingTagEnd(chunkString);
4826
+ if (lastClosingTagEnd > 0) {
4827
+ safeEnqueue(chunkString.slice(0, lastClosingTagEnd));
4828
+ flushPendingRouterHtml();
4829
+ leftover = chunkString.slice(lastClosingTagEnd);
4830
+ if (leftover.length > MAX_LEFTOVER_CHARS) {
4831
+ safeEnqueue(leftover.slice(0, leftover.length - MAX_LEFTOVER_CHARS));
4832
+ leftover = leftover.slice(-MAX_LEFTOVER_CHARS);
4833
+ }
4834
+ } else {
4835
+ const combined = chunkString;
4836
+ if (combined.length > MAX_LEFTOVER_CHARS) {
4837
+ const flushUpto = combined.length - MAX_LEFTOVER_CHARS;
4838
+ safeEnqueue(combined.slice(0, flushUpto));
4839
+ leftover = combined.slice(flushUpto);
4840
+ } else {
4841
+ leftover = combined;
4842
+ }
4843
+ }
4844
+ }
4845
+ if (cleanedUp || isStreamClosed) return;
4846
+ isAppRendering = false;
4847
+ router.serverSsr?.setRenderFinished();
4848
+ if (serializationFinished) {
4849
+ tryFinish();
4850
+ } else {
4851
+ const timeoutMs = opts?.timeoutMs ?? DEFAULT_SERIALIZATION_TIMEOUT_MS;
4852
+ serializationTimeoutHandle = setTimeout(() => {
4853
+ if (!cleanedUp && !isStreamClosed) {
4854
+ console.error("Serialization timeout after app render finished");
4855
+ safeError(
4856
+ new Error("Serialization timeout after app render finished")
4857
+ );
4858
+ cleanup();
4859
+ }
4860
+ }, timeoutMs);
4861
+ }
4862
+ } catch (error) {
4863
+ if (cleanedUp) return;
4864
+ console.error("Error reading appStream:", error);
4865
+ isAppRendering = false;
4866
+ router.serverSsr?.setRenderFinished();
4867
+ safeError(error);
4868
+ cleanup();
4869
+ } finally {
4870
+ reader.releaseLock();
4871
+ }
4872
+ })().catch((error) => {
4873
+ if (cleanedUp) return;
4874
+ console.error("Error in stream transform:", error);
4875
+ safeError(error);
4876
+ cleanup();
4877
+ });
4878
+ return stream;
4879
+ }
4880
+ export {
4881
+ executeRewriteInput as A,
4882
+ BaseRootRoute as B,
4883
+ defaultSerovalPlugins as C,
4884
+ makeSerovalPlugin as D,
4885
+ RouterCore as R,
4886
+ rootRouteId as a,
4887
+ isRedirect as b,
4888
+ transformPipeableStreamWithRouter as c,
4889
+ defaultGetScrollRestorationKey as d,
4890
+ escapeHtml as e,
4891
+ isDangerousProtocol as f,
4892
+ getLocationChangeInfo as g,
4893
+ exactPathTest as h,
4894
+ isNotFound as i,
4895
+ removeTrailingSlash as j,
4896
+ deepEqual as k,
4897
+ functionalUpdate as l,
4898
+ BaseRoute as m,
4899
+ isModuleNotFoundError as n,
4900
+ mergeHeaders as o,
4901
+ parseRedirect as p,
4902
+ getNormalizedURL as q,
4903
+ restoreScroll as r,
4904
+ storageKey as s,
4905
+ transformReadableStreamWithRouter as t,
4906
+ getOrigin as u,
4907
+ attachRouterServerSsrUtils as v,
4908
+ defineHandlerCallback as w,
4909
+ createSerializationAdapter as x,
4910
+ createRawStreamRPCPlugin as y,
4911
+ isResolvedRedirect as z
4912
+ };