@fluixi/compiler 1.0.0-alpha.93 → 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.
Files changed (90) hide show
  1. package/dist/analyze/intrinsics.cjs +13 -1
  2. package/dist/analyze/intrinsics.d.cts +14 -0
  3. package/dist/analyze/intrinsics.d.ts +14 -0
  4. package/dist/analyze/intrinsics.d.ts.map +1 -1
  5. package/dist/analyze/intrinsics.js +17 -0
  6. package/dist/analyze/intrinsics.mjs +13 -1
  7. package/dist/analyze/static-graph.cjs +1 -1
  8. package/dist/analyze/static-graph.mjs +1 -1
  9. package/dist/{babel-RJHJQVEM.mjs → babel-RJFQVFJW.mjs} +4 -4
  10. package/dist/{chunk-56QSOVVL.mjs → chunk-DP2QDWWH.mjs} +1 -1
  11. package/dist/{chunk-R7PPFBCL.mjs → chunk-E2RWTIYE.mjs} +21 -15
  12. package/dist/{chunk-OD53TMER.mjs → chunk-HCCBEJEZ.mjs} +13 -1
  13. package/dist/{chunk-TJIH7TLX.mjs → chunk-HIZU7WI2.mjs} +1 -1
  14. package/dist/{chunk-U7HCFLZ2.mjs → chunk-ZR2QHTEX.mjs} +356 -24
  15. package/dist/codegen/backends/imperative.cjs +1 -1
  16. package/dist/codegen/backends/imperative.d.ts.map +1 -1
  17. package/dist/codegen/backends/imperative.js +2 -1
  18. package/dist/codegen/backends/imperative.mjs +1 -1
  19. package/dist/frontend/babel/build-ir-lit.cjs +352 -22
  20. package/dist/frontend/babel/build-ir-lit.mjs +352 -22
  21. package/dist/frontend/babel/build-ir.cjs +352 -22
  22. package/dist/frontend/babel/build-ir.mjs +352 -22
  23. package/dist/frontend/babel/index.cjs +353 -23
  24. package/dist/frontend/babel/index.mjs +353 -23
  25. package/dist/frontend/babel/lower-template.cjs +352 -22
  26. package/dist/frontend/babel/lower-template.mjs +352 -22
  27. package/dist/frontend/babel/plugin.cjs +352 -22
  28. package/dist/frontend/babel/plugin.mjs +352 -22
  29. package/dist/index.cjs +321 -22
  30. package/dist/index.mjs +333 -22
  31. package/dist/integrations.cjs +1174 -49
  32. package/dist/integrations.d.ts.map +1 -1
  33. package/dist/integrations.js +44 -2
  34. package/dist/integrations.mjs +205 -19
  35. package/dist/lower/compile-template.cjs +315 -21
  36. package/dist/lower/compile-template.d.cts +13 -0
  37. package/dist/lower/compile-template.d.ts +13 -0
  38. package/dist/lower/compile-template.d.ts.map +1 -1
  39. package/dist/lower/compile-template.js +3 -0
  40. package/dist/lower/compile-template.mjs +327 -21
  41. package/dist/lower/entities.cjs +288 -0
  42. package/dist/lower/entities.d.cts +1 -0
  43. package/dist/lower/entities.d.ts +2 -0
  44. package/dist/lower/entities.d.ts.map +1 -0
  45. package/dist/lower/entities.js +54 -0
  46. package/dist/lower/entities.mjs +267 -0
  47. package/dist/lower/jsx.cjs +104 -47
  48. package/dist/lower/jsx.d.cts +8 -0
  49. package/dist/lower/jsx.d.ts +8 -0
  50. package/dist/lower/jsx.d.ts.map +1 -1
  51. package/dist/lower/jsx.js +92 -2
  52. package/dist/lower/jsx.mjs +104 -47
  53. package/dist/lower/template.cjs +293 -20
  54. package/dist/lower/template.d.ts.map +1 -1
  55. package/dist/lower/template.js +35 -19
  56. package/dist/lower/template.mjs +293 -20
  57. package/dist/resolve/builtins.cjs +1 -1
  58. package/dist/resolve/builtins.mjs +1 -1
  59. package/dist/resolve/component-globals.cjs +6 -1
  60. package/dist/resolve/component-globals.js +2 -2
  61. package/dist/resolve/component-globals.mjs +6 -1
  62. package/dist/resolve/write-globals.cjs +6 -1
  63. package/dist/resolve/write-globals.mjs +6 -1
  64. package/dist/{server-fns-ZFRDIQ2X.mjs → server-fns-JLSTKWPS.mjs} +4 -4
  65. package/dist/{server-functions-CTDXX67X.mjs → server-functions-BGY3RD4R.mjs} +3 -3
  66. package/dist/transform/index.cjs +956 -33
  67. package/dist/transform/index.mjs +974 -47
  68. package/dist/transform/props.mjs +19 -14
  69. package/dist/transform/server-fns.mjs +19 -14
  70. package/dist/transform/styles.cjs +588 -0
  71. package/dist/transform/styles.d.cts +211 -0
  72. package/dist/transform/styles.d.ts +212 -0
  73. package/dist/transform/styles.d.ts.map +1 -0
  74. package/dist/transform/styles.js +714 -0
  75. package/dist/transform/styles.mjs +653 -0
  76. package/dist/transform/templates.cjs +955 -32
  77. package/dist/transform/templates.d.cts +13 -0
  78. package/dist/transform/templates.d.ts +13 -0
  79. package/dist/transform/templates.d.ts.map +1 -1
  80. package/dist/transform/templates.js +49 -12
  81. package/dist/transform/templates.mjs +973 -46
  82. package/dist/{transform-QWWQDCXE.mjs → transform-GBP6Y4UI.mjs} +601 -17
  83. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  84. package/dist/vite-styles.cjs +180 -0
  85. package/dist/vite-styles.d.cts +59 -0
  86. package/dist/vite-styles.d.ts +60 -0
  87. package/dist/vite-styles.d.ts.map +1 -0
  88. package/dist/vite-styles.js +198 -0
  89. package/dist/vite-styles.mjs +159 -0
  90. package/package.json +4 -3
