vinext 0.0.37 → 0.0.39
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 +33 -20
- package/dist/build/nitro-route-rules.d.ts +50 -0
- package/dist/build/nitro-route-rules.js +81 -0
- package/dist/build/nitro-route-rules.js.map +1 -0
- package/dist/build/precompress.d.ts +17 -0
- package/dist/build/precompress.js +102 -0
- package/dist/build/precompress.js.map +1 -0
- package/dist/build/prerender.d.ts +27 -22
- package/dist/build/prerender.js +17 -17
- package/dist/build/prerender.js.map +1 -1
- package/dist/build/report.d.ts +3 -4
- package/dist/build/report.js.map +1 -1
- package/dist/build/run-prerender.d.ts +3 -4
- package/dist/build/run-prerender.js.map +1 -1
- package/dist/build/standalone.d.ts +32 -0
- package/dist/build/standalone.js +199 -0
- package/dist/build/standalone.js.map +1 -0
- package/dist/build/static-export.d.ts +17 -29
- package/dist/build/static-export.js.map +1 -1
- package/dist/cache.d.ts +2 -0
- package/dist/cache.js +2 -0
- package/dist/check.d.ts +4 -4
- package/dist/check.js +1 -1
- package/dist/check.js.map +1 -1
- package/dist/cli.js +37 -26
- package/dist/cli.js.map +1 -1
- package/dist/client/empty-module.d.ts +1 -0
- package/dist/client/empty-module.js +1 -0
- package/dist/client/entry.js +2 -0
- package/dist/client/entry.js.map +1 -1
- package/dist/client/instrumentation-client-state.d.ts +10 -0
- package/dist/client/instrumentation-client-state.js +19 -0
- package/dist/client/instrumentation-client-state.js.map +1 -0
- package/dist/client/instrumentation-client.d.ts +8 -0
- package/dist/client/instrumentation-client.js +8 -0
- package/dist/client/instrumentation-client.js.map +1 -0
- package/dist/client/vinext-next-data.d.ts +5 -8
- package/dist/cloudflare/index.js +1 -1
- package/dist/cloudflare/kv-cache-handler.d.ts +5 -3
- package/dist/cloudflare/kv-cache-handler.js +1 -1
- package/dist/cloudflare/kv-cache-handler.js.map +1 -1
- package/dist/cloudflare/tpr.d.ts +35 -27
- package/dist/cloudflare/tpr.js +37 -15
- package/dist/cloudflare/tpr.js.map +1 -1
- package/dist/config/config-matchers.d.ts +2 -2
- package/dist/config/config-matchers.js +1 -1
- package/dist/config/config-matchers.js.map +1 -1
- package/dist/config/dotenv.d.ts +4 -4
- package/dist/config/dotenv.js.map +1 -1
- package/dist/config/next-config.d.ts +40 -61
- package/dist/config/next-config.js +5 -4
- package/dist/config/next-config.js.map +1 -1
- package/dist/deploy.d.ts +25 -41
- package/dist/deploy.js +10 -4
- package/dist/deploy.js.map +1 -1
- package/dist/entries/app-rsc-entry.d.ts +6 -10
- package/dist/entries/app-rsc-entry.js +31 -28
- package/dist/entries/app-rsc-entry.js.map +1 -1
- package/dist/entries/pages-client-entry.js +2 -0
- package/dist/entries/pages-client-entry.js.map +1 -1
- package/dist/entries/pages-server-entry.js +42 -263
- package/dist/entries/pages-server-entry.js.map +1 -1
- package/dist/entries/runtime-entry-module.d.ts +13 -1
- package/dist/entries/runtime-entry-module.js +18 -4
- package/dist/entries/runtime-entry-module.js.map +1 -1
- package/dist/index.d.ts +33 -41
- package/dist/index.js +263 -777
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +14 -26
- package/dist/init.js +8 -2
- package/dist/init.js.map +1 -1
- package/dist/plugins/client-reference-dedup.js.map +1 -1
- package/dist/plugins/fix-use-server-closure-collision.d.ts +29 -0
- package/dist/plugins/fix-use-server-closure-collision.js +204 -0
- package/dist/plugins/fix-use-server-closure-collision.js.map +1 -0
- package/dist/plugins/fonts.d.ts +56 -0
- package/dist/plugins/fonts.js +531 -0
- package/dist/plugins/fonts.js.map +1 -0
- package/dist/plugins/instrumentation-client.d.ts +7 -0
- package/dist/plugins/instrumentation-client.js +29 -0
- package/dist/plugins/instrumentation-client.js.map +1 -0
- package/dist/plugins/og-assets.d.ts +26 -0
- package/dist/plugins/og-assets.js +118 -0
- package/dist/plugins/og-assets.js.map +1 -0
- package/dist/plugins/optimize-imports.d.ts +2 -2
- package/dist/plugins/optimize-imports.js +4 -4
- package/dist/plugins/optimize-imports.js.map +1 -1
- package/dist/plugins/server-externals-manifest.d.ts +27 -0
- package/dist/plugins/server-externals-manifest.js +76 -0
- package/dist/plugins/server-externals-manifest.js.map +1 -0
- package/dist/routing/app-router.d.ts +29 -55
- package/dist/routing/app-router.js.map +1 -1
- package/dist/routing/file-matcher.d.ts +2 -2
- package/dist/routing/file-matcher.js.map +1 -1
- package/dist/routing/pages-router.d.ts +6 -11
- package/dist/routing/pages-router.js.map +1 -1
- package/dist/routing/route-trie.d.ts +2 -2
- package/dist/routing/route-trie.js.map +1 -1
- package/dist/server/api-handler.js +6 -23
- package/dist/server/api-handler.js.map +1 -1
- package/dist/server/app-browser-entry.js +274 -39
- package/dist/server/app-browser-entry.js.map +1 -1
- package/dist/server/app-browser-stream.d.ts +6 -6
- package/dist/server/app-browser-stream.js.map +1 -1
- package/dist/server/app-page-boundary-render.d.ts +8 -8
- package/dist/server/app-page-boundary-render.js +2 -2
- package/dist/server/app-page-boundary-render.js.map +1 -1
- package/dist/server/app-page-boundary.d.ts +13 -11
- package/dist/server/app-page-boundary.js +1 -1
- package/dist/server/app-page-boundary.js.map +1 -1
- package/dist/server/app-page-cache.d.ts +10 -10
- package/dist/server/app-page-cache.js.map +1 -1
- package/dist/server/app-page-execution.d.ts +10 -10
- package/dist/server/app-page-execution.js.map +1 -1
- package/dist/server/app-page-probe.d.ts +2 -2
- package/dist/server/app-page-probe.js.map +1 -1
- package/dist/server/app-page-render.d.ts +4 -4
- package/dist/server/app-page-render.js.map +1 -1
- package/dist/server/app-page-request.d.ts +12 -12
- package/dist/server/app-page-request.js.map +1 -1
- package/dist/server/app-page-response.d.ts +18 -18
- package/dist/server/app-page-response.js.map +1 -1
- package/dist/server/app-page-stream.d.ts +18 -18
- package/dist/server/app-page-stream.js.map +1 -1
- package/dist/server/app-route-handler-cache.d.ts +2 -2
- package/dist/server/app-route-handler-cache.js.map +1 -1
- package/dist/server/app-route-handler-execution.d.ts +6 -6
- package/dist/server/app-route-handler-execution.js.map +1 -1
- package/dist/server/app-route-handler-policy.d.ts +8 -8
- package/dist/server/app-route-handler-policy.js.map +1 -1
- package/dist/server/app-route-handler-response.d.ts +6 -6
- package/dist/server/app-route-handler-response.js.map +1 -1
- package/dist/server/app-route-handler-runtime.d.ts +4 -4
- package/dist/server/app-route-handler-runtime.js.map +1 -1
- package/dist/server/app-ssr-entry.d.ts +4 -4
- package/dist/server/app-ssr-entry.js.map +1 -1
- package/dist/server/app-ssr-stream.d.ts +2 -2
- package/dist/server/app-ssr-stream.js +1 -3
- package/dist/server/app-ssr-stream.js.map +1 -1
- package/dist/server/dev-module-runner.d.ts +2 -2
- package/dist/server/dev-module-runner.js.map +1 -1
- package/dist/server/dev-server.js +8 -8
- package/dist/server/dev-server.js.map +1 -1
- package/dist/server/image-optimization.d.ts +7 -12
- package/dist/server/image-optimization.js.map +1 -1
- package/dist/server/instrumentation.d.ts +13 -13
- package/dist/server/instrumentation.js +16 -7
- package/dist/server/instrumentation.js.map +1 -1
- package/dist/server/isr-cache.d.ts +2 -2
- package/dist/server/isr-cache.js.map +1 -1
- package/dist/server/metadata-routes.d.ts +14 -19
- package/dist/server/metadata-routes.js.map +1 -1
- package/dist/server/middleware.d.ts +10 -16
- package/dist/server/middleware.js +15 -8
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/pages-api-route.d.ts +23 -0
- package/dist/server/pages-api-route.js +40 -0
- package/dist/server/pages-api-route.js.map +1 -0
- package/dist/server/pages-i18n.d.ts +4 -4
- package/dist/server/pages-i18n.js.map +1 -1
- package/dist/server/pages-media-type.d.ts +16 -0
- package/dist/server/pages-media-type.js +25 -0
- package/dist/server/pages-media-type.js.map +1 -0
- package/dist/server/pages-node-compat.d.ts +45 -0
- package/dist/server/pages-node-compat.js +148 -0
- package/dist/server/pages-node-compat.js.map +1 -0
- package/dist/server/pages-page-data.d.ts +22 -22
- package/dist/server/pages-page-data.js.map +1 -1
- package/dist/server/pages-page-response.d.ts +8 -8
- package/dist/server/pages-page-response.js.map +1 -1
- package/dist/server/prod-server.d.ts +20 -15
- package/dist/server/prod-server.js +171 -53
- package/dist/server/prod-server.js.map +1 -1
- package/dist/server/seed-cache.js.map +1 -1
- package/dist/server/static-file-cache.d.ts +57 -0
- package/dist/server/static-file-cache.js +219 -0
- package/dist/server/static-file-cache.js.map +1 -0
- package/dist/shims/app.d.ts +2 -2
- package/dist/shims/cache-for-request.d.ts +58 -0
- package/dist/shims/cache-for-request.js +74 -0
- package/dist/shims/cache-for-request.js.map +1 -0
- package/dist/shims/cache-runtime.d.ts +6 -9
- package/dist/shims/cache-runtime.js.map +1 -1
- package/dist/shims/cache.d.ts +28 -31
- package/dist/shims/cache.js.map +1 -1
- package/dist/shims/config.d.ts +2 -2
- package/dist/shims/config.js.map +1 -1
- package/dist/shims/dynamic.d.ts +2 -2
- package/dist/shims/dynamic.js +30 -17
- package/dist/shims/dynamic.js.map +1 -1
- package/dist/shims/error-boundary.d.ts +7 -7
- package/dist/shims/error-boundary.js.map +1 -1
- package/dist/shims/error.d.ts +2 -2
- package/dist/shims/error.js.map +1 -1
- package/dist/shims/fetch-cache.d.ts +4 -4
- package/dist/shims/fetch-cache.js.map +1 -1
- package/dist/shims/font-google-base.d.ts +4 -4
- package/dist/shims/font-google-base.js.map +1 -1
- package/dist/shims/font-local.d.ts +6 -6
- package/dist/shims/font-local.js.map +1 -1
- package/dist/shims/form.d.ts +4 -8
- package/dist/shims/form.js +4 -6
- package/dist/shims/form.js.map +1 -1
- package/dist/shims/head-state.d.ts +2 -2
- package/dist/shims/head-state.js.map +1 -1
- package/dist/shims/head.d.ts +2 -2
- package/dist/shims/head.js +18 -20
- package/dist/shims/head.js.map +1 -1
- package/dist/shims/headers.d.ts +4 -4
- package/dist/shims/headers.js +1 -1
- package/dist/shims/headers.js.map +1 -1
- package/dist/shims/i18n-context.d.ts +2 -2
- package/dist/shims/i18n-context.js.map +1 -1
- package/dist/shims/i18n-state.d.ts +2 -2
- package/dist/shims/i18n-state.js.map +1 -1
- package/dist/shims/image-config.d.ts +2 -2
- package/dist/shims/image-config.js.map +1 -1
- package/dist/shims/image.d.ts +5 -6
- package/dist/shims/image.js +24 -8
- package/dist/shims/image.js.map +1 -1
- package/dist/shims/internal/app-router-context.d.ts +6 -6
- package/dist/shims/internal/app-router-context.js.map +1 -1
- package/dist/shims/internal/utils.d.ts +2 -2
- package/dist/shims/internal/utils.js.map +1 -1
- package/dist/shims/layout-segment-context.d.ts +12 -5
- package/dist/shims/layout-segment-context.js +18 -7
- package/dist/shims/layout-segment-context.js.map +1 -1
- package/dist/shims/legacy-image.d.ts +5 -8
- package/dist/shims/legacy-image.js.map +1 -1
- package/dist/shims/link.d.ts +21 -31
- package/dist/shims/link.js +4 -56
- package/dist/shims/link.js.map +1 -1
- package/dist/shims/metadata.d.ts +23 -31
- package/dist/shims/metadata.js.map +1 -1
- package/dist/shims/navigation-state.d.ts +2 -2
- package/dist/shims/navigation-state.js.map +1 -1
- package/dist/shims/navigation.d.ts +102 -17
- package/dist/shims/navigation.js +361 -113
- package/dist/shims/navigation.js.map +1 -1
- package/dist/shims/request-context.d.ts +2 -2
- package/dist/shims/request-context.js.map +1 -1
- package/dist/shims/router-state.d.ts +4 -4
- package/dist/shims/router-state.js.map +1 -1
- package/dist/shims/router.d.ts +28 -47
- package/dist/shims/router.js.map +1 -1
- package/dist/shims/script.d.ts +16 -31
- package/dist/shims/script.js.map +1 -1
- package/dist/shims/server.d.ts +11 -10
- package/dist/shims/server.js +3 -0
- package/dist/shims/server.js.map +1 -1
- package/dist/shims/unified-request-context.d.ts +4 -4
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/shims/unified-request-context.js.map +1 -1
- package/dist/shims/web-vitals.d.ts +2 -2
- package/dist/shims/web-vitals.js.map +1 -1
- package/dist/utils/lazy-chunks.d.ts +34 -0
- package/dist/utils/lazy-chunks.js +50 -0
- package/dist/utils/lazy-chunks.js.map +1 -0
- package/dist/utils/vinext-root.d.ts +24 -0
- package/dist/utils/vinext-root.js +31 -0
- package/dist/utils/vinext-root.js.map +1 -0
- package/package.json +8 -4
package/dist/shims/navigation.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { toBrowserNavigationHref, toSameOriginAppPath } from "./url-utils.js";
|
|
3
|
+
import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
|
|
3
4
|
import { ReadonlyURLSearchParams } from "./readonly-url-search-params.js";
|
|
4
5
|
import * as React$1 from "react";
|
|
5
6
|
//#region src/shims/navigation.ts
|
|
@@ -26,18 +27,19 @@ const ServerInsertedHTMLContext = getServerInsertedHTMLContext();
|
|
|
26
27
|
function getLayoutSegmentContext() {
|
|
27
28
|
if (typeof React$1.createContext !== "function") return null;
|
|
28
29
|
const globalState = globalThis;
|
|
29
|
-
if (!globalState[_LAYOUT_SEGMENT_CTX_KEY]) globalState[_LAYOUT_SEGMENT_CTX_KEY] = React$1.createContext([]);
|
|
30
|
+
if (!globalState[_LAYOUT_SEGMENT_CTX_KEY]) globalState[_LAYOUT_SEGMENT_CTX_KEY] = React$1.createContext({ children: [] });
|
|
30
31
|
return globalState[_LAYOUT_SEGMENT_CTX_KEY] ?? null;
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
|
-
* Read the child segments below the current layout
|
|
34
|
-
* Returns [] if no context is available (RSC environment, outside React tree)
|
|
34
|
+
* Read the child segments for a parallel route below the current layout.
|
|
35
|
+
* Returns [] if no context is available (RSC environment, outside React tree)
|
|
36
|
+
* or if the requested key is not present in the segment map.
|
|
35
37
|
*/
|
|
36
|
-
function useChildSegments() {
|
|
38
|
+
function useChildSegments(parallelRoutesKey = "children") {
|
|
37
39
|
const ctx = getLayoutSegmentContext();
|
|
38
40
|
if (!ctx) return [];
|
|
39
41
|
try {
|
|
40
|
-
return React$1.useContext(ctx);
|
|
42
|
+
return React$1.useContext(ctx)[parallelRoutesKey] ?? [];
|
|
41
43
|
} catch {
|
|
42
44
|
return [];
|
|
43
45
|
}
|
|
@@ -129,91 +131,300 @@ function getPrefetchedUrls() {
|
|
|
129
131
|
return window.__VINEXT_RSC_PREFETCHED_URLS__;
|
|
130
132
|
}
|
|
131
133
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* link-heavy pages.
|
|
134
|
+
* Evict prefetch cache entries if at capacity.
|
|
135
|
+
* First sweeps expired entries, then falls back to FIFO eviction.
|
|
135
136
|
*/
|
|
136
|
-
function
|
|
137
|
+
function evictPrefetchCacheIfNeeded() {
|
|
137
138
|
const cache = getPrefetchCache();
|
|
139
|
+
if (cache.size < 50) return;
|
|
138
140
|
const now = Date.now();
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
prefetched.delete(key);
|
|
144
|
-
}
|
|
141
|
+
const prefetched = getPrefetchedUrls();
|
|
142
|
+
for (const [key, entry] of cache) if (now - entry.timestamp >= 3e4) {
|
|
143
|
+
cache.delete(key);
|
|
144
|
+
prefetched.delete(key);
|
|
145
145
|
}
|
|
146
|
-
|
|
146
|
+
while (cache.size >= 50) {
|
|
147
147
|
const oldest = cache.keys().next().value;
|
|
148
148
|
if (oldest !== void 0) {
|
|
149
149
|
cache.delete(oldest);
|
|
150
|
-
|
|
151
|
-
}
|
|
150
|
+
prefetched.delete(oldest);
|
|
151
|
+
} else break;
|
|
152
152
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Store a prefetched RSC response in the cache by snapshotting it to an
|
|
156
|
+
* ArrayBuffer. The snapshot completes asynchronously; during that window
|
|
157
|
+
* the entry is marked `pending` so consumePrefetchResponse() will skip it
|
|
158
|
+
* (the caller falls back to a fresh fetch, which is acceptable).
|
|
159
|
+
*
|
|
160
|
+
* Prefer prefetchRscResponse() for new call-sites — it handles the full
|
|
161
|
+
* prefetch lifecycle including dedup. storePrefetchResponse() is kept for
|
|
162
|
+
* backward compatibility and test helpers.
|
|
163
|
+
*
|
|
164
|
+
* NB: Caller is responsible for managing getPrefetchedUrls() — this
|
|
165
|
+
* function only stores the response in the prefetch cache.
|
|
166
|
+
*/
|
|
167
|
+
function storePrefetchResponse(rscUrl, response) {
|
|
168
|
+
evictPrefetchCacheIfNeeded();
|
|
169
|
+
const entry = { timestamp: Date.now() };
|
|
170
|
+
entry.pending = snapshotRscResponse(response).then((snapshot) => {
|
|
171
|
+
entry.snapshot = snapshot;
|
|
172
|
+
}).catch(() => {
|
|
173
|
+
getPrefetchCache().delete(rscUrl);
|
|
174
|
+
}).finally(() => {
|
|
175
|
+
entry.pending = void 0;
|
|
156
176
|
});
|
|
177
|
+
getPrefetchCache().set(rscUrl, entry);
|
|
157
178
|
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Snapshot an RSC response to an ArrayBuffer for caching and replay.
|
|
181
|
+
* Consumes the response body and stores it with content-type and URL metadata.
|
|
182
|
+
*/
|
|
183
|
+
async function snapshotRscResponse(response) {
|
|
184
|
+
return {
|
|
185
|
+
buffer: await response.arrayBuffer(),
|
|
186
|
+
contentType: response.headers.get("content-type") ?? "text/x-component",
|
|
187
|
+
paramsHeader: response.headers.get("X-Vinext-Params"),
|
|
188
|
+
url: response.url
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Reconstruct a Response from a cached RSC snapshot.
|
|
193
|
+
* Creates a new Response with the original ArrayBuffer so createFromFetch
|
|
194
|
+
* can consume the stream from scratch.
|
|
195
|
+
*
|
|
196
|
+
* NOTE: The reconstructed Response always has `url === ""` — the Response
|
|
197
|
+
* constructor does not accept a `url` option, and `response.url` is read-only
|
|
198
|
+
* set by the fetch infrastructure. Callers that need the original URL should
|
|
199
|
+
* read it from `cached.url` directly rather than from the restored Response.
|
|
200
|
+
*
|
|
201
|
+
* @param copy - When true (default), copies the ArrayBuffer so the cached
|
|
202
|
+
* snapshot remains replayable (needed for the visited-response cache).
|
|
203
|
+
* Pass false for single-consumption paths (e.g. prefetch cache entries
|
|
204
|
+
* that are deleted after consumption) to avoid the extra allocation.
|
|
205
|
+
*/
|
|
206
|
+
function restoreRscResponse(cached, copy = true) {
|
|
207
|
+
const headers = new Headers({ "content-type": cached.contentType });
|
|
208
|
+
if (cached.paramsHeader != null) headers.set("X-Vinext-Params", cached.paramsHeader);
|
|
209
|
+
return new Response(copy ? cached.buffer.slice(0) : cached.buffer, {
|
|
210
|
+
status: 200,
|
|
211
|
+
headers
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Prefetch an RSC response and snapshot it for later consumption.
|
|
216
|
+
* Stores the in-flight promise so immediate clicks can await it instead
|
|
217
|
+
* of firing a duplicate fetch.
|
|
218
|
+
* Enforces a maximum cache size to prevent unbounded memory growth on
|
|
219
|
+
* link-heavy pages.
|
|
220
|
+
*/
|
|
221
|
+
function prefetchRscResponse(rscUrl, fetchPromise) {
|
|
222
|
+
const cache = getPrefetchCache();
|
|
223
|
+
const prefetched = getPrefetchedUrls();
|
|
224
|
+
const entry = { timestamp: Date.now() };
|
|
225
|
+
entry.pending = fetchPromise.then(async (response) => {
|
|
226
|
+
if (response.ok) entry.snapshot = await snapshotRscResponse(response);
|
|
227
|
+
else {
|
|
228
|
+
prefetched.delete(rscUrl);
|
|
229
|
+
cache.delete(rscUrl);
|
|
230
|
+
}
|
|
231
|
+
}).catch(() => {
|
|
232
|
+
prefetched.delete(rscUrl);
|
|
233
|
+
cache.delete(rscUrl);
|
|
234
|
+
}).finally(() => {
|
|
235
|
+
entry.pending = void 0;
|
|
236
|
+
});
|
|
237
|
+
cache.set(rscUrl, entry);
|
|
238
|
+
evictPrefetchCacheIfNeeded();
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Consume a prefetched response for a given rscUrl.
|
|
242
|
+
* Only returns settled (non-pending) snapshots synchronously.
|
|
243
|
+
* Returns null if the entry is still in flight or doesn't exist.
|
|
244
|
+
*/
|
|
245
|
+
function consumePrefetchResponse(rscUrl) {
|
|
246
|
+
const cache = getPrefetchCache();
|
|
247
|
+
const entry = cache.get(rscUrl);
|
|
248
|
+
if (!entry) return null;
|
|
249
|
+
if (entry.pending) return null;
|
|
250
|
+
cache.delete(rscUrl);
|
|
251
|
+
getPrefetchedUrls().delete(rscUrl);
|
|
252
|
+
if (entry.snapshot) {
|
|
253
|
+
if (Date.now() - entry.timestamp >= 3e4) return null;
|
|
254
|
+
return entry.snapshot;
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
const _CLIENT_NAV_STATE_KEY = Symbol.for("vinext.clientNavigationState");
|
|
259
|
+
function getClientNavigationState() {
|
|
260
|
+
if (isServer) return null;
|
|
261
|
+
const globalState = window;
|
|
262
|
+
globalState[_CLIENT_NAV_STATE_KEY] ??= {
|
|
263
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
264
|
+
cachedSearch: window.location.search,
|
|
265
|
+
cachedReadonlySearchParams: new ReadonlyURLSearchParams(window.location.search),
|
|
266
|
+
cachedPathname: stripBasePath(window.location.pathname, __basePath),
|
|
267
|
+
clientParams: {},
|
|
268
|
+
clientParamsJson: "{}",
|
|
269
|
+
pendingClientParams: null,
|
|
270
|
+
pendingClientParamsJson: null,
|
|
271
|
+
originalPushState: window.history.pushState.bind(window.history),
|
|
272
|
+
originalReplaceState: window.history.replaceState.bind(window.history),
|
|
273
|
+
patchInstalled: false,
|
|
274
|
+
hasPendingNavigationUpdate: false,
|
|
275
|
+
suppressUrlNotifyCount: 0,
|
|
276
|
+
navigationSnapshotActiveCount: 0
|
|
277
|
+
};
|
|
278
|
+
return globalState[_CLIENT_NAV_STATE_KEY];
|
|
279
|
+
}
|
|
280
|
+
function notifyNavigationListeners() {
|
|
281
|
+
const state = getClientNavigationState();
|
|
282
|
+
if (!state) return;
|
|
283
|
+
for (const fn of state.listeners) fn();
|
|
161
284
|
}
|
|
162
|
-
let _cachedSearch = !isServer ? window.location.search : "";
|
|
163
|
-
let _cachedReadonlySearchParams = new ReadonlyURLSearchParams(_cachedSearch);
|
|
164
285
|
let _cachedEmptyServerSearchParams = null;
|
|
165
|
-
|
|
286
|
+
/**
|
|
287
|
+
* Get cached pathname snapshot for useSyncExternalStore.
|
|
288
|
+
* Note: Returns cached value from ClientNavigationState, not live window.location.
|
|
289
|
+
* The cache is updated by syncCommittedUrlStateFromLocation() after navigation commits.
|
|
290
|
+
* This ensures referential stability and prevents infinite re-renders.
|
|
291
|
+
* External pushState/replaceState while URL notifications are suppressed won't
|
|
292
|
+
* be visible until the next commit.
|
|
293
|
+
*/
|
|
166
294
|
function getPathnameSnapshot() {
|
|
167
|
-
|
|
168
|
-
if (current !== _cachedPathname) _cachedPathname = current;
|
|
169
|
-
return _cachedPathname;
|
|
295
|
+
return getClientNavigationState()?.cachedPathname ?? "/";
|
|
170
296
|
}
|
|
297
|
+
let _cachedEmptyClientSearchParams = null;
|
|
298
|
+
/**
|
|
299
|
+
* Get cached search params snapshot for useSyncExternalStore.
|
|
300
|
+
* Note: Returns cached value from ClientNavigationState, not live window.location.search.
|
|
301
|
+
* The cache is updated by syncCommittedUrlStateFromLocation() after navigation commits.
|
|
302
|
+
* This ensures referential stability and prevents infinite re-renders.
|
|
303
|
+
* External pushState/replaceState while URL notifications are suppressed won't
|
|
304
|
+
* be visible until the next commit.
|
|
305
|
+
*/
|
|
171
306
|
function getSearchParamsSnapshot() {
|
|
172
|
-
const
|
|
173
|
-
if (
|
|
174
|
-
|
|
175
|
-
|
|
307
|
+
const cached = getClientNavigationState()?.cachedReadonlySearchParams;
|
|
308
|
+
if (cached) return cached;
|
|
309
|
+
if (_cachedEmptyClientSearchParams === null) _cachedEmptyClientSearchParams = new ReadonlyURLSearchParams();
|
|
310
|
+
return _cachedEmptyClientSearchParams;
|
|
311
|
+
}
|
|
312
|
+
function syncCommittedUrlStateFromLocation() {
|
|
313
|
+
const state = getClientNavigationState();
|
|
314
|
+
if (!state) return false;
|
|
315
|
+
let changed = false;
|
|
316
|
+
const pathname = stripBasePath(window.location.pathname, __basePath);
|
|
317
|
+
if (pathname !== state.cachedPathname) {
|
|
318
|
+
state.cachedPathname = pathname;
|
|
319
|
+
changed = true;
|
|
320
|
+
}
|
|
321
|
+
const search = window.location.search;
|
|
322
|
+
if (search !== state.cachedSearch) {
|
|
323
|
+
state.cachedSearch = search;
|
|
324
|
+
state.cachedReadonlySearchParams = new ReadonlyURLSearchParams(search);
|
|
325
|
+
changed = true;
|
|
176
326
|
}
|
|
177
|
-
return
|
|
327
|
+
return changed;
|
|
178
328
|
}
|
|
179
329
|
function getServerSearchParamsSnapshot() {
|
|
180
330
|
const ctx = _getServerContext();
|
|
181
|
-
if (ctx
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
ctx[_READONLY_SEARCH_PARAMS_SOURCE] = searchParams;
|
|
185
|
-
ctx[_READONLY_SEARCH_PARAMS] = new ReadonlyURLSearchParams(searchParams);
|
|
186
|
-
}
|
|
187
|
-
return ctx[_READONLY_SEARCH_PARAMS];
|
|
331
|
+
if (!ctx) {
|
|
332
|
+
if (_cachedEmptyServerSearchParams === null) _cachedEmptyServerSearchParams = new ReadonlyURLSearchParams();
|
|
333
|
+
return _cachedEmptyServerSearchParams;
|
|
188
334
|
}
|
|
189
|
-
|
|
190
|
-
|
|
335
|
+
const source = ctx.searchParams;
|
|
336
|
+
const cached = ctx[_READONLY_SEARCH_PARAMS];
|
|
337
|
+
const cachedSource = ctx[_READONLY_SEARCH_PARAMS_SOURCE];
|
|
338
|
+
if (cached && cachedSource === source) return cached;
|
|
339
|
+
const readonly = new ReadonlyURLSearchParams(source);
|
|
340
|
+
ctx[_READONLY_SEARCH_PARAMS] = readonly;
|
|
341
|
+
ctx[_READONLY_SEARCH_PARAMS_SOURCE] = source;
|
|
342
|
+
return readonly;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Mark a navigation snapshot as active. Called before startTransition
|
|
346
|
+
* in renderNavigationPayload. While active, hooks prefer the snapshot
|
|
347
|
+
* context value over useSyncExternalStore. Uses a counter (not boolean)
|
|
348
|
+
* to handle overlapping navigations — rapid clicks can interleave
|
|
349
|
+
* activate/deactivate if multiple transitions are in flight.
|
|
350
|
+
*/
|
|
351
|
+
function activateNavigationSnapshot() {
|
|
352
|
+
const state = getClientNavigationState();
|
|
353
|
+
if (state) state.navigationSnapshotActiveCount++;
|
|
191
354
|
}
|
|
192
355
|
const _EMPTY_PARAMS = {};
|
|
193
|
-
|
|
194
|
-
|
|
356
|
+
const _CLIENT_NAV_RENDER_CTX_KEY = Symbol.for("vinext.clientNavigationRenderContext");
|
|
357
|
+
function getClientNavigationRenderContext() {
|
|
358
|
+
if (typeof React$1.createContext !== "function") return null;
|
|
359
|
+
const globalState = globalThis;
|
|
360
|
+
if (!globalState[_CLIENT_NAV_RENDER_CTX_KEY]) globalState[_CLIENT_NAV_RENDER_CTX_KEY] = React$1.createContext(null);
|
|
361
|
+
return globalState[_CLIENT_NAV_RENDER_CTX_KEY] ?? null;
|
|
362
|
+
}
|
|
363
|
+
function useClientNavigationRenderSnapshot() {
|
|
364
|
+
const ctx = getClientNavigationRenderContext();
|
|
365
|
+
if (!ctx || typeof React$1.useContext !== "function") return null;
|
|
366
|
+
try {
|
|
367
|
+
return React$1.useContext(ctx);
|
|
368
|
+
} catch {
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function createClientNavigationRenderSnapshot(href, params) {
|
|
373
|
+
const origin = typeof window !== "undefined" ? window.location.origin : "http://localhost";
|
|
374
|
+
const url = new URL(href, origin);
|
|
375
|
+
return {
|
|
376
|
+
pathname: stripBasePath(url.pathname, __basePath),
|
|
377
|
+
searchParams: new ReadonlyURLSearchParams(url.search),
|
|
378
|
+
params
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
let _fallbackClientParams = _EMPTY_PARAMS;
|
|
382
|
+
let _fallbackClientParamsJson = "{}";
|
|
195
383
|
function setClientParams(params) {
|
|
384
|
+
const state = getClientNavigationState();
|
|
385
|
+
if (!state) {
|
|
386
|
+
const json = JSON.stringify(params);
|
|
387
|
+
if (json !== _fallbackClientParamsJson) {
|
|
388
|
+
_fallbackClientParams = params;
|
|
389
|
+
_fallbackClientParamsJson = json;
|
|
390
|
+
}
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const json = JSON.stringify(params);
|
|
394
|
+
if (json !== state.clientParamsJson) {
|
|
395
|
+
state.clientParams = params;
|
|
396
|
+
state.clientParamsJson = json;
|
|
397
|
+
state.pendingClientParams = null;
|
|
398
|
+
state.pendingClientParamsJson = null;
|
|
399
|
+
notifyNavigationListeners();
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
function replaceClientParamsWithoutNotify(params) {
|
|
403
|
+
const state = getClientNavigationState();
|
|
404
|
+
if (!state) return;
|
|
196
405
|
const json = JSON.stringify(params);
|
|
197
|
-
if (json !==
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
406
|
+
if (json !== state.clientParamsJson && json !== state.pendingClientParamsJson) {
|
|
407
|
+
state.pendingClientParams = params;
|
|
408
|
+
state.pendingClientParamsJson = json;
|
|
409
|
+
state.hasPendingNavigationUpdate = true;
|
|
201
410
|
}
|
|
202
411
|
}
|
|
203
412
|
/** Get the current client params (for testing referential stability). */
|
|
204
413
|
function getClientParams() {
|
|
205
|
-
return
|
|
414
|
+
return getClientNavigationState()?.clientParams ?? _fallbackClientParams;
|
|
206
415
|
}
|
|
207
416
|
function getClientParamsSnapshot() {
|
|
208
|
-
return
|
|
417
|
+
return getClientNavigationState()?.clientParams ?? _EMPTY_PARAMS;
|
|
209
418
|
}
|
|
210
419
|
function getServerParamsSnapshot() {
|
|
211
420
|
return _getServerContext()?.params ?? _EMPTY_PARAMS;
|
|
212
421
|
}
|
|
213
422
|
function subscribeToNavigation(cb) {
|
|
214
|
-
|
|
423
|
+
const state = getClientNavigationState();
|
|
424
|
+
if (!state) return () => {};
|
|
425
|
+
state.listeners.add(cb);
|
|
215
426
|
return () => {
|
|
216
|
-
|
|
427
|
+
state.listeners.delete(cb);
|
|
217
428
|
};
|
|
218
429
|
}
|
|
219
430
|
/**
|
|
@@ -222,21 +433,30 @@ function subscribeToNavigation(cb) {
|
|
|
222
433
|
*/
|
|
223
434
|
function usePathname() {
|
|
224
435
|
if (isServer) return _getServerContext()?.pathname ?? "/";
|
|
225
|
-
|
|
436
|
+
const renderSnapshot = useClientNavigationRenderSnapshot();
|
|
437
|
+
const pathname = React$1.useSyncExternalStore(subscribeToNavigation, getPathnameSnapshot, () => _getServerContext()?.pathname ?? "/");
|
|
438
|
+
if (renderSnapshot && (getClientNavigationState()?.navigationSnapshotActiveCount ?? 0) > 0) return renderSnapshot.pathname;
|
|
439
|
+
return pathname;
|
|
226
440
|
}
|
|
227
441
|
/**
|
|
228
442
|
* Returns the current search params as a read-only URLSearchParams.
|
|
229
443
|
*/
|
|
230
444
|
function useSearchParams() {
|
|
231
445
|
if (isServer) return getServerSearchParamsSnapshot();
|
|
232
|
-
|
|
446
|
+
const renderSnapshot = useClientNavigationRenderSnapshot();
|
|
447
|
+
const searchParams = React$1.useSyncExternalStore(subscribeToNavigation, getSearchParamsSnapshot, getServerSearchParamsSnapshot);
|
|
448
|
+
if (renderSnapshot && (getClientNavigationState()?.navigationSnapshotActiveCount ?? 0) > 0) return renderSnapshot.searchParams;
|
|
449
|
+
return searchParams;
|
|
233
450
|
}
|
|
234
451
|
/**
|
|
235
452
|
* Returns the dynamic params for the current route.
|
|
236
453
|
*/
|
|
237
454
|
function useParams() {
|
|
238
455
|
if (isServer) return _getServerContext()?.params ?? _EMPTY_PARAMS;
|
|
239
|
-
|
|
456
|
+
const renderSnapshot = useClientNavigationRenderSnapshot();
|
|
457
|
+
const params = React$1.useSyncExternalStore(subscribeToNavigation, getClientParamsSnapshot, getServerParamsSnapshot);
|
|
458
|
+
if (renderSnapshot && (getClientNavigationState()?.navigationSnapshotActiveCount ?? 0) > 0) return renderSnapshot.params;
|
|
459
|
+
return params;
|
|
240
460
|
}
|
|
241
461
|
/**
|
|
242
462
|
* Check if a href is an external URL (any URL scheme per RFC 3986, or protocol-relative).
|
|
@@ -253,7 +473,7 @@ function isHashOnlyChange(href) {
|
|
|
253
473
|
try {
|
|
254
474
|
const current = new URL(window.location.href);
|
|
255
475
|
const next = new URL(href, window.location.href);
|
|
256
|
-
return current.pathname === next.pathname && current.search === next.search && next.hash !== "";
|
|
476
|
+
return stripBasePath(current.pathname, __basePath) === stripBasePath(next.pathname, __basePath) && current.search === next.search && next.hash !== "";
|
|
257
477
|
} catch {
|
|
258
478
|
return false;
|
|
259
479
|
}
|
|
@@ -270,25 +490,52 @@ function scrollToHash(hash) {
|
|
|
270
490
|
const element = document.getElementById(id);
|
|
271
491
|
if (element) element.scrollIntoView({ behavior: "auto" });
|
|
272
492
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
493
|
+
function withSuppressedUrlNotifications(fn) {
|
|
494
|
+
const state = getClientNavigationState();
|
|
495
|
+
if (!state) return fn();
|
|
496
|
+
state.suppressUrlNotifyCount += 1;
|
|
497
|
+
try {
|
|
498
|
+
return fn();
|
|
499
|
+
} finally {
|
|
500
|
+
state.suppressUrlNotifyCount -= 1;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
function commitClientNavigationState() {
|
|
504
|
+
if (isServer) return;
|
|
505
|
+
const state = getClientNavigationState();
|
|
506
|
+
if (!state) return;
|
|
507
|
+
if (state.navigationSnapshotActiveCount > 0) state.navigationSnapshotActiveCount -= 1;
|
|
508
|
+
const urlChanged = syncCommittedUrlStateFromLocation();
|
|
509
|
+
if (state.pendingClientParams !== null && state.pendingClientParamsJson !== null) {
|
|
510
|
+
state.clientParams = state.pendingClientParams;
|
|
511
|
+
state.clientParamsJson = state.pendingClientParamsJson;
|
|
512
|
+
state.pendingClientParams = null;
|
|
513
|
+
state.pendingClientParamsJson = null;
|
|
514
|
+
}
|
|
515
|
+
const shouldNotify = urlChanged || state.hasPendingNavigationUpdate;
|
|
516
|
+
state.hasPendingNavigationUpdate = false;
|
|
517
|
+
if (shouldNotify) notifyNavigationListeners();
|
|
518
|
+
}
|
|
519
|
+
function pushHistoryStateWithoutNotify(data, unused, url) {
|
|
520
|
+
withSuppressedUrlNotifications(() => {
|
|
521
|
+
getClientNavigationState()?.originalPushState.call(window.history, data, unused, url);
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
function replaceHistoryStateWithoutNotify(data, unused, url) {
|
|
525
|
+
withSuppressedUrlNotifications(() => {
|
|
526
|
+
getClientNavigationState()?.originalReplaceState.call(window.history, data, unused, url);
|
|
527
|
+
});
|
|
528
|
+
}
|
|
280
529
|
/**
|
|
281
530
|
* Save the current scroll position into the current history state.
|
|
282
531
|
* Called before every navigation to enable scroll restoration on back/forward.
|
|
283
532
|
*
|
|
284
|
-
* Uses
|
|
285
|
-
* interception (which would cause spurious re-renders
|
|
533
|
+
* Uses replaceHistoryStateWithoutNotify to avoid triggering the patched
|
|
534
|
+
* history.replaceState interception (which would cause spurious re-renders).
|
|
286
535
|
*/
|
|
287
536
|
function saveScrollPosition() {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
_nativeReplaceState.call(window.history, {
|
|
291
|
-
...state,
|
|
537
|
+
replaceHistoryStateWithoutNotify({
|
|
538
|
+
...window.history.state ?? {},
|
|
292
539
|
__vinext_scrollX: window.scrollX,
|
|
293
540
|
__vinext_scrollY: window.scrollY
|
|
294
541
|
}, "");
|
|
@@ -305,7 +552,8 @@ function saveScrollPosition() {
|
|
|
305
552
|
* This handler fires before the browser entry's popstate handler (because
|
|
306
553
|
* navigation.ts is loaded before hydration completes), so we defer via a
|
|
307
554
|
* microtask to give the browser entry handler a chance to set
|
|
308
|
-
* __VINEXT_RSC_PENDING__
|
|
555
|
+
* __VINEXT_RSC_PENDING__. Promise.resolve() schedules a microtask
|
|
556
|
+
* that runs after all synchronous event listeners have completed.
|
|
309
557
|
*/
|
|
310
558
|
function restoreScrollPosition(state) {
|
|
311
559
|
if (state && typeof state === "object" && "__vinext_scrollY" in state) {
|
|
@@ -326,7 +574,7 @@ function restoreScrollPosition(state) {
|
|
|
326
574
|
/**
|
|
327
575
|
* Navigate to a URL, handling external URLs, hash-only changes, and RSC navigation.
|
|
328
576
|
*/
|
|
329
|
-
async function
|
|
577
|
+
async function navigateClientSide(href, mode, scroll) {
|
|
330
578
|
let normalizedHref = href;
|
|
331
579
|
if (isExternalUrl(href)) {
|
|
332
580
|
const localPath = toSameOriginAppPath(href, __basePath);
|
|
@@ -338,32 +586,35 @@ async function navigateImpl(href, mode, scroll) {
|
|
|
338
586
|
normalizedHref = localPath;
|
|
339
587
|
}
|
|
340
588
|
const fullHref = toBrowserNavigationHref(normalizedHref, window.location.href, __basePath);
|
|
589
|
+
notifyAppRouterTransitionStart(fullHref, mode);
|
|
341
590
|
if (mode === "push") saveScrollPosition();
|
|
342
591
|
if (isHashOnlyChange(fullHref)) {
|
|
343
592
|
const hash = fullHref.includes("#") ? fullHref.slice(fullHref.indexOf("#")) : "";
|
|
344
|
-
if (mode === "replace")
|
|
345
|
-
else
|
|
346
|
-
|
|
593
|
+
if (mode === "replace") replaceHistoryStateWithoutNotify(null, "", fullHref);
|
|
594
|
+
else pushHistoryStateWithoutNotify(null, "", fullHref);
|
|
595
|
+
commitClientNavigationState();
|
|
347
596
|
if (scroll) scrollToHash(hash);
|
|
348
597
|
return;
|
|
349
598
|
}
|
|
350
599
|
const hashIdx = fullHref.indexOf("#");
|
|
351
600
|
const hash = hashIdx !== -1 ? fullHref.slice(hashIdx) : "";
|
|
352
|
-
if (
|
|
353
|
-
else
|
|
354
|
-
|
|
355
|
-
|
|
601
|
+
if (typeof window.__VINEXT_RSC_NAVIGATE__ === "function") await window.__VINEXT_RSC_NAVIGATE__(fullHref, 0, "navigate", mode);
|
|
602
|
+
else {
|
|
603
|
+
if (mode === "replace") replaceHistoryStateWithoutNotify(null, "", fullHref);
|
|
604
|
+
else pushHistoryStateWithoutNotify(null, "", fullHref);
|
|
605
|
+
commitClientNavigationState();
|
|
606
|
+
}
|
|
356
607
|
if (scroll) if (hash) scrollToHash(hash);
|
|
357
608
|
else window.scrollTo(0, 0);
|
|
358
609
|
}
|
|
359
610
|
const _appRouter = {
|
|
360
611
|
push(href, options) {
|
|
361
612
|
if (isServer) return;
|
|
362
|
-
|
|
613
|
+
navigateClientSide(href, "push", options?.scroll !== false);
|
|
363
614
|
},
|
|
364
615
|
replace(href, options) {
|
|
365
616
|
if (isServer) return;
|
|
366
|
-
|
|
617
|
+
navigateClientSide(href, "replace", options?.scroll !== false);
|
|
367
618
|
},
|
|
368
619
|
back() {
|
|
369
620
|
if (isServer) return;
|
|
@@ -375,7 +626,7 @@ const _appRouter = {
|
|
|
375
626
|
},
|
|
376
627
|
refresh() {
|
|
377
628
|
if (isServer) return;
|
|
378
|
-
if (typeof window.__VINEXT_RSC_NAVIGATE__ === "function") window.__VINEXT_RSC_NAVIGATE__(window.location.href);
|
|
629
|
+
if (typeof window.__VINEXT_RSC_NAVIGATE__ === "function") window.__VINEXT_RSC_NAVIGATE__(window.location.href, 0, "refresh");
|
|
379
630
|
},
|
|
380
631
|
prefetch(href) {
|
|
381
632
|
if (isServer) return;
|
|
@@ -383,16 +634,11 @@ const _appRouter = {
|
|
|
383
634
|
const prefetched = getPrefetchedUrls();
|
|
384
635
|
if (prefetched.has(rscUrl)) return;
|
|
385
636
|
prefetched.add(rscUrl);
|
|
386
|
-
fetch(rscUrl, {
|
|
637
|
+
prefetchRscResponse(rscUrl, fetch(rscUrl, {
|
|
387
638
|
headers: { Accept: "text/x-component" },
|
|
388
639
|
credentials: "include",
|
|
389
640
|
priority: "low"
|
|
390
|
-
})
|
|
391
|
-
if (response.ok) storePrefetchResponse(rscUrl, response);
|
|
392
|
-
else prefetched.delete(rscUrl);
|
|
393
|
-
}).catch(() => {
|
|
394
|
-
prefetched.delete(rscUrl);
|
|
395
|
-
});
|
|
641
|
+
}));
|
|
396
642
|
}
|
|
397
643
|
};
|
|
398
644
|
/**
|
|
@@ -415,23 +661,21 @@ function useRouter() {
|
|
|
415
661
|
*
|
|
416
662
|
* @param parallelRoutesKey - Which parallel route to read (default: "children")
|
|
417
663
|
*/
|
|
418
|
-
function useSelectedLayoutSegment(
|
|
419
|
-
const segments = useSelectedLayoutSegments(
|
|
664
|
+
function useSelectedLayoutSegment(parallelRoutesKey) {
|
|
665
|
+
const segments = useSelectedLayoutSegments(parallelRoutesKey);
|
|
420
666
|
return segments.length > 0 ? segments[0] : null;
|
|
421
667
|
}
|
|
422
668
|
/**
|
|
423
669
|
* Returns all active segments below the layout where it's called.
|
|
424
670
|
*
|
|
425
671
|
* Each layout in the App Router tree wraps its children with a
|
|
426
|
-
* LayoutSegmentProvider whose value is
|
|
427
|
-
*
|
|
428
|
-
* and catch-all segments joined with "/"). This hook reads those segments
|
|
429
|
-
* directly from context.
|
|
672
|
+
* LayoutSegmentProvider whose value is a map of parallel route key to
|
|
673
|
+
* segment arrays. The "children" key is the default parallel route.
|
|
430
674
|
*
|
|
431
675
|
* @param parallelRoutesKey - Which parallel route to read (default: "children")
|
|
432
676
|
*/
|
|
433
|
-
function useSelectedLayoutSegments(
|
|
434
|
-
return useChildSegments();
|
|
677
|
+
function useSelectedLayoutSegments(parallelRoutesKey) {
|
|
678
|
+
return useChildSegments(parallelRoutesKey);
|
|
435
679
|
}
|
|
436
680
|
/**
|
|
437
681
|
* useServerInsertedHTML — inject HTML during SSR from client components.
|
|
@@ -559,22 +803,26 @@ function unauthorized() {
|
|
|
559
803
|
throw new VinextNavigationError("NEXT_UNAUTHORIZED", `${HTTP_ERROR_FALLBACK_ERROR_CODE};401`);
|
|
560
804
|
}
|
|
561
805
|
if (!isServer) {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
806
|
+
const state = getClientNavigationState();
|
|
807
|
+
if (state && !state.patchInstalled) {
|
|
808
|
+
state.patchInstalled = true;
|
|
809
|
+
window.addEventListener("popstate", (event) => {
|
|
810
|
+
if (typeof window.__VINEXT_RSC_NAVIGATE__ !== "function") {
|
|
811
|
+
commitClientNavigationState();
|
|
812
|
+
restoreScrollPosition(event.state);
|
|
813
|
+
}
|
|
814
|
+
});
|
|
815
|
+
window.history.pushState = function patchedPushState(data, unused, url) {
|
|
816
|
+
state.originalPushState.call(window.history, data, unused, url);
|
|
817
|
+
if (state.suppressUrlNotifyCount === 0) commitClientNavigationState();
|
|
818
|
+
};
|
|
819
|
+
window.history.replaceState = function patchedReplaceState(data, unused, url) {
|
|
820
|
+
state.originalReplaceState.call(window.history, data, unused, url);
|
|
821
|
+
if (state.suppressUrlNotifyCount === 0) commitClientNavigationState();
|
|
822
|
+
};
|
|
823
|
+
}
|
|
576
824
|
}
|
|
577
825
|
//#endregion
|
|
578
|
-
export { GLOBAL_ACCESSORS_KEY, HTTP_ERROR_FALLBACK_ERROR_CODE, MAX_PREFETCH_CACHE_SIZE, PREFETCH_CACHE_TTL, ReadonlyURLSearchParams, RedirectType, ServerInsertedHTMLContext, _registerStateAccessors, clearServerInsertedHTML, flushServerInsertedHTML, forbidden, getAccessFallbackHTTPStatus, getClientParams, getLayoutSegmentContext, getNavigationContext, getPrefetchCache, getPrefetchedUrls, isHTTPAccessFallbackError, notFound, permanentRedirect, redirect, setClientParams, setNavigationContext, storePrefetchResponse, toRscUrl, unauthorized, useParams, usePathname, useRouter, useSearchParams, useSelectedLayoutSegment, useSelectedLayoutSegments, useServerInsertedHTML };
|
|
826
|
+
export { GLOBAL_ACCESSORS_KEY, HTTP_ERROR_FALLBACK_ERROR_CODE, MAX_PREFETCH_CACHE_SIZE, PREFETCH_CACHE_TTL, ReadonlyURLSearchParams, RedirectType, ServerInsertedHTMLContext, __basePath, _registerStateAccessors, activateNavigationSnapshot, clearServerInsertedHTML, commitClientNavigationState, consumePrefetchResponse, createClientNavigationRenderSnapshot, flushServerInsertedHTML, forbidden, getAccessFallbackHTTPStatus, getClientNavigationRenderContext, getClientParams, getLayoutSegmentContext, getNavigationContext, getPrefetchCache, getPrefetchedUrls, isHTTPAccessFallbackError, navigateClientSide, notFound, permanentRedirect, prefetchRscResponse, pushHistoryStateWithoutNotify, redirect, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, restoreRscResponse, setClientParams, setNavigationContext, snapshotRscResponse, storePrefetchResponse, toRscUrl, unauthorized, useParams, usePathname, useRouter, useSearchParams, useSelectedLayoutSegment, useSelectedLayoutSegments, useServerInsertedHTML };
|
|
579
827
|
|
|
580
828
|
//# sourceMappingURL=navigation.js.map
|