bobe 0.0.31 → 0.0.33

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,75 +1,6 @@
1
+ import { Queue, isNum, matchIdStart2, jsVarRegexp } from 'bobe-shared';
1
2
  import { getPulling, setPulling, Keys, Computed, Effect, toRaw, runWithPulling, Scope, deepSignal, Store, shareSignal, effect } from 'aoye';
2
3
  export * from 'aoye';
3
- import { jsVarRegexp, Queue, isNum, matchIdStart2 } from 'bobe-shared';
4
-
5
- function _arrayLikeToArray(r, a) {
6
- (null == a || a > r.length) && (a = r.length);
7
- for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
8
- return n;
9
- }
10
- function _arrayWithHoles(r) {
11
- if (Array.isArray(r)) return r;
12
- }
13
- function _iterableToArrayLimit(r, l) {
14
- var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
15
- if (null != t) {
16
- var e,
17
- n,
18
- i,
19
- u,
20
- a = [],
21
- f = true,
22
- o = false;
23
- try {
24
- if (i = (t = t.call(r)).next, 0 === l) {
25
- if (Object(t) !== t) return;
26
- f = !1;
27
- } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
28
- } catch (r) {
29
- o = true, n = r;
30
- } finally {
31
- try {
32
- if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
33
- } finally {
34
- if (o) throw n;
35
- }
36
- }
37
- return a;
38
- }
39
- }
40
- function _nonIterableRest() {
41
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
42
- }
43
- function _objectWithoutProperties(e, t) {
44
- if (null == e) return {};
45
- var o,
46
- r,
47
- i = _objectWithoutPropertiesLoose(e, t);
48
- if (Object.getOwnPropertySymbols) {
49
- var n = Object.getOwnPropertySymbols(e);
50
- for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
51
- }
52
- return i;
53
- }
54
- function _objectWithoutPropertiesLoose(r, e) {
55
- if (null == r) return {};
56
- var t = {};
57
- for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
58
- if (-1 !== e.indexOf(n)) continue;
59
- t[n] = r[n];
60
- }
61
- return t;
62
- }
63
- function _slicedToArray(r, e) {
64
- return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
65
- }
66
- function _unsupportedIterableToArray(r, a) {
67
- if (r) {
68
- if ("string" == typeof r) return _arrayLikeToArray(r, a);
69
- var t = {}.toString.call(r).slice(8, -1);
70
- return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
71
- }
72
- }
73
4
 
