bobe 0.0.11 → 0.0.12
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 +223 -69
- package/dist/bobe.cjs.js.map +1 -1
- package/dist/bobe.esm.js +224 -70
- package/dist/bobe.esm.js.map +1 -1
- package/dist/index.d.ts +56 -17
- package/dist/index.umd.js +223 -69
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -3
package/dist/bobe.cjs.js
CHANGED
|
@@ -22,13 +22,94 @@ var LogicType = /* @__PURE__ */ ((LogicType2) => {
|
|
|
22
22
|
LogicType2[LogicType2["Component"] = 16] = "Component";
|
|
23
23
|
LogicType2[LogicType2["Fragment"] = 32] = "Fragment";
|
|
24
24
|
LogicType2[LogicType2["Root"] = 64] = "Root";
|
|
25
|
+
LogicType2[LogicType2["Real"] = 128] = "Real";
|
|
25
26
|
return LogicType2;
|
|
26
27
|
})(LogicType || {});
|
|
28
|
+
const Logical = 1 /* If */ | 2 /* ElseIf */ | 4 /* Else */ | 8 /* For */;
|
|
29
|
+
var NodeType = /* @__PURE__ */ ((NodeType2) => {
|
|
30
|
+
NodeType2[NodeType2["Logic"] = Logical] = "Logic";
|
|
31
|
+
NodeType2[NodeType2["Real"] = 128 /* Real */] = "Real";
|
|
32
|
+
NodeType2[NodeType2["Component"] = 16 /* Component */] = "Component";
|
|
33
|
+
return NodeType2;
|
|
34
|
+
})(NodeType || {});
|
|
27
35
|
var TerpEvt = /* @__PURE__ */ ((TerpEvt2) => {
|
|
28
36
|
TerpEvt2["AllAttrGot"] = "all-attr-got";
|
|
29
37
|
TerpEvt2["HandledComponentNode"] = "handled-component-node";
|
|
30
38
|
return TerpEvt2;
|
|
31
39
|
})(TerpEvt || {});
|
|
40
|
+
const IsAnchor = /* @__PURE__ */ Symbol("is-anchor");
|
|
41
|
+
|
|
42
|
+
class TypedStack {
|
|
43
|
+
constructor() {
|
|
44
|
+
this.top = null;
|
|
45
|
+
// 存储每种类型最近一次出现的包装单元引用
|
|
46
|
+
// 使用 Record 来动态支持不同的类型标签
|
|
47
|
+
this.lastNodes = {};
|
|
48
|
+
this.length = 0;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* @param rawNode 原始节点数据
|
|
52
|
+
* @param type 节点类型
|
|
53
|
+
*/
|
|
54
|
+
push(rawNode, type) {
|
|
55
|
+
var _a;
|
|
56
|
+
const newNode = {
|
|
57
|
+
data: rawNode,
|
|
58
|
+
type,
|
|
59
|
+
prev: this.top,
|
|
60
|
+
prevSameType: (_a = this.lastNodes[type]) != null ? _a : null
|
|
61
|
+
};
|
|
62
|
+
this.top = newNode;
|
|
63
|
+
this.length++;
|
|
64
|
+
this.lastNodes[type] = newNode;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 出栈操作
|
|
68
|
+
* @returns 原始节点数据或 null
|
|
69
|
+
*/
|
|
70
|
+
pop() {
|
|
71
|
+
if (!this.top) return null;
|
|
72
|
+
const popped = this.top;
|
|
73
|
+
this.lastNodes[popped.type] = popped.prevSameType;
|
|
74
|
+
this.top = popped.prev;
|
|
75
|
+
this.length--;
|
|
76
|
+
return popped.data;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* O(1) 获取栈顶节点的前一个同类型节点
|
|
80
|
+
*/
|
|
81
|
+
getPrevSameType() {
|
|
82
|
+
if (!this.top || !this.top.prevSameType) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
return this.top.prevSameType.data;
|
|
86
|
+
}
|
|
87
|
+
findPrevSameType(cb) {
|
|
88
|
+
if (!this.top) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
let point = this.top.prevSameType;
|
|
92
|
+
while (point) {
|
|
93
|
+
if (cb(point.data)) {
|
|
94
|
+
return point.data;
|
|
95
|
+
}
|
|
96
|
+
point = point.prevSameType;
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 获取当前栈顶的类型
|
|
102
|
+
*/
|
|
103
|
+
get peekType() {
|
|
104
|
+
return this.top ? this.top.type : null;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 获取栈顶元素
|
|
108
|
+
*/
|
|
109
|
+
peek() {
|
|
110
|
+
return this.top.data;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
32
113
|
|
|
33
114
|
var __defProp$1 = Object.defineProperty;
|
|
34
115
|
var __defProps$1 = Object.defineProperties;
|
|
@@ -78,61 +159,94 @@ class Interpreter {
|
|
|
78
159
|
return [hookType, value];
|
|
79
160
|
};
|
|
80
161
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// anchor: any;
|
|
162
|
+
isLogicNode(node) {
|
|
163
|
+
return node && node.__logicType & Logical;
|
|
164
|
+
}
|
|
85
165
|
program(root, before) {
|
|
166
|
+
var _a;
|
|
86
167
|
const componentNode = {
|
|
87
168
|
__logicType: LogicType.Component,
|
|
88
169
|
realParent: root,
|
|
89
170
|
store: new aoye.Store()
|
|
90
171
|
};
|
|
91
172
|
this.tokenizer.consume();
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const
|
|
173
|
+
const stack = new TypedStack();
|
|
174
|
+
stack.push({ node: root, prev: null }, NodeType.Real);
|
|
175
|
+
const ctx = {
|
|
176
|
+
realParent: root,
|
|
177
|
+
prevSibling: before,
|
|
178
|
+
current: null,
|
|
179
|
+
stack,
|
|
180
|
+
before
|
|
181
|
+
};
|
|
182
|
+
const rootPulling = aoye.getPulling();
|
|
95
183
|
while (1) {
|
|
96
184
|
if (this.tokenizer.isEof()) {
|
|
97
|
-
|
|
185
|
+
if (!ctx.prevSibling) ctx.prevSibling = before;
|
|
186
|
+
this.handleInsert(root, ctx.current, ctx.prevSibling, componentNode);
|
|
98
187
|
break;
|
|
99
188
|
}
|
|
100
189
|
const token = this.tokenizer.token;
|
|
101
190
|
if (token.type & TokenType.Indent) {
|
|
102
191
|
this.tokenizer.consume();
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
192
|
+
const isLogicNode = this.isLogicNode(ctx.current);
|
|
193
|
+
stack.push(
|
|
194
|
+
{
|
|
195
|
+
node: ctx.current,
|
|
196
|
+
prev: ctx.prevSibling
|
|
197
|
+
},
|
|
198
|
+
ctx.current.__logicType ? isLogicNode ? NodeType.Logic : NodeType.Component : NodeType.Real
|
|
199
|
+
);
|
|
200
|
+
if (ctx.current.__logicType) {
|
|
201
|
+
if (isLogicNode) {
|
|
202
|
+
aoye.setPulling(ctx.current.effect.ins);
|
|
203
|
+
}
|
|
204
|
+
} else {
|
|
205
|
+
ctx.realParent = ctx.current;
|
|
206
|
+
ctx.prevSibling = null;
|
|
207
|
+
}
|
|
208
|
+
ctx.current = this.declaration(ctx);
|
|
109
209
|
continue;
|
|
110
210
|
}
|
|
111
|
-
if (current) {
|
|
112
|
-
if (stack.length
|
|
113
|
-
|
|
114
|
-
this.handleInsert(parent, current, prevSibling);
|
|
115
|
-
} else {
|
|
116
|
-
if (!prevSibling) {
|
|
117
|
-
prevSibling = before;
|
|
118
|
-
}
|
|
119
|
-
this.handleInsert(root, current, prevSibling, componentNode);
|
|
211
|
+
if (ctx.current) {
|
|
212
|
+
if (stack.length === 1 && !ctx.prevSibling) {
|
|
213
|
+
ctx.prevSibling = before;
|
|
120
214
|
}
|
|
215
|
+
this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
|
|
121
216
|
}
|
|
122
217
|
if (this.tokenizer.token.type & TokenType.Dedent) {
|
|
123
218
|
this.tokenizer.consume();
|
|
124
|
-
const { node: parent, prev } = stack.
|
|
125
|
-
|
|
126
|
-
|
|
219
|
+
const { node: parent, prev } = stack.peek();
|
|
220
|
+
if (!parent.__logicType) {
|
|
221
|
+
const prevSameType = stack.getPrevSameType();
|
|
222
|
+
ctx.realParent = prevSameType == null ? void 0 : prevSameType.node;
|
|
223
|
+
} else {
|
|
224
|
+
if (this.isLogicNode(parent)) {
|
|
225
|
+
const parentLogic = (_a = stack.getPrevSameType()) == null ? void 0 : _a.node;
|
|
226
|
+
if (parentLogic) {
|
|
227
|
+
aoye.setPulling(parentLogic.effect.ins);
|
|
228
|
+
} else {
|
|
229
|
+
aoye.setPulling(rootPulling);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
stack.pop();
|
|
234
|
+
ctx.prevSibling = prev;
|
|
235
|
+
ctx.current = parent;
|
|
127
236
|
} else {
|
|
128
|
-
prevSibling = current;
|
|
129
|
-
current = this.declaration(
|
|
237
|
+
ctx.prevSibling = ctx.current || ctx.prevSibling;
|
|
238
|
+
ctx.current = this.declaration(ctx);
|
|
130
239
|
}
|
|
131
240
|
}
|
|
132
|
-
componentNode.lastInserted = this.lastInserted;
|
|
133
|
-
this.lastInserted = null;
|
|
134
241
|
return componentNode;
|
|
135
242
|
}
|
|
243
|
+
insertAfterAnchor(ctx) {
|
|
244
|
+
const { realParent, prevSibling, stack, before } = ctx;
|
|
245
|
+
const afterAnchor = this.createAnchor();
|
|
246
|
+
ctx.prevSibling = stack.length === 1 && !prevSibling ? before : prevSibling;
|
|
247
|
+
this.handleInsert(realParent, afterAnchor, prevSibling);
|
|
248
|
+
return afterAnchor;
|
|
249
|
+
}
|
|
136
250
|
/** 处理
|
|
137
251
|
* 是逻辑 是普通
|
|
138
252
|
* 父节点 将子节点加入 directList 调用 insert 方法挨个插入子节点
|
|
@@ -144,25 +258,14 @@ class Interpreter {
|
|
|
144
258
|
if (!prev || !prev.__logicType) {
|
|
145
259
|
this.insertAfter(parent, child, prev);
|
|
146
260
|
} else {
|
|
147
|
-
const before = prev.
|
|
261
|
+
const before = prev.realAfter;
|
|
148
262
|
this.insertAfter(parent, child, before);
|
|
149
|
-
prev.realAfter = child;
|
|
150
263
|
}
|
|
151
264
|
} else {
|
|
152
265
|
const childCmp = child;
|
|
153
266
|
childCmp.realParent = parent;
|
|
154
|
-
if (
|
|
155
|
-
|
|
156
|
-
this.insertAfter(parent, anchor, prev);
|
|
157
|
-
this.insertAfter(parent, child, anchor);
|
|
158
|
-
childCmp.realBefore = anchor;
|
|
159
|
-
} else if (prev.__logicType) {
|
|
160
|
-
const before = prev.lastInserted;
|
|
161
|
-
const anchor = this.createAnchor();
|
|
162
|
-
this.insertAfter(parent, anchor, before);
|
|
163
|
-
this.insertAfter(parent, child, anchor);
|
|
164
|
-
childCmp.realBefore = anchor;
|
|
165
|
-
prev.realAfter = anchor;
|
|
267
|
+
if (prev.__logicType) {
|
|
268
|
+
childCmp.realBefore = prev.realAfter;
|
|
166
269
|
} else {
|
|
167
270
|
childCmp.realBefore = prev;
|
|
168
271
|
}
|
|
@@ -190,7 +293,7 @@ class Interpreter {
|
|
|
190
293
|
const [hookType, value] = this._hook({});
|
|
191
294
|
let _node;
|
|
192
295
|
if (value === "if") {
|
|
193
|
-
return this.ifDeclaration();
|
|
296
|
+
return this.ifDeclaration(ctx);
|
|
194
297
|
} else if (hookType) {
|
|
195
298
|
if (hookType === "static") {
|
|
196
299
|
if (typeof value === "function" && value.prototype instanceof aoye.Store) {
|
|
@@ -264,37 +367,66 @@ class Interpreter {
|
|
|
264
367
|
child[aoye.Keys.Raw][key] = value;
|
|
265
368
|
}
|
|
266
369
|
};
|
|
370
|
+
const afterAnchor = this.insertAfterAnchor(ctx);
|
|
267
371
|
tap.once(TerpEvt.AllAttrGot, () => {
|
|
268
|
-
const parent = ctx.
|
|
372
|
+
const parent = ctx.realParent;
|
|
269
373
|
const prev = ctx.prevSibling;
|
|
270
374
|
this.onePropParsed = prevOnePropParsed;
|
|
271
375
|
const componentNode = child["ui"](this.opt, { data: child }, parent, prev);
|
|
376
|
+
componentNode.realAfter = afterAnchor;
|
|
272
377
|
tap.emit(TerpEvt.HandledComponentNode, componentNode);
|
|
273
378
|
});
|
|
274
379
|
return { __logicType: LogicType.Component };
|
|
275
380
|
}
|
|
276
|
-
ifDeclaration() {
|
|
381
|
+
ifDeclaration(ctx) {
|
|
277
382
|
this.tokenizer.consume();
|
|
278
|
-
const [
|
|
383
|
+
const [hookType, value] = this._hook({});
|
|
279
384
|
const ifNode = {
|
|
280
385
|
__logicType: LogicType.If,
|
|
281
|
-
condition: value,
|
|
282
|
-
realParent: null,
|
|
283
386
|
snapshot: this.tokenizer.snapshot(),
|
|
387
|
+
condition: null,
|
|
388
|
+
realParent: null,
|
|
284
389
|
isFirstRender: true,
|
|
285
|
-
|
|
286
|
-
anchor: null
|
|
390
|
+
effect: null
|
|
287
391
|
};
|
|
288
|
-
|
|
392
|
+
const valueIsMapKey = Reflect.has(this.data[aoye.Keys.Raw], value);
|
|
393
|
+
let signal;
|
|
394
|
+
if (valueIsMapKey) {
|
|
395
|
+
aoye.runWithPulling(() => this.data[value], null);
|
|
396
|
+
const { cells } = this.data[aoye.Keys.Meta];
|
|
397
|
+
signal = cells.get(value);
|
|
398
|
+
} else {
|
|
399
|
+
const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, this.data);
|
|
400
|
+
signal = aoye.$(fn);
|
|
401
|
+
}
|
|
402
|
+
ifNode.condition = signal;
|
|
403
|
+
ifNode.realAfter = this.insertAfterAnchor(ctx);
|
|
404
|
+
ifNode.effect = aoye.effect(
|
|
289
405
|
({ val }) => {
|
|
290
406
|
if (val) {
|
|
291
|
-
|
|
292
|
-
|
|
407
|
+
if (ifNode.isFirstRender) {
|
|
408
|
+
this.tokenizer.consume();
|
|
409
|
+
this.tokenizer.consume();
|
|
410
|
+
} else {
|
|
411
|
+
this.tokenizer.resume(ifNode.snapshot);
|
|
412
|
+
this.program(ifNode.realParent, ifNode.realBefore);
|
|
413
|
+
}
|
|
293
414
|
} else {
|
|
294
|
-
|
|
415
|
+
if (ifNode.isFirstRender) {
|
|
416
|
+
this.tokenizer.skip();
|
|
417
|
+
} else {
|
|
418
|
+
const { realBefore, realAfter, realParent } = ifNode;
|
|
419
|
+
let point = this.nextSib(realBefore);
|
|
420
|
+
while (point !== realAfter) {
|
|
421
|
+
const next = this.nextSib(point);
|
|
422
|
+
this.remove(point, realParent, realBefore);
|
|
423
|
+
point = next;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
295
426
|
}
|
|
427
|
+
ifNode.isFirstRender = false;
|
|
296
428
|
},
|
|
297
|
-
[
|
|
429
|
+
[signal]
|
|
298
430
|
);
|
|
299
431
|
return ifNode;
|
|
300
432
|
}
|
|
@@ -372,6 +504,11 @@ class Interpreter {
|
|
|
372
504
|
nextSib(node) {
|
|
373
505
|
return node.nextSibling;
|
|
374
506
|
}
|
|
507
|
+
_createAnchor() {
|
|
508
|
+
const anchor = this.createAnchor();
|
|
509
|
+
anchor[IsAnchor] = true;
|
|
510
|
+
return anchor;
|
|
511
|
+
}
|
|
375
512
|
createAnchor() {
|
|
376
513
|
return {
|
|
377
514
|
name: "anchor",
|
|
@@ -379,7 +516,6 @@ class Interpreter {
|
|
|
379
516
|
};
|
|
380
517
|
}
|
|
381
518
|
insertAfter(parent, node, prev) {
|
|
382
|
-
this.lastInserted = node;
|
|
383
519
|
return this.defaultInsert(parent, node, prev);
|
|
384
520
|
}
|
|
385
521
|
defaultInsert(parent, node, prev) {
|
|
@@ -391,11 +527,11 @@ class Interpreter {
|
|
|
391
527
|
parent.firstChild = node;
|
|
392
528
|
}
|
|
393
529
|
}
|
|
394
|
-
remove(
|
|
395
|
-
return this.defaultRemove(
|
|
530
|
+
remove(node, parent, prev) {
|
|
531
|
+
return this.defaultRemove(node, parent, prev);
|
|
396
532
|
}
|
|
397
533
|
// TODO: 默认改成 prevItem
|
|
398
|
-
defaultRemove(
|
|
534
|
+
defaultRemove(node, parent, prevSibling) {
|
|
399
535
|
const next = node.nextSibling;
|
|
400
536
|
if (prevSibling) {
|
|
401
537
|
prevSibling.nextSibling = next;
|
|
@@ -468,7 +604,7 @@ const _Tokenizer = class _Tokenizer {
|
|
|
468
604
|
};
|
|
469
605
|
}
|
|
470
606
|
skip() {
|
|
471
|
-
const
|
|
607
|
+
const logicDentLen = this.dentStack[this.dentStack.length - 1];
|
|
472
608
|
let needIndent = false;
|
|
473
609
|
let skipFragment = ``;
|
|
474
610
|
this.token = void 0;
|
|
@@ -489,7 +625,7 @@ const _Tokenizer = class _Tokenizer {
|
|
|
489
625
|
const { value, isEmptyLine } = this.getDentValue();
|
|
490
626
|
const currLen = value.length;
|
|
491
627
|
if (isEmptyLine) continue;
|
|
492
|
-
if (
|
|
628
|
+
if (currLen > logicDentLen) {
|
|
493
629
|
skipFragment += value;
|
|
494
630
|
} else {
|
|
495
631
|
for (let i = this.dentStack.length - 1; i >= 0; i--) {
|
|
@@ -498,6 +634,9 @@ const _Tokenizer = class _Tokenizer {
|
|
|
498
634
|
if (currLen > expLen) {
|
|
499
635
|
throw SyntaxError(`\u7F29\u8FDB\u9519\u8BEF\uFF0C\u7F29\u8FDB\u957F\u5EA6\u4E0D\u5339\u914D`);
|
|
500
636
|
}
|
|
637
|
+
if (this.shorterThanBaseDentEof()) {
|
|
638
|
+
break;
|
|
639
|
+
}
|
|
501
640
|
this.dentStack.pop();
|
|
502
641
|
if (!this.token) {
|
|
503
642
|
this.setToken(TokenType.Dedent, String(expLen));
|
|
@@ -762,12 +901,15 @@ ${_Tokenizer.EofId}`;
|
|
|
762
901
|
return indentHasLen;
|
|
763
902
|
}
|
|
764
903
|
if (currLen < prevLen) {
|
|
765
|
-
for (let i = this.dentStack.length
|
|
904
|
+
for (let i = this.dentStack.length; i--; ) {
|
|
766
905
|
const expLen = this.dentStack[i];
|
|
767
|
-
|
|
768
|
-
if (currLen > expLen
|
|
906
|
+
if (currLen === expLen) break;
|
|
907
|
+
if (currLen > expLen) {
|
|
769
908
|
throw SyntaxError("\u7F29\u8FDB\u5927\u5C0F\u4E0D\u7EDF\u4E00");
|
|
770
909
|
}
|
|
910
|
+
if (this.shorterThanBaseDentEof()) {
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
771
913
|
this.dentStack.pop();
|
|
772
914
|
if (!this.token) {
|
|
773
915
|
this.setToken(TokenType.Dedent, String(expLen));
|
|
@@ -778,14 +920,26 @@ ${_Tokenizer.EofId}`;
|
|
|
778
920
|
value: String(expLen)
|
|
779
921
|
});
|
|
780
922
|
}
|
|
781
|
-
if (currLen === expLen) {
|
|
782
|
-
break;
|
|
783
|
-
}
|
|
784
923
|
}
|
|
785
924
|
return indentHasLen;
|
|
786
925
|
}
|
|
787
926
|
return indentHasLen;
|
|
788
927
|
}
|
|
928
|
+
shorterThanBaseDentEof() {
|
|
929
|
+
const yes = this.dentStack.length === 1;
|
|
930
|
+
if (yes) {
|
|
931
|
+
if (!this.token) {
|
|
932
|
+
this.setToken(TokenType.Identifier, _Tokenizer.EofId);
|
|
933
|
+
} else {
|
|
934
|
+
this.waitingTokens.push({
|
|
935
|
+
type: TokenType.Identifier,
|
|
936
|
+
typeName: TokenType[TokenType.Identifier],
|
|
937
|
+
value: _Tokenizer.EofId
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
return yes;
|
|
942
|
+
}
|
|
789
943
|
identifier(char) {
|
|
790
944
|
let value = char;
|
|
791
945
|
let nextC;
|