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
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CacheLifeConfig } from "./cache-request-state.js";
|
|
2
|
-
import {
|
|
2
|
+
import { CacheFlightArguments } from "./cache-flight-arguments.js";
|
|
3
3
|
//#region src/shims/cache-runtime.d.ts
|
|
4
|
+
export declare function replayCachedFunction(fn: object, args: CacheFlightArguments): Promise<unknown>;
|
|
4
5
|
/**
|
|
5
6
|
* Used purely as `cause` for the nested-dynamic cache error: its captured stack
|
|
6
7
|
* points at the inner "use cache" invocation that propagated a dynamic cache
|
|
@@ -52,15 +53,6 @@ export declare function getCacheContext(): CacheContext | null;
|
|
|
52
53
|
* Exported for testing.
|
|
53
54
|
*/
|
|
54
55
|
export declare function buildUseCacheKey(id: string, keySeed: string | undefined, argsKey?: string): string;
|
|
55
|
-
/**
|
|
56
|
-
* Convert an encodeReply result (string | FormData) to a cache key string.
|
|
57
|
-
* For FormData (binary args), produces a deterministic SHA-256 hash over
|
|
58
|
-
* the sorted entries. We can't hash `new Response(formData).arrayBuffer()`
|
|
59
|
-
* because multipart boundaries are non-deterministic across serializations.
|
|
60
|
-
*
|
|
61
|
-
* Exported for testing.
|
|
62
|
-
*/
|
|
63
|
-
export declare function replyToCacheKey(reply: string | FormData): Promise<string>;
|
|
64
56
|
export type PrivateCacheState = {
|
|
65
57
|
_privateCache: Map<string, unknown> | null;
|
|
66
58
|
};
|
|
@@ -85,8 +77,13 @@ export type RegisterCachedFunctionOptions = {
|
|
|
85
77
|
acceptsSecondArgument?: boolean;
|
|
86
78
|
/** Number of declared arguments supplied by the directive transform. */
|
|
87
79
|
argumentCount?: number;
|
|
88
|
-
|
|
89
|
-
|
|
80
|
+
/**
|
|
81
|
+
* Set only for an inline function that closes over values. It decrypts the
|
|
82
|
+
* capture envelope bound ahead of the call arguments and must reject any
|
|
83
|
+
* other first argument.
|
|
84
|
+
*/
|
|
85
|
+
decryptCaptures?: (value: unknown) => Promise<unknown[]>;
|
|
86
|
+
encodeInvocation?: (args: CacheFlightArguments) => Promise<string>;
|
|
90
87
|
serverReferenceId?: string;
|
|
91
88
|
};
|
|
92
89
|
/**
|
|
@@ -99,13 +96,8 @@ export type RegisterCachedFunctionOptions = {
|
|
|
99
96
|
* @returns A wrapper function that checks cache before calling the original
|
|
100
97
|
*/
|
|
101
98
|
export declare function registerCachedFunction<TArgs extends unknown[], TResult>(fn: (...args: TArgs) => Promise<TResult>, id: string, variant?: string, options?: RegisterCachedFunctionOptions): (...args: TArgs) => Promise<TResult>;
|
|
99
|
+
/** Memoize in one React render without skipping cache guards or scoped serialization. */
|
|
100
|
+
export declare function memoizeInCacheScope<TArgs extends unknown[], TResult>(fn: (...args: TArgs) => TResult): (...args: TArgs) => TResult;
|
|
102
101
|
/** Whether a loaded server reference is a transformed `"use cache"` function. */
|
|
103
102
|
export declare function isUseCacheFunction(value: unknown): value is (...args: unknown[]) => Promise<unknown>;
|
|
104
|
-
|
|
105
|
-
* A thenable (not an array) with own enumerable properties — the
|
|
106
|
-
* `Object.assign(Promise.resolve(obj), obj)` pattern Next.js params use. The
|
|
107
|
-
* cache key is built from its fields instead of the promise.
|
|
108
|
-
*/
|
|
109
|
-
export declare function isThenableObject(value: object): value is PromiseLike<unknown>;
|
|
110
|
-
//#endregion
|
|
111
|
-
export { markAppPagePropsForUseCache };
|
|
103
|
+
//#endregion
|
|
@@ -4,16 +4,19 @@ import { VINEXT_RSC_MARKER_HEADER } from "../server/headers.js";
|
|
|
4
4
|
import { workUnitAsyncStorage } from "./internal/work-unit-async-storage.js";
|
|
5
5
|
import { isRouteCacheabilityProbe, recordRouteCacheabilityProbeBailout } from "./cacheability-classification.js";
|
|
6
6
|
import { getDataCacheHandler } from "./cache-handler.js";
|
|
7
|
+
import { addCollectedRequestTags, getCurrentFetchSoftTags, runWithDetachedFetchObservations } from "./fetch-cache-state.js";
|
|
7
8
|
import { suppressHangingPromiseAbortRejections } from "./internal/make-hanging-promise.js";
|
|
8
9
|
import { createPprFallbackShellSuspensePromise, trackPprFallbackShellCacheTask } from "./ppr-fallback-shell.js";
|
|
9
10
|
import { markDynamicUsage, throwIfInsideCacheScope } from "./internal/headers-state.js";
|
|
10
11
|
import { isDraftModeEnabled } from "./headers.js";
|
|
11
12
|
import { _registerCacheContextAccessor } from "./internal/cache-context-accessor.js";
|
|
12
|
-
import { _hasPendingRevalidatedTag, _setRequestScopedCacheLife, cacheLifeProfiles } from "./cache-request-state.js";
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
13
|
+
import { _hasPendingRevalidatedTag, _setRequestScopedCacheLife, cacheLifeProfiles, runWithDetachedCacheObservations, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
|
|
14
|
+
import "./fetch-cache.js";
|
|
15
|
+
import { hasUseCacheLayoutMarker, hasUseCachePageMarker, isUseCacheFunctionReference, withoutUseCacheSegmentMarker } from "./internal/app-page-props-cache-key.js";
|
|
16
|
+
import { getFallbackParamsSnapshot, makeThenableParams, restoreThenableParams } from "./thenable-params.js";
|
|
16
17
|
import { getCurrentRootParams } from "./root-params.js";
|
|
18
|
+
import { flightArgumentsKey, restoreFlightReply, snapshotFlightReply } from "./cache-flight-arguments.js";
|
|
19
|
+
import { cache } from "react";
|
|
17
20
|
//#region src/shims/cache-runtime.ts
|
|
18
21
|
/**
|
|
19
22
|
* "use cache" runtime
|
|
@@ -36,14 +39,17 @@ import { getCurrentRootParams } from "./root-params.js";
|
|
|
36
39
|
* and all RSC-serializable types — unlike JSON.stringify which silently
|
|
37
40
|
* drops $$typeof Symbols and function values.
|
|
38
41
|
*
|
|
39
|
-
* When RSC APIs are unavailable (e.g. in unit tests), falls back to
|
|
40
|
-
* JSON.stringify/parse with the same stableStringify cache key generation.
|
|
41
|
-
*
|
|
42
42
|
* Cache variants:
|
|
43
43
|
* - "use cache" — shared cache (default profile)
|
|
44
44
|
* - "use cache: remote" — shared cache (explicit)
|
|
45
45
|
* - "use cache: private" — per-request cache (not shared across requests)
|
|
46
46
|
*/
|
|
47
|
+
const replayableFunctions = /* @__PURE__ */ new WeakMap();
|
|
48
|
+
function replayCachedFunction(fn, args) {
|
|
49
|
+
const replay = replayableFunctions.get(fn);
|
|
50
|
+
if (!replay || args.version !== 1) throw new Error("Invalid cache function arguments");
|
|
51
|
+
return replay(args);
|
|
52
|
+
}
|
|
47
53
|
/** Threshold below which expire is considered "dynamic" (5 minutes in seconds). */
|
|
48
54
|
const DYNAMIC_EXPIRE = 300;
|
|
49
55
|
/**
|
|
@@ -124,16 +130,9 @@ function buildUseCacheKey(id, keySeed, argsKey) {
|
|
|
124
130
|
const scopedId = keySeed ? `build:${encodeURIComponent(keySeed)}:${id}` : id;
|
|
125
131
|
return argsKey === void 0 ? `use-cache:${scopedId}` : `use-cache:${scopedId}:${argsKey}`;
|
|
126
132
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (_rscModule !== NOT_LOADED) return _rscModule;
|
|
131
|
-
try {
|
|
132
|
-
_rscModule = await import("@vitejs/plugin-rsc/react/rsc");
|
|
133
|
-
} catch {
|
|
134
|
-
_rscModule = null;
|
|
135
|
-
}
|
|
136
|
-
return _rscModule;
|
|
133
|
+
let _rscModule;
|
|
134
|
+
function getRscModule() {
|
|
135
|
+
return _rscModule ??= import("@vitejs/plugin-rsc/react/rsc");
|
|
137
136
|
}
|
|
138
137
|
/** Collect a ReadableStream<Uint8Array> into a single Uint8Array. */
|
|
139
138
|
async function collectStream(stream) {
|
|
@@ -171,55 +170,22 @@ function uint8ToStream(bytes) {
|
|
|
171
170
|
} });
|
|
172
171
|
}
|
|
173
172
|
async function serializeCacheResult(result, rsc) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
throw serializationError?.value ?? error;
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
const body = JSON.stringify(result);
|
|
193
|
-
return body === void 0 ? null : {
|
|
194
|
-
result,
|
|
195
|
-
cacheEntry: {
|
|
196
|
-
body,
|
|
197
|
-
headers: {}
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Convert an encodeReply result (string | FormData) to a cache key string.
|
|
203
|
-
* For FormData (binary args), produces a deterministic SHA-256 hash over
|
|
204
|
-
* the sorted entries. We can't hash `new Response(formData).arrayBuffer()`
|
|
205
|
-
* because multipart boundaries are non-deterministic across serializations.
|
|
206
|
-
*
|
|
207
|
-
* Exported for testing.
|
|
208
|
-
*/
|
|
209
|
-
async function replyToCacheKey(reply) {
|
|
210
|
-
if (typeof reply === "string") return reply;
|
|
211
|
-
const entries = [...reply.entries()];
|
|
212
|
-
const valStr = (v) => typeof v === "string" ? v : v.name;
|
|
213
|
-
entries.sort((a, b) => a[0].localeCompare(b[0]) || valStr(a[1]).localeCompare(valStr(b[1])));
|
|
214
|
-
const parts = [];
|
|
215
|
-
for (const [name, value] of entries) if (typeof value === "string") parts.push(`${name}=s:${value}`);
|
|
216
|
-
else {
|
|
217
|
-
const bytes = new Uint8Array(await value.arrayBuffer());
|
|
218
|
-
parts.push(`${name}=b:${value.type}:${value.size}:${Buffer.from(bytes).toString("base64")}`);
|
|
173
|
+
let serializationError;
|
|
174
|
+
const [returnStream, savedStream] = rsc.renderToReadableStream(result, { onError(error) {
|
|
175
|
+
serializationError ??= { value: error };
|
|
176
|
+
} }).tee();
|
|
177
|
+
try {
|
|
178
|
+
const [deserializedResult, bytes] = await Promise.all([rsc.createFromReadableStream(returnStream, {}, { preserveServerReferences: true }), collectStream(savedStream)]);
|
|
179
|
+
return {
|
|
180
|
+
result: deserializedResult,
|
|
181
|
+
cacheEntry: serializationError ? null : {
|
|
182
|
+
body: uint8ToBase64(bytes),
|
|
183
|
+
headers: { [VINEXT_RSC_MARKER_HEADER]: "1" }
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
} catch (error) {
|
|
187
|
+
throw serializationError?.value ?? error;
|
|
219
188
|
}
|
|
220
|
-
const payload = new TextEncoder().encode(parts.join("\0"));
|
|
221
|
-
const hashBuffer = await crypto.subtle.digest("SHA-256", payload);
|
|
222
|
-
return Buffer.from(new Uint8Array(hashBuffer)).toString("base64url");
|
|
223
189
|
}
|
|
224
190
|
/**
|
|
225
191
|
* Resolve collected cacheLife configs into a single effective config.
|
|
@@ -301,6 +267,17 @@ function propagateRootParamNamesToParent(names) {
|
|
|
301
267
|
if (!parent || parent.variant === "private") return;
|
|
302
268
|
for (const name of names) parent.readRootParamNames?.add(name);
|
|
303
269
|
}
|
|
270
|
+
function isServableCacheState(cacheState) {
|
|
271
|
+
if (cacheState === "expired") return false;
|
|
272
|
+
if (cacheState !== "stale") return true;
|
|
273
|
+
return shouldServeStaleUnstableCacheEntry() && process.env.VINEXT_PRERENDER !== "1" && !isRouteCacheabilityProbe();
|
|
274
|
+
}
|
|
275
|
+
function regenerateInBackground(id, regenerate) {
|
|
276
|
+
const regeneration = runWithDetachedCacheObservations(() => runWithDetachedFetchObservations(() => cacheContextStorage.exit(regenerate))).then(() => void 0, (error) => {
|
|
277
|
+
console.error(`[vinext] use cache: background regeneration failed for ${id}:`, error);
|
|
278
|
+
});
|
|
279
|
+
if (isInsideUnifiedScope()) getRequestContext().executionContext?.waitUntil(regeneration);
|
|
280
|
+
}
|
|
304
281
|
/**
|
|
305
282
|
* Register a function as a cached function. This is called by the Vite
|
|
306
283
|
* transform for each "use cache" function.
|
|
@@ -315,7 +292,7 @@ function registerCachedFunction(fn, id, variant, options = {}) {
|
|
|
315
292
|
const omitAppPageSearchParams = cacheVariant !== "private";
|
|
316
293
|
const cacheFunctionId = options.serverReferenceId ? JSON.stringify([id, options.serverReferenceId]) : id;
|
|
317
294
|
const isDev = typeof process !== "undefined" && process.env.NODE_ENV === "development";
|
|
318
|
-
const
|
|
295
|
+
const invoke = (args, replay) => {
|
|
319
296
|
if (cacheVariant === "private") {
|
|
320
297
|
const parentCtx = cacheContextStorage.getStore();
|
|
321
298
|
if (parentCtx && parentCtx.variant !== "private") throwPrivateUseCacheInsidePublicUseCacheError();
|
|
@@ -346,40 +323,60 @@ function registerCachedFunction(fn, id, variant, options = {}) {
|
|
|
346
323
|
}
|
|
347
324
|
}
|
|
348
325
|
return trackPprFallbackShellCacheTask(async () => {
|
|
349
|
-
const
|
|
326
|
+
const codec = await getRscModule();
|
|
327
|
+
const clientReferences = codec.createClientTemporaryReferenceSet();
|
|
328
|
+
const serverReferences = codec.createTemporaryReferenceSet();
|
|
329
|
+
const rsc = {
|
|
330
|
+
...codec,
|
|
331
|
+
renderToReadableStream: (value, options) => codec.renderToReadableStream(value, {
|
|
332
|
+
...options,
|
|
333
|
+
temporaryReferences: serverReferences
|
|
334
|
+
}),
|
|
335
|
+
createFromReadableStream: (stream, options, context) => codec.createFromReadableStream(stream, {
|
|
336
|
+
...options,
|
|
337
|
+
temporaryReferences: clientReferences
|
|
338
|
+
}, context)
|
|
339
|
+
};
|
|
350
340
|
const keySeed = getUseCacheKeySeed();
|
|
351
|
-
const captures = options.decryptCaptures ? await options.decryptCaptures(args[0]) : void 0;
|
|
341
|
+
const captures = !replay && options.decryptCaptures ? await options.decryptCaptures(args[0]) : void 0;
|
|
352
342
|
const hasCaptureEnvelope = captures !== void 0;
|
|
353
|
-
const
|
|
343
|
+
const limitedArgs = options.argumentCount === void 0 ? args : hasCaptureEnvelope ? [args[0], ...args.slice(1, 1 + options.argumentCount)] : args.slice(0, options.argumentCount);
|
|
344
|
+
const pagePropsArgIndex = replay?.pagePropsIndex ?? limitedArgs.findIndex(hasUseCachePageMarker);
|
|
345
|
+
const layoutPropsArgIndex = replay?.layoutPropsIndex ?? limitedArgs.findIndex(hasUseCacheLayoutMarker);
|
|
354
346
|
const isPageInvocation = pagePropsArgIndex !== -1;
|
|
355
|
-
const
|
|
356
|
-
const admittedArgs =
|
|
347
|
+
const segmentPropsIndex = isPageInvocation ? pagePropsArgIndex : layoutPropsArgIndex;
|
|
348
|
+
const admittedArgs = segmentPropsIndex !== -1 && !replay ? replaceArgument(limitedArgs, segmentPropsIndex, withoutUseCacheSegmentMarker(limitedArgs[segmentPropsIndex], isPageInvocation)) : limitedArgs;
|
|
357
349
|
const executionArgs = hasCaptureEnvelope ? [captures, ...admittedArgs.slice(1)] : admittedArgs;
|
|
350
|
+
const outerParams = !replay && segmentPropsIndex !== -1 ? executionArgs[segmentPropsIndex].params : void 0;
|
|
351
|
+
const fallbackParams = getFallbackParamsSnapshot(outerParams);
|
|
352
|
+
const serializationArgs = fallbackParams ? replaceArgument(executionArgs, segmentPropsIndex, {
|
|
353
|
+
...executionArgs[segmentPropsIndex],
|
|
354
|
+
params: fallbackParams
|
|
355
|
+
}) : executionArgs;
|
|
358
356
|
const pagePropsIndex = omitAppPageSearchParams && isPageInvocation ? pagePropsArgIndex : void 0;
|
|
359
|
-
const
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
const argsKey = processedArgs.length > 0 ? stableStringify(processedArgs) : void 0;
|
|
372
|
-
cacheKey = buildUseCacheKey(cacheFunctionId, keySeed, argsKey);
|
|
373
|
-
}
|
|
374
|
-
} catch {
|
|
375
|
-
return (await executeWithContext(fn, callArgs, cacheVariant)).result;
|
|
357
|
+
const keyArgs = pagePropsIndex === void 0 ? serializationArgs : toReplayablePageArgs(serializationArgs, pagePropsIndex);
|
|
358
|
+
const flightArguments = replay ?? await snapshotFlightReply(await rsc.encodeReply(keyArgs, { temporaryReferences: clientReferences }), isPageInvocation ? pagePropsArgIndex : void 0);
|
|
359
|
+
if (!replay && layoutPropsArgIndex !== -1) flightArguments.layoutPropsIndex = layoutPropsArgIndex;
|
|
360
|
+
let cacheKey = buildUseCacheKey(cacheFunctionId, keySeed, flightArgumentsKey(flightArguments));
|
|
361
|
+
let callArgs = await rsc.decodeReply(restoreFlightReply(flightArguments), { temporaryReferences: serverReferences });
|
|
362
|
+
if (segmentPropsIndex !== -1) {
|
|
363
|
+
const props = callArgs[segmentPropsIndex];
|
|
364
|
+
callArgs = replaceArgument(callArgs, segmentPropsIndex, {
|
|
365
|
+
...props,
|
|
366
|
+
params: restoreThenableParams(await props.params, outerParams)
|
|
367
|
+
});
|
|
368
|
+
if (pagePropsIndex !== void 0) callArgs = withErroringPageSearchParams(callArgs, pagePropsIndex);
|
|
376
369
|
}
|
|
370
|
+
if (fallbackParams) return (await executeWithContext(fn, callArgs, cacheVariant, rsc)).result;
|
|
377
371
|
if (cacheVariant === "private") {
|
|
378
372
|
const privateCache = _getPrivateState()._privateCache;
|
|
379
373
|
const privateHit = privateCache.get(cacheKey);
|
|
380
|
-
if (privateHit !== void 0)
|
|
374
|
+
if (privateHit !== void 0) {
|
|
375
|
+
if (privateHit.serialized) return rsc.createFromReadableStream(uint8ToStream(base64ToUint8(privateHit.serialized.body)), {}, { preserveServerReferences: true });
|
|
376
|
+
return privateHit.result;
|
|
377
|
+
}
|
|
381
378
|
const execution = await executeWithContext(fn, callArgs, cacheVariant, rsc);
|
|
382
|
-
if (execution.cacheable) privateCache.set(cacheKey, execution
|
|
379
|
+
if (execution.cacheable) privateCache.set(cacheKey, execution);
|
|
383
380
|
return execution.result;
|
|
384
381
|
}
|
|
385
382
|
if (isDev || isDraftModeEnabled()) return (await executeWithContext(fn, callArgs, cacheVariant, rsc)).result;
|
|
@@ -399,7 +396,7 @@ function registerCachedFunction(fn, id, variant, options = {}) {
|
|
|
399
396
|
console.error("[vinext] use cache: handler.get failed; treating as a cache miss:", error);
|
|
400
397
|
}
|
|
401
398
|
const redirectValue = existing?.value;
|
|
402
|
-
if (isRootParamRedirect(existing) && existing?.cacheState
|
|
399
|
+
if (isRootParamRedirect(existing) && isServableCacheState(existing?.cacheState) && rootParams && redirectValue?.kind === "FETCH" && !_hasPendingRevalidatedTag([...redirectValue.tags ?? [], ...softTags])) {
|
|
403
400
|
cacheKey = coarseCacheKey + computeRootParamsCacheKeySuffix(rootParams, addKnownRootParamNames(id, rootParamNamesFromTags(redirectValue.tags)));
|
|
404
401
|
try {
|
|
405
402
|
existing = await handler.get(cacheKey, {
|
|
@@ -411,78 +408,80 @@ function registerCachedFunction(fn, id, variant, options = {}) {
|
|
|
411
408
|
existing = null;
|
|
412
409
|
}
|
|
413
410
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
if (
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
recordRequestScopedCacheControl(existing.cacheControl);
|
|
421
|
-
return result;
|
|
411
|
+
const generate = async (propagate) => {
|
|
412
|
+
const { result, ctx, effectiveLife, collectedResult } = await runCachedFunctionWithContext(fn, callArgs, cacheVariant, (value) => serializeCacheResult(value, rsc));
|
|
413
|
+
const rootParamNames = ctx.readRootParamNames && ctx.readRootParamNames.size > 0 ? addKnownRootParamNames(id, ctx.readRootParamNames) : knownRootParamsByFunctionId.get(id);
|
|
414
|
+
if (propagate) {
|
|
415
|
+
recordRequestScopedCacheLife(effectiveLife);
|
|
416
|
+
propagateCacheTagsToRequest(ctx.tags);
|
|
422
417
|
}
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
encryptedArgs: await options.encodeInvocationArgs(pagePropsIndex === void 0 ? admittedArgs : toReplayablePageArgs(admittedArgs, pagePropsIndex)),
|
|
437
|
-
referenceId: options.serverReferenceId,
|
|
438
|
-
rootParams: Object.fromEntries(Object.entries(rootParams ?? {}).filter((entry) => entry[1] !== void 0)),
|
|
439
|
-
softTags
|
|
440
|
-
};
|
|
441
|
-
} catch {}
|
|
442
|
-
const serialized = collectedResult.cacheEntry;
|
|
443
|
-
const cacheValue = {
|
|
444
|
-
kind: "FETCH",
|
|
445
|
-
data: {
|
|
446
|
-
headers: serialized.headers,
|
|
447
|
-
body: serialized.body,
|
|
448
|
-
url: cacheKey
|
|
449
|
-
},
|
|
450
|
-
tags: ctx.tags,
|
|
451
|
-
revalidate: revalidateSeconds
|
|
452
|
-
};
|
|
453
|
-
const cacheContext = {
|
|
454
|
-
fetchCache: true,
|
|
455
|
-
tags: ctx.tags,
|
|
456
|
-
...cacheFunctionInvocation ? { cacheFunctionInvocation } : {},
|
|
457
|
-
cacheControl: {
|
|
458
|
-
revalidate: revalidateSeconds,
|
|
459
|
-
expire: effectiveLife.expire,
|
|
460
|
-
stale: effectiveLife.stale
|
|
461
|
-
}
|
|
462
|
-
};
|
|
463
|
-
if (rootParamNames && rootParamNames.size > 0 && rootParams) {
|
|
464
|
-
const specificCacheKey = coarseCacheKey + computeRootParamsCacheKeySuffix(rootParams, rootParamNames);
|
|
465
|
-
const redirectTags = [...ctx.tags, ...[...rootParamNames].map((name) => ROOT_PARAM_TAG_PREFIX + name)];
|
|
466
|
-
await handler.set(coarseCacheKey, {
|
|
418
|
+
const revalidateSeconds = effectiveLife.revalidate ?? cacheLifeProfiles.default.revalidate ?? 900;
|
|
419
|
+
if (collectedResult?.cacheEntry) try {
|
|
420
|
+
let cacheFunctionInvocation;
|
|
421
|
+
if (options.serverReferenceId && options.encodeInvocation) try {
|
|
422
|
+
cacheFunctionInvocation = {
|
|
423
|
+
encryptedArgs: await options.encodeInvocation(flightArguments),
|
|
424
|
+
referenceId: options.serverReferenceId,
|
|
425
|
+
rootParams: Object.fromEntries(Object.entries(rootParams ?? {}).filter((entry) => entry[1] !== void 0)),
|
|
426
|
+
softTags
|
|
427
|
+
};
|
|
428
|
+
} catch {}
|
|
429
|
+
const serialized = collectedResult.cacheEntry;
|
|
430
|
+
const cacheValue = {
|
|
467
431
|
kind: "FETCH",
|
|
468
432
|
data: {
|
|
469
|
-
headers:
|
|
470
|
-
body:
|
|
471
|
-
url:
|
|
433
|
+
headers: serialized.headers,
|
|
434
|
+
body: serialized.body,
|
|
435
|
+
url: cacheKey
|
|
472
436
|
},
|
|
473
|
-
tags:
|
|
437
|
+
tags: ctx.tags,
|
|
474
438
|
revalidate: revalidateSeconds
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
439
|
+
};
|
|
440
|
+
const cacheContext = {
|
|
441
|
+
fetchCache: true,
|
|
442
|
+
tags: ctx.tags,
|
|
443
|
+
...cacheFunctionInvocation ? { cacheFunctionInvocation } : {},
|
|
444
|
+
cacheControl: {
|
|
445
|
+
revalidate: revalidateSeconds,
|
|
446
|
+
expire: effectiveLife.expire,
|
|
447
|
+
stale: effectiveLife.stale
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
if (rootParamNames && rootParamNames.size > 0 && rootParams) {
|
|
451
|
+
const specificCacheKey = coarseCacheKey + computeRootParamsCacheKeySuffix(rootParams, rootParamNames);
|
|
452
|
+
const redirectTags = [...ctx.tags, ...[...rootParamNames].map((name) => ROOT_PARAM_TAG_PREFIX + name)];
|
|
453
|
+
await handler.set(coarseCacheKey, {
|
|
454
|
+
kind: "FETCH",
|
|
455
|
+
data: {
|
|
456
|
+
headers: { [ROOT_PARAM_REDIRECT_HEADER]: "1" },
|
|
457
|
+
body: "",
|
|
458
|
+
url: coarseCacheKey
|
|
459
|
+
},
|
|
460
|
+
tags: redirectTags,
|
|
461
|
+
revalidate: revalidateSeconds
|
|
462
|
+
}, {
|
|
463
|
+
...cacheContext,
|
|
464
|
+
tags: redirectTags
|
|
465
|
+
});
|
|
466
|
+
cacheValue.data.url = specificCacheKey;
|
|
467
|
+
await handler.set(specificCacheKey, cacheValue, cacheContext);
|
|
468
|
+
} else await handler.set(cacheKey, cacheValue, cacheContext);
|
|
469
|
+
} catch {}
|
|
470
|
+
return collectedResult ? collectedResult.result : result;
|
|
471
|
+
};
|
|
472
|
+
if (existing?.value && existing.value.kind === "FETCH" && existing.value.data.headers["x-vinext-rsc"] === "1" && isServableCacheState(existing.cacheState) && !_hasPendingRevalidatedTag([...existing.value.tags ?? [], ...softTags])) try {
|
|
473
|
+
propagateRootParamNamesToParent(knownRootParamsByFunctionId.get(id));
|
|
474
|
+
propagateCacheTagsToRequest(existing.value.tags);
|
|
475
|
+
const result = await rsc.createFromReadableStream(uint8ToStream(base64ToUint8(existing.value.data.body)), {}, { preserveServerReferences: true });
|
|
476
|
+
recordRequestScopedCacheControl(existing.cacheControl);
|
|
477
|
+
if (existing.cacheState === "stale") regenerateInBackground(id, () => generate(false));
|
|
478
|
+
return result;
|
|
482
479
|
} catch {}
|
|
483
|
-
return
|
|
480
|
+
return generate(true);
|
|
484
481
|
}, cacheVariant);
|
|
485
482
|
};
|
|
483
|
+
const cachedFn = memoizeInCacheScope((...args) => invoke(args));
|
|
484
|
+
replayableFunctions.set(cachedFn, (data) => invoke([], data));
|
|
486
485
|
Object.defineProperty(cachedFn, "length", {
|
|
487
486
|
value: fn.length,
|
|
488
487
|
configurable: true
|
|
@@ -491,6 +490,11 @@ function registerCachedFunction(fn, id, variant, options = {}) {
|
|
|
491
490
|
if (options.acceptsSecondArgument !== void 0) Reflect.set(cachedFn, USE_CACHE_ACCEPTS_SECOND_ARGUMENT_SYMBOL, options.acceptsSecondArgument);
|
|
492
491
|
return cachedFn;
|
|
493
492
|
}
|
|
493
|
+
/** Memoize in one React render without skipping cache guards or scoped serialization. */
|
|
494
|
+
function memoizeInCacheScope(fn) {
|
|
495
|
+
const memoized = cache((_parent, _workUnit, _unstable, ...args) => fn(...args));
|
|
496
|
+
return (...args) => memoized(cacheContextStorage.getStore(), workUnitAsyncStorage.getStore(), unstableCacheContextStorage.getStore() === true, ...args);
|
|
497
|
+
}
|
|
494
498
|
/** @internal Symbol used to identify "use cache" wrapper functions. */
|
|
495
499
|
const USE_CACHE_FUNCTION_SYMBOL = Symbol.for("vinext.useCacheFunction");
|
|
496
500
|
/** @internal Symbol carrying transform-derived cached function argument metadata. */
|
|
@@ -555,11 +559,12 @@ function propagateCacheTagsToRequest(tags) {
|
|
|
555
559
|
addCollectedRequestTags(tags);
|
|
556
560
|
}
|
|
557
561
|
async function executeWithContext(fn, args, variant, rsc) {
|
|
558
|
-
const { result, ctx: _ctx, effectiveLife, collectedResult } = await runCachedFunctionWithContext(fn, args, variant,
|
|
562
|
+
const { result, ctx: _ctx, effectiveLife, collectedResult } = await runCachedFunctionWithContext(fn, args, variant, (value) => serializeCacheResult(value, rsc));
|
|
559
563
|
recordRequestScopedCacheLife(effectiveLife);
|
|
560
564
|
return {
|
|
561
565
|
result: collectedResult ? collectedResult.result : result,
|
|
562
|
-
cacheable: collectedResult?.cacheEntry !== null
|
|
566
|
+
cacheable: collectedResult?.cacheEntry !== null,
|
|
567
|
+
serialized: collectedResult?.cacheEntry
|
|
563
568
|
};
|
|
564
569
|
}
|
|
565
570
|
async function runCachedFunctionWithContext(fn, args, variant, collectResult) {
|
|
@@ -605,31 +610,6 @@ async function runCachedFunctionWithContext(fn, args, variant, collectResult) {
|
|
|
605
610
|
collectedResult
|
|
606
611
|
};
|
|
607
612
|
}
|
|
608
|
-
function unwrapThenableObjects(value, options) {
|
|
609
|
-
if (value === null || value === void 0 || typeof value !== "object") return value;
|
|
610
|
-
const childOptions = { omitMarkedAppPageSearchParams: options.omitMarkedAppPageSearchParams };
|
|
611
|
-
if (Array.isArray(value)) return value.map((item) => unwrapThenableObjects(item, childOptions));
|
|
612
|
-
if (isThenableObject(value)) {
|
|
613
|
-
const plain = {};
|
|
614
|
-
for (const key of Object.keys(value)) plain[key] = unwrapThenableObjects(value[key], childOptions);
|
|
615
|
-
return plain;
|
|
616
|
-
}
|
|
617
|
-
if (typeof value.then === "function") return value;
|
|
618
|
-
const result = {};
|
|
619
|
-
for (const key of Object.keys(value)) {
|
|
620
|
-
if (key === "searchParams" && (options.omitAppPageSearchParamsAtRoot || options.omitMarkedAppPageSearchParams && isMarkedAppPagePropsObject(value))) continue;
|
|
621
|
-
result[key] = unwrapThenableObjects(value[key], childOptions);
|
|
622
|
-
}
|
|
623
|
-
return result;
|
|
624
|
-
}
|
|
625
|
-
/**
|
|
626
|
-
* A thenable (not an array) with own enumerable properties — the
|
|
627
|
-
* `Object.assign(Promise.resolve(obj), obj)` pattern Next.js params use. The
|
|
628
|
-
* cache key is built from its fields instead of the promise.
|
|
629
|
-
*/
|
|
630
|
-
function isThenableObject(value) {
|
|
631
|
-
return !Array.isArray(value) && "then" in value && typeof value.then === "function" && Object.keys(value).length > 0;
|
|
632
|
-
}
|
|
633
613
|
function isPagePropsObject(value) {
|
|
634
614
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
635
615
|
}
|
|
@@ -638,26 +618,17 @@ function replaceArgument(args, index, value) {
|
|
|
638
618
|
result[index] = value;
|
|
639
619
|
return result;
|
|
640
620
|
}
|
|
641
|
-
/** Remove the `$$isPage` invocation marker before props reach the key or user code. */
|
|
642
|
-
function withoutUseCachePageMarker(props) {
|
|
643
|
-
const { [APP_PAGE_USE_CACHE_MARKER]: _marker, ...pageProps } = props;
|
|
644
|
-
return isMarkedAppPagePropsObject(props) ? markAppPagePropsForUseCache(pageProps) : pageProps;
|
|
645
|
-
}
|
|
646
621
|
/**
|
|
647
622
|
* Response Store replay args for a public page cache: drop `searchParams` from
|
|
648
623
|
* the page props at `index` (after a capture envelope, if any), as Next.js does
|
|
649
|
-
* for the serialized arguments (use-cache-wrapper.ts, `isPageSegmentFunction`)
|
|
650
|
-
*
|
|
651
|
-
* the erroring searchParams fallback.
|
|
624
|
+
* for the serialized arguments (use-cache-wrapper.ts, `isPageSegmentFunction`).
|
|
625
|
+
* The replay regains page semantics from `CacheFlightArguments.pagePropsIndex`.
|
|
652
626
|
*/
|
|
653
627
|
function toReplayablePageArgs(args, index) {
|
|
654
628
|
const props = args[index];
|
|
655
629
|
if (!isPagePropsObject(props)) return [...args];
|
|
656
630
|
const { searchParams: _searchParams, ...pageProps } = props;
|
|
657
|
-
return replaceArgument(args, index,
|
|
658
|
-
...pageProps,
|
|
659
|
-
[APP_PAGE_USE_CACHE_MARKER]: true
|
|
660
|
-
});
|
|
631
|
+
return replaceArgument(args, index, pageProps);
|
|
661
632
|
}
|
|
662
633
|
/**
|
|
663
634
|
* Give page props at `index` without `searchParams` (a Response Store replay of
|
|
@@ -673,35 +644,5 @@ function withErroringPageSearchParams(args, index) {
|
|
|
673
644
|
searchParams: makeThenableParams({}, { observeParamAccess: () => throwIfInsideCacheScope("searchParams") })
|
|
674
645
|
});
|
|
675
646
|
}
|
|
676
|
-
function unwrapThenableObjectArray(values, options) {
|
|
677
|
-
return values.map((value, index) => unwrapThenableObjects(value, {
|
|
678
|
-
omitAppPageSearchParamsAtRoot: index === options.pagePropsIndex,
|
|
679
|
-
omitMarkedAppPageSearchParams: options.omitMarkedAppPageSearchParams
|
|
680
|
-
}));
|
|
681
|
-
}
|
|
682
|
-
function stableStringify(value, seen) {
|
|
683
|
-
if (value === void 0) return "undefined";
|
|
684
|
-
if (value === null) return "null";
|
|
685
|
-
if (typeof value === "function") throw new Error("Cannot serialize function");
|
|
686
|
-
if (typeof value === "symbol") throw new Error("Cannot serialize symbol");
|
|
687
|
-
if (Array.isArray(value)) {
|
|
688
|
-
if (!seen) seen = /* @__PURE__ */ new Set();
|
|
689
|
-
if (seen.has(value)) throw new Error("Circular reference");
|
|
690
|
-
seen.add(value);
|
|
691
|
-
const result = "[" + value.map((v) => stableStringify(v, seen)).join(",") + "]";
|
|
692
|
-
seen.delete(value);
|
|
693
|
-
return result;
|
|
694
|
-
}
|
|
695
|
-
if (typeof value === "object" && value !== null) {
|
|
696
|
-
if (value instanceof Date) return `Date(${value.getTime()})`;
|
|
697
|
-
if (!seen) seen = /* @__PURE__ */ new Set();
|
|
698
|
-
if (seen.has(value)) throw new Error("Circular reference");
|
|
699
|
-
seen.add(value);
|
|
700
|
-
const result = "{" + Object.keys(value).sort().map((k) => `${JSON.stringify(k)}:${stableStringify(value[k], seen)}`).join(",") + "}";
|
|
701
|
-
seen.delete(value);
|
|
702
|
-
return result;
|
|
703
|
-
}
|
|
704
|
-
return JSON.stringify(value);
|
|
705
|
-
}
|
|
706
647
|
//#endregion
|
|
707
|
-
export { NestedDynamicUseCacheError, buildUseCacheKey, cacheContextStorage, clearPrivateCache, getCacheContext,
|
|
648
|
+
export { NestedDynamicUseCacheError, buildUseCacheKey, cacheContextStorage, clearPrivateCache, getCacheContext, isUseCacheFunction, memoizeInCacheScope, registerCachedFunction, replayCachedFunction, runWithPrivateCache };
|
package/dist/shims/cache.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ExecutionContextLike, getRequestExecutionContext, runWithExecutionContext } from "./request-context.js";
|
|
2
2
|
import { _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext } from "./internal/cache-context-accessor.js";
|
|
3
|
-
import { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheLifeConfig, CacheState, UnstableCacheObservation, UnstableCacheRevalidationMode, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, markActionRevalidation, recordUnstableCacheObservation, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
|
|
3
|
+
import { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheLifeConfig, CacheLifeSink, CacheState, UnstableCacheObservation, UnstableCacheRevalidationMode, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, getAndClearActionRevalidationKind, markActionRevalidation, recordUnstableCacheObservation, runWithDetachedCacheObservations, shouldServeStaleUnstableCacheEntry } from "./cache-request-state.js";
|
|
4
4
|
import { CacheControlMetadata, CacheHandler, CacheHandlerContext, CacheHandlerValue, CachedAppPageValue, CachedFetchValue, CachedImageValue, CachedPagesValue, CachedRedirectValue, CachedRouteValue, IncrementalCacheValue, MemoryCacheHandler, NoOpCacheHandler, configureMemoryCacheHandler, getCacheHandler, getDataCacheHandler, registerDataCacheHandler, registerLazyDataCacheHandler, setCacheHandler, setDataCacheHandler } from "./cache-handler.js";
|
|
5
5
|
//#region src/shims/cache.d.ts
|
|
6
6
|
/**
|
|
@@ -137,9 +137,9 @@ type UnstableCacheOptions = {
|
|
|
137
137
|
/**
|
|
138
138
|
* Wrap an async function with caching.
|
|
139
139
|
*
|
|
140
|
-
* Returns a new function that caches results. The cache key is
|
|
141
|
-
*
|
|
140
|
+
* Returns a new function that caches results. The cache key is a SHA-256
|
|
141
|
+
* digest of the callback source, keyParts and serialized arguments.
|
|
142
142
|
*/
|
|
143
143
|
export declare function unstable_cache<T extends (...args: any[]) => Promise<any>>(fn: T, keyParts?: string[], options?: UnstableCacheOptions): T;
|
|
144
144
|
//#endregion
|
|
145
|
-
export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheControlMetadata, CacheHandler, CacheHandlerContext, CacheHandlerValue, CacheLifeConfig, CacheState, CachedAppPageValue, CachedFetchValue, CachedImageValue, CachedPagesValue, CachedRedirectValue, CachedRouteValue, type ExecutionContextLike, IncrementalCacheValue, MemoryCacheHandler, NoOpCacheHandler, UnstableCacheObservation, UnstableCacheRevalidationMode, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _recordUseCacheRootParamRead, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, configureMemoryCacheHandler, getAndClearActionRevalidationKind, getCacheHandler, getDataCacheHandler, getRegisteredCacheContext, getRequestExecutionContext, markActionRevalidation, unstable_noStore as noStore, recordUnstableCacheObservation, registerDataCacheHandler, registerLazyDataCacheHandler, runWithExecutionContext, setCacheHandler, setDataCacheHandler, shouldServeStaleUnstableCacheEntry };
|
|
145
|
+
export { ACTION_DID_REVALIDATE_DYNAMIC_ONLY, ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC, ActionRevalidationKind, CacheControlMetadata, CacheHandler, CacheHandlerContext, CacheHandlerValue, CacheLifeConfig, CacheLifeSink, CacheState, CachedAppPageValue, CachedFetchValue, CachedImageValue, CachedPagesValue, CachedRedirectValue, CachedRouteValue, type ExecutionContextLike, IncrementalCacheValue, MemoryCacheHandler, NoOpCacheHandler, UnstableCacheObservation, UnstableCacheRevalidationMode, _captureRequestScopedCacheLifeAccessors, _consumeRequestScopedCacheLife, _drainPendingRevalidations, _hasPendingRevalidatedTag, _initRequestScopedCacheState, _markPendingRevalidatedTag, _peekRequestScopedCacheLife, _peekUnstableCacheObservations, _queuePendingRevalidation, _recordUseCacheRootParamRead, _registerCacheContextAccessor, _runWithCacheState, _setRequestScopedCacheLife, cacheLifeProfiles, configureMemoryCacheHandler, getAndClearActionRevalidationKind, getCacheHandler, getDataCacheHandler, getRegisteredCacheContext, getRequestExecutionContext, markActionRevalidation, unstable_noStore as noStore, recordUnstableCacheObservation, registerDataCacheHandler, registerLazyDataCacheHandler, runWithDetachedCacheObservations, runWithExecutionContext, setCacheHandler, setDataCacheHandler, shouldServeStaleUnstableCacheEntry };
|