bobe 0.0.59 → 0.0.61

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.
@@ -34,15 +34,15 @@ let FakeType = function (FakeType) {
34
34
  FakeType[FakeType["ForItem"] = 64] = "ForItem";
35
35
  FakeType[FakeType["Context"] = 128] = "Context";
36
36
  FakeType[FakeType["DynamicText"] = 256] = "DynamicText";
37
+ FakeType[FakeType["Tp"] = 512] = "Tp";
37
38
  return FakeType;
38
39
  }({});
39
40
  const CondBit = FakeType.If | FakeType.Fail | FakeType.Else;
40
- const LogicalBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.For | FakeType.ForItem;
41
41
  const CtxProviderBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.For | FakeType.ForItem | FakeType.Component | FakeType.Fragment | FakeType.DynamicText;
42
- const ContextBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.ForItem | FakeType.Context;
42
+ const ContextBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.ForItem | FakeType.Context | FakeType.Tp;
43
43
  const TokenizerSwitcherBit = FakeType.Component | FakeType.Fragment;
44
44
  let NodeSort = function (NodeSort) {
45
- NodeSort[NodeSort["Logic"] = 1] = "Logic";
45
+ NodeSort[NodeSort["EffectNode"] = 1] = "EffectNode";
46
46
  NodeSort[NodeSort["Real"] = 2] = "Real";
47
47
  NodeSort[NodeSort["Component"] = 4] = "Component";
48
48
  NodeSort[NodeSort["CtxProvider"] = 8] = "CtxProvider";
@@ -55,6 +55,7 @@ let NodeSort = function (NodeSort) {
55
55
  TerpEvt["HandledComponentNode"] = "handled-component-node";
56
56
  return TerpEvt;
57
57
  })({});
