@elenajs/core 1.0.0-rc.1 → 1.0.0-rc.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,7 +22,7 @@
22
22
 
23
23
  <br/>
24
24
 
25
- <p align="center">Elena is a simple, tiny library (2.6kB) for building <a href="https://elenajs.com/">Progressive Web Components</a>. Unlike most web component libraries, Elena doesn’t force JavaScript for everything. You can load HTML and CSS first, then use JavaScript to progressively add interactivity.</p>
25
+ <p align="center">Elena is a simple, tiny library for building <a href="https://elenajs.com/">Progressive Web Components</a>. Unlike most web component libraries, Elena doesn’t force JavaScript for everything. You can load HTML and CSS first, then use JavaScript to progressively add interactivity.</p>
26
26
 
27
27
  ## Documentation
28
28
 
@@ -38,16 +38,12 @@ Elena is a monorepo containing several packages published to npm under the `@ele
38
38
 
39
39
  | Package | Description | Version | Stability |
40
40
  | --- | --- | --- | --- |
41
- | [`@elenajs/core`](https://github.com/getelena/elena/tree/main/packages/core) | Elena core runtime library. | [![npm](https://img.shields.io/npm/v/@elenajs/core.svg)](https://www.npmjs.com/package/@elenajs/core) | [![stability-release-candidate](https://img.shields.io/badge/stability-pre--release-48c9b0.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#release-candidate) |
42
- | [`@elenajs/components`](https://github.com/getelena/elena/tree/main/packages/components) | Elena web components. | [![npm](https://img.shields.io/npm/v/@elenajs/components.svg)](https://www.npmjs.com/package/@elenajs/components) | [![stability-release-candidate](https://img.shields.io/badge/stability-pre--release-48c9b0.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#release-candidate) |
43
- | [`@elenajs/bundler`](https://github.com/getelena/elena/tree/main/packages/bundler) | Elena bundler for web component libraries. | [![npm](https://img.shields.io/npm/v/@elenajs/bundler.svg)](https://www.npmjs.com/package/@elenajs/bundler) | [![stability-release-candidate](https://img.shields.io/badge/stability-pre--release-48c9b0.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#release-candidate) |
44
- | [`@elenajs/cli`](https://github.com/getelena/elena/tree/main/packages/cli) | Elena CLI for scaffolding web components. | [![npm](https://img.shields.io/npm/v/@elenajs/cli.svg)](https://www.npmjs.com/package/@elenajs/cli) | [![stability-release-candidate](https://img.shields.io/badge/stability-pre--release-48c9b0.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#release-candidate) |
45
- | [`@elenajs/plugin-cem-define`](https://github.com/getelena/elena/tree/main/packages/plugin-cem-define) | Elena CEM Define plugin. | [![npm](https://img.shields.io/npm/v/@elenajs/plugin-cem-define.svg)](https://www.npmjs.com/package/@elenajs/plugin-cem-define) | [![stability-beta](https://img.shields.io/badge/stability-beta-33bbff.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#beta) |
46
- | [`@elenajs/plugin-cem-tag`](https://github.com/getelena/elena/tree/main/packages/plugin-cem-tag) | Elena CEM Tag plugin. | [![npm](https://img.shields.io/npm/v/@elenajs/cli.svg)](https://www.npmjs.com/package/@elenajs/cli) | [![stability-beta](https://img.shields.io/badge/stability-beta-33bbff.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#beta) |
47
- | [`@elenajs/plugin-cem-typescript`](https://github.com/getelena/elena/tree/main/packages/plugin-cem-typescript) | Elena CEM TypeScript plugin. | [![npm](https://img.shields.io/npm/v/@elenajs/plugin-cem-typescript.svg)](https://www.npmjs.com/package/@elenajs/plugin-cem-typescript) | [![stability-beta](https://img.shields.io/badge/stability-beta-33bbff.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#beta) |
48
- | [`@elenajs/plugin-rollup-css`](https://github.com/getelena/elena/tree/main/packages/plugin-rollup-css) | Elena Rollup CSS plugin. | [![npm](https://img.shields.io/npm/v/@elenajs/plugin-rollup-css.svg)](https://www.npmjs.com/package/@elenajs/plugin-rollup-css) | [![stability-beta](https://img.shields.io/badge/stability-beta-33bbff.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#beta) |
49
- | [`@elenajs/ssr`](https://github.com/getelena/elena/tree/main/packages/ssr) | Elena server-side rendering tools. | [![npm](https://img.shields.io/npm/v/@elenajs/ssr.svg)](https://www.npmjs.com/package/@elenajs/ssr) | [![stability-experimental](https://img.shields.io/badge/stability-experimental-orange.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#experimental) |
50
- | [`@elenajs/mcp`](https://github.com/getelena/elena/tree/main/packages/ssr) | Elena MCP server. | [![npm](https://img.shields.io/npm/v/@elenajs/mcp.svg)](https://www.npmjs.com/package/@elenajs/mcp) | [![stability-experimental](https://img.shields.io/badge/stability-experimental-orange.svg)](https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md#experimental) |
41
+ | [`@elenajs/core`](https://github.com/getelena/elena/tree/main/packages/core) | Elena core runtime library. | [![npm](https://img.shields.io/npm/v/@elenajs/core.svg)](https://www.npmjs.com/package/@elenajs/core) | ![stability-release-candidate](https://img.shields.io/badge/stability-pre--release-48c9b0.svg) |
42
+ | [`@elenajs/components`](https://github.com/getelena/elena/tree/main/packages/components) | Elena demo web components. | [![npm](https://img.shields.io/npm/v/@elenajs/components.svg)](https://www.npmjs.com/package/@elenajs/components) | ![stability-release-candidate](https://img.shields.io/badge/stability-pre--release-48c9b0.svg) |
43
+ | [`@elenajs/bundler`](https://github.com/getelena/elena/tree/main/packages/bundler) | Elena bundler for component libraries. | [![npm](https://img.shields.io/npm/v/@elenajs/bundler.svg)](https://www.npmjs.com/package/@elenajs/bundler) | ![stability-release-candidate](https://img.shields.io/badge/stability-pre--release-48c9b0.svg) |
44
+ | [`@elenajs/cli`](https://github.com/getelena/elena/tree/main/packages/cli) | Elena CLI for scaffolding web components. | [![npm](https://img.shields.io/npm/v/@elenajs/cli.svg)](https://www.npmjs.com/package/@elenajs/cli) | ![stability-release-candidate](https://img.shields.io/badge/stability-pre--release-48c9b0.svg) |
45
+ | [`@elenajs/ssr`](https://github.com/getelena/elena/tree/main/packages/ssr) | Elena server-side rendering tools. | [![npm](https://img.shields.io/npm/v/@elenajs/ssr.svg)](https://www.npmjs.com/package/@elenajs/ssr) | ![stability-experimental](https://img.shields.io/badge/stability-experimental-red.svg) |
46
+ | [`@elenajs/mcp`](https://github.com/getelena/elena/tree/main/packages/ssr) | Elena MCP server. | [![npm](https://img.shields.io/npm/v/@elenajs/mcp.svg)](https://www.npmjs.com/package/@elenajs/mcp) | ![stability-experimental](https://img.shields.io/badge/stability-experimental-red.svg) |
51
47
 
52
48
  <!-- https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md -->
53
49
 
package/dist/bundle.js CHANGED
@@ -1,2 +1,6 @@
1
- function t(t,e,s){if(e="boolean"===t&&"boolean"!=typeof e?null!==e:e,!s)return e;if("toAttribute"===s)switch(t){case"object":case"array":return null===e?null:JSON.stringify(e);case"boolean":return e?"":null;case"number":return null===e?null:e;default:return""===e?null:e}else switch(t){case"object":case"array":if(!e)return e;try{return JSON.parse(e)}catch{return console.warn("░█ [ELENA]: Invalid JSON: "+e),null}case"boolean":return e;case"number":return null!==e?+e:e;default:return e??""}}function e(t,e,s){t?null===s?t.removeAttribute(e):t.setAttribute(e,s):console.warn("░█ [ELENA]: Cannot sync attrs.")}const s={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};function n(t){return Array.isArray(t)?t.map(t=>i(t)).join(""):i(t)}function i(t){return t?.t?String(t):(e=String(t??""),String(e).replace(/[&<>"']/g,t=>s[t]));var e}function r(t,...e){let s;return{t:!0,strings:t,values:e,toString:()=>(void 0===s&&(s=t.reduce((t,s,i)=>t+s+n(e[i]),"")),s)}}function o(t){return{t:!0,toString:()=>t??""}}const h=Object.freeze({t:!0,toString:()=>""}),c=t=>Array.isArray(t)?t.some(t=>t?.t):t?.t,u=t=>Array.isArray(t)?t.map(t=>String(t??"")).join(""):String(t??"");function l(t){return t.replace(/>\n\s*/g,">").replace(/\n\s*</g,"<").replace(/\n\s*/g," ")}const a=new WeakMap,f="e"+Math.random().toString(36).slice(2,6);function d(t,e,s){return!function(t,e,s){if(t.i!==e||!t.o)return!1;for(let e=0;e<s.length;e++){const n=s[e],i=Array.isArray(n)?u(n):n;if(i!==t.h[e]){if(c(n)||!t.o[e])return!1;t.h[e]=i,t.o[e].textContent=u(n)}}return!0}(t,e,s)&&(function(t,e,s){let i=a.get(e);if(!i){const t=Array.from(e,l);i={processedStrings:t,template:s.length>0?p(t,s.length):null},a.set(e,i)}if(i.template)t.o=function(t,e,s){const i=e.content.cloneNode(!0),r=document.createTreeWalker(i,NodeFilter.SHOW_COMMENT),o=new Array(s.length),h=[];let l;for(;l=r.nextNode();)l.data===f&&h.push(l);for(let t=0;t<h.length;t++){const e=s[t];if(c(e)){const s=document.createElement("template");s.innerHTML=n(e),h[t].parentNode.replaceChild(s.content,h[t])}else{const s=document.createTextNode(u(e));h[t].parentNode.replaceChild(s,h[t]),o[t]=s}}return t.replaceChildren(i),o}(t,i.template,s);else{const e=s.map(t=>n(t)),r=i.processedStrings.reduce((t,s,n)=>t+s+(e[n]??""),"").replace(/>\s+</g,"><").trim(),o=document.createElement("template");o.innerHTML=r,y(t,o.content.childNodes),t.o=new Array(s.length)}t.i=e,t.h=s.map(t=>Array.isArray(t)?u(t):t)}(t,e,s),!0)}function p(t,e){const s=`\x3c!--${f}--\x3e`,n=t.reduce((t,n,i)=>t+n.replace(/>\s+</g,"><")+(i<e?s:""),"").trim(),i=document.createElement("template");i.innerHTML=n;const r=document.createTreeWalker(i.content,NodeFilter.SHOW_COMMENT);let o=0;for(;r.nextNode();)r.currentNode.data===f&&o++;return o===e?i:null}function y(t,e){const s=Array.from(t.childNodes),n=Array.from(e),i=Math.max(s.length,n.length);for(let e=0;e<i;e++){const i=s[e],r=n[e];i?r?i.nodeType!==r.nodeType||i.nodeType===Node.ELEMENT_NODE&&i.tagName!==r.tagName?t.replaceChild(r,i):i.nodeType===Node.TEXT_NODE?i.textContent!==r.textContent&&(i.textContent=r.textContent):i.nodeType===Node.ELEMENT_NODE&&(g(i,r),y(i,r.childNodes)):t.removeChild(i):t.appendChild(r)}}function g(t,e){for(let s=t.attributes.length-1;s>=0;s--){const{name:n}=t.attributes[s];e.hasAttribute(n)||t.removeAttribute(n)}for(let s=0;s<e.attributes.length;s++){const{name:n,value:i}=e.attributes[s];t.getAttribute(n)!==i&&t.setAttribute(n,i)}}class m extends Event{constructor(t,e){super(t,{bubbles:!0,composed:!0,...e})}}const b=new WeakSet;function w(s){return class extends s{element=null;attributeChangedCallback(e,s,n){super.attributeChangedCallback?.(e,s,n),"text"!==e?(this.u=!0,function(e,s,n,i){if(n!==i){const n=typeof e[s];"undefined"===n&&console.warn(`░█ [ELENA]: Prop "${s}" has no default.`);const r=t(n,i,"toProp");e[s]=r}}(this,e,s,n),this.u=!1,this.l&&s!==n&&!this.p&&this.m()):this.text=n??""}static get observedAttributes(){if(this.A)return this.A;const t=this.S||(this.props||[]).map(t=>"string"==typeof t?t:t.name);return this.A=[...t,"text"],this.A}connectedCallback(){super.connectedCallback?.(),this.N(),this._(),this.v(),this.C(),this.willUpdate(),this.L(),this.k(),this.O(),this.P(),this.l||(this.l=!0,this.setAttribute("hydrated",""),this.firstUpdated()),this.updated()}N(){const s=this.constructor;if(b.has(s))return;const n=new Set,i=[];if(s.props){for(const t of s.props)"string"==typeof t?i.push(t):(i.push(t.name),!1===t.reflect&&n.add(t.name));i.includes("text")&&console.warn('░█ [ELENA]: "text" is reserved.'),function(s,n,i){for(const r of n){const n=!i||!i.has(r);Object.defineProperty(s,r,{configurable:!0,enumerable:!0,get(){return this.j?this.j.get(r):void 0},set(s){if(this.j||(this.j=new Map),s!==this.j.get(r)&&(this.j.set(r,s),this.isConnected))if(n){if(!this.u){const n=t(typeof s,s,"toAttribute");e(this,r,n)}}else this.l&&!this.p&&this.m()}})}}(s.prototype,i,n)}var r;s.S=i,s.M=n,s.U=s.events||null,s.q=(r=s.element)?t=>t.querySelector(r):t=>t.firstElementChild,b.add(s)}_(){this.u=!0;for(const t of this.constructor.S)if(Object.prototype.hasOwnProperty.call(this,t)){const e=this[t];delete this[t],this[t]=e}this.u=!1}v(){this.l||void 0!==this.F||(this.text=this.textContent.trim())}get J(){return this.R??this.shadowRoot??this}C(){const t=this.constructor;if(!t.shadow)return;(this.R??this.shadowRoot)||(this.R=this.attachShadow({mode:t.shadow}));const e=this.R??this.shadowRoot;if(t.styles){if(!t.I){const e=Array.isArray(t.styles)?t.styles:[t.styles];t.I=e.map(t=>{if("string"==typeof t){const e=new CSSStyleSheet;return e.replaceSync(t),e}return t})}e.adoptedStyleSheets=t.I}}L(){const t=this.render();if(t&&t.strings){const e=this.J,s=d(e,t.strings,t.values);this.l&&s&&(this.element=this.constructor.q(e))}}k(){if(!this.element){const t=this.J;this.element=this.constructor.q(t),this.element||(this.constructor.element&&console.warn("░█ [ELENA]: Element not found."),this.element=t.firstElementChild)}}O(){if(this.j){const s=this.constructor.M;for(const[n,i]of this.j){if(s.has(n))continue;const r=t(typeof i,i,"toAttribute");(null!==r||this.hasAttribute(n))&&e(this,n,r)}}}P(){const t=this.constructor.U;if(!this.W&&t?.length)if(this.element){this.W=!0;for(const e of t)this.element.addEventListener(e,this),this[e]=(...t)=>this.element[e](...t)}else console.warn("░█ [ELENA]: Cannot add events.")}render(){}willUpdate(){}firstUpdated(){}updated(){}adoptedCallback(){super.adoptedCallback?.()}disconnectedCallback(){if(super.disconnectedCallback?.(),this.W){this.W=!1;for(const t of this.constructor.U)this.element?.removeEventListener(t,this)}}handleEvent(t){this.constructor.U?.includes(t.type)&&(t.stopPropagation(),this.dispatchEvent(new m(t.type,{cancelable:!0})))}get text(){return this.F??""}set text(t){const e=this.F;this.F=t,this.l&&e!==t&&!this.p&&this.m()}static define(){var t,e;this.tagName?(t=this.tagName,e=this,"undefined"!=typeof window&&"customElements"in window&&(window.customElements.get(t)||window.customElements.define(t,e))):console.warn("░█ [ELENA]: define() without a tagName.")}m(){this.p||this.$||(this.$=!0,this.D=new Promise(t=>{this.T=t}),queueMicrotask(()=>{try{this.B()}catch(t){console.error("░█ [ELENA]:",t)}}))}B(){this.$=!1;const t=this.T;this.T=null;try{try{this.willUpdate(),this.p=!0,this.L()}finally{this.p=!1}this.updated()}finally{this.D=null,t()}}get updateComplete(){return this.D?this.D:Promise.resolve()}requestUpdate(){this.l&&!this.p&&this.m()}}}export{w as Elena,m as ElenaEvent,r as html,h as nothing,o as unsafeHTML};
2
- //# sourceMappingURL=bundle.js.map
1
+ /**
2
+ * @elenajs/core v1.0.0-rc.11
3
+ * (c) 2025-present Ariel Salminen and Elena contributors
4
+ * @license MIT
5
+ */
6
+ const t="░█ [ELENA]: ",s=Array.isArray,i=Symbol("elena.raw"),n=s=>console.warn(t+s),e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};function o(t){return s(t)?t.map(r).join(""):r(t)}function r(t){return t?.[i]?String(t):String(t??"").replace(/[&<>"']/g,t=>e[t])}class h{constructor(t,s){this.strings=t,this.values=s}toString(){return null==this.t&&(this.t=this.strings.reduce((t,s,i)=>t+s+o(this.values[i]),"")),this.t}}function c(t,...s){return new h(t,s)}function l(t){return{[i]:!0,toString:()=>t??""}}h.prototype[i]=!0;const u={[i]:!0,toString:()=>""},f=t=>s(t)?t.some(t=>t?.[i]):t?.[i],a=t=>s(t)?t.join(""):String(t??"");function d(t){return t.replace(/(>)\n\s*|\n\s*(<)/g,"$1$2").replace(/\n\s*/g," ").replace(/>\s+</g,"><")}function p(t,s,i){if(s="boolean"===t&&"boolean"!=typeof s?null!==s:s,!i)return s;if("toAttribute"===i)switch(t){case"object":case"array":return s&&JSON.stringify(s);case"boolean":return s?"":null;default:return""===s?null:s}else switch(t){case"object":case"array":if(!s)return s;try{return JSON.parse(s)}catch{return n("Invalid JSON: "+s),null}case"number":return null!==s?+s:s;default:return s??""}}function g(t,s,i){t?null===i?t.removeAttribute(s):t.setAttribute(s,i):n("Cannot sync attrs.")}const y=new WeakMap,b="e"+Math.random().toString(36).slice(2),S=()=>document.createElement("template"),m=t=>document.createTreeWalker(t,128);function _(t,s){const i=`\x3c!--${b}--\x3e`,n=[];let e="";for(let o=0;o<t.length;o++)if(e+=t[o],o<s){const s=t[o].match(/([^\s"'>/=]+)\s*=\s*["']$/);s?(n.push(s[1]),e+=b+"_"+o):(n.push(null),e+=i)}const o=S();o.innerHTML=e.trim();const r=m(o.content);let h=0;for(;r.nextNode();)r.currentNode.data===b&&h++;return h!==n.filter(t=>null===t).length?null:{i:o,o:n}}function w(t,s){const i=Array.from(t.childNodes),n=Array.from(s),e=Math.max(i.length,n.length);for(let s=0;s<e;s++){const e=i[s],o=n[s];e?o?e.nodeType!==o.nodeType||1===e.nodeType&&e.tagName!==o.tagName?t.replaceChild(o,e):3===e.nodeType?e.textContent!==o.textContent&&(e.textContent=o.textContent):1===e.nodeType&&(v(e,o),w(e,o.childNodes)):t.removeChild(e):t.appendChild(o)}}function v(t,s){for(let i=t.attributes.length-1;i>=0;i--){const{name:n}=t.attributes[i];s.hasAttribute(n)||t.removeAttribute(n)}for(let i=0;i<s.attributes.length;i++){const{name:n,value:e}=s.attributes[i];t.getAttribute(n)!==e&&t.setAttribute(n,e)}}const x=new WeakSet,C=(t,s)=>Object.prototype.hasOwnProperty.call(t,s);function A(i){return class extends i{element=null;attributeChangedCallback(t,s,i){if(super.attributeChangedCallback?.(t,s,i),"text"!==t){if(s!==i)if(this.h&&!this.l){const s=this.u.get(t),n=typeof s,e="string"===n?i??"":p(n,i,"toProp");e!==s&&this.u.set(t,e),this.p()}else this.S=!0,function(t,s,i,e){if(i!==e){const i=typeof t[s];"undefined"===i&&n(`Prop "${s}" has no default.`);const o=p(i,e,"toProp");t[s]=o}}(this,t,s,i),this.S=!1}else this.text=i??""}static get observedAttributes(){if(this.m)return this.m;const t=(this.props||[]).map(t=>"string"==typeof t?t:t.name);return this.m=[...t,"text"],this.m}connectedCallback(){super.connectedCallback?.(),this._(),this.v(),this.h||void 0!==this.C||(this.text=this.textContent.trim()),this.A(),this.k=this.P??this.shadowRoot??this,this.$??=()=>{try{this.M()}catch(s){console.error(t,s)}},this.willUpdate(),this.N(),this.O(),this.j(),this.h||(this.h=!0,this.setAttribute("hydrated",""),this.firstUpdated()),this.updated()}_(){const t=this.constructor;if(x.has(t))return;const s=new Set,i=[];if(t.props){for(const n of t.props)"string"==typeof n?i.push(n):(i.push(n.name),!1===n.reflect&&s.add(n.name));i.includes("text")&&n('"text" is reserved.'),function(t,s,i){for(const n of s){const s=!i||!i.has(n);Object.defineProperty(t,n,{configurable:!0,enumerable:!0,get(){return this.u?.get(n)},set(t){if(this.u||(this.u=new Map),t!==this.u.get(n)&&(this.u.set(n,t),this.isConnected))if(s){if(!this.S){const s=p(typeof t,t,"toAttribute");g(this,n,s)}}else this.h&&!this.l&&this.p()}})}}(t.prototype,i,s)}if(t.U=i,t.q=s,t.J=t.events||null,t.J)for(const s of t.J)C(t.prototype,s)||(t.prototype[s]=function(...t){return this.element[s](...t)});var e;t.R=(e=t.element)?t=>t.querySelector(e):t=>t.firstElementChild,x.add(t)}v(){this.S=!0;for(const t of this.constructor.U)if(C(this,t)){const s=this[t];delete this[t],this[t]=s}this.S=!1}A(){const t=this.constructor;if(!t.shadow)return;this.P||this.shadowRoot||(this.P=this.attachShadow({mode:t.shadow}));const s=this.P??this.shadowRoot;if(t.styles){if(!t.W){const s=[t.styles].flat();t.W=s.map(t=>{if("string"==typeof t){const s=new CSSStyleSheet;return s.replaceSync(t),s}return t})}s.adoptedStyleSheets=t.W}}N(){const t=this.constructor,i=this.k,e=this.render();if(e&&e.strings&&!function(t,i,n){if(t.D!==i||!t.F)return!1;const e=t.F,o=t.I;for(let t=0;t<n.length;t++){const i=n[t],r=s(i)?a(i):i;if(r===o[t])continue;if(f(i)&&i!==u)return!1;const h=e[t];if(!h)return!1;o[t]=r;const c=String(r??"");h.nodeType?h.textContent=c:h[0].setAttribute(h[1],c)}return!0}(r=i,h=e.strings,c=e.values)&&(function(t,i,n){let e=y.get(i);if(!e){const t=i.map(d);e={L:t,T:n.length>0?_(t,n.length):null},y.set(i,e)}if(e.T)t.F=function(t,i,n){const{i:e,o:r}=i,h=e.content.cloneNode(!0),c=m(h),l=Array(n.length),d=[];let p;for(;p=c.nextNode();)p.data===b&&d.push(p);let g=0;for(let t=0;t<n.length;t++){const i=r[t];if(i){const e=h.querySelector(`[${i}="${b+"_"+t}"]`);if(e){const o=n[t],r=String((s(o)?a(o):o)??"");e.setAttribute(i,r),l[t]=[e,i]}}else{const s=d[g++],i=n[t];if(f(i)&&i!==u){const t=S();t.innerHTML=o(i),s.parentNode.replaceChild(t.content,s)}else{const n=document.createTextNode(a(i));s.parentNode.replaceChild(n,s),l[t]=n}}}return t.D?(w(t,h.childNodes),null):(t.replaceChildren(h),l)}(t,e.T,n);else{const s=n.map(o),i=e.L.reduce((t,i,n)=>t+i+(s[n]??""),"").replace(/>\s+</g,"><").trim(),r=S();r.innerHTML=i,w(t,r.content.childNodes),t.F=null}t.D=i,t.I=n.map(t=>s(t)?a(t):t)}(r,h,c),1)){const s=this.element;if(this.element=t.R(i),this.B&&s&&this.element!==s){const i=t.J;for(const t of i)s.removeEventListener(t,this),this.element.addEventListener(t,this)}}var r,h,c;this.element||(this.element=t.R(i),this.element||(t.element&&n("Element not found."),this.element=i.firstElementChild))}O(){if(this.u){const t=this.constructor.q;for(const[s,i]of this.u){if(t.has(s))continue;const n=p(typeof i,i,"toAttribute");(null!==n||this.hasAttribute(s))&&g(this,s,n)}}}j(){const t=this.constructor.J;if(!this.B&&t?.length)if(this.element){this.B=!0;for(const s of t)this.element.addEventListener(s,this)}else n("Cannot add events.")}render(){}willUpdate(){}firstUpdated(){}updated(){}adoptedCallback(){super.adoptedCallback?.()}disconnectedCallback(){if(super.disconnectedCallback?.(),this.B){this.B=!1;for(const t of this.constructor.J)this.element?.removeEventListener(t,this)}}handleEvent(t){this.constructor.J?.includes(t.type)&&(t.bubbles&&(t.composed||this.k===this)||this.dispatchEvent(new Event(t.type,{bubbles:t.bubbles})))}get text(){return this.C??""}set text(t){const s=this.C;this.C=t,this.h&&s!==t&&!this.l&&this.p()}static define(){const t=this.tagName;t?function(t,s){const i=globalThis.customElements;i?.get(t)||i?.define(t,s)}(t,this):n("define() without a tagName.")}p(){this.l||this.G||(this.G=!0,queueMicrotask(this.$))}M(){this.G=!1;const t=this.H;this.H=null;try{try{this.willUpdate(),this.l=!0,this.N()}finally{this.l=!1}this.updated()}finally{this.K=null,t?.()}}get updateComplete(){return this.G?(this.K||(this.K=new Promise(t=>{this.H=t})),this.K):Promise.resolve()}requestUpdate(){this.h&&!this.l&&this.p()}}}export{A as Elena,c as html,u as nothing,l as unsafeHTML};
@@ -1 +1 @@
1
- {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/common/props.js"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,mCAJW,MAAM,SACN,GAAG,cACH,aAAa,GAAG,QAAQ,OAwClC;AAED;;;;;;GAMG;AACH,uCAJW,OAAO,QACP,MAAM,SACN,MAAM,GAAG,IAAI,QAYvB;AAED;;;;;;;;GAQG;AACH,qDAHW,MAAM,EAAE,cACR,GAAG,CAAC,MAAM,CAAC,QAsCrB;AAED;;;;;;;;GAQG;AACH,kCALW,MAAM,QACN,MAAM,YACN,GAAG,YACH,GAAG,QAWb"}
1
+ {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/common/props.js"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,mCAJW,MAAM,SACN,GAAG,cACH,aAAa,GAAG,QAAQ,OAqClC;AAED;;;;;;GAMG;AACH,uCAJW,OAAO,QACP,MAAM,SACN,MAAM,GAAG,IAAI,QAYvB;AAED;;;;;;;;GAQG;AACH,qDAHW,MAAM,EAAE,cACR,GAAG,CAAC,MAAM,CAAC,QAsCrB;AAED;;;;;;;;GAQG;AACH,kCALW,MAAM,QACN,MAAM,YACN,GAAG,YACH,GAAG,QAWb"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Render a tagged template into an Elena Element with DOM diffing.
3
- * Returns true if the DOM was fully rebuilt, false if only text
4
- * nodes were patched in place.
3
+ * Returns true if the DOM was fully rebuilt, false if parts were
4
+ * patched in place.
5
5
  *
6
6
  * @param {HTMLElement} element
7
7
  * @param {TemplateStringsArray} strings - Static parts of the tagged template
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/common/render.js"],"names":[],"mappings":"AAKA;;;;;;;;;GASG;AACH,wCALW,WAAW,WACX,oBAAoB,kBAElB,OAAO,CAQnB"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/common/render.js"],"names":[],"mappings":"AAWA;;;;;;;;;GASG;AACH,wCALW,WAAW,WACX,oBAAoB,kBAElB,OAAO,CAQnB"}
@@ -20,10 +20,9 @@ export function resolveValue(value: any): string;
20
20
  *
21
21
  * @param {TemplateStringsArray} strings
22
22
  * @param {...*} values
23
- * @returns {{ __raw: true, strings: TemplateStringsArray, values: Array, toString(): string }}
23
+ * @returns {{ strings: TemplateStringsArray, values: Array, toString(): string }}
24
24
  */
25
25
  export function html(strings: TemplateStringsArray, ...values: any[]): {
26
- __raw: true;
27
26
  strings: TemplateStringsArray;
28
27
  values: any[];
29
28
  toString(): string;
@@ -32,10 +31,9 @@ export function html(strings: TemplateStringsArray, ...values: any[]): {
32
31
  * Renders a string as HTML rather than text.
33
32
  *
34
33
  * @param {string} str - The raw HTML string to trust.
35
- * @returns {{ __raw: true, toString(): string }}
34
+ * @returns {{ toString(): string }}
36
35
  */
37
36
  export function unsafeHTML(str: string): {
38
- __raw: true;
39
37
  toString(): string;
40
38
  };
41
39
  /**
@@ -45,16 +43,18 @@ export function unsafeHTML(str: string): {
45
43
  * @returns {string}
46
44
  */
47
45
  export function collapseWhitespace(string: string): string;
46
+ export function warn(msg: string): void;
48
47
  /**
49
48
  * A placeholder you can return from a conditional expression
50
49
  * inside a template to render nothing.
51
50
  *
52
- * @type {{ __raw: true, toString(): string }}
51
+ * @type {{ toString(): string }}
53
52
  */
54
53
  export const nothing: {
55
- __raw: true;
56
54
  toString(): string;
57
55
  };
58
56
  export function isRaw(value: any): boolean;
59
57
  export function toPlainText(value: any): string;
58
+ export const prefix: "\u2591\u2588 [ELENA]: ";
59
+ export const isArray: (arg: any) => arg is any[];
60
60
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/common/utils.js"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,uCAHW,MAAM,2BAShB;AASD,6CAEC;AAED;;;;;;GAMG;AACH,oCAHW,GAAC,GACC,MAAM,CAOlB;AAaD;;;;;;;GAOG;AACH,8BAJW,oBAAoB,aACjB,GAAC,EAAA,GACF;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,oBAAoB,CAAC;IAAC,MAAM,QAAQ;IAAC,QAAQ,IAAI,MAAM,CAAA;CAAE,CAiB7F;AAED;;;;;GAKG;AACH,gCAHW,MAAM,GACJ;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,IAAI,MAAM,CAAA;CAAE,CAI/C;AA4BD;;;;;GAKG;AACH,2CAHW,MAAM,GACJ,MAAM,CAOlB;AArCD;;;;;GAKG;AACH,sBAFU;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,IAAI,MAAM,CAAA;CAAE,CAE6B;AAQnE,6BAHI,GAAC,GACC,OAAO,CAGmD;AAQhE,mCAHI,GAAC,GACC,MAAM,CAG0E"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/common/utils.js"],"names":[],"mappings":"AAWA;;;;;GAKG;AACH,uCAHW,MAAM,2BAMhB;AASD,6CAEC;AAED;;;;;;GAMG;AACH,oCAHW,GAAC,GACC,MAAM,CAOlB;AAkCD;;;;;;;GAOG;AACH,8BAJW,oBAAoB,aACjB,GAAC,EAAA,GACF;IAAE,OAAO,EAAE,oBAAoB,CAAC;IAAC,MAAM,QAAQ;IAAC,QAAQ,IAAI,MAAM,CAAA;CAAE,CAIhF;AAED;;;;;GAKG;AACH,gCAHW,MAAM,GACJ;IAAE,QAAQ,IAAI,MAAM,CAAA;CAAE,CAIlC;AA0BD;;;;;GAKG;AACH,2CAHW,MAAM,GACJ,MAAM,CAOlB;AAhIM,0BAHI,MAAM,QAGoC;AA6FrD;;;;;GAKG;AACH,sBAFU;IAAE,QAAQ,IAAI,MAAM,CAAA;CAAE,CAE2B;AAQpD,6BAHI,GAAC,GACC,OAAO,CAE2E;AAQxF,mCAHI,GAAC,GACC,MAAM,CAEwE;AA3H3F,qBAAe,wBAAc,CAAC;AAC9B,iDAA8B"}
package/dist/elena.d.ts CHANGED
@@ -13,10 +13,12 @@ export type ElenaConstructor = new (...args: any[]) => HTMLElement;
13
13
  export type ElenaInstanceMembers = {
14
14
  text: string;
15
15
  element: HTMLElement | null;
16
+ updateComplete: Promise<void>;
16
17
  render(): void;
17
18
  willUpdate(): void;
18
19
  firstUpdated(): void;
19
20
  updated(): void;
21
+ requestUpdate(): void;
20
22
  connectedCallback(): void;
21
23
  disconnectedCallback(): void;
22
24
  };
@@ -37,6 +39,5 @@ export type ElenaElementConstructor = (new (...args: any[]) => HTMLElement & Ele
37
39
  import { html } from "./common/utils.js";
38
40
  import { unsafeHTML } from "./common/utils.js";
39
41
  import { nothing } from "./common/utils.js";
40
- import { ElenaEvent } from "./common/events.js";
41
- export { html, unsafeHTML, nothing, ElenaEvent };
42
+ export { html, unsafeHTML, nothing };
42
43
  //# sourceMappingURL=elena.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"elena.d.ts","sourceRoot":"","sources":["../src/elena.js"],"names":[],"mappings":"AAkEA;;;;;;;;;GASG;AACH,kCAHW,gBAAgB,GACd,uBAAuB,CAwdnC;+BA3fY,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,WAAW;mCAInC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAAC,MAAM,IAAI,IAAI,CAAC;IAAC,UAAU,IAAI,IAAI,CAAC;IAAC,YAAY,IAAI,IAAI,CAAC;IAAC,OAAO,IAAI,IAAI,CAAC;IAAC,iBAAiB,IAAI,IAAI,CAAC;IAAC,oBAAoB,IAAI,IAAI,CAAA;CAAE;8BAIjL;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE;sCAInC,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,WAAW,GAAG,oBAAoB,CAAC,GAAG;IACvE,MAAM,IAAI,IAAI,CAAC;IACnB,QAAY,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,eAAe,CAAC,EAAE,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,MAAM,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC;CAC9D;qBA7CqD,mBAAmB;2BAAnB,mBAAmB;wBAAnB,mBAAmB;2BAEjD,oBAAoB"}
1
+ {"version":3,"file":"elena.d.ts","sourceRoot":"","sources":["../src/elena.js"],"names":[],"mappings":"AAkEA;;;;;;;;;GASG;AACH,kCAHW,gBAAgB,GACd,uBAAuB,CAwenC;+BA5gBY,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,WAAW;mCAInC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAAC,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,MAAM,IAAI,IAAI,CAAC;IAAC,UAAU,IAAI,IAAI,CAAC;IAAC,YAAY,IAAI,IAAI,CAAC;IAAC,OAAO,IAAI,IAAI,CAAC;IAAC,aAAa,IAAI,IAAI,CAAC;IAAC,iBAAiB,IAAI,IAAI,CAAC;IAAC,oBAAoB,IAAI,IAAI,CAAA;CAAE;8BAIvO;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE;sCAInC,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,WAAW,GAAG,oBAAoB,CAAC,GAAG;IACvE,MAAM,IAAI,IAAI,CAAC;IACnB,QAAY,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,eAAe,CAAC,EAAE,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,MAAM,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC;CAC9D;qBA5CmE,mBAAmB;2BAAnB,mBAAmB;wBAAnB,mBAAmB"}
package/dist/elena.js CHANGED
@@ -1,2 +1,6 @@
1
- import{getProps as t,setProps as e,getPropValue as s,syncAttribute as i}from"./props.js";import{defineElement as n}from"./utils.js";export{html,nothing,unsafeHTML}from"./utils.js";import{renderTemplate as r}from"./render.js";import{ElenaEvent as o}from"./events.js";const h=new WeakSet;function a(a){return class extends a{element=null;attributeChangedCallback(e,s,i){super.attributeChangedCallback?.(e,s,i),"text"!==e?(this._syncing=!0,t(this,e,s,i),this._syncing=!1,this._hydrated&&s!==i&&!this._isRendering&&this._safeRender()):this.text=i??""}static get observedAttributes(){if(this._observedAttrs)return this._observedAttrs;const t=this._propNames||(this.props||[]).map(t=>"string"==typeof t?t:t.name);return this._observedAttrs=[...t,"text"],this._observedAttrs}connectedCallback(){super.connectedCallback?.(),this._setupStaticProps(),this._captureClassFieldDefaults(),this._captureText(),this._attachShadow(),this.willUpdate(),this._applyRender(),this._resolveInnerElement(),this._syncProps(),this._delegateEvents(),this._hydrated||(this._hydrated=!0,this.setAttribute("hydrated",""),this.firstUpdated()),this.updated()}_setupStaticProps(){const t=this.constructor;if(h.has(t))return;const s=new Set,i=[];if(t.props){for(const e of t.props)"string"==typeof e?i.push(e):(i.push(e.name),!1===e.reflect&&s.add(e.name));i.includes("text")&&console.warn('░█ [ELENA]: "text" is reserved.'),e(t.prototype,i,s)}var n;t._propNames=i,t._noReflect=s,t._elenaEvents=t.events||null,t._resolver=(n=t.element)?t=>t.querySelector(n):t=>t.firstElementChild,h.add(t)}_captureClassFieldDefaults(){this._syncing=!0;for(const t of this.constructor._propNames)if(Object.prototype.hasOwnProperty.call(this,t)){const e=this[t];delete this[t],this[t]=e}this._syncing=!1}_captureText(){this._hydrated||void 0!==this._text||(this.text=this.textContent.trim())}get _renderRoot(){return this._shadow??this.shadowRoot??this}_attachShadow(){const t=this.constructor;if(!t.shadow)return;(this._shadow??this.shadowRoot)||(this._shadow=this.attachShadow({mode:t.shadow}));const e=this._shadow??this.shadowRoot;if(t.styles){if(!t._adoptedSheets){const e=Array.isArray(t.styles)?t.styles:[t.styles];t._adoptedSheets=e.map(t=>{if("string"==typeof t){const e=new CSSStyleSheet;return e.replaceSync(t),e}return t})}e.adoptedStyleSheets=t._adoptedSheets}}_applyRender(){const t=this.render();if(t&&t.strings){const e=this._renderRoot,s=r(e,t.strings,t.values);this._hydrated&&s&&(this.element=this.constructor._resolver(e))}}_resolveInnerElement(){if(!this.element){const t=this._renderRoot;this.element=this.constructor._resolver(t),this.element||(this.constructor.element&&console.warn("░█ [ELENA]: Element not found."),this.element=t.firstElementChild)}}_syncProps(){if(this._props){const t=this.constructor._noReflect;for(const[e,n]of this._props){if(t.has(e))continue;const r=s(typeof n,n,"toAttribute");(null!==r||this.hasAttribute(e))&&i(this,e,r)}}}_delegateEvents(){const t=this.constructor._elenaEvents;if(!this._events&&t?.length)if(this.element){this._events=!0;for(const e of t)this.element.addEventListener(e,this),this[e]=(...t)=>this.element[e](...t)}else console.warn("░█ [ELENA]: Cannot add events.")}render(){}willUpdate(){}firstUpdated(){}updated(){}adoptedCallback(){super.adoptedCallback?.()}disconnectedCallback(){if(super.disconnectedCallback?.(),this._events){this._events=!1;for(const t of this.constructor._elenaEvents)this.element?.removeEventListener(t,this)}}handleEvent(t){this.constructor._elenaEvents?.includes(t.type)&&(t.stopPropagation(),this.dispatchEvent(new o(t.type,{cancelable:!0})))}get text(){return this._text??""}set text(t){const e=this._text;this._text=t,this._hydrated&&e!==t&&!this._isRendering&&this._safeRender()}static define(){this.tagName?n(this.tagName,this):console.warn("░█ [ELENA]: define() without a tagName.")}_safeRender(){this._isRendering||this._renderPending||(this._renderPending=!0,this._updateComplete=new Promise(t=>{this._resolveUpdate=t}),queueMicrotask(()=>{try{this._performUpdate()}catch(t){console.error("░█ [ELENA]:",t)}}))}_performUpdate(){this._renderPending=!1;const t=this._resolveUpdate;this._resolveUpdate=null;try{try{this.willUpdate(),this._isRendering=!0,this._applyRender()}finally{this._isRendering=!1}this.updated()}finally{this._updateComplete=null,t()}}get updateComplete(){return this._updateComplete?this._updateComplete:Promise.resolve()}requestUpdate(){this._hydrated&&!this._isRendering&&this._safeRender()}}}export{a as Elena,o as ElenaEvent};
2
- //# sourceMappingURL=elena.js.map
1
+ /**
2
+ * @elenajs/core v1.0.0-rc.11
3
+ * (c) 2025-present Ariel Salminen and Elena contributors
4
+ * @license MIT
5
+ */
6
+ import{getPropValue as t,getProps as e,setProps as s,syncAttribute as i}from"./props.js";import{prefix as n,warn as r,defineElement as o}from"./utils.js";export{html,nothing,unsafeHTML}from"./utils.js";import{renderTemplate as h}from"./render.js";const a=new WeakSet,d=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);function l(l){return class extends l{element=null;attributeChangedCallback(s,i,n){if(super.attributeChangedCallback?.(s,i,n),"text"!==s){if(i!==n)if(this._hydrated&&!this._isRendering){const e=this._props.get(s),i=typeof e,r="string"===i?n??"":t(i,n,"toProp");r!==e&&this._props.set(s,r),this._safeRender()}else this._syncing=!0,e(this,s,i,n),this._syncing=!1}else this.text=n??""}static get observedAttributes(){if(this._observedAttrs)return this._observedAttrs;const t=(this.props||[]).map(t=>"string"==typeof t?t:t.name);return this._observedAttrs=[...t,"text"],this._observedAttrs}connectedCallback(){super.connectedCallback?.(),this._setupStaticProps(),this._captureClassFieldDefaults(),this._hydrated||void 0!==this._text||(this.text=this.textContent.trim()),this._attachShadow(),this._root=this._shadow??this.shadowRoot??this,this._runUpdate??=()=>{try{this._performUpdate()}catch(t){console.error(n,t)}},this.willUpdate(),this._applyRender(),this._syncProps(),this._delegateEvents(),this._hydrated||(this._hydrated=!0,this.setAttribute("hydrated",""),this.firstUpdated()),this.updated()}_setupStaticProps(){const t=this.constructor;if(a.has(t))return;const e=new Set,i=[];if(t.props){for(const s of t.props)"string"==typeof s?i.push(s):(i.push(s.name),!1===s.reflect&&e.add(s.name));i.includes("text")&&r('"text" is reserved.'),s(t.prototype,i,e)}if(t._propNames=i,t._noReflect=e,t._elenaEvents=t.events||null,t._elenaEvents)for(const e of t._elenaEvents)d(t.prototype,e)||(t.prototype[e]=function(...t){return this.element[e](...t)});var n;t._resolver=(n=t.element)?t=>t.querySelector(n):t=>t.firstElementChild,a.add(t)}_captureClassFieldDefaults(){this._syncing=!0;for(const t of this.constructor._propNames)if(d(this,t)){const e=this[t];delete this[t],this[t]=e}this._syncing=!1}_attachShadow(){const t=this.constructor;if(!t.shadow)return;this._shadow||this.shadowRoot||(this._shadow=this.attachShadow({mode:t.shadow}));const e=this._shadow??this.shadowRoot;if(t.styles){if(!t._adoptedSheets){const e=[t.styles].flat();t._adoptedSheets=e.map(t=>{if("string"==typeof t){const e=new CSSStyleSheet;return e.replaceSync(t),e}return t})}e.adoptedStyleSheets=t._adoptedSheets}}_applyRender(){const t=this.constructor,e=this._root,s=this.render();if(s&&s.strings&&h(e,s.strings,s.values)){const s=this.element;if(this.element=t._resolver(e),this._events&&s&&this.element!==s){const e=t._elenaEvents;for(const t of e)s.removeEventListener(t,this),this.element.addEventListener(t,this)}}this.element||(this.element=t._resolver(e),this.element||(t.element&&r("Element not found."),this.element=e.firstElementChild))}_syncProps(){if(this._props){const e=this.constructor._noReflect;for(const[s,n]of this._props){if(e.has(s))continue;const r=t(typeof n,n,"toAttribute");(null!==r||this.hasAttribute(s))&&i(this,s,r)}}}_delegateEvents(){const t=this.constructor._elenaEvents;if(!this._events&&t?.length)if(this.element){this._events=!0;for(const e of t)this.element.addEventListener(e,this)}else r("Cannot add events.")}render(){}willUpdate(){}firstUpdated(){}updated(){}adoptedCallback(){super.adoptedCallback?.()}disconnectedCallback(){if(super.disconnectedCallback?.(),this._events){this._events=!1;for(const t of this.constructor._elenaEvents)this.element?.removeEventListener(t,this)}}handleEvent(t){this.constructor._elenaEvents?.includes(t.type)&&(t.bubbles&&(t.composed||this._root===this)||this.dispatchEvent(new Event(t.type,{bubbles:t.bubbles})))}get text(){return this._text??""}set text(t){const e=this._text;this._text=t,this._hydrated&&e!==t&&!this._isRendering&&this._safeRender()}static define(){const t=this.tagName;t?o(t,this):r("define() without a tagName.")}_safeRender(){this._isRendering||this._renderPending||(this._renderPending=!0,queueMicrotask(this._runUpdate))}_performUpdate(){this._renderPending=!1;const t=this._resolveUpdate;this._resolveUpdate=null;try{try{this.willUpdate(),this._isRendering=!0,this._applyRender()}finally{this._isRendering=!1}this.updated()}finally{this._updateComplete=null,t?.()}}get updateComplete(){return this._renderPending?(this._updateComplete||(this._updateComplete=new Promise(t=>{this._resolveUpdate=t})),this._updateComplete):Promise.resolve()}requestUpdate(){this._hydrated&&!this._isRendering&&this._safeRender()}}}export{l as Elena};
package/dist/props.js CHANGED
@@ -1,2 +1 @@
1
- function t(t,e,n){if(e="boolean"===t&&"boolean"!=typeof e?null!==e:e,!n)return e;if("toAttribute"===n)switch(t){case"object":case"array":return null===e?null:JSON.stringify(e);case"boolean":return e?"":null;case"number":return null===e?null:e;default:return""===e?null:e}else switch(t){case"object":case"array":if(!e)return e;try{return JSON.parse(e)}catch{return console.warn("░█ [ELENA]: Invalid JSON: "+e),null}case"boolean":return e;case"number":return null!==e?+e:e;default:return e??""}}function e(t,e,n){t?null===n?t.removeAttribute(e):t.setAttribute(e,n):console.warn("░█ [ELENA]: Cannot sync attrs.")}function n(n,r,s){for(const o of r){const r=!s||!s.has(o);Object.defineProperty(n,o,{configurable:!0,enumerable:!0,get(){return this._props?this._props.get(o):void 0},set(n){if(this._props||(this._props=new Map),n!==this._props.get(o)&&(this._props.set(o,n),this.isConnected))if(r){if(!this._syncing){const r=t(typeof n,n,"toAttribute");e(this,o,r)}}else this._hydrated&&!this._isRendering&&this._safeRender()}})}}function r(e,n,r,s){if(r!==s){const r=typeof e[n];"undefined"===r&&console.warn(`░█ [ELENA]: Prop "${n}" has no default.`);const o=t(r,s,"toProp");e[n]=o}}export{t as getPropValue,r as getProps,n as setProps,e as syncAttribute};
2
- //# sourceMappingURL=props.js.map
1
+ import{warn as t}from"./utils.js";function e(e,n,r){if(n="boolean"===e&&"boolean"!=typeof n?null!==n:n,!r)return n;if("toAttribute"===r)switch(e){case"object":case"array":return n&&JSON.stringify(n);case"boolean":return n?"":null;default:return""===n?null:n}else switch(e){case"object":case"array":if(!n)return n;try{return JSON.parse(n)}catch{return t("Invalid JSON: "+n),null}case"number":return null!==n?+n:n;default:return n??""}}function n(e,n,r){e?null===r?e.removeAttribute(n):e.setAttribute(n,r):t("Cannot sync attrs.")}function r(t,r,s){for(const o of r){const r=!s||!s.has(o);Object.defineProperty(t,o,{configurable:!0,enumerable:!0,get(){return this._props?.get(o)},set(t){if(this._props||(this._props=new Map),t!==this._props.get(o)&&(this._props.set(o,t),this.isConnected))if(r){if(!this._syncing){const r=e(typeof t,t,"toAttribute");n(this,o,r)}}else this._hydrated&&!this._isRendering&&this._safeRender()}})}}function s(n,r,s,o){if(s!==o){const s=typeof n[r];"undefined"===s&&t(`Prop "${r}" has no default.`);const i=e(s,o,"toProp");n[r]=i}}export{e as getPropValue,s as getProps,r as setProps,n as syncAttribute};
package/dist/render.js CHANGED
@@ -1,2 +1 @@
1
- import{toPlainText as e,isRaw as t,collapseWhitespace as n,resolveValue as r}from"./utils.js";const o=new WeakMap,l="e"+Math.random().toString(36).slice(2,6);function a(a,i,d){return!function(n,r,o){if(n._tplStrings!==r||!n._tplParts)return!1;for(let r=0;r<o.length;r++){const l=o[r],a=Array.isArray(l)?e(l):l;if(a!==n._tplValues[r]){if(t(l)||!n._tplParts[r])return!1;n._tplValues[r]=a,n._tplParts[r].textContent=e(l)}}return!0}(a,i,d)&&(function(a,i,d){let p=o.get(i);if(!p){const e=Array.from(i,n);p={processedStrings:e,template:d.length>0?c(e,d.length):null},o.set(i,p)}if(p.template)a._tplParts=function(n,o,a){const c=o.content.cloneNode(!0),s=document.createTreeWalker(c,NodeFilter.SHOW_COMMENT),i=new Array(a.length),d=[];let p;for(;p=s.nextNode();)p.data===l&&d.push(p);for(let n=0;n<d.length;n++){const o=a[n];if(t(o)){const e=document.createElement("template");e.innerHTML=r(o),d[n].parentNode.replaceChild(e.content,d[n])}else{const t=document.createTextNode(e(o));d[n].parentNode.replaceChild(t,d[n]),i[n]=t}}return n.replaceChildren(c),i}(a,p.template,d);else{const e=d.map(e=>r(e)),t=p.processedStrings.reduce((t,n,r)=>t+n+(e[r]??""),"").replace(/>\s+</g,"><").trim(),n=document.createElement("template");n.innerHTML=t,s(a,n.content.childNodes),a._tplParts=new Array(d.length)}a._tplStrings=i,a._tplValues=d.map(t=>Array.isArray(t)?e(t):t)}(a,i,d),!0)}function c(e,t){const n=`\x3c!--${l}--\x3e`,r=e.reduce((e,r,o)=>e+r.replace(/>\s+</g,"><")+(o<t?n:""),"").trim(),o=document.createElement("template");o.innerHTML=r;const a=document.createTreeWalker(o.content,NodeFilter.SHOW_COMMENT);let c=0;for(;a.nextNode();)a.currentNode.data===l&&c++;return c===t?o:null}function s(e,t){const n=Array.from(e.childNodes),r=Array.from(t),o=Math.max(n.length,r.length);for(let t=0;t<o;t++){const o=n[t],l=r[t];o?l?o.nodeType!==l.nodeType||o.nodeType===Node.ELEMENT_NODE&&o.tagName!==l.tagName?e.replaceChild(l,o):o.nodeType===Node.TEXT_NODE?o.textContent!==l.textContent&&(o.textContent=l.textContent):o.nodeType===Node.ELEMENT_NODE&&(i(o,l),s(o,l.childNodes)):e.removeChild(o):e.appendChild(l)}}function i(e,t){for(let n=e.attributes.length-1;n>=0;n--){const{name:r}=e.attributes[n];t.hasAttribute(r)||e.removeAttribute(r)}for(let n=0;n<t.attributes.length;n++){const{name:r,value:o}=t.attributes[n];e.getAttribute(r)!==o&&e.setAttribute(r,o)}}export{a as renderTemplate};
2
- //# sourceMappingURL=render.js.map
1
+ import{isArray as t,toPlainText as e,isRaw as n,nothing as r,collapseWhitespace as o,resolveValue as l}from"./utils.js";const s=new WeakMap,a="e"+Math.random().toString(36).slice(2),c=()=>document.createElement("template"),i=t=>document.createTreeWalker(t,128);function u(u,m,f){return!function(o,l,s){if(o._templateStrings!==l||!o._templateParts)return!1;const a=o._templateParts,c=o._templateValues;for(let o=0;o<s.length;o++){const l=s[o],i=t(l)?e(l):l;if(i===c[o])continue;if(n(l)&&l!==r)return!1;const u=a[o];if(!u)return!1;c[o]=i;const p=String(i??"");u.nodeType?u.textContent=p:u[0].setAttribute(u[1],p)}return!0}(u,m,f)&&(function(u,m,f){let h=s.get(m);if(!h){const t=m.map(o);h={_strings:t,_template:f.length>0?p(t,f.length):null},s.set(m,h)}if(h._template)u._templateParts=function(o,s,u){const{_tpl:p,_attrs:m}=s,f=p.content.cloneNode(!0),h=i(f),g=Array(u.length),_=[];let N;for(;N=h.nextNode();)N.data===a&&_.push(N);let x=0;for(let o=0;o<u.length;o++){const s=m[o];if(s){const n=f.querySelector(`[${s}="${a+"_"+o}"]`);if(n){const r=u[o],l=String((t(r)?e(r):r)??"");n.setAttribute(s,l),g[o]=[n,s]}}else{const t=_[x++],s=u[o];if(n(s)&&s!==r){const e=c();e.innerHTML=l(s),t.parentNode.replaceChild(e.content,t)}else{const n=document.createTextNode(e(s));t.parentNode.replaceChild(n,t),g[o]=n}}}return o._templateStrings?(d(o,f.childNodes),null):(o.replaceChildren(f),g)}(u,h._template,f);else{const t=f.map(l),e=h._strings.reduce((e,n,r)=>e+n+(t[r]??""),"").replace(/>\s+</g,"><").trim(),n=c();n.innerHTML=e,d(u,n.content.childNodes),u._templateParts=null}u._templateStrings=m,u._templateValues=f.map(n=>t(n)?e(n):n)}(u,m,f),!0)}function p(t,e){const n=`\x3c!--${a}--\x3e`,r=[];let o="";for(let l=0;l<t.length;l++)if(o+=t[l],l<e){const e=t[l].match(/([^\s"'>/=]+)\s*=\s*["']$/);e?(r.push(e[1]),o+=a+"_"+l):(r.push(null),o+=n)}const l=c();l.innerHTML=o.trim();const s=i(l.content);let u=0;for(;s.nextNode();)s.currentNode.data===a&&u++;return u!==r.filter(t=>null===t).length?null:{_tpl:l,_attrs:r}}function d(t,e){const n=Array.from(t.childNodes),r=Array.from(e),o=Math.max(n.length,r.length);for(let e=0;e<o;e++){const o=n[e],l=r[e];o?l?o.nodeType!==l.nodeType||1===o.nodeType&&o.tagName!==l.tagName?t.replaceChild(l,o):3===o.nodeType?o.textContent!==l.textContent&&(o.textContent=l.textContent):1===o.nodeType&&(m(o,l),d(o,l.childNodes)):t.removeChild(o):t.appendChild(l)}}function m(t,e){for(let n=t.attributes.length-1;n>=0;n--){const{name:r}=t.attributes[n];e.hasAttribute(r)||t.removeAttribute(r)}for(let n=0;n<e.attributes.length;n++){const{name:r,value:o}=e.attributes[n];t.getAttribute(r)!==o&&t.setAttribute(r,o)}}export{u as renderTemplate};
package/dist/utils.js CHANGED
@@ -1,2 +1 @@
1
- function n(n,r){"undefined"!=typeof window&&"customElements"in window&&(window.customElements.get(n)||window.customElements.define(n,r))}const r={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};function t(n){return String(n).replace(/[&<>"']/g,n=>r[n])}function e(n){return Array.isArray(n)?n.map(n=>i(n)).join(""):i(n)}function i(n){return n?.__raw?String(n):t(String(n??""))}function o(n,...r){let t;return{__raw:!0,strings:n,values:r,toString:()=>(void 0===t&&(t=n.reduce((n,t,i)=>n+t+e(r[i]),"")),t)}}function a(n){return{__raw:!0,toString:()=>n??""}}const u=Object.freeze({__raw:!0,toString:()=>""}),c=n=>Array.isArray(n)?n.some(n=>n?.__raw):n?.__raw,s=n=>Array.isArray(n)?n.map(n=>String(n??"")).join(""):String(n??"");function g(n){return n.replace(/>\n\s*/g,">").replace(/\n\s*</g,"<").replace(/\n\s*/g," ")}export{g as collapseWhitespace,n as defineElement,t as escapeHtml,o as html,c as isRaw,u as nothing,e as resolveValue,s as toPlainText,a as unsafeHTML};
2
- //# sourceMappingURL=utils.js.map
1
+ const t="░█ [ELENA]: ",n=Array.isArray,r=Symbol("elena.raw"),s=n=>console.warn(t+n);function e(t,n){const r=globalThis.customElements;r?.get(t)||r?.define(t,n)}const o={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};function i(t){return String(t).replace(/[&<>"']/g,t=>o[t])}function c(t){return n(t)?t.map(u).join(""):u(t)}function u(t){return t?.[r]?String(t):i(t??"")}class l{constructor(t,n){this.strings=t,this.values=n}toString(){return null==this._str&&(this._str=this.strings.reduce((t,n,r)=>t+n+c(this.values[r]),"")),this._str}}function a(t,...n){return new l(t,n)}function g(t){return{[r]:!0,toString:()=>t??""}}l.prototype[r]=!0;const p={[r]:!0,toString:()=>""},f=t=>n(t)?t.some(t=>t?.[r]):t?.[r],h=t=>n(t)?t.join(""):String(t??"");function S(t){return t.replace(/(>)\n\s*|\n\s*(<)/g,"$1$2").replace(/\n\s*/g," ").replace(/>\s+</g,"><")}export{S as collapseWhitespace,e as defineElement,i as escapeHtml,a as html,n as isArray,f as isRaw,p as nothing,t as prefix,c as resolveValue,h as toPlainText,g as unsafeHTML,s as warn};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elenajs/core",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.11",
4
4
  "description": "Elena is a simple, tiny library for building Progressive Web Components.",
5
5
  "author": "Elena <hi@elenajs.com>",
6
6
  "homepage": "https://elenajs.com/",
@@ -16,6 +16,7 @@
16
16
  "publishConfig": {
17
17
  "access": "public"
18
18
  },
19
+ "source": "./src/elena.js",
19
20
  "main": "./dist/elena.js",
20
21
  "types": "./dist/elena.d.ts",
21
22
  "type": "module",
@@ -27,7 +28,8 @@
27
28
  "./bundle": "./dist/bundle.js"
28
29
  },
29
30
  "files": [
30
- "dist"
31
+ "dist",
32
+ "src"
31
33
  ],
32
34
  "scripts": {
33
35
  "prebuild": "npm run -s clean",
@@ -41,18 +43,18 @@
41
43
  "clean": "rm -rf dist/"
42
44
  },
43
45
  "devDependencies": {
44
- "@playwright/test": "^1.58.2",
45
- "@rollup/plugin-terser": "0.4.4",
46
- "@vitest/browser": "4.0.18",
47
- "@vitest/browser-playwright": "4.0.18",
48
- "@vitest/coverage-v8": "4.0.18",
49
- "happy-dom": "20.8.3",
50
- "lit": "^3.3.0",
51
- "rollup": "4.59.0",
46
+ "@playwright/test": "1.58.2",
47
+ "@rollup/plugin-terser": "1.0.0",
48
+ "@vitest/browser": "4.1.1",
49
+ "@vitest/browser-playwright": "4.1.1",
50
+ "@vitest/coverage-v8": "4.1.1",
51
+ "happy-dom": "20.8.9",
52
+ "lit": "3.3.2",
53
+ "rollup": "4.60.0",
52
54
  "rollup-plugin-summary": "3.0.1",
53
- "serve": "^14.2.6",
54
- "typescript": "5.9.3",
55
- "vitest": "4.0.18"
55
+ "serve": "14.2.6",
56
+ "typescript": "6.0.2",
57
+ "vitest": "4.1.1"
56
58
  },
57
- "gitHead": "66d1e66dd467c20d7c5c70ffcb5678c6a2694690"
59
+ "gitHead": "7797f7103a74ea241f192e407a08122c11405a94"
58
60
  }
@@ -0,0 +1,131 @@
1
+ import { warn } from "./utils.js";
2
+
3
+ /**
4
+ * Get the value of the Elena Element property.
5
+ *
6
+ * @param {string} type
7
+ * @param {any} value
8
+ * @param {"toAttribute" | "toProp"} [transform]
9
+ */
10
+ export function getPropValue(type, value, transform) {
11
+ value = type === "boolean" && typeof value !== "boolean" ? value !== null : value;
12
+
13
+ if (!transform) {
14
+ return value;
15
+ } else if (transform === "toAttribute") {
16
+ switch (type) {
17
+ case "object":
18
+ case "array":
19
+ return value && JSON.stringify(value);
20
+ case "boolean":
21
+ return value ? "" : null;
22
+ // number, string:
23
+ default:
24
+ return value === "" ? null : value;
25
+ }
26
+ } else {
27
+ switch (type) {
28
+ case "object":
29
+ case "array":
30
+ if (!value) {
31
+ return value;
32
+ }
33
+ try {
34
+ return JSON.parse(value);
35
+ } catch {
36
+ warn("Invalid JSON: " + value);
37
+ return null;
38
+ }
39
+ case "number":
40
+ return value !== null ? +value : value;
41
+ default:
42
+ return value ?? "";
43
+ }
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Set or remove an attribute on an Elena Element.
49
+ *
50
+ * @param {Element} element - Target element
51
+ * @param {string} name - Attribute name
52
+ * @param {string | null} value - Attribute value, or null to remove
53
+ */
54
+ export function syncAttribute(element, name, value) {
55
+ if (!element) {
56
+ warn("Cannot sync attrs.");
57
+ return;
58
+ }
59
+ if (value === null) {
60
+ element.removeAttribute(name);
61
+ } else {
62
+ element.setAttribute(name, value);
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Define prop getters/setters on the prototype once
68
+ * at class-creation time. Values are stored per-instance
69
+ * via a `_props` Map that is lazily created.
70
+ *
71
+ * @param {Function} proto - The class prototype
72
+ * @param {string[]} propNames - Prop names to define
73
+ * @param {Set<string>} [noReflect] - Props that should not reflect to attributes
74
+ */
75
+ export function setProps(proto, propNames, noReflect) {
76
+ for (const prop of propNames) {
77
+ const reflects = !noReflect || !noReflect.has(prop);
78
+ Object.defineProperty(proto, prop, {
79
+ configurable: true,
80
+ enumerable: true,
81
+ get() {
82
+ return this._props?.get(prop);
83
+ },
84
+ set(value) {
85
+ if (!this._props) {
86
+ this._props = new Map();
87
+ }
88
+ if (value === this._props.get(prop)) {
89
+ return;
90
+ }
91
+
92
+ this._props.set(prop, value);
93
+ if (!this.isConnected) {
94
+ return;
95
+ }
96
+
97
+ if (reflects) {
98
+ // Skip reflection when called from attributeChangedCallback. The
99
+ // attribute is already at the new value, setting it again is redundant
100
+ // and would fire an extra attributeChangedCallback with identical values.
101
+ if (!this._syncing) {
102
+ const attrValue = getPropValue(typeof value, value, "toAttribute");
103
+ syncAttribute(this, prop, attrValue);
104
+ }
105
+ } else if (this._hydrated && !this._isRendering) {
106
+ this._safeRender();
107
+ }
108
+ },
109
+ });
110
+ }
111
+ }
112
+
113
+ /**
114
+ * We need to update the internals of the Elena Element
115
+ * when props on the host element are changed.
116
+ *
117
+ * @param {object} context
118
+ * @param {string} name
119
+ * @param {any} oldValue
120
+ * @param {any} newValue
121
+ */
122
+ export function getProps(context, name, oldValue, newValue) {
123
+ if (oldValue !== newValue) {
124
+ const type = typeof context[name];
125
+ if (type === "undefined") {
126
+ warn(`Prop "${name}" has no default.`);
127
+ }
128
+ const newAttr = getPropValue(type, newValue, "toProp");
129
+ context[name] = newAttr;
130
+ }
131
+ }