bobe 0.0.56 → 0.0.58

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,11 +33,12 @@ let FakeType = function (FakeType) {
33
33
  FakeType[FakeType["Fragment"] = 32] = "Fragment";
34
34
  FakeType[FakeType["ForItem"] = 64] = "ForItem";
35
35
  FakeType[FakeType["Context"] = 128] = "Context";
36
+ FakeType[FakeType["DynamicText"] = 256] = "DynamicText";
36
37
  return FakeType;
37
38
  }({});
38
39
  const CondBit = FakeType.If | FakeType.Fail | FakeType.Else;
39
40
  const LogicalBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.For | FakeType.ForItem;
40
- FakeType.If | FakeType.Fail | FakeType.Else | FakeType.For | FakeType.ForItem | FakeType.Component | FakeType.Fragment;
41
+ const CtxProviderBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.For | FakeType.ForItem | FakeType.Component | FakeType.Fragment | FakeType.DynamicText;
41
42
  const ContextBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.ForItem | FakeType.Context;
42
43
  const TokenizerSwitcherBit = FakeType.Component | FakeType.Fragment;
43
44
  let NodeSort = function (NodeSort) {
@@ -1445,6 +1446,17 @@ function macInc(arr) {
1445
1446
  }
1446
1447
  return candyLast;
1447
1448
  }
1449
+ class InlineFragment {
1450
+ [aoye.Keys.ProxyFreeObject] = true;
1451
+ constructor(snapshot, data, key, tokenizer) {
1452
+ this.snapshot = snapshot;
1453
+ this.data = data;
1454
+ this.key = key;
1455
+ this.tokenizer = tokenizer;
1456
+ }
1457
+ }
1458
+ const isUI = fn => typeof fn === 'function' && fn.__BOBE_IS_UI;
1459
+ const isRenderAble = val => aoye.isStore(val) || isUI(val) || val instanceof InlineFragment;
1448
1460
 
1449
1461
  const KEY_INDEX = '__BOBE_KEY_INDEX';
1450
1462
  let _ctxStack;
