@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
package/src/loader.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* @rangojs/router/loader (client version)
|
|
3
3
|
*
|
|
4
4
|
* Client-only stub for createLoader. Returns a minimal loader definition
|
|
5
|
-
* that can be passed to hooks like useLoader.
|
|
6
|
-
* is not included
|
|
5
|
+
* ({ __brand, $$id }) that can be passed to hooks like useLoader.
|
|
6
|
+
* The actual loader function is not included -- it only exists on the server.
|
|
7
|
+
*
|
|
8
|
+
* For export-only loader files, the Vite plugin replaces the entire file with
|
|
9
|
+
* object literals (bypassing this function). Those stubs only contain
|
|
10
|
+
* { __brand, $$id }.
|
|
11
|
+
* This function only runs when loaders are in mixed files (not export-only).
|
|
7
12
|
*
|
|
8
13
|
* The $$id is injected by the Vite exposeInternalIds plugin.
|
|
9
14
|
*/
|
|
@@ -13,35 +18,48 @@ import type {
|
|
|
13
18
|
LoaderDefinition,
|
|
14
19
|
LoaderFn,
|
|
15
20
|
} from "./types.js";
|
|
21
|
+
import { missingInjectedIdError } from "./missing-id-error.js";
|
|
22
|
+
import { isUnderTestRunner } from "./runtime-env.js";
|
|
16
23
|
|
|
17
24
|
// Overload 1: With function only (not fetchable)
|
|
18
25
|
export function createLoader<T>(
|
|
19
|
-
fn: LoaderFn<T, Record<string, string | undefined>, any
|
|
26
|
+
fn: LoaderFn<T, Record<string, string | undefined>, any>,
|
|
20
27
|
): LoaderDefinition<Awaited<T>, Record<string, string | undefined>>;
|
|
21
28
|
|
|
22
29
|
// Overload 2: Fetchable with `true` (no middleware)
|
|
23
30
|
export function createLoader<T>(
|
|
24
31
|
fn: LoaderFn<T, Record<string, string | undefined>, any>,
|
|
25
|
-
fetchable: true
|
|
32
|
+
fetchable: true,
|
|
26
33
|
): LoaderDefinition<Awaited<T>, Record<string, string | undefined>>;
|
|
27
34
|
|
|
28
35
|
// Overload 3: Fetchable with middleware options
|
|
29
36
|
export function createLoader<T>(
|
|
30
37
|
fn: LoaderFn<T, Record<string, string | undefined>, any>,
|
|
31
|
-
options: FetchableLoaderOptions
|
|
38
|
+
options: FetchableLoaderOptions,
|
|
32
39
|
): LoaderDefinition<Awaited<T>, Record<string, string | undefined>>;
|
|
33
40
|
|
|
34
|
-
// Implementation - client stub
|
|
35
|
-
// The $$id parameter is injected by Vite plugin, not user-provided
|
|
41
|
+
// Implementation - client stub ($$id injected by Vite plugin, not user-provided)
|
|
36
42
|
export function createLoader<T>(
|
|
37
43
|
_fn: LoaderFn<T, Record<string, string | undefined>, any>,
|
|
38
44
|
_fetchable?: true | FetchableLoaderOptions,
|
|
39
|
-
__injectedId?: string
|
|
45
|
+
__injectedId?: string,
|
|
40
46
|
): LoaderDefinition<Awaited<T>, Record<string, string | undefined>> {
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
const loaderId = __injectedId || "";
|
|
48
|
+
|
|
49
|
+
// Under test runner, no id needed (loaderId stays ""; loader.rsc.ts provides fallback).
|
|
50
|
+
// Otherwise, missing id means unsupported shape — fail loud to avoid wrong key.
|
|
51
|
+
if (!loaderId && !isUnderTestRunner()) {
|
|
52
|
+
if (process.env.NODE_ENV !== "production") {
|
|
53
|
+
throw missingInjectedIdError("Loader", "createLoader");
|
|
54
|
+
}
|
|
55
|
+
throw new Error(
|
|
56
|
+
"[rango] Loader is missing $$id — the build plugin did not inject one. " +
|
|
57
|
+
"Export it as `export const X = createLoader(...)`.",
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
43
61
|
return {
|
|
44
62
|
__brand: "loader",
|
|
45
|
-
$$id:
|
|
63
|
+
$$id: loaderId,
|
|
46
64
|
};
|
|
47
65
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Builds the error thrown when a create*() call (createLoader / createHandle)
|
|
2
|
+
// reaches runtime without an injected $$id. The exposeInternalIds Vite transform
|
|
3
|
+
// injects $$id only for an EXPORTED const declaration, so a non-exported const,
|
|
4
|
+
// an `export let/var`, or an inline create*() call gets none. Previously this
|
|
5
|
+
// failed with a terse message and no source location; this helper adds the
|
|
6
|
+
// offending call site (best-effort, from the stack) and actionable guidance.
|
|
7
|
+
//
|
|
8
|
+
// The "<Kind> is missing $$id" prefix is preserved so existing tests and any
|
|
9
|
+
// log scrapers keep matching. Dev-only: the call sites guard on
|
|
10
|
+
// process.env.NODE_ENV === "development", so production builds fold the branch
|
|
11
|
+
// away and tree-shake this module out.
|
|
12
|
+
|
|
13
|
+
// create*() implementation files to skip when locating the user's call site.
|
|
14
|
+
const SELF_FILES = new Set([
|
|
15
|
+
"missing-id-error",
|
|
16
|
+
"loader",
|
|
17
|
+
"loader.rsc",
|
|
18
|
+
"handle",
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Best-effort "path:line:column" of the user's create*() call, parsed from the
|
|
23
|
+
* current stack. Skips @rangojs/router internals and node_modules. Returns
|
|
24
|
+
* undefined if nothing usable is found (stack parsing is inherently fragile).
|
|
25
|
+
*/
|
|
26
|
+
function findUserCallSite(): string | undefined {
|
|
27
|
+
try {
|
|
28
|
+
const stack = new Error().stack;
|
|
29
|
+
if (!stack) return undefined;
|
|
30
|
+
for (const frame of stack.split("\n").slice(1)) {
|
|
31
|
+
const m = frame.match(
|
|
32
|
+
/(?:\(|@|\s)(?:file:\/\/)?((?:\/|[A-Za-z]:[\\/])[^()\s]+?\.(?:ts|tsx|js|jsx|mts|cts)):(\d+):(\d+)\)?/,
|
|
33
|
+
);
|
|
34
|
+
if (!m) continue;
|
|
35
|
+
const path = m[1];
|
|
36
|
+
if (path.includes("node_modules") || path.includes("@rangojs/router")) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const base = path
|
|
40
|
+
.split(/[\\/]/)
|
|
41
|
+
.pop()!
|
|
42
|
+
.replace(/\.(?:ts|tsx|js|jsx|mts|cts)$/, "");
|
|
43
|
+
if (SELF_FILES.has(base)) continue;
|
|
44
|
+
return `${path}:${m[2]}:${m[3]}`;
|
|
45
|
+
}
|
|
46
|
+
} catch {
|
|
47
|
+
// best-effort only
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function missingInjectedIdError(
|
|
53
|
+
kind: "Loader" | "Handle",
|
|
54
|
+
fnName: "createLoader" | "createHandle",
|
|
55
|
+
): Error {
|
|
56
|
+
const site = findUserCallSite();
|
|
57
|
+
const at = site ? ` (created at ${site})` : "";
|
|
58
|
+
return new Error(
|
|
59
|
+
`[rango] ${kind} is missing $$id${at}.\n` +
|
|
60
|
+
`The @rangojs/router:expose-internal-ids Vite transform injects ${fnName}()'s ` +
|
|
61
|
+
`stable $$id from an EXPORTED const declaration only:\n` +
|
|
62
|
+
` export const X = ${fnName}(...)\n` +
|
|
63
|
+
` const X = ${fnName}(...); export { X }\n` +
|
|
64
|
+
`A non-exported const, an \`export let/var\`, or an inline ${fnName}(...) ` +
|
|
65
|
+
`call gets no $$id — export it as \`export const\`. (A matching ` +
|
|
66
|
+
`"Unsupported ${fnName} shape" warning names the exact file:line.)`,
|
|
67
|
+
);
|
|
68
|
+
}
|
package/src/outlet-context.ts
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useContext, useMemo, type ReactNode } from "react";
|
|
4
|
+
import { OutletContext, type OutletContextValue } from "./outlet-context.js";
|
|
5
|
+
import type { ResolvedSegment } from "./types.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Outlet content provider — stores parent context for useLoader chain walking.
|
|
9
|
+
*/
|
|
10
|
+
export function OutletProvider({
|
|
11
|
+
content,
|
|
12
|
+
parallel,
|
|
13
|
+
segment,
|
|
14
|
+
loaderData,
|
|
15
|
+
children,
|
|
16
|
+
}: {
|
|
17
|
+
content: ReactNode;
|
|
18
|
+
parallel?: ResolvedSegment[];
|
|
19
|
+
segment?: ResolvedSegment;
|
|
20
|
+
loaderData?: Record<string, any>;
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
}): ReactNode {
|
|
23
|
+
// Get parent context to enable walking up the chain for loader lookups
|
|
24
|
+
const parentContext = useContext(OutletContext);
|
|
25
|
+
|
|
26
|
+
const value = useMemo(
|
|
27
|
+
() => ({
|
|
28
|
+
content,
|
|
29
|
+
parallel,
|
|
30
|
+
segment,
|
|
31
|
+
loaderData,
|
|
32
|
+
parent: parentContext,
|
|
33
|
+
loading: segment?.loading,
|
|
34
|
+
}),
|
|
35
|
+
[content, parallel, segment, loaderData, parentContext],
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<OutletContext.Provider value={value}>{children}</OutletContext.Provider>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Deterministic param hashing for prerender storage keys.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* runtime (worker) to look up pre-rendered data. Both environments
|
|
6
|
-
* must produce identical hashes for the same params.
|
|
7
|
-
*
|
|
8
|
-
* Uses a simple DJB2-based hash that works in all JS environments
|
|
9
|
-
* (Node.js, Cloudflare Workers, browsers) without crypto imports.
|
|
3
|
+
* Used at build time and runtime; both must produce identical hashes.
|
|
4
|
+
* DJB2-based; works in all JS environments without crypto imports.
|
|
10
5
|
*/
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*/
|
|
7
|
+
import { encodeKV } from "../encode-kv.js";
|
|
8
|
+
|
|
9
|
+
// For static routes (no params), returns "_".
|
|
16
10
|
export function hashParams(params: Record<string, string>): string {
|
|
17
11
|
const entries = Object.entries(params);
|
|
18
12
|
if (entries.length === 0) return "_";
|
|
19
13
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
// Byte-order sort + encodeURIComponent join (see encodeKV); output is
|
|
15
|
+
// byte-identical to the prior inline implementation, so build-time and
|
|
16
|
+
// runtime hashes stay stable.
|
|
17
|
+
return djb2Hex(encodeKV(entries, { sort: true }));
|
|
23
18
|
}
|
|
24
19
|
|
|
25
20
|
/**
|
|
26
21
|
* DJB2 hash returning an 8-char hex string.
|
|
27
22
|
* Deterministic across all JS runtimes.
|
|
23
|
+
*
|
|
24
|
+
* 32-bit output: per-route collision probability hits ~50% near ~77k distinct
|
|
25
|
+
* param sets (birthday bound). The production store keys solely on
|
|
26
|
+
* routeName/paramHash and does not verify the canonical param string, so a
|
|
27
|
+
* collision serves the surviving entry for both param sets. Benign for typical
|
|
28
|
+
* catalogs; revisit (wider hash or stored-param verification) before
|
|
29
|
+
* pre-rendering hundreds of thousands of pages per route.
|
|
28
30
|
*/
|
|
29
31
|
function djb2Hex(str: string): string {
|
|
30
32
|
let hash = 5381;
|
package/src/prerender/store.ts
CHANGED
|
@@ -1,28 +1,59 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Prerender Store
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* The data is stored as globalThis.__PRERENDER_MANIFEST, a map of
|
|
6
|
-
* "<routeName>/<paramHash>" to dynamic import functions that resolve
|
|
7
|
-
* individual prerender entry modules.
|
|
2
|
+
* Prerender Store — reads pre-rendered segment data from the worker bundle.
|
|
3
|
+
* Manifest module (injected via globalThis.__loadPrerenderManifestModule)
|
|
4
|
+
* contains key-to-specifier map and loadPrerenderAsset for import() resolution.
|
|
8
5
|
*/
|
|
9
6
|
|
|
10
|
-
import type { SerializedSegmentData
|
|
7
|
+
import type { SerializedSegmentData } from "../cache/types.js";
|
|
11
8
|
|
|
12
9
|
export interface PrerenderEntry {
|
|
13
10
|
segments: SerializedSegmentData[];
|
|
14
|
-
|
|
11
|
+
/** RSC-encoded handle map (see handle-snapshot.ts encodeHandles); "" when the
|
|
12
|
+
* route pushed no handles. Encoded so Promise/ReactNode handle values survive
|
|
13
|
+
* the JSON-serialized build artifact / dev wire, identical to the runtime cache. */
|
|
14
|
+
handles: string;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export interface PrerenderStore {
|
|
18
|
-
get(
|
|
19
|
-
|
|
18
|
+
get(
|
|
19
|
+
routeName: string,
|
|
20
|
+
paramHash: string,
|
|
21
|
+
meta?: { pathname: string; isPassthroughRoute?: boolean },
|
|
22
|
+
): PrerenderEntry | null | Promise<PrerenderEntry | null>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface StaticEntry {
|
|
26
|
+
encoded: string;
|
|
27
|
+
/** RSC-encoded single-segment handle data (see encodeHandleValue); "" when the
|
|
28
|
+
* Static handler pushed no handles. */
|
|
29
|
+
handles: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface StaticStore {
|
|
33
|
+
get(handlerId: string): Promise<StaticEntry | null>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface PrerenderManifestModule {
|
|
37
|
+
default: Record<string, string>;
|
|
38
|
+
loadPrerenderAsset: (
|
|
39
|
+
specifier: string,
|
|
40
|
+
) => Promise<{ default: PrerenderEntry }>;
|
|
20
41
|
}
|
|
21
42
|
|
|
22
43
|
declare global {
|
|
23
|
-
// Injected by closeBundle post-processing:
|
|
44
|
+
// Injected by closeBundle post-processing: lazy loader for the prerender
|
|
45
|
+
// manifest module. The module exports a key→specifier map and a
|
|
46
|
+
// loadPrerenderAsset function that anchors import() relative to the manifest.
|
|
24
47
|
// eslint-disable-next-line no-var
|
|
25
|
-
var
|
|
48
|
+
var __loadPrerenderManifestModule:
|
|
49
|
+
| (() => Promise<PrerenderManifestModule>)
|
|
50
|
+
| undefined;
|
|
51
|
+
// Injected by closeBundle post-processing: map of handlerId -> () => import("./assets/__st-*.js")
|
|
52
|
+
// Asset default export is either a string (no handles) or { encoded, handles } object.
|
|
53
|
+
// eslint-disable-next-line no-var
|
|
54
|
+
var __STATIC_MANIFEST:
|
|
55
|
+
| Record<string, () => Promise<{ default: string | StaticEntry }>>
|
|
56
|
+
| undefined;
|
|
26
57
|
// Injected by virtual module in dev mode for on-demand prerender
|
|
27
58
|
// eslint-disable-next-line no-var
|
|
28
59
|
var __PRERENDER_DEV_URL: string | undefined;
|
|
@@ -35,9 +66,12 @@ declare global {
|
|
|
35
66
|
*/
|
|
36
67
|
export function createDevPrerenderStore(devUrl: string): PrerenderStore {
|
|
37
68
|
return {
|
|
38
|
-
async get(
|
|
69
|
+
async get(routeName, paramHash, meta) {
|
|
39
70
|
if (!meta?.pathname) return null;
|
|
40
|
-
const
|
|
71
|
+
const isIntercept = paramHash.endsWith("/i");
|
|
72
|
+
let url = `${devUrl}/__rsc_prerender?pathname=${encodeURIComponent(meta.pathname)}&routeName=${encodeURIComponent(routeName)}`;
|
|
73
|
+
if (isIntercept) url += "&intercept=1";
|
|
74
|
+
if (meta.isPassthroughRoute) url += "&passthrough=1";
|
|
41
75
|
try {
|
|
42
76
|
const res = await fetch(url);
|
|
43
77
|
if (!res.ok) return null;
|
|
@@ -52,17 +86,35 @@ export function createDevPrerenderStore(devUrl: string): PrerenderStore {
|
|
|
52
86
|
/**
|
|
53
87
|
* Create a prerender store.
|
|
54
88
|
* Dev mode: on-demand fetch from Vite dev server (node:fs works there).
|
|
55
|
-
* Production: backed by globalThis.
|
|
89
|
+
* Production: backed by globalThis.__loadPrerenderManifestModule which lazily
|
|
90
|
+
* loads the manifest module on first access.
|
|
56
91
|
* Returns null if no prerender data is available.
|
|
57
92
|
*/
|
|
58
93
|
export function createPrerenderStore(): PrerenderStore | null {
|
|
59
94
|
if (globalThis.__PRERENDER_DEV_URL) {
|
|
60
95
|
return createDevPrerenderStore(globalThis.__PRERENDER_DEV_URL);
|
|
61
96
|
}
|
|
62
|
-
|
|
63
|
-
if (!manifest || Object.keys(manifest).length === 0) return null;
|
|
97
|
+
if (!globalThis.__loadPrerenderManifestModule) return null;
|
|
64
98
|
|
|
65
99
|
const cache = new Map<string, Promise<PrerenderEntry | null>>();
|
|
100
|
+
let manifestModulePromise: Promise<PrerenderManifestModule> | null = null;
|
|
101
|
+
|
|
102
|
+
function loadManifestModule(): Promise<PrerenderManifestModule> {
|
|
103
|
+
if (!manifestModulePromise) {
|
|
104
|
+
// Do not cache a failed manifest-module load: clear the memoized promise
|
|
105
|
+
// on rejection so the next get() retries, and let the error propagate
|
|
106
|
+
// (consistent with the per-asset load policy below) instead of caching a
|
|
107
|
+
// null for the isolate lifetime, which would silently degrade every
|
|
108
|
+
// prerendered route to a miss after one transient failure.
|
|
109
|
+
manifestModulePromise = globalThis.__loadPrerenderManifestModule!().catch(
|
|
110
|
+
(err) => {
|
|
111
|
+
manifestModulePromise = null;
|
|
112
|
+
throw err;
|
|
113
|
+
},
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
return manifestModulePromise;
|
|
117
|
+
}
|
|
66
118
|
|
|
67
119
|
return {
|
|
68
120
|
get(routeName: string, paramHash: string): Promise<PrerenderEntry | null> {
|
|
@@ -70,11 +122,59 @@ export function createPrerenderStore(): PrerenderStore | null {
|
|
|
70
122
|
const cached = cache.get(key);
|
|
71
123
|
if (cached) return cached;
|
|
72
124
|
|
|
73
|
-
const
|
|
74
|
-
|
|
125
|
+
const promise = loadManifestModule().then((mod) => {
|
|
126
|
+
const specifier = mod.default[key];
|
|
127
|
+
if (!specifier) return null;
|
|
128
|
+
// Let asset load errors propagate — a missing/corrupted artifact
|
|
129
|
+
// for a key that exists in the manifest is a build/deploy error
|
|
130
|
+
// and should surface as a 500, not be silently swallowed as null
|
|
131
|
+
// (which the handler stub would misreport as a 404).
|
|
132
|
+
return mod.loadPrerenderAsset(specifier).then((asset) => asset.default);
|
|
133
|
+
});
|
|
134
|
+
// Only memoize once the manifest module resolved: a manifest-load
|
|
135
|
+
// rejection must not poison the per-key cache, or the retry above is moot.
|
|
136
|
+
cache.set(
|
|
137
|
+
key,
|
|
138
|
+
promise.catch((err) => {
|
|
139
|
+
cache.delete(key);
|
|
140
|
+
throw err;
|
|
141
|
+
}),
|
|
142
|
+
);
|
|
143
|
+
return promise;
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Create a static segment store.
|
|
150
|
+
* Production only: backed by globalThis.__STATIC_MANIFEST injected at build time.
|
|
151
|
+
* Returns null if no static data is available (dev mode or no Static handlers).
|
|
152
|
+
*/
|
|
153
|
+
export function createStaticStore(): StaticStore | null {
|
|
154
|
+
const manifest = globalThis.__STATIC_MANIFEST;
|
|
155
|
+
if (!manifest || Object.keys(manifest).length === 0) return null;
|
|
156
|
+
|
|
157
|
+
const cache = new Map<string, Promise<StaticEntry | null>>();
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
get(handlerId: string): Promise<StaticEntry | null> {
|
|
161
|
+
const cached = cache.get(handlerId);
|
|
162
|
+
if (cached) return cached;
|
|
163
|
+
|
|
164
|
+
const importFn = manifest[handlerId];
|
|
165
|
+
if (!importFn) return Promise.resolve(null);
|
|
75
166
|
|
|
76
|
-
const promise =
|
|
77
|
-
|
|
167
|
+
const promise = importFn()
|
|
168
|
+
.then((mod) => {
|
|
169
|
+
const val = mod.default;
|
|
170
|
+
// Normalize: string-only (no handles) or { encoded, handles }
|
|
171
|
+
if (typeof val === "string") {
|
|
172
|
+
return { encoded: val, handles: "" } as StaticEntry;
|
|
173
|
+
}
|
|
174
|
+
return val as StaticEntry;
|
|
175
|
+
})
|
|
176
|
+
.catch(() => null);
|
|
177
|
+
cache.set(handlerId, promise);
|
|
78
178
|
return promise;
|
|
79
179
|
},
|
|
80
180
|
};
|