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