@@ -1,4 +1,4 @@
1
- /*! @fluixi/compiler v1.0.0-alpha.93 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/compiler v1.0.0-alpha.94 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
  import {
3
3
  INTRINSICS,
4
4
  RESERVED_COMPONENTS,
@@ -7,7 +7,7 @@ import {
7
7
  builtinComponentMap,
8
8
  isIntrinsicName,
9
9
  isPrimitiveModule
10
- } from "./chunk-OD53TMER.mjs";
10
+ } from "./chunk-HCCBEJEZ.mjs";
11
11
 
12
12
  // src/analyze/expr-shape.ts
13
13
  var CALL = /* @__PURE__ */ new Set(["CallExpression", "OptionalCallExpression"]);
@@ -867,7 +867,7 @@ function emitComponent(name, props, children, used, templates, at) {
867
867
  }
868
868
  let obj = `{ ${bodies.map(([name2, body]) => `get ${propKey(name2)}() { return ${body}; }`).join(", ")} }`;
869
869
  if (bodies.some(([, body]) => /\bthis\b/.test(body))) {
870
- const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => ${body}`);
870
+ const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => (${body})`);
871
871
  const getters = bodies.map(([name2]) => `get ${propKey(name2)}() { return _$t[${JSON.stringify(name2)}](); }`);
872
872
  obj = `((_$t) => ({ ${getters.join(", ")} }))({ ${thunks.join(", ")} })`;
873
873
  }
@@ -1220,9 +1220,12 @@ function attrExprCode(attr, ctx) {
1220
1220
  }
1221
1221
  return null;
1222
1222
  }
