@vistagenic/vista 0.2.7 → 0.2.8
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/bin/build-rsc.js +6 -0
- package/dist/bin/build.js +6 -0
- package/dist/bin/deploy-output.d.ts +7 -0
- package/dist/bin/deploy-output.js +78 -0
- package/dist/build/manifest.d.ts +1 -1
- package/dist/build/manifest.js +5 -3
- package/dist/image/index.js +4 -32
- package/dist/server/rsc-engine.js +7 -5
- package/dist/server/static-generator.js +162 -25
- package/package.json +1 -1
package/dist/bin/build-rsc.js
CHANGED
|
@@ -28,6 +28,7 @@ const static_generator_1 = require("../server/static-generator");
|
|
|
28
28
|
const structure_log_1 = require("../server/structure-log");
|
|
29
29
|
const devtools_indicator_snippet_1 = require("./devtools-indicator-snippet");
|
|
30
30
|
const dev_error_overlay_snippet_1 = require("./dev-error-overlay-snippet");
|
|
31
|
+
const deploy_output_1 = require("./deploy-output");
|
|
31
32
|
const _debug = !!process.env.VISTA_DEBUG;
|
|
32
33
|
/**
|
|
33
34
|
* Run PostCSS for CSS compilation
|
|
@@ -555,6 +556,11 @@ async function buildRSC(watch = false) {
|
|
|
555
556
|
const prerenderManifestPath = path_1.default.join(vistaDirs.root, 'prerender-manifest.json');
|
|
556
557
|
fs_1.default.writeFileSync(prerenderManifestPath, JSON.stringify(ssgResult.manifest, null, 2));
|
|
557
558
|
console.log('[Vista JS RSC] Wrote prerender-manifest.json');
|
|
559
|
+
(0, deploy_output_1.generateDeploymentOutputs)({
|
|
560
|
+
cwd,
|
|
561
|
+
vistaDir: vistaDirs.root,
|
|
562
|
+
debug: _debug,
|
|
563
|
+
});
|
|
558
564
|
console.log('');
|
|
559
565
|
console.log('╔══════════════════════════════════════════════════════════════╗');
|
|
560
566
|
console.log('║ Build Complete! 🎉 ║');
|
package/dist/bin/build.js
CHANGED
|
@@ -17,6 +17,7 @@ const structure_validator_1 = require("../server/structure-validator");
|
|
|
17
17
|
const structure_log_1 = require("../server/structure-log");
|
|
18
18
|
const devtools_indicator_snippet_1 = require("./devtools-indicator-snippet");
|
|
19
19
|
const dev_error_overlay_snippet_1 = require("./dev-error-overlay-snippet");
|
|
20
|
+
const deploy_output_1 = require("./deploy-output");
|
|
20
21
|
const _debug = !!process.env.VISTA_DEBUG;
|
|
21
22
|
// Helper to run PostCSS
|
|
22
23
|
function runPostCSS(cwd, vistaDir) {
|
|
@@ -418,6 +419,11 @@ async function buildClient(watch = false, onRebuild) {
|
|
|
418
419
|
console.log(stats?.toString('minimal'));
|
|
419
420
|
// Build CSS
|
|
420
421
|
runPostCSS(cwd, vistaDir);
|
|
422
|
+
(0, deploy_output_1.generateDeploymentOutputs)({
|
|
423
|
+
cwd,
|
|
424
|
+
vistaDir,
|
|
425
|
+
debug: _debug,
|
|
426
|
+
});
|
|
421
427
|
compiler.close((closeErr) => {
|
|
422
428
|
if (closeErr)
|
|
423
429
|
console.error('Error closing compiler:', closeErr);
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateDeploymentOutputs = generateDeploymentOutputs;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
function isVercelBuildEnvironment() {
|
|
10
|
+
return process.env.VERCEL === '1' || process.env.NOW_REGION !== undefined;
|
|
11
|
+
}
|
|
12
|
+
function hasUserVercelConfig(cwd) {
|
|
13
|
+
return fs_1.default.existsSync(path_1.default.join(cwd, 'vercel.json'));
|
|
14
|
+
}
|
|
15
|
+
function copyDirectoryRecursive(sourceDir, targetDir) {
|
|
16
|
+
if (!fs_1.default.existsSync(sourceDir))
|
|
17
|
+
return;
|
|
18
|
+
fs_1.default.mkdirSync(targetDir, { recursive: true });
|
|
19
|
+
const entries = fs_1.default.readdirSync(sourceDir, { withFileTypes: true });
|
|
20
|
+
for (const entry of entries) {
|
|
21
|
+
const from = path_1.default.join(sourceDir, entry.name);
|
|
22
|
+
const to = path_1.default.join(targetDir, entry.name);
|
|
23
|
+
if (entry.isDirectory()) {
|
|
24
|
+
copyDirectoryRecursive(from, to);
|
|
25
|
+
}
|
|
26
|
+
else if (entry.isFile()) {
|
|
27
|
+
fs_1.default.copyFileSync(from, to);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function copyFileIfPresent(sourceFile, targetFile) {
|
|
32
|
+
if (!fs_1.default.existsSync(sourceFile))
|
|
33
|
+
return;
|
|
34
|
+
fs_1.default.mkdirSync(path_1.default.dirname(targetFile), { recursive: true });
|
|
35
|
+
fs_1.default.copyFileSync(sourceFile, targetFile);
|
|
36
|
+
}
|
|
37
|
+
function writeVercelBuildOutput(options) {
|
|
38
|
+
const { cwd, vistaDir, debug } = options;
|
|
39
|
+
if (!isVercelBuildEnvironment()) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (hasUserVercelConfig(cwd)) {
|
|
43
|
+
if (debug) {
|
|
44
|
+
console.log('[vista:deploy] Found custom vercel.json, skipping internal Vercel output.');
|
|
45
|
+
}
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const vercelOutputDir = path_1.default.join(cwd, '.vercel', 'output');
|
|
49
|
+
const vercelStaticDir = path_1.default.join(vercelOutputDir, 'static');
|
|
50
|
+
fs_1.default.rmSync(vercelOutputDir, { recursive: true, force: true });
|
|
51
|
+
fs_1.default.mkdirSync(vercelStaticDir, { recursive: true });
|
|
52
|
+
// Public assets: /favicon.ico, /vista.svg, etc.
|
|
53
|
+
copyDirectoryRecursive(path_1.default.join(cwd, 'public'), vercelStaticDir);
|
|
54
|
+
// Vista static artifacts: /static/pages, /static/chunks, etc.
|
|
55
|
+
copyDirectoryRecursive(path_1.default.join(vistaDir, 'static'), path_1.default.join(vercelStaticDir, 'static'));
|
|
56
|
+
// Global CSS alias support (/styles.css and /client.css)
|
|
57
|
+
const clientCssPath = path_1.default.join(vistaDir, 'client.css');
|
|
58
|
+
copyFileIfPresent(clientCssPath, path_1.default.join(vercelStaticDir, 'client.css'));
|
|
59
|
+
copyFileIfPresent(clientCssPath, path_1.default.join(vercelStaticDir, 'styles.css'));
|
|
60
|
+
const config = {
|
|
61
|
+
version: 3,
|
|
62
|
+
routes: [
|
|
63
|
+
{ handle: 'filesystem' },
|
|
64
|
+
{ src: '^/_vista/(.*)$', dest: '/$1' },
|
|
65
|
+
{ src: '^/(?:rsc|_rsc)/?$', dest: '/static/pages/index.rsc' },
|
|
66
|
+
{ src: '^/(?:rsc|_rsc)/(.+)$', dest: '/static/pages/$1.rsc' },
|
|
67
|
+
{ src: '^/$', dest: '/static/pages/index.html' },
|
|
68
|
+
{ src: '^/(.+)$', dest: '/static/pages/$1.html' },
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
fs_1.default.writeFileSync(path_1.default.join(vercelOutputDir, 'config.json'), JSON.stringify(config, null, 2));
|
|
72
|
+
if (debug) {
|
|
73
|
+
console.log('[vista:deploy] Generated internal Vercel Build Output at .vercel/output/');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function generateDeploymentOutputs(options) {
|
|
77
|
+
writeVercelBuildOutput(options);
|
|
78
|
+
}
|
package/dist/build/manifest.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export interface VistaDirs {
|
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
24
|
* Create the .vista directory structure.
|
|
25
|
-
* In legacy mode, only creates root
|
|
25
|
+
* In legacy mode, only creates root (no empty server/static dirs).
|
|
26
26
|
* In RSC mode, creates the full structure for server/client bundles.
|
|
27
27
|
*/
|
|
28
28
|
export declare function createVistaDirectories(cwd: string, mode?: 'legacy' | 'rsc'): VistaDirs;
|
package/dist/build/manifest.js
CHANGED
|
@@ -54,7 +54,7 @@ function getBuildId(vistaDir, forceNew = false) {
|
|
|
54
54
|
}
|
|
55
55
|
/**
|
|
56
56
|
* Create the .vista directory structure.
|
|
57
|
-
* In legacy mode, only creates root
|
|
57
|
+
* In legacy mode, only creates root (no empty server/static dirs).
|
|
58
58
|
* In RSC mode, creates the full structure for server/client bundles.
|
|
59
59
|
*/
|
|
60
60
|
function createVistaDirectories(cwd, mode = 'legacy') {
|
|
@@ -71,8 +71,10 @@ function createVistaDirectories(cwd, mode = 'legacy') {
|
|
|
71
71
|
// Always create root
|
|
72
72
|
fs_1.default.mkdirSync(root, { recursive: true });
|
|
73
73
|
if (mode === 'rsc') {
|
|
74
|
-
// RSC mode: create
|
|
75
|
-
|
|
74
|
+
// RSC mode: create only currently-used directories.
|
|
75
|
+
// Keep css/media paths reserved in `dirs` for future use, but do not
|
|
76
|
+
// create empty folders unless the build actually emits files there.
|
|
77
|
+
[dirs.root, dirs.cache, dirs.server, dirs.static, dirs.chunks].forEach((dir) => {
|
|
76
78
|
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
77
79
|
});
|
|
78
80
|
// Cache subdirectories
|
package/dist/image/index.js
CHANGED
|
@@ -27,12 +27,11 @@ const wrapperStyle = {
|
|
|
27
27
|
exports.Image = (0, react_1.forwardRef)((props, ref) => {
|
|
28
28
|
const { placeholder, blurDataURL, onLoadingComplete, priority, ...restProps } = props;
|
|
29
29
|
const [isLoaded, setIsLoaded] = (0, react_1.useState)(false);
|
|
30
|
-
const [isInView, setIsInView] = (0, react_1.useState)(priority || false);
|
|
31
|
-
const imgRef = (0, react_1.useRef)(null);
|
|
32
|
-
const observerRef = (0, react_1.useRef)(null);
|
|
33
30
|
// Combine refs
|
|
34
31
|
const setRefs = (0, react_1.useCallback)((node) => {
|
|
35
|
-
|
|
32
|
+
if (node && node.complete && node.naturalWidth > 0) {
|
|
33
|
+
setIsLoaded(true);
|
|
34
|
+
}
|
|
36
35
|
if (typeof ref === 'function') {
|
|
37
36
|
ref(node);
|
|
38
37
|
}
|
|
@@ -40,31 +39,6 @@ exports.Image = (0, react_1.forwardRef)((props, ref) => {
|
|
|
40
39
|
ref.current = node;
|
|
41
40
|
}
|
|
42
41
|
}, [ref]);
|
|
43
|
-
// IntersectionObserver for lazy loading
|
|
44
|
-
(0, react_1.useEffect)(() => {
|
|
45
|
-
if (priority) {
|
|
46
|
-
setIsInView(true);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
const element = imgRef.current;
|
|
50
|
-
if (!element)
|
|
51
|
-
return;
|
|
52
|
-
observerRef.current = new IntersectionObserver((entries) => {
|
|
53
|
-
entries.forEach((entry) => {
|
|
54
|
-
if (entry.isIntersecting) {
|
|
55
|
-
setIsInView(true);
|
|
56
|
-
observerRef.current?.disconnect();
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}, {
|
|
60
|
-
rootMargin: '200px', // Start loading 200px before viewport
|
|
61
|
-
threshold: 0,
|
|
62
|
-
});
|
|
63
|
-
observerRef.current.observe(element);
|
|
64
|
-
return () => {
|
|
65
|
-
observerRef.current?.disconnect();
|
|
66
|
-
};
|
|
67
|
-
}, [priority]);
|
|
68
42
|
// Handle image load complete
|
|
69
43
|
const handleLoad = (0, react_1.useCallback)((event) => {
|
|
70
44
|
const img = event.currentTarget;
|
|
@@ -88,9 +62,7 @@ exports.Image = (0, react_1.forwardRef)((props, ref) => {
|
|
|
88
62
|
opacity: isLoaded ? 1 : 0,
|
|
89
63
|
transition: 'opacity 0.5s ease-in-out'
|
|
90
64
|
} : {}),
|
|
91
|
-
},
|
|
92
|
-
// Only set src when in view (lazy loading)
|
|
93
|
-
src: isInView ? imgProps.src : undefined, srcSet: isInView ? imgProps.srcSet : undefined, decoding: priority ? 'sync' : 'async', fetchPriority: priority ? 'high' : undefined }));
|
|
65
|
+
}, src: imgProps.src, srcSet: imgProps.srcSet, decoding: priority ? 'sync' : 'async', fetchPriority: priority ? 'high' : undefined }));
|
|
94
66
|
// Wrap with blur placeholder if needed
|
|
95
67
|
if (needsWrapper) {
|
|
96
68
|
return ((0, jsx_runtime_1.jsxs)("span", { style: {
|
|
@@ -844,12 +844,14 @@ function startRSCServer(options = {}) {
|
|
|
844
844
|
}
|
|
845
845
|
let serverManifest = JSON.parse(fs_1.default.readFileSync(serverManifestPath, 'utf-8'));
|
|
846
846
|
// ========================================================================
|
|
847
|
-
// Load pre-rendered static pages from disk into in-memory cache
|
|
847
|
+
// Load pre-rendered static pages from disk into in-memory cache (production)
|
|
848
848
|
// ========================================================================
|
|
849
849
|
const vistaDirRoot = path_1.default.join(cwd, constants_1.BUILD_DIR);
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
850
|
+
if (!isDev) {
|
|
851
|
+
const loadedStaticPages = (0, static_cache_1.loadStaticPagesFromDisk)(vistaDirRoot);
|
|
852
|
+
if (loadedStaticPages > 0) {
|
|
853
|
+
(0, logger_1.logInfo)(`Loaded ${loadedStaticPages} pre-rendered page(s) from cache`);
|
|
854
|
+
}
|
|
853
855
|
}
|
|
854
856
|
const upstreamChild = spawnUpstream(cwd, upstreamPort);
|
|
855
857
|
upstreamChild.stdout.setEncoding('utf8');
|
|
@@ -1254,7 +1256,7 @@ function startRSCServer(options = {}) {
|
|
|
1254
1256
|
// For ISR pages whose revalidate window has expired, serve the stale
|
|
1255
1257
|
// cached version immediately and kick off background revalidation.
|
|
1256
1258
|
// ==================================================================
|
|
1257
|
-
{
|
|
1259
|
+
if (!isDev) {
|
|
1258
1260
|
const cached = (0, static_cache_1.getCachedPage)(req.path);
|
|
1259
1261
|
if (cached.page) {
|
|
1260
1262
|
if (cached.stale) {
|
|
@@ -16,6 +16,7 @@ exports.generateStaticPages = generateStaticPages;
|
|
|
16
16
|
exports.revalidatePath = revalidatePath;
|
|
17
17
|
const path_1 = __importDefault(require("path"));
|
|
18
18
|
const fs_1 = __importDefault(require("fs"));
|
|
19
|
+
const child_process_1 = require("child_process");
|
|
19
20
|
const constants_1 = require("../constants");
|
|
20
21
|
const static_cache_1 = require("./static-cache");
|
|
21
22
|
const CjsModule = require('module');
|
|
@@ -325,6 +326,116 @@ function getChunkScripts(cwd) {
|
|
|
325
326
|
return '';
|
|
326
327
|
}
|
|
327
328
|
}
|
|
329
|
+
function resolveUpstreamScriptPath() {
|
|
330
|
+
const jsPath = path_1.default.join(__dirname, 'rsc-upstream.js');
|
|
331
|
+
if (fs_1.default.existsSync(jsPath)) {
|
|
332
|
+
return jsPath;
|
|
333
|
+
}
|
|
334
|
+
const tsPath = path_1.default.join(__dirname, 'rsc-upstream.ts');
|
|
335
|
+
if (fs_1.default.existsSync(tsPath)) {
|
|
336
|
+
return tsPath;
|
|
337
|
+
}
|
|
338
|
+
return null;
|
|
339
|
+
}
|
|
340
|
+
function waitForUpstreamReady(child, timeoutMs) {
|
|
341
|
+
return new Promise((resolve, reject) => {
|
|
342
|
+
let logs = '';
|
|
343
|
+
const timer = setTimeout(() => {
|
|
344
|
+
cleanup();
|
|
345
|
+
reject(new Error(`[vista:ssg] Timed out waiting for RSC upstream readiness (${timeoutMs}ms)\n${logs}`));
|
|
346
|
+
}, timeoutMs);
|
|
347
|
+
const cleanup = () => {
|
|
348
|
+
clearTimeout(timer);
|
|
349
|
+
child.stdout.removeListener('data', onData);
|
|
350
|
+
child.stderr.removeListener('data', onData);
|
|
351
|
+
child.removeListener('exit', onExit);
|
|
352
|
+
child.removeListener('error', onError);
|
|
353
|
+
};
|
|
354
|
+
const onData = (chunk) => {
|
|
355
|
+
logs += chunk.toString();
|
|
356
|
+
if (logs.includes('Listening on')) {
|
|
357
|
+
cleanup();
|
|
358
|
+
resolve();
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
const onExit = (code) => {
|
|
362
|
+
cleanup();
|
|
363
|
+
reject(new Error(`[vista:ssg] RSC upstream exited before readiness (code: ${code ?? 'unknown'})`));
|
|
364
|
+
};
|
|
365
|
+
const onError = (error) => {
|
|
366
|
+
cleanup();
|
|
367
|
+
reject(error);
|
|
368
|
+
};
|
|
369
|
+
child.stdout.on('data', onData);
|
|
370
|
+
child.stderr.on('data', onData);
|
|
371
|
+
child.once('exit', onExit);
|
|
372
|
+
child.once('error', onError);
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
async function startStaticFlightUpstream(cwd) {
|
|
376
|
+
const upstreamScript = resolveUpstreamScriptPath();
|
|
377
|
+
if (!upstreamScript) {
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
const port = Number(process.env.VISTA_STATIC_RSC_PORT || 3181);
|
|
381
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
382
|
+
return null;
|
|
383
|
+
}
|
|
384
|
+
const child = (0, child_process_1.spawn)(process.execPath, ['--conditions', 'react-server', upstreamScript, '--port', String(port)], {
|
|
385
|
+
cwd,
|
|
386
|
+
env: {
|
|
387
|
+
...process.env,
|
|
388
|
+
NODE_ENV: process.env.NODE_ENV || 'production',
|
|
389
|
+
RSC_UPSTREAM_PORT: String(port),
|
|
390
|
+
},
|
|
391
|
+
stdio: 'pipe',
|
|
392
|
+
});
|
|
393
|
+
await waitForUpstreamReady(child, 12000);
|
|
394
|
+
const close = async () => {
|
|
395
|
+
if (child.killed)
|
|
396
|
+
return;
|
|
397
|
+
await new Promise((resolve) => {
|
|
398
|
+
const timeout = setTimeout(() => {
|
|
399
|
+
try {
|
|
400
|
+
child.kill('SIGKILL');
|
|
401
|
+
}
|
|
402
|
+
catch {
|
|
403
|
+
// ignore force-kill failures
|
|
404
|
+
}
|
|
405
|
+
}, 2500);
|
|
406
|
+
child.once('exit', () => {
|
|
407
|
+
clearTimeout(timeout);
|
|
408
|
+
resolve();
|
|
409
|
+
});
|
|
410
|
+
try {
|
|
411
|
+
child.kill();
|
|
412
|
+
}
|
|
413
|
+
catch {
|
|
414
|
+
clearTimeout(timeout);
|
|
415
|
+
resolve();
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
};
|
|
419
|
+
return {
|
|
420
|
+
async fetchFlight(urlPath) {
|
|
421
|
+
const normalizedPath = urlPath === '/' ? '' : urlPath;
|
|
422
|
+
const flightUrl = `http://127.0.0.1:${port}/rsc${normalizedPath}`;
|
|
423
|
+
try {
|
|
424
|
+
const response = await fetch(flightUrl, {
|
|
425
|
+
headers: { Accept: 'text/x-component' },
|
|
426
|
+
});
|
|
427
|
+
if (!response.ok) {
|
|
428
|
+
return undefined;
|
|
429
|
+
}
|
|
430
|
+
return await response.text();
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
return undefined;
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
close,
|
|
437
|
+
};
|
|
438
|
+
}
|
|
328
439
|
function wrapInDocument(bodyHtml, _urlPath, metadataHtml, cwd) {
|
|
329
440
|
const headInjection = `\n <meta charset="utf-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1" />\n ${metadataHtml}\n ${getCSSLinks(cwd)}`;
|
|
330
441
|
const scripts = getChunkScripts(cwd);
|
|
@@ -373,32 +484,26 @@ async function generateStaticPages(options) {
|
|
|
373
484
|
}
|
|
374
485
|
const staticRoutes = manifest.routes.filter((r) => r.renderMode === 'static' || r.renderMode === 'isr');
|
|
375
486
|
console.log(`[vista:ssg] Found ${staticRoutes.length} routes eligible for static generation`);
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
else if (route.hasGenerateStaticParams) {
|
|
392
|
-
// Dynamic route with generateStaticParams — expand to concrete URLs
|
|
393
|
-
const paramSets = await resolveStaticParams(route, cwd);
|
|
394
|
-
if (paramSets.length === 0) {
|
|
395
|
-
console.log(`[vista:ssg] No static params for ${route.pattern} — will render on demand`);
|
|
396
|
-
continue;
|
|
397
|
-
}
|
|
398
|
-
for (const params of paramSets) {
|
|
399
|
-
const urlPath = expandPattern(route.pattern, params);
|
|
400
|
-
const page = await prerenderPage(urlPath, route, params, cwd);
|
|
487
|
+
let flightUpstream = null;
|
|
488
|
+
try {
|
|
489
|
+
flightUpstream = await startStaticFlightUpstream(cwd);
|
|
490
|
+
}
|
|
491
|
+
catch (flightError) {
|
|
492
|
+
console.warn(`[vista:ssg] Flight payload pre-generation disabled: ${flightError.message}`);
|
|
493
|
+
}
|
|
494
|
+
try {
|
|
495
|
+
for (const route of staticRoutes) {
|
|
496
|
+
if (route.type === 'static') {
|
|
497
|
+
// Simple static route — single URL
|
|
498
|
+
const urlPath = route.pattern;
|
|
499
|
+
const page = await prerenderPage(urlPath, route, undefined, cwd);
|
|
401
500
|
if (page) {
|
|
501
|
+
if (flightUpstream) {
|
|
502
|
+
const flightData = await flightUpstream.fetchFlight(urlPath);
|
|
503
|
+
if (flightData) {
|
|
504
|
+
page.flightData = flightData;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
402
507
|
(0, static_cache_1.setCachedPage)(urlPath, page);
|
|
403
508
|
(0, static_cache_1.writeStaticPageToDisk)(vistaDirRoot, urlPath, page);
|
|
404
509
|
result.generatedPaths.push(urlPath);
|
|
@@ -408,6 +513,38 @@ async function generateStaticPages(options) {
|
|
|
408
513
|
result.failedPaths.push({ path: urlPath, error: 'Prerender returned null' });
|
|
409
514
|
}
|
|
410
515
|
}
|
|
516
|
+
else if (route.hasGenerateStaticParams) {
|
|
517
|
+
// Dynamic route with generateStaticParams — expand to concrete URLs
|
|
518
|
+
const paramSets = await resolveStaticParams(route, cwd);
|
|
519
|
+
if (paramSets.length === 0) {
|
|
520
|
+
console.log(`[vista:ssg] No static params for ${route.pattern} — will render on demand`);
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
for (const params of paramSets) {
|
|
524
|
+
const urlPath = expandPattern(route.pattern, params);
|
|
525
|
+
const page = await prerenderPage(urlPath, route, params, cwd);
|
|
526
|
+
if (page) {
|
|
527
|
+
if (flightUpstream) {
|
|
528
|
+
const flightData = await flightUpstream.fetchFlight(urlPath);
|
|
529
|
+
if (flightData) {
|
|
530
|
+
page.flightData = flightData;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
(0, static_cache_1.setCachedPage)(urlPath, page);
|
|
534
|
+
(0, static_cache_1.writeStaticPageToDisk)(vistaDirRoot, urlPath, page);
|
|
535
|
+
result.generatedPaths.push(urlPath);
|
|
536
|
+
result.pagesGenerated++;
|
|
537
|
+
}
|
|
538
|
+
else {
|
|
539
|
+
result.failedPaths.push({ path: urlPath, error: 'Prerender returned null' });
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
finally {
|
|
546
|
+
if (flightUpstream) {
|
|
547
|
+
await flightUpstream.close();
|
|
411
548
|
}
|
|
412
549
|
}
|
|
413
550
|
// Generate prerender manifest
|