tutuca 0.9.26 → 0.9.28

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.
@@ -245,6 +245,7 @@ class PathBuilder {
245
245
  var VALID_VAL_ID_RE = /^[a-zA-Z][a-zA-Z0-9_]*$/;
246
246
  var isValidValId = (name) => VALID_VAL_ID_RE.test(name);
247
247
  var VALID_FLOAT_RE = /^-?[0-9]+(\.[0-9]+)?$/;
248
+ var STR_TPL_SPLIT_RE = /(\{[^}]+\})/g;
248
249
  var parseStrTemplate = (v, px) => StrTplVal.parse(v, px);
249
250
  var parseConst = (v, _) => new ConstVal(v);
250
251
  var parseName = (v, _) => isValidValId(v) ? new NameVal(v) : null;
@@ -293,13 +294,10 @@ class ValParser {
293
294
  switch (charCode) {
294
295
  case 94: {
295
296
  const newS = px.frame.macroVars?.[s.slice(1)];
296
- if (newS !== undefined) {
297
+ if (newS !== undefined)
297
298
  return this.parse(newS, px);
298
- }
299
299
  return null;
300
300
  }
301
- case 126:
302
- return this.okStrTpl ? parseConst(s.slice(1), px) : null;
303
301
  case 39:
304
302
  return this.okStrTpl ? parseConst(s.slice(1, -1), px) : null;
305
303
  case 64:
@@ -423,7 +421,7 @@ class StrTplVal extends VarVal {
423
421
  return strs.join("");
424
422
  }
425
423
  static parse(s, px) {
426
- const parts = s.split(/(\{[^}]+\})/g);
424
+ const parts = s.split(STR_TPL_SPLIT_RE);
427
425
  const vals = new Array(parts.length);
428
426
  let allConsts = true;
429
427
  for (let i = 0;i < parts.length; i++) {
@@ -920,8 +918,8 @@ class TextNode extends BaseNode {
920
918
  }
921
919
  return false;
922
920
  }
923
- condenseWhiteSpace() {
924
- this.val = "";
921
+ condenseWhiteSpace(replacement = "") {
922
+ this.val = replacement;
925
923
  }
926
924
  isConstant() {
927
925
  return true;
@@ -944,9 +942,8 @@ function optimizeChilds(childs) {
944
942
  }
945
943
  }
946
944
  function optimizeNode(node) {
947
- if (node.isConstant()) {
945
+ if (node.isConstant())
948
946
  return new RenderOnceNode(node);
949
- }
950
947
  node.optimize();
951
948
  return node;
952
949
  }
@@ -1013,9 +1010,9 @@ class ANode extends BaseNode {
1013
1010
  return ANode.fromDOM(nodes[0] ?? new px.Text(""), px);
1014
1011
  }
1015
1012
  static fromDOM(node, px) {
1016
- if (px.isTextNode(node))
1013
+ if (node instanceof px.Text)
1017
1014
  return new TextNode(node.textContent);
1018
- else if (px.isCommentNode(node))
1015
+ else if (node instanceof px.Comment)
1019
1016
  return new CommentNode(node.textContent);
1020
1017
  const { childNodes, attributes: attrs, tagName: tag } = node;
1021
1018
  const childs = new Array(childNodes.length);
@@ -1061,7 +1058,7 @@ class ANode extends BaseNode {
1061
1058
  if (textChild)
1062
1059
  childs.unshift(new RenderTextNode(null, textChild));
1063
1060
  const domChilds = tag !== "PRE" ? condenseChildsWhites(childs) : childs;
1064
- return wrap(new DomNode(tag.toLowerCase(), nAttrs, domChilds), px, wrappers);
1061
+ return wrap(new DomNode(tag, nAttrs, domChilds), px, wrappers);
1065
1062
  }
1066
1063
  return new CommentNode(`Error: InvalidTagName ${tag}`);
1067
1064
  }
@@ -1104,9 +1101,9 @@ class MacroNode extends BaseNode {
1104
1101
  if (this.px.isInsideMacro(name))
1105
1102
  throw new Error(`Recursive macro expansion: ${name}`);
1106
1103
  const macro = scope.lookupMacro(name);
1107
- if (macro === null) {
1104
+ if (macro === null)
1108
1105
  this.node = new CommentNode(`bad macro: ${name}`);
1109
- } else {
1106
+ else {
1110
1107
  const vars = { ...macro.defaults, ...attrs };
1111
1108
  this.node = macro.expand(this.px.enterMacro(name, vars, slots));
1112
1109
  for (const key in this.dataAttrs)
@@ -1325,12 +1322,6 @@ class ParseContext {
1325
1322
  newDOMParser() {
1326
1323
  return new this.DOMParser;
1327
1324
  }
1328
- isTextNode(v) {
1329
- return v instanceof this.Text;
1330
- }
1331
- isCommentNode(v) {
1332
- return v instanceof this.Comment;
1333
- }
1334
1325
  addNodeIf(Class, val, extra) {
1335
1326
  if (val !== null) {
1336
1327
  const nodeId = this.nodes.length;
@@ -1349,21 +1340,18 @@ class ParseContext {
1349
1340
  newMacroNode(macroName, mAttrs, childs) {
1350
1341
  const anySlot = [];
1351
1342
  const slots = { _: new FragmentNode(anySlot) };
1352
- for (const child of childs) {
1353
- if (child instanceof SlotNode) {
1343
+ for (const child of childs)
1344
+ if (child instanceof SlotNode)
1354
1345
  slots[child.val.val] = child.node;
1355
- } else if (!(child instanceof TextNode) || !child.isWhiteSpace()) {
1346
+ else if (!(child instanceof TextNode) || !child.isWhiteSpace())
1356
1347
  anySlot.push(child);
1357
- }
1358
- }
1359
1348
  const node = new MacroNode(macroName, mAttrs, slots, this);
1360
1349
  this.macroNodes.push(node);
1361
1350
  return node;
1362
1351
  }
1363
1352
  compile(scope) {
1364
- for (let i = 0;i < this.macroNodes.length; i++) {
1353
+ for (let i = 0;i < this.macroNodes.length; i++)
1365
1354
  this.macroNodes[i].compile(scope);
1366
- }
1367
1355
  }
1368
1356
  *genEventNames() {
1369
1357
  for (const event of this.events)
@@ -1377,29 +1365,35 @@ class ParseContext {
1377
1365
  }
1378
1366
  onAttributes(_attrs, _wrapperAttrs, _textChild, _isMacroCall) {}
1379
1367
  }
1380
- var isTextNodeAllBlanks = (n) => n instanceof TextNode && n.isWhiteSpace();
1381
- var isFirstDomNode = (n) => n instanceof DomNode || n instanceof FragmentNode && n.childs[0] instanceof DomNode;
1368
+ var _htmlBlockTags = "ADDRESS,ARTICLE,ASIDE,BLOCKQUOTE,CAPTION,COL,COLGROUP,DETAILS,DIALOG,DIV,DD,DL,DT,FIELDSET,FIGCAPTION,FIGURE,FOOTER,FORM,H1,H2,H3,H4,H5,H6,HEADER,HGROUP,HR,LEGEND,LI,MAIN,MENU,NAV,OL,P,PRE,SECTION,SUMMARY,TABLE,TBODY,TD,TFOOT,TH,THEAD,TR,UL";
1369
+ var HTML_BLOCK_TAGS = new Set(_htmlBlockTags.split(","));
1370
+ var isBlockDomNode = (n) => {
1371
+ const node = n instanceof FragmentNode ? n.childs[0] : n;
1372
+ return node instanceof DomNode && HTML_BLOCK_TAGS.has(node.tagName);
1373
+ };
1382
1374
  function condenseChildsWhites(childs) {
1383
- let end = childs.length;
1384
- if (end === 0)
1375
+ if (childs.length === 0)
1385
1376
  return childs;
1386
- let start = 0;
1387
1377
  let changed = false;
1388
- if (isTextNodeAllBlanks(childs[0])) {
1389
- start = 1;
1378
+ if (childs[0].isWhiteSpace?.()) {
1379
+ childs[0].condenseWhiteSpace();
1390
1380
  changed = true;
1391
1381
  }
1392
- if (end > 1 && isTextNodeAllBlanks(childs[end - 1])) {
1393
- end -= 1;
1382
+ const last = childs.length - 1;
1383
+ if (last > 0 && childs[last].isWhiteSpace?.()) {
1384
+ childs[last].condenseWhiteSpace();
1394
1385
  changed = true;
1395
1386
  }
1396
- for (let i = 1;i < end - 1; i++) {
1387
+ for (let i = 1;i < last; i++) {
1397
1388
  const cur = childs[i];
1398
- if (isTextNodeAllBlanks(cur) && isFirstDomNode(childs[i - 1]) && isFirstDomNode(childs[i + 1]) && cur.hasNewLine()) {
1399
- cur.condenseWhiteSpace();
1389
+ if (cur.isWhiteSpace?.() && cur.hasNewLine()) {
1390
+ const bothBlock = isBlockDomNode(childs[i - 1]) && isBlockDomNode(childs[i + 1]);
1391
+ cur.condenseWhiteSpace(bothBlock ? "" : " ");
1392
+ if (bothBlock)
1393
+ changed = true;
1400
1394
  }
1401
1395
  }
1402
- return changed ? childs.slice(start, end) : childs;
1396
+ return changed ? childs.filter((c) => !(c instanceof TextNode && c.val === "")) : childs;
1403
1397
  }
1404
1398
 
1405
1399
  class View {
@@ -1438,12 +1432,11 @@ class NodeEvents {
1438
1432
  }
1439
1433
  getHandlersFor(eventName) {
1440
1434
  let r = null;
1441
- for (const handler of this.handlers) {
1435
+ for (const handler of this.handlers)
1442
1436
  if (handler.handlesEventName(eventName)) {
1443
1437
  r ??= [];
1444
1438
  r.push(handler);
1445
1439
  }
1446
- }
1447
1440
  return r;
1448
1441
  }
1449
1442
  }
@@ -1497,10 +1490,8 @@ function compileModifiers(eventName, names) {
1497
1490
 
1498
1491
  // src/cache.js
1499
1492
  class NullDomCache {
1500
- get(_k, _cacheKey) {}
1501
- set(_k, _cacheKey, _v) {}
1502
- get2(_k1, _k2, _cacheKey) {}
1503
- set2(_k1, _k2, _cacheKey, _v) {}
1493
+ get(_keys, _cacheKey) {}
1494
+ set(_keys, _cacheKey, _v) {}
1504
1495
  evict() {
1505
1496
  return { hit: 0, miss: 0, badKey: 0 };
1506
1497
  }
@@ -1509,7 +1500,7 @@ class NullDomCache {
1509
1500
  class WeakMapDomCache {
1510
1501
  constructor() {
1511
1502
  this.hit = this.miss = this.badKey = 0;
1512
- this.map = new WeakMap;
1503
+ this.keysByLen = new Map;
1513
1504
  }
1514
1505
  _returnValue(r) {
1515
1506
  if (r === undefined)
@@ -1518,41 +1509,51 @@ class WeakMapDomCache {
1518
1509
  this.hit += 1;
1519
1510
  return r;
1520
1511
  }
1521
- get(k, cacheKey) {
1522
- return this._returnValue(this.map.get(k)?.[cacheKey]);
1523
- }
1524
- set(k, cacheKey, v) {
1525
- const cur = this.map.get(k);
1526
- if (cur)
1527
- cur[cacheKey] = v;
1528
- else if (typeof k === "object")
1529
- this.map.set(k, { [cacheKey]: v });
1512
+ get(keys, cacheKey) {
1513
+ const len = keys.length;
1514
+ let cur = this.keysByLen.get(len);
1515
+ if (!cur)
1516
+ return this._returnValue(undefined);
1517
+ for (let i = 0;i < len - 1; i++) {
1518
+ cur = cur.get(keys[i]);
1519
+ if (!cur)
1520
+ return this._returnValue(undefined);
1521
+ }
1522
+ return this._returnValue(cur.get(keys[len - 1])?.[cacheKey]);
1523
+ }
1524
+ set(keys, cacheKey, v) {
1525
+ const len = keys.length;
1526
+ let cur = this.keysByLen.get(len);
1527
+ if (!cur) {
1528
+ cur = new WeakMap;
1529
+ this.keysByLen.set(len, cur);
1530
+ }
1531
+ for (let i = 0;i < len - 1; i++) {
1532
+ const key = keys[i];
1533
+ let next = cur.get(key);
1534
+ if (!next) {
1535
+ if (typeof key !== "object") {
1536
+ this.badKey += 1;
1537
+ return;
1538
+ }
1539
+ next = new WeakMap;
1540
+ cur.set(key, next);
1541
+ }
1542
+ cur = next;
1543
+ }
1544
+ const lastKey = keys[len - 1];
1545
+ const leaf = cur.get(lastKey);
1546
+ if (leaf)
1547
+ leaf[cacheKey] = v;
1548
+ else if (typeof lastKey === "object")
1549
+ cur.set(lastKey, { [cacheKey]: v });
1530
1550
  else
1531
1551
  this.badKey += 1;
1532
1552
  }
1533
- get2(k1, k2, cacheKey) {
1534
- return this._returnValue(this.map.get(k1)?.get?.(k2)?.[cacheKey]);
1535
- }
1536
- set2(k1, k2, cacheKey, v) {
1537
- const cur1 = this.map.get(k1);
1538
- if (cur1) {
1539
- const cur = cur1.get(k2);
1540
- if (cur)
1541
- cur[cacheKey] = v;
1542
- else
1543
- cur1.set(k2, { [cacheKey]: v });
1544
- } else if (typeof k1 === "object" && typeof k2 === "object") {
1545
- const cur = new WeakMap;
1546
- cur.set(k2, { [cacheKey]: v });
1547
- this.map.set(k1, cur);
1548
- } else {
1549
- this.badKey += 1;
1550
- }
1551
- }
1552
1553
  evict() {
1553
1554
  const { hit, miss, badKey } = this;
1554
1555
  this.hit = this.miss = this.badKey = 0;
1555
- this.map = new WeakMap;
1556
+ this.keysByLen = new Map;
1556
1557
  return { hit, miss, badKey };
1557
1558
  }
1558
1559
  }
@@ -1774,8 +1775,8 @@ class Component {
1774
1775
  `);
1775
1776
  }
1776
1777
  }
1777
- function defaultOnStackEnter(stack) {
1778
- return stack;
1778
+ function defaultOnStackEnter() {
1779
+ return null;
1779
1780
  }
1780
1781
 
1781
1782
  // src/stack.js
@@ -1836,7 +1837,7 @@ class Stack {
1836
1837
  this.ctx = ctx;
1837
1838
  }
1838
1839
  _enrichOnEnter() {
1839
- return this.comps.getOnEnterFor(this.it).call(this.it, this) ?? this;
1840
+ return this.withDynamicBindings(this.comps.getOnEnterFor(this.it).call(this.it));
1840
1841
  }
1841
1842
  upToFrameBinds() {
1842
1843
  const { comps, binds, dynBinds, views, viewsId, ctx } = this;
@@ -1851,7 +1852,8 @@ class Stack {
1851
1852
  enter(it, bindings = {}, isFrame = true) {
1852
1853
  const { comps, binds, dynBinds, views, viewsId, ctx } = this;
1853
1854
  const newBinds = [new BindFrame(it, bindings, isFrame), binds];
1854
- return new Stack(comps, it, newBinds, dynBinds, views, viewsId, ctx)._enrichOnEnter();
1855
+ const stack = new Stack(comps, it, newBinds, dynBinds, views, viewsId, ctx);
1856
+ return isFrame ? stack._enrichOnEnter() : stack;
1855
1857
  }
1856
1858
  pushViewName(name) {
1857
1859
  const { comps, it, binds, dynBinds, views, ctx } = this;
@@ -1859,17 +1861,26 @@ class Stack {
1859
1861
  return new Stack(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
1860
1862
  }
1861
1863
  withDynamicBindings(dynamics) {
1864
+ if (dynamics == null || dynamics.length === 0)
1865
+ return this;
1862
1866
  const dynObj = {};
1863
1867
  const comp = this.comps.getCompFor(this.it);
1864
1868
  for (const dynName of dynamics)
1865
1869
  comp.dynamic[dynName].evalAndBind(this, dynObj);
1866
- const { comps, it, binds, views, viewsId, ctx } = this;
1867
1870
  const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
1871
+ const { comps, it, binds, views, viewsId, ctx } = this;
1868
1872
  return new Stack(comps, it, binds, newDynBinds, views, viewsId, ctx);
1869
1873
  }
1874
+ _pushDynBindValuesToArray(arr, dyns) {
1875
+ for (const k in dyns)
1876
+ arr.push(this._lookupDynamicWithDynVal(dyns[k]));
1877
+ }
1878
+ _lookupDynamicWithDynVal(d) {
1879
+ return lookup(this.dynBinds, d.getSymbol(this)) ?? d.val.eval(this);
1880
+ }
1870
1881
  lookupDynamic(name) {
1871
1882
  const d = this.comps.getCompFor(this.it)?.dynamic[name];
1872
- return d ? lookup(this.dynBinds, d.getSymbol(this)) ?? d.val.eval(this) : null;
1883
+ return d ? this._lookupDynamicWithDynVal(d) : null;
1873
1884
  }
1874
1885
  lookupBind(name) {
1875
1886
  return lookup(this.binds, name);
@@ -2374,10 +2385,13 @@ class VNode extends VBase {
2374
2385
  get nodeType() {
2375
2386
  return 1;
2376
2387
  }
2388
+ isSameKind(other) {
2389
+ return this.tag === other.tag && this.namespace === other.namespace && this.key === other.key;
2390
+ }
2377
2391
  isEqualTo(other) {
2378
2392
  if (this === other)
2379
2393
  return true;
2380
- if (!(other instanceof VNode) || this.tag !== other.tag || this.key !== other.key || this.namespace !== other.namespace || this.childs.length !== other.childs.length) {
2394
+ if (!(other instanceof VNode) || !this.isSameKind(other) || this.childs.length !== other.childs.length) {
2381
2395
  return false;
2382
2396
  }
2383
2397
  if (this.attrs !== other.attrs) {
@@ -2452,23 +2466,20 @@ function morphNode(domNode, source, target, opts) {
2452
2466
  domNode.data = target.text;
2453
2467
  return domNode;
2454
2468
  }
2455
- if (type === 1 && source.tag === target.tag && source.namespace === target.namespace && source.key === target.key) {
2469
+ if (type === 1 && source.isSameKind(target)) {
2456
2470
  const propsDiff = diffProps(source.attrs, target.attrs);
2457
2471
  const isSelect = source.tag === "SELECT";
2458
2472
  if (propsDiff) {
2459
2473
  if (isSelect && "value" in propsDiff) {
2460
2474
  const { value: _v, ...rest } = propsDiff;
2461
2475
  applyProperties(domNode, rest, source.attrs);
2462
- } else {
2476
+ } else
2463
2477
  applyProperties(domNode, propsDiff, source.attrs);
2464
- }
2465
2478
  }
2466
- if (!target.attrs.dangerouslySetInnerHTML) {
2479
+ if (!target.attrs.dangerouslySetInnerHTML)
2467
2480
  morphChildren(domNode, source.childs, target.childs, opts);
2468
- }
2469
- if (isSelect && target.attrs.value !== undefined) {
2481
+ if (isSelect && target.attrs.value !== undefined)
2470
2482
  applyProperties(domNode, { value: target.attrs.value }, source.attrs);
2471
- }
2472
2483
  return domNode;
2473
2484
  }
2474
2485
  if (type === 11) {
@@ -2547,24 +2558,20 @@ function morphChildren(parentDom, oldChilds, newChilds, opts) {
2547
2558
  if (!used[i] && domNodes[i].parentNode === parentDom)
2548
2559
  parentDom.removeChild(domNodes[i]);
2549
2560
  }
2550
- var renderCache = new WeakMap;
2551
- function render(vnode, container, options) {
2552
- const cached = renderCache.get(container);
2561
+ function render(vnode, container, options, prev) {
2553
2562
  const isFragment = vnode instanceof VFragment;
2554
- if (cached && cached.vnode instanceof VFragment === isFragment) {
2555
- const oldDom = isFragment ? container : cached.dom;
2556
- const newDom = morphNode(oldDom, cached.vnode, vnode, options);
2557
- renderCache.set(container, { vnode, dom: isFragment ? container : newDom });
2558
- return newDom;
2563
+ if (prev && prev.vnode instanceof VFragment === isFragment) {
2564
+ const oldDom = isFragment ? container : prev.dom;
2565
+ const newDom = morphNode(oldDom, prev.vnode, vnode, options);
2566
+ return { vnode, dom: isFragment ? container : newDom };
2559
2567
  }
2560
- renderCache.delete(container);
2561
2568
  const domNode = vnode.toDom(options);
2562
2569
  container.replaceChildren(domNode);
2563
- renderCache.set(container, { vnode, dom: isFragment ? container : domNode });
2564
- return domNode;
2570
+ return { vnode, dom: isFragment ? container : domNode };
2565
2571
  }
2566
2572
  function h(tagName, properties, children) {
2567
- const tag = tagName.toUpperCase();
2573
+ const c = tagName.charCodeAt(0);
2574
+ const tag = c >= 97 && c <= 122 ? tagName.toUpperCase() : tagName;
2568
2575
  const props = {};
2569
2576
  let key, namespace;
2570
2577
  if (properties) {
@@ -2615,6 +2622,7 @@ class App {
2615
2622
  };
2616
2623
  this._compiled = false;
2617
2624
  this._renderOpts = { document: rootNode.ownerDocument };
2625
+ this._renderState = null;
2618
2626
  }
2619
2627
  get state() {
2620
2628
  return this.transactor.state;
@@ -2721,7 +2729,10 @@ class App {
2721
2729
  render() {
2722
2730
  const root = this.state.val;
2723
2731
  const stack = this.makeStack(root);
2724
- return render(this.renderer.renderRoot(stack, root), this.rootNode, this._renderOpts);
2732
+ const { renderer, rootNode, _renderOpts, _renderState } = this;
2733
+ const newState = render(renderer.renderRoot(stack, root), rootNode, _renderOpts, _renderState);
2734
+ this._renderState = newState;
2735
+ return newState.dom;
2725
2736
  }
2726
2737
  onChange(callback) {
2727
2738
  this.transactor.state.onChange(callback);
@@ -7700,7 +7711,7 @@ class Renderer {
7700
7711
  renderToDOM(stack, val) {
7701
7712
  const rootNode = document.createElement("div");
7702
7713
  const rOpts = { document };
7703
- render(h("div", null, [this.renderRoot(stack, val)]), rootNode, rOpts);
7714
+ render(h("DIV", null, [this.renderRoot(stack, val)]), rootNode, rOpts);
7704
7715
  return rootNode.childNodes[0];
7705
7716
  }
7706
7717
  renderToString(stack, val, cleanAttrs = true) {
@@ -7724,13 +7735,15 @@ class Renderer {
7724
7735
  }
7725
7736
  _rValComp(stack, val, comp, nid, key, viewName) {
7726
7737
  const cacheKey = `${viewName ?? stack.viewsId ?? ""}${nid}-${key}`;
7727
- const cachedNode = this.cache.get(val, cacheKey);
7738
+ const cachePath = [val];
7739
+ stack._pushDynBindValuesToArray(cachePath, comp.dynamic);
7740
+ const cachedNode = this.cache.get(cachePath, cacheKey);
7728
7741
  if (cachedNode)
7729
7742
  return cachedNode;
7730
7743
  const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
7731
7744
  const meta = this._renderMetadata({ $: "Comp", nid });
7732
7745
  const dom = new VFragment([meta, this.renderView(view, stack)]);
7733
- this.cache.set(val, cacheKey, dom);
7746
+ this.cache.set(cachePath, cacheKey, dom);
7734
7747
  return dom;
7735
7748
  }
7736
7749
  pushEachEntry(r, nid, attrName, key, dom) {
@@ -7742,8 +7755,7 @@ class Renderer {
7742
7755
  const iterData = loopWith.call(stack.it, seq);
7743
7756
  this.getSeqInfo(seq)(seq, (key, value, attrName) => {
7744
7757
  if (filter.call(stack.it, key, value, iterData)) {
7745
- const newStack = stack.enter(value, { key }, true);
7746
- const dom = this.renderIt(newStack, nodeId, key, viewName);
7758
+ const dom = this.renderIt(stack.enter(value, { key }, true), nodeId, key, viewName);
7747
7759
  this.pushEachEntry(r, nodeId, attrName, key, dom);
7748
7760
  }
7749
7761
  });
@@ -7756,25 +7768,19 @@ class Renderer {
7756
7768
  const it = stack.it;
7757
7769
  this.getSeqInfo(seq)(seq, (key, value, attrName) => {
7758
7770
  if (filter.call(it, key, value, iterData)) {
7771
+ const cachePath = enricher ? [it, value] : [value];
7759
7772
  const bindings = { key, value };
7760
7773
  const cacheKey = `${nid}-${key}`;
7761
- let cachedNode;
7762
- if (enricher) {
7774
+ if (enricher)
7763
7775
  enricher.call(it, bindings, key, value, iterData);
7764
- cachedNode = this.cache.get2(it, value, cacheKey);
7765
- } else
7766
- cachedNode = this.cache.get(value, cacheKey);
7767
- if (cachedNode) {
7776
+ const cachedNode = this.cache.get(cachePath, cacheKey);
7777
+ if (cachedNode)
7768
7778
  this.pushEachEntry(r, nid, attrName, key, cachedNode);
7769
- return;
7779
+ else {
7780
+ const dom = this.renderView(view, stack.enter(value, bindings, false));
7781
+ this.pushEachEntry(r, nid, attrName, key, dom);
7782
+ this.cache.set(cachePath, cacheKey, dom);
7770
7783
  }
7771
- const newStack = stack.enter(value, bindings, false);
7772
- const dom = this.renderView(view, newStack);
7773
- this.pushEachEntry(r, nid, attrName, key, dom);
7774
- if (enricher)
7775
- this.cache.set2(it, value, cacheKey, dom);
7776
- else
7777
- this.cache.set(value, cacheKey, dom);
7778
7784
  }
7779
7785
  });
7780
7786
  return r;