bobe 0.0.10 → 0.0.11

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.esm.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { Store, Keys, effect, shareSignal, $ } from 'aoye';
2
- import { BaseEvent } from 'bobe-shared';
2
+ export * from 'aoye';
3
+ import { BaseEvent, Queue, isNum } from 'bobe-shared';
3
4
 
4
5
  var TokenType = /* @__PURE__ */ ((TokenType2) => {
5
6
  TokenType2[TokenType2["NewLine"] = 1] = "NewLine";
@@ -28,27 +29,27 @@ var TerpEvt = /* @__PURE__ */ ((TerpEvt2) => {
28
29
  return TerpEvt2;
29
30
  })(TerpEvt || {});
30
31
 
31
- var __defProp = Object.defineProperty;
32
- var __defProps = Object.defineProperties;
33
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
34
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
35
- var __hasOwnProp = Object.prototype.hasOwnProperty;
36
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
37
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
38
- var __spreadValues = (a, b) => {
32
+ var __defProp$1 = Object.defineProperty;
33
+ var __defProps$1 = Object.defineProperties;
34
+ var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
35
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
36
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
37
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
38
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
39
+ var __spreadValues$1 = (a, b) => {
39
40
  for (var prop in b || (b = {}))
40
- if (__hasOwnProp.call(b, prop))
41
- __defNormalProp(a, prop, b[prop]);
42
- if (__getOwnPropSymbols)
43
- for (var prop of __getOwnPropSymbols(b)) {
44
- if (__propIsEnum.call(b, prop))
45
- __defNormalProp(a, prop, b[prop]);
41
+ if (__hasOwnProp$1.call(b, prop))
42
+ __defNormalProp$1(a, prop, b[prop]);
43
+ if (__getOwnPropSymbols$1)
44
+ for (var prop of __getOwnPropSymbols$1(b)) {
45
+ if (__propIsEnum$1.call(b, prop))
46
+ __defNormalProp$1(a, prop, b[prop]);
46
47
  }
47
48
  return a;
48
49
  };
49
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
50
+ var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
50
51
  const tap = new BaseEvent();
51
- class Terp {
52
+ class Interpreter {
52
53
  constructor(tokenizer) {
53
54
  this.tokenizer = tokenizer;
54
55
  /** 模板字符串动态节点的占位符 */
@@ -57,7 +58,6 @@ class Terp {
57
58
  this.data = {};
58
59
  /** 模板字符串动态节点索引 */
59
60
  this.hookI = 0;
60
- this.stack = [];
61
61
  this._hook = (props) => {
62
62
  const value = this.tokenizer.token.value;
63
63
  const isDynamicHook = this.tokenizer.token.type & TokenType.InsertionExp;
@@ -65,7 +65,7 @@ class Terp {
65
65
  const hookType = isDynamicHook ? "dynamic" : isStaticHook ? "static" : void 0;
66
66
  if (this.hook && isStaticHook) {
67
67
  const hookI = Number(value.slice(this.HookId.length));
68
- const res = this.hook(__spreadProps(__spreadValues({}, props), {
68
+ const res = this.hook(__spreadProps$1(__spreadValues$1({}, props), {
69
69
  HookId: this.HookId,
70
70
  i: hookI
71
71
  }));
@@ -81,119 +81,89 @@ class Terp {
81
81
  // root: any;
82
82
  // /** program 挂载的前置节点 */
83
83
  // anchor: any;
84
- program() {
85
- const root = {
84
+ program(root, before) {
85
+ const componentNode = {
86
86
  __logicType: LogicType.Component,
87
- store: this.data,
88
- realList: [],
89
- directList: []
87
+ realParent: root,
88
+ store: new Store()
90
89
  };
91
90
  this.tokenizer.consume();
91
+ let prevSibling = null;
92
92
  let current;
93
- let prevSibling;
94
- this.stack = [{ node: root, prevSibling }];
93
+ const stack = [{ node: root, prev: prevSibling }];
95
94
  while (1) {
96
95
  if (this.tokenizer.isEof()) {
97
- this.handleInsert(root, current, root.realList[root.realList.length - 1]);
96
+ this.handleInsert(root, current, prevSibling, componentNode);
98
97
  break;
99
98
  }
100
99
  const token = this.tokenizer.token;
101
100
  if (token.type & TokenType.Indent) {
102
101
  this.tokenizer.consume();
103
- this.stack.push({
104
- prevSibling,
105
- node: current
102
+ stack.push({
103
+ node: current,
104
+ prev: prevSibling
106
105
  });
106
+ current = this.declaration({ stack, prevSibling });
107
107
  prevSibling = null;
108
- current = this.declaration();
109
108
  continue;
110
109
  }
111
110
  if (current) {
112
- if (this.stack.length > 1) {
113
- const parent = this.stack[this.stack.length - 1].node;
111
+ if (stack.length > 1) {
112
+ const { node: parent } = stack[stack.length - 1];
114
113
  this.handleInsert(parent, current, prevSibling);
115
114
  } else {
116
- this.handleInsert(root, current, prevSibling);
115
+ if (!prevSibling) {
116
+ prevSibling = before;
117
+ }
118
+ this.handleInsert(root, current, prevSibling, componentNode);
117
119
  }
118
120
  }
119
121
  if (this.tokenizer.token.type & TokenType.Dedent) {
120
122
  this.tokenizer.consume();
121
- const { node: parent, prevSibling: prevParent } = this.stack.pop();
122
- prevSibling = prevParent;
123
+ const { node: parent, prev } = stack.pop();
124
+ prevSibling = prev;
123
125
  current = parent;
124
126
  } else {
125
127
  prevSibling = current;
126
- current = this.declaration();
128
+ current = this.declaration({ stack, prevSibling });
127
129
  }
128
130
  }
129
- return root;
131
+ componentNode.lastInserted = this.lastInserted;
132
+ this.lastInserted = null;
133
+ return componentNode;
130
134
  }
131
135
  /** 处理
132
- * 是逻辑 是普通
133
- * 父节点 将子节点们插入到 realList 调用 insert 方法挨个插入子节点
134
- * 子节点 将其下 realList 插入到父节点 将本节点插入父节点
136
+ * 是逻辑 是普通
137
+ * 父节点 将子节点加入 directList 调用 insert 方法挨个插入子节点
138
+ * 子节点 仅插入到父逻辑节点 将本节点插入父节点
139
+ * 理论上父节点不能是一个 逻辑节点,遇到if 时 Terp 会重新执行 program 这种情况下,会指定 root 为真实 dom
135
140
  */
136
- handleInsert(parent, child, prevSibling) {
137
- let insertFn = this.insert.bind(this);
138
- if (parent.__logicType) {
139
- insertFn = (parent2, child2, prevSibling2) => {
140
- parent2.realList.splice(parent2.realList.indexOf(prevSibling2) + 1, 0, child2);
141
- };
142
- }
143
- if (child.__logicType) {
144
- const realList = child.realList;
145
- for (let i = realList.length; i--; ) {
146
- const item = realList[i];
147
- insertFn(parent, item, prevSibling);
141
+ handleInsert(parent, child, prev, parentComponent) {
142
+ if (!child.__logicType) {
143
+ if (!prev || !prev.__logicType) {
144
+ this.insertAfter(parent, child, prev);
145
+ } else {
146
+ const before = prev.lastInserted;
147
+ this.insertAfter(parent, child, before);
148
+ prev.realAfter = child;
148
149
  }
149
150
  } else {
150
- insertFn(parent, child, prevSibling);
151
- }
152
- }
153
- /**
154
- * @deprecated
155
- * 节点列表:
156
- * 可以是一个节点,也可以跟随更多节点
157
- * <nodeList> ::= <node> <nodeList> <EOF|Dedent>
158
- * |
159
- */
160
- nodeList(parent) {
161
- let _node;
162
- let prevSibling;
163
- let prevItem;
164
- while (1) {
165
- if (this.tokenizer.isEof()) {
166
- return;
167
- }
168
- if (this.tokenizer.token.type & TokenType.Dedent) {
169
- this.tokenizer.consume();
170
- return;
171
- }
172
- _node = this.node();
173
- const insert = parent.__logicType ? this.defaultInsert : this.insert.bind(this);
174
- parent.__logicType ? this.defaultRemove : this.remove.bind(this);
175
- if (!_node.__logicType) {
176
- const realPrev = this.getPrevRealSibling(prevSibling);
177
- const currItem = insert(parent, _node, realPrev, prevItem);
178
- prevItem = currItem;
179
- prevSibling = _node;
180
- continue;
181
- }
182
- if (prevSibling) {
183
- _node.anchor = prevSibling;
184
- } else if (parent.__logicType) {
185
- _node.anchor = parent;
186
- } else ;
187
- if (_node.child && _node.condition()) {
188
- let item = _node.child;
189
- while (item != null) {
190
- const { value: child } = item;
191
- const realPrev = this.getPrevRealSibling(prevSibling);
192
- const currItem = insert(parent, child, realPrev, prevItem);
193
- item = item.next;
194
- prevItem = currItem;
195
- prevSibling = child;
196
- }
151
+ const childCmp = child;
152
+ childCmp.realParent = parent;
153
+ if (!prev) {
154
+ const anchor = this.createAnchor();
155
+ this.insertAfter(parent, anchor, prev);
156
+ this.insertAfter(parent, child, anchor);
157
+ childCmp.realBefore = anchor;
158
+ } else if (prev.__logicType) {
159
+ const before = prev.lastInserted;
160
+ const anchor = this.createAnchor();
161
+ this.insertAfter(parent, anchor, before);
162
+ this.insertAfter(parent, child, anchor);
163
+ childCmp.realBefore = anchor;
164
+ prev.realAfter = anchor;
165
+ } else {
166
+ childCmp.realBefore = prev;
197
167
  }
198
168
  }
199
169
  }
@@ -210,25 +180,12 @@ class Terp {
210
180
  point = point.anchor;
211
181
  }
212
182
  }
213
- /**
214
- * 单个节点:
215
- * 由声明部分和(可选的)子节点块组成
216
- * <node> ::= <declaration> <childrenBlockOpt>
217
- * */
218
- node() {
219
- const _declaration = this.declaration();
220
- if (_declaration.__logicType & LogicType.If && !_declaration.condition()) {
221
- return _declaration;
222
- }
223
- this.childrenBlockOpt(_declaration);
224
- return _declaration;
225
- }
226
183
  /**
227
184
  * 声明部分:
228
185
  * 包含首行定义和(可选的)多行属性扩展
229
186
  * <declaration> ::= <tagName=token> <headerLine> <extensionLines>
230
187
  * */
231
- declaration() {
188
+ declaration(ctx) {
232
189
  const [hookType, value] = this._hook({});
233
190
  let _node;
234
191
  if (value === "if") {
@@ -236,7 +193,7 @@ class Terp {
236
193
  } else if (hookType) {
237
194
  if (hookType === "static") {
238
195
  if (typeof value === "function" && value.prototype instanceof Store) {
239
- _node = this.componentDeclaration(value);
196
+ _node = this.componentDeclaration(value, ctx);
240
197
  } else if (typeof value === "function") {
241
198
  _node = this.fragmentDeclaration(value);
242
199
  } else {
@@ -263,8 +220,7 @@ class Terp {
263
220
  fragmentDeclaration(renderFragment) {
264
221
  const fragmentNode = {
265
222
  __logicType: LogicType.Fragment,
266
- directList: [],
267
- realList: []
223
+ realParent: null
268
224
  };
269
225
  renderFragment.call(this.data, this.opt, { data: this.data, root: "", anchor: "" });
270
226
  return fragmentNode;
@@ -292,7 +248,7 @@ class Terp {
292
248
  this.setProp(node, key, value, hookI);
293
249
  }
294
250
  }
295
- componentDeclaration(Component) {
251
+ componentDeclaration(Component, ctx) {
296
252
  const child = Component.new();
297
253
  const prevOnePropParsed = this.onePropParsed;
298
254
  this.onePropParsed = (node, key, value, valueIsMapKey, hookI) => {
@@ -308,9 +264,11 @@ class Terp {
308
264
  }
309
265
  };
310
266
  tap.once(TerpEvt.AllAttrGot, () => {
267
+ const parent = ctx.stack[ctx.stack.length - 1].node;
268
+ const prev = ctx.prevSibling;
311
269
  this.onePropParsed = prevOnePropParsed;
312
- const root = child["ui"](this.opt, { data: child });
313
- tap.emit(TerpEvt.HandledComponentNode, root);
270
+ const componentNode = child["ui"](this.opt, { data: child }, parent, prev);
271
+ tap.emit(TerpEvt.HandledComponentNode, componentNode);
314
272
  });
315
273
  return { __logicType: LogicType.Component };
316
274
  }
@@ -320,8 +278,7 @@ class Terp {
320
278
  const ifNode = {
321
279
  __logicType: LogicType.If,
322
280
  condition: value,
323
- directList: [],
324
- realList: [],
281
+ realParent: null,
325
282
  snapshot: this.tokenizer.snapshot(),
326
283
  isFirstRender: true,
327
284
  watcher: null,
@@ -400,19 +357,6 @@ class Terp {
400
357
  this.tokenizer.consume();
401
358
  }
402
359
  }
403
- /** 子节点块:
404
- * 必须被缩进包裹
405
- * <childrenBlockOpt> ::= INDENT <nodeList>
406
- * | ε /* 空(表示叶子节点,没有孩子)
407
- * */
408
- childrenBlockOpt(parent) {
409
- if (!(this.tokenizer.token.type & TokenType.Indent)) {
410
- return [];
411
- }
412
- this.tokenizer.consume();
413
- const list = this.nodeList(parent);
414
- return list;
415
- }
416
360
  config(opt) {
417
361
  Object.assign(this, opt);
418
362
  this.opt = opt;
@@ -420,28 +364,43 @@ class Terp {
420
364
  createNode(name) {
421
365
  return {
422
366
  name,
423
- props: {}
367
+ props: {},
368
+ nextSibling: null
424
369
  };
425
370
  }
426
- insert(parent, node, prevSibling, prevItem) {
427
- return this.defaultInsert(parent, node, prevSibling, prevItem);
371
+ nextSib(node) {
372
+ return node.nextSibling;
428
373
  }
429
- defaultInsert(parent, node, prevSibling, prevItem) {
430
- if (prevSibling) {
431
- const children = parent.children;
432
- const insertI = children.findIndex((item) => item === prevSibling);
433
- children.splice(insertI + 1, 0, node);
374
+ createAnchor() {
375
+ return {
376
+ name: "anchor",
377
+ nextSibling: null
378
+ };
379
+ }
380
+ insertAfter(parent, node, prev) {
381
+ this.lastInserted = node;
382
+ return this.defaultInsert(parent, node, prev);
383
+ }
384
+ defaultInsert(parent, node, prev) {
385
+ if (prev) {
386
+ const next = prev.nextSibling;
387
+ prev.nextSibling = node;
388
+ node.nextSibling = next;
434
389
  } else {
435
- parent.children = [node];
390
+ parent.firstChild = node;
436
391
  }
437
392
  }
438
- remove(parent, node, prevSibling, prevItem) {
439
- return this.defaultRemove(parent, node, prevSibling, prevItem);
393
+ remove(parent, node, prevSibling) {
394
+ return this.defaultRemove(parent, node, prevSibling);
440
395
  }
441
396
  // TODO: 默认改成 prevItem
442
- defaultRemove(parent, node, prevSibling, prevItem) {
443
- if (parent.children) {
444
- parent.children.splice(parent.children.indexOf(node), 1);
397
+ defaultRemove(parent, node, prevSibling) {
398
+ const next = node.nextSibling;
399
+ if (prevSibling) {
400
+ prevSibling.nextSibling = next;
401
+ }
402
+ if (parent.firstChild === node) {
403
+ parent.firstChild = next;
445
404
  }
446
405
  }
447
406
  setProp(node, key, value, hookI) {
@@ -461,5 +420,469 @@ class Terp {
461
420
  }
462
421
  }
463
422
 
464
- export { Terp };
423
+ const _Tokenizer = class _Tokenizer {
424
+ constructor() {
425
+ /** 缩进大小 默认 2 */
426
+ this.TabSize = 2;
427
+ /** 缩进字符 */
428
+ this.Tab = Array.from({ length: this.TabSize }, () => " ").join("");
429
+ /** 匹配标识符 */
430
+ this.IdExp = /[\d\w\/]/;
431
+ /** 回车后需要判断缩进 */
432
+ this.needIndent = false;
433
+ /** 用于跳过第一个节点前的空白字符串,以及生成基础缩进 */
434
+ this.isFirstToken = true;
435
+ /** 记录历史缩进的长度,相对于行首 */
436
+ this.dentStack = [0];
437
+ /** 当前字符 index */
438
+ this.i = 0;
439
+ this.handledTokens = [];
440
+ /**
441
+ * 有些标识符能产生多个 token
442
+ * 例如 dedent
443
+ * parent1
444
+ * child
445
+ * subChild
446
+ * parent2 <- 产生两个 dedent
447
+ */
448
+ this.waitingTokens = new Queue();
449
+ }
450
+ consume() {
451
+ const token = this.token;
452
+ this.nextToken();
453
+ return token;
454
+ }
455
+ // /** 恢复至某一个现场,进行 token 重算 */
456
+ resume(_snapshot) {
457
+ this.token = void 0;
458
+ this.needIndent = false;
459
+ this.isFirstToken = true;
460
+ this.dentStack = [0];
461
+ Object.assign(this, _snapshot);
462
+ }
463
+ snapshot() {
464
+ return {
465
+ i: this.i,
466
+ waitingTokens: this.waitingTokens.clone()
467
+ };
468
+ }
469
+ skip() {
470
+ const dentLen = this.dentStack[this.dentStack.length - 1];
471
+ let needIndent = false;
472
+ let skipFragment = ``;
473
+ this.token = void 0;
474
+ while (1) {
475
+ const char = this.char;
476
+ if (char === "\n") {
477
+ needIndent = true;
478
+ skipFragment += char;
479
+ this.next();
480
+ continue;
481
+ }
482
+ if (!needIndent) {
483
+ skipFragment += char;
484
+ this.next();
485
+ continue;
486
+ }
487
+ needIndent = false;
488
+ const { value, isEmptyLine } = this.getDentValue();
489
+ const currLen = value.length;
490
+ if (isEmptyLine) continue;
491
+ if (value.length > dentLen) {
492
+ skipFragment += value;
493
+ } else {
494
+ for (let i = this.dentStack.length - 1; i >= 0; i--) {
495
+ const expLen = this.dentStack[i];
496
+ if (currLen === expLen) break;
497
+ if (currLen > expLen) {
498
+ throw SyntaxError(`\u7F29\u8FDB\u9519\u8BEF\uFF0C\u7F29\u8FDB\u957F\u5EA6\u4E0D\u5339\u914D`);
499
+ }
500
+ this.dentStack.pop();
501
+ if (!this.token) {
502
+ this.setToken(TokenType.Dedent, String(expLen));
503
+ } else {
504
+ this.waitingTokens.push({
505
+ type: TokenType.Dedent,
506
+ typeName: TokenType[TokenType.Dedent],
507
+ value: String(expLen)
508
+ });
509
+ }
510
+ }
511
+ break;
512
+ }
513
+ }
514
+ if (!this.token) {
515
+ this.nextToken();
516
+ }
517
+ return skipFragment;
518
+ }
519
+ setCode(code) {
520
+ this.code = "\n" + code.trimEnd() + `
521
+ ${_Tokenizer.EofId}`;
522
+ }
523
+ tokenize() {
524
+ var _a, _b;
525
+ do {
526
+ this.nextToken();
527
+ console.log("token:", TokenType[(_a = this.token) == null ? void 0 : _a.type], JSON.stringify(((_b = this.token) == null ? void 0 : _b.value) || ""));
528
+ } while (!this.isEof());
529
+ }
530
+ isEof() {
531
+ if (!this.token) return false;
532
+ return this.token.type & TokenType.Identifier && this.token.value === _Tokenizer.EofId;
533
+ }
534
+ get char() {
535
+ return this.code[this.i];
536
+ }
537
+ get prev() {
538
+ return this.code[this.i - 1];
539
+ }
540
+ get after() {
541
+ return this.code[this.i + 1];
542
+ }
543
+ next() {
544
+ const prev = this.code[this.i];
545
+ this.i++;
546
+ const curr = this.code[this.i];
547
+ return [prev, curr];
548
+ }
549
+ setToken(type, value) {
550
+ this.token = {
551
+ type,
552
+ typeName: TokenType[type],
553
+ value
554
+ };
555
+ this.isFirstToken = false;
556
+ }
557
+ testId(value) {
558
+ if (typeof value !== "string") return false;
559
+ return this.IdExp.test(value);
560
+ }
561
+ nextToken() {
562
+ try {
563
+ if (this.isEof()) {
564
+ return this.token;
565
+ }
566
+ this.token = void 0;
567
+ if (this.waitingTokens.len) {
568
+ const item = this.waitingTokens.shift();
569
+ this.setToken(item.type, item.value);
570
+ return this.token;
571
+ }
572
+ outer: while (1) {
573
+ if (this.needIndent) {
574
+ this.dent();
575
+ } else {
576
+ let { char } = this;
577
+ switch (char) {
578
+ case " ":
579
+ case " ":
580
+ break;
581
+ // 找后续所有 newLine
582
+ case "\n":
583
+ this.newLine();
584
+ this.needIndent = true;
585
+ break;
586
+ case "=":
587
+ this.assignment();
588
+ break;
589
+ case "|":
590
+ this.pipe();
591
+ break;
592
+ case "'":
593
+ case '"':
594
+ this.str(char);
595
+ break;
596
+ case "{":
597
+ this.brace();
598
+ break;
599
+ case "$":
600
+ const handled = this.dynamic(char);
601
+ if (handled) break;
602
+ default:
603
+ if (isNum(char)) {
604
+ this.number(char);
605
+ break;
606
+ }
607
+ if (this.testId(char)) {
608
+ this.identifier(char);
609
+ }
610
+ break;
611
+ }
612
+ this.next();
613
+ }
614
+ if (this.token) {
615
+ break;
616
+ }
617
+ }
618
+ return this.token;
619
+ } catch (error) {
620
+ console.error(error);
621
+ } finally {
622
+ this.handledTokens.push(this.token);
623
+ }
624
+ }
625
+ assignment() {
626
+ this.setToken(TokenType.Assign, "=");
627
+ }
628
+ pipe() {
629
+ this.setToken(TokenType.Pipe, "|");
630
+ }
631
+ dynamic(char) {
632
+ let nextC = this.after;
633
+ if (nextC !== "{") {
634
+ return false;
635
+ }
636
+ this.next();
637
+ let value = "${";
638
+ let innerBrace = 0;
639
+ while (1) {
640
+ nextC = this.after;
641
+ value += nextC;
642
+ this.next();
643
+ if (nextC === "{") {
644
+ innerBrace++;
645
+ }
646
+ if (nextC === "}") {
647
+ if (!innerBrace) {
648
+ break;
649
+ }
650
+ innerBrace--;
651
+ }
652
+ }
653
+ this.setToken(TokenType.Identifier, value);
654
+ return true;
655
+ }
656
+ brace() {
657
+ let inComment, inString, count = 0, value = "", backslashCount = 0;
658
+ while (1) {
659
+ const char = this.char;
660
+ const nextChar = this.after;
661
+ if (inComment === "single" && char === "\n") {
662
+ inComment = null;
663
+ } else if (inComment === "multi" && char === "*" && nextChar === "/") {
664
+ inComment = null;
665
+ value += this.next()[0];
666
+ } else if (inString) {
667
+ if (char === inString && backslashCount % 2 === 0) {
668
+ inString = null;
669
+ }
670
+ backslashCount = char === "\\" ? backslashCount + 1 : 0;
671
+ } else {
672
+ if (char === "/" && nextChar === "/") {
673
+ inComment = "single";
674
+ value += this.next()[0];
675
+ } else if (char === "/" && nextChar === "*") {
676
+ inComment = "multi";
677
+ value += this.next()[0];
678
+ } else if (char === "'" || char === '"' || char === "`") {
679
+ inString = char;
680
+ } else if (char === "{") {
681
+ count++;
682
+ } else if (char === "}") {
683
+ count--;
684
+ }
685
+ }
686
+ if (count === 0 && inString == null && inComment == null) {
687
+ this.setToken(TokenType.InsertionExp, value.slice(1));
688
+ return;
689
+ }
690
+ value += this.next()[0];
691
+ }
692
+ }
693
+ newLine() {
694
+ let value = "\n";
695
+ let nextC;
696
+ while (1) {
697
+ nextC = this.after;
698
+ if (nextC !== "\n") {
699
+ break;
700
+ }
701
+ value += nextC;
702
+ this.next();
703
+ }
704
+ if (this.isFirstToken) {
705
+ return;
706
+ }
707
+ this.setToken(TokenType.NewLine, value);
708
+ }
709
+ getDentValue() {
710
+ let value = "";
711
+ let nextC;
712
+ let isEmptyLine = false;
713
+ while (1) {
714
+ const nextChar = this.char;
715
+ switch (nextChar) {
716
+ case " ":
717
+ nextC = this.Tab;
718
+ break;
719
+ case " ":
720
+ nextC = " ";
721
+ break;
722
+ case "\n":
723
+ nextC = "\n";
724
+ break;
725
+ default:
726
+ nextC = "";
727
+ break;
728
+ }
729
+ if (nextC === "\n") {
730
+ isEmptyLine = true;
731
+ break;
732
+ }
733
+ if (!nextC) {
734
+ break;
735
+ }
736
+ value += nextC;
737
+ this.next();
738
+ }
739
+ return {
740
+ value,
741
+ isEmptyLine
742
+ };
743
+ }
744
+ dent() {
745
+ const { value, isEmptyLine } = this.getDentValue();
746
+ if (isEmptyLine) {
747
+ this.needIndent = true;
748
+ return;
749
+ }
750
+ this.needIndent = false;
751
+ if (this.isFirstToken) {
752
+ this.dentStack[0] = value.length;
753
+ return;
754
+ }
755
+ let currLen = value.length;
756
+ const indentHasLen = currLen > 0;
757
+ const prevLen = this.dentStack[this.dentStack.length - 1];
758
+ if (currLen > prevLen) {
759
+ this.dentStack.push(currLen);
760
+ this.setToken(TokenType.Indent, String(currLen));
761
+ return indentHasLen;
762
+ }
763
+ if (currLen < prevLen) {
764
+ for (let i = this.dentStack.length - 2; i >= 0; i--) {
765
+ const expLen = this.dentStack[i];
766
+ const prevExpLen = this.dentStack[i + 1];
767
+ if (currLen > expLen && currLen < prevExpLen) {
768
+ throw SyntaxError("\u7F29\u8FDB\u5927\u5C0F\u4E0D\u7EDF\u4E00");
769
+ }
770
+ this.dentStack.pop();
771
+ if (!this.token) {
772
+ this.setToken(TokenType.Dedent, String(expLen));
773
+ } else {
774
+ this.waitingTokens.push({
775
+ type: TokenType.Dedent,
776
+ typeName: TokenType[TokenType.Dedent],
777
+ value: String(expLen)
778
+ });
779
+ }
780
+ if (currLen === expLen) {
781
+ break;
782
+ }
783
+ }
784
+ return indentHasLen;
785
+ }
786
+ return indentHasLen;
787
+ }
788
+ identifier(char) {
789
+ let value = char;
790
+ let nextC;
791
+ while (1) {
792
+ nextC = this.after;
793
+ if (!this.testId(nextC)) {
794
+ break;
795
+ }
796
+ value += nextC;
797
+ this.next();
798
+ }
799
+ let realValue = value === "null" ? null : value === "undefined" ? void 0 : value === "false" ? false : value === "true" ? true : value;
800
+ this.setToken(TokenType.Identifier, realValue);
801
+ }
802
+ str(char) {
803
+ let value = '"';
804
+ let nextC;
805
+ let continuousBackslashCount = 0;
806
+ while (1) {
807
+ nextC = this.after;
808
+ value += nextC;
809
+ const memoCount = continuousBackslashCount;
810
+ if (nextC === "\\") {
811
+ continuousBackslashCount++;
812
+ } else {
813
+ continuousBackslashCount = 0;
814
+ }
815
+ this.next();
816
+ if (nextC === char && memoCount % 2 === 0) {
817
+ break;
818
+ }
819
+ }
820
+ this.setToken(TokenType.Identifier, JSON.parse(value.slice(0, -1) + '"'));
821
+ }
822
+ number(char) {
823
+ let value = char;
824
+ let nextC;
825
+ while (1) {
826
+ nextC = this.after;
827
+ if (!isNum(nextC)) {
828
+ break;
829
+ }
830
+ value += nextC;
831
+ this.next();
832
+ }
833
+ this.setToken(TokenType.Identifier, Number(value));
834
+ }
835
+ eof() {
836
+ this.setToken(TokenType.Eof, "End Of File");
837
+ }
838
+ };
839
+ /** Eof 标识符的值 */
840
+ _Tokenizer.EofId = `__EOF__${Date.now()}`;
841
+ let Tokenizer = _Tokenizer;
842
+
843
+ var __defProp = Object.defineProperty;
844
+ var __defProps = Object.defineProperties;
845
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
846
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
847
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
848
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
849
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
850
+ var __spreadValues = (a, b) => {
851
+ for (var prop in b || (b = {}))
852
+ if (__hasOwnProp.call(b, prop))
853
+ __defNormalProp(a, prop, b[prop]);
854
+ if (__getOwnPropSymbols)
855
+ for (var prop of __getOwnPropSymbols(b)) {
856
+ if (__propIsEnum.call(b, prop))
857
+ __defNormalProp(a, prop, b[prop]);
858
+ }
859
+ return a;
860
+ };
861
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
862
+ function bobe(fragments, ...values) {
863
+ const ui = function ui2(options, valueOpt, root, before) {
864
+ const tokenizer = new Tokenizer();
865
+ const cmp = new Interpreter(tokenizer);
866
+ Object.assign(cmp, valueOpt);
867
+ cmp.config(__spreadProps(__spreadValues({}, options), {
868
+ hook({ i }) {
869
+ return values[i];
870
+ },
871
+ setProp(node, key, value, hookI) {
872
+ node.props[key] = value;
873
+ }
874
+ }));
875
+ cmp.init(Array.from(fragments));
876
+ return cmp.program(root, before);
877
+ };
878
+ return ui;
879
+ }
880
+ function customRender(option) {
881
+ return function render(Ctor, root) {
882
+ const store = Ctor.new();
883
+ return [store["ui"](option, { data: store }, root), store];
884
+ };
885
+ }
886
+
887
+ export { bobe, customRender };
465
888
  //# sourceMappingURL=bobe.esm.js.map