bobe 0.0.60 → 0.0.62

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.
@@ -1,5 +1,5 @@
1
- import { Queue, isNum, matchIdStart2, matchId, escapeMap, pickInPlace, jsVarRegexp, date32 } from 'bobe-shared';
2
- import { Signal, Computed, Keys, isStore, getPulling, setPulling, deepSignal, toRaw, ScheduleType, runWithPulling, Scope, Store, noopEffect, NoopEffect, Effect, effect as effect$1, shareSignal, flushMicroEffectManual } from 'aoye';
1
+ import { Queue, isNum, matchIdStart2, matchId, escapeMap, pickInPlace, jsVarRegexp, date32, hasOwn } from 'bobe-shared';
2
+ import { Signal, Computed, Keys, isStore, getPulling, setPulling, runWithPulling, getProxyHasKey, deepSignal, Scope, backupSignal, toRaw, ScheduleType, Store, noopEffect, NoopEffect, Effect, effect as effect$1, shareSignal, flushMicroEffectManual } from 'aoye';
3
3
  export { Store } from 'aoye';
4
4
 
5
5
  let TokenType = function (TokenType) {
@@ -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";
@@ -1460,7 +1461,7 @@ const SAFE_HANDLER = {
1460
1461
  has: () => true,
1461
1462
  get: (t, k) => {
1462
1463
  if (typeof k === 'symbol') return t[k];
1463
- return k in t ? t[k] : undefined;
1464
+ return t[k];
1464
1465
  }
1465
1466
  };
1466
1467
  const safe = data => new Proxy(data, SAFE_HANDLER);
@@ -1475,9 +1476,6 @@ class Interpreter {
1475
1476
  constructor(tokenizer) {
1476
1477
  this.tokenizer = tokenizer;
1477
1478
  }
1478
- isLogicNode(node) {
1479
- return node && node.__logicType & LogicalBit;
1480
- }
1481
1479
  rootComponent = null;
1482
1480
  program(root, componentNode, before, ctxProvider) {
1483
1481
  this.rootComponent = componentNode;
@@ -1496,7 +1494,7 @@ class Interpreter {
1496
1494
  stack.push({
1497
1495
  node: ctxProvider,
1498
1496
  prev: null
1499
- }, (ctxProvider.__logicType & LogicalBit ? NodeSort.Logic : 0) | NodeSort.CtxProvider);
1497
+ }, (ctxProvider.__logicType && ctxProvider.effect ? NodeSort.EffectNode : 0) | NodeSort.CtxProvider);
1500
1498
  }
1501
1499
  const rootLen = stack.length;
1502
1500
  const ctx = this.ctx = {
@@ -1519,18 +1517,24 @@ class Interpreter {
1519
1517
  const token = this.tokenizer.token;
1520
1518
  if (token.type & TokenType.Indent) {
1521
1519
  this.tokenizer.nextToken();
1522
- const isLogicNode = this.isLogicNode(ctx.current);
1520
+ const isEffectNode = ctx.current && ctx.current.__logicType && ctx.current.effect;
1523
1521
  stack.push({
1524
1522
  node: ctx.current,
1525
1523
  prev: ctx.prevSibling
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));
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 === FakeType.Tp ? NodeSort.Real : 0) | (ctx.current.__logicType & CtxProviderBit ? NodeSort.CtxProvider : 0));
1527
1525
  if (ctx.current.__logicType) {
1528
1526
  this.beforeLogicIndent?.(ctx.current);
1529
- if (isLogicNode) {
1527
+ if (isEffectNode) {
1530
1528
  setPulling(ctx.current.effect);
1531
1529
  if (ctx.current.__logicType & FakeType.ForItem) {
1532
1530
  ctx.prevSibling = ctx.current.realBefore;
1533
1531
  }
1532
+ if (ctx.current.__logicType & FakeType.Tp) {
1533
+ runWithPulling(() => {
1534
+ ctx.realParent = ctx.current.tpData.node;
1535
+ }, null);
1536
+ ctx.prevSibling = ctx.current.contentBefore;
1537
+ }
1534
1538
  }
1535
1539
  } else {
1536
1540
  if (ctx.current) {
@@ -1564,16 +1568,24 @@ class Interpreter {
1564
1568
  sort = _stack$pop2[1];
1565
1569
  if (!parent.__logicType) {
1566
1570
  const prevSameType = stack.peekByType(NodeSort.Real);
1567
- ctx.realParent = prevSameType?.node || root;
1571
+ const sameNode = prevSameType?.node;
1572
+ if (sameNode) {
1573
+ ctx.realParent = sameNode.__logicType === FakeType.Tp ? runWithPulling(() => sameNode.tpData.node, null) : sameNode;
1574
+ } else {
1575
+ ctx.realParent = root;
1576
+ }
1568
1577
  } else {
1569
- if (sort & NodeSort.Logic) {
1570
- const parentLogic = stack.peekByType(NodeSort.Logic)?.node;
1578
+ if (sort & NodeSort.EffectNode) {
1579
+ const parentLogic = stack.peekByType(NodeSort.EffectNode)?.node;
1571
1580
  if (parentLogic) {
1572
1581
  setPulling(parentLogic.effect);
1573
1582
  } else {
1574
1583
  setPulling(rootPulling);
1575
1584
  }
1576
1585
  }
1586
+ if (parent.__logicType === FakeType.Tp) {
1587
+ ctx.realParent = parent.realParent;
1588
+ }
1577
1589
  if (sort & NodeSort.TokenizerSwitcher) {
1578
1590
  const switcher = stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1579
1591
  if (parent.resumeSnapshot) {
@@ -1610,13 +1622,17 @@ class Interpreter {
1610
1622
  }
1611
1623
  return componentNode;
1612
1624
  }
1613
- insertAnchor(name = 'anchor', isBefore = false) {
1625
+ insertAnchor(node, name = 'anchor', isBefore = false) {
1614
1626
  const _this$ctx = this.ctx,
1615
1627
  realParent = _this$ctx.realParent,
1616
1628
  prevSibling = _this$ctx.prevSibling,
1617
1629
  stack = _this$ctx.stack,
1618
1630
  before = _this$ctx.before;
1631
+ _this$ctx.current;
1619
1632
  const afterAnchor = this.createAnchor(name, isBefore);
1633
+ if (!isBefore) {
1634
+ this.anchorRefBack(afterAnchor, node);
1635
+ }
1620
1636
  this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
1621
1637
  this.handleInsert(realParent, afterAnchor, prevSibling);
1622
1638
  return afterAnchor;
@@ -1661,6 +1677,8 @@ class Interpreter {
1661
1677
  return this.condDeclaration(ctx);
1662
1678
  } else if (value === 'context') {
1663
1679
  _node = this.createContextNode();
1680
+ } else if (value === 'tp') {
1681
+ return this.createTpNode();
1664
1682
  } else if (value === 'for') {
1665
1683
  return this.forDeclaration();
1666
1684
  } else if (hookType) {
@@ -1692,7 +1710,7 @@ class Interpreter {
1692
1710
  return _node;
1693
1711
  }
1694
1712
  dynamicDeclaration(pData, value, ctx) {
1695
- const valueIsMapKey = Reflect.has(pData[Keys.Raw], value);
1713
+ const valueIsMapKey = Boolean(getProxyHasKey(pData, value));
1696
1714
  let node = {
1697
1715
  __logicType: null,
1698
1716
  realParent: null,
@@ -1704,7 +1722,7 @@ class Interpreter {
1704
1722
  parentDataProvider: ctx.stack.peekByType(NodeSort.CtxProvider)?.node
1705
1723
  };
1706
1724
  let isUpdate = false;
1707
- node.realAfter = this.insertAnchor(`dynamic-after`);
1725
+ node.realAfter = this.insertAnchor(node, `dynamic-after`);
1708
1726
  node.effect = this.effect(({
1709
1727
  old,
1710
1728
  val
@@ -1776,10 +1794,110 @@ class Interpreter {
1776
1794
  this.removeLogicNode(node);
1777
1795
  }
1778
1796
  };
1779
- }, [() => {
1780
- const val = valueIsMapKey ? pData[value] : this.getFn(pData, value)();
1781
- return val;
1782
- }], {
1797
+ }, [valueIsMapKey ? () => pData[value] : this.getFn(pData, value)], {
1798
+ type: 'render'
1799
+ });
1800
+ return node;
1801
+ }
1802
+ createTpNode() {
1803
+ const child = deepSignal({}, getPulling());
1804
+ const node = {
1805
+ __logicType: FakeType.Tp,
1806
+ data: this.getData(),
1807
+ realParent: null,
1808
+ realBefore: null,
1809
+ realAfter: null,
1810
+ contentBefore: null,
1811
+ contentAfter: null,
1812
+ effect: null,
1813
+ snapshot: null,
1814
+ tpData: child,
1815
+ owner: this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node
1816
+ };
1817
+ this.onePropParsed = createStoreOnePropParsed(child);
1818
+ this.tokenizer.nextToken();
1819
+ this.headerLineAndExtensions(node);
1820
+ this.onePropParsed = this.oneRealPropParsed;
1821
+ node.realAfter = this.insertAnchor(node, 'tp-after');
1822
+ const before = node.contentBefore = this.createAnchor('tp-content-before', true);
1823
+ const after = node.contentAfter = this.createAnchor('tp-content-after', true);
1824
+ let firstRender = true;
1825
+ let scope = new Scope(() => {});
1826
+ scope.scope = null;
1827
+ runWithPulling(() => {
1828
+ scope.get();
1829
+ }, null);
1830
+ node.effect = scope;
1831
+ this.effect(({
1832
+ old: oldDom,
1833
+ val: dom
1834
+ }) => {
1835
+ const removeTpChild = () => {
1836
+ if (oldDom) {
1837
+ let point = before;
1838
+ do {
1839
+ const next = this.nextSib(point);
1840
+ this.remove(point, oldDom, null);
1841
+ if (point === after) break;
1842
+ point = next;
1843
+ } while (true);
1844
+ }
1845
+ };
1846
+ if (firstRender) {
1847
+ if (dom) {
1848
+ this.handleInsert(dom, after, null);
1849
+ this.handleInsert(dom, before, null);
1850
+ } else {
1851
+ if (this.tokenizer.token.type === TokenType.Indent) {
1852
+ const dentLen = this.tokenizer.dentStack[this.tokenizer.dentStack.length - 2] ?? 0;
1853
+ this.tokenizer.skip(dentLen);
1854
+ }
1855
+ }
1856
+ } else {
1857
+ if (dom) {
1858
+ if (oldDom) {
1859
+ let point = before,
1860
+ lastInsert = null;
1861
+ do {
1862
+ const next = this.nextSib(point);
1863
+ const fakeNode = point[FakeNode];
1864
+ if (fakeNode) {
1865
+ fakeNode.realParent = dom;
1866
+ }
1867
+ this.handleInsert(dom, point, lastInsert);
1868
+ if (point === after) break;
1869
+ lastInsert = point;
1870
+ point = next;
1871
+ } while (true);
1872
+ } else {
1873
+ this.handleInsert(dom, after, null);
1874
+ this.handleInsert(dom, before, null);
1875
+ runWithPulling(() => {
1876
+ this.tokenizer = node.owner.tokenizer;
1877
+ this.tokenizer.resume(node.snapshot);
1878
+ this.tokenizer.useDedentAsEof = false;
1879
+ this.program(dom, node.owner, before, node);
1880
+ }, scope);
1881
+ }
1882
+ } else {
1883
+ removeTpChild();
1884
+ scope.dispose();
1885
+ scope = new Scope(() => {});
1886
+ scope.scope = null;
1887
+ runWithPulling(() => {
1888
+ scope.get();
1889
+ }, null);
1890
+ node.effect = scope;
1891
+ }
1892
+ }
1893
+ firstRender = false;
1894
+ return isDestroy => {
1895
+ if (isDestroy) {
1896
+ removeTpChild();
1897
+ scope.dispose();
1898
+ }
1899
+ };
1900
+ }, [() => child.node], {
1783
1901
  type: 'render'
1784
1902
  });
1785
1903
  return node;
@@ -1788,7 +1906,7 @@ class Interpreter {
1788
1906
  const child = deepSignal({}, getPulling());
1789
1907
  const parentContext = this.ctx.stack.peekByType(NodeSort.Context)?.node?.context;
1790
1908
  if (parentContext) {
1791
- Object.setPrototypeOf(child, parentContext);
1909
+ backupSignal(child, parentContext);
1792
1910
  }
1793
1911
  this.onePropParsed = createStoreOnePropParsed(child);
1794
1912
  const node = {
@@ -1798,7 +1916,7 @@ class Interpreter {
1798
1916
  realBefore: null,
1799
1917
  realAfter: null
1800
1918
  };
1801
- node.realAfter = this.insertAnchor('context-after');
1919
+ node.realAfter = this.insertAnchor(node, 'context-after');
1802
1920
  return node;
1803
1921
  }
1804
1922
  formatForCollection(collection) {
@@ -1891,13 +2009,12 @@ class Interpreter {
1891
2009
  const rawGetKey = new Function('data', `with(data){return (${keyExp})}`);
1892
2010
  forNode.getKey = data => rawGetKey(safe(data));
1893
2011
  }
1894
- window['for1'] = forNode;
1895
2012
  const data = this.getData();
1896
2013
  const cells = data[Keys.Meta].cells;
1897
2014
  const hasArrExpKey = Reflect.has(data[Keys.Raw], arrExp);
1898
2015
  const arrSignal = hasArrExpKey ? (data[arrExp], cells.get(arrExp)) : new Computed(this.getFn(data, arrExp));
1899
2016
  forNode.arrSignal = arrSignal;
1900
- forNode.realAfter = this.insertAnchor('for-after');
2017
+ forNode.realAfter = this.insertAnchor(forNode, 'for-after');
1901
2018
  const _forNode$snapshot = forNode.snapshot;
1902
2019
  _forNode$snapshot.dentStack;
1903
2020
  _forNode$snapshot.isFirstToken;
@@ -1920,8 +2037,8 @@ class Interpreter {
1920
2037
  const len = arr.length;
1921
2038
  for (let i = len; i--;) {
1922
2039
  const item = this.createForItem(forNode, i, data);
1923
- item.realAfter = this.insertAnchor('for-item-after');
1924
- item.realBefore = this.insertAnchor('for-item-before', true);
2040
+ item.realAfter = this.insertAnchor(item, 'for-item-after');
2041
+ item.realBefore = this.insertAnchor(item, 'for-item-before', true);
1925
2042
  item.realParent = forNode.realParent;
1926
2043
  children[i] = item;
1927
2044
  }
@@ -2083,10 +2200,14 @@ class Interpreter {
2083
2200
  }, ScheduleType.Render);
2084
2201
  return forNode.children[0] || forNode;
2085
2202
  }
2203
+ anchorRefBack(anchor, node) {
2204
+ anchor[FakeNode] = node;
2205
+ }
2086
2206
  insertForItem(forNode, i, parentData, newChildren, before, snapshotForUpdate) {
2087
2207
  const item = this.createForItem(forNode, i, parentData);
2088
2208
  newChildren[i] = item;
2089
2209
  let realAfter = this.createAnchor('for-item-after');
2210
+ this.anchorRefBack(realAfter, item);
2090
2211
  this.handleInsert(forNode.realParent, realAfter, before);
2091
2212
  let realBefore = this.createAnchor('for-item-before', true);
2092
2213
  this.handleInsert(forNode.realParent, realBefore, before);
@@ -2173,7 +2294,7 @@ class Interpreter {
2173
2294
  cells.set(name, new Computed(() => computedData.get()[name]));
2174
2295
  }
2175
2296
  }
2176
- Object.setPrototypeOf(data, parentData);
2297
+ backupSignal(data, parentData);
2177
2298
  return data;
2178
2299
  }
2179
2300
  getData() {
@@ -2214,7 +2335,7 @@ class Interpreter {
2214
2335
  } else if (ComponentOrRender instanceof InlineFragment) {
2215
2336
  const conf = ComponentOrRender;
2216
2337
  child = deepSignal({}, getPulling(), true);
2217
- Object.setPrototypeOf(child, conf.data);
2338
+ backupSignal(child, conf.data);
2218
2339
  tokenizer = conf.tokenizer;
2219
2340
  fragmentSnapshot = conf.snapshot;
2220
2341
  __logicType = FakeType.Fragment;
@@ -2224,7 +2345,7 @@ class Interpreter {
2224
2345
  const boundStore = render.boundStore;
2225
2346
  child = deepSignal({}, getPulling(), true);
2226
2347
  if (boundStore) {
2227
- Object.setPrototypeOf(child, boundStore);
2348
+ backupSignal(child, boundStore);
2228
2349
  }
2229
2350
  tokenizer = render(true);
2230
2351
  __logicType = FakeType.Fragment;
@@ -2257,7 +2378,7 @@ class Interpreter {
2257
2378
  resumeSnapshot
2258
2379
  };
2259
2380
  this.onePropParsed = onePropParsed;
2260
- node.realAfter = this.insertAnchor('component-after');
2381
+ node.realAfter = this.insertAnchor(node, 'component-after');
2261
2382
  return node;
2262
2383
  }
2263
2384
  getFn(data, expression) {
@@ -2352,7 +2473,7 @@ class Interpreter {
2352
2473
  break;
2353
2474
  }
2354
2475
  ifNode.condition = signal;
2355
- ifNode.realAfter = this.insertAnchor(`${keyWord.value}-after`);
2476
+ ifNode.realAfter = this.insertAnchor(ifNode, `${keyWord.value}-after`);
2356
2477
  const ef = this.effect(({
2357
2478
  val
2358
2479
  }) => {
@@ -2395,10 +2516,11 @@ class Interpreter {
2395
2516
  const tokenizer = this.tokenizer;
2396
2517
  do {
2397
2518
  const isComponent = _node.__logicType & TokenizerSwitcherBit;
2519
+ const isTp = _node.__logicType === FakeType.Tp;
2398
2520
  let snapshot, dentLen;
2399
2521
  const data = this.getData();
2400
2522
  const unHandledKey = this.attributeList(_node, data);
2401
- if (isComponent) {
2523
+ if (isComponent || isTp) {
2402
2524
  snapshot = tokenizer.snapshot(undefined, -1);
2403
2525
  dentLen = tokenizer.dentStack[tokenizer.dentStack.length - 1];
2404
2526
  }
@@ -2410,6 +2532,9 @@ class Interpreter {
2410
2532
  if ((tokenizer.token.type & TokenType.Pipe) === 0) {
2411
2533
  break;
2412
2534
  }
2535
+ } else if (isTp) {
2536
+ _node.snapshot = snapshot;
2537
+ break;
2413
2538
  } else {
2414
2539
  break;
2415
2540
  }
@@ -2468,7 +2593,7 @@ class Interpreter {
2468
2593
  prevKeys.delete(k);
2469
2594
  if (isComponent) {
2470
2595
  const savedK = savedDefaults.has(k);
2471
- if (!savedK && Object.prototype.hasOwnProperty.call(rawTarget, k)) {
2596
+ if (!savedK && hasOwn(rawTarget, k)) {
2472
2597
  savedDefaults.set(k, rawTarget[k]);
2473
2598
  }
2474
2599
  const val = props[k];
@@ -2501,7 +2626,7 @@ class Interpreter {
2501
2626
  }).get();
2502
2627
  }
2503
2628
  } else if (hookType === 'dynamic') {
2504
- const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
2629
+ const valueIsMapKey = Boolean(getProxyHasKey(data, value));
2505
2630
  const fn = isFn ? rawVal : valueIsMapKey ? value : this.getFn(data, value);
2506
2631
  this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
2507
2632
  } else if (hookType === 'static') {