vinext 0.1.3 → 0.1.5

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.
Files changed (185) hide show
  1. package/dist/build/client-build-config.d.ts +11 -2
  2. package/dist/build/client-build-config.js +17 -6
  3. package/dist/build/css-url-assets.d.ts +1 -1
  4. package/dist/build/css-url-assets.js +9 -7
  5. package/dist/build/prerender.js +3 -1
  6. package/dist/cache/cache-adapters-virtual.js +1 -1
  7. package/dist/client/pages-router-link-navigation.d.ts +33 -7
  8. package/dist/client/pages-router-link-navigation.js +32 -2
  9. package/dist/client/vinext-next-data.js +2 -0
  10. package/dist/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +1 -1
  11. package/dist/config/config-matchers.d.ts +11 -1
  12. package/dist/config/config-matchers.js +14 -2
  13. package/dist/config/tsconfig-paths.js +14 -1
  14. package/dist/deploy.js +20 -13
  15. package/dist/entries/app-rsc-entry.js +27 -22
  16. package/dist/entries/pages-client-entry.js +14 -13
  17. package/dist/entries/pages-server-entry.js +8 -27
  18. package/dist/index.js +365 -147
  19. package/dist/plugins/css-data-url.js +30 -26
  20. package/dist/plugins/dynamic-preload-metadata.js +2 -4
  21. package/dist/plugins/extensionless-dynamic-import.js +27 -24
  22. package/dist/plugins/fonts.js +5 -4
  23. package/dist/plugins/import-meta-url.js +21 -15
  24. package/dist/plugins/instrumentation-client.js +1 -1
  25. package/dist/plugins/middleware-server-only.js +7 -6
  26. package/dist/plugins/og-assets.js +48 -46
  27. package/dist/plugins/optimize-imports.js +9 -3
  28. package/dist/plugins/remove-console.d.ts +7 -1
  29. package/dist/plugins/remove-console.js +4 -1
  30. package/dist/plugins/require-context.js +21 -20
  31. package/dist/plugins/strip-server-exports.d.ts +16 -8
  32. package/dist/plugins/strip-server-exports.js +496 -46
  33. package/dist/routing/app-route-graph.js +2 -2
  34. package/dist/server/app-bfcache-identity.d.ts +26 -0
  35. package/dist/server/app-bfcache-identity.js +127 -0
  36. package/dist/server/app-browser-action-result.js +1 -1
  37. package/dist/server/app-browser-entry.js +22 -12
  38. package/dist/server/app-browser-navigation-controller.d.ts +1 -1
  39. package/dist/server/app-browser-navigation-controller.js +1 -1
  40. package/dist/server/app-browser-state.d.ts +3 -22
  41. package/dist/server/app-browser-state.js +23 -139
  42. package/dist/server/app-browser-stream.js +1 -1
  43. package/dist/server/app-browser-visible-commit.d.ts +1 -1
  44. package/dist/server/app-browser-visible-commit.js +3 -2
  45. package/dist/server/app-fallback-renderer.d.ts +1 -1
  46. package/dist/server/app-layout-param-observation.d.ts +1 -1
  47. package/dist/server/app-layout-param-observation.js +1 -1
  48. package/dist/server/app-middleware.js +2 -1
  49. package/dist/server/app-page-boundary-render.d.ts +1 -1
  50. package/dist/server/app-page-boundary.js +1 -1
  51. package/dist/server/app-page-cache-finalizer.d.ts +62 -0
  52. package/dist/server/app-page-cache-finalizer.js +122 -0
  53. package/dist/server/app-page-cache-render.d.ts +2 -2
  54. package/dist/server/app-page-cache-render.js +1 -1
  55. package/dist/server/app-page-cache.d.ts +2 -53
  56. package/dist/server/app-page-cache.js +5 -131
  57. package/dist/server/app-page-dispatch.d.ts +2 -2
  58. package/dist/server/app-page-dispatch.js +10 -8
  59. package/dist/server/app-page-probe.js +3 -2
  60. package/dist/server/app-page-render-observation.js +2 -2
  61. package/dist/server/app-page-render.d.ts +3 -3
  62. package/dist/server/app-page-render.js +3 -2
  63. package/dist/server/app-page-stream.d.ts +2 -9
  64. package/dist/server/app-page-stream.js +1 -35
  65. package/dist/server/app-pages-bridge.d.ts +5 -1
  66. package/dist/server/app-pages-bridge.js +5 -13
  67. package/dist/server/app-request-context.d.ts +1 -2
  68. package/dist/server/app-request-context.js +2 -1
  69. package/dist/server/app-route-handler-dispatch.js +3 -2
  70. package/dist/server/app-route-handler-execution.d.ts +1 -1
  71. package/dist/server/app-route-handler-execution.js +1 -1
  72. package/dist/server/app-route-handler-response.d.ts +1 -1
  73. package/dist/server/app-router-entry.js +2 -1
  74. package/dist/server/app-rsc-handler.d.ts +3 -0
  75. package/dist/server/app-rsc-handler.js +73 -31
  76. package/dist/server/app-rsc-response-finalizer.js +1 -1
  77. package/dist/server/app-rsc-route-matching.js +6 -2
  78. package/dist/server/app-server-action-execution.d.ts +1 -1
  79. package/dist/server/app-server-action-execution.js +10 -6
  80. package/dist/server/app-ssr-entry.d.ts +1 -1
  81. package/dist/server/app-ssr-entry.js +12 -38
  82. package/dist/server/app-ssr-router-instance.d.ts +6 -0
  83. package/dist/server/app-ssr-router-instance.js +24 -0
  84. package/dist/server/app-ssr-stream.js +1 -1
  85. package/dist/server/artifact-compatibility.js +1 -1
  86. package/dist/server/before-interactive-head.d.ts +17 -0
  87. package/dist/server/before-interactive-head.js +35 -0
  88. package/dist/server/client-reuse-manifest.js +1 -1
  89. package/dist/server/csp.js +1 -4
  90. package/dist/server/defer-until-stream-consumed.d.ts +7 -0
  91. package/dist/server/defer-until-stream-consumed.js +34 -0
  92. package/dist/server/dev-server.js +82 -37
  93. package/dist/server/instrumentation.js +1 -1
  94. package/dist/server/isr-cache.d.ts +1 -1
  95. package/dist/server/isr-cache.js +1 -1
  96. package/dist/server/isr-decision.d.ts +1 -1
  97. package/dist/server/middleware-matcher.js +20 -9
  98. package/dist/server/middleware-runtime.d.ts +3 -4
  99. package/dist/server/middleware-runtime.js +4 -2
  100. package/dist/server/navigation-planner.d.ts +3 -12
  101. package/dist/server/navigation-planner.js +24 -0
  102. package/dist/server/navigation-trace.d.ts +2 -1
  103. package/dist/server/navigation-trace.js +1 -0
  104. package/dist/server/open-redirect.d.ts +12 -0
  105. package/dist/server/open-redirect.js +21 -0
  106. package/dist/server/operation-token.d.ts +40 -0
  107. package/dist/server/operation-token.js +85 -0
  108. package/dist/server/pages-data-route.d.ts +1 -1
  109. package/dist/server/pages-data-route.js +7 -4
  110. package/dist/server/pages-dev-module-url.d.ts +4 -0
  111. package/dist/server/pages-dev-module-url.js +15 -0
  112. package/dist/server/pages-document-initial-props.d.ts +4 -15
  113. package/dist/server/pages-document-initial-props.js +27 -56
  114. package/dist/server/pages-i18n.js +2 -2
  115. package/dist/server/pages-page-data.d.ts +1 -1
  116. package/dist/server/pages-page-data.js +3 -1
  117. package/dist/server/pages-page-handler.js +3 -1
  118. package/dist/server/pages-page-response.d.ts +3 -1
  119. package/dist/server/pages-page-response.js +6 -6
  120. package/dist/server/pages-readiness.js +1 -1
  121. package/dist/server/pages-request-pipeline.d.ts +7 -7
  122. package/dist/server/pages-request-pipeline.js +63 -21
  123. package/dist/server/prod-server.d.ts +3 -1
  124. package/dist/server/prod-server.js +43 -11
  125. package/dist/server/request-pipeline.d.ts +1 -24
  126. package/dist/server/request-pipeline.js +1 -33
  127. package/dist/server/seed-cache.d.ts +1 -1
  128. package/dist/server/static-file-cache.js +16 -4
  129. package/dist/shims/before-interactive-context.d.ts +14 -3
  130. package/dist/shims/cache-handler.d.ts +106 -0
  131. package/dist/shims/cache-handler.js +176 -0
  132. package/dist/shims/cache-request-state.d.ts +47 -0
  133. package/dist/shims/cache-request-state.js +126 -0
  134. package/dist/shims/cache-runtime.d.ts +2 -2
  135. package/dist/shims/cache-runtime.js +3 -14
  136. package/dist/shims/cache.d.ts +3 -231
  137. package/dist/shims/cache.js +17 -383
  138. package/dist/shims/cdn-cache.d.ts +1 -1
  139. package/dist/shims/cdn-cache.js +1 -1
  140. package/dist/shims/document.d.ts +15 -20
  141. package/dist/shims/document.js +5 -8
  142. package/dist/shims/error-boundary-navigation.d.ts +7 -0
  143. package/dist/shims/error-boundary-navigation.js +44 -0
  144. package/dist/shims/error-boundary.js +10 -8
  145. package/dist/shims/error.js +2 -1
  146. package/dist/shims/fetch-cache.js +1 -1
  147. package/dist/shims/form.js +1 -1
  148. package/dist/shims/image.js +74 -9
  149. package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -0
  150. package/dist/shims/internal/app-page-props-cache-key.js +16 -0
  151. package/dist/shims/internal/navigation-untracked.js +2 -1
  152. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +6 -7
  153. package/dist/shims/internal/pages-data-fetch-dedup.js +67 -14
  154. package/dist/shims/internal/pages-data-target.js +1 -1
  155. package/dist/shims/layout-segment-context.d.ts +1 -1
  156. package/dist/shims/layout-segment-context.js +2 -1
  157. package/dist/shims/link.js +38 -17
  158. package/dist/shims/metadata.js +4 -4
  159. package/dist/shims/navigation-context-state.d.ts +40 -0
  160. package/dist/shims/navigation-context-state.js +116 -0
  161. package/dist/shims/navigation-errors.d.ts +55 -0
  162. package/dist/shims/navigation-errors.js +110 -0
  163. package/dist/shims/navigation-server.d.ts +3 -0
  164. package/dist/shims/navigation-server.js +3 -0
  165. package/dist/shims/navigation-state.d.ts +1 -2
  166. package/dist/shims/navigation-state.js +2 -1
  167. package/dist/shims/navigation.d.ts +3 -291
  168. package/dist/shims/navigation.js +16 -445
  169. package/dist/shims/navigation.react-server.d.ts +2 -2
  170. package/dist/shims/navigation.react-server.js +3 -1
  171. package/dist/shims/request-state-types.d.ts +3 -3
  172. package/dist/shims/router.d.ts +6 -2
  173. package/dist/shims/router.js +99 -20
  174. package/dist/shims/script.js +9 -5
  175. package/dist/shims/slot.js +3 -1
  176. package/dist/shims/unified-request-context.d.ts +2 -2
  177. package/dist/utils/has-trailing-comma.d.ts +24 -0
  178. package/dist/utils/has-trailing-comma.js +62 -0
  179. package/dist/utils/text-stream.d.ts +1 -1
  180. package/dist/utils/text-stream.js +2 -2
  181. package/dist/utils/virtual-module.d.ts +5 -0
  182. package/dist/utils/virtual-module.js +0 -0
  183. package/dist/utils/vite-version.d.ts +12 -1
  184. package/dist/utils/vite-version.js +9 -1
  185. package/package.json +5 -1