1223
- function buildProps(attrs, ctx) {
1223
+ function buildProps(attrs, ctx, element = false) {
1224
1224
  const props = [];
1225
1225
  const usePairs = [];
1226
+ const classEntries = [];
1227
+ const styleEntries = [];
1228
+ let styleAt;
1226
1229
  for (const a of attrs) {
1227
1230
  if (a.type === "JSXSpreadAttribute") {
1228
1231
  props.push({ name: "", kind: "spread", expr: ctx.code(a.argument) });
@@ -1238,6 +1241,27 @@ function buildProps(attrs, ctx) {
1238
1241
  usePairs.push(opts != null ? `[${dir}, () => ${paren(opts, "arrowBody")}]` : `[${dir}]`);
1239
1242
  continue;
1240
1243
  }
1244
+ if (element && (ns === "class" || ns === "style")) {
1245
+ const key = JSON.stringify(a.name.name.name);
1246
+ const v = a.value;
1247
+ let value;
1248
+ if (v == null) value = "true";
1249
+ else if (isString(v)) value = JSON.stringify(literalOf(v));
1250
+ else if (v.type === "JSXExpressionContainer" && v.expression?.type !== "JSXEmptyExpression") {
1251
+ value = keyValue(v.expression, ctx);
1252
+ if (ns === "style") styleAt ??= posOf(v.expression, ctx);
1253
+ } else continue;
1254
+ (ns === "class" ? classEntries : styleEntries).push(`${key}: ${value}`);
1255
+ continue;
1256
+ }
1257
+ if (element && a.name.type === "JSXIdentifier" && a.name.name === "style" && a.value?.type === "JSXExpressionContainer") {
1258
+ const entries = objectEntries(a.value.expression, ctx);
1259
+ if (entries) {
1260
+ styleEntries.unshift(...entries);
1261
+ styleAt = posOf(a.value.expression, ctx);
1262
+ continue;
1263
+ }
1264
+ }
1241
1265
  if (ns === "oncapture") {
1242
1266
  const evt = a.name.name.name.toLowerCase();
1243
1267
  const h = attrExprCode(a, ctx) ?? "undefined";
@@ -1246,9 +1270,37 @@ function buildProps(attrs, ctx) {
1246
1270
  }
1247
1271
  props.push(buildAttr(a, ctx));
1248
1272
  }
1273
+ if (classEntries.length > 0) props.push({ name: "classList", kind: "attr", expr: `{ ${classEntries.join(", ")} }`, reactive: false });
1274
+ if (styleEntries.length > 0) {
1275
+ const entries = `{ ${styleEntries.join(", ")} }`;
1276
+ const base = props.findIndex((p) => p.name === "style" && p.kind === "attr");
1277
+ if (base === -1) props.push({ name: "style", kind: "attr", expr: entries, reactive: false, ...styleAt ? { at: styleAt } : {} });
1278
+ else {
1279
+ const prop = props[base];
1280
+ const value = prop.literal !== void 0 ? JSON.stringify(prop.literal) : prop.reactive ? `() => ${paren(prop.expr, "arrowBody")}` : prop.expr;
1281
+ props[base] = { name: "style", kind: "attr", expr: `[${value}, ${entries}]`, reactive: false, ...prop.at ? { at: prop.at } : {} };
1282
+ }
1283
+ }
1249
1284
  if (usePairs.length > 0) props.push({ name: "use", kind: "attr", expr: `[${usePairs.join(", ")}]` });
1250
1285
  return props;
1251
1286
  }
1287
+ function keyValue(expr, ctx) {
1288
+ const code = ctx.code(expr);
1289
+ if (!isReactive(expr)) return code;
1290
+ const accessor = `() => ${paren(code, "arrowBody")}`;
1291
+ const at = posOf(expr, ctx);
1292
+ return at ? markHole(accessor, at.line, at.column) : accessor;
1293
+ }
1294
+ function objectEntries(expr, ctx) {
1295
+ if (expr?.type !== "ObjectExpression") return null;
1296
+ const entries = [];
1297
+ for (const p of expr.properties) {
1298
+ if (p.type !== "ObjectProperty") return null;
1299
+ const key = p.computed ? `[${ctx.code(p.key)}]` : p.key.type === "Identifier" ? JSON.stringify(p.key.name) : JSON.stringify(String(p.key.value));
1300
+ entries.push(`${key}: ${keyValue(p.value, ctx)}`);
1301
+ }
1302
+ return entries;
1303
+ }
1252
1304
  function buildChildren(children, ctx) {
1253
1305
  const out = [];
1254
1306
  for (let i = 0; i < children.length; i++) {
@@ -1276,6 +1328,7 @@ function buildChildren(children, ctx) {
1276
1328
  });
1277
1329
  }
1278
1330
  } else if (child.type === "JSXElement" || child.type === "JSXFragment") {
1331
+ if (ctx.dropStyles?.has(child.start)) continue;
1279
1332
  out.push(buildNode(child, ctx));
1280
1333
  } else if (child.type === "JSXSpreadChild") {
1281
1334
  out.push({ kind: "expr", code: ctx.code(child.expression), reactive: false });
@@ -1345,13 +1398,17 @@ function buildElement(node, ctx, handled) {
1345
1398
  const children = each ? [each] : buildChildren(node.children, ctx);
1346
1399
  if (tag === CONTAINER) return children.length === 1 ? children[0] : { kind: "fragment", children };
1347
1400
  const at = ctx.sourceFile && node.loc?.start ? { file: ctx.sourceFile, line: node.loc.start.line, column: node.loc.start.column } : void 0;
1348
- return { kind: "element", tag, svg: SVG_TAGS.has(tag), props: buildProps(attributes, ctx), children, static: false, ...at ? { at } : {} };
1401
+ const props = buildProps(attributes, ctx, true);
1402
+ const scope = ctx.scopes?.find((s) => node.start >= s.start && node.end <= s.end);
1403
+ if (scope) props.unshift({ name: "data-fx-s", kind: "attr", literal: scope.value });
1404
+ return { kind: "element", tag, svg: SVG_TAGS.has(tag), props, children, static: false, ...at ? { at } : {} };
1349
1405
  }
1350
1406
  function buildNode(node, ctx) {
1351
1407
  if (node.type === "JSXFragment") {
1352
1408
  return { kind: "fragment", children: buildChildren(node.children, ctx) };
1353
1409
  }
1354
1410
  if (directive(node, "if")) return buildIf(node, null, ctx);
1411
+ if (ctx.dropStyles?.has(node.start)) return { kind: "fragment", children: [] };
1355
1412
  const { tag, component } = tagInfo(node.openingElement.name, ctx);
1356
1413
  if (!component) return buildElement(node, ctx, []);
1357
1414
  const props = buildProps(node.openingElement.attributes, ctx);
@@ -1370,6 +1427,273 @@ function buildJsxIR(node, ctx) {
1370
1427
  import {
1371
1428
  parseTemplate
1372
1429
  } from "@fluixi/template-parser";
1430
+
1431
+ // src/lower/entities.ts
1432
+ var NAMED = {
1433
+ quot: 34,
1434
+ amp: 38,
1435
+ apos: 39,
1436
+ lt: 60,
1437
+ gt: 62,
1438
+ nbsp: 160,
1439
+ iexcl: 161,
1440
+ cent: 162,
1441
+ pound: 163,
1442
+ curren: 164,
1443
+ yen: 165,
1444
+ brvbar: 166,
1445
+ sect: 167,
1446
+ uml: 168,
1447
+ copy: 169,
1448
+ ordf: 170,
1449
+ laquo: 171,
1450
+ not: 172,
1451
+ shy: 173,
1452
+ reg: 174,
1453
+ macr: 175,
1454
+ deg: 176,
1455
+ plusmn: 177,
1456
+ sup2: 178,
1457
+ sup3: 179,
1458
+ acute: 180,
1459
+ micro: 181,
1460
+ para: 182,
1461
+ middot: 183,
1462
+ cedil: 184,
1463
+ sup1: 185,
1464
+ ordm: 186,
1465
+ raquo: 187,
1466
+ frac14: 188,
1467
+ frac12: 189,
1468
+ frac34: 190,
1469
+ iquest: 191,
1470
+ Agrave: 192,
1471
+ Aacute: 193,
1472
+ Acirc: 194,
1473
+ Atilde: 195,
1474
+ Auml: 196,
1475
+ Aring: 197,
1476
+ AElig: 198,
1477
+ Ccedil: 199,
1478
+ Egrave: 200,
1479
+ Eacute: 201,
1480
+ Ecirc: 202,
1481
+ Euml: 203,
1482
+ Igrave: 204,
1483
+ Iacute: 205,
1484
+ Icirc: 206,
1485
+ Iuml: 207,
1486
+ ETH: 208,
1487
+ Ntilde: 209,
1488
+ Ograve: 210,
1489
+ Oacute: 211,
1490
+ Ocirc: 212,
1491
+ Otilde: 213,
1492
+ Ouml: 214,
1493
+ times: 215,
1494
+ Oslash: 216,
1495
+ Ugrave: 217,
1496
+ Uacute: 218,
1497
+ Ucirc: 219,
1498
+ Uuml: 220,
1499
+ Yacute: 221,
1500
+ THORN: 222,
1501
+ szlig: 223,
1502
+ agrave: 224,
1503
+ aacute: 225,
1504
+ acirc: 226,
1505
+ atilde: 227,
1506
+ auml: 228,
1507
+ aring: 229,
1508
+ aelig: 230,
1509
+ ccedil: 231,
1510
+ egrave: 232,
1511
+ eacute: 233,
1512
+ ecirc: 234,
1513
+ euml: 235,
1514
+ igrave: 236,
1515
+ iacute: 237,
1516
+ icirc: 238,
1517
+ iuml: 239,
1518
+ eth: 240,
1519
+ ntilde: 241,
1520
+ ograve: 242,
1521
+ oacute: 243,
1522
+ ocirc: 244,
1523
+ otilde: 245,
1524
+ ouml: 246,
1525
+ divide: 247,
1526
+ oslash: 248,
1527
+ ugrave: 249,
1528
+ uacute: 250,
1529
+ ucirc: 251,
1530
+ uuml: 252,
1531
+ yacute: 253,
1532
+ thorn: 254,
1533
+ yuml: 255,
1534
+ OElig: 338,
1535
+ oelig: 339,
1536
+ Scaron: 352,
1537
+ scaron: 353,
1538
+ Yuml: 376,
1539
+ fnof: 402,
1540
+ circ: 710,
1541
+ tilde: 732,
1542
+ Alpha: 913,
1543
+ Beta: 914,
1544
+ Gamma: 915,
1545
+ Delta: 916,
1546
+ Epsilon: 917,
1547
+ Zeta: 918,
1548
+ Eta: 919,
1549
+ Theta: 920,
1550
+ Iota: 921,
1551
+ Kappa: 922,
1552
+ Lambda: 923,
1553
+ Mu: 924,
1554
+ Nu: 925,
1555
+ Xi: 926,
1556
+ Omicron: 927,
1557
+ Pi: 928,
1558
+ Rho: 929,
1559
+ Sigma: 931,
1560
+ Tau: 932,
1561
+ Upsilon: 933,
1562
+ Phi: 934,
1563
+ Chi: 935,
1564
+ Psi: 936,
1565
+ Omega: 937,
1566
+ alpha: 945,
1567
+ beta: 946,
1568
+ gamma: 947,
1569
+ delta: 948,
1570
+ epsilon: 949,
1571
+ zeta: 950,
1572
+ eta: 951,
1573
+ theta: 952,
1574
+ iota: 953,
1575
+ kappa: 954,
1576
+ lambda: 955,
1577
+ mu: 956,
1578
+ nu: 957,
1579
+ xi: 958,
1580
+ omicron: 959,
1581
+ pi: 960,
1582
+ rho: 961,
1583
+ sigmaf: 962,
1584
+ sigma: 963,
1585
+ tau: 964,
1586
+ upsilon: 965,
1587
+ phi: 966,
1588
+ chi: 967,
1589
+ psi: 968,
1590
+ omega: 969,
1591
+ thetasym: 977,
1592
+ upsih: 978,
1593
+ piv: 982,
1594
+ ensp: 8194,
1595
+ emsp: 8195,
1596
+ thinsp: 8201,
1597
+ zwnj: 8204,
1598
+ zwj: 8205,
1599
+ lrm: 8206,
1600
+ rlm: 8207,
1601
+ ndash: 8211,
1602
+ mdash: 8212,
1603
+ lsquo: 8216,
1604
+ rsquo: 8217,
1605
+ sbquo: 8218,
1606
+ ldquo: 8220,
1607
+ rdquo: 8221,
1608
+ bdquo: 8222,
1609
+ dagger: 8224,
1610
+ Dagger: 8225,
1611
+ bull: 8226,
1612
+ hellip: 8230,
1613
+ permil: 8240,
1614
+ prime: 8242,
1615
+ Prime: 8243,
1616
+ lsaquo: 8249,
1617
+ rsaquo: 8250,
1618
+ oline: 8254,
1619
+ frasl: 8260,
1620
+ euro: 8364,
1621
+ image: 8465,
1622
+ weierp: 8472,
1623
+ real: 8476,
1624
+ trade: 8482,
1625
+ alefsym: 8501,
1626
+ larr: 8592,
1627
+ uarr: 8593,
1628
+ rarr: 8594,
1629
+ darr: 8595,
1630
+ harr: 8596,
1631
+ crarr: 8629,
1632
+ lArr: 8656,
1633
+ uArr: 8657,
1634
+ rArr: 8658,
1635
+ dArr: 8659,
1636
+ hArr: 8660,
1637
+ forall: 8704,
1638
+ part: 8706,
1639
+ exist: 8707,
1640
+ empty: 8709,
1641
+ nabla: 8711,
1642
+ isin: 8712,
1643
+ notin: 8713,
1644
+ ni: 8715,
1645
+ prod: 8719,
1646
+ sum: 8721,
1647
+ minus: 8722,
1648
+ lowast: 8727,
1649
+ radic: 8730,
1650
+ prop: 8733,
1651
+ infin: 8734,
1652
+ ang: 8736,
1653
+ and: 8743,
1654
+ or: 8744,
1655
+ cap: 8745,
1656
+ cup: 8746,
1657
+ int: 8747,
1658
+ there4: 8756,
1659
+ sim: 8764,
1660
+ cong: 8773,
1661
+ asymp: 8776,
1662
+ ne: 8800,
1663
+ equiv: 8801,
1664
+ le: 8804,
1665
+ ge: 8805,
1666
+ sub: 8834,
1667
+ sup: 8835,
1668
+ nsub: 8836,
1669
+ sube: 8838,
1670
+ supe: 8839,
1671
+ oplus: 8853,
1672
+ otimes: 8855,
1673
+ perp: 8869,
1674
+ sdot: 8901,
1675
+ lceil: 8968,
1676
+ rceil: 8969,
1677
+ lfloor: 8970,
1678
+ rfloor: 8971,
1679
+ lang: 9001,
1680
+ rang: 9002,
1681
+ loz: 9674,
1682
+ spades: 9824,
1683
+ clubs: 9827,
1684
+ hearts: 9829,
1685
+ diams: 9830
1686
+ };
1687
+ var REFERENCE = /&(?:#[xX]([0-9a-fA-F]{1,6})|#([0-9]{1,7})|([a-zA-Z][a-zA-Z0-9]{1,31}));/g;
1688
+ function decodeEntities(value) {
1689
+ if (!value.includes("&")) return value;
1690
+ return value.replace(REFERENCE, (match, hex, dec, name) => {
1691
+ const code = hex ? parseInt(hex, 16) : dec ? parseInt(dec, 10) : Object.prototype.hasOwnProperty.call(NAMED, name) ? NAMED[name] : void 0;
1692
+ return code !== void 0 && code <= 1114111 ? String.fromCodePoint(code) : match;
1693
+ });
1694
+ }
1695
+
1696
+ // src/lower/template.ts
1373
1697
  var DELEGATED2 = /* @__PURE__ */ new Set([
1374
1698
  "click",
1375
1699
  "dblclick",
@@ -1455,7 +1779,7 @@ var Lowerer = class {
1455
1779
  switch (node.kind) {
1456
1780
  case "Text": {
1457
1781
  if (node.raw) return { kind: "text", value: node.value };
1458
- const cleaned = cleanTemplateText(node.value);
1782
+ const cleaned = decodeEntities(cleanTemplateText(node.value));
1459
1783
  return cleaned ? { kind: "text", value: cleaned } : null;
1460
1784
  }
1461
1785
  case "Comment":
@@ -1491,7 +1815,7 @@ var Lowerer = class {
1491
1815
  kind: "element",
1492
1816
  tag: el.tag,
1493
1817
  svg: el.namespace === "svg",
1494
- props: this.lowerAttributes(el.attributes),
1818
+ props: this.lowerAttributes(el.attributes, true),
1495
1819
  children,
1496
1820
  static: false,
1497
1821
  ...at ? { at } : {}
@@ -1604,13 +1928,22 @@ var Lowerer = class {
1604
1928
  return clone.kind === "Element" ? this.lowerElement(clone) : this.lowerComponent(clone);
1605
1929
  }
1606
1930
  // --- attributes ---------------------------------------------------------
1607
- lowerAttributes(attrs) {
1931
+ /**
1932
+ * `element`: a DOM element, where each class:/style: value that moves is its own accessor.
1933
+ * A component gets the object as before, rebuilt whole when any value moves.
1934
+ */
1935
+ lowerAttributes(attrs, element = false) {
1936
+ let anyReactive = false;
1937
+ const entry = (name, h) => {
1938
+ anyReactive ||= h.reactive;
1939
+ if (!element || !h.reactive) return `${JSON.stringify(name)}: ${h.code}`;
1940
+ const accessor = `() => ${paren(h.code, "arrowBody")}`;
1941
+ return `${JSON.stringify(name)}: ${h.at ? markHole(accessor, h.at.line, h.at.column) : accessor}`;
1942
+ };
1608
1943
  const props = [];
1609
1944
  const classEntries = [];
1610
- let classReactive = false;
1611
1945
  let classAt;
1612
1946
  const styleEntries = [];
1613
- let styleReactive = false;
1614
1947
  let styleAt;
1615
1948
  const usePairs = [];
1616
1949
  for (const a of attrs) {
@@ -1650,15 +1983,13 @@ var Lowerer = class {
1650
1983
  break;
1651
1984
  case "ClassDirective": {
1652
1985
  const h = this.hole(a.hole);
1653
- classEntries.push(`${JSON.stringify(a.name)}: ${h.code}`);
1654
- classReactive = classReactive || h.reactive;
1986
+ classEntries.push(entry(a.name, h));
1655
1987
  classAt ??= h.at;
1656
1988
  break;
1657
1989
  }
1658
1990
  case "StyleDirective": {
1659
1991
  const h = this.hole(a.hole);
1660
- styleEntries.push(`${JSON.stringify(a.name)}: ${h.code}`);
1661
- styleReactive = styleReactive || h.reactive;
1992
+ styleEntries.push(entry(a.name, h));
1662
1993
  styleAt ??= h.at;
1663
1994
  break;
1664
1995
  }
@@ -1678,18 +2009,19 @@ var Lowerer = class {
1678
2009
  name: "classList",
1679
2010
  kind: "attr",
1680
2011
  expr: `{ ${classEntries.join(", ")} }`,
1681
- reactive: classReactive,
2012
+ reactive: !element && anyReactive,
1682
2013
  ...classAt ? { at: classAt } : {}
1683
2014
  });
1684
2015
  }
1685
2016
  if (styleEntries.length > 0) {
1686
- props.push({
1687
- name: "style",
1688
- kind: "attr",
1689
- expr: `{ ${styleEntries.join(", ")} }`,
1690
- reactive: styleReactive,
1691
- ...styleAt ? { at: styleAt } : {}
1692
- });
2017
+ const entries = `{ ${styleEntries.join(", ")} }`;
2018
+ const base = props.findIndex((p) => p.name === "style");
2019
+ if (base === -1) props.push({ name: "style", kind: "attr", expr: entries, reactive: !element && anyReactive, ...styleAt ? { at: styleAt } : {} });
2020
+ else {
2021
+ const prop = props[base];
2022
+ const value = prop.expr === void 0 ? JSON.stringify(prop.literal) : prop.reactive ? `() => ${paren(prop.expr, "arrowBody")}` : prop.expr;
2023
+ props[base] = { name: "style", kind: "attr", expr: `[${value}, ${entries}]`, reactive: false, ...prop.at ? { at: prop.at } : {} };
2024
+ }
1693
2025
  }
1694
2026
  if (usePairs.length > 0) {
1695
2027
  props.push({ name: "use", kind: "attr", expr: `[${usePairs.join(", ")}]` });
@@ -1778,7 +2110,7 @@ var Lowerer = class {
1778
2110
  return base;
1779
2111
  }
1780
2112
  if (v.kind === "static") {
1781
- base.literal = v.value;
2113
+ base.literal = decodeEntities(v.value);
1782
2114
  return base;
1783
2115
  }
1784
2116
  if (v.kind === "hole") {
@@ -1791,7 +2123,7 @@ var Lowerer = class {
1791
2123
  let reactive = false;
1792
2124
  let at;
1793
2125
  const body = v.parts.map((p) => {
1794
- if ("text" in p) return escapeTemplate(p.text);
2126
+ if ("text" in p) return escapeTemplate(decodeEntities(p.text));
1795
2127
  const h = this.hole(p.hole);
1796
2128
  reactive = reactive || h.reactive;
1797
2129
  at ??= h.at;
@@ -444,7 +444,7 @@ function emitComponent(name, props, children, used, templates, at) {
444
444
  }
445
445
  let obj = `{ ${bodies.map(([name2, body]) => `get ${propKey(name2)}() { return ${body}; }`).join(", ")} }`;
446
446
  if (bodies.some(([, body]) => /\bthis\b/.test(body))) {
447
- const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => ${body}`);
447
+ const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => (${body})`);
448
448
  const getters = bodies.map(([name2]) => `get ${propKey(name2)}() { return _$t[${JSON.stringify(name2)}](); }`);
449
449
  obj = `((_$t) => ({ ${getters.join(", ")} }))({ ${thunks.join(", ")} })`;
450
450
  }
@@ -1 +1 @@
1
- {"version":3,"file":"imperative.d.ts","sourceRoot":"","sources":["../../../src/codegen/backends/imperative.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,cAAc,EAAE,MAAM,eAAe,CAAC;AAkVnF;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,SAAS,GAAG,MAAM,CAK7F;AAED,eAAO,MAAM,iBAAiB,EAAE,cAgB/B,CAAC"}
1
+ {"version":3,"file":"imperative.d.ts","sourceRoot":"","sources":["../../../src/codegen/backends/imperative.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,cAAc,EAAE,MAAM,eAAe,CAAC;AAmVnF;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,SAAS,GAAG,MAAM,CAK7F;AAED,eAAO,MAAM,iBAAiB,EAAE,cAgB/B,CAAC"}
@@ -116,7 +116,8 @@ function emitComponent(name, props, children, used, templates, at) {
116
116
  // element. Arrows keep the enclosing `this`, so those props go out as arrow thunks and the
117
117
  // getters call them. Only when some prop mentions `this`; everything else is unchanged.
118
118
  if (bodies.some(([, body]) => /\bthis\b/.test(body))) {
119
- const thunks = bodies.map(([name, body]) => `${JSON.stringify(name)}: () => ${body}`);
119
+ // Parenthesised: an object literal body would otherwise parse as a block.
120
+ const thunks = bodies.map(([name, body]) => `${JSON.stringify(name)}: () => (${body})`);
120
121
  const getters = bodies.map(([name]) => `get ${propKey(name)}() { return _$t[${JSON.stringify(name)}](); }`);
121
122
  obj = `((_$t) => ({ ${getters.join(', ')} }))({ ${thunks.join(', ')} })`;
122
123
  }
@@ -417,7 +417,7 @@ function emitComponent(name, props, children, used, templates, at) {
417
417
  }
418
418
  let obj = `{ ${bodies.map(([name2, body]) => `get ${propKey(name2)}() { return ${body}; }`).join(", ")} }`;
419
419
  if (bodies.some(([, body]) => /\bthis\b/.test(body))) {
420
- const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => ${body}`);
420
+ const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => (${body})`);
421
421
  const getters = bodies.map(([name2]) => `get ${propKey(name2)}() { return _$t[${JSON.stringify(name2)}](); }`);
422
422
  obj = `((_$t) => ({ ${getters.join(", ")} }))({ ${thunks.join(", ")} })`;
423
423
  }