tutuca 0.9.11 → 0.9.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/tutuca.js CHANGED
@@ -280,9 +280,6 @@ class ValParser {
280
280
  this.okStrTpl = false;
281
281
  this.okSeqAccess = false;
282
282
  }
283
- parseIfOk(s, px, isOk, parseFn) {
284
- return isOk ? parseFn(s, px) : null;
285
- }
286
283
  _parseSeqAccess(s, px) {
287
284
  if (!this.okSeqAccess) {
288
285
  return null;
@@ -296,13 +293,13 @@ class ValParser {
296
293
  parse(s, px) {
297
294
  switch (getValSubType(s)) {
298
295
  case VAL_SUB_TYPE_STRING_TEMPLATE:
299
- return this.parseIfOk(s, px, this.okStrTpl, parseStrTemplate);
296
+ return this.okStrTpl ? parseStrTemplate(s, px) : null;
300
297
  case VAL_SUB_TYPE_CONST_STRING:
301
- return this.parseIfOk(s, px, this.okStrTpl, parseConst);
298
+ return this.okStrTpl ? parseConst(s, px) : null;
302
299
  case VAL_SUB_TYPE_SEQ_ACCESS:
303
300
  return this._parseSeqAccess(s, px);
304
301
  case VAL_SUB_TYPE_INVALID:
305
- return this.parseIfOk(s, px, this.okStrTpl, parseStrTemplate);
302
+ return this.okStrTpl ? parseStrTemplate(s, px) : null;
306
303
  }
307
304
  const charCode = s.charCodeAt(0);
308
305
  switch (charCode) {
@@ -314,29 +311,29 @@ class ValParser {
314
311
  return null;
315
312
  }
316
313
  case 126:
317
- return this.parseIfOk(s.slice(1), px, this.okStrTpl, parseConst);
314
+ return this.okStrTpl ? parseConst(s.slice(1), px) : null;
318
315
  case 39:
319
- return this.parseIfOk(s.slice(1, -1), px, this.okStrTpl, parseConst);
316
+ return this.okStrTpl ? parseConst(s.slice(1, -1), px) : null;
320
317
  case 64:
321
- return this.parseIfOk(s.slice(1), px, this.okBind, parseBind);
318
+ return this.okBind ? parseBind(s.slice(1), px) : null;
322
319
  case 42:
323
- return this.parseIfOk(s.slice(1), px, this.okDyn, parseDyn);
320
+ return this.okDyn ? parseDyn(s.slice(1), px) : null;
324
321
  case 46:
325
- return this.parseIfOk(s.slice(1), px, this.okField, parseField);
322
+ return this.okField ? parseField(s.slice(1), px) : null;
326
323
  case 36:
327
- return this.parseIfOk(s.slice(1), px, this.okComputed, parseComp);
324
+ return this.okComputed ? parseComp(s.slice(1), px) : null;
328
325
  case 33:
329
- return this.parseIfOk(s.slice(1), px, this.okRequest, parseReq);
326
+ return this.okRequest ? parseReq(s.slice(1), px) : null;
330
327
  }
331
328
  const num = VALID_FLOAT_RE.test(s) ? parseFloat(s) : null;
332
329
  if (Number.isFinite(num)) {
333
- return this.parseIfOk(num, px, this.okConst, parseConst);
330
+ return this.okConst ? parseConst(num, px) : null;
334
331
  } else if (s === "true" || s === "false") {
335
- return this.parseIfOk(s === "true", px, this.okConst, parseConst);
332
+ return this.okConst ? parseConst(s === "true", px) : null;
336
333
  } else if (charCode >= 97 && charCode <= 122) {
337
- return this.parseIfOk(s, px, this.okName, parseName);
334
+ return this.okName ? parseName(s, px) : null;
338
335
  } else if (charCode >= 65 && charCode <= 90) {
339
- return this.parseIfOk(s, px, this.okType, parseType);
336
+ return this.okType ? parseType(s, px) : null;
340
337
  }
341
338
  return null;
342
339
  }
@@ -419,18 +416,18 @@ class BaseVal {
419
416
  }
420
417
 
421
418
  class ConstVal extends BaseVal {
422
- constructor(value) {
419
+ constructor(val) {
423
420
  super();
424
- this.value = value;
421
+ this.val = val;
425
422
  }
426
423
  render(_stack, _rx) {
427
- return this.value;
424
+ return this.val;
428
425
  }
429
426
  eval(_stack) {
430
- return this.value;
427
+ return this.val;
431
428
  }
432
429
  toString() {
433
- const v = this.value;
430
+ const v = this.val;
434
431
  return typeof v === "string" ? `'${v}'` : `${v}`;
435
432
  }
436
433
  }
@@ -464,7 +461,7 @@ class StrTplVal extends VarVal {
464
461
  vals[i] = val;
465
462
  allConsts &&= val instanceof ConstVal;
466
463
  }
467
- return allConsts ? new ConstVal(vals.map((v) => v.value).join("")) : new StrTplVal(vals);
464
+ return allConsts ? new ConstVal(vals.map((v) => v.val).join("")) : new StrTplVal(vals);
468
465
  }
469
466
  }
470
467
 
@@ -483,13 +480,13 @@ class NameVal extends VarVal {
483
480
 
484
481
  class InputHandlerNameVal extends NameVal {
485
482
  eval(stack) {
486
- return stack.getInputHandler(this.name) ?? mk404Handler("input", this.name);
483
+ return stack.getHandlerFor(this.name, "input") ?? mk404Handler("input", this.name);
487
484
  }
488
485
  }
489
486
 
490
487
  class AlterHandlerNameVal extends NameVal {
491
488
  eval(stack) {
492
- return stack.getAlterHandler(this.name) ?? mk404Handler("alter", this.name);
489
+ return stack.getHandlerFor(this.name, "alter") ?? mk404Handler("alter", this.name);
493
490
  }
494
491
  }
495
492
  var mk404Handler = (type, name) => function(...args) {
@@ -798,7 +795,7 @@ class ConstAttrs extends Attributes {
798
795
  static fromAttrs(attrs) {
799
796
  const attrsObj = {};
800
797
  for (const attr of attrs) {
801
- attrsObj[attr.name] = attr.value.eval(null);
798
+ attrsObj[attr.name] = attr.val.eval(null);
802
799
  }
803
800
  return new ConstAttrs(attrsObj);
804
801
  }
@@ -831,7 +828,7 @@ class DynAttrs extends Attributes {
831
828
  toMacroVars() {
832
829
  const r = {};
833
830
  for (const attr of this.items) {
834
- r[attr.name] = attr.value.toString();
831
+ r[attr.name] = attr.val.toString();
835
832
  }
836
833
  return r;
837
834
  }
@@ -844,23 +841,23 @@ class BaseAttr {
844
841
  }
845
842
 
846
843
  class Attr extends BaseAttr {
847
- constructor(name, value) {
844
+ constructor(name, val) {
848
845
  super(name);
849
- this.value = value;
846
+ this.val = val;
850
847
  }
851
848
  eval(stack) {
852
- return this.value.eval(stack);
849
+ return this.val.eval(stack);
853
850
  }
854
851
  }
855
852
 
856
853
  class ConstAttr extends Attr {
857
854
  }
858
855
  class RawHtmlAttr extends Attr {
859
- constructor(value) {
860
- super("dangerouslySetInnerHTML", value ?? vp.nullConstVal);
856
+ constructor(val) {
857
+ super("dangerouslySetInnerHTML", val ?? vp.nullConstVal);
861
858
  }
862
859
  eval(stack) {
863
- return { __html: `${this.value.eval(stack)}` };
860
+ return { __html: `${this.val.eval(stack)}` };
864
861
  }
865
862
  }
866
863
  var NOT_SET_VAL = vp.nullConstVal;
@@ -940,16 +937,16 @@ class BaseNode {
940
937
  }
941
938
 
942
939
  class TextNode extends BaseNode {
943
- constructor(v) {
940
+ constructor(val) {
944
941
  super();
945
- this.v = v;
942
+ this.val = val;
946
943
  }
947
944
  render(_stack, rx) {
948
- return rx.renderText(this.v);
945
+ return rx.renderText(this.val);
949
946
  }
950
947
  isWhiteSpace() {
951
- for (let i = 0;i < this.v.length; i++) {
952
- const c = this.v.charCodeAt(i);
948
+ for (let i = 0;i < this.val.length; i++) {
949
+ const c = this.val.charCodeAt(i);
953
950
  if (!(c === 32 || c === 10 || c === 9 || c === 13)) {
954
951
  return false;
955
952
  }
@@ -957,8 +954,8 @@ class TextNode extends BaseNode {
957
954
  return true;
958
955
  }
959
956
  hasNewLine() {
960
- for (let i = 0;i < this.v.length; i++) {
961
- const c = this.v.charCodeAt(i);
957
+ for (let i = 0;i < this.val.length; i++) {
958
+ const c = this.val.charCodeAt(i);
962
959
  if (c === 10 || c === 13) {
963
960
  return true;
964
961
  }
@@ -966,7 +963,7 @@ class TextNode extends BaseNode {
966
963
  return false;
967
964
  }
968
965
  condenseWhiteSpace() {
969
- this.v = "";
966
+ this.val = "";
970
967
  }
971
968
  isConstant() {
972
969
  return true;
@@ -976,7 +973,7 @@ class TextNode extends BaseNode {
976
973
 
977
974
  class CommentNode extends TextNode {
978
975
  render(_stack, rx) {
979
- return rx.renderComment(this.v);
976
+ return rx.renderComment(this.val);
980
977
  }
981
978
  }
982
979
  function optimizeChilds(childs) {
@@ -1205,7 +1202,8 @@ class RenderNode extends RenderViewId {
1205
1202
 
1206
1203
  class RenderItNode extends RenderViewId {
1207
1204
  render(stack, rx) {
1208
- return rx.renderIt(stack, this.nodeId, "", this.viewId);
1205
+ const newStack = stack.enter(stack.it, {}, true);
1206
+ return rx.renderIt(newStack, this.nodeId, "", this.viewId);
1209
1207
  }
1210
1208
  pathInNext = true;
1211
1209
  }
@@ -1400,7 +1398,7 @@ class ParseContext {
1400
1398
  const slots = { _: new FragmentNode(anySlot) };
1401
1399
  for (const child of childs) {
1402
1400
  if (child instanceof SlotNode) {
1403
- slots[child.val.value] = child.node;
1401
+ slots[child.val.val] = child.node;
1404
1402
  } else if (!(child instanceof TextNode) || !child.isWhiteSpace()) {
1405
1403
  anySlot.push(child);
1406
1404
  }
@@ -1664,18 +1662,15 @@ class Components {
1664
1662
  const comp = this.getCompFor(v);
1665
1663
  return comp ? comp.on.stackEnter : defaultOnStackEnter;
1666
1664
  }
1667
- getInputHandlerFor(v, name) {
1668
- return this.getCompFor(v)?.input[name] ?? null;
1669
- }
1670
- getAlterHandlerFor(v, name) {
1671
- return this.getCompFor(v)?.alter[name] ?? null;
1665
+ getHandlerFor(v, name, key) {
1666
+ return this.getCompFor(v)?.[key][name] ?? null;
1672
1667
  }
1673
1668
  getRequestFor(v, name) {
1674
1669
  const comp = this.getCompFor(v);
1675
1670
  return comp ? comp.scope.lookupRequest(name) : null;
1676
1671
  }
1677
1672
  lookupComputed(v, name) {
1678
- const fn = this.getCompFor(v)?.computed[name];
1673
+ const fn = this.getHandlerFor(v, name, "computed");
1679
1674
  return fn ? this.computedCache.getKey(v, name, fn) : null;
1680
1675
  }
1681
1676
  compileStyles() {
@@ -1954,11 +1949,8 @@ class Stack {
1954
1949
  const node = this.binds.head.isFrame ? this.binds.head : this.binds.tail.head;
1955
1950
  return this.comps.lookupComputed(node.it, name);
1956
1951
  }
1957
- getInputHandler(name) {
1958
- return this.comps.getInputHandlerFor(this.it, name);
1959
- }
1960
- getAlterHandler(name) {
1961
- return this.comps.getAlterHandlerFor(this.it, name);
1952
+ getHandlerFor(name, key) {
1953
+ return this.comps.getHandlerFor(this.it, name, key);
1962
1954
  }
1963
1955
  lookupRequest(name) {
1964
1956
  return this.comps.getRequestFor(this.it, name);
@@ -1976,22 +1968,22 @@ class Stack {
1976
1968
 
1977
1969
  // src/transactor.js
1978
1970
  class State {
1979
- constructor(value) {
1980
- this.value = value;
1971
+ constructor(val) {
1972
+ this.val = val;
1981
1973
  this.changeSubs = [];
1982
1974
  }
1983
1975
  onChange(cb) {
1984
1976
  this.changeSubs.push(cb);
1985
1977
  }
1986
- set(value, info) {
1987
- const old = this.value;
1988
- this.value = value;
1978
+ set(val, info) {
1979
+ const old = this.val;
1980
+ this.val = val;
1989
1981
  for (const sub of this.changeSubs) {
1990
- sub({ value, old, info, timestamp: Date.now() });
1982
+ sub({ val, old, info, timestamp: Date.now() });
1991
1983
  }
1992
1984
  }
1993
1985
  update(fn, info) {
1994
- return this.set(fn(this.value), info);
1986
+ return this.set(fn(this.val), info);
1995
1987
  }
1996
1988
  }
1997
1989
 
@@ -2015,7 +2007,7 @@ class Transactor {
2015
2007
  return this.pushTransaction(new BubbleEvent(path, this, name, args, parent, newOpts));
2016
2008
  }
2017
2009
  async pushRequest(path, name, args = [], opts = {}, parent = null) {
2018
- const curRoot = this.state.value;
2010
+ const curRoot = this.state.val;
2019
2011
  const curLeaf = path.lookup(curRoot);
2020
2012
  const handler = this.comps.getRequestFor(curLeaf, name) ?? mkReq404(name);
2021
2013
  const resHandlerName = opts?.onResName ?? name;
@@ -2045,7 +2037,7 @@ class Transactor {
2045
2037
  }
2046
2038
  }
2047
2039
  transact(transaction) {
2048
- const curState = this.state.value;
2040
+ const curState = this.state.val;
2049
2041
  const newState = transaction.run(curState, this.comps);
2050
2042
  if (newState !== undefined) {
2051
2043
  this.state.set(newState, { transaction });
@@ -2068,10 +2060,10 @@ function nullHandler() {
2068
2060
  }
2069
2061
 
2070
2062
  class Transaction {
2071
- constructor(path, transactor) {
2063
+ constructor(path, transactor, parentTransaction = null) {
2072
2064
  this.path = path;
2073
2065
  this.transactor = transactor;
2074
- this.parentTransaction = null;
2066
+ this.parentTransaction = parentTransaction;
2075
2067
  this._task = null;
2076
2068
  }
2077
2069
  get task() {
@@ -2229,7 +2221,7 @@ class Task {
2229
2221
  constructor(info) {
2230
2222
  this.info = info;
2231
2223
  this.deps = [];
2232
- this.value = this.resolve = this.reject = null;
2224
+ this.val = this.resolve = this.reject = null;
2233
2225
  this.promise = new Promise((res, rej) => {
2234
2226
  this.resolve = res;
2235
2227
  this.reject = rej;
@@ -2241,8 +2233,8 @@ class Task {
2241
2233
  this.deps.push(task);
2242
2234
  task.promise.then((_) => this._check());
2243
2235
  }
2244
- complete(value) {
2245
- this.value = value;
2236
+ complete(val) {
2237
+ this.val = val;
2246
2238
  this._check();
2247
2239
  }
2248
2240
  _check() {
@@ -2345,7 +2337,7 @@ class App {
2345
2337
  }
2346
2338
  } else if (isDragStart) {
2347
2339
  e.target.dataset.dragging = 1;
2348
- const rootValue = this.state.value;
2340
+ const rootValue = this.state.val;
2349
2341
  const value = path.lookup(rootValue);
2350
2342
  const type = e.target.dataset.dragtype ?? "?";
2351
2343
  const stack = path.buildStack(this.makeStack(rootValue));
@@ -2371,7 +2363,7 @@ class App {
2371
2363
  }
2372
2364
  }
2373
2365
  render() {
2374
- const root = this.state.value;
2366
+ const root = this.state.val;
2375
2367
  const stack = this.makeStack(root);
2376
2368
  return this.renderFn(this.renderer.renderRoot(stack, root), this.rootNode);
2377
2369
  }
@@ -2397,7 +2389,7 @@ class App {
2397
2389
  this.rootNode.addEventListener(name, this);
2398
2390
  }
2399
2391
  this.onChange((info) => {
2400
- if (info.value !== info.old) {
2392
+ if (info.val !== info.old) {
2401
2393
  this.render();
2402
2394
  }
2403
2395
  });
@@ -2468,11 +2460,11 @@ function getClosestDropTarget(target, rootNode, count) {
2468
2460
  }
2469
2461
 
2470
2462
  class DragInfo {
2471
- constructor(path, stack, e, value, type, node) {
2463
+ constructor(path, stack, e, val, type, node) {
2472
2464
  this.path = path;
2473
2465
  this.stack = stack;
2474
2466
  this.e = e;
2475
- this.value = value;
2467
+ this.val = val;
2476
2468
  this.type = type;
2477
2469
  this.node = node;
2478
2470
  }
@@ -6865,7 +6857,7 @@ class Renderer {
6865
6857
  this.comps = comps;
6866
6858
  this.h = h;
6867
6859
  this.fragment = fragment;
6868
- this.comment = comment;
6860
+ this.renderComment = comment;
6869
6861
  this.renderFn = renderFn;
6870
6862
  this.getSeqInfo = getSeqInfo ?? basicGetSeqInfo;
6871
6863
  this.cache = cache ?? new WeakMapDomCache;
@@ -6891,13 +6883,13 @@ class Renderer {
6891
6883
  return dom.innerHTML;
6892
6884
  }
6893
6885
  renderRoot(stack, val, viewName = null) {
6894
- const c = this.comps.getCompFor(val);
6895
- const nid = c.getView(viewName).anode.nodeId ?? null;
6896
- return c ? this._rValComp(stack, val, c, nid, "ROOT", viewName) : null;
6886
+ const comp = this.comps.getCompFor(val);
6887
+ const nid = comp.getView(viewName).anode.nodeId ?? null;
6888
+ return comp ? this._rValComp(stack, val, comp, nid, "ROOT", viewName) : null;
6897
6889
  }
6898
6890
  renderIt(stack, nodeId, key, viewName) {
6899
- const c = this.comps.getCompFor(stack.it);
6900
- return c ? this._rValComp(stack, stack.it, c, nodeId, key, viewName) : null;
6891
+ const comp = this.comps.getCompFor(stack.it);
6892
+ return comp ? this._rValComp(stack, stack.it, comp, nodeId, key, viewName) : null;
6901
6893
  }
6902
6894
  _rValComp(stack, val, comp, nid, key, viewName) {
6903
6895
  const cacheKey = `${viewName ?? stack.viewsId ?? ""}${nid}-${key}`;
@@ -6907,10 +6899,13 @@ class Renderer {
6907
6899
  }
6908
6900
  const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
6909
6901
  const meta = this.renderMetadata("Comp", { nid });
6910
- const dom = this.renderFragment([meta, view.render(stack, this)]);
6902
+ const dom = this.renderFragment([meta, this.renderView(view, stack)]);
6911
6903
  this.cache.set(val, cacheKey, dom);
6912
6904
  return dom;
6913
6905
  }
6906
+ pushEachEntry(r, nid, attrName, key, dom) {
6907
+ r.push(this.renderMetadata("Each", { nid, [attrName]: key }), dom);
6908
+ }
6914
6909
  renderEach(stack, iterInfo, nodeId, viewName) {
6915
6910
  const { seq, filter, loopWith } = iterInfo.eval(stack);
6916
6911
  const [attrName, gen] = this.getSeqInfo(seq);
@@ -6920,16 +6915,14 @@ class Renderer {
6920
6915
  if (filter.call(stack.it, key, value, iterData)) {
6921
6916
  const newStack = stack.enter(value, { key }, true);
6922
6917
  const dom = this.renderIt(newStack, nodeId, key, viewName);
6923
- r.push(this.renderMetadata("Each", { nid: nodeId, [attrName]: key }));
6924
- r.push(dom);
6918
+ this.pushEachEntry(r, nodeId, attrName, key, dom);
6925
6919
  }
6926
6920
  }
6927
6921
  return r;
6928
6922
  }
6929
- renderEachWhen(stack, iterInfo, node, nid) {
6923
+ renderEachWhen(stack, iterInfo, view, nid) {
6930
6924
  const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
6931
6925
  const [attrName, gen] = this.getSeqInfo(seq);
6932
- const hasEnricher = !!enricher;
6933
6926
  const r = [];
6934
6927
  const iterData = loopWith.call(stack.it, seq);
6935
6928
  for (const [key, value] of gen(seq)) {
@@ -6937,30 +6930,31 @@ class Renderer {
6937
6930
  const bindings = { key, value };
6938
6931
  const cacheKey = `${nid}-${key}`;
6939
6932
  let cachedNode;
6940
- if (hasEnricher) {
6933
+ if (enricher) {
6941
6934
  enricher.call(stack.it, bindings, key, value, iterData);
6942
6935
  cachedNode = this.cache.get2(stack.it, value, cacheKey);
6943
6936
  } else {
6944
6937
  cachedNode = this.cache.get(value, cacheKey);
6945
6938
  }
6946
6939
  if (cachedNode) {
6947
- r.push(this.renderMetadata("Each", { nid, [attrName]: key }));
6948
- r.push(cachedNode);
6940
+ this.pushEachEntry(r, nid, attrName, key, cachedNode);
6949
6941
  continue;
6950
6942
  }
6951
6943
  const newStack = stack.enter(value, bindings, false);
6952
- const dom = node.render(newStack, this);
6953
- r.push(this.renderMetadata("Each", { nid, [attrName]: key }));
6954
- if (hasEnricher) {
6944
+ const dom = this.renderView(view, newStack);
6945
+ this.pushEachEntry(r, nid, attrName, key, dom);
6946
+ if (enricher) {
6955
6947
  this.cache.set2(stack.it, value, cacheKey, dom);
6956
6948
  } else {
6957
6949
  this.cache.set(value, cacheKey, dom);
6958
6950
  }
6959
- r.push(dom);
6960
6951
  }
6961
6952
  }
6962
6953
  return r;
6963
6954
  }
6955
+ renderView(view, stack) {
6956
+ return view.render(stack, this);
6957
+ }
6964
6958
  renderText(text) {
6965
6959
  return text;
6966
6960
  }
@@ -6968,10 +6962,7 @@ class Renderer {
6968
6962
  info.$ = type;
6969
6963
  return this.renderComment(`§${JSON.stringify(info)}§`);
6970
6964
  }
6971
- renderComment(text) {
6972
- return this.comment(text);
6973
- }
6974
- renderEmpty(_text) {
6965
+ renderEmpty() {
6975
6966
  return null;
6976
6967
  }
6977
6968
  renderTag(tagName, attrs, childs) {
@@ -7001,6 +6992,7 @@ function basicGetSeqInfo(seq) {
7001
6992
  // src/vdom.js
7002
6993
  var isHtmlAttribute = (propName) => propName[4] === "-" && (propName[0] === "d" || propName[0] === "a");
7003
6994
  var isObject = (v) => v !== null && typeof v === "object";
6995
+ var prototypesDiffer = (a, b) => Object.getPrototypeOf(a) !== Object.getPrototypeOf(b);
7004
6996
  function applyProperties(node, props, previous) {
7005
6997
  for (const propName in props) {
7006
6998
  const propValue = props[propName];
@@ -7022,41 +7014,48 @@ function applyProperties(node, props, previous) {
7022
7014
  function removeProperty(node, propName, previous) {
7023
7015
  const previousValue = previous[propName];
7024
7016
  if (propName === "dangerouslySetInnerHTML") {
7025
- node.innerHTML = "";
7017
+ node.replaceChildren();
7018
+ } else if (propName === "className") {
7019
+ node.removeAttribute("class");
7020
+ } else if (propName === "htmlFor") {
7021
+ node.removeAttribute("for");
7026
7022
  } else if (typeof previousValue === "string" || isHtmlAttribute(propName)) {
7027
- const attrName = propName === "className" ? "class" : propName === "htmlFor" ? "for" : propName;
7028
- node.removeAttribute(attrName);
7023
+ node.removeAttribute(propName);
7029
7024
  } else {
7030
7025
  node[propName] = null;
7031
7026
  }
7032
7027
  }
7033
7028
  function patchObject(node, previous, propName, propValue) {
7034
7029
  const previousValue = previous?.[propName];
7035
- if (isObject(previousValue) && Object.getPrototypeOf(previousValue) !== Object.getPrototypeOf(propValue)) {
7030
+ if (isObject(previousValue) && prototypesDiffer(previousValue, propValue)) {
7036
7031
  node[propName] = propValue;
7037
7032
  return;
7038
7033
  }
7039
- let current = node[propName];
7040
- if (!isObject(current)) {
7034
+ if (!isObject(node[propName])) {
7041
7035
  node[propName] = {};
7042
- current = node[propName];
7043
7036
  }
7044
- const target = current;
7037
+ const target = node[propName];
7045
7038
  for (const k in propValue) {
7046
7039
  target[k] = propValue[k];
7047
7040
  }
7048
7041
  }
7049
7042
 
7050
7043
  class VBase {
7051
- isEqualTo(other) {
7052
- return this === other;
7053
- }
7054
- toDom(_opts) {
7055
- return null;
7056
- }
7057
7044
  }
7058
7045
  var getKey = (child) => child instanceof VNode2 ? child.key : undefined;
7059
7046
  var isIterable = (obj) => obj != null && typeof obj !== "string" && typeof obj[Symbol.iterator] === "function";
7047
+ function childsEqual(a, b) {
7048
+ for (let i = 0;i < a.length; i++) {
7049
+ if (!a[i].isEqualTo(b[i]))
7050
+ return false;
7051
+ }
7052
+ return true;
7053
+ }
7054
+ function appendChildNodes(parent, childs, opts) {
7055
+ for (const child of childs) {
7056
+ parent.appendChild(child.toDom(opts));
7057
+ }
7058
+ }
7060
7059
  function addChild(normalizedChildren, child) {
7061
7060
  if (child == null)
7062
7061
  return;
@@ -7120,21 +7119,11 @@ class VFragment extends VBase {
7120
7119
  if (!(other instanceof VFragment) || this.childs.length !== other.childs.length) {
7121
7120
  return false;
7122
7121
  }
7123
- for (let i = 0;i < this.childs.length; i++) {
7124
- if (!this.childs[i].isEqualTo(other.childs[i])) {
7125
- return false;
7126
- }
7127
- }
7128
- return true;
7122
+ return childsEqual(this.childs, other.childs);
7129
7123
  }
7130
7124
  toDom(opts) {
7131
7125
  const fragment = opts.document.createDocumentFragment();
7132
- for (const child of this.childs) {
7133
- const childNode = child.toDom(opts);
7134
- if (childNode) {
7135
- fragment.appendChild(childNode);
7136
- }
7137
- }
7126
+ appendChildNodes(fragment, this.childs, opts);
7138
7127
  return fragment;
7139
7128
  }
7140
7129
  }
@@ -7165,23 +7154,13 @@ class VNode2 extends VBase {
7165
7154
  return false;
7166
7155
  }
7167
7156
  }
7168
- for (let i = 0;i < this.childs.length; i++) {
7169
- if (!this.childs[i].isEqualTo(other.childs[i])) {
7170
- return false;
7171
- }
7172
- }
7173
- return true;
7157
+ return childsEqual(this.childs, other.childs);
7174
7158
  }
7175
7159
  toDom(opts) {
7176
7160
  const doc = opts.document;
7177
7161
  const node = this.namespace === null ? doc.createElement(this.tag) : doc.createElementNS(this.namespace, this.tag);
7178
7162
  applyProperties(node, this.attrs, {});
7179
- for (const child of this.childs) {
7180
- const childNode = child.toDom(opts);
7181
- if (childNode) {
7182
- node.appendChild(childNode);
7183
- }
7184
- }
7163
+ appendChildNodes(node, this.childs, opts);
7185
7164
  return node;
7186
7165
  }
7187
7166
  }
@@ -7195,8 +7174,10 @@ function diffProps(a, b) {
7195
7174
  }
7196
7175
  const aValue = a[aKey];
7197
7176
  const bValue = b[aKey];
7198
- if (aValue === bValue) {} else if (isObject(aValue) && isObject(bValue)) {
7199
- if (Object.getPrototypeOf(bValue) !== Object.getPrototypeOf(aValue)) {
7177
+ if (aValue === bValue)
7178
+ continue;
7179
+ if (isObject(aValue) && isObject(bValue)) {
7180
+ if (prototypesDiffer(bValue, aValue)) {
7200
7181
  diff ??= {};
7201
7182
  diff[aKey] = bValue;
7202
7183
  } else {
@@ -7219,55 +7200,44 @@ function diffProps(a, b) {
7219
7200
  }
7220
7201
  return diff;
7221
7202
  }
7222
- function replaceNode(domNode, vnode, options) {
7223
- const parentNode = domNode.parentNode;
7224
- const newNode = vnode.toDom(options);
7225
- if (parentNode && newNode && newNode !== domNode) {
7226
- parentNode.replaceChild(newNode, domNode);
7227
- }
7228
- return newNode || domNode;
7229
- }
7230
- var bothInstanceOf = (a, b, C) => a instanceof C && b instanceof C;
7231
7203
  function morphNode(domNode, source, target, opts) {
7232
7204
  if (source === target || source.isEqualTo(target))
7233
7205
  return domNode;
7234
- if (bothInstanceOf(source, target, VText) || bothInstanceOf(source, target, VComment)) {
7235
- domNode.data = target.text;
7236
- return domNode;
7237
- }
7238
- if (bothInstanceOf(source, target, VNode2) && source.tag === target.tag && source.namespace === target.namespace && source.key === target.key) {
7239
- const propsDiff = diffProps(source.attrs, target.attrs);
7240
- if (propsDiff) {
7241
- applyProperties(domNode, propsDiff, source.attrs);
7206
+ const type = source.nodeType;
7207
+ if (type === target.nodeType) {
7208
+ if (type === 3 || type === 8) {
7209
+ domNode.data = target.text;
7210
+ return domNode;
7242
7211
  }
7243
- if (!target.attrs.dangerouslySetInnerHTML) {
7244
- morphChildren(domNode, source.childs, target.childs, source.tag, opts);
7212
+ if (type === 1 && source.tag === target.tag && source.namespace === target.namespace && source.key === target.key) {
7213
+ const propsDiff = diffProps(source.attrs, target.attrs);
7214
+ if (propsDiff)
7215
+ applyProperties(domNode, propsDiff, source.attrs);
7216
+ if (!target.attrs.dangerouslySetInnerHTML) {
7217
+ morphChildren(domNode, source.childs, target.childs, opts);
7218
+ }
7219
+ return domNode;
7220
+ }
7221
+ if (type === 11) {
7222
+ morphChildren(domNode, source.childs, target.childs, opts);
7223
+ return domNode;
7245
7224
  }
7246
- return domNode;
7247
- }
7248
- if (bothInstanceOf(source, target, VFragment)) {
7249
- morphChildren(domNode, source.childs, target.childs, null, opts);
7250
- return domNode;
7251
7225
  }
7252
- return replaceNode(domNode, target, opts);
7226
+ const newNode = target.toDom(opts);
7227
+ domNode.parentNode?.replaceChild(newNode, domNode);
7228
+ return newNode;
7253
7229
  }
7254
- function morphChildren(parentDom, oldChilds, newChilds, _parentTag, opts) {
7230
+ function morphChildren(parentDom, oldChilds, newChilds, opts) {
7255
7231
  if (oldChilds.length === 0) {
7256
- for (const child of newChilds) {
7257
- const node = child.toDom(opts);
7258
- if (node)
7259
- parentDom.appendChild(node);
7260
- }
7232
+ appendChildNodes(parentDom, newChilds, opts);
7261
7233
  return;
7262
7234
  }
7263
7235
  if (newChilds.length === 0) {
7264
- while (parentDom.firstChild) {
7265
- parentDom.removeChild(parentDom.firstChild);
7266
- }
7236
+ parentDom.replaceChildren();
7267
7237
  return;
7268
7238
  }
7269
7239
  const domNodes = Array.from(parentDom.childNodes);
7270
- const oldKeyMap = {};
7240
+ const oldKeyMap = Object.create(null);
7271
7241
  for (let i = 0;i < oldChilds.length; i++) {
7272
7242
  const key = getKey(oldChilds[i]);
7273
7243
  if (key != null)
@@ -7294,17 +7264,13 @@ function morphChildren(parentDom, oldChilds, newChilds, _parentTag, opts) {
7294
7264
  }
7295
7265
  if (oldIdx >= 0) {
7296
7266
  used[oldIdx] = 1;
7297
- const dom = domNodes[oldIdx];
7298
- const newDom = morphNode(dom, oldChilds[oldIdx], newChild, opts);
7267
+ const newDom = morphNode(domNodes[oldIdx], oldChilds[oldIdx], newChild, opts);
7299
7268
  const ref = parentDom.childNodes[j] ?? null;
7300
7269
  if (newDom !== ref)
7301
7270
  parentDom.insertBefore(newDom, ref);
7302
7271
  } else {
7303
- const dom = newChild.toDom(opts);
7304
- if (dom) {
7305
- const ref = parentDom.childNodes[j] ?? null;
7306
- parentDom.insertBefore(dom, ref);
7307
- }
7272
+ const ref = parentDom.childNodes[j] ?? null;
7273
+ parentDom.insertBefore(newChild.toDom(opts), ref);
7308
7274
  }
7309
7275
  }
7310
7276
  for (let i = oldChilds.length - 1;i >= 0; i--) {
@@ -7317,24 +7283,16 @@ var renderCache = new WeakMap;
7317
7283
  function render(vnode, container, options) {
7318
7284
  const cached = renderCache.get(container);
7319
7285
  const isFragment = vnode instanceof VFragment;
7320
- if (cached) {
7321
- const wasFragment = cached.vnode instanceof VFragment;
7322
- if (wasFragment === isFragment) {
7323
- const rootNode = wasFragment ? container : cached.dom;
7324
- const newDom = morphNode(rootNode, cached.vnode, vnode, options);
7325
- const domToCache = isFragment ? container : newDom;
7326
- renderCache.set(container, { vnode, dom: domToCache });
7327
- return newDom;
7328
- }
7329
- renderCache.delete(container);
7286
+ if (cached && cached.vnode instanceof VFragment === isFragment) {
7287
+ const oldDom = isFragment ? container : cached.dom;
7288
+ const newDom = morphNode(oldDom, cached.vnode, vnode, options);
7289
+ renderCache.set(container, { vnode, dom: isFragment ? container : newDom });
7290
+ return newDom;
7330
7291
  }
7292
+ renderCache.delete(container);
7331
7293
  const domNode = vnode.toDom(options);
7332
- if (domNode) {
7333
- container.innerHTML = "";
7334
- container.appendChild(domNode);
7335
- const domToCache = isFragment ? container : domNode;
7336
- renderCache.set(container, { vnode, dom: domToCache });
7337
- }
7294
+ container.replaceChildren(domNode);
7295
+ renderCache.set(container, { vnode, dom: isFragment ? container : domNode });
7338
7296
  return domNode;
7339
7297
  }
7340
7298
  function h(tagName, properties, children) {