58
+ const FakeNode = Symbol('fake-node');
58
59
  let ParseErrorCode = function (ParseErrorCode) {
59
60
  ParseErrorCode[ParseErrorCode["UNCLOSED_BRACE"] = 9001] = "UNCLOSED_BRACE";
60
61
  ParseErrorCode[ParseErrorCode["UNCLOSED_STRING"] = 9002] = "UNCLOSED_STRING";
@@ -1457,6 +1458,14 @@ class InlineFragment {
1457
1458
  }
1458
1459
  const isUI = fn => typeof fn === 'function' && fn.__BOBE_IS_UI;
1459
1460
  const isRenderAble = val => aoye.isStore(val) || isUI(val) || val instanceof InlineFragment;
1461
+ const SAFE_HANDLER = {
1462
+ has: () => true,
1463
+ get: (t, k) => {
1464
+ if (typeof k === 'symbol') return t[k];
1465
+ return k in t ? t[k] : undefined;
1466
+ }
1467
+ };
1468
+ const safe = data => new Proxy(data, SAFE_HANDLER);
1460
1469
 
1461
1470
  const KEY_INDEX = '__BOBE_KEY_INDEX';
1462
1471
  let _ctxStack;
@@ -1468,9 +1477,6 @@ class Interpreter {
1468
1477
  constructor(tokenizer) {
1469
1478
  this.tokenizer = tokenizer;
1470
1479
  }
1471
- isLogicNode(node) {
1472
- return node && node.__logicType & LogicalBit;
1473
- }
1474
1480
  rootComponent = null;
1475
1481
  program(root, componentNode, before, ctxProvider) {
1476
1482
  this.rootComponent = componentNode;
@@ -1489,7 +1495,7 @@ class Interpreter {
1489
1495
  stack.push({
1490
1496
  node: ctxProvider,
1491
1497
  prev: null
1492
- }, (ctxProvider.__logicType & LogicalBit ? NodeSort.Logic : 0) | NodeSort.CtxProvider);
1498
+ }, (ctxProvider.__logicType && ctxProvider.effect ? NodeSort.EffectNode : 0) | NodeSort.CtxProvider);
1493
1499
  }
1494
1500
  const rootLen = stack.length;
1495
1501
  const ctx = this.ctx = {
@@ -1512,18 +1518,22 @@ class Interpreter {
1512
1518
  const token = this.tokenizer.token;
1513
1519
  if (token.type & TokenType.Indent) {
1514
1520
  this.tokenizer.nextToken();
1515
- const isLogicNode = this.isLogicNode(ctx.current);
1521
+ const isEffectNode = ctx.current && ctx.current.__logicType && ctx.current.effect;
1516
1522
  stack.push({
1517
1523
  node: ctx.current,
1518
1524
  prev: ctx.prevSibling
1519
- }, !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));
1525
+ }, !ctx.current.__logicType ? NodeSort.Real : (isEffectNode ? NodeSort.EffectNode : 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));
1520
1526
  if (ctx.current.__logicType) {
1521
1527
  this.beforeLogicIndent?.(ctx.current);
1522
- if (isLogicNode) {
1528
+ if (isEffectNode) {
1523
1529
  aoye.setPulling(ctx.current.effect);
1524
1530
  if (ctx.current.__logicType & FakeType.ForItem) {
1525
1531
  ctx.prevSibling = ctx.current.realBefore;
1526
1532
  }
1533
+ if (ctx.current.__logicType & FakeType.Tp) {
1534
+ ctx.realParent = ctx.current.tpData[aoye.Keys.Raw].node;
1535
+ ctx.prevSibling = ctx.current.contentBefore;
1536
+ }
1527
1537
  }
1528
1538
  } else {
1529
1539
  if (ctx.current) {
@@ -1559,14 +1569,17 @@ class Interpreter {
1559
1569
  const prevSameType = stack.peekByType(NodeSort.Real);
1560
1570
  ctx.realParent = prevSameType?.node || root;
1561
1571
  } else {
1562
- if (sort & NodeSort.Logic) {
1563
- const parentLogic = stack.peekByType(NodeSort.Logic)?.node;
1572
+ if (sort & NodeSort.EffectNode) {
1573
+ const parentLogic = stack.peekByType(NodeSort.EffectNode)?.node;
1564
1574
  if (parentLogic) {
1565
1575
  aoye.setPulling(parentLogic.effect);
1566
1576
  } else {
1567
1577
  aoye.setPulling(rootPulling);
1568
1578
  }
1569
1579
  }
1580
+ if (parent.__logicType === FakeType.Tp) {
1581
+ ctx.realParent = parent.realParent;
1582
+ }
1570
1583
  if (sort & NodeSort.TokenizerSwitcher) {
1571
1584
  const switcher = stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1572
1585
  if (parent.resumeSnapshot) {
@@ -1603,13 +1616,17 @@ class Interpreter {
1603
1616
  }
1604
1617
  return componentNode;
1605
1618
  }
1606
- insertAnchor(name = 'anchor', isBefore = false) {
1619
+ insertAnchor(node, name = 'anchor', isBefore = false) {
1607
1620
  const _this$ctx = this.ctx,
1608
1621
  realParent = _this$ctx.realParent,
1609
1622
  prevSibling = _this$ctx.prevSibling,
1610
1623
  stack = _this$ctx.stack,
1611
1624
  before = _this$ctx.before;
1625
+ _this$ctx.current;
1612
1626
  const afterAnchor = this.createAnchor(name, isBefore);
1627
+ if (!isBefore) {
1628
+ this.anchorRefBack(afterAnchor, node);
1629
+ }
1613
1630
  this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
1614
1631
  this.handleInsert(realParent, afterAnchor, prevSibling);
1615
1632
  return afterAnchor;
@@ -1654,6 +1671,8 @@ class Interpreter {
1654
1671
  return this.condDeclaration(ctx);
1655
1672
  } else if (value === 'context') {
1656
1673
  _node = this.createContextNode();
1674
+ } else if (value === 'tp') {
1675
+ return this.createTpNode();
1657
1676
  } else if (value === 'for') {
1658
1677
  return this.forDeclaration();
1659
1678
  } else if (hookType) {
@@ -1693,11 +1712,11 @@ class Interpreter {
1693
1712
  effect: null,
1694
1713
  textNode: null,
1695
1714
  owner: ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node,
1696
- snapshot: this.tokenizer.snapshot(['dentStack']),
1715
+ snapshot: this.tokenizer.snapshot(['dentStack', 'isFirstToken']),
1697
1716
  parentDataProvider: ctx.stack.peekByType(NodeSort.CtxProvider)?.node
1698
1717
  };
1699
1718
  let isUpdate = false;
1700
- node.realAfter = this.insertAnchor(`dynamic-after`);
1719
+ node.realAfter = this.insertAnchor(node, `dynamic-after`);
1701
1720
  node.effect = this.effect(({
1702
1721
  old,
1703
1722
  val
@@ -1706,7 +1725,7 @@ class Interpreter {
1706
1725
  oldTextNode = node.textNode;
1707
1726
  if (oldLogicType) {
1708
1727
  this.removeLogicNode(node);
1709
- bobeShared.pickInPlace(node, ['realParent', 'realBefore', 'realAfter',, 'owner', 'snapshot', 'parentDataProvider']);
1728
+ bobeShared.pickInPlace(node, ['realParent', 'realBefore', 'realAfter', 'owner', 'snapshot', 'parentDataProvider']);
1710
1729
  }
1711
1730
  if (isRenderAble(val)) {
1712
1731
  if (oldTextNode) {
@@ -1736,7 +1755,7 @@ class Interpreter {
1736
1755
  }
1737
1756
  if (isUpdate) {
1738
1757
  this.tokenizer.useDedentAsEof = false;
1739
- this.program(node.realParent, node.owner, node.realBefore, node);
1758
+ this.program(node.realParent, node, node.realBefore);
1740
1759
  } else {
1741
1760
  this.tokenizer.useDedentAsEof = true;
1742
1761
  this.tokenizer.initIndentWhenUseDedentAsEof();
@@ -1777,6 +1796,93 @@ class Interpreter {
1777
1796
  });
1778
1797
  return node;
1779
1798
  }
1799
+ createTpNode() {
1800
+ const child = aoye.deepSignal({}, aoye.getPulling());
1801
+ const node = {
1802
+ __logicType: FakeType.Tp,
1803
+ data: this.getData(),
1804
+ realParent: null,
1805
+ realBefore: null,
1806
+ realAfter: null,
1807
+ contentBefore: null,
1808
+ contentAfter: null,
1809
+ effect: null,
1810
+ snapshot: null,
1811
+ tpData: child,
1812
+ owner: this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node
1813
+ };
1814
+ this.onePropParsed = createStoreOnePropParsed(child);
1815
+ this.tokenizer.nextToken();
1816
+ this.headerLineAndExtensions(node);
1817
+ this.onePropParsed = this.oneRealPropParsed;
1818
+ node.realAfter = this.insertAnchor(node, 'tp-after');
1819
+ const before = node.contentBefore = this.createAnchor('tp-content-before', true);
1820
+ const after = node.contentAfter = this.createAnchor('tp-content-after', true);
1821
+ let firstRender = true;
1822
+ node.effect = this.effect(({
1823
+ old: oldDom,
1824
+ val: dom
1825
+ }) => {
1826
+ const removeTpChild = () => {
1827
+ if (oldDom) {
1828
+ let point = before;
1829
+ do {
1830
+ const next = this.nextSib(point);
1831
+ this.remove(point, oldDom, null);
1832
+ if (point === after) break;
1833
+ point = next;
1834
+ } while (true);
1835
+ }
1836
+ };
1837
+ if (firstRender) {
1838
+ if (dom) {
1839
+ this.handleInsert(dom, after, null);
1840
+ this.handleInsert(dom, before, null);
1841
+ } else {
1842
+ if (this.tokenizer.token.type === TokenType.Indent) {
1843
+ const dentLen = this.tokenizer.dentStack[this.tokenizer.dentStack.length - 2] ?? 0;
1844
+ this.tokenizer.skip(dentLen);
1845
+ }
1846
+ }
1847
+ } else {
1848
+ if (dom) {
1849
+ if (oldDom) {
1850
+ let point = before,
1851
+ lastInsert = null;
1852
+ do {
1853
+ const next = this.nextSib(point);
1854
+ const fakeNode = point[FakeNode];
1855
+ if (fakeNode) {
1856
+ fakeNode.realParent = dom;
1857
+ }
1858
+ this.handleInsert(dom, point, lastInsert);
1859
+ if (point === after) break;
1860
+ lastInsert = point;
1861
+ point = next;
1862
+ } while (true);
1863
+ } else {
1864
+ this.handleInsert(dom, after, null);
1865
+ this.handleInsert(dom, before, null);
1866
+ this.tokenizer = node.owner.tokenizer;
1867
+ this.tokenizer.resume(node.snapshot);
1868
+ this.tokenizer.useDedentAsEof = false;
1869
+ this.program(dom, node.owner, before, node);
1870
+ }
1871
+ } else {
1872
+ removeTpChild();
1873
+ }
1874
+ }
1875
+ firstRender = false;
1876
+ return isDestroy => {
1877
+ if (isDestroy) {
1878
+ removeTpChild();
1879
+ }
1880
+ };
1881
+ }, [() => child.node], {
1882
+ type: 'render'
1883
+ });
1884
+ return node;
1885
+ }
1780
1886
  createContextNode() {
1781
1887
  const child = aoye.deepSignal({}, aoye.getPulling());
1782
1888
  const parentContext = this.ctx.stack.peekByType(NodeSort.Context)?.node?.context;
@@ -1791,7 +1897,7 @@ class Interpreter {
1791
1897
  realBefore: null,
1792
1898
  realAfter: null
1793
1899
  };
1794
- node.realAfter = this.insertAnchor('context-after');
1900
+ node.realAfter = this.insertAnchor(node, 'context-after');
1795
1901
  return node;
1796
1902
  }
1797
1903
  formatForCollection(collection) {
@@ -1881,15 +1987,15 @@ class Interpreter {
1881
1987
  i: 0
1882
1988
  };
1883
1989
  if (keyExp) {
1884
- forNode.getKey = new Function('data', `let v;with(data){v=${keyExp}\n};return v;`);
1990
+ const rawGetKey = new Function('data', `with(data){return (${keyExp})}`);
1991
+ forNode.getKey = data => rawGetKey(safe(data));
1885
1992
  }
1886
- window['for1'] = forNode;
1887
1993
  const data = this.getData();
1888
1994
  const cells = data[aoye.Keys.Meta].cells;
1889
1995
  const hasArrExpKey = Reflect.has(data[aoye.Keys.Raw], arrExp);
1890
1996
  const arrSignal = hasArrExpKey ? (data[arrExp], cells.get(arrExp)) : new aoye.Computed(this.getFn(data, arrExp));
1891
1997
  forNode.arrSignal = arrSignal;
1892
- forNode.realAfter = this.insertAnchor('for-after');
1998
+ forNode.realAfter = this.insertAnchor(forNode, 'for-after');
1893
1999
  const _forNode$snapshot = forNode.snapshot;
1894
2000
  _forNode$snapshot.dentStack;
1895
2001
  _forNode$snapshot.isFirstToken;
@@ -1912,8 +2018,8 @@ class Interpreter {
1912
2018
  const len = arr.length;
1913
2019
  for (let i = len; i--;) {
1914
2020
  const item = this.createForItem(forNode, i, data);
1915
- item.realAfter = this.insertAnchor('for-item-after');
1916
- item.realBefore = this.insertAnchor('for-item-before', true);
2021
+ item.realAfter = this.insertAnchor(item, 'for-item-after');
2022
+ item.realBefore = this.insertAnchor(item, 'for-item-before', true);
1917
2023
  item.realParent = forNode.realParent;
1918
2024
  children[i] = item;
1919
2025
  }
@@ -2075,10 +2181,14 @@ class Interpreter {
2075
2181
  }, aoye.ScheduleType.Render);
2076
2182
  return forNode.children[0] || forNode;
2077
2183
  }
2184
+ anchorRefBack(anchor, node) {
2185
+ anchor[FakeNode] = node;
2186
+ }
2078
2187
  insertForItem(forNode, i, parentData, newChildren, before, snapshotForUpdate) {
2079
2188
  const item = this.createForItem(forNode, i, parentData);
2080
2189
  newChildren[i] = item;
2081
2190
  let realAfter = this.createAnchor('for-item-after');
2191
+ this.anchorRefBack(realAfter, item);
2082
2192
  this.handleInsert(forNode.realParent, realAfter, before);
2083
2193
  let realBefore = this.createAnchor('for-item-before', true);
2084
2194
  this.handleInsert(forNode.realParent, realBefore, before);
@@ -2249,11 +2359,11 @@ class Interpreter {
2249
2359
  resumeSnapshot
2250
2360
  };
2251
2361
  this.onePropParsed = onePropParsed;
2252
- node.realAfter = this.insertAnchor('component-after');
2362
+ node.realAfter = this.insertAnchor(node, 'component-after');
2253
2363
  return node;
2254
2364
  }
2255
2365
  getFn(data, expression) {
2256
- return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
2366
+ return new Function('data', `with(data){return (${expression})}`).bind(undefined, safe(data));
2257
2367
  }
2258
2368
  getAssignFn(data, expression) {
2259
2369
  const valueId = `value_bobe_${bobeShared.date32()}`;
@@ -2344,7 +2454,7 @@ class Interpreter {
2344
2454
  break;
2345
2455
  }
2346
2456
  ifNode.condition = signal;
2347
- ifNode.realAfter = this.insertAnchor(`${keyWord.value}-after`);
2457
+ ifNode.realAfter = this.insertAnchor(ifNode, `${keyWord.value}-after`);
2348
2458
  const ef = this.effect(({
2349
2459
  val
2350
2460
  }) => {
@@ -2387,10 +2497,11 @@ class Interpreter {
2387
2497
  const tokenizer = this.tokenizer;
2388
2498
  do {
2389
2499
  const isComponent = _node.__logicType & TokenizerSwitcherBit;
2500
+ const isTp = _node.__logicType === FakeType.Tp;
2390
2501
  let snapshot, dentLen;
2391
2502
  const data = this.getData();
2392
2503
  const unHandledKey = this.attributeList(_node, data);
2393
- if (isComponent) {
2504
+ if (isComponent || isTp) {
2394
2505
  snapshot = tokenizer.snapshot(undefined, -1);
2395
2506
  dentLen = tokenizer.dentStack[tokenizer.dentStack.length - 1];
2396
2507
  }
@@ -2402,6 +2513,9 @@ class Interpreter {
2402
2513
  if ((tokenizer.token.type & TokenType.Pipe) === 0) {
2403
2514
  break;
2404
2515
  }
2516
+ } else if (isTp) {
2517
+ _node.snapshot = snapshot;
2518
+ break;
2405
2519
  } else {
2406
2520
  break;
2407
2521
  }
@@ -2603,6 +2717,7 @@ function bobe(fragments, ...values) {
2603
2717
  return tokenizer;
2604
2718
  };
2605
2719
  ui.boundStore = aoye.Store.Current;
2720
+ ui[aoye.Keys.ProxyFreeObject] = true;
2606
2721
  ui.__BOBE_IS_UI = true;
2607
2722
  return ui;
2608
2723
  }