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
  }
@@ -1942,10 +1935,8 @@ function lintIdToMessage(id, info) {
1942
1935
 
1943
1936
  // src/cache.js
1944
1937
  class NullDomCache {
1945
- get(_k, _cacheKey) {}
1946
- set(_k, _cacheKey, _v) {}
1947
- get2(_k1, _k2, _cacheKey) {}
1948
- set2(_k1, _k2, _cacheKey, _v) {}
1938
+ get(_keys, _cacheKey) {}
1939
+ set(_keys, _cacheKey, _v) {}
1949
1940
  evict() {
1950
1941
  return { hit: 0, miss: 0, badKey: 0 };
1951
1942
  }
@@ -1954,7 +1945,7 @@ class NullDomCache {
1954
1945
  class WeakMapDomCache {
1955
1946
  constructor() {
1956
1947
  this.hit = this.miss = this.badKey = 0;
1957
- this.map = new WeakMap;
1948
+ this.keysByLen = new Map;
1958
1949
  }
1959
1950
  _returnValue(r) {
1960
1951
  if (r === undefined)
@@ -1963,41 +1954,51 @@ class WeakMapDomCache {
1963
1954
  this.hit += 1;
1964
1955
  return r;
1965
1956
  }
1966
- get(k, cacheKey) {
1967
- return this._returnValue(this.map.get(k)?.[cacheKey]);
1968
- }
1969
- set(k, cacheKey, v) {
1970
- const cur = this.map.get(k);
1971
- if (cur)
1972
- cur[cacheKey] = v;
1973
- else if (typeof k === "object")
1974
- this.map.set(k, { [cacheKey]: v });
1957
+ get(keys, cacheKey) {
1958
+ const len = keys.length;
1959
+ let cur = this.keysByLen.get(len);
1960
+ if (!cur)
1961
+ return this._returnValue(undefined);
1962
+ for (let i = 0;i < len - 1; i++) {
1963
+ cur = cur.get(keys[i]);
1964
+ if (!cur)
1965
+ return this._returnValue(undefined);
1966
+ }
1967
+ return this._returnValue(cur.get(keys[len - 1])?.[cacheKey]);
1968
+ }
1969
+ set(keys, cacheKey, v) {
1970
+ const len = keys.length;
1971
+ let cur = this.keysByLen.get(len);
1972
+ if (!cur) {
1973
+ cur = new WeakMap;
1974
+ this.keysByLen.set(len, cur);
1975
+ }
1976
+ for (let i = 0;i < len - 1; i++) {
1977
+ const key = keys[i];
1978
+ let next = cur.get(key);
1979
+ if (!next) {
1980
+ if (typeof key !== "object") {
1981
+ this.badKey += 1;
1982
+ return;
1983
+ }
1984
+ next = new WeakMap;
1985
+ cur.set(key, next);
1986
+ }
1987
+ cur = next;
1988
+ }
1989
+ const lastKey = keys[len - 1];
1990
+ const leaf = cur.get(lastKey);
1991
+ if (leaf)
1992
+ leaf[cacheKey] = v;
1993
+ else if (typeof lastKey === "object")
1994
+ cur.set(lastKey, { [cacheKey]: v });
1975
1995
  else
1976
1996
  this.badKey += 1;
1977
1997
  }
1978
- get2(k1, k2, cacheKey) {
1979
- return this._returnValue(this.map.get(k1)?.get?.(k2)?.[cacheKey]);
1980
- }
1981
- set2(k1, k2, cacheKey, v) {
1982
- const cur1 = this.map.get(k1);
1983
- if (cur1) {
1984
- const cur = cur1.get(k2);
1985
- if (cur)
1986
- cur[cacheKey] = v;
1987
- else
1988
- cur1.set(k2, { [cacheKey]: v });
1989
- } else if (typeof k1 === "object" && typeof k2 === "object") {
1990
- const cur = new WeakMap;
1991
- cur.set(k2, { [cacheKey]: v });
1992
- this.map.set(k1, cur);
1993
- } else {
1994
- this.badKey += 1;
1995
- }
1996
- }
1997
1998
  evict() {
1998
1999
  const { hit, miss, badKey } = this;
1999
2000
  this.hit = this.miss = this.badKey = 0;
2000
- this.map = new WeakMap;
2001
+ this.keysByLen = new Map;
2001
2002
  return { hit, miss, badKey };
2002
2003
  }
2003
2004
  }
@@ -2219,8 +2220,8 @@ class Component {
2219
2220
  `);
2220
2221
  }
2221
2222
  }
2222
- function defaultOnStackEnter(stack) {
2223
- return stack;
2223
+ function defaultOnStackEnter() {
2224
+ return null;
2224
2225
  }
2225
2226
 
2226
2227
  // src/stack.js
@@ -2281,7 +2282,7 @@ class Stack {
2281
2282
  this.ctx = ctx;
2282
2283
  }
2283
2284
  _enrichOnEnter() {
2284
- return this.comps.getOnEnterFor(this.it).call(this.it, this) ?? this;
2285
+ return this.withDynamicBindings(this.comps.getOnEnterFor(this.it).call(this.it));
2285
2286
  }
2286
2287
  upToFrameBinds() {
2287
2288
  const { comps, binds, dynBinds, views, viewsId, ctx } = this;
@@ -2296,7 +2297,8 @@ class Stack {
2296
2297
  enter(it, bindings = {}, isFrame = true) {
2297
2298
  const { comps, binds, dynBinds, views, viewsId, ctx } = this;
2298
2299
  const newBinds = [new BindFrame(it, bindings, isFrame), binds];
2299
- return new Stack(comps, it, newBinds, dynBinds, views, viewsId, ctx)._enrichOnEnter();
2300
+ const stack = new Stack(comps, it, newBinds, dynBinds, views, viewsId, ctx);
2301
+ return isFrame ? stack._enrichOnEnter() : stack;
2300
2302
  }
2301
2303
  pushViewName(name) {
2302
2304
  const { comps, it, binds, dynBinds, views, ctx } = this;
@@ -2304,17 +2306,26 @@ class Stack {
2304
2306
  return new Stack(comps, it, binds, dynBinds, newViews, computeViewsId(newViews), ctx);
2305
2307
  }
2306
2308
  withDynamicBindings(dynamics) {
2309
+ if (dynamics == null || dynamics.length === 0)
2310
+ return this;
2307
2311
  const dynObj = {};
2308
2312
  const comp = this.comps.getCompFor(this.it);
2309
2313
  for (const dynName of dynamics)
2310
2314
  comp.dynamic[dynName].evalAndBind(this, dynObj);
2311
- const { comps, it, binds, views, viewsId, ctx } = this;
2312
2315
  const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
2316
+ const { comps, it, binds, views, viewsId, ctx } = this;
2313
2317
  return new Stack(comps, it, binds, newDynBinds, views, viewsId, ctx);
2314
2318
  }
2319
+ _pushDynBindValuesToArray(arr, dyns) {
2320
+ for (const k in dyns)
2321
+ arr.push(this._lookupDynamicWithDynVal(dyns[k]));
2322
+ }
2323
+ _lookupDynamicWithDynVal(d) {
2324
+ return lookup(this.dynBinds, d.getSymbol(this)) ?? d.val.eval(this);
2325
+ }
2315
2326
  lookupDynamic(name) {
2316
2327
  const d = this.comps.getCompFor(this.it)?.dynamic[name];
2317
- return d ? lookup(this.dynBinds, d.getSymbol(this)) ?? d.val.eval(this) : null;
2328
+ return d ? this._lookupDynamicWithDynVal(d) : null;
2318
2329
  }
2319
2330
  lookupBind(name) {
2320
2331
  return lookup(this.binds, name);
@@ -2819,10 +2830,13 @@ class VNode extends VBase {
2819
2830
  get nodeType() {
2820
2831
  return 1;
2821
2832
  }
2833
+ isSameKind(other) {
2834
+ return this.tag === other.tag && this.namespace === other.namespace && this.key === other.key;
2835
+ }
2822
2836
  isEqualTo(other) {
2823
2837
  if (this === other)
2824
2838
  return true;
2825
- if (!(other instanceof VNode) || this.tag !== other.tag || this.key !== other.key || this.namespace !== other.namespace || this.childs.length !== other.childs.length) {
2839
+ if (!(other instanceof VNode) || !this.isSameKind(other) || this.childs.length !== other.childs.length) {
2826
2840
  return false;
2827
2841
  }
2828
2842
  if (this.attrs !== other.attrs) {
@@ -2897,23 +2911,20 @@ function morphNode(domNode, source, target, opts) {
2897
2911
  domNode.data = target.text;
2898
2912
  return domNode;
2899
2913
  }
2900
- if (type === 1 && source.tag === target.tag && source.namespace === target.namespace && source.key === target.key) {
2914
+ if (type === 1 && source.isSameKind(target)) {
2901
2915
  const propsDiff = diffProps(source.attrs, target.attrs);
2902
2916
  const isSelect = source.tag === "SELECT";
2903
2917
  if (propsDiff) {
2904
2918
  if (isSelect && "value" in propsDiff) {
2905
2919
  const { value: _v, ...rest } = propsDiff;
2906
2920
  applyProperties(domNode, rest, source.attrs);
2907
- } else {
2921
+ } else
2908
2922
  applyProperties(domNode, propsDiff, source.attrs);
2909
- }
2910
2923
  }
2911
- if (!target.attrs.dangerouslySetInnerHTML) {
2924
+ if (!target.attrs.dangerouslySetInnerHTML)
2912
2925
  morphChildren(domNode, source.childs, target.childs, opts);
2913
- }
2914
- if (isSelect && target.attrs.value !== undefined) {
2926
+ if (isSelect && target.attrs.value !== undefined)
2915
2927
  applyProperties(domNode, { value: target.attrs.value }, source.attrs);
2916
- }
2917
2928
  return domNode;
2918
2929
  }
2919
2930
  if (type === 11) {
@@ -2992,24 +3003,20 @@ function morphChildren(parentDom, oldChilds, newChilds, opts) {
2992
3003
  if (!used[i] && domNodes[i].parentNode === parentDom)
2993
3004
  parentDom.removeChild(domNodes[i]);
2994
3005
  }
2995
- var renderCache = new WeakMap;
2996
- function render(vnode, container, options) {
2997
- const cached = renderCache.get(container);
3006
+ function render(vnode, container, options, prev) {
2998
3007
  const isFragment = vnode instanceof VFragment;
2999
- if (cached && cached.vnode instanceof VFragment === isFragment) {
3000
- const oldDom = isFragment ? container : cached.dom;
3001
- const newDom = morphNode(oldDom, cached.vnode, vnode, options);
3002
- renderCache.set(container, { vnode, dom: isFragment ? container : newDom });
3003
- return newDom;
3008
+ if (prev && prev.vnode instanceof VFragment === isFragment) {
3009
+ const oldDom = isFragment ? container : prev.dom;
3010
+ const newDom = morphNode(oldDom, prev.vnode, vnode, options);
3011
+ return { vnode, dom: isFragment ? container : newDom };
3004
3012
  }
3005
- renderCache.delete(container);
3006
3013
  const domNode = vnode.toDom(options);
3007
3014
  container.replaceChildren(domNode);
3008
- renderCache.set(container, { vnode, dom: isFragment ? container : domNode });
3009
- return domNode;
3015
+ return { vnode, dom: isFragment ? container : domNode };
3010
3016
  }
3011
3017
  function h(tagName, properties, children) {
3012
- const tag = tagName.toUpperCase();
3018
+ const c = tagName.charCodeAt(0);
3019
+ const tag = c >= 97 && c <= 122 ? tagName.toUpperCase() : tagName;
3013
3020
  const props = {};
3014
3021
  let key, namespace;
3015
3022
  if (properties) {
@@ -3060,6 +3067,7 @@ class App {
3060
3067
  };
3061
3068
  this._compiled = false;
3062
3069
  this._renderOpts = { document: rootNode.ownerDocument };
3070
+ this._renderState = null;
3063
3071
  }
3064
3072
  get state() {
3065
3073
  return this.transactor.state;
@@ -3166,7 +3174,10 @@ class App {
3166
3174
  render() {
3167
3175
  const root = this.state.val;
3168
3176
  const stack = this.makeStack(root);
3169
- return render(this.renderer.renderRoot(stack, root), this.rootNode, this._renderOpts);
3177
+ const { renderer, rootNode, _renderOpts, _renderState } = this;
3178
+ const newState = render(renderer.renderRoot(stack, root), rootNode, _renderOpts, _renderState);
3179
+ this._renderState = newState;
3180
+ return newState.dom;
3170
3181
  }
3171
3182
  onChange(callback) {
3172
3183
  this.transactor.state.onChange(callback);
@@ -8088,7 +8099,7 @@ class Renderer {
8088
8099
  renderToDOM(stack, val) {
8089
8100
  const rootNode = document.createElement("div");
8090
8101
  const rOpts = { document };
8091
- render(h("div", null, [this.renderRoot(stack, val)]), rootNode, rOpts);
8102
+ render(h("DIV", null, [this.renderRoot(stack, val)]), rootNode, rOpts);
8092
8103
  return rootNode.childNodes[0];
8093
8104
  }
8094
8105
  renderToString(stack, val, cleanAttrs = true) {
@@ -8112,13 +8123,15 @@ class Renderer {
8112
8123
  }
8113
8124
  _rValComp(stack, val, comp, nid, key, viewName) {
8114
8125
  const cacheKey = `${viewName ?? stack.viewsId ?? ""}${nid}-${key}`;
8115
- const cachedNode = this.cache.get(val, cacheKey);
8126
+ const cachePath = [val];
8127
+ stack._pushDynBindValuesToArray(cachePath, comp.dynamic);
8128
+ const cachedNode = this.cache.get(cachePath, cacheKey);
8116
8129
  if (cachedNode)
8117
8130
  return cachedNode;
8118
8131
  const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
8119
8132
  const meta = this._renderMetadata({ $: "Comp", nid });
8120
8133
  const dom = new VFragment([meta, this.renderView(view, stack)]);
8121
- this.cache.set(val, cacheKey, dom);
8134
+ this.cache.set(cachePath, cacheKey, dom);
8122
8135
  return dom;
8123
8136
  }
8124
8137
  pushEachEntry(r, nid, attrName, key, dom) {
@@ -8130,8 +8143,7 @@ class Renderer {
8130
8143
  const iterData = loopWith.call(stack.it, seq);
8131
8144
  this.getSeqInfo(seq)(seq, (key, value, attrName) => {
8132
8145
  if (filter.call(stack.it, key, value, iterData)) {
8133
- const newStack = stack.enter(value, { key }, true);
8134
- const dom = this.renderIt(newStack, nodeId, key, viewName);
8146
+ const dom = this.renderIt(stack.enter(value, { key }, true), nodeId, key, viewName);
8135
8147
  this.pushEachEntry(r, nodeId, attrName, key, dom);
8136
8148
  }
8137
8149
  });
@@ -8144,25 +8156,19 @@ class Renderer {
8144
8156
  const it = stack.it;
8145
8157
  this.getSeqInfo(seq)(seq, (key, value, attrName) => {
8146
8158
  if (filter.call(it, key, value, iterData)) {
8159
+ const cachePath = enricher ? [it, value] : [value];
8147
8160
  const bindings = { key, value };
8148
8161
  const cacheKey = `${nid}-${key}`;
8149
- let cachedNode;
8150
- if (enricher) {
8162
+ if (enricher)
8151
8163
  enricher.call(it, bindings, key, value, iterData);
8152
- cachedNode = this.cache.get2(it, value, cacheKey);
8153
- } else
8154
- cachedNode = this.cache.get(value, cacheKey);
8155
- if (cachedNode) {
8164
+ const cachedNode = this.cache.get(cachePath, cacheKey);
8165
+ if (cachedNode)
8156
8166
  this.pushEachEntry(r, nid, attrName, key, cachedNode);
8157
- return;
8167
+ else {
8168
+ const dom = this.renderView(view, stack.enter(value, bindings, false));
8169
+ this.pushEachEntry(r, nid, attrName, key, dom);
8170
+ this.cache.set(cachePath, cacheKey, dom);
8158
8171
  }
8159
- const newStack = stack.enter(value, bindings, false);
8160
- const dom = this.renderView(view, newStack);
8161
- this.pushEachEntry(r, nid, attrName, key, dom);
8162
- if (enricher)
8163
- this.cache.set2(it, value, cacheKey, dom);
8164
- else
8165
- this.cache.set(value, cacheKey, dom);
8166
8172
  }
8167
8173
  });
8168
8174
  return r;