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.
@@ -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
 
@@ -234,7 +234,7 @@ class Tokenizer {
234
234
  if (!this.token) return false;
235
235
  return this.token.type & TokenType.Identifier && this.token.value === Tokenizer.EofId;
236
236
  }
237
- setToken(type, value) {
237
+ setToken(type, value, dt = 1) {
238
238
  this.token = {
239
239
  type,
240
240
  typeName: TokenType[type],
@@ -246,11 +246,11 @@ class Tokenizer {
246
246
  column: this.preCol
247
247
  },
248
248
  end: {
249
- offset: this.i + 1,
249
+ offset: this.i + dt,
250
250
  line: this.line,
251
- column: this.column + 1
251
+ column: this.column + dt
252
252
  },
253
- source: this.code.slice(this.preI, this.i + 1)
253
+ source: this.code.slice(this.preI, this.i + dt)
254
254
  } : null
255
255
  };
256
256
  this.isFirstToken = false;
@@ -360,26 +360,22 @@ class Tokenizer {
360
360
  }
361
361
  let value = '';
362
362
  this.token = null;
363
- try {
364
- if (this.code[this.i] === '\n') {
365
- this.setToken(TokenType.Identifier, true);
366
- return this.token;
367
- }
368
- while (this.code[this.i + 1] !== '\n') {
369
- value += this.code[this.i];
370
- this.next();
363
+ let char = this.code[this.i];
364
+ while (char !== '\n') {
365
+ if (char === '"' || char === "'") {
366
+ value += char + this.getStr(char);
371
367
  }
372
368
  value += this.code[this.i];
373
- const trimmed = value.replace(/\/\/[\s\S]+/, '').trim();
374
- this.setToken(TokenType.Identifier, trimmed ? trimmed : true);
375
- return this.token;
376
- } finally {
377
369
  this.next();
378
- this.handledTokens.push(this.token);
379
- {
380
- this.needLoc = false;
381
- }
370
+ char = this.code[this.i];
382
371
  }
372
+ const trimmed = value.replace(/\/\/[\s\S]+/, '').trim();
373
+ this.setToken(TokenType.Identifier, trimmed ? trimmed : true, 0);
374
+ this.handledTokens.push(this.token);
375
+ {
376
+ this.needLoc = false;
377
+ }
378
+ return this.token;
383
379
  }
384
380
  isEol(i) {
385
381
  return this.code[i] === '\n' || this.code[i] === '/';
@@ -392,28 +388,21 @@ class Tokenizer {
392
388
  }
393
389
  this.token = null;
394
390
  let value = '';
395
- try {
396
- const char = this.code[this.i];
397
- if (char === ';' || char === '\n') {
398
- this.setToken(TokenType.Identifier, value);
399
- return this.token;
400
- }
401
- let nextC = this.code[this.i + 1];
402
- while (nextC !== ';' && nextC !== '\n') {
403
- value += this.code[this.i];
404
- this.next();
405
- nextC = this.code[this.i + 1];
391
+ let char = this.code[this.i];
392
+ while (char !== ';' && char !== '\n') {
393
+ if (char === '"' || char === "'") {
394
+ value += char + this.getStr(char);
406
395
  }
407
396
  value += this.code[this.i];
408
- this.setToken(TokenType.Identifier, value);
409
- return this.token;
410
- } finally {
411
397
  this.next();
412
- this.handledTokens.push(this.token);
413
- {
414
- this.needLoc = false;
415
- }
398
+ char = this.code[this.i];
416
399
  }
400
+ this.setToken(TokenType.Identifier, value, 0);
401
+ this.handledTokens.push(this.token);
402
+ {
403
+ this.needLoc = false;
404
+ }
405
+ return this.token;
417
406
  }
418
407
  peekChar() {
419
408
  let i = this.i;
@@ -471,10 +460,8 @@ class Tokenizer {
471
460
  startLine = this.line,
472
461
  startCol = this.preCol;
473
462
  let inComment,
474
- inString,
475
463
  count = 0,
476
- value = '',
477
- backslashCount = 0;
464
+ value = '';
478
465
  while (1) {
479
466
  const char = this.code[this.i];
480
467
  if (char === undefined) {
@@ -487,11 +474,6 @@ class Tokenizer {
487
474
  inComment = null;
488
475
  value += this.code[this.i];
489
476
  this.next();
490
- } else if (inString) {
491
- if (char === inString && backslashCount % 2 === 0) {
492
- inString = null;
493
- }
494
- backslashCount = char === '\\' ? backslashCount + 1 : 0;
495
477
  } else {
496
478
  if (char === '/' && nextChar === '/') {
497
479
  inComment = 'single';
@@ -501,15 +483,15 @@ class Tokenizer {
501
483
  inComment = 'multi';
502
484
  value += this.code[this.i];
503
485
  this.next();
504
- } else if (char === "'" || char === '"' || char === '`') {
505
- inString = char;
486
+ } else if (char === "'" || char === '"') {
487
+ value += char + this.getStr(char);
506
488
  } else if (char === '{') {
507
489
  count++;
508
490
  } else if (char === '}') {
509
491
  count--;
510
492
  }
511
493
  }
512
- if (count === 0 && inString == null && inComment == null) {
494
+ if (count === 0 && inComment == null) {
513
495
  return value.slice(1);
514
496
  }
515
497
  value += this.code[this.i];
@@ -705,7 +687,7 @@ class Tokenizer {
705
687
  }
706
688
  this.setToken(tokenType, realValue);
707
689
  }
708
- str(char) {
690
+ getStr(head, parseEscape = true) {
709
691
  const startOffset = this.preI,
710
692
  startLine = this.line,
711
693
  startCol = this.preCol;
@@ -724,11 +706,18 @@ class Tokenizer {
724
706
  continuousBackslashCount = 0;
725
707
  }
726
708
  this.next();
727
- if (nextC === char && memoCount % 2 === 0) {
709
+ if (nextC === head && memoCount % 2 === 0) {
728
710
  break;
729
711
  }
730
- value += nextC;
712
+ escapeMap[nextC];
713
+ {
714
+ value += nextC;
715
+ }
731
716
  }
717
+ return value;
718
+ }
719
+ str(char) {
720
+ const value = this.getStr(char, false);
732
721
  this.setToken(TokenType.String, value);
733
722
  }
734
723
  number(char) {
@@ -1168,7 +1157,7 @@ class Compiler {
1168
1157
  }
1169
1158
  parseLoopNode(node) {
1170
1159
  const forLoc = this.tokenizer.token.loc ?? this.tokenizer.emptyLoc();
1171
- this.tokenizer.nextToken();
1160
+ this.tokenizer.jsExp();
1172
1161
  const collection = this.parseJsExp();
1173
1162
  if (!collection.value && collection.value !== 0) {
1174
1163
  this.addError(ParseErrorCode.MISSING_FOR_COLLECTION, '"for" 缺少集合表达式', forLoc, node);
@@ -1629,7 +1618,7 @@ class Interpreter {
1629
1618
  return _node;
1630
1619
  }
1631
1620
  forDeclaration() {
1632
- const arrExp = this.tokenizer.nextToken().value;
1621
+ const arrExp = this.tokenizer.jsExp().value;
1633
1622
  this.tokenizer.nextToken();
1634
1623
  const itemToken = this.tokenizer.nextToken();
1635
1624
  const isDestruct = itemToken.type === TokenType.InsertionExp;
@@ -1960,16 +1949,20 @@ class Interpreter {
1960
1949
  }
1961
1950
  onePropParsed(data, node, key, value, valueIsMapKey, isFn, hookI) {
1962
1951
  if (isFn) {
1963
- this.setProp(node, key, value, hookI);
1952
+ new Scope(() => {
1953
+ return this.setProp(node, key, value, hookI);
1954
+ }).get();
1964
1955
  } else if (typeof value === 'function') {
1965
1956
  new Effect(() => {
1966
- const res = value();
1967
- this.setProp(node, key, res, hookI);
1957
+ const res = value(data);
1958
+ const dispose = this.setProp(node, key, res, hookI);
1959
+ return dispose;
1968
1960
  });
1969
1961
  } else if (valueIsMapKey) {
1970
1962
  new Effect(() => {
1971
1963
  const res = data[value];
1972
- this.setProp(node, key, res, hookI);
1964
+ const dispose = this.setProp(node, key, res, hookI);
1965
+ return dispose;
1973
1966
  });
1974
1967
  } else {
1975
1968
  this.setProp(node, key, value, hookI);
@@ -1994,7 +1987,7 @@ class Interpreter {
1994
1987
  realBefore: null,
1995
1988
  realAfter: null,
1996
1989
  data: child,
1997
- tokenizer: render ? render(true) : child['ui'](true)
1990
+ tokenizer: render ? render(true) : child.ui(true)
1998
1991
  };
1999
1992
  this.onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
2000
1993
  if (isFn) {
@@ -2005,7 +1998,7 @@ class Interpreter {
2005
1998
  const meta = child[Keys.Meta];
2006
1999
  const cells = meta.cells;
2007
2000
  if (typeof value === 'function') {
2008
- const computed = new Computed(value);
2001
+ const computed = new Computed(() => value(data));
2009
2002
  cells.set(key, computed);
2010
2003
  child[Keys.Raw][key] = undefined;
2011
2004
  } else {
@@ -2022,6 +2015,10 @@ class Interpreter {
2022
2015
  getFn(data, expression) {
2023
2016
  return new Function('data', `let v;with(data){v=${expression}};return v;`).bind(undefined, data);
2024
2017
  }
2018
+ getAssignFn(data, expression) {
2019
+ const valueId = `value_bobe_${date32()}`;
2020
+ return new Function('data', valueId, `with(data){${expression}=${valueId}};`).bind(undefined, data);
2021
+ }
2025
2022
  condDeclaration(ctx) {
2026
2023
  const prevSibling = ctx.prevSibling;
2027
2024
  const keyWord = this.tokenizer.token;
@@ -2175,7 +2172,27 @@ class Interpreter {
2175
2172
  hookI = _this$tokenizer$_hook4[2];
2176
2173
  const rawVal = data[Keys.Raw][value];
2177
2174
  const isFn = typeof rawVal === 'function';
2178
- if (hookType === 'dynamic') {
2175
+ if (key === 'ref') {
2176
+ const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
2177
+ let refValue = _node;
2178
+ if (_node.__logicType === FakeType.Component) {
2179
+ refValue = _node.data;
2180
+ } else {
2181
+ refValue[Keys.ProxyFreeObject] = true;
2182
+ }
2183
+ if (valueIsMapKey) {
2184
+ data[value] = refValue;
2185
+ new Scope(() => () => {
2186
+ data[value] = null;
2187
+ }).get();
2188
+ } else {
2189
+ const fn = this.getAssignFn(data, value);
2190
+ fn(refValue);
2191
+ new Scope(() => () => {
2192
+ fn(null);
2193
+ }).get();
2194
+ }
2195
+ } else if (hookType === 'dynamic') {
2179
2196
  const valueIsMapKey = Reflect.has(data[Keys.Raw], value);
2180
2197
  const fn = isFn ? rawVal : valueIsMapKey ? value : this.getFn(data, value);
2181
2198
  this.onePropParsed(data, _node, key, fn, valueIsMapKey, isFn, hookI);
@@ -2260,7 +2277,7 @@ function bobe(fragments, ...values) {
2260
2277
  function customRender(option) {
2261
2278
  return function render(Ctor, root) {
2262
2279
  const store = Ctor.new();
2263
- const tokenizer = store['ui'](false);
2280
+ const tokenizer = store.ui(false);
2264
2281
  const terp = new Interpreter(tokenizer);
2265
2282
  terp.config(option);
2266
2283
  const componentNode = {