@fluixi/compiler 1.0.0-alpha.105 → 1.0.0-alpha.106
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/static-graph.cjs +1 -1
- package/dist/analyze/static-graph.mjs +1 -1
- package/dist/{babel-USPHNEJF.mjs → babel-HJY4RVAV.mjs} +33 -20
- package/dist/{chunk-OQYQ7UTD.mjs → chunk-4XEOMQ57.mjs} +1 -1
- package/dist/{chunk-EK4OMGTU.mjs → chunk-JUFI6IR3.mjs} +1 -1
- package/dist/{chunk-5GAYDAAC.mjs → chunk-LCQHL2VQ.mjs} +132 -10
- package/dist/{chunk-XBAQME2V.mjs → chunk-LGUZRHYN.mjs} +2 -2
- package/dist/{chunk-O6OBEV4V.mjs → chunk-TDN5MYWI.mjs} +1 -1
- package/dist/{chunk-EQIIWIEU.mjs → chunk-W7DYOMXJ.mjs} +2 -2
- package/dist/{chunk-FMIIK5UM.mjs → chunk-WHEDRMNR.mjs} +1 -1
- package/dist/codegen/backends/imperative.cjs +130 -8
- package/dist/codegen/backends/imperative.d.ts.map +1 -1
- package/dist/codegen/backends/imperative.js +62 -0
- package/dist/codegen/backends/imperative.mjs +130 -8
- package/dist/codegen/partial-template.cjs +80 -8
- package/dist/codegen/partial-template.d.cts +21 -4
- package/dist/codegen/partial-template.d.ts +21 -4
- package/dist/codegen/partial-template.d.ts.map +1 -1
- package/dist/codegen/partial-template.js +0 -0
- package/dist/codegen/partial-template.mjs +80 -8
- package/dist/codegen/serialize-static.cjs +1 -0
- package/dist/codegen/serialize-static.d.cts +8 -0
- package/dist/codegen/serialize-static.d.ts +8 -0
- package/dist/codegen/serialize-static.d.ts.map +1 -1
- package/dist/codegen/serialize-static.js +1 -1
- package/dist/codegen/serialize-static.mjs +1 -0
- package/dist/frontend/babel/build-ir-html.cjs +149 -21
- package/dist/frontend/babel/build-ir-html.d.cts +3 -1
- package/dist/frontend/babel/build-ir-html.d.ts +3 -1
- package/dist/frontend/babel/build-ir-html.d.ts.map +1 -1
- package/dist/frontend/babel/build-ir-html.mjs +149 -21
- package/dist/frontend/babel/build-ir.cjs +149 -21
- package/dist/frontend/babel/build-ir.d.cts +11 -2
- package/dist/frontend/babel/build-ir.d.ts +11 -2
- package/dist/frontend/babel/build-ir.d.ts.map +1 -1
- package/dist/frontend/babel/build-ir.js +15 -9
- package/dist/frontend/babel/build-ir.mjs +149 -21
- package/dist/frontend/babel/index.cjs +160 -25
- package/dist/frontend/babel/index.mjs +160 -25
- package/dist/frontend/babel/lower-template.cjs +149 -21
- package/dist/frontend/babel/lower-template.d.cts +2 -1
- package/dist/frontend/babel/lower-template.d.ts +2 -1
- package/dist/frontend/babel/lower-template.d.ts.map +1 -1
- package/dist/frontend/babel/lower-template.js +4 -4
- package/dist/frontend/babel/lower-template.mjs +149 -21
- package/dist/frontend/babel/plugin.cjs +158 -23
- package/dist/frontend/babel/plugin.js +9 -2
- package/dist/frontend/babel/plugin.mjs +158 -23
- package/dist/index.cjs +131 -9
- package/dist/index.mjs +131 -9
- package/dist/integrations.cjs +165 -33
- package/dist/integrations.mjs +11 -11
- package/dist/lower/compile-template.cjs +131 -9
- package/dist/lower/compile-template.mjs +131 -9
- package/dist/lower/jsx.cjs +130 -8
- package/dist/lower/jsx.mjs +130 -8
- package/dist/lower/template.cjs +130 -8
- package/dist/lower/template.mjs +130 -8
- package/dist/resolve/builtins.cjs +1 -1
- package/dist/resolve/builtins.mjs +1 -1
- package/dist/{server-fns-7Y25MR3B.mjs → server-fns-WZJK4BJE.mjs} +5 -5
- package/dist/{server-functions-43CFKXY3.mjs → server-functions-4KTFFEO3.mjs} +3 -3
- package/dist/transform/index.cjs +135 -16
- package/dist/transform/index.mjs +135 -16
- package/dist/transform/templates.cjs +134 -15
- package/dist/transform/templates.d.ts.map +1 -1
- package/dist/transform/templates.js +4 -8
- package/dist/transform/templates.mjs +134 -15
- package/dist/{transform-YUDW7K4J.mjs → transform-NO46NFQH.mjs} +11 -14
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +4 -4
package/dist/integrations.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.106 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __create = Object.create;
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -1055,10 +1055,63 @@ function isHole(node) {
|
|
|
1055
1055
|
function isTemplateChild(node) {
|
|
1056
1056
|
return node.kind === "text" || node.kind === "element" && isTemplateElement(node);
|
|
1057
1057
|
}
|
|
1058
|
+
function disposition(prop) {
|
|
1059
|
+
if (prop.kind === "spread") return null;
|
|
1060
|
+
if (prop.name === "ref") return "ref";
|
|
1061
|
+
if (prop.name === "use") return "use";
|
|
1062
|
+
if (prop.kind === "event") return prop.event ? "event" : null;
|
|
1063
|
+
if (prop.kind === "prop") return "property";
|
|
1064
|
+
if (prop.kind !== "attr") return null;
|
|
1065
|
+
const name = prop.name;
|
|
1066
|
+
if (name.startsWith("on:")) return "nativeEvent";
|
|
1067
|
+
if (name.startsWith("prop:")) return "property";
|
|
1068
|
+
if (name.startsWith("attr:")) return "attr";
|
|
1069
|
+
if (name.startsWith("bool:")) return "boolAttr";
|
|
1070
|
+
if (name === "className" || name === "class") {
|
|
1071
|
+
return isPlainLiteralAttr(prop) ? "serialize" : "class";
|
|
1072
|
+
}
|
|
1073
|
+
if (name === "classList") {
|
|
1074
|
+
if (isPlainLiteralAttr(prop)) return "serialize";
|
|
1075
|
+
return prop.reactive ? "classListDynamic" : "classList";
|
|
1076
|
+
}
|
|
1077
|
+
if (name === "style") {
|
|
1078
|
+
if (isPlainLiteralAttr(prop)) return "serialize";
|
|
1079
|
+
return prop.reactive ? "styleDynamic" : "style";
|
|
1080
|
+
}
|
|
1081
|
+
if (name.includes(":")) return null;
|
|
1082
|
+
if (PROPERTY_ONLY.has(name)) return null;
|
|
1083
|
+
if (PROPERTY_BINDS.has(name)) return "property";
|
|
1084
|
+
if (prop.expr === void 0) return isPlainLiteralAttr(prop) ? "serialize" : null;
|
|
1085
|
+
return "attr";
|
|
1086
|
+
}
|
|
1087
|
+
function effectiveProps(el) {
|
|
1088
|
+
const order = [];
|
|
1089
|
+
const byName = /* @__PURE__ */ new Map();
|
|
1090
|
+
for (const prop of el.props) {
|
|
1091
|
+
if (!byName.has(prop.name)) order.push(prop.name);
|
|
1092
|
+
byName.set(prop.name, prop);
|
|
1093
|
+
}
|
|
1094
|
+
return order.map((name) => byName.get(name));
|
|
1095
|
+
}
|
|
1096
|
+
function propPlan(el) {
|
|
1097
|
+
const custom = el.tag.includes("-");
|
|
1098
|
+
const plan = { serialize: [], bindings: [] };
|
|
1099
|
+
for (const prop of effectiveProps(el)) {
|
|
1100
|
+
const kind = disposition(prop);
|
|
1101
|
+
if (kind === null) return null;
|
|
1102
|
+
if (kind === "serialize") {
|
|
1103
|
+
plan.serialize.push(prop);
|
|
1104
|
+
continue;
|
|
1105
|
+
}
|
|
1106
|
+
if (custom) return null;
|
|
1107
|
+
plan.bindings.push({ prop, kind });
|
|
1108
|
+
}
|
|
1109
|
+
return plan;
|
|
1110
|
+
}
|
|
1058
1111
|
function isTemplateElement(node) {
|
|
1059
1112
|
if (node.svg) return false;
|
|
1060
1113
|
if (isRawTextElement(node.tag)) return false;
|
|
1061
|
-
if (!node
|
|
1114
|
+
if (!propPlan(node)) return false;
|
|
1062
1115
|
return node.children.every((c) => isTemplateChild(c) || isHole(c));
|
|
1063
1116
|
}
|
|
1064
1117
|
function containsHole(node) {
|
|
@@ -1066,6 +1119,15 @@ function containsHole(node) {
|
|
|
1066
1119
|
const children = node.children;
|
|
1067
1120
|
return children ? children.some(containsHole) : false;
|
|
1068
1121
|
}
|
|
1122
|
+
function containsBinding(node) {
|
|
1123
|
+
if (node.kind !== "element") return false;
|
|
1124
|
+
const plan = propPlan(node);
|
|
1125
|
+
if (plan && plan.bindings.length > 0) return true;
|
|
1126
|
+
return node.children.some(containsBinding);
|
|
1127
|
+
}
|
|
1128
|
+
function interesting(node) {
|
|
1129
|
+
return containsHole(node) || containsBinding(node);
|
|
1130
|
+
}
|
|
1069
1131
|
function addressable(el) {
|
|
1070
1132
|
for (let i = 0; i < el.children.length; i++) {
|
|
1071
1133
|
const child = el.children[i];
|
|
@@ -1079,9 +1141,10 @@ function addressable(el) {
|
|
|
1079
1141
|
function planPartialTemplate(root) {
|
|
1080
1142
|
if (!isTemplateElement(root)) return null;
|
|
1081
1143
|
if (!addressable(root)) return null;
|
|
1082
|
-
if (!root
|
|
1144
|
+
if (!interesting(root)) return null;
|
|
1083
1145
|
const steps = [];
|
|
1084
1146
|
const holes = [];
|
|
1147
|
+
const bindings = [];
|
|
1085
1148
|
let refCount = 0;
|
|
1086
1149
|
const declare2 = (expr) => {
|
|
1087
1150
|
const ref = `_n$${refCount++}`;
|
|
@@ -1089,11 +1152,17 @@ function planPartialTemplate(root) {
|
|
|
1089
1152
|
return ref;
|
|
1090
1153
|
};
|
|
1091
1154
|
walk8(root, "_el$");
|
|
1092
|
-
return { html: serializeWithMarkers(root), tag: root.tag, steps, holes };
|
|
1155
|
+
return { html: serializeWithMarkers(root), tag: root.tag, steps, holes, bindings };
|
|
1093
1156
|
function walk8(el, elementRef) {
|
|
1157
|
+
const plan = propPlan(el);
|
|
1158
|
+
if (plan) {
|
|
1159
|
+
for (const binding of plan.bindings) {
|
|
1160
|
+
bindings.push({ ref: elementRef, prop: binding.prop, kind: binding.kind });
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1094
1163
|
let last = -1;
|
|
1095
1164
|
el.children.forEach((child, i) => {
|
|
1096
|
-
if (
|
|
1165
|
+
if (interesting(child)) last = i;
|
|
1097
1166
|
});
|
|
1098
1167
|
let previous = null;
|
|
1099
1168
|
for (let i = 0; i <= last; i++) {
|
|
@@ -1107,29 +1176,32 @@ function planPartialTemplate(root) {
|
|
|
1107
1176
|
continue;
|
|
1108
1177
|
}
|
|
1109
1178
|
const ref = declare2(expr);
|
|
1110
|
-
if (child.kind === "element" &&
|
|
1179
|
+
if (child.kind === "element" && interesting(child)) walk8(child, ref);
|
|
1111
1180
|
previous = ref;
|
|
1112
1181
|
}
|
|
1113
1182
|
}
|
|
1114
1183
|
}
|
|
1115
1184
|
function serializeWithMarkers(el) {
|
|
1116
|
-
return serializeStatic(
|
|
1185
|
+
return serializeStatic(templateTree(el)).split(SENTINEL).join(HOLE_START + HOLE_END);
|
|
1117
1186
|
}
|
|
1118
|
-
function
|
|
1187
|
+
function templateTree(el) {
|
|
1188
|
+
const plan = propPlan(el);
|
|
1119
1189
|
return {
|
|
1120
1190
|
...el,
|
|
1191
|
+
props: plan ? plan.serialize : [],
|
|
1121
1192
|
children: el.children.map(
|
|
1122
|
-
(child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ?
|
|
1193
|
+
(child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ? templateTree(child) : child
|
|
1123
1194
|
)
|
|
1124
1195
|
};
|
|
1125
1196
|
}
|
|
1126
|
-
var HOLE_START, HOLE_END, SENTINEL;
|
|
1197
|
+
var HOLE_START, HOLE_END, PROPERTY_BINDS, SENTINEL;
|
|
1127
1198
|
var init_partial_template = __esm({
|
|
1128
1199
|
"src/codegen/partial-template.ts"() {
|
|
1129
1200
|
"use strict";
|
|
1130
1201
|
init_serialize_static();
|
|
1131
1202
|
HOLE_START = "<!--fx-->";
|
|
1132
1203
|
HOLE_END = "<!--fx/-->";
|
|
1204
|
+
PROPERTY_BINDS = /* @__PURE__ */ new Set(["indeterminate"]);
|
|
1133
1205
|
SENTINEL = "\0fx-hole\0";
|
|
1134
1206
|
}
|
|
1135
1207
|
});
|
|
@@ -1693,6 +1765,55 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
1693
1765
|
const mark = at ? `globalThis.${SOURCE_MARKER}?.(${JSON.stringify(at.file)},${at.line},${at.column},${JSON.stringify(name)}), ` : "";
|
|
1694
1766
|
return `createMemo(${paren(`${mark}() => createComponent(${name}, ${obj})`, "value")})`;
|
|
1695
1767
|
}
|
|
1768
|
+
function bindingTarget(binding) {
|
|
1769
|
+
const name = binding.prop.name;
|
|
1770
|
+
if (binding.kind === "boolAttr") return name.slice("bool:".length);
|
|
1771
|
+
if (name.startsWith("prop:")) return name.slice("prop:".length);
|
|
1772
|
+
if (name.startsWith("attr:")) return name.slice("attr:".length);
|
|
1773
|
+
return htmlAttrName(name);
|
|
1774
|
+
}
|
|
1775
|
+
function bindingStatement(binding, used) {
|
|
1776
|
+
const { ref, prop, kind } = binding;
|
|
1777
|
+
const value = propValue(prop);
|
|
1778
|
+
switch (kind) {
|
|
1779
|
+
case "class":
|
|
1780
|
+
used.add("setClassName");
|
|
1781
|
+
return `setClassName(${ref}, ${value});`;
|
|
1782
|
+
case "classList":
|
|
1783
|
+
used.add("setClassList");
|
|
1784
|
+
return `setClassList(${ref}, ${value}, []);`;
|
|
1785
|
+
case "classListDynamic":
|
|
1786
|
+
used.add("setDynamicClassList");
|
|
1787
|
+
return `setDynamicClassList(${ref}, ${value});`;
|
|
1788
|
+
case "style":
|
|
1789
|
+
used.add("setStyle");
|
|
1790
|
+
return `setStyle(${ref}, ${value}, []);`;
|
|
1791
|
+
case "styleDynamic":
|
|
1792
|
+
used.add("setDynamicStyle");
|
|
1793
|
+
return `setDynamicStyle(${ref}, ${value});`;
|
|
1794
|
+
case "attr":
|
|
1795
|
+
used.add("setDynamicAttribute");
|
|
1796
|
+
return `setDynamicAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
1797
|
+
case "property":
|
|
1798
|
+
used.add("setDynamicProperty");
|
|
1799
|
+
return `setDynamicProperty(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
1800
|
+
case "boolAttr":
|
|
1801
|
+
used.add("setDynamicBoolAttribute");
|
|
1802
|
+
return `setDynamicBoolAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
1803
|
+
case "event":
|
|
1804
|
+
used.add("addDelegatedEventListener");
|
|
1805
|
+
return `addDelegatedEventListener(${ref}, ${JSON.stringify(prop.event.name)}, ${value});`;
|
|
1806
|
+
case "nativeEvent":
|
|
1807
|
+
used.add("addNativeEventListener");
|
|
1808
|
+
return `addNativeEventListener(${ref}, ${JSON.stringify(prop.name.slice(3))}, ${value});`;
|
|
1809
|
+
case "ref":
|
|
1810
|
+
used.add("handleRef");
|
|
1811
|
+
return `handleRef(${value}, ${ref});`;
|
|
1812
|
+
case "use":
|
|
1813
|
+
used.add("applyUse");
|
|
1814
|
+
return `applyUse(${ref}, ${value});`;
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1696
1817
|
function staticAttrAssignment(el, prop) {
|
|
1697
1818
|
const name = htmlAttrName(prop.name);
|
|
1698
1819
|
const value = prop.literal;
|
|
@@ -1742,6 +1863,7 @@ function emitNode(node, used, templates) {
|
|
|
1742
1863
|
`const _el$ = templateNode(${id}, ${JSON.stringify(plan.tag)}, true${at ? `, false, ${JSON.stringify(at)}` : ""});`
|
|
1743
1864
|
];
|
|
1744
1865
|
for (const step of plan.steps) lines.push(`const ${step.ref} = ${step.expr};`);
|
|
1866
|
+
for (const binding of plan.bindings) lines.push(bindingStatement(binding, used));
|
|
1745
1867
|
for (const hole of plan.holes) {
|
|
1746
1868
|
lines.push(
|
|
1747
1869
|
`insert(${hole.parentRef}, holeScope(${hole.startRef}, () => ${paren(emitNode(hole.node, used, templates), "arrowBody")}), ${hole.endRef}, holeContent(${hole.startRef}, ${hole.endRef}));`
|
|
@@ -2581,16 +2703,16 @@ var init_template = __esm({
|
|
|
2581
2703
|
function gen(node) {
|
|
2582
2704
|
return generate(node, { concise: true }).code;
|
|
2583
2705
|
}
|
|
2584
|
-
function bindHole(expr, used, onNested) {
|
|
2706
|
+
function bindHole(expr, used, onNested, emit) {
|
|
2585
2707
|
const hole = {
|
|
2586
|
-
code: genExpr(expr, used, onNested),
|
|
2708
|
+
code: genExpr(expr, used, onNested, emit),
|
|
2587
2709
|
reactive: isReactiveExpr(expr)
|
|
2588
2710
|
};
|
|
2589
2711
|
if (import_core.types.isArrowFunctionExpression(expr) && !import_core.types.isBlockStatement(expr.body)) {
|
|
2590
2712
|
const body = expr.body;
|
|
2591
2713
|
hole.arrow = {
|
|
2592
2714
|
params: expr.params.map((p) => gen(p)),
|
|
2593
|
-
body: genExpr(body, used, onNested),
|
|
2715
|
+
body: genExpr(body, used, onNested, emit),
|
|
2594
2716
|
bodyReactive: isReactiveExpr(body)
|
|
2595
2717
|
};
|
|
2596
2718
|
}
|
|
@@ -2599,7 +2721,7 @@ function bindHole(expr, used, onNested) {
|
|
|
2599
2721
|
}
|
|
2600
2722
|
function lowerHtmlTemplate(node, used, opts = {}) {
|
|
2601
2723
|
const quasi = node.quasi;
|
|
2602
|
-
const holes = quasi.expressions.map((e) => bindHole(e, used, opts.onNested));
|
|
2724
|
+
const holes = quasi.expressions.map((e) => bindHole(e, used, opts.onNested, opts.emit));
|
|
2603
2725
|
return lowerTemplate(buildPieces(quasi), holes, used, opts);
|
|
2604
2726
|
}
|
|
2605
2727
|
function buildPieces(quasi) {
|
|
@@ -3135,7 +3257,7 @@ var init_jsx = __esm({
|
|
|
3135
3257
|
function gen2(node) {
|
|
3136
3258
|
return generate2(node, { concise: true }).code;
|
|
3137
3259
|
}
|
|
3138
|
-
function transformNestedJSX(node, used, onNested) {
|
|
3260
|
+
function transformNestedJSX(node, used, onNested, emit) {
|
|
3139
3261
|
const clone = import_core2.types.cloneNode(node, true);
|
|
3140
3262
|
const file = import_core2.types.file(import_core2.types.program([import_core2.types.expressionStatement(clone)]));
|
|
3141
3263
|
let changed = false;
|
|
@@ -3148,9 +3270,12 @@ function transformNestedJSX(node, used, onNested) {
|
|
|
3148
3270
|
(0, import_core2.traverse)(file, {
|
|
3149
3271
|
"JSXElement|JSXFragment"(path) {
|
|
3150
3272
|
const jsx = path.node;
|
|
3151
|
-
const nestedIR = buildIR(jsx, used, onNested);
|
|
3273
|
+
const nestedIR = buildIR(jsx, used, onNested, emit);
|
|
3152
3274
|
onNested?.(nestedIR);
|
|
3153
|
-
const { code, imports, templates } = imperativeBackend.emit(nestedIR, {
|
|
3275
|
+
const { code, imports, templates } = imperativeBackend.emit(nestedIR, {
|
|
3276
|
+
templateClone: emit?.templateClone,
|
|
3277
|
+
partialTemplates: emit?.partialTemplates ?? true
|
|
3278
|
+
});
|
|
3154
3279
|
emitInto(path, inlineTemplates(code, templates), imports);
|
|
3155
3280
|
},
|
|
3156
3281
|
// Nested html templates compose: ${cond ? html`...` : html`...`},
|
|
@@ -3158,26 +3283,29 @@ function transformNestedJSX(node, used, onNested) {
|
|
|
3158
3283
|
TaggedTemplateExpression(path) {
|
|
3159
3284
|
const tag = path.node.tag;
|
|
3160
3285
|
if (!import_core2.types.isIdentifier(tag) || tag.name !== "html" && tag.name !== "svg") return;
|
|
3161
|
-
const ir = buildIRFromHtml(path.node, used, { svg: tag.name === "svg", onNested });
|
|
3286
|
+
const ir = buildIRFromHtml(path.node, used, { svg: tag.name === "svg", onNested, emit });
|
|
3162
3287
|
onNested?.(ir);
|
|
3163
|
-
const { code, imports, templates } = imperativeBackend.emit(ir, {
|
|
3288
|
+
const { code, imports, templates } = imperativeBackend.emit(ir, {
|
|
3289
|
+
templateClone: emit?.templateClone,
|
|
3290
|
+
partialTemplates: emit?.partialTemplates ?? true
|
|
3291
|
+
});
|
|
3164
3292
|
emitInto(path, inlineTemplates(code, templates), imports);
|
|
3165
3293
|
}
|
|
3166
3294
|
});
|
|
3167
3295
|
return changed ? file.program.body[0].expression : node;
|
|
3168
3296
|
}
|
|
3169
|
-
function genExpr(node, used, onNested) {
|
|
3170
|
-
return gen2(transformNestedJSX(node, used, onNested));
|
|
3297
|
+
function genExpr(node, used, onNested, emit) {
|
|
3298
|
+
return gen2(transformNestedJSX(node, used, onNested, emit));
|
|
3171
3299
|
}
|
|
3172
3300
|
function isReactiveExpr(node) {
|
|
3173
3301
|
return isReactiveShape(shapeOf(node));
|
|
3174
3302
|
}
|
|
3175
|
-
function buildIR(node, used = /* @__PURE__ */ new Set(), onNested) {
|
|
3303
|
+
function buildIR(node, used = /* @__PURE__ */ new Set(), onNested, emit) {
|
|
3176
3304
|
const ir = buildJsxIR(node, {
|
|
3177
3305
|
code: (n) => (
|
|
3178
3306
|
// A member-expression tag (`<ns.Foo/>`) is not an Expression, so it cannot go
|
|
3179
3307
|
// through the nested-JSX compile: it only ever needs printing.
|
|
3180
|
-
n.type === "JSXMemberExpression" ? gen2(n) : genExpr(n, used, onNested)
|
|
3308
|
+
n.type === "JSXMemberExpression" ? gen2(n) : genExpr(n, used, onNested, emit)
|
|
3181
3309
|
),
|
|
3182
3310
|
used
|
|
3183
3311
|
});
|
|
@@ -3250,7 +3378,10 @@ function adoptTemplates(code, templates, state) {
|
|
|
3250
3378
|
}
|
|
3251
3379
|
function emitViaIR(node, state) {
|
|
3252
3380
|
const used = /* @__PURE__ */ new Set();
|
|
3253
|
-
const ir = buildIR(node, used, nestedHook(state)
|
|
3381
|
+
const ir = buildIR(node, used, nestedHook(state), {
|
|
3382
|
+
partialTemplates: state.partialTemplates,
|
|
3383
|
+
templateClone: state.templateClone
|
|
3384
|
+
});
|
|
3254
3385
|
resolveComponentSources(ir, {
|
|
3255
3386
|
resolver: state.componentResolver,
|
|
3256
3387
|
modules: {
|
|
@@ -3299,7 +3430,11 @@ function dedupeImports(imports) {
|
|
|
3299
3430
|
function emitHtmlViaIR(node, state) {
|
|
3300
3431
|
const used = /* @__PURE__ */ new Set();
|
|
3301
3432
|
const svg = import_core3.types.isIdentifier(node.tag) && node.tag.name === "svg";
|
|
3302
|
-
const ir = buildIRFromHtml(node, used, {
|
|
3433
|
+
const ir = buildIRFromHtml(node, used, {
|
|
3434
|
+
svg,
|
|
3435
|
+
onNested: nestedHook(state),
|
|
3436
|
+
emit: { partialTemplates: state.partialTemplates, templateClone: state.templateClone }
|
|
3437
|
+
});
|
|
3303
3438
|
resolveComponentSources(ir, {
|
|
3304
3439
|
resolver: state.componentResolver,
|
|
3305
3440
|
modules: {
|
|
@@ -3694,7 +3829,7 @@ function createPreset(options = {}) {
|
|
|
3694
3829
|
{
|
|
3695
3830
|
runtime: "automatic",
|
|
3696
3831
|
importSource: "@fluixi/jsx",
|
|
3697
|
-
development:
|
|
3832
|
+
development: process.env.NODE_ENV === "development",
|
|
3698
3833
|
detectReactivity: true,
|
|
3699
3834
|
useHtmlTag: true,
|
|
3700
3835
|
hoistStatics: true,
|
|
@@ -4488,11 +4623,8 @@ function transformTemplates(code, id, options = {}) {
|
|
|
4488
4623
|
const hoisted = /* @__PURE__ */ new Map();
|
|
4489
4624
|
const edits = [...props.edits, ...intrinsics.edits, ...sources.edits, ...styles?.edits ?? []];
|
|
4490
4625
|
for (const node of found) {
|
|
4491
|
-
const nested = found.some(
|
|
4492
|
-
(o) => o !== node && o.start <= node.start && o.end >= node.end && o.end - o.start > node.end - node.start
|
|
4493
|
-
);
|
|
4494
4626
|
if (isJsx(node)) {
|
|
4495
|
-
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits,
|
|
4627
|
+
edits.push({ start: node.start, end: node.end, code: compileJsx(code, node, edits, used, needs, hoisted, options, sourceName, styles) });
|
|
4496
4628
|
continue;
|
|
4497
4629
|
}
|
|
4498
4630
|
const holes = node.quasi.expressions.map(
|
|
@@ -4519,7 +4651,7 @@ function transformTemplates(code, id, options = {}) {
|
|
|
4519
4651
|
...options.sourceLocations === true ? { sourceFile: sourceName, positionAt: positionsIn(code) } : {},
|
|
4520
4652
|
// Same defaults as the plugin, so moving a build over is not a rendering change.
|
|
4521
4653
|
templateClone: options.templateClone ?? true,
|
|
4522
|
-
partialTemplates:
|
|
4654
|
+
partialTemplates: options.partialTemplates ?? true,
|
|
4523
4655
|
svg: templateTags.get(node.tag.name) === "svg"
|
|
4524
4656
|
});
|
|
4525
4657
|
for (const symbol of result.imports) used.add(symbol);
|
|
@@ -4591,7 +4723,7 @@ function transformTemplates(code, id, options = {}) {
|
|
|
4591
4723
|
...styles?.references.length ? { styleReferences: styles.references } : {}
|
|
4592
4724
|
};
|
|
4593
4725
|
}
|
|
4594
|
-
function compileJsx(code, node, edits,
|
|
4726
|
+
function compileJsx(code, node, edits, used, needs, hoisted, options, sourceFile, styles) {
|
|
4595
4727
|
const ir = buildJsxIR(node, {
|
|
4596
4728
|
code: (n) => slice(code, n.start, n.end, edits),
|
|
4597
4729
|
used,
|
|
@@ -4616,7 +4748,7 @@ function compileJsx(code, node, edits, nested, used, needs, hoisted, options, so
|
|
|
4616
4748
|
collapseStrategies(ir);
|
|
4617
4749
|
const emitted = imperativeBackend.emit(ir, {
|
|
4618
4750
|
templateClone: options.templateClone ?? true,
|
|
4619
|
-
partialTemplates:
|
|
4751
|
+
partialTemplates: options.partialTemplates ?? true
|
|
4620
4752
|
});
|
|
4621
4753
|
for (const symbol of emitted.imports) used.add(symbol);
|
|
4622
4754
|
collectNeeds(ir, needs);
|
package/dist/integrations.mjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.106 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
import {
|
|
3
3
|
styleIds
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-W7DYOMXJ.mjs";
|
|
5
5
|
import {
|
|
6
6
|
INTRINSICS,
|
|
7
7
|
TAG_INTRINSICS,
|
|
8
8
|
builtinComponentMap,
|
|
9
9
|
createComponentResolver
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-TDN5MYWI.mjs";
|
|
11
|
+
import "./chunk-JUFI6IR3.mjs";
|
|
12
12
|
import {
|
|
13
13
|
__require
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-4XEOMQ57.mjs";
|
|
15
15
|
|
|
16
16
|
// src/resolve/write-globals.ts
|
|
17
17
|
import { mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
@@ -432,7 +432,7 @@ import { dirname as dirname3, join as _join, resolve as resolvePath2 } from "nod
|
|
|
432
432
|
async function createBabelPlugin(options = {}) {
|
|
433
433
|
let pluginModule = null;
|
|
434
434
|
try {
|
|
435
|
-
pluginModule = await import("./babel-
|
|
435
|
+
pluginModule = await import("./babel-HJY4RVAV.mjs");
|
|
436
436
|
} catch (e) {
|
|
437
437
|
console.warn("Could not load the babel front-end:", e);
|
|
438
438
|
}
|
|
@@ -521,7 +521,7 @@ function createVitePlugin(options = {}) {
|
|
|
521
521
|
const entry = config?.command === "build" && config.build?.lib ? config.build.lib.entry : void 0;
|
|
522
522
|
const first = typeof entry === "string" ? entry : Array.isArray(entry) ? entry[0] : entry && typeof entry === "object" ? Object.values(entry)[0] : void 0;
|
|
523
523
|
if (typeof first === "string") componentStyles.setLibrary(dirname3(resolvePath2(config.root ?? process.cwd(), first)));
|
|
524
|
-
if (componentStyles.active) ({ transformTemplates } = await import("./transform-
|
|
524
|
+
if (componentStyles.active) ({ transformTemplates } = await import("./transform-NO46NFQH.mjs"));
|
|
525
525
|
},
|
|
526
526
|
generateBundle() {
|
|
527
527
|
for (const [fileName, source] of componentStyles.libraryFiles()) this.emitFile({ type: "asset", fileName, source });
|
|
@@ -639,7 +639,7 @@ function transformOptions(options, id) {
|
|
|
639
639
|
}
|
|
640
640
|
async function rewriteProps(code, id, options) {
|
|
641
641
|
if (options.propsDestructure === false) return code;
|
|
642
|
-
const { transformProps } = await import("./transform-
|
|
642
|
+
const { transformProps } = await import("./transform-NO46NFQH.mjs");
|
|
643
643
|
const result = transformProps(code, id);
|
|
644
644
|
reportDiagnostics({ propsDiagnostics: result.diagnostics }, id);
|
|
645
645
|
return result.rewritten > 0 ? result.code : code;
|
|
@@ -663,7 +663,7 @@ function reportDiagnostics(result, id) {
|
|
|
663
663
|
}
|
|
664
664
|
async function compileModule(code, id, options) {
|
|
665
665
|
if (!options.babel) {
|
|
666
|
-
const { transformTemplates } = await import("./transform-
|
|
666
|
+
const { transformTemplates } = await import("./transform-NO46NFQH.mjs");
|
|
667
667
|
const result2 = transformTemplates(code, id, transformOptions(options, id));
|
|
668
668
|
reportDiagnostics(result2, id);
|
|
669
669
|
return result2;
|
|
@@ -782,10 +782,10 @@ export { isServerFnRequest, handleServerFn } from '@fluixi/start/server-fn';
|
|
|
782
782
|
if (!code.includes("use server")) return null;
|
|
783
783
|
const args = { ssr: !!opts?.ssr, filename: id, root };
|
|
784
784
|
if (options.babel) {
|
|
785
|
-
const { transformServerFunctions } = await import("./server-functions-
|
|
785
|
+
const { transformServerFunctions } = await import("./server-functions-4KTFFEO3.mjs");
|
|
786
786
|
return transformServerFunctions(code, args);
|
|
787
787
|
}
|
|
788
|
-
const { transformServerFns } = await import("./server-fns-
|
|
788
|
+
const { transformServerFns } = await import("./server-fns-WZJK4BJE.mjs");
|
|
789
789
|
return transformServerFns(code, args);
|
|
790
790
|
}
|
|
791
791
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/compiler v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/compiler v1.0.0-alpha.106 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -382,10 +382,64 @@ function isHole(node) {
|
|
|
382
382
|
function isTemplateChild(node) {
|
|
383
383
|
return node.kind === "text" || node.kind === "element" && isTemplateElement(node);
|
|
384
384
|
}
|
|
385
|
+
var PROPERTY_BINDS = /* @__PURE__ */ new Set(["indeterminate"]);
|
|
386
|
+
function disposition(prop) {
|
|
387
|
+
if (prop.kind === "spread") return null;
|
|
388
|
+
if (prop.name === "ref") return "ref";
|
|
389
|
+
if (prop.name === "use") return "use";
|
|
390
|
+
if (prop.kind === "event") return prop.event ? "event" : null;
|
|
391
|
+
if (prop.kind === "prop") return "property";
|
|
392
|
+
if (prop.kind !== "attr") return null;
|
|
393
|
+
const name = prop.name;
|
|
394
|
+
if (name.startsWith("on:")) return "nativeEvent";
|
|
395
|
+
if (name.startsWith("prop:")) return "property";
|
|
396
|
+
if (name.startsWith("attr:")) return "attr";
|
|
397
|
+
if (name.startsWith("bool:")) return "boolAttr";
|
|
398
|
+
if (name === "className" || name === "class") {
|
|
399
|
+
return isPlainLiteralAttr(prop) ? "serialize" : "class";
|
|
400
|
+
}
|
|
401
|
+
if (name === "classList") {
|
|
402
|
+
if (isPlainLiteralAttr(prop)) return "serialize";
|
|
403
|
+
return prop.reactive ? "classListDynamic" : "classList";
|
|
404
|
+
}
|
|
405
|
+
if (name === "style") {
|
|
406
|
+
if (isPlainLiteralAttr(prop)) return "serialize";
|
|
407
|
+
return prop.reactive ? "styleDynamic" : "style";
|
|
408
|
+
}
|
|
409
|
+
if (name.includes(":")) return null;
|
|
410
|
+
if (PROPERTY_ONLY.has(name)) return null;
|
|
411
|
+
if (PROPERTY_BINDS.has(name)) return "property";
|
|
412
|
+
if (prop.expr === void 0) return isPlainLiteralAttr(prop) ? "serialize" : null;
|
|
413
|
+
return "attr";
|
|
414
|
+
}
|
|
415
|
+
function effectiveProps(el) {
|
|
416
|
+
const order = [];
|
|
417
|
+
const byName = /* @__PURE__ */ new Map();
|
|
418
|
+
for (const prop of el.props) {
|
|
419
|
+
if (!byName.has(prop.name)) order.push(prop.name);
|
|
420
|
+
byName.set(prop.name, prop);
|
|
421
|
+
}
|
|
422
|
+
return order.map((name) => byName.get(name));
|
|
423
|
+
}
|
|
424
|
+
function propPlan(el) {
|
|
425
|
+
const custom = el.tag.includes("-");
|
|
426
|
+
const plan = { serialize: [], bindings: [] };
|
|
427
|
+
for (const prop of effectiveProps(el)) {
|
|
428
|
+
const kind = disposition(prop);
|
|
429
|
+
if (kind === null) return null;
|
|
430
|
+
if (kind === "serialize") {
|
|
431
|
+
plan.serialize.push(prop);
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
if (custom) return null;
|
|
435
|
+
plan.bindings.push({ prop, kind });
|
|
436
|
+
}
|
|
437
|
+
return plan;
|
|
438
|
+
}
|
|
385
439
|
function isTemplateElement(node) {
|
|
386
440
|
if (node.svg) return false;
|
|
387
441
|
if (isRawTextElement(node.tag)) return false;
|
|
388
|
-
if (!node
|
|
442
|
+
if (!propPlan(node)) return false;
|
|
389
443
|
return node.children.every((c) => isTemplateChild(c) || isHole(c));
|
|
390
444
|
}
|
|
391
445
|
function containsHole(node) {
|
|
@@ -393,6 +447,15 @@ function containsHole(node) {
|
|
|
393
447
|
const children = node.children;
|
|
394
448
|
return children ? children.some(containsHole) : false;
|
|
395
449
|
}
|
|
450
|
+
function containsBinding(node) {
|
|
451
|
+
if (node.kind !== "element") return false;
|
|
452
|
+
const plan = propPlan(node);
|
|
453
|
+
if (plan && plan.bindings.length > 0) return true;
|
|
454
|
+
return node.children.some(containsBinding);
|
|
455
|
+
}
|
|
456
|
+
function interesting(node) {
|
|
457
|
+
return containsHole(node) || containsBinding(node);
|
|
458
|
+
}
|
|
396
459
|
function addressable(el) {
|
|
397
460
|
for (let i = 0; i < el.children.length; i++) {
|
|
398
461
|
const child = el.children[i];
|
|
@@ -406,9 +469,10 @@ function addressable(el) {
|
|
|
406
469
|
function planPartialTemplate(root) {
|
|
407
470
|
if (!isTemplateElement(root)) return null;
|
|
408
471
|
if (!addressable(root)) return null;
|
|
409
|
-
if (!root
|
|
472
|
+
if (!interesting(root)) return null;
|
|
410
473
|
const steps = [];
|
|
411
474
|
const holes = [];
|
|
475
|
+
const bindings = [];
|
|
412
476
|
let refCount = 0;
|
|
413
477
|
const declare = (expr) => {
|
|
414
478
|
const ref = `_n$${refCount++}`;
|
|
@@ -416,11 +480,17 @@ function planPartialTemplate(root) {
|
|
|
416
480
|
return ref;
|
|
417
481
|
};
|
|
418
482
|
walk2(root, "_el$");
|
|
419
|
-
return { html: serializeWithMarkers(root), tag: root.tag, steps, holes };
|
|
483
|
+
return { html: serializeWithMarkers(root), tag: root.tag, steps, holes, bindings };
|
|
420
484
|
function walk2(el, elementRef) {
|
|
485
|
+
const plan = propPlan(el);
|
|
486
|
+
if (plan) {
|
|
487
|
+
for (const binding of plan.bindings) {
|
|
488
|
+
bindings.push({ ref: elementRef, prop: binding.prop, kind: binding.kind });
|
|
489
|
+
}
|
|
490
|
+
}
|
|
421
491
|
let last = -1;
|
|
422
492
|
el.children.forEach((child, i) => {
|
|
423
|
-
if (
|
|
493
|
+
if (interesting(child)) last = i;
|
|
424
494
|
});
|
|
425
495
|
let previous = null;
|
|
426
496
|
for (let i = 0; i <= last; i++) {
|
|
@@ -434,19 +504,21 @@ function planPartialTemplate(root) {
|
|
|
434
504
|
continue;
|
|
435
505
|
}
|
|
436
506
|
const ref = declare(expr);
|
|
437
|
-
if (child.kind === "element" &&
|
|
507
|
+
if (child.kind === "element" && interesting(child)) walk2(child, ref);
|
|
438
508
|
previous = ref;
|
|
439
509
|
}
|
|
440
510
|
}
|
|
441
511
|
}
|
|
442
512
|
function serializeWithMarkers(el) {
|
|
443
|
-
return serializeStatic(
|
|
513
|
+
return serializeStatic(templateTree(el)).split(SENTINEL).join(HOLE_START + HOLE_END);
|
|
444
514
|
}
|
|
445
|
-
function
|
|
515
|
+
function templateTree(el) {
|
|
516
|
+
const plan = propPlan(el);
|
|
446
517
|
return {
|
|
447
518
|
...el,
|
|
519
|
+
props: plan ? plan.serialize : [],
|
|
448
520
|
children: el.children.map(
|
|
449
|
-
(child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ?
|
|
521
|
+
(child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ? templateTree(child) : child
|
|
450
522
|
)
|
|
451
523
|
};
|
|
452
524
|
}
|
|
@@ -719,6 +791,55 @@ function emitComponent(name, props, children, used, templates, at) {
|
|
|
719
791
|
const mark = at ? `globalThis.${SOURCE_MARKER}?.(${JSON.stringify(at.file)},${at.line},${at.column},${JSON.stringify(name)}), ` : "";
|
|
720
792
|
return `createMemo(${paren(`${mark}() => createComponent(${name}, ${obj})`, "value")})`;
|
|
721
793
|
}
|
|
794
|
+
function bindingTarget(binding) {
|
|
795
|
+
const name = binding.prop.name;
|
|
796
|
+
if (binding.kind === "boolAttr") return name.slice("bool:".length);
|
|
797
|
+
if (name.startsWith("prop:")) return name.slice("prop:".length);
|
|
798
|
+
if (name.startsWith("attr:")) return name.slice("attr:".length);
|
|
799
|
+
return htmlAttrName(name);
|
|
800
|
+
}
|
|
801
|
+
function bindingStatement(binding, used) {
|
|
802
|
+
const { ref, prop, kind } = binding;
|
|
803
|
+
const value = propValue(prop);
|
|
804
|
+
switch (kind) {
|
|
805
|
+
case "class":
|
|
806
|
+
used.add("setClassName");
|
|
807
|
+
return `setClassName(${ref}, ${value});`;
|
|
808
|
+
case "classList":
|
|
809
|
+
used.add("setClassList");
|
|
810
|
+
return `setClassList(${ref}, ${value}, []);`;
|
|
811
|
+
case "classListDynamic":
|
|
812
|
+
used.add("setDynamicClassList");
|
|
813
|
+
return `setDynamicClassList(${ref}, ${value});`;
|
|
814
|
+
case "style":
|
|
815
|
+
used.add("setStyle");
|
|
816
|
+
return `setStyle(${ref}, ${value}, []);`;
|
|
817
|
+
case "styleDynamic":
|
|
818
|
+
used.add("setDynamicStyle");
|
|
819
|
+
return `setDynamicStyle(${ref}, ${value});`;
|
|
820
|
+
case "attr":
|
|
821
|
+
used.add("setDynamicAttribute");
|
|
822
|
+
return `setDynamicAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
823
|
+
case "property":
|
|
824
|
+
used.add("setDynamicProperty");
|
|
825
|
+
return `setDynamicProperty(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
826
|
+
case "boolAttr":
|
|
827
|
+
used.add("setDynamicBoolAttribute");
|
|
828
|
+
return `setDynamicBoolAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
|
|
829
|
+
case "event":
|
|
830
|
+
used.add("addDelegatedEventListener");
|
|
831
|
+
return `addDelegatedEventListener(${ref}, ${JSON.stringify(prop.event.name)}, ${value});`;
|
|
832
|
+
case "nativeEvent":
|
|
833
|
+
used.add("addNativeEventListener");
|
|
834
|
+
return `addNativeEventListener(${ref}, ${JSON.stringify(prop.name.slice(3))}, ${value});`;
|
|
835
|
+
case "ref":
|
|
836
|
+
used.add("handleRef");
|
|
837
|
+
return `handleRef(${value}, ${ref});`;
|
|
838
|
+
case "use":
|
|
839
|
+
used.add("applyUse");
|
|
840
|
+
return `applyUse(${ref}, ${value});`;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
722
843
|
function staticAttrAssignment(el, prop) {
|
|
723
844
|
const name = htmlAttrName(prop.name);
|
|
724
845
|
const value = prop.literal;
|
|
@@ -769,6 +890,7 @@ function emitNode(node, used, templates) {
|
|
|
769
890
|
`const _el$ = templateNode(${id}, ${JSON.stringify(plan.tag)}, true${at ? `, false, ${JSON.stringify(at)}` : ""});`
|
|
770
891
|
];
|
|
771
892
|
for (const step of plan.steps) lines.push(`const ${step.ref} = ${step.expr};`);
|
|
893
|
+
for (const binding of plan.bindings) lines.push(bindingStatement(binding, used));
|
|
772
894
|
for (const hole of plan.holes) {
|
|
773
895
|
lines.push(
|
|
774
896
|
`insert(${hole.parentRef}, holeScope(${hole.startRef}, () => ${paren(emitNode(hole.node, used, templates), "arrowBody")}), ${hole.endRef}, holeContent(${hole.startRef}, ${hole.endRef}));`
|