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.js CHANGED
@@ -1,6 +1,5 @@
1
1
  // signal.js
2
2
  var current;
3
- var batched;
4
3
  var signal = (v, s, obs = /* @__PURE__ */ new Set()) => (s = {
5
4
  get value() {
6
5
  current?.deps.push(obs.add(current));
@@ -9,7 +8,7 @@ var signal = (v, s, obs = /* @__PURE__ */ new Set()) => (s = {
9
8
  set value(val) {
10
9
  if (val === v) return;
11
10
  v = val;
12
- for (let sub of obs) batched ? batched.add(sub) : sub();
11
+ for (let sub of obs) sub();
13
12
  },
14
13
  peek() {
15
14
  return v;
@@ -34,31 +33,19 @@ var computed = (fn, s = signal(), c, e) => (c = {
34
33
  },
35
34
  peek: s.peek
36
35
  }, c.toJSON = c.then = c.toString = c.valueOf = () => c.value, c);
37
- var batch = (fn) => {
38
- let fxs = batched;
39
- if (!fxs) batched = /* @__PURE__ */ new Set();
40
- try {
41
- fn();
42
- } finally {
43
- if (!fxs) {
44
- fxs = batched;
45
- batched = null;
46
- for (const fx of fxs) fx();
47
- }
48
- }
49
- };
50
- var untracked = (fn, prev, v) => (prev = current, current = null, v = fn(), current = prev, v);
36
+ var batch = (fn) => fn();
37
+ var untracked = batch;
51
38
  function use(s) {
52
39
  signal = s.signal;
53
40
  effect = s.effect;
54
41
  computed = s.computed;
55
- batch = s.batch || ((fn) => fn());
42
+ batch = s.batch || batch;
56
43
  untracked = s.untracked || batch;
57
44
  }
58
45
 
59
46
  // store.js
60
47
  var _signals = Symbol("signals");
61
- var _change = Symbol("length");
48
+ var _change = Symbol("change");
62
49
  function store(values, parent) {
63
50
  if (!values) return values;
64
51
  if (values[_signals]) return values;
@@ -122,14 +109,13 @@ function set(signals, key, v) {
122
109
  else if (s._set) s._set(v);
123
110
  else if (Array.isArray(v) && Array.isArray(s.peek())) {
124
111
  const cur = s.peek();
125
- if (cur[_change]) untracked(() => {
112
+ if (cur[_change]) {
126
113
  batch(() => {
127
114
  let i = 0, l = v.length;
128
115
  for (; i < l; i++) cur[i] = v[i];
129
116
  cur.length = l;
130
117
  });
131
- });
132
- else {
118
+ } else {
133
119
  s.value = v;
134
120
  }
135
121
  } else {
@@ -149,6 +135,7 @@ var _state = Symbol("state");
149
135
  var _on = Symbol("on");
150
136
  var _off = Symbol("off");
151
137
  var directive = {};
138
+ var 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)));
152
139
  function sprae(el, values) {
153
140
  if (!el?.childNodes) return;
154
141
  if (_state in el) {
@@ -168,13 +155,12 @@ function sprae(el, values) {
168
155
  function init(el2) {
169
156
  if (!el2.childNodes) return;
170
157
  for (let i = 0; i < el2.attributes?.length; ) {
171
- let attr2 = el2.attributes[i];
158
+ let attr2 = el2.attributes[i], update;
172
159
  if (attr2.name[0] === ":") {
173
160
  el2.removeAttribute(attr2.name);
174
161
  for (let name of attr2.name.slice(1).split(":")) {
175
- let dir = directive[name] || directive.default, update = dir(el2, (dir.parse || parse)(attr2.value), state, name);
176
- fx.push(update);
177
- offs.push(effect(update));
162
+ update = (directive[name] || directive.default)(el2, attr2.value, state, name);
163
+ fx.push(update), offs.push(effect(update));
178
164
  if (_state in el2) return;
179
165
  }
180
166
  } else i++;
@@ -184,19 +170,20 @@ function sprae(el, values) {
184
170
  ;
185
171
  }
186
172
  var memo = {};
187
- var parse = (expr, dir, fn) => {
173
+ var parse = (expr, dir2) => {
174
+ let fn;
188
175
  if (fn = memo[expr = expr.trim()]) return fn;
189
176
  try {
190
177
  fn = compile(expr);
191
178
  } catch (e) {
192
- err(e, dir, expr);
179
+ err(e, dir2, expr);
193
180
  }
194
181
  return memo[expr] = fn;
195
182
  };
196
- var err = (e, dir, expr = "") => {
183
+ var err = (e, dir2, expr = "") => {
197
184
  throw Object.assign(e, { message: `\u2234 ${e.message}
198
185
 
199
- ${dir}${expr ? `="${expr}"
186
+ ${dir2}${expr ? `="${expr}"
200
187
 
201
188
  ` : ""}`, expr });
202
189
  };
@@ -229,8 +216,9 @@ var frag = (tpl) => {
229
216
 
230
217
  // directive/if.js
231
218
  var _prevIf = Symbol("if");
232
- directive.if = (el, evaluate, state) => {
233
- let next = el.nextElementSibling, holder = document.createTextNode(""), curEl, ifEl, elseEl;
219
+ dir("if", (el, state) => {
220
+ const holder = document.createTextNode("");
221
+ let next = el.nextElementSibling, curEl, ifEl, elseEl;
234
222
  el.replaceWith(holder);
235
223
  ifEl = el.content ? frag(el) : el;
236
224
  ifEl[_state] = null;
@@ -238,8 +226,8 @@ directive.if = (el, evaluate, state) => {
238
226
  next.removeAttribute(":else");
239
227
  if (!next.hasAttribute(":if")) next.remove(), elseEl = next.content ? frag(next) : next, elseEl[_state] = null;
240
228
  }
241
- return () => {
242
- const newEl = evaluate(state) ? ifEl : el[_prevIf] ? null : elseEl;
229
+ return (value) => {
230
+ const newEl = value ? ifEl : el[_prevIf] ? null : elseEl;
243
231
  if (next) next[_prevIf] = newEl === ifEl;
244
232
  if (curEl != newEl) {
245
233
  if (curEl) curEl.remove(), curEl[_off]?.();
@@ -250,41 +238,28 @@ directive.if = (el, evaluate, state) => {
250
238
  }
251
239
  }
252
240
  };
253
- };
241
+ });
254
242
 
255
243
  // directive/each.js
256
- directive.each = (tpl, [itemVar, idxVar, evaluate], state) => {
257
- const holder = document.createTextNode("");
258
- tpl.replaceWith(holder);
259
- tpl[_state] = null;
260
- let cur, keys2, prevl = 0;
261
- const items = computed(() => {
262
- keys2 = null;
263
- let items2 = evaluate(state);
264
- if (typeof items2 === "number") items2 = Array.from({ length: items2 }, (_, i) => i + 1);
265
- if (items2?.constructor === Object) keys2 = Object.keys(items2), items2 = Object.values(items2);
266
- return items2 || [];
267
- });
268
- const update = () => {
269
- untracked(() => {
244
+ dir(
245
+ "each",
246
+ (tpl, state, expr) => {
247
+ const [itemVar, idxVar = "$"] = expr.split(/\s+in\s+/)[0].split(/\s*,\s*/);
248
+ const holder = document.createTextNode("");
249
+ tpl.replaceWith(holder);
250
+ tpl[_state] = null;
251
+ let cur, keys2, items, prevl = 0;
252
+ const update = () => {
270
253
  var _a, _b;
271
- let i = 0, newItems = items.value, newl = newItems.length;
254
+ let i = 0, newItems = items, newl = newItems.length;
272
255
  if (cur && !cur[_change]) {
273
- for (let s of cur[_signals] || []) {
274
- s[Symbol.dispose]();
275
- }
256
+ for (let s of cur[_signals] || []) s[Symbol.dispose]();
276
257
  cur = null, prevl = 0;
277
258
  }
278
- if (newl < prevl) {
279
- cur.length = newl;
280
- } else {
281
- if (!cur) {
282
- cur = newItems;
283
- } else {
284
- for (; i < prevl; i++) {
285
- cur[i] = newItems[i];
286
- }
287
- }
259
+ if (newl < prevl) cur.length = newl;
260
+ else {
261
+ if (!cur) cur = newItems;
262
+ else while (i < prevl) cur[i] = newItems[i++];
288
263
  for (; i < newl; i++) {
289
264
  cur[i] = newItems[i];
290
265
  let idx = i, scope = store({
@@ -299,48 +274,39 @@ directive.each = (tpl, [itemVar, idxVar, evaluate], state) => {
299
274
  }
300
275
  }
301
276
  prevl = newl;
302
- });
303
- };
304
- let planned = 0;
305
- return () => {
306
- items.value[_change]?.value;
307
- if (!planned++) update(), queueMicrotask(() => (planned > 1 && update(), planned = 0));
308
- };
309
- };
310
- directive.each.parse = (expr) => {
311
- let [leftSide, itemsExpr] = expr.split(/\s+in\s+/);
312
- let [itemVar, idxVar = "$"] = leftSide.split(/\s*,\s*/);
313
- return [itemVar, idxVar, parse(itemsExpr)];
314
- };
277
+ };
278
+ return (value) => {
279
+ keys2 = null;
280
+ if (typeof value === "number") items = Array.from({ length: value }, (_, i) => i + 1);
281
+ else if (value?.constructor === Object) keys2 = Object.keys(value), items = Object.values(value);
282
+ else items = value || [];
283
+ let planned = 0;
284
+ return effect(() => {
285
+ items[_change]?.value;
286
+ if (!planned++) update(), queueMicrotask(() => (planned > 1 && update(), planned = 0));
287
+ });
288
+ };
289
+ },
290
+ // redefine evaluator to take second part of expression
291
+ (expr) => parse(expr.split(/\s+in\s+/)[1])
292
+ );
315
293
 
316
294
  // directive/ref.js
317
- directive.ref = (el, evaluate, state) => {
318
- return () => evaluate(state)?.call?.(null, el);
319
- };
295
+ dir("ref", (el, state, expr) => (v) => v.call(null, el));
320
296
 
321
297
  // directive/with.js
322
- directive.with = (el, evaluate, rootState) => {
323
- let state;
324
- return () => {
325
- let values = evaluate(rootState);
326
- sprae(el, state ? values : state = store(values, rootState));
327
- };
328
- };
298
+ dir("with", (el, rootState, state) => (state = null, (values) => sprae(el, state ? values : state = store(values, rootState))));
329
299
 
330
300
  // directive/text.js
331
- directive.text = (el, evaluate, state) => {
332
- if (el.content) el.replaceWith(el = frag(el).childNodes[0]);
333
- return () => {
334
- let value = evaluate(state);
335
- el.textContent = value == null ? "" : value;
336
- };
337
- };
301
+ dir("text", (el) => (
302
+ // <template :text="a"/> or previously initialized template
303
+ (el.content && el.replaceWith(el = frag(el).childNodes[0]), (value) => el.textContent = value == null ? "" : value)
304
+ ));
338
305
 
339
306
  // directive/class.js
340
- directive.class = (el, evaluate, state) => {
341
- let cur = /* @__PURE__ */ new Set();
342
- return () => {
343
- let v = evaluate(state);
307
+ dir(
308
+ "class",
309
+ (el, cur) => (cur = /* @__PURE__ */ new Set(), (v) => {
344
310
  let clsx = /* @__PURE__ */ new Set();
345
311
  if (v) {
346
312
  if (typeof v === "string") v.split(" ").map((cls) => clsx.add(cls));
@@ -350,44 +316,36 @@ directive.class = (el, evaluate, state) => {
350
316
  for (let cls of cur) if (clsx.has(cls)) clsx.delete(cls);
351
317
  else el.classList.remove(cls);
352
318
  for (let cls of cur = clsx) el.classList.add(cls);
353
- };
354
- };
319
+ })
320
+ );
355
321
 
356
322
  // directive/style.js
357
- directive.style = (el, evaluate, state) => {
358
- let initStyle = el.getAttribute("style");
359
- return () => {
360
- let v = evaluate(state);
323
+ dir(
324
+ "style",
325
+ (el, initStyle) => (initStyle = el.getAttribute("style"), (v) => {
361
326
  if (typeof v === "string") el.setAttribute("style", initStyle + (initStyle.endsWith(";") ? "" : "; ") + v);
362
327
  else {
363
328
  if (initStyle) el.setAttribute("style", initStyle);
364
329
  for (let k in v) k[0] == "-" ? el.style.setProperty(k, v[k]) : el.style[k] = v[k];
365
330
  }
366
- };
367
- };
331
+ })
332
+ );
368
333
 
369
334
  // directive/default.js
370
- directive.default = (target, evaluate, state, name) => {
371
- if (!name.startsWith("on")) return () => {
372
- let value = evaluate(state);
373
- if (name) attr(target, name, value);
374
- else for (let key in value) attr(target, dashcase(key), value[key]);
375
- };
335
+ dir("default", (target, state, expr, name) => {
336
+ if (!name.startsWith("on"))
337
+ return name ? (value) => attr(target, name, value) : (value) => {
338
+ for (let key in value) attr(target, dashcase(key), value[key]);
339
+ };
376
340
  const ctxs = name.split("..").map((e) => {
377
341
  let ctx = { evt: "", target, test: () => true };
378
342
  ctx.evt = (e.startsWith("on") ? e.slice(2) : e).replace(
379
343
  /\.(\w+)?-?([-\w]+)?/g,
380
- (match, mod, param = "") => (ctx.test = mods[mod]?.(ctx, ...param.split("-")) || ctx.test, "")
344
+ (_, mod, param = "") => (ctx.test = mods[mod]?.(ctx, ...param.split("-")) || ctx.test, "")
381
345
  );
382
346
  return ctx;
383
347
  });
384
- if (ctxs.length == 1) return () => addListener(evaluate(state), ctxs[0]);
385
- let startFn, nextFn, off, idx = 0;
386
- const nextListener = (fn) => {
387
- off = addListener((e) => (off(), nextFn = fn?.(e), (idx = ++idx % ctxs.length) ? nextListener(nextFn) : startFn && nextListener(startFn)), ctxs[idx]);
388
- };
389
- return () => (startFn = evaluate(state), !off && nextListener(startFn), () => startFn = null);
390
- function addListener(fn, { evt, target: target2, test, defer, stop, prevent, immediate, ...opts }) {
348
+ const addListener = (fn, { evt, target: target2, test, defer, stop, prevent, immediate, ...opts }) => {
391
349
  if (defer) fn = defer(fn);
392
350
  const cb = (e) => {
393
351
  try {
@@ -398,9 +356,14 @@ directive.default = (target, evaluate, state, name) => {
398
356
  };
399
357
  target2.addEventListener(evt, cb, opts);
400
358
  return () => target2.removeEventListener(evt, cb, opts);
401
- }
402
- ;
403
- };
359
+ };
360
+ if (ctxs.length == 1) return (v) => addListener(v, ctxs[0]);
361
+ let startFn, nextFn, off, idx = 0;
362
+ const nextListener = (fn) => {
363
+ off = addListener((e) => (off(), nextFn = fn?.(e), (idx = ++idx % ctxs.length) ? nextListener(nextFn) : startFn && nextListener(startFn)), ctxs[idx]);
364
+ };
365
+ return (value) => (startFn = value, !off && nextListener(startFn), () => startFn = null);
366
+ });
404
367
  var mods = {
405
368
  // actions
406
369
  prevent(ctx) {
@@ -478,10 +441,6 @@ var keys = {
478
441
  letter: (e) => /^\p{L}$/gu.test(e.key),
479
442
  char: (e) => /^\S$/.test(e.key)
480
443
  };
481
- var attr = (el, name, v) => {
482
- if (v == null || v === false) el.removeAttribute(name);
483
- else el.setAttribute(name, v === true ? "" : typeof v === "number" || typeof v === "string" ? v : "");
484
- };
485
444
  var throttle = (fn, limit) => {
486
445
  let pause, planned, block = (e) => {
487
446
  pause = true;
@@ -506,12 +465,16 @@ var debounce = (fn, wait) => {
506
465
  }, wait);
507
466
  };
508
467
  };
468
+ var attr = (el, name, v) => {
469
+ if (v == null || v === false) el.removeAttribute(name);
470
+ else el.setAttribute(name, v === true ? "" : typeof v === "number" || typeof v === "string" ? v : "");
471
+ };
509
472
  var dashcase = (str) => {
510
473
  return str.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g, (match, i) => (i ? "-" : "") + match.toLowerCase());
511
474
  };
512
475
 
513
476
  // directive/value.js
514
- directive.value = (el, [getValue, setValue], state) => {
477
+ dir("value", (el, state, expr) => {
515
478
  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) => (
516
479
  // we retain selection in input
517
480
  (from = el.selectionStart, to = el.selectionEnd, el.setAttribute("value", el.value = value == null ? "" : value), from && el.setSelectionRange(from, to))
@@ -523,50 +486,39 @@ directive.value = (el, [getValue, setValue], state) => {
523
486
  for (let o of el.options) o.removeAttribute("selected");
524
487
  for (let v of value) el.querySelector(`[value="${v}"]`).setAttribute("selected", "");
525
488
  } : (value) => el.value = value;
526
- 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);
489
+ let set2 = setter(expr);
490
+ 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);
527
491
  el.oninput = el.onchange = handleChange;
528
492
  if (el.type?.startsWith("select")) {
529
493
  new MutationObserver(handleChange).observe(el, { childList: true, subtree: true, attributes: true });
530
494
  sprae(el, state);
531
495
  }
532
- return () => {
533
- update(getValue(state));
534
- };
535
- };
536
- directive.value.parse = (expr) => {
537
- let evaluate = [parse(expr)];
496
+ return update;
497
+ });
498
+ var setter = (expr) => {
538
499
  try {
539
500
  const set2 = parse(`${expr}=__`);
540
- evaluate.push((state, value) => {
501
+ return (state, value) => {
541
502
  state.__ = value;
542
503
  set2(state, value);
543
504
  delete state.__;
544
- });
505
+ };
545
506
  } catch (e) {
546
507
  }
547
- return evaluate;
548
508
  };
549
509
 
550
510
  // directive/fx.js
551
- directive.fx = (el, evaluate, state) => {
552
- return () => evaluate(state);
553
- };
511
+ dir("fx", (_) => (_2) => _2);
554
512
 
555
513
  // directive/aria.js
556
- directive["aria"] = (el, evaluate, state) => {
557
- const update = (value) => {
558
- for (let key in value) attr(el, "aria-" + dashcase(key), value[key] == null ? null : value[key] + "");
559
- };
560
- return () => update(evaluate(state));
561
- };
514
+ dir("aria", (el) => (value) => {
515
+ for (let key in value) attr(el, "aria-" + dashcase(key), value[key] == null ? null : value[key] + "");
516
+ });
562
517
 
563
518
  // directive/data.js
564
- directive["data"] = (el, evaluate, state) => {
565
- return () => {
566
- let value = evaluate(state);
567
- for (let key in value) el.dataset[key] = value[key];
568
- };
569
- };
519
+ dir("data", (el) => (value) => {
520
+ for (let key in value) el.dataset[key] = value[key];
521
+ });
570
522
 
571
523
  // sprae.js
572
524
  sprae.use({ compile: (expr) => sprae.constructor(`with (arguments[0]) { return ${expr} };`) });