bobe 0.0.42 → 0.0.44
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 +109 -31
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.compiler.cjs.js +109 -31
- package/dist/bobe.compiler.cjs.js.map +1 -1
- package/dist/bobe.compiler.esm.js +111 -34
- package/dist/bobe.compiler.esm.js.map +1 -1
- package/dist/bobe.esm.js +111 -34
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +19 -4
- package/dist/index.umd.js +109 -31
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ declare class Interpreter {
|
|
|
29
29
|
* <declaration> ::= <tagName=token> <headerLine> <extensionLines>
|
|
30
30
|
* */
|
|
31
31
|
declaration(ctx: ProgramCtx): any;
|
|
32
|
+
createContextNode(): ContextNode;
|
|
32
33
|
forDeclaration(): ForNode | ForItemNode;
|
|
33
34
|
insertForItem(forNode: ForNode, i: number, parentData: any, newChildren: ForItemNode[], before: any, snapshotForUpdate: any): void;
|
|
34
35
|
removeForItem(children: ForItemNode[], i: number): void;
|
|
@@ -49,6 +50,7 @@ declare class Interpreter {
|
|
|
49
50
|
oneRealPropParsed: Interpreter['onePropParsed'];
|
|
50
51
|
componentOrFragmentDeclaration(ComponentOrRender: BobeUI | typeof Store, ctx: ProgramCtx): ComponentNode$1;
|
|
51
52
|
getFn(data: any, expression: string | number): any;
|
|
53
|
+
getAssignFn(data: any, expression: string | number): any;
|
|
52
54
|
condDeclaration(ctx: ProgramCtx): IfNode;
|
|
53
55
|
removeLogicNode(node: LogicNode): void;
|
|
54
56
|
/**
|
|
@@ -89,7 +91,7 @@ declare class Interpreter {
|
|
|
89
91
|
defaultInsert(parent: any, node: any, prev: any): void;
|
|
90
92
|
remove(node: any, parent?: any, prev?: any): void;
|
|
91
93
|
defaultRemove(node: any, parent: any, prevSibling: any): void;
|
|
92
|
-
setProp(node: any, key: string, value: any, hookI?: number): void;
|
|
94
|
+
setProp(node: any, key: string, value: any, hookI?: number): void | undefined | (() => void);
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
interface StackNode<T> {
|
|
@@ -148,7 +150,8 @@ declare enum FakeType {
|
|
|
148
150
|
For = 8,
|
|
149
151
|
Component = 16,
|
|
150
152
|
Fragment = 32,
|
|
151
|
-
ForItem = 64
|
|
153
|
+
ForItem = 64,
|
|
154
|
+
Context = 128
|
|
152
155
|
}
|
|
153
156
|
type NodeSortBit = number;
|
|
154
157
|
type BaseType = string | number | boolean | undefined | null;
|
|
@@ -249,6 +252,7 @@ type ForItemNode = LogicNode & {
|
|
|
249
252
|
forNode: ForNode;
|
|
250
253
|
effect: Scope;
|
|
251
254
|
key?: any;
|
|
255
|
+
context: any;
|
|
252
256
|
};
|
|
253
257
|
type IfNode = LogicNode & {
|
|
254
258
|
condition: SignalNode;
|
|
@@ -257,6 +261,11 @@ type IfNode = LogicNode & {
|
|
|
257
261
|
effect: Effect;
|
|
258
262
|
preCond: IfNode | null;
|
|
259
263
|
owner: ComponentNode$1 | FragmentNode$1;
|
|
264
|
+
context: any;
|
|
265
|
+
};
|
|
266
|
+
/** data 是 map<storeKey, store> */
|
|
267
|
+
type ContextNode = Omit<LogicNode, 'data'> & {
|
|
268
|
+
context: any;
|
|
260
269
|
};
|
|
261
270
|
type FragmentNode$1 = LogicNode & {
|
|
262
271
|
tokenizer: Tokenizer;
|
|
@@ -520,5 +529,11 @@ type ParseHooks = Partial<{
|
|
|
520
529
|
declare function bobe(fragments: TemplateStringsArray, ...values: any[]): BobeUI;
|
|
521
530
|
declare function customRender(option: CustomRenderConf): <T>(Ctor: typeof Store, root: any) => (ComponentNode$1 | Store)[];
|
|
522
531
|
|
|
523
|
-
|
|
524
|
-
|
|
532
|
+
type IContext = {
|
|
533
|
+
<T = any>(name: string): T;
|
|
534
|
+
<T = any>(): T;
|
|
535
|
+
};
|
|
536
|
+
declare const context: IContext;
|
|
537
|
+
|
|
538
|
+
export { Compiler, NodeType, ParseErrorCode, ParseSyntaxError, Tokenizer, bobe, context, customRender };
|
|
539
|
+
export type { ASTNodeType, BaseNode, CommentNode, ComponentNode, ConditionalNode, DynamicValue, ElementNode, FragmentNode, IContext, InterpolationNode, LoopNode, ParseError, Program, Property, PropertyKeyNode, PropertyValue, SourceLocation, StaticValue, TemplateNode, TextNode };
|
package/dist/index.umd.js
CHANGED
|
@@ -33,11 +33,13 @@
|
|
|
33
33
|
FakeType[FakeType["Component"] = 16] = "Component";
|
|
34
34
|
FakeType[FakeType["Fragment"] = 32] = "Fragment";
|
|
35
35
|
FakeType[FakeType["ForItem"] = 64] = "ForItem";
|
|
36
|
+
FakeType[FakeType["Context"] = 128] = "Context";
|
|
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
41
|
FakeType.If | FakeType.Fail | FakeType.Else | FakeType.For | FakeType.ForItem | FakeType.Component | FakeType.Fragment;
|
|
42
|
+
const ContextBit = FakeType.If | FakeType.Fail | FakeType.Else | FakeType.ForItem | FakeType.Context;
|
|
41
43
|
const TokenizerSwitcherBit = FakeType.Component | FakeType.Fragment;
|
|
42
44
|
let NodeSort = function (NodeSort) {
|
|
43
45
|
NodeSort[NodeSort["Logic"] = 1] = "Logic";
|
|
@@ -45,6 +47,7 @@
|
|
|
45
47
|
NodeSort[NodeSort["Component"] = 4] = "Component";
|
|
46
48
|
NodeSort[NodeSort["CtxProvider"] = 8] = "CtxProvider";
|
|
47
49
|
NodeSort[NodeSort["TokenizerSwitcher"] = 16] = "TokenizerSwitcher";
|
|
50
|
+
NodeSort[NodeSort["Context"] = 32] = "Context";
|
|
48
51
|
return NodeSort;
|
|
49
52
|
}({});
|
|
50
53
|
(function (TerpEvt) {
|
|
@@ -1371,6 +1374,9 @@
|
|
|
1371
1374
|
}
|
|
1372
1375
|
|
|
1373
1376
|
const KEY_INDEX = '__BOBE_KEY_INDEX';
|
|
1377
|
+
let _ctxStack;
|
|
1378
|
+
const getCtxStack = () => _ctxStack;
|
|
1379
|
+
const setCtxStack = stack => _ctxStack = stack;
|
|
1374
1380
|
|
|
1375
1381
|
const _excluded = ["dentStack", "isFirstToken"];
|
|
1376
1382
|
class Interpreter {
|
|
@@ -1385,6 +1391,7 @@
|
|
|
1385
1391
|
this.rootComponent = componentNode;
|
|
1386
1392
|
this.tokenizer.nextToken();
|
|
1387
1393
|
const stack = new MultiTypeStack();
|
|
1394
|
+
setCtxStack(stack);
|
|
1388
1395
|
stack.push({
|
|
1389
1396
|
node: root,
|
|
1390
1397
|
prev: null
|
|
@@ -1421,7 +1428,7 @@
|
|
|
1421
1428
|
stack.push({
|
|
1422
1429
|
node: ctx.current,
|
|
1423
1430
|
prev: ctx.prevSibling
|
|
1424
|
-
}, !ctx.current.__logicType ? NodeSort.Real : (ctx.current.__logicType & LogicalBit ? NodeSort.Logic : 0) | (ctx.current.__logicType & TokenizerSwitcherBit ? NodeSort.TokenizerSwitcher : 0) | (ctx.current.__logicType === FakeType.Component ? NodeSort.Component : 0) | NodeSort.CtxProvider);
|
|
1431
|
+
}, !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));
|
|
1425
1432
|
if (ctx.current.__logicType) {
|
|
1426
1433
|
if (isLogicNode) {
|
|
1427
1434
|
aoye.setPulling(ctx.current.effect);
|
|
@@ -1545,6 +1552,8 @@
|
|
|
1545
1552
|
let _node;
|
|
1546
1553
|
if (value === 'if' || value === 'else' || value === 'fail') {
|
|
1547
1554
|
return this.condDeclaration(ctx);
|
|
1555
|
+
} else if (value === 'context') {
|
|
1556
|
+
_node = this.createContextNode();
|
|
1548
1557
|
} else if (value === 'for') {
|
|
1549
1558
|
return this.forDeclaration();
|
|
1550
1559
|
} else if (hookType) {
|
|
@@ -1572,12 +1581,29 @@
|
|
|
1572
1581
|
this.tokenizer.nextToken();
|
|
1573
1582
|
this.headerLine(_node);
|
|
1574
1583
|
this.extensionLines(_node);
|
|
1584
|
+
this.onePropParsed = this.oneRealPropParsed;
|
|
1575
1585
|
if (_node.__logicType & TokenizerSwitcherBit) {
|
|
1576
|
-
this.onePropParsed = this.oneRealPropParsed;
|
|
1577
1586
|
this.tokenizer = _node.tokenizer;
|
|
1578
1587
|
}
|
|
1579
1588
|
return _node;
|
|
1580
1589
|
}
|
|
1590
|
+
createContextNode() {
|
|
1591
|
+
const child = aoye.deepSignal({}, aoye.getPulling());
|
|
1592
|
+
const parentContext = this.ctx.stack.peekByType(NodeSort.Context)?.node?.context;
|
|
1593
|
+
if (parentContext) {
|
|
1594
|
+
Object.setPrototypeOf(child, parentContext);
|
|
1595
|
+
}
|
|
1596
|
+
this.onePropParsed = createStoreOnePropParsed(child);
|
|
1597
|
+
const node = {
|
|
1598
|
+
__logicType: FakeType.Context,
|
|
1599
|
+
context: child,
|
|
1600
|
+
realParent: null,
|
|
1601
|
+
realBefore: null,
|
|
1602
|
+
realAfter: null
|
|
1603
|
+
};
|
|
1604
|
+
node.realAfter = this.insertAfterAnchor('context-after');
|
|
1605
|
+
return node;
|
|
1606
|
+
}
|
|
1581
1607
|
forDeclaration() {
|
|
1582
1608
|
const arrExp = this.tokenizer.jsExp().value;
|
|
1583
1609
|
this.tokenizer.nextToken();
|
|
@@ -1857,6 +1883,7 @@
|
|
|
1857
1883
|
scope.get();
|
|
1858
1884
|
}, null);
|
|
1859
1885
|
data = this.getItemData(forNode, i, parentData);
|
|
1886
|
+
const context = this.ctx.stack.peekByType(NodeSort.Context)?.node?.data;
|
|
1860
1887
|
forItemNode = {
|
|
1861
1888
|
id: this.forItemId++,
|
|
1862
1889
|
__logicType: FakeType.ForItem,
|
|
@@ -1866,7 +1893,8 @@
|
|
|
1866
1893
|
forNode,
|
|
1867
1894
|
key: forNode.getKey?.(data),
|
|
1868
1895
|
effect: null,
|
|
1869
|
-
data
|
|
1896
|
+
data,
|
|
1897
|
+
context
|
|
1870
1898
|
};
|
|
1871
1899
|
forItemNode.effect = scope;
|
|
1872
1900
|
return forItemNode;
|
|
@@ -1910,16 +1938,20 @@
|
|
|
1910
1938
|
}
|
|
1911
1939
|
onePropParsed(data, node, key, value, valueIsMapKey, isFn, hookI) {
|
|
1912
1940
|
if (isFn) {
|
|
1913
|
-
|
|
1941
|
+
new aoye.Scope(() => {
|
|
1942
|
+
return this.setProp(node, key, value, hookI);
|
|
1943
|
+
}).get();
|
|
1914
1944
|
} else if (typeof value === 'function') {
|
|
1915
1945
|
new aoye.Effect(() => {
|
|
1916
|
-
const res = value();
|
|
1917
|
-
this.setProp(node, key, res, hookI);
|
|
1946
|
+
const res = value(data);
|
|
1947
|
+
const dispose = this.setProp(node, key, res, hookI);
|
|
1948
|
+
return dispose;
|
|
1918
1949
|
});
|
|
1919
1950
|
} else if (valueIsMapKey) {
|
|
1920
1951
|
new aoye.Effect(() => {
|
|
1921
1952
|
const res = data[value];
|
|
1922
|
-
this.setProp(node, key, res, hookI);
|
|
1953
|
+
const dispose = this.setProp(node, key, res, hookI);
|
|
1954
|
+
return dispose;
|
|
1923
1955
|
});
|
|
1924
1956
|
} else {
|
|
1925
1957
|
this.setProp(node, key, value, hookI);
|
|
@@ -1944,34 +1976,19 @@
|
|
|
1944
1976
|
realBefore: null,
|
|
1945
1977
|
realAfter: null,
|
|
1946
1978
|
data: child,
|
|
1947
|
-
tokenizer: render ? render(true) : child
|
|
1948
|
-
};
|
|
1949
|
-
this.onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
|
|
1950
|
-
if (isFn) {
|
|
1951
|
-
child[aoye.Keys.Raw][key] = value;
|
|
1952
|
-
} else if (valueIsMapKey) {
|
|
1953
|
-
aoye.shareSignal(data, value, child, key);
|
|
1954
|
-
} else {
|
|
1955
|
-
const meta = child[aoye.Keys.Meta];
|
|
1956
|
-
const cells = meta.cells;
|
|
1957
|
-
if (typeof value === 'function') {
|
|
1958
|
-
const computed = new aoye.Computed(value);
|
|
1959
|
-
cells.set(key, computed);
|
|
1960
|
-
child[aoye.Keys.Raw][key] = undefined;
|
|
1961
|
-
} else {
|
|
1962
|
-
cells.set(key, {
|
|
1963
|
-
get: () => value
|
|
1964
|
-
});
|
|
1965
|
-
child[aoye.Keys.Raw][key] = value;
|
|
1966
|
-
}
|
|
1967
|
-
}
|
|
1979
|
+
tokenizer: render ? render(true) : child.ui(true)
|
|
1968
1980
|
};
|
|
1981
|
+
this.onePropParsed = createStoreOnePropParsed(child);
|
|
1969
1982
|
node.realAfter = this.insertAfterAnchor('component-after');
|
|
1970
1983
|
return node;
|
|
1971
1984
|
}
|
|
1972
1985
|
getFn(data, expression) {
|
|
1973
1986
|
return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
|
|
1974
1987
|
}
|
|
1988
|
+
getAssignFn(data, expression) {
|
|
1989
|
+
const valueId = `value_bobe_${bobeShared.date32()}`;
|
|
1990
|
+
return new Function('data', valueId, `with(data){${expression}=${valueId}};`).bind(undefined, data);
|
|
1991
|
+
}
|
|
1975
1992
|
condDeclaration(ctx) {
|
|
1976
1993
|
const prevSibling = ctx.prevSibling;
|
|
1977
1994
|
const keyWord = this.tokenizer.token;
|
|
@@ -1984,6 +2001,7 @@
|
|
|
1984
2001
|
const noCond = value === true;
|
|
1985
2002
|
const valueIsMapKey = !noCond && Reflect.has(data[aoye.Keys.Raw], value);
|
|
1986
2003
|
const owner = ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
|
|
2004
|
+
const context = ctx.stack.peekByType(NodeSort.Context)?.node?.data;
|
|
1987
2005
|
const ifNode = {
|
|
1988
2006
|
__logicType: isElse ? FakeType.Else : isIf ? FakeType.If : FakeType.Fail,
|
|
1989
2007
|
snapshot: this.tokenizer.snapshot(),
|
|
@@ -1995,7 +2013,8 @@
|
|
|
1995
2013
|
isFirstRender: true,
|
|
1996
2014
|
effect: null,
|
|
1997
2015
|
owner,
|
|
1998
|
-
data
|
|
2016
|
+
data,
|
|
2017
|
+
context
|
|
1999
2018
|
};
|
|
2000
2019
|
let signal;
|
|
2001
2020
|
switch (keyWord.value) {
|
|
@@ -2125,7 +2144,27 @@
|
|
|
2125
2144
|
hookI = _this$tokenizer$_hook4[2];
|
|
2126
2145
|
const rawVal = data[aoye.Keys.Raw][value];
|
|
2127
2146
|
const isFn = typeof rawVal === 'function';
|
|
2128
|
-
if (
|
|
2147
|
+
if (key === 'ref') {
|
|
2148
|
+
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
2149
|
+
let refValue = _node;
|
|
2150
|
+
if (_node.__logicType === FakeType.Component) {
|
|
2151
|
+
refValue = _node.data;
|
|
2152
|
+
} else {
|
|
2153
|
+
refValue[aoye.Keys.ProxyFreeObject] = true;
|
|
2154
|
+
}
|
|
2155
|
+
if (valueIsMapKey) {
|
|
2156
|
+
data[value] = refValue;
|
|
2157
|
+
new aoye.Scope(() => () => {
|
|
2158
|
+
data[value] = null;
|
|
2159
|
+
}).get();
|
|
2160
|
+
} else {
|
|
2161
|
+
const fn = this.getAssignFn(data, value);
|
|
2162
|
+
fn(refValue);
|
|
2163
|
+
new aoye.Scope(() => () => {
|
|
2164
|
+
fn(null);
|
|
2165
|
+
}).get();
|
|
2166
|
+
}
|
|
2167
|
+
} else if (hookType === 'dynamic') {
|
|
2129
2168
|
const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
|
|
2130
2169
|
const fn = isFn ? rawVal : valueIsMapKey ? value : this.getFn(data, value);
|
|
2131
2170
|
this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
|
|
@@ -2193,6 +2232,29 @@
|
|
|
2193
2232
|
node.props[key] = value;
|
|
2194
2233
|
}
|
|
2195
2234
|
}
|
|
2235
|
+
function createStoreOnePropParsed(child) {
|
|
2236
|
+
const onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
|
|
2237
|
+
if (isFn) {
|
|
2238
|
+
child[aoye.Keys.Raw][key] = value;
|
|
2239
|
+
} else if (valueIsMapKey) {
|
|
2240
|
+
aoye.shareSignal(data, value, child, key);
|
|
2241
|
+
} else {
|
|
2242
|
+
const meta = child[aoye.Keys.Meta];
|
|
2243
|
+
const cells = meta.cells;
|
|
2244
|
+
if (typeof value === 'function') {
|
|
2245
|
+
const computed = new aoye.Computed(() => value(data));
|
|
2246
|
+
cells.set(key, computed);
|
|
2247
|
+
child[aoye.Keys.Raw][key] = undefined;
|
|
2248
|
+
} else {
|
|
2249
|
+
cells.set(key, {
|
|
2250
|
+
get: () => value
|
|
2251
|
+
});
|
|
2252
|
+
child[aoye.Keys.Raw][key] = value;
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
};
|
|
2256
|
+
return onePropParsed;
|
|
2257
|
+
}
|
|
2196
2258
|
|
|
2197
2259
|
function bobe(fragments, ...values) {
|
|
2198
2260
|
const ui = function ui(isSub) {
|
|
@@ -2210,7 +2272,7 @@
|
|
|
2210
2272
|
function customRender(option) {
|
|
2211
2273
|
return function render(Ctor, root) {
|
|
2212
2274
|
const store = Ctor.new();
|
|
2213
|
-
const tokenizer = store
|
|
2275
|
+
const tokenizer = store.ui(false);
|
|
2214
2276
|
const terp = new Interpreter(tokenizer);
|
|
2215
2277
|
terp.config(option);
|
|
2216
2278
|
const componentNode = {
|
|
@@ -2224,11 +2286,27 @@
|
|
|
2224
2286
|
};
|
|
2225
2287
|
}
|
|
2226
2288
|
|
|
2289
|
+
const context = name => {
|
|
2290
|
+
const stack = getCtxStack();
|
|
2291
|
+
if (!stack) {
|
|
2292
|
+
throw new Error('context() api 只能在组件中使用');
|
|
2293
|
+
}
|
|
2294
|
+
let context = stack.peekByType(NodeSort.Context)?.node?.context;
|
|
2295
|
+
if (name) {
|
|
2296
|
+
context = context?.[name];
|
|
2297
|
+
}
|
|
2298
|
+
if (!context) {
|
|
2299
|
+
console.warn(`context(${name ?? ''}) 为空`);
|
|
2300
|
+
}
|
|
2301
|
+
return context;
|
|
2302
|
+
};
|
|
2303
|
+
|
|
2227
2304
|
exports.Compiler = Compiler;
|
|
2228
2305
|
exports.NodeType = NodeType;
|
|
2229
2306
|
exports.ParseSyntaxError = ParseSyntaxError;
|
|
2230
2307
|
exports.Tokenizer = Tokenizer;
|
|
2231
2308
|
exports.bobe = bobe;
|
|
2309
|
+
exports.context = context;
|
|
2232
2310
|
exports.customRender = customRender;
|
|
2233
2311
|
Object.keys(aoye).forEach(function (k) {
|
|
2234
2312
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|