vinext 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build/css-url-assets.d.ts +1 -1
- package/dist/build/css-url-assets.js +9 -7
- package/dist/build/prerender.js +2 -1
- package/dist/cache/cache-adapters-virtual.js +1 -1
- package/dist/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +1 -1
- package/dist/entries/app-rsc-entry.js +24 -20
- package/dist/entries/pages-server-entry.js +2 -1
- package/dist/index.js +187 -146
- package/dist/plugins/css-data-url.js +30 -26
- package/dist/plugins/extensionless-dynamic-import.js +27 -24
- package/dist/plugins/import-meta-url.js +21 -15
- package/dist/plugins/instrumentation-client.js +1 -1
- package/dist/plugins/middleware-server-only.js +7 -6
- package/dist/plugins/og-assets.js +48 -46
- package/dist/plugins/optimize-imports.js +9 -3
- package/dist/plugins/remove-console.d.ts +7 -1
- package/dist/plugins/remove-console.js +4 -1
- package/dist/plugins/require-context.js +21 -20
- package/dist/plugins/strip-server-exports.d.ts +7 -1
- package/dist/plugins/strip-server-exports.js +4 -1
- package/dist/server/app-bfcache-identity.d.ts +26 -0
- package/dist/server/app-bfcache-identity.js +127 -0
- package/dist/server/app-browser-entry.js +14 -11
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-browser-state.d.ts +2 -21
- package/dist/server/app-browser-state.js +4 -128
- package/dist/server/app-browser-stream.js +1 -1
- package/dist/server/app-browser-visible-commit.js +3 -2
- package/dist/server/app-fallback-renderer.d.ts +1 -1
- package/dist/server/app-layout-param-observation.d.ts +1 -1
- package/dist/server/app-layout-param-observation.js +1 -1
- package/dist/server/app-middleware.js +2 -1
- package/dist/server/app-page-boundary-render.d.ts +1 -1
- package/dist/server/app-page-boundary.js +1 -1
- package/dist/server/app-page-cache-finalizer.d.ts +62 -0
- package/dist/server/app-page-cache-finalizer.js +122 -0
- package/dist/server/app-page-cache-render.d.ts +2 -2
- package/dist/server/app-page-cache-render.js +1 -1
- package/dist/server/app-page-cache.d.ts +2 -53
- package/dist/server/app-page-cache.js +5 -131
- package/dist/server/app-page-dispatch.d.ts +2 -2
- package/dist/server/app-page-dispatch.js +10 -8
- package/dist/server/app-page-probe.js +3 -2
- package/dist/server/app-page-render-observation.js +2 -2
- package/dist/server/app-page-render.d.ts +3 -3
- package/dist/server/app-page-render.js +3 -2
- package/dist/server/app-page-stream.d.ts +2 -9
- package/dist/server/app-page-stream.js +1 -35
- package/dist/server/app-request-context.d.ts +1 -2
- package/dist/server/app-request-context.js +2 -1
- package/dist/server/app-route-handler-dispatch.js +3 -2
- package/dist/server/app-route-handler-execution.d.ts +1 -1
- package/dist/server/app-route-handler-execution.js +1 -1
- package/dist/server/app-route-handler-response.d.ts +1 -1
- package/dist/server/app-router-entry.js +2 -1
- package/dist/server/app-rsc-handler.js +22 -16
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-server-action-execution.d.ts +1 -1
- package/dist/server/app-server-action-execution.js +5 -4
- package/dist/server/app-ssr-entry.d.ts +1 -1
- package/dist/server/app-ssr-entry.js +11 -9
- package/dist/server/app-ssr-router-instance.d.ts +6 -0
- package/dist/server/app-ssr-router-instance.js +24 -0
- package/dist/server/app-ssr-stream.js +1 -1
- package/dist/server/artifact-compatibility.js +1 -1
- package/dist/server/client-reuse-manifest.js +1 -1
- package/dist/server/defer-until-stream-consumed.d.ts +7 -0
- package/dist/server/defer-until-stream-consumed.js +34 -0
- package/dist/server/dev-server.js +1 -1
- package/dist/server/instrumentation.js +1 -1
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +1 -1
- package/dist/server/isr-decision.d.ts +1 -1
- package/dist/server/middleware-matcher.js +8 -6
- package/dist/server/middleware-runtime.js +2 -2
- package/dist/server/open-redirect.d.ts +12 -0
- package/dist/server/open-redirect.js +21 -0
- package/dist/server/pages-page-data.d.ts +1 -1
- package/dist/server/pages-page-response.d.ts +1 -1
- package/dist/server/pages-page-response.js +2 -2
- package/dist/server/prod-server.js +2 -1
- package/dist/server/request-pipeline.d.ts +1 -24
- package/dist/server/request-pipeline.js +1 -33
- package/dist/server/seed-cache.d.ts +1 -1
- package/dist/shims/cache-handler.d.ts +106 -0
- package/dist/shims/cache-handler.js +176 -0
- package/dist/shims/cache-request-state.d.ts +47 -0
- package/dist/shims/cache-request-state.js +126 -0
- package/dist/shims/cache-runtime.d.ts +2 -2
- package/dist/shims/cache-runtime.js +3 -14
- package/dist/shims/cache.d.ts +3 -231
- package/dist/shims/cache.js +17 -383
- package/dist/shims/cdn-cache.d.ts +1 -1
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/error-boundary-navigation.d.ts +7 -0
- package/dist/shims/error-boundary-navigation.js +44 -0
- package/dist/shims/error-boundary.js +10 -8
- package/dist/shims/error.js +2 -1
- package/dist/shims/fetch-cache.js +1 -1
- package/dist/shims/form.js +1 -1
- package/dist/shims/image.js +67 -9
- package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -0
- package/dist/shims/internal/app-page-props-cache-key.js +16 -0
- package/dist/shims/internal/navigation-untracked.js +2 -1
- package/dist/shims/layout-segment-context.d.ts +1 -1
- package/dist/shims/layout-segment-context.js +2 -1
- package/dist/shims/link.js +2 -2
- package/dist/shims/navigation-context-state.d.ts +40 -0
- package/dist/shims/navigation-context-state.js +116 -0
- package/dist/shims/navigation-errors.d.ts +55 -0
- package/dist/shims/navigation-errors.js +110 -0
- package/dist/shims/navigation-server.d.ts +3 -0
- package/dist/shims/navigation-server.js +3 -0
- package/dist/shims/navigation-state.d.ts +1 -2
- package/dist/shims/navigation-state.js +2 -1
- package/dist/shims/navigation.d.ts +3 -291
- package/dist/shims/navigation.js +14 -445
- package/dist/shims/navigation.react-server.d.ts +2 -2
- package/dist/shims/navigation.react-server.js +3 -1
- package/dist/shims/request-state-types.d.ts +3 -3
- package/dist/shims/script.js +1 -1
- package/dist/shims/slot.js +3 -1
- package/dist/shims/unified-request-context.d.ts +2 -2
- package/dist/utils/virtual-module.d.ts +5 -0
- package/dist/utils/virtual-module.js +0 -0
- package/package.json +5 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { VIRTUAL_MODULE_ID_RE } from "../utils/virtual-module.js";
|
|
1
2
|
import { collectBindingNames, forEachAstChild, hasRange, isAstRecord, isIdentifierNamed, nodeArray } from "./ast-utils.js";
|
|
2
3
|
import { tryRealpathSync } from "../build/ssr-manifest.js";
|
|
3
4
|
import path from "node:path";
|
|
@@ -32,18 +33,26 @@ function createImportMetaUrlPlugin(options) {
|
|
|
32
33
|
outputDirs = [config.build.outDir];
|
|
33
34
|
rootPaths = createRootPaths(root, { outputDirs });
|
|
34
35
|
},
|
|
35
|
-
transform
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
36
|
+
transform: {
|
|
37
|
+
filter: {
|
|
38
|
+
id: {
|
|
39
|
+
include: /\.(?:[cm]?[jt]s|[jt]sx)(?:\?.*)?$/,
|
|
40
|
+
exclude: [/[\\/]node_modules[\\/]/, VIRTUAL_MODULE_ID_RE]
|
|
41
|
+
},
|
|
42
|
+
code: /import\.meta(?:\.|\?\.)url|__filename|__dirname/
|
|
43
|
+
},
|
|
44
|
+
handler(code, id) {
|
|
45
|
+
const paths = getRootPaths();
|
|
46
|
+
if (!paths) return null;
|
|
47
|
+
const canonicalId = transformableModuleCanonicalId(cleanModuleId(id), paths);
|
|
48
|
+
if (!canonicalId) return null;
|
|
49
|
+
const rewritten = rewriteCanonicalSourceIdentity(code, canonicalId, paths, this.environment?.name === "client" ? "client" : "server");
|
|
50
|
+
if (!rewritten) return null;
|
|
51
|
+
return {
|
|
52
|
+
code: rewritten.code,
|
|
53
|
+
map: rewritten.map
|
|
54
|
+
};
|
|
55
|
+
}
|
|
47
56
|
}
|
|
48
57
|
};
|
|
49
58
|
}
|
|
@@ -120,9 +129,6 @@ function mayContainImportMetaUrl(code) {
|
|
|
120
129
|
function mayContainServerCjsGlobal(code) {
|
|
121
130
|
return code.includes("__filename") || code.includes("__dirname");
|
|
122
131
|
}
|
|
123
|
-
function mayContainSourceIdentityToken(code) {
|
|
124
|
-
return mayContainImportMetaUrl(code) || mayContainServerCjsGlobal(code);
|
|
125
|
-
}
|
|
126
132
|
function excludedRelativePrefixes(canonicalRoot, normalizedRoot, options) {
|
|
127
133
|
const prefixes = new Set([
|
|
128
134
|
".next",
|
|
@@ -8,7 +8,7 @@ function createInstrumentationClientTransformPlugin(getInstrumentationClientPath
|
|
|
8
8
|
transform(code, id) {
|
|
9
9
|
const instrumentationClientPath = getInstrumentationClientPath();
|
|
10
10
|
if (!instrumentationClientPath) return null;
|
|
11
|
-
if (normalizePath(id.split("?", 1)[0]) !==
|
|
11
|
+
if (normalizePath(id.split("?", 1)[0]) !== instrumentationClientPath) return null;
|
|
12
12
|
if (code.includes("__vinextInstrumentationClientStart")) return null;
|
|
13
13
|
const ast = parseAst(code);
|
|
14
14
|
let insertPos = 0;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizePathSeparators } from "../utils/path.js";
|
|
1
2
|
//#region src/plugins/middleware-server-only.ts
|
|
2
3
|
/**
|
|
3
4
|
* Allow `import 'server-only'` from middleware (and any module reachable
|
|
@@ -44,16 +45,16 @@
|
|
|
44
45
|
*/
|
|
45
46
|
function createMiddlewareServerOnlyPlugin(options) {
|
|
46
47
|
const tainted = /* @__PURE__ */ new Set();
|
|
48
|
+
function canonicalizeId(id) {
|
|
49
|
+
const queryIndex = id.indexOf("?");
|
|
50
|
+
return normalizePathSeparators(queryIndex === -1 ? id : id.slice(0, queryIndex));
|
|
51
|
+
}
|
|
47
52
|
function isTainted(id) {
|
|
48
53
|
if (!id) return false;
|
|
49
|
-
|
|
50
|
-
const queryIndex = id.indexOf("?");
|
|
51
|
-
if (queryIndex !== -1) return tainted.has(id.slice(0, queryIndex));
|
|
52
|
-
return false;
|
|
54
|
+
return tainted.has(canonicalizeId(id));
|
|
53
55
|
}
|
|
54
56
|
function addTainted(id) {
|
|
55
|
-
|
|
56
|
-
tainted.add(queryIndex === -1 ? id : id.slice(0, queryIndex));
|
|
57
|
+
tainted.add(canonicalizeId(id));
|
|
57
58
|
}
|
|
58
59
|
return {
|
|
59
60
|
name: "vinext:middleware-server-only",
|
|
@@ -25,54 +25,56 @@ function createOgInlineFetchAssetsPlugin() {
|
|
|
25
25
|
buildStart() {
|
|
26
26
|
if (isBuild) cache.clear();
|
|
27
27
|
},
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
28
|
+
transform: {
|
|
29
|
+
filter: { code: "import.meta.url" },
|
|
30
|
+
async handler(code, id) {
|
|
31
|
+
const useCache = isBuild;
|
|
32
|
+
const moduleDir = path.dirname(id);
|
|
33
|
+
let newCode = code;
|
|
34
|
+
let didReplace = false;
|
|
35
|
+
const readAsBase64 = async (absPath) => {
|
|
36
|
+
const cached = useCache ? cache.get(absPath) : void 0;
|
|
37
|
+
if (cached !== void 0) return cached;
|
|
38
|
+
try {
|
|
39
|
+
const b64 = (await fs.promises.readFile(absPath)).toString("base64");
|
|
40
|
+
if (useCache) cache.set(absPath, b64);
|
|
41
|
+
return b64;
|
|
42
|
+
} catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
if (code.includes("fetch(")) for (const match of code.matchAll(/fetch\(\s*new URL\(\s*(["'])(\.[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)(?:\.then\(\s*(?:function\s*\([^)]*\)|\([^)]*\)\s*=>)\s*\{?\s*return\s+[^.]+\.arrayBuffer\(\)\s*;?\s*\}?\s*,?\s*\)|\.then\(\s*\([^)]*\)\s*=>\s*[^.]+\.arrayBuffer\(\)\s*,?\s*\))/g)) {
|
|
47
|
+
const fullMatch = match[0];
|
|
48
|
+
const relPath = match[2];
|
|
49
|
+
const fileBase64 = await readAsBase64(path.resolve(moduleDir, relPath));
|
|
50
|
+
if (fileBase64 === null) continue;
|
|
51
|
+
const inlined = [
|
|
52
|
+
`(function(){`,
|
|
53
|
+
`var b=${JSON.stringify(fileBase64)};`,
|
|
54
|
+
`var r=atob(b);`,
|
|
55
|
+
`var a=new Uint8Array(r.length);`,
|
|
56
|
+
`for(var i=0;i<r.length;i++)a[i]=r.charCodeAt(i);`,
|
|
57
|
+
`return Promise.resolve(a.buffer);`,
|
|
58
|
+
`})()`
|
|
59
|
+
].join("");
|
|
60
|
+
newCode = newCode.replaceAll(fullMatch, inlined);
|
|
61
|
+
didReplace = true;
|
|
43
62
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
].join("");
|
|
59
|
-
newCode = newCode.replaceAll(fullMatch, inlined);
|
|
60
|
-
didReplace = true;
|
|
61
|
-
}
|
|
62
|
-
if (code.includes("readFileSync(")) for (const match of newCode.matchAll(/[a-zA-Z_$][a-zA-Z0-9_$]*\.readFileSync\(\s*(?:[a-zA-Z_$][a-zA-Z0-9_$]*\.)?fileURLToPath\(\s*new URL\(\s*(["'])(\.[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)\s*\)/g)) {
|
|
63
|
-
const fullMatch = match[0];
|
|
64
|
-
const relPath = match[2];
|
|
65
|
-
const fileBase64 = await readAsBase64(path.resolve(moduleDir, relPath));
|
|
66
|
-
if (fileBase64 === null) continue;
|
|
67
|
-
const inlined = `Buffer.from(${JSON.stringify(fileBase64)},"base64")`;
|
|
68
|
-
newCode = newCode.replaceAll(fullMatch, inlined);
|
|
69
|
-
didReplace = true;
|
|
63
|
+
if (code.includes("readFileSync(")) for (const match of newCode.matchAll(/[a-zA-Z_$][a-zA-Z0-9_$]*\.readFileSync\(\s*(?:[a-zA-Z_$][a-zA-Z0-9_$]*\.)?fileURLToPath\(\s*new URL\(\s*(["'])(\.[^"']+)\1\s*,\s*import\.meta\.url\s*\)\s*\)\s*\)/g)) {
|
|
64
|
+
const fullMatch = match[0];
|
|
65
|
+
const relPath = match[2];
|
|
66
|
+
const fileBase64 = await readAsBase64(path.resolve(moduleDir, relPath));
|
|
67
|
+
if (fileBase64 === null) continue;
|
|
68
|
+
const inlined = `Buffer.from(${JSON.stringify(fileBase64)},"base64")`;
|
|
69
|
+
newCode = newCode.replaceAll(fullMatch, inlined);
|
|
70
|
+
didReplace = true;
|
|
71
|
+
}
|
|
72
|
+
if (!didReplace) return null;
|
|
73
|
+
return {
|
|
74
|
+
code: newCode,
|
|
75
|
+
map: null
|
|
76
|
+
};
|
|
70
77
|
}
|
|
71
|
-
if (!didReplace) return null;
|
|
72
|
-
return {
|
|
73
|
-
code: newCode,
|
|
74
|
-
map: null
|
|
75
|
-
};
|
|
76
78
|
}
|
|
77
79
|
};
|
|
78
80
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizePathSeparators } from "../utils/path.js";
|
|
2
2
|
import { escapeRegExp } from "../utils/regex.js";
|
|
3
|
+
import { VIRTUAL_MODULE_ID_RE } from "../utils/virtual-module.js";
|
|
3
4
|
import { getAstName } from "./ast-utils.js";
|
|
4
5
|
import { createRequire } from "node:module";
|
|
5
6
|
import path from "node:path";
|
|
@@ -445,12 +446,17 @@ function createOptimizeImportsPlugin(getNextConfig, getRoot) {
|
|
|
445
446
|
return await this.resolve(source, barrelEntry, { skipSelf: true }) ?? void 0;
|
|
446
447
|
},
|
|
447
448
|
transform: {
|
|
448
|
-
filter: {
|
|
449
|
-
|
|
449
|
+
filter: {
|
|
450
|
+
id: {
|
|
451
|
+
include: /\.(tsx?|jsx?|mjs)$/,
|
|
452
|
+
exclude: VIRTUAL_MODULE_ID_RE
|
|
453
|
+
},
|
|
454
|
+
code: /\bimport\b[\s\S]*\bfrom\b/
|
|
455
|
+
},
|
|
456
|
+
async handler(code) {
|
|
450
457
|
const env = this.environment;
|
|
451
458
|
if (env?.name === "client") return null;
|
|
452
459
|
const preferReactServer = env?.name === "rsc";
|
|
453
|
-
if (id.startsWith("\0")) return null;
|
|
454
460
|
const packages = optimizedPackages;
|
|
455
461
|
if (!hasOptimizedImportSource(code)) return null;
|
|
456
462
|
let ast;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import MagicString from "magic-string";
|
|
2
|
+
|
|
1
3
|
//#region src/plugins/remove-console.d.ts
|
|
2
4
|
type RemoveConsoleConfig = boolean | {
|
|
3
5
|
exclude: string[];
|
|
4
6
|
};
|
|
7
|
+
type RemoveConsoleResult = {
|
|
8
|
+
code: string;
|
|
9
|
+
map: ReturnType<MagicString["generateMap"]>;
|
|
10
|
+
};
|
|
5
11
|
/**
|
|
6
12
|
* Walk the AST body looking for expression statements whose expression is a
|
|
7
13
|
* CallExpression with a callee of `console.<identifier>`. When found, check
|
|
@@ -10,6 +16,6 @@ type RemoveConsoleConfig = boolean | {
|
|
|
10
16
|
*
|
|
11
17
|
* Returns `null` if no console calls are removed.
|
|
12
18
|
*/
|
|
13
|
-
declare function removeConsoleCalls(code: string, config: RemoveConsoleConfig):
|
|
19
|
+
declare function removeConsoleCalls(code: string, config: RemoveConsoleConfig): RemoveConsoleResult | null;
|
|
14
20
|
//#endregion
|
|
15
21
|
export { removeConsoleCalls };
|
|
@@ -168,7 +168,10 @@ function removeConsoleCalls(code, config) {
|
|
|
168
168
|
}
|
|
169
169
|
for (const node of ast.body) walk(node);
|
|
170
170
|
if (!changed) return null;
|
|
171
|
-
return
|
|
171
|
+
return {
|
|
172
|
+
code: s.toString(),
|
|
173
|
+
map: s.generateMap({ hires: "boundary" })
|
|
174
|
+
};
|
|
172
175
|
}
|
|
173
176
|
//#endregion
|
|
174
177
|
export { removeConsoleCalls };
|
|
@@ -16,30 +16,31 @@ function createRequireContextPlugin() {
|
|
|
16
16
|
return {
|
|
17
17
|
name: "vinext:require-context",
|
|
18
18
|
enforce: "pre",
|
|
19
|
-
transform
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
transform: {
|
|
20
|
+
filter: {
|
|
21
|
+
id: /\.(?:[cm]?[jt]s|[jt]sx)(?:\?.*)?$/i,
|
|
22
|
+
code: /\brequire\b[\s\S]*\.context/
|
|
23
|
+
},
|
|
24
|
+
handler(code, id) {
|
|
25
|
+
const lang = langForId(id);
|
|
26
|
+
let ast;
|
|
27
|
+
try {
|
|
28
|
+
ast = parseAst(code, { lang });
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
const calls = collectRequireContextCalls(ast);
|
|
33
|
+
if (calls.length === 0) return null;
|
|
34
|
+
const output = new MagicString(code);
|
|
35
|
+
for (const call of calls) output.overwrite(call.range.start, call.range.end, buildReplacement(call));
|
|
36
|
+
return {
|
|
37
|
+
code: output.toString(),
|
|
38
|
+
map: output.generateMap({ hires: "boundary" })
|
|
39
|
+
};
|
|
28
40
|
}
|
|
29
|
-
const calls = collectRequireContextCalls(ast);
|
|
30
|
-
if (calls.length === 0) return null;
|
|
31
|
-
const output = new MagicString(code);
|
|
32
|
-
for (const call of calls) output.overwrite(call.range.start, call.range.end, buildReplacement(call));
|
|
33
|
-
return {
|
|
34
|
-
code: output.toString(),
|
|
35
|
-
map: output.generateMap({ hires: "boundary" })
|
|
36
|
-
};
|
|
37
41
|
}
|
|
38
42
|
};
|
|
39
43
|
}
|
|
40
|
-
function mayContainRequireContext(code) {
|
|
41
|
-
return code.includes("require") && code.includes(".context");
|
|
42
|
-
}
|
|
43
44
|
function langForId(id) {
|
|
44
45
|
const clean = id.split("?", 1)[0];
|
|
45
46
|
const dot = clean.lastIndexOf(".");
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import MagicString from "magic-string";
|
|
2
|
+
|
|
1
3
|
//#region src/plugins/strip-server-exports.d.ts
|
|
2
4
|
declare function hasServerExportCandidate(code: string): boolean;
|
|
3
5
|
declare function hasExportAllCandidate(code: string): boolean;
|
|
4
6
|
declare function validatePageExports(code: string): void;
|
|
7
|
+
type StripServerExportsResult = {
|
|
8
|
+
code: string;
|
|
9
|
+
map: ReturnType<MagicString["generateMap"]>;
|
|
10
|
+
};
|
|
5
11
|
/**
|
|
6
12
|
* Strip server-only Pages Router data-fetching exports and their unique
|
|
7
13
|
* dependency graph from browser bundles.
|
|
@@ -10,6 +16,6 @@ declare function validatePageExports(code: string): void;
|
|
|
10
16
|
* - test/unit/babel-plugin-next-ssg-transform.test.ts
|
|
11
17
|
* - crates/next-custom-transforms/src/transforms/strip_page_exports.rs
|
|
12
18
|
*/
|
|
13
|
-
declare function stripServerExports(code: string):
|
|
19
|
+
declare function stripServerExports(code: string): StripServerExportsResult | null;
|
|
14
20
|
//#endregion
|
|
15
21
|
export { hasExportAllCandidate, hasServerExportCandidate, stripServerExports, validatePageExports };
|
|
@@ -509,7 +509,10 @@ function stripServerExports(code) {
|
|
|
509
509
|
string.overwrite(edit.start, edit.end, edit.replacement);
|
|
510
510
|
lastStart = edit.start;
|
|
511
511
|
}
|
|
512
|
-
return
|
|
512
|
+
return {
|
|
513
|
+
code: string.toString(),
|
|
514
|
+
map: string.generateMap({ hires: "boundary" })
|
|
515
|
+
};
|
|
513
516
|
}
|
|
514
517
|
//#endregion
|
|
515
518
|
export { hasExportAllCandidate, hasServerExportCandidate, stripServerExports, validatePageExports };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AppElements } from "./app-elements-wire.js";
|
|
2
|
+
import { BfcacheIdMap } from "./app-history-state.js";
|
|
3
|
+
|
|
4
|
+
//#region src/server/app-bfcache-identity.d.ts
|
|
5
|
+
type BfcacheStateKeyMap = Readonly<Record<string, string>>;
|
|
6
|
+
declare function createInitialBfcacheIdMap(elements: AppElements): BfcacheIdMap;
|
|
7
|
+
declare function createBfcacheSegmentStateKeyMap(options: {
|
|
8
|
+
elements: AppElements;
|
|
9
|
+
pathname: string;
|
|
10
|
+
}): BfcacheStateKeyMap;
|
|
11
|
+
declare function createNextBfcacheIdMap(options: {
|
|
12
|
+
current: BfcacheIdMap;
|
|
13
|
+
currentElements: AppElements;
|
|
14
|
+
currentPathname: string;
|
|
15
|
+
elements: AppElements;
|
|
16
|
+
nextPathname: string;
|
|
17
|
+
restored?: BfcacheIdMap | null;
|
|
18
|
+
reuseCurrent?: boolean;
|
|
19
|
+
}): BfcacheIdMap;
|
|
20
|
+
declare function preserveBfcacheIdsForMergedElements(options: {
|
|
21
|
+
elements: AppElements;
|
|
22
|
+
next: BfcacheIdMap;
|
|
23
|
+
previous: BfcacheIdMap;
|
|
24
|
+
}): BfcacheIdMap;
|
|
25
|
+
//#endregion
|
|
26
|
+
export { BfcacheStateKeyMap, createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { countConsumedPathnameSegments, isInvisibleSegment, normalizePathnameForRouteMatch, splitPathSegments } from "../routing/utils.js";
|
|
2
|
+
import { normalizePath } from "./normalize-path.js";
|
|
3
|
+
import { AppElementsWire } from "./app-elements-wire.js";
|
|
4
|
+
import "./app-elements.js";
|
|
5
|
+
import "./app-bfcache-id.js";
|
|
6
|
+
import { isBfcacheSegmentId } from "./app-history-state.js";
|
|
7
|
+
//#region src/server/app-bfcache-identity.ts
|
|
8
|
+
let nextBfcacheId = 0;
|
|
9
|
+
function rememberBfcacheId(value) {
|
|
10
|
+
const match = /^_b_(\d+)_$/.exec(value);
|
|
11
|
+
if (!match) return;
|
|
12
|
+
nextBfcacheId = Math.max(nextBfcacheId, Number(match[1]));
|
|
13
|
+
}
|
|
14
|
+
function mintBfcacheId() {
|
|
15
|
+
nextBfcacheId += 1;
|
|
16
|
+
return `_b_${nextBfcacheId}_`;
|
|
17
|
+
}
|
|
18
|
+
function getVisibleTreePathSegments(treePath) {
|
|
19
|
+
return splitPathSegments(treePath).filter((segment) => !isInvisibleSegment(segment));
|
|
20
|
+
}
|
|
21
|
+
function getTreePathIdentityPrefix(pathname, treePath) {
|
|
22
|
+
const pathnameSegments = splitPathSegments(pathname);
|
|
23
|
+
const consumedPathnameSegments = countConsumedPathnameSegments(getVisibleTreePathSegments(treePath), pathnameSegments.length);
|
|
24
|
+
if (consumedPathnameSegments === 0) return "/";
|
|
25
|
+
return `/${pathnameSegments.slice(0, consumedPathnameSegments).join("/")}`;
|
|
26
|
+
}
|
|
27
|
+
function readAppElementsMetadata(elements) {
|
|
28
|
+
let metadata;
|
|
29
|
+
try {
|
|
30
|
+
metadata = AppElementsWire.readMetadata(elements);
|
|
31
|
+
} catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const slotBindingsBySlotId = /* @__PURE__ */ new Map();
|
|
35
|
+
for (const binding of metadata.slotBindings) slotBindingsBySlotId.set(binding.slotId, binding);
|
|
36
|
+
return {
|
|
37
|
+
metadata,
|
|
38
|
+
slotBindingsBySlotId
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function createActiveSlotIdentity(id, parsed) {
|
|
42
|
+
const activeSlotBinding = parsed?.slotBindingsBySlotId.get(id);
|
|
43
|
+
if (activeSlotBinding?.activeRouteId != null) return `${id}@${activeSlotBinding.activeRouteId}`;
|
|
44
|
+
const interception = parsed?.metadata.interception;
|
|
45
|
+
if (interception?.slotId !== id) return null;
|
|
46
|
+
return `${id}@${interception.targetRouteId}`;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Derive BFCache identity from AppElements wire keys. Keep wire-key parsing
|
|
50
|
+
* contained here until vinext has a route-manifest authority equivalent to
|
|
51
|
+
* Next.js CacheNode or segment-cache state.
|
|
52
|
+
*/
|
|
53
|
+
function createBfcacheSegmentIdentity(id, options) {
|
|
54
|
+
const parsed = AppElementsWire.parseElementKey(id);
|
|
55
|
+
if (!parsed) return null;
|
|
56
|
+
if (parsed.kind === "page") return `${id}@${options.pathname}`;
|
|
57
|
+
if (parsed.kind === "slot") {
|
|
58
|
+
const activeSlotIdentity = createActiveSlotIdentity(id, options.metadata);
|
|
59
|
+
if (activeSlotIdentity !== null) return activeSlotIdentity;
|
|
60
|
+
return `${id}@${getTreePathIdentityPrefix(options.pathname, parsed.treePath)}`;
|
|
61
|
+
}
|
|
62
|
+
if (parsed.kind === "layout" || parsed.kind === "template") return `${id}@${getTreePathIdentityPrefix(options.pathname, parsed.treePath)}`;
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
function collectBfcacheSegmentIds(elements, parsed) {
|
|
66
|
+
const ids = new Set(Object.keys(elements));
|
|
67
|
+
const metadata = parsed === void 0 ? readAppElementsMetadata(elements) : parsed;
|
|
68
|
+
for (const layoutId of metadata?.metadata.layoutIds ?? []) ids.add(layoutId);
|
|
69
|
+
return Array.from(ids).filter(isBfcacheSegmentId);
|
|
70
|
+
}
|
|
71
|
+
function createInitialBfcacheIdMap(elements) {
|
|
72
|
+
const ids = {};
|
|
73
|
+
for (const id of collectBfcacheSegmentIds(elements)) ids[id] = "0";
|
|
74
|
+
return ids;
|
|
75
|
+
}
|
|
76
|
+
function normalizeBfcachePathname(pathname) {
|
|
77
|
+
const normalized = normalizePath(normalizePathnameForRouteMatch(pathname));
|
|
78
|
+
return normalized.length > 1 ? normalized.replace(/\/$/, "") : normalized;
|
|
79
|
+
}
|
|
80
|
+
function createBfcacheSegmentStateKeyMap(options) {
|
|
81
|
+
const metadata = readAppElementsMetadata(options.elements);
|
|
82
|
+
const normalizedPathname = normalizeBfcachePathname(options.pathname);
|
|
83
|
+
const stateKeys = {};
|
|
84
|
+
for (const id of collectBfcacheSegmentIds(options.elements, metadata)) {
|
|
85
|
+
const stateKey = createBfcacheSegmentIdentity(id, {
|
|
86
|
+
metadata,
|
|
87
|
+
pathname: normalizedPathname
|
|
88
|
+
});
|
|
89
|
+
if (stateKey !== null) stateKeys[id] = stateKey;
|
|
90
|
+
}
|
|
91
|
+
return stateKeys;
|
|
92
|
+
}
|
|
93
|
+
function createNextBfcacheIdMap(options) {
|
|
94
|
+
const current = options.reuseCurrent === false ? {} : options.current;
|
|
95
|
+
for (const value of Object.values(current)) rememberBfcacheId(value);
|
|
96
|
+
for (const value of Object.values(options.restored ?? {})) rememberBfcacheId(value);
|
|
97
|
+
const currentMetadata = readAppElementsMetadata(options.currentElements);
|
|
98
|
+
const nextMetadata = readAppElementsMetadata(options.elements);
|
|
99
|
+
const currentPathname = normalizeBfcachePathname(options.currentPathname);
|
|
100
|
+
const nextPathname = normalizeBfcachePathname(options.nextPathname);
|
|
101
|
+
const ids = {};
|
|
102
|
+
for (const id of collectBfcacheSegmentIds(options.elements, nextMetadata)) {
|
|
103
|
+
const currentValue = createBfcacheSegmentIdentity(id, {
|
|
104
|
+
metadata: currentMetadata,
|
|
105
|
+
pathname: currentPathname
|
|
106
|
+
}) === createBfcacheSegmentIdentity(id, {
|
|
107
|
+
metadata: nextMetadata,
|
|
108
|
+
pathname: nextPathname
|
|
109
|
+
}) ? current[id] : void 0;
|
|
110
|
+
const value = options.restored?.[id] ?? currentValue ?? mintBfcacheId();
|
|
111
|
+
ids[id] = value;
|
|
112
|
+
rememberBfcacheId(value);
|
|
113
|
+
}
|
|
114
|
+
return ids;
|
|
115
|
+
}
|
|
116
|
+
function preserveBfcacheIdsForMergedElements(options) {
|
|
117
|
+
const ids = {};
|
|
118
|
+
for (const id of collectBfcacheSegmentIds(options.elements)) {
|
|
119
|
+
const value = options.next[id] ?? options.previous[id];
|
|
120
|
+
if (value === void 0) continue;
|
|
121
|
+
ids[id] = value;
|
|
122
|
+
rememberBfcacheId(value);
|
|
123
|
+
}
|
|
124
|
+
return ids;
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
export { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements };
|
|
@@ -6,25 +6,28 @@ import { getMountedSlotIdsHeader, resolveVisitedResponseInterceptionContext } fr
|
|
|
6
6
|
import { AppRouterContext } from "../shims/internal/app-router-context.js";
|
|
7
7
|
import { installWindowNext, setWindowNextInternalSourcePage } from "../client/window-next.js";
|
|
8
8
|
import { retryScrollTo, scrollToHashTargetOnNextFrame } from "../shims/hash-scroll.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { clearAppNavigationFailureTarget, installAppNavigationFailureListeners } from "../client/app-nav-failure-handler.js";
|
|
12
|
-
import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
|
|
13
|
-
import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
|
|
14
|
-
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
|
|
15
|
-
import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
|
|
16
|
-
import { navigationPlanner } from "./navigation-planner.js";
|
|
17
|
-
import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
|
|
18
|
-
import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, decodeRedirectError, getBfcacheIdMapContext, getClientNavigationRenderContext, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, isRedirectError, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setNavigationContext, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
9
|
+
import { getBfcacheIdMapContext, setNavigationContext } from "../shims/navigation-context-state.js";
|
|
10
|
+
import { decodeRedirectError, isRedirectError } from "../shims/navigation-errors.js";
|
|
19
11
|
import DefaultGlobalError from "../shims/default-global-error.js";
|
|
12
|
+
import { clearAppNavigationFailureTarget, installAppNavigationFailureListeners } from "../client/app-nav-failure-handler.js";
|
|
20
13
|
import { DevRecoveryBoundary, GlobalErrorBoundary, RedirectBoundary } from "../shims/error-boundary.js";
|
|
14
|
+
import { beginAppRouterScrollIntent, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
|
|
21
15
|
import { AppRouterScrollCommitProvider } from "../shims/app-router-scroll.js";
|
|
22
16
|
import { BfcacheStateKeyMapContext, ElementsContext, Slot } from "../shims/slot.js";
|
|
17
|
+
import { VINEXT_RSC_COMPATIBILITY_ID_HEADER, VINEXT_RSC_CONTENT_TYPE, createRscRequestHeaders, createRscRequestUrl, createServerActionRequestUrl, getVinextRscCompatibilityId } from "./app-rsc-cache-busting.js";
|
|
18
|
+
import { getNavigationRuntime, registerNavigationRuntimeBootstrap, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
19
|
+
import { notifyAppRouterTransitionStart } from "../client/instrumentation-client-state.js";
|
|
23
20
|
import "../client/instrumentation-client.js";
|
|
21
|
+
import { readHistoryStatePreviousNextUrl } from "./app-history-state.js";
|
|
22
|
+
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
|
|
24
23
|
import { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, createServerActionResultFacts, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, shouldClearClientNavigationCachesForServerActionResult } from "./app-browser-action-result.js";
|
|
25
24
|
import { createClientReuseManifestHeaderFromVisibleAppState } from "./app-browser-client-reuse-manifest.js";
|
|
25
|
+
import { resolveManifestNavigationInterceptionContext, resolveMiddlewareRewriteNavigationInterceptionContext } from "./app-browser-interception-context.js";
|
|
26
|
+
import { AppBrowserMpaNavigationScheduler } from "./app-browser-mpa-navigation.js";
|
|
27
|
+
import { navigationPlanner } from "./navigation-planner.js";
|
|
28
|
+
import { __basePath, appRouterInstance, commitClientNavigationState, consumePrefetchResponseForNavigation, createCachedRscResponseSnapshot, createClientNavigationRenderSnapshot, createSnapshotPathAndSearch, getClientNavigationRenderContext, getPrefetchCache, hasPrefetchCacheEntryForNavigation, invalidatePrefetchCache, pushHistoryStateWithoutNotify, replaceClientParamsWithoutNotify, replaceHistoryStateWithoutNotify, resolvePrefetchCacheEntryMountedSlotsHeader, restoreRscResponse, saveScrollPosition, setClientParams, setMountedSlotsHeader, setPendingPathname, useRouter } from "../shims/navigation.js";
|
|
26
29
|
import { chunksToReadableStream, createProgressiveRscStream, getVinextBrowserGlobal } from "./app-browser-stream.js";
|
|
27
|
-
import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN,
|
|
30
|
+
import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN, isCacheRestorableAppPayloadMetadata, resolveInterceptionContextFromPreviousNextUrl, resolveServerActionRequestState } from "./app-browser-state.js";
|
|
28
31
|
import { clearHardNavigationLoopGuard, createAppBrowserNavigationController, createBasePathStrippedPathAndSearch } from "./app-browser-navigation-controller.js";
|
|
29
32
|
import { applyServerActionResultDecision } from "./app-browser-server-action-navigation.js";
|
|
30
33
|
import { consumeInitialFormState, createVinextHydrateRootOptions, hydrateRootInTransition } from "./app-browser-hydration.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { clearAppNavigationFailureTarget, getAppNavigationFailureTarget } from "../client/app-nav-failure-handler.js";
|
|
3
3
|
import { claimAppRouterScrollIntentForCommit, consumeAppRouterScrollIntent } from "../shims/app-router-scroll-state.js";
|
|
4
|
-
import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
|
|
5
4
|
import { shouldScheduleRefreshForDiscardedServerAction } from "./app-browser-action-result.js";
|
|
5
|
+
import { activateNavigationSnapshot, clearPendingPathname, commitClientNavigationState, createSnapshotPathAndSearch } from "../shims/navigation.js";
|
|
6
6
|
import { FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN, createPendingNavigationCommit } from "./app-browser-state.js";
|
|
7
7
|
import { applyApprovedVisibleCommit, approveHmrVisibleCommit, approvePendingNavigationCommit, resolveAndClassifyNavigationCommit } from "./app-browser-visible-commit.js";
|
|
8
8
|
import { startTransition, useInsertionEffect, useLayoutEffect } from "react";
|
|
@@ -3,8 +3,9 @@ import { CacheEntryReuseProof } from "./cache-proof.js";
|
|
|
3
3
|
import { AppElements, AppElementsInterception, AppElementsSlotBinding, LayoutFlags } from "./app-elements-wire.js";
|
|
4
4
|
import { NavigationTrace } from "./navigation-trace.js";
|
|
5
5
|
import { OperationLane } from "./operation-token.js";
|
|
6
|
-
import { ClientNavigationRenderSnapshot } from "../shims/navigation.js";
|
|
7
6
|
import { BfcacheIdMap, HistoryTraversalIntent, createHistoryStateWithNavigationMetadata, createHistoryStateWithPreviousNextUrl, isHistoryStateBfcacheVersionCurrent, readHistoryStateBfcacheIds, readHistoryStateBfcacheVersion, readHistoryStatePreviousNextUrl, readHistoryStateTraversalIndex, resolveHistoryTraversalIntent } from "./app-history-state.js";
|
|
7
|
+
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap, createNextBfcacheIdMap, preserveBfcacheIdsForMergedElements } from "./app-bfcache-identity.js";
|
|
8
|
+
import { ClientNavigationRenderSnapshot } from "../shims/navigation.js";
|
|
8
9
|
|
|
9
10
|
//#region src/server/app-browser-state.d.ts
|
|
10
11
|
type OperationRecordBase = {
|
|
@@ -70,7 +71,6 @@ type AppNavigationPayloadOrigin = Readonly<{
|
|
|
70
71
|
} | {
|
|
71
72
|
origin: "visited-cache";
|
|
72
73
|
}>;
|
|
73
|
-
type BfcacheStateKeyMap = Readonly<Record<string, string>>;
|
|
74
74
|
declare const FRESH_APP_NAVIGATION_PAYLOAD_ORIGIN: AppNavigationPayloadOrigin;
|
|
75
75
|
declare const VISITED_CACHE_APP_NAVIGATION_PAYLOAD_ORIGIN: AppNavigationPayloadOrigin;
|
|
76
76
|
type PendingNavigationCommitDisposition = "dispatch" | "hard-navigate" | "skip";
|
|
@@ -91,25 +91,6 @@ type NonDispatchPendingNavigationCommitDispositionDecision = {
|
|
|
91
91
|
trace: NavigationTrace;
|
|
92
92
|
};
|
|
93
93
|
type PendingNavigationCommitDispositionDecision = DispatchPendingNavigationCommitDispositionDecision | NonDispatchPendingNavigationCommitDispositionDecision;
|
|
94
|
-
declare function createInitialBfcacheIdMap(elements: AppElements): BfcacheIdMap;
|
|
95
|
-
declare function createBfcacheSegmentStateKeyMap(options: {
|
|
96
|
-
elements: AppElements;
|
|
97
|
-
pathname: string;
|
|
98
|
-
}): BfcacheStateKeyMap;
|
|
99
|
-
declare function createNextBfcacheIdMap(options: {
|
|
100
|
-
current: BfcacheIdMap;
|
|
101
|
-
currentElements: AppElements;
|
|
102
|
-
currentPathname: string;
|
|
103
|
-
elements: AppElements;
|
|
104
|
-
nextPathname: string;
|
|
105
|
-
restored?: BfcacheIdMap | null;
|
|
106
|
-
reuseCurrent?: boolean;
|
|
107
|
-
}): BfcacheIdMap;
|
|
108
|
-
declare function preserveBfcacheIdsForMergedElements(options: {
|
|
109
|
-
elements: AppElements;
|
|
110
|
-
next: BfcacheIdMap;
|
|
111
|
-
previous: BfcacheIdMap;
|
|
112
|
-
}): BfcacheIdMap;
|
|
113
94
|
declare function isCacheRestorableAppPayloadMetadata(metadata: CacheRestorableAppPayloadMetadata): metadata is CacheRestorableAppPayloadMetadata & {
|
|
114
95
|
cacheEntryReuseProof: CacheEntryReuseProof;
|
|
115
96
|
};
|