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.
package/dist/bobe.esm.js CHANGED
@@ -243,7 +243,6 @@ class Tokenizer {
243
243
  }
244
244
  isEof() {
245
245
  if (!this.token) return false;
246
- if (this.i >= this.code.length && !this.waitingTokens.len) return true;
247
246
  return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
248
247
  }
249
248
  setToken(type, value, dt = 1) {
@@ -260,6 +259,7 @@ class Tokenizer {
260
259
  if (this.isEof()) {
261
260
  return this.token;
262
261
  }
262
+ if (this.i >= this.code.length && !this.waitingTokens.len) return this.token;
263
263
  this.token = undefined;
264
264
  if (this.waitingTokens.len) {
265
265
  const item = this.waitingTokens.shift();
@@ -1429,6 +1429,14 @@ class InlineFragment {
1429
1429
  }
1430
1430
  const isUI = fn => typeof fn === 'function' && fn.__BOBE_IS_UI;
1431
1431
  const isRenderAble = val => isStore(val) || isUI(val) || val instanceof InlineFragment;
1432
+ const SAFE_HANDLER = {
1433
+ has: () => true,
1434
+ get: (t, k) => {
1435
+ if (typeof k === 'symbol') return t[k];
1436
+ return k in t ? t[k] : undefined;
1437
+ }
1438
+ };
1439
+ const safe = data => new Proxy(data, SAFE_HANDLER);
1432
1440
 
1433
1441
  const KEY_INDEX = '__BOBE_KEY_INDEX';
1434
1442
  let _ctxStack;
@@ -1476,6 +1484,9 @@ class Interpreter {
1476
1484
  if (this.tokenizer.isEof()) {
1477
1485
  if (!ctx.prevSibling) ctx.prevSibling = before;
1478
1486
  this.handleInsert(root, ctx.current, ctx.prevSibling, componentNode);
1487
+ if (ctx.current) {
1488
+ ctx.current.__logicType ? this.leaveLogicNode?.(ctx.current, false) : this.leaveNode?.(ctx.current, false);
1489
+ }
1479
1490
  break;
1480
1491
  }
1481
1492
  const token = this.tokenizer.token;
@@ -1487,6 +1498,7 @@ class Interpreter {
1487
1498
  prev: ctx.prevSibling
1488
1499
  }, !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));
1489
1500
  if (ctx.current.__logicType) {
1501
+ this.beforeLogicIndent?.(ctx.current);
1490
1502
  if (isLogicNode) {
1491
1503
  setPulling(ctx.current.effect);
1492
1504
  if (ctx.current.__logicType & FakeType.ForItem) {
@@ -1495,6 +1507,12 @@ class Interpreter {
1495
1507
  }
1496
1508
  } else {
1497
1509
  if (ctx.current) {
1510
+ if (this.beforeIndent?.(ctx.current) === false) {
1511
+ const dentLen = this.tokenizer.dentStack[this.tokenizer.dentStack.length - 1];
1512
+ this.tokenizer.skip(dentLen);
1513
+ ctx.current = null;
1514
+ continue;
1515
+ }
1498
1516
  ctx.realParent = ctx.current;
1499
1517
  }
1500
1518
  ctx.prevSibling = null;
@@ -1507,6 +1525,7 @@ class Interpreter {
1507
1525
  ctx.prevSibling = before;
1508
1526
  }
1509
1527
  this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
1528
+ ctx.current.__logicType ? this.leaveLogicNode?.(ctx.current, false) : this.leaveNode?.(ctx.current, false);
1510
1529
  }
1511
1530
  if (this.tokenizer.token.type & TokenType.Dedent) {
1512
1531
  this.tokenizer.nextToken();
@@ -1541,6 +1560,7 @@ class Interpreter {
1541
1560
  const i = forNode.i,
1542
1561
  arr = forNode.arr,
1543
1562
  snapshot = forNode.snapshot;
1563
+ this.leaveLogicNode?.(parent, false);
1544
1564
  if (i + 1 < arr.length) {
1545
1565
  this.tokenizer.resume(snapshot);
1546
1566
  this.tokenizer.nextToken();
@@ -1563,13 +1583,13 @@ class Interpreter {
1563
1583
  }
1564
1584
  return componentNode;
1565
1585
  }
1566
- insertAfterAnchor(name = 'anchor') {
1586
+ insertAnchor(name = 'anchor', isBefore = false) {
1567
1587
  const _this$ctx = this.ctx,
1568
1588
  realParent = _this$ctx.realParent,
1569
1589
  prevSibling = _this$ctx.prevSibling,
1570
1590
  stack = _this$ctx.stack,
1571
1591
  before = _this$ctx.before;
1572
- const afterAnchor = this.createAnchor(name);
1592
+ const afterAnchor = this.createAnchor(name, isBefore);
1573
1593
  this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
1574
1594
  this.handleInsert(realParent, afterAnchor, prevSibling);
1575
1595
  return afterAnchor;
@@ -1623,7 +1643,7 @@ class Interpreter {
1623
1643
  _node = this.componentOrFragmentDeclaration(value, ctx);
1624
1644
  } else {
1625
1645
  _node = this.createNode('text');
1626
- _node.text = String(value);
1646
+ this.setProp(_node, 'text', String(value));
1627
1647
  }
1628
1648
  } else {
1629
1649
  return this.dynamicDeclaration(data, value, ctx);
@@ -1653,11 +1673,11 @@ class Interpreter {
1653
1673
  effect: null,
1654
1674
  textNode: null,
1655
1675
  owner: ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node,
1656
- snapshot: this.tokenizer.snapshot(['dentStack']),
1676
+ snapshot: this.tokenizer.snapshot(['dentStack', 'isFirstToken']),
1657
1677
  parentDataProvider: ctx.stack.peekByType(NodeSort.CtxProvider)?.node
1658
1678
  };
1659
1679
  let isUpdate = false;
1660
- node.realAfter = this.insertAfterAnchor(`dynamic-after`);
1680
+ node.realAfter = this.insertAnchor(`dynamic-after`);
1661
1681
  node.effect = this.effect(({
1662
1682
  old,
1663
1683
  val
@@ -1666,7 +1686,7 @@ class Interpreter {
1666
1686
  oldTextNode = node.textNode;
1667
1687
  if (oldLogicType) {
1668
1688
  this.removeLogicNode(node);
1669
- pickInPlace(node, ['realParent', 'realBefore', 'realAfter',, 'owner', 'snapshot', 'parentDataProvider']);
1689
+ pickInPlace(node, ['realParent', 'realBefore', 'realAfter', 'owner', 'snapshot', 'parentDataProvider']);
1670
1690
  }
1671
1691
  if (isRenderAble(val)) {
1672
1692
  if (oldTextNode) {
@@ -1693,11 +1713,13 @@ class Interpreter {
1693
1713
  this.tokenizer = node.tokenizer;
1694
1714
  if (node.fragmentSnapshot) {
1695
1715
  this.tokenizer.resume(node.fragmentSnapshot);
1696
- this.tokenizer.useDedentAsEof = true;
1697
- this.tokenizer.initIndentWhenUseDedentAsEof();
1698
1716
  }
1699
1717
  if (isUpdate) {
1700
- this.program(node.realParent, node.owner, node.realBefore, node);
1718
+ this.tokenizer.useDedentAsEof = false;
1719
+ this.program(node.realParent, node, node.realBefore);
1720
+ } else {
1721
+ this.tokenizer.useDedentAsEof = true;
1722
+ this.tokenizer.initIndentWhenUseDedentAsEof();
1701
1723
  }
1702
1724
  } else {
1703
1725
  node.__logicType = FakeType.DynamicText;
@@ -1706,7 +1728,7 @@ class Interpreter {
1706
1728
  if (isNewTextNode) {
1707
1729
  textNode = node.textNode = this.createNode('text');
1708
1730
  }
1709
- textNode.text = String(val);
1731
+ this.setProp(textNode, 'text', String(val));
1710
1732
  if (isNewTextNode) {
1711
1733
  if (isUpdate) {
1712
1734
  this.handleInsert(node.realParent, textNode, node.realBefore);
@@ -1718,6 +1740,7 @@ class Interpreter {
1718
1740
  prevSibling = _this$ctx2.prevSibling;
1719
1741
  this.handleInsert(realParent, textNode, prevSibling);
1720
1742
  }
1743
+ this.leaveNode?.(textNode, false);
1721
1744
  }
1722
1745
  }
1723
1746
  isUpdate = true;
@@ -1748,7 +1771,7 @@ class Interpreter {
1748
1771
  realBefore: null,
1749
1772
  realAfter: null
1750
1773
  };
1751
- node.realAfter = this.insertAfterAnchor('context-after');
1774
+ node.realAfter = this.insertAnchor('context-after');
1752
1775
  return node;
1753
1776
  }
1754
1777
  formatForCollection(collection) {
@@ -1838,7 +1861,8 @@ class Interpreter {
1838
1861
  i: 0
1839
1862
  };
1840
1863
  if (keyExp) {
1841
- forNode.getKey = new Function('data', `let v;with(data){v=${keyExp}\n};return v;`);
1864
+ const rawGetKey = new Function('data', `with(data){return (${keyExp})}`);
1865
+ forNode.getKey = data => rawGetKey(safe(data));
1842
1866
  }
1843
1867
  window['for1'] = forNode;
1844
1868
  const data = this.getData();
@@ -1846,7 +1870,7 @@ class Interpreter {
1846
1870
  const hasArrExpKey = Reflect.has(data[Keys.Raw], arrExp);
1847
1871
  const arrSignal = hasArrExpKey ? (data[arrExp], cells.get(arrExp)) : new Computed(this.getFn(data, arrExp));
1848
1872
  forNode.arrSignal = arrSignal;
1849
- forNode.realAfter = this.insertAfterAnchor('for-after');
1873
+ forNode.realAfter = this.insertAnchor('for-after');
1850
1874
  const _forNode$snapshot = forNode.snapshot;
1851
1875
  _forNode$snapshot.dentStack;
1852
1876
  _forNode$snapshot.isFirstToken;
@@ -1869,8 +1893,8 @@ class Interpreter {
1869
1893
  const len = arr.length;
1870
1894
  for (let i = len; i--;) {
1871
1895
  const item = this.createForItem(forNode, i, data);
1872
- item.realAfter = this.insertAfterAnchor('for-item-after');
1873
- item.realBefore = this.insertAfterAnchor('for-item-before');
1896
+ item.realAfter = this.insertAnchor('for-item-after');
1897
+ item.realBefore = this.insertAnchor('for-item-before', true);
1874
1898
  item.realParent = forNode.realParent;
1875
1899
  children[i] = item;
1876
1900
  }
@@ -2037,7 +2061,7 @@ class Interpreter {
2037
2061
  newChildren[i] = item;
2038
2062
  let realAfter = this.createAnchor('for-item-after');
2039
2063
  this.handleInsert(forNode.realParent, realAfter, before);
2040
- let realBefore = this.createAnchor('for-item-before');
2064
+ let realBefore = this.createAnchor('for-item-before', true);
2041
2065
  this.handleInsert(forNode.realParent, realBefore, before);
2042
2066
  item.realBefore = realBefore;
2043
2067
  item.realAfter = realAfter;
@@ -2206,11 +2230,11 @@ class Interpreter {
2206
2230
  resumeSnapshot
2207
2231
  };
2208
2232
  this.onePropParsed = onePropParsed;
2209
- node.realAfter = this.insertAfterAnchor('component-after');
2233
+ node.realAfter = this.insertAnchor('component-after');
2210
2234
  return node;
2211
2235
  }
2212
2236
  getFn(data, expression) {
2213
- return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
2237
+ return new Function('data', `with(data){return (${expression})}`).bind(undefined, safe(data));
2214
2238
  }
2215
2239
  getAssignFn(data, expression) {
2216
2240
  const valueId = `value_bobe_${date32()}`;
@@ -2301,7 +2325,7 @@ class Interpreter {
2301
2325
  break;
2302
2326
  }
2303
2327
  ifNode.condition = signal;
2304
- ifNode.realAfter = this.insertAfterAnchor(`${keyWord.value}-after`);
2328
+ ifNode.realAfter = this.insertAnchor(`${keyWord.value}-after`);
2305
2329
  const ef = this.effect(({
2306
2330
  val
2307
2331
  }) => {
@@ -2486,10 +2510,11 @@ class Interpreter {
2486
2510
  firstChild(node) {
2487
2511
  return node.firstChild;
2488
2512
  }
2489
- createAnchor(name) {
2513
+ createAnchor(name, isBefore) {
2490
2514
  return {
2491
2515
  name,
2492
- nextSibling: null
2516
+ nextSibling: null,
2517
+ isBefore
2493
2518
  };
2494
2519
  }
2495
2520
  insertAfter(parent, node, prev) {
@@ -2559,6 +2584,7 @@ function bobe(fragments, ...values) {
2559
2584
  return tokenizer;
2560
2585
  };
2561
2586
  ui.boundStore = Store.Current;
2587
+ ui[Keys.ProxyFreeObject] = true;
2562
2588
  ui.__BOBE_IS_UI = true;
2563
2589
  return ui;
2564
2590
  }
@@ -2575,6 +2601,7 @@ function customRender(option) {
2575
2601
  tokenizer
2576
2602
  };
2577
2603
  terp.program(root, componentNode);
2604
+ option.onBeforeFlush?.();
2578
2605
  flushMicroEffectManual();
2579
2606
  return [componentNode, store];
2580
2607
  };