@rangojs/router 0.17.0 → 0.19.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/types/browser/cookie-name.d.ts +6 -0
- package/dist/types/browser/event-controller.d.ts +3 -3
- package/dist/types/browser/history-state.d.ts +18 -0
- package/dist/types/browser/navigation-transaction.d.ts +20 -2
- package/dist/types/browser/partial-update.d.ts +16 -1
- package/dist/types/browser/prefetch/cache.d.ts +6 -6
- package/dist/types/browser/react/Link.d.ts +19 -9
- package/dist/types/browser/react/context.d.ts +2 -2
- package/dist/types/browser/react/location-state-shared.d.ts +95 -56
- package/dist/types/browser/react/location-state.d.ts +1 -1
- package/dist/types/browser/transition-when.d.ts +80 -0
- package/dist/types/browser/types.d.ts +104 -9
- package/dist/types/build/generate-manifest.d.ts +8 -0
- package/dist/types/cache/background-task.d.ts +24 -2
- package/dist/types/cache/cache-exec-scope.d.ts +31 -0
- package/dist/types/cache/cache-key-utils.d.ts +48 -2
- package/dist/types/cache/cache-policy.d.ts +18 -1
- package/dist/types/cache/cache-runtime.d.ts +7 -0
- package/dist/types/cache/cache-scope.d.ts +192 -26
- package/dist/types/cache/cache-tag.d.ts +116 -11
- package/dist/types/cache/cf/cf-base64.d.ts +6 -0
- package/dist/types/cache/cf/cf-cache-constants.d.ts +11 -0
- package/dist/types/cache/cf/cf-cache-store.d.ts +224 -72
- package/dist/types/cache/cf/cf-cache-types.d.ts +31 -4
- package/dist/types/cache/cf/cf-shell-frame.d.ts +95 -0
- package/dist/types/cache/cf/cf-tag-marker-memo.d.ts +19 -0
- package/dist/types/cache/document-cache.d.ts +10 -0
- package/dist/types/cache/handle-snapshot.d.ts +41 -8
- package/dist/types/cache/index.d.ts +1 -0
- package/dist/types/cache/invalidation-order.d.ts +23 -0
- package/dist/types/cache/isolate-tag-memo.d.ts +149 -0
- package/dist/types/cache/request-tag-mask.d.ts +54 -0
- package/dist/types/cache/shell-memo.d.ts +178 -0
- package/dist/types/cache/shell-snapshot.d.ts +141 -105
- package/dist/types/cache/tag-invalidation.d.ts +54 -3
- package/dist/types/cache/types.d.ts +267 -96
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +123 -18
- package/dist/types/client-urls/navigation.d.ts +28 -2
- package/dist/types/client-urls/server-projection.d.ts +5 -2
- package/dist/types/client-urls/types.d.ts +5 -5
- package/dist/types/client.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.rsc.d.ts +1 -1
- package/dist/types/prerender/build-shell-capture.d.ts +11 -4
- package/dist/types/route-definition/helpers-types.d.ts +11 -11
- package/dist/types/route-name.d.ts +7 -0
- package/dist/types/router/error-handling.d.ts +1 -1
- package/dist/types/router/instrument.d.ts +8 -0
- package/dist/types/router/intercept-resolution.d.ts +2 -0
- package/dist/types/router/match-context.d.ts +5 -0
- package/dist/types/router/match-middleware/background-revalidation.d.ts +0 -4
- package/dist/types/router/middleware-types.d.ts +6 -1
- package/dist/types/router/router-options.d.ts +4 -1
- package/dist/types/router/segment-resolution/loader-cache.d.ts +58 -12
- package/dist/types/router/segment-resolution/loader-mask.d.ts +3 -4
- package/dist/types/router/segment-resolution/loader-snapshot.d.ts +33 -48
- package/dist/types/router/segment-resolution/mask-nested.d.ts +73 -24
- package/dist/types/router/segment-resolution/view-transition-default.d.ts +7 -5
- package/dist/types/router/transition-when.d.ts +24 -10
- package/dist/types/rsc/attach-transition-when.d.ts +18 -0
- package/dist/types/rsc/full-payload.d.ts +21 -0
- package/dist/types/rsc/handler.d.ts +1 -1
- package/dist/types/rsc/response-cache-serve.d.ts +15 -12
- package/dist/types/rsc/shell-build-manifest.d.ts +12 -3
- package/dist/types/rsc/shell-capture-constants.d.ts +116 -12
- package/dist/types/rsc/shell-capture.d.ts +202 -74
- package/dist/types/rsc/shell-serve.d.ts +144 -50
- package/dist/types/rsc/types.d.ts +9 -0
- package/dist/types/segment-system.d.ts +7 -0
- package/dist/types/server/context.d.ts +155 -33
- package/dist/types/server/cookie-store.d.ts +33 -0
- package/dist/types/server/handle-store.d.ts +52 -1
- package/dist/types/server/request-context.d.ts +210 -63
- package/dist/types/server/request-headers.d.ts +44 -0
- package/dist/types/server.d.ts +1 -0
- package/dist/types/ssr/index.d.ts +9 -0
- package/dist/types/ssr/ssr-root.d.ts +9 -8
- package/dist/types/testing/e2e/index.d.ts +1 -1
- package/dist/types/testing/flight.entry.d.ts +7 -0
- package/dist/types/testing/index.d.ts +3 -2
- package/dist/types/testing/internal/action-id.d.ts +7 -0
- package/dist/types/testing/location-state-key.d.ts +24 -0
- package/dist/types/testing/render-route.d.ts +17 -1
- package/dist/types/testing/run-loader.d.ts +18 -3
- package/dist/types/testing/run-transition-when.d.ts +44 -69
- package/dist/types/testing/serve-shell-request.d.ts +133 -0
- package/dist/types/testing/shell-status.d.ts +44 -19
- package/dist/types/transition-when-ref.d.ts +79 -0
- package/dist/types/types/cache-types.d.ts +15 -3
- package/dist/types/types/handler-context.d.ts +14 -1
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/segments.d.ts +86 -71
- package/dist/types/urls/path-helper-types.d.ts +3 -4
- package/dist/types/urls/pattern-types.d.ts +21 -18
- package/dist/types/vite/plugins/transition-when-hoist.d.ts +45 -0
- package/dist/types/vite/router-discovery.d.ts +29 -2
- package/dist/vite/index.js +1005 -105
- package/package.json +1 -1
- package/skills/breadcrumbs/SKILL.md +17 -7
- package/skills/cache-guide/SKILL.md +175 -76
- package/skills/caching/SKILL.md +361 -33
- package/skills/catalog.json +1 -1
- package/skills/client-urls/SKILL.md +12 -7
- package/skills/cloudflare/SKILL.md +15 -0
- package/skills/comparison/references/framework-comparison.md +52 -37
- package/skills/defer-hydration/SKILL.md +50 -30
- package/skills/deployment-caching/SKILL.md +5 -2
- package/skills/document-cache/SKILL.md +32 -2
- package/skills/handler-use/SKILL.md +2 -0
- package/skills/hooks/SKILL.md +3 -1
- package/skills/hooks/handle-and-actions.md +3 -1
- package/skills/hooks/navigation.md +23 -2
- package/skills/hooks/state.md +101 -7
- package/skills/intercept/SKILL.md +29 -12
- package/skills/loader/SKILL.md +197 -44
- package/skills/middleware/SKILL.md +34 -9
- package/skills/migrate-nextjs/SKILL.md +68 -37
- package/skills/migrate-react-router/SKILL.md +2 -1
- package/skills/migrate-react-router/component-migration.md +3 -1
- package/skills/migrate-react-router/data-and-actions.md +3 -1
- package/skills/migrate-react-router/route-mapping.md +7 -4
- package/skills/observability/SKILL.md +65 -0
- package/skills/parallel/SKILL.md +13 -8
- package/skills/ppr/SKILL.md +715 -371
- package/skills/prerender/SKILL.md +30 -17
- package/skills/rango/SKILL.md +72 -34
- package/skills/route/SKILL.md +14 -7
- package/skills/router-setup/SKILL.md +4 -2
- package/skills/scripts/SKILL.md +8 -1
- package/skills/server-actions/SKILL.md +11 -0
- package/skills/shell-manifest/SKILL.md +21 -12
- package/skills/testing/SKILL.md +49 -43
- package/skills/testing/cache-prerender.md +15 -14
- package/skills/testing/client-components.md +45 -3
- package/skills/testing/loader.md +19 -1
- package/skills/testing/middleware.md +1 -0
- package/skills/testing/predicates.md +49 -49
- package/skills/testing/render-handler.md +1 -0
- package/skills/testing/serve-shell-request.md +202 -0
- package/skills/testing/server-actions.md +9 -3
- package/skills/theme/SKILL.md +56 -4
- package/skills/typesafety/env-and-bindings.md +18 -2
- package/skills/use-cache/SKILL.md +91 -23
- package/skills/vercel/SKILL.md +14 -2
- package/skills/view-transitions/SKILL.md +150 -29
- package/src/__augment-tests__/augmented.check.ts +23 -0
- package/src/browser/cookie-name.ts +23 -0
- package/src/browser/event-controller.ts +4 -4
- package/src/browser/history-state.ts +75 -1
- package/src/browser/link-interceptor.ts +4 -0
- package/src/browser/navigation-bridge.ts +77 -18
- package/src/browser/navigation-client.ts +4 -3
- package/src/browser/navigation-store.ts +43 -1
- package/src/browser/navigation-transaction.ts +31 -11
- package/src/browser/partial-update.ts +146 -35
- package/src/browser/prefetch/cache.ts +6 -6
- package/src/browser/prefetch/fetch.ts +2 -2
- package/src/browser/react/Link.tsx +38 -33
- package/src/browser/react/NavigationProvider.tsx +2 -2
- package/src/browser/react/context.ts +2 -2
- package/src/browser/react/location-state-shared.ts +241 -49
- package/src/browser/react/location-state.ts +5 -2
- package/src/browser/rsc-router.tsx +9 -0
- package/src/browser/server-action-bridge.ts +84 -15
- package/src/browser/transition-when.ts +205 -0
- package/src/browser/types.ts +124 -10
- package/src/build/generate-manifest.ts +77 -1
- package/src/cache/background-task.ts +55 -2
- package/src/cache/cache-exec-scope.ts +48 -1
- package/src/cache/cache-key-utils.ts +62 -2
- package/src/cache/cache-policy.ts +31 -4
- package/src/cache/cache-runtime.ts +209 -129
- package/src/cache/cache-scope.ts +573 -69
- package/src/cache/cache-tag.ts +475 -19
- package/src/cache/cf/cf-base64.ts +36 -4
- package/src/cache/cf/cf-cache-constants.ts +12 -0
- package/src/cache/cf/cf-cache-store.ts +1094 -376
- package/src/cache/cf/cf-cache-types.ts +32 -4
- package/src/cache/cf/cf-shell-frame.ts +258 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +55 -40
- package/src/cache/document-cache.ts +53 -7
- package/src/cache/handle-snapshot.ts +53 -9
- package/src/cache/index.ts +2 -0
- package/src/cache/invalidation-order.ts +84 -0
- package/src/cache/isolate-tag-memo.ts +308 -0
- package/src/cache/request-tag-mask.ts +147 -0
- package/src/cache/shell-memo.ts +341 -0
- package/src/cache/shell-snapshot.ts +249 -277
- package/src/cache/tag-invalidation.ts +109 -18
- package/src/cache/types.ts +274 -102
- package/src/cache/vercel/vercel-cache-store.ts +561 -74
- package/src/client-urls/client-root.tsx +8 -4
- package/src/client-urls/client-urls.ts +8 -6
- package/src/client-urls/navigation.ts +55 -4
- package/src/client-urls/server-projection.ts +31 -10
- package/src/client-urls/types.ts +12 -5
- package/src/client.tsx +2 -0
- package/src/host/cookie-handler.ts +2 -1
- package/src/index.rsc.ts +3 -0
- package/src/index.ts +3 -0
- package/src/loader-redirect.tsx +7 -3
- package/src/prerender/build-shell-capture.ts +173 -110
- package/src/route-definition/dsl-helpers.ts +6 -3
- package/src/route-definition/helpers-types.ts +11 -11
- package/src/route-name.ts +12 -0
- package/src/router/content-negotiation.ts +4 -1
- package/src/router/error-handling.ts +5 -2
- package/src/router/handler-context.ts +42 -5
- package/src/router/instrument.ts +54 -2
- package/src/router/intercept-resolution.ts +30 -8
- package/src/router/loader-resolution.ts +89 -33
- package/src/router/logging.ts +5 -3
- package/src/router/match-api.ts +89 -42
- package/src/router/match-context.ts +5 -0
- package/src/router/match-handlers.ts +14 -29
- package/src/router/match-middleware/background-revalidation.ts +3 -5
- package/src/router/match-middleware/cache-lookup.ts +52 -19
- package/src/router/match-middleware/cache-store.ts +36 -10
- package/src/router/match-result.ts +1 -0
- package/src/router/middleware-types.ts +6 -1
- package/src/router/middleware.ts +20 -4
- package/src/router/navigation-snapshot.ts +6 -5
- package/src/router/prerender-match.ts +10 -0
- package/src/router/request-classification.ts +7 -4
- package/src/router/router-options.ts +4 -1
- package/src/router/segment-resolution/fresh.ts +18 -13
- package/src/router/segment-resolution/helpers.ts +4 -2
- package/src/router/segment-resolution/loader-cache.ts +366 -70
- package/src/router/segment-resolution/loader-mask.ts +3 -4
- package/src/router/segment-resolution/loader-snapshot.ts +215 -126
- package/src/router/segment-resolution/mask-nested.ts +161 -42
- package/src/router/segment-resolution/revalidation.ts +27 -13
- package/src/router/segment-resolution/view-transition-default.ts +6 -21
- package/src/router/telemetry.ts +6 -3
- package/src/router/transition-when.ts +34 -52
- package/src/router.ts +2 -1
- package/src/rsc/attach-transition-when.ts +47 -0
- package/src/rsc/full-payload.ts +47 -3
- package/src/rsc/handler.ts +24 -10
- package/src/rsc/loader-fetch.ts +2 -1
- package/src/rsc/manifest-init.ts +4 -0
- package/src/rsc/origin-guard.ts +8 -5
- package/src/rsc/progressive-enhancement.ts +10 -32
- package/src/rsc/response-cache-serve.ts +69 -78
- package/src/rsc/response-route-handler.ts +2 -2
- package/src/rsc/rsc-rendering.ts +712 -338
- package/src/rsc/server-action.ts +8 -20
- package/src/rsc/shell-build-manifest.ts +49 -29
- package/src/rsc/shell-capture-constants.ts +182 -12
- package/src/rsc/shell-capture.ts +1126 -612
- package/src/rsc/shell-serve.ts +331 -85
- package/src/rsc/ssr-setup.ts +3 -2
- package/src/rsc/types.ts +9 -0
- package/src/segment-system.tsx +40 -7
- package/src/server/context.ts +328 -72
- package/src/server/cookie-store.ts +184 -133
- package/src/server/handle-store.ts +245 -27
- package/src/server/request-context.ts +364 -100
- package/src/server/request-headers.ts +134 -0
- package/src/server.ts +4 -0
- package/src/ssr/index.tsx +96 -37
- package/src/ssr/ssr-root.tsx +9 -8
- package/src/testing/dispatch.ts +4 -7
- package/src/testing/e2e/index.ts +1 -0
- package/src/testing/flight.entry.ts +14 -0
- package/src/testing/index.ts +5 -0
- package/src/testing/internal/action-id.ts +25 -0
- package/src/testing/internal/context.ts +1 -1
- package/src/testing/location-state-key.ts +45 -0
- package/src/testing/render-handler.ts +1 -1
- package/src/testing/render-route.tsx +109 -16
- package/src/testing/run-client-revalidate.ts +3 -19
- package/src/testing/run-loader.ts +67 -5
- package/src/testing/run-transition-when.ts +109 -172
- package/src/testing/serve-shell-request.ts +381 -0
- package/src/testing/shell-status.ts +73 -47
- package/src/theme/ThemeProvider.tsx +7 -6
- package/src/transition-when-ref.ts +220 -0
- package/src/types/cache-types.ts +15 -3
- package/src/types/handler-context.ts +14 -1
- package/src/types/index.ts +3 -0
- package/src/types/segments.ts +94 -91
- package/src/urls/path-helper-types.ts +3 -4
- package/src/urls/pattern-types.ts +21 -18
- package/src/vite/discovery/discover-routers.ts +3 -0
- package/src/vite/discovery/shell-prerender-phase.ts +9 -2
- package/src/vite/discovery/virtual-module-codegen.ts +16 -6
- package/src/vite/plugins/transition-when-hoist.ts +1064 -0
- package/src/vite/rango.ts +2 -0
- package/src/vite/router-discovery.ts +89 -9
- package/dist/types/rsc/transition-gate.d.ts +0 -23
- package/src/rsc/transition-gate.ts +0 -86
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type LocationStateDefinition } from "../browser/react/location-state-shared.js";
|
|
2
|
+
/**
|
|
3
|
+
* Assign a location-state key to a `createLocationState()` definition in a unit
|
|
4
|
+
* test that runs without the rango Vite plugin (which injects the key in dev
|
|
5
|
+
* and build). Outside production, a definition without a key throws on first
|
|
6
|
+
* use (`MyState(value)`, `useLocationState(MyState)`, `.read()`).
|
|
7
|
+
*
|
|
8
|
+
* - `withLocationStateKey(GridState, "GridState")` sets `__rsc_ls_GridState`
|
|
9
|
+
* (a name that already starts with `__rsc_ls_` is used as-is).
|
|
10
|
+
* - Without a name, a key already set (by the plugin or an earlier call) is
|
|
11
|
+
* kept; otherwise the definition gets a synthetic `__rsc_ls_test_<n>` key,
|
|
12
|
+
* which then stays on it.
|
|
13
|
+
*
|
|
14
|
+
* Returns the definition.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { withLocationStateKey } from "@rangojs/router/testing";
|
|
19
|
+
* import { GridState } from "../src/location-states";
|
|
20
|
+
*
|
|
21
|
+
* withLocationStateKey(GridState);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare function withLocationStateKey<TDefinition extends LocationStateDefinition<any, any>>(definition: TDefinition, name?: string): TDefinition;
|
|
@@ -30,6 +30,11 @@
|
|
|
30
30
|
* model is the held-navigation useLoader().isLoading: a `transition` spec
|
|
31
31
|
* plus a pending Promise seeded via navigate(url, { loaders }) commits
|
|
32
32
|
* through production's commitInTransition (browser/partial-update.ts).
|
|
33
|
+
* - A spec's transition({ when }) decides every commit with production's
|
|
34
|
+
* browser decision: navigate() and useRouter().push model kind "push",
|
|
35
|
+
* useRouter().replace kind "replace", refresh() kind "revalidate".
|
|
36
|
+
* Back/forward, action and optimistic clientUrls() swap decisions are
|
|
37
|
+
* e2e territory.
|
|
33
38
|
* What it DOES cover: client hooks that read NavigationProvider /
|
|
34
39
|
* OutletContext — useParams, useReverse, useHref, useMount, useNavigation,
|
|
35
40
|
* useRouter, usePathname, useSearchParams, Outlet/useOutlet nesting and seeded
|
|
@@ -273,8 +278,19 @@ export interface TestRouterHandle {
|
|
|
273
278
|
* // reader: isLoading true, old data
|
|
274
279
|
* await act(async () => resolve({ name: "Product 2" }));
|
|
275
280
|
* // reader: isLoading false, new data
|
|
281
|
+
*
|
|
282
|
+
* `options.transition: false` is the per-navigation opt-out
|
|
283
|
+
* (`router.push(url, { transition: false })`, `<Link transition={false}>`):
|
|
284
|
+
* the commit is urgent and no transition({ when }) predicate is called.
|
|
285
|
+
*/
|
|
286
|
+
navigate(url: string, options?: Pick<RenderRouteOptions, "loaders"> & {
|
|
287
|
+
transition?: boolean;
|
|
288
|
+
}): Promise<void>;
|
|
289
|
+
/**
|
|
290
|
+
* Re-render the current location, as router.refresh() does: a spec's
|
|
291
|
+
* transition({ when }) decides it with kind "revalidate" (`to` is `from`).
|
|
276
292
|
*/
|
|
277
|
-
|
|
293
|
+
refresh(): Promise<void>;
|
|
278
294
|
/** The current committed pathname. */
|
|
279
295
|
pathname(): string;
|
|
280
296
|
/** The current committed params. */
|
|
@@ -38,6 +38,7 @@ import { type Handle } from "../handle.js";
|
|
|
38
38
|
import type { ThemeConfig } from "../theme/types.js";
|
|
39
39
|
import type { SegmentCacheStore } from "../cache/types.js";
|
|
40
40
|
import type { CacheProfile } from "../cache/profile-registry.js";
|
|
41
|
+
import type { PartialCacheOptions } from "../types/cache-types.js";
|
|
41
42
|
import { type VarsInit, type StateCookieSeed } from "./internal/context.js";
|
|
42
43
|
/**
|
|
43
44
|
* The loader context surfaced to a `runLoader` body. It mirrors the runtime
|
|
@@ -81,9 +82,11 @@ export interface RunLoaderOptions<TEnv = any> {
|
|
|
81
82
|
basename?: string;
|
|
82
83
|
/**
|
|
83
84
|
* Theme config in the same shape `createRouter({ theme })` takes (e.g. `true`
|
|
84
|
-
* or `{ themes: [...] }`). Seeds the request's theme config so
|
|
85
|
-
*
|
|
86
|
-
*
|
|
85
|
+
* or `{ themes: [...] }`). Seeds the request's theme config, so the loader
|
|
86
|
+
* body reads the visitor's theme (the Cookie on `request`, or the default)
|
|
87
|
+
* with `getRequestContext().theme`. That read is guarded like `cookies()`: it
|
|
88
|
+
* throws inside a `"use cache"` function (#971). The loader ctx has no
|
|
89
|
+
* `theme`/`setTheme` (those are handler/middleware-only).
|
|
87
90
|
*/
|
|
88
91
|
theme?: ThemeConfig | true;
|
|
89
92
|
/** Environment bindings surfaced as `ctx.env`. */
|
|
@@ -121,6 +124,18 @@ export interface RunLoaderOptions<TEnv = any> {
|
|
|
121
124
|
cacheStore?: SegmentCacheStore;
|
|
122
125
|
/** Cache profiles (the `createRouter({ cacheProfiles })` shape). */
|
|
123
126
|
cacheProfiles?: Record<string, CacheProfile>;
|
|
127
|
+
/**
|
|
128
|
+
* Run the loader through the `cache()` a route binds it with — the options
|
|
129
|
+
* `loader(Loader, () => [cache({...})])` takes — using the production
|
|
130
|
+
* read-through against `cache.store`, else `cacheStore`. A HIT returns the
|
|
131
|
+
* stored value without running the body and records the tags the body
|
|
132
|
+
* recorded when the entry was written, so `updateTag()` of any of them drops
|
|
133
|
+
* the entry. The write is a background task the call does not await (spy
|
|
134
|
+
* on the store's `setItem` to wait for it). A raw loader body is keyed by
|
|
135
|
+
* its function reference. `handlePushes` lists the body's pushes, so a HIT
|
|
136
|
+
* reports none: the replay into the page's handle store is not modeled.
|
|
137
|
+
*/
|
|
138
|
+
cache?: PartialCacheOptions;
|
|
124
139
|
/**
|
|
125
140
|
* Customize the rango state cookie a loader that calls
|
|
126
141
|
* `invalidateClientCache()` rotates (the name is always seeded — default
|
|
@@ -1,78 +1,53 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* runTransitionWhen — unit-test a transition({ when }) predicate
|
|
2
|
+
* runTransitionWhen — unit-test a transition({ when }) browser predicate.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* (
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* assembled `whenContext` so tests can assert the exact fields without reaching
|
|
12
|
-
* into private request-context state.
|
|
4
|
+
* Builds the context and evaluates the predicate through the SAME browser
|
|
5
|
+
* functions the router uses at navigation time (browser/transition-when.ts):
|
|
6
|
+
* a throw counts as false and is logged. `from`/`to` take a URL string or a
|
|
7
|
+
* partial RouteLocation; a `state` given as location-state entries
|
|
8
|
+
* (`[Def(value)]`, what Link/push take) is stored the way a push stores it,
|
|
9
|
+
* so `Def.read(ctx.to)` reads it back. Accepts the predicate or a whole
|
|
10
|
+
* TransitionConfig.
|
|
13
11
|
*
|
|
14
|
-
*
|
|
15
|
-
* match -> render pipeline that wires these together only runs under real RSC
|
|
16
|
-
* rendering (which the Flight primitives do not drive), so without this primitive
|
|
17
|
-
* a consumer could not test their predicate through @rangojs/router/testing.
|
|
18
|
-
*
|
|
19
|
-
* Synchronous: a transition predicate returns a boolean and the gate has no I/O.
|
|
20
|
-
*/
|
|
21
|
-
import { type RequestContext } from "../server/request-context.js";
|
|
22
|
-
import { type VarsInit } from "./internal/context.js";
|
|
23
|
-
import type { TransitionConfig, TransitionWhenContext } from "../types/segments.js";
|
|
24
|
-
import type { OnErrorCallback } from "../types/error-types.js";
|
|
25
|
-
/**
|
|
26
|
-
* Options for runTransitionWhen. All navigation/action fields are optional and
|
|
27
|
-
* default to "absent", matching what the gate sees for an initial full load with
|
|
28
|
-
* no action: omit `currentUrl`/`currentParams`/`fromRouteName` to model the
|
|
29
|
-
* navigation source being unavailable, and omit the `action*` fields to model a
|
|
30
|
-
* plain (non-action) navigation.
|
|
12
|
+
* Synchronous: a transition predicate returns a boolean and has no I/O.
|
|
31
13
|
*/
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
vars?: VarsInit;
|
|
43
|
-
/** Navigation SOURCE url (`currentUrl`): a URL or path string. */
|
|
44
|
-
currentUrl?: string | URL;
|
|
45
|
-
/** Source route params (`currentParams`). */
|
|
46
|
-
currentParams?: Record<string, string>;
|
|
47
|
-
/** Source route name (`fromRouteName`). */
|
|
48
|
-
fromRouteName?: string;
|
|
49
|
-
/** Id of the action that triggered a revalidation (`actionId`). */
|
|
50
|
-
actionId?: string;
|
|
51
|
-
/** Url the action was submitted from (`actionUrl`). */
|
|
52
|
-
actionUrl?: string | URL;
|
|
53
|
-
/** The action's return value (`actionResult`). */
|
|
54
|
-
actionResult?: unknown;
|
|
55
|
-
/** FormData from a form action (`formData`). */
|
|
14
|
+
import type { RouteLocation, TransitionConfig, TransitionWhenContext, TransitionWhenFn, TransitionWhenKind } from "../types/segments.js";
|
|
15
|
+
type ImportedAction = (...args: never[]) => unknown;
|
|
16
|
+
/** A navigation side: a URL, or a partial RouteLocation. */
|
|
17
|
+
export type RunTransitionWhenLocation = string | URL | (Partial<Omit<RouteLocation, "url">> & {
|
|
18
|
+
url?: string | URL;
|
|
19
|
+
});
|
|
20
|
+
/** The action fields of a `kind: "action"` context. */
|
|
21
|
+
export interface RunTransitionWhenAction {
|
|
22
|
+
/** The triggering action: an imported server action or its actionId. */
|
|
23
|
+
ref?: ImportedAction | string;
|
|
56
24
|
formData?: FormData;
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
|
|
25
|
+
/** The action's return value on success. */
|
|
26
|
+
result?: unknown;
|
|
27
|
+
/** What a failed action threw (the error lane). */
|
|
28
|
+
error?: unknown;
|
|
61
29
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
dropped: boolean;
|
|
30
|
+
export interface RunTransitionWhenOptions {
|
|
31
|
+
/** Defaults to `"action"` when `action` is given, `"push"` otherwise. */
|
|
32
|
+
kind?: TransitionWhenKind;
|
|
33
|
+
/** The committed location being left. Defaults to `http://localhost/`. */
|
|
34
|
+
from?: RunTransitionWhenLocation;
|
|
35
|
+
/** The destination. Defaults to `from`; always `from` for "action" and "revalidate". */
|
|
36
|
+
to?: RunTransitionWhenLocation;
|
|
70
37
|
/**
|
|
71
|
-
* The
|
|
72
|
-
*
|
|
38
|
+
* The triggering action (like runClientRevalidate's): an imported server
|
|
39
|
+
* action (id via `$id ?? $$id`), an actionId string, or
|
|
40
|
+
* `{ ref, formData, result, error }`.
|
|
73
41
|
*/
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
42
|
+
action?: ImportedAction | string | RunTransitionWhenAction;
|
|
43
|
+
}
|
|
44
|
+
export interface RunTransitionWhenResult {
|
|
45
|
+
/** True when the navigation holds (the predicate did not return false or throw, or there is none). */
|
|
46
|
+
applied: boolean;
|
|
47
|
+
/** Inverse of `applied`. */
|
|
48
|
+
gatedOff: boolean;
|
|
49
|
+
/** The context the predicate received. */
|
|
50
|
+
context: TransitionWhenContext;
|
|
77
51
|
}
|
|
78
|
-
export declare function runTransitionWhen
|
|
52
|
+
export declare function runTransitionWhen(whenOrConfig: TransitionWhenFn | TransitionConfig, opts?: RunTransitionWhenOptions): RunTransitionWhenResult;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* serveShellRequest — one request through the production PPR serve path.
|
|
3
|
+
*
|
|
4
|
+
* Builds the router's request handler as `router.fetch` does
|
|
5
|
+
* (`createRSCHandler` with the router's `nonce`, `version` and `cache`
|
|
6
|
+
* config) and serves one GET through it, so middleware, the shell serve path
|
|
7
|
+
* and a MISS's background capture all run production code, on real Flight
|
|
8
|
+
* (the vendored react-server-dom serializer). The call settles every
|
|
9
|
+
* background task the request scheduled before it returns, so a MISS's
|
|
10
|
+
* `putShell` has landed.
|
|
11
|
+
*
|
|
12
|
+
* The one stub is the SSR module (the HTML step): `react-dom/server` refuses
|
|
13
|
+
* to load under the react-server condition this project runs with.
|
|
14
|
+
* - `renderHTML` passes the Flight stream through: a document body is its
|
|
15
|
+
* Flight payload.
|
|
16
|
+
* - `captureShellHTML` returns, as the prelude, the Flight text the capture
|
|
17
|
+
* rendered before `quiesce` (plus the post-quiesce task hops the real
|
|
18
|
+
* capture takes). `postponed` is always null. A capture that does not
|
|
19
|
+
* quiesce within what `ppr.captureTimeout` leaves after the handler output
|
|
20
|
+
* settled returns no shell; the real one goes on to its abort and returns
|
|
21
|
+
* whatever prelude rendered by then.
|
|
22
|
+
* - `resumeShellHTML` passes the tail's Flight stream through: a HIT body is
|
|
23
|
+
* the stored prelude followed by the tail's Flight payload.
|
|
24
|
+
* So there is no HTML: the prelude's `<body` sanity gate, SSR render errors
|
|
25
|
+
* (production refuses the capture on one), fizz resume of the holes,
|
|
26
|
+
* bootstrap scripts and nonce injection stay e2e-only. A route whose real
|
|
27
|
+
* capture refuses for a root postpone (a live loader read with no boundary
|
|
28
|
+
* above it) or an SSR render error is captured here.
|
|
29
|
+
*
|
|
30
|
+
* Must run under the `react-server` condition (the rsc Vitest project), with
|
|
31
|
+
* `rangoTestAliases()` resolving `@vitejs/plugin-rsc/rsc/server` to the stub
|
|
32
|
+
* that carries the Flight runtime.
|
|
33
|
+
*/
|
|
34
|
+
import { type Rango } from "../router/router-interfaces.js";
|
|
35
|
+
import type { SegmentCacheStore, ShellCacheEntry } from "../cache/types.js";
|
|
36
|
+
import { type PprReplayStatus, type ShellStatus } from "./shell-status.js";
|
|
37
|
+
/** Options for {@link serveShellRequest}. */
|
|
38
|
+
export interface ServeShellRequestOptions<TEnv = any> {
|
|
39
|
+
/**
|
|
40
|
+
* The shell and segment store for this request, in place of the router's
|
|
41
|
+
* `createRouter({ cache })` store. The rest of that config (`enabled`,
|
|
42
|
+
* `searchParams`) still applies. Omit it to serve through the router's own
|
|
43
|
+
* store.
|
|
44
|
+
*/
|
|
45
|
+
cacheStore?: SegmentCacheStore;
|
|
46
|
+
/** Environment bindings, as `router.fetch(request, { env })` passes them. */
|
|
47
|
+
env?: TEnv;
|
|
48
|
+
/**
|
|
49
|
+
* Request headers. A document request defaults `accept` to `text/html`.
|
|
50
|
+
*/
|
|
51
|
+
headers?: HeadersInit;
|
|
52
|
+
/**
|
|
53
|
+
* Serve the client navigation the browser sends (`?_rsc_partial`) instead
|
|
54
|
+
* of a document GET: from `from` (default `/`) with `segments` mounted
|
|
55
|
+
* (default none), advertising fragment passthrough. The replay decision is
|
|
56
|
+
* `result.replayStatus`.
|
|
57
|
+
*/
|
|
58
|
+
partial?: true | {
|
|
59
|
+
from?: string;
|
|
60
|
+
segments?: readonly string[];
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/** Result of {@link serveShellRequest}. */
|
|
64
|
+
export interface ServeShellRequestResult {
|
|
65
|
+
/** The handler's Response. Its body is already read: see `body`. */
|
|
66
|
+
response: Response;
|
|
67
|
+
/** The response body text. */
|
|
68
|
+
body: string;
|
|
69
|
+
/** `x-rango-shell` (`HIT` | `MISS`), or null when the header is absent. */
|
|
70
|
+
shellStatus: ShellStatus | null;
|
|
71
|
+
/** `x-rango-ppr-replay` on a partial request, or null. */
|
|
72
|
+
replayStatus: PprReplayStatus | null;
|
|
73
|
+
/**
|
|
74
|
+
* The prelude a HIT served: the capture's Flight text at quiesce (the
|
|
75
|
+
* shell as captured). Undefined unless `shellStatus` is `HIT`.
|
|
76
|
+
*/
|
|
77
|
+
prelude: string | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* The Flight payload this request rendered: a HIT's tail, a document's
|
|
80
|
+
* render, or a Flight response. Undefined when no Flight was rendered (a
|
|
81
|
+
* redirect or a middleware response).
|
|
82
|
+
*/
|
|
83
|
+
flight: string | undefined;
|
|
84
|
+
/**
|
|
85
|
+
* The shell key production resolved for this request: for a document the
|
|
86
|
+
* serve path read and captured (a MISS or a HIT), the key it used, request
|
|
87
|
+
* partition included (a route partitioned by `cache({ key })` or the
|
|
88
|
+
* store's `keyGenerator`). Otherwise (a route without `ppr`, a request
|
|
89
|
+
* passed to axis 1 before its key was resolved, a partial request) the
|
|
90
|
+
* document URL's key without a partition, as `shellCacheKey` builds it.
|
|
91
|
+
*/
|
|
92
|
+
key: string;
|
|
93
|
+
/**
|
|
94
|
+
* Read the document shell entry under `key` from the request's store
|
|
95
|
+
* (a passive `getShell`), or null. A read, so on a store with a shell memo
|
|
96
|
+
* (CFCacheStore, VercelCacheStore) it warms the memo like any other read.
|
|
97
|
+
*/
|
|
98
|
+
readEntry(): Promise<ShellCacheEntry | null>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Reset the per-isolate PPR state requests leave behind, so the next test
|
|
102
|
+
* starts as a fresh worker would: the capture's stampede guard, its backoff
|
|
103
|
+
* (a refused capture backs its URL off for later tests too), the shell path's
|
|
104
|
+
* once-per-key warnings, the build-shell manifest memo, the "use cache"
|
|
105
|
+
* in-flight leaders and warnings, and CFCacheStore's isolate memos (shells,
|
|
106
|
+
* tag markers, tag hints) and warnings, which every CFCacheStore in the
|
|
107
|
+
* process shares by namespace and URL. Call it in `beforeEach`, never while
|
|
108
|
+
* a request is in flight. VercelCacheStore's memos live on the `cache`
|
|
109
|
+
* handle it is given: a new handle starts empty.
|
|
110
|
+
*/
|
|
111
|
+
export declare function resetShellTestState(): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* Serve one GET for `url` through the router's production request handler
|
|
114
|
+
* and settle the background tasks it scheduled (a MISS's capture and
|
|
115
|
+
* `putShell` included). The first request for a `ppr` route is a MISS; the
|
|
116
|
+
* next one with the same store is a HIT from the stored shell. The HTML step
|
|
117
|
+
* is stubbed (see the module header), so `prelude` and `flight` are Flight
|
|
118
|
+
* text. The request starts in a later millisecond than the call: a store
|
|
119
|
+
* refuses a capture that starts in the millisecond of a tag invalidation, so
|
|
120
|
+
* an `updateTag()` made just before the call never refuses its recapture.
|
|
121
|
+
* Rejects when the handler throws or the response stream errors (a failing
|
|
122
|
+
* HIT tail), after settling the tasks scheduled so far.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* const store = new MemorySegmentCacheStore();
|
|
126
|
+
* const miss = await serveShellRequest(router, "/product/1", { cacheStore: store });
|
|
127
|
+
* expect(miss.shellStatus).toBe("MISS");
|
|
128
|
+
* const hit = await serveShellRequest(router, "/product/1", { cacheStore: store });
|
|
129
|
+
* expect(hit.shellStatus).toBe("HIT");
|
|
130
|
+
* expect(hit.prelude).toContain("Widget"); // captured shell
|
|
131
|
+
* expect(hit.flight).toContain("in stock"); // live hole, rendered now
|
|
132
|
+
*/
|
|
133
|
+
export declare function serveShellRequest<TEnv = any>(router: Rango<TEnv, any>, url: string | URL, options?: ServeShellRequestOptions<TEnv>): Promise<ServeShellRequestResult>;
|
|
@@ -18,25 +18,25 @@
|
|
|
18
18
|
* Secondary unit signal: `store.getShell(shellCacheKey(url))` after a real
|
|
19
19
|
* capture flush (background `putShell`). There is no Flight flag for shell HIT.
|
|
20
20
|
*
|
|
21
|
-
* 3. **
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
21
|
+
* 3. **A real MISS → capture → HIT in unit tests:** `serveShellRequest`
|
|
22
|
+
* (`@rangojs/router/testing/flight`, serve-shell-request.ts) serves one
|
|
23
|
+
* request through the router's production handler and settles its
|
|
24
|
+
* background capture; a later request with the same store is a real HIT or
|
|
25
|
+
* partial replay. Its only stub is the HTML step (the SSR module).
|
|
26
|
+
* **Stays e2e-only:** real HTML (the prelude's `<body` gate, fizz resume of
|
|
27
|
+
* holes), browser resume of holes, live Cloudflare/Vercel runtimes (store
|
|
28
|
+
* test doubles work in unit), and build-time producer B bake. The unit layer
|
|
29
|
+
* must never stub a shell HIT response.
|
|
26
30
|
*
|
|
27
31
|
* Import from `@rangojs/router/testing` (Vitest) or `@rangojs/router/testing/e2e`
|
|
28
32
|
* (Playwright — same pure helpers, no Vite virtuals).
|
|
29
33
|
*/
|
|
34
|
+
import { PPR_REPLAY_STATUS_HEADER, SHELL_STATUS_HEADER, type PprReplayBypassReason } from "../rsc/shell-capture-constants.js";
|
|
30
35
|
import { type CacheSearchParams } from "../cache/search-params-filter.js";
|
|
31
|
-
|
|
32
|
-
export
|
|
33
|
-
/** Partial-navigation replay decision header from `rsc/rsc-rendering.ts`. */
|
|
34
|
-
export declare const PPR_REPLAY_STATUS_HEADER: string;
|
|
36
|
+
export { PPR_REPLAY_STATUS_HEADER, SHELL_STATUS_HEADER };
|
|
37
|
+
export type { PprReplayBypassReason };
|
|
35
38
|
/** Values the serve path writes on `x-rango-shell`. */
|
|
36
39
|
export type ShellStatus = "HIT" | "MISS";
|
|
37
|
-
declare const PPR_REPLAY_BYPASS_REASONS: readonly ["method", "dynamic", "nonce", "store-unavailable", "passive-read-unsupported", "no-navigation-context", "prerender-store", "intercept", "cache-disabled", "read-error", "no-entry", "invalid-version", "corrupt-entry", "handler-live-holes", "transition-when", "no-segment-snapshot", "snapshot-miss", "explicit-cache-hit", "stale-build-entry"];
|
|
38
|
-
/** Bounded reasons a PPR partial request can fall open to ordinary matching. */
|
|
39
|
-
export type PprReplayBypassReason = (typeof PPR_REPLAY_BYPASS_REASONS)[number];
|
|
40
40
|
/** Parsed `x-rango-ppr-replay` value. */
|
|
41
41
|
export type PprReplayStatus = {
|
|
42
42
|
outcome: "HIT";
|
|
@@ -50,17 +50,43 @@ export type ShellStatusTarget = Response | {
|
|
|
50
50
|
headers: Headers;
|
|
51
51
|
};
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
|
|
53
|
+
* What partitions a ppr route's shell, for {@link shellCacheKey}: the
|
|
54
|
+
* request's results of the functions that partition the route's cache()
|
|
55
|
+
* record.
|
|
56
|
+
*/
|
|
57
|
+
export interface ShellCachePartition {
|
|
58
|
+
/** The route's cache() `key()` results, outermost first. */
|
|
59
|
+
keys?: readonly string[];
|
|
60
|
+
/**
|
|
61
|
+
* Store `keyGenerator` results, one per store, outermost first: an
|
|
62
|
+
* enclosing cache() on another store's, then the store's of the route's
|
|
63
|
+
* own cache() when it sets no `key()` (with no route cache(), the app
|
|
64
|
+
* store's). When every one returns the default key they partition
|
|
65
|
+
* nothing: leave them out. Otherwise each keeps its position, and one
|
|
66
|
+
* that returns the default key is `""`.
|
|
67
|
+
*/
|
|
68
|
+
generated?: readonly string[];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Shell store key for a document URL: the production `buildShellKey` (host +
|
|
72
|
+
* pathname + sorted search + `:shell`) and `partitionShellKey`, both from the
|
|
73
|
+
* React-free leaf `rsc/shell-capture-constants.ts`, so the testing barrel never
|
|
74
|
+
* imports the shell-serve module (it pulls React).
|
|
57
75
|
*
|
|
58
76
|
* Accepts a `URL` or an absolute/relative request URL string (relative strings
|
|
59
77
|
* resolve against `http://localhost`). Pass the router's `cache.searchParams`
|
|
60
78
|
* config as `searchParams` when the app under test sets one — the production
|
|
61
|
-
* key applies it, so the expected key must too.
|
|
79
|
+
* key applies it, so the expected key must too. When the route's record is
|
|
80
|
+
* partitioned by the request, its shell is too: pass what partitions it as
|
|
81
|
+
* `partition`, composed as production composes it (`composeCacheKeys`,
|
|
82
|
+
* which namespaces each `key()` result):
|
|
83
|
+
* - its `cache({ key })` result, as a string;
|
|
84
|
+
* - nested keyed `cache()` scopes' `key()` results, as an array, outermost
|
|
85
|
+
* first;
|
|
86
|
+
* - store `keyGenerator` results, with or without `key()` results, as
|
|
87
|
+
* `{ keys, generated }` (see {@link ShellCachePartition}).
|
|
62
88
|
*/
|
|
63
|
-
export declare function shellCacheKey(url: URL | string, searchParams?: CacheSearchParams): string;
|
|
89
|
+
export declare function shellCacheKey(url: URL | string, searchParams?: CacheSearchParams, partition?: string | readonly string[] | ShellCachePartition): string;
|
|
64
90
|
/**
|
|
65
91
|
* Read `x-rango-shell` from a response. Returns `null` when the header is
|
|
66
92
|
* absent (axis-1 / non-ppr / ineligible request).
|
|
@@ -78,4 +104,3 @@ export declare function assertShellStatus(target: ShellStatusTarget, expected: S
|
|
|
78
104
|
export declare function parsePprReplayStatus(target: ShellStatusTarget): PprReplayStatus | null;
|
|
79
105
|
/** Assert a partial response's PPR replay outcome and freshness/reason. */
|
|
80
106
|
export declare function assertPprReplayStatus(target: ShellStatusTarget, expected: PprReplayStatus): void;
|
|
81
|
-
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* transition({ when }) references: what a route definition may carry as a
|
|
3
|
+
* `when`, how definitions are validated, and how the browser turns the carried
|
|
4
|
+
* value back into a callable predicate.
|
|
5
|
+
*
|
|
6
|
+
* `when` is a BROWSER predicate. The server never calls it; it only carries it
|
|
7
|
+
* to the browser inside the segment's transition config, as one of:
|
|
8
|
+
*
|
|
9
|
+
* - a React client reference: a function exported from a `"use client"`
|
|
10
|
+
* module and imported into a server `urls()` file, or an inline literal the
|
|
11
|
+
* build hoisted into one (vite/plugins/transition-when-hoist.ts). Flight
|
|
12
|
+
* serializes it as a module reference and the browser resolves it to the
|
|
13
|
+
* real function;
|
|
14
|
+
* - a clientUrls() when reference, synthesized by the projection materializer
|
|
15
|
+
* (client-urls/server-projection.ts): the group's definition client
|
|
16
|
+
* reference plus the route id. The browser resolves it to the `when` the
|
|
17
|
+
* route declared in its `"use client"` module.
|
|
18
|
+
*
|
|
19
|
+
* A plain function (a server function) cannot cross Flight, and a
|
|
20
|
+
* non-function is never callable. Both are LOUD errors: route discovery
|
|
21
|
+
* (generateManifestFull `validateTransitionWhen`) fails dev startup, the
|
|
22
|
+
* build and HMR re-discovery, and attachTransitionWhen (rsc/) throws the same
|
|
23
|
+
* error at render time for a route discovery did not see.
|
|
24
|
+
*
|
|
25
|
+
* Telling a client reference apart from a server function needs the
|
|
26
|
+
* react-server module graph, where a `"use client"` import IS a client
|
|
27
|
+
* reference. Outside it (a node/DOM unit-test project that aliases the router
|
|
28
|
+
* entry) the import is the plain function, so strict validation is enabled
|
|
29
|
+
* only by the Vite plugin: discovery passes the option, and the generated
|
|
30
|
+
* routes-manifest module calls enableTransitionWhenValidation() in the app's
|
|
31
|
+
* RSC realm (vite/discovery/virtual-module-codegen.ts).
|
|
32
|
+
*/
|
|
33
|
+
import type { TransitionWhenFn } from "./types/segments.js";
|
|
34
|
+
export declare function isClientReference(value: unknown): boolean;
|
|
35
|
+
export declare function createClientUrlsWhenRef(definition: unknown, routeId: string): TransitionWhenFn;
|
|
36
|
+
/**
|
|
37
|
+
* Turn on server-function rejection for this realm. Called by the Vite
|
|
38
|
+
* plugin's generated routes-manifest module, never by tests: see the module
|
|
39
|
+
* comment for why it cannot be on by default.
|
|
40
|
+
*/
|
|
41
|
+
export declare function enableTransitionWhenValidation(): void;
|
|
42
|
+
export declare function isTransitionWhenValidationEnabled(): boolean;
|
|
43
|
+
/** @internal Reset for unit tests. */
|
|
44
|
+
export declare function resetTransitionWhenValidation(): void;
|
|
45
|
+
/** Thrown for an invalid transition({ when }); recognized by the dev HMR overlay. */
|
|
46
|
+
export declare class TransitionWhenError extends Error {
|
|
47
|
+
readonly name: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The TransitionWhenError in an error's cause chain, matched by name: discovery
|
|
51
|
+
* throws it from the module runner's copy of this module (another class
|
|
52
|
+
* object), and include resolution wraps it (build/generate-manifest.ts).
|
|
53
|
+
*/
|
|
54
|
+
export declare function findTransitionWhenError(error: unknown): Error | undefined;
|
|
55
|
+
/** Where an invalid `when` was declared, for the error message. */
|
|
56
|
+
export interface TransitionWhenSite {
|
|
57
|
+
/** The route the entry belongs to (the matched or enumerated route). */
|
|
58
|
+
readonly routeName?: string;
|
|
59
|
+
readonly pattern?: string;
|
|
60
|
+
/** The declaring entry's type when it is not the route itself. */
|
|
61
|
+
readonly entryType?: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The problem with a `when` value, or null when it is valid. Non-functions
|
|
65
|
+
* are always invalid; a plain function is invalid only under strict
|
|
66
|
+
* validation (see the module comment).
|
|
67
|
+
*/
|
|
68
|
+
export declare function transitionWhenProblem(when: unknown, strict: boolean): "not-a-function" | "server-function" | null;
|
|
69
|
+
export declare function createTransitionWhenError(when: unknown, problem: "not-a-function" | "server-function", site: TransitionWhenSite): TransitionWhenError;
|
|
70
|
+
/**
|
|
71
|
+
* Definition-time shape check (the DSL's transition()). Runs in every
|
|
72
|
+
* environment, so it rejects only what is invalid everywhere: a non-function.
|
|
73
|
+
*/
|
|
74
|
+
export declare function assertTransitionWhenShape(when: unknown): void;
|
|
75
|
+
/**
|
|
76
|
+
* Browser: turn a transition config's `when` into the predicate to call.
|
|
77
|
+
* Undefined when there is none (or a clientUrls route no longer declares it).
|
|
78
|
+
*/
|
|
79
|
+
export declare function resolveTransitionWhen(when: unknown): TransitionWhenFn | undefined;
|
|
@@ -69,7 +69,13 @@ export interface CacheOptions<TEnv = unknown> {
|
|
|
69
69
|
/**
|
|
70
70
|
* Override the cache store for this boundary.
|
|
71
71
|
* When specified, this boundary and its children use this store
|
|
72
|
-
* instead of the app-level store from handler config.
|
|
72
|
+
* instead of the app-level store from handler config. The records of a
|
|
73
|
+
* boundary with a store here are partitioned by the `keyGenerator` of each
|
|
74
|
+
* enclosing cache() without a `key` whose store differs, the app-level
|
|
75
|
+
* store included: under `cache(() => [...])` on an app store with a
|
|
76
|
+
* `keyGenerator`, `cache({ store })` records are split by its result too.
|
|
77
|
+
* Likewise, without a `key` of its own, this store's `keyGenerator`
|
|
78
|
+
* partitions a nested cache() on another store.
|
|
73
79
|
*
|
|
74
80
|
* Useful for:
|
|
75
81
|
* - Different backends per route section (memory vs KV vs Redis)
|
|
@@ -104,6 +110,8 @@ export interface CacheOptions<TEnv = unknown> {
|
|
|
104
110
|
/**
|
|
105
111
|
* Conditional cache read function.
|
|
106
112
|
* Return false to skip cache for this request (always fetch fresh).
|
|
113
|
+
* It gates every cache() nested under this one too: a nested boundary
|
|
114
|
+
* caches only when every enclosing condition allows it.
|
|
107
115
|
*
|
|
108
116
|
* Has access to full RequestContext including env, request, params, cookies, etc.
|
|
109
117
|
* Runs after global and route middleware on RSC routes; on response routes,
|
|
@@ -123,7 +131,10 @@ export interface CacheOptions<TEnv = unknown> {
|
|
|
123
131
|
condition?: (ctx: import("../server/request-context.js").RequestContext<TEnv>) => boolean;
|
|
124
132
|
/**
|
|
125
133
|
* Custom cache key function - FULL OVERRIDE.
|
|
126
|
-
* Bypasses default key generation AND store's keyGenerator.
|
|
134
|
+
* Bypasses default key generation AND store's keyGenerator. The result is
|
|
135
|
+
* stored namespaced (`key:` plus its URI encoding), so no value it returns
|
|
136
|
+
* names another route's record; a nested cache() keys its records within
|
|
137
|
+
* this partition.
|
|
127
138
|
*
|
|
128
139
|
* Has access to full RequestContext including env, request, params, cookies, etc.
|
|
129
140
|
* Runs after global and route middleware on RSC routes; on response routes,
|
|
@@ -144,7 +155,8 @@ export interface CacheOptions<TEnv = unknown> {
|
|
|
144
155
|
key?: (ctx: import("../server/request-context.js").RequestContext<TEnv>) => string | Promise<string>;
|
|
145
156
|
/**
|
|
146
157
|
* Tags for cache invalidation.
|
|
147
|
-
* Can be a static array or a function that returns tags.
|
|
158
|
+
* Can be a static array or a function that returns tags. They tag the
|
|
159
|
+
* records of every cache() nested under this one too.
|
|
148
160
|
*
|
|
149
161
|
* The built-in `MemorySegmentCacheStore`, `CFCacheStore`, and
|
|
150
162
|
* `VercelCacheStore` index by tag.
|
|
@@ -235,6 +235,12 @@ export type HandlerContext<TParams = {}, TEnv = DefaultEnv, TSearch extends Sear
|
|
|
235
235
|
* Current theme (from cookie or default).
|
|
236
236
|
* Only available when theme is enabled in router config.
|
|
237
237
|
*
|
|
238
|
+
* The visitor's cookie, so it is guarded like `cookies()`: reading it on a
|
|
239
|
+
* `ppr` route refuses the shell capture, and inside a `cache()` boundary or
|
|
240
|
+
* a `"use cache"` function it throws (#971). Read it with `useTheme()` in a
|
|
241
|
+
* client component, or in a live loader, on those routes. A read-only,
|
|
242
|
+
* non-enumerable getter: `{ ...ctx }` does not carry it.
|
|
243
|
+
*
|
|
238
244
|
* @example
|
|
239
245
|
* ```typescript
|
|
240
246
|
* route("settings", (ctx) => {
|
|
@@ -243,7 +249,7 @@ export type HandlerContext<TParams = {}, TEnv = DefaultEnv, TSearch extends Sear
|
|
|
243
249
|
* });
|
|
244
250
|
* ```
|
|
245
251
|
*/
|
|
246
|
-
theme?: Theme;
|
|
252
|
+
readonly theme?: Theme;
|
|
247
253
|
/**
|
|
248
254
|
* Set the theme (only available when theme is enabled in router config).
|
|
249
255
|
* Sets a cookie with the new theme value.
|
|
@@ -349,6 +355,13 @@ export type InternalHandlerContext<TParams = {}, TEnv = DefaultEnv, TSearch exte
|
|
|
349
355
|
* from the page. See setupLoaderAccess.
|
|
350
356
|
*/
|
|
351
357
|
_runLoaderIsolated?: (loader: any) => Promise<any>;
|
|
358
|
+
/**
|
|
359
|
+
* @internal A loader's cache() binding started with these cache() tags: an
|
|
360
|
+
* execution of that loader outside the binding (a reader started it first,
|
|
361
|
+
* or a stale refresh runs it) answers for them too (#964). See
|
|
362
|
+
* setupLoaderAccess.
|
|
363
|
+
*/
|
|
364
|
+
_bindLoaderCacheTags?: (loaderId: string, tags: Set<string>) => void;
|
|
352
365
|
};
|
|
353
366
|
/**
|
|
354
367
|
* Generic params type - flexible object with string keys
|
|
@@ -4,7 +4,7 @@ export type { DocumentProps, ExtractParams, TrailingSlashMode, RouteConfig, Rout
|
|
|
4
4
|
export type { ErrorInfo, ErrorBoundaryFallbackProps, ErrorBoundaryHandler, ClientErrorBoundaryFallbackProps, LoaderDataResult, NotFoundInfo, NotFoundBoundaryFallbackProps, NotFoundBoundaryHandler, } from "./boundaries.js";
|
|
5
5
|
export { isLoaderDataResult } from "./boundaries.js";
|
|
6
6
|
export type { MiddlewareFn, ScopedRouteMap, Handler, HandlerContext, InternalHandlerContext, GenericParams, RevalidateParams, ShouldRevalidateFn, ActionRef, IsActionFn, RouteKeys, ExtractRouteParams, HandlersForRouteMap, Revalidate, Middleware, } from "./handler-context.js";
|
|
7
|
-
export type { ViewTransitionClass, TransitionConfig, TransitionWhenFn, TransitionWhenContext, ResolvedSegment, SegmentMetadata, SlotState, RootLayoutProps, MatchResult, } from "./segments.js";
|
|
7
|
+
export type { ViewTransitionClass, TransitionConfig, TransitionWhenFn, TransitionWhenContext, TransitionWhenKind, RouteLocation, ServerRouteLocation, ResolvedSegment, SegmentMetadata, SlotState, RootLayoutProps, MatchResult, } from "./segments.js";
|
|
8
8
|
export type { LazyIncludeContext, RouteEntry } from "./route-entry.js";
|
|
9
9
|
export type { LoaderContext, LoaderFn, FetchableLoaderOptions, LoaderOptions, LoadOptions, LoaderDefinition, } from "./loader-types.js";
|
|
10
10
|
export type { CacheContext, CacheOptions, PartialCacheOptions, EntryCacheConfig, } from "./cache-types.js";
|