@symbiotejs/symbiote 1.9.0 → 1.10.0

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.
@@ -1 +1 @@
1
- var O=Object.defineProperty;var N=(l,t,e)=>t in l?O(l,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):l[t]=e;var S=(l,t,e)=>(N(l,typeof t!="symbol"?t+"":t,e),e);function $(l){let t=e=>{var s;for(let i in e)((s=e[i])==null?void 0:s.constructor)===Object&&(e[i]=t(e[i]));return{...e}};return t(l)}var c=class{constructor(t){this.uid=Symbol(),this.name=t.name||null,t.schema.constructor===Object?this.store=$(t.schema):(this._storeIsProxy=!0,this.store=t.schema),this.callbackMap=Object.create(null)}static warn(t,e){console.warn(`Symbiote Data: cannot ${t}. Prop name: `+e)}read(t){return!this._storeIsProxy&&!this.store.hasOwnProperty(t)?(c.warn("read",t),null):this.store[t]}has(t){return this._storeIsProxy?this.store[t]!==void 0:this.store.hasOwnProperty(t)}add(t,e,s=!1){if(!s&&Object.keys(this.store).includes(t)){e!==this.store[t]&&this.notify(t);return}this.store[t]=e,this.notify(t)}pub(t,e){if(!this._storeIsProxy&&!this.store.hasOwnProperty(t)){c.warn("publish",t);return}this.store[t]=e,this.notify(t)}multiPub(t){for(let e in t)this.pub(e,t[e])}notify(t){this.callbackMap[t]&&this.callbackMap[t].forEach(e=>{e(this.store[t])})}sub(t,e,s=!0){return!this._storeIsProxy&&!this.store.hasOwnProperty(t)?(c.warn("subscribe",t),null):(this.callbackMap[t]||(this.callbackMap[t]=new Set),this.callbackMap[t].add(e),s&&e(this.store[t]),{remove:()=>{this.callbackMap[t].delete(e),this.callbackMap[t].size||delete this.callbackMap[t]},callback:e})}remove(){delete c.globalStore[this.uid]}static registerLocalCtx(t){let e=new c({schema:t});return c.globalStore[e.uid]=e,e}static registerNamedCtx(t,e){let s=c.globalStore[t];return s?console.warn('State: context name "'+t+'" already in use'):(s=new c({name:t,schema:e}),c.globalStore[t]=s),s}static clearNamedCtx(t){delete c.globalStore[t]}static getNamedCtx(t,e=!0){return c.globalStore[t]||(e&&console.warn('State: wrong context name - "'+t+'"'),null)}};c.globalStore=Object.create(null);var o=Object.freeze({BIND_ATTR:"set",ATTR_BIND_PRFX:"@",EXT_DATA_CTX_PRFX:"*",NAMED_DATA_CTX_SPLTR:"/",CTX_NAME_ATTR:"ctx-name",CSS_CTX_PROP:"--ctx-name",EL_REF_ATTR:"ref",AUTO_TAG_PRFX:"sym",REPEAT_ATTR:"repeat",REPEAT_ITEM_TAG_ATTR:"repeat-item-tag",SET_LATER_KEY:"__toSetLater__"});var y="1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm",k=y.length-1,g=class{static generate(t="XXXXXXXXX-XXX"){let e="";for(let s=0;s<t.length;s++)e+=t[s]==="-"?t[s]:y.charAt(Math.random()*k);return e}};function E(l,t,e){let s=!0,i,r=t.split(".");return r.forEach((n,h)=>{h<r.length-1?l=l[n]:i=n}),l?l[i]=e:s=!1,s}function x(l){return l.split("-").map((t,e)=>t&&e?t[0].toUpperCase()+t.slice(1):t).join("").split("_").map((t,e)=>t&&e?t.toUpperCase():t).join("")}function R(l,t){[...l.querySelectorAll(`[${o.REPEAT_ATTR}]`)].forEach(e=>{let s=e.getAttribute(o.REPEAT_ITEM_TAG_ATTR),i;if(s&&(i=window.customElements.get(s)),!i){i=class extends t.BaseComponent{constructor(){super();s||(this.style.display="contents")}};let n=e.innerHTML;i.template=n,i.reg(s)}for(;e.firstChild;)e.firstChild.remove();let r=e.getAttribute(o.REPEAT_ATTR);t.sub(r,n=>{if(!n){for(;e.firstChild;)e.firstChild.remove();return}let h=[...e.children],f,b=u=>{u.forEach((a,p)=>{if(h[p])if(h[p].set$)h[p].set$(a);else for(let C in a)h[p][C]=a[C];else{f||(f=new DocumentFragment);let C=new i;Object.assign(C.init$,a),f.appendChild(C)}}),f&&e.appendChild(f);let d=h.slice(u.length,h.length);for(let a of d)a.remove()};if(n.constructor===Array)b(n);else if(n.constructor===Object){let u=[];for(let d in n){let a=n[d];Object.defineProperty(a,"_KEY_",{value:d,enumerable:!0}),u.push(a)}b(u)}else console.warn("Symbiote repeat data type error:"),console.log(n)}),e.removeAttribute(o.REPEAT_ATTR),e.removeAttribute(o.REPEAT_ITEM_TAG_ATTR)})}function I(l,t){if(t.shadowRoot)return;let e=[...l.querySelectorAll("slot")];if(t.initChildren.length&&e.length){let s={};e.forEach(i=>{let r=i.getAttribute("name");r?s[r]={slot:i,fr:document.createDocumentFragment()}:s.__default__={slot:i,fr:document.createDocumentFragment()}}),t.initChildren.forEach(i=>{var n;let r=(n=i.getAttribute)==null?void 0:n.call(i,"slot");r?(i.removeAttribute("slot"),s[r].fr.appendChild(i)):s.__default__&&s.__default__.fr.appendChild(i)}),Object.values(s).forEach(i=>{i.slot.parentNode.insertBefore(i.fr,i.slot),i.slot.remove()})}}function L(l,t){[...l.querySelectorAll(`[${o.EL_REF_ATTR}]`)].forEach(e=>{let s=e.getAttribute(o.EL_REF_ATTR);t.ref[s]=e,e.removeAttribute(o.EL_REF_ATTR)})}function M(l,t){[...l.querySelectorAll(`[${o.BIND_ATTR}]`)].forEach(e=>{let i=e.getAttribute(o.BIND_ATTR).split(";");[...e.attributes].forEach(r=>{if(r.name.startsWith("-")&&r.value){let n=x(r.name.replace("-",""));i.push(n+":"+r.value),e.removeAttribute(r.name)}}),i.forEach(r=>{if(!r)return;let n=r.split(":").map(u=>u.trim()),h=n[0],f;h.indexOf(o.ATTR_BIND_PRFX)===0&&(f=!0,h=h.replace(o.ATTR_BIND_PRFX,""));let b=n[1].split(",").map(u=>u.trim());for(let u of b){let d;u.startsWith("!!")?(d="double",u=u.replace("!!","")):u.startsWith("!")&&(d="single",u=u.replace("!","")),t.sub(u,a=>{d==="double"?a=!!a:d==="single"&&(a=!a),f?(a==null?void 0:a.constructor)===Boolean?a?e.setAttribute(h,""):e.removeAttribute(h):e.setAttribute(h,a):E(e,h,a)||(e[o.SET_LATER_KEY]||(e[o.SET_LATER_KEY]=Object.create(null)),e[o.SET_LATER_KEY][h]=a)})}}),e.removeAttribute(o.BIND_ATTR)})}var P="{{",A="}}",j="skip-text";function F(l){let t,e=[],s=document.createTreeWalker(l,NodeFilter.SHOW_TEXT,{acceptNode:i=>{var r;return!((r=i.parentElement)==null?void 0:r.hasAttribute(j))&&i.textContent.includes(P)&&i.textContent.includes(A)&&1}});for(;t=s.nextNode();)e.push(t);return e}var K=function(l,t){F(l).forEach(s=>{let i=[],r;for(;s.textContent.includes(A);)s.textContent.startsWith(P)?(r=s.textContent.indexOf(A)+A.length,s.splitText(r),i.push(s)):(r=s.textContent.indexOf(P),s.splitText(r)),s=s.nextSibling;i.forEach(n=>{let h=n.textContent.replace(P,"").replace(A,"");t.sub(h,f=>{n.textContent=f})})})},w=[R,I,L,M,K];var D=0,m=null,_=null,T=class extends HTMLElement{constructor(){super();S(this,"updateCssData",()=>{var t;this.dropCssDataCache(),(t=this.__boundCssProps)==null||t.forEach(e=>{let s=this.getCssData(this.__extractCssName(e),!0);this.$[e]!==s&&(this.$[e]=s)})});this.init$=Object.create(null),this.cssInit$=Object.create(null),this.tplProcessors=new Set,this.ref=Object.create(null),this.allSubs=new Set,this.pauseRender=!1,this.renderShadow=!1,this.readyToDestroy=!0,this.processInnerHtml=!1}get BaseComponent(){return T}initCallback(){}__initCallback(){var t;this.__initialized||(this.__initialized=!0,(t=this.initCallback)==null||t.call(this))}render(t,e=this.renderShadow){let s;if((e||this.constructor.__shadowStylesUrl)&&!this.shadowRoot&&this.attachShadow({mode:"open"}),this.processInnerHtml)for(let r of this.tplProcessors)r(this,this);if(t||this.constructor.template){if(this.constructor.template&&!this.constructor.__tpl&&(this.constructor.__tpl=document.createElement("template"),this.constructor.__tpl.innerHTML=this.constructor.template),(t==null?void 0:t.constructor)===DocumentFragment)s=t;else if((t==null?void 0:t.constructor)===String){let r=document.createElement("template");r.innerHTML=t,s=r.content.cloneNode(!0)}else this.constructor.__tpl&&(s=this.constructor.__tpl.content.cloneNode(!0));for(let r of this.tplProcessors)r(s,this)}let i=()=>{s&&(e&&this.shadowRoot.appendChild(s)||this.appendChild(s)),this.__initCallback()};if(this.constructor.__shadowStylesUrl){e=!0;let r=document.createElement("link");r.rel="stylesheet",r.href=this.constructor.__shadowStylesUrl,r.onload=i,this.shadowRoot.prepend(r)}else i()}addTemplateProcessor(t){this.tplProcessors.add(t)}get autoCtxName(){return this.__autoCtxName||(this.__autoCtxName=g.generate(),this.style.setProperty(o.CSS_CTX_PROP,`'${this.__autoCtxName}'`)),this.__autoCtxName}get cssCtxName(){return this.getCssData(o.CSS_CTX_PROP,!0)}get ctxName(){var t;return((t=this.getAttribute(o.CTX_NAME_ATTR))==null?void 0:t.trim())||this.cssCtxName||this.autoCtxName}get localCtx(){return this.__localCtx||(this.__localCtx=c.registerLocalCtx({})),this.__localCtx}get nodeCtx(){return c.getNamedCtx(this.ctxName,!1)||c.registerNamedCtx(this.ctxName,{})}static __parseProp(t,e){let s,i;if(t.startsWith(o.EXT_DATA_CTX_PRFX))s=e.nodeCtx,i=t.replace(o.EXT_DATA_CTX_PRFX,"");else if(t.includes(o.NAMED_DATA_CTX_SPLTR)){let r=t.split(o.NAMED_DATA_CTX_SPLTR);s=c.getNamedCtx(r[0]),i=r[1]}else s=e.localCtx,i=t;return{ctx:s,name:i}}sub(t,e){let s=T.__parseProp(t,this);s.ctx.has(t)?this.allSubs.add(s.ctx.sub(s.name,e)):window.setTimeout(()=>{this.allSubs.add(s.ctx.sub(s.name,e))})}notify(t){let e=T.__parseProp(t,this);e.ctx.notify(e.name)}has(t){let e=T.__parseProp(t,this);return e.ctx.has(e.name)}add(t,e){let s=T.__parseProp(t,this);s.ctx.add(s.name,e,!1)}add$(t){for(let e in t)this.add(e,t[e])}get $(){if(!this.__stateProxy){let t=Object.create(null);this.__stateProxy=new Proxy(t,{set:(e,s,i)=>{let r=T.__parseProp(s,this);return r.ctx.pub(r.name,i),!0},get:(e,s)=>{let i=T.__parseProp(s,this);return i.ctx.read(i.name)}})}return this.__stateProxy}set$(t,e=!1){for(let s in t){let i=t[s];e||![String,Number,Boolean].includes(i==null?void 0:i.constructor)?this.$[s]=i:this.$[s]!==i&&(this.$[s]=i)}}__initDataCtx(){let t=this.constructor.__attrDesc;if(t)for(let e of Object.values(t))Object.keys(this.init$).includes(e)||(this.init$[e]="");for(let e in this.init$)if(e.startsWith(o.EXT_DATA_CTX_PRFX))this.nodeCtx.add(e.replace(o.EXT_DATA_CTX_PRFX,""),this.init$[e]);else if(e.includes(o.NAMED_DATA_CTX_SPLTR)){let s=e.split(o.NAMED_DATA_CTX_SPLTR),i=s[0].trim(),r=s[1].trim();if(i&&r){let n=c.getNamedCtx(i,!1);n||(n=c.registerNamedCtx(i,{})),n.add(r,this.init$[e])}}else this.localCtx.add(e,this.init$[e]);for(let e in this.cssInit$)this.bindCssData(e,this.cssInit$[e]);this.__dataCtxInitialized=!0}connectedCallback(){var t;if(this.__disconnectTimeout&&window.clearTimeout(this.__disconnectTimeout),!this.connectedOnce){let e=(t=this.getAttribute(o.CTX_NAME_ATTR))==null?void 0:t.trim();if(e&&this.style.setProperty(o.CSS_CTX_PROP,`'${e}'`),this.__initDataCtx(),this[o.SET_LATER_KEY]){for(let s in this[o.SET_LATER_KEY])E(this,s,this[o.SET_LATER_KEY][s]);delete this[o.SET_LATER_KEY]}this.initChildren=[...this.childNodes];for(let s of w)this.addTemplateProcessor(s);this.pauseRender?this.__initCallback():this.render()}this.connectedOnce=!0}destroyCallback(){}disconnectedCallback(){this.dropCssDataCache(),!!this.readyToDestroy&&(this.__disconnectTimeout&&window.clearTimeout(this.__disconnectTimeout),this.__disconnectTimeout=window.setTimeout(()=>{this.destroyCallback();for(let t of this.allSubs)t.remove(),this.allSubs.delete(t);for(let t of this.tplProcessors)this.tplProcessors.delete(t);_==null||_.delete(this.updateCssData),(_==null?void 0:_.size)||(m==null||m.disconnect(),m=null,_=null)},100))}static reg(t,e=!1){if(t||(D++,t=`${o.AUTO_TAG_PRFX}-${D}`),this.__tag=t,window.customElements.get(t)){console.warn(`${t} - is already in "customElements" registry`);return}window.customElements.define(t,e?class extends this{}:this)}static get is(){return this.__tag||this.reg(),this.__tag}static bindAttributes(t){this.observedAttributes=Object.keys(t),this.__attrDesc=t}attributeChangedCallback(t,e,s){if(e===s)return;let i=this.constructor.__attrDesc[t];i?this.__dataCtxInitialized?this.$[i]=s:this.init$[i]=s:this[t]=s}getCssData(t,e=!1){if(this.__cssDataCache||(this.__cssDataCache=Object.create(null)),!Object.keys(this.__cssDataCache).includes(t)){this.__computedStyle||(this.__computedStyle=window.getComputedStyle(this));let s=this.__computedStyle.getPropertyValue(t).trim();s.startsWith("'")&&s.endsWith("'")&&(s=s.replace(/\'/g,'"'));try{this.__cssDataCache[t]=JSON.parse(s)}catch{!e&&console.warn(`CSS Data error: ${t}`),this.__cssDataCache[t]=null}}return this.__cssDataCache[t]}__extractCssName(t){return t.split("--").map((e,s)=>s===0?"":e).join("--")}__initStyleAttrObserver(){_||(_=new Set),_.add(this.updateCssData),m||(m=new MutationObserver(t=>{t[0].type==="attributes"&&_.forEach(e=>{e()})}),m.observe(document,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style"]}))}bindCssData(t,e=""){this.__boundCssProps||(this.__boundCssProps=new Set),this.__boundCssProps.add(t);let s=this.getCssData(this.__extractCssName(t),!0);s===null&&(s=e),this.add(t,s),this.__initStyleAttrObserver()}dropCssDataCache(){this.__cssDataCache=null,this.__computedStyle=null}defineAccessor(t,e,s){let i="__"+t;this[i]=this[t],Object.defineProperty(this,t,{set:r=>{this[i]=r,s?window.setTimeout(()=>{e==null||e(r)}):e==null||e(r)},get:()=>this[i]}),this[t]=this[i]}static set shadowStyles(t){let e=new Blob([t],{type:"text/css"});this.__shadowStylesUrl=URL.createObjectURL(e)}},X=T;S(X,"template");export{X as BaseComponent};
1
+ var O=Object.defineProperty;var N=(n,t,e)=>t in n?O(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e;var P=(n,t,e)=>(N(n,typeof t!="symbol"?t+"":t,e),e);function $(n){let t=e=>{var s;for(let i in e)((s=e[i])==null?void 0:s.constructor)===Object&&(e[i]=t(e[i]));return{...e}};return t(n)}var h=class{constructor(t){this.uid=Symbol(),this.name=t.name||null,t.schema.constructor===Object?this.store=$(t.schema):(this._storeIsProxy=!0,this.store=t.schema),this.callbackMap=Object.create(null)}static warn(t,e){console.warn(`Symbiote Data: cannot ${t}. Prop name: `+e)}read(t){return!this._storeIsProxy&&!this.store.hasOwnProperty(t)?(h.warn("read",t),null):this.store[t]}has(t){return this._storeIsProxy?this.store[t]!==void 0:this.store.hasOwnProperty(t)}add(t,e,s=!1){if(!s&&Object.keys(this.store).includes(t)){e!==this.store[t]&&this.notify(t);return}this.store[t]=e,this.notify(t)}pub(t,e){if(!this._storeIsProxy&&!this.store.hasOwnProperty(t)){h.warn("publish",t);return}this.store[t]=e,this.notify(t)}multiPub(t){for(let e in t)this.pub(e,t[e])}notify(t){this.callbackMap[t]&&this.callbackMap[t].forEach(e=>{e(this.store[t])})}sub(t,e,s=!0){return!this._storeIsProxy&&!this.store.hasOwnProperty(t)?(h.warn("subscribe",t),null):(this.callbackMap[t]||(this.callbackMap[t]=new Set),this.callbackMap[t].add(e),s&&e(this.store[t]),{remove:()=>{this.callbackMap[t].delete(e),this.callbackMap[t].size||delete this.callbackMap[t]},callback:e})}remove(){delete h.globalStore[this.uid]}static registerLocalCtx(t){let e=new h({schema:t});return h.globalStore[e.uid]=e,e}static registerNamedCtx(t,e){let s=h.globalStore[t];return s?console.warn('State: context name "'+t+'" already in use'):(s=new h({name:t,schema:e}),h.globalStore[t]=s),s}static clearNamedCtx(t){delete h.globalStore[t]}static getNamedCtx(t,e=!0){return h.globalStore[t]||(e&&console.warn('State: wrong context name - "'+t+'"'),null)}};h.globalStore=Object.create(null);var o=Object.freeze({BIND_ATTR:"set",ATTR_BIND_PRFX:"@",EXT_DATA_CTX_PRFX:"*",NAMED_DATA_CTX_SPLTR:"/",CTX_NAME_ATTR:"ctx-name",CSS_CTX_PROP:"--ctx-name",EL_REF_ATTR:"ref",AUTO_TAG_PRFX:"sym",REPEAT_ATTR:"repeat",REPEAT_ITEM_TAG_ATTR:"repeat-item-tag",SET_LATER_KEY:"__toSetLater__",USE_TPL:"use-template"});var g="1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm",k=g.length-1,y=class{static generate(t="XXXXXXXXX-XXX"){let e="";for(let s=0;s<t.length;s++)e+=t[s]==="-"?t[s]:g.charAt(Math.random()*k);return e}};function E(n,t,e){let s=!0,i,r=t.split(".");return r.forEach((l,a)=>{a<r.length-1?n=n[l]:i=l}),n?n[i]=e:s=!1,s}function x(n){return n.split("-").map((t,e)=>t&&e?t[0].toUpperCase()+t.slice(1):t).join("").split("_").map((t,e)=>t&&e?t.toUpperCase():t).join("")}function R(n,t){[...n.querySelectorAll(`[${o.REPEAT_ATTR}]`)].forEach(e=>{let s=e.getAttribute(o.REPEAT_ITEM_TAG_ATTR),i;if(s&&(i=window.customElements.get(s)),!i){i=class extends t.BaseComponent{constructor(){super();s||(this.style.display="contents")}};let l=e.innerHTML;i.template=l,i.reg(s)}for(;e.firstChild;)e.firstChild.remove();let r=e.getAttribute(o.REPEAT_ATTR);t.sub(r,l=>{if(!l){for(;e.firstChild;)e.firstChild.remove();return}let a=[...e.children],f,b=u=>{u.forEach((c,A)=>{if(a[A])if(a[A].set$)a[A].set$(c);else for(let C in c)a[A][C]=c[C];else{f||(f=new DocumentFragment);let C=new i;Object.assign(C.init$,c),f.appendChild(C)}}),f&&e.appendChild(f);let d=a.slice(u.length,a.length);for(let c of d)c.remove()};if(l.constructor===Array)b(l);else if(l.constructor===Object){let u=[];for(let d in l){let c=l[d];Object.defineProperty(c,"_KEY_",{value:d,enumerable:!0}),u.push(c)}b(u)}else console.warn("Symbiote repeat data type error:"),console.log(l)}),e.removeAttribute(o.REPEAT_ATTR),e.removeAttribute(o.REPEAT_ITEM_TAG_ATTR)})}function I(n,t){if(t.shadowRoot)return;let e=[...n.querySelectorAll("slot")];if(t.initChildren.length&&e.length){let s={};e.forEach(i=>{let r=i.getAttribute("name");r?s[r]={slot:i,fr:document.createDocumentFragment()}:s.__default__={slot:i,fr:document.createDocumentFragment()}}),t.initChildren.forEach(i=>{var l;let r=(l=i.getAttribute)==null?void 0:l.call(i,"slot");r?(i.removeAttribute("slot"),s[r].fr.appendChild(i)):s.__default__&&s.__default__.fr.appendChild(i)}),Object.values(s).forEach(i=>{i.slot.parentNode.insertBefore(i.fr,i.slot),i.slot.remove()})}}function L(n,t){[...n.querySelectorAll(`[${o.EL_REF_ATTR}]`)].forEach(e=>{let s=e.getAttribute(o.EL_REF_ATTR);t.ref[s]=e,e.removeAttribute(o.EL_REF_ATTR)})}function M(n,t){[...n.querySelectorAll(`[${o.BIND_ATTR}]`)].forEach(e=>{let i=e.getAttribute(o.BIND_ATTR).split(";");[...e.attributes].forEach(r=>{if(r.name.startsWith("-")&&r.value){let l=x(r.name.replace("-",""));i.push(l+":"+r.value),e.removeAttribute(r.name)}}),i.forEach(r=>{if(!r)return;let l=r.split(":").map(u=>u.trim()),a=l[0],f;a.indexOf(o.ATTR_BIND_PRFX)===0&&(f=!0,a=a.replace(o.ATTR_BIND_PRFX,""));let b=l[1].split(",").map(u=>u.trim());for(let u of b){let d;u.startsWith("!!")?(d="double",u=u.replace("!!","")):u.startsWith("!")&&(d="single",u=u.replace("!","")),t.sub(u,c=>{d==="double"?c=!!c:d==="single"&&(c=!c),f?(c==null?void 0:c.constructor)===Boolean?c?e.setAttribute(a,""):e.removeAttribute(a):e.setAttribute(a,c):E(e,a,c)||(e[o.SET_LATER_KEY]||(e[o.SET_LATER_KEY]=Object.create(null)),e[o.SET_LATER_KEY][a]=c)})}}),e.removeAttribute(o.BIND_ATTR)})}var S="{{",p="}}",j="skip-text";function F(n){let t,e=[],s=document.createTreeWalker(n,NodeFilter.SHOW_TEXT,{acceptNode:i=>{var r;return!((r=i.parentElement)==null?void 0:r.hasAttribute(j))&&i.textContent.includes(S)&&i.textContent.includes(p)&&1}});for(;t=s.nextNode();)e.push(t);return e}var K=function(n,t){F(n).forEach(s=>{let i=[],r;for(;s.textContent.includes(p);)s.textContent.startsWith(S)?(r=s.textContent.indexOf(p)+p.length,s.splitText(r),i.push(s)):(r=s.textContent.indexOf(S),s.splitText(r)),s=s.nextSibling;i.forEach(l=>{let a=l.textContent.replace(S,"").replace(p,"");l.textContent="",t.sub(a,f=>{l.textContent=f})})})},w=[R,I,L,M,K];var D=0,m=null,_=null,T=class extends HTMLElement{constructor(){super();P(this,"updateCssData",()=>{var t;this.dropCssDataCache(),(t=this.__boundCssProps)==null||t.forEach(e=>{let s=this.getCssData(this.__extractCssName(e),!0);this.$[e]!==s&&(this.$[e]=s)})});this.init$=Object.create(null),this.cssInit$=Object.create(null),this.tplProcessors=new Set,this.ref=Object.create(null),this.allSubs=new Set,this.pauseRender=!1,this.renderShadow=!1,this.readyToDestroy=!0,this.processInnerHtml=!1,this.allowCustomTemplate=!1}get BaseComponent(){return T}initCallback(){}__initCallback(){var t;this.__initialized||(this.__initialized=!0,(t=this.initCallback)==null||t.call(this))}render(t,e=this.renderShadow){let s;if((e||this.constructor.__shadowStylesUrl)&&!this.shadowRoot&&this.attachShadow({mode:"open"}),this.allowCustomTemplate){let r=this.getAttribute(o.USE_TPL);if(r){let l=this.getRootNode(),a=(l==null?void 0:l.querySelector(r))||document.querySelector(r);a?t=a.content.cloneNode(!0):console.warn(`Symbiote template "${r}" is not found...`)}}if(this.processInnerHtml)for(let r of this.tplProcessors)r(this,this);if(t||this.constructor.template){if(this.constructor.template&&!this.constructor.__tpl&&(this.constructor.__tpl=document.createElement("template"),this.constructor.__tpl.innerHTML=this.constructor.template),(t==null?void 0:t.constructor)===DocumentFragment)s=t;else if((t==null?void 0:t.constructor)===String){let r=document.createElement("template");r.innerHTML=t,s=r.content.cloneNode(!0)}else this.constructor.__tpl&&(s=this.constructor.__tpl.content.cloneNode(!0));for(let r of this.tplProcessors)r(s,this)}let i=()=>{s&&(e&&this.shadowRoot.appendChild(s)||this.appendChild(s)),this.__initCallback()};if(this.constructor.__shadowStylesUrl){e=!0;let r=document.createElement("link");r.rel="stylesheet",r.href=this.constructor.__shadowStylesUrl,r.onload=i,this.shadowRoot.prepend(r)}else i()}addTemplateProcessor(t){this.tplProcessors.add(t)}get autoCtxName(){return this.__autoCtxName||(this.__autoCtxName=y.generate(),this.style.setProperty(o.CSS_CTX_PROP,`'${this.__autoCtxName}'`)),this.__autoCtxName}get cssCtxName(){return this.getCssData(o.CSS_CTX_PROP,!0)}get ctxName(){var t;return((t=this.getAttribute(o.CTX_NAME_ATTR))==null?void 0:t.trim())||this.cssCtxName||this.autoCtxName}get localCtx(){return this.__localCtx||(this.__localCtx=h.registerLocalCtx({})),this.__localCtx}get nodeCtx(){return h.getNamedCtx(this.ctxName,!1)||h.registerNamedCtx(this.ctxName,{})}static __parseProp(t,e){let s,i;if(t.startsWith(o.EXT_DATA_CTX_PRFX))s=e.nodeCtx,i=t.replace(o.EXT_DATA_CTX_PRFX,"");else if(t.includes(o.NAMED_DATA_CTX_SPLTR)){let r=t.split(o.NAMED_DATA_CTX_SPLTR);s=h.getNamedCtx(r[0]),i=r[1]}else s=e.localCtx,i=t;return{ctx:s,name:i}}sub(t,e){let s=T.__parseProp(t,this);s.ctx.has(t)?this.allSubs.add(s.ctx.sub(s.name,e)):window.setTimeout(()=>{this.allSubs.add(s.ctx.sub(s.name,e))})}notify(t){let e=T.__parseProp(t,this);e.ctx.notify(e.name)}has(t){let e=T.__parseProp(t,this);return e.ctx.has(e.name)}add(t,e){let s=T.__parseProp(t,this);s.ctx.add(s.name,e,!1)}add$(t){for(let e in t)this.add(e,t[e])}get $(){if(!this.__stateProxy){let t=Object.create(null);this.__stateProxy=new Proxy(t,{set:(e,s,i)=>{let r=T.__parseProp(s,this);return r.ctx.pub(r.name,i),!0},get:(e,s)=>{let i=T.__parseProp(s,this);return i.ctx.read(i.name)}})}return this.__stateProxy}set$(t,e=!1){for(let s in t){let i=t[s];e||![String,Number,Boolean].includes(i==null?void 0:i.constructor)?this.$[s]=i:this.$[s]!==i&&(this.$[s]=i)}}__initDataCtx(){let t=this.constructor.__attrDesc;if(t)for(let e of Object.values(t))Object.keys(this.init$).includes(e)||(this.init$[e]="");for(let e in this.init$)if(e.startsWith(o.EXT_DATA_CTX_PRFX))this.nodeCtx.add(e.replace(o.EXT_DATA_CTX_PRFX,""),this.init$[e]);else if(e.includes(o.NAMED_DATA_CTX_SPLTR)){let s=e.split(o.NAMED_DATA_CTX_SPLTR),i=s[0].trim(),r=s[1].trim();if(i&&r){let l=h.getNamedCtx(i,!1);l||(l=h.registerNamedCtx(i,{})),l.add(r,this.init$[e])}}else this.localCtx.add(e,this.init$[e]);for(let e in this.cssInit$)this.bindCssData(e,this.cssInit$[e]);this.__dataCtxInitialized=!0}connectedCallback(){var t;if(!!this.isConnected){if(this.__disconnectTimeout&&window.clearTimeout(this.__disconnectTimeout),!this.connectedOnce){let e=(t=this.getAttribute(o.CTX_NAME_ATTR))==null?void 0:t.trim();if(e&&this.style.setProperty(o.CSS_CTX_PROP,`'${e}'`),this.__initDataCtx(),this[o.SET_LATER_KEY]){for(let s in this[o.SET_LATER_KEY])E(this,s,this[o.SET_LATER_KEY][s]);delete this[o.SET_LATER_KEY]}this.initChildren=[...this.childNodes];for(let s of w)this.addTemplateProcessor(s);this.pauseRender?this.__initCallback():this.render()}this.connectedOnce=!0}}destroyCallback(){}disconnectedCallback(){!this.connectedOnce||(this.dropCssDataCache(),!!this.readyToDestroy&&(this.__disconnectTimeout&&window.clearTimeout(this.__disconnectTimeout),this.__disconnectTimeout=window.setTimeout(()=>{this.destroyCallback();for(let t of this.allSubs)t.remove(),this.allSubs.delete(t);for(let t of this.tplProcessors)this.tplProcessors.delete(t);_==null||_.delete(this.updateCssData),(_==null?void 0:_.size)||(m==null||m.disconnect(),m=null,_=null)},100)))}static reg(t,e=!1){if(t||(D++,t=`${o.AUTO_TAG_PRFX}-${D}`),this.__tag=t,window.customElements.get(t)){console.warn(`${t} - is already in "customElements" registry`);return}window.customElements.define(t,e?class extends this{}:this)}static get is(){return this.__tag||this.reg(),this.__tag}static bindAttributes(t){this.observedAttributes=Object.keys(t),this.__attrDesc=t}attributeChangedCallback(t,e,s){if(e===s)return;let i=this.constructor.__attrDesc[t];i?this.__dataCtxInitialized?this.$[i]=s:this.init$[i]=s:this[t]=s}getCssData(t,e=!1){if(this.__cssDataCache||(this.__cssDataCache=Object.create(null)),!Object.keys(this.__cssDataCache).includes(t)){this.__computedStyle||(this.__computedStyle=window.getComputedStyle(this));let s=this.__computedStyle.getPropertyValue(t).trim();s.startsWith("'")&&s.endsWith("'")&&(s=s.replace(/\'/g,'"'));try{this.__cssDataCache[t]=JSON.parse(s)}catch{!e&&console.warn(`CSS Data error: ${t}`),this.__cssDataCache[t]=null}}return this.__cssDataCache[t]}__extractCssName(t){return t.split("--").map((e,s)=>s===0?"":e).join("--")}__initStyleAttrObserver(){_||(_=new Set),_.add(this.updateCssData),m||(m=new MutationObserver(t=>{t[0].type==="attributes"&&_.forEach(e=>{e()})}),m.observe(document,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style"]}))}bindCssData(t,e=""){this.__boundCssProps||(this.__boundCssProps=new Set),this.__boundCssProps.add(t);let s=this.getCssData(this.__extractCssName(t),!0);s===null&&(s=e),this.add(t,s),this.__initStyleAttrObserver()}dropCssDataCache(){this.__cssDataCache=null,this.__computedStyle=null}defineAccessor(t,e,s){let i="__"+t;this[i]=this[t],Object.defineProperty(this,t,{set:r=>{this[i]=r,s?window.setTimeout(()=>{e==null||e(r)}):e==null||e(r)},get:()=>this[i]}),this[t]=this[i]}static set shadowStyles(t){let e=new Blob([t],{type:"text/css"});this.__shadowStylesUrl=URL.createObjectURL(e)}},X=T;P(X,"template");export{X as BaseComponent};
@@ -67,6 +67,7 @@ export class BaseComponent<S> extends HTMLElement {
67
67
  renderShadow: boolean;
68
68
  readyToDestroy: boolean;
69
69
  processInnerHtml: boolean;
70
+ allowCustomTemplate: boolean;
70
71
  get autoCtxName(): string;
71
72
  private __autoCtxName;
72
73
  get cssCtxName(): string;
@@ -102,69 +103,6 @@ export class BaseComponent<S> extends HTMLElement {
102
103
  dropCssDataCache(): void;
103
104
  defineAccessor(propName: string, handler?: Function, isAsync?: boolean): void;
104
105
  }
105
- export class TypedData {
106
- constructor(typedSchema: {
107
- [x: string]: {
108
- type: any;
109
- value: any;
110
- nullable?: boolean;
111
- };
112
- }, ctxName?: string);
113
- private __typedSchema;
114
- private __ctxId;
115
- private __schema;
116
- private __data;
117
- get uid(): string;
118
- setValue(prop: string, value: any): void;
119
- setMultipleValues(updObj: {
120
- [x: string]: any;
121
- }): void;
122
- getValue(prop: string): any;
123
- subscribe(prop: string, handler: (newVal: any) => void): {
124
- remove: () => void;
125
- callback: Function;
126
- };
127
- remove(): void;
128
- }
129
- export class TypedCollection {
130
- constructor(options: {
131
- typedSchema: {
132
- [x: string]: {
133
- type: any;
134
- value: any;
135
- };
136
- };
137
- watchList?: string[];
138
- handler?: (list: string[]) => void;
139
- ctxName?: string;
140
- });
141
- private __typedSchema;
142
- private __ctxId;
143
- private __data;
144
- private __watchList;
145
- private __handler;
146
- private __subsMap;
147
- private __observers;
148
- private __items;
149
- private __notifyObservers;
150
- private __observeTimeout;
151
- notify(): void;
152
- private __notifyTimeout;
153
- add(init: {
154
- [x: string]: any;
155
- }): any;
156
- read(id: string): TypedData;
157
- readProp(id: string, propName: string): any;
158
- publishProp<T>(id: string, propName: string, value: T): void;
159
- remove(id: string): void;
160
- clearAll(): void;
161
- observe(handler: Function): void;
162
- unobserve(handler: Function): void;
163
- findItems(checkFn: (item: TypedData) => boolean): string[];
164
- items(): string[];
165
- get size(): number;
166
- destroy(): void;
167
- }
168
106
  export class AppRouter {
169
107
  private static _print;
170
108
  static setDefaultTitle(title: string): void;
@@ -189,6 +127,8 @@ export class AppRouter {
189
127
  static createRouterData(ctxName: string, routingMap: {
190
128
  [x: string]: {};
191
129
  }): Data;
130
+ static initPopstateListener(): void;
131
+ static removePopstateListener(): void;
192
132
  }
193
133
  export namespace AppRouter {
194
134
  const defaultTitle: string;
@@ -196,6 +136,7 @@ export namespace AppRouter {
196
136
  const errorRoute: string;
197
137
  const __routingEventName: string;
198
138
  const _separator: string;
139
+ function __onPopstate(): void;
199
140
  const appMap: any;
200
141
  }
201
142
  export class UID {
package/build/symbiote.js CHANGED
@@ -139,7 +139,8 @@ var DICT = Object.freeze({
139
139
  AUTO_TAG_PRFX: "sym",
140
140
  REPEAT_ATTR: "repeat",
141
141
  REPEAT_ITEM_TAG_ATTR: "repeat-item-tag",
142
- SET_LATER_KEY: "__toSetLater__"
142
+ SET_LATER_KEY: "__toSetLater__",
143
+ USE_TPL: "use-template"
143
144
  });
144
145
 
145
146
  // utils/UID.js
@@ -406,6 +407,7 @@ var txtNodesProcessor = function(fr, fnCtx) {
406
407
  }
407
408
  tokenNodes.forEach((tNode) => {
408
409
  let prop = tNode.textContent.replace(OPEN_TOKEN, "").replace(CLOSE_TOKEN, "");
410
+ tNode.textContent = "";
409
411
  fnCtx.sub(prop, (val) => {
410
412
  tNode.textContent = val;
411
413
  });
@@ -438,6 +440,7 @@ var _BaseComponent = class extends HTMLElement {
438
440
  this.renderShadow = false;
439
441
  this.readyToDestroy = true;
440
442
  this.processInnerHtml = false;
443
+ this.allowCustomTemplate = false;
441
444
  }
442
445
  get BaseComponent() {
443
446
  return _BaseComponent;
@@ -459,6 +462,18 @@ var _BaseComponent = class extends HTMLElement {
459
462
  mode: "open"
460
463
  });
461
464
  }
465
+ if (this.allowCustomTemplate) {
466
+ let customTplSelector = this.getAttribute(DICT.USE_TPL);
467
+ if (customTplSelector) {
468
+ let root = this.getRootNode();
469
+ let customTpl = (root == null ? void 0 : root.querySelector(customTplSelector)) || document.querySelector(customTplSelector);
470
+ if (customTpl) {
471
+ template = customTpl.content.cloneNode(true);
472
+ } else {
473
+ console.warn(`Symbiote template "${customTplSelector}" is not found...`);
474
+ }
475
+ }
476
+ }
462
477
  if (this.processInnerHtml) {
463
478
  for (let fn of this.tplProcessors) {
464
479
  fn(this, this);
@@ -631,6 +646,9 @@ var _BaseComponent = class extends HTMLElement {
631
646
  }
632
647
  connectedCallback() {
633
648
  var _a;
649
+ if (!this.isConnected) {
650
+ return;
651
+ }
634
652
  if (this.__disconnectTimeout) {
635
653
  window.clearTimeout(this.__disconnectTimeout);
636
654
  }
@@ -661,6 +679,9 @@ var _BaseComponent = class extends HTMLElement {
661
679
  destroyCallback() {
662
680
  }
663
681
  disconnectedCallback() {
682
+ if (!this.connectedOnce) {
683
+ return;
684
+ }
664
685
  this.dropCssDataCache();
665
686
  if (!this.readyToDestroy) {
666
687
  return;
@@ -812,165 +833,6 @@ var _BaseComponent = class extends HTMLElement {
812
833
  var BaseComponent = _BaseComponent;
813
834
  __publicField(BaseComponent, "template");
814
835
 
815
- // core/TypedData.js
816
- var MSG_NAME = "[Typed State] Wrong property name: ";
817
- var MSG_TYPE = "[Typed State] Wrong property type: ";
818
- var TypedData = class {
819
- constructor(typedSchema, ctxName) {
820
- this.__typedSchema = typedSchema;
821
- this.__ctxId = ctxName || UID.generate();
822
- this.__schema = Object.keys(typedSchema).reduce((acc, key) => {
823
- acc[key] = typedSchema[key].value;
824
- return acc;
825
- }, {});
826
- this.__data = Data.registerNamedCtx(this.__ctxId, this.__schema);
827
- }
828
- get uid() {
829
- return this.__ctxId;
830
- }
831
- setValue(prop, value) {
832
- if (!this.__typedSchema.hasOwnProperty(prop)) {
833
- console.warn(MSG_NAME + prop);
834
- return;
835
- }
836
- let pDesc = this.__typedSchema[prop];
837
- if ((value == null ? void 0 : value.constructor) === pDesc.type || pDesc.nullable && value === null) {
838
- this.__data.pub(prop, value);
839
- return;
840
- }
841
- console.warn(MSG_TYPE + prop);
842
- }
843
- setMultipleValues(updObj) {
844
- for (let prop in updObj) {
845
- this.setValue(prop, updObj[prop]);
846
- }
847
- }
848
- getValue(prop) {
849
- if (!this.__typedSchema.hasOwnProperty(prop)) {
850
- console.warn(MSG_NAME + prop);
851
- return void 0;
852
- }
853
- return this.__data.read(prop);
854
- }
855
- subscribe(prop, handler) {
856
- return this.__data.sub(prop, handler);
857
- }
858
- remove() {
859
- this.__data.remove();
860
- }
861
- };
862
-
863
- // core/TypedCollection.js
864
- var TypedCollection = class {
865
- constructor(options) {
866
- this.__typedSchema = options.typedSchema;
867
- this.__ctxId = options.ctxName || UID.generate();
868
- this.__data = Data.registerNamedCtx(this.__ctxId, {});
869
- this.__watchList = options.watchList || [];
870
- this.__handler = options.handler || null;
871
- this.__subsMap = Object.create(null);
872
- this.__observers = /* @__PURE__ */ new Set();
873
- this.__items = /* @__PURE__ */ new Set();
874
- let changeMap = Object.create(null);
875
- this.__notifyObservers = (propName, ctxId) => {
876
- if (this.__observeTimeout) {
877
- window.clearTimeout(this.__observeTimeout);
878
- }
879
- if (!changeMap[propName]) {
880
- changeMap[propName] = /* @__PURE__ */ new Set();
881
- }
882
- changeMap[propName].add(ctxId);
883
- this.__observeTimeout = window.setTimeout(() => {
884
- this.__observers.forEach((handler) => {
885
- handler({ ...changeMap });
886
- });
887
- changeMap = Object.create(null);
888
- });
889
- };
890
- }
891
- notify() {
892
- if (this.__notifyTimeout) {
893
- window.clearTimeout(this.__notifyTimeout);
894
- }
895
- this.__notifyTimeout = window.setTimeout(() => {
896
- var _a;
897
- (_a = this.__handler) == null ? void 0 : _a.call(this, [...this.__items]);
898
- });
899
- }
900
- add(init) {
901
- let item = new TypedData(this.__typedSchema);
902
- for (let prop in init) {
903
- item.setValue(prop, init[prop]);
904
- }
905
- this.__data.add(item.uid, item);
906
- this.__watchList.forEach((propName) => {
907
- if (!this.__subsMap[item.uid]) {
908
- this.__subsMap[item.uid] = [];
909
- }
910
- this.__subsMap[item.uid].push(item.subscribe(propName, () => {
911
- this.__notifyObservers(propName, item.uid);
912
- }));
913
- });
914
- this.__items.add(item.uid);
915
- this.notify();
916
- return item;
917
- }
918
- read(id) {
919
- return this.__data.read(id);
920
- }
921
- readProp(id, propName) {
922
- let item = this.read(id);
923
- return item.getValue(propName);
924
- }
925
- publishProp(id, propName, value) {
926
- let item = this.read(id);
927
- item.setValue(propName, value);
928
- }
929
- remove(id) {
930
- this.__items.delete(id);
931
- this.notify();
932
- this.__data.pub(id, null);
933
- delete this.__subsMap[id];
934
- }
935
- clearAll() {
936
- this.__items.forEach((id) => {
937
- this.remove(id);
938
- });
939
- }
940
- observe(handler) {
941
- this.__observers.add(handler);
942
- }
943
- unobserve(handler) {
944
- this.__observers.delete(handler);
945
- }
946
- findItems(checkFn) {
947
- let result = [];
948
- this.__items.forEach((id) => {
949
- let item = this.read(id);
950
- if (checkFn(item)) {
951
- result.push(id);
952
- }
953
- });
954
- return result;
955
- }
956
- items() {
957
- return [...this.__items];
958
- }
959
- get size() {
960
- return this.__items.size;
961
- }
962
- destroy() {
963
- this.__data.remove();
964
- this.__observers = null;
965
- for (let id in this.__subsMap) {
966
- this.__subsMap[id].forEach((sub) => {
967
- sub.remove();
968
- });
969
- delete this.__subsMap[id];
970
- }
971
- }
972
- };
973
-
974
836
  // core/AppRouter.js
975
837
  var AppRouter = class {
976
838
  static _print(msg) {
@@ -1084,13 +946,24 @@ var AppRouter = class {
1084
946
  });
1085
947
  });
1086
948
  AppRouter.notify();
949
+ this.initPopstateListener();
1087
950
  return routeData;
1088
951
  }
952
+ static initPopstateListener() {
953
+ if (this.__onPopstate) {
954
+ return;
955
+ }
956
+ this.__onPopstate = () => {
957
+ this.notify();
958
+ };
959
+ window.addEventListener("popstate", this.__onPopstate);
960
+ }
961
+ static removePopstateListener() {
962
+ window.removeEventListener("popstate", this.__onPopstate);
963
+ this.__onPopstate = null;
964
+ }
1089
965
  };
1090
966
  AppRouter.appMap = Object.create(null);
1091
- window.onpopstate = () => {
1092
- AppRouter.notify();
1093
- };
1094
967
 
1095
968
  // utils/dom-helpers.js
1096
969
  function applyStyles(el, styleMap) {
@@ -1322,8 +1195,6 @@ export {
1322
1195
  BaseComponent,
1323
1196
  Data,
1324
1197
  IDB,
1325
- TypedCollection,
1326
- TypedData,
1327
1198
  UID,
1328
1199
  applyAttributes,
1329
1200
  applyStyles,
@@ -1 +1 @@
1
- var B=Object.defineProperty;var U=(o,t,e)=>t in o?B(o,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[t]=e;var y=(o,t,e)=>(U(o,typeof t!="symbol"?t+"":t,e),e);function W(o){let t=e=>{var s;for(let i in e)((s=e[i])==null?void 0:s.constructor)===Object&&(e[i]=t(e[i]));return{...e}};return t(o)}var h=class{constructor(t){this.uid=Symbol(),this.name=t.name||null,t.schema.constructor===Object?this.store=W(t.schema):(this._storeIsProxy=!0,this.store=t.schema),this.callbackMap=Object.create(null)}static warn(t,e){console.warn(`Symbiote Data: cannot ${t}. Prop name: `+e)}read(t){return!this._storeIsProxy&&!this.store.hasOwnProperty(t)?(h.warn("read",t),null):this.store[t]}has(t){return this._storeIsProxy?this.store[t]!==void 0:this.store.hasOwnProperty(t)}add(t,e,s=!1){if(!s&&Object.keys(this.store).includes(t)){e!==this.store[t]&&this.notify(t);return}this.store[t]=e,this.notify(t)}pub(t,e){if(!this._storeIsProxy&&!this.store.hasOwnProperty(t)){h.warn("publish",t);return}this.store[t]=e,this.notify(t)}multiPub(t){for(let e in t)this.pub(e,t[e])}notify(t){this.callbackMap[t]&&this.callbackMap[t].forEach(e=>{e(this.store[t])})}sub(t,e,s=!0){return!this._storeIsProxy&&!this.store.hasOwnProperty(t)?(h.warn("subscribe",t),null):(this.callbackMap[t]||(this.callbackMap[t]=new Set),this.callbackMap[t].add(e),s&&e(this.store[t]),{remove:()=>{this.callbackMap[t].delete(e),this.callbackMap[t].size||delete this.callbackMap[t]},callback:e})}remove(){delete h.globalStore[this.uid]}static registerLocalCtx(t){let e=new h({schema:t});return h.globalStore[e.uid]=e,e}static registerNamedCtx(t,e){let s=h.globalStore[t];return s?console.warn('State: context name "'+t+'" already in use'):(s=new h({name:t,schema:e}),h.globalStore[t]=s),s}static clearNamedCtx(t){delete h.globalStore[t]}static getNamedCtx(t,e=!0){return h.globalStore[t]||(e&&console.warn('State: wrong context name - "'+t+'"'),null)}};h.globalStore=Object.create(null);var n=Object.freeze({BIND_ATTR:"set",ATTR_BIND_PRFX:"@",EXT_DATA_CTX_PRFX:"*",NAMED_DATA_CTX_SPLTR:"/",CTX_NAME_ATTR:"ctx-name",CSS_CTX_PROP:"--ctx-name",EL_REF_ATTR:"ref",AUTO_TAG_PRFX:"sym",REPEAT_ATTR:"repeat",REPEAT_ITEM_TAG_ATTR:"repeat-item-tag",SET_LATER_KEY:"__toSetLater__"});var N="1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm",H=N.length-1,b=class{static generate(t="XXXXXXXXX-XXX"){let e="";for(let s=0;s<t.length;s++)e+=t[s]==="-"?t[s]:N.charAt(Math.random()*H);return e}};function w(o,t,e){let s=!0,i,r=t.split(".");return r.forEach((a,l)=>{l<r.length-1?o=o[a]:i=a}),o?o[i]=e:s=!1,s}function R(o){return o.split("-").map((t,e)=>t&&e?t[0].toUpperCase()+t.slice(1):t).join("").split("_").map((t,e)=>t&&e?t.toUpperCase():t).join("")}function v(o,t){[...o.querySelectorAll(`[${n.REPEAT_ATTR}]`)].forEach(e=>{let s=e.getAttribute(n.REPEAT_ITEM_TAG_ATTR),i;if(s&&(i=window.customElements.get(s)),!i){i=class extends t.BaseComponent{constructor(){super();s||(this.style.display="contents")}};let a=e.innerHTML;i.template=a,i.reg(s)}for(;e.firstChild;)e.firstChild.remove();let r=e.getAttribute(n.REPEAT_ATTR);t.sub(r,a=>{if(!a){for(;e.firstChild;)e.firstChild.remove();return}let l=[...e.children],_,m=c=>{c.forEach((u,g)=>{if(l[g])if(l[g].set$)l[g].set$(u);else for(let C in u)l[g][C]=u[C];else{_||(_=new DocumentFragment);let C=new i;Object.assign(C.init$,u),_.appendChild(C)}}),_&&e.appendChild(_);let f=l.slice(c.length,l.length);for(let u of f)u.remove()};if(a.constructor===Array)m(a);else if(a.constructor===Object){let c=[];for(let f in a){let u=a[f];Object.defineProperty(u,"_KEY_",{value:f,enumerable:!0}),c.push(u)}m(c)}else console.warn("Symbiote repeat data type error:"),console.log(a)}),e.removeAttribute(n.REPEAT_ATTR),e.removeAttribute(n.REPEAT_ITEM_TAG_ATTR)})}function K(o,t){if(t.shadowRoot)return;let e=[...o.querySelectorAll("slot")];if(t.initChildren.length&&e.length){let s={};e.forEach(i=>{let r=i.getAttribute("name");r?s[r]={slot:i,fr:document.createDocumentFragment()}:s.__default__={slot:i,fr:document.createDocumentFragment()}}),t.initChildren.forEach(i=>{var a;let r=(a=i.getAttribute)==null?void 0:a.call(i,"slot");r?(i.removeAttribute("slot"),s[r].fr.appendChild(i)):s.__default__&&s.__default__.fr.appendChild(i)}),Object.values(s).forEach(i=>{i.slot.parentNode.insertBefore(i.fr,i.slot),i.slot.remove()})}}function q(o,t){[...o.querySelectorAll(`[${n.EL_REF_ATTR}]`)].forEach(e=>{let s=e.getAttribute(n.EL_REF_ATTR);t.ref[s]=e,e.removeAttribute(n.EL_REF_ATTR)})}function V(o,t){[...o.querySelectorAll(`[${n.BIND_ATTR}]`)].forEach(e=>{let i=e.getAttribute(n.BIND_ATTR).split(";");[...e.attributes].forEach(r=>{if(r.name.startsWith("-")&&r.value){let a=R(r.name.replace("-",""));i.push(a+":"+r.value),e.removeAttribute(r.name)}}),i.forEach(r=>{if(!r)return;let a=r.split(":").map(c=>c.trim()),l=a[0],_;l.indexOf(n.ATTR_BIND_PRFX)===0&&(_=!0,l=l.replace(n.ATTR_BIND_PRFX,""));let m=a[1].split(",").map(c=>c.trim());for(let c of m){let f;c.startsWith("!!")?(f="double",c=c.replace("!!","")):c.startsWith("!")&&(f="single",c=c.replace("!","")),t.sub(c,u=>{f==="double"?u=!!u:f==="single"&&(u=!u),_?(u==null?void 0:u.constructor)===Boolean?u?e.setAttribute(l,""):e.removeAttribute(l):e.setAttribute(l,u):w(e,l,u)||(e[n.SET_LATER_KEY]||(e[n.SET_LATER_KEY]=Object.create(null)),e[n.SET_LATER_KEY][l]=u)})}}),e.removeAttribute(n.BIND_ATTR)})}var x="{{",A="}}",z="skip-text";function Y(o){let t,e=[],s=document.createTreeWalker(o,NodeFilter.SHOW_TEXT,{acceptNode:i=>{var r;return!((r=i.parentElement)==null?void 0:r.hasAttribute(z))&&i.textContent.includes(x)&&i.textContent.includes(A)&&1}});for(;t=s.nextNode();)e.push(t);return e}var G=function(o,t){Y(o).forEach(s=>{let i=[],r;for(;s.textContent.includes(A);)s.textContent.startsWith(x)?(r=s.textContent.indexOf(A)+A.length,s.splitText(r),i.push(s)):(r=s.textContent.indexOf(x),s.splitText(r)),s=s.nextSibling;i.forEach(a=>{let l=a.textContent.replace(x,"").replace(A,"");t.sub(l,_=>{a.textContent=_})})})},O=[v,K,q,V,G];var M=0,T=null,d=null,p=class extends HTMLElement{constructor(){super();y(this,"updateCssData",()=>{var t;this.dropCssDataCache(),(t=this.__boundCssProps)==null||t.forEach(e=>{let s=this.getCssData(this.__extractCssName(e),!0);this.$[e]!==s&&(this.$[e]=s)})});this.init$=Object.create(null),this.cssInit$=Object.create(null),this.tplProcessors=new Set,this.ref=Object.create(null),this.allSubs=new Set,this.pauseRender=!1,this.renderShadow=!1,this.readyToDestroy=!0,this.processInnerHtml=!1}get BaseComponent(){return p}initCallback(){}__initCallback(){var t;this.__initialized||(this.__initialized=!0,(t=this.initCallback)==null||t.call(this))}render(t,e=this.renderShadow){let s;if((e||this.constructor.__shadowStylesUrl)&&!this.shadowRoot&&this.attachShadow({mode:"open"}),this.processInnerHtml)for(let r of this.tplProcessors)r(this,this);if(t||this.constructor.template){if(this.constructor.template&&!this.constructor.__tpl&&(this.constructor.__tpl=document.createElement("template"),this.constructor.__tpl.innerHTML=this.constructor.template),(t==null?void 0:t.constructor)===DocumentFragment)s=t;else if((t==null?void 0:t.constructor)===String){let r=document.createElement("template");r.innerHTML=t,s=r.content.cloneNode(!0)}else this.constructor.__tpl&&(s=this.constructor.__tpl.content.cloneNode(!0));for(let r of this.tplProcessors)r(s,this)}let i=()=>{s&&(e&&this.shadowRoot.appendChild(s)||this.appendChild(s)),this.__initCallback()};if(this.constructor.__shadowStylesUrl){e=!0;let r=document.createElement("link");r.rel="stylesheet",r.href=this.constructor.__shadowStylesUrl,r.onload=i,this.shadowRoot.prepend(r)}else i()}addTemplateProcessor(t){this.tplProcessors.add(t)}get autoCtxName(){return this.__autoCtxName||(this.__autoCtxName=b.generate(),this.style.setProperty(n.CSS_CTX_PROP,`'${this.__autoCtxName}'`)),this.__autoCtxName}get cssCtxName(){return this.getCssData(n.CSS_CTX_PROP,!0)}get ctxName(){var t;return((t=this.getAttribute(n.CTX_NAME_ATTR))==null?void 0:t.trim())||this.cssCtxName||this.autoCtxName}get localCtx(){return this.__localCtx||(this.__localCtx=h.registerLocalCtx({})),this.__localCtx}get nodeCtx(){return h.getNamedCtx(this.ctxName,!1)||h.registerNamedCtx(this.ctxName,{})}static __parseProp(t,e){let s,i;if(t.startsWith(n.EXT_DATA_CTX_PRFX))s=e.nodeCtx,i=t.replace(n.EXT_DATA_CTX_PRFX,"");else if(t.includes(n.NAMED_DATA_CTX_SPLTR)){let r=t.split(n.NAMED_DATA_CTX_SPLTR);s=h.getNamedCtx(r[0]),i=r[1]}else s=e.localCtx,i=t;return{ctx:s,name:i}}sub(t,e){let s=p.__parseProp(t,this);s.ctx.has(t)?this.allSubs.add(s.ctx.sub(s.name,e)):window.setTimeout(()=>{this.allSubs.add(s.ctx.sub(s.name,e))})}notify(t){let e=p.__parseProp(t,this);e.ctx.notify(e.name)}has(t){let e=p.__parseProp(t,this);return e.ctx.has(e.name)}add(t,e){let s=p.__parseProp(t,this);s.ctx.add(s.name,e,!1)}add$(t){for(let e in t)this.add(e,t[e])}get $(){if(!this.__stateProxy){let t=Object.create(null);this.__stateProxy=new Proxy(t,{set:(e,s,i)=>{let r=p.__parseProp(s,this);return r.ctx.pub(r.name,i),!0},get:(e,s)=>{let i=p.__parseProp(s,this);return i.ctx.read(i.name)}})}return this.__stateProxy}set$(t,e=!1){for(let s in t){let i=t[s];e||![String,Number,Boolean].includes(i==null?void 0:i.constructor)?this.$[s]=i:this.$[s]!==i&&(this.$[s]=i)}}__initDataCtx(){let t=this.constructor.__attrDesc;if(t)for(let e of Object.values(t))Object.keys(this.init$).includes(e)||(this.init$[e]="");for(let e in this.init$)if(e.startsWith(n.EXT_DATA_CTX_PRFX))this.nodeCtx.add(e.replace(n.EXT_DATA_CTX_PRFX,""),this.init$[e]);else if(e.includes(n.NAMED_DATA_CTX_SPLTR)){let s=e.split(n.NAMED_DATA_CTX_SPLTR),i=s[0].trim(),r=s[1].trim();if(i&&r){let a=h.getNamedCtx(i,!1);a||(a=h.registerNamedCtx(i,{})),a.add(r,this.init$[e])}}else this.localCtx.add(e,this.init$[e]);for(let e in this.cssInit$)this.bindCssData(e,this.cssInit$[e]);this.__dataCtxInitialized=!0}connectedCallback(){var t;if(this.__disconnectTimeout&&window.clearTimeout(this.__disconnectTimeout),!this.connectedOnce){let e=(t=this.getAttribute(n.CTX_NAME_ATTR))==null?void 0:t.trim();if(e&&this.style.setProperty(n.CSS_CTX_PROP,`'${e}'`),this.__initDataCtx(),this[n.SET_LATER_KEY]){for(let s in this[n.SET_LATER_KEY])w(this,s,this[n.SET_LATER_KEY][s]);delete this[n.SET_LATER_KEY]}this.initChildren=[...this.childNodes];for(let s of O)this.addTemplateProcessor(s);this.pauseRender?this.__initCallback():this.render()}this.connectedOnce=!0}destroyCallback(){}disconnectedCallback(){this.dropCssDataCache(),!!this.readyToDestroy&&(this.__disconnectTimeout&&window.clearTimeout(this.__disconnectTimeout),this.__disconnectTimeout=window.setTimeout(()=>{this.destroyCallback();for(let t of this.allSubs)t.remove(),this.allSubs.delete(t);for(let t of this.tplProcessors)this.tplProcessors.delete(t);d==null||d.delete(this.updateCssData),(d==null?void 0:d.size)||(T==null||T.disconnect(),T=null,d=null)},100))}static reg(t,e=!1){if(t||(M++,t=`${n.AUTO_TAG_PRFX}-${M}`),this.__tag=t,window.customElements.get(t)){console.warn(`${t} - is already in "customElements" registry`);return}window.customElements.define(t,e?class extends this{}:this)}static get is(){return this.__tag||this.reg(),this.__tag}static bindAttributes(t){this.observedAttributes=Object.keys(t),this.__attrDesc=t}attributeChangedCallback(t,e,s){if(e===s)return;let i=this.constructor.__attrDesc[t];i?this.__dataCtxInitialized?this.$[i]=s:this.init$[i]=s:this[t]=s}getCssData(t,e=!1){if(this.__cssDataCache||(this.__cssDataCache=Object.create(null)),!Object.keys(this.__cssDataCache).includes(t)){this.__computedStyle||(this.__computedStyle=window.getComputedStyle(this));let s=this.__computedStyle.getPropertyValue(t).trim();s.startsWith("'")&&s.endsWith("'")&&(s=s.replace(/\'/g,'"'));try{this.__cssDataCache[t]=JSON.parse(s)}catch{!e&&console.warn(`CSS Data error: ${t}`),this.__cssDataCache[t]=null}}return this.__cssDataCache[t]}__extractCssName(t){return t.split("--").map((e,s)=>s===0?"":e).join("--")}__initStyleAttrObserver(){d||(d=new Set),d.add(this.updateCssData),T||(T=new MutationObserver(t=>{t[0].type==="attributes"&&d.forEach(e=>{e()})}),T.observe(document,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style"]}))}bindCssData(t,e=""){this.__boundCssProps||(this.__boundCssProps=new Set),this.__boundCssProps.add(t);let s=this.getCssData(this.__extractCssName(t),!0);s===null&&(s=e),this.add(t,s),this.__initStyleAttrObserver()}dropCssDataCache(){this.__cssDataCache=null,this.__computedStyle=null}defineAccessor(t,e,s){let i="__"+t;this[i]=this[t],Object.defineProperty(this,t,{set:r=>{this[i]=r,s?window.setTimeout(()=>{e==null||e(r)}):e==null||e(r)},get:()=>this[i]}),this[t]=this[i]}static set shadowStyles(t){let e=new Blob([t],{type:"text/css"});this.__shadowStylesUrl=URL.createObjectURL(e)}},D=p;y(D,"template");var X="[Typed State] Wrong property name: ",J="[Typed State] Wrong property type: ",S=class{constructor(t,e){this.__typedSchema=t,this.__ctxId=e||b.generate(),this.__schema=Object.keys(t).reduce((s,i)=>(s[i]=t[i].value,s),{}),this.__data=h.registerNamedCtx(this.__ctxId,this.__schema)}get uid(){return this.__ctxId}setValue(t,e){if(!this.__typedSchema.hasOwnProperty(t)){console.warn(X+t);return}let s=this.__typedSchema[t];if((e==null?void 0:e.constructor)===s.type||s.nullable&&e===null){this.__data.pub(t,e);return}console.warn(J+t)}setMultipleValues(t){for(let e in t)this.setValue(e,t[e])}getValue(t){if(!this.__typedSchema.hasOwnProperty(t)){console.warn(X+t);return}return this.__data.read(t)}subscribe(t,e){return this.__data.sub(t,e)}remove(){this.__data.remove()}};var I=class{constructor(t){this.__typedSchema=t.typedSchema,this.__ctxId=t.ctxName||b.generate(),this.__data=h.registerNamedCtx(this.__ctxId,{}),this.__watchList=t.watchList||[],this.__handler=t.handler||null,this.__subsMap=Object.create(null),this.__observers=new Set,this.__items=new Set;let e=Object.create(null);this.__notifyObservers=(s,i)=>{this.__observeTimeout&&window.clearTimeout(this.__observeTimeout),e[s]||(e[s]=new Set),e[s].add(i),this.__observeTimeout=window.setTimeout(()=>{this.__observers.forEach(r=>{r({...e})}),e=Object.create(null)})}}notify(){this.__notifyTimeout&&window.clearTimeout(this.__notifyTimeout),this.__notifyTimeout=window.setTimeout(()=>{var t;(t=this.__handler)==null||t.call(this,[...this.__items])})}add(t){let e=new S(this.__typedSchema);for(let s in t)e.setValue(s,t[s]);return this.__data.add(e.uid,e),this.__watchList.forEach(s=>{this.__subsMap[e.uid]||(this.__subsMap[e.uid]=[]),this.__subsMap[e.uid].push(e.subscribe(s,()=>{this.__notifyObservers(s,e.uid)}))}),this.__items.add(e.uid),this.notify(),e}read(t){return this.__data.read(t)}readProp(t,e){return this.read(t).getValue(e)}publishProp(t,e,s){this.read(t).setValue(e,s)}remove(t){this.__items.delete(t),this.notify(),this.__data.pub(t,null),delete this.__subsMap[t]}clearAll(){this.__items.forEach(t=>{this.remove(t)})}observe(t){this.__observers.add(t)}unobserve(t){this.__observers.delete(t)}findItems(t){let e=[];return this.__items.forEach(s=>{let i=this.read(s);t(i)&&e.push(s)}),e}items(){return[...this.__items]}get size(){return this.__items.size}destroy(){this.__data.remove(),this.__observers=null;for(let t in this.__subsMap)this.__subsMap[t].forEach(e=>{e.remove()}),delete this.__subsMap[t]}};var E=class{static _print(t){console.warn(t)}static setDefaultTitle(t){this.defaultTitle=t}static setRoutingMap(t){Object.assign(this.appMap,t);for(let e in this.appMap)!this.defaultRoute&&this.appMap[e].default===!0?this.defaultRoute=e:!this.errorRoute&&this.appMap[e].error===!0&&(this.errorRoute=e)}static set routingEventName(t){this.__routingEventName=t}static get routingEventName(){return this.__routingEventName||"sym-on-route"}static readAddressBar(){let t={route:null,options:{}};return window.location.search.split(this.separator).forEach(s=>{if(s.includes("?"))t.route=s.replace("?","");else if(s.includes("=")){let i=s.split("=");t.options[i[0]]=decodeURI(i[1])}else t.options[s]=!0}),t}static notify(){let t=this.readAddressBar(),e=this.appMap[t.route];if(e&&e.title&&(document.title=e.title),t.route===null&&this.defaultRoute){this.applyRoute(this.defaultRoute);return}else if(!e&&this.errorRoute){this.applyRoute(this.errorRoute);return}else if(!e&&this.defaultRoute){this.applyRoute(this.defaultRoute);return}else if(!e){this._print(`Route "${t.route}" not found...`);return}let s=new CustomEvent(E.routingEventName,{detail:{route:t.route,options:Object.assign(e||{},t.options)}});window.dispatchEvent(s)}static reflect(t,e={}){let s=this.appMap[t];if(!s){this._print("Wrong route: "+t);return}let i="?"+t;for(let a in e)e[a]===!0?i+=this.separator+a:i+=this.separator+a+`=${e[a]}`;let r=s.title||this.defaultTitle||"";window.history.pushState(null,r,i),document.title=r}static applyRoute(t,e={}){this.reflect(t,e),this.notify()}static setSeparator(t){this._separator=t}static get separator(){return this._separator||"&"}static createRouterData(t,e){this.setRoutingMap(e);let s=h.registerNamedCtx(t,{route:null,options:null,title:null});return window.addEventListener(this.routingEventName,i=>{var r;s.multiPub({route:i.detail.route,options:i.detail.options,title:((r=i.detail.options)==null?void 0:r.title)||this.defaultTitle||""})}),E.notify(),s}};E.appMap=Object.create(null);window.onpopstate=()=>{E.notify()};function j(o,t){for(let e in t)e.includes("-")?o.style.setProperty(e,t[e]):o.style[e]=t[e]}function L(o,t){for(let e in t)t[e].constructor===Boolean?t[e]?o.setAttribute(e,""):o.removeAttribute(e):o.setAttribute(e,t[e])}function $(o={tag:"div"}){let t=document.createElement(o.tag);if(o.attributes&&L(t,o.attributes),o.styles&&j(t,o.styles),o.properties)for(let e in o.properties)t[e]=o.properties[e];return o.processors&&o.processors.forEach(e=>{e(t)}),o.children&&o.children.forEach(e=>{let s=$(e);t.appendChild(s)}),t}var k="idb-store-ready",Q="symbiote-db",Z="symbiote-idb-update_",F=class{_notifyWhenReady(t=null){window.dispatchEvent(new CustomEvent(k,{detail:{dbName:this.name,storeName:this.storeName,event:t}}))}get _updEventName(){return Z+this.name}_getUpdateEvent(t){return new CustomEvent(this._updEventName,{detail:{key:this.name,newValue:t}})}_notifySubscribers(t){window.localStorage.removeItem(this.name),window.localStorage.setItem(this.name,t),window.dispatchEvent(this._getUpdateEvent(t))}constructor(t,e){this.name=t,this.storeName=e,this.version=1,this.request=window.indexedDB.open(this.name,this.version),this.request.onupgradeneeded=s=>{this.db=s.target.result,this.objStore=this.db.createObjectStore(e,{keyPath:"_key"}),this.objStore.transaction.oncomplete=i=>{this._notifyWhenReady(i)}},this.request.onsuccess=s=>{this.db=s.target.result,this._notifyWhenReady(s)},this.request.onerror=s=>{console.error(s)},this._subscriptionsMap={},this._updateHandler=s=>{s.key===this.name&&this._subscriptionsMap[s.newValue]&&this._subscriptionsMap[s.newValue].forEach(async r=>{r(await this.read(s.newValue))})},this._localUpdateHandler=s=>{this._updateHandler(s.detail)},window.addEventListener("storage",this._updateHandler),window.addEventListener(this._updEventName,this._localUpdateHandler)}read(t){let s=this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).get(t);return new Promise((i,r)=>{s.onsuccess=a=>{var l;((l=a.target.result)==null?void 0:l._value)?i(a.target.result._value):(i(null),console.warn(`IDB: cannot read "${t}"`))},s.onerror=a=>{r(a)}})}write(t,e,s=!1){let i={_key:t,_value:e},a=this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).put(i);return new Promise((l,_)=>{a.onsuccess=m=>{s||this._notifySubscribers(t),l(m.target.result)},a.onerror=m=>{_(m)}})}delete(t,e=!1){let i=this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).delete(t);return new Promise((r,a)=>{i.onsuccess=l=>{e||this._notifySubscribers(t),r(l)},i.onerror=l=>{a(l)}})}getAll(){let e=this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).getAll();return new Promise((s,i)=>{e.onsuccess=r=>{let a=r.target.result;s(a.map(l=>l._value))},e.onerror=r=>{i(r)}})}subscribe(t,e){this._subscriptionsMap[t]||(this._subscriptionsMap[t]=new Set);let s=this._subscriptionsMap[t];return s.add(e),{remove:()=>{s.delete(e),s.size||delete this._subscriptionsMap[t]}}}stop(){window.removeEventListener("storage",this._updateHandler),this._subscriptionsMap=null,P.clear(this.name)}},P=class{static get readyEventName(){return k}static open(t=Q,e="store"){let s=t+"/"+e;return this._reg[s]||(this._reg[s]=new F(t,e)),this._reg[s]}static clear(t){window.indexedDB.deleteDatabase(t);for(let e in this._reg)e.split("/")[0]===t&&delete this._reg[e]}};y(P,"_reg",Object.create(null));export{E as AppRouter,D as BaseComponent,h as Data,P as IDB,I as TypedCollection,S as TypedData,b as UID,L as applyAttributes,j as applyStyles,$ as create,R as kebabToCamel,w as setNestedProp};
1
+ var j=Object.defineProperty;var k=(o,t,e)=>t in o?j(o,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[t]=e;var E=(o,t,e)=>(k(o,typeof t!="symbol"?t+"":t,e),e);function F(o){let t=e=>{var s;for(let i in e)((s=e[i])==null?void 0:s.constructor)===Object&&(e[i]=t(e[i]));return{...e}};return t(o)}var c=class{constructor(t){this.uid=Symbol(),this.name=t.name||null,t.schema.constructor===Object?this.store=F(t.schema):(this._storeIsProxy=!0,this.store=t.schema),this.callbackMap=Object.create(null)}static warn(t,e){console.warn(`Symbiote Data: cannot ${t}. Prop name: `+e)}read(t){return!this._storeIsProxy&&!this.store.hasOwnProperty(t)?(c.warn("read",t),null):this.store[t]}has(t){return this._storeIsProxy?this.store[t]!==void 0:this.store.hasOwnProperty(t)}add(t,e,s=!1){if(!s&&Object.keys(this.store).includes(t)){e!==this.store[t]&&this.notify(t);return}this.store[t]=e,this.notify(t)}pub(t,e){if(!this._storeIsProxy&&!this.store.hasOwnProperty(t)){c.warn("publish",t);return}this.store[t]=e,this.notify(t)}multiPub(t){for(let e in t)this.pub(e,t[e])}notify(t){this.callbackMap[t]&&this.callbackMap[t].forEach(e=>{e(this.store[t])})}sub(t,e,s=!0){return!this._storeIsProxy&&!this.store.hasOwnProperty(t)?(c.warn("subscribe",t),null):(this.callbackMap[t]||(this.callbackMap[t]=new Set),this.callbackMap[t].add(e),s&&e(this.store[t]),{remove:()=>{this.callbackMap[t].delete(e),this.callbackMap[t].size||delete this.callbackMap[t]},callback:e})}remove(){delete c.globalStore[this.uid]}static registerLocalCtx(t){let e=new c({schema:t});return c.globalStore[e.uid]=e,e}static registerNamedCtx(t,e){let s=c.globalStore[t];return s?console.warn('State: context name "'+t+'" already in use'):(s=new c({name:t,schema:e}),c.globalStore[t]=s),s}static clearNamedCtx(t){delete c.globalStore[t]}static getNamedCtx(t,e=!0){return c.globalStore[t]||(e&&console.warn('State: wrong context name - "'+t+'"'),null)}};c.globalStore=Object.create(null);var a=Object.freeze({BIND_ATTR:"set",ATTR_BIND_PRFX:"@",EXT_DATA_CTX_PRFX:"*",NAMED_DATA_CTX_SPLTR:"/",CTX_NAME_ATTR:"ctx-name",CSS_CTX_PROP:"--ctx-name",EL_REF_ATTR:"ref",AUTO_TAG_PRFX:"sym",REPEAT_ATTR:"repeat",REPEAT_ITEM_TAG_ATTR:"repeat-item-tag",SET_LATER_KEY:"__toSetLater__",USE_TPL:"use-template"});var D="1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm",B=D.length-1,y=class{static generate(t="XXXXXXXXX-XXX"){let e="";for(let s=0;s<t.length;s++)e+=t[s]==="-"?t[s]:D.charAt(Math.random()*B);return e}};function A(o,t,e){let s=!0,i,r=t.split(".");return r.forEach((n,l)=>{l<r.length-1?o=o[n]:i=n}),o?o[i]=e:s=!1,s}function x(o){return o.split("-").map((t,e)=>t&&e?t[0].toUpperCase()+t.slice(1):t).join("").split("_").map((t,e)=>t&&e?t.toUpperCase():t).join("")}function N(o,t){[...o.querySelectorAll(`[${a.REPEAT_ATTR}]`)].forEach(e=>{let s=e.getAttribute(a.REPEAT_ITEM_TAG_ATTR),i;if(s&&(i=window.customElements.get(s)),!i){i=class extends t.BaseComponent{constructor(){super();s||(this.style.display="contents")}};let n=e.innerHTML;i.template=n,i.reg(s)}for(;e.firstChild;)e.firstChild.remove();let r=e.getAttribute(a.REPEAT_ATTR);t.sub(r,n=>{if(!n){for(;e.firstChild;)e.firstChild.remove();return}let l=[...e.children],_,m=h=>{h.forEach((u,w)=>{if(l[w])if(l[w].set$)l[w].set$(u);else for(let C in u)l[w][C]=u[C];else{_||(_=new DocumentFragment);let C=new i;Object.assign(C.init$,u),_.appendChild(C)}}),_&&e.appendChild(_);let f=l.slice(h.length,l.length);for(let u of f)u.remove()};if(n.constructor===Array)m(n);else if(n.constructor===Object){let h=[];for(let f in n){let u=n[f];Object.defineProperty(u,"_KEY_",{value:f,enumerable:!0}),h.push(u)}m(h)}else console.warn("Symbiote repeat data type error:"),console.log(n)}),e.removeAttribute(a.REPEAT_ATTR),e.removeAttribute(a.REPEAT_ITEM_TAG_ATTR)})}function U(o,t){if(t.shadowRoot)return;let e=[...o.querySelectorAll("slot")];if(t.initChildren.length&&e.length){let s={};e.forEach(i=>{let r=i.getAttribute("name");r?s[r]={slot:i,fr:document.createDocumentFragment()}:s.__default__={slot:i,fr:document.createDocumentFragment()}}),t.initChildren.forEach(i=>{var n;let r=(n=i.getAttribute)==null?void 0:n.call(i,"slot");r?(i.removeAttribute("slot"),s[r].fr.appendChild(i)):s.__default__&&s.__default__.fr.appendChild(i)}),Object.values(s).forEach(i=>{i.slot.parentNode.insertBefore(i.fr,i.slot),i.slot.remove()})}}function H(o,t){[...o.querySelectorAll(`[${a.EL_REF_ATTR}]`)].forEach(e=>{let s=e.getAttribute(a.EL_REF_ATTR);t.ref[s]=e,e.removeAttribute(a.EL_REF_ATTR)})}function K(o,t){[...o.querySelectorAll(`[${a.BIND_ATTR}]`)].forEach(e=>{let i=e.getAttribute(a.BIND_ATTR).split(";");[...e.attributes].forEach(r=>{if(r.name.startsWith("-")&&r.value){let n=x(r.name.replace("-",""));i.push(n+":"+r.value),e.removeAttribute(r.name)}}),i.forEach(r=>{if(!r)return;let n=r.split(":").map(h=>h.trim()),l=n[0],_;l.indexOf(a.ATTR_BIND_PRFX)===0&&(_=!0,l=l.replace(a.ATTR_BIND_PRFX,""));let m=n[1].split(",").map(h=>h.trim());for(let h of m){let f;h.startsWith("!!")?(f="double",h=h.replace("!!","")):h.startsWith("!")&&(f="single",h=h.replace("!","")),t.sub(h,u=>{f==="double"?u=!!u:f==="single"&&(u=!u),_?(u==null?void 0:u.constructor)===Boolean?u?e.setAttribute(l,""):e.removeAttribute(l):e.setAttribute(l,u):A(e,l,u)||(e[a.SET_LATER_KEY]||(e[a.SET_LATER_KEY]=Object.create(null)),e[a.SET_LATER_KEY][l]=u)})}}),e.removeAttribute(a.BIND_ATTR)})}var S="{{",g="}}",W="skip-text";function q(o){let t,e=[],s=document.createTreeWalker(o,NodeFilter.SHOW_TEXT,{acceptNode:i=>{var r;return!((r=i.parentElement)==null?void 0:r.hasAttribute(W))&&i.textContent.includes(S)&&i.textContent.includes(g)&&1}});for(;t=s.nextNode();)e.push(t);return e}var Y=function(o,t){q(o).forEach(s=>{let i=[],r;for(;s.textContent.includes(g);)s.textContent.startsWith(S)?(r=s.textContent.indexOf(g)+g.length,s.splitText(r),i.push(s)):(r=s.textContent.indexOf(S),s.splitText(r)),s=s.nextSibling;i.forEach(n=>{let l=n.textContent.replace(S,"").replace(g,"");n.textContent="",t.sub(l,_=>{n.textContent=_})})})},v=[N,U,H,K,Y];var O=0,T=null,d=null,p=class extends HTMLElement{constructor(){super();E(this,"updateCssData",()=>{var t;this.dropCssDataCache(),(t=this.__boundCssProps)==null||t.forEach(e=>{let s=this.getCssData(this.__extractCssName(e),!0);this.$[e]!==s&&(this.$[e]=s)})});this.init$=Object.create(null),this.cssInit$=Object.create(null),this.tplProcessors=new Set,this.ref=Object.create(null),this.allSubs=new Set,this.pauseRender=!1,this.renderShadow=!1,this.readyToDestroy=!0,this.processInnerHtml=!1,this.allowCustomTemplate=!1}get BaseComponent(){return p}initCallback(){}__initCallback(){var t;this.__initialized||(this.__initialized=!0,(t=this.initCallback)==null||t.call(this))}render(t,e=this.renderShadow){let s;if((e||this.constructor.__shadowStylesUrl)&&!this.shadowRoot&&this.attachShadow({mode:"open"}),this.allowCustomTemplate){let r=this.getAttribute(a.USE_TPL);if(r){let n=this.getRootNode(),l=(n==null?void 0:n.querySelector(r))||document.querySelector(r);l?t=l.content.cloneNode(!0):console.warn(`Symbiote template "${r}" is not found...`)}}if(this.processInnerHtml)for(let r of this.tplProcessors)r(this,this);if(t||this.constructor.template){if(this.constructor.template&&!this.constructor.__tpl&&(this.constructor.__tpl=document.createElement("template"),this.constructor.__tpl.innerHTML=this.constructor.template),(t==null?void 0:t.constructor)===DocumentFragment)s=t;else if((t==null?void 0:t.constructor)===String){let r=document.createElement("template");r.innerHTML=t,s=r.content.cloneNode(!0)}else this.constructor.__tpl&&(s=this.constructor.__tpl.content.cloneNode(!0));for(let r of this.tplProcessors)r(s,this)}let i=()=>{s&&(e&&this.shadowRoot.appendChild(s)||this.appendChild(s)),this.__initCallback()};if(this.constructor.__shadowStylesUrl){e=!0;let r=document.createElement("link");r.rel="stylesheet",r.href=this.constructor.__shadowStylesUrl,r.onload=i,this.shadowRoot.prepend(r)}else i()}addTemplateProcessor(t){this.tplProcessors.add(t)}get autoCtxName(){return this.__autoCtxName||(this.__autoCtxName=y.generate(),this.style.setProperty(a.CSS_CTX_PROP,`'${this.__autoCtxName}'`)),this.__autoCtxName}get cssCtxName(){return this.getCssData(a.CSS_CTX_PROP,!0)}get ctxName(){var t;return((t=this.getAttribute(a.CTX_NAME_ATTR))==null?void 0:t.trim())||this.cssCtxName||this.autoCtxName}get localCtx(){return this.__localCtx||(this.__localCtx=c.registerLocalCtx({})),this.__localCtx}get nodeCtx(){return c.getNamedCtx(this.ctxName,!1)||c.registerNamedCtx(this.ctxName,{})}static __parseProp(t,e){let s,i;if(t.startsWith(a.EXT_DATA_CTX_PRFX))s=e.nodeCtx,i=t.replace(a.EXT_DATA_CTX_PRFX,"");else if(t.includes(a.NAMED_DATA_CTX_SPLTR)){let r=t.split(a.NAMED_DATA_CTX_SPLTR);s=c.getNamedCtx(r[0]),i=r[1]}else s=e.localCtx,i=t;return{ctx:s,name:i}}sub(t,e){let s=p.__parseProp(t,this);s.ctx.has(t)?this.allSubs.add(s.ctx.sub(s.name,e)):window.setTimeout(()=>{this.allSubs.add(s.ctx.sub(s.name,e))})}notify(t){let e=p.__parseProp(t,this);e.ctx.notify(e.name)}has(t){let e=p.__parseProp(t,this);return e.ctx.has(e.name)}add(t,e){let s=p.__parseProp(t,this);s.ctx.add(s.name,e,!1)}add$(t){for(let e in t)this.add(e,t[e])}get $(){if(!this.__stateProxy){let t=Object.create(null);this.__stateProxy=new Proxy(t,{set:(e,s,i)=>{let r=p.__parseProp(s,this);return r.ctx.pub(r.name,i),!0},get:(e,s)=>{let i=p.__parseProp(s,this);return i.ctx.read(i.name)}})}return this.__stateProxy}set$(t,e=!1){for(let s in t){let i=t[s];e||![String,Number,Boolean].includes(i==null?void 0:i.constructor)?this.$[s]=i:this.$[s]!==i&&(this.$[s]=i)}}__initDataCtx(){let t=this.constructor.__attrDesc;if(t)for(let e of Object.values(t))Object.keys(this.init$).includes(e)||(this.init$[e]="");for(let e in this.init$)if(e.startsWith(a.EXT_DATA_CTX_PRFX))this.nodeCtx.add(e.replace(a.EXT_DATA_CTX_PRFX,""),this.init$[e]);else if(e.includes(a.NAMED_DATA_CTX_SPLTR)){let s=e.split(a.NAMED_DATA_CTX_SPLTR),i=s[0].trim(),r=s[1].trim();if(i&&r){let n=c.getNamedCtx(i,!1);n||(n=c.registerNamedCtx(i,{})),n.add(r,this.init$[e])}}else this.localCtx.add(e,this.init$[e]);for(let e in this.cssInit$)this.bindCssData(e,this.cssInit$[e]);this.__dataCtxInitialized=!0}connectedCallback(){var t;if(!!this.isConnected){if(this.__disconnectTimeout&&window.clearTimeout(this.__disconnectTimeout),!this.connectedOnce){let e=(t=this.getAttribute(a.CTX_NAME_ATTR))==null?void 0:t.trim();if(e&&this.style.setProperty(a.CSS_CTX_PROP,`'${e}'`),this.__initDataCtx(),this[a.SET_LATER_KEY]){for(let s in this[a.SET_LATER_KEY])A(this,s,this[a.SET_LATER_KEY][s]);delete this[a.SET_LATER_KEY]}this.initChildren=[...this.childNodes];for(let s of v)this.addTemplateProcessor(s);this.pauseRender?this.__initCallback():this.render()}this.connectedOnce=!0}}destroyCallback(){}disconnectedCallback(){!this.connectedOnce||(this.dropCssDataCache(),!!this.readyToDestroy&&(this.__disconnectTimeout&&window.clearTimeout(this.__disconnectTimeout),this.__disconnectTimeout=window.setTimeout(()=>{this.destroyCallback();for(let t of this.allSubs)t.remove(),this.allSubs.delete(t);for(let t of this.tplProcessors)this.tplProcessors.delete(t);d==null||d.delete(this.updateCssData),(d==null?void 0:d.size)||(T==null||T.disconnect(),T=null,d=null)},100)))}static reg(t,e=!1){if(t||(O++,t=`${a.AUTO_TAG_PRFX}-${O}`),this.__tag=t,window.customElements.get(t)){console.warn(`${t} - is already in "customElements" registry`);return}window.customElements.define(t,e?class extends this{}:this)}static get is(){return this.__tag||this.reg(),this.__tag}static bindAttributes(t){this.observedAttributes=Object.keys(t),this.__attrDesc=t}attributeChangedCallback(t,e,s){if(e===s)return;let i=this.constructor.__attrDesc[t];i?this.__dataCtxInitialized?this.$[i]=s:this.init$[i]=s:this[t]=s}getCssData(t,e=!1){if(this.__cssDataCache||(this.__cssDataCache=Object.create(null)),!Object.keys(this.__cssDataCache).includes(t)){this.__computedStyle||(this.__computedStyle=window.getComputedStyle(this));let s=this.__computedStyle.getPropertyValue(t).trim();s.startsWith("'")&&s.endsWith("'")&&(s=s.replace(/\'/g,'"'));try{this.__cssDataCache[t]=JSON.parse(s)}catch{!e&&console.warn(`CSS Data error: ${t}`),this.__cssDataCache[t]=null}}return this.__cssDataCache[t]}__extractCssName(t){return t.split("--").map((e,s)=>s===0?"":e).join("--")}__initStyleAttrObserver(){d||(d=new Set),d.add(this.updateCssData),T||(T=new MutationObserver(t=>{t[0].type==="attributes"&&d.forEach(e=>{e()})}),T.observe(document,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style"]}))}bindCssData(t,e=""){this.__boundCssProps||(this.__boundCssProps=new Set),this.__boundCssProps.add(t);let s=this.getCssData(this.__extractCssName(t),!0);s===null&&(s=e),this.add(t,s),this.__initStyleAttrObserver()}dropCssDataCache(){this.__cssDataCache=null,this.__computedStyle=null}defineAccessor(t,e,s){let i="__"+t;this[i]=this[t],Object.defineProperty(this,t,{set:r=>{this[i]=r,s?window.setTimeout(()=>{e==null||e(r)}):e==null||e(r)},get:()=>this[i]}),this[t]=this[i]}static set shadowStyles(t){let e=new Blob([t],{type:"text/css"});this.__shadowStylesUrl=URL.createObjectURL(e)}},R=p;E(R,"template");var b=class{static _print(t){console.warn(t)}static setDefaultTitle(t){this.defaultTitle=t}static setRoutingMap(t){Object.assign(this.appMap,t);for(let e in this.appMap)!this.defaultRoute&&this.appMap[e].default===!0?this.defaultRoute=e:!this.errorRoute&&this.appMap[e].error===!0&&(this.errorRoute=e)}static set routingEventName(t){this.__routingEventName=t}static get routingEventName(){return this.__routingEventName||"sym-on-route"}static readAddressBar(){let t={route:null,options:{}};return window.location.search.split(this.separator).forEach(s=>{if(s.includes("?"))t.route=s.replace("?","");else if(s.includes("=")){let i=s.split("=");t.options[i[0]]=decodeURI(i[1])}else t.options[s]=!0}),t}static notify(){let t=this.readAddressBar(),e=this.appMap[t.route];if(e&&e.title&&(document.title=e.title),t.route===null&&this.defaultRoute){this.applyRoute(this.defaultRoute);return}else if(!e&&this.errorRoute){this.applyRoute(this.errorRoute);return}else if(!e&&this.defaultRoute){this.applyRoute(this.defaultRoute);return}else if(!e){this._print(`Route "${t.route}" not found...`);return}let s=new CustomEvent(b.routingEventName,{detail:{route:t.route,options:Object.assign(e||{},t.options)}});window.dispatchEvent(s)}static reflect(t,e={}){let s=this.appMap[t];if(!s){this._print("Wrong route: "+t);return}let i="?"+t;for(let n in e)e[n]===!0?i+=this.separator+n:i+=this.separator+n+`=${e[n]}`;let r=s.title||this.defaultTitle||"";window.history.pushState(null,r,i),document.title=r}static applyRoute(t,e={}){this.reflect(t,e),this.notify()}static setSeparator(t){this._separator=t}static get separator(){return this._separator||"&"}static createRouterData(t,e){this.setRoutingMap(e);let s=c.registerNamedCtx(t,{route:null,options:null,title:null});return window.addEventListener(this.routingEventName,i=>{var r;s.multiPub({route:i.detail.route,options:i.detail.options,title:((r=i.detail.options)==null?void 0:r.title)||this.defaultTitle||""})}),b.notify(),this.initPopstateListener(),s}static initPopstateListener(){this.__onPopstate||(this.__onPopstate=()=>{this.notify()},window.addEventListener("popstate",this.__onPopstate))}static removePopstateListener(){window.removeEventListener("popstate",this.__onPopstate),this.__onPopstate=null}};b.appMap=Object.create(null);function X(o,t){for(let e in t)e.includes("-")?o.style.setProperty(e,t[e]):o.style[e]=t[e]}function L(o,t){for(let e in t)t[e].constructor===Boolean?t[e]?o.setAttribute(e,""):o.removeAttribute(e):o.setAttribute(e,t[e])}function I(o={tag:"div"}){let t=document.createElement(o.tag);if(o.attributes&&L(t,o.attributes),o.styles&&X(t,o.styles),o.properties)for(let e in o.properties)t[e]=o.properties[e];return o.processors&&o.processors.forEach(e=>{e(t)}),o.children&&o.children.forEach(e=>{let s=I(e);t.appendChild(s)}),t}var M="idb-store-ready",z="symbiote-db",G="symbiote-idb-update_",$=class{_notifyWhenReady(t=null){window.dispatchEvent(new CustomEvent(M,{detail:{dbName:this.name,storeName:this.storeName,event:t}}))}get _updEventName(){return G+this.name}_getUpdateEvent(t){return new CustomEvent(this._updEventName,{detail:{key:this.name,newValue:t}})}_notifySubscribers(t){window.localStorage.removeItem(this.name),window.localStorage.setItem(this.name,t),window.dispatchEvent(this._getUpdateEvent(t))}constructor(t,e){this.name=t,this.storeName=e,this.version=1,this.request=window.indexedDB.open(this.name,this.version),this.request.onupgradeneeded=s=>{this.db=s.target.result,this.objStore=this.db.createObjectStore(e,{keyPath:"_key"}),this.objStore.transaction.oncomplete=i=>{this._notifyWhenReady(i)}},this.request.onsuccess=s=>{this.db=s.target.result,this._notifyWhenReady(s)},this.request.onerror=s=>{console.error(s)},this._subscriptionsMap={},this._updateHandler=s=>{s.key===this.name&&this._subscriptionsMap[s.newValue]&&this._subscriptionsMap[s.newValue].forEach(async r=>{r(await this.read(s.newValue))})},this._localUpdateHandler=s=>{this._updateHandler(s.detail)},window.addEventListener("storage",this._updateHandler),window.addEventListener(this._updEventName,this._localUpdateHandler)}read(t){let s=this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).get(t);return new Promise((i,r)=>{s.onsuccess=n=>{var l;((l=n.target.result)==null?void 0:l._value)?i(n.target.result._value):(i(null),console.warn(`IDB: cannot read "${t}"`))},s.onerror=n=>{r(n)}})}write(t,e,s=!1){let i={_key:t,_value:e},n=this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).put(i);return new Promise((l,_)=>{n.onsuccess=m=>{s||this._notifySubscribers(t),l(m.target.result)},n.onerror=m=>{_(m)}})}delete(t,e=!1){let i=this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).delete(t);return new Promise((r,n)=>{i.onsuccess=l=>{e||this._notifySubscribers(t),r(l)},i.onerror=l=>{n(l)}})}getAll(){let e=this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).getAll();return new Promise((s,i)=>{e.onsuccess=r=>{let n=r.target.result;s(n.map(l=>l._value))},e.onerror=r=>{i(r)}})}subscribe(t,e){this._subscriptionsMap[t]||(this._subscriptionsMap[t]=new Set);let s=this._subscriptionsMap[t];return s.add(e),{remove:()=>{s.delete(e),s.size||delete this._subscriptionsMap[t]}}}stop(){window.removeEventListener("storage",this._updateHandler),this._subscriptionsMap=null,P.clear(this.name)}},P=class{static get readyEventName(){return M}static open(t=z,e="store"){let s=t+"/"+e;return this._reg[s]||(this._reg[s]=new $(t,e)),this._reg[s]}static clear(t){window.indexedDB.deleteDatabase(t);for(let e in this._reg)e.split("/")[0]===t&&delete this._reg[e]}};E(P,"_reg",Object.create(null));export{b as AppRouter,R as BaseComponent,c as Data,P as IDB,y as UID,L as applyAttributes,X as applyStyles,I as create,x as kebabToCamel,A as setNestedProp};
package/core/AppRouter.js CHANGED
@@ -144,12 +144,25 @@ export class AppRouter {
144
144
  });
145
145
  });
