sprae 9.0.1 → 9.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/sprae.min.js CHANGED
@@ -1 +1 @@
1
- var e=Object.defineProperty,t=(e,r,a,l=null)=>{let s,n,o,i=0,c=a.length,u=r.length,{remove:p,same:f,insert:d,replace:v}=t;for(;i<c&&i<u&&f(r[i],a[i]);)i++;for(;i<c&&i<u&&f(a[c-1],r[u-1]);)l=a[(--u,--c)];if(i==u)for(;i<c;)d(l,a[i++],e);else{for(s=r[i];i<c;)o=a[i++],n=s?s.nextSibling:l,f(s,o)?s=n:i<c&&f(a[i],n)?(v(s,o,e),s=n):d(s,o,e);for(;!f(s,l);)n=s.nextSibling,p(s,e),s=n}return a};t.same=(e,t)=>e==t,t.replace=(e,t,r)=>r.replaceChild(t,e),t.insert=(e,t,r)=>r.insertBefore(t,e),t.remove=(e,t)=>t.removeChild(e);var r,a=t,l={};((t,r)=>{for(var a in r)e(t,a,{get:r[a],enumerable:!0})})(l,{batch:()=>u,computed:()=>c,current:()=>r,effect:()=>i,signal:()=>o,untracked:()=>p});var s,n,o=(e,t,a=new Set)=>((t={get value(){return r?.deps.push(a.add(r)),e},set value(t){if(t!==e){e=t;for(let e of a)e(t)}},peek:()=>e}).toJSON=t.then=t.toString=t.valueOf=()=>t.value,t),i=(e,t,a,l)=>(l=(a=l=>{t?.call?.(),l=r,r=a;try{t=e()}finally{r=l}}).deps=[],a(),e=>{for(t?.call?.();e=l.pop();)e.delete(a)}),c=(e,t=o(),r,a)=>((r={get value(){return a||=i((()=>t.value=e())),t.value},peek:t.peek}).toJSON=r.then=r.toString=r.valueOf=()=>r.value,r),u=e=>e(),p=(e,t,a)=>(t=r,r=null,a=e(),r=t,a),f=e=>(s=0,n=e,e=h(),n[s]?d():e||""),d=(e="Bad syntax",t=n.slice(0,s).split("\n"),r=t.pop())=>{let a=n.slice(s-108,s).split("\n").pop(),l=n.slice(s,s+108).split("\n").shift();throw EvalError(`${e} at ${t.length}:${r.length} \`${s>=108?"…":""}${a}┃${l}\``,"font-weight: bold")},v=(e,t=s,r)=>{for(;r=e(n.charCodeAt(s));)s+=r;return n.slice(t,s)},y=(e=1,t=s)=>(s+=e,n.slice(t,s)),h=(e=0,t,r,a,l,n)=>{for(;(r=f.space())&&(l=((n=m[r])&&n(a,e))??(!a&&v(f.id)));)a=l;return t&&(r==t?s++:d()),a},m=(f.id=e=>e>=48&&e<=57||e>=65&&e<=90||e>=97&&e<=122||36==e||95==e||e>=192&&215!=e&&247!=e,f.space=e=>{for(;(e=n.charCodeAt(s))<=32;)s++;return e},[]),g=(e,t=32,r,a=e.charCodeAt(0),l=e.length,o=m[a],i=e.toUpperCase()!==e)=>m[a]=(a,c,u=s)=>c<t&&(l<2||n.substr(s,l)==e)&&(!i||!f.id(n.charCodeAt(s+l)))&&(s+=l,r(a,c))||(s=u,o?.(a,c)),b=(e,t,r=!1)=>g(e,t,((a,l)=>a&&(l=h(t-(r?.5:0)))&&[e,a,l])),k=(e,t,r)=>g(e,t,(a=>r?a&&[e,a]:!a&&(a=h(t-.5))&&[e,a])),A=(e,t)=>{g(e,t,((r,a)=>(a=h(t),(!r||r[0]!==e)&&(r=[e,r]),r.push(a),r)))},N=(e,t)=>g(e[0],t,(t=>!t&&[e,h(0,e.charCodeAt(1))])),O=(e,t)=>g(e[0],t,(t=>t&&[e[0],t,h(0,e.charCodeAt(1))])),w=f,C=e=>Array.isArray(e)?e[0]?S[e[0]](...e.slice(1)):()=>e[1]:C.id(e),S=(C.id=e=>t=>t?.[e],{}),x=(e,t,r=S[e])=>S[e]=(...e)=>t(...e)||r&&r(...e),$=(e,t,r,a,l)=>"()"===e[0]?$(e[1],t,r):"string"==typeof e?r=>t(r,e,r):"."===e[0]?(a=C(e[1]),l=e[2],e=>t(a(e),l,e)):"["===e[0]?(a=C(e[1]),l=C(e[2]),e=>t(a(e),l(e),e)):r?(e=C(e),r=>t([e(r)],0,r)):()=>d("Bad left value"),E=C,T=(e,t)=>[,(e=+v((e=>46===e||e>=48&&e<=57||(69===e||101===e?2:0))))!=e?d():e];m[46]=e=>!e&&T();for(let e=48;e<=57;e++)m[e]=e=>e?d():T();var W={n:"\n",r:"\r",t:"\t",b:"\b",f:"\f",v:"\v"},j=e=>(t,r,a="")=>{for(t&&d("Unexpected string"),y();(r=n.charCodeAt(s))-e;)92===r?(y(),r=y(),a+=W[r]||r):a+=y();return y()||d("Bad string"),[,a]};m[34]=j(34),m[39]=j(39),O("()",17),x("(",((e,t,r)=>(r=t?","===t[0]?(t=t.slice(1).map((e=>e?C(e):err())),e=>t.map((t=>t(e)))):(t=C(t),e=>[t(e)]):()=>[],$(e,((e,t,a)=>e[t](...r(a))),!0)))),O("[]",17),x("[",((e,t)=>t?(e=C(e),t=C(t),r=>e(r)[t(r)]):err())),b(".",17),x(".",((e,t)=>(e=C(e),t=t[0]?t:t[1],r=>e(r)[t]))),N("()",17),x("()",(e=>(!e&&d("Empty ()"),C(e))));var L=(...e)=>(e=e.map(C),t=>e.map((e=>e(t))).pop());A(",",1),x(",",L),A(";",1),x(";",L),b("*",12),x("*",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)*t(r)))),b("/",12),x("/",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)/t(r)))),b("%",12),x("%",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)%t(r)))),b("*=",2,!0),x("*=",((e,t)=>(t=C(t),$(e,((e,r,a)=>e[r]*=t(a)))))),b("/=",2,!0),x("/=",((e,t)=>(t=C(t),$(e,((e,r,a)=>e[r]/=t(a)))))),b("%=",2,!0),x("%=",((e,t)=>(t=C(t),$(e,((e,r,a)=>e[r]%=t(a)))))),k("+",14),x("+",((e,t)=>!t&&(e=C(e),t=>+e(t)))),k("-",14),x("-",((e,t)=>!t&&(e=C(e),t=>-e(t)))),b("+",11),x("+",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)+t(r)))),b("-",11),x("-",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)-t(r)))),b("+=",2,!0),x("+=",((e,t)=>(t=C(t),$(e,((e,r,a)=>e[r]+=t(a)))))),b("-=",2,!0),x("-=",((e,t)=>(t=C(t),$(e,((e,r,a)=>e[r]-=t(a)))))),g("++",15,(e=>e?["++-",e]:["++",h(14)])),x("++",(e=>$(e,((e,t,r)=>++e[t])))),x("++-",(e=>$(e,((e,t,r)=>e[t]++)))),g("--",15,(e=>e?["--+",e]:["--",h(14)])),x("--",(e=>$(e,((e,t,r)=>--e[t])))),x("--+",(e=>$(e,((e,t,r)=>e[t]--)))),k("~",14),x("~",((e,t)=>!t&&(e=C(e),t=>~e(t)))),b("|",5),x("|",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)|t(r)))),b("&",7),x("&",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)&t(r)))),b("^",6),x("^",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)^t(r)))),b(">>",10),x(">>",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)>>t(r)))),b("<<",10),x("<<",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)<<t(r)))),b("==",8),x("==",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)==t(r)))),b("!=",8),x("!=",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)!=t(r)))),b(">",9),x(">",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)>t(r)))),b("<",9),x("<",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)<t(r)))),b(">=",9),x(">=",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)>=t(r)))),b("<=",9),x("<=",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)<=t(r)))),k("!",14),x("!",((e,t)=>!t&&(e=C(e),t=>!e(t)))),b("||",3),x("||",((e,t)=>(e=C(e),t=C(t),r=>e(r)||t(r)))),b("&&",4),x("&&",((e,t)=>(e=C(e),t=C(t),r=>e(r)&&t(r)))),b("=",2,!0),x("=",((e,t)=>(t=C(t),$(e,((e,r,a)=>e[r]=t(a)))))),g("/*",20,((e,t)=>(v((e=>42!==e&&47!==n.charCodeAt(s+1))),y(2),e||h(t)||[]))),g("//",20,((e,t)=>(v((e=>e>=32)),e||h(t)||[""]))),b("**",13,!0),x("**",((e,t)=>t&&(e=C(e),t=C(t),r=>e(r)**t(r)))),g("?",2,((e,t,r)=>e&&(t=h(1.5,58))&&["?",e,t,h(1.5)])),x("?",((e,t,r)=>(e=C(e),t=C(t),r=C(r),a=>e(a)?t(a):r(a)))),g("true",20,(e=>e?err():[,!0])),g("false",20,(e=>e?err():[,!1])),N("[]",20),x("[]",((e,t)=>(e=(e=e?","===e[0]?e.slice(1):[e]:[]).map((e=>"..."===e[0]?(e=C(e[1]),t=>e(t)):(e=C(e),t=>[e(t)]))),t=>e.flatMap((e=>e(t)))))),N("{}",20),x("{}",((e,t)=>(e=(e=e?","!==e[0]?[e]:e.slice(1):[]).map((e=>C("string"==typeof e?[":",e,e]:e))),t=>Object.fromEntries(e.flatMap((e=>e(t))))))),b(":",1.5,!0),x(":",((e,t)=>(t=C(t),Array.isArray(e)?(e=C(e),r=>[[e(r),t(r)]]):r=>[[e,t(r)]]))),b("=>",2,!0),x("=>",((e,t)=>(e=(e="()"===e[0]?e[1]:e)?e=","===e[0]?e.slice(1):[e]:[],t=C("{}"===t[0]?t[1]:t),(r=null)=>(r=Object.create(r),(...a)=>(e.map(((e,t)=>r[e]=a[t])),t(r)))))),b(""),g("?.",17,(e=>e&&["?.",e])),x("?.",(e=>(e=C(e),t=>e(t)||(()=>{})))),g("?.",17,((e,t)=>e&&!(t=h(17))?.map&&["?.",e,t])),x("?.",((e,t)=>t&&(e=C(e),r=>e(r)?.[t]))),x("(",((e,t,r,a,l,s)=>"?."===e[0]&&(e[2]||Array.isArray(e[1]))&&(a=t?","===t[0]?(t=t.slice(1).map(C),e=>t.map((t=>t(e)))):(t=C(t),e=>[t(e)]):()=>[],!e[2]&&(e=e[1]),l="["===e[0]?C(e[2]):()=>e[2],r=C(e[1]),e=>r(e)?.[l(e)]?.(...a(e))))),k("...",14),x("...",(e=>(e=C(e),t=>Object.entries(e(t))))),b("in",9),x("in",((e,t)=>t&&(e=E(e),t=E(t),r=>e(r)in t(r)))),b("===",8),b("!==",9),x("===",((e,t)=>(e=E(e),t=E(t),r=>e(r)===t(r)))),x("!==",((e,t)=>(e=E(e),t=E(t),r=>e(r)!==t(r)))),b("??",3),x("??",((e,t)=>t&&(e=E(e),t=E(t),r=>e(r)??t(r)))),b("??=",2,!0),x("??=",((e,t)=>(t=E(t),$(e,((e,r,a)=>e[r]??=t(a)))))),b("||=",2,!0),x("||=",((e,t)=>(t=E(t),$(e,((e,r,a)=>e[r]||=t(a)))))),b("&&=",2,!0),x("&&=",((e,t)=>(t=E(t),$(e,((e,r,a)=>e[r]&&=t(a)))))),g("undefined",20,(e=>e?d():[,void 0])),g("NaN",20,(e=>e?d():[,NaN])),g("null",20,(e=>e?d():[,null]));var B=Symbol.dispose||=Symbol("dispose"),{signal:D,effect:M,batch:K,computed:P,untracked:J}=l,R={},U=new WeakMap;function Z(e,t){if(!e.children)return;if(U.has(e)){const[r,a]=U.get(e);for(let e in t)r[e]=t[e];J((()=>{for(let e of a)e()}))}const r=t||{},a=[],l=(e,t=e.parentNode)=>{if(e.attributes)for(let l=0;l<e.attributes.length;){let s=e.attributes[l];if(":"===s.name[0]){e.removeAttribute(s.name);let l=s.name.slice(1).split(":");for(let t of l){let l=(R[t]||R.default)(e,s.value,r,t);l&&(l[B]=M(l),a.push(l))}if(U.has(e))return;if(e.parentNode!==t)return!1}else l++}for(let t,r=0;t=e.children[r];r++)!1===l(t,e)&&r--};return l(e),U.has(e)||(U.set(e,[r,a]),e.classList?.add("∴"),e[B]=()=>{for(;a.length;)a.pop()[B]();e.classList.remove("∴"),U.delete(e);let t=e.getElementsByClassName("∴");for(;t.length;)t[0][B]?.()}),r}var z={},H=(e,t,r)=>{if(r=z[e=e.trim()])return r;try{r=E(w(e))}catch(r){throw Object.assign(r,{message:`∴ ${r.message}\n\n${t}${e?`="${e}"\n\n`:""}`,expr:e})}return z[e]=r},X=a,_=(e,t)=>e?.replace?e.replace(/\$<([^>]+)>/g,((e,r)=>t[r]?.valueOf?.()??"")):e;Z.use=e=>{e.signal&&(D=e.signal,M=e.effect,P=e.computed,K=e.batch||(e=>e()),J=e.untracked||K),e.swap&&(X=e.swap)};var q=Symbol(":each"),F={};R.each=(e,t,r,a)=>{let[l,s]=t.split(/\s+in\s+/),[n,o="_$"]=l.split(/\s*,\s*/);const i=e[q]=document.createTextNode("");e.replaceWith(i);const c=H(s,a),u=new WeakMap;e.removeAttribute(":key");let p=[];return()=>{let t=c(r)?.valueOf(),a=[];"number"==typeof t&&(t=Array.from({length:t},((e,t)=>t)));const l=new WeakSet;for(let s in t){let i=t[s],c=Object.create(r,{[o]:{value:s}});c[n]=i;let p,f=i.key??i.id??i;null==f?p=e.cloneNode(!0):(Object(f)!==f&&(f=F[f]||=Object(f)),l.has(f)?(console.warn("Duplicate key",f),p=e.cloneNode(!0)):(l.add(f),p=u.get(f)||u.set(f,e.cloneNode(!0)).get(f))),p.content&&(p=p.content.cloneNode(!0)),Z(p,c),11===p.nodeType?a.push(...p.childNodes):a.push(p)}X(i.parentNode,p,p=a,i)}};var G=Symbol("if");R.if=(e,t,r,a)=>{let l,s,n,o=e.parentNode,i=e.nextElementSibling,c=document.createTextNode(""),u=H(t,a),p=[];return e.after(c),e.content?(l=p,e.remove(),s=[...e.content.childNodes]):s=l=[e],i?.hasAttribute(":else")?(i.removeAttribute(":else"),i.hasAttribute(":if")?n=p:(i.remove(),n=i.content?[...i.content.childNodes]:[i])):n=p,()=>{const t=u(r)?.valueOf()?s:e[G]?p:n;if(i&&(i[G]=t===s),l!=t){l[0]?.[q]&&(l=[l[0][q]]),X(o,l,l=t,c);for(let e of l)Z(e,r)}}},R.ref=(e,t,r)=>{let a;return()=>{a&&delete r[a],r[a=_(t,r)]=e}},R.scope=(e,t,r,a)=>{let l=H(t,a);return()=>{Z(e,{...r,...l(r)?.valueOf?.()||{}})}},R.html=(e,t,r,a)=>{let l=H(t,a)(r);if(!l)return;let s=(l.content||l).cloneNode(!0);e.replaceChildren(s),Z(e,r)},R.text=(e,t,r)=>{let a=H(t,"text");return e.content&&e.replaceWith(e=document.createTextNode("")),()=>{let t=a(r)?.valueOf();e.textContent=null==t?"":t}},R.class=(e,t,r)=>{let a=H(t,"class"),l=new Set;return()=>{let t=a(r),s=new Set;t&&("string"==typeof t?_(t?.valueOf?.(),r).split(" ").map((e=>s.add(e))):Array.isArray(t)?t.map((e=>(e=_(e?.valueOf?.(),r))&&s.add(e))):Object.entries(t).map((([e,t])=>t?.valueOf?.()&&s.add(e))));for(let t of l)s.has(t)?s.delete(t):e.classList.remove(t);for(let t of l=s)e.classList.add(t)}},R.style=(e,t,r)=>{let a=H(t,"style"),l=e.getAttribute("style")||"";return l.endsWith(";")||(l+="; "),()=>{let t=a(r)?.valueOf();if("string"==typeof t)e.setAttribute("style",l+_(t,r));else{e.setAttribute("style",l);for(let a in t)e.style.setProperty(a,_(t[a],r))}}},R.default=(e,t,r,a)=>{let l=a.startsWith("on")&&a.slice(2),s=H(t,a);if(l){let t;return()=>(t?.(),t=I(e,l,s(r)))}return()=>{let t=s(r)?.valueOf();if(a)Y(e,a,_(t,r));else for(let a in t)Y(e,re(a),_(t[a],r))}};var I=(e,t,r=(()=>{}))=>{const a={evt:"",target:e,test:()=>!0};a.evt=t.replace(/\.(\w+)?-?([-\w]+)?/g,((e,t,r="")=>(a.test=Q[t]?.(a,...r.split("-"))||a.test,"")));const{evt:l,target:s,test:n,defer:o,stop:i,prevent:c,...u}=a;o&&(r=o(r));const p=e=>n(e)&&(i&&e.stopPropagation(),c&&e.preventDefault(),r.call(s,e));return s.addEventListener(l,p,u),()=>s.removeEventListener(l,p,u)},Q={prevent(e){e.prevent=!0},stop(e){e.stop=!0},once(e){e.once=!0},passive(e){e.passive=!0},capture(e){e.capture=!0},window(e){e.target=window},document(e){e.target=document},throttle(e,t){e.defer=e=>ee(e,t?Number(t)||0:108)},debounce(e,t){e.defer=e=>te(e,t?Number(t)||0:108)},outside:e=>t=>{let r=e.target;return!(r.contains(t.target)||!1===t.target.isConnected||r.offsetWidth<1&&r.offsetHeight<1)},self:e=>t=>t.target===e.target,ctrl:(e,...t)=>e=>V.ctrl(e)&&t.every((t=>V[t]?V[t](e):e.key===t)),shift:(e,...t)=>e=>V.shift(e)&&t.every((t=>V[t]?V[t](e):e.key===t)),alt:(e,...t)=>e=>V.alt(e)&&t.every((t=>V[t]?V[t](e):e.key===t)),meta:(e,...t)=>e=>V.meta(e)&&t.every((t=>V[t]?V[t](e):e.key===t)),arrow:()=>V.arrow,enter:()=>V.enter,escape:()=>V.escape,tab:()=>V.tab,space:()=>V.space,backspace:()=>V.backspace,delete:()=>V.delete,digit:()=>V.digit,letter:()=>V.letter,character:()=>V.character},V={ctrl:e=>e.ctrlKey||"Control"===e.key||"Ctrl"===e.key,shift:e=>e.shiftKey||"Shift"===e.key,alt:e=>e.altKey||"Alt"===e.key,meta:e=>e.metaKey||"Meta"===e.key||"Command"===e.key,arrow:e=>e.key.startsWith("Arrow"),enter:e=>"Enter"===e.key,escape:e=>e.key.startsWith("Esc"),tab:e=>"Tab"===e.key,space:e=>" "===e.key||"Space"===e.key||" "===e.key,backspace:e=>"Backspace"===e.key,delete:e=>"Delete"===e.key,digit:e=>/^\d$/.test(e.key),letter:e=>/^[a-zA-Z]$/.test(e.key),character:e=>/^\S$/.test(e.key)},Y=(e,t,r)=>{null==r||!1===r?e.removeAttribute(t):e.setAttribute(t,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},ee=(e,t)=>{let r,a,l=s=>{r=!0,setTimeout((()=>{if(r=!1,a)return a=!1,l(s),e(s)}),t)};return t=>r?a=!0:(l(t),e(t))},te=(e,t)=>{let r;return a=>{clearTimeout(r),r=setTimeout((()=>{r=null,e(a)}),t)}},re=e=>e.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(e=>"-"+e.toLowerCase()));R.value=(e,t,r)=>{let a,l,s=H(t,"value"),n="text"===e.type||""===e.type?t=>e.setAttribute("value",e.value=null==t?"":t):"TEXTAREA"===e.tagName||"text"===e.type||""===e.type?t=>(a=e.selectionStart,l=e.selectionEnd,e.setAttribute("value",e.value=null==t?"":t),a&&e.setSelectionRange(a,l)):"checkbox"===e.type?t=>(e.checked=t,Y(e,"checked",t)):"select-one"===e.type?t=>{for(let t in e.options)t.removeAttribute("selected");e.value=t,e.selectedOptions[0]?.setAttribute("selected","")}:t=>e.value=t;return()=>n(s(r)?.valueOf?.())},R.fx=(e,t,r,a)=>{let l=H(t,a);return()=>l(r)};export{K as batch,H as compile,P as computed,Z as default,R as directive,M as effect,_ as ipol,D as signal,X as swap,J as untracked};
1
+ var e,t,r,l,a,s=Object.defineProperty,n=Symbol.dispose||=Symbol("dispose"),o={},c=new WeakMap;function i(e,r){if(!e.children)return;if(c.has(e)){const[t,l]=c.get(e);for(let e in r)t[e]=r[e];a((()=>{for(let e of l)e()}))}const l=r||{},s=[],i=(e,r=e.parentNode)=>{if(e.attributes)for(let a=0;a<e.attributes.length;){let i=e.attributes[a];if(":"===i.name[0]){e.removeAttribute(i.name);let a=i.name.slice(1).split(":");for(let r of a){let a=o[r]||o.default,c=a(e,(a.parse||d)(i.value,d),l,r);c&&(c[n]=t(c),s.push(c))}if(c.has(e))return;if(e.parentNode!==r)return!1}else a++}for(let t,r=0;t=e.children[r];r++)!1===i(t,e)&&r--};return i(e),c.has(e)||(c.set(e,[l,s]),e.classList?.add("∴"),e[n]=()=>{for(;s.length;)s.pop()[n]();e.classList.remove("∴"),c.delete(e);let t=e.getElementsByClassName("∴");for(;t.length;)t[0][n]?.()}),l}var u,p,f={},d=(e,t,r)=>{if(r=f[e=e.trim()])return r;try{r=u(e)}catch(r){throw Object.assign(r,{message:`∴ ${r.message}\n\n${t}${e?`="${e}"\n\n`:""}`,expr:e})}return r.expr=e,f[e]=r};i.use=s=>{s.signal&&(e=s.signal,t=s.effect,l=s.computed,r=s.batch||(e=>e()),a=s.untracked||r),s.swap&&(p=s.swap),s.compile&&(u=s.compile)};var v,y={};((e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})})(y,{batch:()=>g,computed:()=>b,effect:()=>h,signal:()=>m,untracked:()=>k});var m=(e,t,r=new Set)=>((t={get value(){return v?.deps.push(r.add(v)),e},set value(t){if(t!==e){e=t;for(let e of r)e(t)}},peek:()=>e}).toJSON=t.then=t.toString=t.valueOf=()=>t.value,t),h=(e,t,r,l)=>(l=(r=l=>{t?.call?.(),l=v,v=r;try{t=e()}finally{v=l}}).deps=[],r(),e=>{for(t?.call?.();e=l.pop();)e.delete(r)}),b=(e,t=m(),r,l)=>((r={get value(){return l||=h((()=>t.value=e())),t.value},peek:t.peek}).toJSON=r.then=r.toString=r.valueOf=()=>r.value,r),g=e=>e(),k=(e,t,r)=>(t=v,v=null,r=e(),v=t,r),w=(e,t,r,l=null,{remove:a,insert:s}=w)=>{let n,o,c,i=0,u=new Set(r);for(;c=t[i++];)u.has(c)?n=n||c:a(c,e);for(n=n||l,i=0;c=r[i++];)o=n?n.nextSibling:l,n===c?n=o:(r[i]===o&&(n=o),s(c,n,e));return r};w.insert=(e,t,r)=>r.insertBefore(e,t),w.remove=(e,t)=>t.removeChild(e);var O=w,A=Symbol(":each"),S={},N=Symbol("key");(o.each=(e,[t,r,l],a)=>{const s=e[A]=document.createTextNode(""),n=e.parentNode;e.replaceWith(s);const o=new WeakMap,c=new WeakMap;let u=[];const{insert:f,replace:d}=p,v={remove:e=>{e.remove(),e[Symbol.dispose]?.(),e[N]&&(o.delete(e[N]),c.delete(e[N]))},insert:f,replace:d};return()=>{let f=l(a)?.valueOf(),d=[];"number"==typeof f&&(f=Array.from({length:f},((e,t)=>t)));const y=new WeakMap;for(let l in f){let s,n=f[l],u=n?.key??n?.id??n??l;u=Object(u)!==u?S[u]||=Object(u):n,null==u||y.has(u)||e.content?s=(e.content||e).cloneNode(!0):(y.set(u,1),(s=o.get(u)||(o.set(u,e.cloneNode(!0)),o.get(u)))[N]=u);let p=c.get(u)||(c.set(u,Object.create(a,{[r]:{value:l}})),c.get(u));p[t]=n,i(s,p),11===s.nodeType?d.push(...s.childNodes):d.push(s)}p(n,u,u=d,s,v)}}).parse=(e,t)=>{let[r,l]=e.split(/\s+in\s+/),[a,s="$"]=r.split(/\s*,\s*/);return[a,s,t(l)]};var x=Symbol("if");o.if=(e,t,r)=>{let l,a,s,n=e.parentNode,o=e.nextElementSibling,c=document.createTextNode(""),u=[];return e.after(c),e.content?(l=u,e.remove(),a=[...e.content.childNodes]):a=l=[e],o?.hasAttribute(":else")?(o.removeAttribute(":else"),o.hasAttribute(":if")?s=u:(o.remove(),s=o.content?[...o.content.childNodes]:[o])):s=u,()=>{const f=t(r)?.valueOf()?a:e[x]?u:s;if(o&&(o[x]=f===a),l!=f){l[0]?.[A]&&(l=[l[0][A]]),p(n,l,l=f,c);for(let e of l)i(e,r)}}},o.default=(e,t,r,l)=>{let a=l.startsWith("on")&&l.slice(2);if(a){let l;return()=>(l?.(),l=W(e,a,t(r)?.valueOf()))}return()=>{let a=t(r)?.valueOf();if(l)T(e,l,D(a,r));else for(let t in a)T(e,j(t),D(a[t],r))}};var W=(e,t,r=(()=>{}))=>{const l={evt:"",target:e,test:()=>!0};l.evt=t.replace(/\.(\w+)?-?([-\w]+)?/g,((e,t,r="")=>(l.test=C[t]?.(l,...r.split("-"))||l.test,"")));const{evt:a,target:s,test:n,defer:o,stop:c,prevent:i,...u}=l;o&&(r=o(r));const p=e=>n(e)&&(c&&e.stopPropagation(),i&&e.preventDefault(),r.call(s,e));return s.addEventListener(a,p,u),()=>s.removeEventListener(a,p,u)},C={prevent(e){e.prevent=!0},stop(e){e.stop=!0},once(e){e.once=!0},passive(e){e.passive=!0},capture(e){e.capture=!0},window(e){e.target=window},document(e){e.target=document},throttle(e,t){e.defer=e=>$(e,t?Number(t)||0:108)},debounce(e,t){e.defer=e=>L(e,t?Number(t)||0:108)},outside:e=>t=>{let r=e.target;return!(r.contains(t.target)||!1===t.target.isConnected||r.offsetWidth<1&&r.offsetHeight<1)},self:e=>t=>t.target===e.target,ctrl:(e,...t)=>e=>E.ctrl(e)&&t.every((t=>E[t]?E[t](e):e.key===t)),shift:(e,...t)=>e=>E.shift(e)&&t.every((t=>E[t]?E[t](e):e.key===t)),alt:(e,...t)=>e=>E.alt(e)&&t.every((t=>E[t]?E[t](e):e.key===t)),meta:(e,...t)=>e=>E.meta(e)&&t.every((t=>E[t]?E[t](e):e.key===t)),arrow:()=>E.arrow,enter:()=>E.enter,escape:()=>E.escape,tab:()=>E.tab,space:()=>E.space,backspace:()=>E.backspace,delete:()=>E.delete,digit:()=>E.digit,letter:()=>E.letter,character:()=>E.character},E={ctrl:e=>e.ctrlKey||"Control"===e.key||"Ctrl"===e.key,shift:e=>e.shiftKey||"Shift"===e.key,alt:e=>e.altKey||"Alt"===e.key,meta:e=>e.metaKey||"Meta"===e.key||"Command"===e.key,arrow:e=>e.key.startsWith("Arrow"),enter:e=>"Enter"===e.key,escape:e=>e.key.startsWith("Esc"),tab:e=>"Tab"===e.key,space:e=>" "===e.key||"Space"===e.key||" "===e.key,backspace:e=>"Backspace"===e.key,delete:e=>"Delete"===e.key,digit:e=>/^\d$/.test(e.key),letter:e=>/^[a-zA-Z]$/.test(e.key),character:e=>/^\S$/.test(e.key)},T=(e,t,r)=>{null==r||!1===r?e.removeAttribute(t):e.setAttribute(t,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},$=(e,t)=>{let r,l,a=s=>{r=!0,setTimeout((()=>{if(r=!1,l)return l=!1,a(s),e(s)}),t)};return t=>r?l=!0:(a(t),e(t))},L=(e,t)=>{let r;return l=>{clearTimeout(r),r=setTimeout((()=>{r=null,e(l)}),t)}},j=e=>e.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(e=>"-"+e.toLowerCase())),D=(e,t)=>e?.replace?e.replace(/\$<([^>]+)>/g,((e,r)=>t[r]?.valueOf?.()??"")):e;(o.ref=(e,t,r)=>{let l;return()=>{l&&delete r[l],r[l=D(t,r)]=e}}).parse=e=>e,o.scope=(e,t,r)=>()=>{i(e,{...r,...t(r)?.valueOf?.()||{}})},o.html=(e,t,r)=>{let l=t(r);if(!l)return;let a=(l.content||l).cloneNode(!0);e.replaceChildren(a),i(e,r)},o.text=(e,t,r)=>(e.content&&e.replaceWith(e=document.createTextNode("")),()=>{let l=t(r)?.valueOf();e.textContent=null==l?"":l}),o.class=(e,t,r)=>{let l=new Set;return()=>{let a=t(r),s=new Set;a&&("string"==typeof a?D(a?.valueOf?.(),r).split(" ").map((e=>s.add(e))):Array.isArray(a)?a.map((e=>(e=D(e?.valueOf?.(),r))&&s.add(e))):Object.entries(a).map((([e,t])=>t?.valueOf?.()&&s.add(e))));for(let t of l)s.has(t)?s.delete(t):e.classList.remove(t);for(let t of l=s)e.classList.add(t)}},o.style=(e,t,r)=>{let l=e.getAttribute("style")||"";return l.endsWith(";")||(l+="; "),()=>{let a=t(r)?.valueOf();if("string"==typeof a)e.setAttribute("style",l+D(a,r));else{e.setAttribute("style",l);for(let t in a)e.style.setProperty(t,D(a[t],r))}}},o.value=(e,t,r)=>{let l,a,s="text"===e.type||""===e.type?t=>e.setAttribute("value",e.value=null==t?"":t):"TEXTAREA"===e.tagName||"text"===e.type||""===e.type?t=>(l=e.selectionStart,a=e.selectionEnd,e.setAttribute("value",e.value=null==t?"":t),l&&e.setSelectionRange(l,a)):"checkbox"===e.type?t=>(e.checked=t,T(e,"checked",t)):"select-one"===e.type?t=>{for(let t in e.options)t.removeAttribute("selected");e.value=t,e.selectedOptions[0]?.setAttribute("selected","")}:t=>e.value=t;return()=>s(t(r)?.valueOf?.())},o.fx=(e,t,r)=>()=>t(r),i.use(y),i.use({compile:e=>i.constructor("__scope",`with (__scope) { return ${e} };`)}),i.use({swap:O});var M=i;export{r as batch,u as compile,l as computed,M as default,o as directive,t as effect,e as signal,p as swap,a as untracked};
package/package.json CHANGED
@@ -1,20 +1,19 @@
1
1
  {
2
2
  "name": "sprae",
3
3
  "description": "DOM microhydration.",
4
- "version": "9.0.1",
4
+ "version": "9.1.1",
5
5
  "main": "./sprae.js",
6
6
  "module": "./sprae.js",
7
7
  "type": "module",
8
8
  "files": [
9
9
  "core.js",
10
10
  "sprae.js",
11
+ "signal.js",
11
12
  "directive",
12
13
  "dist"
13
14
  ],
14
15
  "dependencies": {
15
- "subscript": "^8.3.4",
16
- "swapdom": "^1.1.1",
17
- "ulive": "^1.0.1"
16
+ "swapdom": "^1.2.1"
18
17
  },
19
18
  "devDependencies": {
20
19
  "@preact/signals": "^1.1.3",
@@ -23,8 +22,10 @@
23
22
  "esbuild": "^0.15.14",
24
23
  "hyperf": "^1.6.2",
25
24
  "jsdom": "^21.1.0",
25
+ "subscript": "^8.3.4",
26
26
  "terser": "^5.15.1",
27
27
  "tst": "^7.1.1",
28
+ "ulive": "^1.0.1",
28
29
  "usignal": "^0.9.0",
29
30
  "wait-please": "^3.1.0"
30
31
  },
package/readme.md CHANGED
@@ -3,8 +3,8 @@
3
3
  > DOM tree microhydration
4
4
 
5
5
  _Sprae_ is a compact & ergonomic progressive enhancement framework.<br/>
6
- It provides `:`-attributes for inline markup logic with _signals_-based reactivity.<br/>
7
- Perfect for small-scale websites, prototypes, or lightweight UI.<br/>
6
+ It provides `:`-attributes for inline markup logic with signals reactivity.<br/>
7
+ Perfect for small-scale websites, static pages, landings, prototypes, or lightweight UI.<br/>
8
8
 
9
9
 
10
10
  ## Usage
@@ -121,7 +121,7 @@ Set value of an input, textarea or select. Takes handle of `checked` and `select
121
121
  </select>
122
122
  ```
123
123
 
124
- #### `:*="value"`, `:="values"`
124
+ #### `:[prop]="value"`, `:="values"`
125
125
 
126
126
  Set any attribute(s).
127
127
 
@@ -170,7 +170,7 @@ Run effect, not changing any attribute.<br/>Optional cleanup is called in-betwee
170
170
  <div :fx="id = setInterval(tick, interval), () => clearInterval(tick)" />
171
171
  ```
172
172
 
173
- #### `:on*="handler"`
173
+ #### `:on[event]="handler"`
174
174
 
175
175
  Attach event(s) listener with possible modifiers.
176
176
 
@@ -265,10 +265,40 @@ Trigger when element is connected / disconnected from DOM.
265
265
  ```
266
266
  -->
267
267
 
268
+ ## Signals
269
+
270
+ Sprae uses signals for reactivity (see [_sprae/signal.js_](./signal.js)). It can be switched to any alternative preact-flavored signals for compatibility or performance:
271
+
272
+ ```js
273
+ import sprae, { signal, computed, effect, batch, untracked } from 'sprae';
274
+ import * as signals from '@preact/signals-core';
275
+
276
+ sprae.use(signals);
277
+
278
+ sprae(el, { name: signal('Kitty') });
279
+ ```
280
+
281
+ Provider | Size | Feature
282
+ :---|:---|:---
283
+ [`ulive`](https://ghub.io/ulive) | 350b | Minimal implementation, basic performance, good for small states
284
+ [`@webreflection/signal`](https://ghib.io/@webreflection/signal) | 531b | Class-based, better performance, good for small-medium states
285
+ [`usignal`](https://ghib.io/usignal) | 850b | Class-based with optimizations, good for medium states
286
+ [`@preact/signals-core`](https://ghub.io/@preact/signals-core) | 1.47kb | Best performance, good for any states
287
+ [`signal-polyfill`](https://github.com/tc39/proposal-signals) | 2.5kb | Standard signals, slowest performance. Use via [adapter](https://gist.github.com/dy/bbac687464ccf5322ab0e2fd0680dc4d).
268
288
 
269
- ## Expressions
270
289
 
271
- Expressions use [_justin_](https://github.com/dy/subscript?tab=readme-ov-file#justin), a minimal JS subset. It avoids "unsafe-eval" CSP and provides sandboxing. Also it's _fast_.
290
+ ## Evaluator
291
+
292
+ Expressions use _new Function_ as default evaluator, which is fast & compact way, but violates "unsafe-eval" CSP. To make eval stricter & safer, as well as sandbox expressions, an alternative evaluator can be configured, eg. _justin_:
293
+
294
+ ```js
295
+ import sprae from 'sprae'
296
+ import justin from 'subscript/justin'
297
+
298
+ sprae.use({compile: justin}) // set up justin as default compiler
299
+ ```
300
+
301
+ [_Justin_](https://github.com/dy/subscript?tab=readme-ov-file#justin) is minimal JS subset. It avoids "unsafe-eval" CSP and provides sandboxing.
272
302
 
273
303
  ###### Operators:
274
304
 
@@ -283,42 +313,48 @@ Expressions use [_justin_](https://github.com/dy/subscript?tab=readme-ov-file#ju
283
313
  `true false null undefined NaN`
284
314
 
285
315
 
286
- ## Signals
316
+ ## Directives
287
317
 
288
- Sprae uses minimal signals based on [`ulive`](https://ghub.io/ulive). It can be switched to [`@preact/signals-core`](https://ghub.io/@preact/signals-core), [`@webreflection/signal`](https://ghib.io/@webreflection/signal), [`usignal`](https://ghib.io/usignal), which are better for complex states:
318
+ Custom directives can be added as:
289
319
 
290
320
  ```js
291
- import sprae, { signal, computed, effect, batch, untracked } from 'sprae';
292
- import * as signals from '@preact/signals-core';
321
+ import sprae, { directive } from 'sprae/core.js'
293
322
 
294
- sprae.use(signals);
295
-
296
- sprae(el, { name: signal('Kitty') });
323
+ // define custom directive
324
+ directive.id = (el, evaluate, state) => {
325
+ return () => el.id = evaluate(state) // return update function
326
+ }
297
327
  ```
298
328
 
329
+ ## Custom build
299
330
 
300
- ## Customization
301
-
302
- Sprae build can be tailored to project needs via `sprae/core` and `sprae/directive/*`:
331
+ _Sprae_ can be tailored to project needs via `sprae/core` for performance, size or compatibility purposes:
303
332
 
304
333
  ```js
305
- import sprae, { directive, compile } from 'sprae/core.js'
334
+ // sprae.custom.js
335
+ import sprae, { directive } from 'sprae/core.js'
336
+ import * as signals from '@preact/signals'
337
+ import compile from 'subscript'
338
+ import diff from 'udomdiff
306
339
 
307
340
  // include directives
308
- import 'sprae/directive/if.js';
309
- import 'sprae/directive/text.js';
341
+ import 'sprae/directive/if.js'
342
+ import 'sprae/directive/text.js'
310
343
 
311
- // define custom directive
312
- directive.id = (el, expr, state) => {
313
- const evaluate = compile(state, 'id') // expression string -> evaluator
314
- return () => el.id = evaluate(state) // return update function
315
- }
344
+ // configure signals
345
+ sprae.use(signals)
346
+
347
+ // configure compiler
348
+ sprae.use({ compile })
349
+
350
+ // configure dom differ
351
+ sprae.use({ swap: (parent, from, to, before) => udomdiff(parent, from, to, node=>node, before) })
316
352
  ```
317
353
 
318
354
  <!--
319
355
  ### DOM diffing
320
356
 
321
- DOM differ uses [swapdom](https://github.com/dy/swapdom), can be reconfigured to [list-difference](https://github.com/paldepind/list-difference/), [udomdiff](https://github.com/WebReflection/udomdiff), [domdiff](https://github.com/WebReflection/domdiff), [etc](https://github.com/luwes/js-diff-benchmark):
357
+ DOM diffing uses [swapdom](https://github.com/dy/swapdom), but can be reconfigured to [list-difference](https://github.com/paldepind/list-difference/), [udomdiff](https://github.com/WebReflection/udomdiff), [domdiff](https://github.com/WebReflection/domdiff), or any other ([benchmark](https://github.com/luwes/js-diff-benchmark)):
322
358
 
323
359
  ```js
324
360
  import sprae from 'sprae';
@@ -329,26 +365,13 @@ sprae.use({ swap: domdiff });
329
365
  ```
330
366
  -->
331
367
 
332
- <!--
333
- ### Custom Build
334
-
335
- `sprae/core` exports bare-bones engine without directives, which allows tailoring build to project needs:
336
-
337
- ```js
338
- import sprae, { directive, effect } from 'sprae/core'
339
-
340
- // include required directives
341
- import 'sprae/directive/if'
342
- import 'sprae/directive/text'
343
- ```
344
- -->
345
-
346
368
 
347
369
  <!-- ## Dispose
348
370
 
349
371
  To destroy state and detach sprae handlers, call `element[Symbol.dispose]()`. -->
350
372
 
351
373
 
374
+ <!--
352
375
  ## v9 changes
353
376
 
354
377
  * No autoinit → use manual init via `import sprae from 'sprae'; sprae(document.body, state)`.
@@ -361,7 +384,7 @@ To destroy state and detach sprae handlers, call `element[Symbol.dispose]()`. --
361
384
  * Async props / events are not supported, pass async functions via state.
362
385
  * Directives order matters, eg. `<a :if :each :scope />` !== `<a :scope :each :if />`
363
386
  * Only one directive per `<template>`, eg. `<template :each />`, not `<template :if :each/>`
364
-
387
+ -->
365
388
 
366
389
  ## Justification
367
390
 
package/signal.js ADDED
@@ -0,0 +1,43 @@
1
+ // ulive minimal signal impl (decoupled from ulive to keep internal dep adjustable easily)
2
+ let current
3
+
4
+ export const signal = (v, s, obs = new Set) => (
5
+ s = {
6
+ get value() {
7
+ current?.deps.push(obs.add(current));
8
+ return v
9
+ },
10
+ set value(val) {
11
+ if (val === v) return
12
+ v = val;
13
+ for (let sub of obs) sub(val); // notify effects
14
+ },
15
+ peek() { return v },
16
+ },
17
+ s.toJSON = s.then = s.toString = s.valueOf = () => s.value,
18
+ s
19
+ ),
20
+ effect = (fn, teardown, run, deps) => (
21
+ run = (prev) => {
22
+ teardown?.call?.();
23
+ prev = current, current = run;
24
+ try { teardown = fn(); } finally { current = prev; }
25
+ },
26
+ deps = run.deps = [],
27
+
28
+ run(),
29
+ (dep) => { teardown?.call?.(); while (dep = deps.pop()) dep.delete(run); }
30
+ ),
31
+ computed = (fn, s = signal(), c, e) => (
32
+ c = {
33
+ get value() {
34
+ e ||= effect(() => s.value = fn());
35
+ return s.value
36
+ },
37
+ peek: s.peek
38
+ },
39
+ c.toJSON = c.then = c.toString = c.valueOf = () => c.value,
40
+ c
41
+ ),
42
+ batch = (fn) => fn(),
43
+ untracked = (fn, prev, v) => (prev = current, current = null, v = fn(), current = prev, v);
package/sprae.js CHANGED
@@ -1,6 +1,9 @@
1
- export * from './core.js'
2
- export { default } from './core.js'
1
+ import sprae from './core.js'
2
+
3
+ import * as signals from './signal.js'
4
+ import swap from 'swapdom/deflate'
3
5
 
6
+ // default directives
4
7
  import './directive/if.js'
5
8
  import './directive/each.js'
6
9
  import './directive/ref.js'
@@ -12,3 +15,15 @@ import './directive/style.js'
12
15
  import './directive/value.js'
13
16
  import './directive/fx.js'
14
17
  import './directive/default.js'
18
+
19
+ // default signals
20
+ sprae.use(signals)
21
+
22
+ // default compiler (indirect new Function to avoid detector)
23
+ sprae.use({ compile: expr => sprae.constructor(`__scope`, `with (__scope) { return ${expr} };`) })
24
+
25
+ // defaul dom swapper
26
+ sprae.use({ swap })
27
+
28
+ export default sprae
29
+ export * from './core.js'