@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,240 +1,366 @@
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.normalizeReactClientReferenceManifest = normalizeReactClientReferenceManifest;
7
- exports.normalizeReactServerConsumerManifest = normalizeReactServerConsumerManifest;
8
- exports.createGuardedReactClientManifest = createGuardedReactClientManifest;
9
- const fs_1 = __importDefault(require("fs"));
10
- const url_1 = require("url");
11
- function extractExportNames(source) {
12
- const exports = new Set();
13
- if (/export\s+default\s+/.test(source)) {
14
- exports.add('default');
15
- }
16
- const namedExportRegex = /export\s+(?:async\s+)?(?:function|const|let|var|class)\s+([A-Za-z_$][\w$]*)/g;
17
- let match;
18
- while ((match = namedExportRegex.exec(source)) !== null) {
19
- exports.add(match[1]);
20
- }
21
- const reExportRegex = /export\s+\{([^}]+)\}/g;
22
- while ((match = reExportRegex.exec(source)) !== null) {
23
- const names = match[1]
24
- .split(',')
25
- .map((entry) => entry
26
- .trim()
27
- .split(/\s+as\s+/)
28
- .pop()
29
- ?.trim())
30
- .filter(Boolean);
31
- for (const name of names) {
32
- exports.add(name);
33
- }
34
- }
35
- const commonJsExportRegex = /exports\.([A-Za-z_$][\w$]*)\s*=/g;
36
- while ((match = commonJsExportRegex.exec(source)) !== null) {
37
- if (match[1] !== '__esModule') {
38
- exports.add(match[1]);
39
- }
40
- }
41
- if (/module\.exports\s*=/.test(source) || /exports\.default\s*=/.test(source)) {
42
- exports.add('default');
43
- }
44
- return Array.from(exports);
45
- }
46
- function resolveManifestFilePath(specifier) {
47
- const baseSpecifier = specifier.split('#', 1)[0];
48
- if (!baseSpecifier.startsWith('file://')) {
49
- return null;
50
- }
51
- try {
52
- return (0, url_1.fileURLToPath)(baseSpecifier);
53
- }
54
- catch {
55
- try {
56
- return decodeURI(baseSpecifier
57
- .replace(/^file:\/\/\//, '')
58
- .replace(/^file:\/\//, ''));
59
- }
60
- catch {
61
- return null;
62
- }
63
- }
64
- }
65
- function addDriveLetterVariants(specifier, variants) {
66
- variants.add(specifier);
67
- const match = specifier.match(/^file:\/\/\/([A-Za-z]):/);
68
- if (!match) {
69
- return;
70
- }
71
- const lowerDrive = match[1].toLowerCase();
72
- const upperDrive = match[1].toUpperCase();
73
- variants.add(specifier.replace(/^file:\/\/\/([A-Za-z]):/, `file:///${lowerDrive}:`));
74
- variants.add(specifier.replace(/^file:\/\/\/([A-Za-z]):/, `file:///${upperDrive}:`));
75
- }
76
- function buildSpecifierVariants(specifier) {
77
- const baseSpecifier = specifier.split('#', 1)[0];
78
- const variants = new Set();
79
- addDriveLetterVariants(baseSpecifier, variants);
80
- if (baseSpecifier.startsWith('file://')) {
81
- try {
82
- addDriveLetterVariants(decodeURI(baseSpecifier), variants);
83
- }
84
- catch {
85
- // ignore decode failures
86
- }
87
- try {
88
- addDriveLetterVariants((0, url_1.pathToFileURL)((0, url_1.fileURLToPath)(baseSpecifier)).toString(), variants);
89
- }
90
- catch {
91
- // ignore encode failures
92
- }
93
- }
94
- return Array.from(variants);
95
- }
96
- function createAliasedEntry(entry, exportName) {
97
- if (exportName === '') {
98
- return {
99
- ...entry,
100
- name: '',
101
- };
102
- }
103
- return {
104
- ...entry,
105
- name: exportName,
106
- };
107
- }
108
- function normalizeReactClientReferenceManifest(input) {
109
- const manifest = { ...input };
110
- for (const [rawSpecifier, rawEntry] of Object.entries(input || {})) {
111
- if (!rawEntry || typeof rawEntry !== 'object') {
112
- continue;
113
- }
114
- const entry = {
115
- id: rawEntry.id,
116
- chunks: Array.isArray(rawEntry.chunks) ? rawEntry.chunks : [],
117
- name: rawEntry.name || '*',
118
- };
119
- const sourcePath = resolveManifestFilePath(rawSpecifier);
120
- const exportNames = new Set();
121
- if (entry.name && entry.name !== '*') {
122
- exportNames.add(entry.name);
123
- }
124
- if (sourcePath && fs_1.default.existsSync(sourcePath)) {
125
- try {
126
- const source = fs_1.default.readFileSync(sourcePath, 'utf-8');
127
- for (const exportName of extractExportNames(source)) {
128
- exportNames.add(exportName);
129
- }
130
- }
131
- catch {
132
- // Keep manifest normalization resilient even if a source file disappears mid-build.
133
- }
134
- }
135
- for (const baseSpecifier of buildSpecifierVariants(rawSpecifier)) {
136
- if (!manifest[baseSpecifier]) {
137
- manifest[baseSpecifier] = entry;
138
- }
139
- const emptyExportKey = `${baseSpecifier}#`;
140
- if (!manifest[emptyExportKey]) {
141
- manifest[emptyExportKey] = createAliasedEntry(entry, '');
142
- }
143
- const defaultExportKey = `${baseSpecifier}#default`;
144
- if (!manifest[defaultExportKey]) {
145
- manifest[defaultExportKey] = createAliasedEntry(entry, 'default');
146
- }
147
- for (const exportName of exportNames) {
148
- const exportKey = `${baseSpecifier}#${exportName}`;
149
- if (!manifest[exportKey]) {
150
- manifest[exportKey] = createAliasedEntry(entry, exportName);
151
- }
152
- }
153
- }
154
- }
155
- return manifest;
156
- }
157
- function normalizeReactServerConsumerManifest(input) {
158
- if (!input?.moduleMap) {
159
- return input;
160
- }
161
- for (const [moduleKey, rawExportsMap] of Object.entries(input.moduleMap)) {
162
- const normalizedExportsMap = {};
163
- const exportNames = new Set();
164
- let sourceSpecifier = null;
165
- let seedEntry = null;
166
- for (const [exportName, rawEntry] of Object.entries(rawExportsMap || {})) {
167
- const entry = {
168
- id: rawEntry?.id ?? rawEntry?.specifier ?? moduleKey,
169
- chunks: Array.isArray(rawEntry?.chunks) ? rawEntry.chunks : [],
170
- name: rawEntry?.name || exportName,
171
- };
172
- normalizedExportsMap[exportName] = entry;
173
- if (exportName !== '*') {
174
- exportNames.add(exportName);
175
- }
176
- if (entry.name && entry.name !== '*') {
177
- exportNames.add(entry.name);
178
- }
179
- if (!seedEntry) {
180
- seedEntry = entry;
181
- }
182
- if (!sourceSpecifier && typeof entry.id === 'string' && entry.id.startsWith('file://')) {
183
- sourceSpecifier = entry.id;
184
- }
185
- if (!sourceSpecifier && typeof rawEntry?.specifier === 'string' && rawEntry.specifier.startsWith('file://')) {
186
- sourceSpecifier = rawEntry.specifier;
187
- }
188
- }
189
- const sourcePath = sourceSpecifier ? resolveManifestFilePath(sourceSpecifier) : null;
190
- if (sourcePath && fs_1.default.existsSync(sourcePath)) {
191
- try {
192
- const source = fs_1.default.readFileSync(sourcePath, 'utf-8');
193
- for (const exportName of extractExportNames(source)) {
194
- exportNames.add(exportName);
195
- }
196
- }
197
- catch {
198
- // Keep manifest normalization resilient even if the source file changes mid-build.
199
- }
200
- }
201
- if (seedEntry) {
202
- if (!normalizedExportsMap['*']) {
203
- normalizedExportsMap['*'] = {
204
- ...seedEntry,
205
- name: '*',
206
- };
207
- }
208
- for (const exportName of exportNames) {
209
- if (!normalizedExportsMap[exportName]) {
210
- normalizedExportsMap[exportName] = {
211
- ...seedEntry,
212
- name: exportName,
213
- };
214
- }
215
- }
216
- }
217
- input.moduleMap[moduleKey] = normalizedExportsMap;
218
- }
219
- return input;
220
- }
221
- /**
222
- * React looks up `file://...#ExportName` in the Flight manifest and throws a
223
- * generic error when the key is missing. Wrap the manifest so the message names
224
- * the file and the scan-directory requirement.
225
- */
226
- function createGuardedReactClientManifest(manifest) {
227
- return new Proxy(manifest, {
228
- get(target, prop, receiver) {
229
- if (typeof prop === 'string' &&
230
- (prop.startsWith('file:') || prop.includes('#')) &&
231
- !Object.prototype.hasOwnProperty.call(target, prop)) {
232
- const fileHint = prop.split('#')[0];
233
- throw new Error(`Could not find the module "${prop}" in the React Client Manifest. ` +
234
- `Client Components need a 'use client' directive and must live under a scanned project directory ` +
235
- `(app/, components/, utils/, lib/, src/, ...). Missing: ${fileHint}`);
236
- }
237
- return Reflect.get(target, prop, receiver);
238
- },
239
- });
240
- }
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.resolveReactClientManifestEntry = resolveReactClientManifestEntry;
7
+ exports.normalizeReactClientReferenceManifest = normalizeReactClientReferenceManifest;
8
+ exports.normalizeReactServerConsumerManifest = normalizeReactServerConsumerManifest;
9
+ exports.createGuardedReactClientManifest = createGuardedReactClientManifest;
10
+ const fs_1 = __importDefault(require("fs"));
11
+ const url_1 = require("url");
12
+ function extractExportNames(source) {
13
+ const exports = new Set();
14
+ if (/export\s+default\s+/.test(source)) {
15
+ exports.add('default');
16
+ }
17
+ const namedExportRegex = /export\s+(?:async\s+)?(?:function|const|let|var|class)\s+([A-Za-z_$][\w$]*)/g;
18
+ let match;
19
+ while ((match = namedExportRegex.exec(source)) !== null) {
20
+ exports.add(match[1]);
21
+ }
22
+ const reExportRegex = /export\s+\{([^}]+)\}/g;
23
+ while ((match = reExportRegex.exec(source)) !== null) {
24
+ const names = match[1]
25
+ .split(',')
26
+ .map((entry) => entry
27
+ .trim()
28
+ .split(/\s+as\s+/)
29
+ .pop()
30
+ ?.trim())
31
+ .filter(Boolean);
32
+ for (const name of names) {
33
+ exports.add(name);
34
+ }
35
+ }
36
+ const commonJsExportRegex = /exports\.([A-Za-z_$][\w$]*)\s*=/g;
37
+ while ((match = commonJsExportRegex.exec(source)) !== null) {
38
+ if (match[1] !== '__esModule') {
39
+ exports.add(match[1]);
40
+ }
41
+ }
42
+ if (/module\.exports\s*=/.test(source) || /exports\.default\s*=/.test(source)) {
43
+ exports.add('default');
44
+ }
45
+ return Array.from(exports);
46
+ }
47
+ function resolveManifestFilePath(specifier) {
48
+ const baseSpecifier = specifier.split('#', 1)[0];
49
+ if (!baseSpecifier.startsWith('file://')) {
50
+ return null;
51
+ }
52
+ try {
53
+ return (0, url_1.fileURLToPath)(baseSpecifier);
54
+ }
55
+ catch {
56
+ try {
57
+ return decodeURI(baseSpecifier
58
+ .replace(/^file:\/\/\//, '')
59
+ .replace(/^file:\/\//, ''));
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ }
65
+ }
66
+ function addDriveLetterVariants(specifier, variants) {
67
+ variants.add(specifier);
68
+ const match = specifier.match(/^file:\/\/\/([A-Za-z]):/);
69
+ if (!match) {
70
+ return;
71
+ }
72
+ const lowerDrive = match[1].toLowerCase();
73
+ const upperDrive = match[1].toUpperCase();
74
+ variants.add(specifier.replace(/^file:\/\/\/([A-Za-z]):/, `file:///${lowerDrive}:`));
75
+ variants.add(specifier.replace(/^file:\/\/\/([A-Za-z]):/, `file:///${upperDrive}:`));
76
+ }
77
+ function addStandalonePathVariants(specifier, variants) {
78
+ addDriveLetterVariants(specifier, variants);
79
+ const standaloneProject = '/.vista/standalone/project';
80
+ const standaloneRuntime = '/.vista/standalone/runtime';
81
+ if (specifier.includes(standaloneProject)) {
82
+ addDriveLetterVariants(specifier.split(standaloneProject).join(''), variants);
83
+ }
84
+ if (specifier.includes(standaloneRuntime)) {
85
+ addDriveLetterVariants(specifier.split(standaloneRuntime).join(''), variants);
86
+ }
87
+ if (!specifier.includes('/.vista/standalone/') && specifier.startsWith('file://')) {
88
+ const inserted = specifier.replace(/^(file:\/\/\/(?:[A-Za-z]:)?(?:\/[^/]+)*)(\/(?:app|components|utils|lib|src|content|hooks)\/)/i, `$1${standaloneProject}$2`);
89
+ if (inserted !== specifier) {
90
+ addDriveLetterVariants(inserted, variants);
91
+ }
92
+ }
93
+ }
94
+ function buildSpecifierVariants(specifier) {
95
+ const baseSpecifier = specifier.split('#', 1)[0];
96
+ const variants = new Set();
97
+ addStandalonePathVariants(baseSpecifier, variants);
98
+ if (baseSpecifier.startsWith('file://')) {
99
+ try {
100
+ addStandalonePathVariants(decodeURI(baseSpecifier), variants);
101
+ }
102
+ catch {
103
+ // ignore decode failures
104
+ }
105
+ try {
106
+ addStandalonePathVariants((0, url_1.pathToFileURL)((0, url_1.fileURLToPath)(baseSpecifier)).toString(), variants);
107
+ }
108
+ catch {
109
+ // ignore encode failures
110
+ }
111
+ }
112
+ return Array.from(variants);
113
+ }
114
+ function splitManifestKey(key) {
115
+ const hashIdx = key.lastIndexOf('#');
116
+ if (hashIdx <= 0) {
117
+ return { specifier: key, exportName: null };
118
+ }
119
+ return {
120
+ specifier: key.slice(0, hashIdx),
121
+ exportName: key.slice(hashIdx + 1),
122
+ };
123
+ }
124
+ function normalizeManifestSpecifier(specifier) {
125
+ return specifier
126
+ .replace(/\\/g, '/')
127
+ .replace(/^file:\/\//i, '')
128
+ .replace(/^\/+/, '')
129
+ .replace(/\/\.vista\/standalone\/(?:project|runtime)/gi, '')
130
+ .toLowerCase();
131
+ }
132
+ function relativeClientPath(normalized) {
133
+ const markers = [
134
+ '/app/',
135
+ '/components/',
136
+ '/utils/',
137
+ '/lib/',
138
+ '/src/',
139
+ '/content/',
140
+ '/hooks/',
141
+ '/packages/vista/',
142
+ ];
143
+ let best = normalized;
144
+ for (const marker of markers) {
145
+ const idx = normalized.lastIndexOf(marker);
146
+ if (idx !== -1) {
147
+ const sliced = normalized.slice(idx);
148
+ if (sliced.length <= best.length) {
149
+ best = sliced;
150
+ }
151
+ }
152
+ }
153
+ return best.replace(/\.(tsx|ts|jsx|js|mjs|cjs)$/i, '');
154
+ }
155
+ function exportNamesCompatible(requested, existing) {
156
+ if (requested === null || existing === null)
157
+ return true;
158
+ if (requested === existing)
159
+ return true;
160
+ const aliases = new Set(['', '*', 'default']);
161
+ return aliases.has(requested) && aliases.has(existing);
162
+ }
163
+ /**
164
+ * Flight encode looks up `file://...#ExportName`. Webpack may have keyed the
165
+ * same module under a standalone copy, a different drive-letter case, or a
166
+ * slightly different absolute prefix. Resolve those aliases at lookup time so
167
+ * missing keys do not serialize as Flight `E{"digest":""}` rows.
168
+ */
169
+ function resolveReactClientManifestEntry(manifest, key) {
170
+ if (Object.prototype.hasOwnProperty.call(manifest, key)) {
171
+ return manifest[key];
172
+ }
173
+ const { specifier, exportName } = splitManifestKey(key);
174
+ const candidates = [];
175
+ for (const variant of buildSpecifierVariants(specifier)) {
176
+ candidates.push(variant);
177
+ if (exportName !== null) {
178
+ candidates.push(`${variant}#${exportName}`);
179
+ candidates.push(`${variant}#`);
180
+ candidates.push(`${variant}#default`);
181
+ candidates.push(`${variant}#*`);
182
+ }
183
+ }
184
+ for (const candidate of candidates) {
185
+ if (Object.prototype.hasOwnProperty.call(manifest, candidate)) {
186
+ return manifest[candidate];
187
+ }
188
+ }
189
+ const needle = normalizeManifestSpecifier(specifier);
190
+ const needleFile = needle.split('/').pop() || needle;
191
+ let fuzzy;
192
+ for (const [existingKey, entry] of Object.entries(manifest)) {
193
+ if (!entry || typeof entry !== 'object')
194
+ continue;
195
+ const existing = splitManifestKey(existingKey);
196
+ const existingNorm = normalizeManifestSpecifier(existing.specifier);
197
+ const existingFile = existingNorm.split('/').pop() || existingNorm;
198
+ const existingStem = existingFile.replace(/\.(tsx|ts|jsx|js|mjs|cjs)$/i, '');
199
+ const needleStem = needleFile.replace(/\.(tsx|ts|jsx|js|mjs|cjs)$/i, '');
200
+ const genericStem = existingStem === 'index' || existingStem === 'page' || existingStem === 'layout';
201
+ const pathMatches = existingNorm === needle ||
202
+ relativeClientPath(existingNorm) === relativeClientPath(needle) ||
203
+ (Boolean(needleFile) && !genericStem && existingStem === needleStem);
204
+ if (!pathMatches || !exportNamesCompatible(exportName, existing.exportName)) {
205
+ continue;
206
+ }
207
+ if (existing.exportName === exportName) {
208
+ return entry;
209
+ }
210
+ fuzzy = entry;
211
+ }
212
+ return fuzzy;
213
+ }
214
+ function createAliasedEntry(entry, exportName) {
215
+ if (exportName === '') {
216
+ return {
217
+ ...entry,
218
+ name: '',
219
+ };
220
+ }
221
+ return {
222
+ ...entry,
223
+ name: exportName,
224
+ };
225
+ }
226
+ function normalizeReactClientReferenceManifest(input) {
227
+ const manifest = { ...input };
228
+ for (const [rawSpecifier, rawEntry] of Object.entries(input || {})) {
229
+ if (!rawEntry || typeof rawEntry !== 'object') {
230
+ continue;
231
+ }
232
+ const entry = {
233
+ id: rawEntry.id,
234
+ chunks: Array.isArray(rawEntry.chunks) ? rawEntry.chunks : [],
235
+ name: rawEntry.name || '*',
236
+ };
237
+ const sourcePath = resolveManifestFilePath(rawSpecifier);
238
+ const exportNames = new Set();
239
+ if (entry.name && entry.name !== '*') {
240
+ exportNames.add(entry.name);
241
+ }
242
+ if (sourcePath && fs_1.default.existsSync(sourcePath)) {
243
+ try {
244
+ const source = fs_1.default.readFileSync(sourcePath, 'utf-8');
245
+ for (const exportName of extractExportNames(source)) {
246
+ exportNames.add(exportName);
247
+ }
248
+ }
249
+ catch {
250
+ // Keep manifest normalization resilient even if a source file disappears mid-build.
251
+ }
252
+ }
253
+ for (const baseSpecifier of buildSpecifierVariants(rawSpecifier)) {
254
+ if (!manifest[baseSpecifier]) {
255
+ manifest[baseSpecifier] = entry;
256
+ }
257
+ const emptyExportKey = `${baseSpecifier}#`;
258
+ if (!manifest[emptyExportKey]) {
259
+ manifest[emptyExportKey] = createAliasedEntry(entry, '');
260
+ }
261
+ const defaultExportKey = `${baseSpecifier}#default`;
262
+ if (!manifest[defaultExportKey]) {
263
+ manifest[defaultExportKey] = createAliasedEntry(entry, 'default');
264
+ }
265
+ for (const exportName of exportNames) {
266
+ const exportKey = `${baseSpecifier}#${exportName}`;
267
+ if (!manifest[exportKey]) {
268
+ manifest[exportKey] = createAliasedEntry(entry, exportName);
269
+ }
270
+ }
271
+ }
272
+ }
273
+ return manifest;
274
+ }
275
+ function normalizeReactServerConsumerManifest(input) {
276
+ if (!input?.moduleMap) {
277
+ return input;
278
+ }
279
+ for (const [moduleKey, rawExportsMap] of Object.entries(input.moduleMap)) {
280
+ const normalizedExportsMap = {};
281
+ const exportNames = new Set();
282
+ let sourceSpecifier = null;
283
+ let seedEntry = null;
284
+ for (const [exportName, rawEntry] of Object.entries(rawExportsMap || {})) {
285
+ const entry = {
286
+ id: rawEntry?.id ?? rawEntry?.specifier ?? moduleKey,
287
+ chunks: Array.isArray(rawEntry?.chunks) ? rawEntry.chunks : [],
288
+ name: rawEntry?.name || exportName,
289
+ };
290
+ normalizedExportsMap[exportName] = entry;
291
+ if (exportName !== '*') {
292
+ exportNames.add(exportName);
293
+ }
294
+ if (entry.name && entry.name !== '*') {
295
+ exportNames.add(entry.name);
296
+ }
297
+ if (!seedEntry) {
298
+ seedEntry = entry;
299
+ }
300
+ if (!sourceSpecifier && typeof entry.id === 'string' && entry.id.startsWith('file://')) {
301
+ sourceSpecifier = entry.id;
302
+ }
303
+ if (!sourceSpecifier && typeof rawEntry?.specifier === 'string' && rawEntry.specifier.startsWith('file://')) {
304
+ sourceSpecifier = rawEntry.specifier;
305
+ }
306
+ }
307
+ const sourcePath = sourceSpecifier ? resolveManifestFilePath(sourceSpecifier) : null;
308
+ if (sourcePath && fs_1.default.existsSync(sourcePath)) {
309
+ try {
310
+ const source = fs_1.default.readFileSync(sourcePath, 'utf-8');
311
+ for (const exportName of extractExportNames(source)) {
312
+ exportNames.add(exportName);
313
+ }
314
+ }
315
+ catch {
316
+ // Keep manifest normalization resilient even if the source file changes mid-build.
317
+ }
318
+ }
319
+ if (seedEntry) {
320
+ if (!normalizedExportsMap['*']) {
321
+ normalizedExportsMap['*'] = {
322
+ ...seedEntry,
323
+ name: '*',
324
+ };
325
+ }
326
+ for (const exportName of exportNames) {
327
+ if (!normalizedExportsMap[exportName]) {
328
+ normalizedExportsMap[exportName] = {
329
+ ...seedEntry,
330
+ name: exportName,
331
+ };
332
+ }
333
+ }
334
+ }
335
+ input.moduleMap[moduleKey] = normalizedExportsMap;
336
+ }
337
+ return input;
338
+ }
339
+ /**
340
+ * React looks up `file://...#ExportName` in the Flight manifest and throws a
341
+ * generic error when the key is missing. Wrap the manifest so the message names
342
+ * the file and the scan-directory requirement.
343
+ */
344
+ function createGuardedReactClientManifest(manifest) {
345
+ return new Proxy(manifest, {
346
+ get(target, prop, receiver) {
347
+ if (typeof prop === 'string' && (prop.startsWith('file:') || prop.includes('#'))) {
348
+ const resolved = resolveReactClientManifestEntry(target, prop);
349
+ if (resolved) {
350
+ return resolved;
351
+ }
352
+ const fileHint = prop.split('#')[0];
353
+ throw new Error(`Could not find the module "${prop}" in the React Client Manifest. ` +
354
+ `Client Components need a 'use client' directive and must live under a scanned project directory ` +
355
+ `(app/, components/, utils/, lib/, src/, ...). Missing: ${fileHint}`);
356
+ }
357
+ return Reflect.get(target, prop, receiver);
358
+ },
359
+ has(target, prop) {
360
+ if (typeof prop === 'string' && (prop.startsWith('file:') || prop.includes('#'))) {
361
+ return Boolean(resolveReactClientManifestEntry(target, prop));
362
+ }
363
+ return Reflect.has(target, prop);
364
+ },
365
+ });
366
+ }