bobe 0.0.73 → 0.0.75
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 +135 -8
- package/dist/bobe.cjs.map +1 -1
- package/dist/bobe.compiler.cjs +135 -8
- package/dist/bobe.compiler.cjs.map +1 -1
- package/dist/bobe.compiler.esm.js +135 -9
- package/dist/bobe.compiler.esm.js.map +1 -1
- package/dist/bobe.esm.js +135 -9
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +19 -3
- package/dist/index.umd.js +135 -8
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -70,9 +70,11 @@ declare class Interpreter {
|
|
|
70
70
|
private createComponentData;
|
|
71
71
|
componentOrFragmentDeclaration(ComponentOrRender: UI | typeof Store | InlineFragment, ctx: ProgramCtx): ComponentNode$1;
|
|
72
72
|
getFn(data: any, expression: string | number): any;
|
|
73
|
+
getBoolFn(data: any, expression: string | number): any;
|
|
73
74
|
getAssignFn(data: any, expression: string | number): any;
|
|
74
75
|
condDeclaration(ctx: ProgramCtx): IfNode;
|
|
75
76
|
removeLogicNode(node: LogicNode): void;
|
|
77
|
+
private skipComponentTypeArguments;
|
|
76
78
|
/**
|
|
77
79
|
* 首行属性 + 可选的 pipe 扩展行
|
|
78
80
|
* <headerLineAndExtensions> ::= <attributeList> NEWLINE (PIPE <attributeList> NEWLINE)*
|
|
@@ -178,7 +180,8 @@ declare enum TokenType {
|
|
|
178
180
|
Boolean = 4096,
|
|
179
181
|
Null = 8192,
|
|
180
182
|
Undefined = 16384,
|
|
181
|
-
Comment = 32768
|
|
183
|
+
Comment = 32768,
|
|
184
|
+
TypeArguments = 65536
|
|
182
185
|
}
|
|
183
186
|
declare enum FakeType {
|
|
184
187
|
If = 1,
|
|
@@ -209,6 +212,10 @@ type Token = {
|
|
|
209
212
|
typeName: string;
|
|
210
213
|
value: BaseType;
|
|
211
214
|
loc: SourceLocation;
|
|
215
|
+
typeArguments?: {
|
|
216
|
+
raw: string;
|
|
217
|
+
loc: SourceLocation;
|
|
218
|
+
}[];
|
|
212
219
|
};
|
|
213
220
|
type HookProps = {
|
|
214
221
|
/** 通过哪个 HookId 进入的 */
|
|
@@ -247,7 +254,8 @@ declare enum ParseErrorCode {
|
|
|
247
254
|
MISSING_FOR_ITEM = 9014,
|
|
248
255
|
MISSING_COMMENT_SECOND_SLASH = 9015,
|
|
249
256
|
MISSING_PROP_ASSIGNMENT = 9016,
|
|
250
|
-
PIPE_IN_WRONG_CONTEXT = 9017
|
|
257
|
+
PIPE_IN_WRONG_CONTEXT = 9017,
|
|
258
|
+
UNCLOSED_TYPE_ARGUMENTS = 9018
|
|
251
259
|
}
|
|
252
260
|
type ParseError = {
|
|
253
261
|
code: ParseErrorCode;
|
|
@@ -434,6 +442,7 @@ declare class Tokenizer {
|
|
|
434
442
|
* @returns {boolean} 是否含有 key
|
|
435
443
|
*/
|
|
436
444
|
jsExp(): Token;
|
|
445
|
+
private typeArguments;
|
|
437
446
|
peekChar(): string;
|
|
438
447
|
peekCharIsEol(): boolean;
|
|
439
448
|
charIsEol(char: string): char is "/" | "\n";
|
|
@@ -538,9 +547,15 @@ interface LoopNode extends BaseNode {
|
|
|
538
547
|
key?: PropertyValue;
|
|
539
548
|
children: TemplateNode[];
|
|
540
549
|
}
|
|
550
|
+
interface TypeArgumentNode extends BaseNode {
|
|
551
|
+
type: NodeType.StaticValue;
|
|
552
|
+
raw: string;
|
|
553
|
+
}
|
|
541
554
|
interface ComponentNode extends BaseNode {
|
|
542
555
|
type: NodeType.Component;
|
|
543
556
|
componentName: PropertyValue;
|
|
557
|
+
typeArguments?: TypeArgumentNode[];
|
|
558
|
+
typeArgumentsLoc?: SourceLocation;
|
|
544
559
|
props: Property[];
|
|
545
560
|
children?: TemplateNode[];
|
|
546
561
|
}
|
|
@@ -618,6 +633,7 @@ type ParseHooks = Partial<{
|
|
|
618
633
|
[K in keyof ParseProps]: {
|
|
619
634
|
enter?: (this: Compiler, ...args: Parameters<ParseProps[K]>) => void;
|
|
620
635
|
leave?: (this: Compiler, ...args: Parameters<ParseProps[K]>) => void;
|
|
636
|
+
nameAdded?: (this: Compiler, ...args: Parameters<ParseProps[K]>) => void;
|
|
621
637
|
propsAdded?: (this: Compiler, ...args: Parameters<ParseProps[K]>) => void;
|
|
622
638
|
};
|
|
623
639
|
}>;
|
|
@@ -631,4 +647,4 @@ declare const context: IContext;
|
|
|
631
647
|
declare const effect: (callback: (...args: ValueDiff[]) => void, depOrOpt?: Dep[] | Dep | CustomEffectOpt, opt?: CustomEffectOpt) => aoye.Effect;
|
|
632
648
|
|
|
633
649
|
export { Compiler, FakeType, Interpreter, Mw, MwCtx, NodeType, ParseErrorCode, ParseSyntaxError, Tokenizer, bobe, context, customRender, effect };
|
|
634
|
-
export type { ASTNodeType, BaseNode, CommentNode, ComponentNode, ConditionalNode, DynamicValue, ElementNode, FragmentNode, IContext, InterpolationNode, LogicNode, LoopNode, ParseError, Program, Property, PropertyKeyNode, PropertyValue, SourceLocation, StaticValue, TemplateNode, TextNode, UI };
|
|
650
|
+
export type { ASTNodeType, BaseNode, CommentNode, ComponentNode, ConditionalNode, DynamicValue, ElementNode, FragmentNode, IContext, InterpolationNode, LogicNode, LoopNode, ParseError, Program, Property, PropertyKeyNode, PropertyValue, SourceLocation, StaticValue, TemplateNode, TextNode, TypeArgumentNode, UI };
|
package/dist/index.umd.js
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
TokenType[TokenType["Null"] = 8192] = "Null";
|
|
22
22
|
TokenType[TokenType["Undefined"] = 16384] = "Undefined";
|
|
23
23
|
TokenType[TokenType["Comment"] = 32768] = "Comment";
|
|
24
|
+
TokenType[TokenType["TypeArguments"] = 65536] = "TypeArguments";
|
|
24
25
|
return TokenType;
|
|
25
26
|
}({});
|
|
26
27
|
const ChildrenSugarType = TokenType.String | TokenType.InsertionExp;
|
|
@@ -76,6 +77,7 @@
|
|
|
76
77
|
ParseErrorCode[ParseErrorCode["MISSING_COMMENT_SECOND_SLASH"] = 9015] = "MISSING_COMMENT_SECOND_SLASH";
|
|
77
78
|
ParseErrorCode[ParseErrorCode["MISSING_PROP_ASSIGNMENT"] = 9016] = "MISSING_PROP_ASSIGNMENT";
|
|
78
79
|
ParseErrorCode[ParseErrorCode["PIPE_IN_WRONG_CONTEXT"] = 9017] = "PIPE_IN_WRONG_CONTEXT";
|
|
80
|
+
ParseErrorCode[ParseErrorCode["UNCLOSED_TYPE_ARGUMENTS"] = 9018] = "UNCLOSED_TYPE_ARGUMENTS";
|
|
79
81
|
return ParseErrorCode;
|
|
80
82
|
}({});
|
|
81
83
|
class ParseSyntaxError extends SyntaxError {
|
|
@@ -249,12 +251,13 @@
|
|
|
249
251
|
if (!this.token) return false;
|
|
250
252
|
return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
|
|
251
253
|
}
|
|
252
|
-
setToken(type, value, dt = 1) {
|
|
254
|
+
setToken(type, value, dt = 1, extra) {
|
|
253
255
|
this.token = {
|
|
254
256
|
type,
|
|
255
257
|
typeName: TokenType[type],
|
|
256
258
|
value,
|
|
257
|
-
loc: null
|
|
259
|
+
loc: null,
|
|
260
|
+
...extra
|
|
258
261
|
};
|
|
259
262
|
this.isFirstToken = false;
|
|
260
263
|
}
|
|
@@ -308,6 +311,9 @@
|
|
|
308
311
|
const braceToken = this.brace();
|
|
309
312
|
this.setToken(TokenType.InsertionExp, braceToken);
|
|
310
313
|
break;
|
|
314
|
+
case '<':
|
|
315
|
+
this.typeArguments();
|
|
316
|
+
break;
|
|
311
317
|
case '$':
|
|
312
318
|
const handled = this.staticIns();
|
|
313
319
|
if (handled) break;
|
|
@@ -396,6 +402,104 @@
|
|
|
396
402
|
this.locEnd();
|
|
397
403
|
return this.token;
|
|
398
404
|
}
|
|
405
|
+
typeArguments() {
|
|
406
|
+
const startOffset = this.i;
|
|
407
|
+
const startLine = this.line;
|
|
408
|
+
const startColumn = this.column;
|
|
409
|
+
let angleDepth = 0;
|
|
410
|
+
let braceDepth = 0;
|
|
411
|
+
let bracketDepth = 0;
|
|
412
|
+
let parenDepth = 0;
|
|
413
|
+
let current = '';
|
|
414
|
+
const args = [];
|
|
415
|
+
let argStart = this.i + 1;
|
|
416
|
+
const makeLoc = (start, end) => ({
|
|
417
|
+
start: {
|
|
418
|
+
offset: start,
|
|
419
|
+
line: startLine,
|
|
420
|
+
column: startColumn + (start - startOffset)
|
|
421
|
+
},
|
|
422
|
+
end: {
|
|
423
|
+
offset: end,
|
|
424
|
+
line: startLine,
|
|
425
|
+
column: startColumn + (end - startOffset)
|
|
426
|
+
},
|
|
427
|
+
source: this.code.slice(start, end)
|
|
428
|
+
});
|
|
429
|
+
const pushArg = end => {
|
|
430
|
+
const raw = current.trim();
|
|
431
|
+
if (!raw) return;
|
|
432
|
+
const leading = current.length - current.trimStart().length;
|
|
433
|
+
const trailingEnd = current.trimEnd().length;
|
|
434
|
+
args.push({
|
|
435
|
+
raw,
|
|
436
|
+
loc: makeLoc(argStart + leading, argStart + trailingEnd)
|
|
437
|
+
});
|
|
438
|
+
};
|
|
439
|
+
while (true) {
|
|
440
|
+
const char = this.code[this.i];
|
|
441
|
+
if (char === undefined || char === '\n') {
|
|
442
|
+
throw new ParseSyntaxError(ParseErrorCode.UNCLOSED_TYPE_ARGUMENTS, '未闭合的组件泛型参数', makeLoc(startOffset, this.i));
|
|
443
|
+
}
|
|
444
|
+
if (char === '\'' || char === '"' || char === '`') {
|
|
445
|
+
const quote = char;
|
|
446
|
+
current += char;
|
|
447
|
+
this.next();
|
|
448
|
+
while (true) {
|
|
449
|
+
const inner = this.code[this.i];
|
|
450
|
+
if (inner === undefined || inner === '\n') {
|
|
451
|
+
throw new ParseSyntaxError(ParseErrorCode.UNCLOSED_TYPE_ARGUMENTS, '未闭合的组件泛型参数', makeLoc(startOffset, this.i));
|
|
452
|
+
}
|
|
453
|
+
current += inner;
|
|
454
|
+
if (inner === '\\') {
|
|
455
|
+
this.next();
|
|
456
|
+
current += this.code[this.i] ?? '';
|
|
457
|
+
} else if (inner === quote) {
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
460
|
+
this.next();
|
|
461
|
+
}
|
|
462
|
+
} else if (char === '<') {
|
|
463
|
+
angleDepth++;
|
|
464
|
+
if (angleDepth > 1) current += char;
|
|
465
|
+
} else if (char === '>' && this.code[this.i - 1] !== '=') {
|
|
466
|
+
angleDepth--;
|
|
467
|
+
if (angleDepth === 0) {
|
|
468
|
+
pushArg(this.i);
|
|
469
|
+
this.setToken(TokenType.TypeArguments, this.code.slice(startOffset + 1, this.i), 1, {
|
|
470
|
+
typeArguments: args
|
|
471
|
+
});
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
current += char;
|
|
475
|
+
} else if (char === '{') {
|
|
476
|
+
braceDepth++;
|
|
477
|
+
current += char;
|
|
478
|
+
} else if (char === '}') {
|
|
479
|
+
braceDepth = Math.max(0, braceDepth - 1);
|
|
480
|
+
current += char;
|
|
481
|
+
} else if (char === '[') {
|
|
482
|
+
bracketDepth++;
|
|
483
|
+
current += char;
|
|
484
|
+
} else if (char === ']') {
|
|
485
|
+
bracketDepth = Math.max(0, bracketDepth - 1);
|
|
486
|
+
current += char;
|
|
487
|
+
} else if (char === '(') {
|
|
488
|
+
parenDepth++;
|
|
489
|
+
current += char;
|
|
490
|
+
} else if (char === ')') {
|
|
491
|
+
parenDepth = Math.max(0, parenDepth - 1);
|
|
492
|
+
current += char;
|
|
493
|
+
} else if (char === ',' && angleDepth === 1 && braceDepth === 0 && bracketDepth === 0 && parenDepth === 0) {
|
|
494
|
+
pushArg(this.i);
|
|
495
|
+
current = '';
|
|
496
|
+
argStart = this.i + 1;
|
|
497
|
+
} else {
|
|
498
|
+
current += char;
|
|
499
|
+
}
|
|
500
|
+
this.next();
|
|
501
|
+
}
|
|
502
|
+
}
|
|
399
503
|
peekChar() {
|
|
400
504
|
let i = this.i;
|
|
401
505
|
while (this.code[i] === ' ' || this.code[i] === '\t') {
|
|
@@ -1107,8 +1211,19 @@
|
|
|
1107
1211
|
parseComponentNode(node) {
|
|
1108
1212
|
const name = this.parseName();
|
|
1109
1213
|
this.tokenizer.nextToken();
|
|
1214
|
+
const typeArgumentsToken = this.tokenizer.token.type & TokenType.TypeArguments ? this.tokenizer.token : undefined;
|
|
1215
|
+
if (typeArgumentsToken) {
|
|
1216
|
+
this.tokenizer.nextToken();
|
|
1217
|
+
}
|
|
1110
1218
|
node.type = NodeType.Component;
|
|
1111
1219
|
node.componentName = name;
|
|
1220
|
+
node.typeArguments = typeArgumentsToken?.typeArguments?.map(arg => ({
|
|
1221
|
+
type: NodeType.StaticValue,
|
|
1222
|
+
raw: arg.raw,
|
|
1223
|
+
loc: arg.loc
|
|
1224
|
+
}));
|
|
1225
|
+
node.typeArgumentsLoc = typeArgumentsToken?.loc;
|
|
1226
|
+
this.hooks.parseComponentNode?.nameAdded?.call(this, node);
|
|
1112
1227
|
const props = this.headerLineAndExtensions();
|
|
1113
1228
|
node.props = props;
|
|
1114
1229
|
this.hooks.parseComponentNode?.propsAdded?.call(this, node);
|
|
@@ -1696,6 +1811,7 @@
|
|
|
1696
1811
|
_node = this.createNode(value);
|
|
1697
1812
|
}
|
|
1698
1813
|
this.tokenizer.nextToken();
|
|
1814
|
+
this.skipComponentTypeArguments(_node);
|
|
1699
1815
|
this.headerLineAndExtensions(_node);
|
|
1700
1816
|
this.onePropParsed = this.oneRealPropParsed;
|
|
1701
1817
|
if (_node.__logicType & TokenizerSwitcherBit) {
|
|
@@ -1749,6 +1865,7 @@
|
|
|
1749
1865
|
}, NodeSort.CtxProvider);
|
|
1750
1866
|
}
|
|
1751
1867
|
this.tokenizer.nextToken();
|
|
1868
|
+
this.skipComponentTypeArguments(node);
|
|
1752
1869
|
this.headerLineAndExtensions(node);
|
|
1753
1870
|
if (isUpdate) {
|
|
1754
1871
|
this.ctx.stack.pop();
|
|
@@ -1778,6 +1895,7 @@
|
|
|
1778
1895
|
this.handleInsert(node.realParent, textNode, node.realBefore);
|
|
1779
1896
|
} else {
|
|
1780
1897
|
this.tokenizer.nextToken();
|
|
1898
|
+
this.skipComponentTypeArguments(node, true);
|
|
1781
1899
|
this.headerLineAndExtensions(node);
|
|
1782
1900
|
const _this$ctx2 = this.ctx,
|
|
1783
1901
|
realParent = _this$ctx2.realParent,
|
|
@@ -2383,6 +2501,11 @@
|
|
|
2383
2501
|
getFn(data, expression) {
|
|
2384
2502
|
return new Function('data', `with(data){return (${expression})}`).bind(undefined, safe(data));
|
|
2385
2503
|
}
|
|
2504
|
+
getBoolFn(data, expression) {
|
|
2505
|
+
return new Function('data', `with(data){return Boolean(${expression})}`).bind(undefined, safeExclude(data, {
|
|
2506
|
+
'Boolean': true
|
|
2507
|
+
}));
|
|
2508
|
+
}
|
|
2386
2509
|
getAssignFn(data, expression) {
|
|
2387
2510
|
const valueId = `value_bobe_${bobeShared.date32()}`;
|
|
2388
2511
|
return new Function('data', valueId, `with(data){${expression}=${valueId}};`).bind(undefined, safeExclude(data, {
|
|
@@ -2420,11 +2543,9 @@
|
|
|
2420
2543
|
switch (keyWord.value) {
|
|
2421
2544
|
case 'if':
|
|
2422
2545
|
if (valueIsMapKey) {
|
|
2423
|
-
aoye.
|
|
2424
|
-
const cells = data[aoye.Keys.Meta].cells;
|
|
2425
|
-
signal = cells.get(value);
|
|
2546
|
+
signal = new aoye.Computed(() => Boolean(data[value]));
|
|
2426
2547
|
} else {
|
|
2427
|
-
const fn = this.
|
|
2548
|
+
const fn = this.getBoolFn(data, value);
|
|
2428
2549
|
signal = new aoye.Computed(fn);
|
|
2429
2550
|
}
|
|
2430
2551
|
break;
|
|
@@ -2444,7 +2565,7 @@
|
|
|
2444
2565
|
return true;
|
|
2445
2566
|
});
|
|
2446
2567
|
} else {
|
|
2447
|
-
const fn = valueIsMapKey ? null : this.
|
|
2568
|
+
const fn = valueIsMapKey ? null : this.getBoolFn(data, value);
|
|
2448
2569
|
signal = new aoye.Computed(() => {
|
|
2449
2570
|
let point = ifNode.preCond;
|
|
2450
2571
|
while (point) {
|
|
@@ -2456,7 +2577,7 @@
|
|
|
2456
2577
|
}
|
|
2457
2578
|
point = point.preCond;
|
|
2458
2579
|
}
|
|
2459
|
-
return valueIsMapKey ? data[value] : fn();
|
|
2580
|
+
return valueIsMapKey ? Boolean(data[value]) : fn();
|
|
2460
2581
|
});
|
|
2461
2582
|
}
|
|
2462
2583
|
break;
|
|
@@ -2513,6 +2634,11 @@
|
|
|
2513
2634
|
point = next;
|
|
2514
2635
|
}
|
|
2515
2636
|
}
|
|
2637
|
+
skipComponentTypeArguments(node, force = false) {
|
|
2638
|
+
if ((force || node.__logicType & TokenizerSwitcherBit) && this.tokenizer.token.type & TokenType.TypeArguments) {
|
|
2639
|
+
this.tokenizer.nextToken();
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2516
2642
|
headerLineAndExtensions(_node) {
|
|
2517
2643
|
const tokenizer = this.tokenizer;
|
|
2518
2644
|
do {
|
|
@@ -2872,6 +2998,7 @@
|
|
|
2872
2998
|
exports.Mw = Mw;
|
|
2873
2999
|
exports.MwCtx = MwCtx;
|
|
2874
3000
|
exports.NodeType = NodeType;
|
|
3001
|
+
exports.ParseErrorCode = ParseErrorCode;
|
|
2875
3002
|
exports.ParseSyntaxError = ParseSyntaxError;
|
|
2876
3003
|
exports.Tokenizer = Tokenizer;
|
|
2877
3004
|
exports.bobe = bobe;
|