@rangojs/router 0.0.0-experimental.79 → 0.0.0-experimental.7c7e4327
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 +8 -4
- package/README.md +301 -797
- package/dist/bin/rango.js +603 -145
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3750 -1160
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +96 -24
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +85 -6
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +228 -33
- package/skills/caching/SKILL.md +336 -19
- package/skills/catalog.json +271 -0
- 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 +110 -4
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +5 -3
- package/skills/defer-hydration/SKILL.md +235 -0
- package/skills/document-cache/SKILL.md +87 -56
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +12 -10
- package/skills/hooks/SKILL.md +73 -691
- package/skills/hooks/data.md +273 -0
- package/skills/hooks/handle-and-actions.md +103 -0
- package/skills/hooks/navigation.md +110 -0
- package/skills/hooks/outlets.md +41 -0
- package/skills/hooks/state.md +228 -0
- package/skills/hooks/urls.md +135 -0
- package/skills/host-router/SKILL.md +129 -27
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +75 -19
- package/skills/layout/SKILL.md +40 -19
- package/skills/links/SKILL.md +247 -17
- package/skills/loader/SKILL.md +248 -10
- package/skills/middleware/SKILL.md +25 -13
- package/skills/migrate-nextjs/SKILL.md +205 -20
- package/skills/migrate-react-router/SKILL.md +59 -670
- package/skills/migrate-react-router/cloudflare-workers.md +129 -0
- package/skills/migrate-react-router/component-migration.md +196 -0
- package/skills/migrate-react-router/data-and-actions.md +225 -0
- package/skills/migrate-react-router/route-mapping.md +271 -0
- package/skills/mime-routes/SKILL.md +29 -2
- package/skills/observability/SKILL.md +202 -0
- package/skills/parallel/SKILL.md +40 -10
- package/skills/ppr/SKILL.md +616 -0
- package/skills/prerender/SKILL.md +72 -60
- package/skills/rango/SKILL.md +318 -26
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +138 -49
- package/skills/route/SKILL.md +117 -9
- package/skills/router-setup/SKILL.md +44 -9
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +776 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +130 -0
- 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 +1 -1
- package/skills/typesafety/SKILL.md +45 -626
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +335 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +74 -15
- 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 +0 -65
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +252 -158
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/logging.ts +28 -0
- package/src/browser/merge-segment-loaders.ts +6 -4
- package/src/browser/navigation-bridge.ts +94 -25
- package/src/browser/navigation-client.ts +144 -79
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +161 -73
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +183 -144
- package/src/browser/prefetch/cache.ts +242 -77
- package/src/browser/prefetch/fetch.ts +325 -69
- package/src/browser/prefetch/queue.ts +61 -12
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +58 -20
- package/src/browser/react/NavigationProvider.tsx +202 -120
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +17 -14
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +33 -8
- package/src/browser/react/use-navigation.ts +32 -7
- package/src/browser/react/use-params.ts +20 -10
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +25 -3
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +11 -21
- package/src/browser/response-adapter.ts +99 -8
- package/src/browser/rsc-router.tsx +145 -28
- package/src/browser/scroll-restoration.ts +37 -22
- package/src/browser/segment-reconciler.ts +31 -21
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +236 -65
- package/src/browser/types.ts +102 -9
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +203 -154
- package/src/build/generate-route-types.ts +3 -1
- package/src/build/index.ts +11 -3
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +152 -21
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +16 -5
- package/src/build/route-types/include-resolution.ts +456 -62
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +22 -6
- package/src/build/route-types/router-processing.ts +128 -51
- package/src/build/route-types/scan-filter.ts +1 -1
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +13 -21
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +58 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +421 -58
- package/src/cache/cache-scope.ts +187 -96
- package/src/cache/cache-tag.ts +149 -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 +2202 -372
- 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 +6 -16
- package/src/cache/document-cache.ts +126 -41
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +243 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +13 -21
- package/src/cache/shell-snapshot.ts +417 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +180 -99
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1127 -0
- package/src/client.rsc.tsx +41 -21
- package/src/client.tsx +33 -61
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +108 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +18 -6
- 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 +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +67 -37
- package/src/handles/MetaTags.tsx +24 -53
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +35 -8
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +14 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +13 -22
- package/src/host/index.ts +9 -2
- package/src/host/pattern-matcher.ts +23 -52
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +97 -12
- package/src/index.ts +98 -14
- package/src/internal-debug.ts +11 -10
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +20 -13
- package/src/loader.ts +12 -11
- package/src/missing-id-error.ts +68 -0
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +32 -37
- package/src/prerender.ts +78 -10
- package/src/redirect-origin.ts +114 -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 +65 -39
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +304 -309
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +87 -59
- package/src/route-definition/index.ts +1 -2
- package/src/route-definition/redirect.ts +44 -11
- package/src/route-definition/resolve-handler-use.ts +12 -1
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +41 -20
- package/src/route-types.ts +19 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +73 -25
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +129 -30
- package/src/router/handler-context.ts +27 -42
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +39 -20
- package/src/router/lazy-includes.ts +82 -59
- package/src/router/loader-resolution.ts +167 -72
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +74 -40
- package/src/router/match-api.ts +80 -55
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +211 -165
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +159 -285
- package/src/router/match-middleware/cache-store.ts +64 -52
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +0 -22
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +69 -79
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -134
- package/src/router/middleware.ts +298 -172
- package/src/router/navigation-snapshot.ts +7 -56
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +181 -150
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +112 -67
- package/src/router/preview-match.ts +6 -2
- package/src/router/request-classification.ts +50 -69
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +14 -3
- package/src/router/router-context.ts +6 -29
- package/src/router/router-interfaces.ts +115 -36
- package/src/router/router-options.ts +166 -5
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +131 -86
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +139 -39
- package/src/router/segment-resolution/loader-mask.ts +67 -0
- package/src/router/segment-resolution/loader-snapshot.ts +251 -0
- package/src/router/segment-resolution/revalidation.ts +272 -320
- package/src/router/segment-resolution/static-store.ts +19 -5
- 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 +5 -1
- package/src/router/segment-wrappers.ts +6 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +105 -20
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -59
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +157 -71
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +291 -217
- package/src/rsc/helpers.ts +168 -46
- package/src/rsc/index.ts +2 -5
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +114 -38
- package/src/rsc/manifest-init.ts +29 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +124 -13
- package/src/rsc/redirect-guard.ts +100 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +99 -189
- package/src/rsc/rsc-rendering.ts +421 -76
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +282 -116
- package/src/rsc/shell-capture.ts +1158 -0
- package/src/rsc/shell-serve.ts +150 -0
- package/src/rsc/ssr-setup.ts +16 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +53 -5
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-loader-promise.ts +49 -4
- package/src/segment-system.tsx +350 -149
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +208 -51
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +152 -5
- package/src/server/handle-store.ts +21 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +395 -176
- package/src/ssr/index.tsx +458 -178
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +10 -13
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +813 -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 +56 -84
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +13 -4
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +110 -62
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +11 -9
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +0 -6
- package/src/types/segments.ts +135 -14
- package/src/urls/include-helper.ts +19 -64
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -11
- package/src/urls/path-helper-types.ts +63 -17
- package/src/urls/path-helper.ts +22 -106
- package/src/urls/pattern-types.ts +72 -19
- package/src/urls/response-types.ts +22 -29
- package/src/urls/type-extraction.ts +98 -154
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +292 -107
- 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 +8 -7
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +127 -86
- 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 +96 -68
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +45 -1
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +4 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +210 -10
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- package/src/vite/plugins/client-ref-dedup.ts +16 -11
- package/src/vite/plugins/client-ref-hashing.ts +28 -15
- 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/plugins/expose-action-id.ts +48 -95
- package/src/vite/plugins/expose-id-utils.ts +88 -55
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +11 -90
- package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
- package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
- package/src/vite/plugins/expose-internal-ids.ts +505 -486
- package/src/vite/plugins/performance-tracks.ts +26 -25
- package/src/vite/plugins/refresh-cmd.ts +1 -1
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +37 -40
- package/src/vite/plugins/virtual-entries.ts +138 -27
- package/src/vite/rango.ts +236 -138
- package/src/vite/router-discovery.ts +927 -136
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +1 -1
- package/src/vite/utils/bundle-analysis.ts +10 -15
- 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 +4 -59
- package/src/vite/utils/package-resolution.ts +20 -52
- package/src/vite/utils/prerender-utils.ts +71 -43
- package/src/vite/utils/shared-utils.ts +142 -43
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/react/use-client-cache.ts +0 -58
- package/src/browser/shallow.ts +0 -40
- package/src/handles/index.ts +0 -7
- package/src/network-error-thrower.tsx +0 -23
- package/src/router/middleware-cookies.ts +0 -55
|
@@ -28,7 +28,6 @@ import type {
|
|
|
28
28
|
ParallelUseItem,
|
|
29
29
|
InterceptUseItem,
|
|
30
30
|
LoaderUseItem,
|
|
31
|
-
WhenItem,
|
|
32
31
|
TypedCacheItem,
|
|
33
32
|
TransitionItem,
|
|
34
33
|
TypedTransitionItem,
|
|
@@ -42,7 +41,6 @@ import type {
|
|
|
42
41
|
PassthroughHandlerDefinition,
|
|
43
42
|
} from "../prerender.js";
|
|
44
43
|
import type { StaticHandlerDefinition } from "../static-handler.js";
|
|
45
|
-
import type { InterceptWhenFn } from "../server/context";
|
|
46
44
|
import type {
|
|
47
45
|
ResponseHandler,
|
|
48
46
|
ResponseHandlerContext,
|
|
@@ -114,6 +112,12 @@ export type ResponsePathFn<TEnv> = <
|
|
|
114
112
|
* Path function for JSON response routes (path.json()).
|
|
115
113
|
* Handler can return plain JSON-serializable values or Response.
|
|
116
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.
|
|
117
121
|
*/
|
|
118
122
|
export type JsonResponsePathFn<TEnv> = <
|
|
119
123
|
const TPattern extends string,
|
|
@@ -148,6 +152,30 @@ export type TextResponsePathFn<TEnv> = <
|
|
|
148
152
|
use?: () => UseItems<ResponseRouteUseItem>,
|
|
149
153
|
) => TypedRouteItem<TName, TPattern, string, TSearch>;
|
|
150
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
|
+
|
|
151
179
|
/**
|
|
152
180
|
* Base include function signature.
|
|
153
181
|
*/
|
|
@@ -158,7 +186,7 @@ export type IncludeFn<TEnv> = <
|
|
|
158
186
|
TResponses extends Record<string, unknown> = Record<string, unknown>,
|
|
159
187
|
>(
|
|
160
188
|
prefix: TUrlPrefix,
|
|
161
|
-
patterns:
|
|
189
|
+
patterns: IncludeArg<TEnv, TRoutes, TResponses>,
|
|
162
190
|
options?: IncludeOptions<TNamePrefix>,
|
|
163
191
|
) => TypedIncludeItem<TRoutes, TNamePrefix, TUrlPrefix, TResponses>;
|
|
164
192
|
|
|
@@ -240,9 +268,16 @@ export type PathHelpers<TEnv> = {
|
|
|
240
268
|
* `{ handler, use? }` whose `use` is scoped to that slot only. Per-slot
|
|
241
269
|
* merge order is `handler.use` → shared `use` → slot-local `use`, with
|
|
242
270
|
* narrowest scope winning for last-write-wins items like `loading()`.
|
|
271
|
+
*
|
|
272
|
+
* Not generic over the slots record: an inferred type parameter makes the
|
|
273
|
+
* object literal an inference site, which suppresses contextual typing of
|
|
274
|
+
* arrow slot handlers (`(ctx) => ...` was implicit any). Bare handlers infer
|
|
275
|
+
* now; a descriptor's `handler:` arrow still needs an explicit ctx annotation
|
|
276
|
+
* because StaticHandlerDefinition's own `.handler` joins the contextual union
|
|
277
|
+
* (two callables — see parallel-slot-handler-types.test.ts).
|
|
243
278
|
*/
|
|
244
|
-
parallel:
|
|
245
|
-
|
|
279
|
+
parallel: (
|
|
280
|
+
slots: Record<
|
|
246
281
|
`@${string}`,
|
|
247
282
|
| Handler<any, any, TEnv>
|
|
248
283
|
| ReactNode
|
|
@@ -255,8 +290,6 @@ export type PathHelpers<TEnv> = {
|
|
|
255
290
|
use?: () => ParallelUseItem[];
|
|
256
291
|
}
|
|
257
292
|
>,
|
|
258
|
-
>(
|
|
259
|
-
slots: TSlots,
|
|
260
293
|
use?: () => ParallelUseItem[],
|
|
261
294
|
) => ParallelItem;
|
|
262
295
|
|
|
@@ -264,17 +297,23 @@ export type PathHelpers<TEnv> = {
|
|
|
264
297
|
* Define an intercepting route for soft navigation
|
|
265
298
|
* Note: routeName must match a named path() in this urlpatterns
|
|
266
299
|
*/
|
|
267
|
-
intercept: keyof
|
|
300
|
+
intercept: keyof Rango.GeneratedRouteMap extends never
|
|
268
301
|
? (
|
|
269
302
|
slotName: `@${string}`,
|
|
270
303
|
routeName: string,
|
|
271
304
|
handler: ReactNode | Handler<any, any, TEnv>,
|
|
305
|
+
config?:
|
|
306
|
+
| import("../server/context.js").InterceptConfig<TEnv>
|
|
307
|
+
| (() => InterceptUseItem[]),
|
|
272
308
|
use?: () => InterceptUseItem[],
|
|
273
309
|
) => InterceptItem
|
|
274
310
|
: (
|
|
275
311
|
slotName: `@${string}`,
|
|
276
|
-
routeName: (keyof
|
|
312
|
+
routeName: (keyof Rango.GeneratedRouteMap & string) | `.${string}`,
|
|
277
313
|
handler: ReactNode | Handler<any, any, TEnv>,
|
|
314
|
+
config?:
|
|
315
|
+
| import("../server/context.js").InterceptConfig<TEnv>
|
|
316
|
+
| (() => InterceptUseItem[]),
|
|
278
317
|
use?: () => InterceptUseItem[],
|
|
279
318
|
) => InterceptItem;
|
|
280
319
|
|
|
@@ -329,11 +368,6 @@ export type PathHelpers<TEnv> = {
|
|
|
329
368
|
fallback: ReactNode | NotFoundBoundaryHandler,
|
|
330
369
|
) => NotFoundBoundaryItem;
|
|
331
370
|
|
|
332
|
-
/**
|
|
333
|
-
* Define a condition for when an intercept should activate
|
|
334
|
-
*/
|
|
335
|
-
when: (fn: InterceptWhenFn) => WhenItem;
|
|
336
|
-
|
|
337
371
|
/**
|
|
338
372
|
* Define cache configuration for segments
|
|
339
373
|
*/
|
|
@@ -342,15 +376,27 @@ export type PathHelpers<TEnv> = {
|
|
|
342
376
|
<const TChildren extends readonly (AllUseItems | readonly AllUseItems[])[]>(
|
|
343
377
|
children: () => TChildren,
|
|
344
378
|
): TypedCacheItem<ExtractRoutes<TChildren>, ExtractResponses<TChildren>>;
|
|
345
|
-
(options: PartialCacheOptions | false): TypedCacheItem<{}, {}>;
|
|
379
|
+
(options: PartialCacheOptions<TEnv> | false): TypedCacheItem<{}, {}>;
|
|
346
380
|
<const TChildren extends readonly (AllUseItems | readonly AllUseItems[])[]>(
|
|
347
|
-
options: PartialCacheOptions | false,
|
|
381
|
+
options: PartialCacheOptions<TEnv> | false,
|
|
348
382
|
use: () => TChildren,
|
|
349
383
|
): TypedCacheItem<ExtractRoutes<TChildren>, ExtractResponses<TChildren>>;
|
|
350
384
|
};
|
|
351
385
|
|
|
352
386
|
/**
|
|
353
|
-
*
|
|
387
|
+
* Opt a route (or group of routes) into transition-driven navigation.
|
|
388
|
+
*
|
|
389
|
+
* Two independent layers: (1) startTransition, on all React versions, holds
|
|
390
|
+
* the previous content across a same-route nav (no skeleton flash) and is the
|
|
391
|
+
* precondition for any view transition; (2) on experimental React, an
|
|
392
|
+
* additional `<ViewTransition>` boundary cross-fades/morphs the swap. Pass
|
|
393
|
+
* `{ viewTransition: false }` to keep #1 without the router boundary. A view
|
|
394
|
+
* transition cannot fire without a startTransition. See
|
|
395
|
+
* skills/view-transitions for the startTransition x ViewTransition matrix.
|
|
396
|
+
*
|
|
397
|
+
* Pass `when: (ctx) => boolean` to gate the transition per request: it runs
|
|
398
|
+
* server-side after the route handler (can read `ctx.get(...)`), and returning
|
|
399
|
+
* false drops the transition so the navigation streams its loading() skeleton.
|
|
354
400
|
*/
|
|
355
401
|
transition: {
|
|
356
402
|
(): TransitionItem;
|
package/src/urls/path-helper.ts
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { Handler } from "../types.js";
|
|
3
|
-
import type {
|
|
4
|
-
AllUseItems,
|
|
5
|
-
RouteItem,
|
|
6
|
-
RouteUseItem,
|
|
7
|
-
UseItems,
|
|
8
|
-
} from "../route-types.js";
|
|
3
|
+
import type { RouteItem, RouteUseItem, UseItems } from "../route-types.js";
|
|
9
4
|
import {
|
|
10
|
-
getContext,
|
|
11
5
|
getUrlPrefix,
|
|
12
6
|
getNamePrefix,
|
|
13
7
|
getRootScoped,
|
|
8
|
+
requireDslContext,
|
|
14
9
|
} from "../server/context";
|
|
15
10
|
import { invariant, DataNotFoundError } from "../errors";
|
|
16
11
|
import { validateUserRouteName } from "../route-name.js";
|
|
@@ -39,40 +34,11 @@ import {
|
|
|
39
34
|
resolveHandlerUse,
|
|
40
35
|
mergeHandlerUse,
|
|
41
36
|
} from "../route-definition/resolve-handler-use.js";
|
|
37
|
+
import {
|
|
38
|
+
emptySegmentBase,
|
|
39
|
+
runAndValidateUseItems,
|
|
40
|
+
} from "../route-definition/dsl-helpers.js";
|
|
42
41
|
|
|
43
|
-
/**
|
|
44
|
-
* Check if a value is a valid use item
|
|
45
|
-
*/
|
|
46
|
-
const isValidUseItem = (item: any): item is AllUseItems | undefined | null => {
|
|
47
|
-
return (
|
|
48
|
-
typeof item === "undefined" ||
|
|
49
|
-
item === null ||
|
|
50
|
-
(item &&
|
|
51
|
-
typeof item === "object" &&
|
|
52
|
-
"type" in item &&
|
|
53
|
-
[
|
|
54
|
-
"layout",
|
|
55
|
-
"route",
|
|
56
|
-
"middleware",
|
|
57
|
-
"revalidate",
|
|
58
|
-
"parallel",
|
|
59
|
-
"intercept",
|
|
60
|
-
"loader",
|
|
61
|
-
"loading",
|
|
62
|
-
"errorBoundary",
|
|
63
|
-
"notFoundBoundary",
|
|
64
|
-
"when",
|
|
65
|
-
"cache",
|
|
66
|
-
"transition",
|
|
67
|
-
"include",
|
|
68
|
-
].includes(item.type))
|
|
69
|
-
);
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Apply URL prefix to a pattern
|
|
74
|
-
* Handles edge cases like "/" patterns and double slashes
|
|
75
|
-
*/
|
|
76
42
|
function applyUrlPrefix(prefix: string, pattern: string): string {
|
|
77
43
|
if (!prefix) return pattern;
|
|
78
44
|
if (pattern === "/") return prefix;
|
|
@@ -82,29 +48,17 @@ function applyUrlPrefix(prefix: string, pattern: string): string {
|
|
|
82
48
|
return prefix + pattern;
|
|
83
49
|
}
|
|
84
50
|
|
|
85
|
-
/**
|
|
86
|
-
* Apply name prefix to a route name
|
|
87
|
-
*/
|
|
88
51
|
function applyNamePrefix(prefix: string | undefined, name: string): string {
|
|
89
52
|
if (!prefix) return name;
|
|
90
53
|
return `${prefix}.${name}`;
|
|
91
54
|
}
|
|
92
55
|
|
|
93
|
-
/**
|
|
94
|
-
* Resolve response type from path options (set by path.json(), path.text(), etc.)
|
|
95
|
-
*/
|
|
96
56
|
function resolveResponseType(
|
|
97
57
|
options: PathOptions | undefined,
|
|
98
58
|
): string | undefined {
|
|
99
59
|
return options?.[RESPONSE_TYPE];
|
|
100
60
|
}
|
|
101
61
|
|
|
102
|
-
/**
|
|
103
|
-
* Create path() helper
|
|
104
|
-
*
|
|
105
|
-
* The path() function is the key new feature - it combines URL pattern
|
|
106
|
-
* with handler at the definition site.
|
|
107
|
-
*/
|
|
108
62
|
export function createPathHelper<TEnv>(): PathFn<TEnv> {
|
|
109
63
|
return ((
|
|
110
64
|
pattern: string,
|
|
@@ -112,17 +66,15 @@ export function createPathHelper<TEnv>(): PathFn<TEnv> {
|
|
|
112
66
|
optionsOrUse?: PathOptions | (() => UseItems<RouteUseItem>),
|
|
113
67
|
maybeUse?: () => UseItems<RouteUseItem>,
|
|
114
68
|
): RouteItem => {
|
|
115
|
-
const store =
|
|
116
|
-
|
|
117
|
-
|
|
69
|
+
const { store, ctx } = requireDslContext(
|
|
70
|
+
"path() must be called inside urls()",
|
|
71
|
+
);
|
|
118
72
|
|
|
119
73
|
invariant(
|
|
120
74
|
!ctx.parent || ctx.parent.type !== "parallel",
|
|
121
75
|
"path() cannot be used inside parallel()",
|
|
122
76
|
);
|
|
123
77
|
|
|
124
|
-
// Walk the parent chain to prevent path() nested under another path(),
|
|
125
|
-
// even when separated by intermediate layouts (e.g. path(layout(path())))
|
|
126
78
|
{
|
|
127
79
|
let ancestor = ctx.parent;
|
|
128
80
|
while (ancestor) {
|
|
@@ -134,7 +86,6 @@ export function createPathHelper<TEnv>(): PathFn<TEnv> {
|
|
|
134
86
|
}
|
|
135
87
|
}
|
|
136
88
|
|
|
137
|
-
// Determine options and use based on argument types
|
|
138
89
|
let options: PathOptions | undefined;
|
|
139
90
|
let use: (() => UseItems<RouteUseItem>) | undefined;
|
|
140
91
|
|
|
@@ -147,49 +98,29 @@ export function createPathHelper<TEnv>(): PathFn<TEnv> {
|
|
|
147
98
|
use = maybeUse;
|
|
148
99
|
}
|
|
149
100
|
|
|
150
|
-
// Merge handler.use() defaults with explicit use()
|
|
151
|
-
// Response routes (path.json, path.text, etc.) only allow middleware + cache
|
|
152
101
|
const handlerUseFn = resolveHandlerUse(handler);
|
|
153
102
|
const mountSite = resolveResponseType(options) ? "response" : "path";
|
|
154
103
|
const mergedUse = mergeHandlerUse(handlerUseFn, use, mountSite);
|
|
155
104
|
|
|
156
|
-
// Get prefixes from context (set by include())
|
|
157
105
|
const urlPrefix = getUrlPrefix();
|
|
158
106
|
const namePrefix = getNamePrefix();
|
|
159
107
|
|
|
160
|
-
// Apply URL prefix to pattern
|
|
161
108
|
const prefixedPattern = applyUrlPrefix(urlPrefix, pattern);
|
|
162
109
|
|
|
163
|
-
// Generate route name - use provided name or generate from pattern
|
|
164
110
|
const localName =
|
|
165
111
|
options?.name || `$path_${pattern.replace(/[/:*?]/g, "_")}`;
|
|
166
112
|
if (options?.name) {
|
|
167
113
|
validateUserRouteName(options.name);
|
|
168
114
|
}
|
|
169
|
-
// Apply name prefix if set (from include())
|
|
170
115
|
const routeName = applyNamePrefix(namePrefix, localName);
|
|
171
116
|
|
|
172
117
|
const namespace = `${ctx.namespace}.${store.getNextIndex("route")}.${routeName}`;
|
|
173
118
|
|
|
174
|
-
// Per-request pruning: skip registration for routes that won't be rendered.
|
|
175
|
-
// forRoute is set by loadManifest() to the matched route name. During
|
|
176
|
-
// evaluateLazyEntry() (route matching), forRoute is unset so all routes
|
|
177
|
-
// register normally. We still increment counters to keep shortCodes stable
|
|
178
|
-
// across different routes (needed for segment reconciliation on navigation).
|
|
179
|
-
//
|
|
180
|
-
// include() does not need its own forRoute pruning. include() creates lazy
|
|
181
|
-
// entries that defer handler execution until route matching. When the lazy
|
|
182
|
-
// handler eventually runs inside loadManifest(), this path() check already
|
|
183
|
-
// covers all routes defined inside the include.
|
|
184
119
|
if (ctx.forRoute && routeName !== ctx.forRoute) {
|
|
185
120
|
store.getShortCode("route");
|
|
186
121
|
return { type: "route" } as RouteItem;
|
|
187
122
|
}
|
|
188
123
|
|
|
189
|
-
// Ensure handler is always a function (wrap ReactNode or extract from prerender/static def)
|
|
190
|
-
// For prerender stubs (production builds where handler code is evicted),
|
|
191
|
-
// handler.handler is undefined — provide a notFound fallback so requests
|
|
192
|
-
// for non-prerendered params get 404 instead of "handler is not a function".
|
|
193
124
|
const wrappedHandler: Handler<any, any, TEnv> =
|
|
194
125
|
typeof handler === "function"
|
|
195
126
|
? (handler as Handler<any, any, TEnv>)
|
|
@@ -214,22 +145,13 @@ export function createPathHelper<TEnv>(): PathFn<TEnv> {
|
|
|
214
145
|
: () => handler;
|
|
215
146
|
|
|
216
147
|
const entry = {
|
|
148
|
+
...emptySegmentBase(),
|
|
217
149
|
id: namespace,
|
|
218
150
|
shortCode: store.getShortCode("route"),
|
|
219
151
|
type: "route" as const,
|
|
220
152
|
parent: ctx.parent,
|
|
221
153
|
handler: wrappedHandler,
|
|
222
|
-
// Store the PREFIXED pattern for route matching
|
|
223
154
|
pattern: prefixedPattern,
|
|
224
|
-
loading: undefined,
|
|
225
|
-
middleware: [],
|
|
226
|
-
revalidate: [],
|
|
227
|
-
errorBoundary: [],
|
|
228
|
-
notFoundBoundary: [],
|
|
229
|
-
layout: [],
|
|
230
|
-
parallel: {},
|
|
231
|
-
intercept: [],
|
|
232
|
-
loader: [],
|
|
233
155
|
...(urlPrefix ? { mountPath: urlPrefix } : {}),
|
|
234
156
|
...(isPassthroughHandler(handler)
|
|
235
157
|
? {
|
|
@@ -253,31 +175,30 @@ export function createPathHelper<TEnv>(): PathFn<TEnv> {
|
|
|
253
175
|
...(resolveResponseType(options)
|
|
254
176
|
? { responseType: resolveResponseType(options) }
|
|
255
177
|
: {}),
|
|
178
|
+
// PPR shell-caching opt-in (document-level). Stored raw; the integrated
|
|
179
|
+
// serve path normalizes it via resolvePprConfig (rsc/shell-serve.ts).
|
|
180
|
+
...(options?.ppr !== undefined && options.ppr !== false
|
|
181
|
+
? { ppr: options.ppr }
|
|
182
|
+
: {}),
|
|
256
183
|
};
|
|
257
184
|
|
|
258
|
-
// Capture namespace prefix on static handler for build-time reverse() resolution
|
|
259
185
|
if (isStaticHandler(handler) && handler.$$id && ctx.namePrefix) {
|
|
260
186
|
(handler as any).$$routePrefix = ctx.namePrefix;
|
|
261
187
|
}
|
|
262
188
|
|
|
263
|
-
// Check for duplicate route names (TypeScript should catch this, but runtime check too)
|
|
264
189
|
invariant(
|
|
265
190
|
ctx.manifest.get(routeName) === undefined,
|
|
266
191
|
`Duplicate route name: ${routeName} at ${namespace}`,
|
|
267
192
|
);
|
|
268
193
|
|
|
269
|
-
// Register route entry with prefixed name
|
|
270
194
|
ctx.manifest.set(routeName, entry);
|
|
271
195
|
|
|
272
|
-
// Register root-scope flag for dot-local reverse resolution
|
|
273
196
|
registerRouteRootScope(routeName, getRootScoped());
|
|
274
197
|
|
|
275
|
-
// Also store pattern in a separate map for URL generation
|
|
276
198
|
if (ctx.patterns) {
|
|
277
199
|
ctx.patterns.set(routeName, prefixedPattern);
|
|
278
200
|
}
|
|
279
201
|
|
|
280
|
-
// Store pattern grouped by URL prefix for separate entry creation
|
|
281
202
|
if (ctx.patternsByPrefix) {
|
|
282
203
|
const urlPrefix = getUrlPrefix() || "";
|
|
283
204
|
if (!ctx.patternsByPrefix.has(urlPrefix)) {
|
|
@@ -286,12 +207,10 @@ export function createPathHelper<TEnv>(): PathFn<TEnv> {
|
|
|
286
207
|
ctx.patternsByPrefix.get(urlPrefix)!.set(routeName, prefixedPattern);
|
|
287
208
|
}
|
|
288
209
|
|
|
289
|
-
// Store trailing slash config if specified
|
|
290
210
|
if (options?.trailingSlash && ctx.trailingSlash) {
|
|
291
211
|
ctx.trailingSlash.set(routeName, options.trailingSlash);
|
|
292
212
|
}
|
|
293
213
|
|
|
294
|
-
// Store search schema if specified
|
|
295
214
|
if (options?.search) {
|
|
296
215
|
if (ctx.searchSchemas) {
|
|
297
216
|
ctx.searchSchemas.set(routeName, options.search);
|
|
@@ -299,12 +218,14 @@ export function createPathHelper<TEnv>(): PathFn<TEnv> {
|
|
|
299
218
|
registerSearchSchema(routeName, options.search);
|
|
300
219
|
}
|
|
301
220
|
|
|
302
|
-
// Run merged use callback (handler.use defaults + explicit use) if present
|
|
303
221
|
if (mergedUse) {
|
|
304
|
-
const result =
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
222
|
+
const result = runAndValidateUseItems(
|
|
223
|
+
store,
|
|
224
|
+
namespace,
|
|
225
|
+
entry,
|
|
226
|
+
mergedUse,
|
|
227
|
+
"path",
|
|
228
|
+
"use",
|
|
308
229
|
);
|
|
309
230
|
return { name: namespace, type: "route", uses: result } as RouteItem;
|
|
310
231
|
}
|
|
@@ -313,10 +234,6 @@ export function createPathHelper<TEnv>(): PathFn<TEnv> {
|
|
|
313
234
|
}) as PathFn<TEnv>;
|
|
314
235
|
}
|
|
315
236
|
|
|
316
|
-
/**
|
|
317
|
-
* Attach response type tag methods (.json, .text, .html, .xml, .md, .image, .stream, .any) to a path helper.
|
|
318
|
-
* Each tag wraps the original path() call with the RESPONSE_TYPE option set.
|
|
319
|
-
*/
|
|
320
237
|
export function attachPathResponseTags<TEnv>(
|
|
321
238
|
pathFn: PathFn<TEnv>,
|
|
322
239
|
): PathFn<TEnv> & {
|
|
@@ -338,7 +255,6 @@ export function attachPathResponseTags<TEnv>(
|
|
|
338
255
|
) => {
|
|
339
256
|
let options: PathOptions;
|
|
340
257
|
let use: (() => any[]) | undefined;
|
|
341
|
-
|
|
342
258
|
if (typeof optionsOrUse === "function") {
|
|
343
259
|
options = { [RESPONSE_TYPE]: responseType };
|
|
344
260
|
use = optionsOrUse;
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
AllUseItems,
|
|
5
|
-
RouteUseItem,
|
|
6
|
-
UrlPatternsBrand,
|
|
7
|
-
} from "../route-types.js";
|
|
1
|
+
import type { TrailingSlashMode } from "../types.js";
|
|
2
|
+
import type { AllUseItems, UrlPatternsBrand } from "../route-types.js";
|
|
8
3
|
import type { SearchSchema } from "../search-params.js";
|
|
9
4
|
import { RESPONSE_TYPE } from "./response-types.js";
|
|
10
5
|
import type { DefaultEnv } from "../types.js";
|
|
@@ -40,12 +35,48 @@ export type LocalOnlyInclude = string & { [LOCAL_ONLY_BRAND]: void };
|
|
|
40
35
|
/**
|
|
41
36
|
* Options for path() function
|
|
42
37
|
*/
|
|
38
|
+
/**
|
|
39
|
+
* Options for the `ppr` path option (PPR shell caching — Axis 2, see
|
|
40
|
+
* docs/design/ppr-shell-resume.md and the /ppr skill). Declaring
|
|
41
|
+
* `ppr: true | PartialPrerenderProps` on a page route opts that DOCUMENT into
|
|
42
|
+
* shell capture: the rendered HTML shell (everything that is not a live hole) is
|
|
43
|
+
* cached and, on a later GET, flushed immediately while fizz resumes only the
|
|
44
|
+
* holes. Serving is integral to the router — there is no middleware to mount;
|
|
45
|
+
* the shell store is the app-level `createRouter({ cache })` store (which must
|
|
46
|
+
* implement the `getShell`/`putShell` family).
|
|
47
|
+
*/
|
|
48
|
+
export interface PartialPrerenderProps {
|
|
49
|
+
/**
|
|
50
|
+
* Shell time-to-live in seconds. Defaults to 300 (`ppr: true` uses the same
|
|
51
|
+
* default).
|
|
52
|
+
*/
|
|
53
|
+
ttl?: number;
|
|
54
|
+
/**
|
|
55
|
+
* Stale-while-revalidate window in seconds: a stale shell is still served
|
|
56
|
+
* while a background recapture refreshes it.
|
|
57
|
+
*/
|
|
58
|
+
swr?: number;
|
|
59
|
+
/**
|
|
60
|
+
* Operational tags attached to the captured shell entry for
|
|
61
|
+
* `updateTag()`/`revalidateTag()`-driven eviction. UNIONED with the tags the
|
|
62
|
+
* capture render auto-collects (the shell's own non-loader request tags).
|
|
63
|
+
*/
|
|
64
|
+
tags?: string[];
|
|
65
|
+
}
|
|
66
|
+
|
|
43
67
|
export interface PathOptions<
|
|
44
68
|
TName extends string = string,
|
|
45
69
|
TSearch extends SearchSchema = {},
|
|
46
70
|
> {
|
|
47
71
|
/** Route name for href() lookups */
|
|
48
72
|
name?: TName;
|
|
73
|
+
/**
|
|
74
|
+
* PPR shell caching opt-in for this page route (document-level). `true` uses
|
|
75
|
+
* the default policy (ttl 300); an object sets ttl/swr/tags. See
|
|
76
|
+
* {@link PartialPrerenderProps}. Routes without this option are pure axis 1 —
|
|
77
|
+
* no capture, no store reads, no logs.
|
|
78
|
+
*/
|
|
79
|
+
ppr?: boolean | PartialPrerenderProps;
|
|
49
80
|
/** Search param schema for typed query parameters */
|
|
50
81
|
search?: TSearch;
|
|
51
82
|
/** Trailing slash behavior: "never" (redirect /path/ to /path), "always" (redirect /path to /path/), "ignore" (match both) */
|
|
@@ -54,16 +85,6 @@ export interface PathOptions<
|
|
|
54
85
|
[RESPONSE_TYPE]?: string;
|
|
55
86
|
}
|
|
56
87
|
|
|
57
|
-
/**
|
|
58
|
-
* Internal representation of a URL pattern definition
|
|
59
|
-
*/
|
|
60
|
-
export interface PathDefinition {
|
|
61
|
-
pattern: string;
|
|
62
|
-
name?: string;
|
|
63
|
-
handler: ReactNode | Handler<any, any, any>;
|
|
64
|
-
use?: RouteUseItem[];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
88
|
/**
|
|
68
89
|
* Result of urls() - contains the route definitions
|
|
69
90
|
*/
|
|
@@ -72,8 +93,6 @@ export interface UrlPatterns<
|
|
|
72
93
|
TRoutes extends Record<string, any> = Record<string, string>,
|
|
73
94
|
TResponses extends Record<string, unknown> = Record<string, unknown>,
|
|
74
95
|
> {
|
|
75
|
-
/** Internal: route definitions */
|
|
76
|
-
readonly definitions: PathDefinition[];
|
|
77
96
|
/** Internal: compiled handler function */
|
|
78
97
|
readonly handler: () => AllUseItems[];
|
|
79
98
|
/** Internal: trailing slash config per route name */
|
|
@@ -88,6 +107,40 @@ export interface UrlPatterns<
|
|
|
88
107
|
readonly _responses?: TResponses;
|
|
89
108
|
}
|
|
90
109
|
|
|
110
|
+
/**
|
|
111
|
+
* Extract the phantom env type carried by a UrlPatterns value.
|
|
112
|
+
*/
|
|
113
|
+
export type UrlPatternsEnv<T> =
|
|
114
|
+
T extends UrlPatterns<infer TEnv, any, any> ? TEnv : never;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Guards `routes()` env compatibility without over-constraining.
|
|
118
|
+
*
|
|
119
|
+
* - An env-agnostic block (its env is `unknown` — e.g. a shared urls() module,
|
|
120
|
+
* or an app that does not augment `Rango.Env`) attaches to any router.
|
|
121
|
+
* - A block carrying a concrete env is accepted only when the router env
|
|
122
|
+
* (`TRouterEnv`) satisfies it; resolves to `never` otherwise, so a
|
|
123
|
+
* `urls<{ DB: D1Database }>()` cannot be mounted on a `createRouter<{}>()`.
|
|
124
|
+
*
|
|
125
|
+
* Use as `patterns: T & EnvCompatible<T, TEnv>` so `T` still infers from the
|
|
126
|
+
* argument — a bare `EnvCompatible<T, TEnv>` parameter sits in a non-inferrable
|
|
127
|
+
* conditional position and would collapse `T` to its constraint.
|
|
128
|
+
*
|
|
129
|
+
* Known limitation: `TRouterEnv extends ...` distributes over a union router env,
|
|
130
|
+
* so a `urls<A>()` block is accepted on `createRouter<A | B>()` even though the
|
|
131
|
+
* `B` arm cannot supply `A`'s env. Suppressing distribution with
|
|
132
|
+
* `[TRouterEnv] extends [...]` would close that edge but breaks the common
|
|
133
|
+
* generic-`TEnv` call sites (a deferred type parameter can't resolve the tuple
|
|
134
|
+
* conditional, so the intersection stops reducing to `T`). A router has one env,
|
|
135
|
+
* so a union env is not a supported pattern; the distributive form is kept.
|
|
136
|
+
*/
|
|
137
|
+
export type EnvCompatible<TPatterns, TRouterEnv> =
|
|
138
|
+
unknown extends UrlPatternsEnv<TPatterns>
|
|
139
|
+
? TPatterns
|
|
140
|
+
: TRouterEnv extends UrlPatternsEnv<TPatterns>
|
|
141
|
+
? TPatterns
|
|
142
|
+
: never;
|
|
143
|
+
|
|
91
144
|
/**
|
|
92
145
|
* Options for include()
|
|
93
146
|
*/
|
|
@@ -5,6 +5,7 @@ import type {
|
|
|
5
5
|
DefaultVars,
|
|
6
6
|
} from "../types/global-namespace.js";
|
|
7
7
|
import type { UseItems, ResponseRouteUseItem } from "../route-types.js";
|
|
8
|
+
import type { RequestScope } from "../types/request-scope.js";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Reverse function for response handler contexts.
|
|
@@ -31,21 +32,32 @@ type ResponseReverseFunction = [DefaultReverseRouteMap] extends [
|
|
|
31
32
|
* Symbol marking a route as a response route (non-RSC).
|
|
32
33
|
* Stored on PathOptions and UrlPatterns to signal the trie to short-circuit.
|
|
33
34
|
*/
|
|
34
|
-
export const RESPONSE_TYPE: unique symbol = Symbol.for(
|
|
35
|
-
"rangojs.responseType",
|
|
36
|
-
) as any;
|
|
35
|
+
export const RESPONSE_TYPE: unique symbol = Symbol.for("rangojs.responseType");
|
|
37
36
|
|
|
38
37
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
38
|
+
* Shared shape of a response-route handler: a function returning TReturn (or a
|
|
39
|
+
* promise of it), plus an optional composable `use` thunk merged at mount time.
|
|
41
40
|
*/
|
|
42
|
-
|
|
41
|
+
type ResponseHandlerOf<
|
|
42
|
+
TReturn,
|
|
43
|
+
TParams = Record<string, string>,
|
|
44
|
+
TEnv = any,
|
|
45
|
+
> = ((
|
|
43
46
|
ctx: ResponseHandlerContext<TParams, TEnv>,
|
|
44
|
-
) =>
|
|
47
|
+
) => TReturn | Promise<TReturn>) & {
|
|
45
48
|
/** Composable default DSL items merged when the handler is mounted. */
|
|
46
49
|
use?: () => UseItems<ResponseRouteUseItem>;
|
|
47
50
|
};
|
|
48
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Handler that must return Response (not ReactNode).
|
|
54
|
+
* Used by path.image(), path.stream(), path.any() (binary/streaming data).
|
|
55
|
+
*/
|
|
56
|
+
export type ResponseHandler<
|
|
57
|
+
TParams = Record<string, string>,
|
|
58
|
+
TEnv = any,
|
|
59
|
+
> = ResponseHandlerOf<Response, TParams, TEnv>;
|
|
60
|
+
|
|
49
61
|
/**
|
|
50
62
|
* JSON-serializable value type for auto-wrap support.
|
|
51
63
|
*/
|
|
@@ -64,12 +76,7 @@ export type JsonValue =
|
|
|
64
76
|
export type JsonResponseHandler<
|
|
65
77
|
TParams = Record<string, string>,
|
|
66
78
|
TEnv = any,
|
|
67
|
-
> =
|
|
68
|
-
ctx: ResponseHandlerContext<TParams, TEnv>,
|
|
69
|
-
) => JsonValue | Response | Promise<JsonValue | Response>) & {
|
|
70
|
-
/** Composable default DSL items merged when the handler is mounted. */
|
|
71
|
-
use?: () => UseItems<ResponseRouteUseItem>;
|
|
72
|
-
};
|
|
79
|
+
> = ResponseHandlerOf<JsonValue | Response, TParams, TEnv>;
|
|
73
80
|
|
|
74
81
|
/**
|
|
75
82
|
* Handler for text-based response routes (text, html, xml).
|
|
@@ -78,12 +85,7 @@ export type JsonResponseHandler<
|
|
|
78
85
|
export type TextResponseHandler<
|
|
79
86
|
TParams = Record<string, string>,
|
|
80
87
|
TEnv = any,
|
|
81
|
-
> =
|
|
82
|
-
ctx: ResponseHandlerContext<TParams, TEnv>,
|
|
83
|
-
) => string | Response | Promise<string | Response>) & {
|
|
84
|
-
/** Composable default DSL items merged when the handler is mounted. */
|
|
85
|
-
use?: () => UseItems<ResponseRouteUseItem>;
|
|
86
|
-
};
|
|
88
|
+
> = ResponseHandlerOf<string | Response, TParams, TEnv>;
|
|
87
89
|
|
|
88
90
|
/**
|
|
89
91
|
* Lighter handler context for response routes.
|
|
@@ -93,19 +95,10 @@ export type TextResponseHandler<
|
|
|
93
95
|
export interface ResponseHandlerContext<
|
|
94
96
|
TParams = Record<string, string>,
|
|
95
97
|
TEnv = any,
|
|
96
|
-
> {
|
|
97
|
-
request: Request;
|
|
98
|
+
> extends RequestScope<TEnv> {
|
|
98
99
|
params: TParams;
|
|
99
100
|
/** @internal Phantom property for params type invariance. Prevents mounting handlers on wrong routes. */
|
|
100
101
|
readonly _paramCheck?: (params: TParams) => TParams;
|
|
101
|
-
/** Platform bindings (DB, KV, secrets, etc.). */
|
|
102
|
-
env: TEnv;
|
|
103
|
-
/** Query parameters from the URL (system params like `_rsc*` are filtered). */
|
|
104
|
-
searchParams: URLSearchParams;
|
|
105
|
-
/** The full URL object (with system params filtered). */
|
|
106
|
-
url: URL;
|
|
107
|
-
/** The pathname portion of the request URL. */
|
|
108
|
-
pathname: string;
|
|
109
102
|
reverse: ResponseReverseFunction;
|
|
110
103
|
/** Read a variable set by middleware via ctx.set(key, value) or ctx.set(ContextVar, value). */
|
|
111
104
|
get: {
|