UNPKG

@kloudsoftware/eisen

Version:

Declarative and expressive TypeScript framework for building modern web applications

3 lines (2 loc) 23.8 kB
function arraysEquals(t,e){if(null==t&&null==e)return!0;if(t.length!=e.length)return!1;for(let n=0;n<t.length;n++)if(!t[n].equals(e[n]))return!1;return!0}const dataRegex=/{{(.*?)}}/g;class Stringparser{constructor(){}static getFromProps(t,e){let n=t.split("{{")[1].split("}}")[0].trim();return e.getProp(n)}static buildStringFunc(t,e,n){return n.split(t).join(Stringparser.getFromProps(t,e))}parse(t,e){let n=dataRegex.exec(t);if(null==n||0==n.length)return t;let r=t.match(dataRegex),s="";return r.forEach(n=>s=Stringparser.buildStringFunc(n,e,""!==s?s:t)),s}}const invokeIfDefined=t=>{null!=t&&t()},getOrNoop=t=>isFunction(t)?t:()=>{};function isFunction(t){return t&&"[object Function]"==={}.toString.call(t)}const isDefinedAndNotEmpty=t=>null!=t&&""!=t;function raceToSuccess(t){return Promise.all(t.map(t=>t.then(t=>Promise.reject(t),t=>Promise.resolve(t)))).then(t=>Promise.reject(t),t=>Promise.resolve(t))}class EventPipeline{constructor(){this.events=new Map}registerEvent(t,e){this.events.has(t)?this.events.get(t).push(e):this.events.set(t,[e])}callEvent(t,e){const n=this.events.get(t);void 0!==n&&n.forEach(t=>t(e))}}class ComponentEventPipeline extends EventPipeline{constructor(){super(...arguments),this.components=[]}callEventComponent(t,e){this.components.map(e=>e[t]).filter(t=>null!=t).forEach(t=>t(e))}removeComponent(t){-1!==this.components.indexOf(t)&&this.components.splice(this.components.indexOf(t),1)}}class Component{constructor(t){this.subComponents=new Map,this.componentEvent=new ComponentEventPipeline,this.rerender=()=>{var t,e,n,r;null==(t=(e=this.lifeCycle()).beforererender)||t.call(e),this.forcedUpdate(),this.subComponents.forEach(t=>t.rerender()),null==(n=(r=this.lifeCycle()).afterrerender)||n.call(r)},this.forcedUpdate=()=>{this.app.rerenderComponent(this,this.props)},this.emit=(t,e)=>{this.componentEvent.callEventComponent(t,e)},this.app=t}mount(t,e,n,r){if(this.subComponents.has(r))return this.subComponents.get(r);const s=new t(e);return this.subComponents.set(r,s),this.app.mountSubComponent(s,n,this.props,this),s}mountArgs(t,e,n,r,...s){if(this.subComponents.has(r))return this.subComponents.get(r);const i=new t(e,s);return this.subComponents.set(r,i),this.app.mountSubComponent(i,n,this.props,this),i}}const reactiveWatchersKey=Symbol("reactiveWatchers");function reactive(){const t=Symbol(),e=Symbol();return(n,r)=>{Object.defineProperty(n,r,{set:function(n){var s;if(this[e]=void 0===this[e],!this[e]&&this[t]===n)return;this[t]=n;const i=null==(s=this[reactiveWatchersKey])?void 0:s[r];i&&(i.forEach(t=>t(n)),this[reactiveWatchersKey][r]=[]),this.rerender()},get:function(){return this[t]},configurable:!0})}}class ComponentProps{}class ComponentHolder{constructor(t,e){this.mounted=[!1,t.mounted],this.remount=[!0,t.remount],this.unmounted=t.unmounted,this.component=e}}class Props{constructor(t,e){this.cbs=new Map,null==e&&(e=new Map),this.props=e,this.app=t,this.callbacksExclusive=new Map}registerCallback(t,e,n=!1){if(n)this.callbacksExclusive.set(t,e);else if(this.cbs.has(t))this.cbs.get(t).push(e);else{const n=[e];this.cbs.set(t,n),this.cbs.set(t,n)}}setPropSilent(t,e){this.props.set(t,e),this.notifyCallbacks(t,e)}setProp(t,e){this.props.set(t,e),this.notifyCallbacks(t,e),this.app.notifyDirty()}notifyCallbacks(t,e){this.cbs.has(t)&&this.cbs.get(t).forEach(t=>t(e)),this.callbacksExclusive.has(t)&&this.callbacksExclusive.get(t)(e)}getProp(t){let e=this.props.get(t);if(null!=e)return e}clearCallbacks(){}}class Resolver{getPrefix(){return"$_"}isStrict(){return!1}}class StringLocaleResolver extends Resolver{constructor(t){super(),this.localeStringObj=t}get(t,e){return new Promise((n,r)=>{const s=this.localeStringObj[t];null==s&&r(`Could not find a match for ${t} for locale ${e}`);const i=s[e];null!=i?n(i):r(`Could not find a match for ${t} for locale ${e}`)})}}const getLocale=()=>{let t=window.localStorage.getItem("locale");return null==t&&(t=navigator.language),t},setLocale=t=>{window.localStorage.setItem("locale",t)},toggleError=t=>{t.addClass("error")},parse=(t,e)=>{const n=[];for(let e=0;e<t.attributes.length;e++){const r=t.attributes.item(e);n.push(new Attribute(r.name,r.value))}const r=e.k(t.nodeName,{attrs:n}),s=Array.from(t.children).filter(t=>t.nodeType===Node.TEXT_NODE).map(t=>t.nodeValue);return r.$setInnerHtmlNoDirty(null!=s&&s.length>0?s[0]:""),Array.from(t.children).map(t=>parse(t,e)).forEach(t=>{t.parent=r,r.$getChildren().push(t)}),r},parseStrIntoVNode=(t,e)=>{const n=(new DOMParser).parseFromString(t,"text/html");let r=Array.from(n.body.children).map(t=>parse(t,e));const s=e.k("div",{},r);return r.forEach(t=>{t.parent=s,s.$getChildren().push(t)}),s},parseIntoUnmanaged=(t,e)=>{const n=e.app.createUnmanagedNoDirty(e);return n.addOnDomEventOrExecute(e=>{e.innerHTML=t}),n};class VNode{constructor(t,e,n,r,s,i,o,l,a){if(this.dynamicContent=!1,this.modifiedInnerHtml=!1,this.onDomEvenList=new Array,this.rawInnerHtml=void 0,this.lastResolvedLocale=void 0,this.isRouterLink=!1,this.value=void 0,this.addClass=t=>{this.app.notifyDirty();let e=this.attrs.filter(t=>"class"==t.attrName)[0];return null==e?(e=new Attribute("class",t),void this.attrs.push(e)):(e.attrValue=e.attrValue+" "+t,this)},this.hasClass=t=>{const e=this.attrs.filter(t=>"class"==t.attrName)[0];return null!=e&&-1!=e.attrValue.indexOf(t)},this.removeClass=t=>{this.app.notifyDirty();const e=this.attrs.filter(t=>"class"==t.attrName)[0];if(null!=e)return e.attrValue=e.attrValue.replace(t,""),this},this.attrs=null==i?[]:i,this.app=t,null==s&&(s=new Props(t)),this.props=s,this.nodeName=e,this.innerHtml=r,this.parent=o,this.children=n,this.value=a,this.id=null!=l?l:Math.random().toString(36).substr(2,9),null!=r){let t=r.match(dataRegex);null!=t&&0!=t.length&&(this.dynamicContent=!0)}this.attrs.map(t=>t.attrName).forEach(t=>{this.app.renderer.$knownAttributes.add(t)})}addFocusListener(t){null!=this.htmlElement?this.htmlElement.addEventListener("focus",t):this.onDomEvenList.push(e=>{e.addEventListener("focus",t)})}setHtmlElement(t){this.htmlElement=t,this.onDomEvenList.forEach(e=>e(t))}addOnDomEventOrExecute(t){null!=this.htmlElement?t(this.htmlElement):this.onDomEvenList.push(t)}$getAttrs(){return this.attrs}getAttributeValue(t){if(null==this.attrs)return null;const e=this.attrs.find(e=>e.attrName==t);return null!=e?e.attrValue:null}addBlurListener(t){null!=this.htmlElement?this.htmlElement.addEventListener("blur",t):this.onDomEvenList.push(e=>{e.addEventListener("blur",t)})}removeAttribute(t){const e=this.attrs.filter(e=>e.attrName==t);if(null!=e&&0!=e.length)return this.attrs.splice(this.attrs.indexOf(e[0],1)),void this.app.notifyDirty()}setAttribute(t,e){this.$setAttribute(t,e),this.app.notifyDirty()}$setAttribute(t,e){const n=this.attrs.filter(e=>e.attrName==t).length>0;this.app.renderer.$knownAttributes.add(t),n?this.attrs.filter(e=>e.attrName==t)[0].attrValue=e:this.attrs.push(new Attribute(t,e))}$getChildren(){return this.children}setInnerHtml(t){this.app.notifyDirty(),this.modifiedInnerHtml=!0,this.innerHtml=t}$setInnerHtmlNoDirty(t){this.modifiedInnerHtml=!0,this.innerHtml=t}getInnerHtml(){const t=getLocale(),e=null!=this.rawInnerHtml?this.rawInnerHtml:this.innerHtml;return null!=this.app.i18nResolver&&this.app.i18nResolver.some(t=>e.startsWith(t.getPrefix()))&&t!=this.lastResolvedLocale&&this.resolvei18n().catch(t=>console.error(t)),(new Stringparser).parse(this.innerHtml,this.props)}replaceChild(t,e){this.replaceWith(t,e)}removeChild(t){this.app.notifyDirty(),this.replaceWith(t,void 0)}appendChild(t){this.app.notifyDirty(),t.parent=this,this.children.push(t)}appendChildren(t){t.forEach(t=>this.appendChild(t))}addEventlistener(t,e,n=!0){this.app.eventHandler.registerEventListener(t,e,this,n)}$clone(t){const e=this.id,n=this.nodeName,r=this.innerHtml,s=this.value,i=this.key,o=Object.assign(this.props,{}),l=this.attrs.map(t=>t.clone()),a=new VNode(this.app,n,[],r,o,l,t,e,s);a.key=i;const h=new Array;return this.children.forEach(t=>{h.push(t.$clone(a))}),a.children=h,this.addOnDomEventOrExecute(t=>{a.htmlElement=t}),a}equals(t){return null!=t&&this.nodeName==t.nodeName}$replaceWith(t,e){let n=-1;for(let e=0;e<this.children.length;e++)if(this.children[e]==t){n=e;break}-1!=n&&null!=e?this.children[n]=e:this.children.splice(n,1)}resolvei18n(){return new Promise((t,e)=>{const n=getLocale(),r=null!=this.rawInnerHtml?this.rawInnerHtml:this.innerHtml,s=this.app.i18nResolver.filter(t=>r.startsWith(t.getPrefix())),i=s.filter(t=>t.isStrict()).map(t=>t.get(r,n)),o=s.filter(t=>!t.isStrict()).map(t=>t.get(r,n.split("-")[0])),l=t=>{null!=t&&(null==this.rawInnerHtml&&(this.rawInnerHtml=r),this.lastResolvedLocale=n,this.setInnerHtml(t))};raceToSuccess(i).then(e=>{l(e),t()}).catch(n=>{raceToSuccess(o).then(e=>{l(e),t()}).catch(t=>e(t))})})}replaceWith(t,e){this.app.notifyDirty(),this.$replaceWith(t,e)}}const cssClass=(...t)=>{if(1==t.length)return new Attribute("class",t[0]);const e=t.reduce((t,e)=>t+e+" ","").trim();return new Attribute("class",e)},id=t=>new Attribute("id",t),labelFor=t=>new Attribute("for",t),password=()=>new Attribute("type","password"),email=()=>new Attribute("type","email"),inputType=t=>new Attribute("type",t),placeholder=t=>new Attribute("placeholder",t),src=t=>new Attribute("src",t),style=t=>new Attribute("style",t);class Attribute{constructor(t,e){this.attrName=t,this.attrValue=e}clone(){return new Attribute(this.attrName,this.attrValue)}equals(t){return this.attrName==t.attrName&&this.attrValue==t.attrValue}}class VInputNode extends VNode{constructor(){super(...arguments),this.validationFuncs=new Array,this.hasError=!1,this.hasValidateBlurFunction=!1}bindObject(t,e){null==t[reactiveWatchersKey]&&(t[reactiveWatchersKey]={}),null==t[reactiveWatchersKey][e]&&(t[reactiveWatchersKey][e]=new Array),t[reactiveWatchersKey][e].push(t=>{this.value=t}),this.app.eventHandler.registerEventListener("input",(n,r)=>{if("file"==r.getAttributeValue("type")){const n=r.htmlElement.files;t[e]=null!=n?n[0]:null}else this.value=r.htmlElement.value,t[e]=r.htmlElement.value},this)}bind(t,e){this.onDomEvenList.push(()=>{this.htmlElement.value=null!=t.getProp(e)?t.getProp(e):"",this.value=this.htmlElement.value}),t.registerCallback(e,t=>{null!=this.htmlElement&&(this.value=t,this.htmlElement.value=t)},!0),this.app.eventHandler.registerEventListener("input",(n,r)=>{t.setProp(e,r.htmlElement.value),this.value=r.htmlElement.value},this)}doValidation(t){return!this.validationFuncs.map(e=>{let n=e[0](t);if(0==n){if(this.hasClass(e[1]))return n;this.hasError=!0,this.addClass(e[1])}else this.hasClass(e[1])&&this.removeClass(e[1]);return n}).some(t=>0==t)}validate(t,e){this.validationFuncs.push([t,e]),this.hasValidateBlurFunction||this.addBlurListener(t=>{this.doValidation(!0)})}}const splitAtSlash=t=>t.split("/"),stringIncludesCurlyBrace=t=>t.includes("{"),pathVariableRegex=/{([a-zA-Z$_][a-zA-Z$_0-9]+)}/;function splitPathVars(t){return splitAtSlash(t).map(t=>pathVariableRegex.exec(t)).filter(t=>null!=t).map(t=>t[1])}function matchSubPath(t,e){for(let n=0;n<t.length;n++){const r=t[n],s=e[n];if(null==s)return!1;if(!stringIncludesCurlyBrace(r)&&r!=s)return!1}return!0}class Router{constructor(t,e){this.resolvedRouterMap=new Map,this.componentMap=new Map,this.currPath=void 0,this.middleWares=new Array,this.pathVariables=[],this.mount=e,this.app=t,window.onpopstate=()=>{this.resolveRoute(document.location.pathname)}}useMiddleWare(t){this.middleWares.push(t)}registerRoute(t,e,n){null==n&&(n=new Props(this.app)),splitPathVars(t).length>0&&this.pathVariables.push(t),this.componentMap.set(t,[e,n])}hasRouteRegistered(t){return null!=this.findMatchingPath(t)}findMatchingPath(t){if(this.componentMap.has(t))return t;t.endsWith("/")&&(t=t.substr(0,t.length-1));const e=splitAtSlash(t),n=e.length-1,r=this.pathVariables.filter(t=>splitAtSlash(t).length-1==n);for(let t of r)if(matchSubPath(t.split("/"),e))return t}resolveRoute(t){return Promise.all(this.middleWares.map(e=>e.check(t))).then(()=>{if(history.replaceState(null,"",t),this.currPath==t)return Promise.resolve(!0);if(this.resolvedRouterMap.has(t))return this.mount.$getChildren().forEach(t=>this.mount.removeChild(t)),this.app.remountComponent(this.resolvedRouterMap.get(t),this.mount),this.currPath=t,Promise.resolve(!0);const e=this.findMatchingPath(t);if(null==e)return Promise.reject("No component registered with the router for "+t+" register one using 'registerRoute()'");this.mount.$getChildren().forEach(t=>this.mount.removeChild(t)),this.currPath=t;let n=this.componentMap.get(e);if(stringIncludesCurlyBrace(e)){const r=splitAtSlash(e),s=splitAtSlash(t),i=n[1].props;for(let t=0;t<r.length;t++)if(stringIncludesCurlyBrace(r[t])){const e="_"+r[t].replace("{","").replace("}","");i.setProp(e,s[t])}}return this.resolvedRouterMap.set(t,this.app.routerMountComponent(n[0],this.mount,n[1])),Promise.resolve(!0)})}}const isRouterLink=t=>t.isRouterLink;class RouterLink extends VNode{constructor(t,e,n,r,s,i,o,l){super(t,"a",n,r,s,i,o,l),this.isRouterLink=!0,this.target=e,this.attrs.push(new Attribute("href",e)),this.addEventlistener("click",this.clickFunction)}clickFunction(t,e){const n=e;if(n.app.router.hasRouteRegistered(n.target))return t.preventDefault(),history.pushState({},"",document.location.pathname),void n.app.router.resolveRoute(n.target).catch(t=>console.error("Error occured in routing: ",t))}}class EventHandler{constructor(t){this.events=["click","close","complete","copy","cut","deviceorientation","DOMContentLoaded","keyup","drag","dragend","dragenter","dragleave","dragover","dragstart","drop","durationchange","ended","endEvent","error","focusin","focusout","fullscreenchange","fullscreenerror","input","invalid","keydown","keypress","mousedown","mouseenter","mouseleave","mousemove","mouseout","mouseover","mouseup","offline","online","open","orientationchange","pagehide","pageshow","paste","pause","play","playing","progress","readystatechange","reset","scroll","seeked","seeking","select","show","stalled","storage","submit","success","suspend","timeout","timeupdate","touchcancel","touchend","touchenter","touchleave","touchmove","touchstart","visibilitychange","volumechange","waiting","wheel","change"],this.handlers=new Map,this.routerLnks=new Array;const e=t.rootNode.htmlElement;this.events.forEach(t=>{e.addEventListener(t,this.handleEvent(this))})}purge(t,e=!1){e&&t.$getChildren().forEach(t=>this.purge(t,!0)),this.handlers.forEach(e=>{e.forEach((n,r)=>{r===t&&e.delete(r)})})}registerEventListener(t,e,n,r=!0){isRouterLink(n)&&this.routerLnks.push(n),null==this.handlers&&(this.handlers=new Map);let s=this.handlers.get(t);null==s&&(s=new Map),null!=s.get(n)?s.get(n).push([e,r]):s.set(n,[[e,r]]),this.handlers.set(t,s)}handleEvent(t){return e=>{if(null==t.handlers)return;const n=e.target,r=t.handlers.get(e.type);if(null==r)return;let s=!1;Array.from(r.keys()).filter(t=>function t(e,n){return e==n||null!=n.parentElement&&t(e,n.parentElement)}(t.htmlElement,n)).forEach(t=>{r.get(t).forEach(n=>{if(s=!0,!n[1])return;const r=n[0](e,t);!1===r&&e.preventDefault(),r&&isRouterLink(t.parent)&&"click"==e.type&&t.parent.clickFunction(e,t.parent)})}),s||this.routerLnks.filter(t=>t.htmlElement==n.parentNode).forEach(t=>{e.preventDefault(),t.clickFunction(e,t)})}}}let currentApp;function jsx(t,e,...n){if(!currentApp)throw new Error("No VApp configured for JSX. Call setJSXApp first.");const r=[],s=[];let i=new Props(currentApp),o="",l=void 0,a=void 0;if(e){e.props&&e.props instanceof Props&&(i=e.props,delete e.props),"string"==typeof e.value&&(o=e.value,delete e.value);let t=!0;if(Object.keys(e).forEach(n=>{const i=e[n];if(!1!==i&&null!=i)if(n.startsWith("e-if")&&"function"==typeof i&&(t=i()),"ref"===n&&"function"==typeof i&&(l=i),"key"!==n)if(n.startsWith("on")&&"function"==typeof i){const t=n.substring(2).toLowerCase();s.push([t,i])}else r.push(new Attribute(n,String(i)));else a=String(i)}),!t)return null}const h=[];n.forEach(t=>{"string"==typeof t?o+=t:Array.isArray(t)?t.forEach(t=>{"string"==typeof t?o+=t:t&&h.push(t)}):t&&h.push(t)});const u=currentApp.k(t,{attrs:r,props:i,value:o},h);return void 0!==a&&(u.id=a,u.key=a),s.forEach(([t,e])=>u.addEventlistener(t,e)),l&&l(u),u}function setJSXApp(t){currentApp=t}globalThis.jsx=jsx;const unmanagedNode="__UNMANAGED__";class VApp{constructor(t,e,n){this.snapshots=[],this.eventListeners=[],this.initial=!0,this.compProps=new Array,this.compsToNotifyUnmount=new Array,this.pluginMap=new Map,this.oneTimeRenderCallbacks=new Array,this.eventPipeLine=new EventPipeline,setJSXApp(this),this.targetId=t,this.renderer=e;let r=document.getElementById(t),s=r.tagName.toLowerCase();this.dirty=!1,null!=n?this.rootNode=n.$clone(void 0):(this.rootNode=new VNode(this,s,new Array,"",new Props(this),[new Attribute("id",r.id)],void 0),this.rootNode.htmlElement=r),this.eventHandler=new EventHandler(this)}useRouter(t){return this.router=new Router(this,t),this.router}useCustomRouter(t){return this.router=t,this.router}addInitialRenderEventlistener(t){this.eventListeners.push(t)}mountComponent(t,e,n){let r=this.k("div");r.parent=e,t.app=this,t.props=n,e.$getChildren().push(r);let s=t.render(n);return r.$getChildren().push(s),t.$mount=r,this.compProps.push(new ComponentHolder(t.lifeCycle?t.lifeCycle():{},t)),this.notifyDirty(),r}mountSubComponent(t,e,n,r){t.componentEvent=r.componentEvent,this.mountComponent(t,e,n)}rerenderComponent(t,e){if(!t.$mount)return;t.props.clearCallbacks(),this.eventHandler.purge(t.$mount,!0);const n=t.$mount.children[0],r=t.render(e);n&&(r.id=n.id),t.$mount.children=[r],this.notifyDirty()}notifyUnmount(t){this.eventHandler.purge(t,!0),this.compProps.filter(e=>e.component.$mount===t).forEach(t=>{t.component.componentEvent.removeComponent(t.component),this.compProps.splice(this.compProps.indexOf(t),1),invokeIfDefined(t.unmounted)})}routerMountComponent(t,e,n){t.app=this,t.props=n;let r,s=t.render(n);return e.children.push(s),t.$mount=s,r=new ComponentHolder(t.lifeCycle?t.lifeCycle():{},t),this.compProps.push(r),r}remountComponent(t,e){t.remount[0]=!1,e.appendChild(t.component.$mount),this.compProps.includes(t)||this.compProps.push(t)}unmountComponent(t){const e=this.compProps.filter(e=>e.component.$mount==t);if(0==e.length)return void console.error("Node is not component mount");if(!e[0].mounted)return void console.error("Component cannot be unmounted before it was mounted");let n=e[0];n.component.$mount.parent?(n.component.componentEvent.removeComponent(n.component),n.component.$mount.parent.removeChild(n.component.$mount),this.compProps.splice(this.compProps.indexOf(n),1),this.compsToNotifyUnmount.push(n.unmounted)):console.error("Component is not on dom")}getComponentsWithMountAs(t){return this.compProps.filter(e=>e.component.$mount==t).map(t=>t.component)}init(){this.snapshots.push(this.clone()),this.tick()}notifyDirty(){this.dirty=!0}getLatestSnapshot(){if(!(this.snapshots.length<1))return this.snapshots[this.snapshots.length-1]}getPreviousSnapshot(){if(!(this.snapshots.length<2))return this.snapshots[this.snapshots.length-2]}clone(){return new VApp(this.targetId,this.renderer,this.rootNode)}createElement(t,e="",n,r,s){let i;return this.notifyDirty(),null==s&&(s=new Props(this)),null==n&&(n=this.rootNode),i="input"==t?new VInputNode(this,t,new Array,e,s,r,n):new VNode(this,t,new Array,e,s,r,n),n.appendChild(i),i}createUnmanagedNode(t){return this.notifyDirty(),this.createUnmanagedNoDirty(t)}createUnmanagedNoDirty(t){let e=new VNode(this,"div",[],"",new Props(this),[],t,"__UNMANAGED__");return t.$getChildren().push(e),e}k(t,e,n){let r,s,i;null==n&&(n=[]),null==e?(r=[],i="",s=new Props(this)):(r=null!=e.attrs?e.attrs:[],s=null!=e.props?e.props:new Props(this),i=null!=e.value?e.value:"");let o,l=n.filter(t=>!0);return o="input"==t||"textarea"==t||"select"==t?new VInputNode(this,t,l,i,s,r,void 0,void 0,i):new VNode(this,t,l,i,s,r),l.forEach(t=>{t.parent=o}),o}use(t,e){this.pluginMap.set(t,e)}get(t){return this.pluginMap.get(t)}useTranslationResolver(t){null==this.i18nResolver&&(this.i18nResolver=new Array),this.i18nResolver.push(t)}tick(){setInterval(()=>{this.dirty&&(this.renderer.diffAgainstLatest(this)(this.rootNode.htmlElement),this.dirty=!1,this.initial&&(this.initial=!1,this.eventListeners.forEach(t=>t())),this.compProps.filter(t=>void 0!==t.mounted).filter(t=>!t.mounted[0]).forEach(t=>{t.mounted[0]=!0,getOrNoop(t.mounted[1])(t.component)}),this.compProps.filter(t=>void 0!==t.remount).filter(t=>!t.remount[0]).forEach(t=>{t.remount[0]=!0,getOrNoop(t.remount[1])(t.component)}),this.compsToNotifyUnmount.forEach(t=>invokeIfDefined(t)),this.compsToNotifyUnmount=[])},50)}}class Renderer{constructor(){this.$knownAttributes=new Set}static removeElement(t,e){e.app.eventHandler.purge(e,!0),e.app.notifyUnmount(e),e.htmlElement.remove()}diffAgainstLatest(t){const e=t.getLatestSnapshot(),n=e?this.diff(e,t):t=>t;return e=>{const r=n(e);return t.snapshots.push(t.clone()),r}}diff(t,e){return this.diffElement(t.rootNode,e.rootNode)}renderTree(t){let e=document.createElement(t.nodeName);return e.innerHTML=t.getInnerHtml(),t.$getAttrs().forEach(t=>e.setAttribute(t.attrName,t.attrValue)),t.$getChildren().forEach(t=>{e.appendChild(this.renderTree(t))}),t.setHtmlElement(e),e}diffElement(t,e){if(null==e)return null==t?t=>t:e=>(Renderer.removeElement(e,t),e);if(null==t)return t=>(t.appendChild(this.renderTree(e)),t);if(e.id==unmanagedNode)return t=>t;if(!t.equals(e))return n=>(t.app.eventHandler.purge(t,!0),t.app.notifyUnmount(t),n.replaceChild(this.renderTree(e),t.htmlElement),n);const n=[],r=t.$getChildren(),s=e.$getChildren();r.length===s.length&&s.forEach((t,e)=>{void 0===t.key&&r[e]&&void 0===r[e].key&&(t.id=r[e].id)});const i=new Map;r.forEach(t=>i.set(t.id,t)),s.forEach((t,e)=>{const r=i.get(t.id);r?(n.push(t=>{var n;const s=null!=(n=t.children[e])?n:null;return r.htmlElement&&r.htmlElement!==s&&t.insertBefore(r.htmlElement,s),t}),n.push(this.diffElement(r,t)),i.delete(t.id)):n.push(n=>{var r;const s=null!=(r=n.children[e])?r:null;return n.insertBefore(this.renderTree(t),s),n})}),i.forEach(t=>{n.push(e=>(Renderer.removeElement(e,t),e))});let o=this.diffAttributes(t,e),l=this.diffInnerHtml(t,e),a=this.diffValue(t,e);return r=>(t.addOnDomEventOrExecute(t=>{n.forEach(e=>e(t)),o(t),l(t),a(t)}),e.app.eventHandler.purge(t),e.setHtmlElement(t.htmlElement),r)}diffInnerHtml(t,e){return t.getInnerHtml()!==e.getInnerHtml()||e.dynamicContent?t=>(t.innerHTML=e.getInnerHtml(),t):t=>t}diffAttributes(t,e){let n=[],r=[];e.htmlElement&&(r=Array.from(e.htmlElement.attributes).filter(t=>this.$knownAttributes.has(t.name)));const s=new Map,i=new Map;return r.forEach(t=>{s.set(t.name,t.value)}),e.$getAttrs().forEach(t=>{i.set(t.attrName,t.attrValue)}),s.forEach((t,e)=>{const r=i.get(e);return void 0===r?(n.push(t=>(t.removeAttribute(e),t)),void i.delete(e)):r!==t?(n.push(t=>(t.setAttribute(e,r),t)),void i.delete(e)):void 0}),i.forEach((t,e)=>{n.push(n=>(n.setAttribute(e,t),n))}),t=>(n.forEach(e=>e(t)),t)}diffValue(t,e){return t.value!==e.value?t=>(t instanceof HTMLInputElement&&(t.value=e.value),t):t=>t}}function compileTsx(source,jsxFactory="jsx"){const ts=eval("require")("typescript"),result=ts.transpileModule(source,{compilerOptions:{jsx:ts.JsxEmit.React,jsxFactory,module:ts.ModuleKind.ESNext,target:ts.ScriptTarget.ES2017}});return result.outputText}export{Attribute,Component,ComponentEventPipeline,ComponentHolder,ComponentProps,EventHandler,EventPipeline,Props,Renderer,Resolver,Router,RouterLink,StringLocaleResolver,Stringparser,VApp,VInputNode,VNode,arraysEquals,compileTsx,cssClass,dataRegex,email,getLocale,getOrNoop,id,inputType,invokeIfDefined,isDefinedAndNotEmpty,isRouterLink,jsx,labelFor,parseIntoUnmanaged,parseStrIntoVNode,password,placeholder,raceToSuccess,reactive,reactiveWatchersKey,setJSXApp,setLocale,src,style,toggleError,unmanagedNode}; //# sourceMappingURL=index.modern.js.modern.js.map