dinou 6.1.1 → 7.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/CHANGELOG.md +106 -0
- package/README.md +9352 -1081
- package/cli.js +314 -91
- package/dinou/adapters/bun.js +62 -0
- package/dinou/adapters/cloudflare.js +65 -0
- package/dinou/adapters/deno.js +48 -0
- package/dinou/adapters/netlify.js +85 -0
- package/dinou/adapters/node.mjs +31 -0
- package/dinou/bun/build.mjs +1077 -0
- package/dinou/cloudflare/build.mjs +1121 -0
- package/dinou/cloudflare/shims/child_process.js +14 -0
- package/dinou/cloudflare/shims/empty.js +2 -0
- package/dinou/cloudflare/shims/fs.js +99 -0
- package/dinou/cloudflare/shims/os.js +29 -0
- package/dinou/config.js +1 -0
- package/dinou/config.mjs +2 -0
- package/dinou/constants.js +29 -4
- package/dinou/core/babel-esm-loader.js +66 -37
- package/dinou/core/bailout-proxy.js +61 -0
- package/dinou/core/build-static-pages.js +322 -165
- package/dinou/core/cache-revalidate.js +471 -144
- package/dinou/core/cache-slot.js +387 -0
- package/dinou/core/client-redirect.jsx +12 -7
- package/dinou/core/client-webpack.jsx +457 -82
- package/dinou/core/client.jsx +452 -82
- package/dinou/core/config.js +11 -0
- package/dinou/core/dinou-paths.js +52 -0
- package/dinou/core/edge-ssr.js +122 -0
- package/dinou/core/export-static.mjs +64 -0
- package/dinou/core/generate-route-types.js +252 -0
- package/dinou/core/generate-static-page.js +55 -94
- package/dinou/core/generate-static-rsc.js +47 -15
- package/dinou/core/generate-static.js +212 -10
- package/dinou/core/generating-isg.js +5 -0
- package/dinou/core/get-asset-from-manifest.js +9 -3
- package/dinou/core/get-error-jsx.js +221 -41
- package/dinou/core/get-file-path-and-dynamic-params.js +9 -13
- package/dinou/core/get-jsx.js +175 -96
- package/dinou/core/handler.js +2303 -0
- package/dinou/core/http-adapter.js +115 -0
- package/dinou/core/import-module.js +83 -53
- package/dinou/core/layout-functions.js +183 -0
- package/dinou/core/link.jsx +18 -6
- package/dinou/core/load-dinou-config.js +60 -0
- package/dinou/core/manifest-provider.js +261 -0
- package/dinou/core/navigation-utils.js +4 -0
- package/dinou/core/navigation.js +50 -39
- package/dinou/core/parse-exports.js +252 -2
- package/dinou/core/ppr-context.js +105 -0
- package/dinou/core/ppr-runtime.js +263 -0
- package/dinou/core/redirect.jsx +20 -19
- package/dinou/core/render-jsx-to-client-jsx.js +91 -87
- package/dinou/core/request-context.js +47 -13
- package/dinou/core/resolve-module-ppr.js +34 -0
- package/dinou/core/revalidating.js +28 -9
- package/dinou/core/route-generator.js +107 -0
- package/dinou/core/rsc-renderer.js +90 -0
- package/dinou/core/run-ssg.js +19 -0
- package/dinou/core/scan-dependency-components.js +218 -0
- package/dinou/core/server-function-proxy-webpack.js +3 -0
- package/dinou/core/server-function-proxy.js +3 -0
- package/dinou/core/slot.js +302 -0
- package/dinou/core/status-manifest.js +41 -1
- package/dinou/core/storage-adapter.js +522 -0
- package/dinou/core/url-resolver.js +16 -16
- package/dinou/core/vfs.js +139 -68
- package/dinou/deno/build.mjs +1112 -0
- package/dinou/deno/seed-kv.js +115 -0
- package/dinou/esbuild/build.mjs +51 -1
- package/dinou/esbuild/dev.mjs +290 -224
- package/dinou/esbuild/helpers-esbuild/get-config-esbuild-prod.mjs +3 -2
- package/dinou/esbuild/helpers-esbuild/get-config-esbuild.mjs +104 -16
- package/dinou/esbuild/helpers-esbuild/get-esbuild-entries.mjs +31 -19
- package/dinou/esbuild/helpers-esbuild/strip-namespace.mjs +9 -0
- package/dinou/esbuild/helpers-esbuild/swc-disk-cache.mjs +225 -0
- package/dinou/esbuild/helpers-esbuild/update-manifest-for-module.mjs +7 -0
- package/dinou/esbuild/helpers-esbuild/write.mjs +111 -2
- package/dinou/esbuild/plugins-esbuild/assets-plugin.mjs +236 -161
- package/dinou/esbuild/plugins-esbuild/css-processor-plugin.mjs +101 -5
- package/dinou/esbuild/plugins-esbuild/react-client-manifest-plugin.mjs +63 -24
- package/dinou/esbuild/plugins-esbuild/server-functions-plugin.mjs +177 -56
- package/dinou/esbuild/plugins-esbuild/skip-missing-entry-points-plugin.mjs +3 -0
- package/dinou/esbuild/plugins-esbuild/stable-chunk-names-and-maps-plugin.mjs +182 -137
- package/dinou/esbuild/plugins-postcss/postcss-extract-plugin.js +38 -11
- package/dinou/esbuild/react-refresh/esm-hmr/client.mjs +55 -8
- package/dinou/esbuild/react-refresh/esm-hmr/server.js +1 -1
- package/dinou/esbuild/react-refresh/esm-hmr-plugin.mjs +238 -101
- package/dinou/esbuild/react-refresh/is-react-refresh-boundary.mjs +18 -4
- package/dinou/index.d.ts +315 -11
- package/dinou/index.js +12 -6
- package/dinou/index.mjs +9 -0
- package/dinou/node/build.mjs +195 -0
- package/dinou/node/bundle-dual-engine.mjs +1012 -0
- package/dinou/node/dev.mjs +2589 -0
- package/dinou/node/port-selector.mjs +164 -0
- package/dinou/node/terminal-status.mjs +345 -0
- package/dinou/package.json +16 -14
- package/dinou/rollup/react-refresh/esm-hmr/client.js +66 -10
- package/dinou/rollup/react-refresh/esm-hmr/server.js +1 -1
- package/dinou/rollup/react-refresh/is-react-refresh-boundary.js +24 -5
- package/dinou/rollup/react-refresh/react-refresh-runtime.js +13 -6
- package/dinou/rollup/react-refresh/react-refresh-wrap-modules.js +56 -11
- package/dinou/rollup/react-refresh/rollup-plugin-esm-hmr.js +176 -48
- package/dinou/rollup/rollup-plugins/dinou-asset-plugin.js +9 -5
- package/dinou/rollup/rollup-plugins/rollup-plugin-memory.js +66 -0
- package/dinou/rollup/rollup-plugins/rollup-plugin-react-client-manifest.js +468 -123
- package/dinou/rollup/rollup-plugins/rollup-plugin-server-functions.js +44 -12
- package/dinou/rollup/rollup-plugins/rollup-plugin-swc.js +100 -0
- package/dinou/rollup/rollup.config.js +155 -43
- package/dinou/server.d.ts +114 -12
- package/dinou/server.js +35 -10
- package/dinou/server.mjs +30 -9
- package/dinou/webpack/helpers/get-webpack-entries.js +14 -19
- package/dinou/webpack/loaders/server-functions-loader.js +22 -1
- package/dinou/webpack/loaders/swc-loader.js +76 -0
- package/dinou/webpack/plugins/manifest-generator-plugin.js +1 -0
- package/dinou/webpack/plugins/server-functions-plugin.js +75 -19
- package/dinou/webpack/plugins/webpack-memory-plugin.js +66 -0
- package/dinou/webpack/webpack.config.js +227 -29
- package/eject.js +113 -34
- package/package.json +18 -16
- package/dinou/core/asset-require-hook.js +0 -58
- package/dinou/core/client-error-webpack.jsx +0 -432
- package/dinou/core/client-error.jsx +0 -432
- package/dinou/core/concurrency-manager.js +0 -48
- package/dinou/core/context-proxy.js +0 -68
- package/dinou/core/generate-static-pages.js +0 -130
- package/dinou/core/generate-static-rscs.js +0 -151
- package/dinou/core/get-ssg-metadata.js +0 -31
- package/dinou/core/register-loader.mjs +0 -11
- package/dinou/core/register-paths.js +0 -27
- package/dinou/core/render-app-to-html.js +0 -430
- package/dinou/core/render-html.js +0 -407
- package/dinou/core/server.js +0 -1542
- package/dinou/esbuild/plugins-esbuild/write-metafile-plugin.mjs +0 -16
|
@@ -7,9 +7,60 @@ const {
|
|
|
7
7
|
} = require("./get-file-path-and-dynamic-params");
|
|
8
8
|
const importModule = require("./import-module");
|
|
9
9
|
const { requestStorage } = require("./request-context.js");
|
|
10
|
+
const { getLayoutProps, resolveLayoutFunctionsConfig } = require("./layout-functions");
|
|
11
|
+
const { runWithPprContext, getRegisteredHoles } = require("./ppr-context.js");
|
|
12
|
+
const { resolveModulePpr } = require("./resolve-module-ppr");
|
|
13
|
+
const { getDinouConfig } = require("./load-dinou-config");
|
|
14
|
+
|
|
15
|
+
async function resolveBuildPprForRoute(segments, pagePath, pageFunctionsPath, srcFolder) {
|
|
16
|
+
const globalCfg = await getDinouConfig();
|
|
17
|
+
let inheritedPpr = Boolean(globalCfg?.ppr);
|
|
18
|
+
try {
|
|
19
|
+
const parentLayouts = getFilePathAndDynamicParams(
|
|
20
|
+
segments || [],
|
|
21
|
+
{},
|
|
22
|
+
srcFolder,
|
|
23
|
+
"layout",
|
|
24
|
+
true,
|
|
25
|
+
false,
|
|
26
|
+
undefined,
|
|
27
|
+
0,
|
|
28
|
+
{},
|
|
29
|
+
true
|
|
30
|
+
);
|
|
31
|
+
if (parentLayouts && Array.isArray(parentLayouts)) {
|
|
32
|
+
for (const [lPath, lParams] of parentLayouts) {
|
|
33
|
+
const lConfig = await resolveLayoutFunctionsConfig(lPath, lParams);
|
|
34
|
+
if (lConfig && lConfig.ppr !== null && lConfig.ppr !== undefined) {
|
|
35
|
+
inheritedPpr = Boolean(lConfig.ppr);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
} catch (e) {}
|
|
40
|
+
|
|
41
|
+
let explicitPagePpr = null;
|
|
42
|
+
if (pageFunctionsPath) {
|
|
43
|
+
try {
|
|
44
|
+
const module = await importModule(pageFunctionsPath);
|
|
45
|
+
explicitPagePpr = await resolveModulePpr(module);
|
|
46
|
+
} catch (e) {}
|
|
47
|
+
}
|
|
48
|
+
if (explicitPagePpr === null && typeof globalThis !== "undefined" && globalThis.__DINOU_ROUTE_METADATA__) {
|
|
49
|
+
const normKey = pageFunctionsPath ? pageFunctionsPath.replace(/\\/g, "/") : "";
|
|
50
|
+
for (const [k, meta] of Object.entries(globalThis.__DINOU_ROUTE_METADATA__)) {
|
|
51
|
+
if (meta.ppr !== undefined && (normKey === k || normKey.endsWith("/" + k) || normKey.endsWith(k))) {
|
|
52
|
+
explicitPagePpr = Boolean(meta.ppr);
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return explicitPagePpr !== null ? explicitPagePpr : inheritedPpr;
|
|
59
|
+
}
|
|
10
60
|
|
|
11
61
|
const staticRoutes = new Set();
|
|
12
62
|
const staticMetadata = new Map();
|
|
63
|
+
const staticLayouts = new Map();
|
|
13
64
|
|
|
14
65
|
function safeDecode(val) {
|
|
15
66
|
try {
|
|
@@ -19,65 +70,21 @@ function safeDecode(val) {
|
|
|
19
70
|
}
|
|
20
71
|
}
|
|
21
72
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* @param {Function} onBailout - Callback to execute when access is detected
|
|
27
|
-
*/
|
|
28
|
-
function createBailoutProxy(target, label, onBailout) {
|
|
29
|
-
// If there is no target, use an empty object to avoid crashes,
|
|
30
|
-
// but ideally pass whatever you have.
|
|
31
|
-
const safeTarget = target || {};
|
|
32
|
-
|
|
33
|
-
return new Proxy(safeTarget, {
|
|
34
|
-
get(t, prop, receiver) {
|
|
35
|
-
// Ignore internal Node/Console symbols
|
|
36
|
-
if (
|
|
37
|
-
typeof prop === "symbol" ||
|
|
38
|
-
prop === "inspect" ||
|
|
39
|
-
prop === "valueOf" ||
|
|
40
|
-
prop === "toString" // Sometimes useful to ignore
|
|
41
|
-
) {
|
|
42
|
-
return Reflect.get(t, prop, receiver);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// 🚨 ALARM: Access detected
|
|
46
|
-
console.log(
|
|
47
|
-
`[StaticBailout] Access to ${label} detected: "${String(prop)}".`,
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
// Execute logic to mark as dynamic
|
|
51
|
-
onBailout();
|
|
52
|
-
|
|
53
|
-
// IMPORTANT: Return the real value of the original object
|
|
54
|
-
return Reflect.get(t, prop, receiver);
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
ownKeys(t) {
|
|
58
|
-
console.log(`[StaticBailout] Iteration of ${label} detected.`);
|
|
59
|
-
onBailout();
|
|
60
|
-
return Reflect.ownKeys(t);
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
// Optional: Detect if they try to ask "prop in headers"
|
|
64
|
-
has(t, prop) {
|
|
65
|
-
console.log(
|
|
66
|
-
`[StaticBailout] Existence check (IN) in ${label}: "${String(prop)}".`,
|
|
67
|
-
);
|
|
68
|
-
onBailout();
|
|
69
|
-
return Reflect.has(t, prop);
|
|
70
|
-
},
|
|
71
|
-
});
|
|
73
|
+
async function isDynamicRoute(revalidate) {
|
|
74
|
+
if (revalidate === undefined || revalidate === false) return false;
|
|
75
|
+
const val = typeof revalidate === "function" ? await revalidate() : revalidate;
|
|
76
|
+
return typeof val === "number" && val < 1;
|
|
72
77
|
}
|
|
73
78
|
|
|
79
|
+
const { createBailoutProxy } = require("./bailout-proxy.js");
|
|
80
|
+
|
|
74
81
|
/**
|
|
75
82
|
* Compiles all static pages in the application.
|
|
76
83
|
* Crawls the "src/" folder to collect all routes, resolves dynamic path segments,
|
|
77
84
|
* mock-renders them inside a server context, and serializes successful static renders
|
|
78
85
|
* into RSC JSON payloads.
|
|
79
86
|
*/
|
|
80
|
-
async function buildStaticPages() {
|
|
87
|
+
async function buildStaticPages(onProgress = null) {
|
|
81
88
|
const srcFolder = path.resolve(process.cwd(), "src");
|
|
82
89
|
|
|
83
90
|
/**
|
|
@@ -95,8 +102,32 @@ async function buildStaticPages() {
|
|
|
95
102
|
const entries = readdirSync(currentPath, { withFileTypes: true });
|
|
96
103
|
const pages = [];
|
|
97
104
|
|
|
105
|
+
// 🛡️ Descubrir layout en esta carpeta si existe
|
|
106
|
+
const layoutExtensions = [".tsx", ".jsx", ".ts", ".js"];
|
|
107
|
+
for (const ext of layoutExtensions) {
|
|
108
|
+
const candidateLayout = path.join(currentPath, `layout${ext}`);
|
|
109
|
+
if (existsSync(candidateLayout)) {
|
|
110
|
+
const routePath = segments.length ? "/" + segments.join("/") : "/";
|
|
111
|
+
const { resolveLayoutFunctionsConfig } = require("./layout-functions");
|
|
112
|
+
const layoutConfig = await resolveLayoutFunctionsConfig(candidateLayout, params);
|
|
113
|
+
if (!layoutConfig.isDynamic) {
|
|
114
|
+
staticLayouts.set(routePath, {
|
|
115
|
+
folderPath: currentPath,
|
|
116
|
+
layoutPath: candidateLayout,
|
|
117
|
+
routePath,
|
|
118
|
+
segments,
|
|
119
|
+
params,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
98
126
|
for (const entry of entries) {
|
|
99
127
|
if (entry.isDirectory()) {
|
|
128
|
+
if (entry.name.startsWith("_")) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
100
131
|
if (entry.name.startsWith("(") && entry.name.endsWith(")")) {
|
|
101
132
|
pages.push(
|
|
102
133
|
...(await collectPages(
|
|
@@ -134,22 +165,26 @@ async function buildStaticPages() {
|
|
|
134
165
|
segments.length,
|
|
135
166
|
);
|
|
136
167
|
|
|
137
|
-
let
|
|
168
|
+
let revalidate, getStaticPaths;
|
|
138
169
|
if (pageFunctionsPath) {
|
|
139
170
|
const module = await importModule(pageFunctionsPath);
|
|
140
|
-
getStaticPaths = module.getStaticPaths;
|
|
141
|
-
|
|
171
|
+
getStaticPaths = module.getStaticPaths || module.default?.getStaticPaths;
|
|
172
|
+
revalidate = module.revalidate || module.default?.revalidate;
|
|
142
173
|
}
|
|
143
174
|
const isLocalPage =
|
|
144
175
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
145
|
-
if (isLocalPage && !
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
176
|
+
if (isLocalPage && !(await isDynamicRoute(revalidate))) {
|
|
177
|
+
if (process.env.DINOU_DEBUG) {
|
|
178
|
+
console.log(
|
|
179
|
+
`Found optional catch-all route: ${segments.join("/") ?? ""
|
|
180
|
+
}/[[...${paramName}]]`,
|
|
181
|
+
);
|
|
182
|
+
}
|
|
150
183
|
try {
|
|
151
184
|
if (getStaticPaths) {
|
|
152
|
-
const paths = await getStaticPaths
|
|
185
|
+
const paths = await (typeof getStaticPaths === "function"
|
|
186
|
+
? getStaticPaths()
|
|
187
|
+
: getStaticPaths);
|
|
153
188
|
for (const pathItem of paths) {
|
|
154
189
|
// 1. Preparation of Structure and Extraction
|
|
155
190
|
const currentStructure = [...dynamicStructure, paramName];
|
|
@@ -275,22 +310,26 @@ async function buildStaticPages() {
|
|
|
275
310
|
segments.length,
|
|
276
311
|
);
|
|
277
312
|
|
|
278
|
-
let
|
|
313
|
+
let revalidate, getStaticPaths;
|
|
279
314
|
if (pageFunctionsPath) {
|
|
280
315
|
const module = await importModule(pageFunctionsPath);
|
|
281
|
-
getStaticPaths = module.getStaticPaths;
|
|
282
|
-
|
|
316
|
+
getStaticPaths = module.getStaticPaths || module.default?.getStaticPaths;
|
|
317
|
+
revalidate = module.revalidate || module.default?.revalidate;
|
|
283
318
|
}
|
|
284
319
|
const isLocalPage =
|
|
285
320
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
286
|
-
if (isLocalPage && !
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
321
|
+
if (isLocalPage && !(await isDynamicRoute(revalidate))) {
|
|
322
|
+
if (process.env.DINOU_DEBUG) {
|
|
323
|
+
console.log(
|
|
324
|
+
`Found catch-all route: ${segments.join("/") ?? ""
|
|
325
|
+
}/[...${paramName}]`,
|
|
326
|
+
);
|
|
327
|
+
}
|
|
291
328
|
try {
|
|
292
329
|
if (getStaticPaths) {
|
|
293
|
-
const paths = await getStaticPaths
|
|
330
|
+
const paths = await (typeof getStaticPaths === "function"
|
|
331
|
+
? getStaticPaths()
|
|
332
|
+
: getStaticPaths);
|
|
294
333
|
for (const pathItem of paths) {
|
|
295
334
|
const currentStructure = [...dynamicStructure, paramName];
|
|
296
335
|
const isObject =
|
|
@@ -379,22 +418,26 @@ async function buildStaticPages() {
|
|
|
379
418
|
segments.length,
|
|
380
419
|
);
|
|
381
420
|
|
|
382
|
-
let
|
|
421
|
+
let revalidate, getStaticPaths;
|
|
383
422
|
if (pageFunctionsPath) {
|
|
384
423
|
const module = await importModule(pageFunctionsPath);
|
|
385
|
-
getStaticPaths = module.getStaticPaths;
|
|
386
|
-
|
|
424
|
+
getStaticPaths = module.getStaticPaths || module.default?.getStaticPaths;
|
|
425
|
+
revalidate = module.revalidate || module.default?.revalidate;
|
|
387
426
|
}
|
|
388
427
|
const isLocalPage =
|
|
389
428
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
390
|
-
if (isLocalPage && !
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
429
|
+
if (isLocalPage && !(await isDynamicRoute(revalidate))) {
|
|
430
|
+
if (process.env.DINOU_DEBUG) {
|
|
431
|
+
console.log(
|
|
432
|
+
`Found optional dynamic route: ${segments.join("/") ?? ""
|
|
433
|
+
}/[[${paramName}]]`,
|
|
434
|
+
);
|
|
435
|
+
}
|
|
395
436
|
try {
|
|
396
437
|
if (getStaticPaths) {
|
|
397
|
-
const paths = await getStaticPaths
|
|
438
|
+
const paths = await (typeof getStaticPaths === "function"
|
|
439
|
+
? getStaticPaths()
|
|
440
|
+
: getStaticPaths);
|
|
398
441
|
for (const pathItem of paths) {
|
|
399
442
|
// 1. Preparation of Structure and Extraction
|
|
400
443
|
const currentStructure = [...dynamicStructure, paramName];
|
|
@@ -502,20 +545,51 @@ async function buildStaticPages() {
|
|
|
502
545
|
);
|
|
503
546
|
let dynamic;
|
|
504
547
|
let getStaticPaths;
|
|
548
|
+
let revalidate;
|
|
505
549
|
if (pageFunctionsPath) {
|
|
506
550
|
const module = await importModule(pageFunctionsPath);
|
|
507
|
-
|
|
508
|
-
|
|
551
|
+
const defMod = module.default?.default ? module.default.default : module.default;
|
|
552
|
+
getStaticPaths = module.getStaticPaths || defMod?.getStaticPaths;
|
|
553
|
+
revalidate = module.revalidate || defMod?.revalidate;
|
|
554
|
+
}
|
|
555
|
+
const { getLayoutFunctionsPath } = require("./layout-functions");
|
|
556
|
+
const lfPath = getLayoutFunctionsPath(dynamicPath);
|
|
557
|
+
if (lfPath) {
|
|
558
|
+
const lmod = await importModule(lfPath);
|
|
559
|
+
const lmodGetStaticPaths = lmod.getStaticPaths || lmod.default?.getStaticPaths;
|
|
560
|
+
const lmodRevalidate = lmod.revalidate || lmod.default?.revalidate;
|
|
561
|
+
if (!getStaticPaths && lmodGetStaticPaths) {
|
|
562
|
+
getStaticPaths = lmodGetStaticPaths;
|
|
563
|
+
}
|
|
564
|
+
if (revalidate === undefined && lmodRevalidate !== undefined) {
|
|
565
|
+
revalidate = lmodRevalidate;
|
|
566
|
+
}
|
|
509
567
|
}
|
|
510
568
|
const isLocalPage =
|
|
511
569
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
570
|
+
const [layoutPath] = getFilePathAndDynamicParams(
|
|
571
|
+
segments,
|
|
572
|
+
{},
|
|
573
|
+
dynamicPath,
|
|
574
|
+
"layout",
|
|
575
|
+
true,
|
|
576
|
+
true,
|
|
577
|
+
undefined,
|
|
578
|
+
segments.length,
|
|
579
|
+
);
|
|
580
|
+
const hasLocalLayout =
|
|
581
|
+
layoutPath && path.dirname(layoutPath) === dynamicPath;
|
|
582
|
+
if ((isLocalPage || hasLocalLayout) && !(await isDynamicRoute(revalidate))) {
|
|
583
|
+
if (process.env.DINOU_DEBUG) {
|
|
584
|
+
console.log(
|
|
585
|
+
`Found dynamic route: ${segments.join("/") ?? ""}/[${paramName}]`,
|
|
586
|
+
);
|
|
587
|
+
}
|
|
516
588
|
try {
|
|
517
589
|
if (getStaticPaths) {
|
|
518
|
-
const paths = await getStaticPaths
|
|
590
|
+
const paths = await (typeof getStaticPaths === "function"
|
|
591
|
+
? getStaticPaths()
|
|
592
|
+
: getStaticPaths);
|
|
519
593
|
for (const pathItem of paths) {
|
|
520
594
|
const currentStructure = [...dynamicStructure, paramName];
|
|
521
595
|
const isObject =
|
|
@@ -598,19 +672,22 @@ async function buildStaticPages() {
|
|
|
598
672
|
undefined,
|
|
599
673
|
segments.length,
|
|
600
674
|
);
|
|
601
|
-
let
|
|
675
|
+
let revalidate;
|
|
602
676
|
let getStaticPaths;
|
|
603
677
|
if (pageFunctionsPath) {
|
|
604
678
|
const module = await importModule(pageFunctionsPath);
|
|
605
|
-
|
|
606
|
-
|
|
679
|
+
const defMod = module.default?.default ? module.default.default : module.default;
|
|
680
|
+
getStaticPaths = module.getStaticPaths || defMod?.getStaticPaths;
|
|
681
|
+
revalidate = module.revalidate || defMod?.revalidate;
|
|
607
682
|
}
|
|
608
683
|
const isLocalPage =
|
|
609
684
|
pagePath && path.dirname(pagePath) === dynamicPath;
|
|
610
|
-
if (isLocalPage && !
|
|
685
|
+
if (isLocalPage && !(await isDynamicRoute(revalidate))) {
|
|
611
686
|
try {
|
|
612
687
|
if (getStaticPaths) {
|
|
613
|
-
const paths = await getStaticPaths
|
|
688
|
+
const paths = await (typeof getStaticPaths === "function"
|
|
689
|
+
? getStaticPaths()
|
|
690
|
+
: getStaticPaths);
|
|
614
691
|
for (const pathItem of paths) {
|
|
615
692
|
const currentStructure = dynamicStructure;
|
|
616
693
|
const isObject =
|
|
@@ -707,19 +784,30 @@ async function buildStaticPages() {
|
|
|
707
784
|
undefined,
|
|
708
785
|
segments.length,
|
|
709
786
|
);
|
|
710
|
-
let
|
|
787
|
+
let revalidate;
|
|
711
788
|
if (pageFunctionsPath) {
|
|
712
|
-
|
|
713
|
-
|
|
789
|
+
try {
|
|
790
|
+
const module = await importModule(pageFunctionsPath);
|
|
791
|
+
revalidate = module.revalidate || module.default?.revalidate;
|
|
792
|
+
} catch (e) {}
|
|
714
793
|
}
|
|
715
794
|
|
|
716
|
-
|
|
795
|
+
const isPpr = await resolveBuildPprForRoute(segments, pagePath, pageFunctionsPath, srcFolder);
|
|
796
|
+
|
|
797
|
+
if (pagePath && (!(await isDynamicRoute(revalidate)) || isPpr) && !doNotPushAtEnd) {
|
|
717
798
|
pages.push({
|
|
718
799
|
path: currentPath,
|
|
719
800
|
segments,
|
|
720
801
|
params: dParams,
|
|
802
|
+
ppr: isPpr,
|
|
721
803
|
});
|
|
722
|
-
|
|
804
|
+
const routeName = segments.join("/") ? "/" + segments.join("/") : "/";
|
|
805
|
+
if (typeof onProgress === "function") {
|
|
806
|
+
onProgress({ phase: "crawling", route: routeName, count: pages.length });
|
|
807
|
+
}
|
|
808
|
+
if (process.env.DINOU_DEBUG) {
|
|
809
|
+
console.log(`Found static route: ${routeName}${isPpr ? " (PPR)" : ""}`);
|
|
810
|
+
}
|
|
723
811
|
}
|
|
724
812
|
|
|
725
813
|
return pages;
|
|
@@ -728,9 +816,14 @@ async function buildStaticPages() {
|
|
|
728
816
|
// Crawl complete, start rendering and serialization loop for all discovered static pages
|
|
729
817
|
const pages = await collectPages(srcFolder);
|
|
730
818
|
|
|
731
|
-
|
|
819
|
+
let pageIdx = 0;
|
|
820
|
+
for (const { path: folderPath, segments, params, ppr: pageIsPpr } of pages) {
|
|
821
|
+
pageIdx++;
|
|
732
822
|
try {
|
|
733
823
|
const reqPath = segments.length ? "/" + segments.join("/") + "/" : "/";
|
|
824
|
+
if (typeof onProgress === "function") {
|
|
825
|
+
onProgress({ phase: "discovering", route: reqPath, current: pageIdx, total: pages.length });
|
|
826
|
+
}
|
|
734
827
|
// ====================================================================
|
|
735
828
|
// 1. MOCK RES: Fulfilling ResponseProxy interface
|
|
736
829
|
// ====================================================================
|
|
@@ -780,9 +873,11 @@ async function buildStaticPages() {
|
|
|
780
873
|
this._redirectUrl = url;
|
|
781
874
|
|
|
782
875
|
// Log warning because a redirect in SSG is usually problematic
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
876
|
+
if (process.env.DINOU_DEBUG) {
|
|
877
|
+
console.warn(
|
|
878
|
+
`⚠️ [SSG] Redirect detected in ${reqPath} -> ${url} (${status})`,
|
|
879
|
+
);
|
|
880
|
+
}
|
|
786
881
|
},
|
|
787
882
|
};
|
|
788
883
|
|
|
@@ -826,7 +921,8 @@ async function buildStaticPages() {
|
|
|
826
921
|
let revalidate;
|
|
827
922
|
let cacheTags = [];
|
|
828
923
|
const jsx = await requestStorage.run(mockContext, async () => {
|
|
829
|
-
|
|
924
|
+
return await runWithPprContext({ isPpr: Boolean(pageIsPpr) }, async () => {
|
|
925
|
+
const [pagePath] = getFilePathAndDynamicParams(
|
|
830
926
|
segments,
|
|
831
927
|
{},
|
|
832
928
|
folderPath,
|
|
@@ -856,17 +952,21 @@ async function buildStaticPages() {
|
|
|
856
952
|
|
|
857
953
|
if (pageFunctionsPath) {
|
|
858
954
|
const pageFunctionsModule = await importModule(pageFunctionsPath);
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
|
|
955
|
+
const defMod = pageFunctionsModule.default?.default ? pageFunctionsModule.default.default : pageFunctionsModule.default;
|
|
956
|
+
const getProps = pageFunctionsModule.getProps || defMod?.getProps;
|
|
957
|
+
revalidate = pageFunctionsModule.revalidate || defMod?.revalidate;
|
|
958
|
+
const rawTags = pageFunctionsModule.getCacheTags ?? defMod?.getCacheTags;
|
|
959
|
+
if (typeof rawTags === "function") {
|
|
862
960
|
try {
|
|
863
|
-
cacheTags = await
|
|
961
|
+
cacheTags = await rawTags(params);
|
|
864
962
|
} catch (e) {
|
|
865
963
|
console.error("Error running getCacheTags in buildStaticPages:", e);
|
|
866
964
|
}
|
|
965
|
+
} else if (Array.isArray(rawTags)) {
|
|
966
|
+
cacheTags = rawTags;
|
|
867
967
|
}
|
|
868
968
|
pageFunctionsProps = await getProps?.(params);
|
|
869
|
-
props = { ...props, ...(pageFunctionsProps
|
|
969
|
+
props = { ...props, ...(pageFunctionsProps ?? {}) };
|
|
870
970
|
}
|
|
871
971
|
|
|
872
972
|
let jsx = React.createElement(Page, props);
|
|
@@ -902,19 +1002,30 @@ async function buildStaticPages() {
|
|
|
902
1002
|
false,
|
|
903
1003
|
)[0];
|
|
904
1004
|
const updatedSlots = {};
|
|
905
|
-
for (const [slotName,
|
|
906
|
-
const alreadyFoundPath = slotElement.props?.__modulePath;
|
|
907
|
-
const slotElementWithModule = {
|
|
908
|
-
...slotElement,
|
|
909
|
-
__modulePath: alreadyFoundPath ?? null,
|
|
910
|
-
};
|
|
911
|
-
|
|
1005
|
+
for (const [slotName, slotValue] of Object.entries(slots)) {
|
|
912
1006
|
let updatedSlotElement;
|
|
1007
|
+
const slotFilePath = slotValue?.slotPath || slotValue?.props?.__modulePath;
|
|
1008
|
+
const slotParams = slotValue?.slotParams || slotValue?.props?.params || {};
|
|
1009
|
+
|
|
913
1010
|
try {
|
|
914
|
-
|
|
915
|
-
|
|
1011
|
+
let elementToRender;
|
|
1012
|
+
if (slotValue && slotValue.slotPath) {
|
|
1013
|
+
const slotModule = await importModule(slotValue.slotPath);
|
|
1014
|
+
const Slot = slotModule.default ?? slotModule;
|
|
1015
|
+
elementToRender = React.createElement(Slot, {
|
|
1016
|
+
params: slotParams,
|
|
1017
|
+
key: slotName,
|
|
1018
|
+
__modulePath: slotValue.slotPath,
|
|
1019
|
+
});
|
|
1020
|
+
} else {
|
|
1021
|
+
elementToRender = {
|
|
1022
|
+
...slotValue,
|
|
1023
|
+
__modulePath: slotFilePath ?? null,
|
|
1024
|
+
};
|
|
1025
|
+
}
|
|
1026
|
+
await asyncRenderJSXToClientJSX(elementToRender);
|
|
1027
|
+
updatedSlotElement = elementToRender;
|
|
916
1028
|
} catch (e) {
|
|
917
|
-
const slotFilePath = alreadyFoundPath;
|
|
918
1029
|
if (slotFilePath) {
|
|
919
1030
|
const realSlotFolder = path.dirname(slotFilePath);
|
|
920
1031
|
const [slotErrorPath, slotErrorParams] =
|
|
@@ -959,13 +1070,12 @@ async function buildStaticPages() {
|
|
|
959
1070
|
}
|
|
960
1071
|
updatedSlots[slotName] = updatedSlotElement;
|
|
961
1072
|
}
|
|
1073
|
+
const layoutProps = await getLayoutProps(layoutPath, dParams);
|
|
962
1074
|
let props = {
|
|
963
1075
|
params: dParams,
|
|
964
1076
|
...updatedSlots,
|
|
1077
|
+
...(layoutProps ?? {}),
|
|
965
1078
|
};
|
|
966
|
-
if (index === layouts.length - 1 || resetLayoutPath) {
|
|
967
|
-
props = { ...props, ...(pageFunctionsProps?.layout ?? {}) };
|
|
968
|
-
}
|
|
969
1079
|
jsx = React.createElement(Layout, props, jsx);
|
|
970
1080
|
jsx = { ...jsx, __modulePath: layoutPath };
|
|
971
1081
|
if (resetLayoutPath) {
|
|
@@ -978,16 +1088,19 @@ async function buildStaticPages() {
|
|
|
978
1088
|
|
|
979
1089
|
// Render the layout-nested React element tree to client-side RSC JSON format
|
|
980
1090
|
return await asyncRenderJSXToClientJSX(jsx);
|
|
1091
|
+
});
|
|
981
1092
|
});
|
|
982
1093
|
|
|
983
|
-
if (!isStatic) {
|
|
1094
|
+
if (!isStatic && !pageIsPpr) {
|
|
984
1095
|
// ❌ DO NOT save file.
|
|
985
1096
|
// Will behave as pure SSR at runtime.
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
1097
|
+
if (process.env.DINOU_DEBUG) {
|
|
1098
|
+
console.log(
|
|
1099
|
+
`Skipping static generation for ${segments.join(
|
|
1100
|
+
"/",
|
|
1101
|
+
)} due to dynamic usage.`,
|
|
1102
|
+
);
|
|
1103
|
+
}
|
|
991
1104
|
continue;
|
|
992
1105
|
}
|
|
993
1106
|
|
|
@@ -996,20 +1109,27 @@ async function buildStaticPages() {
|
|
|
996
1109
|
cookies: mockRes._cookies,
|
|
997
1110
|
};
|
|
998
1111
|
|
|
1112
|
+
const holes = pageIsPpr ? getRegisteredHoles() : [];
|
|
999
1113
|
staticRoutes.add(reqPath);
|
|
1000
1114
|
staticMetadata.set(reqPath, {
|
|
1001
|
-
revalidate: revalidate
|
|
1115
|
+
revalidate: typeof revalidate === "function" ? await revalidate() : revalidate,
|
|
1002
1116
|
effects: sideEffects,
|
|
1003
1117
|
tags: cacheTags,
|
|
1118
|
+
ppr: Boolean(pageIsPpr),
|
|
1119
|
+
holes,
|
|
1004
1120
|
});
|
|
1005
|
-
|
|
1121
|
+
if (process.env.DINOU_DEBUG) {
|
|
1122
|
+
console.log(`Registered static page at ${reqPath}${pageIsPpr ? " (PPR)" : ""}`);
|
|
1123
|
+
}
|
|
1006
1124
|
} catch (err) {
|
|
1007
1125
|
console.error(`Error building page ${segments.join("/")}:`, err);
|
|
1008
1126
|
continue;
|
|
1009
1127
|
}
|
|
1010
1128
|
}
|
|
1011
1129
|
|
|
1012
|
-
|
|
1130
|
+
if (process.env.DINOU_DEBUG) {
|
|
1131
|
+
console.log(`Static site generated with ${pages.length} pages`);
|
|
1132
|
+
}
|
|
1013
1133
|
}
|
|
1014
1134
|
|
|
1015
1135
|
/**
|
|
@@ -1031,7 +1151,8 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1031
1151
|
segment &&
|
|
1032
1152
|
((segment.startsWith("(") && segment.endsWith(")")) ||
|
|
1033
1153
|
(segment.startsWith("[") && segment.endsWith("]")) ||
|
|
1034
|
-
segment.startsWith("@")
|
|
1154
|
+
segment.startsWith("@") ||
|
|
1155
|
+
segment.startsWith("_"));
|
|
1035
1156
|
const currentPath = path.join(folderPath, segment);
|
|
1036
1157
|
if (existsSync(currentPath) && !isRouterSyntaxInSegment) {
|
|
1037
1158
|
folderPath = currentPath;
|
|
@@ -1110,9 +1231,11 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1110
1231
|
this._redirectUrl = url;
|
|
1111
1232
|
|
|
1112
1233
|
// We log a warning because a redirect in SSG is usually problematic
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1234
|
+
if (process.env.DINOU_DEBUG) {
|
|
1235
|
+
console.warn(
|
|
1236
|
+
`⚠️ [SSG] Redirect detected in ${reqPath} -> ${url} (${status})`,
|
|
1237
|
+
);
|
|
1238
|
+
}
|
|
1116
1239
|
},
|
|
1117
1240
|
};
|
|
1118
1241
|
|
|
@@ -1155,6 +1278,7 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1155
1278
|
|
|
1156
1279
|
let revalidate;
|
|
1157
1280
|
let cacheTags = [];
|
|
1281
|
+
let pageIsPpr = false;
|
|
1158
1282
|
const jsx = await requestStorage.run(mockContext, async () => {
|
|
1159
1283
|
const [pagePath, dParams] = getFilePathAndDynamicParams(
|
|
1160
1284
|
segments,
|
|
@@ -1171,8 +1295,6 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1171
1295
|
|
|
1172
1296
|
const pageModule = await importModule(pagePath);
|
|
1173
1297
|
const Page = pageModule.default ?? pageModule;
|
|
1174
|
-
|
|
1175
|
-
let props = { params: dParams };
|
|
1176
1298
|
const [pageFunctionsPath] = getFilePathAndDynamicParams(
|
|
1177
1299
|
segments,
|
|
1178
1300
|
{},
|
|
@@ -1184,22 +1306,31 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1184
1306
|
segments.length,
|
|
1185
1307
|
);
|
|
1186
1308
|
|
|
1309
|
+
pageIsPpr = await resolveBuildPprForRoute(segments, pagePath, pageFunctionsPath, srcFolder);
|
|
1310
|
+
|
|
1311
|
+
return await runWithPprContext({ isPpr: pageIsPpr }, async () => {
|
|
1312
|
+
let props = { params: dParams };
|
|
1313
|
+
|
|
1187
1314
|
let pageFunctionsProps;
|
|
1188
1315
|
if (pageFunctionsPath) {
|
|
1189
1316
|
const pageFunctionsModule = await importModule(pageFunctionsPath);
|
|
1190
|
-
const
|
|
1191
|
-
|
|
1317
|
+
const defMod = pageFunctionsModule.default?.default ? pageFunctionsModule.default.default : pageFunctionsModule.default;
|
|
1318
|
+
const getProps = pageFunctionsModule.getProps || defMod?.getProps;
|
|
1319
|
+
revalidate = pageFunctionsModule.revalidate || defMod?.revalidate;
|
|
1320
|
+
if (isDynamic && (isDynamic.value = await isDynamicRoute(revalidate)))
|
|
1192
1321
|
return;
|
|
1193
|
-
|
|
1194
|
-
if (
|
|
1322
|
+
const rawTags = pageFunctionsModule.getCacheTags ?? defMod?.getCacheTags;
|
|
1323
|
+
if (typeof rawTags === "function") {
|
|
1195
1324
|
try {
|
|
1196
|
-
cacheTags = await
|
|
1325
|
+
cacheTags = await rawTags(dParams);
|
|
1197
1326
|
} catch (e) {
|
|
1198
1327
|
console.error("Error running getCacheTags:", e);
|
|
1199
1328
|
}
|
|
1329
|
+
} else if (Array.isArray(rawTags)) {
|
|
1330
|
+
cacheTags = rawTags;
|
|
1200
1331
|
}
|
|
1201
1332
|
pageFunctionsProps = await getProps?.(dParams);
|
|
1202
|
-
props = { ...props, ...(pageFunctionsProps
|
|
1333
|
+
props = { ...props, ...(pageFunctionsProps ?? {}) };
|
|
1203
1334
|
}
|
|
1204
1335
|
|
|
1205
1336
|
let jsx = React.createElement(Page, props);
|
|
@@ -1233,19 +1364,30 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1233
1364
|
false,
|
|
1234
1365
|
)[0];
|
|
1235
1366
|
const updatedSlots = {};
|
|
1236
|
-
for (const [slotName,
|
|
1237
|
-
const alreadyFoundPath = slotElement.props?.__modulePath;
|
|
1238
|
-
const slotElementWithModule = {
|
|
1239
|
-
...slotElement,
|
|
1240
|
-
__modulePath: alreadyFoundPath ?? null,
|
|
1241
|
-
};
|
|
1242
|
-
|
|
1367
|
+
for (const [slotName, slotValue] of Object.entries(slots)) {
|
|
1243
1368
|
let updatedSlotElement;
|
|
1369
|
+
const slotFilePath = slotValue?.slotPath || slotValue?.props?.__modulePath;
|
|
1370
|
+
const slotParams = slotValue?.slotParams || slotValue?.props?.params || {};
|
|
1371
|
+
|
|
1244
1372
|
try {
|
|
1245
|
-
|
|
1246
|
-
|
|
1373
|
+
let elementToRender;
|
|
1374
|
+
if (slotValue && slotValue.slotPath) {
|
|
1375
|
+
const slotModule = await importModule(slotValue.slotPath);
|
|
1376
|
+
const Slot = slotModule.default ?? slotModule;
|
|
1377
|
+
elementToRender = React.createElement(Slot, {
|
|
1378
|
+
params: slotParams,
|
|
1379
|
+
key: slotName,
|
|
1380
|
+
__modulePath: slotValue.slotPath,
|
|
1381
|
+
});
|
|
1382
|
+
} else {
|
|
1383
|
+
elementToRender = {
|
|
1384
|
+
...slotValue,
|
|
1385
|
+
__modulePath: slotFilePath ?? null,
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
await asyncRenderJSXToClientJSX(elementToRender);
|
|
1389
|
+
updatedSlotElement = elementToRender;
|
|
1247
1390
|
} catch (e) {
|
|
1248
|
-
const slotFilePath = alreadyFoundPath;
|
|
1249
1391
|
if (slotFilePath) {
|
|
1250
1392
|
const realSlotFolder = path.dirname(slotFilePath);
|
|
1251
1393
|
const [slotErrorPath, slotErrorParams] =
|
|
@@ -1294,12 +1436,11 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1294
1436
|
params: dParams,
|
|
1295
1437
|
...updatedSlots,
|
|
1296
1438
|
};
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
}
|
|
1439
|
+
const customLayoutProps = await getLayoutProps(layoutPath, dParams);
|
|
1440
|
+
layoutProps = {
|
|
1441
|
+
...layoutProps,
|
|
1442
|
+
...(customLayoutProps ?? {}),
|
|
1443
|
+
};
|
|
1303
1444
|
jsx = React.createElement(Layout, layoutProps, jsx);
|
|
1304
1445
|
jsx = { ...jsx, __modulePath: layoutPath };
|
|
1305
1446
|
if (resetLayoutPath) {
|
|
@@ -1310,17 +1451,20 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1310
1451
|
}
|
|
1311
1452
|
}
|
|
1312
1453
|
|
|
1313
|
-
|
|
1454
|
+
return await asyncRenderJSXToClientJSX(jsx);
|
|
1455
|
+
});
|
|
1314
1456
|
});
|
|
1315
1457
|
|
|
1316
|
-
if (!isStatic) {
|
|
1458
|
+
if (!isStatic && !pageIsPpr) {
|
|
1317
1459
|
// ❌ DO NOT save file.
|
|
1318
1460
|
// It will behave as pure SSR at runtime.
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1461
|
+
if (process.env.DINOU_DEBUG) {
|
|
1462
|
+
console.log(
|
|
1463
|
+
`Skipping static generation for ${segments.join(
|
|
1464
|
+
"/",
|
|
1465
|
+
)} due to dynamic usage.`,
|
|
1466
|
+
);
|
|
1467
|
+
}
|
|
1324
1468
|
if (isDynamic) {
|
|
1325
1469
|
isDynamic.value = true;
|
|
1326
1470
|
}
|
|
@@ -1332,13 +1476,16 @@ async function buildStaticPage(reqPath, isDynamic = null) {
|
|
|
1332
1476
|
cookies: mockRes._cookies,
|
|
1333
1477
|
};
|
|
1334
1478
|
|
|
1479
|
+
const holes = pageIsPpr ? getRegisteredHoles() : [];
|
|
1335
1480
|
staticRoutes.add(reqPath);
|
|
1336
1481
|
staticMetadata.set(reqPath, {
|
|
1337
|
-
revalidate: revalidate
|
|
1482
|
+
revalidate: typeof revalidate === "function" ? await revalidate() : revalidate,
|
|
1338
1483
|
effects: sideEffects,
|
|
1339
1484
|
tags: cacheTags,
|
|
1485
|
+
ppr: pageIsPpr,
|
|
1486
|
+
holes,
|
|
1340
1487
|
});
|
|
1341
|
-
console.warn(`Registered rebuilt static page at ${reqPath}`);
|
|
1488
|
+
console.warn(`Registered rebuilt static page at ${reqPath}${pageIsPpr ? " (PPR)" : ""}`);
|
|
1342
1489
|
} catch (error) {
|
|
1343
1490
|
console.error(`Error building page ${reqPath}:`, error);
|
|
1344
1491
|
throw error;
|
|
@@ -1350,7 +1497,14 @@ function getStaticPaths() {
|
|
|
1350
1497
|
}
|
|
1351
1498
|
|
|
1352
1499
|
function getStaticMetadata(reqPath) {
|
|
1353
|
-
|
|
1500
|
+
if (!reqPath) return null;
|
|
1501
|
+
const noSlash = reqPath.endsWith("/") ? reqPath.slice(0, -1) : reqPath;
|
|
1502
|
+
const withSlash = noSlash + "/";
|
|
1503
|
+
return staticMetadata.get(reqPath) || staticMetadata.get(noSlash) || staticMetadata.get(withSlash) || null;
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1506
|
+
function getStaticLayouts() {
|
|
1507
|
+
return Array.from(staticLayouts.values());
|
|
1354
1508
|
}
|
|
1355
1509
|
|
|
1356
1510
|
module.exports = {
|
|
@@ -1358,4 +1512,7 @@ module.exports = {
|
|
|
1358
1512
|
buildStaticPage,
|
|
1359
1513
|
getStaticPaths,
|
|
1360
1514
|
getStaticMetadata,
|
|
1515
|
+
getStaticLayouts,
|
|
1516
|
+
isDynamicRoute,
|
|
1361
1517
|
};
|
|
1518
|
+
|