@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
package/src/rsc/helpers.ts
CHANGED
|
@@ -4,7 +4,96 @@
|
|
|
4
4
|
* Utility functions for RSC request handling.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
_getRequestContext,
|
|
9
|
+
getLocationState,
|
|
10
|
+
} from "../server/request-context.js";
|
|
11
|
+
import type { RequestContext } from "../server/request-context.js";
|
|
12
|
+
import { resolveLocationStateEntries } from "../browser/react/location-state-shared.js";
|
|
13
|
+
import { isRedirectResponse } from "../response-utils.js";
|
|
14
|
+
import {
|
|
15
|
+
EXTERNAL_REDIRECT_MARKER,
|
|
16
|
+
isExternalRedirect,
|
|
17
|
+
markExternalRedirect,
|
|
18
|
+
} from "../redirect-origin.js";
|
|
19
|
+
import type { MiddlewareEntry, MiddlewareFn } from "../router/middleware.js";
|
|
20
|
+
import { formatCacheSignalHeader } from "../router/telemetry.js";
|
|
21
|
+
import type { RscPayload } from "./types.js";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* DEVELOPMENT/TEST ONLY. When the debug cache signal gate is on,
|
|
25
|
+
* match/matchPartial populate ctx._cacheSignal. Emit it as the X-Rango-Cache
|
|
26
|
+
* header. When the gate is off, ctx._cacheSignal is undefined and NOTHING is
|
|
27
|
+
* attached — output is byte-identical to the default. Header mutation failures
|
|
28
|
+
* are swallowed so immutable Response headers (e.g. protocol-switch) are safe.
|
|
29
|
+
*/
|
|
30
|
+
function applyCacheSignalHeader(target: Headers, ctx: RequestContext): void {
|
|
31
|
+
const signal = ctx._cacheSignal;
|
|
32
|
+
if (!signal || signal.length === 0) return;
|
|
33
|
+
try {
|
|
34
|
+
target.set("X-Rango-Cache", formatCacheSignalHeader(signal));
|
|
35
|
+
} catch {
|
|
36
|
+
// Headers immutable — skip.
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Copy stub headers from the request context onto a target Headers instance:
|
|
42
|
+
* append Set-Cookie entries, set everything else only if absent. Header
|
|
43
|
+
* mutation failures are swallowed so the same logic works against Response
|
|
44
|
+
* headers that may be immutable (e.g. Cloudflare protocol-switch responses).
|
|
45
|
+
*/
|
|
46
|
+
function applyStubHeaders(target: Headers, stub: Headers): void {
|
|
47
|
+
stub.forEach((value, name) => {
|
|
48
|
+
try {
|
|
49
|
+
// The reserved external-redirect marker is internal and never a trust
|
|
50
|
+
// signal; never copy a stub value (e.g. a stray ctx.header() call) onto a
|
|
51
|
+
// browser-facing response. The opt-in is the out-of-band brand.
|
|
52
|
+
if (name.toLowerCase() === EXTERNAL_REDIRECT_MARKER) return;
|
|
53
|
+
if (name.toLowerCase() === "set-cookie") {
|
|
54
|
+
target.append(name, value);
|
|
55
|
+
} else if (!target.has(name)) {
|
|
56
|
+
target.set(name, value);
|
|
57
|
+
}
|
|
58
|
+
} catch {
|
|
59
|
+
// Headers immutable — skip.
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Drain ctx._onResponseCallbacks onto a response. Swapping the array before
|
|
66
|
+
* iteration prevents re-entrant registrations from double-firing and matches
|
|
67
|
+
* the contract that each callback runs at most once per request.
|
|
68
|
+
*
|
|
69
|
+
* Exported so the testing primitives' buildRunResponse can reuse the exact
|
|
70
|
+
* production drain (swap-before-iterate + external-redirect brand preservation)
|
|
71
|
+
* rather than maintain a hand-synced copy. This module is plugin-rsc-free on its
|
|
72
|
+
* eager graph (dispatch.ts already statically imports from here in the same
|
|
73
|
+
* testing barrel), so importing it adds nothing to the unit runner's graph.
|
|
74
|
+
*/
|
|
75
|
+
export function drainOnResponseCallbacks(
|
|
76
|
+
ctx: RequestContext,
|
|
77
|
+
response: Response,
|
|
78
|
+
): Response {
|
|
79
|
+
const callbacks = ctx._onResponseCallbacks;
|
|
80
|
+
if (callbacks.length === 0) return response;
|
|
81
|
+
ctx._onResponseCallbacks = [];
|
|
82
|
+
// An onResponse callback may return a NEW Response (e.g. to add a header),
|
|
83
|
+
// which drops the out-of-band external-redirect brand (brand is keyed on
|
|
84
|
+
// Response object identity). Preserve a redirect(url, { external: true })
|
|
85
|
+
// opt-in across that rebuild so a callback can't silently neutralize the
|
|
86
|
+
// off-host redirect at the guard chokepoint.
|
|
87
|
+
const wasExternal = isExternalRedirect(response);
|
|
88
|
+
let result = response;
|
|
89
|
+
for (const callback of callbacks) {
|
|
90
|
+
result = callback(result) ?? result;
|
|
91
|
+
}
|
|
92
|
+
if (wasExternal && !isExternalRedirect(result)) {
|
|
93
|
+
markExternalRedirect(result);
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
8
97
|
|
|
9
98
|
/**
|
|
10
99
|
* Check if a request body has content to decode
|
|
@@ -27,38 +116,205 @@ export function hasBodyContent(body: FormData | string): boolean {
|
|
|
27
116
|
*/
|
|
28
117
|
export function createResponseWithMergedHeaders(
|
|
29
118
|
body: BodyInit | null,
|
|
30
|
-
init: ResponseInit
|
|
119
|
+
init: ResponseInit,
|
|
31
120
|
): Response {
|
|
32
|
-
const ctx =
|
|
121
|
+
const ctx = _getRequestContext();
|
|
33
122
|
if (!ctx) {
|
|
34
123
|
return new Response(body, init);
|
|
35
124
|
}
|
|
36
125
|
|
|
37
|
-
//
|
|
126
|
+
// Delete Set-Cookie from the stub after consuming so downstream merge
|
|
127
|
+
// points (e.g. executeMiddleware) don't duplicate them.
|
|
38
128
|
const mergedHeaders = new Headers(init.headers);
|
|
39
|
-
ctx.res.headers
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
} else if (!mergedHeaders.has(name)) {
|
|
43
|
-
// Only set if not already present in init.headers
|
|
44
|
-
mergedHeaders.set(name, value);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
129
|
+
applyStubHeaders(mergedHeaders, ctx.res.headers);
|
|
130
|
+
ctx.res.headers.delete("set-cookie");
|
|
131
|
+
applyCacheSignalHeader(mergedHeaders, ctx);
|
|
47
132
|
|
|
48
|
-
//
|
|
49
|
-
//
|
|
133
|
+
// ctx.res.status overrides init.status when explicitly set (e.g. 404 for
|
|
134
|
+
// notFound, 500 for error). Default ctx.res.status is 200.
|
|
50
135
|
const status = ctx.res.status !== 200 ? ctx.res.status : init.status;
|
|
51
136
|
|
|
52
|
-
|
|
137
|
+
const response = new Response(body, {
|
|
53
138
|
...init,
|
|
54
139
|
status,
|
|
55
140
|
headers: mergedHeaders,
|
|
56
141
|
});
|
|
57
142
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
143
|
+
return drainOnResponseCallbacks(ctx, response);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Create a 204 response with X-RSC-Redirect header for stateless redirects.
|
|
148
|
+
* Used during partial/action requests where fetch would auto-follow a raw
|
|
149
|
+
* 3xx to a URL that renders full HTML instead of Flight data. The 204 status
|
|
150
|
+
* prevents auto-follow; the client reads the header and re-navigates via
|
|
151
|
+
* the router.
|
|
152
|
+
*/
|
|
153
|
+
export function createSimpleRedirectResponse(redirectUrl: string): Response {
|
|
154
|
+
return createResponseWithMergedHeaders(null, {
|
|
155
|
+
status: 204,
|
|
156
|
+
headers: { "X-RSC-Redirect": redirectUrl },
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Carry over headers from a source redirect Response to a wrapper Response.
|
|
162
|
+
* Skips Location and X-RSC-Redirect (intentionally replaced by the wrapper) and
|
|
163
|
+
* appends Set-Cookie to avoid clobbering multiple cookie headers.
|
|
164
|
+
*
|
|
165
|
+
* This is a GENERIC copier used by every redirect-rebuild path (PE
|
|
166
|
+
* extractRedirectResponse, the SPA intercept below, the guard's neutralize
|
|
167
|
+
* rebuild), so it has two redirect-specific jobs:
|
|
168
|
+
*
|
|
169
|
+
* 1. NEVER copy the reserved external-redirect header: it is no longer a trust
|
|
170
|
+
* signal (the opt-in is the out-of-band brand), and a forged value from a
|
|
171
|
+
* proxied upstream must not ride a rebuilt response to the browser.
|
|
172
|
+
* 2. Transfer the out-of-band external brand: a rebuilt document-native redirect
|
|
173
|
+
* has to carry the opt-in to the guard chokepoint, which reads and clears it.
|
|
174
|
+
* Without this transfer, redirect(url, { external: true }) would be silently
|
|
175
|
+
* neutralized on any rebuild path (fail-closed, but a feature regression).
|
|
176
|
+
*/
|
|
177
|
+
export function carryOverRedirectHeaders(
|
|
178
|
+
source: Response,
|
|
179
|
+
target: Response,
|
|
180
|
+
): void {
|
|
181
|
+
source.headers.forEach((value, name) => {
|
|
182
|
+
const lower = name.toLowerCase();
|
|
183
|
+
if (lower === "location" || lower === "x-rsc-redirect") return;
|
|
184
|
+
if (lower === EXTERNAL_REDIRECT_MARKER) return;
|
|
185
|
+
if (lower === "set-cookie") {
|
|
186
|
+
target.headers.append(name, value);
|
|
187
|
+
} else if (!target.headers.has(name)) {
|
|
188
|
+
target.headers.set(name, value);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
if (isExternalRedirect(source)) {
|
|
192
|
+
markExternalRedirect(target);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* If a response is a 3xx redirect during a partial (client-side) request,
|
|
198
|
+
* intercept it and return a Flight-compatible redirect instead.
|
|
199
|
+
* fetch() auto-follows 3xx which would hit a URL that renders full HTML
|
|
200
|
+
* the client can't parse. Returns null if the response is not a redirect.
|
|
201
|
+
*/
|
|
202
|
+
export function interceptRedirectForPartial(
|
|
203
|
+
response: Response,
|
|
204
|
+
createRedirectFlightResponse: (
|
|
205
|
+
redirectUrl: string,
|
|
206
|
+
locationState?: Record<string, unknown>,
|
|
207
|
+
external?: boolean,
|
|
208
|
+
) => Response,
|
|
209
|
+
): Response | null {
|
|
210
|
+
if (!isRedirectResponse(response)) {
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
const redirectUrl = response.headers.get("Location")!;
|
|
214
|
+
// redirect(url, { external: true }) marks an explicit off-host redirect via
|
|
215
|
+
// the out-of-band brand (not a wire header). On the SPA/action channel the
|
|
216
|
+
// intent must travel as a Flight payload (metadata.redirect.external) so the
|
|
217
|
+
// client does a scheme-validated hard navigation (location.assign) rather than
|
|
218
|
+
// a partial fetch. The client re-validates the scheme; see partial-update.ts.
|
|
219
|
+
const external = isExternalRedirect(response);
|
|
220
|
+
const locationState = getLocationState();
|
|
221
|
+
let intercepted: Response;
|
|
222
|
+
if (locationState) {
|
|
223
|
+
intercepted = createRedirectFlightResponse(
|
|
224
|
+
redirectUrl,
|
|
225
|
+
resolveLocationStateEntries(locationState),
|
|
226
|
+
external,
|
|
227
|
+
);
|
|
228
|
+
} else if (external) {
|
|
229
|
+
intercepted = createRedirectFlightResponse(redirectUrl, undefined, true);
|
|
230
|
+
} else {
|
|
231
|
+
intercepted = createSimpleRedirectResponse(redirectUrl);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
carryOverRedirectHeaders(response, intercepted);
|
|
235
|
+
// Defense-in-depth at the SPA browser-facing exit: carryOverRedirectHeaders
|
|
236
|
+
// already refuses to copy the reserved marker, but strip any value that might
|
|
237
|
+
// exist on `intercepted` so a forged header can never ride the 200/204 to the
|
|
238
|
+
// browser. The external intent travels in metadata.redirect.external (Flight),
|
|
239
|
+
// where the client re-validates the scheme.
|
|
240
|
+
try {
|
|
241
|
+
intercepted.headers.delete(EXTERNAL_REDIRECT_MARKER);
|
|
242
|
+
} catch {
|
|
243
|
+
// Immutable headers: the marker was never copied here, so this is inert.
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return intercepted;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Attach location state set during a request to a payload's metadata.
|
|
251
|
+
* No-op if no location state was set. Callers must ensure payload.metadata
|
|
252
|
+
* is populated (the non-null assertion holds for the partial/action payloads
|
|
253
|
+
* that reach this helper).
|
|
254
|
+
*/
|
|
255
|
+
export function attachLocationStateIfPresent(payload: RscPayload): void {
|
|
256
|
+
const locationState = getLocationState();
|
|
257
|
+
if (locationState) {
|
|
258
|
+
payload.metadata!.locationState =
|
|
259
|
+
resolveLocationStateEntries(locationState);
|
|
61
260
|
}
|
|
261
|
+
}
|
|
62
262
|
|
|
63
|
-
|
|
263
|
+
/**
|
|
264
|
+
* Only cache successful responses. Non-200 statuses (errors, redirects) are
|
|
265
|
+
* not cached -- notFound() produces 500 in response routes, and explicit
|
|
266
|
+
* non-200 Responses are rare enough that caching them would be surprising.
|
|
267
|
+
*/
|
|
268
|
+
export function isCacheableStatus(status: number): boolean {
|
|
269
|
+
return status === 200;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Convert route-level middleware entries to the format expected by
|
|
274
|
+
* executeMiddleware. Route middleware from previewMatch carries just
|
|
275
|
+
* { handler, params }; this wraps them in the full MiddlewareEntry shape.
|
|
276
|
+
*/
|
|
277
|
+
export function buildRouteMiddlewareEntries<TEnv>(
|
|
278
|
+
routeMiddleware: Array<{
|
|
279
|
+
handler: MiddlewareFn;
|
|
280
|
+
params: Record<string, string>;
|
|
281
|
+
}>,
|
|
282
|
+
): Array<{ entry: MiddlewareEntry<TEnv>; params: Record<string, string> }> {
|
|
283
|
+
return routeMiddleware.map((mw) => ({
|
|
284
|
+
entry: {
|
|
285
|
+
pattern: null,
|
|
286
|
+
regex: null,
|
|
287
|
+
paramNames: [],
|
|
288
|
+
handler: mw.handler,
|
|
289
|
+
} as MiddlewareEntry<TEnv>,
|
|
290
|
+
params: mw.params,
|
|
291
|
+
}));
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Merge stub headers from the request context onto an existing Response in
|
|
296
|
+
* place, then drain onResponse callbacks. Used when a Response cannot flow
|
|
297
|
+
* through `new Response()` — status 101 is outside the constructor's
|
|
298
|
+
* 200-599 range, and the Cloudflare-specific `webSocket` property would be
|
|
299
|
+
* lost on reconstruction.
|
|
300
|
+
*/
|
|
301
|
+
export function mergeStubHeadersAndFinalize(response: Response): Response {
|
|
302
|
+
const ctx = _getRequestContext();
|
|
303
|
+
if (!ctx) return response;
|
|
304
|
+
|
|
305
|
+
applyStubHeaders(response.headers, ctx.res.headers);
|
|
306
|
+
ctx.res.headers.delete("set-cookie");
|
|
307
|
+
|
|
308
|
+
return drainOnResponseCallbacks(ctx, response);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Run onResponse callbacks on an existing Response. Used by code paths that
|
|
313
|
+
* bypass createResponseWithMergedHeaders (e.g. middleware short-circuits)
|
|
314
|
+
* but still need ctx.onResponse() callbacks to fire.
|
|
315
|
+
*/
|
|
316
|
+
export function finalizeResponse(response: Response): Response {
|
|
317
|
+
const ctx = _getRequestContext();
|
|
318
|
+
if (!ctx) return response;
|
|
319
|
+
return drainOnResponseCallbacks(ctx, response);
|
|
64
320
|
}
|
package/src/rsc/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Rango - RSC Entry Point
|
|
3
3
|
*
|
|
4
4
|
* This module provides RSC utilities for server-side rendering,
|
|
5
5
|
* server actions, loader fetching, and progressive enhancement.
|
|
@@ -29,28 +29,5 @@ export type {
|
|
|
29
29
|
NonceProvider,
|
|
30
30
|
} from "./types.js";
|
|
31
31
|
|
|
32
|
-
// Re-export HandleStore types for consumers who need custom handling
|
|
33
|
-
export {
|
|
34
|
-
createHandleStore,
|
|
35
|
-
type HandleStore,
|
|
36
|
-
type HandleData,
|
|
37
|
-
} from "../server/handle-store.js";
|
|
38
|
-
|
|
39
32
|
// Re-export request context utilities for server-side access to env/request/params
|
|
40
|
-
export {
|
|
41
|
-
getRequestContext,
|
|
42
|
-
requireRequestContext,
|
|
43
|
-
setRequestContextParams,
|
|
44
|
-
} from "../server/request-context.js";
|
|
45
|
-
|
|
46
|
-
// Re-export cache store types and implementations
|
|
47
|
-
export type {
|
|
48
|
-
SegmentCacheStore,
|
|
49
|
-
CachedEntryData,
|
|
50
|
-
CachedEntryResult,
|
|
51
|
-
SegmentCacheProvider,
|
|
52
|
-
SegmentHandleData,
|
|
53
|
-
} from "../cache/types.js";
|
|
54
|
-
|
|
55
|
-
export { MemorySegmentCacheStore } from "../cache/memory-segment-store.js";
|
|
56
|
-
export { CFCacheStore, type CFCacheStoreOptions } from "../cache/cf/index.js";
|
|
33
|
+
export { getRequestContext } from "../server/request-context.js";
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared serialization for `json()` response-route results.
|
|
3
|
+
*
|
|
4
|
+
* Kept in its own lightweight module (depends only on `errors.js`) so the
|
|
5
|
+
* `dispatch()` testing primitive can import it WITHOUT dragging in
|
|
6
|
+
* `response-route-handler.ts`'s heavy runtime graph, which transitively reaches
|
|
7
|
+
* a Vite virtual module and breaks a plain (non-Vite) vitest import.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { RouterError } from "../errors.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Serialize a `json()` response-route result, rejecting a nested unresolved
|
|
14
|
+
* Promise (the forgotten-await footgun: `() => ({ data: fetchSomething() })`).
|
|
15
|
+
* `JSON.stringify` would silently emit `{}` for a Promise, shipping empty data;
|
|
16
|
+
* the RSC pipeline awaits nested promises but this path does not. Throwing
|
|
17
|
+
* `RESPONSE_NOT_SERIALIZABLE` makes the failure loud.
|
|
18
|
+
*
|
|
19
|
+
* Shared by the production response-route handler and the `dispatch()` testing
|
|
20
|
+
* primitive so a `dispatch` json test of a forgotten await fails exactly where
|
|
21
|
+
* production 500s, instead of going green.
|
|
22
|
+
*/
|
|
23
|
+
export function stringifyJsonRouteResult(result: unknown): string {
|
|
24
|
+
return JSON.stringify(result, (_key, value) => {
|
|
25
|
+
if (
|
|
26
|
+
value != null &&
|
|
27
|
+
typeof (value as { then?: unknown }).then === "function"
|
|
28
|
+
) {
|
|
29
|
+
throw new RouterError(
|
|
30
|
+
"RESPONSE_NOT_SERIALIZABLE",
|
|
31
|
+
"A json() response route returned a Promise (likely a forgotten " +
|
|
32
|
+
"await). Await async values before returning so they serialize, " +
|
|
33
|
+
"instead of emitting an empty {}.",
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return value;
|
|
37
|
+
});
|
|
38
|
+
}
|