bobe 0.0.10 → 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/index.umd.js CHANGED
@@ -23,35 +23,116 @@
23
23
  LogicType2[LogicType2["Component"] = 16] = "Component";
24
24
  LogicType2[LogicType2["Fragment"] = 32] = "Fragment";
25
25
  LogicType2[LogicType2["Root"] = 64] = "Root";
26
+ LogicType2[LogicType2["Real"] = 128] = "Real";
26
27
  return LogicType2;
27
28
  })(LogicType || {});
29
+ const Logical = 1 /* If */ | 2 /* ElseIf */ | 4 /* Else */ | 8 /* For */;
30
+ var NodeType = /* @__PURE__ */ ((NodeType2) => {
31
+ NodeType2[NodeType2["Logic"] = Logical] = "Logic";
32
+ NodeType2[NodeType2["Real"] = 128 /* Real */] = "Real";
33
+ NodeType2[NodeType2["Component"] = 16 /* Component */] = "Component";
34
+ return NodeType2;
35
+ })(NodeType || {});
28
36
  var TerpEvt = /* @__PURE__ */ ((TerpEvt2) => {
29
37
  TerpEvt2["AllAttrGot"] = "all-attr-got";
30
38
  TerpEvt2["HandledComponentNode"] = "handled-component-node";
31
39
  return TerpEvt2;
32
40
  })(TerpEvt || {});
41
+ const IsAnchor = /* @__PURE__ */ Symbol("is-anchor");
33
42
 
