@fluixi/compiler 1.0.0-alpha.82 → 1.0.0-alpha.83

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 (75) hide show
  1. package/dist/analyze/static-graph.cjs +1 -0
  2. package/dist/analyze/static-graph.d.ts +103 -0
  3. package/dist/analyze/static-graph.d.ts.map +1 -0
  4. package/dist/analyze/static-graph.js +869 -0
  5. package/dist/analyze/static-graph.mjs +1 -0
  6. package/dist/{babel-4JUDAR2G.mjs → babel-VXKH6MRQ.mjs} +1 -1
  7. package/dist/chunk-5KMMN5QP.mjs +1 -0
  8. package/dist/chunk-YKZ54NVE.mjs +1 -0
  9. package/dist/codegen/backends/imperative.cjs +1 -1
  10. package/dist/codegen/backends/imperative.d.ts.map +1 -1
  11. package/dist/codegen/backends/imperative.js +62 -11
  12. package/dist/codegen/backends/imperative.mjs +1 -1
  13. package/dist/codegen/partial-template.cjs +1 -1
  14. package/dist/codegen/partial-template.mjs +1 -1
  15. package/dist/codegen/serialize-static.cjs +1 -1
  16. package/dist/codegen/serialize-static.d.ts +16 -0
  17. package/dist/codegen/serialize-static.d.ts.map +1 -1
  18. package/dist/codegen/serialize-static.js +25 -0
  19. package/dist/codegen/serialize-static.mjs +1 -1
  20. package/dist/frontend/babel/build-ir-lit.cjs +1 -1
  21. package/dist/frontend/babel/build-ir-lit.mjs +1 -1
  22. package/dist/frontend/babel/build-ir.cjs +1 -1
  23. package/dist/frontend/babel/build-ir.mjs +1 -1
  24. package/dist/frontend/babel/index.cjs +1 -1
  25. package/dist/frontend/babel/index.mjs +1 -1
  26. package/dist/frontend/babel/lower-template.cjs +1 -1
  27. package/dist/frontend/babel/lower-template.mjs +1 -1
  28. package/dist/frontend/babel/plugin.cjs +1 -1
  29. package/dist/frontend/babel/plugin.mjs +1 -1
  30. package/dist/index.cjs +8 -8
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +3 -0
  33. package/dist/index.mjs +8 -8
  34. package/dist/integrations.cjs +18 -18
  35. package/dist/integrations.d.ts +16 -0
  36. package/dist/integrations.d.ts.map +1 -1
  37. package/dist/integrations.js +21 -2
  38. package/dist/integrations.mjs +5 -5
  39. package/dist/ir/nodes.cjs +1 -1
  40. package/dist/ir/nodes.d.ts +46 -0
  41. package/dist/ir/nodes.d.ts.map +1 -1
  42. package/dist/lower/compile-template.cjs +1 -1
  43. package/dist/lower/compile-template.d.ts +12 -0
  44. package/dist/lower/compile-template.d.ts.map +1 -1
  45. package/dist/lower/compile-template.js +5 -1
  46. package/dist/lower/compile-template.mjs +1 -1
  47. package/dist/lower/jsx.cjs +1 -1
  48. package/dist/lower/jsx.d.ts +2 -0
  49. package/dist/lower/jsx.d.ts.map +1 -1
  50. package/dist/lower/jsx.js +25 -3
  51. package/dist/lower/jsx.mjs +1 -1
  52. package/dist/lower/template.cjs +1 -1
  53. package/dist/lower/template.d.ts +14 -1
  54. package/dist/lower/template.d.ts.map +1 -1
  55. package/dist/lower/template.js +101 -15
  56. package/dist/lower/template.mjs +1 -1
  57. package/dist/transform/index.cjs +5 -5
  58. package/dist/transform/index.mjs +12 -12
  59. package/dist/transform/source-locations.cjs +1 -0
  60. package/dist/transform/source-locations.d.ts +44 -0
  61. package/dist/transform/source-locations.d.ts.map +1 -0
  62. package/dist/transform/source-locations.js +238 -0
  63. package/dist/transform/source-locations.mjs +1 -0
  64. package/dist/transform/templates.cjs +4 -4
  65. package/dist/transform/templates.d.ts +12 -4
  66. package/dist/transform/templates.d.ts.map +1 -1
  67. package/dist/transform/templates.js +72 -7
  68. package/dist/transform/templates.mjs +11 -11
  69. package/dist/transform-C4ZXRVGP.mjs +8 -0
  70. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  71. package/package.json +3 -3
  72. package/dist/chunk-PVR2SN3B.mjs +0 -1
  73. package/dist/chunk-QUIYULS2.mjs +0 -1
  74. package/dist/chunk-YR3SAEO7.mjs +0 -1
  75. package/dist/transform-5WC4FWJE.mjs +0 -8
package/dist/lower/jsx.js CHANGED
@@ -13,6 +13,13 @@ const DELEGATED = new Set([
13
13
  'keydown', 'keyup', 'keypress', 'mousedown', 'mouseup',
14
14
  ]);
15
15
  const isReactive = (node) => isReactiveShape(shapeOf(node));
16
+ /** Only when the host asked for source locations — the flag that records usage sites too. */
17
+ const posOf = (node, ctx) => {
18
+ if (!ctx.sourceFile)
19
+ return undefined;
20
+ const at = node.loc?.start;
21
+ return at ? { line: at.line, column: at.column } : undefined;
22
+ };
16
23
  /** A literal value, or undefined when the node is not one. */