74
5
  let TokenType = function (TokenType) {
75
6
  TokenType[TokenType["NewLine"] = 1] = "NewLine";
@@ -81,6 +12,7 @@ let TokenType = function (TokenType) {
81
12
  TokenType[TokenType["Eof"] = 64] = "Eof";
82
13
  TokenType[TokenType["InsertionExp"] = 128] = "InsertionExp";
83
14
  TokenType[TokenType["Semicolon"] = 256] = "Semicolon";
15
+ TokenType[TokenType["StaticInsExp"] = 512] = "StaticInsExp";
84
16
  return TokenType;
85
17
  }({});
86
18
  let FakeType = function (FakeType) {
@@ -111,1427 +43,1922 @@ let NodeSort = function (NodeSort) {
111
43
  return TerpEvt;
112
44
  })({});
113
45
 
114
- class MultiTypeStack {
115
- typeTops = {};
116
- length = 0;
117
- stack = [];
118
- push(value, bits) {
119
- const newNode = {
120
- value,
121
- types: bits,
122
- prevByType: {}
123
- };
124
- let bit;
125
- while (1) {
126
- bit = bits & ~bits + 1;
127
- if (!bit) break;
128
- bits &= ~bit;
129
- newNode.prevByType[bit] = this.typeTops[bit] || undefined;
130
- this.typeTops[bit] = newNode;
131
- }
132
- this.stack[this.length++] = newNode;
133
- }
134
- pop() {
135
- const poppedNode = this.stack[this.length - 1];
136
- this.stack[--this.length] = null;
137
- if (!poppedNode) return undefined;
138
- let bits = poppedNode.types;
139
- let bit;
140
- while (1) {
141
- bit = bits & ~bits + 1;
142
- if (!bit) break;
143
- bits &= ~bit;
144
- this.typeTops[bit] = poppedNode.prevByType[bit];
46
+ class Tokenizer {
47
+ TabSize = 2;
48
+ Tab = Array.from({
49
+ length: this.TabSize
50
+ }, () => ' ').join('');
51
+ static EofId = `__EOF__${Date.now()}`;
52
+ static DedentId = `__DEDENT__${Date.now()}`;
53
+ needIndent = false;
54
+ isFirstToken = true;
55
+ dentStack = [0];
56
+ i = 0;
57
+ line = 0;
58
+ column = 0;
59
+ preCol = 0;
60
+ preI = 0;
61
+ needLoc = false;
62
+ handledTokens = [];
63
+ waitingTokens = new Queue();
64
+ source = '';
65
+ constructor(hook, useDedentAsEof) {
66
+ this.hook = hook;
67
+ this.useDedentAsEof = useDedentAsEof;
68
+ if (useDedentAsEof) {
69
+ this.setToken(TokenType.Indent, '');
70
+ this.isFirstToken = true;
145
71
  }
146
- return [poppedNode.value, poppedNode.types];
147
72
  }
148
- peekByType(cat) {
149
- return this.typeTops[cat]?.value;
73
+ next() {
74
+ this.i++;
150
75
  }
151
- peekType() {
152
- return this.stack.at(-1).types;
76
+ getCurrentPos() {
77
+ return {
78
+ offset: this.i,
79
+ line: this.line,
80
+ column: this.column
81
+ };
153
82
  }
154
- peek() {
155
- return this.stack.at(-1).value;
83
+ resume(_snapshot) {
84
+ this.token = undefined;
85
+ this.needIndent = false;
86
+ this.isFirstToken = true;
87
+ this.dentStack = [0];
88
+ Object.assign(this, _snapshot);
156
89
  }
157
- }
158
-
159
- function macInc(arr) {
160
- const len = arr.length;
161
- let candyLast = [],
162
- i = 0;
163
- while (i < len) {
164
- const it = arr[i];
165
- if (it !== -1) {
166
- candyLast = [i];
167
- break;
90
+ snapshot(keys) {
91
+ const snap = {
92
+ i: this.i,
93
+ waitingTokens: this.waitingTokens.clone()
94
+ };
95
+ if (keys) {
96
+ for (const k of keys) {
97
+ snap[k] = this[k];
98
+ if (k === 'dentStack') {
99
+ snap[k] = this[k].slice();
100
+ }
101
+ }
168
102
  }
169
- i++;
103
+ return snap;
170
104
  }
171
- if (i + 1 >= len) return candyLast;
172
- const toPrev = new Int32Array(len);
173
- while (i < len) {
174
- const target = arr[i];
175
- if (target === -1) continue;
176
- let start = -1,
177
- end = candyLast.length;
178
- while (start + 1 < end) {
179
- const mid = start + end >> 1;
180
- if (arr[candyLast[mid]] < target) {
181
- start = mid;
105
+ skip() {
106
+ const logicDentLen = this.dentStack[this.dentStack.length - 1];
107
+ let needIndent = false;
108
+ let skipFragment = ``;
109
+ this.token = undefined;
110
+ while (1) {
111
+ const char = this.code[this.i];
112
+ if (char === '\n') {
113
+ needIndent = true;
114
+ skipFragment += char;
115
+ this.next();
116
+ continue;
117
+ }
118
+ if (!needIndent) {
119
+ skipFragment += char;
120
+ this.next();
121
+ continue;
122
+ }
123
+ needIndent = false;
124
+ const _this$getDentValue = this.getDentValue(),
125
+ value = _this$getDentValue.value,
126
+ isEmptyLine = _this$getDentValue.isEmptyLine;
127
+ const currLen = value.length;
128
+ if (isEmptyLine) continue;
129
+ if (currLen > logicDentLen) {
130
+ skipFragment += value;
182
131
  } else {
183
- end = mid;
132
+ for (let i = this.dentStack.length - 1; i >= 0; i--) {
133
+ const expLen = this.dentStack[i];
134
+ if (currLen === expLen) break;
135
+ if (currLen > expLen) {
136
+ throw SyntaxError(`缩进错误,缩进长度不匹配`);
137
+ }
138
+ if (this.shorterThanBaseDentEof()) {
139
+ break;
140
+ }
141
+ this.dentStack.pop();
142
+ if (!this.token) {
143
+ this.setToken(TokenType.Dedent, String(expLen));
144
+ } else {
145
+ this.waitingTokens.push({
146
+ type: TokenType.Dedent,
147
+ typeName: TokenType[TokenType.Dedent],
148
+ value: String(expLen),
149
+ loc: null
150
+ });
151
+ }
152
+ }
153
+ break;
184
154
  }
185
155
  }
186
- candyLast[end] = i;
187
- toPrev[i] = candyLast[start];
188
- i++;
156
+ if (!this.token) {
157
+ this.nextToken();
158
+ }
159
+ return skipFragment;
189
160
  }
190
- let length = candyLast.length;
191
- for (let j = length - 1; j > 0; j--) {
192
- const prev = toPrev[candyLast[j]];
193
- candyLast[j - 1] = prev;
161
+ setCode(code) {
162
+ this.code = '\n' + code.trimEnd() + `\n${Tokenizer.EofId}`;
194
163
  }
195
- return candyLast;
196
- }
197
-
198
- const KEY_INDEX = '__BOBE_KEY_INDEX';
199
-
200
- const _excluded = ["dentStack", "isFirstToken"];
201
- class Interpreter {
202
- constructor(tokenizer) {
203
- this.tokenizer = tokenizer;
164
+ tokenize() {
165
+ do {
166
+ this.nextToken();
167
+ console.log('token:', TokenType[this.token?.type], JSON.stringify(this.token?.value || ''));
168
+ } while (!this.isEof());
204
169
  }
205
- isLogicNode(node) {
206
- return node && node.__logicType & LogicalBit;
170
+ isEof() {
171
+ if (!this.token) return false;
172
+ return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
207
173
  }
208
- rootComponent = null;
209
- program(root, componentNode, before, ctxProvider) {
210
- this.rootComponent = componentNode;
211
- this.tokenizer.nextToken();
212
- const stack = new MultiTypeStack();
213
- stack.push({
214
- node: root,
215
- prev: null
216
- }, NodeSort.Real);
217
- stack.push({
218
- node: componentNode,
219
- prev: null
220
- }, NodeSort.Component | NodeSort.CtxProvider | NodeSort.TokenizerSwitcher);
221
- if (ctxProvider) {
222
- stack.push({
223
- node: ctxProvider,
224
- prev: null
225
- }, (ctxProvider.__logicType & LogicalBit ? NodeSort.Logic : 0) | NodeSort.CtxProvider);
226
- }
227
- const rootLen = stack.length;
228
- const ctx = this.ctx = {
229
- realParent: root,
230
- prevSibling: before,
231
- current: null,
232
- stack,
233
- before
174
+ setToken(type, value) {
175
+ this.token = {
176
+ type,
177
+ typeName: TokenType[type],
178
+ value,
179
+ loc: null
234
180
  };
235
- const rootPulling = getPulling();
236
- while (1) {
237
- if (this.tokenizer.isEof()) {
238
- if (!ctx.prevSibling) ctx.prevSibling = before;
239
- this.handleInsert(root, ctx.current, ctx.prevSibling, componentNode);
240
- break;
241
- }
242
- const token = this.tokenizer.token;
243
- if (token.type & TokenType.Indent) {
244
- this.tokenizer.nextToken();
245
- const isLogicNode = this.isLogicNode(ctx.current);
246
- stack.push({
247
- node: ctx.current,
248
- prev: ctx.prevSibling
249
- }, !ctx.current.__logicType ? NodeSort.Real : (ctx.current.__logicType & LogicalBit ? NodeSort.Logic : 0) | (ctx.current.__logicType & TokenizerSwitcherBit ? NodeSort.TokenizerSwitcher : 0) | (ctx.current.__logicType === FakeType.Component ? NodeSort.Component : 0) | NodeSort.CtxProvider);
250
- if (ctx.current.__logicType) {
251
- if (isLogicNode) {
252
- setPulling(ctx.current.effect);
253
- if (ctx.current.__logicType & FakeType.ForItem) {
254
- ctx.prevSibling = ctx.current.realBefore;
255
- }
256
- }
257
- } else {
258
- if (ctx.current) {
259
- ctx.realParent = ctx.current;
260
- }
261
- ctx.prevSibling = null;
262
- }
263
- ctx.current = this.declaration(ctx);
264
- continue;
181
+ this.isFirstToken = false;
182
+ }
183
+ nextToken() {
184
+ try {
185
+ if (this.isEof()) {
186
+ return this.token;
265
187
  }
266
- if (ctx.current) {
267
- if (stack.length === rootLen && !ctx.prevSibling) {
268
- ctx.prevSibling = before;
269
- }
270
- this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
188
+ this.token = undefined;
189
+ if (this.waitingTokens.len) {
190
+ const item = this.waitingTokens.shift();
191
+ this.setToken(item.type, item.value);
192
+ return this.token;
271
193
  }
272
- if (this.tokenizer.token.type & TokenType.Dedent) {
273
- this.tokenizer.nextToken();
274
- const _stack$pop = stack.pop(),
275
- _stack$pop2 = _slicedToArray(_stack$pop, 2),
276
- _stack$pop2$ = _stack$pop2[0],
277
- parent = _stack$pop2$.node,
278
- prev = _stack$pop2$.prev,
279
- sort = _stack$pop2[1];
280
- if (!parent.__logicType) {
281
- const prevSameType = stack.peekByType(NodeSort.Real);
282
- ctx.realParent = prevSameType?.node || root;
194
+ outer: while (1) {
195
+ if (this.needIndent) {
196
+ this.dent();
283
197
  } else {
284
- if (sort & NodeSort.Logic) {
285
- const parentLogic = stack.peekByType(NodeSort.Logic)?.node;
286
- if (parentLogic) {
287
- setPulling(parentLogic.effect);
288
- } else {
289
- setPulling(rootPulling);
290
- }
291
- }
292
- if (sort & NodeSort.TokenizerSwitcher) {
293
- const switcher = stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
294
- this.tokenizer = switcher.tokenizer;
295
- }
296
- if (parent.__logicType === FakeType.ForItem) {
297
- const _ref = parent,
298
- forNode = _ref.forNode;
299
- const i = forNode.i,
300
- arr = forNode.arr,
301
- snapshot = forNode.snapshot;
302
- if (i + 1 < arr.length) {
303
- this.tokenizer.resume(snapshot);
304
- this.tokenizer.nextToken();
305
- this.tokenizer.nextToken();
306
- ctx.current = forNode.children[++forNode.i];
307
- ctx.prevSibling = ctx.current.realBefore;
308
- continue;
309
- }
310
- ctx.prevSibling = forNode.prevSibling;
311
- ctx.current = forNode;
312
- continue;
198
+ const char = this.code[this.i];
199
+ switch (char) {
200
+ case '\t':
201
+ case ' ':
202
+ break;
203
+ case '\n':
204
+ this.newLine();
205
+ this.needIndent = true;
206
+ break;
207
+ case '=':
208
+ this.assignment();
209
+ break;
210
+ case '|':
211
+ this.pipe();
212
+ break;
213
+ case ';':
214
+ this.setToken(TokenType.Semicolon, ';');
215
+ break;
216
+ default:
217
+ if (false) ;
218
+ switch (char) {
219
+ case "'":
220
+ case '"':
221
+ this.str(char);
222
+ break;
223
+ case '{':
224
+ const braceToken = this.brace();
225
+ this.setToken(TokenType.InsertionExp, braceToken);
226
+ break;
227
+ case '$':
228
+ const handled = this.staticIns();
229
+ if (handled) break;
230
+ default:
231
+ if (isNum(char)) {
232
+ this.number(char);
233
+ break;
234
+ }
235
+ if (typeof char === 'string' && matchIdStart2(char, 0)) {
236
+ this.identifier(char);
237
+ }
238
+ break;
239
+ }
240
+ if (false) ;
241
+ break;
313
242
  }
243
+ this.next();
244
+ }
245
+ if (this.token) {
246
+ break;
314
247
  }
315
- ctx.prevSibling = prev;
316
- ctx.current = parent;
317
- } else {
318
- ctx.prevSibling = ctx.current || ctx.prevSibling;
319
- ctx.current = this.declaration(ctx);
320
248
  }
249
+ return this.token;
250
+ } catch (error) {
251
+ console.error(error);
252
+ return this.token;
253
+ } finally {
254
+ this.handledTokens.push(this.token);
321
255
  }
322
- return componentNode;
323
- }
324
- insertAfterAnchor(name = 'anchor') {
325
- const _this$ctx = this.ctx,
326
- realParent = _this$ctx.realParent,
327
- prevSibling = _this$ctx.prevSibling,
328
- stack = _this$ctx.stack,
329
- before = _this$ctx.before;
330
- const afterAnchor = this.createAnchor(name);
331
- this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
332
- this.handleInsert(realParent, afterAnchor, prevSibling);
333
- return afterAnchor;
334
256
  }
335
- handleInsert(parent, child, prev, parentComponent) {
336
- if (!child.__logicType) {
337
- if (!prev || !prev.__logicType) {
338
- this.insertAfter(parent, child, prev);
339
- } else {
340
- const before = prev.realAfter;
341
- this.insertAfter(parent, child, before);
257
+ condExp() {
258
+ let value = '';
259
+ this.token = null;
260
+ try {
261
+ if (this.code[this.i] === '\n') {
262
+ this.setToken(TokenType.Identifier, true);
263
+ return this.token;
342
264
  }
343
- } else {
344
- const childCmp = child;
345
- childCmp.realParent = parent;
346
- if (prev?.__logicType) {
347
- childCmp.realBefore = prev.forNode ? prev.forNode.realAfter : prev.realAfter;
348
- } else {
349
- childCmp.realBefore = prev;
265
+ while (this.code[this.i + 1] !== '\n') {
266
+ value += this.code[this.i];
267
+ this.next();
350
268
  }
269
+ value += this.code[this.i];
270
+ const trimmed = value.trim();
271
+ this.setToken(TokenType.Identifier, trimmed ? value : true);
272
+ return this.token;
273
+ } finally {
274
+ this.next();
275
+ this.handledTokens.push(this.token);
351
276
  }
352
277
  }
353
- getPrevRealSibling(prevSibling) {
354
- if (!prevSibling || !prevSibling.__logicType) {
355
- return prevSibling;
356
- }
357
- let point = prevSibling;
358
- while (point != null) {
359
- if (point.lastChild) {
360
- return point.lastChild.value;
278
+ jsExp() {
279
+ this.token = null;
280
+ let value = '';
281
+ try {
282
+ const char = this.code[this.i];
283
+ if (char === ';' || char === '\n') {
284
+ this.setToken(TokenType.Identifier, value);
285
+ return this.token;
361
286
  }
362
- point = point.anchor;
363
- }
364
- }
365
- declaration(ctx) {
366
- const _this$tokenizer$_hook = this.tokenizer._hook({}),
367
- _this$tokenizer$_hook2 = _slicedToArray(_this$tokenizer$_hook, 2),
368
- hookType = _this$tokenizer$_hook2[0],
369
- value = _this$tokenizer$_hook2[1];
370
- let _node;
371
- if (value === 'if' || value === 'else' || value === 'fail') {
372
- return this.condDeclaration(ctx);
373
- } else if (value === 'for') {
374
- return this.forDeclaration();
375
- } else if (hookType) {
376
- const data = this.getData();
377
- if (hookType === 'static') {
378
- if (typeof value === 'function') {
379
- _node = this.componentOrFragmentDeclaration(value, ctx);
380
- } else {
381
- throw new SyntaxError(`declaration 不支持 ${value} 类型的静态插值`);
382
- }
383
- } else {
384
- const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
385
- const val = data[Keys.Raw][value];
386
- if (typeof val === 'function') {
387
- _node = this.componentOrFragmentDeclaration(val, ctx);
388
- } else {
389
- const str = valueIsMapKey ? value : this.getFn(data, value);
390
- _node = this.createNode('text');
391
- this.onePropParsed(data, _node, 'text', str, valueIsMapKey, false);
392
- }
287
+ let nextC = this.code[this.i + 1];
288
+ while (nextC !== ';' && nextC !== '\n') {
289
+ value += this.code[this.i];
290
+ this.next();
291
+ nextC = this.code[this.i + 1];
393
292
  }
394
- } else {
395
- _node = this.createNode(value);
293
+ value += this.code[this.i];
294
+ this.setToken(TokenType.Identifier, value);
295
+ return this.token;
296
+ } finally {
297
+ this.next();
298
+ this.handledTokens.push(this.token);
396
299
  }
397
- this.tokenizer.nextToken();
398
- this.headerLine(_node);
399
- this.extensionLines(_node);
400
- if (_node.__logicType & TokenizerSwitcherBit) {
401
- this.onePropParsed = this.oneRealPropParsed;
402
- this.tokenizer = _node.tokenizer;
300
+ }
301
+ peekChar() {
302
+ let i = this.i;
303
+ while (this.code[i] === ' ' || this.code[i] === '\t') {
304
+ i++;
403
305
  }
404
- return _node;
306
+ return this.code[i];
405
307
  }
406
- forDeclaration() {
407
- const arrExp = this.tokenizer.nextToken().value;
408
- this.tokenizer.nextToken();
409
- const itemToken = this.tokenizer.nextToken();
410
- const isDestruct = itemToken.type === TokenType.InsertionExp;
411
- let itemExp = itemToken.value,
412
- vars;
413
- if (isDestruct) {
414
- itemExp = '{' + itemExp + '}';
415
- vars = itemExp.match(jsVarRegexp);
416
- const varStr = vars.join(',');
417
- itemExp = new Function(itemExp, `return {${varStr}};`);
308
+ assignment() {
309
+ this.setToken(TokenType.Assign, '=');
310
+ }
311
+ pipe() {
312
+ this.setToken(TokenType.Pipe, '|');
313
+ }
314
+ staticIns() {
315
+ let nextC = this.code[this.i + 1];
316
+ if (nextC !== '{') {
317
+ return false;
418
318
  }
419
- let indexName,
420
- keyExp,
421
- char = this.tokenizer.peekChar();
422
- if (char === ';') {
423
- this.tokenizer.nextToken();
424
- if (this.tokenizer.peekChar() !== '\n') keyExp = this.tokenizer.jsExp().value;
425
- } else if (char === '\n') ; else {
426
- indexName = this.tokenizer.nextToken().value;
427
- if (this.tokenizer.peekChar() === ';') {
428
- this.tokenizer.nextToken();
429
- if (this.tokenizer.peekChar() !== '\n') keyExp = this.tokenizer.jsExp().value;
319
+ this.next();
320
+ let value = '';
321
+ let innerBrace = 0;
322
+ while (1) {
323
+ nextC = this.code[this.i + 1];
324
+ value += nextC;
325
+ this.next();
326
+ if (nextC === '{') {
327
+ innerBrace++;
328
+ }
329
+ if (nextC === '}') {
330
+ if (!innerBrace) {
331
+ break;
332
+ }
333
+ innerBrace--;
430
334
  }
431
335
  }
432
- const owner = this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
433
- const prevSibling = this.ctx.prevSibling;
434
- const forNode = {
435
- __logicType: FakeType.For,
436
- snapshot: this.tokenizer.snapshot(['dentStack', 'isFirstToken']),
437
- realParent: this.ctx.realParent,
438
- prevSibling,
439
- realBefore: prevSibling?.realAfter || prevSibling,
440
- realAfter: null,
441
- arr: null,
442
- arrSignal: null,
443
- itemExp,
444
- indexName,
445
- getKey: null,
446
- children: [],
447
- effect: null,
448
- owner,
449
- vars,
450
- i: 0
336
+ this.setToken(TokenType.StaticInsExp, value.slice(0, -1));
337
+ return true;
338
+ }
339
+ brace() {
340
+ let inComment,
341
+ inString,
342
+ count = 0,
343
+ value = '',
344
+ backslashCount = 0;
345
+ while (1) {
346
+ const char = this.code[this.i];
347
+ const nextChar = this.code[this.i + 1];
348
+ if (inComment === 'single' && char === '\n') {
349
+ inComment = null;
350
+ } else if (inComment === 'multi' && char === '*' && nextChar === '/') {
351
+ inComment = null;
352
+ value += this.code[this.i];
353
+ this.next();
354
+ } else if (inString) {
355
+ if (char === inString && backslashCount % 2 === 0) {
356
+ inString = null;
357
+ }
358
+ backslashCount = char === '\\' ? backslashCount + 1 : 0;
359
+ } else {
360
+ if (char === '/' && nextChar === '/') {
361
+ inComment = 'single';
362
+ value += this.code[this.i];
363
+ this.next();
364
+ } else if (char === '/' && nextChar === '*') {
365
+ inComment = 'multi';
366
+ value += this.code[this.i];
367
+ this.next();
368
+ } else if (char === "'" || char === '"' || char === '`') {
369
+ inString = char;
370
+ } else if (char === '{') {
371
+ count++;
372
+ } else if (char === '}') {
373
+ count--;
374
+ }
375
+ }
376
+ if (count === 0 && inString == null && inComment == null) {
377
+ return value.slice(1);
378
+ }
379
+ value += this.code[this.i];
380
+ this.next();
381
+ }
382
+ }
383
+ newLine() {
384
+ let value = '\n';
385
+ let nextC;
386
+ while (1) {
387
+ nextC = this.code[this.i + 1];
388
+ if (nextC !== '\n') {
389
+ break;
390
+ }
391
+ value += nextC;
392
+ this.next();
393
+ }
394
+ if (this.isFirstToken) {
395
+ return;
396
+ }
397
+ this.setToken(TokenType.NewLine, value);
398
+ }
399
+ getDentValue() {
400
+ let value = '';
401
+ let nextC;
402
+ let isEmptyLine = false;
403
+ while (1) {
404
+ const nextChar = this.code[this.i];
405
+ switch (nextChar) {
406
+ case '\t':
407
+ nextC = this.Tab;
408
+ break;
409
+ case ' ':
410
+ nextC = ' ';
411
+ break;
412
+ case '\n':
413
+ nextC = '\n';
414
+ break;
415
+ default:
416
+ nextC = '';
417
+ break;
418
+ }
419
+ if (nextC === '\n') {
420
+ isEmptyLine = true;
421
+ break;
422
+ }
423
+ if (!nextC) {
424
+ break;
425
+ }
426
+ value += nextC;
427
+ this.next();
428
+ }
429
+ return {
430
+ value,
431
+ isEmptyLine
451
432
  };
452
- if (keyExp) {
453
- forNode.getKey = new Function('data', `let v;with(data){v=${keyExp}};return v;`);
433
+ }
434
+ dent() {
435
+ const _this$getDentValue2 = this.getDentValue(),
436
+ value = _this$getDentValue2.value,
437
+ isEmptyLine = _this$getDentValue2.isEmptyLine;
438
+ if (isEmptyLine) {
439
+ this.needIndent = true;
440
+ return;
454
441
  }
455
- window['for1'] = forNode;
456
- const data = this.getData();
457
- const cells = data[Keys.Meta].cells;
458
- const hasArrExpKey = Reflect.has(data[Keys.Raw], arrExp);
459
- const arrSignal = hasArrExpKey ? (data[arrExp], cells.get(arrExp)) : new Computed(this.getFn(data, arrExp));
460
- forNode.arrSignal = arrSignal;
461
- forNode.realAfter = this.insertAfterAnchor('for-after');
462
- const _forNode$snapshot = forNode.snapshot;
463
- _forNode$snapshot.dentStack;
464
- _forNode$snapshot.isFirstToken;
465
- const snapshotForUpdate = _objectWithoutProperties(_forNode$snapshot, _excluded);
466
- let isFirstRender = true;
467
- forNode.effect = new Effect(() => {
468
- let arr = arrSignal.get();
469
- arr[Keys.Iterator];
470
- const prevCtx = getPulling();
471
- setPulling(null);
472
- forNode.arr = arr = toRaw(arr);
473
- const children = forNode.children;
474
- if (isFirstRender) {
475
- const len = arr.length;
476
- for (let i = len; i--;) {
477
- const item = this.createForItem(forNode, i, data);
478
- item.realAfter = this.insertAfterAnchor('for-item-after');
479
- item.realBefore = this.insertAfterAnchor('for-item-before');
480
- item.realParent = forNode.realParent;
481
- children[i] = item;
442
+ this.needIndent = false;
443
+ if (this.isFirstToken) {
444
+ this.dentStack[0] = value.length;
445
+ return;
446
+ }
447
+ let currLen = value.length;
448
+ const indentHasLen = currLen > 0;
449
+ const prevLen = this.dentStack[this.dentStack.length - 1];
450
+ if (currLen > prevLen) {
451
+ this.dentStack.push(currLen);
452
+ this.setToken(TokenType.Indent, currLen);
453
+ return indentHasLen;
454
+ }
455
+ if (currLen < prevLen) {
456
+ for (let i = this.dentStack.length; i--;) {
457
+ const expLen = this.dentStack[i];
458
+ if (currLen === expLen) break;
459
+ if (currLen > expLen) {
460
+ throw SyntaxError('缩进大小不统一');
482
461
  }
483
- const firstInsert = children[0];
484
- if (firstInsert) {
485
- this.tokenizer.nextToken();
486
- this.tokenizer.nextToken();
487
- } else {
488
- this.tokenizer.skip();
462
+ if (this.shorterThanBaseDentEof()) {
463
+ return;
489
464
  }
490
- } else {
491
- const oldLen = children.length;
492
- const newLen = arr.length;
493
- const minLen = Math.min(oldLen, newLen);
494
- const newChildren = [];
495
- if (!forNode.getKey) {
496
- if (newLen < oldLen) {
497
- for (let i = oldLen - 1; i >= newLen; i--) {
498
- this.removeForItem(children, i);
499
- }
500
- }
501
- if (oldLen < newLen) {
502
- const lastAfter = children.at(-1)?.realAfter || forNode.realBefore;
503
- for (let i = newLen - 1; i >= oldLen; i--) {
504
- this.insertForItem(forNode, i, data, newChildren, lastAfter, snapshotForUpdate);
505
- }
506
- }
507
- for (let i = minLen; i--;) {
508
- const child = children[i];
509
- newChildren[i] = child;
510
- this.reuseForItem(child, arr[i], itemExp, i, indexName);
511
- }
465
+ this.dentStack.pop();
466
+ if (!this.token) {
467
+ this.setToken(TokenType.Dedent, String(expLen));
512
468
  } else {
513
- let s = 0,
514
- e1 = oldLen - 1,
515
- e2 = newLen - 1;
516
- while (s <= e1 && s <= e2) {
517
- const child = children[s];
518
- const old = child.key;
519
- const itemData = this.getItemData(forNode, s, data);
520
- const key = forNode.getKey(itemData);
521
- if (old === key) {
522
- newChildren[s] = child;
523
- this.reuseForItem(child, arr[s], itemExp, s, indexName);
524
- s++;
525
- } else {
526
- break;
527
- }
528
- }
529
- while (s <= e1 && s <= e2) {
530
- const child = children[e1];
531
- const old = child.key;
532
- const itemData = this.getItemData(forNode, e2, data);
533
- const key = forNode.getKey(itemData);
534
- if (old === key) {
535
- newChildren[e2] = child;
536
- this.reuseForItem(child, arr[e2], itemExp, e2, indexName);
537
- e1--;
538
- e2--;
539
- } else {
540
- break;
541
- }
542
- }
543
- if (s > e1) {
544
- if (s <= e2) {
545
- const firstBefore = s > 0 ? children.at(-1)?.realAfter || forNode.realBefore : forNode.realBefore;
546
- for (let i = e2; i >= s; i--) {
547
- this.insertForItem(forNode, i, data, newChildren, firstBefore, snapshotForUpdate);
548
- }
549
- }
550
- } else if (s > e2) {
551
- if (s <= e1) {
552
- for (let i = e1; i >= s; i--) {
553
- this.removeForItem(children, i);
554
- }
555
- }
556
- } else {
557
- let s1 = s,
558
- s2 = s;
559
- const mixLen = e2 - s2 + 1;
560
- const key2new = new Map();
561
- for (let i = s2; i <= e2; i++) {
562
- const itemData = this.getItemData(forNode, i, data);
563
- const key = forNode.getKey(itemData);
564
- key2new.set(key, i);
565
- }
566
- let maxIncNewI = -1;
567
- let hasMove = false;
568
- const new2oldI = new Array(mixLen).fill(-1);
569
- for (let i = s1; i <= e1; i++) {
570
- const key = children[i].key;
571
- const newI = key2new.get(key);
572
- if (newI == null) {
573
- this.removeForItem(children, i);
574
- continue;
575
- }
576
- const child = children[i];
577
- newChildren[newI] = child;
578
- this.reuseForItem(child, arr[newI], itemExp, newI, indexName);
579
- new2oldI[newI - s2] = i;
580
- key2new.delete(key);
581
- if (newI < maxIncNewI) {
582
- hasMove = true;
583
- } else {
584
- maxIncNewI = newI;
585
- }
586
- }
587
- if (!hasMove) {
588
- key2new.forEach((i, key) => {
589
- const before = i === 0 ? forNode.realBefore : newChildren[i - 1].realAfter;
590
- this.insertForItem(forNode, i, data, newChildren, before, snapshotForUpdate);
591
- });
592
- } else {
593
- const incI = macInc(new2oldI),
594
- incLen = incI.length;
595
- let p1, p2;
596
- for (p1 = s2, p2 = 0; p1 <= e2; p1++) {
597
- const oldI = new2oldI[p1];
598
- if (oldI === -1) {
599
- const before = p1 === 0 ? forNode.realBefore : newChildren[p1 - 1].realAfter;
600
- this.insertForItem(forNode, p1, data, newChildren, before, snapshotForUpdate);
601
- continue;
602
- }
603
- const staticIdx = incI[p2] + s2;
604
- if (p1 === staticIdx) {
605
- p2 <= incLen && p2++;
606
- continue;
607
- }
608
- let before = p1 === 0 ? forNode.realBefore : newChildren[p1 - 1].realAfter;
609
- const child = newChildren[p1];
610
- const realBefore = child.realBefore,
611
- realAfter = child.realAfter,
612
- realParent = child.realParent;
613
- let point = realBefore,
614
- next;
615
- do {
616
- next = this.nextSib(point);
617
- this.insertAfter(realParent, point, before);
618
- before = point;
619
- if (point === realAfter) break;
620
- point = next;
621
- } while (true);
622
- }
623
- }
624
- }
469
+ this.waitingTokens.push({
470
+ type: TokenType.Dedent,
471
+ typeName: TokenType[TokenType.Dedent],
472
+ value: String(expLen),
473
+ loc: null
474
+ });
625
475
  }
626
- forNode.children = newChildren;
627
476
  }
628
- isFirstRender = false;
629
- setPulling(prevCtx);
630
- return isDestroy => {
631
- if (isDestroy) {
632
- for (let i = 0; i < forNode.children.length; i++) {
633
- const item = forNode.children[i];
634
- item.effect.dispose();
635
- }
477
+ return indentHasLen;
478
+ }
479
+ return indentHasLen;
480
+ }
481
+ shorterThanBaseDentEof() {
482
+ const yes = this.dentStack.length === 1;
483
+ if (yes) {
484
+ if (!this.token) {
485
+ if (this.useDedentAsEof) {
486
+ this.setToken(TokenType.Dedent, '');
487
+ } else {
488
+ this.setToken(TokenType.Identifier, Tokenizer.EofId);
636
489
  }
637
- };
638
- });
639
- return forNode.children[0] || forNode;
490
+ } else {
491
+ if (this.useDedentAsEof) {
492
+ this.waitingTokens.push({
493
+ type: TokenType.Dedent,
494
+ typeName: TokenType[TokenType.Dedent],
495
+ value: '',
496
+ loc: null
497
+ });
498
+ } else {
499
+ this.waitingTokens.push({
500
+ type: TokenType.Identifier,
501
+ typeName: TokenType[TokenType.Identifier],
502
+ value: Tokenizer.EofId,
503
+ loc: null
504
+ });
505
+ }
506
+ }
507
+ }
508
+ return yes;
640
509
  }
641
- insertForItem(forNode, i, parentData, newChildren, before, snapshotForUpdate) {
642
- const item = this.createForItem(forNode, i, parentData);
643
- newChildren[i] = item;
644
- let realAfter = this.createAnchor('for-item-after');
645
- this.handleInsert(forNode.realParent, realAfter, before);
646
- let realBefore = this.createAnchor('for-item-before');
647
- this.handleInsert(forNode.realParent, realBefore, before);
648
- item.realBefore = realBefore;
649
- item.realAfter = realAfter;
650
- this.tokenizer = forNode.owner.tokenizer;
651
- this.tokenizer.resume(snapshotForUpdate);
652
- this.tokenizer.useDedentAsEof = false;
653
- runWithPulling(() => {
654
- this.program(forNode.realParent, forNode.owner, realBefore, item);
655
- }, item.effect);
510
+ identifier(char) {
511
+ let value = char;
512
+ let nextC;
513
+ while (1) {
514
+ nextC = this.code[this.i + 1];
515
+ if (typeof nextC !== 'string' || !matchIdStart2(nextC, 0)) {
516
+ break;
517
+ }
518
+ value += nextC;
519
+ this.next();
520
+ }
521
+ if (value === Tokenizer.EofId && this.useDedentAsEof) {
522
+ this.setToken(TokenType.Dedent, '');
523
+ return;
524
+ }
525
+ let realValue = value === 'null' ? null : value === 'undefined' ? undefined : value === 'false' ? false : value === 'true' ? true : value;
526
+ this.setToken(TokenType.Identifier, realValue);
656
527
  }
657
- removeForItem(children, i) {
658
- const child = children[i];
659
- this.removeLogicNode(child);
660
- this.remove(child.realBefore);
661
- this.remove(child.realAfter);
662
- child.effect.dispose();
528
+ str(char) {
529
+ let value = '';
530
+ let nextC;
531
+ let continuousBackslashCount = 0;
532
+ while (1) {
533
+ nextC = this.code[this.i + 1];
534
+ const memoCount = continuousBackslashCount;
535
+ if (nextC === '\\') {
536
+ continuousBackslashCount++;
537
+ } else {
538
+ continuousBackslashCount = 0;
539
+ }
540
+ this.next();
541
+ if (nextC === char && memoCount % 2 === 0) {
542
+ break;
543
+ }
544
+ value += nextC;
545
+ }
546
+ this.setToken(TokenType.Identifier, value);
663
547
  }
664
- reuseForItem(child, data, itemExp, i, indexName) {
665
- if (typeof itemExp === 'string') {
666
- child.data[itemExp] = data;
667
- if (indexName) {
668
- child.data[indexName] = i;
548
+ number(char) {
549
+ let value = char;
550
+ let nextC;
551
+ while (1) {
552
+ nextC = this.code[this.i + 1];
553
+ if (!isNum(nextC)) {
554
+ break;
669
555
  }
556
+ value += nextC;
557
+ this.next();
558
+ }
559
+ this.setToken(TokenType.Identifier, Number(value));
560
+ }
561
+ eof() {
562
+ this.setToken(TokenType.Eof, 'End Of File');
563
+ }
564
+ HookId = '_h_o_o_k_';
565
+ hookI = 0;
566
+ _hook = props => {
567
+ const value = this.token.value;
568
+ const isDynamicHook = this.token.type & TokenType.InsertionExp;
569
+ let isStaticHook;
570
+ {
571
+ isStaticHook = typeof value === 'string' && value.indexOf(this.HookId) === 0;
572
+ }
573
+ const hookType = isDynamicHook ? 'dynamic' : isStaticHook ? 'static' : undefined;
574
+ if (this.hook && isStaticHook) {
575
+ const hookI = Number(value.slice(this.HookId.length));
576
+ const res = this.hook({
577
+ ...props,
578
+ HookId: this.HookId,
579
+ i: hookI
580
+ });
581
+ return [hookType, res, hookI];
582
+ } else if (isDynamicHook) {
583
+ return [hookType, value];
584
+ }
585
+ return [hookType, value];
586
+ };
587
+ init(fragments) {
588
+ if (typeof fragments === 'string') {
589
+ this.setCode(fragments);
670
590
  } else {
671
- indexName = indexName || KEY_INDEX;
672
- child.data[indexName] = i;
591
+ let code = '';
592
+ for (let i = 0; i < fragments.length - 1; i++) {
593
+ const fragment = fragments[i];
594
+ code += fragment + `${this.HookId}${i}`;
595
+ }
596
+ this.setCode(code + fragments[fragments.length - 1]);
673
597
  }
674
598
  }
675
- forItemId = 0;
676
- createForItem(forNode, i, parentData) {
677
- let forItemNode;
678
- let data;
679
- const scope = new Scope(() => {});
680
- scope.scope = null;
681
- runWithPulling(() => {
682
- scope.get();
683
- }, null);
684
- data = this.getItemData(forNode, i, parentData);
685
- forItemNode = {
686
- id: this.forItemId++,
687
- __logicType: FakeType.ForItem,
688
- realParent: null,
689
- realBefore: null,
690
- realAfter: null,
691
- forNode,
692
- key: forNode.getKey?.(data),
693
- effect: null,
694
- data
599
+ }
600
+
601
+ var NodeType = function (NodeType) {
602
+ NodeType["Element"] = "Element";
603
+ NodeType["Text"] = "Text";
604
+ NodeType["Interpolation"] = "Interpolation";
605
+ NodeType["Property"] = "Property";
606
+ NodeType["PropertyKey"] = "PropertyKey";
607
+ NodeType["StaticValue"] = "StaticValue";
608
+ NodeType["DynamicValue"] = "DynamicValue";
609
+ NodeType["Program"] = "Program";
610
+ NodeType["If"] = "If";
611
+ NodeType["Else"] = "Else";
612
+ NodeType["Fail"] = "Fail";
613
+ NodeType["For"] = "For";
614
+ NodeType["Component"] = "Component";
615
+ NodeType["Fragment"] = "Fragment";
616
+ return NodeType;
617
+ }(NodeType || {});
618
+
619
+ function _applyDecs2311(e, t, n, r, o, i) {
620
+ var a,
621
+ c,
622
+ u,
623
+ s,
624
+ f,
625
+ l,
626
+ p,
627
+ d = Symbol.metadata || Symbol.for("Symbol.metadata"),
628
+ m = Object.defineProperty,
629
+ h = Object.create,
630
+ y = [h(null), h(null)],
631
+ v = t.length;
632
+ function g(t, n, r) {
633
+ return function (o, i) {
634
+ n && (i = o, o = e);
635
+ for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []);
636
+ return r ? i : o;
695
637
  };
696
- forItemNode.effect = scope;
697
- return forItemNode;
698
638
  }
699
- getItemData(forNode, i, parentData) {
700
- const arr = forNode.arr,
701
- itemExp = forNode.itemExp,
702
- vars = forNode.vars,
703
- arrSignal = forNode.arrSignal,
704
- getKey = forNode.getKey;
705
- let indexName = forNode.indexName;
706
- let data;
707
- if (typeof itemExp === 'string') {
708
- data = deepSignal(indexName ? {
709
- [itemExp]: arr[i],
710
- [indexName]: i
711
- } : {
712
- [itemExp]: arr[i]
713
- }, getPulling());
714
- } else {
715
- indexName = indexName ?? KEY_INDEX;
716
- const rawData = {
717
- [indexName]: i
639
+ function b(e, t, n, r) {
640
+ if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined"));
641
+ return e;
642
+ }
643
+ function applyDec(e, t, n, r, o, i, u, s, f, l, p) {
644
+ function d(e) {
645
+ if (!p(e)) throw new TypeError("Attempted to access private element on non-instance");
646
+ }
647
+ var h = [].concat(t[0]),
648
+ v = t[3],
649
+ w = !u,
650
+ D = 1 === o,
651
+ S = 3 === o,
652
+ j = 4 === o,
653
+ E = 2 === o;
654
+ function I(t, n, r) {
655
+ return function (o, i) {
656
+ return n && (i = o, o = e), r && r(o), P[t].call(o, i);
718
657
  };
719
- data = deepSignal(rawData, getPulling());
720
- const computedData = new Computed(() => itemExp(arrSignal.get()[getKey ? data[indexName] : i]));
721
- const cells = data[Keys.Meta].cells;
722
- for (let i = 0; i < vars.length; i++) {
723
- const name = vars[i];
724
- rawData[name] = undefined;
725
- cells.set(name, new Computed(() => computedData.get()[name]));
658
+ }
659
+ if (!w) {
660
+ var P = {},
661
+ k = [],
662
+ F = S ? "get" : j || D ? "set" : "value";
663
+ if (f ? (l || D ? P = {
664
+ get: _setFunctionName(function () {
665
+ return v(this);
666
+ }, r, "get"),
667
+ set: function (e) {
668
+ t[4](this, e);
669
+ }
670
+ } : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) {
671
+ if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet");
672
+ y[+s][r] = o < 3 ? 1 : o;
726
673
  }
727
674
  }
728
- Object.setPrototypeOf(data, parentData);
729
- return data;
675
+ for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) {
676
+ var T = b(h[O], "A decorator", "be", true),
677
+ z = n ? h[O - 1] : void 0,
678
+ A = {},
679
+ H = {
680
+ kind: ["field", "accessor", "method", "getter", "setter", "class"][o],
681
+ name: r,
682
+ metadata: a,
683
+ addInitializer: function (e, t) {
684
+ if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished");
685
+ b(t, "An initializer", "be", true), i.push(t);
686
+ }.bind(null, A)
687
+ };
688
+ if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);else if (H.static = s, H.private = f, c = H.access = {
689
+ has: f ? p.bind() : function (e) {
690
+ return r in e;
691
+ }
692
+ }, j || (c.get = f ? E ? function (e) {
693
+ return d(e), P.value;
694
+ } : I("get", 0, d) : function (e) {
695
+ return e[r];
696
+ }), E || S || (c.set = f ? I("set", 0, d) : function (e, t) {
697
+ e[r] = t;
698
+ }), N = T.call(z, D ? {
699
+ get: P.get,
700
+ set: P.set
701
+ } : P[F], H), A.v = 1, D) {
702
+ if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined");
703
+ } else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N);
704
+ }
705
+ return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N;
730
706
  }
731
- getData() {
732
- const _this$ctx$stack$peekB = this.ctx.stack.peekByType(NodeSort.CtxProvider),
733
- node = _this$ctx$stack$peekB.node;
734
- return node.data;
707
+ function w(e) {
708
+ return m(e, d, {
709
+ configurable: true,
710
+ enumerable: true,
711
+ value: a
712
+ });
735
713
  }
736
- onePropParsed(data, node, key, value, valueIsMapKey, isFn, hookI) {
737
- if (isFn) {
738
- this.setProp(node, key, value, hookI);
739
- } else if (typeof value === 'function') {
740
- new Effect(() => {
741
- const res = value();
742
- this.setProp(node, key, res, hookI);
743
- });
744
- } else if (valueIsMapKey) {
745
- new Effect(() => {
746
- const res = data[value];
747
- this.setProp(node, key, res, hookI);
748
- });
749
- } else {
750
- this.setProp(node, key, value, hookI);
714
+ return a = h(null == a ? null : a), f = [], l = function (e) {
715
+ e && f.push(g(e));
716
+ }, p = function (t, r) {
717
+ for (var i = 0; i < n.length; i++) {
718
+ var a = n[i],
719
+ c = a[1],
720
+ l = 7 & c;
721
+ if ((8 & c) == t && !l == r) {
722
+ var p = a[2],
723
+ d = !!a[3],
724
+ m = 16 & c;
725
+ applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function (t) {
726
+ return _checkInRHS(t) === e;
727
+ } : o);
728
+ }
729
+ }
730
+ }, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), {
731
+ e: c,
732
+ get c() {
733
+ var n = [];
734
+ return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)];
735
+ }
736
+ };
737
+ }
738
+ function _arrayLikeToArray(r, a) {
739
+ (null == a || a > r.length) && (a = r.length);
740
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
741
+ return n;
742
+ }
743
+ function _arrayWithHoles(r) {
744
+ if (Array.isArray(r)) return r;
745
+ }
746
+ function _checkInRHS(e) {
747
+ if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null"));
748
+ return e;
749
+ }
750
+ function _iterableToArrayLimit(r, l) {
751
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
752
+ if (null != t) {
753
+ var e,
754
+ n,
755
+ i,
756
+ u,
757
+ a = [],
758
+ f = true,
759
+ o = false;
760
+ try {
761
+ if (i = (t = t.call(r)).next, 0 === l) {
762
+ if (Object(t) !== t) return;
763
+ f = !1;
764
+ } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
765
+ } catch (r) {
766
+ o = true, n = r;
767
+ } finally {
768
+ try {
769
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
770
+ } finally {
771
+ if (o) throw n;
772
+ }
751
773
  }
774
+ return a;
775
+ }
776
+ }
777
+ function _nonIterableRest() {
778
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
779
+ }
780
+ function _objectWithoutProperties(e, t) {
781
+ if (null == e) return {};
782
+ var o,
783
+ r,
784
+ i = _objectWithoutPropertiesLoose(e, t);
785
+ if (Object.getOwnPropertySymbols) {
786
+ var n = Object.getOwnPropertySymbols(e);
787
+ for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
788
+ }
789
+ return i;
790
+ }
791
+ function _objectWithoutPropertiesLoose(r, e) {
792
+ if (null == r) return {};
793
+ var t = {};
794
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
795
+ if (-1 !== e.indexOf(n)) continue;
796
+ t[n] = r[n];
797
+ }
798
+ return t;
799
+ }
800
+ function _setFunctionName(e, t, n) {
801
+ "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : "");
802
+ try {
803
+ Object.defineProperty(e, "name", {
804
+ configurable: !0,
805
+ value: n ? n + " " + t : t
806
+ });
807
+ } catch (e) {}
808
+ return e;
809
+ }
810
+ function _slicedToArray(r, e) {
811
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
812
+ }
813
+ function _toPrimitive(t, r) {
814
+ if ("object" != typeof t || !t) return t;
815
+ var e = t[Symbol.toPrimitive];
816
+ if (void 0 !== e) {
817
+ var i = e.call(t, r);
818
+ if ("object" != typeof i) return i;
819
+ throw new TypeError("@@toPrimitive must return a primitive value.");
820
+ }
821
+ return ("string" === r ? String : Number)(t);
822
+ }
823
+ function _toPropertyKey(t) {
824
+ var i = _toPrimitive(t, "string");
825
+ return "symbol" == typeof i ? i : i + "";
826
+ }
827
+ function _unsupportedIterableToArray(r, a) {
828
+ if (r) {
829
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
830
+ var t = {}.toString.call(r).slice(8, -1);
831
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
752
832
  }
753
- oneRealPropParsed = this.onePropParsed.bind(this);
754
- componentOrFragmentDeclaration(ComponentOrRender, ctx) {
755
- let Component, render, child;
756
- const isCC = ComponentOrRender.prototype instanceof Store;
757
- if (isCC) {
758
- Component = ComponentOrRender;
759
- child = Component.new();
760
- } else {
761
- render = ComponentOrRender;
762
- const boundStore = render.boundStore;
763
- child = deepSignal({}, getPulling(), true);
764
- Object.setPrototypeOf(child, boundStore);
833
+ }
834
+
835
+ let _initProto;
836
+ class Compiler {
837
+ static {
838
+ var _applyDecs$e = _slicedToArray(_applyDecs2311(this, [], [[NodeHook, 2, "parseProgram"], [[NodeHook, NodeLoc], 2, "parseComponentNode"], [[NodeHook, NodeLoc], 2, "parseElementNode"], [[NodeHook, NodeLoc], 2, "parseConditionalNode"], [[NodeHook, NodeLoc], 2, "parseLoopNode"], [NodeHook, 2, "parseProperty"], [[NodeHook, TokenLoc], 2, "parsePropertyKey"], [[NodeHook, TokenLoc], 2, "parsePropertyValue"]]).e, 1);
839
+ _initProto = _applyDecs$e[0];
840
+ }
841
+ constructor(tokenizer, hooks = {}) {
842
+ this.tokenizer = tokenizer;
843
+ this.hooks = hooks;
844
+ _initProto(this);
845
+ }
846
+ parseProgram() {
847
+ this.tokenizer.nextToken();
848
+ const body = [];
849
+ while (!this.tokenizer.isEof()) {
850
+ const node = this.templateNode();
851
+ if (node) {
852
+ body.push(node);
853
+ }
765
854
  }
766
- const node = {
767
- __logicType: isCC ? FakeType.Component : FakeType.Fragment,
768
- realParent: ctx.realParent,
769
- realBefore: null,
770
- realAfter: null,
771
- data: child,
772
- tokenizer: render ? render(true) : child['ui'](true)
773
- };
774
- this.onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
775
- if (isFn) {
776
- child[Keys.Raw][key] = value;
777
- } else if (valueIsMapKey) {
778
- shareSignal(data, value, child, key);
779
- } else {
780
- const meta = child[Keys.Meta];
781
- const cells = meta.cells;
782
- if (typeof value === 'function') {
783
- const computed = new Computed(value);
784
- cells.set(key, computed);
785
- child[Keys.Raw][key] = undefined;
786
- } else {
787
- cells.set(key, {
788
- get: () => value
789
- });
790
- child[Keys.Raw][key] = value;
791
- }
855
+ return {
856
+ type: NodeType.Program,
857
+ body,
858
+ loc: {
859
+ start: {
860
+ offset: 0,
861
+ line: 1,
862
+ column: 0
863
+ },
864
+ end: {
865
+ offset: this.tokenizer.preI,
866
+ line: this.tokenizer.line,
867
+ column: this.tokenizer.column
868
+ },
869
+ source: this.tokenizer.code
792
870
  }
793
871
  };
794
- node.realAfter = this.insertAfterAnchor('component-after');
795
- return node;
796
872
  }
797
- getFn(data, expression) {
798
- return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
799
- }
800
- condDeclaration(ctx) {
801
- const prevSibling = ctx.prevSibling;
802
- const keyWord = this.tokenizer.token;
803
- const expToken = this.tokenizer.condExp();
804
- const value = expToken.value;
805
- const isElse = keyWord.value === 'else';
806
- const isIf = keyWord.value === 'if';
807
- const preIsCond = prevSibling?.__logicType & CondBit;
808
- const data = this.getData();
809
- const noCond = value === true;
810
- const valueIsMapKey = !noCond && Reflect.has(data[Keys.Raw], value);
811
- const owner = ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
812
- const ifNode = {
813
- __logicType: isElse ? FakeType.Else : isIf ? FakeType.If : FakeType.Fail,
814
- snapshot: this.tokenizer.snapshot(),
815
- realParent: null,
816
- realBefore: null,
817
- realAfter: null,
818
- condition: null,
819
- preCond: preIsCond ? prevSibling : null,
820
- isFirstRender: true,
821
- effect: null,
822
- owner,
823
- data
824
- };
825
- let signal;
826
- switch (keyWord.value) {
827
- case 'if':
828
- if (valueIsMapKey) {
829
- runWithPulling(() => data[value], null);
830
- const cells = data[Keys.Meta].cells;
831
- signal = cells.get(value);
832
- } else {
833
- const fn = this.getFn(data, value);
834
- signal = new Computed(fn);
835
- }
836
- break;
837
- case 'else':
838
- if (noCond) {
839
- signal = new Computed(() => {
840
- let point = ifNode.preCond;
841
- while (point) {
842
- if (point.condition.get()) {
843
- return false;
844
- }
845
- if (point.__logicType === FakeType.If) {
846
- break;
847
- }
848
- point = point.preCond;
849
- }
850
- return true;
851
- });
852
- } else {
853
- const fn = valueIsMapKey ? null : this.getFn(data, value);
854
- signal = new Computed(() => {
855
- let point = ifNode.preCond;
856
- while (point) {
857
- if (point.condition.get()) {
858
- return false;
859
- }
860
- if (point.__logicType === FakeType.If) {
861
- break;
862
- }
863
- point = point.preCond;
864
- }
865
- return valueIsMapKey ? data[value] : fn();
866
- });
867
- }
868
- break;
869
- case 'fail':
870
- signal = new Computed(() => {
871
- let point = ifNode.preCond;
872
- while (point) {
873
- if (point.condition.get()) {
874
- return false;
875
- }
876
- point = point.preCond;
877
- }
878
- return true;
879
- });
880
- break;
881
- }
882
- ifNode.condition = signal;
883
- ifNode.realAfter = this.insertAfterAnchor(`${keyWord.value}-after`);
884
- const ef = effect(({
885
- val
886
- }) => {
887
- if (val) {
888
- if (ifNode.isFirstRender) {
889
- this.tokenizer.nextToken();
890
- this.tokenizer.nextToken();
891
- } else {
892
- this.tokenizer = ifNode.owner.tokenizer;
893
- this.tokenizer.resume(ifNode.snapshot);
894
- this.tokenizer.useDedentAsEof = false;
895
- this.program(ifNode.realParent, ifNode.owner, ifNode.realBefore, ifNode);
896
- }
897
- } else {
898
- if (ifNode.isFirstRender) {
899
- this.tokenizer.skip();
900
- } else {
901
- this.removeLogicNode(ifNode);
873
+ handleChildren() {
874
+ const children = [];
875
+ if (this.tokenizer.token.type & TokenType.Indent) {
876
+ this.tokenizer.nextToken();
877
+ while (!(this.tokenizer.token.type & TokenType.Dedent) && !this.tokenizer.isEof()) {
878
+ const child = this.templateNode();
879
+ if (child) {
880
+ children.push(child);
902
881
  }
903
882
  }
904
- ifNode.isFirstRender = false;
905
- }, [signal]);
906
- ifNode.effect = ef;
907
- return ifNode;
883
+ if (this.tokenizer.token.type & TokenType.Dedent) {
884
+ this.tokenizer.nextToken();
885
+ }
886
+ }
887
+ return children;
908
888
  }
909
- removeLogicNode(node) {
910
- const realBefore = node.realBefore,
911
- realAfter = node.realAfter,
912
- realParent = node.realParent;
913
- let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
914
- while (point !== realAfter) {
915
- const next = this.nextSib(point);
916
- this.remove(point, realParent, realBefore);
917
- point = next;
889
+ templateNode() {
890
+ this.tokenizer.token;
891
+ const _this$tokenizer$_hook = this.tokenizer._hook({}),
892
+ _this$tokenizer$_hook2 = _slicedToArray(_this$tokenizer$_hook, 2),
893
+ hookType = _this$tokenizer$_hook2[0],
894
+ value = _this$tokenizer$_hook2[1];
895
+ if (value === 'if' || value === 'else' || value === 'fail') {
896
+ return this.parseConditionalNode();
918
897
  }
898
+ if (value === 'for') {
899
+ return this.parseLoopNode();
900
+ }
901
+ if (hookType) {
902
+ return this.parseComponentNode();
903
+ }
904
+ return this.parseElementNode();
919
905
  }
920
- extensionLines(_node) {
921
- while (1) {
922
- if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
923
- return;
924
- }
906
+ parseComponentNode(node) {
907
+ const tagToken = this.tokenizer.token;
908
+ const tagName = tagToken.value;
909
+ this.tokenizer.nextToken();
910
+ const props = this.headerLineAndExtensions();
911
+ node.type = NodeType.Component;
912
+ node.componentName = tagName;
913
+ node.props = props;
914
+ this.hooks.parseComponentNode?.propsAdded?.call(this, node);
915
+ const children = this.handleChildren();
916
+ node.children = children;
917
+ return node;
918
+ }
919
+ parseElementNode(node) {
920
+ const tagToken = this.tokenizer.token;
921
+ const tagName = tagToken.value;
922
+ this.tokenizer.nextToken();
923
+ const props = this.headerLineAndExtensions();
924
+ node.type = NodeType.Element;
925
+ node.tagName = tagName;
926
+ node.props = props;
927
+ this.hooks.parseElementNode?.propsAdded?.call(this, node);
928
+ const children = this.handleChildren();
929
+ node.children = children;
930
+ return node;
931
+ }
932
+ parseConditionalNode(node) {
933
+ const keyword = this.tokenizer.token.value;
934
+ const conditionToken = this.tokenizer.condExp();
935
+ const condition = conditionToken.value;
936
+ this.tokenizer.nextToken();
937
+ this.tokenizer.nextToken();
938
+ node.type = keyword === 'if' ? NodeType.If : keyword === 'else' ? NodeType.Else : NodeType.Fail;
939
+ node.condition = condition;
940
+ this.hooks.parseConditionalNode?.propsAdded?.call(this, node);
941
+ const children = this.handleChildren();
942
+ node.children = children;
943
+ return node;
944
+ }
945
+ parseLoopNode(node) {
946
+ const collection = this.tokenizer.nextToken().value;
947
+ this.tokenizer.nextToken();
948
+ const itemToken = this.tokenizer.nextToken();
949
+ const isDestruct = itemToken.type === TokenType.InsertionExp;
950
+ let item = isDestruct ? `{${itemToken.value}}` : itemToken.value;
951
+ let char = this.tokenizer.peekChar(),
952
+ key,
953
+ index;
954
+ if (char === ';') {
925
955
  this.tokenizer.nextToken();
926
- this.attributeList(_node);
927
- if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
928
- return;
956
+ if (this.tokenizer.peekChar() !== '\n') key = this.tokenizer.jsExp().value;
957
+ } else if (char === '\n') ; else {
958
+ index = this.tokenizer.nextToken().value;
959
+ if (this.tokenizer.peekChar() === ';') {
960
+ this.tokenizer.nextToken();
961
+ if (this.tokenizer.peekChar() !== '\n') key = this.tokenizer.jsExp().value;
929
962
  }
930
- this.tokenizer.nextToken();
931
963
  }
932
- }
933
- headerLine(_node) {
934
- this.attributeList(_node);
935
964
  this.tokenizer.nextToken();
965
+ this.tokenizer.nextToken();
966
+ node.type = NodeType.For;
967
+ node.collection = collection;
968
+ node.item = item;
969
+ node.index = index;
970
+ node.key = key;
971
+ this.hooks.parseLoopNode?.propsAdded?.call(this, node);
972
+ const children = this.handleChildren();
973
+ node.children = children;
974
+ return node;
936
975
  }
937
- attributeList(_node) {
938
- let key, eq;
939
- const data = this.getData();
940
- while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
941
- if (key == null) {
942
- key = this.tokenizer.token.value;
943
- } else if (eq == null) {
944
- eq = '=';
945
- } else {
946
- const _this$tokenizer$_hook3 = this.tokenizer._hook({}),
947
- _this$tokenizer$_hook4 = _slicedToArray(_this$tokenizer$_hook3, 3),
948
- hookType = _this$tokenizer$_hook4[0],
949
- value = _this$tokenizer$_hook4[1],
950
- hookI = _this$tokenizer$_hook4[2];
951
- const rawVal = data[Keys.Raw][value];
952
- const isFn = typeof rawVal === 'function';
953
- if (hookType === 'dynamic') {
954
- const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
955
- const fn = isFn ? rawVal : valueIsMapKey ? value : this.getFn(data, value);
956
- this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
957
- } else if (hookType === 'static') {
958
- this.onePropParsed(data, _node, key, value, false, isFn, hookI);
959
- } else {
960
- this.onePropParsed(data, _node, key, value, false, isFn, hookI);
961
- }
962
- key = null;
963
- eq = null;
976
+ headerLineAndExtensions() {
977
+ const props = [];
978
+ props.push(...this.attributeList());
979
+ if (this.tokenizer.token.type & TokenType.NewLine) {
980
+ this.tokenizer.nextToken();
981
+ }
982
+ while (this.tokenizer.token.type & TokenType.Pipe) {
983
+ this.tokenizer.nextToken();
984
+ props.push(...this.attributeList());
985
+ if (this.tokenizer.token.type & TokenType.NewLine) {
986
+ this.tokenizer.nextToken();
964
987
  }
988
+ }
989
+ return props;
990
+ }
991
+ attributeList() {
992
+ const props = [];
993
+ while (!(this.tokenizer.token.type & TokenType.NewLine) && !(this.tokenizer.token.type & TokenType.Pipe) && !this.tokenizer.isEof()) {
994
+ props.push(this.parseProperty());
995
+ }
996
+ return props;
997
+ }
998
+ parseProperty(node) {
999
+ node.type = NodeType.Property;
1000
+ node.key = this.parsePropertyKey();
1001
+ const token = this.tokenizer.nextToken();
1002
+ if (token.value === '=') {
1003
+ this.tokenizer.nextToken();
1004
+ node.value = this.parsePropertyValue();
965
1005
  this.tokenizer.nextToken();
966
1006
  }
1007
+ node.loc.start = node.key.loc.start;
1008
+ node.loc.end = node.value ? node.value.loc.end : node.key.loc.end;
1009
+ node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1010
+ return node;
1011
+ }
1012
+ parsePropertyKey(node) {
1013
+ node.type = NodeType.PropertyKey;
1014
+ node.key = this.tokenizer.token.value;
1015
+ return node;
967
1016
  }
968
- config(opt) {
969
- Object.assign(this, opt);
970
- this.opt = opt;
1017
+ parsePropertyValue(node) {
1018
+ const _this$tokenizer$_hook3 = this.tokenizer._hook({}),
1019
+ _this$tokenizer$_hook4 = _slicedToArray(_this$tokenizer$_hook3, 2),
1020
+ hookType = _this$tokenizer$_hook4[0],
1021
+ value = _this$tokenizer$_hook4[1];
1022
+ node.type = hookType === 'dynamic' ? NodeType.DynamicValue : NodeType.StaticValue;
1023
+ node.value = value;
1024
+ return node;
971
1025
  }
972
- createNode(name) {
973
- return {
974
- name,
975
- props: {},
976
- nextSibling: null
1026
+ }
1027
+ function NodeLoc(target, context) {
1028
+ return function (_node) {
1029
+ _node.loc.start = this.tokenizer.token.loc.start;
1030
+ const result = target.call(this, _node);
1031
+ _node.loc.end = this.tokenizer.token.loc ? this.tokenizer.token.loc.start : this.tokenizer.getCurrentPos();
1032
+ _node.loc.source = this.tokenizer.code.slice(_node.loc.start.offset, _node.loc.end.offset);
1033
+ return result;
1034
+ };
1035
+ }
1036
+ function TokenLoc(target, context) {
1037
+ return function (_node) {
1038
+ const result = target.call(this, _node);
1039
+ _node.loc = this.tokenizer.token.loc;
1040
+ return result;
1041
+ };
1042
+ }
1043
+ function NodeHook(target, context) {
1044
+ return function (_node) {
1045
+ const hook = this.hooks[context.name];
1046
+ const node = {
1047
+ loc: {}
1048
+ };
1049
+ hook?.enter?.call(this, node);
1050
+ const result = target.call(this, node);
1051
+ hook?.leave?.call(this, node);
1052
+ return result;
1053
+ };
1054
+ }
1055
+
1056
+ class MultiTypeStack {
1057
+ typeTops = {};
1058
+ length = 0;
1059
+ stack = [];
1060
+ push(value, bits) {
1061
+ const newNode = {
1062
+ value,
1063
+ types: bits,
1064
+ prevByType: {}
977
1065
  };
1066
+ let bit;
1067
+ while (1) {
1068
+ bit = bits & ~bits + 1;
1069
+ if (!bit) break;
1070
+ bits &= ~bit;
1071
+ newNode.prevByType[bit] = this.typeTops[bit] || undefined;
1072
+ this.typeTops[bit] = newNode;
1073
+ }
1074
+ this.stack[this.length++] = newNode;
978
1075
  }
979
- nextSib(node) {
980
- return node.nextSibling;
1076
+ pop() {
1077
+ const poppedNode = this.stack[this.length - 1];
1078
+ this.stack[--this.length] = null;
1079
+ if (!poppedNode) return undefined;
1080
+ let bits = poppedNode.types;
1081
+ let bit;
1082
+ while (1) {
1083
+ bit = bits & ~bits + 1;
1084
+ if (!bit) break;
1085
+ bits &= ~bit;
1086
+ this.typeTops[bit] = poppedNode.prevByType[bit];
1087
+ }
1088
+ return [poppedNode.value, poppedNode.types];
981
1089
  }
982
- firstChild(node) {
983
- return node.firstChild;
1090
+ peekByType(cat) {
1091
+ return this.typeTops[cat]?.value;
984
1092
  }
985
- createAnchor(name) {
986
- return {
987
- name,
988
- nextSibling: null
989
- };
1093
+ peekType() {
1094
+ return this.stack.at(-1).types;
990
1095
  }
991
- insertAfter(parent, node, prev) {
992
- return this.defaultInsert(parent, node, prev);
1096
+ peek() {
1097
+ return this.stack.at(-1).value;
993
1098
  }
994
- defaultInsert(parent, node, prev) {
995
- if (prev) {
996
- const next = prev.nextSibling;
997
- prev.nextSibling = node;
998
- node.nextSibling = next;
999
- } else {
1000
- const next = parent.firstChild;
1001
- parent.firstChild = node;
1002
- node.nextSibling = next;
1099
+ }
1100
+
1101
+ function macInc(arr) {
1102
+ const len = arr.length;
1103
+ let candyLast = [],
1104
+ i = 0;
1105
+ while (i < len) {
1106
+ const it = arr[i];
1107
+ if (it !== -1) {
1108
+ candyLast = [i];
1109
+ break;
1003
1110
  }
1111
+ i++;
1004
1112
  }
1005
- remove(node, parent, prev) {
1006
- return this.defaultRemove(node, parent, prev);
1007
- }
1008
- defaultRemove(node, parent, prevSibling) {
1009
- const next = node.nextSibling;
1010
- if (prevSibling) {
1011
- prevSibling.nextSibling = next;
1012
- }
1013
- if (parent.firstChild === node) {
1014
- parent.firstChild = next;
1113
+ if (i + 1 >= len) return candyLast;
1114
+ const toPrev = new Int32Array(len);
1115
+ while (i < len) {
1116
+ const target = arr[i];
1117
+ if (target === -1) continue;
1118
+ let start = -1,
1119
+ end = candyLast.length;
1120
+ while (start + 1 < end) {
1121
+ const mid = start + end >> 1;
1122
+ if (arr[candyLast[mid]] < target) {
1123
+ start = mid;
1124
+ } else {
1125
+ end = mid;
1126
+ }
1015
1127
  }
1128
+ candyLast[end] = i;
1129
+ toPrev[i] = candyLast[start];
1130
+ i++;
1016
1131
  }
1017
- setProp(node, key, value, hookI) {
1018
- node.props[key] = value;
1132
+ let length = candyLast.length;
1133
+ for (let j = length - 1; j > 0; j--) {
1134
+ const prev = toPrev[candyLast[j]];
1135
+ candyLast[j - 1] = prev;
1019
1136
  }
1137
+ return candyLast;
1020
1138
  }
1021
1139
 
1022
- class Tokenizer {
1023
- TabSize = 2;
1024
- Tab = Array.from({
1025
- length: this.TabSize
1026
- }, () => ' ').join('');
1027
- static EofId = `__EOF__${Date.now()}`;
1028
- static DedentId = `__DEDENT__${Date.now()}`;
1029
- needIndent = false;
1030
- isFirstToken = true;
1031
- dentStack = [0];
1032
- i = 0;
1033
- handledTokens = [];
1034
- waitingTokens = new Queue();
1035
- constructor(hook, useDedentAsEof) {
1036
- this.hook = hook;
1037
- this.useDedentAsEof = useDedentAsEof;
1038
- if (useDedentAsEof) {
1039
- this.setToken(TokenType.Indent, '');
1040
- this.isFirstToken = true;
1140
+ const KEY_INDEX = '__BOBE_KEY_INDEX';
1141
+
1142
+ const _excluded = ["dentStack", "isFirstToken"];
1143
+ class Interpreter {
1144
+ constructor(tokenizer) {
1145
+ this.tokenizer = tokenizer;
1146
+ }
1147
+ isLogicNode(node) {
1148
+ return node && node.__logicType & LogicalBit;
1149
+ }
1150
+ rootComponent = null;
1151
+ program(root, componentNode, before, ctxProvider) {
1152
+ this.rootComponent = componentNode;
1153
+ this.tokenizer.nextToken();
1154
+ const stack = new MultiTypeStack();
1155
+ stack.push({
1156
+ node: root,
1157
+ prev: null
1158
+ }, NodeSort.Real);
1159
+ stack.push({
1160
+ node: componentNode,
1161
+ prev: null
1162
+ }, NodeSort.Component | NodeSort.CtxProvider | NodeSort.TokenizerSwitcher);
1163
+ if (ctxProvider) {
1164
+ stack.push({
1165
+ node: ctxProvider,
1166
+ prev: null
1167
+ }, (ctxProvider.__logicType & LogicalBit ? NodeSort.Logic : 0) | NodeSort.CtxProvider);
1168
+ }
1169
+ const rootLen = stack.length;
1170
+ const ctx = this.ctx = {
1171
+ realParent: root,
1172
+ prevSibling: before,
1173
+ current: null,
1174
+ stack,
1175
+ before
1176
+ };
1177
+ const rootPulling = getPulling();
1178
+ while (1) {
1179
+ if (this.tokenizer.isEof()) {
1180
+ if (!ctx.prevSibling) ctx.prevSibling = before;
1181
+ this.handleInsert(root, ctx.current, ctx.prevSibling, componentNode);
1182
+ break;
1183
+ }
1184
+ const token = this.tokenizer.token;
1185
+ if (token.type & TokenType.Indent) {
1186
+ this.tokenizer.nextToken();
1187
+ const isLogicNode = this.isLogicNode(ctx.current);
1188
+ stack.push({
1189
+ node: ctx.current,
1190
+ prev: ctx.prevSibling
1191
+ }, !ctx.current.__logicType ? NodeSort.Real : (ctx.current.__logicType & LogicalBit ? NodeSort.Logic : 0) | (ctx.current.__logicType & TokenizerSwitcherBit ? NodeSort.TokenizerSwitcher : 0) | (ctx.current.__logicType === FakeType.Component ? NodeSort.Component : 0) | NodeSort.CtxProvider);
1192
+ if (ctx.current.__logicType) {
1193
+ if (isLogicNode) {
1194
+ setPulling(ctx.current.effect);
1195
+ if (ctx.current.__logicType & FakeType.ForItem) {
1196
+ ctx.prevSibling = ctx.current.realBefore;
1197
+ }
1198
+ }
1199
+ } else {
1200
+ if (ctx.current) {
1201
+ ctx.realParent = ctx.current;
1202
+ }
1203
+ ctx.prevSibling = null;
1204
+ }
1205
+ ctx.current = this.declaration(ctx);
1206
+ continue;
1207
+ }
1208
+ if (ctx.current) {
1209
+ if (stack.length === rootLen && !ctx.prevSibling) {
1210
+ ctx.prevSibling = before;
1211
+ }
1212
+ this.handleInsert(ctx.realParent, ctx.current, ctx.prevSibling);
1213
+ }
1214
+ if (this.tokenizer.token.type & TokenType.Dedent) {
1215
+ this.tokenizer.nextToken();
1216
+ const _stack$pop = stack.pop(),
1217
+ _stack$pop2 = _slicedToArray(_stack$pop, 2),
1218
+ _stack$pop2$ = _stack$pop2[0],
1219
+ parent = _stack$pop2$.node,
1220
+ prev = _stack$pop2$.prev,
1221
+ sort = _stack$pop2[1];
1222
+ if (!parent.__logicType) {
1223
+ const prevSameType = stack.peekByType(NodeSort.Real);
1224
+ ctx.realParent = prevSameType?.node || root;
1225
+ } else {
1226
+ if (sort & NodeSort.Logic) {
1227
+ const parentLogic = stack.peekByType(NodeSort.Logic)?.node;
1228
+ if (parentLogic) {
1229
+ setPulling(parentLogic.effect);
1230
+ } else {
1231
+ setPulling(rootPulling);
1232
+ }
1233
+ }
1234
+ if (sort & NodeSort.TokenizerSwitcher) {
1235
+ const switcher = stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1236
+ this.tokenizer = switcher.tokenizer;
1237
+ }
1238
+ if (parent.__logicType === FakeType.ForItem) {
1239
+ const _ref = parent,
1240
+ forNode = _ref.forNode;
1241
+ const i = forNode.i,
1242
+ arr = forNode.arr,
1243
+ snapshot = forNode.snapshot;
1244
+ if (i + 1 < arr.length) {
1245
+ this.tokenizer.resume(snapshot);
1246
+ this.tokenizer.nextToken();
1247
+ this.tokenizer.nextToken();
1248
+ ctx.current = forNode.children[++forNode.i];
1249
+ ctx.prevSibling = ctx.current.realBefore;
1250
+ continue;
1251
+ }
1252
+ ctx.prevSibling = forNode.prevSibling;
1253
+ ctx.current = forNode;
1254
+ continue;
1255
+ }
1256
+ }
1257
+ ctx.prevSibling = prev;
1258
+ ctx.current = parent;
1259
+ } else {
1260
+ ctx.prevSibling = ctx.current || ctx.prevSibling;
1261
+ ctx.current = this.declaration(ctx);
1262
+ }
1041
1263
  }
1264
+ return componentNode;
1042
1265
  }
1043
- consume() {
1044
- const token = this.token;
1045
- this.nextToken();
1046
- return token;
1047
- }
1048
- resume(_snapshot) {
1049
- this.token = undefined;
1050
- this.needIndent = false;
1051
- this.isFirstToken = true;
1052
- this.dentStack = [0];
1053
- Object.assign(this, _snapshot);
1266
+ insertAfterAnchor(name = 'anchor') {
1267
+ const _this$ctx = this.ctx,
1268
+ realParent = _this$ctx.realParent,
1269
+ prevSibling = _this$ctx.prevSibling,
1270
+ stack = _this$ctx.stack,
1271
+ before = _this$ctx.before;
1272
+ const afterAnchor = this.createAnchor(name);
1273
+ this.ctx.prevSibling = stack.length === 2 && !prevSibling ? before : prevSibling;
1274
+ this.handleInsert(realParent, afterAnchor, prevSibling);
1275
+ return afterAnchor;
1054
1276
  }
1055
- snapshot(keys) {
1056
- const snap = {
1057
- i: this.i,
1058
- waitingTokens: this.waitingTokens.clone()
1059
- };
1060
- if (keys) {
1061
- for (const k of keys) {
1062
- snap[k] = this[k];
1063
- if (k === 'dentStack') {
1064
- snap[k] = this[k].slice();
1065
- }
1277
+ handleInsert(parent, child, prev, parentComponent) {
1278
+ if (!child.__logicType) {
1279
+ if (!prev || !prev.__logicType) {
1280
+ this.insertAfter(parent, child, prev);
1281
+ } else {
1282
+ const before = prev.realAfter;
1283
+ this.insertAfter(parent, child, before);
1284
+ }
1285
+ } else {
1286
+ const childCmp = child;
1287
+ childCmp.realParent = parent;
1288
+ if (prev?.__logicType) {
1289
+ childCmp.realBefore = prev.forNode ? prev.forNode.realAfter : prev.realAfter;
1290
+ } else {
1291
+ childCmp.realBefore = prev;
1066
1292
  }
1067
1293
  }
1068
- return snap;
1069
1294
  }
1070
- skip() {
1071
- const logicDentLen = this.dentStack[this.dentStack.length - 1];
1072
- let needIndent = false;
1073
- let skipFragment = ``;
1074
- this.token = undefined;
1075
- while (1) {
1076
- const char = this.code[this.i];
1077
- if (char === '\n') {
1078
- needIndent = true;
1079
- skipFragment += char;
1080
- this.i++;
1081
- continue;
1082
- }
1083
- if (!needIndent) {
1084
- skipFragment += char;
1085
- this.i++;
1086
- continue;
1295
+ getPrevRealSibling(prevSibling) {
1296
+ if (!prevSibling || !prevSibling.__logicType) {
1297
+ return prevSibling;
1298
+ }
1299
+ let point = prevSibling;
1300
+ while (point != null) {
1301
+ if (point.lastChild) {
1302
+ return point.lastChild.value;
1087
1303
  }
1088
- needIndent = false;
1089
- const _this$getDentValue = this.getDentValue(),
1090
- value = _this$getDentValue.value,
1091
- isEmptyLine = _this$getDentValue.isEmptyLine;
1092
- const currLen = value.length;
1093
- if (isEmptyLine) continue;
1094
- if (currLen > logicDentLen) {
1095
- skipFragment += value;
1304
+ point = point.anchor;
1305
+ }
1306
+ }
1307
+ declaration(ctx) {
1308
+ const _this$tokenizer$_hook = this.tokenizer._hook({}),
1309
+ _this$tokenizer$_hook2 = _slicedToArray(_this$tokenizer$_hook, 2),
1310
+ hookType = _this$tokenizer$_hook2[0],
1311
+ value = _this$tokenizer$_hook2[1];
1312
+ let _node;
1313
+ if (value === 'if' || value === 'else' || value === 'fail') {
1314
+ return this.condDeclaration(ctx);
1315
+ } else if (value === 'for') {
1316
+ return this.forDeclaration();
1317
+ } else if (hookType) {
1318
+ const data = this.getData();
1319
+ if (hookType === 'static') {
1320
+ if (typeof value === 'function') {
1321
+ _node = this.componentOrFragmentDeclaration(value, ctx);
1322
+ } else {
1323
+ throw new SyntaxError(`declaration 不支持 ${value} 类型的静态插值`);
1324
+ }
1096
1325
  } else {
1097
- for (let i = this.dentStack.length - 1; i >= 0; i--) {
1098
- const expLen = this.dentStack[i];
1099
- if (currLen === expLen) break;
1100
- if (currLen > expLen) {
1101
- throw SyntaxError(`缩进错误,缩进长度不匹配`);
1102
- }
1103
- if (this.shorterThanBaseDentEof()) {
1104
- break;
1105
- }
1106
- this.dentStack.pop();
1107
- if (!this.token) {
1108
- this.setToken(TokenType.Dedent, String(expLen));
1109
- } else {
1110
- this.waitingTokens.push({
1111
- type: TokenType.Dedent,
1112
- typeName: TokenType[TokenType.Dedent],
1113
- value: String(expLen)
1114
- });
1115
- }
1326
+ const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
1327
+ const val = data[Keys.Raw][value];
1328
+ if (typeof val === 'function') {
1329
+ _node = this.componentOrFragmentDeclaration(val, ctx);
1330
+ } else {
1331
+ const str = valueIsMapKey ? value : this.getFn(data, value);
1332
+ _node = this.createNode('text');
1333
+ this.onePropParsed(data, _node, 'text', str, valueIsMapKey, false);
1116
1334
  }
1117
- break;
1118
1335
  }
1336
+ } else {
1337
+ _node = this.createNode(value);
1119
1338
  }
1120
- if (!this.token) {
1121
- this.nextToken();
1339
+ this.tokenizer.nextToken();
1340
+ this.headerLine(_node);
1341
+ this.extensionLines(_node);
1342
+ if (_node.__logicType & TokenizerSwitcherBit) {
1343
+ this.onePropParsed = this.oneRealPropParsed;
1344
+ this.tokenizer = _node.tokenizer;
1122
1345
  }
1123
- return skipFragment;
1124
- }
1125
- setCode(code) {
1126
- this.code = '\n' + code.trimEnd() + `\n${Tokenizer.EofId}`;
1127
- }
1128
- tokenize() {
1129
- do {
1130
- this.nextToken();
1131
- console.log('token:', TokenType[this.token?.type], JSON.stringify(this.token?.value || ''));
1132
- } while (!this.isEof());
1133
- }
1134
- isEof() {
1135
- if (!this.token) return false;
1136
- return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
1137
- }
1138
- setToken(type, value) {
1139
- this.token = {
1140
- type,
1141
- typeName: TokenType[type],
1142
- value
1143
- };
1144
- this.isFirstToken = false;
1346
+ return _node;
1145
1347
  }
1146
- nextToken() {
1147
- try {
1148
- if (this.isEof()) {
1149
- return this.token;
1150
- }
1151
- this.token = undefined;
1152
- if (this.waitingTokens.len) {
1153
- const item = this.waitingTokens.shift();
1154
- this.setToken(item.type, item.value);
1155
- return this.token;
1348
+ forDeclaration() {
1349
+ const arrExp = this.tokenizer.nextToken().value;
1350
+ this.tokenizer.nextToken();
1351
+ const itemToken = this.tokenizer.nextToken();
1352
+ const isDestruct = itemToken.type === TokenType.InsertionExp;
1353
+ let itemExp = itemToken.value,
1354
+ vars;
1355
+ if (isDestruct) {
1356
+ itemExp = '{' + itemExp + '}';
1357
+ vars = itemExp.match(jsVarRegexp);
1358
+ const varStr = vars.join(',');
1359
+ itemExp = new Function(itemExp, `return {${varStr}};`);
1360
+ }
1361
+ let indexName,
1362
+ keyExp,
1363
+ char = this.tokenizer.peekChar();
1364
+ if (char === ';') {
1365
+ this.tokenizer.nextToken();
1366
+ if (this.tokenizer.peekChar() !== '\n') keyExp = this.tokenizer.jsExp().value;
1367
+ } else if (char === '\n') ; else {
1368
+ indexName = this.tokenizer.nextToken().value;
1369
+ if (this.tokenizer.peekChar() === ';') {
1370
+ this.tokenizer.nextToken();
1371
+ if (this.tokenizer.peekChar() !== '\n') keyExp = this.tokenizer.jsExp().value;
1156
1372
  }
1157
- outer: while (1) {
1158
- if (this.needIndent) {
1159
- this.dent();
1373
+ }
1374
+ const owner = this.ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1375
+ const prevSibling = this.ctx.prevSibling;
1376
+ const forNode = {
1377
+ __logicType: FakeType.For,
1378
+ snapshot: this.tokenizer.snapshot(['dentStack', 'isFirstToken']),
1379
+ realParent: this.ctx.realParent,
1380
+ prevSibling,
1381
+ realBefore: prevSibling?.realAfter || prevSibling,
1382
+ realAfter: null,
1383
+ arr: null,
1384
+ arrSignal: null,
1385
+ itemExp,
1386
+ indexName,
1387
+ getKey: null,
1388
+ children: [],
1389
+ effect: null,
1390
+ owner,
1391
+ vars,
1392
+ i: 0
1393
+ };
1394
+ if (keyExp) {
1395
+ forNode.getKey = new Function('data', `let v;with(data){v=${keyExp}};return v;`);
1396
+ }
1397
+ window['for1'] = forNode;
1398
+ const data = this.getData();
1399
+ const cells = data[Keys.Meta].cells;
1400
+ const hasArrExpKey = Reflect.has(data[Keys.Raw], arrExp);
1401
+ const arrSignal = hasArrExpKey ? (data[arrExp], cells.get(arrExp)) : new Computed(this.getFn(data, arrExp));
1402
+ forNode.arrSignal = arrSignal;
1403
+ forNode.realAfter = this.insertAfterAnchor('for-after');
1404
+ const _forNode$snapshot = forNode.snapshot;
1405
+ _forNode$snapshot.dentStack;
1406
+ _forNode$snapshot.isFirstToken;
1407
+ const snapshotForUpdate = _objectWithoutProperties(_forNode$snapshot, _excluded);
1408
+ let isFirstRender = true;
1409
+ forNode.effect = new Effect(() => {
1410
+ let arr = arrSignal.get();
1411
+ arr[Keys.Iterator];
1412
+ const prevCtx = getPulling();
1413
+ setPulling(null);
1414
+ forNode.arr = arr = toRaw(arr);
1415
+ const children = forNode.children;
1416
+ if (isFirstRender) {
1417
+ const len = arr.length;
1418
+ for (let i = len; i--;) {
1419
+ const item = this.createForItem(forNode, i, data);
1420
+ item.realAfter = this.insertAfterAnchor('for-item-after');
1421
+ item.realBefore = this.insertAfterAnchor('for-item-before');
1422
+ item.realParent = forNode.realParent;
1423
+ children[i] = item;
1424
+ }
1425
+ const firstInsert = children[0];
1426
+ if (firstInsert) {
1427
+ this.tokenizer.nextToken();
1428
+ this.tokenizer.nextToken();
1160
1429
  } else {
1161
- const char = this.code[this.i];
1162
- switch (char) {
1163
- case '\t':
1164
- case ' ':
1165
- break;
1166
- case '\n':
1167
- this.newLine();
1168
- this.needIndent = true;
1169
- break;
1170
- case '=':
1171
- this.assignment();
1172
- break;
1173
- case '|':
1174
- this.pipe();
1175
- break;
1176
- case "'":
1177
- case '"':
1178
- this.str(char);
1179
- break;
1180
- case '{':
1181
- const braceToken = this.brace();
1182
- this.setToken(TokenType.InsertionExp, braceToken);
1430
+ this.tokenizer.skip();
1431
+ }
1432
+ } else {
1433
+ const oldLen = children.length;
1434
+ const newLen = arr.length;
1435
+ const minLen = Math.min(oldLen, newLen);
1436
+ const newChildren = [];
1437
+ if (!forNode.getKey) {
1438
+ if (newLen < oldLen) {
1439
+ for (let i = oldLen - 1; i >= newLen; i--) {
1440
+ this.removeForItem(children, i);
1441
+ }
1442
+ }
1443
+ if (oldLen < newLen) {
1444
+ const lastAfter = children.at(-1)?.realAfter || forNode.realBefore;
1445
+ for (let i = newLen - 1; i >= oldLen; i--) {
1446
+ this.insertForItem(forNode, i, data, newChildren, lastAfter, snapshotForUpdate);
1447
+ }
1448
+ }
1449
+ for (let i = minLen; i--;) {
1450
+ const child = children[i];
1451
+ newChildren[i] = child;
1452
+ this.reuseForItem(child, arr[i], itemExp, i, indexName);
1453
+ }
1454
+ } else {
1455
+ let s = 0,
1456
+ e1 = oldLen - 1,
1457
+ e2 = newLen - 1;
1458
+ while (s <= e1 && s <= e2) {
1459
+ const child = children[s];
1460
+ const old = child.key;
1461
+ const itemData = this.getItemData(forNode, s, data);
1462
+ const key = forNode.getKey(itemData);
1463
+ if (old === key) {
1464
+ newChildren[s] = child;
1465
+ this.reuseForItem(child, arr[s], itemExp, s, indexName);
1466
+ s++;
1467
+ } else {
1183
1468
  break;
1184
- case '$':
1185
- const handled = this.dynamic(char);
1186
- if (handled) break;
1187
- case ';':
1188
- this.setToken(TokenType.Semicolon, ';');
1469
+ }
1470
+ }
1471
+ while (s <= e1 && s <= e2) {
1472
+ const child = children[e1];
1473
+ const old = child.key;
1474
+ const itemData = this.getItemData(forNode, e2, data);
1475
+ const key = forNode.getKey(itemData);
1476
+ if (old === key) {
1477
+ newChildren[e2] = child;
1478
+ this.reuseForItem(child, arr[e2], itemExp, e2, indexName);
1479
+ e1--;
1480
+ e2--;
1481
+ } else {
1189
1482
  break;
1190
- default:
1191
- if (isNum(char)) {
1192
- this.number(char);
1193
- break;
1483
+ }
1484
+ }
1485
+ if (s > e1) {
1486
+ if (s <= e2) {
1487
+ const firstBefore = s > 0 ? children[s - 1]?.realAfter || forNode.realBefore : forNode.realBefore;
1488
+ for (let i = e2; i >= s; i--) {
1489
+ this.insertForItem(forNode, i, data, newChildren, firstBefore, snapshotForUpdate);
1194
1490
  }
1195
- if (typeof char === 'string' && matchIdStart2(char, 0)) {
1196
- this.identifier(char);
1491
+ }
1492
+ } else if (s > e2) {
1493
+ if (s <= e1) {
1494
+ for (let i = e1; i >= s; i--) {
1495
+ this.removeForItem(children, i);
1197
1496
  }
1198
- break;
1497
+ }
1498
+ } else {
1499
+ let s1 = s,
1500
+ s2 = s;
1501
+ const mixLen = e2 - s2 + 1;
1502
+ const key2new = new Map();
1503
+ for (let i = s2; i <= e2; i++) {
1504
+ const itemData = this.getItemData(forNode, i, data);
1505
+ const key = forNode.getKey(itemData);
1506
+ key2new.set(key, i);
1507
+ }
1508
+ let maxIncNewI = -1;
1509
+ let hasMove = false;
1510
+ const new2oldI = new Array(mixLen).fill(-1);
1511
+ for (let i = s1; i <= e1; i++) {
1512
+ const key = children[i].key;
1513
+ const newI = key2new.get(key);
1514
+ if (newI == null) {
1515
+ this.removeForItem(children, i);
1516
+ continue;
1517
+ }
1518
+ const child = children[i];
1519
+ newChildren[newI] = child;
1520
+ this.reuseForItem(child, arr[newI], itemExp, newI, indexName);
1521
+ new2oldI[newI - s2] = i;
1522
+ key2new.delete(key);
1523
+ if (newI < maxIncNewI) {
1524
+ hasMove = true;
1525
+ } else {
1526
+ maxIncNewI = newI;
1527
+ }
1528
+ }
1529
+ if (!hasMove) {
1530
+ key2new.forEach((i, key) => {
1531
+ const before = i === 0 ? forNode.realBefore : newChildren[i - 1].realAfter;
1532
+ this.insertForItem(forNode, i, data, newChildren, before, snapshotForUpdate);
1533
+ });
1534
+ } else {
1535
+ const incI = macInc(new2oldI),
1536
+ incLen = incI.length;
1537
+ let p1, p2;
1538
+ for (p1 = s2, p2 = 0; p1 <= e2; p1++) {
1539
+ const oldI = new2oldI[p1];
1540
+ if (oldI === -1) {
1541
+ const before = p1 === 0 ? forNode.realBefore : newChildren[p1 - 1].realAfter;
1542
+ this.insertForItem(forNode, p1, data, newChildren, before, snapshotForUpdate);
1543
+ continue;
1544
+ }
1545
+ const staticIdx = incI[p2] + s2;
1546
+ if (p1 === staticIdx) {
1547
+ p2 <= incLen && p2++;
1548
+ continue;
1549
+ }
1550
+ let before = p1 === 0 ? forNode.realBefore : newChildren[p1 - 1].realAfter;
1551
+ const child = newChildren[p1];
1552
+ const realBefore = child.realBefore,
1553
+ realAfter = child.realAfter,
1554
+ realParent = child.realParent;
1555
+ let point = realBefore,
1556
+ next;
1557
+ do {
1558
+ next = this.nextSib(point);
1559
+ this.insertAfter(realParent, point, before);
1560
+ before = point;
1561
+ if (point === realAfter) break;
1562
+ point = next;
1563
+ } while (true);
1564
+ }
1565
+ }
1199
1566
  }
1200
- this.i++;
1201
1567
  }
1202
- if (this.token) {
1203
- break;
1568
+ forNode.children = newChildren;
1569
+ }
1570
+ isFirstRender = false;
1571
+ setPulling(prevCtx);
1572
+ return isDestroy => {
1573
+ if (isDestroy) {
1574
+ for (let i = 0; i < forNode.children.length; i++) {
1575
+ const item = forNode.children[i];
1576
+ item.effect.dispose();
1577
+ }
1204
1578
  }
1579
+ };
1580
+ });
1581
+ return forNode.children[0] || forNode;
1582
+ }
1583
+ insertForItem(forNode, i, parentData, newChildren, before, snapshotForUpdate) {
1584
+ const item = this.createForItem(forNode, i, parentData);
1585
+ newChildren[i] = item;
1586
+ let realAfter = this.createAnchor('for-item-after');
1587
+ this.handleInsert(forNode.realParent, realAfter, before);
1588
+ let realBefore = this.createAnchor('for-item-before');
1589
+ this.handleInsert(forNode.realParent, realBefore, before);
1590
+ item.realBefore = realBefore;
1591
+ item.realAfter = realAfter;
1592
+ this.tokenizer = forNode.owner.tokenizer;
1593
+ this.tokenizer.resume(snapshotForUpdate);
1594
+ this.tokenizer.useDedentAsEof = false;
1595
+ runWithPulling(() => {
1596
+ this.program(forNode.realParent, forNode.owner, realBefore, item);
1597
+ }, item.effect);
1598
+ }
1599
+ removeForItem(children, i) {
1600
+ const child = children[i];
1601
+ this.removeLogicNode(child);
1602
+ this.remove(child.realBefore);
1603
+ this.remove(child.realAfter);
1604
+ child.effect.dispose();
1605
+ }
1606
+ reuseForItem(child, data, itemExp, i, indexName) {
1607
+ if (typeof itemExp === 'string') {
1608
+ child.data[itemExp] = data;
1609
+ if (indexName) {
1610
+ child.data[indexName] = i;
1205
1611
  }
1206
- return this.token;
1207
- } catch (error) {
1208
- console.error(error);
1209
- return this.token;
1210
- } finally {
1211
- this.handledTokens.push(this.token);
1612
+ } else {
1613
+ indexName = indexName || KEY_INDEX;
1614
+ child.data[indexName] = i;
1212
1615
  }
1213
1616
  }
1214
- condExp() {
1215
- let value = '';
1216
- this.token = null;
1217
- while (1) {
1218
- const char = this.code[this.i];
1219
- if (char === '\n') {
1220
- break;
1617
+ forItemId = 0;
1618
+ createForItem(forNode, i, parentData) {
1619
+ let forItemNode;
1620
+ let data;
1621
+ const scope = new Scope(() => {});
1622
+ scope.scope = null;
1623
+ runWithPulling(() => {
1624
+ scope.get();
1625
+ }, null);
1626
+ data = this.getItemData(forNode, i, parentData);
1627
+ forItemNode = {
1628
+ id: this.forItemId++,
1629
+ __logicType: FakeType.ForItem,
1630
+ realParent: null,
1631
+ realBefore: null,
1632
+ realAfter: null,
1633
+ forNode,
1634
+ key: forNode.getKey?.(data),
1635
+ effect: null,
1636
+ data
1637
+ };
1638
+ forItemNode.effect = scope;
1639
+ return forItemNode;
1640
+ }
1641
+ getItemData(forNode, i, parentData) {
1642
+ const arr = forNode.arr,
1643
+ itemExp = forNode.itemExp,
1644
+ vars = forNode.vars,
1645
+ arrSignal = forNode.arrSignal,
1646
+ getKey = forNode.getKey;
1647
+ let indexName = forNode.indexName;
1648
+ let data;
1649
+ if (typeof itemExp === 'string') {
1650
+ data = deepSignal(indexName ? {
1651
+ [itemExp]: arr[i],
1652
+ [indexName]: i
1653
+ } : {
1654
+ [itemExp]: arr[i]
1655
+ }, getPulling());
1656
+ } else {
1657
+ indexName = indexName ?? KEY_INDEX;
1658
+ const rawData = {
1659
+ [indexName]: i
1660
+ };
1661
+ data = deepSignal(rawData, getPulling());
1662
+ const computedData = new Computed(() => itemExp(arrSignal.get()[getKey ? data[indexName] : i]));
1663
+ const cells = data[Keys.Meta].cells;
1664
+ for (let i = 0; i < vars.length; i++) {
1665
+ const name = vars[i];
1666
+ rawData[name] = undefined;
1667
+ cells.set(name, new Computed(() => computedData.get()[name]));
1221
1668
  }
1222
- value += char;
1223
- this.i++;
1224
1669
  }
1225
- value = value.trim();
1226
- this.setToken(TokenType.Identifier, value || true);
1227
- return this.token;
1670
+ Object.setPrototypeOf(data, parentData);
1671
+ return data;
1228
1672
  }
1229
- jsExp() {
1230
- this.token = null;
1231
- let value = '';
1232
- while (1) {
1233
- const char = this.code[this.i];
1234
- if (char === ';' || char === '\n') {
1235
- this.setToken(TokenType.Identifier, value.trim());
1236
- return this.token;
1237
- } else {
1238
- value += char;
1239
- }
1240
- this.i++;
1241
- }
1673
+ getData() {
1674
+ const _this$ctx$stack$peekB = this.ctx.stack.peekByType(NodeSort.CtxProvider),
1675
+ node = _this$ctx$stack$peekB.node;
1676
+ return node.data;
1242
1677
  }
1243
- peekChar() {
1244
- let i = this.i;
1245
- while (this.code[i] === ' ' || this.code[i] === '\t') {
1246
- i++;
1678
+ onePropParsed(data, node, key, value, valueIsMapKey, isFn, hookI) {
1679
+ if (isFn) {
1680
+ this.setProp(node, key, value, hookI);
1681
+ } else if (typeof value === 'function') {
1682
+ new Effect(() => {
1683
+ const res = value();
1684
+ this.setProp(node, key, res, hookI);
1685
+ });
1686
+ } else if (valueIsMapKey) {
1687
+ new Effect(() => {
1688
+ const res = data[value];
1689
+ this.setProp(node, key, res, hookI);
1690
+ });
1691
+ } else {
1692
+ this.setProp(node, key, value, hookI);
1247
1693
  }
1248
- return this.code[i];
1249
- }
1250
- assignment() {
1251
- this.setToken(TokenType.Assign, '=');
1252
- }
1253
- pipe() {
1254
- this.setToken(TokenType.Pipe, '|');
1255
1694
  }
1256
- dynamic(char) {
1257
- let nextC = this.code[this.i + 1];
1258
- if (nextC !== '{') {
1259
- return false;
1260
- }
1261
- this.i++;
1262
- let value = '${';
1263
- let innerBrace = 0;
1264
- while (1) {
1265
- nextC = this.code[this.i + 1];
1266
- value += nextC;
1267
- this.i++;
1268
- if (nextC === '{') {
1269
- innerBrace++;
1270
- }
1271
- if (nextC === '}') {
1272
- if (!innerBrace) {
1273
- break;
1274
- }
1275
- innerBrace--;
1276
- }
1695
+ oneRealPropParsed = this.onePropParsed.bind(this);
1696
+ componentOrFragmentDeclaration(ComponentOrRender, ctx) {
1697
+ let Component, render, child;
1698
+ const isCC = ComponentOrRender.prototype instanceof Store;
1699
+ if (isCC) {
1700
+ Component = ComponentOrRender;
1701
+ child = Component.new();
1702
+ } else {
1703
+ render = ComponentOrRender;
1704
+ const boundStore = render.boundStore;
1705
+ child = deepSignal({}, getPulling(), true);
1706
+ Object.setPrototypeOf(child, boundStore);
1277
1707
  }
1278
- this.setToken(TokenType.Identifier, value);
1279
- return true;
1280
- }
1281
- brace() {
1282
- let inComment,
1283
- inString,
1284
- count = 0,
1285
- value = '',
1286
- backslashCount = 0;
1287
- while (1) {
1288
- const char = this.code[this.i];
1289
- const nextChar = this.code[this.i + 1];
1290
- if (inComment === 'single' && char === '\n') {
1291
- inComment = null;
1292
- } else if (inComment === 'multi' && char === '*' && nextChar === '/') {
1293
- inComment = null;
1294
- value += this.code[this.i];
1295
- this.i++;
1296
- } else if (inString) {
1297
- if (char === inString && backslashCount % 2 === 0) {
1298
- inString = null;
1299
- }
1300
- backslashCount = char === '\\' ? backslashCount + 1 : 0;
1708
+ const node = {
1709
+ __logicType: isCC ? FakeType.Component : FakeType.Fragment,
1710
+ realParent: ctx.realParent,
1711
+ realBefore: null,
1712
+ realAfter: null,
1713
+ data: child,
1714
+ tokenizer: render ? render(true) : child['ui'](true)
1715
+ };
1716
+ this.onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
1717
+ if (isFn) {
1718
+ child[Keys.Raw][key] = value;
1719
+ } else if (valueIsMapKey) {
1720
+ shareSignal(data, value, child, key);
1301
1721
  } else {
1302
- if (char === '/' && nextChar === '/') {
1303
- inComment = 'single';
1304
- value += this.code[this.i];
1305
- this.i++;
1306
- } else if (char === '/' && nextChar === '*') {
1307
- inComment = 'multi';
1308
- value += this.code[this.i];
1309
- this.i++;
1310
- } else if (char === "'" || char === '"' || char === '`') {
1311
- inString = char;
1312
- } else if (char === '{') {
1313
- count++;
1314
- } else if (char === '}') {
1315
- count--;
1722
+ const meta = child[Keys.Meta];
1723
+ const cells = meta.cells;
1724
+ if (typeof value === 'function') {
1725
+ const computed = new Computed(value);
1726
+ cells.set(key, computed);
1727
+ child[Keys.Raw][key] = undefined;
1728
+ } else {
1729
+ cells.set(key, {
1730
+ get: () => value
1731
+ });
1732
+ child[Keys.Raw][key] = value;
1316
1733
  }
1317
1734
  }
1318
- if (count === 0 && inString == null && inComment == null) {
1319
- return value.slice(1);
1320
- }
1321
- value += this.code[this.i];
1322
- this.i++;
1323
- }
1735
+ };
1736
+ node.realAfter = this.insertAfterAnchor('component-after');
1737
+ return node;
1324
1738
  }
1325
- newLine() {
1326
- let value = '\n';
1327
- let nextC;
1328
- while (1) {
1329
- nextC = this.code[this.i + 1];
1330
- if (nextC !== '\n') {
1331
- break;
1332
- }
1333
- value += nextC;
1334
- this.i++;
1335
- }
1336
- if (this.isFirstToken) {
1337
- return;
1338
- }
1339
- this.setToken(TokenType.NewLine, value);
1739
+ getFn(data, expression) {
1740
+ return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
1340
1741
  }
1341
- getDentValue() {
1342
- let value = '';
1343
- let nextC;
1344
- let isEmptyLine = false;
1345
- while (1) {
1346
- const nextChar = this.code[this.i];
1347
- switch (nextChar) {
1348
- case '\t':
1349
- nextC = this.Tab;
1350
- break;
1351
- case ' ':
1352
- nextC = ' ';
1353
- break;
1354
- case '\n':
1355
- nextC = '\n';
1356
- break;
1357
- default:
1358
- nextC = '';
1359
- break;
1360
- }
1361
- if (nextC === '\n') {
1362
- isEmptyLine = true;
1363
- break;
1364
- }
1365
- if (!nextC) {
1366
- break;
1367
- }
1368
- value += nextC;
1369
- this.i++;
1370
- }
1371
- return {
1372
- value,
1373
- isEmptyLine
1742
+ condDeclaration(ctx) {
1743
+ const prevSibling = ctx.prevSibling;
1744
+ const keyWord = this.tokenizer.token;
1745
+ const expToken = this.tokenizer.condExp();
1746
+ const value = expToken.value;
1747
+ const isElse = keyWord.value === 'else';
1748
+ const isIf = keyWord.value === 'if';
1749
+ const preIsCond = prevSibling?.__logicType & CondBit;
1750
+ const data = this.getData();
1751
+ const noCond = value === true;
1752
+ const valueIsMapKey = !noCond && Reflect.has(data[Keys.Raw], value);
1753
+ const owner = ctx.stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1754
+ const ifNode = {
1755
+ __logicType: isElse ? FakeType.Else : isIf ? FakeType.If : FakeType.Fail,
1756
+ snapshot: this.tokenizer.snapshot(),
1757
+ realParent: null,
1758
+ realBefore: null,
1759
+ realAfter: null,
1760
+ condition: null,
1761
+ preCond: preIsCond ? prevSibling : null,
1762
+ isFirstRender: true,
1763
+ effect: null,
1764
+ owner,
1765
+ data
1374
1766
  };
1375
- }
1376
- dent() {
1377
- const _this$getDentValue2 = this.getDentValue(),
1378
- value = _this$getDentValue2.value,
1379
- isEmptyLine = _this$getDentValue2.isEmptyLine;
1380
- if (isEmptyLine) {
1381
- this.needIndent = true;
1382
- return;
1383
- }
1384
- this.needIndent = false;
1385
- if (this.isFirstToken) {
1386
- this.dentStack[0] = value.length;
1387
- return;
1388
- }
1389
- let currLen = value.length;
1390
- const indentHasLen = currLen > 0;
1391
- const prevLen = this.dentStack[this.dentStack.length - 1];
1392
- if (currLen > prevLen) {
1393
- this.dentStack.push(currLen);
1394
- this.setToken(TokenType.Indent, currLen);
1395
- return indentHasLen;
1396
- }
1397
- if (currLen < prevLen) {
1398
- for (let i = this.dentStack.length; i--;) {
1399
- const expLen = this.dentStack[i];
1400
- if (currLen === expLen) break;
1401
- if (currLen > expLen) {
1402
- throw SyntaxError('缩进大小不统一');
1403
- }
1404
- if (this.shorterThanBaseDentEof()) {
1405
- return;
1767
+ let signal;
1768
+ switch (keyWord.value) {
1769
+ case 'if':
1770
+ if (valueIsMapKey) {
1771
+ runWithPulling(() => data[value], null);
1772
+ const cells = data[Keys.Meta].cells;
1773
+ signal = cells.get(value);
1774
+ } else {
1775
+ const fn = this.getFn(data, value);
1776
+ signal = new Computed(fn);
1406
1777
  }
1407
- this.dentStack.pop();
1408
- if (!this.token) {
1409
- this.setToken(TokenType.Dedent, String(expLen));
1778
+ break;
1779
+ case 'else':
1780
+ if (noCond) {
1781
+ signal = new Computed(() => {
1782
+ let point = ifNode.preCond;
1783
+ while (point) {
1784
+ if (point.condition.get()) {
1785
+ return false;
1786
+ }
1787
+ if (point.__logicType === FakeType.If) {
1788
+ break;
1789
+ }
1790
+ point = point.preCond;
1791
+ }
1792
+ return true;
1793
+ });
1410
1794
  } else {
1411
- this.waitingTokens.push({
1412
- type: TokenType.Dedent,
1413
- typeName: TokenType[TokenType.Dedent],
1414
- value: String(expLen)
1795
+ const fn = valueIsMapKey ? null : this.getFn(data, value);
1796
+ signal = new Computed(() => {
1797
+ let point = ifNode.preCond;
1798
+ while (point) {
1799
+ if (point.condition.get()) {
1800
+ return false;
1801
+ }
1802
+ if (point.__logicType === FakeType.If) {
1803
+ break;
1804
+ }
1805
+ point = point.preCond;
1806
+ }
1807
+ return valueIsMapKey ? data[value] : fn();
1415
1808
  });
1416
1809
  }
1417
- }
1418
- return indentHasLen;
1810
+ break;
1811
+ case 'fail':
1812
+ signal = new Computed(() => {
1813
+ let point = ifNode.preCond;
1814
+ while (point) {
1815
+ if (point.condition.get()) {
1816
+ return false;
1817
+ }
1818
+ point = point.preCond;
1819
+ }
1820
+ return true;
1821
+ });
1822
+ break;
1419
1823
  }
1420
- return indentHasLen;
1421
- }
1422
- shorterThanBaseDentEof() {
1423
- const yes = this.dentStack.length === 1;
1424
- if (yes) {
1425
- if (!this.token) {
1426
- if (this.useDedentAsEof) {
1427
- this.setToken(TokenType.Dedent, '');
1824
+ ifNode.condition = signal;
1825
+ ifNode.realAfter = this.insertAfterAnchor(`${keyWord.value}-after`);
1826
+ const ef = effect(({
1827
+ val
1828
+ }) => {
1829
+ if (val) {
1830
+ if (ifNode.isFirstRender) {
1831
+ this.tokenizer.nextToken();
1832
+ this.tokenizer.nextToken();
1428
1833
  } else {
1429
- this.setToken(TokenType.Identifier, Tokenizer.EofId);
1834
+ this.tokenizer = ifNode.owner.tokenizer;
1835
+ this.tokenizer.resume(ifNode.snapshot);
1836
+ this.tokenizer.useDedentAsEof = false;
1837
+ this.program(ifNode.realParent, ifNode.owner, ifNode.realBefore, ifNode);
1430
1838
  }
1431
1839
  } else {
1432
- if (this.useDedentAsEof) {
1433
- this.waitingTokens.push({
1434
- type: TokenType.Dedent,
1435
- typeName: TokenType[TokenType.Dedent],
1436
- value: ''
1437
- });
1840
+ if (ifNode.isFirstRender) {
1841
+ this.tokenizer.skip();
1438
1842
  } else {
1439
- this.waitingTokens.push({
1440
- type: TokenType.Identifier,
1441
- typeName: TokenType[TokenType.Identifier],
1442
- value: Tokenizer.EofId
1443
- });
1843
+ this.removeLogicNode(ifNode);
1444
1844
  }
1445
1845
  }
1846
+ ifNode.isFirstRender = false;
1847
+ }, [signal]);
1848
+ ifNode.effect = ef;
1849
+ return ifNode;
1850
+ }
1851
+ removeLogicNode(node) {
1852
+ const realBefore = node.realBefore,
1853
+ realAfter = node.realAfter,
1854
+ realParent = node.realParent;
1855
+ let point = realBefore ? this.nextSib(realBefore) : this.firstChild(realParent);
1856
+ while (point !== realAfter) {
1857
+ const next = this.nextSib(point);
1858
+ this.remove(point, realParent, realBefore);
1859
+ point = next;
1446
1860
  }
1447
- return yes;
1448
1861
  }
1449
- identifier(char) {
1450
- let value = char;
1451
- let nextC;
1862
+ extensionLines(_node) {
1452
1863
  while (1) {
1453
- nextC = this.code[this.i + 1];
1454
- if (typeof nextC !== 'string' || !matchIdStart2(nextC, 0)) {
1455
- break;
1864
+ if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
1865
+ return;
1456
1866
  }
1457
- value += nextC;
1458
- this.i++;
1459
- }
1460
- if (value === Tokenizer.EofId && this.useDedentAsEof) {
1461
- this.setToken(TokenType.Dedent, '');
1462
- return;
1867
+ this.tokenizer.nextToken();
1868
+ this.attributeList(_node);
1869
+ if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
1870
+ return;
1871
+ }
1872
+ this.tokenizer.nextToken();
1463
1873
  }
1464
- let realValue = value === 'null' ? null : value === 'undefined' ? undefined : value === 'false' ? false : value === 'true' ? true : value;
1465
- this.setToken(TokenType.Identifier, realValue);
1466
1874
  }
1467
- str(char) {
1468
- let value = '';
1469
- let nextC;
1470
- let continuousBackslashCount = 0;
1471
- while (1) {
1472
- nextC = this.code[this.i + 1];
1473
- const memoCount = continuousBackslashCount;
1474
- if (nextC === '\\') {
1475
- continuousBackslashCount++;
1875
+ headerLine(_node) {
1876
+ this.attributeList(_node);
1877
+ this.tokenizer.nextToken();
1878
+ }
1879
+ attributeList(_node) {
1880
+ let key, eq;
1881
+ const data = this.getData();
1882
+ while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
1883
+ if (key == null) {
1884
+ key = this.tokenizer.token.value;
1885
+ } else if (eq == null) {
1886
+ eq = '=';
1476
1887
  } else {
1477
- continuousBackslashCount = 0;
1478
- }
1479
- this.i++;
1480
- if (nextC === char && memoCount % 2 === 0) {
1481
- break;
1888
+ const _this$tokenizer$_hook3 = this.tokenizer._hook({}),
1889
+ _this$tokenizer$_hook4 = _slicedToArray(_this$tokenizer$_hook3, 3),
1890
+ hookType = _this$tokenizer$_hook4[0],
1891
+ value = _this$tokenizer$_hook4[1],
1892
+ hookI = _this$tokenizer$_hook4[2];
1893
+ const rawVal = data[Keys.Raw][value];
1894
+ const isFn = typeof rawVal === 'function';
1895
+ if (hookType === 'dynamic') {
1896
+ const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
1897
+ const fn = isFn ? rawVal : valueIsMapKey ? value : this.getFn(data, value);
1898
+ this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
1899
+ } else if (hookType === 'static') {
1900
+ this.onePropParsed(data, _node, key, value, false, isFn, hookI);
1901
+ } else {
1902
+ this.onePropParsed(data, _node, key, value, false, isFn, hookI);
1903
+ }
1904
+ key = null;
1905
+ eq = null;
1482
1906
  }
1483
- value += nextC;
1907
+ this.tokenizer.nextToken();
1484
1908
  }
1485
- this.setToken(TokenType.Identifier, value);
1486
1909
  }
1487
- number(char) {
1488
- let value = char;
1489
- let nextC;
1490
- while (1) {
1491
- nextC = this.code[this.i + 1];
1492
- if (!isNum(nextC)) {
1493
- break;
1494
- }
1495
- value += nextC;
1496
- this.i++;
1910
+ config(opt) {
1911
+ Object.assign(this, opt);
1912
+ this.opt = opt;
1913
+ }
1914
+ createNode(name) {
1915
+ return {
1916
+ name,
1917
+ props: {},
1918
+ nextSibling: null
1919
+ };
1920
+ }
1921
+ nextSib(node) {
1922
+ return node.nextSibling;
1923
+ }
1924
+ firstChild(node) {
1925
+ return node.firstChild;
1926
+ }
1927
+ createAnchor(name) {
1928
+ return {
1929
+ name,
1930
+ nextSibling: null
1931
+ };
1932
+ }
1933
+ insertAfter(parent, node, prev) {
1934
+ return this.defaultInsert(parent, node, prev);
1935
+ }
1936
+ defaultInsert(parent, node, prev) {
1937
+ if (prev) {
1938
+ const next = prev.nextSibling;
1939
+ prev.nextSibling = node;
1940
+ node.nextSibling = next;
1941
+ } else {
1942
+ const next = parent.firstChild;
1943
+ parent.firstChild = node;
1944
+ node.nextSibling = next;
1497
1945
  }
1498
- this.setToken(TokenType.Identifier, Number(value));
1499
1946
  }
1500
- eof() {
1501
- this.setToken(TokenType.Eof, 'End Of File');
1947
+ remove(node, parent, prev) {
1948
+ return this.defaultRemove(node, parent, prev);
1502
1949
  }
1503
- HookId = '_h_o_o_k_';
1504
- hookI = 0;
1505
- _hook = props => {
1506
- const value = this.token.value;
1507
- const isDynamicHook = this.token.type & TokenType.InsertionExp;
1508
- const isStaticHook = typeof value === 'string' && value.indexOf(this.HookId) === 0;
1509
- const hookType = isDynamicHook ? 'dynamic' : isStaticHook ? 'static' : undefined;
1510
- if (this.hook && isStaticHook) {
1511
- const hookI = Number(value.slice(this.HookId.length));
1512
- const res = this.hook({
1513
- ...props,
1514
- HookId: this.HookId,
1515
- i: hookI
1516
- });
1517
- return [hookType, res, hookI];
1518
- } else if (isDynamicHook) {
1519
- return [hookType, value];
1950
+ defaultRemove(node, parent, prevSibling) {
1951
+ const next = node.nextSibling;
1952
+ if (prevSibling) {
1953
+ prevSibling.nextSibling = next;
1520
1954
  }
1521
- return [hookType, value];
1522
- };
1523
- init(fragments) {
1524
- if (typeof fragments === 'string') {
1525
- this.setCode(fragments);
1526
- } else {
1527
- let code = '';
1528
- for (let i = 0; i < fragments.length - 1; i++) {
1529
- const fragment = fragments[i];
1530
- code += fragment + `${this.HookId}${i}`;
1531
- }
1532
- this.setCode(code + fragments[fragments.length - 1]);
1955
+ if (parent.firstChild === node) {
1956
+ parent.firstChild = next;
1533
1957
  }
1534
1958
  }
1959
+ setProp(node, key, value, hookI) {
1960
+ node.props[key] = value;
1961
+ }
1535
1962
  }
1536
1963
 
1537
1964
  function bobe(fragments, ...values) {
@@ -1564,5 +1991,5 @@ function customRender(option) {
1564
1991
  };
1565
1992
  }
1566
1993
 
1567
- export { bobe, customRender };
1994
+ export { Compiler, NodeType, Tokenizer, bobe, customRender };
1568
1995
  //# sourceMappingURL=bobe.esm.js.map