@rangojs/router 0.0.0-experimental.b9cb8739 → 0.0.0-experimental.bdaf10aa

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 (449) hide show
  1. package/AGENTS.md +8 -4
  2. package/README.md +303 -741
  3. package/dist/bin/rango.js +730 -184
  4. package/dist/testing/vitest.js +82 -0
  5. package/dist/vite/index.js +4344 -1335
  6. package/dist/vite/index.js.bak +5448 -0
  7. package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  8. package/package.json +86 -15
  9. package/skills/api-client/SKILL.md +211 -0
  10. package/skills/breadcrumbs/SKILL.md +85 -6
  11. package/skills/bundle-analysis/SKILL.md +159 -0
  12. package/skills/cache-guide/SKILL.md +251 -24
  13. package/skills/caching/SKILL.md +375 -17
  14. package/skills/catalog.json +271 -0
  15. package/skills/comparison/SKILL.md +50 -0
  16. package/skills/comparison/agents/openai.yaml +4 -0
  17. package/skills/comparison/references/framework-comparison.md +837 -0
  18. package/skills/composability/SKILL.md +110 -4
  19. package/skills/css/SKILL.md +76 -0
  20. package/skills/debug-manifest/SKILL.md +5 -3
  21. package/skills/defer-hydration/SKILL.md +235 -0
  22. package/skills/document-cache/SKILL.md +87 -56
  23. package/skills/fonts/SKILL.md +1 -1
  24. package/skills/handler-use/SKILL.md +364 -0
  25. package/skills/hooks/SKILL.md +73 -691
  26. package/skills/hooks/data.md +273 -0
  27. package/skills/hooks/handle-and-actions.md +103 -0
  28. package/skills/hooks/navigation.md +110 -0
  29. package/skills/hooks/outlets.md +41 -0
  30. package/skills/hooks/state.md +228 -0
  31. package/skills/hooks/urls.md +135 -0
  32. package/skills/host-router/SKILL.md +129 -27
  33. package/skills/i18n/SKILL.md +276 -0
  34. package/skills/intercept/SKILL.md +94 -18
  35. package/skills/layout/SKILL.md +62 -19
  36. package/skills/links/SKILL.md +249 -17
  37. package/skills/loader/SKILL.md +302 -54
  38. package/skills/middleware/SKILL.md +59 -16
  39. package/skills/migrate-nextjs/SKILL.md +745 -0
  40. package/skills/migrate-react-router/SKILL.md +153 -0
  41. package/skills/migrate-react-router/cloudflare-workers.md +129 -0
  42. package/skills/migrate-react-router/component-migration.md +196 -0
  43. package/skills/migrate-react-router/data-and-actions.md +225 -0
  44. package/skills/migrate-react-router/route-mapping.md +271 -0
  45. package/skills/mime-routes/SKILL.md +29 -2
  46. package/skills/observability/SKILL.md +202 -0
  47. package/skills/parallel/SKILL.md +225 -10
  48. package/skills/ppr/SKILL.md +622 -0
  49. package/skills/prerender/SKILL.md +178 -124
  50. package/skills/rango/SKILL.md +318 -24
  51. package/skills/react-compiler/SKILL.md +168 -0
  52. package/skills/response-routes/SKILL.md +138 -49
  53. package/skills/route/SKILL.md +172 -9
  54. package/skills/router-setup/SKILL.md +131 -11
  55. package/skills/scripts/SKILL.md +179 -0
  56. package/skills/server-actions/SKILL.md +776 -0
  57. package/skills/shell-manifest/SKILL.md +185 -0
  58. package/skills/streams-and-websockets/SKILL.md +283 -0
  59. package/skills/tailwind/SKILL.md +28 -4
  60. package/skills/testing/SKILL.md +130 -0
  61. package/skills/testing/bindings.md +103 -0
  62. package/skills/testing/cache-prerender.md +127 -0
  63. package/skills/testing/client-components.md +124 -0
  64. package/skills/testing/e2e-parity.md +125 -0
  65. package/skills/testing/flight.md +91 -0
  66. package/skills/testing/handles.md +131 -0
  67. package/skills/testing/loader.md +128 -0
  68. package/skills/testing/middleware.md +99 -0
  69. package/skills/testing/render-handler.md +122 -0
  70. package/skills/testing/response-routes.md +95 -0
  71. package/skills/testing/reverse-and-types.md +85 -0
  72. package/skills/testing/server-actions.md +107 -0
  73. package/skills/testing/server-tree.md +128 -0
  74. package/skills/testing/setup.md +123 -0
  75. package/skills/theme/SKILL.md +1 -1
  76. package/skills/typesafety/SKILL.md +45 -616
  77. package/skills/typesafety/env-and-bindings.md +254 -0
  78. package/skills/typesafety/generated-files-and-cli.md +335 -0
  79. package/skills/typesafety/params-and-search.md +153 -0
  80. package/skills/typesafety/route-types.md +209 -0
  81. package/skills/use-cache/SKILL.md +74 -15
  82. package/skills/vercel/SKILL.md +128 -0
  83. package/skills/view-transitions/SKILL.md +337 -0
  84. package/src/__augment-tests__/augment.ts +81 -0
  85. package/src/__augment-tests__/augmented.check.ts +116 -0
  86. package/src/__internal.ts +1 -66
  87. package/src/browser/action-coordinator.ts +53 -36
  88. package/src/browser/action-fence.ts +47 -0
  89. package/src/browser/app-shell.ts +39 -0
  90. package/src/browser/app-version.ts +14 -0
  91. package/src/browser/connection-warmup.ts +134 -0
  92. package/src/browser/cookie-name.ts +140 -0
  93. package/src/browser/event-controller.ts +257 -158
  94. package/src/browser/history-state.ts +21 -0
  95. package/src/browser/index.ts +3 -3
  96. package/src/browser/invalidate-client-cache.ts +52 -0
  97. package/src/browser/logging.ts +28 -0
  98. package/src/browser/merge-segment-loaders.ts +6 -4
  99. package/src/browser/navigation-bridge.ts +132 -33
  100. package/src/browser/navigation-client.ts +218 -68
  101. package/src/browser/navigation-store-handle.ts +38 -0
  102. package/src/browser/navigation-store.ts +203 -80
  103. package/src/browser/navigation-transaction.ts +18 -66
  104. package/src/browser/network-error-handler.ts +34 -7
  105. package/src/browser/partial-update.ts +241 -127
  106. package/src/browser/prefetch/cache.ts +271 -44
  107. package/src/browser/prefetch/fetch.ts +367 -40
  108. package/src/browser/prefetch/queue.ts +144 -23
  109. package/src/browser/prefetch/resource-ready.ts +77 -0
  110. package/src/browser/rango-state.ts +158 -76
  111. package/src/browser/react/Link.tsx +121 -16
  112. package/src/browser/react/NavigationProvider.tsx +240 -122
  113. package/src/browser/react/ScrollRestoration.tsx +10 -6
  114. package/src/browser/react/context.ts +7 -2
  115. package/src/browser/react/filter-segment-order.ts +66 -7
  116. package/src/browser/react/index.ts +0 -48
  117. package/src/browser/react/location-state-shared.ts +178 -8
  118. package/src/browser/react/location-state.ts +39 -14
  119. package/src/browser/react/use-action.ts +6 -15
  120. package/src/browser/react/use-handle.ts +23 -69
  121. package/src/browser/react/use-href.tsx +8 -1
  122. package/src/browser/react/use-link-status.ts +33 -8
  123. package/src/browser/react/use-navigation.ts +32 -7
  124. package/src/browser/react/use-params.ts +20 -10
  125. package/src/browser/react/use-reverse.ts +106 -0
  126. package/src/browser/react/use-router.ts +46 -11
  127. package/src/browser/react/use-search-params.ts +0 -5
  128. package/src/browser/react/use-segments.ts +11 -21
  129. package/src/browser/response-adapter.ts +99 -8
  130. package/src/browser/rsc-router.tsx +272 -80
  131. package/src/browser/scroll-restoration.ts +56 -22
  132. package/src/browser/segment-reconciler.ts +44 -7
  133. package/src/browser/segment-structure-assert.ts +2 -2
  134. package/src/browser/server-action-bridge.ts +244 -71
  135. package/src/browser/types.ts +136 -12
  136. package/src/browser/validate-redirect-origin.ts +43 -16
  137. package/src/build/collect-fallback-refs.ts +107 -0
  138. package/src/build/generate-manifest.ts +207 -158
  139. package/src/build/generate-route-types.ts +6 -1
  140. package/src/build/index.ts +11 -3
  141. package/src/build/prefix-tree-utils.ts +123 -0
  142. package/src/build/route-trie.ts +198 -41
  143. package/src/build/route-types/ast-route-extraction.ts +15 -8
  144. package/src/build/route-types/codegen.ts +16 -5
  145. package/src/build/route-types/include-resolution.ts +464 -63
  146. package/src/build/route-types/param-extraction.ts +6 -3
  147. package/src/build/route-types/per-module-writer.ts +22 -6
  148. package/src/build/route-types/router-processing.ts +336 -110
  149. package/src/build/route-types/scan-filter.ts +9 -2
  150. package/src/build/route-types/source-scan.ts +216 -0
  151. package/src/build/runtime-discovery.ts +13 -21
  152. package/src/cache/cache-error.ts +104 -0
  153. package/src/cache/cache-key-utils.ts +58 -13
  154. package/src/cache/cache-policy.ts +108 -34
  155. package/src/cache/cache-runtime.ts +454 -97
  156. package/src/cache/cache-scope.ts +235 -103
  157. package/src/cache/cache-tag.ts +149 -0
  158. package/src/cache/cf/cf-base64.ts +33 -0
  159. package/src/cache/cf/cf-cache-constants.ts +127 -0
  160. package/src/cache/cf/cf-cache-store.ts +2446 -170
  161. package/src/cache/cf/cf-cache-types.ts +349 -0
  162. package/src/cache/cf/cf-kv-utils.ts +46 -0
  163. package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
  164. package/src/cache/cf/index.ts +11 -17
  165. package/src/cache/document-cache.ts +144 -49
  166. package/src/cache/handle-snapshot.ts +70 -0
  167. package/src/cache/index.ts +24 -20
  168. package/src/cache/memory-segment-store.ts +243 -37
  169. package/src/cache/profile-registry.ts +46 -31
  170. package/src/cache/read-through-swr.ts +56 -12
  171. package/src/cache/segment-codec.ts +13 -21
  172. package/src/cache/shell-snapshot.ts +417 -0
  173. package/src/cache/tag-invalidation.ts +230 -0
  174. package/src/cache/taint.ts +55 -0
  175. package/src/cache/types.ts +194 -99
  176. package/src/cache/vercel/index.ts +11 -0
  177. package/src/cache/vercel/vercel-cache-store.ts +1132 -0
  178. package/src/client.rsc.tsx +41 -21
  179. package/src/client.tsx +116 -290
  180. package/src/cloudflare/index.ts +11 -0
  181. package/src/cloudflare/tracing.ts +108 -0
  182. package/src/component-utils.ts +19 -0
  183. package/src/components/DefaultDocument.tsx +8 -2
  184. package/src/context-var.ts +84 -2
  185. package/src/debug.ts +2 -2
  186. package/src/decode-loader-results.ts +52 -0
  187. package/src/defer.ts +185 -0
  188. package/src/deps/ssr.ts +0 -1
  189. package/src/encode-kv.ts +49 -0
  190. package/src/errors.ts +30 -4
  191. package/src/escape-script.ts +52 -0
  192. package/src/handle.ts +104 -34
  193. package/src/handles/MetaTags.tsx +24 -53
  194. package/src/handles/Scripts.tsx +183 -0
  195. package/src/handles/breadcrumbs.ts +35 -8
  196. package/src/handles/deferred-resolution.ts +127 -0
  197. package/src/handles/is-thenable.ts +18 -0
  198. package/src/handles/meta.ts +14 -40
  199. package/src/handles/script.ts +244 -0
  200. package/src/host/cookie-handler.ts +9 -60
  201. package/src/host/errors.ts +13 -22
  202. package/src/host/index.ts +9 -2
  203. package/src/host/pattern-matcher.ts +23 -52
  204. package/src/host/router.ts +107 -99
  205. package/src/host/testing.ts +40 -27
  206. package/src/host/types.ts +37 -4
  207. package/src/host/utils.ts +1 -1
  208. package/src/href-client.ts +137 -22
  209. package/src/index.rsc.ts +100 -13
  210. package/src/index.ts +143 -19
  211. package/src/internal-debug.ts +11 -10
  212. package/src/loader-store.ts +500 -0
  213. package/src/loader.rsc.ts +20 -13
  214. package/src/loader.ts +12 -11
  215. package/src/missing-id-error.ts +68 -0
  216. package/src/outlet-context.ts +1 -1
  217. package/src/outlet-provider.tsx +1 -5
  218. package/src/prerender/param-hash.ts +16 -16
  219. package/src/prerender/store.ts +37 -41
  220. package/src/prerender.ts +215 -86
  221. package/src/redirect-origin.ts +114 -0
  222. package/src/regex-escape.ts +8 -0
  223. package/src/render-error-thrower.tsx +20 -0
  224. package/src/response-utils.ts +62 -0
  225. package/src/reverse.ts +65 -15
  226. package/src/root-error-boundary.tsx +1 -19
  227. package/src/route-content-wrapper.tsx +19 -77
  228. package/src/route-definition/dsl-helpers.ts +485 -303
  229. package/src/route-definition/helper-factories.ts +28 -140
  230. package/src/route-definition/helpers-types.ts +153 -77
  231. package/src/route-definition/index.ts +4 -2
  232. package/src/route-definition/redirect.ts +53 -12
  233. package/src/route-definition/resolve-handler-use.ts +160 -0
  234. package/src/route-definition/use-item-types.ts +29 -0
  235. package/src/route-map-builder.ts +48 -21
  236. package/src/route-types.ts +37 -46
  237. package/src/router/basename.ts +14 -0
  238. package/src/router/content-negotiation.ts +164 -17
  239. package/src/router/error-handling.ts +45 -18
  240. package/src/router/find-match.ts +130 -29
  241. package/src/router/handler-context.ts +83 -39
  242. package/src/router/instrument.ts +355 -0
  243. package/src/router/intercept-resolution.ts +50 -24
  244. package/src/router/lazy-includes.ts +89 -63
  245. package/src/router/loader-resolution.ts +286 -56
  246. package/src/router/logging.ts +5 -8
  247. package/src/router/manifest.ts +105 -56
  248. package/src/router/match-api.ts +178 -218
  249. package/src/router/match-context.ts +0 -22
  250. package/src/router/match-handlers.ts +211 -165
  251. package/src/router/match-middleware/background-revalidation.ts +66 -22
  252. package/src/router/match-middleware/cache-lookup.ts +214 -263
  253. package/src/router/match-middleware/cache-store.ts +105 -50
  254. package/src/router/match-middleware/intercept-resolution.ts +8 -28
  255. package/src/router/match-middleware/segment-resolution.ts +52 -18
  256. package/src/router/match-pipelines.ts +1 -42
  257. package/src/router/match-result.ts +128 -44
  258. package/src/router/metrics.ts +5 -34
  259. package/src/router/middleware-types.ts +13 -142
  260. package/src/router/middleware.ts +301 -177
  261. package/src/router/navigation-snapshot.ts +133 -0
  262. package/src/router/params-util.ts +23 -0
  263. package/src/router/parse-pattern.ts +115 -0
  264. package/src/router/pattern-matching.ts +181 -150
  265. package/src/router/prefetch-cache-ttl.ts +51 -0
  266. package/src/router/prefetch-limits.ts +37 -0
  267. package/src/router/prerender-match.ts +203 -58
  268. package/src/router/preview-match.ts +35 -103
  269. package/src/router/request-classification.ts +291 -0
  270. package/src/router/revalidation.ts +123 -73
  271. package/src/router/route-snapshot.ts +256 -0
  272. package/src/router/router-context.ts +11 -29
  273. package/src/router/router-interfaces.ts +146 -35
  274. package/src/router/router-options.ts +202 -15
  275. package/src/router/router-registry.ts +2 -5
  276. package/src/router/segment-resolution/fresh.ts +301 -78
  277. package/src/router/segment-resolution/helpers.ts +115 -30
  278. package/src/router/segment-resolution/loader-cache.ts +156 -39
  279. package/src/router/segment-resolution/loader-mask.ts +60 -0
  280. package/src/router/segment-resolution/loader-snapshot.ts +259 -0
  281. package/src/router/segment-resolution/mask-nested.ts +83 -0
  282. package/src/router/segment-resolution/revalidation.ts +477 -385
  283. package/src/router/segment-resolution/static-store.ts +19 -5
  284. package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
  285. package/src/router/segment-resolution/view-transition-default.ts +56 -0
  286. package/src/router/segment-resolution.ts +5 -1
  287. package/src/router/segment-wrappers.ts +8 -5
  288. package/src/router/state-cookie-name.ts +33 -0
  289. package/src/router/substitute-pattern-params.ts +75 -0
  290. package/src/router/telemetry-otel.ts +160 -200
  291. package/src/router/telemetry.ts +105 -20
  292. package/src/router/timeout.ts +0 -20
  293. package/src/router/tracing.ts +215 -0
  294. package/src/router/trie-matching.ts +171 -59
  295. package/src/router/types.ts +10 -63
  296. package/src/router/url-params.ts +57 -0
  297. package/src/router.ts +210 -71
  298. package/src/rsc/full-payload.ts +70 -0
  299. package/src/rsc/handler-context.ts +3 -2
  300. package/src/rsc/handler.ts +682 -508
  301. package/src/rsc/helpers.ts +168 -46
  302. package/src/rsc/index.ts +2 -5
  303. package/src/rsc/json-route-result.ts +38 -0
  304. package/src/rsc/loader-fetch.ts +127 -31
  305. package/src/rsc/manifest-init.ts +33 -42
  306. package/src/rsc/nonce.ts +10 -1
  307. package/src/rsc/origin-guard.ts +39 -25
  308. package/src/rsc/progressive-enhancement.ts +138 -15
  309. package/src/rsc/redirect-guard.ts +100 -0
  310. package/src/rsc/response-cache-serve.ts +238 -0
  311. package/src/rsc/response-error.ts +79 -12
  312. package/src/rsc/response-route-handler.ts +99 -189
  313. package/src/rsc/rsc-rendering.ts +509 -73
  314. package/src/rsc/runtime-warnings.ts +23 -10
  315. package/src/rsc/server-action.ts +287 -113
  316. package/src/rsc/shell-capture.ts +1190 -0
  317. package/src/rsc/shell-serve.ts +181 -0
  318. package/src/rsc/ssr-setup.ts +18 -2
  319. package/src/rsc/transition-gate.ts +89 -0
  320. package/src/rsc/types.ts +62 -6
  321. package/src/runtime-env.ts +18 -0
  322. package/src/search-params.ts +35 -30
  323. package/src/segment-content-promise.ts +67 -0
  324. package/src/segment-loader-promise.ts +167 -0
  325. package/src/segment-system.tsx +449 -132
  326. package/src/serialize.ts +243 -0
  327. package/src/server/context.ts +367 -61
  328. package/src/server/cookie-parse.ts +32 -0
  329. package/src/server/cookie-store.ts +152 -5
  330. package/src/server/handle-store.ts +40 -38
  331. package/src/server/loader-registry.ts +38 -46
  332. package/src/server/request-context.ts +558 -173
  333. package/src/ssr/index.tsx +491 -174
  334. package/src/ssr/inject-rsc-eager.ts +167 -0
  335. package/src/ssr/ssr-root.tsx +228 -0
  336. package/src/static-handler.ts +27 -18
  337. package/src/testing/cache-status.ts +162 -0
  338. package/src/testing/collect-handle.ts +46 -0
  339. package/src/testing/dispatch.ts +813 -0
  340. package/src/testing/dom.entry.ts +22 -0
  341. package/src/testing/e2e/fixture.ts +188 -0
  342. package/src/testing/e2e/index.ts +128 -0
  343. package/src/testing/e2e/matchers.ts +35 -0
  344. package/src/testing/e2e/page-helpers.ts +272 -0
  345. package/src/testing/e2e/parity.ts +387 -0
  346. package/src/testing/e2e/server.ts +195 -0
  347. package/src/testing/flight-matchers.ts +97 -0
  348. package/src/testing/flight-normalize.ts +11 -0
  349. package/src/testing/flight-runtime.d.ts +57 -0
  350. package/src/testing/flight-tree.ts +682 -0
  351. package/src/testing/flight.entry.ts +52 -0
  352. package/src/testing/flight.ts +257 -0
  353. package/src/testing/generated-routes.ts +199 -0
  354. package/src/testing/index.ts +105 -0
  355. package/src/testing/internal/context.ts +371 -0
  356. package/src/testing/internal/flight-client-globals.ts +30 -0
  357. package/src/testing/internal/seed-vars.ts +54 -0
  358. package/src/testing/render-handler.ts +357 -0
  359. package/src/testing/render-route.tsx +584 -0
  360. package/src/testing/run-loader.ts +385 -0
  361. package/src/testing/run-middleware.ts +205 -0
  362. package/src/testing/run-transition-when.ts +164 -0
  363. package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
  364. package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
  365. package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
  366. package/src/testing/vitest-stubs/version.ts +5 -0
  367. package/src/testing/vitest.ts +305 -0
  368. package/src/theme/ThemeProvider.tsx +56 -84
  369. package/src/theme/ThemeScript.tsx +7 -9
  370. package/src/theme/constants.ts +52 -13
  371. package/src/theme/index.ts +0 -7
  372. package/src/theme/theme-context.ts +1 -5
  373. package/src/theme/theme-script.ts +22 -21
  374. package/src/theme/use-theme.ts +0 -3
  375. package/src/types/boundaries.ts +0 -35
  376. package/src/types/cache-types.ts +17 -8
  377. package/src/types/error-types.ts +30 -90
  378. package/src/types/global-namespace.ts +54 -41
  379. package/src/types/handler-context.ts +234 -82
  380. package/src/types/index.ts +3 -10
  381. package/src/types/loader-types.ts +44 -15
  382. package/src/types/request-scope.ts +112 -0
  383. package/src/types/route-config.ts +20 -52
  384. package/src/types/route-entry.ts +19 -7
  385. package/src/types/segments.ts +137 -14
  386. package/src/urls/include-helper.ts +40 -75
  387. package/src/urls/include-provider.ts +71 -0
  388. package/src/urls/index.ts +2 -11
  389. package/src/urls/path-helper-types.ts +102 -23
  390. package/src/urls/path-helper.ts +62 -111
  391. package/src/urls/pattern-types.ts +84 -19
  392. package/src/urls/response-types.ts +25 -22
  393. package/src/urls/type-extraction.ts +98 -154
  394. package/src/urls/urls-function.ts +1 -19
  395. package/src/use-loader.tsx +346 -89
  396. package/src/vercel/index.ts +11 -0
  397. package/src/vercel/tracing.ts +88 -0
  398. package/src/vite/debug.ts +185 -0
  399. package/src/vite/discovery/bundle-postprocess.ts +36 -38
  400. package/src/vite/discovery/dev-prerender-cache.ts +117 -0
  401. package/src/vite/discovery/discover-routers.ts +130 -85
  402. package/src/vite/discovery/discovery-errors.ts +255 -0
  403. package/src/vite/discovery/gate-state.ts +171 -0
  404. package/src/vite/discovery/prerender-collection.ts +214 -132
  405. package/src/vite/discovery/route-types-writer.ts +40 -84
  406. package/src/vite/discovery/self-gen-tracking.ts +27 -1
  407. package/src/vite/discovery/state.ts +57 -6
  408. package/src/vite/discovery/virtual-module-codegen.ts +14 -34
  409. package/src/vite/index.ts +15 -0
  410. package/src/vite/inject-client-debug.ts +88 -0
  411. package/src/vite/plugin-types.ts +234 -62
  412. package/src/vite/plugins/cjs-to-esm.ts +16 -19
  413. package/src/vite/plugins/client-ref-dedup.ts +16 -11
  414. package/src/vite/plugins/client-ref-hashing.ts +28 -15
  415. package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
  416. package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
  417. package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
  418. package/src/vite/plugins/expose-action-id.ts +49 -98
  419. package/src/vite/plugins/expose-id-utils.ts +96 -51
  420. package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
  421. package/src/vite/plugins/expose-ids/handler-transform.ts +15 -64
  422. package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
  423. package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
  424. package/src/vite/plugins/expose-internal-ids.ts +553 -317
  425. package/src/vite/plugins/performance-tracks.ts +89 -0
  426. package/src/vite/plugins/refresh-cmd.ts +89 -27
  427. package/src/vite/plugins/use-cache-transform.ts +73 -83
  428. package/src/vite/plugins/vercel-output.ts +384 -0
  429. package/src/vite/plugins/version-injector.ts +40 -29
  430. package/src/vite/plugins/version-plugin.ts +46 -37
  431. package/src/vite/plugins/virtual-entries.ts +138 -27
  432. package/src/vite/rango.ts +353 -303
  433. package/src/vite/router-discovery.ts +1090 -166
  434. package/src/vite/utils/ast-handler-extract.ts +26 -35
  435. package/src/vite/utils/banner.ts +4 -4
  436. package/src/vite/utils/bundle-analysis.ts +10 -15
  437. package/src/vite/utils/client-chunks.ts +184 -0
  438. package/src/vite/utils/directive-prologue.ts +40 -0
  439. package/src/vite/utils/forward-user-plugins.ts +171 -0
  440. package/src/vite/utils/manifest-utils.ts +4 -59
  441. package/src/vite/utils/package-resolution.ts +20 -52
  442. package/src/vite/utils/prerender-utils.ts +98 -38
  443. package/src/vite/utils/shared-utils.ts +144 -44
  444. package/src/browser/action-response-classifier.ts +0 -99
  445. package/src/browser/react/use-client-cache.ts +0 -58
  446. package/src/browser/shallow.ts +0 -40
  447. package/src/handles/index.ts +0 -7
  448. package/src/network-error-thrower.tsx +0 -23
  449. package/src/router/middleware-cookies.ts +0 -55
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Loader-family capture snapshot: elide + overlay for bake-lane loader
3
+ * containers (docs/design/loader-container-bake.md).
4
+ *
5
+ * A loader on an entry with NO renderable loading() executes during shell
6
+ * capture; its settled container bakes into the prelude while every promise
7
+ * still pending at the quiet window postpones as a hole. To keep a HIT's fresh
8
+ * payload byte-identical to that frozen prelude, the capture pins the container
9
+ * in the shell snapshot:
10
+ *
11
+ * - elide: deep-walk the settled container; a PENDING nested promise is a
12
+ * hole, replaced by {@link LOADER_HOLE_KEY} — and since
13
+ * loader-cache masks every nested thenable at capture
14
+ * ({@link maskNestedContainerThenables}), nested promises are
15
+ * ALWAYS pending here for new captures. The SETTLED-marker branch
16
+ * below is legacy: it fires only if a settled thenable reaches
17
+ * elide anyway, and the overlay keeps decoding SETTLED markers
18
+ * from pre-mask snapshots. The result is promise-free and
19
+ * Flight-serializable.
20
+ * - overlay: on a HIT the loader runs fresh (only the loader body can mint
21
+ * the live nested promises), then the recorded container is laid
22
+ * over it: recorded paths win (they are what the prelude froze),
23
+ * hole-marker paths take the fresh run's value (the live hole),
24
+ * SETTLED-marker paths become Promise.resolve(pinned) — consumers
25
+ * wrote use(data.x) against a promise-shaped container, and
26
+ * handing them the raw value throws React #438 on every HIT (the
27
+ * storefront PDP regression) — and fresh-only paths pass through
28
+ * (they cannot contradict prelude bytes that never rendered them).
29
+ */
30
+
31
+ import { isThenable } from "../../handles/is-thenable.js";
32
+
33
+ // Capture-side nested-thenable masking lives in the LEAF module mask-nested.ts
34
+ // (request-context also needs it for handle pushes and cannot import through
35
+ // loader-mask without a cycle). Re-exported here so loader-cache and the unit
36
+ // tests keep one import site for the snapshot family.
37
+ export { maskNestedContainerThenables } from "./mask-nested.js";
38
+
39
+ /**
40
+ * Marker object standing in for a pending nested promise in a recorded loader
41
+ * container. Shape-checked (not identity-checked) because the record round-trips
42
+ * through Flight serialization and a JSON-embedding store envelope.
43
+ */
44
+ export const LOADER_HOLE_KEY = "$rangoLoaderHole" as const;
45
+
46
+ export interface LoaderHoleMarker {
47
+ [LOADER_HOLE_KEY]: 1;
48
+ }
49
+
50
+ export function isLoaderHoleMarker(value: unknown): value is LoaderHoleMarker {
51
+ return (
52
+ typeof value === "object" &&
53
+ value !== null &&
54
+ (value as Record<string, unknown>)[LOADER_HOLE_KEY] === 1
55
+ );
56
+ }
57
+
58
+ /**
59
+ * Marker wrapping the inlined value of a NESTED promise that settled during
60
+ * capture. The value baked (physics), but the container key was a promise —
61
+ * the overlay must hand consumers a Promise.resolve(value), not the raw value,
62
+ * or an unconditional use(data.x) throws React #438 on every HIT. The ROOT
63
+ * container is never wrapped: loader-cache overlays against the awaited fresh
64
+ * container value.
65
+ */
66
+ export const LOADER_SETTLED_KEY = "$rangoLoaderSettled" as const;
67
+
68
+ export interface LoaderSettledMarker {
69
+ [LOADER_SETTLED_KEY]: 1;
70
+ value: unknown;
71
+ /**
72
+ * Present when the pinned subtree contains hole markers. Computed once at
73
+ * capture (elide already visits every node) so the per-HIT overlay never
74
+ * rescans the pinned structure to pick its rehydration path.
75
+ */
76
+ holes?: 1;
77
+ }
78
+
79
+ export function isLoaderSettledMarker(
80
+ value: unknown,
81
+ ): value is LoaderSettledMarker {
82
+ return (
83
+ typeof value === "object" &&
84
+ value !== null &&
85
+ (value as Record<string, unknown>)[LOADER_SETTLED_KEY] === 1
86
+ );
87
+ }
88
+
89
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
90
+ if (typeof value !== "object" || value === null) return false;
91
+ const proto = Object.getPrototypeOf(value);
92
+ return proto === Object.prototype || proto === null;
93
+ }
94
+
95
+ /**
96
+ * Probe whether a promise is already settled without waiting for it: races it
97
+ * against an immediately-resolved sentinel across two microtask hops (then
98
+ * chaining means a resolved inner value needs one extra hop to surface).
99
+ * Returns the settled state, or "pending" if it has not settled by then.
100
+ */
101
+ async function probeSettled(
102
+ p: PromiseLike<unknown>,
103
+ ): Promise<
104
+ | { state: "fulfilled"; value: unknown }
105
+ | { state: "rejected" }
106
+ | { state: "pending" }
107
+ > {
108
+ const PENDING = Symbol("pending");
109
+ // Two sentinel hops: Promise.resolve(p) adoption costs a microtask, so a
110
+ // single-hop sentinel would misreport an already-fulfilled promise as pending.
111
+ const sentinel = Promise.resolve()
112
+ .then(() => undefined)
113
+ .then(() => PENDING as unknown);
114
+ try {
115
+ const raced = await Promise.race([Promise.resolve(p), sentinel]);
116
+ if (raced === PENDING) return { state: "pending" };
117
+ return { state: "fulfilled", value: raced };
118
+ } catch {
119
+ return { state: "rejected" };
120
+ }
121
+ }
122
+
123
+ export type ElideResult =
124
+ | { state: "ok"; value: unknown; hasHole: boolean }
125
+ | { state: "rejected" };
126
+
127
+ /**
128
+ * Deep-elide a settled bake-lane container for recording. Settled nested
129
+ * promises pin their value behind a settled marker (they baked, but consumers
130
+ * hold a promise-shaped key); pending ones become hole markers; a REJECTED
131
+ * nested promise poisons the record (error UI must never bake into a shared
132
+ * shell) — the caller refuses the capture. Only plain objects/arrays are
133
+ * traversed; anything else (Date, Map, class instance) is a pinned leaf.
134
+ * Cycles are cut as pinned references (best effort — Flight rejects true
135
+ * cycles later regardless).
136
+ *
137
+ * The ROOT container promise-chain unwraps with NO marker: loader-cache
138
+ * overlays against the AWAITED fresh container, so the recorded root must be
139
+ * the unwrapped structure. Everything below it goes through elideNested.
140
+ */
141
+ export async function elideLoaderContainer(
142
+ value: unknown,
143
+ seen: Set<object> = new Set(),
144
+ ): Promise<ElideResult> {
145
+ if (isThenable(value)) {
146
+ const probed = await probeSettled(value);
147
+ if (probed.state === "pending") {
148
+ return { state: "ok", value: { [LOADER_HOLE_KEY]: 1 }, hasHole: true };
149
+ }
150
+ if (probed.state === "rejected") return { state: "rejected" };
151
+ return elideLoaderContainer(probed.value, seen);
152
+ }
153
+ return elideNested(value, seen);
154
+ }
155
+
156
+ async function elideNested(
157
+ value: unknown,
158
+ seen: Set<object>,
159
+ ): Promise<ElideResult> {
160
+ if (isThenable(value)) {
161
+ const probed = await probeSettled(value);
162
+ if (probed.state === "pending") {
163
+ return { state: "ok", value: { [LOADER_HOLE_KEY]: 1 }, hasHole: true };
164
+ }
165
+ if (probed.state === "rejected") return { state: "rejected" };
166
+ const inner = await elideNested(probed.value, seen);
167
+ if (inner.state === "rejected") return inner;
168
+ const marker: LoaderSettledMarker = inner.hasHole
169
+ ? { [LOADER_SETTLED_KEY]: 1, value: inner.value, holes: 1 }
170
+ : { [LOADER_SETTLED_KEY]: 1, value: inner.value };
171
+ return { state: "ok", value: marker, hasHole: inner.hasHole };
172
+ }
173
+
174
+ if (Array.isArray(value)) {
175
+ if (seen.has(value)) return { state: "ok", value, hasHole: false };
176
+ seen.add(value);
177
+ const out: unknown[] = new Array(value.length);
178
+ let hasHole = false;
179
+ for (let i = 0; i < value.length; i++) {
180
+ const r = await elideNested(value[i], seen);
181
+ if (r.state === "rejected") return r;
182
+ out[i] = r.value;
183
+ hasHole ||= r.hasHole;
184
+ }
185
+ return { state: "ok", value: out, hasHole };
186
+ }
187
+
188
+ if (isPlainObject(value)) {
189
+ if (seen.has(value)) return { state: "ok", value, hasHole: false };
190
+ seen.add(value);
191
+ const out: Record<string, unknown> = {};
192
+ let hasHole = false;
193
+ for (const key of Object.keys(value)) {
194
+ const r = await elideNested(value[key], seen);
195
+ if (r.state === "rejected") return r;
196
+ out[key] = r.value;
197
+ hasHole ||= r.hasHole;
198
+ }
199
+ return { state: "ok", value: out, hasHole };
200
+ }
201
+
202
+ return { state: "ok", value, hasHole: false };
203
+ }
204
+
205
+ /**
206
+ * Overlay a recorded (elided) container onto the fresh run's container for a
207
+ * shell HIT. Recorded wins per path; hole markers take the fresh value (the
208
+ * live nested promise); fresh-only object keys pass through. Where the shapes
209
+ * disagree structurally, recorded wins wholesale — it is what the prelude
210
+ * froze, and parity beats freshness inside the shell.
211
+ */
212
+ export function overlayLoaderContainer(
213
+ fresh: unknown,
214
+ recorded: unknown,
215
+ ): unknown {
216
+ if (isLoaderHoleMarker(recorded)) return fresh;
217
+
218
+ if (isLoaderSettledMarker(recorded)) {
219
+ const pinned = recorded.value;
220
+ // Deep holes inside a settled container (capture-computed `holes` bit)
221
+ // need the fresh promise's resolved value to fill them; a fully-pinned
222
+ // container resolves immediately (the prelude already shows it — never
223
+ // gate it on fresh latency). A rejecting fresh run degrades holes to
224
+ // undefined instead of poisoning the pin.
225
+ if (recorded.holes === 1) {
226
+ return Promise.resolve(fresh).then(
227
+ (freshValue) => overlayLoaderContainer(freshValue, pinned),
228
+ () => overlayLoaderContainer(undefined, pinned),
229
+ );
230
+ }
231
+ return Promise.resolve(overlayLoaderContainer(undefined, pinned));
232
+ }
233
+
234
+ if (Array.isArray(recorded)) {
235
+ const freshArr = Array.isArray(fresh) ? fresh : [];
236
+ return recorded.map((item, i) => overlayLoaderContainer(freshArr[i], item));
237
+ }
238
+
239
+ if (isPlainObject(recorded)) {
240
+ if (!isPlainObject(fresh)) {
241
+ // Shape drift: still honor markers (holes fall back to undefined).
242
+ const out: Record<string, unknown> = {};
243
+ for (const key of Object.keys(recorded)) {
244
+ out[key] = overlayLoaderContainer(undefined, recorded[key]);
245
+ }
246
+ return out;
247
+ }
248
+ const out: Record<string, unknown> = {};
249
+ for (const key of Object.keys(recorded)) {
250
+ out[key] = overlayLoaderContainer(fresh[key], recorded[key]);
251
+ }
252
+ for (const key of Object.keys(fresh)) {
253
+ if (!(key in out)) out[key] = fresh[key];
254
+ }
255
+ return out;
256
+ }
257
+
258
+ return recorded;
259
+ }
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Capture-side nested-thenable masking — the mechanism behind "nested-promise
3
+ * shape is the liveness declaration" for BOTH bake-lane loader containers
4
+ * (loader-cache.ts) and pushed handle containers (request-context.ts
5
+ * createUseFunction).
6
+ *
7
+ * Deliberately a LEAF module: request-context needs the mask for handle
8
+ * pushes, and loader-mask (the other natural home) imports request-context —
9
+ * importing from there would cycle. This module imports only is-thenable.
10
+ */
11
+
12
+ import { isThenable } from "../../handles/is-thenable.js";
13
+
14
+ /**
15
+ * A promise that never settles — the masked stand-in for a per-request value
16
+ * during shell capture. The consuming Suspense subtree suspends forever, so
17
+ * the static prerender postpones it as a hole instead of baking a per-request
18
+ * value into the shared shell. The capture abort (`maxWaitMs` in
19
+ * captureShellHTML) bounds how long the prerender waits before it freezes the
20
+ * prelude, so this never hangs the request.
21
+ */
22
+ export function createMaskedLoaderPromise<T = unknown>(): Promise<T> {
23
+ return new Promise<T>(() => {});
24
+ }
25
+
26
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
27
+ if (typeof value !== "object" || value === null) return false;
28
+ const proto = Object.getPrototypeOf(value);
29
+ return proto === Object.prototype || proto === null;
30
+ }
31
+
32
+ /**
33
+ * Deep-copy a container with every NESTED thenable replaced by a masked
34
+ * (never-resolving) promise. Applied during shell capture to (a) bake-lane
35
+ * loader containers (loader-cache.ts) and (b) pushed handle containers
36
+ * (createUseFunction) — the two rango-owned funnels where consumers declare
37
+ * per-request data by promise SHAPE.
38
+ *
39
+ * Why: a nested promise that happened to SETTLE before the capture's quiet
40
+ * window closed used to bake its value into the SHARED shell (and, for
41
+ * loaders, the snapshot pinned it for every HIT) — per-request data frozen
42
+ * and served cross-session (found live: a storefront basket, carrying the
43
+ * capturing session's basketId/customer identifiers, served to anonymous
44
+ * visitors). The window waits for the slowest shared material on the page, so
45
+ * any real data source (a 5ms SQL read, a 200ms basket API) lost the race.
46
+ * Masking makes the consuming subtree postpone as a hole no matter when the
47
+ * promise settles: liveness by declaration, not by racing the window.
48
+ *
49
+ * Only plain objects/arrays are traversed; other values are leaves. The INPUT
50
+ * IS NEVER MUTATED — handler-side loader consumption (the consumption-lane
51
+ * rule, semantic-matrix PPR3) shares the raw container and must keep real
52
+ * values. Cycles are preserved as cycles in the copy.
53
+ */
54
+ export function maskNestedContainerThenables(
55
+ value: unknown,
56
+ seen: Map<object, unknown> = new Map(),
57
+ ): unknown {
58
+ if (isThenable(value)) return createMaskedLoaderPromise();
59
+
60
+ if (Array.isArray(value)) {
61
+ const cached = seen.get(value);
62
+ if (cached !== undefined) return cached;
63
+ const out: unknown[] = new Array(value.length);
64
+ seen.set(value, out);
65
+ for (let i = 0; i < value.length; i++) {
66
+ out[i] = maskNestedContainerThenables(value[i], seen);
67
+ }
68
+ return out;
69
+ }
70
+
71
+ if (isPlainObject(value)) {
72
+ const cached = seen.get(value);
73
+ if (cached !== undefined) return cached;
74
+ const out: Record<string, unknown> = {};
75
+ seen.set(value, out);
76
+ for (const key of Object.keys(value)) {
77
+ out[key] = maskNestedContainerThenables(value[key], seen);
78
+ }
79
+ return out;
80
+ }
81
+
82
+ return value;
83
+ }