@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
package/dist/bin/rango.js
CHANGED
|
@@ -1571,6 +1571,11 @@ function mergeFullManifests(manifests) {
|
|
|
1571
1571
|
manifest.passthroughRoutes,
|
|
1572
1572
|
overwrittenRoutes
|
|
1573
1573
|
),
|
|
1574
|
+
onDemandRoutes: mergeRouteList(
|
|
1575
|
+
merged.onDemandRoutes,
|
|
1576
|
+
manifest.onDemandRoutes,
|
|
1577
|
+
overwrittenRoutes
|
|
1578
|
+
),
|
|
1574
1579
|
responseTypeRoutes: mergeRouteRecord(
|
|
1575
1580
|
merged.responseTypeRoutes,
|
|
1576
1581
|
manifest.responseTypeRoutes,
|
|
@@ -1599,14 +1604,33 @@ var init_merge_full_manifests = __esm({
|
|
|
1599
1604
|
}
|
|
1600
1605
|
});
|
|
1601
1606
|
|
|
1607
|
+
// src/router-versions.ts
|
|
1608
|
+
var DEFAULT_ROUTER_VERSIONS_KEY;
|
|
1609
|
+
var init_router_versions = __esm({
|
|
1610
|
+
"src/router-versions.ts"() {
|
|
1611
|
+
"use strict";
|
|
1612
|
+
DEFAULT_ROUTER_VERSIONS_KEY = "*";
|
|
1613
|
+
}
|
|
1614
|
+
});
|
|
1615
|
+
|
|
1602
1616
|
// src/vite/plugins/virtual-entries.ts
|
|
1603
1617
|
function getVirtualVersionContent(version) {
|
|
1604
|
-
return
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1618
|
+
return [
|
|
1619
|
+
`export const VERSION = ${JSON.stringify(version)};`,
|
|
1620
|
+
`export const ROUTER_VERSIONS = undefined;`
|
|
1621
|
+
].join("\n");
|
|
1622
|
+
}
|
|
1623
|
+
function getVirtualBuildVersionContent() {
|
|
1624
|
+
return [
|
|
1625
|
+
`export const ROUTER_VERSIONS = ${ROUTER_VERSIONS_PLACEHOLDER};`,
|
|
1626
|
+
`export const VERSION = ROUTER_VERSIONS[${JSON.stringify(DEFAULT_ROUTER_VERSIONS_KEY)}][1];`
|
|
1627
|
+
].join("\n");
|
|
1628
|
+
}
|
|
1629
|
+
var VIRTUAL_ENTRY_BROWSER, VIRTUAL_IDS, ROUTER_VERSIONS_PLACEHOLDER;
|
|
1607
1630
|
var init_virtual_entries = __esm({
|
|
1608
1631
|
"src/vite/plugins/virtual-entries.ts"() {
|
|
1609
1632
|
"use strict";
|
|
1633
|
+
init_router_versions();
|
|
1610
1634
|
VIRTUAL_ENTRY_BROWSER = `
|
|
1611
1635
|
import {
|
|
1612
1636
|
createFromReadableStream,
|
|
@@ -1634,6 +1658,12 @@ async function initializeApp() {
|
|
|
1634
1658
|
// is the default; createRouter({ strictMode: false }) ships the opt-out in the
|
|
1635
1659
|
// payload metadata. StrictMode emits no DOM, so toggling never changes markup.
|
|
1636
1660
|
const { strictMode, initialPayload } = await initBrowserApp({ rscStream, deps });
|
|
1661
|
+
// Set only on a document a no-JS useActionState POST rendered: React needs
|
|
1662
|
+
// the server's form state to hydrate the hook without resetting it. A state
|
|
1663
|
+
// Flight could not carry rejects: hydrate without it, as before.
|
|
1664
|
+
const formState = await Promise.resolve(initialPayload.formState).catch(
|
|
1665
|
+
() => undefined
|
|
1666
|
+
);
|
|
1637
1667
|
|
|
1638
1668
|
if (import.meta.hot) {
|
|
1639
1669
|
const { startDevDiscoveryHandshake } = await import(
|
|
@@ -1648,7 +1678,8 @@ async function initializeApp() {
|
|
|
1648
1678
|
const app = createElement(Rango);
|
|
1649
1679
|
hydrateRoot(
|
|
1650
1680
|
document,
|
|
1651
|
-
strictMode === false ? app : createElement(StrictMode, null, app)
|
|
1681
|
+
strictMode === false ? app : createElement(StrictMode, null, app),
|
|
1682
|
+
formState ? { formState } : undefined
|
|
1652
1683
|
);
|
|
1653
1684
|
}
|
|
1654
1685
|
|
|
@@ -1660,6 +1691,7 @@ initializeApp().catch(console.error);
|
|
|
1660
1691
|
rsc: "virtual:rsc-router/entry.rsc.js",
|
|
1661
1692
|
version: "@rangojs/router:version"
|
|
1662
1693
|
};
|
|
1694
|
+
ROUTER_VERSIONS_PLACEHOLDER = "__RANGO_ROUTER_VERSIONS__";
|
|
1663
1695
|
}
|
|
1664
1696
|
});
|
|
1665
1697
|
|
|
@@ -1772,8 +1804,7 @@ function getClientModuleSignature(source) {
|
|
|
1772
1804
|
};
|
|
1773
1805
|
}
|
|
1774
1806
|
function createVersionPlugin() {
|
|
1775
|
-
|
|
1776
|
-
let currentVersion = buildVersion;
|
|
1807
|
+
let currentVersion = Date.now().toString(16);
|
|
1777
1808
|
let isDev = false;
|
|
1778
1809
|
let server = null;
|
|
1779
1810
|
let resolvedCacheDir;
|
|
@@ -1793,13 +1824,6 @@ function createVersionPlugin() {
|
|
|
1793
1824
|
return {
|
|
1794
1825
|
name: "@rangojs/router:version",
|
|
1795
1826
|
enforce: "pre",
|
|
1796
|
-
// The build-time shell capture phase (producer B, #699) stamps entries
|
|
1797
|
-
// with THIS instance's version — the value folded into the shipped worker
|
|
1798
|
-
// — never the discovery temp server's own version-plugin value (a
|
|
1799
|
-
// different Date.now() stamp that would fail the serve-side gate).
|
|
1800
|
-
api: {
|
|
1801
|
-
getBuildVersion: () => currentVersion
|
|
1802
|
-
},
|
|
1803
1827
|
configResolved(config) {
|
|
1804
1828
|
isDev = config.command === "serve";
|
|
1805
1829
|
resolvedCacheDir = config.cacheDir ? String(config.cacheDir).replace(/\\/g, "/") : void 0;
|
|
@@ -1821,7 +1845,7 @@ function createVersionPlugin() {
|
|
|
1821
1845
|
},
|
|
1822
1846
|
load(id) {
|
|
1823
1847
|
if (id === "\0" + VIRTUAL_IDS.version) {
|
|
1824
|
-
return getVirtualVersionContent(currentVersion);
|
|
1848
|
+
return isDev ? getVirtualVersionContent(currentVersion) : getVirtualBuildVersionContent();
|
|
1825
1849
|
}
|
|
1826
1850
|
return null;
|
|
1827
1851
|
},
|
|
@@ -2150,7 +2174,7 @@ if (command === "generate") {
|
|
|
2150
2174
|
Modes:
|
|
2151
2175
|
(default) Static parser with error on unresolvable includes
|
|
2152
2176
|
--runtime Vite-based runtime discovery (100% coverage)
|
|
2153
|
-
Requires vite
|
|
2177
|
+
Requires vite
|
|
2154
2178
|
--static Static parser, accept partial output with warnings
|
|
2155
2179
|
|
|
2156
2180
|
Options:
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { NavigationLocation, NavigateOptionsInternal, TrackedActionState, InflightAction, RscMetadata, HandleData, StreamingToken } from "./types.js";
|
|
3
|
+
import { type LocationStateSnapshot } from "./react/location-state-shared.js";
|
|
3
4
|
/**
|
|
4
5
|
* Phase of a navigation operation
|
|
5
6
|
*/
|
|
@@ -101,6 +102,15 @@ export interface HandleState {
|
|
|
101
102
|
segmentOrder: string[];
|
|
102
103
|
routeSegmentIds: string[];
|
|
103
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* What the document's HTML was rendered with, kept for the hydration window
|
|
107
|
+
* (EventController.lockHydration).
|
|
108
|
+
*/
|
|
109
|
+
export interface HydrationSnapshot {
|
|
110
|
+
state: DerivedNavigationState;
|
|
111
|
+
params: Record<string, string>;
|
|
112
|
+
handles: HandleState;
|
|
113
|
+
}
|
|
104
114
|
/**
|
|
105
115
|
* Result from starting a navigation
|
|
106
116
|
* Implements Disposable for use with `using` keyword
|
|
@@ -196,6 +206,31 @@ export interface EventController {
|
|
|
196
206
|
*/
|
|
197
207
|
resolvedIds?: string[]): void;
|
|
198
208
|
getHandleState(): HandleState;
|
|
209
|
+
/**
|
|
210
|
+
* Open the hydration window. Until releaseHydrationLock(), getHandleState()
|
|
211
|
+
* returns the state the document's HTML was rendered with, and handle writes
|
|
212
|
+
* (setHandleData, setRouteSegmentIds) wait in order. initBrowserApp opens it
|
|
213
|
+
* before hydrateRoot, once the document's handle snapshot is applied: a hook
|
|
214
|
+
* reading the handle state when its boundary hydrates, however late, reads
|
|
215
|
+
* what SSR rendered (issue #1035).
|
|
216
|
+
*/
|
|
217
|
+
lockHydration(): void;
|
|
218
|
+
/**
|
|
219
|
+
* While the hydration window is open, the state the document's HTML was
|
|
220
|
+
* rendered with; undefined once it closes. A router hook's first render
|
|
221
|
+
* reads it: a component hydrating in a boundary that streamed in late
|
|
222
|
+
* renders what SSR rendered, even after a navigation or an action started.
|
|
223
|
+
* The hook's effect then catches up with the live state, and its
|
|
224
|
+
* subscription stays live, so pending UI is not held back.
|
|
225
|
+
*/
|
|
226
|
+
getHydrationSnapshot(): HydrationSnapshot | undefined;
|
|
227
|
+
/**
|
|
228
|
+
* Close the hydration window: apply the writes that waited, in order, and
|
|
229
|
+
* notify handle subscribers. NavigationProvider calls it after the commit
|
|
230
|
+
* that made React hydrate every boundary still dehydrated (its barrier).
|
|
231
|
+
* Idempotent.
|
|
232
|
+
*/
|
|
233
|
+
releaseHydrationLock(): void;
|
|
199
234
|
/**
|
|
200
235
|
* Update ONLY `routeSegmentIds` (what `useSegments` reads) from `matched`,
|
|
201
236
|
* leaving `data` and `segmentOrder` (what `useHandle` collects over) untouched.
|
|
@@ -206,6 +241,20 @@ export interface EventController {
|
|
|
206
241
|
setRouteSegmentIds(matched: string[]): void;
|
|
207
242
|
setParams(params: Record<string, string>): void;
|
|
208
243
|
getParams(): Record<string, string>;
|
|
244
|
+
/**
|
|
245
|
+
* Record the committed history entry's location state from `entryState`:
|
|
246
|
+
* the state object the commit pushed, restored or merged into the entry,
|
|
247
|
+
* so the entry and its readers have one source. Notifies nobody:
|
|
248
|
+
* NavigationProvider takes the snapshot with the entry's payload
|
|
249
|
+
* (LocationStateContext). `treeless` marks a commit no payload follows (a
|
|
250
|
+
* shallow navigation, a commit that keeps every segment, an action's
|
|
251
|
+
* state): the provider takes it with this commit's state notification, in
|
|
252
|
+
* the batch of the location.
|
|
253
|
+
*/
|
|
254
|
+
commitLocationState(entryState: unknown, treeless?: boolean): void;
|
|
255
|
+
getLocationState(): LocationStateSnapshot;
|
|
256
|
+
/** True once after a `treeless` commit. */
|
|
257
|
+
takeTreelessLocationState(): boolean;
|
|
209
258
|
getCurrentNavigation(): NavigationEntry | null;
|
|
210
259
|
getInflightActions(): Map<string, ActionEntry>;
|
|
211
260
|
/** Whether any concurrent actions have occurred (shared across all handles) */
|
|
@@ -37,8 +37,20 @@ export declare const SHELL_MISS_MARKER: string;
|
|
|
37
37
|
*/
|
|
38
38
|
export declare function stripShellMissMarker(): void;
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* so
|
|
40
|
+
* Remove the `clearOnReload` slots of the entry a document load starts on:
|
|
41
|
+
* the server rendered this document without them. One pass before hydration
|
|
42
|
+
* (initBrowserApp; renderRoute's `hydrate` mode), so no reader needs to know
|
|
43
|
+
* the page began as a document load, and a slot nobody reads is removed too.
|
|
44
|
+
* No server-set state exists yet to lose: a document response carries none
|
|
45
|
+
* (rsc-rendering.ts attaches it to partial payloads only).
|
|
46
|
+
*
|
|
47
|
+
* A slot is recognised by its key alone (the `~r` suffix): at start-up the
|
|
48
|
+
* module that defines it may not be loaded.
|
|
43
49
|
*/
|
|
44
|
-
export declare function
|
|
50
|
+
export declare function clearLocationStateOnDocumentLoad(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Merge server-set location state into the current history entry and return
|
|
53
|
+
* the entry state written. Readers see it when the caller commits it
|
|
54
|
+
* (EventController.commitLocationState).
|
|
55
|
+
*/
|
|
56
|
+
export declare function mergeLocationState(locationState: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NavigationStore, ResolvedSegment, HandleData } from "./types.js";
|
|
2
|
+
import type { EventController } from "./event-controller.js";
|
|
2
3
|
/**
|
|
3
4
|
* Clone the handleData CONTAINERS (the handle-name map and each segment map) so
|
|
4
5
|
* a cache entry is decoupled from the live map that eventController mutates — it
|
|
@@ -11,6 +12,14 @@ import type { NavigationStore, ResolvedSegment, HandleData } from "./types.js";
|
|
|
11
12
|
* non-serializable bucket contents (React elements, functions, etc.).
|
|
12
13
|
*/
|
|
13
14
|
export declare function cloneHandleData(handleData: HandleData): HandleData;
|
|
15
|
+
/**
|
|
16
|
+
* Handle data to write into the history cache for the page on screen. During
|
|
17
|
+
* the hydration window getHandleState() is the document snapshot while late
|
|
18
|
+
* pushes sit queued in the controller (they are already in the cache entry,
|
|
19
|
+
* written by rsc-router), so writing the snapshot back would drop them; the
|
|
20
|
+
* entry's own data is the live view then.
|
|
21
|
+
*/
|
|
22
|
+
export declare function liveHandleDataForCache(eventController: Pick<EventController, "getHandleState" | "getHydrationSnapshot">, store: Pick<NavigationStore, "getCachedSegments">, historyKey: string): HandleData;
|
|
14
23
|
/**
|
|
15
24
|
* Options for generating a history key
|
|
16
25
|
*/
|
|
@@ -36,6 +36,11 @@ interface CommitOptions {
|
|
|
36
36
|
* partial updater reuses it instead of deciding again.
|
|
37
37
|
*/
|
|
38
38
|
transitionGatedOff?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* No payload follows this commit: every segment is kept and the tree on
|
|
41
|
+
* screen stays (EventController.commitLocationState).
|
|
42
|
+
*/
|
|
43
|
+
treeless?: boolean;
|
|
39
44
|
}
|
|
40
45
|
/**
|
|
41
46
|
* Options that can override the pre-configured commit settings
|
|
@@ -57,6 +62,8 @@ interface BoundCommitOverrides {
|
|
|
57
62
|
serverState?: Record<string, unknown>;
|
|
58
63
|
/** The committed route's name (payload metadata), remembered per history entry. */
|
|
59
64
|
routeName?: string;
|
|
65
|
+
/** No payload follows this commit (CommitOptions.treeless). */
|
|
66
|
+
treeless?: boolean;
|
|
60
67
|
}
|
|
61
68
|
/**
|
|
62
69
|
* Bound transaction with pre-configured commit options (without segmentIds/segments)
|
|
@@ -3,6 +3,7 @@ import type { ReactNode } from "react";
|
|
|
3
3
|
import type { RenderSegmentsOptions } from "../segment-system.js";
|
|
4
4
|
import type { BoundTransaction } from "./navigation-transaction.js";
|
|
5
5
|
import type { NavigationUpdate } from "./types.js";
|
|
6
|
+
import type { LoaderStore } from "../loader-store.js";
|
|
6
7
|
import { type TransitionWhenActionInput } from "./transition-when.js";
|
|
7
8
|
/**
|
|
8
9
|
* Hold/animate decision for a commit: a non-intercept segment carries a
|
|
@@ -18,7 +19,7 @@ export declare function shouldStartViewTransition(segments: readonly ResolvedSeg
|
|
|
18
19
|
* directly: nothing is held there, a reader of a pending stream suspends to
|
|
19
20
|
* its fallback. Also used by renderRoute's navigate() (testing/render-route.tsx).
|
|
20
21
|
*/
|
|
21
|
-
export declare function commitInTransition(onUpdate: UpdateSubscriber, segments: readonly ResolvedSegment[], update: NavigationUpdate, transitionTypes: readonly string[]): void;
|
|
22
|
+
export declare function commitInTransition(loaders: LoaderStore, onUpdate: UpdateSubscriber, segments: readonly ResolvedSegment[], update: NavigationUpdate, transitionTypes: readonly string[]): void;
|
|
22
23
|
/**
|
|
23
24
|
* Configuration for creating a partial updater
|
|
24
25
|
*/
|
|
@@ -2,30 +2,26 @@
|
|
|
2
2
|
* Router-wide default prefetch strategy (client seat).
|
|
3
3
|
*
|
|
4
4
|
* The server resolves `createRouter({ defaultPrefetch })` once at router init
|
|
5
|
-
* (router/prefetch-default.ts) and ships it in initial payload metadata
|
|
6
|
-
*
|
|
7
|
-
* `
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* `data-prefetch-scope`.
|
|
12
|
-
*
|
|
13
|
-
* The module initial value must equal the server resolver's environment default:
|
|
14
|
-
* `"none"` in development and `"viewport"` in production. During SSR this
|
|
15
|
-
* module is never initialized from metadata, so keeping both seats aligned also
|
|
16
|
-
* gives metadata-less payloads the documented behavior.
|
|
5
|
+
* (router/prefetch-default.ts) and ships it in initial payload metadata. The
|
|
6
|
+
* router store carries it to its readers: `<Link>` reads
|
|
7
|
+
* `NavigationStoreContext.defaultPrefetch`, and delegated plain anchors get it
|
|
8
|
+
* from the navigation bridge. Every `<Link>` without an explicit `prefetch`
|
|
9
|
+
* prop and every eligible intercepted plain anchor that has not opted out with
|
|
10
|
+
* `data-prefetch="false"` or `data-prefetch="none"` uses it. Containers use the
|
|
11
|
+
* same `false`/`none` vocabulary via `data-prefetch-scope`.
|
|
17
12
|
*/
|
|
18
13
|
import type { PrefetchStrategy } from "../../router/prefetch-default.js";
|
|
19
|
-
/** Reset module state between tests that replace browser media globals. */
|
|
20
|
-
export declare function resetAdaptiveStrategyForTesting(): void;
|
|
21
14
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
15
|
+
* The default for a payload without `defaultPrefetch`: the server resolver's
|
|
16
|
+
* environment default (`"none"` in development, `"viewport"` in production),
|
|
17
|
+
* mirrored without pulling router-layer code into the client bundle. NODE_ENV
|
|
18
|
+
* is folded by the app build.
|
|
19
|
+
*/
|
|
20
|
+
export declare const ENVIRONMENT_DEFAULT_PREFETCH: PrefetchStrategy;
|
|
21
|
+
/**
|
|
22
|
+
* Resolve adaptive to the strategy for the current input capability. Called
|
|
23
|
+
* when a prefetch is armed or triggered, never during render.
|
|
24
24
|
*/
|
|
25
|
-
export declare function setDefaultPrefetchStrategy(strategy: PrefetchStrategy): void;
|
|
26
|
-
/** Current default strategy for Links and delegated plain anchors. */
|
|
27
|
-
export declare function getDefaultPrefetchStrategy(): PrefetchStrategy;
|
|
28
|
-
/** Resolve adaptive to the strategy for the current input capability. */
|
|
29
25
|
export declare function resolveAdaptiveStrategy(strategy: PrefetchStrategy): PrefetchStrategy;
|
|
30
26
|
/** Subscribe to changes in the input capability used by adaptive prefetch. */
|
|
31
27
|
export declare function subscribeToAdaptiveStrategyChange(listener: () => void): () => void;
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* cache keys responses by (URL, X-Rango-State value).
|
|
8
8
|
*
|
|
9
9
|
* Value format: `{buildVersion}:{invalidationTimestamp}`
|
|
10
|
-
* - Build version
|
|
10
|
+
* - Build version: the router's document version. It changes when a deploy
|
|
11
|
+
* changes the router's server code or the client assets, busting all cached
|
|
12
|
+
* prefetches at boot; a deploy that changes neither keeps them.
|
|
11
13
|
* - Timestamp rotates on invalidation (server action, invalidateClientCache).
|
|
12
14
|
*
|
|
13
15
|
* Storage is a session cookie named by the server-resolved name passed to
|
|
@@ -63,6 +63,19 @@ export interface NavigationProviderProps {
|
|
|
63
63
|
* it to seed a nonce so components calling useNonce() can be exercised.
|
|
64
64
|
*/
|
|
65
65
|
nonce?: string;
|
|
66
|
+
/**
|
|
67
|
+
* The document this provider hydrates (initBrowserApp; renderRoute with
|
|
68
|
+
* `hydrate: true`), whose store EventController.lockHydration locked.
|
|
69
|
+
* `settled` resolves once the stream has ended and React has revealed every
|
|
70
|
+
* boundary. Until then location state is `undefined`, as SSR rendered it;
|
|
71
|
+
* then one transition gives the entry's state and changes
|
|
72
|
+
* HydrationBarrierContext, and the store is released after that commit. A
|
|
73
|
+
* navigation committed earlier releases the store before its update.
|
|
74
|
+
* Absent for a provider mounted on the client.
|
|
75
|
+
*/
|
|
76
|
+
hydration?: {
|
|
77
|
+
settled: Promise<void>;
|
|
78
|
+
};
|
|
66
79
|
}
|
|
67
80
|
/**
|
|
68
81
|
* Navigation provider component
|
|
@@ -85,4 +98,4 @@ export interface NavigationProviderProps {
|
|
|
85
98
|
* />
|
|
86
99
|
* ```
|
|
87
100
|
*/
|
|
88
|
-
export declare function NavigationProvider({ store, eventController, initialPayload, bridge, themeConfig, initialTheme, warmupEnabled, version, basename, appShellRef, nonce, }: NavigationProviderProps): ReactNode;
|
|
101
|
+
export declare function NavigationProvider({ store, eventController, initialPayload, bridge, themeConfig, initialTheme, warmupEnabled, version, basename, appShellRef, nonce, hydration, }: NavigationProviderProps): ReactNode;
|
|
@@ -2,6 +2,7 @@ import { type Context } from "react";
|
|
|
2
2
|
import type { NavigationStore, NavigateOptionsInternal } from "../types.js";
|
|
3
3
|
import type { EventController } from "../event-controller.js";
|
|
4
4
|
import type { PrefetchStrategy } from "../../router/prefetch-default.js";
|
|
5
|
+
import type { LocationStateSnapshot } from "./location-state-shared.js";
|
|
5
6
|
/**
|
|
6
7
|
* Navigation context value provided by NavigationProvider
|
|
7
8
|
*
|
|
@@ -47,6 +48,12 @@ export interface NavigationStoreContextValue {
|
|
|
47
48
|
basename: string | undefined;
|
|
48
49
|
/** Router default from this instance's initial payload. */
|
|
49
50
|
defaultPrefetch?: PrefetchStrategy;
|
|
51
|
+
/**
|
|
52
|
+
* The document's origin, fixed for its lifetime. Link compares absolute
|
|
53
|
+
* hrefs against it (data-external) and useLinkStatus resolves link targets
|
|
54
|
+
* with it.
|
|
55
|
+
*/
|
|
56
|
+
origin: string | undefined;
|
|
50
57
|
}
|
|
51
58
|
/**
|
|
52
59
|
* React context for navigation store
|
|
@@ -55,3 +62,21 @@ export interface NavigationStoreContextValue {
|
|
|
55
62
|
* Use useNavigation hook for reactive state access.
|
|
56
63
|
*/
|
|
57
64
|
export declare const NavigationStoreContext: Context<NavigationStoreContextValue | null>;
|
|
65
|
+
/**
|
|
66
|
+
* The location state of the history entry whose tree is on screen, for
|
|
67
|
+
* useLocationState. NavigationProvider holds it as React state next to the
|
|
68
|
+
* payload and sets both in one update, so a render sees an entry's state
|
|
69
|
+
* exactly when it sees that entry's tree: a transition React holds renders
|
|
70
|
+
* the destination's value, an urgent render of the content still on screen
|
|
71
|
+
* (a reader mounting there included) the value of the entry being left
|
|
72
|
+
* (#1029). Undefined on the server and outside a provider.
|
|
73
|
+
*/
|
|
74
|
+
export declare const LocationStateContext: Context<LocationStateSnapshot>;
|
|
75
|
+
/**
|
|
76
|
+
* Read by no component. NavigationProvider changes its value in a transition so
|
|
77
|
+
* that React hydrates every boundary still dehydrated beneath it before that
|
|
78
|
+
* commit: React hydrates a dehydrated boundary first when a provider above it
|
|
79
|
+
* changes, and nothing re-renders for a value nobody reads. See
|
|
80
|
+
* NavigationProviderProps.hydration.
|
|
81
|
+
*/
|
|
82
|
+
export declare const HydrationBarrierContext: Context<number>;
|
|
@@ -9,12 +9,82 @@ export interface LocationStateEntry {
|
|
|
9
9
|
readonly __rsc_ls_value: unknown;
|
|
10
10
|
readonly __rsc_ls_lazy?: boolean;
|
|
11
11
|
}
|
|
12
|
+
/** Prefix of every typed location-state slot in `history.state`. */
|
|
13
|
+
export declare const LOCATION_STATE_KEY_PREFIX: string;
|
|
14
|
+
export declare function isLocationStateKey(key: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* `clearOnReload` is part of a slot's KEY (`<key>~r`); the value is always
|
|
17
|
+
* stored raw. Slots outlive deploys, so nothing that reads one may depend on a
|
|
18
|
+
* stored format: a definition without the option reads the plain key and never
|
|
19
|
+
* sees such a slot.
|
|
20
|
+
*
|
|
21
|
+
* An injected key ends in `#<ExportName>` (expose-id-utils.ts makeStubId; only
|
|
22
|
+
* identifier exports are keyed) and "~" cannot occur in an identifier, so no
|
|
23
|
+
* file or export name produces a suffix. withLocationStateKey rejects it.
|
|
24
|
+
*/
|
|
25
|
+
export declare const LOCATION_STATE_KEY_SUFFIX_SEPARATOR: string;
|
|
26
|
+
export declare const CLEAR_ON_RELOAD_KEY_SUFFIX: string;
|
|
27
|
+
/**
|
|
28
|
+
* @internal The version the document loaded under (rsc-router.tsx
|
|
29
|
+
* initBrowserApp). Deliberately not getAppVersion(): a dev HMR bump moves that
|
|
30
|
+
* one inside a running session (bridge.updateVersion), and the state that
|
|
31
|
+
* session wrote must stay readable until the next document load.
|
|
32
|
+
*/
|
|
33
|
+
export declare function setLocationStateVersion(version: string | undefined): void;
|
|
34
|
+
/**
|
|
35
|
+
* The state of a `{ state }` snapshot when its location state may be read:
|
|
36
|
+
* an object recorded under the client's version. Without a snapshot, the
|
|
37
|
+
* current entry (`window.history` is a `{ state }`), and nothing on the
|
|
38
|
+
* server.
|
|
39
|
+
*/
|
|
40
|
+
export declare function readableLocationState(location?: {
|
|
41
|
+
readonly state: unknown;
|
|
42
|
+
} | undefined): Record<string, unknown> | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* One history entry's location state as useLocationState readers receive it:
|
|
45
|
+
* its typed slots and plain `state`, or undefined when it holds none.
|
|
46
|
+
*/
|
|
47
|
+
export type LocationStateSnapshot = Readonly<Record<string, unknown>> | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* The snapshot of `entryState`: the state object a commit pushes, restores or
|
|
50
|
+
* merges into its history entry. Only state recorded under the client's
|
|
51
|
+
* version is in it (readableLocationState).
|
|
52
|
+
*
|
|
53
|
+
* The snapshot is a React context value, so identity decides who re-renders.
|
|
54
|
+
* It is `previous` itself when every slot holds the value `previous` holds:
|
|
55
|
+
* an entry without state after another, a primitive carried over, or the
|
|
56
|
+
* object a reader got from `previous` passed back by the navigation. Any
|
|
57
|
+
* other value is new, equal content included: a link clicked twice announces
|
|
58
|
+
* its state twice (a flash message, a scroll target). A new value is a
|
|
59
|
+
* structured clone, as history.state holds it, so a reader never shares an
|
|
60
|
+
* object with the caller of the navigation.
|
|
61
|
+
*/
|
|
62
|
+
export declare function locationStateSnapshot(entryState: unknown, previous?: LocationStateSnapshot): LocationStateSnapshot;
|
|
63
|
+
/**
|
|
64
|
+
* Record the client's version on a state object that carries location state
|
|
65
|
+
* and no record yet. A client without a version (a renderRoute tree) writes
|
|
66
|
+
* none.
|
|
67
|
+
*/
|
|
68
|
+
export declare function stampLocationState(state: Record<string, unknown>): void;
|
|
69
|
+
/**
|
|
70
|
+
* `entryState` plus `additions`, recorded under the client's version. The
|
|
71
|
+
* record is per entry, so location state another version left there is dropped
|
|
72
|
+
* first, with its record: under the new one it would be readable again. Router
|
|
73
|
+
* bookkeeping (idx, scroll key, intercept) is kept.
|
|
74
|
+
*/
|
|
75
|
+
export declare function addLocationState(entryState: unknown, additions?: Record<string, unknown>): Record<string, unknown>;
|
|
12
76
|
/**
|
|
13
77
|
* Options for createLocationState
|
|
14
78
|
*/
|
|
15
79
|
export interface LocationStateOptions {
|
|
16
80
|
/** When true, the state is cleared from history after first read (flash message pattern) */
|
|
17
81
|
flash?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* When true, the state does not survive a document load of its entry (a
|
|
84
|
+
* refresh, a back/forward that loads the document): the server rendered
|
|
85
|
+
* without it. Not together with `flash`.
|
|
86
|
+
*/
|
|
87
|
+
clearOnReload?: boolean;
|
|
18
88
|
}
|
|
19
89
|
type LocationStateUnsafeFn = (...args: never[]) => unknown;
|
|
20
90
|
type LocationStateUnsafeCtor = abstract new (...args: never[]) => unknown;
|
|
@@ -116,13 +186,16 @@ export interface LocationStateDefinition<TArgs extends unknown[], TState> {
|
|
|
116
186
|
(...args: TArgs): LocationStateEntry;
|
|
117
187
|
/**
|
|
118
188
|
* Injected by Vite plugin - do not set manually. Unit tests without the
|
|
119
|
-
* plugin use withLocationStateKey() from @rangojs/router/testing.
|
|
189
|
+
* plugin use withLocationStateKey() from @rangojs/router/testing. Reads back
|
|
190
|
+
* as the slot's key in `history.state`: the injected key plus the
|
|
191
|
+
* `clearOnReload` suffix.
|
|
120
192
|
*/
|
|
121
193
|
__rsc_ls_key: string;
|
|
122
194
|
/** Whether this state auto-clears after first read */
|
|
123
195
|
readonly __rsc_ls_flash: boolean;
|
|
124
196
|
/**
|
|
125
|
-
* Read the current value from history.state.
|
|
197
|
+
* Read the current value from history.state. State the entry holds from
|
|
198
|
+
* another version of the app (an older build) reads as undefined.
|
|
126
199
|
*
|
|
127
200
|
* Returns undefined during SSR (no `window`). To stay hydration-safe, do
|
|
128
201
|
* NOT call read() inline during the initial render — the server returns
|
|
@@ -145,13 +218,14 @@ export interface LocationStateDefinition<TArgs extends unknown[], TState> {
|
|
|
145
218
|
/**
|
|
146
219
|
* Statically write the value into the current history entry under this
|
|
147
220
|
* definition's key, preserving any other keys already on history.state
|
|
148
|
-
* (e.g. router bookkeeping, other LocationState slots).
|
|
221
|
+
* (e.g. router bookkeeping, other LocationState slots). Location state
|
|
222
|
+
* another version of the app left on the entry is dropped.
|
|
149
223
|
*
|
|
150
|
-
* This is the non-reactive counterpart to read(): it
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
224
|
+
* This is the non-reactive counterpart to read(): it changes the history
|
|
225
|
+
* entry and nothing a useLocationState() reader shows, whether the reader
|
|
226
|
+
* is mounted now or mounts later. read() returns the value at once; a
|
|
227
|
+
* reader gets it when the entry is next restored: back/forward to it, or
|
|
228
|
+
* (unless the definition sets `clearOnReload`) a hard refresh of it.
|
|
155
229
|
*
|
|
156
230
|
* Client-only: throws when called on the server (no history available).
|
|
157
231
|
*/
|
|
@@ -161,8 +235,8 @@ export interface LocationStateDefinition<TArgs extends unknown[], TState> {
|
|
|
161
235
|
* leaving any other keys on history.state untouched. Idempotent: removing
|
|
162
236
|
* a slot that isn't present is a no-op.
|
|
163
237
|
*
|
|
164
|
-
* Same non-reactive semantics as write():
|
|
165
|
-
*
|
|
238
|
+
* Same non-reactive semantics as write(): useLocationState() readers keep
|
|
239
|
+
* the value until the entry is next restored.
|
|
166
240
|
*
|
|
167
241
|
* Client-only: throws when called on the server (no history available).
|
|
168
242
|
*/
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { type LocationStateDefinition } from "./location-state-shared.js";
|
|
2
2
|
export { createLocationState, isLocationStateEntry, resolveLocationStateEntries, type LocationStateEntry, type LocationStateDefinition, type LocationStateOptions, } from "./location-state-shared.js";
|
|
3
3
|
/**
|
|
4
|
-
* Hook to read location state
|
|
4
|
+
* Hook to read the location state of the history entry on screen
|
|
5
|
+
*
|
|
6
|
+
* A reader sees an entry's state together with that entry's tree: on a
|
|
7
|
+
* navigation the value changes in the React commit that brings the
|
|
8
|
+
* destination, so content a pending navigation keeps on screen keeps the
|
|
9
|
+
* state of the entry being left, for a reader that mounts there too (#1029).
|
|
5
10
|
*
|
|
6
11
|
* Behavior depends on the definition:
|
|
7
|
-
* - Normal state: persists across navigations
|
|
12
|
+
* - Normal state: persists across navigations and back/forward
|
|
8
13
|
* - Flash state (created with { flash: true }): read once, cleared after paint
|
|
9
14
|
*
|
|
10
15
|
* Overloaded:
|
|
@@ -95,6 +95,12 @@ export interface BrowserAppContext {
|
|
|
95
95
|
* prefetch TTL are document-lifetime too (see AppShell).
|
|
96
96
|
*/
|
|
97
97
|
appShellRef?: import("./app-shell.js").AppShellRef;
|
|
98
|
+
/**
|
|
99
|
+
* Resolves when the document's stream has ended and every Suspense boundary
|
|
100
|
+
* in it has been revealed. NavigationProvider closes the hydration window
|
|
101
|
+
* then (NavigationProviderProps.hydration).
|
|
102
|
+
*/
|
|
103
|
+
documentRevealed: Promise<void>;
|
|
98
104
|
}
|
|
99
105
|
/**
|
|
100
106
|
* Initialize the browser app. Must be called before rendering Rango.
|
|
@@ -131,13 +137,18 @@ export interface RangoProps {
|
|
|
131
137
|
* import * as rscBrowser from "@vitejs/plugin-rsc/browser";
|
|
132
138
|
*
|
|
133
139
|
* async function main() {
|
|
134
|
-
* await initBrowserApp({ rscStream, deps: rscBrowser });
|
|
140
|
+
* const { initialPayload } = await initBrowserApp({ rscStream, deps: rscBrowser });
|
|
141
|
+
* // Rejects when the action's state is not Flight-serializable.
|
|
142
|
+
* const formState = await Promise.resolve(initialPayload.formState).catch(
|
|
143
|
+
* () => undefined,
|
|
144
|
+
* );
|
|
135
145
|
*
|
|
136
146
|
* hydrateRoot(
|
|
137
147
|
* document,
|
|
138
148
|
* <React.StrictMode>
|
|
139
149
|
* <Rango />
|
|
140
|
-
* </React.StrictMode
|
|
150
|
+
* </React.StrictMode>,
|
|
151
|
+
* formState ? { formState } : undefined
|
|
141
152
|
* );
|
|
142
153
|
* }
|
|
143
154
|
* main();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReactNode, ComponentType } from "react";
|
|
2
|
+
import type { ReactFormState } from "react-dom/client";
|
|
2
3
|
import type { ResolvedSegment, SlotState } from "../types.js";
|
|
3
4
|
import type { ResolvedThemeConfig, Theme } from "../theme/types.js";
|
|
4
5
|
import type { RenderSegmentsOptions } from "../segment-system.js";
|
|
@@ -9,6 +10,11 @@ import type { RenderSegmentsOptions } from "../segment-system.js";
|
|
|
9
10
|
export interface RscPayload<TMetadata = RscMetadata> {
|
|
10
11
|
metadata?: TMetadata;
|
|
11
12
|
returnValue?: ActionResult;
|
|
13
|
+
/**
|
|
14
|
+
* Form state of a PE POST document, for hydrateRoot's `formState` option.
|
|
15
|
+
* Rejects when the action's state is not Flight-serializable.
|
|
16
|
+
*/
|
|
17
|
+
formState?: Promise<ReactFormState>;
|
|
12
18
|
}
|
|
13
19
|
/**
|
|
14
20
|
* Handle data structure: handleName -> segmentId -> entries[]
|
|
@@ -406,6 +412,8 @@ export interface NavigateOptionsInternal extends Omit<NavigateOptions, "state">
|
|
|
406
412
|
state?: unknown;
|
|
407
413
|
/** Skip segment cache (used by redirect-with-state to force re-render) */
|
|
408
414
|
_skipCache?: boolean;
|
|
415
|
+
/** Server redirects already followed by this navigation chain (0 for a user navigation) */
|
|
416
|
+
_redirectHops?: number;
|
|
409
417
|
}
|
|
410
418
|
/**
|
|
411
419
|
* Options for useRouter push/replace methods.
|
|
@@ -476,6 +484,8 @@ export type StateListener = () => void;
|
|
|
476
484
|
* EventController owns the public navigation lifecycle exposed by hooks.
|
|
477
485
|
*/
|
|
478
486
|
export interface NavigationStore {
|
|
487
|
+
/** Client loader data for useLoader / useFetchLoader (loader-store.ts). */
|
|
488
|
+
readonly loaders: import("../loader-store.js").LoaderStore;
|
|
479
489
|
getSegmentState(): SegmentState;
|
|
480
490
|
setPath(path: string): void;
|
|
481
491
|
setCurrentUrl(url: string): void;
|
|
@@ -37,6 +37,8 @@ export interface GeneratedManifest {
|
|
|
37
37
|
prerenderRoutes?: string[];
|
|
38
38
|
/** Route names wrapped with Passthrough() (live handler for runtime fallback) */
|
|
39
39
|
passthroughRoutes?: string[];
|
|
40
|
+
/** Route names opted into on-demand prerender (Prerender(..., { onDemand })) */
|
|
41
|
+
onDemandRoutes?: string[];
|
|
40
42
|
/** Route name → response type for non-RSC routes */
|
|
41
43
|
responseTypeRoutes?: Record<string, string>;
|
|
42
44
|
/** Route name -> search schema descriptor for typed URL helpers */
|