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
package/dist/bobe.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Queue, isNum, matchIdStart2, matchId, escapeMap, jsVarRegexp, date32 } from 'bobe-shared';
|
|
2
|
-
import { Signal, Computed, Keys, 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 } 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';
|
|
3
3
|
export { Store } from 'aoye';
|
|
4
4
|
|
|
5
5
|
let TokenType = function (TokenType) {
|
|
@@ -32,11 +32,12 @@ let FakeType = function (FakeType) {
|
|
|
32
32
|
FakeType[FakeType["Fragment"] = 32] = "Fragment";
|
|
33
33
|
FakeType[FakeType["ForItem"] = 64] = "ForItem";
|
|
34
34
|
FakeType[FakeType["Context"] = 128] = "Context";
|
|
35
|
+
FakeType[FakeType["DynamicText"] = 256] = "DynamicText";
|
|
35
36
|
return FakeType;
|
|
36
37
|
}({});
|
|
37
38
|
const CondBit = FakeType.If | FakeType.Fail | FakeType.Else;
|
|
38
39
|
const LogicalBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.For | FakeType.ForItem;
|
|
39
|
-
FakeType.If | FakeType.Fail | FakeType.Else | FakeType.For | FakeType.ForItem | FakeType.Component | FakeType.Fragment;
|
|
40
|
+
const CtxProviderBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.For | FakeType.ForItem | FakeType.Component | FakeType.Fragment | FakeType.DynamicText;
|
|
40
41
|
const ContextBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.ForItem | FakeType.Context;
|
|
41
42
|
const TokenizerSwitcherBit = FakeType.Component | FakeType.Fragment;
|
|
42
43
|
let NodeSort = function (NodeSort) {
|
|
@@ -1417,6 +1418,17 @@ function macInc(arr) {
|
|
|
1417
1418
|
}
|
|
1418
1419
|
return candyLast;
|
|
1419
1420
|
}
|
|
1421
|
+
class InlineFragment {
|
|
1422
|
+
[Keys.ProxyFreeObject] = true;
|
|
1423
|
+
constructor(snapshot, data, key, tokenizer) {
|
|
1424
|
+
this.snapshot = snapshot;
|
|
1425
|
+
this.data = data;
|
|
1426
|
+
this.key = key;
|
|
1427
|
+
this.tokenizer = tokenizer;
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
const isUI = fn => typeof fn === 'function' && fn.__BOBE_IS_UI;
|
|
1431
|
+
const isRenderAble = val => isStore(val) || isUI(val) || val instanceof InlineFragment;
|
|
1420
1432
|
|
|
1421
1433
|
const KEY_INDEX = '__BOBE_KEY_INDEX';
|
|
1422
1434
|
let _ctxStack;
|
|
@@ -1473,7 +1485,7 @@ class Interpreter {
|
|
|
1473
1485
|
stack.push({
|
|
1474
1486
|
node: ctx.current,
|
|
1475
1487
|
prev: ctx.prevSibling
|
|
1476
|
-
}, !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
|
|
1488
|
+
}, !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));
|
|
1477
1489
|
if (ctx.current.__logicType) {
|
|
1478
1490
|
if (isLogicNode) {
|
|
1479
1491
|
setPulling(ctx.current.effect);
|
|
@@ -1607,21 +1619,14 @@ class Interpreter {
|
|
|
1607
1619
|
} else if (hookType) {
|
|
1608
1620
|
const data = this.getData();
|
|
1609
1621
|
if (hookType === 'static') {
|
|
1610
|
-
if (
|
|
1622
|
+
if (isRenderAble(value)) {
|
|
1611
1623
|
_node = this.componentOrFragmentDeclaration(value, ctx);
|
|
1612
1624
|
} else {
|
|
1613
|
-
throw new SyntaxError(`declaration 不支持 ${value} 类型的静态插值`);
|
|
1614
|
-
}
|
|
1615
|
-
} else {
|
|
1616
|
-
const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
|
|
1617
|
-
const val = data[Keys.Raw][value];
|
|
1618
|
-
if (typeof val === 'function' || val instanceof InlineFragment) {
|
|
1619
|
-
_node = this.componentOrFragmentDeclaration(val, ctx);
|
|
1620
|
-
} else {
|
|
1621
|
-
const str = valueIsMapKey ? value : this.getFn(data, value);
|
|
1622
1625
|
_node = this.createNode('text');
|
|
1623
|
-
|
|
1626
|
+
_node.text = String(value);
|
|
1624
1627
|
}
|
|
1628
|
+
} else {
|
|
1629
|
+
return this.dynamicDeclaration(data, value, ctx);
|
|
1625
1630
|
}
|
|
1626
1631
|
} else {
|
|
1627
1632
|
_node = this.createNode(value);
|
|
@@ -1639,6 +1644,96 @@ class Interpreter {
|
|
|
1639
1644
|
}
|
|
1640
1645
|
return _node;
|
|
1641
1646
|
}
|
|
1647
|
+
dynamicDeclaration(pData, value, ctx) {
|
|
1648
|
+
const valueIsMapKey = Reflect.has(pData[Keys.Raw], value);
|
|
1649
|
+
let node = {
|
|
1650
|
+
__logicType: null,
|
|
1651
|
+
realParent: null,
|
|
1652
|
+
tokenizer: null,
|
|
1653
|
+
effect: null,
|
|
1654
|
+
textNode: null,
|
|
1655
|
+
owner: ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node,
|
|
1656
|
+
snapshot: this.tokenizer.snapshot(['dentStack']),
|
|
1657
|
+
parentDataProvider: ctx.stack.peekByType(NodeSort.CtxProvider)?.node
|
|
1658
|
+
};
|
|
1659
|
+
let isUpdate = false;
|
|
1660
|
+
node.realAfter = this.insertAfterAnchor(`dynamic-after`);
|
|
1661
|
+
node.effect = this.effect(({
|
|
1662
|
+
old,
|
|
1663
|
+
val
|
|
1664
|
+
}) => {
|
|
1665
|
+
let oldLogicType = node.__logicType,
|
|
1666
|
+
oldTextNode = node.textNode;
|
|
1667
|
+
if (oldLogicType) {
|
|
1668
|
+
this.removeLogicNode(node);
|
|
1669
|
+
pickInPlace(node, ['realParent', 'realBefore', 'realAfter',, 'owner', 'snapshot', 'parentDataProvider']);
|
|
1670
|
+
}
|
|
1671
|
+
if (isRenderAble(val)) {
|
|
1672
|
+
if (oldTextNode) {
|
|
1673
|
+
this.remove(oldTextNode);
|
|
1674
|
+
}
|
|
1675
|
+
const info = this.createComponentData(val);
|
|
1676
|
+
info.__logicType;
|
|
1677
|
+
Object.assign(node, info);
|
|
1678
|
+
this.onePropParsed = info.onePropParsed;
|
|
1679
|
+
if (isUpdate) {
|
|
1680
|
+
this.tokenizer = node.owner.tokenizer;
|
|
1681
|
+
this.tokenizer.resume(node.snapshot);
|
|
1682
|
+
this.ctx.stack.push({
|
|
1683
|
+
node: node.parentDataProvider,
|
|
1684
|
+
prev: null
|
|
1685
|
+
}, NodeSort.CtxProvider);
|
|
1686
|
+
}
|
|
1687
|
+
this.tokenizer.nextToken();
|
|
1688
|
+
this.headerLineAndExtensions(node);
|
|
1689
|
+
if (isUpdate) {
|
|
1690
|
+
this.ctx.stack.pop();
|
|
1691
|
+
}
|
|
1692
|
+
this.onePropParsed = this.oneRealPropParsed;
|
|
1693
|
+
this.tokenizer = node.tokenizer;
|
|
1694
|
+
if (node.fragmentSnapshot) {
|
|
1695
|
+
this.tokenizer.resume(node.fragmentSnapshot);
|
|
1696
|
+
this.tokenizer.useDedentAsEof = true;
|
|
1697
|
+
this.tokenizer.initIndentWhenUseDedentAsEof();
|
|
1698
|
+
}
|
|
1699
|
+
if (isUpdate) {
|
|
1700
|
+
this.program(node.realParent, node.owner, node.realBefore, node);
|
|
1701
|
+
}
|
|
1702
|
+
} else {
|
|
1703
|
+
node.__logicType = FakeType.DynamicText;
|
|
1704
|
+
let textNode = oldTextNode;
|
|
1705
|
+
const isNewTextNode = !textNode;
|
|
1706
|
+
if (isNewTextNode) {
|
|
1707
|
+
textNode = node.textNode = this.createNode('text');
|
|
1708
|
+
}
|
|
1709
|
+
textNode.text = String(val);
|
|
1710
|
+
if (isNewTextNode) {
|
|
1711
|
+
if (isUpdate) {
|
|
1712
|
+
this.handleInsert(node.realParent, textNode, node.realBefore);
|
|
1713
|
+
} else {
|
|
1714
|
+
this.tokenizer.nextToken();
|
|
1715
|
+
this.headerLineAndExtensions(node);
|
|
1716
|
+
const _this$ctx2 = this.ctx,
|
|
1717
|
+
realParent = _this$ctx2.realParent,
|
|
1718
|
+
prevSibling = _this$ctx2.prevSibling;
|
|
1719
|
+
this.handleInsert(realParent, textNode, prevSibling);
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
isUpdate = true;
|
|
1724
|
+
return isDestroy => {
|
|
1725
|
+
if (isDestroy) {
|
|
1726
|
+
this.removeLogicNode(node);
|
|
1727
|
+
}
|
|
1728
|
+
};
|
|
1729
|
+
}, [() => {
|
|
1730
|
+
const val = valueIsMapKey ? pData[value] : this.getFn(pData, value)();
|
|
1731
|
+
return val;
|
|
1732
|
+
}], {
|
|
1733
|
+
type: 'render'
|
|
1734
|
+
});
|
|
1735
|
+
return node;
|
|
1736
|
+
}
|
|
1642
1737
|
createContextNode() {
|
|
1643
1738
|
const child = deepSignal({}, getPulling());
|
|
1644
1739
|
const parentContext = this.ctx.stack.peekByType(NodeSort.Context)?.node?.context;
|
|
@@ -2057,20 +2152,22 @@ class Interpreter {
|
|
|
2057
2152
|
}
|
|
2058
2153
|
}
|
|
2059
2154
|
oneRealPropParsed = this.onePropParsed.bind(this);
|
|
2060
|
-
|
|
2061
|
-
let
|
|
2155
|
+
createComponentData(ComponentOrRender) {
|
|
2156
|
+
let tokenizer, child, fragmentSnapshot, resumeSnapshot, __logicType;
|
|
2062
2157
|
const isCC = ComponentOrRender.prototype instanceof Store;
|
|
2063
2158
|
if (isCC) {
|
|
2064
|
-
Component = ComponentOrRender;
|
|
2159
|
+
const Component = ComponentOrRender;
|
|
2065
2160
|
child = Component.new();
|
|
2066
2161
|
tokenizer = child.ui(true);
|
|
2162
|
+
__logicType = FakeType.Component;
|
|
2067
2163
|
} else if (ComponentOrRender instanceof InlineFragment) {
|
|
2068
2164
|
const conf = ComponentOrRender;
|
|
2069
2165
|
child = deepSignal({}, getPulling(), true);
|
|
2070
2166
|
Object.setPrototypeOf(child, conf.data);
|
|
2071
2167
|
tokenizer = conf.tokenizer;
|
|
2072
2168
|
fragmentSnapshot = conf.snapshot;
|
|
2073
|
-
|
|
2169
|
+
__logicType = FakeType.Fragment;
|
|
2170
|
+
resumeSnapshot = tokenizer.snapshot(['dentStack', 'token', 'needIndent', 'isFirstToken', 'isFirstToken', 'useDedentAsEof']);
|
|
2074
2171
|
} else {
|
|
2075
2172
|
const render = ComponentOrRender;
|
|
2076
2173
|
const boundStore = render.boundStore;
|
|
@@ -2079,18 +2176,36 @@ class Interpreter {
|
|
|
2079
2176
|
Object.setPrototypeOf(child, boundStore);
|
|
2080
2177
|
}
|
|
2081
2178
|
tokenizer = render(true);
|
|
2179
|
+
__logicType = FakeType.Fragment;
|
|
2082
2180
|
}
|
|
2181
|
+
return {
|
|
2182
|
+
data: child,
|
|
2183
|
+
tokenizer,
|
|
2184
|
+
onePropParsed: createStoreOnePropParsed(child),
|
|
2185
|
+
fragmentSnapshot,
|
|
2186
|
+
resumeSnapshot,
|
|
2187
|
+
__logicType
|
|
2188
|
+
};
|
|
2189
|
+
}
|
|
2190
|
+
componentOrFragmentDeclaration(ComponentOrRender, ctx) {
|
|
2191
|
+
const _this$createComponent = this.createComponentData(ComponentOrRender),
|
|
2192
|
+
data = _this$createComponent.data,
|
|
2193
|
+
tokenizer = _this$createComponent.tokenizer,
|
|
2194
|
+
onePropParsed = _this$createComponent.onePropParsed,
|
|
2195
|
+
fragmentSnapshot = _this$createComponent.fragmentSnapshot,
|
|
2196
|
+
resumeSnapshot = _this$createComponent.resumeSnapshot,
|
|
2197
|
+
__logicType = _this$createComponent.__logicType;
|
|
2083
2198
|
const node = {
|
|
2084
|
-
__logicType
|
|
2199
|
+
__logicType,
|
|
2085
2200
|
realParent: ctx.realParent,
|
|
2086
2201
|
realBefore: null,
|
|
2087
2202
|
realAfter: null,
|
|
2088
|
-
data
|
|
2203
|
+
data,
|
|
2089
2204
|
tokenizer,
|
|
2090
2205
|
fragmentSnapshot,
|
|
2091
2206
|
resumeSnapshot
|
|
2092
2207
|
};
|
|
2093
|
-
this.onePropParsed =
|
|
2208
|
+
this.onePropParsed = onePropParsed;
|
|
2094
2209
|
node.realAfter = this.insertAfterAnchor('component-after');
|
|
2095
2210
|
return node;
|
|
2096
2211
|
}
|
|
@@ -2270,10 +2385,54 @@ class Interpreter {
|
|
|
2270
2385
|
hookI = _this$tokenizer$_hook4[2];
|
|
2271
2386
|
const rawVal = data[Keys.Raw][value];
|
|
2272
2387
|
const isFn = typeof rawVal === 'function';
|
|
2273
|
-
if (key === '
|
|
2388
|
+
if (key === 'props') {
|
|
2389
|
+
let prevKeys = new Set();
|
|
2390
|
+
const savedDefaults = new Map();
|
|
2391
|
+
new this.Effect(() => {
|
|
2392
|
+
const props = isFn ? rawVal : Reflect.has(data[Keys.Raw], value) ? data[value] : this.getFn(data, value)();
|
|
2393
|
+
const isComponent = _node.__logicType & TokenizerSwitcherBit;
|
|
2394
|
+
const rawTarget = isComponent ? _node.data[Keys.Raw] : null;
|
|
2395
|
+
const cleanupKeys = keysToClean => {
|
|
2396
|
+
for (const k of keysToClean) {
|
|
2397
|
+
if (k.startsWith('on')) continue;
|
|
2398
|
+
if (isComponent) {
|
|
2399
|
+
_node.data[k] = savedDefaults.has(k) ? savedDefaults.get(k) : undefined;
|
|
2400
|
+
} else {
|
|
2401
|
+
this.setProp(_node, k, undefined, hookI);
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
};
|
|
2405
|
+
if (!props || typeof props !== 'object') {
|
|
2406
|
+
cleanupKeys(prevKeys);
|
|
2407
|
+
prevKeys.clear();
|
|
2408
|
+
return;
|
|
2409
|
+
}
|
|
2410
|
+
props[Keys.Iterator];
|
|
2411
|
+
const raw = props[Keys.Raw] || props;
|
|
2412
|
+
const keys = Object.keys(raw);
|
|
2413
|
+
const newKeys = new Set();
|
|
2414
|
+
for (let i = 0; i < keys.length; i++) {
|
|
2415
|
+
const k = keys[i];
|
|
2416
|
+
newKeys.add(k);
|
|
2417
|
+
prevKeys.delete(k);
|
|
2418
|
+
if (isComponent) {
|
|
2419
|
+
const savedK = savedDefaults.has(k);
|
|
2420
|
+
if (!savedK && Object.prototype.hasOwnProperty.call(rawTarget, k)) {
|
|
2421
|
+
savedDefaults.set(k, rawTarget[k]);
|
|
2422
|
+
}
|
|
2423
|
+
const val = props[k];
|
|
2424
|
+
_node.data[k] = val === undefined && savedK ? savedDefaults.get(k) : val;
|
|
2425
|
+
} else {
|
|
2426
|
+
this.onePropParsed(props, _node, k, k, true, false, hookI);
|
|
2427
|
+
}
|
|
2428
|
+
}
|
|
2429
|
+
cleanupKeys(prevKeys);
|
|
2430
|
+
prevKeys = newKeys;
|
|
2431
|
+
}, ScheduleType.Render);
|
|
2432
|
+
} else if (key === 'ref') {
|
|
2274
2433
|
const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
|
|
2275
2434
|
let refValue = _node;
|
|
2276
|
-
if (_node.__logicType
|
|
2435
|
+
if (_node.__logicType & TokenizerSwitcherBit) {
|
|
2277
2436
|
refValue = _node.data;
|
|
2278
2437
|
} else {
|
|
2279
2438
|
refValue[Keys.ProxyFreeObject] = true;
|
|
@@ -2299,8 +2458,8 @@ class Interpreter {
|
|
|
2299
2458
|
} else {
|
|
2300
2459
|
this.onePropParsed(data, _node, key, value, false, isFn, hookI);
|
|
2301
2460
|
}
|
|
2302
|
-
key =
|
|
2303
|
-
eq =
|
|
2461
|
+
key = undefined;
|
|
2462
|
+
eq = undefined;
|
|
2304
2463
|
}
|
|
2305
2464
|
this.tokenizer.nextToken();
|
|
2306
2465
|
}
|
|
@@ -2388,15 +2547,6 @@ function createStoreOnePropParsed(child) {
|
|
|
2388
2547
|
};
|
|
2389
2548
|
return onePropParsed;
|
|
2390
2549
|
}
|
|
2391
|
-
class InlineFragment {
|
|
2392
|
-
[Keys.ProxyFreeObject] = true;
|
|
2393
|
-
constructor(snapshot, data, key, tokenizer) {
|
|
2394
|
-
this.snapshot = snapshot;
|
|
2395
|
-
this.data = data;
|
|
2396
|
-
this.key = key;
|
|
2397
|
-
this.tokenizer = tokenizer;
|
|
2398
|
-
}
|
|
2399
|
-
}
|
|
2400
2550
|
|
|
2401
2551
|
function bobe(fragments, ...values) {
|
|
2402
2552
|
const ui = function ui(isSub) {
|
|
@@ -2409,6 +2559,7 @@ function bobe(fragments, ...values) {
|
|
|
2409
2559
|
return tokenizer;
|
|
2410
2560
|
};
|
|
2411
2561
|
ui.boundStore = Store.Current;
|
|
2562
|
+
ui.__BOBE_IS_UI = true;
|
|
2412
2563
|
return ui;
|
|
2413
2564
|
}
|
|
2414
2565
|
function customRender(option) {
|