bobe 0.0.47 → 0.0.49

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
@@ -81,6 +81,7 @@ class ParseSyntaxError extends SyntaxError {
81
81
  this.loc = loc;
82
82
  }
83
83
  }
84
+ const isDep = target => target && (target instanceof aoye.Signal || target instanceof aoye.Computed || typeof target === 'function' || typeof target === 'string');
84
85
 
85
86
  class Tokenizer {
86
87
  TabSize = 2;
@@ -105,10 +106,13 @@ class Tokenizer {
105
106
  this.hook = hook;
106
107
  this.useDedentAsEof = useDedentAsEof;
107
108
  if (useDedentAsEof) {
108
- this.setToken(TokenType.Indent, '');
109
- this.isFirstToken = true;
109
+ this.initIndentWhenUseDedentAsEof();
110
110
  }
111
111
  }
112
+ initIndentWhenUseDedentAsEof() {
113
+ this.setToken(TokenType.Indent, '');
114
+ this.isFirstToken = true;
115
+ }
112
116
  next() {
113
117
  this.i++;
114
118
  }
@@ -138,16 +142,23 @@ class Tokenizer {
138
142
  throwUnclosed(code, message, startOffset, startLine, startCol) {
139
143
  throw new ParseSyntaxError(code, message, this.unclosedLoc(startOffset, startLine, startCol));
140
144
  }
141
- resume(_snapshot) {
145
+ resume({
146
+ dentStack,
147
+ waitingTokens,
148
+ ..._snapshot
149
+ }) {
142
150
  this.token = undefined;
143
151
  this.needIndent = false;
144
152
  this.isFirstToken = true;
145
- this.dentStack = [0];
153
+ this.dentStack = dentStack ? dentStack.slice() : [0];
154
+ if (waitingTokens) {
155
+ this.waitingTokens = waitingTokens.clone();
156
+ }
146
157
  Object.assign(this, _snapshot);
147
158
  }
148
- snapshot(keys) {
159
+ snapshot(keys, dtI = 0) {
149
160
  const snap = {
150
- i: this.i,
161
+ i: this.i + dtI,
151
162
  waitingTokens: this.waitingTokens.clone()
152
163
  };
153
164
  if (keys) {
@@ -160,8 +171,10 @@ class Tokenizer {
160
171
  }
161
172
  return snap;
162
173
  }
163
- skip() {
164
- const logicDentLen = this.dentStack[this.dentStack.length - 1];
174
+ skip(targetDentLen) {
175
+ if (targetDentLen == undefined) {
176
+ targetDentLen = this.dentStack[this.dentStack.length - 1];
177
+ }
165
178
  let needIndent = false;
166
179
  let skipFragment = ``;
167
180
  this.token = undefined;
@@ -184,7 +197,7 @@ class Tokenizer {
184
197
  isEmptyLine = _this$getDentValue.isEmptyLine;
185
198
  const currLen = value.length;
186
199
  if (isEmptyLine) continue;
187
- if (currLen > logicDentLen) {
200
+ if (currLen > targetDentLen) {
188
201
  skipFragment += value;
189
202
  } else {
190
203
  for (let i = this.dentStack.length - 1; i >= 0; i--) {
@@ -197,6 +210,9 @@ class Tokenizer {
197
210
  break;
198
211
  }
199
212
  this.dentStack.pop();
213
+ if (expLen > targetDentLen) {
214
+ continue;
215
+ }
200
216
  if (!this.token) {
201
217
  this.setToken(TokenType.Dedent, String(expLen));
202
218
  } else {
@@ -251,29 +267,31 @@ class Tokenizer {
251
267
  }
252
268
  outer: while (1) {
253
269
  if (this.needIndent) {
270
+ this.locStart();
254
271
  this.dent();
272
+ this.locEnd();
255
273
  } else {
256
274
  const char = this.code[this.i];
257
275
  switch (char) {
258
276
  case '\t':
259
277
  case ' ':
260
278
  break;
261
- case '\n':
262
- this.newLine();
263
- this.needIndent = true;
264
- break;
265
- case '=':
266
- this.assignment();
267
- break;
268
- case '|':
269
- this.pipe();
270
- break;
271
- case ';':
272
- this.setToken(TokenType.Semicolon, ';');
273
- break;
274
279
  default:
275
- if (false) ;
280
+ this.locStart();
276
281
  switch (char) {
282
+ case '\n':
283
+ this.newLine();
284
+ this.needIndent = true;
285
+ break;
286
+ case '=':
287
+ this.assignment();
288
+ break;
289
+ case '|':
290
+ this.pipe();
291
+ break;
292
+ case ';':
293
+ this.setToken(TokenType.Semicolon, ';');
294
+ break;
277
295
  case '/':
278
296
  this.comment();
279
297
  break;
@@ -298,7 +316,7 @@ class Tokenizer {
298
316
  }
299
317
  break;
300
318
  }
301
- if (false) ;
319
+ this.locEnd();
302
320
  break;
303
321
  }
304
322
  this.next();
@@ -314,6 +332,10 @@ class Tokenizer {
314
332
  this.handledTokens.push(this.token);
315
333
  }
316
334
  }
335
+ locStart() {
336
+ }
337
+ locEnd() {
338
+ }
317
339
  getComment() {
318
340
  let value = '/';
319
341
  let nextC = this.code[this.i + 1];
@@ -330,6 +352,7 @@ class Tokenizer {
330
352
  this.getComment();
331
353
  }
332
354
  condExp() {
355
+ this.locStart();
333
356
  let value = '';
334
357
  this.token = null;
335
358
  let char = this.code[this.i];
@@ -344,12 +367,14 @@ class Tokenizer {
344
367
  const trimmed = value.replace(/\/\/[\s\S]+/, '').trim();
345
368
  this.setToken(TokenType.Identifier, trimmed ? trimmed : true, 0);
346
369
  this.handledTokens.push(this.token);
370
+ this.locEnd();
347
371
  return this.token;
348
372
  }
349
373
  isEol(i) {
350
374
  return this.code[i] === '\n' || this.code[i] === '/';
351
375
  }
352
376
  jsExp() {
377
+ this.locStart();
353
378
  this.token = null;
354
379
  let value = '';
355
380
  let char = this.code[this.i];
@@ -363,6 +388,7 @@ class Tokenizer {
363
388
  }
364
389
  this.setToken(TokenType.Identifier, value, 0);
365
390
  this.handledTokens.push(this.token);
391
+ this.locEnd();
366
392
  return this.token;
367
393
  }
368
394
  peekChar() {
@@ -550,7 +576,7 @@ class Tokenizer {
550
576
  const prevLen = this.dentStack[this.dentStack.length - 1];
551
577
  if (currLen > prevLen) {
552
578
  this.dentStack.push(currLen);
553
- this.setToken(TokenType.Indent, currLen);
579
+ this.setToken(TokenType.Indent, currLen, 0);
554
580
  return indentHasLen;
555
581
  }
556
582
  if (currLen < prevLen) {
@@ -565,7 +591,7 @@ class Tokenizer {
565
591
  }
566
592
  this.dentStack.pop();
567
593
  if (!this.token) {
568
- this.setToken(TokenType.Dedent, String(expLen));
594
+ this.setToken(TokenType.Dedent, String(expLen), 0);
569
595
  } else {
570
596
  this.waitingTokens.push({
571
597
  type: TokenType.Dedent,
@@ -974,7 +1000,7 @@ var NodeType = function (NodeType) {
974
1000
  let _initProto;
975
1001
  class Compiler {
976
1002
  static {
977
- 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, "parseJsExp"], [[NodeHook, TokenLoc], 2, "parsePropertyValue"], [[NodeHook, TokenLoc], 2, "parseName"]]).e, 1);
1003
+ 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, "parseJsExp"], [[NodeHook, TokenLoc], 2, "parsePropertyValue"], [[NodeHook, NodeLoc], 2, "parsePropertyInlineFragment"], [[NodeHook, TokenLoc], 2, "parseName"]]).e, 1);
978
1004
  _initProto = _applyDecs$e[0];
979
1005
  }
980
1006
  errors = (_initProto(this), []);
@@ -1076,9 +1102,9 @@ class Compiler {
1076
1102
  parseComponentNode(node) {
1077
1103
  const name = this.parseName();
1078
1104
  this.tokenizer.nextToken();
1079
- const props = this.headerLineAndExtensions();
1080
1105
  node.type = NodeType.Component;
1081
1106
  node.componentName = name;
1107
+ const props = this.headerLineAndExtensions();
1082
1108
  node.props = props;
1083
1109
  this.hooks.parseComponentNode?.propsAdded?.call(this, node);
1084
1110
  const children = this.handleChildren();
@@ -1096,9 +1122,9 @@ class Compiler {
1096
1122
  }
1097
1123
  const tagName = tagToken.value;
1098
1124
  this.tokenizer.nextToken();
1099
- const props = this.headerLineAndExtensions();
1100
1125
  node.type = NodeType.Element;
1101
1126
  node.tagName = tagName;
1127
+ const props = this.headerLineAndExtensions();
1102
1128
  node.props = props;
1103
1129
  this.hooks.parseElementNode?.propsAdded?.call(this, node);
1104
1130
  const children = this.handleChildren();
@@ -1172,17 +1198,17 @@ class Compiler {
1172
1198
  }
1173
1199
  headerLineAndExtensions() {
1174
1200
  const props = [];
1175
- props.push(...this.attributeList());
1176
- if (this.tokenizer.token.type & TokenType.NewLine) {
1177
- this.tokenizer.nextToken();
1178
- }
1179
- while (this.tokenizer.token.type & TokenType.Pipe) {
1180
- this.tokenizer.nextToken();
1201
+ do {
1181
1202
  props.push(...this.attributeList());
1182
1203
  if (this.tokenizer.token.type & TokenType.NewLine) {
1183
1204
  this.tokenizer.nextToken();
1184
1205
  }
1185
- }
1206
+ if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
1207
+ break;
1208
+ } else {
1209
+ this.tokenizer.nextToken();
1210
+ }
1211
+ } while (true);
1186
1212
  return props;
1187
1213
  }
1188
1214
  attributeList() {
@@ -1206,25 +1232,35 @@ class Compiler {
1206
1232
  const token = this.tokenizer.nextToken();
1207
1233
  if (token.value !== '=') {
1208
1234
  this.addError(ParseErrorCode.MISSING_ASSIGN, `属性 "${node.key.key}" 缺少 "=" 赋值符号`, node.key.loc ?? this.tokenizer.emptyLoc(), node);
1209
- node.loc.start = node.key.loc.start;
1210
- node.loc.end = node.key.loc.end;
1211
- node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1235
+ this.handleOnlyKeyLoc(node);
1212
1236
  return node;
1213
1237
  }
1214
1238
  const valueToken = this.tokenizer.nextToken();
1239
+ if (valueToken.type & TokenType.NewLine) {
1240
+ this.tokenizer.nextToken();
1241
+ node.value = this.parsePropertyInlineFragment();
1242
+ this.handleKeyValueLoc(node);
1243
+ return node;
1244
+ }
1215
1245
  if ((valueToken.type & ValueTokenType) === 0) {
1216
1246
  this.addError(ParseErrorCode.MISSING_PROP_ASSIGNMENT, `属性值不合法, "${valueToken.value}" 不合法`, valueToken.loc ?? this.tokenizer.emptyLoc(), node);
1217
- node.loc.start = node.key.loc.start;
1218
- node.loc.end = node.key.loc.end;
1219
- node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1247
+ this.handleOnlyKeyLoc(node);
1220
1248
  return node;
1221
1249
  }
1222
1250
  node.value = this.parsePropertyValue();
1223
1251
  this.tokenizer.nextToken();
1252
+ this.handleKeyValueLoc(node);
1253
+ return node;
1254
+ }
1255
+ handleOnlyKeyLoc(node) {
1256
+ node.loc.start = node.key.loc.start;
1257
+ node.loc.end = node.key.loc.end;
1258
+ node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1259
+ }
1260
+ handleKeyValueLoc(node) {
1224
1261
  node.loc.start = node.key.loc.start;
1225
1262
  node.loc.end = node.value.loc.end;
1226
1263
  node.loc.source = this.tokenizer.code.slice(node.loc.start.offset, node.loc.end.offset);
1227
- return node;
1228
1264
  }
1229
1265
  parsePropertyKey(node) {
1230
1266
  node.type = NodeType.PropertyKey;
@@ -1249,6 +1285,12 @@ class Compiler {
1249
1285
  node.value = value;
1250
1286
  return node;
1251
1287
  }
1288
+ parsePropertyInlineFragment(node) {
1289
+ const list = this.handleChildren();
1290
+ node.type = NodeType.StaticValue;
1291
+ node.value = list;
1292
+ return node;
1293
+ }
1252
1294
  parseName(node) {
1253
1295
  const _this$tokenizer$_hook7 = this.tokenizer._hook({}),
1254
1296
  _this$tokenizer$_hook8 = _slicedToArray(_this$tokenizer$_hook7, 2),
@@ -1472,6 +1514,9 @@ class Interpreter {
1472
1514
  }
1473
1515
  if (sort & NodeSort.TokenizerSwitcher) {
1474
1516
  const switcher = stack.peekByType(NodeSort.TokenizerSwitcher)?.node;
1517
+ if (parent.resumeSnapshot) {
1518
+ this.tokenizer.resume(parent.resumeSnapshot);
1519
+ }
1475
1520
  this.tokenizer = switcher.tokenizer;
1476
1521
  }
1477
1522
  if (parent.__logicType === FakeType.ForItem) {
@@ -1566,7 +1611,7 @@ class Interpreter {
1566
1611
  } else {
1567
1612
  const valueIsMapKey = Reflect.has(data[aoye.Keys.Raw], value);
1568
1613
  const val = data[aoye.Keys.Raw][value];
1569
- if (typeof val === 'function') {
1614
+ if (typeof val === 'function' || val instanceof InlineFragment) {
1570
1615
  _node = this.componentOrFragmentDeclaration(val, ctx);
1571
1616
  } else {
1572
1617
  const str = valueIsMapKey ? value : this.getFn(data, value);
@@ -1578,11 +1623,15 @@ class Interpreter {
1578
1623
  _node = this.createNode(value);
1579
1624
  }
1580
1625
  this.tokenizer.nextToken();
1581
- this.headerLine(_node);
1582
- this.extensionLines(_node);
1626
+ this.headerLineAndExtensions(_node);
1583
1627
  this.onePropParsed = this.oneRealPropParsed;
1584
1628
  if (_node.__logicType & TokenizerSwitcherBit) {
1585
1629
  this.tokenizer = _node.tokenizer;
1630
+ if (_node.fragmentSnapshot) {
1631
+ this.tokenizer.resume(_node.fragmentSnapshot);
1632
+ this.tokenizer.useDedentAsEof = true;
1633
+ this.tokenizer.initIndentWhenUseDedentAsEof();
1634
+ }
1586
1635
  }
1587
1636
  return _node;
1588
1637
  }
@@ -1664,7 +1713,7 @@ class Interpreter {
1664
1713
  _forNode$snapshot.isFirstToken;
1665
1714
  const snapshotForUpdate = _objectWithoutProperties(_forNode$snapshot, _excluded);
1666
1715
  let isFirstRender = true;
1667
- forNode.effect = new aoye.Effect(() => {
1716
+ forNode.effect = new this.Effect(() => {
1668
1717
  let arr = arrSignal.get();
1669
1718
  arr[aoye.Keys.Iterator];
1670
1719
  const prevCtx = aoye.getPulling();
@@ -1835,7 +1884,7 @@ class Interpreter {
1835
1884
  }
1836
1885
  }
1837
1886
  };
1838
- });
1887
+ }, aoye.ScheduleType.Render);
1839
1888
  return forNode.children[0] || forNode;
1840
1889
  }
1841
1890
  insertForItem(forNode, i, parentData, newChildren, before, snapshotForUpdate) {
@@ -1941,33 +1990,42 @@ class Interpreter {
1941
1990
  return this.setProp(node, key, value, hookI);
1942
1991
  }).get();
1943
1992
  } else if (typeof value === 'function') {
1944
- new aoye.Effect(() => {
1993
+ new this.Effect(() => {
1945
1994
  const res = value(data);
1946
1995
  const dispose = this.setProp(node, key, res, hookI);
1947
1996
  return dispose;
1948
- });
1997
+ }, aoye.ScheduleType.Render);
1949
1998
  } else if (valueIsMapKey) {
1950
- new aoye.Effect(() => {
1999
+ new this.Effect(() => {
1951
2000
  const res = data[value];
1952
2001
  const dispose = this.setProp(node, key, res, hookI);
1953
2002
  return dispose;
1954
- });
2003
+ }, aoye.ScheduleType.Render);
1955
2004
  } else {
1956
2005
  this.setProp(node, key, value, hookI);
1957
2006
  }
1958
2007
  }
1959
2008
  oneRealPropParsed = this.onePropParsed.bind(this);
1960
2009
  componentOrFragmentDeclaration(ComponentOrRender, ctx) {
1961
- let Component, render, child;
2010
+ let Component, tokenizer, child, fragmentSnapshot, resumeSnapshot;
1962
2011
  const isCC = ComponentOrRender.prototype instanceof aoye.Store;
1963
2012
  if (isCC) {
1964
2013
  Component = ComponentOrRender;
1965
2014
  child = Component.new();
2015
+ tokenizer = child.ui(true);
2016
+ } else if (ComponentOrRender instanceof InlineFragment) {
2017
+ const conf = ComponentOrRender;
2018
+ child = aoye.deepSignal({}, aoye.getPulling(), true);
2019
+ Object.setPrototypeOf(child, conf.data);
2020
+ tokenizer = conf.tokenizer;
2021
+ fragmentSnapshot = conf.snapshot;
2022
+ resumeSnapshot = tokenizer.snapshot(['token', 'needIndent', 'isFirstToken', 'dentStack', 'isFirstToken', 'useDedentAsEof']);
1966
2023
  } else {
1967
- render = ComponentOrRender;
2024
+ const render = ComponentOrRender;
1968
2025
  const boundStore = render.boundStore;
1969
2026
  child = aoye.deepSignal({}, aoye.getPulling(), true);
1970
2027
  Object.setPrototypeOf(child, boundStore);
2028
+ tokenizer = render(true);
1971
2029
  }
1972
2030
  const node = {
1973
2031
  __logicType: isCC ? FakeType.Component : FakeType.Fragment,
@@ -1975,7 +2033,9 @@ class Interpreter {
1975
2033
  realBefore: null,
1976
2034
  realAfter: null,
1977
2035
  data: child,
1978
- tokenizer: render ? render(true) : child.ui(true)
2036
+ tokenizer,
2037
+ fragmentSnapshot,
2038
+ resumeSnapshot
1979
2039
  };
1980
2040
  this.onePropParsed = createStoreOnePropParsed(child);
1981
2041
  node.realAfter = this.insertAfterAnchor('component-after');
@@ -2074,7 +2134,7 @@ class Interpreter {
2074
2134
  }
2075
2135
  ifNode.condition = signal;
2076
2136
  ifNode.realAfter = this.insertAfterAnchor(`${keyWord.value}-after`);
2077
- const ef = aoye.effect(({
2137
+ const ef = this.effect(({
2078
2138
  val
2079
2139
  }) => {
2080
2140
  if (val) {
@@ -2095,7 +2155,9 @@ class Interpreter {
2095
2155
  }
2096
2156
  }
2097
2157
  ifNode.isFirstRender = false;
2098
- }, [signal]);
2158
+ }, [signal], {
2159
+ type: 'render'
2160
+ });
2099
2161
  ifNode.effect = ef;
2100
2162
  return ifNode;
2101
2163
  }
@@ -2110,26 +2172,38 @@ class Interpreter {
2110
2172
  point = next;
2111
2173
  }
2112
2174
  }
2113
- extensionLines(_node) {
2114
- while (1) {
2115
- if ((this.tokenizer.token.type & TokenType.Pipe) === 0) {
2116
- return;
2175
+ headerLineAndExtensions(_node) {
2176
+ const tokenizer = this.tokenizer;
2177
+ do {
2178
+ const isComponent = _node.__logicType & TokenizerSwitcherBit;
2179
+ let snapshot, dentLen;
2180
+ const data = this.getData();
2181
+ const unHandledKey = this.attributeList(_node, data);
2182
+ if (isComponent) {
2183
+ snapshot = tokenizer.snapshot(undefined, -1);
2184
+ dentLen = tokenizer.dentStack[tokenizer.dentStack.length - 1];
2117
2185
  }
2118
- this.tokenizer.nextToken();
2119
- this.attributeList(_node);
2120
- if ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
2121
- return;
2186
+ tokenizer.nextToken();
2187
+ if ((tokenizer.token.type & TokenType.Pipe) === 0) {
2188
+ if (isComponent && tokenizer.token.type & TokenType.Indent) {
2189
+ this.inlineFragment(_node, snapshot, data, unHandledKey);
2190
+ tokenizer.skip(dentLen);
2191
+ if ((tokenizer.token.type & TokenType.Pipe) === 0) {
2192
+ break;
2193
+ }
2194
+ } else {
2195
+ break;
2196
+ }
2122
2197
  }
2123
- this.tokenizer.nextToken();
2124
- }
2198
+ tokenizer.nextToken();
2199
+ } while (true);
2125
2200
  }
2126
- headerLine(_node) {
2127
- this.attributeList(_node);
2128
- this.tokenizer.nextToken();
2201
+ inlineFragment(_node, snapshot, data, key = 'children') {
2202
+ const value = new InlineFragment(snapshot, data, key, this.tokenizer);
2203
+ this.onePropParsed(data, _node, key, value, false, true);
2129
2204
  }
2130
- attributeList(_node) {
2205
+ attributeList(_node, data) {
2131
2206
  let key, eq;
2132
- const data = this.getData();
2133
2207
  while ((this.tokenizer.token.type & TokenType.NewLine) === 0) {
2134
2208
  if (key == null) {
2135
2209
  key = this.tokenizer.token.value;
@@ -2177,10 +2251,15 @@ class Interpreter {
2177
2251
  }
2178
2252
  this.tokenizer.nextToken();
2179
2253
  }
2254
+ return key;
2180
2255
  }
2181
2256
  config(opt) {
2182
2257
  Object.assign(this, opt);
2183
2258
  this.opt = opt;
2259
+ if (opt.noopEffect) {
2260
+ this.effect = aoye.noopEffect;
2261
+ this.Effect = aoye.NoopEffect;
2262
+ }
2184
2263
  }
2185
2264
  createNode(name) {
2186
2265
  return {
@@ -2230,6 +2309,8 @@ class Interpreter {
2230
2309
  setProp(node, key, value, hookI) {
2231
2310
  node.props[key] = value;
2232
2311
  }
2312
+ Effect = aoye.Effect;
2313
+ effect = aoye.effect;
2233
2314
  }
2234
2315
  function createStoreOnePropParsed(child) {
2235
2316
  const onePropParsed = (data, _, key, value, valueIsMapKey, isFn, hookI) => {
@@ -2254,6 +2335,15 @@ function createStoreOnePropParsed(child) {
2254
2335
  };
2255
2336
  return onePropParsed;
2256
2337
  }
2338
+ class InlineFragment {
2339
+ [aoye.Keys.ProxyFreeObject] = true;
2340
+ constructor(snapshot, data, key, tokenizer) {
2341
+ this.snapshot = snapshot;
2342
+ this.data = data;
2343
+ this.key = key;
2344
+ this.tokenizer = tokenizer;
2345
+ }
2346
+ }
2257
2347
 
2258
2348
  function bobe(fragments, ...values) {
2259
2349
  const ui = function ui(isSub) {
@@ -2300,6 +2390,34 @@ const context = name => {
2300
2390
  return context;
2301
2391
  };
2302
2392
 
2393
+ const depTokenizer = new Tokenizer(() => '', false);
2394
+ const effect = (callback, depOrOpt, opt) => {
2395
+ const isArray = Array.isArray(depOrOpt);
2396
+ const isSingleDep = isDep(depOrOpt);
2397
+ const deps = isArray ? depOrOpt : isSingleDep ? [depOrOpt] : [];
2398
+ const option = isArray || isSingleDep ? opt : depOrOpt;
2399
+ const newDeps = [];
2400
+ for (let i = 0; i < deps.length; i++) {
2401
+ const dep = deps[i];
2402
+ if (typeof dep === 'string') {
2403
+ depTokenizer.code = dep.trim() + '\n';
2404
+ let exp;
2405
+ while (depTokenizer.i < depTokenizer.code.length) {
2406
+ exp = depTokenizer.jsExp().value;
2407
+ depTokenizer.nextToken();
2408
+ newDeps.push(new Function('data', `let v;with(data){v=${exp};}return v;`).bind(undefined, aoye.Store.Current));
2409
+ }
2410
+ } else {
2411
+ newDeps.push(dep);
2412
+ }
2413
+ }
2414
+ return aoye.effect(callback, newDeps, option);
2415
+ };
2416
+
2417
+ Object.defineProperty(exports, "Store", {
2418
+ enumerable: true,
2419
+ get: function () { return aoye.Store; }
2420
+ });
2303
2421
  exports.Compiler = Compiler;
2304
2422
  exports.NodeType = NodeType;
2305
2423
  exports.ParseSyntaxError = ParseSyntaxError;
@@ -2307,10 +2425,5 @@ exports.Tokenizer = Tokenizer;
2307
2425
  exports.bobe = bobe;
2308
2426
  exports.context = context;
2309
2427
  exports.customRender = customRender;
2310
- Object.keys(aoye).forEach(function (k) {
2311
- if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
2312
- enumerable: true,
2313
- get: function () { return aoye[k]; }
2314
- });
2315
- });
2428
+ exports.effect = effect;
2316
2429
  //# sourceMappingURL=bobe.cjs.js.map