convex-cms 0.0.2 → 0.0.3

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