17
24
  function literalOf(node) {
18
25
  if (node.type === 'StringLiteral' || node.type === 'NumericLiteral' || node.type === 'BooleanLiteral') {
@@ -60,10 +67,12 @@ function buildAttr(attr, ctx) {
60
67
  const v = attr.value;
61
68
  if (v == null) {
62
69
  base.literal = true; // valueless attribute
70
+ base.at = posOf(attr, ctx);
63
71
  return base;
64
72
  }
65
73
  if (isString(v)) {
66
74
  base.literal = literalOf(v);
75
+ base.at = posOf(v, ctx);
67
76
  return base;
68
77
  }
69
78
  if (v.type === 'JSXExpressionContainer' && v.expression?.type !== 'JSXEmptyExpression') {
@@ -71,10 +80,14 @@ function buildAttr(attr, ctx) {
71
80
  const literal = literalOf(expr);
72
81
  if (literal !== undefined) {
73
82
  base.literal = literal;
83
+ base.at = posOf(expr, ctx);
74
84
  return base;
75
85
  }
76
86
  base.expr = ctx.code(expr);
77
87
  base.reactive = isHandler ? false : isReactive(expr);
88
+ // Every prop, not only the ones that move: a panel names the line for each of them.
89
+ // Nothing treats this as a binding position — that asks for `reactive` as well.
90
+ base.at = posOf(expr, ctx);
78
91
  if (expr.type === 'JSXElement' || expr.type === 'JSXFragment')
79
92
  base.jsxElement = true;
80
93
  return base;
@@ -143,7 +156,13 @@ function buildChildren(children, ctx) {
143
156
  else if (child.type === 'JSXExpressionContainer') {
144
157
  if (child.expression?.type !== 'JSXEmptyExpression') {
145
158
  const expr = child.expression;
146
- out.push({ kind: 'expr', code: ctx.code(expr), reactive: isReactive(expr) });
159
+ const reactive = isReactive(expr);
160
+ out.push({
161
+ kind: 'expr',
162
+ code: ctx.code(expr),
163
+ reactive,
164
+ ...(reactive ? { at: posOf(expr, ctx) } : {}),
165
+ });
147
166
  }
148
167
  }
149
168
  else if (child.type === 'JSXElement' || child.type === 'JSXFragment') {
@@ -177,11 +196,14 @@ function buildNode(node, ctx) {
177
196
  const { tag, component } = tagInfo(node.openingElement.name, ctx);
178
197
  const props = buildProps(node.openingElement.attributes, ctx);
179
198
  const children = buildChildren(node.children, ctx);
199
+ const at = ctx.sourceFile && node.loc?.start
200
+ ? { file: ctx.sourceFile, line: node.loc.start.line, column: node.loc.start.column }
201
+ : undefined;
180
202
  if (component) {
181
203
  const load = readLoad(node.openingElement.attributes);
182
- return { kind: 'component', name: tag, props, children, ...(load ? { load } : {}) };
204
+ return { kind: 'component', name: tag, props, children, ...(load ? { load } : {}), ...(at ? { at } : {}) };
183
205
  }
184
- return { kind: 'element', tag, svg: SVG_TAGS.has(tag), props, children, static: false };
206
+ return { kind: 'element', tag, svg: SVG_TAGS.has(tag), props, children, static: false, ...(at ? { at } : {}) };
185
207
  }
186
208
  /** Build IR from a JSXElement or JSXFragment. */
187
209
  export function buildJsxIR(node, ctx) {
@@ -1 +1 @@
1
- var b={kind:"eager"},w=["pointerdown","focusin","keydown"],h=new Set(["eager","idle","visible","interaction","media","never"]),c=class extends Error{};function d(e){return e.startsWith("load:")}function E(e,t){let n=e.slice(5);if(!h.has(n))throw new c(`Unknown load strategy 'load:${n}'. Expected one of ${[...h].join(", ")}.`);switch(n){case"eager":return b;case"idle":return{kind:"idle"};case"never":return{kind:"never"};case"visible":return t?{kind:"visible",rootMargin:t}:{kind:"visible"};case"interaction":return{kind:"interaction",events:t?J(t):[...w]};case"media":if(!t)throw new c(`'load:media' needs a query, e.g. load:media="(min-width: 1024px)".`);return{kind:"media",query:t};default:throw new c(`Unhandled load strategy '${n}'.`)}}function J(e){let t=e.split(/[\s,]+/).map(n=>n.trim()).filter(Boolean);if(t.length===0)throw new c("'load:interaction' was given no event names.");return t}var L="children";function f(e){switch(e.kind){case"call":return!0;case"member":return e.property!==L;case"compound":return e.parts.some(f);case"opaque":return!1}}var C=new Set(["CallExpression","OptionalCallExpression"]),X=new Set(["MemberExpression","OptionalMemberExpression"]);function m(e){if(!e)return{kind:"opaque"};if(C.has(e.type))return{kind:"call"};if(X.has(e.type)){let t=e.property;return{kind:"member",property:!(e.computed===!0)&&t?.type==="Identifier"?t.name:null}}return e.type==="ConditionalExpression"?{kind:"compound",parts:[e.test,e.consequent,e.alternate].map(l)}:e.type==="LogicalExpression"||e.type==="BinaryExpression"?{kind:"compound",parts:[e.left,e.right].map(l)}:e.type==="TemplateLiteral"?{kind:"compound",parts:e.expressions.map(l)}:e.type==="ObjectExpression"?{kind:"compound",parts:e.properties.filter(n=>(n.type==="ObjectProperty"||n.type==="Property")&&n.computed!==!0).map(n=>l(n.value))}:e.type==="ArrayExpression"?{kind:"compound",parts:e.elements.filter(n=>n!=null&&n.type!=="SpreadElement").map(l)}:{kind:"opaque"}}var l=e=>m(e);function A(e){switch(e.kind){case"event":return"event";case"ref":return"ref";case"spread":return"spread";case"class":case"style":return"class-or-style-directive";case"attr":case"prop":return e.reactive?"reactive-prop":e.expr!==void 0?"expression-prop":void 0;default:return"expression-prop"}}function k(e){let t=[],n=new Map,o=r=>{switch(r.kind){case"text":return!0;case"expr":return!1;case"component":case"control":for(let s of r.children)o(s);return!1;case"fragment":for(let s of r.children)o(s);return!1;case"element":{let s=!0;for(let a of r.children)o(a)||(s=!1);let i;for(let a of r.props)if(i=A(a),i)break;return!i&&!s&&(i=$(r)),r.static=!i,i?n.set(r,i):t.push(r),r.static}default:return!1}};for(let r of Array.isArray(e)?e:[e])o(r);return{staticElements:t,reasons:n}}function $(e){for(let t of e.children){if(t.kind==="expr")return"expression-child";if(t.kind==="component")return"component-child";if(t.kind==="control")return"control-child";if(t.kind==="element"&&!t.static||t.kind==="fragment")return"expression-child"}return"expression-child"}function v(e){let t=e.split(/\r\n|\n|\r/),n=0;for(let r=0;r<t.length;r++)/[^ \t]/.test(t[r])&&(n=r);let o="";for(let r=0;r<t.length;r++){let s=t[r].replace(/\t/g," ");r!==0&&(s=s.replace(/^ +/,"")),r!==t.length-1&&(s=s.replace(/ +$/,"")),s&&(r!==n&&(s+=" "),o+=s)}return o}var T=new Set(["svg","path","circle","rect","line","polygon","polyline","ellipse","g","defs","clipPath","text"]),D=/^on[A-Z]/,P=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]),N=e=>f(m(e));function u(e){if(e.type==="StringLiteral"||e.type==="NumericLiteral"||e.type==="BooleanLiteral"||e.type==="Literal"&&(typeof e.value=="string"||typeof e.value=="number"||typeof e.value=="boolean"))return e.value}var y=e=>!!e&&typeof u(e)=="string";function M(e,t){return e.type==="JSXIdentifier"?{tag:e.name,component:e.name[0]!==e.name[0].toLowerCase()}:e.type==="JSXMemberExpression"?{tag:t.code(e),component:!0}:e.type==="JSXNamespacedName"?{tag:`${e.namespace.name}:${e.name.name}`,component:!1}:{tag:"div",component:!1}}function x(e){return e.type==="JSXIdentifier"?e.name==="class"?"className":e.name:e.type==="JSXNamespacedName"?`${e.namespace.name}:${e.name.name}`:"unknown"}function j(e,t){let n=x(e.name),o=D.test(n),r=o||n.startsWith("on:")||n==="ref",i={name:n,kind:o?"event":"attr"};if(o){let p=n.slice(2).toLowerCase();i.event={name:p,delegated:P.has(p)}}let a=e.value;if(a==null)return i.literal=!0,i;if(y(a))return i.literal=u(a),i;if(a.type==="JSXExpressionContainer"&&a.expression?.type!=="JSXEmptyExpression"){let p=a.expression,g=u(p);return g!==void 0?(i.literal=g,i):(i.expr=t.code(p),i.reactive=r?!1:N(p),(p.type==="JSXElement"||p.type==="JSXFragment")&&(i.jsxElement=!0),i)}return i.literal=!0,i}function S(e,t){let n=e.value;return n==null?null:y(n)?JSON.stringify(u(n)):n.type==="JSXExpressionContainer"&&n.expression?.type!=="JSXEmptyExpression"?t.code(n.expression):null}function q(e,t){let n=[],o=[];for(let r of e){if(r.type==="JSXSpreadAttribute"){n.push({name:"",kind:"spread",expr:t.code(r.argument)});continue}if(r.type!=="JSXAttribute"||d(x(r.name)))continue;let s=r.name.type==="JSXNamespacedName"?r.name.namespace.name:null;if(s==="use"){let i=r.name.name.name;t.used.add(i);let a=S(r,t);o.push(a!=null?`[${i}, () => (${a})]`:`[${i}]`);continue}if(s==="oncapture"){let i=r.name.name.name.toLowerCase(),a=S(r,t)??"undefined";n.push({name:"on:"+i,kind:"attr",expr:`[${a}, { capture: true }]`});continue}n.push(j(r,t))}return o.length>0&&n.push({name:"use",kind:"attr",expr:`[${o.join(", ")}]`}),n}function R(e,t){let n=[];for(let o of e)if(o.type==="JSXText"){let r=v(o.value);r&&n.push({kind:"text",value:r})}else if(o.type==="JSXExpressionContainer"){if(o.expression?.type!=="JSXEmptyExpression"){let r=o.expression;n.push({kind:"expr",code:t.code(r),reactive:N(r)})}}else o.type==="JSXElement"||o.type==="JSXFragment"?n.push(I(o,t)):o.type==="JSXSpreadChild"&&n.push({kind:"expr",code:t.code(o.expression),reactive:!1});return n}function O(e){for(let t of e){if(t.type!=="JSXAttribute")continue;let n=x(t.name);if(d(n)){if(t.value&&!y(t.value))throw new c(`'${n}' needs a literal value, not an expression — the strategy is compile-time.`);return E(n,t.value?u(t.value):null)}}}function I(e,t){if(e.type==="JSXFragment")return{kind:"fragment",children:R(e.children,t)};let{tag:n,component:o}=M(e.openingElement.name,t),r=q(e.openingElement.attributes,t),s=R(e.children,t);if(o){let i=O(e.openingElement.attributes);return{kind:"component",name:n,props:r,children:s,...i?{load:i}:{}}}return{kind:"element",tag:n,svg:T.has(n),props:r,children:s,static:!1}}function Z(e,t){let n=I(e,t);return k(n),n}export{T as SVG_TAGS,Z as buildJsxIR};
1
+ var w={kind:"eager"},J=["pointerdown","focusin","keydown"],E=new Set(["eager","idle","visible","interaction","media","never"]),c=class extends Error{};function f(e){return e.startsWith("load:")}function k(e,t){let n=e.slice(5);if(!E.has(n))throw new c(`Unknown load strategy 'load:${n}'. Expected one of ${[...E].join(", ")}.`);switch(n){case"eager":return w;case"idle":return{kind:"idle"};case"never":return{kind:"never"};case"visible":return t?{kind:"visible",rootMargin:t}:{kind:"visible"};case"interaction":return{kind:"interaction",events:t?L(t):[...J]};case"media":if(!t)throw new c(`'load:media' needs a query, e.g. load:media="(min-width: 1024px)".`);return{kind:"media",query:t};default:throw new c(`Unhandled load strategy '${n}'.`)}}function L(e){let t=e.split(/[\s,]+/).map(n=>n.trim()).filter(Boolean);if(t.length===0)throw new c("'load:interaction' was given no event names.");return t}var C="children";function m(e){switch(e.kind){case"call":return!0;case"member":return e.property!==C;case"compound":return e.parts.some(m);case"opaque":return!1}}var X=new Set(["CallExpression","OptionalCallExpression"]),A=new Set(["MemberExpression","OptionalMemberExpression"]);function y(e){if(!e)return{kind:"opaque"};if(X.has(e.type))return{kind:"call"};if(A.has(e.type)){let t=e.property;return{kind:"member",property:!(e.computed===!0)&&t?.type==="Identifier"?t.name:null}}return e.type==="ConditionalExpression"?{kind:"compound",parts:[e.test,e.consequent,e.alternate].map(l)}:e.type==="LogicalExpression"||e.type==="BinaryExpression"?{kind:"compound",parts:[e.left,e.right].map(l)}:e.type==="TemplateLiteral"?{kind:"compound",parts:e.expressions.map(l)}:e.type==="ObjectExpression"?{kind:"compound",parts:e.properties.filter(n=>(n.type==="ObjectProperty"||n.type==="Property")&&n.computed!==!0).map(n=>l(n.value))}:e.type==="ArrayExpression"?{kind:"compound",parts:e.elements.filter(n=>n!=null&&n.type!=="SpreadElement").map(l)}:{kind:"opaque"}}var l=e=>y(e);function $(e){switch(e.kind){case"event":return"event";case"ref":return"ref";case"spread":return"spread";case"class":case"style":return"class-or-style-directive";case"attr":case"prop":return e.reactive?"reactive-prop":e.expr!==void 0?"expression-prop":void 0;default:return"expression-prop"}}function v(e){let t=[],n=new Map,o=r=>{switch(r.kind){case"text":return!0;case"expr":return!1;case"component":case"control":for(let s of r.children)o(s);return!1;case"fragment":for(let s of r.children)o(s);return!1;case"element":{let s=!0;for(let a of r.children)o(a)||(s=!1);let i;for(let a of r.props)if(i=$(a),i)break;return!i&&!s&&(i=T(r)),r.static=!i,i?n.set(r,i):t.push(r),r.static}default:return!1}};for(let r of Array.isArray(e)?e:[e])o(r);return{staticElements:t,reasons:n}}function T(e){for(let t of e.children){if(t.kind==="expr")return"expression-child";if(t.kind==="component")return"component-child";if(t.kind==="control")return"control-child";if(t.kind==="element"&&!t.static||t.kind==="fragment")return"expression-child"}return"expression-child"}function S(e){let t=e.split(/\r\n|\n|\r/),n=0;for(let r=0;r<t.length;r++)/[^ \t]/.test(t[r])&&(n=r);let o="";for(let r=0;r<t.length;r++){let s=t[r].replace(/\t/g," ");r!==0&&(s=s.replace(/^ +/,"")),r!==t.length-1&&(s=s.replace(/ +$/,"")),s&&(r!==n&&(s+=" "),o+=s)}return o}var D=new Set(["svg","path","circle","rect","line","polygon","polyline","ellipse","g","defs","clipPath","text"]),P=/^on[A-Z]/,M=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]),b=e=>m(y(e)),u=(e,t)=>{if(!t.sourceFile)return;let n=e.loc?.start;return n?{line:n.line,column:n.column}:void 0};function d(e){if(e.type==="StringLiteral"||e.type==="NumericLiteral"||e.type==="BooleanLiteral"||e.type==="Literal"&&(typeof e.value=="string"||typeof e.value=="number"||typeof e.value=="boolean"))return e.value}var x=e=>!!e&&typeof d(e)=="string";function O(e,t){return e.type==="JSXIdentifier"?{tag:e.name,component:e.name[0]!==e.name[0].toLowerCase()}:e.type==="JSXMemberExpression"?{tag:t.code(e),component:!0}:e.type==="JSXNamespacedName"?{tag:`${e.namespace.name}:${e.name.name}`,component:!1}:{tag:"div",component:!1}}function g(e){return e.type==="JSXIdentifier"?e.name==="class"?"className":e.name:e.type==="JSXNamespacedName"?`${e.namespace.name}:${e.name.name}`:"unknown"}function j(e,t){let n=g(e.name),o=P.test(n),r=o||n.startsWith("on:")||n==="ref",i={name:n,kind:o?"event":"attr"};if(o){let p=n.slice(2).toLowerCase();i.event={name:p,delegated:M.has(p)}}let a=e.value;if(a==null)return i.literal=!0,i.at=u(e,t),i;if(x(a))return i.literal=d(a),i.at=u(a,t),i;if(a.type==="JSXExpressionContainer"&&a.expression?.type!=="JSXEmptyExpression"){let p=a.expression,h=d(p);return h!==void 0?(i.literal=h,i.at=u(p,t),i):(i.expr=t.code(p),i.reactive=r?!1:b(p),i.at=u(p,t),(p.type==="JSXElement"||p.type==="JSXFragment")&&(i.jsxElement=!0),i)}return i.literal=!0,i}function R(e,t){let n=e.value;return n==null?null:x(n)?JSON.stringify(d(n)):n.type==="JSXExpressionContainer"&&n.expression?.type!=="JSXEmptyExpression"?t.code(n.expression):null}function q(e,t){let n=[],o=[];for(let r of e){if(r.type==="JSXSpreadAttribute"){n.push({name:"",kind:"spread",expr:t.code(r.argument)});continue}if(r.type!=="JSXAttribute"||f(g(r.name)))continue;let s=r.name.type==="JSXNamespacedName"?r.name.namespace.name:null;if(s==="use"){let i=r.name.name.name;t.used.add(i);let a=R(r,t);o.push(a!=null?`[${i}, () => (${a})]`:`[${i}]`);continue}if(s==="oncapture"){let i=r.name.name.name.toLowerCase(),a=R(r,t)??"undefined";n.push({name:"on:"+i,kind:"attr",expr:`[${a}, { capture: true }]`});continue}n.push(j(r,t))}return o.length>0&&n.push({name:"use",kind:"attr",expr:`[${o.join(", ")}]`}),n}function N(e,t){let n=[];for(let o of e)if(o.type==="JSXText"){let r=S(o.value);r&&n.push({kind:"text",value:r})}else if(o.type==="JSXExpressionContainer"){if(o.expression?.type!=="JSXEmptyExpression"){let r=o.expression,s=b(r);n.push({kind:"expr",code:t.code(r),reactive:s,...s?{at:u(r,t)}:{}})}}else o.type==="JSXElement"||o.type==="JSXFragment"?n.push(I(o,t)):o.type==="JSXSpreadChild"&&n.push({kind:"expr",code:t.code(o.expression),reactive:!1});return n}function F(e){for(let t of e){if(t.type!=="JSXAttribute")continue;let n=g(t.name);if(f(n)){if(t.value&&!x(t.value))throw new c(`'${n}' needs a literal value, not an expression — the strategy is compile-time.`);return k(n,t.value?d(t.value):null)}}}function I(e,t){if(e.type==="JSXFragment")return{kind:"fragment",children:N(e.children,t)};let{tag:n,component:o}=O(e.openingElement.name,t),r=q(e.openingElement.attributes,t),s=N(e.children,t),i=t.sourceFile&&e.loc?.start?{file:t.sourceFile,line:e.loc.start.line,column:e.loc.start.column}:void 0;if(o){let a=F(e.openingElement.attributes);return{kind:"component",name:n,props:r,children:s,...a?{load:a}:{},...i?{at:i}:{}}}return{kind:"element",tag:n,svg:D.has(n),props:r,children:s,static:!1,...i?{at:i}:{}}}function Q(e,t){let n=I(e,t);return v(n),n}export{D as SVG_TAGS,Q as buildJsxIR};
@@ -1 +1 @@
1
- "use strict";var R=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var q=Object.getOwnPropertyNames;var G=Object.prototype.hasOwnProperty;var K=(t,e)=>{for(var n in e)R(t,n,{get:e[n],enumerable:!0})},Y=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of q(e))!G.call(t,i)&&i!==n&&R(t,i,{get:()=>e[i],enumerable:!(r=W(e,i))||r.enumerable});return t};var Z=t=>Y(R({},"__esModule",{value:!0}),t);var Re={};K(Re,{lowerTemplate:()=>Ne});module.exports=Z(Re);var U=require("@fluixi/template-parser");var X={kind:"eager"},Q=["pointerdown","focusin","keydown"],T=new Set(["eager","idle","visible","interaction","media","never"]),u=class extends Error{};function S(t,e){let n=t.slice(5);if(!T.has(n))throw new u(`Unknown load strategy 'load:${n}'. Expected one of ${[...T].join(", ")}.`);switch(n){case"eager":return X;case"idle":return{kind:"idle"};case"never":return{kind:"never"};case"visible":return e?{kind:"visible",rootMargin:e}:{kind:"visible"};case"interaction":return{kind:"interaction",events:e?ee(e):[...Q]};case"media":if(!e)throw new u(`'load:media' needs a query, e.g. load:media="(min-width: 1024px)".`);return{kind:"media",query:e};default:throw new u(`Unhandled load strategy '${n}'.`)}}function ee(t){let e=t.split(/[\s,]+/).map(n=>n.trim()).filter(Boolean);if(e.length===0)throw new u("'load:interaction' was given no event names.");return e}var te=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),C={className:"class",htmlFor:"for"},ne=new Set(["innerHTML","outerHTML","innerText","textContent","value","checked","selected","muted","defaultValue","defaultChecked","children","ref"]),re=new Set(["script","style","textarea","title"]);function $(t){return re.has(t)}function P(t){return C[t]??t}function h(t){return t.kind!=="attr"||t.expr!==void 0||t.name.includes(":")?!1:!ne.has(t.name)}function b(t){if(!t.static||$(t.tag))return!1;for(let e of t.props)if(!h(e))return!1;for(let e of t.children)if(e.kind!=="text"&&!(e.kind==="element"&&b(e)))return!1;return!0}function f(t){let e=t.props.map(oe).filter(Boolean).join(""),n=`<${t.tag}${e}>`;return te.has(t.tag)?n:`${n}${t.children.map(ie).join("")}</${t.tag}>`}function ie(t){if(t.kind==="text")return ae(t.value);if(t.kind!=="element")throw new Error(`serializeStatic: unexpected ${t.kind}`);return f(t)}function oe(t){let e=C[t.name]??t.name,n=t.literal;return n===!0||n===void 0?` ${e}`:n===!1||n===null?"":` ${e}="${se(String(n))}"`}function se(t){return t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function ae(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var le="<!--fx-->",ce="<!--fx/-->";function N(t){return t.kind==="expr"||t.kind==="component"||t.kind==="control"}function de(t){return t.kind==="text"||t.kind==="element"&&A(t)}function A(t){return t.svg||$(t.tag)||!t.props.every(e=>h(e))?!1:t.children.every(e=>de(e)||N(e))}function k(t){if(N(t))return!0;let e=t.children;return e?e.some(k):!1}function L(t){for(let e=0;e<t.children.length;e++){let n=t.children[e];if(n.kind==="text"&&(n.value===""||t.children[e+1]?.kind==="text"))return!1}return t.children.every(e=>e.kind!=="element"||L(e))}function D(t){if(!A(t)||!L(t)||!t.children.some(k))return null;let e=[],n=[],r=0,i=c=>{let s=`_n$${r++}`;return e.push({ref:s,expr:c}),s};return o(t,"_el$"),{html:pe(t),tag:t.tag,steps:e,holes:n};function o(c,s){let a=-1;c.children.forEach((d,p)=>{k(d)&&(a=p)});let l=null;for(let d=0;d<=a;d++){let p=c.children[d],m=l?`${l}.nextSibling`:`${s}.firstChild`;if(N(p)){let w=i(m),y=i(`holeEnd(${w})`);n.push({parentRef:s,startRef:w,endRef:y,node:p}),l=y;continue}let v=i(m);p.kind==="element"&&k(p)&&o(p,v),l=v}}}function pe(t){return f(j(t)).split(O).join(le+ce)}function j(t){return{...t,children:t.children.map(e=>N(e)?{kind:"text",value:O}:e.kind==="element"?j(e):e)}}var O="\0fx-hole\0";var x={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},we={version:2,module:"@fluixi/dom",symbols:[...x.symbols,"template","cloneTemplate","walk"]};var ue={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function me(t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)}function M(t){return me(t)?t:JSON.stringify(t)}function he(t){return t.expr!==void 0?t.reactive?`() => (${t.expr})`:`(${t.expr})`:JSON.stringify(t.literal??!0)}function fe(t){return t.expr!==void 0?`(${t.expr})`:JSON.stringify(t.literal??!0)}function ge(t,e,n){let r=t.filter(s=>s.kind==="spread"),o=t.filter(s=>s.kind!=="spread").map(s=>`${M(s.name)}: ${he(s)}`);e!=null&&o.push(`children: ${e}`);let c=`{ ${o.join(", ")} }`;return r.length>0?(n.add("mergeProps"),`mergeProps(${r.map(s=>s.expr).join(", ")}, ${c})`):c}function H(t,e,n){return t.length===1?g(t[0],e,n):`[${t.map(r=>g(r,e,n)).join(", ")}]`}function _(t,e,n,r,i){r.add("createMemo"),r.add("createComponent");let o=e.filter(l=>l.kind==="spread"),s=e.filter(l=>l.kind!=="spread").map(l=>`get ${M(l.name)}() { return ${fe(l)}; }`);n.length>0&&s.push(`get children() { return ${H(n,r,i)}; }`);let a=`{ ${s.join(", ")} }`;return o.length>0&&(r.add("mergeProps"),a=`mergeProps(${o.map(l=>l.expr).join(", ")}, ${a})`),`createMemo(() => createComponent(${t}, ${a}))`}function ve(t,e){let n=P(e.name),r=e.literal;return r===!0||r===void 0?`${t}.setAttribute(${JSON.stringify(n)}, "");`:r===!1||r===null?"":`${t}.setAttribute(${JSON.stringify(n)}, ${JSON.stringify(String(r))});`}var B=!1;function g(t,e,n){switch(t.kind){case"text":return JSON.stringify(t.value);case"expr":return t.reactive?`() => (${t.code})`:`(${t.code})`;case"fragment":return t.children.length===0?"null":H(t.children,e,n);case"component":return _(t.name,t.props,t.children,e,n);case"control":{let r=ue[t.control]??t.control;return e.add(r),_(r,t.props,t.children,e,n)}case"element":{if(n&&t.static&&!t.svg&&b(t)){e.add("templateNode");let s=`_tmpl$${n.length}`;return n.push({id:s,html:f(t),tag:t.tag,svg:!1}),`templateNode(${s}, ${JSON.stringify(t.tag)})`}if(n&&B){let s=D(t);if(s){e.add("templateNode"),e.add("insert"),e.add("holeEnd"),e.add("holeContent"),e.add("holeScope");let a=`_tmpl$${n.length}`;n.push({id:a,html:s.html,tag:s.tag,svg:!1});let l=[`const _el$ = templateNode(${a}, ${JSON.stringify(s.tag)}, true);`];for(let d of s.steps)l.push(`const ${d.ref} = ${d.expr};`);for(let d of s.holes)l.push(`insert(${d.parentRef}, holeScope(${d.startRef}, () => (${g(d.node,e,n)})), ${d.endRef}, holeContent(${d.startRef}, ${d.endRef}));`);return l.push("return _el$;"),`(() => { ${l.join(" ")} })()`}}e.add("createNativeElement");let r=JSON.stringify(t.tag),i="_el$",o=[],c=t.svg?`${r}, true`:r;if(o.push(`const ${i} = createNativeElement(${c});`),t.props.length>0)if(!t.svg&&t.props.every(h))for(let s of t.props)o.push(ve(i,s));else{e.add("spread");let s=t.svg?", isSVG: true":"";o.push(`spread({ element: ${i}, props: ${ge(t.props,null,e)}${s} });`)}for(let s of t.children){e.add("insert");let a=g(s,e,n),l=s.kind==="expr"&&s.reactive||s.kind==="component"||s.kind==="control";o.push(l?`insert(${i}, ${a}, null);`:`insert(${i}, ${a});`)}return o.push(`return ${i};`),`(() => { ${o.join(" ")} })()`}}}function J(t,e){if(!e||e.length===0)return t;let n=new Map(e.map(r=>[r.id,JSON.stringify(r.html)]));return t.replace(/_tmpl\$\d+/g,r=>n.get(r)??r)}var z={name:"imperative",contract:x,emit(t,e){let n=new Set,r=e?.templateClone!==!1?[]:void 0;return B=e?.partialTemplates===!0,{code:g(t,n,r),imports:Array.from(n),templates:r}}};function E(t){let e=t.split(/\r\n|\n|\r/),n=0;for(let i=0;i<e.length;i++)/[^ \t]/.test(e[i])&&(n=i);let r="";for(let i=0;i<e.length;i++){let o=e[i].replace(/\t/g," ");i!==0&&(o=o.replace(/^ +/,"")),i!==e.length-1&&(o=o.replace(/ +$/,"")),o&&(i!==n&&(o+=" "),r+=o)}return r}var V=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]);function ke(t){return t.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/\$\{/g,"\\${")}function F(t){return t.charAt(0).toUpperCase()+t.slice(1)}var I=class{constructor(e,n){this.holes=e;this.used=n}hole(e){return this.holes[e]??{code:"undefined",reactive:!1}}emit(e){let{code:n,imports:r,templates:i}=z.emit(e,{});for(let o of r)this.used.add(o);return J(n,i)}lowerRoot(e){let n=this.lowerChildren(e);return n.length===1?n[0]:{kind:"fragment",children:n}}lowerChildren(e){let n=[];for(let r=0;r<e.length;r++){let i=e[r];if(i.kind==="Element"||i.kind==="Component"){let c=i.attributes.find(s=>s.kind==="IfDirective");if(c&&c.kind==="IfDirective"){let s=r+1;s<e.length&&this.isBlankText(e[s])&&s++;let a=e[s],l=a&&(a.kind==="Element"||a.kind==="Component")&&a.attributes.some(d=>d.kind==="ElseDirective");n.push(this.lowerIf(i,c.hole,l?a:null)),l&&(r=s);continue}if(i.attributes.some(s=>s.kind==="EachDirective")){n.push(this.lowerEach(i));continue}}let o=this.lowerNode(i);o&&n.push(o)}return n}isBlankText(e){return e.kind==="Text"&&!e.raw&&E(e.value)===""}lowerNode(e){switch(e.kind){case"Text":{if(e.raw)return{kind:"text",value:e.value};let n=E(e.value);return n?{kind:"text",value:n}:null}case"Comment":return null;case"Expression":{let n=this.hole(e.hole);return{kind:"expr",code:n.code,reactive:n.reactive}}case"Fragment":return{kind:"fragment",children:this.lowerChildren(e.children)};case"Element":return this.lowerElement(e);case"Component":return this.lowerComponent(e);default:return null}}lowerElement(e){let n=e.attributes.find(r=>r.kind==="Attribute"&&r.name==="is");if(e.tag==="component"&&n&&n.value&&n.value.kind==="hole"){let r=e.attributes.filter(o=>o!==n),i=this.lowerComponent({...e,kind:"Component",tag:"Dynamic",tagHole:null,attributes:r});return i.props.unshift({name:"component",kind:"attr",expr:`() => (${this.hole(n.value.hole).code})`}),i}return{kind:"element",tag:e.tag,svg:e.namespace==="svg",props:this.lowerAttributes(e.attributes),children:this.lowerChildren(e.children),static:!1}}lowerComponent(e){let n=e.tagHole!=null?this.hole(e.tagHole).code:e.tag,r=this.lowerAttributes(e.attributes),{slots:i,rest:o}=this.partitionSlots(e.children);for(let[a,l]of i){let d=l.length===1?l[0]:{kind:"fragment",children:l},p={name:a,kind:"attr",expr:this.emit(d),jsxElement:!0},m=r.findIndex(v=>v.name===a);m>=0?r[m]=p:r.push(p)}let c=e.attributes.find(a=>a.kind==="LoadDirective"),s=c?S(`load:${c.strategy}`,c.modifier):void 0;return{kind:"component",name:n,props:r,children:this.lowerChildren(o),...s?{load:s}:{}}}partitionSlots(e){let n=new Map,r=[];for(let i of e){if(i.kind==="Element"||i.kind==="Component"){let o=i.attributes.find(c=>c.kind==="Attribute"&&c.name==="slot");if(o&&o.value&&o.value.kind==="static"){let c={...i,attributes:i.attributes.filter(l=>l!==o)},s=c.kind==="Element"?this.lowerElement(c):this.lowerComponent(c),a=n.get(o.value.value)??[];a.push(s),n.set(o.value.value,a);continue}}r.push(i)}return{slots:n,rest:r}}lowerIf(e,n,r){let i=this.hole(n),o=[{name:"when",kind:"attr",expr:i.code,reactive:i.reactive}];if(r){let s=this.stripAndLower(r,a=>a.kind==="ElseDirective");o.push({name:"fallback",kind:"attr",expr:this.emit(s),jsxElement:!0})}let c=this.stripAndLower(e,s=>s.kind==="IfDirective");return{kind:"component",name:"Show",props:o,children:[c]}}lowerEach(e){let n=e.attributes.find(a=>a.kind==="EachDirective");if(!n||n.kind!=="EachDirective")return this.lowerNode(e);let r=this.hole(n.hole),i=[{name:"each",kind:"attr",expr:r.code,reactive:r.reactive}];if(n.key){let a="static"in n.key?`(item) => item[${JSON.stringify(n.key.static)}]`:this.hole(n.key.hole).code;i.push({name:"by",kind:"attr",expr:a})}let o=this.itemArrow(e),c;if(o){let a={kind:"expr",code:o.body,reactive:o.bodyReactive},l=this.rebuildWithChildren(e,[a]);c=`(${o.params.join(", ")}) => (${this.emit(l)})`}else{let a=this.stripAndLower(e,l=>l.kind==="EachDirective");c=`() => (${this.emit(a)})`}return{kind:"component",name:"For",props:i,children:[{kind:"expr",code:c,reactive:!1}]}}itemArrow(e){let n=e.children.filter(r=>!this.isBlankText(r));return n.length!==1||n[0].kind!=="Expression"?null:this.hole(n[0].hole).arrow??null}stripAndLower(e,n){let r={...e,attributes:e.attributes.filter(i=>!n(i))};return r.kind==="Element"?this.lowerElement(r):this.lowerComponent(r)}rebuildWithChildren(e,n){let r=this.lowerAttributes(e.attributes.filter(i=>i.kind!=="EachDirective"));return e.kind==="Element"?{kind:"element",tag:e.tag,svg:e.namespace==="svg",props:r,children:n,static:!1}:{kind:"component",name:e.tag,props:r,children:n}}lowerAttributes(e){let n=[],r=[],i=!1,o=[],c=!1,s=[];for(let a of e)switch(a.kind){case"IfDirective":case"EachDirective":case"ElseDirective":break;case"Attribute":n.push(this.plainAttr(a));break;case"PropertyBinding":n.push({name:a.name,kind:"prop",expr:this.hole(a.hole).code,reactive:this.hole(a.hole).reactive});break;case"EventBinding":n.push(this.eventProp(a));break;case"RefBinding":n.push({name:"ref",kind:"ref",expr:this.hole(a.hole).code,reactive:this.hole(a.hole).reactive});break;case"Spread":n.push({name:"",kind:"spread",expr:this.hole(a.hole).code});break;case"ClassDirective":{let l=this.hole(a.hole);r.push(`${JSON.stringify(a.name)}: ${l.code}`),i=i||l.reactive;break}case"StyleDirective":{let l=this.hole(a.hole);o.push(`${JSON.stringify(a.name)}: ${l.code}`),c=c||l.reactive;break}case"BindDirective":n.push(...this.bindProps(a.name,this.hole(a.hole).code));break;case"UseDirective":{let l=a.name??(a.hole!=null?this.hole(a.hole).code:null);if(!l)break;s.push(a.name!=null&&a.hole!=null?`[${l}, () => (${this.hole(a.hole).code})]`:`[${l}]`);break}}return r.length>0&&n.push({name:"classList",kind:"attr",expr:`{ ${r.join(", ")} }`,reactive:i}),o.length>0&&n.push({name:"style",kind:"attr",expr:`{ ${o.join(", ")} }`,reactive:c}),s.length>0&&n.push({name:"use",kind:"attr",expr:`[${s.join(", ")}]`}),n}eventProp(e){let n=e.name.toLowerCase(),r=this.hole(e.hole).code;if(!(e.syntax==="colon"||e.modifiers.length>0))return{name:"on"+F(e.name),kind:"event",event:{name:n,delegated:V.has(n)},expr:r};let o=this.wrapHandler(r,e.modifiers),c=this.eventOptions(e.modifiers),s=c?`[${o}, ${c}]`:o;return{name:"on:"+n,kind:"attr",expr:s}}wrapHandler(e,n){let r=n.includes("self")?"if (e.target !== e.currentTarget) return; ":"",i=[];return n.includes("prevent")&&i.push("e.preventDefault();"),n.includes("stop")&&i.push("e.stopPropagation();"),!r&&i.length===0?e:`(e) => { ${r}${i.join(" ")} return (${e})(e); }`}eventOptions(e){let n=[];return e.includes("capture")&&n.push("capture: true"),e.includes("once")&&n.push("once: true"),e.includes("passive")&&n.push("passive: true"),n.length?`{ ${n.join(", ")} }`:null}bindProps(e,n){let r=e==="checked",i=r?"change":"input",o=r?"checked":"value";this.used.add("bindPair");let c=`bindPair(${n})`;return[{name:e,kind:"attr",expr:`${c}[0]()`,reactive:!0},{name:"on"+F(i),kind:"event",event:{name:i,delegated:V.has(i)},expr:`(e) => ${c}[1](e.target.${o})`}]}plainAttr(e){let n=e.value,r=e.name;e.name==="class"?r=n&&n.kind==="hole"&&this.hole(n.hole).object?"classList":"className":e.name==="html"&&(r="innerHTML");let o={name:r,kind:"attr"};if(n==null)return o.literal=!0,o;if(n.kind==="static")return o.literal=n.value,o;if(n.kind==="hole"){let a=this.hole(n.hole);return o.expr=a.code,o.reactive=a.reactive,o}let c=!1,s=n.parts.map(a=>{if("text"in a)return ke(a.text);let l=this.hole(a.hole);return c=c||l.reactive,"${"+l.code+"}"}).join("");return o.expr="`"+s+"`",o.reactive=c,o}};function Ne(t,e,n,r={}){let{root:i}=(0,U.parseTemplate)(t,{svg:r.svg});return new I(e,n).lowerRoot(i.children)}
1
+ "use strict";var $=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var ee=Object.getOwnPropertyNames;var te=Object.prototype.hasOwnProperty;var ne=(t,e)=>{for(var n in e)$(t,n,{get:e[n],enumerable:!0})},re=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ee(e))!te.call(t,i)&&i!==n&&$(t,i,{get:()=>e[i],enumerable:!(r=Q(e,i))||r.enumerable});return t};var ie=t=>re($({},"__esModule",{value:!0}),t);var Te={};ne(Te,{lowerTemplate:()=>we});module.exports=ie(Te);var X=require("@fluixi/template-parser");var oe={kind:"eager"},se=["pointerdown","focusin","keydown"],P=new Set(["eager","idle","visible","interaction","media","never"]),m=class extends Error{};function D(t,e){let n=t.slice(5);if(!P.has(n))throw new m(`Unknown load strategy 'load:${n}'. Expected one of ${[...P].join(", ")}.`);switch(n){case"eager":return oe;case"idle":return{kind:"idle"};case"never":return{kind:"never"};case"visible":return e?{kind:"visible",rootMargin:e}:{kind:"visible"};case"interaction":return{kind:"interaction",events:e?ae(e):[...se]};case"media":if(!e)throw new m(`'load:media' needs a query, e.g. load:media="(min-width: 1024px)".`);return{kind:"media",query:e};default:throw new m(`Unhandled load strategy '${n}'.`)}}function ae(t){let e=t.split(/[\s,]+/).map(n=>n.trim()).filter(Boolean);if(e.length===0)throw new m("'load:interaction' was given no event names.");return e}var le=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),O={className:"class",htmlFor:"for"},ce=new Set(["innerHTML","outerHTML","innerText","textContent","value","checked","selected","muted","defaultValue","defaultChecked","children","ref"]),ue=new Set(["script","style","textarea","title"]);function I(t){return ue.has(t)}function _(t){return O[t]??t}function N(t){return t.kind!=="attr"||t.expr!==void 0||t.name.includes(":")?!1:!ce.has(t.name)}function E(t){if(!t.static||I(t.tag))return!1;for(let e of t.props)if(!N(e))return!1;for(let e of t.children)if(e.kind!=="text"&&!(e.kind==="element"&&E(e)))return!1;return!0}function v(t){let e=t.props.map(pe).filter(Boolean).join(""),n=`<${t.tag}${e}>`;return le.has(t.tag)?n:`${n}${t.children.map(de).join("")}</${t.tag}>`}function de(t){if(t.kind==="text")return me(t.value);if(t.kind!=="element")throw new Error(`serializeStatic: unexpected ${t.kind}`);return v(t)}function pe(t){let e=O[t.name]??t.name,n=t.literal;return n===!0||n===void 0?` ${e}`:n===!1||n===null?"":` ${e}="${fe(String(n))}"`}function fe(t){return t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function me(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function S(t){let e=[],n,r=i=>{n??=i.at?.file,e.push(i.at?.line??0,i.at?.column??0);for(let o of i.children)o.kind==="element"&&r(o)};return r(t),n&&e.some(i=>i!==0)?{file:n,pos:e}:void 0}var he="<!--fx-->",ge="<!--fx/-->";function x(t){return t.kind==="expr"||t.kind==="component"||t.kind==="control"}function Ne(t){return t.kind==="text"||t.kind==="element"&&M(t)}function M(t){return t.svg||I(t.tag)||!t.props.every(e=>N(e))?!1:t.children.every(e=>Ne(e)||x(e))}function R(t){if(x(t))return!0;let e=t.children;return e?e.some(R):!1}function j(t){for(let e=0;e<t.children.length;e++){let n=t.children[e];if(n.kind==="text"&&(n.value===""||t.children[e+1]?.kind==="text"))return!1}return t.children.every(e=>e.kind!=="element"||j(e))}function L(t){if(!M(t)||!j(t)||!t.children.some(R))return null;let e=[],n=[],r=0,i=l=>{let s=`_n$${r++}`;return e.push({ref:s,expr:l}),s};return o(t,"_el$"),{html:ve(t),tag:t.tag,steps:e,holes:n};function o(l,s){let u=-1;l.children.forEach((a,d)=>{R(a)&&(u=d)});let c=null;for(let a=0;a<=u;a++){let d=l.children[a],p=c?`${c}.nextSibling`:`${s}.firstChild`;if(x(d)){let g=i(p),y=i(`holeEnd(${g})`);n.push({parentRef:s,startRef:g,endRef:y,node:d}),c=y;continue}let h=i(p);d.kind==="element"&&R(d)&&o(d,h),c=h}}}function ve(t){return v(H(t)).split(B).join(he+ge)}function H(t){return{...t,children:t.children.map(e=>x(e)?{kind:"text",value:B}:e.kind==="element"?H(e):e)}}var B="\0fx-hole\0";var w={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},_e={version:2,module:"@fluixi/dom",symbols:[...w.symbols,"template","cloneTemplate","walk"]};var f="@fluixi/reactive/signal",T={$signal:{export:"signal",module:f,returns:"signal-handle"},$memo:{export:"memo",module:f,returns:"memo-handle"},$effect:{export:"effect",module:f,returns:"effect"},$store:{export:"store",module:"@fluixi/reactive/store",returns:"store-handle"},$resource:{export:"resource",module:f,returns:"resource-handle"},$selector:{export:"createSelector",module:f,returns:"memo-accessor"},$deferred:{export:"createDeferred",module:f,returns:"memo-accessor"},$untrack:{export:"untrack",module:f,returns:"plain"},$untrackStore:{export:"untrackStore",module:"@fluixi/reactive/store",returns:"plain"}};var je=new RegExp(`\\$(?:${Object.keys(T).map(t=>t.slice(1)).join("|")})\\s*\\(`);var F="__fx_source";var ke="__fx_hole",k=(t,e,n,r)=>`(globalThis.${ke} ?? ((f) => f))(${t},${e},${n}${r===void 0?"":`,${JSON.stringify(r)}`})`,be="__fx_props",J=(t,e)=>`(globalThis.${be} ?? ((p) => p))(${t},${JSON.stringify(e)})`;var ye={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function Re(t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)}function K(t){return Re(t)?t:JSON.stringify(t)}function xe(t){if(t.expr!==void 0){if(t.name==="ref"&&t.at)return k(`(${t.expr})`,t.at.line,t.at.column,t.expr);if(!t.reactive)return`(${t.expr})`;let e=`() => (${t.expr})`;return t.at?k(e,t.at.line,t.at.column,t.directive):e}return JSON.stringify(t.literal??!0)}function $e(t){return t.expr!==void 0?`(${t.expr})`:JSON.stringify(t.literal??!0)}function Ie(t,e,n){let r=t.filter(s=>s.kind==="spread"),o=t.filter(s=>s.kind!=="spread").map(s=>`${K(s.name)}: ${xe(s)}`);e!=null&&o.push(`children: ${e}`);let l=`{ ${o.join(", ")} }`;return r.length>0?(n.add("mergeProps"),`mergeProps(${r.map(s=>s.expr).join(", ")}, ${l})`):l}function V(t,e){return e?k(t,e.line,e.column):t}function z(t,e,n){return t.length===1?b(t[0],e,n):`[${t.map(r=>b(r,e,n)).join(", ")}]`}function U(t,e,n,r,i,o){r.add("createMemo"),r.add("createComponent");let l=e.filter(p=>p.kind==="spread"),s=e.filter(p=>p.kind!=="spread"),u=s.map(p=>`get ${K(p.name)}() { return ${$e(p)}; }`);n.length>0&&u.push(`get children() { return ${z(n,r,i)}; }`);let c=`{ ${u.join(", ")} }`;l.length>0&&(r.add("mergeProps"),c=`mergeProps(${l.map(p=>p.expr).join(", ")}, ${c})`);let a={};for(let p of s)p.at&&(a[p.name]=[p.at.line,p.at.column]);return Object.keys(a).length&&(c=J(c,a)),`createMemo((${o?`globalThis.${F}?.(${JSON.stringify(o.file)},${o.line},${o.column},${JSON.stringify(t)}), `:""}() => createComponent(${t}, ${c})))`}function Ee(t,e){let n=_(e.name),r=e.literal;return r===!0||r===void 0?`${t}.setAttribute(${JSON.stringify(n)}, "");`:r===!1||r===null?"":`${t}.setAttribute(${JSON.stringify(n)}, ${JSON.stringify(String(r))});`}var W=!1;function b(t,e,n){switch(t.kind){case"text":return JSON.stringify(t.value);case"expr":{if(!t.reactive)return`(${t.code})`;let r=`() => (${t.code})`;return t.at?k(r,t.at.line,t.at.column):r}case"fragment":return t.children.length===0?"null":z(t.children,e,n);case"component":return V(U(t.name,t.props,t.children,e,n,t.at),t.bindAt??t.at);case"control":{let r=ye[t.control]??t.control;return e.add(r),V(U(r,t.props,t.children,e,n),t.bindAt)}case"element":{if(n&&t.static&&!t.svg&&E(t)){e.add("templateNode");let s=`_tmpl$${n.length}`;n.push({id:s,html:v(t),tag:t.tag,svg:!1});let u=S(t);return u?`templateNode(${s}, ${JSON.stringify(t.tag)}, false, false, ${JSON.stringify(u)})`:`templateNode(${s}, ${JSON.stringify(t.tag)})`}if(n&&W){let s=L(t);if(s){e.add("templateNode"),e.add("insert"),e.add("holeEnd"),e.add("holeContent"),e.add("holeScope");let u=`_tmpl$${n.length}`;n.push({id:u,html:s.html,tag:s.tag,svg:!1});let c=S(t),a=[`const _el$ = templateNode(${u}, ${JSON.stringify(s.tag)}, true${c?`, false, ${JSON.stringify(c)}`:""});`];for(let d of s.steps)a.push(`const ${d.ref} = ${d.expr};`);for(let d of s.holes)a.push(`insert(${d.parentRef}, holeScope(${d.startRef}, () => (${b(d.node,e,n)})), ${d.endRef}, holeContent(${d.startRef}, ${d.endRef}));`);return a.push("return _el$;"),`(() => { ${a.join(" ")} })()`}}e.add("createNativeElement");let r=JSON.stringify(t.tag),i="_el$",o=[],l=t.at?`${r}, ${t.svg}, ${JSON.stringify(t.at)}`:t.svg?`${r}, true`:r;if(o.push(`const ${i} = createNativeElement(${l});`),t.props.length>0)if(!t.svg&&t.props.every(N))for(let s of t.props)o.push(Ee(i,s));else{e.add("spread");let s=t.svg?", isSVG: true":"";o.push(`spread({ element: ${i}, props: ${Ie(t.props,null,e)}${s} });`)}for(let s of t.children){e.add("insert");let u=b(s,e,n),c=s.kind==="expr"&&s.reactive||s.kind==="component"||s.kind==="control";o.push(c?`insert(${i}, ${u}, null);`:`insert(${i}, ${u});`)}return o.push(`return ${i};`),`(() => { ${o.join(" ")} })()`}}}function q(t,e){if(!e||e.length===0)return t;let n=new Map(e.map(r=>[r.id,JSON.stringify(r.html)]));return t.replace(/_tmpl\$\d+/g,r=>n.get(r)??r)}var G={name:"imperative",contract:w,emit(t,e){let n=new Set,r=e?.templateClone!==!1?[]:void 0;return W=e?.partialTemplates===!0,{code:b(t,n,r),imports:Array.from(n),templates:r}}};function A(t){let e=t.split(/\r\n|\n|\r/),n=0;for(let i=0;i<e.length;i++)/[^ \t]/.test(e[i])&&(n=i);let r="";for(let i=0;i<e.length;i++){let o=e[i].replace(/\t/g," ");i!==0&&(o=o.replace(/^ +/,"")),i!==e.length-1&&(o=o.replace(/ +$/,"")),o&&(i!==n&&(o+=" "),r+=o)}return r}var Y=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]);function Se(t){return t.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/\$\{/g,"\\${")}function Z(t){return t.charAt(0).toUpperCase()+t.slice(1)}var C=class{constructor(e,n,r,i){this.holes=e;this.used=n;this.sourceFile=r;this.positionAt=i}tagAt(e){let n=e.loc?.start;if(!this.sourceFile||!this.positionAt||n==null)return;let{line:r,column:i}=this.positionAt(n);return{file:this.sourceFile,line:r,column:i}}hole(e){return this.holes[e]??{code:"undefined",reactive:!1}}emit(e){let{code:n,imports:r,templates:i}=G.emit(e,{});for(let o of r)this.used.add(o);return q(n,i)}lowerRoot(e){let n=this.lowerChildren(e);return n.length===1?n[0]:{kind:"fragment",children:n}}lowerChildren(e){let n=[];for(let r=0;r<e.length;r++){let i=e[r];if(i.kind==="Element"||i.kind==="Component"){let l=i.attributes.find(s=>s.kind==="IfDirective");if(l&&l.kind==="IfDirective"){let s=r+1;s<e.length&&this.isBlankText(e[s])&&s++;let u=e[s],c=u&&(u.kind==="Element"||u.kind==="Component")&&u.attributes.some(a=>a.kind==="ElseDirective");n.push(this.lowerIf(i,l.hole,c?u:null)),c&&(r=s);continue}if(i.attributes.some(s=>s.kind==="EachDirective")){n.push(this.lowerEach(i));continue}}let o=this.lowerNode(i);o&&n.push(o)}return n}isBlankText(e){return e.kind==="Text"&&!e.raw&&A(e.value)===""}lowerNode(e){switch(e.kind){case"Text":{if(e.raw)return{kind:"text",value:e.value};let n=A(e.value);return n?{kind:"text",value:n}:null}case"Comment":return null;case"Expression":{let n=this.hole(e.hole);return{kind:"expr",code:n.code,reactive:n.reactive,...n.at?{at:n.at}:{}}}case"Fragment":return{kind:"fragment",children:this.lowerChildren(e.children)};case"Element":return this.lowerElement(e);case"Component":return this.lowerComponent(e);default:return null}}lowerElement(e){let n=e.attributes.find(i=>i.kind==="Attribute"&&i.name==="is");if(e.tag==="component"&&n&&n.value&&n.value.kind==="hole"){let i=e.attributes.filter(l=>l!==n),o=this.lowerComponent({...e,kind:"Component",tag:"Dynamic",tagHole:null,attributes:i});return o.props.unshift({name:"component",kind:"attr",expr:`() => (${this.hole(n.value.hole).code})`}),o}let r=this.tagAt(e);return{kind:"element",tag:e.tag,svg:e.namespace==="svg",props:this.lowerAttributes(e.attributes),children:this.lowerChildren(e.children),static:!1,...r?{at:r}:{}}}lowerComponent(e){let n=e.tagHole!=null?this.hole(e.tagHole).code:e.tag,r=this.lowerAttributes(e.attributes),{slots:i,rest:o}=this.partitionSlots(e.children);for(let[a,d]of i){let p=d.length===1?d[0]:{kind:"fragment",children:d},h={name:a,kind:"attr",expr:this.emit(p),jsxElement:!0},g=r.findIndex(y=>y.name===a);g>=0?r[g]=h:r.push(h)}let l=e.attributes.find(a=>a.kind==="LoadDirective"),s=l?D(`load:${l.strategy}`,l.modifier):void 0,u=r.find(a=>a.at&&a.reactive)?.at,c=this.tagAt(e);return{kind:"component",name:n,props:r,children:this.lowerChildren(o),...c?{at:c}:{},...u?{bindAt:u}:{},...s?{load:s}:{}}}partitionSlots(e){let n=new Map,r=[];for(let i of e){if(i.kind==="Element"||i.kind==="Component"){let o=i.attributes.find(l=>l.kind==="Attribute"&&l.name==="slot");if(o&&o.value&&o.value.kind==="static"){let l={...i,attributes:i.attributes.filter(c=>c!==o)},s=l.kind==="Element"?this.lowerElement(l):this.lowerComponent(l),u=n.get(o.value.value)??[];u.push(s),n.set(o.value.value,u);continue}}r.push(i)}return{slots:n,rest:r}}lowerIf(e,n,r){let i=this.hole(n),o=[{name:"when",kind:"attr",expr:i.code,reactive:i.reactive,...i.at?{at:i.at}:{}}];if(r){let u=this.stripAndLower(r,c=>c.kind==="ElseDirective");o.push({name:"fallback",kind:"attr",expr:this.emit(u),jsxElement:!0})}let l=this.stripAndLower(e,u=>u.kind==="IfDirective"),s=this.tagAt(e);return{kind:"component",name:"Show",props:o,children:[l],...s?{at:s}:{},...i.at?{bindAt:i.at}:{}}}lowerEach(e){let n=e.attributes.find(c=>c.kind==="EachDirective");if(!n||n.kind!=="EachDirective")return this.lowerNode(e);let r=this.hole(n.hole),i=[{name:"each",kind:"attr",expr:r.code,reactive:r.reactive,...r.at?{at:r.at}:{}}];if(n.key){let c="static"in n.key?`(item) => item[${JSON.stringify(n.key.static)}]`:this.hole(n.key.hole).code;i.push({name:"by",kind:"attr",expr:c})}let o=this.itemArrow(e),l;if(o){let c={kind:"expr",code:o.body,reactive:o.bodyReactive},a=this.rebuildWithChildren(e,[c]);l=`(${o.params.join(", ")}) => (${this.emit(a)})`}else{let c=this.stripAndLower(e,a=>a.kind==="EachDirective");l=`() => (${this.emit(c)})`}let s=[{kind:"expr",code:l,reactive:!1}],u=this.tagAt(e);return{kind:"component",name:"For",props:i,children:s,...u?{at:u}:{},...r.at?{bindAt:r.at}:{}}}itemArrow(e){let n=e.children.filter(r=>!this.isBlankText(r));return n.length!==1||n[0].kind!=="Expression"?null:this.hole(n[0].hole).arrow??null}stripAndLower(e,n){let r={...e,attributes:e.attributes.filter(i=>!n(i))};return r.kind==="Element"?this.lowerElement(r):this.lowerComponent(r)}rebuildWithChildren(e,n){let r=this.lowerAttributes(e.attributes.filter(i=>i.kind!=="EachDirective"));if(e.kind==="Element"){let i=this.tagAt(e);return{kind:"element",tag:e.tag,svg:e.namespace==="svg",props:r,children:n,static:!1,...i?{at:i}:{}}}return{kind:"component",name:e.tag,props:r,children:n}}lowerAttributes(e){let n=[],r=[],i=!1,o,l=[],s=!1,u,c=[];for(let a of e)switch(a.kind){case"IfDirective":case"EachDirective":case"ElseDirective":break;case"Attribute":n.push(this.plainAttr(a));break;case"PropertyBinding":n.push({name:a.name,kind:"prop",expr:this.hole(a.hole).code,reactive:this.hole(a.hole).reactive,...this.hole(a.hole).at?{at:this.hole(a.hole).at}:{}});break;case"EventBinding":n.push(this.eventProp(a));break;case"RefBinding":n.push({name:"ref",kind:"ref",expr:this.hole(a.hole).code,reactive:this.hole(a.hole).reactive,...this.hole(a.hole).at?{at:this.hole(a.hole).at}:{}});break;case"Spread":n.push({name:"",kind:"spread",expr:this.hole(a.hole).code});break;case"ClassDirective":{let d=this.hole(a.hole);r.push(`${JSON.stringify(a.name)}: ${d.code}`),i=i||d.reactive,o??=d.at;break}case"StyleDirective":{let d=this.hole(a.hole);l.push(`${JSON.stringify(a.name)}: ${d.code}`),s=s||d.reactive,u??=d.at;break}case"BindDirective":n.push(...this.bindProps(a.name,this.hole(a.hole)));break;case"UseDirective":{let d=a.name??(a.hole!=null?this.hole(a.hole).code:null);if(!d)break;c.push(a.name!=null&&a.hole!=null?`[${d}, () => (${this.hole(a.hole).code})]`:`[${d}]`);break}}return r.length>0&&n.push({name:"classList",kind:"attr",expr:`{ ${r.join(", ")} }`,reactive:i,...o?{at:o}:{}}),l.length>0&&n.push({name:"style",kind:"attr",expr:`{ ${l.join(", ")} }`,reactive:s,...u?{at:u}:{}}),c.length>0&&n.push({name:"use",kind:"attr",expr:`[${c.join(", ")}]`}),n}eventProp(e){let n=e.name.toLowerCase(),r=this.hole(e.hole).code;if(!(e.syntax==="colon"||e.modifiers.length>0))return{name:"on"+Z(e.name),kind:"event",event:{name:n,delegated:Y.has(n)},expr:r};let o=this.wrapHandler(r,e.modifiers),l=this.eventOptions(e.modifiers),s=l?`[${o}, ${l}]`:o;return{name:"on:"+n,kind:"attr",expr:s}}wrapHandler(e,n){let r=n.includes("self")?"if (e.target !== e.currentTarget) return; ":"",i=[];return n.includes("prevent")&&i.push("e.preventDefault();"),n.includes("stop")&&i.push("e.stopPropagation();"),!r&&i.length===0?e:`(e) => { ${r}${i.join(" ")} return (${e})(e); }`}eventOptions(e){let n=[];return e.includes("capture")&&n.push("capture: true"),e.includes("once")&&n.push("once: true"),e.includes("passive")&&n.push("passive: true"),n.length?`{ ${n.join(", ")} }`:null}bindProps(e,n){let r=n.code,i=e==="checked",o=i?"change":"input",l=i?"checked":"value";this.used.add("bindPair");let s=`bindPair(${r})`;return[{name:e,kind:"attr",expr:`${s}[0]()`,reactive:!0,directive:`bind:${e}`,...n.at?{at:n.at}:{}},{name:"on"+Z(o),kind:"event",event:{name:o,delegated:Y.has(o)},expr:`(e) => ${s}[1](e.target.${l})`}]}plainAttr(e){let n=e.value,r=e.name;e.name==="class"?r=n&&n.kind==="hole"&&this.hole(n.hole).object?"classList":"className":e.name==="html"&&(r="innerHTML");let o={name:r,kind:"attr"};if(n==null)return o.literal=!0,o;if(n.kind==="static")return o.literal=n.value,o;if(n.kind==="hole"){let c=this.hole(n.hole);return o.expr=c.code,o.reactive=c.reactive,c.at&&(o.at=c.at),o}let l=!1,s,u=n.parts.map(c=>{if("text"in c)return Se(c.text);let a=this.hole(c.hole);return l=l||a.reactive,s??=a.at,"${"+a.code+"}"}).join("");return o.expr="`"+u+"`",o.reactive=l,s&&(o.at=s),o}};function we(t,e,n,r={}){let{root:i}=(0,X.parseTemplate)(t,{svg:r.svg});return new C(e,n,r.sourceFile,r.positionAt).lowerRoot(i.children)}
@@ -7,7 +7,7 @@
7
7
  * Pipeline: pieces → parseTemplate → Template AST → lowerTemplate → IRNode
