From 5c52d6dd9794bd7ad7fa66eab22430e9ada0b694 Mon Sep 17 00:00:00 2001 From: webreflection Date: Fri, 5 Jan 2024 15:32:20 +0100 Subject: [PATCH] Added a very interesting TODO in the rabbit "hole" --- esm/literals.js | 2 +- esm/rabbit.js | 24 +++++++++++++++++------- signal.js | 6 +++--- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/esm/literals.js b/esm/literals.js index 4369412..b5db02d 100644 --- a/esm/literals.js +++ b/esm/literals.js @@ -74,7 +74,7 @@ export const entry = (t, p, u, n = '') => ({ t, p, u, n }); * @param {Cache[]} s the cache stack * @returns {Cache} */ -export const cache = s => ({ s, t: null, n: null, d: empty}); +export const cache = s => ({ s, a: false, t: null, n: null, d: empty}); /** * @typedef {Object} Parsed diff --git a/esm/rabbit.js b/esm/rabbit.js index 555e19e..f583d7f 100644 --- a/esm/rabbit.js +++ b/esm/rabbit.js @@ -6,23 +6,34 @@ import parser from './parser.js'; const parseHTML = create(parser(false)); const parseSVG = create(parser(true)); +// TODO: check twice for isArray or check attributes +// makes literally no sense and it's performance +// critical. The template details know all of this +// so there's gonna be a way to drill those details +// down this loop, avoiding any unnecessary check. + /** * @param {import("./literals.js").Cache} cache * @param {Hole} hole * @returns {Node} */ export const unroll = (cache, { s: svg, t: template, v: values }) => { - if (values.length && cache.s === empty) cache.s = []; - const length = unrollValues(cache, values); + if (cache.s === empty && values.length) cache.s = []; if (cache.t !== template) { + // this is necessary only on first time ... after that there are details + unrollValues(cache, values); const { n: node, d: details } = (svg ? parseSVG : parseHTML)(template, values); cache.t = template; cache.n = node; cache.d = details; } else { + // this makes no sense here ... it could be just one loop + unrollValues(cache, values); const { d: details } = cache; - for (let i = 0; i < length; i++) { + // this loop could resolve values[i] in a go + // making the need to loop more than once unnecessary + for (let i = 0; i < values.length; i++) { const value = values[i]; const detail = details[i]; const { v: previous } = detail; @@ -41,8 +52,7 @@ export const unroll = (cache, { s: svg, t: template, v: values }) => { * @returns {number} */ const unrollValues = ({ s: stack }, values) => { - const { length } = values; - for (let i = 0; i < length; i++) { + for (let i = 0; i < values.length; i++) { const hole = values[i]; if (hole instanceof Hole) values[i] = unroll(stack[i] || (stack[i] = cache(empty)), hole); @@ -51,8 +61,8 @@ const unrollValues = ({ s: stack }, values) => { else stack[i] = null; } - if (length < stack.length) stack.splice(length); - return length; + if (values.length < stack.length) + stack.splice(values.length); }; /** diff --git a/signal.js b/signal.js index aa1fd46..8c6c942 100644 --- a/signal.js +++ b/signal.js @@ -1,4 +1,4 @@ /*! (c) Andrea Giammarchi */ -let e=null;const t=t=>{let n=e;n||(e=new Set);try{t()}finally{if(!n){[e,n]=[null,e];for(const e of n)e._()}}},n=e=>{const t=[...e];return e.clear(),t};class r extends Set{constructor(e){super()._=e}dispose(){for(const e of n(this))e.delete(this),e.dispose?.()}}let s=null;const o=e=>{const t=new r((()=>{const n=s;s=t;try{e()}finally{s=n}}));return t},l=(e,t)=>{const n=o((()=>{t=e(t)}));return s&&s.add(n),n._(),()=>n.dispose()};class i extends Set{constructor(e){super()._=e}get value(){return s&&s.add(this.add(s)),this._}set value(t){if(this._!==t){this._=t;const r=!e;for(const t of n(this))r?t._():e.add(t)}}peek(){return this._}toJSON(){return this.value}valueOf(){return this.value}toString(){return String(this.value)}}const c=e=>new i(e);class a extends i{constructor(e,t){super(t).f=e,this.e=null}get value(){return this.e||(this.e=o((()=>{super.value=this.f(this._)})))._(),super.value}set value(e){throw new Error("computed is read-only")}}const u=(e,t)=>new a(e,t),{isArray:h}=Array,{getPrototypeOf:d,getOwnPropertyDescriptor:f}=Object,p=[],g=()=>document.createRange(),v=(e,t,n)=>(e.set(t,n),n),m=(e,t,n,r="")=>({t:e,p:t,u:n,n:r}),w=e=>({s:e,t:null,n:null,d:p}),{setPrototypeOf:y}=Object;let x;const b=({firstChild:e,lastChild:t},n)=>((e,t,n)=>(x||(x=g()),n?x.setStartAfter(e):x.setStartBefore(e),x.setEndAfter(t),x.deleteContents(),e))(e,t,n);let $=!1;const N=(e,t)=>$&&11===e.nodeType?1/t<0?t?b(e,!0):e.lastChild:t?e.valueOf():e.firstChild:e;class C extends((e=>{function t(e){return y(e,new.target.prototype)}return t.prototype=e.prototype,t})(DocumentFragment)){#e;#t;constructor(e){const t=[...e.childNodes];super(e),this.#e=t,this.#t=t.length,$=!0}get firstChild(){return this.#e[0]}get lastChild(){return this.#e.at(-1)}get parentNode(){return this.#e[0].parentNode}remove(){b(this,!1)}replaceWith(e){b(this,!0).replaceWith(e)}valueOf(){return this.childNodes.length!==this.#t&&this.replaceChildren(...this.#e),this}}const S=(e,t)=>t.reduceRight(k,e),k=(e,t)=>e.childNodes[t];var W=e=>(t,n)=>{const{c:r,e:s,l:o}=e(t,n),l=r.cloneNode(!0);let i,c,a=s.length,u=a?s.slice(0):p;for(;a--;){const{t:e,p:t,u:r,n:o}=s[a],h=t===c?i:i=S(l,c=t),d=8===e?r():r;u[a]={v:d(h,n[a],o,p),u:d,t:h,n:o}}return((e,t)=>({n:e,d:t}))(1===o?l.firstChild||i:new C(l),u)};const O=/^(?:plaintext|script|style|textarea|title|xmp)$/i,_=/^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i,A=/<([a-zA-Z0-9]+[a-zA-Z0-9:._-]*)([^>]*?)(\/?)>/g,M=/([^\s\\>"'=]+)\s*=\s*(['"]?)\x01/g,E=/[\x01\x02]/g;const T=(e,t,n)=>e.setAttribute(t,n),j=(e,t)=>e.removeAttribute(t),B=()=>V;let P;const R=(e,t,n)=>{n=n.slice(1),P||(P=new WeakMap);const r=P.get(e)||v(P,e,{});let s=r[n];return s&&s[0]&&e.removeEventListener(n,...s),s=h(t)?t:[t,!1],r[n]=s,s[0]&&e.addEventListener(n,...s),t};function z(e,t){const n=this.n||(this.n=e);switch(typeof t){case"string":case"number":case"boolean":n!==e&&n.replaceWith(this.n=e),this.n.data=t;break;case"object":case"undefined":null==t?(this.n=e).data="":this.n=t.valueOf(),n.replaceWith(this.n)}return t}const F=()=>z.bind({n:null}),L=(e,t,n)=>e[n]=t,D=(e,t,n)=>L(e,t,n.slice(1)),H=(e,t,n)=>null==t?(j(e,n),t):L(e,t,n),Z=(e,t)=>("function"==typeof t?t(e):t.current=e,t),G=(e,t,n)=>(null==t?j(e,n):T(e,n,t),t),J=(e,t,n)=>(e.toggleAttribute(n.slice(1),t),t),V=(e,t,n,r)=>((e,t,n,r,s)=>{const o=n.length;let l=t.length,i=o,c=0,a=0,u=null;for(;cs-a){const o=r(t[c],0);for(;a{for(const n in t){const r=t[n],s="role"===n?n:`aria-${n}`;null==r?j(e,s):T(e,s,r)}return t}],["class",(e,t)=>H(e,t,null==t?"class":"className")],["data",(e,t)=>{const{dataset:n}=e;for(const e in t)null==t[e]?delete n[e]:n[e]=t[e];return t}],["ref",Z],["style",(e,t)=>null==t?H(e,t,"style"):L(e.style,t,"cssText")]]),I=(e,t,n)=>{switch(t[0]){case".":return D;case"?":return J;case"@":return R;default:return n||"ownerSVGElement"in e?"ref"===t?Z:G:q.get(t)||(t in e?t.startsWith("on")?L:((e,t)=>{let n;do{n=f(e,t)}while(!n&&(e=d(e)));return n})(e,t)?.set?H:G:G)}},K=(e,t)=>(e.textContent=null==t?"":t,t);let Q,U,X=document.createElement("template");var Y=(e,t)=>{if(t)return Q||(Q=document.createElementNS("http://www.w3.org/2000/svg","svg"),U=g(),U.selectNodeContents(Q)),U.createContextualFragment(e);X.innerHTML=e;const{content:n}=X;return X=X.cloneNode(!1),n};const ee=e=>{const t=[];let n;for(;n=e.parentNode;)t.push(t.indexOf.call(n.childNodes,e)),e=n;return t},te=(e,t,n)=>{const r=Y(((e,t,n)=>{let r=0;return e.join("").trim().replace(A,((e,t,r,s)=>`<${t}${r.replace(M,"=$2$1").trimEnd()}${s?n||_.test(t)?" /":`>`)).replace(E,(e=>""===e?`\x3c!--${t+r++}--\x3e`:t+r++))})(e,re,n),n),{length:s}=e;let o=!1,l=p;if(s>1){const e=document.createTreeWalker(r,129),i=[];let c=0,a=`${re}${c++}`;for(l=[];c({c:e,e:t,l:n}))(r,l,1===i&&o?0:i))},ne=new WeakMap,re="isµ";var se=e=>(t,n)=>ne.get(t)||te(t,n,e);const oe=W(se(!1)),le=W(se(!0)),ie=(e,{s:t,t:n,v:r})=>{r.length&&e.s===p&&(e.s=[]);const s=ce(e,r);if(e.t!==n){const{n:s,d:o}=(t?le:oe)(n,r);e.t=n,e.n=s,e.d=o}else{const{d:t}=e;for(let e=0;e{const{length:n}=t;for(let r=0;r(t,...n)=>new ae(e,t,n),he=ue(!1),de=ue(!0),fe=new WeakMap;var pe=(e,t,n)=>{const r=fe.get(e)||v(fe,e,w(p)),s=n&&"function"==typeof t?t():t,{n:o}=r,l=s instanceof ae?ie(r,s):s;return o!==l&&e.replaceChildren(r.n=l),e}; -/*! (c) Andrea Giammarchi - MIT */const ge=new WeakMap,ve=e=>(t,n)=>{const r=ge.get(t)||v(ge,t,new Map);return r.get(n)||v(r,n,function(t,...n){return ie(this,new ae(e,t,n))}.bind(w(p)))},me=ve(!1),we=ve(!0),ye=new FinalizationRegistry((([e,t,n])=>{n&&console.debug(`Held value ${String(t)} not relevant anymore`),e(t)})),xe=Object.create(null),be=new WeakMap,$e=e=>e();const Ne=(e=>(t,n)=>{let r=be.get(t);var s;if(r&&(s=r,ye.unregister(s),r()),"function"==typeof n){const s=new WeakRef(t);return r=e((()=>{pe(s.deref(),n(),!1)})),be.set(t,r),((e,t,{debug:n,return:r,token:s=e}=xe)=>{const o=r||new Proxy(e,xe),l=[o,[t,e,!!n]];return!1!==s&&l.push(s),ye.register(...l),o})(r,$e,{return:t})}return be.delete(t),pe(t,n,!1)})(l);export{a as Computed,ae as Hole,i as Signal,q as attr,t as batch,u as computed,l as effect,he as html,me as htmlFor,Ne as render,c as signal,de as svg,we as svgFor}; +let e=null;const t=t=>{let n=e;n||(e=new Set);try{t()}finally{if(!n){[e,n]=[null,e];for(const e of n)e._()}}},n=e=>{const t=[...e];return e.clear(),t};class r extends Set{constructor(e){super()._=e}dispose(){for(const e of n(this))e.delete(this),e.dispose?.()}}let s=null;const l=e=>{const t=new r((()=>{const n=s;s=t;try{e()}finally{s=n}}));return t},o=(e,t)=>{const n=l((()=>{t=e(t)}));return s&&s.add(n),n._(),()=>n.dispose()};class i extends Set{constructor(e){super()._=e}get value(){return s&&s.add(this.add(s)),this._}set value(t){if(this._!==t){this._=t;const r=!e;for(const t of n(this))r?t._():e.add(t)}}peek(){return this._}toJSON(){return this.value}valueOf(){return this.value}toString(){return String(this.value)}}const c=e=>new i(e);class a extends i{constructor(e,t){super(t).f=e,this.e=null}get value(){return this.e||(this.e=l((()=>{super.value=this.f(this._)})))._(),super.value}set value(e){throw new Error("computed is read-only")}}const u=(e,t)=>new a(e,t),{isArray:h}=Array,{getPrototypeOf:d,getOwnPropertyDescriptor:f}=Object,p=[],g=()=>document.createRange(),v=(e,t,n)=>(e.set(t,n),n),m=(e,t,n,r="")=>({t:e,p:t,u:n,n:r}),w=e=>({s:e,a:!1,t:null,n:null,d:p}),{setPrototypeOf:y}=Object;let x;const b=({firstChild:e,lastChild:t},n)=>((e,t,n)=>(x||(x=g()),n?x.setStartAfter(e):x.setStartBefore(e),x.setEndAfter(t),x.deleteContents(),e))(e,t,n);let $=!1;const N=(e,t)=>$&&11===e.nodeType?1/t<0?t?b(e,!0):e.lastChild:t?e.valueOf():e.firstChild:e;class C extends((e=>{function t(e){return y(e,new.target.prototype)}return t.prototype=e.prototype,t})(DocumentFragment)){#e;#t;constructor(e){const t=[...e.childNodes];super(e),this.#e=t,this.#t=t.length,$=!0}get firstChild(){return this.#e[0]}get lastChild(){return this.#e.at(-1)}get parentNode(){return this.#e[0].parentNode}remove(){b(this,!1)}replaceWith(e){b(this,!0).replaceWith(e)}valueOf(){return this.childNodes.length!==this.#t&&this.replaceChildren(...this.#e),this}}const S=(e,t)=>t.reduceRight(k,e),k=(e,t)=>e.childNodes[t];var W=e=>(t,n)=>{const{c:r,e:s,l:l}=e(t,n),o=r.cloneNode(!0);let i,c,a=s.length,u=a?s.slice(0):p;for(;a--;){const{t:e,p:t,u:r,n:l}=s[a],h=t===c?i:i=S(o,c=t),d=8===e?r():r;u[a]={v:d(h,n[a],l,p),u:d,t:h,n:l}}return((e,t)=>({n:e,d:t}))(1===l?o.firstChild||i:new C(o),u)};const O=/^(?:plaintext|script|style|textarea|title|xmp)$/i,_=/^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i,A=/<([a-zA-Z0-9]+[a-zA-Z0-9:._-]*)([^>]*?)(\/?)>/g,M=/([^\s\\>"'=]+)\s*=\s*(['"]?)\x01/g,E=/[\x01\x02]/g;const T=(e,t,n)=>e.setAttribute(t,n),j=(e,t)=>e.removeAttribute(t),B=()=>V;let P;const R=(e,t,n)=>{n=n.slice(1),P||(P=new WeakMap);const r=P.get(e)||v(P,e,{});let s=r[n];return s&&s[0]&&e.removeEventListener(n,...s),s=h(t)?t:[t,!1],r[n]=s,s[0]&&e.addEventListener(n,...s),t};function z(e,t){const n=this.n||(this.n=e);switch(typeof t){case"string":case"number":case"boolean":n!==e&&n.replaceWith(this.n=e),this.n.data=t;break;case"object":case"undefined":null==t?(this.n=e).data="":this.n=t.valueOf(),n.replaceWith(this.n)}return t}const F=()=>z.bind({n:null}),L=(e,t,n)=>e[n]=t,D=(e,t,n)=>L(e,t,n.slice(1)),H=(e,t,n)=>null==t?(j(e,n),t):L(e,t,n),Z=(e,t)=>("function"==typeof t?t(e):t.current=e,t),G=(e,t,n)=>(null==t?j(e,n):T(e,n,t),t),J=(e,t,n)=>(e.toggleAttribute(n.slice(1),t),t),V=(e,t,n,r)=>((e,t,n,r,s)=>{const l=n.length;let o=t.length,i=l,c=0,a=0,u=null;for(;cs-a){const l=r(t[c],0);for(;a{for(const n in t){const r=t[n],s="role"===n?n:`aria-${n}`;null==r?j(e,s):T(e,s,r)}return t}],["class",(e,t)=>H(e,t,null==t?"class":"className")],["data",(e,t)=>{const{dataset:n}=e;for(const e in t)null==t[e]?delete n[e]:n[e]=t[e];return t}],["ref",Z],["style",(e,t)=>null==t?H(e,t,"style"):L(e.style,t,"cssText")]]),I=(e,t,n)=>{switch(t[0]){case".":return D;case"?":return J;case"@":return R;default:return n||"ownerSVGElement"in e?"ref"===t?Z:G:q.get(t)||(t in e?t.startsWith("on")?L:((e,t)=>{let n;do{n=f(e,t)}while(!n&&(e=d(e)));return n})(e,t)?.set?H:G:G)}},K=(e,t)=>(e.textContent=null==t?"":t,t);let Q,U,X=document.createElement("template");var Y=(e,t)=>{if(t)return Q||(Q=document.createElementNS("http://www.w3.org/2000/svg","svg"),U=g(),U.selectNodeContents(Q)),U.createContextualFragment(e);X.innerHTML=e;const{content:n}=X;return X=X.cloneNode(!1),n};const ee=e=>{const t=[];let n;for(;n=e.parentNode;)t.push(t.indexOf.call(n.childNodes,e)),e=n;return t},te=(e,t,n)=>{const r=Y(((e,t,n)=>{let r=0;return e.join("").trim().replace(A,((e,t,r,s)=>`<${t}${r.replace(M,"=$2$1").trimEnd()}${s?n||_.test(t)?" /":`>`)).replace(E,(e=>""===e?`\x3c!--${t+r++}--\x3e`:t+r++))})(e,re,n),n),{length:s}=e;let l=!1,o=p;if(s>1){const e=document.createTreeWalker(r,129),i=[];let c=0,a=`${re}${c++}`;for(o=[];c({c:e,e:t,l:n}))(r,o,1===i&&l?0:i))},ne=new WeakMap,re="isµ";var se=e=>(t,n)=>ne.get(t)||te(t,n,e);const le=W(se(!1)),oe=W(se(!0)),ie=(e,{s:t,t:n,v:r})=>{if(e.s===p&&r.length&&(e.s=[]),e.t!==n){ce(e,r);const{n:s,d:l}=(t?oe:le)(n,r);e.t=n,e.n=s,e.d=l}else{ce(e,r);const{d:t}=e;for(let e=0;e{for(let n=0;n(t,...n)=>new ae(e,t,n),he=ue(!1),de=ue(!0),fe=new WeakMap;var pe=(e,t,n)=>{const r=fe.get(e)||v(fe,e,w(p)),s=n&&"function"==typeof t?t():t,{n:l}=r,o=s instanceof ae?ie(r,s):s;return l!==o&&e.replaceChildren(r.n=o),e}; +/*! (c) Andrea Giammarchi - MIT */const ge=new WeakMap,ve=e=>(t,n)=>{const r=ge.get(t)||v(ge,t,new Map);return r.get(n)||v(r,n,function(t,...n){return ie(this,new ae(e,t,n))}.bind(w(p)))},me=ve(!1),we=ve(!0),ye=new FinalizationRegistry((([e,t,n])=>{n&&console.debug(`Held value ${String(t)} not relevant anymore`),e(t)})),xe=Object.create(null),be=new WeakMap,$e=e=>e();const Ne=(e=>(t,n)=>{let r=be.get(t);var s;if(r&&(s=r,ye.unregister(s),r()),"function"==typeof n){const s=new WeakRef(t);return r=e((()=>{pe(s.deref(),n(),!1)})),be.set(t,r),((e,t,{debug:n,return:r,token:s=e}=xe)=>{const l=r||new Proxy(e,xe),o=[l,[t,e,!!n]];return!1!==s&&o.push(s),ye.register(...o),l})(r,$e,{return:t})}return be.delete(t),pe(t,n,!1)})(o);export{a as Computed,ae as Hole,i as Signal,q as attr,t as batch,u as computed,o as effect,he as html,me as htmlFor,Ne as render,c as signal,de as svg,we as svgFor};