@rangojs/router 0.31.0 → 0.33.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 +3 -2
- package/dist/bin/browser-7KIJ5HSV.js +15 -0
- package/dist/bin/chunk-3B7CKBRO.js +463 -0
- package/dist/bin/chunk-524VACCG.js +71 -0
- package/dist/bin/chunk-LD7UBHT4.js +196 -0
- package/dist/bin/chunk-TO6CRWLN.js +1429 -0
- package/dist/bin/chunk-TTXC2U3G.js +2477 -0
- package/dist/bin/client-urls-projection-DQLWPDAT.js +28 -0
- package/dist/bin/forward-user-plugins-URBZKJP4.js +62 -0
- package/dist/bin/rango.js +42 -10143
- package/dist/bin/runtime-EPUDEHO4.js +596 -0
- package/dist/bin/runtime-discovery-CZ2QHT4Q.js +352 -0
- package/dist/bin/state-ACD2MGKJ.js +16 -0
- package/dist/bin/temp-rsc-server-QRR6HD6T.js +3190 -0
- package/dist/types/bin/rango.d.ts +1 -0
- package/dist/types/browser/action-fence.d.ts +20 -0
- package/dist/types/browser/cookie-name.d.ts +51 -10
- package/dist/types/browser/history-state.d.ts +13 -2
- package/dist/types/browser/invalidate-client-cache.d.ts +8 -6
- package/dist/types/browser/navigation-bridge.d.ts +36 -1
- package/dist/types/browser/navigation-client.d.ts +19 -0
- package/dist/types/browser/navigation-store-handle.d.ts +37 -4
- package/dist/types/browser/navigation-store.d.ts +2 -2
- package/dist/types/browser/navigation-transaction.d.ts +0 -1
- package/dist/types/browser/partial-update.d.ts +13 -0
- package/dist/types/browser/prefetch/cache.d.ts +96 -8
- package/dist/types/browser/prefetch/fetch.d.ts +26 -2
- package/dist/types/browser/prefetch/queue.d.ts +3 -2
- package/dist/types/browser/rango-state.d.ts +34 -5
- package/dist/types/browser/react/Link.d.ts +19 -13
- package/dist/types/browser/react/location-state-shared.d.ts +2 -1
- package/dist/types/browser/types.d.ts +25 -0
- package/dist/types/build/generate-route-types.d.ts +1 -1
- package/dist/types/build/route-types/include-resolution.d.ts +9 -1
- package/dist/types/build/route-types/router-processing.d.ts +3 -1
- package/dist/types/cache/cache-key-utils.d.ts +12 -8
- package/dist/types/cache/cache-scope.d.ts +4 -2
- package/dist/types/cache/cf/cf-cache-types.d.ts +9 -5
- package/dist/types/cache/document-cache-policy.d.ts +9 -1
- package/dist/types/cache/memory-segment-store.d.ts +3 -2
- package/dist/types/cache/segment-codec.d.ts +2 -2
- package/dist/types/cache/shell-snapshot.d.ts +1 -1
- package/dist/types/cache/types.d.ts +12 -7
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +2 -1
- package/dist/types/client-urls/types.d.ts +7 -5
- package/dist/types/prefetch-markers.d.ts +9 -0
- package/dist/types/prefetch-source-scope.d.ts +66 -0
- package/dist/types/route-definition/helpers-types.d.ts +8 -5
- package/dist/types/route-definition/redirect.d.ts +5 -0
- package/dist/types/router/intercept-resolution.d.ts +25 -11
- package/dist/types/router/match-context.d.ts +1 -0
- package/dist/types/router/match-handlers.d.ts +1 -1
- package/dist/types/router/middleware-types.d.ts +6 -0
- package/dist/types/router/prefetch-cache-ttl.d.ts +11 -3
- package/dist/types/router/router-context.d.ts +1 -1
- package/dist/types/router/router-options.d.ts +6 -3
- package/dist/types/router/segment-resolution/loader-cache.d.ts +8 -0
- package/dist/types/router/segment-resolution/prefetch-deferral.d.ts +23 -7
- package/dist/types/router/segment-resolution/revalidation.d.ts +19 -0
- package/dist/types/router/source-reads.d.ts +53 -0
- package/dist/types/router/types.d.ts +1 -1
- package/dist/types/rsc/helpers.d.ts +8 -3
- package/dist/types/rsc/prefetch-render-error.d.ts +7 -2
- package/dist/types/rsc/request-stages.d.ts +4 -0
- package/dist/types/rsc/shell-serve.d.ts +6 -1
- package/dist/types/server/context.d.ts +23 -6
- package/dist/types/server/cookie-store.d.ts +15 -1
- package/dist/types/server/document-location-state.d.ts +59 -0
- package/dist/types/server/handle-store.d.ts +2 -0
- package/dist/types/server/request-context.d.ts +65 -12
- package/dist/types/testing/e2e/server.d.ts +16 -1
- package/dist/types/testing/render-route.d.ts +83 -2
- package/dist/types/testing/serve-shell-request.d.ts +15 -3
- package/dist/types/types/handler-context.d.ts +21 -4
- package/dist/types/types/loader-types.d.ts +7 -4
- package/dist/types/types/segments.d.ts +18 -1
- package/dist/types/urls/path-helper-types.d.ts +7 -5
- package/dist/types/vite/temp-rsc-server.d.ts +2 -2
- package/dist/types/vite/utils/forward-user-plugins.d.ts +32 -2
- package/dist/vite/index.js +451 -191
- package/package.json +2 -2
- package/skills/app-structure/SKILL.md +74 -0
- package/skills/app-structure/e-commerce.md +10 -9
- package/skills/app-structure/large-app.md +15 -2
- package/skills/caching/SKILL.md +10 -5
- package/skills/client-urls/SKILL.md +18 -11
- package/skills/comparison/references/framework-comparison.md +16 -10
- package/skills/document-cache/SKILL.md +13 -0
- package/skills/hooks/navigation.md +8 -8
- package/skills/hooks/state.md +132 -12
- package/skills/intercept/SKILL.md +33 -11
- package/skills/layout/SKILL.md +11 -0
- package/skills/links/SKILL.md +101 -4
- package/skills/loader/SKILL.md +49 -22
- package/skills/migrate-nextjs/SKILL.md +8 -2
- package/skills/migrate-react-router/data-and-actions.md +5 -0
- package/skills/ppr/SKILL.md +38 -5
- package/skills/prerender/SKILL.md +4 -1
- package/skills/route/SKILL.md +6 -6
- package/skills/router-setup/SKILL.md +2 -1
- package/skills/server-actions/SKILL.md +49 -8
- package/skills/testing/client-components.md +73 -32
- package/skills/testing/serve-shell-request.md +45 -20
- package/skills/testing/server-actions.md +8 -0
- package/skills/ux-architecture/SKILL.md +67 -15
- package/src/bin/rango.ts +39 -13
- package/src/browser/action-fence.ts +72 -0
- package/src/browser/cookie-name.ts +82 -14
- package/src/browser/history-state.ts +24 -2
- package/src/browser/invalidate-client-cache.ts +9 -7
- package/src/browser/navigation-bridge.ts +164 -32
- package/src/browser/navigation-client.ts +95 -20
- package/src/browser/navigation-store-handle.ts +67 -5
- package/src/browser/navigation-store.ts +86 -17
- package/src/browser/navigation-transaction.ts +0 -6
- package/src/browser/partial-update.ts +31 -12
- package/src/browser/prefetch/cache.ts +188 -11
- package/src/browser/prefetch/fetch.ts +211 -51
- package/src/browser/prefetch/queue.ts +3 -2
- package/src/browser/rango-state.ts +50 -8
- package/src/browser/react/Link.tsx +24 -16
- package/src/browser/react/location-state-shared.ts +8 -1
- package/src/browser/react/use-navigation.ts +1 -1
- package/src/browser/rsc-router.tsx +13 -3
- package/src/browser/server-action-bridge.ts +3 -3
- package/src/browser/types.ts +25 -0
- package/src/build/generate-route-types.ts +1 -0
- package/src/build/route-types/include-resolution.ts +40 -3
- package/src/build/route-types/router-processing.ts +170 -25
- package/src/build/route-types/scan-filter.ts +1 -0
- package/src/build/runtime-discovery.ts +46 -8
- package/src/cache/cache-key-utils.ts +12 -8
- package/src/cache/cache-runtime.ts +5 -1
- package/src/cache/cache-scope.ts +28 -7
- package/src/cache/cf/cf-cache-types.ts +9 -5
- package/src/cache/document-cache-policy.ts +37 -1
- package/src/cache/document-cache.ts +12 -0
- package/src/cache/memory-segment-store.ts +3 -2
- package/src/cache/segment-codec.ts +2 -2
- package/src/cache/shell-snapshot.ts +1 -1
- package/src/cache/types.ts +12 -7
- package/src/cache/vercel/vercel-cache-store.ts +2 -1
- package/src/client-urls/types.ts +7 -5
- package/src/prefetch-markers.ts +10 -0
- package/src/prefetch-source-scope.ts +137 -0
- package/src/route-definition/helpers-types.ts +8 -5
- package/src/route-definition/redirect.ts +5 -0
- package/src/router/intercept-resolution.ts +94 -50
- package/src/router/loader-resolution.ts +8 -6
- package/src/router/match-api.ts +33 -29
- package/src/router/match-context.ts +5 -0
- package/src/router/match-handlers.ts +2 -1
- package/src/router/match-middleware/cache-lookup.ts +39 -14
- package/src/router/match-result.ts +45 -85
- package/src/router/middleware-types.ts +6 -0
- package/src/router/navigation-snapshot.ts +18 -3
- package/src/router/prefetch-cache-ttl.ts +15 -3
- package/src/router/revalidation.ts +63 -13
- package/src/router/router-context.ts +2 -1
- package/src/router/router-options.ts +6 -3
- package/src/router/segment-resolution/loader-cache.ts +21 -3
- package/src/router/segment-resolution/prefetch-deferral.ts +38 -31
- package/src/router/segment-resolution/revalidation.ts +40 -12
- package/src/router/source-reads.ts +122 -0
- package/src/router/types.ts +2 -1
- package/src/router.ts +11 -12
- package/src/rsc/helpers.ts +20 -6
- package/src/rsc/prefetch-render-error.ts +7 -2
- package/src/rsc/progressive-enhancement.ts +8 -2
- package/src/rsc/request-stages.ts +87 -1
- package/src/rsc/rsc-rendering.ts +78 -32
- package/src/rsc/server-action.ts +2 -1
- package/src/rsc/shell-capture.ts +4 -5
- package/src/rsc/shell-serve.ts +12 -1
- package/src/segment-system.tsx +1 -1
- package/src/server/context.ts +37 -6
- package/src/server/cookie-store.ts +22 -1
- package/src/server/document-location-state.ts +334 -0
- package/src/server/handle-store.ts +2 -0
- package/src/server/request-context.ts +137 -33
- package/src/testing/dispatch.ts +6 -0
- package/src/testing/e2e/fixture.ts +4 -12
- package/src/testing/e2e/server.ts +91 -4
- package/src/testing/render-route.tsx +309 -10
- package/src/testing/run-revalidate.ts +11 -1
- package/src/testing/serve-shell-request.ts +22 -3
- package/src/types/handler-context.ts +21 -4
- package/src/types/loader-types.ts +7 -4
- package/src/types/segments.ts +18 -1
- package/src/urls/path-helper-types.ts +7 -5
- package/src/vite/temp-rsc-server.ts +2 -2
- package/src/vite/utils/forward-user-plugins.ts +13 -5
|
@@ -31,6 +31,7 @@ import type { RoutineTrace } from "../rsc/routine-plan.js";
|
|
|
31
31
|
import type { ActionContinuation } from "../rsc/server-action.js";
|
|
32
32
|
import type { ShellCaptureState } from "../rsc/shell-capture.js";
|
|
33
33
|
import type { FormActionOutcome } from "../rsc/progressive-enhancement.js";
|
|
34
|
+
import { type RequestKind } from "../router/segment-resolution/prefetch-deferral.js";
|
|
34
35
|
import { type ExecutionStart } from "../cache/invalidation-order.js";
|
|
35
36
|
export interface RenderForegroundCursor {
|
|
36
37
|
mode: RenderMode;
|
|
@@ -119,8 +120,12 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
119
120
|
setStatus(status: number): void;
|
|
120
121
|
/** @internal Set status bypassing cache-exec guard (for framework error handling) */
|
|
121
122
|
_setStatus(status: number): void;
|
|
122
|
-
/**
|
|
123
|
-
|
|
123
|
+
/**
|
|
124
|
+
* @internal Rotate the rango state cookie: its timestamp (the server seat of
|
|
125
|
+
* invalidateClientCache), or with `"write"` only its write part (a server
|
|
126
|
+
* action without a directive, cookie-store.ts runActionBody).
|
|
127
|
+
*/
|
|
128
|
+
_rotateStateCookie(part?: "write"): void;
|
|
124
129
|
/** @internal Set the keepClientCache() directive header on the response. */
|
|
125
130
|
_setKeepCacheDirective(): void;
|
|
126
131
|
/**
|
|
@@ -532,11 +537,28 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
532
537
|
*/
|
|
533
538
|
_payloadDeferred?: boolean;
|
|
534
539
|
/**
|
|
535
|
-
* @internal
|
|
536
|
-
*
|
|
537
|
-
*
|
|
540
|
+
* @internal Set by the RSC handler when a partial response carries an
|
|
541
|
+
* `x-rsc-prefetch-scope` (router/source-reads.ts prefetchScopeOf): its diff
|
|
542
|
+
* is right for its source page, or a group of them, only. The document
|
|
543
|
+
* cache keys a partial without its source, so it does not store that
|
|
544
|
+
* response, whatever Cache-Control it ends up with.
|
|
545
|
+
*/
|
|
546
|
+
_payloadSourceScoped?: boolean;
|
|
547
|
+
/**
|
|
548
|
+
* @internal Set when the answer has nothing live in it, so nothing in it can
|
|
549
|
+
* fail after the 200's headers left: the document cache middleware on a
|
|
550
|
+
* fresh HIT, and the RSC handler when the partial match came from storage
|
|
551
|
+
* (MatchResult.fromStorage). finalizeRequestResponse (rsc/request-stages.ts)
|
|
552
|
+
* sends such a prefetch the router's prefetch Cache-Control.
|
|
553
|
+
*/
|
|
554
|
+
_servedFromStorage?: boolean;
|
|
555
|
+
/**
|
|
556
|
+
* @internal What the request says it is: a speculative `<Link>` prefetch,
|
|
557
|
+
* an intent prefetch (hover, `prefetch()`) or a fill (`prefetch: false`),
|
|
558
|
+
* read once at creation (segment-resolution/prefetch-deferral.ts
|
|
559
|
+
* requestKind).
|
|
538
560
|
*/
|
|
539
|
-
_requestKind?:
|
|
561
|
+
_requestKind?: RequestKind;
|
|
540
562
|
/**
|
|
541
563
|
* @internal Set when a render shows the visitor's URL of a rewritten
|
|
542
564
|
* request: the payload or SSR seed (renderedLocation, rsc/full-payload.ts)
|
|
@@ -547,12 +569,27 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
547
569
|
/**
|
|
548
570
|
* Attach location state entries to the current response.
|
|
549
571
|
*
|
|
550
|
-
* For
|
|
551
|
-
* metadata and merged into history.
|
|
552
|
-
*
|
|
553
|
-
*
|
|
572
|
+
* For a client navigation or an action, the state is included in the RSC
|
|
573
|
+
* payload metadata and merged into the entry's history.state on the
|
|
574
|
+
* client. For a document request (a page load, a no-JS form post), it rides
|
|
575
|
+
* the document's bootstrap payload and is merged into the entry when the
|
|
576
|
+
* client starts; readers get it once the page has hydrated. For a redirect,
|
|
577
|
+
* the state travels with the redirect: in its Flight payload on a
|
|
578
|
+
* navigation or action, in a one-shot cookie the target's document request
|
|
579
|
+
* reads on a document request. A document that carries state is sent
|
|
580
|
+
* `Cache-Control: private, no-store` and never stored by the document cache
|
|
581
|
+
* or as a PPR shell.
|
|
554
582
|
*
|
|
555
|
-
*
|
|
583
|
+
* Call it from middleware, a handler or an action. A loader's call
|
|
584
|
+
* (through `getRequestContext()`) is not supported: the payload takes the
|
|
585
|
+
* state before loaders settle, so the write may be dropped, and a PPR
|
|
586
|
+
* shell HIT never sends it.
|
|
587
|
+
*
|
|
588
|
+
* Multiple calls accumulate entries across definitions. For one definition
|
|
589
|
+
* the last write wins: two entries of the same definition share its slot
|
|
590
|
+
* in history.state, so a later call (or a later entry in one array)
|
|
591
|
+
* replaces an earlier one. To combine writes, make the state an array and
|
|
592
|
+
* write it once.
|
|
556
593
|
*
|
|
557
594
|
* @example
|
|
558
595
|
* ```typescript
|
|
@@ -562,6 +599,22 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
562
599
|
setLocationState(entries: LocationStateEntry | LocationStateEntry[]): void;
|
|
563
600
|
/** @internal Accumulated location state entries */
|
|
564
601
|
_locationState?: LocationStateEntry[];
|
|
602
|
+
/**
|
|
603
|
+
* @internal Set when a document's payload carries location state
|
|
604
|
+
* (rsc/rsc-rendering.ts, rsc/progressive-enhancement.ts), a shell HIT's
|
|
605
|
+
* included. The document is per visitor: the document cache refuses it,
|
|
606
|
+
* and it leaves `private, no-store` (server/document-location-state.ts).
|
|
607
|
+
*/
|
|
608
|
+
_documentLocationState?: boolean;
|
|
609
|
+
/**
|
|
610
|
+
* @internal The `document.cookie` line that re-creates the location state
|
|
611
|
+
* cookie this request consumed (server/document-location-state.ts). The
|
|
612
|
+
* consuming response clears the cookie in its headers; a shell HIT that
|
|
613
|
+
* degrades into a reload after those headers left writes this line first
|
|
614
|
+
* (rsc/shell-serve.ts shellReloadScript), so the reload reads the state
|
|
615
|
+
* again.
|
|
616
|
+
*/
|
|
617
|
+
_carriedLocationStateCookie?: string;
|
|
565
618
|
/**
|
|
566
619
|
* The matched route name, if the route has an explicit name.
|
|
567
620
|
* Undefined before route matching or for unnamed routes.
|
|
@@ -795,7 +848,7 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
795
848
|
* This is the type exported to library consumers. Internal code should
|
|
796
849
|
* use the full RequestContext interface directly.
|
|
797
850
|
*/
|
|
798
|
-
export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, string>> = Omit<RequestContext<TEnv, TParams>, "cookie" | "cookies" | "_readCookie" | "_readCookies" | "setCookie" | "deleteCookie" | "_handleStore" | "_transitionWhenRefs" | "_pprReplayPostMatchReason" | "_cacheStore" | "_prerender" | "_onDemandProducer" | "_searchParamsFilter" | "_shellCaptureState" | "_shellImplicitCache" | "_shellLoaderSeed" | "_resolvedCacheKeys" | "_shellKey" | "_shellForcedMiss" | "_prerenderWarm" | "_runAtRequestEntry" | "_shellFragmentPayload" | "_explicitTaggedStores" | "_requestTags" | "_recordTagOwners" | "_recordLoaderTags" | "_cacheProfiles" | "_onResponseCallbacks" | "_pendingBackgroundTasks" | "_themeConfig" | "_readTheme" | "_documentCacheRender" | "_payloadVisitorTheme" | "_payloadDeferred" | "_requestKind" | "_payloadVisitorLocation" | "_locationState" | "_routeName" | "_prevRouteKey" | "_visitorMoved" | "_inActionRevalidation" | "_actionRan" | "_reportedErrors" | "_throwers" | "_printedErrors" | "_renderErrors" | "_recoveredHandlerErrors" | "_renderBarrier" | "_resolveRenderBarrier" | "_renderBarrierSegmentOrder" | "_treeHasStreaming" | "_renderBarrierWaiters" | "_handlerLoaderDeps" | "_awaitBeforeFlushLoaderIds" | "_renderBarrierHandleSnapshot" | "_renderBarrierGuardClosed" | "_reportBackgroundError" | "_debugPerformance" | "_metricsStore" | "_renderForeground" | "_activeRoutine" | "_renderDiagnosticsEnabled" | "_handlerStart" | "_handlerTiming" | "_tracing" | "_basename" | "_routerId" | "_versions" | "_setStatus" | "_rotateStateCookie" | "_setKeepCacheDirective" | "_freshReads" | "_setFreshReadsCookie" | "_requestRoot" | "_requestStart" | "_responseSent" | "_variables" | "_classifiedRoute" | "_requestMode" | "_cacheSignal" | "_dynamic" | "res">;
|
|
851
|
+
export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, string>> = Omit<RequestContext<TEnv, TParams>, "cookie" | "cookies" | "_readCookie" | "_readCookies" | "setCookie" | "deleteCookie" | "_handleStore" | "_transitionWhenRefs" | "_pprReplayPostMatchReason" | "_cacheStore" | "_prerender" | "_onDemandProducer" | "_searchParamsFilter" | "_shellCaptureState" | "_shellImplicitCache" | "_shellLoaderSeed" | "_resolvedCacheKeys" | "_shellKey" | "_shellForcedMiss" | "_prerenderWarm" | "_runAtRequestEntry" | "_shellFragmentPayload" | "_explicitTaggedStores" | "_requestTags" | "_recordTagOwners" | "_recordLoaderTags" | "_cacheProfiles" | "_onResponseCallbacks" | "_pendingBackgroundTasks" | "_themeConfig" | "_readTheme" | "_documentCacheRender" | "_payloadVisitorTheme" | "_payloadDeferred" | "_payloadSourceScoped" | "_servedFromStorage" | "_requestKind" | "_payloadVisitorLocation" | "_locationState" | "_documentLocationState" | "_carriedLocationStateCookie" | "_routeName" | "_prevRouteKey" | "_visitorMoved" | "_inActionRevalidation" | "_actionRan" | "_reportedErrors" | "_throwers" | "_printedErrors" | "_renderErrors" | "_recoveredHandlerErrors" | "_renderBarrier" | "_resolveRenderBarrier" | "_renderBarrierSegmentOrder" | "_treeHasStreaming" | "_renderBarrierWaiters" | "_handlerLoaderDeps" | "_awaitBeforeFlushLoaderIds" | "_renderBarrierHandleSnapshot" | "_renderBarrierGuardClosed" | "_reportBackgroundError" | "_debugPerformance" | "_metricsStore" | "_renderForeground" | "_activeRoutine" | "_renderDiagnosticsEnabled" | "_handlerStart" | "_handlerTiming" | "_tracing" | "_basename" | "_routerId" | "_versions" | "_setStatus" | "_rotateStateCookie" | "_setKeepCacheDirective" | "_freshReads" | "_setFreshReadsCookie" | "_requestRoot" | "_requestStart" | "_responseSent" | "_variables" | "_classifiedRoute" | "_requestMode" | "_cacheSignal" | "_dynamic" | "res">;
|
|
799
852
|
/**
|
|
800
853
|
* Marker for a waitUntil-scheduled fn whose task promise must NOT enter
|
|
801
854
|
* _pendingBackgroundTasks. Used by the PPR shell capture for its own task:
|
|
@@ -11,7 +11,13 @@ export interface RunCliHandle {
|
|
|
11
11
|
*/
|
|
12
12
|
exitCode: Promise<number | null>;
|
|
13
13
|
findPort: (timeoutMs?: number) => Promise<number>;
|
|
14
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Stop the process and what it spawned (the whole process group). SIGTERM by
|
|
16
|
+
* default; `stopServer` escalates to SIGKILL for a process that outlives the
|
|
17
|
+
* wait.
|
|
18
|
+
*/
|
|
19
|
+
kill: (signal?: NodeJS.Signals) => void;
|
|
20
|
+
readonly pid: number | undefined;
|
|
15
21
|
stdout: () => string;
|
|
16
22
|
stderr: () => string;
|
|
17
23
|
}
|
|
@@ -19,6 +25,15 @@ export declare function runCli(options: {
|
|
|
19
25
|
command: string;
|
|
20
26
|
label?: string;
|
|
21
27
|
} & SpawnOptions): RunCliHandle;
|
|
28
|
+
/**
|
|
29
|
+
* Stop a server started by `runCli` and wait for its whole process group to
|
|
30
|
+
* exit: SIGTERM to the group, then SIGKILL (and a log naming the pid) for a
|
|
31
|
+
* process that outlives the wait, so a leaked server is visible rather than
|
|
32
|
+
* left holding its port.
|
|
33
|
+
*/
|
|
34
|
+
export declare function stopServer(server: RunCliHandle, options?: {
|
|
35
|
+
exitWaitMs?: number;
|
|
36
|
+
}): Promise<void>;
|
|
22
37
|
export declare function tailOutput(text: string, maxChars?: number): string;
|
|
23
38
|
export declare function createIsolatedViteCacheDir(cwd: string, projectName: string, mode: "dev" | "build" | undefined): string;
|
|
24
39
|
export declare function waitForReady(url: string, getOutput?: () => {
|
|
@@ -35,6 +35,16 @@
|
|
|
35
35
|
* not modeled). navigate(url, { streamUntil }) gives the navigation a
|
|
36
36
|
* response stream that stays open past the commit (isStreaming).
|
|
37
37
|
* useAction().state stays idle: no action runs.
|
|
38
|
+
* - prefetch(url) keeps a page as a prefetch made now carries it, and
|
|
39
|
+
* action() lands a server action's response: the page on screen
|
|
40
|
+
* re-renders with its post-write loader data, and, without
|
|
41
|
+
* `keepClientCache`, production's store marks every history entry and
|
|
42
|
+
* prefetch stale (browser/navigation-store.ts). A navigate(url) to a
|
|
43
|
+
* prefetched page commits the prefetch's data; when an action made it
|
|
44
|
+
* stale, the page then revalidates once the navigation settled, in the
|
|
45
|
+
* lane production's Back uses (useNavigation() idle), with the loader
|
|
46
|
+
* data current then. The prefetch request, its decode and the HTTP cache
|
|
47
|
+
* are e2e territory.
|
|
38
48
|
* - A spec's transition({ when }) decides every commit with production's
|
|
39
49
|
* browser decision: navigate() and useRouter().push model kind "push",
|
|
40
50
|
* useRouter().replace kind "replace", refresh() kind "revalidate", and a
|
|
@@ -49,8 +59,8 @@
|
|
|
49
59
|
* written there, and another page is on screen, its page is restored
|
|
50
60
|
* from the history cache, with the handle values it had, as production's
|
|
51
61
|
* restore is; otherwise the tree keeps its location. A stale entry's
|
|
52
|
-
* revalidation, a restore that fetches, a server action's
|
|
53
|
-
* redirect's and an intercept's are e2e territory.
|
|
62
|
+
* revalidation on Back, a restore that fetches, a server action's
|
|
63
|
+
* location state, a redirect's and an intercept's are e2e territory.
|
|
54
64
|
* What it DOES cover: client hooks that read NavigationProvider /
|
|
55
65
|
* OutletContext — useParams, useReverse, useHref, useMount, useNavigation,
|
|
56
66
|
* useRouter, usePathname, useSearchParams, Outlet/useOutlet nesting and seeded
|
|
@@ -185,6 +195,23 @@ export interface RenderRouteOptions {
|
|
|
185
195
|
* });
|
|
186
196
|
*/
|
|
187
197
|
locationState?: ReadonlyArray<readonly [LocationStateDefinition<any, any>, unknown]>;
|
|
198
|
+
/**
|
|
199
|
+
* Location state the document response carries, as `[def, value]` pairs:
|
|
200
|
+
* what a handler, middleware or no-JS form action set with
|
|
201
|
+
* `ctx.setLocationState()` (or a document redirect carried) for this page
|
|
202
|
+
* load. Merged into the entry at start-up as initBrowserApp merges the
|
|
203
|
+
* bootstrap payload's: after `locationState` and, with `hydrate: true`,
|
|
204
|
+
* after the `clearOnReload` pass, so a `clearOnReload` slot given here is
|
|
205
|
+
* applied. With `hydrate: true` a reader hydrates as `undefined` and gets
|
|
206
|
+
* the value once the root has hydrated.
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* await renderRoute([{ path: "/", Component: FlashBanner }], {
|
|
210
|
+
* hydrate: true,
|
|
211
|
+
* documentLocationState: [[FlashMessage, { text: "Payment declined" }]],
|
|
212
|
+
* });
|
|
213
|
+
*/
|
|
214
|
+
documentLocationState?: ReadonlyArray<readonly [LocationStateDefinition<any, any>, unknown]>;
|
|
188
215
|
/**
|
|
189
216
|
* Handles to seed by REFERENCE, for components that read handle output via
|
|
190
217
|
* `useHandle(SomeHandle)` (e.g. a client `Breadcrumbs` trail). Each entry is
|
|
@@ -403,6 +430,60 @@ export interface TestRouterHandle {
|
|
|
403
430
|
* transition({ when }) decides it with kind "revalidate" (`to` is `from`).
|
|
404
431
|
*/
|
|
405
432
|
refresh(): Promise<void>;
|
|
433
|
+
/**
|
|
434
|
+
* Prefetch `url`, as a `<Link>` hover or viewport trigger does: the page is
|
|
435
|
+
* kept with the loader data its response would carry now (the render-time
|
|
436
|
+
* seeds, `options.loaders` merged over). A later `navigate(url)` without
|
|
437
|
+
* `loaders` commits that data, whatever the seeds are by then.
|
|
438
|
+
*
|
|
439
|
+
* The prefetch is stamped with production's stale epoch
|
|
440
|
+
* (browser/prefetch/cache.ts): an `action()` without `keepClientCache`
|
|
441
|
+
* makes it stale. A click on a stale prefetch commits it at once, then the
|
|
442
|
+
* page revalidates once the navigation settled (its `streamUntil` ended),
|
|
443
|
+
* in Back's stale-revalidation lane: `useNavigation().state` stays "idle"
|
|
444
|
+
* and `isNavigating` reads true while its request is open, `useLinkStatus`
|
|
445
|
+
* shows no pending state, and the commit runs through commitInTransition
|
|
446
|
+
* with kind "revalidate", reading the loader data current then. A newer
|
|
447
|
+
* navigation aborts it.
|
|
448
|
+
*
|
|
449
|
+
* @example
|
|
450
|
+
* router.prefetch("/cart"); // carries count 2
|
|
451
|
+
* await router.action({ loaders: [[BasketLoader, { count: 3 }]] });
|
|
452
|
+
* await router.navigate("/cart"); // count 2, at once
|
|
453
|
+
* await waitFor(() => expect(count()).toBe("3")); // revalidated
|
|
454
|
+
*/
|
|
455
|
+
prefetch(url: string, options?: Pick<RenderRouteOptions, "loaders">): void;
|
|
456
|
+
/**
|
|
457
|
+
* Land a server action's response on the page on screen. `loaders` are the
|
|
458
|
+
* loader values after the action's write: they become the data every
|
|
459
|
+
* later response carries, and the page on screen re-renders with them in
|
|
460
|
+
* the action lane (commitInTransition, kind "action", unless
|
|
461
|
+
* transition({ when }) gates it off). Without `keepClientCache`,
|
|
462
|
+
* production's store then marks every history entry and every prefetch
|
|
463
|
+
* stale (`markCacheAsStaleAndBroadcast()`), as the action bridge does:
|
|
464
|
+
* nothing is flushed and the state cookie is not rotated.
|
|
465
|
+
* `keepClientCache: true` is the `keepClientCache()` directive: caches stay
|
|
466
|
+
* fresh. The action's own lifecycle (`useAction()`), its follow-up and its
|
|
467
|
+
* redirect are e2e territory.
|
|
468
|
+
*/
|
|
469
|
+
action(options?: Pick<RenderRouteOptions, "loaders"> & {
|
|
470
|
+
keepClientCache?: boolean;
|
|
471
|
+
}): Promise<void>;
|
|
472
|
+
/**
|
|
473
|
+
* The background revalidations a click on a stale prefetch started, in
|
|
474
|
+
* order: the page's pathname and search, and the segment ids the request
|
|
475
|
+
* holds, as production's bridge plans them
|
|
476
|
+
* (navigation-bridge.ts scheduleStalePrefetchRevalidation). A click on a
|
|
477
|
+
* fresh prefetch, or after a `keepClientCache` action, starts none.
|
|
478
|
+
*
|
|
479
|
+
* @example
|
|
480
|
+
* await router.navigate("/cart"); // a stale prefetch
|
|
481
|
+
* await waitFor(() => expect(router.revalidations()).toHaveLength(1));
|
|
482
|
+
*/
|
|
483
|
+
revalidations(): ReadonlyArray<{
|
|
484
|
+
url: string;
|
|
485
|
+
segmentIds: string[];
|
|
486
|
+
}>;
|
|
406
487
|
/** The current committed pathname. */
|
|
407
488
|
pathname(): string;
|
|
408
489
|
/** The current committed params. */
|
|
@@ -65,9 +65,12 @@ export interface ServeShellRequestOptions<TEnv = any> {
|
|
|
65
65
|
* (default none), advertising fragment passthrough. The replay decision is
|
|
66
66
|
* `result.replayStatus`.
|
|
67
67
|
*
|
|
68
|
-
* `prefetch: true` sends
|
|
69
|
-
* `X-Rango-Prefetch`
|
|
70
|
-
* entries are deferred: `result.readDeferred()`
|
|
68
|
+
* `prefetch: true` sends the speculative kind a viewport or render
|
|
69
|
+
* `<Link>` prefetch sends (`X-Rango-Prefetch: 1`), so `prefetch: false`
|
|
70
|
+
* loaders and `loading()` entries are deferred: `result.readDeferred()`
|
|
71
|
+
* lists them. A hover's or `prefetch()`'s intent prefetch defers nothing;
|
|
72
|
+
* serve it with `prefetch: true` and `headers: { "X-Rango-Prefetch":
|
|
73
|
+
* "intent" }`, which `prefetch: true` leaves as given. `fill: true`
|
|
71
74
|
* sends the request the browser follows an adopted prefetch with
|
|
72
75
|
* (`_rsc_fill`): pass the ids the prefetch delivered, without the deferred
|
|
73
76
|
* ones, as `segments`, and the same URL as `from`. `interceptSource` sends
|
|
@@ -229,6 +232,15 @@ export interface ServeShellRequestResult {
|
|
|
229
232
|
* hydrates without it.
|
|
230
233
|
*/
|
|
231
234
|
readPayloadFormState(): Promise<unknown>;
|
|
235
|
+
/**
|
|
236
|
+
* The payload's location state as the browser reads it: the slots
|
|
237
|
+
* (`Def.__rsc_ls_key` to value) a document's start-up merges into its
|
|
238
|
+
* entry (or a navigation's commit, for a `partial` request). Undefined when
|
|
239
|
+
* the payload carries none (or no Flight was rendered). A redirect carries
|
|
240
|
+
* a document request's state in a `Set-Cookie` instead: pass that cookie
|
|
241
|
+
* on the request of its target to read what the target's payload carries.
|
|
242
|
+
*/
|
|
243
|
+
readLocationState(): Promise<Record<string, unknown> | undefined>;
|
|
232
244
|
/**
|
|
233
245
|
* For an `action` request, the call's answer as the browser reads it: its
|
|
234
246
|
* result and the `revalidationError` its loaders' reruns report.
|
|
@@ -274,9 +274,16 @@ export type HandlerContext<TParams = {}, TEnv = DefaultEnv, TSearch extends Sear
|
|
|
274
274
|
*/
|
|
275
275
|
setTheme?: (theme: Theme) => void;
|
|
276
276
|
/**
|
|
277
|
-
* Attach location state entries to this response
|
|
278
|
-
*
|
|
279
|
-
*
|
|
277
|
+
* Attach location state entries to this response, for the useLocationState()
|
|
278
|
+
* hook to read on the entry this response renders. A client navigation
|
|
279
|
+
* delivers it with its payload; a document load (a link from outside the
|
|
280
|
+
* app, a no-JS form post) with its bootstrap payload, once the page has
|
|
281
|
+
* hydrated; a redirect carries it to its target (in a one-shot cookie on a
|
|
282
|
+
* document request). A document carrying it is sent
|
|
283
|
+
* `Cache-Control: private, no-store`.
|
|
284
|
+
*
|
|
285
|
+
* Entries accumulate across definitions; for one definition the last write
|
|
286
|
+
* wins (an earlier entry of it is replaced, not merged).
|
|
280
287
|
*
|
|
281
288
|
* @example
|
|
282
289
|
* ```typescript
|
|
@@ -390,6 +397,16 @@ export type InternalHandlerContext<TParams = {}, TEnv = DefaultEnv, TSearch exte
|
|
|
390
397
|
* request is a fill. See router/segment-resolution/prefetch-deferral.ts.
|
|
391
398
|
*/
|
|
392
399
|
_prefetchDeferral?: import("../router/segment-resolution/prefetch-deferral.js").PrefetchDeferral;
|
|
400
|
+
/**
|
|
401
|
+
* @internal A revalidate() predicate that read the source page
|
|
402
|
+
* (`currentParams`, `currentUrl`, `fromRouteName`) kept a held segment, so
|
|
403
|
+
* this match's diff is right only for pages with equal values of what the
|
|
404
|
+
* kept decisions read (#1331). Set by evaluateRevalidation
|
|
405
|
+
* (router/revalidation.ts) and the stored-entry keep
|
|
406
|
+
* (match-middleware/cache-lookup.ts); match-result.ts turns it into
|
|
407
|
+
* `sourceHeld`, which scopes a prefetch of the response to that group.
|
|
408
|
+
*/
|
|
409
|
+
_sourceHeld?: import("../router/source-reads.js").SourceHeld;
|
|
393
410
|
/**
|
|
394
411
|
* @internal DSL loaders registered and not started, by `$$id`: a prefetch
|
|
395
412
|
* deferred them, or a pass that skips loaders (`skipLoaders`) did not run
|
|
@@ -534,7 +551,7 @@ export type IsActionFn = (...actions: ActionRef[]) => boolean;
|
|
|
534
551
|
export type ShouldRevalidateFn<TParams = GenericParams, TEnv = any> = (args: {
|
|
535
552
|
/** Route params from the page being navigated away from. */
|
|
536
553
|
currentParams: TParams;
|
|
537
|
-
/** Full URL of the page being navigated away from. */
|
|
554
|
+
/** Full URL of the page being navigated away from, without its #fragment. */
|
|
538
555
|
currentUrl: URL;
|
|
539
556
|
/** Route params for the navigation target. */
|
|
540
557
|
nextParams: TParams;
|
|
@@ -182,10 +182,13 @@ export type LoaderFn<T, TParams = Record<string, string | undefined>, TEnv = Def
|
|
|
182
182
|
export type LoaderOptions = {
|
|
183
183
|
ssr?: boolean;
|
|
184
184
|
/**
|
|
185
|
-
* `prefetch: false` keeps this loader out of prefetches. A
|
|
186
|
-
* prefetch (a partial request with
|
|
187
|
-
*
|
|
188
|
-
*
|
|
185
|
+
* `prefetch: false` keeps this loader out of speculative prefetches. A
|
|
186
|
+
* viewport or render `<Link>` prefetch (a partial request with
|
|
187
|
+
* `X-Rango-Prefetch: 1`) does not execute it; the payload marks it
|
|
188
|
+
* deferred. A hover prefetch and `useRouter().prefetch()`
|
|
189
|
+
* (`X-Rango-Prefetch: intent`) count as intent to click and run it, so a
|
|
190
|
+
* click after a hover needs no follow-up request. A document request and a
|
|
191
|
+
* navigation with no prefetch to adopt run it as usual.
|
|
189
192
|
*
|
|
190
193
|
* A deferred loader never blocks the navigation that adopts the prefetch:
|
|
191
194
|
* it behaves like a loader that is still streaming. Its own `<Suspense>`
|
|
@@ -147,7 +147,6 @@ export interface ResolvedSegment {
|
|
|
147
147
|
layoutName?: string;
|
|
148
148
|
parallelName?: string;
|
|
149
149
|
loaderId?: string;
|
|
150
|
-
_inherited?: boolean;
|
|
151
150
|
loaderData?: any;
|
|
152
151
|
/**
|
|
153
152
|
* True when this loader was awaited before first flush
|
|
@@ -274,6 +273,24 @@ export interface MatchResult {
|
|
|
274
273
|
* source, so the RSC handler scopes its prefetch entry to it (#1007).
|
|
275
274
|
*/
|
|
276
275
|
interceptTargeted?: true;
|
|
276
|
+
/**
|
|
277
|
+
* Set on a partial match when a revalidate() predicate read the source page
|
|
278
|
+
* and kept a held segment: the diff is right for the pages with equal values
|
|
279
|
+
* of what it read. The RSC handler scopes its prefetch entry to that group,
|
|
280
|
+
* or to the source page when the predicate read `currentUrl` (#1331).
|
|
281
|
+
*/
|
|
282
|
+
sourceHeld?: import("../router/source-reads.js").SourceHeld;
|
|
283
|
+
/**
|
|
284
|
+
* Set on a partial match whose answer has nothing live in it: the cache
|
|
285
|
+
* lookup served it (a cache() record, a Prerender entry, a shell replay's
|
|
286
|
+
* record, not a stale cache() record or stale overlay entry), it sends a
|
|
287
|
+
* segment, every segment it
|
|
288
|
+
* sends is one that lookup decoded, and no loader ran. A stored segment
|
|
289
|
+
* cannot fail after the headers left, since every writer refuses a failed
|
|
290
|
+
* render; a live segment or a loader can. The RSC handler marks the request
|
|
291
|
+
* `_servedFromStorage` from it.
|
|
292
|
+
*/
|
|
293
|
+
fromStorage?: true;
|
|
277
294
|
/**
|
|
278
295
|
* Redirect URL for trailing slash normalization.
|
|
279
296
|
* When set, the RSC handler should return a 308 redirect to this URL
|
|
@@ -161,9 +161,10 @@ export type PathHelpers<TEnv> = {
|
|
|
161
161
|
* freezes into the shell (nested promises stay live holes) — the pre-flush
|
|
162
162
|
* promise applied to the prelude.
|
|
163
163
|
*
|
|
164
|
-
* Pass `{ prefetch: false }` to keep the loader out of
|
|
165
|
-
* prefetch skips it and the click
|
|
166
|
-
* one follow-up request
|
|
164
|
+
* Pass `{ prefetch: false }` to keep the loader out of speculative
|
|
165
|
+
* prefetches (viewport, render): such a prefetch skips it and the click
|
|
166
|
+
* that adopts it fetches it in one follow-up request; a hover prefetch runs
|
|
167
|
+
* it (see {@link LoaderOptions}). Only on a segment the
|
|
167
168
|
* client does not have yet: a loader the client already holds runs in the
|
|
168
169
|
* prefetch when it revalidates.
|
|
169
170
|
*/
|
|
@@ -172,8 +173,9 @@ export type PathHelpers<TEnv> = {
|
|
|
172
173
|
* Attach a loading component to the current route/layout.
|
|
173
174
|
*
|
|
174
175
|
* `{ ssr: false }` skips the fallback on document requests. `{ prefetch:
|
|
175
|
-
* false }` keeps what the fallback covers out of
|
|
176
|
-
*
|
|
176
|
+
* false }` keeps what the fallback covers out of viewport and render
|
|
177
|
+
* prefetches (a hover prefetch runs it), when this entry's segment is new
|
|
178
|
+
* to the client: the entry's handler, its loaders,
|
|
177
179
|
* its orphan layouts and parallel slots and, for a layout, every deeper
|
|
178
180
|
* entry. The click that adopts the prefetch shows the fallback and fetches
|
|
179
181
|
* them in one follow-up request, which reads cache() and "use cache" as
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Sits in src/vite/, not src/vite/discovery/: the loader hook URL below
|
|
9
9
|
* resolves against this module's import.meta.url, and the published bundles
|
|
10
|
-
* (dist/vite/index.js, dist/bin/
|
|
11
|
-
* path.
|
|
10
|
+
* (dist/vite/index.js, and the CLI's code-split chunks in dist/bin/) ship the
|
|
11
|
+
* hook at the same relative path.
|
|
12
12
|
*/
|
|
13
13
|
import type { ViteDevServer } from "vite";
|
|
14
14
|
import type { DiscoveryState } from "./discovery/state.js";
|
|
@@ -1,4 +1,34 @@
|
|
|
1
1
|
import type { Plugin, ResolvedConfig, UserConfig } from "vite";
|
|
2
|
+
/**
|
|
3
|
+
* Whether a user plugin must NOT be forwarded into the discovery temp server.
|
|
4
|
+
*
|
|
5
|
+
* Framework-owned plugins are matched precisely -- by exact name or a
|
|
6
|
+
* namespaced prefix -- rather than by a loose substring/word prefix, so an
|
|
7
|
+
* unrelated user resolver named e.g. `rsc-paths` or `cloudflare-kv-alias` is
|
|
8
|
+
* still forwarded (it would otherwise reproduce issue #500).
|
|
9
|
+
*
|
|
10
|
+
* - `vite:*` Vite core + official plugins (incl.
|
|
11
|
+
* @vitejs/plugin-react's `vite:react-*`). The temp
|
|
12
|
+
* server already provides its own core; forwarding
|
|
13
|
+
* these would duplicate or conflict with it.
|
|
14
|
+
* - `rsc` / `rsc:*` @vitejs/plugin-rsc. createTempRscServer instantiates
|
|
15
|
+
* its own rsc() plugin; forwarding would duplicate it.
|
|
16
|
+
* Matched exactly (`rsc`) or by the `rsc:` namespace --
|
|
17
|
+
* NOT every `rsc`-prefixed name.
|
|
18
|
+
* - `@rangojs/router*` Our own plugins. The discovery plugin spawns the
|
|
19
|
+
* temp server, so forwarding would recurse infinitely.
|
|
20
|
+
* - `@cloudflare/vite-plugin*` / @cloudflare/vite-plugin (emits the scoped
|
|
21
|
+
* `vite-plugin-cloudflare*` `@cloudflare/vite-plugin` and unscoped
|
|
22
|
+
* `vite-plugin-cloudflare` / `vite-plugin-cloudflare:*`).
|
|
23
|
+
* Forwarding re-inits workerd, defeating the Node temp
|
|
24
|
+
* server. Matched specifically so a scoped user resolver
|
|
25
|
+
* like `@cloudflare/kv-alias` is still forwarded.
|
|
26
|
+
*
|
|
27
|
+
* `rango generate --runtime` drops these before it resolves the user's config,
|
|
28
|
+
* so rango()'s configResolved (which writes the static gen files) and the
|
|
29
|
+
* Cloudflare plugin's config hooks never run there.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isFrameworkPlugin(name: string): boolean;
|
|
2
32
|
/**
|
|
3
33
|
* Pick the user's resolution plugins from the resolved plugin list, denylist
|
|
4
34
|
* framework-owned plugins, keep only those with resolution hooks, and strip
|
|
@@ -20,8 +50,8 @@ export interface ForwardedRunnerConfig {
|
|
|
20
50
|
/**
|
|
21
51
|
* Extract the data-only config slice to mirror into the discovery temp server.
|
|
22
52
|
* `alias` is included here so callers no longer need to thread it separately.
|
|
23
|
-
* Accepts the unresolved config too: `rango generate --runtime`
|
|
24
|
-
*
|
|
53
|
+
* Accepts the unresolved config too: `rango generate --runtime` passes the
|
|
54
|
+
* config file's own values, without what plugin `config` hooks add.
|
|
25
55
|
*
|
|
26
56
|
* `tsconfigPaths` is forwarded so Vite 8's native tsconfig `paths` resolution
|
|
27
57
|
* (a top-level `resolve` flag, off by default) reaches the temp server. The
|