vinext 1.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +93 -10
- package/dist/build/app-page-static-eligibility.d.ts +15 -0
- package/dist/build/app-page-static-eligibility.js +82 -0
- package/dist/build/client-build-config.d.ts +10 -0
- package/dist/build/client-build-config.js +18 -2
- package/dist/build/pages-client-assets-module.d.ts +8 -0
- package/dist/build/pages-client-assets-module.js +21 -1
- package/dist/build/prerender-paths.js +8 -81
- package/dist/build/prerender.js +33 -8
- package/dist/build/run-prerender.js +1 -1
- package/dist/build/server-manifest.d.ts +7 -0
- package/dist/build/server-manifest.js +11 -1
- package/dist/build/ssr-manifest.d.ts +2 -0
- package/dist/build/ssr-manifest.js +6 -2
- package/dist/cache/cache-adapters-virtual.d.ts +7 -1
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/check.js +7 -6
- package/dist/cli.js +2 -1
- package/dist/client/client-redirect-matcher.d.ts +14 -0
- package/dist/client/client-redirect-matcher.js +37 -0
- package/dist/client/client-redirects.d.ts +27 -0
- package/dist/client/client-redirects.js +28 -0
- package/dist/client/client-rewrites.d.ts +2 -1
- package/dist/client/client-rewrites.js +1 -1
- package/dist/client/navigation-runtime.d.ts +11 -0
- package/dist/client/navigation-runtime.js +1 -1
- package/dist/config/config-matchers.d.ts +26 -11
- package/dist/config/config-matchers.js +81 -82
- package/dist/config/destination-params.d.ts +47 -0
- package/dist/config/destination-params.js +116 -0
- package/dist/config/next-config.d.ts +14 -0
- package/dist/config/next-config.js +21 -3
- package/dist/entries/app-rsc-entry.d.ts +6 -0
- package/dist/entries/app-rsc-entry.js +84 -49
- package/dist/entries/pages-client-entry.js +3 -1
- package/dist/entries/pages-server-entry.js +13 -37
- package/dist/index.d.ts +7 -2
- package/dist/index.js +193 -73
- package/dist/init-cloudflare.d.ts +9 -0
- package/dist/init-cloudflare.js +107 -31
- package/dist/init-platform.d.ts +4 -0
- package/dist/init-platform.js +27 -2
- package/dist/init.d.ts +1 -0
- package/dist/init.js +67 -3
- package/dist/plugins/ast-scope.d.ts +7 -0
- package/dist/plugins/ast-scope.js +59 -3
- package/dist/plugins/cache-flight-codec.d.ts +19 -0
- package/dist/plugins/cache-flight-codec.js +68 -0
- package/dist/plugins/commonjs-esm-facade.d.ts +35 -0
- package/dist/plugins/commonjs-esm-facade.js +80 -0
- package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
- package/dist/plugins/dynamic-preload-metadata.js +9 -8
- package/dist/plugins/fonts.d.ts +8 -11
- package/dist/plugins/fonts.js +71 -34
- package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
- package/dist/plugins/ignore-dynamic-requests.js +3 -4
- package/dist/plugins/middleware-server-only.d.ts +5 -4
- package/dist/plugins/middleware-server-only.js +8 -5
- package/dist/plugins/pages-node-externals.js +1 -1
- package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
- package/dist/plugins/rsc-scan-glob-imports.js +50 -0
- package/dist/plugins/strip-server-exports.js +262 -98
- package/dist/plugins/transform-result.d.ts +9 -5
- package/dist/plugins/transitive-externals.js +1 -1
- package/dist/plugins/typeof-window.d.ts +2 -2
- package/dist/plugins/use-cache-callable.js +8 -2
- package/dist/plugins/worker-server-only-imports.d.ts +20 -0
- package/dist/plugins/worker-server-only-imports.js +31 -0
- package/dist/plugins/worker-use-server.d.ts +25 -0
- package/dist/plugins/worker-use-server.js +129 -0
- package/dist/routing/file-matcher.d.ts +1 -0
- package/dist/routing/file-matcher.js +1 -1
- package/dist/server/api-handler.d.ts +1 -0
- package/dist/server/api-handler.js +19 -8
- package/dist/server/app-browser-action-result.d.ts +1 -1
- package/dist/server/app-browser-action-result.js +9 -2
- package/dist/server/app-browser-entry.js +11 -7
- package/dist/server/app-browser-history-controller.d.ts +2 -0
- package/dist/server/app-browser-history-controller.js +8 -0
- package/dist/server/app-browser-interception-context.js +26 -2
- package/dist/server/app-browser-navigation-controller.d.ts +7 -1
- package/dist/server/app-browser-navigation-controller.js +94 -11
- package/dist/server/app-browser-server-action-client.js +1 -1
- package/dist/server/app-fallback-renderer.d.ts +2 -0
- package/dist/server/app-fallback-renderer.js +1 -0
- package/dist/server/app-history-state.d.ts +3 -0
- package/dist/server/app-history-state.js +7 -0
- package/dist/server/app-middleware.d.ts +11 -0
- package/dist/server/app-middleware.js +19 -3
- package/dist/server/app-optimistic-routing.js +1 -1
- package/dist/server/app-page-boundary-render.d.ts +5 -0
- package/dist/server/app-page-boundary-render.js +6 -4
- package/dist/server/app-page-cache-finalizer.d.ts +11 -0
- package/dist/server/app-page-cache-finalizer.js +41 -7
- package/dist/server/app-page-cache-render.d.ts +18 -0
- package/dist/server/app-page-cache-render.js +63 -43
- package/dist/server/app-page-cache.d.ts +6 -1
- package/dist/server/app-page-cache.js +28 -8
- package/dist/server/app-page-dispatch.d.ts +12 -2
- package/dist/server/app-page-dispatch.js +51 -33
- package/dist/server/app-page-element-builder.d.ts +7 -0
- package/dist/server/app-page-element-builder.js +27 -42
- package/dist/server/app-page-execution.d.ts +15 -12
- package/dist/server/app-page-execution.js +30 -40
- package/dist/server/app-page-head.d.ts +5 -0
- package/dist/server/app-page-head.js +9 -3
- package/dist/server/app-page-ppr-runtime.js +1 -1
- package/dist/server/app-page-probe.d.ts +0 -109
- package/dist/server/app-page-probe.js +3 -136
- package/dist/server/app-page-render-identity.d.ts +0 -1
- package/dist/server/app-page-render-identity.js +1 -1
- package/dist/server/app-page-render-observation.js +3 -3
- package/dist/server/app-page-render.d.ts +13 -5
- package/dist/server/app-page-render.js +219 -119
- package/dist/server/app-page-request.d.ts +0 -1
- package/dist/server/app-page-request.js +54 -17
- package/dist/server/app-page-response.d.ts +4 -3
- package/dist/server/app-page-response.js +4 -3
- package/dist/server/app-page-route-wiring.d.ts +17 -5
- package/dist/server/app-page-route-wiring.js +57 -35
- package/dist/server/app-page-rsc-render-status.d.ts +48 -0
- package/dist/server/app-page-rsc-render-status.js +54 -0
- package/dist/server/app-page-stream.d.ts +15 -8
- package/dist/server/app-page-stream.js +6 -0
- package/dist/server/app-pages-bridge.d.ts +1 -1
- package/dist/server/app-pages-bridge.js +2 -3
- package/dist/server/app-prerender-endpoints.js +9 -6
- package/dist/server/app-request-stage-dispatch.js +7 -3
- package/dist/server/app-request-stage-independent-entry.js +29 -9
- package/dist/server/app-response-header-provenance.d.ts +2 -0
- package/dist/server/app-response-header-provenance.js +10 -4
- package/dist/server/app-response-stage-entry.js +10 -2
- package/dist/server/app-route-handler-cache.d.ts +1 -0
- package/dist/server/app-route-handler-cache.js +1 -0
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +6 -3
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- package/dist/server/app-route-handler-execution.js +1 -0
- package/dist/server/app-route-handler-runtime.d.ts +4 -1
- package/dist/server/app-route-handler-runtime.js +45 -24
- package/dist/server/app-router-entry.js +27 -8
- package/dist/server/app-rsc-cache-busting.js +1 -1
- package/dist/server/app-rsc-errors.js +20 -16
- package/dist/server/app-rsc-handler.d.ts +11 -0
- package/dist/server/app-rsc-handler.js +291 -125
- package/dist/server/app-rsc-request-normalization.d.ts +3 -1
- package/dist/server/app-rsc-request-normalization.js +4 -2
- package/dist/server/app-rsc-response-stage.d.ts +1 -1
- package/dist/server/app-rsc-response-stage.js +10 -6
- package/dist/server/app-rsc-route-matching.d.ts +9 -1
- package/dist/server/app-rsc-route-matching.js +36 -19
- package/dist/server/app-segment-config.d.ts +2 -1
- package/dist/server/app-server-action-execution.d.ts +2 -1
- package/dist/server/app-server-action-execution.js +62 -23
- package/dist/server/app-ssr-entry.d.ts +3 -2
- package/dist/server/app-ssr-entry.js +8 -5
- package/dist/server/app-ssr-stream.d.ts +6 -1
- package/dist/server/app-ssr-stream.js +34 -15
- package/dist/server/app-worker-stages.d.ts +7 -2
- package/dist/server/app-worker-stages.js +4 -4
- package/dist/server/cacheability-request.js +11 -7
- package/dist/server/client-build-files.d.ts +16 -0
- package/dist/server/client-build-files.js +36 -0
- package/dist/server/client-reuse-manifest.js +1 -1
- package/dist/server/config-headers.js +2 -0
- package/dist/server/dev-server.js +50 -29
- package/dist/server/dev-stack-sourcemap.js +18 -23
- package/dist/server/document-initial-head.d.ts +0 -11
- package/dist/server/document-initial-head.js +1 -1
- package/dist/server/forwarded-middleware-context.d.ts +5 -0
- package/dist/server/forwarded-middleware-context.js +22 -0
- package/dist/server/headers.d.ts +18 -1
- package/dist/server/headers.js +19 -2
- package/dist/server/http-conditional.d.ts +11 -0
- package/dist/server/http-conditional.js +10 -1
- package/dist/server/http-error-responses.d.ts +1 -1
- package/dist/server/image-optimization.d.ts +54 -0
- package/dist/server/image-optimization.js +118 -9
- package/dist/server/isr-cache.d.ts +10 -0
- package/dist/server/isr-cache.js +43 -8
- package/dist/server/metadata-route-response.js +9 -8
- package/dist/server/middleware-matcher-pattern.js +8 -4
- package/dist/server/middleware-matcher.d.ts +2 -0
- package/dist/server/middleware-matcher.js +23 -2
- package/dist/server/middleware-response-headers.js +2 -0
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +33 -20
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.js +3 -1
- package/dist/server/multi-stage.d.ts +19 -0
- package/dist/server/navigation-planner.js +1 -1
- package/dist/server/node-response-signal.d.ts +16 -0
- package/dist/server/node-response-signal.js +26 -0
- package/dist/server/normalize-path.d.ts +0 -13
- package/dist/server/normalize-path.js +1 -34
- package/dist/server/open-redirect.d.ts +47 -0
- package/dist/server/open-redirect.js +74 -1
- package/dist/server/pages-api-route.d.ts +3 -2
- package/dist/server/pages-api-route.js +4 -3
- package/dist/server/pages-cache-tag.d.ts +12 -0
- package/dist/server/pages-cache-tag.js +19 -0
- package/dist/server/pages-client-assets.d.ts +2 -0
- package/dist/server/pages-data-route.d.ts +10 -0
- package/dist/server/pages-data-route.js +19 -2
- package/dist/server/pages-document-asset-props.d.ts +5 -1
- package/dist/server/pages-document-asset-props.js +13 -5
- package/dist/server/pages-document-splice.d.ts +19 -0
- package/dist/server/pages-document-splice.js +55 -0
- package/dist/server/pages-i18n.d.ts +12 -1
- package/dist/server/pages-i18n.js +18 -4
- package/dist/server/pages-node-compat.d.ts +16 -5
- package/dist/server/pages-node-compat.js +20 -12
- package/dist/server/pages-page-data.d.ts +32 -24
- package/dist/server/pages-page-data.js +50 -120
- package/dist/server/pages-page-handler.d.ts +0 -6
- package/dist/server/pages-page-handler.js +209 -130
- package/dist/server/pages-page-response.d.ts +12 -6
- package/dist/server/pages-page-response.js +41 -34
- package/dist/server/pages-request-pipeline.d.ts +10 -2
- package/dist/server/pages-request-pipeline.js +37 -18
- package/dist/server/pages-request-stage-entry.d.ts +6 -0
- package/dist/server/pages-request-stage-entry.js +79 -16
- package/dist/server/pages-response-stage-entry.js +4 -0
- package/dist/server/pages-revalidate.js +1 -1
- package/dist/server/pages-router-entry.js +4 -3
- package/dist/server/prerender-manifest.d.ts +3 -3
- package/dist/server/prerender-manifest.js +4 -3
- package/dist/server/prerender-work-unit-setup.js +4 -0
- package/dist/server/prod-server.d.ts +20 -7
- package/dist/server/prod-server.js +343 -129
- package/dist/server/proper-error.d.ts +4 -0
- package/dist/server/proper-error.js +31 -0
- package/dist/server/request-pipeline.d.ts +24 -9
- package/dist/server/request-pipeline.js +24 -9
- package/dist/server/response-compression.d.ts +43 -0
- package/dist/server/response-compression.js +111 -0
- package/dist/server/revalidation-request.d.ts +1 -0
- package/dist/server/revalidation-request.js +1 -1
- package/dist/server/rsc-stream-hints.js +31 -2
- package/dist/server/seed-cache.d.ts +1 -0
- package/dist/server/seed-cache.js +15 -11
- package/dist/server/server-reference-loader.d.ts +4 -0
- package/dist/server/server-reference-loader.js +29 -0
- package/dist/server/socket-error-backstop.d.ts +23 -1
- package/dist/server/socket-error-backstop.js +69 -17
- package/dist/server/static-file-signal.d.ts +15 -4
- package/dist/server/static-file-signal.js +46 -12
- package/dist/server/worker-image-optimization.d.ts +34 -0
- package/dist/server/worker-image-optimization.js +86 -0
- package/dist/server/worker-stages.d.ts +1 -1
- package/dist/server/worker-stages.js +2 -2
- package/dist/server/worker-utils.d.ts +8 -3
- package/dist/server/worker-utils.js +12 -7
- package/dist/shims/app-router-scroll.js +4 -1
- package/dist/shims/app-router-tree-context.d.ts +5 -0
- package/dist/shims/app-router-tree-context.js +27 -0
- package/dist/shims/cache-adapter-instantiate.d.ts +50 -0
- package/dist/shims/cache-adapter-instantiate.js +118 -0
- package/dist/shims/cache-callable-runtime.d.ts +6 -42
- package/dist/shims/cache-callable-runtime.js +65 -174
- package/dist/shims/cache-flight-arguments.d.ts +22 -0
- package/dist/shims/cache-flight-arguments.js +56 -0
- package/dist/shims/cache-handler.js +1 -9
- package/dist/shims/cache-request-state.d.ts +15 -0
- package/dist/shims/cache-request-state.js +31 -8
- package/dist/shims/cache-runtime.d.ts +12 -20
- package/dist/shims/cache-runtime.js +166 -225
- package/dist/shims/cache.d.ts +4 -4
- package/dist/shims/cache.js +44 -16
- package/dist/shims/cacheability-classification.d.ts +7 -0
- package/dist/shims/cdn-cache.d.ts +8 -0
- package/dist/shims/cdn-cache.js +17 -1
- package/dist/shims/disable-smooth-scroll.d.ts +3 -0
- package/dist/shims/disable-smooth-scroll.js +36 -0
- package/dist/shims/document-placeholders.d.ts +19 -0
- package/dist/shims/document-placeholders.js +45 -0
- package/dist/shims/document.js +21 -5
- package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
- package/dist/shims/dynamic-preload-chunks.js +13 -9
- package/dist/shims/dynamic.d.ts +1 -1
- package/dist/shims/dynamic.js +60 -8
- package/dist/shims/error-boundary-navigation.d.ts +7 -0
- package/dist/shims/error-boundary-navigation.js +19 -1
- package/dist/shims/error-boundary.d.ts +10 -10
- package/dist/shims/error-boundary.js +26 -7
- package/dist/shims/fetch-cache-state.d.ts +66 -0
- package/dist/shims/fetch-cache-state.js +92 -0
- package/dist/shims/fetch-cache.d.ts +3 -61
- package/dist/shims/fetch-cache.js +161 -108
- package/dist/shims/form.js +1 -1
- package/dist/shims/head.d.ts +10 -6
- package/dist/shims/head.js +15 -13
- package/dist/shims/headers.d.ts +13 -0
- package/dist/shims/headers.js +47 -4
- package/dist/shims/image.js +2 -1
- package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -2
- package/dist/shims/internal/app-page-props-cache-key.js +24 -15
- package/dist/shims/internal/headers-state.d.ts +0 -1
- package/dist/shims/internal/work-store-scope.d.ts +5 -0
- package/dist/shims/internal/work-store-scope.js +24 -0
- package/dist/shims/metadata.js +3 -3
- package/dist/shims/navigation-errors.d.ts +6 -0
- package/dist/shims/navigation-errors.js +11 -1
- package/dist/shims/navigation.d.ts +7 -0
- package/dist/shims/navigation.js +45 -9
- package/dist/shims/request-context.d.ts +11 -0
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/router.js +12 -20
- package/dist/shims/server.d.ts +16 -0
- package/dist/shims/server.js +24 -4
- package/dist/shims/thenable-params.d.ts +4 -0
- package/dist/shims/thenable-params.js +25 -3
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/shims/url-utils.d.ts +2 -0
- package/dist/shims/url-utils.js +3 -1
- package/dist/utils/client-runtime-metadata.js +1 -1
- package/dist/utils/hash.d.ts +7 -0
- package/dist/utils/hash.js +11 -1
- package/dist/utils/mdx-scan.d.ts +5 -0
- package/dist/utils/mdx-scan.js +8 -1
- package/dist/utils/package-name.d.ts +6 -0
- package/dist/utils/package-name.js +12 -1
- package/dist/utils/plugin-rsc-version.d.ts +4 -0
- package/dist/utils/plugin-rsc-version.js +15 -0
- package/dist/utils/prerender-output-paths.js +15 -4
- package/dist/utils/public-file-path.d.ts +10 -2
- package/dist/utils/public-file-path.js +13 -9
- package/dist/utils/public-routes.js +2 -2
- package/dist/utils/react-version.d.ts +3 -0
- package/dist/utils/react-version.js +1 -1
- package/dist/utils/regex-safety.d.ts +10 -0
- package/dist/utils/regex-safety.js +70 -18
- package/package.json +9 -5
package/dist/shims/cache.js
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import { getOrCreateAls } from "./internal/als-registry.js";
|
|
2
2
|
import { getRequestContext, isInsideUnifiedScope } from "./unified-request-context.js";
|
|
3
3
|
import { getRequestExecutionContext, runWithExecutionContext } from "./request-context.js";
|
|
4
|
+
import { isInsideWorkStoreScope } from "./internal/work-store-scope.js";
|
|
4
5
|
import { workUnitAsyncStorage } from "./internal/work-unit-async-storage.js";
|
|
5
6
|
import { getCdnCacheAdapter } from "./cdn-cache.js";
|
|
6
7
|
import { isStagedCacheabilityProbeActive } from "./cacheability-classification.js";
|
|
7
|
-
import { fnv1a64 } from "../utils/hash.js";
|
|
8
8
|
import { MemoryCacheHandler, NoOpCacheHandler, configureMemoryCacheHandler, getCacheHandler, getDataCacheHandler, registerDataCacheHandler, registerLazyDataCacheHandler, setCacheHandler, setDataCacheHandler } from "./cache-handler.js";
|
|
9
9
|
import { encodeCacheTag, encodeCacheTags } from "../utils/encode-cache-tag.js";
|
|
10
|
+
import { fnv1a64, sha256Hex } from "../utils/hash.js";
|
|
11
|
+
import { addCollectedRequestTags, getCurrentFetchSoftTags, runWithDetachedFetchObservations } from "./fetch-cache-state.js";
|
|
10
12
|
import { makeHangingPromise } from "./internal/make-hanging-promise.js";
|
|
11
13
|
import { getHeadersAccessPhase, markDynamicUsage } from "./internal/headers-state.js";
|
|
12
14
|
import { isDraftModeEnabled } from "./headers.js";
|
|
13
15
|
import { _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext } from "./internal/cache-context-accessor.js";
|
|
14
|
-
import { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
|
|
15
|
-
import { addCollectedRequestTags, getCurrentFetchSoftTags } from "./fetch-cache.js";
|
|
16
|
+
import { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, markActionRevalidation, recordUnstableCacheObservation, runWithDetachedCacheObservations, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
|
|
16
17
|
//#region src/shims/cache.ts
|
|
17
18
|
/**
|
|
18
19
|
* next/cache shim
|
|
@@ -322,6 +323,8 @@ const UNSTABLE_CACHE_KEY_PREFIX = "unstable_cache:v2";
|
|
|
322
323
|
* a direct import (avoiding circular dependencies).
|
|
323
324
|
*/
|
|
324
325
|
const _unstableCacheAls = getOrCreateAls("vinext.unstableCache.als");
|
|
326
|
+
const _useCacheContextAls = getOrCreateAls("vinext.cacheRuntime.contextAls");
|
|
327
|
+
const _unstableCacheCallbackAls = getOrCreateAls("vinext.unstableCache.callbackAls");
|
|
325
328
|
function serializeUnstableCacheResult(value) {
|
|
326
329
|
return JSON.stringify(value === void 0 ? { undef: true } : { v: value });
|
|
327
330
|
}
|
|
@@ -347,6 +350,18 @@ function tryDeserializeUnstableCacheResult(body) {
|
|
|
347
350
|
function isInsideUnstableCacheScope() {
|
|
348
351
|
return _unstableCacheAls.getStore() === true;
|
|
349
352
|
}
|
|
353
|
+
/**
|
|
354
|
+
* Whether an unstable_cache call is nested in another one's callback, as
|
|
355
|
+
* Next.js's `isNestedUnstableCache` decides: only where Next.js has a work
|
|
356
|
+
* store (not in Pages Router or outside a render), and only when the
|
|
357
|
+
* innermost cache scope is that callback rather than a "use cache" function
|
|
358
|
+
* it called.
|
|
359
|
+
* Source: https://github.com/vercel/next.js/blob/canary/packages/next/src/server/web/spec-extension/unstable-cache.ts
|
|
360
|
+
*/
|
|
361
|
+
function isNestedUnstableCacheCall() {
|
|
362
|
+
const callback = _unstableCacheCallbackAls.getStore();
|
|
363
|
+
return callback !== void 0 && callback.useCacheContext === _useCacheContextAls.getStore() && isInsideWorkStoreScope();
|
|
364
|
+
}
|
|
350
365
|
const _UNSTABLE_CACHE_PENDING_REVALIDATIONS_KEY = Symbol.for("vinext.unstableCache.pendingRevalidations");
|
|
351
366
|
function getPendingUnstableCacheRevalidations() {
|
|
352
367
|
const existing = _g[_UNSTABLE_CACHE_PENDING_REVALIDATIONS_KEY];
|
|
@@ -362,7 +377,7 @@ function waitUntilUnstableCacheRevalidation(promise) {
|
|
|
362
377
|
function scheduleUnstableCacheBackgroundRevalidation(cacheKey, refresh) {
|
|
363
378
|
const pending = getPendingUnstableCacheRevalidations();
|
|
364
379
|
if (pending.has(cacheKey)) return;
|
|
365
|
-
const trackedRevalidation =
|
|
380
|
+
const trackedRevalidation = runWithDetachedCacheObservations(() => runWithDetachedFetchObservations(() => _useCacheContextAls.exit(refresh))).then(() => void 0).catch((err) => {
|
|
366
381
|
console.error(`[vinext] unstable_cache background revalidation failed for ${cacheKey}:`, err);
|
|
367
382
|
}).finally(() => {
|
|
368
383
|
if (pending.get(cacheKey) === trackedRevalidation) pending.delete(cacheKey);
|
|
@@ -370,8 +385,10 @@ function scheduleUnstableCacheBackgroundRevalidation(cacheKey, refresh) {
|
|
|
370
385
|
pending.set(cacheKey, trackedRevalidation);
|
|
371
386
|
waitUntilUnstableCacheRevalidation(trackedRevalidation);
|
|
372
387
|
}
|
|
373
|
-
async function refreshUnstableCacheResult(fn, args, cacheKey, tags, revalidateSeconds) {
|
|
374
|
-
const
|
|
388
|
+
async function refreshUnstableCacheResult(fn, args, keyedArgs, cacheKey, tags, revalidateSeconds) {
|
|
389
|
+
const argsUnchanged = serializeArgsOrNull(args) === keyedArgs;
|
|
390
|
+
const result = await _unstableCacheAls.run(true, () => _unstableCacheCallbackAls.run({ useCacheContext: _useCacheContextAls.getStore() }, () => fn(...args)));
|
|
391
|
+
if (!argsUnchanged) return result;
|
|
375
392
|
const cacheValue = {
|
|
376
393
|
kind: "FETCH",
|
|
377
394
|
data: {
|
|
@@ -389,29 +406,40 @@ async function refreshUnstableCacheResult(fn, args, cacheKey, tags, revalidateSe
|
|
|
389
406
|
});
|
|
390
407
|
return result;
|
|
391
408
|
}
|
|
409
|
+
function serializeArgsOrNull(args) {
|
|
410
|
+
try {
|
|
411
|
+
return JSON.stringify(args);
|
|
412
|
+
} catch {
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
392
416
|
/**
|
|
393
417
|
* Wrap an async function with caching.
|
|
394
418
|
*
|
|
395
|
-
* Returns a new function that caches results. The cache key is
|
|
396
|
-
*
|
|
419
|
+
* Returns a new function that caches results. The cache key is a SHA-256
|
|
420
|
+
* digest of the callback source, keyParts and serialized arguments.
|
|
397
421
|
*/
|
|
398
422
|
function unstable_cache(fn, keyParts, options) {
|
|
399
|
-
|
|
423
|
+
if (typeof window !== "undefined") return function cached(...args) {
|
|
424
|
+
return fn.apply(this, args);
|
|
425
|
+
};
|
|
426
|
+
const fixedKey = JSON.stringify([fn.toString(), keyParts ?? null]);
|
|
400
427
|
const tags = encodeCacheTags(options?.tags ?? []);
|
|
401
428
|
const revalidateSeconds = options?.revalidate;
|
|
402
429
|
const cachedFn = async (...args) => {
|
|
403
|
-
const
|
|
404
|
-
const
|
|
430
|
+
const keyedArgs = JSON.stringify(args);
|
|
431
|
+
const invocationKey = `${fixedKey}${keyedArgs}`;
|
|
405
432
|
addCollectedRequestTags(tags);
|
|
406
433
|
recordUnstableCacheObservation({
|
|
407
434
|
kind: "unstable_cache",
|
|
408
|
-
keyHash: fnv1a64(
|
|
435
|
+
keyHash: fnv1a64(invocationKey),
|
|
409
436
|
revalidate: typeof revalidateSeconds === "number" ? revalidateSeconds : revalidateSeconds === false ? false : null,
|
|
410
437
|
tagCount: tags.length,
|
|
411
438
|
tagHash: tags.length > 0 ? fnv1a64(JSON.stringify(tags)) : null
|
|
412
439
|
});
|
|
440
|
+
const cacheKey = `${UNSTABLE_CACHE_KEY_PREFIX}:${await sha256Hex(invocationKey)}`;
|
|
413
441
|
const isDraftMode = isDraftModeEnabled();
|
|
414
|
-
if (!isDraftMode) {
|
|
442
|
+
if (!isDraftMode && !isNestedUnstableCacheCall()) {
|
|
415
443
|
const softTags = getCurrentFetchSoftTags();
|
|
416
444
|
const existing = _hasPendingRevalidatedTag([...tags, ...softTags]) ? null : await getDataCacheHandler().get(cacheKey, {
|
|
417
445
|
kind: "FETCH",
|
|
@@ -423,7 +451,7 @@ function unstable_cache(fn, keyParts, options) {
|
|
|
423
451
|
if (cached.ok) {
|
|
424
452
|
if (existing.cacheState === "stale") {
|
|
425
453
|
if (shouldServeStaleUnstableCacheEntry()) {
|
|
426
|
-
scheduleUnstableCacheBackgroundRevalidation(cacheKey, () => refreshUnstableCacheResult(fn, args, cacheKey, tags, revalidateSeconds));
|
|
454
|
+
scheduleUnstableCacheBackgroundRevalidation(cacheKey, () => refreshUnstableCacheResult(fn, args, keyedArgs, cacheKey, tags, revalidateSeconds));
|
|
427
455
|
return cached.value;
|
|
428
456
|
}
|
|
429
457
|
} else return cached.value;
|
|
@@ -431,9 +459,9 @@ function unstable_cache(fn, keyParts, options) {
|
|
|
431
459
|
}
|
|
432
460
|
}
|
|
433
461
|
if (isDraftMode) return await _unstableCacheAls.run(true, () => fn(...args));
|
|
434
|
-
return await refreshUnstableCacheResult(fn, args, cacheKey, tags, revalidateSeconds);
|
|
462
|
+
return await refreshUnstableCacheResult(fn, args, keyedArgs, cacheKey, tags, revalidateSeconds);
|
|
435
463
|
};
|
|
436
464
|
return cachedFn;
|
|
437
465
|
}
|
|
438
466
|
//#endregion
|
|
439
|
-
export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, MemoryCacheHandler, NoOpCacheHandler, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _recordUseCacheRootParamRead, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLife, cacheLifeProfiles, cacheTag, configureMemoryCacheHandler, getAndClearActionRevalidationKind, getCacheHandler, getDataCacheHandler, getRegisteredCacheContext, getRequestExecutionContext, io, isInsideUnstableCacheScope, markActionRevalidation, unstable_noStore as noStore, unstable_noStore, recordUnstableCacheObservation, refresh, registerDataCacheHandler, registerLazyDataCacheHandler, revalidatePath, revalidateTag, runWithExecutionContext, setCacheHandler, setDataCacheHandler, shouldServeStaleUnstableCacheEntry, unstable_cache, unstable_cacheLife, unstable_cacheTag, unstable_io, updateTag };
|
|
467
|
+
export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, MemoryCacheHandler, NoOpCacheHandler, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _recordUseCacheRootParamRead, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLife, cacheLifeProfiles, cacheTag, configureMemoryCacheHandler, getAndClearActionRevalidationKind, getCacheHandler, getDataCacheHandler, getRegisteredCacheContext, getRequestExecutionContext, io, isInsideUnstableCacheScope, markActionRevalidation, unstable_noStore as noStore, unstable_noStore, recordUnstableCacheObservation, refresh, registerDataCacheHandler, registerLazyDataCacheHandler, revalidatePath, revalidateTag, runWithDetachedCacheObservations, runWithExecutionContext, setCacheHandler, setDataCacheHandler, shouldServeStaleUnstableCacheEntry, unstable_cache, unstable_cacheLife, unstable_cacheTag, unstable_io, updateTag };
|
|
@@ -10,6 +10,13 @@ export type RouteCacheabilityOutcome = {
|
|
|
10
10
|
searchParamsUnread?: true;
|
|
11
11
|
/** A transient classification failure that may succeed on another bounded attempt. */
|
|
12
12
|
retryable?: true;
|
|
13
|
+
/**
|
|
14
|
+
* App page RSC: the status and headers that replace the streamed 200 of a
|
|
15
|
+
* render whose special error rejected its document's shell, once the
|
|
16
|
+
* response is complete.
|
|
17
|
+
*/
|
|
18
|
+
status?: number;
|
|
19
|
+
headers?: Readonly<Record<string, string>>;
|
|
13
20
|
tags?: readonly string[];
|
|
14
21
|
};
|
|
15
22
|
export type RouteCacheabilityState = {
|
|
@@ -54,6 +54,8 @@ export type CdnResponsePolicy = {
|
|
|
54
54
|
export declare function splitCacheControlDirectives(cacheControl: string): string[];
|
|
55
55
|
/** Whether a Cache-Control value contains an exact non-cacheable directive. */
|
|
56
56
|
export declare function isNonCacheableCacheControl(cacheControl: string, scope?: "shared" | "browser"): boolean;
|
|
57
|
+
/** Whether a request carries credentials a shared response cache must not capture. */
|
|
58
|
+
export declare function hasSharedCacheCredentials(headers: Headers): boolean;
|
|
57
59
|
/**
|
|
58
60
|
* The serving strategy for page-level ISR. Implement this to delegate
|
|
59
61
|
* page/route/image caching to a CDN edge instead of the origin store.
|
|
@@ -88,6 +90,12 @@ export type CdnCacheAdapter = {
|
|
|
88
90
|
deferCompletedPageResponseAdmission?(response: Response, complete: (response: Response) => Promise<Response>): Response | null;
|
|
89
91
|
/** Capture the full-route RSC side stream while admitting a completed HTML response. */
|
|
90
92
|
captureAppPageRscData?(rscData: Promise<ArrayBuffer>): void;
|
|
93
|
+
/**
|
|
94
|
+
* Whether this adapter sends the 304 for a Pages render whose If-None-Match
|
|
95
|
+
* matches. When it does, the render returns the page, so an adapter that
|
|
96
|
+
* stores completed responses stores the page rather than the 304.
|
|
97
|
+
*/
|
|
98
|
+
deferNotModifiedResponse?(): boolean;
|
|
91
99
|
/**
|
|
92
100
|
* Validate provider-specific request routing before the application handles
|
|
93
101
|
* the request. Returning a response short-circuits the request pipeline;
|
package/dist/shims/cdn-cache.js
CHANGED
|
@@ -31,6 +31,22 @@ function isNonCacheableCacheControl(cacheControl, scope = "shared") {
|
|
|
31
31
|
return name === "no-store" || equals === -1 && (name === "no-cache" || scope === "shared" && name === "private");
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Request headers that identify the caller. A shared response cache never
|
|
36
|
+
* admits a Route Handler or API response's own policy for a request carrying
|
|
37
|
+
* them, and never replays such a render to refill its data entries.
|
|
38
|
+
* `x-api-key` matches the fetch cache's credential headers.
|
|
39
|
+
*/
|
|
40
|
+
const SHARED_CACHE_CREDENTIAL_HEADERS = [
|
|
41
|
+
"authorization",
|
|
42
|
+
"cookie",
|
|
43
|
+
"proxy-authorization",
|
|
44
|
+
"x-api-key"
|
|
45
|
+
];
|
|
46
|
+
/** Whether a request carries credentials a shared response cache must not capture. */
|
|
47
|
+
function hasSharedCacheCredentials(headers) {
|
|
48
|
+
return SHARED_CACHE_CREDENTIAL_HEADERS.some((name) => headers.has(name));
|
|
49
|
+
}
|
|
34
50
|
const PENDING_DYNAMIC_CACHE_CONTROL = "no-store, must-revalidate";
|
|
35
51
|
/**
|
|
36
52
|
* Default origin-managed ISR strategy: store page artifacts in the data cache,
|
|
@@ -95,4 +111,4 @@ function getCdnCacheAdapter() {
|
|
|
95
111
|
return _defaultAdapter ??= new DefaultCdnCacheAdapter();
|
|
96
112
|
}
|
|
97
113
|
//#endregion
|
|
98
|
-
export { DefaultCdnCacheAdapter, getCdnCacheAdapter, isNonCacheableCacheControl, setCdnCacheAdapter, splitCacheControlDirectives };
|
|
114
|
+
export { DefaultCdnCacheAdapter, getCdnCacheAdapter, hasSharedCacheCredentials, isNonCacheableCacheControl, setCdnCacheAdapter, splitCacheControlDirectives };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/shims/disable-smooth-scroll.ts
|
|
2
|
+
/**
|
|
3
|
+
* Run a route-transition scroll with `scroll-behavior: auto` on `<html>`.
|
|
4
|
+
*
|
|
5
|
+
* Ported from Next.js:
|
|
6
|
+
* packages/next/src/shared/lib/router/utils/disable-smooth-scroll.ts
|
|
7
|
+
*
|
|
8
|
+
* Since Next.js 16 (vercel/next.js#84102) the override is opt-in: it only
|
|
9
|
+
* applies when the root element carries `data-scroll-behavior="smooth"`.
|
|
10
|
+
* Without the attribute, a page-level `scroll-behavior: smooth` is respected
|
|
11
|
+
* and route-change scrolls animate (development warns once about the missing
|
|
12
|
+
* opt-in). Hash-only navigations never use this helper, so in-page anchor
|
|
13
|
+
* jumps keep the smooth behavior.
|
|
14
|
+
*/
|
|
15
|
+
let warnedMissingDataScrollBehavior = false;
|
|
16
|
+
function disableSmoothScrollDuringRouteTransition(fn) {
|
|
17
|
+
const htmlElement = document.documentElement;
|
|
18
|
+
if (htmlElement.dataset.scrollBehavior !== "smooth") {
|
|
19
|
+
if (process.env.NODE_ENV === "development" && !warnedMissingDataScrollBehavior && getComputedStyle(htmlElement).scrollBehavior === "smooth") {
|
|
20
|
+
warnedMissingDataScrollBehavior = true;
|
|
21
|
+
console.warn("Detected `scroll-behavior: smooth` on the `<html>` element. To disable smooth scrolling during route transitions, add `data-scroll-behavior=\"smooth\"` to your <html> element. Learn more: https://nextjs.org/docs/messages/missing-data-scroll-behavior");
|
|
22
|
+
}
|
|
23
|
+
fn();
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const previousScrollBehavior = htmlElement.style.scrollBehavior;
|
|
27
|
+
htmlElement.style.scrollBehavior = "auto";
|
|
28
|
+
htmlElement.getClientRects();
|
|
29
|
+
try {
|
|
30
|
+
fn();
|
|
31
|
+
} finally {
|
|
32
|
+
htmlElement.style.scrollBehavior = previousScrollBehavior;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { disableSmoothScrollDuringRouteTransition };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
//#region src/shims/document-placeholders.d.ts
|
|
3
|
+
/** Attribute `<Head>` adds last on its opening tag. */
|
|
4
|
+
export declare const DOCUMENT_HEAD_OPEN_ATTRIBUTE = "data-vinext-head-open";
|
|
5
|
+
/** Attribute of the `<template>` `<Head>` renders as its last child. */
|
|
6
|
+
export declare const DOCUMENT_HEAD_CLOSE_ATTRIBUTE = "data-vinext-head-close";
|
|
7
|
+
export declare function createDocumentPlaceholderToken(): string;
|
|
8
|
+
export declare function withDocumentPlaceholders(element: React.ReactElement, token: string): React.ReactElement;
|
|
9
|
+
export declare function useDocumentPlaceholderToken(): string | null;
|
|
10
|
+
/**
|
|
11
|
+
* `<Main />`'s placeholder. Without a renderer-provided token (a Document
|
|
12
|
+
* rendered on its own, e.g. in tests) it falls back to a static comment.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getDocumentMainPlaceholder(token: string | null): string;
|
|
15
|
+
export declare function getDocumentScriptsPlaceholder(token: string | null): string;
|
|
16
|
+
/** The marker attribute on `<Head>`'s opening tag. */
|
|
17
|
+
export declare function getDocumentHeadOpenMarker(token: string): string;
|
|
18
|
+
export declare function getDocumentHeadCloseMarker(token: string): string;
|
|
19
|
+
//#endregion
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
//#region src/shims/document-placeholders.ts
|
|
3
|
+
/**
|
|
4
|
+
* Per-render placeholders for the Pages Router `next/document` shims.
|
|
5
|
+
*
|
|
6
|
+
* The renderers splice the page body, `next/head` output, asset tags and
|
|
7
|
+
* hydration scripts into the serialized custom Document. Each render provides
|
|
8
|
+
* a fresh random token, and `<Head>`, `<Main />` and `<NextScript />` mark
|
|
9
|
+
* their splice points with it. Nothing the Document renders, request data in
|
|
10
|
+
* raw `<script>` text included, can know the token, so nothing can be mistaken
|
|
11
|
+
* for a splice point.
|
|
12
|
+
*/
|
|
13
|
+
const DocumentPlaceholderContext = React.createContext(null);
|
|
14
|
+
/** Attribute `<Head>` adds last on its opening tag. */
|
|
15
|
+
const DOCUMENT_HEAD_OPEN_ATTRIBUTE = "data-vinext-head-open";
|
|
16
|
+
/** Attribute of the `<template>` `<Head>` renders as its last child. */
|
|
17
|
+
const DOCUMENT_HEAD_CLOSE_ATTRIBUTE = "data-vinext-head-close";
|
|
18
|
+
function createDocumentPlaceholderToken() {
|
|
19
|
+
return crypto.randomUUID();
|
|
20
|
+
}
|
|
21
|
+
function withDocumentPlaceholders(element, token) {
|
|
22
|
+
return React.createElement(DocumentPlaceholderContext.Provider, { value: token }, element);
|
|
23
|
+
}
|
|
24
|
+
function useDocumentPlaceholderToken() {
|
|
25
|
+
return React.useContext(DocumentPlaceholderContext);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* `<Main />`'s placeholder. Without a renderer-provided token (a Document
|
|
29
|
+
* rendered on its own, e.g. in tests) it falls back to a static comment.
|
|
30
|
+
*/
|
|
31
|
+
function getDocumentMainPlaceholder(token) {
|
|
32
|
+
return token ? `<!--__NEXT_MAIN__:${token}-->` : "<!-- __NEXT_MAIN__ -->";
|
|
33
|
+
}
|
|
34
|
+
function getDocumentScriptsPlaceholder(token) {
|
|
35
|
+
return token ? `<!--__NEXT_SCRIPTS__:${token}-->` : "<!-- __NEXT_SCRIPTS__ -->";
|
|
36
|
+
}
|
|
37
|
+
/** The marker attribute on `<Head>`'s opening tag. */
|
|
38
|
+
function getDocumentHeadOpenMarker(token) {
|
|
39
|
+
return ` ${DOCUMENT_HEAD_OPEN_ATTRIBUTE}="${token}"`;
|
|
40
|
+
}
|
|
41
|
+
function getDocumentHeadCloseMarker(token) {
|
|
42
|
+
return `<template ${DOCUMENT_HEAD_CLOSE_ATTRIBUTE}="${token}"></template>`;
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { DOCUMENT_HEAD_CLOSE_ATTRIBUTE, DOCUMENT_HEAD_OPEN_ATTRIBUTE, createDocumentPlaceholderToken, getDocumentHeadCloseMarker, getDocumentHeadOpenMarker, getDocumentMainPlaceholder, getDocumentScriptsPlaceholder, useDocumentPlaceholderToken, withDocumentPlaceholders };
|
package/dist/shims/document.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { safeJsonStringify } from "../server/html.js";
|
|
2
|
+
import { DOCUMENT_HEAD_CLOSE_ATTRIBUTE, DOCUMENT_HEAD_OPEN_ATTRIBUTE, getDocumentMainPlaceholder, getDocumentScriptsPlaceholder, useDocumentPlaceholderToken } from "./document-placeholders.js";
|
|
2
3
|
import React from "react";
|
|
3
4
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
4
5
|
//#region src/shims/document.tsx
|
|
@@ -47,7 +48,7 @@ var Head = class extends React.Component {
|
|
|
47
48
|
}
|
|
48
49
|
render() {
|
|
49
50
|
const { children, nonce, crossOrigin, ...props } = this.props;
|
|
50
|
-
return /* @__PURE__ */ jsx(
|
|
51
|
+
return /* @__PURE__ */ jsx(DocumentHeadElement, {
|
|
51
52
|
...props,
|
|
52
53
|
...nonce ? { [documentAssetMarkerAttributes.headNonce]: nonce } : {},
|
|
53
54
|
...crossOrigin ? { [documentAssetMarkerAttributes.headCrossOrigin]: crossOrigin } : {},
|
|
@@ -55,10 +56,19 @@ var Head = class extends React.Component {
|
|
|
55
56
|
});
|
|
56
57
|
}
|
|
57
58
|
};
|
|
59
|
+
function DocumentHeadElement({ children, ...props }) {
|
|
60
|
+
const token = useDocumentPlaceholderToken();
|
|
61
|
+
return /* @__PURE__ */ jsxs("head", {
|
|
62
|
+
...props,
|
|
63
|
+
...token ? { [DOCUMENT_HEAD_OPEN_ATTRIBUTE]: token } : {},
|
|
64
|
+
children: [children, token ? /* @__PURE__ */ jsx("template", { [DOCUMENT_HEAD_CLOSE_ATTRIBUTE]: token }) : null]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
58
67
|
function Main() {
|
|
68
|
+
const token = useDocumentPlaceholderToken();
|
|
59
69
|
return /* @__PURE__ */ jsx("div", {
|
|
60
70
|
id: "__next",
|
|
61
|
-
dangerouslySetInnerHTML: { __html:
|
|
71
|
+
dangerouslySetInnerHTML: { __html: getDocumentMainPlaceholder(token) }
|
|
62
72
|
});
|
|
63
73
|
}
|
|
64
74
|
var NextScript = class extends React.Component {
|
|
@@ -80,13 +90,19 @@ var NextScript = class extends React.Component {
|
|
|
80
90
|
}
|
|
81
91
|
render() {
|
|
82
92
|
const { nonce, crossOrigin } = this.props;
|
|
83
|
-
return /* @__PURE__ */ jsx(
|
|
93
|
+
return /* @__PURE__ */ jsx(NextScriptPlaceholder, {
|
|
84
94
|
...nonce ? { [documentAssetMarkerAttributes.scriptNonce]: nonce } : {},
|
|
85
|
-
...crossOrigin ? { [documentAssetMarkerAttributes.scriptCrossOrigin]: crossOrigin } : {}
|
|
86
|
-
dangerouslySetInnerHTML: { __html: "<!-- __NEXT_SCRIPTS__ -->" }
|
|
95
|
+
...crossOrigin ? { [documentAssetMarkerAttributes.scriptCrossOrigin]: crossOrigin } : {}
|
|
87
96
|
});
|
|
88
97
|
}
|
|
89
98
|
};
|
|
99
|
+
function NextScriptPlaceholder(props) {
|
|
100
|
+
const token = useDocumentPlaceholderToken();
|
|
101
|
+
return /* @__PURE__ */ jsx("span", {
|
|
102
|
+
...props,
|
|
103
|
+
dangerouslySetInnerHTML: { __html: getDocumentScriptsPlaceholder(token) }
|
|
104
|
+
});
|
|
105
|
+
}
|
|
90
106
|
var Document = class extends React.Component {
|
|
91
107
|
static getInitialProps(ctx) {
|
|
92
108
|
return ctx.defaultGetInitialProps(ctx);
|
|
@@ -2,5 +2,6 @@ import React from "react";
|
|
|
2
2
|
//#region src/shims/dynamic-preload-chunks.d.ts
|
|
3
3
|
export declare function DynamicPreloadChunks(props: {
|
|
4
4
|
moduleIds?: readonly string[];
|
|
5
|
+
assets: "styles" | "scripts";
|
|
5
6
|
}): React.FunctionComponentElement<React.FragmentProps> | null;
|
|
6
7
|
//#endregion
|
|
@@ -56,6 +56,7 @@ function DynamicPreloadChunks(props) {
|
|
|
56
56
|
for (const file of files) {
|
|
57
57
|
const assetHref = dynamicPreloadHref(file);
|
|
58
58
|
if (assetHref.endsWith(".css")) {
|
|
59
|
+
if (props.assets !== "styles") continue;
|
|
59
60
|
const href = appendAssetDeploymentIdQuery(assetHref);
|
|
60
61
|
if (initialStylesheetHrefs?.has(href)) continue;
|
|
61
62
|
preloadLinks.push(React.createElement("link", {
|
|
@@ -68,15 +69,18 @@ function DynamicPreloadChunks(props) {
|
|
|
68
69
|
}));
|
|
69
70
|
continue;
|
|
70
71
|
}
|
|
71
|
-
if (assetHref.endsWith(".js"))
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
72
|
+
if (assetHref.endsWith(".js")) {
|
|
73
|
+
if (props.assets !== "scripts") continue;
|
|
74
|
+
preloadLinks.push(React.createElement("link", {
|
|
75
|
+
key: assetHref,
|
|
76
|
+
rel: "modulepreload",
|
|
77
|
+
href: assetHref,
|
|
78
|
+
as: "script",
|
|
79
|
+
crossOrigin,
|
|
80
|
+
fetchPriority: "low",
|
|
81
|
+
nonce
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
80
84
|
}
|
|
81
85
|
return preloadLinks.length > 0 ? React.createElement(React.Fragment, null, ...preloadLinks) : null;
|
|
82
86
|
}
|
package/dist/shims/dynamic.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { DynamicOptions, DynamicOptionsLoadingProps, LoadableComponent, Loadable
|
|
|
4
4
|
type DynamicInput<P> = DynamicOptions<P> | Loader<P>;
|
|
5
5
|
/**
|
|
6
6
|
* Retained for the Pages Router render pipeline, which calls this before
|
|
7
|
-
* rendering. Dynamic imports now use React.lazy
|
|
7
|
+
* rendering. Dynamic imports now use React.lazy, so there is no
|
|
8
8
|
* separate preload work to await.
|
|
9
9
|
*/
|
|
10
10
|
export declare function flushPreloads(): Promise<void[]>;
|
package/dist/shims/dynamic.js
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
|
+
import { AppRouterTreeContext } from "./app-router-tree-context.js";
|
|
1
2
|
import { DynamicPreloadChunks } from "./dynamic-preload-chunks.js";
|
|
2
3
|
import React from "react";
|
|
3
4
|
//#region src/shims/dynamic.ts
|
|
4
5
|
/**
|
|
5
6
|
* next/dynamic shim
|
|
6
7
|
*
|
|
7
|
-
* SSR-safe dynamic imports. On the server, uses React.lazy
|
|
8
|
+
* SSR-safe dynamic imports. On the server, uses React.lazy so that
|
|
8
9
|
* renderToReadableStream suspends until the dynamically-imported component is
|
|
9
|
-
* available. On the client, also uses React.lazy for code splitting.
|
|
10
|
+
* available. On the client, also uses React.lazy for code splitting. As in
|
|
11
|
+
* the Next.js App Router, a Suspense boundary is added only for `ssr: false`
|
|
12
|
+
* or an explicit `loading` component. Other trees (Pages Router) keep it.
|
|
10
13
|
*
|
|
11
14
|
* Works in RSC, SSR, and client environments:
|
|
12
|
-
* - RSC: Uses React.lazy
|
|
15
|
+
* - RSC: Uses React.lazy (available in React 19.x react-server).
|
|
13
16
|
* Falls back to async component pattern if a future React version
|
|
14
17
|
* strips lazy from react-server.
|
|
15
|
-
* - SSR: React.lazy
|
|
16
|
-
* - Client: React.lazy
|
|
18
|
+
* - SSR: React.lazy (renderToReadableStream suspends)
|
|
19
|
+
* - Client: React.lazy (standard code splitting)
|
|
17
20
|
*
|
|
18
21
|
* Supports:
|
|
19
22
|
* - dynamic(import('./Component'))
|
|
@@ -115,8 +118,55 @@ function getDynamicErrorBoundary() {
|
|
|
115
118
|
}
|
|
116
119
|
const isServer = typeof window === "undefined";
|
|
117
120
|
/**
|
|
121
|
+
* Whether this dynamic() renders in an App Router tree. RSC renders the App
|
|
122
|
+
* Router only, and react-server has no context support. On the server, the
|
|
123
|
+
* App Router SSR entry marks its tree; in the browser, App Router documents
|
|
124
|
+
* set `window.next.appDir` before anything renders, which also covers
|
|
125
|
+
* separate client roots (e.g. a modal rendered with createRoot). Everything
|
|
126
|
+
* else (Pages Router pages, `pages/_document`, ad-hoc react-dom/server
|
|
127
|
+
* renders) keeps the boundary, since Pages next/dynamic is react-loadable,
|
|
128
|
+
* which never suspends.
|
|
129
|
+
*/
|
|
130
|
+
function useIsAppRouterTree() {
|
|
131
|
+
if (!isServer) return window.next?.appDir === true;
|
|
132
|
+
return AppRouterTreeContext ? React.use(AppRouterTreeContext) : true;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The element tree around an SSR-enabled dynamic() component. The client
|
|
136
|
+
* renders empty slots where the server renders the preload chunks, so both
|
|
137
|
+
* sides render the same shape and useId values inside the dynamic component
|
|
138
|
+
* match on hydration.
|
|
139
|
+
*
|
|
140
|
+
* Match Next.js App Router Loadable: the component only gets a Suspense
|
|
141
|
+
* boundary when it has a `loading` component. Without one, the lazy component
|
|
142
|
+
* suspends up to the nearest parent boundary, so the server shell waits for
|
|
143
|
+
* the import instead of flushing an empty boundary and streaming the
|
|
144
|
+
* component in after first paint. Other trees always get the boundary.
|
|
145
|
+
*
|
|
146
|
+
* React hoists the preload links out of place, but a hoisted <link> right
|
|
147
|
+
* after a text node leaves a `<!-- -->` separator behind. Next.js avoids it by
|
|
148
|
+
* hinting scripts with ReactDOM.preload(), which renders nothing. vinext
|
|
149
|
+
* renders real modulepreload links (preloadModule() drops the nonce and
|
|
150
|
+
* fetchPriority), so they go where text rarely precedes them: first inside the
|
|
151
|
+
* boundary, or after the content when there is no boundary (a component whose
|
|
152
|
+
* output ends in text still gets a separator after it). Stylesheets stay
|
|
153
|
+
* before the boundary: a precedence stylesheet inside it makes React outline
|
|
154
|
+
* the boundary even when its content is already resolved, and rendering them
|
|
155
|
+
* ahead of the content keeps their nonce when the content links the same CSS.
|
|
156
|
+
* A dynamic component with CSS right after text therefore still gets the
|
|
157
|
+
* separator.
|
|
158
|
+
*/
|
|
159
|
+
function createDynamicBoundary(fallback, content, preloadModuleIds, hasBoundary) {
|
|
160
|
+
const preloadChunks = (assets) => isServer ? React.createElement(DynamicPreloadChunks, {
|
|
161
|
+
moduleIds: preloadModuleIds,
|
|
162
|
+
assets
|
|
163
|
+
}) : null;
|
|
164
|
+
if (!hasBoundary) return React.createElement(React.Fragment, null, preloadChunks("styles"), content, preloadChunks("scripts"));
|
|
165
|
+
return React.createElement(React.Fragment, null, preloadChunks("styles"), React.createElement(React.Suspense, { fallback }, preloadChunks("scripts"), content));
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
118
168
|
* Retained for the Pages Router render pipeline, which calls this before
|
|
119
|
-
* rendering. Dynamic imports now use React.lazy
|
|
169
|
+
* rendering. Dynamic imports now use React.lazy, so there is no
|
|
120
170
|
* separate preload work to await.
|
|
121
171
|
*/
|
|
122
172
|
function flushPreloads() {
|
|
@@ -170,6 +220,7 @@ function dynamic(dynamicInput, options) {
|
|
|
170
220
|
}
|
|
171
221
|
const LazyServer = createLazyComponent(loader);
|
|
172
222
|
const ServerDynamic = (props) => {
|
|
223
|
+
const isAppRouterTree = useIsAppRouterTree();
|
|
173
224
|
const fallback = LoadingComponent ? React.createElement(LoadingComponent, createDynamicLoadingProps()) : null;
|
|
174
225
|
const lazyElement = createElementWithProps(LazyServer, props);
|
|
175
226
|
let content = lazyElement;
|
|
@@ -181,7 +232,7 @@ function dynamic(dynamicInput, options) {
|
|
|
181
232
|
resetKey: 0
|
|
182
233
|
}, lazyElement);
|
|
183
234
|
}
|
|
184
|
-
return
|
|
235
|
+
return createDynamicBoundary(fallback, content, preloadModuleIds, LoadingComponent != null || !isAppRouterTree);
|
|
185
236
|
};
|
|
186
237
|
ServerDynamic.displayName = "DynamicServer";
|
|
187
238
|
return ServerDynamic;
|
|
@@ -189,6 +240,7 @@ function dynamic(dynamicInput, options) {
|
|
|
189
240
|
const InitialLazyComponent = createLazyComponent(loader);
|
|
190
241
|
const ClientDynamic = (props) => {
|
|
191
242
|
const { LazyComponent, retry, retryKey } = useRetryableLazyComponent(loader, InitialLazyComponent);
|
|
243
|
+
const isAppRouterTree = useIsAppRouterTree();
|
|
192
244
|
const fallback = LoadingComponent ? React.createElement(LoadingComponent, createDynamicLoadingProps({ retry })) : null;
|
|
193
245
|
const lazyElement = createElementWithProps(LazyComponent, props);
|
|
194
246
|
let content = lazyElement;
|
|
@@ -200,7 +252,7 @@ function dynamic(dynamicInput, options) {
|
|
|
200
252
|
resetKey: retryKey
|
|
201
253
|
}, lazyElement);
|
|
202
254
|
}
|
|
203
|
-
return
|
|
255
|
+
return createDynamicBoundary(fallback, content, preloadModuleIds, LoadingComponent != null || !isAppRouterTree);
|
|
204
256
|
};
|
|
205
257
|
ClientDynamic.displayName = "DynamicClient";
|
|
206
258
|
return ClientDynamic;
|
|
@@ -2,4 +2,11 @@ import { AppRouterInstance } from "./internal/app-router-context.js";
|
|
|
2
2
|
//#region src/shims/error-boundary-navigation.d.ts
|
|
3
3
|
export declare function useErrorBoundaryPathname(): string;
|
|
4
4
|
export declare function useErrorBoundaryRouter(): AppRouterInstance;
|
|
5
|
+
/**
|
|
6
|
+
* Whether following a redirect() would refetch the URL the browser is at,
|
|
7
|
+
* which renders the same redirect again. As in the navigation planner, only the
|
|
8
|
+
* exact URL refreshes the page; any hash change, including removing the
|
|
9
|
+
* current hash, only scrolls.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isRedirectToCurrentUrl(redirect: string): boolean;
|
|
5
12
|
//#endregion
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { markPprFallbackShellDynamicBoundary } from "./ppr-fallback-shell.js";
|
|
3
3
|
import { AppRouterContext } from "./internal/app-router-context.js";
|
|
4
|
+
import { toCanonicalBrowserNavigationHref, toSameOriginAppPath } from "./url-utils.js";
|
|
4
5
|
import { getNavigationContext } from "./navigation-context-state.js";
|
|
5
6
|
import "./navigation-server.js";
|
|
6
7
|
import * as React$1 from "react";
|
|
@@ -8,6 +9,7 @@ import * as React$1 from "react";
|
|
|
8
9
|
const CLIENT_NAVIGATION_STATE_KEY = Symbol.for("vinext.clientNavigationState");
|
|
9
10
|
const CLIENT_NAVIGATION_RENDER_CONTEXT_KEY = Symbol.for("vinext.clientNavigationRenderContext");
|
|
10
11
|
const BASE_PATH = process.env.__NEXT_ROUTER_BASEPATH ?? "";
|
|
12
|
+
const TRAILING_SLASH = process.env.__VINEXT_TRAILING_SLASH === "true";
|
|
11
13
|
function getClientNavigationState() {
|
|
12
14
|
return globalThis[CLIENT_NAVIGATION_STATE_KEY];
|
|
13
15
|
}
|
|
@@ -40,5 +42,21 @@ function useErrorBoundaryRouter() {
|
|
|
40
42
|
if (router === null) throw new Error("invariant expected app router to be mounted");
|
|
41
43
|
return router;
|
|
42
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Whether following a redirect() would refetch the URL the browser is at,
|
|
47
|
+
* which renders the same redirect again. As in the navigation planner, only the
|
|
48
|
+
* exact URL refreshes the page; any hash change, including removing the
|
|
49
|
+
* current hash, only scrolls.
|
|
50
|
+
*/
|
|
51
|
+
function isRedirectToCurrentUrl(redirect) {
|
|
52
|
+
if (typeof window === "undefined") return false;
|
|
53
|
+
try {
|
|
54
|
+
const current = new URL(window.location.href);
|
|
55
|
+
const target = new URL(toCanonicalBrowserNavigationHref(toSameOriginAppPath(redirect, BASE_PATH) ?? redirect, current.href, BASE_PATH, TRAILING_SLASH), current.href);
|
|
56
|
+
return target.hash === current.hash && target.origin === current.origin && target.pathname === current.pathname && target.search === current.search;
|
|
57
|
+
} catch {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
43
61
|
//#endregion
|
|
44
|
-
export { useErrorBoundaryPathname, useErrorBoundaryRouter };
|
|
62
|
+
export { isRedirectToCurrentUrl, useErrorBoundaryPathname, useErrorBoundaryRouter };
|
|
@@ -29,6 +29,11 @@ type CapturedError = {
|
|
|
29
29
|
type RedirectBoundaryState = {
|
|
30
30
|
redirect: string | null;
|
|
31
31
|
redirectType: "push" | "replace" | null;
|
|
32
|
+
previousResetKey: string | null;
|
|
33
|
+
};
|
|
34
|
+
type RedirectBoundaryProps = {
|
|
35
|
+
children?: React.ReactNode;
|
|
36
|
+
resetKey?: string | null;
|
|
32
37
|
};
|
|
33
38
|
type ErrorBoundaryInnerProps = {
|
|
34
39
|
isImplicitRootErrorBoundary?: boolean;
|
|
@@ -39,18 +44,13 @@ export type ErrorBoundaryState = {
|
|
|
39
44
|
previousPathname: string | null;
|
|
40
45
|
previousResetKey: string | null;
|
|
41
46
|
};
|
|
42
|
-
export declare class RedirectErrorBoundary extends React.Component<{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
children?: React.ReactNode;
|
|
47
|
-
});
|
|
48
|
-
static getDerivedStateFromError(error: unknown): RedirectBoundaryState;
|
|
47
|
+
export declare class RedirectErrorBoundary extends React.Component<RedirectBoundaryProps, RedirectBoundaryState> {
|
|
48
|
+
constructor(props: RedirectBoundaryProps);
|
|
49
|
+
static getDerivedStateFromProps(props: RedirectBoundaryProps, state: RedirectBoundaryState): RedirectBoundaryState | null;
|
|
50
|
+
static getDerivedStateFromError(error: unknown): Omit<RedirectBoundaryState, "previousResetKey">;
|
|
49
51
|
render(): string | number | bigint | boolean | React.JSX.Element | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | Iterable<React.ReactNode> | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | React.ReactPortal | null | undefined> | null | undefined;
|
|
50
52
|
}
|
|
51
|
-
export declare function RedirectBoundary({ children }:
|
|
52
|
-
children?: React.ReactNode;
|
|
53
|
-
}): React.JSX.Element;
|
|
53
|
+
export declare function RedirectBoundary({ children, resetKey }: RedirectBoundaryProps): React.JSX.Element;
|
|
54
54
|
/**
|
|
55
55
|
* Generic ErrorBoundary used to wrap route segments with error.tsx.
|
|
56
56
|
* This must be a client component since error boundaries use
|