@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.
Files changed (102) hide show
  1. package/dist/analyze/intrinsics.cjs +31 -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 +35 -0
  6. package/dist/analyze/intrinsics.mjs +31 -1
  7. package/dist/analyze/reactive-bindings.cjs +18 -0
  8. package/dist/analyze/reactive-bindings.mjs +18 -0
  9. package/dist/analyze/static-graph.cjs +22 -4
  10. package/dist/analyze/static-graph.d.ts.map +1 -1
  11. package/dist/analyze/static-graph.js +6 -4
  12. package/dist/analyze/static-graph.mjs +22 -4
  13. package/dist/{babel-GI375YZ2.mjs → babel-RJFQVFJW.mjs} +4 -4
  14. package/dist/{chunk-QZ4CJPYP.mjs → chunk-DP2QDWWH.mjs} +1 -1
  15. package/dist/{chunk-DWNWN5RH.mjs → chunk-E2RWTIYE.mjs} +21 -15
  16. package/dist/{chunk-XJ5H2MXY.mjs → chunk-HCCBEJEZ.mjs} +31 -1
  17. package/dist/{chunk-VOUI6XPV.mjs → chunk-HIZU7WI2.mjs} +1 -1
  18. package/dist/{chunk-VC6X44FS.mjs → chunk-ZR2QHTEX.mjs} +505 -68
  19. package/dist/codegen/backends/imperative.cjs +24 -6
  20. package/dist/codegen/backends/imperative.d.ts.map +1 -1
  21. package/dist/codegen/backends/imperative.js +20 -4
  22. package/dist/codegen/backends/imperative.mjs +24 -6
  23. package/dist/frontend/babel/build-ir-lit.cjs +470 -63
  24. package/dist/frontend/babel/build-ir-lit.mjs +470 -63
  25. package/dist/frontend/babel/build-ir.cjs +470 -63
  26. package/dist/frontend/babel/build-ir.mjs +470 -63
  27. package/dist/frontend/babel/index.cjs +471 -64
  28. package/dist/frontend/babel/index.mjs +471 -64
  29. package/dist/frontend/babel/lower-template.cjs +470 -63
  30. package/dist/frontend/babel/lower-template.mjs +470 -63
  31. package/dist/frontend/babel/plugin.cjs +470 -63
  32. package/dist/frontend/babel/plugin.mjs +470 -63
  33. package/dist/index.cjs +360 -58
  34. package/dist/index.mjs +372 -58
  35. package/dist/integrations.cjs +1347 -98
  36. package/dist/integrations.d.ts.map +1 -1
  37. package/dist/integrations.js +44 -2
  38. package/dist/integrations.mjs +205 -19
  39. package/dist/lower/compile-template.cjs +354 -57
  40. package/dist/lower/compile-template.d.cts +13 -0
  41. package/dist/lower/compile-template.d.ts +13 -0
  42. package/dist/lower/compile-template.d.ts.map +1 -1
  43. package/dist/lower/compile-template.js +3 -0
  44. package/dist/lower/compile-template.mjs +366 -57
  45. package/dist/lower/entities.cjs +288 -0
  46. package/dist/lower/entities.d.cts +1 -0
  47. package/dist/lower/entities.d.ts +2 -0
  48. package/dist/lower/entities.d.ts.map +1 -0
  49. package/dist/lower/entities.js +54 -0
  50. package/dist/lower/entities.mjs +267 -0
  51. package/dist/lower/jsx.cjs +567 -7
  52. package/dist/lower/jsx.d.cts +8 -0
  53. package/dist/lower/jsx.d.ts +8 -0
  54. package/dist/lower/jsx.d.ts.map +1 -1
  55. package/dist/lower/jsx.js +205 -7
  56. package/dist/lower/jsx.mjs +567 -7
  57. package/dist/lower/template.cjs +332 -56
  58. package/dist/lower/template.d.ts.map +1 -1
  59. package/dist/lower/template.js +57 -49
  60. package/dist/lower/template.mjs +332 -56
  61. package/dist/resolve/builtins.cjs +1 -1
  62. package/dist/resolve/builtins.mjs +1 -1
  63. package/dist/resolve/component-globals.cjs +20 -1
  64. package/dist/resolve/component-globals.js +2 -2
  65. package/dist/resolve/component-globals.mjs +20 -1
  66. package/dist/resolve/write-globals.cjs +20 -1
  67. package/dist/resolve/write-globals.mjs +20 -1
  68. package/dist/{server-fns-BBZRZUPP.mjs → server-fns-JLSTKWPS.mjs} +4 -4
  69. package/dist/{server-functions-VEGLIFCE.mjs → server-functions-BGY3RD4R.mjs} +3 -3
  70. package/dist/transform/index.cjs +1123 -77
  71. package/dist/transform/index.mjs +1141 -91
  72. package/dist/transform/intrinsics.cjs +18 -0
  73. package/dist/transform/intrinsics.mjs +18 -0
  74. package/dist/transform/props.mjs +19 -14
  75. package/dist/transform/server-fns.mjs +19 -14
  76. package/dist/transform/source-locations.cjs +64 -3
  77. package/dist/transform/source-locations.d.cts +7 -2
  78. package/dist/transform/source-locations.d.ts +7 -2
  79. package/dist/transform/source-locations.d.ts.map +1 -1
  80. package/dist/transform/source-locations.js +68 -3
  81. package/dist/transform/source-locations.mjs +64 -3
  82. package/dist/transform/styles.cjs +588 -0
  83. package/dist/transform/styles.d.cts +211 -0
  84. package/dist/transform/styles.d.ts +212 -0
  85. package/dist/transform/styles.d.ts.map +1 -0
  86. package/dist/transform/styles.js +714 -0
  87. package/dist/transform/styles.mjs +653 -0
  88. package/dist/transform/templates.cjs +1122 -76
  89. package/dist/transform/templates.d.cts +13 -0
  90. package/dist/transform/templates.d.ts +13 -0
  91. package/dist/transform/templates.d.ts.map +1 -1
  92. package/dist/transform/templates.js +51 -14
  93. package/dist/transform/templates.mjs +1140 -90
  94. package/dist/{transform-UWZ7ZGJ2.mjs → transform-GBP6Y4UI.mjs} +603 -19
  95. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  96. package/dist/vite-styles.cjs +180 -0
  97. package/dist/vite-styles.d.cts +59 -0
  98. package/dist/vite-styles.d.ts +60 -0
  99. package/dist/vite-styles.d.ts.map +1 -0
  100. package/dist/vite-styles.js +198 -0
  101. package/dist/vite-styles.mjs +159 -0
  102. package/package.json +10 -3
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- /*! @fluixi/compiler v1.0.0-alpha.92 | (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
 
3
3
  // src/analyze/reactive-expr.ts
4
4
  var STABLE_MEMBER = "children";
@@ -281,6 +281,7 @@ var INTRINSICS = {
281
281
  $effect: { export: "effect", module: REACTIVE_MODULE, returns: "effect" },
282
282
  $store: { export: "store", module: "@fluixi/reactive/store", returns: "store-handle" },
283
283
  $resource: { export: "resource", module: REACTIVE_MODULE, returns: "resource-handle" },
284
+ $cachedResource: { export: "cachedResource", module: "@fluixi/reactive/cached-resource", returns: "resource-handle" },
284
285
  // No short runtime form for these yet, so the intrinsic stands for the `create*`
285
286
  // name. Still worth having: no import to write, and when a shorter form is
286
287
  // designed, the change is this line rather than a compiler pass.
@@ -291,9 +292,27 @@ var INTRINSICS = {
291
292
  // dependency analysis must not guess at.
292
293
  $untrack: { export: "untrack", module: REACTIVE_MODULE, returns: "plain" },
293
294
  $untrackStore: { export: "untrackStore", module: "@fluixi/reactive/store", returns: "plain" },
295
+ // Scopes, scheduling and lifecycle: no value to classify, but the same authoring promise,
296
+ // no import to write. `$cleanup` registers a callback on the current owner (`onCleanup`).
297
+ $batch: { export: "batch", module: REACTIVE_MODULE, returns: "plain" },
298
+ $cleanup: { export: "onCleanup", module: REACTIVE_MODULE, returns: "plain" },
299
+ $root: { export: "root", module: REACTIVE_MODULE, returns: "plain" },
300
+ $context: { export: "context", module: REACTIVE_MODULE, returns: "plain" },
301
+ $renderEffect: { export: "renderEffect", module: REACTIVE_MODULE, returns: "effect" },
302
+ $computed: { export: "computed", module: REACTIVE_MODULE, returns: "effect" },
303
+ // Storage for where the code runs, and a signal kept in it. `$persisted` is a signal
304
+ // handle as far as reads go: the same accessor with `set` on it.
305
+ $storage: { export: "useStorage", module: "@fluixi/core/storage", returns: "plain" },
306
+ $asyncStorage: { export: "useAsyncStorage", module: "@fluixi/core/storage", returns: "plain" },
307
+ $persisted: { export: "persisted", module: "@fluixi/core/storage", returns: "signal-handle" },
294
308
  // An environment variable, public or server-only; the browser build refuses a secret.
295
309
  $env: { export: "env", module: "@fluixi/start/env", returns: "plain" }
296
310
  };
311
+ var TAG_INTRINSICS = {
312
+ $html: { export: "html", module: "@fluixi/core" },
313
+ $svg: { export: "svg", module: "@fluixi/core" },
314
+ $css: { export: "css", module: "@fluixi/core" }
315
+ };
297
316
  var INTRINSIC_CALL = new RegExp(`\\$(?:${Object.keys(INTRINSICS).map((n) => n.slice(1)).join("|")})\\s*\\(`);
298
317
 
299
318
  // src/transform/source-locations.ts
@@ -468,13 +487,16 @@ function emitComponent(name, props, children, used, templates, at) {
468
487
  used.add("createComponent");
469
488
  const spreads = props.filter((p) => p.kind === "spread");
470
489
  const normal = props.filter((p) => p.kind !== "spread");
471
- const entries = normal.map(
472
- (p) => `get ${propKey(p.name)}() { return ${componentPropValue(p)}; }`
473
- );
490
+ const bodies = normal.map((p) => [p.name, componentPropValue(p)]);
474
491
  if (children.length > 0) {
475
- entries.push(`get children() { return ${emitChildren(children, used, templates)}; }`);
492
+ bodies.push(["children", emitChildren(children, used, templates)]);
493
+ }
494
+ let obj = `{ ${bodies.map(([name2, body]) => `get ${propKey(name2)}() { return ${body}; }`).join(", ")} }`;
495
+ if (bodies.some(([, body]) => /\bthis\b/.test(body))) {
496
+ const thunks = bodies.map(([name2, body]) => `${JSON.stringify(name2)}: () => (${body})`);
497
+ const getters = bodies.map(([name2]) => `get ${propKey(name2)}() { return _$t[${JSON.stringify(name2)}](); }`);
498
+ obj = `((_$t) => ({ ${getters.join(", ")} }))({ ${thunks.join(", ")} })`;
476
499
  }
477
- let obj = `{ ${entries.join(", ")} }`;
478
500
  if (spreads.length > 0) {
479
501
  used.add("mergeProps");
480
502
  obj = `mergeProps(${spreads.map((s) => s.expr).join(", ")}, ${obj})`;
@@ -556,7 +578,8 @@ function emitNode(node, used, templates) {
556
578
  } else {
557
579
  used.add("spread");
558
580
  const svgFlag = node.svg ? ", isSVG: true" : "";
559
- const customFlag = node.tag.includes("-") ? ", isCustomElement: true" : "";
581
+ const accessors = node.props.filter((p) => p.kind !== "spread" && p.expr !== void 0 && p.reactive && p.name !== "ref").map((p) => p.name);
582
+ const customFlag = node.tag.includes("-") ? `, isCustomElement: true, accessors: ${JSON.stringify(accessors)}` : "";
560
583
  parts.push(
561
584
  `spread({ element: ${el}, props: ${emitProps(node.props, null, used)}${svgFlag}${customFlag} });`
562
585
  );
@@ -609,6 +632,271 @@ function cleanTemplateText(value) {
609
632
  return out;
610
633
  }
611
634
 
635
+ // src/lower/entities.ts
636
+ var NAMED = {
637
+ quot: 34,
638
+ amp: 38,
639
+ apos: 39,
640
+ lt: 60,
641
+ gt: 62,
642
+ nbsp: 160,
643
+ iexcl: 161,
644
+ cent: 162,
645
+ pound: 163,
646
+ curren: 164,
647
+ yen: 165,
648
+ brvbar: 166,
649
+ sect: 167,
650
+ uml: 168,
651
+ copy: 169,
652
+ ordf: 170,
653
+ laquo: 171,
654
+ not: 172,
655
+ shy: 173,
656
+ reg: 174,
657
+ macr: 175,
658
+ deg: 176,
659
+ plusmn: 177,
660
+ sup2: 178,
661
+ sup3: 179,
662
+ acute: 180,
663
+ micro: 181,
664
+ para: 182,
665
+ middot: 183,
666
+ cedil: 184,
667
+ sup1: 185,
668
+ ordm: 186,
669
+ raquo: 187,
670
+ frac14: 188,
671
+ frac12: 189,
672
+ frac34: 190,
673
+ iquest: 191,
674
+ Agrave: 192,
675
+ Aacute: 193,
676
+ Acirc: 194,
677
+ Atilde: 195,
678
+ Auml: 196,
679
+ Aring: 197,
680
+ AElig: 198,
681
+ Ccedil: 199,
682
+ Egrave: 200,
683
+ Eacute: 201,
684
+ Ecirc: 202,
685
+ Euml: 203,
686
+ Igrave: 204,
687
+ Iacute: 205,
688
+ Icirc: 206,
689
+ Iuml: 207,
690
+ ETH: 208,
691
+ Ntilde: 209,
692
+ Ograve: 210,
693
+ Oacute: 211,
694
+ Ocirc: 212,
695
+ Otilde: 213,
696
+ Ouml: 214,
697
+ times: 215,
698
+ Oslash: 216,
699
+ Ugrave: 217,
700
+ Uacute: 218,
701
+ Ucirc: 219,
702
+ Uuml: 220,
703
+ Yacute: 221,
704
+ THORN: 222,
705
+ szlig: 223,
706
+ agrave: 224,
707
+ aacute: 225,
708
+ acirc: 226,
709
+ atilde: 227,
710
+ auml: 228,
711
+ aring: 229,
712
+ aelig: 230,
713
+ ccedil: 231,
714
+ egrave: 232,
715
+ eacute: 233,
716
+ ecirc: 234,
717
+ euml: 235,
718
+ igrave: 236,
719
+ iacute: 237,
720
+ icirc: 238,
721
+ iuml: 239,
722
+ eth: 240,
723
+ ntilde: 241,
724
+ ograve: 242,
725
+ oacute: 243,
726
+ ocirc: 244,
727
+ otilde: 245,
728
+ ouml: 246,
729
+ divide: 247,
730
+ oslash: 248,
731
+ ugrave: 249,
732
+ uacute: 250,
733
+ ucirc: 251,
734
+ uuml: 252,
735
+ yacute: 253,
736
+ thorn: 254,
737
+ yuml: 255,
738
+ OElig: 338,
739
+ oelig: 339,
740
+ Scaron: 352,
741
+ scaron: 353,
742
+ Yuml: 376,
743
+ fnof: 402,
744
+ circ: 710,
745
+ tilde: 732,
746
+ Alpha: 913,
747
+ Beta: 914,
748
+ Gamma: 915,
749
+ Delta: 916,
750
+ Epsilon: 917,
751
+ Zeta: 918,
752
+ Eta: 919,
753
+ Theta: 920,
754
+ Iota: 921,
755
+ Kappa: 922,
756
+ Lambda: 923,
757
+ Mu: 924,
758
+ Nu: 925,
759
+ Xi: 926,
760
+ Omicron: 927,
761
+ Pi: 928,
762
+ Rho: 929,
763
+ Sigma: 931,
764
+ Tau: 932,
765
+ Upsilon: 933,
766
+ Phi: 934,
767
+ Chi: 935,
768
+ Psi: 936,
769
+ Omega: 937,
770
+ alpha: 945,
771
+ beta: 946,
772
+ gamma: 947,
773
+ delta: 948,
774
+ epsilon: 949,
775
+ zeta: 950,
776
+ eta: 951,
777
+ theta: 952,
778
+ iota: 953,
779
+ kappa: 954,
780
+ lambda: 955,
781
+ mu: 956,
782
+ nu: 957,
783
+ xi: 958,
784
+ omicron: 959,
785
+ pi: 960,
786
+ rho: 961,
787
+ sigmaf: 962,
788
+ sigma: 963,
789
+ tau: 964,
790
+ upsilon: 965,
791
+ phi: 966,
792
+ chi: 967,
793
+ psi: 968,
794
+ omega: 969,
795
+ thetasym: 977,
796
+ upsih: 978,
797
+ piv: 982,
798
+ ensp: 8194,
799
+ emsp: 8195,
800
+ thinsp: 8201,
801
+ zwnj: 8204,
802
+ zwj: 8205,
803
+ lrm: 8206,
804
+ rlm: 8207,
805
+ ndash: 8211,
806
+ mdash: 8212,
807
+ lsquo: 8216,
808
+ rsquo: 8217,
809
+ sbquo: 8218,
810
+ ldquo: 8220,
811
+ rdquo: 8221,
812
+ bdquo: 8222,
813
+ dagger: 8224,
814
+ Dagger: 8225,
815
+ bull: 8226,
816
+ hellip: 8230,
817
+ permil: 8240,
818
+ prime: 8242,
819
+ Prime: 8243,
820
+ lsaquo: 8249,
821
+ rsaquo: 8250,
822
+ oline: 8254,
823
+ frasl: 8260,
824
+ euro: 8364,
825
+ image: 8465,
826
+ weierp: 8472,
827
+ real: 8476,
828
+ trade: 8482,
829
+ alefsym: 8501,
830
+ larr: 8592,
831
+ uarr: 8593,
832
+ rarr: 8594,
833
+ darr: 8595,
834
+ harr: 8596,
835
+ crarr: 8629,
836
+ lArr: 8656,
837
+ uArr: 8657,
838
+ rArr: 8658,
839
+ dArr: 8659,
840
+ hArr: 8660,
841
+ forall: 8704,
842
+ part: 8706,
843
+ exist: 8707,
844
+ empty: 8709,
845
+ nabla: 8711,
846
+ isin: 8712,
847
+ notin: 8713,
848
+ ni: 8715,
849
+ prod: 8719,
850
+ sum: 8721,
851
+ minus: 8722,
852
+ lowast: 8727,
853
+ radic: 8730,
854
+ prop: 8733,
855
+ infin: 8734,
856
+ ang: 8736,
857
+ and: 8743,
858
+ or: 8744,
859
+ cap: 8745,
860
+ cup: 8746,
861
+ int: 8747,
862
+ there4: 8756,
863
+ sim: 8764,
864
+ cong: 8773,
865
+ asymp: 8776,
866
+ ne: 8800,
867
+ equiv: 8801,
868
+ le: 8804,
869
+ ge: 8805,
870
+ sub: 8834,
871
+ sup: 8835,
872
+ nsub: 8836,
873
+ sube: 8838,
874
+ supe: 8839,
875
+ oplus: 8853,
876
+ otimes: 8855,
877
+ perp: 8869,
878
+ sdot: 8901,
879
+ lceil: 8968,
880
+ rceil: 8969,
881
+ lfloor: 8970,
882
+ rfloor: 8971,
883
+ lang: 9001,
884
+ rang: 9002,
885
+ loz: 9674,
886
+ spades: 9824,
887
+ clubs: 9827,
888
+ hearts: 9829,
889
+ diams: 9830
890
+ };
891
+ var REFERENCE = /&(?:#[xX]([0-9a-fA-F]{1,6})|#([0-9]{1,7})|([a-zA-Z][a-zA-Z0-9]{1,31}));/g;
892
+ function decodeEntities(value) {
893
+ if (!value.includes("&")) return value;
894
+ return value.replace(REFERENCE, (match, hex, dec, name) => {
895
+ const code = hex ? parseInt(hex, 16) : dec ? parseInt(dec, 10) : Object.prototype.hasOwnProperty.call(NAMED, name) ? NAMED[name] : void 0;
896
+ return code !== void 0 && code <= 1114111 ? String.fromCodePoint(code) : match;
897
+ });
898
+ }
899
+
612
900
  // src/lower/template.ts
613
901
  var DELEGATED = /* @__PURE__ */ new Set([
614
902
  "click",
@@ -627,6 +915,7 @@ var DELEGATED = /* @__PURE__ */ new Set([
627
915
  function escapeTemplate(s) {
628
916
  return s.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$\{/g, "\\${");
629
917
  }
918
+ var CONTAINER = "container";
630
919
  function capitalize(s) {
631
920
  return s.charAt(0).toUpperCase() + s.slice(1);
632
921
  }
@@ -681,10 +970,6 @@ var Lowerer = class {
681
970
  if (hasElse) i = elseIdx;
682
971
  continue;
683
972
  }
684
- if (child.attributes.some((a) => a.kind === "EachDirective")) {
685
- out.push(this.lowerEach(child));
686
- continue;
687
- }
688
973
  }
689
974
  const node = this.lowerNode(child);
690
975
  if (node) out.push(node);
@@ -698,7 +983,7 @@ var Lowerer = class {
698
983
  switch (node.kind) {
699
984
  case "Text": {
700
985
  if (node.raw) return { kind: "text", value: node.value };
701
- const cleaned = cleanTemplateText(node.value);
986
+ const cleaned = decodeEntities(cleanTemplateText(node.value));
702
987
  return cleaned ? { kind: "text", value: cleaned } : null;
703
988
  }
704
989
  case "Comment":
@@ -726,13 +1011,16 @@ var Lowerer = class {
726
1011
  node.props.unshift({ name: "component", kind: "attr", expr: `() => ${paren(this.hole(isAttr.value.hole).code, "arrowBody")}` });
727
1012
  return node;
728
1013
  }
1014
+ const each = this.lowerEach(el);
1015
+ const children = each ? [each] : this.lowerChildren(el.children);
1016
+ if (el.tag === CONTAINER) return children.length === 1 ? children[0] : { kind: "fragment", children };
729
1017
  const at = this.tagAt(el);
730
1018
  return {
731
1019
  kind: "element",
732
1020
  tag: el.tag,
733
1021
  svg: el.namespace === "svg",
734
- props: this.lowerAttributes(el.attributes),
735
- children: this.lowerChildren(el.children),
1022
+ props: this.lowerAttributes(el.attributes, true),
1023
+ children,
736
1024
  static: false,
737
1025
  ...at ? { at } : {}
738
1026
  };
@@ -804,10 +1092,14 @@ var Lowerer = class {
804
1092
  const at = this.tagAt(el);
805
1093
  return { kind: "component", name: "Show", props, children: [child], ...at ? { at } : {}, ...cond.at ? { bindAt: cond.at } : {} };
806
1094
  }
807
- /** `<el each=${items} key?>${item => …}</el>` → `<For each>{item => <el>…</el>}</For>`. */
1095
+ /**
1096
+ * `<el each=${items} key?>${item => …}</el>` → `<el><For each>{item => …}</For></el>`: the
1097
+ * content is repeated per item. Content that is not a `${item => …}` arrow is repeated as
1098
+ * it is. Null when the element has no `each`.
1099
+ */
808
1100
  lowerEach(el) {
809
1101
  const eachDir = el.attributes.find((a) => a.kind === "EachDirective");
810
- if (!eachDir || eachDir.kind !== "EachDirective") return this.lowerNode(el);
1102
+ if (!eachDir || eachDir.kind !== "EachDirective") return null;
811
1103
  const each = this.hole(eachDir.hole);
812
1104
  const props = [{ name: "each", kind: "attr", expr: each.code, reactive: each.reactive, ...each.at ? { at: each.at } : {} }];
813
1105
  if (eachDir.key) {
@@ -817,12 +1109,12 @@ var Lowerer = class {
817
1109
  const arrow = this.itemArrow(el);
818
1110
  let childrenCode;
819
1111
  if (arrow) {
820
- const bodyIR = { kind: "expr", code: arrow.body, reactive: arrow.bodyReactive };
821
- const repeated = this.rebuildWithChildren(el, [bodyIR]);
822
- childrenCode = `(${arrow.params.join(", ")}) => ${paren(this.emit(repeated), "arrowBody")}`;
1112
+ const body = arrow.bodyReactive ? `() => ${paren(arrow.body, "arrowBody")}` : paren(arrow.body, "arrowBody");
1113
+ childrenCode = `(${arrow.params.join(", ")}) => ${body}`;
823
1114
  } else {
824
- const repeated = this.stripAndLower(el, (a) => a.kind === "EachDirective");
825
- childrenCode = `() => ${paren(this.emit(repeated), "arrowBody")}`;
1115
+ const content = this.lowerChildren(el.children);
1116
+ const ir = content.length === 1 ? content[0] : { kind: "fragment", children: content };
1117
+ childrenCode = `() => ${paren(this.emit(ir), "arrowBody")}`;
826
1118
  }
827
1119
  const children = [{ kind: "expr", code: childrenCode, reactive: false }];
828
1120
  const at = this.tagAt(el);
@@ -839,33 +1131,23 @@ var Lowerer = class {
839
1131
  const clone = { ...el, attributes: el.attributes.filter((a) => !drop(a)) };
840
1132
  return clone.kind === "Element" ? this.lowerElement(clone) : this.lowerComponent(clone);
841
1133
  }
842
- /** Same element (minus each/key) but with explicit IR children. */
843
- rebuildWithChildren(el, children) {
844
- const props = this.lowerAttributes(
845
- el.attributes.filter((a) => a.kind !== "EachDirective")
846
- );
847
- if (el.kind === "Element") {
848
- const at = this.tagAt(el);
849
- return {
850
- kind: "element",
851
- tag: el.tag,
852
- svg: el.namespace === "svg",
853
- props,
854
- children,
855
- static: false,
856
- ...at ? { at } : {}
857
- };
858
- }
859
- return { kind: "component", name: el.tag, props, children };
860
- }
861
1134
  // --- attributes ---------------------------------------------------------
862
- lowerAttributes(attrs) {
1135
+ /**
1136
+ * `element`: a DOM element, where each class:/style: value that moves is its own accessor.
1137
+ * A component gets the object as before, rebuilt whole when any value moves.
1138
+ */
1139
+ lowerAttributes(attrs, element = false) {
1140
+ let anyReactive = false;
1141
+ const entry = (name, h) => {
1142
+ anyReactive ||= h.reactive;
1143
+ if (!element || !h.reactive) return `${JSON.stringify(name)}: ${h.code}`;
1144
+ const accessor = `() => ${paren(h.code, "arrowBody")}`;
1145
+ return `${JSON.stringify(name)}: ${h.at ? markHole(accessor, h.at.line, h.at.column) : accessor}`;
1146
+ };
863
1147
  const props = [];
864
1148
  const classEntries = [];
865
- let classReactive = false;
866
1149
  let classAt;
867
1150
  const styleEntries = [];
868
- let styleReactive = false;
869
1151
  let styleAt;
870
1152
  const usePairs = [];
871
1153
  for (const a of attrs) {
@@ -905,15 +1187,13 @@ var Lowerer = class {
905
1187
  break;
906
1188
  case "ClassDirective": {
907
1189
  const h = this.hole(a.hole);
908
- classEntries.push(`${JSON.stringify(a.name)}: ${h.code}`);
909
- classReactive = classReactive || h.reactive;
1190
+ classEntries.push(entry(a.name, h));
910
1191
  classAt ??= h.at;
911
1192
  break;
912
1193
  }
913
1194
  case "StyleDirective": {
914
1195
  const h = this.hole(a.hole);
915
- styleEntries.push(`${JSON.stringify(a.name)}: ${h.code}`);
916
- styleReactive = styleReactive || h.reactive;
1196
+ styleEntries.push(entry(a.name, h));
917
1197
  styleAt ??= h.at;
918
1198
  break;
919
1199
  }
@@ -933,18 +1213,19 @@ var Lowerer = class {
933
1213
  name: "classList",
934
1214
  kind: "attr",
935
1215
  expr: `{ ${classEntries.join(", ")} }`,
936
- reactive: classReactive,
1216
+ reactive: !element && anyReactive,
937
1217
  ...classAt ? { at: classAt } : {}
938
1218
  });
939
1219
  }
940
1220
  if (styleEntries.length > 0) {
941
- props.push({
942
- name: "style",
943
- kind: "attr",
944
- expr: `{ ${styleEntries.join(", ")} }`,
945
- reactive: styleReactive,
946
- ...styleAt ? { at: styleAt } : {}
947
- });
1221
+ const entries = `{ ${styleEntries.join(", ")} }`;
1222
+ const base = props.findIndex((p) => p.name === "style");
1223
+ if (base === -1) props.push({ name: "style", kind: "attr", expr: entries, reactive: !element && anyReactive, ...styleAt ? { at: styleAt } : {} });
1224
+ else {
1225
+ const prop = props[base];
1226
+ const value = prop.expr === void 0 ? JSON.stringify(prop.literal) : prop.reactive ? `() => ${paren(prop.expr, "arrowBody")}` : prop.expr;
1227
+ props[base] = { name: "style", kind: "attr", expr: `[${value}, ${entries}]`, reactive: false, ...prop.at ? { at: prop.at } : {} };
1228
+ }
948
1229
  }
949
1230
  if (usePairs.length > 0) {
950
1231
  props.push({ name: "use", kind: "attr", expr: `[${usePairs.join(", ")}]` });
@@ -1033,7 +1314,7 @@ var Lowerer = class {
1033
1314
  return base;
1034
1315
  }
1035
1316
  if (v.kind === "static") {
1036
- base.literal = v.value;
1317
+ base.literal = decodeEntities(v.value);
1037
1318
  return base;
1038
1319
  }
1039
1320
  if (v.kind === "hole") {
@@ -1046,7 +1327,7 @@ var Lowerer = class {
1046
1327
  let reactive = false;
1047
1328
  let at;
1048
1329
  const body = v.parts.map((p) => {
1049
- if ("text" in p) return escapeTemplate(p.text);
1330
+ if ("text" in p) return escapeTemplate(decodeEntities(p.text));
1050
1331
  const h = this.hole(p.hole);
1051
1332
  reactive = reactive || h.reactive;
1052
1333
  at ??= h.at;
@@ -1063,6 +1344,38 @@ function lowerTemplate(pieces, holes, used, opts = {}) {
1063
1344
  return new Lowerer(holes, used, opts.sourceFile, opts.positionAt).lowerRoot(root.children);
1064
1345
  }
1065
1346
 
1347
+ // ../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.6.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
1348
+ var comma = ",".charCodeAt(0);
1349
+ var semicolon = ";".charCodeAt(0);
1350
+ var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1351
+ var intToChar = new Uint8Array(64);
1352
+ var charToInt = new Uint8Array(128);
1353
+ for (let i = 0; i < chars.length; i++) {
1354
+ const c = chars.charCodeAt(i);
1355
+ intToChar[i] = c;
1356
+ charToInt[c] = i;
1357
+ }
1358
+ var bufLength = 1024 * 16;
1359
+
1360
+ // src/transform/styles.ts
1361
+ var SCOPE_ATTR = "data-fx-s";
1362
+ function applyTemplateStyles(ir, t) {
1363
+ const walk2 = (node) => {
1364
+ const children = node.children;
1365
+ if (children) {
1366
+ for (let i = children.length - 1; i >= 0; i--) {
1367
+ const child = children[i];
1368
+ if (child.kind === "element" && child.tag === "style" && t.owner) children.splice(i, 1);
1369
+ else walk2(child);
1370
+ }
1371
+ }
1372
+ if (t.scope && node.kind === "element" && node.tag !== "style" && node.props && !node.props.some((p) => p.name === SCOPE_ATTR)) {
1373
+ node.props.unshift({ name: SCOPE_ATTR, kind: "attr", literal: t.scope });
1374
+ }
1375
+ };
1376
+ walk2(ir);
1377
+ }
1378
+
1066
1379
  // src/optimize/analyze-static.ts
1067
1380
  function propReason(prop) {
1068
1381
  switch (prop.kind) {
@@ -1338,6 +1651,7 @@ function compilePieces(pieces, holes, options = {}) {
1338
1651
  ...options.sourceFile ? { sourceFile: options.sourceFile } : {},
1339
1652
  ...options.positionAt ? { positionAt: options.positionAt } : {}
1340
1653
  });
1654
+ if (options.templateStyles) applyTemplateStyles(ir, options.templateStyles);
1341
1655
  analyzeStatic(ir);
1342
1656
  resolveComponentSources(ir, {
1343
1657
  resolver: createComponentResolver(options.resolve ?? []),
@@ -1421,7 +1735,7 @@ function componentGlobals(rules, options = {}) {
1421
1735
  resolved.set(name, target);
1422
1736
  }
1423
1737
  }
1424
- const usableIntrinsics = intrinsics ? Object.entries(INTRINSICS).filter(([, i]) => {
1738
+ const usableIntrinsics = intrinsics ? Object.entries({ ...INTRINSICS, ...TAG_INTRINSICS }).filter(([, i]) => {
1425
1739
  const pkg = packageOf(i.module);
1426
1740
  return !available || !pkg || available.has(pkg);
1427
1741
  }) : [];