34
- var __defProp = Object.defineProperty;
35
- var __defProps = Object.defineProperties;
36
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
37
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
38
- var __hasOwnProp = Object.prototype.hasOwnProperty;
39
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
40
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
41
- var __spreadValues = (a, b) => {
43
+ class TypedStack {
44
+ constructor() {
45
+ this.top = null;
46
+ // 存储每种类型最近一次出现的包装单元引用
47
+ // 使用 Record 来动态支持不同的类型标签
48
+ this.lastNodes = {};
49
+ this.length = 0;
50
+ }
51
+ /**
52
+ * @param rawNode 原始节点数据
53
+ * @param type 节点类型
54
+ */
55
+ push(rawNode, type) {
56
+ var _a;
57
+ const newNode = {
58
+ data: rawNode,
59
+ type,
60
+ prev: this.top,
61
+ prevSameType: (_a = this.lastNodes[type]) != null ? _a : null
62
+ };
63
+ this.top = newNode;
64
+ this.length++;
65
+ this.lastNodes[type] = newNode;
66
+ }
67
+ /**
68
+ * 出栈操作
69
+ * @returns 原始节点数据或 null
70
+ */
71
+ pop() {
72
+ if (!this.top) return null;
73
+ const popped = this.top;
74
+ this.lastNodes[popped.type] = popped.prevSameType;
75
+ this.top = popped.prev;
76
+ this.length--;
77
+ return popped.data;
78
+ }
79
+ /**
80
+ * O(1) 获取栈顶节点的前一个同类型节点
81
+ */
82
+ getPrevSameType() {
83
+ if (!this.top || !this.top.prevSameType) {
84
+ return null;
85
+ }
86
+ return this.top.prevSameType.data;
87
+ }
88
+ findPrevSameType(cb) {
89
+ if (!this.top) {
90
+ return null;
91
+ }
92
+ let point = this.top.prevSameType;
93
+ while (point) {
94
+ if (cb(point.data)) {
95
+ return point.data;
96
+ }
97
+ point = point.prevSameType;
98
+ }
99
+ return null;
100
+ }
101
+ /**
102
+ * 获取当前栈顶的类型
103
+ */
104
+ get peekType() {
105
+ return this.top ? this.top.type : null;
106
+ }
107
+ /**
108
+ * 获取栈顶元素
109
+ */
110
+ peek() {
111
+ return this.top.data;
112
+ }
113
+ }
114
+
115
+ var __defProp$1 = Object.defineProperty;
116
+ var __defProps$1 = Object.defineProperties;
117
+ var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
118
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
119
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
120
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
121
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
122
+ var __spreadValues$1 = (a, b) => {
42
123
  for (var prop in b || (b = {}))
43
- if (__hasOwnProp.call(b, prop))
44
- __defNormalProp(a, prop, b[prop]);
45
- if (__getOwnPropSymbols)
46
- for (var prop of __getOwnPropSymbols(b)) {
47
- if (__propIsEnum.call(b, prop))
48
- __defNormalProp(a, prop, b[prop]);
124
+ if (__hasOwnProp$1.call(b, prop))
125
+ __defNormalProp$1(a, prop, b[prop]);
126
+ if (__getOwnPropSymbols$1)
127
+ for (var prop of __getOwnPropSymbols$1(b)) {
128
+ if (__propIsEnum$1.call(b, prop))
129
+ __defNormalProp$1(a, prop, b[prop]);
49
130
  }
50
131
  return a;
51
132
  };
52
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
133
+ var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
53
134
  const tap = new bobeShared.BaseEvent();
54
- class Terp {
135
+ class Interpreter {
55
136
  constructor(tokenizer) {
56
137
  this.tokenizer = tokenizer;
57
138
  /** 模板字符串动态节点的占位符 */
@@ -60,7 +141,6 @@
60
141
  this.data = {};
61
142
  /** 模板字符串动态节点索引 */
62
143
  this.hookI = 0;
63
- this.stack = [];
64
144
  this._hook = (props) => {
65
145
  const value = this.tokenizer.token.value;
66
146
  const isDynamicHook = this.tokenizer.token.type & TokenType.InsertionExp;
@@ -68,7 +148,7 @@
68
148
  const hookType = isDynamicHook ? "dynamic" : isStaticHook ? "static" : void 0;
69
149
  if (this.hook && isStaticHook) {
70
150
  const hookI = Number(value.slice(this.HookId.length));
71
- const res = this.hook(__spreadProps(__spreadValues({}, props), {
151
+ const res = this.hook(__spreadProps$1(__spreadValues$1({}, props), {
72
152
  HookId: this.HookId,
73
153
  i: hookI
74
154
  }));
@@ -80,123 +160,115 @@
80
160
  return [hookType, value];
81
161
  };
82
162
  }
83
- // /** program 要挂载的父节点位置 */
84
- // root: any;
85
- // /** program 挂载的前置节点 */
86
- // anchor: any;
87
- program() {
88
- const root = {
163
+ isLogicNode(node) {
164
+ return node && node.__logicType & Logical;
165
+ }
166
+ program(root, before) {
167
+ var _a;
168
+ const componentNode = {
89
169
  __logicType: LogicType.Component,
90
- store: this.data,
91
- realList: [],
92
- directList: []
170
+ realParent: root,
171
+ store: new aoye.Store()
93
172
  };
94
173
  this.tokenizer.consume();
95
- let current;
96
- let prevSibling;
97
- this.stack = [{ node: root, prevSibling }];
174
+ const stack = new TypedStack();
175
+ stack.push({ node: root, prev: null }, NodeType.Real);
176
+ const ctx = {
177
+ realParent: root,
178
+ prevSibling: before,
179
+ current: null,
180
+ stack,
181
+ before
182
+ };
183
+ const rootPulling = aoye.getPulling();
98
184
  while (1) {
99
185
  if (this.tokenizer.isEof()) {
100
- this.handleInsert(root, current, root.realList[root.realList.length - 1]);
186
+ if (!ctx.prevSibling) ctx.prevSibling = before;
187
+ this.handleInsert(root, ctx.current, ctx.prevSibling, componentNode);
101
188
  break;
102
189
  }
103
190
  const token = this.tokenizer.token;
104
191
  if (token.type & TokenType.Indent) {
105
192
  this.tokenizer.consume();
106
- this.stack.push({
107
- prevSibling,
108
- node: current
109
- });
110
- prevSibling = null;
111
- current = this.declaration();
193
+ const isLogicNode = this.isLogicNode(ctx.current);
194
+ stack.push(
195
+ {
196
+ node: ctx.current,
197
+ prev: ctx.prevSibling
198
+ },
199
+ ctx.current.__logicType ? isLogicNode ? NodeType.Logic : NodeType.Component : NodeType.Real
200
+ );
201
+ if (ctx.current.__logicType) {
202
+ if (isLogicNode) {
203
+ aoye.setPulling(ctx.current.effect.ins);
204
+ }
205
+ } else {
206
+ ctx.realParent = ctx.current;
207
+ ctx.prevSibling = null;
208
+ }
209
+ ctx.current = this.declaration(ctx);
112
210
  continue;
113
211
  }
114
- if (current) {
115
- if (this.stack.length > 1) {
116
- const parent = this.stack[this.stack.length - 1].node;
117
- this.handleInsert(parent, current, prevSibling);
118
- } else {
119
- this.handleInsert(root, current, prevSibling);
212
+ if (ctx.current) {
213
+ if (stack.length === 1 && !ctx.prevSibling) {
214
+ ctx.prevSibling = before;
120
215
  }
216
+ this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
121
217
  }
122
218
  if (this.tokenizer.token.type & TokenType.Dedent) {
123
219
  this.tokenizer.consume();
124
- const { node: parent, prevSibling: prevParent } = this.stack.pop();
125
- prevSibling = prevParent;
126
- current = parent;
220
+ const { node: parent, prev } = stack.peek();
221
+ if (!parent.__logicType) {
222
+ const prevSameType = stack.getPrevSameType();
223
+ ctx.realParent = prevSameType == null ? void 0 : prevSameType.node;
224
+ } else {
225
+ if (this.isLogicNode(parent)) {
226
+ const parentLogic = (_a = stack.getPrevSameType()) == null ? void 0 : _a.node;
227
+ if (parentLogic) {
228
+ aoye.setPulling(parentLogic.effect.ins);
229
+ } else {
230
+ aoye.setPulling(rootPulling);
231
+ }
232
+ }
233
+ }
234
+ stack.pop();
235
+ ctx.prevSibling = prev;
236
+ ctx.current = parent;
127
237
  } else {
128
- prevSibling = current;
129
- current = this.declaration();
238
+ ctx.prevSibling = ctx.current || ctx.prevSibling;
239
+ ctx.current = this.declaration(ctx);
130
240
  }
131
241
  }
132
- return root;
242
+ return componentNode;
243
+ }
244
+ insertAfterAnchor(ctx) {
245
+ const { realParent, prevSibling, stack, before } = ctx;
246
+ const afterAnchor = this.createAnchor();
247
+ ctx.prevSibling = stack.length === 1 && !prevSibling ? before : prevSibling;
248
+ this.handleInsert(realParent, afterAnchor, prevSibling);
249
+ return afterAnchor;
133
250
  }
134
251
  /** 处理
135
- * 是逻辑 是普通
136
- * 父节点 将子节点们插入到 realList 调用 insert 方法挨个插入子节点
137
- * 子节点 将其下 realList 插入到父节点 将本节点插入父节点
252
+ * 是逻辑 是普通
253
+ * 父节点 将子节点加入 directList 调用 insert 方法挨个插入子节点
254
+ * 子节点 仅插入到父逻辑节点 将本节点插入父节点
255
+ * 理论上父节点不能是一个 逻辑节点,遇到if 时 Terp 会重新执行 program 这种情况下,会指定 root 为真实 dom
138
256
  */
139
- handleInsert(parent, child, prevSibling) {
140
- let insertFn = this.insert.bind(this);
141
- if (parent.__logicType) {
142
- insertFn = (parent2, child2, prevSibling2) => {
143
- parent2.realList.splice(parent2.realList.indexOf(prevSibling2) + 1, 0, child2);
144
- };
145
- }
146
- if (child.__logicType) {
147
- const realList = child.realList;
148
- for (let i = realList.length; i--; ) {
149
- const item = realList[i];
150
- insertFn(parent, item, prevSibling);
257
+ handleInsert(parent, child, prev, parentComponent) {
258
+ if (!child.__logicType) {
259
+ if (!prev || !prev.__logicType) {
260
+ this.insertAfter(parent, child, prev);
261
+ } else {
262
+ const before = prev.realAfter;
263
+ this.insertAfter(parent, child, before);
151
264
  }
152
265
  } else {
153
- insertFn(parent, child, prevSibling);
154
- }
155
- }
156
- /**
157
- * @deprecated
158
- * 节点列表:
159
- * 可以是一个节点,也可以跟随更多节点
160
- * <nodeList> ::= <node> <nodeList> <EOF|Dedent>
161
- * |
162
- */
163
- nodeList(parent) {
164
- let _node;
165
- let prevSibling;
166
- let prevItem;
167
- while (1) {
168
- if (this.tokenizer.isEof()) {
169
- return;
170
- }
171
- if (this.tokenizer.token.type & TokenType.Dedent) {
172
- this.tokenizer.consume();
173
- return;
174
- }
175
- _node = this.node();
176
- const insert = parent.__logicType ? this.defaultInsert : this.insert.bind(this);
177
- parent.__logicType ? this.defaultRemove : this.remove.bind(this);
178
- if (!_node.__logicType) {
179
- const realPrev = this.getPrevRealSibling(prevSibling);
180
- const currItem = insert(parent, _node, realPrev, prevItem);
181
- prevItem = currItem;
182
- prevSibling = _node;
183
- continue;
184
- }
185
- if (prevSibling) {
186
- _node.anchor = prevSibling;
187
- } else if (parent.__logicType) {
188
- _node.anchor = parent;
189
- } else ;
190
- if (_node.child && _node.condition()) {
191
- let item = _node.child;
192
- while (item != null) {
193
- const { value: child } = item;
194
- const realPrev = this.getPrevRealSibling(prevSibling);
195
- const currItem = insert(parent, child, realPrev, prevItem);
196
- item = item.next;
197
- prevItem = currItem;
198
- prevSibling = child;
199
- }
266
+ const childCmp = child;
267
+ childCmp.realParent = parent;
268
+ if (prev.__logicType) {
269
+ childCmp.realBefore = prev.realAfter;
270
+ } else {
271
+ childCmp.realBefore = prev;
200
272
  }
201
273
  }
202
274
  }
@@ -213,33 +285,20 @@
213
285
  point = point.anchor;
214
286
  }
215
287
  }
216
- /**
217
- * 单个节点:
218
- * 由声明部分和(可选的)子节点块组成
219
- * <node> ::= <declaration> <childrenBlockOpt>
220
- * */
221
- node() {
222
- const _declaration = this.declaration();
223
- if (_declaration.__logicType & LogicType.If && !_declaration.condition()) {
224
- return _declaration;
225
- }
226
- this.childrenBlockOpt(_declaration);
227
- return _declaration;
228
- }
229
288
  /**
230
289
  * 声明部分:
231
290
  * 包含首行定义和(可选的)多行属性扩展
232
291
  * <declaration> ::= <tagName=token> <headerLine> <extensionLines>
233
292
  * */
234
- declaration() {
293
+ declaration(ctx) {
235
294
  const [hookType, value] = this._hook({});
236
295
  let _node;
237
296
  if (value === "if") {
238
- return this.ifDeclaration();
297
+ return this.ifDeclaration(ctx);
239
298
  } else if (hookType) {
240
299
  if (hookType === "static") {
241
300
  if (typeof value === "function" && value.prototype instanceof aoye.Store) {
242
- _node = this.componentDeclaration(value);
301
+ _node = this.componentDeclaration(value, ctx);
243
302
  } else if (typeof value === "function") {
244
303
  _node = this.fragmentDeclaration(value);
245
304
  } else {
@@ -266,8 +325,7 @@
266
325
  fragmentDeclaration(renderFragment) {
267
326
  const fragmentNode = {
268
327
  __logicType: LogicType.Fragment,
269
- directList: [],
270
- realList: []
328
+ realParent: null
271
329
  };
272
330
  renderFragment.call(this.data, this.opt, { data: this.data, root: "", anchor: "" });
273
331
  return fragmentNode;
@@ -295,7 +353,7 @@
295
353
  this.setProp(node, key, value, hookI);
296
354
  }
297
355
  }
298
- componentDeclaration(Component) {
356
+ componentDeclaration(Component, ctx) {
299
357
  const child = Component.new();
300
358
  const prevOnePropParsed = this.onePropParsed;
301
359
  this.onePropParsed = (node, key, value, valueIsMapKey, hookI) => {
@@ -310,36 +368,66 @@
310
368
  child[aoye.Keys.Raw][key] = value;
311
369
  }
312
370
  };
371
+ const afterAnchor = this.insertAfterAnchor(ctx);
313
372
  tap.once(TerpEvt.AllAttrGot, () => {
373
+ const parent = ctx.realParent;
374
+ const prev = ctx.prevSibling;
314
375
  this.onePropParsed = prevOnePropParsed;
315
- const root = child["ui"](this.opt, { data: child });
316
- tap.emit(TerpEvt.HandledComponentNode, root);
376
+ const componentNode = child["ui"](this.opt, { data: child }, parent, prev);
377
+ componentNode.realAfter = afterAnchor;
378
+ tap.emit(TerpEvt.HandledComponentNode, componentNode);
317
379
  });
318
380
  return { __logicType: LogicType.Component };
319
381
  }
320
- ifDeclaration() {
382
+ ifDeclaration(ctx) {
321
383
  this.tokenizer.consume();
322
- const [isHook, value] = this._hook({});
384
+ const [hookType, value] = this._hook({});
323
385
  const ifNode = {
324
386
  __logicType: LogicType.If,
325
- condition: value,
326
- directList: [],
327
- realList: [],
328
387
  snapshot: this.tokenizer.snapshot(),
388
+ condition: null,
389
+ realParent: null,
329
390
  isFirstRender: true,
330
- watcher: null,
331
- anchor: null
391
+ effect: null
332
392
  };
333
- ifNode.watcher = aoye.effect(
393
+ const valueIsMapKey = Reflect.has(this.data[aoye.Keys.Raw], value);
394
+ let signal;
395
+ if (valueIsMapKey) {
396
+ aoye.runWithPulling(() => this.data[value], null);
397
+ const { cells } = this.data[aoye.Keys.Meta];
398
+ signal = cells.get(value);
399
+ } else {
400
+ const fn = new Function("data", `let v;with(data){v=${value}};return v;`).bind(void 0, this.data);
401
+ signal = aoye.$(fn);
402
+ }
403
+ ifNode.condition = signal;
404
+ ifNode.realAfter = this.insertAfterAnchor(ctx);
405
+ ifNode.effect = aoye.effect(
334
406
  ({ val }) => {
335
407
  if (val) {
336
- this.tokenizer.consume();
337
- this.tokenizer.consume();
408
+ if (ifNode.isFirstRender) {
409
+ this.tokenizer.consume();
410
+ this.tokenizer.consume();
411
+ } else {
412
+ this.tokenizer.resume(ifNode.snapshot);
413
+ this.program(ifNode.realParent, ifNode.realBefore);
414
+ }
338
415
  } else {
339
- this.tokenizer.skip();
416
+ if (ifNode.isFirstRender) {
417
+ this.tokenizer.skip();
418
+ } else {
419
+ const { realBefore, realAfter, realParent } = ifNode;
420
+ let point = this.nextSib(realBefore);
421
+ while (point !== realAfter) {
422
+ const next = this.nextSib(point);
423
+ this.remove(point, realParent, realBefore);
424
+ point = next;
425
+ }
426
+ }
340
427
  }
428
+ ifNode.isFirstRender = false;
341
429
  },
342
- [value]
430
+ [signal]
343
431
  );
344
432
  return ifNode;
345
433
  }
@@ -403,19 +491,6 @@
403
491
  this.tokenizer.consume();
404
492
  }
405
493
  }
406
- /** 子节点块:
407
- * 必须被缩进包裹
408
- * <childrenBlockOpt> ::= INDENT <nodeList>
409
- * | ε /* 空(表示叶子节点,没有孩子)
410
- * */
411
- childrenBlockOpt(parent) {
412
- if (!(this.tokenizer.token.type & TokenType.Indent)) {
413
- return [];
414
- }
415
- this.tokenizer.consume();
416
- const list = this.nodeList(parent);
417
- return list;
418
- }
419
494
  config(opt) {
420
495
  Object.assign(this, opt);
421
496
  this.opt = opt;
@@ -423,28 +498,47 @@
423
498
  createNode(name) {
424
499
  return {
425
500
  name,
426
- props: {}
501
+ props: {},
502
+ nextSibling: null
427
503
  };
428
504
  }
429
- insert(parent, node, prevSibling, prevItem) {
430
- return this.defaultInsert(parent, node, prevSibling, prevItem);
505
+ nextSib(node) {
506
+ return node.nextSibling;
431
507
  }
432
- defaultInsert(parent, node, prevSibling, prevItem) {
433
- if (prevSibling) {
434
- const children = parent.children;
435
- const insertI = children.findIndex((item) => item === prevSibling);
436
- children.splice(insertI + 1, 0, node);
508
+ _createAnchor() {
509
+ const anchor = this.createAnchor();
510
+ anchor[IsAnchor] = true;
511
+ return anchor;
512
+ }
513
+ createAnchor() {
514
+ return {
515
+ name: "anchor",
516
+ nextSibling: null
517
+ };
518
+ }
519
+ insertAfter(parent, node, prev) {
520
+ return this.defaultInsert(parent, node, prev);
521
+ }
522
+ defaultInsert(parent, node, prev) {
523
+ if (prev) {
524
+ const next = prev.nextSibling;
525
+ prev.nextSibling = node;
526
+ node.nextSibling = next;
437
527
  } else {
438
- parent.children = [node];
528
+ parent.firstChild = node;
439
529
  }
440
530
  }
441
- remove(parent, node, prevSibling, prevItem) {
442
- return this.defaultRemove(parent, node, prevSibling, prevItem);
531
+ remove(node, parent, prev) {
532
+ return this.defaultRemove(node, parent, prev);
443
533
  }
444
534
  // TODO: 默认改成 prevItem
445
- defaultRemove(parent, node, prevSibling, prevItem) {
446
- if (parent.children) {
447
- parent.children.splice(parent.children.indexOf(node), 1);
535
+ defaultRemove(node, parent, prevSibling) {
536
+ const next = node.nextSibling;
537
+ if (prevSibling) {
538
+ prevSibling.nextSibling = next;
539
+ }
540
+ if (parent.firstChild === node) {
541
+ parent.firstChild = next;
448
542
  }
449
543
  }
450
544
  setProp(node, key, value, hookI) {
@@ -464,7 +558,496 @@
464
558
  }
465
559
  }
466
560
 
467
- exports.Terp = Terp;
561
+ const _Tokenizer = class _Tokenizer {
562
+ constructor() {
563
+ /** 缩进大小 默认 2 */
564
+ this.TabSize = 2;
565
+ /** 缩进字符 */
566
+ this.Tab = Array.from({ length: this.TabSize }, () => " ").join("");
567
+ /** 匹配标识符 */
568
+ this.IdExp = /[\d\w\/]/;
569
+ /** 回车后需要判断缩进 */
570
+ this.needIndent = false;
571
+ /** 用于跳过第一个节点前的空白字符串,以及生成基础缩进 */
572
+ this.isFirstToken = true;
573
+ /** 记录历史缩进的长度,相对于行首 */
574
+ this.dentStack = [0];
575
+ /** 当前字符 index */
576
+ this.i = 0;
577
+ this.handledTokens = [];
578
+ /**
579
+ * 有些标识符能产生多个 token
580
+ * 例如 dedent
581
+ * parent1
582
+ * child
583
+ * subChild
584
+ * parent2 <- 产生两个 dedent
585
+ */
586
+ this.waitingTokens = new bobeShared.Queue();
587
+ }
588
+ consume() {
589
+ const token = this.token;
590
+ this.nextToken();
591
+ return token;
592
+ }
593
+ // /** 恢复至某一个现场,进行 token 重算 */
594
+ resume(_snapshot) {
595
+ this.token = void 0;
596
+ this.needIndent = false;
597
+ this.isFirstToken = true;
598
+ this.dentStack = [0];
599
+ Object.assign(this, _snapshot);
600
+ }
601
+ snapshot() {
602
+ return {
603
+ i: this.i,
604
+ waitingTokens: this.waitingTokens.clone()
605
+ };
606
+ }
607
+ skip() {
608
+ const logicDentLen = this.dentStack[this.dentStack.length - 1];
609
+ let needIndent = false;
610
+ let skipFragment = ``;
611
+ this.token = void 0;
612
+ while (1) {
613
+ const char = this.char;
614
+ if (char === "\n") {
615
+ needIndent = true;
616
+ skipFragment += char;
617
+ this.next();
618
+ continue;
619
+ }
620
+ if (!needIndent) {
621
+ skipFragment += char;
622
+ this.next();
623
+ continue;
624
+ }
625
+ needIndent = false;
626
+ const { value, isEmptyLine } = this.getDentValue();
627
+ const currLen = value.length;
628
+ if (isEmptyLine) continue;
629
+ if (currLen > logicDentLen) {
630
+ skipFragment += value;
631
+ } else {
632
+ for (let i = this.dentStack.length - 1; i >= 0; i--) {
633
+ const expLen = this.dentStack[i];
634
+ if (currLen === expLen) break;
635
+ if (currLen > expLen) {
636
+ throw SyntaxError(`\u7F29\u8FDB\u9519\u8BEF\uFF0C\u7F29\u8FDB\u957F\u5EA6\u4E0D\u5339\u914D`);
637
+ }
638
+ if (this.shorterThanBaseDentEof()) {
639
+ break;
640
+ }
641
+ this.dentStack.pop();
642
+ if (!this.token) {
643
+ this.setToken(TokenType.Dedent, String(expLen));
644
+ } else {
645
+ this.waitingTokens.push({
646
+ type: TokenType.Dedent,
647
+ typeName: TokenType[TokenType.Dedent],
648
+ value: String(expLen)
649
+ });
650
+ }
651
+ }
652
+ break;
653
+ }
654
+ }
655
+ if (!this.token) {
656
+ this.nextToken();
657
+ }
658
+ return skipFragment;
659
+ }
660
+ setCode(code) {
661
+ this.code = "\n" + code.trimEnd() + `
662
+ ${_Tokenizer.EofId}`;
663
+ }
664
+ tokenize() {
665
+ var _a, _b;
666
+ do {
667
+ this.nextToken();
668
+ console.log("token:", TokenType[(_a = this.token) == null ? void 0 : _a.type], JSON.stringify(((_b = this.token) == null ? void 0 : _b.value) || ""));
669
+ } while (!this.isEof());
670
+ }
671
+ isEof() {
672
+ if (!this.token) return false;
673
+ return this.token.type & TokenType.Identifier && this.token.value === _Tokenizer.EofId;
674
+ }
675
+ get char() {
676
+ return this.code[this.i];
677
+ }
678
+ get prev() {
679
+ return this.code[this.i - 1];
680
+ }
681
+ get after() {
682
+ return this.code[this.i + 1];
683
+ }
684
+ next() {
685
+ const prev = this.code[this.i];
686
+ this.i++;
687
+ const curr = this.code[this.i];
688
+ return [prev, curr];
689
+ }
690
+ setToken(type, value) {
691
+ this.token = {
692
+ type,
693
+ typeName: TokenType[type],
694
+ value
695
+ };
696
+ this.isFirstToken = false;
697
+ }
698
+ testId(value) {
699
+ if (typeof value !== "string") return false;
700
+ return this.IdExp.test(value);
701
+ }
702
+ nextToken() {
703
+ try {
704
+ if (this.isEof()) {
705
+ return this.token;
706
+ }
707
+ this.token = void 0;
708
+ if (this.waitingTokens.len) {
709
+ const item = this.waitingTokens.shift();
710
+ this.setToken(item.type, item.value);
711
+ return this.token;
712
+ }
713
+ outer: while (1) {
714
+ if (this.needIndent) {
715
+ this.dent();
716
+ } else {
717
+ let { char } = this;
718
+ switch (char) {
719
+ case " ":
720
+ case " ":
721
+ break;
722
+ // 找后续所有 newLine
723
+ case "\n":
724
+ this.newLine();
725
+ this.needIndent = true;
726
+ break;
727
+ case "=":
728
+ this.assignment();
729
+ break;
730
+ case "|":
731
+ this.pipe();
732
+ break;
733
+ case "'":
734
+ case '"':
735
+ this.str(char);
736
+ break;
737
+ case "{":
738
+ this.brace();
739
+ break;
740
+ case "$":
741
+ const handled = this.dynamic(char);
742
+ if (handled) break;
743
+ default:
744
+ if (bobeShared.isNum(char)) {
745
+ this.number(char);
746
+ break;
747
+ }
748
+ if (this.testId(char)) {
749
+ this.identifier(char);
750
+ }
751
+ break;
752
+ }
753
+ this.next();
754
+ }
755
+ if (this.token) {
756
+ break;
757
+ }
758
+ }
759
+ return this.token;
760
+ } catch (error) {
761
+ console.error(error);
762
+ } finally {
763
+ this.handledTokens.push(this.token);
764
+ }
765
+ }
766
+ assignment() {
767
+ this.setToken(TokenType.Assign, "=");
768
+ }
769
+ pipe() {
770
+ this.setToken(TokenType.Pipe, "|");
771
+ }
772
+ dynamic(char) {
773
+ let nextC = this.after;
774
+ if (nextC !== "{") {
775
+ return false;
776
+ }
777
+ this.next();
778
+ let value = "${";
779
+ let innerBrace = 0;
780
+ while (1) {
781
+ nextC = this.after;
782
+ value += nextC;
783
+ this.next();
784
+ if (nextC === "{") {
785
+ innerBrace++;
786
+ }
787
+ if (nextC === "}") {
788
+ if (!innerBrace) {
789
+ break;
790
+ }
791
+ innerBrace--;
792
+ }
793
+ }
794
+ this.setToken(TokenType.Identifier, value);
795
+ return true;
796
+ }
797
+ brace() {
798
+ let inComment, inString, count = 0, value = "", backslashCount = 0;
799
+ while (1) {
800
+ const char = this.char;
801
+ const nextChar = this.after;
802
+ if (inComment === "single" && char === "\n") {
803
+ inComment = null;
804
+ } else if (inComment === "multi" && char === "*" && nextChar === "/") {
805
+ inComment = null;
806
+ value += this.next()[0];
807
+ } else if (inString) {
808
+ if (char === inString && backslashCount % 2 === 0) {
809
+ inString = null;
810
+ }
811
+ backslashCount = char === "\\" ? backslashCount + 1 : 0;
812
+ } else {
813
+ if (char === "/" && nextChar === "/") {
814
+ inComment = "single";
815
+ value += this.next()[0];
816
+ } else if (char === "/" && nextChar === "*") {
817
+ inComment = "multi";
818
+ value += this.next()[0];
819
+ } else if (char === "'" || char === '"' || char === "`") {
820
+ inString = char;
821
+ } else if (char === "{") {
822
+ count++;
823
+ } else if (char === "}") {
824
+ count--;
825
+ }
826
+ }
827
+ if (count === 0 && inString == null && inComment == null) {
828
+ this.setToken(TokenType.InsertionExp, value.slice(1));
829
+ return;
830
+ }
831
+ value += this.next()[0];
832
+ }
833
+ }
834
+ newLine() {
835
+ let value = "\n";
836
+ let nextC;
837
+ while (1) {
838
+ nextC = this.after;
839
+ if (nextC !== "\n") {
840
+ break;
841
+ }
842
+ value += nextC;
843
+ this.next();
844
+ }
845
+ if (this.isFirstToken) {
846
+ return;
847
+ }
848
+ this.setToken(TokenType.NewLine, value);
849
+ }
850
+ getDentValue() {
851
+ let value = "";
852
+ let nextC;
853
+ let isEmptyLine = false;
854
+ while (1) {
855
+ const nextChar = this.char;
856
+ switch (nextChar) {
857
+ case " ":
858
+ nextC = this.Tab;
859
+ break;
860
+ case " ":
861
+ nextC = " ";
862
+ break;
863
+ case "\n":
864
+ nextC = "\n";
865
+ break;
866
+ default:
867
+ nextC = "";
868
+ break;
869
+ }
870
+ if (nextC === "\n") {
871
+ isEmptyLine = true;
872
+ break;
873
+ }
874
+ if (!nextC) {
875
+ break;
876
+ }
877
+ value += nextC;
878
+ this.next();
879
+ }
880
+ return {
881
+ value,
882
+ isEmptyLine
883
+ };
884
+ }
885
+ dent() {
886
+ const { value, isEmptyLine } = this.getDentValue();
887
+ if (isEmptyLine) {
888
+ this.needIndent = true;
889
+ return;
890
+ }
891
+ this.needIndent = false;
892
+ if (this.isFirstToken) {
893
+ this.dentStack[0] = value.length;
894
+ return;
895
+ }
896
+ let currLen = value.length;
897
+ const indentHasLen = currLen > 0;
898
+ const prevLen = this.dentStack[this.dentStack.length - 1];
899
+ if (currLen > prevLen) {
900
+ this.dentStack.push(currLen);
901
+ this.setToken(TokenType.Indent, String(currLen));
902
+ return indentHasLen;
903
+ }
904
+ if (currLen < prevLen) {
905
+ for (let i = this.dentStack.length; i--; ) {
906
+ const expLen = this.dentStack[i];
907
+ if (currLen === expLen) break;
908
+ if (currLen > expLen) {
909
+ throw SyntaxError("\u7F29\u8FDB\u5927\u5C0F\u4E0D\u7EDF\u4E00");
910
+ }
911
+ if (this.shorterThanBaseDentEof()) {
912
+ return;
913
+ }
914
+ this.dentStack.pop();
915
+ if (!this.token) {
916
+ this.setToken(TokenType.Dedent, String(expLen));
917
+ } else {
918
+ this.waitingTokens.push({
919
+ type: TokenType.Dedent,
920
+ typeName: TokenType[TokenType.Dedent],
921
+ value: String(expLen)
922
+ });
923
+ }
924
+ }
925
+ return indentHasLen;
926
+ }
927
+ return indentHasLen;
928
+ }
929
+ shorterThanBaseDentEof() {
930
+ const yes = this.dentStack.length === 1;
931
+ if (yes) {
932
+ if (!this.token) {
933
+ this.setToken(TokenType.Identifier, _Tokenizer.EofId);
934
+ } else {
935
+ this.waitingTokens.push({
936
+ type: TokenType.Identifier,
937
+ typeName: TokenType[TokenType.Identifier],
938
+ value: _Tokenizer.EofId
939
+ });
940
+ }
941
+ }
942
+ return yes;
943
+ }
944
+ identifier(char) {
945
+ let value = char;
946
+ let nextC;
947
+ while (1) {
948
+ nextC = this.after;
949
+ if (!this.testId(nextC)) {
950
+ break;
951
+ }
952
+ value += nextC;
953
+ this.next();
954
+ }
955
+ let realValue = value === "null" ? null : value === "undefined" ? void 0 : value === "false" ? false : value === "true" ? true : value;
956
+ this.setToken(TokenType.Identifier, realValue);
957
+ }
958
+ str(char) {
959
+ let value = '"';
960
+ let nextC;
961
+ let continuousBackslashCount = 0;
962
+ while (1) {
963
+ nextC = this.after;
964
+ value += nextC;
965
+ const memoCount = continuousBackslashCount;
966
+ if (nextC === "\\") {
967
+ continuousBackslashCount++;
968
+ } else {
969
+ continuousBackslashCount = 0;
970
+ }
971
+ this.next();
972
+ if (nextC === char && memoCount % 2 === 0) {
973
+ break;
974
+ }
975
+ }
976
+ this.setToken(TokenType.Identifier, JSON.parse(value.slice(0, -1) + '"'));
977
+ }
978
+ number(char) {
979
+ let value = char;
980
+ let nextC;
981
+ while (1) {
982
+ nextC = this.after;
983
+ if (!bobeShared.isNum(nextC)) {
984
+ break;
985
+ }
986
+ value += nextC;
987
+ this.next();
988
+ }
989
+ this.setToken(TokenType.Identifier, Number(value));
990
+ }
991
+ eof() {
992
+ this.setToken(TokenType.Eof, "End Of File");
993
+ }
994
+ };
995
+ /** Eof 标识符的值 */
996
+ _Tokenizer.EofId = `__EOF__${Date.now()}`;
997
+ let Tokenizer = _Tokenizer;
998
+
999
+ var __defProp = Object.defineProperty;
1000
+ var __defProps = Object.defineProperties;
1001
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
1002
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
1003
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
1004
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
1005
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1006
+ var __spreadValues = (a, b) => {
1007
+ for (var prop in b || (b = {}))
1008
+ if (__hasOwnProp.call(b, prop))
1009
+ __defNormalProp(a, prop, b[prop]);
1010
+ if (__getOwnPropSymbols)
1011
+ for (var prop of __getOwnPropSymbols(b)) {
1012
+ if (__propIsEnum.call(b, prop))
1013
+ __defNormalProp(a, prop, b[prop]);
1014
+ }
1015
+ return a;
1016
+ };
1017
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
1018
+ function bobe(fragments, ...values) {
1019
+ const ui = function ui2(options, valueOpt, root, before) {
1020
+ const tokenizer = new Tokenizer();
1021
+ const cmp = new Interpreter(tokenizer);
1022
+ Object.assign(cmp, valueOpt);
1023
+ cmp.config(__spreadProps(__spreadValues({}, options), {
1024
+ hook({ i }) {
1025
+ return values[i];
1026
+ },
1027
+ setProp(node, key, value, hookI) {
1028
+ node.props[key] = value;
1029
+ }
1030
+ }));
1031
+ cmp.init(Array.from(fragments));
1032
+ return cmp.program(root, before);
1033
+ };
1034
+ return ui;
1035
+ }
1036
+ function customRender(option) {
1037
+ return function render(Ctor, root) {
1038
+ const store = Ctor.new();
1039
+ return [store["ui"](option, { data: store }, root), store];
1040
+ };
1041
+ }
1042
+
1043
+ exports.bobe = bobe;
1044
+ exports.customRender = customRender;
1045
+ Object.keys(aoye).forEach(function (k) {
1046
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
1047
+ enumerable: true,
1048
+ get: function () { return aoye[k]; }
1049
+ });
1050
+ });
468
1051
 
469
1052
  }));
470
1053
  //# sourceMappingURL=index.umd.js.map