sprae 2.14.1 → 2.14.2

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,13 +1,12 @@
1
1
  {
2
2
  "name": "sprae",
3
3
  "description": "DOM microhydration.",
4
- "version": "2.14.1",
4
+ "version": "2.14.2",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
7
7
  "type": "module",
8
8
  "dependencies": {
9
9
  "@preact/signals-core": "^1.2.3",
10
- "primitive-pool": "^2.0.0",
11
10
  "signal-struct": "^1.10.0",
12
11
  "swapdom": "^1.1.1"
13
12
  },
package/r&d.md CHANGED
@@ -359,12 +359,12 @@
359
359
  ? maybe define setters such that when they're set
360
360
 
361
361
  2. Use sandboxed proxy
362
- - tough evaluation
363
- - implementation hiccups
364
- - screwed up data
365
- - no full protection
362
+ - tougher evaluation
363
+ - no full protection (Function.constructor)
366
364
  - relatively slow
367
365
  + does minimal catch
366
+ + allows scope control
367
+ + allows dynamic subscription to requested fields ( no need for preact/signals neither for signal-struct )
368
368
 
369
369
  ## [x] :onclick="direct code" ? -> no: immediately invoked.
370
370
 
@@ -447,7 +447,9 @@
447
447
  * onkey.after, onkey.microtask, onkey.defer, onkey.immediate
448
448
  * onkey.tick-1?
449
449
 
450
- ## [x] Mods design -> use event modifiers, not props modifiers
450
+ ### [ ] onkey.unfocusable
451
+
452
+ ## [ ] Prop modifiers
451
453
 
452
454
  * [ ] Prop modifiers
453
455
  - overall seems code complication without much benefit
@@ -470,7 +472,8 @@
470
472
  * [ ] prop.fx="" - run effect without changing property
471
473
  * [ ] x.prop="xyz" - set element property, rather than attribute (following topic)
472
474
  * [ ] x.raf="abc" - run regularly?
473
- * [ ] x.watch-xyz - update by change of any of the deps
475
+ * [ ] x.watch-a-b-c - update by change of any of the deps
476
+ * [ ] :x.always - update by _any_ dep change
474
477
 
475
478
  ## [x] Writing props on elements (like ones in :each) -> nah, just use `:x="this.x=abc"`
476
479
 
@@ -522,4 +525,4 @@
522
525
  ? does it replace element or puts a content?
523
526
 
524
527
  1. :use="ref-id"
525
- 2. :
528
+ 2. :
package/readme.md CHANGED
@@ -139,7 +139,7 @@ Set any attribute value or run effect.
139
139
  <!-- Bulk properties -->
140
140
  <input :="{ id: name, name, type:'text', value }" />
141
141
 
142
- <!-- Effect (triggers any time foo or bar changes) -->
142
+ <!-- Effects (trigger any time foo or bar changes) -->
143
143
  <div :="if (foo) bar()" :fx="void bar()" ></div>
144
144
  ```
145
145
 
package/sprae.js CHANGED
@@ -500,22 +500,35 @@ function domdiff_default(parent, a2, b2, before) {
500
500
  return b2;
501
501
  }
502
502
 
503
- // node_modules/primitive-pool/index.js
504
- var cache = {};
505
- var nullObj = {};
506
- var undefinedObj = {};
507
- var primitive_pool_default = (key) => {
508
- if (key === null)
509
- return nullObj;
510
- if (key === void 0)
511
- return undefinedObj;
512
- if (typeof key === "number" || key instanceof Number)
513
- return cache[key] || (cache[key] = new Number(key));
514
- if (typeof key === "string" || key instanceof String)
515
- return cache[key] || (cache[key] = new String(key));
516
- if (typeof key === "boolean" || key instanceof Boolean)
517
- return cache[key] || (cache[key] = new Boolean(key));
518
- return key;
503
+ // src/weakish-map.js
504
+ var refs = /* @__PURE__ */ new WeakMap();
505
+ var set = (value) => {
506
+ const ref = new WeakRef(value);
507
+ refs.set(value, ref);
508
+ return ref;
509
+ };
510
+ var get = (value) => refs.get(value) || set(value);
511
+ var WeakishMap = class extends Map {
512
+ #registry = new FinalizationRegistry((key) => super.delete(key));
513
+ get size() {
514
+ return [...this].length;
515
+ }
516
+ constructor(entries = []) {
517
+ super();
518
+ for (const [key, value] of entries)
519
+ this.set(key, value);
520
+ }
521
+ get(key) {
522
+ return super.get(key)?.deref();
523
+ }
524
+ set(key, value) {
525
+ let ref = super.get(key);
526
+ if (ref)
527
+ this.#registry.unregister(ref);
528
+ ref = get(value);
529
+ this.#registry.register(value, key, ref);
530
+ return super.set(key, ref);
531
+ }
519
532
  };
520
533
 
521
534
  // src/directives.js
@@ -563,8 +576,8 @@ primary["each"] = (tpl, expr) => {
563
576
  const keyExpr = tpl.getAttribute(":key");
564
577
  const itemKey = keyExpr ? parseExpr(null, keyExpr) : null;
565
578
  tpl.removeAttribute(":key");
566
- const scopes = /* @__PURE__ */ new WeakMap();
567
- const itemEls = /* @__PURE__ */ new WeakMap();
579
+ const scopes = new WeakishMap();
580
+ const itemEls = new WeakishMap();
568
581
  let curEls = [];
569
582
  return (state) => {
570
583
  let list = evaluate(state);
@@ -581,8 +594,6 @@ primary["each"] = (tpl, expr) => {
581
594
  let newEls = [], elScopes = [];
582
595
  for (let [idx, item] of list) {
583
596
  let el, scope, key = itemKey?.({ [each[0]]: item, [each[1]]: idx });
584
- if (isPrimitive(key))
585
- key = primitive_pool_default(key);
586
597
  if (key == null)
587
598
  el = tpl.cloneNode(true);
588
599
  else
@@ -870,7 +881,7 @@ var evaluatorMemo = {};
870
881
  function parseExpr(el, expression, dir) {
871
882
  let evaluate = evaluatorMemo[expression];
872
883
  if (!evaluate) {
873
- let rightSideSafeExpression = /^[\n\s]*if.*\(.*\)/.test(expression) || /\b(let|const)\s/.test(expression) ? `(() => { ${expression} })()` : expression;
884
+ let rightSideSafeExpression = /^[\n\s]*if.*\(.*\)/.test(expression) || /\b(let|const)\s/.test(expression) && !dir.startsWith(":on") ? `(() => {${expression}})()` : expression;
874
885
  try {
875
886
  evaluate = evaluatorMemo[expression] = new Function(`__scope`, `with (__scope) { return ${rightSideSafeExpression.trim()} };`);
876
887
  } catch (e2) {
@@ -901,9 +912,6 @@ ${dir}=${expression ? `"${expression}"
901
912
  function dashcase(str) {
902
913
  return str.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g, (match) => "-" + match.toLowerCase());
903
914
  }