8
8
  */
9
9
  import { type Piece } from '@fluixi/template-parser';
10
- import type { IRNode } from '../ir/nodes.js';
10
+ import type { HolePosition, IRNode } from '../ir/nodes.js';
11
11
  /**
12
12
  * One `${…}` slot, as the front-end describes it. Conclusions about the
13
13
  * expression only — never a syntax tree, or the parser dependency creeps back.
@@ -29,6 +29,14 @@ export interface TemplateHole {
29
29
  };
30
30
  /** Whether the hole is an object literal — `class=${{…}}` lowers to classList. */
31
31
  object?: boolean;
32
+ /**
33
+ * Where the `${…}` was written. Only kept when the host asked for source locations.
34
+ *
35
+ * A template is emitted as one overwrite, so every hole in it traces back through the
36
+ * source map to the line the template opens at. Without this, every node a template makes
37
+ * reports that one position.
38
+ */
39
+ at?: HolePosition;
32
40
  }
33
41
  /**
34
42
  * Lower a parsed template to IR. `pieces` are the static runs and hole slots as
@@ -37,5 +45,10 @@ export interface TemplateHole {
37
45
  */
38
46
  export declare function lowerTemplate(pieces: Piece[], holes: TemplateHole[], used: Set<string>, opts?: {
39
47
  svg?: boolean;
48
+ sourceFile?: string;
49
+ positionAt?: (offset: number) => {
50
+ line: number;
51
+ column: number;
52
+ };
40
53
  }): IRNode;
