@vistagenic/vista 0.3.2 → 0.3.4

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.
Files changed (118) hide show
  1. package/bin/vista.js +79 -109
  2. package/dist/ai/embeddings.d.ts +11 -11
  3. package/dist/ai/embeddings.js +71 -71
  4. package/dist/ai/index.d.ts +10 -10
  5. package/dist/ai/index.js +26 -26
  6. package/dist/ai/providers/base.js +85 -85
  7. package/dist/ai/react/react-server.d.ts +1 -1
  8. package/dist/ai/react/react-server.js +17 -17
  9. package/dist/ai/react/use-agent.js +138 -138
  10. package/dist/auth/core.d.ts +140 -140
  11. package/dist/auth/core.js +165 -165
  12. package/dist/auth/index.d.ts +20 -20
  13. package/dist/auth/index.js +369 -369
  14. package/dist/auth/react-server.d.ts +1 -1
  15. package/dist/auth/react-server.js +10 -10
  16. package/dist/auth/react.d.ts +18 -18
  17. package/dist/auth/react.js +71 -71
  18. package/dist/bin/build-rsc-flashpack.js +6 -0
  19. package/dist/bin/build-rsc.js +555 -492
  20. package/dist/bin/build.js +365 -353
  21. package/dist/bin/generate.js +513 -510
  22. package/dist/bin/webpack.config.d.ts +3 -1
  23. package/dist/bin/webpack.config.js +7 -4
  24. package/dist/build/manifest.d.ts +169 -169
  25. package/dist/build/manifest.js +423 -423
  26. package/dist/build/rsc/client-manifest.d.ts +62 -62
  27. package/dist/build/rsc/client-manifest.js +295 -295
  28. package/dist/build/rsc/compiler.d.ts +3 -1
  29. package/dist/build/rsc/compiler.js +12 -7
  30. package/dist/build/rsc/native-scanner.d.ts +135 -135
  31. package/dist/build/rsc/native-scanner.js +203 -203
  32. package/dist/build/rsc/react-client-reference-manifest.d.ts +35 -28
  33. package/dist/build/rsc/react-client-reference-manifest.js +366 -240
  34. package/dist/build/standalone.js +260 -254
  35. package/dist/client/dynamic.react-server.d.ts +2 -2
  36. package/dist/client/dynamic.react-server.js +23 -23
  37. package/dist/client/link.js +1 -1
  38. package/dist/client/link.react-server.d.ts +2 -2
  39. package/dist/client/link.react-server.js +11 -11
  40. package/dist/client/navigation.js +2 -2
  41. package/dist/client/navigation.react-server.d.ts +1 -1
  42. package/dist/client/navigation.react-server.js +17 -17
  43. package/dist/client/router.react-server.d.ts +1 -1
  44. package/dist/client/router.react-server.js +17 -17
  45. package/dist/client/rsc-router.d.ts +1 -3
  46. package/dist/client/rsc-router.js +98 -45
  47. package/dist/client/rsc-router.react-server.d.ts +1 -1
  48. package/dist/client/rsc-router.react-server.js +17 -17
  49. package/dist/client/script.react-server.d.ts +2 -2
  50. package/dist/client/script.react-server.js +23 -23
  51. package/dist/config.d.ts +1 -1
  52. package/dist/config.js +1 -7
  53. package/dist/deploy/adapters/cloudflare.js +42 -41
  54. package/dist/deploy/adapters/docker.d.ts +1 -0
  55. package/dist/deploy/adapters/docker.js +5 -4
  56. package/dist/deploy/adapters/netlify.js +60 -27
  57. package/dist/deploy/adapters/vercel.js +80 -50
  58. package/dist/deploy/preflight.js +4 -3
  59. package/dist/deploy/runtime-pack.d.ts +11 -0
  60. package/dist/deploy/runtime-pack.js +300 -0
  61. package/dist/deploy/utils.d.ts +7 -1
  62. package/dist/deploy/utils.js +95 -3
  63. package/dist/flashpack/command.js +1 -0
  64. package/dist/flashpack/runtime.js +2 -1
  65. package/dist/image/get-img-props.js +21 -11
  66. package/dist/image/image-config.d.ts +2 -0
  67. package/dist/image/image-config.js +17 -0
  68. package/dist/image/index.d.ts +18 -3
  69. package/dist/image/index.js +1 -1
  70. package/dist/image/react-server.d.ts +1 -2
  71. package/dist/image/react-server.js +1 -1
  72. package/dist/index.d.ts +23 -23
  73. package/dist/index.js +61 -61
  74. package/dist/server/app-dir.d.ts +22 -0
  75. package/dist/server/app-dir.js +77 -0
  76. package/dist/server/app-router-runtime.d.ts +1 -0
  77. package/dist/server/app-router-runtime.js +34 -9
  78. package/dist/server/cookie-parse.d.ts +4 -4
  79. package/dist/server/cookie-parse.js +14 -14
  80. package/dist/server/engine.js +5 -5
  81. package/dist/server/hydration-chunks.d.ts +7 -0
  82. package/dist/server/hydration-chunks.js +49 -0
  83. package/dist/server/image-optimizer.js +2 -1
  84. package/dist/server/index.d.ts +109 -109
  85. package/dist/server/index.js +315 -315
  86. package/dist/server/middleware-runner.d.ts +125 -125
  87. package/dist/server/middleware-runner.js +607 -615
  88. package/dist/server/middleware-security.d.ts +36 -36
  89. package/dist/server/middleware-security.js +183 -183
  90. package/dist/server/module-compile-hook.js +706 -695
  91. package/dist/server/root-resolver.js +6 -5
  92. package/dist/server/rsc-engine-flashpack.d.ts +3 -1
  93. package/dist/server/rsc-engine-flashpack.js +12 -1
  94. package/dist/server/rsc-engine.d.ts +6 -1
  95. package/dist/server/rsc-engine.js +217 -280
  96. package/dist/server/rsc-upstream.js +900 -892
  97. package/dist/server/ssr-webpack-shim.d.ts +6 -0
  98. package/dist/server/ssr-webpack-shim.js +29 -0
  99. package/dist/server/static-generator.d.ts +2 -0
  100. package/dist/server/static-generator.js +33 -32
  101. package/dist/server/structure-validator.js +2 -1
  102. package/dist/server/structure-watch.js +2 -0
  103. package/dist/server/typed-api-runtime.js +639 -635
  104. package/dist/server/vista-import-map.js +134 -134
  105. package/dist/stack/index.d.ts +34 -34
  106. package/dist/stack/index.js +49 -49
  107. package/dist/stack/server/caller.d.ts +13 -13
  108. package/dist/stack/server/caller.js +42 -42
  109. package/dist/stack/server/executor.d.ts +40 -40
  110. package/dist/stack/server/executor.js +222 -222
  111. package/dist/stack/server/index.d.ts +11 -11
  112. package/dist/stack/server/index.js +24 -24
  113. package/dist/stack/server/procedure.d.ts +20 -20
  114. package/dist/stack/server/procedure.js +66 -66
  115. package/dist/stack/server/types.d.ts +113 -113
  116. package/dist/theme/react-server.d.ts +10 -10
  117. package/dist/theme/react-server.js +16 -16
  118. package/package.json +1 -1
