@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.
Files changed (71) hide show
  1. package/dist/analyze/static-graph.cjs +1 -1
  2. package/dist/analyze/static-graph.mjs +1 -1
  3. package/dist/{babel-USPHNEJF.mjs → babel-HJY4RVAV.mjs} +33 -20
  4. package/dist/{chunk-OQYQ7UTD.mjs → chunk-4XEOMQ57.mjs} +1 -1
  5. package/dist/{chunk-EK4OMGTU.mjs → chunk-JUFI6IR3.mjs} +1 -1
  6. package/dist/{chunk-5GAYDAAC.mjs → chunk-LCQHL2VQ.mjs} +132 -10
  7. package/dist/{chunk-XBAQME2V.mjs → chunk-LGUZRHYN.mjs} +2 -2
  8. package/dist/{chunk-O6OBEV4V.mjs → chunk-TDN5MYWI.mjs} +1 -1
  9. package/dist/{chunk-EQIIWIEU.mjs → chunk-W7DYOMXJ.mjs} +2 -2
  10. package/dist/{chunk-FMIIK5UM.mjs → chunk-WHEDRMNR.mjs} +1 -1
  11. package/dist/codegen/backends/imperative.cjs +130 -8
  12. package/dist/codegen/backends/imperative.d.ts.map +1 -1
  13. package/dist/codegen/backends/imperative.js +62 -0
  14. package/dist/codegen/backends/imperative.mjs +130 -8
  15. package/dist/codegen/partial-template.cjs +80 -8
  16. package/dist/codegen/partial-template.d.cts +21 -4
  17. package/dist/codegen/partial-template.d.ts +21 -4
  18. package/dist/codegen/partial-template.d.ts.map +1 -1
  19. package/dist/codegen/partial-template.js +0 -0
  20. package/dist/codegen/partial-template.mjs +80 -8
  21. package/dist/codegen/serialize-static.cjs +1 -0
  22. package/dist/codegen/serialize-static.d.cts +8 -0
  23. package/dist/codegen/serialize-static.d.ts +8 -0
  24. package/dist/codegen/serialize-static.d.ts.map +1 -1
  25. package/dist/codegen/serialize-static.js +1 -1
  26. package/dist/codegen/serialize-static.mjs +1 -0
  27. package/dist/frontend/babel/build-ir-html.cjs +149 -21
  28. package/dist/frontend/babel/build-ir-html.d.cts +3 -1
  29. package/dist/frontend/babel/build-ir-html.d.ts +3 -1
  30. package/dist/frontend/babel/build-ir-html.d.ts.map +1 -1
  31. package/dist/frontend/babel/build-ir-html.mjs +149 -21
  32. package/dist/frontend/babel/build-ir.cjs +149 -21
  33. package/dist/frontend/babel/build-ir.d.cts +11 -2
  34. package/dist/frontend/babel/build-ir.d.ts +11 -2
  35. package/dist/frontend/babel/build-ir.d.ts.map +1 -1
  36. package/dist/frontend/babel/build-ir.js +15 -9
  37. package/dist/frontend/babel/build-ir.mjs +149 -21
  38. package/dist/frontend/babel/index.cjs +160 -25
  39. package/dist/frontend/babel/index.mjs +160 -25
  40. package/dist/frontend/babel/lower-template.cjs +149 -21
  41. package/dist/frontend/babel/lower-template.d.cts +2 -1
  42. package/dist/frontend/babel/lower-template.d.ts +2 -1
  43. package/dist/frontend/babel/lower-template.d.ts.map +1 -1
  44. package/dist/frontend/babel/lower-template.js +4 -4
  45. package/dist/frontend/babel/lower-template.mjs +149 -21
  46. package/dist/frontend/babel/plugin.cjs +158 -23
  47. package/dist/frontend/babel/plugin.js +9 -2
  48. package/dist/frontend/babel/plugin.mjs +158 -23
  49. package/dist/index.cjs +131 -9
  50. package/dist/index.mjs +131 -9
  51. package/dist/integrations.cjs +165 -33
  52. package/dist/integrations.mjs +11 -11
  53. package/dist/lower/compile-template.cjs +131 -9
  54. package/dist/lower/compile-template.mjs +131 -9
  55. package/dist/lower/jsx.cjs +130 -8
  56. package/dist/lower/jsx.mjs +130 -8
  57. package/dist/lower/template.cjs +130 -8
  58. package/dist/lower/template.mjs +130 -8
  59. package/dist/resolve/builtins.cjs +1 -1
  60. package/dist/resolve/builtins.mjs +1 -1
  61. package/dist/{server-fns-7Y25MR3B.mjs → server-fns-WZJK4BJE.mjs} +5 -5
  62. package/dist/{server-functions-43CFKXY3.mjs → server-functions-4KTFFEO3.mjs} +3 -3
  63. package/dist/transform/index.cjs +135 -16
  64. package/dist/transform/index.mjs +135 -16
  65. package/dist/transform/templates.cjs +134 -15
  66. package/dist/transform/templates.d.ts.map +1 -1
  67. package/dist/transform/templates.js +4 -8
  68. package/dist/transform/templates.mjs +134 -15
  69. package/dist/{transform-YUDW7K4J.mjs → transform-NO46NFQH.mjs} +11 -14
  70. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  71. package/package.json +4 -4
