pudui 0.0.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/README.md +161 -0
- package/dist/component-D3kwgmef.mjs +275 -0
- package/dist/core-Cypb6mR9.d.mts +434 -0
- package/dist/hmr-runtime.d.mts +99 -0
- package/dist/hmr-runtime.mjs +177 -0
- package/dist/hydration-markers-DdjOvH6g.mjs +218 -0
- package/dist/index.d.mts +109 -0
- package/dist/index.mjs +1505 -0
- package/dist/jsx-dev-runtime.d.mts +36 -0
- package/dist/jsx-dev-runtime.mjs +2 -0
- package/dist/jsx-runtime.d.mts +36 -0
- package/dist/jsx-runtime.mjs +2 -0
- package/dist/macros.d.mts +43 -0
- package/dist/macros.mjs +47 -0
- package/dist/server.d.mts +55 -0
- package/dist/server.mjs +223 -0
- package/dist/transforms-DUsCAPAL.mjs +707 -0
- package/dist/transforms.d.mts +150 -0
- package/dist/transforms.mjs +2 -0
- package/dist/vite-plugin.d.mts +224 -0
- package/dist/vite-plugin.mjs +748 -0
- package/dist/vite-runtime.d.mts +42 -0
- package/dist/vite-runtime.mjs +89 -0
- package/dist/vnode-Lr-Tpypk.mjs +182 -0
- package/package.json +99 -0
|
@@ -0,0 +1,748 @@
|
|
|
1
|
+
import { C as readNodeArray, D as walkWithScopes, E as walkSkippingNestedFunctions, O as normalizePath, S as readLiteralValue, T as walk, _ as shouldTransformModule, a as transformUseClient, b as parseProgram, d as parseHydrateMarker, f as cleanModuleId, g as relativeToRoot, h as publicAssetPath, i as transformHydrate, k as pathExtname, m as devModulePath, n as shouldTransformHydrate, o as createEntryMarker, p as devBrowserEntryPath, r as shouldTransformUseClient, s as createHydrateMarker, t as replaceHydrateMarkers, u as parseEntryMarker, v as getBody, w as readOptionalNode, x as readIdentifierName, y as isFunctionLike } from "./transforms-DUsCAPAL.mjs";
|
|
2
|
+
import MagicString from "magic-string";
|
|
3
|
+
import "oxc-parser";
|
|
4
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
5
|
+
import { dirname, isAbsolute, resolve } from "node:path";
|
|
6
|
+
//#region src/hmr-transform.ts
|
|
7
|
+
const defaultRuntimeModule = "#pudui/hmr-runtime";
|
|
8
|
+
const defaultRuntimeName = "__puduiHmr";
|
|
9
|
+
const defaultRefreshParameterName = "__puduiRefresh";
|
|
10
|
+
const defaultImportMeta = "import.meta";
|
|
11
|
+
/**
|
|
12
|
+
* Rewrites component modules so Vite HMR can refresh component implementations.
|
|
13
|
+
*
|
|
14
|
+
* The transform preserves compatible state cells when a component's captured
|
|
15
|
+
* state shape is unchanged and invalidates when exports change incompatibly.
|
|
16
|
+
*
|
|
17
|
+
* @param code Module source code.
|
|
18
|
+
* @param id Stable module identifier.
|
|
19
|
+
* @param options Transform customization options.
|
|
20
|
+
* @returns Transform result, or `null` when the module has no refreshable components.
|
|
21
|
+
*/
|
|
22
|
+
function transformHmr(code, id, options = {}) {
|
|
23
|
+
if (!code.includes("Component")) return null;
|
|
24
|
+
const components = findComponents(parseProgram(code, id));
|
|
25
|
+
if (components.length === 0) return null;
|
|
26
|
+
const runtimeName = options.runtimeName ?? defaultRuntimeName;
|
|
27
|
+
const refreshParameterName = options.refreshParameterName ?? defaultRefreshParameterName;
|
|
28
|
+
const importMeta = options.importMeta ?? defaultImportMeta;
|
|
29
|
+
const transformed = new MagicString(code);
|
|
30
|
+
transformed.prepend(`import * as ${runtimeName} from ${JSON.stringify(options.runtimeModule ?? defaultRuntimeModule)};\n`);
|
|
31
|
+
for (const component of components) applyComponentTransform(code, transformed, component, refreshParameterName);
|
|
32
|
+
transformed.append("\n");
|
|
33
|
+
for (const component of components) {
|
|
34
|
+
transformed.append(`${exportPrefix(component)}const ${component.localName} = ${runtimeName}.register(${importMeta}, ${JSON.stringify(id)}, ${JSON.stringify(component.exportName)}, ${JSON.stringify(signatureForState(component.state))}, ${component.setupName}, { exported: ${component.exported ? "true" : "false"} });\n`);
|
|
35
|
+
if (component.exportName === "default") transformed.append(`export default ${component.localName};\n`);
|
|
36
|
+
}
|
|
37
|
+
transformed.append(`if (${importMeta}.hot) {\n ${importMeta}.hot.accept((__puduiHmrModule) => {\n ${runtimeName}.accept(${importMeta}, __puduiHmrModule);\n });\n}\n`);
|
|
38
|
+
return {
|
|
39
|
+
code: transformed.toString(),
|
|
40
|
+
components: components.map((component) => ({
|
|
41
|
+
exportName: component.exportName,
|
|
42
|
+
localName: component.localName,
|
|
43
|
+
signature: signatureForState(component.state),
|
|
44
|
+
state: component.state.map((binding) => binding.name)
|
|
45
|
+
})),
|
|
46
|
+
map: null
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function applyComponentTransform(code, transformed, component, refreshParameterName) {
|
|
50
|
+
if (component.replacement.removeExportStart !== void 0) transformed.remove(component.replacement.removeExportStart, component.replacement.declaration.start);
|
|
51
|
+
if (component.exportStart !== void 0 && component.exportEnd !== void 0) transformed.remove(component.exportStart, component.exportEnd);
|
|
52
|
+
if (component.replacement.kind === "function") replaceFunctionHeader(code, transformed, component.replacement.functionNode, component.setupName, refreshParameterName);
|
|
53
|
+
else {
|
|
54
|
+
transformed.update(component.replacement.declaration.start, component.replacement.functionNode.start, `const ${component.setupName} = `);
|
|
55
|
+
insertRefreshParameter(code, transformed, component.replacement.functionNode, refreshParameterName);
|
|
56
|
+
}
|
|
57
|
+
const body = readOptionalNode(component.replacement.functionNode.body);
|
|
58
|
+
if (body?.type !== "BlockStatement") return;
|
|
59
|
+
const references = collectReferences(body, new Set(component.state.map((binding) => binding.name)), new Set(component.state.map((binding) => `${binding.id.start}:${binding.id.end}`)));
|
|
60
|
+
replaceStateDeclarations(code, transformed, component.state, references, refreshParameterName);
|
|
61
|
+
replaceComponentConstructors(transformed, body, refreshParameterName);
|
|
62
|
+
appendReferenceValues(transformed, references, component.state);
|
|
63
|
+
}
|
|
64
|
+
function replaceFunctionHeader(code, transformed, functionNode, setupName, refreshParameterName) {
|
|
65
|
+
const id = readOptionalNode(functionNode.id);
|
|
66
|
+
const body = readOptionalNode(functionNode.body);
|
|
67
|
+
if (id?.type !== "Identifier" || body === void 0) throw new Error("Cannot transform anonymous function declaration.");
|
|
68
|
+
const tail = code.slice(id.end, body.start);
|
|
69
|
+
transformed.update(functionNode.start, body.start, `function ${setupName}${withRefreshParameter(tail, refreshParameterName)}`);
|
|
70
|
+
}
|
|
71
|
+
function insertRefreshParameter(code, transformed, functionNode, refreshParameterName) {
|
|
72
|
+
const body = readOptionalNode(functionNode.body);
|
|
73
|
+
if (body?.type !== "BlockStatement") throw new Error("Fast refresh only supports component factories with block bodies.");
|
|
74
|
+
if (functionNode.type === "ArrowFunctionExpression") {
|
|
75
|
+
const params = readNodeArray(functionNode.params);
|
|
76
|
+
if (params.length === 1 && code[functionNode.start] !== "(") {
|
|
77
|
+
const param = params[0];
|
|
78
|
+
transformed.update(param.start, param.end, `(${refreshParameterName}, ${code.slice(param.start, param.end)})`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
transformed.update(functionNode.start, body.start, withRefreshParameter(code.slice(functionNode.start, body.start), refreshParameterName));
|
|
83
|
+
}
|
|
84
|
+
function withRefreshParameter(functionTail, refreshParameterName) {
|
|
85
|
+
const openParen = functionTail.indexOf("(");
|
|
86
|
+
if (openParen === -1) throw new Error("Cannot find component factory parameter list.");
|
|
87
|
+
const closeParen = matchingParen(functionTail, openParen);
|
|
88
|
+
const beforeParams = functionTail.slice(0, openParen + 1);
|
|
89
|
+
const params = functionTail.slice(openParen + 1, closeParen);
|
|
90
|
+
const afterParams = functionTail.slice(closeParen);
|
|
91
|
+
return `${beforeParams}${refreshParameterName}${params.trim() === "" ? "" : ", "}${params}${afterParams}`;
|
|
92
|
+
}
|
|
93
|
+
function matchingParen(value, openParen) {
|
|
94
|
+
let depth = 0;
|
|
95
|
+
for (let index = openParen; index < value.length; index++) {
|
|
96
|
+
const char = value[index];
|
|
97
|
+
if (char === "(") depth++;
|
|
98
|
+
else if (char === ")") {
|
|
99
|
+
depth--;
|
|
100
|
+
if (depth === 0) return index;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
throw new Error("Cannot find component factory parameter list.");
|
|
104
|
+
}
|
|
105
|
+
function replaceStateDeclarations(code, transformed, state, references, refreshParameterName) {
|
|
106
|
+
const byDeclaration = /* @__PURE__ */ new Map();
|
|
107
|
+
for (const binding of state) byDeclaration.set(binding.declaration, [...byDeclaration.get(binding.declaration) ?? [], binding]);
|
|
108
|
+
for (const [declaration, bindings] of byDeclaration) {
|
|
109
|
+
const replacement = bindings.map((binding) => {
|
|
110
|
+
const initializer = binding.init === void 0 ? "undefined" : rewrittenSegment(code, binding.init.start, binding.init.end, references);
|
|
111
|
+
return `const ${binding.name} = ${refreshParameterName}.cell(${JSON.stringify(binding.name)}, () => ${initializer});`;
|
|
112
|
+
}).join("\n");
|
|
113
|
+
transformed.update(declaration.start, declaration.end, replacement);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function replaceComponentConstructors(transformed, body, refreshParameterName) {
|
|
117
|
+
walk(body, (node) => {
|
|
118
|
+
if (node.type !== "NewExpression") return;
|
|
119
|
+
const callee = readOptionalNode(node.callee);
|
|
120
|
+
if (callee?.type === "Identifier" && readIdentifierName(callee) === "Component") transformed.update(node.start, callee.end, `${refreshParameterName}.component`);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
function appendReferenceValues(transformed, references, state) {
|
|
124
|
+
const declarationRanges = state.map((binding) => [binding.declaration.start, binding.declaration.end]);
|
|
125
|
+
for (const reference of references) {
|
|
126
|
+
if (declarationRanges.some(([start, end]) => reference.start >= start && reference.end <= end)) continue;
|
|
127
|
+
if (reference.replacement !== void 0) transformed.update(reference.start, reference.end, reference.replacement);
|
|
128
|
+
else transformed.appendLeft(reference.end, ".value");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function rewrittenSegment(code, start, end, references) {
|
|
132
|
+
const nestedReferences = references.filter((reference) => reference.start >= start && reference.end <= end).sort((left, right) => right.end - left.end);
|
|
133
|
+
let output = code.slice(start, end);
|
|
134
|
+
for (const reference of nestedReferences) {
|
|
135
|
+
const replacement = reference.replacement ?? `${reference.name}.value`;
|
|
136
|
+
output = output.slice(0, reference.start - start) + replacement + output.slice(reference.end - start);
|
|
137
|
+
}
|
|
138
|
+
return output;
|
|
139
|
+
}
|
|
140
|
+
function findComponents(program) {
|
|
141
|
+
const topLevelFunctions = /* @__PURE__ */ new Map();
|
|
142
|
+
const namedExports = /* @__PURE__ */ new Map();
|
|
143
|
+
const components = [];
|
|
144
|
+
for (const statement of getBody(program)) if (statement.type === "FunctionDeclaration") {
|
|
145
|
+
const name = readIdentifierName(statement.id);
|
|
146
|
+
if (name !== "") topLevelFunctions.set(name, {
|
|
147
|
+
declaration: statement,
|
|
148
|
+
functionNode: statement,
|
|
149
|
+
kind: "function"
|
|
150
|
+
});
|
|
151
|
+
} else if (statement.type === "VariableDeclaration") collectTopLevelVariableFunctions(statement, topLevelFunctions);
|
|
152
|
+
else if (statement.type === "ExportNamedDeclaration") collectExportedDeclaration(statement, topLevelFunctions, namedExports, components);
|
|
153
|
+
else if (statement.type === "ExportDefaultDeclaration") collectDefaultExportedDeclaration(statement, topLevelFunctions, namedExports, components);
|
|
154
|
+
for (const [localName, namedExport] of namedExports) {
|
|
155
|
+
const replacement = topLevelFunctions.get(localName);
|
|
156
|
+
if (replacement !== void 0) addComponent(components, localName, namedExport.exportName, replacement, {
|
|
157
|
+
exported: true,
|
|
158
|
+
exportEnd: namedExport.exportEnd,
|
|
159
|
+
exportStart: namedExport.exportStart
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
const exportedLocals = new Set(components.map((component) => component.localName));
|
|
163
|
+
for (const [localName, replacement] of topLevelFunctions) if (!exportedLocals.has(localName)) addComponent(components, localName, localName, replacement, { exported: false });
|
|
164
|
+
return dedupeComponents(components).filter((component) => containsComponentConstructor(component.replacement.functionNode));
|
|
165
|
+
}
|
|
166
|
+
function collectExportedDeclaration(statement, topLevelFunctions, namedExports, components) {
|
|
167
|
+
const declaration = readOptionalNode(statement.declaration);
|
|
168
|
+
if (declaration !== void 0) {
|
|
169
|
+
if (declaration.type === "FunctionDeclaration") {
|
|
170
|
+
const localName = readIdentifierName(declaration.id);
|
|
171
|
+
if (localName !== "") addComponent(components, localName, localName, {
|
|
172
|
+
declaration,
|
|
173
|
+
functionNode: declaration,
|
|
174
|
+
kind: "function",
|
|
175
|
+
removeExportStart: statement.start
|
|
176
|
+
}, { exported: true });
|
|
177
|
+
} else if (declaration.type === "VariableDeclaration") collectExportedVariableFunctions(statement, declaration, components, void 0, true);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (statement.source !== null) return;
|
|
181
|
+
for (const specifier of readNodeArray(statement.specifiers)) if (specifier.type === "ExportSpecifier") namedExports.set(readIdentifierName(specifier.local), { exportName: readIdentifierName(specifier.exported) });
|
|
182
|
+
}
|
|
183
|
+
function collectDefaultExportedDeclaration(statement, topLevelFunctions, namedExports, components) {
|
|
184
|
+
const declaration = readOptionalNode(statement.declaration);
|
|
185
|
+
if (declaration === void 0) return;
|
|
186
|
+
if (declaration.type === "FunctionDeclaration") addComponent(components, readIdentifierName(declaration.id) || "__puduiDefault", "default", {
|
|
187
|
+
declaration,
|
|
188
|
+
functionNode: declaration,
|
|
189
|
+
kind: "function",
|
|
190
|
+
removeExportStart: statement.start
|
|
191
|
+
}, { exported: true });
|
|
192
|
+
else if (declaration.type === "Identifier") namedExports.set(readIdentifierName(declaration), {
|
|
193
|
+
exportEnd: statement.end,
|
|
194
|
+
exportName: "default",
|
|
195
|
+
exportStart: statement.start
|
|
196
|
+
});
|
|
197
|
+
else if (declaration.type === "VariableDeclaration") collectExportedVariableFunctions(statement, declaration, components, "default", true);
|
|
198
|
+
}
|
|
199
|
+
function collectTopLevelVariableFunctions(declaration, topLevelFunctions) {
|
|
200
|
+
for (const declarator of readNodeArray(declaration.declarations)) {
|
|
201
|
+
const id = readOptionalNode(declarator.id);
|
|
202
|
+
const init = readOptionalNode(declarator.init);
|
|
203
|
+
if (id?.type === "Identifier" && init !== void 0 && isBlockFunction(init)) topLevelFunctions.set(readIdentifierName(id), {
|
|
204
|
+
declaration,
|
|
205
|
+
functionNode: init,
|
|
206
|
+
id,
|
|
207
|
+
kind: "variable"
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function collectExportedVariableFunctions(statement, declaration, components, exportName, exported = false) {
|
|
212
|
+
const declarations = readNodeArray(declaration.declarations);
|
|
213
|
+
if (declarations.length !== 1) return;
|
|
214
|
+
const declarator = declarations[0];
|
|
215
|
+
const id = readOptionalNode(declarator.id);
|
|
216
|
+
const init = readOptionalNode(declarator.init);
|
|
217
|
+
if (id?.type !== "Identifier" || init === void 0 || !isBlockFunction(init)) return;
|
|
218
|
+
const localName = readIdentifierName(id);
|
|
219
|
+
addComponent(components, localName, exportName ?? localName, {
|
|
220
|
+
declaration,
|
|
221
|
+
functionNode: init,
|
|
222
|
+
id,
|
|
223
|
+
kind: "variable",
|
|
224
|
+
removeExportStart: statement.start
|
|
225
|
+
}, { exported });
|
|
226
|
+
}
|
|
227
|
+
function addComponent(components, localName, exportName, replacement, options = {}) {
|
|
228
|
+
components.push({
|
|
229
|
+
exportEnd: options.exportEnd,
|
|
230
|
+
exported: options.exported ?? false,
|
|
231
|
+
exportName,
|
|
232
|
+
exportStart: options.exportStart,
|
|
233
|
+
localName,
|
|
234
|
+
node: replacement.functionNode,
|
|
235
|
+
replacement,
|
|
236
|
+
setupName: setupName(localName, exportName),
|
|
237
|
+
state: collectStateBindings(replacement.functionNode)
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
function dedupeComponents(components) {
|
|
241
|
+
const seen = /* @__PURE__ */ new Set();
|
|
242
|
+
const deduped = [];
|
|
243
|
+
for (const component of components) {
|
|
244
|
+
const key = `${component.localName}:${component.exportName}`;
|
|
245
|
+
if (!seen.has(key)) {
|
|
246
|
+
seen.add(key);
|
|
247
|
+
deduped.push(component);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return deduped;
|
|
251
|
+
}
|
|
252
|
+
function collectStateBindings(functionNode) {
|
|
253
|
+
const body = readOptionalNode(functionNode.body);
|
|
254
|
+
const state = [];
|
|
255
|
+
if (body?.type !== "BlockStatement") return state;
|
|
256
|
+
for (const statement of readNodeArray(body.body)) {
|
|
257
|
+
if (statement.type !== "VariableDeclaration") continue;
|
|
258
|
+
const declarations = readNodeArray(statement.declarations);
|
|
259
|
+
if (declarations.length === 0 || declarations.some((declarator) => {
|
|
260
|
+
const id = readOptionalNode(declarator.id);
|
|
261
|
+
const init = readOptionalNode(declarator.init);
|
|
262
|
+
return id?.type !== "Identifier" || isComponentConstructor(init);
|
|
263
|
+
})) continue;
|
|
264
|
+
for (const declarator of declarations) {
|
|
265
|
+
const id = readOptionalNode(declarator.id);
|
|
266
|
+
state.push({
|
|
267
|
+
declaration: statement,
|
|
268
|
+
id,
|
|
269
|
+
init: readOptionalNode(declarator.init),
|
|
270
|
+
kind: typeof statement.kind === "string" ? statement.kind : "let",
|
|
271
|
+
name: readIdentifierName(id)
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return state;
|
|
276
|
+
}
|
|
277
|
+
function collectReferences(root, names, stateBindingIds) {
|
|
278
|
+
const references = [];
|
|
279
|
+
const scopeStack = [];
|
|
280
|
+
walkWithScopes(root, void 0, {
|
|
281
|
+
enterScope(node) {
|
|
282
|
+
scopeStack.push(collectScopeBindings(node, names, stateBindingIds));
|
|
283
|
+
},
|
|
284
|
+
leaveScope() {
|
|
285
|
+
scopeStack.pop();
|
|
286
|
+
},
|
|
287
|
+
visit(node, parent) {
|
|
288
|
+
if (node.type !== "Identifier") return;
|
|
289
|
+
const name = readIdentifierName(node);
|
|
290
|
+
if (!names.has(name) || isShadowed(name, scopeStack) || !isReferenceIdentifier(node, parent)) return;
|
|
291
|
+
references.push({
|
|
292
|
+
start: node.start,
|
|
293
|
+
end: node.end,
|
|
294
|
+
name,
|
|
295
|
+
replacement: shorthandReplacement(node, parent, name)
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
return references;
|
|
300
|
+
}
|
|
301
|
+
function collectScopeBindings(node, names, stateBindingIds) {
|
|
302
|
+
const bindings = /* @__PURE__ */ new Set();
|
|
303
|
+
if (isFunctionLike(node)) for (const param of readNodeArray(node.params)) collectPatternBindings(param, names, stateBindingIds, bindings);
|
|
304
|
+
const statements = node.type === "BlockStatement" ? readNodeArray(node.body) : isFunctionLike(node) && readOptionalNode(node.body)?.type === "BlockStatement" ? readNodeArray(readOptionalNode(node.body)?.body) : [];
|
|
305
|
+
for (const statement of statements) {
|
|
306
|
+
if (statement.type !== "VariableDeclaration") continue;
|
|
307
|
+
for (const declarator of readNodeArray(statement.declarations)) {
|
|
308
|
+
const id = readOptionalNode(declarator.id);
|
|
309
|
+
if (id !== void 0) collectPatternBindings(id, names, stateBindingIds, bindings);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return bindings;
|
|
313
|
+
}
|
|
314
|
+
function collectPatternBindings(pattern, names, stateBindingIds, bindings) {
|
|
315
|
+
walk(pattern, (node) => {
|
|
316
|
+
if (node.type !== "Identifier") return;
|
|
317
|
+
const name = readIdentifierName(node);
|
|
318
|
+
if (names.has(name) && !stateBindingIds.has(`${node.start}:${node.end}`)) bindings.add(name);
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
function isShadowed(name, scopeStack) {
|
|
322
|
+
return scopeStack.some((scope) => scope.has(name));
|
|
323
|
+
}
|
|
324
|
+
function shorthandReplacement(node, parent, name) {
|
|
325
|
+
if ((parent?.type === "Property" || parent?.type === "ObjectProperty") && parent.value === node && parent.shorthand === true) return `${name}: ${name}.value`;
|
|
326
|
+
}
|
|
327
|
+
function isReferenceIdentifier(node, parent) {
|
|
328
|
+
if (parent === void 0) return true;
|
|
329
|
+
if (parent.type === "VariableDeclarator" && parent.id === node) return false;
|
|
330
|
+
if ((parent.type === "FunctionDeclaration" || parent.type === "FunctionExpression" || parent.type === "ArrowFunctionExpression") && readNodeArray(parent.params).includes(node)) return false;
|
|
331
|
+
if (parent.type === "MemberExpression" || parent.type === "OptionalMemberExpression") {
|
|
332
|
+
if (parent.property === node && parent.computed !== true) return false;
|
|
333
|
+
const property = readOptionalNode(parent.property);
|
|
334
|
+
if (parent.object === node && property?.type === "Identifier" && readIdentifierName(property) === "value" && parent.computed !== true) return false;
|
|
335
|
+
}
|
|
336
|
+
if (parent.type === "Property" || parent.type === "ObjectProperty") {
|
|
337
|
+
if (parent.key === node && parent.computed !== true) return false;
|
|
338
|
+
}
|
|
339
|
+
if (parent.type === "LabeledStatement" || parent.type === "BreakStatement" || parent.type === "ContinueStatement") return false;
|
|
340
|
+
if (parent.type.startsWith("TS")) return false;
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
function containsComponentConstructor(functionNode) {
|
|
344
|
+
let found = false;
|
|
345
|
+
walkComponentFactoryBody(functionNode, (node) => {
|
|
346
|
+
if (isComponentConstructor(node)) found = true;
|
|
347
|
+
});
|
|
348
|
+
return found;
|
|
349
|
+
}
|
|
350
|
+
function walkComponentFactoryBody(functionNode, enter) {
|
|
351
|
+
const body = readOptionalNode(functionNode.body);
|
|
352
|
+
if (body?.type !== "BlockStatement") return;
|
|
353
|
+
walkSkippingNestedFunctions(body, enter);
|
|
354
|
+
}
|
|
355
|
+
function isComponentConstructor(node) {
|
|
356
|
+
if (node?.type !== "NewExpression") return false;
|
|
357
|
+
const callee = readOptionalNode(node.callee);
|
|
358
|
+
return callee?.type === "Identifier" && readIdentifierName(callee) === "Component";
|
|
359
|
+
}
|
|
360
|
+
function isBlockFunction(node) {
|
|
361
|
+
return isFunctionLike(node) && readOptionalNode(node.body)?.type === "BlockStatement";
|
|
362
|
+
}
|
|
363
|
+
function exportPrefix(component) {
|
|
364
|
+
return component.exported && component.exportName === component.localName && component.exportName !== "default" ? "export " : "";
|
|
365
|
+
}
|
|
366
|
+
function setupName(localName, exportName) {
|
|
367
|
+
const base = localName === "" ? "__puduiDefault" : localName;
|
|
368
|
+
return `${base === "default" ? "__puduiDefault" : base}$${exportName === "default" ? "default" : "setup"}`;
|
|
369
|
+
}
|
|
370
|
+
function signatureForState(state) {
|
|
371
|
+
return state.map((binding) => `${binding.kind}:${binding.name}`).join("|");
|
|
372
|
+
}
|
|
373
|
+
//#endregion
|
|
374
|
+
//#region src/transforms/manifest.ts
|
|
375
|
+
/**
|
|
376
|
+
* Reads the Vite manifest asset from a Rolldown output object.
|
|
377
|
+
*
|
|
378
|
+
* @param output Build output to inspect.
|
|
379
|
+
* @returns Parsed manifest, or `undefined` when no manifest asset exists.
|
|
380
|
+
*/
|
|
381
|
+
function readManifestFromOutput(output) {
|
|
382
|
+
const manifestAsset = output.output.find((chunk) => chunk.type === "asset" && chunk.fileName === ".vite/manifest.json");
|
|
383
|
+
if (manifestAsset?.source === void 0) return;
|
|
384
|
+
return JSON.parse(manifestAsset.source.toString());
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Reads the Vite manifest asset from an output bundle.
|
|
388
|
+
*
|
|
389
|
+
* @param bundle Output bundle to inspect.
|
|
390
|
+
* @returns Parsed manifest, or `undefined` when no manifest asset exists.
|
|
391
|
+
*/
|
|
392
|
+
function readManifestFromBundle(bundle) {
|
|
393
|
+
const manifestAsset = Object.values(bundle).find((chunk) => chunk.type === "asset" && chunk.fileName === ".vite/manifest.json");
|
|
394
|
+
if (manifestAsset?.source === void 0) return;
|
|
395
|
+
return JSON.parse(manifestAsset.source.toString());
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Finds the manifest chunk for a source module id.
|
|
399
|
+
*
|
|
400
|
+
* @param manifest Manifest to search.
|
|
401
|
+
* @param id Source module id.
|
|
402
|
+
* @param config Vite config used for root-relative matching.
|
|
403
|
+
* @returns Matching manifest chunk, or `undefined`.
|
|
404
|
+
*/
|
|
405
|
+
function findManifestEntry(manifest, id, config) {
|
|
406
|
+
if (manifest === void 0) return;
|
|
407
|
+
const normalizedId = normalizePath(id);
|
|
408
|
+
const rootRelativeId = config === void 0 ? void 0 : relativeToRoot(config.root, id);
|
|
409
|
+
for (const [key, entry] of Object.entries(manifest)) if (isManifestIdMatch(key, normalizedId, rootRelativeId, config) || entry.src !== void 0 && isManifestIdMatch(entry.src, normalizedId, rootRelativeId, config)) return entry;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Collects imported chunk URLs for a manifest chunk.
|
|
413
|
+
*
|
|
414
|
+
* @param chunk Manifest chunk to inspect.
|
|
415
|
+
* @param manifest Full Vite manifest.
|
|
416
|
+
* @param config Vite config used for public asset paths.
|
|
417
|
+
* @returns Public URLs for transitive imported chunks.
|
|
418
|
+
*/
|
|
419
|
+
function collectManifestImportPaths(chunk, manifest, config) {
|
|
420
|
+
const imports = /* @__PURE__ */ new Set();
|
|
421
|
+
collectManifestImports(chunk, manifest, imports);
|
|
422
|
+
return [...imports].map((fileName) => publicAssetPath(fileName, config));
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Collects stylesheet URLs for a manifest chunk and its imports.
|
|
426
|
+
*
|
|
427
|
+
* @param chunk Manifest chunk to inspect.
|
|
428
|
+
* @param manifest Full Vite manifest.
|
|
429
|
+
* @param config Vite config used for public asset paths.
|
|
430
|
+
* @returns Public stylesheet URLs.
|
|
431
|
+
*/
|
|
432
|
+
function collectManifestStyles(chunk, manifest, config) {
|
|
433
|
+
const styles = /* @__PURE__ */ new Set();
|
|
434
|
+
collectManifestStyleFiles(chunk, manifest, styles, /* @__PURE__ */ new Set());
|
|
435
|
+
return [...styles].map((fileName) => publicAssetPath(fileName, config));
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Collects stylesheet URLs for an entire Vite environment manifest.
|
|
439
|
+
*
|
|
440
|
+
* @param manifest Manifest to inspect.
|
|
441
|
+
* @param config Vite config used for public asset paths.
|
|
442
|
+
* @returns Public stylesheet URLs.
|
|
443
|
+
*/
|
|
444
|
+
function collectManifestEnvironmentStyles(manifest, config) {
|
|
445
|
+
if (manifest === void 0) return [];
|
|
446
|
+
const styles = /* @__PURE__ */ new Set();
|
|
447
|
+
const chunks = Object.values(manifest);
|
|
448
|
+
const entryChunks = chunks.filter((chunk) => chunk.isEntry);
|
|
449
|
+
for (const chunk of entryChunks.length === 0 ? chunks : entryChunks) collectManifestStyleFiles(chunk, manifest, styles, /* @__PURE__ */ new Set());
|
|
450
|
+
return [...styles].map((fileName) => publicAssetPath(fileName, config));
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Collects emitted asset filenames for an entire Vite environment manifest.
|
|
454
|
+
*
|
|
455
|
+
* @param manifest Manifest to inspect.
|
|
456
|
+
* @returns Emitted asset filenames.
|
|
457
|
+
*/
|
|
458
|
+
function collectManifestEnvironmentAssetFiles(manifest) {
|
|
459
|
+
if (manifest === void 0) return [];
|
|
460
|
+
const assets = /* @__PURE__ */ new Set();
|
|
461
|
+
const chunks = Object.values(manifest);
|
|
462
|
+
const entryChunks = chunks.filter((chunk) => chunk.isEntry);
|
|
463
|
+
for (const chunk of entryChunks.length === 0 ? chunks : entryChunks) collectManifestAssetFiles(chunk, manifest, assets, /* @__PURE__ */ new Set());
|
|
464
|
+
return [...assets];
|
|
465
|
+
}
|
|
466
|
+
function isManifestIdMatch(manifestId, normalizedId, rootRelativeId, config) {
|
|
467
|
+
const normalizedManifestId = normalizePath(manifestId);
|
|
468
|
+
return normalizedManifestId === normalizedId || normalizedManifestId === rootRelativeId || rootRelativeId !== void 0 && normalizedManifestId === `/${rootRelativeId}` || config !== void 0 && normalizePath(`${config.root}/${normalizedManifestId}`) === normalizedId;
|
|
469
|
+
}
|
|
470
|
+
function collectManifestImports(chunk, manifest, imports) {
|
|
471
|
+
if (manifest === void 0) return;
|
|
472
|
+
for (const manifestKey of chunk.imports ?? []) {
|
|
473
|
+
const importedChunk = manifest[manifestKey];
|
|
474
|
+
if (importedChunk === void 0 || imports.has(importedChunk.file)) continue;
|
|
475
|
+
imports.add(importedChunk.file);
|
|
476
|
+
collectManifestImports(importedChunk, manifest, imports);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
function collectManifestStyleFiles(chunk, manifest, styles, visited) {
|
|
480
|
+
if (visited.has(chunk)) return;
|
|
481
|
+
visited.add(chunk);
|
|
482
|
+
if (manifest !== void 0) for (const manifestKey of chunk.imports ?? []) {
|
|
483
|
+
const importedChunk = manifest[manifestKey];
|
|
484
|
+
if (importedChunk !== void 0) collectManifestStyleFiles(importedChunk, manifest, styles, visited);
|
|
485
|
+
}
|
|
486
|
+
for (const fileName of chunk.css ?? []) styles.add(fileName);
|
|
487
|
+
}
|
|
488
|
+
function collectManifestAssetFiles(chunk, manifest, assets, visited) {
|
|
489
|
+
if (visited.has(chunk)) return;
|
|
490
|
+
visited.add(chunk);
|
|
491
|
+
if (manifest !== void 0) for (const manifestKey of chunk.imports ?? []) {
|
|
492
|
+
const importedChunk = manifest[manifestKey];
|
|
493
|
+
if (importedChunk !== void 0) collectManifestAssetFiles(importedChunk, manifest, assets, visited);
|
|
494
|
+
}
|
|
495
|
+
for (const fileName of chunk.css ?? []) assets.add(fileName);
|
|
496
|
+
for (const fileName of chunk.assets ?? []) assets.add(fileName);
|
|
497
|
+
}
|
|
498
|
+
//#endregion
|
|
499
|
+
//#region src/vite-plugin.ts
|
|
500
|
+
/**
|
|
501
|
+
* Creates the full Pudui Vite plugin set.
|
|
502
|
+
*
|
|
503
|
+
* The returned plugins transform `"use client"` components, replace
|
|
504
|
+
* `pudui/macros` calls, wire build manifest assets, and enable component HMR in
|
|
505
|
+
* development.
|
|
506
|
+
*
|
|
507
|
+
* @param options Pudui Vite plugin options.
|
|
508
|
+
* @returns Vite plugins required for Pudui applications.
|
|
509
|
+
*
|
|
510
|
+
* @example
|
|
511
|
+
* ```ts
|
|
512
|
+
* import { defineConfig } from "vite";
|
|
513
|
+
* import pudui from "pudui/vite-plugin";
|
|
514
|
+
*
|
|
515
|
+
* export default defineConfig({
|
|
516
|
+
* plugins: [pudui({ browserEntry: "app/browser.tsx" })],
|
|
517
|
+
* });
|
|
518
|
+
* ```
|
|
519
|
+
*/
|
|
520
|
+
function pudui(options) {
|
|
521
|
+
return [
|
|
522
|
+
useClientPlugin(),
|
|
523
|
+
macrosPlugin(options),
|
|
524
|
+
hrmPlugin(options)
|
|
525
|
+
];
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Creates the transform that injects hydration macros for `"use client"` modules.
|
|
529
|
+
*
|
|
530
|
+
* Most applications should use the default {@link pudui} plugin set instead of
|
|
531
|
+
* composing this directly.
|
|
532
|
+
*
|
|
533
|
+
* @returns A Vite plugin that scans client modules for exported components.
|
|
534
|
+
*/
|
|
535
|
+
function useClientPlugin() {
|
|
536
|
+
return {
|
|
537
|
+
name: "pudui:use-client",
|
|
538
|
+
enforce: "pre",
|
|
539
|
+
sharedDuringBuild: true,
|
|
540
|
+
transform(code, rawId) {
|
|
541
|
+
const id = cleanModuleId(rawId);
|
|
542
|
+
if (!shouldTransformModule(id) || !shouldTransformUseClient(code)) return null;
|
|
543
|
+
return transformUseClient(code, id);
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Creates the transform and build hooks that resolve Pudui macros.
|
|
549
|
+
*
|
|
550
|
+
* The plugin replaces `hydrate()` and `entry()` macro calls, adds client build
|
|
551
|
+
* entries for hydrated modules, and copies manifest asset metadata between Vite
|
|
552
|
+
* environments.
|
|
553
|
+
*
|
|
554
|
+
* @param options Pudui Vite plugin options.
|
|
555
|
+
* @param options.browserEntry Browser entry module used for hydrated client bundles.
|
|
556
|
+
* @returns A Vite plugin for macro transformation and build metadata.
|
|
557
|
+
*/
|
|
558
|
+
function macrosPlugin(options) {
|
|
559
|
+
const { browserEntry } = options;
|
|
560
|
+
let config;
|
|
561
|
+
const clientEntryIds = /* @__PURE__ */ new Set();
|
|
562
|
+
let clientManifest;
|
|
563
|
+
return {
|
|
564
|
+
name: "pudui:macros",
|
|
565
|
+
enforce: "pre",
|
|
566
|
+
sharedDuringBuild: true,
|
|
567
|
+
configResolved(resolvedConfig) {
|
|
568
|
+
config = resolvedConfig;
|
|
569
|
+
},
|
|
570
|
+
buildApp: {
|
|
571
|
+
order: "post",
|
|
572
|
+
async handler(builder) {
|
|
573
|
+
const { client, ...rest } = builder.environments;
|
|
574
|
+
await Promise.all(Object.values(rest).map((environment) => builder.build(environment)));
|
|
575
|
+
if (client !== void 0) {
|
|
576
|
+
const input = client.config.build.rolldownOptions.input;
|
|
577
|
+
if (input !== void 0 && !Array.isArray(input)) throw new Error("Pudui builder does not support non-array client input. Use an array of entry points instead.");
|
|
578
|
+
client.config.build.rolldownOptions.input = Array.from(new Set([
|
|
579
|
+
...input ?? [],
|
|
580
|
+
browserEntry,
|
|
581
|
+
...clientEntryIds
|
|
582
|
+
]));
|
|
583
|
+
client.config.build.rolldownOptions.preserveEntrySignatures ??= "exports-only";
|
|
584
|
+
const manifest = readManifestFromOutput(await builder.build(client));
|
|
585
|
+
if (manifest === void 0) throw new Error("Failed to find Vite manifest asset in client build output.");
|
|
586
|
+
clientManifest = manifest;
|
|
587
|
+
}
|
|
588
|
+
const outputs = await Promise.all(Object.values(rest).map((environment) => builder.build(environment)));
|
|
589
|
+
if (client !== void 0) await copyManifestAssetsToClient(outputs, client, config);
|
|
590
|
+
}
|
|
591
|
+
},
|
|
592
|
+
configEnvironment(name) {
|
|
593
|
+
if (name === "client") return { build: { manifest: true } };
|
|
594
|
+
return { build: {
|
|
595
|
+
emitAssets: true,
|
|
596
|
+
manifest: true
|
|
597
|
+
} };
|
|
598
|
+
},
|
|
599
|
+
async transform(code, rawId) {
|
|
600
|
+
const id = cleanModuleId(rawId);
|
|
601
|
+
if (!shouldTransformModule(id)) return null;
|
|
602
|
+
const build = isBuild(this.environment, config);
|
|
603
|
+
const clientBuild = build && this.environment?.name === "client";
|
|
604
|
+
const devServerStyles = build ? [] : await collectDevServerStylePaths(this, code, id, config);
|
|
605
|
+
const transformed = shouldTransformHydrate(code) ? transformHydrate(code, id, clientBuild ? { mode: "client" } : build ? {
|
|
606
|
+
browserEntry,
|
|
607
|
+
mode: "build",
|
|
608
|
+
createEntryMarker(moduleId) {
|
|
609
|
+
return createEntryMarker(moduleId);
|
|
610
|
+
},
|
|
611
|
+
createHydrateMarker(moduleId, exportName) {
|
|
612
|
+
return createHydrateMarker(moduleId, exportName);
|
|
613
|
+
}
|
|
614
|
+
} : {
|
|
615
|
+
browserEntry,
|
|
616
|
+
browserEntryPath: devBrowserEntryPath(browserEntry, config),
|
|
617
|
+
entryStylesExpression: devServerStylesExpression(),
|
|
618
|
+
mode: "dev",
|
|
619
|
+
modulePath: devModulePath(id, config)
|
|
620
|
+
}) : null;
|
|
621
|
+
if (transformed === null && devServerStyles.length === 0) return null;
|
|
622
|
+
if (build && !clientBuild && transformed?.hydrateCalls.length) clientEntryIds.add(id);
|
|
623
|
+
return {
|
|
624
|
+
code: `${registerDevServerStyles(devServerStyles)}${transformed?.code ?? code}`,
|
|
625
|
+
map: null
|
|
626
|
+
};
|
|
627
|
+
},
|
|
628
|
+
generateBundle: {
|
|
629
|
+
order: "post",
|
|
630
|
+
handler(_options, _bundle) {
|
|
631
|
+
const serverStyles = collectManifestEnvironmentStyles(readManifestFromBundle(_bundle), config);
|
|
632
|
+
for (const chunk of Object.values(_bundle)) {
|
|
633
|
+
if (chunk.type !== "chunk" || !chunk.code.includes("__PUDUI_HYDRATE__") && !chunk.code.includes("__PUDUI_ENTRY__")) continue;
|
|
634
|
+
chunk.code = replaceHydrateMarkers(chunk.code, (marker) => {
|
|
635
|
+
const entryInfo = parseEntryMarker(marker);
|
|
636
|
+
if (entryInfo !== void 0) {
|
|
637
|
+
const manifestEntry = findManifestEntry(clientManifest, entryInfo.id, config);
|
|
638
|
+
if (manifestEntry === void 0) return;
|
|
639
|
+
return [
|
|
640
|
+
publicAssetPath(manifestEntry.file, config),
|
|
641
|
+
collectManifestImportPaths(manifestEntry, clientManifest, config),
|
|
642
|
+
unique([...collectManifestStyles(manifestEntry, clientManifest, config), ...serverStyles])
|
|
643
|
+
];
|
|
644
|
+
}
|
|
645
|
+
const markerInfo = parseHydrateMarker(marker);
|
|
646
|
+
if (markerInfo === void 0) return;
|
|
647
|
+
const manifestEntry = findManifestEntry(clientManifest, markerInfo.id, config);
|
|
648
|
+
if (manifestEntry === void 0) return;
|
|
649
|
+
return [
|
|
650
|
+
publicAssetPath(manifestEntry.file, config),
|
|
651
|
+
markerInfo.exportName,
|
|
652
|
+
collectManifestImportPaths(manifestEntry, clientManifest, config),
|
|
653
|
+
collectManifestStyles(manifestEntry, clientManifest, config)
|
|
654
|
+
];
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Creates the Pudui component HMR transform.
|
|
663
|
+
*
|
|
664
|
+
* This is exported for advanced Vite integrations that need to compose Pudui's
|
|
665
|
+
* plugin pieces manually.
|
|
666
|
+
*
|
|
667
|
+
* @param options HMR plugin options.
|
|
668
|
+
* @param options.hmr HMR options, or `false` to disable the transform.
|
|
669
|
+
* @returns A Vite plugin that rewrites components for refresh.
|
|
670
|
+
*/
|
|
671
|
+
function hrmPlugin(options = {}) {
|
|
672
|
+
const { hmr } = options;
|
|
673
|
+
let config;
|
|
674
|
+
return {
|
|
675
|
+
name: "pudui:hmr",
|
|
676
|
+
enforce: "pre",
|
|
677
|
+
sharedDuringBuild: true,
|
|
678
|
+
configResolved(resolvedConfig) {
|
|
679
|
+
config = resolvedConfig;
|
|
680
|
+
},
|
|
681
|
+
transform(code, rawId) {
|
|
682
|
+
const id = cleanModuleId(rawId);
|
|
683
|
+
const build = isBuild(this.environment, config);
|
|
684
|
+
if (!shouldTransformModule(id) || !shouldTransformHmr(code, build, this.environment) || hmr === false) return null;
|
|
685
|
+
return transformHmr(code, id, {
|
|
686
|
+
...hmr,
|
|
687
|
+
runtimeModule: hmr?.runtimeModule ?? "pudui/hmr-runtime"
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Alias for {@link hrmPlugin}.
|
|
694
|
+
*/
|
|
695
|
+
const hmrPlugin = hrmPlugin;
|
|
696
|
+
function unique(values) {
|
|
697
|
+
return [...new Set(values)];
|
|
698
|
+
}
|
|
699
|
+
async function collectDevServerStylePaths(context, code, id, config) {
|
|
700
|
+
if (context.environment?.name === void 0 || context.environment.name === "client") return [];
|
|
701
|
+
const styleSources = collectCssImportSources(code, id);
|
|
702
|
+
if (styleSources.length === 0) return [];
|
|
703
|
+
return Promise.all(styleSources.map(async (source) => devModulePath(await resolveStyleId(context, source, id, config), config)));
|
|
704
|
+
}
|
|
705
|
+
function collectCssImportSources(code, id) {
|
|
706
|
+
const program = parseProgram(code, id);
|
|
707
|
+
const sources = /* @__PURE__ */ new Set();
|
|
708
|
+
for (const statement of getBody(program)) {
|
|
709
|
+
if (statement.type !== "ImportDeclaration") continue;
|
|
710
|
+
const source = readLiteralValue(statement.source);
|
|
711
|
+
if (pathExtname(cleanModuleId(source)) === ".css") sources.add(source);
|
|
712
|
+
}
|
|
713
|
+
return [...sources];
|
|
714
|
+
}
|
|
715
|
+
async function resolveStyleId(context, source, importer, config) {
|
|
716
|
+
const resolved = await context.resolve?.(source, importer, { skipSelf: true });
|
|
717
|
+
if (resolved !== void 0 && resolved !== null) return cleanModuleId(resolved.id);
|
|
718
|
+
if (source.startsWith(".")) return resolve(dirname(importer), source);
|
|
719
|
+
if (isAbsolute(source)) return source;
|
|
720
|
+
return config === void 0 ? source : resolve(config.root, "node_modules", source);
|
|
721
|
+
}
|
|
722
|
+
function registerDevServerStyles(styles) {
|
|
723
|
+
if (styles.length === 0) return "";
|
|
724
|
+
return `globalThis.__PUDUI_DEV_STYLES__ ??= new Set();\n${styles.map((href) => `globalThis.__PUDUI_DEV_STYLES__.add(${JSON.stringify(href)});`).join("\n")}\n`;
|
|
725
|
+
}
|
|
726
|
+
function devServerStylesExpression() {
|
|
727
|
+
return "Array.from(globalThis.__PUDUI_DEV_STYLES__ ?? [])";
|
|
728
|
+
}
|
|
729
|
+
async function copyManifestAssetsToClient(outputs, client, config) {
|
|
730
|
+
const clientOutDir = resolve(config?.root ?? "", client.config.build.outDir ?? "dist/client");
|
|
731
|
+
await Promise.all(outputs.flatMap((output) => {
|
|
732
|
+
const manifest = readManifestFromOutput(output);
|
|
733
|
+
const assetFiles = new Set(collectManifestEnvironmentAssetFiles(manifest));
|
|
734
|
+
return output.output.flatMap((chunk) => {
|
|
735
|
+
if (chunk.type !== "asset" || chunk.source === void 0 || !assetFiles.has(chunk.fileName)) return [];
|
|
736
|
+
const filePath = resolve(clientOutDir, chunk.fileName);
|
|
737
|
+
return mkdir(dirname(filePath), { recursive: true }).then(() => writeFile(filePath, chunk.source ?? ""));
|
|
738
|
+
});
|
|
739
|
+
}));
|
|
740
|
+
}
|
|
741
|
+
function shouldTransformHmr(code, build, environment) {
|
|
742
|
+
return !build && (environment?.name === void 0 || environment.name === "client") && code.includes("Component");
|
|
743
|
+
}
|
|
744
|
+
function isBuild(environment, config) {
|
|
745
|
+
return environment?.mode === "build" || config?.command === "build";
|
|
746
|
+
}
|
|
747
|
+
//#endregion
|
|
748
|
+
export { pudui as default, hmrPlugin, hrmPlugin, macrosPlugin, replaceHydrateMarkers, transformHydrate, transformUseClient, useClientPlugin };
|