@@ -1,295 +1,295 @@
1
- "use strict";
2
- /**
3
- * Client Component Manifest Generator
4
- *
5
- * Scans the app directory and builds a manifest of all Client Components.
6
- * Client components are those with 'use client' directive.
7
- *
8
- * The manifest maps component paths to their chunk names for client-side loading.
9
- */
10
- var __importDefault = (this && this.__importDefault) || function (mod) {
11
- return (mod && mod.__esModule) ? mod : { "default": mod };
12
- };
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.discoverProjectClientRoots = discoverProjectClientRoots;
15
- exports.generateClientManifest = generateClientManifest;
16
- exports.generateClientManifestWithRoots = generateClientManifestWithRoots;
17
- exports.getClientComponent = getClientComponent;
18
- exports.getClientComponentByPath = getClientComponentByPath;
19
- exports.isClientComponentPath = isClientComponentPath;
20
- const fs_1 = __importDefault(require("fs"));
21
- const path_1 = __importDefault(require("path"));
22
- const component_identity_1 = require("./component-identity");
23
- const constants_1 = require("../../constants");
24
- const native_scanner_1 = require("./native-scanner");
25
- const PROJECT_CLIENT_SCAN_SKIP = new Set([
26
- 'node_modules',
27
- '.vista',
28
- '.flash',
29
- 'dist',
30
- 'public',
31
- 'coverage',
32
- 'build',
33
- 'out',
34
- ]);
35
- /**
36
- * Top-level app directories that may contain `'use client'` modules.
37
- * Discovery is directory membership, not the import graph, so `utils/`,
38
- * `lib/`, and `src/` have to be scanned explicitly or they never enter
39
- * the React Client Manifest.
40
- */
41
- function discoverProjectClientRoots(cwd) {
42
- const roots = [];
43
- if (!fs_1.default.existsSync(cwd)) {
44
- return roots;
45
- }
46
- let entries;
47
- try {
48
- entries = fs_1.default.readdirSync(cwd, { withFileTypes: true });
49
- }
50
- catch {
51
- return roots;
52
- }
53
- for (const entry of entries) {
54
- if (!entry.isDirectory())
55
- continue;
56
- if (entry.name.startsWith('.'))
57
- continue;
58
- if (PROJECT_CLIENT_SCAN_SKIP.has(entry.name))
59
- continue;
60
- roots.push({
61
- dir: path_1.default.join(cwd, entry.name),
62
- prefix: `${entry.name.replace(/\\/g, '/')}/`,
63
- });
64
- }
65
- return roots;
66
- }
67
- // Try to load Rust NAPI bindings
68
- let rustNative = null;
69
- try {
70
- const possiblePaths = [
71
- path_1.default.resolve(__dirname, '../../../../../crates/vista-napi'),
72
- path_1.default.resolve(__dirname, '../../../../crates/vista-napi'),
73
- ];
74
- for (const p of possiblePaths) {
75
- try {
76
- rustNative = require(p);
77
- break;
78
- }
79
- catch (e) {
80
- // Try next
81
- }
82
- }
83
- }
84
- catch (e) {
85
- // Fallback to JS
86
- }
87
- /**
88
- * Check if source has 'use client' directive
89
- */
90
- function hasClientDirective(source) {
91
- const trimmed = source.trimStart();
92
- if (trimmed.startsWith("'use client'") || trimmed.startsWith('"use client"')) {
93
- return true;
94
- }
95
- if (rustNative?.isClientComponent) {
96
- return rustNative.isClientComponent(source);
97
- }
98
- return false;
99
- }
100
- /**
101
- * Extract export names from source (simple regex approach)
102
- */
103
- function extractExports(source) {
104
- const exports = [];
105
- // Default export
106
- if (/export\s+default\s+/.test(source)) {
107
- exports.push('default');
108
- }
109
- // Named exports: export function Name, export const Name, export class Name
110
- const namedExportRegex = /export\s+(?:async\s+)?(?:function|const|let|var|class)\s+([A-Z][a-zA-Z0-9_]*)/g;
111
- let match;
112
- while ((match = namedExportRegex.exec(source)) !== null) {
113
- exports.push(match[1]);
114
- }
115
- // Export { Name1, Name2 }
116
- const reExportRegex = /export\s+\{([^}]+)\}/g;
117
- while ((match = reExportRegex.exec(source)) !== null) {
118
- const names = match[1]
119
- .split(',')
120
- .map((n) => n
121
- .trim()
122
- .split(/\s+as\s+/)
123
- .pop()
124
- ?.trim())
125
- .filter(Boolean);
126
- exports.push(...names);
127
- }
128
- return [...new Set(exports)];
129
- }
130
- function isSameOrInside(target, ancestor) {
131
- const resolvedTarget = path_1.default.resolve(target);
132
- const resolvedAncestor = path_1.default.resolve(ancestor);
133
- if (resolvedTarget === resolvedAncestor)
134
- return true;
135
- const prefix = resolvedAncestor.endsWith(path_1.default.sep)
136
- ? resolvedAncestor
137
- : `${resolvedAncestor}${path_1.default.sep}`;
138
- return resolvedTarget.startsWith(prefix);
139
- }
140
- function additionalRootsMatchDiscovery(cwd, appDir, additionalRoots) {
141
- const discovered = discoverProjectClientRoots(cwd).filter((root) => path_1.default.resolve(root.dir) !== path_1.default.resolve(appDir));
142
- if (additionalRoots.length !== discovered.length)
143
- return false;
144
- const extra = new Set(additionalRoots.map((root) => path_1.default.resolve(root.dir)));
145
- return discovered.every((root) => extra.has(path_1.default.resolve(root.dir)));
146
- }
147
- /**
148
- * Scan directory recursively for client components
149
- */
150
- function scanForClientComponents(dir, scanRoot, components, pathPrefix = '', skipInside) {
151
- if (!fs_1.default.existsSync(dir))
152
- return;
153
- if (skipInside && isSameOrInside(dir, skipInside))
154
- return;
155
- const items = fs_1.default.readdirSync(dir, { withFileTypes: true });
156
- for (const item of items) {
157
- const fullPath = path_1.default.join(dir, item.name);
158
- if (item.isDirectory()) {
159
- if (!item.name.startsWith('.') && item.name !== 'node_modules') {
160
- scanForClientComponents(fullPath, scanRoot, components, pathPrefix, skipInside);
161
- }
162
- }
163
- else if (item.isFile()) {
164
- if (skipInside && isSameOrInside(fullPath, skipInside))
165
- continue;
166
- const ext = path_1.default.extname(item.name);
167
- if (!['.tsx', '.ts', '.jsx', '.js'].includes(ext))
168
- continue;
169
- try {
170
- const source = fs_1.default.readFileSync(fullPath, 'utf-8');
171
- if (hasClientDirective(source)) {
172
- const relativePathBase = (0, component_identity_1.relativeComponentPath)(scanRoot, fullPath);
173
- const relativePath = pathPrefix ? `${pathPrefix}${relativePathBase}` : relativePathBase;
174
- const moduleId = (0, component_identity_1.createComponentId)('client', relativePath);
175
- components.push({
176
- id: moduleId,
177
- path: relativePath,
178
- absolutePath: fullPath,
179
- chunkName: (0, component_identity_1.createChunkName)(relativePath),
180
- exports: extractExports(source),
181
- async: false,
182
- });
183
- }
184
- }
185
- catch (e) {
186
- console.warn(`[Vista RSC] Failed to read ${fullPath}:`, e);
187
- }
188
- }
189
- }
190
- }
191
- /**
192
- * Generate the client component manifest
193
- */
194
- function generateClientManifest(cwd, appDir) {
195
- const additionalRoots = discoverProjectClientRoots(cwd).filter((root) => path_1.default.resolve(root.dir) !== path_1.default.resolve(appDir));
196
- return generateClientManifestWithRoots(cwd, appDir, additionalRoots);
197
- }
198
- function readBuildId(cwd) {
199
- const buildIdPath = path_1.default.join(cwd, constants_1.BUILD_DIR, 'BUILD_ID');
200
- try {
201
- if (fs_1.default.existsSync(buildIdPath)) {
202
- return fs_1.default.readFileSync(buildIdPath, 'utf-8').trim();
203
- }
204
- }
205
- catch {
206
- // Use dev
207
- }
208
- return 'dev';
209
- }
210
- function nativeClientManifestToJs(native) {
211
- const clientModules = {};
212
- const pathToId = {};
213
- const ssrModuleMapping = {};
214
- for (const component of native.clientModules) {
215
- const entry = {
216
- id: component.id,
217
- path: component.path,
218
- absolutePath: component.absolutePath,
219
- chunkName: component.chunkName,
220
- exports: component.exports,
221
- async: component.asyncLoad,
222
- };
223
- clientModules[component.id] = entry;
224
- const normalizedRelativePath = (0, component_identity_1.normalizeComponentPath)(component.path);
225
- const normalizedAbsolutePath = (0, component_identity_1.normalizeComponentPath)(component.absolutePath);
226
- pathToId[component.path] = component.id;
227
- pathToId[normalizedRelativePath] = component.id;
228
- pathToId[component.absolutePath] = component.id;
229
- pathToId[normalizedAbsolutePath] = component.id;
230
- ssrModuleMapping[component.absolutePath] = `${constants_1.STATIC_CHUNKS_PATH}${component.chunkName}.js`;
231
- ssrModuleMapping[normalizedAbsolutePath] = `${constants_1.STATIC_CHUNKS_PATH}${component.chunkName}.js`;
232
- }
233
- return {
234
- buildId: native.buildId,
235
- clientModules,
236
- pathToId,
237
- ssrModuleMapping,
238
- };
239
- }
240
- function generateClientManifestWithRoots(cwd, appDir, additionalRoots = []) {
241
- if (additionalRootsMatchDiscovery(cwd, appDir, additionalRoots)) {
242
- const native = (0, native_scanner_1.generateClientManifestForProjectNative)(cwd, appDir, readBuildId(cwd));
243
- if (native && Array.isArray(native.clientModules)) {
244
- return nativeClientManifestToJs(native);
245
- }
246
- }
247
- const components = [];
248
- scanForClientComponents(appDir, appDir, components);
249
- for (const root of additionalRoots) {
250
- if (!fs_1.default.existsSync(root.dir))
251
- continue;
252
- scanForClientComponents(root.dir, root.dir, components, root.prefix || '', appDir);
253
- }
254
- const clientModules = {};
255
- const pathToId = {};
256
- const ssrModuleMapping = {};
257
- for (const component of components) {
258
- clientModules[component.id] = component;
259
- const normalizedRelativePath = (0, component_identity_1.normalizeComponentPath)(component.path);
260
- const normalizedAbsolutePath = (0, component_identity_1.normalizeComponentPath)(component.absolutePath);
261
- pathToId[component.path] = component.id;
262
- pathToId[normalizedRelativePath] = component.id;
263
- pathToId[component.absolutePath] = component.id;
264
- pathToId[normalizedAbsolutePath] = component.id;
265
- ssrModuleMapping[component.absolutePath] = `${constants_1.STATIC_CHUNKS_PATH}${component.chunkName}.js`;
266
- ssrModuleMapping[normalizedAbsolutePath] = `${constants_1.STATIC_CHUNKS_PATH}${component.chunkName}.js`;
267
- }
268
- return {
269
- buildId: readBuildId(cwd),
270
- clientModules,
271
- pathToId,
272
- ssrModuleMapping,
273
- };
274
- }
275
- /**
276
- * Get client component info by module ID
277
- */
278
- function getClientComponent(manifest, moduleId) {
279
- return manifest.clientModules[moduleId];
280
- }
281
- /**
282
- * Get client component by file path
283
- */
284
- function getClientComponentByPath(manifest, filePath) {
285
- const moduleId = manifest.pathToId[filePath];
286
- if (!moduleId)
287
- return undefined;
288
- return manifest.clientModules[moduleId];
289
- }
290
- /**
291
- * Check if a path is a client component
292
- */
293
- function isClientComponentPath(manifest, filePath) {
294
- return filePath in manifest.pathToId;
295
- }
1
+ "use strict";
2
+ /**
3
+ * Client Component Manifest Generator
4
+ *
5
+ * Scans the app directory and builds a manifest of all Client Components.
6
+ * Client components are those with 'use client' directive.
7
+ *
8
+ * The manifest maps component paths to their chunk names for client-side loading.
9
+ */
10
+ var __importDefault = (this && this.__importDefault) || function (mod) {
11
+ return (mod && mod.__esModule) ? mod : { "default": mod };
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.discoverProjectClientRoots = discoverProjectClientRoots;
15
+ exports.generateClientManifest = generateClientManifest;
16
+ exports.generateClientManifestWithRoots = generateClientManifestWithRoots;
17
+ exports.getClientComponent = getClientComponent;
18
+ exports.getClientComponentByPath = getClientComponentByPath;
19
+ exports.isClientComponentPath = isClientComponentPath;
20
+ const fs_1 = __importDefault(require("fs"));
21
+ const path_1 = __importDefault(require("path"));
22
+ const component_identity_1 = require("./component-identity");
23
+ const constants_1 = require("../../constants");
24
+ const native_scanner_1 = require("./native-scanner");
25
+ const PROJECT_CLIENT_SCAN_SKIP = new Set([
26
+ 'node_modules',
27
+ '.vista',
28
+ '.flash',
29
+ 'dist',
30
+ 'public',
31
+ 'coverage',
32
+ 'build',
33
+ 'out',
34
+ ]);
35
+ /**
36
+ * Top-level app directories that may contain `'use client'` modules.
37
+ * Discovery is directory membership, not the import graph, so `utils/`,
38
+ * `lib/`, and `src/` have to be scanned explicitly or they never enter
39
+ * the React Client Manifest.
40
+ */
41
+ function discoverProjectClientRoots(cwd) {
42
+ const roots = [];
43
+ if (!fs_1.default.existsSync(cwd)) {
44
+ return roots;
45
+ }
46
+ let entries;
47
+ try {
48
+ entries = fs_1.default.readdirSync(cwd, { withFileTypes: true });
49
+ }
50
+ catch {
51
+ return roots;
52
+ }
53
+ for (const entry of entries) {
54
+ if (!entry.isDirectory())
55
+ continue;
56
+ if (entry.name.startsWith('.'))
57
+ continue;
58
+ if (PROJECT_CLIENT_SCAN_SKIP.has(entry.name))
59
+ continue;
60
+ roots.push({
61
+ dir: path_1.default.join(cwd, entry.name),
62
+ prefix: `${entry.name.replace(/\\/g, '/')}/`,
63
+ });
64
+ }
65
+ return roots;
66
+ }
67
+ // Try to load Rust NAPI bindings
68
+ let rustNative = null;
69
+ try {
70
+ const possiblePaths = [
71
+ path_1.default.resolve(__dirname, '../../../../../crates/vista-napi'),
72
+ path_1.default.resolve(__dirname, '../../../../crates/vista-napi'),
73
+ ];
74
+ for (const p of possiblePaths) {
75
+ try {
76
+ rustNative = require(p);
77
+ break;
78
+ }
79
+ catch (e) {
80
+ // Try next
81
+ }
82
+ }
83
+ }
84
+ catch (e) {
85
+ // Fallback to JS
86
+ }
87
+ /**
88
+ * Check if source has 'use client' directive
89
+ */
90
+ function hasClientDirective(source) {
91
+ const trimmed = source.trimStart();
92
+ if (trimmed.startsWith("'use client'") || trimmed.startsWith('"use client"')) {
93
+ return true;
94
+ }
95
+ if (rustNative?.isClientComponent) {
96
+ return rustNative.isClientComponent(source);
97
+ }
98
+ return false;
99
+ }
100
+ /**
101
+ * Extract export names from source (simple regex approach)
102
+ */
103
+ function extractExports(source) {
104
+ const exports = [];
105
+ // Default export
106
+ if (/export\s+default\s+/.test(source)) {
107
+ exports.push('default');
108
+ }
109
+ // Named exports: export function Name, export const Name, export class Name
110
+ const namedExportRegex = /export\s+(?:async\s+)?(?:function|const|let|var|class)\s+([A-Z][a-zA-Z0-9_]*)/g;
111
+ let match;
112
+ while ((match = namedExportRegex.exec(source)) !== null) {
113
+ exports.push(match[1]);
114
+ }
115
+ // Export { Name1, Name2 }
116
+ const reExportRegex = /export\s+\{([^}]+)\}/g;
117
+ while ((match = reExportRegex.exec(source)) !== null) {
118
+ const names = match[1]
119
+ .split(',')
120
+ .map((n) => n
121
+ .trim()
122
+ .split(/\s+as\s+/)
123
+ .pop()
124
+ ?.trim())
125
+ .filter(Boolean);
126
+ exports.push(...names);
127
+ }
128
+ return [...new Set(exports)];
129
+ }
130
+ function isSameOrInside(target, ancestor) {
131
+ const resolvedTarget = path_1.default.resolve(target);
132
+ const resolvedAncestor = path_1.default.resolve(ancestor);
133
+ if (resolvedTarget === resolvedAncestor)
134
+ return true;
135
+ const prefix = resolvedAncestor.endsWith(path_1.default.sep)
136
+ ? resolvedAncestor
137
+ : `${resolvedAncestor}${path_1.default.sep}`;
138
+ return resolvedTarget.startsWith(prefix);
139
+ }
140
+ function additionalRootsMatchDiscovery(cwd, appDir, additionalRoots) {
141
+ const discovered = discoverProjectClientRoots(cwd).filter((root) => path_1.default.resolve(root.dir) !== path_1.default.resolve(appDir));
142
+ if (additionalRoots.length !== discovered.length)
143
+ return false;
144
+ const extra = new Set(additionalRoots.map((root) => path_1.default.resolve(root.dir)));
145
+ return discovered.every((root) => extra.has(path_1.default.resolve(root.dir)));
146
+ }
147
+ /**
148
+ * Scan directory recursively for client components
149
+ */
150
+ function scanForClientComponents(dir, scanRoot, components, pathPrefix = '', skipInside) {
151
+ if (!fs_1.default.existsSync(dir))
152
+ return;
153
+ if (skipInside && isSameOrInside(dir, skipInside))
154
+ return;
155
+ const items = fs_1.default.readdirSync(dir, { withFileTypes: true });
156
+ for (const item of items) {
157
+ const fullPath = path_1.default.join(dir, item.name);
158
+ if (item.isDirectory()) {
159
+ if (!item.name.startsWith('.') && item.name !== 'node_modules') {
160
+ scanForClientComponents(fullPath, scanRoot, components, pathPrefix, skipInside);
161
+ }
162
+ }
163
+ else if (item.isFile()) {
164
+ if (skipInside && isSameOrInside(fullPath, skipInside))
165
+ continue;
166
+ const ext = path_1.default.extname(item.name);
167
+ if (!['.tsx', '.ts', '.jsx', '.js'].includes(ext))
168
+ continue;
169
+ try {
170
+ const source = fs_1.default.readFileSync(fullPath, 'utf-8');
171
+ if (hasClientDirective(source)) {
172
+ const relativePathBase = (0, component_identity_1.relativeComponentPath)(scanRoot, fullPath);
173
+ const relativePath = pathPrefix ? `${pathPrefix}${relativePathBase}` : relativePathBase;
174
+ const moduleId = (0, component_identity_1.createComponentId)('client', relativePath);
175
+ components.push({
176
+ id: moduleId,
177
+ path: relativePath,
178
+ absolutePath: fullPath,
179
+ chunkName: (0, component_identity_1.createChunkName)(relativePath),
180
+ exports: extractExports(source),
181
+ async: false,
182
+ });
183
+ }
184
+ }
185
+ catch (e) {
186
+ console.warn(`[Vista RSC] Failed to read ${fullPath}:`, e);
187
+ }
188
+ }
189
+ }
190
+ }
191
+ /**
192
+ * Generate the client component manifest
193
+ */
194
+ function generateClientManifest(cwd, appDir) {
195
+ const additionalRoots = discoverProjectClientRoots(cwd).filter((root) => path_1.default.resolve(root.dir) !== path_1.default.resolve(appDir));
196
+ return generateClientManifestWithRoots(cwd, appDir, additionalRoots);
197
+ }
198
+ function readBuildId(cwd) {
199
+ const buildIdPath = path_1.default.join(cwd, constants_1.BUILD_DIR, 'BUILD_ID');
200
+ try {
201
+ if (fs_1.default.existsSync(buildIdPath)) {
202
+ return fs_1.default.readFileSync(buildIdPath, 'utf-8').trim();
203
+ }
204
+ }
205
+ catch {
206
+ // Use dev
207
+ }
208
+ return 'dev';
209
+ }
210
+ function nativeClientManifestToJs(native) {
211
+ const clientModules = {};
212
+ const pathToId = {};
213
+ const ssrModuleMapping = {};
214
+ for (const component of native.clientModules) {
215
+ const entry = {
216
+ id: component.id,
217
+ path: component.path,
218
+ absolutePath: component.absolutePath,
219
+ chunkName: component.chunkName,
220
+ exports: component.exports,
221
+ async: component.asyncLoad,
222
+ };
223
+ clientModules[component.id] = entry;
224
+ const normalizedRelativePath = (0, component_identity_1.normalizeComponentPath)(component.path);
225
+ const normalizedAbsolutePath = (0, component_identity_1.normalizeComponentPath)(component.absolutePath);
226
+ pathToId[component.path] = component.id;
227
+ pathToId[normalizedRelativePath] = component.id;
228
+ pathToId[component.absolutePath] = component.id;
229
+ pathToId[normalizedAbsolutePath] = component.id;
230
+ ssrModuleMapping[component.absolutePath] = `${constants_1.STATIC_CHUNKS_PATH}${component.chunkName}.js`;
231
+ ssrModuleMapping[normalizedAbsolutePath] = `${constants_1.STATIC_CHUNKS_PATH}${component.chunkName}.js`;
232
+ }
233
+ return {
234
+ buildId: native.buildId,
235
+ clientModules,
236
+ pathToId,
237
+ ssrModuleMapping,
238
+ };
239
+ }
240
+ function generateClientManifestWithRoots(cwd, appDir, additionalRoots = []) {
241
+ if (additionalRootsMatchDiscovery(cwd, appDir, additionalRoots)) {
242
+ const native = (0, native_scanner_1.generateClientManifestForProjectNative)(cwd, appDir, readBuildId(cwd));
243
+ if (native && Array.isArray(native.clientModules)) {
244
+ return nativeClientManifestToJs(native);
245
+ }
246
+ }
247
+ const components = [];
248
+ scanForClientComponents(appDir, appDir, components);
249
+ for (const root of additionalRoots) {
250
+ if (!fs_1.default.existsSync(root.dir))
251
+ continue;
252
+ scanForClientComponents(root.dir, root.dir, components, root.prefix || '', appDir);
253
+ }
254
+ const clientModules = {};
255
+ const pathToId = {};
256
+ const ssrModuleMapping = {};
257
+ for (const component of components) {
258
+ clientModules[component.id] = component;
259
+ const normalizedRelativePath = (0, component_identity_1.normalizeComponentPath)(component.path);
260
+ const normalizedAbsolutePath = (0, component_identity_1.normalizeComponentPath)(component.absolutePath);
261
+ pathToId[component.path] = component.id;
262
+ pathToId[normalizedRelativePath] = component.id;
263
+ pathToId[component.absolutePath] = component.id;
264
+ pathToId[normalizedAbsolutePath] = component.id;
265
+ ssrModuleMapping[component.absolutePath] = `${constants_1.STATIC_CHUNKS_PATH}${component.chunkName}.js`;
266
+ ssrModuleMapping[normalizedAbsolutePath] = `${constants_1.STATIC_CHUNKS_PATH}${component.chunkName}.js`;
267
+ }
268
+ return {
269
+ buildId: readBuildId(cwd),
270
+ clientModules,
271
+ pathToId,
272
+ ssrModuleMapping,
273
+ };
274
+ }
275
+ /**
276
+ * Get client component info by module ID
277
+ */
278
+ function getClientComponent(manifest, moduleId) {
279
+ return manifest.clientModules[moduleId];
280
+ }
281
+ /**
282
+ * Get client component by file path
283
+ */
284
+ function getClientComponentByPath(manifest, filePath) {
285
+ const moduleId = manifest.pathToId[filePath];
286
+ if (!moduleId)
287
+ return undefined;
288
+ return manifest.clientModules[moduleId];
289
+ }
290
+ /**
291
+ * Check if a path is a client component
292
+ */
293
+ function isClientComponentPath(manifest, filePath) {
294
+ return filePath in manifest.pathToId;
295
+ }
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import webpack from 'webpack';
9
9
  import { VistaDirs } from '../manifest';
10
- import type { VistaEngineVariant } from '../../config';
10
+ import type { DeployOutput, VistaEngineVariant } from '../../config';
11
11
  export interface RSCCompilerOptions {
12
12
  cwd: string;
13
13
  isDev: boolean;
@@ -15,6 +15,8 @@ export interface RSCCompilerOptions {
15
15
  buildId: string;
16
16
  engineVariant?: VistaEngineVariant;
17
17
  clientReferenceFiles?: string[];
18
+ imagesUnoptimized?: boolean;
19
+ deployOutput?: DeployOutput;
18
20
  }
19
21
  /**
20
22
  * Create Server-Side Webpack Configuration