sprae 10.1.0 → 10.1.2
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/core.js +2 -1
- package/directive/each.js +2 -2
- package/dist/sprae.js +10 -17
- package/dist/sprae.min.js +1 -1
- package/package.json +1 -1
- package/readme.md +4 -4
- package/store.js +10 -13
package/core.js
CHANGED
|
@@ -28,6 +28,7 @@ export default function sprae(el, values) {
|
|
|
28
28
|
// if element was spraed by :with or :each instruction - skip, otherwise save
|
|
29
29
|
if (!memo.has(el)) memo.set(el, state);
|
|
30
30
|
|
|
31
|
+
// disposer draes all internal elements
|
|
31
32
|
el[_dispose] = () => {
|
|
32
33
|
while (disposes.length) disposes.pop()();
|
|
33
34
|
memo.delete(el);
|
|
@@ -84,7 +85,7 @@ const parse = (expr, dir, fn) => {
|
|
|
84
85
|
|
|
85
86
|
export let compile
|
|
86
87
|
|
|
87
|
-
// configure signals/compile
|
|
88
|
+
// configure signals/compile
|
|
88
89
|
// it's more compact than using sprae.signal = signal etc.
|
|
89
90
|
sprae.use = s => {
|
|
90
91
|
s.signal && use(s);
|
package/directive/each.js
CHANGED
|
@@ -80,8 +80,8 @@ directive.each = (tpl, [itemVar, idxVar, evaluate], state) => {
|
|
|
80
80
|
|
|
81
81
|
let planned = 0
|
|
82
82
|
return effect(() => {
|
|
83
|
-
// subscribe to items change (.length)
|
|
84
|
-
|
|
83
|
+
// subscribe to items change (.length) - we do it every time (not just on init) since preact unsubscribes unused signals
|
|
84
|
+
items.value[_change]?.value
|
|
85
85
|
|
|
86
86
|
// make first render immediately, debounce subsequent renders
|
|
87
87
|
if (!planned) {
|
package/dist/sprae.js
CHANGED
|
@@ -34,7 +34,7 @@ function store(values) {
|
|
|
34
34
|
const state = new Proxy(signals, {
|
|
35
35
|
get: (_, key) => key === _change ? _len : key === _signals ? signals : signals[key]?.valueOf(),
|
|
36
36
|
set: (_, key, v, s) => (s = signals[key], set(signals, key, v), s || ++_len.value),
|
|
37
|
-
deleteProperty: (_, key) => del(signals, key)
|
|
37
|
+
deleteProperty: (_, key) => (signals[key] && (del(signals, key), _len.value--), 1),
|
|
38
38
|
ownKeys() {
|
|
39
39
|
_len.value;
|
|
40
40
|
return Reflect.ownKeys(signals);
|
|
@@ -58,10 +58,8 @@ function list(values) {
|
|
|
58
58
|
let _len = signal(values.length), signals = Array(values.length).fill(null);
|
|
59
59
|
const state = new Proxy(signals, {
|
|
60
60
|
get(_, key) {
|
|
61
|
-
if (key ===
|
|
62
|
-
return _len;
|
|
63
|
-
if (key === _signals)
|
|
64
|
-
return signals;
|
|
61
|
+
if (typeof key === "symbol")
|
|
62
|
+
return key === _change ? _len : key === _signals ? signals : signals[key];
|
|
65
63
|
if (key === "length")
|
|
66
64
|
return Array.prototype[lastProp] ? _len.peek() : _len.value;
|
|
67
65
|
lastProp = key;
|
|
@@ -82,7 +80,7 @@ function list(values) {
|
|
|
82
80
|
_len.value = signals.length = Number(key) + 1;
|
|
83
81
|
return true;
|
|
84
82
|
},
|
|
85
|
-
deleteProperty: (_, key) => (del(signals, key),
|
|
83
|
+
deleteProperty: (_, key) => (signals[key] && del(signals, key), 1)
|
|
86
84
|
});
|
|
87
85
|
return state;
|
|
88
86
|
}
|
|
@@ -113,15 +111,11 @@ function set(signals, key, v) {
|
|
|
113
111
|
}
|
|
114
112
|
}
|
|
115
113
|
function del(signals, key) {
|
|
116
|
-
const s = signals[key];
|
|
117
|
-
if (
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
delete signals[key];
|
|
122
|
-
del2?.();
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
114
|
+
const s = signals[key], del2 = s[Symbol.dispose];
|
|
115
|
+
if (del2)
|
|
116
|
+
delete s[Symbol.dispose];
|
|
117
|
+
delete signals[key];
|
|
118
|
+
del2?.();
|
|
125
119
|
}
|
|
126
120
|
|
|
127
121
|
// core.js
|
|
@@ -312,8 +306,7 @@ directive.each = (tpl, [itemVar, idxVar, evaluate], state) => {
|
|
|
312
306
|
};
|
|
313
307
|
let planned = 0;
|
|
314
308
|
return effect(() => {
|
|
315
|
-
|
|
316
|
-
items.value[_change]?.value;
|
|
309
|
+
items.value[_change]?.value;
|
|
317
310
|
if (!planned) {
|
|
318
311
|
update();
|
|
319
312
|
queueMicrotask(() => (planned && update(), planned = 0));
|
package/dist/sprae.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,t,r,l,n,s=Object.defineProperty,a=Symbol("signals"),o=Symbol("length");function i(t){if(!t)return t;if(t[a])return t;if(Array.isArray(t))return function(t){let r;if(t[a])return t;let l=e(t.length),n=Array(t.length).fill(null);const s=new Proxy(n,{get:(s,c)=>c===o?l:c===a?n:"length"===c?Array.prototype[r]?l.peek():l.value:(r=c,n[c]?n[c].valueOf():c<n.length?(n[c]=e(i(t[c]))).value:void 0),set(e,t,r){if("length"===t){for(let e=r,t=n.length;e<t;e++)delete s[e];return l.value=n.length=r,!0}return c(n,t,r),t>=l.peek()&&(l.value=n.length=Number(t)+1),!0},deleteProperty:(e,t)=>(u(n,t)
|
|
1
|
+
var e,t,r,l,n,s=Object.defineProperty,a=Symbol("signals"),o=Symbol("length");function i(t){if(!t)return t;if(t[a])return t;if(Array.isArray(t))return function(t){let r;if(t[a])return t;let l=e(t.length),n=Array(t.length).fill(null);const s=new Proxy(n,{get:(s,c)=>"symbol"==typeof c?c===o?l:c===a?n:n[c]:"length"===c?Array.prototype[r]?l.peek():l.value:(r=c,n[c]?n[c].valueOf():c<n.length?(n[c]=e(i(t[c]))).value:void 0),set(e,t,r){if("length"===t){for(let e=r,t=n.length;e<t;e++)delete s[e];return l.value=n.length=r,!0}return c(n,t,r),t>=l.peek()&&(l.value=n.length=Number(t)+1),!0},deleteProperty:(e,t)=>(n[t]&&u(n,t),1)});return s}(t);if(t.constructor!==Object)return t;let r={},l=e(Object.values(t).length);const s=new Proxy(r,{get:(e,t)=>t===o?l:t===a?r:r[t]?.valueOf(),set:(e,t,n,s)=>(s=r[t],c(r,t,n),s||++l.value),deleteProperty:(e,t)=>(r[t]&&(u(r,t),l.value--),1),ownKeys:()=>(l.value,Reflect.ownKeys(r))});for(let e in t){const l=Object.getOwnPropertyDescriptor(t,e);l?.get?(r[e]=n(l.get.bind(s)))._set=l.set?.bind(s):(r[e]=null,c(r,e,t[e]))}return s}function c(t,n,s){let a=t[n];if(a)if(s===a.peek());else if(a._set)a._set(s);else if(Array.isArray(s)&&Array.isArray(a.peek())){const e=a.peek();e[o]?r((()=>{l((()=>{let t=0,r=s.length;for(;t<r;t++)e[t]=s[t];e.length=r}))})):a.value=s}else a.value=i(s);else t[n]=a=s?.peek?s:e(i(s))}function u(e,t){const r=e[t],l=r[Symbol.dispose];l&&delete r[Symbol.dispose],delete e[t],l?.()}var f=Symbol.dispose||=Symbol("dispose"),p={},d=new WeakMap;function y(e,t){if(!e?.children)return;if(d.has(e))return Object.assign(d.get(e),t);const r=i(t||{}),l=[];return function e(t,n=t.parentNode){if(t.attributes)for(let e=0;e<t.attributes.length;){let s=t.attributes[e];if(":"===s.name[0]){t.removeAttribute(s.name);let e=s.name.slice(1).split(":");for(let n of e){let e=p[n]||p.default,a=e(t,(e.parse||b)(s.value,b),r,n);a&&l.push(a)}if(d.has(t))return l.push(t[f]);if(t.parentNode!==n)return}else e++}for(let r of[...t.children])e(r,t)}(e),d.has(e)||d.set(e,r),e[f]=()=>{for(;l.length;)l.pop()();d.delete(e)},r}var v,h={},b=(e,t,r)=>{if(r=h[e=e.trim()])return r;try{r=v(e)}catch(r){throw Object.assign(r,{message:`∴ ${r.message}\n\n${t}${e?`="${e}"\n\n`:""}`,expr:e})}return h[e]=r};y.use=s=>{s.signal&&function(s){e=s.signal,t=s.effect,n=s.computed,l=s.batch||(e=>e()),r=s.untracked||l}(s),s.compile&&(v=s.compile)};var g,m,k={};((e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})})(k,{batch:()=>O,computed:()=>w,effect:()=>S,signal:()=>A,untracked:()=>N});var A=(e,t,r=new Set)=>((t={get value(){return g?.deps.push(r.add(g)),e},set value(t){if(t!==e){e=t;for(let e of r)m?m.add(e):e()}},peek:()=>e}).toJSON=t.then=t.toString=t.valueOf=()=>t.value,t),S=(e,t,r,l)=>(l=(r=l=>{t?.call?.(),l=g,g=r;try{t=e()}finally{g=l}}).deps=[],r(),e=>{for(t?.call?.();e=l.pop();)e.delete(r)}),w=(e,t=A(),r,l)=>((r={get value(){return l||=S((()=>t.value=e())),t.value},peek:t.peek}).toJSON=r.then=r.toString=r.valueOf=()=>r.value,r),O=e=>{let t=m;t||(m=new Set);try{e()}finally{if(!t){t=m,m=null;for(const e of t)e()}}},N=(e,t,r)=>(t=g,g=null,r=e(),g=t,r),j=Symbol(":each");p.each=(e,[l,s,i],c)=>{const u=e[j]=document.createTextNode("");e.replaceWith(u);let f,p,d=0;const v=n((()=>{p=null;let e=i(c);return"number"==typeof e&&(e=Array.from({length:e},((e,t)=>t+1))),e?.constructor===Object&&(p=Object.keys(e),e=Object.values(e)),e||[]})),h=()=>{r((()=>{let t=0,r=v.value,n=r.length;if(f&&!f[o]){for(let e of f[a]||[])e[Symbol.dispose]();f=null,d=0}if(n<d)f.length=n;else{if(f)for(;t<d;t++)f[t]=r[t];else f=r;for(;t<n;t++){f[t]=r[t];let n=t,o=Object.create(c,{[l]:{get:()=>f[n]},[s]:{value:p?p[n]:n}}),i=(e.content||e).cloneNode(!0),d=e.content?{children:[...i.children],remove(){this.children.map((e=>e.remove()))}}:i;u.before(i),y(d,o),((f[a]||=[])[t]||={})[Symbol.dispose]=()=>{d[Symbol.dispose](),d.remove()}}}d=n}))};let b=0;return t((()=>{v.value[o]?.value,b?b++:(h(),queueMicrotask((()=>(b&&h(),b=0))))}))},p.each.parse=(e,t)=>{let[r,l]=e.split(/\s+in\s+/),[n,s="$"]=r.split(/\s*,\s*/);return[n,s,t(l)]};var x=Symbol("if");p.if=(e,r,l)=>{let n,s,a,o=e.parentNode,i=e.nextElementSibling,c=document.createTextNode(""),u=[];return e.after(c),e.content?(n=u,e.remove(),s=[...e.content.childNodes]):s=n=[e],i?.hasAttribute(":else")?(i.removeAttribute(":else"),i.hasAttribute(":if")?a=u:(i.remove(),a=i.content?[...i.content.childNodes]:[i])):a=u,t((()=>{const t=r(l)?s:e[x]?u:a;if(i&&(i[x]=t===s),n!=t){n[0]?.[j]&&(n=[n[0][j]]);for(let e of n)e.remove();n=t;for(let e of n)o.insertBefore(e,c),y(e,l)}}))},p.default=(e,r,l,n)=>{let s,a=n.startsWith("on")&&n.slice(2);return t(a?()=>(s?.(),s=$(e,a,r(l))):()=>{let t=r(l);if(n)T(e,n,D(t,l));else for(let r in t)T(e,_(r),D(t[r],l))})};var $=(e,t,r=(()=>{}))=>{const l={evt:"",target:e,test:()=>!0};l.evt=t.replace(/\.(\w+)?-?([-\w]+)?/g,((e,t,r="")=>(l.test=E[t]?.(l,...r.split("-"))||l.test,"")));const{evt:n,target:s,test:a,defer:o,stop:i,prevent:c,...u}=l;o&&(r=o(r));const f=e=>a(e)&&(i&&e.stopPropagation(),c&&e.preventDefault(),r.call(s,e));return s.addEventListener(n,f,u),()=>s.removeEventListener(n,f,u)},E={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=>C(e,t?Number(t)||0:108)},debounce(e,t){e.defer=e=>W(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=>P.ctrl(e)&&t.every((t=>P[t]?P[t](e):e.key===t)),shift:(e,...t)=>e=>P.shift(e)&&t.every((t=>P[t]?P[t](e):e.key===t)),alt:(e,...t)=>e=>P.alt(e)&&t.every((t=>P[t]?P[t](e):e.key===t)),meta:(e,...t)=>e=>P.meta(e)&&t.every((t=>P[t]?P[t](e):e.key===t)),arrow:()=>P.arrow,enter:()=>P.enter,escape:()=>P.escape,tab:()=>P.tab,space:()=>P.space,backspace:()=>P.backspace,delete:()=>P.delete,digit:()=>P.digit,letter:()=>P.letter,character:()=>P.character},P={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:"")},C=(e,t)=>{let r,l,n=s=>{r=!0,setTimeout((()=>{if(r=!1,l)return l=!1,n(s),e(s)}),t)};return t=>r?l=!0:(n(t),e(t))},W=(e,t)=>{let r;return l=>{clearTimeout(r),r=setTimeout((()=>{r=null,e(l)}),t)}},_=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]??"")):e;p.ref=(e,t,r)=>{Object.defineProperty(r,D(t,r),{value:e})},p.ref.parse=e=>e,p.with=(e,r,l)=>{let n;return t((()=>{let t=r(l);if(n)Object.assign(n,t);else{n=i({}),Object.assign(n[a],l[a]);for(let e in t)n[a][e]=null,n[e]=t[e];y(e,n)}}))},p.html=(e,t,r)=>{let l=t(r);if(!l)return;let n=(l.content||l).cloneNode(!0);e.replaceChildren(n),y(e,r)},p.text=(e,r,l)=>(e.content&&e.replaceWith(e=document.createTextNode("")),t((()=>{let t=r(l);e.textContent=null==t?"":t}))),p.class=(e,r,l)=>{let n=new Set;return t((()=>{let t=r(l),s=new Set;t&&("string"==typeof t?D(t,l).split(" ").map((e=>s.add(e))):Array.isArray(t)?t.map((e=>(e=D(e,l))&&s.add(e))):Object.entries(t).map((([e,t])=>t&&s.add(e))));for(let t of n)s.has(t)?s.delete(t):e.classList.remove(t);for(let t of n=s)e.classList.add(t)}))},p.style=(e,r,l)=>{let n=e.getAttribute("style")||"";return n.endsWith(";")||(n+="; "),t((()=>{let t=r(l);if("string"==typeof t)e.setAttribute("style",n+D(t,l));else{e.setAttribute("style",n);for(let r in t)e.style.setProperty(r,D(t[r],l))}}))},p.value=(e,r,l)=>{let n,s,a="text"===e.type||""===e.type?t=>e.setAttribute("value",e.value=null==t?"":t):"TEXTAREA"===e.tagName||"text"===e.type||""===e.type?t=>(n=e.selectionStart,s=e.selectionEnd,e.setAttribute("value",e.value=null==t?"":t),n&&e.setSelectionRange(n,s)):"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 t((()=>a(r(l))))},p.fx=(e,r,l)=>t((()=>r(l))),y.use(k),y.use({compile:e=>y.constructor("__scope",`with (__scope) { return ${e} };`)});var K=y;export{K as default};
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -407,14 +407,14 @@ npm ci
|
|
|
407
407
|
npm run build-prod
|
|
408
408
|
|
|
409
409
|
# bench
|
|
410
|
-
cd ../../../webdriver-ts
|
|
410
|
+
[cd ../../../webdriver-ts
|
|
411
411
|
npm ci
|
|
412
|
-
npm run compile
|
|
412
|
+
npm run compile]
|
|
413
413
|
npm run bench keyed/sprae
|
|
414
414
|
|
|
415
415
|
# show results
|
|
416
|
-
cd ../webdriver-ts-results
|
|
417
|
-
npm ci
|
|
416
|
+
[cd ../webdriver-ts-results
|
|
417
|
+
npm ci]
|
|
418
418
|
cd ../webdriver-ts
|
|
419
419
|
npm run results
|
|
420
420
|
```
|
package/store.js
CHANGED
|
@@ -23,7 +23,7 @@ export default function store(values) {
|
|
|
23
23
|
const state = new Proxy(signals, {
|
|
24
24
|
get: (_, key) => key === _change ? _len : key === _signals ? signals : signals[key]?.valueOf(),
|
|
25
25
|
set: (_, key, v, s) => (s = signals[key], set(signals, key, v), s || (++_len.value)), // bump length for new signal
|
|
26
|
-
deleteProperty: (_, key) => del(signals, key)
|
|
26
|
+
deleteProperty: (_, key) => (signals[key] && (del(signals, key), _len.value--), 1),
|
|
27
27
|
ownKeys() {
|
|
28
28
|
// subscribe to length when object is spread
|
|
29
29
|
_len.value
|
|
@@ -67,8 +67,8 @@ export function list(values) {
|
|
|
67
67
|
// proxy conducts prop access to signals
|
|
68
68
|
const state = new Proxy(signals, {
|
|
69
69
|
get(_, key) {
|
|
70
|
-
|
|
71
|
-
if (key ===
|
|
70
|
+
// covers Symbol.isConcatSpreadable etc.
|
|
71
|
+
if (typeof key === 'symbol') return key === _change ? _len : key === _signals ? signals : signals[key]
|
|
72
72
|
|
|
73
73
|
// console.log('get', key)
|
|
74
74
|
// if .length is read within .push/etc - peek signal to avoid recursive subscription
|
|
@@ -83,10 +83,12 @@ export function list(values) {
|
|
|
83
83
|
},
|
|
84
84
|
|
|
85
85
|
set(_, key, v) {
|
|
86
|
+
// console.log('set', key, v)
|
|
86
87
|
// .length
|
|
87
88
|
if (key === 'length') {
|
|
88
89
|
// force cleaning up tail
|
|
89
90
|
for (let i = v, l = signals.length; i < l; i++) delete state[i]
|
|
91
|
+
// .length = N directly
|
|
90
92
|
_len.value = signals.length = v;
|
|
91
93
|
return true
|
|
92
94
|
}
|
|
@@ -99,7 +101,7 @@ export function list(values) {
|
|
|
99
101
|
return true
|
|
100
102
|
},
|
|
101
103
|
|
|
102
|
-
deleteProperty: (_, key) => (del(signals, key),
|
|
104
|
+
deleteProperty: (_, key) => (signals[key] && del(signals, key), 1),
|
|
103
105
|
|
|
104
106
|
})
|
|
105
107
|
|
|
@@ -142,13 +144,8 @@ function set(signals, key, v) {
|
|
|
142
144
|
|
|
143
145
|
// delete signal
|
|
144
146
|
function del(signals, key) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
if (del) delete s[Symbol.dispose]
|
|
150
|
-
delete signals[key]
|
|
151
|
-
del?.()
|
|
152
|
-
return true
|
|
153
|
-
}
|
|
147
|
+
const s = signals[key], del = s[Symbol.dispose]
|
|
148
|
+
if (del) delete s[Symbol.dispose]
|
|
149
|
+
delete signals[key]
|
|
150
|
+
del?.()
|
|
154
151
|
}
|