sprae 2.14.2 → 3.0.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/package.json +3 -4
- package/r&d.md +24 -24
- package/readme.md +5 -87
- package/sprae.js +216 -566
- package/sprae.min.js +1 -1
- package/src/core.js +12 -6
- package/src/directives.js +8 -5
- package/src/state.js +113 -0
- package/test/dom.js +935 -0
- package/test/index.html +2 -1
- package/test/state.js +274 -0
- package/test/test.js +2 -922
- package/todo.md +4 -4
package/sprae.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function t(){throw new Error("Cycle detected")}function e(){if(n>1)n--;else{for(var t,e=!1;void 0!==i;){var r=i;for(i=void 0,s++;void 0!==r;){var o=r.o;if(r.o=void 0,r.f&=-3,!(8&r.f)&&u(r))try{r.c()}catch(r){e||(t=r,e=!0)}r=o}}if(s=0,n--,e)throw t}}var r=void 0,i=void 0,n=0,s=0,o=0;function l(t){if(void 0!==r){var e=t.n;if(void 0===e||e.t!==r)return e={i:0,S:t,p:r.s,n:void 0,t:r,e:void 0,x:void 0,r:e},void 0!==r.s&&(r.s.n=e),r.s=e,t.n=e,32&r.f&&t.S(e),e;if(-1===e.i)return e.i=0,void 0!==e.n&&(e.n.p=e.p,void 0!==e.p&&(e.p.n=e.n),e.p=r.s,e.n=void 0,r.s.n=e,r.s=e),e}}function a(t){this.v=t,this.i=0,this.n=void 0,this.t=void 0}function u(t){for(var e=t.s;void 0!==e;e=e.n)if(e.S.i!==e.i||!e.S.h()||e.S.i!==e.i)return!0;return!1}function f(t){for(var e=t.s;void 0!==e;e=e.n){var r=e.S.n;if(void 0!==r&&(e.r=r),e.S.n=e,e.i=-1,void 0===e.n){t.s=e;break}}}function c(t){for(var e=t.s,r=void 0;void 0!==e;){var i=e.p;-1===e.i?(e.S.U(e),void 0!==i&&(i.n=e.n),void 0!==e.n&&(e.n.p=i)):r=e,e.S.n=e.r,void 0!==e.r&&(e.r=void 0),e=i}t.s=r}function h(t){a.call(this,void 0),this.x=t,this.s=void 0,this.g=o-1,this.f=4}function v(t){var i=t.u;if(t.u=void 0,"function"==typeof i){n++;var s=r;r=void 0;try{i()}catch(e){throw t.f&=-2,t.f|=8,p(t),e}finally{r=s,e()}}}function p(t){for(var e=t.s;void 0!==e;e=e.n)e.S.U(e);t.x=void 0,t.s=void 0,v(t)}function d(t){if(r!==this)throw new Error("Out-of-order effect");c(this),r=t,this.f&=-2,8&this.f&&p(this),e()}function y(t){this.x=t,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32}function b(t){var e=new y(t);try{e.c()}catch(t){throw e.d(),t}return e.d.bind(e)}a.prototype.h=function(){return!0},a.prototype.S=function(t){this.t!==t&&void 0===t.e&&(t.x=this.t,void 0!==this.t&&(this.t.e=t),this.t=t)},a.prototype.U=function(t){if(void 0!==this.t){var e=t.e,r=t.x;void 0!==e&&(e.x=r,t.e=void 0),void 0!==r&&(r.e=e,t.x=void 0),t===this.t&&(this.t=r)}},a.prototype.subscribe=function(t){var e=this;return b((function(){var r=e.value,i=32&this.f;this.f&=-33;try{t(r)}finally{this.f|=i}}))},a.prototype.valueOf=function(){return this.value},a.prototype.toString=function(){return this.value+""},a.prototype.peek=function(){return this.v},Object.defineProperty(a.prototype,"value",{get:function(){var t=l(this);return void 0!==t&&(t.i=this.i),this.v},set:function(r){if(r!==this.v){s>100&&t(),this.v=r,this.i++,o++,n++;try{for(var i=this.t;void 0!==i;i=i.x)i.t.N()}finally{e()}}}}),(h.prototype=new a).h=function(){if(this.f&=-3,1&this.f)return!1;if(32==(36&this.f))return!0;if(this.f&=-5,this.g===o)return!0;if(this.g=o,this.f|=1,this.i>0&&!u(this))return this.f&=-2,!0;var t=r;try{f(this),r=this;var e=this.x();(16&this.f||this.v!==e||0===this.i)&&(this.v=e,this.f&=-17,this.i++)}catch(t){this.v=t,this.f|=16,this.i++}return r=t,c(this),this.f&=-2,!0},h.prototype.S=function(t){if(void 0===this.t){this.f|=36;for(var e=this.s;void 0!==e;e=e.n)e.S.S(e)}a.prototype.S.call(this,t)},h.prototype.U=function(t){if(void 0!==this.t&&(a.prototype.U.call(this,t),void 0===this.t)){this.f&=-33;for(var e=this.s;void 0!==e;e=e.n)e.S.U(e)}},h.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var t=this.t;void 0!==t;t=t.x)t.t.N()}},h.prototype.peek=function(){if(this.h()||t(),16&this.f)throw this.v;return this.v},Object.defineProperty(h.prototype,"value",{get:function(){1&this.f&&t();var e=l(this);if(this.h(),void 0!==e&&(e.i=this.i),16&this.f)throw this.v;return this.v}}),y.prototype.c=function(){var t=this.S();try{8&this.f||void 0===this.x||(this.u=this.x())}finally{t()}},y.prototype.S=function(){1&this.f&&t(),this.f|=1,this.f&=-9,v(this),f(this),n++;var e=r;return r=this,d.bind(this,e)},y.prototype.N=function(){2&this.f||(this.f|=2,this.o=i,i=this)},y.prototype.d=function(){this.f|=8,1&this.f||p(this)},Symbol.observable||=Symbol("observable");var g=new FinalizationRegistry((t=>t.call?.())),m=(t,e,r,i,n,s)=>{return t&&(o=(t[Symbol.observable]?.()||t).subscribe?.(e,r,i),s=o&&(()=>o.unsubscribe?.())||t.set&&t.call?.(n,e)||(t.then?.((t=>(!n&&e(t),i?.())),r)||(async s=>{try{for await(s of t){if(n)return;e(s)}i?.()}catch(t){r?.(t)}})())&&(t=>n=1),g.register(t,s),s);var o},w=t=>t&&t[k],k=Symbol("signal-struct");function A(t,e){if(w(t)&&!e)return t;if(S(t)){const n=Object.create(e||Object.getPrototypeOf(t)),s={},o=Object.getOwnPropertyDescriptors(t);for(let t in o){let e=o[t];if(e.get){let r=s[t]=new h(e.get.bind(n));Object.defineProperty(n,t,{get:()=>r.value,set:e.set?.bind(n),configurable:!1,enumerable:!0})}else{let o=e.value,l=(i=o)&&!!(i[Symbol.observable]||i[Symbol.asyncIterator]||i.call&&i.set||i.subscribe||i.then),u=s[t]=(r=o)&&r.peek?o:new a(l?void 0:S(o)?Object.seal(A(o)):Array.isArray(o)?A(o):o);l&&m(o,(t=>u.value=t)),Object.defineProperty(n,t,{get:()=>u.value,set(t){if(S(t)){if(S(u.value))try{return void Object.assign(u.value,t)}catch(t){}u.value=Object.seal(A(t))}else Array.isArray(t)?u.value=A(t):u.value=t},enumerable:!0,configurable:!1})}}return Object.defineProperty(n,k,{configurable:!1,enumerable:!1,value:!0}),n}var r,i;if(Array.isArray(t)&&!w(t[0]))for(let e=0;e<t.length;e++)t[e]=A(t[e]);return t}function S(t){return t&&t.constructor===Object}A.isStruct=w;var x=new WeakMap,O=class extends Map{#t=new FinalizationRegistry((t=>super.delete(t)));get size(){return[...this].length}constructor(t=[]){super();for(const[e,r]of t)this.set(e,r)}get(t){return super.get(t)?.deref()}set(t,e){let r=super.get(t);return r&&this.#t.unregister(r),r=(t=>x.get(t)||(t=>{const e=new WeakRef(t);return x.set(t,e),e})(t))(e),this.#t.register(e,t,r),super.set(t,r)}},j={},N={};j.if=(t,e)=>{let r=document.createTextNode(""),i=[U(t,e,":if")],n=[t],s=t;for(;(s=t.nextElementSibling)&&s.hasAttribute(":else");)s.removeAttribute(":else"),(e=s.getAttribute(":if"))?(s.removeAttribute(":if"),s.remove(),n.push(s),i.push(U(t,e,":else :if"))):(s.remove(),n.push(s),i.push((()=>1)));return t.replaceWith(s=r),t=>{let e=i.findIndex((e=>e(t)));n[e]!=s&&((s[E]||s).replaceWith(s=n[e]||r),_(s,t))}},j.with=(t,e,r)=>{_(t,A(U(t,e,"with")(r),r))};var E=Symbol(":each");j.each=(t,e)=>{let r=function(t){let e=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,r=t.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!r)return;let i=r[2].trim(),n=r[1].replace(/^\s*\(|\)\s*$/g,"").trim(),s=n.match(e);return s?[n.replace(e,"").trim(),s[1].trim(),i]:[n,"",i]}(e);if(!r)return R(new Error,t,e);const i=t[E]=document.createTextNode("");t.replaceWith(i);const n=U(t,r[2],":each"),s=t.getAttribute(":key"),o=s?U(null,s):null;t.removeAttribute(":key");const l=new O,a=new O;let u=[];return s=>{let f=n(s);f?"number"==typeof f?f=Array.from({length:f},((t,e)=>[e,e+1])):Array.isArray(f)?f=f.map(((t,e)=>[e+1,t])):"object"==typeof f?f=Object.entries(f):R(Error("Bad list value"),t,e,":each"):f=[];let c=[],h=[];for(let[e,i]of f){let n,u,f=o?.({[r[0]]:i,[r[1]]:e});null==f?n=t.cloneNode(!0):(n=a.get(f))||a.set(f,n=t.cloneNode(!0)),c.push(n),null!=f&&(u=l.get(f))?u[r[0]]=i:(u=A({[r[0]]:i,[r[1]]:e},s),null!=f&&l.set(f,u)),h.push(u)}!function(t,e,r,i){const n=new Map,s=new Map;let o,l;for(o=0;o<e.length;o++)n.set(e[o],o);for(o=0;o<r.length;o++)s.set(r[o],o);for(o=l=0;o!==e.length||l!==r.length;){var a=e[o],u=r[l];if(null===a)o++;else if(r.length<=l)t.removeChild(e[o]),o++;else if(e.length<=o)t.insertBefore(u,e[o]||i),l++;else if(a===u)o++,l++;else{var f=s.get(a),c=n.get(u);void 0===f?(t.removeChild(e[o]),o++):void 0===c?(t.insertBefore(u,e[o]||i),l++):(t.insertBefore(e[c],e[o]||i),e[c]=null,c>o+1&&o++,l++)}}}(i.parentNode,u,c,i),u=c;for(let t=0;t<c.length;t++)_(c[t],h[t])}},N.ref=(t,e,r)=>{r[e]=t},N.id=(t,e)=>{let r=U(t,e,":id");return e=>{return i=r(e),t.id=i||0===i?i:"";var i}},N.class=(t,e)=>{let r=U(t,e,":class"),i=t.className;return e=>{let n=r(e),s="string"==typeof n?n:(Array.isArray(n)?n:Object.entries(n).map((([t,e])=>e?t:""))).filter(Boolean).join(" ");t.className=[i,s].filter(Boolean).join(" ")}},N.style=(t,e)=>{let r=U(t,e,":style"),i=t.getAttribute("style")||"";return i.endsWith(";")||(i+="; "),e=>{let n=r(e);if("string"==typeof n)t.setAttribute("style",i+n);else{t.setAttribute("style",i);for(let e in n)t.style.setProperty(e,n[e])}}},N.text=(t,e)=>{let r=U(t,e,":text");return e=>{let i=r(e);t.textContent=null==i?"":i}},N.data=(t,e)=>{let r=U(t,e,":data");return e=>{let i=r(e);for(let e in i)t.dataset[e]=i[e]}},N.aria=(t,e)=>{let r=U(t,e,":aria");return e=>(e=>{for(let r in e)D(t,"aria-"+z(r),null==e[r]?null:e[r]+"")})(r(e))},N[""]=(t,e)=>{let r=U(t,e,":");if(r)return e=>{let i=r(e);for(let e in i)D(t,z(e),i[e])}},N.value=(t,e)=>{let r,i,n=U(t,e,":value"),s="text"===t.type||""===t.type?e=>t.setAttribute("value",t.value=null==e?"":e):"TEXTAREA"===t.tagName||"text"===t.type||""===t.type?e=>(r=t.selectionStart,i=t.selectionEnd,t.setAttribute("value",t.value=null==e?"":e),r&&t.setSelectionRange(r,i)):"checkbox"===t.type?e=>(t.value=e?"on":"",D(t,"checked",e)):"select-one"===t.type?e=>{for(let e in t.options)e.removeAttribute("selected");t.value=e,t.selectedOptions[0]?.setAttribute("selected","")}:e=>t.value=e;return t=>s(n(t))},N.on=(t,e)=>{let r=U(t,e,":on");return e=>{let i=r(e),n=[];for(let e in i)n.push($(t,e,i[e]));return()=>{for(let t of n)t()}}};var W=(t,e,r,i)=>{let n=i.startsWith("on")&&i.slice(2),s=U(t,e,":"+i);if(s)return n?e=>{let r=s(e)||(()=>{});return $(t,n,r)}:e=>D(t,i,s(e))},$=(t,e,r)=>{if(!r)return;let i=e.split("..").map((e=>{let r={evt:"",target:t,test:()=>!0};return r.evt=(e.startsWith("on")?e.slice(2):e).replace(/\.(\w+)?-?([-\w]+)?/g,((t,e,i="")=>(r.test=C[e]?.(r,...i.split("-"))||r.test,""))),r}));if(1==i.length)return o(r,i[0]);const n=(e,r=0)=>{let s;return s=o((o=>{r&&s();let l=e.call(t,o);"function"!=typeof l&&(l=()=>{}),r+1<i.length&&n(l,r?r+1:1)}),i[r])};let s=n(r);return()=>s();function o(t,{evt:e,target:r,test:i,defer:n,stop:s,prevent:o,...l}){n&&(t=n(t));let a=e=>i(e)&&(s&&e.stopPropagation(),o&&e.preventDefault(),t.call(r,e));return r.addEventListener(e,a,l),()=>r.removeEventListener(e,a,l)}},C={prevent(t){t.prevent=!0},stop(t){t.stop=!0},once(t){t.once=!0},passive(t){t.passive=!0},capture(t){t.capture=!0},window(t){t.target=window},document(t){t.target=document},toggle(t){t.defer=(e,r)=>i=>r?(r.call?.(t.target,i),r=null):r=e()},throttle(t,e){t.defer=t=>T(t,e?Number(e)||0:108)},debounce(t,e){t.defer=t=>B(t,e?Number(e)||0:108)},outside:t=>e=>{let r=t.target;return!(r.contains(e.target)||!1===e.target.isConnected||r.offsetWidth<1&&r.offsetHeight<1)},self:t=>e=>e.target===t.target,ctrl:(t,...e)=>t=>P.ctrl(t)&&e.every((e=>P[e]?P[e](t):t.key===e)),shift:(t,...e)=>t=>P.shift(t)&&e.every((e=>P[e]?P[e](t):t.key===e)),alt:(t,...e)=>t=>P.alt(t)&&e.every((e=>P[e]?P[e](t):t.key===e)),meta:(t,...e)=>t=>P.meta(t)&&e.every((e=>P[e]?P[e](t):t.key===e)),arrow:t=>P.arrow,enter:t=>P.enter,escape:t=>P.escape,tab:t=>P.tab,space:t=>P.space,backspace:t=>P.backspace,delete:t=>P.delete,digit:t=>P.digit,letter:t=>P.letter,character:t=>P.character},P={ctrl:t=>t.ctrlKey||"Control"===t.key||"Ctrl"===t.key,shift:t=>t.shiftKey||"Shift"===t.key,alt:t=>t.altKey||"Alt"===t.key,meta:t=>t.metaKey||"Meta"===t.key||"Command"===t.key,arrow:t=>t.key.startsWith("Arrow"),enter:t=>"Enter"===t.key,escape:t=>t.key.startsWith("Esc"),tab:t=>"Tab"===t.key,space:t=>" "===t.key||"Space"===t.key||" "===t.key,backspace:t=>"Backspace"===t.key,delete:t=>"Delete"===t.key,digit:t=>/^\d$/.test(t.key),letter:t=>/^[a-zA-Z]$/.test(t.key),character:t=>/^\S$/.test(t.key)},T=(t,e)=>{let r,i,n=s=>{r=!0,setTimeout((()=>{if(r=!1,i)return i=!1,n(s),t(s)}),e)};return e=>r?i=!0:(n(e),t(e))},B=(t,e)=>{let r;return i=>{clearTimeout(r),r=setTimeout((()=>{r=null,t(i)}),e)}},D=(t,e,r)=>{null==r||!1===r?t.removeAttribute(e):t.setAttribute(e,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},M={};function U(t,e,r){let i=M[e];if(!i){let n=/^[\n\s]*if.*\(.*\)/.test(e)||/\b(let|const)\s/.test(e)&&!r.startsWith(":on")?`(() => {${e}})()`:e;try{i=M[e]=new Function("__scope",`with (__scope) { return ${n.trim()} };`)}catch(i){return R(i,t,e,r)}}return n=>{let s;try{s=i.call(t,n)}catch(i){return R(i,t,e,r)}return s}}function R(t,e,r,i){Object.assign(t,{element:e,expression:r}),console.warn(`∴ ${t.message}\n\n${i}=${r?`"${r}"\n\n`:""}`,e),setTimeout((()=>{throw t}),0)}function z(t){return t.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(t=>"-"+t.toLowerCase()))}var K=new WeakMap;function _(t,r){if(!t.children)return;if(K.has(t)){let i=K.get(t);return function(t){if(n>0)return t();n++;try{t()}finally{e()}}((()=>Object.assign(i,r))),i}const i=A(r||{}),s=[],o=(t,e=t.parentNode)=>{for(let r in j){let n=":"+r;if(t.hasAttribute?.(n)){let o=t.getAttribute(n);if(t.removeAttribute(n),s.push(j[r](t,o,i,r)),K.has(t)||t.parentNode!==e)return!1}}if(t.attributes)for(let r=0;r<t.attributes.length;){let n=t.attributes[r];if(":"!==n.name[0]){r++;continue}t.removeAttribute(n.name);let o=n.value,l=n.name.slice(1).split(":");for(let r of l){let n=N[r]||W;if(s.push(n(t,o,i,r)),K.has(t)||t.parentNode!==e)return!1}}for(let e,r=0;e=t.children[r];r++)!1===o(e,t)&&r--};o(t);for(let t of s)if(t){let e;b((()=>{"function"==typeof e&&e(),e=t(i)}))}return Object.seal(i),K.set(t,i),i}var F=_;export{F as default};
|
|
1
|
+
var e,t,r=new WeakMap,n=new WeakMap,l=new WeakMap,s=Symbol("parent"),a={Array:Array,Object:Object,Number:Number,String:String,Boolean:Boolean,Date:Date,console:console},i={has:()=>!0,get(t,l){if("symbol"==typeof l)return t[l];if(!(l in t))return t[s]?.[l];if(Array.isArray(t)&&l in Array.prototype)return t[l];let a=t[l];if(e){let n=r.get(t);n||r.set(t,n={}),n[l]?n[l].includes(e)||n[l].push(e):n[l]=[e]}if(a&&a.constructor===Object||Array.isArray(a)){let e=n.get(a);return e||n.set(a,e=new Proxy(a,i)),e}return a},set(e,n,l){if(!(n in e)&&e[s]&&n in e[s])return e[s][n]=l;if(Array.isArray(e)&&n in Array.prototype)return e[n]=l;const a=e[n];if(Object.is(a,l))return!0;e[n]=l;let i=r.get(e)?.[n];if(i)for(let e of i)t?t.add(e):e.call();return!0},deleteProperty:(e,t)=>(e[t]=void 0,delete e[t],!0)},o=(e,t)=>{if(n.has(e))return n.get(e);if(l.has(e))return e;let r=new Proxy(e,i);return n.set(e,r),l.set(r,e),e[s]=t?o(t):a,r},u=t=>{const r=()=>{let n=e;e=r,t(),e=n};return r(),r},c=new WeakMap,f=class extends Map{#e=new FinalizationRegistry((e=>super.delete(e)));get size(){return[...this].length}constructor(e=[]){super();for(const[t,r]of e)this.set(t,r)}get(e){return super.get(e)?.deref()}set(e,t){let r=super.get(e);return r&&this.#e.unregister(r),r=(e=>c.get(e)||(e=>{const t=new WeakRef(e);return c.set(e,t),t})(e))(t),this.#e.register(t,e,r),super.set(e,r)}},p={},y={};p.if=(e,t)=>{let r=document.createTextNode(""),n=[W(e,t,":if")],l=[e],s=e;for(;(s=e.nextElementSibling)&&s.hasAttribute(":else");)s.removeAttribute(":else"),(t=s.getAttribute(":if"))?(s.removeAttribute(":if"),s.remove(),l.push(s),n.push(W(e,t,":else :if"))):(s.remove(),l.push(s),n.push((()=>1)));return e.replaceWith(s=r),e=>{let t=n.findIndex((t=>t(e)));l[t]!=s&&((s[h]||s).replaceWith(s=l[t]||r),j(s,e))}},p.with=(e,t,r)=>{const n=W(e,t,"with")(r);j(e,o(n,r))};var h=Symbol(":each");p.each=(e,t)=>{let r=function(e){let t=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,r=e.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!r)return;let n=r[2].trim(),l=r[1].replace(/^\s*\(|\)\s*$/g,"").trim(),s=l.match(t);return s?[l.replace(t,"").trim(),s[1].trim(),n]:[l,"",n]}(t);if(!r)return x(new Error,e,t);const n=e[h]=document.createTextNode("");e.replaceWith(n);const l=W(e,r[2],":each"),s=e.getAttribute(":key"),a=s?W(null,s):null;e.removeAttribute(":key");const i=e.getAttribute(":ref"),u=new f,c=new f;let p=[];return s=>{let f=l(s);f?"number"==typeof f?f=Array.from({length:f},((e,t)=>[t,t+1])):Array.isArray(f)?f=f.map(((e,t)=>[t+1,e])):"object"==typeof f?f=Object.entries(f):x(Error("Bad list value"),e,t,":each"):f=[];let y=[],h=[];for(let[t,n]of f){let l,f,p=a?.({[r[0]]:n,[r[1]]:t});null==p?l=e.cloneNode(!0):(l=c.get(p))||c.set(p,l=e.cloneNode(!0)),y.push(l),null!=p&&(f=u.get(p))?f[r[0]]=n:(f=o({[r[0]]:n,[i||""]:null,[r[1]]:t},s),null!=p&&u.set(p,f)),h.push(f)}!function(e,t,r,n){const l=new Map,s=new Map;let a,i;for(a=0;a<t.length;a++)l.set(t[a],a);for(a=0;a<r.length;a++)s.set(r[a],a);for(a=i=0;a!==t.length||i!==r.length;){var o=t[a],u=r[i];if(null===o)a++;else if(r.length<=i)e.removeChild(t[a]),a++;else if(t.length<=a)e.insertBefore(u,t[a]||n),i++;else if(o===u)a++,i++;else{var c=s.get(o),f=l.get(u);void 0===c?(e.removeChild(t[a]),a++):void 0===f?(e.insertBefore(u,t[a]||n),i++):(e.insertBefore(t[f],t[a]||n),t[f]=null,f>a+1&&a++,i++)}}}(n.parentNode,p,y,n),p=y;for(let e=0;e<y.length;e++)j(y[e],h[e])}},y.ref=(e,t,r)=>{r[t]=e},y.id=(e,t)=>{let r=W(e,t,":id");return t=>{return n=r(t),e.id=n||0===n?n:"";var n}},y.class=(e,t)=>{let r=W(e,t,":class"),n=e.className;return t=>{let l=r(t),s="string"==typeof l?l:(Array.isArray(l)?l:Object.entries(l).map((([e,t])=>t?e:""))).filter(Boolean).join(" ");e.className=[n,s].filter(Boolean).join(" ")}},y.style=(e,t)=>{let r=W(e,t,":style"),n=e.getAttribute("style")||"";return n.endsWith(";")||(n+="; "),t=>{let l=r(t);if("string"==typeof l)e.setAttribute("style",n+l);else{e.setAttribute("style",n);for(let t in l)e.style.setProperty(t,l[t])}}},y.text=(e,t)=>{let r=W(e,t,":text");return t=>{let n=r(t);e.textContent=null==n?"":n}},y.data=(e,t)=>{let r=W(e,t,":data");return t=>{let n=r(t);for(let t in n)e.dataset[t]=n[t]}},y.aria=(e,t)=>{let r=W(e,t,":aria");return t=>(t=>{for(let r in t)k(e,"aria-"+N(r),null==t[r]?null:t[r]+"")})(r(t))},y[""]=(e,t)=>{let r=W(e,t,":");if(r)return t=>{let n=r(t);for(let t in n)k(e,N(t),n[t])}},y.value=(e,t)=>{let r,n,l=W(e,t,":value"),s="text"===e.type||""===e.type?t=>e.setAttribute("value",e.value=null==t?"":t):"TEXTAREA"===e.tagName||"text"===e.type||""===e.type?t=>(r=e.selectionStart,n=e.selectionEnd,e.setAttribute("value",e.value=null==t?"":t),r&&e.setSelectionRange(r,n)):"checkbox"===e.type?t=>(e.value=t?"on":"",k(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 e=>s(l(e))},y.on=(e,t)=>{let r=W(e,t,":on");return t=>{let n=r(t),l=[];for(let t in n)l.push(d(e,t,n[t]));return()=>{for(let e of l)e()}}};var g=(e,t,r,n)=>{let l=n.startsWith("on")&&n.slice(2),s=W(e,t,":"+n);if(s)return l?t=>{let r=s(t)||(()=>{});return d(e,l,r)}:t=>k(e,n,s(t))},d=(e,t,r)=>{if(!r)return;let n=t.split("..").map((t=>{let r={evt:"",target:e,test:()=>!0};return r.evt=(t.startsWith("on")?t.slice(2):t).replace(/\.(\w+)?-?([-\w]+)?/g,((e,t,n="")=>(r.test=m[t]?.(r,...n.split("-"))||r.test,""))),r}));if(1==n.length)return a(r,n[0]);const l=(t,r=0)=>{let s;return s=a((a=>{r&&s();let i=t.call(e,a);"function"!=typeof i&&(i=()=>{}),r+1<n.length&&l(i,r?r+1:1)}),n[r])};let s=l(r);return()=>s();function a(e,{evt:t,target:r,test:n,defer:l,stop:s,prevent:a,...i}){l&&(e=l(e));let o=t=>n(t)&&(s&&t.stopPropagation(),a&&t.preventDefault(),e.call(r,t));return r.addEventListener(t,o,i),()=>r.removeEventListener(t,o,i)}},m={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},toggle(e){e.defer=(t,r)=>n=>r?(r.call?.(e.target,n),r=null):r=t()},throttle(e,t){e.defer=e=>v(e,t?Number(t)||0:108)},debounce(e,t){e.defer=e=>A(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=>b.ctrl(e)&&t.every((t=>b[t]?b[t](e):e.key===t)),shift:(e,...t)=>e=>b.shift(e)&&t.every((t=>b[t]?b[t](e):e.key===t)),alt:(e,...t)=>e=>b.alt(e)&&t.every((t=>b[t]?b[t](e):e.key===t)),meta:(e,...t)=>e=>b.meta(e)&&t.every((t=>b[t]?b[t](e):e.key===t)),arrow:e=>b.arrow,enter:e=>b.enter,escape:e=>b.escape,tab:e=>b.tab,space:e=>b.space,backspace:e=>b.backspace,delete:e=>b.delete,digit:e=>b.digit,letter:e=>b.letter,character:e=>b.character},b={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)},v=(e,t)=>{let r,n,l=s=>{r=!0,setTimeout((()=>{if(r=!1,n)return n=!1,l(s),e(s)}),t)};return t=>r?n=!0:(l(t),e(t))},A=(e,t)=>{let r;return n=>{clearTimeout(r),r=setTimeout((()=>{r=null,e(n)}),t)}},k=(e,t,r)=>{null==r||!1===r?e.removeAttribute(t):e.setAttribute(t,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},w={};function W(e,t,r){let n=w[t];if(!n){let l=/^[\n\s]*if.*\(.*\)/.test(t)||/\b(let|const)\s/.test(t)&&!r.startsWith(":on")?`(() => {${t}})()`:t;try{n=w[t]=new Function("__scope",`with (__scope) { return ${l.trim()} };`)}catch(n){return x(n,e,t,r)}}return l=>{let s;try{s=n.call(e,l)}catch(n){return x(n,e,t,r)}return s}}function x(e,t,r,n){Object.assign(e,{element:t,expression:r}),console.warn(`∴ ${e.message}\n\n${n}=${r?`"${r}"\n\n`:""}`,t),queueMicrotask((()=>{throw e}),0)}function N(e){return e.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(e=>"-"+e.toLowerCase()))}j.globals=a;var S=new WeakMap;function j(e,r){if(!e.children)return;if(S.has(e)){let n=S.get(e);return(e=>{let l=t;t=new Set,Object.assign(n,r);for(let e of t)e.call();t.clear(),t=l})(),n}const n=o(r||{}),l=[],s=(e,t=e.parentNode)=>{for(let r in p){let s=":"+r;if(e.hasAttribute?.(s)){let a=e.getAttribute(s);if(e.removeAttribute(s),l.push(p[r](e,a,n,r)),S.has(e)||e.parentNode!==t)return!1}}if(e.attributes)for(let r=0;r<e.attributes.length;){let s=e.attributes[r];if(":"!==s.name[0]){r++;continue}e.removeAttribute(s.name);let a=s.value,i=s.name.slice(1).split(":");for(let r of i){let s=y[r]||g;if(l.push(s(e,a,n,r)),S.has(e)||e.parentNode!==t)return!1}}for(let t,r=0;t=e.children[r];r++)!1===s(t,e)&&r--};s(e);for(let e of l)if(e){let t;u((()=>{"function"==typeof t&&t(),t=e(n)}))}return S.set(e,n),n}var E=j;export{E as default};
|
package/src/core.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { state as createState, fx, batch, sandbox } from './state.js';
|
|
2
2
|
import defaultDirective, { primary, secondary } from './directives.js';
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
sprae.globals=sandbox
|
|
4
5
|
|
|
5
6
|
// sprae element: apply directives
|
|
6
7
|
const memo = new WeakMap
|
|
@@ -12,8 +13,14 @@ export default function sprae(container, values) {
|
|
|
12
13
|
return state
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
//
|
|
16
|
-
|
|
16
|
+
// subscribe to reactives
|
|
17
|
+
// for (let prop in values) {
|
|
18
|
+
// if (observable(values[prop])) {
|
|
19
|
+
// let value = values[prop]; values[prop] = null
|
|
20
|
+
// sube(value, value => state[prop] = value)
|
|
21
|
+
// }
|
|
22
|
+
// }
|
|
23
|
+
const state = createState(values || {});
|
|
17
24
|
const updates = []
|
|
18
25
|
|
|
19
26
|
// init directives on element
|
|
@@ -64,13 +71,12 @@ export default function sprae(container, values) {
|
|
|
64
71
|
// state is created after inits because directives can extend init values (expose refs etc)
|
|
65
72
|
for (let update of updates) if (update) {
|
|
66
73
|
let teardown
|
|
67
|
-
|
|
74
|
+
fx(() => {
|
|
68
75
|
if (typeof teardown === 'function') teardown()
|
|
69
76
|
teardown = update(state)
|
|
70
77
|
});
|
|
71
78
|
}
|
|
72
79
|
|
|
73
|
-
Object.seal(state);
|
|
74
80
|
memo.set(container, state);
|
|
75
81
|
|
|
76
82
|
return state;
|
package/src/directives.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// directives & parsing
|
|
2
2
|
import sprae from './core.js'
|
|
3
3
|
import swap from './domdiff.js'
|
|
4
|
-
import
|
|
4
|
+
import { state as createState} from './state.js'
|
|
5
5
|
import { WeakishMap } from './weakish-map.js'
|
|
6
6
|
|
|
7
7
|
// reserved directives - order matters!
|
|
@@ -47,7 +47,10 @@ primary['if'] = (el, expr) => {
|
|
|
47
47
|
// :with must come before :each, but :if has primary importance
|
|
48
48
|
primary['with'] = (el, expr, rootState) => {
|
|
49
49
|
let evaluate = parseExpr(el, expr, 'with')
|
|
50
|
-
|
|
50
|
+
const localState = evaluate(rootState)
|
|
51
|
+
let state = createState(localState, rootState)
|
|
52
|
+
// console.log(123, state.foo, state.bar)
|
|
53
|
+
sprae(el, state);
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
const _each = Symbol(':each')
|
|
@@ -68,6 +71,7 @@ primary['each'] = (tpl, expr) => {
|
|
|
68
71
|
const itemKey = keyExpr ? parseExpr(null, keyExpr) : null;
|
|
69
72
|
tpl.removeAttribute(':key')
|
|
70
73
|
|
|
74
|
+
const refExpr = tpl.getAttribute(':ref');
|
|
71
75
|
|
|
72
76
|
const scopes = new WeakishMap() // stores scope per data item
|
|
73
77
|
const itemEls = new WeakishMap() // element per data item
|
|
@@ -97,7 +101,7 @@ primary['each'] = (tpl, expr) => {
|
|
|
97
101
|
newEls.push(el)
|
|
98
102
|
|
|
99
103
|
if (key == null || !(scope = scopes.get(key))) {
|
|
100
|
-
scope =
|
|
104
|
+
scope = createState({[each[0]]: item, [refExpr||'']: null, [each[1]]: idx}, state)
|
|
101
105
|
if (key != null) scopes.set(key, scope)
|
|
102
106
|
}
|
|
103
107
|
// need to explicitly set item to update existing children's values
|
|
@@ -177,7 +181,6 @@ secondary['style'] = (el, expr) => {
|
|
|
177
181
|
|
|
178
182
|
secondary['text'] = (el, expr) => {
|
|
179
183
|
let evaluate = parseExpr(el, expr, ':text')
|
|
180
|
-
|
|
181
184
|
return (state) => {
|
|
182
185
|
let value = evaluate(state)
|
|
183
186
|
el.textContent = value == null ? '' : value;
|
|
@@ -443,7 +446,7 @@ function parseExpr(el, expression, dir) {
|
|
|
443
446
|
function exprError(error, element, expression, dir) {
|
|
444
447
|
Object.assign( error, { element, expression } )
|
|
445
448
|
console.warn(`∴ ${error.message}\n\n${dir}=${ expression ? `"${expression}"\n\n` : '' }`, element)
|
|
446
|
-
|
|
449
|
+
queueMicrotask(() => { throw error }, 0)
|
|
447
450
|
}
|
|
448
451
|
|
|
449
452
|
function dashcase(str) {
|
package/src/state.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// currentFx stack of listeners
|
|
2
|
+
let currentFx, currentBatch
|
|
3
|
+
|
|
4
|
+
const targetFxs = new WeakMap
|
|
5
|
+
const targetProxy = new WeakMap
|
|
6
|
+
const proxyTarget = new WeakMap
|
|
7
|
+
const _parent = Symbol('parent')
|
|
8
|
+
|
|
9
|
+
// default root sandbox
|
|
10
|
+
export const sandbox = {
|
|
11
|
+
Array, Object, Number, String, Boolean, Date,
|
|
12
|
+
console
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const handler = {
|
|
16
|
+
has(){
|
|
17
|
+
// sandbox everything
|
|
18
|
+
return true
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
get(target, prop) {
|
|
22
|
+
if (typeof prop === 'symbol') return target[prop]
|
|
23
|
+
if (!(prop in target)) return target[_parent]?.[prop]
|
|
24
|
+
if (Array.isArray(target) && prop in Array.prototype) return target[prop];
|
|
25
|
+
let value = target[prop]
|
|
26
|
+
|
|
27
|
+
if (currentFx) {
|
|
28
|
+
// get actual target from prototype chain
|
|
29
|
+
// while (!target.hasOwnProperty(prop)) target = Object.getPrototypeOf(target)
|
|
30
|
+
|
|
31
|
+
// register an fx for target-prop path
|
|
32
|
+
let propFxs = targetFxs.get(target)
|
|
33
|
+
if (!propFxs) targetFxs.set(target, propFxs = {})
|
|
34
|
+
if (!propFxs[prop]) propFxs[prop] = [currentFx]
|
|
35
|
+
else if (!propFxs[prop].includes(currentFx)) propFxs[prop].push(currentFx)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// if internal is trackable path - return proxy
|
|
39
|
+
if ((value && value.constructor === Object) || Array.isArray(value)) {
|
|
40
|
+
let proxy = targetProxy.get(value)
|
|
41
|
+
// FIXME: we can avoid saving it here, since it's created by new state
|
|
42
|
+
if (!proxy) targetProxy.set(value, proxy = new Proxy(value, handler))
|
|
43
|
+
return proxy
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return value
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
set(target, prop, value) {
|
|
50
|
+
if (!(prop in target) && (target[_parent] && prop in target[_parent])) return target[_parent][prop] = value
|
|
51
|
+
if (Array.isArray(target) && prop in Array.prototype) return target[prop] = value;
|
|
52
|
+
|
|
53
|
+
const prev = target[prop]
|
|
54
|
+
|
|
55
|
+
// avoid bumping unchanged values
|
|
56
|
+
if (Object.is(prev, value)) return true
|
|
57
|
+
|
|
58
|
+
target[prop] = value
|
|
59
|
+
|
|
60
|
+
// whenever target prop is set, call all dependent fxs
|
|
61
|
+
let propFxs = targetFxs.get(target)?.[prop]
|
|
62
|
+
|
|
63
|
+
if (propFxs) for (let fx of propFxs) currentBatch ? currentBatch.add(fx) : fx.call()
|
|
64
|
+
|
|
65
|
+
// FIXME: unsubscribe / delete effects by setting null/undefined
|
|
66
|
+
// if (value == null) targetFxs.delete(prev)
|
|
67
|
+
|
|
68
|
+
return true
|
|
69
|
+
},
|
|
70
|
+
|
|
71
|
+
deleteProperty(target, prop) {
|
|
72
|
+
target[prop] = undefined
|
|
73
|
+
delete target[prop]
|
|
74
|
+
return true
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const state = (obj, parent) => {
|
|
79
|
+
if (targetProxy.has(obj)) return targetProxy.get(obj)
|
|
80
|
+
if (proxyTarget.has(obj)) return obj // is proxy already
|
|
81
|
+
|
|
82
|
+
let proxy = new Proxy(obj, handler)
|
|
83
|
+
targetProxy.set(obj, proxy)
|
|
84
|
+
proxyTarget.set(proxy, obj)
|
|
85
|
+
|
|
86
|
+
// inherit from parent state
|
|
87
|
+
obj[_parent] = parent ? state(parent) : sandbox
|
|
88
|
+
|
|
89
|
+
return proxy
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const fx = (fn) => {
|
|
93
|
+
const call = () => {
|
|
94
|
+
let prev = currentFx
|
|
95
|
+
currentFx = call
|
|
96
|
+
fn()
|
|
97
|
+
currentFx = prev
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// collect deps from the first call
|
|
101
|
+
call()
|
|
102
|
+
|
|
103
|
+
return call
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export const batch = fn => {
|
|
107
|
+
let prevBatch = currentBatch
|
|
108
|
+
currentBatch = new Set
|
|
109
|
+
fn()
|
|
110
|
+
for (let fx of currentBatch) fx.call()
|
|
111
|
+
currentBatch.clear()
|
|
112
|
+
currentBatch = prevBatch
|
|
113
|
+
}
|