@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.
- package/AGENTS.md +8 -4
- package/README.md +303 -741
- package/dist/bin/rango.js +730 -184
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +4344 -1335
- package/dist/vite/index.js.bak +5448 -0
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +86 -15
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +85 -6
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +251 -24
- package/skills/caching/SKILL.md +375 -17
- package/skills/catalog.json +271 -0
- 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 +110 -4
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +5 -3
- package/skills/defer-hydration/SKILL.md +235 -0
- package/skills/document-cache/SKILL.md +87 -56
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +73 -691
- package/skills/hooks/data.md +273 -0
- package/skills/hooks/handle-and-actions.md +103 -0
- package/skills/hooks/navigation.md +110 -0
- package/skills/hooks/outlets.md +41 -0
- package/skills/hooks/state.md +228 -0
- package/skills/hooks/urls.md +135 -0
- package/skills/host-router/SKILL.md +129 -27
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +94 -18
- package/skills/layout/SKILL.md +62 -19
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +302 -54
- package/skills/middleware/SKILL.md +59 -16
- package/skills/migrate-nextjs/SKILL.md +745 -0
- package/skills/migrate-react-router/SKILL.md +153 -0
- package/skills/migrate-react-router/cloudflare-workers.md +129 -0
- package/skills/migrate-react-router/component-migration.md +196 -0
- package/skills/migrate-react-router/data-and-actions.md +225 -0
- package/skills/migrate-react-router/route-mapping.md +271 -0
- package/skills/mime-routes/SKILL.md +29 -2
- package/skills/observability/SKILL.md +202 -0
- package/skills/parallel/SKILL.md +225 -10
- package/skills/ppr/SKILL.md +622 -0
- package/skills/prerender/SKILL.md +178 -124
- package/skills/rango/SKILL.md +318 -24
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +138 -49
- package/skills/route/SKILL.md +172 -9
- package/skills/router-setup/SKILL.md +131 -11
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +776 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +130 -0
- 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 +1 -1
- package/skills/typesafety/SKILL.md +45 -616
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +335 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +74 -15
- 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 +1 -66
- package/src/browser/action-coordinator.ts +53 -36
- 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 +257 -158
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/logging.ts +28 -0
- package/src/browser/merge-segment-loaders.ts +6 -4
- package/src/browser/navigation-bridge.ts +132 -33
- package/src/browser/navigation-client.ts +218 -68
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +203 -80
- package/src/browser/navigation-transaction.ts +18 -66
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +241 -127
- package/src/browser/prefetch/cache.ts +271 -44
- package/src/browser/prefetch/fetch.ts +367 -40
- package/src/browser/prefetch/queue.ts +144 -23
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +121 -16
- package/src/browser/react/NavigationProvider.tsx +240 -122
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +23 -69
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +33 -8
- package/src/browser/react/use-navigation.ts +32 -7
- package/src/browser/react/use-params.ts +20 -10
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +46 -11
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +11 -21
- package/src/browser/response-adapter.ts +99 -8
- package/src/browser/rsc-router.tsx +272 -80
- package/src/browser/scroll-restoration.ts +56 -22
- package/src/browser/segment-reconciler.ts +44 -7
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +244 -71
- package/src/browser/types.ts +136 -12
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +207 -158
- package/src/build/generate-route-types.ts +6 -1
- package/src/build/index.ts +11 -3
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +198 -41
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +16 -5
- package/src/build/route-types/include-resolution.ts +464 -63
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +22 -6
- package/src/build/route-types/router-processing.ts +336 -110
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +13 -21
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +58 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +454 -97
- package/src/cache/cache-scope.ts +235 -103
- package/src/cache/cache-tag.ts +149 -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 +2446 -170
- 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 +11 -17
- package/src/cache/document-cache.ts +144 -49
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +24 -20
- package/src/cache/memory-segment-store.ts +243 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +13 -21
- package/src/cache/shell-snapshot.ts +417 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +55 -0
- package/src/cache/types.ts +194 -99
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1132 -0
- package/src/client.rsc.tsx +41 -21
- package/src/client.tsx +116 -290
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +108 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +84 -2
- package/src/debug.ts +2 -2
- 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 +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +104 -34
- package/src/handles/MetaTags.tsx +24 -53
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +35 -8
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +14 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +13 -22
- package/src/host/index.ts +9 -2
- package/src/host/pattern-matcher.ts +23 -52
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +100 -13
- package/src/index.ts +143 -19
- package/src/internal-debug.ts +11 -10
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +20 -13
- package/src/loader.ts +12 -11
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +215 -86
- package/src/redirect-origin.ts +114 -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 +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +485 -303
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +153 -77
- package/src/route-definition/index.ts +4 -2
- package/src/route-definition/redirect.ts +53 -12
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +48 -21
- package/src/route-types.ts +37 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +164 -17
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +130 -29
- package/src/router/handler-context.ts +83 -39
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +50 -24
- package/src/router/lazy-includes.ts +89 -63
- package/src/router/loader-resolution.ts +286 -56
- package/src/router/logging.ts +5 -8
- package/src/router/manifest.ts +105 -56
- package/src/router/match-api.ts +178 -218
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +211 -165
- package/src/router/match-middleware/background-revalidation.ts +66 -22
- package/src/router/match-middleware/cache-lookup.ts +214 -263
- package/src/router/match-middleware/cache-store.ts +105 -50
- package/src/router/match-middleware/intercept-resolution.ts +8 -28
- package/src/router/match-middleware/segment-resolution.ts +52 -18
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +128 -44
- package/src/router/metrics.ts +5 -34
- package/src/router/middleware-types.ts +13 -142
- package/src/router/middleware.ts +301 -177
- 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 +181 -150
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +203 -58
- package/src/router/preview-match.ts +35 -103
- package/src/router/request-classification.ts +291 -0
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +256 -0
- package/src/router/router-context.ts +11 -29
- package/src/router/router-interfaces.ts +146 -35
- package/src/router/router-options.ts +202 -15
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +301 -78
- package/src/router/segment-resolution/helpers.ts +115 -30
- package/src/router/segment-resolution/loader-cache.ts +156 -39
- package/src/router/segment-resolution/loader-mask.ts +60 -0
- package/src/router/segment-resolution/loader-snapshot.ts +259 -0
- package/src/router/segment-resolution/mask-nested.ts +83 -0
- package/src/router/segment-resolution/revalidation.ts +477 -385
- package/src/router/segment-resolution/static-store.ts +19 -5
- 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 +5 -1
- package/src/router/segment-wrappers.ts +8 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +105 -20
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -59
- package/src/router/types.ts +10 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +210 -71
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +682 -508
- package/src/rsc/helpers.ts +168 -46
- package/src/rsc/index.ts +2 -5
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +127 -31
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +138 -15
- package/src/rsc/redirect-guard.ts +100 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +99 -189
- package/src/rsc/rsc-rendering.ts +509 -73
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +287 -113
- package/src/rsc/shell-capture.ts +1190 -0
- package/src/rsc/shell-serve.ts +181 -0
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +62 -6
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +167 -0
- package/src/segment-system.tsx +449 -132
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +367 -61
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +152 -5
- package/src/server/handle-store.ts +40 -38
- package/src/server/loader-registry.ts +38 -46
- package/src/server/request-context.ts +558 -173
- package/src/ssr/index.tsx +491 -174
- package/src/ssr/inject-rsc-eager.ts +167 -0
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +27 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +813 -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 +56 -84
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +17 -8
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +234 -82
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +44 -15
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +19 -7
- package/src/types/segments.ts +137 -14
- package/src/urls/include-helper.ts +40 -75
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -11
- package/src/urls/path-helper-types.ts +102 -23
- package/src/urls/path-helper.ts +62 -111
- package/src/urls/pattern-types.ts +84 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +98 -154
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +346 -89
- 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 +36 -38
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +130 -85
- 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 +214 -132
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +57 -6
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +15 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +234 -62
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- package/src/vite/plugins/client-ref-dedup.ts +16 -11
- package/src/vite/plugins/client-ref-hashing.ts +28 -15
- 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/plugins/expose-action-id.ts +49 -98
- package/src/vite/plugins/expose-id-utils.ts +96 -51
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +15 -64
- package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
- package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
- package/src/vite/plugins/expose-internal-ids.ts +553 -317
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +46 -37
- package/src/vite/plugins/virtual-entries.ts +138 -27
- package/src/vite/rango.ts +353 -303
- package/src/vite/router-discovery.ts +1090 -166
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +4 -4
- package/src/vite/utils/bundle-analysis.ts +10 -15
- 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 +4 -59
- package/src/vite/utils/package-resolution.ts +20 -52
- package/src/vite/utils/prerender-utils.ts +98 -38
- package/src/vite/utils/shared-utils.ts +144 -44
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/react/use-client-cache.ts +0 -58
- package/src/browser/shallow.ts +0 -40
- package/src/handles/index.ts +0 -7
- package/src/network-error-thrower.tsx +0 -23
- package/src/router/middleware-cookies.ts +0 -55
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import type { ReactNode } from "react";
|
|
9
9
|
import { _getRequestContext } from "../../server/request-context.js";
|
|
10
10
|
import type { StaticStore } from "../../prerender/store.js";
|
|
11
|
+
import type { SegmentHandleData } from "../../cache/types.js";
|
|
11
12
|
|
|
12
13
|
// Lazy-initialized static store for production Static handler interception.
|
|
13
14
|
// Remains undefined until first check; null means checked but no manifest.
|
|
@@ -19,6 +20,9 @@ let _staticStore: StaticStore | null | undefined =
|
|
|
19
20
|
? undefined
|
|
20
21
|
: null;
|
|
21
22
|
let _deserializeComponent: ((encoded: string) => Promise<unknown>) | undefined;
|
|
23
|
+
let _decodeHandleValue:
|
|
24
|
+
| typeof import("../../cache/handle-snapshot.js").decodeHandleValue
|
|
25
|
+
| undefined;
|
|
22
26
|
|
|
23
27
|
async function ensureStaticDeps(): Promise<void> {
|
|
24
28
|
if (_staticStore === undefined) {
|
|
@@ -29,6 +33,9 @@ async function ensureStaticDeps(): Promise<void> {
|
|
|
29
33
|
const { deserializeComponent } =
|
|
30
34
|
await import("../../cache/segment-codec.js");
|
|
31
35
|
_deserializeComponent = deserializeComponent;
|
|
36
|
+
const { decodeHandleValue } =
|
|
37
|
+
await import("../../cache/handle-snapshot.js");
|
|
38
|
+
_decodeHandleValue = decodeHandleValue;
|
|
32
39
|
}
|
|
33
40
|
}
|
|
34
41
|
|
|
@@ -53,13 +60,20 @@ export async function tryStaticLookup(
|
|
|
53
60
|
const entry = await _staticStore.get(handlerId);
|
|
54
61
|
if (!entry) return undefined;
|
|
55
62
|
|
|
56
|
-
// Replay handle data captured during build-time rendering.
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
|
|
63
|
+
// Replay handle data captured during build-time rendering. entry.handles is a
|
|
64
|
+
// Flight-encoded string ("" when none) — decode before replay so
|
|
65
|
+
// Promise/ReactNode handle values are revived. The data was keyed by handlerId
|
|
66
|
+
// at build time; replay under segmentId so it matches the segment order used
|
|
67
|
+
// by useHandle on the client.
|
|
68
|
+
if (entry.handles && _decodeHandleValue) {
|
|
60
69
|
const handleStore = _getRequestContext()?._handleStore;
|
|
61
70
|
if (handleStore) {
|
|
62
|
-
|
|
71
|
+
const segHandles = await _decodeHandleValue<SegmentHandleData>(
|
|
72
|
+
entry.handles,
|
|
73
|
+
);
|
|
74
|
+
if (segHandles) {
|
|
75
|
+
handleStore.replaySegmentData(segmentId, segHandles);
|
|
76
|
+
}
|
|
63
77
|
}
|
|
64
78
|
}
|
|
65
79
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streamed Handler Telemetry
|
|
3
|
+
*
|
|
4
|
+
* Shared fire-and-forget rejection observer for streamed handler promises,
|
|
5
|
+
* used by both the fresh and revalidation segment-resolution paths. Lives in
|
|
6
|
+
* its own module (never mocked) so the resolution unit tests that mock
|
|
7
|
+
* helpers.js / telemetry.js with explicit export lists do not resolve it to
|
|
8
|
+
* undefined.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { ReactNode } from "react";
|
|
12
|
+
import { getRouterContext } from "../router-context.js";
|
|
13
|
+
import { resolveSink, safeEmit } from "../telemetry.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Attach a fire-and-forget rejection observer to a streamed handler promise.
|
|
17
|
+
* React catches the actual error via its error boundary; this only emits
|
|
18
|
+
* the handler.error telemetry event.
|
|
19
|
+
*/
|
|
20
|
+
export function observeStreamedHandler(
|
|
21
|
+
promise: Promise<ReactNode>,
|
|
22
|
+
segmentId: string,
|
|
23
|
+
segmentType: string,
|
|
24
|
+
pathname?: string,
|
|
25
|
+
routeKey?: string,
|
|
26
|
+
params?: Record<string, string>,
|
|
27
|
+
): void {
|
|
28
|
+
let routerCtx;
|
|
29
|
+
try {
|
|
30
|
+
routerCtx = getRouterContext();
|
|
31
|
+
} catch {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (!routerCtx?.telemetry) return;
|
|
35
|
+
const sink = resolveSink(routerCtx.telemetry);
|
|
36
|
+
const reqId = routerCtx.requestId;
|
|
37
|
+
promise.catch((err: unknown) => {
|
|
38
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
39
|
+
safeEmit(sink, {
|
|
40
|
+
type: "handler.error",
|
|
41
|
+
timestamp: performance.now(),
|
|
42
|
+
requestId: reqId,
|
|
43
|
+
segmentId,
|
|
44
|
+
segmentType,
|
|
45
|
+
error: errorObj,
|
|
46
|
+
handledByBoundary: true,
|
|
47
|
+
pathname,
|
|
48
|
+
routeKey,
|
|
49
|
+
params,
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* View-transition boundary default resolution.
|
|
3
|
+
*
|
|
4
|
+
* Kept in its own module (rather than helpers.ts) because several resolution
|
|
5
|
+
* tests mock helpers.ts with an explicit export list; a shared util here is
|
|
6
|
+
* never mocked, so the fresh and revalidation paths always get the real
|
|
7
|
+
* implementation.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { EntryData } from "../../server/context";
|
|
11
|
+
import { getRequestContext } from "../../server/request-context.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a segment's transition config: stamp the `viewTransition` default and
|
|
15
|
+
* peel off a transition({ when }) predicate.
|
|
16
|
+
*
|
|
17
|
+
* `viewTransition`: the per-segment value (set via the transition() DSL) always
|
|
18
|
+
* wins. When it is unset, the router-level createRouter({ viewTransition })
|
|
19
|
+
* default is stamped in so the render gate reads the boundary decision off the
|
|
20
|
+
* segment — server and client, via the serialized segment — without the router
|
|
21
|
+
* option being threaded to the client. Only `false` is ever stamped; an unset
|
|
22
|
+
* (or "auto") value is left untouched because it already means "wrap" at the
|
|
23
|
+
* gate, which also avoids needless object allocation and payload growth.
|
|
24
|
+
*
|
|
25
|
+
* `when`: a server-only predicate. It is STRIPPED from the returned config (a
|
|
26
|
+
* function cannot cross Flight or the segment cache) and recorded on the request
|
|
27
|
+
* context keyed by `segmentId`, so rsc-rendering can evaluate it post-handler —
|
|
28
|
+
* outside any cache scope — and drop this segment's transition when it returns
|
|
29
|
+
* false. Used by both the fresh and revalidation resolution paths.
|
|
30
|
+
*/
|
|
31
|
+
export function applyViewTransitionDefault(
|
|
32
|
+
transition: EntryData["transition"],
|
|
33
|
+
viewTransitionDefault: "auto" | false | undefined,
|
|
34
|
+
segmentId?: string,
|
|
35
|
+
): EntryData["transition"] {
|
|
36
|
+
if (!transition) return transition;
|
|
37
|
+
let result = transition;
|
|
38
|
+
if (result.when) {
|
|
39
|
+
if (segmentId !== undefined) {
|
|
40
|
+
try {
|
|
41
|
+
const ctx = getRequestContext();
|
|
42
|
+
(ctx._transitionWhen ??= []).push({ id: segmentId, when: result.when });
|
|
43
|
+
} catch {
|
|
44
|
+
// No active request context (e.g. a unit test calling this util
|
|
45
|
+
// directly). Skip collection; the strip below still applies so the
|
|
46
|
+
// serialized config never carries the function.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const { when: _when, ...rest } = result;
|
|
50
|
+
result = rest;
|
|
51
|
+
}
|
|
52
|
+
if (result.viewTransition === undefined && viewTransitionDefault === false) {
|
|
53
|
+
return { ...result, viewTransition: false };
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
// Barrel re-export -- see segment-resolution/ for implementations.
|
|
2
|
-
export {
|
|
2
|
+
export {
|
|
3
|
+
handleHandlerResult,
|
|
4
|
+
warnOnStreamedResponse,
|
|
5
|
+
buildLoaderErrorContext,
|
|
6
|
+
} from "./segment-resolution/helpers.js";
|
|
3
7
|
export {
|
|
4
8
|
resolveLoaders,
|
|
5
9
|
type ResolveSegmentOptions,
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
ShouldRevalidateFn,
|
|
6
6
|
} from "../types";
|
|
7
7
|
import type { SegmentResolutionDeps } from "./types.js";
|
|
8
|
+
import type { ResolveSegmentOptions } from "./segment-resolution.js";
|
|
8
9
|
|
|
9
10
|
import {
|
|
10
11
|
resolveAllSegments as _resolveAllSegments,
|
|
@@ -29,7 +30,7 @@ export interface SegmentWrappers<TEnv = any> {
|
|
|
29
30
|
params: Record<string, string>,
|
|
30
31
|
context: HandlerContext<any, TEnv>,
|
|
31
32
|
loaderPromises: Map<string, Promise<any>>,
|
|
32
|
-
options?:
|
|
33
|
+
options?: ResolveSegmentOptions,
|
|
33
34
|
) => Promise<ResolvedSegment[]>;
|
|
34
35
|
resolveLoadersOnly: (
|
|
35
36
|
entries: EntryData[],
|
|
@@ -68,7 +69,6 @@ export interface SegmentWrappers<TEnv = any> {
|
|
|
68
69
|
request: Request,
|
|
69
70
|
prevUrl: URL,
|
|
70
71
|
nextUrl: URL,
|
|
71
|
-
loaderPromises: Map<string, Promise<any>>,
|
|
72
72
|
actionContext:
|
|
73
73
|
| {
|
|
74
74
|
actionId?: string;
|
|
@@ -94,6 +94,7 @@ export interface SegmentWrappers<TEnv = any> {
|
|
|
94
94
|
context: HandlerContext<any, TEnv>,
|
|
95
95
|
belongsToRoute?: boolean,
|
|
96
96
|
revalidationContext?: any,
|
|
97
|
+
options?: { skipMiddleware?: boolean },
|
|
97
98
|
) => Promise<ResolvedSegment[]>;
|
|
98
99
|
resolveInterceptLoadersOnly: (
|
|
99
100
|
interceptEntry: InterceptEntry,
|
|
@@ -124,7 +125,7 @@ export function createSegmentWrappers<TEnv = any>(
|
|
|
124
125
|
params: Record<string, string>,
|
|
125
126
|
context: HandlerContext<any, TEnv>,
|
|
126
127
|
loaderPromises: Map<string, Promise<any>>,
|
|
127
|
-
options?:
|
|
128
|
+
options?: ResolveSegmentOptions,
|
|
128
129
|
): ReturnType<typeof _resolveAllSegments> {
|
|
129
130
|
return _resolveAllSegments(
|
|
130
131
|
entries,
|
|
@@ -192,7 +193,6 @@ export function createSegmentWrappers<TEnv = any>(
|
|
|
192
193
|
request: Request,
|
|
193
194
|
prevUrl: URL,
|
|
194
195
|
nextUrl: URL,
|
|
195
|
-
loaderPromises: Map<string, Promise<any>>,
|
|
196
196
|
actionContext:
|
|
197
197
|
| {
|
|
198
198
|
actionId?: string;
|
|
@@ -204,6 +204,7 @@ export function createSegmentWrappers<TEnv = any>(
|
|
|
204
204
|
interceptResult: { intercept: InterceptEntry; entry: EntryData } | null,
|
|
205
205
|
localRouteName: string,
|
|
206
206
|
pathname: string,
|
|
207
|
+
stale?: boolean,
|
|
207
208
|
): ReturnType<typeof _resolveAllSegmentsWithRevalidation> {
|
|
208
209
|
return _resolveAllSegmentsWithRevalidation(
|
|
209
210
|
entries,
|
|
@@ -215,12 +216,12 @@ export function createSegmentWrappers<TEnv = any>(
|
|
|
215
216
|
request,
|
|
216
217
|
prevUrl,
|
|
217
218
|
nextUrl,
|
|
218
|
-
loaderPromises,
|
|
219
219
|
actionContext,
|
|
220
220
|
interceptResult,
|
|
221
221
|
localRouteName,
|
|
222
222
|
pathname,
|
|
223
223
|
segmentDeps,
|
|
224
|
+
stale,
|
|
224
225
|
);
|
|
225
226
|
}
|
|
226
227
|
|
|
@@ -245,6 +246,7 @@ export function createSegmentWrappers<TEnv = any>(
|
|
|
245
246
|
context: HandlerContext<any, TEnv>,
|
|
246
247
|
belongsToRoute: boolean = true,
|
|
247
248
|
revalidationContext?: any,
|
|
249
|
+
options?: { skipMiddleware?: boolean },
|
|
248
250
|
): ReturnType<typeof _resolveInterceptEntry> {
|
|
249
251
|
return _resolveInterceptEntry(
|
|
250
252
|
interceptEntry,
|
|
@@ -254,6 +256,7 @@ export function createSegmentWrappers<TEnv = any>(
|
|
|
254
256
|
belongsToRoute,
|
|
255
257
|
segmentDeps,
|
|
256
258
|
revalidationContext,
|
|
259
|
+
options,
|
|
257
260
|
);
|
|
258
261
|
}
|
|
259
262
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { DEFAULT_STATE_COOKIE_PREFIX } from "../browser/cookie-name.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the rango state cookie name once, server-side, at router init. The
|
|
5
|
+
* resolved string is shipped in payload metadata and the client reads it
|
|
6
|
+
* verbatim, so composition happens in exactly one place.
|
|
7
|
+
*
|
|
8
|
+
* Shape: `{sanitizedPrefix}_{sanitizedRouterId}`. The prefix charset excludes
|
|
9
|
+
* `_` so the FIRST `_` is always the prefix/routerId boundary; that keeps the
|
|
10
|
+
* name injective even though a routerId may legitimately contain `_` (the
|
|
11
|
+
* counter fallback is `router_{n}`). Without that exclusion, prefix
|
|
12
|
+
* `rango-state` + id `router_0` and prefix `rango-state_router` + id `0` would
|
|
13
|
+
* both resolve to `rango-state_router_0` and silently share a cache key.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
// Prefix excludes `_` so it can never collide with the separator.
|
|
17
|
+
function sanitizePrefix(prefix: string): string {
|
|
18
|
+
return prefix.replace(/[^A-Za-z0-9-]/g, "");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// routerId keeps `_` (so `router_0` survives); other illegal chars are dropped.
|
|
22
|
+
function sanitizeRouterId(routerId: string): string {
|
|
23
|
+
return routerId.replace(/[^A-Za-z0-9_-]/g, "");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function resolveStateCookieName(
|
|
27
|
+
prefix: string | undefined,
|
|
28
|
+
routerId: string,
|
|
29
|
+
): string {
|
|
30
|
+
const sanitized = sanitizePrefix(prefix ?? DEFAULT_STATE_COOKIE_PREFIX);
|
|
31
|
+
const finalPrefix = sanitized || DEFAULT_STATE_COOKIE_PREFIX;
|
|
32
|
+
return `${finalPrefix}_${sanitizeRouterId(routerId)}`;
|
|
33
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { encodePathSegment, encodePathRemainder } from "./url-params.js";
|
|
2
|
+
import { parsePattern } from "./parse-pattern.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Substitute `:param` placeholders in a route pattern with values from
|
|
6
|
+
* `params`, producing a URL. Built by walking the SAME parsed segments the
|
|
7
|
+
* matcher uses (`parsePattern`) and emitting one piece per segment — so a
|
|
8
|
+
* substituted value is never re-scanned as if it were another placeholder (a
|
|
9
|
+
* catch-all value like `sha:abc/x` used to make the "required" pass read `:abc`
|
|
10
|
+
* and throw). Constraint syntax (`:name(en|gb)`) is stripped; trailing-slash
|
|
11
|
+
* patterns like `/blog/` are preserved unless an optional segment was omitted.
|
|
12
|
+
*
|
|
13
|
+
* Semantics per segment:
|
|
14
|
+
* - static -> emitted verbatim.
|
|
15
|
+
* - `:name` -> required; `undefined` throws, `""` yields an empty segment.
|
|
16
|
+
* - `:name?` -> optional; `undefined`/`""` omitted.
|
|
17
|
+
* - `:name*` / `:name+`-> catch-all; the value is multi-segment, so each segment
|
|
18
|
+
* is encoded and the `/` separators are preserved. `+`
|
|
19
|
+
* (one-or-more) throws when absent; `*` (and bare `*`)
|
|
20
|
+
* omit when absent.
|
|
21
|
+
*
|
|
22
|
+
* Shared by `ctx.reverse()` (server), `createReverse()` (typed runtime
|
|
23
|
+
* helper), and `useReverse()` (client hook). The behavior must stay
|
|
24
|
+
* identical across all three call sites.
|
|
25
|
+
*/
|
|
26
|
+
export function substitutePatternParams(
|
|
27
|
+
pattern: string,
|
|
28
|
+
params: Record<string, string | undefined>,
|
|
29
|
+
routeName: string,
|
|
30
|
+
): string {
|
|
31
|
+
const hasTrailingSlash = pattern.length > 1 && pattern.endsWith("/");
|
|
32
|
+
const normalized = hasTrailingSlash ? pattern.slice(0, -1) : pattern;
|
|
33
|
+
const segments = parsePattern(normalized);
|
|
34
|
+
|
|
35
|
+
const parts: string[] = [];
|
|
36
|
+
for (const seg of segments) {
|
|
37
|
+
if (seg.type === "static") {
|
|
38
|
+
parts.push("/" + seg.value);
|
|
39
|
+
} else if (seg.type === "wildcard") {
|
|
40
|
+
const value = params[seg.value];
|
|
41
|
+
if (value === undefined || value === "") {
|
|
42
|
+
// `:name+` requires at least one segment; bare `*` / `:name*` collapse.
|
|
43
|
+
if (seg.oneOrMore) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`Missing param "${seg.value}" for route "${routeName}"`,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
parts.push("/" + encodePathRemainder(value));
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
// Plain param. Constraint (`seg.constraint`) is intentionally not re-emitted.
|
|
53
|
+
const value = params[seg.value];
|
|
54
|
+
const suffix = seg.suffix ?? "";
|
|
55
|
+
if (seg.optional) {
|
|
56
|
+
// The matcher omits absent optionals (`undefined`); callers/getParams()
|
|
57
|
+
// may pass `""` explicitly — treat both as absent.
|
|
58
|
+
if (value !== undefined && value !== "") {
|
|
59
|
+
parts.push("/" + encodePathSegment(value) + suffix);
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
if (value === undefined) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`Missing param "${seg.value}" for route "${routeName}"`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
parts.push("/" + encodePathSegment(value) + suffix);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let result = parts.join("") || "/";
|
|
73
|
+
if (hasTrailingSlash && !result.endsWith("/")) result += "/";
|
|
74
|
+
return result;
|
|
75
|
+
}
|