@rangojs/router 0.0.0-experimental.14 → 0.0.0-experimental.140
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.
- package/AGENTS.md +17 -0
- package/README.md +432 -7
- package/dist/bin/rango.js +2073 -213
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +7258 -2714
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +140 -67
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +329 -0
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +487 -0
- package/skills/caching/SKILL.md +357 -25
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +246 -0
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +16 -10
- package/skills/document-cache/SKILL.md +87 -62
- package/skills/fonts/SKILL.md +6 -4
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +557 -79
- package/skills/host-router/SKILL.md +320 -0
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +207 -15
- package/skills/layout/SKILL.md +146 -6
- package/skills/links/SKILL.md +304 -25
- package/skills/loader/SKILL.md +616 -54
- package/skills/middleware/SKILL.md +217 -37
- package/skills/migrate-nextjs/SKILL.md +611 -0
- package/skills/migrate-react-router/SKILL.md +927 -0
- package/skills/mime-routes/SKILL.md +42 -11
- package/skills/observability/SKILL.md +194 -0
- package/skills/parallel/SKILL.md +284 -3
- package/skills/ppr/SKILL.md +426 -0
- package/skills/prerender/SKILL.md +437 -52
- package/skills/rango/SKILL.md +369 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +263 -121
- package/skills/route/SKILL.md +350 -21
- package/skills/router-setup/SKILL.md +246 -33
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +126 -222
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +131 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +85 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +532 -103
- package/skills/use-cache/SKILL.md +367 -0
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +77 -44
- package/src/bin/rango.ts +312 -15
- package/src/browser/action-coordinator.ts +114 -0
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +293 -202
- package/src/browser/history-state.ts +101 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +11 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +385 -576
- package/src/browser/navigation-client.ts +245 -75
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +184 -118
- package/src/browser/navigation-transaction.ts +247 -0
- package/src/browser/network-error-handler.ts +88 -0
- package/src/browser/partial-update.ts +412 -364
- package/src/browser/prefetch/cache.ts +359 -0
- package/src/browser/prefetch/fetch.ts +452 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +209 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +194 -0
- package/src/browser/react/Link.tsx +275 -68
- package/src/browser/react/NavigationProvider.tsx +265 -109
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +11 -0
- package/src/browser/react/filter-segment-order.ts +70 -0
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +272 -60
- package/src/browser/react/location-state.ts +90 -20
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +35 -66
- package/src/browser/react/use-handle.ts +39 -126
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +39 -13
- package/src/browser/react/use-navigation.ts +53 -69
- package/src/browser/react/use-params.ts +75 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +98 -0
- package/src/browser/react/use-search-params.ts +51 -0
- package/src/browser/react/use-segments.ts +72 -99
- package/src/browser/response-adapter.ts +164 -0
- package/src/browser/rsc-router.tsx +300 -72
- package/src/browser/scroll-restoration.ts +138 -50
- package/src/browser/segment-reconciler.ts +243 -0
- package/src/browser/segment-structure-assert.ts +17 -1
- package/src/browser/server-action-bridge.ts +668 -613
- package/src/browser/types.ts +223 -51
- package/src/browser/validate-redirect-origin.ts +56 -0
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +252 -161
- package/src/build/generate-route-types.ts +41 -1038
- package/src/build/index.ts +12 -7
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +225 -42
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +105 -0
- package/src/build/route-types/codegen.ts +113 -0
- package/src/build/route-types/include-resolution.ts +812 -0
- package/src/build/route-types/param-extraction.ts +51 -0
- package/src/build/route-types/per-module-writer.ts +144 -0
- package/src/build/route-types/router-processing.ts +695 -0
- package/src/build/route-types/scan-filter.ts +85 -0
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +223 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +60 -0
- package/src/cache/cache-policy.ts +199 -0
- package/src/cache/cache-runtime.ts +525 -0
- package/src/cache/cache-scope.ts +298 -332
- package/src/cache/cache-tag.ts +103 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +2500 -158
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +17 -17
- package/src/cache/document-cache.ts +199 -92
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +111 -0
- package/src/cache/index.ts +29 -35
- package/src/cache/memory-segment-store.ts +363 -30
- package/src/cache/profile-registry.ts +88 -0
- package/src/cache/read-through-swr.ts +178 -0
- package/src/cache/segment-codec.ts +248 -0
- package/src/cache/shell-cache.ts +386 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +153 -0
- package/src/cache/types.ts +156 -211
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1102 -0
- package/src/client.rsc.tsx +43 -21
- package/src/client.tsx +131 -347
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/component-utils.ts +23 -4
- package/src/components/DefaultDocument.tsx +13 -3
- package/src/context-var.ts +168 -0
- package/src/debug.ts +19 -9
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +106 -10
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +110 -35
- package/src/handles/MetaTags.tsx +83 -59
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +93 -0
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +44 -53
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +20 -65
- package/src/host/errors.ts +21 -30
- package/src/host/index.ts +13 -9
- package/src/host/pattern-matcher.ts +50 -79
- package/src/host/router.ts +151 -121
- package/src/host/testing.ts +45 -32
- package/src/host/types.ts +52 -11
- package/src/host/utils.ts +2 -2
- package/src/href-client.ts +192 -57
- package/src/index.rsc.ts +177 -35
- package/src/index.ts +255 -71
- package/src/internal-debug.ts +9 -2
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +31 -99
- package/src/loader.ts +30 -12
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +41 -0
- package/src/prerender/param-hash.ts +16 -14
- package/src/prerender/store.ts +121 -21
- package/src/prerender.ts +460 -26
- package/src/redirect-origin.ts +100 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +62 -0
- package/src/reverse.ts +198 -128
- package/src/root-error-boundary.tsx +42 -48
- package/src/route-content-wrapper.tsx +22 -77
- package/src/route-definition/dsl-helpers.ts +1116 -0
- package/src/route-definition/helper-factories.ts +88 -0
- package/src/route-definition/helpers-types.ts +505 -0
- package/src/route-definition/index.ts +54 -0
- package/src/route-definition/redirect.ts +134 -0
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-definition.ts +1 -1481
- package/src/route-map-builder.ts +82 -144
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +71 -45
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +263 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +54 -27
- package/src/router/find-match.ts +245 -0
- package/src/router/handler-context.ts +377 -125
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +59 -28
- package/src/router/lazy-includes.ts +254 -0
- package/src/router/loader-resolution.ts +421 -157
- package/src/router/logging.ts +106 -6
- package/src/router/manifest.ts +131 -57
- package/src/router/match-api.ts +167 -246
- package/src/router/match-context.ts +4 -24
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +117 -93
- package/src/router/match-middleware/cache-lookup.ts +297 -150
- package/src/router/match-middleware/cache-store.ts +123 -51
- package/src/router/match-middleware/intercept-resolution.ts +44 -43
- package/src/router/match-middleware/segment-resolution.ts +64 -22
- package/src/router/match-pipelines.ts +11 -87
- package/src/router/match-result.ts +121 -50
- package/src/router/metrics.ts +219 -28
- package/src/router/middleware-types.ts +93 -0
- package/src/router/middleware.ts +505 -441
- package/src/router/navigation-snapshot.ts +133 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +311 -142
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +547 -0
- package/src/router/preview-match.ts +102 -0
- package/src/router/request-classification.ts +278 -0
- package/src/router/revalidation.ts +203 -62
- package/src/router/route-snapshot.ts +246 -0
- package/src/router/router-context.ts +45 -48
- package/src/router/router-interfaces.ts +554 -0
- package/src/router/router-options.ts +779 -0
- package/src/router/router-registry.ts +21 -0
- package/src/router/segment-resolution/fresh.ts +772 -0
- package/src/router/segment-resolution/helpers.ts +348 -0
- package/src/router/segment-resolution/loader-cache.ts +250 -0
- package/src/router/segment-resolution/loader-mask.ts +44 -0
- package/src/router/segment-resolution/revalidation.ts +1331 -0
- package/src/router/segment-resolution/static-store.ts +81 -0
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +56 -0
- package/src/router/segment-resolution.ts +25 -1354
- package/src/router/segment-wrappers.ts +292 -0
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +261 -0
- package/src/router/telemetry.ts +377 -0
- package/src/router/timeout.ts +128 -0
- package/src/router/tracing.ts +206 -0
- package/src/router/trie-matching.ts +240 -61
- package/src/router/types.ts +23 -70
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +781 -2378
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +46 -0
- package/src/rsc/handler.ts +905 -1142
- package/src/rsc/helpers.ts +275 -19
- package/src/rsc/index.ts +2 -25
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +305 -0
- package/src/rsc/manifest-init.ts +77 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +155 -0
- package/src/rsc/progressive-enhancement.ts +502 -0
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +104 -0
- package/src/rsc/response-route-handler.ts +257 -0
- package/src/rsc/rsc-rendering.ts +337 -0
- package/src/rsc/runtime-warnings.ts +55 -0
- package/src/rsc/server-action.ts +522 -0
- package/src/rsc/shell-capture.ts +439 -0
- package/src/rsc/ssr-setup.ts +144 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +95 -12
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +99 -82
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +149 -0
- package/src/segment-system.tsx +349 -134
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +452 -85
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +310 -0
- package/src/server/fetchable-loader-store.ts +11 -6
- package/src/server/handle-store.ts +123 -42
- package/src/server/live.ts +130 -0
- package/src/server/loader-registry.ts +51 -100
- package/src/server/request-context.ts +842 -157
- package/src/server.ts +15 -8
- package/src/ssr/index.tsx +412 -136
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +45 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +701 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +257 -0
- package/src/testing/generated-routes.ts +199 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +357 -0
- package/src/testing/render-route.tsx +584 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +40 -72
- package/src/theme/ThemeScript.tsx +12 -14
- package/src/theme/constants.ts +57 -15
- package/src/theme/index.ts +3 -20
- package/src/theme/theme-context.ts +5 -35
- package/src/theme/theme-script.ts +43 -39
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +123 -0
- package/src/types/cache-types.ts +207 -0
- package/src/types/error-types.ts +132 -0
- package/src/types/global-namespace.ts +113 -0
- package/src/types/handler-context.ts +839 -0
- package/src/types/index.ts +81 -0
- package/src/types/loader-types.ts +212 -0
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +138 -0
- package/src/types/route-entry.ts +114 -0
- package/src/types/segments.ts +271 -0
- package/src/types.ts +1 -1795
- package/src/urls/include-helper.ts +162 -0
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +43 -0
- package/src/urls/path-helper-types.ts +413 -0
- package/src/urls/path-helper.ts +275 -0
- package/src/urls/pattern-types.ts +124 -0
- package/src/urls/response-types.ts +109 -0
- package/src/urls/type-extraction.ts +316 -0
- package/src/urls/urls-function.ts +80 -0
- package/src/urls.ts +1 -1341
- package/src/use-loader.tsx +406 -141
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +182 -0
- package/src/vite/discovery/discover-routers.ts +389 -0
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +467 -0
- package/src/vite/discovery/route-types-writer.ts +214 -0
- package/src/vite/discovery/self-gen-tracking.ts +73 -0
- package/src/vite/discovery/state.ts +161 -0
- package/src/vite/discovery/virtual-module-codegen.ts +183 -0
- package/src/vite/index.ts +23 -2255
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +303 -0
- package/src/vite/plugins/cjs-to-esm.ts +90 -0
- package/src/vite/plugins/client-ref-dedup.ts +120 -0
- package/src/vite/plugins/client-ref-hashing.ts +118 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +88 -110
- package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +89 -79
- package/src/vite/plugins/expose-ids/export-analysis.ts +363 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +130 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +64 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +199 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +805 -0
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +313 -0
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +94 -0
- package/src/vite/plugins/version-plugin.ts +263 -0
- package/src/vite/plugins/virtual-entries.ts +234 -0
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +560 -0
- package/src/vite/router-discovery.ts +1638 -0
- package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +200 -37
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +132 -0
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +15 -0
- package/src/vite/utils/package-resolution.ts +89 -0
- package/src/vite/utils/prerender-utils.ts +249 -0
- package/src/vite/utils/shared-utils.ts +269 -0
- package/CLAUDE.md +0 -43
- package/dist/vite/index.named-routes.gen.ts +0 -103
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/react/use-client-cache.ts +0 -56
- package/src/browser/request-controller.ts +0 -164
- package/src/browser/shallow.ts +0 -35
- package/src/cache/memory-store.ts +0 -253
- package/src/handles/index.ts +0 -6
- package/src/href-context.ts +0 -33
- package/src/network-error-thrower.tsx +0 -21
- package/src/router.gen.ts +0 -6
- package/src/static-handler.gen.ts +0 -5
- package/src/urls.gen.ts +0 -8
- package/src/vite/expose-internal-ids.ts +0 -1167
- package/src/vite/package-resolution.ts +0 -125
- package/src/vite/virtual-entries.ts +0 -114
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RSC Rendering Handler (Navigation)
|
|
3
|
+
*
|
|
4
|
+
* Handles RSC rendering for both partial (client-side navigation) and full
|
|
5
|
+
* (initial page load) requests. Includes prerender collection for build-time
|
|
6
|
+
* static generation.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
getRequestContext,
|
|
11
|
+
setRequestContextParams,
|
|
12
|
+
} from "../server/request-context.js";
|
|
13
|
+
import { appendMetric } from "../router/metrics.js";
|
|
14
|
+
import { observePhase, PHASES } from "../router/instrument.js";
|
|
15
|
+
import { getSSRSetup, isRscRequest } from "./ssr-setup.js";
|
|
16
|
+
import type { RscPayload } from "./types.js";
|
|
17
|
+
import type { SSRModule } from "./types.js";
|
|
18
|
+
import type { RequestContext } from "../server/request-context.js";
|
|
19
|
+
import {
|
|
20
|
+
createResponseWithMergedHeaders,
|
|
21
|
+
createSimpleRedirectResponse,
|
|
22
|
+
attachLocationStateIfPresent,
|
|
23
|
+
} from "./helpers.js";
|
|
24
|
+
import type { HandlerContext } from "./handler-context.js";
|
|
25
|
+
import { gateTransitions } from "./transition-gate.js";
|
|
26
|
+
import { buildFullPayload } from "./full-payload.js";
|
|
27
|
+
import { scheduleShellCapture } from "./shell-capture.js";
|
|
28
|
+
|
|
29
|
+
export function handleRscRendering<TEnv>(
|
|
30
|
+
ctx: HandlerContext<TEnv>,
|
|
31
|
+
request: Request,
|
|
32
|
+
env: TEnv,
|
|
33
|
+
url: URL,
|
|
34
|
+
isPartial: boolean,
|
|
35
|
+
handleStore: ReturnType<typeof getRequestContext>["_handleStore"],
|
|
36
|
+
nonce: string | undefined,
|
|
37
|
+
): Promise<Response> {
|
|
38
|
+
// Instrument the whole render phase once through the unified API: it records
|
|
39
|
+
// the "render:total" perf metric AND opens the "rango.render" span from the
|
|
40
|
+
// same boundary (match -> serialize -> SSR), so the two surfaces agree.
|
|
41
|
+
// Loaders kicked off during matching nest under the span; the SSR HTML pass
|
|
42
|
+
// below opens "rango.ssr" the same way.
|
|
43
|
+
return observePhase(PHASES.render, () =>
|
|
44
|
+
handleRscRenderingInner(
|
|
45
|
+
ctx,
|
|
46
|
+
request,
|
|
47
|
+
env,
|
|
48
|
+
url,
|
|
49
|
+
isPartial,
|
|
50
|
+
handleStore,
|
|
51
|
+
nonce,
|
|
52
|
+
),
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async function handleRscRenderingInner<TEnv>(
|
|
57
|
+
ctx: HandlerContext<TEnv>,
|
|
58
|
+
request: Request,
|
|
59
|
+
env: TEnv,
|
|
60
|
+
url: URL,
|
|
61
|
+
isPartial: boolean,
|
|
62
|
+
handleStore: ReturnType<typeof getRequestContext>["_handleStore"],
|
|
63
|
+
nonce: string | undefined,
|
|
64
|
+
): Promise<Response> {
|
|
65
|
+
const reqCtx = getRequestContext();
|
|
66
|
+
|
|
67
|
+
let payload: RscPayload;
|
|
68
|
+
let hasInterceptSlots = false;
|
|
69
|
+
|
|
70
|
+
if (isPartial) {
|
|
71
|
+
// Partial render (navigation)
|
|
72
|
+
const result = await ctx.router.matchPartial(request, { env });
|
|
73
|
+
|
|
74
|
+
if (!result) {
|
|
75
|
+
// Fall back to full render
|
|
76
|
+
const match = await ctx.router.match(request, { env });
|
|
77
|
+
setRequestContextParams(match.params, match.routeName);
|
|
78
|
+
|
|
79
|
+
if (match.redirect) {
|
|
80
|
+
// Partial request: use X-RSC-Redirect header so the client can
|
|
81
|
+
// perform SPA navigation. A raw 308 would be auto-followed by
|
|
82
|
+
// fetch, hitting the target without _rsc_partial.
|
|
83
|
+
return createSimpleRedirectResponse(match.redirect);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
payload = buildFullPayload(match, ctx, url, reqCtx, handleStore);
|
|
87
|
+
} else {
|
|
88
|
+
setRequestContextParams(result.params, result.routeName);
|
|
89
|
+
|
|
90
|
+
hasInterceptSlots = !!result.slots;
|
|
91
|
+
|
|
92
|
+
payload = {
|
|
93
|
+
metadata: {
|
|
94
|
+
pathname: url.pathname,
|
|
95
|
+
// routerId is serialized on every payload (including within-session
|
|
96
|
+
// ones) so the frontend can read the current app/router identity. It
|
|
97
|
+
// always equals the current app's id: a cross-app navigation is
|
|
98
|
+
// intercepted server-side (X-RSC-Reload) and never delivers a
|
|
99
|
+
// different-router payload to the client.
|
|
100
|
+
routerId: ctx.router.id,
|
|
101
|
+
segments: gateTransitions(
|
|
102
|
+
result.segments,
|
|
103
|
+
reqCtx,
|
|
104
|
+
ctx.router.onError,
|
|
105
|
+
),
|
|
106
|
+
matched: result.matched,
|
|
107
|
+
diff: result.diff,
|
|
108
|
+
resolvedIds: result.resolvedIds,
|
|
109
|
+
params: result.params,
|
|
110
|
+
isPartial: true,
|
|
111
|
+
slots: result.slots,
|
|
112
|
+
handles: handleStore.stream(),
|
|
113
|
+
version: ctx.version,
|
|
114
|
+
prefetchCacheTTL: ctx.router.prefetchCacheTTL,
|
|
115
|
+
prefetchCacheSize: ctx.router.prefetchCacheSize,
|
|
116
|
+
prefetchConcurrency: ctx.router.prefetchConcurrency,
|
|
117
|
+
stateCookieName: ctx.router.resolvedStateCookieName,
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
// Full render (initial page load)
|
|
123
|
+
const match = await ctx.router.match(request, { env });
|
|
124
|
+
setRequestContextParams(match.params, match.routeName);
|
|
125
|
+
|
|
126
|
+
if (match.redirect) {
|
|
127
|
+
return createResponseWithMergedHeaders(null, {
|
|
128
|
+
status: 308,
|
|
129
|
+
headers: { Location: match.redirect },
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Caching is now handled in router.match() via cache provider in request context
|
|
134
|
+
// match.segments already contains cached or fresh segments as appropriate
|
|
135
|
+
|
|
136
|
+
if (url.searchParams.has("__prerender_collect")) {
|
|
137
|
+
// Build-time prerender collection: serialize segments and handle data
|
|
138
|
+
// to JSON for storage as build artifacts. At runtime the worker
|
|
139
|
+
// deserializes these and feeds them through the normal segment pipeline.
|
|
140
|
+
const nonLoaderSegments = match.segments.filter(
|
|
141
|
+
(s) => s.type !== "loader",
|
|
142
|
+
);
|
|
143
|
+
handleStore.seal();
|
|
144
|
+
await handleStore.settled;
|
|
145
|
+
const { serializeSegments } = await import("../cache/segment-codec.js");
|
|
146
|
+
const serializedSegments = await serializeSegments(nonLoaderSegments);
|
|
147
|
+
const handles: Record<string, Record<string, unknown[]>> = {};
|
|
148
|
+
for (const seg of nonLoaderSegments) {
|
|
149
|
+
const segHandles = handleStore.getDataForSegment(seg.id);
|
|
150
|
+
if (Object.keys(segHandles).length > 0) {
|
|
151
|
+
handles[seg.id] = segHandles;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return new Response(
|
|
155
|
+
JSON.stringify({
|
|
156
|
+
segments: serializedSegments,
|
|
157
|
+
handles,
|
|
158
|
+
routeName: match.routeName,
|
|
159
|
+
params: match.params,
|
|
160
|
+
}),
|
|
161
|
+
{ headers: { "Content-Type": "application/json" } },
|
|
162
|
+
);
|
|
163
|
+
} else {
|
|
164
|
+
payload = buildFullPayload(match, ctx, url, reqCtx, handleStore);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// For partial requests, include any server-set location state in the payload.
|
|
169
|
+
// SSR (full page) requests ignore location state since there's no history.state
|
|
170
|
+
// to write to on a fresh page load.
|
|
171
|
+
if (isPartial && payload.metadata) {
|
|
172
|
+
attachLocationStateIfPresent(payload);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const metricsStore = reqCtx._metricsStore;
|
|
176
|
+
|
|
177
|
+
// Serialize to RSC stream
|
|
178
|
+
const rscSerializeStart = performance.now();
|
|
179
|
+
const rscStream = ctx.renderToReadableStream<RscPayload>(payload, {
|
|
180
|
+
onError: (error: unknown) => {
|
|
181
|
+
ctx.callOnError(error, "rendering", { request, url, env });
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
const rscSerializeDur = performance.now() - rscSerializeStart;
|
|
185
|
+
// This measures synchronous stream creation, not end-to-end stream consumption.
|
|
186
|
+
appendMetric(
|
|
187
|
+
metricsStore,
|
|
188
|
+
"rsc-serialize",
|
|
189
|
+
rscSerializeStart,
|
|
190
|
+
rscSerializeDur,
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
if (isRscRequest(request, url, isPartial)) {
|
|
194
|
+
// render:total is recorded by the observePhase wrapper around this function.
|
|
195
|
+
const rscHeaders: Record<string, string> = {
|
|
196
|
+
"content-type": "text/x-component;charset=utf-8",
|
|
197
|
+
vary: "accept, X-Rango-State, X-RSC-Router-Client-Path",
|
|
198
|
+
// Router identity, so the client can verify pre-decode (before importing
|
|
199
|
+
// chunks) that this content payload belongs to its app and refuse a
|
|
200
|
+
// foreign one (cache/proxy/bug). Control-only reload/redirect responses
|
|
201
|
+
// are deliberately NOT stamped. See browser/response-adapter.ts.
|
|
202
|
+
"X-RSC-Router-Id": ctx.router.id,
|
|
203
|
+
};
|
|
204
|
+
// Tell the client's prefetch cache to scope this response to its source
|
|
205
|
+
// URL (instead of the default source-agnostic wildcard). Intercept
|
|
206
|
+
// responses depend on the source page matching an intercept rule, so
|
|
207
|
+
// they must not be reused for navigations from other sources.
|
|
208
|
+
if (hasInterceptSlots) {
|
|
209
|
+
rscHeaders["x-rsc-prefetch-scope"] = "source";
|
|
210
|
+
}
|
|
211
|
+
// Enable browser HTTP caching for prefetch responses only.
|
|
212
|
+
// Requires X-Rango-Prefetch header (sent by Link prefetch fetch),
|
|
213
|
+
// non-intercept context (intercept responses depend on source page),
|
|
214
|
+
// and a configured cache-control value (false disables caching).
|
|
215
|
+
const isPrefetch = request.headers.has("X-Rango-Prefetch");
|
|
216
|
+
if (isPrefetch && isPartial && !hasInterceptSlots) {
|
|
217
|
+
const cc = ctx.router.prefetchCacheControl;
|
|
218
|
+
if (cc) {
|
|
219
|
+
rscHeaders["cache-control"] = cc;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
return createResponseWithMergedHeaders(rscStream, {
|
|
223
|
+
headers: rscHeaders,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Delegate to SSR for HTML response (reuse early setup if available)
|
|
228
|
+
const [ssrModule, streamMode] = await getSSRSetup(
|
|
229
|
+
ctx,
|
|
230
|
+
request,
|
|
231
|
+
env,
|
|
232
|
+
url,
|
|
233
|
+
metricsStore,
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
// --- Axis 2: PPR shell RESUME (see docs/design/ppr-shell-resume.md) ---
|
|
237
|
+
// The shell-cache middleware armed reqCtx._shellResume optimistically on a
|
|
238
|
+
// validated shell HIT. The render layer is the FINAL AUTHORITY: resume only on
|
|
239
|
+
// the main 200 HTML document path (we are past the isRscRequest early return, so
|
|
240
|
+
// !isPartial holds), with no per-request nonce (a frozen prelude cannot carry a
|
|
241
|
+
// fresh nonce), not under allReady buffering (which defeats streaming), and only
|
|
242
|
+
// when the SSR module actually exports the resume strategy. When we resume we
|
|
243
|
+
// MUST mark the response with x-rango-shell-resumed so the middleware prepends
|
|
244
|
+
// the cached prelude; if any guard fails we fall through to a normal renderHTML
|
|
245
|
+
// with no marker and the middleware fails open to axis 1.
|
|
246
|
+
const shellResume = reqCtx._shellResume;
|
|
247
|
+
let response: Response;
|
|
248
|
+
if (
|
|
249
|
+
shellResume &&
|
|
250
|
+
!isPartial &&
|
|
251
|
+
nonce === undefined &&
|
|
252
|
+
streamMode !== "allReady" &&
|
|
253
|
+
ssrModule.resumeShellHTML
|
|
254
|
+
) {
|
|
255
|
+
const resumedStream = await observePhase(PHASES.ssr, () =>
|
|
256
|
+
ssrModule.resumeShellHTML!(rscStream, {
|
|
257
|
+
postponed: shellResume.postponed,
|
|
258
|
+
nonce,
|
|
259
|
+
}),
|
|
260
|
+
);
|
|
261
|
+
response = createResponseWithMergedHeaders(resumedStream, {
|
|
262
|
+
headers: {
|
|
263
|
+
"content-type": "text/html;charset=utf-8",
|
|
264
|
+
"x-rango-shell-resumed": "1",
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
} else {
|
|
268
|
+
// ssr-render-html metric + rango.ssr span from one boundary. render:total is
|
|
269
|
+
// recorded by the observePhase wrapper around this function.
|
|
270
|
+
const htmlStream = await observePhase(PHASES.ssr, () =>
|
|
271
|
+
ssrModule.renderHTML(rscStream, {
|
|
272
|
+
nonce,
|
|
273
|
+
streamMode,
|
|
274
|
+
}),
|
|
275
|
+
);
|
|
276
|
+
response = createResponseWithMergedHeaders(htmlStream, {
|
|
277
|
+
headers: { "content-type": "text/html;charset=utf-8" },
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// --- Axis 2: PPR shell CAPTURE (background task; see design doc) ---
|
|
282
|
+
// The middleware set reqCtx._shellCapture (the "capture wanted" descriptor)
|
|
283
|
+
// before its single next(). Capture does NOT flow through the HTTP pipeline: we
|
|
284
|
+
// schedule a background task that re-derives the shell via router.match() under
|
|
285
|
+
// its own derived context (fresh handle store, _shellCaptureRun: true), so the
|
|
286
|
+
// middleware chain never re-runs. Eligibility mirrors resume plus a servable
|
|
287
|
+
// 200-HTML gate; the descriptor is read now (still set — the middleware clears
|
|
288
|
+
// it in a finally after next() returns, which is after this synchronous point).
|
|
289
|
+
maybeScheduleShellCapture(
|
|
290
|
+
ctx,
|
|
291
|
+
request,
|
|
292
|
+
env,
|
|
293
|
+
url,
|
|
294
|
+
reqCtx,
|
|
295
|
+
ssrModule,
|
|
296
|
+
nonce,
|
|
297
|
+
streamMode,
|
|
298
|
+
isPartial,
|
|
299
|
+
response,
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
return response;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Schedule a background PPR shell capture when the middleware requested one
|
|
307
|
+
* (`reqCtx._shellCapture` descriptor present) and this render is eligible: no
|
|
308
|
+
* per-request nonce (a frozen prelude cannot carry a fresh nonce), not under
|
|
309
|
+
* allReady buffering (which defeats streaming), the document path (never a
|
|
310
|
+
* partial), the SSR module exports the capture strategy, and the served response
|
|
311
|
+
* is a 200 HTML document (a 404/redirect/JSON is not a cacheable shell). All
|
|
312
|
+
* gating lives here so the middleware stays a thin descriptor-setter.
|
|
313
|
+
*/
|
|
314
|
+
function maybeScheduleShellCapture(
|
|
315
|
+
ctx: HandlerContext<any>,
|
|
316
|
+
request: Request,
|
|
317
|
+
env: any,
|
|
318
|
+
url: URL,
|
|
319
|
+
reqCtx: RequestContext<any>,
|
|
320
|
+
ssrModule: SSRModule,
|
|
321
|
+
nonce: string | undefined,
|
|
322
|
+
streamMode: import("../router/router-options.js").SSRStreamMode,
|
|
323
|
+
isPartial: boolean,
|
|
324
|
+
response: Response,
|
|
325
|
+
): void {
|
|
326
|
+
const descriptor = reqCtx._shellCapture;
|
|
327
|
+
if (!descriptor) return;
|
|
328
|
+
if (nonce !== undefined) return;
|
|
329
|
+
if (streamMode === "allReady") return;
|
|
330
|
+
if (isPartial) return;
|
|
331
|
+
if (!ssrModule.captureShellHTML) return;
|
|
332
|
+
if (response.status !== 200) return;
|
|
333
|
+
if (!(response.headers.get("content-type") ?? "").includes("text/html")) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
scheduleShellCapture(ctx, request, env, url, reqCtx, ssrModule, descriptor);
|
|
337
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime guardrail warnings (dev-only).
|
|
3
|
+
*
|
|
4
|
+
* W3: PE action redirect / Response handling.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
createResponseWithMergedHeaders,
|
|
9
|
+
carryOverRedirectHeaders,
|
|
10
|
+
} from "./helpers.js";
|
|
11
|
+
import { isRedirectResponse } from "../response-utils.js";
|
|
12
|
+
|
|
13
|
+
// W3 -----------------------------------------------------------------------
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Extract a redirect Response from a thrown or returned value.
|
|
17
|
+
* Returns a redirect Response to send to the client, or null if the value
|
|
18
|
+
* is not a redirect Response.
|
|
19
|
+
*/
|
|
20
|
+
export function extractRedirectResponse(value: unknown): Response | null {
|
|
21
|
+
if (!(value instanceof Response)) return null;
|
|
22
|
+
if (!isRedirectResponse(value)) return null;
|
|
23
|
+
const location = value.headers.get("Location")!;
|
|
24
|
+
const redirect = createResponseWithMergedHeaders(null, {
|
|
25
|
+
status: value.status,
|
|
26
|
+
headers: { Location: location },
|
|
27
|
+
});
|
|
28
|
+
carryOverRedirectHeaders(value, redirect);
|
|
29
|
+
return redirect;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Warn when a non-redirect Response is returned from an action during PE.
|
|
34
|
+
*/
|
|
35
|
+
export function warnNonRedirectPeResponse(): void {
|
|
36
|
+
console.warn(
|
|
37
|
+
`[rango] Server action returned a non-redirect Response during ` +
|
|
38
|
+
`progressive enhancement (no-JS) request. The Response will be ` +
|
|
39
|
+
`ignored — the page will re-render at the current URL instead.`,
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Warn when a non-redirect Response is returned (not thrown) from an action
|
|
45
|
+
* on the JS (fetch) path. A raw Response cannot be serialized into Flight, so
|
|
46
|
+
* it is discarded — mirroring the PE path. Use `throw redirect('/path')` for
|
|
47
|
+
* redirects.
|
|
48
|
+
*/
|
|
49
|
+
export function warnNonRedirectActionResponse(actionId: string): void {
|
|
50
|
+
console.warn(
|
|
51
|
+
`[@rangojs/router] Server action "${actionId}" returned a Response ` +
|
|
52
|
+
`that is not a redirect. Non-redirect Responses cannot be serialized ` +
|
|
53
|
+
`and are ignored. Use \`throw redirect('/path')\` for redirects.`,
|
|
54
|
+
);
|
|
55
|
+
}
|