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.
- package/dist/bobe.cjs.js +184 -33
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.compiler.cjs.js +184 -33
- package/dist/bobe.compiler.cjs.js.map +1 -1
- package/dist/bobe.compiler.esm.js +186 -35
- package/dist/bobe.compiler.esm.js.map +1 -1
- package/dist/bobe.esm.js +186 -35
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +30 -10
- package/dist/index.umd.js +184 -33
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
|
@@ -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
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
2089
|
-
let
|
|
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
|
-
|
|
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
|
|
2227
|
+
__logicType,
|
|
2113
2228
|
realParent: ctx.realParent,
|
|
2114
2229
|
realBefore: null,
|
|
2115
2230
|
realAfter: null,
|
|
2116
|
-
data
|
|
2231
|
+
data,
|
|
2117
2232
|
tokenizer,
|
|
2118
2233
|
fragmentSnapshot,
|
|
2119
2234
|
resumeSnapshot
|
|
2120
2235
|
};
|
|
2121
|
-
this.onePropParsed =
|
|
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 === '
|
|
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
|
|
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 =
|
|
2331
|
-
eq =
|
|
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) {
|