@rangojs/router 0.0.0-experimental.31 → 0.0.0-experimental.3232cd17
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 +4 -0
- package/README.md +198 -44
- package/dist/bin/rango.js +287 -105
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3248 -1117
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +73 -21
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +107 -1
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +245 -21
- package/skills/caching/SKILL.md +302 -6
- package/skills/composability/SKILL.md +27 -2
- package/skills/css/SKILL.md +76 -0
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +270 -30
- package/skills/host-router/SKILL.md +82 -22
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +49 -5
- package/skills/layout/SKILL.md +35 -9
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +294 -30
- package/skills/middleware/SKILL.md +52 -13
- package/skills/migrate-nextjs/SKILL.md +584 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/mime-routes/SKILL.md +27 -0
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +203 -7
- package/skills/prerender/SKILL.md +123 -100
- package/skills/rango/SKILL.md +250 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +122 -47
- package/skills/route/SKILL.md +97 -5
- package/skills/router-setup/SKILL.md +90 -5
- 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 +89 -0
- package/skills/testing/cache-prerender.md +124 -0
- package/skills/testing/client-components.md +122 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +92 -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 +120 -0
- package/skills/typesafety/SKILL.md +329 -27
- package/skills/use-cache/SKILL.md +36 -5
- 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 +67 -40
- 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/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +86 -147
- 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/link-interceptor.ts +4 -0
- package/src/browser/navigation-bridge.ts +148 -19
- package/src/browser/navigation-client.ts +187 -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/partial-update.ts +123 -94
- package/src/browser/prefetch/cache.ts +214 -36
- package/src/browser/prefetch/fetch.ts +260 -38
- package/src/browser/prefetch/policy.ts +6 -0
- 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 +93 -11
- package/src/browser/react/NavigationProvider.tsx +115 -34
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +49 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +166 -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-link-status.ts +0 -4
- package/src/browser/react/use-navigation.ts +22 -5
- 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 +52 -1
- package/src/browser/rsc-router.tsx +215 -76
- package/src/browser/scroll-restoration.ts +46 -39
- package/src/browser/segment-reconciler.ts +36 -9
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +176 -50
- package/src/browser/types.ts +95 -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 -0
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +137 -32
- package/src/build/route-types/codegen.ts +4 -4
- package/src/build/route-types/include-resolution.ts +9 -2
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +7 -4
- package/src/build/route-types/router-processing.ts +278 -96
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +118 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-policy.ts +68 -28
- package/src/cache/cache-runtime.ts +149 -43
- package/src/cache/cache-scope.ts +148 -81
- package/src/cache/cache-tag.ts +98 -0
- package/src/cache/cf/cf-cache-store.ts +2550 -93
- package/src/cache/cf/index.ts +11 -17
- package/src/cache/document-cache.ts +78 -27
- package/src/cache/handle-snapshot.ts +63 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +6 -30
- package/src/cache/read-through-swr.ts +41 -11
- package/src/cache/segment-codec.ts +0 -16
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +55 -0
- package/src/cache/types.ts +33 -100
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +799 -0
- package/src/client.rsc.tsx +6 -21
- package/src/client.tsx +108 -290
- package/src/component-utils.ts +19 -0
- package/src/context-var.ts +84 -2
- package/src/debug.ts +2 -2
- package/src/decode-loader-results.ts +36 -0
- package/src/defer.ts +196 -0
- package/src/deps/ssr.ts +0 -1
- package/src/errors.ts +30 -4
- package/src/handle.ts +70 -22
- package/src/handles/MetaTags.tsx +0 -14
- package/src/handles/breadcrumbs.ts +16 -5
- package/src/handles/meta.ts +0 -39
- package/src/host/cookie-handler.ts +0 -36
- package/src/host/errors.ts +0 -24
- package/src/host/index.ts +8 -2
- package/src/host/pattern-matcher.ts +7 -50
- 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 +52 -26
- package/src/index.ts +100 -38
- package/src/internal-debug.ts +2 -4
- 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/network-error-thrower.tsx +1 -6
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +10 -11
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +198 -82
- package/src/redirect-origin.ts +100 -0
- package/src/response-utils.ts +37 -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 +437 -274
- 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 +52 -10
- 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 +108 -9
- package/src/router/error-handling.ts +13 -17
- package/src/router/find-match.ts +45 -22
- package/src/router/handler-context.ts +83 -41
- package/src/router/intercept-resolution.ts +25 -23
- package/src/router/lazy-includes.ts +19 -53
- package/src/router/loader-resolution.ts +213 -30
- package/src/router/logging.ts +5 -8
- package/src/router/manifest.ts +49 -45
- package/src/router/match-api.ts +121 -205
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- package/src/router/match-middleware/background-revalidation.ts +27 -6
- package/src/router/match-middleware/cache-lookup.ts +205 -249
- package/src/router/match-middleware/cache-store.ts +45 -32
- 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 +173 -143
- package/src/router/navigation-snapshot.ts +131 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +109 -63
- package/src/router/prerender-match.ts +192 -54
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +276 -0
- package/src/router/revalidation.ts +63 -55
- package/src/router/route-snapshot.ts +244 -0
- package/src/router/router-context.ts +6 -28
- package/src/router/router-interfaces.ts +100 -35
- package/src/router/router-options.ts +91 -11
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +242 -75
- package/src/router/segment-resolution/helpers.ts +64 -25
- package/src/router/segment-resolution/loader-cache.ts +41 -37
- package/src/router/segment-resolution/revalidation.ts +456 -372
- 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 +4 -1
- package/src/router/segment-wrappers.ts +2 -3
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +0 -20
- package/src/router/telemetry.ts +96 -19
- package/src/router/timeout.ts +0 -20
- package/src/router/trie-matching.ts +91 -46
- package/src/router/types.ts +10 -63
- package/src/router/url-params.ts +44 -0
- package/src/router.ts +134 -43
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +492 -383
- package/src/rsc/helpers.ts +162 -46
- package/src/rsc/index.ts +1 -1
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +23 -3
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +30 -3
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +90 -63
- package/src/rsc/rsc-rendering.ts +56 -54
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +74 -67
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/types.ts +25 -6
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +4 -20
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +134 -0
- package/src/segment-system.tsx +272 -129
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +309 -61
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +26 -24
- package/src/server/loader-registry.ts +10 -28
- package/src/server/request-context.ts +348 -128
- package/src/ssr/index.tsx +23 -15
- 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 +618 -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 +232 -0
- package/src/testing/generated-routes.ts +183 -0
- package/src/testing/index.ts +99 -0
- package/src/testing/internal/context.ts +348 -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 +330 -0
- package/src/testing/render-route.tsx +566 -0
- package/src/testing/run-loader.ts +378 -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 +0 -52
- package/src/theme/ThemeScript.tsx +0 -6
- package/src/theme/constants.ts +0 -12
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +0 -14
- 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 +107 -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 +192 -99
- 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 +51 -6
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +8 -0
- package/src/vite/plugin-types.ts +187 -69
- package/src/vite/plugins/cjs-to-esm.ts +8 -18
- 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 +11 -50
- package/src/vite/plugins/expose-ids/export-analysis.ts +76 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +10 -48
- package/src/vite/plugins/expose-ids/loader-transform.ts +3 -20
- package/src/vite/plugins/expose-ids/router-transform.ts +20 -16
- package/src/vite/plugins/expose-internal-ids.ts +554 -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/vercel-output.ts +258 -0
- package/src/vite/plugins/version-injector.ts +21 -25
- package/src/vite/plugins/version-plugin.ts +41 -20
- package/src/vite/plugins/virtual-entries.ts +2 -17
- package/src/vite/rango.ts +257 -289
- package/src/vite/router-discovery.ts +930 -140
- package/src/vite/utils/ast-handler-extract.ts +15 -31
- 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/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 +27 -29
- 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/router/middleware-cookies.ts +0 -55
|
@@ -10,7 +10,12 @@ import type { ReactNode } from "react";
|
|
|
10
10
|
import { invariant } from "../../errors";
|
|
11
11
|
import { revalidate } from "../loader-resolution.js";
|
|
12
12
|
import { evaluateRevalidation } from "../revalidation.js";
|
|
13
|
-
import
|
|
13
|
+
import {
|
|
14
|
+
getParallelEntries,
|
|
15
|
+
getParallelSlotEntries,
|
|
16
|
+
type EntryData,
|
|
17
|
+
type ParallelEntryData,
|
|
18
|
+
} from "../../server/context";
|
|
14
19
|
import type {
|
|
15
20
|
HandlerContext,
|
|
16
21
|
InternalHandlerContext,
|
|
@@ -30,54 +35,40 @@ import {
|
|
|
30
35
|
import { resolveLoaderData } from "./loader-cache.js";
|
|
31
36
|
import {
|
|
32
37
|
handleHandlerResult,
|
|
38
|
+
warnOnStreamedResponse,
|
|
33
39
|
tryStaticHandler,
|
|
34
40
|
tryStaticSlot,
|
|
35
41
|
resolveLayoutComponent,
|
|
36
42
|
resolveWithErrorBoundary,
|
|
37
43
|
} from "./helpers.js";
|
|
44
|
+
import { applyViewTransitionDefault } from "./view-transition-default.js";
|
|
38
45
|
import { getRouterContext } from "../router-context.js";
|
|
39
46
|
import { resolveSink, safeEmit } from "../telemetry.js";
|
|
40
|
-
import {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
import { observeStreamedHandler } from "./streamed-handler-telemetry.js";
|
|
48
|
+
import {
|
|
49
|
+
track,
|
|
50
|
+
RangoContext,
|
|
51
|
+
runInsideLoaderScope,
|
|
52
|
+
} from "../../server/context.js";
|
|
45
53
|
|
|
46
54
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
55
|
+
* Trace a parallel slot that's being force-rendered on a full refetch (client
|
|
56
|
+
* has no cached state). User revalidate fns are bypassed in this case — see
|
|
57
|
+
* the call sites for the load-bearing rationale.
|
|
49
58
|
*/
|
|
50
|
-
function
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
segmentType: string,
|
|
54
|
-
pathname?: string,
|
|
55
|
-
routeKey?: string,
|
|
56
|
-
params?: Record<string, string>,
|
|
59
|
+
function traceFullRefetchedParallelSlot(
|
|
60
|
+
parallelId: string,
|
|
61
|
+
belongsToRoute: boolean,
|
|
57
62
|
): void {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
promise.catch((err: unknown) => {
|
|
68
|
-
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
69
|
-
safeEmit(sink, {
|
|
70
|
-
type: "handler.error",
|
|
71
|
-
timestamp: performance.now(),
|
|
72
|
-
requestId: reqId,
|
|
73
|
-
segmentId,
|
|
74
|
-
segmentType,
|
|
75
|
-
error: errorObj,
|
|
76
|
-
handledByBoundary: true,
|
|
77
|
-
pathname,
|
|
78
|
-
routeKey,
|
|
79
|
-
params,
|
|
80
|
-
});
|
|
63
|
+
if (!isTraceActive()) return;
|
|
64
|
+
pushRevalidationTraceEntry({
|
|
65
|
+
segmentId: parallelId,
|
|
66
|
+
segmentType: "parallel",
|
|
67
|
+
belongsToRoute,
|
|
68
|
+
source: "parallel",
|
|
69
|
+
defaultShouldRevalidate: true,
|
|
70
|
+
finalShouldRevalidate: true,
|
|
71
|
+
reason: "full-refetch",
|
|
81
72
|
});
|
|
82
73
|
}
|
|
83
74
|
|
|
@@ -228,7 +219,9 @@ export async function resolveLoadersWithRevalidation<TEnv>(
|
|
|
228
219
|
params: ctx.params,
|
|
229
220
|
loaderId: loader.$$id,
|
|
230
221
|
loaderData: deps.wrapLoaderPromise(
|
|
231
|
-
|
|
222
|
+
runInsideLoaderScope(() =>
|
|
223
|
+
resolveLoaderData(loaderEntry, ctx, ctx.pathname),
|
|
224
|
+
),
|
|
232
225
|
entry,
|
|
233
226
|
segmentId,
|
|
234
227
|
ctx.pathname,
|
|
@@ -258,26 +251,95 @@ export async function resolveLoadersOnlyWithRevalidation<TEnv>(
|
|
|
258
251
|
): Promise<{ segments: ResolvedSegment[]; matchedIds: string[] }> {
|
|
259
252
|
const allLoaderSegments: ResolvedSegment[] = [];
|
|
260
253
|
const allMatchedIds: string[] = [];
|
|
254
|
+
const seenIds = new Set<string>();
|
|
255
|
+
|
|
256
|
+
async function collectEntryLoaders(
|
|
257
|
+
entry: EntryData,
|
|
258
|
+
belongsToRoute: boolean,
|
|
259
|
+
shortCodeOverride?: string,
|
|
260
|
+
): Promise<void> {
|
|
261
|
+
// Skip if all loaders from this entry have already been resolved
|
|
262
|
+
// via a parent (e.g., cache boundary wrapping a layout with shared loaders).
|
|
263
|
+
const loaderEntries = entry.loader ?? [];
|
|
264
|
+
const sc = shortCodeOverride ?? entry.shortCode;
|
|
265
|
+
const allAlreadySeen =
|
|
266
|
+
loaderEntries.length > 0 &&
|
|
267
|
+
loaderEntries.every((le, i) =>
|
|
268
|
+
seenIds.has(`${sc}D${i}.${le.loader.$$id}`),
|
|
269
|
+
);
|
|
270
|
+
if (!allAlreadySeen) {
|
|
271
|
+
const { segments, matchedIds } = await resolveLoadersWithRevalidation(
|
|
272
|
+
entry,
|
|
273
|
+
context,
|
|
274
|
+
belongsToRoute,
|
|
275
|
+
clientSegmentIds,
|
|
276
|
+
prevParams,
|
|
277
|
+
request,
|
|
278
|
+
prevUrl,
|
|
279
|
+
nextUrl,
|
|
280
|
+
routeKey,
|
|
281
|
+
deps,
|
|
282
|
+
actionContext,
|
|
283
|
+
shortCodeOverride,
|
|
284
|
+
stale,
|
|
285
|
+
);
|
|
286
|
+
for (const seg of segments) {
|
|
287
|
+
if (!seenIds.has(seg.id)) {
|
|
288
|
+
seenIds.add(seg.id);
|
|
289
|
+
allLoaderSegments.push(seg);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
allMatchedIds.push(...matchedIds);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const seenParallelEntryIds = new Set<string>();
|
|
296
|
+
for (const parallelEntry of getParallelEntries(entry.parallel)) {
|
|
297
|
+
if (seenParallelEntryIds.has(parallelEntry.id)) continue;
|
|
298
|
+
seenParallelEntryIds.add(parallelEntry.id);
|
|
299
|
+
await collectEntryLoaders(parallelEntry, belongsToRoute, entry.shortCode);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const childBelongsToRoute = belongsToRoute || entry.type === "route";
|
|
303
|
+
for (const layoutEntry of entry.layout) {
|
|
304
|
+
await collectEntryLoaders(layoutEntry, childBelongsToRoute);
|
|
305
|
+
// Inherit route loaders for orphan layouts with parallels.
|
|
306
|
+
// Resolve directly — do NOT re-enter collectEntryLoaders with the
|
|
307
|
+
// route entry, as that would re-iterate route.layout and loop.
|
|
308
|
+
if (
|
|
309
|
+
entry.type === "route" &&
|
|
310
|
+
entry.loader &&
|
|
311
|
+
entry.loader.length > 0 &&
|
|
312
|
+
Object.keys(layoutEntry.parallel).length > 0
|
|
313
|
+
) {
|
|
314
|
+
const inherited = await resolveLoadersWithRevalidation(
|
|
315
|
+
entry,
|
|
316
|
+
context,
|
|
317
|
+
childBelongsToRoute,
|
|
318
|
+
clientSegmentIds,
|
|
319
|
+
prevParams,
|
|
320
|
+
request,
|
|
321
|
+
prevUrl,
|
|
322
|
+
nextUrl,
|
|
323
|
+
routeKey,
|
|
324
|
+
deps,
|
|
325
|
+
actionContext,
|
|
326
|
+
layoutEntry.shortCode,
|
|
327
|
+
stale,
|
|
328
|
+
);
|
|
329
|
+
for (const seg of inherited.segments) {
|
|
330
|
+
if (!seenIds.has(seg.id)) {
|
|
331
|
+
seenIds.add(seg.id);
|
|
332
|
+
seg._inherited = true;
|
|
333
|
+
allLoaderSegments.push(seg);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
allMatchedIds.push(...inherited.matchedIds);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
261
340
|
|
|
262
341
|
for (const entry of entries) {
|
|
263
|
-
|
|
264
|
-
const { segments, matchedIds } = await resolveLoadersWithRevalidation(
|
|
265
|
-
entry,
|
|
266
|
-
context,
|
|
267
|
-
belongsToRoute,
|
|
268
|
-
clientSegmentIds,
|
|
269
|
-
prevParams,
|
|
270
|
-
request,
|
|
271
|
-
prevUrl,
|
|
272
|
-
nextUrl,
|
|
273
|
-
routeKey,
|
|
274
|
-
deps,
|
|
275
|
-
actionContext,
|
|
276
|
-
undefined, // shortCodeOverride
|
|
277
|
-
stale,
|
|
278
|
-
);
|
|
279
|
-
allLoaderSegments.push(...segments);
|
|
280
|
-
allMatchedIds.push(...matchedIds);
|
|
342
|
+
await collectEntryLoaders(entry, entry.type === "route");
|
|
281
343
|
}
|
|
282
344
|
|
|
283
345
|
return { segments: allLoaderSegments, matchedIds: allMatchedIds };
|
|
@@ -301,22 +363,20 @@ export function buildEntryRevalidateMap(
|
|
|
301
363
|
map.set(entry.shortCode, { entry, revalidate: entry.revalidate });
|
|
302
364
|
|
|
303
365
|
if (entry.type !== "parallel") {
|
|
304
|
-
for (const parallelEntry of
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
}
|
|
314
|
-
}
|
|
366
|
+
for (const { slot, entry: parallelEntry } of getParallelSlotEntries(
|
|
367
|
+
entry.parallel,
|
|
368
|
+
)) {
|
|
369
|
+
const parallelParentShortCode = parentShortCode ?? entry.shortCode;
|
|
370
|
+
const parallelId = `${parallelParentShortCode}.${slot}`;
|
|
371
|
+
map.set(parallelId, {
|
|
372
|
+
entry: parallelEntry,
|
|
373
|
+
revalidate: parallelEntry.revalidate,
|
|
374
|
+
});
|
|
315
375
|
}
|
|
316
376
|
}
|
|
317
377
|
|
|
318
378
|
for (const layoutEntry of entry.layout) {
|
|
319
|
-
processEntry(layoutEntry);
|
|
379
|
+
processEntry(layoutEntry, entry.shortCode);
|
|
320
380
|
}
|
|
321
381
|
}
|
|
322
382
|
|
|
@@ -327,6 +387,97 @@ export function buildEntryRevalidateMap(
|
|
|
327
387
|
return map;
|
|
328
388
|
}
|
|
329
389
|
|
|
390
|
+
/**
|
|
391
|
+
* Resolve the component for a single parallel slot on the revalidation path.
|
|
392
|
+
* Pure component resolution shared verbatim by
|
|
393
|
+
* resolveParallelSegmentsWithRevalidation and the orphan-inlined loop in
|
|
394
|
+
* resolveOrphanLayoutWithRevalidation: try the static slot cache, else run the
|
|
395
|
+
* slot handler (pinning _currentSegmentId to the slot id so handle pushes land
|
|
396
|
+
* in the slot's own bucket, and wrapping a streamed handler). Returns the
|
|
397
|
+
* resolved component and whether the handler actually ran. Does NOT touch the
|
|
398
|
+
* revalidate-default policy (the caller decides shouldResolve, including the
|
|
399
|
+
* orphan-vs-main defaultOverride divergence) or loader-resolution ordering.
|
|
400
|
+
*/
|
|
401
|
+
async function resolveParallelSlotComponent<TEnv>(args: {
|
|
402
|
+
shouldResolve: boolean;
|
|
403
|
+
parallelEntry: ParallelEntryData;
|
|
404
|
+
slot: string;
|
|
405
|
+
parallelId: string;
|
|
406
|
+
handler:
|
|
407
|
+
| ((ctx: HandlerContext<any, TEnv>) => ReactNode | Promise<ReactNode>)
|
|
408
|
+
| ReactNode
|
|
409
|
+
| undefined;
|
|
410
|
+
context: HandlerContext<any, TEnv>;
|
|
411
|
+
deps: SegmentResolutionDeps<TEnv>;
|
|
412
|
+
routeKey: string;
|
|
413
|
+
params: Record<string, string>;
|
|
414
|
+
}): Promise<{ component: ReactNode | undefined; handlerRan: boolean }> {
|
|
415
|
+
const {
|
|
416
|
+
shouldResolve,
|
|
417
|
+
parallelEntry,
|
|
418
|
+
slot,
|
|
419
|
+
parallelId,
|
|
420
|
+
handler,
|
|
421
|
+
context,
|
|
422
|
+
deps,
|
|
423
|
+
routeKey,
|
|
424
|
+
params,
|
|
425
|
+
} = args;
|
|
426
|
+
|
|
427
|
+
let component: ReactNode | undefined;
|
|
428
|
+
let handlerRan = false;
|
|
429
|
+
if (shouldResolve) {
|
|
430
|
+
component = await tryStaticSlot(parallelEntry, slot, parallelId);
|
|
431
|
+
// tryStaticSlot returning a value means the static cache supplied the
|
|
432
|
+
// component — handler did NOT run. handlerRan stays false.
|
|
433
|
+
}
|
|
434
|
+
if (component === undefined) {
|
|
435
|
+
const hasLoadingFallback =
|
|
436
|
+
parallelEntry.loading !== undefined && parallelEntry.loading !== false;
|
|
437
|
+
if (!shouldResolve) {
|
|
438
|
+
component = null;
|
|
439
|
+
} else if (handler === undefined) {
|
|
440
|
+
// Handler evicted (production static slot) but static lookup missed.
|
|
441
|
+
// Nothing to render — use null so the client keeps its cached version.
|
|
442
|
+
component = null;
|
|
443
|
+
} else {
|
|
444
|
+
// Slot-keyed pushes — slot owns its own bucket, parent layout owns its
|
|
445
|
+
// own. On slot-only revalidations the partial merge updates only the
|
|
446
|
+
// slot's bucket; the parent's bucket stays intact.
|
|
447
|
+
(context as InternalHandlerContext<any, TEnv>)._currentSegmentId =
|
|
448
|
+
parallelId;
|
|
449
|
+
handlerRan = true;
|
|
450
|
+
if (hasLoadingFallback) {
|
|
451
|
+
const result =
|
|
452
|
+
typeof handler === "function" ? handler(context) : handler;
|
|
453
|
+
if (result instanceof Promise) {
|
|
454
|
+
warnOnStreamedResponse(result, parallelId);
|
|
455
|
+
const tracked = deps.trackHandler(result, {
|
|
456
|
+
segmentId: parallelId,
|
|
457
|
+
segmentType: "parallel",
|
|
458
|
+
});
|
|
459
|
+
observeStreamedHandler(
|
|
460
|
+
tracked,
|
|
461
|
+
parallelId,
|
|
462
|
+
"parallel",
|
|
463
|
+
context.pathname,
|
|
464
|
+
routeKey,
|
|
465
|
+
params,
|
|
466
|
+
);
|
|
467
|
+
component = tracked as ReactNode;
|
|
468
|
+
} else {
|
|
469
|
+
component = result as ReactNode;
|
|
470
|
+
}
|
|
471
|
+
} else {
|
|
472
|
+
component =
|
|
473
|
+
typeof handler === "function" ? await handler(context) : handler;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
return { component, handlerRan };
|
|
479
|
+
}
|
|
480
|
+
|
|
330
481
|
/**
|
|
331
482
|
* Resolve parallel segments with revalidation.
|
|
332
483
|
*/
|
|
@@ -344,11 +495,35 @@ export async function resolveParallelSegmentsWithRevalidation<TEnv>(
|
|
|
344
495
|
deps: SegmentResolutionDeps<TEnv>,
|
|
345
496
|
actionContext?: ActionContext,
|
|
346
497
|
stale?: boolean,
|
|
498
|
+
options?: {
|
|
499
|
+
/**
|
|
500
|
+
* Seed for an unknown parent-chain slot (slot not in clientSegmentIds) when
|
|
501
|
+
* there are no deciding revalidate fns. "type-derived" (default, main path):
|
|
502
|
+
* `belongsToRoute || isNewParent`. "force-render" (orphan path): always
|
|
503
|
+
* `true` — orphan parallels always belong to the route and must render
|
|
504
|
+
* unless the user opts out via revalidate(); the #482 blank-parent-chain-
|
|
505
|
+
* slot guard.
|
|
506
|
+
*/
|
|
507
|
+
parentChainDefault?: "type-derived" | "force-render";
|
|
508
|
+
/**
|
|
509
|
+
* When a slot's loaders are resolved relative to the slot segment push.
|
|
510
|
+
* "after" (default, main path) pushes the slot segment first; "before"
|
|
511
|
+
* (orphan path) resolves loaders first. This only changes the
|
|
512
|
+
* segments/matchedIds emission ORDER (the client reconciler is insensitive
|
|
513
|
+
* to it: loader sub-ids are filtered out and slots are re-grouped by parent).
|
|
514
|
+
*/
|
|
515
|
+
loaderOrder?: "after" | "before";
|
|
516
|
+
},
|
|
347
517
|
): Promise<SegmentRevalidationResult> {
|
|
348
518
|
const segments: ResolvedSegment[] = [];
|
|
349
519
|
const matchedIds: string[] = [];
|
|
520
|
+
const parentChainDefault = options?.parentChainDefault ?? "type-derived";
|
|
521
|
+
const loaderOrder = options?.loaderOrder ?? "after";
|
|
350
522
|
|
|
351
|
-
|
|
523
|
+
const resolvedParallelEntries = new Set<string>();
|
|
524
|
+
for (const { slot, entry: parallelEntry } of getParallelSlotEntries(
|
|
525
|
+
entry.parallel,
|
|
526
|
+
)) {
|
|
352
527
|
invariant(
|
|
353
528
|
parallelEntry.type === "parallel",
|
|
354
529
|
`Expected parallel entry, got: ${parallelEntry.type}`,
|
|
@@ -359,141 +534,78 @@ export async function resolveParallelSegmentsWithRevalidation<TEnv>(
|
|
|
359
534
|
| ((ctx: HandlerContext<any, TEnv>) => ReactNode | Promise<ReactNode>)
|
|
360
535
|
| ReactNode
|
|
361
536
|
>;
|
|
537
|
+
// In production, static handler bodies are evicted and the slot value
|
|
538
|
+
// may be undefined. The static store holds the pre-rendered component.
|
|
539
|
+
// We defer the handler check until after tryStaticSlot.
|
|
540
|
+
const handler = slots[slot];
|
|
362
541
|
|
|
363
|
-
|
|
364
|
-
const parallelId = `${entry.shortCode}.${slot}`;
|
|
365
|
-
|
|
366
|
-
const isFullRefetch = clientSegmentIds.size === 0;
|
|
367
|
-
// When the parent layout is new (not in client's segment set),
|
|
368
|
-
// all its parallel children must be resolved and tracked.
|
|
369
|
-
// Without this, navigating to a new layout with parallels
|
|
370
|
-
// (e.g., BlogLayout with @sidebar) from a different route
|
|
371
|
-
// would silently drop those parallel segments.
|
|
372
|
-
const isNewParent = !clientSegmentIds.has(entry.shortCode);
|
|
373
|
-
if (
|
|
374
|
-
isFullRefetch ||
|
|
375
|
-
clientSegmentIds.has(parallelId) ||
|
|
376
|
-
belongsToRoute ||
|
|
377
|
-
isNewParent
|
|
378
|
-
) {
|
|
379
|
-
matchedIds.push(parallelId);
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
const shouldResolve = await (async () => {
|
|
383
|
-
if (isFullRefetch) {
|
|
384
|
-
if (isTraceActive()) {
|
|
385
|
-
pushRevalidationTraceEntry({
|
|
386
|
-
segmentId: parallelId,
|
|
387
|
-
segmentType: "parallel",
|
|
388
|
-
belongsToRoute,
|
|
389
|
-
source: "parallel",
|
|
390
|
-
defaultShouldRevalidate: true,
|
|
391
|
-
finalShouldRevalidate: true,
|
|
392
|
-
reason: "full-refetch",
|
|
393
|
-
});
|
|
394
|
-
}
|
|
395
|
-
return true;
|
|
396
|
-
}
|
|
397
|
-
if (!clientSegmentIds.has(parallelId)) {
|
|
398
|
-
const result = belongsToRoute || isNewParent;
|
|
399
|
-
if (isTraceActive()) {
|
|
400
|
-
pushRevalidationTraceEntry({
|
|
401
|
-
segmentId: parallelId,
|
|
402
|
-
segmentType: "parallel",
|
|
403
|
-
belongsToRoute,
|
|
404
|
-
source: "parallel",
|
|
405
|
-
defaultShouldRevalidate: result,
|
|
406
|
-
finalShouldRevalidate: result,
|
|
407
|
-
reason: result ? "new-segment" : "skip-parent-chain",
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
return result;
|
|
411
|
-
}
|
|
542
|
+
const parallelId = `${entry.shortCode}.${slot}`;
|
|
412
543
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
namespace: parallelEntry.id,
|
|
416
|
-
type: "parallel",
|
|
417
|
-
index: 0,
|
|
418
|
-
component: null as any,
|
|
419
|
-
params,
|
|
420
|
-
slot,
|
|
421
|
-
belongsToRoute,
|
|
422
|
-
parallelName: `${parallelEntry.id}.${slot}`,
|
|
423
|
-
...(parallelEntry.mountPath
|
|
424
|
-
? { mountPath: parallelEntry.mountPath }
|
|
425
|
-
: {}),
|
|
426
|
-
};
|
|
544
|
+
const isFullRefetch = clientSegmentIds.size === 0;
|
|
545
|
+
const isNewParent = !clientSegmentIds.has(entry.shortCode);
|
|
427
546
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
actionContext,
|
|
442
|
-
stale,
|
|
443
|
-
traceSource: "parallel",
|
|
444
|
-
});
|
|
445
|
-
})();
|
|
446
|
-
emitRevalidationDecision(
|
|
447
|
-
parallelId,
|
|
448
|
-
context.pathname,
|
|
547
|
+
// A slot's loaders (never cached) are deduped per parallel entry and
|
|
548
|
+
// emitted either before or after the slot segment per loaderOrder.
|
|
549
|
+
const resolveSlotLoaders = async () => {
|
|
550
|
+
if (resolvedParallelEntries.has(parallelEntry.id)) return;
|
|
551
|
+
const loaderResult = await resolveLoadersWithRevalidation(
|
|
552
|
+
parallelEntry,
|
|
553
|
+
context,
|
|
554
|
+
belongsToRoute,
|
|
555
|
+
clientSegmentIds,
|
|
556
|
+
prevParams,
|
|
557
|
+
request,
|
|
558
|
+
prevUrl,
|
|
559
|
+
nextUrl,
|
|
449
560
|
routeKey,
|
|
450
|
-
|
|
561
|
+
deps,
|
|
562
|
+
actionContext,
|
|
563
|
+
entry.shortCode,
|
|
564
|
+
stale,
|
|
451
565
|
);
|
|
566
|
+
segments.push(...loaderResult.segments);
|
|
567
|
+
matchedIds.push(...loaderResult.matchedIds);
|
|
568
|
+
resolvedParallelEntries.add(parallelEntry.id);
|
|
569
|
+
};
|
|
452
570
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
} else {
|
|
484
|
-
component =
|
|
485
|
-
typeof handler === "function" ? await handler(context) : handler;
|
|
486
|
-
}
|
|
571
|
+
if (loaderOrder === "before") {
|
|
572
|
+
await resolveSlotLoaders();
|
|
573
|
+
}
|
|
574
|
+
// Always announce the slot in matchedIds — it's unconditionally appended
|
|
575
|
+
// to `segments` below, and a segment present in segments but missing from
|
|
576
|
+
// matched lets the client prune it (then it's missing from clientSegmentIds
|
|
577
|
+
// on the next request, perpetuating the staleness).
|
|
578
|
+
matchedIds.push(parallelId);
|
|
579
|
+
|
|
580
|
+
let shouldResolve: boolean;
|
|
581
|
+
if (isFullRefetch) {
|
|
582
|
+
// Client has nothing cached — slot MUST render. User revalidate fns are
|
|
583
|
+
// bypassed here because returning false would leave the segment blank
|
|
584
|
+
// with no client-side fallback.
|
|
585
|
+
traceFullRefetchedParallelSlot(parallelId, belongsToRoute);
|
|
586
|
+
shouldResolve = true;
|
|
587
|
+
} else {
|
|
588
|
+
// For non-empty client sets, consult user revalidate fns. When the slot
|
|
589
|
+
// is unknown to the client, override the type-derived default so the
|
|
590
|
+
// soft chain seeds with the right "new segment" / "parent-chain" value.
|
|
591
|
+
let defaultOverride: { value: boolean; reason: string } | undefined;
|
|
592
|
+
if (!clientSegmentIds.has(parallelId)) {
|
|
593
|
+
const value =
|
|
594
|
+
parentChainDefault === "force-render"
|
|
595
|
+
? true
|
|
596
|
+
: belongsToRoute || isNewParent;
|
|
597
|
+
defaultOverride = {
|
|
598
|
+
value,
|
|
599
|
+
reason: value ? "new-segment" : "skip-parent-chain",
|
|
600
|
+
};
|
|
487
601
|
}
|
|
488
602
|
|
|
489
|
-
|
|
603
|
+
const dummySegment: ResolvedSegment = {
|
|
490
604
|
id: parallelId,
|
|
491
605
|
namespace: parallelEntry.id,
|
|
492
606
|
type: "parallel",
|
|
493
607
|
index: 0,
|
|
494
|
-
component,
|
|
495
|
-
loading: parallelEntry.loading === false ? null : parallelEntry.loading,
|
|
496
|
-
transition: parallelEntry.transition,
|
|
608
|
+
component: null as any,
|
|
497
609
|
params,
|
|
498
610
|
slot,
|
|
499
611
|
belongsToRoute,
|
|
@@ -501,27 +613,69 @@ export async function resolveParallelSegmentsWithRevalidation<TEnv>(
|
|
|
501
613
|
...(parallelEntry.mountPath
|
|
502
614
|
? { mountPath: parallelEntry.mountPath }
|
|
503
615
|
: {}),
|
|
504
|
-
}
|
|
505
|
-
}
|
|
616
|
+
};
|
|
506
617
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
parallelEntry,
|
|
510
|
-
context,
|
|
511
|
-
belongsToRoute,
|
|
512
|
-
clientSegmentIds,
|
|
618
|
+
shouldResolve = await evaluateRevalidation({
|
|
619
|
+
segment: dummySegment,
|
|
513
620
|
prevParams,
|
|
621
|
+
getPrevSegment: null,
|
|
514
622
|
request,
|
|
515
623
|
prevUrl,
|
|
516
624
|
nextUrl,
|
|
625
|
+
revalidations: parallelEntry.revalidate.map((fn, i) => ({
|
|
626
|
+
name: `revalidate${i}`,
|
|
627
|
+
fn,
|
|
628
|
+
})),
|
|
517
629
|
routeKey,
|
|
518
|
-
|
|
630
|
+
context,
|
|
519
631
|
actionContext,
|
|
520
|
-
entry.shortCode,
|
|
521
632
|
stale,
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
633
|
+
traceSource: "parallel",
|
|
634
|
+
defaultOverride,
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
emitRevalidationDecision(
|
|
638
|
+
parallelId,
|
|
639
|
+
context.pathname,
|
|
640
|
+
routeKey,
|
|
641
|
+
shouldResolve,
|
|
642
|
+
);
|
|
643
|
+
|
|
644
|
+
const { component, handlerRan } = await resolveParallelSlotComponent({
|
|
645
|
+
shouldResolve,
|
|
646
|
+
parallelEntry,
|
|
647
|
+
slot,
|
|
648
|
+
parallelId,
|
|
649
|
+
handler,
|
|
650
|
+
context,
|
|
651
|
+
deps,
|
|
652
|
+
routeKey,
|
|
653
|
+
params,
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
segments.push({
|
|
657
|
+
id: parallelId,
|
|
658
|
+
namespace: parallelEntry.id,
|
|
659
|
+
type: "parallel",
|
|
660
|
+
index: 0,
|
|
661
|
+
component,
|
|
662
|
+
loading: parallelEntry.loading === false ? null : parallelEntry.loading,
|
|
663
|
+
transition: applyViewTransitionDefault(
|
|
664
|
+
parallelEntry.transition,
|
|
665
|
+
deps.viewTransitionDefault,
|
|
666
|
+
),
|
|
667
|
+
params,
|
|
668
|
+
slot,
|
|
669
|
+
_handlerRan: handlerRan,
|
|
670
|
+
belongsToRoute,
|
|
671
|
+
parallelName: `${parallelEntry.id}.${slot}`,
|
|
672
|
+
...(parallelEntry.mountPath
|
|
673
|
+
? { mountPath: parallelEntry.mountPath }
|
|
674
|
+
: {}),
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
if (loaderOrder === "after") {
|
|
678
|
+
await resolveSlotLoaders();
|
|
525
679
|
}
|
|
526
680
|
}
|
|
527
681
|
|
|
@@ -548,6 +702,7 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
|
|
|
548
702
|
): Promise<{ segment: ResolvedSegment; matchedId: string }> {
|
|
549
703
|
const matchedId = entry.shortCode;
|
|
550
704
|
|
|
705
|
+
let handlerRan = false;
|
|
551
706
|
const component = await revalidate(
|
|
552
707
|
async () => {
|
|
553
708
|
const hasSegment = clientSegmentIds.has(entry.shortCode);
|
|
@@ -608,6 +763,8 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
|
|
|
608
763
|
context,
|
|
609
764
|
actionContext,
|
|
610
765
|
stale,
|
|
766
|
+
traceSource:
|
|
767
|
+
entry.type === "route" ? "route-handler" : "layout-handler",
|
|
611
768
|
});
|
|
612
769
|
emitRevalidationDecision(
|
|
613
770
|
entry.shortCode,
|
|
@@ -622,6 +779,7 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
|
|
|
622
779
|
return shouldRevalidate;
|
|
623
780
|
},
|
|
624
781
|
async () => {
|
|
782
|
+
handlerRan = true;
|
|
625
783
|
const doneHandler = track(`handler:${entry.id}`, 2);
|
|
626
784
|
(context as InternalHandlerContext<any, TEnv>)._currentSegmentId =
|
|
627
785
|
entry.shortCode;
|
|
@@ -636,14 +794,22 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
|
|
|
636
794
|
return staticComponent;
|
|
637
795
|
}
|
|
638
796
|
const routeEntry = entry as Extract<EntryData, { type: "route" }>;
|
|
797
|
+
// For Passthrough routes at runtime, use the live handler instead of
|
|
798
|
+
// the build handler. At build time (context.build === true), always
|
|
799
|
+
// use the build handler from routeEntry.handler.
|
|
800
|
+
const handler =
|
|
801
|
+
!context.build && routeEntry.liveHandler
|
|
802
|
+
? routeEntry.liveHandler
|
|
803
|
+
: routeEntry.handler;
|
|
639
804
|
if (!routeEntry.loading) {
|
|
640
|
-
const result = handleHandlerResult(await
|
|
805
|
+
const result = handleHandlerResult(await handler(context));
|
|
641
806
|
doneHandler();
|
|
642
807
|
return result;
|
|
643
808
|
}
|
|
644
809
|
if (!actionContext) {
|
|
645
|
-
const result = handleHandlerResult(
|
|
810
|
+
const result = handleHandlerResult(handler(context));
|
|
646
811
|
if (result instanceof Promise) {
|
|
812
|
+
warnOnStreamedResponse(result, routeEntry.id);
|
|
647
813
|
result.finally(doneHandler).catch(() => {});
|
|
648
814
|
const tracked = deps.trackHandler(result, {
|
|
649
815
|
segmentId: entry.shortCode,
|
|
@@ -665,9 +831,7 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
|
|
|
665
831
|
debugLog("segment.action", "resolving action route with awaited value", {
|
|
666
832
|
entryId: entry.id,
|
|
667
833
|
});
|
|
668
|
-
const actionResult = handleHandlerResult(
|
|
669
|
-
await routeEntry.handler(context),
|
|
670
|
-
);
|
|
834
|
+
const actionResult = handleHandlerResult(await handler(context));
|
|
671
835
|
doneHandler();
|
|
672
836
|
return {
|
|
673
837
|
content: Promise.resolve(actionResult),
|
|
@@ -676,10 +840,12 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
|
|
|
676
840
|
() => null,
|
|
677
841
|
);
|
|
678
842
|
|
|
843
|
+
// Normalize void handlers (undefined) to null so the reconciler's
|
|
844
|
+
// component === null checks work consistently for both void and explicit null.
|
|
679
845
|
const resolvedComponent =
|
|
680
846
|
component && typeof component === "object" && "content" in component
|
|
681
|
-
? (component as { content: ReactNode }).content
|
|
682
|
-
: component;
|
|
847
|
+
? ((component as { content: ReactNode }).content ?? null)
|
|
848
|
+
: (component ?? null);
|
|
683
849
|
|
|
684
850
|
const segment: ResolvedSegment = {
|
|
685
851
|
id: entry.shortCode,
|
|
@@ -689,13 +855,17 @@ export async function resolveEntryHandlerWithRevalidation<TEnv>(
|
|
|
689
855
|
index: 0,
|
|
690
856
|
component: resolvedComponent,
|
|
691
857
|
loading: entry.loading === false ? null : entry.loading,
|
|
692
|
-
transition:
|
|
858
|
+
transition: applyViewTransitionDefault(
|
|
859
|
+
entry.transition,
|
|
860
|
+
deps.viewTransitionDefault,
|
|
861
|
+
),
|
|
693
862
|
params,
|
|
694
863
|
belongsToRoute,
|
|
695
864
|
...(entry.type === "layout" || entry.type === "cache"
|
|
696
865
|
? { layoutName: entry.id }
|
|
697
866
|
: {}),
|
|
698
867
|
...(entry.mountPath ? { mountPath: entry.mountPath } : {}),
|
|
868
|
+
_handlerRan: handlerRan,
|
|
699
869
|
};
|
|
700
870
|
|
|
701
871
|
return { segment, matchedId };
|
|
@@ -714,7 +884,6 @@ export async function resolveSegmentWithRevalidation<TEnv>(
|
|
|
714
884
|
request: Request,
|
|
715
885
|
prevUrl: URL,
|
|
716
886
|
nextUrl: URL,
|
|
717
|
-
loaderPromises: Map<string, Promise<any>>,
|
|
718
887
|
deps: SegmentResolutionDeps<TEnv>,
|
|
719
888
|
actionContext?: ActionContext,
|
|
720
889
|
stale?: boolean,
|
|
@@ -776,11 +945,11 @@ export async function resolveSegmentWithRevalidation<TEnv>(
|
|
|
776
945
|
prevUrl,
|
|
777
946
|
nextUrl,
|
|
778
947
|
routeKey,
|
|
779
|
-
loaderPromises,
|
|
780
948
|
true,
|
|
781
949
|
deps,
|
|
782
950
|
actionContext,
|
|
783
951
|
stale,
|
|
952
|
+
entry,
|
|
784
953
|
);
|
|
785
954
|
segments.push(...orphanResult.segments);
|
|
786
955
|
matchedIds.push(...orphanResult.matchedIds);
|
|
@@ -860,7 +1029,6 @@ export async function resolveSegmentWithRevalidation<TEnv>(
|
|
|
860
1029
|
prevUrl,
|
|
861
1030
|
nextUrl,
|
|
862
1031
|
routeKey,
|
|
863
|
-
loaderPromises,
|
|
864
1032
|
false,
|
|
865
1033
|
deps,
|
|
866
1034
|
actionContext,
|
|
@@ -887,11 +1055,12 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
|
|
|
887
1055
|
prevUrl: URL,
|
|
888
1056
|
nextUrl: URL,
|
|
889
1057
|
routeKey: string,
|
|
890
|
-
loaderPromises: Map<string, Promise<any>>,
|
|
891
1058
|
belongsToRoute: boolean,
|
|
892
1059
|
deps: SegmentResolutionDeps<TEnv>,
|
|
893
1060
|
actionContext?: ActionContext,
|
|
894
1061
|
stale?: boolean,
|
|
1062
|
+
/** Parent route entry — its loaders are inherited so parallel slots can access them. */
|
|
1063
|
+
parentRouteEntry?: EntryData,
|
|
895
1064
|
): Promise<SegmentRevalidationResult> {
|
|
896
1065
|
invariant(
|
|
897
1066
|
orphan.type === "layout" || orphan.type === "cache",
|
|
@@ -919,6 +1088,37 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
|
|
|
919
1088
|
segments.push(...loaderResult.segments);
|
|
920
1089
|
matchedIds.push(...loaderResult.matchedIds);
|
|
921
1090
|
|
|
1091
|
+
// Inherit parent route's loaders so parallel slots inside this layout
|
|
1092
|
+
// can access them via useLoader(). See resolveOrphanLayout in fresh.ts.
|
|
1093
|
+
if (
|
|
1094
|
+
parentRouteEntry &&
|
|
1095
|
+
parentRouteEntry.loader &&
|
|
1096
|
+
parentRouteEntry.loader.length > 0 &&
|
|
1097
|
+
Object.keys(orphan.parallel).length > 0
|
|
1098
|
+
) {
|
|
1099
|
+
const inheritedResult = await resolveLoadersWithRevalidation(
|
|
1100
|
+
parentRouteEntry,
|
|
1101
|
+
context,
|
|
1102
|
+
belongsToRoute,
|
|
1103
|
+
clientSegmentIds,
|
|
1104
|
+
prevParams,
|
|
1105
|
+
request,
|
|
1106
|
+
prevUrl,
|
|
1107
|
+
nextUrl,
|
|
1108
|
+
routeKey,
|
|
1109
|
+
deps,
|
|
1110
|
+
actionContext,
|
|
1111
|
+
orphan.shortCode,
|
|
1112
|
+
stale,
|
|
1113
|
+
);
|
|
1114
|
+
// Tag as inherited so buildMatchResult can deduplicate when safe
|
|
1115
|
+
for (const s of inheritedResult.segments) {
|
|
1116
|
+
s._inherited = true;
|
|
1117
|
+
}
|
|
1118
|
+
segments.push(...inheritedResult.segments);
|
|
1119
|
+
matchedIds.push(...inheritedResult.matchedIds);
|
|
1120
|
+
}
|
|
1121
|
+
|
|
922
1122
|
// Handler-first: resolve orphan layout handler before its parallels
|
|
923
1123
|
// so ctx.set() values are visible to parallel children.
|
|
924
1124
|
matchedIds.push(orphan.shortCode);
|
|
@@ -991,157 +1191,40 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
|
|
|
991
1191
|
belongsToRoute,
|
|
992
1192
|
layoutName: orphan.id,
|
|
993
1193
|
loading: orphan.loading === false ? null : orphan.loading,
|
|
994
|
-
transition:
|
|
1194
|
+
transition: applyViewTransitionDefault(
|
|
1195
|
+
orphan.transition,
|
|
1196
|
+
deps.viewTransitionDefault,
|
|
1197
|
+
),
|
|
995
1198
|
...(orphan.mountPath ? { mountPath: orphan.mountPath } : {}),
|
|
996
1199
|
});
|
|
997
1200
|
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
| ReactNode
|
|
1026
|
-
>;
|
|
1027
|
-
|
|
1028
|
-
for (const [slot, handler] of Object.entries(slots)) {
|
|
1029
|
-
// Use orphan.shortCode (the parent layout) to match the SSR path
|
|
1030
|
-
// (resolveParallelEntry receives parentShortCode = orphan.shortCode).
|
|
1031
|
-
// Using parallelEntry.shortCode would generate IDs the client doesn't know about.
|
|
1032
|
-
const parallelId = `${orphan.shortCode}.${slot}`;
|
|
1033
|
-
matchedIds.push(parallelId);
|
|
1034
|
-
|
|
1035
|
-
const shouldResolve = await (async () => {
|
|
1036
|
-
if (!clientSegmentIds.has(parallelId)) {
|
|
1037
|
-
if (isTraceActive()) {
|
|
1038
|
-
pushRevalidationTraceEntry({
|
|
1039
|
-
segmentId: parallelId,
|
|
1040
|
-
segmentType: "parallel",
|
|
1041
|
-
belongsToRoute,
|
|
1042
|
-
source: "parallel",
|
|
1043
|
-
defaultShouldRevalidate: true,
|
|
1044
|
-
finalShouldRevalidate: true,
|
|
1045
|
-
reason: "new-segment",
|
|
1046
|
-
});
|
|
1047
|
-
}
|
|
1048
|
-
return true;
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
const dummySegment: ResolvedSegment = {
|
|
1052
|
-
id: parallelId,
|
|
1053
|
-
namespace: parallelEntry.id,
|
|
1054
|
-
type: "parallel",
|
|
1055
|
-
index: 0,
|
|
1056
|
-
component: null as any,
|
|
1057
|
-
params,
|
|
1058
|
-
slot,
|
|
1059
|
-
belongsToRoute,
|
|
1060
|
-
parallelName: `${parallelEntry.id}.${slot}`,
|
|
1061
|
-
...(parallelEntry.mountPath
|
|
1062
|
-
? { mountPath: parallelEntry.mountPath }
|
|
1063
|
-
: {}),
|
|
1064
|
-
};
|
|
1065
|
-
|
|
1066
|
-
return await evaluateRevalidation({
|
|
1067
|
-
segment: dummySegment,
|
|
1068
|
-
prevParams,
|
|
1069
|
-
getPrevSegment: null,
|
|
1070
|
-
request,
|
|
1071
|
-
prevUrl,
|
|
1072
|
-
nextUrl,
|
|
1073
|
-
revalidations: parallelEntry.revalidate.map((fn, i) => ({
|
|
1074
|
-
name: `revalidate${i}`,
|
|
1075
|
-
fn,
|
|
1076
|
-
})),
|
|
1077
|
-
routeKey,
|
|
1078
|
-
context,
|
|
1079
|
-
actionContext,
|
|
1080
|
-
stale,
|
|
1081
|
-
traceSource: "parallel",
|
|
1082
|
-
});
|
|
1083
|
-
})();
|
|
1084
|
-
emitRevalidationDecision(
|
|
1085
|
-
parallelId,
|
|
1086
|
-
context.pathname,
|
|
1087
|
-
routeKey,
|
|
1088
|
-
shouldResolve,
|
|
1089
|
-
);
|
|
1090
|
-
|
|
1091
|
-
let component: ReactNode | undefined;
|
|
1092
|
-
if (shouldResolve) {
|
|
1093
|
-
component = await tryStaticSlot(parallelEntry, slot, parallelId);
|
|
1094
|
-
}
|
|
1095
|
-
if (component === undefined) {
|
|
1096
|
-
const hasLoadingFallback =
|
|
1097
|
-
parallelEntry.loading !== undefined &&
|
|
1098
|
-
parallelEntry.loading !== false;
|
|
1099
|
-
if (!shouldResolve) {
|
|
1100
|
-
component = null;
|
|
1101
|
-
} else if (hasLoadingFallback) {
|
|
1102
|
-
const result =
|
|
1103
|
-
typeof handler === "function" ? handler(context) : handler;
|
|
1104
|
-
if (result instanceof Promise) {
|
|
1105
|
-
const tracked = deps.trackHandler(result, {
|
|
1106
|
-
segmentId: parallelId,
|
|
1107
|
-
segmentType: "parallel",
|
|
1108
|
-
});
|
|
1109
|
-
observeStreamedHandler(
|
|
1110
|
-
tracked,
|
|
1111
|
-
parallelId,
|
|
1112
|
-
"parallel",
|
|
1113
|
-
context.pathname,
|
|
1114
|
-
routeKey,
|
|
1115
|
-
params,
|
|
1116
|
-
);
|
|
1117
|
-
component = tracked as ReactNode;
|
|
1118
|
-
} else {
|
|
1119
|
-
component = result as ReactNode;
|
|
1120
|
-
}
|
|
1121
|
-
} else {
|
|
1122
|
-
component =
|
|
1123
|
-
typeof handler === "function" ? await handler(context) : handler;
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
segments.push({
|
|
1128
|
-
id: parallelId,
|
|
1129
|
-
namespace: parallelEntry.id,
|
|
1130
|
-
type: "parallel",
|
|
1131
|
-
index: 0,
|
|
1132
|
-
component,
|
|
1133
|
-
loading: parallelEntry.loading === false ? null : parallelEntry.loading,
|
|
1134
|
-
transition: parallelEntry.transition,
|
|
1135
|
-
params,
|
|
1136
|
-
slot,
|
|
1137
|
-
belongsToRoute,
|
|
1138
|
-
parallelName: `${parallelEntry.id}.${slot}`,
|
|
1139
|
-
...(parallelEntry.mountPath
|
|
1140
|
-
? { mountPath: parallelEntry.mountPath }
|
|
1141
|
-
: {}),
|
|
1142
|
-
});
|
|
1143
|
-
}
|
|
1144
|
-
}
|
|
1201
|
+
// Resolve the orphan layout's parallel slots through the shared main-path
|
|
1202
|
+
// helper. The orphan policy is carried by explicit args, byte-for-byte:
|
|
1203
|
+
// - parentChainDefault "force-render": an unknown parent-chain slot seeds
|
|
1204
|
+
// `true` (orphan parallels always belong to the route — the #482 guard),
|
|
1205
|
+
// where the main path would seed `belongsToRoute || isNewParent`.
|
|
1206
|
+
// - loaderOrder "before": a slot's loaders are emitted before the slot
|
|
1207
|
+
// segment, matching the prior inlined order.
|
|
1208
|
+
// `entry.shortCode` inside the helper is `orphan.shortCode` (orphan is passed
|
|
1209
|
+
// as `entry`), so the parallel ids + loader shortCodeOverride are unchanged.
|
|
1210
|
+
const parallelResult = await resolveParallelSegmentsWithRevalidation(
|
|
1211
|
+
orphan,
|
|
1212
|
+
params,
|
|
1213
|
+
context,
|
|
1214
|
+
belongsToRoute,
|
|
1215
|
+
clientSegmentIds,
|
|
1216
|
+
prevParams,
|
|
1217
|
+
request,
|
|
1218
|
+
prevUrl,
|
|
1219
|
+
nextUrl,
|
|
1220
|
+
routeKey,
|
|
1221
|
+
deps,
|
|
1222
|
+
actionContext,
|
|
1223
|
+
stale,
|
|
1224
|
+
{ parentChainDefault: "force-render", loaderOrder: "before" },
|
|
1225
|
+
);
|
|
1226
|
+
segments.push(...parallelResult.segments);
|
|
1227
|
+
matchedIds.push(...parallelResult.matchedIds);
|
|
1145
1228
|
|
|
1146
1229
|
return { segments, matchedIds };
|
|
1147
1230
|
}
|
|
@@ -1159,12 +1242,12 @@ export async function resolveAllSegmentsWithRevalidation<TEnv>(
|
|
|
1159
1242
|
request: Request,
|
|
1160
1243
|
prevUrl: URL,
|
|
1161
1244
|
nextUrl: URL,
|
|
1162
|
-
loaderPromises: Map<string, Promise<any>>,
|
|
1163
1245
|
actionContext: ActionContext | undefined,
|
|
1164
1246
|
interceptResult: { intercept: any; entry: EntryData } | null,
|
|
1165
1247
|
localRouteName: string,
|
|
1166
1248
|
pathname: string,
|
|
1167
1249
|
deps: SegmentResolutionDeps<TEnv>,
|
|
1250
|
+
stale?: boolean,
|
|
1168
1251
|
): Promise<{ segments: ResolvedSegment[]; matchedIds: string[] }> {
|
|
1169
1252
|
const allSegments: ResolvedSegment[] = [];
|
|
1170
1253
|
const matchedIds: string[] = [];
|
|
@@ -1191,6 +1274,10 @@ export async function resolveAllSegmentsWithRevalidation<TEnv>(
|
|
|
1191
1274
|
}
|
|
1192
1275
|
|
|
1193
1276
|
const nonParallelEntry = entry as Exclude<EntryData, { type: "parallel" }>;
|
|
1277
|
+
if (entry.type === "cache") {
|
|
1278
|
+
const store = RangoContext.getStore();
|
|
1279
|
+
if (store) store.insideCacheScope = true;
|
|
1280
|
+
}
|
|
1194
1281
|
const doneEntry = track(`segment:${entry.id}`, 1);
|
|
1195
1282
|
const resolved = await resolveWithErrorBoundary(
|
|
1196
1283
|
nonParallelEntry,
|
|
@@ -1206,16 +1293,13 @@ export async function resolveAllSegmentsWithRevalidation<TEnv>(
|
|
|
1206
1293
|
request,
|
|
1207
1294
|
prevUrl,
|
|
1208
1295
|
nextUrl,
|
|
1209
|
-
loaderPromises,
|
|
1210
1296
|
deps,
|
|
1211
1297
|
actionContext,
|
|
1212
|
-
|
|
1298
|
+
stale,
|
|
1213
1299
|
),
|
|
1214
1300
|
(seg) => ({ segments: [seg], matchedIds: [seg.id] }),
|
|
1215
1301
|
deps,
|
|
1216
|
-
telemetry
|
|
1217
|
-
? { request, url: context.url, routeKey, isPartial: true, telemetry }
|
|
1218
|
-
: undefined,
|
|
1302
|
+
{ request, url: context.url, routeKey, isPartial: true, telemetry },
|
|
1219
1303
|
pathname,
|
|
1220
1304
|
);
|
|
1221
1305
|
doneEntry();
|