@vistagenic/vista 0.2.10 → 0.2.13
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/bin/vista.js +183 -36
- package/dist/bin/build-rsc-flashpack.d.ts +4 -0
- package/dist/bin/build-rsc-flashpack.js +29 -0
- package/dist/bin/build-rsc.js +61 -16
- package/dist/bin/build.js +36 -13
- package/dist/bin/devtools-indicator-snippet.js +30 -0
- package/dist/bin/file-scanner.d.ts +1 -1
- package/dist/bin/file-scanner.js +8 -0
- package/dist/bin/flashpack-runner.d.ts +1 -0
- package/dist/bin/flashpack-runner.js +61 -0
- package/dist/bin/server-component-plugin.d.ts +6 -4
- package/dist/bin/server-component-plugin.js +22 -69
- package/dist/bin/webpack.config.d.ts +3 -0
- package/dist/bin/webpack.config.js +12 -3
- package/dist/build/manifest.d.ts +17 -3
- package/dist/build/manifest.js +99 -23
- package/dist/build/rsc/compiler.d.ts +2 -0
- package/dist/build/rsc/compiler.js +25 -5
- package/dist/build/rsc/react-client-reference-manifest.d.ts +22 -0
- package/dist/build/rsc/react-client-reference-manifest.js +219 -0
- package/dist/build/rsc/server-manifest.d.ts +23 -2
- package/dist/build/rsc/server-manifest.js +162 -24
- package/dist/build/standalone.d.ts +31 -0
- package/dist/build/standalone.js +334 -0
- package/dist/client/rsc-router.d.ts +31 -0
- package/dist/client/rsc-router.js +89 -0
- package/dist/config.d.ts +23 -0
- package/dist/config.js +106 -5
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +3 -1
- package/dist/flashpack/command.d.ts +8 -0
- package/dist/flashpack/command.js +134 -0
- package/dist/flashpack/runtime.d.ts +39 -0
- package/dist/flashpack/runtime.js +249 -0
- package/dist/server/app-router-runtime.d.ts +26 -0
- package/dist/server/app-router-runtime.js +321 -0
- package/dist/server/artifact-validator.js +21 -1
- package/dist/server/cache.d.ts +10 -0
- package/dist/server/cache.js +270 -0
- package/dist/server/client-boundary.js +20 -2
- package/dist/server/engine.js +236 -159
- package/dist/server/fetch-policy.d.ts +2 -0
- package/dist/server/fetch-policy.js +123 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.js +131 -22
- package/dist/server/module-boundary-validator.d.ts +15 -0
- package/dist/server/module-boundary-validator.js +262 -0
- package/dist/server/module-compile-hook.d.ts +7 -0
- package/dist/server/module-compile-hook.js +662 -0
- package/dist/server/ppr.d.ts +18 -0
- package/dist/server/ppr.js +59 -0
- package/dist/server/request-context.d.ts +31 -0
- package/dist/server/request-context.js +95 -0
- package/dist/server/rsc-engine-flashpack.d.ts +4 -0
- package/dist/server/rsc-engine-flashpack.js +27 -0
- package/dist/server/rsc-engine.d.ts +2 -0
- package/dist/server/rsc-engine.js +589 -317
- package/dist/server/rsc-upstream.js +539 -233
- package/dist/server/runtime-actions.d.ts +5 -0
- package/dist/server/runtime-actions.js +80 -0
- package/dist/server/runtime-artifacts.d.ts +11 -0
- package/dist/server/runtime-artifacts.js +35 -0
- package/dist/server/segment-config.d.ts +37 -0
- package/dist/server/segment-config.js +205 -0
- package/dist/server/spawn-permissions.d.ts +2 -0
- package/dist/server/spawn-permissions.js +21 -0
- package/dist/server/static-cache.d.ts +15 -1
- package/dist/server/static-cache.js +83 -3
- package/dist/server/static-generator.js +254 -100
- package/dist/server/structure-validator.d.ts +1 -1
- package/dist/server/structure-validator.js +26 -5
- package/dist/server/structure-watch.js +1 -1
- package/dist/server/typed-api-runtime.d.ts +1 -0
- package/dist/server/typed-api-runtime.js +145 -25
- package/dist/server/vista-import-map.d.ts +1 -0
- package/dist/server/vista-import-map.js +123 -0
- package/package.json +13 -1
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
const fs_1 = __importDefault(require("fs"));
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const build_rsc_1 = require("./build-rsc");
|
|
9
|
+
const rsc_engine_1 = require("../server/rsc-engine");
|
|
10
|
+
function parseCliArg(flag) {
|
|
11
|
+
const index = process.argv.indexOf(flag);
|
|
12
|
+
if (index === -1)
|
|
13
|
+
return undefined;
|
|
14
|
+
return process.argv[index + 1];
|
|
15
|
+
}
|
|
16
|
+
function normalizePhase(raw) {
|
|
17
|
+
const value = String(raw || '')
|
|
18
|
+
.trim()
|
|
19
|
+
.toLowerCase();
|
|
20
|
+
if (value === 'dev' || value === 'development')
|
|
21
|
+
return 'dev';
|
|
22
|
+
if (value === 'start')
|
|
23
|
+
return 'start';
|
|
24
|
+
return 'build';
|
|
25
|
+
}
|
|
26
|
+
async function main() {
|
|
27
|
+
const phase = normalizePhase(parseCliArg('--phase'));
|
|
28
|
+
const rawPort = parseCliArg('--port') || process.env.PORT || '3003';
|
|
29
|
+
const port = Number(rawPort) || 3003;
|
|
30
|
+
process.env.VISTA_ENGINE = 'flashpack';
|
|
31
|
+
process.env.VISTA_ENGINE_VARIANT = 'flashpack';
|
|
32
|
+
process.env.VISTA_FLASHPACK = 'true';
|
|
33
|
+
process.env.VISTA_FLASHPACK_PIPELINE = process.env.VISTA_FLASHPACK_PIPELINE || 'rust-cli';
|
|
34
|
+
if (phase === 'build') {
|
|
35
|
+
await (0, build_rsc_1.buildRSC)(false);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (phase === 'dev') {
|
|
39
|
+
const buildResult = await (0, build_rsc_1.buildRSC)(true);
|
|
40
|
+
(0, rsc_engine_1.startRSCServer)({
|
|
41
|
+
port,
|
|
42
|
+
compiler: buildResult.clientCompiler,
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const standaloneServerPath = path_1.default.join(process.cwd(), '.vista', 'standalone', 'server.js');
|
|
47
|
+
if (fs_1.default.existsSync(standaloneServerPath)) {
|
|
48
|
+
const standalone = require(standaloneServerPath);
|
|
49
|
+
const startStandaloneServer = standalone.startStandaloneServer || standalone.default || standalone;
|
|
50
|
+
startStandaloneServer({
|
|
51
|
+
port,
|
|
52
|
+
engine: 'flashpack',
|
|
53
|
+
});
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
(0, rsc_engine_1.startRSCServer)({ port });
|
|
57
|
+
}
|
|
58
|
+
main().catch((error) => {
|
|
59
|
+
console.error(error && error.stack ? error.stack : error);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
});
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Vista Server Component Webpack Plugin
|
|
3
3
|
*
|
|
4
|
-
* Checks for server
|
|
5
|
-
*
|
|
4
|
+
* Checks for server/client boundary violations and invalid route segment
|
|
5
|
+
* config on every webpack compilation.
|
|
6
6
|
*/
|
|
7
7
|
import type { Compiler } from 'webpack';
|
|
8
8
|
export declare class VistaServerComponentPlugin {
|
|
9
9
|
private appDir;
|
|
10
|
+
private componentsDir?;
|
|
11
|
+
private cacheComponentsEnabled;
|
|
10
12
|
constructor(options: {
|
|
11
13
|
appDir: string;
|
|
14
|
+
componentsDir?: string;
|
|
15
|
+
cacheComponentsEnabled?: boolean;
|
|
12
16
|
});
|
|
13
17
|
apply(compiler: Compiler): void;
|
|
14
|
-
private checkServerComponents;
|
|
15
|
-
private scanDirectory;
|
|
16
18
|
}
|
|
17
19
|
export default VistaServerComponentPlugin;
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Vista Server Component Webpack Plugin
|
|
4
4
|
*
|
|
5
|
-
* Checks for server
|
|
6
|
-
*
|
|
5
|
+
* Checks for server/client boundary violations and invalid route segment
|
|
6
|
+
* config on every webpack compilation.
|
|
7
7
|
*/
|
|
8
8
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
9
|
if (k2 === undefined) k2 = k;
|
|
@@ -40,94 +40,47 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
40
40
|
})();
|
|
41
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
42
|
exports.VistaServerComponentPlugin = void 0;
|
|
43
|
-
const fs = __importStar(require("fs"));
|
|
44
43
|
const path = __importStar(require("path"));
|
|
45
|
-
|
|
46
|
-
const CLIENT_HOOKS = [
|
|
47
|
-
'useState', 'useEffect', 'useLayoutEffect', 'useReducer', 'useRef',
|
|
48
|
-
'useImperativeHandle', 'useCallback', 'useMemo', 'useContext',
|
|
49
|
-
'useDebugValue', 'useDeferredValue', 'useTransition', 'useId',
|
|
50
|
-
'useSyncExternalStore', 'useInsertionEffect',
|
|
51
|
-
];
|
|
52
|
-
function hasClientDirective(source) {
|
|
53
|
-
const trimmed = source.trim();
|
|
54
|
-
return trimmed.startsWith("'use client'") || trimmed.startsWith('"use client"');
|
|
55
|
-
}
|
|
56
|
-
function detectClientHooks(source) {
|
|
57
|
-
const usedHooks = [];
|
|
58
|
-
for (const hook of CLIENT_HOOKS) {
|
|
59
|
-
const regex = new RegExp(`\\b${hook}\\s*[(<]`, 'g');
|
|
60
|
-
if (regex.test(source)) {
|
|
61
|
-
usedHooks.push(hook);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
// Check for event handlers
|
|
65
|
-
if (/\bon[A-Z][a-zA-Z]*\s*=/g.test(source)) {
|
|
66
|
-
usedHooks.push('event handlers');
|
|
67
|
-
}
|
|
68
|
-
return [...new Set(usedHooks)];
|
|
69
|
-
}
|
|
44
|
+
const module_boundary_validator_1 = require("../server/module-boundary-validator");
|
|
70
45
|
class VistaServerComponentPlugin {
|
|
71
46
|
appDir;
|
|
47
|
+
componentsDir;
|
|
48
|
+
cacheComponentsEnabled;
|
|
72
49
|
constructor(options) {
|
|
73
50
|
this.appDir = options.appDir;
|
|
51
|
+
this.componentsDir = options.componentsDir;
|
|
52
|
+
this.cacheComponentsEnabled = Boolean(options.cacheComponentsEnabled);
|
|
74
53
|
}
|
|
75
54
|
apply(compiler) {
|
|
76
55
|
// Use afterCompile hook so we can add errors to compilation
|
|
77
56
|
compiler.hooks.afterCompile.tap('VistaServerComponentPlugin', (compilation) => {
|
|
78
|
-
const errors =
|
|
57
|
+
const errors = (0, module_boundary_validator_1.validateModuleBoundaries)({
|
|
58
|
+
appDir: this.appDir,
|
|
59
|
+
extraRoots: this.componentsDir ? [this.componentsDir] : [],
|
|
60
|
+
cacheComponentsEnabled: this.cacheComponentsEnabled,
|
|
61
|
+
}).issues;
|
|
79
62
|
if (errors.length > 0) {
|
|
80
63
|
console.log('');
|
|
81
|
-
console.log('\x1b[41m\x1b[37m ERROR \x1b[0m \x1b[31mServer
|
|
64
|
+
console.log('\x1b[41m\x1b[37m ERROR \x1b[0m \x1b[31mServer/Segment Validation Error\x1b[0m');
|
|
82
65
|
console.log('');
|
|
83
66
|
for (const error of errors) {
|
|
84
|
-
|
|
85
|
-
console.log(
|
|
86
|
-
console.log(
|
|
87
|
-
console.log(` \x1b[36mTo fix:\x1b[0m Add \x1b[33m'use client'\x1b[0m at the top of your file:`);
|
|
88
|
-
console.log('');
|
|
89
|
-
console.log(` \x1b[32m'use client';\x1b[0m`);
|
|
67
|
+
const relativeFile = path.relative(this.appDir, error.filePath);
|
|
68
|
+
console.log(`\x1b[31m✗\x1b[0m ${relativeFile}`);
|
|
69
|
+
console.log(` ${error.message}`);
|
|
90
70
|
console.log('');
|
|
71
|
+
if (error.fix) {
|
|
72
|
+
console.log(` \x1b[36mTo fix:\x1b[0m ${error.fix}`);
|
|
73
|
+
console.log('');
|
|
74
|
+
}
|
|
91
75
|
// Add webpack error so it shows in overlay
|
|
92
76
|
const WebpackError = require('webpack').WebpackError;
|
|
93
|
-
const err = new WebpackError(
|
|
94
|
-
|
|
95
|
-
`Add 'use client' at the top of your file to make it a Client Component.`);
|
|
96
|
-
err.file = error.file;
|
|
77
|
+
const err = new WebpackError(`${error.message}\n${error.fix ? `Fix: ${error.fix}` : ''}`.trim());
|
|
78
|
+
err.file = relativeFile;
|
|
97
79
|
compilation.errors.push(err);
|
|
98
80
|
}
|
|
99
81
|
}
|
|
100
82
|
});
|
|
101
83
|
}
|
|
102
|
-
checkServerComponents() {
|
|
103
|
-
const errors = [];
|
|
104
|
-
this.scanDirectory(this.appDir, errors);
|
|
105
|
-
return errors;
|
|
106
|
-
}
|
|
107
|
-
scanDirectory(dir, errors) {
|
|
108
|
-
if (!fs.existsSync(dir))
|
|
109
|
-
return;
|
|
110
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
111
|
-
for (const entry of entries) {
|
|
112
|
-
const fullPath = path.join(dir, entry.name);
|
|
113
|
-
if (entry.isDirectory()) {
|
|
114
|
-
if (!entry.name.startsWith('.') && entry.name !== 'node_modules') {
|
|
115
|
-
this.scanDirectory(fullPath, errors);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
else if (entry.isFile() && /\.(tsx?|jsx?)$/.test(entry.name)) {
|
|
119
|
-
const source = fs.readFileSync(fullPath, 'utf-8');
|
|
120
|
-
const isClient = hasClientDirective(source);
|
|
121
|
-
const clientHooks = detectClientHooks(source);
|
|
122
|
-
if (!isClient && clientHooks.length > 0) {
|
|
123
|
-
errors.push({
|
|
124
|
-
file: path.relative(this.appDir, fullPath),
|
|
125
|
-
hooks: clientHooks
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
84
|
}
|
|
132
85
|
exports.VistaServerComponentPlugin = VistaServerComponentPlugin;
|
|
133
86
|
exports.default = VistaServerComponentPlugin;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import webpack from 'webpack';
|
|
2
|
+
import type { VistaEngineVariant } from '../config';
|
|
2
3
|
export interface WebpackConfigOptions {
|
|
3
4
|
cwd: string;
|
|
4
5
|
isDev: boolean;
|
|
6
|
+
engineVariant?: VistaEngineVariant;
|
|
7
|
+
cacheComponentsEnabled?: boolean;
|
|
5
8
|
}
|
|
6
9
|
export declare function createWebpackConfig(options: WebpackConfigOptions): webpack.Configuration;
|
|
@@ -12,8 +12,9 @@ const server_component_plugin_1 = require("./server-component-plugin");
|
|
|
12
12
|
const vista_flight_plugin_1 = require("../build/webpack/plugins/vista-flight-plugin");
|
|
13
13
|
const constants_1 = require("../constants");
|
|
14
14
|
function createWebpackConfig(options) {
|
|
15
|
-
const { cwd, isDev } = options;
|
|
15
|
+
const { cwd, isDev, engineVariant = 'default', cacheComponentsEnabled = false } = options;
|
|
16
16
|
const vistaDir = path_1.default.join(cwd, constants_1.BUILD_DIR);
|
|
17
|
+
const flashDir = path_1.default.join(cwd, constants_1.FLASH_DIR);
|
|
17
18
|
const entryPoint = path_1.default.join(vistaDir, 'client.tsx');
|
|
18
19
|
// Find React - check local node_modules first, then traverse up for monorepo hoisting
|
|
19
20
|
const findModulePath = (moduleName) => {
|
|
@@ -56,7 +57,9 @@ function createWebpackConfig(options) {
|
|
|
56
57
|
cache: isDev
|
|
57
58
|
? {
|
|
58
59
|
type: 'filesystem',
|
|
59
|
-
cacheDirectory:
|
|
60
|
+
cacheDirectory: engineVariant === 'flashpack'
|
|
61
|
+
? path_1.default.join(flashDir, 'cache', 'webpack')
|
|
62
|
+
: path_1.default.join(cwd, 'node_modules', '.cache', 'vista-webpack'),
|
|
60
63
|
buildDependencies: {
|
|
61
64
|
config: [__filename],
|
|
62
65
|
},
|
|
@@ -143,7 +146,11 @@ function createWebpackConfig(options) {
|
|
|
143
146
|
},
|
|
144
147
|
plugins: [
|
|
145
148
|
// Server Component enforcement - runs on every compile
|
|
146
|
-
new server_component_plugin_1.VistaServerComponentPlugin({
|
|
149
|
+
new server_component_plugin_1.VistaServerComponentPlugin({
|
|
150
|
+
appDir: path_1.default.join(cwd, 'app'),
|
|
151
|
+
componentsDir: path_1.default.join(cwd, 'components'),
|
|
152
|
+
cacheComponentsEnabled,
|
|
153
|
+
}),
|
|
147
154
|
// Vista Flight Plugin - RSC bundle separation and manifest
|
|
148
155
|
new vista_flight_plugin_1.VistaFlightPlugin({ appDir: path_1.default.join(cwd, 'app'), dev: isDev }),
|
|
149
156
|
...(isDev
|
|
@@ -156,6 +163,8 @@ function createWebpackConfig(options) {
|
|
|
156
163
|
: []),
|
|
157
164
|
new webpack_1.default.DefinePlugin({
|
|
158
165
|
'process.env.NODE_ENV': JSON.stringify(isDev ? 'development' : 'production'),
|
|
166
|
+
'process.env.VISTA_ENGINE': JSON.stringify(engineVariant),
|
|
167
|
+
'process.env.VISTA_ENGINE_VARIANT': JSON.stringify(engineVariant),
|
|
159
168
|
}),
|
|
160
169
|
new mini_css_extract_plugin_1.default({
|
|
161
170
|
filename: isDev ? 'modules.css' : 'modules-[contenthash:8].css',
|
package/dist/build/manifest.d.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Generates build manifests, BUILD_ID, and manages .vista output structure.
|
|
5
5
|
*/
|
|
6
|
+
import type { VistaEngineVariant } from '../config';
|
|
7
|
+
import type { ImageConfig } from '../image/image-config';
|
|
6
8
|
/**
|
|
7
9
|
* Generate a unique build ID based on timestamp and random bytes.
|
|
8
10
|
*/
|
|
@@ -14,6 +16,7 @@ export declare function getBuildId(vistaDir: string, forceNew?: boolean): string
|
|
|
14
16
|
export interface VistaDirs {
|
|
15
17
|
root: string;
|
|
16
18
|
cache: string;
|
|
19
|
+
imageCache: string;
|
|
17
20
|
server: string;
|
|
18
21
|
static: string;
|
|
19
22
|
chunks: string;
|
|
@@ -48,6 +51,10 @@ export interface ArtifactManifest {
|
|
|
48
51
|
requiredServerFiles: string;
|
|
49
52
|
reactClientManifest: string;
|
|
50
53
|
reactServerManifest: string;
|
|
54
|
+
serverManifest?: string;
|
|
55
|
+
runtimeManifest?: string;
|
|
56
|
+
fileTrace?: string;
|
|
57
|
+
standaloneServer?: string;
|
|
51
58
|
};
|
|
52
59
|
}
|
|
53
60
|
/**
|
|
@@ -61,10 +68,16 @@ interface RouteLike {
|
|
|
61
68
|
}
|
|
62
69
|
export declare function generateAppPathRoutesManifest(vistaDir: string, routes?: RouteLike[]): Record<string, string>;
|
|
63
70
|
export declare function generatePrerenderManifest(vistaDir: string): void;
|
|
64
|
-
export declare function generateRequiredServerFilesManifest(cwd: string, vistaDir: string): void;
|
|
71
|
+
export declare function generateRequiredServerFilesManifest(cwd: string, vistaDir: string, extraFiles?: string[], appDir?: string): void;
|
|
65
72
|
export declare function ensureJsonFile(vistaDir: string, relativePath: string, fallback?: unknown): void;
|
|
66
|
-
export declare function writeArtifactManifest(vistaDir: string, buildId: string): ArtifactManifest;
|
|
73
|
+
export declare function writeArtifactManifest(vistaDir: string, buildId: string, extraManifestEntries?: Partial<ArtifactManifest['manifests']>): ArtifactManifest;
|
|
67
74
|
export declare function writeCanonicalVistaArtifacts(cwd: string, vistaDir: string, buildId: string, routes?: RouteLike[]): ArtifactManifest;
|
|
75
|
+
interface WriteReservedVistaArtifactsOptions {
|
|
76
|
+
buildId: string;
|
|
77
|
+
engineVariant?: VistaEngineVariant;
|
|
78
|
+
imagesConfig?: Partial<ImageConfig> | undefined;
|
|
79
|
+
}
|
|
80
|
+
export declare function writeReservedVistaArtifacts(vistaDir: string, options: WriteReservedVistaArtifactsOptions): void;
|
|
68
81
|
export interface RouteInfo {
|
|
69
82
|
page: string;
|
|
70
83
|
regex: string;
|
|
@@ -109,7 +122,7 @@ export declare function generateServerComponentsManifest(vistaDir: string, serve
|
|
|
109
122
|
/**
|
|
110
123
|
* Get Webpack cache configuration for persistent caching.
|
|
111
124
|
*/
|
|
112
|
-
export declare function getWebpackCacheConfig(vistaDir: string, buildId: string, name: string): {
|
|
125
|
+
export declare function getWebpackCacheConfig(vistaDir: string, buildId: string, name: string, engineVariant?: VistaEngineVariant, cwd?: string): {
|
|
113
126
|
type: "filesystem";
|
|
114
127
|
version: string;
|
|
115
128
|
cacheDirectory: string;
|
|
@@ -122,4 +135,5 @@ export declare function getWebpackCacheConfig(vistaDir: string, buildId: string,
|
|
|
122
135
|
* Clean old cache entries (keeps last N builds).
|
|
123
136
|
*/
|
|
124
137
|
export declare function cleanOldCache(vistaDir: string, keepBuilds?: number): void;
|
|
138
|
+
export declare function pruneEmptyVistaDirectories(vistaDir: string): void;
|
|
125
139
|
export {};
|
package/dist/build/manifest.js
CHANGED
|
@@ -18,11 +18,13 @@ exports.generateRequiredServerFilesManifest = generateRequiredServerFilesManifes
|
|
|
18
18
|
exports.ensureJsonFile = ensureJsonFile;
|
|
19
19
|
exports.writeArtifactManifest = writeArtifactManifest;
|
|
20
20
|
exports.writeCanonicalVistaArtifacts = writeCanonicalVistaArtifacts;
|
|
21
|
+
exports.writeReservedVistaArtifacts = writeReservedVistaArtifacts;
|
|
21
22
|
exports.generateRoutesManifest = generateRoutesManifest;
|
|
22
23
|
exports.generateClientComponentsManifest = generateClientComponentsManifest;
|
|
23
24
|
exports.generateServerComponentsManifest = generateServerComponentsManifest;
|
|
24
25
|
exports.getWebpackCacheConfig = getWebpackCacheConfig;
|
|
25
26
|
exports.cleanOldCache = cleanOldCache;
|
|
27
|
+
exports.pruneEmptyVistaDirectories = pruneEmptyVistaDirectories;
|
|
26
28
|
const fs_1 = __importDefault(require("fs"));
|
|
27
29
|
const path_1 = __importDefault(require("path"));
|
|
28
30
|
const crypto_1 = __importDefault(require("crypto"));
|
|
@@ -62,6 +64,7 @@ function createVistaDirectories(cwd, mode = 'legacy') {
|
|
|
62
64
|
const dirs = {
|
|
63
65
|
root,
|
|
64
66
|
cache: path_1.default.join(root, 'cache'),
|
|
67
|
+
imageCache: path_1.default.join(root, 'cache', 'images'),
|
|
65
68
|
server: path_1.default.join(root, 'server'),
|
|
66
69
|
static: path_1.default.join(root, 'static'),
|
|
67
70
|
chunks: path_1.default.join(root, 'static', 'chunks'),
|
|
@@ -71,19 +74,9 @@ function createVistaDirectories(cwd, mode = 'legacy') {
|
|
|
71
74
|
// Always create root
|
|
72
75
|
fs_1.default.mkdirSync(root, { recursive: true });
|
|
73
76
|
if (mode === 'rsc') {
|
|
74
|
-
|
|
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) => {
|
|
77
|
+
[dirs.root, dirs.cache, dirs.imageCache, dirs.server, dirs.static, dirs.chunks, dirs.media].forEach((dir) => {
|
|
78
78
|
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
79
79
|
});
|
|
80
|
-
// Cache subdirectories
|
|
81
|
-
fs_1.default.mkdirSync(path_1.default.join(dirs.cache, 'webpack'), { recursive: true });
|
|
82
|
-
fs_1.default.mkdirSync(path_1.default.join(dirs.cache, 'swc'), { recursive: true });
|
|
83
|
-
fs_1.default.mkdirSync(path_1.default.join(dirs.cache, 'images'), { recursive: true });
|
|
84
|
-
// Server subdirectories
|
|
85
|
-
fs_1.default.mkdirSync(path_1.default.join(dirs.server, 'app'), { recursive: true });
|
|
86
|
-
fs_1.default.mkdirSync(path_1.default.join(dirs.server, 'chunks'), { recursive: true });
|
|
87
80
|
}
|
|
88
81
|
// Legacy mode: only root dir is created — webpack outputs directly into .vista/
|
|
89
82
|
return dirs;
|
|
@@ -159,18 +152,21 @@ function generatePrerenderManifest(vistaDir) {
|
|
|
159
152
|
};
|
|
160
153
|
fs_1.default.writeFileSync(path_1.default.join(vistaDir, 'prerender-manifest.json'), JSON.stringify(manifest, null, 2));
|
|
161
154
|
}
|
|
162
|
-
function generateRequiredServerFilesManifest(cwd, vistaDir) {
|
|
155
|
+
function generateRequiredServerFilesManifest(cwd, vistaDir, extraFiles = [], appDir = cwd) {
|
|
156
|
+
const files = Array.from(new Set([
|
|
157
|
+
`${constants_1.BUILD_DIR}/BUILD_ID`,
|
|
158
|
+
`${constants_1.BUILD_DIR}/build-manifest.json`,
|
|
159
|
+
`${constants_1.BUILD_DIR}/routes-manifest.json`,
|
|
160
|
+
`${constants_1.BUILD_DIR}/app-path-routes-manifest.json`,
|
|
161
|
+
`${constants_1.BUILD_DIR}/server/server-manifest.json`,
|
|
162
|
+
...extraFiles,
|
|
163
|
+
]));
|
|
163
164
|
const manifest = {
|
|
164
165
|
version: 1,
|
|
165
166
|
config: {},
|
|
166
|
-
appDir
|
|
167
|
-
relativeAppDir: '.',
|
|
168
|
-
files
|
|
169
|
-
`${constants_1.BUILD_DIR}/BUILD_ID`,
|
|
170
|
-
`${constants_1.BUILD_DIR}/build-manifest.json`,
|
|
171
|
-
`${constants_1.BUILD_DIR}/routes-manifest.json`,
|
|
172
|
-
`${constants_1.BUILD_DIR}/app-path-routes-manifest.json`,
|
|
173
|
-
],
|
|
167
|
+
appDir,
|
|
168
|
+
relativeAppDir: path_1.default.relative(cwd, appDir) || '.',
|
|
169
|
+
files,
|
|
174
170
|
};
|
|
175
171
|
fs_1.default.writeFileSync(path_1.default.join(vistaDir, 'required-server-files.json'), JSON.stringify(manifest, null, 2));
|
|
176
172
|
}
|
|
@@ -180,7 +176,7 @@ function ensureJsonFile(vistaDir, relativePath, fallback = {}) {
|
|
|
180
176
|
fs_1.default.writeFileSync(absolutePath, JSON.stringify(fallback, null, 2));
|
|
181
177
|
}
|
|
182
178
|
}
|
|
183
|
-
function writeArtifactManifest(vistaDir, buildId) {
|
|
179
|
+
function writeArtifactManifest(vistaDir, buildId, extraManifestEntries = {}) {
|
|
184
180
|
const artifactManifest = {
|
|
185
181
|
schemaVersion: 1,
|
|
186
182
|
buildId,
|
|
@@ -194,6 +190,7 @@ function writeArtifactManifest(vistaDir, buildId) {
|
|
|
194
190
|
requiredServerFiles: 'required-server-files.json',
|
|
195
191
|
reactClientManifest: 'react-client-manifest.json',
|
|
196
192
|
reactServerManifest: 'react-server-manifest.json',
|
|
193
|
+
...extraManifestEntries,
|
|
197
194
|
},
|
|
198
195
|
};
|
|
199
196
|
fs_1.default.writeFileSync(path_1.default.join(vistaDir, 'artifact-manifest.json'), JSON.stringify(artifactManifest, null, 2));
|
|
@@ -212,6 +209,59 @@ function writeCanonicalVistaArtifacts(cwd, vistaDir, buildId, routes = []) {
|
|
|
212
209
|
ensureJsonFile(vistaDir, 'react-server-manifest.json', {});
|
|
213
210
|
return writeArtifactManifest(vistaDir, buildId);
|
|
214
211
|
}
|
|
212
|
+
function writeReservedVistaArtifacts(vistaDir, options) {
|
|
213
|
+
const engineVariant = options.engineVariant || 'default';
|
|
214
|
+
const generatedAt = new Date().toISOString();
|
|
215
|
+
const cacheDir = path_1.default.join(vistaDir, 'cache');
|
|
216
|
+
const imageCacheDir = path_1.default.join(cacheDir, 'images');
|
|
217
|
+
const mediaDir = path_1.default.join(vistaDir, 'static', 'media');
|
|
218
|
+
fs_1.default.mkdirSync(cacheDir, { recursive: true });
|
|
219
|
+
fs_1.default.mkdirSync(imageCacheDir, { recursive: true });
|
|
220
|
+
fs_1.default.mkdirSync(mediaDir, { recursive: true });
|
|
221
|
+
fs_1.default.writeFileSync(path_1.default.join(cacheDir, 'cache-manifest.json'), JSON.stringify({
|
|
222
|
+
schemaVersion: 1,
|
|
223
|
+
buildId: options.buildId,
|
|
224
|
+
generatedAt,
|
|
225
|
+
engine: engineVariant,
|
|
226
|
+
activeCacheRoot: engineVariant === 'flashpack' ? '.flash/cache' : '.vista/cache/webpack',
|
|
227
|
+
directories: {
|
|
228
|
+
localCache: '.vista/cache',
|
|
229
|
+
webpack: engineVariant === 'flashpack' ? '.flash/cache/webpack' : '.vista/cache/webpack',
|
|
230
|
+
images: '.vista/cache/images',
|
|
231
|
+
},
|
|
232
|
+
notes: [
|
|
233
|
+
engineVariant === 'flashpack'
|
|
234
|
+
? 'Flashpack stores its hot build cache in .flash while .vista/cache keeps framework metadata.'
|
|
235
|
+
: 'Default engine stores framework metadata here and may add webpack cache artifacts during rebuilds.',
|
|
236
|
+
],
|
|
237
|
+
}, null, 2));
|
|
238
|
+
fs_1.default.writeFileSync(path_1.default.join(imageCacheDir, 'manifest.json'), JSON.stringify({
|
|
239
|
+
schemaVersion: 1,
|
|
240
|
+
buildId: options.buildId,
|
|
241
|
+
generatedAt,
|
|
242
|
+
endpoint: constants_1.IMAGE_ENDPOINT,
|
|
243
|
+
cacheDirectory: '.vista/cache/images',
|
|
244
|
+
config: options.imagesConfig || {},
|
|
245
|
+
behavior: {
|
|
246
|
+
optimization: 'on-demand',
|
|
247
|
+
staticImportsEmitInto: '.vista/static/media',
|
|
248
|
+
publicReferencesStayIn: 'public/',
|
|
249
|
+
},
|
|
250
|
+
}, null, 2));
|
|
251
|
+
const emittedMedia = fs_1.default
|
|
252
|
+
.readdirSync(mediaDir, { withFileTypes: true })
|
|
253
|
+
.filter((entry) => entry.isFile() && entry.name !== 'media-manifest.json')
|
|
254
|
+
.map((entry) => entry.name)
|
|
255
|
+
.sort();
|
|
256
|
+
fs_1.default.writeFileSync(path_1.default.join(mediaDir, 'media-manifest.json'), JSON.stringify({
|
|
257
|
+
schemaVersion: 1,
|
|
258
|
+
buildId: options.buildId,
|
|
259
|
+
generatedAt,
|
|
260
|
+
mediaDirectory: '.vista/static/media',
|
|
261
|
+
emittedFiles: emittedMedia,
|
|
262
|
+
note: 'This directory is reserved for emitted media assets. Public file references are served from public/ and may leave this list empty.',
|
|
263
|
+
}, null, 2));
|
|
264
|
+
}
|
|
215
265
|
/**
|
|
216
266
|
* Generate routes-manifest.json from route tree.
|
|
217
267
|
*/
|
|
@@ -257,11 +307,14 @@ function generateServerComponentsManifest(vistaDir, serverModules = {}) {
|
|
|
257
307
|
/**
|
|
258
308
|
* Get Webpack cache configuration for persistent caching.
|
|
259
309
|
*/
|
|
260
|
-
function getWebpackCacheConfig(vistaDir, buildId, name) {
|
|
310
|
+
function getWebpackCacheConfig(vistaDir, buildId, name, engineVariant = 'default', cwd = process.cwd()) {
|
|
311
|
+
const cacheDirectory = engineVariant === 'flashpack'
|
|
312
|
+
? path_1.default.join(cwd, constants_1.FLASH_DIR, 'cache', 'webpack')
|
|
313
|
+
: path_1.default.join(vistaDir, 'cache', 'webpack');
|
|
261
314
|
return {
|
|
262
315
|
type: 'filesystem',
|
|
263
316
|
version: buildId,
|
|
264
|
-
cacheDirectory
|
|
317
|
+
cacheDirectory,
|
|
265
318
|
name: name,
|
|
266
319
|
buildDependencies: {
|
|
267
320
|
config: [__filename],
|
|
@@ -289,3 +342,26 @@ function cleanOldCache(vistaDir, keepBuilds = 5) {
|
|
|
289
342
|
fs_1.default.rmSync(entry.path, { recursive: true, force: true });
|
|
290
343
|
});
|
|
291
344
|
}
|
|
345
|
+
function pruneEmptyVistaDirectories(vistaDir) {
|
|
346
|
+
if (!fs_1.default.existsSync(vistaDir))
|
|
347
|
+
return;
|
|
348
|
+
const prune = (absolutePath) => {
|
|
349
|
+
const entries = fs_1.default.readdirSync(absolutePath, { withFileTypes: true });
|
|
350
|
+
for (const entry of entries) {
|
|
351
|
+
if (!entry.isDirectory())
|
|
352
|
+
continue;
|
|
353
|
+
const childPath = path_1.default.join(absolutePath, entry.name);
|
|
354
|
+
prune(childPath);
|
|
355
|
+
}
|
|
356
|
+
// Never remove the root .vista directory itself.
|
|
357
|
+
if (absolutePath === vistaDir)
|
|
358
|
+
return false;
|
|
359
|
+
const remaining = fs_1.default.readdirSync(absolutePath);
|
|
360
|
+
if (remaining.length === 0) {
|
|
361
|
+
fs_1.default.rmdirSync(absolutePath);
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
return false;
|
|
365
|
+
};
|
|
366
|
+
prune(vistaDir);
|
|
367
|
+
}
|
|
@@ -7,11 +7,13 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import webpack from 'webpack';
|
|
9
9
|
import { VistaDirs } from '../manifest';
|
|
10
|
+
import type { VistaEngineVariant } from '../../config';
|
|
10
11
|
export interface RSCCompilerOptions {
|
|
11
12
|
cwd: string;
|
|
12
13
|
isDev: boolean;
|
|
13
14
|
vistaDirs: VistaDirs;
|
|
14
15
|
buildId: string;
|
|
16
|
+
engineVariant?: VistaEngineVariant;
|
|
15
17
|
clientReferenceFiles?: string[];
|
|
16
18
|
}
|
|
17
19
|
/**
|
|
@@ -19,6 +19,7 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
19
19
|
const manifest_1 = require("../manifest");
|
|
20
20
|
const client_manifest_1 = require("./client-manifest");
|
|
21
21
|
const server_manifest_1 = require("./server-manifest");
|
|
22
|
+
const react_client_reference_manifest_1 = require("./react-client-reference-manifest");
|
|
22
23
|
const constants_1 = require("../../constants");
|
|
23
24
|
// Find module path (handles monorepo hoisting)
|
|
24
25
|
const findModulePath = (moduleName, cwd) => {
|
|
@@ -59,7 +60,7 @@ function resolveFromWorkspace(specifier, cwd) {
|
|
|
59
60
|
* Output goes to .vista/server/ and is NEVER sent to the client.
|
|
60
61
|
*/
|
|
61
62
|
function createServerWebpackConfig(options) {
|
|
62
|
-
const { cwd, isDev, vistaDirs, buildId } = options;
|
|
63
|
+
const { cwd, isDev, vistaDirs, buildId, engineVariant = 'default' } = options;
|
|
63
64
|
const swcLoaderPath = resolveFromWorkspace('swc-loader', cwd);
|
|
64
65
|
const nullLoaderPath = resolveFromWorkspace('null-loader', cwd);
|
|
65
66
|
const cssLoaderPath = resolveFromWorkspace('css-loader', cwd);
|
|
@@ -119,7 +120,9 @@ function createServerWebpackConfig(options) {
|
|
|
119
120
|
callback();
|
|
120
121
|
},
|
|
121
122
|
],
|
|
122
|
-
cache: isDev
|
|
123
|
+
cache: isDev
|
|
124
|
+
? (0, manifest_1.getWebpackCacheConfig)(vistaDirs.root, buildId, 'server-development', engineVariant, cwd)
|
|
125
|
+
: false,
|
|
123
126
|
resolve: {
|
|
124
127
|
extensions: ['.tsx', '.ts', '.jsx', '.js'],
|
|
125
128
|
modules: [path_1.default.resolve(cwd, 'node_modules'), 'node_modules'],
|
|
@@ -175,6 +178,8 @@ function createServerWebpackConfig(options) {
|
|
|
175
178
|
plugins: [
|
|
176
179
|
new webpack_1.default.DefinePlugin({
|
|
177
180
|
'process.env.NODE_ENV': JSON.stringify(isDev ? 'development' : 'production'),
|
|
181
|
+
'process.env.VISTA_ENGINE': JSON.stringify(engineVariant),
|
|
182
|
+
'process.env.VISTA_ENGINE_VARIANT': JSON.stringify(engineVariant),
|
|
178
183
|
[constants_1.BUILD_ID_DEFINE]: JSON.stringify(buildId),
|
|
179
184
|
[constants_1.SERVER_DEFINE]: 'true',
|
|
180
185
|
}),
|
|
@@ -190,7 +195,7 @@ function createServerWebpackConfig(options) {
|
|
|
190
195
|
* Server components are replaced with client references.
|
|
191
196
|
*/
|
|
192
197
|
function createClientWebpackConfig(options) {
|
|
193
|
-
const { cwd, isDev, vistaDirs, buildId, clientReferenceFiles = [] } = options;
|
|
198
|
+
const { cwd, isDev, vistaDirs, buildId, engineVariant = 'default', clientReferenceFiles = [] } = options;
|
|
194
199
|
const swcLoaderPath = resolveFromWorkspace('swc-loader', cwd);
|
|
195
200
|
const nullLoaderPath = resolveFromWorkspace('null-loader', cwd);
|
|
196
201
|
const cssLoaderPath = resolveFromWorkspace('css-loader', cwd);
|
|
@@ -343,14 +348,26 @@ function createClientWebpackConfig(options) {
|
|
|
343
348
|
// and preloadModule with the chunks array).
|
|
344
349
|
{
|
|
345
350
|
apply(compiler) {
|
|
346
|
-
compiler.hooks.make.tap('
|
|
351
|
+
compiler.hooks.make.tap('VistaFlightManifestPatch', (compilation) => {
|
|
347
352
|
compilation.hooks.processAssets.tap({
|
|
348
|
-
name: '
|
|
353
|
+
name: 'VistaFlightManifestPatch',
|
|
349
354
|
// Run after the Flight plugin (REPORT stage) has emitted assets
|
|
350
355
|
stage: webpack_1.default.Compilation.PROCESS_ASSETS_STAGE_REPORT + 1,
|
|
351
356
|
}, () => {
|
|
357
|
+
const clientAssetName = '../../react-client-manifest.json';
|
|
352
358
|
const ssrAssetName = '../../react-server-manifest.json';
|
|
359
|
+
const clientAsset = compilation.getAsset(clientAssetName);
|
|
353
360
|
const ssrAsset = compilation.getAsset(ssrAssetName);
|
|
361
|
+
if (clientAsset) {
|
|
362
|
+
try {
|
|
363
|
+
const manifest = JSON.parse(clientAsset.source.source().toString());
|
|
364
|
+
const normalized = (0, react_client_reference_manifest_1.normalizeReactClientReferenceManifest)(manifest);
|
|
365
|
+
compilation.updateAsset(clientAssetName, new webpack_1.default.sources.RawSource(JSON.stringify(normalized, null, 2), false));
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
// If parsing fails, leave the asset as-is
|
|
369
|
+
}
|
|
370
|
+
}
|
|
354
371
|
if (!ssrAsset)
|
|
355
372
|
return;
|
|
356
373
|
try {
|
|
@@ -372,6 +389,7 @@ function createClientWebpackConfig(options) {
|
|
|
372
389
|
}
|
|
373
390
|
}
|
|
374
391
|
}
|
|
392
|
+
(0, react_client_reference_manifest_1.normalizeReactServerConsumerManifest)(manifest);
|
|
375
393
|
compilation.updateAsset(ssrAssetName, new webpack_1.default.sources.RawSource(JSON.stringify(manifest, null, 2), false));
|
|
376
394
|
}
|
|
377
395
|
}
|
|
@@ -384,6 +402,8 @@ function createClientWebpackConfig(options) {
|
|
|
384
402
|
},
|
|
385
403
|
new webpack_1.default.DefinePlugin({
|
|
386
404
|
'process.env.NODE_ENV': JSON.stringify(isDev ? 'development' : 'production'),
|
|
405
|
+
'process.env.VISTA_ENGINE': JSON.stringify(engineVariant),
|
|
406
|
+
'process.env.VISTA_ENGINE_VARIANT': JSON.stringify(engineVariant),
|
|
387
407
|
[constants_1.BUILD_ID_DEFINE]: JSON.stringify(buildId),
|
|
388
408
|
[constants_1.SERVER_DEFINE]: 'false',
|
|
389
409
|
}),
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ReactClientReferenceManifestEntry {
|
|
2
|
+
id: string | number;
|
|
3
|
+
chunks: Array<string | number>;
|
|
4
|
+
name: string;
|
|
5
|
+
}
|
|
6
|
+
export type ReactClientReferenceManifest = Record<string, ReactClientReferenceManifestEntry>;
|
|
7
|
+
export interface ReactServerConsumerManifestEntry {
|
|
8
|
+
specifier?: string;
|
|
9
|
+
id?: string | number;
|
|
10
|
+
chunks?: Array<string | number>;
|
|
11
|
+
name?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ReactServerConsumerManifest {
|
|
14
|
+
moduleLoading?: {
|
|
15
|
+
prefix: string;
|
|
16
|
+
crossOrigin: string | null;
|
|
17
|
+
};
|
|
18
|
+
moduleMap?: Record<string, Record<string, ReactServerConsumerManifestEntry>>;
|
|
19
|
+
serverModuleMap?: Record<string, unknown>;
|
|
20
|
+
}
|
|
21
|
+
export declare function normalizeReactClientReferenceManifest(input: ReactClientReferenceManifest): ReactClientReferenceManifest;
|
|
22
|
+
export declare function normalizeReactServerConsumerManifest(input: ReactServerConsumerManifest): ReactServerConsumerManifest;
|