@rangojs/router 0.0.0-experimental.14 → 0.0.0-experimental.140
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +17 -0
- package/README.md +432 -7
- package/dist/bin/rango.js +2073 -213
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +7258 -2714
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +140 -67
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +329 -0
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +487 -0
- package/skills/caching/SKILL.md +357 -25
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +246 -0
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +16 -10
- package/skills/document-cache/SKILL.md +87 -62
- package/skills/fonts/SKILL.md +6 -4
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +557 -79
- package/skills/host-router/SKILL.md +320 -0
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +207 -15
- package/skills/layout/SKILL.md +146 -6
- package/skills/links/SKILL.md +304 -25
- package/skills/loader/SKILL.md +616 -54
- package/skills/middleware/SKILL.md +217 -37
- package/skills/migrate-nextjs/SKILL.md +611 -0
- package/skills/migrate-react-router/SKILL.md +927 -0
- package/skills/mime-routes/SKILL.md +42 -11
- package/skills/observability/SKILL.md +194 -0
- package/skills/parallel/SKILL.md +284 -3
- package/skills/ppr/SKILL.md +426 -0
- package/skills/prerender/SKILL.md +437 -52
- package/skills/rango/SKILL.md +369 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +263 -121
- package/skills/route/SKILL.md +350 -21
- package/skills/router-setup/SKILL.md +246 -33
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +126 -222
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +131 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +85 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +532 -103
- package/skills/use-cache/SKILL.md +367 -0
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +77 -44
- package/src/bin/rango.ts +312 -15
- package/src/browser/action-coordinator.ts +114 -0
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +293 -202
- package/src/browser/history-state.ts +101 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +11 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +385 -576
- package/src/browser/navigation-client.ts +245 -75
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +184 -118
- package/src/browser/navigation-transaction.ts +247 -0
- package/src/browser/network-error-handler.ts +88 -0
- package/src/browser/partial-update.ts +412 -364
- package/src/browser/prefetch/cache.ts +359 -0
- package/src/browser/prefetch/fetch.ts +452 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +209 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +194 -0
- package/src/browser/react/Link.tsx +275 -68
- package/src/browser/react/NavigationProvider.tsx +265 -109
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +11 -0
- package/src/browser/react/filter-segment-order.ts +70 -0
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +272 -60
- package/src/browser/react/location-state.ts +90 -20
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +35 -66
- package/src/browser/react/use-handle.ts +39 -126
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +39 -13
- package/src/browser/react/use-navigation.ts +53 -69
- package/src/browser/react/use-params.ts +75 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +98 -0
- package/src/browser/react/use-search-params.ts +51 -0
- package/src/browser/react/use-segments.ts +72 -99
- package/src/browser/response-adapter.ts +164 -0
- package/src/browser/rsc-router.tsx +300 -72
- package/src/browser/scroll-restoration.ts +138 -50
- package/src/browser/segment-reconciler.ts +243 -0
- package/src/browser/segment-structure-assert.ts +17 -1
- package/src/browser/server-action-bridge.ts +668 -613
- package/src/browser/types.ts +223 -51
- package/src/browser/validate-redirect-origin.ts +56 -0
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +252 -161
- package/src/build/generate-route-types.ts +41 -1038
- package/src/build/index.ts +12 -7
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +225 -42
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +105 -0
- package/src/build/route-types/codegen.ts +113 -0
- package/src/build/route-types/include-resolution.ts +812 -0
- package/src/build/route-types/param-extraction.ts +51 -0
- package/src/build/route-types/per-module-writer.ts +144 -0
- package/src/build/route-types/router-processing.ts +695 -0
- package/src/build/route-types/scan-filter.ts +85 -0
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +223 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +60 -0
- package/src/cache/cache-policy.ts +199 -0
- package/src/cache/cache-runtime.ts +525 -0
- package/src/cache/cache-scope.ts +298 -332
- package/src/cache/cache-tag.ts +103 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +2500 -158
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +17 -17
- package/src/cache/document-cache.ts +199 -92
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +111 -0
- package/src/cache/index.ts +29 -35
- package/src/cache/memory-segment-store.ts +363 -30
- package/src/cache/profile-registry.ts +88 -0
- package/src/cache/read-through-swr.ts +178 -0
- package/src/cache/segment-codec.ts +248 -0
- package/src/cache/shell-cache.ts +386 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +153 -0
- package/src/cache/types.ts +156 -211
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1102 -0
- package/src/client.rsc.tsx +43 -21
- package/src/client.tsx +131 -347
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/component-utils.ts +23 -4
- package/src/components/DefaultDocument.tsx +13 -3
- package/src/context-var.ts +168 -0
- package/src/debug.ts +19 -9
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +106 -10
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +110 -35
- package/src/handles/MetaTags.tsx +83 -59
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +93 -0
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +44 -53
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +20 -65
- package/src/host/errors.ts +21 -30
- package/src/host/index.ts +13 -9
- package/src/host/pattern-matcher.ts +50 -79
- package/src/host/router.ts +151 -121
- package/src/host/testing.ts +45 -32
- package/src/host/types.ts +52 -11
- package/src/host/utils.ts +2 -2
- package/src/href-client.ts +192 -57
- package/src/index.rsc.ts +177 -35
- package/src/index.ts +255 -71
- package/src/internal-debug.ts +9 -2
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +31 -99
- package/src/loader.ts +30 -12
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +41 -0
- package/src/prerender/param-hash.ts +16 -14
- package/src/prerender/store.ts +121 -21
- package/src/prerender.ts +460 -26
- package/src/redirect-origin.ts +100 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +62 -0
- package/src/reverse.ts +198 -128
- package/src/root-error-boundary.tsx +42 -48
- package/src/route-content-wrapper.tsx +22 -77
- package/src/route-definition/dsl-helpers.ts +1116 -0
- package/src/route-definition/helper-factories.ts +88 -0
- package/src/route-definition/helpers-types.ts +505 -0
- package/src/route-definition/index.ts +54 -0
- package/src/route-definition/redirect.ts +134 -0
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-definition.ts +1 -1481
- package/src/route-map-builder.ts +82 -144
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +71 -45
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +263 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +54 -27
- package/src/router/find-match.ts +245 -0
- package/src/router/handler-context.ts +377 -125
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +59 -28
- package/src/router/lazy-includes.ts +254 -0
- package/src/router/loader-resolution.ts +421 -157
- package/src/router/logging.ts +106 -6
- package/src/router/manifest.ts +131 -57
- package/src/router/match-api.ts +167 -246
- package/src/router/match-context.ts +4 -24
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +117 -93
- package/src/router/match-middleware/cache-lookup.ts +297 -150
- package/src/router/match-middleware/cache-store.ts +123 -51
- package/src/router/match-middleware/intercept-resolution.ts +44 -43
- package/src/router/match-middleware/segment-resolution.ts +64 -22
- package/src/router/match-pipelines.ts +11 -87
- package/src/router/match-result.ts +121 -50
- package/src/router/metrics.ts +219 -28
- package/src/router/middleware-types.ts +93 -0
- package/src/router/middleware.ts +505 -441
- package/src/router/navigation-snapshot.ts +133 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +311 -142
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +547 -0
- package/src/router/preview-match.ts +102 -0
- package/src/router/request-classification.ts +278 -0
- package/src/router/revalidation.ts +203 -62
- package/src/router/route-snapshot.ts +246 -0
- package/src/router/router-context.ts +45 -48
- package/src/router/router-interfaces.ts +554 -0
- package/src/router/router-options.ts +779 -0
- package/src/router/router-registry.ts +21 -0
- package/src/router/segment-resolution/fresh.ts +772 -0
- package/src/router/segment-resolution/helpers.ts +348 -0
- package/src/router/segment-resolution/loader-cache.ts +250 -0
- package/src/router/segment-resolution/loader-mask.ts +44 -0
- package/src/router/segment-resolution/revalidation.ts +1331 -0
- package/src/router/segment-resolution/static-store.ts +81 -0
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +56 -0
- package/src/router/segment-resolution.ts +25 -1354
- package/src/router/segment-wrappers.ts +292 -0
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +261 -0
- package/src/router/telemetry.ts +377 -0
- package/src/router/timeout.ts +128 -0
- package/src/router/tracing.ts +206 -0
- package/src/router/trie-matching.ts +240 -61
- package/src/router/types.ts +23 -70
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +781 -2378
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +46 -0
- package/src/rsc/handler.ts +905 -1142
- package/src/rsc/helpers.ts +275 -19
- package/src/rsc/index.ts +2 -25
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +305 -0
- package/src/rsc/manifest-init.ts +77 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +155 -0
- package/src/rsc/progressive-enhancement.ts +502 -0
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +104 -0
- package/src/rsc/response-route-handler.ts +257 -0
- package/src/rsc/rsc-rendering.ts +337 -0
- package/src/rsc/runtime-warnings.ts +55 -0
- package/src/rsc/server-action.ts +522 -0
- package/src/rsc/shell-capture.ts +439 -0
- package/src/rsc/ssr-setup.ts +144 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +95 -12
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +99 -82
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +149 -0
- package/src/segment-system.tsx +349 -134
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +452 -85
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +310 -0
- package/src/server/fetchable-loader-store.ts +11 -6
- package/src/server/handle-store.ts +123 -42
- package/src/server/live.ts +130 -0
- package/src/server/loader-registry.ts +51 -100
- package/src/server/request-context.ts +842 -157
- package/src/server.ts +15 -8
- package/src/ssr/index.tsx +412 -136
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +45 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +701 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +257 -0
- package/src/testing/generated-routes.ts +199 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +357 -0
- package/src/testing/render-route.tsx +584 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +40 -72
- package/src/theme/ThemeScript.tsx +12 -14
- package/src/theme/constants.ts +57 -15
- package/src/theme/index.ts +3 -20
- package/src/theme/theme-context.ts +5 -35
- package/src/theme/theme-script.ts +43 -39
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +123 -0
- package/src/types/cache-types.ts +207 -0
- package/src/types/error-types.ts +132 -0
- package/src/types/global-namespace.ts +113 -0
- package/src/types/handler-context.ts +839 -0
- package/src/types/index.ts +81 -0
- package/src/types/loader-types.ts +212 -0
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +138 -0
- package/src/types/route-entry.ts +114 -0
- package/src/types/segments.ts +271 -0
- package/src/types.ts +1 -1795
- package/src/urls/include-helper.ts +162 -0
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +43 -0
- package/src/urls/path-helper-types.ts +413 -0
- package/src/urls/path-helper.ts +275 -0
- package/src/urls/pattern-types.ts +124 -0
- package/src/urls/response-types.ts +109 -0
- package/src/urls/type-extraction.ts +316 -0
- package/src/urls/urls-function.ts +80 -0
- package/src/urls.ts +1 -1341
- package/src/use-loader.tsx +406 -141
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +182 -0
- package/src/vite/discovery/discover-routers.ts +389 -0
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +467 -0
- package/src/vite/discovery/route-types-writer.ts +214 -0
- package/src/vite/discovery/self-gen-tracking.ts +73 -0
- package/src/vite/discovery/state.ts +161 -0
- package/src/vite/discovery/virtual-module-codegen.ts +183 -0
- package/src/vite/index.ts +23 -2255
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +303 -0
- package/src/vite/plugins/cjs-to-esm.ts +90 -0
- package/src/vite/plugins/client-ref-dedup.ts +120 -0
- package/src/vite/plugins/client-ref-hashing.ts +118 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +88 -110
- package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +89 -79
- package/src/vite/plugins/expose-ids/export-analysis.ts +363 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +130 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +64 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +199 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +805 -0
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +313 -0
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +94 -0
- package/src/vite/plugins/version-plugin.ts +263 -0
- package/src/vite/plugins/virtual-entries.ts +234 -0
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +560 -0
- package/src/vite/router-discovery.ts +1638 -0
- package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +200 -37
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +132 -0
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +15 -0
- package/src/vite/utils/package-resolution.ts +89 -0
- package/src/vite/utils/prerender-utils.ts +249 -0
- package/src/vite/utils/shared-utils.ts +269 -0
- package/CLAUDE.md +0 -43
- package/dist/vite/index.named-routes.gen.ts +0 -103
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/react/use-client-cache.ts +0 -56
- package/src/browser/request-controller.ts +0 -164
- package/src/browser/shallow.ts +0 -35
- package/src/cache/memory-store.ts +0 -253
- package/src/handles/index.ts +0 -6
- package/src/href-context.ts +0 -33
- package/src/network-error-thrower.tsx +0 -21
- package/src/router.gen.ts +0 -6
- package/src/static-handler.gen.ts +0 -5
- package/src/urls.gen.ts +0 -8
- package/src/vite/expose-internal-ids.ts +0 -1167
- package/src/vite/package-resolution.ts +0 -125
- package/src/vite/virtual-entries.ts +0 -114
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* live() — the deterministic PPR hole primitive (docs/design/ppr-shell-resume.md).
|
|
3
|
+
*
|
|
4
|
+
* A PPR shell is captured by masking loaders and freezing everything that
|
|
5
|
+
* settles synchronously or on a microtask into the shared prelude. That freeze
|
|
6
|
+
* has a sharp edge: a value that is ALREADY resolved — `Promise.resolve(x)`, an
|
|
7
|
+
* in-memory lookup, a cached read — settles during the capture's quiet window
|
|
8
|
+
* and gets baked into the shell, served to every user of the URL. That is
|
|
9
|
+
* usually what you want (deterministic content belongs in the shell), but not
|
|
10
|
+
* when the value is per-request. `live()` is the escape hatch: it makes its
|
|
11
|
+
* boundary a deterministic HOLE regardless of how fast the data resolves, so the
|
|
12
|
+
* capture postpones there and the resumed serve pass streams the fresh value in.
|
|
13
|
+
*
|
|
14
|
+
* It is the userland analogue of the loader mask (loader-mask.ts): during the
|
|
15
|
+
* background shell-capture render `live()` returns a never-settling promise so
|
|
16
|
+
* the consuming Suspense subtree suspends and React's static prerender postpones
|
|
17
|
+
* it. Outside capture — the ordinary serve pass, and the client — it is a
|
|
18
|
+
* passthrough: the thunk runs, or the promise passes through unchanged.
|
|
19
|
+
*
|
|
20
|
+
* Two forms:
|
|
21
|
+
*
|
|
22
|
+
* // Thunk (preferred): during capture the fn NEVER runs — no fetch, no cost.
|
|
23
|
+
* const price = await live(() => fetchPrice());
|
|
24
|
+
*
|
|
25
|
+
* // Value: the work already fired before live() saw it, so during capture the
|
|
26
|
+
* // real promise is discarded and a hole is returned in its place. Use the
|
|
27
|
+
* // thunk form unless you already hold the promise.
|
|
28
|
+
* const price = await live(pricePromise);
|
|
29
|
+
*
|
|
30
|
+
* The consumer story in one line: a hole even when the data is already resolved —
|
|
31
|
+
* const x = await live(() => Promise.resolve(value)); // postpones under capture
|
|
32
|
+
*
|
|
33
|
+
* @see docs/design/ppr-shell-resume.md ("The live() hole primitive")
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
import { _getRequestContext } from "./request-context.js";
|
|
37
|
+
import { isInsideCacheScope } from "./context.js";
|
|
38
|
+
import { INSIDE_CACHE_EXEC } from "../cache/taint.js";
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A promise that never settles — the capture-time hole. Same mechanism and
|
|
42
|
+
* lifecycle as the loader mask (loader-mask.ts createMaskedLoaderPromise): the
|
|
43
|
+
* consuming Suspense subtree suspends forever, so the static prerender postpones
|
|
44
|
+
* it as a hole instead of baking a per-request value into the shared shell.
|
|
45
|
+
* Nothing awaits it to settle — the capture aborts fizz to freeze the prelude
|
|
46
|
+
* (maxWaitMs in captureShellHTML bounds that), and workerd/GC reclaims the
|
|
47
|
+
* pending promise when the capture render tree is dropped. Kept never-settling
|
|
48
|
+
* (not reject-on-abort) deliberately, to stay identical to the loader mask: a
|
|
49
|
+
* capture-scoped reject signal would buy no capture-behavior difference, since
|
|
50
|
+
* the abort — not the hole promise — is what ends the render.
|
|
51
|
+
*/
|
|
52
|
+
function captureHole<T>(): Promise<T> {
|
|
53
|
+
return new Promise<T>(() => {});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** True only inside the background shell-capture render (shell-capture.ts sets
|
|
57
|
+
* `_shellCaptureRun` on its derived context). Non-throwing: outside any request
|
|
58
|
+
* context this is simply false, so live() passes through. */
|
|
59
|
+
function isShellCaptureActive(): boolean {
|
|
60
|
+
return _getRequestContext()?._shellCaptureRun === true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Mark a Suspense boundary as a deterministic PPR hole (see the module doc).
|
|
65
|
+
*
|
|
66
|
+
* @param fn - Thunk producing the live value. During shell capture it is NOT
|
|
67
|
+
* invoked (no side effects, no cost); a never-settling promise is returned so
|
|
68
|
+
* the boundary postpones. Outside capture it runs and its result is returned
|
|
69
|
+
* as a promise.
|
|
70
|
+
*/
|
|
71
|
+
export function live<T>(fn: () => Promise<T> | T): Promise<T>;
|
|
72
|
+
/**
|
|
73
|
+
* @param promise - A promise whose work has already fired. During shell capture
|
|
74
|
+
* the promise is discarded and a hole is returned in its place (the work still
|
|
75
|
+
* ran — prefer the thunk form to avoid that). Outside capture the promise
|
|
76
|
+
* passes through unchanged.
|
|
77
|
+
*/
|
|
78
|
+
export function live<T>(promise: Promise<T>): Promise<T>;
|
|
79
|
+
export function live<T>(
|
|
80
|
+
input: (() => Promise<T> | T) | Promise<T>,
|
|
81
|
+
): Promise<T> {
|
|
82
|
+
assertNotInsideCacheBoundary();
|
|
83
|
+
if (isShellCaptureActive()) {
|
|
84
|
+
return captureHole<T>();
|
|
85
|
+
}
|
|
86
|
+
return typeof input === "function"
|
|
87
|
+
? Promise.resolve((input as () => Promise<T> | T)())
|
|
88
|
+
: input;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Throw when live() is called inside a cache boundary — a "use cache" function
|
|
93
|
+
* (INSIDE_CACHE_EXEC stamped on the request context) or a cache() DSL scope.
|
|
94
|
+
*
|
|
95
|
+
* live() only masks during the SHELL capture (ring 4). The inner cache rings
|
|
96
|
+
* freeze first: a cache()/prerender write deep-settles the promise and stores
|
|
97
|
+
* its VALUE in the segment cache, and the handler never re-runs on replay — so
|
|
98
|
+
* a live() there is silently inert, and if the value is per-request it is the
|
|
99
|
+
* same shared-cache leak cookies()/headers() guard against, defeated by the
|
|
100
|
+
* very primitive the caller believed made it safe. A "use cache" miss during a
|
|
101
|
+
* capture render is worse: the fn body runs under the capture flag, live()
|
|
102
|
+
* returns a never-settling promise, and the cache write wedges awaiting it.
|
|
103
|
+
* Same guard shape as assertNotInsideCacheContext in cookie-store.ts.
|
|
104
|
+
*/
|
|
105
|
+
function assertNotInsideCacheBoundary(): void {
|
|
106
|
+
const ctx = _getRequestContext();
|
|
107
|
+
if (
|
|
108
|
+
ctx !== null &&
|
|
109
|
+
ctx !== undefined &&
|
|
110
|
+
(INSIDE_CACHE_EXEC as symbol) in (ctx as unknown as Record<symbol, unknown>)
|
|
111
|
+
) {
|
|
112
|
+
throw new Error(
|
|
113
|
+
`live() cannot be called inside a "use cache" function. The cached ` +
|
|
114
|
+
`function's value is stored and replayed, so nothing inside it can ` +
|
|
115
|
+
`stay live — and per-request data would be frozen into a shared ` +
|
|
116
|
+
`cache entry. Read live data in a loader instead (loaders are never ` +
|
|
117
|
+
`cached), or move the live() call outside the cached function.`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
if (isInsideCacheScope()) {
|
|
121
|
+
throw new Error(
|
|
122
|
+
`live() cannot be called inside a cache() boundary. The segment cache ` +
|
|
123
|
+
`deep-settles and stores the resolved VALUE at write time, and the ` +
|
|
124
|
+
`handler never re-runs on a cache hit — so live() cannot keep this ` +
|
|
125
|
+
`value live, and per-request data would be frozen into the shared ` +
|
|
126
|
+
`cached segments. Use a loader behind loading() instead: loaders are ` +
|
|
127
|
+
`the live lane through every cache ring.`,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -6,25 +6,15 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { LoaderFn } from "../types.js";
|
|
9
|
-
import
|
|
10
|
-
|
|
9
|
+
import {
|
|
10
|
+
getFetchableLoader,
|
|
11
|
+
type LoaderRegistryEntry,
|
|
12
|
+
} from "./fetchable-loader-store.js";
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Server-side cache - maps loader $$id to function and middleware
|
|
18
|
-
// This is a CACHE populated by getLoaderLazy() when loaders are first accessed.
|
|
19
|
-
// The source of truth is fetchableLoaderRegistry in loader.ts, which is populated
|
|
20
|
-
// when createLoader() runs. This cache exists to:
|
|
21
|
-
// 1. Avoid repeated lookups/imports for the same loader
|
|
22
|
-
// 2. Support lazy loading in production (loaders imported on-demand)
|
|
23
|
-
// 3. Provide a stable reference for the RSC handler
|
|
24
|
-
const loaderRegistry = new Map<string, RegisteredLoader>();
|
|
14
|
+
// Cache populated by getLoaderLazy() when loaders are first accessed.
|
|
15
|
+
// Source of truth is fetchableLoaderRegistry in loader.ts (populated on createLoader).
|
|
16
|
+
const loaderRegistry = new Map<string, LoaderRegistryEntry>();
|
|
25
17
|
|
|
26
|
-
// Lazy import map - set by the loader manifest
|
|
27
|
-
// Maps loader $$id to a function that imports the loader module
|
|
28
18
|
type LazyLoaderImport = () => Promise<{ $$id: string }>;
|
|
29
19
|
let lazyLoaderImports: Map<string, LazyLoaderImport> | null = null;
|
|
30
20
|
|
|
@@ -32,35 +22,11 @@ let lazyLoaderImports: Map<string, LazyLoaderImport> | null = null;
|
|
|
32
22
|
* Set the lazy loader imports map (called by the loader manifest)
|
|
33
23
|
*/
|
|
34
24
|
export function setLoaderImports(
|
|
35
|
-
imports: Record<string, LazyLoaderImport
|
|
25
|
+
imports: Record<string, LazyLoaderImport>,
|
|
36
26
|
): void {
|
|
37
27
|
lazyLoaderImports = new Map(Object.entries(imports));
|
|
38
28
|
}
|
|
39
29
|
|
|
40
|
-
/**
|
|
41
|
-
* Register a fetchable loader by $$id
|
|
42
|
-
* Called by createLoader when fetchable option is provided
|
|
43
|
-
*/
|
|
44
|
-
export function registerLoader(
|
|
45
|
-
id: string,
|
|
46
|
-
fn: LoaderFn<any, any, any>,
|
|
47
|
-
middleware: MiddlewareFn[] = []
|
|
48
|
-
): void {
|
|
49
|
-
if (loaderRegistry.has(id)) {
|
|
50
|
-
// Already registered (can happen during HMR)
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
loaderRegistry.set(id, { fn, middleware });
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Get a registered loader by $$id (synchronous)
|
|
58
|
-
* Returns undefined if loader is not registered
|
|
59
|
-
*/
|
|
60
|
-
export function getLoader(id: string): RegisteredLoader | undefined {
|
|
61
|
-
return loaderRegistry.get(id);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
30
|
/**
|
|
65
31
|
* Get a loader by $$id, loading it lazily if needed
|
|
66
32
|
* This is the primary method for the RSC handler to get loaders
|
|
@@ -69,81 +35,69 @@ export function getLoader(id: string): RegisteredLoader | undefined {
|
|
|
69
35
|
* In dev: IDs are "filePath#exportName", resolved via dynamic import
|
|
70
36
|
*/
|
|
71
37
|
export async function getLoaderLazy(
|
|
72
|
-
id: string
|
|
73
|
-
): Promise<
|
|
74
|
-
// Check
|
|
75
|
-
|
|
76
|
-
if (existing) {
|
|
77
|
-
return existing;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Check the fetchable loader registry (populated by createLoader)
|
|
38
|
+
id: string,
|
|
39
|
+
): Promise<LoaderRegistryEntry | undefined> {
|
|
40
|
+
// Check fetchableLoaderRegistry first — it's the source of truth.
|
|
41
|
+
// createLoader() updates it on HMR, ensuring fresh functions after file changes.
|
|
81
42
|
const fetchable = getFetchableLoader(id);
|
|
82
43
|
if (fetchable) {
|
|
83
|
-
// Cache in main registry for future requests
|
|
84
44
|
loaderRegistry.set(id, fetchable);
|
|
85
45
|
return fetchable;
|
|
86
46
|
}
|
|
87
47
|
|
|
88
|
-
|
|
48
|
+
const existing = loaderRegistry.get(id);
|
|
49
|
+
if (existing) {
|
|
50
|
+
return existing;
|
|
51
|
+
}
|
|
52
|
+
|
|
89
53
|
if (lazyLoaderImports && lazyLoaderImports.size > 0) {
|
|
90
54
|
const lazyImport = lazyLoaderImports.get(id);
|
|
91
55
|
if (lazyImport) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
56
|
+
// A failed import is a real server breakage (broken transitive import,
|
|
57
|
+
// syntax error, throw in module top-level code), not a "loader not
|
|
58
|
+
// registered" case. Rethrow so the caller can return a 500 and route
|
|
59
|
+
// the failure through onError, instead of collapsing it to a 404.
|
|
60
|
+
await lazyImport();
|
|
95
61
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return registered;
|
|
101
|
-
}
|
|
102
|
-
} catch (error) {
|
|
103
|
-
console.error(`[LoaderRegistry] Failed to load loader "${id}":`, error);
|
|
62
|
+
const registered = getFetchableLoader(id);
|
|
63
|
+
if (registered) {
|
|
64
|
+
loaderRegistry.set(id, registered);
|
|
65
|
+
return registered;
|
|
104
66
|
}
|
|
105
67
|
}
|
|
106
68
|
}
|
|
107
69
|
|
|
108
|
-
//
|
|
109
|
-
//
|
|
70
|
+
// The remaining dev fallback (parse the id as "src/path/file.ts#ExportName"
|
|
71
|
+
// and import it by path) only makes sense in dev, where ids ARE file paths
|
|
72
|
+
// and the dev loader manifest is intentionally empty. In production ids are
|
|
73
|
+
// hashed ("<hash>#ExportName") and every resolvable loader is reached above
|
|
74
|
+
// via the in-memory registry or the lazy import manifest. The hash is not a
|
|
75
|
+
// path, so a production fall-through would run import("/<hash>") and throw a
|
|
76
|
+
// misleading "No such module <hash>" 500 instead of reporting the loader as
|
|
77
|
+
// unregistered. Return undefined in production so a genuinely unknown loader
|
|
78
|
+
// is a clean 404 "not found in registry" from handleLoaderFetch.
|
|
79
|
+
if (process.env.NODE_ENV === "production") {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
110
83
|
const hashIndex = id.indexOf("#");
|
|
111
84
|
if (hashIndex !== -1) {
|
|
112
85
|
const filePath = id.slice(0, hashIndex);
|
|
113
86
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
await import(/* @vite-ignore */ `/${filePath}`);
|
|
87
|
+
// Same as the lazy branch: a thrown import is a server error, not a
|
|
88
|
+
// not-found. Let it propagate to the caller for a 500 + onError.
|
|
89
|
+
await import(/* @vite-ignore */ `/${filePath}`);
|
|
118
90
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return registered;
|
|
124
|
-
}
|
|
125
|
-
} catch (error) {
|
|
126
|
-
console.error(`[LoaderRegistry] Failed to load loader "${id}":`, error);
|
|
91
|
+
const registered = getFetchableLoader(id);
|
|
92
|
+
if (registered) {
|
|
93
|
+
loaderRegistry.set(id, registered);
|
|
94
|
+
return registered;
|
|
127
95
|
}
|
|
128
96
|
}
|
|
129
97
|
|
|
130
98
|
return undefined;
|
|
131
99
|
}
|
|
132
100
|
|
|
133
|
-
/**
|
|
134
|
-
* Check if a loader is registered by $$id
|
|
135
|
-
*/
|
|
136
|
-
export function hasLoader(id: string): boolean {
|
|
137
|
-
return loaderRegistry.has(id) || getFetchableLoader(id) !== undefined;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Get all registered loader IDs (for debugging)
|
|
142
|
-
*/
|
|
143
|
-
export function getRegisteredLoaderIds(): string[] {
|
|
144
|
-
return Array.from(loaderRegistry.keys());
|
|
145
|
-
}
|
|
146
|
-
|
|
147
101
|
/**
|
|
148
102
|
* Register a loader by its $$id (injected by Vite plugin)
|
|
149
103
|
* This is called during module loading to cache loaders
|
|
@@ -155,20 +109,17 @@ export function registerLoaderById(loader: {
|
|
|
155
109
|
if (!loader.$$id) {
|
|
156
110
|
return;
|
|
157
111
|
}
|
|
158
|
-
if (loaderRegistry.has(loader.$$id)) {
|
|
159
|
-
// Already registered (can happen during HMR)
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// For fetchable loaders, fn is stored in the fetchable registry by $$id
|
|
164
112
|
const fetchable = getFetchableLoader(loader.$$id);
|
|
165
113
|
if (fetchable) {
|
|
166
114
|
loaderRegistry.set(loader.$$id, fetchable);
|
|
167
115
|
return;
|
|
168
116
|
}
|
|
169
117
|
|
|
170
|
-
// Fall back to using fn from the loader object (non-fetchable loaders)
|
|
171
118
|
if (loader.fn) {
|
|
172
|
-
loaderRegistry.set(loader.$$id, {
|
|
119
|
+
loaderRegistry.set(loader.$$id, {
|
|
120
|
+
fn: loader.fn,
|
|
121
|
+
middleware: [],
|
|
122
|
+
fetchable: false,
|
|
123
|
+
});
|
|
173
124
|
}
|
|
174
125
|
}
|