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