arrmatura 6.5.0 → 6.5.1
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/README.md +3 -3
- package/dist/index.js +3 -3
- package/package.json +8 -4
- package/src/compiler/index.test.ts +152 -0
- package/src/controls/Iterative.test.ts +116 -0
- package/src/controls/block.test.ts +44 -0
- package/src/controls/composition.test.ts +56 -0
- package/src/controls/conditionals.test.ts +103 -0
- package/src/controls/connector.test.ts +62 -0
- package/src/controls/elementary.test.ts +37 -0
- package/src/controls/fragment.test.ts +26 -0
- package/src/controls/root.test.ts +50 -0
- package/src/controls/root.ts +33 -34
- package/src/controls/routing.test.ts +64 -0
- package/src/controls/selection.test.ts +62 -0
- package/src/controls/slot.test.ts +62 -0
- package/src/core/Arrmatron.test.ts +680 -0
- package/src/core/Arrmatron.ts +616 -613
- package/src/core/Component.test.ts +203 -0
- package/src/core/ManifestNode.test.ts +225 -0
- package/src/core/ManifestNode.ts +259 -252
- package/src/core/NativeElement.test.ts +173 -0
- package/src/core/Platform.test.ts +127 -0
- package/src/core/Registry.test.ts +171 -0
- package/src/core/launch.test.ts +37 -0
- package/src/expr/Expression.test.ts +132 -0
- package/src/expr/Expression.ts +47 -44
- package/src/expr/ExpressionParser.test.ts +353 -0
- package/src/expr/ExpressionParser.ts +208 -208
- package/src/expr/ExpressionParserBase.test.ts +292 -0
- package/src/expr/ExpressionParserBase.ts +67 -12
- package/src/expr/compileEmitterExpression.test.ts +142 -0
- package/src/expr/compileEmitterExpression.ts +20 -10
- package/src/expr/compilePlaceholder.test.ts +44 -0
- package/src/expr/compilePlaceholder.ts +9 -9
- package/src/expr/operations.test.ts +138 -0
- package/src/expr/prepareConnectedProps.test.ts +44 -0
- package/src/expr/resolveExpression.test.ts +96 -0
- package/src/types.ts +38 -7
- package/src/utils/applyStateChangedToImpl.test.ts +28 -0
- package/src/utils/applyStateChangedToImpl.ts +11 -8
- package/src/utils/applyTemplate.test.ts +53 -0
- package/src/utils/asyncValueCall.test.ts +20 -0
- package/src/utils/capitalize.test.ts +21 -0
- package/src/utils/createRegisterTypes.test.ts +70 -0
- package/src/utils/defineCalculatedProperty.test.ts +58 -0
- package/src/utils/defineCalculatedProperty.ts +45 -41
- package/src/utils/defineObjectRef.test.ts +30 -0
- package/src/utils/hashCodeOf.test.ts +124 -0
- package/src/utils/isEquals.test.ts +76 -0
- package/src/utils/mapEntries.test.ts +22 -0
- package/src/utils/mergeObject.test.ts +34 -0
- package/src/utils/mergeObject.ts +1 -1
- package/src/utils/narrowData.test.ts +51 -0
- package/src/utils/scalarParse.test.ts +38 -0
- package/src/utils/scalarParse.ts +1 -1
- package/src/utils/splitTopLevel.test.ts +34 -0
- package/src/utils/splitTopLevel.ts +24 -24
- package/src/utils/stringify.test.ts +59 -0
- package/src/utils/stringify.ts +24 -20
- package/src/utils/toNativeTree.test.ts +53 -0
- package/src/utils/toNativeTree.ts +14 -11
- package/src/utils/xmlParse.test.ts +78 -0
- package/src/utils/xmlParse.ts +1 -1
- package/dist/index.cjs +0 -4
package/README.md
CHANGED
|
@@ -70,6 +70,6 @@ It strips away the "toolchain bloat" of modern JavaScript.
|
|
|
70
70
|
|
|
71
71
|
## Documentation
|
|
72
72
|
|
|
73
|
-
- the runtime model [architecture.md](./architecture.md).
|
|
74
|
-
- the CML syntax reference [cml.md](./cml.md);
|
|
75
|
-
- the semantics of each built-in element [built-ins.md](./built-ins.md);
|
|
73
|
+
- the runtime model [architecture.md](./docs/architecture.md).
|
|
74
|
+
- the CML syntax reference [cml.md](./docs/cml.md);
|
|
75
|
+
- the semantics of each built-in element [built-ins.md](./docs/built-ins.md);
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`):"";return`${t}<${
|
|
1
|
+
"use strict";var K=Object.defineProperty;var re=Object.getOwnPropertyDescriptor;var se=Object.getOwnPropertyNames;var oe=Object.prototype.hasOwnProperty;var i=(n,t)=>K(n,"name",{value:t,configurable:!0});var Tt=(n,t)=>{for(var e in t)K(n,e,{get:t[e],enumerable:!0})},ie=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of se(t))!oe.call(n,s)&&s!==e&&K(n,s,{get:()=>t[s],enumerable:!(r=re(t,s))||r.enumerable});return n};var ae=n=>ie(K({},"__esModule",{value:!0}),n);var Ze={};Tt(Ze,{CRootNode:()=>$,Component:()=>A,Platform:()=>z,applyTemplate:()=>Ye,compileManifestNode:()=>V,compileManifestNodes:()=>tt,createRegisterTypes:()=>Rt,launch:()=>We});module.exports=ae(Ze);var pt={};Tt(pt,{HASH_SYMBOL:()=>y,asyncValueCall:()=>_,capitalize:()=>q,defineObjectHashCodeProperty:()=>P,defineObjectRef:()=>st,hashCodeOf:()=>C,isEquals:()=>w,mapEntries:()=>x,mergeObject:()=>b,scalarParse:()=>O,stringHashCode:()=>h,xmlParse:()=>at});function _(n,t){return n instanceof Promise?n.then(t):t(n)}i(_,"asyncValueCall");var pe=i(n=>n==null?"":String(n),"str");function q(n){let t=pe(n);return t.length?t[0].toUpperCase()+t.slice(1):""}i(q,"capitalize");function st(n,t,e){return Object.defineProperty(n,t,{get(){return e},enumerable:!1,configurable:!1}),n}i(st,"defineObjectRef");var E=i(()=>Math.floor((1+Math.random())*65536).toString(16).substring(1),"s4"),ce=i(()=>`${E()}${E()}-${E()}-${E()}-${E()}-${E()}${E()}${E()}`,"guid"),y=Symbol("HASH_SYMBOL"),bt=new Map([["",ot("__empty__")]]),Ot=new Map([[void 0,h("__undefined__")],[null,h("__null__")],["",h("__empty__")],[NaN,h("__NaN__")],[!1,h("__false__")],[!0,h("__true__")]]),I={Object:h("__Object__"),Date:h("__Date__"),Array:h("__Array__"),Map:h("__Map__"),Set:h("__Set__")};function ot(n){let t=-2128831035;for(let e=0;e<n.length;e++)t^=n.charCodeAt(e),t=Math.imul(t,16777619);return t|0}i(ot,"__stringHashCode");function g(n,t){return Math.imul(t^n,16777619)|0}i(g,"numberHashCode");function h(n){let t=bt.get(n);if(t)return t;let e=ot(n);return bt.set(n,e),e}i(h,"stringHashCode");function P(n,t){if(!n||Object.hasOwn(n,y))return n;let e=t??ot(ce());return Object.defineProperty(n,y,{get(){return e},configurable:!1,enumerable:!1}),n}i(P,"defineObjectHashCodeProperty");function fe(n,t){if(t>10)return-1;let e=t+1,r=0;if(n instanceof Map){r=g(I.Map,r);for(let[s,o]of n)r=g(h(s),r),r=g(I.Map,r),r=g(C(o,e),r)}else if(n instanceof Set){r=g(I.Set,r);for(let s of n)r=g(C(s,e),r)}else if(Array.isArray(n)){r=g(I.Array,r);for(let s of n)r=g(C(s,e),r)}else{r=g(I.Object,r);for(let s in n)Object.hasOwn(n,s)&&s[0]!=="$"&&(r=g(h(s),r),r=g(I.Object,r),r=g(C(n[s],e),r))}return r}i(fe,"containerHashCode");var C=i((n,t=0)=>Ot.has(n)?Ot.get(n):typeof n=="string"?h(n):typeof n=="number"?n:typeof n=="bigint"?h(n.toString(16)):typeof n=="symbol"?h(n.description??n.toString()):typeof n=="function"?P(n)[y]:y in n?n[y]:n instanceof Date?g(n.getTime(),I.Date):n instanceof Promise?P(n)[y]:fe(n,t),"hashCodeOf");function w(n,t,e=0){if(Number.isNaN(n))return!1;if(n===null||typeof n!="object")return n===t;if(t===null||typeof t!="object")return!1;if(y in n&&y in t)return n[y]===t[y];if(e>10)return!0;let r=e+1;if(Array.isArray(n)){if(!Array.isArray(t)||n.length!==t.length)return!1;for(let o=0;o<n.length;o++)if(!w(n[o],t[o],r))return!1;return!0}if(n instanceof Map){if(!(t instanceof Map)||n.size!==t.size)return!1;for(let[o,a]of n){let p=t.get(o);if(p===void 0&&!t.has(o)||!w(a,p,r))return!1}return!0}if(n instanceof Set){if(!(t instanceof Set)||n.size!==t.size)return!1;for(let o of n)if(!t.has(o))return!1;return!0}if(Array.isArray(t)||t instanceof Map||t instanceof Set)return!1;if(n instanceof Date||t instanceof Date)return n instanceof Date&&t instanceof Date&&n.getTime()===t.getTime();let s=0;for(let o in n)if(!(o[0]==="$"||!Object.hasOwn(n,o))&&(s++,!Object.hasOwn(t,o)||!w(n[o],t[o],r)))return!1;for(let o in t)if(o[0]!=="$"&&Object.hasOwn(t,o)&&--s<0)return!1;return s===0}i(w,"isEquals");var le=i((n,t)=>({id:n,value:t}),"DEFAULT_ENTRY_HANDLER"),x=i((n,t=le)=>n?Object.entries(n).map(([e,r])=>t(e,r)):[],"mapEntries");var b=i((n,t)=>{if(!n||typeof n!="object")return t;if(!t||typeof t!="object")return n;for(let[e,r]of Object.entries(t))typeof r=="object"&&typeof n[e]=="object"?Array.isArray(n[e])?n[e]=r:n[e]=b(n[e],r):n[e]=r;return n},"mergeObject");var O=i(n=>{if(n==="")return"";if(n==="true")return!0;if(n==="false")return!1;if(n==="0")return 0;if(n==="1")return 1;if(n&&"1234567890+-".includes(n[0])&&n.length<=17){let t=+n;return Number.isNaN(t)?n:t}if(n==="null")return null;if(n!=="undefined")return n},"scalarParse");var ue=/&#?[0-9a-zA-Z]{2,5};/g,me={amp:"&",gt:">",lt:"<",quot:'"',nbsp:" "},he=i(n=>{let t=n.slice(1,-1);if(t[0]!=="#")return me[t]||" ";let e=t.slice(1),r=e[0]==="x"||e[0]==="X"?parseInt(e.slice(1),16):parseInt(e,10);return Number.isFinite(r)?String.fromCharCode(r):" "},"FN_XML_ENTITY"),kt=i(n=>String(n??"").replaceAll(ue,he),"decodeXmlEntities"),de=i((n,t='"',e=t)=>n[0]===t&&n[n.length-1]===e?n.slice(1,-1):n,"skipQuotes"),it=/([a-zA-Z][a-zA-Z0-9-:$]*)(="[^"]*")?/g,Dt=/^\s*$/,ge=/<!--((?!-->)[\s\S])*-->/g,G=/(<)(\/?)([a-z][a-z0-9\-_:.]*)((?:\s+[a-zA-Z][a-z0-9-:$]*(?:="[^"]*")?)*)\s*(\/?)>/gi,ye={img:1,input:1,br:1,hr:1,col:1,source:1},Ce="Text",Xt=i((n,t,e)=>{let r={tag:t,id:e};return(n.nodes??=[]).push(r),r},"addNode"),_e=i((n,t)=>{if(t){n.attrs={},it.lastIndex=0;for(let e=it.exec(t);e;e=it.exec(t)){let r=e[2]?O(kt(de(e[2].slice(1)))):!0;n.attrs[e[1]]=r}}},"parseAttrs"),at=i(n=>{let t=0,e=[{tag:"#root",id:String(t)}],r=String(n).trim().replace(ge,""),s=0;G.lastIndex=0;for(let o=G.exec(r);o;o=G.exec(r)){let a=o.index&&r.slice(s,o.index);if(o[2]){if(a&&!e[0].nodes?.length&&(a===" "||!a.match(Dt))&&(e[0].text=kt(a.trim())),e[0].tag!==o[3])throw new Error(` XML Parse closing tag does not match at: ${String(o.index)} near ${o.input.slice(Math.max(o.index-150,0),o.index)}^^^^${o.input.slice(o.index,Math.min(o.index+150,o.input.length))}`);e.shift()}else{if(a&&!a.match(Dt)){let c=Xt(e[0],Ce,`T${String(++t)}`);c.attrs={text:a}}let p=Xt(e[0],o[3],`X${String(++t)}`);if(_e(p,o[4].trim()),!(o[5]||o[3]in ye)&&(e.unshift(p),e.length===1))throw new Error(`Parse error at: ${o[0]}`)}s=G.lastIndex}return e[0].nodes??[]},"xmlParse");function Ht(n,t){t.__stateChanged?t.__stateChanged(n):n.forEach((e,r)=>{t[r]=e})}i(Ht,"applyStateChangedToImpl");var jt=i(n=>typeof n=="object"?Array.isArray(n)?n.length?`[${jt(n[0])??""} x${String(n.length)}]`:"[]":`{${Object.keys(n).toString()}}`:n??"","attributesToString"),Ne=i(n=>{if(!n)return"";let t=[];return Object.entries(n).forEach(([e,r])=>{r!=null&&e[0]!=="$"&&t.push(` ${e}="${jt(r)}"`)}),t.length?t.join(""):""},"stringifyState"),ct=i((n,t="")=>{let{uid:e,displayName:r=e,$component:s,children:o}=n,a=o?.size?[...o.values()].map(p=>ct(p,` ${t}`)).join(`
|
|
2
|
+
`):"";return`${t}<${r}${Ne(s)}${a?`>
|
|
3
3
|
${a}
|
|
4
|
-
${t}</${n}>`:"/>"}`},"stringify");var ct={};Rt(ct,{HASH_SYMBOL:()=>y,asyncValueCall:()=>_,capitalize:()=>K,defineObjectHashCodeProperty:()=>P,defineObjectRef:()=>it,hashCodeOf:()=>C,isEquals:()=>w,mapEntries:()=>I,mergeObject:()=>b,scalarParse:()=>O,stringHashCode:()=>h,xmlParse:()=>D});function _(r,t){return r instanceof Promise?r.then(t):t(r)}i(_,"asyncValueCall");var pe=i(r=>r==null?"":String(r),"str");function K(r){let t=pe(r);return t.length?t[0].toUpperCase()+t.slice(1):""}i(K,"capitalize");function it(r,t,e){return Object.defineProperty(r,t,{get(){return e},enumerable:!1,configurable:!1}),r}i(it,"defineObjectRef");var E=i(()=>Math.floor((1+Math.random())*65536).toString(16).substring(1),"s4"),ce=i(()=>`${E()}${E()}-${E()}-${E()}-${E()}-${E()}${E()}${E()}`,"guid"),y=Symbol("HASH_SYMBOL"),Ot=new Map([["",at("__empty__")]]),Dt=new Map([[void 0,h("__undefined__")],[null,h("__null__")],["",h("__empty__")],[NaN,h("__NaN__")],[!1,h("__false__")],[!0,h("__true__")]]),x={Object:h("__Object__"),Date:h("__Date__"),Array:h("__Array__"),Map:h("__Map__"),Set:h("__Set__")};function at(r){let t=-2128831035;for(let e=0;e<r.length;e++)t^=r.charCodeAt(e),t=Math.imul(t,16777619);return t|0}i(at,"__stringHashCode");function g(r,t){return Math.imul(t^r,16777619)|0}i(g,"numberHashCode");function h(r){let t=Ot.get(r);if(t)return t;let e=at(r);return Ot.set(r,e),e}i(h,"stringHashCode");function P(r,t){if(!r||Object.hasOwn(r,y))return r;let e=t??at(ce());return Object.defineProperty(r,y,{get(){return e},configurable:!1,enumerable:!1}),r}i(P,"defineObjectHashCodeProperty");function fe(r,t){if(t>10)return-1;let e=t+1,n=0;if(r instanceof Map){n=g(x.Map,n);for(let[s,o]of r)n=g(h(s),n),n=g(x.Map,n),n=g(C(o,e),n)}else if(r instanceof Set){n=g(x.Set,n);for(let s of r)n=g(C(s,e),n)}else if(Array.isArray(r)){n=g(x.Array,n);for(let s of r)n=g(C(s,e),n)}else{n=g(x.Object,n);for(let s in r)Object.hasOwn(r,s)&&s[0]!=="$"&&(n=g(h(s),n),n=g(x.Object,n),n=g(C(r[s],e),n))}return n}i(fe,"containerHashCode");var C=i((r,t=0)=>Dt.has(r)?Dt.get(r):typeof r=="string"?h(r):typeof r=="number"?r:typeof r=="bigint"?h(r.toString(16)):typeof r=="symbol"?h(r.description??r.toString()):typeof r=="function"?P(r)[y]:y in r?r[y]:r instanceof Date?g(r.getTime(),x.Date):r instanceof Promise?P(r)[y]:fe(r,t),"hashCodeOf");function w(r,t,e=0){if(Number.isNaN(r))return!1;if(r===null||typeof r!="object")return r===t;if(t===null||typeof t!="object")return!1;if(y in r&&y in t)return r[y]===t[y];if(e>10)return!0;let n=e+1;if(Array.isArray(r)){if(!Array.isArray(t)||r.length!==t.length)return!1;for(let o=0;o<r.length;o++)if(!w(r[o],t[o],n))return!1;return!0}if(r instanceof Map){if(!(t instanceof Map)||r.size!==t.size)return!1;for(let[o,a]of r){let p=t.get(o);if(p===void 0&&!t.has(o)||!w(a,p,n))return!1}return!0}if(r instanceof Set){if(!(t instanceof Set)||r.size!==t.size)return!1;for(let o of r)if(!t.has(o))return!1;return!0}if(Array.isArray(t)||t instanceof Map||t instanceof Set)return!1;if(r instanceof Date||t instanceof Date)return r instanceof Date&&t instanceof Date&&r.getTime()===t.getTime();let s=0;for(let o in r)if(!(o[0]==="$"||!Object.hasOwn(r,o))&&(s++,!Object.hasOwn(t,o)||!w(r[o],t[o],n)))return!1;for(let o in t)if(o[0]!=="$"&&Object.hasOwn(t,o)&&--s<0)return!1;return s===0}i(w,"isEquals");var le=i((r,t)=>({id:r,value:t}),"DEFAULT_ENTRY_HANDLER"),I=i((r,t=le)=>r?Object.entries(r).map(([e,n])=>t(e,n)):[],"mapEntries");var b=i((r,t)=>{if(!r||typeof r!="object")return t;if(!t||typeof t!="object")return r;for(let[e,n]of Object.entries(t))typeof n=="object"&&typeof r[e]=="object"?Array.isArray(r[e])?r[e]=n:r[e]=b(r[e],n):r[e]=n;return r},"mergeObject");var O=i(r=>{if(r==="")return"";if(r==="true")return!0;if(r==="false")return!1;if(r==="0")return 0;if(r==="1")return 1;if(r&&"1234567890+-".includes(r[0])&&r.length<=17){let t=+r;return Number.isNaN(t)?r:t}if(r==="null")return null;if(r!=="undefined")return r},"scalarParse");var me=/&#?[0-9a-zA-Z]{2,5};/g,ue={amp:"&",gt:">",lt:"<",quot:'"',nbsp:" "},he=i(r=>{let t=r.slice(1,-1);if(t[0]!=="#")return ue[t]||" ";let e=t.slice(1),n=e[0]==="x"||e[0]==="X"?parseInt(e.slice(1),16):parseInt(e,10);return Number.isFinite(n)?String.fromCharCode(n):" "},"FN_XML_ENTITY"),Ht=i(r=>String(r??"").replaceAll(me,he),"decodeXmlEntities"),de=i((r,t='"',e=t)=>r[0]===t&&r[r.length-1]===e?r.slice(1,-1):r,"skipQuotes"),pt=/([a-zA-Z][a-zA-Z0-9-:$]*)(="[^"]*")?/g,Xt=/^\s*$/,ge=/<!--((?!-->)[\s\S])*-->/g,Y=/(<)(\/?)([a-z][a-z0-9\-_:.]*)((?:\s+[a-zA-Z][a-z0-9-:$]*(?:="[^"]*")?)*)\s*(\/?)>/gi,ye={img:1,input:1,br:1,hr:1,col:1,source:1},Ce="Text",kt=i((r,t,e)=>{let n={tag:t,id:e};return(r.nodes??=[]).push(n),n},"addNode"),_e=i((r,t)=>{if(t){r.attrs={},pt.lastIndex=0;for(let e=pt.exec(t);e;e=pt.exec(t)){let n=e[2]?O(Ht(de(e[2].slice(1)))):!0;r.attrs[e[1]]=n}}},"parseAttrs"),D=i(r=>{let t=0,e=[{tag:"#root",id:String(t)}],n=String(r).trim().replace(ge,""),s=0;Y.lastIndex=0;for(let o=Y.exec(n);o;o=Y.exec(n)){let a=o.index&&n.slice(s,o.index);if(o[2]){if(a&&!e[0].nodes?.length&&(a===" "||!a.match(Xt))&&(e[0].text=Ht(a.trim())),e[0].tag!==o[3])throw new Error(` XML Parse closing tag does not match at: ${String(o.index)} near ${o.input.slice(Math.max(o.index-150,0),o.index)}^^^^${o.input.slice(o.index,Math.min(o.index+150,o.input.length))}`);e.shift()}else{if(a&&!a.match(Xt)){let c=kt(e[0],Ce,`T${String(++t)}`);c.attrs={text:a}}let p=kt(e[0],o[3],`X${String(++t)}`);if(_e(p,o[4].trim()),!(o[5]||o[3]in ye)&&(e.unshift(p),e.length===1))throw new Error(`Parse error at: ${o[0]}`)}s=Y.lastIndex}return e[0].nodes??[]},"xmlParse");function jt(r,t,e,n){let s,o,a=0;Object.defineProperty(r,t,{get(){let p=n?.length?n.map(l=>r.get(l)):[],c=p.some(l=>l instanceof Promise),f=i(l=>{let N=l.map(d=>C(d));return(!s||N.some((d,T)=>d!==s[T]))&&(s=N,o=e.apply(r,l)),o},"functor");return c?(a++,new Promise((l,N)=>{Promise.all(p.map(d=>d instanceof Promise?d:Promise.resolve(d))).then(f).then((d=>T=>{d===a&&l(T)})(a)).catch(d=>{N(d)})})):f(p)}})}i(jt,"defineCalculatedProperty");var Z="$$$ARRMATURA";var A=class{static{i(this,"Component")}name;get $$(){return this[Z]}get $uid(){return this.$$.uid}get $parentComponent(){return this.$$.parent?.$component}get refId(){return this.$$.refId}get platform(){return this.$$.platform}__init(){}get(t){return this.$$.get(t)}up(t){return this.$$.up(t)}touch(){return this.$$.touch()}getComponentByRef(t){return this.$$.getByRef(t)?.$component}emit(t,e={}){return this.$$.emit(t,e)}subscribeTo(t,e){return this.$$.subscribeTo(t,e)}defer(t){this.$$.defer(t)}__defineCalculatedProperty(t,e,n){jt(this,t,e,n)}__defineCalculatedProperties(t){Object.entries(t).forEach(([e,n])=>{let[s,o]=e.split("("),a=o?.slice(0,-1).split(",").map(p=>p.trim());this.__defineCalculatedProperty(s,n,a)})}log(t,...e){return this.$$.log(t,...e),t}logError(t,...e){return this.$$.logError(t,...e),t}toString(){return`${this.$$.toString()}${this.name?`(${this.name})`:""}`}};var X="outer$",vt=new Map,Ne=[],ft=0,m=class{constructor(t,e,n,s){this.platform=t;this.manifest=e;this.__parent=n;P(this),this.scope=s??this,this.root=s?.root??this;let o=this.createComponent();P(o),it(o,Z,this),this.$component=o,this.refId&&this.scope.addReference(this.refId,this)}platform;manifest;__parent;static{i(this,"Arrmatron")}$component;root;scope;__children;__propCache;__localScope;__isDone=!1;__isInited=!1;__fprints={};__listeners;__defered=[];__propFnMap;#t;#e=10;#r;get parent(){return this.__parent}get uid(){return this.manifest.uid}get hashCode(){return C(this)}get refId(){return this.manifest.refId}get displayName(){return`\u{1F539}${this.manifest.tag}`}createComponent(){return new A}up(t,e=!1){if(!t||this.__isDone)return;if(this.#r){Object.assign(this.#r,t);return}if(t instanceof Promise){this.platform.applyAsyncValue(`${this.hashCode}:set`,t,s=>this.up(s));return}let n=new Map;Object.entries(t).forEach(([s,o])=>{if(o instanceof Promise){let a=!s||s.startsWith("...");this.platform.applyAsyncValue(`${this.hashCode}:set:${s}`,o,p=>{this.up(a?p:{[s]:p})});return}!s||s[0]==="$"||(!(s in this.__fprints)||!w(this.__fprints[s],o))&&(this.__fprints[s]=o,n.set(s,o),this.__propCache?.delete(s))}),(n.size||e)&&(Tt(n,this.$component),this.#e&&(this.#e--,this.touch(),this.#e++))}get(t){if(!t)return null;let e,n;if(t.indexOf(".")===-1)e=t,n=Ne;else{let l=vt.get(t);l||(l=t.split("."),vt.set(t,l)),[e,...n]=l}let s=n.length===0;if(s){if(this.__propCache?.has(t))return this.__propCache.get(t)}else this.log("ERROR: Nested key",t);let o=this.__propFnMap??=new Map;if(o.has(t)){let l=o.get(t)();return s&&(this.__propCache??=new Map).set(t,l),l}let a=null,p=this.$component,c=p[t];if(c&&typeof c=="function"){let l=c.bind(p);a=i(()=>l,"fn")}else if(t==="This")a=i(()=>this.$component,"fn");else if(e==="R"){let l=this.platform.getResource(n)??null;a=i(()=>l,"fn")}else if(`get${K(e)}`in p){let l=p[`get${K(e)}`],N=typeof l=="function"?()=>l.call(p)??null:()=>p[e]??null;a=n.length?()=>n.reduce((d,T)=>d?.[T]??null,N()):N}else if(p.__getStateProperty)a=i(()=>p.__getStateProperty?.(t),"fn");else{let l=i(()=>p[e]??null,"fn0");a=n.length?()=>n.reduce((N,d)=>N?.[d]??null,l()):l}o.set(t,a);let f=a();return s&&(this.__propCache??(this.__propCache=new Map)).set(t,f),f}putInLocalScope(t,e){(this.__localScope??(this.__localScope=new Map)).set(t,e)}getFromScope(t){return t.startsWith(X)?this.__localScope?.get(t):this.scope.get(t)}notify(){this.__listeners?.forEach(t=>{try{t(this)}catch(e){this.logError("Notification:",e)}})}addListener(t){this.__listeners??=new Set;let e=this.__listeners;return e.add(t),()=>{e.delete(t)}}subscribeTo(t,e){let n=typeof t=="string"?this.getByRef(t):t;if(!n)throw new Error(`No such reference: ${t}`);this.defer(n.addListener(e))}emit(t,...e){if(!this.__isDone)try{if(t.endsWith(")")){let[n,s]=t.split("(")[0].split(".");s||(s=n,n="This");let o=this.getByRef(n);if(!o)throw new Error(`No such reference: ${n}`);let a=o.$component,p=a[s];if(typeof p!="function")throw new Error(`Not a method: ${n}.${s}()`);return e.length>1?p.apply(a,e):this.platform.applyAsyncValue(`${this.hashCode}:emit:${t}`,e[0],c=>p.call(a,c))}else{let n=e[0],[s,o]=t.split(".");o||(o=s||"*",s="this");let a=this.getByRef(s);if(!a)throw new Error(`No such reference: ${s}`);return a.up(o==="*"?n:{[o]:n})}}catch(n){this.logError(`emit ${t}:`,n)}}touch(){ft++;try{this.__propCache?.clear();let t=this.__isDone?null:this.contentManifests;if(t?.size||this.__children?.size)if(this.__children?.forEach(e=>{t?.has(e.uid)||e.done()}),t?.size){let e=this.__children;this.__children=new Map,t.forEach((n,s)=>{let o=e?.get(s),a=o&&!o?.__isDone?o:n.createArrmatron(this.platform,this,this.scopeForChildren);this.__children?.set(a.uid,a)});for(let n of this.__children.values())n.settle()}else this.__children=this.__children?.size===0?this.__children:new Map;this.__isDone?(this.__defered?.forEach(e=>e(this)),this.__defered=void 0,this.__parent=void 0,this.refId&&this.scope.#t&&delete this.scope.#t[this.refId],this.__listeners=void 0,this.__propFnMap=void 0,this.__propCache=void 0,this.__localScope=void 0):this.notify()}finally{ft--,ft||this.platform.redraw(this,this.root)}}done(){this.__isDone=!0,this.touch()}settle(){if(!this.__isDone)if(this.__isInited){let t=this.manifest.resolveProps(this);this.up(t,!!this.children?.size)}else{if(this.__isInited=!0,this.#r=this.manifest.resolveInitialProps(this),this.manifest.connectors)for(let[e,n]of this.manifest.connectors.entries()){let[s,o]=e.split("."),a=this.parent?.getByRef(s);if(!a){this.logError(`Connect: No such ref: ${s}`);continue}this.defer(a.addListener(()=>{this.platform.applyAsyncValue(`${this.hashCode}:connect:${e}`,a.get(o),p=>n(this,p))})),this.platform.applyAsyncValue(`${this.hashCode}:connect:${e}`,a.get(o),p=>n(this,p))}let t=this.#r;this.#r=null,this.up(t,!0),this.$component.__init?.()}}defer(t){t&&typeof t=="function"&&(this.__defered??=[],this.__defered.push(t))}get children(){return this.__children}get contentManifests(){return this.manifest.getSubNodes(this.platform)}get scopeForChildren(){return this.scope}getByRef(t){if(!t)return;if(t==="this"||t==="This")return this;let e=this.#t?.[t];return e||this.parent?.getByRef(t)}addReference(t,e){this.#t??={},this.#t[t]=e}log(t,...e){return this.platform.log({level:"log",source:`${this.displayName}:${this.uid}`,message:t,params:e}),t}logError(t,...e){return this.platform.log({level:"error",source:`${this.displayName}:${this.uid}`,error:t,message:`${String(t.message||t)}`,params:e}),t}toString(){return ot(this)}};function lt(r,t){let e=[],n=0,s=!1,o="",a=0;for(let c=0;c<r.length;c++){let f=r[c];s?f===o&&(s=!1):f==='"'||f==="'"?(s=!0,o=f):f==="("||f==="["?n++:f===")"||f==="]"?n--:f===t&&n===0&&(e.push(r.slice(a,c).trim()),a=c+1)}let p=r.slice(a).trim();return p&&e.push(p),e}i(lt,"splitTopLevel");var zt=i(()=>!1,"fnFalse"),qt=i(()=>!0,"fnTrue"),Gt=i(()=>null,"fnNull"),Ft=i((r,t)=>r&&t,"fnAnd"),Lt=i((r,t)=>r||t,"fnOr"),Ae=i((r,t)=>r+t,"fnPlus"),Kt=i(()=>{},"fnUndefined"),Ee=i(r=>!r,"fnNot"),$e=i((r,t)=>r===t,"fnEqual"),xe=i((r,t)=>r!==t,"fnNotEqual"),Ut=i((r,t)=>r<t,"fnLessThan"),Ie=i((r,t)=>r<=t,"fnLessThanOrEqual"),Bt=i((r,t)=>r>t,"fnGreaterThan"),Wt=i((r,t)=>r>=t,"fnGreaterThanOrEqual"),Pe=i((r,t)=>r-t,"fnMinus"),we=i((r,t)=>r*t,"fnMultiply"),Se=i((r,t)=>r/t,"fnDivide"),Me=i((r,t)=>r%t,"fnModulo"),Re=i((r,t)=>r**t,"fnExponent"),Te=i((r,t)=>r===t,"fnStrictEqual"),be=i((r,t)=>r??t,"fnCoalesce");var Yt={"&&":Ft,AND:Ft,"||":Lt,OR:Lt,"!":Ee,"==":$e,"===":Te,"!=":xe,"<":Ut,LT:Ut,">":Bt,GT:Bt,GTE:Wt,"<=":Ie,">=":Wt,"+":Ae,"-":Pe,"*":we,"/":Se,"%":Me,"**":Re,"??":be};var Q=class{constructor(t,e){this.ctx=e;this.input=t.trim(),this.length=this.input.length}ctx;static{i(this,"ExpressionParserBase")}input;position=0;length=0;checkIf(t){return this.input.startsWith(t,this.position)}checkIfNum(){return/[0-9+-]/.test(this.input[this.position])}checkExceeded(){this.position!==this.length&&this.throw("Unexpected end of expression")}consumeIf(t){return this.checkIf(t)?(this.position+=t.length,!0):!1}throw(t){throw new Error(`${t} in '${this.input.slice(0,this.position)}<<<<${this.input.slice(this.position)}'`)}consume(t){return this.consumeIf(t)||this.throw(`Expected expression '${t}' at position ${this.position}`),!0}consumeWhitespace(){for(;this.position<this.length&&/\s/.test(this.input[this.position]);)this.position++}parseLeftRight(t,e,n){let s=this[e]();for(let o=0;o<t.length;o++){let a=t[o];if(this.consumeWhitespace(),this.consumeIf(a)){this.consumeWhitespace();let p=this[n](),c=Yt[a];return{type:a,left:s,right:p,fn:i((f,l)=>c(s.fn(f,l),p.fn(f,l)),"fn")}}}return s}parseString(){let t=this.input[this.position],e="";for(this.position++;this.position<this.input.length&&this.input[this.position]!==t;)e+=this.input[this.position],this.position++;return this.input[this.position]===t&&this.position++,{type:"String",value:e,fn:i(()=>e,"fn")}}parseNumber(){let t="";for(this.position<this.input.length&&/[0-9.+-]/.test(this.input[this.position])&&(t+=this.input[this.position],this.position++);this.position<this.input.length&&/[0-9.]/.test(this.input[this.position]);)t+=this.input[this.position],this.position++;let e=parseFloat(t);return{type:"Number",value:e,fn:i(()=>e,"fn")}}parseIdentifier(){let t="";for(;this.position<this.input.length&&/[a-zA-Z0-9_$-]/.test(this.input[this.position]);)t+=this.input[this.position],this.position++;return t==="it"||t==="event"?{type:"Event",name:t,fn:i((e,n)=>n,"fn")}:t.startsWith("R.")?{type:"Resource",name:t,fn:i(e=>this.ctx.resolveIdentifier(e,t),"fn")}:(this.ctx.propNames.add(t),{type:"Identifier",name:t,fn:i(e=>this.ctx.resolveIdentifier(e,t),"fn")})}};var S=class extends Q{static{i(this,"ExpressionParser")}parse(){let t=this.parsePipesExpression(this.parseExpression());return this.checkExceeded(),t}parsePipesExpression(t){if(this.consumeIf("|")){this.consumeWhitespace();let e=this.parseIdentifier().name;this.consumeWhitespace();let n=[];for(;this.consumeIf(":");)this.consumeWhitespace(),n.push(this.parseExpression());return this.parsePipesExpression({type:"Pipe",args:n,pipeId:e,from:t,fn:i((s,o)=>{let a=this.ctx.getFunction(s,e);a||s.logError(`Undefined pipe function:${e}`);let p=t.fn(s,o);return _(p,c=>a?.call(s,c,...n.map(f=>f.fn(s,o))))},"fn")})}return t}parseExpression(){let t=this.parseTernary();return this.consumeWhitespace(),t}parseTernary(){let t=this.parseCoalesce();if(this.consumeIf("?")){this.consumeWhitespace();let e=this.parseExpression(),n;return this.consumeIf(":")&&(this.consumeWhitespace(),n=this.parseExpression()),{type:"Ternary",condition:t,trueExpr:e,falseExpr:n,fn:i((s,o)=>t.fn(s,o)?e.fn(s,o):n?n.fn(s,o):void 0,"fn")}}return t}parseCoalesce(){return this.parseLeftRight(["??"],"parseOr","parseCoalesce")}parseOr(){return this.parseLeftRight(["||","OR"],"parseAnd","parseOr")}parseAnd(){return this.parseLeftRight(["&&","AND"],"parseCompare","parseAnd")}parseCompare(){return this.parseLeftRight(["===","==","!="],"parseEquality","parseEquality")}parseEquality(){return this.parseLeftRight([">=",">","GTE","GT","<=","<","LT"],"parsePlus","parsePlus")}parsePlus(){return this.parseLeftRight(["+","-"],"parseMulti","parsePlus")}parseMulti(){return this.parseLeftRight(["*","/","%"],"parseUnary","parseMulti")}parseUnary(){if(this.consumeIf("!")){let t=this.parseUnary();return{type:"Not",expr:t,fn:i((e,n)=>!t.fn(e,n),"fn")}}return this.parsePrimary()}parsePrimary(){if(this.consumeIf("(")){this.consumeWhitespace();let t=this.parseExpression();return this.consume(")"),this.parsePropertyAccess(t)}return this.consumeIf("true")?{type:"Boolean",value:!0,fn:qt}:this.consumeIf("false")?{type:"Boolean",value:!1,fn:zt}:this.consumeIf("null")?{type:"Null",fn:Gt}:this.consumeIf("undefined")?{type:"Undefined",fn:Kt}:this.checkIf("'")||this.checkIf('"')?this.parseString():this.checkIfNum()?this.parseNumber():this.parsePropertyAccess(this.parseIdentifier())}parsePropertyAccess(t){if(this.consumeWhitespace(),this.consumeIf(".")){let e=this.parseIdentifier();return this.parsePropertyAccess({type:"PropertyAccess",object:t,property:e.name,fn:i((n,s)=>t.fn(n,s)?.[e.name],"fn")})}if(this.consumeIf("(")){this.consumeWhitespace();let e=t.name,n=[];if(!this.consumeIf(")")){for(n.push(this.parseExpression());this.consumeIf(",");)this.consumeWhitespace(),n.push(this.parseExpression());this.consumeWhitespace(),this.consume(")")}return this.parsePropertyAccess({type:"Function",args:n,pipeId:e,fn:i((s,o)=>{if(!e)return s.logError(`Empty pipe function: ${e}`),n[0]?.fn(s,o);let a=this.ctx.getFunction(s,e);return a||s.logError(`Undefined pipe function: ${e}`),a?.apply(s,n.map(p=>p.fn(s,o)))},"fn")})}if(this.consumeIf("[")){this.consumeWhitespace();let e=this.parseExpression();return this.consumeWhitespace(),this.consume("]"),this.parsePropertyAccess({type:"ComputedPropertyAccess",object:t,property:e,fn:i((n,s)=>t.fn(n,s)?.[e.fn(n,s)],"fn")})}return t}};var Zt=new Map,Oe=1,De=i((r,t)=>t,"identityFunc"),Xe={$RefProp:i(r=>(t,e)=>r.getByRef(t)?.get(e),"$RefProp")},M=class r{static{i(this,"Expression")}static from(t){let e=Zt.get(t);if(e)return e;let n=new r,s=t.replaceAll(/@(\w+)\.(\w+)/g,o=>{let a=`${X}C${Oe++}`;return n.connectedPropsNames.set(a,o.slice(1)),a});try{let o=new S(s,n).parse();n.functor=o.fn}catch(o){throw console.error(`Expression: ${t}`,o),o}return Zt.set(t,n),n}functor=De;connectedPropsNames=new Map;propNames=new Set;resolveIdentifier(t,e){return t.getFromScope(e)}getFunction(t,e){return e[0]==="$"?Xe[e](t):t.platform.getFunction(e)}};function R(r){let t=new M;try{let e=new S(r,t).parse();t.functor=e.fn}catch(e){throw console.error(`Expression: ${r}`,e),e}return t}i(R,"compilePlaceholder");function Qt(r,t){r.startsWith("@")&&(r=r.slice(1));let e=r.indexOf("="),n=r.indexOf("(");if(e>0&&(n===-1||e<n)){let s=r.slice(0,e).trim();r=r.slice(e+1).replaceAll(/@(\w+)\.(\w+)/g,(a,p,c)=>`$RefProp('${p}', '${c}')`);let o=R(r).functor;return a=>p=>a.scope?.emit(s,o(a,p))}if(n>0){let s=`${r.slice(0,n)}()`,o=r.slice(n+1,-1).trim();if(o=o.replaceAll(/@(\w+)\.(\w+)/g,(p,c,f)=>`$RefProp('${c}', '${f}')`),!o)return p=>c=>p.scope?.emit(s,c);let a=lt(o,",").map(p=>R(p).functor);return p=>c=>p.scope?.emit(s,...a.map(f=>f(p,c)))}return r=r.trim(),s=>o=>s.scope?.emit(r,o)}i(Qt,"compileSingleExpression");function Jt(r,t){let e=lt(r,";").filter(Boolean);if(e.length<=1)return Qt(e[0]??r,t);let n=e.map(s=>Qt(s,t));return s=>async o=>{for(let a of n)await a(s)(o)}}i(Jt,"compileEmitterExpression");var ke=i(r=>r==null?"":String(r),"str"),He=/\{([^}]+)\}/g,Vt="{$$$}",mt=new Map;function je(r,t){let e=[],n=r.replace(He,(a,p)=>(e.push(t(p.trim())),Vt));if(!e.length)return()=>n;let s=n.split(Vt),o=s.pop();return(...a)=>s.map((p,c)=>`${p}${ke(e[c](...a))}`).join("")+o}i(je,"createStringInterpolator");function ve(r){let t=O(r);return()=>t}i(ve,"compileConstant");function Fe(r){if(typeof r!="string")return()=>r;if(r.includes("{")){let t=r.slice(1,-1);return r[0]==="{"&&r.at(-1)==="}"&&!t.includes("{")?R(t).functor:je(r,e=>R(e).functor)}return ve(r)}i(Fe,"_resolveExpression");var J=i(r=>mt.has(r)?mt.get(r):mt.set(r,Fe(r)).get(r),"resolveExpression");var Le=1;function V(r){let t={};return r=r.replaceAll(/@(\w+)\.(\w+)/g,n=>{let s=X+Le++;return t[s]=n.slice(1),s}),{expr:J(r),props:Object.entries(t)}}i(V,"prepareConnectedProps");var te=1;var u=class{static{i(this,"ManifestNode")}$content;uid;refId;propertyResolvers=[];initialState={};connectors;tag;constructor(t){this.uid=`N${String(te++)}:${t}`}createArrmatron(t,e,n){return new this.EntitronConstructor(t,this,e,n)}getSubNodes(t){return this.$content}bindExpression(t,e){let{functor:n,connectedPropsNames:s,propNames:o}=M.from(t);if(s?.size)for(let[a,p]of s.entries())this.addConnector(p,(c,f)=>{c.putInLocalScope(a,f),c.up(e(n(c)))});o?.size&&this.propertyResolvers.push((a,p)=>(Object.assign(p,e(n(a))),p))}addConnectedPropertyResolver(t,e){let{expr:n,props:s}=V(t);s.forEach(([o,a])=>{this.addConnector(a,(p,c)=>(p.putInLocalScope(o,c),_(n(p),f=>{p.up({[e]:f})})))}),this.propertyResolvers.push((o,a)=>(a[e]=n(o),a))}addConnectedDataPropertyResolver(t,e){if(typeof t!="string")this.addDataPropertyResolver(J(t),e);else{let{expr:n,props:s}=V(t);s.forEach(([o,a])=>{this.addConnector(a,(p,c)=>(p.putInLocalScope(o,c),_(n(p),f=>{p.up({data:{...p.get("data"),[e]:f}})})))}),this.addDataPropertyResolver(n,e)}}addDataPropertyResolver(t,e){this.propertyResolvers.push((n,s)=>{let o=t(n);return s.data=Object.assign(s.data||{},{[e]:o}),s})}addConnectedPropertiesResolver(t){let{expr:e,props:n}=V(t);n.forEach(([s,o])=>{this.addConnector(o,(a,p)=>(a.putInLocalScope(s,p),_(e(a),c=>{let f=a.$$propKeys??(a.$$propKeys={});Object.keys(c??{}).forEach(l=>f[l]=null),a.up({...f,...c})})))}),this.propertyResolvers.push((s,o)=>{let a=e(s);if(a&&typeof a=="object"){let p=s.$$propKeys??(s.$$propKeys={});Object.keys(p).forEach(c=>o[c]=null),Object.entries(a).forEach(([c,f])=>{p[c]=null,o[c]=f})}return o})}addConnector(t,e){let n=this.connectors??(this.connectors=new Map),[s,o]=t.trim().split("."),a=`${s}.${o||"This"}.${te++}`;n.set(a,e)}resolveInitialProps(t){let e=Object.entries(this.initialState).reduce((n,[s,o])=>(n[s]=o(t),n),{});return this.resolveProps(t,e)}resolveProps(t,e={}){return this.propertyResolvers.reduce((n,s)=>s(t,n),e)}compileAttribute(t,e){if(t.startsWith("data-")&&t!=="data-theme")this.addConnectedDataPropertyResolver(e,t.slice(5));else if(t==="Ref")this.refId=String(e);else if(t==="Props")this.addConnectedPropertiesResolver(String(e));else if(typeof e!="string")this.initialState[t]=()=>e;else if(e[0]==="'"&&e.at(-1)==="'"){let n=e.slice(1,-1);this.initialState[t]=()=>n}else if(e.includes("{"))this.addConnectedPropertyResolver(e,t);else if(e.startsWith("@")){let[n,s]=e.slice(1).trim().split(".");s?this.bindExpression(e,o=>({[t]:o})):this.initialState[t]=o=>o.getByRef(n)?.$component}else e.startsWith("->")?this.initialState[t]=Jt(e.slice(2).trim(),this):this.initialState[t]=()=>e}compileAttributes(t){t&&Object.entries(t).forEach(e=>this.compileAttribute(...e))}};var ut=class extends m{static{i(this,"Block")}get displayName(){return`\u{1F4A0}${this.manifest.tag}`}get contentManifests(){let t=this.get("Nodes")??[];return this.platform.getCompiledNodes(t)}},k=class extends u{static{i(this,"CBlockNode")}constructor({id:t,attrs:e}){super(t+(e?.Ref?`:${e?.Ref}`:"")),this.compileAttributes(e)}get EntitronConstructor(){return ut}};var ht=class extends m{static{i(this,"Composite")}get displayName(){return`\u{1F4A0}${this.manifest.tag}`}get scopeForChildren(){return this}slotContent(t){return this.manifest.getSlotContent(this.platform,t)}createComponent(){return this.platform.createComponent(this.manifest.tag)}},H=class extends u{static{i(this,"CCompositeNode")}slotContent=null;tag;nodes;constructor({id:t,tag:e,attrs:n,nodes:s}){super(t+(n?.Ref?`:${n?.Ref}`:"")),this.tag=e,this.nodes=s,this.compileAttributes(n)}getSlotContent(t,e){if(!this.slotContent){let n=this.nodes?.reduce((s,o)=>{if(o){let a=String(o.attrs?.Slot??"default");s[a]=(s[a]||[]).concat(o)}return s},{});this.slotContent=Object.entries(n??{}).reduce((s,[o,a])=>(s[o]=t.getCompiledNodes(a),s),{})}return this.slotContent[e||"default"]??void 0}getSubNodes(t){return t.getCompiledNodes(this.tag)}get EntitronConstructor(){return ht}};var dt=class extends m{static{i(this,"Conditional")}get contentManifests(){return this.ifCondition?this.ifBranches.thenBlock:this.ifBranches.elseBlock}get ifCondition(){return this.$component.condition}get ifBranches(){return this.manifest.getBranches(this.platform)}get displayName(){return`\u{1F539}if:${this.manifest.expr}`}},j=class extends u{static{i(this,"CIfNode")}#t;#e;expr;constructor(t,e){super(t.id),this.#t=t,this.expr=e,this.compileCondition(e)}get EntitronConstructor(){return dt}getBranches(t){if(this.#e)return this.#e;this.#e={};let{nodes:e}=this.#t,n=[this.#t];if(e?.length){let s=e.find(a=>a.tag==="Else"),o=e.find(a=>a.tag==="Then");s?(this.#e.elseBlock=s.nodes?t.getCompiledNodes(s.nodes):void 0,n=o?o.nodes:[{...this.#t,nodes:e.filter(a=>a!==s)}]):o&&(n=o.nodes)}return this.#e.thenBlock=n?t.getCompiledNodes(n):void 0,this.#e}compileCondition(t){if(t.startsWith("Slot(")){let e=t.slice(5,-1);this.propertyResolvers.push((n,s)=>(s.condition=!!n.scope.slotContent?.(e)?.size,s))}else t[0]==="{"&&t[t.length-1]==="}"&&(t=t.slice(1,-1)),this.bindExpression(t,e=>({condition:!!e}))}};var gt=class extends A{static{i(this,"DataConnectorComponent")}_data;change;get data(){return this._data}set data(t){this._data=t,_(t,e=>{e!==void 0&&this.change?.(e)})}},yt=class extends A{static{i(this,"TriggerConnectorComponent")}change;_trigger;data;get trigger(){return this._trigger}set trigger(t){this._trigger=t,_(t,e=>{e!==void 0&&_(this.data,n=>{this.change?.(n)})})}},Ct=class extends m{static{i(this,"Connector")}createComponent(){let t=this.manifest.componentClass;return new t}get displayName(){return"\u{1F539}Connector"}},v=class extends u{static{i(this,"ConnectorNode")}componentClass;constructor({attrs:t,id:e}){super(e);let{trigger:n,change:s,...o}=t;this.compileAttributes(n?{change:s,...o,trigger:n}:{change:s,...o}),this.componentClass=n?yt:gt}get EntitronConstructor(){return Ct}};var _t=class extends m{static{i(this,"NativeElementEntitron")}get displayName(){return this.manifest.tag}createComponent(){return this.platform.createComponent({tag:this.manifest.tag,native:!0})}},F=class extends u{static{i(this,"CElementNode")}#t;constructor({id:t,tag:e,attrs:n,nodes:s,text:o}){super(t),this.tag=e,this.compileAttributes(n),o&&this.compileAttribute("#text",o),this.#t=s}getSubNodes(t){return this.#t?t.getCompiledNodes(this.#t):void 0}get EntitronConstructor(){return _t}};var L=class extends u{static{i(this,"CFragmentNode")}#t;constructor({id:t,nodes:e,attrs:n}){super(t),this.#t=e,this.compileAttributes(n)}getSubNodes(t){return this.#t?t.getCompiledNodes(this.#t):void 0}get EntitronConstructor(){return m}};var ee=i(r=>r?typeof r=="string"?r.split(",").map(t=>t.trim()).map(t=>({id:t,name:t})):Array.isArray(r)?r.map(t=>typeof t=="object"?{...t,id:String(t.id??"")}:{id:String(t),name:String(t??"--")}):typeof r[Symbol.iterator]=="function"?[...r]:typeof r=="object"?I(r,(t,e)=>typeof e=="object"?{...e,id:t}:{id:t,name:String(e)}):[{id:String(r),name:String(r)}]:[],"narrowData");var Nt=class extends m{static{i(this,"Iterative")}pkHash={};get displayName(){return`\u{1F7EA}each:${this.manifest.itemName}`}get eachList(){return this.$component.each}get contentManifests(){let t=ee(this.eachList),e=this.manifest.getItemCtxNode(this.platform),n=new Map;return this.pkHash={},t.forEach(s=>{let o=String(s.id||C(s));if(this.pkHash[o]){this.logError(`ERROR: duplicate item id : ${o} (skipped)`,s);return}this.pkHash[o]=s;let a=e.cloneWithDatum(s,this.platform);a.propertyResolvers.push((p,c)=>(c[e.itemName]=this.pkHash[o],c)),n.set(a.uid,a)}),n}},U=class extends u{static{i(this,"CForNode")}#t;itemName;#e;constructor(t,e,n){super(t.id),this.#e=t,this.itemName=e,this.bindExpression(n,s=>({each:s}))}getItemCtxNode(t){return this.#t??=new Et(this.#e.id,this.itemName,t.getCompiledNodes([this.#e])),this.#t}get EntitronConstructor(){return Nt}},At=class extends m{static{i(this,"IterativeItem")}get scopeForChildren(){return this}get displayName(){return`\u{1F7EA}each:item:${this.manifest.itemName}`}emit(t,...e){return this.scope.emit(t,...e)}get(t){let e=this.manifest.itemName;return t.startsWith(`${e}.`)||t===e?super.get(t):this.scope.get(t)}},Et=class r extends u{static{i(this,"CItemNode")}itemName;constructor(t,e,n){super(t),this.itemName=e,this.$content=n}cloneWithDatum(t,e){let n=`${String(this.uid)}#${t.id||C(t)}`,s=new r(n,this.itemName,this.getSubNodes(e));return s.uid=n,s}get EntitronConstructor(){return At}};var $t=class extends m{static{i(this,"DynamicTag")}get displayName(){return"dynamics"}get _dynamicTag(){return this.$component._dynamicTag}get contentManifests(){let t=this._dynamicTag,e=`${this.uid}:${String(t??"")}`,n=this.manifest.getCompiledForTag(this.platform,t);return new Map([[e,Object.assign(n,{uid:e})]])}},B=class extends u{static{i(this,"CDynamicTagNode")}xml;#t=new Map;constructor(t,e){super(t.id),this.compileAttribute("_dynamicTag",e),this.xml=t}getCompiledForTag(t,e){let n=String(e??""),s=this.#t.get(n);return s||(s=t.getCompiledNodes({...this.xml,tag:e}),this.#t.set(n,s)),s}get EntitronConstructor(){return $t}};var xt=class extends m{static{i(this,"Selector")}get displayName(){return"\u{1F4A0}Selector"}get contentManifests(){let t=this.manifest.getCases(this.platform),e=this.$component.On;return t?.[e]??t?.default}},W=class extends u{static{i(this,"CSelectorNode")}cases=null;key="";nodes;constructor({id:t,tag:e,attrs:n,nodes:s}){super(t),this.tag=e,this.nodes=s,this.compileAttributes(n)}getCases(t){return this.cases??(this.cases=(this.nodes??[]).reduce((e,n)=>(e[n.attrs?.When]=t.getCompiledNodes(n.nodes??[]),e),{}))}get EntitronConstructor(){return xt}};var It=class extends m{static{i(this,"Slot")}get displayName(){return"\u{1F538}slot"}getByRef(t){return this.scope?.getByRef(t)}get slotContent(){return this.scope.slotContent(this.manifest.key)}get contentManifests(){return this.slotContent}get scopeForChildren(){return this.scope.scope}},z=class extends u{static{i(this,"CSlotNode")}key;constructor(t){super(t.id),this.key=t.attrs?.Key}get EntitronConstructor(){return It}};var Pt=i((r,t)=>{let{[t]:e,...n}=r.attrs??{};return{text:r.text,tag:r.tag,id:r.id,attrs:n,nodes:r.nodes?.map(s=>s)}},"cloneNode"),Ue=i(r=>{let{tag:t="div",attrs:e}=r;if(e?.Each){let[n,,...s]=String(e.Each).trim().split(" ");return new U(Pt(r,"Each"),n,s.join(" "))}return e?.If?new j(Pt(r,"If"),String(e.If)):t==="div"||t?.[0]?.match(/[A-Z0-9]/)==null?new F(r):t==="Dynamic"?new B(Pt(r,"As"),String(e?.As??"Error.Dynamic")):t==="Slot"?new z(r):t==="Selector"?new W(r):t==="Connector"?new v(r):t==="Fragment"||t==="Then"||t==="Else"?new L(r):t==="Block"?new k(r):new H(r)},"__compileManifestNode"),wt=new Map,tt=i(r=>wt.has(r)?wt.get(r):wt.set(r,Ue(r)).get(r),"compileManifestNode"),et=i(r=>new Map(r?.map(tt).map(t=>[t.uid,t])??[]),"compileManifestNodes");var St=class extends m{static{i(this,"RootCtx")}get displayName(){return"ROOT"}get scopeForChildren(){return this}slotContent(t){}createComponent(){return this.platform.createComponent({})}},$=class extends u{constructor(e){super("R0");this.template=e;this.slotContent={},this.parsed=D(this.template)}template;static{i(this,"CRootNode")}slotContent;nodes;parsed;getSubNodes(e){return e.getCompiledNodes(this.parsed)}getSlotContent(e,n){}get EntitronConstructor(){return St}};var Be=i((r,t)=>{let e=new $(t).createArrmatron(r);return e.touch(),e},"launch");var We=1;function ze(r,t){t({Ctor:r,tag:r.name??Ge(r)})}i(ze,"registerFromFunction");function qe(r,t){r.replaceAll(/<Component\s+id="([^"]+)"(?:[^>]*)>([\s\S]*?)<\/Component>/gm,(e,n,s)=>(s=s.replaceAll(/<Signature\b[^>]*?\/>/gm,"").replaceAll(/<Signature\b[^>]*?>[\s\S]*?<\/Signature>/gm,"").replaceAll(/<Subcomponent\s+id="([^"]+)"(?:[^>]*)>([\s\S]*?)<\/Subcomponent>/gm,(o,a,p)=>(p=p.replaceAll(/<(\/?)This-/gm,(c,f)=>`<${f}${n}-`).trim(),t({tag:`${n}-${a}`,template:p}),"")).replaceAll(/<(\/?)This-/gm,(o,a)=>`<${a}${n}-`).trim(),t({tag:n,template:s}),""))}i(qe,"registerFromString");var Ge=i(r=>(/^function\s+([\w$]+)\s*\(/.exec(r.toString())??[])[1]??`C${String(We++)}`,"fnName");function Mt(r){return t=>{if(!t)return;let e=i(n=>{Array.isArray(n)?n.filter(Boolean).forEach(e):typeof n=="string"?qe(n,r):typeof n=="function"?ze(n,r):n.tag||n.id?r({...n,tag:n.tag??n.id}):I(n,(s,o)=>r({tag:s,template:o}))},"registerType");e(t)}}i(Mt,"createRegisterTypes");var rt=class{constructor(t,e){this.tag=t}tag;static{i(this,"NativeElement")}nodes=[];attrs={};native=!0;__stateChanged(t){Object.assign(this.attrs,Object.fromEntries([...t.entries()]))}getName(){return this.tag}getAttribute(t,e=null){return this.attrs[t]??e}getRequiredAttribute(t){let e=this.getAttribute(t);if(!e)throw new Error(`Required attribute '${t}' missing for ${this.getName()}`);return e}getBooleanAttribute(t,e=!1){let n=this.getAttribute(t,e);return typeof n=="boolean"?n:["true","1","yes","on"].includes(String(n).toLowerCase())}getNumericAttribute(t,e=0){let n=this.getAttribute(t,e);return parseFloat(n)||e}getEnumAttribute(t,e,n){let s=this.getAttribute(t,n);return e.includes(s)?s:n}getTextContent(){return this.attrs["#text"]}getChildren(){return this.nodes}};var nt=class{static{i(this,"Registry")}typeRegistry=new Map;compiledTemplates=new Map;NativeElement=rt;registerTypes(t){Mt(e=>{let n=String(e.tag);this.compiledTemplates.delete(n),this.typeRegistry.set(n,e)})(t)}getByTag(t){let e=this.typeRegistry.get(t);if(e)return e;let n=t.split(".");for(n.pop();n.length;n.pop()){let s=this.typeRegistry.get(n.join("."));if(s)return s}return{tag:t,unknown:!0}}xmlParse(t){try{return D(t)}catch(e){return[{tag:"div",text:String(e),id:"error"}]}}getCompiledNodes(t){if(typeof t=="string"){let e=this.compiledTemplates;if(e.has(t))return e.get(t);let n=this.getByTag(t);if(!n?.template)return[];let s=n.template,o=typeof s=="string"?this.xmlParse(s):s,a=et(o);return e.set(t,a),a}return Array.isArray(t)?et(t):tt(t)}createComponent(t){if(typeof t=="string")return this.createComponent(this.getByTag(t));let e=this.NativeElement;try{let{Ctor:n,tag:s,unknown:o,native:a}=t;return a?new e(s??"div",this):n?new n:o?(this.log({level:"info",message:`<-- unknown tag: ${s} -->`,source:"registry"}),new e("div",this)):new A}catch(n){return this.log({level:"error",message:"createComponent failed",error:n,source:"registry"}),new e("div",this)}}log(t){typeof t=="string"?console.log(t):console.log(t.source??"",t.message??"",...t.params??[])}};var q=class extends nt{static{i(this,"Platform")}resources={};constructor(t){super(),this.updateResources(t)}redraw(t,e){}updateResources(t){I(t,(e,n)=>{if(e[0]==="$")return;if(e==="NativeElement"){this.NativeElement=n;return}if(e==="components"){this.registerTypes(n);return}let s=e.split(".");if(s.length>1){let o=s.pop()??"-",a=s.reduce((p,c)=>p[c]??(p[c]={}),this.resources);a[o]=b(a[o],n);return}this.resources[e]=b(this.resources[e],n)})}getResource(t){let[e,...n]=typeof t=="string"?t.split("."):t,{resources:s}=this,o=e?s[e]:s;return!o||n.length===0?o:n.length===1?o[n[0]]:n.reduce((a,p)=>a?a[p]:null,o)}getFunction(t){return ct[t]||this.resources.functions?.[t]}applyAsyncValue(t,e,n){return e instanceof Promise?e.then(s=>n(s)):n(e)}};function st(r,t){if(r)for(let e of r.values()){let n=e.$component;n.native?(st(e.children,n),t.nodes.push(n)):st(e.children,t)}}i(st,"toNativeTree");function Ke(r,{reflow:t=st,rootElement:e={tag:"root",nodes:[]},...n}){let s=new q(n),o=new $(r).createArrmatron(s);return s.redraw=()=>{t(o.children,e)},o.touch(),e}i(Ke,"applyTemplate");0&&(module.exports={CRootNode,Component,Platform,applyTemplate,compileManifestNode,compileManifestNodes,createRegisterTypes,launch});
|
|
4
|
+
${t}</${r}>`:"/>"}`},"stringify");function Ft(n,t,e,r){let s,o,a=0;Object.defineProperty(n,t,{get(){let p=r?.length?r.map(l=>n.get(l)):[],c=p.some(l=>l instanceof Promise),f=i(l=>{let N=l.map(d=>C(d));return(!s||N.some((d,T)=>d!==s[T]))&&(s=N,o=e.apply(n,l)),o},"functor");return c?(a++,new Promise((l,N)=>{Promise.all(p.map(d=>d instanceof Promise?d:Promise.resolve(d))).then(f).then((d=>T=>{d===a&&l(T)})(a)).catch(d=>{N(d)})})):f(p)}})}i(Ft,"defineCalculatedProperty");var Y="$$$ARRMATURA";var A=class{static{i(this,"Component")}name;get $$(){return this[Y]}get $uid(){return this.$$.uid}get $parentComponent(){return this.$$.parent?.$component}get refId(){return this.$$.refId}get platform(){return this.$$.platform}__init(){}get(t){return this.$$.get(t)}up(t){return this.$$.up(t)}touch(){return this.$$.touch()}getComponentByRef(t){return this.$$.getByRef(t)?.$component}emit(t,e={}){return this.$$.emit(t,e)}subscribeTo(t,e){return this.$$.subscribeTo(t,e)}defer(t){this.$$.defer(t)}__defineCalculatedProperty(t,e,r){Ft(this,t,e,r)}__defineCalculatedProperties(t){Object.entries(t).forEach(([e,r])=>{let[s,o]=e.split("("),a=o?.slice(0,-1).split(",").map(p=>p.trim());this.__defineCalculatedProperty(s,r,a)})}log(t,...e){return this.$$.log(t,...e),t}logError(t,...e){return this.$$.logError(t,...e),t}toString(){return`${this.$$.toString()}${this.name?`(${this.name})`:""}`}};var D="outer$",vt=new Map,Ae=[],ft=0,u=class{constructor(t,e,r,s){this.platform=t;this.manifest=e;this.__parent=r;P(this),this.scope=s??this,this.root=s?.root??this;let o=this.createComponent();P(o),st(o,Y,this),this.$component=o,this.refId&&this.scope.addReference(this.refId,this)}platform;manifest;__parent;static{i(this,"Arrmatron")}$component;root;scope;__children;__propCache;__localScope;__isDone=!1;__isInited=!1;__fprints={};__listeners;__defered=[];__propFnMap;#t;#e=10;#n;get parent(){return this.__parent}get uid(){return this.manifest.uid}get hashCode(){return C(this)}get refId(){return this.manifest.refId}get displayName(){return`\u{1F539}${this.manifest.tag}`}createComponent(){return new A}up(t,e=!1){if(!t||this.__isDone)return;if(this.#n){Object.assign(this.#n,t);return}if(t instanceof Promise){this.platform.applyAsyncValue(`${this.hashCode}:set`,t,s=>this.up(s));return}let r=new Map;Object.entries(t).forEach(([s,o])=>{if(o instanceof Promise){let a=!s||s.startsWith("...");this.platform.applyAsyncValue(`${this.hashCode}:set:${s}`,o,p=>{this.up(a?p:{[s]:p})});return}!s||s[0]==="$"||(!(s in this.__fprints)||!w(this.__fprints[s],o))&&(this.__fprints[s]=o,r.set(s,o),this.__propCache?.delete(s))}),(r.size||e)&&(Ht(r,this.$component),this.#e&&(this.#e--,this.touch(),this.#e++))}get(t){if(!t)return null;let e,r;if(t.indexOf(".")===-1)e=t,r=Ae;else{let l=vt.get(t);l||(l=t.split("."),vt.set(t,l)),[e,...r]=l}let s=r.length===0;if(s&&this.__propCache?.has(t))return this.__propCache.get(t);let o=this.__propFnMap??=new Map;if(o.has(t)){let l=o.get(t)();return!s&&l===null&&this.log("ERROR: Nested key",t),s&&(this.__propCache??=new Map).set(t,l),l}let a=null,p=this.$component,c=p[t];if(c&&typeof c=="function"){let l=c.bind(p);a=i(()=>l,"fn")}else if(t==="This")a=i(()=>this.$component,"fn");else if(e==="R"){let l=this.platform.getResource(r)??null;a=i(()=>l,"fn")}else if(`get${q(e)}`in p){let l=p[`get${q(e)}`],N=typeof l=="function"?()=>l.call(p)??null:()=>p[e]??null;a=r.length?()=>r.reduce((d,T)=>d?.[T]??null,N()):N}else if(p.__getStateProperty)a=i(()=>p.__getStateProperty?.(t),"fn");else{let l=i(()=>p[e]??null,"fn0");a=r.length?()=>r.reduce((N,d)=>N?.[d]??null,l()):l}o.set(t,a);let f=a();return!s&&f===null&&this.log("ERROR: Nested key",t),s&&(this.__propCache??(this.__propCache=new Map)).set(t,f),f}putInLocalScope(t,e){(this.__localScope??(this.__localScope=new Map)).set(t,e)}getFromScope(t){return t.startsWith(D)?this.__localScope?.get(t):this.scope.get(t)}notify(){this.__listeners?.forEach(t=>{try{t(this)}catch(e){this.logError("Notification:",e)}})}addListener(t){this.__listeners??=new Set;let e=this.__listeners;return e.add(t),()=>{e.delete(t)}}subscribeTo(t,e){let r=typeof t=="string"?this.getByRef(t):t;if(!r)throw new Error(`No such reference: ${t}`);this.defer(r.addListener(e))}emit(t,...e){if(!this.__isDone)try{if(t.endsWith(")")){let[r,s]=t.split("(")[0].split(".");s||(s=r,r="This");let o=this.getByRef(r);if(!o)throw new Error(`No such reference: ${r}`);let a=o.$component,p=a[s];if(typeof p!="function")throw new Error(`Not a method: ${r}.${s}()`);return e.length>1?p.apply(a,e):this.platform.applyAsyncValue(`${this.hashCode}:emit:${t}`,e[0],c=>p.call(a,c))}else{let r=e[0],[s,o]=t.split(".");o||(o=s||"*",s="this");let a=this.getByRef(s);if(!a)throw new Error(`No such reference: ${s}`);return a.up(o==="*"?r:{[o]:r})}}catch(r){this.logError(`emit ${t}:`,r)}}touch(){ft++;try{this.__propCache?.clear();let t=this.__isDone?null:this.contentManifests;if(t?.size||this.__children?.size)if(this.__children?.forEach(e=>{t?.has(e.uid)||e.done()}),t?.size){let e=this.__children;this.__children=new Map,t.forEach((r,s)=>{let o=e?.get(s),a=o&&!o?.__isDone?o:r.createArrmatron(this.platform,this,this.scopeForChildren);this.__children?.set(a.uid,a)});for(let r of this.__children.values())r.settle()}else this.__children=this.__children?.size===0?this.__children:new Map;this.__isDone?(this.__defered?.forEach(e=>e(this)),this.__defered=void 0,this.__parent=void 0,this.refId&&this.scope.#t&&delete this.scope.#t[this.refId],this.__listeners=void 0,this.__propFnMap=void 0,this.__propCache=void 0,this.__localScope=void 0):this.notify()}finally{ft--,ft||this.platform.redraw(this,this.root)}}done(){this.__isDone=!0,this.touch()}settle(){if(!this.__isDone)if(this.__isInited){let t=this.manifest.resolveProps(this);this.up(t,!!this.children?.size)}else{if(this.__isInited=!0,this.#n=this.manifest.resolveInitialProps(this),this.manifest.connectors)for(let[e,r]of this.manifest.connectors.entries()){let[s,o]=e.split("."),a=this.parent?.getByRef(s);if(!a){this.logError(`Connect: No such ref: ${s}`);continue}this.defer(a.addListener(()=>{this.platform.applyAsyncValue(`${this.hashCode}:connect:${e}`,a.get(o),p=>r(this,p))})),this.platform.applyAsyncValue(`${this.hashCode}:connect:${e}`,a.get(o),p=>r(this,p))}let t=this.#n;this.#n=null,this.up(t,!0),this.$component.__init?.()}}defer(t){t&&typeof t=="function"&&(this.__defered??=[],this.__defered.push(t))}get children(){return this.__children}get contentManifests(){return this.manifest.getSubNodes(this.platform)}get scopeForChildren(){return this.scope}getByRef(t){if(!t)return;if(t==="this"||t==="This")return this;let e=this.#t?.[t];return e||this.parent?.getByRef(t)}addReference(t,e){this.#t??={},this.#t[t]=e}log(t,...e){return this.platform.log({level:"log",source:`${this.displayName}:${this.uid}`,message:t,params:e}),t}logError(t,...e){return this.platform.log({level:"error",source:`${this.displayName}:${this.uid}`,error:t,message:`${String(t.message||t)}`,params:e}),t}toString(){return ct(this)}};function lt(n,t){let e=[],r=0,s=!1,o="",a=0;for(let c=0;c<n.length;c++){let f=n[c];s?f===o&&(s=!1):f==='"'||f==="'"?(s=!0,o=f):f==="("||f==="["?r++:f===")"||f==="]"?r--:f===t&&r===0&&(e.push(n.slice(a,c).trim()),a=c+1)}let p=n.slice(a).trim();return p&&e.push(p),e}i(lt,"splitTopLevel");var Kt=i(()=>!1,"fnFalse"),qt=i(()=>!0,"fnTrue"),Gt=i(()=>null,"fnNull"),Lt=i((n,t)=>n&&t,"fnAnd"),Ut=i((n,t)=>n||t,"fnOr"),Ee=i((n,t)=>n+t,"fnPlus"),Yt=i(()=>{},"fnUndefined"),$e=i(n=>!n,"fnNot"),Ie=i((n,t)=>n===t,"fnEqual"),xe=i((n,t)=>n!==t,"fnNotEqual"),Bt=i((n,t)=>n<t,"fnLessThan"),Pe=i((n,t)=>n<=t,"fnLessThanOrEqual"),Wt=i((n,t)=>n>t,"fnGreaterThan"),zt=i((n,t)=>n>=t,"fnGreaterThanOrEqual"),we=i((n,t)=>n-t,"fnMinus"),Se=i((n,t)=>n*t,"fnMultiply"),Me=i((n,t)=>n/t,"fnDivide"),Re=i((n,t)=>n%t,"fnModulo"),Te=i((n,t)=>n**t,"fnExponent"),be=i((n,t)=>n===t,"fnStrictEqual"),Oe=i((n,t)=>n??t,"fnCoalesce");var Zt={"&&":Lt,AND:Lt,"||":Ut,OR:Ut,"!":$e,"==":Ie,"===":be,"!=":xe,"<":Bt,LT:Bt,">":Wt,GT:Wt,GTE:zt,"<=":Pe,">=":zt,"+":Ee,"-":we,"*":Se,"/":Me,"%":Re,"**":Te,"??":Oe};var ut=/[a-zA-Z0-9_$-]/,Z=class{constructor(t,e){this.ctx=e;this.input=t.trim(),this.length=this.input.length}ctx;static{i(this,"ExpressionParserBase")}input;position=0;length=0;checkIf(t){return this.input.startsWith(t,this.position)}checkIfNum(){return/[0-9+-]/.test(this.input[this.position])}checkExceeded(){this.position!==this.length&&this.throw("Unexpected end of expression")}consumeIf(t){return this.checkIf(t)?(this.position+=t.length,!0):!1}consumeKeyword(t){if(!this.checkIf(t))return!1;let e=this.input[this.position+t.length];return e!==void 0&&ut.test(e)?!1:this.consumeIf(t)}throw(t){throw new Error(`${t} in '${this.input.slice(0,this.position)}<<<<${this.input.slice(this.position)}'`)}consume(t){return this.consumeIf(t)||this.throw(`Expected expression '${t}' at position ${this.position}`),!0}consumeWhitespace(){for(;this.position<this.length&&/\s/.test(this.input[this.position]);)this.position++}parseLeftRight(t,e,r){let s=this[e]();for(let o=0;o<t.length;o++){let a=t[o];if(this.consumeWhitespace(),this.consumeIf(a)){this.consumeWhitespace();let p=this[r](),c=Zt[a];return{type:a,left:s,right:p,fn:i((f,l)=>c(s.fn(f,l),p.fn(f,l)),"fn")}}}return s}parseString(){let t=this.input[this.position],e="";for(this.position++;this.position<this.input.length&&this.input[this.position]!==t;)e+=this.input[this.position],this.position++;return this.input[this.position]===t&&this.position++,{type:"String",value:e,fn:i(()=>e,"fn")}}parseNumber(){let t="";for(this.position<this.input.length&&/[0-9.+-]/.test(this.input[this.position])&&(t+=this.input[this.position],this.position++);this.position<this.input.length&&/[0-9.]/.test(this.input[this.position]);)t+=this.input[this.position],this.position++;let e=parseFloat(t);return{type:"Number",value:e,fn:i(()=>e,"fn")}}parseIdentifier(){let t="";for(;this.position<this.input.length&&ut.test(this.input[this.position]);)t+=this.input[this.position],this.position++;if(t==="it"||t==="event")return{type:"Event",name:t,fn:i((e,r)=>r,"fn")};if(t==="R"&&this.input[this.position]==="."){for(;this.position<this.input.length&&(this.input[this.position]==="."||ut.test(this.input[this.position]));)t+=this.input[this.position],this.position++;return{type:"Resource",name:t,fn:i(e=>this.ctx.resolveIdentifier(e,t),"fn")}}return this.ctx.propNames.add(t),{type:"Identifier",name:t,fn:i(e=>this.ctx.resolveIdentifier(e,t),"fn")}}};var S=class extends Z{static{i(this,"ExpressionParser")}parse(){let t=this.parsePipesExpression(this.parseExpression());return this.checkExceeded(),t}parsePipesExpression(t){if(this.consumeIf("|")){this.consumeWhitespace();let e=this.parseIdentifier().name;this.consumeWhitespace();let r=[];for(;this.consumeIf(":");)this.consumeWhitespace(),r.push(this.parseExpression());return this.parsePipesExpression({type:"Pipe",args:r,pipeId:e,from:t,fn:i((s,o)=>{let a=this.ctx.getFunction(s,e);a||s.logError(`Undefined pipe function:${e}`);let p=t.fn(s,o);return _(p,c=>a?.call(s,c,...r.map(f=>f.fn(s,o))))},"fn")})}return t}parseExpression(){let t=this.parseTernary();return this.consumeWhitespace(),t}parseTernary(){let t=this.parseCoalesce();if(this.consumeIf("?")){this.consumeWhitespace();let e=this.parseExpression(),r;return this.consumeIf(":")&&(this.consumeWhitespace(),r=this.parseExpression()),{type:"Ternary",condition:t,trueExpr:e,falseExpr:r,fn:i((s,o)=>t.fn(s,o)?e.fn(s,o):r?r.fn(s,o):void 0,"fn")}}return t}parseCoalesce(){return this.parseLeftRight(["??"],"parseOr","parseCoalesce")}parseOr(){return this.parseLeftRight(["||","OR"],"parseAnd","parseOr")}parseAnd(){return this.parseLeftRight(["&&","AND"],"parseCompare","parseAnd")}parseCompare(){return this.parseLeftRight(["===","==","!="],"parseEquality","parseEquality")}parseEquality(){return this.parseLeftRight([">=",">","GTE","GT","<=","<","LT"],"parsePlus","parsePlus")}parsePlus(){return this.parseLeftRight(["+","-"],"parseMulti","parsePlus")}parseMulti(){return this.parseLeftRight(["*","/","%"],"parseUnary","parseMulti")}parseUnary(){if(this.consumeIf("!")){let t=this.parseUnary();return{type:"Not",expr:t,fn:i((e,r)=>!t.fn(e,r),"fn")}}return this.parsePrimary()}parsePrimary(){if(this.consumeIf("(")){this.consumeWhitespace();let t=this.parseExpression();return this.consume(")"),this.parsePropertyAccess(t)}return this.consumeKeyword("true")?{type:"Boolean",value:!0,fn:qt}:this.consumeKeyword("false")?{type:"Boolean",value:!1,fn:Kt}:this.consumeKeyword("null")?{type:"Null",fn:Gt}:this.consumeKeyword("undefined")?{type:"Undefined",fn:Yt}:this.checkIf("'")||this.checkIf('"')?this.parseString():this.checkIfNum()?this.parseNumber():this.parsePropertyAccess(this.parseIdentifier())}parsePropertyAccess(t){if(this.consumeWhitespace(),this.consumeIf(".")){let e=this.parseIdentifier();return this.parsePropertyAccess({type:"PropertyAccess",object:t,property:e.name,fn:i((r,s)=>t.fn(r,s)?.[e.name],"fn")})}if(this.consumeIf("(")){this.consumeWhitespace();let e=t.name,r=[];if(!this.consumeIf(")")){for(r.push(this.parseExpression());this.consumeIf(",");)this.consumeWhitespace(),r.push(this.parseExpression());this.consumeWhitespace(),this.consume(")")}return this.parsePropertyAccess({type:"Function",args:r,pipeId:e,fn:i((s,o)=>{if(!e)return s.logError(`Empty pipe function: ${e}`),r[0]?.fn(s,o);let a=this.ctx.getFunction(s,e);return a||s.logError(`Undefined pipe function: ${e}`),a?.apply(s,r.map(p=>p.fn(s,o)))},"fn")})}if(this.consumeIf("[")){this.consumeWhitespace();let e=this.parseExpression();return this.consumeWhitespace(),this.consume("]"),this.parsePropertyAccess({type:"ComputedPropertyAccess",object:t,property:e,fn:i((r,s)=>t.fn(r,s)?.[e.fn(r,s)],"fn")})}return t}};var Qt=new Map,De=1,Xe=i((n,t)=>t,"identityFunc"),ke={$RefProp:i(n=>(t,e)=>n.getByRef(t)?.get(e),"$RefProp")},M=class n{static{i(this,"Expression")}static from(t){let e=Qt.get(t);if(e)return e;let r=new n,s=t.replaceAll(/@(\w+)\.(\w+)/g,o=>{let a=`${D}C${De++}`;return r.connectedPropsNames.set(a,o.slice(1)),a});try{let o=new S(s,r).parse();r.functor=o.fn}catch(o){throw console.error(`Expression: ${t}`,o),o}return Qt.set(t,r),r}functor=Xe;connectedPropsNames=new Map;propNames=new Set;resolveIdentifier(t,e){return t.getFromScope(e)}getFunction(t,e){return e[0]==="$"?ke[e](t):t.platform.getFunction(e)}};function R(n){let t=new M;try{let e=new S(n,t).parse();t.functor=e.fn}catch(e){throw console.error(`Expression: ${n}`,e),e}return t}i(R,"compilePlaceholder");function Jt(n,t){n.startsWith("@")&&(n=n.slice(1));let e=n.indexOf("="),r=n.indexOf("(");if(e>0&&(r===-1||e<r)){let s=n.slice(0,e).trim();n=n.slice(e+1).replaceAll(/@(\w+)\.(\w+)/g,(a,p,c)=>`$RefProp('${p}', '${c}')`);let o=R(n).functor;return a=>p=>a.scope?.emit(s,o(a,p))}if(r>0){let s=`${n.slice(0,r)}()`,o=n.slice(r+1,-1).trim();if(o=o.replaceAll(/@(\w+)\.(\w+)/g,(p,c,f)=>`$RefProp('${c}', '${f}')`),!o)return p=>c=>p.scope?.emit(s,c);let a=lt(o,",").map(p=>R(p).functor);return p=>c=>p.scope?.emit(s,...a.map(f=>f(p,c)))}return n=n.trim(),s=>o=>s.scope?.emit(n,o)}i(Jt,"compileSingleExpression");function Vt(n,t){let e=lt(n,";").filter(Boolean);if(e.length<=1)return Jt(e[0]??n,t);let r=e.map(s=>Jt(s,t));return s=>async o=>{for(let a of r)await a(s)(o)}}i(Vt,"compileEmitterExpression");var He=i(n=>n==null?"":String(n),"str"),je=/\{([^}]+)\}/g,te="{$$$}",mt=new Map;function Fe(n,t){let e=[],r=n.replace(je,(a,p)=>(e.push(t(p.trim())),te));if(!e.length)return()=>r;let s=r.split(te),o=s.pop();return(...a)=>s.map((p,c)=>`${p}${He(e[c](...a))}`).join("")+o}i(Fe,"createStringInterpolator");function ve(n){let t=O(n);return()=>t}i(ve,"compileConstant");function Le(n){if(typeof n!="string")return()=>n;if(n.includes("{")){let t=n.slice(1,-1);return n[0]==="{"&&n.at(-1)==="}"&&!t.includes("{")?R(t).functor:Fe(n,e=>R(e).functor)}return ve(n)}i(Le,"_resolveExpression");var Q=i(n=>mt.has(n)?mt.get(n):mt.set(n,Le(n)).get(n),"resolveExpression");var Ue=1;function J(n){let t={};return n=n.replaceAll(/@(\w+)\.(\w+)/g,r=>{let s=D+Ue++;return t[s]=r.slice(1),s}),{expr:Q(n),props:Object.entries(t)}}i(J,"prepareConnectedProps");var ee=1;var m=class{static{i(this,"ManifestNode")}$content;uid;refId;propertyResolvers=[];initialState={};connectors;tag;constructor(t){this.uid=`N${String(ee++)}:${t}`}createArrmatron(t,e,r){return new this.EntitronConstructor(t,this,e,r)}getSubNodes(t){return this.$content}bindExpression(t,e){let{functor:r,connectedPropsNames:s}=M.from(t);if(s?.size)for(let[o,a]of s.entries())this.addConnector(a,(p,c)=>{p.putInLocalScope(o,c),p.up(e(r(p)))});this.propertyResolvers.push((o,a)=>(Object.assign(a,e(r(o))),a))}addConnectedPropertyResolver(t,e){let{expr:r,props:s}=J(t);s.forEach(([o,a])=>{this.addConnector(a,(p,c)=>(p.putInLocalScope(o,c),_(r(p),f=>{p.up({[e]:f})})))}),this.propertyResolvers.push((o,a)=>(a[e]=r(o),a))}addConnectedDataPropertyResolver(t,e){if(typeof t!="string")this.addDataPropertyResolver(Q(t),e);else{let{expr:r,props:s}=J(t);s.forEach(([o,a])=>{this.addConnector(a,(p,c)=>(p.putInLocalScope(o,c),_(r(p),f=>{p.up({data:{...p.get("data"),[e]:f}})})))}),this.addDataPropertyResolver(r,e)}}addDataPropertyResolver(t,e){this.propertyResolvers.push((r,s)=>{let o=t(r);return s.data=Object.assign(s.data||{},{[e]:o}),s})}addConnectedPropertiesResolver(t){let{expr:e,props:r}=J(t);r.forEach(([s,o])=>{this.addConnector(o,(a,p)=>(a.putInLocalScope(s,p),_(e(a),c=>{let f=a.$$propKeys??(a.$$propKeys={});Object.keys(c??{}).forEach(l=>f[l]=null),a.up({...f,...c})})))}),this.propertyResolvers.push((s,o)=>{let a=e(s);if(a&&typeof a=="object"){let p=s.$$propKeys??(s.$$propKeys={});Object.keys(p).forEach(c=>o[c]=null),Object.entries(a).forEach(([c,f])=>{p[c]=null,o[c]=f})}return o})}addConnector(t,e){let r=this.connectors??(this.connectors=new Map),[s,o]=t.trim().split("."),a=`${s}.${o||"This"}.${ee++}`;r.set(a,e)}resolveInitialProps(t){let e=Object.entries(this.initialState).reduce((r,[s,o])=>(r[s]=o(t),r),{});return this.resolveProps(t,e)}resolveProps(t,e={}){return this.propertyResolvers.reduce((r,s)=>s(t,r),e)}compileAttribute(t,e){if(t.startsWith("data-")&&t!=="data-theme")if(typeof e=="string"&&e[0]==="'"&&e.at(-1)==="'"){let r=e.slice(1,-1);this.addDataPropertyResolver(()=>r,t.slice(5))}else this.addConnectedDataPropertyResolver(e,t.slice(5));else if(t==="Ref")this.refId=String(e);else if(t==="Props")this.addConnectedPropertiesResolver(String(e));else if(typeof e!="string")this.initialState[t]=()=>e;else if(e[0]==="'"&&e.at(-1)==="'"){let r=e.slice(1,-1);this.initialState[t]=()=>r}else if(e.includes("{"))this.addConnectedPropertyResolver(e,t);else if(e.startsWith("@")){let[r,s]=e.slice(1).trim().split(".");s?this.bindExpression(e,o=>({[t]:o})):this.initialState[t]=o=>o.getByRef(r)?.$component}else e.startsWith("->")?this.initialState[t]=Vt(e.slice(2).trim(),this):this.initialState[t]=()=>e}compileAttributes(t){t&&Object.entries(t).forEach(e=>this.compileAttribute(...e))}};var ht=class extends u{static{i(this,"Block")}get displayName(){return`\u{1F4A0}${this.manifest.tag}`}get contentManifests(){let t=this.get("Nodes")??[];return this.platform.getCompiledNodes(t)}},X=class extends m{static{i(this,"CBlockNode")}constructor({id:t,attrs:e}){super(t+(e?.Ref?`:${e?.Ref}`:"")),this.compileAttributes(e)}get EntitronConstructor(){return ht}};var dt=class extends u{static{i(this,"Composite")}get displayName(){return`\u{1F4A0}${this.manifest.tag}`}get scopeForChildren(){return this}slotContent(t){return this.manifest.getSlotContent(this.platform,t)}createComponent(){return this.platform.createComponent(this.manifest.tag)}},k=class extends m{static{i(this,"CCompositeNode")}slotContent=null;tag;nodes;constructor({id:t,tag:e,attrs:r,nodes:s}){super(t+(r?.Ref?`:${r?.Ref}`:"")),this.tag=e,this.nodes=s,this.compileAttributes(r)}getSlotContent(t,e){if(!this.slotContent){let r=this.nodes?.reduce((s,o)=>{if(o){let a=String(o.attrs?.Slot??"default");s[a]=(s[a]||[]).concat(o)}return s},{});this.slotContent=Object.entries(r??{}).reduce((s,[o,a])=>(s[o]=t.getCompiledNodes(a),s),{})}return this.slotContent[e||"default"]??void 0}getSubNodes(t){return t.getCompiledNodes(this.tag)}get EntitronConstructor(){return dt}};var gt=class extends u{static{i(this,"Conditional")}get contentManifests(){return this.ifCondition?this.ifBranches.thenBlock:this.ifBranches.elseBlock}get ifCondition(){return this.$component.condition}get ifBranches(){return this.manifest.getBranches(this.platform)}get displayName(){return`\u{1F539}if:${this.manifest.expr}`}},H=class extends m{static{i(this,"CIfNode")}#t;#e;expr;constructor(t,e){super(t.id),this.#t=t,this.expr=e,this.compileCondition(e)}get EntitronConstructor(){return gt}getBranches(t){if(this.#e)return this.#e;this.#e={};let{nodes:e}=this.#t,r=[this.#t];if(e?.length){let s=e.find(a=>a.tag==="Else"),o=e.find(a=>a.tag==="Then");s?(this.#e.elseBlock=s.nodes?t.getCompiledNodes(s.nodes):void 0,r=o?o.nodes:[{...this.#t,nodes:e.filter(a=>a!==s)}]):o&&(r=o.nodes)}return this.#e.thenBlock=r?t.getCompiledNodes(r):void 0,this.#e}compileCondition(t){if(t.startsWith("Slot(")){let e=t.slice(5,-1);this.propertyResolvers.push((r,s)=>(s.condition=!!r.scope.slotContent?.(e)?.size,s))}else t[0]==="{"&&t[t.length-1]==="}"&&(t=t.slice(1,-1)),this.bindExpression(t,e=>({condition:!!e}))}};var yt=class extends A{static{i(this,"DataConnectorComponent")}_data;change;get data(){return this._data}set data(t){this._data=t,_(t,e=>{e!==void 0&&this.change?.(e)})}},Ct=class extends A{static{i(this,"TriggerConnectorComponent")}change;_trigger;data;get trigger(){return this._trigger}set trigger(t){this._trigger=t,_(t,e=>{e!==void 0&&_(this.data,r=>{this.change?.(r)})})}},_t=class extends u{static{i(this,"Connector")}createComponent(){let t=this.manifest.componentClass;return new t}get displayName(){return"\u{1F539}Connector"}},j=class extends m{static{i(this,"ConnectorNode")}componentClass;constructor({attrs:t,id:e}){super(e);let{trigger:r,change:s,...o}=t;this.compileAttributes(r?{change:s,...o,trigger:r}:{change:s,...o}),this.componentClass=r?Ct:yt}get EntitronConstructor(){return _t}};var Nt=class extends u{static{i(this,"NativeElementEntitron")}get displayName(){return this.manifest.tag}createComponent(){return this.platform.createComponent({tag:this.manifest.tag,native:!0})}},F=class extends m{static{i(this,"CElementNode")}#t;constructor({id:t,tag:e,attrs:r,nodes:s,text:o}){super(t),this.tag=e,this.compileAttributes(r),o&&this.compileAttribute("#text",o),this.#t=s}getSubNodes(t){return this.#t?t.getCompiledNodes(this.#t):void 0}get EntitronConstructor(){return Nt}};var v=class extends m{static{i(this,"CFragmentNode")}#t;constructor({id:t,nodes:e,attrs:r}){super(t),this.#t=e,this.compileAttributes(r)}getSubNodes(t){return this.#t?t.getCompiledNodes(this.#t):void 0}get EntitronConstructor(){return u}};var ne=i(n=>n?typeof n=="string"?n.split(",").map(t=>t.trim()).map(t=>({id:t,name:t})):Array.isArray(n)?n.map(t=>typeof t=="object"?{...t,id:String(t.id??"")}:{id:String(t),name:String(t??"--")}):typeof n[Symbol.iterator]=="function"?[...n]:typeof n=="object"?x(n,(t,e)=>typeof e=="object"?{...e,id:t}:{id:t,name:String(e)}):[{id:String(n),name:String(n)}]:[],"narrowData");var At=class extends u{static{i(this,"Iterative")}pkHash={};get displayName(){return`\u{1F7EA}each:${this.manifest.itemName}`}get eachList(){return this.$component.each}get contentManifests(){let t=ne(this.eachList),e=this.manifest.getItemCtxNode(this.platform),r=new Map;return this.pkHash={},t.forEach(s=>{let o=String(s.id||C(s));if(this.pkHash[o]){this.logError(`ERROR: duplicate item id : ${o} (skipped)`,s);return}this.pkHash[o]=s;let a=e.cloneWithDatum(s,this.platform);a.propertyResolvers.push((p,c)=>(c[e.itemName]=this.pkHash[o],c)),r.set(a.uid,a)}),r}},L=class extends m{static{i(this,"CForNode")}#t;itemName;#e;constructor(t,e,r){super(t.id),this.#e=t,this.itemName=e,this.bindExpression(r,s=>({each:s}))}getItemCtxNode(t){return this.#t??=new $t(this.#e.id,this.itemName,t.getCompiledNodes([this.#e])),this.#t}get EntitronConstructor(){return At}},Et=class extends u{static{i(this,"IterativeItem")}get scopeForChildren(){return this}get displayName(){return`\u{1F7EA}each:item:${this.manifest.itemName}`}emit(t,...e){return this.scope.emit(t,...e)}get(t){let e=this.manifest.itemName;return t.startsWith(`${e}.`)||t===e?super.get(t):this.scope.get(t)}},$t=class n extends m{static{i(this,"CItemNode")}itemName;constructor(t,e,r){super(t),this.itemName=e,this.$content=r}cloneWithDatum(t,e){let r=`${String(this.uid)}#${t.id||C(t)}`,s=new n(r,this.itemName,this.getSubNodes(e));return s.uid=r,s}get EntitronConstructor(){return Et}};var It=class extends u{static{i(this,"DynamicTag")}get displayName(){return"dynamics"}get _dynamicTag(){return this.$component._dynamicTag}get contentManifests(){let t=this._dynamicTag,e=`${this.uid}:${String(t??"")}`,r=this.manifest.getCompiledForTag(this.platform,t);return new Map([[e,Object.assign(r,{uid:e})]])}},U=class extends m{static{i(this,"CDynamicTagNode")}xml;#t=new Map;constructor(t,e){super(t.id),this.compileAttribute("_dynamicTag",e),this.xml=t}getCompiledForTag(t,e){let r=String(e??""),s=this.#t.get(r);return s||(s=t.getCompiledNodes({...this.xml,tag:e}),this.#t.set(r,s)),s}get EntitronConstructor(){return It}};var xt=class extends u{static{i(this,"Selector")}get displayName(){return"\u{1F4A0}Selector"}get contentManifests(){let t=this.manifest.getCases(this.platform),e=this.$component.On;return t?.[e]??t?.default}},B=class extends m{static{i(this,"CSelectorNode")}cases=null;key="";nodes;constructor({id:t,tag:e,attrs:r,nodes:s}){super(t),this.tag=e,this.nodes=s,this.compileAttributes(r)}getCases(t){return this.cases??(this.cases=(this.nodes??[]).reduce((e,r)=>(e[r.attrs?.When]=t.getCompiledNodes(r.nodes??[]),e),{}))}get EntitronConstructor(){return xt}};var Pt=class extends u{static{i(this,"Slot")}get displayName(){return"\u{1F538}slot"}getByRef(t){return this.scope?.getByRef(t)}get slotContent(){return this.scope.slotContent(this.manifest.key)}get contentManifests(){return this.slotContent}get scopeForChildren(){return this.scope.scope}},W=class extends m{static{i(this,"CSlotNode")}key;constructor(t){super(t.id),this.key=t.attrs?.Key}get EntitronConstructor(){return Pt}};var wt=i((n,t)=>{let{[t]:e,...r}=n.attrs??{};return{text:n.text,tag:n.tag,id:n.id,attrs:r,nodes:n.nodes?.map(s=>s)}},"cloneNode"),Be=i(n=>{let{tag:t="div",attrs:e}=n;if(e?.Each){let[r,,...s]=String(e.Each).trim().split(" ");return new L(wt(n,"Each"),r,s.join(" "))}return e?.If?new H(wt(n,"If"),String(e.If)):t==="div"||t?.[0]?.match(/[A-Z0-9]/)==null?new F(n):t==="Dynamic"?new U(wt(n,"As"),String(e?.As??"Error.Dynamic")):t==="Slot"?new W(n):t==="Selector"?new B(n):t==="Connector"?new j(n):t==="Fragment"||t==="Then"||t==="Else"?new v(n):t==="Block"?new X(n):new k(n)},"__compileManifestNode"),St=new Map,V=i(n=>St.has(n)?St.get(n):St.set(n,Be(n)).get(n),"compileManifestNode"),tt=i(n=>new Map(n?.map(V).map(t=>[t.uid,t])??[]),"compileManifestNodes");var Mt=class extends u{static{i(this,"RootCtx")}get displayName(){return"ROOT"}get scopeForChildren(){return this}slotContent(t){}createComponent(){return this.platform.createComponent({})}},$=class extends m{constructor(e){super("R0");this.template=e;this.slotContent={}}template;static{i(this,"CRootNode")}slotContent;nodes;#t;getSubNodes(e){return this.#t??=e.xmlParse(this.template),e.getCompiledNodes(this.#t)}getSlotContent(e,r){}get EntitronConstructor(){return Mt}};var We=i((n,t)=>{let e=new $(t).createArrmatron(n);return e.touch(),e},"launch");var ze=1;function Ke(n,t){t({Ctor:n,tag:n.name??Ge(n)})}i(Ke,"registerFromFunction");function qe(n,t){n.replaceAll(/<Component\s+id="([^"]+)"(?:[^>]*)>([\s\S]*?)<\/Component>/gm,(e,r,s)=>(s=s.replaceAll(/<Signature\b[^>]*?\/>/gm,"").replaceAll(/<Signature\b[^>]*?>[\s\S]*?<\/Signature>/gm,"").replaceAll(/<Subcomponent\s+id="([^"]+)"(?:[^>]*)>([\s\S]*?)<\/Subcomponent>/gm,(o,a,p)=>(p=p.replaceAll(/<(\/?)This-/gm,(c,f)=>`<${f}${r}-`).trim(),t({tag:`${r}-${a}`,template:p}),"")).replaceAll(/<(\/?)This-/gm,(o,a)=>`<${a}${r}-`).trim(),t({tag:r,template:s}),""))}i(qe,"registerFromString");var Ge=i(n=>(/^function\s+([\w$]+)\s*\(/.exec(n.toString())??[])[1]??`C${String(ze++)}`,"fnName");function Rt(n){return t=>{if(!t)return;let e=i(r=>{Array.isArray(r)?r.filter(Boolean).forEach(e):typeof r=="string"?qe(r,n):typeof r=="function"?Ke(r,n):r.tag||r.id?n({...r,tag:r.tag??r.id}):x(r,(s,o)=>n({tag:s,template:o}))},"registerType");e(t)}}i(Rt,"createRegisterTypes");var et=class{constructor(t,e){this.tag=t}tag;static{i(this,"NativeElement")}nodes=[];attrs={};native=!0;__stateChanged(t){Object.assign(this.attrs,Object.fromEntries([...t.entries()]))}getName(){return this.tag}getAttribute(t,e=null){return this.attrs[t]??e}getRequiredAttribute(t){let e=this.getAttribute(t);if(!e)throw new Error(`Required attribute '${t}' missing for ${this.getName()}`);return e}getBooleanAttribute(t,e=!1){let r=this.getAttribute(t,e);return typeof r=="boolean"?r:["true","1","yes","on"].includes(String(r).toLowerCase())}getNumericAttribute(t,e=0){let r=this.getAttribute(t,e);return parseFloat(r)||e}getEnumAttribute(t,e,r){let s=this.getAttribute(t,r);return e.includes(s)?s:r}getTextContent(){return this.attrs["#text"]}getChildren(){return this.nodes}};var nt=class{static{i(this,"Registry")}typeRegistry=new Map;compiledTemplates=new Map;NativeElement=et;registerTypes(t){Rt(e=>{let r=String(e.tag);this.compiledTemplates.delete(r),this.typeRegistry.set(r,e)})(t)}getByTag(t){let e=this.typeRegistry.get(t);if(e)return e;let r=t.split(".");for(r.pop();r.length;r.pop()){let s=this.typeRegistry.get(r.join("."));if(s)return s}return{tag:t,unknown:!0}}xmlParse(t){try{return at(t)}catch(e){return[{tag:"div",text:String(e),id:"error"}]}}getCompiledNodes(t){if(typeof t=="string"){let e=this.compiledTemplates;if(e.has(t))return e.get(t);let r=this.getByTag(t);if(!r?.template)return[];let s=r.template,o=typeof s=="string"?this.xmlParse(s):s,a=tt(o);return e.set(t,a),a}return Array.isArray(t)?tt(t):V(t)}createComponent(t){if(typeof t=="string")return this.createComponent(this.getByTag(t));let e=this.NativeElement;try{let{Ctor:r,tag:s,unknown:o,native:a}=t;return a?new e(s??"div",this):r?new r:o?(this.log({level:"info",message:`<-- unknown tag: ${s} -->`,source:"registry"}),new e("div",this)):new A}catch(r){return this.log({level:"error",message:"createComponent failed",error:r,source:"registry"}),new e("div",this)}}log(t){typeof t=="string"?console.log(t):console.log(t.source??"",t.message??"",...t.params??[])}};var z=class extends nt{static{i(this,"Platform")}resources={};constructor(t){super(),this.updateResources(t)}redraw(t,e){}updateResources(t){x(t,(e,r)=>{if(e[0]==="$")return;if(e==="NativeElement"){this.NativeElement=r;return}if(e==="components"){this.registerTypes(r);return}let s=e.split(".");if(s.length>1){let o=s.pop()??"-",a=s.reduce((p,c)=>p[c]??(p[c]={}),this.resources);a[o]=b(a[o],r);return}this.resources[e]=b(this.resources[e],r)})}getResource(t){let[e,...r]=typeof t=="string"?t.split("."):t,{resources:s}=this,o=e?s[e]:s;return!o||r.length===0?o:r.length===1?o[r[0]]:r.reduce((a,p)=>a?a[p]:null,o)}getFunction(t){return pt[t]||this.resources.functions?.[t]}applyAsyncValue(t,e,r){return e instanceof Promise?e.then(s=>r(s)):r(e)}};function rt(n,t){if(n)for(let e of n.values()){let r=e.$component;r.native?(rt(e.children,r),t.nodes.push(r)):rt(e.children,t)}}i(rt,"toNativeTree");function Ye(n,{reflow:t=rt,rootElement:e={tag:"root",nodes:[]},...r}){let s=new z(r),o=new $(n).createArrmatron(s);return s.redraw=()=>{t(o.children,e)},o.touch(),e}i(Ye,"applyTemplate");0&&(module.exports={CRootNode,Component,Platform,applyTemplate,compileManifestNode,compileManifestNodes,createRegisterTypes,launch});
|
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arrmatura",
|
|
3
|
-
"version": "6.5.
|
|
3
|
+
"version": "6.5.1",
|
|
4
4
|
"description": "General-purpose FRP framework",
|
|
5
5
|
"author": "alitskevich",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
|
-
"types": "./index.ts",
|
|
9
8
|
"exports": {
|
|
10
9
|
"types": "./src/index.ts",
|
|
11
10
|
"require": "./dist/index.js",
|
|
@@ -19,11 +18,16 @@
|
|
|
19
18
|
],
|
|
20
19
|
"scripts": {
|
|
21
20
|
"build": "esbuild index.ts --bundle --outdir=dist --format=cjs --platform=node --target=esnext --packages=external --minify --keep-names",
|
|
21
|
+
"gates": "npx --yes npm-run-all --parallel typecheck lint test",
|
|
22
22
|
"lint": "biome check ./src",
|
|
23
23
|
"lint:fix": "biome check ./src --fix",
|
|
24
|
-
"test": "vitest",
|
|
24
|
+
"test": "vitest run",
|
|
25
25
|
"typecheck": "tsc",
|
|
26
|
-
"prepublish": "npm run build",
|
|
26
|
+
"prepublish": "npm run build && npm run gates",
|
|
27
27
|
"publish": "npm publish"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^26.6.2",
|
|
31
|
+
"vitest": "^5.0.1"
|
|
28
32
|
}
|
|
29
33
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
CBlockNode,
|
|
4
|
+
CCompositeNode,
|
|
5
|
+
CDynamicTagNode,
|
|
6
|
+
CElementNode,
|
|
7
|
+
CForNode,
|
|
8
|
+
CFragmentNode,
|
|
9
|
+
CIfNode,
|
|
10
|
+
ConnectorNode,
|
|
11
|
+
CSelectorNode,
|
|
12
|
+
CSlotNode,
|
|
13
|
+
} from "../controls";
|
|
14
|
+
import type { XmlNode } from "../types";
|
|
15
|
+
import { compileManifestNode, compileManifestNodes } from "./index";
|
|
16
|
+
|
|
17
|
+
const node = (partial: Partial<XmlNode>): XmlNode => ({
|
|
18
|
+
tag: "div",
|
|
19
|
+
id: "x1",
|
|
20
|
+
attrs: {},
|
|
21
|
+
...partial,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe("compileManifestNode: dispatch", () => {
|
|
25
|
+
test("Each wins over If on the same element", () => {
|
|
26
|
+
const n = compileManifestNode(
|
|
27
|
+
node({ attrs: { Each: "item of items", If: "cond" } }),
|
|
28
|
+
);
|
|
29
|
+
expect(n).toBeInstanceOf(CForNode);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("Each alone compiles to CForNode", () => {
|
|
33
|
+
const n = compileManifestNode(node({ attrs: { Each: "item of items" } }));
|
|
34
|
+
expect(n).toBeInstanceOf(CForNode);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("If alone compiles to CIfNode", () => {
|
|
38
|
+
const n = compileManifestNode(node({ attrs: { If: "cond" } }));
|
|
39
|
+
expect(n).toBeInstanceOf(CIfNode);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('"div" is always a CElementNode, even with an uppercase-looking twist', () => {
|
|
43
|
+
const n = compileManifestNode(node({ tag: "div" }));
|
|
44
|
+
expect(n).toBeInstanceOf(CElementNode);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("a lowercase tag compiles to CElementNode", () => {
|
|
48
|
+
const n = compileManifestNode(node({ tag: "span" }));
|
|
49
|
+
expect(n).toBeInstanceOf(CElementNode);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("a digit-leading tag is treated as a component (CCompositeNode), per the built-ins gotcha", () => {
|
|
53
|
+
const n = compileManifestNode(node({ tag: "123weird" }));
|
|
54
|
+
expect(n).toBeInstanceOf(CCompositeNode);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("no tag at all defaults to div, a CElementNode", () => {
|
|
58
|
+
const n = compileManifestNode(
|
|
59
|
+
node({ tag: undefined as unknown as string }),
|
|
60
|
+
);
|
|
61
|
+
expect(n).toBeInstanceOf(CElementNode);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('"Dynamic" compiles to CDynamicTagNode', () => {
|
|
65
|
+
const n = compileManifestNode(
|
|
66
|
+
node({ tag: "Dynamic", attrs: { As: "Foo" } }),
|
|
67
|
+
);
|
|
68
|
+
expect(n).toBeInstanceOf(CDynamicTagNode);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('"Slot" compiles to CSlotNode', () => {
|
|
72
|
+
const n = compileManifestNode(node({ tag: "Slot" }));
|
|
73
|
+
expect(n).toBeInstanceOf(CSlotNode);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('"Selector" compiles to CSelectorNode', () => {
|
|
77
|
+
const n = compileManifestNode(node({ tag: "Selector" }));
|
|
78
|
+
expect(n).toBeInstanceOf(CSelectorNode);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('"Connector" compiles to ConnectorNode', () => {
|
|
82
|
+
const n = compileManifestNode(node({ tag: "Connector" }));
|
|
83
|
+
expect(n).toBeInstanceOf(ConnectorNode);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test.each(["Fragment", "Then", "Else"])(
|
|
87
|
+
'"%s" compiles to CFragmentNode',
|
|
88
|
+
(tag) => {
|
|
89
|
+
const n = compileManifestNode(node({ tag }));
|
|
90
|
+
expect(n).toBeInstanceOf(CFragmentNode);
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
test('"Block" compiles to CBlockNode', () => {
|
|
95
|
+
const n = compileManifestNode(node({ tag: "Block" }));
|
|
96
|
+
expect(n).toBeInstanceOf(CBlockNode);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("any other capitalized tag falls to CCompositeNode", () => {
|
|
100
|
+
const n = compileManifestNode(node({ tag: "MyWidget" }));
|
|
101
|
+
expect(n).toBeInstanceOf(CCompositeNode);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("Each and If both take priority over a reserved tag name", () => {
|
|
105
|
+
const n1 = compileManifestNode(
|
|
106
|
+
node({ tag: "Selector", attrs: { Each: "item of items" } }),
|
|
107
|
+
);
|
|
108
|
+
expect(n1).toBeInstanceOf(CForNode);
|
|
109
|
+
const n2 = compileManifestNode(
|
|
110
|
+
node({ tag: "Block", attrs: { If: "cond" } }),
|
|
111
|
+
);
|
|
112
|
+
expect(n2).toBeInstanceOf(CIfNode);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe("compileManifestNode: memoization", () => {
|
|
117
|
+
test("the same XmlNode object always compiles to the same instance", () => {
|
|
118
|
+
const x = node({ tag: "MyWidget" });
|
|
119
|
+
const a = compileManifestNode(x);
|
|
120
|
+
const b = compileManifestNode(x);
|
|
121
|
+
expect(a).toBe(b);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("two distinct XmlNode objects (even if deep-equal) compile to distinct instances", () => {
|
|
125
|
+
const a = compileManifestNode(node({ tag: "MyWidget" }));
|
|
126
|
+
const b = compileManifestNode(node({ tag: "MyWidget" }));
|
|
127
|
+
expect(a).not.toBe(b);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe("compileManifestNodes", () => {
|
|
132
|
+
test("compiles a list, keyed by each node's compiled uid", () => {
|
|
133
|
+
const x1 = node({ tag: "a", id: "1" });
|
|
134
|
+
const x2 = node({ tag: "b", id: "2" });
|
|
135
|
+
const map = compileManifestNodes([x1, x2]);
|
|
136
|
+
const c1 = compileManifestNode(x1);
|
|
137
|
+
const c2 = compileManifestNode(x2);
|
|
138
|
+
expect(map.size).toBe(2);
|
|
139
|
+
expect(map.get(c1.uid)).toBe(c1);
|
|
140
|
+
expect(map.get(c2.uid)).toBe(c2);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
test("nullish input yields an empty map", () => {
|
|
144
|
+
expect(compileManifestNodes(undefined as unknown as XmlNode[]).size).toBe(
|
|
145
|
+
0,
|
|
146
|
+
);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
test("empty array input yields an empty map", () => {
|
|
150
|
+
expect(compileManifestNodes([]).size).toBe(0);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
|
2
|
+
import { applyTemplate } from "../utils/applyTemplate";
|
|
3
|
+
|
|
4
|
+
describe('Iterative: CForNode (<... Each="item of expr">)', () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
vi.spyOn(console, "log").mockImplementation(() => {});
|
|
7
|
+
});
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
vi.restoreAllMocks();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test("renders one element per item, in source order", () => {
|
|
13
|
+
const items = [
|
|
14
|
+
{ id: "a", name: "Alice" },
|
|
15
|
+
{ id: "b", name: "Bob" },
|
|
16
|
+
];
|
|
17
|
+
const root = applyTemplate(
|
|
18
|
+
'<div Each="item of R.items" label="{item.name}"/>',
|
|
19
|
+
{ items },
|
|
20
|
+
);
|
|
21
|
+
expect(root.nodes.map((n: any) => n.attrs.label)).toEqual(["Alice", "Bob"]);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("a falsy list renders no items at all", () => {
|
|
25
|
+
const root = applyTemplate('<div Each="item of R.items" label="x"/>', {
|
|
26
|
+
items: null,
|
|
27
|
+
});
|
|
28
|
+
expect(root.nodes).toEqual([]);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test("a comma-separated string list narrows to one { id, name } item per token", () => {
|
|
32
|
+
const root = applyTemplate(
|
|
33
|
+
'<div Each="item of R.items" label="{item.name}"/>',
|
|
34
|
+
{
|
|
35
|
+
items: "a, b, c",
|
|
36
|
+
},
|
|
37
|
+
);
|
|
38
|
+
expect(root.nodes.map((n: any) => n.attrs.label)).toEqual(["a", "b", "c"]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test("a plain array of scalars narrows to { id, name } per entry", () => {
|
|
42
|
+
const root = applyTemplate(
|
|
43
|
+
'<div Each="item of R.items" label="{item.name}"/>',
|
|
44
|
+
{
|
|
45
|
+
items: [1, 2],
|
|
46
|
+
},
|
|
47
|
+
);
|
|
48
|
+
expect(root.nodes.map((n: any) => n.attrs.label)).toEqual(["1", "2"]);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("an object narrows to one item per entry, keyed by its own key", () => {
|
|
52
|
+
const root = applyTemplate(
|
|
53
|
+
'<div Each="item of R.items" label="{item.id}-{item.name}"/>',
|
|
54
|
+
{
|
|
55
|
+
items: { x: 1, y: 2 },
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
expect(root.nodes.map((n: any) => n.attrs.label)).toEqual(["x-1", "y-2"]);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("a duplicate id is skipped (logged as an error), so the row disappears", () => {
|
|
62
|
+
const logSpy = vi.spyOn(console, "log").mockImplementation(() => {});
|
|
63
|
+
const items = [
|
|
64
|
+
{ id: "a", name: "First" },
|
|
65
|
+
{ id: "a", name: "Second" },
|
|
66
|
+
];
|
|
67
|
+
const root = applyTemplate(
|
|
68
|
+
'<div Each="item of R.items" label="{item.name}"/>',
|
|
69
|
+
{ items },
|
|
70
|
+
);
|
|
71
|
+
expect(root.nodes.map((n: any) => n.attrs.label)).toEqual(["First"]);
|
|
72
|
+
expect(logSpy).toHaveBeenCalledWith(
|
|
73
|
+
expect.stringContaining("each:item"),
|
|
74
|
+
expect.stringContaining("duplicate item id"),
|
|
75
|
+
{ id: "a", name: "Second" },
|
|
76
|
+
);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("inside the loop body, only the item name resolves locally — everything else falls through to the enclosing scope", () => {
|
|
80
|
+
const root = applyTemplate(
|
|
81
|
+
'<div Each="item of R.items" label="{item.name}-{R.suffix}"/>',
|
|
82
|
+
{ items: [{ id: "a", name: "Alice" }], suffix: "!" },
|
|
83
|
+
);
|
|
84
|
+
expect(root.nodes[0].attrs.label).toBe("Alice-!");
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("Each and If together: the loop is outer, the condition is evaluated per item", () => {
|
|
88
|
+
const items = [
|
|
89
|
+
{ id: "a", name: "Alice", active: true },
|
|
90
|
+
{ id: "b", name: "Bob", active: false },
|
|
91
|
+
{ id: "c", name: "Carl", active: true },
|
|
92
|
+
];
|
|
93
|
+
const root = applyTemplate(
|
|
94
|
+
'<div Each="item of R.items" If="{item.active}" label="{item.name}"/>',
|
|
95
|
+
{ items },
|
|
96
|
+
);
|
|
97
|
+
expect(root.nodes.map((n: any) => n.attrs.label)).toEqual([
|
|
98
|
+
"Alice",
|
|
99
|
+
"Carl",
|
|
100
|
+
]);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test("the Each syntax skips the second token (conventionally `of`) and joins the rest as the expression", () => {
|
|
104
|
+
const root = applyTemplate(
|
|
105
|
+
'<div Each="row of R.data | mapEntries" label="{row.id}"/>',
|
|
106
|
+
{
|
|
107
|
+
data: { k: "v" },
|
|
108
|
+
functions: {
|
|
109
|
+
mapEntries: (obj: Record<string, unknown>) =>
|
|
110
|
+
Object.entries(obj).map(([id, value]) => ({ id, value })),
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
);
|
|
114
|
+
expect(root.nodes.map((n: any) => n.attrs.label)).toEqual(["k"]);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
|
2
|
+
import { applyTemplate } from "../utils/applyTemplate";
|
|
3
|
+
|
|
4
|
+
describe("block: CBlockNode", () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
vi.spyOn(console, "log").mockImplementation(() => {});
|
|
7
|
+
});
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
vi.restoreAllMocks();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test("renders a runtime XmlNode[] passed via Nodes", () => {
|
|
13
|
+
const nodes = [
|
|
14
|
+
{ tag: "div", id: "b1", attrs: { label: "hi" }, nodes: [] },
|
|
15
|
+
{ tag: "span", id: "b2", attrs: {}, nodes: [] },
|
|
16
|
+
];
|
|
17
|
+
const root = applyTemplate('<Block Nodes="{R.nodes}"/>', { nodes });
|
|
18
|
+
expect(root.nodes.map((n: any) => n.tag)).toEqual(["div", "span"]);
|
|
19
|
+
expect(root.nodes[0].attrs.label).toBe("hi");
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("a missing Nodes attribute renders nothing", () => {
|
|
23
|
+
const root = applyTemplate("<Block/>", {});
|
|
24
|
+
expect(root.nodes).toEqual([]);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("an empty Nodes array renders nothing", () => {
|
|
28
|
+
const root = applyTemplate('<Block Nodes="{R.nodes}"/>', { nodes: [] });
|
|
29
|
+
expect(root.nodes).toEqual([]);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("nested children of the runtime nodes render too", () => {
|
|
33
|
+
const nodes = [
|
|
34
|
+
{
|
|
35
|
+
tag: "div",
|
|
36
|
+
id: "b1",
|
|
37
|
+
attrs: {},
|
|
38
|
+
nodes: [{ tag: "a", id: "b2", attrs: {} }],
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
const root = applyTemplate('<Block Nodes="{R.nodes}"/>', { nodes });
|
|
42
|
+
expect(root.nodes[0].nodes.map((n: any) => n.tag)).toEqual(["a"]);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
|
2
|
+
import { applyTemplate } from "../utils/applyTemplate";
|
|
3
|
+
|
|
4
|
+
describe("composition: CCompositeNode (registered components)", () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
vi.spyOn(console, "log").mockImplementation(() => {});
|
|
7
|
+
});
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
vi.restoreAllMocks();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test("content comes from the registered template, not from children written at the call site", () => {
|
|
13
|
+
const root = applyTemplate("<Card><p/></Card>", {
|
|
14
|
+
components: { Card: '<div label="card-body"/>' },
|
|
15
|
+
});
|
|
16
|
+
expect(root.nodes[0].tag).toBe("div");
|
|
17
|
+
expect(root.nodes[0].attrs.label).toBe("card-body");
|
|
18
|
+
// the caller's <p/> is not rendered inline into Card's body — it is slot content,
|
|
19
|
+
// and this Card template declares no <Slot/> to project it into.
|
|
20
|
+
expect(root.nodes[0].nodes).toEqual([]);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("props passed at the call site resolve inside the component's own template", () => {
|
|
24
|
+
const root = applyTemplate('<Card title="hi"/>', {
|
|
25
|
+
components: { Card: '<div label="{title}"/>' },
|
|
26
|
+
});
|
|
27
|
+
expect(root.nodes[0].attrs.label).toBe("hi");
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("two usages of the same tag differing only by Ref render as distinct, independent instances", () => {
|
|
31
|
+
const root = applyTemplate(
|
|
32
|
+
'<Card Ref="a" title="A"/><Card Ref="b" title="B"/>',
|
|
33
|
+
{
|
|
34
|
+
components: { Card: '<div label="{title}"/>' },
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
expect(root.nodes.map((n: any) => n.attrs.label)).toEqual(["A", "B"]);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("tag lookup falls back through dotted prefixes", () => {
|
|
41
|
+
const root = applyTemplate("<Page.Docs.Header/>", {
|
|
42
|
+
components: { "Page.Docs": '<div label="fallback"/>' },
|
|
43
|
+
});
|
|
44
|
+
expect(root.nodes[0].attrs.label).toBe("fallback");
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("an unregistered tag logs an unknown-tag line and renders as a plain div", () => {
|
|
48
|
+
const logSpy = vi.spyOn(console, "log").mockImplementation(() => {});
|
|
49
|
+
const root = applyTemplate("<Ghost/>", {});
|
|
50
|
+
expect(root.nodes[0].tag).toBe("div");
|
|
51
|
+
expect(logSpy).toHaveBeenCalledWith(
|
|
52
|
+
"registry",
|
|
53
|
+
"<-- unknown tag: Ghost -->",
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
});
|