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