@rangojs/router 0.15.1 → 0.17.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 +254 -89
- package/dist/testing/vitest.js +252 -0
- package/dist/types/browser/navigation-transaction.d.ts +6 -0
- package/dist/types/browser/partial-update.d.ts +11 -0
- package/dist/types/browser/react/ScrollRestoration.d.ts +6 -6
- package/dist/types/browser/rsc-router.d.ts +1 -1
- package/dist/types/browser/scroll-restoration.d.ts +7 -0
- package/dist/types/cache/cache-exec-scope.d.ts +18 -1
- package/dist/types/cache/cache-scope.d.ts +34 -5
- package/dist/types/cache/handle-capture.d.ts +41 -3
- package/dist/types/cache/handle-snapshot.d.ts +53 -13
- package/dist/types/cache/segment-codec.d.ts +10 -3
- package/dist/types/cache/taint.d.ts +1 -1
- package/dist/types/cache/types.d.ts +15 -3
- package/dist/types/client.d.ts +4 -4
- package/dist/types/client.rsc.d.ts +4 -5
- package/dist/types/components/DefaultDocument.d.ts +5 -2
- package/dist/types/context-var.d.ts +6 -5
- package/dist/types/escape-script.d.ts +1 -1
- package/dist/types/handles/MetaTags.d.ts +5 -4
- package/dist/types/handles/Scripts.d.ts +8 -7
- package/dist/types/handles/meta.d.ts +2 -2
- package/dist/types/handles/script.d.ts +17 -16
- package/dist/types/href-client.d.ts +1 -1
- package/dist/types/html.d.ts +12 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.rsc.d.ts +3 -2
- package/dist/types/loader-store.d.ts +52 -0
- package/dist/types/reverse.d.ts +36 -4
- package/dist/types/route-definition/dsl-helpers.d.ts +3 -3
- package/dist/types/route-definition/helpers-types.d.ts +36 -10
- package/dist/types/route-definition/resolve-handler-use.d.ts +23 -1
- package/dist/types/route-types.d.ts +3 -1
- package/dist/types/router/debug-manifest.d.ts +3 -2
- package/dist/types/router/error-handling.d.ts +20 -0
- package/dist/types/router/handler-context.d.ts +6 -0
- package/dist/types/router/match-middleware/background-revalidation.d.ts +46 -5
- package/dist/types/router/middleware-types.d.ts +3 -2
- package/dist/types/router/router-context.d.ts +3 -1
- package/dist/types/router/router-interfaces.d.ts +24 -2
- package/dist/types/router/router-options.d.ts +8 -5
- package/dist/types/router/segment-resolution/fresh.d.ts +10 -0
- package/dist/types/router/segment-resolution/loader-cache.d.ts +37 -1
- package/dist/types/router/segment-resolution/loader-mask.d.ts +9 -19
- package/dist/types/router/segment-resolution/loader-snapshot.d.ts +3 -3
- package/dist/types/router/segment-resolution/mask-nested.d.ts +7 -7
- package/dist/types/router/segment-resolution/revalidation.d.ts +6 -2
- package/dist/types/router/segment-wrappers.d.ts +1 -1
- package/dist/types/rsc/response-route-handler.d.ts +1 -1
- package/dist/types/rsc/rsc-rendering.d.ts +1 -2
- package/dist/types/rsc/shell-capture-constants.d.ts +8 -0
- package/dist/types/rsc/shell-capture.d.ts +5 -4
- package/dist/types/rsc/ssr-setup.d.ts +6 -6
- package/dist/types/rsc/types.d.ts +10 -0
- package/dist/types/server/context.d.ts +33 -3
- package/dist/types/server/handle-store.d.ts +26 -2
- package/dist/types/server/request-context.d.ts +24 -21
- package/dist/types/ssr/index.d.ts +15 -0
- package/dist/types/static-handler.d.ts +4 -1
- package/dist/types/testing/generated-routes.d.ts +2 -2
- package/dist/types/testing/internal/context.d.ts +1 -1
- package/dist/types/testing/render-route.d.ts +32 -6
- package/dist/types/testing/vitest-stubs/plugin-rsc.d.ts +28 -5
- package/dist/types/testing/vitest.d.ts +35 -1
- package/dist/types/theme/ThemeScript.d.ts +3 -3
- package/dist/types/thenable-status.d.ts +9 -0
- package/dist/types/types/cache-types.d.ts +14 -10
- package/dist/types/types/handler-context.d.ts +14 -0
- package/dist/types/types/loader-types.d.ts +8 -6
- package/dist/types/urls/response-types.d.ts +3 -12
- package/dist/types/use-loader.d.ts +12 -3
- package/dist/types/vite/plugins/use-cache-transform.d.ts +33 -2
- package/dist/types/vite/rango.d.ts +1 -1
- package/dist/vite/index.js +884 -768
- package/package.json +4 -4
- package/skills/api-client/SKILL.md +22 -10
- package/skills/breadcrumbs/SKILL.md +65 -22
- package/skills/bundle-analysis/SKILL.md +22 -22
- package/skills/cache-guide/SKILL.md +207 -97
- package/skills/caching/SKILL.md +295 -93
- package/skills/catalog.json +16 -16
- package/skills/client-urls/SKILL.md +53 -31
- package/skills/cloudflare/SKILL.md +72 -20
- package/skills/cloudflare/references/d1-and-local-dev.md +15 -2
- package/skills/cloudflare/references/streaming-and-deploy.md +10 -3
- package/skills/cloudflare/references/webhooks-and-crypto.md +9 -2
- package/skills/comparison/SKILL.md +5 -0
- package/skills/comparison/references/framework-comparison.md +39 -33
- package/skills/composability/SKILL.md +38 -29
- package/skills/css/SKILL.md +10 -13
- package/skills/debug-manifest/SKILL.md +74 -31
- package/skills/defer-hydration/SKILL.md +2 -1
- package/skills/deployment-caching/SKILL.md +6 -1
- package/skills/document-cache/SKILL.md +92 -28
- package/skills/fonts/SKILL.md +16 -8
- package/skills/handler-use/SKILL.md +53 -17
- package/skills/hooks/SKILL.md +28 -20
- package/skills/hooks/data.md +43 -1
- package/skills/hooks/handle-and-actions.md +31 -16
- package/skills/hooks/navigation.md +39 -10
- package/skills/hooks/outlets.md +13 -6
- package/skills/hooks/state.md +37 -15
- package/skills/hooks/urls.md +7 -5
- package/skills/host-router/SKILL.md +64 -12
- package/skills/i18n/SKILL.md +60 -34
- package/skills/intercept/SKILL.md +161 -26
- package/skills/layout/SKILL.md +106 -50
- package/skills/links/SKILL.md +51 -19
- package/skills/loader/SKILL.md +242 -106
- package/skills/middleware/SKILL.md +119 -23
- package/skills/migrate-nextjs/SKILL.md +100 -45
- package/skills/migrate-nextjs/backend-host-swap.md +5 -2
- package/skills/migrate-react-router/SKILL.md +49 -38
- package/skills/migrate-react-router/component-migration.md +25 -6
- package/skills/migrate-react-router/data-and-actions.md +18 -5
- package/skills/migrate-react-router/route-mapping.md +12 -6
- package/skills/mime-routes/SKILL.md +12 -7
- package/skills/observability/SKILL.md +28 -14
- package/skills/parallel/SKILL.md +75 -39
- package/skills/ppr/SKILL.md +345 -150
- package/skills/prerender/SKILL.md +189 -100
- package/skills/rango/SKILL.md +65 -34
- package/skills/react-compiler/SKILL.md +6 -5
- package/skills/response-routes/SKILL.md +133 -25
- package/skills/route/SKILL.md +165 -60
- package/skills/router-setup/SKILL.md +418 -240
- package/skills/scripts/SKILL.md +31 -20
- package/skills/server-actions/SKILL.md +220 -59
- package/skills/shell-manifest/SKILL.md +12 -7
- package/skills/streams-and-websockets/SKILL.md +32 -14
- package/skills/tailwind/SKILL.md +37 -33
- package/skills/testing/SKILL.md +68 -32
- package/skills/testing/cache-prerender.md +55 -29
- package/skills/testing/client-components.md +59 -6
- package/skills/testing/e2e-parity.md +12 -2
- package/skills/testing/flight.md +19 -11
- package/skills/testing/handles.md +8 -5
- package/skills/testing/loader.md +8 -5
- package/skills/testing/middleware.md +8 -3
- package/skills/testing/predicates.md +120 -0
- package/skills/testing/render-handler.md +70 -22
- package/skills/testing/response-routes.md +11 -4
- package/skills/testing/reverse-and-types.md +20 -14
- package/skills/testing/server-actions.md +12 -3
- package/skills/testing/server-tree.md +9 -0
- package/skills/testing/setup.md +9 -5
- package/skills/theme/SKILL.md +106 -29
- package/skills/typesafety/SKILL.md +20 -9
- package/skills/typesafety/env-and-bindings.md +126 -47
- package/skills/typesafety/generated-files-and-cli.md +26 -14
- package/skills/typesafety/params-and-search.md +44 -19
- package/skills/typesafety/route-types.md +50 -14
- package/skills/use-cache/SKILL.md +200 -82
- package/skills/vercel/SKILL.md +21 -11
- package/skills/view-transitions/SKILL.md +41 -20
- package/src/__augment-tests__/augmented.check.ts +26 -1
- package/src/browser/index.ts +2 -2
- package/src/browser/navigation-bridge.ts +3 -4
- package/src/browser/navigation-transaction.ts +22 -2
- package/src/browser/partial-update.ts +75 -80
- package/src/browser/react/ScrollRestoration.tsx +6 -6
- package/src/browser/rsc-router.tsx +1 -1
- package/src/browser/scroll-restoration.ts +53 -6
- package/src/cache/cache-exec-scope.ts +37 -4
- package/src/cache/cache-key-utils.ts +1 -6
- package/src/cache/cache-runtime.ts +230 -61
- package/src/cache/cache-scope.ts +76 -12
- package/src/cache/document-cache.ts +15 -0
- package/src/cache/handle-capture.ts +90 -10
- package/src/cache/handle-snapshot.ts +132 -28
- package/src/cache/segment-codec.ts +26 -7
- package/src/cache/tag-invalidation.ts +4 -3
- package/src/cache/taint.ts +1 -1
- package/src/cache/types.ts +16 -3
- package/src/client.rsc.tsx +10 -9
- package/src/client.tsx +5 -4
- package/src/components/DefaultDocument.tsx +7 -2
- package/src/context-var.ts +6 -5
- package/src/escape-script.ts +1 -1
- package/src/handles/MetaTags.tsx +13 -11
- package/src/handles/Scripts.tsx +11 -10
- package/src/handles/meta.ts +2 -2
- package/src/handles/script.ts +17 -16
- package/src/href-client.ts +1 -1
- package/src/html.ts +12 -0
- package/src/index.rsc.ts +5 -0
- package/src/index.ts +1 -0
- package/src/loader-store.ts +106 -0
- package/src/prerender/build-shell-capture.ts +8 -11
- package/src/reverse.ts +44 -4
- package/src/route-definition/dsl-helpers.ts +134 -42
- package/src/route-definition/helpers-types.ts +36 -10
- package/src/route-definition/resolve-handler-use.ts +121 -6
- package/src/route-types.ts +2 -3
- package/src/router/debug-manifest.ts +10 -2
- package/src/router/error-handling.ts +51 -15
- package/src/router/handler-context.ts +34 -25
- package/src/router/intercept-resolution.ts +125 -39
- package/src/router/loader-resolution.ts +56 -11
- package/src/router/match-api.ts +12 -17
- package/src/router/match-middleware/background-revalidation.ts +161 -96
- package/src/router/match-middleware/cache-lookup.ts +93 -10
- package/src/router/match-middleware/cache-store.ts +17 -90
- package/src/router/middleware-types.ts +3 -5
- package/src/router/middleware.ts +52 -9
- package/src/router/prerender-match.ts +53 -19
- package/src/router/route-snapshot.ts +11 -1
- package/src/router/router-context.ts +2 -0
- package/src/router/router-interfaces.ts +25 -2
- package/src/router/router-options.ts +8 -5
- package/src/router/segment-resolution/fresh.ts +44 -12
- package/src/router/segment-resolution/loader-cache.ts +205 -45
- package/src/router/segment-resolution/loader-mask.ts +12 -22
- package/src/router/segment-resolution/loader-snapshot.ts +6 -6
- package/src/router/segment-resolution/mask-nested.ts +7 -7
- package/src/router/segment-resolution/revalidation.ts +34 -6
- package/src/router/segment-wrappers.ts +4 -0
- package/src/rsc/render-pipeline.ts +3 -0
- package/src/rsc/response-route-handler.ts +11 -3
- package/src/rsc/rsc-rendering.ts +8 -45
- package/src/rsc/shell-capture-constants.ts +13 -0
- package/src/rsc/shell-capture.ts +111 -90
- package/src/rsc/ssr-setup.ts +14 -8
- package/src/rsc/types.ts +11 -0
- package/src/server/context.ts +88 -11
- package/src/server/cookie-store.ts +5 -4
- package/src/server/handle-store.ts +232 -7
- package/src/server/request-context.ts +35 -30
- package/src/ssr/index.tsx +40 -7
- package/src/ssr-suspension-warning.ts +2 -13
- package/src/static-handler.ts +4 -1
- package/src/testing/flight-runtime.d.ts +21 -0
- package/src/testing/generated-routes.ts +2 -2
- package/src/testing/internal/context.ts +1 -1
- package/src/testing/internal/flight-client-globals.ts +7 -5
- package/src/testing/render-route.tsx +85 -24
- package/src/testing/run-loader.ts +5 -1
- package/src/testing/vitest-stubs/plugin-rsc.ts +123 -20
- package/src/testing/vitest.ts +62 -1
- package/src/theme/ThemeProvider.tsx +14 -12
- package/src/theme/ThemeScript.tsx +3 -3
- package/src/thenable-status.ts +16 -0
- package/src/types/cache-types.ts +14 -10
- package/src/types/handler-context.ts +14 -0
- package/src/types/loader-types.ts +8 -6
- package/src/urls/response-types.ts +3 -23
- package/src/use-loader.tsx +24 -4
- package/src/vite/plugins/use-cache-transform.ts +118 -74
- package/src/vite/rango.ts +7 -3
|
@@ -50,10 +50,11 @@ declare function delay(ms: number): Promise<void>;
|
|
|
50
50
|
* mode's ceiling (60s in production, {@link REFUSED_CAPTURE_DEV_MAX_MS} in dev).
|
|
51
51
|
*
|
|
52
52
|
* Why exponential and not a flat 60s: a flat long window conflates two very
|
|
53
|
-
* different failures. A STRUCTURALLY ineligible route (
|
|
54
|
-
* reader) fails forever and wants the long 60s cap. But a
|
|
55
|
-
* can also fail the in-place retry under a truly cold
|
|
56
|
-
* or a cold worker under parallel load) — and it
|
|
53
|
+
* different failures. A STRUCTURALLY ineligible route (a boundary-less live
|
|
54
|
+
* loader read, a cookie reader) fails forever and wants the long 60s cap. But a
|
|
55
|
+
* cold-but-ELIGIBLE route can also fail the in-place retry under a truly cold
|
|
56
|
+
* graph (dev module transform, or a cold worker under parallel load) — and it
|
|
57
|
+
* must recover FAST, on the next
|
|
57
58
|
* request or two, not be frozen for 60s (that would re-break the very cold-start DX
|
|
58
59
|
* the retry fixes; it bit the cloudflare dev e2e). Escalating from 1s means the
|
|
59
60
|
* eligible route re-probes almost immediately (warm now → HIT and clear), while the
|
|
@@ -33,11 +33,11 @@ export interface SsrHtmlStageOptions<TEnv> {
|
|
|
33
33
|
/** Metrics store for ssr:module-load / ssr:stream-mode timing (per call site). */
|
|
34
34
|
metricsStore: MetricsStore | undefined;
|
|
35
35
|
/**
|
|
36
|
-
* renderHTML options minus streamMode (the stage
|
|
37
|
-
* the per-site nonce and, for the PE action re-render, formState.
|
|
38
|
-
* verbatim so each call site's exact key set is preserved.
|
|
36
|
+
* renderHTML options minus streamMode and onError (the stage owns both).
|
|
37
|
+
* Carries the per-site nonce and, for the PE action re-render, formState.
|
|
38
|
+
* Spread verbatim so each call site's exact key set is preserved.
|
|
39
39
|
*/
|
|
40
|
-
render: Omit<SSRRenderOptions, "streamMode">;
|
|
40
|
+
render: Omit<SSRRenderOptions, "streamMode" | "onError">;
|
|
41
41
|
/** ResponseInit merged into the prepared render (e.g. content-type). */
|
|
42
42
|
init?: ResponseInit;
|
|
43
43
|
}
|
|
@@ -59,8 +59,8 @@ export declare function getSSRSetup<TEnv>(ctx: HandlerContext<TEnv>, request: Re
|
|
|
59
59
|
* Classify whether a request may require SSR (HTML rendering).
|
|
60
60
|
*
|
|
61
61
|
* Returns false for requests that are definitively RSC-only: transport
|
|
62
|
-
* params (partial/action/loader/__rsc)
|
|
63
|
-
*
|
|
62
|
+
* params (partial/action/loader/__rsc) or an explicit Accept:
|
|
63
|
+
* text/x-component. Must never return false for a request whose
|
|
64
64
|
* render-time decision (isRscRequest) will be HTML — the two share
|
|
65
65
|
* acceptsFlightExplicitly so the Accept rule cannot drift. document-cache.ts
|
|
66
66
|
* keys its HTML/RSC response slots off this function, so any divergence from
|
|
@@ -181,6 +181,12 @@ export interface SSRRenderOptions {
|
|
|
181
181
|
* the browser across hydration. Absent on host-agnostic build captures.
|
|
182
182
|
*/
|
|
183
183
|
origin?: string;
|
|
184
|
+
/**
|
|
185
|
+
* Called for each error Fizz reports through its onError: a component that
|
|
186
|
+
* threw inside a Suspense boundary, which leaves the boundary errored in an
|
|
187
|
+
* otherwise completed document. React's default console.error is kept.
|
|
188
|
+
*/
|
|
189
|
+
onError?: (error: unknown) => void;
|
|
184
190
|
}
|
|
185
191
|
/**
|
|
186
192
|
* SSR module interface for HTML rendering
|
|
@@ -200,6 +206,8 @@ export interface SSRModule {
|
|
|
200
206
|
maxWaitMs?: number;
|
|
201
207
|
search?: string;
|
|
202
208
|
origin?: string;
|
|
209
|
+
/** Each component error the prerender reports (never the capture's own abort). */
|
|
210
|
+
onError?: (error: unknown) => void;
|
|
203
211
|
}) => Promise<{
|
|
204
212
|
prelude: Uint8Array;
|
|
205
213
|
postponed: string | null;
|
|
@@ -217,6 +225,8 @@ export interface SSRModule {
|
|
|
217
225
|
nonce?: string;
|
|
218
226
|
search?: string;
|
|
219
227
|
origin?: string;
|
|
228
|
+
/** Each component error the resumed holes report. */
|
|
229
|
+
onError?: (error: unknown) => void;
|
|
220
230
|
}) => Promise<ReadableStream<Uint8Array>>;
|
|
221
231
|
}
|
|
222
232
|
/**
|
|
@@ -2,6 +2,7 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
2
2
|
import type { ReactNode } from "react";
|
|
3
3
|
import type { PartialCacheOptions, ErrorBoundaryHandler, Handler, LoaderDefinition, MiddlewareFn, NotFoundBoundaryHandler, ShouldRevalidateFn, TransitionConfig } from "../types";
|
|
4
4
|
import type { DefaultRouteName } from "../types/global-namespace.js";
|
|
5
|
+
import type { ContextVar } from "../context-var.js";
|
|
5
6
|
/**
|
|
6
7
|
* Performance metric entry for a single measured operation
|
|
7
8
|
*
|
|
@@ -44,6 +45,17 @@ export type EntryPropCommon = {
|
|
|
44
45
|
id: string;
|
|
45
46
|
shortCode: string;
|
|
46
47
|
parent: EntryData | null;
|
|
48
|
+
/**
|
|
49
|
+
* Orphan siblings only (attachOrphanSibling in
|
|
50
|
+
* route-definition/dsl-helpers.ts): the entry whose `layout[]` holds this
|
|
51
|
+
* one. `parent` stays null on an orphan (matchError's matched-id stack in
|
|
52
|
+
* router/match-api.ts starts at the boundary-holding entry, possibly an
|
|
53
|
+
* orphan, and must stop there), so the boundary walkers in
|
|
54
|
+
* router/error-handling.ts follow this instead. A lookup that starts at an
|
|
55
|
+
* orphan (its loaders, an intercept it declares) then reaches the owner's
|
|
56
|
+
* boundaries and the owner's ancestors.
|
|
57
|
+
*/
|
|
58
|
+
orphanOwner?: EntryData;
|
|
47
59
|
/** Cache configuration for this entry (set by cache() DSL) */
|
|
48
60
|
cache?: EntryCacheConfig;
|
|
49
61
|
/** URL prefix from include() scope, used for MountContext on client */
|
|
@@ -156,9 +168,6 @@ export type InterceptEntry = {
|
|
|
156
168
|
routeName: string;
|
|
157
169
|
handler: ReactNode | Handler<any, any, any>;
|
|
158
170
|
middleware: MiddlewareFn<any, any>[];
|
|
159
|
-
revalidate: ShouldRevalidateFn<any, any>[];
|
|
160
|
-
errorBoundary: (ReactNode | ErrorBoundaryHandler)[];
|
|
161
|
-
notFoundBoundary: (ReactNode | NotFoundBoundaryHandler)[];
|
|
162
171
|
loader: LoaderEntry[];
|
|
163
172
|
loading?: ReactNode | false;
|
|
164
173
|
transition?: TransitionConfig;
|
|
@@ -403,6 +412,20 @@ export declare function track(label: string, depth?: number): () => void;
|
|
|
403
412
|
* (never cached), so non-cacheable reads are safe.
|
|
404
413
|
*/
|
|
405
414
|
export declare function isInsideCacheScope(): boolean;
|
|
415
|
+
/**
|
|
416
|
+
* Read guard for a non-cacheable variable (`createVar({ cache: false })` or a
|
|
417
|
+
* `ctx.set(..., { cache: false })` write). Callers check isNonCacheable() first
|
|
418
|
+
* so ordinary reads never reach the scope lookups.
|
|
419
|
+
*
|
|
420
|
+
* Throws inside a "use cache" body: the key does not include the value, so the
|
|
421
|
+
* first caller's value would be stored and served to later callers (#925). A
|
|
422
|
+
* loader body entered INSIDE the cached function is exempt, the same baked-copy
|
|
423
|
+
* trade isInsideCacheScope() makes for cache(). A cached function called FROM a
|
|
424
|
+
* loader is not: the loader re-runs, the cached body does not. The body scope
|
|
425
|
+
* records the exec scope it was entered in, so the exemption holds only while
|
|
426
|
+
* that is still the innermost one.
|
|
427
|
+
*/
|
|
428
|
+
export declare function assertNonCacheableReadAllowed(keyOrVar: string | ContextVar<unknown>): void;
|
|
406
429
|
/**
|
|
407
430
|
* Check if the current execution is inside a DSL loader scope
|
|
408
431
|
* (wrapped by runInsideLoaderScope). Used by rendered() barrier
|
|
@@ -498,6 +521,13 @@ export declare function runInsideLoaderBodyScope<T>(fn: () => T, loaderId?: stri
|
|
|
498
521
|
* (issue #672, secondary).
|
|
499
522
|
*/
|
|
500
523
|
export declare function getCurrentLoaderBodyId(): string | undefined;
|
|
524
|
+
/**
|
|
525
|
+
* True while `loaderId`'s body, or a loader it awaits via ctx.use at any
|
|
526
|
+
* depth, is executing. The loader-level cache records these pushes
|
|
527
|
+
* (loader-cache.ts): a HIT skips the cached body, so a dep that no other
|
|
528
|
+
* reader runs in that request only reaches the page through the replay.
|
|
529
|
+
*/
|
|
530
|
+
export declare function isInsideLoaderBody(loaderId: string): boolean;
|
|
501
531
|
/**
|
|
502
532
|
* True while a HANDLER-invoked loader body (`await ctx.use(Loader)` from a
|
|
503
533
|
* handler, not the DSL segment funnel) is executing. The consumption-lane
|
|
@@ -71,8 +71,23 @@ export interface HandleStore {
|
|
|
71
71
|
* Push handle data for a specific handle and segment.
|
|
72
72
|
* Multiple pushes to the same handle/segment accumulate in an array.
|
|
73
73
|
* Each push triggers an emission on the stream.
|
|
74
|
+
*
|
|
75
|
+
* `loaderPush` overrides the push-time DSL-loader tag
|
|
76
|
+
* (isInsideLoaderScope()) that getDataForSegment(id, true) excludes. The
|
|
77
|
+
* PPR shell capture passes false for the bake-lane pushes its record keeps
|
|
78
|
+
* (shell-capture.ts deriveShellCaptureContext), with `owner` set to the
|
|
79
|
+
* pushing loader's id so the record can restore them through pushReplayed
|
|
80
|
+
* (getRecordOwners).
|
|
74
81
|
*/
|
|
75
|
-
push(handleName: string, segmentId: string, data: unknown): void;
|
|
82
|
+
push(handleName: string, segmentId: string, data: unknown, loaderPush?: boolean, owner?: string): void;
|
|
83
|
+
/**
|
|
84
|
+
* push() a loader-cache HIT's replayed value, recorded from `loaderId`'s
|
|
85
|
+
* body (loader-cache.ts replayLoaderHandles). If that loader then runs live
|
|
86
|
+
* in this request, its first push removes every value replayed for it and
|
|
87
|
+
* takes the first one's position (later live pushes follow it), so the
|
|
88
|
+
* handle output stays live without a duplicate.
|
|
89
|
+
*/
|
|
90
|
+
pushReplayed(handleName: string, segmentId: string, data: unknown, loaderId: string): void;
|
|
76
91
|
/**
|
|
77
92
|
* Get all collected handle data after all handlers have settled.
|
|
78
93
|
* Waits for `settled` (handler lane), then returns the data at that point.
|
|
@@ -100,8 +115,17 @@ export interface HandleStore {
|
|
|
100
115
|
/**
|
|
101
116
|
* Get handle data for a specific segment (for caching).
|
|
102
117
|
* Returns data in format: { handleName: [values...] }
|
|
118
|
+
*
|
|
119
|
+
* `excludeLoaderPushes` drops values tagged as DSL-loader pushes at push
|
|
120
|
+
* time (see push); see captureHandles.
|
|
121
|
+
*/
|
|
122
|
+
getDataForSegment(segmentId: string, excludeLoaderPushes?: boolean): Record<string, unknown[]>;
|
|
123
|
+
/**
|
|
124
|
+
* The push `owner` of each value in getDataForSegment(segmentId, true),
|
|
125
|
+
* index-aligned per handle (null: no owner). Handles without an owned
|
|
126
|
+
* value are omitted; undefined when none has one.
|
|
103
127
|
*/
|
|
104
|
-
|
|
128
|
+
getRecordOwners(segmentId: string): Record<string, (string | null)[]> | undefined;
|
|
105
129
|
/**
|
|
106
130
|
* Replay cached handle data back into the store (for cache hits).
|
|
107
131
|
* Used to restore handle data when serving cached segments.
|
|
@@ -129,8 +129,13 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
129
129
|
};
|
|
130
130
|
/** HTTP method (GET, POST, PUT, PATCH, DELETE, etc.) */
|
|
131
131
|
method: string;
|
|
132
|
-
/**
|
|
133
|
-
|
|
132
|
+
/**
|
|
133
|
+
* @internal Handle store for tracking handle data across segments.
|
|
134
|
+
* Readonly: a background render that needs its own store derives a context
|
|
135
|
+
* (rerenderAndCacheRoute, shell-capture.ts) instead of swapping this field,
|
|
136
|
+
* which the foreground still reads while it produces the page.
|
|
137
|
+
*/
|
|
138
|
+
readonly _handleStore: HandleStore;
|
|
134
139
|
/**
|
|
135
140
|
* @internal transition({ when }) predicates for segments matched this request,
|
|
136
141
|
* keyed by segment id. Collected during resolution (the function is stripped
|
|
@@ -178,13 +183,12 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
178
183
|
/**
|
|
179
184
|
* @internal Bake-lane loader containers collected DURING a shell capture:
|
|
180
185
|
* segment-key -> the loader's (pre-wrap) result promise. Populated by
|
|
181
|
-
* resolveLoaderData for loaders
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
* shared shell). Own property of the capture's derived context only.
|
|
186
|
+
* resolveLoaderData for bake-lane loaders (lane rule: see its JSDoc in
|
|
187
|
+
* loader-cache.ts). Drained by captureAndStoreShell after the shell
|
|
188
|
+
* quiesces: settled containers are promise-elided, Flight-serialized, and
|
|
189
|
+
* pinned into the snapshot's loader family; a REJECTED container refuses
|
|
190
|
+
* the capture (error UI must never bake into the shared shell). Own
|
|
191
|
+
* property of the capture's derived context only.
|
|
188
192
|
*/
|
|
189
193
|
_shellCaptureLoaderRecords?: Map<string, Promise<unknown>>;
|
|
190
194
|
/**
|
|
@@ -297,17 +301,6 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
297
301
|
pendingPushes: number;
|
|
298
302
|
handlerInvokedLoader: boolean;
|
|
299
303
|
};
|
|
300
|
-
/**
|
|
301
|
-
* @internal Handle values pushed from a DSL loader scope DURING a shell
|
|
302
|
-
* capture (identity set; populated by the capture push wrapper in
|
|
303
|
-
* shell-capture.ts). cacheRoute threads it into captureHandles so those
|
|
304
|
-
* values stay out of cache-write handle records — loaders re-run fresh on
|
|
305
|
-
* every HIT, so replaying their captured (masked) values would duplicate
|
|
306
|
-
* the fresh push and stall the Flight handle encode. Own property of the
|
|
307
|
-
* capture's derived context only; render-time handle consumers are
|
|
308
|
-
* unaffected (the exclusion applies only at the captureHandles call site).
|
|
309
|
-
*/
|
|
310
|
-
_shellCaptureLoaderHandleValues?: WeakSet<object>;
|
|
311
304
|
/**
|
|
312
305
|
* @internal Set (to the offending fn name) by the cookies()/headers()
|
|
313
306
|
* capture guard when it throws DURING a capture render. Load-bearing for the
|
|
@@ -535,6 +528,16 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
535
528
|
_renderBarrierGuardClosed?: boolean;
|
|
536
529
|
/** @internal Per-request error dedup set for onError reporting */
|
|
537
530
|
_reportedErrors: WeakSet<object>;
|
|
531
|
+
/**
|
|
532
|
+
* @internal Errors this response's Flight or Fizz render reported through
|
|
533
|
+
* onError: a component that threw does not fail the stream, which completes
|
|
534
|
+
* with an error row or an errored Suspense boundary. Whole-response captures
|
|
535
|
+
* (document-cache.ts, captureAndStoreShell) store nothing while it is
|
|
536
|
+
* non-empty (issue #915). An array so a render under a derived context (the
|
|
537
|
+
* shell HIT tail) pushes into the request's own list through the prototype;
|
|
538
|
+
* deriveShellCaptureContext gives the capture its own.
|
|
539
|
+
*/
|
|
540
|
+
_renderErrors?: unknown[];
|
|
538
541
|
/**
|
|
539
542
|
* @internal Report a non-fatal background error through the router's
|
|
540
543
|
* onError callback. Wired by the RSC handler / router during request
|
|
@@ -598,7 +601,7 @@ export interface RequestContext<TEnv = DefaultEnv, TParams = Record<string, stri
|
|
|
598
601
|
* This is the type exported to library consumers. Internal code should
|
|
599
602
|
* use the full RequestContext interface directly.
|
|
600
603
|
*/
|
|
601
|
-
export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, string>> = Omit<RequestContext<TEnv, TParams>, "cookie" | "cookies" | "setCookie" | "deleteCookie" | "_handleStore" | "_transitionWhen" | "_pprTransitionDecisions" | "_pprReplayPostMatchReason" | "_cacheStore" | "_searchParamsFilter" | "_shellCaptureRun" | "_shellImplicitCache" | "_shellLoaderSeed" | "_shellCaptureLoaderRecords" | "_shellCaptureHandleLiveness" | "
|
|
604
|
+
export type PublicRequestContext<TEnv = DefaultEnv, TParams = Record<string, string>> = Omit<RequestContext<TEnv, TParams>, "cookie" | "cookies" | "setCookie" | "deleteCookie" | "_handleStore" | "_transitionWhen" | "_pprTransitionDecisions" | "_pprReplayPostMatchReason" | "_cacheStore" | "_searchParamsFilter" | "_shellCaptureRun" | "_shellImplicitCache" | "_shellLoaderSeed" | "_shellCaptureLoaderRecords" | "_shellCaptureHandleLiveness" | "_shellFragmentPayload" | "_shellCaptureGuardTripped" | "_shellCaptureGuardTrippedLoaderId" | "_explicitTaggedStores" | "_requestTags" | "_cacheProfiles" | "_onResponseCallbacks" | "_pendingBackgroundTasks" | "_themeConfig" | "_locationState" | "_routeName" | "_prevRouteKey" | "_gateCurrentUrl" | "_gateCurrentParams" | "_gateActionId" | "_gateActionUrl" | "_gateActionResult" | "_gateFormData" | "_inActionRevalidation" | "_reportedErrors" | "_renderErrors" | "_renderBarrier" | "_resolveRenderBarrier" | "_renderBarrierSegmentOrder" | "_treeHasStreaming" | "_renderBarrierWaiters" | "_handlerLoaderDeps" | "_awaitBeforeFlushLoaderIds" | "_renderBarrierHandleSnapshot" | "_renderBarrierGuardClosed" | "_reportBackgroundError" | "_debugPerformance" | "_metricsStore" | "_renderForeground" | "_activeRoutine" | "_renderDiagnosticsEnabled" | "_handlerStart" | "_tracing" | "_basename" | "_routerId" | "_setStatus" | "_rotateStateCookie" | "_setKeepCacheDirective" | "_variables" | "_classifiedRoute" | "_requestMode" | "_cacheSignal" | "_dynamic" | "res">;
|
|
602
605
|
/**
|
|
603
606
|
* Marker for a waitUntil-scheduled fn whose task promise must NOT enter
|
|
604
607
|
* _pendingBackgroundTasks. Used by the PPR shell capture for its own task:
|
|
@@ -20,6 +20,7 @@ interface RenderToReadableStreamOptions {
|
|
|
20
20
|
nonce?: string;
|
|
21
21
|
formState?: unknown;
|
|
22
22
|
progressiveChunkSize?: number;
|
|
23
|
+
onError?: (error: unknown) => void;
|
|
23
24
|
}
|
|
24
25
|
/**
|
|
25
26
|
* ReadableStream with the allReady promise added by react-dom/server.edge.
|
|
@@ -99,6 +100,12 @@ export interface SSRRenderOptions {
|
|
|
99
100
|
* prerender pass (host-agnostic bare captures).
|
|
100
101
|
*/
|
|
101
102
|
origin?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Called for each error Fizz reports through its onError: a component that
|
|
105
|
+
* threw inside a Suspense boundary, which leaves the boundary errored in an
|
|
106
|
+
* otherwise completed document. React's default console.error is kept.
|
|
107
|
+
*/
|
|
108
|
+
onError?: (error: unknown) => void;
|
|
102
109
|
}
|
|
103
110
|
/**
|
|
104
111
|
* SSR dependencies from external packages
|
|
@@ -225,6 +232,12 @@ interface ShellCaptureOptions {
|
|
|
225
232
|
* capture, resume, and browser hydration.
|
|
226
233
|
*/
|
|
227
234
|
origin?: string;
|
|
235
|
+
/**
|
|
236
|
+
* Called for each component error the prerender reports (an errored
|
|
237
|
+
* boundary in the prelude), never for the capture's own abort. The caller
|
|
238
|
+
* refuses to store the shell (issue #915).
|
|
239
|
+
*/
|
|
240
|
+
onError?: (error: unknown) => void;
|
|
228
241
|
}
|
|
229
242
|
/**
|
|
230
243
|
* Result of a successful shell capture. `prelude` is the raw prelude bytes;
|
|
@@ -253,6 +266,8 @@ interface ShellResumeOptions {
|
|
|
253
266
|
search?: string;
|
|
254
267
|
/** The HIT request's origin — same host as the capture's (key-scoped). */
|
|
255
268
|
origin?: string;
|
|
269
|
+
/** Called for each component error the resumed holes report. */
|
|
270
|
+
onError?: (error: unknown) => void;
|
|
256
271
|
}
|
|
257
272
|
/**
|
|
258
273
|
* Create an SSR handler that converts RSC streams to HTML.
|
|
@@ -21,11 +21,14 @@
|
|
|
21
21
|
* ```ts
|
|
22
22
|
* export const DocsNav = Static((ctx) => <Nav docs={readDocsSync()} />);
|
|
23
23
|
* export const DocShell = Static((ctx) => <Shell />);
|
|
24
|
+
* // Prerender/Static must be exported consts; an inline call inside path()
|
|
25
|
+
* // gets no build-injected $$id and throws.
|
|
26
|
+
* export const DocPage = Prerender(getParams, DocPageHandler);
|
|
24
27
|
*
|
|
25
28
|
* urls(({ path, layout }) => [
|
|
26
29
|
* layout(DocsNav, () => [
|
|
27
30
|
* path("/getting-started", DocShell, { name: "doc.gs" }),
|
|
28
|
-
* path("/:slug",
|
|
31
|
+
* path("/:slug", DocPage),
|
|
29
32
|
* ]),
|
|
30
33
|
* ]);
|
|
31
34
|
* ```
|
|
@@ -56,10 +56,10 @@ export declare function diffGeneratedRoutes(router: RouterWithRouteMap, generate
|
|
|
56
56
|
*
|
|
57
57
|
* @example
|
|
58
58
|
* ```ts
|
|
59
|
-
* import
|
|
59
|
+
* import { NamedRoutes } from "./router.named-routes.gen";
|
|
60
60
|
* import { router } from "./router";
|
|
61
61
|
*
|
|
62
|
-
* await assertGeneratedRoutesMatch(router,
|
|
62
|
+
* await assertGeneratedRoutesMatch(router, NamedRoutes);
|
|
63
63
|
* ```
|
|
64
64
|
*/
|
|
65
65
|
export declare function assertGeneratedRoutesMatch(router: RouterWithRouteMap, generatedMap?: Record<string, unknown>): Promise<void>;
|
|
@@ -205,7 +205,7 @@ export declare function buildRunSnapshot<TEnv>(ctx: RequestContext<TEnv>, thrown
|
|
|
205
205
|
*
|
|
206
206
|
* @example
|
|
207
207
|
* ```ts
|
|
208
|
-
* const {
|
|
208
|
+
* const { cookies, headers, response, thrown } = await runInRequestContext(
|
|
209
209
|
* () => loginAction(input), // sets a session cookie, then `throw redirect("/app")`
|
|
210
210
|
* {
|
|
211
211
|
* env,
|
|
@@ -23,10 +23,13 @@
|
|
|
23
23
|
* SEEDED directly into client context (see the `loaders` / `locationState` /
|
|
24
24
|
* `handles` / `outletPending` options) — nothing is executed on the server.
|
|
25
25
|
* This exercises the context read path, not the run path.
|
|
26
|
-
* - navigate()
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
26
|
+
* - navigate() does NOT drive the navigation lifecycle: useNavigation().state,
|
|
27
|
+
* useLinkStatus().pending, and useAction().state stay "idle". Assert
|
|
28
|
+
* pending/loading/submitting transition states with renderServerTree / e2e
|
|
29
|
+
* instead (navigate() warns once if used). The one pending state it does
|
|
30
|
+
* model is the held-navigation useLoader().isLoading: a `transition` spec
|
|
31
|
+
* plus a pending Promise seeded via navigate(url, { loaders }) commits
|
|
32
|
+
* through production's commitInTransition (browser/partial-update.ts).
|
|
30
33
|
* What it DOES cover: client hooks that read NavigationProvider /
|
|
31
34
|
* OutletContext — useParams, useReverse, useHref, useMount, useNavigation,
|
|
32
35
|
* useRouter, usePathname, useSearchParams, Outlet/useOutlet nesting and seeded
|
|
@@ -42,7 +45,7 @@ import { type ComponentType } from "react";
|
|
|
42
45
|
import type { RenderResult } from "@testing-library/react";
|
|
43
46
|
import type { NavigationStore } from "../browser/types.js";
|
|
44
47
|
import type { EventController } from "../browser/event-controller.js";
|
|
45
|
-
import type { LoaderDefinition } from "../types.js";
|
|
48
|
+
import type { LoaderDefinition, TransitionConfig } from "../types.js";
|
|
46
49
|
import type { LocationStateDefinition } from "../browser/react/location-state-shared.js";
|
|
47
50
|
import type { Handle } from "../handle.js";
|
|
48
51
|
import type { ThemeConfig } from "../theme/types.js";
|
|
@@ -78,6 +81,14 @@ export interface RenderRouteSpec {
|
|
|
78
81
|
loaderIds?: string[];
|
|
79
82
|
/** Optional route name (informational; not used for matching). */
|
|
80
83
|
name?: string;
|
|
84
|
+
/**
|
|
85
|
+
* The `transition()` config this node declares (`{}` for a bare
|
|
86
|
+
* `transition()`), attached to its segment as the DSL does. Puts the chain in
|
|
87
|
+
* a transition scope: param-agnostic keys (segment-system.tsx) and a held
|
|
88
|
+
* navigate() commit, so a pending loader seed passed to
|
|
89
|
+
* `router.navigate(url, { loaders })` pins `useLoader().isLoading`.
|
|
90
|
+
*/
|
|
91
|
+
transition?: TransitionConfig;
|
|
81
92
|
}
|
|
82
93
|
/**
|
|
83
94
|
* Options for renderRoute.
|
|
@@ -247,8 +258,23 @@ export interface TestRouterHandle {
|
|
|
247
258
|
* updates params + location, and re-renders the segment tree. This is a
|
|
248
259
|
* client-only navigation: no server fetch occurs, so only the components in
|
|
249
260
|
* `routes` can be reached.
|
|
261
|
+
*
|
|
262
|
+
* `options.loaders` seeds loader data for THIS navigation, merged over the
|
|
263
|
+
* render-time seeds (the data a real navigation's response would carry). A
|
|
264
|
+
* pending Promise suspends the read like a streaming Flight chunk. When a
|
|
265
|
+
* spec in the chain has `transition`, the commit goes through production's
|
|
266
|
+
* commitInTransition: the reader stays on screen with
|
|
267
|
+
* `useLoader().isLoading === true` until the promise settles. Settle it
|
|
268
|
+
* inside RTL's `act()` to flush the commit. Without `transition` the commit
|
|
269
|
+
* is urgent and the read suspends to the nearest Suspense boundary.
|
|
270
|
+
*
|
|
271
|
+
* @example
|
|
272
|
+
* await router.navigate("/products/2", { loaders: [[ProductLoader, next]] });
|
|
273
|
+
* // reader: isLoading true, old data
|
|
274
|
+
* await act(async () => resolve({ name: "Product 2" }));
|
|
275
|
+
* // reader: isLoading false, new data
|
|
250
276
|
*/
|
|
251
|
-
navigate(url: string): Promise<void>;
|
|
277
|
+
navigate(url: string, options?: Pick<RenderRouteOptions, "loaders">): Promise<void>;
|
|
252
278
|
/** The current committed pathname. */
|
|
253
279
|
pathname(): string;
|
|
254
280
|
/** The current committed params. */
|
|
@@ -1,9 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Stub for `@vitejs/plugin-rsc/rsc` and the split `/rsc/server`, `/rsc/client`
|
|
3
|
+
* entries, shipped so consumers do not have to write a per-file `vi.mock(...)`.
|
|
4
|
+
* The real entries top-level import Vite virtuals that do not resolve in plain
|
|
5
|
+
* node.
|
|
6
|
+
*
|
|
7
|
+
* Under the `react-server` condition (the Flight project) the "use cache"
|
|
8
|
+
* codec runs on real Flight: the vendored react-server-dom `server.edge` /
|
|
9
|
+
* `client.edge` builds that plugin-rsc's `react/rsc/server` and
|
|
10
|
+
* `react/rsc/client` wrap, with the same manifests and the same server-side
|
|
11
|
+
* reference loader (`@vitejs/plugin-rsc/core/rsc` `setRequireModule`), so
|
|
12
|
+
* keys, writes, hits, value round trips and error rows match a build. The
|
|
13
|
+
* wrappers are not reused: their manifests read `import.meta.env.DEV`, which
|
|
14
|
+
* is undefined in a module node loads directly (vitest externalizes
|
|
15
|
+
* node_modules).
|
|
16
|
+
*
|
|
17
|
+
* Without the condition React's server build refuses to load, so the codec
|
|
18
|
+
* functions throw and a "use cache" call runs uncached. Any other load failure
|
|
19
|
+
* (a moved vendored path, a missing peer) throws. The action entries stay
|
|
20
|
+
* inert either way: no primitive decodes an action request.
|
|
21
|
+
*/
|
|
22
|
+
export declare const renderToReadableStream: (value: unknown, options?: object) => ReadableStream<Uint8Array>;
|
|
23
|
+
export declare const createTemporaryReferenceSet: () => unknown;
|
|
24
|
+
export declare const createFromReadableStream: (stream: ReadableStream<Uint8Array>, options?: object, extraOptions?: {
|
|
25
|
+
preserveServerReferences?: boolean;
|
|
26
|
+
}) => Promise<unknown>;
|
|
27
|
+
export declare const encodeReply: (value: unknown, options?: object) => Promise<string | FormData>;
|
|
28
|
+
export declare const createClientTemporaryReferenceSet: () => unknown;
|
|
3
29
|
export declare const loadServerAction: () => undefined;
|
|
4
30
|
export declare const decodeReply: () => undefined;
|
|
5
31
|
export declare const decodeAction: () => undefined;
|
|
6
32
|
export declare const decodeFormState: () => undefined;
|
|
7
|
-
export declare const createTemporaryReferenceSet: () => Record<string, never>;
|
|
8
|
-
export declare const encodeReply: () => never;
|
|
9
|
-
export declare const createClientTemporaryReferenceSet: () => Record<string, never>;
|
|
@@ -170,6 +170,7 @@ interface FlightTransformPlugin {
|
|
|
170
170
|
* import { defineConfig } from "vitest/config";
|
|
171
171
|
* import {
|
|
172
172
|
* rangoUseClientTransform,
|
|
173
|
+
* rangoUseCacheTransform,
|
|
173
174
|
* rangoTestAliases,
|
|
174
175
|
* rangoInlineDeps,
|
|
175
176
|
* } from "@rangojs/router/testing/vitest";
|
|
@@ -179,7 +180,7 @@ interface FlightTransformPlugin {
|
|
|
179
180
|
* process.env.NODE_ENV = "production";
|
|
180
181
|
*
|
|
181
182
|
* export default defineConfig({
|
|
182
|
-
* plugins: [rangoUseClientTransform()],
|
|
183
|
+
* plugins: [rangoUseClientTransform(), rangoUseCacheTransform()],
|
|
183
184
|
* resolve: {
|
|
184
185
|
* conditions: ["react-server"],
|
|
185
186
|
* // Bare `@rangojs/router` -> its react-server build, so a handler/component
|
|
@@ -203,4 +204,37 @@ interface FlightTransformPlugin {
|
|
|
203
204
|
* so `renderToFlightString` of pure leaf trees is unaffected.
|
|
204
205
|
*/
|
|
205
206
|
export declare function rangoUseClientTransform(): FlightTransformPlugin;
|
|
207
|
+
/** The Vite plugin shape {@link rangoUseCacheTransform} returns. */
|
|
208
|
+
interface UseCacheTransformPlugin {
|
|
209
|
+
name: string;
|
|
210
|
+
enforce: "post";
|
|
211
|
+
configResolved(config: {
|
|
212
|
+
root: string;
|
|
213
|
+
}): void;
|
|
214
|
+
transform(this: {
|
|
215
|
+
warn(message: string): void;
|
|
216
|
+
}, code: string, id: string): Promise<{
|
|
217
|
+
code: string;
|
|
218
|
+
map: unknown;
|
|
219
|
+
} | undefined>;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* A Vite plugin that applies the rango plugin's `"use cache"` transform in a
|
|
223
|
+
* Vitest project, so a function written with the directive is wrapped with
|
|
224
|
+
* `registerCachedFunction` as in dev and a build. `rango()` runs that transform
|
|
225
|
+
* only in its `rsc` environment and Vitest transforms in `ssr`, so without this
|
|
226
|
+
* plugin the directive is an inert string and the function runs on every call.
|
|
227
|
+
*
|
|
228
|
+
* Add it to the react-server project next to {@link rangoUseClientTransform}
|
|
229
|
+
* (see that function's config). There, with a seeded `cacheStore`,
|
|
230
|
+
* `renderHandler` / `runLoader` observe real hits. In the node project the
|
|
231
|
+
* wrap applies too, but the stubbed Flight serializer cannot write an entry.
|
|
232
|
+
*
|
|
233
|
+
* Ids are the ones `vite dev` emits: `<path relative to the Vitest root>#<name>`
|
|
234
|
+
* (a function-level directive gives `src/data.ts#$$hoist_0_getData`), not the
|
|
235
|
+
* build's hashed path, so store keys stay readable. `configResolved` sets that
|
|
236
|
+
* root. If `@vitejs/plugin-rsc/transforms` fails to load, the transform throws
|
|
237
|
+
* instead of leaving the module unwrapped (which the rango plugin does).
|
|
238
|
+
*/
|
|
239
|
+
export declare function rangoUseCacheTransform(): UseCacheTransformPlugin;
|
|
206
240
|
export {};
|
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Must be placed in the <head> element of your document, before any stylesheets.
|
|
10
10
|
*
|
|
11
|
-
* Note: when theme is enabled in the router config, `<
|
|
11
|
+
* Note: when theme is enabled in the router config, `<Html.Meta />` ALREADY
|
|
12
12
|
* renders this FOUC script. Use `<ThemeScript />` only if you do NOT render
|
|
13
|
-
* `<
|
|
13
|
+
* `<Html.Meta />`. Rendering both is safe — the inline script guards the
|
|
14
14
|
* matchMedia listener registration against double-running — but it is redundant.
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
17
17
|
* ```tsx
|
|
18
|
-
* // In your document component. Use ThemeScript only when you do not render
|
|
18
|
+
* // In your document component. Use ThemeScript only when you do not render Html.Meta.
|
|
19
19
|
* import { ThemeScript } from "@rangojs/router/theme";
|
|
20
20
|
*
|
|
21
21
|
* export function Document({ children }) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thenable statuses React's `use()` unwraps without suspending: React's
|
|
3
|
+
* re-check after `.then()` handles "fulfilled", and Flight chunks in the
|
|
4
|
+
* resolved_* states initialize synchronously inside that same call. Anything
|
|
5
|
+
* else (pending, blocked, an unstamped native promise) suspends at least once.
|
|
6
|
+
* Shared by the dev SSR-suspension diagnostic and the held-navigation
|
|
7
|
+
* isLoading registration (loader-store.ts), which must agree on "settled".
|
|
8
|
+
*/
|
|
9
|
+
export declare function unwrapsSynchronously(stream: Promise<unknown>): boolean;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Context passed to cache condition/key/tags functions
|
|
2
|
+
* Context passed to cache condition/key/tags functions (the full
|
|
3
|
+
* RequestContext).
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
5
|
+
* Ordering: global middleware wraps the whole request, and on RSC routes route
|
|
6
|
+
* middleware wraps the match/render pipeline (rsc/handler.ts executeRender), so
|
|
7
|
+
* variables they set before `next()` are readable via `ctx.get()`. On response
|
|
8
|
+
* routes the cache lookup runs BEFORE route middleware, which wraps only the
|
|
9
|
+
* handler run on a miss (rsc/response-route-handler.ts); only global-middleware
|
|
10
|
+
* variables are populated there.
|
|
10
11
|
*/
|
|
11
12
|
export type { RequestContext as CacheContext } from "../server/request-context.js";
|
|
12
13
|
/**
|
|
@@ -105,7 +106,8 @@ export interface CacheOptions<TEnv = unknown> {
|
|
|
105
106
|
* Return false to skip cache for this request (always fetch fresh).
|
|
106
107
|
*
|
|
107
108
|
* Has access to full RequestContext including env, request, params, cookies, etc.
|
|
108
|
-
*
|
|
109
|
+
* Runs after global and route middleware on RSC routes; on response routes,
|
|
110
|
+
* before route middleware (see CacheContext).
|
|
109
111
|
*
|
|
110
112
|
* @example
|
|
111
113
|
* ```typescript
|
|
@@ -124,7 +126,8 @@ export interface CacheOptions<TEnv = unknown> {
|
|
|
124
126
|
* Bypasses default key generation AND store's keyGenerator.
|
|
125
127
|
*
|
|
126
128
|
* Has access to full RequestContext including env, request, params, cookies, etc.
|
|
127
|
-
*
|
|
129
|
+
* Runs after global and route middleware on RSC routes; on response routes,
|
|
130
|
+
* before route middleware (see CacheContext).
|
|
128
131
|
*
|
|
129
132
|
* @example
|
|
130
133
|
* ```typescript
|
|
@@ -143,7 +146,8 @@ export interface CacheOptions<TEnv = unknown> {
|
|
|
143
146
|
* Tags for cache invalidation.
|
|
144
147
|
* Can be a static array or a function that returns tags.
|
|
145
148
|
*
|
|
146
|
-
* The built-in `MemorySegmentCacheStore
|
|
149
|
+
* The built-in `MemorySegmentCacheStore`, `CFCacheStore`, and
|
|
150
|
+
* `VercelCacheStore` index by tag.
|
|
147
151
|
* Invalidate on demand with `updateTag(...tags)` (awaitable, read-your-own-writes;
|
|
148
152
|
* for server actions) or `revalidateTag(...tags)` (background hard-purge, not
|
|
149
153
|
* awaited; for route handlers / webhooks). For `CFCacheStore`, distributed
|
|
@@ -335,6 +335,20 @@ export type InternalHandlerContext<TParams = {}, TEnv = DefaultEnv, TSearch exte
|
|
|
335
335
|
* table (so a loader cannot await its own in-flight memoized promise).
|
|
336
336
|
*/
|
|
337
337
|
_loaderCacheOriginalUse?: (item: any) => any;
|
|
338
|
+
/**
|
|
339
|
+
* @internal A loader-cache HIT asks before replaying a loader's recorded
|
|
340
|
+
* pushes: true when that loader has not run in this request and no other
|
|
341
|
+
* replay delivered it; its later run then replaces the replayed values
|
|
342
|
+
* (HandleStore.pushReplayed). One copy per loader per request. See
|
|
343
|
+
* setupLoaderAccess.
|
|
344
|
+
*/
|
|
345
|
+
_claimLoaderPushes?: (loaderId: string) => boolean;
|
|
346
|
+
/**
|
|
347
|
+
* @internal Run a loader on a fresh executor (own memo map): a loader-cache
|
|
348
|
+
* stale refresh, whose diverted pushes must not take a dependency's run
|
|
349
|
+
* from the page. See setupLoaderAccess.
|
|
350
|
+
*/
|
|
351
|
+
_runLoaderIsolated?: (loader: any) => Promise<any>;
|
|
338
352
|
};
|
|
339
353
|
/**
|
|
340
354
|
* Generic params type - flexible object with string keys
|