bobe 0.0.58 → 0.0.60

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.
@@ -252,7 +252,6 @@ class Tokenizer {
252
252
  }
253
253
  isEof() {
254
254
  if (!this.token) return false;
255
- if (this.i >= this.code.length && !this.waitingTokens.len) return true;
256
255
  return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
257
256
  }
258
257
  setToken(type, value, dt = 1) {
@@ -281,6 +280,7 @@ class Tokenizer {
281
280
  if (this.isEof()) {
282
281
  return this.token;
283
282
  }
283
+ if (this.i >= this.code.length && !this.waitingTokens.len) return this.token;
284
284
  this.token = undefined;
285
285
  if (this.waitingTokens.len) {
286
286
  const item = this.waitingTokens.shift();
@@ -1456,6 +1456,14 @@ class InlineFragment {
1456
1456
  }
1457
1457
  const isUI = fn => typeof fn === 'function' && fn.__BOBE_IS_UI;
1458
1458
  const isRenderAble = val => isStore(val) || isUI(val) || val instanceof InlineFragment;
1459
+ const SAFE_HANDLER = {
1460
+ has: () => true,
1461
+ get: (t, k) => {
1462
+ if (typeof k === 'symbol') return t[k];
1463
+ return k in t ? t[k] : undefined;
1464
+ }
1465
+ };
1466
+ const safe = data => new Proxy(data, SAFE_HANDLER);
1459
1467
 
1460
1468
  const KEY_INDEX = '__BOBE_KEY_INDEX';
1461
1469
  let _ctxStack;
@@ -1503,6 +1511,9 @@ class Interpreter {
1503
1511
  if (this.tokenizer.isEof()) {
1504
1512
  if (!ctx.prevSibling) ctx.prevSibling = before;
1505
1513
  this.handleInsert(root, ctx.current, ctx.prevSibling, componentNode);
1514
+ if (ctx.current) {
1515
+ ctx.current.__logicType ? this.leaveLogicNode?.(ctx.current, false) : this.leaveNode?.(ctx.current, false);
1516
+ }
1506
1517
  break;
1507
1518
  }
1508
1519
  const token = this.tokenizer.token;
@@ -1514,6 +1525,7 @@ class Interpreter {
1514
1525
  prev: ctx.prevSibling
1515
1526
  }, !ctx.current.__logicType ? NodeSort.Real : (ctx.current.__logicType & LogicalBit ? NodeSort.Logic : 0) | (ctx.current.__logicType & TokenizerSwitcherBit ? NodeSort.TokenizerSwitcher : 0) | (ctx.current.__logicType & ContextBit ? NodeSort.Context : 0) | (ctx.current.__logicType === FakeType.Component ? NodeSort.Component : 0) | (ctx.current.__logicType & CtxProviderBit ? NodeSort.CtxProvider : 0));
1516
1527
  if (ctx.current.__logicType) {
1528
+ this.beforeLogicIndent?.(ctx.current);
1517
1529
  if (isLogicNode) {
1518
1530
  setPulling(ctx.current.effect);
1519
1531
  if (ctx.current.__logicType & FakeType.ForItem) {
@@ -1522,6 +1534,12 @@ class Interpreter {
1522
1534
  }
1523
1535
  } else {
1524
1536
  if (ctx.current) {
1537
+ if (this.beforeIndent?.(ctx.current) === false) {
1538
+ const dentLen = this.tokenizer.dentStack[this.tokenizer.dentStack.length - 1];
1539
+ this.tokenizer.skip(dentLen);
1540
+ ctx.current = null;
1541
+ continue;
1542
+ }
1525
1543
  ctx.realParent = ctx.current;
1526
1544
  }
1527
1545
  ctx.prevSibling = null;
@@ -1534,6 +1552,7 @@ class Interpreter {
1534
1552
  ctx.prevSibling = before;
1535
1553
  }
1536
1554
  this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
1555
+ ctx.current.__logicType ? this.leaveLogicNode?.(ctx.current, false) : this.leaveNode?.(ctx.current, false);
1537
1556
  }
1538
1557
  if (this.tokenizer.token.type & TokenType.Dedent) {
1539
1558
  this.tokenizer.nextToken();
@@ -1568,6 +1587,7 @@ class Interpreter {
1568
1587
  const i = forNode.i,
1569
1588
  arr = forNode.arr,
1570
1589
  snapshot = forNode.snapshot;
1590
+ this.leaveLogicNode?.(parent, false);
1571
1591
  if (i + 1 < arr.length) {
1572
1592
  this.tokenizer.resume(snapshot);
1573
1593
  this.tokenizer.nextToken();
@@ -1590,13 +1610,13 @@ class Interpreter {
1590
1610
  }
1591
1611
  return componentNode;
1592
1612
  }
1593
- insertAfterAnchor(name = 'anchor') {
1613
+ insertAnchor(name = 'anchor', isBefore = false) {
1594
1614
  const _this$ctx = this.ctx,
1595
1615
  realParent = _this$ctx.realParent,
1596
1616
  prevSibling = _this$ctx.prevSibling,
1597
1617
  stack = _this$ctx.stack,
1598
1618
  before = _this$ctx.before;
1599
- const afterAnchor = this.createAnchor(name);
1619
+ const afterAnchor = this.createAnchor(name, isBefore);
1600
1620
  this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
1601
1621
  this.handleInsert(realParent, afterAnchor, prevSibling);
1602
1622
  return afterAnchor;
@@ -1650,7 +1670,7 @@ class Interpreter {
1650
1670
  _node = this.componentOrFragmentDeclaration(value, ctx);
1651
1671
  } else {
1652
1672
  _node = this.createNode('text');
1653
- _node.text = String(value);
1673
+ this.setProp(_node, 'text', String(value));
1654
1674
  }
1655
1675
  } else {
1656
1676
  return this.dynamicDeclaration(data, value, ctx);
@@ -1680,11 +1700,11 @@ class Interpreter {
1680
1700
  effect: null,
1681
1701
  textNode: null,
1682
1702
  owner: ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node,
1683
- snapshot: this.tokenizer.snapshot(['dentStack']),
1703
+ snapshot: this.tokenizer.snapshot(['dentStack', 'isFirstToken']),
1684
1704
  parentDataProvider: ctx.stack.peekByType(NodeSort.CtxProvider)?.node
1685
1705
  };
1686
1706
  let isUpdate = false;
1687
- node.realAfter = this.insertAfterAnchor(`dynamic-after`);
1707
+ node.realAfter = this.insertAnchor(`dynamic-after`);
1688
1708
  node.effect = this.effect(({
1689
1709
  old,
1690
1710
  val
@@ -1693,7 +1713,7 @@ class Interpreter {
1693
1713
  oldTextNode = node.textNode;
1694
1714
  if (oldLogicType) {
1695
1715
  this.removeLogicNode(node);
1696
- pickInPlace(node, ['realParent', 'realBefore', 'realAfter',, 'owner', 'snapshot', 'parentDataProvider']);
1716
+ pickInPlace(node, ['realParent', 'realBefore', 'realAfter', 'owner', 'snapshot', 'parentDataProvider']);
1697
1717
  }
1698
1718
  if (isRenderAble(val)) {
1699
1719
  if (oldTextNode) {
@@ -1720,11 +1740,13 @@ class Interpreter {
1720
1740
  this.tokenizer = node.tokenizer;
1721
1741
  if (node.fragmentSnapshot) {
1722
1742
  this.tokenizer.resume(node.fragmentSnapshot);
1723
- this.tokenizer.useDedentAsEof = true;
1724
- this.tokenizer.initIndentWhenUseDedentAsEof();
1725
1743
  }
1726
1744
  if (isUpdate) {
1727
- this.program(node.realParent, node.owner, node.realBefore, node);
1745
+ this.tokenizer.useDedentAsEof = false;
1746
+ this.program(node.realParent, node, node.realBefore);
1747
+ } else {
1748
+ this.tokenizer.useDedentAsEof = true;
1749
+ this.tokenizer.initIndentWhenUseDedentAsEof();
1728
1750
  }
1729
1751
  } else {
1730
1752
  node.__logicType = FakeType.DynamicText;
@@ -1733,7 +1755,7 @@ class Interpreter {
1733
1755
  if (isNewTextNode) {
1734
1756
  textNode = node.textNode = this.createNode('text');
1735
1757
  }
1736
- textNode.text = String(val);
1758
+ this.setProp(textNode, 'text', String(val));
1737
1759
  if (isNewTextNode) {
1738
1760
  if (isUpdate) {
1739
1761
  this.handleInsert(node.realParent, textNode, node.realBefore);
@@ -1745,6 +1767,7 @@ class Interpreter {
1745
1767
  prevSibling = _this$ctx2.prevSibling;
1746
1768
  this.handleInsert(realParent, textNode, prevSibling);
1747
1769
  }
1770
+ this.leaveNode?.(textNode, false);
1748
1771
  }
1749
1772
  }
1750
1773
  isUpdate = true;
@@ -1775,7 +1798,7 @@ class Interpreter {
1775
1798
  realBefore: null,
1776
1799
  realAfter: null
1777
1800
  };
1778
- node.realAfter = this.insertAfterAnchor('context-after');
1801
+ node.realAfter = this.insertAnchor('context-after');
1779
1802
  return node;
1780
1803
  }
1781
1804
  formatForCollection(collection) {
@@ -1865,7 +1888,8 @@ class Interpreter {
1865
1888
  i: 0
1866
1889
  };
1867
1890
  if (keyExp) {
1868
- forNode.getKey = new Function('data', `let v;with(data){v=${keyExp}\n};return v;`);
1891
+ const rawGetKey = new Function('data', `with(data){return (${keyExp})}`);
1892
+ forNode.getKey = data => rawGetKey(safe(data));
1869
1893
  }
1870
1894
  window['for1'] = forNode;
1871
1895
  const data = this.getData();
@@ -1873,7 +1897,7 @@ class Interpreter {
1873
1897
  const hasArrExpKey = Reflect.has(data[Keys.Raw], arrExp);
1874
1898
  const arrSignal = hasArrExpKey ? (data[arrExp], cells.get(arrExp)) : new Computed(this.getFn(data, arrExp));
1875
1899
  forNode.arrSignal = arrSignal;
1876
- forNode.realAfter = this.insertAfterAnchor('for-after');
1900
+ forNode.realAfter = this.insertAnchor('for-after');
1877
1901
  const _forNode$snapshot = forNode.snapshot;
1878
1902
  _forNode$snapshot.dentStack;
1879
1903
  _forNode$snapshot.isFirstToken;
@@ -1896,8 +1920,8 @@ class Interpreter {
1896
1920
  const len = arr.length;
1897
1921
  for (let i = len; i--;) {
1898
1922
  const item = this.createForItem(forNode, i, data);
1899
- item.realAfter = this.insertAfterAnchor('for-item-after');
1900
- item.realBefore = this.insertAfterAnchor('for-item-before');
1923
+ item.realAfter = this.insertAnchor('for-item-after');
1924
+ item.realBefore = this.insertAnchor('for-item-before', true);
1901
1925
  item.realParent = forNode.realParent;
1902
1926
  children[i] = item;
1903
1927
  }
@@ -2064,7 +2088,7 @@ class Interpreter {
2064
2088
  newChildren[i] = item;
2065
2089
  let realAfter = this.createAnchor('for-item-after');
2066
2090
  this.handleInsert(forNode.realParent, realAfter, before);
2067
- let realBefore = this.createAnchor('for-item-before');
2091
+ let realBefore = this.createAnchor('for-item-before', true);
2068
2092
  this.handleInsert(forNode.realParent, realBefore, before);
2069
2093
  item.realBefore = realBefore;
2070
2094
  item.realAfter = realAfter;
@@ -2233,11 +2257,11 @@ class Interpreter {
2233
2257
  resumeSnapshot
2234
2258
  };
2235
2259
  this.onePropParsed = onePropParsed;
2236
- node.realAfter = this.insertAfterAnchor('component-after');
2260
+ node.realAfter = this.insertAnchor('component-after');
2237
2261
  return node;
2238
2262
  }
2239
2263
  getFn(data, expression) {
2240
- return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
2264
+ return new Function('data', `with(data){return (${expression})}`).bind(undefined, safe(data));
2241
2265
  }
2242
2266
  getAssignFn(data, expression) {
2243
2267
  const valueId = `value_bobe_${date32()}`;
@@ -2328,7 +2352,7 @@ class Interpreter {
2328
2352
  break;
2329
2353
  }
2330
2354
  ifNode.condition = signal;
2331
- ifNode.realAfter = this.insertAfterAnchor(`${keyWord.value}-after`);
2355
+ ifNode.realAfter = this.insertAnchor(`${keyWord.value}-after`);
2332
2356
  const ef = this.effect(({
2333
2357
  val
2334
2358
  }) => {
@@ -2513,10 +2537,11 @@ class Interpreter {
2513
2537
  firstChild(node) {
2514
2538
  return node.firstChild;
2515
2539
  }
2516
- createAnchor(name) {
2540
+ createAnchor(name, isBefore) {
2517
2541
  return {
2518
2542
  name,
2519
- nextSibling: null
2543
+ nextSibling: null,
2544
+ isBefore
2520
2545
  };
2521
2546
  }
2522
2547
  insertAfter(parent, node, prev) {
@@ -2586,6 +2611,7 @@ function bobe(fragments, ...values) {
2586
2611
  return tokenizer;
2587
2612
  };
2588
2613
  ui.boundStore = Store.Current;
2614
+ ui[Keys.ProxyFreeObject] = true;
2589
2615
  ui.__BOBE_IS_UI = true;
2590
2616
  return ui;
2591
2617
  }
@@ -2602,6 +2628,7 @@ function customRender(option) {
2602
2628
  tokenizer
2603
2629
  };
2604
2630
  terp.program(root, componentNode);
2631
+ option.onBeforeFlush?.();
2605
2632
  flushMicroEffectManual();
2606
2633
  return [componentNode, store];
2607
2634
  };