@rangojs/router 0.0.0-experimental.14 → 0.0.0-experimental.141
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 +293 -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 +2508 -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 +24 -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-snapshot.ts +368 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +153 -0
- package/src/cache/types.ts +222 -211
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1113 -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 +173 -35
- package/src/index.ts +241 -73
- 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 +527 -0
- package/src/rsc/runtime-warnings.ts +55 -0
- package/src/rsc/server-action.ts +522 -0
- package/src/rsc/shell-capture.ts +897 -0
- package/src/rsc/shell-serve.ts +124 -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 +459 -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/loader-registry.ts +51 -100
- package/src/server/request-context.ts +848 -157
- package/src/server.ts +15 -8
- package/src/ssr/index.tsx +443 -135
- 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 +76 -98
- 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 +44 -0
- package/src/urls/path-helper-types.ts +413 -0
- package/src/urls/path-helper.ts +280 -0
- package/src/urls/pattern-types.ts +160 -0
- package/src/urls/response-types.ts +109 -0
- package/src/urls/type-extraction.ts +316 -0
- package/src/urls/urls-function.ts +80 -0
- package/src/urls.ts +1 -1341
- package/src/use-loader.tsx +406 -141
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +182 -0
- package/src/vite/discovery/discover-routers.ts +389 -0
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +467 -0
- package/src/vite/discovery/route-types-writer.ts +214 -0
- package/src/vite/discovery/self-gen-tracking.ts +73 -0
- package/src/vite/discovery/state.ts +161 -0
- package/src/vite/discovery/virtual-module-codegen.ts +183 -0
- package/src/vite/index.ts +23 -2255
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +303 -0
- package/src/vite/plugins/cjs-to-esm.ts +90 -0
- package/src/vite/plugins/client-ref-dedup.ts +120 -0
- package/src/vite/plugins/client-ref-hashing.ts +118 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +88 -110
- package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +89 -79
- package/src/vite/plugins/expose-ids/export-analysis.ts +363 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +130 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +64 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +199 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +805 -0
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +313 -0
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +94 -0
- package/src/vite/plugins/version-plugin.ts +263 -0
- package/src/vite/plugins/virtual-entries.ts +234 -0
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +560 -0
- package/src/vite/router-discovery.ts +1638 -0
- package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +200 -37
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +132 -0
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +15 -0
- package/src/vite/utils/package-resolution.ts +89 -0
- package/src/vite/utils/prerender-utils.ts +249 -0
- package/src/vite/utils/shared-utils.ts +269 -0
- package/CLAUDE.md +0 -43
- package/dist/vite/index.named-routes.gen.ts +0 -103
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/react/use-client-cache.ts +0 -56
- package/src/browser/request-controller.ts +0 -164
- package/src/browser/shallow.ts +0 -35
- package/src/cache/memory-store.ts +0 -253
- package/src/handles/index.ts +0 -6
- package/src/href-context.ts +0 -33
- package/src/network-error-thrower.tsx +0 -21
- package/src/router.gen.ts +0 -6
- package/src/static-handler.gen.ts +0 -5
- package/src/urls.gen.ts +0 -8
- package/src/vite/expose-internal-ids.ts +0 -1167
- package/src/vite/package-resolution.ts +0 -125
- package/src/vite/virtual-entries.ts +0 -114
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Taint symbol for request-scoped objects.
|
|
3
|
+
*
|
|
4
|
+
* Objects branded with NOCACHE_SYMBOL (ctx, env, req) are excluded from
|
|
5
|
+
* "use cache" cache keys and trigger handle capture mode so that side
|
|
6
|
+
* effects (breadcrumbs, metadata) are recorded and replayed on cache hit.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export const NOCACHE_SYMBOL: unique symbol = Symbol.for("rango:nocache") as any;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Check if a value is tainted (request-scoped, should not be in cache key).
|
|
13
|
+
*/
|
|
14
|
+
export function isTainted(value: unknown): boolean {
|
|
15
|
+
return (
|
|
16
|
+
value !== null &&
|
|
17
|
+
value !== undefined &&
|
|
18
|
+
typeof value === "object" &&
|
|
19
|
+
(NOCACHE_SYMBOL as symbol) in (value as Record<symbol, unknown>)
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Symbol stamped on tainted ctx during "use cache" function execution.
|
|
25
|
+
* cookies(), headers(), ctx.set(), ctx.header(), etc. check this flag and
|
|
26
|
+
* throw if present — reads would cache per-request data under a shared key,
|
|
27
|
+
* and side effects would be lost on cache hit.
|
|
28
|
+
*
|
|
29
|
+
* The value is a numeric reference count, not a boolean. Multiple concurrent
|
|
30
|
+
* cached functions sharing the same ctx/requestCtx each increment on entry
|
|
31
|
+
* and decrement on exit. Guards fire when count > 0.
|
|
32
|
+
*/
|
|
33
|
+
export const INSIDE_CACHE_EXEC: unique symbol = Symbol.for(
|
|
34
|
+
"rango:inside-cache-exec",
|
|
35
|
+
) as any;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Increment the INSIDE_CACHE_EXEC ref count on an object.
|
|
39
|
+
*/
|
|
40
|
+
export function stampCacheExec(obj: object): void {
|
|
41
|
+
const current = (obj as any)[INSIDE_CACHE_EXEC] ?? 0;
|
|
42
|
+
(obj as any)[INSIDE_CACHE_EXEC] = current + 1;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Decrement the INSIDE_CACHE_EXEC ref count on an object.
|
|
47
|
+
* Deletes the symbol when the count reaches zero so the `in` check
|
|
48
|
+
* used by guards no longer fires.
|
|
49
|
+
*/
|
|
50
|
+
export function unstampCacheExec(obj: object): void {
|
|
51
|
+
const current = (obj as any)[INSIDE_CACHE_EXEC] ?? 0;
|
|
52
|
+
if (current <= 1) {
|
|
53
|
+
delete (obj as any)[INSIDE_CACHE_EXEC];
|
|
54
|
+
} else {
|
|
55
|
+
(obj as any)[INSIDE_CACHE_EXEC] = current - 1;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Throw if ctx is inside a "use cache" execution.
|
|
61
|
+
* Call from side-effecting ctx methods (set, header, etc.) and cookie mutations.
|
|
62
|
+
*/
|
|
63
|
+
export function assertNotInsideCacheExec(
|
|
64
|
+
ctx: unknown,
|
|
65
|
+
methodName: string,
|
|
66
|
+
): void {
|
|
67
|
+
if (
|
|
68
|
+
ctx !== null &&
|
|
69
|
+
ctx !== undefined &&
|
|
70
|
+
typeof ctx === "object" &&
|
|
71
|
+
(INSIDE_CACHE_EXEC as symbol) in (ctx as Record<symbol, unknown>)
|
|
72
|
+
) {
|
|
73
|
+
throw new Error(
|
|
74
|
+
`ctx.${methodName}() cannot be called inside a "use cache" function. ` +
|
|
75
|
+
`Side effects on the request context are lost on cache hit because ` +
|
|
76
|
+
`the function body is skipped. Extract the data fetch into a separate ` +
|
|
77
|
+
`cached function and call ctx.${methodName}() outside it, or use the ` +
|
|
78
|
+
`route-level cache() DSL which caches all segments (handler + children) ` +
|
|
79
|
+
`together.`,
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Symbol stamped on ctx when resolving handlers inside a cache() DSL boundary.
|
|
86
|
+
* Separate from INSIDE_CACHE_EXEC ("use cache") because cache() allows
|
|
87
|
+
* ctx.set() (children are also cached) but blocks response-level side effects
|
|
88
|
+
* (headers, cookies, status) which are lost on cache hit.
|
|
89
|
+
*/
|
|
90
|
+
export const INSIDE_CACHE_SCOPE: unique symbol = Symbol.for(
|
|
91
|
+
"rango:inside-cache-scope",
|
|
92
|
+
) as any;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Mark ctx as inside a cache() scope. Must be paired with unstampCacheScope.
|
|
96
|
+
*/
|
|
97
|
+
export function stampCacheScope(obj: object): void {
|
|
98
|
+
const current = (obj as any)[INSIDE_CACHE_SCOPE] ?? 0;
|
|
99
|
+
(obj as any)[INSIDE_CACHE_SCOPE] = current + 1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Remove cache() scope mark.
|
|
104
|
+
*/
|
|
105
|
+
export function unstampCacheScope(obj: object): void {
|
|
106
|
+
const current = (obj as any)[INSIDE_CACHE_SCOPE] ?? 0;
|
|
107
|
+
if (current <= 1) {
|
|
108
|
+
delete (obj as any)[INSIDE_CACHE_SCOPE];
|
|
109
|
+
} else {
|
|
110
|
+
(obj as any)[INSIDE_CACHE_SCOPE] = current - 1;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Throw if ctx is inside a cache() DSL boundary.
|
|
116
|
+
* Call from response-level side effects (header, setCookie, setStatus, etc.)
|
|
117
|
+
* which are lost on cache hit because the handler body is skipped.
|
|
118
|
+
* ctx.set() is allowed inside cache() — children are also cached and can
|
|
119
|
+
* read the value.
|
|
120
|
+
*/
|
|
121
|
+
export function assertNotInsideCacheScope(
|
|
122
|
+
ctx: unknown,
|
|
123
|
+
methodName: string,
|
|
124
|
+
): void {
|
|
125
|
+
if (
|
|
126
|
+
ctx !== null &&
|
|
127
|
+
ctx !== undefined &&
|
|
128
|
+
typeof ctx === "object" &&
|
|
129
|
+
(INSIDE_CACHE_SCOPE as symbol) in (ctx as Record<symbol, unknown>)
|
|
130
|
+
) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
`ctx.${methodName}() cannot be called inside a cache() boundary. ` +
|
|
133
|
+
`On cache hit the handler is skipped, so this side effect would be lost. ` +
|
|
134
|
+
`Move ctx.${methodName}() to a middleware or layout outside the cache() scope.`,
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Brand symbol for functions wrapped by registerCachedFunction().
|
|
141
|
+
* Used at runtime to detect when a "use cache" function is misused
|
|
142
|
+
* (e.g., passed as middleware).
|
|
143
|
+
*/
|
|
144
|
+
export const CACHED_FN_SYMBOL: unique symbol = Symbol.for(
|
|
145
|
+
"rango:cached-fn",
|
|
146
|
+
) as any;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Check if a value is a "use cache" wrapped function.
|
|
150
|
+
*/
|
|
151
|
+
export function isCachedFunction(value: unknown): boolean {
|
|
152
|
+
return typeof value === "function" && (CACHED_FN_SYMBOL as symbol) in value;
|
|
153
|
+
}
|
package/src/cache/types.ts
CHANGED
|
@@ -12,10 +12,6 @@
|
|
|
12
12
|
import type { ResolvedSegment } from "../types.js";
|
|
13
13
|
import type { RequestContext } from "../server/request-context.js";
|
|
14
14
|
|
|
15
|
-
// ============================================================================
|
|
16
|
-
// Segment Cache Store (low-level storage interface)
|
|
17
|
-
// ============================================================================
|
|
18
|
-
|
|
19
15
|
/**
|
|
20
16
|
* Result from cache get() including data and revalidation status
|
|
21
17
|
*/
|
|
@@ -75,14 +71,14 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
75
71
|
* @example Using cookies for locale
|
|
76
72
|
* ```typescript
|
|
77
73
|
* keyGenerator: (ctx, defaultKey) => {
|
|
78
|
-
* const locale =
|
|
74
|
+
* const locale = cookies().get('locale')?.value || 'en';
|
|
79
75
|
* return `${locale}:${defaultKey}`;
|
|
80
76
|
* }
|
|
81
77
|
* ```
|
|
82
78
|
*/
|
|
83
79
|
readonly keyGenerator?: (
|
|
84
80
|
ctx: RequestContext<TEnv>,
|
|
85
|
-
defaultKey: string
|
|
81
|
+
defaultKey: string,
|
|
86
82
|
) => string | Promise<string>;
|
|
87
83
|
|
|
88
84
|
/**
|
|
@@ -98,7 +94,12 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
98
94
|
* @param ttl - Time-to-live in seconds
|
|
99
95
|
* @param swr - Optional stale-while-revalidate window in seconds
|
|
100
96
|
*/
|
|
101
|
-
set(
|
|
97
|
+
set(
|
|
98
|
+
key: string,
|
|
99
|
+
data: CachedEntryData,
|
|
100
|
+
ttl: number,
|
|
101
|
+
swr?: number,
|
|
102
|
+
): Promise<void>;
|
|
102
103
|
|
|
103
104
|
/**
|
|
104
105
|
* Delete a cached entry
|
|
@@ -111,17 +112,13 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
111
112
|
*/
|
|
112
113
|
clear?(): Promise<void>;
|
|
113
114
|
|
|
114
|
-
// ============================================================================
|
|
115
|
-
// Document Cache Methods (optional)
|
|
116
|
-
// ============================================================================
|
|
117
|
-
// These methods are for caching full HTTP responses (document-level caching).
|
|
118
|
-
// Stores that support response caching should implement these methods.
|
|
119
|
-
|
|
120
115
|
/**
|
|
121
116
|
* Get a cached Response by key.
|
|
122
117
|
* Returns the response and whether it should be revalidated (SWR).
|
|
123
118
|
*/
|
|
124
|
-
getResponse?(
|
|
119
|
+
getResponse?(
|
|
120
|
+
key: string,
|
|
121
|
+
): Promise<{ response: Response; shouldRevalidate: boolean } | null>;
|
|
125
122
|
|
|
126
123
|
/**
|
|
127
124
|
* Store a Response with TTL and optional SWR window.
|
|
@@ -129,8 +126,202 @@ export interface SegmentCacheStore<TEnv = unknown> {
|
|
|
129
126
|
* @param response - Response to cache (will be cloned)
|
|
130
127
|
* @param ttl - Time-to-live in seconds
|
|
131
128
|
* @param swr - Optional stale-while-revalidate window in seconds
|
|
129
|
+
* @param tags - Optional cache tags for invalidation
|
|
130
|
+
*/
|
|
131
|
+
putResponse?(
|
|
132
|
+
key: string,
|
|
133
|
+
response: Response,
|
|
134
|
+
ttl: number,
|
|
135
|
+
swr?: number,
|
|
136
|
+
tags?: string[],
|
|
137
|
+
): Promise<void>;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Get a cached PPR shell entry by key.
|
|
141
|
+
* Returns the stored prelude/postponed pair (see ShellCacheEntry) and whether
|
|
142
|
+
* it should be revalidated (SWR). Used by the shell-cache middleware to serve
|
|
143
|
+
* a cached HTML shell and resume fizz for just the live holes.
|
|
144
|
+
*
|
|
145
|
+
* Optional: a store that does not implement the shell family disables the
|
|
146
|
+
* shell-cache middleware (it fails open to the normal HTML render path).
|
|
147
|
+
*/
|
|
148
|
+
getShell?(
|
|
149
|
+
key: string,
|
|
150
|
+
): Promise<{ entry: ShellCacheEntry; shouldRevalidate?: boolean } | null>;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Store a PPR shell entry with TTL and optional SWR window.
|
|
154
|
+
* The prelude bytes and postponed state are version- and generation-coupled
|
|
155
|
+
* and travel together in a single entry (they must never mix across a React
|
|
156
|
+
* upgrade — the reactVersion field on the entry gates that at read time).
|
|
157
|
+
* @param key - Cache key
|
|
158
|
+
* @param entry - The shell prelude/postponed/version/createdAt bundle
|
|
159
|
+
* @param ttlSeconds - Time-to-live in seconds
|
|
160
|
+
* @param swrSeconds - Optional stale-while-revalidate window in seconds
|
|
161
|
+
* @param tags - Optional cache tags for invalidation (participates in
|
|
162
|
+
* invalidateTags via the same tag machinery as the item family)
|
|
163
|
+
*/
|
|
164
|
+
putShell?(
|
|
165
|
+
key: string,
|
|
166
|
+
entry: ShellCacheEntry,
|
|
167
|
+
ttlSeconds?: number,
|
|
168
|
+
swrSeconds?: number,
|
|
169
|
+
tags?: string[],
|
|
170
|
+
): Promise<void>;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get a cached function result by key.
|
|
174
|
+
* Returns the serialized value, optional handle data, and staleness flag.
|
|
175
|
+
*/
|
|
176
|
+
getItem?(key: string): Promise<CacheItemResult | null>;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Store a function result with TTL and optional SWR window.
|
|
180
|
+
* @param key - Cache key (format: use-cache:{functionId}:{serializedArgs})
|
|
181
|
+
* @param value - RSC-serialized return value
|
|
182
|
+
* @param options - TTL, SWR, handle data, and tags
|
|
183
|
+
*/
|
|
184
|
+
setItem?(
|
|
185
|
+
key: string,
|
|
186
|
+
value: string,
|
|
187
|
+
options?: CacheItemOptions,
|
|
188
|
+
): Promise<void>;
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Invalidate every cache entry (segment, response, item) tagged with any of
|
|
192
|
+
* `tags`. Store-level primitive that the public updateTag()/revalidateTag()
|
|
193
|
+
* APIs delegate to. Receives ALL of one invalidation call's tags at once so
|
|
194
|
+
* stores can batch their work (e.g. a single CDN purge request rather than
|
|
195
|
+
* one per tag). Stores that do not support tags simply omit this method.
|
|
196
|
+
* @param tags - The cache tags to invalidate
|
|
132
197
|
*/
|
|
133
|
-
|
|
198
|
+
invalidateTags?(tags: string[]): Promise<void>;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Result from getItem() for function-level caching ("use cache").
|
|
203
|
+
*/
|
|
204
|
+
export interface CacheItemResult {
|
|
205
|
+
/** RSC-serialized return value */
|
|
206
|
+
value: string;
|
|
207
|
+
/** RSC-encoded handle data captured during execution (breadcrumbs, metadata,
|
|
208
|
+
* etc.). Encoded via the Flight codec so Promise/ReactNode handle values
|
|
209
|
+
* survive JSON-serializing stores — see handle-snapshot.ts encodeHandles. */
|
|
210
|
+
handles?: string;
|
|
211
|
+
/** Whether the entry is stale and should be revalidated */
|
|
212
|
+
shouldRevalidate: boolean;
|
|
213
|
+
/**
|
|
214
|
+
* The entry's cache tags (including runtime cacheTag() tags), surfaced on read
|
|
215
|
+
* so a "use cache" HIT can still contribute its tags to the request-scoped tag
|
|
216
|
+
* set used by document-level caching. On a hit the cached function is not
|
|
217
|
+
* re-run, so its runtime tags are only available here, not from re-execution.
|
|
218
|
+
*/
|
|
219
|
+
tags?: string[];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* A cached PPR (Partial Pre-rendering) shell entry.
|
|
224
|
+
*
|
|
225
|
+
* One entry carries BOTH artifacts a resume needs — the rendered HTML prelude
|
|
226
|
+
* and React's postponed state — because the pair is version- and
|
|
227
|
+
* generation-coupled and must never be mixed across a React upgrade or a build
|
|
228
|
+
* change. The reactVersion field is the read-time gate that enforces that: the
|
|
229
|
+
* shell-cache middleware treats an entry whose reactVersion differs from the
|
|
230
|
+
* running React as a miss (the postponed blob is build-coupled and cannot be
|
|
231
|
+
* resumed by a different React).
|
|
232
|
+
*/
|
|
233
|
+
export interface ShellCacheEntry {
|
|
234
|
+
/** Rendered HTML prelude bytes, base64-encoded (stores are JSON-serializing). */
|
|
235
|
+
prelude: string;
|
|
236
|
+
/**
|
|
237
|
+
* JSON.stringify of React's postponed state, or null when the shell settled
|
|
238
|
+
* with no holes (the DATA variant — served without a fizz resume).
|
|
239
|
+
*/
|
|
240
|
+
postponed: string | null;
|
|
241
|
+
/** React.version captured at prerender time; the read-time invalidation gate. */
|
|
242
|
+
reactVersion: string;
|
|
243
|
+
/**
|
|
244
|
+
* The initialTheme the CAPTURE render was built with (the derived context's
|
|
245
|
+
* reqCtx.theme). The resume tail must render ThemeProvider with the SAME
|
|
246
|
+
* initialTheme the frozen prelude was rendered with: React resume requires the
|
|
247
|
+
* tree above the holes to match the prerendered tree, and initialTheme is
|
|
248
|
+
* per-request METADATA, not part of the cached segments — a visitor whose
|
|
249
|
+
* theme differs from the capturer's would otherwise produce a divergent resume
|
|
250
|
+
* tree (broken stitching/hydration). The visitor's real theme is applied
|
|
251
|
+
* pre-paint by the FOUC script and re-synced from the cookie post-mount by
|
|
252
|
+
* ThemeProvider.
|
|
253
|
+
*/
|
|
254
|
+
initialTheme?: string;
|
|
255
|
+
/**
|
|
256
|
+
* The CAPTURE DATA SNAPSHOT: every cache-store read-hit and write the capture
|
|
257
|
+
* render performed, in stored/serialized form. Replaying these on a HIT (via
|
|
258
|
+
* the SeededShellStore overlay, for the tail render only) reproduces the
|
|
259
|
+
* shell's cached content byte-identically, so the freshly rendered hydration
|
|
260
|
+
* payload matches the frozen prelude even after the underlying cache entries
|
|
261
|
+
* have drifted (expired, been recomputed, or been tag-invalidated).
|
|
262
|
+
*
|
|
263
|
+
* Optional: an entry captured before this field existed simply has no
|
|
264
|
+
* snapshot and keeps the pre-snapshot behavior (the tail reads live, so any
|
|
265
|
+
* shell-baked cached value that drifted mismatches the prelude). Recapture
|
|
266
|
+
* heals it. See docs/design/ppr-shell-resume.md ("the capture data snapshot").
|
|
267
|
+
*/
|
|
268
|
+
snapshot?: ShellSnapshotRecord[];
|
|
269
|
+
/** Epoch ms when the shell was captured. */
|
|
270
|
+
createdAt: number;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* The cache-store families a shell snapshot pins. Excludes the shell family
|
|
275
|
+
* itself (getShell/putShell) — the snapshot rides INSIDE a shell entry, so
|
|
276
|
+
* recording it would be self-referential.
|
|
277
|
+
*/
|
|
278
|
+
export type ShellSnapshotFamily = "item" | "segment" | "response";
|
|
279
|
+
|
|
280
|
+
/** A serialized cached Response for the response family of a shell snapshot. */
|
|
281
|
+
export interface ShellSnapshotResponseValue {
|
|
282
|
+
status: number;
|
|
283
|
+
/** Client-facing header pairs (per-client signal headers excluded at record). */
|
|
284
|
+
headers: [string, string][];
|
|
285
|
+
/** base64-encoded response body (binary-safe, JSON-serializable). */
|
|
286
|
+
body: string;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** The stored form of an item-family (use cache / loader cache) snapshot value. */
|
|
290
|
+
export interface ShellSnapshotItemValue {
|
|
291
|
+
/** RSC-serialized return value. */
|
|
292
|
+
value: string;
|
|
293
|
+
/** RSC-encoded handle data, if any. */
|
|
294
|
+
handles?: string;
|
|
295
|
+
/** The entry's cache tags. */
|
|
296
|
+
tags?: string[];
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* One recorded cache-store read-hit or write from the capture render. `value`
|
|
301
|
+
* carries the entry in its stored/serialized shape so it round-trips through a
|
|
302
|
+
* JSON-serializing store (KV, CF, Vercel) with the rest of the ShellCacheEntry:
|
|
303
|
+
* - `item` -> {@link ShellSnapshotItemValue}
|
|
304
|
+
* - `segment` -> {@link CachedEntryData} (already JSON-able)
|
|
305
|
+
* - `response`-> {@link ShellSnapshotResponseValue}
|
|
306
|
+
*/
|
|
307
|
+
export interface ShellSnapshotRecord {
|
|
308
|
+
family: ShellSnapshotFamily;
|
|
309
|
+
key: string;
|
|
310
|
+
value: ShellSnapshotItemValue | CachedEntryData | ShellSnapshotResponseValue;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Options for setItem() for function-level caching ("use cache").
|
|
315
|
+
*/
|
|
316
|
+
export interface CacheItemOptions {
|
|
317
|
+
/** RSC-encoded handle data to store alongside the value (see encodeHandles). */
|
|
318
|
+
handles?: string;
|
|
319
|
+
/** Time-to-live in seconds */
|
|
320
|
+
ttl?: number;
|
|
321
|
+
/** Stale-while-revalidate window in seconds */
|
|
322
|
+
swr?: number;
|
|
323
|
+
/** Cache tags for invalidation */
|
|
324
|
+
tags?: string[];
|
|
134
325
|
}
|
|
135
326
|
|
|
136
327
|
/**
|
|
@@ -151,7 +342,10 @@ export interface SerializedSegmentData {
|
|
|
151
342
|
/** RSC-encoded loaderDataPromise (if present) */
|
|
152
343
|
encodedLoaderDataPromise?: string;
|
|
153
344
|
/** Segment metadata (everything except component, layout, loading, and loader data) */
|
|
154
|
-
metadata: Omit<
|
|
345
|
+
metadata: Omit<
|
|
346
|
+
ResolvedSegment,
|
|
347
|
+
"component" | "layout" | "loading" | "loaderData" | "loaderDataPromise"
|
|
348
|
+
>;
|
|
155
349
|
}
|
|
156
350
|
|
|
157
351
|
/**
|
|
@@ -162,16 +356,18 @@ export interface SerializedSegmentData {
|
|
|
162
356
|
export interface CachedEntryData {
|
|
163
357
|
/** Serialized segments for this entry */
|
|
164
358
|
segments: SerializedSegmentData[];
|
|
165
|
-
/**
|
|
166
|
-
|
|
359
|
+
/** RSC-encoded handle data keyed by segment ID. Encoded via the Flight codec
|
|
360
|
+
* (see handle-snapshot.ts encodeHandles) so Promise/ReactNode handle values
|
|
361
|
+
* round-trip through JSON-serializing stores instead of being flattened. */
|
|
362
|
+
handles: string;
|
|
167
363
|
/** Expiration timestamp (ms since epoch) */
|
|
168
364
|
expiresAt: number;
|
|
365
|
+
/** Cache tags for invalidation */
|
|
366
|
+
tags?: string[];
|
|
367
|
+
/** Timestamp (ms since epoch) when tags were attached, for distributed invalidation */
|
|
368
|
+
taggedAt?: number;
|
|
169
369
|
}
|
|
170
370
|
|
|
171
|
-
// ============================================================================
|
|
172
|
-
// Cache Configuration
|
|
173
|
-
// ============================================================================
|
|
174
|
-
|
|
175
371
|
/**
|
|
176
372
|
* Default cache options applied to all cache() boundaries.
|
|
177
373
|
* Individual cache() calls can override any of these values.
|
|
@@ -187,206 +383,21 @@ export interface CacheDefaults {
|
|
|
187
383
|
/**
|
|
188
384
|
* Default time-to-live in seconds.
|
|
189
385
|
* After TTL expires, cached entry is considered stale.
|
|
386
|
+
* Must be a finite, non-negative number; an invalid value (NaN/Infinity/
|
|
387
|
+
* negative) falls back to the default at read time.
|
|
190
388
|
*/
|
|
191
389
|
ttl?: number;
|
|
192
390
|
/**
|
|
193
391
|
* Default stale-while-revalidate window in seconds.
|
|
194
392
|
* During SWR window, stale content is served while revalidating in background.
|
|
393
|
+
* Must be a finite, non-negative number; an invalid value (NaN/Infinity/
|
|
394
|
+
* negative) falls back to the default at read time.
|
|
195
395
|
*/
|
|
196
396
|
swr?: number;
|
|
197
397
|
}
|
|
198
398
|
|
|
199
|
-
/**
|
|
200
|
-
* Cache configuration for RSC handler
|
|
201
|
-
*/
|
|
202
|
-
export interface CacheConfig {
|
|
203
|
-
/** Cache store implementation (includes defaults) */
|
|
204
|
-
store: SegmentCacheStore;
|
|
205
|
-
/** Enable/disable caching (default: true) */
|
|
206
|
-
enabled?: boolean;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/**
|
|
210
|
-
* Cache configuration - can be static or a function receiving env
|
|
211
|
-
*/
|
|
212
|
-
export type CacheConfigOrFactory<TEnv> =
|
|
213
|
-
| CacheConfig
|
|
214
|
-
| ((env: TEnv) => CacheConfig);
|
|
215
|
-
|
|
216
|
-
// ============================================================================
|
|
217
|
-
// Segment Cache Provider (request-level interface)
|
|
218
|
-
// ============================================================================
|
|
219
|
-
|
|
220
399
|
/**
|
|
221
400
|
* Handle data for a single segment
|
|
222
401
|
* Structure: { handleName: [values...] }
|
|
223
402
|
*/
|
|
224
403
|
export type SegmentHandleData = Record<string, unknown[]>;
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Result from cache get() including segments and their handle data
|
|
228
|
-
* Each entry can produce multiple segments (main + parallels)
|
|
229
|
-
*/
|
|
230
|
-
export interface CachedEntryResult {
|
|
231
|
-
/** All segments for this entry (main segment + parallels) */
|
|
232
|
-
segments: ResolvedSegment[];
|
|
233
|
-
/** Handle data keyed by segment ID */
|
|
234
|
-
handles: Record<string, SegmentHandleData>;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Segment cache provider interface
|
|
240
|
-
*
|
|
241
|
-
* Used by router to check/store segment cache during matching.
|
|
242
|
-
* Accessed via request context - if not present, caching is disabled.
|
|
243
|
-
*
|
|
244
|
-
* @internal Not currently implemented - CacheScope is used directly.
|
|
245
|
-
* Reserved for future extensibility.
|
|
246
|
-
*/
|
|
247
|
-
export interface SegmentCacheProvider {
|
|
248
|
-
/** Whether caching is enabled for this request */
|
|
249
|
-
readonly enabled: boolean;
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* Get cached segments and restore handles/loaders.
|
|
253
|
-
*
|
|
254
|
-
* Combines cache get with handle replay and loader data restoration.
|
|
255
|
-
* Returns tuple of [segments, segmentIds] if cache hit, null if miss or disabled.
|
|
256
|
-
*
|
|
257
|
-
* @param cacheKey - Cache key to look up
|
|
258
|
-
* @param params - Route params for cache key generation
|
|
259
|
-
* @param loaderPromises - Map to restore loader data into
|
|
260
|
-
* @returns Tuple of [segments, segmentIds] or null if miss
|
|
261
|
-
*/
|
|
262
|
-
restore(
|
|
263
|
-
cacheKey: string,
|
|
264
|
-
params: Record<string, string>,
|
|
265
|
-
loaderPromises: Map<string, Promise<any>>
|
|
266
|
-
): Promise<[ResolvedSegment[], string[]] | null>;
|
|
267
|
-
|
|
268
|
-
/**
|
|
269
|
-
* Cache entry with automatic handle collection (non-blocking).
|
|
270
|
-
*
|
|
271
|
-
* Schedules caching via waitUntil - handles are collected after they settle.
|
|
272
|
-
* Validates segments have actual components before caching.
|
|
273
|
-
*
|
|
274
|
-
* @param cacheKey - The cache key to store under
|
|
275
|
-
* @param segments - All resolved segments for this entry
|
|
276
|
-
*/
|
|
277
|
-
cacheEntry(cacheKey: string, segments: ResolvedSegment[]): void;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// ============================================================================
|
|
281
|
-
// Generic Cache Store (for future extensibility)
|
|
282
|
-
// ============================================================================
|
|
283
|
-
// These types support a general-purpose cache interface that can be used
|
|
284
|
-
// for caching arbitrary values (responses, streams, objects). Currently,
|
|
285
|
-
// the segment caching system uses SegmentCacheStore directly, but these
|
|
286
|
-
// types enable future use cases like response caching or data caching.
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* Supported cache value types for the generic CacheStore interface.
|
|
290
|
-
* @internal Reserved for future extensibility
|
|
291
|
-
*/
|
|
292
|
-
export type CacheValue =
|
|
293
|
-
| ReadableStream<Uint8Array>
|
|
294
|
-
| Response
|
|
295
|
-
| ArrayBuffer
|
|
296
|
-
| string
|
|
297
|
-
| unknown[] // JSON-serializable array
|
|
298
|
-
| Record<string, unknown>; // JSON-serializable object
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Cache entry returned by match().
|
|
302
|
-
* @internal Reserved for future extensibility
|
|
303
|
-
*/
|
|
304
|
-
export interface CacheEntry<T = CacheValue> {
|
|
305
|
-
/** The cached value */
|
|
306
|
-
value: T;
|
|
307
|
-
/** Optional metadata stored with the entry */
|
|
308
|
-
metadata?: CacheMetadata;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Original value type for reconstruction.
|
|
313
|
-
* @internal Reserved for future extensibility
|
|
314
|
-
*/
|
|
315
|
-
export type CacheValueType =
|
|
316
|
-
| "stream"
|
|
317
|
-
| "response"
|
|
318
|
-
| "arraybuffer"
|
|
319
|
-
| "string"
|
|
320
|
-
| "object";
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Metadata associated with a cache entry.
|
|
324
|
-
* @internal Reserved for future extensibility
|
|
325
|
-
*/
|
|
326
|
-
export interface CacheMetadata {
|
|
327
|
-
/** Timestamp when entry expires (ms since epoch) */
|
|
328
|
-
expiresAt?: number;
|
|
329
|
-
/** Tags for bulk invalidation */
|
|
330
|
-
tags?: string[];
|
|
331
|
-
/** Original value type for reconstruction on read */
|
|
332
|
-
valueType?: CacheValueType;
|
|
333
|
-
/** Response headers (preserved when caching Response) */
|
|
334
|
-
responseHeaders?: Record<string, string>;
|
|
335
|
-
/** Response status (preserved when caching Response) */
|
|
336
|
-
responseStatus?: number;
|
|
337
|
-
/** Custom metadata */
|
|
338
|
-
[key: string]: unknown;
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Options for put().
|
|
343
|
-
* @internal Reserved for future extensibility
|
|
344
|
-
*/
|
|
345
|
-
export interface CachePutOptions {
|
|
346
|
-
/** Time-to-live in seconds */
|
|
347
|
-
ttl?: number;
|
|
348
|
-
/** Metadata to store with entry */
|
|
349
|
-
metadata?: Omit<CacheMetadata, "expiresAt">;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Generic cache store interface for arbitrary value types.
|
|
354
|
-
*
|
|
355
|
-
* This interface is designed for future extensibility to support caching
|
|
356
|
-
* responses, streams, and other values. Currently, segment caching uses
|
|
357
|
-
* the SegmentCacheStore interface directly.
|
|
358
|
-
*
|
|
359
|
-
* Implementations must handle:
|
|
360
|
-
* - Stream values (clone before storing, streams can only be read once)
|
|
361
|
-
* - Promise values (await before storing)
|
|
362
|
-
* - Expiration/TTL
|
|
363
|
-
*
|
|
364
|
-
* @internal Reserved for future extensibility
|
|
365
|
-
*/
|
|
366
|
-
export interface CacheStore {
|
|
367
|
-
/**
|
|
368
|
-
* Retrieve a cached entry by key.
|
|
369
|
-
* @param key - Cache key
|
|
370
|
-
* @returns The cached entry or undefined if not found/expired
|
|
371
|
-
*/
|
|
372
|
-
match<T = CacheValue>(key: string): Promise<CacheEntry<T> | undefined>;
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Store a value in the cache.
|
|
376
|
-
* @param key - Cache key
|
|
377
|
-
* @param value - Value to cache (stream, response, string, object, etc.)
|
|
378
|
-
* @param options - TTL, metadata, etc.
|
|
379
|
-
*/
|
|
380
|
-
put<T extends CacheValue>(
|
|
381
|
-
key: string,
|
|
382
|
-
value: T,
|
|
383
|
-
options?: CachePutOptions
|
|
384
|
-
): Promise<void>;
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* Delete a cached entry.
|
|
388
|
-
* @param key - Cache key
|
|
389
|
-
* @returns true if entry was deleted, false if not found
|
|
390
|
-
*/
|
|
391
|
-
delete(key: string): Promise<boolean>;
|
|
392
|
-
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export {
|
|
2
|
+
VercelCacheStore,
|
|
3
|
+
type VercelCacheStoreOptions,
|
|
4
|
+
type VercelRuntimeCache,
|
|
5
|
+
type VercelCacheDebug,
|
|
6
|
+
type VercelCacheReadDebugEvent,
|
|
7
|
+
type VercelCacheReadOutcome,
|
|
8
|
+
VERCEL_MAX_ITEM_BYTES,
|
|
9
|
+
VERCEL_MAX_TAGS_PER_ITEM,
|
|
10
|
+
VERCEL_MAX_TAG_BYTES,
|
|
11
|
+
} from "./vercel-cache-store.js";
|