sprae 11.0.7 → 11.0.8

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
@@ -25,10 +25,10 @@ function use(s) {
25
25
  signal = s.signal;
26
26
  effect = s.effect;
27
27
  computed = s.computed;
28
- batch = s.batch || ((fn) => fn());
28
+ batch = s.batch || batch;
29
29
  untracked = s.untracked || batch;
30
30
  }
31
- var current, batched, signal, effect, computed, batch, untracked;
31
+ var current, signal, effect, computed, batch, untracked;
32
32
  var init_signal = __esm({
33
33
  "signal.js"() {
34
34
  signal = (v, s, obs = /* @__PURE__ */ new Set()) => (s = {
@@ -39,7 +39,7 @@ var init_signal = __esm({
39
39
  set value(val) {
40
40
  if (val === v) return;
41
41
  v = val;
42
- for (let sub of obs) batched ? batched.add(sub) : sub();
42
+ for (let sub of obs) sub();
43
43
  },
44
44
  peek() {
45
45
  return v;
@@ -64,20 +64,8 @@ var init_signal = __esm({
64
64
  },
65
65
  peek: s.peek
66
66
  }, c.toJSON = c.then = c.toString = c.valueOf = () => c.value, c);
67
- batch = (fn) => {
68
- let fxs = batched;
69
- if (!fxs) batched = /* @__PURE__ */ new Set();
70
- try {
71
- fn();
72
- } finally {
73
- if (!fxs) {
74
- fxs = batched;
75
- batched = null;
76
- for (const fx of fxs) fx();
77
- }
78
- }
79
- };
80
- untracked = (fn, prev, v) => (prev = current, current = null, v = fn(), current = prev, v);
67
+ batch = (fn) => fn();
68
+ untracked = batch;
81
69
  }
82
70
  });
83
71
 
@@ -144,14 +132,13 @@ function set(signals, key, v) {
144
132
  else if (s._set) s._set(v);
145
133
  else if (Array.isArray(v) && Array.isArray(s.peek())) {
146
134
  const cur = s.peek();
147
- if (cur[_change]) untracked(() => {
135
+ if (cur[_change]) {
148
136
  batch(() => {
149
137
  let i = 0, l = v.length;
150
138
  for (; i < l; i++) cur[i] = v[i];
151
139
  cur.length = l;
152
140
  });
153
- });
154
- else {
141
+ } else {
155
142
  s.value = v;
156
143
  }
157
144
  } else {
@@ -169,7 +156,7 @@ var init_store = __esm({
169
156
  "store.js"() {
170
157
  init_signal();
171
158
  _signals = Symbol("signals");
172
- _change = Symbol("length");
159
+ _change = Symbol("change");
173
160
  mut = { push: 1, pop: 1, shift: 1, unshift: 1, splice: 1 };
174
161
  }
175
162
  });
@@ -194,13 +181,12 @@ function sprae(el, values) {
194
181
  function init(el2) {
195
182
  if (!el2.childNodes) return;
196
183
  for (let i = 0; i < el2.attributes?.length; ) {
197
- let attr2 = el2.attributes[i];
184
+ let attr2 = el2.attributes[i], update;
198
185
  if (attr2.name[0] === ":") {
199
186
  el2.removeAttribute(attr2.name);
200
187
  for (let name of attr2.name.slice(1).split(":")) {
201
- let dir = directive[name] || directive.default, update = dir(el2, (dir.parse || parse)(attr2.value), state, name);
202
- fx.push(update);
203
- offs.push(effect(update));
188
+ update = (directive[name] || directive.default)(el2, attr2.value, state, name);
189
+ fx.push(update), offs.push(effect(update));
204
190
  if (_state in el2) return;
205
191
  }
206
192
  } else i++;
@@ -209,7 +195,7 @@ function sprae(el, values) {
209
195
  }
210
196
  ;
211
197
  }
212
- var _dispose, _state, _on, _off, directive, memo, parse, err, compile, frag;
198
+ var _dispose, _state, _on, _off, directive, dir, memo, parse, err, compile, frag;
213
199
  var init_core = __esm({
214
200
  "core.js"() {
215
201
  init_signal();
@@ -219,20 +205,22 @@ var init_core = __esm({
219
205
  _on = Symbol("on");
220
206
  _off = Symbol("off");
221
207
  directive = {};
208
+ dir = (name, create, p = parse) => directive[name] = (el, expr, state, name2, update, evaluate) => (evaluate = p(expr), update = create(el, state, expr, name2), () => update(evaluate(state)));
222
209
  memo = {};
223
- parse = (expr, dir, fn) => {
210
+ parse = (expr, dir2) => {
211
+ let fn;
224
212
  if (fn = memo[expr = expr.trim()]) return fn;
225
213
  try {
226
214
  fn = compile(expr);
227
215
  } catch (e) {
228
- err(e, dir, expr);
216
+ err(e, dir2, expr);
229
217
  }
230
218
  return memo[expr] = fn;
231
219
  };
232
- err = (e, dir, expr = "") => {
220
+ err = (e, dir2, expr = "") => {
233
221
  throw Object.assign(e, { message: `\u2234 ${e.message}
234
222
 
235
- ${dir}${expr ? `="${expr}"
223
+ ${dir2}${expr ? `="${expr}"
236
224
 
237
225
  ` : ""}`, expr });
238
226
  };
@@ -270,8 +258,9 @@ var init_if = __esm({
270
258
  "directive/if.js"() {
271
259
  init_core();
272
260
  _prevIf = Symbol("if");
273
- directive.if = (el, evaluate, state) => {
274
- let next = el.nextElementSibling, holder = document.createTextNode(""), curEl, ifEl, elseEl;
261
+ dir("if", (el, state) => {
262
+ const holder = document.createTextNode("");
263
+ let next = el.nextElementSibling, curEl, ifEl, elseEl;
275
264
  el.replaceWith(holder);
276
265
  ifEl = el.content ? frag(el) : el;
277
266
  ifEl[_state] = null;
@@ -279,8 +268,8 @@ var init_if = __esm({
279
268
  next.removeAttribute(":else");
280
269
  if (!next.hasAttribute(":if")) next.remove(), elseEl = next.content ? frag(next) : next, elseEl[_state] = null;
281
270
  }
282
- return () => {
283
- const newEl = evaluate(state) ? ifEl : el[_prevIf] ? null : elseEl;
271
+ return (value) => {
272
+ const newEl = value ? ifEl : el[_prevIf] ? null : elseEl;
284
273
  if (next) next[_prevIf] = newEl === ifEl;
285
274
  if (curEl != newEl) {
286
275
  if (curEl) curEl.remove(), curEl[_off]?.();
@@ -291,7 +280,7 @@ var init_if = __esm({
291
280
  }
292
281
  }
293
282
  };
294
- };
283
+ });
295
284
  }
296
285
  });
297
286
 
@@ -301,38 +290,25 @@ var init_each = __esm({
301
290
  init_core();
302
291
  init_store();
303
292
  init_signal();
304
- directive.each = (tpl, [itemVar, idxVar, evaluate], state) => {
305
- const holder = document.createTextNode("");
306
- tpl.replaceWith(holder);
307
- tpl[_state] = null;
308
- let cur, keys2, prevl = 0;
309
- const items = computed(() => {
310
- keys2 = null;
311
- let items2 = evaluate(state);
312
- if (typeof items2 === "number") items2 = Array.from({ length: items2 }, (_, i) => i + 1);
313
- if (items2?.constructor === Object) keys2 = Object.keys(items2), items2 = Object.values(items2);
314
- return items2 || [];
315
- });
316
- const update = () => {
317
- untracked(() => {
293
+ dir(
294
+ "each",
295
+ (tpl, state, expr) => {
296
+ const [itemVar, idxVar = "$"] = expr.split(/\s+in\s+/)[0].split(/\s*,\s*/);
297
+ const holder = document.createTextNode("");
298
+ tpl.replaceWith(holder);
299
+ tpl[_state] = null;
300
+ let cur, keys2, items, prevl = 0;
301
+ const update = () => {
318
302
  var _a, _b;
319
- let i = 0, newItems = items.value, newl = newItems.length;
303
+ let i = 0, newItems = items, newl = newItems.length;
320
304
  if (cur && !cur[_change]) {
321
- for (let s of cur[_signals] || []) {
322
- s[Symbol.dispose]();
323
- }
305
+ for (let s of cur[_signals] || []) s[Symbol.dispose]();
324
306
  cur = null, prevl = 0;
325
307
  }
326
- if (newl < prevl) {
327
- cur.length = newl;
328
- } else {
329
- if (!cur) {
330
- cur = newItems;
331
- } else {
332
- for (; i < prevl; i++) {
333
- cur[i] = newItems[i];
334
- }
335
- }
308
+ if (newl < prevl) cur.length = newl;
309
+ else {
310
+ if (!cur) cur = newItems;
311
+ else while (i < prevl) cur[i] = newItems[i++];
336
312
  for (; i < newl; i++) {
337
313
  cur[i] = newItems[i];
338
314
  let idx = i, scope = store({
@@ -347,19 +323,22 @@ var init_each = __esm({
347
323
  }
348
324
  }
349
325
  prevl = newl;
350
- });
351
- };
352
- let planned = 0;
353
- return () => {
354
- items.value[_change]?.value;
355
- if (!planned++) update(), queueMicrotask(() => (planned > 1 && update(), planned = 0));
356
- };
357
- };
358
- directive.each.parse = (expr) => {
359
- let [leftSide, itemsExpr] = expr.split(/\s+in\s+/);
360
- let [itemVar, idxVar = "$"] = leftSide.split(/\s*,\s*/);
361
- return [itemVar, idxVar, parse(itemsExpr)];
362
- };
326
+ };
327
+ return (value) => {
328
+ keys2 = null;
329
+ if (typeof value === "number") items = Array.from({ length: value }, (_, i) => i + 1);
330
+ else if (value?.constructor === Object) keys2 = Object.keys(value), items = Object.values(value);
331
+ else items = value || [];
332
+ let planned = 0;
333
+ return effect(() => {
334
+ items[_change]?.value;
335
+ if (!planned++) update(), queueMicrotask(() => (planned > 1 && update(), planned = 0));
336
+ });
337
+ };
338
+ },
339
+ // redefine evaluator to take second part of expression
340
+ (expr) => parse(expr.split(/\s+in\s+/)[1])
341
+ );
363
342
  }
364
343
  });
365
344
 
@@ -367,9 +346,7 @@ var init_each = __esm({
367
346
  var init_ref = __esm({
368
347
  "directive/ref.js"() {
369
348
  init_core();
370
- directive.ref = (el, evaluate, state) => {
371
- return () => evaluate(state)?.call?.(null, el);
372
- };
349
+ dir("ref", (el, state, expr) => (v) => v.call(null, el));
373
350
  }
374
351
  });
375
352
 
@@ -378,13 +355,7 @@ var init_with = __esm({
378
355
  "directive/with.js"() {
379
356
  init_core();
380
357
  init_store();
381
- directive.with = (el, evaluate, rootState) => {
382
- let state;
383
- return () => {
384
- let values = evaluate(rootState);
385
- sprae(el, state ? values : state = store(values, rootState));
386
- };
387
- };
358
+ dir("with", (el, rootState, state) => (state = null, (values) => sprae(el, state ? values : state = store(values, rootState))));
388
359
  }
389
360
  });
390
361
 
@@ -392,13 +363,10 @@ var init_with = __esm({
392
363
  var init_text = __esm({
393
364
  "directive/text.js"() {
394
365
  init_core();
395
- directive.text = (el, evaluate, state) => {
396
- if (el.content) el.replaceWith(el = frag(el).childNodes[0]);
397
- return () => {
398
- let value = evaluate(state);
399
- el.textContent = value == null ? "" : value;
400
- };
401
- };
366
+ dir("text", (el) => (
367
+ // <template :text="a"/> or previously initialized template
368
+ (el.content && el.replaceWith(el = frag(el).childNodes[0]), (value) => el.textContent = value == null ? "" : value)
369
+ ));
402
370
  }
403
371
  });
404
372
 
@@ -406,10 +374,9 @@ var init_text = __esm({
406
374
  var init_class = __esm({
407
375
  "directive/class.js"() {
408
376
  init_core();
409
- directive.class = (el, evaluate, state) => {
410
- let cur = /* @__PURE__ */ new Set();
411
- return () => {
412
- let v = evaluate(state);
377
+ dir(
378
+ "class",
379
+ (el, cur) => (cur = /* @__PURE__ */ new Set(), (v) => {
413
380
  let clsx = /* @__PURE__ */ new Set();
414
381
  if (v) {
415
382
  if (typeof v === "string") v.split(" ").map((cls) => clsx.add(cls));
@@ -419,8 +386,8 @@ var init_class = __esm({
419
386
  for (let cls of cur) if (clsx.has(cls)) clsx.delete(cls);
420
387
  else el.classList.remove(cls);
421
388
  for (let cls of cur = clsx) el.classList.add(cls);
422
- };
423
- };
389
+ })
390
+ );
424
391
  }
425
392
  });
426
393
 
@@ -428,46 +395,38 @@ var init_class = __esm({
428
395
  var init_style = __esm({
429
396
  "directive/style.js"() {
430
397
  init_core();
431
- directive.style = (el, evaluate, state) => {
432
- let initStyle = el.getAttribute("style");
433
- return () => {
434
- let v = evaluate(state);
398
+ dir(
399
+ "style",
400
+ (el, initStyle) => (initStyle = el.getAttribute("style"), (v) => {
435
401
  if (typeof v === "string") el.setAttribute("style", initStyle + (initStyle.endsWith(";") ? "" : "; ") + v);
436
402
  else {
437
403
  if (initStyle) el.setAttribute("style", initStyle);
438
404
  for (let k in v) k[0] == "-" ? el.style.setProperty(k, v[k]) : el.style[k] = v[k];
439
405
  }
440
- };
441
- };
406
+ })
407
+ );
442
408
  }
443
409
  });
444
410
 
445
411
  // directive/default.js
446
- var mods, keys, attr, throttle, debounce, dashcase;
412
+ var mods, keys, throttle, debounce, attr, dashcase;
447
413
  var init_default = __esm({
448
414
  "directive/default.js"() {
449
415
  init_core();
450
- directive.default = (target, evaluate, state, name) => {
451
- if (!name.startsWith("on")) return () => {
452
- let value = evaluate(state);
453
- if (name) attr(target, name, value);
454
- else for (let key in value) attr(target, dashcase(key), value[key]);
455
- };
416
+ dir("default", (target, state, expr, name) => {
417
+ if (!name.startsWith("on"))
418
+ return name ? (value) => attr(target, name, value) : (value) => {
419
+ for (let key in value) attr(target, dashcase(key), value[key]);
420
+ };
456
421
  const ctxs = name.split("..").map((e) => {
457
422
  let ctx = { evt: "", target, test: () => true };
458
423
  ctx.evt = (e.startsWith("on") ? e.slice(2) : e).replace(
459
424
  /\.(\w+)?-?([-\w]+)?/g,
460
- (match, mod, param = "") => (ctx.test = mods[mod]?.(ctx, ...param.split("-")) || ctx.test, "")
425
+ (_, mod, param = "") => (ctx.test = mods[mod]?.(ctx, ...param.split("-")) || ctx.test, "")
461
426
  );
462
427
  return ctx;
463
428
  });
464
- if (ctxs.length == 1) return () => addListener(evaluate(state), ctxs[0]);
465
- let startFn, nextFn, off, idx = 0;
466
- const nextListener = (fn) => {
467
- off = addListener((e) => (off(), nextFn = fn?.(e), (idx = ++idx % ctxs.length) ? nextListener(nextFn) : startFn && nextListener(startFn)), ctxs[idx]);
468
- };
469
- return () => (startFn = evaluate(state), !off && nextListener(startFn), () => startFn = null);
470
- function addListener(fn, { evt, target: target2, test, defer, stop, prevent, immediate, ...opts }) {
429
+ const addListener = (fn, { evt, target: target2, test, defer, stop, prevent, immediate, ...opts }) => {
471
430
  if (defer) fn = defer(fn);
472
431
  const cb = (e) => {
473
432
  try {
@@ -478,9 +437,14 @@ var init_default = __esm({
478
437
  };
479
438
  target2.addEventListener(evt, cb, opts);
480
439
  return () => target2.removeEventListener(evt, cb, opts);
481
- }
482
- ;
483
- };
440
+ };
441
+ if (ctxs.length == 1) return (v) => addListener(v, ctxs[0]);
442
+ let startFn, nextFn, off, idx = 0;
443
+ const nextListener = (fn) => {
444
+ off = addListener((e) => (off(), nextFn = fn?.(e), (idx = ++idx % ctxs.length) ? nextListener(nextFn) : startFn && nextListener(startFn)), ctxs[idx]);
445
+ };
446
+ return (value) => (startFn = value, !off && nextListener(startFn), () => startFn = null);
447
+ });
484
448
  mods = {
485
449
  // actions
486
450
  prevent(ctx) {
@@ -558,10 +522,6 @@ var init_default = __esm({
558
522
  letter: (e) => /^\p{L}$/gu.test(e.key),
559
523
  char: (e) => /^\S$/.test(e.key)
560
524
  };
561
- attr = (el, name, v) => {
562
- if (v == null || v === false) el.removeAttribute(name);
563
- else el.setAttribute(name, v === true ? "" : typeof v === "number" || typeof v === "string" ? v : "");
564
- };
565
525
  throttle = (fn, limit) => {
566
526
  let pause, planned, block = (e) => {
567
527
  pause = true;
@@ -586,6 +546,10 @@ var init_default = __esm({
586
546
  }, wait);
587
547
  };
588
548
  };
549
+ attr = (el, name, v) => {
550
+ if (v == null || v === false) el.removeAttribute(name);
551
+ else el.setAttribute(name, v === true ? "" : typeof v === "number" || typeof v === "string" ? v : "");
552
+ };
589
553
  dashcase = (str) => {
590
554
  return str.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g, (match, i) => (i ? "-" : "") + match.toLowerCase());
591
555
  };
@@ -593,12 +557,13 @@ var init_default = __esm({
593
557
  });
594
558
 
595
559
  // directive/value.js
560
+ var setter;
596
561
  var init_value = __esm({
597
562
  "directive/value.js"() {
598
563
  init_core();
599
564
  init_core();
600
565
  init_default();
601
- directive.value = (el, [getValue, setValue], state) => {
566
+ dir("value", (el, state, expr) => {
602
567
  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) => (
603
568
  // we retain selection in input
604
569
  (from = el.selectionStart, to = el.selectionEnd, el.setAttribute("value", el.value = value == null ? "" : value), from && el.setSelectionRange(from, to))
@@ -610,28 +575,25 @@ var init_value = __esm({
610
575
  for (let o of el.options) o.removeAttribute("selected");
611
576
  for (let v of value) el.querySelector(`[value="${v}"]`).setAttribute("selected", "");
612
577
  } : (value) => el.value = value;
613
- const handleChange = el.type === "checkbox" ? () => setValue(state, el.checked) : el.type === "select-multiple" ? () => setValue(state, [...el.selectedOptions].map((o) => o.value)) : (e) => setValue(state, el.selectedIndex < 0 ? null : el.value);
578
+ let set2 = setter(expr);
579
+ const handleChange = el.type === "checkbox" ? () => set2(state, el.checked) : el.type === "select-multiple" ? () => set2(state, [...el.selectedOptions].map((o) => o.value)) : () => set2(state, el.selectedIndex < 0 ? null : el.value);
614
580
  el.oninput = el.onchange = handleChange;
615
581
  if (el.type?.startsWith("select")) {
616
582
  new MutationObserver(handleChange).observe(el, { childList: true, subtree: true, attributes: true });
617
583
  sprae(el, state);
618
584
  }
619
- return () => {
620
- update(getValue(state));
621
- };
622
- };
623
- directive.value.parse = (expr) => {
624
- let evaluate = [parse(expr)];
585
+ return update;
586
+ });
587
+ setter = (expr) => {
625
588
  try {
626
589
  const set2 = parse(`${expr}=__`);
627
- evaluate.push((state, value) => {
590
+ return (state, value) => {
628
591
  state.__ = value;
629
592
  set2(state, value);
630
593
  delete state.__;
631
- });
594
+ };
632
595
  } catch (e) {
633
596
  }
634
- return evaluate;
635
597
  };
636
598
  }
637
599
  });
@@ -640,9 +602,7 @@ var init_value = __esm({
640
602
  var init_fx = __esm({
641
603
  "directive/fx.js"() {
642
604
  init_core();
643
- directive.fx = (el, evaluate, state) => {
644
- return () => evaluate(state);
645
- };
605
+ dir("fx", (_) => (_2) => _2);
646
606
  }
647
607
  });
648
608
 
@@ -651,12 +611,9 @@ var init_aria = __esm({
651
611
  "directive/aria.js"() {
652
612
  init_core();
653
613
  init_default();
654
- directive["aria"] = (el, evaluate, state) => {
655
- const update = (value) => {
656
- for (let key in value) attr(el, "aria-" + dashcase(key), value[key] == null ? null : value[key] + "");
657
- };
658
- return () => update(evaluate(state));
659
- };
614
+ dir("aria", (el) => (value) => {
615
+ for (let key in value) attr(el, "aria-" + dashcase(key), value[key] == null ? null : value[key] + "");
616
+ });
660
617
  }
661
618
  });
662
619
 
@@ -664,12 +621,9 @@ var init_aria = __esm({
664
621
  var init_data = __esm({
665
622
  "directive/data.js"() {
666
623
  init_core();
667
- directive["data"] = (el, evaluate, state) => {
668
- return () => {
669
- let value = evaluate(state);
670
- for (let key in value) el.dataset[key] = value[key];
671
- };
672
- };
624
+ dir("data", (el) => (value) => {
625
+ for (let key in value) el.dataset[key] = value[key];
626
+ });
673
627
  }
674
628
  });
675
629