904
- function isPrimitive(obj) {
905
- return typeof obj === "string" || typeof obj === "boolean" || typeof obj === "number";
906
- }
907
915
 
908
916
  // src/core.js
909
917
  var memo = /* @__PURE__ */ new WeakMap();
package/sprae.min.js CHANGED
@@ -1 +1 @@
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)&&f(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 e={i:0,S:t,p:r.s,n:void 0,t:r,e:void 0,x:void 0,r:e},void 0!==r.s&&(r.s.n=e),r.s=e,t.n=e,32&r.f&&t.S(e),e;if(-1===e.i)return e.i=0,void 0!==e.n&&(e.n.p=e.p,void 0!==e.p&&(e.p.n=e.n),e.p=r.s,e.n=void 0,r.s.n=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 u(t){for(var e=t.s;void 0!==e;e=e.n){var r=e.S.n;if(void 0!==r&&(e.r=r),e.S.n=e,e.i=-1,void 0===e.n){t.s=e;break}}}function c(t){for(var e=t.s,r=void 0;void 0!==e;){var i=e.p;-1===e.i?(e.S.U(e),void 0!==i&&(i.n=e.n),void 0!==e.n&&(e.n.p=i)):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);try{e.c()}catch(t){throw e.d(),t}return 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){if(void 0!==this.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&&!f(this))return this.f&=-2,!0;var t=r;try{u(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(void 0!==this.t&&(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),u(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[k],k=Symbol("signal-struct");function S(t,e){if(w(t)&&!e)return t;if(A(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),f=o[t]=(r=s)&&r.peek?s:new a(l?void 0:A(s)?Object.seal(S(s)):Array.isArray(s)?S(s):s);l&&m(s,(t=>f.value=t)),Object.defineProperty(n,t,{get:()=>f.value,set(t){if(A(t)){if(A(f.value))try{return void Object.assign(f.value,t)}catch(t){}f.value=Object.seal(S(t))}else Array.isArray(t)?f.value=S(t):f.value=t},enumerable:!0,configurable:!1})}}return Object.defineProperty(n,k,{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]=S(t[e]);return t}function A(t){return t&&t.constructor===Object}S.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=[_(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(_(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),F(o,t))}},E.with=(t,e,r)=>{F(t,S(_(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 L(new Error,t,e);const i=t[$]=document.createTextNode("");t.replaceWith(i);const n=_(t,r[2],":each"),o=t.getAttribute(":key"),s=o?_(null,o):null;t.removeAttribute(":key");const l=new WeakMap,a=new WeakMap;let f=[];return o=>{let u=n(o);u?"number"==typeof u?u=Array.from({length:u},((t,e)=>[e,e+1])):Array.isArray(u)?u=u.map(((t,e)=>[e+1,t])):"object"==typeof u?u=Object.entries(u):L(Error("Bad list value"),t,e,":each"):u=[];let c=[],h=[];for(let[e,i]of u){let n,f,u=s?.({[r[0]]:i,[r[1]]:e});("string"==typeof(v=u)||"boolean"==typeof v||"number"==typeof v)&&(u=N(u)),null==u?n=t.cloneNode(!0):(n=a.get(u))||a.set(u,n=t.cloneNode(!0)),c.push(n),null!=u&&(f=l.get(u))?f[r[0]]=i:(f=S({[r[0]]:i,[r[1]]:e},o),null!=u&&l.set(u,f)),h.push(f)}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],f=r[l];if(null===a)s++;else if(r.length<=l)t.removeChild(e[s]),s++;else if(e.length<=s)t.insertBefore(f,e[s]||i),l++;else if(a===f)s++,l++;else{var u=o.get(a),c=n.get(f);void 0===u?(t.removeChild(e[s]),s++):void 0===c?(t.insertBefore(f,e[s]||i),l++):(t.insertBefore(e[c],e[s]||i),e[c]=null,c>s+1&&s++,l++)}}}(i.parentNode,f,c,i),f=c;for(let t=0;t<c.length;t++)F(c[t],h[t])}},W.ref=(t,e,r)=>{r[e]=t},W.id=(t,e)=>{let r=_(t,e,":id");return e=>{return i=r(e),t.id=i||0===i?i:"";var i}},W.class=(t,e)=>{let r=_(t,e,":class"),i=t.className;return e=>{let n=r(e),o="string"==typeof n?n:(Array.isArray(n)?n:Object.entries(n).map((([t,e])=>e?t:""))).filter(Boolean).join(" ");t.className=[i,o].filter(Boolean).join(" ")}},W.style=(t,e)=>{let r=_(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{t.setAttribute("style",i);for(let e in n)t.style.setProperty(e,n[e])}}},W.text=(t,e)=>{let r=_(t,e,":text");return e=>{let i=r(e);t.textContent=null==i?"":i}},W.data=(t,e)=>{let r=_(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=_(t,e,":aria");return e=>(e=>{for(let r in e)U(t,"aria-"+R(r),null==e[r]?null:e[r]+"")})(r(e))},W[""]=(t,e)=>{let r=_(t,e,":");if(r)return e=>{let i=r(e);for(let e in i)U(t,R(e),i[e])}},W.value=(t,e)=>{let r,i,n=_(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=_(t,e,":on");return e=>{let i=r(e),n=[];for(let e in i)n.push(B(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=_(t,e,":"+i);if(o)return n?e=>{let r=o(e)||(()=>{});return B(t,n,r)}:e=>U(t,i,o(e))},B=(t,e,r)=>{if(!r)return;let i=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.split("-"))||r.test,""))),r}));if(1==i.length)return s(r,i[0]);const n=(e,r=0)=>{let o;return o=s((s=>{r&&o();let l=e.call(t,s);"function"!=typeof l&&(l=()=>{}),r+1<i.length&&n(l,r?r+1:1)}),i[r])};let o=n(r);return()=>o();function s(t,{evt:e,target:r,test:i,defer: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},toggle(t){t.defer=(e,r)=>i=>r?(r.call?.(t.target,i),r=null):r=e()},throttle(t,e){t.defer=t=>D(t,e?Number(e)||0:108)},debounce(t,e){t.defer=t=>M(t,e?Number(e)||0: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,...e)=>t=>T.ctrl(t)&&e.every((e=>T[e]?T[e](t):t.key===e)),shift:(t,...e)=>t=>T.shift(t)&&e.every((e=>T[e]?T[e](t):t.key===e)),alt:(t,...e)=>t=>T.alt(t)&&e.every((e=>T[e]?T[e](t):t.key===e)),meta:(t,...e)=>t=>T.meta(t)&&e.every((e=>T[e]?T[e](t):t.key===e)),arrow:t=>T.arrow,enter:t=>T.enter,escape:t=>T.escape,tab:t=>T.tab,space:t=>T.space,backspace:t=>T.backspace,delete:t=>T.delete,digit:t=>T.digit,letter:t=>T.letter,character:t=>T.character},T={ctrl:t=>t.ctrlKey||"Control"===t.key||"Ctrl"===t.key,shift:t=>t.shiftKey||"Shift"===t.key,alt:t=>t.altKey||"Alt"===t.key,meta:t=>t.metaKey||"Meta"===t.key||"Command"===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=>" "===t.key||"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:"")},K={};function _(t,e,r){let i=K[e];if(!i){let n=/^[\n\s]*if.*\(.*\)/.test(e)||/\b(let|const)\s/.test(e)?`(() => { ${e} })()`:e;try{i=K[e]=new Function("__scope",`with (__scope) { return ${n.trim()} };`)}catch(i){return L(i,t,e,r)}}return n=>{let o;try{o=i.call(t,n)}catch(i){return L(i,t,e,r)}return o}}function L(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 R(t){return t.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(t=>"-"+t.toLowerCase()))}var z=new WeakMap;function F(t,r){if(!t.children)return;if(z.has(t)){let i=z.get(t);return function(t){if(n>0)return t();n++;try{t()}finally{e()}}((()=>Object.assign(i,r))),i}const i=S(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)),z.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)),z.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),z.set(t,i),i}var I=F;export{I 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,s++;void 0!==r;){var o=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=o}}if(s=0,n--,e)throw t}}var r=void 0,i=void 0,n=0,s=0,o=0;function l(t){if(void 0!==r){var e=t.n;if(void 0===e||e.t!==r)return e={i:0,S:t,p:r.s,n:void 0,t:r,e:void 0,x:void 0,r:e},void 0!==r.s&&(r.s.n=e),r.s=e,t.n=e,32&r.f&&t.S(e),e;if(-1===e.i)return e.i=0,void 0!==e.n&&(e.n.p=e.p,void 0!==e.p&&(e.p.n=e.n),e.p=r.s,e.n=void 0,r.s.n=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;if(void 0!==r&&(e.r=r),e.S.n=e,e.i=-1,void 0===e.n){t.s=e;break}}}function c(t){for(var e=t.s,r=void 0;void 0!==e;){var i=e.p;-1===e.i?(e.S.U(e),void 0!==i&&(i.n=e.n),void 0!==e.n&&(e.n.p=i)):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=o-1,this.f=4}function v(t){var i=t.u;if(t.u=void 0,"function"==typeof i){n++;var s=r;r=void 0;try{i()}catch(e){throw t.f&=-2,t.f|=8,p(t),e}finally{r=s,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);try{e.c()}catch(t){throw e.d(),t}return 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){if(void 0!==this.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){s>100&&t(),this.v=r,this.i++,o++,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===o)return!0;if(this.g=o,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(void 0!==this.t&&(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,s)=>{return t&&(o=(t[Symbol.observable]?.()||t).subscribe?.(e,r,i),s=o&&(()=>o.unsubscribe?.())||t.set&&t.call?.(n,e)||(t.then?.((t=>(!n&&e(t),i?.())),r)||(async s=>{try{for await(s of t){if(n)return;e(s)}i?.()}catch(t){r?.(t)}})())&&(t=>n=1),g.register(t,s),s);var o},w=t=>t&&t[k],k=Symbol("signal-struct");function A(t,e){if(w(t)&&!e)return t;if(S(t)){const n=Object.create(e||Object.getPrototypeOf(t)),s={},o=Object.getOwnPropertyDescriptors(t);for(let t in o){let e=o[t];if(e.get){let r=s[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 o=e.value,l=(i=o)&&!!(i[Symbol.observable]||i[Symbol.asyncIterator]||i.call&&i.set||i.subscribe||i.then),u=s[t]=(r=o)&&r.peek?o:new a(l?void 0:S(o)?Object.seal(A(o)):Array.isArray(o)?A(o):o);l&&m(o,(t=>u.value=t)),Object.defineProperty(n,t,{get:()=>u.value,set(t){if(S(t)){if(S(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,k,{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 S(t){return t&&t.constructor===Object}A.isStruct=w;var x=new WeakMap,O=class extends Map{#t=new FinalizationRegistry((t=>super.delete(t)));get size(){return[...this].length}constructor(t=[]){super();for(const[e,r]of t)this.set(e,r)}get(t){return super.get(t)?.deref()}set(t,e){let r=super.get(t);return r&&this.#t.unregister(r),r=(t=>x.get(t)||(t=>{const e=new WeakRef(t);return x.set(t,e),e})(t))(e),this.#t.register(e,t,r),super.set(t,r)}},j={},N={};j.if=(t,e)=>{let r=document.createTextNode(""),i=[U(t,e,":if")],n=[t],s=t;for(;(s=t.nextElementSibling)&&s.hasAttribute(":else");)s.removeAttribute(":else"),(e=s.getAttribute(":if"))?(s.removeAttribute(":if"),s.remove(),n.push(s),i.push(U(t,e,":else :if"))):(s.remove(),n.push(s),i.push((()=>1)));return t.replaceWith(s=r),t=>{let e=i.findIndex((e=>e(t)));n[e]!=s&&((s[E]||s).replaceWith(s=n[e]||r),_(s,t))}},j.with=(t,e,r)=>{_(t,A(U(t,e,"with")(r),r))};var E=Symbol(":each");j.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(),s=n.match(e);return s?[n.replace(e,"").trim(),s[1].trim(),i]:[n,"",i]}(e);if(!r)return R(new Error,t,e);const i=t[E]=document.createTextNode("");t.replaceWith(i);const n=U(t,r[2],":each"),s=t.getAttribute(":key"),o=s?U(null,s):null;t.removeAttribute(":key");const l=new O,a=new O;let u=[];return s=>{let f=n(s);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=o?.({[r[0]]:i,[r[1]]:e});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},s),null!=f&&l.set(f,u)),h.push(u)}!function(t,e,r,i){const n=new Map,s=new Map;let o,l;for(o=0;o<e.length;o++)n.set(e[o],o);for(o=0;o<r.length;o++)s.set(r[o],o);for(o=l=0;o!==e.length||l!==r.length;){var a=e[o],u=r[l];if(null===a)o++;else if(r.length<=l)t.removeChild(e[o]),o++;else if(e.length<=o)t.insertBefore(u,e[o]||i),l++;else if(a===u)o++,l++;else{var f=s.get(a),c=n.get(u);void 0===f?(t.removeChild(e[o]),o++):void 0===c?(t.insertBefore(u,e[o]||i),l++):(t.insertBefore(e[c],e[o]||i),e[c]=null,c>o+1&&o++,l++)}}}(i.parentNode,u,c,i),u=c;for(let t=0;t<c.length;t++)_(c[t],h[t])}},N.ref=(t,e,r)=>{r[e]=t},N.id=(t,e)=>{let r=U(t,e,":id");return e=>{return i=r(e),t.id=i||0===i?i:"";var i}},N.class=(t,e)=>{let r=U(t,e,":class"),i=t.className;return e=>{let n=r(e),s="string"==typeof n?n:(Array.isArray(n)?n:Object.entries(n).map((([t,e])=>e?t:""))).filter(Boolean).join(" ");t.className=[i,s].filter(Boolean).join(" ")}},N.style=(t,e)=>{let r=U(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{t.setAttribute("style",i);for(let e in n)t.style.setProperty(e,n[e])}}},N.text=(t,e)=>{let r=U(t,e,":text");return e=>{let i=r(e);t.textContent=null==i?"":i}},N.data=(t,e)=>{let r=U(t,e,":data");return e=>{let i=r(e);for(let e in i)t.dataset[e]=i[e]}},N.aria=(t,e)=>{let r=U(t,e,":aria");return e=>(e=>{for(let r in e)D(t,"aria-"+z(r),null==e[r]?null:e[r]+"")})(r(e))},N[""]=(t,e)=>{let r=U(t,e,":");if(r)return e=>{let i=r(e);for(let e in i)D(t,z(e),i[e])}},N.value=(t,e)=>{let r,i,n=U(t,e,":value"),s="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":"",D(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=>s(n(t))},N.on=(t,e)=>{let r=U(t,e,":on");return e=>{let i=r(e),n=[];for(let e in i)n.push($(t,e,i[e]));return()=>{for(let t of n)t()}}};var W=(t,e,r,i)=>{let n=i.startsWith("on")&&i.slice(2),s=U(t,e,":"+i);if(s)return n?e=>{let r=s(e)||(()=>{});return $(t,n,r)}:e=>D(t,i,s(e))},$=(t,e,r)=>{if(!r)return;let i=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=C[e]?.(r,...i.split("-"))||r.test,""))),r}));if(1==i.length)return o(r,i[0]);const n=(e,r=0)=>{let s;return s=o((o=>{r&&s();let l=e.call(t,o);"function"!=typeof l&&(l=()=>{}),r+1<i.length&&n(l,r?r+1:1)}),i[r])};let s=n(r);return()=>s();function o(t,{evt:e,target:r,test:i,defer:n,stop:s,prevent:o,...l}){n&&(t=n(t));let a=e=>i(e)&&(s&&e.stopPropagation(),o&&e.preventDefault(),t.call(r,e));return r.addEventListener(e,a,l),()=>r.removeEventListener(e,a,l)}},C={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},toggle(t){t.defer=(e,r)=>i=>r?(r.call?.(t.target,i),r=null):r=e()},throttle(t,e){t.defer=t=>T(t,e?Number(e)||0:108)},debounce(t,e){t.defer=t=>B(t,e?Number(e)||0: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,...e)=>t=>P.ctrl(t)&&e.every((e=>P[e]?P[e](t):t.key===e)),shift:(t,...e)=>t=>P.shift(t)&&e.every((e=>P[e]?P[e](t):t.key===e)),alt:(t,...e)=>t=>P.alt(t)&&e.every((e=>P[e]?P[e](t):t.key===e)),meta:(t,...e)=>t=>P.meta(t)&&e.every((e=>P[e]?P[e](t):t.key===e)),arrow:t=>P.arrow,enter:t=>P.enter,escape:t=>P.escape,tab:t=>P.tab,space:t=>P.space,backspace:t=>P.backspace,delete:t=>P.delete,digit:t=>P.digit,letter:t=>P.letter,character:t=>P.character},P={ctrl:t=>t.ctrlKey||"Control"===t.key||"Ctrl"===t.key,shift:t=>t.shiftKey||"Shift"===t.key,alt:t=>t.altKey||"Alt"===t.key,meta:t=>t.metaKey||"Meta"===t.key||"Command"===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=>" "===t.key||"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)},T=(t,e)=>{let r,i,n=s=>{r=!0,setTimeout((()=>{if(r=!1,i)return i=!1,n(s),t(s)}),e)};return e=>r?i=!0:(n(e),t(e))},B=(t,e)=>{let r;return i=>{clearTimeout(r),r=setTimeout((()=>{r=null,t(i)}),e)}},D=(t,e,r)=>{null==r||!1===r?t.removeAttribute(e):t.setAttribute(e,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},M={};function U(t,e,r){let i=M[e];if(!i){let n=/^[\n\s]*if.*\(.*\)/.test(e)||/\b(let|const)\s/.test(e)&&!r.startsWith(":on")?`(() => {${e}})()`:e;try{i=M[e]=new Function("__scope",`with (__scope) { return ${n.trim()} };`)}catch(i){return R(i,t,e,r)}}return n=>{let s;try{s=i.call(t,n)}catch(i){return R(i,t,e,r)}return s}}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 K=new WeakMap;function _(t,r){if(!t.children)return;if(K.has(t)){let i=K.get(t);return function(t){if(n>0)return t();n++;try{t()}finally{e()}}((()=>Object.assign(i,r))),i}const i=A(r||{}),s=[],o=(t,e=t.parentNode)=>{for(let r in j){let n=":"+r;if(t.hasAttribute?.(n)){let o=t.getAttribute(n);if(t.removeAttribute(n),s.push(j[r](t,o,i,r)),K.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 o=n.value,l=n.name.slice(1).split(":");for(let r of l){let n=N[r]||W;if(s.push(n(t,o,i,r)),K.has(t)||t.parentNode!==e)return!1}}for(let e,r=0;e=t.children[r];r++)!1===o(e,t)&&r--};o(t);for(let t of s)if(t){let e;b((()=>{"function"==typeof e&&e(),e=t(i)}))}return Object.seal(i),K.set(t,i),i}var F=_;export{F as default};
package/src/directives.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import sprae from './core.js'
3
3
  import swap from './domdiff.js'
4
4
  import signalStruct from 'signal-struct'
5
- import p from 'primitive-pool'
5
+ import { WeakishMap } from './weakish-map.js'
6
6
 
7
7
  // reserved directives - order matters!
8
8
  // primary initialized first by selector, secondary initialized by iterating attributes
@@ -69,8 +69,8 @@ primary['each'] = (tpl, expr) => {
69
69
  tpl.removeAttribute(':key')
70
70
 
71
71
 
72
- const scopes = new WeakMap() // stores scope per data item
73
- const itemEls = new WeakMap() // element per data item
72
+ const scopes = new WeakishMap() // stores scope per data item
73
+ const itemEls = new WeakishMap() // element per data item
74
74
  let curEls = []
75
75
 
76
76
  return (state) => {
@@ -88,7 +88,6 @@ primary['each'] = (tpl, expr) => {
88
88
 
89
89
  for (let [idx, item] of list) {
90
90
  let el, scope, key = itemKey?.({[each[0]]: item, [each[1]]: idx})
91
- if (isPrimitive(key)) key = p(key); // singletonize key
92
91
 
93
92
  // we consider if data items are primitive, then nodes needn't be cached
94
93
  // since likely they're very simple to create
@@ -107,7 +106,6 @@ primary['each'] = (tpl, expr) => {
107
106
  elScopes.push(scope)
108
107
  }
109
108
 
110
- // swap is really fast & tiny
111
109
  swap(holder.parentNode, curEls, newEls, holder)
112
110
  curEls = newEls
113
111
 
@@ -422,8 +420,8 @@ function parseExpr(el, expression, dir) {
422
420
  // Support expressions starting with "if" statements like: "if (...) doSomething()"
423
421
  || /^[\n\s]*if.*\(.*\)/.test(expression)
424
422
  // Support expressions starting with "let/const" like: "let foo = 'bar'"
425
- || /\b(let|const)\s/.test(expression)
426
- ? `(() => { ${expression} })()`
423
+ || (/\b(let|const)\s/.test(expression) && !dir.startsWith(':on'))
424
+ ? `(() => {${expression}})()`
427
425
  : expression;
428
426
 
429
427
  try {
@@ -451,7 +449,3 @@ function exprError(error, element, expression, dir) {
451
449
  function dashcase(str) {
452
450
  return str.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g, (match) => '-' + match.toLowerCase());
453
451
  };
454
-
455
- function isPrimitive(obj) {
456
- return typeof obj === 'string' || typeof obj === 'boolean' || typeof obj === 'number'
457
- }
@@ -0,0 +1,29 @@
1
+ // based on https://github.com/WebReflection/not-so-weak/
2
+ const refs = new WeakMap;
3
+
4
+ const set = value => {
5
+ const ref = new WeakRef(value);
6
+ refs.set(value, ref);
7
+ return ref;
8
+ };
9
+
10
+ const get = value => refs.get(value) || set(value);
11
+
12
+ export class WeakishMap extends Map {
13
+ #registry = new FinalizationRegistry(key => super.delete(key));
14
+ get size() { return [...this].length }
15
+ constructor(entries = []) {
16
+ super();
17
+ for (const [key, value] of entries) this.set(key, value);
18
+ }
19
+ get(key) {
20
+ return super.get(key)?.deref();
21
+ }
22
+ set(key, value) {
23
+ let ref = super.get(key);
24
+ if (ref) this.#registry.unregister(ref);
25
+ ref = get(value);
26
+ this.#registry.register(value, key, ref);
27
+ return super.set(key, ref);
28
+ }
29
+ }
package/test/test.js CHANGED
@@ -64,6 +64,13 @@ test('common: newlines', async () => {
64
64
  is(el.outerHTML, `<x>1</x>`)
65
65
  })
66
66
 
67
+ test('common: const in on', async () => {
68
+ let el = h`<div :onx="() => {const x=1; y=x+1}"></div>`
69
+ let state = sprae(el, {y:0})
70
+ el.dispatchEvent(new CustomEvent('x'))
71
+ is(state.y, 2)
72
+ })
73
+
67
74
  test('style', async () => {
68
75
  let el = h`<x style="left: 1px" :style="style"></x>`
69
76
  let params = sprae(el, {style: "top: 1px"})
@@ -113,7 +120,7 @@ test('props: multiprop', async () => {
113
120
  })
114
121
 
115
122
  // FIXME: this must work without return
116
- test.todo('props: calculation', async () => {
123
+ test('props: calculation', async () => {
117
124
  let el = h`<x :x="let a = 5; return Array.from({length: x}, (_,i)=>i).join('')"></x>`
118
125
  let state = sprae(el, {x:3});
119
126
  is(el.outerHTML, `<x x="012"></x>`)