@rangojs/router 0.20.0 → 0.22.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/dist/bin/rango.js +39 -15
- package/dist/types/browser/event-controller.d.ts +49 -0
- package/dist/types/browser/history-state.d.ts +16 -4
- package/dist/types/browser/navigation-store.d.ts +9 -0
- package/dist/types/browser/navigation-transaction.d.ts +7 -0
- package/dist/types/browser/partial-update.d.ts +2 -1
- package/dist/types/browser/prefetch/default-strategy.d.ts +16 -20
- package/dist/types/browser/rango-state.d.ts +3 -1
- package/dist/types/browser/react/NavigationProvider.d.ts +14 -1
- package/dist/types/browser/react/context.d.ts +25 -0
- package/dist/types/browser/react/location-state-shared.d.ts +84 -10
- package/dist/types/browser/react/location-state.d.ts +7 -2
- package/dist/types/browser/rsc-router.d.ts +13 -2
- package/dist/types/browser/types.d.ts +10 -0
- package/dist/types/build/generate-manifest.d.ts +2 -0
- package/dist/types/cache/background-task.d.ts +22 -0
- package/dist/types/cache/cache-key-utils.d.ts +50 -5
- package/dist/types/cache/cache-policy.d.ts +17 -0
- package/dist/types/cache/cache-scope.d.ts +5 -6
- package/dist/types/cache/cf/cf-cache-store.d.ts +34 -7
- package/dist/types/cache/cf/cf-cache-types.d.ts +12 -4
- package/dist/types/cache/document-cache.d.ts +8 -5
- package/dist/types/cache/handle-snapshot.d.ts +59 -50
- package/dist/types/cache/index.d.ts +3 -1
- package/dist/types/cache/invalidation-order.d.ts +14 -0
- package/dist/types/cache/memory-segment-store.d.ts +33 -1
- package/dist/types/cache/shell-snapshot.d.ts +29 -4
- package/dist/types/cache/store-scope.d.ts +22 -0
- package/dist/types/cache/tag-invalidation.d.ts +7 -6
- package/dist/types/cache/types.d.ts +84 -24
- package/dist/types/cache/vercel/vercel-cache-store.d.ts +35 -17
- package/dist/types/client-urls/navigation.d.ts +7 -1
- package/dist/types/client-urls/optimistic-location.d.ts +10 -4
- package/dist/types/errors.d.ts +6 -0
- package/dist/types/handles/deferred-resolution.d.ts +18 -1
- package/dist/types/internal-suspense-audit.d.ts +1 -0
- package/dist/types/loader-store.d.ts +4 -8
- package/dist/types/outlet-provider.d.ts +2 -1
- package/dist/types/prerender/build-shell-capture.d.ts +8 -6
- package/dist/types/prerender/cloudflare.d.ts +49 -0
- package/dist/types/prerender/create-prerender-trigger.d.ts +121 -0
- package/dist/types/prerender/index.d.ts +12 -0
- package/dist/types/prerender/memory-prerender-store.d.ts +29 -0
- package/dist/types/prerender/on-demand.d.ts +272 -0
- package/dist/types/prerender/producer-guard.d.ts +33 -0
- package/dist/types/prerender/shell-manifest-key.d.ts +1 -18
- package/dist/types/prerender/warm-request.d.ts +65 -0
- package/dist/types/prerender/warm.d.ts +65 -0
- package/dist/types/prerender/writable-store.d.ts +170 -0
- package/dist/types/prerender.d.ts +27 -0
- package/dist/types/reverse.d.ts +1 -1
- package/dist/types/route-content-wrapper.d.ts +3 -1
- package/dist/types/router/error-handling.d.ts +2 -0
- package/dist/types/router/handler-context.d.ts +1 -1
- package/dist/types/router/match-middleware/cache-lookup.d.ts +15 -1
- package/dist/types/router/navigation-snapshot.d.ts +8 -1
- package/dist/types/router/pattern-matching.d.ts +2 -0
- package/dist/types/router/prefetch-default.d.ts +4 -4
- package/dist/types/router/prerender-match.d.ts +23 -1
- package/dist/types/router/route-trie-builder.d.ts +8 -1
- package/dist/types/router/router-context.d.ts +1 -0
- package/dist/types/router/router-interfaces.d.ts +32 -1
- package/dist/types/router/router-options.d.ts +39 -5
- package/dist/types/router/segment-resolution/fresh.d.ts +7 -0
- package/dist/types/router/segment-resolution/loader-cache.d.ts +23 -10
- package/dist/types/router/segment-resolution/revalidation.d.ts +5 -1
- package/dist/types/router/segment-resolution/streamed-handler-boundary.d.ts +43 -0
- package/dist/types/router/trie-matching.d.ts +2 -0
- package/dist/types/router-versions.d.ts +39 -0
- package/dist/types/rsc/handler-context.d.ts +5 -0
- package/dist/types/rsc/shell-build-manifest.d.ts +9 -6
- package/dist/types/rsc/shell-capture-constants.d.ts +20 -5
- package/dist/types/rsc/shell-capture.d.ts +14 -1
- package/dist/types/rsc/shell-serve.d.ts +2 -2
- package/dist/types/rsc/ssr-module-loader.d.ts +15 -0
- package/dist/types/rsc/types.d.ts +12 -6
- package/dist/types/segment-boundary-content.d.ts +17 -0
- package/dist/types/segment-loader-promise.d.ts +2 -6
- package/dist/types/server/build-version-table.d.ts +53 -0
- package/dist/types/server/context.d.ts +12 -4
- package/dist/types/server/handle-store.d.ts +89 -46
- package/dist/types/server/request-context.d.ts +84 -9
- package/dist/types/suspense-audit-react.d.ts +26 -0
- package/dist/types/suspense-audit.d.ts +157 -0
- package/dist/types/testing/action-form.d.ts +34 -0
- package/dist/types/testing/build-versions.d.ts +32 -0
- package/dist/types/testing/dom.entry.d.ts +1 -1
- package/dist/types/testing/flight.entry.d.ts +3 -1
- package/dist/types/testing/index.d.ts +6 -0
- package/dist/types/testing/internal/seed-vars.d.ts +7 -2
- package/dist/types/testing/internal/server-modules.d.ts +8 -0
- package/dist/types/testing/location-state-key.d.ts +5 -1
- package/dist/types/testing/render-route.d.ts +77 -6
- package/dist/types/testing/serve-shell-request.d.ts +55 -4
- package/dist/types/testing/shell-status.d.ts +14 -6
- package/dist/types/testing/vitest-stubs/plugin-rsc.d.ts +9 -6
- package/dist/types/testing/vitest-stubs/version.d.ts +1 -0
- package/dist/types/thenable-status.d.ts +6 -0
- package/dist/types/types/handler-context.d.ts +15 -5
- package/dist/types/types/route-entry.d.ts +5 -0
- package/dist/types/urls/path-helper.d.ts +18 -0
- package/dist/types/vite/discovery/build-versions.d.ts +393 -0
- package/dist/types/vite/discovery/installed-packages.d.ts +26 -0
- package/dist/types/vite/discovery/router-versions-phase.d.ts +52 -0
- package/dist/types/vite/discovery/shell-prerender-phase.d.ts +7 -17
- package/dist/types/vite/discovery/state.d.ts +25 -0
- package/dist/types/vite/encryption-key.d.ts +18 -0
- package/dist/types/vite/inject-client-debug.d.ts +6 -25
- package/dist/types/vite/plugin-types.d.ts +27 -0
- package/dist/types/vite/plugins/{version-injector.d.ts → entry-bootstrap-injector.d.ts} +4 -6
- package/dist/types/vite/plugins/expose-ids/export-analysis.d.ts +1 -0
- package/dist/types/vite/plugins/expose-ids/router-transform.d.ts +14 -0
- package/dist/types/vite/plugins/stable-rsc-output.d.ts +51 -0
- package/dist/types/vite/plugins/version-plugin.d.ts +9 -11
- package/dist/types/vite/plugins/virtual-entries.d.ts +18 -1
- package/dist/types/vite/router-discovery.d.ts +6 -0
- package/dist/types/vite/utils/bundle-analysis.d.ts +6 -2
- package/dist/types/vite/utils/client-chunks.d.ts +2 -0
- package/dist/types/vite/utils/compare-strings.d.ts +7 -0
- package/dist/types/vite/utils/package-resolution.d.ts +8 -0
- package/dist/types/vite/utils/prerender-utils.d.ts +2 -0
- package/dist/vite/index.js +1707 -931
- package/package.json +12 -3
- package/skills/cache-guide/SKILL.md +102 -37
- package/skills/caching/SKILL.md +56 -9
- package/skills/catalog.json +1 -1
- package/skills/client-urls/SKILL.md +16 -0
- package/skills/cloudflare/SKILL.md +133 -1
- package/skills/comparison/references/framework-comparison.md +17 -13
- package/skills/deployment-caching/SKILL.md +33 -12
- package/skills/document-cache/SKILL.md +16 -14
- package/skills/hooks/SKILL.md +25 -0
- package/skills/hooks/handle-and-actions.md +5 -0
- package/skills/hooks/navigation.md +38 -0
- package/skills/hooks/state.md +213 -11
- package/skills/hooks/urls.md +40 -1
- package/skills/host-router/SKILL.md +31 -0
- package/skills/intercept/SKILL.md +6 -0
- package/skills/loader/SKILL.md +25 -5
- package/skills/middleware/SKILL.md +2 -0
- package/skills/migrate-nextjs/SKILL.md +82 -9
- package/skills/ppr/SKILL.md +150 -48
- package/skills/prerender/SKILL.md +651 -10
- package/skills/rango/SKILL.md +9 -7
- package/skills/response-routes/SKILL.md +5 -5
- package/skills/route/SKILL.md +29 -0
- package/skills/router-setup/SKILL.md +15 -1
- package/skills/testing/SKILL.md +32 -27
- package/skills/testing/cache-prerender.md +18 -17
- package/skills/testing/client-components.md +193 -8
- package/skills/testing/handles.md +2 -0
- package/skills/testing/loader.md +1 -1
- package/skills/testing/middleware.md +1 -1
- package/skills/testing/render-handler.md +18 -18
- package/skills/testing/serve-shell-request.md +167 -22
- package/skills/testing/server-actions.md +17 -17
- package/skills/testing/server-tree.md +1 -1
- package/skills/typesafety/generated-files-and-cli.md +1 -1
- package/skills/use-cache/SKILL.md +25 -10
- package/skills/vercel/SKILL.md +5 -3
- package/skills/view-transitions/SKILL.md +9 -4
- package/src/bin/rango.ts +1 -1
- package/src/browser/event-controller.ts +119 -2
- package/src/browser/history-state.ts +39 -17
- package/src/browser/link-interceptor.ts +2 -2
- package/src/browser/navigation-bridge.ts +104 -41
- package/src/browser/navigation-store.ts +26 -0
- package/src/browser/navigation-transaction.ts +24 -12
- package/src/browser/network-error-handler.ts +2 -0
- package/src/browser/partial-update.ts +58 -14
- package/src/browser/prefetch/default-strategy.ts +22 -42
- package/src/browser/rango-state.ts +3 -1
- package/src/browser/react/Link.tsx +37 -43
- package/src/browser/react/NavigationProvider.tsx +85 -1
- package/src/browser/react/context.ts +30 -0
- package/src/browser/react/location-state-shared.ts +200 -34
- package/src/browser/react/location-state.ts +28 -77
- package/src/browser/react/use-action.ts +4 -1
- package/src/browser/react/use-handle.ts +3 -0
- package/src/browser/react/use-link-status.ts +4 -3
- package/src/browser/react/use-navigation.ts +4 -1
- package/src/browser/react/use-params.ts +4 -1
- package/src/browser/react/use-pathname.ts +4 -1
- package/src/browser/react/use-search-params.ts +5 -3
- package/src/browser/react/use-segments.ts +36 -54
- package/src/browser/rsc-router.tsx +93 -31
- package/src/browser/segment-reconciler.ts +3 -3
- package/src/browser/server-action-bridge.ts +43 -7
- package/src/browser/types.ts +11 -0
- package/src/build/generate-manifest.ts +17 -0
- package/src/build/merge-full-manifests.ts +5 -0
- package/src/build/route-trie.ts +1 -0
- package/src/cache/background-task.ts +61 -0
- package/src/cache/cache-key-utils.ts +91 -12
- package/src/cache/cache-policy.ts +11 -2
- package/src/cache/cache-runtime.ts +23 -23
- package/src/cache/cache-scope.ts +48 -36
- package/src/cache/cf/cf-cache-store.ts +91 -66
- package/src/cache/cf/cf-cache-types.ts +12 -4
- package/src/cache/document-cache.ts +35 -14
- package/src/cache/handle-snapshot.ts +118 -86
- package/src/cache/index.ts +5 -0
- package/src/cache/invalidation-order.ts +53 -0
- package/src/cache/memory-segment-store.ts +52 -1
- package/src/cache/shell-snapshot.ts +52 -5
- package/src/cache/store-scope.ts +36 -0
- package/src/cache/tag-invalidation.ts +7 -5
- package/src/cache/types.ts +90 -24
- package/src/cache/vercel/vercel-cache-store.ts +68 -26
- package/src/client-urls/client-root.tsx +1 -0
- package/src/client-urls/navigation.ts +10 -0
- package/src/client-urls/optimistic-location.ts +10 -4
- package/src/client.tsx +40 -3
- package/src/errors.ts +13 -6
- package/src/handles/deferred-resolution.ts +36 -0
- package/src/internal-suspense-audit.ts +12 -0
- package/src/loader-store.ts +4 -9
- package/src/outlet-provider.tsx +25 -1
- package/src/prerender/build-shell-capture.ts +11 -9
- package/src/prerender/cloudflare.ts +130 -0
- package/src/prerender/create-prerender-trigger.ts +780 -0
- package/src/prerender/index.ts +39 -0
- package/src/prerender/memory-prerender-store.ts +115 -0
- package/src/prerender/on-demand.ts +339 -0
- package/src/prerender/producer-guard.ts +66 -0
- package/src/prerender/shell-manifest-key.ts +12 -17
- package/src/prerender/warm-request.ts +154 -0
- package/src/prerender/warm.ts +193 -0
- package/src/prerender/writable-store.ts +278 -0
- package/src/prerender.ts +29 -0
- package/src/reverse.ts +1 -1
- package/src/route-content-wrapper.tsx +107 -13
- package/src/router/error-handling.ts +12 -12
- package/src/router/find-match.ts +1 -0
- package/src/router/handler-context.ts +2 -0
- package/src/router/intercept-resolution.ts +15 -8
- package/src/router/loader-resolution.ts +2 -10
- package/src/router/manifest.ts +2 -0
- package/src/router/match-middleware/background-revalidation.ts +2 -0
- package/src/router/match-middleware/cache-lookup.ts +239 -54
- package/src/router/navigation-snapshot.ts +25 -6
- package/src/router/pattern-matching.ts +14 -0
- package/src/router/prefetch-default.ts +4 -4
- package/src/router/prerender-match.ts +460 -352
- package/src/router/request-classification.ts +15 -12
- package/src/router/route-trie-builder.ts +9 -0
- package/src/router/router-context.ts +1 -0
- package/src/router/router-interfaces.ts +35 -1
- package/src/router/router-options.ts +45 -5
- package/src/router/segment-resolution/fresh.ts +20 -19
- package/src/router/segment-resolution/loader-cache.ts +110 -77
- package/src/router/segment-resolution/revalidation.ts +34 -24
- package/src/router/segment-resolution/streamed-handler-boundary.ts +133 -0
- package/src/router/trie-matching.ts +3 -0
- package/src/router-versions.ts +60 -0
- package/src/router.ts +107 -1
- package/src/rsc/full-payload.ts +6 -2
- package/src/rsc/handler-context.ts +5 -0
- package/src/rsc/handler.ts +64 -7
- package/src/rsc/progressive-enhancement.ts +5 -1
- package/src/rsc/response-cache-serve.ts +10 -4
- package/src/rsc/rsc-rendering.ts +65 -12
- package/src/rsc/shell-build-manifest.ts +17 -12
- package/src/rsc/shell-capture-constants.ts +39 -7
- package/src/rsc/shell-capture.ts +144 -45
- package/src/rsc/shell-serve.ts +12 -6
- package/src/rsc/ssr-module-loader.ts +26 -0
- package/src/rsc/types.ts +12 -6
- package/src/segment-boundary-content.ts +25 -0
- package/src/segment-loader-promise.ts +28 -38
- package/src/segment-system.tsx +117 -57
- package/src/server/build-version-table.ts +130 -0
- package/src/server/context.ts +40 -17
- package/src/server/cookie-store.ts +5 -0
- package/src/server/handle-store.ts +357 -127
- package/src/server/request-context.ts +149 -12
- package/src/ssr/ssr-root.tsx +32 -13
- package/src/suspense-audit-react.tsx +98 -0
- package/src/suspense-audit.ts +1030 -0
- package/src/testing/action-form.ts +66 -0
- package/src/testing/build-versions.ts +64 -0
- package/src/testing/dispatch.ts +6 -0
- package/src/testing/dom.entry.ts +1 -0
- package/src/testing/flight-runtime.d.ts +27 -0
- package/src/testing/flight.entry.ts +4 -0
- package/src/testing/index.ts +22 -0
- package/src/testing/internal/context.ts +2 -1
- package/src/testing/internal/seed-vars.ts +14 -2
- package/src/testing/internal/server-modules.ts +32 -0
- package/src/testing/location-state-key.ts +18 -8
- package/src/testing/render-handler.ts +2 -1
- package/src/testing/render-route.tsx +293 -46
- package/src/testing/serve-shell-request.ts +262 -37
- package/src/testing/shell-status.ts +17 -6
- package/src/testing/vitest-stubs/plugin-rsc.ts +37 -11
- package/src/testing/vitest-stubs/version.ts +4 -1
- package/src/thenable-status.ts +10 -0
- package/src/types/handler-context.ts +15 -5
- package/src/types/route-entry.ts +6 -0
- package/src/urls/path-helper.ts +69 -9
- package/src/use-loader.tsx +57 -30
- package/src/vite/discovery/build-versions.ts +1281 -0
- package/src/vite/discovery/bundle-postprocess.ts +4 -0
- package/src/vite/discovery/discover-routers.ts +15 -0
- package/src/vite/discovery/installed-packages.ts +159 -0
- package/src/vite/discovery/prerender-collection.ts +38 -1
- package/src/vite/discovery/router-versions-phase.ts +336 -0
- package/src/vite/discovery/shell-prerender-phase.ts +33 -43
- package/src/vite/discovery/state.ts +36 -1
- package/src/vite/discovery/virtual-module-codegen.ts +7 -2
- package/src/vite/encryption-key.ts +101 -9
- package/src/vite/inject-client-debug.ts +42 -20
- package/src/vite/plugin-types.ts +28 -0
- package/src/vite/plugins/{version-injector.ts → entry-bootstrap-injector.ts} +7 -22
- package/src/vite/plugins/expose-ids/export-analysis.ts +1 -1
- package/src/vite/plugins/expose-ids/router-transform.ts +36 -15
- package/src/vite/plugins/expose-internal-ids.ts +12 -3
- package/src/vite/plugins/stable-rsc-output.ts +147 -0
- package/src/vite/plugins/version-plugin.ts +19 -24
- package/src/vite/plugins/version.d.ts +17 -2
- package/src/vite/plugins/virtual-entries.ts +39 -6
- package/src/vite/rango.ts +28 -3
- package/src/vite/router-discovery.ts +96 -13
- package/src/vite/utils/bundle-analysis.ts +39 -7
- package/src/vite/utils/client-chunks.ts +5 -1
- package/src/vite/utils/compare-strings.ts +9 -0
- package/src/vite/utils/package-resolution.ts +9 -0
- package/src/vite/utils/prerender-utils.ts +4 -1
- package/src/vite/utils/shared-utils.ts +1 -1
- package/dist/types/segment-content-promise.d.ts +0 -13
- package/src/segment-content-promise.ts +0 -67
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import type { ReactNode } from "react";
|
|
3
|
-
import { Component, Suspense, use } from "react";
|
|
4
|
-
import { OutletProvider } from "./outlet-provider.js";
|
|
2
|
+
import type { ComponentProps, ReactElement, ReactNode } from "react";
|
|
3
|
+
import { Component, Suspense, use, useMemo } from "react";
|
|
4
|
+
import { AuditedOutletProvider, OutletProvider } from "./outlet-provider.js";
|
|
5
5
|
import type { ResolvedSegment } from "./types.js";
|
|
6
6
|
import {
|
|
7
7
|
decodeLoaderResults,
|
|
@@ -10,6 +10,12 @@ import {
|
|
|
10
10
|
LOADER_REDIRECT,
|
|
11
11
|
} from "./decode-loader-results.js";
|
|
12
12
|
import { LoaderRedirect } from "./loader-redirect.js";
|
|
13
|
+
import type { BoundaryAudit } from "./suspense-audit.js";
|
|
14
|
+
import {
|
|
15
|
+
AuditedFallback,
|
|
16
|
+
useBoundaryAudit,
|
|
17
|
+
useRevealAudit,
|
|
18
|
+
} from "./suspense-audit-react.js";
|
|
13
19
|
|
|
14
20
|
/**
|
|
15
21
|
* Router-owned error boundary for read-site loader errors. segment-system
|
|
@@ -97,8 +103,8 @@ export function RouteContentWrapper({
|
|
|
97
103
|
fallback,
|
|
98
104
|
segmentId,
|
|
99
105
|
}: {
|
|
100
|
-
//
|
|
101
|
-
//
|
|
106
|
+
// A pending promise suspends (use()) and shows the fallback; a node renders
|
|
107
|
+
// without suspending (see getBoundaryContent).
|
|
102
108
|
content: Promise<ReactNode> | ReactNode;
|
|
103
109
|
fallback?: ReactNode;
|
|
104
110
|
segmentId?: string;
|
|
@@ -113,19 +119,62 @@ export function RouteContentWrapper({
|
|
|
113
119
|
);
|
|
114
120
|
}
|
|
115
121
|
|
|
122
|
+
// Dev only (suspense-audit.ts): RouteContentWrapper's Suspense, keys and
|
|
123
|
+
// content, with the audit's hooks in components of their own.
|
|
124
|
+
//
|
|
125
|
+
// Chosen where the element is created, inside a NODE_ENV test, so a build
|
|
126
|
+
// folds to the product component and nothing else. Two other ways leave
|
|
127
|
+
// bytes in cloudflare-basic's router chunk, both measured: a dev branch
|
|
128
|
+
// inside the product component (React Compiler runs before NODE_ENV is
|
|
129
|
+
// folded and keeps the branch's memo slots, +76 B gzip), and one
|
|
130
|
+
// `export const X = dev ? Audited : Product` per module (the alias statement
|
|
131
|
+
// survives minification, +27 B gzip for three).
|
|
132
|
+
//
|
|
133
|
+
// Line comments on purpose, here and on the other dev-only declarations: the
|
|
134
|
+
// server bundles are not minified and keep a JSDoc block even when the
|
|
135
|
+
// declaration under it is removed.
|
|
136
|
+
export function AuditedRouteContent({
|
|
137
|
+
content,
|
|
138
|
+
fallback,
|
|
139
|
+
segmentId,
|
|
140
|
+
}: ComponentProps<typeof RouteContentWrapper>): ReactNode {
|
|
141
|
+
const audit = useBoundaryAudit(
|
|
142
|
+
`content:${segmentId}`,
|
|
143
|
+
segmentId ?? "",
|
|
144
|
+
content,
|
|
145
|
+
);
|
|
146
|
+
return (
|
|
147
|
+
<Suspense
|
|
148
|
+
fallback={
|
|
149
|
+
<AuditedFallback audit={audit}>{fallback ?? null}</AuditedFallback>
|
|
150
|
+
}
|
|
151
|
+
key={segmentId ? "route-content-suspense-" + segmentId : undefined}
|
|
152
|
+
>
|
|
153
|
+
<AuditedSuspender content={content} audit={audit} key={segmentId} />
|
|
154
|
+
</Suspense>
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function AuditedSuspender({
|
|
159
|
+
content,
|
|
160
|
+
audit,
|
|
161
|
+
}: {
|
|
162
|
+
content: Promise<ReactNode> | ReactNode;
|
|
163
|
+
audit: BoundaryAudit;
|
|
164
|
+
}): ReactNode {
|
|
165
|
+
useRevealAudit(audit);
|
|
166
|
+
return Suspender({ content });
|
|
167
|
+
}
|
|
168
|
+
|
|
116
169
|
const Suspender = ({
|
|
117
170
|
content,
|
|
118
171
|
}: {
|
|
119
172
|
content: Promise<ReactNode> | ReactNode;
|
|
120
173
|
}): ReactNode => {
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
//
|
|
125
|
-
// fallback on a NORMAL (non-transition) commit. The wrapper tree
|
|
126
|
-
// (RouteContentWrapper > Suspense > Suspender) is identical either way, so this
|
|
127
|
-
// preserves tree structure (see docs/tree-structure.md) — only whether use()
|
|
128
|
-
// suspends differs, exactly like LoaderResolver's resolved-data branch.
|
|
174
|
+
// A pending promise suspends here and the wrapping Suspense shows the
|
|
175
|
+
// loading() fallback; a node renders without suspending. The wrapper tree
|
|
176
|
+
// (RouteContentWrapper > Suspense > Suspender) is identical either way (see
|
|
177
|
+
// docs/tree-structure.md), like LoaderResolver's resolved-data branch.
|
|
129
178
|
return content instanceof Promise ? use(content) : content;
|
|
130
179
|
};
|
|
131
180
|
|
|
@@ -191,6 +240,51 @@ export function LoaderBoundary({
|
|
|
191
240
|
);
|
|
192
241
|
}
|
|
193
242
|
|
|
243
|
+
// Dev only (suspense-audit.ts): LoaderBoundary, as AuditedRouteContent.
|
|
244
|
+
export function AuditedLoaderBoundary({
|
|
245
|
+
fallback,
|
|
246
|
+
children,
|
|
247
|
+
...resolver
|
|
248
|
+
}: LoaderBoundaryProps): ReactNode {
|
|
249
|
+
const nodes = useMemo(
|
|
250
|
+
() => [children, resolver.outletContent],
|
|
251
|
+
[children, resolver.outletContent],
|
|
252
|
+
);
|
|
253
|
+
const audit = useBoundaryAudit(
|
|
254
|
+
`loaders:${resolver.outletKey}`,
|
|
255
|
+
resolver.segment.id,
|
|
256
|
+
resolver.loaderDataPromise,
|
|
257
|
+
resolver.loaderStreams,
|
|
258
|
+
nodes,
|
|
259
|
+
);
|
|
260
|
+
return (
|
|
261
|
+
<Suspense
|
|
262
|
+
fallback={
|
|
263
|
+
<AuditedFallback audit={audit}>{fallback ?? null}</AuditedFallback>
|
|
264
|
+
}
|
|
265
|
+
key={`loader-boundary-${resolver.outletKey}`}
|
|
266
|
+
>
|
|
267
|
+
<AuditedLoaderResolver audit={audit} {...resolver}>
|
|
268
|
+
{children}
|
|
269
|
+
</AuditedLoaderResolver>
|
|
270
|
+
</Suspense>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function AuditedLoaderResolver({
|
|
275
|
+
audit,
|
|
276
|
+
...props
|
|
277
|
+
}: Omit<LoaderBoundaryProps, "fallback"> & {
|
|
278
|
+
audit: BoundaryAudit;
|
|
279
|
+
}): ReactNode {
|
|
280
|
+
useRevealAudit(audit);
|
|
281
|
+
// The resolver's OutletProvider, as its audited component.
|
|
282
|
+
const outlet = LoaderResolver(props) as ReactElement<
|
|
283
|
+
ComponentProps<typeof OutletProvider>
|
|
284
|
+
>;
|
|
285
|
+
return <AuditedOutletProvider {...outlet.props} key={outlet.key} />;
|
|
286
|
+
}
|
|
287
|
+
|
|
194
288
|
/**
|
|
195
289
|
* Internal component that resolves loader promises and renders OutletProvider
|
|
196
290
|
*
|
|
@@ -271,6 +271,17 @@ export function createErrorInfo(
|
|
|
271
271
|
};
|
|
272
272
|
}
|
|
273
273
|
|
|
274
|
+
/** Invoke an errorBoundary() fallback that may be a handler or a plain node. */
|
|
275
|
+
export function renderErrorFallback(
|
|
276
|
+
fallback: ReactNode | ErrorBoundaryHandler,
|
|
277
|
+
errorInfo: ErrorInfo,
|
|
278
|
+
): ReactNode {
|
|
279
|
+
if (typeof fallback === "function") {
|
|
280
|
+
return fallback({ error: errorInfo } satisfies ErrorBoundaryFallbackProps);
|
|
281
|
+
}
|
|
282
|
+
return fallback;
|
|
283
|
+
}
|
|
284
|
+
|
|
274
285
|
/**
|
|
275
286
|
* Create an error segment with the fallback component
|
|
276
287
|
* Renders the fallback with error info and reset function
|
|
@@ -281,23 +292,12 @@ export function createErrorSegment(
|
|
|
281
292
|
entry: EntryData,
|
|
282
293
|
params: Record<string, string>,
|
|
283
294
|
): ResolvedSegment {
|
|
284
|
-
let component: ReactNode;
|
|
285
|
-
|
|
286
|
-
if (typeof fallback === "function") {
|
|
287
|
-
const props: ErrorBoundaryFallbackProps = {
|
|
288
|
-
error: errorInfo,
|
|
289
|
-
};
|
|
290
|
-
component = fallback(props);
|
|
291
|
-
} else {
|
|
292
|
-
component = fallback;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
295
|
return {
|
|
296
296
|
id: entry.shortCode,
|
|
297
297
|
namespace: entry.id,
|
|
298
298
|
type: "error",
|
|
299
299
|
index: 0,
|
|
300
|
-
component,
|
|
300
|
+
component: renderErrorFallback(fallback, errorInfo),
|
|
301
301
|
params,
|
|
302
302
|
error: errorInfo,
|
|
303
303
|
};
|
package/src/router/find-match.ts
CHANGED
|
@@ -159,6 +159,7 @@ export function createFindMatch<TEnv = any>(
|
|
|
159
159
|
redirectTo: trieResult.redirectTo,
|
|
160
160
|
...(trieResult.pr ? { pr: true } : {}),
|
|
161
161
|
...(trieResult.pt ? { pt: true } : {}),
|
|
162
|
+
...(trieResult.od ? { od: true } : {}),
|
|
162
163
|
...(trieResult.responseType
|
|
163
164
|
? { responseType: trieResult.responseType }
|
|
164
165
|
: {}),
|
|
@@ -383,6 +383,7 @@ export function createPrerenderContext<TEnv>(
|
|
|
383
383
|
isPassthroughRoute?: boolean,
|
|
384
384
|
buildEnv?: TEnv,
|
|
385
385
|
devMode?: boolean,
|
|
386
|
+
onDemand?: boolean,
|
|
386
387
|
): InternalHandlerContext<any, TEnv> {
|
|
387
388
|
const syntheticUrl = new URL(`http://prerender${pathname}`);
|
|
388
389
|
const variables = buildVars ?? {};
|
|
@@ -401,6 +402,7 @@ export function createPrerenderContext<TEnv>(
|
|
|
401
402
|
// gate. dynamic() only reaches the shell axis on a live request or capture.
|
|
402
403
|
dynamic: () => {},
|
|
403
404
|
dev: devMode ?? false,
|
|
405
|
+
onDemand: onDemand ?? false,
|
|
404
406
|
get request(): Request {
|
|
405
407
|
return throwUnavailable("request");
|
|
406
408
|
},
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
buildLoaderErrorContext,
|
|
28
28
|
} from "./segment-resolution.js";
|
|
29
29
|
import { catchSegmentError } from "./segment-resolution/helpers.js";
|
|
30
|
+
import { trackStreamedHandler } from "./segment-resolution/streamed-handler-boundary.js";
|
|
30
31
|
import { findInOrphans } from "./error-handling.js";
|
|
31
32
|
import { resolveLoaderData } from "./segment-resolution/loader-cache.js";
|
|
32
33
|
import type { SegmentResolutionDeps } from "./types.js";
|
|
@@ -390,14 +391,20 @@ export async function resolveInterceptEntry<TEnv>(
|
|
|
390
391
|
|
|
391
392
|
let component: ReactNode;
|
|
392
393
|
let loaderDataPromise: Promise<any[]> | any[] | undefined;
|
|
393
|
-
// A streamed (loading()) handler resolves after the 200 has started
|
|
394
|
-
//
|
|
395
|
-
//
|
|
396
|
-
|
|
397
|
-
|
|
394
|
+
// A streamed (loading()) handler resolves after the 200 has started: tracked
|
|
395
|
+
// like route handlers (onError report, handle-store completion) and
|
|
396
|
+
// recovered into the declared boundary, except on the skipMiddleware
|
|
397
|
+
// background re-render, which must reject so a failure is never cached.
|
|
398
|
+
const streamedComponent = (promise: Promise<unknown>): ReactNode =>
|
|
399
|
+
trackStreamedHandler(deps, promise, {
|
|
400
|
+
boundaryEntry: parentEntry,
|
|
398
401
|
segmentId: `${parentEntry.shortCode}.${interceptEntry.slotName}`,
|
|
399
402
|
segmentType: "parallel",
|
|
400
|
-
|
|
403
|
+
context,
|
|
404
|
+
routeKey: interceptEntry.routeName,
|
|
405
|
+
params,
|
|
406
|
+
recover: !options?.skipMiddleware,
|
|
407
|
+
});
|
|
401
408
|
|
|
402
409
|
if (interceptEntry.loading && loaderPromises.length > 0) {
|
|
403
410
|
if (handlerResult instanceof Promise) {
|
|
@@ -408,11 +415,11 @@ export async function resolveInterceptEntry<TEnv>(
|
|
|
408
415
|
}
|
|
409
416
|
component =
|
|
410
417
|
handlerResult instanceof Promise
|
|
411
|
-
?
|
|
418
|
+
? streamedComponent(handlerResult)
|
|
412
419
|
: (Promise.resolve(handlerResult) as ReactNode);
|
|
413
420
|
loaderDataPromise = Promise.all(loaderPromises);
|
|
414
421
|
} else if (interceptEntry.loading && handlerResult instanceof Promise) {
|
|
415
|
-
component =
|
|
422
|
+
component = streamedComponent(handlerResult);
|
|
416
423
|
} else {
|
|
417
424
|
if (loaderPromises.length > 0) {
|
|
418
425
|
loaderDataPromise = await Promise.all(loaderPromises);
|
|
@@ -29,7 +29,6 @@ import type {
|
|
|
29
29
|
LoaderContext,
|
|
30
30
|
LoaderDataResult,
|
|
31
31
|
ErrorBoundaryHandler,
|
|
32
|
-
ErrorBoundaryFallbackProps,
|
|
33
32
|
ErrorInfo,
|
|
34
33
|
NotFoundBoundaryHandler,
|
|
35
34
|
NotFoundBoundaryFallbackProps,
|
|
@@ -44,6 +43,7 @@ import {
|
|
|
44
43
|
} from "../redirect-origin.js";
|
|
45
44
|
import {
|
|
46
45
|
createNotFoundInfo,
|
|
46
|
+
renderErrorFallback,
|
|
47
47
|
renderNotFoundFallback,
|
|
48
48
|
resolveNotFoundFallback,
|
|
49
49
|
} from "./error-handling.js";
|
|
@@ -302,15 +302,7 @@ export function wrapLoaderWithErrorHandling<T>(
|
|
|
302
302
|
// error, and the wrapped promise still resolves to a LoaderDataResult.
|
|
303
303
|
let renderedFallback: ReactNode;
|
|
304
304
|
try {
|
|
305
|
-
|
|
306
|
-
// ErrorBoundaryHandler - call with error info
|
|
307
|
-
const props: ErrorBoundaryFallbackProps = {
|
|
308
|
-
error: errorInfo,
|
|
309
|
-
};
|
|
310
|
-
renderedFallback = fallback(props);
|
|
311
|
-
} else {
|
|
312
|
-
renderedFallback = fallback;
|
|
313
|
-
}
|
|
305
|
+
renderedFallback = renderErrorFallback(fallback, errorInfo);
|
|
314
306
|
} catch (fallbackError) {
|
|
315
307
|
debugLog("loader", "error boundary fallback render threw", {
|
|
316
308
|
segmentId,
|
package/src/router/manifest.ts
CHANGED
|
@@ -38,6 +38,8 @@ const MODULE_LOAD_FAILURE = Symbol.for("rango.moduleLoadFailure");
|
|
|
38
38
|
// LP1 in docs/internal/matching-and-lazy-discovery.md. VERSION comes from the
|
|
39
39
|
// @rangojs/router:version virtual module which Vite invalidates on RSC module HMR.
|
|
40
40
|
// When VERSION changes, this module re-evaluates and the cache is recreated empty.
|
|
41
|
+
// Dev module generation only: in production VERSION is constant per process, so
|
|
42
|
+
// the per-router cache versions play no part in this cache.
|
|
41
43
|
const manifestModuleCache = new Map<string, Map<string, EntryData>>();
|
|
42
44
|
|
|
43
45
|
/**
|
|
@@ -171,6 +171,8 @@ export async function rerenderAndCacheRoute<TEnv>(
|
|
|
171
171
|
{
|
|
172
172
|
_handleStore: handleStore,
|
|
173
173
|
_metricsStore: undefined,
|
|
174
|
+
_renderErrors: [],
|
|
175
|
+
_recoveredHandlerErrors: undefined,
|
|
174
176
|
_onResponseCallbacks: [],
|
|
175
177
|
header: sink.header,
|
|
176
178
|
setCookie: sink.setCookie,
|