@fluixi/compiler 1.0.0-alpha.69 → 1.0.0-alpha.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/babel-NY6FXXLW.mjs +2 -0
- package/dist/codegen/backend.cjs +1 -1
- package/dist/codegen/backend.d.ts +14 -0
- package/dist/codegen/backend.d.ts.map +1 -1
- package/dist/codegen/backends/imperative.cjs +1 -1
- package/dist/codegen/backends/imperative.d.ts +10 -1
- package/dist/codegen/backends/imperative.d.ts.map +1 -1
- package/dist/codegen/backends/imperative.js +127 -16
- package/dist/codegen/backends/imperative.mjs +1 -1
- package/dist/codegen/partial-template.cjs +1 -0
- package/dist/codegen/partial-template.d.ts +62 -0
- package/dist/codegen/partial-template.d.ts.map +1 -0
- package/dist/codegen/partial-template.js +0 -0
- package/dist/codegen/partial-template.mjs +1 -0
- package/dist/codegen/serialize-static.cjs +1 -0
- package/dist/codegen/serialize-static.d.ts +23 -0
- package/dist/codegen/serialize-static.d.ts.map +1 -0
- package/dist/codegen/serialize-static.js +140 -0
- package/dist/codegen/serialize-static.mjs +1 -0
- package/dist/frontend/babel/build-ir-lit.cjs +1 -1
- package/dist/frontend/babel/build-ir-lit.d.ts.map +1 -1
- package/dist/frontend/babel/build-ir-lit.js +5 -1
- package/dist/frontend/babel/build-ir-lit.mjs +1 -1
- package/dist/frontend/babel/build-ir.cjs +1 -1
- package/dist/frontend/babel/build-ir.d.ts.map +1 -1
- package/dist/frontend/babel/build-ir.js +36 -8
- package/dist/frontend/babel/build-ir.mjs +1 -1
- package/dist/frontend/babel/index.cjs +2 -2
- package/dist/frontend/babel/index.mjs +2 -2
- package/dist/frontend/babel/lower-template.cjs +1 -1
- package/dist/frontend/babel/lower-template.d.ts.map +1 -1
- package/dist/frontend/babel/lower-template.js +34 -5
- package/dist/frontend/babel/lower-template.mjs +1 -1
- package/dist/frontend/babel/plugin.cjs +2 -2
- package/dist/frontend/babel/plugin.d.ts +4 -0
- package/dist/frontend/babel/plugin.d.ts.map +1 -1
- package/dist/frontend/babel/plugin.js +258 -50
- package/dist/frontend/babel/plugin.mjs +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.mjs +1 -1
- package/dist/integrations.cjs +8 -8
- package/dist/integrations.d.ts +6 -0
- package/dist/integrations.d.ts.map +1 -1
- package/dist/integrations.js +6 -0
- package/dist/integrations.mjs +4 -4
- package/dist/ir/nodes.cjs +1 -1
- package/dist/ir/nodes.d.ts +43 -0
- package/dist/ir/nodes.d.ts.map +1 -1
- package/dist/optimize/analyze-static.cjs +1 -0
- package/dist/optimize/analyze-static.d.ts +40 -0
- package/dist/optimize/analyze-static.d.ts.map +1 -0
- package/dist/optimize/analyze-static.js +131 -0
- package/dist/optimize/analyze-static.mjs +1 -0
- package/dist/optimize/collapse-strategies.cjs +1 -0
- package/dist/optimize/collapse-strategies.d.ts +31 -0
- package/dist/optimize/collapse-strategies.d.ts.map +1 -0
- package/dist/optimize/collapse-strategies.js +33 -0
- package/dist/optimize/collapse-strategies.mjs +1 -0
- package/dist/options.cjs +1 -1
- package/dist/options.d.ts +18 -0
- package/dist/options.d.ts.map +1 -1
- package/dist/resolve/builtins.cjs +1 -0
- package/dist/resolve/builtins.d.ts +69 -0
- package/dist/resolve/builtins.d.ts.map +1 -0
- package/dist/resolve/builtins.js +64 -0
- package/dist/resolve/builtins.mjs +1 -0
- package/dist/resolve/load-directive.cjs +1 -0
- package/dist/resolve/load-directive.d.ts +54 -0
- package/dist/resolve/load-directive.d.ts.map +1 -0
- package/dist/resolve/load-directive.js +93 -0
- package/dist/resolve/load-directive.mjs +1 -0
- package/dist/resolve/resolve-ir.cjs +1 -0
- package/dist/resolve/resolve-ir.d.ts +54 -0
- package/dist/resolve/resolve-ir.d.ts.map +1 -0
- package/dist/resolve/resolve-ir.js +58 -0
- package/dist/resolve/resolve-ir.mjs +1 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/dist/babel-UKVEBBZL.mjs +0 -2
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import"./chunk-3SAEGOMQ.mjs";import{declare as sn}from"@babel/helper-plugin-utils";var vt=e=>"components"in e;function Je(e,t){return e.replace(/\$(\d+)/g,(n,o)=>t[Number(o)]??n)}function bt(e,t){return typeof t=="string"?{module:t,export:e}:t}function Te(e=[]){let t=new Map,n=[],o=[];for(let a of e){if(!vt(a)){o.push(a);continue}for(let[l,c]of Object.entries(a.components)){let p=bt(l,c),m=t.get(l);if(m&&m.module!==p.module){let u=n.find(E=>E.name===l);u?u.modules.push(p.module):n.push({name:l,modules:[m.module,p.module]});continue}t.set(l,p)}}let i=new Map;return{resolve:a=>{if(i.has(a))return i.get(a);let l=t.get(a);if(!l)for(let c of o){let p=a.match(new RegExp(c.match.source,c.match.flags.replace("g","")));if(p){l={module:Je(c.module,p),export:c.export?Je(c.export,p):a};break}}return i.set(a,l),l},names:()=>[...t.keys()],conflicts:()=>n}}var V=["Show","For","Index","Switch","Match","Portal","Dynamic","ErrorBoundary"],D=["Suspense","SuspenseList","Await"],_=["Router","Outlet","Redirect","Link"],Pn=[...V,...D,..._],pe=new Set([...V,...D]);function Pe(e={}){let{controlFlowModule:t="@fluixi/dom",coreModule:n="@fluixi/core",routerModule:o="@fluixi/core/router-next"}=e,i={};for(let s of V)i[s]=t;for(let s of D)i[s]=n;for(let s of _)i[s]=o;return i}var A={kind:"eager"},yt=["pointerdown","focusin","keydown"],Xe=new Set(["eager","idle","visible","interaction","media","never"]),J=class extends Error{};function W(e){return e.startsWith("load:")}function B(e,t){let n=e.slice(5);if(!Xe.has(n))throw new J(`Unknown load strategy 'load:${n}'. Expected one of ${[...Xe].join(", ")}.`);switch(n){case"eager":return A;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?Rt(t):[...yt]};case"media":if(!t)throw new J(`'load:media' needs a query, e.g. load:media="(min-width: 1024px)".`);return{kind:"media",query:t};default:throw new J(`Unhandled load strategy '${n}'.`)}}function Rt(e){let t=e.split(/[\s,]+/).map(n=>n.trim()).filter(Boolean);if(t.length===0)throw new J("'load:interaction' was given no event names.");return t}function P(e){return e.kind!=="eager"&&e.kind!=="never"}function ue(e,t={}){let{resolver:n,isBound:o,modules:i,strategyFor:s}=t,a=Pe(i),l=new Map,c=new Set,p=u=>{let{name:E}=u;if(!E||E.includes(".")||o?.(E))return;let y=m(E);if(!y){c.add(E);return}let R=y.origin==="builtin"&&pe.has(E)?A:s?.(u)??A;u.source={...y,loading:R},l.set(E,u.source)},m=u=>{if(pe.has(u))return{module:a[u],export:u,origin:"builtin"};let E=n?.resolve(u);if(E)return{module:E.module,export:E.export,origin:"rule"};if(_.includes(u))return{module:a[u],export:u,origin:"builtin"}};return ee(e,u=>{u.kind==="component"&&p(u)}),{resolved:l,unresolved:[...c]}}function ee(e,t){let n=Array.isArray(e)?e:[e];for(let o of n){t(o);let i=o.children;i&&ee(i,t)}}function de(e){let t=[];ee(e,s=>{s.kind==="component"&&s.source&&t.push(s)});let n=new Set,o=new Set;for(let s of t){let{module:a,loading:l}=s.source;l.kind==="eager"&&n.add(a),l.kind==="never"&&o.add(a)}let i=new Map;for(let s of t){let a=s.source;P(a.loading)&&n.has(a.module)&&(a.loading={kind:"eager"},i.set(a.module,(i.get(a.module)??0)+1))}return{collapsed:i,conflicted:[...o].filter(s=>n.has(s))}}import{types as r,template as it}from"@babel/core";import{types as f,traverse as qt,template as Gt}from"@babel/core";import Ke from"@babel/generator";var Ct=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),$e={className:"class",htmlFor:"for"},It=new Set(["innerHTML","outerHTML","innerText","textContent","value","checked","selected","muted","defaultValue","defaultChecked","children","ref"]),wt=new Set(["script","style","textarea","title"]);function me(e){return wt.has(e)}function Ae(e){return $e[e]??e}function H(e){return e.kind!=="attr"||e.expr!==void 0||e.name.includes(":")?!1:!It.has(e.name)}function fe(e){if(!e.static||me(e.tag))return!1;for(let t of e.props)if(!H(t))return!1;for(let t of e.children)if(t.kind!=="text"&&!(t.kind==="element"&&fe(t)))return!1;return!0}function U(e){let t=e.props.map(kt).filter(Boolean).join(""),n=`<${e.tag}${t}>`;return Ct.has(e.tag)?n:`${n}${e.children.map(Nt).join("")}</${e.tag}>`}function Nt(e){if(e.kind==="text")return Mt(e.value);if(e.kind!=="element")throw new Error(`serializeStatic: unexpected ${e.kind}`);return U(e)}function kt(e){let t=$e[e.name]??e.name,n=e.literal;return n===!0||n===void 0?` ${t}`:n===!1||n===null?"":` ${t}="${Lt(String(n))}"`}function Lt(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function Mt(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}var Jt="<!--fx-->",Tt="<!--fx/-->";function ne(e){return e.kind==="expr"||e.kind==="component"||e.kind==="control"}function Pt(e){return e.kind==="text"||e.kind==="element"&&je(e)}function je(e){return e.svg||me(e.tag)||!e.props.every(t=>H(t))?!1:e.children.every(t=>Pt(t)||ne(t))}function te(e){if(ne(e))return!0;let t=e.children;return t?t.some(te):!1}function Oe(e){for(let t=0;t<e.children.length;t++){let n=e.children[t];if(n.kind==="text"&&(n.value===""||e.children[t+1]?.kind==="text"))return!1}return e.children.every(t=>t.kind!=="element"||Oe(t))}function Fe(e){if(!je(e)||!Oe(e)||!e.children.some(te))return null;let t=[],n=[],o=0,i=a=>{let l=`_n$${o++}`;return t.push({ref:l,expr:a}),l};return s(e,"_el$"),{html:Xt(e),tag:e.tag,steps:t,holes:n};function s(a,l){let c=-1;a.children.forEach((m,u)=>{te(m)&&(c=u)});let p=null;for(let m=0;m<=c;m++){let u=a.children[m],E=p?`${p}.nextSibling`:`${l}.firstChild`;if(ne(u)){let R=i(E),I=i(`holeEnd(${R})`);n.push({parentRef:l,startRef:R,endRef:I,node:u}),p=I;continue}let y=i(E);u.kind==="element"&&te(u)&&s(u,y),p=y}}}function Xt(e){return U(De(e)).split(_e).join(Jt+Tt)}function De(e){return{...e,children:e.children.map(t=>ne(t)?{kind:"text",value:_e}:t.kind==="element"?De(t):t)}}var _e="\0fx-hole\0";var ge={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},Wn={version:2,module:"@fluixi/dom",symbols:[...ge.symbols,"template","cloneTemplate","walk"]};var $t={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function At(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function ze(e){return At(e)?e:JSON.stringify(e)}function jt(e){return e.expr!==void 0?e.reactive?`() => (${e.expr})`:`(${e.expr})`:JSON.stringify(e.literal??!0)}function Ot(e){return e.expr!==void 0?`(${e.expr})`:JSON.stringify(e.literal??!0)}function Ft(e,t,n){let o=e.filter(l=>l.kind==="spread"),s=e.filter(l=>l.kind!=="spread").map(l=>`${ze(l.name)}: ${jt(l)}`);t!=null&&s.push(`children: ${t}`);let a=`{ ${s.join(", ")} }`;return o.length>0?(n.add("mergeProps"),`mergeProps(${o.map(l=>l.expr).join(", ")}, ${a})`):a}function Ve(e,t,n){return e.length===1?q(e[0],t,n):`[${e.map(o=>q(o,t,n)).join(", ")}]`}function Be(e,t,n,o,i){o.add("createMemo"),o.add("createComponent");let s=t.filter(p=>p.kind==="spread"),l=t.filter(p=>p.kind!=="spread").map(p=>`get ${ze(p.name)}() { return ${Ot(p)}; }`);n.length>0&&l.push(`get children() { return ${Ve(n,o,i)}; }`);let c=`{ ${l.join(", ")} }`;return s.length>0&&(o.add("mergeProps"),c=`mergeProps(${s.map(p=>p.expr).join(", ")}, ${c})`),`createMemo(() => createComponent(${e}, ${c}))`}function Dt(e,t){let n=Ae(t.name),o=t.literal;return o===!0||o===void 0?`${e}.setAttribute(${JSON.stringify(n)}, "");`:o===!1||o===null?"":`${e}.setAttribute(${JSON.stringify(n)}, ${JSON.stringify(String(o))});`}var We=!1;function q(e,t,n){switch(e.kind){case"text":return JSON.stringify(e.value);case"expr":return e.reactive?`() => (${e.code})`:`(${e.code})`;case"fragment":return e.children.length===0?"null":Ve(e.children,t,n);case"component":return Be(e.name,e.props,e.children,t,n);case"control":{let o=$t[e.control]??e.control;return t.add(o),Be(o,e.props,e.children,t,n)}case"element":{if(n&&e.static&&!e.svg&&fe(e)){t.add("templateNode");let l=`_tmpl$${n.length}`;return n.push({id:l,html:U(e),tag:e.tag,svg:!1}),`templateNode(${l}, ${JSON.stringify(e.tag)})`}if(n&&We){let l=Fe(e);if(l){t.add("templateNode"),t.add("insert"),t.add("holeEnd"),t.add("holeContent"),t.add("holeScope");let c=`_tmpl$${n.length}`;n.push({id:c,html:l.html,tag:l.tag,svg:!1});let p=[`const _el$ = templateNode(${c}, ${JSON.stringify(l.tag)}, true);`];for(let m of l.steps)p.push(`const ${m.ref} = ${m.expr};`);for(let m of l.holes)p.push(`insert(${m.parentRef}, holeScope(${m.startRef}, () => (${q(m.node,t,n)})), ${m.endRef}, holeContent(${m.startRef}, ${m.endRef}));`);return p.push("return _el$;"),`(() => { ${p.join(" ")} })()`}}t.add("createNativeElement");let o=JSON.stringify(e.tag),i="_el$",s=[],a=e.svg?`${o}, true`:o;if(s.push(`const ${i} = createNativeElement(${a});`),e.props.length>0)if(!e.svg&&e.props.every(H))for(let l of e.props)s.push(Dt(i,l));else{t.add("spread");let l=e.svg?", isSVG: true":"";s.push(`spread({ element: ${i}, props: ${Ft(e.props,null,t)}${l} });`)}for(let l of e.children){t.add("insert");let c=q(l,t,n),p=l.kind==="expr"&&l.reactive||l.kind==="component"||l.kind==="control";s.push(p?`insert(${i}, ${c}, null);`:`insert(${i}, ${c});`)}return s.push(`return ${i};`),`(() => { ${s.join(" ")} })()`}}}function G(e,t){if(!t||t.length===0)return e;let n=new Map(t.map(o=>[o.id,JSON.stringify(o.html)]));return e.replace(/_tmpl\$\d+/g,o=>n.get(o)??o)}var X={name:"imperative",contract:ge,emit(e,t){let n=new Set,o=t?.templateClone!==!1?[]:void 0;return We=t?.partialTemplates===!0,{code:q(e,n,o),imports:Array.from(n),templates:o}}};import{types as re}from"@babel/core";import He from"@babel/generator";import{parseTemplate as _t}from"@fluixi/template-parser";var Bt=He.default??He;function zt(e){return Bt(e,{concise:!0}).code}var Ue=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]);function Vt(e){return e.replace(/\\/g,"\\\\").replace(/`/g,"\\`").replace(/\$\{/g,"\\${")}function qe(e){return e.charAt(0).toUpperCase()+e.slice(1)}var he=class{constructor(t,n){this.holes=t;this.used=n}hole(t){return this.holes[t]??{node:re.identifier("undefined"),code:"undefined",reactive:!1}}emit(t){let{code:n,imports:o,templates:i}=X.emit(t,{});for(let s of o)this.used.add(s);return G(n,i)}lowerRoot(t){let n=this.lowerChildren(t);return n.length===1?n[0]:{kind:"fragment",children:n}}lowerChildren(t){let n=[];for(let o=0;o<t.length;o++){let i=t[o];if(i.kind==="Element"||i.kind==="Component"){let a=i.attributes.find(l=>l.kind==="IfDirective");if(a&&a.kind==="IfDirective"){let l=o+1;l<t.length&&this.isBlankText(t[l])&&l++;let c=t[l],p=c&&(c.kind==="Element"||c.kind==="Component")&&c.attributes.some(m=>m.kind==="ElseDirective");n.push(this.lowerIf(i,a.hole,p?c:null)),p&&(o=l);continue}if(i.attributes.some(l=>l.kind==="EachDirective")){n.push(this.lowerEach(i));continue}}let s=this.lowerNode(i);s&&n.push(s)}return n}isBlankText(t){return t.kind==="Text"&&!t.raw&&ie(t.value)===""}lowerNode(t){switch(t.kind){case"Text":{if(t.raw)return{kind:"text",value:t.value};let n=ie(t.value);return n?{kind:"text",value:n}:null}case"Comment":return null;case"Expression":{let n=this.hole(t.hole);return{kind:"expr",code:n.code,reactive:n.reactive}}case"Fragment":return{kind:"fragment",children:this.lowerChildren(t.children)};case"Element":return this.lowerElement(t);case"Component":return this.lowerComponent(t);default:return null}}lowerElement(t){let n=t.attributes.find(o=>o.kind==="Attribute"&&o.name==="is");if(t.tag==="component"&&n&&n.value&&n.value.kind==="hole"){let o=t.attributes.filter(s=>s!==n),i=this.lowerComponent({...t,kind:"Component",tag:"Dynamic",tagHole:null,attributes:o});return i.props.unshift({name:"component",kind:"attr",expr:`() => (${this.hole(n.value.hole).code})`}),i}return{kind:"element",tag:t.tag,svg:t.namespace==="svg",props:this.lowerAttributes(t.attributes),children:this.lowerChildren(t.children),static:!1}}lowerComponent(t){let n=t.tagHole!=null?this.hole(t.tagHole).code:t.tag,o=this.lowerAttributes(t.attributes),{slots:i,rest:s}=this.partitionSlots(t.children);for(let[c,p]of i){let m=p.length===1?p[0]:{kind:"fragment",children:p},u={name:c,kind:"attr",expr:this.emit(m),jsxElement:!0},E=o.findIndex(y=>y.name===c);E>=0?o[E]=u:o.push(u)}let a=t.attributes.find(c=>c.kind==="LoadDirective"),l=a?B(`load:${a.strategy}`,a.modifier):void 0;return{kind:"component",name:n,props:o,children:this.lowerChildren(s),...l?{load:l}:{}}}partitionSlots(t){let n=new Map,o=[];for(let i of t){if(i.kind==="Element"||i.kind==="Component"){let s=i.attributes.find(a=>a.kind==="Attribute"&&a.name==="slot");if(s&&s.value&&s.value.kind==="static"){let a={...i,attributes:i.attributes.filter(p=>p!==s)},l=a.kind==="Element"?this.lowerElement(a):this.lowerComponent(a),c=n.get(s.value.value)??[];c.push(l),n.set(s.value.value,c);continue}}o.push(i)}return{slots:n,rest:o}}lowerIf(t,n,o){let i=this.hole(n),s=[{name:"when",kind:"attr",expr:i.code,reactive:i.reactive}];if(o){let l=this.stripAndLower(o,c=>c.kind==="ElseDirective");s.push({name:"fallback",kind:"attr",expr:this.emit(l),jsxElement:!0})}let a=this.stripAndLower(t,l=>l.kind==="IfDirective");return{kind:"component",name:"Show",props:s,children:[a]}}lowerEach(t){let n=t.attributes.find(c=>c.kind==="EachDirective");if(!n||n.kind!=="EachDirective")return this.lowerNode(t);let o=this.hole(n.hole),i=[{name:"each",kind:"attr",expr:o.code,reactive:o.reactive}];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 s=this.itemArrow(t),a;if(s){let c=s.body,p={kind:"expr",code:$(c,this.used),reactive:N(c)},m=this.rebuildWithChildren(t,[p]);a=`(${s.params.map(u=>zt(u)).join(", ")}) => (${this.emit(m)})`}else{let c=this.stripAndLower(t,p=>p.kind==="EachDirective");a=`() => (${this.emit(c)})`}return{kind:"component",name:"For",props:i,children:[{kind:"expr",code:a,reactive:!1}]}}itemArrow(t){let n=t.children.filter(i=>!this.isBlankText(i));if(n.length!==1||n[0].kind!=="Expression")return null;let o=this.hole(n[0].hole).node;return re.isArrowFunctionExpression(o)&&!re.isBlockStatement(o.body)?o:null}stripAndLower(t,n){let o={...t,attributes:t.attributes.filter(i=>!n(i))};return o.kind==="Element"?this.lowerElement(o):this.lowerComponent(o)}rebuildWithChildren(t,n){let o=this.lowerAttributes(t.attributes.filter(i=>i.kind!=="EachDirective"));return t.kind==="Element"?{kind:"element",tag:t.tag,svg:t.namespace==="svg",props:o,children:n,static:!1}:{kind:"component",name:t.tag,props:o,children:n}}lowerAttributes(t){let n=[],o=[],i=!1,s=[],a=!1,l=[];for(let c of t)switch(c.kind){case"IfDirective":case"EachDirective":case"ElseDirective":break;case"Attribute":n.push(this.plainAttr(c));break;case"PropertyBinding":n.push({name:c.name,kind:"prop",expr:this.hole(c.hole).code,reactive:this.hole(c.hole).reactive});break;case"EventBinding":n.push(this.eventProp(c));break;case"RefBinding":n.push({name:"ref",kind:"ref",expr:this.hole(c.hole).code,reactive:this.hole(c.hole).reactive});break;case"Spread":n.push({name:"",kind:"spread",expr:this.hole(c.hole).code});break;case"ClassDirective":{let p=this.hole(c.hole);o.push(`${JSON.stringify(c.name)}: ${p.code}`),i=i||p.reactive;break}case"StyleDirective":{let p=this.hole(c.hole);s.push(`${JSON.stringify(c.name)}: ${p.code}`),a=a||p.reactive;break}case"BindDirective":n.push(...this.bindProps(c.name,this.hole(c.hole).code));break;case"UseDirective":{let p=c.name??(c.hole!=null?this.hole(c.hole).code:null);if(!p)break;l.push(c.name!=null&&c.hole!=null?`[${p}, () => (${this.hole(c.hole).code})]`:`[${p}]`);break}}return o.length>0&&n.push({name:"classList",kind:"attr",expr:`{ ${o.join(", ")} }`,reactive:i}),s.length>0&&n.push({name:"style",kind:"attr",expr:`{ ${s.join(", ")} }`,reactive:a}),l.length>0&&n.push({name:"use",kind:"attr",expr:`[${l.join(", ")}]`}),n}eventProp(t){let n=t.name.toLowerCase(),o=this.hole(t.hole).code;if(!(t.syntax==="colon"||t.modifiers.length>0))return{name:"on"+qe(t.name),kind:"event",event:{name:n,delegated:Ue.has(n)},expr:o};let s=this.wrapHandler(o,t.modifiers),a=this.eventOptions(t.modifiers),l=a?`[${s}, ${a}]`:s;return{name:"on:"+n,kind:"attr",expr:l}}wrapHandler(t,n){let o=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();"),!o&&i.length===0?t:`(e) => { ${o}${i.join(" ")} return (${t})(e); }`}eventOptions(t){let n=[];return t.includes("capture")&&n.push("capture: true"),t.includes("once")&&n.push("once: true"),t.includes("passive")&&n.push("passive: true"),n.length?`{ ${n.join(", ")} }`:null}bindProps(t,n){let o=t==="checked",i=o?"change":"input",s=o?"checked":"value",a=`(${n})`;return[{name:t,kind:"attr",expr:`${a}[0]()`,reactive:!0},{name:"on"+qe(i),kind:"event",event:{name:i,delegated:Ue.has(i)},expr:`(e) => ${a}[1](e.target.${s})`}]}plainAttr(t){let n=t.value,o=t.name;t.name==="class"?o=n&&n.kind==="hole"&&re.isObjectExpression(this.hole(n.hole).node)?"classList":"className":t.name==="html"&&(o="innerHTML");let s={name:o,kind:"attr"};if(n==null)return s.literal=!0,s;if(n.kind==="static")return s.literal=n.value,s;if(n.kind==="hole"){let c=this.hole(n.hole);return s.expr=c.code,s.reactive=c.reactive,s}let a=!1,l=n.parts.map(c=>{if("text"in c)return Vt(c.text);let p=this.hole(c.hole);return a=a||p.reactive,"${"+p.code+"}"}).join("");return s.expr="`"+l+"`",s.reactive=a,s}};function Ge(e,t,n={}){let o=e.quasi,i=o.expressions.map(l=>{let c=l;return{node:c,code:$(c,t),reactive:N(c)}}),s=Wt(o),{root:a}=_t(s,{svg:n.svg});return new he(i,t).lowerRoot(a.children)}function Wt(e){let t=[];return e.quasis.forEach((n,o)=>{let i=n.value.cooked??n.value.raw;if(t.push({kind:"static",text:i,start:n.start??0}),o<e.expressions.length){let s=e.expressions[o];t.push({kind:"hole",index:o,start:s.start??0,end:s.end??0})}}),t}function Ht(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 oe(e){let t=[],n=new Map,o=i=>{switch(i.kind){case"text":return!0;case"expr":return!1;case"component":case"control":for(let s of i.children)o(s);return!1;case"fragment":for(let s of i.children)o(s);return!1;case"element":{let s=!0;for(let l of i.children)o(l)||(s=!1);let a;for(let l of i.props)if(a=Ht(l),a)break;return!a&&!s&&(a=Ut(i)),i.static=!a,a?n.set(i,a):t.push(i),i.static}default:return!1}};for(let i of Array.isArray(e)?e:[e])o(i);return{staticElements:t,reasons:n}}function Ut(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 se(e,t=new Set,n={}){let o=Ge(e,t,n);return oe(o),o}var Kt=Ke.default??Ke;function Qe(e){return Kt(e,{concise:!0}).code}function Zt(e,t){let n=f.cloneNode(e,!0),o=f.file(f.program([f.expressionStatement(n)])),i=!1,s=(a,l,c)=>{for(let p of c)t.add(p);a.replaceWith(Gt.expression(l,{placeholderPattern:!1,plugins:["typescript"]})()),a.skip(),i=!0};return qt(o,{"JSXElement|JSXFragment"(a){let l=a.node,{code:c,imports:p,templates:m}=X.emit(Se(l,t),{});s(a,G(c,m),p)},TaggedTemplateExpression(a){let l=a.node.tag;if(!f.isIdentifier(l)||l.name!=="html"&&l.name!=="svg")return;let c=se(a.node,t,{svg:l.name==="svg"}),{code:p,imports:m,templates:u}=X.emit(c,{});s(a,G(p,u),m)}}),i?o.program.body[0].expression:e}function $(e,t){return Qe(Zt(e,t))}var Yt=new Set(["svg","path","circle","rect","line","polygon","polyline","ellipse","g","defs","clipPath","text"]),Qt=/^on[A-Z]/,en=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]);function tn(e){if(f.isJSXIdentifier(e)){let t=e.name[0]!==e.name[0].toLowerCase();return{tag:e.name,component:t}}return f.isJSXMemberExpression(e)?{tag:Qe(e),component:!0}:f.isJSXNamespacedName(e)?{tag:`${e.namespace.name}:${e.name.name}`,component:!1}:{tag:"div",component:!1}}function xe(e){return f.isJSXIdentifier(e)?e.name==="class"?"className":e.name:f.isJSXNamespacedName(e)?`${e.namespace.name}:${e.name.name}`:"unknown"}function N(e){return f.isCallExpression(e)||f.isOptionalCallExpression(e)?!0:f.isMemberExpression(e)||f.isOptionalMemberExpression(e)?!(!e.computed&&f.isIdentifier(e.property,{name:"children"})):f.isConditionalExpression(e)?N(e.test)||N(e.consequent)||N(e.alternate):f.isLogicalExpression(e)||f.isBinaryExpression(e)?N(e.left)||N(e.right):f.isTemplateLiteral(e)?e.expressions.some(t=>N(t)):f.isObjectExpression(e)?e.properties.some(t=>f.isObjectProperty(t)&&!t.computed&&N(t.value)):f.isArrayExpression(e)?e.elements.some(t=>t!=null&&!f.isSpreadElement(t)&&N(t)):!1}function nn(e,t){let n=xe(e.name),o=Qt.test(n),i=o||n.startsWith("on:"),a={name:n,kind:o?"event":"attr"};o&&(a.event={name:n.slice(2).toLowerCase(),delegated:en.has(n.slice(2).toLowerCase())});let l=e.value;if(l==null)return a.literal=!0,a;if(f.isStringLiteral(l))return a.literal=l.value,a;if(f.isJSXExpressionContainer(l)&&!f.isJSXEmptyExpression(l.expression)){let c=l.expression;return f.isStringLiteral(c)||f.isNumericLiteral(c)||f.isBooleanLiteral(c)?(a.literal=c.value,a):(a.expr=$(c,t),a.reactive=i?!1:N(c),(f.isJSXElement(c)||f.isJSXFragment(c))&&(a.jsxElement=!0),a)}return a.literal=!0,a}function Ze(e,t){let n=e.value;return n==null?null:f.isStringLiteral(n)?JSON.stringify(n.value):f.isJSXExpressionContainer(n)&&!f.isJSXEmptyExpression(n.expression)?$(n.expression,t):null}function rn(e,t){let n=[],o=[];for(let i of e){if(f.isJSXSpreadAttribute(i)){n.push({name:"",kind:"spread",expr:$(i.argument,t)});continue}if(!f.isJSXAttribute(i)||W(xe(i.name)))continue;let s=f.isJSXNamespacedName(i.name)?i.name.namespace.name:null;if(s==="use"){let a=i.name.name.name;t.add(a);let l=Ze(i,t);o.push(l!=null?`[${a}, () => (${l})]`:`[${a}]`);continue}if(s==="oncapture"){let a=i.name.name.name.toLowerCase(),l=Ze(i,t)??"undefined";n.push({name:"on:"+a,kind:"attr",expr:`[${l}, { capture: true }]`});continue}n.push(nn(i,t))}return o.length>0&&n.push({name:"use",kind:"attr",expr:`[${o.join(", ")}]`}),n}function ie(e){let t=e.split(/\r\n|\n|\r/),n=0;for(let i=0;i<t.length;i++)/[^ \t]/.test(t[i])&&(n=i);let o="";for(let i=0;i<t.length;i++){let s=t[i].replace(/\t/g," ");i!==0&&(s=s.replace(/^ +/,"")),i!==t.length-1&&(s=s.replace(/ +$/,"")),s&&(i!==n&&(s+=" "),o+=s)}return o}function Ye(e,t){let n=[];for(let o of e)if(f.isJSXText(o)){let i=ie(o.value);i&&n.push({kind:"text",value:i})}else if(f.isJSXExpressionContainer(o)){if(!f.isJSXEmptyExpression(o.expression)){let i=o.expression;n.push({kind:"expr",code:$(i,t),reactive:N(i)})}}else f.isJSXElement(o)||f.isJSXFragment(o)?n.push(Ee(o,t)):f.isJSXSpreadChild(o)&&n.push({kind:"expr",code:$(o.expression,t),reactive:!1});return n}function Se(e,t=new Set){let n=Ee(e,t);return oe(n),n}function Ee(e,t){if(f.isJSXFragment(e))return{kind:"fragment",children:Ye(e.children,t)};let{tag:n,component:o}=tn(e.openingElement.name),i=rn(e.openingElement.attributes,t),s=Ye(e.children,t);if(o){let a=on(e.openingElement.attributes);return{kind:"component",name:n,props:i,children:s,...a?{load:a}:{}}}return{kind:"element",tag:n,svg:Yt.has(n),props:i,children:s,static:!1}}function on(e){for(let t of e){if(!f.isJSXAttribute(t))continue;let n=xe(t.name);if(W(n)){if(t.value&&!f.isStringLiteral(t.value))throw new J(`'${n}' needs a literal value, not an expression — the strategy is compile-time.`);return B(n,t.value?t.value.value:null)}}}var le=new Set([...V,...D]),et=new Set(D),ae=new Set(_),an={Show:"when",For:"each",Index:"each",Match:"when"};var ot=/^on[A-Z]/,st=["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup","mouseover","mouseout","mouseenter","mouseleave"],Z=sn((e,t={})=>{e.assertVersion(7);let{runtime:n="automatic",importSource:o="@fluixi/jsx",pragma:i="jsx",pragmaFrag:s="Fragment",development:a=!1,detectReactivity:l=!0,useLitHTML:c=!0,hoistStatics:p=!0,delegateEvents:m=!0,delegatedEvents:u=st,optimizeControlFlow:E=!0,sourceMaps:y=!0,signalModule:R="@fluixi/dom",controlFlowModule:I="@fluixi/dom",routerModule:O="@fluixi/core/router-next",reactiveModule:Ie="@fluixi/reactive/signal",autoShowTransform:we=!1,backend:M="imperative",codegen:z="inline",templateClone:Ne=!0,partialTemplates:ke=!0,format:Le="both",litTag:ht="html",resolve:Et=[]}=t,Me=Te(Et),xt=Le==="lit"||Le==="both",St={backend:M,codegen:z,irImports:new Set,libModule:"@fluixi/core",controlFlowModule:I,routerModule:O,templateClone:Ne,partialTemplates:ke,hasJSX:!1,hasReactivity:!1,hasLitHTML:!1,needsSignalImport:!1,needsControlFlowImport:!1,needsCreateMemo:!1,controlFlowComponents:new Set,resolvedComponents:new Map,deferredComponents:new Map,componentResolver:Me,delegatedEvents:new Set,staticElements:new Map,staticTemplates:new Map,staticCounter:0};return{name:"@fluixi/babel-plugin-jsx",manipulateOptions(g,d){d.plugins.push("jsx","typescript")},pre(g){Object.assign(g,St)},visitor:{ImportDeclaration(g,d){g.node.source.value==="@fluixi/core/rx"&&(g.node.source=r.stringLiteral("@fluixi/reactive"))},Program:{enter(g,d){Object.assign(d,{hasJSX:!1,hasReactivity:!1,hasLitHTML:!1,hasLitIR:!1,needsSignalImport:!1,needsControlFlowImport:!1,needsCreateMemo:!1,controlFlowComponents:new Set,resolvedComponents:new Map,deferredComponents:new Map,componentResolver:Me,delegatedEvents:new Set,staticElements:new Map,staticTemplates:new Map,autoShow:we,staticCounter:0,libModule:"@fluixi/core",controlFlowModule:I,routerModule:O,templateClone:Ne,partialTemplates:ke,backend:M,codegen:z,irImports:new Set,needsCreateNativeElement:!1,needsInsert:!1,needsSpread:!1,needsCreateComponent:!1,needsMergeProps:!1})},exit(g,d){let h=[];if(d.hasJSX||d.needsSignalImport&&h.push(r.importDeclaration([r.importSpecifier(r.identifier("signal"),r.identifier("signal"))],r.stringLiteral(R))),d.hasJSX||d.hasLitIR){if(d.irImports.size>0){let S=new Set(["Show","For","Index","Switch","Match","Dynamic","ErrorBoundary","Portal","Suspense"]),x=new Set(["createMemo","createEffect","createRenderEffect","createRoot","createSignal","onCleanup","batch","untrack"]),v=Array.from(d.irImports),C=b=>r.importSpecifier(r.identifier(b),r.identifier(b)),L=b=>!g.scope.hasBinding(b),F=v.filter(b=>x.has(b)&&L(b)),w=v.filter(b=>!S.has(b)&&!x.has(b)&&L(b)),Q=v.filter(b=>S.has(b)&&L(b));F.length>0&&h.push(r.importDeclaration(F.map(C),r.stringLiteral(Ie))),w.length>0&&h.push(r.importDeclaration(w.map(C),r.stringLiteral(R))),Q.length>0&&h.push(r.importDeclaration(Q.map(C),r.stringLiteral(I)))}if(d.hasJSX&&M==="imperative"&&z!=="ir"){let x=[[!!d.needsCreateNativeElement,"createNativeElement"],[!!d.needsSpread,"spread"],[!!d.needsInsert,"insert"],[!!d.needsCreateComponent,"createComponent"],[!!d.needsMergeProps,"mergeProps"]].filter(([v,C])=>v&&!g.scope.hasBinding(C)).map(([,v])=>r.importSpecifier(r.identifier(v),r.identifier(v)));x.length>0&&h.push(r.importDeclaration(x,r.stringLiteral(R)))}else if(d.hasJSX&&n==="automatic"&&M!=="imperative"){let S=[r.importSpecifier(r.identifier("jsx"),r.identifier("jsx")),r.importSpecifier(r.identifier("jsxs"),r.identifier("jsxs")),r.importSpecifier(r.identifier("Fragment"),r.identifier("Fragment"))];a&&S.push(r.importSpecifier(r.identifier("jsxDEV"),r.identifier("jsxDEV"))),d.needsMergeProps&&S.push(r.importSpecifier(r.identifier("mergeProps"),r.identifier("mergeProps"))),h.push(r.importDeclaration(S,r.stringLiteral(o)))}if(d.needsCreateMemo&&!g.scope.hasBinding("createMemo")&&h.push(r.importDeclaration([r.importSpecifier(r.identifier("createMemo"),r.identifier("createMemo"))],r.stringLiteral(M==="imperative"?Ie:d.libModule??"@fluixi/core"))),d.needsControlFlowImport&&d.controlFlowComponents.size>0){let S=Array.from(d.controlFlowComponents).filter(w=>!g.scope.hasBinding(w)),x=d.libModule??"@fluixi/core",v=S.filter(w=>ae.has(w)),C=S.filter(w=>et.has(w)),L=S.filter(w=>!et.has(w)&&!ae.has(w)),F=(w,Q)=>r.importDeclaration(w.map(b=>r.importSpecifier(r.identifier(b),r.identifier(b))),r.stringLiteral(Q));L.length>0&&h.push(F(L,I)),C.length>0&&h.push(F(C,x)),v.length>0&&h.push(F(v,O))}let k=[];if(d.deferredComponents.size>0){for(let[S,x]of d.deferredComponents)g.scope.hasBinding(S)||k.push(r.variableDeclaration("const",[r.variableDeclarator(r.identifier(S),r.callExpression(r.identifier("deferred"),[r.arrowFunctionExpression([],r.callExpression(r.import(),[r.stringLiteral(x.module)])),r.objectExpression([r.objectProperty(r.identifier("strategy"),dn(x.strategy)),r.objectProperty(r.identifier("export"),r.stringLiteral(x.export))])]))]));k.length>0&&!g.scope.hasBinding("deferred")&&h.push(r.importDeclaration([r.importSpecifier(r.identifier("deferred"),r.identifier("deferred"))],r.stringLiteral(d.libModule??"@fluixi/core")))}if(d.resolvedComponents.size>0){let S=new Map;for(let[x,v]of d.resolvedComponents){if(g.scope.hasBinding(x))continue;let C=S.get(v.module)??[];C.push({local:x,exported:v.export}),S.set(v.module,C)}for(let[x,v]of S)h.push(r.importDeclaration(v.map(({local:C,exported:L})=>L==="default"?r.importDefaultSpecifier(r.identifier(C)):r.importSpecifier(r.identifier(C),r.identifier(L))),r.stringLiteral(x)))}if(m&&d.delegatedEvents.size>0){h.push(r.importDeclaration([r.importSpecifier(r.identifier("delegateEvents"),r.identifier("delegateEvents"))],r.stringLiteral(M==="imperative"?R:"@fluixi/jsx")));let S=r.arrayExpression(Array.from(d.delegatedEvents).map(v=>r.stringLiteral(v))),x=r.expressionStatement(r.callExpression(r.identifier("delegateEvents"),[S]));g.node.body.unshift(x)}if(p&&d.staticElements.size>0){let S=[];d.staticElements.forEach((x,v)=>{S.push(r.variableDeclaration("const",[r.variableDeclarator(r.identifier(v),x)]))}),g.node.body.unshift(...S)}if(k.length>0&&g.node.body.unshift(...k),d.staticTemplates.size>0){let S=[];for(let[x,v]of d.staticTemplates){let L=x.startsWith("svg:")?x.slice(4):x;S.push(r.variableDeclaration("const",[r.variableDeclarator(r.identifier(v),r.stringLiteral(L))]))}g.node.body.unshift(...S)}}h.length>0&&g.node.body.unshift(...fn(h))}},JSXElement(g,d){if(d.hasJSX=!0,M==="imperative"&&z==="ir"){g.replaceWith(nt(g.node,d));return}let h=g.node,k=h.openingElement;if(r.isJSXIdentifier(k.name)&&ae.has(k.name.name)&&!d.componentResolver?.resolve(k.name.name)&&(d.controlFlowComponents.add(k.name.name),d.needsControlFlowImport=!0),r.isJSXIdentifier(k.name)&&le.has(k.name.name)&&(d.controlFlowComponents.add(k.name.name),E)){let x=Ln(h,d);if(x){g.replaceWith(x);return}}if(p&&M!=="imperative"&>(h,d)){let x=kn(h,d);if(x){g.replaceWith(x);return}}let S=ln(h,d,{runtime:n,pragma:i,development:a,detectReactivity:l,useLitHTML:c,autoShow:we});g.replaceWith(S)},JSXFragment(g,d){if(d.hasJSX=!0,M==="imperative"&&z==="ir"){g.replaceWith(nt(g.node,d));return}let h=ce(g.node,d,{runtime:n,pragmaFrag:s,development:a});g.replaceWith(h)},CallExpression(g,d){if(!l)return;let h=g.node.callee;h.name,r.isIdentifier(h)&&(h.name==="createSignal"||h.name==="createStore"||h.name==="useContext"||h.name==="useLocation")&&(d.hasReactivity=!0)},JSXExpressionContainer(g){},TaggedTemplateExpression(g,d){if(xt&&M==="imperative"&&r.isIdentifier(g.node.tag)&&(g.node.tag.name===ht||g.node.tag.name==="svg")){g.replaceWith(gn(g.node,d));return}}}}});function ln(e,t,n){let{runtime:o,pragma:i,development:s,autoShow:a=!0}=n;return o==="automatic"?Y(e,t,s,a):xn(e,t,i)}var cn=new Set(["svg","path","circle","rect","line","polygon","polyline","ellipse","g","defs","clipPath","text"]);function tt(e,t,n){return t.length>0?(n.needsMergeProps=!0,r.callExpression(r.identifier("mergeProps"),[...t,r.objectExpression(e)])):r.objectExpression(e)}function at(e){return e.length===1?e[0]:r.arrayExpression(e)}function pn(e,t,n,o,i,s){if(!t){let u=[...n];return i.length>0&&u.push(r.objectMethod("get",r.identifier("children"),[],r.blockStatement([r.returnStatement(at(i))]))),lt(e,tt(u,o,s),s)}let a=e.value,l=cn.has(a),c=r.identifier("_el$"),p=[];s.needsCreateNativeElement=!0;let m=[e];if(l&&m.push(r.booleanLiteral(!0)),p.push(r.variableDeclaration("const",[r.variableDeclarator(c,r.callExpression(r.identifier("createNativeElement"),m))])),n.length>0||o.length>0){s.needsSpread=!0;let u=[r.objectProperty(r.identifier("element"),c),r.objectProperty(r.identifier("props"),tt(n,o,s))];l&&u.push(r.objectProperty(r.identifier("isSVG"),r.booleanLiteral(!0))),p.push(r.expressionStatement(r.callExpression(r.identifier("spread"),[r.objectExpression(u)])))}if(i.length>0){s.needsInsert=!0;for(let u of i){let y=r.isArrowFunctionExpression(u)||r.isFunctionExpression(u)||r.isCallExpression(u)&&r.isIdentifier(u.callee)&&u.callee.name==="createMemo"?[r.cloneNode(c),u,r.nullLiteral()]:[r.cloneNode(c),u];p.push(r.expressionStatement(r.callExpression(r.identifier("insert"),y)))}}return p.push(r.returnStatement(c)),r.callExpression(r.arrowFunctionExpression([],r.blockStatement(p)),[])}function un(e,t){let n=null;if(t.value)if(r.isStringLiteral(t.value))n=t.value.value;else throw new J(`'${e}' needs a literal value, not an expression — the strategy is compile-time.`);return B(e,n)}function dn(e){let t=[r.objectProperty(r.identifier("kind"),r.stringLiteral(e.kind))];return e.kind==="visible"&&e.rootMargin&&t.push(r.objectProperty(r.identifier("rootMargin"),r.stringLiteral(e.rootMargin))),e.kind==="interaction"&&t.push(r.objectProperty(r.identifier("events"),r.arrayExpression(e.events.map(n=>r.stringLiteral(n))))),e.kind==="media"&&t.push(r.objectProperty(r.identifier("query"),r.stringLiteral(e.query))),r.objectExpression(t)}function mn(e,t){return!P(e)||!P(t)?A:e}function lt(e,t,n){r.isIdentifier(e)&&le.has(e.name)&&(n.controlFlowComponents.add(e.name),n.needsControlFlowImport=!0);let o=!1;if(r.isIdentifier(e)&&!le.has(e.name)&&n.componentResolver){let i=n.componentResolver.resolve(e.name);if(i){let s=n.pendingLoad??A,a=n.resolvedComponents.has(e.name);if(P(s)&&!a){let l=n.deferredComponents.get(e.name),c=l?mn(l.strategy,s):s;P(c)?n.deferredComponents.set(e.name,{...i,strategy:c}):(n.deferredComponents.delete(e.name),n.resolvedComponents.set(e.name,i))}else n.deferredComponents.delete(e.name),n.resolvedComponents.set(e.name,i);o=!0}}return n.pendingLoad=void 0,!o&&r.isIdentifier(e)&&ae.has(e.name)&&(n.controlFlowComponents.add(e.name),n.needsControlFlowImport=!0),n.backend==="imperative"?(n.needsCreateComponent=!0,n.needsCreateMemo=!0,r.callExpression(r.identifier("createMemo"),[r.arrowFunctionExpression([],r.callExpression(r.identifier("createComponent"),[e,t]))])):r.callExpression(r.identifier("jsx"),[e,t])}function ct(e,t,n){if(!t||t.length===0)return e;let o=new Map;for(let i of t){let s=`${i.svg?"svg:":""}${i.html}`,a=n.staticTemplates.get(s);a||(a=`_tmpl$${n.staticTemplates.size}`,n.staticTemplates.set(s,a)),o.set(i.id,a)}return e.replace(/_tmpl\$\d+/g,i=>o.get(i)??i)}function nt(e,t){let n=new Set,o=Se(e,n);ue(o,{resolver:t.componentResolver,modules:{controlFlowModule:t.controlFlowModule,coreModule:t.libModule,routerModule:t.routerModule},strategyFor:c=>c.load}),de(o);let{code:i,imports:s,templates:a}=X.emit(o,{templateClone:t.templateClone,partialTemplates:t.partialTemplates});for(let c of s)n.add(c);for(let c of n)t.irImports.add(c);be(o,t);let l=ct(i,a,t);return it.expression(l,{placeholderPattern:!1,plugins:["typescript"]})()}function fn(e){let t=new Map,n=[];for(let o of e){let i=o.source.value;if(!o.specifiers.every(l=>r.isImportSpecifier(l))){n.push(o);continue}let a=t.get(i);if(!a){let l=new Set(o.specifiers.map(c=>c.local.name));t.set(i,{decl:o,names:l}),n.push(o);continue}for(let l of o.specifiers)a.names.has(l.local.name)||(a.names.add(l.local.name),a.decl.specifiers.push(l))}return n}function gn(e,t){let n=new Set,o=r.isIdentifier(e.tag)&&e.tag.name==="svg",i=se(e,n,{svg:o});ue(i,{resolver:t.componentResolver,modules:{controlFlowModule:t.controlFlowModule,coreModule:t.libModule,routerModule:t.routerModule},strategyFor:p=>p.load}),de(i);let{code:s,imports:a,templates:l}=X.emit(i,{templateClone:t.templateClone,partialTemplates:t.partialTemplates});for(let p of a)n.add(p);for(let p of n)t.irImports.add(p);be(i,t),t.hasLitIR=!0;let c=it.expression(ct(s,l,t),{placeholderPattern:!1,plugins:["typescript"]})();return hn(c,e),c}function hn(e,t){if(!t.loc)return;let n=new Set,o=i=>{if(!n.has(i)){n.add(i),i.loc||(i.loc=t.loc,i.start=t.start,i.end=t.end);for(let s of r.VISITOR_KEYS[i.type]??[]){let a=i[s];if(Array.isArray(a))for(let l of a)l&&typeof l=="object"&&"type"in l&&o(l);else a&&typeof a=="object"&&"type"in a&&o(a)}}};o(e)}function be(e,t){if(e.kind==="component"&&e.source&&(e.source.origin==="builtin"?(t.controlFlowComponents.add(e.name),t.needsControlFlowImport=!0):P(e.source.loading)&&!t.resolvedComponents.has(e.name)?t.deferredComponents.set(e.name,{module:e.source.module,export:e.source.export,strategy:e.source.loading}):(t.deferredComponents.delete(e.name),t.resolvedComponents.set(e.name,{module:e.source.module,export:e.source.export}))),(e.kind==="element"||e.kind==="component"||e.kind==="control")&&"props"in e)for(let n of e.props)n.kind==="event"&&n.event?.delegated&&t.delegatedEvents.add(n.event.name);if("children"in e&&e.children)for(let n of e.children)be(n,t)}function En(e){return e.map(t=>{if(r.isObjectProperty(t)){let n=t.key,o=t.computed,i=t.value;return r.objectMethod("get",n,[],r.blockStatement([r.returnStatement(i)]),o)}return t})}function Y(e,t,n,o=!0){let i=e.openingElement,s=e.children,a=pt(i.name),l=r.isJSXIdentifier(i.name)&&/^[a-z]/.test(i.name.name),c=dt(i.attributes,t,l,r.isJSXIdentifier(i.name)?i.name.name:""),p=c.props,m=c.spreads;l||(p=En(p));let u=ye(s,t,o);if(t.backend==="imperative")return pn(a,l,p,m,u,t);if(u.length>0){let I=u.length===1?u[0]:r.arrayExpression(u);p.push(r.objectProperty(r.identifier("children"),I))}let E;if(m.length>0){let I=p.length>0?r.objectExpression(p):r.objectExpression([]);t.needsMergeProps=!0,E=r.callExpression(r.identifier("mergeProps"),[...m,I])}else E=r.objectExpression(p);let y=n?"jsxDEV":u.length>1?"jsxs":"jsx",R=[a,E];return n&&R.push(r.identifier("undefined"),r.booleanLiteral(!1),r.identifier("undefined"),r.identifier("undefined")),r.callExpression(r.identifier(y),R)}function xn(e,t,n){let o=e.openingElement,i=e.children,s=pt(o.name),a=r.isJSXIdentifier(o.name)&&/^[a-z]/.test(o.name.name),{props:l,spreads:c}=dt(o.attributes,t,a,r.isJSXIdentifier(o.name)?o.name.name:""),p=ye(i,t,t.autoShow??!0),m;if(c.length>0){let E=l.length>0?r.objectExpression(l):r.objectExpression([]);t.needsMergeProps=!0,m=r.callExpression(r.identifier("mergeProps"),[...c,E])}else m=l.length>0?r.objectExpression(l):r.nullLiteral();let u=[s,m,...p];return r.callExpression(r.identifier(n),u)}function ce(e,t,n){let{runtime:o,pragmaFrag:i,development:s}=n,a=ye(e.children,t,t.autoShow??!0);if(t.backend==="imperative")return a.length===0?r.nullLiteral():at(a);if(o==="automatic"){let l=s?"jsxDEV":a.length>1?"jsxs":"jsx",c=r.objectExpression([r.objectProperty(r.identifier("children"),a.length===1?a[0]:r.arrayExpression(a))]),p=[r.identifier("Fragment"),c];return s&&p.push(r.identifier("undefined"),r.booleanLiteral(!1),r.identifier("undefined"),r.identifier("undefined")),r.callExpression(r.identifier(l),p)}else return r.callExpression(r.identifier(i),a)}function pt(e){if(r.isJSXIdentifier(e)){let t=e.name;return t[0]===t[0].toLowerCase()?r.stringLiteral(t):r.identifier(t)}return r.isJSXMemberExpression(e)?ut(e):r.isJSXNamespacedName(e)?r.stringLiteral(`${e.namespace.name}:${e.name.name}`):r.stringLiteral("div")}function ut(e){let t;return r.isJSXIdentifier(e.object)?t=r.identifier(e.object.name):t=ut(e.object),r.memberExpression(t,r.identifier(e.property.name))}function Sn(e){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(e)}function dt(e,t,n=!0,o=""){let i=[],s=[],a=an[o];t.pendingLoad=void 0;for(let l of e)if(r.isJSXSpreadAttribute(l))s.push(l.argument);else if(r.isJSXAttribute(l)){let c=vn(l.name);if(W(c)){t.pendingLoad=un(c,l);continue}let p=bn(l.value,t,c,n);if(ot.test(c)){let O=c.slice(2).toLowerCase();st.includes(O)&&t.delegatedEvents.add(O)}let m=Sn(c)?r.identifier(c):r.stringLiteral(c),u=l.value,E=r.isJSXElement(u)||r.isJSXFragment(u)||r.isJSXExpressionContainer(u)&&(r.isJSXElement(u.expression)||r.isJSXFragment(u.expression)),y=!n&&c===a,R=r.isJSXExpressionContainer(u)&&!r.isJSXEmptyExpression(u.expression)?u.expression:null,I=!n&&!!R&&mt(R,c);!n&&E||y||I?i.push(r.objectMethod("get",m,[],r.blockStatement([r.returnStatement(p)]))):i.push(r.objectProperty(m,p))}return{props:i,spreads:s}}function vn(e){return r.isJSXIdentifier(e)?e.name==="class"?"className":e.name:r.isJSXNamespacedName(e)?`${e.namespace.name}:${e.name.name}`:"unknown"}function bn(e,t,n="",o=!0){if(e===null)return r.booleanLiteral(!0);if(r.isStringLiteral(e))return e.value.includes(`
|
|
2
|
+
`)?r.stringLiteral(e.value.replace(/\s+/g," ").trim()):e;if(r.isJSXExpressionContainer(e)){if(r.isJSXEmptyExpression(e.expression))return r.booleanLiteral(!0);let i=e.expression;return o&&mt(i,n)?r.arrowFunctionExpression([],i):i}return r.isJSXElement(e)?Y(e,t,!1,t.autoShow??!0):r.isJSXFragment(e)?ce(e,t,{runtime:"automatic",pragmaFrag:"Fragment",development:!1}):r.booleanLiteral(!0)}function mt(e,t){return ot.test(t)||t.startsWith("on:")||t==="ref"||t.startsWith("use:")||r.isArrowFunctionExpression(e)||r.isFunctionExpression(e)||r.isIdentifier(e)||r.isStringLiteral(e)||r.isNumericLiteral(e)||r.isBooleanLiteral(e)||r.isNullLiteral(e)?!1:!!(r.isCallExpression(e)||r.isOptionalCallExpression(e)||r.isMemberExpression(e)||r.isOptionalMemberExpression(e)||r.isLogicalExpression(e)||r.isConditionalExpression(e)||r.isBinaryExpression(e)||r.isUnaryExpression(e)||r.isTemplateLiteral(e)||r.isObjectExpression(e)||r.isArrayExpression(e))}function yn(e){let t=e.split(/\r\n|\n|\r/),n=0;for(let i=0;i<t.length;i++)/[^ \t]/.test(t[i])&&(n=i);let o="";for(let i=0;i<t.length;i++){let s=t[i].replace(/\t/g," ");i!==0&&(s=s.replace(/^ +/,"")),i!==t.length-1&&(s=s.replace(/ +$/,"")),s&&(i!==n&&(s+=" "),o+=s)}return o}function ye(e,t,n=!0){let o=[];for(let i of e)if(r.isJSXText(i)){let s=yn(i.value);s&&o.push(r.stringLiteral(s))}else if(r.isJSXExpressionContainer(i)){if(!r.isJSXEmptyExpression(i.expression)){let s=i.expression;if(n){let a=Rn(s,t)??Cn(s,t);if(a){o.push(a);continue}}else{let a=In(s,t);if(a){o.push(a);continue}}Nn(s)?o.push(r.arrowFunctionExpression([],s)):o.push(s)}}else r.isJSXElement(i)?o.push(Y(i,t,!1,t.autoShow??!0)):r.isJSXFragment(i)?o.push(ce(i,t,{runtime:"automatic",pragmaFrag:"Fragment",development:!1})):r.isJSXSpreadChild(i)&&o.push(i.expression);return o}function Rn(e,t){if(!r.isArrowFunctionExpression(e)||e.params.length!==0||e.async)return null;let n=e.body;if(r.isLogicalExpression(n)&&n.operator==="&&"){let o=T(n.right);if(o)return K(j(n.left),o,null,t)}if(r.isConditionalExpression(n)){let o=T(n.consequent);if(o){let i=Re(n.alternate,t);return K(j(n.test),o,i,t,!0)}}return null}function Cn(e,t){if(r.isLogicalExpression(e)&&e.operator==="&&"){let n=T(e.right);if(n)return K(j(e.left),n,null,t)}if(r.isConditionalExpression(e)){let n=T(e.consequent);if(n){let o=Re(e.alternate,t);return K(j(e.test),n,o,t)}}return null}function In(e,t){let n=r.isArrowFunctionExpression(e)&&e.params.length===0&&!e.async&&r.isExpression(e.body)?e.body:e;if(r.isConditionalExpression(n)){let o=j(n.test),s=T(n.consequent)??n.consequent,l=T(n.alternate)??n.alternate,c=r.conditionalExpression(o,s,l);return ve(n.consequent)||ve(n.alternate)?null:(t.needsCreateMemo=!0,r.callExpression(r.identifier("createMemo"),[r.arrowFunctionExpression([],c)]))}if(r.isLogicalExpression(n)&&n.operator==="&&"){let o=j(n.left),s=T(n.right)??n.right,a=r.logicalExpression("&&",o,s);return ve(n.right)?null:(t.needsCreateMemo=!0,r.callExpression(r.identifier("createMemo"),[r.arrowFunctionExpression([],a)]))}return null}function Re(e,t){if(wn(e))return null;let n=T(e);if(n)return ft(n,t);if(r.isConditionalExpression(e)){let o=e,i=T(o.consequent);if(i){let s=Re(o.alternate,t);return K(j(o.test),i,s,t)}}return e}function rt(e){return r.isJSXElement(e)||r.isJSXFragment(e)}function ve(e){let t=T(e);if(!t||!r.isJSXElement(t))return!1;let n=t.openingElement.name;return r.isJSXIdentifier(n)&&le.has(n.name)}function T(e){return rt(e)?e:r.isArrowFunctionExpression(e)&&e.params.length===0&&!e.async&&rt(e.body)?e.body:null}function j(e){return r.isArrowFunctionExpression(e)&&e.params.length===0&&!e.async&&r.isExpression(e.body)?e.body:e}function wn(e){return r.isNullLiteral(e)||r.isIdentifier(e)&&e.name==="undefined"||r.isBooleanLiteral(e)&&e.value===!1}function ft(e,t){return r.isJSXElement(e)?Y(e,t,!1,t.autoShow??!0):ce(e,t,{runtime:"automatic",pragmaFrag:"Fragment",development:!1})}function K(e,t,n,o,i=!1){o.controlFlowComponents.add("Show"),o.needsControlFlowImport=!0;let s=ft(t,o),a=[r.objectProperty(r.identifier("when"),r.arrowFunctionExpression([],e)),r.objectProperty(r.identifier("children"),s)];return n&&a.push(r.objectProperty(r.identifier("fallback"),n)),lt(r.identifier("Show"),r.objectExpression(a),o)}function Nn(e){return r.isMemberExpression(e)||r.isOptionalMemberExpression(e)?!(!e.computed&&r.isIdentifier(e.property,{name:"children"})):r.isCallExpression(e)||r.isOptionalCallExpression(e)?!0:r.isIdentifier(e)?!1:!!(r.isLogicalExpression(e)||r.isConditionalExpression(e)||r.isBinaryExpression(e)||r.isUnaryExpression(e)||r.isTemplateLiteral(e))}function gt(e,t){let n=e.openingElement;if(!r.isJSXIdentifier(n.name))return!1;let o=n.name.name;if(o[0]!==o[0].toLowerCase())return!1;for(let i of n.attributes){if(r.isJSXSpreadAttribute(i))return!1;if(r.isJSXAttribute(i)){let s=i.value;if(r.isJSXExpressionContainer(s)&&!r.isStringLiteral(s.expression)&&!r.isNumericLiteral(s.expression))return!1}}for(let i of e.children)if(r.isJSXElement(i)&&!gt(i,t)||r.isJSXExpressionContainer(i))return!1;return!0}function kn(e,t){let n=`_$static${t.staticCounter++}`,o=Y(e,t,!1);return t.staticElements.set(n,o),r.identifier(n)}function Ln(e,t){let n=e.openingElement.name.name;return n==="Show"?Mn(e,t):n==="For"?Jn(e,t):null}function Mn(e,t){return null}function Jn(e,t){return null}var Nr=Z;function kr(e){return[Z,e]}function Ce(e={}){return{plugins:[[Z,{runtime:"automatic",importSource:"@fluixi/jsx",development:!1,detectReactivity:!0,useLitHTML:!0,hoistStatics:!0,delegateEvents:!0,optimizeControlFlow:!0,sourceMaps:!0,...e}]]}}var Lr={production:Ce({development:!1,hoistStatics:!0,delegateEvents:!0,optimizeControlFlow:!0}),development:Ce({development:!0,hoistStatics:!1,sourceMaps:!0}),minimal:Ce({detectReactivity:!1,useLitHTML:!1,hoistStatics:!1,delegateEvents:!1,optimizeControlFlow:!1})};export{Nr as babelPluginReactiveJSX,kr as createPlugin,Ce as createPreset,Z as default,Lr as presets};
|
package/dist/codegen/backend.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var i=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var a=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of s(t))!m.call(e,o)&&o!==r&&i(e,o,{get:()=>t[o],enumerable:!(n=p(t,o))||n.enumerable});return e};var c=e=>a(i({},"__esModule",{value:!0}),e);var g={};module.exports=c(g);
|
|
@@ -6,6 +6,20 @@ export interface CodegenResult {
|
|
|
6
6
|
map?: unknown;
|
|
7
7
|
/** runtime symbols this output imports (subset of the backend's contract) */
|
|
8
8
|
imports: string[];
|
|
9
|
+
/**
|
|
10
|
+
* Templates to declare once at module scope, so a static subtree is parsed once and
|
|
11
|
+
* cloned per instance rather than rebuilt element by element.
|
|
12
|
+
*/
|
|
13
|
+
templates?: StaticTemplate[];
|
|
14
|
+
}
|
|
15
|
+
export interface StaticTemplate {
|
|
16
|
+
/** Identifier to declare, unique within the emitted unit. */
|
|
17
|
+
id: string;
|
|
18
|
+
/** The HTML the template is built from. */
|
|
19
|
+
html: string;
|
|
20
|
+
/** Root tag name, so hydration can match the server's node before adopting it. */
|
|
21
|
+
tag: string;
|
|
22
|
+
svg: boolean;
|
|
9
23
|
}
|
|
10
24
|
/**
|
|
11
25
|
* A codegen backend turns IR into runtime calls. This is the swap point: the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/codegen/backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,6EAA6E;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../../src/codegen/backend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,6EAA6E;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,2CAA2C;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,OAAO,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,QAAQ,EAAE,eAAe,CAAC;IAC1B,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,aAAa,CAAC;CAC7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var $=Object.defineProperty;var M=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var J=(e,t)=>{for(var r in t)$(e,r,{get:t[r],enumerable:!0})},H=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of L(t))!z.call(e,o)&&o!==r&&$(e,o,{get:()=>t[o],enumerable:!(i=M(t,o))||i.enumerable});return e};var V=e=>H($({},"__esModule",{value:!0}),e);var ae={};J(ae,{imperativeBackend:()=>se,inlineTemplates:()=>oe});module.exports=V(ae);var B=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),k={className:"class",htmlFor:"for"},F=new Set(["innerHTML","outerHTML","innerText","textContent","value","checked","selected","muted","defaultValue","defaultChecked","children","ref"]),W=new Set(["script","style","textarea","title"]);function R(e){return W.has(e)}function y(e){return k[e]??e}function p(e){return e.kind!=="attr"||e.expr!==void 0||e.name.includes(":")?!1:!F.has(e.name)}function x(e){if(!e.static||R(e.tag))return!1;for(let t of e.props)if(!p(t))return!1;for(let t of e.children)if(t.kind!=="text"&&!(t.kind==="element"&&x(t)))return!1;return!0}function m(e){let t=e.props.map(U).filter(Boolean).join(""),r=`<${e.tag}${t}>`;return B.has(e.tag)?r:`${r}${e.children.map(D).join("")}</${e.tag}>`}function D(e){if(e.kind==="text")return Z(e.value);if(e.kind!=="element")throw new Error(`serializeStatic: unexpected ${e.kind}`);return m(e)}function U(e){let t=k[e.name]??e.name,r=e.literal;return r===!0||r===void 0?` ${t}`:r===!1||r===null?"":` ${t}="${Y(String(r))}"`}function Y(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function Z(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}var q="<!--fx-->",G="<!--fx/-->";function h(e){return e.kind==="expr"||e.kind==="component"||e.kind==="control"}function K(e){return e.kind==="text"||e.kind==="element"&&v(e)}function v(e){return e.svg||R(e.tag)||!e.props.every(t=>p(t))?!1:e.children.every(t=>K(t)||h(t))}function d(e){if(h(e))return!0;let t=e.children;return t?t.some(d):!1}function C(e){for(let t=0;t<e.children.length;t++){let r=e.children[t];if(r.kind==="text"&&(r.value===""||e.children[t+1]?.kind==="text"))return!1}return e.children.every(t=>t.kind!=="element"||C(t))}function b(e){if(!v(e)||!C(e)||!e.children.some(d))return null;let t=[],r=[],i=0,o=f=>{let n=`_n$${i++}`;return t.push({ref:n,expr:f}),n};return a(e,"_el$"),{html:X(e),tag:e.tag,steps:t,holes:r};function a(f,n){let c=-1;f.children.forEach((l,u)=>{d(l)&&(c=u)});let s=null;for(let l=0;l<=c;l++){let u=f.children[l],S=s?`${s}.nextSibling`:`${n}.firstChild`;if(h(u)){let T=o(S),E=o(`holeEnd(${T})`);r.push({parentRef:n,startRef:T,endRef:E,node:u}),s=E;continue}let I=o(S);u.kind==="element"&&d(u)&&a(u,I),s=I}}}function X(e){return m(P(e)).split(O).join(q+G)}function P(e){return{...e,children:e.children.map(t=>h(t)?{kind:"text",value:O}:t.kind==="element"?P(t):t)}}var O="\0fx-hole\0";var N={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},pe={version:2,module:"@fluixi/dom",symbols:[...N.symbols,"template","cloneTemplate","walk"]};var Q={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function ee(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function A(e){return ee(e)?e:JSON.stringify(e)}function te(e){return e.expr!==void 0?e.reactive?`() => (${e.expr})`:`(${e.expr})`:JSON.stringify(e.literal??!0)}function re(e){return e.expr!==void 0?`(${e.expr})`:JSON.stringify(e.literal??!0)}function ne(e,t,r){let i=e.filter(n=>n.kind==="spread"),a=e.filter(n=>n.kind!=="spread").map(n=>`${A(n.name)}: ${te(n)}`);t!=null&&a.push(`children: ${t}`);let f=`{ ${a.join(", ")} }`;return i.length>0?(r.add("mergeProps"),`mergeProps(${i.map(n=>n.expr).join(", ")}, ${f})`):f}function w(e,t,r){return e.length===1?g(e[0],t,r):`[${e.map(i=>g(i,t,r)).join(", ")}]`}function _(e,t,r,i,o){i.add("createMemo"),i.add("createComponent");let a=t.filter(s=>s.kind==="spread"),n=t.filter(s=>s.kind!=="spread").map(s=>`get ${A(s.name)}() { return ${re(s)}; }`);r.length>0&&n.push(`get children() { return ${w(r,i,o)}; }`);let c=`{ ${n.join(", ")} }`;return a.length>0&&(i.add("mergeProps"),c=`mergeProps(${a.map(s=>s.expr).join(", ")}, ${c})`),`createMemo(() => createComponent(${e}, ${c}))`}function ie(e,t){let r=y(t.name),i=t.literal;return i===!0||i===void 0?`${e}.setAttribute(${JSON.stringify(r)}, "");`:i===!1||i===null?"":`${e}.setAttribute(${JSON.stringify(r)}, ${JSON.stringify(String(i))});`}var j=!1;function g(e,t,r){switch(e.kind){case"text":return JSON.stringify(e.value);case"expr":return e.reactive?`() => (${e.code})`:`(${e.code})`;case"fragment":return e.children.length===0?"null":w(e.children,t,r);case"component":return _(e.name,e.props,e.children,t,r);case"control":{let i=Q[e.control]??e.control;return t.add(i),_(i,e.props,e.children,t,r)}case"element":{if(r&&e.static&&!e.svg&&x(e)){t.add("templateNode");let n=`_tmpl$${r.length}`;return r.push({id:n,html:m(e),tag:e.tag,svg:!1}),`templateNode(${n}, ${JSON.stringify(e.tag)})`}if(r&&j){let n=b(e);if(n){t.add("templateNode"),t.add("insert"),t.add("holeEnd"),t.add("holeContent"),t.add("holeScope");let c=`_tmpl$${r.length}`;r.push({id:c,html:n.html,tag:n.tag,svg:!1});let s=[`const _el$ = templateNode(${c}, ${JSON.stringify(n.tag)}, true);`];for(let l of n.steps)s.push(`const ${l.ref} = ${l.expr};`);for(let l of n.holes)s.push(`insert(${l.parentRef}, holeScope(${l.startRef}, () => (${g(l.node,t,r)})), ${l.endRef}, holeContent(${l.startRef}, ${l.endRef}));`);return s.push("return _el$;"),`(() => { ${s.join(" ")} })()`}}t.add("createNativeElement");let i=JSON.stringify(e.tag),o="_el$",a=[],f=e.svg?`${i}, true`:i;if(a.push(`const ${o} = createNativeElement(${f});`),e.props.length>0)if(!e.svg&&e.props.every(p))for(let n of e.props)a.push(ie(o,n));else{t.add("spread");let n=e.svg?", isSVG: true":"";a.push(`spread({ element: ${o}, props: ${ne(e.props,null,t)}${n} });`)}for(let n of e.children){t.add("insert");let c=g(n,t,r),s=n.kind==="expr"&&n.reactive||n.kind==="component"||n.kind==="control";a.push(s?`insert(${o}, ${c}, null);`:`insert(${o}, ${c});`)}return a.push(`return ${o};`),`(() => { ${a.join(" ")} })()`}}}function oe(e,t){if(!t||t.length===0)return e;let r=new Map(t.map(i=>[i.id,JSON.stringify(i.html)]));return e.replace(/_tmpl\$\d+/g,i=>r.get(i)??i)}var se={name:"imperative",contract:N,emit(e,t){let r=new Set,i=t?.templateClone!==!1?[]:void 0;return j=t?.partialTemplates===!0,{code:g(e,r,i),imports:Array.from(r),templates:i}}};
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
import type { CodegenBackend } from '../backend.js';
|
|
1
|
+
import type { CodegenBackend, StaticTemplate } from '../backend.js';
|
|
2
|
+
/**
|
|
3
|
+
* Substitute template declarations into the code as inline `createTemplate` calls.
|
|
4
|
+
*
|
|
5
|
+
* For hosts that cannot hoist — nested JSX lowered inside an expression, where there is
|
|
6
|
+
* no module scope to reach. `createTemplate` caches by HTML string, so this costs a Map
|
|
7
|
+
* lookup per instantiation rather than a re-parse, and is still far cheaper than
|
|
8
|
+
* building the subtree element by element.
|
|
9
|
+
*/
|
|
10
|
+
export declare function inlineTemplates(code: string, templates: StaticTemplate[] | undefined): string;
|
|
2
11
|
export declare const imperativeBackend: CodegenBackend;
|
|
3
12
|
//# sourceMappingURL=imperative.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"imperative.d.ts","sourceRoot":"","sources":["../../../src/codegen/backends/imperative.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"imperative.d.ts","sourceRoot":"","sources":["../../../src/codegen/backends/imperative.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAiB,cAAc,EAAE,MAAM,eAAe,CAAC;AAgQnF;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,SAAS,GAAG,MAAM,CAK7F;AAED,eAAO,MAAM,iBAAiB,EAAE,cAgB/B,CAAC"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { planPartialTemplate } from '../partial-template.js';
|
|
2
|
+
import { isSerializable, serializeStatic, isPlainLiteralAttr, htmlAttrName, } from '../serialize-static.js';
|
|
1
3
|
import { RUNTIME_CONTRACT_V1 } from '../contract.js';
|
|
2
4
|
/**
|
|
3
5
|
* Imperative fine-grained backend — emits createNativeElement/insert/spread/
|
|
@@ -65,12 +67,12 @@ function emitProps(props, childrenExpr, used) {
|
|
|
65
67
|
}
|
|
66
68
|
return obj;
|
|
67
69
|
}
|
|
68
|
-
function emitChildren(children, used) {
|
|
70
|
+
function emitChildren(children, used, templates) {
|
|
69
71
|
if (children.length === 1)
|
|
70
|
-
return emitNode(children[0], used);
|
|
71
|
-
return `[${children.map((c) => emitNode(c, used)).join(', ')}]`;
|
|
72
|
+
return emitNode(children[0], used, templates);
|
|
73
|
+
return `[${children.map((c) => emitNode(c, used, templates)).join(', ')}]`;
|
|
72
74
|
}
|
|
73
|
-
function emitComponent(name, props, children, used) {
|
|
75
|
+
function emitComponent(name, props, children, used, templates) {
|
|
74
76
|
used.add('createMemo');
|
|
75
77
|
used.add('createComponent');
|
|
76
78
|
const spreads = props.filter((p) => p.kind === 'spread');
|
|
@@ -86,16 +88,48 @@ function emitComponent(name, props, children, used) {
|
|
|
86
88
|
// child components are created in the component's owner scope (preserves owner
|
|
87
89
|
// nesting for context/Suspense), after the component runs (correct provider
|
|
88
90
|
// ordering), and lazily (ErrorBoundary can still catch a throwing child).
|
|
89
|
-
entries.push(`get children() { return ${emitChildren(children, used)}; }`);
|
|
91
|
+
entries.push(`get children() { return ${emitChildren(children, used, templates)}; }`);
|
|
90
92
|
}
|
|
91
93
|
let obj = `{ ${entries.join(', ')} }`;
|
|
92
94
|
if (spreads.length > 0) {
|
|
93
95
|
used.add('mergeProps');
|
|
94
96
|
obj = `mergeProps(${spreads.map((s) => s.expr).join(', ')}, ${obj})`;
|
|
95
97
|
}
|
|
98
|
+
// The memo never recomputes — every prop is a getter, so this callback reads nothing
|
|
99
|
+
// reactive. It is here for what it makes `insert` do, and it cannot be elided.
|
|
100
|
+
//
|
|
101
|
+
// A component whose return value is *itself* bare control flow (`return <Show …/>`)
|
|
102
|
+
// produces a memo, which `createComponent` deliberately does not stamp as a component.
|
|
103
|
+
// Without this wrapper `insert` stops re-reading it, and the subtree goes stale when a
|
|
104
|
+
// sibling updates the context it depends on — see `show-context-insert.spec.ts`.
|
|
105
|
+
//
|
|
106
|
+
// Static props are not a sufficient condition for dropping it either: safety depends on
|
|
107
|
+
// what the callee *returns*, which lives in another module and is not visible here.
|
|
108
|
+
//
|
|
109
|
+
// Nor can it be a plain `() => createComponent(...)` thunk. The memo also provides
|
|
110
|
+
// *identity*: it runs once and caches. A thunk is re-invoked by insert's render effect
|
|
111
|
+
// on every run, rebuilding the component with a fresh owner — which loses context,
|
|
112
|
+
// duplicates the tree on hydration and piles up Portals. Measured: dropping the wrapper
|
|
113
|
+
// fails 3 tests, replacing it with a thunk fails 14.
|
|
114
|
+
//
|
|
115
|
+
// Control flow does use a bare arrow, and that is not a counter-example: control flow
|
|
116
|
+
// is the reactive boundary and is *meant* to re-run. A user component is meant to run
|
|
117
|
+
// once.
|
|
96
118
|
return `createMemo(() => createComponent(${name}, ${obj}))`;
|
|
97
119
|
}
|
|
98
|
-
|
|
120
|
+
/** `el.setAttribute("class", "card")` for a compile-time constant. */
|
|
121
|
+
function staticAttrAssignment(el, prop) {
|
|
122
|
+
const name = htmlAttrName(prop.name);
|
|
123
|
+
const value = prop.literal;
|
|
124
|
+
// A valueless attribute is `true` in the IR and the empty string in the DOM.
|
|
125
|
+
if (value === true || value === undefined)
|
|
126
|
+
return `${el}.setAttribute(${JSON.stringify(name)}, "");`;
|
|
127
|
+
if (value === false || value === null)
|
|
128
|
+
return '';
|
|
129
|
+
return `${el}.setAttribute(${JSON.stringify(name)}, ${JSON.stringify(String(value))});`;
|
|
130
|
+
}
|
|
131
|
+
let partial = false;
|
|
132
|
+
function emitNode(node, used, templates) {
|
|
99
133
|
switch (node.kind) {
|
|
100
134
|
case 'text':
|
|
101
135
|
return JSON.stringify(node.value);
|
|
@@ -104,15 +138,59 @@ function emitNode(node, used) {
|
|
|
104
138
|
case 'fragment':
|
|
105
139
|
if (node.children.length === 0)
|
|
106
140
|
return 'null';
|
|
107
|
-
return emitChildren(node.children, used);
|
|
141
|
+
return emitChildren(node.children, used, templates);
|
|
108
142
|
case 'component':
|
|
109
|
-
return emitComponent(node.name, node.props, node.children, used);
|
|
143
|
+
return emitComponent(node.name, node.props, node.children, used, templates);
|
|
110
144
|
case 'control': {
|
|
111
145
|
const name = CONTROL_COMPONENT[node.control] ?? node.control;
|
|
112
146
|
used.add(name);
|
|
113
|
-
return emitComponent(name, node.props, node.children, used);
|
|
147
|
+
return emitComponent(name, node.props, node.children, used, templates);
|
|
114
148
|
}
|
|
115
149
|
case 'element': {
|
|
150
|
+
// A static subtree is parsed once into a <template> and cloned per instance:
|
|
151
|
+
// one cloneNode instead of an createNativeElement + spread per element.
|
|
152
|
+
// SVG is excluded: the runtime wraps SVG template HTML in an <svg> host and
|
|
153
|
+
// `cloneTemplate(t, true)` returns that wrapper, not the serialized element, so
|
|
154
|
+
// cloning would hand back the wrong node. Correctness first — SVG keeps the
|
|
155
|
+
// imperative path until the runtime grows an unwrapping clone.
|
|
156
|
+
if (templates && node.static && !node.svg && isSerializable(node)) {
|
|
157
|
+
used.add('templateNode');
|
|
158
|
+
const id = `_tmpl$${templates.length}`;
|
|
159
|
+
templates.push({ id, html: serializeStatic(node), tag: node.tag, svg: false });
|
|
160
|
+
return `templateNode(${id}, ${JSON.stringify(node.tag)})`;
|
|
161
|
+
}
|
|
162
|
+
// Structure static, contents dynamic — the common shape. One template for the
|
|
163
|
+
// structure, then each hole filled through a reference into the clone. Every
|
|
164
|
+
// reference is read before any insertion, since inserting shifts later positions.
|
|
165
|
+
if (templates && partial) {
|
|
166
|
+
const plan = planPartialTemplate(node);
|
|
167
|
+
if (plan) {
|
|
168
|
+
used.add('templateNode');
|
|
169
|
+
used.add('insert');
|
|
170
|
+
used.add('holeEnd');
|
|
171
|
+
used.add('holeContent');
|
|
172
|
+
used.add('holeScope');
|
|
173
|
+
const id = `_tmpl$${templates.length}`;
|
|
174
|
+
templates.push({ id, html: plan.html, tag: plan.tag, svg: false });
|
|
175
|
+
const lines = [`const _el$ = templateNode(${id}, ${JSON.stringify(plan.tag)}, true);`];
|
|
176
|
+
// Every reference first: inserting shifts what follows, so the walk has to be
|
|
177
|
+
// complete before any content goes in.
|
|
178
|
+
for (const step of plan.steps)
|
|
179
|
+
lines.push(`const ${step.ref} = ${step.expr};`);
|
|
180
|
+
for (const hole of plan.holes) {
|
|
181
|
+
// The fourth argument is what the hole already holds — nothing on a fresh
|
|
182
|
+
// clone, the server's content when hydrating. `insert` reconciles against it,
|
|
183
|
+
// so hydration reuses those nodes rather than building new ones.
|
|
184
|
+
// `holeScope` places the hydration cursor at what the server rendered for
|
|
185
|
+
// this hole, so anything the content builds internally adopts too.
|
|
186
|
+
lines.push(`insert(${hole.parentRef}, holeScope(${hole.startRef}, () => ` +
|
|
187
|
+
`(${emitNode(hole.node, used, templates)})), ` +
|
|
188
|
+
`${hole.endRef}, holeContent(${hole.startRef}, ${hole.endRef}));`);
|
|
189
|
+
}
|
|
190
|
+
lines.push('return _el$;');
|
|
191
|
+
return `(() => { ${lines.join(' ')} })()`;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
116
194
|
used.add('createNativeElement');
|
|
117
195
|
const tag = JSON.stringify(node.tag);
|
|
118
196
|
const el = '_el$';
|
|
@@ -120,9 +198,19 @@ function emitNode(node, used) {
|
|
|
120
198
|
const createArgs = node.svg ? `${tag}, true` : tag;
|
|
121
199
|
parts.push(`const ${el} = createNativeElement(${createArgs});`);
|
|
122
200
|
if (node.props.length > 0) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
201
|
+
// Literal attributes are written straight on. `spread` is a generic helper that
|
|
202
|
+
// walks every prop checking for reactivity, events, refs, class/style objects and
|
|
203
|
+
// namespaces — none of which a compile-time constant needs. Same predicate the
|
|
204
|
+
// template serializer uses, so the two agree on what a plain attribute is.
|
|
205
|
+
if (!node.svg && node.props.every(isPlainLiteralAttr)) {
|
|
206
|
+
for (const p of node.props)
|
|
207
|
+
parts.push(staticAttrAssignment(el, p));
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
used.add('spread');
|
|
211
|
+
const svgFlag = node.svg ? ', isSVG: true' : '';
|
|
212
|
+
parts.push(`spread({ element: ${el}, props: ${emitProps(node.props, null, used)}${svgFlag} });`);
|
|
213
|
+
}
|
|
126
214
|
}
|
|
127
215
|
// Insert each child individually (like the jsx runtime's applyProps), so a
|
|
128
216
|
// reactive/component child that isn't the only child still gets its own
|
|
@@ -130,7 +218,7 @@ function emitNode(node, used) {
|
|
|
130
218
|
// elements sitting inside the array.
|
|
131
219
|
for (const child of node.children) {
|
|
132
220
|
used.add('insert');
|
|
133
|
-
const childCode = emitNode(child, used);
|
|
221
|
+
const childCode = emitNode(child, used, templates);
|
|
134
222
|
const isFn = (child.kind === 'expr' && child.reactive) ||
|
|
135
223
|
child.kind === 'component' ||
|
|
136
224
|
child.kind === 'control';
|
|
@@ -141,12 +229,35 @@ function emitNode(node, used) {
|
|
|
141
229
|
}
|
|
142
230
|
}
|
|
143
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* Substitute template declarations into the code as inline `createTemplate` calls.
|
|
234
|
+
*
|
|
235
|
+
* For hosts that cannot hoist — nested JSX lowered inside an expression, where there is
|
|
236
|
+
* no module scope to reach. `createTemplate` caches by HTML string, so this costs a Map
|
|
237
|
+
* lookup per instantiation rather than a re-parse, and is still far cheaper than
|
|
238
|
+
* building the subtree element by element.
|
|
239
|
+
*/
|
|
240
|
+
export function inlineTemplates(code, templates) {
|
|
241
|
+
if (!templates || templates.length === 0)
|
|
242
|
+
return code;
|
|
243
|
+
const byId = new Map(templates.map((t) => [t.id, JSON.stringify(t.html)]));
|
|
244
|
+
// Single pass, for the same reason `adoptTemplates` needs one.
|
|
245
|
+
return code.replace(/_tmpl\$\d+/g, (id) => byId.get(id) ?? id);
|
|
246
|
+
}
|
|
144
247
|
export const imperativeBackend = {
|
|
145
248
|
name: 'imperative',
|
|
146
249
|
contract: RUNTIME_CONTRACT_V1,
|
|
147
|
-
emit(node,
|
|
250
|
+
emit(node, options) {
|
|
148
251
|
const used = new Set();
|
|
149
|
-
|
|
150
|
-
|
|
252
|
+
// Off by default: `createTemplate` builds real DOM nodes, so on the server they
|
|
253
|
+
// land in a ServerElement tree and clash, and during hydration a clone creates a
|
|
254
|
+
// fresh node where the existing one must be adopted. Both need runtime support
|
|
255
|
+
// that does not exist yet, so the client-only win stays opt-in until it does.
|
|
256
|
+
const templates = options?.templateClone !== false
|
|
257
|
+
? []
|
|
258
|
+
: undefined;
|
|
259
|
+
partial = options?.partialTemplates === true;
|
|
260
|
+
const code = emitNode(node, used, templates);
|
|
261
|
+
return { code, imports: Array.from(used), templates };
|
|
151
262
|
},
|
|
152
263
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var l={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},
|
|
1
|
+
var j=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),E={className:"class",htmlFor:"for"},M=new Set(["innerHTML","outerHTML","innerText","textContent","value","checked","selected","muted","defaultValue","defaultChecked","children","ref"]),L=new Set(["script","style","textarea","title"]);function $(e){return L.has(e)}function k(e){return E[e]??e}function p(e){return e.kind!=="attr"||e.expr!==void 0||e.name.includes(":")?!1:!M.has(e.name)}function R(e){if(!e.static||$(e.tag))return!1;for(let t of e.props)if(!p(t))return!1;for(let t of e.children)if(t.kind!=="text"&&!(t.kind==="element"&&R(t)))return!1;return!0}function m(e){let t=e.props.map(J).filter(Boolean).join(""),r=`<${e.tag}${t}>`;return j.has(e.tag)?r:`${r}${e.children.map(z).join("")}</${e.tag}>`}function z(e){if(e.kind==="text")return V(e.value);if(e.kind!=="element")throw new Error(`serializeStatic: unexpected ${e.kind}`);return m(e)}function J(e){let t=E[e.name]??e.name,r=e.literal;return r===!0||r===void 0?` ${t}`:r===!1||r===null?"":` ${t}="${H(String(r))}"`}function H(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function V(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}var B="<!--fx-->",F="<!--fx/-->";function h(e){return e.kind==="expr"||e.kind==="component"||e.kind==="control"}function W(e){return e.kind==="text"||e.kind==="element"&&y(e)}function y(e){return e.svg||$(e.tag)||!e.props.every(t=>p(t))?!1:e.children.every(t=>W(t)||h(t))}function d(e){if(h(e))return!0;let t=e.children;return t?t.some(d):!1}function v(e){for(let t=0;t<e.children.length;t++){let r=e.children[t];if(r.kind==="text"&&(r.value===""||e.children[t+1]?.kind==="text"))return!1}return e.children.every(t=>t.kind!=="element"||v(t))}function C(e){if(!y(e)||!v(e)||!e.children.some(d))return null;let t=[],r=[],i=0,l=f=>{let n=`_n$${i++}`;return t.push({ref:n,expr:f}),n};return s(e,"_el$"),{html:D(e),tag:e.tag,steps:t,holes:r};function s(f,n){let c=-1;f.children.forEach((a,u)=>{d(a)&&(c=u)});let o=null;for(let a=0;a<=c;a++){let u=f.children[a],N=o?`${o}.nextSibling`:`${n}.firstChild`;if(h(u)){let I=l(N),T=l(`holeEnd(${I})`);r.push({parentRef:n,startRef:I,endRef:T,node:u}),o=T;continue}let S=l(N);u.kind==="element"&&d(u)&&s(u,S),o=S}}}function D(e){return m(b(e)).split(P).join(B+F)}function b(e){return{...e,children:e.children.map(t=>h(t)?{kind:"text",value:P}:t.kind==="element"?b(t):t)}}var P="\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"]},te={version:2,module:"@fluixi/dom",symbols:[...x.symbols,"template","cloneTemplate","walk"]};var U={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function Y(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function _(e){return Y(e)?e:JSON.stringify(e)}function Z(e){return e.expr!==void 0?e.reactive?`() => (${e.expr})`:`(${e.expr})`:JSON.stringify(e.literal??!0)}function q(e){return e.expr!==void 0?`(${e.expr})`:JSON.stringify(e.literal??!0)}function G(e,t,r){let i=e.filter(n=>n.kind==="spread"),s=e.filter(n=>n.kind!=="spread").map(n=>`${_(n.name)}: ${Z(n)}`);t!=null&&s.push(`children: ${t}`);let f=`{ ${s.join(", ")} }`;return i.length>0?(r.add("mergeProps"),`mergeProps(${i.map(n=>n.expr).join(", ")}, ${f})`):f}function A(e,t,r){return e.length===1?g(e[0],t,r):`[${e.map(i=>g(i,t,r)).join(", ")}]`}function O(e,t,r,i,l){i.add("createMemo"),i.add("createComponent");let s=t.filter(o=>o.kind==="spread"),n=t.filter(o=>o.kind!=="spread").map(o=>`get ${_(o.name)}() { return ${q(o)}; }`);r.length>0&&n.push(`get children() { return ${A(r,i,l)}; }`);let c=`{ ${n.join(", ")} }`;return s.length>0&&(i.add("mergeProps"),c=`mergeProps(${s.map(o=>o.expr).join(", ")}, ${c})`),`createMemo(() => createComponent(${e}, ${c}))`}function K(e,t){let r=k(t.name),i=t.literal;return i===!0||i===void 0?`${e}.setAttribute(${JSON.stringify(r)}, "");`:i===!1||i===null?"":`${e}.setAttribute(${JSON.stringify(r)}, ${JSON.stringify(String(i))});`}var w=!1;function g(e,t,r){switch(e.kind){case"text":return JSON.stringify(e.value);case"expr":return e.reactive?`() => (${e.code})`:`(${e.code})`;case"fragment":return e.children.length===0?"null":A(e.children,t,r);case"component":return O(e.name,e.props,e.children,t,r);case"control":{let i=U[e.control]??e.control;return t.add(i),O(i,e.props,e.children,t,r)}case"element":{if(r&&e.static&&!e.svg&&R(e)){t.add("templateNode");let n=`_tmpl$${r.length}`;return r.push({id:n,html:m(e),tag:e.tag,svg:!1}),`templateNode(${n}, ${JSON.stringify(e.tag)})`}if(r&&w){let n=C(e);if(n){t.add("templateNode"),t.add("insert"),t.add("holeEnd"),t.add("holeContent"),t.add("holeScope");let c=`_tmpl$${r.length}`;r.push({id:c,html:n.html,tag:n.tag,svg:!1});let o=[`const _el$ = templateNode(${c}, ${JSON.stringify(n.tag)}, true);`];for(let a of n.steps)o.push(`const ${a.ref} = ${a.expr};`);for(let a of n.holes)o.push(`insert(${a.parentRef}, holeScope(${a.startRef}, () => (${g(a.node,t,r)})), ${a.endRef}, holeContent(${a.startRef}, ${a.endRef}));`);return o.push("return _el$;"),`(() => { ${o.join(" ")} })()`}}t.add("createNativeElement");let i=JSON.stringify(e.tag),l="_el$",s=[],f=e.svg?`${i}, true`:i;if(s.push(`const ${l} = createNativeElement(${f});`),e.props.length>0)if(!e.svg&&e.props.every(p))for(let n of e.props)s.push(K(l,n));else{t.add("spread");let n=e.svg?", isSVG: true":"";s.push(`spread({ element: ${l}, props: ${G(e.props,null,t)}${n} });`)}for(let n of e.children){t.add("insert");let c=g(n,t,r),o=n.kind==="expr"&&n.reactive||n.kind==="component"||n.kind==="control";s.push(o?`insert(${l}, ${c}, null);`:`insert(${l}, ${c});`)}return s.push(`return ${l};`),`(() => { ${s.join(" ")} })()`}}}function se(e,t){if(!t||t.length===0)return e;let r=new Map(t.map(i=>[i.id,JSON.stringify(i.html)]));return e.replace(/_tmpl\$\d+/g,i=>r.get(i)??i)}var ae={name:"imperative",contract:x,emit(e,t){let r=new Set,i=t?.templateClone!==!1?[]:void 0;return w=t?.partialTemplates===!0,{code:g(e,r,i),imports:Array.from(r),templates:i}}};export{ae as imperativeBackend,se as inlineTemplates};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var p=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames;var w=Object.prototype.hasOwnProperty;var H=(e,t)=>{for(var n in t)p(e,n,{get:t[n],enumerable:!0})},_=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of L(t))!w.call(e,r)&&r!==n&&p(e,r,{get:()=>t[r],enumerable:!(s=v(t,r))||s.enumerable});return e};var z=e=>_(p({},"__esModule",{value:!0}),e);var B={};H(B,{HOLE_END:()=>N,HOLE_START:()=>T,planPartialTemplate:()=>Y});module.exports=z(B);var A=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),M={className:"class",htmlFor:"for"},y=new Set(["innerHTML","outerHTML","innerText","textContent","value","checked","selected","muted","defaultValue","defaultChecked","children","ref"]),C=new Set(["script","style","textarea","title"]);function I(e){return C.has(e)}function k(e){return e.kind!=="attr"||e.expr!==void 0||e.name.includes(":")?!1:!y.has(e.name)}function m(e){let t=e.props.map(O).filter(Boolean).join(""),n=`<${e.tag}${t}>`;return A.has(e.tag)?n:`${n}${e.children.map(j).join("")}</${e.tag}>`}function j(e){if(e.kind==="text")return D(e.value);if(e.kind!=="element")throw new Error(`serializeStatic: unexpected ${e.kind}`);return m(e)}function O(e){let t=M[e.name]??e.name,n=e.literal;return n===!0||n===void 0?` ${t}`:n===!1||n===null?"":` ${t}="${W(String(n))}"`}function W(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function D(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}var T="<!--fx-->",N="<!--fx/-->";function c(e){return e.kind==="expr"||e.kind==="component"||e.kind==="control"}function V(e){return e.kind==="text"||e.kind==="element"&&S(e)}function S(e){return e.svg||I(e.tag)||!e.props.every(t=>k(t))?!1:e.children.every(t=>V(t)||c(t))}function u(e){if(c(e))return!0;let t=e.children;return t?t.some(u):!1}function b(e){for(let t=0;t<e.children.length;t++){let n=e.children[t];if(n.kind==="text"&&(n.value===""||e.children[t+1]?.kind==="text"))return!1}return e.children.every(t=>t.kind!=="element"||b(t))}function Y(e){if(!S(e)||!b(e)||!e.children.some(u))return null;let t=[],n=[],s=0,r=o=>{let l=`_n$${s++}`;return t.push({ref:l,expr:o}),l};return d(e,"_el$"),{html:q(e),tag:e.tag,steps:t,holes:n};function d(o,l){let g=-1;o.children.forEach((a,i)=>{u(a)&&(g=i)});let f=null;for(let a=0;a<=g;a++){let i=o.children[a],R=f?`${f}.nextSibling`:`${l}.firstChild`;if(c(i)){let x=r(R),E=r(`holeEnd(${x})`);n.push({parentRef:l,startRef:x,endRef:E,node:i}),f=E;continue}let h=r(R);i.kind==="element"&&u(i)&&d(i,h),f=h}}}function q(e){return m($(e)).split(P).join(T+N)}function $(e){return{...e,children:e.children.map(t=>c(t)?{kind:"text",value:P}:t.kind==="element"?$(t):t)}}var P="\0fx-hole\0";
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cloning a subtree whose *structure* is static but which contains dynamic holes.
|
|
3
|
+
*
|
|
4
|
+
* The fully-static case is easy: serialize, clone, done. The common case is not static —
|
|
5
|
+
* a card wrapper with one reactive value inside — and a single hole used to send the
|
|
6
|
+
* whole subtree back to being built an element at a time. This plans the middle ground:
|
|
7
|
+
* the structure becomes one template, and each hole is filled through a reference into
|
|
8
|
+
* the cloned tree.
|
|
9
|
+
*
|
|
10
|
+
* Three things make it correct in all three environments — fresh client render, server
|
|
11
|
+
* render, and hydration:
|
|
12
|
+
*
|
|
13
|
+
* - **Each hole is bracketed by a marker pair.** A hole's content is then, by
|
|
14
|
+
* definition, the nodes between its own two markers. That is what lets hydration
|
|
15
|
+
* *adopt* what the server rendered rather than rebuild it, with no dependence on where
|
|
16
|
+
* a hydration cursor happens to be.
|
|
17
|
+
* - **The walk is sequential, not positional.** Index arithmetic against the template
|
|
18
|
+
* only describes a fresh clone: the server's DOM has the rendered content sitting
|
|
19
|
+
* between the markers, so every position after a hole is shifted. Each node is reached
|
|
20
|
+
* from the previous sibling instead, and a hole's end marker is found at runtime.
|
|
21
|
+
* - **Every reference is read before any insertion**, since inserting shifts what
|
|
22
|
+
* follows.
|
|
23
|
+
*/
|
|
24
|
+
import type { IRElement, IRNode } from '../ir/nodes.js';
|
|
25
|
+
/**
|
|
26
|
+
* The comments bracketing a hole.
|
|
27
|
+
*
|
|
28
|
+
* Named rather than anonymous so they are recognisable in devtools and in a page's
|
|
29
|
+
* source — an unexplained `<!---->` is a support question.
|
|
30
|
+
*/
|
|
31
|
+
export declare const HOLE_START = "<!--fx-->";
|
|
32
|
+
export declare const HOLE_END = "<!--fx/-->";
|
|
33
|
+
/** `const <ref> = <expr>;`, emitted before any insertion happens. */
|
|
34
|
+
export interface WalkStep {
|
|
35
|
+
ref: string;
|
|
36
|
+
expr: string;
|
|
37
|
+
}
|
|
38
|
+
/** A dynamic child, and the markers its content lives between. */
|
|
39
|
+
export interface TemplateHole {
|
|
40
|
+
/** Reference to the hole's parent element. */
|
|
41
|
+
parentRef: string;
|
|
42
|
+
/** Reference to the opening marker. */
|
|
43
|
+
startRef: string;
|
|
44
|
+
/** Reference to the closing marker, resolved at runtime by scanning from the start. */
|
|
45
|
+
endRef: string;
|
|
46
|
+
node: IRNode;
|
|
47
|
+
}
|
|
48
|
+
export interface PartialTemplate {
|
|
49
|
+
html: string;
|
|
50
|
+
tag: string;
|
|
51
|
+
/** Declarations to emit in order, before the inserts. */
|
|
52
|
+
steps: WalkStep[];
|
|
53
|
+
holes: TemplateHole[];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Plan a partial template for `root`, or null when it does not qualify.
|
|
57
|
+
*
|
|
58
|
+
* Returns null for a subtree with no holes: that is the fully-static case, which has a
|
|
59
|
+
* cheaper path of its own and must not be routed through this one.
|
|
60
|
+
*/
|
|
61
|
+
export declare function planPartialTemplate(root: IRElement): PartialTemplate | null;
|
|
62
|
+
//# sourceMappingURL=partial-template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partial-template.d.ts","sourceRoot":"","sources":["../../src/codegen/partial-template.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,EAAU,MAAM,gBAAgB,CAAC;AAGhE;;;;;GAKG;AACH,eAAO,MAAM,UAAU,cAAc,CAAC;AACtC,eAAO,MAAM,QAAQ,eAAe,CAAC;AAErC,qEAAqE;AACrE,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,yDAAyD;IACzD,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAkDD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,GAAG,eAAe,GAAG,IAAI,CA8C3E"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var b=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),$={className:"class",htmlFor:"for"},P=new Set(["innerHTML","outerHTML","innerText","textContent","value","checked","selected","muted","defaultValue","defaultChecked","children","ref"]),v=new Set(["script","style","textarea","title"]);function x(e){return v.has(e)}function E(e){return e.kind!=="attr"||e.expr!==void 0||e.name.includes(":")?!1:!P.has(e.name)}function c(e){let t=e.props.map(w).filter(Boolean).join(""),n=`<${e.tag}${t}>`;return b.has(e.tag)?n:`${n}${e.children.map(L).join("")}</${e.tag}>`}function L(e){if(e.kind==="text")return _(e.value);if(e.kind!=="element")throw new Error(`serializeStatic: unexpected ${e.kind}`);return c(e)}function w(e){let t=$[e.name]??e.name,n=e.literal;return n===!0||n===void 0?` ${t}`:n===!1||n===null?"":` ${t}="${H(String(n))}"`}function H(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function _(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}var z="<!--fx-->",A="<!--fx/-->";function f(e){return e.kind==="expr"||e.kind==="component"||e.kind==="control"}function M(e){return e.kind==="text"||e.kind==="element"&&I(e)}function I(e){return e.svg||x(e.tag)||!e.props.every(t=>E(t))?!1:e.children.every(t=>M(t)||f(t))}function o(e){if(f(e))return!0;let t=e.children;return t?t.some(o):!1}function k(e){for(let t=0;t<e.children.length;t++){let n=e.children[t];if(n.kind==="text"&&(n.value===""||e.children[t+1]?.kind==="text"))return!1}return e.children.every(t=>t.kind!=="element"||k(t))}function O(e){if(!I(e)||!k(e)||!e.children.some(o))return null;let t=[],n=[],S=0,u=a=>{let i=`_n$${S++}`;return t.push({ref:i,expr:a}),i};return p(e,"_el$"),{html:y(e),tag:e.tag,steps:t,holes:n};function p(a,i){let m=-1;a.children.forEach((l,r)=>{o(l)&&(m=r)});let s=null;for(let l=0;l<=m;l++){let r=a.children[l],d=s?`${s}.nextSibling`:`${i}.firstChild`;if(f(r)){let R=u(d),h=u(`holeEnd(${R})`);n.push({parentRef:i,startRef:R,endRef:h,node:r}),s=h;continue}let g=u(d);r.kind==="element"&&o(r)&&p(r,g),s=g}}}function y(e){return c(T(e)).split(N).join(z+A)}function T(e){return{...e,children:e.children.map(t=>f(t)?{kind:"text",value:N}:t.kind==="element"?T(t):t)}}var N="\0fx-hole\0";export{A as HOLE_END,z as HOLE_START,O as planPartialTemplate};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var i=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var m=(e,t)=>{for(var r in t)i(e,r,{get:t[r],enumerable:!0})},d=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of g(t))!p.call(e,n)&&n!==r&&i(e,n,{get:()=>t[n],enumerable:!(a=f(t,n))||a.enumerable});return e};var x=e=>d(i({},"__esModule",{value:!0}),e);var b={};m(b,{htmlAttrName:()=>h,isPlainLiteralAttr:()=>o,isRawTextElement:()=>l,isSerializable:()=>u,serializeStatic:()=>c});module.exports=x(b);var E=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]),s={className:"class",htmlFor:"for"},R=new Set(["innerHTML","outerHTML","innerText","textContent","value","checked","selected","muted","defaultValue","defaultChecked","children","ref"]),T=new Set(["script","style","textarea","title"]);function l(e){return T.has(e)}function h(e){return s[e]??e}function o(e){return e.kind!=="attr"||e.expr!==void 0||e.name.includes(":")?!1:!R.has(e.name)}function u(e){if(!e.static||l(e.tag))return!1;for(let t of e.props)if(!o(t))return!1;for(let t of e.children)if(t.kind!=="text"&&!(t.kind==="element"&&u(t)))return!1;return!0}function c(e){let t=e.props.map(I).filter(Boolean).join(""),r=`<${e.tag}${t}>`;return E.has(e.tag)?r:`${r}${e.children.map(k).join("")}</${e.tag}>`}function k(e){if(e.kind==="text")return $(e.value);if(e.kind!=="element")throw new Error(`serializeStatic: unexpected ${e.kind}`);return c(e)}function I(e){let t=s[e.name]??e.name,r=e.literal;return r===!0||r===void 0?` ${t}`:r===!1||r===null?"":` ${t}="${S(String(r))}"`}function S(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">")}function $(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize a static IR subtree to the HTML a `<template>` can be built from.
|
|
3
|
+
*
|
|
4
|
+
* Only called for nodes `analyzeStatic` marked static, so every prop is a literal and
|
|
5
|
+
* every child is text or another static element — there is nothing here that could need
|
|
6
|
+
* an expression. That invariant is what makes this safe: the serializer never has to
|
|
7
|
+
* guess, and anything it cannot represent is a bug in the analysis, not a fallback.
|
|
8
|
+
*/
|
|
9
|
+
import type { IRElement, IRProp } from '../ir/nodes.js';
|
|
10
|
+
/** True when this element's content must not be entity-escaped. */
|
|
11
|
+
export declare function isRawTextElement(tag: string): boolean;
|
|
12
|
+
/** The HTML spelling of an IR prop name. */
|
|
13
|
+
export declare function htmlAttrName(name: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* True for a prop that is a plain HTML attribute with a compile-time constant value —
|
|
16
|
+
* safe to write straight onto the element, with no runtime interpretation.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isPlainLiteralAttr(prop: IRProp): boolean;
|
|
19
|
+
/** True when the subtree can be represented as HTML text with no loss. */
|
|
20
|
+
export declare function isSerializable(node: IRElement): boolean;
|
|
21
|
+
/** The subtree as HTML. */
|
|
22
|
+
export declare function serializeStatic(node: IRElement): string;
|
|
23
|
+
//# sourceMappingURL=serialize-static.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialize-static.d.ts","sourceRoot":"","sources":["../../src/codegen/serialize-static.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,SAAS,EAAU,MAAM,EAAE,MAAM,gBAAgB,CAAC;AA6DhE,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,4CAA4C;AAC5C,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAKxD;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAgBvD;AAED,2BAA2B;AAC3B,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAKvD"}
|