@@ -177,10 +177,64 @@ function isHole(node) {
177
177
  function isTemplateChild(node) {
178
178
  return node.kind === "text" || node.kind === "element" && isTemplateElement(node);
179
179
  }
180
+ var PROPERTY_BINDS = /* @__PURE__ */ new Set(["indeterminate"]);
181
+ function disposition(prop) {
182
+ if (prop.kind === "spread") return null;
183
+ if (prop.name === "ref") return "ref";
184
+ if (prop.name === "use") return "use";
185
+ if (prop.kind === "event") return prop.event ? "event" : null;
186
+ if (prop.kind === "prop") return "property";
187
+ if (prop.kind !== "attr") return null;
188
+ const name = prop.name;
189
+ if (name.startsWith("on:")) return "nativeEvent";
190
+ if (name.startsWith("prop:")) return "property";
191
+ if (name.startsWith("attr:")) return "attr";
192
+ if (name.startsWith("bool:")) return "boolAttr";
193
+ if (name === "className" || name === "class") {
194
+ return isPlainLiteralAttr(prop) ? "serialize" : "class";
195
+ }
196
+ if (name === "classList") {
197
+ if (isPlainLiteralAttr(prop)) return "serialize";
198
+ return prop.reactive ? "classListDynamic" : "classList";
199
+ }
200
+ if (name === "style") {
201
+ if (isPlainLiteralAttr(prop)) return "serialize";
202
+ return prop.reactive ? "styleDynamic" : "style";
203
+ }
204
+ if (name.includes(":")) return null;
205
+ if (PROPERTY_ONLY.has(name)) return null;
206
+ if (PROPERTY_BINDS.has(name)) return "property";
207
+ if (prop.expr === void 0) return isPlainLiteralAttr(prop) ? "serialize" : null;
208
+ return "attr";
209
+ }
210
+ function effectiveProps(el) {
211
+ const order = [];
212
+ const byName = /* @__PURE__ */ new Map();
213
+ for (const prop of el.props) {
214
+ if (!byName.has(prop.name)) order.push(prop.name);
215
+ byName.set(prop.name, prop);
216
+ }
217
+ return order.map((name) => byName.get(name));
218
+ }
219
+ function propPlan(el) {
220
+ const custom = el.tag.includes("-");
221
+ const plan = { serialize: [], bindings: [] };
222
+ for (const prop of effectiveProps(el)) {
223
+ const kind = disposition(prop);
224
+ if (kind === null) return null;
225
+ if (kind === "serialize") {
226
+ plan.serialize.push(prop);
227
+ continue;
228
+ }
229
+ if (custom) return null;
230
+ plan.bindings.push({ prop, kind });
231
+ }
232
+ return plan;
233
+ }
180
234
  function isTemplateElement(node) {
181
235
  if (node.svg) return false;
182
236
  if (isRawTextElement(node.tag)) return false;
183
- if (!node.props.every((p) => isPlainLiteralAttr(p))) return false;
237
+ if (!propPlan(node)) return false;
184
238
  return node.children.every((c) => isTemplateChild(c) || isHole(c));
185
239
  }
186
240
  function containsHole(node) {
@@ -188,6 +242,15 @@ function containsHole(node) {
188
242
  const children = node.children;
189
243
  return children ? children.some(containsHole) : false;
190
244
  }
245
+ function containsBinding(node) {
246
+ if (node.kind !== "element") return false;
247
+ const plan = propPlan(node);
248
+ if (plan && plan.bindings.length > 0) return true;
249
+ return node.children.some(containsBinding);
250
+ }
251
+ function interesting(node) {
252
+ return containsHole(node) || containsBinding(node);
253
+ }
191
254
  function addressable(el) {
192
255
  for (let i = 0; i < el.children.length; i++) {
193
256
  const child = el.children[i];
@@ -201,9 +264,10 @@ function addressable(el) {
201
264
  function planPartialTemplate(root) {
202
265
  if (!isTemplateElement(root)) return null;
203
266
  if (!addressable(root)) return null;
204
- if (!root.children.some(containsHole)) return null;
267
+ if (!interesting(root)) return null;
205
268
  const steps = [];
206
269
  const holes = [];
270
+ const bindings = [];
207
271
  let refCount = 0;
208
272
  const declare = (expr) => {
209
273
  const ref = `_n$${refCount++}`;
@@ -211,11 +275,17 @@ function planPartialTemplate(root) {
211
275
  return ref;
212
276
  };
213
277
  walk(root, "_el$");
214
- return { html: serializeWithMarkers(root), tag: root.tag, steps, holes };
278
+ return { html: serializeWithMarkers(root), tag: root.tag, steps, holes, bindings };
215
279
  function walk(el, elementRef) {
280
+ const plan = propPlan(el);
281
+ if (plan) {
282
+ for (const binding of plan.bindings) {
283
+ bindings.push({ ref: elementRef, prop: binding.prop, kind: binding.kind });
284
+ }
285
+ }
216
286
  let last = -1;
217
287
  el.children.forEach((child, i) => {
218
- if (containsHole(child)) last = i;
288
+ if (interesting(child)) last = i;
219
289
  });
220
290
  let previous = null;
221
291
  for (let i = 0; i <= last; i++) {
@@ -229,19 +299,21 @@ function planPartialTemplate(root) {
229
299
  continue;
230
300
  }
231
301
  const ref = declare(expr);
232
- if (child.kind === "element" && containsHole(child)) walk(child, ref);
302
+ if (child.kind === "element" && interesting(child)) walk(child, ref);
233
303
  previous = ref;
234
304
  }
235
305
  }
236
306
  }
237
307
  function serializeWithMarkers(el) {
238
- return serializeStatic(withSentinels(el)).split(SENTINEL).join(HOLE_START + HOLE_END);
308
+ return serializeStatic(templateTree(el)).split(SENTINEL).join(HOLE_START + HOLE_END);
239
309
  }
240
- function withSentinels(el) {
310
+ function templateTree(el) {
311
+ const plan = propPlan(el);
241
312
  return {
242
313
  ...el,
314
+ props: plan ? plan.serialize : [],
243
315
  children: el.children.map(
244
- (child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ? withSentinels(child) : child
316
+ (child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ? templateTree(child) : child
245
317
  )
246
318
  };
247
319
  }
@@ -514,6 +586,55 @@ function emitComponent(name, props, children, used, templates, at) {
514
586
  const mark = at ? `globalThis.${SOURCE_MARKER}?.(${JSON.stringify(at.file)},${at.line},${at.column},${JSON.stringify(name)}), ` : "";
515
587
  return `createMemo(${paren(`${mark}() => createComponent(${name}, ${obj})`, "value")})`;
516
588
  }
589
+ function bindingTarget(binding) {
590
+ const name = binding.prop.name;
591
+ if (binding.kind === "boolAttr") return name.slice("bool:".length);
592
+ if (name.startsWith("prop:")) return name.slice("prop:".length);
593
+ if (name.startsWith("attr:")) return name.slice("attr:".length);
594
+ return htmlAttrName(name);
595
+ }
596
+ function bindingStatement(binding, used) {
597
+ const { ref, prop, kind } = binding;
598
+ const value = propValue(prop);
599
+ switch (kind) {
600
+ case "class":
601
+ used.add("setClassName");
602
+ return `setClassName(${ref}, ${value});`;
603
+ case "classList":
604
+ used.add("setClassList");
605
+ return `setClassList(${ref}, ${value}, []);`;
606
+ case "classListDynamic":
607
+ used.add("setDynamicClassList");
608
+ return `setDynamicClassList(${ref}, ${value});`;
609
+ case "style":
610
+ used.add("setStyle");
611
+ return `setStyle(${ref}, ${value}, []);`;
612
+ case "styleDynamic":
613
+ used.add("setDynamicStyle");
614
+ return `setDynamicStyle(${ref}, ${value});`;
615
+ case "attr":
616
+ used.add("setDynamicAttribute");
617
+ return `setDynamicAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
618
+ case "property":
619
+ used.add("setDynamicProperty");
620
+ return `setDynamicProperty(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
621
+ case "boolAttr":
622
+ used.add("setDynamicBoolAttribute");
623
+ return `setDynamicBoolAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
624
+ case "event":
625
+ used.add("addDelegatedEventListener");
626
+ return `addDelegatedEventListener(${ref}, ${JSON.stringify(prop.event.name)}, ${value});`;
627
+ case "nativeEvent":
628
+ used.add("addNativeEventListener");
629
+ return `addNativeEventListener(${ref}, ${JSON.stringify(prop.name.slice(3))}, ${value});`;
630
+ case "ref":
631
+ used.add("handleRef");
632
+ return `handleRef(${value}, ${ref});`;
633
+ case "use":
634
+ used.add("applyUse");
635
+ return `applyUse(${ref}, ${value});`;
636
+ }
637
+ }
517
638
  function staticAttrAssignment(el, prop) {
518
639
  const name = htmlAttrName(prop.name);
519
640
  const value = prop.literal;
@@ -564,6 +685,7 @@ function emitNode(node, used, templates) {
564
685
  `const _el$ = templateNode(${id}, ${JSON.stringify(plan.tag)}, true${at ? `, false, ${JSON.stringify(at)}` : ""});`
565
686
  ];
566
687
  for (const step of plan.steps) lines.push(`const ${step.ref} = ${step.expr};`);
688
+ for (const binding of plan.bindings) lines.push(bindingStatement(binding, used));
567
689
  for (const hole of plan.holes) {
568
690
  lines.push(
569
691
  `insert(${hole.parentRef}, holeScope(${hole.startRef}, () => ${paren(emitNode(hole.node, used, templates), "arrowBody")}), ${hole.endRef}, holeContent(${hole.startRef}, ${hole.endRef}));`
@@ -155,10 +155,64 @@ function isHole(node) {
155
155
  function isTemplateChild(node) {
156
156
  return node.kind === "text" || node.kind === "element" && isTemplateElement(node);
157
157
  }
158
+ var PROPERTY_BINDS = /* @__PURE__ */ new Set(["indeterminate"]);
159
+ function disposition(prop) {
160
+ if (prop.kind === "spread") return null;
161
+ if (prop.name === "ref") return "ref";
162
+ if (prop.name === "use") return "use";
163
+ if (prop.kind === "event") return prop.event ? "event" : null;
164
+ if (prop.kind === "prop") return "property";
165
+ if (prop.kind !== "attr") return null;
166
+ const name = prop.name;
167
+ if (name.startsWith("on:")) return "nativeEvent";
168
+ if (name.startsWith("prop:")) return "property";
169
+ if (name.startsWith("attr:")) return "attr";
170
+ if (name.startsWith("bool:")) return "boolAttr";
171
+ if (name === "className" || name === "class") {
172
+ return isPlainLiteralAttr(prop) ? "serialize" : "class";
173
+ }
174
+ if (name === "classList") {
175
+ if (isPlainLiteralAttr(prop)) return "serialize";
176
+ return prop.reactive ? "classListDynamic" : "classList";
177
+ }
178
+ if (name === "style") {
179
+ if (isPlainLiteralAttr(prop)) return "serialize";
180
+ return prop.reactive ? "styleDynamic" : "style";
181
+ }
182
+ if (name.includes(":")) return null;
183
+ if (PROPERTY_ONLY.has(name)) return null;
184
+ if (PROPERTY_BINDS.has(name)) return "property";
185
+ if (prop.expr === void 0) return isPlainLiteralAttr(prop) ? "serialize" : null;
186
+ return "attr";
187
+ }
188
+ function effectiveProps(el) {
189
+ const order = [];
190
+ const byName = /* @__PURE__ */ new Map();
191
+ for (const prop of el.props) {
192
+ if (!byName.has(prop.name)) order.push(prop.name);
193
+ byName.set(prop.name, prop);
194
+ }
195
+ return order.map((name) => byName.get(name));
196
+ }
197
+ function propPlan(el) {
198
+ const custom = el.tag.includes("-");
199
+ const plan = { serialize: [], bindings: [] };
200
+ for (const prop of effectiveProps(el)) {
201
+ const kind = disposition(prop);
202
+ if (kind === null) return null;
203
+ if (kind === "serialize") {
204
+ plan.serialize.push(prop);
205
+ continue;
206
+ }
207
+ if (custom) return null;
208
+ plan.bindings.push({ prop, kind });
209
+ }
210
+ return plan;
211
+ }
158
212
  function isTemplateElement(node) {
159
213
  if (node.svg) return false;
160
214
  if (isRawTextElement(node.tag)) return false;
161
- if (!node.props.every((p) => isPlainLiteralAttr(p))) return false;
215
+ if (!propPlan(node)) return false;
162
216
  return node.children.every((c) => isTemplateChild(c) || isHole(c));
163
217
  }
164
218
  function containsHole(node) {
@@ -166,6 +220,15 @@ function containsHole(node) {
166
220
  const children = node.children;
167
221
  return children ? children.some(containsHole) : false;
168
222
  }
223
+ function containsBinding(node) {
224
+ if (node.kind !== "element") return false;
225
+ const plan = propPlan(node);
226
+ if (plan && plan.bindings.length > 0) return true;
227
+ return node.children.some(containsBinding);
228
+ }
229
+ function interesting(node) {
230
+ return containsHole(node) || containsBinding(node);
231
+ }
169
232
  function addressable(el) {
170
233
  for (let i = 0; i < el.children.length; i++) {
171
234
  const child = el.children[i];
@@ -179,9 +242,10 @@ function addressable(el) {
179
242
  function planPartialTemplate(root) {
180
243
  if (!isTemplateElement(root)) return null;
181
244
  if (!addressable(root)) return null;
182
- if (!root.children.some(containsHole)) return null;
245
+ if (!interesting(root)) return null;
183
246
  const steps = [];
184
247
  const holes = [];
248
+ const bindings = [];
185
249
  let refCount = 0;
186
250
  const declare = (expr) => {
187
251
  const ref = `_n$${refCount++}`;
@@ -189,11 +253,17 @@ function planPartialTemplate(root) {
189
253
  return ref;
190
254
  };
191
255
  walk(root, "_el$");
192
- return { html: serializeWithMarkers(root), tag: root.tag, steps, holes };
256
+ return { html: serializeWithMarkers(root), tag: root.tag, steps, holes, bindings };
193
257
  function walk(el, elementRef) {
258
+ const plan = propPlan(el);
259
+ if (plan) {
260
+ for (const binding of plan.bindings) {
261
+ bindings.push({ ref: elementRef, prop: binding.prop, kind: binding.kind });
262
+ }
263
+ }
194
264
  let last = -1;
195
265
  el.children.forEach((child, i) => {
196
- if (containsHole(child)) last = i;
266
+ if (interesting(child)) last = i;
197
267
  });
198
268
  let previous = null;
199
269
  for (let i = 0; i <= last; i++) {
@@ -207,19 +277,21 @@ function planPartialTemplate(root) {
207
277
  continue;
208
278
  }
209
279
  const ref = declare(expr);
210
- if (child.kind === "element" && containsHole(child)) walk(child, ref);
280
+ if (child.kind === "element" && interesting(child)) walk(child, ref);
211
281
  previous = ref;
212
282
  }
213
283
  }
214
284
  }
215
285
  function serializeWithMarkers(el) {
216
- return serializeStatic(withSentinels(el)).split(SENTINEL).join(HOLE_START + HOLE_END);
286
+ return serializeStatic(templateTree(el)).split(SENTINEL).join(HOLE_START + HOLE_END);
217
287
  }
218
- function withSentinels(el) {
288
+ function templateTree(el) {
289
+ const plan = propPlan(el);
219
290
  return {
220
291
  ...el,
292
+ props: plan ? plan.serialize : [],
221
293
  children: el.children.map(
222
- (child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ? withSentinels(child) : child
294
+ (child) => isHole(child) ? { kind: "text", value: SENTINEL } : child.kind === "element" ? templateTree(child) : child
223
295
  )
224
296
  };
225
297
  }
@@ -492,6 +564,55 @@ function emitComponent(name, props, children, used, templates, at) {
492
564
  const mark = at ? `globalThis.${SOURCE_MARKER}?.(${JSON.stringify(at.file)},${at.line},${at.column},${JSON.stringify(name)}), ` : "";
493
565
  return `createMemo(${paren(`${mark}() => createComponent(${name}, ${obj})`, "value")})`;
494
566
  }
567
+ function bindingTarget(binding) {
568
+ const name = binding.prop.name;
569
+ if (binding.kind === "boolAttr") return name.slice("bool:".length);
570
+ if (name.startsWith("prop:")) return name.slice("prop:".length);
571
+ if (name.startsWith("attr:")) return name.slice("attr:".length);
572
+ return htmlAttrName(name);
573
+ }
574
+ function bindingStatement(binding, used) {
575
+ const { ref, prop, kind } = binding;
576
+ const value = propValue(prop);
577
+ switch (kind) {
578
+ case "class":
579
+ used.add("setClassName");
580
+ return `setClassName(${ref}, ${value});`;
581
+ case "classList":
582
+ used.add("setClassList");
583
+ return `setClassList(${ref}, ${value}, []);`;
584
+ case "classListDynamic":
585
+ used.add("setDynamicClassList");
586
+ return `setDynamicClassList(${ref}, ${value});`;
587
+ case "style":
588
+ used.add("setStyle");
589
+ return `setStyle(${ref}, ${value}, []);`;
590
+ case "styleDynamic":
591
+ used.add("setDynamicStyle");
592
+ return `setDynamicStyle(${ref}, ${value});`;
593
+ case "attr":
594
+ used.add("setDynamicAttribute");
595
+ return `setDynamicAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
596
+ case "property":
597
+ used.add("setDynamicProperty");
598
+ return `setDynamicProperty(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
599
+ case "boolAttr":
600
+ used.add("setDynamicBoolAttribute");
601
+ return `setDynamicBoolAttribute(${ref}, ${JSON.stringify(bindingTarget(binding))}, ${value});`;
602
+ case "event":
603
+ used.add("addDelegatedEventListener");
604
+ return `addDelegatedEventListener(${ref}, ${JSON.stringify(prop.event.name)}, ${value});`;
605
+ case "nativeEvent":
606
+ used.add("addNativeEventListener");
607
+ return `addNativeEventListener(${ref}, ${JSON.stringify(prop.name.slice(3))}, ${value});`;
608
+ case "ref":
609
+ used.add("handleRef");
610
+ return `handleRef(${value}, ${ref});`;
611
+ case "use":
612
+ used.add("applyUse");
613
+ return `applyUse(${ref}, ${value});`;
614
+ }
615
+ }
495
616
  function staticAttrAssignment(el, prop) {
496
617
  const name = htmlAttrName(prop.name);
497
618
  const value = prop.literal;
@@ -542,6 +663,7 @@ function emitNode(node, used, templates) {
542
663
  `const _el$ = templateNode(${id}, ${JSON.stringify(plan.tag)}, true${at ? `, false, ${JSON.stringify(at)}` : ""});`
543
664
  ];
544
665
  for (const step of plan.steps) lines.push(`const ${step.ref} = ${step.expr};`);
666
+ for (const binding of plan.bindings) lines.push(bindingStatement(binding, used));
545
667
  for (const hole of plan.holes) {
546
668
  lines.push(
547
669
  `insert(${hole.parentRef}, holeScope(${hole.startRef}, () => ${paren(emitNode(hole.node, used, templates), "arrowBody")}), ${hole.endRef}, holeContent(${hole.startRef}, ${hole.endRef}));`
@@ -1,4 +1,4 @@
1
- /*! @fluixi/compiler v1.0.0-alpha.105 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
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;
@@ -1,4 +1,4 @@
1
- /*! @fluixi/compiler v1.0.0-alpha.105 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/compiler v1.0.0-alpha.106 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
 
3
3
  // src/resolve/builtins.ts
4
4
  var DOM_CONTROL_FLOW = [
@@ -1,12 +1,12 @@
1
- /*! @fluixi/compiler v1.0.0-alpha.105 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/compiler v1.0.0-alpha.106 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
  import {
3
3
  MagicString
4
- } from "./chunk-XBAQME2V.mjs";
5
- import "./chunk-EK4OMGTU.mjs";
4
+ } from "./chunk-LGUZRHYN.mjs";
5
+ import "./chunk-JUFI6IR3.mjs";
6
6
  import {
7
7
  serverFnId
8
- } from "./chunk-FMIIK5UM.mjs";
9
- import "./chunk-OQYQ7UTD.mjs";
8
+ } from "./chunk-WHEDRMNR.mjs";
9
+ import "./chunk-4XEOMQ57.mjs";
10
10
 
11
11
  // src/transform/server-fns.ts
12
12
  import { parse } from "@babel/parser";
@@ -1,8 +1,8 @@
1
- /*! @fluixi/compiler v1.0.0-alpha.105 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/compiler v1.0.0-alpha.106 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
  import {
3
3
  serverFnId
4
- } from "./chunk-FMIIK5UM.mjs";
5
- import "./chunk-OQYQ7UTD.mjs";
4
+ } from "./chunk-WHEDRMNR.mjs";
5
+ import "./chunk-4XEOMQ57.mjs";
6
6
 
7
7
  // src/frontend/babel/server-functions.ts
8
8
  import { transformSync } from "@babel/core";