sprae 10.1.3 → 10.1.5

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 CHANGED
@@ -76,13 +76,18 @@ const parse = (expr, dir, fn) => {
76
76
  if (fn = evalMemo[expr = expr.trim()]) return fn
77
77
 
78
78
  // static-time errors
79
- try { fn = compile(expr); }
80
- catch (e) { throw Object.assign(e, { message: `∴ ${e.message}\n\n${dir}${expr ? `="${expr}"\n\n` : ""}`, expr }) }
79
+ try { fn = compile(expr) }
80
+ catch (e) { err(e, dir, expr) }
81
81
 
82
82
  // runtime errors
83
83
  return evalMemo[expr] = fn
84
84
  }
85
85
 
86
+ // wrapped call
87
+ export let err = (e, dir, expr = '') => {
88
+ throw Object.assign(e, { message: `∴ ${e.message}\n\n${dir}${expr ? `="${expr}"\n\n` : ""}`, expr })
89
+ }
90
+
86
91
  export let compile
87
92
 
88
93
  // configure signals/compile
@@ -1,4 +1,4 @@
1
- import { directive } from "../core.js";
1
+ import { directive, err } from "../core.js";
2
2
  import { effect } from "../signal.js";
3
3
 
4
4
  // set generic property directive
@@ -20,7 +20,7 @@ directive.default = (el, evaluate, state, name) => {
20
20
 
21
21
  // bind event to a target
22
22
  const on = (el, e, fn = () => { }) => {
23
- const ctx = { evt: "", target: el, test: () => true };
23
+ const ctx = { evt: '', target: el, test: () => true };
24
24
 
25
25
  // onevt.debounce-108 -> evt.debounce-108
26
26
  ctx.evt = e.replace(
@@ -33,8 +33,11 @@ const on = (el, e, fn = () => { }) => {
33
33
 
34
34
  if (defer) fn = defer(fn);
35
35
 
36
- const cb = (e) =>
37
- test(e) && (stop && e.stopPropagation(), prevent && e.preventDefault(), fn.call(target, e));
36
+ const cb = (e) => {
37
+ try {
38
+ test(e) && (stop && e.stopPropagation(), prevent && e.preventDefault(), fn.call(target, e))
39
+ } catch (error) { err(error, `:on${evt}`, fn) }
40
+ };
38
41
 
39
42
  target.addEventListener(evt, cb, opts);
40
43
 
package/directive/each.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import sprae, { directive } from "../core.js";
2
2
  import store, { _change, _signals } from "../store.js";
3
- import { effect, untracked, computed, signal } from '../signal.js';
3
+ import { effect, untracked, computed } from '../signal.js';
4
4
 
5
5
 
6
6
  export const _each = Symbol(":each");
@@ -54,19 +54,16 @@ directive.each = (tpl, [itemVar, idxVar, evaluate], state) => {
54
54
  for (; i < newl; i++) {
55
55
  cur[i] = newItems[i]
56
56
  let idx = i,
57
- scope = store({}),
57
+ scope = store({
58
+ [itemVar]: cur[_signals]?.[idx] || cur[idx],
59
+ [idxVar]: keys ? keys[idx] : idx
60
+ }, state),
58
61
  el = (tpl.content || tpl).cloneNode(true),
59
62
  frag = tpl.content ?
60
- // fake fragment to init sprae
63
+ // fake fragment to allow sprae multiple elements
61
64
  { children: [...el.children], remove() { this.children.map(el => el.remove()) } } :
62
65
  el;
63
66
 
64
- // define local scope signals
65
- Object.assign(scope[_signals], state[_signals], {
66
- [itemVar]: computed(() => cur[idx]),
67
- [idxVar]: signal(keys ? keys[idx] : idx)
68
- });
69
-
70
67
  holder.before(el);
71
68
  sprae(frag, scope);
72
69
 
package/directive/ref.js CHANGED
@@ -1,11 +1,10 @@
1
- import { signal } from "../signal.js";
2
1
  import { directive } from "../core.js";
3
2
  import { _change, _signals } from "../store.js";
4
3
  import { ipol } from './default.js';
5
4
 
6
5
  // ref must be last within primaries, since that must be skipped by :each, but before secondaries
7
6
  directive.ref = (el, expr, state) => {
8
- state[_signals][ipol(expr, state)] = signal(el)
7
+ state[ipol(expr, state)] = el
9
8
  }
10
9
 
11
10
  directive.ref.parse = expr => expr
package/directive/with.js CHANGED
@@ -1,24 +1,11 @@
1
1
  import sprae, { directive } from "../core.js";
2
2
  import store, { _signals } from '../store.js';
3
3
  import { effect } from "../signal.js";
4
- import { signal } from "ulive";
5
4
 
6
5
  directive.with = (el, evaluate, rootState) => {
7
6
  let state
8
7
  return effect(() => {
9
8
  let values = evaluate(rootState);
10
-
11
- if (!state) {
12
- state = store({});
13
- // inherit root signals
14
- Object.assign(state[_signals], rootState[_signals]);
15
- // create local scope signals
16
- for (let key in values) state[_signals][key] = null, state[key] = values[key]
17
-
18
- sprae(el, state)
19
- }
20
- else {
21
- Object.assign(state, values)
22
- }
9
+ sprae(el, state ? values : state = store(values, rootState))
23
10
  })
24
11
  };
package/dist/sprae.js CHANGED
@@ -21,7 +21,7 @@ function use(s) {
21
21
  // store.js
22
22
  var _signals = Symbol("signals");
23
23
  var _change = Symbol("length");
24
- function store(values) {
24
+ function store(values, parent) {
25
25
  if (!values)
26
26
  return values;
27
27
  if (values[_signals])
@@ -30,7 +30,7 @@ function store(values) {
30
30
  return list(values);
31
31
  if (values.constructor !== Object)
32
32
  return values;
33
- let signals = {}, _len = signal(Object.values(values).length);
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
36
  set: (_, key, v, s) => (s = signals[key], set(signals, key, v), s || ++_len.value),
@@ -51,6 +51,7 @@ function store(values) {
51
51
  }
52
52
  return state;
53
53
  }
54
+ var mut = { push: 1, pop: 1, shift: 1, unshift: 1, splice: 1 };
54
55
  function list(values) {
55
56
  let lastProp;
56
57
  if (values[_signals])
@@ -61,7 +62,7 @@ function list(values) {
61
62
  if (typeof key === "symbol")
62
63
  return key === _change ? _len : key === _signals ? signals : signals[key];
63
64
  if (key === "length")
64
- return Array.prototype[lastProp] ? _len.peek() : _len.value;
65
+ return mut[lastProp] ? _len.peek() : _len.value;
65
66
  lastProp = key;
66
67
  if (signals[key])
67
68
  return signals[key].valueOf();
@@ -172,13 +173,16 @@ var parse = (expr, dir, fn) => {
172
173
  try {
173
174
  fn = compile(expr);
174
175
  } catch (e) {
175
- throw Object.assign(e, { message: `\u2234 ${e.message}
176
+ err(e, dir, expr);
177
+ }
178
+ return evalMemo[expr] = fn;
179
+ };
180
+ var err = (e, dir, expr = "") => {
181
+ throw Object.assign(e, { message: `\u2234 ${e.message}
176
182
 
177
183
  ${dir}${expr ? `="${expr}"
178
184
 
179
185
  ` : ""}`, expr });
180
- }
181
- return evalMemo[expr] = fn;
182
186
  };
183
187
  var compile;
184
188
  sprae.use = (s) => {
@@ -286,13 +290,12 @@ directive.each = (tpl, [itemVar, idxVar, evaluate], state) => {
286
290
  }
287
291
  for (; i < newl; i++) {
288
292
  cur[i] = newItems[i];
289
- let idx = i, scope = store({}), el = (tpl.content || tpl).cloneNode(true), frag = tpl.content ? { children: [...el.children], remove() {
293
+ let idx = i, scope = store({
294
+ [itemVar]: cur[_signals]?.[idx] || cur[idx],
295
+ [idxVar]: keys2 ? keys2[idx] : idx
296
+ }, state), el = (tpl.content || tpl).cloneNode(true), frag = tpl.content ? { children: [...el.children], remove() {
290
297
  this.children.map((el2) => el2.remove());
291
298
  } } : el;
292
- Object.assign(scope[_signals], state[_signals], {
293
- [itemVar]: computed(() => cur[idx]),
294
- [idxVar]: signal(keys2 ? keys2[idx] : idx)
295
- });
296
299
  holder.before(el);
297
300
  sprae(frag, scope);
298
301
  ((cur[_signals] ||= [])[i] ||= {})[Symbol.dispose] = () => {
@@ -376,7 +379,13 @@ var on = (el, e, fn = () => {
376
379
  const { evt, target, test, defer, stop, prevent, ...opts } = ctx;
377
380
  if (defer)
378
381
  fn = defer(fn);
379
- const cb = (e2) => test(e2) && (stop && e2.stopPropagation(), prevent && e2.preventDefault(), fn.call(target, e2));
382
+ const cb = (e2) => {
383
+ try {
384
+ test(e2) && (stop && e2.stopPropagation(), prevent && e2.preventDefault(), fn.call(target, e2));
385
+ } catch (error) {
386
+ err(error, `:on${evt}`, fn);
387
+ }
388
+ };
380
389
  target.addEventListener(evt, cb, opts);
381
390
  return () => target.removeEventListener(evt, cb, opts);
382
391
  };
@@ -491,7 +500,7 @@ var ipol = (v, state) => {
491
500
 
492
501
  // directive/ref.js
493
502
  directive.ref = (el, expr, state) => {
494
- state[_signals][ipol(expr, state)] = signal(el);
503
+ state[ipol(expr, state)] = el;
495
504
  };
496
505
  directive.ref.parse = (expr) => expr;
497
506
 
@@ -500,15 +509,7 @@ directive.with = (el, evaluate, rootState) => {
500
509
  let state;
501
510
  return effect(() => {
502
511
  let values = evaluate(rootState);
503
- if (!state) {
504
- state = store({});
505
- Object.assign(state[_signals], rootState[_signals]);
506
- for (let key in values)
507
- state[_signals][key] = null, state[key] = values[key];
508
- sprae(el, state);
509
- } else {
510
- Object.assign(state, values);
511
- }
512
+ sprae(el, state ? values : state = store(values, rootState));
512
513
  });
513
514
  };
514
515
 
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)=>"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||g)(s.value,g),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={},g=(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 m,b,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 m?.deps.push(r.add(m)),e},set value(t){if(t!==e){e=t;for(let e of r)b?b.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=m,m=r;try{t=e()}finally{m=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=b;t||(b=new Set);try{e()}finally{if(!t){t=b,b=null;for(const e of t)e()}}},N=(e,t,r)=>(t=m,m=null,r=e(),m=t,r),x=Symbol(":each");p.each=(l,[s,c,u],f)=>{const p=l[x]=document.createTextNode("");l.replaceWith(p);let d,v,h=0;const g=n((()=>{v=null;let e=u(f);return"number"==typeof e&&(e=Array.from({length:e},((e,t)=>t+1))),e?.constructor===Object&&(v=Object.keys(e),e=Object.values(e)),e||[]})),m=()=>{r((()=>{let t=0,r=g.value,u=r.length;if(d&&!d[o]){for(let e of d[a]||[])e[Symbol.dispose]();d=null,h=0}if(u<h)d.length=u;else{if(d)for(;t<h;t++)d[t]=r[t];else d=r;for(;t<u;t++){d[t]=r[t];let o=t,u=i({}),h=(l.content||l).cloneNode(!0),g=l.content?{children:[...h.children],remove(){this.children.map((e=>e.remove()))}}:h;Object.assign(u[a],f[a],{[s]:n((()=>d[o])),[c]:e(v?v[o]:o)}),p.before(h),y(g,u),((d[a]||=[])[t]||={})[Symbol.dispose]=()=>{g[Symbol.dispose](),g.remove()}}}h=u}))};let b=0;return t((()=>{g.value[o]?.value,b?b++:(m(),queueMicrotask((()=>(b&&m(),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 j=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[j]?u:a;if(i&&(i[j]=t===s),n!=t){n[0]?.[x]&&(n=[n[0][x]]);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)C(e,n,D(t,l));else for(let r in t)C(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=>P(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=>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,escape:()=>T.escape,tab:()=>T.tab,space:()=>T.space,backspace:()=>T.backspace,delete:()=>T.delete,digit:()=>T.digit,letter:()=>T.letter,character:()=>T.character},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,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)},C=(e,t,r)=>{null==r||!1===r?e.removeAttribute(t):e.setAttribute(t,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},P=(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=(t,r,l)=>{l[a][D(r,l)]=e(t)},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,C(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};
1
+ var e,t,r,l,n,s=Object.defineProperty,a=Symbol("signals"),o=Symbol("length");function i(t,r){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,u)=>"symbol"==typeof u?u===o?l:u===a?n:n[u]:"length"===u?c[r]?l.peek():l.value:(r=u,n[u]?n[u].valueOf():u<n.length?(n[u]=e(i(t[u]))).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 u(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?.[a]},s=e(Object.values(t).length);const p=new Proxy(l,{get:(e,t)=>t===o?s:t===a?l:l[t]?.valueOf(),set:(e,t,r,n)=>(n=l[t],u(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]=null,u(l,e,t[e]))}return p}var c={push:1,pop:1,shift:1,unshift:1,splice:1};function u(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 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,a=e(t,(e.parse||g)(s.value,g),r,n);a&&l.push(a)}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 v,m={},g=(e,t,r)=>{if(r=m[e=e.trim()])return r;try{r=v(e)}catch(r){b(r,t,e)}return m[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&&(v=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,c],u)=>{const f=e[j]=document.createTextNode("");e.replaceWith(f);let p,d,y=0;const v=n((()=>{d=null;let e=c(u);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||[]})),m=()=>{r((()=>{let t=0,r=v.value,n=r.length;if(p&&!p[o]){for(let e of p[a]||[])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,o=i({[l]:p[a]?.[n]||p[n],[s]:d?d[n]:n},u),c=(e.content||e).cloneNode(!0),y=e.content?{children:[...c.children],remove(){this.children.map((e=>e.remove()))}}:c;f.before(c),h(y,o),((p[a]||=[])[t]||={})[Symbol.dispose]=()=>{y[Symbol.dispose](),y.remove()}}}y=n}))};let g=0;return t((()=>{v.value[o]?.value,g?g++:(m(),queueMicrotask((()=>(g&&m(),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,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[E]?u:a;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)o.insertBefore(e,c),h(e,l)}}))},d.default=(e,r,l,n)=>{let s,a=n.startsWith("on")&&n.slice(2);return t(a?()=>(s?.(),s=T(e,a,r(l))):()=>{let t=r(l);if(n)W(e,n,L(t,l));else for(let r in t)W(e,K(r),L(t[r],l))})};var T=(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:n,target:s,test:a,defer:o,stop:i,prevent:c,...u}=l;o&&(r=o(r));const f=e=>{try{a(e)&&(i&&e.stopPropagation(),c&&e.preventDefault(),r.call(s,e))}catch(e){b(e,`:on${n}`,r)}};return s.addEventListener(n,f,u),()=>s.removeEventListener(n,f,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=>D(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)},W=(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,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))},D=(e,t)=>{let r;return l=>{clearTimeout(r),r=setTimeout((()=>{r=null,e(l)}),t)}},K=e=>e.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(e=>"-"+e.toLowerCase())),L=(e,t)=>e?.replace?e.replace(/\$<([^>]+)>/g,((e,r)=>t[r]??"")):e;d.ref=(e,t,r)=>{r[L(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?L(t,l).split(" ").map((e=>s.add(e))):Array.isArray(t)?t.map((e=>(e=L(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+L(t,l));else{e.setAttribute("style",n);for(let r in t)e.style.setProperty(r,L(t[r],l))}}))},d.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,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((()=>a(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 M=h;export{M as default};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sprae",
3
3
  "description": "DOM microhydration.",
4
- "version": "10.1.3",
4
+ "version": "10.1.5",
5
5
  "main": "./sprae.js",
6
6
  "module": "./sprae.js",
7
7
  "type": "module",
package/store.js CHANGED
@@ -4,7 +4,7 @@ import { signal, computed, effect, batch, untracked } from './signal.js'
4
4
  export const _signals = Symbol('signals'), _change = Symbol('length');
5
5
 
6
6
  // object store is not lazy
7
- export default function store(values) {
7
+ export default function store(values, parent) {
8
8
  if (!values) return values
9
9
 
10
10
  // ignore existing state as argument
@@ -17,7 +17,7 @@ export default function store(values) {
17
17
  if (values.constructor !== Object) return values;
18
18
 
19
19
  // NOTE: if you decide to unlazy values, think about large arrays - init upfront can be costly
20
- let signals = {}, _len = signal(Object.values(values).length)
20
+ let signals = { ...parent?.[_signals] }, _len = signal(Object.values(values).length)
21
21
 
22
22
  // proxy conducts prop access to signals
23
23
  const state = new Proxy(signals, {
@@ -50,6 +50,8 @@ export default function store(values) {
50
50
  return state
51
51
  }
52
52
 
53
+ // length mutator methods
54
+ const mut = { push: 1, pop: 1, shift: 1, unshift: 1, splice: 1 }
53
55
 
54
56
  // array store - signals are lazy since arrays can be very large & expensive
55
57
  export function list(values) {
@@ -72,7 +74,9 @@ export function list(values) {
72
74
 
73
75
  // console.log('get', key)
74
76
  // if .length is read within .push/etc - peek signal to avoid recursive subscription
75
- if (key === 'length') return (Array.prototype[lastProp]) ? _len.peek() : _len.value;
77
+ // FIXME: is there a better way to maybe to detect writing .length by an array method and ignoring reactions?
78
+ // maybe somethign via batching?
79
+ if (key === 'length') return mut[lastProp] ? _len.peek() : _len.value;
76
80
 
77
81
  lastProp = key;
78
82