41
54
  //# sourceMappingURL=template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/lower/template.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAML,KAAK,KAAK,EAGX,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,MAAM,EAAsB,MAAM,gBAAgB,CAAC;AAKjE;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC;IAClE,kFAAkF;IAClF,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA4bD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,EAAE,YAAY,EAAE,EACrB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EACjB,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3B,MAAM,CAGR"}
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/lower/template.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAML,KAAK,KAAK,EAGX,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,EAAsB,MAAM,gBAAgB,CAAC;AAK/E;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sFAAsF;IACtF,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,KAAK,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC;IAClE,kFAAkF;IAClF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;OAMG;IACH,EAAE,CAAC,EAAE,YAAY,CAAC;CACnB;AAmhBD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,KAAK,EAAE,EACf,KAAK,EAAE,YAAY,EAAE,EACrB,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,EACjB,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAO,GACnH,MAAM,CAGR"}
@@ -24,9 +24,27 @@ function capitalize(s) {
24
24
  class Lowerer {
25
25
  holes;
26
26
  used;
27
- constructor(holes, used) {
27
+ sourceFile;
28
+ positionAt;
29
+ constructor(holes, used, sourceFile, positionAt) {
28
30
  this.holes = holes;
29
31
  this.used = used;
32
+ this.sourceFile = sourceFile;
33
+ this.positionAt = positionAt;
34
+ }
35
+ /**
36
+ * Where a tag is written, for the mark a component node carries.
37
+ *
38
+ * The parser reports offsets, and they are offsets into the file: the pieces it was given
39
+ * carry the positions the front-end recorded. Only built when the host asked for source
40
+ * locations, which is the only time either of these is set.
41
+ */
42
+ tagAt(node) {
43
+ const start = node.loc?.start;
44
+ if (!this.sourceFile || !this.positionAt || start == null)
45
+ return undefined;
46
+ const { line, column } = this.positionAt(start);
47
+ return { file: this.sourceFile, line, column };
30
48
  }
31
49
  hole(i) {
32
50
  // -1 marks a recovered-from missing binding; emit a harmless undefined.
@@ -95,7 +113,7 @@ class Lowerer {
95
113
  return null; // dropped, like JSX comments
96
114
  case 'Expression': {
97
115
  const h = this.hole(node.hole);
98
- return { kind: 'expr', code: h.code, reactive: h.reactive };
116
+ return { kind: 'expr', code: h.code, reactive: h.reactive, ...(h.at ? { at: h.at } : {}) };
99
117
  }
100
118
  case 'Fragment':
101
119
  return { kind: 'fragment', children: this.lowerChildren(node.children) };
@@ -118,6 +136,7 @@ class Lowerer {
118
136
  node.props.unshift({ name: 'component', kind: 'attr', expr: `() => (${this.hole(isAttr.value.hole).code})` });
119
137
  return node;
120
138
  }
139
+ const at = this.tagAt(el);
121
140
  return {
122
141
  kind: 'element',
123
142
  tag: el.tag,
@@ -125,6 +144,7 @@ class Lowerer {
125
144
  props: this.lowerAttributes(el.attributes),
126
145
  children: this.lowerChildren(el.children),
127
146
  static: false,
147
+ ...(at ? { at } : {}),
128
148
  };
129
149
  }
130
150
  lowerComponent(el) {
@@ -160,11 +180,20 @@ class Lowerer {
160
180
  const load = loadAttr
161
181
  ? parseLoadDirective(`load:${loadAttr.strategy}`, loadAttr.modifier)
162
182
  : undefined;
183
+ // The parser's positions are relative to the template string, not the file, so the
184
+ // tag itself has none to give. The first hole is the closest thing that does, and for
185
+ // the control-flow components — `<Show when=${…}>`, `<For each=${…}>` — it is the
186
+ // expression driving the subtree anyway.
187
+ // A reactive one: a literal carries a position too now, and it drives nothing.
188
+ const bindAt = props.find((p) => p.at && p.reactive)?.at;
189
+ const at = this.tagAt(el);
163
190
  return {
164
191
  kind: 'component',
165
192
  name,
166
193
  props,
167
194
  children: this.lowerChildren(rest),
195
+ ...(at ? { at } : {}),
196
+ ...(bindAt ? { bindAt } : {}),
168
197
  ...(load ? { load } : {}),
169
198
  };
170
199
  }
@@ -193,14 +222,15 @@ class Lowerer {
193
222
  lowerIf(el, condHole, elseEl) {
194
223
  const cond = this.hole(condHole);
195
224
  const props = [
196
- { name: 'when', kind: 'attr', expr: cond.code, reactive: cond.reactive },
225
+ { name: 'when', kind: 'attr', expr: cond.code, reactive: cond.reactive, ...(cond.at ? { at: cond.at } : {}) },
197
226
  ];
198
227
  if (elseEl) {
199
228
  const elseIR = this.stripAndLower(elseEl, (a) => a.kind === 'ElseDirective');
200
229
  props.push({ name: 'fallback', kind: 'attr', expr: this.emit(elseIR), jsxElement: true });
201
230
  }
202
231
  const child = this.stripAndLower(el, (a) => a.kind === 'IfDirective');
203
- return { kind: 'component', name: 'Show', props, children: [child] };
232
+ const at = this.tagAt(el);
233
+ return { kind: 'component', name: 'Show', props, children: [child], ...(at ? { at } : {}), ...(cond.at ? { bindAt: cond.at } : {}) };
204
234
  }
205
235
  /** `<el each=${items} key?>${item => …}</el>` → `<For each>{item => <el>…</el>}</For>`. */
206
236
  lowerEach(el) {
@@ -208,7 +238,7 @@ class Lowerer {
208
238
  if (!eachDir || eachDir.kind !== 'EachDirective')
209
239
  return this.lowerNode(el);
210
240
  const each = this.hole(eachDir.hole);
211
- const props = [{ name: 'each', kind: 'attr', expr: each.code, reactive: each.reactive }];
241
+ const props = [{ name: 'each', kind: 'attr', expr: each.code, reactive: each.reactive, ...(each.at ? { at: each.at } : {}) }];
212
242
  if (eachDir.key) {
213
243
  // `<For by>` wants a KEY FUNCTION, not a string. `key="id"` selects the
214
244
  // `id` field: `(item) => item["id"]`; `key=${fn}` passes the function.
@@ -230,7 +260,8 @@ class Lowerer {
230
260
  childrenCode = `() => (${this.emit(repeated)})`;
231
261
  }
232
262
  const children = [{ kind: 'expr', code: childrenCode, reactive: false }];
233
- return { kind: 'component', name: 'For', props, children };
263
+ const at = this.tagAt(el);
264
+ return { kind: 'component', name: 'For', props, children, ...(at ? { at } : {}), ...(each.at ? { bindAt: each.at } : {}) };
234
265
  }
235
266
  /** The single `${item => expr}` child arrow, if that's the element's content. */
236
267
  itemArrow(el) {
@@ -248,7 +279,16 @@ class Lowerer {
248
279
  rebuildWithChildren(el, children) {
249
280
  const props = this.lowerAttributes(el.attributes.filter((a) => a.kind !== 'EachDirective'));
250
281
  if (el.kind === 'Element') {
251
- return { kind: 'element', tag: el.tag, svg: el.namespace === 'svg', props, children, static: false };
282
+ const at = this.tagAt(el);
283
+ return {
284
+ kind: 'element',
285
+ tag: el.tag,
286
+ svg: el.namespace === 'svg',
287
+ props,
288
+ children,
289
+ static: false,
290
+ ...(at ? { at } : {}),
291
+ };
252
292
  }
253
293
  return { kind: 'component', name: el.tag, props, children };
254
294
  }
@@ -257,8 +297,10 @@ class Lowerer {
257
297
  const props = [];
258
298
  const classEntries = [];
259
299
  let classReactive = false;
300
+ let classAt;
260
301
  const styleEntries = [];
261
302
  let styleReactive = false;
303
+ let styleAt;
262
304
  const usePairs = [];
263
305
  for (const a of attrs) {
264
306
  switch (a.kind) {
@@ -270,13 +312,26 @@ class Lowerer {
270
312
  props.push(this.plainAttr(a));
271
313
  break;
272
314
  case 'PropertyBinding':
273
- props.push({ name: a.name, kind: 'prop', expr: this.hole(a.hole).code, reactive: this.hole(a.hole).reactive });
315
+ props.push({
316
+ name: a.name,
317
+ kind: 'prop',
318
+ expr: this.hole(a.hole).code,
319
+ reactive: this.hole(a.hole).reactive,
320
+ ...(this.hole(a.hole).at ? { at: this.hole(a.hole).at } : {}),
321
+ });
274
322
  break;
275
323
  case 'EventBinding':
276
324
  props.push(this.eventProp(a));
277
325
  break;
278
326
  case 'RefBinding':
279
- props.push({ name: 'ref', kind: 'ref', expr: this.hole(a.hole).code, reactive: this.hole(a.hole).reactive });
327
+ props.push({
328
+ name: 'ref',
329
+ kind: 'ref',
330
+ expr: this.hole(a.hole).code,
331
+ reactive: this.hole(a.hole).reactive,
332
+ // Which variable ends up holding the element, and where it was written.
333
+ ...(this.hole(a.hole).at ? { at: this.hole(a.hole).at } : {}),
334
+ });
280
335
  break;
281
336
  case 'Spread':
282
337
  props.push({ name: '', kind: 'spread', expr: this.hole(a.hole).code });
@@ -285,16 +340,18 @@ class Lowerer {
285
340
  const h = this.hole(a.hole);
286
341
  classEntries.push(`${JSON.stringify(a.name)}: ${h.code}`);
287
342
  classReactive = classReactive || h.reactive;
343
+ classAt ??= h.at;
288
344
  break;
289
345
  }
290
346
  case 'StyleDirective': {
291
347
  const h = this.hole(a.hole);
292
348
  styleEntries.push(`${JSON.stringify(a.name)}: ${h.code}`);
293
349
  styleReactive = styleReactive || h.reactive;
350
+ styleAt ??= h.at;
294
351
  break;
295
352
  }
296
353
  case 'BindDirective':
297
- props.push(...this.bindProps(a.name, this.hole(a.hole).code));
354
+ props.push(...this.bindProps(a.name, this.hole(a.hole)));
298
355
  break;
299
356
  case 'UseDirective': {
300
357
  // `use=${dir}` → [dir]; `use:name` → [name]; `use:name=${opts}` →
@@ -310,11 +367,26 @@ class Lowerer {
310
367
  }
311
368
  // Merge all class:/style: directives into one classList/style prop so they
312
369
  // don't collide as duplicate keys in the emitted props object.
370
+ // One prop covers every directive of its kind, so it carries the first hole's
371
+ // position — a real source line beats the stack fallback, which lands in the
372
+ // compiled file.
313
373
  if (classEntries.length > 0) {
314
- props.push({ name: 'classList', kind: 'attr', expr: `{ ${classEntries.join(', ')} }`, reactive: classReactive });
374
+ props.push({
375
+ name: 'classList',
376
+ kind: 'attr',
377
+ expr: `{ ${classEntries.join(', ')} }`,
378
+ reactive: classReactive,
379
+ ...(classAt ? { at: classAt } : {}),
380
+ });
315
381
  }
316
382
  if (styleEntries.length > 0) {
317
- props.push({ name: 'style', kind: 'attr', expr: `{ ${styleEntries.join(', ')} }`, reactive: styleReactive });
383
+ props.push({
384
+ name: 'style',
385
+ kind: 'attr',
386
+ expr: `{ ${styleEntries.join(', ')} }`,
387
+ reactive: styleReactive,
388
+ ...(styleAt ? { at: styleAt } : {}),
389
+ });
318
390
  }
319
391
  // All use: directives normalize to one `use` prop = an array of [dir, accessor?] pairs.
320
392
  if (usePairs.length > 0) {
@@ -369,7 +441,8 @@ class Lowerer {
369
441
  return opts.length ? `{ ${opts.join(', ')} }` : null;
370
442
  }
371
443
  /** `bind:value=${sig}` → `value={read()}` + `onInput={e => write(e…value)}`. */
372
- bindProps(prop, sigCode) {
444
+ bindProps(prop, h) {
445
+ const sigCode = h.code;
373
446
  const checked = prop === 'checked';
374
447
  const evt = checked ? 'change' : 'input';
375
448
  const accessor = checked ? 'checked' : 'value';
@@ -380,7 +453,14 @@ class Lowerer {
380
453
  this.used.add('bindPair');
381
454
  const sig = `bindPair(${sigCode})`;
382
455
  return [
383
- { name: prop, kind: 'attr', expr: `${sig}[0]()`, reactive: true },
456
+ {
457
+ name: prop,
458
+ kind: 'attr',
459
+ expr: `${sig}[0]()`,
460
+ reactive: true,
461
+ directive: `bind:${prop}`,
462
+ ...(h.at ? { at: h.at } : {}),
463
+ },
384
464
  {
385
465
  name: 'on' + capitalize(evt),
386
466
  kind: 'event',
@@ -418,21 +498,27 @@ class Lowerer {
418
498
  const h = this.hole(v.hole);
419
499
  base.expr = h.code;
420
500
  base.reactive = h.reactive;
501
+ if (h.at)
502
+ base.at = h.at;
421
503
  return base;
422
504
  }
423
505
  // mixed: template literal, reactive if any hole is
424
506
  let reactive = false;
507
+ let at;
425
508
  const body = v.parts
426
509
  .map((p) => {
427
510
  if ('text' in p)
428
511
  return escapeTemplate(p.text);
429
512
  const h = this.hole(p.hole);
430
513
  reactive = reactive || h.reactive;
514
+ at ??= h.at;
431
515
  return '${' + h.code + '}';
432
516
  })
433
517
  .join('');
434
518
  base.expr = '`' + body + '`';
435
519
  base.reactive = reactive;
520
+ if (at)
521
+ base.at = at;
436
522
  return base;
437
523
  }
438
524
  }
@@ -443,5 +529,5 @@ class Lowerer {
443
529
  */
444
530
  export function lowerTemplate(pieces, holes, used, opts = {}) {
445
531
  const { root } = parseTemplate(pieces, { svg: opts.svg });
446
- return new Lowerer(holes, used).lowerRoot(root.children);
532
+ return new Lowerer(holes, used, opts.sourceFile, opts.positionAt).lowerRoot(root.children);
447
533
  }
@@ -1 +1 @@
1
- import{parseTemplate as de}from"@fluixi/template-parser";var F={kind:"eager"},U=["pointerdown","focusin","keydown"],y=new Set(["eager","idle","visible","interaction","media","never"]),u=class extends Error{};function T(t,e){let n=t.slice(5);if(!y.has(n))throw new u(`Unknown load strategy 'load:${n}'. Expected one of ${[...y].join(", ")}.`);switch(n){case"eager":return F;case"idle":return{kind:"idle"};case"never":return{kind:"never"};case"visible":return e?{kind:"visible",rootMargin:e}:{kind:"visible"};case"interaction":return{kind:"interaction",events:e?W(e):[...U]};case"media":if(!e)throw new u(`'load:media' needs a query, e.g. load:media="(min-width: 1024px)".`);return{kind:"media",query:e};default:throw new u(`Unhandled load strategy '${n}'.`)}}function W(t){let e=t.split(/[\s,]+/).map(n=>n.trim()).filter(Boolean);if(e.length===0)throw new u("'load:interaction' was given no event names.");return e}var q=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),S={className:"class",htmlFor:"for"},G=new Set(["innerHTML","outerHTML","innerText","textContent","value","checked","selected","muted","defaultValue","defaultChecked","children","ref"]),K=new Set(["script","style","textarea","title"]);function R(t){return K.has(t)}function C(t){return S[t]??t}function h(t){return t.kind!=="attr"||t.expr!==void 0||t.name.includes(":")?!1:!G.has(t.name)}function $(t){if(!t.static||R(t.tag))return!1;for(let e of t.props)if(!h(e))return!1;for(let e of t.children)if(e.kind!=="text"&&!(e.kind==="element"&&$(e)))return!1;return!0}function f(t){let e=t.props.map(Z).filter(Boolean).join(""),n=`<${t.tag}${e}>`;return q.has(t.tag)?n:`${n}${t.children.map(Y).join("")}</${t.tag}>`}function Y(t){if(t.kind==="text")return Q(t.value);if(t.kind!=="element")throw new Error(`serializeStatic: unexpected ${t.kind}`);return f(t)}function Z(t){let e=S[t.name]??t.name,n=t.literal;return n===!0||n===void 0?` ${e}`:n===!1||n===null?"":` ${e}="${X(String(n))}"`}function X(t){return t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Q(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}var ee="<!--fx-->",te="<!--fx/-->";function N(t){return t.kind==="expr"||t.kind==="component"||t.kind==="control"}function ne(t){return t.kind==="text"||t.kind==="element"&&P(t)}function P(t){return t.svg||R(t.tag)||!t.props.every(e=>h(e))?!1:t.children.every(e=>ne(e)||N(e))}function k(t){if(N(t))return!0;let e=t.children;return e?e.some(k):!1}function A(t){for(let e=0;e<t.children.length;e++){let n=t.children[e];if(n.kind==="text"&&(n.value===""||t.children[e+1]?.kind==="text"))return!1}return t.children.every(e=>e.kind!=="element"||A(e))}function L(t){if(!P(t)||!A(t)||!t.children.some(k))return null;let e=[],n=[],r=0,i=c=>{let s=`_n$${r++}`;return e.push({ref:s,expr:c}),s};return o(t,"_el$"),{html:re(t),tag:t.tag,steps:e,holes:n};function o(c,s){let a=-1;c.children.forEach((d,p)=>{k(d)&&(a=p)});let l=null;for(let d=0;d<=a;d++){let p=c.children[d],m=l?`${l}.nextSibling`:`${s}.firstChild`;if(N(p)){let I=i(m),w=i(`holeEnd(${I})`);n.push({parentRef:s,startRef:I,endRef:w,node:p}),l=w;continue}let v=i(m);p.kind==="element"&&k(p)&&o(p,v),l=v}}}function re(t){return f(D(t)).split(j).join(ee+te)}function D(t){return{...t,children:t.children.map(e=>N(e)?{kind:"text",value:j}:e.kind==="element"?D(e):e)}}var j="\0fx-hole\0";var b={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},ge={version:2,module:"@fluixi/dom",symbols:[...b.symbols,"template","cloneTemplate","walk"]};var ie={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function oe(t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)}function _(t){return oe(t)?t:JSON.stringify(t)}function se(t){return t.expr!==void 0?t.reactive?`() => (${t.expr})`:`(${t.expr})`:JSON.stringify(t.literal??!0)}function ae(t){return t.expr!==void 0?`(${t.expr})`:JSON.stringify(t.literal??!0)}function le(t,e,n){let r=t.filter(s=>s.kind==="spread"),o=t.filter(s=>s.kind!=="spread").map(s=>`${_(s.name)}: ${se(s)}`);e!=null&&o.push(`children: ${e}`);let c=`{ ${o.join(", ")} }`;return r.length>0?(n.add("mergeProps"),`mergeProps(${r.map(s=>s.expr).join(", ")}, ${c})`):c}function M(t,e,n){return t.length===1?g(t[0],e,n):`[${t.map(r=>g(r,e,n)).join(", ")}]`}function O(t,e,n,r,i){r.add("createMemo"),r.add("createComponent");let o=e.filter(l=>l.kind==="spread"),s=e.filter(l=>l.kind!=="spread").map(l=>`get ${_(l.name)}() { return ${ae(l)}; }`);n.length>0&&s.push(`get children() { return ${M(n,r,i)}; }`);let a=`{ ${s.join(", ")} }`;return o.length>0&&(r.add("mergeProps"),a=`mergeProps(${o.map(l=>l.expr).join(", ")}, ${a})`),`createMemo(() => createComponent(${t}, ${a}))`}function ce(t,e){let n=C(e.name),r=e.literal;return r===!0||r===void 0?`${t}.setAttribute(${JSON.stringify(n)}, "");`:r===!1||r===null?"":`${t}.setAttribute(${JSON.stringify(n)}, ${JSON.stringify(String(r))});`}var H=!1;function g(t,e,n){switch(t.kind){case"text":return JSON.stringify(t.value);case"expr":return t.reactive?`() => (${t.code})`:`(${t.code})`;case"fragment":return t.children.length===0?"null":M(t.children,e,n);case"component":return O(t.name,t.props,t.children,e,n);case"control":{let r=ie[t.control]??t.control;return e.add(r),O(r,t.props,t.children,e,n)}case"element":{if(n&&t.static&&!t.svg&&$(t)){e.add("templateNode");let s=`_tmpl$${n.length}`;return n.push({id:s,html:f(t),tag:t.tag,svg:!1}),`templateNode(${s}, ${JSON.stringify(t.tag)})`}if(n&&H){let s=L(t);if(s){e.add("templateNode"),e.add("insert"),e.add("holeEnd"),e.add("holeContent"),e.add("holeScope");let a=`_tmpl$${n.length}`;n.push({id:a,html:s.html,tag:s.tag,svg:!1});let l=[`const _el$ = templateNode(${a}, ${JSON.stringify(s.tag)}, true);`];for(let d of s.steps)l.push(`const ${d.ref} = ${d.expr};`);for(let d of s.holes)l.push(`insert(${d.parentRef}, holeScope(${d.startRef}, () => (${g(d.node,e,n)})), ${d.endRef}, holeContent(${d.startRef}, ${d.endRef}));`);return l.push("return _el$;"),`(() => { ${l.join(" ")} })()`}}e.add("createNativeElement");let r=JSON.stringify(t.tag),i="_el$",o=[],c=t.svg?`${r}, true`:r;if(o.push(`const ${i} = createNativeElement(${c});`),t.props.length>0)if(!t.svg&&t.props.every(h))for(let s of t.props)o.push(ce(i,s));else{e.add("spread");let s=t.svg?", isSVG: true":"";o.push(`spread({ element: ${i}, props: ${le(t.props,null,e)}${s} });`)}for(let s of t.children){e.add("insert");let a=g(s,e,n),l=s.kind==="expr"&&s.reactive||s.kind==="component"||s.kind==="control";o.push(l?`insert(${i}, ${a}, null);`:`insert(${i}, ${a});`)}return o.push(`return ${i};`),`(() => { ${o.join(" ")} })()`}}}function B(t,e){if(!e||e.length===0)return t;let n=new Map(e.map(r=>[r.id,JSON.stringify(r.html)]));return t.replace(/_tmpl\$\d+/g,r=>n.get(r)??r)}var J={name:"imperative",contract:b,emit(t,e){let n=new Set,r=e?.templateClone!==!1?[]:void 0;return H=e?.partialTemplates===!0,{code:g(t,n,r),imports:Array.from(n),templates:r}}};function x(t){let e=t.split(/\r\n|\n|\r/),n=0;for(let i=0;i<e.length;i++)/[^ \t]/.test(e[i])&&(n=i);let r="";for(let i=0;i<e.length;i++){let o=e[i].replace(/\t/g," ");i!==0&&(o=o.replace(/^ +/,"")),i!==e.length-1&&(o=o.replace(/ +$/,"")),o&&(i!==n&&(o+=" "),r+=o)}return r}var z=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]);function pe(t){return t.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/\$\{/g,"\\${")}function V(t){return t.charAt(0).toUpperCase()+t.slice(1)}var E=class{constructor(e,n){this.holes=e;this.used=n}hole(e){return this.holes[e]??{code:"undefined",reactive:!1}}emit(e){let{code:n,imports:r,templates:i}=J.emit(e,{});for(let o of r)this.used.add(o);return B(n,i)}lowerRoot(e){let n=this.lowerChildren(e);return n.length===1?n[0]:{kind:"fragment",children:n}}lowerChildren(e){let n=[];for(let r=0;r<e.length;r++){let i=e[r];if(i.kind==="Element"||i.kind==="Component"){let c=i.attributes.find(s=>s.kind==="IfDirective");if(c&&c.kind==="IfDirective"){let s=r+1;s<e.length&&this.isBlankText(e[s])&&s++;let a=e[s],l=a&&(a.kind==="Element"||a.kind==="Component")&&a.attributes.some(d=>d.kind==="ElseDirective");n.push(this.lowerIf(i,c.hole,l?a:null)),l&&(r=s);continue}if(i.attributes.some(s=>s.kind==="EachDirective")){n.push(this.lowerEach(i));continue}}let o=this.lowerNode(i);o&&n.push(o)}return n}isBlankText(e){return e.kind==="Text"&&!e.raw&&x(e.value)===""}lowerNode(e){switch(e.kind){case"Text":{if(e.raw)return{kind:"text",value:e.value};let n=x(e.value);return n?{kind:"text",value:n}:null}case"Comment":return null;case"Expression":{let n=this.hole(e.hole);return{kind:"expr",code:n.code,reactive:n.reactive}}case"Fragment":return{kind:"fragment",children:this.lowerChildren(e.children)};case"Element":return this.lowerElement(e);case"Component":return this.lowerComponent(e);default:return null}}lowerElement(e){let n=e.attributes.find(r=>r.kind==="Attribute"&&r.name==="is");if(e.tag==="component"&&n&&n.value&&n.value.kind==="hole"){let r=e.attributes.filter(o=>o!==n),i=this.lowerComponent({...e,kind:"Component",tag:"Dynamic",tagHole:null,attributes:r});return i.props.unshift({name:"component",kind:"attr",expr:`() => (${this.hole(n.value.hole).code})`}),i}return{kind:"element",tag:e.tag,svg:e.namespace==="svg",props:this.lowerAttributes(e.attributes),children:this.lowerChildren(e.children),static:!1}}lowerComponent(e){let n=e.tagHole!=null?this.hole(e.tagHole).code:e.tag,r=this.lowerAttributes(e.attributes),{slots:i,rest:o}=this.partitionSlots(e.children);for(let[a,l]of i){let d=l.length===1?l[0]:{kind:"fragment",children:l},p={name:a,kind:"attr",expr:this.emit(d),jsxElement:!0},m=r.findIndex(v=>v.name===a);m>=0?r[m]=p:r.push(p)}let c=e.attributes.find(a=>a.kind==="LoadDirective"),s=c?T(`load:${c.strategy}`,c.modifier):void 0;return{kind:"component",name:n,props:r,children:this.lowerChildren(o),...s?{load:s}:{}}}partitionSlots(e){let n=new Map,r=[];for(let i of e){if(i.kind==="Element"||i.kind==="Component"){let o=i.attributes.find(c=>c.kind==="Attribute"&&c.name==="slot");if(o&&o.value&&o.value.kind==="static"){let c={...i,attributes:i.attributes.filter(l=>l!==o)},s=c.kind==="Element"?this.lowerElement(c):this.lowerComponent(c),a=n.get(o.value.value)??[];a.push(s),n.set(o.value.value,a);continue}}r.push(i)}return{slots:n,rest:r}}lowerIf(e,n,r){let i=this.hole(n),o=[{name:"when",kind:"attr",expr:i.code,reactive:i.reactive}];if(r){let s=this.stripAndLower(r,a=>a.kind==="ElseDirective");o.push({name:"fallback",kind:"attr",expr:this.emit(s),jsxElement:!0})}let c=this.stripAndLower(e,s=>s.kind==="IfDirective");return{kind:"component",name:"Show",props:o,children:[c]}}lowerEach(e){let n=e.attributes.find(a=>a.kind==="EachDirective");if(!n||n.kind!=="EachDirective")return this.lowerNode(e);let r=this.hole(n.hole),i=[{name:"each",kind:"attr",expr:r.code,reactive:r.reactive}];if(n.key){let a="static"in n.key?`(item) => item[${JSON.stringify(n.key.static)}]`:this.hole(n.key.hole).code;i.push({name:"by",kind:"attr",expr:a})}let o=this.itemArrow(e),c;if(o){let a={kind:"expr",code:o.body,reactive:o.bodyReactive},l=this.rebuildWithChildren(e,[a]);c=`(${o.params.join(", ")}) => (${this.emit(l)})`}else{let a=this.stripAndLower(e,l=>l.kind==="EachDirective");c=`() => (${this.emit(a)})`}return{kind:"component",name:"For",props:i,children:[{kind:"expr",code:c,reactive:!1}]}}itemArrow(e){let n=e.children.filter(r=>!this.isBlankText(r));return n.length!==1||n[0].kind!=="Expression"?null:this.hole(n[0].hole).arrow??null}stripAndLower(e,n){let r={...e,attributes:e.attributes.filter(i=>!n(i))};return r.kind==="Element"?this.lowerElement(r):this.lowerComponent(r)}rebuildWithChildren(e,n){let r=this.lowerAttributes(e.attributes.filter(i=>i.kind!=="EachDirective"));return e.kind==="Element"?{kind:"element",tag:e.tag,svg:e.namespace==="svg",props:r,children:n,static:!1}:{kind:"component",name:e.tag,props:r,children:n}}lowerAttributes(e){let n=[],r=[],i=!1,o=[],c=!1,s=[];for(let a of e)switch(a.kind){case"IfDirective":case"EachDirective":case"ElseDirective":break;case"Attribute":n.push(this.plainAttr(a));break;case"PropertyBinding":n.push({name:a.name,kind:"prop",expr:this.hole(a.hole).code,reactive:this.hole(a.hole).reactive});break;case"EventBinding":n.push(this.eventProp(a));break;case"RefBinding":n.push({name:"ref",kind:"ref",expr:this.hole(a.hole).code,reactive:this.hole(a.hole).reactive});break;case"Spread":n.push({name:"",kind:"spread",expr:this.hole(a.hole).code});break;case"ClassDirective":{let l=this.hole(a.hole);r.push(`${JSON.stringify(a.name)}: ${l.code}`),i=i||l.reactive;break}case"StyleDirective":{let l=this.hole(a.hole);o.push(`${JSON.stringify(a.name)}: ${l.code}`),c=c||l.reactive;break}case"BindDirective":n.push(...this.bindProps(a.name,this.hole(a.hole).code));break;case"UseDirective":{let l=a.name??(a.hole!=null?this.hole(a.hole).code:null);if(!l)break;s.push(a.name!=null&&a.hole!=null?`[${l}, () => (${this.hole(a.hole).code})]`:`[${l}]`);break}}return r.length>0&&n.push({name:"classList",kind:"attr",expr:`{ ${r.join(", ")} }`,reactive:i}),o.length>0&&n.push({name:"style",kind:"attr",expr:`{ ${o.join(", ")} }`,reactive:c}),s.length>0&&n.push({name:"use",kind:"attr",expr:`[${s.join(", ")}]`}),n}eventProp(e){let n=e.name.toLowerCase(),r=this.hole(e.hole).code;if(!(e.syntax==="colon"||e.modifiers.length>0))return{name:"on"+V(e.name),kind:"event",event:{name:n,delegated:z.has(n)},expr:r};let o=this.wrapHandler(r,e.modifiers),c=this.eventOptions(e.modifiers),s=c?`[${o}, ${c}]`:o;return{name:"on:"+n,kind:"attr",expr:s}}wrapHandler(e,n){let r=n.includes("self")?"if (e.target !== e.currentTarget) return; ":"",i=[];return n.includes("prevent")&&i.push("e.preventDefault();"),n.includes("stop")&&i.push("e.stopPropagation();"),!r&&i.length===0?e:`(e) => { ${r}${i.join(" ")} return (${e})(e); }`}eventOptions(e){let n=[];return e.includes("capture")&&n.push("capture: true"),e.includes("once")&&n.push("once: true"),e.includes("passive")&&n.push("passive: true"),n.length?`{ ${n.join(", ")} }`:null}bindProps(e,n){let r=e==="checked",i=r?"change":"input",o=r?"checked":"value";this.used.add("bindPair");let c=`bindPair(${n})`;return[{name:e,kind:"attr",expr:`${c}[0]()`,reactive:!0},{name:"on"+V(i),kind:"event",event:{name:i,delegated:z.has(i)},expr:`(e) => ${c}[1](e.target.${o})`}]}plainAttr(e){let n=e.value,r=e.name;e.name==="class"?r=n&&n.kind==="hole"&&this.hole(n.hole).object?"classList":"className":e.name==="html"&&(r="innerHTML");let o={name:r,kind:"attr"};if(n==null)return o.literal=!0,o;if(n.kind==="static")return o.literal=n.value,o;if(n.kind==="hole"){let a=this.hole(n.hole);return o.expr=a.code,o.reactive=a.reactive,o}let c=!1,s=n.parts.map(a=>{if("text"in a)return pe(a.text);let l=this.hole(a.hole);return c=c||l.reactive,"${"+l.code+"}"}).join("");return o.expr="`"+s+"`",o.reactive=c,o}};function ye(t,e,n,r={}){let{root:i}=de(t,{svg:r.svg});return new E(e,n).lowerRoot(i.children)}export{ye as lowerTemplate};
1
+ import{parseTemplate as ke}from"@fluixi/template-parser";var Z={kind:"eager"},X=["pointerdown","focusin","keydown"],C=new Set(["eager","idle","visible","interaction","media","never"]),m=class extends Error{};function P(t,e){let n=t.slice(5);if(!C.has(n))throw new m(`Unknown load strategy 'load:${n}'. Expected one of ${[...C].join(", ")}.`);switch(n){case"eager":return Z;case"idle":return{kind:"idle"};case"never":return{kind:"never"};case"visible":return e?{kind:"visible",rootMargin:e}:{kind:"visible"};case"interaction":return{kind:"interaction",events:e?Q(e):[...X]};case"media":if(!e)throw new m(`'load:media' needs a query, e.g. load:media="(min-width: 1024px)".`);return{kind:"media",query:e};default:throw new m(`Unhandled load strategy '${n}'.`)}}function Q(t){let e=t.split(/[\s,]+/).map(n=>n.trim()).filter(Boolean);if(e.length===0)throw new m("'load:interaction' was given no event names.");return e}var ee=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),D={className:"class",htmlFor:"for"},te=new Set(["innerHTML","outerHTML","innerText","textContent","value","checked","selected","muted","defaultValue","defaultChecked","children","ref"]),ne=new Set(["script","style","textarea","title"]);function $(t){return ne.has(t)}function O(t){return D[t]??t}function N(t){return t.kind!=="attr"||t.expr!==void 0||t.name.includes(":")?!1:!te.has(t.name)}function I(t){if(!t.static||$(t.tag))return!1;for(let e of t.props)if(!N(e))return!1;for(let e of t.children)if(e.kind!=="text"&&!(e.kind==="element"&&I(e)))return!1;return!0}function v(t){let e=t.props.map(ie).filter(Boolean).join(""),n=`<${t.tag}${e}>`;return ee.has(t.tag)?n:`${n}${t.children.map(re).join("")}</${t.tag}>`}function re(t){if(t.kind==="text")return se(t.value);if(t.kind!=="element")throw new Error(`serializeStatic: unexpected ${t.kind}`);return v(t)}function ie(t){let e=D[t.name]??t.name,n=t.literal;return n===!0||n===void 0?` ${e}`:n===!1||n===null?"":` ${e}="${oe(String(n))}"`}function oe(t){return t.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function se(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function E(t){let e=[],n,r=i=>{n??=i.at?.file,e.push(i.at?.line??0,i.at?.column??0);for(let o of i.children)o.kind==="element"&&r(o)};return r(t),n&&e.some(i=>i!==0)?{file:n,pos:e}:void 0}var ae="<!--fx-->",le="<!--fx/-->";function x(t){return t.kind==="expr"||t.kind==="component"||t.kind==="control"}function ce(t){return t.kind==="text"||t.kind==="element"&&_(t)}function _(t){return t.svg||$(t.tag)||!t.props.every(e=>N(e))?!1:t.children.every(e=>ce(e)||x(e))}function R(t){if(x(t))return!0;let e=t.children;return e?e.some(R):!1}function M(t){for(let e=0;e<t.children.length;e++){let n=t.children[e];if(n.kind==="text"&&(n.value===""||t.children[e+1]?.kind==="text"))return!1}return t.children.every(e=>e.kind!=="element"||M(e))}function j(t){if(!_(t)||!M(t)||!t.children.some(R))return null;let e=[],n=[],r=0,i=l=>{let s=`_n$${r++}`;return e.push({ref:s,expr:l}),s};return o(t,"_el$"),{html:ue(t),tag:t.tag,steps:e,holes:n};function o(l,s){let u=-1;l.children.forEach((a,d)=>{R(a)&&(u=d)});let c=null;for(let a=0;a<=u;a++){let d=l.children[a],p=c?`${c}.nextSibling`:`${s}.firstChild`;if(x(d)){let g=i(p),y=i(`holeEnd(${g})`);n.push({parentRef:s,startRef:g,endRef:y,node:d}),c=y;continue}let h=i(p);d.kind==="element"&&R(d)&&o(d,h),c=h}}}function ue(t){return v(L(t)).split(H).join(ae+le)}function L(t){return{...t,children:t.children.map(e=>x(e)?{kind:"text",value:H}:e.kind==="element"?L(e):e)}}var H="\0fx-hole\0";var S={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},Ie={version:2,module:"@fluixi/dom",symbols:[...S.symbols,"template","cloneTemplate","walk"]};var f="@fluixi/reactive/signal",w={$signal:{export:"signal",module:f,returns:"signal-handle"},$memo:{export:"memo",module:f,returns:"memo-handle"},$effect:{export:"effect",module:f,returns:"effect"},$store:{export:"store",module:"@fluixi/reactive/store",returns:"store-handle"},$resource:{export:"resource",module:f,returns:"resource-handle"},$selector:{export:"createSelector",module:f,returns:"memo-accessor"},$deferred:{export:"createDeferred",module:f,returns:"memo-accessor"},$untrack:{export:"untrack",module:f,returns:"plain"},$untrackStore:{export:"untrackStore",module:"@fluixi/reactive/store",returns:"plain"}};var Se=new RegExp(`\\$(?:${Object.keys(w).map(t=>t.slice(1)).join("|")})\\s*\\(`);var B="__fx_source";var de="__fx_hole",k=(t,e,n,r)=>`(globalThis.${de} ?? ((f) => f))(${t},${e},${n}${r===void 0?"":`,${JSON.stringify(r)}`})`,pe="__fx_props",F=(t,e)=>`(globalThis.${pe} ?? ((p) => p))(${t},${JSON.stringify(e)})`;var fe={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function me(t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)}function U(t){return me(t)?t:JSON.stringify(t)}function he(t){if(t.expr!==void 0){if(t.name==="ref"&&t.at)return k(`(${t.expr})`,t.at.line,t.at.column,t.expr);if(!t.reactive)return`(${t.expr})`;let e=`() => (${t.expr})`;return t.at?k(e,t.at.line,t.at.column,t.directive):e}return JSON.stringify(t.literal??!0)}function ge(t){return t.expr!==void 0?`(${t.expr})`:JSON.stringify(t.literal??!0)}function Ne(t,e,n){let r=t.filter(s=>s.kind==="spread"),o=t.filter(s=>s.kind!=="spread").map(s=>`${U(s.name)}: ${he(s)}`);e!=null&&o.push(`children: ${e}`);let l=`{ ${o.join(", ")} }`;return r.length>0?(n.add("mergeProps"),`mergeProps(${r.map(s=>s.expr).join(", ")}, ${l})`):l}function J(t,e){return e?k(t,e.line,e.column):t}function K(t,e,n){return t.length===1?b(t[0],e,n):`[${t.map(r=>b(r,e,n)).join(", ")}]`}function V(t,e,n,r,i,o){r.add("createMemo"),r.add("createComponent");let l=e.filter(p=>p.kind==="spread"),s=e.filter(p=>p.kind!=="spread"),u=s.map(p=>`get ${U(p.name)}() { return ${ge(p)}; }`);n.length>0&&u.push(`get children() { return ${K(n,r,i)}; }`);let c=`{ ${u.join(", ")} }`;l.length>0&&(r.add("mergeProps"),c=`mergeProps(${l.map(p=>p.expr).join(", ")}, ${c})`);let a={};for(let p of s)p.at&&(a[p.name]=[p.at.line,p.at.column]);return Object.keys(a).length&&(c=F(c,a)),`createMemo((${o?`globalThis.${B}?.(${JSON.stringify(o.file)},${o.line},${o.column},${JSON.stringify(t)}), `:""}() => createComponent(${t}, ${c})))`}function ve(t,e){let n=O(e.name),r=e.literal;return r===!0||r===void 0?`${t}.setAttribute(${JSON.stringify(n)}, "");`:r===!1||r===null?"":`${t}.setAttribute(${JSON.stringify(n)}, ${JSON.stringify(String(r))});`}var z=!1;function b(t,e,n){switch(t.kind){case"text":return JSON.stringify(t.value);case"expr":{if(!t.reactive)return`(${t.code})`;let r=`() => (${t.code})`;return t.at?k(r,t.at.line,t.at.column):r}case"fragment":return t.children.length===0?"null":K(t.children,e,n);case"component":return J(V(t.name,t.props,t.children,e,n,t.at),t.bindAt??t.at);case"control":{let r=fe[t.control]??t.control;return e.add(r),J(V(r,t.props,t.children,e,n),t.bindAt)}case"element":{if(n&&t.static&&!t.svg&&I(t)){e.add("templateNode");let s=`_tmpl$${n.length}`;n.push({id:s,html:v(t),tag:t.tag,svg:!1});let u=E(t);return u?`templateNode(${s}, ${JSON.stringify(t.tag)}, false, false, ${JSON.stringify(u)})`:`templateNode(${s}, ${JSON.stringify(t.tag)})`}if(n&&z){let s=j(t);if(s){e.add("templateNode"),e.add("insert"),e.add("holeEnd"),e.add("holeContent"),e.add("holeScope");let u=`_tmpl$${n.length}`;n.push({id:u,html:s.html,tag:s.tag,svg:!1});let c=E(t),a=[`const _el$ = templateNode(${u}, ${JSON.stringify(s.tag)}, true${c?`, false, ${JSON.stringify(c)}`:""});`];for(let d of s.steps)a.push(`const ${d.ref} = ${d.expr};`);for(let d of s.holes)a.push(`insert(${d.parentRef}, holeScope(${d.startRef}, () => (${b(d.node,e,n)})), ${d.endRef}, holeContent(${d.startRef}, ${d.endRef}));`);return a.push("return _el$;"),`(() => { ${a.join(" ")} })()`}}e.add("createNativeElement");let r=JSON.stringify(t.tag),i="_el$",o=[],l=t.at?`${r}, ${t.svg}, ${JSON.stringify(t.at)}`:t.svg?`${r}, true`:r;if(o.push(`const ${i} = createNativeElement(${l});`),t.props.length>0)if(!t.svg&&t.props.every(N))for(let s of t.props)o.push(ve(i,s));else{e.add("spread");let s=t.svg?", isSVG: true":"";o.push(`spread({ element: ${i}, props: ${Ne(t.props,null,e)}${s} });`)}for(let s of t.children){e.add("insert");let u=b(s,e,n),c=s.kind==="expr"&&s.reactive||s.kind==="component"||s.kind==="control";o.push(c?`insert(${i}, ${u}, null);`:`insert(${i}, ${u});`)}return o.push(`return ${i};`),`(() => { ${o.join(" ")} })()`}}}function W(t,e){if(!e||e.length===0)return t;let n=new Map(e.map(r=>[r.id,JSON.stringify(r.html)]));return t.replace(/_tmpl\$\d+/g,r=>n.get(r)??r)}var q={name:"imperative",contract:S,emit(t,e){let n=new Set,r=e?.templateClone!==!1?[]:void 0;return z=e?.partialTemplates===!0,{code:b(t,n,r),imports:Array.from(n),templates:r}}};function T(t){let e=t.split(/\r\n|\n|\r/),n=0;for(let i=0;i<e.length;i++)/[^ \t]/.test(e[i])&&(n=i);let r="";for(let i=0;i<e.length;i++){let o=e[i].replace(/\t/g," ");i!==0&&(o=o.replace(/^ +/,"")),i!==e.length-1&&(o=o.replace(/ +$/,"")),o&&(i!==n&&(o+=" "),r+=o)}return r}var G=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]);function be(t){return t.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/\$\{/g,"\\${")}function Y(t){return t.charAt(0).toUpperCase()+t.slice(1)}var A=class{constructor(e,n,r,i){this.holes=e;this.used=n;this.sourceFile=r;this.positionAt=i}tagAt(e){let n=e.loc?.start;if(!this.sourceFile||!this.positionAt||n==null)return;let{line:r,column:i}=this.positionAt(n);return{file:this.sourceFile,line:r,column:i}}hole(e){return this.holes[e]??{code:"undefined",reactive:!1}}emit(e){let{code:n,imports:r,templates:i}=q.emit(e,{});for(let o of r)this.used.add(o);return W(n,i)}lowerRoot(e){let n=this.lowerChildren(e);return n.length===1?n[0]:{kind:"fragment",children:n}}lowerChildren(e){let n=[];for(let r=0;r<e.length;r++){let i=e[r];if(i.kind==="Element"||i.kind==="Component"){let l=i.attributes.find(s=>s.kind==="IfDirective");if(l&&l.kind==="IfDirective"){let s=r+1;s<e.length&&this.isBlankText(e[s])&&s++;let u=e[s],c=u&&(u.kind==="Element"||u.kind==="Component")&&u.attributes.some(a=>a.kind==="ElseDirective");n.push(this.lowerIf(i,l.hole,c?u:null)),c&&(r=s);continue}if(i.attributes.some(s=>s.kind==="EachDirective")){n.push(this.lowerEach(i));continue}}let o=this.lowerNode(i);o&&n.push(o)}return n}isBlankText(e){return e.kind==="Text"&&!e.raw&&T(e.value)===""}lowerNode(e){switch(e.kind){case"Text":{if(e.raw)return{kind:"text",value:e.value};let n=T(e.value);return n?{kind:"text",value:n}:null}case"Comment":return null;case"Expression":{let n=this.hole(e.hole);return{kind:"expr",code:n.code,reactive:n.reactive,...n.at?{at:n.at}:{}}}case"Fragment":return{kind:"fragment",children:this.lowerChildren(e.children)};case"Element":return this.lowerElement(e);case"Component":return this.lowerComponent(e);default:return null}}lowerElement(e){let n=e.attributes.find(i=>i.kind==="Attribute"&&i.name==="is");if(e.tag==="component"&&n&&n.value&&n.value.kind==="hole"){let i=e.attributes.filter(l=>l!==n),o=this.lowerComponent({...e,kind:"Component",tag:"Dynamic",tagHole:null,attributes:i});return o.props.unshift({name:"component",kind:"attr",expr:`() => (${this.hole(n.value.hole).code})`}),o}let r=this.tagAt(e);return{kind:"element",tag:e.tag,svg:e.namespace==="svg",props:this.lowerAttributes(e.attributes),children:this.lowerChildren(e.children),static:!1,...r?{at:r}:{}}}lowerComponent(e){let n=e.tagHole!=null?this.hole(e.tagHole).code:e.tag,r=this.lowerAttributes(e.attributes),{slots:i,rest:o}=this.partitionSlots(e.children);for(let[a,d]of i){let p=d.length===1?d[0]:{kind:"fragment",children:d},h={name:a,kind:"attr",expr:this.emit(p),jsxElement:!0},g=r.findIndex(y=>y.name===a);g>=0?r[g]=h:r.push(h)}let l=e.attributes.find(a=>a.kind==="LoadDirective"),s=l?P(`load:${l.strategy}`,l.modifier):void 0,u=r.find(a=>a.at&&a.reactive)?.at,c=this.tagAt(e);return{kind:"component",name:n,props:r,children:this.lowerChildren(o),...c?{at:c}:{},...u?{bindAt:u}:{},...s?{load:s}:{}}}partitionSlots(e){let n=new Map,r=[];for(let i of e){if(i.kind==="Element"||i.kind==="Component"){let o=i.attributes.find(l=>l.kind==="Attribute"&&l.name==="slot");if(o&&o.value&&o.value.kind==="static"){let l={...i,attributes:i.attributes.filter(c=>c!==o)},s=l.kind==="Element"?this.lowerElement(l):this.lowerComponent(l),u=n.get(o.value.value)??[];u.push(s),n.set(o.value.value,u);continue}}r.push(i)}return{slots:n,rest:r}}lowerIf(e,n,r){let i=this.hole(n),o=[{name:"when",kind:"attr",expr:i.code,reactive:i.reactive,...i.at?{at:i.at}:{}}];if(r){let u=this.stripAndLower(r,c=>c.kind==="ElseDirective");o.push({name:"fallback",kind:"attr",expr:this.emit(u),jsxElement:!0})}let l=this.stripAndLower(e,u=>u.kind==="IfDirective"),s=this.tagAt(e);return{kind:"component",name:"Show",props:o,children:[l],...s?{at:s}:{},...i.at?{bindAt:i.at}:{}}}lowerEach(e){let n=e.attributes.find(c=>c.kind==="EachDirective");if(!n||n.kind!=="EachDirective")return this.lowerNode(e);let r=this.hole(n.hole),i=[{name:"each",kind:"attr",expr:r.code,reactive:r.reactive,...r.at?{at:r.at}:{}}];if(n.key){let c="static"in n.key?`(item) => item[${JSON.stringify(n.key.static)}]`:this.hole(n.key.hole).code;i.push({name:"by",kind:"attr",expr:c})}let o=this.itemArrow(e),l;if(o){let c={kind:"expr",code:o.body,reactive:o.bodyReactive},a=this.rebuildWithChildren(e,[c]);l=`(${o.params.join(", ")}) => (${this.emit(a)})`}else{let c=this.stripAndLower(e,a=>a.kind==="EachDirective");l=`() => (${this.emit(c)})`}let s=[{kind:"expr",code:l,reactive:!1}],u=this.tagAt(e);return{kind:"component",name:"For",props:i,children:s,...u?{at:u}:{},...r.at?{bindAt:r.at}:{}}}itemArrow(e){let n=e.children.filter(r=>!this.isBlankText(r));return n.length!==1||n[0].kind!=="Expression"?null:this.hole(n[0].hole).arrow??null}stripAndLower(e,n){let r={...e,attributes:e.attributes.filter(i=>!n(i))};return r.kind==="Element"?this.lowerElement(r):this.lowerComponent(r)}rebuildWithChildren(e,n){let r=this.lowerAttributes(e.attributes.filter(i=>i.kind!=="EachDirective"));if(e.kind==="Element"){let i=this.tagAt(e);return{kind:"element",tag:e.tag,svg:e.namespace==="svg",props:r,children:n,static:!1,...i?{at:i}:{}}}return{kind:"component",name:e.tag,props:r,children:n}}lowerAttributes(e){let n=[],r=[],i=!1,o,l=[],s=!1,u,c=[];for(let a of e)switch(a.kind){case"IfDirective":case"EachDirective":case"ElseDirective":break;case"Attribute":n.push(this.plainAttr(a));break;case"PropertyBinding":n.push({name:a.name,kind:"prop",expr:this.hole(a.hole).code,reactive:this.hole(a.hole).reactive,...this.hole(a.hole).at?{at:this.hole(a.hole).at}:{}});break;case"EventBinding":n.push(this.eventProp(a));break;case"RefBinding":n.push({name:"ref",kind:"ref",expr:this.hole(a.hole).code,reactive:this.hole(a.hole).reactive,...this.hole(a.hole).at?{at:this.hole(a.hole).at}:{}});break;case"Spread":n.push({name:"",kind:"spread",expr:this.hole(a.hole).code});break;case"ClassDirective":{let d=this.hole(a.hole);r.push(`${JSON.stringify(a.name)}: ${d.code}`),i=i||d.reactive,o??=d.at;break}case"StyleDirective":{let d=this.hole(a.hole);l.push(`${JSON.stringify(a.name)}: ${d.code}`),s=s||d.reactive,u??=d.at;break}case"BindDirective":n.push(...this.bindProps(a.name,this.hole(a.hole)));break;case"UseDirective":{let d=a.name??(a.hole!=null?this.hole(a.hole).code:null);if(!d)break;c.push(a.name!=null&&a.hole!=null?`[${d}, () => (${this.hole(a.hole).code})]`:`[${d}]`);break}}return r.length>0&&n.push({name:"classList",kind:"attr",expr:`{ ${r.join(", ")} }`,reactive:i,...o?{at:o}:{}}),l.length>0&&n.push({name:"style",kind:"attr",expr:`{ ${l.join(", ")} }`,reactive:s,...u?{at:u}:{}}),c.length>0&&n.push({name:"use",kind:"attr",expr:`[${c.join(", ")}]`}),n}eventProp(e){let n=e.name.toLowerCase(),r=this.hole(e.hole).code;if(!(e.syntax==="colon"||e.modifiers.length>0))return{name:"on"+Y(e.name),kind:"event",event:{name:n,delegated:G.has(n)},expr:r};let o=this.wrapHandler(r,e.modifiers),l=this.eventOptions(e.modifiers),s=l?`[${o}, ${l}]`:o;return{name:"on:"+n,kind:"attr",expr:s}}wrapHandler(e,n){let r=n.includes("self")?"if (e.target !== e.currentTarget) return; ":"",i=[];return n.includes("prevent")&&i.push("e.preventDefault();"),n.includes("stop")&&i.push("e.stopPropagation();"),!r&&i.length===0?e:`(e) => { ${r}${i.join(" ")} return (${e})(e); }`}eventOptions(e){let n=[];return e.includes("capture")&&n.push("capture: true"),e.includes("once")&&n.push("once: true"),e.includes("passive")&&n.push("passive: true"),n.length?`{ ${n.join(", ")} }`:null}bindProps(e,n){let r=n.code,i=e==="checked",o=i?"change":"input",l=i?"checked":"value";this.used.add("bindPair");let s=`bindPair(${r})`;return[{name:e,kind:"attr",expr:`${s}[0]()`,reactive:!0,directive:`bind:${e}`,...n.at?{at:n.at}:{}},{name:"on"+Y(o),kind:"event",event:{name:o,delegated:G.has(o)},expr:`(e) => ${s}[1](e.target.${l})`}]}plainAttr(e){let n=e.value,r=e.name;e.name==="class"?r=n&&n.kind==="hole"&&this.hole(n.hole).object?"classList":"className":e.name==="html"&&(r="innerHTML");let o={name:r,kind:"attr"};if(n==null)return o.literal=!0,o;if(n.kind==="static")return o.literal=n.value,o;if(n.kind==="hole"){let c=this.hole(n.hole);return o.expr=c.code,o.reactive=c.reactive,c.at&&(o.at=c.at),o}let l=!1,s,u=n.parts.map(c=>{if("text"in c)return be(c.text);let a=this.hole(c.hole);return l=l||a.reactive,s??=a.at,"${"+a.code+"}"}).join("");return o.expr="`"+u+"`",o.reactive=l,s&&(o.at=s),o}};function qe(t,e,n,r={}){let{root:i}=ke(t,{svg:r.svg});return new A(e,n,r.sourceFile,r.positionAt).lowerRoot(i.children)}export{qe as lowerTemplate};