@@ -1,7 +1,9 @@
1
1
  "use client";
2
- import { handleAppNavigationFailure } from "../client/app-nav-failure-handler.js";
3
- import { decodeRedirectError, isRedirectError, usePathname, useRouter } from "./navigation.js";
2
+ import { decodeRedirectError, isRedirectError } from "./navigation-errors.js";
3
+ import "./navigation-server.js";
4
+ import { useErrorBoundaryPathname, useErrorBoundaryRouter } from "./error-boundary-navigation.js";
4
5
  import DefaultGlobalError from "./default-global-error.js";
6
+ import { handleAppNavigationFailure } from "../client/app-nav-failure-handler.js";
5
7
  import { VINEXT_DEV_ERROR_RECOVERY_EVENT } from "../utils/dev-error-recovery-event.js";
6
8
  import { isNavigationSignalError } from "../utils/navigation-signal.js";
7
9
  import React from "react";
@@ -31,7 +33,7 @@ function removeDevErrorRecoveryListener(listener) {
31
33
  window.removeEventListener(VINEXT_DEV_ERROR_RECOVERY_EVENT, listener);
32
34
  }
33
35
  function HandleRedirect({ redirect, redirectType, reset }) {
34
- const router = useRouter();
36
+ const router = useErrorBoundaryRouter();
35
37
  React.useEffect(() => {
36
38
  React.startTransition(() => {
37
39
  if (redirectType === "push") router.push(redirect);
@@ -146,7 +148,7 @@ var ErrorBoundaryInner = class extends React.Component {
146
148
  };
147
149
  function ErrorBoundary({ fallback, children, resetKey }) {
148
150
  return /* @__PURE__ */ jsx(ErrorBoundaryInner, {
149
- pathname: usePathname(),
151
+ pathname: useErrorBoundaryPathname(),
150
152
  resetKey,
151
153
  fallback,
152
154
  children
@@ -154,7 +156,7 @@ function ErrorBoundary({ fallback, children, resetKey }) {
154
156
  }
155
157
  function GlobalErrorBoundary({ fallback, children }) {
156
158
  return /* @__PURE__ */ jsx(ErrorBoundaryInner, {
157
- pathname: usePathname(),
159
+ pathname: useErrorBoundaryPathname(),
158
160
  fallback,
159
161
  isImplicitRootErrorBoundary: fallback === DefaultGlobalError,
160
162
  children
@@ -208,7 +210,7 @@ var NotFoundBoundaryInner = class extends React.Component {
208
210
  */
209
211
  function NotFoundBoundary({ fallback, children, resetKey }) {
210
212
  return /* @__PURE__ */ jsx(NotFoundBoundaryInner, {
211
- pathname: usePathname(),
213
+ pathname: useErrorBoundaryPathname(),
212
214
  resetKey,
213
215
  fallback,
214
216
  children
@@ -249,7 +251,7 @@ var ForbiddenBoundaryInner = class extends React.Component {
249
251
  };
250
252
  function ForbiddenBoundary({ fallback, children, resetKey }) {
251
253
  return /* @__PURE__ */ jsx(ForbiddenBoundaryInner, {
252
- pathname: usePathname(),
254
+ pathname: useErrorBoundaryPathname(),
253
255
  resetKey,
254
256
  fallback,
255
257
  children
@@ -290,7 +292,7 @@ var UnauthorizedBoundaryInner = class extends React.Component {
290
292
  };
291
293
  function UnauthorizedBoundary({ fallback, children, resetKey }) {
292
294
  return /* @__PURE__ */ jsx(UnauthorizedBoundaryInner, {
293
- pathname: usePathname(),
295
+ pathname: useErrorBoundaryPathname(),
294
296
  resetKey,
295
297
  fallback,
296
298
  children
@@ -1,6 +1,7 @@
1
1
  import { AppRouterContext } from "./internal/app-router-context.js";
2
2
  import { RouterContext } from "./internal/router-context.js";
3
- import { isNextRouterError } from "./navigation.js";
3
+ import { isNextRouterError } from "./navigation-errors.js";
4
+ import "./navigation.js";
4
5
  import { useUntrackedPathname } from "./internal/navigation-untracked.js";
5
6
  import React from "react";
6
7
  //#region src/shims/error.tsx
@@ -1,9 +1,9 @@
1
1
  import { getOrCreateAls } from "./internal/als-registry.js";
2
2
  import { getRequestContext, isInsideUnifiedScope, runWithUnifiedStateMutation } from "./unified-request-context.js";
3
3
  import { getRequestExecutionContext } from "./request-context.js";
4
+ import { getDataCacheHandler } from "./cache-handler.js";
4
5
  import { markDynamicUsage } from "./headers.js";
5
6
  import { encodeCacheTags } from "../utils/encode-cache-tag.js";
6
- import { getDataCacheHandler } from "./cache.js";
7
7
  //#region src/shims/fetch-cache.ts
8
8
  /**
9
9
  * Extended fetch() with Next.js caching semantics.
@@ -4,8 +4,8 @@ import { isDangerousScheme } from "./url-safety.js";
4
4
  import { AppElementsWire } from "../server/app-elements-wire.js";
5
5
  import "../server/app-elements.js";
6
6
  import { toSameOriginPath, withBasePath } from "./url-utils.js";
7
- import { hasAppNavigationRuntime } from "../client/navigation-runtime.js";
8
7
  import { createRscRequestHeaders, createRscRequestUrl } from "../server/app-rsc-cache-busting.js";
8
+ import { hasAppNavigationRuntime } from "../client/navigation-runtime.js";
9
9
  import { getMountedSlotsHeader, getPrefetchInterceptionContext, getPrefetchedUrls, hasPrefetchCacheEntryForNavigation, navigateClientSide, prefetchRscResponse } from "./navigation.js";
10
10
  import { useMergedRef } from "./use-merged-ref.js";
11
11
  import { forwardRef, useActionState, useCallback, useEffect, useRef } from "react";
@@ -175,6 +175,13 @@ function sanitizeBlurDataURL(url) {
175
175
  function isRemoteUrl(src) {
176
176
  return src.startsWith("http://") || src.startsWith("https://") || src.startsWith("//");
177
177
  }
178
+ function isSvgUrl(src) {
179
+ try {
180
+ return new URL(src, "http://vinext.local").pathname.toLowerCase().endsWith(".svg");
181
+ } catch {
182
+ return false;
183
+ }
184
+ }
178
185
  function getFillStyle(style, backgroundStyle) {
179
186
  return {
180
187
  position: "absolute",
@@ -236,7 +243,7 @@ function generateSrcSet(src, originalWidth, quality = 75) {
236
243
  if (widths.length === 0) return `${imageOptimizationUrl(src, originalWidth, quality)} ${originalWidth}w`;
237
244
  return widths.map((w) => `${imageOptimizationUrl(src, w, quality)} ${w}w`).join(", ");
238
245
  }
239
- const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill, preload, priority, quality, placeholder, blurDataURL, loader, sizes, className, style, onLoad, onLoadingComplete, onError, unoptimized: _unoptimized, overrideSrc: _overrideSrc, loading, ...rest }, ref) {
246
+ const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill, preload, priority, quality, placeholder, blurDataURL, loader, sizes, className, style, onLoad, onLoadingComplete, onError, unoptimized: _unoptimized, overrideSrc, loading, ...rest }, ref) {
240
247
  const lastLoadedSrcRef = useRef(void 0);
241
248
  const lastErrorSrcRef = useRef(void 0);
242
249
  const didInsertRef = useRef(false);
@@ -319,6 +326,40 @@ const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill
319
326
  lastErrorSrcRef.current = src;
320
327
  markBlurComplete();
321
328
  } : void 0;
329
+ if (_unoptimized === true) {
330
+ const renderedSrc = overrideSrc || src;
331
+ const sanitizedBlur = imgBlurDataURL ? sanitizeBlurDataURL(imgBlurDataURL) : void 0;
332
+ const blurStyle = !blurComplete && placeholder === "blur" && sanitizedBlur ? {
333
+ backgroundImage: `url(${sanitizedBlur})`,
334
+ backgroundSize: "cover",
335
+ backgroundRepeat: "no-repeat",
336
+ backgroundPosition: "center"
337
+ } : void 0;
338
+ preloadImageResource({
339
+ shouldPreload,
340
+ src: renderedSrc,
341
+ fetchPriority: priorityFetchPriority
342
+ });
343
+ return /* @__PURE__ */ jsx("img", {
344
+ ref: mergedRef,
345
+ src: renderedSrc,
346
+ alt,
347
+ width: fill ? void 0 : imgWidth,
348
+ height: fill ? void 0 : imgHeight,
349
+ loading: imageLoading,
350
+ fetchPriority: priorityFetchPriority,
351
+ decoding: "async",
352
+ className,
353
+ "data-nimg": fill ? "fill" : "1",
354
+ onLoad: handleLoad,
355
+ onError: handleError,
356
+ style: fill ? getFillStyle(style, blurStyle) : {
357
+ ...blurStyle,
358
+ ...style
359
+ },
360
+ ...rest
361
+ });
362
+ }
322
363
  if (loader) {
323
364
  const resolvedSrc = loader({
324
365
  src,
@@ -364,11 +405,11 @@ const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill
364
405
  } : void 0;
365
406
  const bg = showBlur ? `url(${sanitizedBlur})` : void 0;
366
407
  if (fill) {
367
- const fillSizes = sizes ?? "100vw";
408
+ const imageSizes = sizes ?? "100vw";
368
409
  preloadImageResource({
369
410
  shouldPreload,
370
411
  src,
371
- sizes: fillSizes,
412
+ sizes: imageSizes,
372
413
  fetchPriority: priorityFetchPriority
373
414
  });
374
415
  return /* @__PURE__ */ jsx("img", {
@@ -378,7 +419,7 @@ const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill
378
419
  loading: imageLoading,
379
420
  fetchPriority: priorityFetchPriority,
380
421
  decoding: "async",
381
- sizes: fillSizes,
422
+ sizes: imageSizes,
382
423
  className,
383
424
  "data-nimg": "fill",
384
425
  onLoad: handleLoad,
@@ -414,8 +455,7 @@ const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill
414
455
  }
415
456
  }
416
457
  const imgQuality = quality ?? 75;
417
- const isSvg = src.endsWith(".svg");
418
- const skipOptimization = _unoptimized === true || isSvg && !__dangerouslyAllowSVG;
458
+ const skipOptimization = isSvgUrl(src) && !__dangerouslyAllowSVG;
419
459
  const srcSet = imgWidth && !fill && !skipOptimization ? generateSrcSet(src, imgWidth, imgQuality) : imgWidth && !fill ? RESPONSIVE_WIDTHS.filter((w) => w <= imgWidth * 2).map((w) => `${src} ${w}w`).join(", ") || `${src} ${imgWidth}w` : void 0;
420
460
  const optimizedSrc = skipOptimization ? src : imgWidth ? imageOptimizationUrl(src, imgWidth, imgQuality) : imageOptimizationUrl(src, RESPONSIVE_WIDTHS[0], imgQuality);
421
461
  const sanitizedLocalBlur = imgBlurDataURL ? sanitizeBlurDataURL(imgBlurDataURL) : void 0;
@@ -460,7 +500,7 @@ const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill
460
500
  * Returns the props that would be passed to the underlying <img> element.
461
501
  */
462
502
  function getImageProps(props) {
463
- const { src: srcProp, alt, width, height, fill, preload: _preload, priority, quality: _quality, placeholder, blurDataURL: blurDataURLProp, loader, sizes, className, style, onLoad: _onLoad, onLoadingComplete: _onLoadingComplete, unoptimized: _unoptimized, overrideSrc: _overrideSrc, loading, ...rest } = props;
503
+ const { src: srcProp, alt, width, height, fill, preload: _preload, priority, quality: _quality, placeholder, blurDataURL: blurDataURLProp, loader, sizes, className, style, onLoad: _onLoad, onLoadingComplete: _onLoadingComplete, unoptimized: _unoptimized, overrideSrc, loading, ...rest } = props;
464
504
  const { src, width: imgWidth, height: imgHeight, blurDataURL: imgBlurDataURL } = resolveImageSource({
465
505
  src: srcProp,
466
506
  width,
@@ -468,6 +508,32 @@ function getImageProps(props) {
468
508
  blurDataURL: blurDataURLProp
469
509
  });
470
510
  const shouldPreload = _preload === true || priority === true;
511
+ if (_unoptimized === true) {
512
+ const renderedSrc = overrideSrc || src;
513
+ const sanitizedBlurURL = imgBlurDataURL ? sanitizeBlurDataURL(imgBlurDataURL) : void 0;
514
+ const blurStyle = placeholder === "blur" && sanitizedBlurURL ? {
515
+ backgroundImage: `url(${sanitizedBlurURL})`,
516
+ backgroundSize: "cover",
517
+ backgroundRepeat: "no-repeat",
518
+ backgroundPosition: "center"
519
+ } : void 0;
520
+ return { props: {
521
+ src: renderedSrc,
522
+ alt,
523
+ width: fill ? void 0 : imgWidth,
524
+ height: fill ? void 0 : imgHeight,
525
+ loading: priority ? "eager" : shouldPreload ? loading : loading ?? "lazy",
526
+ fetchPriority: priority ? "high" : void 0,
527
+ decoding: "async",
528
+ className,
529
+ "data-nimg": fill ? "fill" : "1",
530
+ style: fill ? getFillStyle(style, blurStyle) : {
531
+ ...blurStyle,
532
+ ...style
533
+ },
534
+ ...rest
535
+ } };
536
+ }
471
537
  let blockedInProd = false;
472
538
  if (isRemoteUrl(src)) {
473
539
  const validation = validateRemoteUrl(src);
@@ -483,8 +549,7 @@ function getImageProps(props) {
483
549
  width: imgWidth ?? 0,
484
550
  quality: imgQuality
485
551
  }) : src;
486
- const isSvg = resolvedSrc.endsWith(".svg");
487
- const skipOpt = _unoptimized === true || isSvg && !__dangerouslyAllowSVG || blockedInProd || !!loader || isRemoteUrl(resolvedSrc);
552
+ const skipOpt = isSvgUrl(resolvedSrc) && !__dangerouslyAllowSVG || blockedInProd || !!loader || isRemoteUrl(resolvedSrc);
488
553
  const optimizedSrc = skipOpt ? resolvedSrc : imgWidth ? imageOptimizationUrl(resolvedSrc, imgWidth, imgQuality) : imageOptimizationUrl(resolvedSrc, RESPONSIVE_WIDTHS[0], imgQuality);
489
554
  const srcSet = imgWidth && !fill && !isRemoteUrl(resolvedSrc) && !loader && !skipOpt ? generateSrcSet(resolvedSrc, imgWidth, imgQuality) : void 0;
490
555
  const sanitizedBlurURL = imgBlurDataURL ? sanitizeBlurDataURL(imgBlurDataURL) : void 0;
@@ -0,0 +1,5 @@
1
+ //#region src/shims/internal/app-page-props-cache-key.d.ts
2
+ declare function markAppPagePropsForUseCache<T extends object>(props: T): T;
3
+ declare function isMarkedAppPagePropsObject(value: object): boolean;
4
+ //#endregion
5
+ export { isMarkedAppPagePropsObject, markAppPagePropsForUseCache };
@@ -0,0 +1,16 @@
1
+ //#region src/shims/internal/app-page-props-cache-key.ts
2
+ const APP_PAGE_PROPS_CACHE_KEY_MARKER = Symbol.for("vinext.appPagePropsCacheKeyMarker");
3
+ function markAppPagePropsForUseCache(props) {
4
+ Object.defineProperty(props, APP_PAGE_PROPS_CACHE_KEY_MARKER, {
5
+ configurable: false,
6
+ enumerable: false,
7
+ value: true,
8
+ writable: false
9
+ });
10
+ return props;
11
+ }
12
+ function isMarkedAppPagePropsObject(value) {
13
+ return Reflect.get(value, APP_PAGE_PROPS_CACHE_KEY_MARKER) === true;
14
+ }
15
+ //#endregion
16
+ export { isMarkedAppPagePropsObject, markAppPagePropsForUseCache };
@@ -1,5 +1,6 @@
1
+ import { getNavigationContext } from "../navigation-context-state.js";
1
2
  import { getPagesNavigationContext } from "./pages-router-accessor.js";
2
- import { getClientNavigationState, getNavigationContext, useClientNavigationRenderSnapshot } from "../navigation.js";
3
+ import { getClientNavigationState, useClientNavigationRenderSnapshot } from "../navigation.js";
3
4
  //#region src/shims/internal/navigation-untracked.ts
4
5
  /**
5
6
  * Internal navigation-untracked pathname hook.
@@ -24,19 +24,18 @@
24
24
  * directly by anyone, which keeps subsequent clones legal even after one
25
25
  * caller has consumed its copy.
26
26
  *
27
- * - No `AbortSignal` is honored at the shared layer. Each `Router.push` cycle
28
- * has its own AbortController that supersedes prior navigations via
29
- * `_navigationId`; aborting the shared fetch on behalf of one caller would
30
- * destroy the dedup gain for every other concurrent caller. Cancellation is
31
- * handled by the caller's `assertStillCurrent()` checkpoints after `await`,
32
- * not by abort propagation.
27
+ * - Each caller owns one waiter. Cancelling a waiter leaves the shared request
28
+ * alive while another waiter remains; cancelling the final waiter aborts the
29
+ * underlying fetch and evicts the entry immediately so a replacement caller
30
+ * can retry without joining a doomed request.
33
31
  *
34
32
  * - The map is module-scoped (one per realm). The Pages Router runs in the
35
33
  * browser only, so a single `Map` is sufficient.
36
34
  */
37
35
  /**
38
36
  * Dedupe a `fetch()` against the `_next/data` endpoint. Multiple concurrent
39
- * callers for the same `dataHref` share one underlying network request.
37
+ * callers for the same resolved URL and deployment ID share one underlying
38
+ * network request.
40
39
  *
41
40
  * Each call returns a freshly-cloned `Response` so consumers can read the
42
41
  * body independently. Once the in-flight Promise settles (resolve or reject)
@@ -1,3 +1,4 @@
1
+ import "../../utils/deployment-id.js";
1
2
  //#region src/shims/internal/pages-data-fetch-dedup.ts
2
3
  /**
3
4
  * In-flight request dedup for the Pages Router `/_next/data/<id>/<page>.json`
@@ -24,21 +25,57 @@
24
25
  * directly by anyone, which keeps subsequent clones legal even after one
25
26
  * caller has consumed its copy.
26
27
  *
27
- * - No `AbortSignal` is honored at the shared layer. Each `Router.push` cycle
28
- * has its own AbortController that supersedes prior navigations via
29
- * `_navigationId`; aborting the shared fetch on behalf of one caller would
30
- * destroy the dedup gain for every other concurrent caller. Cancellation is
31
- * handled by the caller's `assertStillCurrent()` checkpoints after `await`,
32
- * not by abort propagation.
28
+ * - Each caller owns one waiter. Cancelling a waiter leaves the shared request
29
+ * alive while another waiter remains; cancelling the final waiter aborts the
30
+ * underlying fetch and evicts the entry immediately so a replacement caller
31
+ * can retry without joining a doomed request.
33
32
  *
34
33
  * - The map is module-scoped (one per realm). The Pages Router runs in the
35
34
  * browser only, so a single `Map` is sufficient.
36
35
  */
37
- /** Inflight fetch promises keyed by the resolved data URL. */
36
+ /** Inflight fetch entries keyed by the resolved data request identity. */
38
37
  const inflight = /* @__PURE__ */ new Map();
38
+ function getInflightKey(dataHref, init) {
39
+ let resolvedHref = dataHref;
40
+ if (typeof window !== "undefined") try {
41
+ resolvedHref = new URL(dataHref, window.location.href).href;
42
+ } catch {}
43
+ const deploymentId = new Headers(init?.headers).get("x-deployment-id") ?? "";
44
+ return `${resolvedHref}\n${deploymentId}`;
45
+ }
46
+ function cloneSharedResponse(key, entry, signal) {
47
+ entry.waiters += 1;
48
+ return new Promise((resolve, reject) => {
49
+ let released = false;
50
+ const release = (cancelled) => {
51
+ if (released) return;
52
+ released = true;
53
+ entry.waiters -= 1;
54
+ if (cancelled && entry.waiters === 0 && !entry.settled) {
55
+ if (inflight.get(key) === entry) inflight.delete(key);
56
+ entry.controller.abort();
57
+ }
58
+ };
59
+ const abort = () => {
60
+ release(true);
61
+ reject(new DOMException("Aborted", "AbortError"));
62
+ };
63
+ signal?.addEventListener("abort", abort, { once: true });
64
+ entry.promise.then((response) => {
65
+ signal?.removeEventListener("abort", abort);
66
+ release(false);
67
+ resolve(response.clone());
68
+ }, (error) => {
69
+ signal?.removeEventListener("abort", abort);
70
+ release(false);
71
+ reject(error);
72
+ });
73
+ });
74
+ }
39
75
  /**
40
76
  * Dedupe a `fetch()` against the `_next/data` endpoint. Multiple concurrent
41
- * callers for the same `dataHref` share one underlying network request.
77
+ * callers for the same resolved URL and deployment ID share one underlying
78
+ * network request.
42
79
  *
43
80
  * Each call returns a freshly-cloned `Response` so consumers can read the
44
81
  * body independently. Once the in-flight Promise settles (resolve or reject)
@@ -48,20 +85,36 @@ const inflight = /* @__PURE__ */ new Map();
48
85
  * dropped on failure so the next navigation can retry.
49
86
  */
50
87
  function dedupedPagesDataFetch(dataHref, init) {
51
- let entry = inflight.get(dataHref);
88
+ const key = getInflightKey(dataHref, init);
89
+ const signal = init?.signal ?? void 0;
90
+ if (signal?.aborted) return Promise.reject(new DOMException("Aborted", "AbortError"));
91
+ let entry = inflight.get(key);
52
92
  if (!entry) {
53
- entry = fetch(dataHref, init).finally(() => {
54
- if (inflight.get(dataHref) === entry) inflight.delete(dataHref);
55
- });
56
- inflight.set(dataHref, entry);
93
+ const controller = new AbortController();
94
+ let currentEntry;
95
+ currentEntry = {
96
+ controller,
97
+ promise: fetch(dataHref, {
98
+ ...init,
99
+ signal: controller.signal
100
+ }).finally(() => {
101
+ currentEntry.settled = true;
102
+ if (inflight.get(key) === currentEntry) inflight.delete(key);
103
+ }),
104
+ settled: false,
105
+ waiters: 0
106
+ };
107
+ inflight.set(key, currentEntry);
108
+ entry = currentEntry;
57
109
  }
58
- return entry.then((res) => res.clone());
110
+ return cloneSharedResponse(key, entry, signal);
59
111
  }
60
112
  /**
61
113
  * Drop every cached in-flight entry. Intended for tests; production code
62
114
  * does not need to call this because entries self-evict on settle.
63
115
  */
64
116
  function clearPagesDataInflight() {
117
+ for (const entry of inflight.values()) entry.controller.abort();
65
118
  inflight.clear();
66
119
  }
67
120
  //#endregion
@@ -1,8 +1,8 @@
1
1
  import { stripBasePath } from "../../utils/base-path.js";
2
2
  import { getLocalePathPrefix } from "../../utils/domain-locale.js";
3
3
  import { buildPagesDataHref, matchPagesPattern } from "./pages-data-url.js";
4
- import { dedupedPagesDataFetch } from "./pages-data-fetch-dedup.js";
5
4
  import { NEXT_DEPLOYMENT_ID_HEADER, getDeploymentId } from "../../utils/deployment-id.js";
5
+ import { dedupedPagesDataFetch } from "./pages-data-fetch-dedup.js";
6
6
  //#region src/shims/internal/pages-data-target.ts
7
7
  /**
8
8
  * Shared decision helper for the Pages Router `/_next/data/<id>/<page>.json`
@@ -1,4 +1,4 @@
1
- import { SegmentMap } from "./navigation.js";
1
+ import { SegmentMap } from "./navigation-context-state.js";
2
2
  import { ReactNode } from "react";
3
3
 
4
4
  //#region src/shims/layout-segment-context.d.ts
@@ -1,5 +1,6 @@
1
1
  "use client";
2
- import { getLayoutSegmentContext } from "./navigation.js";
2
+ import { getLayoutSegmentContext } from "./navigation-context-state.js";
3
+ import "./navigation-server.js";
3
4
  import { createElement } from "react";
4
5
  //#region src/shims/layout-segment-context.tsx
5
6
  /**
@@ -14,10 +14,10 @@ import { markAppRouteDetectedOnPrefetch } from "./internal/app-route-detection.j
14
14
  import { isAbsoluteOrProtocolRelativeUrl, normalizePathTrailingSlash, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
15
15
  import { getCurrentBrowserLocale } from "./client-locale.js";
16
16
  import { getCurrentRoutePathnameForWarning } from "./internal/route-pattern-for-warning.js";
17
- import { getNavigationRuntime, hasAppNavigationRuntime, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
18
17
  import { createRscRequestHeaders, createRscRequestUrl, stripRscCacheBustingSearchParam, stripRscSuffix } from "../server/app-rsc-cache-busting.js";
18
+ import { getNavigationRuntime, hasAppNavigationRuntime, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
19
+ import { navigatePagesRouterLinkWithFallback, resolvePagesRouterQueryOnlyHref } from "../client/pages-router-link-navigation.js";
19
20
  import { getMountedSlotsHeader, getPrefetchCache, getPrefetchInterceptionContext, getPrefetchedUrls, hasPrefetchCacheEntryForNavigation, navigateClientSide, prefetchRscResponse } from "./navigation.js";
20
- import { navigatePagesRouterLink } from "../client/pages-router-link-navigation.js";
21
21
  import { getI18nContext } from "./i18n-context.js";
22
22
  import { canLinkIntentPrefetch, canLinkPrefetch, getLinkPrefetchHref } from "./link-prefetch.js";
23
23
  import { clearLinkForCurrentNavigation, notifyLinkNavigationStart, setLinkForCurrentNavigation } from "./internal/link-status-registry.js";
@@ -56,6 +56,19 @@ function resolveHref(href) {
56
56
  }
57
57
  return url;
58
58
  }
59
+ function resolvePagesQueryOnlyHref(href) {
60
+ if (!href.startsWith("?") || typeof window === "undefined") return href;
61
+ const pagesRouter = window.next?.appDir === true ? void 0 : window.next?.router;
62
+ return resolvePagesRouterQueryOnlyHref(href, {
63
+ asPath: pagesRouter && "reload" in pagesRouter && "asPath" in pagesRouter && typeof pagesRouter.asPath === "string" ? pagesRouter.asPath : void 0,
64
+ basePath: __basePath,
65
+ fallbackHref: window.location.href,
66
+ locales: window.__VINEXT_LOCALES__
67
+ });
68
+ }
69
+ function resolvePagesLinkNavigationHref(href, locale) {
70
+ return normalizePathTrailingSlash(applyLocaleToHref(resolvePagesQueryOnlyHref(href), locale), __trailingSlash);
71
+ }
59
72
  /**
60
73
  * Collapse repeated forward-slashes (and convert backslashes to forward-slashes)
61
74
  * in the path portion of a URL, preserving any query string.
@@ -493,7 +506,9 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
493
506
  navigateHref = localPath;
494
507
  }
495
508
  e.preventDefault();
496
- const absoluteFullHref = toBrowserNavigationHref(navigateHref, window.location.href, __basePath);
509
+ const hasAppNavigationRuntime = Boolean(getNavigationRuntime()?.functions.navigate);
510
+ const pagesNavigateHref = resolvedHref.startsWith("?") ? resolvePagesLinkNavigationHref(resolvedHref, locale) : navigateHref;
511
+ const absoluteFullHref = toBrowserNavigationHref(hasAppNavigationRuntime ? navigateHref : pagesNavigateHref, window.location.href, __basePath);
497
512
  if (onNavigate) try {
498
513
  const navUrl = new URL(absoluteFullHref, window.location.origin);
499
514
  let prevented = false;
@@ -509,12 +524,12 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
509
524
  onNavigate(navEvent);
510
525
  if (navEvent.defaultPrevented) return;
511
526
  } catch {}
512
- if (getNavigationRuntime()?.functions.navigate && ["pages", "document"].includes(resolveHybridClientRouteOwner(navigateHref, __basePath) ?? "")) {
527
+ if (hasAppNavigationRuntime && ["pages", "document"].includes(resolveHybridClientRouteOwner(navigateHref, __basePath) ?? "")) {
513
528
  if (replace) window.location.replace(absoluteFullHref);
514
529
  else window.location.assign(absoluteFullHref);
515
530
  return;
516
531
  }
517
- if (getNavigationRuntime()?.functions.navigate) {
532
+ if (hasAppNavigationRuntime) {
518
533
  const setter = setPendingRef.current;
519
534
  if (setter) setLinkForCurrentNavigation(setter);
520
535
  setPending(true);
@@ -525,19 +540,25 @@ const Link = forwardRef(function Link({ href, as, replace = false, prefetch: pre
525
540
  });
526
541
  });
527
542
  return;
528
- } else try {
529
- const Router = (await import("next/router.js")).default;
530
- await navigatePagesRouterLink(Router, {
531
- href: navigateHref,
532
- replace,
533
- scroll,
534
- shallow,
535
- locale
543
+ } else {
544
+ const Router = window.next?.appDir === true ? void 0 : window.next?.router;
545
+ await navigatePagesRouterLinkWithFallback({
546
+ router: Router && "reload" in Router ? Router : void 0,
547
+ loadRouter: async () => (await import("next/router.js")).default,
548
+ navigation: {
549
+ href: pagesNavigateHref,
550
+ replace,
551
+ scroll,
552
+ shallow,
553
+ locale,
554
+ interpolateDynamicRoute: resolvedHref.startsWith("?")
555
+ },
556
+ fallback: () => {
557
+ if (replace) window.history.replaceState({}, "", absoluteFullHref);
558
+ else window.history.pushState({}, "", absoluteFullHref);
559
+ window.dispatchEvent(new PopStateEvent("popstate"));
560
+ }
536
561
  });
537
- } catch {
538
- if (replace) window.history.replaceState({}, "", absoluteFullHref);
539
- else window.history.pushState({}, "", absoluteFullHref);
540
- window.dispatchEvent(new PopStateEvent("popstate"));
541
562
  }
542
563
  };
543
564
  const anchorProps = restWithoutLocale;
@@ -621,7 +621,7 @@ function MetadataHead({ metadata, pathname = "/", trailingSlash }) {
621
621
  }
622
622
  }
623
623
  }
624
- if (tw.players) {
624
+ if (tw.card === "player" && tw.players) {
625
625
  const players = Array.isArray(tw.players) ? tw.players : [tw.players];
626
626
  for (const player of players) {
627
627
  const playerUrl = player.playerUrl.toString();
@@ -644,7 +644,7 @@ function MetadataHead({ metadata, pathname = "/", trailingSlash }) {
644
644
  }, key++));
645
645
  }
646
646
  }
647
- if (tw.app) {
647
+ if (tw.card === "app" && tw.app) {
648
648
  const { app } = tw;
649
649
  for (const platform of [
650
650
  "iphone",
@@ -655,11 +655,11 @@ function MetadataHead({ metadata, pathname = "/", trailingSlash }) {
655
655
  name: `twitter:app:name:${platform}`,
656
656
  content: app.name
657
657
  }, key++));
658
- if (app.id[platform] !== void 0) elements.push(/* @__PURE__ */ jsx("meta", {
658
+ if (app.id[platform]) elements.push(/* @__PURE__ */ jsx("meta", {
659
659
  name: `twitter:app:id:${platform}`,
660
660
  content: String(app.id[platform])
661
661
  }, key++));
662
- if (app.url?.[platform] !== void 0) {
662
+ if (app.url?.[platform]) {
663
663
  const appUrl = app.url[platform].toString();
664
664
  elements.push(/* @__PURE__ */ jsx("meta", {
665
665
  name: `twitter:app:url:${platform}`,
@@ -0,0 +1,40 @@
1
+ import * as React$1 from "react";
2
+
3
+ //#region src/shims/navigation-context-state.d.ts
4
+ /**
5
+ * Map of parallel route key to child segments below the current layout.
6
+ * The "children" key is always present.
7
+ */
8
+ type SegmentMap = Readonly<Record<string, string[]>> & {
9
+ readonly children: string[];
10
+ };
11
+ type NavigationContext = {
12
+ pathname: string;
13
+ searchParams: URLSearchParams;
14
+ params: Record<string, string | string[]>;
15
+ };
16
+ declare const ServerInsertedHTMLContext: React$1.Context<((callback: () => unknown) => void) | null> | null;
17
+ declare function getLayoutSegmentContext(): React$1.Context<SegmentMap> | null;
18
+ declare function getBfcacheIdMapContext(): React$1.Context<Readonly<Record<string, string>> | null> | null;
19
+ declare function getBfcacheSegmentIdContext(): React$1.Context<string | null> | null;
20
+ type NavigationStateAccessors = {
21
+ getServerContext: () => NavigationContext | null;
22
+ setServerContext: (context: NavigationContext | null) => void;
23
+ getInsertedHTMLCallbacks: () => Array<() => unknown>;
24
+ clearInsertedHTMLCallbacks: () => void;
25
+ };
26
+ declare const GLOBAL_ACCESSORS_KEY: unique symbol;
27
+ declare function clearClientHydrationContext(): void;
28
+ /**
29
+ * Register request-scoped accessors supplied by navigation-state.ts.
30
+ * The global accessor key also bridges separate Vite module instances.
31
+ */
32
+ declare function _registerStateAccessors(accessors: NavigationStateAccessors): void;
33
+ declare function getNavigationContext(): NavigationContext | null;
34
+ declare function setNavigationContext(context: NavigationContext | null): void;
35
+ declare function registerServerInsertedHTMLCallback(callback: () => unknown): void;
36
+ declare function flushServerInsertedHTML(): unknown[];
37
+ declare function renderServerInsertedHTML(): unknown[];
38
+ declare function clearServerInsertedHTML(): void;
39
+ //#endregion
40
+ export { GLOBAL_ACCESSORS_KEY, NavigationContext, NavigationStateAccessors, SegmentMap, ServerInsertedHTMLContext, _registerStateAccessors, clearClientHydrationContext, clearServerInsertedHTML, flushServerInsertedHTML, getBfcacheIdMapContext, getBfcacheSegmentIdContext, getLayoutSegmentContext, getNavigationContext, registerServerInsertedHTMLCallback, renderServerInsertedHTML, setNavigationContext };