@@ -1501,7 +1513,7 @@ class Interpreter {
1501
1513
  stack.push({
1502
1514
  node: ctx.current,
1503
1515
  prev: ctx.prevSibling
1504
- }, !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 !== FakeType.Context ? NodeSort.CtxProvider : 0));
1516
+ }, !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));
1505
1517
  if (ctx.current.__logicType) {
1506
1518
  if (isLogicNode) {
1507
1519
  aoye.setPulling(ctx.current.effect);
@@ -1635,21 +1647,14 @@ class Interpreter {
1635
1647
  } else if (hookType) {
1636
1648
  const data = this.getData();
1637
1649
  if (hookType === 'static') {
1638
- if (typeof value === 'function') {
1650
+ if (isRenderAble(value)) {
1639
1651
  _node = this.componentOrFragmentDeclaration(value, ctx);
1640
1652
  } else {
1641
- throw new SyntaxError(`declaration 不支持 ${value} 类型的静态插值`);
1642
- }
1643
- } else {
1644
- const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
1645
- const val = data[aoye.Keys.Raw][value];
1646
- if (typeof val === 'function' || val instanceof InlineFragment) {
1647
- _node = this.componentOrFragmentDeclaration(val, ctx);
1648
- } else {
1649
- const str = valueIsMapKey ? value : this.getFn(data, value);
1650
1653
  _node = this.createNode('text');
1651
- this.onePropParsed(data, _node, 'text', str, valueIsMapKey, false);
1654
+ _node.text = String(value);
1652
1655
  }
1656
+ } else {
1657
+ return this.dynamicDeclaration(data, value, ctx);
1653
1658
  }
1654
1659
  } else {
1655
1660
  _node = this.createNode(value);
@@ -1667,6 +1672,96 @@ class Interpreter {
1667
1672
  }
1668
1673
  return _node;
1669
1674
  }
1675
+ dynamicDeclaration(pData, value, ctx) {
1676
+ const valueIsMapKey = Reflect.has(pData[aoye.Keys.Raw], value);
1677
+ let node = {
1678
+ __logicType: null,
1679
+ realParent: null,
1680
+ tokenizer: null,
1681
+ effect: null,
1682
+ textNode: null,
1683
+ owner: ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node,
1684
+ snapshot: this.tokenizer.snapshot(['dentStack']),
1685
+ parentDataProvider: ctx.stack.peekByType(NodeSort.CtxProvider)?.node
1686
+ };
1687
+ let isUpdate = false;
1688
+ node.realAfter = this.insertAfterAnchor(`dynamic-after`);
1689
+ node.effect = this.effect(({
1690
+ old,
1691
+ val
1692
+ }) => {
1693
+ let oldLogicType = node.__logicType,
1694
+ oldTextNode = node.textNode;
1695
+ if (oldLogicType) {
1696
+ this.removeLogicNode(node);
1697
+ bobeShared.pickInPlace(node, ['realParent', 'realBefore', 'realAfter',, 'owner', 'snapshot', 'parentDataProvider']);
1698
+ }
1699
+ if (isRenderAble(val)) {
1700
+ if (oldTextNode) {
1701
+ this.remove(oldTextNode);
1702
+ }
1703
+ const info = this.createComponentData(val);
1704
+ info.__logicType;
1705
+ Object.assign(node, info);
1706
+ this.onePropParsed = info.onePropParsed;
1707
+ if (isUpdate) {
1708
+ this.tokenizer = node.owner.tokenizer;
1709
+ this.tokenizer.resume(node.snapshot);
1710
+ this.ctx.stack.push({
1711
+ node: node.parentDataProvider,
1712
+ prev: null
1713
+ }, NodeSort.CtxProvider);
1714
+ }
1715
+ this.tokenizer.nextToken();
1716
+ this.headerLineAndExtensions(node);
1717
+ if (isUpdate) {
1718
+ this.ctx.stack.pop();
1719
+ }
1720
+ this.onePropParsed = this.oneRealPropParsed;
1721
+ this.tokenizer = node.tokenizer;
1722
+ if (node.fragmentSnapshot) {
1723
+ this.tokenizer.resume(node.fragmentSnapshot);
1724
+ this.tokenizer.useDedentAsEof = true;
1725
+ this.tokenizer.initIndentWhenUseDedentAsEof();
1726
+ }
1727
+ if (isUpdate) {
1728
+ this.program(node.realParent, node.owner, node.realBefore, node);
1729
+ }
1730
+ } else {
1731
+ node.__logicType = FakeType.DynamicText;
1732
+ let textNode = oldTextNode;
1733
+ const isNewTextNode = !textNode;
1734
+ if (isNewTextNode) {
1735
+ textNode = node.textNode = this.createNode('text');
1736
+ }
1737
+ textNode.text = String(val);
1738
+ if (isNewTextNode) {
1739
+ if (isUpdate) {
1740
+ this.handleInsert(node.realParent, textNode, node.realBefore);
1741
+ } else {
1742
+ this.tokenizer.nextToken();
1743
+ this.headerLineAndExtensions(node);
1744
+ const _this$ctx2 = this.ctx,
1745
+ realParent = _this$ctx2.realParent,
1746
+ prevSibling = _this$ctx2.prevSibling;
1747
+ this.handleInsert(realParent, textNode, prevSibling);
1748
+ }
1749
+ }
1750
+ }
1751
+ isUpdate = true;
1752
+ return isDestroy => {
1753
+ if (isDestroy) {
1754
+ this.removeLogicNode(node);
1755
+ }
1756
+ };
1757
+ }, [() => {
1758
+ const val = valueIsMapKey ? pData[value] : this.getFn(pData, value)();
1759
+ return val;
1760
+ }], {
1761
+ type: 'render'
1762
+ });
1763
+ return node;
1764
+ }
1670
1765
  createContextNode() {
1671
1766
  const child = aoye.deepSignal({}, aoye.getPulling());
1672
1767
  const parentContext = this.ctx.stack.peekByType(NodeSort.Context)?.node?.context;
@@ -2085,20 +2180,22 @@ class Interpreter {
2085
2180
  }
2086
2181
  }
2087
2182
  oneRealPropParsed = this.onePropParsed.bind(this);
2088
- componentOrFragmentDeclaration(ComponentOrRender, ctx) {
2089
- let Component, tokenizer, child, fragmentSnapshot, resumeSnapshot;
2183
+ createComponentData(ComponentOrRender) {
2184
+ let tokenizer, child, fragmentSnapshot, resumeSnapshot, __logicType;
2090
2185
  const isCC = ComponentOrRender.prototype instanceof aoye.Store;
2091
2186
  if (isCC) {
2092
- Component = ComponentOrRender;
2187
+ const Component = ComponentOrRender;
2093
2188
  child = Component.new();
2094
2189
  tokenizer = child.ui(true);
2190
+ __logicType = FakeType.Component;
2095
2191
  } else if (ComponentOrRender instanceof InlineFragment) {
2096
2192
  const conf = ComponentOrRender;
2097
2193
  child = aoye.deepSignal({}, aoye.getPulling(), true);
2098
2194
  Object.setPrototypeOf(child, conf.data);
2099
2195
  tokenizer = conf.tokenizer;
2100
2196
  fragmentSnapshot = conf.snapshot;
2101
- resumeSnapshot = tokenizer.snapshot(['token', 'needIndent', 'isFirstToken', 'dentStack', 'isFirstToken', 'useDedentAsEof']);
2197
+ __logicType = FakeType.Fragment;
2198
+ resumeSnapshot = tokenizer.snapshot(['dentStack', 'token', 'needIndent', 'isFirstToken', 'isFirstToken', 'useDedentAsEof']);
2102
2199
  } else {
2103
2200
  const render = ComponentOrRender;
2104
2201
  const boundStore = render.boundStore;
@@ -2107,18 +2204,36 @@ class Interpreter {
2107
2204
  Object.setPrototypeOf(child, boundStore);
2108
2205
  }
2109
2206
  tokenizer = render(true);
2207
+ __logicType = FakeType.Fragment;
2110
2208
  }
2209
+ return {
2210
+ data: child,
2211
+ tokenizer,
2212
+ onePropParsed: createStoreOnePropParsed(child),
2213
+ fragmentSnapshot,
2214
+ resumeSnapshot,
2215
+ __logicType
2216
+ };
2217
+ }
2218
+ componentOrFragmentDeclaration(ComponentOrRender, ctx) {
2219
+ const _this$createComponent = this.createComponentData(ComponentOrRender),
2220
+ data = _this$createComponent.data,
2221
+ tokenizer = _this$createComponent.tokenizer,
2222
+ onePropParsed = _this$createComponent.onePropParsed,
2223
+ fragmentSnapshot = _this$createComponent.fragmentSnapshot,
2224
+ resumeSnapshot = _this$createComponent.resumeSnapshot,
2225
+ __logicType = _this$createComponent.__logicType;
2111
2226
  const node = {
2112
- __logicType: isCC ? FakeType.Component : FakeType.Fragment,
2227
+ __logicType,
2113
2228
  realParent: ctx.realParent,
2114
2229
  realBefore: null,
2115
2230
  realAfter: null,
2116
- data: child,
2231
+ data,
2117
2232
  tokenizer,
2118
2233
  fragmentSnapshot,
2119
2234
  resumeSnapshot
2120
2235
  };
2121
- this.onePropParsed = createStoreOnePropParsed(child);
2236
+ this.onePropParsed = onePropParsed;
2122
2237
  node.realAfter = this.insertAfterAnchor('component-after');
2123
2238
  return node;
2124
2239
  }
@@ -2298,10 +2413,54 @@ class Interpreter {
2298
2413
  hookI = _this$tokenizer$_hook4[2];
2299
2414
  const rawVal = data[aoye.Keys.Raw][value];
2300
2415
  const isFn = typeof rawVal === 'function';
2301
- if (key === 'ref') {
2416
+ if (key === 'props') {
2417
+ let prevKeys = new Set();
2418
+ const savedDefaults = new Map();
2419
+ new this.Effect(() => {
2420
+ const props = isFn ? rawVal : Reflect.has(data[aoye.Keys.Raw], value) ? data[value] : this.getFn(data, value)();
2421
+ const isComponent = _node.__logicType & TokenizerSwitcherBit;
2422
+ const rawTarget = isComponent ? _node.data[aoye.Keys.Raw] : null;
2423
+ const cleanupKeys = keysToClean => {
2424
+ for (const k of keysToClean) {
2425
+ if (k.startsWith('on')) continue;
2426
+ if (isComponent) {
2427
+ _node.data[k] = savedDefaults.has(k) ? savedDefaults.get(k) : undefined;
2428
+ } else {
2429
+ this.setProp(_node, k, undefined, hookI);
2430
+ }
2431
+ }
2432
+ };
2433
+ if (!props || typeof props !== 'object') {
2434
+ cleanupKeys(prevKeys);
2435
+ prevKeys.clear();
2436
+ return;
2437
+ }
2438
+ props[aoye.Keys.Iterator];
2439
+ const raw = props[aoye.Keys.Raw] || props;
2440
+ const keys = Object.keys(raw);
2441
+ const newKeys = new Set();
2442
+ for (let i = 0; i < keys.length; i++) {
2443
+ const k = keys[i];
2444
+ newKeys.add(k);
2445
+ prevKeys.delete(k);
2446
+ if (isComponent) {
2447
+ const savedK = savedDefaults.has(k);
2448
+ if (!savedK && Object.prototype.hasOwnProperty.call(rawTarget, k)) {
2449
+ savedDefaults.set(k, rawTarget[k]);
2450
+ }
2451
+ const val = props[k];
2452
+ _node.data[k] = val === undefined && savedK ? savedDefaults.get(k) : val;
2453
+ } else {
2454
+ this.onePropParsed(props, _node, k, k, true, false, hookI);
2455
+ }
2456
+ }
2457
+ cleanupKeys(prevKeys);
2458
+ prevKeys = newKeys;
2459
+ }, aoye.ScheduleType.Render);
2460
+ } else if (key === 'ref') {
2302
2461
  const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
2303
2462
  let refValue = _node;
2304
- if (_node.__logicType === FakeType.Component) {
2463
+ if (_node.__logicType & TokenizerSwitcherBit) {
2305
2464
  refValue = _node.data;
2306
2465
  } else {
2307
2466
  refValue[aoye.Keys.ProxyFreeObject] = true;
@@ -2327,8 +2486,8 @@ class Interpreter {
2327
2486
  } else {
2328
2487
  this.onePropParsed(data, _node, key, value, false, isFn, hookI);
2329
2488
  }
2330
- key = null;
2331
- eq = null;
2489
+ key = undefined;
2490
+ eq = undefined;
2332
2491
  }
2333
2492
  this.tokenizer.nextToken();
2334
2493
  }
@@ -2416,15 +2575,6 @@ function createStoreOnePropParsed(child) {
2416
2575
  };
2417
2576
  return onePropParsed;
2418
2577
  }
2419
- class InlineFragment {
2420
- [aoye.Keys.ProxyFreeObject] = true;
2421
- constructor(snapshot, data, key, tokenizer) {
2422
- this.snapshot = snapshot;
2423
- this.data = data;
2424
- this.key = key;
2425
- this.tokenizer = tokenizer;
2426
- }
2427
- }
2428
2578
 
2429
2579
  function bobe(fragments, ...values) {
2430
2580
  const ui = function ui(isSub) {
@@ -2437,6 +2587,7 @@ function bobe(fragments, ...values) {
2437
2587
  return tokenizer;
2438
2588
  };
2439
2589
  ui.boundStore = aoye.Store.Current;
2590
+ ui.__BOBE_IS_UI = true;
2440
2591
  return ui;
2441
2592
  }
2442
2593
  function customRender(option) {