@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,39 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* App-shell metadata: the per-router fields describing the "envelope" around
|
|
5
|
+
* the current app's segment tree — the rootLayout (Document), basename,
|
|
6
|
+
* version, and router identity. Set once from the initial RSC payload and read
|
|
7
|
+
* through the AppShellRef when rendering segments.
|
|
8
|
+
*
|
|
9
|
+
* This is a per-document value. A navigation that crosses a host-router app
|
|
10
|
+
* boundary is a full document load (the server returns X-RSC-Reload for it;
|
|
11
|
+
* see request-classification.ts, mode "app-switch"), so the target app's shell
|
|
12
|
+
* — along with everything else document-level (theme, warmup, prefetch-TTL) —
|
|
13
|
+
* is established fresh by the target app's own load. The shell is never swapped
|
|
14
|
+
* in place within a session.
|
|
15
|
+
*/
|
|
16
|
+
export interface AppShell {
|
|
17
|
+
/** Router identity. Used to namespace per-app client state (e.g. the
|
|
18
|
+
* rango-state localStorage key) so sibling apps on the same origin
|
|
19
|
+
* cannot observe each other's cache invalidations. */
|
|
20
|
+
routerId?: string;
|
|
21
|
+
rootLayout?: ComponentType<{ children: ReactNode }>;
|
|
22
|
+
basename?: string;
|
|
23
|
+
version?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Container for the active app shell. Read-through via `get()` so closures
|
|
28
|
+
* (e.g. the segment renderer) capture the ref and read the shell at call time
|
|
29
|
+
* rather than closing over a stale snapshot.
|
|
30
|
+
*/
|
|
31
|
+
export interface AppShellRef {
|
|
32
|
+
get(): AppShell;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function createAppShellRef(initial: AppShell): AppShellRef {
|
|
36
|
+
return {
|
|
37
|
+
get: () => initial,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mutable app version — updated after HMR revalidation.
|
|
3
|
+
* Read by prefetch, navigation, and context code.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
let currentVersion: string | undefined;
|
|
7
|
+
|
|
8
|
+
export function getAppVersion(): string | undefined {
|
|
9
|
+
return currentVersion;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function setAppVersion(version: string | undefined): void {
|
|
13
|
+
currentVersion = version;
|
|
14
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connection warmup: keep TLS alive after idle periods.
|
|
3
|
+
*
|
|
4
|
+
* After IDLE_TIMEOUT of no user interaction the connection is marked "cold".
|
|
5
|
+
* On the next pointer/touch interaction or a visibility change, a HEAD request
|
|
6
|
+
* warms the TLS connection before the user actually clicks a link.
|
|
7
|
+
*
|
|
8
|
+
* Extracted from NavigationProvider so the idle/cold/warmup state machine is
|
|
9
|
+
* unit-testable with an injected environment (document, fetch, timers).
|
|
10
|
+
*
|
|
11
|
+
* Ordering bug this guards against: the warmup listeners (mousemove/touchstart)
|
|
12
|
+
* share events with the idle-reset listeners, and the idle-reset listener is
|
|
13
|
+
* registered first, so it clears the live "cold" flag before the warmup
|
|
14
|
+
* listener reads it on the same event. A separate coldLatch — set when the
|
|
15
|
+
* connection goes cold and cleared only when warmup fires or listeners detach,
|
|
16
|
+
* never by the idle reset — lets the warmup decision see the pre-reset cold
|
|
17
|
+
* state regardless of listener ordering.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const IDLE_TIMEOUT = 60_000;
|
|
21
|
+
const DEBOUNCE_DELAY = 150;
|
|
22
|
+
|
|
23
|
+
type TimerHandle = ReturnType<typeof setTimeout>;
|
|
24
|
+
|
|
25
|
+
export interface WarmupEnv {
|
|
26
|
+
doc: Pick<
|
|
27
|
+
Document,
|
|
28
|
+
"addEventListener" | "removeEventListener" | "visibilityState"
|
|
29
|
+
>;
|
|
30
|
+
fetch: typeof fetch;
|
|
31
|
+
setTimeout: (fn: () => void, ms: number) => TimerHandle;
|
|
32
|
+
clearTimeout: (handle: TimerHandle | undefined) => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function defaultEnv(): WarmupEnv {
|
|
36
|
+
return {
|
|
37
|
+
doc: document,
|
|
38
|
+
fetch: (...args) => fetch(...args),
|
|
39
|
+
setTimeout: (fn, ms) => setTimeout(fn, ms),
|
|
40
|
+
clearTimeout: (handle) => clearTimeout(handle),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Start the connection-warmup state machine. Returns a cleanup function that
|
|
46
|
+
* cancels timers and removes all listeners.
|
|
47
|
+
*/
|
|
48
|
+
export function startConnectionWarmup(
|
|
49
|
+
env: WarmupEnv = defaultEnv(),
|
|
50
|
+
): () => void {
|
|
51
|
+
const { doc, setTimeout: setT, clearTimeout: clearT } = env;
|
|
52
|
+
|
|
53
|
+
let idleTimer: TimerHandle | undefined;
|
|
54
|
+
let debounceTimer: TimerHandle | undefined;
|
|
55
|
+
// Cold latch for the warmup decision — see module header. Set in markCold;
|
|
56
|
+
// cleared only when warmup fires or listeners detach, NOT by resetIdleTimer,
|
|
57
|
+
// so triggerWarmup sees the pre-reset cold state regardless of listener
|
|
58
|
+
// ordering (the idle-reset listener runs first on a shared mousemove event).
|
|
59
|
+
let coldLatch = false;
|
|
60
|
+
let warmupListenersAttached = false;
|
|
61
|
+
|
|
62
|
+
function sendWarmup() {
|
|
63
|
+
coldLatch = false;
|
|
64
|
+
env.fetch("/?_rsc_warmup", { method: "HEAD" }).catch(() => {});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function triggerWarmup() {
|
|
68
|
+
if (!coldLatch) return;
|
|
69
|
+
clearT(debounceTimer);
|
|
70
|
+
debounceTimer = setT(() => {
|
|
71
|
+
sendWarmup();
|
|
72
|
+
detachWarmupListeners();
|
|
73
|
+
resetIdleTimer();
|
|
74
|
+
}, DEBOUNCE_DELAY);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function onVisibilityChange() {
|
|
78
|
+
if (doc.visibilityState === "visible" && coldLatch) {
|
|
79
|
+
triggerWarmup();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function attachWarmupListeners() {
|
|
84
|
+
if (warmupListenersAttached) return;
|
|
85
|
+
warmupListenersAttached = true;
|
|
86
|
+
doc.addEventListener("visibilitychange", onVisibilityChange);
|
|
87
|
+
doc.addEventListener("mousemove", triggerWarmup, { once: true });
|
|
88
|
+
doc.addEventListener("touchstart", triggerWarmup, { once: true });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function detachWarmupListeners() {
|
|
92
|
+
warmupListenersAttached = false;
|
|
93
|
+
coldLatch = false;
|
|
94
|
+
doc.removeEventListener("visibilitychange", onVisibilityChange);
|
|
95
|
+
doc.removeEventListener("mousemove", triggerWarmup);
|
|
96
|
+
doc.removeEventListener("touchstart", triggerWarmup);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function markCold() {
|
|
100
|
+
coldLatch = true;
|
|
101
|
+
attachWarmupListeners();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function resetIdleTimer() {
|
|
105
|
+
clearT(idleTimer);
|
|
106
|
+
idleTimer = setT(markCold, IDLE_TIMEOUT);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Activity events that reset the idle timer. mousemove/touchstart overlap
|
|
110
|
+
// with the warmup listeners; this listener is registered first, which is the
|
|
111
|
+
// ordering the coldLatch defends against.
|
|
112
|
+
const activityEvents = [
|
|
113
|
+
"mousemove",
|
|
114
|
+
"keydown",
|
|
115
|
+
"touchstart",
|
|
116
|
+
"scroll",
|
|
117
|
+
] as const;
|
|
118
|
+
const activityOptions: AddEventListenerOptions = { passive: true };
|
|
119
|
+
|
|
120
|
+
for (const event of activityEvents) {
|
|
121
|
+
doc.addEventListener(event, resetIdleTimer, activityOptions);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
resetIdleTimer();
|
|
125
|
+
|
|
126
|
+
return () => {
|
|
127
|
+
clearT(idleTimer);
|
|
128
|
+
clearT(debounceTimer);
|
|
129
|
+
detachWarmupListeners();
|
|
130
|
+
for (const event of activityEvents) {
|
|
131
|
+
doc.removeEventListener(event, resetIdleTimer);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rango state cookie: value codec and attribute serialization.
|
|
3
|
+
*
|
|
4
|
+
* Shared by the client (the document.cookie writer in rango-state.ts) and the
|
|
5
|
+
* server (the Set-Cookie writer in invalidateClientCache). Environment-agnostic:
|
|
6
|
+
* no window/document access and no name composition.
|
|
7
|
+
*
|
|
8
|
+
* Name RESOLUTION deliberately lives elsewhere (router init, see
|
|
9
|
+
* router/state-cookie-name.ts). Keeping composition out of this shared module
|
|
10
|
+
* is what lets the client read the server-resolved name verbatim and compose
|
|
11
|
+
* nothing.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** Default prefix when `stateCookiePrefix` is unset or empty after sanitization. */
|
|
15
|
+
export const DEFAULT_STATE_COOKIE_PREFIX = "rango-state";
|
|
16
|
+
|
|
17
|
+
/** Internal response header carrying the keepClientCache() directive. */
|
|
18
|
+
export const KEEP_CACHE_HEADER = "x-rango-keep-cache";
|
|
19
|
+
|
|
20
|
+
// Per-client signal headers (lower-case) that a SHARED response cache must never
|
|
21
|
+
// store or replay (Finding #3): a `Set-Cookie` (rango state rotation, or any
|
|
22
|
+
// cookie a loader set) and the keepClientCache() directive. Strip-all-Set-Cookie
|
|
23
|
+
// is deliberate — a shared store can't know the resolved cookie name, and any
|
|
24
|
+
// per-client cookie in a cacheable document is the hazard. Single source for the
|
|
25
|
+
// predicate, presence check, and strip below.
|
|
26
|
+
const PER_CLIENT_SIGNAL_HEADERS: readonly string[] = [
|
|
27
|
+
"set-cookie",
|
|
28
|
+
KEEP_CACHE_HEADER,
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
/** True for a per-client signal header. */
|
|
32
|
+
export function isPerClientSignalHeader(name: string): boolean {
|
|
33
|
+
return PER_CLIENT_SIGNAL_HEADERS.includes(name.toLowerCase());
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** True if `headers` carries any per-client signal. */
|
|
37
|
+
export function hasPerClientSignal(headers: Headers): boolean {
|
|
38
|
+
return PER_CLIENT_SIGNAL_HEADERS.some((name) => headers.has(name));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Remove every per-client signal header from `headers` in place. */
|
|
42
|
+
export function stripPerClientSignals(headers: Headers): void {
|
|
43
|
+
for (const name of PER_CLIENT_SIGNAL_HEADERS) headers.delete(name);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Read the raw, UNDECODED value of a single cookie from a cookie string (a
|
|
48
|
+
* `document.cookie` jar or a request `Cookie` header). Shared by both seats so
|
|
49
|
+
* the client mirror and the server monotonic-guard read the SAME jar entry —
|
|
50
|
+
* their agreement is the guard's contract. First match wins (the entry the
|
|
51
|
+
* client's mirror holds); exact name boundary via the `=`; an empty value
|
|
52
|
+
* (`name=`) returns null (treated as absent, not a usable prior value).
|
|
53
|
+
*/
|
|
54
|
+
export function getRawCookieValue(
|
|
55
|
+
cookieString: string | null,
|
|
56
|
+
name: string,
|
|
57
|
+
): string | null {
|
|
58
|
+
if (!cookieString) return null;
|
|
59
|
+
const target = name + "=";
|
|
60
|
+
for (const part of cookieString.split(";")) {
|
|
61
|
+
const trimmed = part.trim();
|
|
62
|
+
if (trimmed.startsWith(target)) {
|
|
63
|
+
const value = trimmed.slice(target.length);
|
|
64
|
+
return value === "" ? null : value;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Encode a state value for the wire: `encodeURIComponent(version):timestamp`.
|
|
72
|
+
* Only the build-derived version is encoded (it is arbitrary); the `:`
|
|
73
|
+
* separator and numeric timestamp stay raw, so the `{version}:{timestamp}`
|
|
74
|
+
* shape survives and `:` is a legal cookie-value octet.
|
|
75
|
+
*/
|
|
76
|
+
export function encodeStateValue(version: string, timestamp: number): string {
|
|
77
|
+
return `${encodeURIComponent(version)}:${timestamp}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Parsed state value. `version` is decoded; `timestamp` is the raw integer. */
|
|
81
|
+
export interface StateValue {
|
|
82
|
+
version: string;
|
|
83
|
+
timestamp: number;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Decode a wire value back into `{version, timestamp}`. Returns null for a
|
|
88
|
+
* malformed value (no `:`, empty version, or non-numeric timestamp) so callers
|
|
89
|
+
* mint fresh instead of trusting garbage.
|
|
90
|
+
*/
|
|
91
|
+
export function decodeStateValue(raw: string): StateValue | null {
|
|
92
|
+
const colon = raw.indexOf(":");
|
|
93
|
+
if (colon <= 0) return null;
|
|
94
|
+
const timestamp = Number(raw.slice(colon + 1));
|
|
95
|
+
if (!Number.isFinite(timestamp)) return null;
|
|
96
|
+
let version: string;
|
|
97
|
+
try {
|
|
98
|
+
version = decodeURIComponent(raw.slice(0, colon));
|
|
99
|
+
} catch {
|
|
100
|
+
// A malformed percent-escape (e.g. "%:1") must mint fresh, not throw —
|
|
101
|
+
// a thrown URIError here would 500 the server seat or fail client boot.
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
return { version, timestamp };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Mint a fresh state value whose timestamp is strictly greater than the previous
|
|
109
|
+
* one, so a re-mint inside the same millisecond (or a backward clock step) still
|
|
110
|
+
* differs from the current value. `prevRaw` is the current wire value (the
|
|
111
|
+
* client's in-memory mirror, or the server's inbound header/cookie) or null; its
|
|
112
|
+
* timestamp is the floor. Shared by both seats so the monotonic guard lives once.
|
|
113
|
+
*/
|
|
114
|
+
export function mintStateValue(
|
|
115
|
+
version: string,
|
|
116
|
+
prevRaw: string | null,
|
|
117
|
+
): string {
|
|
118
|
+
const prevTs = prevRaw ? (decodeStateValue(prevRaw)?.timestamp ?? 0) : 0;
|
|
119
|
+
const ts = Math.max(Date.now(), prevTs + 1);
|
|
120
|
+
return encodeStateValue(version, ts);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Attribute string for the state cookie. Session cookie (no Max-Age/Expires),
|
|
125
|
+
* Path=/ (whole app), SameSite=Lax (sent on top-level navigations), and Secure
|
|
126
|
+
* only on https so the document.cookie write does not silently fail on plain
|
|
127
|
+
* http dev. Never HttpOnly (the client reads and writes it).
|
|
128
|
+
*/
|
|
129
|
+
export function stateCookieAttributes(secure: boolean): string {
|
|
130
|
+
return `; Path=/; SameSite=Lax${secure ? "; Secure" : ""}`;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Serialize a full `name=value` cookie string with the state attributes. */
|
|
134
|
+
export function serializeStateCookie(
|
|
135
|
+
name: string,
|
|
136
|
+
value: string,
|
|
137
|
+
secure: boolean,
|
|
138
|
+
): string {
|
|
139
|
+
return `${name}=${value}${stateCookieAttributes(secure)}`;
|
|
140
|
+
}
|