146
146
  AppRouter.notify();
147
+ this.initPopstateListener();
147
148
  return routeData;
148
149
  }
150
+
151
+ static initPopstateListener() {
152
+ if (this.__onPopstate) {
153
+ return;
154
+ }
155
+ /** @private */
156
+ this.__onPopstate = () => {
157
+ this.notify();
158
+ };
159
+ window.addEventListener('popstate', this.__onPopstate);
160
+ }
161
+
162
+ static removePopstateListener() {
163
+ window.removeEventListener('popstate', this.__onPopstate);
164
+ this.__onPopstate = null;
165
+ }
149
166
  }
150
167
 
151
168
  AppRouter.appMap = Object.create(null);
152
-
153
- window.onpopstate = () => {
154
- AppRouter.notify();
155
- };
@@ -46,6 +46,21 @@ export class BaseComponent extends HTMLElement {
46
46
  mode: 'open',
47
47
  });
48
48
  }
49
+ if (this.allowCustomTemplate) {
50
+ let customTplSelector = this.getAttribute(DICT.USE_TPL);
51
+ if (customTplSelector) {
52
+ let root = this.getRootNode();
53
+ /** @type {HTMLTemplateElement} */
54
+ // @ts-ignore
55
+ let customTpl = root?.querySelector(customTplSelector) || document.querySelector(customTplSelector);
56
+ if (customTpl) {
57
+ // @ts-ignore
58
+ template = customTpl.content.cloneNode(true);
59
+ } else {
60
+ console.warn(`Symbiote template "${customTplSelector}" is not found...`);
61
+ }
62
+ }
63
+ }
49
64
  if (this.processInnerHtml) {
50
65
  for (let fn of this.tplProcessors) {
51
66
  fn(this, this);
@@ -116,6 +131,8 @@ export class BaseComponent extends HTMLElement {
116
131
  this.readyToDestroy = true;
117
132
  /** @type {Boolean} */
118
133
  this.processInnerHtml = false;
134
+ /** @type {Boolean} */
135
+ this.allowCustomTemplate = false;
119
136
  }
120
137
 
121
138
  /** @returns {String} */
@@ -301,6 +318,11 @@ export class BaseComponent extends HTMLElement {
301
318
  }
302
319
 
303
320
  connectedCallback() {
321
+ // As `connectedCallback` calls are queued, it could be called after element being detached from DOM
322
+ // See example at https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-conformance
323
+ if (!this.isConnected) {
324
+ return;
325
+ }
304
326
  if (this.__disconnectTimeout) {
305
327
  window.clearTimeout(this.__disconnectTimeout);
306
328
  }
@@ -332,6 +354,10 @@ export class BaseComponent extends HTMLElement {
332
354
  destroyCallback() {}
333
355
 
334
356
  disconnectedCallback() {
357
+ // if element wasn't connected, there is no need to disconnect it
358
+ if (!this.connectedOnce) {
359
+ return;
360
+ }
335
361
  this.dropCssDataCache();
336
362
  if (!this.readyToDestroy) {
337
363
  return;
@@ -22,4 +22,6 @@ export const DICT = Object.freeze({
22
22
  REPEAT_ITEM_TAG_ATTR: 'repeat-item-tag',
23
23
  // Key to restore nested properties was set before component construction
24
24
  SET_LATER_KEY: '__toSetLater__',
25
+ // Attribute to provide selector of custom template
26
+ USE_TPL: 'use-template',
25
27
  });
package/core/symbiote.js CHANGED
@@ -1,8 +1,6 @@
1
1
  // Core modules:
2
2
  export { BaseComponent } from './BaseComponent.js';
3
3
  export { Data } from './Data.js';
4
- export { TypedData } from './TypedData.js';
5
- export { TypedCollection } from './TypedCollection.js';
6
4
  export { AppRouter } from './AppRouter.js';
7
5
 
8
6
  // Utils:
@@ -172,6 +172,7 @@ const txtNodesProcessor = function (fr, fnCtx) {
172
172
  }
173
173
  tokenNodes.forEach((tNode) => {
174
174
  let prop = tNode.textContent.replace(OPEN_TOKEN, '').replace(CLOSE_TOKEN, '');
175
+ tNode.textContent = '';
175
176
  fnCtx.sub(prop, (val) => {
176
177
  tNode.textContent = val;
177
178
  });
package/package.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "publishConfig": {
26
26
  "access": "public"
27
27
  },
28
- "version": "1.9.0",
28
+ "version": "1.10.0",
29
29
  "description": "Symbiote.js",
30
30
  "author": "hello@symbiotejs.org",
31
31
  "license": "MIT",
package/build/s.js DELETED
@@ -1 +0,0 @@
1
- var __defProp=Object.defineProperty,__defNormalProp=(t,e,s)=>e in t?__defProp(t,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[e]=s,__publicField=(t,e,s)=>(__defNormalProp(t,"symbol"!=typeof e?e+"":e,s),s);function cloneObj(t){let e=t=>{var s;for(let r in t)(null==(s=t[r])?void 0:s.constructor)===Object&&(t[r]=e(t[r]));return{...t}};return e(t)}var Data=class{constructor(t){this.uid=Symbol(),this.name=t.name||null,t.schema.constructor===Object?this.store=cloneObj(t.schema):(this._storeIsProxy=!0,this.store=t.schema),this.callbackMap=Object.create(null)}static warn(t,e){console.warn(`Symbiote Data: cannot ${t}. Prop name: `+e)}read(t){return this._storeIsProxy||this.store.hasOwnProperty(t)?this.store[t]:(Data.warn("read",t),null)}has(t){return this._storeIsProxy?void 0!==this.store[t]:this.store.hasOwnProperty(t)}add(t,e,s=!0){!s&&Object.keys(this.store).includes(t)||(this.store[t]=e,this.callbackMap[t]&&this.callbackMap[t].forEach((e=>{e(this.store[t])})))}pub(t,e){this._storeIsProxy||this.store.hasOwnProperty(t)?this.add(t,e):Data.warn("publish",t)}multiPub(t){for(let e in t)this.pub(e,t[e])}notify(t){this.callbackMap[t]&&this.callbackMap[t].forEach((e=>{e(this.store[t])}))}sub(t,e,s=!0){return this._storeIsProxy||this.store.hasOwnProperty(t)?(this.callbackMap[t]||(this.callbackMap[t]=new Set),this.callbackMap[t].add(e),s&&e(this.store[t]),{remove:()=>{this.callbackMap[t].delete(e),this.callbackMap[t].size||delete this.callbackMap[t]},callback:e}):(Data.warn("subscribe",t),null)}remove(){delete Data.globalStore[this.uid]}static registerLocalCtx(t){let e=new Data({schema:t});return Data.globalStore[e.uid]=e,e}static registerNamedCtx(t,e){let s=Data.globalStore[t];return s?console.warn('State: context name "'+t+'" already in use'):(s=new Data({name:t,schema:e}),Data.globalStore[t]=s),s}static clearNamedCtx(t){delete Data.globalStore[t]}static getNamedCtx(t,e=!0){return Data.globalStore[t]||(e&&console.warn('State: wrong context name - "'+t+'"'),null)}};Data.globalStore=Object.create(null);var DICT=Object.freeze({BIND_ATTR:"set",ATTR_BIND_PRFX:"@",EXT_DATA_CTX_PRFX:"*",NAMED_DATA_CTX_SPLTR:"/",CTX_NAME_ATTR:"ctx-name",CSS_CTX_PROP:"--ctx-name",EL_REF_ATTR:"ref",AUTO_TAG_PRFX:"sym",REPEAT_ATTR:"repeat",REPEAT_ITEM_TAG_ATTR:"repeat-item-tag"}),CHARS="1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm",CHLENGTH=CHARS.length-1,UID=class{static generate(t="XXXXXXXXX-XXX"){let e="";for(let s=0;s<t.length;s++)e+="-"===t[s]?t[s]:CHARS.charAt(Math.random()*CHLENGTH);return e}};function repeatProcessor(t,e){[...t.querySelectorAll(`[${DICT.REPEAT_ATTR}]`)].forEach((t=>{let s,r=t.getAttribute(DICT.REPEAT_ITEM_TAG_ATTR);if(r&&(s=window.customElements.get(r)),!s){s=class extends e.BaseComponent{constructor(){super(),r||(this.style.display="contents")}};let i=t.innerHTML;s.template=i,s.reg(r)}for(;t.firstChild;)t.firstChild.remove();let i=t.getAttribute(DICT.REPEAT_ATTR);e.sub(i,(e=>{if(!e){for(;t.firstChild;)t.firstChild.remove();return}let r,i=[...t.children],a=e=>{e.forEach(((t,e)=>{if(i[e])if(i[e].set$)i[e].set$(t);else for(let s in t)i[e][s]=t[s];else{r||(r=new DocumentFragment);let e=new s;Object.assign(e.init$,t),r.appendChild(e)}})),r&&t.appendChild(r);let a=i.slice(e.length,i.length);for(let t of a)t.remove()};if(e.constructor===Array)a(e);else if(e.constructor===Object){let t=[];for(let s in e){let r=e[s];Object.defineProperty(r,"_KEY_",{value:s,enumerable:!0}),t.push(r)}a(t)}else console.warn("Symbiote repeat data type error:"),console.log(e)})),t.removeAttribute(DICT.REPEAT_ATTR),t.removeAttribute(DICT.REPEAT_ITEM_TAG_ATTR)}))}function slotProcessor(t,e){if(e.shadowRoot)return;let s=[...t.querySelectorAll("slot")];if(e.initChildren.length&&s.length){let t={};s.forEach((e=>{let s=e.getAttribute("name");s?t[s]={slot:e,fr:document.createDocumentFragment()}:t.__default__={slot:e,fr:document.createDocumentFragment()}})),e.initChildren.forEach((e=>{var s;let r=null==(s=e.getAttribute)?void 0:s.call(e,"slot");r?(e.removeAttribute("slot"),t[r].fr.appendChild(e)):t.__default__&&t.__default__.fr.appendChild(e)})),Object.values(t).forEach((t=>{t.slot.parentNode.insertBefore(t.fr,t.slot),t.slot.remove()}))}}function refProcessor(t,e){[...t.querySelectorAll(`[${DICT.EL_REF_ATTR}]`)].forEach((t=>{let s=t.getAttribute(DICT.EL_REF_ATTR);e.ref[s]=t,t.removeAttribute(DICT.EL_REF_ATTR)}))}function domSetProcessor(t,e){[...t.querySelectorAll(`[${DICT.BIND_ATTR}]`)].forEach((t=>{t.getAttribute(DICT.BIND_ATTR).split(";").forEach((s=>{if(!s)return;let r,i=s.split(":").map((t=>t.trim())),a=i[0];0===a.indexOf(DICT.ATTR_BIND_PRFX)&&(r=!0,a=a.replace(DICT.ATTR_BIND_PRFX,""));let o,n,l,c,h=i[1].split(",").map((t=>t.trim()));if(a.includes(".")){o=!0;let e=a.split(".");c=()=>{n=t,e.forEach(((t,s)=>{s<e.length-1?n=n[t]:l=t}))},c()}for(let s of h){let i;s.startsWith("!!")?(i="double",s=s.replace("!!","")):s.startsWith("!")&&(i="single",s=s.replace("!","")),e.sub(s,(e=>{"double"===i?e=!!e:"single"===i&&(e=!e),r?(null==e?void 0:e.constructor)===Boolean?e?t.setAttribute(a,""):t.removeAttribute(a):t.setAttribute(a,e):o?n?n[l]=e:window.setTimeout((()=>{c(),n[l]=e})):t[a]=e}))}})),t.removeAttribute(DICT.BIND_ATTR)}))}var OPEN_TOKEN="{{",CLOSE_TOKEN="}}",SKIP_ATTR="skip-text";function getTextNodesWithTokens(t){let e,s=[],r=document.createTreeWalker(t,NodeFilter.SHOW_TEXT,{acceptNode:t=>{var e;return!(null==(e=t.parentElement)?void 0:e.hasAttribute(SKIP_ATTR))&&t.textContent.includes(OPEN_TOKEN)&&t.textContent.includes(CLOSE_TOKEN)&&1}});for(;e=r.nextNode();)s.push(e);return s}var txtNodesProcessor=function(t,e){getTextNodesWithTokens(t).forEach((t=>{let s,r=[];for(;t.textContent.includes(CLOSE_TOKEN);)t.textContent.startsWith(OPEN_TOKEN)?(s=t.textContent.indexOf(CLOSE_TOKEN)+CLOSE_TOKEN.length,t.splitText(s),r.push(t)):(s=t.textContent.indexOf(OPEN_TOKEN),t.splitText(s)),t=t.nextSibling;r.forEach((t=>{let s=t.textContent.replace(OPEN_TOKEN,"").replace(CLOSE_TOKEN,"");e.sub(s,(e=>{t.textContent=e}))}))}))},tpl_processors_default=[repeatProcessor,slotProcessor,refProcessor,domSetProcessor,txtNodesProcessor],autoTagsCount=0,styleMutationObserver=null,styleMutationObserverCbList=null,_BaseComponent=class extends HTMLElement{constructor(){super(),__publicField(this,"updateCssData",(()=>{var t;this.dropCssDataCache(),null==(t=this.__boundCssProps)||t.forEach((t=>{let e=this.getCssData(this.__extractCssName(t),!0);this.$[t]!==e&&(this.$[t]=e)}))})),this.init$=Object.create(null),this.cssInit$=Object.create(null),this.tplProcessors=new Set,this.ref=Object.create(null),this.allSubs=new Set,this.pauseRender=!1,this.renderShadow=!1,this.readyToDestroy=!0,this.processInnerHtml=!1}get BaseComponent(){return _BaseComponent}initCallback(){}__initCallback(){var t;this.__initialized||(this.__initialized=!0,null==(t=this.initCallback)||t.call(this))}render(t,e=this.renderShadow){let s;if(!e&&!this.constructor.__shadowStylesUrl||this.shadowRoot||this.attachShadow({mode:"open"}),this.processInnerHtml)for(let t of this.tplProcessors)t(this,this);if(t||this.constructor.template){if(this.constructor.template&&!this.constructor.__tpl&&(this.constructor.__tpl=document.createElement("template"),this.constructor.__tpl.innerHTML=this.constructor.template),(null==t?void 0:t.constructor)===DocumentFragment)s=t;else if((null==t?void 0:t.constructor)===String){let e=document.createElement("template");e.innerHTML=t,s=e.content.cloneNode(!0)}else this.constructor.__tpl&&(s=this.constructor.__tpl.content.cloneNode(!0));for(let t of this.tplProcessors)t(s,this)}let r=()=>{s&&(e&&this.shadowRoot.appendChild(s)||this.appendChild(s)),this.__initCallback()};if(this.constructor.__shadowStylesUrl){e=!0;let t=document.createElement("link");t.rel="stylesheet",t.href=this.constructor.__shadowStylesUrl,t.onload=r,this.shadowRoot.prepend(t)}else r()}addTemplateProcessor(t){this.tplProcessors.add(t)}get autoCtxName(){return this.__autoCtxName||(this.__autoCtxName=UID.generate(),this.style.setProperty(DICT.CSS_CTX_PROP,`'${this.__autoCtxName}'`)),this.__autoCtxName}get cssCtxName(){return this.getCssData(DICT.CSS_CTX_PROP,!0)}get ctxName(){var t;return(null==(t=this.getAttribute(DICT.CTX_NAME_ATTR))?void 0:t.trim())||this.cssCtxName||this.autoCtxName}get localCtx(){return this.__localCtx||(this.__localCtx=Data.registerLocalCtx({})),this.__localCtx}get nodeCtx(){return Data.getNamedCtx(this.ctxName,!1)||Data.registerNamedCtx(this.ctxName,{})}static __parseProp(t,e){let s,r;if(t.startsWith(DICT.EXT_DATA_CTX_PRFX))s=e.nodeCtx,r=t.replace(DICT.EXT_DATA_CTX_PRFX,"");else if(t.includes(DICT.NAMED_DATA_CTX_SPLTR)){let e=t.split(DICT.NAMED_DATA_CTX_SPLTR);s=Data.getNamedCtx(e[0]),r=e[1]}else s=e.localCtx,r=t;return{ctx:s,name:r}}sub(t,e){let s=_BaseComponent.__parseProp(t,this);this.allSubs.add(s.ctx.sub(s.name,e))}notify(t){let e=_BaseComponent.__parseProp(t,this);e.ctx.notify(e.name)}has(t){let e=_BaseComponent.__parseProp(t,this);return e.ctx.has(e.name)}add(t,e){let s=_BaseComponent.__parseProp(t,this);s.ctx.add(s.name,e,!1)}add$(t){for(let e in t)this.add(e,t[e])}get $(){if(!this.__stateProxy){let t=Object.create(null);this.__stateProxy=new Proxy(t,{set:(t,e,s)=>{let r=_BaseComponent.__parseProp(e,this);return r.ctx.pub(r.name,s),!0},get:(t,e)=>{let s=_BaseComponent.__parseProp(e,this);return s.ctx.read(s.name)}})}return this.__stateProxy}set$(t,e=!1){for(let s in t){let r=t[s],i=[String,Number,Boolean];(e||!i.includes(null==r?void 0:r.constructor)||this.$[s]!==r)&&(this.$[s]=r)}}__initDataCtx(){let t=this.constructor.__attrDesc;if(t)for(let e of Object.values(t))Object.keys(this.init$).includes(e)||(this.init$[e]="");for(let t in this.init$)if(t.startsWith(DICT.EXT_DATA_CTX_PRFX))this.nodeCtx.add(t.replace(DICT.EXT_DATA_CTX_PRFX,""),this.init$[t]);else if(t.includes(DICT.NAMED_DATA_CTX_SPLTR)){let e=t.split(DICT.NAMED_DATA_CTX_SPLTR),s=e[0].trim(),r=e[1].trim();if(s&&r){let e=Data.getNamedCtx(s,!1);e||(e=Data.registerNamedCtx(s,{})),e.add(r,this.init$[t])}}else this.localCtx.add(t,this.init$[t]);for(let t in this.cssInit$)this.bindCssData(t,this.cssInit$[t]);this.__dataCtxInitialized=!0}connectedCallback(){var t;if(this.__disconnectTimeout&&window.clearTimeout(this.__disconnectTimeout),!this.connectedOnce){let e=null==(t=this.getAttribute(DICT.CTX_NAME_ATTR))?void 0:t.trim();e&&this.style.setProperty(DICT.CSS_CTX_PROP,`'${e}'`),this.__initDataCtx(),this.initChildren=[...this.childNodes];for(let t of tpl_processors_default)this.addTemplateProcessor(t);this.pauseRender?this.__initCallback():this.render()}this.connectedOnce=!0}destroyCallback(){}disconnectedCallback(){this.dropCssDataCache(),this.readyToDestroy&&(this.__disconnectTimeout&&window.clearTimeout(this.__disconnectTimeout),this.__disconnectTimeout=window.setTimeout((()=>{this.destroyCallback();for(let t of this.allSubs)t.remove(),this.allSubs.delete(t);for(let t of this.tplProcessors)this.tplProcessors.delete(t);null==styleMutationObserverCbList||styleMutationObserverCbList.delete(this.updateCssData),(null==styleMutationObserverCbList?void 0:styleMutationObserverCbList.size)||(null==styleMutationObserver||styleMutationObserver.disconnect(),styleMutationObserver=null,styleMutationObserverCbList=null)}),100))}static reg(t,e=!1){t||(autoTagsCount++,t=`${DICT.AUTO_TAG_PRFX}-${autoTagsCount}`),this.__tag=t,window.customElements.get(t)?console.warn(`${t} - is already in "customElements" registry`):window.customElements.define(t,e?class extends(this){}:this)}static get is(){return this.__tag||this.reg(),this.__tag}static bindAttributes(t){this.observedAttributes=Object.keys(t),this.__attrDesc=t}attributeChangedCallback(t,e,s){if(e===s)return;let r=this.constructor.__attrDesc[t];r?this.__dataCtxInitialized?this.$[r]=s:this.init$[r]=s:this[t]=s}getCssData(t,e=!1){if(this.__cssDataCache||(this.__cssDataCache=Object.create(null)),!Object.keys(this.__cssDataCache).includes(t)){this.__computedStyle||(this.__computedStyle=window.getComputedStyle(this));let s=this.__computedStyle.getPropertyValue(t).trim();s.startsWith("'")&&s.endsWith("'")&&(s=s.replace(/\'/g,'"'));try{this.__cssDataCache[t]=JSON.parse(s)}catch(s){!e&&console.warn(`CSS Data error: ${t}`),this.__cssDataCache[t]=null}}return this.__cssDataCache[t]}__extractCssName(t){return t.split("--").map(((t,e)=>0===e?"":t)).join("--")}__initStyleAttrObserver(){styleMutationObserverCbList||(styleMutationObserverCbList=new Set),styleMutationObserverCbList.add(this.updateCssData),styleMutationObserver||(styleMutationObserver=new MutationObserver((t=>{"attributes"===t[0].type&&styleMutationObserverCbList.forEach((t=>{t()}))}))).observe(document,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["style"]})}bindCssData(t,e=""){this.__boundCssProps||(this.__boundCssProps=new Set),this.__boundCssProps.add(t);let s=this.getCssData(this.__extractCssName(t),!0);null===s&&(s=e),this.add(t,s),this.__initStyleAttrObserver()}dropCssDataCache(){this.__cssDataCache=null,this.__computedStyle=null}defineAccessor(t,e,s){let r="__"+t;this[r]=this[t],Object.defineProperty(this,t,{set:t=>{this[r]=t,s?window.setTimeout((()=>{null==e||e(t)})):null==e||e(t)},get:()=>this[r]}),this[t]=this[r]}static set shadowStyles(t){let e=new Blob([t],{type:"text/css"});this.__shadowStylesUrl=URL.createObjectURL(e)}},BaseComponent=_BaseComponent;__publicField(BaseComponent,"template");var MSG_NAME="[Typed State] Wrong property name: ",MSG_TYPE="[Typed State] Wrong property type: ",TypedData=class{constructor(t,e){this.__typedSchema=t,this.__ctxId=e||UID.generate(),this.__schema=Object.keys(t).reduce(((e,s)=>(e[s]=t[s].value,e)),{}),this.__data=Data.registerNamedCtx(this.__ctxId,this.__schema)}get uid(){return this.__ctxId}setValue(t,e){if(!this.__typedSchema.hasOwnProperty(t))return void console.warn(MSG_NAME+t);let s=this.__typedSchema[t];(null==e?void 0:e.constructor)===s.type||s.nullable&&null===e?this.__data.pub(t,e):console.warn(MSG_TYPE+t)}setMultipleValues(t){for(let e in t)this.setValue(e,t[e])}getValue(t){if(this.__typedSchema.hasOwnProperty(t))return this.__data.read(t);console.warn(MSG_NAME+t)}subscribe(t,e){return this.__data.sub(t,e)}remove(){this.__data.remove()}},TypedCollection=class{constructor(t){this.__typedSchema=t.typedSchema,this.__ctxId=t.ctxName||UID.generate(),this.__data=Data.registerNamedCtx(this.__ctxId,{}),this.__watchList=t.watchList||[],this.__handler=t.handler||null,this.__subsMap=Object.create(null),this.__observers=new Set,this.__items=new Set;let e=Object.create(null);this.__notifyObservers=(t,s)=>{this.__observeTimeout&&window.clearTimeout(this.__observeTimeout),e[t]||(e[t]=new Set),e[t].add(s),this.__observeTimeout=window.setTimeout((()=>{this.__observers.forEach((t=>{t({...e})})),e=Object.create(null)}))}}notify(){this.__notifyTimeout&&window.clearTimeout(this.__notifyTimeout),this.__notifyTimeout=window.setTimeout((()=>{var t;null==(t=this.__handler)||t.call(this,[...this.__items])}))}add(t){let e=new TypedData(this.__typedSchema);for(let s in t)e.setValue(s,t[s]);return this.__data.add(e.uid,e),this.__watchList.forEach((t=>{this.__subsMap[e.uid]||(this.__subsMap[e.uid]=[]),this.__subsMap[e.uid].push(e.subscribe(t,(()=>{this.__notifyObservers(t,e.uid)})))})),this.__items.add(e.uid),this.notify(),e}read(t){return this.__data.read(t)}readProp(t,e){return this.read(t).getValue(e)}publishProp(t,e,s){this.read(t).setValue(e,s)}remove(t){this.__items.delete(t),this.notify(),this.__data.pub(t,null),delete this.__subsMap[t]}clearAll(){this.__items.forEach((t=>{this.remove(t)}))}observe(t){this.__observers.add(t)}unobserve(t){this.__observers.delete(t)}findItems(t){let e=[];return this.__items.forEach((s=>{let r=this.read(s);t(r)&&e.push(s)})),e}items(){return[...this.__items]}get size(){return this.__items.size}destroy(){this.__data.remove(),this.__observers=null;for(let t in this.__subsMap)this.__subsMap[t].forEach((t=>{t.remove()})),delete this.__subsMap[t]}},AppRouter=class{static _print(t){console.warn(t)}static setDefaultTitle(t){this.defaultTitle=t}static setRoutingMap(t){Object.assign(this.appMap,t);for(let t in this.appMap)this.defaultRoute||!0!==this.appMap[t].default?this.errorRoute||!0!==this.appMap[t].error||(this.errorRoute=t):this.defaultRoute=t}static set routingEventName(t){this.__routingEventName=t}static get routingEventName(){return this.__routingEventName||"sym-on-route"}static readAddressBar(){let t={route:null,options:{}};return window.location.search.split(this.separator).forEach((e=>{if(e.includes("?"))t.route=e.replace("?","");else if(e.includes("=")){let s=e.split("=");t.options[s[0]]=decodeURI(s[1])}else t.options[e]=!0})),t}static notify(){let t=this.readAddressBar(),e=this.appMap[t.route];if(e&&e.title&&(document.title=e.title),null===t.route&&this.defaultRoute)return void this.applyRoute(this.defaultRoute);if(!e&&this.errorRoute)return void this.applyRoute(this.errorRoute);if(!e&&this.defaultRoute)return void this.applyRoute(this.defaultRoute);if(!e)return void this._print(`Route "${t.route}" not found...`);let s=new CustomEvent(AppRouter.routingEventName,{detail:{route:t.route,options:Object.assign(e||{},t.options)}});window.dispatchEvent(s)}static reflect(t,e={}){let s=this.appMap[t];if(!s)return void this._print("Wrong route: "+t);let r="?"+t;for(let t in e)!0===e[t]?r+=this.separator+t:r+=this.separator+t+`=${e[t]}`;let i=s.title||this.defaultTitle||"";window.history.pushState(null,i,r),document.title=i}static applyRoute(t,e={}){this.reflect(t,e),this.notify()}static setSeparator(t){this._separator=t}static get separator(){return this._separator||"&"}static createRouterData(t,e){this.setRoutingMap(e);let s=Data.registerNamedCtx(t,{route:null,options:null,title:null});return window.addEventListener(this.routingEventName,(t=>{var e;s.multiPub({route:t.detail.route,options:t.detail.options,title:(null==(e=t.detail.options)?void 0:e.title)||this.defaultTitle||""})})),AppRouter.notify(),s}};function applyStyles(t,e){for(let s in e)s.includes("-")?t.style.setProperty(s,e[s]):t.style[s]=e[s]}function applyAttributes(t,e){for(let s in e)e[s].constructor===Boolean?e[s]?t.setAttribute(s,""):t.removeAttribute(s):t.setAttribute(s,e[s])}function create(t={tag:"div"}){let e=document.createElement(t.tag);if(t.attributes&&applyAttributes(e,t.attributes),t.styles&&applyStyles(e,t.styles),t.properties)for(let s in t.properties)e[s]=t.properties[s];return t.processors&&t.processors.forEach((t=>{t(e)})),t.children&&t.children.forEach((t=>{let s=create(t);e.appendChild(s)})),e}AppRouter.appMap=Object.create(null),window.onpopstate=()=>{AppRouter.notify()};var READY_EVENT_NAME="idb-store-ready",DEFAULT_DB_NAME="symbiote-db",UPD_EVENT_PREFIX="symbiote-idb-update_",DbInstance=class{_notifyWhenReady(t=null){window.dispatchEvent(new CustomEvent(READY_EVENT_NAME,{detail:{dbName:this.name,storeName:this.storeName,event:t}}))}get _updEventName(){return UPD_EVENT_PREFIX+this.name}_getUpdateEvent(t){return new CustomEvent(this._updEventName,{detail:{key:this.name,newValue:t}})}_notifySubscribers(t){window.localStorage.removeItem(this.name),window.localStorage.setItem(this.name,t),window.dispatchEvent(this._getUpdateEvent(t))}constructor(t,e){this.name=t,this.storeName=e,this.version=1,this.request=window.indexedDB.open(this.name,this.version),this.request.onupgradeneeded=t=>{this.db=t.target.result,this.objStore=this.db.createObjectStore(e,{keyPath:"_key"}),this.objStore.transaction.oncomplete=t=>{this._notifyWhenReady(t)}},this.request.onsuccess=t=>{this.db=t.target.result,this._notifyWhenReady(t)},this.request.onerror=t=>{console.error(t)},this._subscriptionsMap={},this._updateHandler=t=>{if(t.key===this.name&&this._subscriptionsMap[t.newValue]){this._subscriptionsMap[t.newValue].forEach((async e=>{e(await this.read(t.newValue))}))}},this._localUpdateHandler=t=>{this._updateHandler(t.detail)},window.addEventListener("storage",this._updateHandler),window.addEventListener(this._updEventName,this._localUpdateHandler)}read(t){let e=this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).get(t);return new Promise(((s,r)=>{e.onsuccess=e=>{var r;(null==(r=e.target.result)?void 0:r._value)?s(e.target.result._value):(s(null),console.warn(`IDB: cannot read "${t}"`))},e.onerror=t=>{r(t)}}))}write(t,e,s=!1){let r={_key:t,_value:e},i=this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).put(r);return new Promise(((e,r)=>{i.onsuccess=r=>{s||this._notifySubscribers(t),e(r.target.result)},i.onerror=t=>{r(t)}}))}delete(t,e=!1){let s=this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).delete(t);return new Promise(((r,i)=>{s.onsuccess=s=>{e||this._notifySubscribers(t),r(s)},s.onerror=t=>{i(t)}}))}getAll(){let t=this.db.transaction(this.storeName,"readwrite").objectStore(this.storeName).getAll();return new Promise(((e,s)=>{t.onsuccess=t=>{let s=t.target.result;e(s.map((t=>t._value)))},t.onerror=t=>{s(t)}}))}subscribe(t,e){this._subscriptionsMap[t]||(this._subscriptionsMap[t]=new Set);let s=this._subscriptionsMap[t];return s.add(e),{remove:()=>{s.delete(e),s.size||delete this._subscriptionsMap[t]}}}stop(){window.removeEventListener("storage",this._updateHandler),this._subscriptionsMap=null,IDB.clear(this.name)}},IDB=class{static get readyEventName(){return READY_EVENT_NAME}static open(t=DEFAULT_DB_NAME,e="store"){let s=t+"/"+e;return this._reg[s]||(this._reg[s]=new DbInstance(t,e)),this._reg[s]}static clear(t){window.indexedDB.deleteDatabase(t);for(let e in this._reg)e.split("/")[0]===t&&delete this._reg[e]}};__publicField(IDB,"_reg",Object.create(null));export{AppRouter,BaseComponent,Data,IDB,TypedCollection,TypedData,UID,applyAttributes,applyStyles,create};
@@ -1,201 +0,0 @@
1
- import { UID } from '../utils/UID.js';
2
- import { Data } from './Data.js';
3
- import { TypedData } from './TypedData.js';
4
-
5
- export class TypedCollection {
6
- /**
7
- * @param {Object} options
8
- * @param {Object<string, { type: any; value: any }>} options.typedSchema
9
- * @param {String[]} [options.watchList]
10
- * @param {(list: string[]) => void} [options.handler]
11
- * @param {String} [options.ctxName]
12
- */
13
- constructor(options) {
14
- /**
15
- * @private
16
- * @type {Object<string, { type: any; value: any }>}
17
- */
18
- this.__typedSchema = options.typedSchema;
19
- /**
20
- * @private
21
- * @type {String}
22
- */
23
- this.__ctxId = options.ctxName || UID.generate();
24
- /**
25
- * @private
26
- * @type {Data}
27
- */
28
- this.__data = Data.registerNamedCtx(this.__ctxId, {});
29
- /**
30
- * @private
31
- * @type {string[]}
32
- */
33
- this.__watchList = options.watchList || [];
34
- /**
35
- * @private
36
- * @type {(list: string[]) => void}
37
- */
38
- this.__handler = options.handler || null;
39
- /**
40
- * @private
41
- * @type {Object<string, any>}
42
- */
43
- this.__subsMap = Object.create(null);
44
- /**
45
- * @private
46
- * @type {Set}
47
- */
48
- this.__observers = new Set();
49
- /**
50
- * @private
51
- * @type {Set<string>}
52
- */
53
- this.__items = new Set();
54
-
55
- let changeMap = Object.create(null);
56
-
57
- /**
58
- * @private
59
- * @param {String} propName
60
- * @param {String} ctxId
61
- */
62
- this.__notifyObservers = (propName, ctxId) => {
63
- if (this.__observeTimeout) {
64
- window.clearTimeout(this.__observeTimeout);
65
- }
66
- if (!changeMap[propName]) {
67
- changeMap[propName] = new Set();
68
- }
69
- changeMap[propName].add(ctxId);
70
- /** @private */
71
- this.__observeTimeout = window.setTimeout(() => {
72
- this.__observers.forEach((handler) => {
73
- handler({ ...changeMap });
74
- });
75
- changeMap = Object.create(null);
76
- });
77
- };
78
- }
79
-
80
- notify() {
81
- if (this.__notifyTimeout) {
82
- window.clearTimeout(this.__notifyTimeout);
83
- }
84
- /** @private */
85
- this.__notifyTimeout = window.setTimeout(() => {
86
- this.__handler?.([...this.__items]);
87
- });
88
- }
89
-
90
- /**
91
- * @param {Object<string, any>} init
92
- * @returns {any}
93
- */
94
- add(init) {
95
- let item = new TypedData(this.__typedSchema);
96
- for (let prop in init) {
97
- item.setValue(prop, init[prop]);
98
- }
99
- this.__data.add(item.uid, item);
100
- this.__watchList.forEach((propName) => {
101
- if (!this.__subsMap[item.uid]) {
102
- this.__subsMap[item.uid] = [];
103
- }
104
- this.__subsMap[item.uid].push(
105
- item.subscribe(propName, () => {
106
- this.__notifyObservers(propName, item.uid);
107
- })
108
- );
109
- });
110
- this.__items.add(item.uid);
111
- this.notify();
112
- return item;
113
- }
114
-
115
- /**
116
- * @param {String} id
117
- * @returns {TypedData}
118
- */
119
- read(id) {
120
- return this.__data.read(id);
121
- }
122
-
123
- /**
124
- * @param {String} id
125
- * @param {String} propName
126
- * @returns {any}
127
- */
128
- readProp(id, propName) {
129
- let item = this.read(id);
130
- return item.getValue(propName);
131
- }
132
-
133
- /**
134
- * @template T
135
- * @param {String} id
136
- * @param {String} propName
137
- * @param {T} value
138
- */
139
- publishProp(id, propName, value) {
140
- let item = this.read(id);
141
- item.setValue(propName, value);
142
- }
143
-
144
- /** @param {String} id */
145
- remove(id) {
146
- this.__items.delete(id);
147
- this.notify();
148
- this.__data.pub(id, null);
149
- delete this.__subsMap[id];
150
- }
151
-
152
- clearAll() {
153
- this.__items.forEach((id) => {
154
- this.remove(id);
155
- });
156
- }
157
-
158
- /** @param {Function} handler */
159
- observe(handler) {
160
- this.__observers.add(handler);
161
- }
162
-
163
- /** @param {Function} handler */
164
- unobserve(handler) {
165
- this.__observers.delete(handler);
166
- }
167
-
168
- /**
169
- * @param {(item: TypedData) => Boolean} checkFn
170
- * @returns {String[]}
171
- */
172
- findItems(checkFn) {
173
- let result = [];
174
- this.__items.forEach((id) => {
175
- let item = this.read(id);
176
- if (checkFn(item)) {
177
- result.push(id);
178
- }
179
- });
180
- return result;
181
- }
182
-
183
- items() {
184
- return [...this.__items];
185
- }
186
-
187
- get size() {
188
- return this.__items.size;
189
- }
190
-
191
- destroy() {
192
- this.__data.remove();
193
- this.__observers = null;
194
- for (let id in this.__subsMap) {
195
- this.__subsMap[id].forEach((sub) => {
196
- sub.remove();
197
- });
198
- delete this.__subsMap[id];
199
- }
200
- }
201
- }
package/core/TypedData.js DELETED
@@ -1,78 +0,0 @@
1
- import { UID } from '../utils/UID.js';
2
- import { Data } from './Data.js';
3
-
4
- const MSG_NAME = '[Typed State] Wrong property name: ';
5
- const MSG_TYPE = '[Typed State] Wrong property type: ';
6
-
7
- export class TypedData {
8
- /**
9
- * @param {Object<string, { type: any; value: any; nullable?: Boolean }>} typedSchema
10
- * @param {String} [ctxName]
11
- */
12
- constructor(typedSchema, ctxName) {
13
- /** @private */
14
- this.__typedSchema = typedSchema;
15
- /** @private */
16
- this.__ctxId = ctxName || UID.generate();
17
- /** @private */
18
- this.__schema = Object.keys(typedSchema).reduce((acc, key) => {
19
- acc[key] = typedSchema[key].value;
20
- return acc;
21
- }, {});
22
- /**
23
- * @private
24
- * @type {Data}
25
- */
26
- this.__data = Data.registerNamedCtx(this.__ctxId, this.__schema);
27
- }
28
-
29
- /** @returns {String} */
30
- get uid() {
31
- return this.__ctxId;
32
- }
33
-
34
- /**
35
- * @param {String} prop
36
- * @param {any} value
37
- */
38
- setValue(prop, value) {
39
- if (!this.__typedSchema.hasOwnProperty(prop)) {
40
- console.warn(MSG_NAME + prop);
41
- return;
42
- }
43
- let pDesc = this.__typedSchema[prop];
44
- if (value?.constructor === pDesc.type || (pDesc.nullable && value === null)) {
45
- this.__data.pub(prop, value);
46
- return;
47
- }
48
- console.warn(MSG_TYPE + prop);
49
- }
50
-
51
- /** @param {Object<string, any>} updObj */
52
- setMultipleValues(updObj) {
53
- for (let prop in updObj) {
54
- this.setValue(prop, updObj[prop]);
55
- }
56
- }
57
-
58
- /** @param {String} prop */
59
- getValue(prop) {
60
- if (!this.__typedSchema.hasOwnProperty(prop)) {
61
- console.warn(MSG_NAME + prop);
62
- return undefined;
63
- }
64
- return this.__data.read(prop);
65
- }
66
-
67
- /**
68
- * @param {String} prop
69
- * @param {(newVal: any) => void} handler
70
- */
71
- subscribe(prop, handler) {
72
- return this.__data.sub(prop, handler);
73
- }
74
-
75
- remove() {
76
- this.__data.remove();
77
- }
78
- }