@fluixi/compiler 1.0.0-alpha.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +76 -0
  3. package/dist/babel-OGRQKOZA.mjs +2 -0
  4. package/dist/chunk-3SAEGOMQ.mjs +1 -0
  5. package/dist/codegen/backend.cjs +1 -0
  6. package/dist/codegen/backend.d.ts +22 -0
  7. package/dist/codegen/backend.d.ts.map +1 -0
  8. package/dist/codegen/backend.js +1 -0
  9. package/dist/codegen/backend.mjs +0 -0
  10. package/dist/codegen/backends/imperative.cjs +1 -0
  11. package/dist/codegen/backends/imperative.d.ts +3 -0
  12. package/dist/codegen/backends/imperative.d.ts.map +1 -0
  13. package/dist/codegen/backends/imperative.js +152 -0
  14. package/dist/codegen/backends/imperative.mjs +1 -0
  15. package/dist/codegen/contract.cjs +1 -0
  16. package/dist/codegen/contract.d.ts +25 -0
  17. package/dist/codegen/contract.d.ts.map +1 -0
  18. package/dist/codegen/contract.js +30 -0
  19. package/dist/codegen/contract.mjs +1 -0
  20. package/dist/frontend/babel/build-ir.cjs +1 -0
  21. package/dist/frontend/babel/build-ir.d.ts +23 -0
  22. package/dist/frontend/babel/build-ir.d.ts.map +1 -0
  23. package/dist/frontend/babel/build-ir.js +224 -0
  24. package/dist/frontend/babel/build-ir.mjs +1 -0
  25. package/dist/frontend/babel/index.cjs +2 -0
  26. package/dist/frontend/babel/index.d.ts +34 -0
  27. package/dist/frontend/babel/index.d.ts.map +1 -0
  28. package/dist/frontend/babel/index.js +65 -0
  29. package/dist/frontend/babel/index.mjs +2 -0
  30. package/dist/frontend/babel/plugin.cjs +2 -0
  31. package/dist/frontend/babel/plugin.d.ts +122 -0
  32. package/dist/frontend/babel/plugin.d.ts.map +1 -0
  33. package/dist/frontend/babel/plugin.js +1509 -0
  34. package/dist/frontend/babel/plugin.mjs +2 -0
  35. package/dist/frontend/babel/server-functions.cjs +1 -0
  36. package/dist/frontend/babel/server-functions.d.ts +11 -0
  37. package/dist/frontend/babel/server-functions.d.ts.map +1 -0
  38. package/dist/frontend/babel/server-functions.js +88 -0
  39. package/dist/frontend/babel/server-functions.mjs +1 -0
  40. package/dist/frontend/babel/types.cjs +1 -0
  41. package/dist/frontend/babel/types.d.ts +34 -0
  42. package/dist/frontend/babel/types.d.ts.map +1 -0
  43. package/dist/frontend/babel/types.js +1 -0
  44. package/dist/frontend/babel/types.mjs +0 -0
  45. package/dist/frontend/types.cjs +1 -0
  46. package/dist/frontend/types.d.ts +26 -0
  47. package/dist/frontend/types.d.ts.map +1 -0
  48. package/dist/frontend/types.js +1 -0
  49. package/dist/frontend/types.mjs +0 -0
  50. package/dist/index.cjs +1 -0
  51. package/dist/index.d.ts +19 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +20 -0
  54. package/dist/index.mjs +1 -0
  55. package/dist/integrations.cjs +12 -0
  56. package/dist/integrations.d.ts +251 -0
  57. package/dist/integrations.d.ts.map +1 -0
  58. package/dist/integrations.js +790 -0
  59. package/dist/integrations.mjs +11 -0
  60. package/dist/ir/nodes.cjs +1 -0
  61. package/dist/ir/nodes.d.ts +80 -0
  62. package/dist/ir/nodes.d.ts.map +1 -0
  63. package/dist/ir/nodes.js +1 -0
  64. package/dist/ir/nodes.mjs +0 -0
  65. package/dist/options.cjs +1 -0
  66. package/dist/options.d.ts +18 -0
  67. package/dist/options.d.ts.map +1 -0
  68. package/dist/options.js +9 -0
  69. package/dist/options.mjs +1 -0
  70. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  71. package/package.json +70 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fluixi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/fluixi/assets/main/logos/128x128.png" alt="Fluixi" width="120" height="120" />
