sprae 10.4.1 → 10.6.0
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/directive/default.js +1 -8
- package/dist/sprae.js +6 -12
- package/dist/sprae.min.js +1 -1
- package/package.json +1 -1
- package/readme.md +31 -21
- package/store.js +7 -5
package/directive/default.js
CHANGED
|
@@ -88,11 +88,8 @@ const mods = {
|
|
|
88
88
|
shift: (_, ...param) => (e) => keys.shift(e) && param.every((p) => (keys[p] ? keys[p](e) : e.key === p)),
|
|
89
89
|
alt: (_, ...param) => (e) => keys.alt(e) && param.every((p) => (keys[p] ? keys[p](e) : e.key === p)),
|
|
90
90
|
meta: (_, ...param) => (e) => keys.meta(e) && param.every((p) => (keys[p] ? keys[p](e) : e.key === p)),
|
|
91
|
+
// NOTE: we don't expose up/left/right/down as too verbose: can and better be handled/differentiated at once
|
|
91
92
|
arrow: () => keys.arrow,
|
|
92
|
-
up: () => keys.up,
|
|
93
|
-
left: () => keys.left,
|
|
94
|
-
right: () => keys.right,
|
|
95
|
-
down: () => keys.down,
|
|
96
93
|
enter: () => keys.enter,
|
|
97
94
|
esc: () => keys.esc,
|
|
98
95
|
tab: () => keys.tab,
|
|
@@ -110,10 +107,6 @@ const keys = {
|
|
|
110
107
|
alt: (e) => e.altKey || e.key === "Alt",
|
|
111
108
|
meta: (e) => e.metaKey || e.key === "Meta" || e.key === "Command",
|
|
112
109
|
arrow: (e) => e.key.startsWith("Arrow"),
|
|
113
|
-
up: (e) => e.key === "ArrowUp",
|
|
114
|
-
left: (e) => e.key === "ArrowLeft",
|
|
115
|
-
right: (e) => e.key === "ArrowRight",
|
|
116
|
-
down: (e) => e.key === "ArrowDown",
|
|
117
110
|
enter: (e) => e.key === "Enter",
|
|
118
111
|
esc: (e) => e.key.startsWith("Esc"),
|
|
119
112
|
tab: (e) => e.key === "Tab",
|
package/dist/sprae.js
CHANGED
|
@@ -33,7 +33,7 @@ function store(values, parent) {
|
|
|
33
33
|
let signals = { ...parent?.[_signals] }, _len = signal(Object.values(values).length);
|
|
34
34
|
const state = new Proxy(signals, {
|
|
35
35
|
get: (_, key) => key === _change ? _len : key === _signals ? signals : signals[key]?.valueOf(),
|
|
36
|
-
set: (_, key, v, s) => (s = signals[key], set(signals, key, v), s
|
|
36
|
+
set: (_, key, v, s) => (s = signals[key], set(signals, key, v), s ?? ++_len.value),
|
|
37
37
|
deleteProperty: (_, key) => (signals[key] && (del(signals, key), _len.value--), 1),
|
|
38
38
|
ownKeys() {
|
|
39
39
|
_len.value;
|
|
@@ -45,7 +45,7 @@ function store(values, parent) {
|
|
|
45
45
|
if (desc?.get) {
|
|
46
46
|
(signals[key] = computed(desc.get.bind(state)))._set = desc.set?.bind(state);
|
|
47
47
|
} else {
|
|
48
|
-
signals[key] =
|
|
48
|
+
signals[key] = void 0;
|
|
49
49
|
set(signals, key, values[key]);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -56,7 +56,7 @@ function list(values) {
|
|
|
56
56
|
let lastProp;
|
|
57
57
|
if (values[_signals])
|
|
58
58
|
return values;
|
|
59
|
-
let _len = signal(values.length), signals = Array(values.length).fill(
|
|
59
|
+
let _len = signal(values.length), signals = Array(values.length).fill();
|
|
60
60
|
const state = new Proxy(signals, {
|
|
61
61
|
get(_, key) {
|
|
62
62
|
if (typeof key === "symbol")
|
|
@@ -87,7 +87,9 @@ function list(values) {
|
|
|
87
87
|
}
|
|
88
88
|
function set(signals, key, v) {
|
|
89
89
|
let s = signals[key];
|
|
90
|
-
if (
|
|
90
|
+
if (key[0] === "_")
|
|
91
|
+
signals[key] = v;
|
|
92
|
+
else if (!s) {
|
|
91
93
|
signals[key] = s = v?.peek ? v : signal(store(v));
|
|
92
94
|
} else if (v === s.peek())
|
|
93
95
|
;
|
|
@@ -443,10 +445,6 @@ var mods = {
|
|
|
443
445
|
alt: (_, ...param) => (e) => keys.alt(e) && param.every((p) => keys[p] ? keys[p](e) : e.key === p),
|
|
444
446
|
meta: (_, ...param) => (e) => keys.meta(e) && param.every((p) => keys[p] ? keys[p](e) : e.key === p),
|
|
445
447
|
arrow: () => keys.arrow,
|
|
446
|
-
up: () => keys.up,
|
|
447
|
-
left: () => keys.left,
|
|
448
|
-
right: () => keys.right,
|
|
449
|
-
down: () => keys.down,
|
|
450
448
|
enter: () => keys.enter,
|
|
451
449
|
esc: () => keys.esc,
|
|
452
450
|
tab: () => keys.tab,
|
|
@@ -462,10 +460,6 @@ var keys = {
|
|
|
462
460
|
alt: (e) => e.altKey || e.key === "Alt",
|
|
463
461
|
meta: (e) => e.metaKey || e.key === "Meta" || e.key === "Command",
|
|
464
462
|
arrow: (e) => e.key.startsWith("Arrow"),
|
|
465
|
-
up: (e) => e.key === "ArrowUp",
|
|
466
|
-
left: (e) => e.key === "ArrowLeft",
|
|
467
|
-
right: (e) => e.key === "ArrowRight",
|
|
468
|
-
down: (e) => e.key === "ArrowDown",
|
|
469
463
|
enter: (e) => e.key === "Enter",
|
|
470
464
|
esc: (e) => e.key.startsWith("Esc"),
|
|
471
465
|
tab: (e) => e.key === "Tab",
|
package/dist/sprae.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,t,r,l,n,
|
|
1
|
+
var e,t,r,l,n,s=Object.defineProperty,o=Symbol("signals"),a=Symbol("length");function i(t,r){if(!t)return t;if(t[o])return t;if(Array.isArray(t))return function(t){let r;if(t[o])return t;let l=e(t.length),n=Array(t.length).fill();const s=new Proxy(n,{get:(s,c)=>"symbol"==typeof c?c===a?l:c===o?n:n[c]:"length"===c?u[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]&&f(n,t),1)});return s}(t);if(t.constructor!==Object)return t;let l={...r?.[o]},s=e(Object.values(t).length);const p=new Proxy(l,{get:(e,t)=>t===a?s:t===o?l:l[t]?.valueOf(),set:(e,t,r,n)=>(n=l[t],c(l,t,r),n??++s.value),deleteProperty:(e,t)=>(l[t]&&(f(l,t),s.value--),1),ownKeys:()=>(s.value,Reflect.ownKeys(l))});for(let e in t){const r=Object.getOwnPropertyDescriptor(t,e);r?.get?(l[e]=n(r.get.bind(p)))._set=r.set?.bind(p):(l[e]=void 0,c(l,e,t[e]))}return p}var u={push:1,pop:1,shift:1,unshift:1,splice:1};function c(t,n,s){let o=t[n];if("_"===n[0])t[n]=s;else if(o)if(s===o.peek());else if(o._set)o._set(s);else if(Array.isArray(s)&&Array.isArray(o.peek())){const e=o.peek();e[a]?r((()=>{l((()=>{let t=0,r=s.length;for(;t<r;t++)e[t]=s[t];e.length=r}))})):o.value=s}else o.value=i(s);else t[n]=o=s?.peek?s:e(i(s))}function f(e,t){const r=e[t],l=r[Symbol.dispose];l&&delete r[Symbol.dispose],delete e[t],l?.()}var p=Symbol.dispose||=Symbol("dispose"),d={},y=new WeakMap;function h(e,t){if(!e?.children)return;if(y.has(e))return Object.assign(y.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=d[n]||d.default,o=e(t,(e.parse||g)(s.value,g),r,n);o&&l.push(o)}if(y.has(t))return l.push(t[p]);if(t.parentNode!==n)return}else e++}for(let r of[...t.children])e(r,t)}(e),y.has(e)||y.set(e,r),e[p]=()=>{for(;l.length;)l.pop()();y.delete(e)},r}var m,v={},g=(e,t,r)=>{if(r=v[e=e.trim()])return r;try{r=m(e)}catch(r){b(r,t,e)}return v[e]=r},b=(e,t,r="")=>{throw Object.assign(e,{message:`∴ ${e.message}\n\n${t}${r?`="${r}"\n\n`:""}`,expr:r})};h.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&&(m=s.compile)};var k,A,S={};((e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})})(S,{batch:()=>x,computed:()=>N,effect:()=>O,signal:()=>w,untracked:()=>$});var w=(e,t,r=new Set)=>((t={get value(){return k?.deps.push(r.add(k)),e},set value(t){if(t!==e){e=t;for(let e of r)A?A.add(e):e()}},peek:()=>e}).toJSON=t.then=t.toString=t.valueOf=()=>t.value,t),O=(e,t,r,l)=>(l=(r=l=>{t?.call?.(),l=k,k=r;try{t=e()}finally{k=l}}).deps=[],r(),e=>{for(t?.call?.();e=l.pop();)e.delete(r)}),N=(e,t=w(),r,l)=>((r={get value(){return l||=O((()=>t.value=e())),t.value},peek:t.peek}).toJSON=r.then=r.toString=r.valueOf=()=>r.value,r),x=e=>{let t=A;t||(A=new Set);try{e()}finally{if(!t){t=A,A=null;for(const e of t)e()}}},$=(e,t,r)=>(t=k,k=null,r=e(),k=t,r),j=Symbol(":each");d.each=(e,[l,s,u],c)=>{const f=e[j]=document.createTextNode("");e.replaceWith(f);let p,d,y=0;const m=n((()=>{d=null;let e=u(c);return"number"==typeof e&&(e=Array.from({length:e},((e,t)=>t+1))),e?.constructor===Object&&(d=Object.keys(e),e=Object.values(e)),e||[]})),v=()=>{r((()=>{let t=0,r=m.value,n=r.length;if(p&&!p[a]){for(let e of p[o]||[])e[Symbol.dispose]();p=null,y=0}if(n<y)p.length=n;else{if(p)for(;t<y;t++)p[t]=r[t];else p=r;for(;t<n;t++){p[t]=r[t];let n=t,a=i({[l]:p[o]?.[n]||p[n],[s]:d?d[n]:n},c),u=(e.content||e).cloneNode(!0),y=e.content?{children:[...u.children],remove(){this.children.map((e=>e.remove()))}}:u;f.before(u),h(y,a),((p[o]||=[])[t]||={})[Symbol.dispose]=()=>{y[Symbol.dispose](),y.remove()}}}y=n}))};let g=0;return t((()=>{m.value[a]?.value,g?g++:(v(),queueMicrotask((()=>(g&&v(),g=0))))}))},d.each.parse=(e,t)=>{let[r,l]=e.split(/\s+in\s+/),[n,s="$"]=r.split(/\s*,\s*/);return[n,s,t(l)]};var E=Symbol("if");d.if=(e,r,l)=>{let n,s,o,a=e.parentNode,i=e.nextElementSibling,u=document.createTextNode(""),c=[];return e.after(u),e.content?(n=c,e.remove(),s=[...e.content.childNodes]):s=n=[e],i?.hasAttribute(":else")?(i.removeAttribute(":else"),i.hasAttribute(":if")?o=c:(i.remove(),o=i.content?[...i.content.childNodes]:[i])):o=c,t((()=>{const t=r(l)?s:e[E]?c:o;if(i&&(i[E]=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)a.insertBefore(e,u),h(e,l)}}))},d.default=(e,r,l,n)=>{if(!n.startsWith("on"))return t((()=>{let t=r(l);if(n)W(e,n,K(t,l));else for(let r in t)W(e,D(r),K(t[r],l))}));const s=n.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,l="")=>(r.test=P[t]?.(r,...l.split("-"))||r.test,""))),r}));if(1==s.length)return t((()=>f(r(l),s[0])));let o,a,i,u=0;const c=e=>{i=f((t=>(i(),a=e?.(t),(u=++u%s.length)?c(a):o&&c(o))),s[u])};return t((()=>(o=r(l),!i&&c(o),()=>o=null)));function f(e,{evt:t,target:r,test:l,defer:n,stop:s,prevent:o,immediate:a,...i}){n&&(e=n(e));const u=r=>{try{l(r)&&(s&&(a?r.stopImmediatePropagation():r.stopPropagation()),o&&r.preventDefault(),e?.(r))}catch(r){b(r,`:on${t}`,e)}};return r.addEventListener(t,u,i),()=>r.removeEventListener(t,u,i)}};var P={prevent(e){e.prevent=!0},stop(e){e.stop=!0},immediate(e){e.immediate=!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=>_(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=>T.ctrl(e)&&t.every((t=>T[t]?T[t](e):e.key===t)),shift:(e,...t)=>e=>T.shift(e)&&t.every((t=>T[t]?T[t](e):e.key===t)),alt:(e,...t)=>e=>T.alt(e)&&t.every((t=>T[t]?T[t](e):e.key===t)),meta:(e,...t)=>e=>T.meta(e)&&t.every((t=>T[t]?T[t](e):e.key===t)),arrow:()=>T.arrow,enter:()=>T.enter,esc:()=>T.esc,tab:()=>T.tab,space:()=>T.space,delete:()=>T.delete,digit:()=>T.digit,letter:()=>T.letter,char:()=>T.char},T={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,esc:e=>e.key.startsWith("Esc"),tab:e=>"Tab"===e.key,space:e=>" "===e.key||"Space"===e.key||" "===e.key,delete:e=>"Delete"===e.key||"Backspace"===e.key,digit:e=>/^\d$/.test(e.key),letter:e=>/^\p{L}$/gu.test(e.key),char:e=>/^\S$/.test(e.key)},W=(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))},_=(e,t)=>{let r;return l=>{clearTimeout(r),r=setTimeout((()=>{r=null,e(l)}),t)}},D=e=>e.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(e=>"-"+e.toLowerCase())),K=(e,t)=>e?.replace?e.replace(/\$<([^>]+)>/g,((e,r)=>t[r]??"")):e;d.ref=(e,t,r)=>{r[K(t,r)]=e},d.ref.parse=e=>e,d.with=(e,r,l)=>{let n;return t((()=>{let t=r(l);h(e,n?t:n=i(t,l))}))},d.html=(e,t,r)=>{let l=t(r);if(!l)return;let n=(l.content||l).cloneNode(!0);e.replaceChildren(n),h(e,r)},d.text=(e,r,l)=>(e.content&&e.replaceWith(e=document.createTextNode("")),t((()=>{let t=r(l);e.textContent=null==t?"":t}))),d.class=(e,r,l)=>{let n=new Set;return t((()=>{let t=r(l),s=new Set;t&&("string"==typeof t?K(t,l).split(" ").map((e=>s.add(e))):Array.isArray(t)?t.map((e=>(e=K(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)}))},d.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+K(t,l));else{e.setAttribute("style",n);for(let r in t)e.style.setProperty(r,K(t[r],l))}}))},d.value=(e,r,l)=>{let n,s,o="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,W(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((()=>o(r(l))))},d.fx=(e,r,l)=>t((()=>r(l))),h.use(S),h.use({compile:e=>h.constructor("__scope",`with (__scope) { return ${e} };`)});var L=h;export{L as default};
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# ∴ spræ [](https://github.com/dy/sprae/actions/workflows/node.js.yml) [](https://github.com/dy/sprae/actions/workflows/node.js.yml) [](https://bundlejs.com/?q=sprae) [](https://npmjs.org/sprae)
|
|
2
2
|
|
|
3
3
|
> DOM tree microhydration
|
|
4
4
|
|
|
@@ -197,32 +197,15 @@ Attach event(s) listener with optional modifiers.
|
|
|
197
197
|
* `.window`, `.document`, `.outside`, `.self` – specify event target.
|
|
198
198
|
* `.throttle-<ms>`, `.debounce-<ms>` – defer function call with one of the methods.
|
|
199
199
|
* `.<key>` – filtered by [`event.key`](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values):
|
|
200
|
-
* `.ctrl`, `.shift`, `.alt`, `.meta`, `.enter`, `.esc`, `.tab`, `.space
|
|
200
|
+
* `.ctrl`, `.shift`, `.alt`, `.meta`, `.enter`, `.esc`, `.tab`, `.space` – direct key
|
|
201
201
|
* `.delete` – delete or backspace
|
|
202
|
-
* `.arrow` – up, right, down or left
|
|
202
|
+
* `.arrow` – up, right, down or left arrow
|
|
203
203
|
* `.digit` – 0-9
|
|
204
204
|
* `.letter` – A-Z, a-z or any [unicode letter](https://unicode.org/reports/tr18/#General_Category_Property)
|
|
205
205
|
* `.char` – any non-space character
|
|
206
206
|
* `.ctrl-<key>, .alt-<key>, .meta-<key>, .shift-<key>` – key combinations, eg. `.ctrl-alt-delete` or `.meta-x`.
|
|
207
207
|
* `.*` – any other modifier has no effect, but allows binding multiple handlers to same event (like jQuery event classes).
|
|
208
208
|
|
|
209
|
-
#### `:html="element"` 🔌
|
|
210
|
-
|
|
211
|
-
> Include as `import 'sprae/directive/html'`.
|
|
212
|
-
|
|
213
|
-
Set html content of an element or instantiate a template.
|
|
214
|
-
|
|
215
|
-
```html
|
|
216
|
-
Hello, <span :html="userElement">Guest</span>.
|
|
217
|
-
|
|
218
|
-
<!-- fragment -->
|
|
219
|
-
Hello, <template :html="user.name">Guest</template>.
|
|
220
|
-
|
|
221
|
-
<!-- instantiate template -->
|
|
222
|
-
<template :ref="tpl"><span :text="foo"></span></template>
|
|
223
|
-
<div :html="tpl" :with="{foo:'bar'}">...inserted here...</div>
|
|
224
|
-
```
|
|
225
|
-
|
|
226
209
|
#### `:data="values"` 🔌
|
|
227
210
|
|
|
228
211
|
> Include as `import 'sprae/directive/data'`.
|
|
@@ -253,6 +236,24 @@ Set `aria-*` attributes. Boolean values are stringified.
|
|
|
253
236
|
-->
|
|
254
237
|
```
|
|
255
238
|
|
|
239
|
+
|
|
240
|
+
#### `:html="element"` 🔌 (experimental)
|
|
241
|
+
|
|
242
|
+
> Include as `import 'sprae/directive/html'`.
|
|
243
|
+
|
|
244
|
+
Set html content of an element or instantiate a template.
|
|
245
|
+
|
|
246
|
+
```html
|
|
247
|
+
Hello, <span :html="userElement">Guest</span>.
|
|
248
|
+
|
|
249
|
+
<!-- fragment -->
|
|
250
|
+
Hello, <template :html="user.name">Guest</template>.
|
|
251
|
+
|
|
252
|
+
<!-- instantiate template -->
|
|
253
|
+
<template :ref="tpl"><span :text="foo"></span></template>
|
|
254
|
+
<div :html="tpl" :with="{foo:'bar'}">...inserted here...</div>
|
|
255
|
+
```
|
|
256
|
+
|
|
256
257
|
<!--
|
|
257
258
|
#### `:onvisible..oninvisible="e => e => {}"`
|
|
258
259
|
|
|
@@ -300,8 +301,17 @@ Provider | Size | Feature
|
|
|
300
301
|
[`@webreflection/signal`](https://ghib.io/@webreflection/signal) | 531b | Class-based, better performance, good for small-medium states.
|
|
301
302
|
[`usignal`](https://ghib.io/usignal) | 850b | Class-based with optimizations, good for medium states.
|
|
302
303
|
[`@preact/signals-core`](https://ghub.io/@preact/signals-core) | 1.47kb | Best performance, good for any states, industry standard.
|
|
303
|
-
[`signal-polyfill`](https://github.com/
|
|
304
|
+
[`signal-polyfill`](https://github.com/proposal-signals/signal-polyfill) | 2.5kb | Proposal signals. Use via [adapter](https://gist.github.com/dy/bbac687464ccf5322ab0e2fd0680dc4d).
|
|
304
305
|
|
|
306
|
+
## Untracked
|
|
307
|
+
|
|
308
|
+
Properties prefixed with `_` indicate untracked value:
|
|
309
|
+
|
|
310
|
+
```js
|
|
311
|
+
let state = sprae(el, {x:1, _y:2})
|
|
312
|
+
state.x++ // updates template
|
|
313
|
+
state._y++ // no side-effect
|
|
314
|
+
```
|
|
305
315
|
|
|
306
316
|
## Evaluator
|
|
307
317
|
|
package/store.js
CHANGED
|
@@ -21,8 +21,8 @@ export default function store(values, parent) {
|
|
|
21
21
|
|
|
22
22
|
// proxy conducts prop access to signals
|
|
23
23
|
const state = new Proxy(signals, {
|
|
24
|
-
get: (_, key) => key === _change ? _len : key === _signals ? signals : signals[key]?.valueOf(),
|
|
25
|
-
set: (_, key, v, s) => (s = signals[key], set(signals, key, v), s
|
|
24
|
+
get: (_, key) => key === _change ? _len : key === _signals ? signals : (signals[key]?.valueOf()),
|
|
25
|
+
set: (_, key, v, s) => (s = signals[key], set(signals, key, v), s ?? (++_len.value)), // bump length for new signal
|
|
26
26
|
deleteProperty: (_, key) => (signals[key] && (del(signals, key), _len.value--), 1),
|
|
27
27
|
ownKeys() {
|
|
28
28
|
// subscribe to length when object is spread
|
|
@@ -42,7 +42,7 @@ export default function store(values, parent) {
|
|
|
42
42
|
}
|
|
43
43
|
else {
|
|
44
44
|
// init blank signal - make sure we don't take prototype one
|
|
45
|
-
signals[key] =
|
|
45
|
+
signals[key] = undefined
|
|
46
46
|
set(signals, key, values[key]);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
@@ -64,7 +64,7 @@ export function list(values) {
|
|
|
64
64
|
// .length signal is stored separately, since it cannot be replaced on array
|
|
65
65
|
let _len = signal(values.length),
|
|
66
66
|
// gotta fill with null since proto methods like .reduce may fail
|
|
67
|
-
signals = Array(values.length).fill(
|
|
67
|
+
signals = Array(values.length).fill();
|
|
68
68
|
|
|
69
69
|
// proxy conducts prop access to signals
|
|
70
70
|
const state = new Proxy(signals, {
|
|
@@ -114,8 +114,10 @@ export function list(values) {
|
|
|
114
114
|
function set(signals, key, v) {
|
|
115
115
|
let s = signals[key]
|
|
116
116
|
|
|
117
|
+
// untracked
|
|
118
|
+
if (key[0] === '_') signals[key] = v
|
|
117
119
|
// new property
|
|
118
|
-
if (!s) {
|
|
120
|
+
else if (!s) {
|
|
119
121
|
// preserve signal value as is
|
|
120
122
|
signals[key] = s = v?.peek ? v : signal(store(v))
|
|
121
123
|
}
|