bobe 0.0.41 → 0.0.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bobe.cjs.js CHANGED
@@ -226,7 +226,7 @@ class Tokenizer {
226
226
  if (!this.token) return false;
227
227
  return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
228
228
  }
229
- setToken(type, value) {
229
+ setToken(type, value, dt = 1) {
230
230
  this.token = {
231
231
  type,
232
232
  typeName: TokenType[type],
@@ -329,23 +329,19 @@ class Tokenizer {
329
329
  condExp() {
330
330
  let value = '';
331
331
  this.token = null;
332
- try {
333
- if (this.code[this.i] === '\n') {
334
- this.setToken(TokenType.Identifier, true);
335
- return this.token;
336
- }
337
- while (this.code[this.i + 1] !== '\n') {
338
- value += this.code[this.i];
339
- this.next();
332
+ let char = this.code[this.i];
333
+ while (char !== '\n') {
334
+ if (char === '"' || char === "'") {
335
+ value += char + this.getStr(char);
340
336
  }
341
337
  value += this.code[this.i];
342
- const trimmed = value.replace(/\/\/[\s\S]+/, '').trim();
343
- this.setToken(TokenType.Identifier, trimmed ? trimmed : true);
344
- return this.token;
345
- } finally {
346
338
  this.next();
347
- this.handledTokens.push(this.token);
339
+ char = this.code[this.i];
348
340
  }
341
+ const trimmed = value.replace(/\/\/[\s\S]+/, '').trim();
342
+ this.setToken(TokenType.Identifier, trimmed ? trimmed : true, 0);
343
+ this.handledTokens.push(this.token);
344
+ return this.token;
349
345
  }
350
346
  isEol(i) {
351
347
  return this.code[i] === '\n' || this.code[i] === '/';
@@ -353,25 +349,18 @@ class Tokenizer {
353
349
  jsExp() {
354
350
  this.token = null;
355
351
  let value = '';
356
- try {
357
- const char = this.code[this.i];
358
- if (char === ';' || char === '\n') {
359
- this.setToken(TokenType.Identifier, value);
360
- return this.token;
361
- }
362
- let nextC = this.code[this.i + 1];
363
- while (nextC !== ';' && nextC !== '\n') {
364
- value += this.code[this.i];
365
- this.next();
366
- nextC = this.code[this.i + 1];
352
+ let char = this.code[this.i];
353
+ while (char !== ';' && char !== '\n') {
354
+ if (char === '"' || char === "'") {
355
+ value += char + this.getStr(char);
367
356
  }
368
357
  value += this.code[this.i];
369
- this.setToken(TokenType.Identifier, value);
370
- return this.token;
371
- } finally {
372
358
  this.next();
373
- this.handledTokens.push(this.token);
359
+ char = this.code[this.i];
374
360
  }
361
+ this.setToken(TokenType.Identifier, value, 0);
362
+ this.handledTokens.push(this.token);
363
+ return this.token;
375
364
  }
376
365
  peekChar() {
377
366
  let i = this.i;
@@ -429,10 +418,8 @@ class Tokenizer {
429
418
  startLine = this.line,
430
419
  startCol = this.preCol;
431
420
  let inComment,
432
- inString,
433
421
  count = 0,
434
- value = '',
435
- backslashCount = 0;
422
+ value = '';
436
423
  while (1) {
437
424
  const char = this.code[this.i];
438
425
  if (char === undefined) {
@@ -445,11 +432,6 @@ class Tokenizer {
445
432
  inComment = null;
446
433
  value += this.code[this.i];
447
434
  this.next();
448
- } else if (inString) {
449
- if (char === inString && backslashCount % 2 === 0) {
450
- inString = null;
451
- }
452
- backslashCount = char === '\\' ? backslashCount + 1 : 0;
453
435
  } else {
454
436
  if (char === '/' && nextChar === '/') {
455
437
  inComment = 'single';
@@ -459,15 +441,15 @@ class Tokenizer {
459
441
  inComment = 'multi';
460
442
  value += this.code[this.i];
461
443
  this.next();
462
- } else if (char === "'" || char === '"' || char === '`') {
463
- inString = char;
444
+ } else if (char === "'" || char === '"') {
445
+ value += char + this.getStr(char);
464
446
  } else if (char === '{') {
465
447
  count++;
466
448
  } else if (char === '}') {
467
449
  count--;
468
450
  }
469
451
  }
470
- if (count === 0 && inString == null && inComment == null) {
452
+ if (count === 0 && inComment == null) {
471
453
  return value.slice(1);
472
454
  }
473
455
  value += this.code[this.i];
@@ -663,7 +645,7 @@ class Tokenizer {
663
645
  }
664
646
  this.setToken(tokenType, realValue);
665
647
  }
666
- str(char) {
648
+ getStr(head, parseEscape = true) {
667
649
  const startOffset = this.preI,
668
650
  startLine = this.line,
669
651
  startCol = this.preCol;
@@ -682,11 +664,20 @@ class Tokenizer {
682
664
  continuousBackslashCount = 0;
683
665
  }
684
666
  this.next();
685
- if (nextC === char && memoCount % 2 === 0) {
667
+ if (nextC === head && memoCount % 2 === 0) {
686
668
  break;
687
669
  }
688
- value += nextC;
670
+ const mapped = bobeShared.escapeMap[nextC];
671
+ if (parseEscape && mapped) {
672
+ value += mapped;
673
+ } else {
674
+ value += nextC;
675
+ }
689
676
  }
677
+ return value;
678
+ }
679
+ str(char) {
680
+ const value = this.getStr(char, false);
690
681
  this.setToken(TokenType.String, value);
691
682
  }
692
683
  number(char) {
@@ -1126,7 +1117,7 @@ class Compiler {
1126
1117
  }
1127
1118
  parseLoopNode(node) {
1128
1119
  const forLoc = this.tokenizer.token.loc ?? this.tokenizer.emptyLoc();
1129
- this.tokenizer.nextToken();
1120
+ this.tokenizer.jsExp();
1130
1121
  const collection = this.parseJsExp();
1131
1122
  if (!collection.value && collection.value !== 0) {
1132
1123
  this.addError(ParseErrorCode.MISSING_FOR_COLLECTION, '"for" 缺少集合表达式', forLoc, node);
@@ -1587,7 +1578,7 @@ class Interpreter {
1587
1578
  return _node;
1588
1579
  }
1589
1580
  forDeclaration() {
1590
- const arrExp = this.tokenizer.nextToken().value;
1581
+ const arrExp = this.tokenizer.jsExp().value;
1591
1582
  this.tokenizer.nextToken();
1592
1583
  const itemToken = this.tokenizer.nextToken();
1593
1584
  const isDestruct = itemToken.type === TokenType.InsertionExp;
@@ -1918,16 +1909,20 @@ class Interpreter {
1918
1909
  }
1919
1910
  onePropParsed(data, node, key, value, valueIsMapKey, isFn, hookI) {
1920
1911
  if (isFn) {
1921
- this.setProp(node, key, value, hookI);
1912
+ new aoye.Scope(() => {
1913
+ return this.setProp(node, key, value, hookI);
1914
+ }).get();
1922
1915
  } else if (typeof value === 'function') {
1923
1916
  new aoye.Effect(() => {
1924
- const res = value();
1925
- this.setProp(node, key, res, hookI);
1917
+ const res = value(data);
1918
+ const dispose = this.setProp(node, key, res, hookI);
1919
+ return dispose;
1926
1920
  });
1927
1921
  } else if (valueIsMapKey) {
1928
1922
  new aoye.Effect(() => {
1929
1923
  const res = data[value];
1930
- this.setProp(node, key, res, hookI);
1924
+ const dispose = this.setProp(node, key, res, hookI);
1925
+ return dispose;
1931
1926
  });
1932
1927
  } else {
1933
1928
  this.setProp(node, key, value, hookI);
@@ -1952,7 +1947,7 @@ class Interpreter {
1952
1947
  realBefore: null,
1953
1948
  realAfter: null,
1954
1949
  data: child,
1955
- tokenizer: render ? render(true) : child['ui'](true)
1950
+ tokenizer: render ? render(true) : child.ui(true)
1956
1951
  };
1957
1952
  this.onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
1958
1953
  if (isFn) {
@@ -1963,7 +1958,7 @@ class Interpreter {
1963
1958
  const meta = child[aoye.Keys.Meta];
1964
1959
  const cells = meta.cells;
1965
1960
  if (typeof value === 'function') {
1966
- const computed = new aoye.Computed(value);
1961
+ const computed = new aoye.Computed(() => value(data));
1967
1962
  cells.set(key, computed);
1968
1963
  child[aoye.Keys.Raw][key] = undefined;
1969
1964
  } else {
@@ -1980,6 +1975,10 @@ class Interpreter {
1980
1975
  getFn(data, expression) {
1981
1976
  return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
1982
1977
  }
1978
+ getAssignFn(data, expression) {
1979
+ const valueId = `value_bobe_${bobeShared.date32()}`;
1980
+ return new Function('data', valueId, `with(data){${expression}=${valueId}};`).bind(undefined, data);
1981
+ }
1983
1982
  condDeclaration(ctx) {
1984
1983
  const prevSibling = ctx.prevSibling;
1985
1984
  const keyWord = this.tokenizer.token;
@@ -2133,7 +2132,27 @@ class Interpreter {
2133
2132
  hookI = _this$tokenizer$_hook4[2];
2134
2133
  const rawVal = data[aoye.Keys.Raw][value];
2135
2134
  const isFn = typeof rawVal === 'function';
2136
- if (hookType === 'dynamic') {
2135
+ if (key === 'ref') {
2136
+ const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
2137
+ let refValue = _node;
2138
+ if (_node.__logicType === FakeType.Component) {
2139
+ refValue = _node.data;
2140
+ } else {
2141
+ refValue[aoye.Keys.ProxyFreeObject] = true;
2142
+ }
2143
+ if (valueIsMapKey) {
2144
+ data[value] = refValue;
2145
+ new aoye.Scope(() => () => {
2146
+ data[value] = null;
2147
+ }).get();
2148
+ } else {
2149
+ const fn = this.getAssignFn(data, value);
2150
+ fn(refValue);
2151
+ new aoye.Scope(() => () => {
2152
+ fn(null);
2153
+ }).get();
2154
+ }
2155
+ } else if (hookType === 'dynamic') {
2137
2156
  const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
2138
2157
  const fn = isFn ? rawVal : valueIsMapKey ? value : this.getFn(data, value);
2139
2158
  this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
@@ -2218,7 +2237,7 @@ function bobe(fragments, ...values) {
2218
2237
  function customRender(option) {
2219
2238
  return function render(Ctor, root) {
2220
2239
  const store = Ctor.new();
2221
- const tokenizer = store['ui'](false);
2240
+ const tokenizer = store.ui(false);
2222
2241
  const terp = new Interpreter(tokenizer);
2223
2242
  terp.config(option);
2224
2243
  const componentNode = {