vinext 1.0.0 → 1.1.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 +72 -1
- package/THIRD_PARTY_LICENSES.md +26 -0
- package/dist/build/app-page-static-eligibility.d.ts +15 -0
- package/dist/build/app-page-static-eligibility.js +82 -0
- package/dist/build/lifecycle.js +10 -10
- package/dist/build/pages-client-assets-module.js +6 -1
- package/dist/build/precompress.js +1 -1
- package/dist/build/prerender-paths.js +6 -85
- package/dist/build/prerender.d.ts +8 -1
- package/dist/build/prerender.js +167 -46
- package/dist/build/run-prerender.js +4 -3
- package/dist/build/server-entry.d.ts +2 -0
- package/dist/build/server-entry.js +7 -1
- package/dist/build/server-manifest.d.ts +7 -0
- package/dist/build/server-manifest.js +11 -1
- package/dist/cache/cache-adapters-virtual.d.ts +7 -1
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/client/browser-globals.d.ts +4 -0
- package/dist/client/browser-globals.js +5 -0
- package/dist/client/navigation-runtime.d.ts +11 -1
- package/dist/client/navigation-runtime.js +3 -3
- package/dist/config/config-matchers.js +3 -1
- package/dist/config/dotenv.js +14 -3
- package/dist/config/next-config.d.ts +7 -0
- package/dist/config/next-config.js +18 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +67 -45
- package/dist/index.d.ts +4 -1
- package/dist/index.js +200 -100
- package/dist/init-cloudflare.d.ts +1 -1
- package/dist/init-cloudflare.js +6 -6
- package/dist/init-platform.js +1 -1
- package/dist/init.js +4 -2
- 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/commonjs-syntax.d.ts +16 -0
- package/dist/plugins/commonjs-syntax.js +22 -0
- package/dist/plugins/fonts.d.ts +8 -11
- package/dist/plugins/fonts.js +71 -34
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +54 -3
- package/dist/plugins/import-meta-url.js +6 -6
- package/dist/plugins/og-asset-ownership.d.ts +2 -0
- package/dist/plugins/og-asset-ownership.js +24 -13
- package/dist/plugins/og-assets.d.ts +18 -0
- package/dist/plugins/og-assets.js +50 -8
- package/dist/plugins/og-harfbuzz.js +38 -27
- package/dist/plugins/optimize-imports.js +2 -1
- package/dist/plugins/require-context.d.ts +1 -0
- package/dist/plugins/require-context.js +28 -1
- package/dist/plugins/scan-build-css.d.ts +12 -0
- package/dist/plugins/scan-build-css.js +39 -0
- package/dist/plugins/strip-server-exports.d.ts +2 -0
- package/dist/plugins/strip-server-exports.js +3 -1
- package/dist/plugins/transform-result.d.ts +18 -0
- package/dist/plugins/transform-result.js +23 -2
- package/dist/plugins/typeof-window.d.ts +10 -0
- package/dist/plugins/typeof-window.js +33 -9
- package/dist/routing/app-route-graph.d.ts +0 -1
- package/dist/routing/app-route-graph.js +2 -4
- package/dist/routing/app-route-ids.d.ts +3 -0
- package/dist/routing/app-route-ids.js +6 -0
- package/dist/routing/file-matcher.d.ts +1 -0
- package/dist/routing/file-matcher.js +1 -1
- package/dist/server/api-handler.js +17 -7
- package/dist/server/app-bfcache-id.d.ts +1 -0
- package/dist/server/app-bfcache-id.js +7 -1
- package/dist/server/app-bfcache-identity.js +1 -2
- package/dist/server/app-browser-entry.js +15 -9
- 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-hydration.d.ts +1 -1
- package/dist/server/app-browser-hydration.js +2 -2
- 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-state.js +1 -1
- package/dist/server/app-browser-stream.d.ts +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 -1
- package/dist/server/app-history-state.js +9 -5
- package/dist/server/app-middleware.js +2 -1
- 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 +65 -44
- package/dist/server/app-page-cache.d.ts +5 -0
- package/dist/server/app-page-cache.js +27 -7
- package/dist/server/app-page-dispatch.d.ts +9 -1
- package/dist/server/app-page-dispatch.js +47 -30
- 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-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 +2 -2
- package/dist/server/app-page-render.d.ts +13 -5
- package/dist/server/app-page-render.js +219 -118
- package/dist/server/app-page-request.d.ts +0 -1
- package/dist/server/app-page-request.js +1 -2
- 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 +55 -33
- 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-search-params-observation.js +1 -1
- package/dist/server/app-page-stream.d.ts +15 -8
- package/dist/server/app-page-stream.js +7 -1
- package/dist/server/app-page-tracing.js +2 -1
- package/dist/server/app-pages-bridge.js +3 -2
- package/dist/server/app-render-abort-error.d.ts +3 -0
- package/dist/server/app-render-abort-error.js +8 -0
- package/dist/server/app-request-stage-dispatch.js +1 -1
- package/dist/server/app-request-stage-independent-entry.js +8 -11
- 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-route-handler-cache.d.ts +2 -1
- package/dist/server/app-route-handler-cache.js +11 -7
- package/dist/server/app-route-handler-dispatch.js +11 -4
- package/dist/server/app-route-handler-execution.d.ts +9 -1
- package/dist/server/app-route-handler-execution.js +28 -13
- package/dist/server/app-route-handler-policy.js +2 -2
- package/dist/server/app-route-handler-response.d.ts +1 -1
- package/dist/server/app-route-handler-response.js +14 -5
- package/dist/server/app-router-entry.d.ts +2 -1
- package/dist/server/app-router-entry.js +8 -12
- package/dist/server/app-rsc-errors.d.ts +0 -1
- package/dist/server/app-rsc-errors.js +2 -6
- package/dist/server/app-rsc-handler.d.ts +5 -0
- package/dist/server/app-rsc-handler.js +229 -102
- package/dist/server/app-rsc-request-normalization.d.ts +4 -2
- package/dist/server/app-rsc-request-normalization.js +7 -4
- package/dist/server/app-rsc-response-finalizer.js +4 -1
- package/dist/server/app-rsc-response-stage.d.ts +1 -1
- package/dist/server/app-rsc-response-stage.js +6 -4
- package/dist/server/app-rsc-route-matching.d.ts +9 -1
- package/dist/server/app-rsc-route-matching.js +37 -20
- package/dist/server/app-server-action-execution.d.ts +2 -1
- package/dist/server/app-server-action-execution.js +1 -1
- package/dist/server/app-ssr-entry.d.ts +3 -2
- package/dist/server/app-ssr-entry.js +9 -7
- package/dist/server/app-ssr-search-params-gate.js +1 -1
- package/dist/server/app-ssr-stream.d.ts +6 -1
- package/dist/server/app-ssr-stream.js +35 -16
- package/dist/server/app-worker-stages.d.ts +2 -2
- package/dist/server/app-worker-stages.js +3 -3
- package/dist/server/cache-control.js +3 -11
- package/dist/server/cacheability-request.js +56 -52
- package/dist/server/config-headers.js +3 -1
- package/dist/server/dev-server.js +23 -5
- package/dist/server/headers.d.ts +16 -0
- package/dist/server/headers.js +19 -1
- package/dist/server/http-error-responses.js +1 -0
- package/dist/server/image-optimization.d.ts +16 -0
- package/dist/server/image-optimization.js +26 -6
- package/dist/server/isr-cache.d.ts +2 -0
- package/dist/server/isr-cache.js +8 -3
- package/dist/server/metadata-route-response.js +94 -37
- package/dist/server/middleware-matcher-pattern.js +8 -4
- package/dist/server/middleware-response-headers.js +2 -0
- package/dist/server/multi-stage.d.ts +8 -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/open-redirect.d.ts +47 -0
- package/dist/server/open-redirect.js +74 -1
- package/dist/server/pages-api-route.js +8 -2
- package/dist/server/pages-asset-tags.d.ts +1 -0
- package/dist/server/pages-asset-tags.js +73 -22
- package/dist/server/pages-client-assets.d.ts +2 -0
- package/dist/server/pages-page-data.d.ts +6 -1
- package/dist/server/pages-page-data.js +71 -65
- package/dist/server/pages-page-handler.js +50 -15
- package/dist/server/pages-page-response.js +3 -1
- package/dist/server/pages-request-pipeline.d.ts +2 -1
- package/dist/server/pages-request-pipeline.js +20 -5
- package/dist/server/pages-request-stage-entry.js +14 -8
- package/dist/server/prerender-manifest.d.ts +6 -0
- package/dist/server/prerender-manifest.js +1 -1
- package/dist/server/prod-server.d.ts +8 -7
- package/dist/server/prod-server.js +152 -78
- package/dist/server/request-pipeline.d.ts +20 -8
- package/dist/server/request-pipeline.js +21 -7
- package/dist/server/response-compression.d.ts +43 -0
- package/dist/server/response-compression.js +111 -0
- package/dist/server/response-stage-cacheability.js +1 -1
- package/dist/server/seed-cache.js +10 -7
- package/dist/server/socket-error-backstop.d.ts +14 -0
- package/dist/server/socket-error-backstop.js +27 -4
- package/dist/server/worker-revalidation-context.d.ts +2 -1
- package/dist/server/worker-revalidation-context.js +1 -0
- package/dist/server/workers-tracing.d.ts +17 -0
- package/dist/server/workers-tracing.js +48 -8
- 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 +2 -40
- package/dist/shims/cache-callable-runtime.js +50 -168
- package/dist/shims/cache-flight-arguments.d.ts +22 -0
- package/dist/shims/cache-flight-arguments.js +56 -0
- package/dist/shims/cache-request-state.d.ts +18 -14
- package/dist/shims/cache-request-state.js +33 -21
- package/dist/shims/cache-runtime.d.ts +6 -19
- package/dist/shims/cache-runtime.js +168 -226
- package/dist/shims/cache.d.ts +3 -2
- package/dist/shims/cache.js +8 -5
- package/dist/shims/cacheability-classification.d.ts +8 -1
- package/dist/shims/cacheability-classification.js +2 -2
- package/dist/shims/cdn-cache.d.ts +10 -1
- package/dist/shims/cdn-cache.js +16 -9
- 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/error.d.ts +4 -18
- package/dist/shims/error.js +17 -10
- package/dist/shims/error.react-server.d.ts +4 -6
- package/dist/shims/error.react-server.js +4 -1
- package/dist/shims/fetch-cache.d.ts +6 -0
- package/dist/shims/fetch-cache.js +23 -4
- package/dist/shims/form.js +1 -1
- package/dist/shims/headers.d.ts +19 -69
- package/dist/shims/headers.js +82 -183
- 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/cache-context-accessor.d.ts +16 -0
- package/dist/shims/internal/cache-context-accessor.js +15 -0
- package/dist/shims/internal/headers-state.d.ts +73 -0
- package/dist/shims/internal/headers-state.js +157 -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 +16 -6
- package/dist/shims/request-context.d.ts +9 -0
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/root-params.js +1 -1
- package/dist/shims/server.js +52 -2
- 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/utils/encode-cache-tag.d.ts +1 -0
- package/dist/utils/encode-cache-tag.js +11 -1
- package/dist/utils/mdx-scan.d.ts +5 -0
- package/dist/utils/mdx-scan.js +8 -1
- package/dist/utils/regex-safety.d.ts +10 -0
- package/dist/utils/regex-safety.js +70 -18
- package/dist/utils/vite-cli-invocation.js +8 -1
- package/package.json +8 -4
- package/dist/server/metadata-route-cache-policy.d.ts +0 -5
- package/dist/server/metadata-route-cache-policy.js +0 -6
package/dist/shims/headers.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ensureRenderDynamicLatch, getRequestContext, isInsideUnifiedScope, runWithUnifiedStateMutation } from "./unified-request-context.js";
|
|
1
|
+
import { ensureRenderDynamicLatch, isInsideUnifiedScope, runWithUnifiedStateMutation } from "./unified-request-context.js";
|
|
3
2
|
import { MIDDLEWARE_SET_COOKIE_HEADER } from "../utils/protocol-headers.js";
|
|
4
3
|
import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
|
|
5
4
|
import { parseEdgeRequestCookieHeader } from "../utils/parse-cookie.js";
|
|
6
5
|
import { FLIGHT_HEADERS, NEXT_HTML_REQUEST_ID_HEADER, NEXT_REQUEST_ID_HEADER } from "../server/headers.js";
|
|
7
6
|
import { serializeSetCookie, validateCookieName } from "./internal/cookie-serialize.js";
|
|
8
7
|
import { createPprFallbackShellSuspensePromise } from "./ppr-fallback-shell.js";
|
|
8
|
+
import { createRenderDynamicLatch, getHeadersAccessPhase, getHeadersShimState, headersShimAls, isInsideAnyCacheScope, isRenderDynamicLatched, markDynamicUsage, markRenderRequestApiUsage, onRenderDynamicLatched, throwIfInsideCacheScope, throwIfStaticGenerationAccessError } from "./internal/headers-state.js";
|
|
9
9
|
//#region src/shims/headers.ts
|
|
10
10
|
/**
|
|
11
11
|
* next/headers shim
|
|
@@ -16,26 +16,6 @@ import { createPprFallbackShellSuspensePromise } from "./ppr-fallback-shell.js";
|
|
|
16
16
|
* In Next.js 15+, cookies() and headers() return Promises (async).
|
|
17
17
|
* We support both the sync (legacy) and async patterns.
|
|
18
18
|
*/
|
|
19
|
-
function createRenderDynamicLatch() {
|
|
20
|
-
return {
|
|
21
|
-
dynamic: false,
|
|
22
|
-
listeners: /* @__PURE__ */ new Set()
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
const _FALLBACK_KEY = Symbol.for("vinext.nextHeadersShim.fallback");
|
|
26
|
-
const _g = globalThis;
|
|
27
|
-
const _als = getOrCreateAls("vinext.nextHeadersShim.als");
|
|
28
|
-
const _fallbackState = _g[_FALLBACK_KEY] ??= {
|
|
29
|
-
headersContext: null,
|
|
30
|
-
dynamicUsageDetected: false,
|
|
31
|
-
renderDynamicLatch: createRenderDynamicLatch(),
|
|
32
|
-
renderRequestApiUsage: /* @__PURE__ */ new Set(),
|
|
33
|
-
connectionProbe: null,
|
|
34
|
-
invalidDynamicUsageError: null,
|
|
35
|
-
pendingSetCookies: [],
|
|
36
|
-
draftModeCookieHeader: null,
|
|
37
|
-
phase: "render"
|
|
38
|
-
};
|
|
39
19
|
function splitMiddlewareSetCookieHeader(value) {
|
|
40
20
|
const cookies = [];
|
|
41
21
|
let start = 0;
|
|
@@ -103,72 +83,6 @@ function mergeMiddlewareSetCookies(ctx, rawHeader) {
|
|
|
103
83
|
}
|
|
104
84
|
return merged;
|
|
105
85
|
}
|
|
106
|
-
function _getState() {
|
|
107
|
-
if (isInsideUnifiedScope()) return getRequestContext();
|
|
108
|
-
return _als.getStore() ?? _fallbackState;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Dynamic usage flag — set when a component calls connection(), cookies(),
|
|
112
|
-
* headers(), or noStore() during rendering. When true, ISR caching is
|
|
113
|
-
* bypassed and the response gets Cache-Control: no-store.
|
|
114
|
-
*/
|
|
115
|
-
/**
|
|
116
|
-
* Mark the current render as requiring dynamic (uncached) rendering.
|
|
117
|
-
* Called by connection(), cookies(), headers(), and noStore().
|
|
118
|
-
*/
|
|
119
|
-
function markDynamicUsage() {
|
|
120
|
-
const state = _getState();
|
|
121
|
-
if (state.headersContext?.forceStatic) return;
|
|
122
|
-
state.dynamicUsageDetected = true;
|
|
123
|
-
const latches = [ensureRenderDynamicLatch(state)];
|
|
124
|
-
forEachConnectionProbeTarget(state, (target) => {
|
|
125
|
-
target.dynamicUsageDetected = true;
|
|
126
|
-
latches.push(ensureRenderDynamicLatch(target));
|
|
127
|
-
});
|
|
128
|
-
for (const latch of latches) latchRenderDynamic(latch);
|
|
129
|
-
}
|
|
130
|
-
function latchRenderDynamic(latch) {
|
|
131
|
-
if (latch.dynamic) return;
|
|
132
|
-
latch.dynamic = true;
|
|
133
|
-
const listeners = [...latch.listeners];
|
|
134
|
-
latch.listeners.clear();
|
|
135
|
-
for (const listener of listeners) try {
|
|
136
|
-
listener();
|
|
137
|
-
} catch (error) {
|
|
138
|
-
console.error(error);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
/** Whether the current render has used a dynamic API at any point so far. */
|
|
142
|
-
function isRenderDynamicLatched() {
|
|
143
|
-
return ensureRenderDynamicLatch(_getState()).dynamic;
|
|
144
|
-
}
|
|
145
|
-
/**
|
|
146
|
-
* Call `listener` once when the current render first uses a dynamic API.
|
|
147
|
-
* Returns an unsubscribe function. The listener never runs if the render is
|
|
148
|
-
* already latched; check `isRenderDynamicLatched()` first.
|
|
149
|
-
*/
|
|
150
|
-
function onRenderDynamicLatched(listener) {
|
|
151
|
-
const latch = ensureRenderDynamicLatch(_getState());
|
|
152
|
-
if (latch.dynamic) return () => {};
|
|
153
|
-
latch.listeners.add(listener);
|
|
154
|
-
return () => {
|
|
155
|
-
latch.listeners.delete(listener);
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
function forEachConnectionProbeTarget(state, visit) {
|
|
159
|
-
let target = state.connectionProbe?.dynamicUsageTarget ?? null;
|
|
160
|
-
const seen = /* @__PURE__ */ new Set([state]);
|
|
161
|
-
while (target && !seen.has(target)) {
|
|
162
|
-
seen.add(target);
|
|
163
|
-
visit(target);
|
|
164
|
-
target = target.connectionProbe?.dynamicUsageTarget ?? null;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
function propagateInvalidDynamicUsageError(state, error) {
|
|
168
|
-
forEachConnectionProbeTarget(state, (target) => {
|
|
169
|
-
if (target.invalidDynamicUsageError == null) target.invalidDynamicUsageError = error;
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
86
|
/**
|
|
173
87
|
* Measure dynamic usage in a child async scope without clearing the parent.
|
|
174
88
|
* Concurrent work that already belongs to the request (such as deferred
|
|
@@ -192,23 +106,59 @@ async function runWithIsolatedDynamicUsage(fn) {
|
|
|
192
106
|
return runInChildState(childState);
|
|
193
107
|
});
|
|
194
108
|
}
|
|
195
|
-
const parentState =
|
|
109
|
+
const parentState = getHeadersShimState();
|
|
196
110
|
const childState = {
|
|
197
111
|
...parentState,
|
|
198
112
|
renderDynamicLatch: ensureRenderDynamicLatch(parentState),
|
|
199
113
|
dynamicUsageDetected: false
|
|
200
114
|
};
|
|
201
|
-
return await
|
|
115
|
+
return await headersShimAls.run(childState, () => runInChildState(childState));
|
|
202
116
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Run a pre-render probe without letting its dynamic API usage classify the
|
|
119
|
+
* request. Next.js has no probe: only the render decides whether a page is
|
|
120
|
+
* dynamic, and the render runs the probed layouts and page again. Returns the
|
|
121
|
+
* probe's own usage and cacheLife for a caller whose probe response replaces
|
|
122
|
+
* the render.
|
|
123
|
+
*/
|
|
124
|
+
async function runWithDetachedDynamicUsage(fn) {
|
|
125
|
+
const runInChildState = async (childState, cacheLifeSink) => {
|
|
126
|
+
return {
|
|
127
|
+
result: await fn(),
|
|
128
|
+
cacheLife: cacheLifeSink?.cacheLife ?? null,
|
|
129
|
+
dynamicDetected: childState.dynamicUsageDetected || childState.renderDynamicLatch.dynamic
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
if (isInsideUnifiedScope()) {
|
|
133
|
+
let childState = null;
|
|
134
|
+
const cacheLifeSink = { cacheLife: null };
|
|
135
|
+
return await runWithUnifiedStateMutation((context) => {
|
|
136
|
+
context.cacheLifeSink = cacheLifeSink;
|
|
137
|
+
context.dynamicUsageDetected = false;
|
|
138
|
+
context.renderDynamicLatch = createRenderDynamicLatch();
|
|
139
|
+
context.renderRequestApiUsage = /* @__PURE__ */ new Set();
|
|
140
|
+
context.requestCache = /* @__PURE__ */ new WeakMap();
|
|
141
|
+
context.cacheableFetchUrls = /* @__PURE__ */ new Set();
|
|
142
|
+
context.currentRequestTags = [];
|
|
143
|
+
context.dynamicFetchUrls = /* @__PURE__ */ new Set();
|
|
144
|
+
context.requestScopedCacheLife = null;
|
|
145
|
+
context.unstableCacheObservations = /* @__PURE__ */ new Map();
|
|
146
|
+
childState = context;
|
|
147
|
+
}, () => {
|
|
148
|
+
if (!childState) throw new Error("Dynamic usage scope was not initialized");
|
|
149
|
+
return runInChildState(childState, cacheLifeSink);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
const childState = {
|
|
153
|
+
...getHeadersShimState(),
|
|
154
|
+
dynamicUsageDetected: false,
|
|
155
|
+
renderDynamicLatch: createRenderDynamicLatch(),
|
|
156
|
+
renderRequestApiUsage: /* @__PURE__ */ new Set()
|
|
157
|
+
};
|
|
158
|
+
return await headersShimAls.run(childState, () => runInChildState(childState, null));
|
|
209
159
|
}
|
|
210
160
|
async function runWithConnectionProbe(fn) {
|
|
211
|
-
const parentState =
|
|
161
|
+
const parentState = getHeadersShimState();
|
|
212
162
|
const parentInvalidDynamicUsageError = parentState.invalidDynamicUsageError;
|
|
213
163
|
let interruptProbe = () => {};
|
|
214
164
|
const interrupted = new Promise((resolve) => {
|
|
@@ -222,8 +172,7 @@ async function runWithConnectionProbe(fn) {
|
|
|
222
172
|
if (probe.interrupted) return;
|
|
223
173
|
probe.interrupted = true;
|
|
224
174
|
interruptProbe();
|
|
225
|
-
}
|
|
226
|
-
pending: new Promise(() => {})
|
|
175
|
+
}
|
|
227
176
|
};
|
|
228
177
|
const runInChildState = async (childState) => {
|
|
229
178
|
try {
|
|
@@ -234,6 +183,7 @@ async function runWithConnectionProbe(fn) {
|
|
|
234
183
|
return await Promise.race([completed, interrupted]);
|
|
235
184
|
} finally {
|
|
236
185
|
probe.active = false;
|
|
186
|
+
interruptProbe();
|
|
237
187
|
childState.connectionProbe = parentState.connectionProbe ?? probe;
|
|
238
188
|
if (childState.dynamicUsageDetected) parentState.dynamicUsageDetected = true;
|
|
239
189
|
if (childState.invalidDynamicUsageError !== parentInvalidDynamicUsageError && parentState.invalidDynamicUsageError === parentInvalidDynamicUsageError) parentState.invalidDynamicUsageError = childState.invalidDynamicUsageError;
|
|
@@ -254,79 +204,23 @@ async function runWithConnectionProbe(fn) {
|
|
|
254
204
|
renderDynamicLatch: ensureRenderDynamicLatch(parentState),
|
|
255
205
|
connectionProbe: probe
|
|
256
206
|
};
|
|
257
|
-
return await
|
|
207
|
+
return await headersShimAls.run(childState, () => runInChildState(childState));
|
|
258
208
|
}
|
|
259
209
|
function suspendConnectionProbe() {
|
|
260
|
-
const probe =
|
|
210
|
+
const probe = getHeadersShimState().connectionProbe;
|
|
261
211
|
if (!probe?.active) return null;
|
|
262
212
|
probe.interrupt();
|
|
263
|
-
return
|
|
213
|
+
return new Promise(() => {});
|
|
264
214
|
}
|
|
265
215
|
function peekRenderRequestApiUsage() {
|
|
266
|
-
return [...
|
|
216
|
+
return [...getHeadersShimState().renderRequestApiUsage].sort();
|
|
267
217
|
}
|
|
268
218
|
function consumeRenderRequestApiUsage() {
|
|
269
|
-
const state =
|
|
219
|
+
const state = getHeadersShimState();
|
|
270
220
|
const observed = [...state.renderRequestApiUsage].sort();
|
|
271
221
|
state.renderRequestApiUsage = /* @__PURE__ */ new Set();
|
|
272
222
|
return observed;
|
|
273
223
|
}
|
|
274
|
-
/** Symbol used by cache-runtime.ts to store the "use cache" ALS on globalThis */
|
|
275
|
-
const _USE_CACHE_ALS_KEY = Symbol.for("vinext.cacheRuntime.contextAls");
|
|
276
|
-
/** Symbol used by cache.ts to store the unstable_cache ALS on globalThis */
|
|
277
|
-
const _UNSTABLE_CACHE_ALS_KEY = Symbol.for("vinext.unstableCache.als");
|
|
278
|
-
function _getGlobalCacheScopeStore(key) {
|
|
279
|
-
const value = Reflect.get(globalThis, key);
|
|
280
|
-
if (!value || typeof value !== "object") return null;
|
|
281
|
-
const getStore = Reflect.get(value, "getStore");
|
|
282
|
-
if (typeof getStore !== "function") return null;
|
|
283
|
-
return getStore.call(value);
|
|
284
|
-
}
|
|
285
|
-
function _getUseCacheGuardContext() {
|
|
286
|
-
const store = _getGlobalCacheScopeStore(_USE_CACHE_ALS_KEY);
|
|
287
|
-
if (!store || typeof store !== "object") return null;
|
|
288
|
-
return store;
|
|
289
|
-
}
|
|
290
|
-
function _isInsidePublicUseCache() {
|
|
291
|
-
const ctx = _getUseCacheGuardContext();
|
|
292
|
-
return ctx !== null && ctx.variant !== "private";
|
|
293
|
-
}
|
|
294
|
-
function _isInsideUnstableCache() {
|
|
295
|
-
return _getGlobalCacheScopeStore(_UNSTABLE_CACHE_ALS_KEY) === true;
|
|
296
|
-
}
|
|
297
|
-
/** Whether work is executing inside a cache boundary that owns its reuse. */
|
|
298
|
-
function isInsideAnyCacheScope() {
|
|
299
|
-
return _getUseCacheGuardContext() !== null || _isInsideUnstableCache();
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Throw if the current execution is inside a "use cache" or unstable_cache()
|
|
303
|
-
* scope. Called by dynamic request APIs (headers, cookies, connection) to
|
|
304
|
-
* prevent request-specific data from being frozen into cached results.
|
|
305
|
-
*
|
|
306
|
-
* @param apiName - The name of the API being called (e.g. "connection()")
|
|
307
|
-
*/
|
|
308
|
-
function throwIfInsideCacheScope(apiName) {
|
|
309
|
-
if (_isInsidePublicUseCache()) {
|
|
310
|
-
const error = /* @__PURE__ */ new Error(`\`${apiName}\` cannot be called inside "use cache". If you need this data inside a cached function, call \`${apiName}\` outside and pass the required data as an argument.`);
|
|
311
|
-
try {
|
|
312
|
-
const cacheCtx = _getUseCacheGuardContext();
|
|
313
|
-
if (cacheCtx) cacheCtx.invalidDynamicUsageError = error;
|
|
314
|
-
const ctx = getRequestContext();
|
|
315
|
-
if (ctx) ctx.invalidDynamicUsageError = error;
|
|
316
|
-
propagateInvalidDynamicUsageError(_getState(), error);
|
|
317
|
-
} catch {}
|
|
318
|
-
throw error;
|
|
319
|
-
}
|
|
320
|
-
if (_isInsideUnstableCache()) {
|
|
321
|
-
const error = /* @__PURE__ */ new Error(`\`${apiName}\` cannot be called inside a function cached with \`unstable_cache()\`. If you need this data inside a cached function, call \`${apiName}\` outside and pass the required data as an argument.`);
|
|
322
|
-
try {
|
|
323
|
-
const ctx = getRequestContext();
|
|
324
|
-
if (ctx) ctx.invalidDynamicUsageError = error;
|
|
325
|
-
propagateInvalidDynamicUsageError(_getState(), error);
|
|
326
|
-
} catch {}
|
|
327
|
-
throw error;
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
224
|
/**
|
|
331
225
|
* Check, consume, and return any invalid dynamic usage error recorded during
|
|
332
226
|
* the render (e.g. cookies() called inside "use cache"). This error persists
|
|
@@ -337,7 +231,7 @@ function throwIfInsideCacheScope(apiName) {
|
|
|
337
231
|
* https://github.com/vercel/next.js/commit/f5e54c06726b571a042fce67417e40a29f6b8689
|
|
338
232
|
*/
|
|
339
233
|
function consumeInvalidDynamicUsageError() {
|
|
340
|
-
const state =
|
|
234
|
+
const state = getHeadersShimState();
|
|
341
235
|
const err = state.invalidDynamicUsageError;
|
|
342
236
|
state.invalidDynamicUsageError = null;
|
|
343
237
|
return err;
|
|
@@ -347,7 +241,7 @@ function consumeInvalidDynamicUsageError() {
|
|
|
347
241
|
* Called by the server after rendering to decide on caching.
|
|
348
242
|
*/
|
|
349
243
|
function consumeDynamicUsage() {
|
|
350
|
-
const state =
|
|
244
|
+
const state = getHeadersShimState();
|
|
351
245
|
const used = state.dynamicUsageDetected;
|
|
352
246
|
state.dynamicUsageDetected = false;
|
|
353
247
|
return used;
|
|
@@ -360,7 +254,7 @@ function consumeDynamicUsage() {
|
|
|
360
254
|
* that leave no other observable trace.
|
|
361
255
|
*/
|
|
362
256
|
function peekDynamicUsage() {
|
|
363
|
-
return
|
|
257
|
+
return getHeadersShimState().dynamicUsageDetected;
|
|
364
258
|
}
|
|
365
259
|
function _setStatePhase(state, phase) {
|
|
366
260
|
const previous = state.phase;
|
|
@@ -369,14 +263,11 @@ function _setStatePhase(state, phase) {
|
|
|
369
263
|
return previous;
|
|
370
264
|
}
|
|
371
265
|
function _areCookiesMutableInCurrentPhase() {
|
|
372
|
-
const phase =
|
|
266
|
+
const phase = getHeadersShimState().phase;
|
|
373
267
|
return phase === "action" || phase === "route-handler";
|
|
374
268
|
}
|
|
375
269
|
function setHeadersAccessPhase(phase) {
|
|
376
|
-
return _setStatePhase(
|
|
377
|
-
}
|
|
378
|
-
function getHeadersAccessPhase() {
|
|
379
|
-
return _getState().phase;
|
|
270
|
+
return _setStatePhase(getHeadersShimState(), phase);
|
|
380
271
|
}
|
|
381
272
|
/**
|
|
382
273
|
* Set the headers/cookies context for the current RSC render.
|
|
@@ -393,7 +284,7 @@ function getHeadersAccessPhase() {
|
|
|
393
284
|
* request context for afterFiles/fallback rewrite has/missing evaluation.
|
|
394
285
|
*/
|
|
395
286
|
function getHeadersContext() {
|
|
396
|
-
return
|
|
287
|
+
return getHeadersShimState().headersContext;
|
|
397
288
|
}
|
|
398
289
|
/** Serialize the effective request-cookie view, including middleware Set-Cookie overlays. */
|
|
399
290
|
function getEffectiveRequestCookieHeader() {
|
|
@@ -418,7 +309,7 @@ function hasEffectiveRequestCookieChanges(cookieHeader) {
|
|
|
418
309
|
* that split view without changing the request Headers object.
|
|
419
310
|
*/
|
|
420
311
|
function applyEffectiveRequestCookieHeader(cookieHeader) {
|
|
421
|
-
const context =
|
|
312
|
+
const context = getHeadersShimState().headersContext;
|
|
422
313
|
if (!context) return;
|
|
423
314
|
rebuildCookiesFromHeader(context, cookieHeader);
|
|
424
315
|
context.readonlyCookies = void 0;
|
|
@@ -426,7 +317,7 @@ function applyEffectiveRequestCookieHeader(cookieHeader) {
|
|
|
426
317
|
}
|
|
427
318
|
/** Restore a middleware draft-mode transition inside a staged render scope. */
|
|
428
319
|
function restoreDraftModeTransition(cookieHeader) {
|
|
429
|
-
const state =
|
|
320
|
+
const state = getHeadersShimState();
|
|
430
321
|
const context = state.headersContext;
|
|
431
322
|
if (!context) return;
|
|
432
323
|
const entry = setCookieNameValue(cookieHeader);
|
|
@@ -437,8 +328,12 @@ function restoreDraftModeTransition(cookieHeader) {
|
|
|
437
328
|
context.draftModeEnabled = entry.value === validateDraftModeSecret(context.draftModeSecret ?? "");
|
|
438
329
|
state.draftModeCookieHeader = cookieHeader;
|
|
439
330
|
}
|
|
331
|
+
/** Replace request API inputs while retaining dynamic usage and pending mutations. */
|
|
332
|
+
function replaceHeadersContext(ctx) {
|
|
333
|
+
getHeadersShimState().headersContext = ctx;
|
|
334
|
+
}
|
|
440
335
|
function setHeadersContext(ctx) {
|
|
441
|
-
const state =
|
|
336
|
+
const state = getHeadersShimState();
|
|
442
337
|
if (ctx !== null) {
|
|
443
338
|
state.headersContext = ctx;
|
|
444
339
|
state.dynamicUsageDetected = false;
|
|
@@ -474,7 +369,7 @@ function runWithHeadersContext(ctx, fn) {
|
|
|
474
369
|
draftModeCookieHeader: null,
|
|
475
370
|
phase: "render"
|
|
476
371
|
};
|
|
477
|
-
return
|
|
372
|
+
return headersShimAls.run(state, fn);
|
|
478
373
|
}
|
|
479
374
|
/**
|
|
480
375
|
* Apply middleware-forwarded request headers to the current headers context.
|
|
@@ -496,7 +391,7 @@ function runWithHeadersContext(ctx, fn) {
|
|
|
496
391
|
* middleware-modified view.
|
|
497
392
|
*/
|
|
498
393
|
function applyMiddlewareRequestHeaders(middlewareResponseHeaders) {
|
|
499
|
-
const state =
|
|
394
|
+
const state = getHeadersShimState();
|
|
500
395
|
if (!state.headersContext) return;
|
|
501
396
|
const ctx = state.headersContext;
|
|
502
397
|
const previousCookieHeader = ctx.headers.get("cookie");
|
|
@@ -700,7 +595,7 @@ function headers() {
|
|
|
700
595
|
} catch (error) {
|
|
701
596
|
return _decorateRejectedRequestApiPromise(error);
|
|
702
597
|
}
|
|
703
|
-
const state =
|
|
598
|
+
const state = getHeadersShimState();
|
|
704
599
|
if (!state.headersContext) return _decorateRejectedRequestApiPromise(/* @__PURE__ */ new Error("headers() can only be called from a Server Component, Route Handler, or Server Action. Make sure you're not calling it from a Client Component."));
|
|
705
600
|
if (state.headersContext.accessError) return _decorateRejectedRequestApiPromise(state.headersContext.accessError);
|
|
706
601
|
markDynamicUsage();
|
|
@@ -720,7 +615,7 @@ function cookiesImpl() {
|
|
|
720
615
|
} catch (error) {
|
|
721
616
|
return _decorateRejectedRequestApiPromise(error);
|
|
722
617
|
}
|
|
723
|
-
const state =
|
|
618
|
+
const state = getHeadersShimState();
|
|
724
619
|
if (!state.headersContext) return _decorateRejectedRequestApiPromise(/* @__PURE__ */ new Error("cookies() can only be called from a Server Component, Route Handler, or Server Action."));
|
|
725
620
|
if (state.headersContext.accessError) return _decorateRejectedRequestApiPromise(state.headersContext.accessError);
|
|
726
621
|
markDynamicUsage();
|
|
@@ -738,7 +633,7 @@ function cookies() {
|
|
|
738
633
|
* Called by the framework after rendering to attach headers to the response.
|
|
739
634
|
*/
|
|
740
635
|
function getAndClearPendingCookies() {
|
|
741
|
-
const state =
|
|
636
|
+
const state = getHeadersShimState();
|
|
742
637
|
const cookies = state.pendingSetCookies;
|
|
743
638
|
state.pendingSetCookies = [];
|
|
744
639
|
return cookies;
|
|
@@ -748,8 +643,12 @@ const DRAFT_MODE_COOKIE = "__prerender_bypass";
|
|
|
748
643
|
* Get any Set-Cookie header generated by draftMode().enable()/disable().
|
|
749
644
|
* Called by the framework after rendering to attach the header to the response.
|
|
750
645
|
*/
|
|
646
|
+
/** Check a pending draft transition without consuming its outgoing cookie. */
|
|
647
|
+
function hasDraftModeCookieHeader() {
|
|
648
|
+
return getHeadersShimState().draftModeCookieHeader !== null;
|
|
649
|
+
}
|
|
751
650
|
function getDraftModeCookieHeader() {
|
|
752
|
-
const state =
|
|
651
|
+
const state = getHeadersShimState();
|
|
753
652
|
const header = state.draftModeCookieHeader;
|
|
754
653
|
state.draftModeCookieHeader = null;
|
|
755
654
|
return header;
|
|
@@ -780,7 +679,7 @@ function isDraftModeRequest(request, draftModeSecret) {
|
|
|
780
679
|
* callers fall back to an explicitly supplied request when needed.
|
|
781
680
|
*/
|
|
782
681
|
function getActiveDraftModeState() {
|
|
783
|
-
const context =
|
|
682
|
+
const context = getHeadersShimState().headersContext;
|
|
784
683
|
if (!context) return null;
|
|
785
684
|
if (context.draftModeEnabled !== void 0) return context.draftModeEnabled;
|
|
786
685
|
const secret = context.draftModeSecret;
|
|
@@ -820,7 +719,7 @@ function requireActiveDraftModeContext(state, expectedContext, expression) {
|
|
|
820
719
|
*/
|
|
821
720
|
async function draftMode() {
|
|
822
721
|
markRenderRequestApiUsage("draftMode");
|
|
823
|
-
const state =
|
|
722
|
+
const state = getHeadersShimState();
|
|
824
723
|
const context = state.headersContext;
|
|
825
724
|
if (!context) throw createDraftModeScopeError("draftMode()");
|
|
826
725
|
const secret = ensureContextDraftModeSecret(context);
|
|
@@ -908,7 +807,7 @@ var RequestCookies = class {
|
|
|
908
807
|
});
|
|
909
808
|
const serialized = serializeMutableCookie(responseCookie);
|
|
910
809
|
this[APPLY_RESPONSE_COOKIE](responseCookie);
|
|
911
|
-
|
|
810
|
+
getHeadersShimState().pendingSetCookies.push(serialized);
|
|
912
811
|
return this;
|
|
913
812
|
}
|
|
914
813
|
delete(nameOrOptions) {
|
|
@@ -922,7 +821,7 @@ var RequestCookies = class {
|
|
|
922
821
|
});
|
|
923
822
|
const serialized = serializeMutableCookie(responseCookie);
|
|
924
823
|
this[APPLY_RESPONSE_COOKIE](responseCookie);
|
|
925
|
-
|
|
824
|
+
getHeadersShimState().pendingSetCookies.push(serialized);
|
|
926
825
|
return this;
|
|
927
826
|
}
|
|
928
827
|
get size() {
|
|
@@ -978,4 +877,4 @@ function serializeMutableCookie(cookie) {
|
|
|
978
877
|
});
|
|
979
878
|
}
|
|
980
879
|
//#endregion
|
|
981
|
-
export { applyEffectiveRequestCookieHeader, applyMiddlewareRequestHeaders, consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage, cookies, createRenderDynamicLatch, draftMode, getActiveDraftModeState, getAndClearPendingCookies, getDraftModeCookieHeader, getEffectiveRequestCookieHeader, getHeadersAccessPhase, getHeadersContext, hasEffectiveRequestCookieChanges, headers, headersContextFromRequest, isDraftModeEnabled, isDraftModeRequest, isInsideAnyCacheScope, isRenderDynamicLatched, markDynamicUsage, markRenderRequestApiUsage, onRenderDynamicLatched, peekDynamicUsage, peekRenderRequestApiUsage, restoreDraftModeTransition, runWithConnectionProbe, runWithHeadersContext, runWithIsolatedDynamicUsage, setHeadersAccessPhase, setHeadersContext, suspendConnectionProbe, throwIfInsideCacheScope, throwIfStaticGenerationAccessError };
|
|
880
|
+
export { applyEffectiveRequestCookieHeader, applyMiddlewareRequestHeaders, consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage, cookies, createRenderDynamicLatch, draftMode, getActiveDraftModeState, getAndClearPendingCookies, getDraftModeCookieHeader, getEffectiveRequestCookieHeader, getHeadersAccessPhase, getHeadersContext, hasDraftModeCookieHeader, hasEffectiveRequestCookieChanges, headers, headersContextFromRequest, isDraftModeEnabled, isDraftModeRequest, isInsideAnyCacheScope, isRenderDynamicLatched, markDynamicUsage, markRenderRequestApiUsage, onRenderDynamicLatched, peekDynamicUsage, peekRenderRequestApiUsage, replaceHeadersContext, restoreDraftModeTransition, runWithConnectionProbe, runWithDetachedDynamicUsage, runWithHeadersContext, runWithIsolatedDynamicUsage, setHeadersAccessPhase, setHeadersContext, suspendConnectionProbe, throwIfInsideCacheScope, throwIfStaticGenerationAccessError };
|
|
@@ -5,8 +5,6 @@
|
|
|
5
5
|
* props before a server component is invoked.
|
|
6
6
|
*/
|
|
7
7
|
export declare const APP_PAGE_USE_CACHE_MARKER = "$$isPage";
|
|
8
|
-
export declare function markAppPagePropsForUseCache<T extends object>(props: T): T;
|
|
9
|
-
export declare function isMarkedAppPagePropsObject(value: object): boolean;
|
|
10
8
|
/**
|
|
11
9
|
* Whether `fn` is a transformed `"use cache"` function, including a bound
|
|
12
10
|
* one. Like Next.js's `isUseCacheFunction`, this survives `.bind()`: React's
|
|
@@ -23,6 +21,8 @@ export declare function isUseCacheFunctionReference(fn: unknown): boolean;
|
|
|
23
21
|
* module, or bound.
|
|
24
22
|
*/
|
|
25
23
|
export declare function withUseCachePageMarker<T extends Record<string, unknown>>(fn: unknown, props: T): T;
|
|
24
|
+
/** Layout components and their metadata resolvers retain framework params too. */
|
|
25
|
+
export declare function withUseCacheLayoutMarker<T extends Record<string, unknown>>(fn: unknown, props: T): T;
|
|
26
26
|
/**
|
|
27
27
|
* Whether `value` is page props carrying the `$$isPage` marker. Only plain
|
|
28
28
|
* objects qualify: the framework always passes a plain props object, and
|
|
@@ -30,4 +30,7 @@ export declare function withUseCachePageMarker<T extends Record<string, unknown>
|
|
|
30
30
|
* observed as a param access.
|
|
31
31
|
*/
|
|
32
32
|
export declare function hasUseCachePageMarker(value: unknown): value is Record<string, unknown>;
|
|
33
|
+
export declare function hasUseCacheLayoutMarker(value: unknown): value is Record<string, unknown>;
|
|
34
|
+
/** Remove only this invocation's marker before Flight keys and decodes props. */
|
|
35
|
+
export declare function withoutUseCacheSegmentMarker(props: Record<string, unknown>, isPage: boolean): Record<string, unknown>;
|
|
33
36
|
//#endregion
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
//#region src/shims/internal/app-page-props-cache-key.ts
|
|
2
|
-
const APP_PAGE_PROPS_CACHE_KEY_MARKER = Symbol.for("vinext.appPagePropsCacheKeyMarker");
|
|
3
2
|
const USE_CACHE_FUNCTION_SYMBOL = Symbol.for("vinext.useCacheFunction");
|
|
4
3
|
const SERVER_REFERENCE_TAG = Symbol.for("react.server.reference");
|
|
5
4
|
/**
|
|
@@ -15,18 +14,8 @@ const USE_CACHE_SERVER_REFERENCE_ID_RE = /#\$\$vinext_cache_[0-9a-f]{64}$/;
|
|
|
15
14
|
* props before a server component is invoked.
|
|
16
15
|
*/
|
|
17
16
|
const APP_PAGE_USE_CACHE_MARKER = "$$isPage";
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
configurable: false,
|
|
21
|
-
enumerable: false,
|
|
22
|
-
value: true,
|
|
23
|
-
writable: false
|
|
24
|
-
});
|
|
25
|
-
return props;
|
|
26
|
-
}
|
|
27
|
-
function isMarkedAppPagePropsObject(value) {
|
|
28
|
-
return Reflect.get(value, APP_PAGE_PROPS_CACHE_KEY_MARKER) === true;
|
|
29
|
-
}
|
|
17
|
+
/** Layout marker, matching Next.js's `$$isLayout` prop (create-component-tree.tsx). */
|
|
18
|
+
const APP_LAYOUT_USE_CACHE_MARKER = "$$isLayout";
|
|
30
19
|
/**
|
|
31
20
|
* Whether `fn` is a transformed `"use cache"` function, including a bound
|
|
32
21
|
* one. Like Next.js's `isUseCacheFunction`, this survives `.bind()`: React's
|
|
@@ -53,6 +42,13 @@ function withUseCachePageMarker(fn, props) {
|
|
|
53
42
|
[APP_PAGE_USE_CACHE_MARKER]: true
|
|
54
43
|
} : props;
|
|
55
44
|
}
|
|
45
|
+
/** Layout components and their metadata resolvers retain framework params too. */
|
|
46
|
+
function withUseCacheLayoutMarker(fn, props) {
|
|
47
|
+
return isUseCacheFunctionReference(fn) ? {
|
|
48
|
+
...props,
|
|
49
|
+
[APP_LAYOUT_USE_CACHE_MARKER]: true
|
|
50
|
+
} : props;
|
|
51
|
+
}
|
|
56
52
|
/**
|
|
57
53
|
* Whether `value` is page props carrying the `$$isPage` marker. Only plain
|
|
58
54
|
* objects qualify: the framework always passes a plain props object, and
|
|
@@ -60,9 +56,22 @@ function withUseCachePageMarker(fn, props) {
|
|
|
60
56
|
* observed as a param access.
|
|
61
57
|
*/
|
|
62
58
|
function hasUseCachePageMarker(value) {
|
|
59
|
+
return hasUseCacheSegmentMarker(value, APP_PAGE_USE_CACHE_MARKER);
|
|
60
|
+
}
|
|
61
|
+
function hasUseCacheLayoutMarker(value) {
|
|
62
|
+
return hasUseCacheSegmentMarker(value, APP_LAYOUT_USE_CACHE_MARKER);
|
|
63
|
+
}
|
|
64
|
+
/** Remove only this invocation's marker before Flight keys and decodes props. */
|
|
65
|
+
function withoutUseCacheSegmentMarker(props, isPage) {
|
|
66
|
+
const marker = isPage ? APP_PAGE_USE_CACHE_MARKER : APP_LAYOUT_USE_CACHE_MARKER;
|
|
67
|
+
if (props[marker] !== true) return props;
|
|
68
|
+
const { [marker]: _marker, ...segmentProps } = props;
|
|
69
|
+
return segmentProps;
|
|
70
|
+
}
|
|
71
|
+
function hasUseCacheSegmentMarker(value, marker) {
|
|
63
72
|
if (value === null || typeof value !== "object") return false;
|
|
64
73
|
const prototype = Object.getPrototypeOf(value);
|
|
65
|
-
return (prototype === Object.prototype || prototype === null) && value[
|
|
74
|
+
return (prototype === Object.prototype || prototype === null) && value[marker] === true;
|
|
66
75
|
}
|
|
67
76
|
//#endregion
|
|
68
|
-
export { APP_PAGE_USE_CACHE_MARKER,
|
|
77
|
+
export { APP_PAGE_USE_CACHE_MARKER, hasUseCacheLayoutMarker, hasUseCachePageMarker, isUseCacheFunctionReference, withUseCacheLayoutMarker, withUseCachePageMarker, withoutUseCacheSegmentMarker };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CacheLifeConfig } from "../cache-request-state.js";
|
|
2
|
+
//#region src/shims/internal/cache-context-accessor.d.ts
|
|
3
|
+
type CacheContextLike = {
|
|
4
|
+
tags: string[];
|
|
5
|
+
lifeConfigs: CacheLifeConfig[];
|
|
6
|
+
variant: string;
|
|
7
|
+
readRootParamNames?: Set<string>;
|
|
8
|
+
hasExplicitRevalidate: boolean;
|
|
9
|
+
hasExplicitExpire: boolean;
|
|
10
|
+
dynamicNestedCacheError: Error | undefined;
|
|
11
|
+
};
|
|
12
|
+
export declare function _registerCacheContextAccessor(fn: () => CacheContextLike | null): void;
|
|
13
|
+
export declare function getRegisteredCacheContext(): CacheContextLike | null;
|
|
14
|
+
/** Record a root-param dependency on the active public `"use cache"` scope. */
|
|
15
|
+
export declare function _recordUseCacheRootParamRead(name: string): void;
|
|
16
|
+
//#endregion
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/shims/internal/cache-context-accessor.ts
|
|
2
|
+
let getCacheContext = null;
|
|
3
|
+
function _registerCacheContextAccessor(fn) {
|
|
4
|
+
getCacheContext = fn;
|
|
5
|
+
}
|
|
6
|
+
function getRegisteredCacheContext() {
|
|
7
|
+
return getCacheContext?.() ?? null;
|
|
8
|
+
}
|
|
9
|
+
/** Record a root-param dependency on the active public `"use cache"` scope. */
|
|
10
|
+
function _recordUseCacheRootParamRead(name) {
|
|
11
|
+
const context = getRegisteredCacheContext();
|
|
12
|
+
if (context && context.variant !== "private") context.readRootParamNames?.add(name);
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { _recordUseCacheRootParamRead, _registerCacheContextAccessor, getRegisteredCacheContext };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { RenderRequestApiKind } from "../../server/cache-proof.js";
|
|
2
|
+
import { HeadersContext } from "../headers.js";
|
|
3
|
+
//#region src/shims/internal/headers-state.d.ts
|
|
4
|
+
export type HeadersAccessPhase = "render" | "action" | "route-handler";
|
|
5
|
+
/**
|
|
6
|
+
* Whether the current render has used a dynamic API. Unlike
|
|
7
|
+
* `dynamicUsageDetected`, nothing clears it, and one object is shared by every
|
|
8
|
+
* child scope of the request, so usage inside isolated scopes (such as the
|
|
9
|
+
* layout probe) stays visible to later readers.
|
|
10
|
+
*/
|
|
11
|
+
export type RenderDynamicLatch = {
|
|
12
|
+
dynamic: boolean;
|
|
13
|
+
listeners: Set<() => void>;
|
|
14
|
+
};
|
|
15
|
+
export declare function createRenderDynamicLatch(): RenderDynamicLatch;
|
|
16
|
+
export type VinextHeadersShimState = {
|
|
17
|
+
headersContext: HeadersContext | null;
|
|
18
|
+
dynamicUsageDetected: boolean;
|
|
19
|
+
renderDynamicLatch: RenderDynamicLatch;
|
|
20
|
+
renderRequestApiUsage: Set<RenderRequestApiKind>;
|
|
21
|
+
connectionProbe: ConnectionProbeState | null;
|
|
22
|
+
/** Error recorded by throwIfInsideCacheScope for dev diagnostics, persists even if caught by user code. */
|
|
23
|
+
invalidDynamicUsageError: unknown;
|
|
24
|
+
pendingSetCookies: string[];
|
|
25
|
+
draftModeCookieHeader: string | null;
|
|
26
|
+
phase: HeadersAccessPhase;
|
|
27
|
+
};
|
|
28
|
+
export type ConnectionProbeState = {
|
|
29
|
+
active: boolean;
|
|
30
|
+
dynamicUsageTarget: VinextHeadersShimState;
|
|
31
|
+
interrupted: boolean;
|
|
32
|
+
interrupt: () => void;
|
|
33
|
+
};
|
|
34
|
+
export type ConnectionProbeResult<T> = {
|
|
35
|
+
completed: true;
|
|
36
|
+
result: T;
|
|
37
|
+
} | {
|
|
38
|
+
completed: false;
|
|
39
|
+
};
|
|
40
|
+
export declare const headersShimAls: import("node:async_hooks").AsyncLocalStorage<VinextHeadersShimState>;
|
|
41
|
+
export declare function getHeadersShimState(): VinextHeadersShimState;
|
|
42
|
+
/**
|
|
43
|
+
* Dynamic usage flag — set when a component calls connection(), cookies(),
|
|
44
|
+
* headers(), or noStore() during rendering. When true, ISR caching is
|
|
45
|
+
* bypassed and the response gets Cache-Control: no-store.
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* Mark the current render as requiring dynamic (uncached) rendering.
|
|
49
|
+
* Called by connection(), cookies(), headers(), and noStore().
|
|
50
|
+
*/
|
|
51
|
+
export declare function markDynamicUsage(): void;
|
|
52
|
+
/** Whether the current render has used a dynamic API at any point so far. */
|
|
53
|
+
export declare function isRenderDynamicLatched(): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Call `listener` once when the current render first uses a dynamic API.
|
|
56
|
+
* Returns an unsubscribe function. The listener never runs if the render is
|
|
57
|
+
* already latched; check `isRenderDynamicLatched()` first.
|
|
58
|
+
*/
|
|
59
|
+
export declare function onRenderDynamicLatched(listener: () => void): () => void;
|
|
60
|
+
export declare function markRenderRequestApiUsage(kind: RenderRequestApiKind): void;
|
|
61
|
+
export declare function throwIfStaticGenerationAccessError(): void;
|
|
62
|
+
/** Whether work is executing inside a cache boundary that owns its reuse. */
|
|
63
|
+
export declare function isInsideAnyCacheScope(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Throw if the current execution is inside a "use cache" or unstable_cache()
|
|
66
|
+
* scope. Called by dynamic request APIs (headers, cookies, connection) to
|
|
67
|
+
* prevent request-specific data from being frozen into cached results.
|
|
68
|
+
*
|
|
69
|
+
* @param apiName - The name of the API being called (e.g. "connection()")
|
|
70
|
+
*/
|
|
71
|
+
export declare function throwIfInsideCacheScope(apiName: string): void;
|
|
72
|
+
export declare function getHeadersAccessPhase(): HeadersAccessPhase;
|
|
73
|
+
//#endregion
|