@rangojs/router 0.0.0-experimental.14 → 0.0.0-experimental.141
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +17 -0
- package/README.md +432 -7
- package/dist/bin/rango.js +2073 -213
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +7258 -2714
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +140 -67
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +329 -0
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +487 -0
- package/skills/caching/SKILL.md +357 -25
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +246 -0
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +16 -10
- package/skills/document-cache/SKILL.md +87 -62
- package/skills/fonts/SKILL.md +6 -4
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +557 -79
- package/skills/host-router/SKILL.md +320 -0
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +207 -15
- package/skills/layout/SKILL.md +146 -6
- package/skills/links/SKILL.md +304 -25
- package/skills/loader/SKILL.md +616 -54
- package/skills/middleware/SKILL.md +217 -37
- package/skills/migrate-nextjs/SKILL.md +611 -0
- package/skills/migrate-react-router/SKILL.md +927 -0
- package/skills/mime-routes/SKILL.md +42 -11
- package/skills/observability/SKILL.md +194 -0
- package/skills/parallel/SKILL.md +284 -3
- package/skills/ppr/SKILL.md +293 -0
- package/skills/prerender/SKILL.md +437 -52
- package/skills/rango/SKILL.md +369 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +263 -121
- package/skills/route/SKILL.md +350 -21
- package/skills/router-setup/SKILL.md +246 -33
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +126 -222
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +131 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +85 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/theme/SKILL.md +9 -8
- package/skills/typesafety/SKILL.md +532 -103
- package/skills/use-cache/SKILL.md +367 -0
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +77 -44
- package/src/bin/rango.ts +312 -15
- package/src/browser/action-coordinator.ts +114 -0
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +293 -202
- package/src/browser/history-state.ts +101 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/intercept-utils.ts +52 -0
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/link-interceptor.ts +24 -4
- package/src/browser/logging.ts +11 -0
- package/src/browser/merge-segment-loaders.ts +20 -12
- package/src/browser/navigation-bridge.ts +385 -576
- package/src/browser/navigation-client.ts +245 -75
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +184 -118
- package/src/browser/navigation-transaction.ts +247 -0
- package/src/browser/network-error-handler.ts +88 -0
- package/src/browser/partial-update.ts +412 -364
- package/src/browser/prefetch/cache.ts +359 -0
- package/src/browser/prefetch/fetch.ts +452 -0
- package/src/browser/prefetch/observer.ts +65 -0
- package/src/browser/prefetch/policy.ts +48 -0
- package/src/browser/prefetch/queue.ts +209 -0
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +194 -0
- package/src/browser/react/Link.tsx +275 -68
- package/src/browser/react/NavigationProvider.tsx +265 -109
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +11 -0
- package/src/browser/react/filter-segment-order.ts +70 -0
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +272 -60
- package/src/browser/react/location-state.ts +90 -20
- package/src/browser/react/mount-context.ts +6 -1
- package/src/browser/react/nonce-context.ts +23 -0
- package/src/browser/react/shallow-equal.ts +27 -0
- package/src/browser/react/use-action.ts +35 -66
- package/src/browser/react/use-handle.ts +39 -126
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +39 -13
- package/src/browser/react/use-navigation.ts +53 -69
- package/src/browser/react/use-params.ts +75 -0
- package/src/browser/react/use-pathname.ts +47 -0
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +98 -0
- package/src/browser/react/use-search-params.ts +51 -0
- package/src/browser/react/use-segments.ts +72 -99
- package/src/browser/response-adapter.ts +164 -0
- package/src/browser/rsc-router.tsx +300 -72
- package/src/browser/scroll-restoration.ts +138 -50
- package/src/browser/segment-reconciler.ts +243 -0
- package/src/browser/segment-structure-assert.ts +17 -1
- package/src/browser/server-action-bridge.ts +668 -613
- package/src/browser/types.ts +223 -51
- package/src/browser/validate-redirect-origin.ts +56 -0
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +252 -161
- package/src/build/generate-route-types.ts +41 -1038
- package/src/build/index.ts +12 -7
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +225 -42
- package/src/build/route-types/ast-helpers.ts +25 -0
- package/src/build/route-types/ast-route-extraction.ts +105 -0
- package/src/build/route-types/codegen.ts +113 -0
- package/src/build/route-types/include-resolution.ts +812 -0
- package/src/build/route-types/param-extraction.ts +51 -0
- package/src/build/route-types/per-module-writer.ts +144 -0
- package/src/build/route-types/router-processing.ts +695 -0
- package/src/build/route-types/scan-filter.ts +85 -0
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +223 -0
- package/src/cache/background-task.ts +34 -0
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +60 -0
- package/src/cache/cache-policy.ts +199 -0
- package/src/cache/cache-runtime.ts +525 -0
- package/src/cache/cache-scope.ts +298 -332
- package/src/cache/cache-tag.ts +103 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +2508 -158
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +17 -17
- package/src/cache/document-cache.ts +199 -92
- package/src/cache/handle-capture.ts +81 -0
- package/src/cache/handle-snapshot.ts +111 -0
- package/src/cache/index.ts +24 -35
- package/src/cache/memory-segment-store.ts +363 -30
- package/src/cache/profile-registry.ts +88 -0
- package/src/cache/read-through-swr.ts +178 -0
- package/src/cache/segment-codec.ts +248 -0
- package/src/cache/shell-snapshot.ts +368 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +153 -0
- package/src/cache/types.ts +222 -211
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1113 -0
- package/src/client.rsc.tsx +43 -21
- package/src/client.tsx +131 -347
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/component-utils.ts +23 -4
- package/src/components/DefaultDocument.tsx +13 -3
- package/src/context-var.ts +168 -0
- package/src/debug.ts +19 -9
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +106 -10
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +110 -35
- package/src/handles/MetaTags.tsx +83 -59
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +93 -0
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +44 -53
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +20 -65
- package/src/host/errors.ts +21 -30
- package/src/host/index.ts +13 -9
- package/src/host/pattern-matcher.ts +50 -79
- package/src/host/router.ts +151 -121
- package/src/host/testing.ts +45 -32
- package/src/host/types.ts +52 -11
- package/src/host/utils.ts +2 -2
- package/src/href-client.ts +192 -57
- package/src/index.rsc.ts +173 -35
- package/src/index.ts +241 -73
- package/src/internal-debug.ts +9 -2
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +31 -99
- package/src/loader.ts +30 -12
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +41 -0
- package/src/prerender/param-hash.ts +16 -14
- package/src/prerender/store.ts +121 -21
- package/src/prerender.ts +460 -26
- package/src/redirect-origin.ts +100 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +62 -0
- package/src/reverse.ts +198 -128
- package/src/root-error-boundary.tsx +42 -48
- package/src/route-content-wrapper.tsx +22 -77
- package/src/route-definition/dsl-helpers.ts +1116 -0
- package/src/route-definition/helper-factories.ts +88 -0
- package/src/route-definition/helpers-types.ts +505 -0
- package/src/route-definition/index.ts +54 -0
- package/src/route-definition/redirect.ts +134 -0
- package/src/route-definition/resolve-handler-use.ts +160 -0
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-definition.ts +1 -1481
- package/src/route-map-builder.ts +82 -144
- package/src/route-name.ts +53 -0
- package/src/route-types.ts +71 -45
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +263 -0
- package/src/router/debug-manifest.ts +72 -0
- package/src/router/error-handling.ts +54 -27
- package/src/router/find-match.ts +245 -0
- package/src/router/handler-context.ts +377 -125
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +59 -28
- package/src/router/lazy-includes.ts +254 -0
- package/src/router/loader-resolution.ts +421 -157
- package/src/router/logging.ts +106 -6
- package/src/router/manifest.ts +131 -57
- package/src/router/match-api.ts +167 -246
- package/src/router/match-context.ts +4 -24
- package/src/router/match-handlers.ts +440 -0
- package/src/router/match-middleware/background-revalidation.ts +117 -93
- package/src/router/match-middleware/cache-lookup.ts +297 -150
- package/src/router/match-middleware/cache-store.ts +123 -51
- package/src/router/match-middleware/intercept-resolution.ts +44 -43
- package/src/router/match-middleware/segment-resolution.ts +64 -22
- package/src/router/match-pipelines.ts +11 -87
- package/src/router/match-result.ts +121 -50
- package/src/router/metrics.ts +219 -28
- package/src/router/middleware-types.ts +93 -0
- package/src/router/middleware.ts +505 -441
- package/src/router/navigation-snapshot.ts +133 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +311 -142
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +547 -0
- package/src/router/preview-match.ts +102 -0
- package/src/router/request-classification.ts +278 -0
- package/src/router/revalidation.ts +203 -62
- package/src/router/route-snapshot.ts +246 -0
- package/src/router/router-context.ts +45 -48
- package/src/router/router-interfaces.ts +554 -0
- package/src/router/router-options.ts +779 -0
- package/src/router/router-registry.ts +21 -0
- package/src/router/segment-resolution/fresh.ts +772 -0
- package/src/router/segment-resolution/helpers.ts +348 -0
- package/src/router/segment-resolution/loader-cache.ts +250 -0
- package/src/router/segment-resolution/loader-mask.ts +44 -0
- package/src/router/segment-resolution/revalidation.ts +1331 -0
- package/src/router/segment-resolution/static-store.ts +81 -0
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +56 -0
- package/src/router/segment-resolution.ts +25 -1354
- package/src/router/segment-wrappers.ts +292 -0
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +261 -0
- package/src/router/telemetry.ts +377 -0
- package/src/router/timeout.ts +128 -0
- package/src/router/tracing.ts +206 -0
- package/src/router/trie-matching.ts +240 -61
- package/src/router/types.ts +23 -70
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +781 -2378
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +46 -0
- package/src/rsc/handler.ts +905 -1142
- package/src/rsc/helpers.ts +275 -19
- package/src/rsc/index.ts +2 -25
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +305 -0
- package/src/rsc/manifest-init.ts +77 -0
- package/src/rsc/nonce.ts +14 -0
- package/src/rsc/origin-guard.ts +155 -0
- package/src/rsc/progressive-enhancement.ts +502 -0
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +104 -0
- package/src/rsc/response-route-handler.ts +257 -0
- package/src/rsc/rsc-rendering.ts +527 -0
- package/src/rsc/runtime-warnings.ts +55 -0
- package/src/rsc/server-action.ts +522 -0
- package/src/rsc/shell-capture.ts +897 -0
- package/src/rsc/shell-serve.ts +124 -0
- package/src/rsc/ssr-setup.ts +144 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +95 -12
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +99 -82
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +149 -0
- package/src/segment-system.tsx +349 -134
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +459 -85
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +310 -0
- package/src/server/fetchable-loader-store.ts +11 -6
- package/src/server/handle-store.ts +123 -42
- package/src/server/loader-registry.ts +51 -100
- package/src/server/request-context.ts +848 -157
- package/src/server.ts +15 -8
- package/src/ssr/index.tsx +443 -135
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +45 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +701 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +257 -0
- package/src/testing/generated-routes.ts +199 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +357 -0
- package/src/testing/render-route.tsx +584 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +305 -0
- package/src/theme/ThemeProvider.tsx +76 -98
- package/src/theme/ThemeScript.tsx +12 -14
- package/src/theme/constants.ts +57 -15
- package/src/theme/index.ts +3 -20
- package/src/theme/theme-context.ts +5 -35
- package/src/theme/theme-script.ts +43 -39
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +123 -0
- package/src/types/cache-types.ts +207 -0
- package/src/types/error-types.ts +132 -0
- package/src/types/global-namespace.ts +113 -0
- package/src/types/handler-context.ts +839 -0
- package/src/types/index.ts +81 -0
- package/src/types/loader-types.ts +212 -0
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +138 -0
- package/src/types/route-entry.ts +114 -0
- package/src/types/segments.ts +271 -0
- package/src/types.ts +1 -1795
- package/src/urls/include-helper.ts +162 -0
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +44 -0
- package/src/urls/path-helper-types.ts +413 -0
- package/src/urls/path-helper.ts +280 -0
- package/src/urls/pattern-types.ts +160 -0
- package/src/urls/response-types.ts +109 -0
- package/src/urls/type-extraction.ts +316 -0
- package/src/urls/urls-function.ts +80 -0
- package/src/urls.ts +1 -1341
- package/src/use-loader.tsx +406 -141
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +182 -0
- package/src/vite/discovery/discover-routers.ts +389 -0
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +467 -0
- package/src/vite/discovery/route-types-writer.ts +214 -0
- package/src/vite/discovery/self-gen-tracking.ts +73 -0
- package/src/vite/discovery/state.ts +161 -0
- package/src/vite/discovery/virtual-module-codegen.ts +183 -0
- package/src/vite/index.ts +23 -2255
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +303 -0
- package/src/vite/plugins/cjs-to-esm.ts +90 -0
- package/src/vite/plugins/client-ref-dedup.ts +120 -0
- package/src/vite/plugins/client-ref-hashing.ts +118 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +194 -0
- package/src/vite/{expose-action-id.ts → plugins/expose-action-id.ts} +88 -110
- package/src/vite/{expose-id-utils.ts → plugins/expose-id-utils.ts} +89 -79
- package/src/vite/plugins/expose-ids/export-analysis.ts +363 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +130 -0
- package/src/vite/plugins/expose-ids/loader-transform.ts +64 -0
- package/src/vite/plugins/expose-ids/router-transform.ts +199 -0
- package/src/vite/plugins/expose-ids/types.ts +45 -0
- package/src/vite/plugins/expose-internal-ids.ts +805 -0
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +127 -0
- package/src/vite/plugins/use-cache-transform.ts +313 -0
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +94 -0
- package/src/vite/plugins/version-plugin.ts +263 -0
- package/src/vite/plugins/virtual-entries.ts +234 -0
- package/src/vite/plugins/virtual-stub-plugin.ts +29 -0
- package/src/vite/rango.ts +560 -0
- package/src/vite/router-discovery.ts +1638 -0
- package/src/vite/{ast-handler-extract.ts → utils/ast-handler-extract.ts} +200 -37
- package/src/vite/utils/banner.ts +36 -0
- package/src/vite/utils/bundle-analysis.ts +132 -0
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +15 -0
- package/src/vite/utils/package-resolution.ts +89 -0
- package/src/vite/utils/prerender-utils.ts +249 -0
- package/src/vite/utils/shared-utils.ts +269 -0
- package/CLAUDE.md +0 -43
- package/dist/vite/index.named-routes.gen.ts +0 -103
- package/src/browser/lru-cache.ts +0 -69
- package/src/browser/react/use-client-cache.ts +0 -56
- package/src/browser/request-controller.ts +0 -164
- package/src/browser/shallow.ts +0 -35
- package/src/cache/memory-store.ts +0 -253
- package/src/handles/index.ts +0 -6
- package/src/href-context.ts +0 -33
- package/src/network-error-thrower.tsx +0 -21
- package/src/router.gen.ts +0 -6
- package/src/static-handler.gen.ts +0 -5
- package/src/urls.gen.ts +0 -8
- package/src/vite/expose-internal-ids.ts +0 -1167
- package/src/vite/package-resolution.ts +0 -125
- package/src/vite/virtual-entries.ts +0 -114
- /package/src/vite/{version.d.ts → plugins/version.d.ts} +0 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type { AllUseItems, IncludeItem } from "../route-types.js";
|
|
2
|
+
import {
|
|
3
|
+
getUrlPrefix,
|
|
4
|
+
getNamePrefix,
|
|
5
|
+
requireDslContext,
|
|
6
|
+
} from "../server/context";
|
|
7
|
+
import {
|
|
8
|
+
INTERNAL_INCLUDE_SCOPE_PREFIX,
|
|
9
|
+
validateUserRouteName,
|
|
10
|
+
} from "../route-name.js";
|
|
11
|
+
import type { UrlPatterns, IncludeOptions } from "./pattern-types.js";
|
|
12
|
+
import type { IncludeProvider } from "./include-provider.js";
|
|
13
|
+
import type { IncludeFn } from "./path-helper-types.js";
|
|
14
|
+
|
|
15
|
+
function hasExplicitNameOption(options: IncludeOptions | undefined): boolean {
|
|
16
|
+
return !!options && Object.prototype.hasOwnProperty.call(options, "name");
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function allocateInternalIncludeScopeId(
|
|
20
|
+
counters: Record<string, number>,
|
|
21
|
+
): string {
|
|
22
|
+
const key = "__include_scope__";
|
|
23
|
+
const index = counters[key] ?? 0;
|
|
24
|
+
counters[key] = index + 1;
|
|
25
|
+
return `${INTERNAL_INCLUDE_SCOPE_PREFIX}${index}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Recursively walk items, recursing into layout children.
|
|
30
|
+
*
|
|
31
|
+
* All includes are lazy and kept as-is; the router expands them on the first
|
|
32
|
+
* matching request.
|
|
33
|
+
*/
|
|
34
|
+
export function processItems(items: readonly AllUseItems[]): AllUseItems[] {
|
|
35
|
+
const result: AllUseItems[] = [];
|
|
36
|
+
|
|
37
|
+
for (const item of items) {
|
|
38
|
+
if (!item) continue;
|
|
39
|
+
|
|
40
|
+
if (item.type === "include") {
|
|
41
|
+
result.push(item);
|
|
42
|
+
} else if (item.type === "layout" && (item as any).uses) {
|
|
43
|
+
const layoutItem = item as any;
|
|
44
|
+
layoutItem.uses = processItems(layoutItem.uses);
|
|
45
|
+
result.push(layoutItem);
|
|
46
|
+
} else {
|
|
47
|
+
result.push(item);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Create include() helper for composing URL patterns
|
|
56
|
+
*
|
|
57
|
+
* All includes are lazy: the nested patterns are NOT expanded at definition
|
|
58
|
+
* time. Instead they are evaluated on the first request that matches the
|
|
59
|
+
* prefix, which improves cold start time for apps with many routes.
|
|
60
|
+
*/
|
|
61
|
+
export function createIncludeHelper<TEnv>(): IncludeFn<TEnv> {
|
|
62
|
+
return (
|
|
63
|
+
prefix: string,
|
|
64
|
+
// A `urls()` value (eager) OR an async provider thunk
|
|
65
|
+
// (`() => import("./routes")`) whose evaluation is deferred to the first
|
|
66
|
+
// request matching `prefix`. The provider is stored unevaluated and
|
|
67
|
+
// resolved by the runtime lazy-include expansion / build-time discovery.
|
|
68
|
+
patterns: UrlPatterns<TEnv> | IncludeProvider<TEnv>,
|
|
69
|
+
options?: IncludeOptions,
|
|
70
|
+
): IncludeItem => {
|
|
71
|
+
const { ctx } = requireDslContext("include() must be called inside urls()");
|
|
72
|
+
|
|
73
|
+
const explicitName = options?.name;
|
|
74
|
+
const hasExplicitName = hasExplicitNameOption(options);
|
|
75
|
+
if (hasExplicitName && explicitName) {
|
|
76
|
+
validateUserRouteName(explicitName);
|
|
77
|
+
}
|
|
78
|
+
const name = `$include_${prefix.replace(/[/:*?]/g, "_")}`;
|
|
79
|
+
|
|
80
|
+
// Capture context for deferred evaluation
|
|
81
|
+
const capturedUrlPrefix = getUrlPrefix();
|
|
82
|
+
const capturedNamePrefix = getNamePrefix();
|
|
83
|
+
const capturedParent = ctx.parent;
|
|
84
|
+
const fullPrefix = capturedUrlPrefix
|
|
85
|
+
? capturedUrlPrefix.endsWith("/") && prefix.startsWith("/")
|
|
86
|
+
? capturedUrlPrefix + prefix.slice(1)
|
|
87
|
+
: capturedUrlPrefix + prefix
|
|
88
|
+
: prefix;
|
|
89
|
+
const nextSegment = hasExplicitName
|
|
90
|
+
? explicitName
|
|
91
|
+
: allocateInternalIncludeScopeId(ctx.counters);
|
|
92
|
+
const fullNamePrefix =
|
|
93
|
+
nextSegment !== undefined && nextSegment !== ""
|
|
94
|
+
? capturedNamePrefix
|
|
95
|
+
? `${capturedNamePrefix}.${nextSegment}`
|
|
96
|
+
: nextSegment
|
|
97
|
+
: capturedNamePrefix;
|
|
98
|
+
|
|
99
|
+
// Track this include for build-time manifest generation
|
|
100
|
+
if (ctx.trackedIncludes) {
|
|
101
|
+
ctx.trackedIncludes.push({
|
|
102
|
+
prefix,
|
|
103
|
+
fullPrefix,
|
|
104
|
+
namePrefix: fullNamePrefix,
|
|
105
|
+
patterns,
|
|
106
|
+
lazy: true,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Allocate an include-scope token for this include() call. The token is
|
|
111
|
+
// appended to the parent's shortCode prefix whenever the include's
|
|
112
|
+
// direct-descendant shortCodes are generated (see getShortCode in
|
|
113
|
+
// context.ts), partitioning the parent's counter namespace so routes
|
|
114
|
+
// inside an include cannot collide with siblings declared outside it.
|
|
115
|
+
//
|
|
116
|
+
// Scopes compose: a nested include inside an outer include with scope
|
|
117
|
+
// "I0" allocates against the `${parent.shortCode}I0_include` counter
|
|
118
|
+
// and produces scope "I0I0", "I0I1", etc.
|
|
119
|
+
const parentScope = ctx.includeScope ?? "";
|
|
120
|
+
let includeScope = parentScope;
|
|
121
|
+
if (capturedParent?.shortCode) {
|
|
122
|
+
const includeCounterKey = `${capturedParent.shortCode}${parentScope}_include`;
|
|
123
|
+
ctx.counters[includeCounterKey] ??= 0;
|
|
124
|
+
includeScope = `${parentScope}I${ctx.counters[includeCounterKey]++}`;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Snapshot parent's counters AFTER allocating the include scope so lazy
|
|
128
|
+
// manifest generation starts with the same counter state this include
|
|
129
|
+
// observed — its descendants still get fresh per-scope counters because
|
|
130
|
+
// they key off `${parent.shortCode}${includeScope}_*` (not shared with
|
|
131
|
+
// siblings outside the include).
|
|
132
|
+
const capturedCounters = { ...ctx.counters };
|
|
133
|
+
|
|
134
|
+
// Compute rootScoped at capture time, mirroring the logic in runWithPrefixes.
|
|
135
|
+
// This ensures lazy evaluation restores the correct scope state.
|
|
136
|
+
const parentRootScoped = ctx.rootScoped;
|
|
137
|
+
const capturedRootScoped =
|
|
138
|
+
nextSegment === ""
|
|
139
|
+
? (parentRootScoped ?? true)
|
|
140
|
+
: nextSegment !== undefined
|
|
141
|
+
? (parentRootScoped ?? false)
|
|
142
|
+
: parentRootScoped;
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
type: "include",
|
|
146
|
+
name,
|
|
147
|
+
prefix,
|
|
148
|
+
patterns,
|
|
149
|
+
options,
|
|
150
|
+
lazy: true,
|
|
151
|
+
_lazyContext: {
|
|
152
|
+
urlPrefix: capturedUrlPrefix,
|
|
153
|
+
namePrefix: fullNamePrefix,
|
|
154
|
+
parent: capturedParent,
|
|
155
|
+
counters: capturedCounters,
|
|
156
|
+
cacheProfiles: ctx.cacheProfiles,
|
|
157
|
+
rootScoped: capturedRootScoped,
|
|
158
|
+
includeScope,
|
|
159
|
+
},
|
|
160
|
+
} as IncludeItem;
|
|
161
|
+
};
|
|
162
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { UrlPatterns } from "./pattern-types.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* What an async `include()` provider may resolve to: a `urls()` value directly,
|
|
5
|
+
* or a module namespace whose `default` export is a `urls()` value (the shape
|
|
6
|
+
* produced by `() => import("./routes")` when the route module does
|
|
7
|
+
* `export default urls(...)`).
|
|
8
|
+
*/
|
|
9
|
+
export type IncludeModule<TEnv = any> =
|
|
10
|
+
| UrlPatterns<TEnv>
|
|
11
|
+
| { default: UrlPatterns<TEnv> };
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* An async/lazy include provider: a thunk returning a `urls()` value (or a
|
|
15
|
+
* Promise of one). The thunk is stored unevaluated by `include()` and called
|
|
16
|
+
* once, on the first request that matches the prefix — so the route module and
|
|
17
|
+
* its (code-split) subtree are not evaluated at startup.
|
|
18
|
+
*
|
|
19
|
+
* Forward-compatible: `() => import("./routes")` today (async, separate chunk);
|
|
20
|
+
* `() => m.routes` with native `import defer` later (sync, deferred eval).
|
|
21
|
+
*/
|
|
22
|
+
export type IncludeProvider<TEnv = any> = () =>
|
|
23
|
+
| IncludeModule<TEnv>
|
|
24
|
+
| Promise<IncludeModule<TEnv>>;
|
|
25
|
+
|
|
26
|
+
/** True when the include() argument is a provider thunk rather than a value. */
|
|
27
|
+
export function isIncludeProvider(value: unknown): value is IncludeProvider {
|
|
28
|
+
// A `urls()` value is a (branded) object; a provider is a function.
|
|
29
|
+
return typeof value === "function";
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** A `urls()` value is an object exposing a synchronous `handler()`. */
|
|
33
|
+
function isUrlPatterns(value: unknown): value is UrlPatterns {
|
|
34
|
+
return (
|
|
35
|
+
!!value && typeof (value as { handler?: unknown }).handler === "function"
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Normalize an async provider's resolved value to a `UrlPatterns`. Accepts a
|
|
41
|
+
* `urls()` value directly or a module whose `default` export is one.
|
|
42
|
+
*/
|
|
43
|
+
export function resolveIncludeModule<TEnv = any>(
|
|
44
|
+
mod: IncludeModule<TEnv>,
|
|
45
|
+
id?: string,
|
|
46
|
+
): UrlPatterns<TEnv> {
|
|
47
|
+
// Prefer an explicit `default` export (the `export default urls(...)`
|
|
48
|
+
// convention) BEFORE duck-typing the namespace. isUrlPatterns() keys on a
|
|
49
|
+
// `.handler` function, but a routes module can legitimately carry a NAMED
|
|
50
|
+
// `export function handler(...)` alongside its `export default urls(...)`;
|
|
51
|
+
// checking the namespace first would then misidentify the whole module as the
|
|
52
|
+
// urls() value and invoke the user's helper as the DSL handler (the group
|
|
53
|
+
// 404s with a misleading error). A bare `() => urls(...)` provider (no
|
|
54
|
+
// module) has no `default`, so it still resolves via the mod-as-value branch.
|
|
55
|
+
const def = (mod as { default?: unknown })?.default;
|
|
56
|
+
if (isUrlPatterns(def)) return def as UrlPatterns<TEnv>;
|
|
57
|
+
if (isUrlPatterns(mod)) return mod as UrlPatterns<TEnv>;
|
|
58
|
+
// The common failure is a module namespace whose `default` is missing or not a
|
|
59
|
+
// urls() value (e.g. only named exports); `typeof` alone says "object" and
|
|
60
|
+
// hides that, so name the keys present. "provider" (not "async provider") —
|
|
61
|
+
// synchronous providers are supported (see IncludeProvider).
|
|
62
|
+
const got =
|
|
63
|
+
mod && typeof mod === "object"
|
|
64
|
+
? `a module with keys [${Object.keys(mod).join(", ") || "none"}] but no valid \`default\``
|
|
65
|
+
: typeof mod;
|
|
66
|
+
throw new Error(
|
|
67
|
+
`[@rangojs/router] include() provider${id ? ` for "${id}"` : ""} must ` +
|
|
68
|
+
`resolve to a urls() value — either returned directly or as the module's ` +
|
|
69
|
+
`\`default\` export (e.g. \`export default urls(...)\`). Got ${got}.`,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export {
|
|
2
|
+
RESPONSE_TYPE,
|
|
3
|
+
type ResponseHandler,
|
|
4
|
+
type JsonValue,
|
|
5
|
+
type JsonResponseHandler,
|
|
6
|
+
type TextResponseHandler,
|
|
7
|
+
type ResponseHandlerContext,
|
|
8
|
+
} from "./response-types.js";
|
|
9
|
+
|
|
10
|
+
export type {
|
|
11
|
+
UnnamedRoute,
|
|
12
|
+
LocalOnlyInclude,
|
|
13
|
+
PathOptions,
|
|
14
|
+
PartialPrerenderProps,
|
|
15
|
+
UrlPatterns,
|
|
16
|
+
IncludeOptions,
|
|
17
|
+
} from "./pattern-types.js";
|
|
18
|
+
|
|
19
|
+
export type {
|
|
20
|
+
ExtractRoutes,
|
|
21
|
+
ExtractResponses,
|
|
22
|
+
ProblemDetails,
|
|
23
|
+
RouteResponse,
|
|
24
|
+
} from "./type-extraction.js";
|
|
25
|
+
|
|
26
|
+
export type {
|
|
27
|
+
PathFn,
|
|
28
|
+
ResponsePathFn,
|
|
29
|
+
JsonResponsePathFn,
|
|
30
|
+
TextResponsePathFn,
|
|
31
|
+
IncludeFn,
|
|
32
|
+
PathHelpers,
|
|
33
|
+
} from "./path-helper-types.js";
|
|
34
|
+
|
|
35
|
+
export { urls } from "./urls-function.js";
|
|
36
|
+
|
|
37
|
+
export type {
|
|
38
|
+
AllUseItems,
|
|
39
|
+
IncludeItem,
|
|
40
|
+
TypedRouteItem,
|
|
41
|
+
TypedIncludeItem,
|
|
42
|
+
TypedLayoutItem,
|
|
43
|
+
TypedCacheItem,
|
|
44
|
+
} from "../route-types.js";
|
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type {
|
|
3
|
+
ErrorBoundaryHandler,
|
|
4
|
+
ExtractParams,
|
|
5
|
+
Handler,
|
|
6
|
+
HandlerContext,
|
|
7
|
+
LoaderDefinition,
|
|
8
|
+
MiddlewareFn,
|
|
9
|
+
NotFoundBoundaryHandler,
|
|
10
|
+
PartialCacheOptions,
|
|
11
|
+
ShouldRevalidateFn,
|
|
12
|
+
TransitionConfig,
|
|
13
|
+
} from "../types.js";
|
|
14
|
+
import type {
|
|
15
|
+
AllUseItems,
|
|
16
|
+
TypedLayoutItem,
|
|
17
|
+
ParallelItem,
|
|
18
|
+
InterceptItem,
|
|
19
|
+
MiddlewareItem,
|
|
20
|
+
RevalidateItem,
|
|
21
|
+
LoaderItem,
|
|
22
|
+
LoadingItem,
|
|
23
|
+
ErrorBoundaryItem,
|
|
24
|
+
NotFoundBoundaryItem,
|
|
25
|
+
LayoutUseItem,
|
|
26
|
+
RouteUseItem,
|
|
27
|
+
ResponseRouteUseItem,
|
|
28
|
+
ParallelUseItem,
|
|
29
|
+
InterceptUseItem,
|
|
30
|
+
LoaderUseItem,
|
|
31
|
+
TypedCacheItem,
|
|
32
|
+
TransitionItem,
|
|
33
|
+
TypedTransitionItem,
|
|
34
|
+
TypedRouteItem,
|
|
35
|
+
TypedIncludeItem,
|
|
36
|
+
UseItems,
|
|
37
|
+
} from "../route-types.js";
|
|
38
|
+
import type { SearchSchema } from "../search-params.js";
|
|
39
|
+
import type {
|
|
40
|
+
PrerenderHandlerDefinition,
|
|
41
|
+
PassthroughHandlerDefinition,
|
|
42
|
+
} from "../prerender.js";
|
|
43
|
+
import type { StaticHandlerDefinition } from "../static-handler.js";
|
|
44
|
+
import type {
|
|
45
|
+
ResponseHandler,
|
|
46
|
+
ResponseHandlerContext,
|
|
47
|
+
TextResponseHandler,
|
|
48
|
+
} from "./response-types.js";
|
|
49
|
+
import type {
|
|
50
|
+
UnnamedRoute,
|
|
51
|
+
LocalOnlyInclude,
|
|
52
|
+
PathOptions,
|
|
53
|
+
UrlPatterns,
|
|
54
|
+
IncludeOptions,
|
|
55
|
+
} from "./pattern-types.js";
|
|
56
|
+
import type { ExtractRoutes, ExtractResponses } from "./type-extraction.js";
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Base path function signature for defining routes with URL patterns.
|
|
60
|
+
*/
|
|
61
|
+
export type PathFn<TEnv> = <
|
|
62
|
+
const TPattern extends string,
|
|
63
|
+
const TName extends string = UnnamedRoute,
|
|
64
|
+
const TSearch extends SearchSchema = {},
|
|
65
|
+
TParams extends Record<string, any> = ExtractParams<TPattern>,
|
|
66
|
+
>(
|
|
67
|
+
pattern: TPattern,
|
|
68
|
+
handler:
|
|
69
|
+
| ReactNode
|
|
70
|
+
| ((
|
|
71
|
+
ctx: HandlerContext<TParams, TEnv, TSearch>,
|
|
72
|
+
) => ReactNode | Promise<ReactNode> | Response | Promise<Response>)
|
|
73
|
+
| PrerenderHandlerDefinition<TParams>
|
|
74
|
+
| PassthroughHandlerDefinition<TParams, TEnv>
|
|
75
|
+
| StaticHandlerDefinition<TParams>,
|
|
76
|
+
optionsOrUse?: PathOptions<TName, TSearch> | (() => UseItems<RouteUseItem>),
|
|
77
|
+
use?: () => UseItems<RouteUseItem>,
|
|
78
|
+
// Generic handler bypass: when handler uses index-signature params
|
|
79
|
+
// (e.g. Handler<Record<string, any>>), skip the biconditional.
|
|
80
|
+
// `string extends keyof TParams` is true for index signatures,
|
|
81
|
+
// false for concrete params ({id: string}) and empty ({}).
|
|
82
|
+
//
|
|
83
|
+
// Subset check: pattern params must be assignable to handler params,
|
|
84
|
+
// but handler can have MORE params (e.g. from parent include() prefix).
|
|
85
|
+
// This allows Prerender<"locale.detail"> with {locale, slug} to mount
|
|
86
|
+
// on path("/blog/:slug") where the pattern only declares {slug}.
|
|
87
|
+
) => string extends keyof TParams
|
|
88
|
+
? TypedRouteItem<TName, TPattern, unknown, TSearch>
|
|
89
|
+
: TParams extends ExtractParams<TPattern>
|
|
90
|
+
? TypedRouteItem<TName, TPattern, unknown, TSearch>
|
|
91
|
+
: { __error: `Handler params do not match pattern "${TPattern}"` };
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Path function for response routes that must return Response (image, stream, any).
|
|
95
|
+
* Handler must return Response, not ReactNode. Uses lighter ResponseHandlerContext.
|
|
96
|
+
* Use items restricted to middleware() and cache() only.
|
|
97
|
+
*/
|
|
98
|
+
export type ResponsePathFn<TEnv> = <
|
|
99
|
+
const TPattern extends string,
|
|
100
|
+
const TName extends string = UnnamedRoute,
|
|
101
|
+
const TSearch extends SearchSchema = {},
|
|
102
|
+
>(
|
|
103
|
+
pattern: TPattern,
|
|
104
|
+
handler: ResponseHandler<ExtractParams<TPattern>, TEnv>,
|
|
105
|
+
optionsOrUse?:
|
|
106
|
+
| PathOptions<TName, TSearch>
|
|
107
|
+
| (() => UseItems<ResponseRouteUseItem>),
|
|
108
|
+
use?: () => UseItems<ResponseRouteUseItem>,
|
|
109
|
+
) => TypedRouteItem<TName, TPattern, unknown, TSearch>;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Path function for JSON response routes (path.json()).
|
|
113
|
+
* Handler can return plain JSON-serializable values or Response.
|
|
114
|
+
* TData is inferred from the handler's return type (excluding Response/Promise wrappers).
|
|
115
|
+
*
|
|
116
|
+
* Note: a nested Promise in the return (a forgotten await) is caught at runtime
|
|
117
|
+
* by response-route-handler.ts (it throws instead of silently emitting `{}`). A
|
|
118
|
+
* compile-time JsonValue constraint was evaluated and rejected — it breaks
|
|
119
|
+
* interface-typed returns (interfaces lack the index signature JsonValue
|
|
120
|
+
* requires) and preserves literal types in the inferred response shape.
|
|
121
|
+
*/
|
|
122
|
+
export type JsonResponsePathFn<TEnv> = <
|
|
123
|
+
const TPattern extends string,
|
|
124
|
+
const TName extends string = UnnamedRoute,
|
|
125
|
+
const TSearch extends SearchSchema = {},
|
|
126
|
+
TData = unknown,
|
|
127
|
+
>(
|
|
128
|
+
pattern: TPattern,
|
|
129
|
+
handler: (
|
|
130
|
+
ctx: ResponseHandlerContext<ExtractParams<TPattern>, TEnv>,
|
|
131
|
+
) => TData | Response | Promise<TData | Response>,
|
|
132
|
+
optionsOrUse?:
|
|
133
|
+
| PathOptions<TName, TSearch>
|
|
134
|
+
| (() => UseItems<ResponseRouteUseItem>),
|
|
135
|
+
use?: () => UseItems<ResponseRouteUseItem>,
|
|
136
|
+
) => TypedRouteItem<TName, TPattern, TData, TSearch>;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Path function for text-based response routes (path.text(), path.html(), path.xml()).
|
|
140
|
+
* Handler can return a string or Response. TData is always `string`.
|
|
141
|
+
*/
|
|
142
|
+
export type TextResponsePathFn<TEnv> = <
|
|
143
|
+
const TPattern extends string,
|
|
144
|
+
const TName extends string = UnnamedRoute,
|
|
145
|
+
const TSearch extends SearchSchema = {},
|
|
146
|
+
>(
|
|
147
|
+
pattern: TPattern,
|
|
148
|
+
handler: TextResponseHandler<ExtractParams<TPattern>, TEnv>,
|
|
149
|
+
optionsOrUse?:
|
|
150
|
+
| PathOptions<TName, TSearch>
|
|
151
|
+
| (() => UseItems<ResponseRouteUseItem>),
|
|
152
|
+
use?: () => UseItems<ResponseRouteUseItem>,
|
|
153
|
+
) => TypedRouteItem<TName, TPattern, string, TSearch>;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* What an async include() provider resolves to. Route types (`TRoutes`) are
|
|
157
|
+
* inferred from the resolved `urls()` value so `href()` and named routes stay
|
|
158
|
+
* type-safe through a code-split module (`() => import("./routes")`).
|
|
159
|
+
*/
|
|
160
|
+
type IncludeResolved<
|
|
161
|
+
TEnv,
|
|
162
|
+
TRoutes extends Record<string, any>,
|
|
163
|
+
TResponses extends Record<string, unknown>,
|
|
164
|
+
> =
|
|
165
|
+
| UrlPatterns<TEnv, TRoutes, TResponses>
|
|
166
|
+
| { default: UrlPatterns<TEnv, TRoutes, TResponses> };
|
|
167
|
+
|
|
168
|
+
/** include() argument: an eager `urls()` value or an async provider thunk. */
|
|
169
|
+
export type IncludeArg<
|
|
170
|
+
TEnv,
|
|
171
|
+
TRoutes extends Record<string, any>,
|
|
172
|
+
TResponses extends Record<string, unknown>,
|
|
173
|
+
> =
|
|
174
|
+
| UrlPatterns<TEnv, TRoutes, TResponses>
|
|
175
|
+
| (() =>
|
|
176
|
+
| IncludeResolved<TEnv, TRoutes, TResponses>
|
|
177
|
+
| Promise<IncludeResolved<TEnv, TRoutes, TResponses>>);
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Base include function signature.
|
|
181
|
+
*/
|
|
182
|
+
export type IncludeFn<TEnv> = <
|
|
183
|
+
TRoutes extends Record<string, any>,
|
|
184
|
+
const TUrlPrefix extends string,
|
|
185
|
+
const TNamePrefix extends string = LocalOnlyInclude,
|
|
186
|
+
TResponses extends Record<string, unknown> = Record<string, unknown>,
|
|
187
|
+
>(
|
|
188
|
+
prefix: TUrlPrefix,
|
|
189
|
+
patterns: IncludeArg<TEnv, TRoutes, TResponses>,
|
|
190
|
+
options?: IncludeOptions<TNamePrefix>,
|
|
191
|
+
) => TypedIncludeItem<TRoutes, TNamePrefix, TUrlPrefix, TResponses>;
|
|
192
|
+
|
|
193
|
+
export type PathHelpers<TEnv> = {
|
|
194
|
+
/**
|
|
195
|
+
* Define a route with URL pattern at definition site
|
|
196
|
+
*
|
|
197
|
+
* @example
|
|
198
|
+
* ```typescript
|
|
199
|
+
* // Pattern and component only
|
|
200
|
+
* path("/about", AboutPage)
|
|
201
|
+
*
|
|
202
|
+
* // With options
|
|
203
|
+
* path("/:slug", PostPage, { name: "post" })
|
|
204
|
+
*
|
|
205
|
+
* // With children (loaders, middleware, etc.)
|
|
206
|
+
* path("/:slug", PostPage, { name: "post" }, () => [
|
|
207
|
+
* loader(PostLoader),
|
|
208
|
+
* ])
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
path: PathFn<TEnv> & {
|
|
212
|
+
json: JsonResponsePathFn<TEnv>;
|
|
213
|
+
text: TextResponsePathFn<TEnv>;
|
|
214
|
+
html: TextResponsePathFn<TEnv>;
|
|
215
|
+
xml: TextResponsePathFn<TEnv>;
|
|
216
|
+
md: TextResponsePathFn<TEnv>;
|
|
217
|
+
image: ResponsePathFn<TEnv>;
|
|
218
|
+
stream: ResponsePathFn<TEnv>;
|
|
219
|
+
any: ResponsePathFn<TEnv>;
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Define a layout that wraps child routes
|
|
224
|
+
*/
|
|
225
|
+
layout: {
|
|
226
|
+
(
|
|
227
|
+
component: ReactNode | Handler<any, any, TEnv> | StaticHandlerDefinition,
|
|
228
|
+
): TypedLayoutItem<{}, {}>;
|
|
229
|
+
<
|
|
230
|
+
const TChildren extends readonly (
|
|
231
|
+
| LayoutUseItem
|
|
232
|
+
| readonly LayoutUseItem[]
|
|
233
|
+
)[],
|
|
234
|
+
>(
|
|
235
|
+
component: ReactNode | Handler<any, any, TEnv> | StaticHandlerDefinition,
|
|
236
|
+
use: () => TChildren,
|
|
237
|
+
): TypedLayoutItem<ExtractRoutes<TChildren>, ExtractResponses<TChildren>>;
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Include nested URL patterns under a URL prefix.
|
|
242
|
+
*
|
|
243
|
+
* The `name` option controls how child route names appear in the
|
|
244
|
+
* global route map and generated types:
|
|
245
|
+
*
|
|
246
|
+
* ```typescript
|
|
247
|
+
* // Named — children become "blog.index", "blog.post", etc.
|
|
248
|
+
* // Visible in generated types and globally reversible.
|
|
249
|
+
* include("/blog", blogPatterns, { name: "blog" })
|
|
250
|
+
*
|
|
251
|
+
* // Flattened — children merge into the parent namespace as-is.
|
|
252
|
+
* // Equivalent to defining those routes inline at the include site.
|
|
253
|
+
* include("/blog", blogPatterns, { name: "" })
|
|
254
|
+
*
|
|
255
|
+
* // Local-only (default) — children are scoped privately.
|
|
256
|
+
* // Hidden from generated types and global reverse resolution.
|
|
257
|
+
* // Only dot-local reverse (reverse(".child")) works inside.
|
|
258
|
+
* include("/blog", blogPatterns)
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
include: IncludeFn<TEnv>;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Define parallel routes that render simultaneously in named slots.
|
|
265
|
+
*
|
|
266
|
+
* A slot value can be a Handler / ReactNode / StaticHandlerDefinition
|
|
267
|
+
* (legacy form, broadcast use applies to every slot) or a slot descriptor
|
|
268
|
+
* `{ handler, use? }` whose `use` is scoped to that slot only. Per-slot
|
|
269
|
+
* merge order is `handler.use` → shared `use` → slot-local `use`, with
|
|
270
|
+
* narrowest scope winning for last-write-wins items like `loading()`.
|
|
271
|
+
*/
|
|
272
|
+
parallel: <
|
|
273
|
+
TSlots extends Record<
|
|
274
|
+
`@${string}`,
|
|
275
|
+
| Handler<any, any, TEnv>
|
|
276
|
+
| ReactNode
|
|
277
|
+
| StaticHandlerDefinition
|
|
278
|
+
| {
|
|
279
|
+
handler:
|
|
280
|
+
| Handler<any, any, TEnv>
|
|
281
|
+
| ReactNode
|
|
282
|
+
| StaticHandlerDefinition;
|
|
283
|
+
use?: () => ParallelUseItem[];
|
|
284
|
+
}
|
|
285
|
+
>,
|
|
286
|
+
>(
|
|
287
|
+
slots: TSlots,
|
|
288
|
+
use?: () => ParallelUseItem[],
|
|
289
|
+
) => ParallelItem;
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Define an intercepting route for soft navigation
|
|
293
|
+
* Note: routeName must match a named path() in this urlpatterns
|
|
294
|
+
*/
|
|
295
|
+
intercept: keyof Rango.GeneratedRouteMap extends never
|
|
296
|
+
? (
|
|
297
|
+
slotName: `@${string}`,
|
|
298
|
+
routeName: string,
|
|
299
|
+
handler: ReactNode | Handler<any, any, TEnv>,
|
|
300
|
+
config?:
|
|
301
|
+
| import("../server/context.js").InterceptConfig<TEnv>
|
|
302
|
+
| (() => InterceptUseItem[]),
|
|
303
|
+
use?: () => InterceptUseItem[],
|
|
304
|
+
) => InterceptItem
|
|
305
|
+
: (
|
|
306
|
+
slotName: `@${string}`,
|
|
307
|
+
routeName: (keyof Rango.GeneratedRouteMap & string) | `.${string}`,
|
|
308
|
+
handler: ReactNode | Handler<any, any, TEnv>,
|
|
309
|
+
config?:
|
|
310
|
+
| import("../server/context.js").InterceptConfig<TEnv>
|
|
311
|
+
| (() => InterceptUseItem[]),
|
|
312
|
+
use?: () => InterceptUseItem[],
|
|
313
|
+
) => InterceptItem;
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Attach middleware to the current route/layout, or wrap child segments
|
|
317
|
+
*/
|
|
318
|
+
middleware: {
|
|
319
|
+
(fn: MiddlewareFn<TEnv>): MiddlewareItem;
|
|
320
|
+
(
|
|
321
|
+
fn: MiddlewareFn<TEnv>,
|
|
322
|
+
children: () => UseItems<LayoutUseItem>,
|
|
323
|
+
): MiddlewareItem;
|
|
324
|
+
(fns: MiddlewareFn<TEnv>[]): MiddlewareItem;
|
|
325
|
+
(
|
|
326
|
+
fns: MiddlewareFn<TEnv>[],
|
|
327
|
+
children: () => UseItems<LayoutUseItem>,
|
|
328
|
+
): MiddlewareItem;
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Control when a segment should revalidate during navigation
|
|
333
|
+
*/
|
|
334
|
+
revalidate: (fn: ShouldRevalidateFn<any, TEnv>) => RevalidateItem;
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Attach a data loader to the current route/layout
|
|
338
|
+
*/
|
|
339
|
+
loader: <TData>(
|
|
340
|
+
loaderDef: LoaderDefinition<TData>,
|
|
341
|
+
use?: () => LoaderUseItem[],
|
|
342
|
+
) => LoaderItem;
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Attach a loading component to the current route/layout
|
|
346
|
+
*/
|
|
347
|
+
loading: (
|
|
348
|
+
component: ReactNode | (() => ReactNode),
|
|
349
|
+
options?: { ssr?: boolean },
|
|
350
|
+
) => LoadingItem;
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Attach an error boundary to catch errors in this segment
|
|
354
|
+
*/
|
|
355
|
+
errorBoundary: (
|
|
356
|
+
fallback: ReactNode | ErrorBoundaryHandler,
|
|
357
|
+
) => ErrorBoundaryItem;
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Attach a not-found boundary to handle notFound() calls
|
|
361
|
+
*/
|
|
362
|
+
notFoundBoundary: (
|
|
363
|
+
fallback: ReactNode | NotFoundBoundaryHandler,
|
|
364
|
+
) => NotFoundBoundaryItem;
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Define cache configuration for segments
|
|
368
|
+
*/
|
|
369
|
+
cache: {
|
|
370
|
+
(): TypedCacheItem<{}, {}>;
|
|
371
|
+
<const TChildren extends readonly (AllUseItems | readonly AllUseItems[])[]>(
|
|
372
|
+
children: () => TChildren,
|
|
373
|
+
): TypedCacheItem<ExtractRoutes<TChildren>, ExtractResponses<TChildren>>;
|
|
374
|
+
(options: PartialCacheOptions<TEnv> | false): TypedCacheItem<{}, {}>;
|
|
375
|
+
<const TChildren extends readonly (AllUseItems | readonly AllUseItems[])[]>(
|
|
376
|
+
options: PartialCacheOptions<TEnv> | false,
|
|
377
|
+
use: () => TChildren,
|
|
378
|
+
): TypedCacheItem<ExtractRoutes<TChildren>, ExtractResponses<TChildren>>;
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Opt a route (or group of routes) into transition-driven navigation.
|
|
383
|
+
*
|
|
384
|
+
* Two independent layers: (1) startTransition, on all React versions, holds
|
|
385
|
+
* the previous content across a same-route nav (no skeleton flash) and is the
|
|
386
|
+
* precondition for any view transition; (2) on experimental React, an
|
|
387
|
+
* additional `<ViewTransition>` boundary cross-fades/morphs the swap. Pass
|
|
388
|
+
* `{ viewTransition: false }` to keep #1 without the router boundary. A view
|
|
389
|
+
* transition cannot fire without a startTransition. See
|
|
390
|
+
* skills/view-transitions for the startTransition x ViewTransition matrix.
|
|
391
|
+
*
|
|
392
|
+
* Pass `when: (ctx) => boolean` to gate the transition per request: it runs
|
|
393
|
+
* server-side after the route handler (can read `ctx.get(...)`), and returning
|
|
394
|
+
* false drops the transition so the navigation streams its loading() skeleton.
|
|
395
|
+
*/
|
|
396
|
+
transition: {
|
|
397
|
+
(): TransitionItem;
|
|
398
|
+
(config: TransitionConfig): TransitionItem;
|
|
399
|
+
<const TChildren extends readonly (AllUseItems | readonly AllUseItems[])[]>(
|
|
400
|
+
children: () => TChildren,
|
|
401
|
+
): TypedTransitionItem<
|
|
402
|
+
ExtractRoutes<TChildren>,
|
|
403
|
+
ExtractResponses<TChildren>
|
|
404
|
+
>;
|
|
405
|
+
<const TChildren extends readonly (AllUseItems | readonly AllUseItems[])[]>(
|
|
406
|
+
config: TransitionConfig,
|
|
407
|
+
children: () => TChildren,
|
|
408
|
+
): TypedTransitionItem<
|
|
409
|
+
ExtractRoutes<TChildren>,
|
|
410
|
+
ExtractResponses<TChildren>
|
|
411
|
+
>;
|
|
412
|
+
};
|
|
413
|
+
};
|