sprae 10.11.0 → 10.12.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/dist/sprae.umd.js CHANGED
@@ -37,11 +37,9 @@ var init_signal = __esm({
37
37
  return v;
38
38
  },
39
39
  set value(val) {
40
- if (val === v)
41
- return;
40
+ if (val === v) return;
42
41
  v = val;
43
- for (let sub of obs)
44
- batched ? batched.add(sub) : sub();
42
+ for (let sub of obs) batched ? batched.add(sub) : sub();
45
43
  },
46
44
  peek() {
47
45
  return v;
@@ -57,8 +55,7 @@ var init_signal = __esm({
57
55
  }
58
56
  }, deps = fx.deps = [], fx(), (dep) => {
59
57
  teardown?.call?.();
60
- while (dep = deps.pop())
61
- dep.delete(fx);
58
+ while (dep = deps.pop()) dep.delete(fx);
62
59
  });
63
60
  computed = (fn, s = signal(), c, e) => (c = {
64
61
  get value() {
@@ -69,16 +66,14 @@ var init_signal = __esm({
69
66
  }, c.toJSON = c.then = c.toString = c.valueOf = () => c.value, c);
70
67
  batch = (fn) => {
71
68
  let fxs = batched;
72
- if (!fxs)
73
- batched = /* @__PURE__ */ new Set();
69
+ if (!fxs) batched = /* @__PURE__ */ new Set();
74
70
  try {
75
71
  fn();
76
72
  } finally {
77
73
  if (!fxs) {
78
74
  fxs = batched;
79
75
  batched = null;
80
- for (const fx of fxs)
81
- fx();
76
+ for (const fx of fxs) fx();
82
77
  }
83
78
  }
84
79
  };
@@ -88,18 +83,15 @@ var init_signal = __esm({
88
83
 
89
84
  // store.js
90
85
  function store(values, parent) {
91
- if (!values)
92
- return values;
93
- if (values[_signals])
94
- return values;
95
- if (Array.isArray(values))
96
- return list(values);
97
- if (values.constructor !== Object)
98
- return values;
86
+ if (!values) return values;
87
+ if (values[_signals]) return values;
88
+ if (Array.isArray(values)) return list(values);
89
+ if (values.constructor !== Object) return values;
99
90
  let signals = { ...parent?.[_signals] }, _len = signal(Object.values(values).length);
100
91
  const state = new Proxy(signals, {
101
92
  get: (_, key) => key === _change ? _len : key === _signals ? signals : signals[key]?.valueOf(),
102
93
  set: (_, key, v, s) => (s = signals[key], set(signals, key, v), s ?? ++_len.value, 1),
94
+ // bump length for new signal
103
95
  deleteProperty: (_, key) => (signals[key] && (del(signals, key), _len.value--), 1),
104
96
  ownKeys() {
105
97
  _len.value;
@@ -119,31 +111,24 @@ function store(values, parent) {
119
111
  }
120
112
  function list(values) {
121
113
  let lastProp;
122
- if (values[_signals])
123
- return values;
114
+ if (values[_signals]) return values;
124
115
  let _len = signal(values.length), signals = Array(values.length).fill();
125
116
  const state = new Proxy(signals, {
126
117
  get(_, key) {
127
- if (typeof key === "symbol")
128
- return key === _change ? _len : key === _signals ? signals : signals[key];
129
- if (key === "length")
130
- return mut[lastProp] ? _len.peek() : _len.value;
118
+ if (typeof key === "symbol") return key === _change ? _len : key === _signals ? signals : signals[key];
119
+ if (key === "length") return mut[lastProp] ? _len.peek() : _len.value;
131
120
  lastProp = key;
132
- if (signals[key])
133
- return signals[key].valueOf();
134
- if (key < signals.length)
135
- return (signals[key] = signal(store(values[key]))).value;
121
+ if (signals[key]) return signals[key].valueOf();
122
+ if (key < signals.length) return (signals[key] = signal(store(values[key]))).value;
136
123
  },
137
124
  set(_, key, v) {
138
125
  if (key === "length") {
139
- for (let i = v, l = signals.length; i < l; i++)
140
- delete state[i];
126
+ for (let i = v, l = signals.length; i < l; i++) delete state[i];
141
127
  _len.value = signals.length = v;
142
128
  return true;
143
129
  }
144
130
  set(signals, key, v);
145
- if (key >= _len.peek())
146
- _len.value = signals.length = Number(key) + 1;
131
+ if (key >= _len.peek()) _len.value = signals.length = Number(key) + 1;
147
132
  return true;
148
133
  },
149
134
  deleteProperty: (_, key) => (signals[key] && del(signals, key), 1)
@@ -152,25 +137,20 @@ function list(values) {
152
137
  }
153
138
  function set(signals, key, v) {
154
139
  let s = signals[key];
155
- if (key[0] === "_")
156
- signals[key] = v;
140
+ if (key[0] === "_") signals[key] = v;
157
141
  else if (!s) {
158
142
  signals[key] = s = v?.peek ? v : signal(store(v));
159
- } else if (v === s.peek())
160
- ;
161
- else if (s._set)
162
- s._set(v);
143
+ } else if (v === s.peek()) ;
144
+ else if (s._set) s._set(v);
163
145
  else if (Array.isArray(v) && Array.isArray(s.peek())) {
164
146
  const cur = s.peek();
165
- if (cur[_change])
166
- untracked(() => {
167
- batch(() => {
168
- let i = 0, l = v.length;
169
- for (; i < l; i++)
170
- cur[i] = v[i];
171
- cur.length = l;
172
- });
147
+ if (cur[_change]) untracked(() => {
148
+ batch(() => {
149
+ let i = 0, l = v.length;
150
+ for (; i < l; i++) cur[i] = v[i];
151
+ cur.length = l;
173
152
  });
153
+ });
174
154
  else {
175
155
  s.value = v;
176
156
  }
@@ -180,8 +160,7 @@ function set(signals, key, v) {
180
160
  }
181
161
  function del(signals, key) {
182
162
  const s = signals[key], del2 = s[Symbol.dispose];
183
- if (del2)
184
- delete s[Symbol.dispose];
163
+ if (del2) delete s[Symbol.dispose];
185
164
  delete signals[key];
186
165
  del2?.();
187
166
  }
@@ -197,24 +176,20 @@ var init_store = __esm({
197
176
 
198
177
  // core.js
199
178
  function sprae(el, values) {
200
- if (!el?.childNodes)
201
- return;
179
+ if (!el?.childNodes) return;
202
180
  if (memo.has(el)) {
203
181
  return Object.assign(memo.get(el), values);
204
182
  }
205
183
  const state = store(values || {}), disposes = [];
206
184
  init2(el);
207
- if (!memo.has(el))
208
- memo.set(el, state);
185
+ if (!memo.has(el)) memo.set(el, state);
209
186
  el[_dispose] = () => {
210
- while (disposes.length)
211
- disposes.pop()();
187
+ while (disposes.length) disposes.pop()();
212
188
  memo.delete(el);
213
189
  };
214
190
  return state;
215
191
  function init2(el2, parent = el2.parentNode) {
216
- if (!el2.childNodes)
217
- return;
192
+ if (!el2.childNodes) return;
218
193
  for (let i = 0; i < el2.attributes?.length; ) {
219
194
  let attr2 = el2.attributes[i];
220
195
  if (attr2.name[0] === ":") {
@@ -224,18 +199,13 @@ function sprae(el, values) {
224
199
  let dir = directive[name] || directive.default;
225
200
  let evaluate = (dir.parse || parse)(attr2.value);
226
201
  let dispose = dir(el2, evaluate, state, name);
227
- if (dispose)
228
- disposes.push(dispose);
202
+ if (dispose) disposes.push(dispose);
229
203
  }
230
- if (memo.has(el2))
231
- return el2[_dispose] && disposes.push(el2[_dispose]);
232
- if (el2.parentNode !== parent)
233
- return;
234
- } else
235
- i++;
204
+ if (memo.has(el2)) return el2[_dispose] && disposes.push(el2[_dispose]);
205
+ if (el2.parentNode !== parent) return;
206
+ } else i++;
236
207
  }
237
- for (let child of [...el2.childNodes])
238
- init2(child, el2);
208
+ for (let child of [...el2.childNodes]) init2(child, el2);
239
209
  }
240
210
  ;
241
211
  }
@@ -249,8 +219,7 @@ var init_core = __esm({
249
219
  memo = /* @__PURE__ */ new WeakMap();
250
220
  evalMemo = {};
251
221
  parse = (expr, dir, fn) => {
252
- if (fn = evalMemo[expr = expr.trim()])
253
- return fn;
222
+ if (fn = evalMemo[expr = expr.trim()]) return fn;
254
223
  try {
255
224
  fn = compile(expr);
256
225
  } catch (e) {
@@ -270,16 +239,14 @@ ${dir}${expr ? `="${expr}"
270
239
  s.compile && (compile = s.compile);
271
240
  };
272
241
  frag = (tpl) => {
273
- if (!tpl.nodeType)
274
- return tpl;
242
+ if (!tpl.nodeType) return tpl;
275
243
  let content = tpl.content.cloneNode(true), attributes = [...tpl.attributes], ref = document.createTextNode(""), childNodes = (content.append(ref), [...content.childNodes]);
276
244
  return {
277
245
  childNodes,
278
246
  content,
279
247
  remove: () => content.append(...childNodes),
280
248
  replaceWith(el) {
281
- if (el === ref)
282
- return;
249
+ if (el === ref) return;
283
250
  ref.before(el);
284
251
  content.append(...childNodes);
285
252
  },
@@ -306,13 +273,11 @@ var init_if = __esm({
306
273
  memo.set(ifEl, null);
307
274
  if (next?.hasAttribute(":else")) {
308
275
  next.removeAttribute(":else");
309
- if (!next.hasAttribute(":if"))
310
- next.remove(), elseEl = next.content ? frag(next) : next, memo.set(elseEl, null);
276
+ if (!next.hasAttribute(":if")) next.remove(), elseEl = next.content ? frag(next) : next, memo.set(elseEl, null);
311
277
  }
312
278
  return effect(() => {
313
279
  const newEl = evaluate(state) ? ifEl : el[_prevIf] ? null : elseEl;
314
- if (next)
315
- next[_prevIf] = newEl === ifEl;
280
+ if (next) next[_prevIf] = newEl === ifEl;
316
281
  if (curEl != newEl) {
317
282
  curEl?.remove();
318
283
  if (curEl = newEl) {
@@ -339,10 +304,8 @@ var init_each = __esm({
339
304
  const items = computed(() => {
340
305
  keys2 = null;
341
306
  let items2 = evaluate(state);
342
- if (typeof items2 === "number")
343
- items2 = Array.from({ length: items2 }, (_, i) => i + 1);
344
- if (items2?.constructor === Object)
345
- keys2 = Object.keys(items2), items2 = Object.values(items2);
307
+ if (typeof items2 === "number") items2 = Array.from({ length: items2 }, (_, i) => i + 1);
308
+ if (items2?.constructor === Object) keys2 = Object.keys(items2), items2 = Object.values(items2);
346
309
  return items2 || [];
347
310
  });
348
311
  const update = () => {
@@ -387,8 +350,7 @@ var init_each = __esm({
387
350
  if (!planned) {
388
351
  update();
389
352
  queueMicrotask(() => (planned && update(), planned = 0));
390
- } else
391
- planned++;
353
+ } else planned++;
392
354
  });
393
355
  };
394
356
  directive.each.parse = (expr) => {
@@ -434,8 +396,7 @@ var init_html = __esm({
434
396
  init_core();
435
397
  directive.html = (el, evaluate, state) => {
436
398
  let tpl = evaluate(state);
437
- if (!tpl)
438
- return;
399
+ if (!tpl) return;
439
400
  let content = (tpl.content || tpl).cloneNode(true);
440
401
  el.replaceChildren(content);
441
402
  sprae(el, state);
@@ -449,8 +410,7 @@ var init_text = __esm({
449
410
  init_core();
450
411
  init_signal();
451
412
  directive.text = (el, evaluate, state) => {
452
- if (el.content)
453
- el.replaceWith(el = frag(el).childNodes[0]);
413
+ if (el.content) el.replaceWith(el = frag(el).childNodes[0]);
454
414
  return effect(() => {
455
415
  let value = evaluate(state);
456
416
  el.textContent = value == null ? "" : value;
@@ -470,20 +430,13 @@ var init_class = __esm({
470
430
  let v = evaluate(state);
471
431
  let clsx = /* @__PURE__ */ new Set();
472
432
  if (v) {
473
- if (typeof v === "string")
474
- v.split(" ").map((cls) => clsx.add(cls));
475
- else if (Array.isArray(v))
476
- v.map((v2) => v2 && clsx.add(v2));
477
- else
478
- Object.entries(v).map(([k, v2]) => v2 && clsx.add(k));
433
+ if (typeof v === "string") v.split(" ").map((cls) => clsx.add(cls));
434
+ else if (Array.isArray(v)) v.map((v2) => v2 && clsx.add(v2));
435
+ else Object.entries(v).map(([k, v2]) => v2 && clsx.add(k));
479
436
  }
480
- for (let cls of cur)
481
- if (clsx.has(cls))
482
- clsx.delete(cls);
483
- else
484
- el.classList.remove(cls);
485
- for (let cls of cur = clsx)
486
- el.classList.add(cls);
437
+ for (let cls of cur) if (clsx.has(cls)) clsx.delete(cls);
438
+ else el.classList.remove(cls);
439
+ for (let cls of cur = clsx) el.classList.add(cls);
487
440
  });
488
441
  };
489
442
  }
@@ -498,13 +451,10 @@ var init_style = __esm({
498
451
  let initStyle = el.getAttribute("style");
499
452
  return effect(() => {
500
453
  let v = evaluate(state);
501
- if (typeof v === "string")
502
- el.setAttribute("style", initStyle + (initStyle.endsWith(";") ? "" : "; ") + v);
454
+ if (typeof v === "string") el.setAttribute("style", initStyle + (initStyle.endsWith(";") ? "" : "; ") + v);
503
455
  else {
504
- if (initStyle)
505
- el.setAttribute("style", initStyle);
506
- for (let k in v)
507
- k[0] == "-" ? el.style.setProperty(k, v[k]) : el.style[k] = v[k];
456
+ if (initStyle) el.setAttribute("style", initStyle);
457
+ for (let k in v) k[0] == "-" ? el.style.setProperty(k, v[k]) : el.style[k] = v[k];
508
458
  }
509
459
  });
510
460
  };
@@ -518,15 +468,11 @@ var init_default = __esm({
518
468
  init_core();
519
469
  init_signal();
520
470
  directive.default = (target, evaluate, state, name) => {
521
- if (!name.startsWith("on"))
522
- return effect(() => {
523
- let value = evaluate(state);
524
- if (name)
525
- attr(target, name, value);
526
- else
527
- for (let key in value)
528
- attr(target, dashcase(key), value[key]);
529
- });
471
+ if (!name.startsWith("on")) return effect(() => {
472
+ let value = evaluate(state);
473
+ if (name) attr(target, name, value);
474
+ else for (let key in value) attr(target, dashcase(key), value[key]);
475
+ });
530
476
  const ctxs = name.split("..").map((e) => {
531
477
  let ctx = { evt: "", target, test: () => true };
532
478
  ctx.evt = (e.startsWith("on") ? e.slice(2) : e).replace(
@@ -535,16 +481,14 @@ var init_default = __esm({
535
481
  );
536
482
  return ctx;
537
483
  });
538
- if (ctxs.length == 1)
539
- return effect(() => addListener(evaluate(state), ctxs[0]));
484
+ if (ctxs.length == 1) return effect(() => addListener(evaluate(state), ctxs[0]));
540
485
  let startFn, nextFn, off, idx = 0;
541
486
  const nextListener = (fn) => {
542
487
  off = addListener((e) => (off(), nextFn = fn?.(e), (idx = ++idx % ctxs.length) ? nextListener(nextFn) : startFn && nextListener(startFn)), ctxs[idx]);
543
488
  };
544
489
  return effect(() => (startFn = evaluate(state), !off && nextListener(startFn), () => startFn = null));
545
490
  function addListener(fn, { evt, target: target2, test, defer, stop, prevent, immediate, ...opts }) {
546
- if (defer)
547
- fn = defer(fn);
491
+ if (defer) fn = defer(fn);
548
492
  const cb = (e) => {
549
493
  try {
550
494
  test(e) && (stop && (immediate ? e.stopImmediatePropagation() : e.stopPropagation()), prevent && e.preventDefault(), fn?.(e));
@@ -558,6 +502,7 @@ var init_default = __esm({
558
502
  ;
559
503
  };
560
504
  mods = {
505
+ // actions
561
506
  prevent(ctx) {
562
507
  ctx.prevent = true;
563
508
  },
@@ -567,6 +512,7 @@ var init_default = __esm({
567
512
  immediate(ctx) {
568
513
  ctx.immediate = true;
569
514
  },
515
+ // options
570
516
  once(ctx) {
571
517
  ctx.once = true;
572
518
  },
@@ -576,6 +522,7 @@ var init_default = __esm({
576
522
  capture(ctx) {
577
523
  ctx.capture = true;
578
524
  },
525
+ // target
579
526
  window(ctx) {
580
527
  ctx.target = window;
581
528
  },
@@ -588,21 +535,21 @@ var init_default = __esm({
588
535
  debounce(ctx, wait) {
589
536
  ctx.defer = (fn) => debounce(fn, wait ? Number(wait) || 0 : 108);
590
537
  },
538
+ // test
591
539
  outside: (ctx) => (e) => {
592
540
  let target = ctx.target;
593
- if (target.contains(e.target))
594
- return false;
595
- if (e.target.isConnected === false)
596
- return false;
597
- if (target.offsetWidth < 1 && target.offsetHeight < 1)
598
- return false;
541
+ if (target.contains(e.target)) return false;
542
+ if (e.target.isConnected === false) return false;
543
+ if (target.offsetWidth < 1 && target.offsetHeight < 1) return false;
599
544
  return true;
600
545
  },
601
546
  self: (ctx) => (e) => e.target === ctx.target,
547
+ // keyboard
602
548
  ctrl: (_, ...param) => (e) => keys.ctrl(e) && param.every((p) => keys[p] ? keys[p](e) : e.key === p),
603
549
  shift: (_, ...param) => (e) => keys.shift(e) && param.every((p) => keys[p] ? keys[p](e) : e.key === p),
604
550
  alt: (_, ...param) => (e) => keys.alt(e) && param.every((p) => keys[p] ? keys[p](e) : e.key === p),
605
551
  meta: (_, ...param) => (e) => keys.meta(e) && param.every((p) => keys[p] ? keys[p](e) : e.key === p),
552
+ // NOTE: we don't expose up/left/right/down as too verbose: can and better be handled/differentiated at once
606
553
  arrow: () => keys.arrow,
607
554
  enter: () => keys.enter,
608
555
  esc: () => keys.esc,
@@ -629,23 +576,19 @@ var init_default = __esm({
629
576
  char: (e) => /^\S$/.test(e.key)
630
577
  };
631
578
  attr = (el, name, v) => {
632
- if (v == null || v === false)
633
- el.removeAttribute(name);
634
- else
635
- el.setAttribute(name, v === true ? "" : typeof v === "number" || typeof v === "string" ? v : "");
579
+ if (v == null || v === false) el.removeAttribute(name);
580
+ else el.setAttribute(name, v === true ? "" : typeof v === "number" || typeof v === "string" ? v : "");
636
581
  };
637
582
  throttle = (fn, limit) => {
638
583
  let pause, planned, block = (e) => {
639
584
  pause = true;
640
585
  setTimeout(() => {
641
586
  pause = false;
642
- if (planned)
643
- return planned = false, block(e), fn(e);
587
+ if (planned) return planned = false, block(e), fn(e);
644
588
  }, limit);
645
589
  };
646
590
  return (e) => {
647
- if (pause)
648
- return planned = true;
591
+ if (pause) return planned = true;
649
592
  block(e);
650
593
  return fn(e);
651
594
  };
@@ -669,19 +612,25 @@ var init_default = __esm({
669
612
  // directive/value.js
670
613
  var init_value = __esm({
671
614
  "directive/value.js"() {
615
+ init_core();
672
616
  init_core();
673
617
  init_default();
674
618
  init_signal();
675
619
  directive.value = (el, [getValue, setValue], state) => {
676
- const update = el.type === "text" || el.type === "" ? (value) => el.setAttribute("value", el.value = value == null ? "" : value) : el.tagName === "TEXTAREA" || el.type === "text" || el.type === "" ? (value, from, to) => (from = el.selectionStart, to = el.selectionEnd, el.setAttribute("value", el.value = value == null ? "" : value), from && el.setSelectionRange(from, to)) : el.type === "checkbox" ? (value) => (el.checked = value, attr(el, "checked", value)) : el.type === "select-one" ? (value) => {
677
- for (let option in el.options)
678
- option.removeAttribute("selected");
620
+ const update = el.type === "text" || el.type === "" ? (value) => el.setAttribute("value", el.value = value == null ? "" : value) : el.tagName === "TEXTAREA" || el.type === "text" || el.type === "" ? (value, from, to) => (
621
+ // we retain selection in input
622
+ (from = el.selectionStart, to = el.selectionEnd, el.setAttribute("value", el.value = value == null ? "" : value), from && el.setSelectionRange(from, to))
623
+ ) : el.type === "checkbox" ? (value) => (el.checked = value, attr(el, "checked", value)) : el.type === "select-one" ? (value) => {
624
+ for (let o of el.options)
625
+ o.value == value ? o.setAttribute("selected", "") : o.removeAttribute("selected");
679
626
  el.value = value;
680
- el.selectedOptions[0]?.setAttribute("selected", "");
627
+ } : el.type === "select-multiple" ? (value) => {
628
+ for (let o of el.options) o.removeAttribute("selected");
629
+ for (let v of value) el.querySelector(`[value="${v}"]`).setAttribute("selected", "");
681
630
  } : (value) => el.value = value;
682
- const handleChange = el.type === "checkbox" ? (e) => setValue(state, el.checked) : (e) => setValue(state, el.value);
683
- el.addEventListener("input", handleChange);
684
- el.addEventListener("change", handleChange);
631
+ if (el.type?.startsWith("select")) sprae(el, state);
632
+ const handleChange = el.type === "checkbox" ? (e) => setValue(state, el.checked) : el.type === "select-multiple" ? (e) => setValue(state, [...el.selectedOptions].map((o) => o.value)) : (e) => setValue(state, el.value);
633
+ el.oninput = el.onchange = handleChange;
685
634
  return effect(() => update(getValue(state)));
686
635
  };
687
636
  directive.value.parse = (expr) => {
@@ -746,8 +695,7 @@ var init_data = __esm({
746
695
  directive["data"] = (el, evaluate, state) => {
747
696
  return effect(() => {
748
697
  let value = evaluate(state);
749
- for (let key in value)
750
- el.dataset[key] = value[key];
698
+ for (let key in value) el.dataset[key] = value[key];
751
699
  });
752
700
  };
753
701
  }
@@ -762,8 +710,7 @@ var init_aria = __esm({
762
710
  init_signal();
763
711
  directive["aria"] = (el, evaluate, state) => {
764
712
  const update = (value) => {
765
- for (let key in value)
766
- attr(el, "aria-" + dashcase(key), value[key] == null ? null : value[key] + "");
713
+ for (let key in value) attr(el, "aria-" + dashcase(key), value[key] == null ? null : value[key] + "");
767
714
  };
768
715
  return effect(() => update(evaluate(state)));
769
716
  };
@@ -777,8 +724,7 @@ init_aria();
777
724
  init_html();
778
725
  module.exports = sprae2;
779
726
  var init = document.currentScript?.getAttribute("init") || null;
780
- if (init)
781
- sprae2(document.documentElement, JSON.parse(init));
727
+ if (init) sprae2(document.documentElement, JSON.parse(init));
782
728
  ;if (typeof module.exports == "object" && typeof exports == "object") {
783
729
  var __cp = (to, from, except, desc) => {
784
730
  if ((from && typeof from === "object") || typeof from === "function") {