@benjavicente/router-core 1.168.9

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 (380) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/bin/intent.js +25 -0
  4. package/dist/cjs/Matches.cjs +17 -0
  5. package/dist/cjs/Matches.cjs.map +1 -0
  6. package/dist/cjs/Matches.d.cts +139 -0
  7. package/dist/cjs/RouterProvider.d.cts +27 -0
  8. package/dist/cjs/config.cjs +11 -0
  9. package/dist/cjs/config.cjs.map +1 -0
  10. package/dist/cjs/config.d.cts +17 -0
  11. package/dist/cjs/defer.cjs +41 -0
  12. package/dist/cjs/defer.cjs.map +1 -0
  13. package/dist/cjs/defer.d.cts +37 -0
  14. package/dist/cjs/fileRoute.d.cts +24 -0
  15. package/dist/cjs/global.d.cts +7 -0
  16. package/dist/cjs/hash-scroll.cjs +20 -0
  17. package/dist/cjs/hash-scroll.cjs.map +1 -0
  18. package/dist/cjs/hash-scroll.d.cts +7 -0
  19. package/dist/cjs/history.d.cts +8 -0
  20. package/dist/cjs/index.cjs +96 -0
  21. package/dist/cjs/index.d.cts +53 -0
  22. package/dist/cjs/invariant.cjs +8 -0
  23. package/dist/cjs/invariant.cjs.map +1 -0
  24. package/dist/cjs/invariant.d.cts +1 -0
  25. package/dist/cjs/isServer/client.cjs +7 -0
  26. package/dist/cjs/isServer/client.cjs.map +1 -0
  27. package/dist/cjs/isServer/client.d.cts +1 -0
  28. package/dist/cjs/isServer/development.cjs +7 -0
  29. package/dist/cjs/isServer/development.cjs.map +1 -0
  30. package/dist/cjs/isServer/development.d.cts +1 -0
  31. package/dist/cjs/isServer/server.cjs +7 -0
  32. package/dist/cjs/isServer/server.cjs.map +1 -0
  33. package/dist/cjs/isServer/server.d.cts +1 -0
  34. package/dist/cjs/link.cjs +6 -0
  35. package/dist/cjs/link.cjs.map +1 -0
  36. package/dist/cjs/link.d.cts +221 -0
  37. package/dist/cjs/load-matches.cjs +659 -0
  38. package/dist/cjs/load-matches.cjs.map +1 -0
  39. package/dist/cjs/load-matches.d.cts +18 -0
  40. package/dist/cjs/location.d.cts +50 -0
  41. package/dist/cjs/lru-cache.cjs +70 -0
  42. package/dist/cjs/lru-cache.cjs.map +1 -0
  43. package/dist/cjs/lru-cache.d.cts +6 -0
  44. package/dist/cjs/manifest.cjs +18 -0
  45. package/dist/cjs/manifest.cjs.map +1 -0
  46. package/dist/cjs/manifest.d.cts +35 -0
  47. package/dist/cjs/new-process-route-tree.cjs +754 -0
  48. package/dist/cjs/new-process-route-tree.cjs.map +1 -0
  49. package/dist/cjs/new-process-route-tree.d.cts +236 -0
  50. package/dist/cjs/not-found.cjs +26 -0
  51. package/dist/cjs/not-found.cjs.map +1 -0
  52. package/dist/cjs/not-found.d.cts +32 -0
  53. package/dist/cjs/path.cjs +252 -0
  54. package/dist/cjs/path.cjs.map +1 -0
  55. package/dist/cjs/path.d.cts +56 -0
  56. package/dist/cjs/qss.cjs +70 -0
  57. package/dist/cjs/qss.cjs.map +1 -0
  58. package/dist/cjs/qss.d.cts +33 -0
  59. package/dist/cjs/redirect.cjs +56 -0
  60. package/dist/cjs/redirect.cjs.map +1 -0
  61. package/dist/cjs/redirect.d.cts +77 -0
  62. package/dist/cjs/rewrite.cjs +68 -0
  63. package/dist/cjs/rewrite.cjs.map +1 -0
  64. package/dist/cjs/rewrite.d.cts +30 -0
  65. package/dist/cjs/root.cjs +7 -0
  66. package/dist/cjs/root.cjs.map +1 -0
  67. package/dist/cjs/root.d.cts +3 -0
  68. package/dist/cjs/route.cjs +100 -0
  69. package/dist/cjs/route.cjs.map +1 -0
  70. package/dist/cjs/route.d.cts +552 -0
  71. package/dist/cjs/routeInfo.d.cts +54 -0
  72. package/dist/cjs/router.cjs +1173 -0
  73. package/dist/cjs/router.cjs.map +1 -0
  74. package/dist/cjs/router.d.cts +734 -0
  75. package/dist/cjs/scroll-restoration-inline.cjs +6 -0
  76. package/dist/cjs/scroll-restoration-inline.cjs.map +1 -0
  77. package/dist/cjs/scroll-restoration-inline.d.cts +6 -0
  78. package/dist/cjs/scroll-restoration-script/client.cjs +9 -0
  79. package/dist/cjs/scroll-restoration-script/client.cjs.map +1 -0
  80. package/dist/cjs/scroll-restoration-script/client.d.cts +2 -0
  81. package/dist/cjs/scroll-restoration-script/server.cjs +30 -0
  82. package/dist/cjs/scroll-restoration-script/server.cjs.map +1 -0
  83. package/dist/cjs/scroll-restoration-script/server.d.cts +2 -0
  84. package/dist/cjs/scroll-restoration.cjs +191 -0
  85. package/dist/cjs/scroll-restoration.cjs.map +1 -0
  86. package/dist/cjs/scroll-restoration.d.cts +38 -0
  87. package/dist/cjs/searchMiddleware.cjs +55 -0
  88. package/dist/cjs/searchMiddleware.cjs.map +1 -0
  89. package/dist/cjs/searchMiddleware.d.cts +25 -0
  90. package/dist/cjs/searchParams.cjs +65 -0
  91. package/dist/cjs/searchParams.cjs.map +1 -0
  92. package/dist/cjs/searchParams.d.cts +31 -0
  93. package/dist/cjs/ssr/client.cjs +7 -0
  94. package/dist/cjs/ssr/client.d.cts +6 -0
  95. package/dist/cjs/ssr/constants.cjs +8 -0
  96. package/dist/cjs/ssr/constants.cjs.map +1 -0
  97. package/dist/cjs/ssr/constants.d.cts +3 -0
  98. package/dist/cjs/ssr/createRequestHandler.cjs +44 -0
  99. package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -0
  100. package/dist/cjs/ssr/createRequestHandler.d.cts +9 -0
  101. package/dist/cjs/ssr/handlerCallback.cjs +8 -0
  102. package/dist/cjs/ssr/handlerCallback.cjs.map +1 -0
  103. package/dist/cjs/ssr/handlerCallback.d.cts +9 -0
  104. package/dist/cjs/ssr/headers.cjs +21 -0
  105. package/dist/cjs/ssr/headers.cjs.map +1 -0
  106. package/dist/cjs/ssr/headers.d.cts +3 -0
  107. package/dist/cjs/ssr/json.cjs +11 -0
  108. package/dist/cjs/ssr/json.cjs.map +1 -0
  109. package/dist/cjs/ssr/json.d.cts +10 -0
  110. package/dist/cjs/ssr/serializer/RawStream.cjs +287 -0
  111. package/dist/cjs/ssr/serializer/RawStream.cjs.map +1 -0
  112. package/dist/cjs/ssr/serializer/RawStream.d.cts +64 -0
  113. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs +32 -0
  114. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.cjs.map +1 -0
  115. package/dist/cjs/ssr/serializer/ShallowErrorPlugin.d.cts +9 -0
  116. package/dist/cjs/ssr/serializer/seroval-plugins.cjs +13 -0
  117. package/dist/cjs/ssr/serializer/seroval-plugins.cjs.map +1 -0
  118. package/dist/cjs/ssr/serializer/seroval-plugins.d.cts +2 -0
  119. package/dist/cjs/ssr/serializer/transformer.cjs +53 -0
  120. package/dist/cjs/ssr/serializer/transformer.cjs.map +1 -0
  121. package/dist/cjs/ssr/serializer/transformer.d.cts +91 -0
  122. package/dist/cjs/ssr/server.cjs +13 -0
  123. package/dist/cjs/ssr/server.d.cts +6 -0
  124. package/dist/cjs/ssr/ssr-client.cjs +183 -0
  125. package/dist/cjs/ssr/ssr-client.cjs.map +1 -0
  126. package/dist/cjs/ssr/ssr-client.d.cts +10 -0
  127. package/dist/cjs/ssr/ssr-match-id.cjs +12 -0
  128. package/dist/cjs/ssr/ssr-match-id.cjs.map +1 -0
  129. package/dist/cjs/ssr/ssr-match-id.d.cts +2 -0
  130. package/dist/cjs/ssr/ssr-server.cjs +279 -0
  131. package/dist/cjs/ssr/ssr-server.cjs.map +1 -0
  132. package/dist/cjs/ssr/ssr-server.d.cts +42 -0
  133. package/dist/cjs/ssr/transformStreamWithRouter.cjs +327 -0
  134. package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -0
  135. package/dist/cjs/ssr/transformStreamWithRouter.d.cts +11 -0
  136. package/dist/cjs/ssr/tsrScript.cjs +6 -0
  137. package/dist/cjs/ssr/tsrScript.cjs.map +1 -0
  138. package/dist/cjs/ssr/tsrScript.d.cts +1 -0
  139. package/dist/cjs/ssr/types.d.cts +30 -0
  140. package/dist/cjs/stores.cjs +148 -0
  141. package/dist/cjs/stores.cjs.map +1 -0
  142. package/dist/cjs/stores.d.cts +70 -0
  143. package/dist/cjs/structuralSharing.d.cts +4 -0
  144. package/dist/cjs/typePrimitives.d.cts +65 -0
  145. package/dist/cjs/useLoaderData.d.cts +5 -0
  146. package/dist/cjs/useLoaderDeps.d.cts +5 -0
  147. package/dist/cjs/useNavigate.d.cts +3 -0
  148. package/dist/cjs/useParams.d.cts +5 -0
  149. package/dist/cjs/useRouteContext.d.cts +9 -0
  150. package/dist/cjs/useSearch.d.cts +5 -0
  151. package/dist/cjs/utils.cjs +339 -0
  152. package/dist/cjs/utils.cjs.map +1 -0
  153. package/dist/cjs/utils.d.cts +178 -0
  154. package/dist/cjs/validators.d.cts +51 -0
  155. package/dist/esm/Matches.d.ts +139 -0
  156. package/dist/esm/Matches.js +17 -0
  157. package/dist/esm/Matches.js.map +1 -0
  158. package/dist/esm/RouterProvider.d.ts +27 -0
  159. package/dist/esm/config.d.ts +17 -0
  160. package/dist/esm/config.js +11 -0
  161. package/dist/esm/config.js.map +1 -0
  162. package/dist/esm/defer.d.ts +37 -0
  163. package/dist/esm/defer.js +40 -0
  164. package/dist/esm/defer.js.map +1 -0
  165. package/dist/esm/fileRoute.d.ts +24 -0
  166. package/dist/esm/global.d.ts +7 -0
  167. package/dist/esm/hash-scroll.d.ts +7 -0
  168. package/dist/esm/hash-scroll.js +20 -0
  169. package/dist/esm/hash-scroll.js.map +1 -0
  170. package/dist/esm/history.d.ts +8 -0
  171. package/dist/esm/index.d.ts +53 -0
  172. package/dist/esm/index.js +24 -0
  173. package/dist/esm/invariant.d.ts +1 -0
  174. package/dist/esm/invariant.js +8 -0
  175. package/dist/esm/invariant.js.map +1 -0
  176. package/dist/esm/isServer/client.d.ts +1 -0
  177. package/dist/esm/isServer/client.js +6 -0
  178. package/dist/esm/isServer/client.js.map +1 -0
  179. package/dist/esm/isServer/development.d.ts +1 -0
  180. package/dist/esm/isServer/development.js +6 -0
  181. package/dist/esm/isServer/development.js.map +1 -0
  182. package/dist/esm/isServer/server.d.ts +1 -0
  183. package/dist/esm/isServer/server.js +6 -0
  184. package/dist/esm/isServer/server.js.map +1 -0
  185. package/dist/esm/link.d.ts +221 -0
  186. package/dist/esm/link.js +6 -0
  187. package/dist/esm/link.js.map +1 -0
  188. package/dist/esm/load-matches.d.ts +18 -0
  189. package/dist/esm/load-matches.js +657 -0
  190. package/dist/esm/load-matches.js.map +1 -0
  191. package/dist/esm/location.d.ts +50 -0
  192. package/dist/esm/lru-cache.d.ts +6 -0
  193. package/dist/esm/lru-cache.js +70 -0
  194. package/dist/esm/lru-cache.js.map +1 -0
  195. package/dist/esm/manifest.d.ts +35 -0
  196. package/dist/esm/manifest.js +17 -0
  197. package/dist/esm/manifest.js.map +1 -0
  198. package/dist/esm/new-process-route-tree.d.ts +236 -0
  199. package/dist/esm/new-process-route-tree.js +749 -0
  200. package/dist/esm/new-process-route-tree.js.map +1 -0
  201. package/dist/esm/not-found.d.ts +32 -0
  202. package/dist/esm/not-found.js +25 -0
  203. package/dist/esm/not-found.js.map +1 -0
  204. package/dist/esm/path.d.ts +56 -0
  205. package/dist/esm/path.js +243 -0
  206. package/dist/esm/path.js.map +1 -0
  207. package/dist/esm/qss.d.ts +33 -0
  208. package/dist/esm/qss.js +69 -0
  209. package/dist/esm/qss.js.map +1 -0
  210. package/dist/esm/redirect.d.ts +77 -0
  211. package/dist/esm/redirect.js +53 -0
  212. package/dist/esm/redirect.js.map +1 -0
  213. package/dist/esm/rewrite.d.ts +30 -0
  214. package/dist/esm/rewrite.js +65 -0
  215. package/dist/esm/rewrite.js.map +1 -0
  216. package/dist/esm/root.d.ts +3 -0
  217. package/dist/esm/root.js +7 -0
  218. package/dist/esm/root.js.map +1 -0
  219. package/dist/esm/route.d.ts +552 -0
  220. package/dist/esm/route.js +98 -0
  221. package/dist/esm/route.js.map +1 -0
  222. package/dist/esm/routeInfo.d.ts +54 -0
  223. package/dist/esm/router.d.ts +734 -0
  224. package/dist/esm/router.js +1165 -0
  225. package/dist/esm/router.js.map +1 -0
  226. package/dist/esm/scroll-restoration-inline.d.ts +6 -0
  227. package/dist/esm/scroll-restoration-inline.js +6 -0
  228. package/dist/esm/scroll-restoration-inline.js.map +1 -0
  229. package/dist/esm/scroll-restoration-script/client.d.ts +2 -0
  230. package/dist/esm/scroll-restoration-script/client.js +8 -0
  231. package/dist/esm/scroll-restoration-script/client.js.map +1 -0
  232. package/dist/esm/scroll-restoration-script/server.d.ts +2 -0
  233. package/dist/esm/scroll-restoration-script/server.js +29 -0
  234. package/dist/esm/scroll-restoration-script/server.js.map +1 -0
  235. package/dist/esm/scroll-restoration.d.ts +38 -0
  236. package/dist/esm/scroll-restoration.js +187 -0
  237. package/dist/esm/scroll-restoration.js.map +1 -0
  238. package/dist/esm/searchMiddleware.d.ts +25 -0
  239. package/dist/esm/searchMiddleware.js +54 -0
  240. package/dist/esm/searchMiddleware.js.map +1 -0
  241. package/dist/esm/searchParams.d.ts +31 -0
  242. package/dist/esm/searchParams.js +62 -0
  243. package/dist/esm/searchParams.js.map +1 -0
  244. package/dist/esm/ssr/client.d.ts +6 -0
  245. package/dist/esm/ssr/client.js +4 -0
  246. package/dist/esm/ssr/constants.d.ts +3 -0
  247. package/dist/esm/ssr/constants.js +7 -0
  248. package/dist/esm/ssr/constants.js.map +1 -0
  249. package/dist/esm/ssr/createRequestHandler.d.ts +9 -0
  250. package/dist/esm/ssr/createRequestHandler.js +44 -0
  251. package/dist/esm/ssr/createRequestHandler.js.map +1 -0
  252. package/dist/esm/ssr/handlerCallback.d.ts +9 -0
  253. package/dist/esm/ssr/handlerCallback.js +8 -0
  254. package/dist/esm/ssr/handlerCallback.js.map +1 -0
  255. package/dist/esm/ssr/headers.d.ts +3 -0
  256. package/dist/esm/ssr/headers.js +21 -0
  257. package/dist/esm/ssr/headers.js.map +1 -0
  258. package/dist/esm/ssr/json.d.ts +10 -0
  259. package/dist/esm/ssr/json.js +11 -0
  260. package/dist/esm/ssr/json.js.map +1 -0
  261. package/dist/esm/ssr/serializer/RawStream.d.ts +64 -0
  262. package/dist/esm/ssr/serializer/RawStream.js +282 -0
  263. package/dist/esm/ssr/serializer/RawStream.js.map +1 -0
  264. package/dist/esm/ssr/serializer/ShallowErrorPlugin.d.ts +9 -0
  265. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js +33 -0
  266. package/dist/esm/ssr/serializer/ShallowErrorPlugin.js.map +1 -0
  267. package/dist/esm/ssr/serializer/seroval-plugins.d.ts +2 -0
  268. package/dist/esm/ssr/serializer/seroval-plugins.js +13 -0
  269. package/dist/esm/ssr/serializer/seroval-plugins.js.map +1 -0
  270. package/dist/esm/ssr/serializer/transformer.d.ts +91 -0
  271. package/dist/esm/ssr/serializer/transformer.js +51 -0
  272. package/dist/esm/ssr/serializer/transformer.js.map +1 -0
  273. package/dist/esm/ssr/server.d.ts +6 -0
  274. package/dist/esm/ssr/server.js +5 -0
  275. package/dist/esm/ssr/ssr-client.d.ts +10 -0
  276. package/dist/esm/ssr/ssr-client.js +183 -0
  277. package/dist/esm/ssr/ssr-client.js.map +1 -0
  278. package/dist/esm/ssr/ssr-match-id.d.ts +2 -0
  279. package/dist/esm/ssr/ssr-match-id.js +11 -0
  280. package/dist/esm/ssr/ssr-match-id.js.map +1 -0
  281. package/dist/esm/ssr/ssr-server.d.ts +42 -0
  282. package/dist/esm/ssr/ssr-server.js +277 -0
  283. package/dist/esm/ssr/ssr-server.js.map +1 -0
  284. package/dist/esm/ssr/transformStreamWithRouter.d.ts +11 -0
  285. package/dist/esm/ssr/transformStreamWithRouter.js +325 -0
  286. package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -0
  287. package/dist/esm/ssr/tsrScript.d.ts +0 -0
  288. package/dist/esm/ssr/tsrScript.js +6 -0
  289. package/dist/esm/ssr/tsrScript.js.map +1 -0
  290. package/dist/esm/ssr/types.d.ts +30 -0
  291. package/dist/esm/stores.d.ts +70 -0
  292. package/dist/esm/stores.js +146 -0
  293. package/dist/esm/stores.js.map +1 -0
  294. package/dist/esm/structuralSharing.d.ts +4 -0
  295. package/dist/esm/typePrimitives.d.ts +65 -0
  296. package/dist/esm/useLoaderData.d.ts +5 -0
  297. package/dist/esm/useLoaderDeps.d.ts +5 -0
  298. package/dist/esm/useNavigate.d.ts +3 -0
  299. package/dist/esm/useParams.d.ts +5 -0
  300. package/dist/esm/useRouteContext.d.ts +9 -0
  301. package/dist/esm/useSearch.d.ts +5 -0
  302. package/dist/esm/utils.d.ts +178 -0
  303. package/dist/esm/utils.js +322 -0
  304. package/dist/esm/utils.js.map +1 -0
  305. package/dist/esm/validators.d.ts +51 -0
  306. package/package.json +200 -0
  307. package/skills/router-core/SKILL.md +139 -0
  308. package/skills/router-core/auth-and-guards/SKILL.md +458 -0
  309. package/skills/router-core/code-splitting/SKILL.md +322 -0
  310. package/skills/router-core/data-loading/SKILL.md +485 -0
  311. package/skills/router-core/navigation/SKILL.md +448 -0
  312. package/skills/router-core/not-found-and-errors/SKILL.md +435 -0
  313. package/skills/router-core/path-params/SKILL.md +382 -0
  314. package/skills/router-core/search-params/SKILL.md +349 -0
  315. package/skills/router-core/search-params/references/validation-patterns.md +379 -0
  316. package/skills/router-core/ssr/SKILL.md +437 -0
  317. package/skills/router-core/type-safety/SKILL.md +497 -0
  318. package/src/Matches.ts +291 -0
  319. package/src/RouterProvider.ts +47 -0
  320. package/src/config.ts +42 -0
  321. package/src/defer.ts +69 -0
  322. package/src/fileRoute.ts +164 -0
  323. package/src/global.ts +9 -0
  324. package/src/hash-scroll.ts +21 -0
  325. package/src/history.ts +9 -0
  326. package/src/index.ts +471 -0
  327. package/src/invariant.ts +3 -0
  328. package/src/isServer/client.ts +1 -0
  329. package/src/isServer/development.ts +2 -0
  330. package/src/isServer/server.ts +1 -0
  331. package/src/link.ts +704 -0
  332. package/src/load-matches.ts +1281 -0
  333. package/src/location.ts +51 -0
  334. package/src/lru-cache.ts +74 -0
  335. package/src/manifest.ts +68 -0
  336. package/src/new-process-route-tree.ts +1387 -0
  337. package/src/not-found.ts +41 -0
  338. package/src/path.ts +436 -0
  339. package/src/qss.ts +81 -0
  340. package/src/redirect.ts +179 -0
  341. package/src/rewrite.ts +93 -0
  342. package/src/root.ts +3 -0
  343. package/src/route.ts +2235 -0
  344. package/src/routeInfo.ts +235 -0
  345. package/src/router.ts +3207 -0
  346. package/src/scroll-restoration-inline.ts +81 -0
  347. package/src/scroll-restoration-script/client.ts +5 -0
  348. package/src/scroll-restoration-script/server.ts +64 -0
  349. package/src/scroll-restoration.ts +357 -0
  350. package/src/searchMiddleware.ts +76 -0
  351. package/src/searchParams.ts +90 -0
  352. package/src/ssr/client.ts +6 -0
  353. package/src/ssr/constants.ts +3 -0
  354. package/src/ssr/createRequestHandler.ts +98 -0
  355. package/src/ssr/handlerCallback.ts +15 -0
  356. package/src/ssr/headers.ts +40 -0
  357. package/src/ssr/json.ts +16 -0
  358. package/src/ssr/serializer/RawStream.ts +464 -0
  359. package/src/ssr/serializer/ShallowErrorPlugin.ts +43 -0
  360. package/src/ssr/serializer/seroval-plugins.ts +12 -0
  361. package/src/ssr/serializer/transformer.ts +312 -0
  362. package/src/ssr/server.ts +14 -0
  363. package/src/ssr/ssr-client.ts +313 -0
  364. package/src/ssr/ssr-match-id.ts +7 -0
  365. package/src/ssr/ssr-server.ts +425 -0
  366. package/src/ssr/transformStreamWithRouter.ts +493 -0
  367. package/src/ssr/tsrScript.ts +20 -0
  368. package/src/ssr/types.ts +41 -0
  369. package/src/stores.ts +342 -0
  370. package/src/structuralSharing.ts +7 -0
  371. package/src/typePrimitives.ts +181 -0
  372. package/src/useLoaderData.ts +20 -0
  373. package/src/useLoaderDeps.ts +13 -0
  374. package/src/useNavigate.ts +13 -0
  375. package/src/useParams.ts +20 -0
  376. package/src/useRouteContext.ts +39 -0
  377. package/src/useSearch.ts +20 -0
  378. package/src/utils.ts +708 -0
  379. package/src/validators.ts +121 -0
  380. package/src/vite-env.d.ts +4 -0
