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