@fluixi/compiler 1.0.0-alpha.92 → 1.0.0-alpha.94
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/dist/analyze/intrinsics.cjs +31 -1
- package/dist/analyze/intrinsics.d.cts +14 -0
- package/dist/analyze/intrinsics.d.ts +14 -0
- package/dist/analyze/intrinsics.d.ts.map +1 -1
- package/dist/analyze/intrinsics.js +35 -0
- package/dist/analyze/intrinsics.mjs +31 -1
- package/dist/analyze/reactive-bindings.cjs +18 -0
- package/dist/analyze/reactive-bindings.mjs +18 -0
- package/dist/analyze/static-graph.cjs +22 -4
- package/dist/analyze/static-graph.d.ts.map +1 -1
- package/dist/analyze/static-graph.js +6 -4
- package/dist/analyze/static-graph.mjs +22 -4
- package/dist/{babel-GI375YZ2.mjs → babel-RJFQVFJW.mjs} +4 -4
- package/dist/{chunk-QZ4CJPYP.mjs → chunk-DP2QDWWH.mjs} +1 -1
- package/dist/{chunk-DWNWN5RH.mjs → chunk-E2RWTIYE.mjs} +21 -15
- package/dist/{chunk-XJ5H2MXY.mjs → chunk-HCCBEJEZ.mjs} +31 -1
- package/dist/{chunk-VOUI6XPV.mjs → chunk-HIZU7WI2.mjs} +1 -1
- package/dist/{chunk-VC6X44FS.mjs → chunk-ZR2QHTEX.mjs} +505 -68
- package/dist/codegen/backends/imperative.cjs +24 -6
- package/dist/codegen/backends/imperative.d.ts.map +1 -1
- package/dist/codegen/backends/imperative.js +20 -4
- package/dist/codegen/backends/imperative.mjs +24 -6
- package/dist/frontend/babel/build-ir-lit.cjs +470 -63
- package/dist/frontend/babel/build-ir-lit.mjs +470 -63
- package/dist/frontend/babel/build-ir.cjs +470 -63
- package/dist/frontend/babel/build-ir.mjs +470 -63
- package/dist/frontend/babel/index.cjs +471 -64
- package/dist/frontend/babel/index.mjs +471 -64
- package/dist/frontend/babel/lower-template.cjs +470 -63
- package/dist/frontend/babel/lower-template.mjs +470 -63
- package/dist/frontend/babel/plugin.cjs +470 -63
- package/dist/frontend/babel/plugin.mjs +470 -63
- package/dist/index.cjs +360 -58
- package/dist/index.mjs +372 -58
- package/dist/integrations.cjs +1347 -98
- package/dist/integrations.d.ts.map +1 -1
- package/dist/integrations.js +44 -2
- package/dist/integrations.mjs +205 -19
- package/dist/lower/compile-template.cjs +354 -57
- package/dist/lower/compile-template.d.cts +13 -0
- package/dist/lower/compile-template.d.ts +13 -0
- package/dist/lower/compile-template.d.ts.map +1 -1
- package/dist/lower/compile-template.js +3 -0
- package/dist/lower/compile-template.mjs +366 -57
- package/dist/lower/entities.cjs +288 -0
- package/dist/lower/entities.d.cts +1 -0
- package/dist/lower/entities.d.ts +2 -0
- package/dist/lower/entities.d.ts.map +1 -0
- package/dist/lower/entities.js +54 -0
- package/dist/lower/entities.mjs +267 -0
- package/dist/lower/jsx.cjs +567 -7
- package/dist/lower/jsx.d.cts +8 -0
- package/dist/lower/jsx.d.ts +8 -0
- package/dist/lower/jsx.d.ts.map +1 -1
- package/dist/lower/jsx.js +205 -7
- package/dist/lower/jsx.mjs +567 -7
- package/dist/lower/template.cjs +332 -56
- package/dist/lower/template.d.ts.map +1 -1
- package/dist/lower/template.js +57 -49
- package/dist/lower/template.mjs +332 -56
- package/dist/resolve/builtins.cjs +1 -1
- package/dist/resolve/builtins.mjs +1 -1
- package/dist/resolve/component-globals.cjs +20 -1
- package/dist/resolve/component-globals.js +2 -2
- package/dist/resolve/component-globals.mjs +20 -1
- package/dist/resolve/write-globals.cjs +20 -1
- package/dist/resolve/write-globals.mjs +20 -1
- package/dist/{server-fns-BBZRZUPP.mjs → server-fns-JLSTKWPS.mjs} +4 -4
- package/dist/{server-functions-VEGLIFCE.mjs → server-functions-BGY3RD4R.mjs} +3 -3
- package/dist/transform/index.cjs +1123 -77
- package/dist/transform/index.mjs +1141 -91
- package/dist/transform/intrinsics.cjs +18 -0
- package/dist/transform/intrinsics.mjs +18 -0
- package/dist/transform/props.mjs +19 -14
- package/dist/transform/server-fns.mjs +19 -14
- package/dist/transform/source-locations.cjs +64 -3
- package/dist/transform/source-locations.d.cts +7 -2
- package/dist/transform/source-locations.d.ts +7 -2
- package/dist/transform/source-locations.d.ts.map +1 -1
- package/dist/transform/source-locations.js +68 -3
- package/dist/transform/source-locations.mjs +64 -3
- package/dist/transform/styles.cjs +588 -0
- package/dist/transform/styles.d.cts +211 -0
- package/dist/transform/styles.d.ts +212 -0
- package/dist/transform/styles.d.ts.map +1 -0
- package/dist/transform/styles.js +714 -0
- package/dist/transform/styles.mjs +653 -0
- package/dist/transform/templates.cjs +1122 -76
- package/dist/transform/templates.d.cts +13 -0
- package/dist/transform/templates.d.ts +13 -0
- package/dist/transform/templates.d.ts.map +1 -1
- package/dist/transform/templates.js +51 -14
- package/dist/transform/templates.mjs +1140 -90
- package/dist/{transform-UWZ7ZGJ2.mjs → transform-GBP6Y4UI.mjs} +603 -19
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/vite-styles.cjs +180 -0
- package/dist/vite-styles.d.cts +59 -0
- package/dist/vite-styles.d.ts +60 -0
- package/dist/vite-styles.d.ts.map +1 -0
- package/dist/vite-styles.js +198 -0
- package/dist/vite-styles.mjs +159 -0
- package/package.json +10 -3
package/dist/transform/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.94 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
|
|
3
3
|
// src/transform/templates.ts
|
|
4
4
|
import { parse as parse2 } from "@babel/parser";
|
|
5
5
|
|
|
6
|
-
// ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.
|
|
6
|
+
// ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.6.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
|
|
7
7
|
var comma = ",".charCodeAt(0);
|
|
8
8
|
var semicolon = ";".charCodeAt(0);
|
|
9
9
|
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
@@ -14,16 +14,16 @@ for (let i = 0; i < chars.length; i++) {
|
|
|
14
14
|
intToChar[i] = c;
|
|
15
15
|
charToInt[c] = i;
|
|
16
16
|
}
|
|
17
|
-
function encodeInteger(builder, num
|
|
18
|
-
let delta = num - relative;
|
|
19
|
-
delta = delta < 0 ? -delta << 1 | 1 : delta << 1;
|
|
17
|
+
function encodeInteger(builder, num) {
|
|
20
18
|
do {
|
|
21
|
-
let clamped =
|
|
22
|
-
|
|
23
|
-
if (
|
|
19
|
+
let clamped = num & 31;
|
|
20
|
+
num >>>= 5;
|
|
21
|
+
if (num > 0) clamped |= 32;
|
|
24
22
|
builder.write(intToChar[clamped]);
|
|
25
|
-
} while (
|
|
26
|
-
|
|
23
|
+
} while (num > 0);
|
|
24
|
+
}
|
|
25
|
+
function encodeSign(num) {
|
|
26
|
+
return num < 0 ? -num << 1 | 1 : num << 1;
|
|
27
27
|
}
|
|
28
28
|
var bufLength = 1024 * 16;
|
|
29
29
|
var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? {
|
|
@@ -73,13 +73,18 @@ function encode(decoded) {
|
|
|
73
73
|
for (let j = 0; j < line.length; j++) {
|
|
74
74
|
const segment = line[j];
|
|
75
75
|
if (j > 0) writer.write(comma);
|
|
76
|
-
|
|
76
|
+
encodeInteger(writer, encodeSign(segment[0] - genColumn));
|
|
77
|
+
genColumn = segment[0];
|
|
77
78
|
if (segment.length === 1) continue;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
encodeInteger(writer, encodeSign(segment[1] - sourcesIndex));
|
|
80
|
+
encodeInteger(writer, encodeSign(segment[2] - sourceLine));
|
|
81
|
+
encodeInteger(writer, encodeSign(segment[3] - sourceColumn));
|
|
82
|
+
sourcesIndex = segment[1];
|
|
83
|
+
sourceLine = segment[2];
|
|
84
|
+
sourceColumn = segment[3];
|
|
81
85
|
if (segment.length === 4) continue;
|
|
82
|
-
|
|
86
|
+
encodeInteger(writer, encodeSign(segment[4] - namesIndex));
|
|
87
|
+
namesIndex = segment[4];
|
|
83
88
|
}
|
|
84
89
|
}
|
|
85
90
|
return writer.flush();
|
|
@@ -1076,6 +1081,562 @@ var MagicString = class _MagicString {
|
|
|
1076
1081
|
}
|
|
1077
1082
|
};
|
|
1078
1083
|
|
|
1084
|
+
// src/transform/styles.ts
|
|
1085
|
+
var SCOPE_ATTR = "data-fx-s";
|
|
1086
|
+
var FUNCTIONS = /* @__PURE__ */ new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression", "ObjectMethod", "ClassMethod"]);
|
|
1087
|
+
function collectStyles(program, sourceName, options, tags = { html: /* @__PURE__ */ new Map([["html", "html"]]) }, module) {
|
|
1088
|
+
const plan = {
|
|
1089
|
+
scopes: [],
|
|
1090
|
+
templateOwners: /* @__PURE__ */ new Map(),
|
|
1091
|
+
drop: /* @__PURE__ */ new Set(),
|
|
1092
|
+
styles: [],
|
|
1093
|
+
diagnostics: [],
|
|
1094
|
+
edits: [],
|
|
1095
|
+
literals: [],
|
|
1096
|
+
references: [],
|
|
1097
|
+
shadowClasses: /* @__PURE__ */ new Map()
|
|
1098
|
+
};
|
|
1099
|
+
if (!options) return plan;
|
|
1100
|
+
const literalsOf = findLiterals(program, options.cssModules ?? ["@fluixi/core", "@fluixi/dom"], plan, tags.css ?? []);
|
|
1101
|
+
plan.names = literalsOf;
|
|
1102
|
+
const classOf = /* @__PURE__ */ new Map();
|
|
1103
|
+
const shadowOf = (owner) => {
|
|
1104
|
+
const cls = classOf.get(owner);
|
|
1105
|
+
return cls ? plan.shadowClasses.get(cls) : void 0;
|
|
1106
|
+
};
|
|
1107
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
1108
|
+
const piecesToNodes = (quasis, expressions, at, stack) => {
|
|
1109
|
+
const out = [];
|
|
1110
|
+
for (let i = 0; i < quasis.length; i++) {
|
|
1111
|
+
const text = quasis[i].value.cooked ?? quasis[i].value.raw;
|
|
1112
|
+
if (text.trim()) {
|
|
1113
|
+
try {
|
|
1114
|
+
const start = quasis[i].loc?.start;
|
|
1115
|
+
out.push(...options.process(text, sourceName).map((n2) => start ? shiftLoc(n2, sourceName, start) : n2));
|
|
1116
|
+
} catch (error) {
|
|
1117
|
+
plan.diagnostics.push({ ...at, message: `CSS could not be processed: ${error.message}` });
|
|
1118
|
+
return null;
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
const expr = expressions[i];
|
|
1122
|
+
if (!expr) continue;
|
|
1123
|
+
const value = expr.type === "Identifier" ? resolveLiteral(expr.name, at, stack) : void 0;
|
|
1124
|
+
if (value === void 0) {
|
|
1125
|
+
plan.diagnostics.push({
|
|
1126
|
+
...at,
|
|
1127
|
+
message: "Only css`` values can be interpolated into styles, and only by name: ${base}. Dynamic values go through custom properties (style:--x={...} and var(--x))."
|
|
1128
|
+
});
|
|
1129
|
+
return null;
|
|
1130
|
+
}
|
|
1131
|
+
if (value === null) return null;
|
|
1132
|
+
out.push(...value);
|
|
1133
|
+
}
|
|
1134
|
+
return out;
|
|
1135
|
+
};
|
|
1136
|
+
function resolveLiteral(name, at, stack) {
|
|
1137
|
+
const imported = literalsOf.imports.get(name);
|
|
1138
|
+
if (imported) {
|
|
1139
|
+
const nodes = options?.imported?.get(`${imported.source}#${imported.name}`);
|
|
1140
|
+
if (nodes) return nodes.map(dropLoc);
|
|
1141
|
+
plan.references.push({ name: imported.name, source: imported.source, ...at });
|
|
1142
|
+
plan.diagnostics.push({
|
|
1143
|
+
...at,
|
|
1144
|
+
message: options?.imported ? `${name} from ${imported.source} is not a css\`\` value the build could find.` : `${name} comes from ${imported.source}: style values from another module are resolved by the build.`
|
|
1145
|
+
});
|
|
1146
|
+
return null;
|
|
1147
|
+
}
|
|
1148
|
+
const literal = literalsOf.literals.get(name);
|
|
1149
|
+
if (!literal) return void 0;
|
|
1150
|
+
if (stack.includes(name)) {
|
|
1151
|
+
plan.diagnostics.push({ ...at, message: `css\`\` values include each other: ${[...stack, name].join(" → ")}.` });
|
|
1152
|
+
return null;
|
|
1153
|
+
}
|
|
1154
|
+
if (!resolved.has(name)) {
|
|
1155
|
+
resolved.set(name, piecesToNodes(literal.quasi.quasis, literal.quasi.expressions, at, [...stack, name]));
|
|
1156
|
+
}
|
|
1157
|
+
return resolved.get(name);
|
|
1158
|
+
}
|
|
1159
|
+
for (const [name, literal] of literalsOf.literals) {
|
|
1160
|
+
const at = { line: literal.loc?.start.line ?? 0, column: literal.loc?.start.column ?? 0 };
|
|
1161
|
+
const nodes = resolveLiteral(name, at, []);
|
|
1162
|
+
const id = hash(`${sourceName}:css:${name}`);
|
|
1163
|
+
plan.edits.push({ start: literal.start, end: literal.end, code: `({ $fxStyle: ${JSON.stringify(id)} })` });
|
|
1164
|
+
if (nodes) plan.literals.push({ id, name, css: printStyle(nodes, options.minify) });
|
|
1165
|
+
}
|
|
1166
|
+
const scopeOf = /* @__PURE__ */ new Map();
|
|
1167
|
+
const names = /* @__PURE__ */ new Map();
|
|
1168
|
+
const named = /* @__PURE__ */ new Map();
|
|
1169
|
+
const visit = (node, owners) => {
|
|
1170
|
+
if (!node || typeof node !== "object") return;
|
|
1171
|
+
if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.init && FUNCTIONS.has(node.init.type)) {
|
|
1172
|
+
named.set(node.init, node.id.name);
|
|
1173
|
+
}
|
|
1174
|
+
if ((node.type === "ClassDeclaration" || node.type === "ClassExpression") && node.id) {
|
|
1175
|
+
for (const member of node.body.body) if (member.type === "ClassMethod") named.set(member, node.id.name);
|
|
1176
|
+
}
|
|
1177
|
+
if (node.type === "ClassDeclaration" || node.type === "ClassExpression") {
|
|
1178
|
+
for (const member of node.body.body) if (member.type === "ClassMethod") classOf.set(member, node);
|
|
1179
|
+
const shadow = staticMember(node, "shadow");
|
|
1180
|
+
if (shadow?.value && !(shadow.value.type === "BooleanLiteral" && shadow.value.value === false)) {
|
|
1181
|
+
plan.shadowClasses.set(node, { node, styles: staticMember(node, "styles"), indexes: [] });
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
if (node.type === "TaggedTemplateExpression" && node.tag.type === "Identifier" && tags.html.get(node.tag.name) === "html") {
|
|
1185
|
+
const text = node.quasi.quasis.map((q) => q.value.raw).join("");
|
|
1186
|
+
if (/<style[\s>]/.test(text)) {
|
|
1187
|
+
const at = { line: node.loc?.start.line ?? 0, column: node.loc?.start.column ?? 0 };
|
|
1188
|
+
const owner = owners[0];
|
|
1189
|
+
if (!owner) plan.diagnostics.push({ ...at, message: "<style> has to be written inside a component." });
|
|
1190
|
+
else {
|
|
1191
|
+
const id = idFor(owner);
|
|
1192
|
+
const shadow = shadowOf(owner);
|
|
1193
|
+
plan.templateOwners.set(node.start, { id, component: functionName(owner, named) });
|
|
1194
|
+
for (const block of templateBlocks(node.quasi)) compileBlock(block, block.scoped, owner, at);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
const inner = FUNCTIONS.has(node.type) ? [...owners, node] : owners;
|
|
1199
|
+
if (node.type === "JSXElement" && isStyle(node)) {
|
|
1200
|
+
handle(node, owners);
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
for (const key of Object.keys(node)) {
|
|
1204
|
+
if (key === "loc" || key === "leadingComments" || key === "trailingComments" || key === "innerComments") continue;
|
|
1205
|
+
const value = node[key];
|
|
1206
|
+
if (Array.isArray(value)) for (const v of value) visit(v, inner);
|
|
1207
|
+
else if (value && typeof value === "object" && "type" in value) visit(value, inner);
|
|
1208
|
+
}
|
|
1209
|
+
};
|
|
1210
|
+
const handle = (node, owners) => {
|
|
1211
|
+
const at = { line: node.loc?.start.line ?? 0, column: node.loc?.start.column ?? 0 };
|
|
1212
|
+
const pieces = blockPieces(node);
|
|
1213
|
+
if (pieces === null) {
|
|
1214
|
+
plan.diagnostics.push({
|
|
1215
|
+
...at,
|
|
1216
|
+
message: "<style> needs its CSS as one template literal, <style>{`...`}</style>: JSX reads a bare `{` as an expression."
|
|
1217
|
+
});
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
const owner = owners[0];
|
|
1221
|
+
if (!owner) {
|
|
1222
|
+
plan.diagnostics.push({ ...at, message: "<style> has to be written inside a component." });
|
|
1223
|
+
return;
|
|
1224
|
+
}
|
|
1225
|
+
compileBlock(pieces, isScoped(node), owner, at);
|
|
1226
|
+
plan.drop.add(node.start);
|
|
1227
|
+
};
|
|
1228
|
+
const compileBlock = (pieces, scoped, owner, at) => {
|
|
1229
|
+
const component = functionName(owner, named);
|
|
1230
|
+
const id = idFor(owner);
|
|
1231
|
+
const processed = piecesToNodes(pieces.quasis, pieces.expressions, at, []);
|
|
1232
|
+
if (!processed) return;
|
|
1233
|
+
let nodes = processed;
|
|
1234
|
+
const shadow = shadowOf(owner);
|
|
1235
|
+
if (scoped && !shadow) {
|
|
1236
|
+
if (!plan.scopes.some((s) => s.value === id)) plan.scopes.push({ start: owner.start, end: owner.end, value: id });
|
|
1237
|
+
nodes = scopeNodes(nodes, id, (message) => plan.diagnostics.push({ ...at, message }));
|
|
1238
|
+
}
|
|
1239
|
+
const printed = module ? printStyleWithMap(nodes, options.minify, sourceName, module) : { css: printStyle(nodes, options.minify) };
|
|
1240
|
+
plan.styles.push({ id, scoped: scoped && !shadow, component, ...printed, ...shadow ? { shadow: true } : {}, ...at });
|
|
1241
|
+
if (shadow) shadow.indexes.push(plan.styles.length - 1);
|
|
1242
|
+
};
|
|
1243
|
+
function idFor(owner) {
|
|
1244
|
+
let id = scopeOf.get(owner);
|
|
1245
|
+
if (!id) {
|
|
1246
|
+
const component = functionName(owner, named);
|
|
1247
|
+
const seen = names.get(component) ?? 0;
|
|
1248
|
+
names.set(component, seen + 1);
|
|
1249
|
+
id = hash(`${sourceName}:${component}${seen ? ":" + seen : ""}`);
|
|
1250
|
+
scopeOf.set(owner, id);
|
|
1251
|
+
}
|
|
1252
|
+
return id;
|
|
1253
|
+
}
|
|
1254
|
+
visit(program, []);
|
|
1255
|
+
return plan;
|
|
1256
|
+
}
|
|
1257
|
+
function applyTemplateStyles(ir, t) {
|
|
1258
|
+
const walk8 = (node) => {
|
|
1259
|
+
const children = node.children;
|
|
1260
|
+
if (children) {
|
|
1261
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
1262
|
+
const child = children[i];
|
|
1263
|
+
if (child.kind === "element" && child.tag === "style" && t.owner) children.splice(i, 1);
|
|
1264
|
+
else walk8(child);
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
if (t.scope && node.kind === "element" && node.tag !== "style" && node.props && !node.props.some((p) => p.name === SCOPE_ATTR)) {
|
|
1268
|
+
node.props.unshift({ name: SCOPE_ATTR, kind: "attr", literal: t.scope });
|
|
1269
|
+
}
|
|
1270
|
+
};
|
|
1271
|
+
walk8(ir);
|
|
1272
|
+
}
|
|
1273
|
+
function staticMember(cls, name) {
|
|
1274
|
+
return cls.body.body.find(
|
|
1275
|
+
(m) => m.type === "ClassProperty" && m.static && (m.key.type === "Identifier" && m.key.name === name || m.key.type === "StringLiteral" && m.key.value === name)
|
|
1276
|
+
);
|
|
1277
|
+
}
|
|
1278
|
+
function finishShadowStyles(plan, code, moduleId) {
|
|
1279
|
+
const edits = [];
|
|
1280
|
+
const imports = [];
|
|
1281
|
+
let next = 0;
|
|
1282
|
+
const importOf = (specifier) => {
|
|
1283
|
+
const local = `__fxShadow${next++}`;
|
|
1284
|
+
imports.push(`import ${local} from ${JSON.stringify(specifier)};
|
|
1285
|
+
`);
|
|
1286
|
+
return local;
|
|
1287
|
+
};
|
|
1288
|
+
for (const shadow of plan.shadowClasses.values()) {
|
|
1289
|
+
const blocks = shadow.indexes.map((i) => importOf(`${moduleId}?fx-style&index=${i}&inline&lang.css`));
|
|
1290
|
+
let value;
|
|
1291
|
+
const prop = shadow.styles;
|
|
1292
|
+
if (prop?.value) {
|
|
1293
|
+
const start = prop.value.start;
|
|
1294
|
+
let text = code.slice(start, prop.value.end);
|
|
1295
|
+
const replacements = [];
|
|
1296
|
+
walkIdentifiers(prop.value, (id) => {
|
|
1297
|
+
const local = plan.names?.literals.has(id.name) ? importOf(`${moduleId}?fx-literal=${id.name}&inline&lang.css`) : plan.names?.imports.has(id.name) && !/\.css(\?|$)/.test(plan.names.imports.get(id.name).source) ? importOf(`${plan.names.imports.get(id.name).source}?fx-literal=${plan.names.imports.get(id.name).name}&inline&lang.css`) : void 0;
|
|
1298
|
+
if (local) replacements.push({ at: id.start - start, length: id.name.length, with: local });
|
|
1299
|
+
});
|
|
1300
|
+
for (const r of replacements.sort((a, b) => b.at - a.at)) text = text.slice(0, r.at) + r.with + text.slice(r.at + r.length);
|
|
1301
|
+
value = text;
|
|
1302
|
+
}
|
|
1303
|
+
if (!blocks.length && value === void 0) continue;
|
|
1304
|
+
if (prop?.value) {
|
|
1305
|
+
const merged = blocks.length ? `[${value}, ${blocks.join(", ")}]` : value;
|
|
1306
|
+
edits.push({ start: prop.value.start, end: prop.value.end, code: merged });
|
|
1307
|
+
} else if (blocks.length) {
|
|
1308
|
+
const open = shadow.node.body.start + 1;
|
|
1309
|
+
edits.push({ start: open, end: open, code: ` static styles = [${blocks.join(", ")}];` });
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
if (imports.length) edits.push({ start: 0, end: 0, code: imports.join("") });
|
|
1313
|
+
return edits;
|
|
1314
|
+
}
|
|
1315
|
+
function walkIdentifiers(node, visit) {
|
|
1316
|
+
if (!node || typeof node !== "object") return;
|
|
1317
|
+
if (node.type === "Identifier") return visit(node);
|
|
1318
|
+
if (node.type === "MemberExpression") return walkIdentifiers(node.object, visit);
|
|
1319
|
+
if (node.type === "ObjectProperty") return walkIdentifiers(node.value, visit);
|
|
1320
|
+
for (const key of Object.keys(node)) {
|
|
1321
|
+
if (key === "loc") continue;
|
|
1322
|
+
const value = node[key];
|
|
1323
|
+
if (Array.isArray(value)) for (const v of value) walkIdentifiers(v, visit);
|
|
1324
|
+
else if (value && typeof value === "object" && "type" in value) walkIdentifiers(value, visit);
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
function isStyle(node) {
|
|
1328
|
+
const name = node.openingElement.name;
|
|
1329
|
+
return name.type === "JSXIdentifier" && name.name === "style";
|
|
1330
|
+
}
|
|
1331
|
+
function isScoped(node) {
|
|
1332
|
+
return node.openingElement.attributes.some((a) => a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && a.name.name === "scoped");
|
|
1333
|
+
}
|
|
1334
|
+
function templateBlocks(quasi) {
|
|
1335
|
+
const blocks = [];
|
|
1336
|
+
let open = null;
|
|
1337
|
+
quasi.quasis.forEach((q, i) => {
|
|
1338
|
+
const raw = q.value.raw;
|
|
1339
|
+
let from = 0;
|
|
1340
|
+
while (from <= raw.length) {
|
|
1341
|
+
if (!open) {
|
|
1342
|
+
const tag = /<style\b([^>]*)>/g;
|
|
1343
|
+
tag.lastIndex = from;
|
|
1344
|
+
const m = tag.exec(raw);
|
|
1345
|
+
if (!m) break;
|
|
1346
|
+
open = { quasis: [], expressions: [], scoped: /\bscoped\b/.test(m[1]) };
|
|
1347
|
+
from = m.index + m[0].length;
|
|
1348
|
+
}
|
|
1349
|
+
const close = raw.indexOf("</style", from);
|
|
1350
|
+
open.quasis.push(slicePiece(q, raw, from, close === -1 ? raw.length : close));
|
|
1351
|
+
if (close === -1) break;
|
|
1352
|
+
blocks.push(open);
|
|
1353
|
+
open = null;
|
|
1354
|
+
from = close;
|
|
1355
|
+
}
|
|
1356
|
+
const expr = quasi.expressions[i];
|
|
1357
|
+
if (open && expr) open.expressions.push(expr);
|
|
1358
|
+
});
|
|
1359
|
+
return blocks;
|
|
1360
|
+
}
|
|
1361
|
+
function slicePiece(q, raw, from, to) {
|
|
1362
|
+
const text = raw.slice(from, to);
|
|
1363
|
+
const start = q.loc?.start;
|
|
1364
|
+
if (!start) return { type: "TemplateElement", value: { raw: text, cooked: text } };
|
|
1365
|
+
const before = raw.slice(0, from).split("\n");
|
|
1366
|
+
const line = start.line + before.length - 1;
|
|
1367
|
+
const column = before.length > 1 ? before[before.length - 1].length : start.column + from;
|
|
1368
|
+
return { type: "TemplateElement", value: { raw: text, cooked: text }, loc: { start: { line, column } } };
|
|
1369
|
+
}
|
|
1370
|
+
function blockPieces(node) {
|
|
1371
|
+
const meaningful = node.children.filter((c) => !(c.type === "JSXText" && !c.value.trim()));
|
|
1372
|
+
if (meaningful.length === 0) return { quasis: [], expressions: [] };
|
|
1373
|
+
if (meaningful.length !== 1) return null;
|
|
1374
|
+
const only = meaningful[0];
|
|
1375
|
+
if (only.type !== "JSXExpressionContainer") return null;
|
|
1376
|
+
const expr = only.expression;
|
|
1377
|
+
if (expr.type === "StringLiteral") return { quasis: [{ type: "TemplateElement", value: { raw: expr.value, cooked: expr.value } }], expressions: [] };
|
|
1378
|
+
if (expr.type === "TemplateLiteral") return { quasis: expr.quasis, expressions: expr.expressions };
|
|
1379
|
+
return null;
|
|
1380
|
+
}
|
|
1381
|
+
function findLiterals(program, modules, plan, intrinsic) {
|
|
1382
|
+
const literals = /* @__PURE__ */ new Map();
|
|
1383
|
+
const imports = /* @__PURE__ */ new Map();
|
|
1384
|
+
const tags = new Set(intrinsic);
|
|
1385
|
+
for (const statement of program.body ?? []) {
|
|
1386
|
+
if (statement.type !== "ImportDeclaration") continue;
|
|
1387
|
+
const source = statement.source.value;
|
|
1388
|
+
const specifiers = statement.specifiers;
|
|
1389
|
+
for (const sp of specifiers) {
|
|
1390
|
+
if (sp.type === "ImportSpecifier") imports.set(sp.local.name, { source, name: sp.imported.name ?? sp.imported.value });
|
|
1391
|
+
}
|
|
1392
|
+
if (!modules.includes(source)) continue;
|
|
1393
|
+
const css = specifiers.find((sp) => sp.type === "ImportSpecifier" && (sp.imported.name ?? sp.imported.value) === "css");
|
|
1394
|
+
if (!css) continue;
|
|
1395
|
+
const local = css.local.name;
|
|
1396
|
+
tags.add(local);
|
|
1397
|
+
imports.delete(local);
|
|
1398
|
+
plan.edits.push({ start: statement.start, end: statement.end, code: importWithout(statement, css) });
|
|
1399
|
+
}
|
|
1400
|
+
if (tags.size === 0) return { literals, imports };
|
|
1401
|
+
const visit = (node) => {
|
|
1402
|
+
if (!node || typeof node !== "object") return;
|
|
1403
|
+
if (node.type === "VariableDeclarator" && node.id.type === "Identifier" && node.init?.type === "TaggedTemplateExpression" && node.init.tag.type === "Identifier" && tags.has(node.init.tag.name)) {
|
|
1404
|
+
literals.set(node.id.name, node.init);
|
|
1405
|
+
}
|
|
1406
|
+
for (const key of Object.keys(node)) {
|
|
1407
|
+
if (key === "loc") continue;
|
|
1408
|
+
const value = node[key];
|
|
1409
|
+
if (Array.isArray(value)) for (const v of value) visit(v);
|
|
1410
|
+
else if (value && typeof value === "object" && "type" in value) visit(value);
|
|
1411
|
+
}
|
|
1412
|
+
};
|
|
1413
|
+
visit(program);
|
|
1414
|
+
return { literals, imports };
|
|
1415
|
+
}
|
|
1416
|
+
function importWithout(statement, removed) {
|
|
1417
|
+
const rest = statement.specifiers.filter((sp) => sp !== removed);
|
|
1418
|
+
const source = JSON.stringify(statement.source.value);
|
|
1419
|
+
if (rest.length === 0) return "";
|
|
1420
|
+
const def = rest.find((sp) => sp.type === "ImportDefaultSpecifier");
|
|
1421
|
+
const ns = rest.find((sp) => sp.type === "ImportNamespaceSpecifier");
|
|
1422
|
+
const named = rest.filter((sp) => sp.type === "ImportSpecifier").map((sp) => {
|
|
1423
|
+
const imported = sp.imported.name ?? JSON.stringify(sp.imported.value);
|
|
1424
|
+
return imported === sp.local.name ? imported : `${imported} as ${sp.local.name}`;
|
|
1425
|
+
});
|
|
1426
|
+
const parts = [def?.local.name, ns ? `* as ${ns.local.name}` : void 0, named.length ? `{ ${named.join(", ")} }` : void 0].filter(Boolean);
|
|
1427
|
+
return `import ${parts.join(", ")} from ${source};`;
|
|
1428
|
+
}
|
|
1429
|
+
function functionName(fn, named) {
|
|
1430
|
+
if ((fn.type === "FunctionDeclaration" || fn.type === "FunctionExpression") && fn.id) return fn.id.name;
|
|
1431
|
+
return named.get(fn) ?? "anonymous";
|
|
1432
|
+
}
|
|
1433
|
+
function hash(text) {
|
|
1434
|
+
let h = 2166136261;
|
|
1435
|
+
for (let i = 0; i < text.length; i++) {
|
|
1436
|
+
h ^= text.charCodeAt(i);
|
|
1437
|
+
h = Math.imul(h, 16777619);
|
|
1438
|
+
}
|
|
1439
|
+
return (h >>> 0).toString(36);
|
|
1440
|
+
}
|
|
1441
|
+
var OPAQUE = /(^|-)keyframes$|^font-face$|^property$|^counter-style$|^page$|^font-feature-values$/;
|
|
1442
|
+
function scopeNodes(nodes, id, warn = () => {
|
|
1443
|
+
}) {
|
|
1444
|
+
return nodes.map((node) => {
|
|
1445
|
+
if (node.kind === "rule") return { ...node, selector: scopeSelector(node.selector, id, warn) };
|
|
1446
|
+
if (node.kind === "at-rule" && !OPAQUE.test(node.name)) return { ...node, nodes: scopeNodes(node.nodes, id, warn) };
|
|
1447
|
+
return node;
|
|
1448
|
+
});
|
|
1449
|
+
}
|
|
1450
|
+
function scopeSelector(selector, id, warn = () => {
|
|
1451
|
+
}) {
|
|
1452
|
+
return splitTop(selector, ",").map((complex) => scopeComplex(complex.trim(), `[${SCOPE_ATTR}="${id}"]`, warn)).join(", ");
|
|
1453
|
+
}
|
|
1454
|
+
function scopeComplex(selector, attr, warn) {
|
|
1455
|
+
if (/:host\b|::slotted\(/.test(selector)) {
|
|
1456
|
+
warn(`\`${selector}\` only means something in a shadow root; in a light-DOM component it is left as written.`);
|
|
1457
|
+
return selector;
|
|
1458
|
+
}
|
|
1459
|
+
const parts = compounds(selector);
|
|
1460
|
+
const deep = parts.findIndex((p) => p.text.startsWith(":deep("));
|
|
1461
|
+
if (deep !== -1) {
|
|
1462
|
+
const inner = unwrap(parts[deep].text, ":deep(");
|
|
1463
|
+
const before = parts.slice(0, deep);
|
|
1464
|
+
if (before.length === 0) return `${attr} ${inner}`;
|
|
1465
|
+
const scopedBefore = scopeAt(before, before.length - 1, attr);
|
|
1466
|
+
return `${join(scopedBefore)} ${inner}`;
|
|
1467
|
+
}
|
|
1468
|
+
let target = -1;
|
|
1469
|
+
for (let i = parts.length - 1; i >= 0; i--) {
|
|
1470
|
+
if (!parts[i].text.startsWith(":global(")) {
|
|
1471
|
+
target = i;
|
|
1472
|
+
break;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
const out = target === -1 ? parts : scopeAt(parts, target, attr);
|
|
1476
|
+
return join(out.map((p) => p.text.startsWith(":global(") ? { ...p, text: unwrap(p.text, ":global(") } : p));
|
|
1477
|
+
}
|
|
1478
|
+
function scopeAt(parts, index, attr) {
|
|
1479
|
+
return parts.map((p, i) => i === index ? { ...p, text: insertAttr(p.text, attr) } : p);
|
|
1480
|
+
}
|
|
1481
|
+
function insertAttr(compound, attr) {
|
|
1482
|
+
let depth = 0;
|
|
1483
|
+
let quote = "";
|
|
1484
|
+
for (let i = 0; i < compound.length; i++) {
|
|
1485
|
+
const c = compound[i];
|
|
1486
|
+
if (quote) {
|
|
1487
|
+
if (c === "\\") i++;
|
|
1488
|
+
else if (c === quote) quote = "";
|
|
1489
|
+
continue;
|
|
1490
|
+
}
|
|
1491
|
+
if (c === "\\") {
|
|
1492
|
+
i++;
|
|
1493
|
+
continue;
|
|
1494
|
+
}
|
|
1495
|
+
if (c === '"' || c === "'") quote = c;
|
|
1496
|
+
else if (c === "(" || c === "[") depth++;
|
|
1497
|
+
else if (c === ")" || c === "]") depth--;
|
|
1498
|
+
else if (c === ":" && depth === 0 && i > 0) return compound.slice(0, i) + attr + compound.slice(i);
|
|
1499
|
+
}
|
|
1500
|
+
return compound + attr;
|
|
1501
|
+
}
|
|
1502
|
+
function compounds(selector) {
|
|
1503
|
+
const out = [];
|
|
1504
|
+
let depth = 0;
|
|
1505
|
+
let quote = "";
|
|
1506
|
+
let current = "";
|
|
1507
|
+
let combinator = "";
|
|
1508
|
+
const push = () => {
|
|
1509
|
+
if (current.trim()) out.push({ combinator: out.length ? combinator || " " : "", text: current.trim() });
|
|
1510
|
+
current = "";
|
|
1511
|
+
combinator = "";
|
|
1512
|
+
};
|
|
1513
|
+
for (let i = 0; i < selector.length; i++) {
|
|
1514
|
+
const c = selector[i];
|
|
1515
|
+
if (quote) {
|
|
1516
|
+
current += c;
|
|
1517
|
+
if (c === "\\") current += selector[++i] ?? "";
|
|
1518
|
+
else if (c === quote) quote = "";
|
|
1519
|
+
continue;
|
|
1520
|
+
}
|
|
1521
|
+
if (c === "\\") {
|
|
1522
|
+
current += c + (selector[++i] ?? "");
|
|
1523
|
+
continue;
|
|
1524
|
+
}
|
|
1525
|
+
if (c === '"' || c === "'") quote = c;
|
|
1526
|
+
if (c === "(" || c === "[") depth++;
|
|
1527
|
+
if (c === ")" || c === "]") depth--;
|
|
1528
|
+
if (depth === 0 && (c === ">" || c === "+" || c === "~")) {
|
|
1529
|
+
push();
|
|
1530
|
+
combinator = c;
|
|
1531
|
+
continue;
|
|
1532
|
+
}
|
|
1533
|
+
if (depth === 0 && /\s/.test(c)) {
|
|
1534
|
+
if (current.trim()) {
|
|
1535
|
+
const keep = combinator;
|
|
1536
|
+
push();
|
|
1537
|
+
combinator = keep;
|
|
1538
|
+
}
|
|
1539
|
+
continue;
|
|
1540
|
+
}
|
|
1541
|
+
current += c;
|
|
1542
|
+
}
|
|
1543
|
+
push();
|
|
1544
|
+
return out;
|
|
1545
|
+
}
|
|
1546
|
+
function join(parts) {
|
|
1547
|
+
return parts.map((p, i) => i === 0 ? p.text : p.combinator === " " ? ` ${p.text}` : ` ${p.combinator} ${p.text}`).join("");
|
|
1548
|
+
}
|
|
1549
|
+
function unwrap(text, prefix) {
|
|
1550
|
+
return text.slice(prefix.length, text.lastIndexOf(")")).trim() + text.slice(text.lastIndexOf(")") + 1);
|
|
1551
|
+
}
|
|
1552
|
+
function splitTop(selector, separator) {
|
|
1553
|
+
const parts = [];
|
|
1554
|
+
let depth = 0;
|
|
1555
|
+
let quote = "";
|
|
1556
|
+
let start = 0;
|
|
1557
|
+
for (let i = 0; i < selector.length; i++) {
|
|
1558
|
+
const c = selector[i];
|
|
1559
|
+
if (quote) {
|
|
1560
|
+
if (c === "\\") i++;
|
|
1561
|
+
else if (c === quote) quote = "";
|
|
1562
|
+
} else if (c === '"' || c === "'") quote = c;
|
|
1563
|
+
else if (c === "\\") i++;
|
|
1564
|
+
else if (c === "(" || c === "[") depth++;
|
|
1565
|
+
else if (c === ")" || c === "]") depth--;
|
|
1566
|
+
else if (c === separator && depth === 0) {
|
|
1567
|
+
parts.push(selector.slice(start, i));
|
|
1568
|
+
start = i + 1;
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
parts.push(selector.slice(start));
|
|
1572
|
+
return parts.filter((p) => p.trim());
|
|
1573
|
+
}
|
|
1574
|
+
function shiftLoc(node, source, start) {
|
|
1575
|
+
const loc = node.loc && node.loc.source === source ? { source, line: start.line + node.loc.line - 1, column: node.loc.line === 1 ? start.column + node.loc.column : node.loc.column } : node.loc;
|
|
1576
|
+
if (node.kind === "rule" || node.kind === "at-rule") return { ...node, loc, nodes: node.nodes.map((n2) => shiftLoc(n2, source, start)) };
|
|
1577
|
+
return { ...node, loc };
|
|
1578
|
+
}
|
|
1579
|
+
function dropLoc(node) {
|
|
1580
|
+
const { loc: _loc, ...rest } = node;
|
|
1581
|
+
if (rest.kind === "rule" || rest.kind === "at-rule") return { ...rest, nodes: rest.nodes.map(dropLoc) };
|
|
1582
|
+
return rest;
|
|
1583
|
+
}
|
|
1584
|
+
function printStyleWithMap(nodes, minify, sourceName, module) {
|
|
1585
|
+
const lines = [[]];
|
|
1586
|
+
let css = "";
|
|
1587
|
+
let column = 0;
|
|
1588
|
+
const emit = (text) => {
|
|
1589
|
+
for (const ch of text) {
|
|
1590
|
+
css += ch;
|
|
1591
|
+
if (ch === "\n") {
|
|
1592
|
+
lines.push([]);
|
|
1593
|
+
column = 0;
|
|
1594
|
+
} else column++;
|
|
1595
|
+
}
|
|
1596
|
+
};
|
|
1597
|
+
const mark = (loc) => {
|
|
1598
|
+
if (loc && loc.source === sourceName) lines[lines.length - 1].push([column, 0, loc.line - 1, loc.column]);
|
|
1599
|
+
};
|
|
1600
|
+
const write = (node, depth) => {
|
|
1601
|
+
const pad = minify ? "" : " ".repeat(depth);
|
|
1602
|
+
const nl = minify ? "" : "\n";
|
|
1603
|
+
const sp = minify ? "" : " ";
|
|
1604
|
+
emit(pad);
|
|
1605
|
+
mark(node.loc);
|
|
1606
|
+
if (node.kind === "declaration") {
|
|
1607
|
+
emit(`${node.property}:${sp}${node.value}${node.important ? `${sp}!important` : ""};${nl}`);
|
|
1608
|
+
} else if (node.kind === "raw") {
|
|
1609
|
+
emit(`${node.text}${nl}`);
|
|
1610
|
+
} else {
|
|
1611
|
+
emit(`${node.kind === "rule" ? node.selector : `@${node.name}${node.params ? " " + node.params : ""}`}${sp}{${nl}`);
|
|
1612
|
+
for (const child of node.nodes) write(child, depth + 1);
|
|
1613
|
+
emit(`${pad}}${nl}`);
|
|
1614
|
+
}
|
|
1615
|
+
};
|
|
1616
|
+
for (const node of nodes) write(node, 0);
|
|
1617
|
+
return { css, map: { version: 3, sources: [module.id], sourcesContent: [module.code], names: [], mappings: encode(lines) } };
|
|
1618
|
+
}
|
|
1619
|
+
function printStyle(nodes, minify = false) {
|
|
1620
|
+
const out = [];
|
|
1621
|
+
const write = (node, depth) => {
|
|
1622
|
+
const pad = minify ? "" : " ".repeat(depth);
|
|
1623
|
+
const nl = minify ? "" : "\n";
|
|
1624
|
+
const sp = minify ? "" : " ";
|
|
1625
|
+
if (node.kind === "declaration") {
|
|
1626
|
+
out.push(`${pad}${node.property}:${sp}${node.value}${node.important ? `${sp}!important` : ""};${nl}`);
|
|
1627
|
+
} else if (node.kind === "raw") {
|
|
1628
|
+
out.push(`${pad}${node.text}${nl}`);
|
|
1629
|
+
} else {
|
|
1630
|
+
const header = node.kind === "rule" ? node.selector : `@${node.name}${node.params ? " " + node.params : ""}`;
|
|
1631
|
+
out.push(`${pad}${header}${sp}{${nl}`);
|
|
1632
|
+
for (const child of node.nodes) write(child, depth + 1);
|
|
1633
|
+
out.push(`${pad}}${nl}`);
|
|
1634
|
+
}
|
|
1635
|
+
};
|
|
1636
|
+
for (const node of nodes) write(node, 0);
|
|
1637
|
+
return out.join("");
|
|
1638
|
+
}
|
|
1639
|
+
|
|
1079
1640
|
// src/optimize/analyze-static.ts
|
|
1080
1641
|
function propReason(prop) {
|
|
1081
1642
|
switch (prop.kind) {
|
|
@@ -1521,6 +2082,7 @@ var INTRINSICS = {
|
|
|
1521
2082
|
$effect: { export: "effect", module: REACTIVE_MODULE, returns: "effect" },
|
|
1522
2083
|
$store: { export: "store", module: "@fluixi/reactive/store", returns: "store-handle" },
|
|
1523
2084
|
$resource: { export: "resource", module: REACTIVE_MODULE, returns: "resource-handle" },
|
|
2085
|
+
$cachedResource: { export: "cachedResource", module: "@fluixi/reactive/cached-resource", returns: "resource-handle" },
|
|
1524
2086
|
// No short runtime form for these yet, so the intrinsic stands for the `create*`
|
|
1525
2087
|
// name. Still worth having: no import to write, and when a shorter form is
|
|
1526
2088
|
// designed, the change is this line rather than a compiler pass.
|
|
@@ -1531,6 +2093,19 @@ var INTRINSICS = {
|
|
|
1531
2093
|
// dependency analysis must not guess at.
|
|
1532
2094
|
$untrack: { export: "untrack", module: REACTIVE_MODULE, returns: "plain" },
|
|
1533
2095
|
$untrackStore: { export: "untrackStore", module: "@fluixi/reactive/store", returns: "plain" },
|
|
2096
|
+
// Scopes, scheduling and lifecycle: no value to classify, but the same authoring promise,
|
|
2097
|
+
// no import to write. `$cleanup` registers a callback on the current owner (`onCleanup`).
|
|
2098
|
+
$batch: { export: "batch", module: REACTIVE_MODULE, returns: "plain" },
|
|
2099
|
+
$cleanup: { export: "onCleanup", module: REACTIVE_MODULE, returns: "plain" },
|
|
2100
|
+
$root: { export: "root", module: REACTIVE_MODULE, returns: "plain" },
|
|
2101
|
+
$context: { export: "context", module: REACTIVE_MODULE, returns: "plain" },
|
|
2102
|
+
$renderEffect: { export: "renderEffect", module: REACTIVE_MODULE, returns: "effect" },
|
|
2103
|
+
$computed: { export: "computed", module: REACTIVE_MODULE, returns: "effect" },
|
|
2104
|
+
// Storage for where the code runs, and a signal kept in it. `$persisted` is a signal
|
|
2105
|
+
// handle as far as reads go: the same accessor with `set` on it.
|
|
2106
|
+
$storage: { export: "useStorage", module: "@fluixi/core/storage", returns: "plain" },
|
|
2107
|
+
$asyncStorage: { export: "useAsyncStorage", module: "@fluixi/core/storage", returns: "plain" },
|
|
2108
|
+
$persisted: { export: "persisted", module: "@fluixi/core/storage", returns: "signal-handle" },
|
|
1534
2109
|
// An environment variable, public or server-only; the browser build refuses a secret.
|
|
1535
2110
|
$env: { export: "env", module: "@fluixi/start/env", returns: "plain" }
|
|
1536
2111
|
};
|
|
@@ -1543,8 +2118,11 @@ var RUNTIME_PRIMITIVES = {
|
|
|
1543
2118
|
createMemo: "memo-accessor",
|
|
1544
2119
|
createEffect: "effect",
|
|
1545
2120
|
createRenderEffect: "effect",
|
|
2121
|
+
renderEffect: "effect",
|
|
2122
|
+
computed: "effect",
|
|
1546
2123
|
createStore: "reactive-object",
|
|
1547
2124
|
resource: "resource-handle",
|
|
2125
|
+
cachedResource: "resource-handle",
|
|
1548
2126
|
createResource: "reactive-object",
|
|
1549
2127
|
createSelector: "memo-accessor",
|
|
1550
2128
|
createDeferred: "memo-accessor"
|
|
@@ -1553,8 +2131,19 @@ var PRIMITIVE_MODULES = [
|
|
|
1553
2131
|
"@fluixi/reactive",
|
|
1554
2132
|
"@fluixi/reactive/signal",
|
|
1555
2133
|
"@fluixi/reactive/store",
|
|
2134
|
+
"@fluixi/reactive/cached-resource",
|
|
1556
2135
|
"@fluixi/core"
|
|
1557
2136
|
];
|
|
2137
|
+
var TAG_INTRINSICS = {
|
|
2138
|
+
$html: { export: "html", module: "@fluixi/core" },
|
|
2139
|
+
$svg: { export: "svg", module: "@fluixi/core" },
|
|
2140
|
+
$css: { export: "css", module: "@fluixi/core" }
|
|
2141
|
+
};
|
|
2142
|
+
function tagIntrinsics(bound) {
|
|
2143
|
+
const tags = /* @__PURE__ */ new Map();
|
|
2144
|
+
for (const [name, tag] of Object.entries(TAG_INTRINSICS)) if (!bound.has(name)) tags.set(name, tag.export);
|
|
2145
|
+
return tags;
|
|
2146
|
+
}
|
|
1558
2147
|
var INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n2) => n2.slice(1)).join("|")})\\s*\\(`);
|
|
1559
2148
|
function mayHaveIntrinsic(code) {
|
|
1560
2149
|
return INTRINSIC_CALL.test(code);
|
|
@@ -1688,6 +2277,7 @@ function resolveReactiveBindings(program) {
|
|
|
1688
2277
|
// src/transform/source-locations.ts
|
|
1689
2278
|
var SOURCE_MARKER = "__fx_source";
|
|
1690
2279
|
var COMPONENT_MARKER = "__fx_component";
|
|
2280
|
+
var CLASS_MARKER = "__fx_class";
|
|
1691
2281
|
var HOLE_MARKER = "__fx_hole";
|
|
1692
2282
|
var markHole = (accessor, line, column, name) => `(globalThis.${HOLE_MARKER} ?? ((f) => f))(${accessor},${line},${column}${name === void 0 ? "" : `,${JSON.stringify(name)}`})`;
|
|
1693
2283
|
var PROPS_MARKER = "__fx_props";
|
|
@@ -1705,11 +2295,12 @@ var RUNTIME_PRIMITIVES2 = /* @__PURE__ */ new Set([
|
|
|
1705
2295
|
"createStore",
|
|
1706
2296
|
"createResource"
|
|
1707
2297
|
]);
|
|
1708
|
-
function
|
|
2298
|
+
function mayHaveSourceMarks(code) {
|
|
1709
2299
|
for (const name of RUNTIME_PRIMITIVES2) {
|
|
1710
2300
|
if (code.includes(name)) return true;
|
|
1711
2301
|
}
|
|
1712
|
-
|
|
2302
|
+
if (code.includes("$signal") || code.includes("$memo") || code.includes("$effect") || code.includes("$store")) return true;
|
|
2303
|
+
return /\bclass\b[^{;]*\bextends\b/.test(code);
|
|
1713
2304
|
}
|
|
1714
2305
|
var SINGLE_STATEMENT_PARENTS = /* @__PURE__ */ new Set([
|
|
1715
2306
|
"IfStatement",
|
|
@@ -1728,6 +2319,7 @@ function isLoneBranch(statement, parent) {
|
|
|
1728
2319
|
function isExport(node) {
|
|
1729
2320
|
return node.type === "ExportNamedDeclaration" || node.type === "ExportDefaultDeclaration";
|
|
1730
2321
|
}
|
|
2322
|
+
var CLASS_FIELDS = /* @__PURE__ */ new Set(["PropertyDefinition", "ClassProperty", "ClassPrivateProperty", "AccessorProperty"]);
|
|
1731
2323
|
function isStatement(node) {
|
|
1732
2324
|
return node.type.endsWith("Statement") || node.type === "VariableDeclaration";
|
|
1733
2325
|
}
|
|
@@ -1748,6 +2340,14 @@ function walk3(node, visit, stack = []) {
|
|
|
1748
2340
|
}
|
|
1749
2341
|
function nameFor(stack) {
|
|
1750
2342
|
const declarator = stack[stack.length - 1];
|
|
2343
|
+
if (declarator && CLASS_FIELDS.has(declarator.type)) {
|
|
2344
|
+
const key = declarator.key;
|
|
2345
|
+
if (key?.type === "Identifier" || key?.type === "PrivateIdentifier" || key?.type === "PrivateName") {
|
|
2346
|
+
const name = key.name ?? key.id?.name;
|
|
2347
|
+
return name;
|
|
2348
|
+
}
|
|
2349
|
+
return void 0;
|
|
2350
|
+
}
|
|
1751
2351
|
if (declarator?.type !== "VariableDeclarator") return void 0;
|
|
1752
2352
|
const id = declarator.id;
|
|
1753
2353
|
if (id?.type === "Identifier") return id.name;
|
|
@@ -1796,6 +2396,17 @@ function collectSourceEdits(program, filename) {
|
|
|
1796
2396
|
});
|
|
1797
2397
|
}
|
|
1798
2398
|
}
|
|
2399
|
+
if ((node.type === "ClassDeclaration" || node.type === "ClassExpression") && node.superClass && !node.declare) {
|
|
2400
|
+
const at = node.loc?.start;
|
|
2401
|
+
const body = node.body;
|
|
2402
|
+
if (at && body) {
|
|
2403
|
+
edits.push({
|
|
2404
|
+
start: body.start + 1,
|
|
2405
|
+
end: body.start + 1,
|
|
2406
|
+
code: `static{globalThis.${CLASS_MARKER}?.(this,${JSON.stringify(filename)},${at.line},${at.column});}`
|
|
2407
|
+
});
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
1799
2410
|
if (node.type !== "CallExpression") return;
|
|
1800
2411
|
const callee = node.callee;
|
|
1801
2412
|
if (callee?.type !== "Identifier") return;
|
|
@@ -1805,6 +2416,26 @@ function collectSourceEdits(program, filename) {
|
|
|
1805
2416
|
if (!intrinsic && !imported) return;
|
|
1806
2417
|
const position = node.loc?.start;
|
|
1807
2418
|
if (!position) return;
|
|
2419
|
+
for (let i = stack.length - 1; i >= 0; i--) {
|
|
2420
|
+
const up = stack[i];
|
|
2421
|
+
if (isStatement(up)) break;
|
|
2422
|
+
if (CLASS_FIELDS.has(up.type)) {
|
|
2423
|
+
if (claimed.has(node.start)) return;
|
|
2424
|
+
claimed.add(node.start);
|
|
2425
|
+
const label2 = nameFor(stack);
|
|
2426
|
+
const own = !up.static;
|
|
2427
|
+
const args2 = [
|
|
2428
|
+
JSON.stringify(filename),
|
|
2429
|
+
String(position.line),
|
|
2430
|
+
String(position.column),
|
|
2431
|
+
label2 ? JSON.stringify(label2) : own ? "undefined" : void 0,
|
|
2432
|
+
own ? "this" : void 0
|
|
2433
|
+
].filter((a) => a !== void 0).join(",");
|
|
2434
|
+
edits.push({ start: node.start, end: node.start, code: `(globalThis.${SOURCE_MARKER}?.(${args2}),` });
|
|
2435
|
+
edits.push({ start: node.end, end: node.end, code: ")" });
|
|
2436
|
+
return;
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
1808
2439
|
let statement;
|
|
1809
2440
|
let parent;
|
|
1810
2441
|
let index = -1;
|
|
@@ -2010,13 +2641,16 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
2010
2641
|
used.add("createComponent");
|
|
2011
2642
|
const spreads = props.filter((p) => p.kind === "spread");
|
|
2012
2643
|
const normal = props.filter((p) => p.kind !== "spread");
|
|
2013
|
-
const
|
|
2014
|
-
(p) => `get ${propKey(p.name)}() { return ${componentPropValue(p)}; }`
|
|
2015
|
-
);
|
|
2644
|
+
const bodies = normal.map((p) => [p.name, componentPropValue(p)]);
|
|
2016
2645
|
if (children.length > 0) {
|
|
2017
|
-
|
|
2646
|
+
bodies.push(["children", emitChildren(children, used, templates)]);
|
|
2647
|
+
}
|
|
2648
|
+
let obj = `{ ${bodies.map(([name2, body]) => `get ${propKey(name2)}() { return ${body}; }`).join(", ")} }`;
|
|
2649
|
+
if (bodies.some(([, body]) => /\bthis\b/.test(body))) {
|
|
2650
|
+
const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => (${body})`);
|
|
2651
|
+
const getters = bodies.map(([name2]) => `get ${propKey(name2)}() { return _$t[${JSON.stringify(name2)}](); }`);
|
|
2652
|
+
obj = `((_$t) => ({ ${getters.join(", ")} }))({ ${thunks.join(", ")} })`;
|
|
2018
2653
|
}
|
|
2019
|
-
let obj = `{ ${entries.join(", ")} }`;
|
|
2020
2654
|
if (spreads.length > 0) {
|
|
2021
2655
|
used.add("mergeProps");
|
|
2022
2656
|
obj = `mergeProps(${spreads.map((s) => s.expr).join(", ")}, ${obj})`;
|
|
@@ -2098,7 +2732,8 @@ function emitNode(node, used, templates) {
|
|
|
2098
2732
|
} else {
|
|
2099
2733
|
used.add("spread");
|
|
2100
2734
|
const svgFlag = node.svg ? ", isSVG: true" : "";
|
|
2101
|
-
const
|
|
2735
|
+
const accessors = node.props.filter((p) => p.kind !== "spread" && p.expr !== void 0 && p.reactive && p.name !== "ref").map((p) => p.name);
|
|
2736
|
+
const customFlag = node.tag.includes("-") ? `, isCustomElement: true, accessors: ${JSON.stringify(accessors)}` : "";
|
|
2102
2737
|
parts.push(
|
|
2103
2738
|
`spread({ element: ${el}, props: ${emitProps(node.props, null, used)}${svgFlag}${customFlag} });`
|
|
2104
2739
|
);
|
|
@@ -2213,6 +2848,271 @@ function cleanTemplateText(value) {
|
|
|
2213
2848
|
return out;
|
|
2214
2849
|
}
|
|
2215
2850
|
|
|
2851
|
+
// src/lower/entities.ts
|
|
2852
|
+
var NAMED = {
|
|
2853
|
+
quot: 34,
|
|
2854
|
+
amp: 38,
|
|
2855
|
+
apos: 39,
|
|
2856
|
+
lt: 60,
|
|
2857
|
+
gt: 62,
|
|
2858
|
+
nbsp: 160,
|
|
2859
|
+
iexcl: 161,
|
|
2860
|
+
cent: 162,
|
|
2861
|
+
pound: 163,
|
|
2862
|
+
curren: 164,
|
|
2863
|
+
yen: 165,
|
|
2864
|
+
brvbar: 166,
|
|
2865
|
+
sect: 167,
|
|
2866
|
+
uml: 168,
|
|
2867
|
+
copy: 169,
|
|
2868
|
+
ordf: 170,
|
|
2869
|
+
laquo: 171,
|
|
2870
|
+
not: 172,
|
|
2871
|
+
shy: 173,
|
|
2872
|
+
reg: 174,
|
|
2873
|
+
macr: 175,
|
|
2874
|
+
deg: 176,
|
|
2875
|
+
plusmn: 177,
|
|
2876
|
+
sup2: 178,
|
|
2877
|
+
sup3: 179,
|
|
2878
|
+
acute: 180,
|
|
2879
|
+
micro: 181,
|
|
2880
|
+
para: 182,
|
|
2881
|
+
middot: 183,
|
|
2882
|
+
cedil: 184,
|
|
2883
|
+
sup1: 185,
|
|
2884
|
+
ordm: 186,
|
|
2885
|
+
raquo: 187,
|
|
2886
|
+
frac14: 188,
|
|
2887
|
+
frac12: 189,
|
|
2888
|
+
frac34: 190,
|
|
2889
|
+
iquest: 191,
|
|
2890
|
+
Agrave: 192,
|
|
2891
|
+
Aacute: 193,
|
|
2892
|
+
Acirc: 194,
|
|
2893
|
+
Atilde: 195,
|
|
2894
|
+
Auml: 196,
|
|
2895
|
+
Aring: 197,
|
|
2896
|
+
AElig: 198,
|
|
2897
|
+
Ccedil: 199,
|
|
2898
|
+
Egrave: 200,
|
|
2899
|
+
Eacute: 201,
|
|
2900
|
+
Ecirc: 202,
|
|
2901
|
+
Euml: 203,
|
|
2902
|
+
Igrave: 204,
|
|
2903
|
+
Iacute: 205,
|
|
2904
|
+
Icirc: 206,
|
|
2905
|
+
Iuml: 207,
|
|
2906
|
+
ETH: 208,
|
|
2907
|
+
Ntilde: 209,
|
|
2908
|
+
Ograve: 210,
|
|
2909
|
+
Oacute: 211,
|
|
2910
|
+
Ocirc: 212,
|
|
2911
|
+
Otilde: 213,
|
|
2912
|
+
Ouml: 214,
|
|
2913
|
+
times: 215,
|
|
2914
|
+
Oslash: 216,
|
|
2915
|
+
Ugrave: 217,
|
|
2916
|
+
Uacute: 218,
|
|
2917
|
+
Ucirc: 219,
|
|
2918
|
+
Uuml: 220,
|
|
2919
|
+
Yacute: 221,
|
|
2920
|
+
THORN: 222,
|
|
2921
|
+
szlig: 223,
|
|
2922
|
+
agrave: 224,
|
|
2923
|
+
aacute: 225,
|
|
2924
|
+
acirc: 226,
|
|
2925
|
+
atilde: 227,
|
|
2926
|
+
auml: 228,
|
|
2927
|
+
aring: 229,
|
|
2928
|
+
aelig: 230,
|
|
2929
|
+
ccedil: 231,
|
|
2930
|
+
egrave: 232,
|
|
2931
|
+
eacute: 233,
|
|
2932
|
+
ecirc: 234,
|
|
2933
|
+
euml: 235,
|
|
2934
|
+
igrave: 236,
|
|
2935
|
+
iacute: 237,
|
|
2936
|
+
icirc: 238,
|
|
2937
|
+
iuml: 239,
|
|
2938
|
+
eth: 240,
|
|
2939
|
+
ntilde: 241,
|
|
2940
|
+
ograve: 242,
|
|
2941
|
+
oacute: 243,
|
|
2942
|
+
ocirc: 244,
|
|
2943
|
+
otilde: 245,
|
|
2944
|
+
ouml: 246,
|
|
2945
|
+
divide: 247,
|
|
2946
|
+
oslash: 248,
|
|
2947
|
+
ugrave: 249,
|
|
2948
|
+
uacute: 250,
|
|
2949
|
+
ucirc: 251,
|
|
2950
|
+
uuml: 252,
|
|
2951
|
+
yacute: 253,
|
|
2952
|
+
thorn: 254,
|
|
2953
|
+
yuml: 255,
|
|
2954
|
+
OElig: 338,
|
|
2955
|
+
oelig: 339,
|
|
2956
|
+
Scaron: 352,
|
|
2957
|
+
scaron: 353,
|
|
2958
|
+
Yuml: 376,
|
|
2959
|
+
fnof: 402,
|
|
2960
|
+
circ: 710,
|
|
2961
|
+
tilde: 732,
|
|
2962
|
+
Alpha: 913,
|
|
2963
|
+
Beta: 914,
|
|
2964
|
+
Gamma: 915,
|
|
2965
|
+
Delta: 916,
|
|
2966
|
+
Epsilon: 917,
|
|
2967
|
+
Zeta: 918,
|
|
2968
|
+
Eta: 919,
|
|
2969
|
+
Theta: 920,
|
|
2970
|
+
Iota: 921,
|
|
2971
|
+
Kappa: 922,
|
|
2972
|
+
Lambda: 923,
|
|
2973
|
+
Mu: 924,
|
|
2974
|
+
Nu: 925,
|
|
2975
|
+
Xi: 926,
|
|
2976
|
+
Omicron: 927,
|
|
2977
|
+
Pi: 928,
|
|
2978
|
+
Rho: 929,
|
|
2979
|
+
Sigma: 931,
|
|
2980
|
+
Tau: 932,
|
|
2981
|
+
Upsilon: 933,
|
|
2982
|
+
Phi: 934,
|
|
2983
|
+
Chi: 935,
|
|
2984
|
+
Psi: 936,
|
|
2985
|
+
Omega: 937,
|
|
2986
|
+
alpha: 945,
|
|
2987
|
+
beta: 946,
|
|
2988
|
+
gamma: 947,
|
|
2989
|
+
delta: 948,
|
|
2990
|
+
epsilon: 949,
|
|
2991
|
+
zeta: 950,
|
|
2992
|
+
eta: 951,
|
|
2993
|
+
theta: 952,
|
|
2994
|
+
iota: 953,
|
|
2995
|
+
kappa: 954,
|
|
2996
|
+
lambda: 955,
|
|
2997
|
+
mu: 956,
|
|
2998
|
+
nu: 957,
|
|
2999
|
+
xi: 958,
|
|
3000
|
+
omicron: 959,
|
|
3001
|
+
pi: 960,
|
|
3002
|
+
rho: 961,
|
|
3003
|
+
sigmaf: 962,
|
|
3004
|
+
sigma: 963,
|
|
3005
|
+
tau: 964,
|
|
3006
|
+
upsilon: 965,
|
|
3007
|
+
phi: 966,
|
|
3008
|
+
chi: 967,
|
|
3009
|
+
psi: 968,
|
|
3010
|
+
omega: 969,
|
|
3011
|
+
thetasym: 977,
|
|
3012
|
+
upsih: 978,
|
|
3013
|
+
piv: 982,
|
|
3014
|
+
ensp: 8194,
|
|
3015
|
+
emsp: 8195,
|
|
3016
|
+
thinsp: 8201,
|
|
3017
|
+
zwnj: 8204,
|
|
3018
|
+
zwj: 8205,
|
|
3019
|
+
lrm: 8206,
|
|
3020
|
+
rlm: 8207,
|
|
3021
|
+
ndash: 8211,
|
|
3022
|
+
mdash: 8212,
|
|
3023
|
+
lsquo: 8216,
|
|
3024
|
+
rsquo: 8217,
|
|
3025
|
+
sbquo: 8218,
|
|
3026
|
+
ldquo: 8220,
|
|
3027
|
+
rdquo: 8221,
|
|
3028
|
+
bdquo: 8222,
|
|
3029
|
+
dagger: 8224,
|
|
3030
|
+
Dagger: 8225,
|
|
3031
|
+
bull: 8226,
|
|
3032
|
+
hellip: 8230,
|
|
3033
|
+
permil: 8240,
|
|
3034
|
+
prime: 8242,
|
|
3035
|
+
Prime: 8243,
|
|
3036
|
+
lsaquo: 8249,
|
|
3037
|
+
rsaquo: 8250,
|
|
3038
|
+
oline: 8254,
|
|
3039
|
+
frasl: 8260,
|
|
3040
|
+
euro: 8364,
|
|
3041
|
+
image: 8465,
|
|
3042
|
+
weierp: 8472,
|
|
3043
|
+
real: 8476,
|
|
3044
|
+
trade: 8482,
|
|
3045
|
+
alefsym: 8501,
|
|
3046
|
+
larr: 8592,
|
|
3047
|
+
uarr: 8593,
|
|
3048
|
+
rarr: 8594,
|
|
3049
|
+
darr: 8595,
|
|
3050
|
+
harr: 8596,
|
|
3051
|
+
crarr: 8629,
|
|
3052
|
+
lArr: 8656,
|
|
3053
|
+
uArr: 8657,
|
|
3054
|
+
rArr: 8658,
|
|
3055
|
+
dArr: 8659,
|
|
3056
|
+
hArr: 8660,
|
|
3057
|
+
forall: 8704,
|
|
3058
|
+
part: 8706,
|
|
3059
|
+
exist: 8707,
|
|
3060
|
+
empty: 8709,
|
|
3061
|
+
nabla: 8711,
|
|
3062
|
+
isin: 8712,
|
|
3063
|
+
notin: 8713,
|
|
3064
|
+
ni: 8715,
|
|
3065
|
+
prod: 8719,
|
|
3066
|
+
sum: 8721,
|
|
3067
|
+
minus: 8722,
|
|
3068
|
+
lowast: 8727,
|
|
3069
|
+
radic: 8730,
|
|
3070
|
+
prop: 8733,
|
|
3071
|
+
infin: 8734,
|
|
3072
|
+
ang: 8736,
|
|
3073
|
+
and: 8743,
|
|
3074
|
+
or: 8744,
|
|
3075
|
+
cap: 8745,
|
|
3076
|
+
cup: 8746,
|
|
3077
|
+
int: 8747,
|
|
3078
|
+
there4: 8756,
|
|
3079
|
+
sim: 8764,
|
|
3080
|
+
cong: 8773,
|
|
3081
|
+
asymp: 8776,
|
|
3082
|
+
ne: 8800,
|
|
3083
|
+
equiv: 8801,
|
|
3084
|
+
le: 8804,
|
|
3085
|
+
ge: 8805,
|
|
3086
|
+
sub: 8834,
|
|
3087
|
+
sup: 8835,
|
|
3088
|
+
nsub: 8836,
|
|
3089
|
+
sube: 8838,
|
|
3090
|
+
supe: 8839,
|
|
3091
|
+
oplus: 8853,
|
|
3092
|
+
otimes: 8855,
|
|
3093
|
+
perp: 8869,
|
|
3094
|
+
sdot: 8901,
|
|
3095
|
+
lceil: 8968,
|
|
3096
|
+
rceil: 8969,
|
|
3097
|
+
lfloor: 8970,
|
|
3098
|
+
rfloor: 8971,
|
|
3099
|
+
lang: 9001,
|
|
3100
|
+
rang: 9002,
|
|
3101
|
+
loz: 9674,
|
|
3102
|
+
spades: 9824,
|
|
3103
|
+
clubs: 9827,
|
|
3104
|
+
hearts: 9829,
|
|
3105
|
+
diams: 9830
|
|
3106
|
+
};
|
|
3107
|
+
var REFERENCE = /&(?:#[xX]([0-9a-fA-F]{1,6})|#([0-9]{1,7})|([a-zA-Z][a-zA-Z0-9]{1,31}));/g;
|
|
3108
|
+
function decodeEntities(value) {
|
|
3109
|
+
if (!value.includes("&")) return value;
|
|
3110
|
+
return value.replace(REFERENCE, (match, hex, dec, name) => {
|
|
3111
|
+
const code = hex ? parseInt(hex, 16) : dec ? parseInt(dec, 10) : Object.prototype.hasOwnProperty.call(NAMED, name) ? NAMED[name] : void 0;
|
|
3112
|
+
return code !== void 0 && code <= 1114111 ? String.fromCodePoint(code) : match;
|
|
3113
|
+
});
|
|
3114
|
+
}
|
|
3115
|
+
|
|
2216
3116
|
// src/lower/template.ts
|
|
2217
3117
|
var DELEGATED = /* @__PURE__ */ new Set([
|
|
2218
3118
|
"click",
|
|
@@ -2231,6 +3131,7 @@ var DELEGATED = /* @__PURE__ */ new Set([
|
|
|
2231
3131
|
function escapeTemplate(s) {
|
|
2232
3132
|
return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
|
|
2233
3133
|
}
|
|
3134
|
+
var CONTAINER = "container";
|
|
2234
3135
|
function capitalize(s) {
|
|
2235
3136
|
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
2236
3137
|
}
|
|
@@ -2285,10 +3186,6 @@ var Lowerer = class {
|
|
|
2285
3186
|
if (hasElse) i = elseIdx;
|
|
2286
3187
|
continue;
|
|
2287
3188
|
}
|
|
2288
|
-
if (child.attributes.some((a) => a.kind === "EachDirective")) {
|
|
2289
|
-
out.push(this.lowerEach(child));
|
|
2290
|
-
continue;
|
|
2291
|
-
}
|
|
2292
3189
|
}
|
|
2293
3190
|
const node = this.lowerNode(child);
|
|
2294
3191
|
if (node) out.push(node);
|
|
@@ -2302,7 +3199,7 @@ var Lowerer = class {
|
|
|
2302
3199
|
switch (node.kind) {
|
|
2303
3200
|
case "Text": {
|
|
2304
3201
|
if (node.raw) return { kind: "text", value: node.value };
|
|
2305
|
-
const cleaned = cleanTemplateText(node.value);
|
|
3202
|
+
const cleaned = decodeEntities(cleanTemplateText(node.value));
|
|
2306
3203
|
return cleaned ? { kind: "text", value: cleaned } : null;
|
|
2307
3204
|
}
|
|
2308
3205
|
case "Comment":
|
|
@@ -2330,13 +3227,16 @@ var Lowerer = class {
|
|
|
2330
3227
|
node.props.unshift({ name: "component", kind: "attr", expr: `() => ${paren(this.hole(isAttr.value.hole).code, "arrowBody")}` });
|
|
2331
3228
|
return node;
|
|
2332
3229
|
}
|
|
3230
|
+
const each = this.lowerEach(el);
|
|
3231
|
+
const children = each ? [each] : this.lowerChildren(el.children);
|
|
3232
|
+
if (el.tag === CONTAINER) return children.length === 1 ? children[0] : { kind: "fragment", children };
|
|
2333
3233
|
const at = this.tagAt(el);
|
|
2334
3234
|
return {
|
|
2335
3235
|
kind: "element",
|
|
2336
3236
|
tag: el.tag,
|
|
2337
3237
|
svg: el.namespace === "svg",
|
|
2338
|
-
props: this.lowerAttributes(el.attributes),
|
|
2339
|
-
children
|
|
3238
|
+
props: this.lowerAttributes(el.attributes, true),
|
|
3239
|
+
children,
|
|
2340
3240
|
static: false,
|
|
2341
3241
|
...at ? { at } : {}
|
|
2342
3242
|
};
|
|
@@ -2408,10 +3308,14 @@ var Lowerer = class {
|
|
|
2408
3308
|
const at = this.tagAt(el);
|
|
2409
3309
|
return { kind: "component", name: "Show", props, children: [child], ...at ? { at } : {}, ...cond.at ? { bindAt: cond.at } : {} };
|
|
2410
3310
|
}
|
|
2411
|
-
/**
|
|
3311
|
+
/**
|
|
3312
|
+
* `<el each=${items} key?>${item => …}</el>` → `<el><For each>{item => …}</For></el>`: the
|
|
3313
|
+
* content is repeated per item. Content that is not a `${item => …}` arrow is repeated as
|
|
3314
|
+
* it is. Null when the element has no `each`.
|
|
3315
|
+
*/
|
|
2412
3316
|
lowerEach(el) {
|
|
2413
3317
|
const eachDir = el.attributes.find((a) => a.kind === "EachDirective");
|
|
2414
|
-
if (!eachDir || eachDir.kind !== "EachDirective") return
|
|
3318
|
+
if (!eachDir || eachDir.kind !== "EachDirective") return null;
|
|
2415
3319
|
const each = this.hole(eachDir.hole);
|
|
2416
3320
|
const props = [{ name: "each", kind: "attr", expr: each.code, reactive: each.reactive, ...each.at ? { at: each.at } : {} }];
|
|
2417
3321
|
if (eachDir.key) {
|
|
@@ -2421,12 +3325,12 @@ var Lowerer = class {
|
|
|
2421
3325
|
const arrow = this.itemArrow(el);
|
|
2422
3326
|
let childrenCode;
|
|
2423
3327
|
if (arrow) {
|
|
2424
|
-
const
|
|
2425
|
-
|
|
2426
|
-
childrenCode = `(${arrow.params.join(", ")}) => ${paren(this.emit(repeated), "arrowBody")}`;
|
|
3328
|
+
const body = arrow.bodyReactive ? `() => ${paren(arrow.body, "arrowBody")}` : paren(arrow.body, "arrowBody");
|
|
3329
|
+
childrenCode = `(${arrow.params.join(", ")}) => ${body}`;
|
|
2427
3330
|
} else {
|
|
2428
|
-
const
|
|
2429
|
-
|
|
3331
|
+
const content = this.lowerChildren(el.children);
|
|
3332
|
+
const ir = content.length === 1 ? content[0] : { kind: "fragment", children: content };
|
|
3333
|
+
childrenCode = `() => ${paren(this.emit(ir), "arrowBody")}`;
|
|
2430
3334
|
}
|
|
2431
3335
|
const children = [{ kind: "expr", code: childrenCode, reactive: false }];
|
|
2432
3336
|
const at = this.tagAt(el);
|
|
@@ -2443,33 +3347,23 @@ var Lowerer = class {
|
|
|
2443
3347
|
const clone = { ...el, attributes: el.attributes.filter((a) => !drop(a)) };
|
|
2444
3348
|
return clone.kind === "Element" ? this.lowerElement(clone) : this.lowerComponent(clone);
|
|
2445
3349
|
}
|
|
2446
|
-
/** Same element (minus each/key) but with explicit IR children. */
|
|
2447
|
-
rebuildWithChildren(el, children) {
|
|
2448
|
-
const props = this.lowerAttributes(
|
|
2449
|
-
el.attributes.filter((a) => a.kind !== "EachDirective")
|
|
2450
|
-
);
|
|
2451
|
-
if (el.kind === "Element") {
|
|
2452
|
-
const at = this.tagAt(el);
|
|
2453
|
-
return {
|
|
2454
|
-
kind: "element",
|
|
2455
|
-
tag: el.tag,
|
|
2456
|
-
svg: el.namespace === "svg",
|
|
2457
|
-
props,
|
|
2458
|
-
children,
|
|
2459
|
-
static: false,
|
|
2460
|
-
...at ? { at } : {}
|
|
2461
|
-
};
|
|
2462
|
-
}
|
|
2463
|
-
return { kind: "component", name: el.tag, props, children };
|
|
2464
|
-
}
|
|
2465
3350
|
// --- attributes ---------------------------------------------------------
|
|
2466
|
-
|
|
3351
|
+
/**
|
|
3352
|
+
* `element`: a DOM element, where each class:/style: value that moves is its own accessor.
|
|
3353
|
+
* A component gets the object as before, rebuilt whole when any value moves.
|
|
3354
|
+
*/
|
|
3355
|
+
lowerAttributes(attrs, element = false) {
|
|
3356
|
+
let anyReactive = false;
|
|
3357
|
+
const entry = (name, h) => {
|
|
3358
|
+
anyReactive ||= h.reactive;
|
|
3359
|
+
if (!element || !h.reactive) return `${JSON.stringify(name)}: ${h.code}`;
|
|
3360
|
+
const accessor = `() => ${paren(h.code, "arrowBody")}`;
|
|
3361
|
+
return `${JSON.stringify(name)}: ${h.at ? markHole(accessor, h.at.line, h.at.column) : accessor}`;
|
|
3362
|
+
};
|
|
2467
3363
|
const props = [];
|
|
2468
3364
|
const classEntries = [];
|
|
2469
|
-
let classReactive = false;
|
|
2470
3365
|
let classAt;
|
|
2471
3366
|
const styleEntries = [];
|
|
2472
|
-
let styleReactive = false;
|
|
2473
3367
|
let styleAt;
|
|
2474
3368
|
const usePairs = [];
|
|
2475
3369
|
for (const a of attrs) {
|
|
@@ -2509,15 +3403,13 @@ var Lowerer = class {
|
|
|
2509
3403
|
break;
|
|
2510
3404
|
case "ClassDirective": {
|
|
2511
3405
|
const h = this.hole(a.hole);
|
|
2512
|
-
classEntries.push(
|
|
2513
|
-
classReactive = classReactive || h.reactive;
|
|
3406
|
+
classEntries.push(entry(a.name, h));
|
|
2514
3407
|
classAt ??= h.at;
|
|
2515
3408
|
break;
|
|
2516
3409
|
}
|
|
2517
3410
|
case "StyleDirective": {
|
|
2518
3411
|
const h = this.hole(a.hole);
|
|
2519
|
-
styleEntries.push(
|
|
2520
|
-
styleReactive = styleReactive || h.reactive;
|
|
3412
|
+
styleEntries.push(entry(a.name, h));
|
|
2521
3413
|
styleAt ??= h.at;
|
|
2522
3414
|
break;
|
|
2523
3415
|
}
|
|
@@ -2537,18 +3429,19 @@ var Lowerer = class {
|
|
|
2537
3429
|
name: "classList",
|
|
2538
3430
|
kind: "attr",
|
|
2539
3431
|
expr: `{ ${classEntries.join(", ")} }`,
|
|
2540
|
-
reactive:
|
|
3432
|
+
reactive: !element && anyReactive,
|
|
2541
3433
|
...classAt ? { at: classAt } : {}
|
|
2542
3434
|
});
|
|
2543
3435
|
}
|
|
2544
3436
|
if (styleEntries.length > 0) {
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
3437
|
+
const entries = `{ ${styleEntries.join(", ")} }`;
|
|
3438
|
+
const base = props.findIndex((p) => p.name === "style");
|
|
3439
|
+
if (base === -1) props.push({ name: "style", kind: "attr", expr: entries, reactive: !element && anyReactive, ...styleAt ? { at: styleAt } : {} });
|
|
3440
|
+
else {
|
|
3441
|
+
const prop = props[base];
|
|
3442
|
+
const value = prop.expr === void 0 ? JSON.stringify(prop.literal) : prop.reactive ? `() => ${paren(prop.expr, "arrowBody")}` : prop.expr;
|
|
3443
|
+
props[base] = { name: "style", kind: "attr", expr: `[${value}, ${entries}]`, reactive: false, ...prop.at ? { at: prop.at } : {} };
|
|
3444
|
+
}
|
|
2552
3445
|
}
|
|
2553
3446
|
if (usePairs.length > 0) {
|
|
2554
3447
|
props.push({ name: "use", kind: "attr", expr: `[${usePairs.join(", ")}]` });
|
|
@@ -2637,7 +3530,7 @@ var Lowerer = class {
|
|
|
2637
3530
|
return base;
|
|
2638
3531
|
}
|
|
2639
3532
|
if (v.kind === "static") {
|
|
2640
|
-
base.literal = v.value;
|
|
3533
|
+
base.literal = decodeEntities(v.value);
|
|
2641
3534
|
return base;
|
|
2642
3535
|
}
|
|
2643
3536
|
if (v.kind === "hole") {
|
|
@@ -2650,7 +3543,7 @@ var Lowerer = class {
|
|
|
2650
3543
|
let reactive = false;
|
|
2651
3544
|
let at;
|
|
2652
3545
|
const body = v.parts.map((p) => {
|
|
2653
|
-
if ("text" in p) return escapeTemplate(p.text);
|
|
3546
|
+
if ("text" in p) return escapeTemplate(decodeEntities(p.text));
|
|
2654
3547
|
const h = this.hole(p.hole);
|
|
2655
3548
|
reactive = reactive || h.reactive;
|
|
2656
3549
|
at ??= h.at;
|
|
@@ -2675,6 +3568,7 @@ function compilePieces(pieces, holes, options = {}) {
|
|
|
2675
3568
|
...options.sourceFile ? { sourceFile: options.sourceFile } : {},
|
|
2676
3569
|
...options.positionAt ? { positionAt: options.positionAt } : {}
|
|
2677
3570
|
});
|
|
3571
|
+
if (options.templateStyles) applyTemplateStyles(ir, options.templateStyles);
|
|
2678
3572
|
analyzeStatic(ir);
|
|
2679
3573
|
resolveComponentSources(ir, {
|
|
2680
3574
|
resolver: createComponentResolver(options.resolve ?? []),
|
|
@@ -2780,6 +3674,22 @@ var DELEGATED2 = /* @__PURE__ */ new Set([
|
|
|
2780
3674
|
"mouseup"
|
|
2781
3675
|
]);
|
|
2782
3676
|
var isReactive = (node) => isReactiveShape(shapeOf(node));
|
|
3677
|
+
var CONTAINER2 = "container";
|
|
3678
|
+
function directive(node, name) {
|
|
3679
|
+
if (node.type !== "JSXElement") return void 0;
|
|
3680
|
+
const opening = node.openingElement;
|
|
3681
|
+
if (opening.name.type !== "JSXIdentifier" || opening.name.name[0] !== opening.name.name[0].toLowerCase()) return void 0;
|
|
3682
|
+
return opening.attributes.find((a) => a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && a.name.name === name);
|
|
3683
|
+
}
|
|
3684
|
+
function directiveExpr(attr) {
|
|
3685
|
+
const v = attr.value;
|
|
3686
|
+
return v?.type === "JSXExpressionContainer" && v.expression?.type !== "JSXEmptyExpression" ? v.expression : void 0;
|
|
3687
|
+
}
|
|
3688
|
+
function emitIR(ir, ctx) {
|
|
3689
|
+
const { code, imports, templates } = imperativeBackend.emit(ir, {});
|
|
3690
|
+
for (const s of imports) ctx.used.add(s);
|
|
3691
|
+
return inlineTemplates(code, templates);
|
|
3692
|
+
}
|
|
2783
3693
|
var posOf = (node, ctx) => {
|
|
2784
3694
|
if (!ctx.sourceFile) return void 0;
|
|
2785
3695
|
const at = node.loc?.start;
|
|
@@ -2857,9 +3767,12 @@ function attrExprCode(attr, ctx) {
|
|
|
2857
3767
|
}
|
|
2858
3768
|
return null;
|
|
2859
3769
|
}
|
|
2860
|
-
function buildProps(attrs, ctx) {
|
|
3770
|
+
function buildProps(attrs, ctx, element = false) {
|
|
2861
3771
|
const props = [];
|
|
2862
3772
|
const usePairs = [];
|
|
3773
|
+
const classEntries = [];
|
|
3774
|
+
const styleEntries = [];
|
|
3775
|
+
let styleAt;
|
|
2863
3776
|
for (const a of attrs) {
|
|
2864
3777
|
if (a.type === "JSXSpreadAttribute") {
|
|
2865
3778
|
props.push({ name: "", kind: "spread", expr: ctx.code(a.argument) });
|
|
@@ -2875,6 +3788,27 @@ function buildProps(attrs, ctx) {
|
|
|
2875
3788
|
usePairs.push(opts != null ? `[${dir}, () => ${paren(opts, "arrowBody")}]` : `[${dir}]`);
|
|
2876
3789
|
continue;
|
|
2877
3790
|
}
|
|
3791
|
+
if (element && (ns === "class" || ns === "style")) {
|
|
3792
|
+
const key = JSON.stringify(a.name.name.name);
|
|
3793
|
+
const v = a.value;
|
|
3794
|
+
let value;
|
|
3795
|
+
if (v == null) value = "true";
|
|
3796
|
+
else if (isString(v)) value = JSON.stringify(literalOf(v));
|
|
3797
|
+
else if (v.type === "JSXExpressionContainer" && v.expression?.type !== "JSXEmptyExpression") {
|
|
3798
|
+
value = keyValue(v.expression, ctx);
|
|
3799
|
+
if (ns === "style") styleAt ??= posOf(v.expression, ctx);
|
|
3800
|
+
} else continue;
|
|
3801
|
+
(ns === "class" ? classEntries : styleEntries).push(`${key}: ${value}`);
|
|
3802
|
+
continue;
|
|
3803
|
+
}
|
|
3804
|
+
if (element && a.name.type === "JSXIdentifier" && a.name.name === "style" && a.value?.type === "JSXExpressionContainer") {
|
|
3805
|
+
const entries = objectEntries(a.value.expression, ctx);
|
|
3806
|
+
if (entries) {
|
|
3807
|
+
styleEntries.unshift(...entries);
|
|
3808
|
+
styleAt = posOf(a.value.expression, ctx);
|
|
3809
|
+
continue;
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
2878
3812
|
if (ns === "oncapture") {
|
|
2879
3813
|
const evt = a.name.name.name.toLowerCase();
|
|
2880
3814
|
const h = attrExprCode(a, ctx) ?? "undefined";
|
|
@@ -2883,12 +3817,49 @@ function buildProps(attrs, ctx) {
|
|
|
2883
3817
|
}
|
|
2884
3818
|
props.push(buildAttr(a, ctx));
|
|
2885
3819
|
}
|
|
3820
|
+
if (classEntries.length > 0) props.push({ name: "classList", kind: "attr", expr: `{ ${classEntries.join(", ")} }`, reactive: false });
|
|
3821
|
+
if (styleEntries.length > 0) {
|
|
3822
|
+
const entries = `{ ${styleEntries.join(", ")} }`;
|
|
3823
|
+
const base = props.findIndex((p) => p.name === "style" && p.kind === "attr");
|
|
3824
|
+
if (base === -1) props.push({ name: "style", kind: "attr", expr: entries, reactive: false, ...styleAt ? { at: styleAt } : {} });
|
|
3825
|
+
else {
|
|
3826
|
+
const prop = props[base];
|
|
3827
|
+
const value = prop.literal !== void 0 ? JSON.stringify(prop.literal) : prop.reactive ? `() => ${paren(prop.expr, "arrowBody")}` : prop.expr;
|
|
3828
|
+
props[base] = { name: "style", kind: "attr", expr: `[${value}, ${entries}]`, reactive: false, ...prop.at ? { at: prop.at } : {} };
|
|
3829
|
+
}
|
|
3830
|
+
}
|
|
2886
3831
|
if (usePairs.length > 0) props.push({ name: "use", kind: "attr", expr: `[${usePairs.join(", ")}]` });
|
|
2887
3832
|
return props;
|
|
2888
3833
|
}
|
|
3834
|
+
function keyValue(expr, ctx) {
|
|
3835
|
+
const code = ctx.code(expr);
|
|
3836
|
+
if (!isReactive(expr)) return code;
|
|
3837
|
+
const accessor = `() => ${paren(code, "arrowBody")}`;
|
|
3838
|
+
const at = posOf(expr, ctx);
|
|
3839
|
+
return at ? markHole(accessor, at.line, at.column) : accessor;
|
|
3840
|
+
}
|
|
3841
|
+
function objectEntries(expr, ctx) {
|
|
3842
|
+
if (expr?.type !== "ObjectExpression") return null;
|
|
3843
|
+
const entries = [];
|
|
3844
|
+
for (const p of expr.properties) {
|
|
3845
|
+
if (p.type !== "ObjectProperty") return null;
|
|
3846
|
+
const key = p.computed ? `[${ctx.code(p.key)}]` : p.key.type === "Identifier" ? JSON.stringify(p.key.name) : JSON.stringify(String(p.key.value));
|
|
3847
|
+
entries.push(`${key}: ${keyValue(p.value, ctx)}`);
|
|
3848
|
+
}
|
|
3849
|
+
return entries;
|
|
3850
|
+
}
|
|
2889
3851
|
function buildChildren(children, ctx) {
|
|
2890
3852
|
const out = [];
|
|
2891
|
-
for (
|
|
3853
|
+
for (let i = 0; i < children.length; i++) {
|
|
3854
|
+
const child = children[i];
|
|
3855
|
+
if (directive(child, "if")) {
|
|
3856
|
+
let next = i + 1;
|
|
3857
|
+
while (next < children.length && children[next].type === "JSXText" && !cleanTemplateText(children[next].value)) next++;
|
|
3858
|
+
const fallback = directive(children[next], "else") ? children[next] : null;
|
|
3859
|
+
out.push(buildIf(child, fallback, ctx));
|
|
3860
|
+
if (fallback) i = next;
|
|
3861
|
+
continue;
|
|
3862
|
+
}
|
|
2892
3863
|
if (child.type === "JSXText") {
|
|
2893
3864
|
const text = cleanTemplateText(child.value);
|
|
2894
3865
|
if (text) out.push({ kind: "text", value: text });
|
|
@@ -2904,6 +3875,7 @@ function buildChildren(children, ctx) {
|
|
|
2904
3875
|
});
|
|
2905
3876
|
}
|
|
2906
3877
|
} else if (child.type === "JSXElement" || child.type === "JSXFragment") {
|
|
3878
|
+
if (ctx.dropStyles?.has(child.start)) continue;
|
|
2907
3879
|
out.push(buildNode(child, ctx));
|
|
2908
3880
|
} else if (child.type === "JSXSpreadChild") {
|
|
2909
3881
|
out.push({ kind: "expr", code: ctx.code(child.expression), reactive: false });
|
|
@@ -2925,19 +3897,72 @@ function readLoad(attrs) {
|
|
|
2925
3897
|
}
|
|
2926
3898
|
return void 0;
|
|
2927
3899
|
}
|
|
3900
|
+
function buildIf(node, fallback, ctx) {
|
|
3901
|
+
const cond = directiveExpr(directive(node, "if"));
|
|
3902
|
+
const props = [
|
|
3903
|
+
cond ? { name: "when", kind: "attr", expr: ctx.code(cond), reactive: isReactive(cond), at: posOf(cond, ctx) } : { name: "when", kind: "attr", literal: true }
|
|
3904
|
+
];
|
|
3905
|
+
if (fallback) {
|
|
3906
|
+
props.push({ name: "fallback", kind: "attr", expr: emitIR(buildElement(fallback, ctx, ["else"]), ctx), jsxElement: true });
|
|
3907
|
+
}
|
|
3908
|
+
return { kind: "component", name: "Show", props, children: [buildElement(node, ctx, ["if"])] };
|
|
3909
|
+
}
|
|
3910
|
+
function buildEach(node, ctx) {
|
|
3911
|
+
const attr = directive(node, "each");
|
|
3912
|
+
if (!attr) return null;
|
|
3913
|
+
const list = directiveExpr(attr);
|
|
3914
|
+
const props = [
|
|
3915
|
+
list ? { name: "each", kind: "attr", expr: ctx.code(list), reactive: isReactive(list), at: posOf(list, ctx) } : { name: "each", kind: "attr", expr: "[]" }
|
|
3916
|
+
];
|
|
3917
|
+
const key = directive(node, "key");
|
|
3918
|
+
if (key) {
|
|
3919
|
+
const keyExpr = directiveExpr(key);
|
|
3920
|
+
const by = isString(key.value) ? `(item) => item[${JSON.stringify(literalOf(key.value))}]` : keyExpr ? ctx.code(keyExpr) : void 0;
|
|
3921
|
+
if (by) props.push({ name: "by", kind: "attr", expr: by });
|
|
3922
|
+
}
|
|
3923
|
+
const content = node.children.filter((c) => !(c.type === "JSXText" && !cleanTemplateText(c.value)));
|
|
3924
|
+
const only = content.length === 1 && content[0].type === "JSXExpressionContainer" ? content[0].expression : null;
|
|
3925
|
+
let render;
|
|
3926
|
+
if (only && (only.type === "ArrowFunctionExpression" || only.type === "FunctionExpression")) {
|
|
3927
|
+
const fn = ctx.code(only);
|
|
3928
|
+
const live = only.type === "ArrowFunctionExpression" && only.body.type !== "BlockStatement" && isReactive(only.body);
|
|
3929
|
+
render = live ? `(...args) => () => (${fn})(...args)` : fn;
|
|
3930
|
+
} else {
|
|
3931
|
+
const built = buildChildren(node.children, ctx);
|
|
3932
|
+
const ir = built.length === 1 ? built[0] : { kind: "fragment", children: built };
|
|
3933
|
+
render = `() => ${paren(emitIR(ir, ctx), "arrowBody")}`;
|
|
3934
|
+
}
|
|
3935
|
+
return { kind: "component", name: "For", props, children: [{ kind: "expr", code: render, reactive: false }] };
|
|
3936
|
+
}
|
|
3937
|
+
function buildElement(node, ctx, handled) {
|
|
3938
|
+
const skip = new Set(handled);
|
|
3939
|
+
const directives = /* @__PURE__ */ new Set(["if", "else", "each", ...directive(node, "each") ? ["key"] : []]);
|
|
3940
|
+
const attributes = node.openingElement.attributes.filter(
|
|
3941
|
+
(a) => !(a.type === "JSXAttribute" && a.name.type === "JSXIdentifier" && (skip.has(a.name.name) || directives.has(a.name.name)))
|
|
3942
|
+
);
|
|
3943
|
+
const { tag } = tagInfo(node.openingElement.name, ctx);
|
|
3944
|
+
const each = buildEach(node, ctx);
|
|
3945
|
+
const children = each ? [each] : buildChildren(node.children, ctx);
|
|
3946
|
+
if (tag === CONTAINER2) return children.length === 1 ? children[0] : { kind: "fragment", children };
|
|
3947
|
+
const at = ctx.sourceFile && node.loc?.start ? { file: ctx.sourceFile, line: node.loc.start.line, column: node.loc.start.column } : void 0;
|
|
3948
|
+
const props = buildProps(attributes, ctx, true);
|
|
3949
|
+
const scope = ctx.scopes?.find((s) => node.start >= s.start && node.end <= s.end);
|
|
3950
|
+
if (scope) props.unshift({ name: "data-fx-s", kind: "attr", literal: scope.value });
|
|
3951
|
+
return { kind: "element", tag, svg: SVG_TAGS.has(tag), props, children, static: false, ...at ? { at } : {} };
|
|
3952
|
+
}
|
|
2928
3953
|
function buildNode(node, ctx) {
|
|
2929
3954
|
if (node.type === "JSXFragment") {
|
|
2930
3955
|
return { kind: "fragment", children: buildChildren(node.children, ctx) };
|
|
2931
3956
|
}
|
|
3957
|
+
if (directive(node, "if")) return buildIf(node, null, ctx);
|
|
3958
|
+
if (ctx.dropStyles?.has(node.start)) return { kind: "fragment", children: [] };
|
|
2932
3959
|
const { tag, component } = tagInfo(node.openingElement.name, ctx);
|
|
3960
|
+
if (!component) return buildElement(node, ctx, []);
|
|
2933
3961
|
const props = buildProps(node.openingElement.attributes, ctx);
|
|
2934
3962
|
const children = buildChildren(node.children, ctx);
|
|
2935
3963
|
const at = ctx.sourceFile && node.loc?.start ? { file: ctx.sourceFile, line: node.loc.start.line, column: node.loc.start.column } : void 0;
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
return { kind: "component", name: tag, props, children, ...load ? { load } : {}, ...at ? { at } : {} };
|
|
2939
|
-
}
|
|
2940
|
-
return { kind: "element", tag, svg: SVG_TAGS.has(tag), props, children, static: false, ...at ? { at } : {} };
|
|
3964
|
+
const load = readLoad(node.openingElement.attributes);
|
|
3965
|
+
return { kind: "component", name: tag, props, children, ...load ? { load } : {}, ...at ? { at } : {} };
|
|
2941
3966
|
}
|
|
2942
3967
|
function buildJsxIR(node, ctx) {
|
|
2943
3968
|
const ir = buildNode(node, ctx);
|
|
@@ -3458,8 +4483,8 @@ function isJsxRoot(node, parent, key) {
|
|
|
3458
4483
|
if (!isJsx(node)) return false;
|
|
3459
4484
|
return !(parent && isJsx(parent) && key === "children");
|
|
3460
4485
|
}
|
|
3461
|
-
function isTemplateTag(node,
|
|
3462
|
-
return node.type === "TaggedTemplateExpression" && node.tag?.type === "Identifier" && (node.tag.name
|
|
4486
|
+
function isTemplateTag(node, tags) {
|
|
4487
|
+
return node.type === "TaggedTemplateExpression" && node.tag?.type === "Identifier" && tags.has(node.tag.name);
|
|
3463
4488
|
}
|
|
3464
4489
|
function outermost(list) {
|
|
3465
4490
|
return list.filter(
|
|
@@ -3605,24 +4630,30 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3605
4630
|
const wantsJsx = format !== "lit";
|
|
3606
4631
|
const mayHaveTemplate = wantsLit && (code.includes(`${litTag}\``) || code.includes("svg`"));
|
|
3607
4632
|
const wantsIntrinsics = options.intrinsics !== false && mayHaveIntrinsic(code);
|
|
3608
|
-
const wantsSources = options.sourceLocations === true &&
|
|
4633
|
+
const wantsSources = options.sourceLocations === true && mayHaveSourceMarks(code);
|
|
3609
4634
|
const sourceName = relativeToRoot(id, options.sourceRoot);
|
|
3610
|
-
|
|
4635
|
+
const wantsStyles = options.styles !== void 0 && (code.includes("<style") || code.includes("css`"));
|
|
4636
|
+
if (!mayHaveTemplate && !(wantsJsx && code.includes("<")) && !wantsIntrinsics && !wantsSources && !wantsStyles) return null;
|
|
3611
4637
|
const ast = parse2(code, {
|
|
3612
4638
|
sourceType: "module",
|
|
3613
4639
|
plugins: ["jsx", "typescript"],
|
|
3614
4640
|
errorRecovery: true
|
|
3615
4641
|
});
|
|
4642
|
+
const intrinsicTags = options.intrinsics === false ? /* @__PURE__ */ new Map() : tagIntrinsics(moduleBindings(ast.program));
|
|
4643
|
+
const templateTags = /* @__PURE__ */ new Map([[litTag, "html"], ["svg", "svg"]]);
|
|
4644
|
+
for (const [name, tag] of intrinsicTags) if (tag !== "css") templateTags.set(name, tag);
|
|
4645
|
+
const cssTags = [...intrinsicTags].filter(([, tag]) => tag === "css").map(([name]) => name);
|
|
3616
4646
|
const found = [];
|
|
3617
4647
|
walk7(ast.program, (n2, parent, key) => {
|
|
3618
|
-
if (wantsLit && isTemplateTag(n2,
|
|
4648
|
+
if (wantsLit && isTemplateTag(n2, templateTags)) found.push(n2);
|
|
3619
4649
|
else if (wantsJsx && isJsxRoot(n2, parent, key)) found.push(n2);
|
|
3620
4650
|
});
|
|
3621
4651
|
const props = options.propsDestructure === false ? { edits: [], diagnostics: [], used: /* @__PURE__ */ new Set() } : collectPropsEdits(ast.program, code, { runtimeModule: options.runtimeModule });
|
|
3622
4652
|
const intrinsics = options.intrinsics === false ? { edits: [], diagnostics: [], imports: /* @__PURE__ */ new Map() } : collectIntrinsicEdits(ast.program);
|
|
3623
4653
|
if (intrinsics.edits.length) avoidBindingClashes(ast.program, intrinsics, moduleBindings(ast.program));
|
|
3624
4654
|
const sources = options.sourceLocations === true ? collectSourceEdits(ast.program, sourceName) : { edits: [], marked: 0 };
|
|
3625
|
-
const
|
|
4655
|
+
const styles = wantsStyles ? collectStyles(ast.program, sourceName, options.styles, { html: templateTags, css: cssTags }, { id, code }) : void 0;
|
|
4656
|
+
const silent = found.length === 0 && props.edits.length === 0 && sources.edits.length === 0 && intrinsics.edits.length === 0 && intrinsics.diagnostics.length === 0 && props.diagnostics.length === 0 && !styles?.edits.length && !styles?.diagnostics.length;
|
|
3626
4657
|
if (silent) return null;
|
|
3627
4658
|
found.sort((a, b) => b.start - a.start || a.end - b.end);
|
|
3628
4659
|
const used = new Set(props.used);
|
|
@@ -3636,20 +4667,32 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3636
4667
|
declared: declaredNames(ast.program)
|
|
3637
4668
|
};
|
|
3638
4669
|
const hoisted = /* @__PURE__ */ new Map();
|
|
3639
|
-
const edits = [...props.edits, ...intrinsics.edits, ...sources.edits];
|
|
4670
|
+
const edits = [...props.edits, ...intrinsics.edits, ...sources.edits, ...styles?.edits ?? []];
|
|
3640
4671
|
for (const node of found) {
|
|
3641
4672
|
const nested = found.some(
|
|
3642
4673
|
(o) => o !== node && o.start <= node.start && o.end >= node.end && o.end - o.start > node.end - node.start
|
|
3643
4674
|
);
|
|
3644
4675
|
if (isJsx(node)) {
|
|
3645
|
-
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceName) });
|
|
4676
|
+
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceName, styles) });
|
|
3646
4677
|
continue;
|
|
3647
4678
|
}
|
|
3648
4679
|
const holes = node.quasi.expressions.map(
|
|
3649
4680
|
(e) => bindHole(code, e, edits, options.sourceLocations === true)
|
|
3650
4681
|
);
|
|
4682
|
+
const scope = styles?.scopes.find((s) => node.start >= s.start && node.end <= s.end)?.value;
|
|
4683
|
+
const owner = styles?.templateOwners.get(node.start);
|
|
4684
|
+
const templateStyles = options.styles && styles && (scope || owner) ? {
|
|
4685
|
+
options: options.styles,
|
|
4686
|
+
...scope ? { scope } : {},
|
|
4687
|
+
...owner ? { owner } : {},
|
|
4688
|
+
line: node.loc?.start.line ?? 0,
|
|
4689
|
+
column: node.loc?.start.column ?? 0,
|
|
4690
|
+
styles: styles.styles,
|
|
4691
|
+
diagnostics: styles.diagnostics
|
|
4692
|
+
} : void 0;
|
|
3651
4693
|
const result = compilePieces(toPieces(node), holes, {
|
|
3652
4694
|
...options,
|
|
4695
|
+
...templateStyles ? { templateStyles } : {},
|
|
3653
4696
|
hoistTemplates: true,
|
|
3654
4697
|
// A tag inside a template gets the same mark a JSX tag does. Without one, the nodes it
|
|
3655
4698
|
// makes are the only ones in the module carrying no mark, and they take whichever was
|
|
@@ -3658,12 +4701,13 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3658
4701
|
// Same defaults as the plugin, so moving a build over is not a rendering change.
|
|
3659
4702
|
templateClone: options.templateClone ?? true,
|
|
3660
4703
|
partialTemplates: nested ? false : options.partialTemplates ?? true,
|
|
3661
|
-
svg: node.tag.name === "svg"
|
|
4704
|
+
svg: templateTags.get(node.tag.name) === "svg"
|
|
3662
4705
|
});
|
|
3663
4706
|
for (const symbol of result.imports) used.add(symbol);
|
|
3664
4707
|
collectNeeds(result.ir, needs);
|
|
3665
4708
|
edits.push({ start: node.start, end: node.end, code: adoptTemplates(result.code, result.templates, hoisted) });
|
|
3666
4709
|
}
|
|
4710
|
+
if (styles && options.styles) edits.push(...finishShadowStyles(styles, code, id));
|
|
3667
4711
|
const out = new MagicString(code);
|
|
3668
4712
|
for (const e of outermost(edits)) {
|
|
3669
4713
|
if (e.start === e.end) out.appendLeft(e.start, e.code);
|
|
@@ -3721,13 +4765,19 @@ function transformTemplates(code, id, options = {}) {
|
|
|
3721
4765
|
...loadDiagnostics.length ? { loadDiagnostics } : {},
|
|
3722
4766
|
...unresolvedDiagnostics.length ? { unresolvedDiagnostics } : {},
|
|
3723
4767
|
...props.diagnostics.length ? { propsDiagnostics: props.diagnostics } : {},
|
|
3724
|
-
...intrinsics.diagnostics.length ? { intrinsicDiagnostics: intrinsics.diagnostics } : {}
|
|
4768
|
+
...intrinsics.diagnostics.length ? { intrinsicDiagnostics: intrinsics.diagnostics } : {},
|
|
4769
|
+
...styles?.styles.length ? { styles: styles.styles } : {},
|
|
4770
|
+
...styles?.diagnostics.length ? { styleDiagnostics: styles.diagnostics } : {},
|
|
4771
|
+
...styles?.literals.length ? { styleLiterals: styles.literals } : {},
|
|
4772
|
+
...styles?.references.length ? { styleReferences: styles.references } : {}
|
|
3725
4773
|
};
|
|
3726
4774
|
}
|
|
3727
|
-
function compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceFile) {
|
|
4775
|
+
function compileJsx(code, node, edits, nested, used, needs, hoisted, options, sourceFile, styles) {
|
|
3728
4776
|
const ir = buildJsxIR(node, {
|
|
3729
4777
|
code: (n2) => slice(code, n2.start, n2.end, edits),
|
|
3730
4778
|
used,
|
|
4779
|
+
...styles?.scopes.length ? { scopes: styles.scopes } : {},
|
|
4780
|
+
...styles?.drop.size ? { dropStyles: styles.drop } : {},
|
|
3731
4781
|
...options.sourceLocations === true && sourceFile ? { sourceFile } : {}
|
|
3732
4782
|
});
|
|
3733
4783
|
analyzeStatic(ir);
|