3
+ </p>
4
+
5
+ # @fluixi/compiler
6
+
7
+ **The Fluixi JSX compiler — host-agnostic IR + pluggable codegen backends.**
8
+
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-22c55e.svg)](./LICENSE)
10
+ ![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6?logo=typescript&logoColor=white)
11
+ ![Registry](https://img.shields.io/badge/registry-GitHub%20Packages-181717?logo=github)
12
+
13
+ ---
14
+
15
+ ## ✨ Overview
16
+
17
+ `@fluixi/compiler` turns Fluixi JSX into fine-grained reactive output. A **Babel
18
+ front-end** parses source into a host-agnostic IR; a **codegen backend** emits the result:
19
+
20
+ - **`imperative`** (default) — compiles straight into [`@fluixi/dom`](../dom) runtime
21
+ calls (`createNativeElement`/`spread`/`insert`/`createComponent`/…). No VDOM.
22
+ - **`jsx`** — emits the automatic runtime `jsx()`/`jsxs()` (the [`@fluixi/jsx`](../jsx)
23
+ runtime).
24
+
25
+ It also provides the **`"use server"`** transform (server functions): the client build
26
+ gets an RPC stub, the server build keeps and registers the body.
27
+
28
+ Most apps don't use this package directly — [`@fluixi/vite-plugin`](../vite-plugin) (and
29
+ [`@fluixi/start`](../start)) wrap it.
30
+
31
+ ## 📦 Installation
32
+
33
+ ```ini
34
+ # .npmrc
35
+ @fluixi:registry=https://npm.pkg.github.com
36
+ //npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN}
37
+ ```
38
+
39
+ ```sh
40
+ pnpm add -D @fluixi/compiler
41
+ ```
42
+
43
+ ## 🚀 Usage
44
+
45
+ Via the Vite integration (the common path):
46
+
47
+ ```ts
48
+ import { defineConfig } from 'vite';
49
+ import { createVitePlugin, serverFunctionsVitePlugin } from '@fluixi/compiler/integrations';
50
+
51
+ export default defineConfig({
52
+ plugins: [
53
+ serverFunctionsVitePlugin(), // "use server" transform
54
+ createVitePlugin({ backend: 'imperative' }),
55
+ ],
56
+ });
57
+ ```
58
+
59
+ Or transform a string directly:
60
+
61
+ ```ts
62
+ import { transform } from '@fluixi/compiler';
63
+ const { code } = transform(source, { backend: 'imperative' });
64
+ ```
65
+
66
+ ## 🔌 Subpaths
67
+
68
+ | Import | What |
69
+ | --- | --- |
70
+ | `@fluixi/compiler` | `transform()` + the compile pipeline |
71
+ | `@fluixi/compiler/integrations` | `createVitePlugin`, `serverFunctionsVitePlugin`, webpack/rollup/esbuild adapters |
72
+ | `@fluixi/compiler/babel` | the Babel plugin front-end |
73
+
74
+ ## 📄 License
75
+
76
+ [MIT](./LICENSE) © [Fluixi](https://fluixi.dev)
@@ -0,0 +1,2 @@
1
+ import"./chunk-3SAEGOMQ.mjs";import{declare as Ae}from"@babel/helper-plugin-utils";import{types as e,template as Re}from"@babel/core";import{types as u,traverse as Je,template as Ce}from"@babel/core";import Y from"@babel/generator";var B={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},tt={version:2,module:"@fluixi/dom",symbols:[...B.symbols,"template","cloneTemplate","walk"]};var xe={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function Se(t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)}function K(t){return Se(t)?t:JSON.stringify(t)}function he(t){return t.expr!==void 0?t.reactive?`() => (${t.expr})`:`(${t.expr})`:JSON.stringify(t.literal??!0)}function be(t){return t.expr!==void 0?`(${t.expr})`:JSON.stringify(t.literal??!0)}function ye(t,n,r){let i=t.filter(l=>l.kind==="spread"),o=t.filter(l=>l.kind!=="spread").map(l=>`${K(l.name)}: ${he(l)}`);n!=null&&o.push(`children: ${n}`);let a=`{ ${o.join(", ")} }`;return i.length>0?(r.add("mergeProps"),`mergeProps(${i.map(l=>l.expr).join(", ")}, ${a})`):a}function Q(t,n){return t.length===1?$(t[0],n):`[${t.map(r=>$(r,n)).join(", ")}]`}function U(t,n,r,i){i.add("createMemo"),i.add("createComponent");let s=n.filter(p=>p.kind==="spread"),a=n.filter(p=>p.kind!=="spread").map(p=>`get ${K(p.name)}() { return ${be(p)}; }`);r.length>0&&a.push(`get children() { return ${Q(r,i)}; }`);let l=`{ ${a.join(", ")} }`;return s.length>0&&(i.add("mergeProps"),l=`mergeProps(${s.map(p=>p.expr).join(", ")}, ${l})`),`createMemo(() => createComponent(${t}, ${l}))`}function $(t,n){switch(t.kind){case"text":return JSON.stringify(t.value);case"expr":return t.reactive?`() => (${t.code})`:`(${t.code})`;case"fragment":return t.children.length===0?"null":Q(t.children,n);case"component":return U(t.name,t.props,t.children,n);case"control":{let r=xe[t.control]??t.control;return n.add(r),U(r,t.props,t.children,n)}case"element":{n.add("createNativeElement");let r=JSON.stringify(t.tag),i="_el$",s=[],o=t.svg?`${r}, true`:r;if(s.push(`const ${i} = createNativeElement(${o});`),t.props.length>0){n.add("spread");let a=t.svg?", isSVG: true":"";s.push(`spread({ element: ${i}, props: ${ye(t.props,null,n)}${a} });`)}for(let a of t.children){n.add("insert");let l=$(a,n),p=a.kind==="expr"&&a.reactive||a.kind==="component"||a.kind==="control";s.push(p?`insert(${i}, ${l}, null);`:`insert(${i}, ${l});`)}return s.push(`return ${i};`),`(() => { ${s.join(" ")} })()`}}}var D={name:"imperative",contract:B,emit(t,n){let r=new Set;return{code:$(t,r),imports:Array.from(r)}}};var Xe=Y.default??Y;function te(t){return Xe(t,{concise:!0}).code}function ve(t,n){let r=u.cloneNode(t,!0),i=u.file(u.program([u.expressionStatement(r)])),s=!1;return Je(i,{"JSXElement|JSXFragment"(o){let a=o.node,{code:l,imports:p}=D.emit(A(a,n),{});for(let b of p)n.add(b);let g=Ce.expression(l,{placeholderPattern:!1})();o.replaceWith(g),o.skip(),s=!0}}),s?i.program.body[0].expression:t}function V(t,n){return te(ve(t,n))}var we=new Set(["svg","path","circle","rect","line","polygon","polyline","ellipse","g","defs","clipPath","text"]),Fe=/^on[A-Z]/,je=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]);function Pe(t){if(u.isJSXIdentifier(t)){let n=t.name[0]!==t.name[0].toLowerCase();return{tag:t.name,component:n}}return u.isJSXMemberExpression(t)?{tag:te(t),component:!0}:u.isJSXNamespacedName(t)?{tag:`${t.namespace.name}:${t.name.name}`,component:!1}:{tag:"div",component:!1}}function Ie(t){return u.isJSXIdentifier(t)?t.name==="class"?"className":t.name:u.isJSXNamespacedName(t)?`${t.namespace.name}:${t.name.name}`:"unknown"}function F(t){return u.isCallExpression(t)||u.isOptionalCallExpression(t)?!0:u.isMemberExpression(t)||u.isOptionalMemberExpression(t)?!(!t.computed&&u.isIdentifier(t.property,{name:"children"})):u.isConditionalExpression(t)?F(t.test)||F(t.consequent)||F(t.alternate):u.isLogicalExpression(t)||u.isBinaryExpression(t)?F(t.left)||F(t.right):u.isTemplateLiteral(t)?t.expressions.some(n=>F(n)):!1}function Le(t,n){let r=Ie(t.name),i=Fe.test(r),o={name:r,kind:i?"event":"attr"};i&&(o.event={name:r.slice(2).toLowerCase(),delegated:je.has(r.slice(2).toLowerCase())});let a=t.value;if(a==null)return o.literal=!0,o;if(u.isStringLiteral(a))return o.literal=a.value,o;if(u.isJSXExpressionContainer(a)&&!u.isJSXEmptyExpression(a.expression)){let l=a.expression;return u.isStringLiteral(l)||u.isNumericLiteral(l)||u.isBooleanLiteral(l)?(o.literal=l.value,o):(o.expr=V(l,n),o.reactive=i?!1:F(l),(u.isJSXElement(l)||u.isJSXFragment(l))&&(o.jsxElement=!0),o)}return o.literal=!0,o}function Me(t,n){let r=[];for(let i of t)u.isJSXSpreadAttribute(i)?r.push({name:"",kind:"spread",expr:V(i.argument,n)}):u.isJSXAttribute(i)&&r.push(Le(i,n));return r}function Ne(t){let n=t.split(/\r\n|\n|\r/),r=0;for(let s=0;s<n.length;s++)/[^ \t]/.test(n[s])&&(r=s);let i="";for(let s=0;s<n.length;s++){let o=n[s].replace(/\t/g," ");s!==0&&(o=o.replace(/^ +/,"")),s!==n.length-1&&(o=o.replace(/ +$/,"")),o&&(s!==r&&(o+=" "),i+=o)}return i}function ee(t,n){let r=[];for(let i of t)if(u.isJSXText(i)){let s=Ne(i.value);s&&r.push({kind:"text",value:s})}else if(u.isJSXExpressionContainer(i)){if(!u.isJSXEmptyExpression(i.expression)){let s=i.expression;r.push({kind:"expr",code:V(s,n),reactive:F(s)})}}else u.isJSXElement(i)||u.isJSXFragment(i)?r.push(A(i,n)):u.isJSXSpreadChild(i)&&r.push({kind:"expr",code:V(i.expression,n),reactive:!1});return r}function A(t,n=new Set){if(u.isJSXFragment(t))return{kind:"fragment",children:ee(t.children,n)};let{tag:r,component:i}=Pe(t.openingElement.name),s=Me(t.openingElement.attributes,n),o=ee(t.children,n);return i?{kind:"component",name:r,props:s,children:o}:{kind:"element",tag:r,svg:we.has(r),props:s,children:o,static:!1}}var se=new Set(["Show","For","Index","Switch","Match","Portal","Dynamic","ErrorBoundary","Suspense"]),Oe={Show:"when",For:"each",Index:"each",Match:"when"};var oe=/^on[A-Z]/,ae=["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup","mouseover","mouseout","mouseenter","mouseleave"],O=Ae((t,n={})=>{t.assertVersion(7);let{runtime:r="automatic",importSource:i="@fluixi/jsx",pragma:s="jsx",pragmaFrag:o="Fragment",development:a=!1,detectReactivity:l=!0,useLitHTML:p=!0,hoistStatics:g=!0,delegateEvents:b=!0,delegatedEvents:m=ae,optimizeControlFlow:y=!0,sourceMaps:P=!0,signalModule:J="@fluixi/dom",controlFlowModule:w="@fluixi/dom",reactiveModule:L="@fluixi/reactive/signal",autoShowTransform:Z=!1,backend:X="imperative",codegen:M="inline"}=n,Ee={backend:X,codegen:M,irImports:new Set,libModule:"@fluixi/core",hasJSX:!1,hasReactivity:!1,hasLitHTML:!1,needsSignalImport:!1,needsControlFlowImport:!1,needsCreateMemo:!1,controlFlowComponents:new Set,delegatedEvents:new Set,staticElements:new Map,staticCounter:0};return{name:"@fluixi/babel-plugin-jsx",manipulateOptions(f,c){c.plugins.push("jsx","typescript")},pre(f){Object.assign(f,Ee)},visitor:{ImportDeclaration(f,c){f.node.source.value==="@fluixi/core/rx"&&(f.node.source=e.stringLiteral("@fluixi/reactive"))},Program:{enter(f,c){Object.assign(c,{hasJSX:!1,hasReactivity:!1,hasLitHTML:!1,needsSignalImport:!1,needsLitrxImport:!1,needsControlFlowImport:!1,needsCreateMemo:!1,controlFlowComponents:new Set,delegatedEvents:new Set,staticElements:new Map,autoShow:Z,staticCounter:0,libModule:"@fluixi/core",backend:X,codegen:M,irImports:new Set,needsCreateNativeElement:!1,needsInsert:!1,needsSpread:!1,needsCreateComponent:!1,needsMergeProps:!1})},exit(f,c){let d=[];if(c.hasJSX||(c.needsSignalImport&&d.push(e.importDeclaration([e.importSpecifier(e.identifier("signal"),e.identifier("signal"))],e.stringLiteral(J))),c.needsLitrxImport&&!f.scope.hasBinding("litrx")&&d.push(e.importDeclaration([e.importSpecifier(e.identifier("litrx"),e.identifier("litrx"))],e.stringLiteral(c.libModule)))),c.hasJSX){if(X==="imperative"&&M==="ir"){let x=new Set(["Show","For","Index","Switch","Match","Dynamic","ErrorBoundary","Portal","Suspense"]),S=new Set(["createMemo","createEffect","createRenderEffect","createRoot","createSignal","onCleanup","batch","untrack"]),E=Array.from(c.irImports),v=h=>e.importSpecifier(e.identifier(h),e.identifier(h)),I=h=>!f.scope.hasBinding(h),z=E.filter(h=>S.has(h)&&I(h)),T=E.filter(h=>!x.has(h)&&!S.has(h)&&I(h)),N=E.filter(h=>x.has(h)&&I(h));z.length>0&&d.push(e.importDeclaration(z.map(v),e.stringLiteral(L))),T.length>0&&d.push(e.importDeclaration(T.map(v),e.stringLiteral(J))),N.length>0&&d.push(e.importDeclaration(N.map(v),e.stringLiteral(w)))}else if(X==="imperative"){let S=[[!!c.needsCreateNativeElement,"createNativeElement"],[!!c.needsSpread,"spread"],[!!c.needsInsert,"insert"],[!!c.needsCreateComponent,"createComponent"],[!!c.needsMergeProps,"mergeProps"]].filter(([E,v])=>E&&!f.scope.hasBinding(v)).map(([,E])=>e.importSpecifier(e.identifier(E),e.identifier(E)));S.length>0&&d.push(e.importDeclaration(S,e.stringLiteral(J)))}else if(r==="automatic"){let x=[e.importSpecifier(e.identifier("jsx"),e.identifier("jsx")),e.importSpecifier(e.identifier("jsxs"),e.identifier("jsxs")),e.importSpecifier(e.identifier("Fragment"),e.identifier("Fragment"))];a&&x.push(e.importSpecifier(e.identifier("jsxDEV"),e.identifier("jsxDEV"))),c.needsMergeProps&&x.push(e.importSpecifier(e.identifier("mergeProps"),e.identifier("mergeProps"))),d.push(e.importDeclaration(x,e.stringLiteral(i)))}if(c.needsCreateMemo&&!f.scope.hasBinding("createMemo")&&d.push(e.importDeclaration([e.importSpecifier(e.identifier("createMemo"),e.identifier("createMemo"))],e.stringLiteral(X==="imperative"?L:c.libModule??"@fluixi/core"))),c.needsControlFlowImport&&c.controlFlowComponents.size>0){let x=Array.from(c.controlFlowComponents).filter(S=>!f.scope.hasBinding(S));if(x.length>0){let S=x.map(E=>e.importSpecifier(e.identifier(E),e.identifier(E)));d.push(e.importDeclaration(S,e.stringLiteral(w)))}}if(b&&c.delegatedEvents.size>0){d.push(e.importDeclaration([e.importSpecifier(e.identifier("delegateEvents"),e.identifier("delegateEvents"))],e.stringLiteral(X==="imperative"?J:"@fluixi/jsx")));let x=e.arrayExpression(Array.from(c.delegatedEvents).map(E=>e.stringLiteral(E))),S=e.expressionStatement(e.callExpression(e.identifier("delegateEvents"),[x]));f.node.body.unshift(S)}if(g&&c.staticElements.size>0){let x=[];c.staticElements.forEach((S,E)=>{x.push(e.variableDeclaration("const",[e.variableDeclarator(e.identifier(E),S)]))}),f.node.body.unshift(...x)}}d.length>0&&f.node.body.unshift(...d)}},JSXElement(f,c){if(c.hasJSX=!0,X==="imperative"&&M==="ir"){f.replaceWith(re(f.node,c));return}let d=f.node,x=d.openingElement;if(e.isJSXIdentifier(x.name)&&se.has(x.name.name)&&(c.controlFlowComponents.add(x.name.name),y)){let E=Qe(d,c);if(E){f.replaceWith(E);return}}if(g&&X!=="imperative"&&ge(d,c)){let E=Ke(d,c);if(E){f.replaceWith(E);return}}let S=ke(d,c,{runtime:r,pragma:s,development:a,detectReactivity:l,useLitHTML:p,autoShow:Z});f.replaceWith(S)},JSXFragment(f,c){if(c.hasJSX=!0,X==="imperative"&&M==="ir"){f.replaceWith(re(f.node,c));return}let d=_(f.node,c,{runtime:r,pragmaFrag:o,development:a});f.replaceWith(d)},CallExpression(f,c){if(!l)return;let d=f.node.callee;d.name,e.isIdentifier(d)&&(d.name==="createSignal"||d.name==="createStore"||d.name==="useContext"||d.name==="useLocation")&&(c.hasReactivity=!0)},JSXExpressionContainer(f){},TaggedTemplateExpression(f,c){let{tag:d,quasi:x}=f.node;f.get("quasi").get("expressions").forEach((S,E)=>{let v=S.node,I=x.quasis[E].value.raw;if(I.trim().endsWith("=")||I.match(/@[\w-]+$/))return;let T=!1,N=!1;if(e.isMemberExpression(v)){let h=v.property;e.isIdentifier(h)&&(h.name=h.name.replace("$",""),c.needsLitrxImport=!0,N=!0)}(T||N)&&S.replaceWith(e.callExpression(e.identifier("((window as any).Fluixi.litrx || litrx)"),[e.arrowFunctionExpression([],v)]))})}}}});function ke(t,n,r){let{runtime:i,pragma:s,development:o,autoShow:a=!0}=r;return i==="automatic"?k(t,n,o,a):Ve(t,n,s)}var Te=new Set(["svg","path","circle","rect","line","polygon","polyline","ellipse","g","defs","clipPath","text"]);function ne(t,n,r){return n.length>0?(r.needsMergeProps=!0,e.callExpression(e.identifier("mergeProps"),[...n,e.objectExpression(t)])):e.objectExpression(t)}function le(t){return t.length===1?t[0]:e.arrayExpression(t)}function $e(t,n,r,i,s,o){if(!n){let m=[...r];return s.length>0&&m.push(e.objectMethod("get",e.identifier("children"),[],e.blockStatement([e.returnStatement(le(s))]))),ce(t,ne(m,i,o),o)}let a=t.value,l=Te.has(a),p=e.identifier("_el$"),g=[];o.needsCreateNativeElement=!0;let b=[t];if(l&&b.push(e.booleanLiteral(!0)),g.push(e.variableDeclaration("const",[e.variableDeclarator(p,e.callExpression(e.identifier("createNativeElement"),b))])),r.length>0||i.length>0){o.needsSpread=!0;let m=[e.objectProperty(e.identifier("element"),p),e.objectProperty(e.identifier("props"),ne(r,i,o))];l&&m.push(e.objectProperty(e.identifier("isSVG"),e.booleanLiteral(!0))),g.push(e.expressionStatement(e.callExpression(e.identifier("spread"),[e.objectExpression(m)])))}if(s.length>0){o.needsInsert=!0;for(let m of s){let P=e.isArrowFunctionExpression(m)||e.isFunctionExpression(m)||e.isCallExpression(m)&&e.isIdentifier(m.callee)&&m.callee.name==="createMemo"?[e.cloneNode(p),m,e.nullLiteral()]:[e.cloneNode(p),m];g.push(e.expressionStatement(e.callExpression(e.identifier("insert"),P)))}}return g.push(e.returnStatement(p)),e.callExpression(e.arrowFunctionExpression([],e.blockStatement(g)),[])}function ce(t,n,r){return r.backend==="imperative"?(r.needsCreateComponent=!0,r.needsCreateMemo=!0,e.callExpression(e.identifier("createMemo"),[e.arrowFunctionExpression([],e.callExpression(e.identifier("createComponent"),[t,n]))])):e.callExpression(e.identifier("jsx"),[t,n])}function re(t,n){let r=new Set,i=A(t,r),{code:s,imports:o}=D.emit(i,{});for(let a of o)r.add(a);for(let a of r)n.irImports.add(a);return Re.expression(s,{placeholderPattern:!1})()}function De(t){return t.map(n=>{if(e.isObjectProperty(n)){let r=n.key,i=n.computed,s=n.value;return e.objectMethod("get",r,[],e.blockStatement([e.returnStatement(s)]),i)}return n})}function k(t,n,r,i=!0){let s=t.openingElement,o=t.children,a=pe(s.name),l=e.isJSXIdentifier(s.name)&&/^[a-z]/.test(s.name.name),p=fe(s.attributes,n,l,e.isJSXIdentifier(s.name)?s.name.name:""),g=p.props,b=p.spreads;l||(g=De(g));let m=q(o,n,i);if(n.backend==="imperative")return $e(a,l,g,b,m,n);if(m.length>0){let w=m.length===1?m[0]:e.arrayExpression(m);g.push(e.objectProperty(e.identifier("children"),w))}let y;if(b.length>0){let w=g.length>0?e.objectExpression(g):e.objectExpression([]);n.needsMergeProps=!0,y=e.callExpression(e.identifier("mergeProps"),[...b,w])}else y=e.objectExpression(g);let P=r?"jsxDEV":m.length>1?"jsxs":"jsx",J=[a,y];return r&&J.push(e.identifier("undefined"),e.booleanLiteral(!1),e.identifier("undefined"),e.identifier("undefined")),e.callExpression(e.identifier(P),J)}function Ve(t,n,r){let i=t.openingElement,s=t.children,o=pe(i.name),a=e.isJSXIdentifier(i.name)&&/^[a-z]/.test(i.name.name),{props:l,spreads:p}=fe(i.attributes,n,a,e.isJSXIdentifier(i.name)?i.name.name:""),g=q(s,n,n.autoShow??!0),b;if(p.length>0){let y=l.length>0?e.objectExpression(l):e.objectExpression([]);n.needsMergeProps=!0,b=e.callExpression(e.identifier("mergeProps"),[...p,y])}else b=l.length>0?e.objectExpression(l):e.nullLiteral();let m=[o,b,...g];return e.callExpression(e.identifier(r),m)}function _(t,n,r){let{runtime:i,pragmaFrag:s,development:o}=r,a=q(t.children,n,n.autoShow??!0);if(n.backend==="imperative")return a.length===0?e.nullLiteral():le(a);if(i==="automatic"){let l=o?"jsxDEV":a.length>1?"jsxs":"jsx",p=e.objectExpression([e.objectProperty(e.identifier("children"),a.length===1?a[0]:e.arrayExpression(a))]),g=[e.identifier("Fragment"),p];return o&&g.push(e.identifier("undefined"),e.booleanLiteral(!1),e.identifier("undefined"),e.identifier("undefined")),e.callExpression(e.identifier(l),g)}else return e.callExpression(e.identifier(s),a)}function pe(t){if(e.isJSXIdentifier(t)){let n=t.name;return n[0]===n[0].toLowerCase()?e.stringLiteral(n):e.identifier(n)}return e.isJSXMemberExpression(t)?ue(t):e.isJSXNamespacedName(t)?e.stringLiteral(`${t.namespace.name}:${t.name.name}`):e.stringLiteral("div")}function ue(t){let n;return e.isJSXIdentifier(t.object)?n=e.identifier(t.object.name):n=ue(t.object),e.memberExpression(n,e.identifier(t.property.name))}function _e(t){return/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(t)}function fe(t,n,r=!0,i=""){let s=[],o=[],a=Oe[i];for(let l of t)if(e.isJSXSpreadAttribute(l))o.push(l.argument);else if(e.isJSXAttribute(l)){let p=ze(l.name),g=Be(l.value,n,p,r);if(oe.test(p)){let L=p.slice(2).toLowerCase();ae.includes(L)&&n.delegatedEvents.add(L)}let b=_e(p)?e.identifier(p):e.stringLiteral(p),m=l.value,y=e.isJSXElement(m)||e.isJSXFragment(m)||e.isJSXExpressionContainer(m)&&(e.isJSXElement(m.expression)||e.isJSXFragment(m.expression)),P=!r&&p===a,J=e.isJSXExpressionContainer(m)&&!e.isJSXEmptyExpression(m.expression)?m.expression:null,w=!r&&!!J&&me(J,p);!r&&y||P||w?s.push(e.objectMethod("get",b,[],e.blockStatement([e.returnStatement(g)]))):s.push(e.objectProperty(b,g))}return{props:s,spreads:o}}function ze(t){return e.isJSXIdentifier(t)?t.name==="class"?"className":t.name:e.isJSXNamespacedName(t)?`${t.namespace.name}:${t.name.name}`:"unknown"}function Be(t,n,r="",i=!0){if(t===null)return e.booleanLiteral(!0);if(e.isStringLiteral(t))return t.value.includes(`
2
+ `)?e.stringLiteral(t.value.replace(/\s+/g," ").trim()):t;if(e.isJSXExpressionContainer(t)){if(e.isJSXEmptyExpression(t.expression))return e.booleanLiteral(!0);let s=t.expression;return i&&me(s,r)?e.arrowFunctionExpression([],s):s}return e.isJSXElement(t)?k(t,n,!1,n.autoShow??!0):e.isJSXFragment(t)?_(t,n,{runtime:"automatic",pragmaFrag:"Fragment",development:!1}):e.booleanLiteral(!0)}function me(t,n){return oe.test(n)||n.startsWith("on:")||n==="ref"||n.startsWith("use:")||e.isArrowFunctionExpression(t)||e.isFunctionExpression(t)||e.isIdentifier(t)||e.isStringLiteral(t)||e.isNumericLiteral(t)||e.isBooleanLiteral(t)||e.isNullLiteral(t)?!1:!!(e.isCallExpression(t)||e.isOptionalCallExpression(t)||e.isMemberExpression(t)||e.isOptionalMemberExpression(t)||e.isLogicalExpression(t)||e.isConditionalExpression(t)||e.isBinaryExpression(t)||e.isUnaryExpression(t)||e.isTemplateLiteral(t)||e.isObjectExpression(t)||e.isArrayExpression(t))}function We(t){let n=t.split(/\r\n|\n|\r/),r=0;for(let s=0;s<n.length;s++)/[^ \t]/.test(n[s])&&(r=s);let i="";for(let s=0;s<n.length;s++){let o=n[s].replace(/\t/g," ");s!==0&&(o=o.replace(/^ +/,"")),s!==n.length-1&&(o=o.replace(/ +$/,"")),o&&(s!==r&&(o+=" "),i+=o)}return i}function q(t,n,r=!0){let i=[];for(let s of t)if(e.isJSXText(s)){let o=We(s.value);o&&i.push(e.stringLiteral(o))}else if(e.isJSXExpressionContainer(s)){if(!e.isJSXEmptyExpression(s.expression)){let o=s.expression;if(r){let a=qe(o,n)??Ge(o,n);if(a){i.push(a);continue}}else{let a=He(o,n);if(a){i.push(a);continue}}Ue(o)?i.push(e.arrowFunctionExpression([],o)):i.push(o)}}else e.isJSXElement(s)?i.push(k(s,n,!1,n.autoShow??!0)):e.isJSXFragment(s)?i.push(_(s,n,{runtime:"automatic",pragmaFrag:"Fragment",development:!1})):e.isJSXSpreadChild(s)&&i.push(s.expression);return i}function qe(t,n){if(!e.isArrowFunctionExpression(t)||t.params.length!==0||t.async)return null;let r=t.body;if(e.isLogicalExpression(r)&&r.operator==="&&"){let i=C(r.right);if(i)return R(j(r.left),i,null,n)}if(e.isConditionalExpression(r)){let i=C(r.consequent);if(i){let s=G(r.alternate,n);return R(j(r.test),i,s,n,!0)}}return null}function Ge(t,n){if(e.isLogicalExpression(t)&&t.operator==="&&"){let r=C(t.right);if(r)return R(j(t.left),r,null,n)}if(e.isConditionalExpression(t)){let r=C(t.consequent);if(r){let i=G(t.alternate,n);return R(j(t.test),r,i,n)}}return null}function He(t,n){let r=e.isArrowFunctionExpression(t)&&t.params.length===0&&!t.async&&e.isExpression(t.body)?t.body:t;if(e.isConditionalExpression(r)){let i=j(r.test),o=C(r.consequent)??r.consequent,l=C(r.alternate)??r.alternate,p=e.conditionalExpression(i,o,l);return W(r.consequent)||W(r.alternate)?null:(n.needsCreateMemo=!0,e.callExpression(e.identifier("createMemo"),[e.arrowFunctionExpression([],p)]))}if(e.isLogicalExpression(r)&&r.operator==="&&"){let i=j(r.left),o=C(r.right)??r.right,a=e.logicalExpression("&&",i,o);return W(r.right)?null:(n.needsCreateMemo=!0,e.callExpression(e.identifier("createMemo"),[e.arrowFunctionExpression([],a)]))}return null}function G(t,n){if(Ze(t))return null;let r=C(t);if(r)return de(r,n);if(e.isConditionalExpression(t)){let i=t,s=C(i.consequent);if(s){let o=G(i.alternate,n);return R(j(i.test),s,o,n)}}return t}function ie(t){return e.isJSXElement(t)||e.isJSXFragment(t)}function W(t){let n=C(t);if(!n||!e.isJSXElement(n))return!1;let r=n.openingElement.name;return e.isJSXIdentifier(r)&&se.has(r.name)}function C(t){return ie(t)?t:e.isArrowFunctionExpression(t)&&t.params.length===0&&!t.async&&ie(t.body)?t.body:null}function j(t){return e.isArrowFunctionExpression(t)&&t.params.length===0&&!t.async&&e.isExpression(t.body)?t.body:t}function Ze(t){return e.isNullLiteral(t)||e.isIdentifier(t)&&t.name==="undefined"||e.isBooleanLiteral(t)&&t.value===!1}function de(t,n){return e.isJSXElement(t)?k(t,n,!1,n.autoShow??!0):_(t,n,{runtime:"automatic",pragmaFrag:"Fragment",development:!1})}function R(t,n,r,i,s=!1){i.controlFlowComponents.add("Show"),i.needsControlFlowImport=!0;let o=de(n,i),a=[e.objectProperty(e.identifier("when"),e.arrowFunctionExpression([],t)),e.objectProperty(e.identifier("children"),o)];return r&&a.push(e.objectProperty(e.identifier("fallback"),r)),ce(e.identifier("Show"),e.objectExpression(a),i)}function Ue(t){return e.isMemberExpression(t)||e.isOptionalMemberExpression(t)?!(!t.computed&&e.isIdentifier(t.property,{name:"children"})):e.isCallExpression(t)||e.isOptionalCallExpression(t)?!0:e.isIdentifier(t)?!1:!!(e.isLogicalExpression(t)||e.isConditionalExpression(t)||e.isBinaryExpression(t)||e.isUnaryExpression(t)||e.isTemplateLiteral(t))}function ge(t,n){let r=t.openingElement;if(!e.isJSXIdentifier(r.name))return!1;let i=r.name.name;if(i[0]!==i[0].toLowerCase())return!1;for(let s of r.attributes){if(e.isJSXSpreadAttribute(s))return!1;if(e.isJSXAttribute(s)){let o=s.value;if(e.isJSXExpressionContainer(o)&&!e.isStringLiteral(o.expression)&&!e.isNumericLiteral(o.expression))return!1}}for(let s of t.children)if(e.isJSXElement(s)&&!ge(s,n)||e.isJSXExpressionContainer(s))return!1;return!0}function Ke(t,n){let r=`_$static${n.staticCounter++}`,i=k(t,n,!1);return n.staticElements.set(r,i),e.identifier(r)}function Qe(t,n){let r=t.openingElement.name.name;return r==="Show"?Ye(t,n):r==="For"?et(t,n):null}function Ye(t,n){return null}function et(t,n){return null}var Et=O;function xt(t){return[O,t]}function H(t={}){return{plugins:[[O,{runtime:"automatic",importSource:"@fluixi/jsx",development:!1,detectReactivity:!0,useLitHTML:!0,hoistStatics:!0,delegateEvents:!0,optimizeControlFlow:!0,sourceMaps:!0,...t}]]}}var St={production:H({development:!1,hoistStatics:!0,delegateEvents:!0,optimizeControlFlow:!0}),development:H({development:!0,hoistStatics:!1,sourceMaps:!0}),minimal:H({detectReactivity:!1,useLitHTML:!1,hoistStatics:!1,delegateEvents:!1,optimizeControlFlow:!1})};export{Et as babelPluginReactiveJSX,xt as createPlugin,H as createPreset,O as default,St as presets};
@@ -0,0 +1 @@
1
+ var d=(a=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(a,{get:(b,c)=>(typeof require<"u"?require:b)[c]}):a)(function(a){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});export{d as a};
@@ -0,0 +1 @@
1
+ "use strict";var r=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var s=Object.prototype.hasOwnProperty;var c=(o,t,i,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of m(t))!s.call(o,e)&&e!==i&&r(o,e,{get:()=>t[e],enumerable:!(n=p(t,e))||n.enumerable});return o};var a=o=>c(r({},"__esModule",{value:!0}),o);var d={};module.exports=a(d);
@@ -0,0 +1,22 @@
1
+ import type { IRNode } from '../ir/nodes.js';
2
+ import type { RuntimeContract } from './contract.js';
3
+ import type { CompilerOptions } from '../options.js';
4
+ export interface CodegenResult {
5
+ code: string;
6
+ map?: unknown;
7
+ /** runtime symbols this output imports (subset of the backend's contract) */
8
+ imports: string[];
9
+ }
10
+ /**
11
+ * A codegen backend turns IR into runtime calls. This is the swap point: the
12
+ * imperative backend ships now; a template-clone backend (and hybrids/islands
13
+ * variants) plug in later without touching the front-ends or IR.
14
+ */
15
+ export interface CodegenBackend {
16
+ /** stable id used in CompilerOptions.backend */
17
+ name: string;
18
+ /** the runtime contract this backend emits against */
19
+ contract: RuntimeContract;
20
+ emit(node: IRNode, options: CompilerOptions): CodegenResult;
21
+ }
22
+ //# sourceMappingURL=backend.d.ts.map
@@ -0,0 +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;CACnB;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"}
@@ -0,0 +1 @@
1
+ export {};
File without changes
@@ -0,0 +1 @@
1
+ "use strict";var l=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var $=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var C=(e,t)=>{for(var r in t)l(e,r,{get:t[r],enumerable:!0})},N=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of $(t))!h.call(e,o)&&o!==r&&l(e,o,{get:()=>t[o],enumerable:!(n=f(t,o))||n.enumerable});return e};var R=e=>N(l({},"__esModule",{value:!0}),e);var O={};C(O,{imperativeBackend:()=>k});module.exports=R(O);var m={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},T={version:2,module:"@fluixi/dom",symbols:[...m.symbols,"template","cloneTemplate","walk"]};var y={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function x(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function g(e){return x(e)?e:JSON.stringify(e)}function v(e){return e.expr!==void 0?e.reactive?`() => (${e.expr})`:`(${e.expr})`:JSON.stringify(e.literal??!0)}function I(e){return e.expr!==void 0?`(${e.expr})`:JSON.stringify(e.literal??!0)}function S(e,t,r){let n=e.filter(i=>i.kind==="spread"),c=e.filter(i=>i.kind!=="spread").map(i=>`${g(i.name)}: ${v(i)}`);t!=null&&c.push(`children: ${t}`);let s=`{ ${c.join(", ")} }`;return n.length>0?(r.add("mergeProps"),`mergeProps(${n.map(i=>i.expr).join(", ")}, ${s})`):s}function d(e,t){return e.length===1?p(e[0],t):`[${e.map(r=>p(r,t)).join(", ")}]`}function u(e,t,r,n){n.add("createMemo"),n.add("createComponent");let o=t.filter(a=>a.kind==="spread"),s=t.filter(a=>a.kind!=="spread").map(a=>`get ${g(a.name)}() { return ${I(a)}; }`);r.length>0&&s.push(`get children() { return ${d(r,n)}; }`);let i=`{ ${s.join(", ")} }`;return o.length>0&&(n.add("mergeProps"),i=`mergeProps(${o.map(a=>a.expr).join(", ")}, ${i})`),`createMemo(() => createComponent(${e}, ${i}))`}function p(e,t){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":d(e.children,t);case"component":return u(e.name,e.props,e.children,t);case"control":{let r=y[e.control]??e.control;return t.add(r),u(r,e.props,e.children,t)}case"element":{t.add("createNativeElement");let r=JSON.stringify(e.tag),n="_el$",o=[],c=e.svg?`${r}, true`:r;if(o.push(`const ${n} = createNativeElement(${c});`),e.props.length>0){t.add("spread");let s=e.svg?", isSVG: true":"";o.push(`spread({ element: ${n}, props: ${S(e.props,null,t)}${s} });`)}for(let s of e.children){t.add("insert");let i=p(s,t),a=s.kind==="expr"&&s.reactive||s.kind==="component"||s.kind==="control";o.push(a?`insert(${n}, ${i}, null);`:`insert(${n}, ${i});`)}return o.push(`return ${n};`),`(() => { ${o.join(" ")} })()`}}}var k={name:"imperative",contract:m,emit(e,t){let r=new Set;return{code:p(e,r),imports:Array.from(r)}}};
@@ -0,0 +1,3 @@
1
+ import type { CodegenBackend } from '../backend.js';
2
+ export declare const imperativeBackend: CodegenBackend;
3
+ //# sourceMappingURL=imperative.d.ts.map
@@ -0,0 +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;AAkKnE,eAAO,MAAM,iBAAiB,EAAE,cAQ/B,CAAC"}
@@ -0,0 +1,152 @@
1
+ import { RUNTIME_CONTRACT_V1 } from '../contract.js';
2
+ /**
3
+ * Imperative fine-grained backend — emits createNativeElement/insert/spread/
4
+ * createComponent (RUNTIME_CONTRACT_V1), the runtime proven by the @fluixi/dom
5
+ * contract tests.
6
+ *
7
+ * emit() consumes the host-agnostic IR and returns a code string, so any
8
+ * front-end (babel now, swc later) that can produce IR reuses this exact codegen.
9
+ * The output mirrors what the babel front-end emits inline today:
10
+ *
11
+ * element -> (() => { const _el$ = createNativeElement(tag);
12
+ * spread({ element: _el$, props });
13
+ * insert(_el$, children); return _el$; })()
14
+ * component -> createMemo(() => createComponent(Name, props))
15
+ * fragment -> [ ...children ]
16
+ */
17
+ const CONTROL_COMPONENT = {
18
+ show: 'Show',
19
+ for: 'For',
20
+ index: 'Index',
21
+ switch: 'Switch',
22
+ match: 'Match',
23
+ dynamic: 'Dynamic',
24
+ errorBoundary: 'ErrorBoundary',
25
+ suspense: 'Suspense',
26
+ };
27
+ function isIdent(name) {
28
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name);
29
+ }
30
+ function propKey(name) {
31
+ return isIdent(name) ? name : JSON.stringify(name);
32
+ }
33
+ function propValue(p) {
34
+ if (p.expr !== undefined) {
35
+ // Events and non-reactive expressions pass through; reactive ones become thunks
36
+ // so the runtime (spread/insert) can wire a render effect.
37
+ return p.reactive ? `() => (${p.expr})` : `(${p.expr})`;
38
+ }
39
+ return JSON.stringify(p.literal ?? true);
40
+ }
41
+ /**
42
+ * Component props are passed as VALUES, not thunks (unlike native-element attrs).
43
+ * The whole `createComponent(...)` call sits inside a `createMemo`, so reading a
44
+ * signal in a prop re-evaluates when the memo re-runs — no per-prop thunk needed.
45
+ * This matches the inline codegen; wrapping a prop like
46
+ * `history={createMemoryHistory()}` in `() => …` would hand the component a
47
+ * function instead of the value (e.g. `history.get is not a function`).
48
+ */
49
+ function componentPropValue(p) {
50
+ if (p.expr !== undefined)
51
+ return `(${p.expr})`;
52
+ return JSON.stringify(p.literal ?? true);
53
+ }
54
+ /** Build a props object literal (or mergeProps(...) when spreads are present). */
55
+ function emitProps(props, childrenExpr, used) {
56
+ const spreads = props.filter((p) => p.kind === 'spread');
57
+ const normal = props.filter((p) => p.kind !== 'spread');
58
+ const entries = normal.map((p) => `${propKey(p.name)}: ${propValue(p)}`);
59
+ if (childrenExpr != null)
60
+ entries.push(`children: ${childrenExpr}`);
61
+ const obj = `{ ${entries.join(', ')} }`;
62
+ if (spreads.length > 0) {
63
+ used.add('mergeProps');
64
+ return `mergeProps(${spreads.map((s) => s.expr).join(', ')}, ${obj})`;
65
+ }
66
+ return obj;
67
+ }
68
+ function emitChildren(children, used) {
69
+ if (children.length === 1)
70
+ return emitNode(children[0], used);
71
+ return `[${children.map((c) => emitNode(c, used)).join(', ')}]`;
72
+ }
73
+ function emitComponent(name, props, children, used) {
74
+ used.add('createMemo');
75
+ used.add('createComponent');
76
+ const spreads = props.filter((p) => p.kind === 'spread');
77
+ const normal = props.filter((p) => p.kind !== 'spread');
78
+ // ALL component props are emitted as getters (Solid model): reading a signal in a prop
79
+ // eagerly inside `createMemo(() => createComponent(...))` would re-create the whole component
80
+ // on every change (a <Portal> then piles up). As getters the component is built ONCE and
81
+ // reactivity flows through the getter into its own effects. Static props as getters are
82
+ // harmless (they return the same value). Matches lazyProps() in the inline codegen.
83
+ const entries = normal.map((p) => `get ${propKey(p.name)}() { return ${componentPropValue(p)}; }`);
84
+ if (children.length > 0) {
85
+ // Children are a LAZY getter: evaluated inside the component's execution, so
86
+ // child components are created in the component's owner scope (preserves owner
87
+ // nesting for context/Suspense), after the component runs (correct provider
88
+ // ordering), and lazily (ErrorBoundary can still catch a throwing child).
89
+ entries.push(`get children() { return ${emitChildren(children, used)}; }`);
90
+ }
91
+ let obj = `{ ${entries.join(', ')} }`;
92
+ if (spreads.length > 0) {
93
+ used.add('mergeProps');
94
+ obj = `mergeProps(${spreads.map((s) => s.expr).join(', ')}, ${obj})`;
95
+ }
96
+ return `createMemo(() => createComponent(${name}, ${obj}))`;
97
+ }
98
+ function emitNode(node, used) {
99
+ switch (node.kind) {
100
+ case 'text':
101
+ return JSON.stringify(node.value);
102
+ case 'expr':
103
+ return node.reactive ? `() => (${node.code})` : `(${node.code})`;
104
+ case 'fragment':
105
+ if (node.children.length === 0)
106
+ return 'null';
107
+ return emitChildren(node.children, used);
108
+ case 'component':
109
+ return emitComponent(node.name, node.props, node.children, used);
110
+ case 'control': {
111
+ const name = CONTROL_COMPONENT[node.control] ?? node.control;
112
+ used.add(name);
113
+ return emitComponent(name, node.props, node.children, used);
114
+ }
115
+ case 'element': {
116
+ used.add('createNativeElement');
117
+ const tag = JSON.stringify(node.tag);
118
+ const el = '_el$';
119
+ const parts = [];
120
+ const createArgs = node.svg ? `${tag}, true` : tag;
121
+ parts.push(`const ${el} = createNativeElement(${createArgs});`);
122
+ if (node.props.length > 0) {
123
+ used.add('spread');
124
+ const svgFlag = node.svg ? ', isSVG: true' : '';
125
+ parts.push(`spread({ element: ${el}, props: ${emitProps(node.props, null, used)}${svgFlag} });`);
126
+ }
127
+ // Insert each child individually (like the jsx runtime's applyProps), so a
128
+ // reactive/component child that isn't the only child still gets its own
129
+ // reactive binding. A single insert(el, [array]) does NOT bind function
130
+ // elements sitting inside the array.
131
+ for (const child of node.children) {
132
+ used.add('insert');
133
+ const childCode = emitNode(child, used);
134
+ const isFn = (child.kind === 'expr' && child.reactive) ||
135
+ child.kind === 'component' ||
136
+ child.kind === 'control';
137
+ parts.push(isFn ? `insert(${el}, ${childCode}, null);` : `insert(${el}, ${childCode});`);
138
+ }
139
+ parts.push(`return ${el};`);
140
+ return `(() => { ${parts.join(' ')} })()`;
141
+ }
142
+ }
143
+ }
144
+ export const imperativeBackend = {
145
+ name: 'imperative',
146
+ contract: RUNTIME_CONTRACT_V1,
147
+ emit(node, _options) {
148
+ const used = new Set();
149
+ const code = emitNode(node, used);
150
+ return { code, imports: Array.from(used) };
151
+ },
152
+ };
@@ -0,0 +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"]},N={version:2,module:"@fluixi/dom",symbols:[...l.symbols,"template","cloneTemplate","walk"]};var d={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function f(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function u(e){return f(e)?e:JSON.stringify(e)}function $(e){return e.expr!==void 0?e.reactive?`() => (${e.expr})`:`(${e.expr})`:JSON.stringify(e.literal??!0)}function h(e){return e.expr!==void 0?`(${e.expr})`:JSON.stringify(e.literal??!0)}function C(e,t,r){let o=e.filter(n=>n.kind==="spread"),c=e.filter(n=>n.kind!=="spread").map(n=>`${u(n.name)}: ${$(n)}`);t!=null&&c.push(`children: ${t}`);let i=`{ ${c.join(", ")} }`;return o.length>0?(r.add("mergeProps"),`mergeProps(${o.map(n=>n.expr).join(", ")}, ${i})`):i}function g(e,t){return e.length===1?p(e[0],t):`[${e.map(r=>p(r,t)).join(", ")}]`}function m(e,t,r,o){o.add("createMemo"),o.add("createComponent");let a=t.filter(s=>s.kind==="spread"),i=t.filter(s=>s.kind!=="spread").map(s=>`get ${u(s.name)}() { return ${h(s)}; }`);r.length>0&&i.push(`get children() { return ${g(r,o)}; }`);let n=`{ ${i.join(", ")} }`;return a.length>0&&(o.add("mergeProps"),n=`mergeProps(${a.map(s=>s.expr).join(", ")}, ${n})`),`createMemo(() => createComponent(${e}, ${n}))`}function p(e,t){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":g(e.children,t);case"component":return m(e.name,e.props,e.children,t);case"control":{let r=d[e.control]??e.control;return t.add(r),m(r,e.props,e.children,t)}case"element":{t.add("createNativeElement");let r=JSON.stringify(e.tag),o="_el$",a=[],c=e.svg?`${r}, true`:r;if(a.push(`const ${o} = createNativeElement(${c});`),e.props.length>0){t.add("spread");let i=e.svg?", isSVG: true":"";a.push(`spread({ element: ${o}, props: ${C(e.props,null,t)}${i} });`)}for(let i of e.children){t.add("insert");let n=p(i,t),s=i.kind==="expr"&&i.reactive||i.kind==="component"||i.kind==="control";a.push(s?`insert(${o}, ${n}, null);`:`insert(${o}, ${n});`)}return a.push(`return ${o};`),`(() => { ${a.join(" ")} })()`}}}var x={name:"imperative",contract:l,emit(e,t){let r=new Set;return{code:p(e,r),imports:Array.from(r)}}};export{x as imperativeBackend};
@@ -0,0 +1 @@
1
+ "use strict";var r=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var c=(t,e)=>{for(var n in e)r(t,n,{get:e[n],enumerable:!0})},u=(t,e,n,m)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of i(e))!l.call(t,o)&&o!==n&&r(t,o,{get:()=>e[o],enumerable:!(m=a(e,o))||m.enumerable});return t};var d=t=>u(r({},"__esModule",{value:!0}),t);var p={};c(p,{RUNTIME_CONTRACT_V1:()=>s,RUNTIME_CONTRACT_V2:()=>C});module.exports=d(p);var s={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},C={version:2,module:"@fluixi/dom",symbols:[...s.symbols,"template","cloneTemplate","walk"]};
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The RuntimeContract is the exact set of runtime symbols a codegen backend may
3
+ * emit, paired with the module they import from and a version number. Backend
4
+ * and runtime evolve in lockstep: adding a primitive bumps the version, so old
5
+ * and new backends/runtimes can coexist during a migration.
6
+ */
7
+ export interface RuntimeContract {
8
+ version: number;
9
+ /** module the emitted symbols are imported from */
10
+ module: string;
11
+ symbols: readonly string[];
12
+ }
13
+ /**
14
+ * v1 — the imperative fine-grained runtime, locked by the @fluixi/dom contract
15
+ * tests (createNativeElement/insert/spread/delegateEvents/createComponent + the
16
+ * control-flow components).
17
+ */
18
+ export declare const RUNTIME_CONTRACT_V1: RuntimeContract;
19
+ /**
20
+ * v2 — adds the Solid-style (but ours) template-clone primitives. A future
21
+ * template-clone backend targets this contract; the runtime gains template()/
22
+ * cloneTemplate()/walk() at the same time.
23
+ */
24
+ export declare const RUNTIME_CONTRACT_V2: RuntimeContract;
25
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/codegen/contract.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAcjC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,eAIjC,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * v1 — the imperative fine-grained runtime, locked by the @fluixi/dom contract
3
+ * tests (createNativeElement/insert/spread/delegateEvents/createComponent + the
4
+ * control-flow components).
5
+ */
6
+ export const RUNTIME_CONTRACT_V1 = {
7
+ version: 1,
8
+ module: '@fluixi/dom',
9
+ symbols: [
10
+ 'createNativeElement',
11
+ 'insert',
12
+ 'spread',
13
+ 'setAttribute',
14
+ 'delegateEvents',
15
+ 'createComponent',
16
+ 'createMemo',
17
+ 'untrack',
18
+ 'Show', 'For', 'Index', 'Switch', 'Match', 'Dynamic', 'ErrorBoundary',
19
+ ],
20
+ };
21
+ /**
22
+ * v2 — adds the Solid-style (but ours) template-clone primitives. A future
23
+ * template-clone backend targets this contract; the runtime gains template()/
24
+ * cloneTemplate()/walk() at the same time.
25
+ */
26
+ export const RUNTIME_CONTRACT_V2 = {
27
+ version: 2,
28
+ module: '@fluixi/dom',
29
+ symbols: [...RUNTIME_CONTRACT_V1.symbols, 'template', 'cloneTemplate', 'walk'],
30
+ };
@@ -0,0 +1 @@
1
+ var e={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},t={version:2,module:"@fluixi/dom",symbols:[...e.symbols,"template","cloneTemplate","walk"]};export{e as RUNTIME_CONTRACT_V1,t as RUNTIME_CONTRACT_V2};
@@ -0,0 +1 @@
1
+ "use strict";var C=Object.create;var m=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var X=Object.getOwnPropertyNames;var b=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var P=(e,t)=>{for(var r in t)m(e,r,{get:t[r],enumerable:!0})},S=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of X(t))!k.call(e,i)&&i!==r&&m(e,i,{get:()=>t[i],enumerable:!(n=I(t,i))||n.enumerable});return e};var A=(e,t,r)=>(r=e!=null?C(b(e)):{},S(t||!e||!e.__esModule?m(r,"default",{value:e,enumerable:!0}):r,e)),w=e=>S(m({},"__esModule",{value:!0}),e);var q={};P(q,{buildIR:()=>g});module.exports=w(q);var s=require("@babel/core"),x=A(require("@babel/generator"),1);var d={version:1,module:"@fluixi/dom",symbols:["createNativeElement","insert","spread","setAttribute","delegateEvents","createComponent","createMemo","untrack","Show","For","Index","Switch","Match","Dynamic","ErrorBoundary"]},H={version:2,module:"@fluixi/dom",symbols:[...d.symbols,"template","cloneTemplate","walk"]};var T={show:"Show",for:"For",index:"Index",switch:"Switch",match:"Match",dynamic:"Dynamic",errorBoundary:"ErrorBoundary",suspense:"Suspense"};function O(e){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(e)}function h(e){return O(e)?e:JSON.stringify(e)}function j(e){return e.expr!==void 0?e.reactive?`() => (${e.expr})`:`(${e.expr})`:JSON.stringify(e.literal??!0)}function _(e){return e.expr!==void 0?`(${e.expr})`:JSON.stringify(e.literal??!0)}function M(e,t,r){let n=e.filter(a=>a.kind==="spread"),o=e.filter(a=>a.kind!=="spread").map(a=>`${h(a.name)}: ${j(a)}`);t!=null&&o.push(`children: ${t}`);let p=`{ ${o.join(", ")} }`;return n.length>0?(r.add("mergeProps"),`mergeProps(${n.map(a=>a.expr).join(", ")}, ${p})`):p}function y(e,t){return e.length===1?u(e[0],t):`[${e.map(r=>u(r,t)).join(", ")}]`}function E(e,t,r,n){n.add("createMemo"),n.add("createComponent");let i=t.filter(c=>c.kind==="spread"),p=t.filter(c=>c.kind!=="spread").map(c=>`get ${h(c.name)}() { return ${_(c)}; }`);r.length>0&&p.push(`get children() { return ${y(r,n)}; }`);let a=`{ ${p.join(", ")} }`;return i.length>0&&(n.add("mergeProps"),a=`mergeProps(${i.map(c=>c.expr).join(", ")}, ${a})`),`createMemo(() => createComponent(${e}, ${a}))`}function u(e,t){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":y(e.children,t);case"component":return E(e.name,e.props,e.children,t);case"control":{let r=T[e.control]??e.control;return t.add(r),E(r,e.props,e.children,t)}case"element":{t.add("createNativeElement");let r=JSON.stringify(e.tag),n="_el$",i=[],o=e.svg?`${r}, true`:r;if(i.push(`const ${n} = createNativeElement(${o});`),e.props.length>0){t.add("spread");let p=e.svg?", isSVG: true":"";i.push(`spread({ element: ${n}, props: ${M(e.props,null,t)}${p} });`)}for(let p of e.children){t.add("insert");let a=u(p,t),c=p.kind==="expr"&&p.reactive||p.kind==="component"||p.kind==="control";i.push(c?`insert(${n}, ${a}, null);`:`insert(${n}, ${a});`)}return i.push(`return ${n};`),`(() => { ${i.join(" ")} })()`}}}var $={name:"imperative",contract:d,emit(e,t){let r=new Set;return{code:u(e,r),imports:Array.from(r)}}};var L=x.default.default??x.default;function J(e){return L(e,{concise:!0}).code}function F(e,t){let r=s.types.cloneNode(e,!0),n=s.types.file(s.types.program([s.types.expressionStatement(r)])),i=!1;return(0,s.traverse)(n,{"JSXElement|JSXFragment"(o){let p=o.node,{code:a,imports:c}=$.emit(g(p,t),{});for(let v of c)t.add(v);let R=s.template.expression(a,{placeholderPattern:!1})();o.replaceWith(R),o.skip(),i=!0}}),i?n.program.body[0].expression:e}function f(e,t){return J(F(e,t))}var B=new Set(["svg","path","circle","rect","line","polygon","polyline","ellipse","g","defs","clipPath","text"]),V=/^on[A-Z]/,D=new Set(["click","dblclick","input","change","submit","focus","blur","keydown","keyup","keypress","mousedown","mouseup"]);function G(e){if(s.types.isJSXIdentifier(e)){let t=e.name[0]!==e.name[0].toLowerCase();return{tag:e.name,component:t}}return s.types.isJSXMemberExpression(e)?{tag:J(e),component:!0}:s.types.isJSXNamespacedName(e)?{tag:`${e.namespace.name}:${e.name.name}`,component:!1}:{tag:"div",component:!1}}function K(e){return s.types.isJSXIdentifier(e)?e.name==="class"?"className":e.name:s.types.isJSXNamespacedName(e)?`${e.namespace.name}:${e.name.name}`:"unknown"}function l(e){return s.types.isCallExpression(e)||s.types.isOptionalCallExpression(e)?!0:s.types.isMemberExpression(e)||s.types.isOptionalMemberExpression(e)?!(!e.computed&&s.types.isIdentifier(e.property,{name:"children"})):s.types.isConditionalExpression(e)?l(e.test)||l(e.consequent)||l(e.alternate):s.types.isLogicalExpression(e)||s.types.isBinaryExpression(e)?l(e.left)||l(e.right):s.types.isTemplateLiteral(e)?e.expressions.some(t=>l(t)):!1}function U(e,t){let r=K(e.name),n=V.test(r),o={name:r,kind:n?"event":"attr"};n&&(o.event={name:r.slice(2).toLowerCase(),delegated:D.has(r.slice(2).toLowerCase())});let p=e.value;if(p==null)return o.literal=!0,o;if(s.types.isStringLiteral(p))return o.literal=p.value,o;if(s.types.isJSXExpressionContainer(p)&&!s.types.isJSXEmptyExpression(p.expression)){let a=p.expression;return s.types.isStringLiteral(a)||s.types.isNumericLiteral(a)||s.types.isBooleanLiteral(a)?(o.literal=a.value,o):(o.expr=f(a,t),o.reactive=n?!1:l(a),(s.types.isJSXElement(a)||s.types.isJSXFragment(a))&&(o.jsxElement=!0),o)}return o.literal=!0,o}function Z(e,t){let r=[];for(let n of e)s.types.isJSXSpreadAttribute(n)?r.push({name:"",kind:"spread",expr:f(n.argument,t)}):s.types.isJSXAttribute(n)&&r.push(U(n,t));return r}function z(e){let t=e.split(/\r\n|\n|\r/),r=0;for(let i=0;i<t.length;i++)/[^ \t]/.test(t[i])&&(r=i);let n="";for(let i=0;i<t.length;i++){let o=t[i].replace(/\t/g," ");i!==0&&(o=o.replace(/^ +/,"")),i!==t.length-1&&(o=o.replace(/ +$/,"")),o&&(i!==r&&(o+=" "),n+=o)}return n}function N(e,t){let r=[];for(let n of e)if(s.types.isJSXText(n)){let i=z(n.value);i&&r.push({kind:"text",value:i})}else if(s.types.isJSXExpressionContainer(n)){if(!s.types.isJSXEmptyExpression(n.expression)){let i=n.expression;r.push({kind:"expr",code:f(i,t),reactive:l(i)})}}else s.types.isJSXElement(n)||s.types.isJSXFragment(n)?r.push(g(n,t)):s.types.isJSXSpreadChild(n)&&r.push({kind:"expr",code:f(n.expression,t),reactive:!1});return r}function g(e,t=new Set){if(s.types.isJSXFragment(e))return{kind:"fragment",children:N(e.children,t)};let{tag:r,component:n}=G(e.openingElement.name),i=Z(e.openingElement.attributes,t),o=N(e.children,t);return n?{kind:"component",name:r,props:i,children:o}:{kind:"element",tag:r,svg:B.has(r),props:i,children:o,static:!1}}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Babel front-end: build the host-agnostic IR from a JSX AST node.
3
+ *
4
+ * This is the parsing-end half of the pipeline (AST -> IR); the imperative
5
+ * backend's emit() is the codegen half (IR -> code). Keeping the JSX analysis
6
+ * here and the code generation in the backend is what lets a future swc
7
+ * front-end reuse the exact same backend.
8
+ *
9
+ * JSX can appear nested inside arbitrary expressions (render-props, ternaries,
10
+ * `fallback={<p/>}`, `arr.map(x => <li/>)`, `() => cond && <div/>`, …). The IR
11
+ * models prop/child *expressions* as code strings, so any JSX inside such an
12
+ * expression is recursively compiled (build-ir -> emit) and spliced back in,
13
+ * with the runtime symbols it uses collected into `used` for import injection.
14
+ */
15
+ import { types as t } from '@babel/core';
16
+ import type { IRNode } from '../../ir/nodes.js';
17
+ /**
18
+ * Build IR from a JSXElement or JSXFragment. `used` accumulates the runtime
19
+ * symbols emitted for any JSX nested inside expressions (so the caller can
20
+ * inject the right imports).
21
+ */
22
+ export declare function buildIR(node: t.JSXElement | t.JSXFragment, used?: Set<string>): IRNode;
23
+ //# sourceMappingURL=build-ir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-ir.d.ts","sourceRoot":"","sources":["../../../src/frontend/babel/build-ir.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,KAAK,IAAI,CAAC,EAAsB,MAAM,aAAa,CAAC;AAG7D,OAAO,KAAK,EACV,MAAM,EAGP,MAAM,mBAAmB,CAAC;AA8L3B;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,GAAE,GAAG,CAAC,MAAM,CAAa,GAAG,MAAM,CAYjG"}