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/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
- export { Compiler, NodeType, ParseErrorCode, ParseSyntaxError, Tokenizer, bobe, customRender };
524
- export type { ASTNodeType, BaseNode, CommentNode, ComponentNode, ConditionalNode, DynamicValue, ElementNode, FragmentNode, InterpolationNode, LoopNode, ParseError, Program, Property, PropertyKeyNode, PropertyValue, SourceLocation, StaticValue, TemplateNode, TextNode };
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
- this.setProp(node, key, value, hookI);
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['ui'](true)
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 (hookType === 'dynamic') {
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['ui'](false);
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, {