@rangojs/router 0.0.0-experimental.1b930379 → 0.0.0-experimental.1c0bdfad
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 +12 -0
- package/README.md +245 -49
- package/dist/bin/rango.js +441 -134
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3453 -1240
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +76 -21
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +64 -2
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +247 -23
- package/skills/caching/SKILL.md +318 -15
- package/skills/composability/SKILL.md +27 -2
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +4 -2
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +250 -30
- package/skills/host-router/SKILL.md +83 -23
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +50 -6
- package/skills/layout/SKILL.md +35 -9
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +279 -53
- package/skills/middleware/SKILL.md +52 -13
- package/skills/migrate-nextjs/SKILL.md +584 -0
- package/skills/migrate-react-router/SKILL.md +771 -0
- package/skills/mime-routes/SKILL.md +28 -1
- package/skills/observability/SKILL.md +172 -0
- package/skills/parallel/SKILL.md +203 -7
- package/skills/prerender/SKILL.md +153 -109
- package/skills/rango/SKILL.md +251 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +123 -48
- package/skills/route/SKILL.md +101 -5
- package/skills/router-setup/SKILL.md +116 -8
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +129 -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 +129 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +121 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +84 -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/typesafety/SKILL.md +332 -29
- package/skills/use-cache/SKILL.md +46 -14
- package/skills/view-transitions/SKILL.md +294 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +1 -66
- 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/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 +197 -150
- 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/navigation-bridge.ts +111 -31
- package/src/browser/navigation-client.ts +201 -67
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +76 -67
- package/src/browser/navigation-transaction.ts +18 -66
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +187 -112
- package/src/browser/prefetch/cache.ts +230 -35
- package/src/browser/prefetch/fetch.ts +338 -39
- package/src/browser/prefetch/queue.ts +126 -20
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +111 -16
- package/src/browser/react/NavigationProvider.tsx +135 -120
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- 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 +23 -69
- 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 +46 -11
- 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 +80 -5
- package/src/browser/rsc-router.tsx +218 -76
- package/src/browser/scroll-restoration.ts +54 -42
- package/src/browser/segment-reconciler.ts +36 -9
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +222 -61
- package/src/browser/types.ts +91 -11
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +65 -40
- package/src/build/generate-route-types.ts +5 -1
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +165 -36
- 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 +125 -24
- 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 +272 -96
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +29 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +214 -48
- package/src/cache/cache-scope.ts +236 -89
- 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 +2224 -171
- 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 +11 -17
- package/src/cache/document-cache.ts +89 -27
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +11 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +31 -31
- package/src/cache/read-through-swr.ts +41 -11
- package/src/cache/segment-codec.ts +9 -17
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +55 -0
- package/src/cache/types.ts +37 -100
- package/src/client.rsc.tsx +44 -21
- package/src/client.tsx +119 -290
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +109 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +84 -2
- package/src/debug.ts +2 -2
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +196 -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 +70 -22
- package/src/handles/MetaTags.tsx +56 -19
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +37 -8
- package/src/handles/is-thenable.ts +19 -0
- package/src/handles/meta.ts +51 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +0 -24
- package/src/host/index.ts +8 -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 +93 -12
- package/src/index.ts +133 -15
- 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 +37 -41
- package/src/prerender.ts +198 -82
- 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 +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +7 -72
- package/src/route-definition/dsl-helpers.ts +469 -276
- package/src/route-definition/helper-factories.ts +29 -139
- package/src/route-definition/helpers-types.ts +113 -37
- package/src/route-definition/index.ts +3 -0
- package/src/route-definition/redirect.ts +53 -12
- package/src/route-definition/resolve-handler-use.ts +161 -0
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-map-builder.ts +7 -17
- package/src/route-types.ts +37 -41
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +164 -17
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +45 -22
- package/src/router/handler-context.ts +83 -39
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +50 -24
- package/src/router/lazy-includes.ts +19 -53
- package/src/router/loader-resolution.ts +274 -56
- package/src/router/logging.ts +5 -8
- package/src/router/manifest.ts +49 -45
- package/src/router/match-api.ts +120 -204
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- package/src/router/match-middleware/background-revalidation.ts +33 -6
- package/src/router/match-middleware/cache-lookup.ts +214 -263
- package/src/router/match-middleware/cache-store.ts +73 -33
- package/src/router/match-middleware/intercept-resolution.ts +8 -28
- package/src/router/match-middleware/segment-resolution.ts +52 -18
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +104 -40
- package/src/router/metrics.ts +5 -34
- package/src/router/middleware-types.ts +13 -142
- package/src/router/middleware.ts +270 -172
- package/src/router/navigation-snapshot.ts +131 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +132 -90
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prerender-match.ts +195 -56
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +276 -0
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +244 -0
- package/src/router/router-context.ts +8 -28
- package/src/router/router-interfaces.ts +115 -35
- package/src/router/router-options.ts +172 -15
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +264 -77
- package/src/router/segment-resolution/helpers.ts +115 -30
- package/src/router/segment-resolution/loader-cache.ts +63 -37
- package/src/router/segment-resolution/revalidation.ts +474 -385
- 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 +36 -0
- package/src/router/segment-resolution.ts +5 -1
- package/src/router/segment-wrappers.ts +8 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +161 -199
- package/src/router/telemetry.ts +96 -19
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +206 -0
- package/src/router/trie-matching.ts +163 -59
- package/src/router/types.ts +10 -63
- package/src/router/url-params.ts +44 -0
- package/src/router.ts +163 -55
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +658 -511
- 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 +127 -31
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +77 -11
- package/src/rsc/redirect-guard.ts +99 -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 +105 -72
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +263 -112
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/types.ts +32 -6
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +149 -0
- package/src/segment-system.tsx +281 -129
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +309 -61
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +40 -38
- package/src/server/loader-registry.ts +26 -46
- package/src/server/request-context.ts +398 -172
- package/src/ssr/index.tsx +25 -16
- package/src/static-handler.ts +27 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +40 -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 +183 -0
- package/src/testing/index.ts +99 -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 +343 -0
- package/src/testing/render-route.tsx +581 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -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 +20 -58
- 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 +17 -8
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +233 -81
- package/src/types/index.ts +1 -10
- package/src/types/loader-types.ts +44 -15
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +6 -50
- package/src/types/route-entry.ts +19 -7
- package/src/types/segments.ts +37 -14
- package/src/urls/include-helper.ts +33 -70
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +58 -11
- package/src/urls/path-helper.ts +57 -111
- package/src/urls/pattern-types.ts +48 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +58 -139
- package/src/urls/urls-function.ts +1 -18
- package/src/use-loader.tsx +346 -89
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +36 -38
- package/src/vite/discovery/discover-routers.ts +130 -85
- package/src/vite/discovery/discovery-errors.ts +194 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +214 -132
- 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 +57 -6
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +6 -0
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +155 -65
- 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 +49 -98
- package/src/vite/plugins/expose-id-utils.ts +96 -51
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +15 -64
- 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 +553 -317
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/version-injector.ts +21 -25
- package/src/vite/plugins/version-plugin.ts +46 -37
- package/src/vite/plugins/virtual-entries.ts +13 -18
- package/src/vite/rango.ts +238 -295
- package/src/vite/router-discovery.ts +940 -149
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +4 -4
- 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 +81 -34
- package/src/vite/utils/shared-utils.ts +92 -42
- 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
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL param encode/decode at the route boundary.
|
|
3
|
+
*
|
|
4
|
+
* Extraction (decode): regex/trie matchers keep param values URL-encoded;
|
|
5
|
+
* `safeDecodeURIComponent` turns them back into raw strings so `ctx.params`
|
|
6
|
+
* matches the contract apps expect (Express/React Router/Fastify/Koa) and
|
|
7
|
+
* round-trips through reverse stay stable. Malformed %-encoding is
|
|
8
|
+
* preserved as-is so a broken URL doesn't crash matching.
|
|
9
|
+
*
|
|
10
|
+
* Reversal (encode): `encodePathSegment` escapes only what RFC 3986
|
|
11
|
+
* requires for a path segment — `/`, `?`, `#`, space, control chars,
|
|
12
|
+
* non-ASCII — and leaves pchar sub-delims (`@ : $ & + , ; =` and friends)
|
|
13
|
+
* readable. `encodeURIComponent` over-encodes for path segments, which
|
|
14
|
+
* makes generated URLs harder for humans to read in the address bar
|
|
15
|
+
* (e.g. mailbox IDs like `ivo@example.com` would become
|
|
16
|
+
* `ivo%40example.com` even though `@` is path-legal).
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export function safeDecodeURIComponent(raw: string): string {
|
|
20
|
+
if (raw === "" || raw.indexOf("%") === -1) return raw;
|
|
21
|
+
try {
|
|
22
|
+
return decodeURIComponent(raw);
|
|
23
|
+
} catch {
|
|
24
|
+
return raw;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const PATH_SAFE_ESCAPES: Record<string, string> = {
|
|
29
|
+
"%3A": ":",
|
|
30
|
+
"%40": "@",
|
|
31
|
+
"%24": "$",
|
|
32
|
+
"%26": "&",
|
|
33
|
+
"%2B": "+",
|
|
34
|
+
"%2C": ",",
|
|
35
|
+
"%3B": ";",
|
|
36
|
+
"%3D": "=",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export function encodePathSegment(value: string): string {
|
|
40
|
+
return encodeURIComponent(value).replace(
|
|
41
|
+
/%(?:3A|40|24|26|2B|2C|3B|3D)/gi,
|
|
42
|
+
(match) => PATH_SAFE_ESCAPES[match.toUpperCase()] ?? match,
|
|
43
|
+
);
|
|
44
|
+
}
|
package/src/router.ts
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import { createCacheScope } from "./cache/cache-scope.js";
|
|
3
|
-
import {
|
|
4
|
-
setCacheProfiles,
|
|
5
|
-
resolveCacheProfiles,
|
|
6
|
-
} from "./cache/profile-registry.js";
|
|
3
|
+
import { resolveCacheProfiles } from "./cache/profile-registry.js";
|
|
7
4
|
import { isCachedFunction } from "./cache/taint.js";
|
|
8
5
|
import { assertClientComponent } from "./component-utils.js";
|
|
9
6
|
import { DefaultDocument } from "./components/DefaultDocument.js";
|
|
@@ -19,11 +16,13 @@ import {
|
|
|
19
16
|
import MapRootLayout from "./server/root-layout.js";
|
|
20
17
|
import type { AllUseItems } from "./route-types.js";
|
|
21
18
|
import type { UrlPatterns } from "./urls.js";
|
|
19
|
+
import type { UrlBuilder } from "./urls/pattern-types.js";
|
|
20
|
+
import { urls } from "./urls.js";
|
|
21
|
+
import { buildPrecomputedByPrefix } from "./build/prefix-tree-utils.js";
|
|
22
22
|
import {
|
|
23
|
-
EntryData,
|
|
24
|
-
InterceptSelectorContext,
|
|
23
|
+
type EntryData,
|
|
25
24
|
getContext,
|
|
26
|
-
|
|
25
|
+
RangoContext,
|
|
27
26
|
type MetricsStore,
|
|
28
27
|
} from "./server/context";
|
|
29
28
|
import { createHandleStore, type HandleStore } from "./server/handle-store.js";
|
|
@@ -55,6 +54,7 @@ import { buildDebugManifest } from "./router/debug-manifest.js";
|
|
|
55
54
|
|
|
56
55
|
import type { SegmentResolutionDeps, MatchApiDeps } from "./router/types.js";
|
|
57
56
|
import { createHandlerContext } from "./router/handler-context.js";
|
|
57
|
+
import { normalizeBasename } from "./router/basename.js";
|
|
58
58
|
import {
|
|
59
59
|
setupLoaderAccess,
|
|
60
60
|
setupLoaderAccessSilent,
|
|
@@ -63,15 +63,17 @@ import {
|
|
|
63
63
|
import { loadManifest } from "./router/manifest.js";
|
|
64
64
|
import { createMetricsStore } from "./router/metrics.js";
|
|
65
65
|
import {
|
|
66
|
-
|
|
66
|
+
compileMiddlewarePattern,
|
|
67
67
|
type MiddlewareEntry,
|
|
68
68
|
type MiddlewareFn,
|
|
69
69
|
} from "./router/middleware.js";
|
|
70
70
|
import {
|
|
71
71
|
extractStaticPrefix,
|
|
72
|
+
joinPrefix,
|
|
72
73
|
traverseBack,
|
|
73
74
|
} from "./router/pattern-matching.js";
|
|
74
75
|
import { resolveSink, safeEmit, getRequestId } from "./router/telemetry.js";
|
|
76
|
+
import { resolveTracing } from "./router/tracing.js";
|
|
75
77
|
import { evaluateRevalidation } from "./router/revalidation.js";
|
|
76
78
|
import {
|
|
77
79
|
type RouterContext,
|
|
@@ -89,13 +91,10 @@ import {
|
|
|
89
91
|
RouterRegistry,
|
|
90
92
|
nextRouterAutoId,
|
|
91
93
|
} from "./router/router-registry.js";
|
|
94
|
+
import type { RangoOptions, RootLayoutProps } from "./router/router-options.js";
|
|
92
95
|
import type {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
} from "./router/router-options.js";
|
|
96
|
-
import type {
|
|
97
|
-
RSCRouter,
|
|
98
|
-
RSCRouterInternal,
|
|
96
|
+
Rango,
|
|
97
|
+
RangoInternal,
|
|
99
98
|
RouterRequestInput,
|
|
100
99
|
} from "./router/router-interfaces.js";
|
|
101
100
|
|
|
@@ -110,29 +109,32 @@ import {
|
|
|
110
109
|
matchForPrerender as _matchForPrerender,
|
|
111
110
|
renderStaticSegment as _renderStaticSegment,
|
|
112
111
|
} from "./router/prerender-match.js";
|
|
112
|
+
import { resolveStateCookieName } from "./router/state-cookie-name.js";
|
|
113
|
+
import { resolvePrefetchCacheTTL } from "./router/prefetch-cache-ttl.js";
|
|
113
114
|
|
|
114
115
|
// Re-export public types and values from extracted modules
|
|
115
116
|
export { RSC_ROUTER_BRAND, RouterRegistry } from "./router/router-registry.js";
|
|
116
117
|
export type {
|
|
117
|
-
|
|
118
|
+
RangoOptions,
|
|
118
119
|
RootLayoutProps,
|
|
119
120
|
SSRStreamMode,
|
|
120
121
|
SSROptions,
|
|
121
122
|
ResolveStreamingContext,
|
|
122
123
|
} from "./router/router-options.js";
|
|
123
124
|
export type {
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
Rango,
|
|
126
|
+
RangoInternal,
|
|
126
127
|
RouterRequestInput,
|
|
127
128
|
} from "./router/router-interfaces.js";
|
|
128
129
|
export { toInternal } from "./router/router-interfaces.js";
|
|
129
130
|
|
|
130
131
|
export function createRouter<TEnv = any>(
|
|
131
|
-
options:
|
|
132
|
-
):
|
|
132
|
+
options: RangoOptions<TEnv> = {},
|
|
133
|
+
): Rango<TEnv, {}> {
|
|
133
134
|
const {
|
|
134
135
|
id: userProvidedId,
|
|
135
136
|
$$id: injectedId,
|
|
137
|
+
basename: basenameOption,
|
|
136
138
|
debugPerformance = false,
|
|
137
139
|
document: documentOption,
|
|
138
140
|
defaultErrorBoundary,
|
|
@@ -148,24 +150,46 @@ export function createRouter<TEnv = any>(
|
|
|
148
150
|
nonce,
|
|
149
151
|
version,
|
|
150
152
|
prefetchCacheTTL: prefetchCacheTTLOption,
|
|
153
|
+
stateCookiePrefix: stateCookiePrefixOption,
|
|
151
154
|
warmup: warmupOption,
|
|
152
155
|
allowDebugManifest: allowDebugManifestOption = false,
|
|
153
156
|
telemetry: telemetrySink,
|
|
157
|
+
tracing: tracingOption,
|
|
154
158
|
ssr: ssrOption,
|
|
155
159
|
timeout: timeoutShorthand,
|
|
156
160
|
timeouts: timeoutsOption,
|
|
157
161
|
onTimeout,
|
|
158
162
|
originCheck: originCheckOption,
|
|
163
|
+
viewTransition: viewTransitionOption = "auto",
|
|
164
|
+
debugCacheSignal: debugCacheSignalOption = false,
|
|
165
|
+
strictMode: strictModeOption = true,
|
|
159
166
|
} = options;
|
|
160
167
|
|
|
168
|
+
// Debug cache signal gate (DEVELOPMENT/TEST ONLY). Enabled by the
|
|
169
|
+
// debugCacheSignal option OR the RANGO_TEST_SIGNALS=1 env flag. When off,
|
|
170
|
+
// no X-Rango-Cache header is emitted and output is byte-identical.
|
|
171
|
+
const cacheSignalEnabled =
|
|
172
|
+
debugCacheSignalOption ||
|
|
173
|
+
(typeof process !== "undefined" &&
|
|
174
|
+
(process as { env?: Record<string, string | undefined> }).env
|
|
175
|
+
?.RANGO_TEST_SIGNALS === "1");
|
|
176
|
+
|
|
177
|
+
// Normalize basename: ensure leading slash, strip trailing slash.
|
|
178
|
+
// A bare "/" is equivalent to no basename. Shared with the testing
|
|
179
|
+
// primitives via normalizeBasename so they can never drift.
|
|
180
|
+
const basename = normalizeBasename(basenameOption);
|
|
181
|
+
|
|
161
182
|
// Resolve telemetry sink (no-op when not configured)
|
|
162
183
|
const telemetry = resolveSink(telemetrySink);
|
|
163
184
|
|
|
164
|
-
// Resolve
|
|
165
|
-
//
|
|
166
|
-
|
|
185
|
+
// Resolve span tracing (undefined when not configured; every traceSpan() call
|
|
186
|
+
// is then a direct pass-through with zero behavior change).
|
|
187
|
+
const resolvedTracing = resolveTracing(tracingOption);
|
|
188
|
+
|
|
189
|
+
// Resolve cache profiles: merge user config with the guaranteed default
|
|
190
|
+
// profile. This resolved map is threaded onto each request context; the
|
|
191
|
+
// "use cache: <profile>" runtime path reads it request-scoped.
|
|
167
192
|
const resolvedCacheProfiles = resolveCacheProfiles(cacheProfilesOption);
|
|
168
|
-
setCacheProfiles(resolvedCacheProfiles);
|
|
169
193
|
|
|
170
194
|
// Source file: prefer Vite-injected path (zero cost), fall back to
|
|
171
195
|
// stack trace parsing for non-Vite environments (e.g. tests).
|
|
@@ -200,21 +224,32 @@ export function createRouter<TEnv = any>(
|
|
|
200
224
|
const routerId =
|
|
201
225
|
userProvidedId ?? injectedId ?? `router_${nextRouterAutoId()}`;
|
|
202
226
|
|
|
203
|
-
// Resolve
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
227
|
+
// Resolve the rango state cookie name once, here, so the two cookie writers
|
|
228
|
+
// (the client document.cookie writer and the server Set-Cookie writer)
|
|
229
|
+
// consume one pre-composed name and cannot drift.
|
|
230
|
+
const resolvedStateCookieName = resolveStateCookieName(
|
|
231
|
+
stateCookiePrefixOption,
|
|
232
|
+
routerId,
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
// Resolve prefetch cache TTL (default: 300 seconds / 5 minutes). Clamps to a
|
|
236
|
+
// non-negative integer and guards non-finite (NaN/Infinity) inputs so a
|
|
237
|
+
// malformed `Cache-Control: max-age=NaN` can never reach the wire.
|
|
238
|
+
const resolvedPrefetchCacheTTL = resolvePrefetchCacheTTL(
|
|
239
|
+
prefetchCacheTTLOption,
|
|
240
|
+
);
|
|
241
|
+
const prefetchCacheTTL = resolvedPrefetchCacheTTL.ms;
|
|
210
242
|
const prefetchCacheControl: string | false =
|
|
211
|
-
|
|
212
|
-
? false
|
|
213
|
-
: `private, max-age=${prefetchCacheTTLSeconds}`;
|
|
243
|
+
resolvedPrefetchCacheTTL.cacheControl;
|
|
214
244
|
|
|
215
245
|
// Resolve warmup enabled flag (default: true)
|
|
216
246
|
const warmupEnabled = warmupOption !== false;
|
|
217
247
|
|
|
248
|
+
// Resolve StrictMode flag (default: true). Shipped to the client in payload
|
|
249
|
+
// metadata; the browser entry reads it once to decide whether to wrap the
|
|
250
|
+
// hydrated tree in React.StrictMode.
|
|
251
|
+
const strictMode = strictModeOption !== false;
|
|
252
|
+
|
|
218
253
|
// Resolve theme config (null if theme not enabled)
|
|
219
254
|
const resolvedThemeConfig = themeOption
|
|
220
255
|
? resolveThemeConfig(themeOption)
|
|
@@ -246,9 +281,14 @@ export function createRouter<TEnv = any>(
|
|
|
246
281
|
invokeOnError(onError, error, phase, context, "Router");
|
|
247
282
|
}
|
|
248
283
|
|
|
249
|
-
// Validate document is a client component
|
|
284
|
+
// Validate document is a client component. Under a test runner the "use
|
|
285
|
+
// client" transform has not run, so a real exported document has no marker;
|
|
286
|
+
// allowServerInTest lets the router construct in a bare unit test (for
|
|
287
|
+
// dispatch / assertGeneratedRoutesMatch) while a real build still throws.
|
|
250
288
|
if (documentOption !== undefined) {
|
|
251
|
-
assertClientComponent(documentOption, "document"
|
|
289
|
+
assertClientComponent(documentOption, "document", {
|
|
290
|
+
allowServerInTest: true,
|
|
291
|
+
});
|
|
252
292
|
}
|
|
253
293
|
|
|
254
294
|
// Use default document if none provided (keeps internal name as rootLayout)
|
|
@@ -312,7 +352,7 @@ export function createRouter<TEnv = any>(
|
|
|
312
352
|
let regex: RegExp | null = null;
|
|
313
353
|
let paramNames: string[] = [];
|
|
314
354
|
if (fullPattern) {
|
|
315
|
-
const parsed =
|
|
355
|
+
const parsed = compileMiddlewarePattern(fullPattern);
|
|
316
356
|
regex = parsed.regex;
|
|
317
357
|
paramNames = parsed.paramNames;
|
|
318
358
|
}
|
|
@@ -322,7 +362,6 @@ export function createRouter<TEnv = any>(
|
|
|
322
362
|
regex,
|
|
323
363
|
paramNames,
|
|
324
364
|
handler,
|
|
325
|
-
mountPrefix,
|
|
326
365
|
});
|
|
327
366
|
}
|
|
328
367
|
|
|
@@ -356,9 +395,11 @@ export function createRouter<TEnv = any>(
|
|
|
356
395
|
getRouterPrecomputedEntries(routerId) ?? getPrecomputedEntries();
|
|
357
396
|
if (current !== precomputedSource) {
|
|
358
397
|
precomputedSource = current;
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
398
|
+
// buildPrecomputedByPrefix drops any staticPrefix owned by more than one
|
|
399
|
+
// leaf include instead of collapsing it last-wins (which would mis-assign
|
|
400
|
+
// one include's routes to another's entry and 500 a valid sibling route).
|
|
401
|
+
// Such shared-prefix includes resolve via the handler path instead.
|
|
402
|
+
precomputedByPrefix = current ? buildPrecomputedByPrefix(current) : null;
|
|
362
403
|
}
|
|
363
404
|
return precomputedByPrefix;
|
|
364
405
|
}
|
|
@@ -526,7 +567,9 @@ export function createRouter<TEnv = any>(
|
|
|
526
567
|
trackHandler,
|
|
527
568
|
findNearestErrorBoundary,
|
|
528
569
|
findNearestNotFoundBoundary,
|
|
570
|
+
notFoundComponent: notFound,
|
|
529
571
|
callOnError,
|
|
572
|
+
viewTransitionDefault: viewTransitionOption,
|
|
530
573
|
};
|
|
531
574
|
|
|
532
575
|
// Match API dependencies
|
|
@@ -560,6 +603,7 @@ export function createRouter<TEnv = any>(
|
|
|
560
603
|
mergedRouteMap,
|
|
561
604
|
nextMountIndex: () => mountIndex++,
|
|
562
605
|
getPrecomputedByPrefix,
|
|
606
|
+
routerId,
|
|
563
607
|
};
|
|
564
608
|
|
|
565
609
|
function evaluateLazyEntry(entry: RouteEntry<TEnv>): void {
|
|
@@ -613,6 +657,8 @@ export function createRouter<TEnv = any>(
|
|
|
613
657
|
params: Record<string, string>,
|
|
614
658
|
buildVars?: Record<string, any>,
|
|
615
659
|
isPassthroughRoute?: boolean,
|
|
660
|
+
buildEnv?: TEnv,
|
|
661
|
+
devMode?: boolean,
|
|
616
662
|
) {
|
|
617
663
|
return _matchForPrerender(
|
|
618
664
|
pathname,
|
|
@@ -620,6 +666,8 @@ export function createRouter<TEnv = any>(
|
|
|
620
666
|
prerenderDeps,
|
|
621
667
|
buildVars,
|
|
622
668
|
isPassthroughRoute,
|
|
669
|
+
buildEnv,
|
|
670
|
+
devMode,
|
|
623
671
|
);
|
|
624
672
|
}
|
|
625
673
|
|
|
@@ -627,12 +675,16 @@ export function createRouter<TEnv = any>(
|
|
|
627
675
|
handler: Function,
|
|
628
676
|
handlerId: string,
|
|
629
677
|
routeName?: string,
|
|
678
|
+
buildEnv?: TEnv,
|
|
679
|
+
devMode?: boolean,
|
|
630
680
|
) {
|
|
631
681
|
return _renderStaticSegment<TEnv>(
|
|
632
682
|
handler,
|
|
633
683
|
handlerId,
|
|
634
684
|
mergedRouteMap,
|
|
635
685
|
routeName,
|
|
686
|
+
buildEnv,
|
|
687
|
+
devMode,
|
|
636
688
|
);
|
|
637
689
|
}
|
|
638
690
|
|
|
@@ -645,6 +697,7 @@ export function createRouter<TEnv = any>(
|
|
|
645
697
|
findMatch,
|
|
646
698
|
findInterceptForRoute,
|
|
647
699
|
telemetry: telemetrySink,
|
|
700
|
+
cacheSignalEnabled,
|
|
648
701
|
});
|
|
649
702
|
|
|
650
703
|
const { match, matchPartial, matchError, previewMatch } = matchHandlers;
|
|
@@ -654,11 +707,18 @@ export function createRouter<TEnv = any>(
|
|
|
654
707
|
* The type system tracks accumulated routes through the builder chain
|
|
655
708
|
* Initial TRoutes is {} (empty) to avoid poisoning accumulated types with Record<string, string>
|
|
656
709
|
*/
|
|
657
|
-
const router:
|
|
710
|
+
const router: RangoInternal<TEnv, {}> = {
|
|
658
711
|
__brand: RSC_ROUTER_BRAND,
|
|
659
712
|
id: routerId,
|
|
713
|
+
basename,
|
|
714
|
+
|
|
715
|
+
routes(patternsOrBuilder: UrlPatterns<TEnv> | UrlBuilder<TEnv>): any {
|
|
716
|
+
// Wrap builder functions in urls() automatically
|
|
717
|
+
const urlPatterns: UrlPatterns<TEnv> =
|
|
718
|
+
typeof patternsOrBuilder === "function"
|
|
719
|
+
? (urls(patternsOrBuilder) as UrlPatterns<TEnv>)
|
|
720
|
+
: patternsOrBuilder;
|
|
660
721
|
|
|
661
|
-
routes(urlPatterns: UrlPatterns<TEnv>): any {
|
|
662
722
|
// Store reference for runtime manifest generation
|
|
663
723
|
storedUrlPatterns = urlPatterns;
|
|
664
724
|
const currentMountIndex = mountIndex++;
|
|
@@ -689,13 +749,13 @@ export function createRouter<TEnv = any>(
|
|
|
689
749
|
errorBoundary: [],
|
|
690
750
|
notFoundBoundary: [],
|
|
691
751
|
layout: [],
|
|
692
|
-
parallel:
|
|
752
|
+
parallel: {},
|
|
693
753
|
intercept: [],
|
|
694
754
|
loader: [],
|
|
695
755
|
};
|
|
696
756
|
|
|
697
757
|
let handlerResult: AllUseItems[] = [];
|
|
698
|
-
|
|
758
|
+
RangoContext.run(
|
|
699
759
|
{
|
|
700
760
|
manifest,
|
|
701
761
|
patterns: routePatterns,
|
|
@@ -706,6 +766,10 @@ export function createRouter<TEnv = any>(
|
|
|
706
766
|
counters: {},
|
|
707
767
|
mountIndex: currentMountIndex,
|
|
708
768
|
cacheProfiles: resolvedCacheProfiles,
|
|
769
|
+
// basename sets the initial URL prefix so all path() patterns
|
|
770
|
+
// are registered with the prefix (e.g. "/admin" + "/users" = "/admin/users").
|
|
771
|
+
// No namePrefix — route names stay unprefixed.
|
|
772
|
+
...(basename ? { urlPrefix: basename } : {}),
|
|
709
773
|
},
|
|
710
774
|
() => {
|
|
711
775
|
handlerResult = urlPatterns.handler() as AllUseItems[];
|
|
@@ -725,7 +789,7 @@ export function createRouter<TEnv = any>(
|
|
|
725
789
|
if (entry.type === "route" && entry.isPrerender) {
|
|
726
790
|
if (!prerenderRouteKeys) prerenderRouteKeys = new Set();
|
|
727
791
|
prerenderRouteKeys.add(name);
|
|
728
|
-
if (entry.
|
|
792
|
+
if (entry.isPassthrough === true) {
|
|
729
793
|
if (!passthroughRouteKeys) passthroughRouteKeys = new Set();
|
|
730
794
|
passthroughRouteKeys.add(name);
|
|
731
795
|
}
|
|
@@ -751,6 +815,7 @@ export function createRouter<TEnv = any>(
|
|
|
751
815
|
trailingSlash: trailingSlashConfig,
|
|
752
816
|
handler: urlPatterns.handler,
|
|
753
817
|
mountIndex: currentMountIndex,
|
|
818
|
+
routerId,
|
|
754
819
|
cacheProfiles: resolvedCacheProfiles,
|
|
755
820
|
...(prerenderRouteKeys ? { prerenderRouteKeys } : {}),
|
|
756
821
|
...(passthroughRouteKeys ? { passthroughRouteKeys } : {}),
|
|
@@ -770,6 +835,7 @@ export function createRouter<TEnv = any>(
|
|
|
770
835
|
trailingSlash: trailingSlashConfig,
|
|
771
836
|
handler: urlPatterns.handler,
|
|
772
837
|
mountIndex: currentMountIndex,
|
|
838
|
+
routerId,
|
|
773
839
|
cacheProfiles: resolvedCacheProfiles,
|
|
774
840
|
...(prerenderRouteKeys ? { prerenderRouteKeys } : {}),
|
|
775
841
|
...(passthroughRouteKeys ? { passthroughRouteKeys } : {}),
|
|
@@ -801,10 +867,13 @@ export function createRouter<TEnv = any>(
|
|
|
801
867
|
|
|
802
868
|
// Create placeholder RouteEntry for each lazy include
|
|
803
869
|
for (const lazyInclude of lazyIncludes) {
|
|
804
|
-
// Compute the full URL prefix (combining parent prefix if any)
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
870
|
+
// Compute the full URL prefix (combining parent prefix if any). Use the
|
|
871
|
+
// slash-collapsing join so a trailing-slash parent prefix does not
|
|
872
|
+
// produce a double-slash staticPrefix the trie's sp can never match.
|
|
873
|
+
const fullPrefix = joinPrefix(
|
|
874
|
+
lazyInclude.context.urlPrefix,
|
|
875
|
+
lazyInclude.prefix,
|
|
876
|
+
);
|
|
808
877
|
|
|
809
878
|
const lazyEntry: RouteEntry<TEnv> & { _lazyPrefix?: string } = {
|
|
810
879
|
prefix: "",
|
|
@@ -813,6 +882,7 @@ export function createRouter<TEnv = any>(
|
|
|
813
882
|
trailingSlash: trailingSlashConfig,
|
|
814
883
|
handler: urlPatterns.handler,
|
|
815
884
|
mountIndex: mountIndex++,
|
|
885
|
+
routerId,
|
|
816
886
|
// Lazy evaluation fields
|
|
817
887
|
lazy: true,
|
|
818
888
|
lazyPatterns: lazyInclude.patterns,
|
|
@@ -851,8 +921,18 @@ export function createRouter<TEnv = any>(
|
|
|
851
921
|
patternOrMiddleware: string | MiddlewareFn<TEnv>,
|
|
852
922
|
middleware?: MiddlewareFn<TEnv>,
|
|
853
923
|
): any {
|
|
854
|
-
//
|
|
855
|
-
|
|
924
|
+
// Auto-prefix pattern with basename so router-level middleware
|
|
925
|
+
// patterns are router-relative (e.g. "/users/*" matches "/app/users/*").
|
|
926
|
+
if (basename && typeof patternOrMiddleware === "string") {
|
|
927
|
+
const pattern = patternOrMiddleware;
|
|
928
|
+
const prefixed =
|
|
929
|
+
pattern === "/*" || pattern === "*"
|
|
930
|
+
? `${basename}/*`
|
|
931
|
+
: `${basename}${pattern}`;
|
|
932
|
+
addMiddleware(prefixed, middleware, null);
|
|
933
|
+
} else {
|
|
934
|
+
addMiddleware(patternOrMiddleware, middleware, null);
|
|
935
|
+
}
|
|
856
936
|
return router;
|
|
857
937
|
},
|
|
858
938
|
|
|
@@ -889,12 +969,22 @@ export function createRouter<TEnv = any>(
|
|
|
889
969
|
prefetchCacheControl,
|
|
890
970
|
prefetchCacheTTL,
|
|
891
971
|
|
|
972
|
+
// Expose the resolved rango state cookie name for the server-side writer
|
|
973
|
+
// (invalidateClientCache) and for shipping to the client in metadata.
|
|
974
|
+
resolvedStateCookieName,
|
|
975
|
+
|
|
892
976
|
// Expose warmup enabled flag for handler and client
|
|
893
977
|
warmupEnabled,
|
|
894
978
|
|
|
979
|
+
// Expose StrictMode flag for the initial-render payload metadata
|
|
980
|
+
strictMode,
|
|
981
|
+
|
|
895
982
|
// Expose router-wide performance debugging for request-level metrics setup
|
|
896
983
|
debugPerformance,
|
|
897
984
|
|
|
985
|
+
// Expose resolved span tracing for the handler (Cloudflare custom spans)
|
|
986
|
+
tracing: resolvedTracing,
|
|
987
|
+
|
|
898
988
|
// Expose debug manifest flag for handler
|
|
899
989
|
allowDebugManifest: allowDebugManifestOption,
|
|
900
990
|
|
|
@@ -953,6 +1043,16 @@ export function createRouter<TEnv = any>(
|
|
|
953
1043
|
// Expose source file for per-router type generation
|
|
954
1044
|
__sourceFile,
|
|
955
1045
|
|
|
1046
|
+
// Expose basename for runtime manifest generation
|
|
1047
|
+
__basename: basename,
|
|
1048
|
+
|
|
1049
|
+
// Expose router-level boundary defaults for build-time clientChunks
|
|
1050
|
+
// discovery (so a "use client" default boundary lands in app-fallback).
|
|
1051
|
+
// These are createRouter options, never pushed onto EntryData.
|
|
1052
|
+
__defaultErrorBoundary: defaultErrorBoundary,
|
|
1053
|
+
__defaultNotFoundBoundary: defaultNotFoundBoundary,
|
|
1054
|
+
__notFound: notFound,
|
|
1055
|
+
|
|
956
1056
|
// RSC request handler (lazily created on first call)
|
|
957
1057
|
fetch: (() => {
|
|
958
1058
|
// Handler is created on first call and reused
|
|
@@ -970,8 +1070,10 @@ export function createRouter<TEnv = any>(
|
|
|
970
1070
|
if (!handler) {
|
|
971
1071
|
// Lazy import deferred to first request to avoid dev mode issues
|
|
972
1072
|
const { createRSCHandler } = await import("./rsc/handler.js");
|
|
973
|
-
// Cast:
|
|
974
|
-
//
|
|
1073
|
+
// Cast: createRSCHandler receives `router as any`, which erases TEnv
|
|
1074
|
+
// and infers its handler as RouterRequestInput<unknown>. Re-narrow the
|
|
1075
|
+
// returned handler to RouterRequestInput<TEnv> so the call below stays
|
|
1076
|
+
// typed. (The handler already accepts (request, RouterRequestInput).)
|
|
975
1077
|
handler = createRSCHandler({
|
|
976
1078
|
router: router as any,
|
|
977
1079
|
cache,
|
|
@@ -986,6 +1088,10 @@ export function createRouter<TEnv = any>(
|
|
|
986
1088
|
};
|
|
987
1089
|
})(),
|
|
988
1090
|
|
|
1091
|
+
// Low-level route matching for request classification
|
|
1092
|
+
findMatch: (pathname: string, metricsStore?: any) =>
|
|
1093
|
+
findMatch(pathname, metricsStore),
|
|
1094
|
+
|
|
989
1095
|
// Debug utility for manifest inspection
|
|
990
1096
|
debugManifest: () => buildDebugManifest<TEnv>(routesEntries),
|
|
991
1097
|
};
|
|
@@ -994,8 +1100,10 @@ export function createRouter<TEnv = any>(
|
|
|
994
1100
|
RouterRegistry.set(routerId, router);
|
|
995
1101
|
|
|
996
1102
|
// If urls option was provided, auto-register them
|
|
997
|
-
if (urlsOption) {
|
|
998
|
-
return router.routes(urlsOption) as
|
|
1103
|
+
if (typeof urlsOption === "function") {
|
|
1104
|
+
return router.routes(urlsOption) as Rango<TEnv, {}>;
|
|
1105
|
+
} else if (urlsOption) {
|
|
1106
|
+
return router.routes(urlsOption) as Rango<TEnv, {}>;
|
|
999
1107
|
}
|
|
1000
1108
|
|
|
1001
1109
|
return router;
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
* RSC rendering) so they can be standalone modules without closure coupling.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type {
|
|
9
|
+
import type { RangoInternal } from "../router/router-interfaces.js";
|
|
10
10
|
import type { ErrorPhase } from "../types.js";
|
|
11
11
|
import type { InvokeOnErrorContext } from "../router/error-handling.js";
|
|
12
12
|
import type { RSCDependencies, LoadSSRModule } from "./types.js";
|
|
13
13
|
import type { SSRStreamMode } from "../router/router-options.js";
|
|
14
14
|
|
|
15
15
|
export interface HandlerContext<TEnv = unknown> {
|
|
16
|
-
router:
|
|
16
|
+
router: RangoInternal<TEnv, any>;
|
|
17
17
|
version: string;
|
|
18
18
|
renderToReadableStream: RSCDependencies["renderToReadableStream"];
|
|
19
19
|
decodeReply: RSCDependencies["decodeReply"];
|
|
@@ -31,6 +31,7 @@ export interface HandlerContext<TEnv = unknown> {
|
|
|
31
31
|
createRedirectFlightResponse: (
|
|
32
32
|
redirectUrl: string,
|
|
33
33
|
locationState?: Record<string, unknown>,
|
|
34
|
+
external?: boolean,
|
|
34
35
|
) => Response;
|
|
35
36
|
|
|
36
37
|
/**
|