sprae 2.10.1 → 2.11.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sprae",
3
3
  "description": "DOM microhydration.",
4
- "version": "2.10.1",
4
+ "version": "2.11.0",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
7
7
  "type": "module",
package/r&d.md CHANGED
@@ -350,6 +350,7 @@
350
350
  + allows `let a = 1; a;` case instead of `let a = 1; return a;`
351
351
  - we can't identify dynamic parts like `x[y]`, whereas signals subscribe dynamically
352
352
  ~ we can detect dynamic parts and handle them on proxy
353
+ + subscript allows subscriptions to async functions, unlike signals
353
354
 
354
355
  -> We can benchmark if updating set of known dependencies is faster than using preact subscriptions.
355
356
  + it seems more logical min-ground to know in advance what we depend on, rather than detect by-call as signals do.
@@ -424,9 +425,26 @@
424
425
  + allow multiple setters for same props or multiple listeners for same events
425
426
  + oldschool jquery-compatible events
426
427
 
428
+ * [x] Event modifiers
429
+ * [x] onevt.x, onevt.y
430
+ + jquery-like
431
+ + multiple same events
432
+ * [x] onevt.once, onevt.passive, onevt.capture
433
+ + standard props passing
434
+ * [x] onevt.prevent, onevt.stop
435
+ + conventional mods
436
+ * [x] onevt.outside onevt.window, onevt.document, onevt.self
437
+ + useful handlers, conventional mods
438
+ * [x] onevt.throttle-xxx, onevt.debounce-xxx
439
+ + conventional
440
+ * [x] onevt.shift, onevt.cmd.shift, onevt.meta
441
+ + conventional
442
+ * [x] onkey.enter, .space, .up|.down|.left|.right, .escape, .tab, .period, .slash, .caps-lock
443
+ + conventional
444
+
427
445
  ## [x] Mods design -> use event modifiers, not props modifiers
428
446
 
429
- * [ ] ~~Prop modifiers~~
447
+ * [ ] Prop modifiers
430
448
  - overall seems code complication without much benefit
431
449
  * [ ] value.bind? value.watch?
432
450
  - let's wait for use-case: value can be too big to set it every time
@@ -443,23 +461,11 @@
443
461
  - let's wait until that's really a problem
444
462
  * [ ] prop.class
445
463
  ? what's the use-case
446
-
447
- * [x] Event modifiers
448
- * [x] onevt.x, onevt.y
449
- + jquery-like
450
- + multiple same events
451
- * [x] onevt.once, onevt.passive, onevt.capture
452
- + standard props passing
453
- * [x] onevt.prevent, onevt.stop
454
- + conventional mods
455
- * [x] onevt.outside onevt.window, onevt.document, onevt.self
456
- + useful handlers, conventional mods
457
- * [x] onevt.throttle-xxx, onevt.debounce-xxx
458
- + conventional
459
- * [x] onevt.shift, onevt.cmd.shift, onevt.meta
460
- + conventional
461
- * [x] onkey.enter, .space, .up|.down|.left|.right, .escape, .tab, .period, .slash, .caps-lock
462
- + conventional
464
+ * [ ] prop.next="" - run update after other DOM updates happen
465
+ * [ ] prop.fx="" - run effect without changing property
466
+ * [ ] x.prop="xyz" - set element property, rather than attribute (following topic)
467
+ * [ ] x.raf="abc" - run regularly?
468
+ * [ ] x.watch-xyz - update by change of any of the deps
463
469
 
464
470
  ## [x] Writing props on elements (like ones in :each) -> nah, just use `:x="this.x=abc"`
465
471
 
package/sprae.js CHANGED
@@ -71,16 +71,16 @@ function v(i2) {
71
71
  }
72
72
  }
73
73
  }
