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