@fluojs/react 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.ko.md +715 -0
- package/README.md +729 -0
- package/dist/client/errors.d.ts +12 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +19 -0
- package/dist/client/hooks.d.ts +38 -0
- package/dist/client/hooks.d.ts.map +1 -0
- package/dist/client/hooks.js +56 -0
- package/dist/client/link.d.ts +13 -0
- package/dist/client/link.d.ts.map +1 -0
- package/dist/client/link.js +39 -0
- package/dist/client/provider.d.ts +12 -0
- package/dist/client/provider.d.ts.map +1 -0
- package/dist/client/provider.js +54 -0
- package/dist/client/search-params.d.ts +17 -0
- package/dist/client/search-params.d.ts.map +1 -0
- package/dist/client/search-params.js +39 -0
- package/dist/client/snapshot.d.ts +15 -0
- package/dist/client/snapshot.d.ts.map +1 -0
- package/dist/client/snapshot.js +57 -0
- package/dist/client/store.d.ts +26 -0
- package/dist/client/store.d.ts.map +1 -0
- package/dist/client/store.js +138 -0
- package/dist/client/types.d.ts +63 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +1 -0
- package/dist/client.d.ts +9 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +5 -0
- package/dist/decorators.d.ts +80 -0
- package/dist/decorators.d.ts.map +1 -0
- package/dist/decorators.js +194 -0
- package/dist/experimental/rsc-diagnostics.d.ts +13 -0
- package/dist/experimental/rsc-diagnostics.d.ts.map +1 -0
- package/dist/experimental/rsc-diagnostics.js +58 -0
- package/dist/experimental/rsc-flight-response.d.ts +15 -0
- package/dist/experimental/rsc-flight-response.d.ts.map +1 -0
- package/dist/experimental/rsc-flight-response.js +76 -0
- package/dist/experimental/rsc-manifest.d.ts +13 -0
- package/dist/experimental/rsc-manifest.d.ts.map +1 -0
- package/dist/experimental/rsc-manifest.js +88 -0
- package/dist/experimental/rsc-types.d.ts +118 -0
- package/dist/experimental/rsc-types.d.ts.map +1 -0
- package/dist/experimental/rsc-types.js +50 -0
- package/dist/experimental/rsc.d.ts +11 -0
- package/dist/experimental/rsc.d.ts.map +1 -0
- package/dist/experimental/rsc.js +8 -0
- package/dist/experimental/server-functions-client.d.ts +14 -0
- package/dist/experimental/server-functions-client.d.ts.map +1 -0
- package/dist/experimental/server-functions-client.js +120 -0
- package/dist/experimental/server-functions-configuration.d.ts +17 -0
- package/dist/experimental/server-functions-configuration.d.ts.map +1 -0
- package/dist/experimental/server-functions-configuration.js +68 -0
- package/dist/experimental/server-functions-errors.d.ts +19 -0
- package/dist/experimental/server-functions-errors.d.ts.map +1 -0
- package/dist/experimental/server-functions-errors.js +22 -0
- package/dist/experimental/server-functions-reference.d.ts +22 -0
- package/dist/experimental/server-functions-reference.d.ts.map +1 -0
- package/dist/experimental/server-functions-reference.js +76 -0
- package/dist/experimental/server-functions-serialization.d.ts +37 -0
- package/dist/experimental/server-functions-serialization.d.ts.map +1 -0
- package/dist/experimental/server-functions-serialization.js +158 -0
- package/dist/experimental/server-functions-server.d.ts +14 -0
- package/dist/experimental/server-functions-server.d.ts.map +1 -0
- package/dist/experimental/server-functions-server.js +176 -0
- package/dist/experimental/server-functions-types.d.ts +86 -0
- package/dist/experimental/server-functions-types.d.ts.map +1 -0
- package/dist/experimental/server-functions-types.js +35 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/module.d.ts +40 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +58 -0
- package/dist/render-stream.d.ts +27 -0
- package/dist/render-stream.d.ts.map +1 -0
- package/dist/render-stream.js +135 -0
- package/dist/render.d.ts +50 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +201 -0
- package/dist/server-entry.d.ts +87 -0
- package/dist/server-entry.d.ts.map +1 -0
- package/dist/server-entry.js +126 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/vite/asset-utils.d.ts +57 -0
- package/dist/vite/asset-utils.d.ts.map +1 -0
- package/dist/vite/asset-utils.js +184 -0
- package/dist/vite/create-asset-manifest.d.ts +9 -0
- package/dist/vite/create-asset-manifest.d.ts.map +1 -0
- package/dist/vite/create-asset-manifest.js +127 -0
- package/dist/vite/diagnostics.d.ts +27 -0
- package/dist/vite/diagnostics.d.ts.map +1 -0
- package/dist/vite/diagnostics.js +47 -0
- package/dist/vite/parse-manifest.d.ts +18 -0
- package/dist/vite/parse-manifest.d.ts.map +1 -0
- package/dist/vite/parse-manifest.js +168 -0
- package/dist/vite/types.d.ts +187 -0
- package/dist/vite/types.d.ts.map +1 -0
- package/dist/vite/types.js +59 -0
- package/dist/vite.d.ts +3 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ReactAssetMap, ReactBootstrapAsset } from '../server-entry.js';
|
|
2
|
+
import type { DependencyGraph, ParsedManifest, ParsedManifestEntry } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Collects the import graph for a client manifest entry with dependencies first.
|
|
5
|
+
*
|
|
6
|
+
* @param manifest Parsed Vite manifest.
|
|
7
|
+
* @param rootEntry Browser hydration entry.
|
|
8
|
+
* @returns Ordered graph entries and missing-import diagnostics.
|
|
9
|
+
*/
|
|
10
|
+
export declare function collectDependencyGraph(manifest: ParsedManifest, rootEntry: ParsedManifestEntry): DependencyGraph;
|
|
11
|
+
/**
|
|
12
|
+
* Resolves a Vite manifest file path to a public URL.
|
|
13
|
+
*
|
|
14
|
+
* @param file Manifest file path or already absolute URL.
|
|
15
|
+
* @param base Optional Vite base path.
|
|
16
|
+
* @returns Public URL suitable for emitted HTML or asset maps.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createPublicUrl(file: string, base: string | undefined): string;
|
|
19
|
+
/**
|
|
20
|
+
* Checks whether a Vite output path is a JavaScript chunk supported by the React Vite bridge.
|
|
21
|
+
*
|
|
22
|
+
* @param file Manifest output file path.
|
|
23
|
+
* @returns `true` when the output path has a supported JavaScript extension.
|
|
24
|
+
*/
|
|
25
|
+
export declare function isJavaScriptOutput(file: string): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Clones bootstrap assets while preserving first-seen order by source URL.
|
|
28
|
+
*
|
|
29
|
+
* @param assets Bootstrap assets to clone and deduplicate.
|
|
30
|
+
* @returns Defensive bootstrap asset snapshot.
|
|
31
|
+
*/
|
|
32
|
+
export declare function cloneUniqueBootstrapAssets(assets: readonly ReactBootstrapAsset[]): readonly ReactBootstrapAsset[];
|
|
33
|
+
/**
|
|
34
|
+
* Collects stylesheet URLs in dependency order with duplicate removal.
|
|
35
|
+
*
|
|
36
|
+
* @param entries Dependency-ordered client graph entries.
|
|
37
|
+
* @param base Optional Vite base path.
|
|
38
|
+
* @returns Stylesheet URLs ordered before hydration scripts.
|
|
39
|
+
*/
|
|
40
|
+
export declare function collectCssUrls(entries: readonly ParsedManifestEntry[], base: string | undefined): readonly string[];
|
|
41
|
+
/**
|
|
42
|
+
* Collects JavaScript module URLs in dependency order.
|
|
43
|
+
*
|
|
44
|
+
* @param entries Dependency-ordered client graph entries.
|
|
45
|
+
* @param base Optional Vite base path.
|
|
46
|
+
* @returns Public JavaScript module URLs.
|
|
47
|
+
*/
|
|
48
|
+
export declare function collectModuleUrls(entries: readonly ParsedManifestEntry[], base: string | undefined): readonly string[];
|
|
49
|
+
/**
|
|
50
|
+
* Creates a defensive asset map snapshot from every manifest file, stylesheet, and static asset.
|
|
51
|
+
*
|
|
52
|
+
* @param manifest Parsed Vite manifest.
|
|
53
|
+
* @param base Optional Vite base path.
|
|
54
|
+
* @returns Asset map compatible with the stable React server entry contract.
|
|
55
|
+
*/
|
|
56
|
+
export declare function createAssetMap(manifest: ParsedManifest, base: string | undefined): ReactAssetMap;
|
|
57
|
+
//# sourceMappingURL=asset-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-utils.d.ts","sourceRoot":"","sources":["../../src/vite/asset-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAkC,MAAM,oBAAoB,CAAC;AAI7G,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAMvF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,cAAc,EACxB,SAAS,EAAE,mBAAmB,GAC7B,eAAe,CAkCjB;AAcD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAM9E;AAcD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIxD;AAkBD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,SAAS,mBAAmB,EAAE,GACrC,SAAS,mBAAmB,EAAE,CAgBhC;AAaD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,SAAS,mBAAmB,EAAE,EACvC,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,SAAS,MAAM,EAAE,CAanB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,SAAS,mBAAmB,EAAE,EACvC,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,SAAS,MAAM,EAAE,CAEnB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CA2BhG"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { ABSOLUTE_URL_PATTERN, JAVASCRIPT_OUTPUT_EXTENSIONS } from './types.js';
|
|
2
|
+
import { createMalformedDiagnostic } from './diagnostics.js';
|
|
3
|
+
function readOwnEntry(manifest, entryId) {
|
|
4
|
+
return Object.hasOwn(manifest, entryId) ? manifest[entryId] : undefined;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Collects the import graph for a client manifest entry with dependencies first.
|
|
9
|
+
*
|
|
10
|
+
* @param manifest Parsed Vite manifest.
|
|
11
|
+
* @param rootEntry Browser hydration entry.
|
|
12
|
+
* @returns Ordered graph entries and missing-import diagnostics.
|
|
13
|
+
*/
|
|
14
|
+
export function collectDependencyGraph(manifest, rootEntry) {
|
|
15
|
+
const diagnostics = [];
|
|
16
|
+
const entries = [];
|
|
17
|
+
const visited = new Set();
|
|
18
|
+
function visit(entry) {
|
|
19
|
+
if (visited.has(entry.id)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
visited.add(entry.id);
|
|
23
|
+
for (const importId of entry.imports) {
|
|
24
|
+
const importedEntry = readOwnEntry(manifest, importId);
|
|
25
|
+
if (importedEntry === undefined) {
|
|
26
|
+
diagnostics.push(createMalformedDiagnostic(`React Vite manifest entry "${entry.id}" imports missing chunk "${importId}".`, `${entry.id}.imports`));
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
visit(importedEntry);
|
|
30
|
+
}
|
|
31
|
+
entries.push(entry);
|
|
32
|
+
}
|
|
33
|
+
visit(rootEntry);
|
|
34
|
+
return {
|
|
35
|
+
diagnostics,
|
|
36
|
+
entries
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function normalizeBase(base) {
|
|
40
|
+
if (base === undefined) {
|
|
41
|
+
return '/';
|
|
42
|
+
}
|
|
43
|
+
if (base === '') {
|
|
44
|
+
return '';
|
|
45
|
+
}
|
|
46
|
+
return base.endsWith('/') ? base : `${base}/`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Resolves a Vite manifest file path to a public URL.
|
|
51
|
+
*
|
|
52
|
+
* @param file Manifest file path or already absolute URL.
|
|
53
|
+
* @param base Optional Vite base path.
|
|
54
|
+
* @returns Public URL suitable for emitted HTML or asset maps.
|
|
55
|
+
*/
|
|
56
|
+
export function createPublicUrl(file, base) {
|
|
57
|
+
if (file.startsWith('/') || ABSOLUTE_URL_PATTERN.test(file)) {
|
|
58
|
+
return file;
|
|
59
|
+
}
|
|
60
|
+
return `${normalizeBase(base)}${file}`;
|
|
61
|
+
}
|
|
62
|
+
function stripUrlSuffix(file) {
|
|
63
|
+
const queryIndex = file.indexOf('?');
|
|
64
|
+
const hashIndex = file.indexOf('#');
|
|
65
|
+
const suffixIndexes = [queryIndex, hashIndex].filter(index => index >= 0);
|
|
66
|
+
if (suffixIndexes.length === 0) {
|
|
67
|
+
return file;
|
|
68
|
+
}
|
|
69
|
+
return file.slice(0, Math.min(...suffixIndexes));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Checks whether a Vite output path is a JavaScript chunk supported by the React Vite bridge.
|
|
74
|
+
*
|
|
75
|
+
* @param file Manifest output file path.
|
|
76
|
+
* @returns `true` when the output path has a supported JavaScript extension.
|
|
77
|
+
*/
|
|
78
|
+
export function isJavaScriptOutput(file) {
|
|
79
|
+
const pathname = stripUrlSuffix(file);
|
|
80
|
+
return JAVASCRIPT_OUTPUT_EXTENSIONS.some(extension => pathname.endsWith(extension));
|
|
81
|
+
}
|
|
82
|
+
function getBootstrapAssetSource(asset) {
|
|
83
|
+
return typeof asset === 'string' ? asset : asset.src;
|
|
84
|
+
}
|
|
85
|
+
function cloneBootstrapDescriptor(asset) {
|
|
86
|
+
return {
|
|
87
|
+
...(asset.crossOrigin !== undefined ? {
|
|
88
|
+
crossOrigin: asset.crossOrigin
|
|
89
|
+
} : {}),
|
|
90
|
+
...(asset.integrity !== undefined ? {
|
|
91
|
+
integrity: asset.integrity
|
|
92
|
+
} : {}),
|
|
93
|
+
src: asset.src
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function cloneBootstrapAsset(asset) {
|
|
97
|
+
return typeof asset === 'string' ? asset : cloneBootstrapDescriptor(asset);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Clones bootstrap assets while preserving first-seen order by source URL.
|
|
102
|
+
*
|
|
103
|
+
* @param assets Bootstrap assets to clone and deduplicate.
|
|
104
|
+
* @returns Defensive bootstrap asset snapshot.
|
|
105
|
+
*/
|
|
106
|
+
export function cloneUniqueBootstrapAssets(assets) {
|
|
107
|
+
const cloned = [];
|
|
108
|
+
const seenSources = new Set();
|
|
109
|
+
for (const asset of assets) {
|
|
110
|
+
const source = getBootstrapAssetSource(asset);
|
|
111
|
+
if (seenSources.has(source)) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
seenSources.add(source);
|
|
115
|
+
cloned.push(cloneBootstrapAsset(asset));
|
|
116
|
+
}
|
|
117
|
+
return cloned;
|
|
118
|
+
}
|
|
119
|
+
function appendUniqueUrls(target, seen, urls) {
|
|
120
|
+
for (const url of urls) {
|
|
121
|
+
if (seen.has(url)) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
seen.add(url);
|
|
125
|
+
target.push(url);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Collects stylesheet URLs in dependency order with duplicate removal.
|
|
131
|
+
*
|
|
132
|
+
* @param entries Dependency-ordered client graph entries.
|
|
133
|
+
* @param base Optional Vite base path.
|
|
134
|
+
* @returns Stylesheet URLs ordered before hydration scripts.
|
|
135
|
+
*/
|
|
136
|
+
export function collectCssUrls(entries, base) {
|
|
137
|
+
const css = [];
|
|
138
|
+
const seen = new Set();
|
|
139
|
+
for (const entry of entries) {
|
|
140
|
+
appendUniqueUrls(css, seen, entry.css.map(file => createPublicUrl(file, base)));
|
|
141
|
+
}
|
|
142
|
+
return css;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Collects JavaScript module URLs in dependency order.
|
|
147
|
+
*
|
|
148
|
+
* @param entries Dependency-ordered client graph entries.
|
|
149
|
+
* @param base Optional Vite base path.
|
|
150
|
+
* @returns Public JavaScript module URLs.
|
|
151
|
+
*/
|
|
152
|
+
export function collectModuleUrls(entries, base) {
|
|
153
|
+
return entries.map(entry => createPublicUrl(entry.file, base));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Creates a defensive asset map snapshot from every manifest file, stylesheet, and static asset.
|
|
158
|
+
*
|
|
159
|
+
* @param manifest Parsed Vite manifest.
|
|
160
|
+
* @param base Optional Vite base path.
|
|
161
|
+
* @returns Asset map compatible with the stable React server entry contract.
|
|
162
|
+
*/
|
|
163
|
+
export function createAssetMap(manifest, base) {
|
|
164
|
+
const assetMap = {};
|
|
165
|
+
Object.setPrototypeOf(assetMap, null);
|
|
166
|
+
for (const [entryId, entry] of Object.entries(manifest)) {
|
|
167
|
+
const publicFile = createPublicUrl(entry.file, base);
|
|
168
|
+
assetMap[entryId] = publicFile;
|
|
169
|
+
assetMap[entry.file] = publicFile;
|
|
170
|
+
if (entry.name !== undefined) {
|
|
171
|
+
assetMap[entry.name] = publicFile;
|
|
172
|
+
}
|
|
173
|
+
if (entry.src !== undefined) {
|
|
174
|
+
assetMap[entry.src] = publicFile;
|
|
175
|
+
}
|
|
176
|
+
for (const css of entry.css) {
|
|
177
|
+
assetMap[css] = createPublicUrl(css, base);
|
|
178
|
+
}
|
|
179
|
+
for (const asset of entry.assets) {
|
|
180
|
+
assetMap[asset] = createPublicUrl(asset, base);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return assetMap;
|
|
184
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactViteAssetManifestResult, ReactViteManifestOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parses a Vite manifest into React hydration assets without importing Vite from the root package.
|
|
4
|
+
*
|
|
5
|
+
* @param options Manifest input, explicit React entry selectors, public base path, and trusted bootstrap metadata.
|
|
6
|
+
* @returns A typed asset manifest on success, or diagnostics for expected manifest and output-shape failures.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createReactViteAssetManifest(options: ReactViteManifestOptions): ReactViteAssetManifestResult;
|
|
9
|
+
//# sourceMappingURL=create-asset-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-asset-manifest.d.ts","sourceRoot":"","sources":["../../src/vite/create-asset-manifest.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAMV,4BAA4B,EAG5B,wBAAwB,EAEzB,MAAM,YAAY,CAAC;AA8EpB;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,wBAAwB,GAChC,4BAA4B,CAoC9B"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { cloneUniqueBootstrapAssets, collectCssUrls, collectDependencyGraph, collectModuleUrls, createAssetMap, createPublicUrl, isJavaScriptOutput } from './asset-utils.js';
|
|
2
|
+
import { createMissingEntryDiagnostic, createUnsupportedOutputDiagnostic } from './diagnostics.js';
|
|
3
|
+
import { parseReactViteBuildManifest, resolveManifestEntry } from './parse-manifest.js';
|
|
4
|
+
function createResolvedEntry(entry, base) {
|
|
5
|
+
return {
|
|
6
|
+
assets: entry.assets.map(asset => createPublicUrl(asset, base)),
|
|
7
|
+
css: entry.css.map(css => createPublicUrl(css, base)),
|
|
8
|
+
file: entry.file,
|
|
9
|
+
id: entry.id,
|
|
10
|
+
imports: [...entry.imports],
|
|
11
|
+
publicUrl: createPublicUrl(entry.file, base)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function createBootstrapData(input) {
|
|
15
|
+
return {
|
|
16
|
+
...(input.bootstrapScriptContent !== undefined ? {
|
|
17
|
+
bootstrapScriptContent: input.bootstrapScriptContent
|
|
18
|
+
} : {}),
|
|
19
|
+
...(input.identifierPrefix !== undefined ? {
|
|
20
|
+
identifierPrefix: input.identifierPrefix
|
|
21
|
+
} : {}),
|
|
22
|
+
...(input.nonce !== undefined ? {
|
|
23
|
+
nonce: input.nonce
|
|
24
|
+
} : {})
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function createHydrationOptions(input) {
|
|
28
|
+
return {
|
|
29
|
+
assetMap: input.assetMap,
|
|
30
|
+
...(input.modules.length > 0 ? {
|
|
31
|
+
bootstrapModules: input.modules
|
|
32
|
+
} : {}),
|
|
33
|
+
...(input.bootstrap.bootstrapScriptContent !== undefined ? {
|
|
34
|
+
bootstrapScriptContent: input.bootstrap.bootstrapScriptContent
|
|
35
|
+
} : {}),
|
|
36
|
+
...(input.scripts.length > 0 ? {
|
|
37
|
+
bootstrapScripts: input.scripts
|
|
38
|
+
} : {}),
|
|
39
|
+
...(input.bootstrap.identifierPrefix !== undefined ? {
|
|
40
|
+
identifierPrefix: input.bootstrap.identifierPrefix
|
|
41
|
+
} : {}),
|
|
42
|
+
...(input.bootstrap.nonce !== undefined ? {
|
|
43
|
+
nonce: input.bootstrap.nonce
|
|
44
|
+
} : {})
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function createSuccessManifest(input) {
|
|
48
|
+
const {
|
|
49
|
+
clientGraph,
|
|
50
|
+
manifest,
|
|
51
|
+
options,
|
|
52
|
+
serverEntry
|
|
53
|
+
} = input;
|
|
54
|
+
const assetMap = createAssetMap(manifest, options.base);
|
|
55
|
+
const css = collectCssUrls(clientGraph.entries, options.base);
|
|
56
|
+
const manifestModuleUrls = collectModuleUrls(clientGraph.entries, options.base);
|
|
57
|
+
const modules = cloneUniqueBootstrapAssets([...manifestModuleUrls, ...(options.bootstrapModules ?? [])]);
|
|
58
|
+
const scripts = cloneUniqueBootstrapAssets(options.bootstrapScripts ?? []);
|
|
59
|
+
const bootstrap = createBootstrapData(options);
|
|
60
|
+
const hydrationOptions = createHydrationOptions({
|
|
61
|
+
assetMap,
|
|
62
|
+
bootstrap,
|
|
63
|
+
modules,
|
|
64
|
+
scripts
|
|
65
|
+
});
|
|
66
|
+
const clientEntry = clientGraph.entries[clientGraph.entries.length - 1];
|
|
67
|
+
if (clientEntry === undefined) {
|
|
68
|
+
return {
|
|
69
|
+
diagnostics: [createMissingEntryDiagnostic('client', options.entries.client)],
|
|
70
|
+
ok: false
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
manifest: {
|
|
75
|
+
assetMap,
|
|
76
|
+
bootstrap,
|
|
77
|
+
clientEntry: createResolvedEntry(clientEntry, options.base),
|
|
78
|
+
css,
|
|
79
|
+
hydrationOptions,
|
|
80
|
+
js: {
|
|
81
|
+
modules,
|
|
82
|
+
scripts
|
|
83
|
+
},
|
|
84
|
+
serverEntry: createResolvedEntry(serverEntry, options.base)
|
|
85
|
+
},
|
|
86
|
+
ok: true
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Parses a Vite manifest into React hydration assets without importing Vite from the root package.
|
|
92
|
+
*
|
|
93
|
+
* @param options Manifest input, explicit React entry selectors, public base path, and trusted bootstrap metadata.
|
|
94
|
+
* @returns A typed asset manifest on success, or diagnostics for expected manifest and output-shape failures.
|
|
95
|
+
*/
|
|
96
|
+
export function createReactViteAssetManifest(options) {
|
|
97
|
+
const parsed = parseReactViteBuildManifest(options.manifest);
|
|
98
|
+
if (!parsed.ok) {
|
|
99
|
+
return parsed;
|
|
100
|
+
}
|
|
101
|
+
const serverResult = resolveManifestEntry(parsed.manifest, 'server', options.entries.server);
|
|
102
|
+
const clientResult = resolveManifestEntry(parsed.manifest, 'client', options.entries.client);
|
|
103
|
+
const entryDiagnostics = [...serverResult.diagnostics, ...clientResult.diagnostics];
|
|
104
|
+
const serverEntry = serverResult.entry;
|
|
105
|
+
const clientEntry = clientResult.entry;
|
|
106
|
+
if (serverEntry === undefined || clientEntry === undefined) {
|
|
107
|
+
return {
|
|
108
|
+
diagnostics: entryDiagnostics,
|
|
109
|
+
ok: false
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const clientGraph = collectDependencyGraph(parsed.manifest, clientEntry);
|
|
113
|
+
const unsupportedDiagnostics = [...(isJavaScriptOutput(serverEntry.file) ? [] : [createUnsupportedOutputDiagnostic('server', serverEntry)]), ...clientGraph.entries.flatMap(entry => isJavaScriptOutput(entry.file) ? [] : [createUnsupportedOutputDiagnostic('client', entry)])];
|
|
114
|
+
const diagnostics = [...clientGraph.diagnostics, ...unsupportedDiagnostics];
|
|
115
|
+
if (diagnostics.length > 0) {
|
|
116
|
+
return {
|
|
117
|
+
diagnostics,
|
|
118
|
+
ok: false
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return createSuccessManifest({
|
|
122
|
+
clientGraph,
|
|
123
|
+
manifest: parsed.manifest,
|
|
124
|
+
options,
|
|
125
|
+
serverEntry
|
|
126
|
+
});
|
|
127
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type EntryRole, type ParsedManifestEntry } from './types.js';
|
|
2
|
+
import type { ReactViteManifestDiagnostic } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a malformed-manifest diagnostic.
|
|
5
|
+
*
|
|
6
|
+
* @param message Human-readable explanation for the malformed manifest value.
|
|
7
|
+
* @param path Optional manifest path for field-level failures.
|
|
8
|
+
* @returns A diagnostic with the stable malformed-manifest code.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createMalformedDiagnostic(message: string, path?: string): ReactViteManifestDiagnostic;
|
|
11
|
+
/**
|
|
12
|
+
* Creates a missing-entry diagnostic for the requested React entry role.
|
|
13
|
+
*
|
|
14
|
+
* @param role React entry role being resolved.
|
|
15
|
+
* @param entry Requested manifest key, `src`, or `name`.
|
|
16
|
+
* @returns A diagnostic with the role-specific missing-entry code.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createMissingEntryDiagnostic(role: EntryRole, entry: string): ReactViteManifestDiagnostic;
|
|
19
|
+
/**
|
|
20
|
+
* Creates an unsupported-output diagnostic when a selected chunk is not JavaScript.
|
|
21
|
+
*
|
|
22
|
+
* @param role React entry role whose output shape was rejected.
|
|
23
|
+
* @param entry Parsed manifest entry with the unsupported output file.
|
|
24
|
+
* @returns A diagnostic with the stable unsupported-output code.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createUnsupportedOutputDiagnostic(role: EntryRole, entry: ParsedManifestEntry): ReactViteManifestDiagnostic;
|
|
27
|
+
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/vite/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAE,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACxF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAE9D;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,GACZ,2BAA2B,CAM7B;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,MAAM,GACZ,2BAA2B,CAM7B;AAED;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,mBAAmB,GACzB,2BAA2B,CAM7B"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { DIAGNOSTIC_CODES } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a malformed-manifest diagnostic.
|
|
4
|
+
*
|
|
5
|
+
* @param message Human-readable explanation for the malformed manifest value.
|
|
6
|
+
* @param path Optional manifest path for field-level failures.
|
|
7
|
+
* @returns A diagnostic with the stable malformed-manifest code.
|
|
8
|
+
*/
|
|
9
|
+
export function createMalformedDiagnostic(message, path) {
|
|
10
|
+
return {
|
|
11
|
+
code: DIAGNOSTIC_CODES.malformed,
|
|
12
|
+
message,
|
|
13
|
+
...(path !== undefined ? {
|
|
14
|
+
path
|
|
15
|
+
} : {})
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates a missing-entry diagnostic for the requested React entry role.
|
|
21
|
+
*
|
|
22
|
+
* @param role React entry role being resolved.
|
|
23
|
+
* @param entry Requested manifest key, `src`, or `name`.
|
|
24
|
+
* @returns A diagnostic with the role-specific missing-entry code.
|
|
25
|
+
*/
|
|
26
|
+
export function createMissingEntryDiagnostic(role, entry) {
|
|
27
|
+
return {
|
|
28
|
+
code: role === 'server' ? DIAGNOSTIC_CODES.missingServerEntry : DIAGNOSTIC_CODES.missingClientEntry,
|
|
29
|
+
entry,
|
|
30
|
+
message: `React Vite ${role} entry "${entry}" was not found in the manifest.`
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Creates an unsupported-output diagnostic when a selected chunk is not JavaScript.
|
|
36
|
+
*
|
|
37
|
+
* @param role React entry role whose output shape was rejected.
|
|
38
|
+
* @param entry Parsed manifest entry with the unsupported output file.
|
|
39
|
+
* @returns A diagnostic with the stable unsupported-output code.
|
|
40
|
+
*/
|
|
41
|
+
export function createUnsupportedOutputDiagnostic(role, entry) {
|
|
42
|
+
return {
|
|
43
|
+
code: DIAGNOSTIC_CODES.unsupportedOutputShape,
|
|
44
|
+
entry: entry.id,
|
|
45
|
+
message: `React Vite ${role} entry "${entry.id}" must resolve to a JavaScript output file, received "${entry.file}".`
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { EntryResolveResult, EntryRole, ManifestParseResult, ParsedManifest } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parses unknown Vite manifest data into a typed manifest map.
|
|
4
|
+
*
|
|
5
|
+
* @param value Manifest value loaded at a trust boundary.
|
|
6
|
+
* @returns Parsed manifest data or malformed-manifest diagnostics.
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseReactViteBuildManifest(value: unknown): ManifestParseResult;
|
|
9
|
+
/**
|
|
10
|
+
* Resolves a React server or client entry by manifest key, `src`, or `name`.
|
|
11
|
+
*
|
|
12
|
+
* @param manifest Parsed Vite manifest.
|
|
13
|
+
* @param role React entry role being resolved.
|
|
14
|
+
* @param entryId Requested manifest key, `src`, or `name`.
|
|
15
|
+
* @returns The resolved manifest entry or role-specific diagnostics.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveManifestEntry(manifest: ParsedManifest, role: EntryRole, entryId: string): EntryResolveResult;
|
|
18
|
+
//# sourceMappingURL=parse-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-manifest.d.ts","sourceRoot":"","sources":["../../src/vite/parse-manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EAGT,mBAAmB,EACnB,cAAc,EAIf,MAAM,YAAY,CAAC;AA6HpB;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CA0B/E;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,MAAM,GACd,kBAAkB,CA0BpB"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { DIAGNOSTIC_CODES } from './types.js';
|
|
2
|
+
import { createMalformedDiagnostic, createMissingEntryDiagnostic } from './diagnostics.js';
|
|
3
|
+
function isUnknownRecord(value) {
|
|
4
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
5
|
+
}
|
|
6
|
+
function isStringArray(value) {
|
|
7
|
+
return Array.isArray(value) && value.every(item => typeof item === 'string');
|
|
8
|
+
}
|
|
9
|
+
function readOwnValue(record, key) {
|
|
10
|
+
return Object.hasOwn(record, key) ? record[key] : undefined;
|
|
11
|
+
}
|
|
12
|
+
function readOptionalString(reader, field) {
|
|
13
|
+
const value = readOwnValue(reader.entry, field);
|
|
14
|
+
if (value === undefined) {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
if (typeof value === 'string') {
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
reader.diagnostics.push(createMalformedDiagnostic(`React Vite manifest entry "${reader.entryId}" field "${field}" must be a string.`, `${reader.entryId}.${field}`));
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
function readOptionalBoolean(reader, field) {
|
|
24
|
+
const value = readOwnValue(reader.entry, field);
|
|
25
|
+
if (value === undefined) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
if (typeof value === 'boolean') {
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
reader.diagnostics.push(createMalformedDiagnostic(`React Vite manifest entry "${reader.entryId}" field "${field}" must be a boolean.`, `${reader.entryId}.${field}`));
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
function readOptionalStringArray(reader, field) {
|
|
35
|
+
const value = readOwnValue(reader.entry, field);
|
|
36
|
+
if (value === undefined) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
if (isStringArray(value)) {
|
|
40
|
+
return [...value];
|
|
41
|
+
}
|
|
42
|
+
reader.diagnostics.push(createMalformedDiagnostic(`React Vite manifest entry "${reader.entryId}" field "${field}" must be an array of strings.`, `${reader.entryId}.${field}`));
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
function parseManifestEntry(entryId, rawEntry) {
|
|
46
|
+
if (!isUnknownRecord(rawEntry)) {
|
|
47
|
+
return {
|
|
48
|
+
diagnostics: [createMalformedDiagnostic(`React Vite manifest entry "${entryId}" must be an object.`, entryId)]
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
const diagnostics = [];
|
|
52
|
+
const reader = {
|
|
53
|
+
diagnostics,
|
|
54
|
+
entry: rawEntry,
|
|
55
|
+
entryId
|
|
56
|
+
};
|
|
57
|
+
const fileValue = readOwnValue(rawEntry, 'file');
|
|
58
|
+
const file = typeof fileValue === 'string' ? fileValue : '';
|
|
59
|
+
if (typeof fileValue !== 'string') {
|
|
60
|
+
diagnostics.push(createMalformedDiagnostic(`React Vite manifest entry "${entryId}" field "file" must be a string.`, `${entryId}.file`));
|
|
61
|
+
}
|
|
62
|
+
const assets = readOptionalStringArray(reader, 'assets');
|
|
63
|
+
const css = readOptionalStringArray(reader, 'css');
|
|
64
|
+
const imports = readOptionalStringArray(reader, 'imports');
|
|
65
|
+
const isDynamicEntry = readOptionalBoolean(reader, 'isDynamicEntry');
|
|
66
|
+
const isEntry = readOptionalBoolean(reader, 'isEntry');
|
|
67
|
+
const name = readOptionalString(reader, 'name');
|
|
68
|
+
const src = readOptionalString(reader, 'src');
|
|
69
|
+
if (diagnostics.length > 0) {
|
|
70
|
+
return {
|
|
71
|
+
diagnostics
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
diagnostics: [],
|
|
76
|
+
entry: {
|
|
77
|
+
assets,
|
|
78
|
+
css,
|
|
79
|
+
file,
|
|
80
|
+
id: entryId,
|
|
81
|
+
imports,
|
|
82
|
+
...(isDynamicEntry !== undefined ? {
|
|
83
|
+
isDynamicEntry
|
|
84
|
+
} : {}),
|
|
85
|
+
...(isEntry !== undefined ? {
|
|
86
|
+
isEntry
|
|
87
|
+
} : {}),
|
|
88
|
+
...(name !== undefined ? {
|
|
89
|
+
name
|
|
90
|
+
} : {}),
|
|
91
|
+
...(src !== undefined ? {
|
|
92
|
+
src
|
|
93
|
+
} : {})
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Parses unknown Vite manifest data into a typed manifest map.
|
|
100
|
+
*
|
|
101
|
+
* @param value Manifest value loaded at a trust boundary.
|
|
102
|
+
* @returns Parsed manifest data or malformed-manifest diagnostics.
|
|
103
|
+
*/
|
|
104
|
+
export function parseReactViteBuildManifest(value) {
|
|
105
|
+
if (!isUnknownRecord(value)) {
|
|
106
|
+
return {
|
|
107
|
+
diagnostics: [createMalformedDiagnostic('React Vite manifest must be an object keyed by entry id.')],
|
|
108
|
+
ok: false
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const diagnostics = [];
|
|
112
|
+
const manifest = {};
|
|
113
|
+
Object.setPrototypeOf(manifest, null);
|
|
114
|
+
for (const [entryId, rawEntry] of Object.entries(value)) {
|
|
115
|
+
const parsed = parseManifestEntry(entryId, rawEntry);
|
|
116
|
+
diagnostics.push(...parsed.diagnostics);
|
|
117
|
+
if (parsed.entry !== undefined) {
|
|
118
|
+
manifest[entryId] = parsed.entry;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (diagnostics.length > 0) {
|
|
122
|
+
return {
|
|
123
|
+
diagnostics,
|
|
124
|
+
ok: false
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
manifest,
|
|
129
|
+
ok: true
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Resolves a React server or client entry by manifest key, `src`, or `name`.
|
|
135
|
+
*
|
|
136
|
+
* @param manifest Parsed Vite manifest.
|
|
137
|
+
* @param role React entry role being resolved.
|
|
138
|
+
* @param entryId Requested manifest key, `src`, or `name`.
|
|
139
|
+
* @returns The resolved manifest entry or role-specific diagnostics.
|
|
140
|
+
*/
|
|
141
|
+
export function resolveManifestEntry(manifest, role, entryId) {
|
|
142
|
+
const exactEntry = readOwnValue(manifest, entryId);
|
|
143
|
+
if (exactEntry !== undefined) {
|
|
144
|
+
return {
|
|
145
|
+
diagnostics: [],
|
|
146
|
+
entry: exactEntry
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const matches = Object.values(manifest).filter(entry => entry.src === entryId || entry.name === entryId);
|
|
150
|
+
if (matches.length === 1) {
|
|
151
|
+
return {
|
|
152
|
+
diagnostics: [],
|
|
153
|
+
entry: matches[0]
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
if (matches.length > 1) {
|
|
157
|
+
return {
|
|
158
|
+
diagnostics: [{
|
|
159
|
+
code: DIAGNOSTIC_CODES.unsupportedOutputShape,
|
|
160
|
+
entry: entryId,
|
|
161
|
+
message: `React Vite ${role} entry "${entryId}" matched multiple manifest entries.`
|
|
162
|
+
}]
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
diagnostics: [createMissingEntryDiagnostic(role, entryId)]
|
|
167
|
+
};
|
|
168
|
+
}
|