74
- function e2(i2) {
74
+ function e(i2) {
75
75
  this.v = i2;
76
76
  this.i = 0;
77
77
  this.n = void 0;
78
78
  this.t = void 0;
79
79
  }
80
- e2.prototype.h = function() {
80
+ e.prototype.h = function() {
81
81
  return true;
82
82
  };
83
- e2.prototype.S = function(i2) {
83
+ e.prototype.S = function(i2) {
84
84
  if (this.t !== i2 && void 0 === i2.e) {
85
85
  i2.x = this.t;
86
86
  if (void 0 !== this.t)
@@ -88,7 +88,7 @@ e2.prototype.S = function(i2) {
88
88
  this.t = i2;
89
89
  }
90
90
  };
91
- e2.prototype.U = function(i2) {
91
+ e.prototype.U = function(i2) {
92
92
  var t2 = i2.e, h2 = i2.x;
93
93
  if (void 0 !== t2) {
94
94
  t2.x = h2;
@@ -101,7 +101,7 @@ e2.prototype.U = function(i2) {
101
101
  if (i2 === this.t)
102
102
  this.t = h2;
103
103
  };
104
- e2.prototype.subscribe = function(i2) {
104
+ e.prototype.subscribe = function(i2) {
105
105
  var t2 = this;
106
106
  return b(function() {
107
107
  var h2 = t2.value, o2 = 32 & this.f;
@@ -113,16 +113,16 @@ e2.prototype.subscribe = function(i2) {
113
113
  }
114
114
  });
115
115
  };
116
- e2.prototype.valueOf = function() {
116
+ e.prototype.valueOf = function() {
117
117
  return this.value;
118
118
  };
119
- e2.prototype.toString = function() {
119
+ e.prototype.toString = function() {
120
120
  return this.value + "";
121
121
  };
122
- e2.prototype.peek = function() {
122
+ e.prototype.peek = function() {
123
123
  return this.v;
124
124
  };
125
- Object.defineProperty(e2.prototype, "value", { get: function() {
125
+ Object.defineProperty(e.prototype, "value", { get: function() {
126
126
  var i2 = v(this);
127
127
  if (void 0 !== i2)
128
128
  i2.i = this.i;
@@ -144,7 +144,7 @@ Object.defineProperty(e2.prototype, "value", { get: function() {
144
144
  }
145
145
  } });
146
146
  function u(i2) {
147
- return new e2(i2);
147
+ return new e(i2);
148
148
  }
149
149
  function d(i2) {
150
150
  for (var t2 = i2.s; void 0 !== t2; t2 = t2.n)
@@ -183,13 +183,13 @@ function a(i2) {
183
183
  i2.s = h2;
184
184
  }
185
185
  function l(i2) {
186
- e2.call(this, void 0);
186
+ e.call(this, void 0);
187
187
  this.x = i2;
188
188
  this.s = void 0;
189
189
  this.g = f - 1;
190
190
  this.f = 4;
191
191
  }
192
- (l.prototype = new e2()).h = function() {
192
+ (l.prototype = new e()).h = function() {
193
193
  this.f &= -3;
194
194
  if (1 & this.f)
195
195
  return false;
@@ -230,10 +230,10 @@ l.prototype.S = function(i2) {
230
230
  for (var t2 = this.s; void 0 !== t2; t2 = t2.n)
231
231
  t2.S.S(t2);
232
232
  }
233
- e2.prototype.S.call(this, i2);
233
+ e.prototype.S.call(this, i2);
234
234
  };
235
235
  l.prototype.U = function(i2) {
236
- e2.prototype.U.call(this, i2);
236
+ e.prototype.U.call(this, i2);
237
237
  if (void 0 === this.t) {
238
238
  this.f &= -33;
239
239
  for (var t2 = this.s; void 0 !== t2; t2 = t2.n)
@@ -408,7 +408,7 @@ function signalStruct(values, proto) {
408
408
  try {
409
409
  Object.assign(s2.value, v2);
410
410
  return;
411
- } catch (e3) {
411
+ } catch (e2) {
412
412
  }
413
413
  s2.value = Object.seal(signalStruct(v2));
414
414
  } else if (Array.isArray(v2))
@@ -684,11 +684,12 @@ secondary["on"] = (el, expr) => {
684
684
  let evaluate = parseExpr(el, expr, ":on");
685
685
  return (state) => {
686
686
  let listeners = evaluate(state);
687
+ let offs = [];
687
688
  for (let evt in listeners)
688
- addListener(el, evt, listeners[evt]);
689
+ offs.push(on(el, evt, listeners[evt]));
689
690
  return () => {
690
- for (let evt in listeners)
691
- removeListener(el, evt, listeners[evt]);
691
+ for (let off of offs)
692
+ off();
692
693
  };
693
694
  };
694
695
  };
@@ -701,162 +702,127 @@ var directives_default = (el, expr, state, name) => {
701
702
  return (state2) => {
702
703
  let value = evaluate(state2) || (() => {
703
704
  });
704
- addListener(el, evt, value);
705
- return () => removeListener(el, evt, value);
705
+ return on(el, evt, value);
706
706
  };
707
707
  return (state2) => attr(el, name, evaluate(state2));
708
708
  };
709
- var _stop = Symbol("stop");
710
- var addListener = (el, evt, startFn) => {
711
- let evts = evt.split("..").map((e3) => e3.startsWith("on") ? e3.slice(2) : e3), opts = { target: el, hooks: [], fn: startFn };
712
- evts[0] = evts[0].replace(/\.(\w+)?-?([\w]+)?/g, (match, mod, param) => (mods[mod]?.(opts, param), ""));
713
- let { target, hooks, fn, ...listenerOpts } = opts;
714
- if (hooks.length) {
715
- let _fn = fn;
716
- fn = (e3) => {
717
- for (let hook of hooks)
718
- if (hook(e3) === false)
719
- return false;
720
- return _fn(e3);
709
+ var on = (target, evt, origFn) => {
710
+ let ctxs = evt.split("..").map((e2) => {
711
+ let ctx = { evt: "", target, test: () => true };
712
+ ctx.evt = (e2.startsWith("on") ? e2.slice(2) : e2).replace(
713
+ /\.(\w+)?-?([\w]+)?/g,
714
+ (match, mod, param) => (ctx.test = mods[mod]?.(ctx, param) || ctx.test, "")
715
+ );
716
+ return ctx;
717
+ });
718
+ if (!origFn)
719
+ origFn = () => {
721
720
  };
722
- }
723
- if (evts.length == 1)
724
- target.addEventListener(evts[0], fn, listenerOpts);
725
- else {
726
- const nextEvt = (handler, cur = 0) => {
727
- let curListener = (e3) => {
728
- target.removeEventListener(evts[cur], curListener);
729
- if (typeof (handler = handler.call(target, e3)) !== "function")
730
- handler = () => {
731
- };
732
- if (++cur < evts.length)
733
- nextEvt(handler, cur);
734
- else if (!fn[_stop])
735
- nextEvt(fn);
736
- };
737
- target.addEventListener(evts[cur], curListener, listenerOpts);
721
+ if (ctxs.length == 1)
722
+ return addListener(origFn, ctxs[0]);
723
+ let off;
724
+ const nextEvt = (fn, cur = 0) => {
725
+ let curListener = (e2) => {
726
+ off();
727
+ if (typeof (fn = fn.call(target, e2)) !== "function")
728
+ fn = () => {
729
+ };
730
+ if (++cur < ctxs.length)
731
+ nextEvt(fn, cur);
732
+ else
733
+ nextEvt(origFn);
738
734
  };
739
- nextEvt(fn);
740
- }
735
+ return off = addListener(curListener, ctxs[cur]);
736
+ };
737
+ nextEvt(origFn);
738
+ return () => off();
741
739
  };
742
- var removeListener = (el, evt, fn) => {
743
- if (evt.indexOf("..") >= 0)
744
- fn[_stop] = true;
745
- el.removeEventListener(evt, fn);
740
+ var addListener = (fn, { evt, target, test, delayed, stop, prevent, ...opts }) => {
741
+ if (delayed)
742
+ fn = delayed(fn);
743
+ let wrappedFn = (e2) => test(e2) && (stop && e2.stopPropagation(), prevent && e2.preventDefault(), fn.call(target, e2));
744
+ target.addEventListener(evt, wrappedFn, opts);
745
+ return () => target.removeEventListener(evt, wrappedFn, opts);
746
746
  };
747
747
  var mods = {
748
- prevent({ hooks }) {
749
- hooks.push((e3) => {
750
- e3.preventDefault();
751
- });
752
- },
753
- stop({ hooks }) {
754
- hooks.push((e3) => {
755
- e3.stopPropagation();
756
- });
757
- },
758
- throttle(opts, limit) {
759
- let { fn } = opts;
760
- limit = Number(limit) || 108;
761
- let pause, planned, block = () => {
762
- pause = true;
763
- setTimeout(() => {
764
- pause = false;
765
- if (planned)
766
- return planned = false, block(), fn(e);
767
- });
768
- };
769
- opts.fn = (e3) => {
770
- if (pause)
771
- return planned = true;
772
- block();
773
- return fn(e3);
774
- };
775
- },
776
- debounce(opts, wait) {
777
- let { fn } = opts;
778
- wait = Number(wait) || 108;
779
- let timeout;
780
- opts.fn = (e3) => {
781
- clearTimeout(timeout);
782
- timeout = setTimeout(() => {
783
- timeout = null;
784
- fn(e3);
785
- }, wait);
786
- };
787
- },
788
- window(opts) {
789
- opts.target = window;
790
- },
791
- document(opts) {
792
- opts.target = document;
748
+ prevent(ctx) {
749
+ ctx.prevent = true;
793
750
  },
794
- outside({ target, hooks }) {
795
- hooks.push((e3) => {
796
- if (target.contains(e3.target))
797
- return false;
798
- if (e3.target.isConnected === false)
799
- return false;
800
- if (target.offsetWidth < 1 && target.offsetHeight < 1)
801
- return false;
802
- });
751
+ stop(ctx) {
752
+ ctx.stop = true;
803
753
  },
804
- self({ target, hooks }) {
805
- hooks.push((e3) => {
806
- return e3.target === target;
807
- });
754
+ once(ctx) {
755
+ ctx.once = true;
808
756
  },
809
- once(opts) {
810
- opts.once = true;
757
+ passive(ctx) {
758
+ ctx.passive = true;
811
759
  },
812
- passive(opts) {
813
- opts.passive = true;
760
+ capture(ctx) {
761
+ ctx.capture = true;
814
762
  },
815
- capture(opts) {
816
- opts.capture = true;
763
+ window(ctx) {
764
+ ctx.target = window;
817
765
  },
818
- ctrl({ hooks }) {
819
- hooks.push((e3) => e3.key === "Control" || e3.key === "Ctrl");
766
+ document(ctx) {
767
+ ctx.target = document;
820
768
  },
821
- shift({ hooks }) {
822
- hooks.push((e3) => e3.key === "Shift");
769
+ throttle(ctx, limit) {
770
+ ctx.delayed = (fn) => throttle(fn, Number(limit) || 108);
823
771
  },
824
- alt({ hooks }) {
825
- hooks.push((e3) => e3.key === "Alt");
772
+ debounce(ctx, wait) {
773
+ ctx.delayed = (fn) => debounce(fn, Number(wait) || 108);
826
774
  },
827
- meta({ hooks }) {
828
- hooks.push((e3) => e3.key === "Meta");
829
- },
830
- arrow({ hooks }) {
831
- hooks.push((e3) => e3.key.startsWith("Arrow"));
832
- },
833
- enter({ hooks }) {
834
- hooks.push((e3) => e3.key === "Enter");
835
- },
836
- escape({ hooks }) {
837
- hooks.push((e3) => e3.key.startsWith("Esc"));
838
- },
839
- tab({ hooks }) {
840
- hooks.push((e3) => e3.key === "Tab");
841
- },
842
- space({ hooks }) {
843
- hooks.push((e3) => e3.key === "Space" || e3.key === " ");
844
- },
845
- backspace({ hooks }) {
846
- hooks.push((e3) => e3.key === "Backspace");
847
- },
848
- delete({ hooks }) {
849
- hooks.push((e3) => e3.key === "Delete");
850
- },
851
- digit({ hooks }) {
852
- hooks.push((e3) => /\d/.test(e3.key));
853
- },
854
- letter({ hooks }) {
855
- hooks.push((e3) => /[a-zA-Z]/.test(e3.key));
775
+ outside: (ctx) => (e2) => {
776
+ let target = ctx.target;
777
+ if (target.contains(e2.target))
778
+ return false;
779
+ if (e2.target.isConnected === false)
780
+ return false;
781
+ if (target.offsetWidth < 1 && target.offsetHeight < 1)
782
+ return false;
783
+ return true;
856
784
  },
857
- character({ hooks }) {
858
- hooks.push((e3) => /^\S$/.test(e3.key));
859
- }
785
+ self: (ctx) => (e2) => e2.target === ctx.target,
786
+ ctrl: () => (e2) => e2.key === "Control" || e2.key === "Ctrl",
787
+ shift: () => (e2) => e2.key === "Shift",
788
+ alt: () => (e2) => e2.key === "Alt",
789
+ meta: () => (e2) => e2.key === "Meta",
790
+ arrow: () => (e2) => e2.key.startsWith("Arrow"),
791
+ enter: () => (e2) => e2.key === "Enter",
792
+ escape: () => (e2) => e2.key.startsWith("Esc"),
793
+ tab: () => (e2) => e2.key === "Tab",
794
+ space: () => (e2) => e2.key === "Space" || e2.key === " ",
795
+ backspace: () => (e2) => e2.key === "Backspace",
796
+ delete: () => (e2) => e2.key === "Delete",
797
+ digit: () => (e2) => /^\d$/.test(e2.key),
798
+ letter: () => (e2) => /^[a-zA-Z]$/.test(e2.key),
799
+ character: () => (e2) => /^\S$/.test(e2.key)
800
+ };
801
+ var throttle = (fn, limit) => {
802
+ let pause, planned, block = (e2) => {
803
+ pause = true;
804
+ setTimeout(() => {
805
+ pause = false;
806
+ if (planned)
807
+ return planned = false, block(e2), fn(e2);
808
+ }, limit);
809
+ };
810
+ return (e2) => {
811
+ if (pause)
812
+ return planned = true;
813
+ block(e2);
814
+ return fn(e2);
815
+ };
816
+ };
817
+ var debounce = (fn, wait) => {
818
+ let timeout;
819
+ return (e2) => {
820
+ clearTimeout(timeout);
821
+ timeout = setTimeout(() => {
822
+ timeout = null;
823
+ fn(e2);
824
+ }, wait);
825
+ };
860
826
  };
861
827
  var attr = (el, name, v2) => {
862
828
  if (v2 == null || v2 === false)
@@ -868,19 +834,19 @@ var evaluatorMemo = {};
868
834
  function parseExpr(el, expression, dir) {
869
835
  let evaluate = evaluatorMemo[expression];
870
836
  if (!evaluate) {
871
- let rightSideSafeExpression = /^[\n\s]*if.*\(.*\)/.test(expression) || /^(let|const)\s/.test(expression) ? `(() => { ${expression} })()` : expression;
837
+ let rightSideSafeExpression = /^[\n\s]*if.*\(.*\)/.test(expression) || /\b(let|const)\s/.test(expression) ? `(() => { ${expression} })()` : expression;
872
838
  try {
873
839
  evaluate = evaluatorMemo[expression] = new Function(`__scope`, `with (__scope) { return ${rightSideSafeExpression} };`);
874
- } catch (e3) {
875
- return exprError(e3, el, expression, dir);
840
+ } catch (e2) {
841
+ return exprError(e2, el, expression, dir);
876
842
  }
877
843
  }
878
844
  return (state) => {
879
845
  let result;
880
846
  try {
881
847
  result = evaluate.call(el, state);
882
- } catch (e3) {
883
- return exprError(e3, el, expression, dir);
848
+ } catch (e2) {
849
+ return exprError(e2, el, expression, dir);
884
850
  }
885
851
  return result;
886
852
  };
package/sprae.min.js CHANGED
@@ -1 +1 @@
1
- function t(){throw new Error("Cycle detected")}function i(){if(n>1)n--;else{for(var t,e=!1;void 0!==o;){var i=o;for(o=void 0,s++;void 0!==i;){var r=i.o;if(i.o=void 0,i.f&=-3,!(8&i.f)&&f(i))try{i.c()}catch(i){e||(t=i,e=!0)}i=r}}if(s=0,n--,e)throw t}}var r=void 0,o=void 0,n=0,s=0,l=0;function u(t){if(void 0!==r){var e=t.n;if(void 0===e||e.t!==r)return r.s=e={i:0,S:t,p:void 0,n:r.s,t:r,e:void 0,x:void 0,r:e},t.n=e,32&r.f&&t.S(e),e;if(-1===e.i)return e.i=0,void 0!==e.p&&(e.p.n=e.n,void 0!==e.n&&(e.n.p=e.p),e.p=void 0,e.n=r.s,r.s.p=e,r.s=e),e}}function a(t){this.v=t,this.i=0,this.n=void 0,this.t=void 0}function f(t){for(var e=t.s;void 0!==e;e=e.n)if(e.S.i!==e.i||!e.S.h()||e.S.i!==e.i)return!0;return!1}function h(t){for(var e=t.s;void 0!==e;e=e.n){var i=e.S.n;void 0!==i&&(e.r=i),e.S.n=e,e.i=-1}}function c(t){for(var e=t.s,i=void 0;void 0!==e;){var r=e.n;-1===e.i?(e.S.U(e),e.n=void 0):(void 0!==i&&(i.p=e),e.p=void 0,e.n=i,i=e),e.S.n=e.r,void 0!==e.r&&(e.r=void 0),e=r}t.s=i}function v(t){a.call(this,void 0),this.x=t,this.s=void 0,this.g=l-1,this.f=4}function p(t){var e=t.u;if(t.u=void 0,"function"==typeof e){n++;var o=r;r=void 0;try{e()}catch(e){throw t.f&=-2,t.f|=8,d(t),e}finally{r=o,i()}}}function d(t){for(var e=t.s;void 0!==e;e=e.n)e.S.U(e);t.x=void 0,t.s=void 0,p(t)}function y(t){if(r!==this)throw new Error("Out-of-order effect");c(this),r=t,this.f&=-2,8&this.f&&d(this),i()}function b(t){this.x=t,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32}function g(t){var e=new b(t);return e.c(),e.d.bind(e)}a.prototype.h=function(){return!0},a.prototype.S=function(t){this.t!==t&&void 0===t.e&&(t.x=this.t,void 0!==this.t&&(this.t.e=t),this.t=t)},a.prototype.U=function(t){var e=t.e,i=t.x;void 0!==e&&(e.x=i,t.e=void 0),void 0!==i&&(i.e=e,t.x=void 0),t===this.t&&(this.t=i)},a.prototype.subscribe=function(t){var e=this;return g((function(){var i=e.value,r=32&this.f;this.f&=-33;try{t(i)}finally{this.f|=r}}))},a.prototype.valueOf=function(){return this.value},a.prototype.toString=function(){return this.value+""},a.prototype.peek=function(){return this.v},Object.defineProperty(a.prototype,"value",{get:function(){var t=u(this);return void 0!==t&&(t.i=this.i),this.v},set:function(e){if(e!==this.v){s>100&&t(),this.v=e,this.i++,l++,n++;try{for(var r=this.t;void 0!==r;r=r.x)r.t.N()}finally{i()}}}}),(v.prototype=new a).h=function(){if(this.f&=-3,1&this.f)return!1;if(32==(36&this.f))return!0;if(this.f&=-5,this.g===l)return!0;if(this.g=l,this.f|=1,this.i>0&&!f(this))return this.f&=-2,!0;var t=r;try{h(this),r=this;var e=this.x();(16&this.f||this.v!==e||0===this.i)&&(this.v=e,this.f&=-17,this.i++)}catch(t){this.v=t,this.f|=16,this.i++}return r=t,c(this),this.f&=-2,!0},v.prototype.S=function(t){if(void 0===this.t){this.f|=36;for(var e=this.s;void 0!==e;e=e.n)e.S.S(e)}a.prototype.S.call(this,t)},v.prototype.U=function(t){if(a.prototype.U.call(this,t),void 0===this.t){this.f&=-33;for(var e=this.s;void 0!==e;e=e.n)e.S.U(e)}},v.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var t=this.t;void 0!==t;t=t.x)t.t.N()}},v.prototype.peek=function(){if(this.h()||t(),16&this.f)throw this.v;return this.v},Object.defineProperty(v.prototype,"value",{get:function(){1&this.f&&t();var e=u(this);if(this.h(),void 0!==e&&(e.i=this.i),16&this.f)throw this.v;return this.v}}),b.prototype.c=function(){var t=this.S();try{8&this.f||void 0===this.x||(this.u=this.x())}finally{t()}},b.prototype.S=function(){1&this.f&&t(),this.f|=1,this.f&=-9,p(this),h(this),n++;var e=r;return r=this,y.bind(this,e)},b.prototype.N=function(){2&this.f||(this.f|=2,this.o=o,o=this)},b.prototype.d=function(){this.f|=8,1&this.f||d(this)},Symbol.observable||=Symbol("observable");var m=new FinalizationRegistry((t=>t.call?.())),k=(t,e,i,r,o,n)=>{return t&&(s=(t[Symbol.observable]?.()||t).subscribe?.(e,i,r),n=s&&(()=>s.unsubscribe?.())||t.set&&t.call?.(o,e)||(t.then?.((t=>(!o&&e(t),r?.())),i)||(async n=>{try{for await(n of t){if(o)return;e(n)}r?.()}catch(t){i?.(t)}})())&&(t=>o=1),m.register(t,n),n);var s},w=t=>t&&t[S],S=Symbol("signal-struct");function A(t,e){if(w(t)&&!e)return t;if(x(t)){const o=Object.create(e||Object.getPrototypeOf(t)),n={},s=Object.getOwnPropertyDescriptors(t);for(let t in s){let e=s[t];if(e.get){let i=n[t]=new v(e.get.bind(o));Object.defineProperty(o,t,{get:()=>i.value,set:e.set?.bind(o),configurable:!1,enumerable:!0})}else{let s=e.value,l=(r=s)&&!!(r[Symbol.observable]||r[Symbol.asyncIterator]||r.call&&r.set||r.subscribe||r.then),u=n[t]=(i=s)&&i.peek?s:new a(l?void 0:x(s)?Object.seal(A(s)):Array.isArray(s)?A(s):s);l&&k(s,(t=>u.value=t)),Object.defineProperty(o,t,{get:()=>u.value,set(t){if(x(t)){if(x(u.value))try{return void Object.assign(u.value,t)}catch(t){}u.value=Object.seal(A(t))}else Array.isArray(t)?u.value=A(t):u.value=t},enumerable:!0,configurable:!1})}}return Object.defineProperty(o,S,{configurable:!1,enumerable:!1,value:!0}),o}var i,r;if(Array.isArray(t)&&!w(t[0]))for(let e=0;e<t.length;e++)t[e]=A(t[e]);return t}function x(t){return t&&t.constructor===Object}A.isStruct=w;var O={},j={},N={},E=t=>null===t?j:void 0===t?N:"number"==typeof t||t instanceof Number?O[t]||(O[t]=new Number(t)):"string"==typeof t||t instanceof String?O[t]||(O[t]=new String(t)):"boolean"==typeof t||t instanceof Boolean?O[t]||(O[t]=new Boolean(t)):t,W={},C={};W.if=(t,e)=>{let i=document.createTextNode(""),r=[_(t,e,":if")],o=[t],n=t;for(;(n=t.nextElementSibling)&&n.hasAttribute(":else");)n.removeAttribute(":else"),(e=n.getAttribute(":if"))?(n.removeAttribute(":if"),n.remove(),o.push(n),r.push(_(t,e,":else :if"))):(n.remove(),o.push(n),r.push((()=>1)));return t.replaceWith(n=i),t=>{let e=r.findIndex((e=>e(t)));o[e]!=n&&((n[T]||n).replaceWith(n=o[e]||i),I(n,t))}},W.with=(t,e,i)=>{I(t,A(_(t,e,"with")(i),i))};var T=Symbol(":each");W.each=(t,e)=>{let i=function(t){let e=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,i=t.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!i)return;let r=i[2].trim(),o=i[1].replace(/^\s*\(|\)\s*$/g,"").trim(),n=o.match(e);return n?[o.replace(e,"").trim(),n[1].trim(),r]:[o,"",r]}(e);if(!i)return R(new Error,t,e);const r=t[T]=document.createTextNode("");t.replaceWith(r);const o=_(t,i[2],":each"),n=t.getAttribute(":key"),s=n?_(null,n):null;t.removeAttribute(":key");const l=new WeakMap,u=new WeakMap;let a=[];return n=>{let f=o(n);f?"number"==typeof f?f=Array.from({length:f},((t,e)=>[e,e+1])):Array.isArray(f)?f=f.map(((t,e)=>[e+1,t])):"object"==typeof f?f=Object.entries(f):R(Error("Bad list value"),t,e,":each"):f=[];let h=[],c=[];for(let[e,r]of f){let o,a,f=s?.({[i[0]]:r,[i[1]]:e});("string"==typeof(v=f)||"boolean"==typeof v||"number"==typeof v)&&(f=E(f)),null==f?o=t.cloneNode(!0):(o=u.get(f))||u.set(f,o=t.cloneNode(!0)),h.push(o),null!=f&&(a=l.get(f))?a[i[0]]=r:(a=A({[i[0]]:r,[i[1]]:e},n),null!=f&&l.set(f,a)),c.push(a)}var v;!function(t,e,i,r){const o=new Map,n=new Map;let s,l;for(s=0;s<e.length;s++)o.set(e[s],s);for(s=0;s<i.length;s++)n.set(i[s],s);for(s=l=0;s!==e.length||l!==i.length;){var u=e[s],a=i[l];if(null===u)s++;else if(i.length<=l)t.removeChild(e[s]),s++;else if(e.length<=s)t.insertBefore(a,e[s]||r),l++;else if(u===a)s++,l++;else{var f=n.get(u),h=o.get(a);void 0===f?(t.removeChild(e[s]),s++):void 0===h?(t.insertBefore(a,e[s]||r),l++):(t.insertBefore(e[h],e[s]||r),e[h]=null,h>s+1&&s++,l++)}}}(r.parentNode,a,h,r),a=h;for(let t=0;t<h.length;t++)I(h[t],c[t])}},C.ref=(t,e,i)=>{i[e]=t},C.id=(t,e)=>{let i=_(t,e,":id");return e=>{return r=i(e),t.id=r||0===r?r:"";var r}},C.class=(t,e)=>{let i=_(t,e,":class"),r=t.className;return e=>{let o=i(e);t.className=r+typeof o=="string"?o:(Array.isArray(o)?o:Object.entries(o).map((([t,e])=>e?t:""))).filter(Boolean).join(" ")}},C.style=(t,e)=>{let i=_(t,e,":style"),r=t.getAttribute("style")||"";return r.endsWith(";")||(r+="; "),e=>{let o=i(e);if("string"==typeof o)t.setAttribute("style",r+o);else for(let e in o)t.style[e]=o[e]}},C.text=(t,e)=>{let i=_(t,e,":text");return e=>{let r=i(e);t.textContent=null==r?"":r}},C.data=(t,e)=>{let i=_(t,e,":data");return e=>{let r=i(e);for(let e in r)t.dataset[e]=r[e]}},C.aria=(t,e)=>{let i=_(t,e,":aria");return e=>(e=>{for(let i in e)U(t,"aria-"+z(i),null==e[i]?null:e[i]+"")})(i(e))},C[""]=(t,e)=>{let i=_(t,e,":");if(i)return e=>{let r=i(e);for(let e in r)U(t,z(e),r[e])}},C.value=(t,e)=>{let i,r,o=_(t,e,":value"),n="text"===t.type||""===t.type?e=>t.setAttribute("value",t.value=null==e?"":e):"TEXTAREA"===t.tagName||"text"===t.type||""===t.type?e=>(i=t.selectionStart,r=t.selectionEnd,t.setAttribute("value",t.value=null==e?"":e),i&&t.setSelectionRange(i,r)):"checkbox"===t.type?e=>(t.value=e?"on":"",U(t,"checked",e)):"select-one"===t.type?e=>{for(let e in t.options)e.removeAttribute("selected");t.value=e,t.selectedOptions[0]?.setAttribute("selected","")}:e=>t.value=e;return t=>n(o(t))},C.on=(t,e)=>{let i=_(t,e,":on");return e=>{let r=i(e);for(let e in r)P(t,e,r[e]);return()=>{for(let e in r)D(t,e,r[e])}}};var $=(t,e,i,r)=>{let o=r.startsWith("on")&&r.slice(2),n=_(t,e,":"+r);if(n)return o?e=>{let i=n(e)||(()=>{});return P(t,o,i),()=>D(t,o,i)}:e=>U(t,r,n(e))},B=Symbol("stop"),P=(t,e,i)=>{let r=e.split("..").map((t=>t.startsWith("on")?t.slice(2):t)),o={target:t,hooks:[],fn:i};r[0]=r[0].replace(/\.(\w+)?-?([\w]+)?/g,((t,e,i)=>(M[e]?.(o,i),"")));let{target:n,hooks:s,fn:l,...u}=o;if(s.length){let t=l;l=e=>{for(let t of s)if(!1===t(e))return!1;return t(e)}}if(1==r.length)n.addEventListener(r[0],l,u);else{const t=(e,i=0)=>{let o=s=>{n.removeEventListener(r[i],o),"function"!=typeof(e=e.call(n,s))&&(e=()=>{}),++i<r.length?t(e,i):l[B]||t(l)};n.addEventListener(r[i],o,u)};t(l)}},D=(t,e,i)=>{e.indexOf("..")>=0&&(i[B]=!0),t.removeEventListener(e,i)},M={prevent({hooks:t}){t.push((t=>{t.preventDefault()}))},stop({hooks:t}){t.push((t=>{t.stopPropagation()}))},throttle(t,i){let{fn:r}=t;i=Number(i)||108;let o,n,s=()=>{o=!0,setTimeout((()=>{if(o=!1,n)return n=!1,s(),r(e)}))};t.fn=t=>o?n=!0:(s(),r(t))},debounce(t,e){let i,{fn:r}=t;e=Number(e)||108,t.fn=t=>{clearTimeout(i),i=setTimeout((()=>{i=null,r(t)}),e)}},window(t){t.target=window},document(t){t.target=document},outside({target:t,hooks:e}){e.push((e=>!t.contains(e.target)&&!1!==e.target.isConnected&&!(t.offsetWidth<1&&t.offsetHeight<1)&&void 0))},self({target:t,hooks:e}){e.push((e=>e.target===t))},once(t){t.once=!0},passive(t){t.passive=!0},capture(t){t.capture=!0},ctrl({hooks:t}){t.push((t=>"Control"===t.key||"Ctrl"===t.key))},shift({hooks:t}){t.push((t=>"Shift"===t.key))},alt({hooks:t}){t.push((t=>"Alt"===t.key))},meta({hooks:t}){t.push((t=>"Meta"===t.key))},arrow({hooks:t}){t.push((t=>t.key.startsWith("Arrow")))},enter({hooks:t}){t.push((t=>"Enter"===t.key))},escape({hooks:t}){t.push((t=>t.key.startsWith("Esc")))},tab({hooks:t}){t.push((t=>"Tab"===t.key))},space({hooks:t}){t.push((t=>"Space"===t.key||" "===t.key))},backspace({hooks:t}){t.push((t=>"Backspace"===t.key))},delete({hooks:t}){t.push((t=>"Delete"===t.key))},digit({hooks:t}){t.push((t=>/\d/.test(t.key)))},letter({hooks:t}){t.push((t=>/[a-zA-Z]/.test(t.key)))},character({hooks:t}){t.push((t=>/^\S$/.test(t.key)))}},U=(t,e,i)=>{null==i||!1===i?t.removeAttribute(e):t.setAttribute(e,!0===i?"":"number"==typeof i||"string"==typeof i?i:"")},L={};function _(t,e,i){let r=L[e];if(!r){let o=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)\s/.test(e)?`(() => { ${e} })()`:e;try{r=L[e]=new Function("__scope",`with (__scope) { return ${o} };`)}catch(r){return R(r,t,e,i)}}return o=>{let n;try{n=r.call(t,o)}catch(r){return R(r,t,e,i)}return n}}function R(t,e,i,r){Object.assign(t,{element:e,expression:i}),console.warn(`∴ ${t.message}\n\n${r}=${i?`"${i}"\n\n`:""}`,e),setTimeout((()=>{throw t}),0)}function z(t){return t.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(t=>"-"+t.toLowerCase()))}var F=new WeakMap;function I(t,e){if(!t.children)return;if(F.has(t)){let r=F.get(t);return function(t){if(n>0)return t();n++;try{t()}finally{i()}}((()=>Object.assign(r,e))),r}const r=A(e||{}),o=[],s=(t,e=t.parentNode)=>{for(let i in W){let n=":"+i;if(t.hasAttribute?.(n)){let s=t.getAttribute(n);if(t.removeAttribute(n),o.push(W[i](t,s,r,i)),F.has(t)||t.parentNode!==e)return!1}}if(t.attributes)for(let i=0;i<t.attributes.length;){let n=t.attributes[i];if(":"!==n.name[0]){i++;continue}t.removeAttribute(n.name);let s=n.value,l=n.name.slice(1).split(":");for(let i of l){let n=C[i]||$;if(o.push(n(t,s,r,i)),F.has(t)||t.parentNode!==e)return!1}}for(let e,i=0;e=t.children[i];i++)!1===s(e,t)&&i--};s(t);for(let t of o)if(t){let e;g((()=>{"function"==typeof e&&e(),e=t(r)}))}return Object.seal(r),F.set(t,r),r}var Z=I;export{Z as default};
1
+ function t(){throw new Error("Cycle detected")}function e(){if(n>1)n--;else{for(var t,e=!1;void 0!==i;){var r=i;for(i=void 0,o++;void 0!==r;){var s=r.o;if(r.o=void 0,r.f&=-3,!(8&r.f)&&u(r))try{r.c()}catch(r){e||(t=r,e=!0)}r=s}}if(o=0,n--,e)throw t}}var r=void 0,i=void 0,n=0,o=0,s=0;function l(t){if(void 0!==r){var e=t.n;if(void 0===e||e.t!==r)return r.s=e={i:0,S:t,p:void 0,n:r.s,t:r,e:void 0,x:void 0,r:e},t.n=e,32&r.f&&t.S(e),e;if(-1===e.i)return e.i=0,void 0!==e.p&&(e.p.n=e.n,void 0!==e.n&&(e.n.p=e.p),e.p=void 0,e.n=r.s,r.s.p=e,r.s=e),e}}function a(t){this.v=t,this.i=0,this.n=void 0,this.t=void 0}function u(t){for(var e=t.s;void 0!==e;e=e.n)if(e.S.i!==e.i||!e.S.h()||e.S.i!==e.i)return!0;return!1}function f(t){for(var e=t.s;void 0!==e;e=e.n){var r=e.S.n;void 0!==r&&(e.r=r),e.S.n=e,e.i=-1}}function c(t){for(var e=t.s,r=void 0;void 0!==e;){var i=e.n;-1===e.i?(e.S.U(e),e.n=void 0):(void 0!==r&&(r.p=e),e.p=void 0,e.n=r,r=e),e.S.n=e.r,void 0!==e.r&&(e.r=void 0),e=i}t.s=r}function h(t){a.call(this,void 0),this.x=t,this.s=void 0,this.g=s-1,this.f=4}function v(t){var i=t.u;if(t.u=void 0,"function"==typeof i){n++;var o=r;r=void 0;try{i()}catch(e){throw t.f&=-2,t.f|=8,p(t),e}finally{r=o,e()}}}function p(t){for(var e=t.s;void 0!==e;e=e.n)e.S.U(e);t.x=void 0,t.s=void 0,v(t)}function d(t){if(r!==this)throw new Error("Out-of-order effect");c(this),r=t,this.f&=-2,8&this.f&&p(this),e()}function y(t){this.x=t,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32}function b(t){var e=new y(t);return e.c(),e.d.bind(e)}a.prototype.h=function(){return!0},a.prototype.S=function(t){this.t!==t&&void 0===t.e&&(t.x=this.t,void 0!==this.t&&(this.t.e=t),this.t=t)},a.prototype.U=function(t){var e=t.e,r=t.x;void 0!==e&&(e.x=r,t.e=void 0),void 0!==r&&(r.e=e,t.x=void 0),t===this.t&&(this.t=r)},a.prototype.subscribe=function(t){var e=this;return b((function(){var r=e.value,i=32&this.f;this.f&=-33;try{t(r)}finally{this.f|=i}}))},a.prototype.valueOf=function(){return this.value},a.prototype.toString=function(){return this.value+""},a.prototype.peek=function(){return this.v},Object.defineProperty(a.prototype,"value",{get:function(){var t=l(this);return void 0!==t&&(t.i=this.i),this.v},set:function(r){if(r!==this.v){o>100&&t(),this.v=r,this.i++,s++,n++;try{for(var i=this.t;void 0!==i;i=i.x)i.t.N()}finally{e()}}}}),(h.prototype=new a).h=function(){if(this.f&=-3,1&this.f)return!1;if(32==(36&this.f))return!0;if(this.f&=-5,this.g===s)return!0;if(this.g=s,this.f|=1,this.i>0&&!u(this))return this.f&=-2,!0;var t=r;try{f(this),r=this;var e=this.x();(16&this.f||this.v!==e||0===this.i)&&(this.v=e,this.f&=-17,this.i++)}catch(t){this.v=t,this.f|=16,this.i++}return r=t,c(this),this.f&=-2,!0},h.prototype.S=function(t){if(void 0===this.t){this.f|=36;for(var e=this.s;void 0!==e;e=e.n)e.S.S(e)}a.prototype.S.call(this,t)},h.prototype.U=function(t){if(a.prototype.U.call(this,t),void 0===this.t){this.f&=-33;for(var e=this.s;void 0!==e;e=e.n)e.S.U(e)}},h.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var t=this.t;void 0!==t;t=t.x)t.t.N()}},h.prototype.peek=function(){if(this.h()||t(),16&this.f)throw this.v;return this.v},Object.defineProperty(h.prototype,"value",{get:function(){1&this.f&&t();var e=l(this);if(this.h(),void 0!==e&&(e.i=this.i),16&this.f)throw this.v;return this.v}}),y.prototype.c=function(){var t=this.S();try{8&this.f||void 0===this.x||(this.u=this.x())}finally{t()}},y.prototype.S=function(){1&this.f&&t(),this.f|=1,this.f&=-9,v(this),f(this),n++;var e=r;return r=this,d.bind(this,e)},y.prototype.N=function(){2&this.f||(this.f|=2,this.o=i,i=this)},y.prototype.d=function(){this.f|=8,1&this.f||p(this)},Symbol.observable||=Symbol("observable");var g=new FinalizationRegistry((t=>t.call?.())),m=(t,e,r,i,n,o)=>{return t&&(s=(t[Symbol.observable]?.()||t).subscribe?.(e,r,i),o=s&&(()=>s.unsubscribe?.())||t.set&&t.call?.(n,e)||(t.then?.((t=>(!n&&e(t),i?.())),r)||(async o=>{try{for await(o of t){if(n)return;e(o)}i?.()}catch(t){r?.(t)}})())&&(t=>n=1),g.register(t,o),o);var s},w=t=>t&&t[S],S=Symbol("signal-struct");function A(t,e){if(w(t)&&!e)return t;if(k(t)){const n=Object.create(e||Object.getPrototypeOf(t)),o={},s=Object.getOwnPropertyDescriptors(t);for(let t in s){let e=s[t];if(e.get){let r=o[t]=new h(e.get.bind(n));Object.defineProperty(n,t,{get:()=>r.value,set:e.set?.bind(n),configurable:!1,enumerable:!0})}else{let s=e.value,l=(i=s)&&!!(i[Symbol.observable]||i[Symbol.asyncIterator]||i.call&&i.set||i.subscribe||i.then),u=o[t]=(r=s)&&r.peek?s:new a(l?void 0:k(s)?Object.seal(A(s)):Array.isArray(s)?A(s):s);l&&m(s,(t=>u.value=t)),Object.defineProperty(n,t,{get:()=>u.value,set(t){if(k(t)){if(k(u.value))try{return void Object.assign(u.value,t)}catch(t){}u.value=Object.seal(A(t))}else Array.isArray(t)?u.value=A(t):u.value=t},enumerable:!0,configurable:!1})}}return Object.defineProperty(n,S,{configurable:!1,enumerable:!1,value:!0}),n}var r,i;if(Array.isArray(t)&&!w(t[0]))for(let e=0;e<t.length;e++)t[e]=A(t[e]);return t}function k(t){return t&&t.constructor===Object}A.isStruct=w;var x={},O={},j={},N=t=>null===t?O:void 0===t?j:"number"==typeof t||t instanceof Number?x[t]||(x[t]=new Number(t)):"string"==typeof t||t instanceof String?x[t]||(x[t]=new String(t)):"boolean"==typeof t||t instanceof Boolean?x[t]||(x[t]=new Boolean(t)):t,E={},W={};E.if=(t,e)=>{let r=document.createTextNode(""),i=[L(t,e,":if")],n=[t],o=t;for(;(o=t.nextElementSibling)&&o.hasAttribute(":else");)o.removeAttribute(":else"),(e=o.getAttribute(":if"))?(o.removeAttribute(":if"),o.remove(),n.push(o),i.push(L(t,e,":else :if"))):(o.remove(),n.push(o),i.push((()=>1)));return t.replaceWith(o=r),t=>{let e=i.findIndex((e=>e(t)));n[e]!=o&&((o[$]||o).replaceWith(o=n[e]||r),I(o,t))}},E.with=(t,e,r)=>{I(t,A(L(t,e,"with")(r),r))};var $=Symbol(":each");E.each=(t,e)=>{let r=function(t){let e=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,r=t.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!r)return;let i=r[2].trim(),n=r[1].replace(/^\s*\(|\)\s*$/g,"").trim(),o=n.match(e);return o?[n.replace(e,"").trim(),o[1].trim(),i]:[n,"",i]}(e);if(!r)return R(new Error,t,e);const i=t[$]=document.createTextNode("");t.replaceWith(i);const n=L(t,r[2],":each"),o=t.getAttribute(":key"),s=o?L(null,o):null;t.removeAttribute(":key");const l=new WeakMap,a=new WeakMap;let u=[];return o=>{let f=n(o);f?"number"==typeof f?f=Array.from({length:f},((t,e)=>[e,e+1])):Array.isArray(f)?f=f.map(((t,e)=>[e+1,t])):"object"==typeof f?f=Object.entries(f):R(Error("Bad list value"),t,e,":each"):f=[];let c=[],h=[];for(let[e,i]of f){let n,u,f=s?.({[r[0]]:i,[r[1]]:e});("string"==typeof(v=f)||"boolean"==typeof v||"number"==typeof v)&&(f=N(f)),null==f?n=t.cloneNode(!0):(n=a.get(f))||a.set(f,n=t.cloneNode(!0)),c.push(n),null!=f&&(u=l.get(f))?u[r[0]]=i:(u=A({[r[0]]:i,[r[1]]:e},o),null!=f&&l.set(f,u)),h.push(u)}var v;!function(t,e,r,i){const n=new Map,o=new Map;let s,l;for(s=0;s<e.length;s++)n.set(e[s],s);for(s=0;s<r.length;s++)o.set(r[s],s);for(s=l=0;s!==e.length||l!==r.length;){var a=e[s],u=r[l];if(null===a)s++;else if(r.length<=l)t.removeChild(e[s]),s++;else if(e.length<=s)t.insertBefore(u,e[s]||i),l++;else if(a===u)s++,l++;else{var f=o.get(a),c=n.get(u);void 0===f?(t.removeChild(e[s]),s++):void 0===c?(t.insertBefore(u,e[s]||i),l++):(t.insertBefore(e[c],e[s]||i),e[c]=null,c>s+1&&s++,l++)}}}(i.parentNode,u,c,i),u=c;for(let t=0;t<c.length;t++)I(c[t],h[t])}},W.ref=(t,e,r)=>{r[e]=t},W.id=(t,e)=>{let r=L(t,e,":id");return e=>{return i=r(e),t.id=i||0===i?i:"";var i}},W.class=(t,e)=>{let r=L(t,e,":class"),i=t.className;return e=>{let n=r(e);t.className=i+typeof n=="string"?n:(Array.isArray(n)?n:Object.entries(n).map((([t,e])=>e?t:""))).filter(Boolean).join(" ")}},W.style=(t,e)=>{let r=L(t,e,":style"),i=t.getAttribute("style")||"";return i.endsWith(";")||(i+="; "),e=>{let n=r(e);if("string"==typeof n)t.setAttribute("style",i+n);else for(let e in n)t.style[e]=n[e]}},W.text=(t,e)=>{let r=L(t,e,":text");return e=>{let i=r(e);t.textContent=null==i?"":i}},W.data=(t,e)=>{let r=L(t,e,":data");return e=>{let i=r(e);for(let e in i)t.dataset[e]=i[e]}},W.aria=(t,e)=>{let r=L(t,e,":aria");return e=>(e=>{for(let r in e)U(t,"aria-"+z(r),null==e[r]?null:e[r]+"")})(r(e))},W[""]=(t,e)=>{let r=L(t,e,":");if(r)return e=>{let i=r(e);for(let e in i)U(t,z(e),i[e])}},W.value=(t,e)=>{let r,i,n=L(t,e,":value"),o="text"===t.type||""===t.type?e=>t.setAttribute("value",t.value=null==e?"":e):"TEXTAREA"===t.tagName||"text"===t.type||""===t.type?e=>(r=t.selectionStart,i=t.selectionEnd,t.setAttribute("value",t.value=null==e?"":e),r&&t.setSelectionRange(r,i)):"checkbox"===t.type?e=>(t.value=e?"on":"",U(t,"checked",e)):"select-one"===t.type?e=>{for(let e in t.options)e.removeAttribute("selected");t.value=e,t.selectedOptions[0]?.setAttribute("selected","")}:e=>t.value=e;return t=>o(n(t))},W.on=(t,e)=>{let r=L(t,e,":on");return e=>{let i=r(e),n=[];for(let e in i)n.push(T(t,e,i[e]));return()=>{for(let t of n)t()}}};var C=(t,e,r,i)=>{let n=i.startsWith("on")&&i.slice(2),o=L(t,e,":"+i);if(o)return n?e=>{let r=o(e)||(()=>{});return T(t,n,r)}:e=>U(t,i,o(e))},T=(t,e,r)=>{let i,n=e.split("..").map((e=>{let r={evt:"",target:t,test:()=>!0};return r.evt=(e.startsWith("on")?e.slice(2):e).replace(/\.(\w+)?-?([\w]+)?/g,((t,e,i)=>(r.test=P[e]?.(r,i)||r.test,""))),r}));if(r||(r=()=>{}),1==n.length)return B(r,n[0]);const o=(e,s=0)=>i=B((l=>{i(),"function"!=typeof(e=e.call(t,l))&&(e=()=>{}),++s<n.length?o(e,s):o(r)}),n[s]);return o(r),()=>i()},B=(t,{evt:e,target:r,test:i,delayed:n,stop:o,prevent:s,...l})=>{n&&(t=n(t));let a=e=>i(e)&&(o&&e.stopPropagation(),s&&e.preventDefault(),t.call(r,e));return r.addEventListener(e,a,l),()=>r.removeEventListener(e,a,l)},P={prevent(t){t.prevent=!0},stop(t){t.stop=!0},once(t){t.once=!0},passive(t){t.passive=!0},capture(t){t.capture=!0},window(t){t.target=window},document(t){t.target=document},throttle(t,e){t.delayed=t=>D(t,Number(e)||108)},debounce(t,e){t.delayed=t=>M(t,Number(e)||108)},outside:t=>e=>{let r=t.target;return!(r.contains(e.target)||!1===e.target.isConnected||r.offsetWidth<1&&r.offsetHeight<1)},self:t=>e=>e.target===t.target,ctrl:()=>t=>"Control"===t.key||"Ctrl"===t.key,shift:()=>t=>"Shift"===t.key,alt:()=>t=>"Alt"===t.key,meta:()=>t=>"Meta"===t.key,arrow:()=>t=>t.key.startsWith("Arrow"),enter:()=>t=>"Enter"===t.key,escape:()=>t=>t.key.startsWith("Esc"),tab:()=>t=>"Tab"===t.key,space:()=>t=>"Space"===t.key||" "===t.key,backspace:()=>t=>"Backspace"===t.key,delete:()=>t=>"Delete"===t.key,digit:()=>t=>/^\d$/.test(t.key),letter:()=>t=>/^[a-zA-Z]$/.test(t.key),character:()=>t=>/^\S$/.test(t.key)},D=(t,e)=>{let r,i,n=o=>{r=!0,setTimeout((()=>{if(r=!1,i)return i=!1,n(o),t(o)}),e)};return e=>r?i=!0:(n(e),t(e))},M=(t,e)=>{let r;return i=>{clearTimeout(r),r=setTimeout((()=>{r=null,t(i)}),e)}},U=(t,e,r)=>{null==r||!1===r?t.removeAttribute(e):t.setAttribute(e,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},_={};function L(t,e,r){let i=_[e];if(!i){let n=/^[\n\s]*if.*\(.*\)/.test(e)||/\b(let|const)\s/.test(e)?`(() => { ${e} })()`:e;try{i=_[e]=new Function("__scope",`with (__scope) { return ${n} };`)}catch(i){return R(i,t,e,r)}}return n=>{let o;try{o=i.call(t,n)}catch(i){return R(i,t,e,r)}return o}}function R(t,e,r,i){Object.assign(t,{element:e,expression:r}),console.warn(`∴ ${t.message}\n\n${i}=${r?`"${r}"\n\n`:""}`,e),setTimeout((()=>{throw t}),0)}function z(t){return t.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(t=>"-"+t.toLowerCase()))}var F=new WeakMap;function I(t,r){if(!t.children)return;if(F.has(t)){let i=F.get(t);return function(t){if(n>0)return t();n++;try{t()}finally{e()}}((()=>Object.assign(i,r))),i}const i=A(r||{}),o=[],s=(t,e=t.parentNode)=>{for(let r in E){let n=":"+r;if(t.hasAttribute?.(n)){let s=t.getAttribute(n);if(t.removeAttribute(n),o.push(E[r](t,s,i,r)),F.has(t)||t.parentNode!==e)return!1}}if(t.attributes)for(let r=0;r<t.attributes.length;){let n=t.attributes[r];if(":"!==n.name[0]){r++;continue}t.removeAttribute(n.name);let s=n.value,l=n.name.slice(1).split(":");for(let r of l){let n=W[r]||C;if(o.push(n(t,s,i,r)),F.has(t)||t.parentNode!==e)return!1}}for(let e,r=0;e=t.children[r];r++)!1===s(e,t)&&r--};s(t);for(let t of o)if(t){let e;b((()=>{"function"==typeof e&&e(),e=t(i)}))}return Object.seal(i),F.set(t,i),i}var Z=I;export{Z as default};
package/src/directives.js CHANGED
@@ -238,9 +238,9 @@ secondary['on'] = (el, expr) => {
238
238
 
239
239
  return (state) => {
240
240
  let listeners = evaluate(state);
241
- for (let evt in listeners) addListener(el, evt, listeners[evt])
241
+ let offs = []; for (let evt in listeners) offs.push(on(el, evt, listeners[evt]));
242
242
  return () => {
243
- for (let evt in listeners) removeListener(el, evt, listeners[evt])
243
+ for (let off of offs) off()
244
244
  }
245
245
  }
246
246
  }
@@ -255,122 +255,139 @@ export default (el, expr, state, name) => {
255
255
  if (evt) return (state => {
256
256
  // we need anonymous callback to enable modifiers like prevent
257
257
  let value = evaluate(state) || (()=>{})
258
- addListener(el, evt, value)
259
- return () => removeListener(el, evt, value)
258
+ return on(el, evt, value)
260
259
  })
261
260
 
262
261
  return state => attr(el, name, evaluate(state))
263
262
  }
264
263
 
265
- const _stop = Symbol('stop')
266
- const addListener = (el, evt, startFn) => {
264
+ // bind event to target
265
+ const on = (target, evt, origFn) => {
267
266
  // ona..onb
268
- let evts = evt.split('..').map(e => e.startsWith('on') ? e.slice(2) : e),
269
- opts = {target: el, hooks: [], fn: startFn}
270
-
271
- // onevt.debounce-108
272
- evts[0] = evts[0].replace(/\.(\w+)?-?([\w]+)?/g, (match, mod, param) => (mods[mod]?.(opts, param), ''));
273
- // we collect condition hooks into a sigle callback to check before throttles
274
- let {target, hooks, fn, ...listenerOpts} = opts
275
- if (hooks.length) {
276
- let _fn = fn
277
- fn = (e) => { for (let hook of hooks) if (hook(e) === false) return false; return _fn(e) }
278
- }
279
-
280
- if (evts.length == 1) target.addEventListener(evts[0], fn, listenerOpts);
281
- else {
282
- const nextEvt = (handler, cur=0) => {
283
- let curListener = e => {
284
- target.removeEventListener(evts[cur], curListener)
285
- if (typeof (handler = handler.call(target,e)) !== 'function') handler = ()=>{}
286
- if (++cur < evts.length) nextEvt(handler, cur);
287
- else if (!fn[_stop]) nextEvt(fn); // update only if chain isn't stopped
288
- }
289
- target.addEventListener(evts[cur], curListener, listenerOpts)
267
+ let ctxs = evt.split('..').map(e => {
268
+ let ctx = { evt:'', target, test:()=>true };
269
+ // onevt.debounce-108 -> evt.debounce-108
270
+ ctx.evt = (e.startsWith('on') ? e.slice(2) : e).replace(/\.(\w+)?-?([\w]+)?/g,
271
+ (match, mod, param) => (ctx.test = mods[mod]?.(ctx, param) || ctx.test, '')
272
+ );
273
+ return ctx;
274
+ });
275
+
276
+ // FIXME: must be in throttles
277
+ if (!origFn) origFn = () => {}
278
+
279
+ // single event bind
280
+ if (ctxs.length == 1) return addListener(origFn, ctxs[0])
281
+
282
+ // events chain cycler
283
+ let off
284
+ const nextEvt = (fn, cur=0) => {
285
+ let curListener = e => {
286
+ off();
287
+ if (typeof (fn = fn.call(target, e)) !== 'function') fn = ()=>{}
288
+ if (++cur < ctxs.length) nextEvt(fn, cur);
289
+ else nextEvt(origFn); // back to first event only if chain isn't stopped (by update)
290
290
  }
291
- nextEvt(fn)
291
+ return off = addListener(curListener, ctxs[cur])
292
292
  }
293
+ nextEvt(origFn)
294
+
295
+ return () => off()
293
296
  }
294
- const removeListener = (el, evt, fn) => {
295
- if (evt.indexOf('..')>=0) fn[_stop] = true
296
- el.removeEventListener(evt, fn);
297
- }
297
+ // add listener applying the context
298
+ const addListener = (fn, {evt, target, test, delayed, stop, prevent, ...opts} ) => {
299
+ if (delayed) fn = delayed(fn)
300
+ let wrappedFn = e => (
301
+ test(e) && (
302
+ stop&&e.stopPropagation(),
303
+ prevent&&e.preventDefault(),
304
+ fn.call(target, e)
305
+ )
306
+ )
307
+ target.addEventListener(evt, wrappedFn, opts)
308
+ return () => target.removeEventListener(evt, wrappedFn, opts)
309
+ };
298
310
 
299
311
  // event modifiers
300
312
  const mods = {
301
- prevent({hooks}) { hooks.push(e => { e.preventDefault(); })},
302
- stop({hooks}) { hooks.push(e => { e.stopPropagation(); })},
303
- throttle(opts, limit) {
304
- let {fn} = opts
305
- limit = Number(limit) || 108
306
- let pause, planned, block = () => {
307
- pause = true
308
- setTimeout(() => {
309
- pause = false
310
- // if event happened during blocked time, it schedules call by the end
311
- if (planned) return (planned = false, block(), fn(e))
312
- })
313
- }
314
- opts.fn = e => {
315
- if (pause) return (planned = true)
316
- block();
317
- return fn(e);
318
- }
319
- },
320
- debounce(opts, wait) {
321
- let {fn} = opts
322
- wait = Number(wait) || 108;
323
- let timeout
324
- opts.fn = (e) => {
325
- clearTimeout(timeout)
326
- timeout = setTimeout(() => {timeout = null; fn(e)}, wait)
327
- }
328
- },
313
+ // actions
314
+ prevent(ctx) { ctx.prevent = true },
315
+ stop(ctx) { ctx.stop = true },
316
+
317
+ // options
318
+ once(ctx) { ctx.once = true; },
319
+ passive(ctx) { ctx.passive = true; },
320
+ capture(ctx) { ctx.capture = true; },
329
321
 
330
322
  // target
331
- window(opts) { opts.target = window },
332
- document(opts) { opts.target = document },
333
- outside({target, hooks}) {
334
- hooks.push((e) => {
335
- if (target.contains(e.target)) return false
336
- if (e.target.isConnected === false) return false
337
- if (target.offsetWidth < 1 && target.offsetHeight < 1) return false
338
- })
323
+ window(ctx) { ctx.target = window },
324
+ document(ctx) { ctx.target = document },
325
+
326
+ // FIXME: test looks very similar to test, mb it can be optimized
327
+ throttle(ctx, limit) { ctx.delayed = fn => throttle(fn, Number(limit) || 108)},
328
+ debounce(ctx, wait) { ctx.delayed = fn => debounce(fn, Number(wait) || 108) },
329
+
330
+ // test
331
+ outside: ctx => e => {
332
+ let target = ctx.target
333
+ if (target.contains(e.target)) return false
334
+ if (e.target.isConnected === false) return false
335
+ if (target.offsetWidth < 1 && target.offsetHeight < 1) return false
336
+ return true
339
337
  },
340
- self({target, hooks}) { hooks.push(e => { return e.target === target })},
341
-
342
- // options
343
- once(opts) { opts.once = true; },
344
- passive(opts) { opts.passive = true; },
345
- capture(opts) { opts.capture = true; },
338
+ self: ctx => e => e.target === ctx.target,
346
339
 
347
340
  // keyboard
348
- ctrl({hooks}) { hooks.push(e => e.key === 'Control' || e.key === 'Ctrl')},
349
- shift({hooks}) { hooks.push(e => e.key === 'Shift')},
350
- alt({hooks}) { hooks.push(e => e.key === 'Alt')},
351
- meta({hooks}) { hooks.push(e => e.key === 'Meta')},
352
- arrow({hooks}) { hooks.push(e => e.key.startsWith('Arrow'))},
353
- enter({hooks}) { hooks.push(e => e.key === 'Enter')},
354
- escape({hooks}) { hooks.push(e => e.key.startsWith('Esc'))},
355
- tab({hooks}) { hooks.push(e => e.key === 'Tab')},
356
- space({hooks}) { hooks.push(e => e.key === 'Space' || e.key === ' ')},
357
- backspace({hooks}) { hooks.push(e => e.key === 'Backspace') },
358
- delete({hooks}) { hooks.push(e => e.key === 'Delete') },
359
- digit({hooks}) { hooks.push(e => /\d/.test(e.key)) },
360
- letter({hooks}) { hooks.push(e => /[a-zA-Z]/.test(e.key)) },
361
- character({hooks}) { hooks.push(e => /^\S$/.test(e.key) ) },
341
+ ctrl: ctx => e => e.key === 'Control' || e.key === 'Ctrl',
342
+ shift: ctx => e => e.key === 'Shift',
343
+ alt: ctx => e => e.key === 'Alt',
344
+ meta: ctx => e => e.key === 'Meta',
345
+ arrow: ctx => e => e.key.startsWith('Arrow'),
346
+ enter: ctx => e => e.key === 'Enter',
347
+ escape: ctx => e => e.key.startsWith('Esc'),
348
+ tab: ctx => e => e.key === 'Tab',
349
+ space: ctx => e => e.key === 'Space' || e.key === ' ',
350
+ backspace: ctx => e => e.key === 'Backspace',
351
+ delete: ctx => e => e.key === 'Delete',
352
+ digit: ctx => e => /^\d$/.test(e.key),
353
+ letter: ctx => e => /^[a-zA-Z]$/.test(e.key),
354
+ character: ctx => e => /^\S$/.test(e.key),
362
355
  };
363
356
 
357
+ // create delayed fns
358
+ const throttle = (fn, limit) => {
359
+ let pause, planned, block = (e) => {
360
+ pause = true
361
+ setTimeout(() => {
362
+ pause = false
363
+ // if event happened during blocked time, it schedules call by the end
364
+ if (planned) return (planned = false, block(e), fn(e))
365
+ }, limit)
366
+ }
367
+ return (e) => {
368
+ if (pause) return (planned = true)
369
+ block(e);
370
+ return fn(e);
371
+ }
372
+ }
373
+ const debounce = (fn, wait) => {
374
+ let timeout
375
+ return (e) => {
376
+ clearTimeout(timeout)
377
+ timeout = setTimeout(() => {timeout = null; fn(e)}, wait)
378
+ }
379
+ }
380
+
364
381
  // set attr
365
382
  const attr = (el, name, v) => {
366
383
  if (v == null || v === false) el.removeAttribute(name)
367
384
  else el.setAttribute(name, v === true ? '' : (typeof v === 'number' || typeof v === 'string') ? v : '')
368
385
  }
369
386
 
370
- let evaluatorMemo = {}
371
387
 
372
- // borrowed from alpine: https://github.com/alpinejs/alpine/blob/main/packages/alpinejs/src/evaluator.js#L61
388
+ // borrowed from alpine with improvements https://github.com/alpinejs/alpine/blob/main/packages/alpinejs/src/evaluator.js#L61
373
389
  // it seems to be more robust than subscript
390
+ let evaluatorMemo = {}
374
391
  function parseExpr(el, expression, dir) {
375
392
  // guard static-time eval errors
376
393
  let evaluate = evaluatorMemo[expression]
@@ -383,7 +400,7 @@ function parseExpr(el, expression, dir) {
383
400
  // Support expressions starting with "if" statements like: "if (...) doSomething()"
384
401
  || /^[\n\s]*if.*\(.*\)/.test(expression)
385
402
  // Support expressions starting with "let/const" like: "let foo = 'bar'"
386
- || /^(let|const)\s/.test(expression)
403
+ || /\b(let|const)\s/.test(expression)
387
404
  ? `(() => { ${expression} })()`
388
405
  : expression;
389
406
 
package/test/test.js CHANGED
@@ -96,11 +96,22 @@ test('props: multiprop', async () => {
96
96
 
97
97
  // FIXME: this must work without return
98
98
  test.todo('props: calculation', async () => {
99
- let el = h`<x :x="let a = 5; return Array.from({length:a}, (_,i)=>i).join(' ')"></x>`
100
- sprae(el);
101
- is(el.outerHTML, `<x x="01234"></x>`)
99
+ let el = h`<x :x="let a = 5; return Array.from({length: x}, (_,i)=>i).join('')"></x>`
100
+ let state = sprae(el, {x:3});
101
+ is(el.outerHTML, `<x x="012"></x>`)
102
+ state.x = 4
103
+ is(el.outerHTML, `<x x="0123"></x>`)
102
104
  })
103
105
 
106
+ test.todo('props: semicols in expression', async () => {
107
+ let el = h`<x :x="0; return Array.from({length: x}, (_,i)=>i).join('')"></x>`
108
+ let state = sprae(el, {x:3});
109
+ is(el.outerHTML, `<x x="012"></x>`)
110
+ state.x = 4
111
+ is(el.outerHTML, `<x x="0123"></x>`)
112
+ })
113
+
114
+
104
115
  test('data: base', async () => {
105
116
  let el = h`<input :data="{a:1, fooBar:2}"/>`
106
117
  let params = sprae(el)
@@ -457,7 +468,7 @@ test('each: key-based caching is in-sync with direct elements', () => {
457
468
  })
458
469
 
459
470
  test('on: base', () => {
460
- let el = h`<div :on="{click(e){log.push('click')},x}"></div>`
471
+ let el = h`<div :on="{click(e){log.push('click')}, x}"></div>`
461
472
  let log = signal([])
462
473
  let params = sprae(el, {x(){log.value.push('x')}, log})
463
474
 
@@ -560,30 +571,31 @@ test('on: chain of events', e => {
560
571
  test('on: state changes between chain of events', e => {
561
572
  let el = h`<x :on="{'x..y':fn}"></x>`
562
573
  let log = []
563
- let state = sprae(el, {log, fn: () => console.log('log1')||log.push(1)})
564
- console.log('xx')
574
+ let state = sprae(el, {log, fn: () => (log.push('x1'),()=>log.push('y1'))})
575
+ console.log('emit x, x')
565
576
  el.dispatchEvent(new window.Event('x'));
566
577
  el.dispatchEvent(new window.Event('x'));
567
- is(log, [1])
568
- state.fn = () => (console.log('log1.1')||log.push(1.1), () => log.push(2))
569
- is(log, [1])
578
+ is(log, ['x1'])
579
+ console.log('update fn')
580
+ state.fn = () => (log.push('x2'), () => log.push('y2'))
581
+ is(log, ['x1'])
570
582
  // console.log('xx')
571
583
  // NOTE: state update registers new chain listener before finishing prev chain
572
584
  // el.dispatchEvent(new window.Event('x'));
573
585
  // el.dispatchEvent(new window.Event('x'));
574
586
  // is(log, [1])
575
- console.log('yy')
587
+ console.log('emit y, y')
576
588
  el.dispatchEvent(new window.Event('y'));
577
589
  el.dispatchEvent(new window.Event('y'));
578
- is(log, [1])
579
- console.log('xx')
590
+ is(log, ['x1'])
591
+ console.log('emit x, x')
580
592
  el.dispatchEvent(new window.Event('x'));
581
593
  el.dispatchEvent(new window.Event('x'));
582
- is(log, [1, 1.1])
583
- console.log('yy')
594
+ is(log, ['x1','x2'])
595
+ console.log('emit y, y')
584
596
  el.dispatchEvent(new window.Event('y'));
585
597
  el.dispatchEvent(new window.Event('y'));
586
- is(log, [1, 1.1, 2])
598
+ is(log, ['x1','x2','y2'])
587
599
  })
588
600
 
589
601
  test('on: once', e => {
@@ -641,6 +653,7 @@ test('on: keys with prevent', e => {
641
653
  let el = h`<y :onkeydown="e=>log.push(e.key)"><x :ref="x" :onkeydown.enter.stop></x></y>`
642
654
  let state = sprae(el, {log:[]})
643
655
  state.x.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
656
+ console.log('enter')
644
657
  state.x.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
645
658
  is(state.log,['x'])
646
659
  })
@@ -654,6 +667,35 @@ test('on: debounce', async e => {
654
667
  is(state.log, ['x'])
655
668
  })
656
669
 
670
+ test('on: throttle', async e => {
671
+ let el = h`<x :onkeydown.throttle-10="e=>log.push(e.key)"></x>`
672
+ let state = sprae(el, {log:[]})
673
+ el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
674
+ el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
675
+ is(state.log, ['x'])
676
+ await time(5)
677
+ el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
678
+ is(state.log, ['x'])
679
+ await time(10)
680
+ is(state.log, ['x', 'x'])
681
+ await time(10)
682
+ is(state.log, ['x', 'x'])
683
+ el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
684
+ is(state.log, ['x', 'x', 'x'])
685
+ })
686
+
687
+ test('on: modifiers chain', async e => {
688
+ let el = h`<x :onkeydown.letter..onkeyup.letter="e=>(log.push(e.key),(e)=>log.push(e.key))"></x>`
689
+ let state = sprae(el, {log:[]})
690
+ el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
691
+ el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
692
+ is(state.log,['x'])
693
+ el.dispatchEvent(new window.KeyboardEvent('keyup', { key: 'Enter', bubbles: true }));
694
+ is(state.log,['x'])
695
+ el.dispatchEvent(new window.KeyboardEvent('keyup', { key: 'x', bubbles: true }));
696
+ is(state.log,['x', 'x'])
697
+ })
698
+
657
699
  test('with: inline', () => {
658
700
  let el = h`<x :with="{foo:'bar'}"><y :text="foo + baz"></y></x>`
659
701
  let state = sprae(el, {baz: 'qux'})