@rangojs/router 0.0.0-experimental.eb0645d3 → 0.0.0-experimental.f1468e3c
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 -0
- package/README.md +126 -16
- package/dist/bin/rango.js +319 -95
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +2724 -1053
- package/package.json +68 -14
- 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 +224 -32
- package/skills/caching/SKILL.md +279 -17
- package/skills/composability/SKILL.md +27 -3
- 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 +11 -9
- package/skills/hooks/SKILL.md +243 -29
- package/skills/host-router/SKILL.md +83 -23
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +68 -19
- package/skills/layout/SKILL.md +13 -9
- package/skills/links/SKILL.md +190 -23
- package/skills/loader/SKILL.md +235 -9
- package/skills/middleware/SKILL.md +18 -10
- package/skills/migrate-nextjs/SKILL.md +43 -19
- package/skills/migrate-react-router/SKILL.md +8 -2
- package/skills/mime-routes/SKILL.md +28 -1
- package/skills/observability/SKILL.md +172 -0
- package/skills/parallel/SKILL.md +18 -7
- package/skills/prerender/SKILL.md +65 -60
- package/skills/rango/SKILL.md +251 -24
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +115 -48
- package/skills/route/SKILL.md +46 -5
- package/skills/router-setup/SKILL.md +30 -8
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/tailwind/SKILL.md +27 -3
- 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 +129 -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 +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 +322 -29
- package/skills/use-cache/SKILL.md +57 -14
- 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 +192 -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 +94 -25
- package/src/browser/navigation-client.ts +121 -84
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +115 -67
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +147 -128
- package/src/browser/prefetch/cache.ts +107 -56
- package/src/browser/prefetch/fetch.ts +204 -34
- package/src/browser/prefetch/queue.ts +6 -3
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +30 -7
- package/src/browser/react/NavigationProvider.tsx +283 -118
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/deferred-handle-resolution.ts +75 -0
- 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 +10 -5
- package/src/browser/react/use-params.ts +11 -11
- 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 +91 -24
- package/src/browser/scroll-restoration.ts +30 -17
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +214 -55
- package/src/browser/types.ts +80 -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 +60 -35
- package/src/build/generate-route-types.ts +2 -1
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +117 -14
- 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 +117 -23
- 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 +55 -28
- 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 +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 +224 -41
- package/src/cache/cache-scope.ts +188 -82
- 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 +1989 -378
- 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 +89 -21
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +10 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +9 -17
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +37 -100
- package/src/client.rsc.tsx +44 -21
- package/src/client.tsx +36 -61
- 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 +18 -6
- 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 +31 -23
- package/src/handles/MetaTags.tsx +62 -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 +96 -12
- package/src/index.ts +94 -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 +61 -6
- 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 +34 -0
- package/src/reverse.ts +65 -40
- 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 +82 -55
- 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 +0 -16
- 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 +44 -23
- package/src/router/handler-context.ts +27 -43
- package/src/router/instrument.ts +350 -0
- package/src/router/intercept-resolution.ts +39 -20
- package/src/router/lazy-includes.ts +10 -47
- package/src/router/loader-resolution.ts +155 -72
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +18 -29
- package/src/router/match-api.ts +9 -24
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- 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 +44 -74
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -134
- package/src/router/middleware.ts +247 -166
- package/src/router/navigation-snapshot.ts +0 -51
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +85 -94
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prerender-match.ts +104 -65
- package/src/router/preview-match.ts +3 -1
- package/src/router/request-classification.ts +28 -62
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +0 -1
- package/src/router/router-context.ts +3 -28
- package/src/router/router-interfaces.ts +83 -35
- package/src/router/router-options.ts +136 -5
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +97 -84
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +76 -39
- 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 +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 +162 -64
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +0 -5
- package/src/router.ts +110 -55
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +264 -220
- package/src/rsc/helpers.ts +100 -6
- 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 +28 -41
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +117 -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 +88 -188
- package/src/rsc/rsc-rendering.ts +98 -76
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +281 -117
- package/src/rsc/ssr-setup.ts +16 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +23 -5
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-loader-promise.ts +31 -4
- package/src/segment-system.tsx +254 -143
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +163 -51
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +21 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +287 -178
- package/src/ssr/index.tsx +21 -16
- package/src/static-handler.ts +10 -13
- 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 +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 +581 -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 +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 +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 +6 -50
- package/src/types/route-entry.ts +0 -6
- package/src/types/segments.ts +135 -14
- package/src/urls/include-helper.ts +9 -56
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +29 -12
- package/src/urls/path-helper.ts +17 -106
- package/src/urls/pattern-types.ts +36 -19
- package/src/urls/response-types.ts +22 -29
- package/src/urls/type-extraction.ts +58 -139
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +292 -107
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +8 -7
- package/src/vite/discovery/discover-routers.ts +126 -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 +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 +44 -0
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +2 -0
- package/src/vite/inject-client-debug.ts +36 -0
- package/src/vite/plugin-types.ts +126 -8
- 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-stub.ts +1 -21
- 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/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +37 -40
- package/src/vite/plugins/virtual-entries.ts +39 -25
- package/src/vite/rango.ts +109 -118
- package/src/vite/router-discovery.ts +718 -119
- 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 +54 -39
- package/src/vite/utils/shared-utils.ts +90 -41
- 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
package/src/rsc/rsc-rendering.ts
CHANGED
|
@@ -7,34 +7,95 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
|
-
|
|
10
|
+
getRequestContext,
|
|
11
11
|
setRequestContextParams,
|
|
12
|
-
getLocationState,
|
|
13
12
|
} from "../server/request-context.js";
|
|
14
|
-
import { resolveLocationStateEntries } from "../browser/react/location-state-shared.js";
|
|
15
13
|
import { appendMetric } from "../router/metrics.js";
|
|
16
|
-
import {
|
|
14
|
+
import { observePhase, PHASES } from "../router/instrument.js";
|
|
15
|
+
import { getSSRSetup, isRscRequest } from "./ssr-setup.js";
|
|
17
16
|
import type { RscPayload } from "./types.js";
|
|
17
|
+
import type { MatchResult } from "../types.js";
|
|
18
18
|
import {
|
|
19
19
|
createResponseWithMergedHeaders,
|
|
20
20
|
createSimpleRedirectResponse,
|
|
21
|
+
attachLocationStateIfPresent,
|
|
21
22
|
} from "./helpers.js";
|
|
22
23
|
import type { HandlerContext } from "./handler-context.js";
|
|
24
|
+
import { gateTransitions } from "./transition-gate.js";
|
|
23
25
|
|
|
24
|
-
export
|
|
26
|
+
export function handleRscRendering<TEnv>(
|
|
25
27
|
ctx: HandlerContext<TEnv>,
|
|
26
28
|
request: Request,
|
|
27
29
|
env: TEnv,
|
|
28
30
|
url: URL,
|
|
29
31
|
isPartial: boolean,
|
|
30
|
-
handleStore: ReturnType<typeof
|
|
32
|
+
handleStore: ReturnType<typeof getRequestContext>["_handleStore"],
|
|
31
33
|
nonce: string | undefined,
|
|
32
34
|
): Promise<Response> {
|
|
33
|
-
|
|
35
|
+
// Instrument the whole render phase once through the unified API: it records
|
|
36
|
+
// the "render:total" perf metric AND opens the "rango.render" span from the
|
|
37
|
+
// same boundary (match -> serialize -> SSR), so the two surfaces agree.
|
|
38
|
+
// Loaders kicked off during matching nest under the span; the SSR HTML pass
|
|
39
|
+
// below opens "rango.ssr" the same way.
|
|
40
|
+
return observePhase(PHASES.render, () =>
|
|
41
|
+
handleRscRenderingInner(
|
|
42
|
+
ctx,
|
|
43
|
+
request,
|
|
44
|
+
env,
|
|
45
|
+
url,
|
|
46
|
+
isPartial,
|
|
47
|
+
handleStore,
|
|
48
|
+
nonce,
|
|
49
|
+
),
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function handleRscRenderingInner<TEnv>(
|
|
54
|
+
ctx: HandlerContext<TEnv>,
|
|
55
|
+
request: Request,
|
|
56
|
+
env: TEnv,
|
|
57
|
+
url: URL,
|
|
58
|
+
isPartial: boolean,
|
|
59
|
+
handleStore: ReturnType<typeof getRequestContext>["_handleStore"],
|
|
60
|
+
nonce: string | undefined,
|
|
61
|
+
): Promise<Response> {
|
|
62
|
+
const reqCtx = getRequestContext();
|
|
34
63
|
|
|
35
64
|
let payload: RscPayload;
|
|
36
65
|
let hasInterceptSlots = false;
|
|
37
66
|
|
|
67
|
+
// Shared by the partial-fallback and full-render paths. The partial-success
|
|
68
|
+
// payload below is intentionally different (omits rootLayout/theme, adds slots).
|
|
69
|
+
const buildFullPayload = (m: MatchResult): RscPayload => ({
|
|
70
|
+
metadata: {
|
|
71
|
+
pathname: url.pathname,
|
|
72
|
+
routerId: ctx.router.id,
|
|
73
|
+
basename: ctx.router.basename,
|
|
74
|
+
segments: gateTransitions(m.segments, reqCtx, ctx.router.onError),
|
|
75
|
+
matched: m.matched,
|
|
76
|
+
diff: m.diff,
|
|
77
|
+
resolvedIds: m.resolvedIds,
|
|
78
|
+
params: m.params,
|
|
79
|
+
isPartial: false,
|
|
80
|
+
rootLayout: ctx.router.rootLayout,
|
|
81
|
+
handles: handleStore.stream(),
|
|
82
|
+
version: ctx.version,
|
|
83
|
+
prefetchCacheTTL: ctx.router.prefetchCacheTTL,
|
|
84
|
+
stateCookieName: ctx.router.resolvedStateCookieName,
|
|
85
|
+
themeConfig: ctx.router.themeConfig,
|
|
86
|
+
// Carry warmupEnabled on the initial full-render payload so the client
|
|
87
|
+
// respects warmup:false from first load. The 404 and PE payloads already
|
|
88
|
+
// include it; without it here warmup could never be disabled on the
|
|
89
|
+
// normal full-load path (partial payloads omit it by design).
|
|
90
|
+
warmupEnabled: ctx.router.warmupEnabled,
|
|
91
|
+
// Carry strictMode on the initial full-render payload so the browser
|
|
92
|
+
// entry knows whether to wrap hydration in React.StrictMode. Partial
|
|
93
|
+
// (navigation) payloads omit it by design; StrictMode is decided once.
|
|
94
|
+
strictMode: ctx.router.strictMode,
|
|
95
|
+
initialTheme: reqCtx.theme,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
|
|
38
99
|
if (isPartial) {
|
|
39
100
|
// Partial render (navigation)
|
|
40
101
|
const result = await ctx.router.matchPartial(request, { env });
|
|
@@ -51,24 +112,7 @@ export async function handleRscRendering<TEnv>(
|
|
|
51
112
|
return createSimpleRedirectResponse(match.redirect);
|
|
52
113
|
}
|
|
53
114
|
|
|
54
|
-
payload =
|
|
55
|
-
metadata: {
|
|
56
|
-
pathname: url.pathname,
|
|
57
|
-
routerId: ctx.router.id,
|
|
58
|
-
basename: ctx.router.basename,
|
|
59
|
-
segments: match.segments,
|
|
60
|
-
matched: match.matched,
|
|
61
|
-
diff: match.diff,
|
|
62
|
-
params: match.params,
|
|
63
|
-
isPartial: false,
|
|
64
|
-
rootLayout: ctx.router.rootLayout,
|
|
65
|
-
handles: handleStore.stream(),
|
|
66
|
-
version: ctx.version,
|
|
67
|
-
prefetchCacheTTL: ctx.router.prefetchCacheTTL,
|
|
68
|
-
themeConfig: ctx.router.themeConfig,
|
|
69
|
-
initialTheme: reqCtx.theme,
|
|
70
|
-
},
|
|
71
|
-
};
|
|
115
|
+
payload = buildFullPayload(match);
|
|
72
116
|
} else {
|
|
73
117
|
setRequestContextParams(result.params, result.routeName);
|
|
74
118
|
|
|
@@ -77,16 +121,27 @@ export async function handleRscRendering<TEnv>(
|
|
|
77
121
|
payload = {
|
|
78
122
|
metadata: {
|
|
79
123
|
pathname: url.pathname,
|
|
124
|
+
// routerId is serialized on every payload (including within-session
|
|
125
|
+
// ones) so the frontend can read the current app/router identity. It
|
|
126
|
+
// always equals the current app's id: a cross-app navigation is
|
|
127
|
+
// intercepted server-side (X-RSC-Reload) and never delivers a
|
|
128
|
+
// different-router payload to the client.
|
|
80
129
|
routerId: ctx.router.id,
|
|
81
|
-
segments:
|
|
130
|
+
segments: gateTransitions(
|
|
131
|
+
result.segments,
|
|
132
|
+
reqCtx,
|
|
133
|
+
ctx.router.onError,
|
|
134
|
+
),
|
|
82
135
|
matched: result.matched,
|
|
83
136
|
diff: result.diff,
|
|
137
|
+
resolvedIds: result.resolvedIds,
|
|
84
138
|
params: result.params,
|
|
85
139
|
isPartial: true,
|
|
86
140
|
slots: result.slots,
|
|
87
141
|
handles: handleStore.stream(),
|
|
88
142
|
version: ctx.version,
|
|
89
143
|
prefetchCacheTTL: ctx.router.prefetchCacheTTL,
|
|
144
|
+
stateCookieName: ctx.router.resolvedStateCookieName,
|
|
90
145
|
},
|
|
91
146
|
};
|
|
92
147
|
}
|
|
@@ -133,27 +188,7 @@ export async function handleRscRendering<TEnv>(
|
|
|
133
188
|
{ headers: { "Content-Type": "application/json" } },
|
|
134
189
|
);
|
|
135
190
|
} else {
|
|
136
|
-
payload =
|
|
137
|
-
// Initial SSR can reconstruct the tree from segments + rootLayout,
|
|
138
|
-
// so we omit root to avoid sending the same structure twice.
|
|
139
|
-
|
|
140
|
-
metadata: {
|
|
141
|
-
pathname: url.pathname,
|
|
142
|
-
routerId: ctx.router.id,
|
|
143
|
-
basename: ctx.router.basename,
|
|
144
|
-
segments: match.segments,
|
|
145
|
-
matched: match.matched,
|
|
146
|
-
diff: match.diff,
|
|
147
|
-
params: match.params,
|
|
148
|
-
isPartial: false,
|
|
149
|
-
rootLayout: ctx.router.rootLayout,
|
|
150
|
-
handles: handleStore.stream(),
|
|
151
|
-
version: ctx.version,
|
|
152
|
-
prefetchCacheTTL: ctx.router.prefetchCacheTTL,
|
|
153
|
-
themeConfig: ctx.router.themeConfig,
|
|
154
|
-
initialTheme: reqCtx.theme,
|
|
155
|
-
},
|
|
156
|
-
};
|
|
191
|
+
payload = buildFullPayload(match);
|
|
157
192
|
}
|
|
158
193
|
}
|
|
159
194
|
|
|
@@ -161,15 +196,10 @@ export async function handleRscRendering<TEnv>(
|
|
|
161
196
|
// SSR (full page) requests ignore location state since there's no history.state
|
|
162
197
|
// to write to on a fresh page load.
|
|
163
198
|
if (isPartial && payload.metadata) {
|
|
164
|
-
|
|
165
|
-
if (locationState) {
|
|
166
|
-
payload.metadata.locationState =
|
|
167
|
-
resolveLocationStateEntries(locationState);
|
|
168
|
-
}
|
|
199
|
+
attachLocationStateIfPresent(payload);
|
|
169
200
|
}
|
|
170
201
|
|
|
171
202
|
const metricsStore = reqCtx._metricsStore;
|
|
172
|
-
const renderStart = performance.now();
|
|
173
203
|
|
|
174
204
|
// Serialize to RSC stream
|
|
175
205
|
const rscSerializeStart = performance.now();
|
|
@@ -187,22 +217,16 @@ export async function handleRscRendering<TEnv>(
|
|
|
187
217
|
rscSerializeDur,
|
|
188
218
|
);
|
|
189
219
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
// navigation or prefetch fetch(). We cannot rely on Accept alone since some
|
|
193
|
-
// browsers may send Accept: text/html for non-HTML requests.
|
|
194
|
-
const isRscRequest =
|
|
195
|
-
isPartial ||
|
|
196
|
-
(!request.headers.get("accept")?.includes("text/html") &&
|
|
197
|
-
!url.searchParams.has("__html")) ||
|
|
198
|
-
url.searchParams.has("__rsc");
|
|
199
|
-
|
|
200
|
-
if (isRscRequest) {
|
|
201
|
-
const renderDur = performance.now() - renderStart;
|
|
202
|
-
appendMetric(metricsStore, "render:total", renderStart, renderDur);
|
|
220
|
+
if (isRscRequest(request, url, isPartial)) {
|
|
221
|
+
// render:total is recorded by the observePhase wrapper around this function.
|
|
203
222
|
const rscHeaders: Record<string, string> = {
|
|
204
223
|
"content-type": "text/x-component;charset=utf-8",
|
|
205
224
|
vary: "accept, X-Rango-State, X-RSC-Router-Client-Path",
|
|
225
|
+
// Router identity, so the client can verify pre-decode (before importing
|
|
226
|
+
// chunks) that this content payload belongs to its app and refuse a
|
|
227
|
+
// foreign one (cache/proxy/bug). Control-only reload/redirect responses
|
|
228
|
+
// are deliberately NOT stamped. See browser/response-adapter.ts.
|
|
229
|
+
"X-RSC-Router-Id": ctx.router.id,
|
|
206
230
|
};
|
|
207
231
|
// Tell the client's prefetch cache to scope this response to its source
|
|
208
232
|
// URL (instead of the default source-agnostic wildcard). Intercept
|
|
@@ -236,16 +260,14 @@ export async function handleRscRendering<TEnv>(
|
|
|
236
260
|
metricsStore,
|
|
237
261
|
);
|
|
238
262
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const renderDur = performance.now() - renderStart;
|
|
248
|
-
appendMetric(metricsStore, "render:total", renderStart, renderDur);
|
|
263
|
+
// ssr-render-html metric + rango.ssr span from one boundary. render:total is
|
|
264
|
+
// recorded by the observePhase wrapper around this function.
|
|
265
|
+
const htmlStream = await observePhase(PHASES.ssr, () =>
|
|
266
|
+
ssrModule.renderHTML(rscStream, {
|
|
267
|
+
nonce,
|
|
268
|
+
streamMode,
|
|
269
|
+
}),
|
|
270
|
+
);
|
|
249
271
|
|
|
250
272
|
return createResponseWithMergedHeaders(htmlStream, {
|
|
251
273
|
headers: { "content-type": "text/html;charset=utf-8" },
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
createResponseWithMergedHeaders,
|
|
9
9
|
carryOverRedirectHeaders,
|
|
10
10
|
} from "./helpers.js";
|
|
11
|
+
import { isRedirectResponse } from "../response-utils.js";
|
|
11
12
|
|
|
12
13
|
// W3 -----------------------------------------------------------------------
|
|
13
14
|
|
|
@@ -18,16 +19,14 @@ import {
|
|
|
18
19
|
*/
|
|
19
20
|
export function extractRedirectResponse(value: unknown): Response | null {
|
|
20
21
|
if (!(value instanceof Response)) return null;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
return null;
|
|
22
|
+
if (!isRedirectResponse(value)) return null;
|
|
23
|
+
const location = value.headers.get("Location")!;
|
|
24
|
+
const redirect = createResponseWithMergedHeaders(null, {
|
|
25
|
+
status: value.status,
|
|
26
|
+
headers: { Location: location },
|
|
27
|
+
});
|
|
28
|
+
carryOverRedirectHeaders(value, redirect);
|
|
29
|
+
return redirect;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
/**
|
|
@@ -40,3 +39,17 @@ export function warnNonRedirectPeResponse(): void {
|
|
|
40
39
|
`ignored — the page will re-render at the current URL instead.`,
|
|
41
40
|
);
|
|
42
41
|
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Warn when a non-redirect Response is returned (not thrown) from an action
|
|
45
|
+
* on the JS (fetch) path. A raw Response cannot be serialized into Flight, so
|
|
46
|
+
* it is discarded — mirroring the PE path. Use `throw redirect('/path')` for
|
|
47
|
+
* redirects.
|
|
48
|
+
*/
|
|
49
|
+
export function warnNonRedirectActionResponse(actionId: string): void {
|
|
50
|
+
console.warn(
|
|
51
|
+
`[@rangojs/router] Server action "${actionId}" returned a Response ` +
|
|
52
|
+
`that is not a redirect. Non-redirect Responses cannot be serialized ` +
|
|
53
|
+
`and are ignored. Use \`throw redirect('/path')\` for redirects.`,
|
|
54
|
+
);
|
|
55
|
+
}
|