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