@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
|
@@ -11,15 +11,24 @@ import type {
|
|
|
11
11
|
InterceptEntry,
|
|
12
12
|
InterceptSelectorContext,
|
|
13
13
|
} from "../server/context";
|
|
14
|
-
import type {
|
|
14
|
+
import type {
|
|
15
|
+
HandlerContext,
|
|
16
|
+
InternalHandlerContext,
|
|
17
|
+
ResolvedSegment,
|
|
18
|
+
} from "../types";
|
|
15
19
|
import { evaluateRevalidation } from "./revalidation.js";
|
|
16
20
|
import { getRequestContext } from "../server/request-context.js";
|
|
17
21
|
import { executeInterceptMiddleware } from "./middleware.js";
|
|
18
22
|
import { createReverseFunction } from "./handler-context.js";
|
|
19
23
|
import { getGlobalRouteMap } from "../route-map-builder.js";
|
|
20
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
handleHandlerResult,
|
|
26
|
+
warnOnStreamedResponse,
|
|
27
|
+
buildLoaderErrorContext,
|
|
28
|
+
} from "./segment-resolution.js";
|
|
21
29
|
import type { SegmentResolutionDeps } from "./types.js";
|
|
22
30
|
import { debugLog } from "./logging.js";
|
|
31
|
+
import { runInsideLoaderScope } from "../server/context.js";
|
|
23
32
|
|
|
24
33
|
/**
|
|
25
34
|
* Check if an intercept's when conditions are satisfied.
|
|
@@ -61,28 +70,14 @@ export function findInterceptForRoute(
|
|
|
61
70
|
let current: EntryData | null = fromEntry;
|
|
62
71
|
|
|
63
72
|
while (current) {
|
|
64
|
-
|
|
65
|
-
|
|
73
|
+
// current first, then its sibling layouts — same order as before.
|
|
74
|
+
for (const source of [current, ...current.layout]) {
|
|
75
|
+
for (const intercept of source.intercept) {
|
|
66
76
|
if (
|
|
67
77
|
intercept.routeName === targetRouteKey &&
|
|
68
78
|
evaluateInterceptWhen(intercept, selectorContext, isAction)
|
|
69
79
|
) {
|
|
70
|
-
return { intercept, entry:
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (current.layout && current.layout.length > 0) {
|
|
76
|
-
for (const siblingLayout of current.layout) {
|
|
77
|
-
if (siblingLayout.intercept && siblingLayout.intercept.length > 0) {
|
|
78
|
-
for (const intercept of siblingLayout.intercept) {
|
|
79
|
-
if (
|
|
80
|
-
intercept.routeName === targetRouteKey &&
|
|
81
|
-
evaluateInterceptWhen(intercept, selectorContext, isAction)
|
|
82
|
-
) {
|
|
83
|
-
return { intercept, entry: siblingLayout };
|
|
84
|
-
}
|
|
85
|
-
}
|
|
80
|
+
return { intercept, entry: source };
|
|
86
81
|
}
|
|
87
82
|
}
|
|
88
83
|
}
|
|
@@ -118,10 +113,25 @@ export async function resolveInterceptEntry<TEnv>(
|
|
|
118
113
|
};
|
|
119
114
|
stale?: boolean;
|
|
120
115
|
},
|
|
116
|
+
options?: {
|
|
117
|
+
/**
|
|
118
|
+
* Skip the intercept's middleware execution. Set ONLY by the post-response
|
|
119
|
+
* background re-render paths (proactive caching, stale background
|
|
120
|
+
* revalidation), whose sole purpose is to re-render the segment tree to
|
|
121
|
+
* populate the cache. The foreground request already ran the intercept
|
|
122
|
+
* middleware before the response was sent — it validated auth, set cookies,
|
|
123
|
+
* and wrote context vars into the request context's shared `_variables`,
|
|
124
|
+
* which the background render reuses. Re-running middleware here would fire
|
|
125
|
+
* its side effects a SECOND time, and a middleware that short-circuits with
|
|
126
|
+
* a Response would `throw` and silently abort the cache write. Never set on
|
|
127
|
+
* the foreground path.
|
|
128
|
+
*/
|
|
129
|
+
skipMiddleware?: boolean;
|
|
130
|
+
},
|
|
121
131
|
): Promise<ResolvedSegment[]> {
|
|
122
132
|
const segments: ResolvedSegment[] = [];
|
|
123
133
|
|
|
124
|
-
if (interceptEntry.middleware.length > 0) {
|
|
134
|
+
if (!options?.skipMiddleware && interceptEntry.middleware.length > 0) {
|
|
125
135
|
const requestCtx = getRequestContext();
|
|
126
136
|
if (!requestCtx?.res) {
|
|
127
137
|
throw new Error(
|
|
@@ -133,7 +143,7 @@ export async function resolveInterceptEntry<TEnv>(
|
|
|
133
143
|
context.request,
|
|
134
144
|
context.env,
|
|
135
145
|
params,
|
|
136
|
-
context
|
|
146
|
+
(context as InternalHandlerContext<any, TEnv>)._variables,
|
|
137
147
|
requestCtx.res,
|
|
138
148
|
createReverseFunction(getGlobalRouteMap()),
|
|
139
149
|
);
|
|
@@ -188,6 +198,7 @@ export async function resolveInterceptEntry<TEnv>(
|
|
|
188
198
|
context,
|
|
189
199
|
actionContext,
|
|
190
200
|
stale,
|
|
201
|
+
traceSource: "intercept-loader",
|
|
191
202
|
});
|
|
192
203
|
|
|
193
204
|
if (!shouldRevalidate) {
|
|
@@ -206,10 +217,13 @@ export async function resolveInterceptEntry<TEnv>(
|
|
|
206
217
|
loaderIds.push(loader.$$id);
|
|
207
218
|
loaderPromises.push(
|
|
208
219
|
deps.wrapLoaderPromise(
|
|
209
|
-
context.use(loader),
|
|
220
|
+
runInsideLoaderScope(() => context.use(loader)),
|
|
210
221
|
parentEntry,
|
|
211
222
|
segmentId,
|
|
212
223
|
context.pathname,
|
|
224
|
+
// Report a throwing intercept loader to onError + loader.error telemetry,
|
|
225
|
+
// matching the fresh/revalidation paths.
|
|
226
|
+
buildLoaderErrorContext(context),
|
|
213
227
|
),
|
|
214
228
|
);
|
|
215
229
|
}
|
|
@@ -236,6 +250,12 @@ export async function resolveInterceptEntry<TEnv>(
|
|
|
236
250
|
let loaderDataPromise: Promise<any[]> | any[] | undefined;
|
|
237
251
|
|
|
238
252
|
if (interceptEntry.loading && loaderPromises.length > 0) {
|
|
253
|
+
if (handlerResult instanceof Promise) {
|
|
254
|
+
warnOnStreamedResponse(
|
|
255
|
+
handlerResult,
|
|
256
|
+
`intercept ${interceptEntry.slotName}`,
|
|
257
|
+
);
|
|
258
|
+
}
|
|
239
259
|
component =
|
|
240
260
|
handlerResult instanceof Promise
|
|
241
261
|
? handlerResult
|
|
@@ -355,6 +375,7 @@ export async function resolveInterceptLoadersOnly<TEnv>(
|
|
|
355
375
|
context,
|
|
356
376
|
actionContext,
|
|
357
377
|
stale,
|
|
378
|
+
traceSource: "intercept-loader",
|
|
358
379
|
});
|
|
359
380
|
|
|
360
381
|
if (!shouldRevalidate) {
|
|
@@ -372,10 +393,15 @@ export async function resolveInterceptLoadersOnly<TEnv>(
|
|
|
372
393
|
loaderIds.push(loader.$$id);
|
|
373
394
|
loaderPromises.push(
|
|
374
395
|
deps.wrapLoaderPromise(
|
|
375
|
-
context.use(loader),
|
|
396
|
+
runInsideLoaderScope(() => context.use(loader)),
|
|
376
397
|
parentEntry,
|
|
377
398
|
segmentId,
|
|
378
399
|
context.pathname,
|
|
400
|
+
// Report a throwing intercept loader to onError + loader.error telemetry,
|
|
401
|
+
// matching the fresh/revalidation paths. resolveInterceptLoadersOnly is
|
|
402
|
+
// only called on the cache-hit partial-update path (handleCacheHitIntercept),
|
|
403
|
+
// so flag isPartial:true exactly like revalidation.ts's partial path.
|
|
404
|
+
{ ...buildLoaderErrorContext(context), isPartial: true },
|
|
379
405
|
),
|
|
380
406
|
);
|
|
381
407
|
}
|
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
import { registerRouteMap } from "../route-map-builder.js";
|
|
2
|
-
import { extractStaticPrefix } from "./pattern-matching.js";
|
|
2
|
+
import { extractStaticPrefix, joinPrefix } from "./pattern-matching.js";
|
|
3
3
|
import {
|
|
4
|
-
EntryData,
|
|
5
|
-
|
|
4
|
+
type EntryData,
|
|
5
|
+
RangoContext,
|
|
6
6
|
runWithPrefixes,
|
|
7
|
+
getIsolatedLazyParent,
|
|
7
8
|
} from "../server/context";
|
|
8
9
|
import type { UrlPatterns } from "../urls.js";
|
|
9
10
|
import type { AllUseItems, IncludeItem } from "../route-types.js";
|
|
10
11
|
import type { ResolvedRouteMap, RouteEntry, TrailingSlashMode } from "../types";
|
|
12
|
+
import {
|
|
13
|
+
isIncludeProvider,
|
|
14
|
+
resolveIncludeModule,
|
|
15
|
+
} from "../urls/include-provider.js";
|
|
11
16
|
|
|
12
17
|
export interface LazyEvalDeps<TEnv = any> {
|
|
13
18
|
routesEntries: RouteEntry<TEnv>[];
|
|
14
19
|
mergedRouteMap: Record<string, string>;
|
|
15
20
|
nextMountIndex: () => number;
|
|
16
21
|
getPrecomputedByPrefix: () => Map<string, Record<string, string>> | null;
|
|
22
|
+
routerId?: string;
|
|
17
23
|
}
|
|
18
24
|
|
|
19
|
-
// Detect lazy includes in handler result and create placeholder entries
|
|
20
|
-
// Lazy includes are IncludeItem with lazy: true and _lazyContext
|
|
21
|
-
// Moved to outer scope so it can be reused by evaluateLazyEntry for nested includes
|
|
22
25
|
export function findLazyIncludes<TEnv = any>(
|
|
23
26
|
items: AllUseItems[],
|
|
24
27
|
): Array<{
|
|
@@ -54,7 +57,6 @@ export function findLazyIncludes<TEnv = any>(
|
|
|
54
57
|
});
|
|
55
58
|
}
|
|
56
59
|
}
|
|
57
|
-
// Recursively check nested items (in layouts, etc.)
|
|
58
60
|
if ((item as any).uses && Array.isArray((item as any).uses)) {
|
|
59
61
|
lazyItems.push(...findLazyIncludes((item as any).uses));
|
|
60
62
|
}
|
|
@@ -71,19 +73,11 @@ export function findLazyIncludes<TEnv = any>(
|
|
|
71
73
|
export function evaluateLazyEntry<TEnv = any>(
|
|
72
74
|
entry: RouteEntry<TEnv>,
|
|
73
75
|
deps: LazyEvalDeps<TEnv>,
|
|
74
|
-
): void {
|
|
76
|
+
): void | Promise<void> {
|
|
75
77
|
if (!entry.lazy || entry.lazyEvaluated || !entry.lazyPatterns) {
|
|
76
78
|
return;
|
|
77
79
|
}
|
|
78
80
|
|
|
79
|
-
// Check for pre-computed routes from build-time data.
|
|
80
|
-
// Only leaf nodes (no nested includes) are precomputed, so entries with
|
|
81
|
-
// nested lazy includes fall through to the handler below.
|
|
82
|
-
// When multiple entries share the same staticPrefix (e.g., several
|
|
83
|
-
// include("/", ...) calls), the precomputed data merges all their routes
|
|
84
|
-
// into one entry. Assigning that merged set to the first matching entry
|
|
85
|
-
// causes findMatch to pick the wrong handler for routes belonging to a
|
|
86
|
-
// different include. Skip the shortcut when the prefix is shared.
|
|
87
81
|
const currentPrecomputed = deps.getPrecomputedByPrefix();
|
|
88
82
|
if (currentPrecomputed) {
|
|
89
83
|
const routes = currentPrecomputed.get(entry.staticPrefix);
|
|
@@ -97,56 +91,91 @@ export function evaluateLazyEntry<TEnv = any>(
|
|
|
97
91
|
for (const [name, pattern] of Object.entries(routes)) {
|
|
98
92
|
deps.mergedRouteMap[name] = pattern;
|
|
99
93
|
}
|
|
100
|
-
|
|
94
|
+
// Register only this entry's routes (the delta): the full
|
|
95
|
+
// mergedRouteMap is seeded from the generated manifest at
|
|
96
|
+
// createRouter() time and already registered there — re-passing it
|
|
97
|
+
// made this request-path call O(total routes) (issue #666).
|
|
98
|
+
registerRouteMap(routes);
|
|
101
99
|
return;
|
|
102
100
|
}
|
|
103
101
|
}
|
|
104
102
|
}
|
|
105
103
|
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
|
|
104
|
+
// Async provider (`() => import("./routes")`): the route module is evaluated
|
|
105
|
+
// off the startup path, on the first request reaching this prefix. Concurrent
|
|
106
|
+
// first-hits share one in-flight promise so the import + expansion run exactly
|
|
107
|
+
// once. The eager path below stays fully synchronous (no Promise), so the
|
|
108
|
+
// per-entry match loop pays no microtask for normal includes.
|
|
109
|
+
const lazyPatterns = entry.lazyPatterns;
|
|
110
|
+
if (isIncludeProvider(lazyPatterns)) {
|
|
111
|
+
const inflight = (entry as { _lazyInflight?: Promise<void> })._lazyInflight;
|
|
112
|
+
if (inflight) return inflight;
|
|
113
|
+
const work = (async () => {
|
|
114
|
+
const resolved = resolveIncludeModule(
|
|
115
|
+
await lazyPatterns(),
|
|
116
|
+
entry.staticPrefix,
|
|
117
|
+
);
|
|
118
|
+
// Cache the resolved patterns: any later re-entry expands synchronously.
|
|
119
|
+
entry.lazyPatterns = resolved as unknown as UrlPatterns<TEnv>;
|
|
120
|
+
runExpansion(entry, deps, resolved as UrlPatterns<TEnv>);
|
|
121
|
+
})();
|
|
122
|
+
(entry as { _lazyInflight?: Promise<void> })._lazyInflight = work;
|
|
123
|
+
const clear = () => {
|
|
124
|
+
(entry as { _lazyInflight?: Promise<void> })._lazyInflight = undefined;
|
|
125
|
+
};
|
|
126
|
+
// On failure, clear the flag (lazyEvaluated stays false) so a later request
|
|
127
|
+
// can retry the import rather than wedging the route permanently.
|
|
128
|
+
work.then(clear, clear);
|
|
129
|
+
return work;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
runExpansion(entry, deps, lazyPatterns as UrlPatterns<TEnv>);
|
|
133
|
+
}
|
|
110
134
|
|
|
111
|
-
|
|
135
|
+
/**
|
|
136
|
+
* Synchronously expand a lazy entry's (already-resolved) patterns into routes
|
|
137
|
+
* and splice any nested lazy includes as new entries. Runs once per entry.
|
|
138
|
+
*/
|
|
139
|
+
function runExpansion<TEnv = any>(
|
|
140
|
+
entry: RouteEntry<TEnv>,
|
|
141
|
+
deps: LazyEvalDeps<TEnv>,
|
|
142
|
+
lazyPatterns: UrlPatterns<TEnv>,
|
|
143
|
+
): void {
|
|
144
|
+
// lazyEvaluated is set at the END, only after the handler ran and the routes
|
|
145
|
+
// (and any nested includes) were spliced. Setting it up-front would mark the
|
|
146
|
+
// entry done even if the handler throws mid-expansion: the async provider
|
|
147
|
+
// path clears _lazyInflight on rejection so a later request can retry, but a
|
|
148
|
+
// premature lazyEvaluated=true would make evaluateLazyEntry short-circuit
|
|
149
|
+
// (line ~77) forever, wedging the route at 404 until the isolate restarts.
|
|
112
150
|
const lazyContext = entry.lazyContext;
|
|
113
151
|
|
|
114
|
-
// Create a new context for evaluating the lazy patterns
|
|
115
152
|
const manifest = new Map<string, EntryData>();
|
|
116
153
|
const patterns = new Map<string, string>();
|
|
117
154
|
const patternsByPrefix = new Map<string, Map<string, string>>();
|
|
118
155
|
const trailingSlashMap = new Map<string, TrailingSlashMode>();
|
|
119
156
|
|
|
120
|
-
// Capture the handler result to detect nested lazy includes
|
|
121
157
|
let handlerResult: AllUseItems[] = [];
|
|
122
158
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (lazyContext && (lazyContext as any).counters) {
|
|
127
|
-
const captured = (lazyContext as any).counters as Record<string, number>;
|
|
128
|
-
for (const [key, value] of Object.entries(captured)) {
|
|
129
|
-
lazyCounters[key] = value;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
159
|
+
const lazyCounters: Record<string, number> = lazyContext?.counters
|
|
160
|
+
? { ...lazyContext.counters }
|
|
161
|
+
: {};
|
|
132
162
|
|
|
133
|
-
|
|
163
|
+
RangoContext.run(
|
|
134
164
|
{
|
|
135
165
|
manifest,
|
|
136
166
|
patterns,
|
|
137
167
|
patternsByPrefix,
|
|
138
168
|
trailingSlash: trailingSlashMap,
|
|
139
169
|
namespace: "lazy",
|
|
140
|
-
parent: (lazyContext?.parent as EntryData | null)
|
|
170
|
+
parent: getIsolatedLazyParent(lazyContext?.parent as EntryData | null),
|
|
141
171
|
counters: lazyCounters,
|
|
142
|
-
cacheProfiles:
|
|
143
|
-
rootScoped:
|
|
172
|
+
cacheProfiles: lazyContext?.cacheProfiles,
|
|
173
|
+
rootScoped: lazyContext?.rootScoped,
|
|
174
|
+
includeScope: lazyContext?.includeScope,
|
|
144
175
|
},
|
|
145
176
|
() => {
|
|
146
|
-
// Run the lazy patterns handler with the original context prefixes
|
|
147
|
-
// The prefix comes from the IncludeItem stored in lazyPatterns
|
|
148
177
|
const includePrefix = (entry as any)._lazyPrefix || "";
|
|
149
|
-
const fullPrefix = (lazyContext?.urlPrefix
|
|
178
|
+
const fullPrefix = joinPrefix(lazyContext?.urlPrefix, includePrefix);
|
|
150
179
|
|
|
151
180
|
if (fullPrefix || lazyContext?.namePrefix) {
|
|
152
181
|
runWithPrefixes(fullPrefix, lazyContext?.namePrefix, () => {
|
|
@@ -158,11 +187,9 @@ export function evaluateLazyEntry<TEnv = any>(
|
|
|
158
187
|
},
|
|
159
188
|
);
|
|
160
189
|
|
|
161
|
-
// Populate the entry's routes from the patterns
|
|
162
190
|
const routesObject: Record<string, string> = {};
|
|
163
191
|
for (const [name, pattern] of patterns.entries()) {
|
|
164
192
|
routesObject[name] = pattern;
|
|
165
|
-
// Also add to merged route map for reverse() support
|
|
166
193
|
const existingPattern = deps.mergedRouteMap[name];
|
|
167
194
|
if (existingPattern !== undefined && existingPattern !== pattern) {
|
|
168
195
|
console.warn(
|
|
@@ -173,45 +200,38 @@ export function evaluateLazyEntry<TEnv = any>(
|
|
|
173
200
|
deps.mergedRouteMap[name] = pattern;
|
|
174
201
|
}
|
|
175
202
|
|
|
176
|
-
// Update the entry in-place
|
|
177
203
|
entry.routes = routesObject as ResolvedRouteMap<any>;
|
|
178
204
|
|
|
179
|
-
// Note: Do NOT clear lazyPatterns/lazyContext here.
|
|
180
|
-
// loadManifest() needs them on every request to re-run the handler
|
|
181
|
-
// in the correct AsyncLocalStorage context (Store.manifest).
|
|
182
|
-
|
|
183
|
-
// Update trailing slash config if available
|
|
184
205
|
if (trailingSlashMap.size > 0) {
|
|
185
206
|
entry.trailingSlash = Object.fromEntries(trailingSlashMap);
|
|
186
207
|
}
|
|
187
208
|
|
|
188
|
-
// Detect nested lazy includes and register them as new entries
|
|
189
209
|
const nestedLazyIncludes = findLazyIncludes(handlerResult);
|
|
190
210
|
for (const lazyInclude of nestedLazyIncludes) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
211
|
+
const fullPrefix = joinPrefix(
|
|
212
|
+
lazyInclude.context.urlPrefix,
|
|
213
|
+
lazyInclude.prefix,
|
|
214
|
+
);
|
|
195
215
|
|
|
196
216
|
const nestedEntry: RouteEntry<TEnv> & { _lazyPrefix?: string } = {
|
|
197
217
|
prefix: "",
|
|
198
218
|
staticPrefix: extractStaticPrefix(fullPrefix),
|
|
199
|
-
routes: {} as ResolvedRouteMap<any>,
|
|
219
|
+
routes: {} as ResolvedRouteMap<any>,
|
|
200
220
|
trailingSlash: entry.trailingSlash,
|
|
201
|
-
handler
|
|
221
|
+
// include entries don't invoke their own handler (real handlers come from
|
|
222
|
+
// the expanded routes); use the parent's placeholder. A provider has no
|
|
223
|
+
// `.handler` until resolved, so never read it here.
|
|
224
|
+
handler: isIncludeProvider(lazyInclude.patterns)
|
|
225
|
+
? entry.handler
|
|
226
|
+
: (lazyInclude.patterns as UrlPatterns<TEnv>).handler,
|
|
202
227
|
mountIndex: deps.nextMountIndex(),
|
|
203
|
-
|
|
228
|
+
routerId: deps.routerId,
|
|
204
229
|
lazy: true,
|
|
205
230
|
lazyPatterns: lazyInclude.patterns,
|
|
206
231
|
lazyContext: lazyInclude.context,
|
|
207
232
|
lazyEvaluated: false,
|
|
208
|
-
// Store the include prefix for evaluation
|
|
209
233
|
_lazyPrefix: lazyInclude.prefix,
|
|
210
234
|
};
|
|
211
|
-
// Insert nested lazy entry before any entry whose staticPrefix is a
|
|
212
|
-
// prefix of (but shorter than) this lazy entry's staticPrefix.
|
|
213
|
-
// This ensures more specific lazy includes are matched before
|
|
214
|
-
// less specific eager entries (e.g., "/href/nested" before "/href/:id").
|
|
215
235
|
const nestedPrefix = nestedEntry.staticPrefix;
|
|
216
236
|
let insertIndex = deps.routesEntries.length;
|
|
217
237
|
if (nestedPrefix) {
|
|
@@ -229,6 +249,12 @@ export function evaluateLazyEntry<TEnv = any>(
|
|
|
229
249
|
deps.routesEntries.splice(insertIndex, 0, nestedEntry);
|
|
230
250
|
}
|
|
231
251
|
|
|
232
|
-
//
|
|
233
|
-
registerRouteMap(
|
|
252
|
+
// Delta only — see the matching comment on the precomputed branch above and
|
|
253
|
+
// the WHY block on registerRouteMap (issue #666).
|
|
254
|
+
registerRouteMap(routesObject);
|
|
255
|
+
|
|
256
|
+
// Expansion fully succeeded (handler ran, routes + nested includes spliced) —
|
|
257
|
+
// mark done now so a mid-expansion throw above leaves lazyEvaluated=false and
|
|
258
|
+
// the entry retriable.
|
|
259
|
+
entry.lazyEvaluated = true;
|
|
234
260
|
}
|