@@ -0,0 +1,312 @@
1
+ import { createPlugin } from 'seroval'
2
+ import { GLOBAL_TSR } from '../constants'
3
+ import type { Plugin, SerovalNode } from 'seroval'
4
+ import type {
5
+ RegisteredConfigType,
6
+ RegisteredSsr,
7
+ SSROption,
8
+ } from '../../router'
9
+ import type { LooseReturnType } from '../../utils'
10
+ import type { AnyRoute, ResolveAllSSR } from '../../route'
11
+ import type { RawStream } from './RawStream'
12
+
13
+ declare const TSR_SERIALIZABLE: unique symbol
14
+ export type TSR_SERIALIZABLE = typeof TSR_SERIALIZABLE
15
+
16
+ export type TsrSerializable = { [TSR_SERIALIZABLE]: true }
17
+ export interface DefaultSerializable {
18
+ number: number
19
+ string: string
20
+ boolean: boolean
21
+ null: null
22
+ undefined: undefined
23
+ bigint: bigint
24
+ Date: Date
25
+ Uint8Array: Uint8Array
26
+ RawStream: RawStream
27
+ TsrSerializable: TsrSerializable
28
+ }
29
+
30
+ export interface SerializableExtensions extends DefaultSerializable {}
31
+
32
+ export type Serializable = SerializableExtensions[keyof SerializableExtensions]
33
+
34
+ export type UnionizeSerializationAdaptersInput<
35
+ TAdapters extends ReadonlyArray<AnySerializationAdapter>,
36
+ > = TAdapters[number]['~types']['input']
37
+
38
+ /**
39
+ * Create a strongly-typed serialization adapter for SSR hydration.
40
+ * Use to register custom types with the router serializer.
41
+ */
42
+ export function createSerializationAdapter<
43
+ TInput = unknown,
44
+ TOutput = unknown,
45
+ const TExtendsAdapters extends
46
+ | ReadonlyArray<AnySerializationAdapter>
47
+ | never = never,
48
+ >(
49
+ opts: CreateSerializationAdapterOptions<TInput, TOutput, TExtendsAdapters>,
50
+ ): SerializationAdapter<TInput, TOutput, TExtendsAdapters> {
51
+ return opts as unknown as SerializationAdapter<
52
+ TInput,
53
+ TOutput,
54
+ TExtendsAdapters
55
+ >
56
+ }
57
+
58
+ export interface CreateSerializationAdapterOptions<
59
+ TInput,
60
+ TOutput,
61
+ TExtendsAdapters extends ReadonlyArray<AnySerializationAdapter> | never,
62
+ > {
63
+ key: string
64
+ extends?: TExtendsAdapters
65
+ test: (value: unknown) => value is TInput
66
+ toSerializable: (
67
+ value: TInput,
68
+ ) => ValidateSerializable<
69
+ TOutput,
70
+ Serializable | UnionizeSerializationAdaptersInput<TExtendsAdapters>
71
+ >
72
+ fromSerializable: (value: TOutput) => TInput
73
+ }
74
+
75
+ export type ValidateSerializable<T, TSerializable> =
76
+ T extends ReadonlyArray<unknown>
77
+ ? ResolveArrayShape<T, TSerializable, 'input'>
78
+ : T extends TSerializable
79
+ ? T
80
+ : T extends (...args: Array<any>) => any
81
+ ? 'Function is not serializable'
82
+ : T extends Promise<any>
83
+ ? ValidateSerializablePromise<T, TSerializable>
84
+ : T extends ReadableStream<any>
85
+ ? ValidateReadableStream<T, TSerializable>
86
+ : T extends Set<any>
87
+ ? ValidateSerializableSet<T, TSerializable>
88
+ : T extends Map<any, any>
89
+ ? ValidateSerializableMap<T, TSerializable>
90
+ : T extends AsyncGenerator<any, any>
91
+ ? ValidateSerializableAsyncGenerator<T, TSerializable>
92
+ : {
93
+ [K in keyof T]: ValidateSerializable<T[K], TSerializable>
94
+ }
95
+
96
+ export type ValidateSerializableAsyncGenerator<T, TSerializable> =
97
+ T extends AsyncGenerator<infer T, infer TReturn, infer TNext>
98
+ ? AsyncGenerator<
99
+ ValidateSerializable<T, TSerializable>,
100
+ ValidateSerializable<TReturn, TSerializable>,
101
+ TNext
102
+ >
103
+ : never
104
+
105
+ export type ValidateSerializablePromise<T, TSerializable> =
106
+ T extends Promise<infer TAwaited>
107
+ ? Promise<ValidateSerializable<TAwaited, TSerializable>>
108
+ : never
109
+
110
+ export type ValidateReadableStream<T, TSerializable> =
111
+ T extends ReadableStream<infer TStreamed>
112
+ ? ReadableStream<ValidateSerializable<TStreamed, TSerializable>>
113
+ : never
114
+
115
+ export type ValidateSerializableSet<T, TSerializable> =
116
+ T extends Set<infer TItem>
117
+ ? Set<ValidateSerializable<TItem, TSerializable>>
118
+ : never
119
+
120
+ export type ValidateSerializableMap<T, TSerializable> =
121
+ T extends Map<infer TKey, infer TValue>
122
+ ? Map<
123
+ ValidateSerializable<TKey, TSerializable>,
124
+ ValidateSerializable<TValue, TSerializable>
125
+ >
126
+ : never
127
+
128
+ export type RegisteredReadableStream =
129
+ unknown extends SerializerExtensions['ReadableStream']
130
+ ? never
131
+ : SerializerExtensions['ReadableStream']
132
+
133
+ export interface DefaultSerializerExtensions {
134
+ ReadableStream: unknown
135
+ }
136
+
137
+ export interface SerializerExtensions extends DefaultSerializerExtensions {}
138
+
139
+ export interface SerializationAdapter<
140
+ TInput,
141
+ TOutput,
142
+ TExtendsAdapters extends ReadonlyArray<AnySerializationAdapter>,
143
+ > {
144
+ '~types': SerializationAdapterTypes<TInput, TOutput, TExtendsAdapters>
145
+ key: string
146
+ extends?: TExtendsAdapters
147
+ test: (value: unknown) => value is TInput
148
+ toSerializable: (value: TInput) => TOutput
149
+ fromSerializable: (value: TOutput) => TInput
150
+ }
151
+
152
+ export interface SerializationAdapterTypes<
153
+ TInput,
154
+ TOutput,
155
+ TExtendsAdapters extends ReadonlyArray<AnySerializationAdapter>,
156
+ > {
157
+ input: TInput | UnionizeSerializationAdaptersInput<TExtendsAdapters>
158
+ output: TOutput
159
+ extends: TExtendsAdapters
160
+ }
161
+
162
+ export type AnySerializationAdapter = SerializationAdapter<any, any, any>
163
+
164
+ /** Create a Seroval plugin for server-side serialization only. */
165
+ export function makeSsrSerovalPlugin(
166
+ serializationAdapter: AnySerializationAdapter,
167
+ options: { didRun: boolean },
168
+ ): Plugin<any, SerovalNode> {
169
+ return createPlugin<any, SerovalNode>({
170
+ tag: '$TSR/t/' + serializationAdapter.key,
171
+ test: serializationAdapter.test,
172
+ parse: {
173
+ stream(value, ctx) {
174
+ return ctx.parse(serializationAdapter.toSerializable(value))
175
+ },
176
+ },
177
+ serialize(node, ctx) {
178
+ options.didRun = true
179
+ return (
180
+ GLOBAL_TSR +
181
+ '.t.get("' +
182
+ serializationAdapter.key +
183
+ '")(' +
184
+ ctx.serialize(node) +
185
+ ')'
186
+ )
187
+ },
188
+ // we never deserialize on the server during SSR
189
+ deserialize: undefined as never,
190
+ })
191
+ }
192
+
193
+ /** Create a Seroval plugin for client/server symmetric (de)serialization. */
194
+ export function makeSerovalPlugin(
195
+ serializationAdapter: AnySerializationAdapter,
196
+ ): Plugin<any, SerovalNode> {
197
+ return createPlugin<any, SerovalNode>({
198
+ tag: '$TSR/t/' + serializationAdapter.key,
199
+ test: serializationAdapter.test,
200
+ parse: {
201
+ sync(value, ctx) {
202
+ return ctx.parse(serializationAdapter.toSerializable(value))
203
+ },
204
+ async async(value, ctx) {
205
+ return await ctx.parse(serializationAdapter.toSerializable(value))
206
+ },
207
+ stream(value, ctx) {
208
+ return ctx.parse(serializationAdapter.toSerializable(value))
209
+ },
210
+ },
211
+ // we don't generate JS code outside of SSR (for now)
212
+ serialize: undefined as never,
213
+ deserialize(node, ctx) {
214
+ return serializationAdapter.fromSerializable(ctx.deserialize(node))
215
+ },
216
+ })
217
+ }
218
+
219
+ export type ValidateSerializableInput<TRegister, T> = ValidateSerializable<
220
+ T,
221
+ RegisteredSerializableInput<TRegister>
222
+ >
223
+
224
+ export type RegisteredSerializableInput<TRegister> =
225
+ | (unknown extends RegisteredSerializationAdapters<TRegister>
226
+ ? never
227
+ : RegisteredSerializationAdapters<TRegister> extends ReadonlyArray<AnySerializationAdapter>
228
+ ? RegisteredSerializationAdapters<TRegister>[number]['~types']['input']
229
+ : never)
230
+ | Serializable
231
+
232
+ export type RegisteredSerializationAdapters<TRegister> = RegisteredConfigType<
233
+ TRegister,
234
+ 'serializationAdapters'
235
+ >
236
+
237
+ export type ValidateSerializableInputResult<TRegister, T> =
238
+ ValidateSerializableResult<T, RegisteredSerializableInput<TRegister>>
239
+
240
+ export type ValidateSerializableResult<T, TSerializable> =
241
+ T extends ReadonlyArray<unknown>
242
+ ? ResolveArrayShape<T, TSerializable, 'result'>
243
+ : T extends TSerializable
244
+ ? T
245
+ : unknown extends SerializerExtensions['ReadableStream']
246
+ ? { [K in keyof T]: ValidateSerializableResult<T[K], TSerializable> }
247
+ : T extends SerializerExtensions['ReadableStream']
248
+ ? ReadableStream
249
+ : { [K in keyof T]: ValidateSerializableResult<T[K], TSerializable> }
250
+
251
+ export type RegisteredSSROption<TRegister> =
252
+ unknown extends RegisteredConfigType<TRegister, 'defaultSsr'>
253
+ ? SSROption
254
+ : RegisteredConfigType<TRegister, 'defaultSsr'>
255
+
256
+ export type ValidateSerializableLifecycleResult<
257
+ TRegister,
258
+ TParentRoute extends AnyRoute,
259
+ TSSR,
260
+ TFn,
261
+ > =
262
+ false extends RegisteredSsr<TRegister>
263
+ ? any
264
+ : ValidateSerializableLifecycleResultSSR<
265
+ TRegister,
266
+ TParentRoute,
267
+ TSSR,
268
+ TFn
269
+ > extends infer TInput
270
+ ? TInput
271
+ : never
272
+
273
+ export type ValidateSerializableLifecycleResultSSR<
274
+ TRegister,
275
+ TParentRoute extends AnyRoute,
276
+ TSSR,
277
+ TFn,
278
+ > =
279
+ ResolveAllSSR<TParentRoute, TSSR> extends false
280
+ ? any
281
+ : RegisteredSSROption<TRegister> extends false
282
+ ? any
283
+ : ValidateSerializableInput<TRegister, LooseReturnType<TFn>>
284
+
285
+ type ResolveArrayShape<
286
+ T extends ReadonlyArray<unknown>,
287
+ TSerializable,
288
+ TMode extends 'input' | 'result',
289
+ > = number extends T['length']
290
+ ? T extends Array<infer U>
291
+ ? Array<ArrayModeResult<TMode, U, TSerializable>>
292
+ : ReadonlyArray<ArrayModeResult<TMode, T[number], TSerializable>>
293
+ : ResolveTupleShape<T, TSerializable, TMode>
294
+
295
+ type ResolveTupleShape<
296
+ T extends ReadonlyArray<unknown>,
297
+ TSerializable,
298
+ TMode extends 'input' | 'result',
299
+ > = T extends readonly [infer THead, ...infer TTail]
300
+ ? readonly [
301
+ ArrayModeResult<TMode, THead, TSerializable>,
302
+ ...ResolveTupleShape<Readonly<TTail>, TSerializable, TMode>,
303
+ ]
304
+ : T
305
+
306
+ type ArrayModeResult<
307
+ TMode extends 'input' | 'result',
308
+ TValue,
309
+ TSerializable,
310
+ > = TMode extends 'input'
311
+ ? ValidateSerializable<TValue, TSerializable>
312
+ : ValidateSerializableResult<TValue, TSerializable>
@@ -0,0 +1,14 @@
1
+ export { createRequestHandler } from './createRequestHandler'
2
+ export type { RequestHandler } from './createRequestHandler'
3
+ export { defineHandlerCallback } from './handlerCallback'
4
+ export type { HandlerCallback } from './handlerCallback'
5
+ export {
6
+ transformPipeableStreamWithRouter,
7
+ transformStreamWithRouter,
8
+ transformReadableStreamWithRouter,
9
+ } from './transformStreamWithRouter'
10
+ export {
11
+ attachRouterServerSsrUtils,
12
+ getNormalizedURL,
13
+ getOrigin,
14
+ } from './ssr-server'
@@ -0,0 +1,313 @@
1
+ import { invariant } from '../invariant'
2
+ import { isNotFound } from '../not-found'
3
+ import { createControlledPromise } from '../utils'
4
+ import { hydrateSsrMatchId } from './ssr-match-id'
5
+ import type { GLOBAL_SEROVAL, GLOBAL_TSR } from './constants'
6
+ import type { DehydratedMatch, TsrSsrGlobal } from './types'
7
+ import type { AnyRouteMatch } from '../Matches'
8
+ import type { AnyRouter } from '../router'
9
+ import type { RouteContextOptions } from '../route'
10
+ import type { AnySerializationAdapter } from './serializer/transformer'
11
+
12
+ declare global {
13
+ interface Window {
14
+ [GLOBAL_TSR]?: TsrSsrGlobal
15
+ [GLOBAL_SEROVAL]?: any
16
+ }
17
+ }
18
+
19
+ function hydrateMatch(
20
+ match: AnyRouteMatch,
21
+ deyhydratedMatch: DehydratedMatch,
22
+ ): void {
23
+ match.id = deyhydratedMatch.i
24
+ match.__beforeLoadContext = deyhydratedMatch.b
25
+ match.loaderData = deyhydratedMatch.l
26
+ match.status = deyhydratedMatch.s
27
+ match.ssr = deyhydratedMatch.ssr
28
+ match.updatedAt = deyhydratedMatch.u
29
+ match.error = deyhydratedMatch.e
30
+ // Only hydrate global-not-found when a defined value is present in the
31
+ // dehydrated payload. If omitted, preserve the value computed from the
32
+ // current client location (important for SPA fallback HTML served at unknown
33
+ // URLs, where dehydrated matches may come from `/` but client matching marks
34
+ // root as globalNotFound).
35
+ if (deyhydratedMatch.g !== undefined) {
36
+ match.globalNotFound = deyhydratedMatch.g
37
+ }
38
+ }
39
+
40
+ export async function hydrate(router: AnyRouter): Promise<any> {
41
+ if (!window.$_TSR) {
42
+ if (process.env.NODE_ENV !== 'production') {
43
+ throw new Error(
44
+ 'Invariant failed: Expected to find bootstrap data on window.$_TSR, but we did not. Please file an issue!',
45
+ )
46
+ }
47
+
48
+ invariant()
49
+ }
50
+
51
+ const serializationAdapters = router.options.serializationAdapters as
52
+ | Array<AnySerializationAdapter>
53
+ | undefined
54
+
55
+ if (serializationAdapters?.length) {
56
+ const fromSerializableMap = new Map()
57
+ serializationAdapters.forEach((adapter) => {
58
+ fromSerializableMap.set(adapter.key, adapter.fromSerializable)
59
+ })
60
+ window.$_TSR.t = fromSerializableMap
61
+ window.$_TSR.buffer.forEach((script) => script())
62
+ }
63
+ window.$_TSR.initialized = true
64
+
65
+ if (!window.$_TSR.router) {
66
+ if (process.env.NODE_ENV !== 'production') {
67
+ throw new Error(
68
+ 'Invariant failed: Expected to find a dehydrated data on window.$_TSR.router, but we did not. Please file an issue!',
69
+ )
70
+ }
71
+
72
+ invariant()
73
+ }
74
+
75
+ const dehydratedRouter = window.$_TSR.router
76
+ dehydratedRouter.matches.forEach((dehydratedMatch) => {
77
+ dehydratedMatch.i = hydrateSsrMatchId(dehydratedMatch.i)
78
+ })
79
+ if (dehydratedRouter.lastMatchId) {
80
+ dehydratedRouter.lastMatchId = hydrateSsrMatchId(
81
+ dehydratedRouter.lastMatchId,
82
+ )
83
+ }
84
+ const { manifest, dehydratedData, lastMatchId } = dehydratedRouter
85
+
86
+ router.ssr = {
87
+ manifest,
88
+ }
89
+ const meta = document.querySelector('meta[property="csp-nonce"]') as
90
+ | HTMLMetaElement
91
+ | undefined
92
+ const nonce = meta?.content
93
+ router.options.ssr = {
94
+ nonce,
95
+ }
96
+
97
+ // Hydrate the router state
98
+ const matches = router.matchRoutes(router.stores.location.state)
99
+
100
+ // kick off loading the route chunks
101
+ const routeChunkPromise = Promise.all(
102
+ matches.map((match) =>
103
+ router.loadRouteChunk(router.looseRoutesById[match.routeId]!),
104
+ ),
105
+ )
106
+
107
+ function setMatchForcePending(match: AnyRouteMatch) {
108
+ // usually the minPendingPromise is created in the Match component if a pending match is rendered
109
+ // however, this might be too late if the match synchronously resolves
110
+ const route = router.looseRoutesById[match.routeId]!
111
+ const pendingMinMs =
112
+ route.options.pendingMinMs ?? router.options.defaultPendingMinMs
113
+ if (pendingMinMs) {
114
+ const minPendingPromise = createControlledPromise<void>()
115
+ match._nonReactive.minPendingPromise = minPendingPromise
116
+ match._forcePending = true
117
+
118
+ setTimeout(() => {
119
+ minPendingPromise.resolve()
120
+ // We've handled the minPendingPromise, so we can delete it
121
+ router.updateMatch(match.id, (prev) => {
122
+ prev._nonReactive.minPendingPromise = undefined
123
+ return {
124
+ ...prev,
125
+ _forcePending: undefined,
126
+ }
127
+ })
128
+ }, pendingMinMs)
129
+ }
130
+ }
131
+
132
+ function setRouteSsr(match: AnyRouteMatch) {
133
+ const route = router.looseRoutesById[match.routeId]
134
+ if (route) {
135
+ route.options.ssr = match.ssr
136
+ }
137
+ }
138
+ // Right after hydration and before the first render, we need to rehydrate each match
139
+ // First step is to reyhdrate loaderData and __beforeLoadContext
140
+ let firstNonSsrMatchIndex: number | undefined = undefined
141
+ matches.forEach((match) => {
142
+ const dehydratedMatch = dehydratedRouter.matches.find(
143
+ (d) => d.i === match.id,
144
+ )
145
+ if (!dehydratedMatch) {
146
+ match._nonReactive.dehydrated = false
147
+ match.ssr = false
148
+ setRouteSsr(match)
149
+ return
150
+ }
151
+
152
+ hydrateMatch(match, dehydratedMatch)
153
+ setRouteSsr(match)
154
+
155
+ match._nonReactive.dehydrated = match.ssr !== false
156
+
157
+ if (match.ssr === 'data-only' || match.ssr === false) {
158
+ if (firstNonSsrMatchIndex === undefined) {
159
+ firstNonSsrMatchIndex = match.index
160
+ setMatchForcePending(match)
161
+ }
162
+ }
163
+ })
164
+
165
+ router.stores.setActiveMatches(matches)
166
+
167
+ // Allow the user to handle custom hydration data
168
+ await router.options.hydrate?.(dehydratedData)
169
+
170
+ // now that all necessary data is hydrated:
171
+ // 1) fully reconstruct the route context
172
+ // 2) execute `head()` and `scripts()` for each match
173
+ const activeMatches = router.stores.activeMatchesSnapshot.state
174
+ const location = router.stores.location.state
175
+ await Promise.all(
176
+ activeMatches.map(async (match) => {
177
+ try {
178
+ const route = router.looseRoutesById[match.routeId]!
179
+
180
+ const parentMatch = activeMatches[match.index - 1]
181
+ const parentContext = parentMatch?.context ?? router.options.context
182
+
183
+ // `context()` was already executed by `matchRoutes`, however route context was not yet fully reconstructed
184
+ // so run it again and merge route context
185
+ if (route.options.context) {
186
+ const contextFnContext: RouteContextOptions<any, any, any, any, any> =
187
+ {
188
+ deps: match.loaderDeps,
189
+ params: match.params,
190
+ context: parentContext ?? {},
191
+ location,
192
+ navigate: (opts: any) =>
193
+ router.navigate({
194
+ ...opts,
195
+ _fromLocation: location,
196
+ }),
197
+ buildLocation: router.buildLocation,
198
+ cause: match.cause,
199
+ abortController: match.abortController,
200
+ preload: false,
201
+ matches,
202
+ routeId: route.id,
203
+ }
204
+ match.__routeContext =
205
+ route.options.context(contextFnContext) ?? undefined
206
+ }
207
+
208
+ match.context = {
209
+ ...parentContext,
210
+ ...match.__routeContext,
211
+ ...match.__beforeLoadContext,
212
+ }
213
+
214
+ const assetContext = {
215
+ ssr: router.options.ssr,
216
+ matches: activeMatches,
217
+ match,
218
+ params: match.params,
219
+ loaderData: match.loaderData,
220
+ }
221
+ const headFnContent = await route.options.head?.(assetContext)
222
+
223
+ const scripts = await route.options.scripts?.(assetContext)
224
+
225
+ match.meta = headFnContent?.meta
226
+ match.links = headFnContent?.links
227
+ match.headScripts = headFnContent?.scripts
228
+ match.styles = headFnContent?.styles
229
+ match.scripts = scripts
230
+ } catch (err) {
231
+ if (isNotFound(err)) {
232
+ match.error = { isNotFound: true }
233
+ console.error(
234
+ `NotFound error during hydration for routeId: ${match.routeId}`,
235
+ err,
236
+ )
237
+ } else {
238
+ match.error = err as any
239
+ console.error(
240
+ `Error during hydration for route ${match.routeId}:`,
241
+ err,
242
+ )
243
+ throw err
244
+ }
245
+ }
246
+ }),
247
+ )
248
+
249
+ const isSpaMode = matches[matches.length - 1]!.id !== lastMatchId
250
+ const hasSsrFalseMatches = matches.some((m) => m.ssr === false)
251
+ // all matches have data from the server and we are not in SPA mode so we don't need to kick of router.load()
252
+ if (!hasSsrFalseMatches && !isSpaMode) {
253
+ matches.forEach((match) => {
254
+ // remove the dehydrated flag since we won't run router.load() which would remove it
255
+ match._nonReactive.dehydrated = undefined
256
+ })
257
+ // Mark the current location as resolved so that later load cycles
258
+ // (e.g. preloads, invalidations) don't mistakenly detect a href change
259
+ // (resolvedLocation defaults to undefined and router.load() is skipped
260
+ // in the normal SSR hydration path).
261
+ router.stores.resolvedLocation.setState(() => router.stores.location.state)
262
+ return routeChunkPromise
263
+ }
264
+
265
+ // schedule router.load() to run after the next tick so we can store the promise in the match before loading starts
266
+ const loadPromise = Promise.resolve()
267
+ .then(() => router.load())
268
+ .catch((err) => {
269
+ console.error('Error during router hydration:', err)
270
+ })
271
+
272
+ // in SPA mode we need to keep the first match below the root route pending until router.load() is finished
273
+ // this will prevent that other pending components are rendered but hydration is not blocked
274
+ if (isSpaMode) {
275
+ const match = matches[1]
276
+ if (!match) {
277
+ if (process.env.NODE_ENV !== 'production') {
278
+ throw new Error(
279
+ 'Invariant failed: Expected to find a match below the root match in SPA mode.',
280
+ )
281
+ }
282
+
283
+ invariant()
284
+ }
285
+ setMatchForcePending(match)
286
+
287
+ match._displayPending = true
288
+ match._nonReactive.displayPendingPromise = loadPromise
289
+
290
+ loadPromise.then(() => {
291
+ router.batch(() => {
292
+ // ensure router is not in status 'pending' anymore
293
+ // this usually happens in Transitioner but if loading synchronously resolves,
294
+ // Transitioner won't be rendered while loading so it cannot track the change from loading:true to loading:false
295
+ if (router.stores.status.state === 'pending') {
296
+ router.batch(() => {
297
+ router.stores.status.setState(() => 'idle')
298
+ router.stores.resolvedLocation.setState(
299
+ () => router.stores.location.state,
300
+ )
301
+ })
302
+ }
303
+ // hide the pending component once the load is finished
304
+ router.updateMatch(match.id, (prev) => ({
305
+ ...prev,
306
+ _displayPending: undefined,
307
+ displayPendingPromise: undefined,
308
+ }))
309
+ })
310
+ })
311
+ }
312
+ return routeChunkPromise
313
+ }
@@ -0,0 +1,7 @@
1
+ export function dehydrateSsrMatchId(id: string): string {
2
+ return id.replaceAll('/', '\0')
3
+ }
4
+
5
+ export function hydrateSsrMatchId(id: string): string {
6
+ return id.replaceAll('\0', '/').replaceAll('\uFFFD', '/')
7
+ }