bobe 0.0.16 → 0.0.17
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 +81 -92
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +82 -93
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +2 -19
- package/dist/index.umd.js +81 -92
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/bobe.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getPulling, setPulling, Store, Keys, effect, shareSignal, $, runWithPulling } from 'aoye';
|
|
2
2
|
export * from 'aoye';
|
|
3
|
-
import { BaseEvent, Queue, isNum } from 'bobe-shared';
|
|
3
|
+
import { BaseEvent, Queue, isNum, matchIdStart } from 'bobe-shared';
|
|
4
4
|
|
|
5
5
|
var TokenType = /* @__PURE__ */ ((TokenType2) => {
|
|
6
6
|
TokenType2[TokenType2["NewLine"] = 1] = "NewLine";
|
|
@@ -108,30 +108,34 @@ class MultiTypeStack {
|
|
|
108
108
|
var _a;
|
|
109
109
|
return (_a = this.top) == null ? void 0 : _a.value;
|
|
110
110
|
}
|
|
111
|
-
/**
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
forEach(callback) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
111
|
+
// /**
|
|
112
|
+
// * 1. 全局向前遍历 (不分类)
|
|
113
|
+
// * 从栈顶开始,沿着全局链条向栈底遍历
|
|
114
|
+
// */
|
|
115
|
+
// forEach(callback: (value: T, types: number) => any): void {
|
|
116
|
+
// let current = this.top;
|
|
117
|
+
// while (current !== null) {
|
|
118
|
+
// // 执行回调,如果返回 false 则立即停止
|
|
119
|
+
// const shouldBreak = callback(current.value, current.types);
|
|
120
|
+
// if (shouldBreak) break;
|
|
121
|
+
// current = current.prevGlobal;
|
|
122
|
+
// }
|
|
123
|
+
// }
|
|
124
|
+
// /**
|
|
125
|
+
// * 2. 按类别向前遍历
|
|
126
|
+
// * 仅遍历属于指定类别 cat 的节点
|
|
127
|
+
// */
|
|
128
|
+
// forEachByType(cat: number, callback: (value: T) => any): void {
|
|
129
|
+
// // 从该类别的当前“顶端”节点开始
|
|
130
|
+
// let current = this.typeTops[cat];
|
|
131
|
+
// while (current) {
|
|
132
|
+
// const shouldBreak = callback(current.value);
|
|
133
|
+
// if (shouldBreak) break;
|
|
134
|
+
// // 关键点:直接跳向该节点记录的“上一个同类节点”
|
|
135
|
+
// // 这比遍历全局栈再筛选类别要快得多 (O(m) vs O(n))
|
|
136
|
+
// current = current.prevByType[cat];
|
|
137
|
+
// }
|
|
138
|
+
// }
|
|
135
139
|
}
|
|
136
140
|
|
|
137
141
|
const tap = new BaseEvent();
|
|
@@ -146,7 +150,7 @@ class Interpreter {
|
|
|
146
150
|
program(root, componentNode, before) {
|
|
147
151
|
var _a, _b;
|
|
148
152
|
this.rootComponent = componentNode;
|
|
149
|
-
this.tokenizer.
|
|
153
|
+
this.tokenizer.nextToken();
|
|
150
154
|
const stack = new MultiTypeStack();
|
|
151
155
|
stack.push({ node: root, prev: null }, NodeSort.Real);
|
|
152
156
|
stack.push(
|
|
@@ -169,7 +173,7 @@ class Interpreter {
|
|
|
169
173
|
}
|
|
170
174
|
const token = this.tokenizer.token;
|
|
171
175
|
if (token.type & TokenType.Indent) {
|
|
172
|
-
this.tokenizer.
|
|
176
|
+
this.tokenizer.nextToken();
|
|
173
177
|
const isLogicNode = this.isLogicNode(ctx.current);
|
|
174
178
|
stack.push(
|
|
175
179
|
{
|
|
@@ -198,7 +202,7 @@ class Interpreter {
|
|
|
198
202
|
this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
|
|
199
203
|
}
|
|
200
204
|
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
201
|
-
this.tokenizer.
|
|
205
|
+
this.tokenizer.nextToken();
|
|
202
206
|
const [{ node: parent, prev }, sort] = stack.pop();
|
|
203
207
|
if (!parent.__logicType) {
|
|
204
208
|
const prevSameType = stack.peekByType(NodeSort.Real);
|
|
@@ -303,7 +307,7 @@ class Interpreter {
|
|
|
303
307
|
} else {
|
|
304
308
|
_node = this.createNode(value);
|
|
305
309
|
}
|
|
306
|
-
this.tokenizer.
|
|
310
|
+
this.tokenizer.nextToken();
|
|
307
311
|
this.headerLine(_node);
|
|
308
312
|
this.extensionLines(_node);
|
|
309
313
|
if (_node.__logicType === FakeType.Component) {
|
|
@@ -392,7 +396,8 @@ class Interpreter {
|
|
|
392
396
|
var _a;
|
|
393
397
|
const { prevSibling } = ctx;
|
|
394
398
|
const snapbackUp = this.tokenizer.snapshot();
|
|
395
|
-
const keyWord = this.tokenizer.
|
|
399
|
+
const keyWord = this.tokenizer.token;
|
|
400
|
+
this.tokenizer.nextToken();
|
|
396
401
|
const noSelfCond = this.tokenizer.token.type === TokenType.NewLine;
|
|
397
402
|
const [hookType, value] = this.tokenizer._hook({});
|
|
398
403
|
const isElse = keyWord.value === "else";
|
|
@@ -473,9 +478,9 @@ class Interpreter {
|
|
|
473
478
|
if (val) {
|
|
474
479
|
if (ifNode.isFirstRender) {
|
|
475
480
|
if (!noSelfCond) {
|
|
476
|
-
this.tokenizer.
|
|
481
|
+
this.tokenizer.nextToken();
|
|
477
482
|
}
|
|
478
|
-
this.tokenizer.
|
|
483
|
+
this.tokenizer.nextToken();
|
|
479
484
|
} else {
|
|
480
485
|
this.tokenizer = ifNode.owner.tokenizer;
|
|
481
486
|
this.tokenizer.resume(ifNode.snapshot);
|
|
@@ -510,15 +515,15 @@ class Interpreter {
|
|
|
510
515
|
*/
|
|
511
516
|
extensionLines(_node) {
|
|
512
517
|
while (1) {
|
|
513
|
-
if (
|
|
518
|
+
if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
|
|
514
519
|
return;
|
|
515
520
|
}
|
|
516
|
-
this.tokenizer.
|
|
521
|
+
this.tokenizer.nextToken();
|
|
517
522
|
this.attributeList(_node);
|
|
518
|
-
if (
|
|
523
|
+
if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
|
|
519
524
|
return;
|
|
520
525
|
}
|
|
521
|
-
this.tokenizer.
|
|
526
|
+
this.tokenizer.nextToken();
|
|
522
527
|
}
|
|
523
528
|
}
|
|
524
529
|
/**
|
|
@@ -528,7 +533,7 @@ class Interpreter {
|
|
|
528
533
|
*/
|
|
529
534
|
headerLine(_node) {
|
|
530
535
|
this.attributeList(_node);
|
|
531
|
-
this.tokenizer.
|
|
536
|
+
this.tokenizer.nextToken();
|
|
532
537
|
}
|
|
533
538
|
/**
|
|
534
539
|
* 属性列表:
|
|
@@ -538,19 +543,19 @@ class Interpreter {
|
|
|
538
543
|
*
|
|
539
544
|
* <attribute> ::= <key> = <value>
|
|
540
545
|
* 1. 普通节点 执行 setProps 🪝
|
|
541
|
-
* 2. 组件节点
|
|
546
|
+
* 2. 组件节点 收集映射关系,或 产生 computed
|
|
542
547
|
*/
|
|
543
548
|
attributeList(_node) {
|
|
544
549
|
let key, eq;
|
|
545
550
|
const data = this.getData();
|
|
546
|
-
while (
|
|
551
|
+
while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
|
|
547
552
|
if (key == null) {
|
|
548
553
|
key = this.tokenizer.token.value;
|
|
549
554
|
} else if (eq == null) {
|
|
550
555
|
eq = "=";
|
|
551
556
|
} else {
|
|
552
557
|
const [hookType, value, hookI] = this.tokenizer._hook({});
|
|
553
|
-
const rawVal =
|
|
558
|
+
const rawVal = data[Keys.Raw][value];
|
|
554
559
|
const isFn = typeof rawVal === "function";
|
|
555
560
|
if (hookType === "dynamic") {
|
|
556
561
|
const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
|
|
@@ -564,7 +569,7 @@ class Interpreter {
|
|
|
564
569
|
key = null;
|
|
565
570
|
eq = null;
|
|
566
571
|
}
|
|
567
|
-
this.tokenizer.
|
|
572
|
+
this.tokenizer.nextToken();
|
|
568
573
|
}
|
|
569
574
|
}
|
|
570
575
|
config(opt) {
|
|
@@ -724,16 +729,16 @@ const _Tokenizer = class _Tokenizer {
|
|
|
724
729
|
let skipFragment = ``;
|
|
725
730
|
this.token = void 0;
|
|
726
731
|
while (1) {
|
|
727
|
-
const char = this.
|
|
732
|
+
const char = this.code[this.i];
|
|
728
733
|
if (char === "\n") {
|
|
729
734
|
needIndent = true;
|
|
730
735
|
skipFragment += char;
|
|
731
|
-
this.
|
|
736
|
+
this.i++;
|
|
732
737
|
continue;
|
|
733
738
|
}
|
|
734
739
|
if (!needIndent) {
|
|
735
740
|
skipFragment += char;
|
|
736
|
-
this.
|
|
741
|
+
this.i++;
|
|
737
742
|
continue;
|
|
738
743
|
}
|
|
739
744
|
needIndent = false;
|
|
@@ -786,21 +791,6 @@ ${_Tokenizer.EofId}`;
|
|
|
786
791
|
if (!this.token) return false;
|
|
787
792
|
return this.token.type & TokenType.Identifier && this.token.value === _Tokenizer.EofId;
|
|
788
793
|
}
|
|
789
|
-
get char() {
|
|
790
|
-
return this.code[this.i];
|
|
791
|
-
}
|
|
792
|
-
get prev() {
|
|
793
|
-
return this.code[this.i - 1];
|
|
794
|
-
}
|
|
795
|
-
get after() {
|
|
796
|
-
return this.code[this.i + 1];
|
|
797
|
-
}
|
|
798
|
-
next() {
|
|
799
|
-
const prev = this.code[this.i];
|
|
800
|
-
this.i++;
|
|
801
|
-
const curr = this.code[this.i];
|
|
802
|
-
return [prev, curr];
|
|
803
|
-
}
|
|
804
794
|
setToken(type, value) {
|
|
805
795
|
this.token = {
|
|
806
796
|
type,
|
|
@@ -809,10 +799,6 @@ ${_Tokenizer.EofId}`;
|
|
|
809
799
|
};
|
|
810
800
|
this.isFirstToken = false;
|
|
811
801
|
}
|
|
812
|
-
testId(value) {
|
|
813
|
-
if (typeof value !== "string") return false;
|
|
814
|
-
return _Tokenizer.IdExp.test(value);
|
|
815
|
-
}
|
|
816
802
|
nextToken() {
|
|
817
803
|
try {
|
|
818
804
|
if (this.isEof()) {
|
|
@@ -828,7 +814,7 @@ ${_Tokenizer.EofId}`;
|
|
|
828
814
|
if (this.needIndent) {
|
|
829
815
|
this.dent();
|
|
830
816
|
} else {
|
|
831
|
-
|
|
817
|
+
const char = this.code[this.i];
|
|
832
818
|
switch (char) {
|
|
833
819
|
case " ":
|
|
834
820
|
case " ":
|
|
@@ -859,12 +845,12 @@ ${_Tokenizer.EofId}`;
|
|
|
859
845
|
this.number(char);
|
|
860
846
|
break;
|
|
861
847
|
}
|
|
862
|
-
if (
|
|
848
|
+
if (typeof char === "string" && matchIdStart(char)) {
|
|
863
849
|
this.identifier(char);
|
|
864
850
|
}
|
|
865
851
|
break;
|
|
866
852
|
}
|
|
867
|
-
this.
|
|
853
|
+
this.i++;
|
|
868
854
|
}
|
|
869
855
|
if (this.token) {
|
|
870
856
|
break;
|
|
@@ -873,6 +859,7 @@ ${_Tokenizer.EofId}`;
|
|
|
873
859
|
return this.token;
|
|
874
860
|
} catch (error) {
|
|
875
861
|
console.error(error);
|
|
862
|
+
return this.token;
|
|
876
863
|
} finally {
|
|
877
864
|
this.handledTokens.push(this.token);
|
|
878
865
|
}
|
|
@@ -884,17 +871,17 @@ ${_Tokenizer.EofId}`;
|
|
|
884
871
|
this.setToken(TokenType.Pipe, "|");
|
|
885
872
|
}
|
|
886
873
|
dynamic(char) {
|
|
887
|
-
let nextC = this.
|
|
874
|
+
let nextC = this.code[this.i + 1];
|
|
888
875
|
if (nextC !== "{") {
|
|
889
876
|
return false;
|
|
890
877
|
}
|
|
891
|
-
this.
|
|
878
|
+
this.i++;
|
|
892
879
|
let value = "${";
|
|
893
880
|
let innerBrace = 0;
|
|
894
881
|
while (1) {
|
|
895
|
-
nextC = this.
|
|
882
|
+
nextC = this.code[this.i + 1];
|
|
896
883
|
value += nextC;
|
|
897
|
-
this.
|
|
884
|
+
this.i++;
|
|
898
885
|
if (nextC === "{") {
|
|
899
886
|
innerBrace++;
|
|
900
887
|
}
|
|
@@ -911,13 +898,14 @@ ${_Tokenizer.EofId}`;
|
|
|
911
898
|
brace() {
|
|
912
899
|
let inComment, inString, count = 0, value = "", backslashCount = 0;
|
|
913
900
|
while (1) {
|
|
914
|
-
const char = this.
|
|
915
|
-
const nextChar = this.
|
|
901
|
+
const char = this.code[this.i];
|
|
902
|
+
const nextChar = this.code[this.i + 1];
|
|
916
903
|
if (inComment === "single" && char === "\n") {
|
|
917
904
|
inComment = null;
|
|
918
905
|
} else if (inComment === "multi" && char === "*" && nextChar === "/") {
|
|
919
906
|
inComment = null;
|
|
920
|
-
value += this.
|
|
907
|
+
value += this.code[this.i];
|
|
908
|
+
this.i++;
|
|
921
909
|
} else if (inString) {
|
|
922
910
|
if (char === inString && backslashCount % 2 === 0) {
|
|
923
911
|
inString = null;
|
|
@@ -926,10 +914,12 @@ ${_Tokenizer.EofId}`;
|
|
|
926
914
|
} else {
|
|
927
915
|
if (char === "/" && nextChar === "/") {
|
|
928
916
|
inComment = "single";
|
|
929
|
-
value += this.
|
|
917
|
+
value += this.code[this.i];
|
|
918
|
+
this.i++;
|
|
930
919
|
} else if (char === "/" && nextChar === "*") {
|
|
931
920
|
inComment = "multi";
|
|
932
|
-
value += this.
|
|
921
|
+
value += this.code[this.i];
|
|
922
|
+
this.i++;
|
|
933
923
|
} else if (char === "'" || char === '"' || char === "`") {
|
|
934
924
|
inString = char;
|
|
935
925
|
} else if (char === "{") {
|
|
@@ -942,19 +932,20 @@ ${_Tokenizer.EofId}`;
|
|
|
942
932
|
this.setToken(TokenType.InsertionExp, value.slice(1));
|
|
943
933
|
return;
|
|
944
934
|
}
|
|
945
|
-
value += this.
|
|
935
|
+
value += this.code[this.i];
|
|
936
|
+
this.i++;
|
|
946
937
|
}
|
|
947
938
|
}
|
|
948
939
|
newLine() {
|
|
949
940
|
let value = "\n";
|
|
950
941
|
let nextC;
|
|
951
942
|
while (1) {
|
|
952
|
-
nextC = this.
|
|
943
|
+
nextC = this.code[this.i + 1];
|
|
953
944
|
if (nextC !== "\n") {
|
|
954
945
|
break;
|
|
955
946
|
}
|
|
956
947
|
value += nextC;
|
|
957
|
-
this.
|
|
948
|
+
this.i++;
|
|
958
949
|
}
|
|
959
950
|
if (this.isFirstToken) {
|
|
960
951
|
return;
|
|
@@ -966,7 +957,7 @@ ${_Tokenizer.EofId}`;
|
|
|
966
957
|
let nextC;
|
|
967
958
|
let isEmptyLine = false;
|
|
968
959
|
while (1) {
|
|
969
|
-
const nextChar = this.
|
|
960
|
+
const nextChar = this.code[this.i];
|
|
970
961
|
switch (nextChar) {
|
|
971
962
|
case " ":
|
|
972
963
|
nextC = this.Tab;
|
|
@@ -989,7 +980,7 @@ ${_Tokenizer.EofId}`;
|
|
|
989
980
|
break;
|
|
990
981
|
}
|
|
991
982
|
value += nextC;
|
|
992
|
-
this.
|
|
983
|
+
this.i++;
|
|
993
984
|
}
|
|
994
985
|
return {
|
|
995
986
|
value,
|
|
@@ -1012,7 +1003,7 @@ ${_Tokenizer.EofId}`;
|
|
|
1012
1003
|
const prevLen = this.dentStack[this.dentStack.length - 1];
|
|
1013
1004
|
if (currLen > prevLen) {
|
|
1014
1005
|
this.dentStack.push(currLen);
|
|
1015
|
-
this.setToken(TokenType.Indent,
|
|
1006
|
+
this.setToken(TokenType.Indent, currLen);
|
|
1016
1007
|
return indentHasLen;
|
|
1017
1008
|
}
|
|
1018
1009
|
if (currLen < prevLen) {
|
|
@@ -1071,12 +1062,12 @@ ${_Tokenizer.EofId}`;
|
|
|
1071
1062
|
let value = char;
|
|
1072
1063
|
let nextC;
|
|
1073
1064
|
while (1) {
|
|
1074
|
-
nextC = this.
|
|
1075
|
-
if (!
|
|
1065
|
+
nextC = this.code[this.i + 1];
|
|
1066
|
+
if (typeof nextC !== "string" || !matchIdStart(nextC)) {
|
|
1076
1067
|
break;
|
|
1077
1068
|
}
|
|
1078
1069
|
value += nextC;
|
|
1079
|
-
this.
|
|
1070
|
+
this.i++;
|
|
1080
1071
|
}
|
|
1081
1072
|
if (value === _Tokenizer.EofId && this.isSubToken) {
|
|
1082
1073
|
this.setToken(TokenType.Dedent, "");
|
|
@@ -1086,35 +1077,35 @@ ${_Tokenizer.EofId}`;
|
|
|
1086
1077
|
this.setToken(TokenType.Identifier, realValue);
|
|
1087
1078
|
}
|
|
1088
1079
|
str(char) {
|
|
1089
|
-
let value =
|
|
1080
|
+
let value = "";
|
|
1090
1081
|
let nextC;
|
|
1091
1082
|
let continuousBackslashCount = 0;
|
|
1092
1083
|
while (1) {
|
|
1093
|
-
nextC = this.
|
|
1094
|
-
value += nextC;
|
|
1084
|
+
nextC = this.code[this.i + 1];
|
|
1095
1085
|
const memoCount = continuousBackslashCount;
|
|
1096
1086
|
if (nextC === "\\") {
|
|
1097
1087
|
continuousBackslashCount++;
|
|
1098
1088
|
} else {
|
|
1099
1089
|
continuousBackslashCount = 0;
|
|
1100
1090
|
}
|
|
1101
|
-
this.
|
|
1091
|
+
this.i++;
|
|
1102
1092
|
if (nextC === char && memoCount % 2 === 0) {
|
|
1103
1093
|
break;
|
|
1104
1094
|
}
|
|
1095
|
+
value += nextC;
|
|
1105
1096
|
}
|
|
1106
|
-
this.setToken(TokenType.Identifier,
|
|
1097
|
+
this.setToken(TokenType.Identifier, value);
|
|
1107
1098
|
}
|
|
1108
1099
|
number(char) {
|
|
1109
1100
|
let value = char;
|
|
1110
1101
|
let nextC;
|
|
1111
1102
|
while (1) {
|
|
1112
|
-
nextC = this.
|
|
1103
|
+
nextC = this.code[this.i + 1];
|
|
1113
1104
|
if (!isNum(nextC)) {
|
|
1114
1105
|
break;
|
|
1115
1106
|
}
|
|
1116
1107
|
value += nextC;
|
|
1117
|
-
this.
|
|
1108
|
+
this.i++;
|
|
1118
1109
|
}
|
|
1119
1110
|
this.setToken(TokenType.Identifier, Number(value));
|
|
1120
1111
|
}
|
|
@@ -1134,8 +1125,6 @@ ${_Tokenizer.EofId}`;
|
|
|
1134
1125
|
}
|
|
1135
1126
|
}
|
|
1136
1127
|
};
|
|
1137
|
-
/** 匹配标识符 */
|
|
1138
|
-
_Tokenizer.IdExp = /[\d\w\/]/;
|
|
1139
1128
|
/** Eof 标识符的值 */
|
|
1140
1129
|
_Tokenizer.EofId = `__EOF__${Date.now()}`;
|
|
1141
1130
|
_Tokenizer.DedentId = `__DEDENT__${Date.now()}`;
|