@rangojs/router 0.24.4 → 0.26.0
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/README.md +1 -0
- package/dist/bin/rango.js +363 -39
- package/dist/testing/vitest.js +37 -4
- package/dist/types/browser/event-controller.d.ts +24 -5
- package/dist/types/browser/intercept-utils.d.ts +5 -2
- package/dist/types/browser/merge-segment-loaders.d.ts +0 -23
- package/dist/types/browser/navigation-transaction.d.ts +5 -5
- package/dist/types/browser/partial-update.d.ts +21 -13
- package/dist/types/browser/prefetch/cache.d.ts +8 -0
- package/dist/types/browser/rango-marker.d.ts +7 -0
- package/dist/types/browser/react/filter-segment-order.d.ts +10 -0
- package/dist/types/browser/react/use-handle.d.ts +20 -0
- package/dist/types/browser/react/use-href.d.ts +6 -0
- package/dist/types/browser/react/use-router.d.ts +6 -1
- package/dist/types/browser/response-adapter.d.ts +5 -3
- package/dist/types/browser/scroll-restoration.d.ts +9 -3
- package/dist/types/browser/segment-reconciler.d.ts +10 -13
- package/dist/types/browser/types.d.ts +38 -8
- package/dist/types/build/route-types/per-module-writer.d.ts +12 -0
- package/dist/types/cache/cf/cf-cache-store.d.ts +0 -2
- package/dist/types/cache/cf/cf-cache-types.d.ts +0 -16
- package/dist/types/cache/cf/cf-shell-frame.d.ts +2 -0
- package/dist/types/cache/handle-snapshot.d.ts +2 -2
- package/dist/types/cache/types.d.ts +16 -6
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +1 -15
- package/dist/types/client-urls/client-urls.d.ts +6 -2
- package/dist/types/client-urls/revalidate-registry.d.ts +1 -1
- package/dist/types/client-urls/server-projection.d.ts +9 -5
- package/dist/types/client-urls/types.d.ts +29 -16
- package/dist/types/client.d.ts +2 -2
- package/dist/types/client.rsc.d.ts +2 -2
- package/dist/types/decode-loader-results.d.ts +28 -7
- package/dist/types/handles/deferred-resolution.d.ts +3 -2
- package/dist/types/handles/meta.d.ts +5 -0
- package/dist/types/href-client.d.ts +3 -1
- package/dist/types/index.rsc.d.ts +1 -1
- package/dist/types/loader-redirect.d.ts +2 -3
- package/dist/types/outlet-context.d.ts +7 -6
- package/dist/types/prefetch-markers.d.ts +14 -5
- package/dist/types/prerender/build-shell-capture.d.ts +1 -2
- package/dist/types/prerender/writable-store.d.ts +2 -3
- package/dist/types/route-content-wrapper.d.ts +17 -14
- package/dist/types/route-definition/helpers-types.d.ts +7 -2
- package/dist/types/route-definition/resolve-handler-use.d.ts +6 -1
- package/dist/types/route-definition/rewrite.d.ts +48 -5
- package/dist/types/route-types.d.ts +2 -2
- package/dist/types/router/handler-context.d.ts +14 -2
- package/dist/types/router/intercept-resolution.d.ts +19 -46
- package/dist/types/router/lazy-includes.d.ts +7 -0
- package/dist/types/router/match-middleware/intercept-resolution.d.ts +2 -2
- package/dist/types/router/middleware.d.ts +0 -16
- package/dist/types/router/navigation-snapshot.d.ts +2 -0
- package/dist/types/router/prefetch-cache-ttl.d.ts +8 -11
- package/dist/types/router/revalidation.d.ts +8 -1
- package/dist/types/router/router-context.d.ts +4 -16
- package/dist/types/router/router-interfaces.d.ts +0 -11
- package/dist/types/router/router-options.d.ts +4 -27
- package/dist/types/router/segment-resolution/mask-nested.d.ts +5 -3
- package/dist/types/router/segment-resolution/prefetch-deferral.d.ts +31 -8
- package/dist/types/router/segment-resolution/revalidation.d.ts +38 -4
- package/dist/types/router/segment-resolution.d.ts +1 -1
- package/dist/types/router/segment-wrappers.d.ts +3 -5
- package/dist/types/router/substitute-pattern-params.d.ts +3 -2
- package/dist/types/router/tracing.d.ts +2 -2
- package/dist/types/router-versions.d.ts +8 -6
- package/dist/types/rsc/full-payload.d.ts +14 -2
- package/dist/types/rsc/helpers.d.ts +8 -0
- package/dist/types/rsc/manifest-init.d.ts +20 -0
- package/dist/types/rsc/prefetch-render-error.d.ts +22 -0
- package/dist/types/rsc/progressive-enhancement.d.ts +20 -0
- package/dist/types/rsc/rewrite-passes.d.ts +12 -2
- package/dist/types/rsc/server-action.d.ts +6 -0
- package/dist/types/rsc/shell-capture-constants.d.ts +14 -4
- package/dist/types/rsc/shell-capture.d.ts +23 -2
- package/dist/types/rsc/types.d.ts +5 -8
- package/dist/types/segment-system.d.ts +15 -0
- package/dist/types/server/build-version-table.d.ts +10 -13
- package/dist/types/server/context.d.ts +90 -6
- package/dist/types/server/handle-store.d.ts +17 -6
- package/dist/types/server/request-context.d.ts +45 -7
- package/dist/types/server/request-headers.d.ts +12 -0
- package/dist/types/server/rewrite-trail.d.ts +8 -1
- package/dist/types/testing/build-versions.d.ts +0 -3
- package/dist/types/testing/e2e/index.d.ts +1 -1
- package/dist/types/testing/flight.entry.d.ts +1 -1
- package/dist/types/testing/index.d.ts +1 -1
- package/dist/types/testing/internal/client-urls-projection.d.ts +4 -3
- package/dist/types/testing/internal/seed-vars.d.ts +4 -4
- package/dist/types/testing/render-route.d.ts +21 -11
- package/dist/types/testing/run-loader.d.ts +7 -0
- package/dist/types/testing/run-middleware.d.ts +7 -0
- package/dist/types/testing/run-revalidate.d.ts +5 -4
- package/dist/types/testing/serve-shell-request.d.ts +42 -5
- package/dist/types/testing/shell-status.d.ts +17 -0
- package/dist/types/testing/vitest-stubs/version.d.ts +1 -0
- package/dist/types/testing/vitest.d.ts +10 -1
- package/dist/types/thenable-status.d.ts +0 -6
- package/dist/types/types/handler-context.d.ts +12 -1
- package/dist/types/types/loader-types.d.ts +10 -4
- package/dist/types/types/route-entry.d.ts +2 -1
- package/dist/types/urls/path-helper-types.d.ts +4 -2
- package/dist/types/vite/discovery/client-urls-projection.d.ts +55 -5
- package/dist/types/vite/discovery/state.d.ts +20 -0
- package/dist/types/vite/plugins/client-urls-revalidate-hoist.d.ts +28 -16
- package/dist/types/vite/plugins/hoist/source.d.ts +8 -7
- package/dist/types/vite/plugins/virtual-entries.d.ts +6 -0
- package/dist/types/vite/utils/prerender-utils.d.ts +7 -0
- package/dist/vite/index.js +6819 -6555
- package/package.json +1 -1
- package/skills/app-structure/SKILL.md +255 -0
- package/skills/app-structure/content-site.md +333 -0
- package/skills/app-structure/e-commerce.md +435 -0
- package/skills/app-structure/large-app.md +885 -0
- package/skills/app-structure/multi-app.md +280 -0
- package/skills/breadcrumbs/SKILL.md +6 -1
- package/skills/cache-guide/SKILL.md +4 -8
- package/skills/caching/SKILL.md +6 -6
- package/skills/catalog.json +12 -0
- package/skills/client-urls/SKILL.md +185 -32
- package/skills/comparison/references/framework-comparison.md +1 -1
- package/skills/composability/SKILL.md +10 -8
- package/skills/handler-use/SKILL.md +48 -9
- package/skills/hooks/handle-and-actions.md +104 -0
- package/skills/hooks/navigation.md +24 -10
- package/skills/hooks/urls.md +1 -1
- package/skills/host-router/SKILL.md +1 -1
- package/skills/i18n/SKILL.md +2 -1
- package/skills/intercept/SKILL.md +60 -29
- package/skills/layout/SKILL.md +6 -3
- package/skills/links/SKILL.md +151 -17
- package/skills/loader/SKILL.md +42 -19
- package/skills/middleware/SKILL.md +111 -15
- package/skills/observability/SKILL.md +11 -0
- package/skills/parallel/SKILL.md +5 -5
- package/skills/ppr/SKILL.md +103 -52
- package/skills/prerender/SKILL.md +4 -5
- package/skills/rango/SKILL.md +3 -0
- package/skills/response-routes/SKILL.md +4 -1
- package/skills/router-setup/SKILL.md +0 -2
- package/skills/scripts/SKILL.md +12 -1
- package/skills/server-actions/SKILL.md +60 -20
- package/skills/testing/SKILL.md +1 -0
- package/skills/testing/client-components.md +13 -10
- package/skills/testing/loader.md +25 -24
- package/skills/testing/middleware.md +11 -11
- package/skills/testing/render-handler.md +17 -17
- package/skills/testing/response-routes.md +4 -1
- package/skills/testing/serve-shell-request.md +86 -22
- package/skills/testing/server-actions.md +16 -16
- package/skills/ux-architecture/SKILL.md +980 -0
- package/skills/vercel/SKILL.md +1 -1
- package/skills/view-transitions/SKILL.md +43 -10
- package/src/__augment-tests__/augmented.check.ts +28 -0
- package/src/browser/event-controller.ts +44 -18
- package/src/browser/intercept-utils.ts +3 -2
- package/src/browser/merge-segment-loaders.ts +0 -85
- package/src/browser/navigation-bridge.ts +112 -84
- package/src/browser/navigation-client.ts +20 -15
- package/src/browser/navigation-store.ts +4 -2
- package/src/browser/navigation-transaction.ts +9 -8
- package/src/browser/partial-update.ts +90 -32
- package/src/browser/prefetch/cache.ts +8 -0
- package/src/browser/prefetch/fetch.ts +13 -3
- package/src/browser/rango-marker.ts +13 -0
- package/src/browser/react/NavigationProvider.tsx +25 -7
- package/src/browser/react/filter-segment-order.ts +13 -0
- package/src/browser/react/use-action.ts +9 -15
- package/src/browser/react/use-handle.ts +63 -71
- package/src/browser/react/use-href.tsx +24 -5
- package/src/browser/react/use-link-status.ts +1 -1
- package/src/browser/react/use-navigation.ts +30 -40
- package/src/browser/react/use-router.ts +37 -6
- package/src/browser/react/use-segments.ts +8 -12
- package/src/browser/response-adapter.ts +11 -5
- package/src/browser/rsc-router.tsx +3 -1
- package/src/browser/scroll-restoration.ts +34 -20
- package/src/browser/segment-reconciler.ts +11 -29
- package/src/browser/server-action-bridge.ts +52 -16
- package/src/browser/types.ts +40 -8
- package/src/build/generate-manifest.ts +12 -1
- package/src/build/route-types/codegen.ts +6 -2
- package/src/build/route-types/per-module-writer.ts +94 -61
- package/src/cache/cache-runtime.ts +9 -0
- package/src/cache/cache-scope.ts +2 -1
- package/src/cache/cf/cf-cache-store.ts +6 -7
- package/src/cache/cf/cf-cache-types.ts +0 -17
- package/src/cache/cf/cf-shell-frame.ts +3 -0
- package/src/cache/handle-snapshot.ts +2 -2
- package/src/cache/types.ts +16 -6
- package/src/cache/vercel/vercel-cache-store.ts +8 -19
- package/src/client-urls/client-urls.ts +202 -153
- package/src/client-urls/revalidate-registry.ts +12 -3
- package/src/client-urls/server-projection.ts +137 -66
- package/src/client-urls/types.ts +30 -15
- package/src/client.rsc.tsx +11 -1
- package/src/client.tsx +9 -1
- package/src/decode-loader-results.ts +64 -31
- package/src/handles/deferred-resolution.ts +3 -2
- package/src/handles/meta.ts +5 -0
- package/src/href-client.ts +3 -1
- package/src/index.rsc.ts +1 -0
- package/src/index.ts +12 -4
- package/src/loader-redirect.tsx +2 -3
- package/src/outlet-context.ts +7 -6
- package/src/prefetch-markers.ts +15 -5
- package/src/prerender/build-shell-capture.ts +1 -2
- package/src/prerender/writable-store.ts +2 -3
- package/src/reverse.ts +3 -3
- package/src/route-content-wrapper.tsx +19 -17
- package/src/route-definition/dsl-helpers.ts +41 -21
- package/src/route-definition/helpers-types.ts +7 -2
- package/src/route-definition/resolve-handler-use.ts +23 -10
- package/src/route-definition/rewrite.ts +86 -19
- package/src/route-types.ts +1 -2
- package/src/router/find-match.ts +37 -1
- package/src/router/handler-context.ts +85 -40
- package/src/router/intercept-resolution.ts +161 -307
- package/src/router/lazy-includes.ts +43 -27
- package/src/router/loader-resolution.ts +21 -1
- package/src/router/manifest.ts +15 -10
- package/src/router/match-api.ts +11 -1
- package/src/router/match-middleware/background-revalidation.ts +2 -4
- package/src/router/match-middleware/cache-lookup.ts +16 -20
- package/src/router/match-middleware/intercept-resolution.ts +41 -60
- package/src/router/match-result.ts +31 -2
- package/src/router/middleware.ts +6 -147
- package/src/router/navigation-snapshot.ts +38 -2
- package/src/router/prefetch-cache-ttl.ts +10 -18
- package/src/router/prerender-match.ts +2 -1
- package/src/router/revalidation.ts +24 -3
- package/src/router/router-context.ts +5 -18
- package/src/router/router-interfaces.ts +0 -13
- package/src/router/router-options.ts +4 -28
- package/src/router/segment-resolution/fresh.ts +6 -2
- package/src/router/segment-resolution/helpers.ts +7 -1
- package/src/router/segment-resolution/loader-cache.ts +4 -3
- package/src/router/segment-resolution/mask-nested.ts +5 -3
- package/src/router/segment-resolution/prefetch-deferral.ts +62 -12
- package/src/router/segment-resolution/revalidation.ts +75 -35
- package/src/router/segment-resolution.ts +0 -1
- package/src/router/segment-wrappers.ts +8 -13
- package/src/router/substitute-pattern-params.ts +3 -2
- package/src/router/tracing.ts +2 -2
- package/src/router-versions.ts +7 -7
- package/src/router.ts +5 -17
- package/src/rsc/full-payload.ts +26 -4
- package/src/rsc/handler.ts +86 -48
- package/src/rsc/helpers.ts +13 -0
- package/src/rsc/manifest-init.ts +56 -3
- package/src/rsc/prefetch-render-error.ts +38 -0
- package/src/rsc/progressive-enhancement.ts +161 -211
- package/src/rsc/rewrite-passes.ts +56 -9
- package/src/rsc/rsc-rendering.ts +79 -23
- package/src/rsc/server-action.ts +25 -2
- package/src/rsc/shell-capture-constants.ts +26 -3
- package/src/rsc/shell-capture.ts +137 -51
- package/src/rsc/types.ts +5 -9
- package/src/segment-system.tsx +125 -119
- package/src/server/build-version-table.ts +12 -24
- package/src/server/context.ts +160 -7
- package/src/server/handle-store.ts +80 -12
- package/src/server/request-context.ts +46 -6
- package/src/server/request-headers.ts +32 -0
- package/src/server/rewrite-trail.ts +55 -9
- package/src/ssr/ssr-root.tsx +6 -10
- package/src/testing/build-versions.ts +0 -3
- package/src/testing/dispatch.ts +5 -8
- package/src/testing/e2e/index.ts +1 -0
- package/src/testing/flight.entry.ts +1 -0
- package/src/testing/index.ts +1 -0
- package/src/testing/internal/client-urls-projection.ts +31 -11
- package/src/testing/internal/seed-vars.ts +4 -4
- package/src/testing/render-route.tsx +83 -40
- package/src/testing/run-loader.ts +26 -2
- package/src/testing/run-middleware.ts +10 -0
- package/src/testing/run-revalidate.ts +13 -6
- package/src/testing/serve-shell-request.ts +79 -9
- package/src/testing/shell-status.ts +40 -0
- package/src/testing/vitest-stubs/version.ts +1 -0
- package/src/testing/vitest.ts +74 -7
- package/src/thenable-status.ts +0 -11
- package/src/types/handler-context.ts +12 -1
- package/src/types/loader-types.ts +10 -4
- package/src/types/route-entry.ts +2 -1
- package/src/urls/include-helper.ts +38 -11
- package/src/urls/path-helper-types.ts +4 -2
- package/src/vite/discovery/client-urls-projection.ts +205 -16
- package/src/vite/discovery/discover-routers.ts +2 -2
- package/src/vite/discovery/prerender-collection.ts +2 -6
- package/src/vite/discovery/shell-prerender-phase.ts +1 -5
- package/src/vite/discovery/state.ts +26 -0
- package/src/vite/plugins/client-urls-revalidate-hoist.ts +190 -77
- package/src/vite/plugins/expose-internal-ids.ts +46 -40
- package/src/vite/plugins/hoist/source.ts +8 -7
- package/src/vite/plugins/transition-when-hoist.ts +1 -0
- package/src/vite/plugins/version-plugin.ts +7 -0
- package/src/vite/plugins/version.d.ts +7 -0
- package/src/vite/plugins/virtual-entries.ts +20 -0
- package/src/vite/rango.ts +4 -1
- package/src/vite/router-discovery.ts +39 -7
- package/src/vite/utils/prerender-utils.ts +17 -0
|
@@ -30,12 +30,14 @@ import {
|
|
|
30
30
|
getParallelSlotEntries,
|
|
31
31
|
isPprEntry,
|
|
32
32
|
type EntryData,
|
|
33
|
+
type InterceptEntry,
|
|
33
34
|
type LoaderEntry,
|
|
34
35
|
} from "../../server/context.js";
|
|
35
36
|
import { requestHeaders } from "../../server/request-headers.js";
|
|
36
37
|
import type { HandlerContext, InternalHandlerContext } from "../../types.js";
|
|
37
38
|
import type { CacheScope } from "../../cache/cache-scope.js";
|
|
38
39
|
import { FILL_PARAM, PREFETCH_HEADER } from "../../prefetch-markers.js";
|
|
40
|
+
import { isInterceptSegment } from "../../browser/intercept-utils.js";
|
|
39
41
|
|
|
40
42
|
/**
|
|
41
43
|
* What a request says it is, read once when its context is created
|
|
@@ -271,40 +273,64 @@ export function resolveDeferralScope(
|
|
|
271
273
|
return scope;
|
|
272
274
|
}
|
|
273
275
|
|
|
276
|
+
const interceptScopes = new WeakMap<InterceptEntry, DeferralScope>();
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* The deferral scope of a request that resolves `intercept`: its own flagged
|
|
280
|
+
* loaders, nothing of the target chain. The chain's layouts below the
|
|
281
|
+
* declaring entry render in that request and its `matched` leaves them out
|
|
282
|
+
* (match-result.ts), so a hole there would stand for a segment outside the
|
|
283
|
+
* page. A flagged loading() inside intercept() defers nothing: the slot is
|
|
284
|
+
* never a unit. Memoized on the entry (replaced with its manifest on HMR).
|
|
285
|
+
*/
|
|
286
|
+
export function resolveInterceptDeferralScope(
|
|
287
|
+
intercept: InterceptEntry,
|
|
288
|
+
): DeferralScope {
|
|
289
|
+
const cached = interceptScopes.get(intercept);
|
|
290
|
+
if (cached) return cached;
|
|
291
|
+
const flagged = intercept.loader.filter((l) => l.prefetch === false);
|
|
292
|
+
const scope: DeferralScope =
|
|
293
|
+
flagged.length === 0
|
|
294
|
+
? EMPTY_SCOPE
|
|
295
|
+
: {
|
|
296
|
+
loaders: new Map(flagged.map((l) => [l, true as const])),
|
|
297
|
+
loaderIds: new Set(flagged.map((l) => l.loader.$$id)),
|
|
298
|
+
units: new Map(),
|
|
299
|
+
};
|
|
300
|
+
interceptScopes.set(intercept, scope);
|
|
301
|
+
return scope;
|
|
302
|
+
}
|
|
303
|
+
|
|
274
304
|
/**
|
|
275
305
|
* Which half of the feature a partial request is, if either (`fill` and
|
|
276
306
|
* `prefetch` are requestKind's answer). Both halves are GETs: a request of
|
|
277
307
|
* another method that carries either marker is a normal request. A prefetch
|
|
278
308
|
* defers only on a plain GET navigation: an action re-renders what it
|
|
279
|
-
* changed,
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
* runs the full match): each one states its own reason.
|
|
309
|
+
* changed, and a shell capture is never a prefetch whatever the request that
|
|
310
|
+
* scheduled it sent. The conditions overlap today (an action is a POST, a
|
|
311
|
+
* capture runs the full match): each one states its own reason.
|
|
283
312
|
*/
|
|
284
313
|
export function partialDeferralMode(request: {
|
|
285
314
|
fill: boolean;
|
|
286
315
|
prefetch: boolean;
|
|
287
316
|
method: string;
|
|
288
317
|
isAction: boolean;
|
|
289
|
-
isIntercept: boolean;
|
|
290
318
|
isShellCapture: boolean;
|
|
291
319
|
}): PrefetchDeferral["mode"] {
|
|
292
320
|
if (request.method !== "GET") return undefined;
|
|
293
321
|
if (request.fill) return "fill";
|
|
294
|
-
return request.prefetch &&
|
|
295
|
-
!request.isAction &&
|
|
296
|
-
!request.isIntercept &&
|
|
297
|
-
!request.isShellCapture
|
|
322
|
+
return request.prefetch && !request.isAction && !request.isShellCapture
|
|
298
323
|
? "prefetch"
|
|
299
324
|
: undefined;
|
|
300
325
|
}
|
|
301
326
|
|
|
302
|
-
const NOTHING_HELD: ReadonlySet<string> = new Set();
|
|
327
|
+
export const NOTHING_HELD: ReadonlySet<string> = new Set();
|
|
303
328
|
|
|
304
329
|
/**
|
|
305
330
|
* The plan for one match, or undefined when the tree declares no flag and the
|
|
306
331
|
* request is not a fill (the common case: nothing to carry). `held` is the
|
|
307
|
-
* client's segment ids as the request listed them.
|
|
332
|
+
* client's segment ids as the request listed them. `scope` is the chain's
|
|
333
|
+
* unless the request resolves an intercept (resolveInterceptDeferralScope).
|
|
308
334
|
*/
|
|
309
335
|
export function planPrefetchDeferral(
|
|
310
336
|
entries: readonly EntryData[],
|
|
@@ -312,8 +338,8 @@ export function planPrefetchDeferral(
|
|
|
312
338
|
matched: { pr?: boolean; od?: boolean },
|
|
313
339
|
cacheScope: CacheScope | null | undefined,
|
|
314
340
|
held: ReadonlySet<string> = NOTHING_HELD,
|
|
341
|
+
scope: DeferralScope = resolveDeferralScope(entries),
|
|
315
342
|
): PrefetchDeferral | undefined {
|
|
316
|
-
const scope = resolveDeferralScope(entries);
|
|
317
343
|
if (scope === EMPTY_SCOPE && mode !== "fill") return undefined;
|
|
318
344
|
|
|
319
345
|
const leaf = entries[entries.length - 1];
|
|
@@ -386,6 +412,30 @@ export function fillSends(
|
|
|
386
412
|
return isFillRequest(ctx) ? !held.has(segmentId) : undefined;
|
|
387
413
|
}
|
|
388
414
|
|
|
415
|
+
/**
|
|
416
|
+
* A fill that resolves an intercept sends only what the client lacks of the
|
|
417
|
+
* intercept: a target-chain entry (by id) or stored segment it does not hold
|
|
418
|
+
* lies outside the intercept's `matched` (match-result.ts), so the fill skips
|
|
419
|
+
* it. The intercept's own segments are never skipped.
|
|
420
|
+
*/
|
|
421
|
+
export function interceptFillSkips(
|
|
422
|
+
match: {
|
|
423
|
+
handlerContext: HandlerContext<any, any>;
|
|
424
|
+
isIntercept: boolean;
|
|
425
|
+
clientSegmentSet: ReadonlySet<string>;
|
|
426
|
+
},
|
|
427
|
+
segment: string | { id: string; namespace?: string },
|
|
428
|
+
): boolean {
|
|
429
|
+
if (!match.isIntercept) return false;
|
|
430
|
+
if (typeof segment !== "string") {
|
|
431
|
+
if (isInterceptSegment(segment)) return false;
|
|
432
|
+
segment = segment.id;
|
|
433
|
+
}
|
|
434
|
+
return (
|
|
435
|
+
fillSends(match.handlerContext, segment, match.clientSegmentSet) === true
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
|
|
389
439
|
const RECORD_OPEN: RecordUse = { read: true, write: true, refresh: true };
|
|
390
440
|
|
|
391
441
|
/** PrefetchDeferral.record, or all of it open when the match has no plan. */
|
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
deferUnit,
|
|
44
44
|
fillSends,
|
|
45
45
|
getPrefetchDeferral,
|
|
46
|
+
interceptFillSkips,
|
|
46
47
|
registerDeferredLoader,
|
|
47
48
|
} from "./prefetch-deferral.js";
|
|
48
49
|
import {
|
|
@@ -58,6 +59,7 @@ import { applyViewTransitionDefault } from "./view-transition-default.js";
|
|
|
58
59
|
import { isLayoutLoaderCopy } from "../../client-urls/layout-loader-copies.js";
|
|
59
60
|
import { getRouterContext } from "../router-context.js";
|
|
60
61
|
import { observeEvent, observeSegmentHandler } from "../instrument.js";
|
|
62
|
+
import { withReverseScope } from "../handler-context.js";
|
|
61
63
|
import { runInSegmentTagScope } from "../../cache/cache-tag.js";
|
|
62
64
|
import { trackStreamedHandler } from "./streamed-handler-boundary.js";
|
|
63
65
|
import {
|
|
@@ -156,7 +158,7 @@ const deferredLoaderRuns = new WeakMap<ResolvedSegment, () => unknown>();
|
|
|
156
158
|
* awaits; a streamed handler that reads the loader later is not seen, and
|
|
157
159
|
* that loader runs again in the fill.
|
|
158
160
|
*/
|
|
159
|
-
function deliverStartedLoaders<TEnv>(
|
|
161
|
+
export function deliverStartedLoaders<TEnv>(
|
|
160
162
|
ctx: HandlerContext<any, TEnv>,
|
|
161
163
|
segments: ResolvedSegment[],
|
|
162
164
|
): void {
|
|
@@ -180,14 +182,51 @@ function deliverStartedLoaders<TEnv>(
|
|
|
180
182
|
// ---------------------------------------------------------------------------
|
|
181
183
|
|
|
182
184
|
/**
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
+
* Whose loaders a resolveOwnerLoaders call resolves: a route entry's (or the
|
|
186
|
+
* entry its loaders are inherited into), or an intercept's, whose loaders are
|
|
187
|
+
* loader segments of its slot (`${parent}.${slot}D${i}.${$$id}`).
|
|
185
188
|
*/
|
|
186
|
-
export
|
|
189
|
+
export interface LoaderOwner {
|
|
190
|
+
readonly loaders: readonly LoaderEntry[];
|
|
191
|
+
/** The segments' namespace: the entry id, or `intercept:${routeName}`. */
|
|
192
|
+
readonly namespace: string;
|
|
193
|
+
/** The segment id the loader ids extend and the handle pushes file under. */
|
|
194
|
+
readonly segmentPrefix: string;
|
|
195
|
+
/** Where a loader error renders (wrapLoaderPromise). */
|
|
196
|
+
readonly boundary: EntryData;
|
|
197
|
+
/**
|
|
198
|
+
* resolveLoaderData's PPR bake/seed key for every loader (loader-cache.ts).
|
|
199
|
+
* False for an intercept: never a document.
|
|
200
|
+
*/
|
|
201
|
+
readonly bakeLane: boolean;
|
|
202
|
+
readonly traceSource: "loader" | "intercept-loader";
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** A route entry as a LoaderOwner, under `shortCodeOverride` when inherited. */
|
|
206
|
+
export function ownerOf(
|
|
187
207
|
entry: EntryData,
|
|
208
|
+
shortCodeOverride?: string,
|
|
209
|
+
): LoaderOwner {
|
|
210
|
+
return {
|
|
211
|
+
loaders: entry.loader ?? [],
|
|
212
|
+
namespace: entry.id,
|
|
213
|
+
segmentPrefix: shortCodeOverride ?? entry.shortCode,
|
|
214
|
+
boundary: entry,
|
|
215
|
+
bakeLane: !entryLoadingMasksLoaders(entry.loading),
|
|
216
|
+
traceSource: "loader",
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* The partial lane's one loader funnel: each loader is a segment, run when
|
|
222
|
+
* the client lacks it, asked its revalidate() when held, kept outright in a
|
|
223
|
+
* fill (fillSends), deferred in a prefetch that defers it (defersLoader).
|
|
224
|
+
*/
|
|
225
|
+
export async function resolveOwnerLoaders<TEnv>(
|
|
226
|
+
owner: LoaderOwner,
|
|
188
227
|
ctx: HandlerContext<any, TEnv>,
|
|
189
228
|
belongsToRoute: boolean,
|
|
190
|
-
clientSegmentIds:
|
|
229
|
+
clientSegmentIds: ReadonlySet<string>,
|
|
191
230
|
prevParams: Record<string, string>,
|
|
192
231
|
request: Request,
|
|
193
232
|
prevUrl: URL,
|
|
@@ -195,13 +234,12 @@ export async function resolveLoadersWithRevalidation<TEnv>(
|
|
|
195
234
|
routeKey: string,
|
|
196
235
|
deps: SegmentResolutionDeps<TEnv>,
|
|
197
236
|
actionContext?: ActionContext,
|
|
198
|
-
shortCodeOverride?: string,
|
|
199
237
|
stale?: boolean,
|
|
200
238
|
): Promise<{ segments: ResolvedSegment[]; matchedIds: string[] }> {
|
|
201
|
-
const loaderEntries =
|
|
239
|
+
const loaderEntries = owner.loaders;
|
|
202
240
|
if (loaderEntries.length === 0) return { segments: [], matchedIds: [] };
|
|
203
241
|
|
|
204
|
-
const shortCode =
|
|
242
|
+
const shortCode = owner.segmentPrefix;
|
|
205
243
|
|
|
206
244
|
// Pin `_currentSegmentId` to the OWNING entry before the kickoffs below —
|
|
207
245
|
// createLoaderExecutor captures it synchronously for ctx.use(Handle) push
|
|
@@ -238,7 +276,7 @@ export async function resolveLoadersWithRevalidation<TEnv>(
|
|
|
238
276
|
segmentId,
|
|
239
277
|
segmentType: "loader",
|
|
240
278
|
belongsToRoute,
|
|
241
|
-
source:
|
|
279
|
+
source: owner.traceSource,
|
|
242
280
|
defaultShouldRevalidate: true,
|
|
243
281
|
finalShouldRevalidate: true,
|
|
244
282
|
reason: "new-segment",
|
|
@@ -249,7 +287,7 @@ export async function resolveLoadersWithRevalidation<TEnv>(
|
|
|
249
287
|
|
|
250
288
|
const dummySegment: ResolvedSegment = {
|
|
251
289
|
id: segmentId,
|
|
252
|
-
namespace:
|
|
290
|
+
namespace: owner.namespace,
|
|
253
291
|
type: "loader",
|
|
254
292
|
index,
|
|
255
293
|
component: null,
|
|
@@ -268,14 +306,14 @@ export async function resolveLoadersWithRevalidation<TEnv>(
|
|
|
268
306
|
prevUrl,
|
|
269
307
|
nextUrl,
|
|
270
308
|
revalidations: loaderRevalidateFns.map((fn, j) => ({
|
|
271
|
-
name:
|
|
309
|
+
name: `${owner.traceSource}-revalidate${j}`,
|
|
272
310
|
fn,
|
|
273
311
|
})),
|
|
274
312
|
routeKey,
|
|
275
313
|
context: ctx,
|
|
276
314
|
actionContext,
|
|
277
315
|
stale,
|
|
278
|
-
traceSource:
|
|
316
|
+
traceSource: owner.traceSource,
|
|
279
317
|
held: clientSegmentIds,
|
|
280
318
|
});
|
|
281
319
|
},
|
|
@@ -300,7 +338,7 @@ export async function resolveLoadersWithRevalidation<TEnv>(
|
|
|
300
338
|
// Outside capture the key only activates the _shellLoaderSeed overlay,
|
|
301
339
|
// which serveShellHit seeds for a document HIT and the PPR partial replay
|
|
302
340
|
// (matchPartialWithPprReplay) seeds once its doc record hits.
|
|
303
|
-
const bakeLane =
|
|
341
|
+
const bakeLane = owner.bakeLane;
|
|
304
342
|
|
|
305
343
|
const kickoff = (
|
|
306
344
|
loaderEntry: LoaderEntry,
|
|
@@ -319,6 +357,7 @@ export async function resolveLoadersWithRevalidation<TEnv>(
|
|
|
319
357
|
bakeLane || loaderEntry.bake === true ? segmentId : null,
|
|
320
358
|
),
|
|
321
359
|
loaderId,
|
|
360
|
+
loaderEntry.reverseScope,
|
|
322
361
|
);
|
|
323
362
|
const start = (
|
|
324
363
|
loaderEntry: LoaderEntry,
|
|
@@ -327,7 +366,7 @@ export async function resolveLoadersWithRevalidation<TEnv>(
|
|
|
327
366
|
) =>
|
|
328
367
|
deps.wrapLoaderPromise(
|
|
329
368
|
kickoff(loaderEntry, segmentId, loaderId),
|
|
330
|
-
|
|
369
|
+
owner.boundary,
|
|
331
370
|
segmentId,
|
|
332
371
|
ctx.pathname,
|
|
333
372
|
errorContext,
|
|
@@ -338,7 +377,7 @@ export async function resolveLoadersWithRevalidation<TEnv>(
|
|
|
338
377
|
({ loaderEntry, loader, segmentId, index }) => {
|
|
339
378
|
const base = {
|
|
340
379
|
id: segmentId,
|
|
341
|
-
namespace:
|
|
380
|
+
namespace: owner.namespace,
|
|
342
381
|
type: "loader" as const,
|
|
343
382
|
index,
|
|
344
383
|
component: null,
|
|
@@ -411,8 +450,8 @@ export async function resolveLoadersOnlyWithRevalidation<TEnv>(
|
|
|
411
450
|
seenIds.has(`${sc}D${i}.${le.loader.$$id}`),
|
|
412
451
|
);
|
|
413
452
|
if (!allAlreadySeen) {
|
|
414
|
-
const { segments, matchedIds } = await
|
|
415
|
-
entry,
|
|
453
|
+
const { segments, matchedIds } = await resolveOwnerLoaders(
|
|
454
|
+
ownerOf(entry, shortCodeOverride),
|
|
416
455
|
context,
|
|
417
456
|
belongsToRoute,
|
|
418
457
|
clientSegmentIds,
|
|
@@ -423,7 +462,6 @@ export async function resolveLoadersOnlyWithRevalidation<TEnv>(
|
|
|
423
462
|
routeKey,
|
|
424
463
|
deps,
|
|
425
464
|
actionContext,
|
|
426
|
-
shortCodeOverride,
|
|
427
465
|
stale,
|
|
428
466
|
);
|
|
429
467
|
for (const seg of segments) {
|
|
@@ -454,8 +492,8 @@ export async function resolveLoadersOnlyWithRevalidation<TEnv>(
|
|
|
454
492
|
entry.loader.length > 0 &&
|
|
455
493
|
Object.keys(layoutEntry.parallel).length > 0
|
|
456
494
|
) {
|
|
457
|
-
const inherited = await
|
|
458
|
-
entry,
|
|
495
|
+
const inherited = await resolveOwnerLoaders(
|
|
496
|
+
ownerOf(entry, layoutEntry.shortCode),
|
|
459
497
|
context,
|
|
460
498
|
childBelongsToRoute,
|
|
461
499
|
clientSegmentIds,
|
|
@@ -466,7 +504,6 @@ export async function resolveLoadersOnlyWithRevalidation<TEnv>(
|
|
|
466
504
|
routeKey,
|
|
467
505
|
deps,
|
|
468
506
|
actionContext,
|
|
469
|
-
layoutEntry.shortCode,
|
|
470
507
|
stale,
|
|
471
508
|
);
|
|
472
509
|
for (const seg of inherited.segments) {
|
|
@@ -594,10 +631,11 @@ async function resolveParallelSlotComponent<TEnv>(args: {
|
|
|
594
631
|
(context as InternalHandlerContext<any, TEnv>)._currentSegmentId =
|
|
595
632
|
parallelId;
|
|
596
633
|
handlerRan = true;
|
|
634
|
+
const slotContext = withReverseScope(context, parallelEntry.reverseScope);
|
|
597
635
|
if (hasLoadingFallback) {
|
|
598
636
|
const result =
|
|
599
637
|
typeof handler === "function"
|
|
600
|
-
? runInSegmentTagScope(parallelId, handler,
|
|
638
|
+
? runInSegmentTagScope(parallelId, handler, slotContext)
|
|
601
639
|
: handler;
|
|
602
640
|
if (result instanceof Promise) {
|
|
603
641
|
warnOnStreamedResponse(result, parallelId);
|
|
@@ -616,7 +654,7 @@ async function resolveParallelSlotComponent<TEnv>(args: {
|
|
|
616
654
|
} else {
|
|
617
655
|
component =
|
|
618
656
|
typeof handler === "function"
|
|
619
|
-
? await runInSegmentTagScope(parallelId, handler,
|
|
657
|
+
? await runInSegmentTagScope(parallelId, handler, slotContext)
|
|
620
658
|
: handler;
|
|
621
659
|
}
|
|
622
660
|
}
|
|
@@ -697,8 +735,8 @@ export async function resolveParallelSegmentsWithRevalidation<TEnv>(
|
|
|
697
735
|
// emitted either before or after the slot segment per loaderOrder.
|
|
698
736
|
const resolveSlotLoaders = async () => {
|
|
699
737
|
if (resolvedParallelEntries.has(parallelEntry.id)) return;
|
|
700
|
-
const loaderResult = await
|
|
701
|
-
parallelEntry,
|
|
738
|
+
const loaderResult = await resolveOwnerLoaders(
|
|
739
|
+
ownerOf(parallelEntry, entry.shortCode),
|
|
702
740
|
context,
|
|
703
741
|
belongsToRoute,
|
|
704
742
|
clientSegmentIds,
|
|
@@ -709,7 +747,6 @@ export async function resolveParallelSegmentsWithRevalidation<TEnv>(
|
|
|
709
747
|
routeKey,
|
|
710
748
|
deps,
|
|
711
749
|
actionContext,
|
|
712
|
-
entry.shortCode,
|
|
713
750
|
stale,
|
|
714
751
|
);
|
|
715
752
|
segments.push(...loaderResult.segments);
|
|
@@ -1095,8 +1132,8 @@ export async function resolveSegmentWithRevalidation<TEnv>(
|
|
|
1095
1132
|
|
|
1096
1133
|
const belongsToRoute = entry.type === "route";
|
|
1097
1134
|
|
|
1098
|
-
const loaderResult = await
|
|
1099
|
-
entry,
|
|
1135
|
+
const loaderResult = await resolveOwnerLoaders(
|
|
1136
|
+
ownerOf(entry),
|
|
1100
1137
|
context,
|
|
1101
1138
|
belongsToRoute,
|
|
1102
1139
|
clientSegmentIds,
|
|
@@ -1107,7 +1144,6 @@ export async function resolveSegmentWithRevalidation<TEnv>(
|
|
|
1107
1144
|
routeKey,
|
|
1108
1145
|
deps,
|
|
1109
1146
|
actionContext,
|
|
1110
|
-
undefined,
|
|
1111
1147
|
stale,
|
|
1112
1148
|
);
|
|
1113
1149
|
segments.push(...loaderResult.segments);
|
|
@@ -1266,8 +1302,8 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
|
|
|
1266
1302
|
const segments: ResolvedSegment[] = [];
|
|
1267
1303
|
const matchedIds: string[] = [];
|
|
1268
1304
|
|
|
1269
|
-
const loaderResult = await
|
|
1270
|
-
orphan,
|
|
1305
|
+
const loaderResult = await resolveOwnerLoaders(
|
|
1306
|
+
ownerOf(orphan),
|
|
1271
1307
|
context,
|
|
1272
1308
|
belongsToRoute,
|
|
1273
1309
|
clientSegmentIds,
|
|
@@ -1278,7 +1314,6 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
|
|
|
1278
1314
|
routeKey,
|
|
1279
1315
|
deps,
|
|
1280
1316
|
actionContext,
|
|
1281
|
-
undefined,
|
|
1282
1317
|
stale,
|
|
1283
1318
|
);
|
|
1284
1319
|
segments.push(...loaderResult.segments);
|
|
@@ -1292,8 +1327,8 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
|
|
|
1292
1327
|
parentRouteEntry.loader.length > 0 &&
|
|
1293
1328
|
Object.keys(orphan.parallel).length > 0
|
|
1294
1329
|
) {
|
|
1295
|
-
const inheritedResult = await
|
|
1296
|
-
parentRouteEntry,
|
|
1330
|
+
const inheritedResult = await resolveOwnerLoaders(
|
|
1331
|
+
ownerOf(parentRouteEntry, orphan.shortCode),
|
|
1297
1332
|
context,
|
|
1298
1333
|
belongsToRoute,
|
|
1299
1334
|
clientSegmentIds,
|
|
@@ -1304,7 +1339,6 @@ export async function resolveOrphanLayoutWithRevalidation<TEnv>(
|
|
|
1304
1339
|
routeKey,
|
|
1305
1340
|
deps,
|
|
1306
1341
|
actionContext,
|
|
1307
|
-
orphan.shortCode,
|
|
1308
1342
|
stale,
|
|
1309
1343
|
);
|
|
1310
1344
|
// Tag as inherited so buildMatchResult can deduplicate when safe
|
|
@@ -1491,6 +1525,11 @@ export async function resolveAllSegmentsWithRevalidation<TEnv>(
|
|
|
1491
1525
|
latchPprHeaderScopeForEntries(entries, routeKey);
|
|
1492
1526
|
|
|
1493
1527
|
const telemetry = getRouterContext()?.telemetry;
|
|
1528
|
+
const fillMatch = {
|
|
1529
|
+
handlerContext: context,
|
|
1530
|
+
isIntercept: !!interceptResult,
|
|
1531
|
+
clientSegmentSet,
|
|
1532
|
+
};
|
|
1494
1533
|
|
|
1495
1534
|
for (const entry of entries) {
|
|
1496
1535
|
if (entry.type === "route" && interceptResult) {
|
|
@@ -1508,6 +1547,7 @@ export async function resolveAllSegmentsWithRevalidation<TEnv>(
|
|
|
1508
1547
|
}
|
|
1509
1548
|
continue;
|
|
1510
1549
|
}
|
|
1550
|
+
if (interceptFillSkips(fillMatch, entry.shortCode)) continue;
|
|
1511
1551
|
|
|
1512
1552
|
const nonParallelEntry = entry as Exclude<EntryData, { type: "parallel" }>;
|
|
1513
1553
|
// Same latch as resolveAllSegments (fresh.ts), route-level cache() included.
|
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
} from "../types";
|
|
7
7
|
import type { SegmentResolutionDeps } from "./types.js";
|
|
8
8
|
import type { ResolveSegmentOptions } from "./segment-resolution.js";
|
|
9
|
+
import type { RevalidationContext } from "./router-context.js";
|
|
9
10
|
|
|
10
11
|
import {
|
|
11
12
|
resolveAllSegments as _resolveAllSegments,
|
|
@@ -96,19 +97,15 @@ export interface SegmentWrappers<TEnv = any> {
|
|
|
96
97
|
context: HandlerContext<any, TEnv>,
|
|
97
98
|
belongsToRoute?: boolean,
|
|
98
99
|
revalidationContext?: any,
|
|
99
|
-
options?: {
|
|
100
|
+
options?: { background?: boolean },
|
|
100
101
|
) => Promise<ResolvedSegment[]>;
|
|
101
102
|
resolveInterceptLoadersOnly: (
|
|
102
103
|
interceptEntry: InterceptEntry,
|
|
103
104
|
parentEntry: EntryData,
|
|
104
|
-
params: Record<string, string>,
|
|
105
105
|
context: HandlerContext<any, TEnv>,
|
|
106
|
-
belongsToRoute
|
|
107
|
-
revalidationContext
|
|
108
|
-
) => Promise<
|
|
109
|
-
loaderDataPromise: Promise<any[]> | any[];
|
|
110
|
-
loaderIds: string[];
|
|
111
|
-
} | null>;
|
|
106
|
+
belongsToRoute: boolean,
|
|
107
|
+
revalidationContext: RevalidationContext,
|
|
108
|
+
) => Promise<ResolvedSegment[]>;
|
|
112
109
|
}
|
|
113
110
|
|
|
114
111
|
/**
|
|
@@ -250,7 +247,7 @@ export function createSegmentWrappers<TEnv = any>(
|
|
|
250
247
|
context: HandlerContext<any, TEnv>,
|
|
251
248
|
belongsToRoute: boolean = true,
|
|
252
249
|
revalidationContext?: any,
|
|
253
|
-
options?: {
|
|
250
|
+
options?: { background?: boolean },
|
|
254
251
|
): ReturnType<typeof _resolveInterceptEntry> {
|
|
255
252
|
return _resolveInterceptEntry(
|
|
256
253
|
interceptEntry,
|
|
@@ -267,15 +264,13 @@ export function createSegmentWrappers<TEnv = any>(
|
|
|
267
264
|
function resolveInterceptLoadersOnly(
|
|
268
265
|
interceptEntry: InterceptEntry,
|
|
269
266
|
parentEntry: EntryData,
|
|
270
|
-
params: Record<string, string>,
|
|
271
267
|
context: HandlerContext<any, TEnv>,
|
|
272
|
-
belongsToRoute: boolean
|
|
273
|
-
revalidationContext:
|
|
268
|
+
belongsToRoute: boolean,
|
|
269
|
+
revalidationContext: RevalidationContext,
|
|
274
270
|
): ReturnType<typeof _resolveInterceptLoadersOnly> {
|
|
275
271
|
return _resolveInterceptLoadersOnly(
|
|
276
272
|
interceptEntry,
|
|
277
273
|
parentEntry,
|
|
278
|
-
params,
|
|
279
274
|
context,
|
|
280
275
|
belongsToRoute,
|
|
281
276
|
segmentDeps,
|
|
@@ -20,8 +20,9 @@ import { parsePattern } from "./parse-pattern.js";
|
|
|
20
20
|
* omit when absent.
|
|
21
21
|
*
|
|
22
22
|
* Shared by `ctx.reverse()` (server), `createReverse()` (typed runtime
|
|
23
|
-
* helper),
|
|
24
|
-
*
|
|
23
|
+
* helper), `useReverse()` (client hook), and the include() mount fill of
|
|
24
|
+
* `useHref()` and relative `useRouter().push`. The behavior must stay
|
|
25
|
+
* identical across all of them.
|
|
25
26
|
*/
|
|
26
27
|
export function substitutePatternParams(
|
|
27
28
|
pattern: string,
|
package/src/router/tracing.ts
CHANGED
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
* registry; do not call traceSpan directly from new code.
|
|
25
25
|
*
|
|
26
26
|
* Phase coverage (all via observePhase): rango.request (span-only; handler:total
|
|
27
|
-
* metered directly), rango.middleware (span-only
|
|
28
|
-
*
|
|
27
|
+
* metered directly), rango.middleware (span-only; pre/post metered directly),
|
|
28
|
+
* rango.action (action:<id>; server-action
|
|
29
29
|
* execution, JS + no-JS/PE), rango.loader (loader:<id>; single metering site at
|
|
30
30
|
* useLoader, plus the fetchable path), rango.handler (span-only, one per segment
|
|
31
31
|
* route/layout handler execution; the handler:<id> perf metric is owned by the
|
package/src/router-versions.ts
CHANGED
|
@@ -33,24 +33,24 @@ export type RouterVersionsTable = Readonly<
|
|
|
33
33
|
/** Table key of the whole-build versions. Not a legal `$$id` (8 hex chars). */
|
|
34
34
|
export const DEFAULT_ROUTER_VERSIONS_KEY = "*";
|
|
35
35
|
|
|
36
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* One value for both versions: the dev stamp, the version a build-time shell
|
|
38
|
+
* capture is asked for, or a test's seed.
|
|
39
|
+
*/
|
|
37
40
|
export function uniformVersions(version: string): RouterVersions {
|
|
38
41
|
return { data: version, document: version };
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
/**
|
|
42
|
-
* The versions a router serves with under `table`:
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* tests) or it has neither entry. One function for the request handler and
|
|
45
|
+
* The versions a router serves with under `table`: the router's own entry,
|
|
46
|
+
* else the whole-build pair, for a router the table does not list.
|
|
47
|
+
* `undefined` when there is no table (dev, tests) or it has neither entry. One function for the request handler and
|
|
46
48
|
* the build's shell capture, which must stamp what the handler will check.
|
|
47
49
|
*/
|
|
48
50
|
export function resolveVersionsFrom(
|
|
49
51
|
table: RouterVersionsTable | undefined,
|
|
50
52
|
routerId: string | undefined,
|
|
51
|
-
override: string | undefined,
|
|
52
53
|
): RouterVersions | undefined {
|
|
53
|
-
if (override !== undefined) return uniformVersions(override);
|
|
54
54
|
if (!table) return undefined;
|
|
55
55
|
const pair =
|
|
56
56
|
(routerId !== undefined && Object.hasOwn(table, routerId)
|
package/src/router.ts
CHANGED
|
@@ -170,7 +170,6 @@ export function createRouter<TEnv = any>(
|
|
|
170
170
|
$$routeNames: staticRouteNames,
|
|
171
171
|
$$sourceFile: injectedSourceFile,
|
|
172
172
|
nonce,
|
|
173
|
-
version,
|
|
174
173
|
prefetchCacheTTL: prefetchCacheTTLOption,
|
|
175
174
|
prefetchCacheSize: prefetchCacheSizeOption,
|
|
176
175
|
prefetchConcurrency: prefetchConcurrencyOption,
|
|
@@ -276,14 +275,8 @@ export function createRouter<TEnv = any>(
|
|
|
276
275
|
);
|
|
277
276
|
|
|
278
277
|
// Resolve prefetch cache TTL (default: 300 seconds / 5 minutes). Clamps to a
|
|
279
|
-
// non-negative integer and guards non-finite (NaN/Infinity) inputs
|
|
280
|
-
|
|
281
|
-
const resolvedPrefetchCacheTTL = resolvePrefetchCacheTTL(
|
|
282
|
-
prefetchCacheTTLOption,
|
|
283
|
-
);
|
|
284
|
-
const prefetchCacheTTL = resolvedPrefetchCacheTTL.ms;
|
|
285
|
-
const prefetchCacheControl: string | false =
|
|
286
|
-
resolvedPrefetchCacheTTL.cacheControl;
|
|
278
|
+
// non-negative integer and guards non-finite (NaN/Infinity) inputs.
|
|
279
|
+
const prefetchCacheTTL = resolvePrefetchCacheTTL(prefetchCacheTTLOption).ms;
|
|
287
280
|
|
|
288
281
|
// Resolve client-side prefetch limits (in-memory cache size and queue
|
|
289
282
|
// concurrency). Both are positive-integer counts; sub-1/non-finite inputs
|
|
@@ -777,7 +770,7 @@ export function createRouter<TEnv = any>(
|
|
|
777
770
|
// handler's overlay read makes (resolvePrerenderVersion), so the keys agree.
|
|
778
771
|
const prerenderTrigger = createPrerenderTrigger<TEnv, {}>({
|
|
779
772
|
routerId,
|
|
780
|
-
resolveVersion: () => resolvePrerenderVersion(routerId
|
|
773
|
+
resolveVersion: () => resolvePrerenderVersion(routerId),
|
|
781
774
|
isDev: isDevEnvironment,
|
|
782
775
|
isViteDevServer,
|
|
783
776
|
ensureManifest: () => ensureRouterManifest(routerId),
|
|
@@ -809,7 +802,7 @@ export function createRouter<TEnv = any>(
|
|
|
809
802
|
{},
|
|
810
803
|
{
|
|
811
804
|
...prerenderDeps,
|
|
812
|
-
versions: resolveRouterVersions(routerId
|
|
805
|
+
versions: resolveRouterVersions(routerId),
|
|
813
806
|
},
|
|
814
807
|
undefined,
|
|
815
808
|
isPassthrough,
|
|
@@ -818,7 +811,7 @@ export function createRouter<TEnv = any>(
|
|
|
818
811
|
true,
|
|
819
812
|
),
|
|
820
813
|
// A warm goes through router.fetch's handler: the one createRouter's own
|
|
821
|
-
// cache
|
|
814
|
+
// cache and nonce configure. An entry that passes them to
|
|
822
815
|
// createRSCHandler itself is not what a warm runs.
|
|
823
816
|
resolveCacheConfig: (env, ctx) =>
|
|
824
817
|
typeof cache === "function" ? cache(env, ctx) : cache,
|
|
@@ -1153,7 +1146,6 @@ export function createRouter<TEnv = any>(
|
|
|
1153
1146
|
cacheProfiles: resolvedCacheProfiles,
|
|
1154
1147
|
|
|
1155
1148
|
// Expose prefetch cache settings
|
|
1156
|
-
prefetchCacheControl,
|
|
1157
1149
|
prefetchCacheTTL,
|
|
1158
1150
|
prefetchCacheSize,
|
|
1159
1151
|
prefetchConcurrency,
|
|
@@ -1229,9 +1221,6 @@ export function createRouter<TEnv = any>(
|
|
|
1229
1221
|
// Expose nonce provider for fetch
|
|
1230
1222
|
nonce,
|
|
1231
1223
|
|
|
1232
|
-
// Expose version for fetch
|
|
1233
|
-
version,
|
|
1234
|
-
|
|
1235
1224
|
// Expose urlpatterns for runtime manifest generation
|
|
1236
1225
|
get urlpatterns() {
|
|
1237
1226
|
return storedUrlPatterns ?? undefined;
|
|
@@ -1299,7 +1288,6 @@ export function createRouter<TEnv = any>(
|
|
|
1299
1288
|
router: router as any,
|
|
1300
1289
|
cache,
|
|
1301
1290
|
nonce,
|
|
1302
|
-
version,
|
|
1303
1291
|
}) as (
|
|
1304
1292
|
request: Request,
|
|
1305
1293
|
input: RouterRequestInput<TEnv>,
|