tutuca 0.9.97 → 0.9.98

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,5 +1,5 @@
1
1
  // src/storybook.js
2
- import { component, dispatchPhase, html, injectCss, tutuca } from "tutuca";
2
+ import { component, dispatchPhase, html, injectCss, phaseHasBubble, tutuca } from "tutuca";
3
3
  var Storybook = component({
4
4
  name: "Storybook",
5
5
  fields: {
@@ -274,18 +274,25 @@ var Example = component({
274
274
  },
275
275
  receive: {
276
276
  init(ctx) {
277
- dispatchPhase(ctx, ctx.at.field("value").buildPath(), this.on?.init, this.value);
277
+ this.runPhase(ctx, "init", this.on?.init);
278
278
  return this;
279
279
  },
280
280
  resume(ctx) {
281
- dispatchPhase(ctx, ctx.at.field("value").buildPath(), this.on?.resume, this.value);
281
+ this.runPhase(ctx, "resume", this.on?.resume);
282
282
  return this;
283
283
  },
284
284
  suspend(ctx) {
285
- dispatchPhase(ctx, ctx.at.field("value").buildPath(), this.on?.suspend, this.value);
285
+ this.runPhase(ctx, "suspend", this.on?.suspend);
286
286
  return this;
287
287
  }
288
288
  },
289
+ methods: {
290
+ runPhase(ctx, name, phase) {
291
+ if (phaseHasBubble(phase))
292
+ console.warn(`storybook on.${name}: a \`bubble\` action leaves this example and is received by the storybook engine, so your component's bubble handler won't run. Use send/request/input to drive a preset state.`);
293
+ dispatchPhase(ctx, ctx.at.field("value").buildPath(), phase, this.value);
294
+ }
295
+ },
289
296
  input: {
290
297
  onLogSelected() {
291
298
  console.log(this.value);
@@ -1744,37 +1744,47 @@ class Renderer {
1744
1744
  renderEach(stack, iterInfo, node, viewName) {
1745
1745
  const { seq, filter, loopWith } = iterInfo.eval(stack);
1746
1746
  const r = [];
1747
- const { iterData, start, end } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
1748
- getSeqInfo(seq)(seq, (key, value, attrName) => {
1749
- if (filter.call(stack.it, key, value, iterData)) {
1750
- const dom = this.renderIt(stack.enter(value, { key }, true), node, key, viewName);
1751
- this.pushEachEntry(r, node.nodeId, attrName, key, dom);
1752
- }
1753
- }, start, end);
1747
+ const { iterData, start, end, keys } = unpackLoopResult(loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)), seq);
1748
+ const renderOne = (key, value, attrName) => {
1749
+ const dom = this.renderIt(stack.enter(value, { key }, true), node, key, viewName);
1750
+ this.pushEachEntry(r, node.nodeId, attrName, key, dom);
1751
+ };
1752
+ if (keys)
1753
+ imKeysIter(seq, renderOne, keys);
1754
+ else
1755
+ getSeqInfo(seq)(seq, (key, value, attrName) => {
1756
+ if (filter.call(stack.it, key, value, iterData))
1757
+ renderOne(key, value, attrName);
1758
+ }, start, end);
1754
1759
  return r;
1755
1760
  }
1756
1761
  renderEachWhen(stack, iterInfo, view, nid) {
1757
1762
  const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
1758
1763
  const r = [];
1759
1764
  const it = stack.it;
1760
- const { iterData, start, end } = unpackLoopResult(loopWith.call(it, seq), seq);
1761
- getSeqInfo(seq)(seq, (key, value, attrName) => {
1762
- if (filter.call(it, key, value, iterData)) {
1763
- const cachePath = enricher ? [view, it, value] : [view, value];
1764
- const binds = { key, value };
1765
- const cacheKey = `${nid}-${key}`;
1766
- if (enricher)
1767
- enricher.call(it, binds, key, value, iterData);
1768
- const cachedNode = this.cache.get(cachePath, cacheKey);
1769
- if (cachedNode)
1770
- this.pushEachEntry(r, nid, attrName, key, cachedNode);
1771
- else {
1772
- const dom = this.renderView(view, stack.enter(value, binds, false));
1773
- this.pushEachEntry(r, nid, attrName, key, dom);
1774
- this.cache.set(cachePath, cacheKey, dom);
1775
- }
1765
+ const { iterData, start, end, keys } = unpackLoopResult(loopWith.call(it, seq, makeLoopCtx(stack, filter)), seq);
1766
+ const renderOne = (key, value, attrName) => {
1767
+ const cachePath = enricher ? [view, it, value] : [view, value];
1768
+ const binds = { key, value };
1769
+ const cacheKey = `${nid}-${key}`;
1770
+ if (enricher)
1771
+ enricher.call(it, binds, key, value, iterData);
1772
+ const cachedNode = this.cache.get(cachePath, cacheKey);
1773
+ if (cachedNode)
1774
+ this.pushEachEntry(r, nid, attrName, key, cachedNode);
1775
+ else {
1776
+ const dom = this.renderView(view, stack.enter(value, binds, false));
1777
+ this.pushEachEntry(r, nid, attrName, key, dom);
1778
+ this.cache.set(cachePath, cacheKey, dom);
1776
1779
  }
1777
- }, start, end);
1780
+ };
1781
+ if (keys)
1782
+ imKeysIter(seq, renderOne, keys);
1783
+ else
1784
+ getSeqInfo(seq)(seq, (key, value, attrName) => {
1785
+ if (filter.call(it, key, value, iterData))
1786
+ renderOne(key, value, attrName);
1787
+ }, start, end);
1778
1788
  return r;
1779
1789
  }
1780
1790
  renderView(view, stack) {
@@ -1810,8 +1820,17 @@ var filterAlwaysTrue = (_v, _k, _seq) => true;
1810
1820
  var nullLoopWith = (seq) => ({ iterData: { seq } });
1811
1821
  var unpackLoopResult = (result, seq) => {
1812
1822
  const r = result ?? {};
1813
- return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end };
1823
+ return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end, keys: r.keys };
1824
+ };
1825
+ var imKeysIter = (seq, visit, keys) => {
1826
+ const attrName = isIndexed(seq) ? "si" : "sk";
1827
+ for (const key of keys)
1828
+ visit(key, seq.get(key), attrName);
1814
1829
  };
1830
+ var makeLoopCtx = (stack, filter) => ({
1831
+ lookup: (name) => stack.lookupBind(name),
1832
+ filter: (key, value, iterData) => filter.call(stack.it, key, value, iterData)
1833
+ });
1815
1834
  var imIndexedIter = (seq, visit, start, end) => {
1816
1835
  const [s, e] = normalizeRange(start, end, seq.size);
1817
1836
  for (let i = s;i < e; i++)
@@ -2359,11 +2378,11 @@ class IterInfo {
2359
2378
  return { seq, filter, loopWith, enricher };
2360
2379
  }
2361
2380
  enrichBinds(stack, key) {
2362
- const { seq, loopWith, enricher } = this.eval(stack);
2381
+ const { seq, filter, loopWith, enricher } = this.eval(stack);
2363
2382
  const value = seq?.get ? seq.get(key, null) : null;
2364
2383
  const binds = { key, value };
2365
2384
  if (enricher) {
2366
- const { iterData } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
2385
+ const { iterData } = unpackLoopResult(loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)), seq);
2367
2386
  enricher.call(stack.it, binds, key, value, iterData);
2368
2387
  }
2369
2388
  return binds;
@@ -3714,6 +3733,13 @@ function phaseOps(phase) {
3714
3733
  function resolveArgs(args, self) {
3715
3734
  return typeof args === "function" ? args(self) ?? [] : args ?? [];
3716
3735
  }
3736
+ function phaseHasBubble(phase) {
3737
+ if (!phase)
3738
+ return false;
3739
+ if (phase.bubble?.length)
3740
+ return true;
3741
+ return (phase.do ?? []).some((op) => op.type === "bubble");
3742
+ }
3717
3743
  function dispatchPhase(dispatcher, targetPath, phase, self) {
3718
3744
  if (!phase)
3719
3745
  return;
@@ -4007,7 +4033,8 @@ class FieldSet extends Field {
4007
4033
  }
4008
4034
  function mkCompField(field, scope, args) {
4009
4035
  const Comp = scope?.lookupComponent(field.type) ?? null;
4010
- console.assert(!scope || Comp !== null, "component not found", { field });
4036
+ if (Comp === null)
4037
+ console.warn(scope ? `component field "${field.name}": component "${field.type}" not found in scope` : `component field "${field.name}": cannot resolve component "${field.type}" — built without a registered scope (use ${field.type}.make({}) as the default, or build via a registered component)`);
4011
4038
  return Comp?.make({ ...field.args, ...args }, { scope }) ?? null;
4012
4039
  }
4013
4040
 
@@ -4156,6 +4183,7 @@ export {
4156
4183
  removeIn,
4157
4184
  remove,
4158
4185
  phaseOps,
4186
+ phaseHasBubble,
4159
4187
  mergeWith,
4160
4188
  mergeDeepWith,
4161
4189
  mergeDeep,
package/dist/tutuca.js CHANGED
@@ -6114,37 +6114,47 @@ class Renderer {
6114
6114
  renderEach(stack, iterInfo, node, viewName) {
6115
6115
  const { seq, filter, loopWith } = iterInfo.eval(stack);
6116
6116
  const r = [];
6117
- const { iterData, start, end } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
6118
- getSeqInfo(seq)(seq, (key, value, attrName) => {
6119
- if (filter.call(stack.it, key, value, iterData)) {
6120
- const dom = this.renderIt(stack.enter(value, { key }, true), node, key, viewName);
6121
- this.pushEachEntry(r, node.nodeId, attrName, key, dom);
6122
- }
6123
- }, start, end);
6117
+ const { iterData, start, end, keys } = unpackLoopResult(loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)), seq);
6118
+ const renderOne = (key, value, attrName) => {
6119
+ const dom = this.renderIt(stack.enter(value, { key }, true), node, key, viewName);
6120
+ this.pushEachEntry(r, node.nodeId, attrName, key, dom);
6121
+ };
6122
+ if (keys)
6123
+ imKeysIter(seq, renderOne, keys);
6124
+ else
6125
+ getSeqInfo(seq)(seq, (key, value, attrName) => {
6126
+ if (filter.call(stack.it, key, value, iterData))
6127
+ renderOne(key, value, attrName);
6128
+ }, start, end);
6124
6129
  return r;
6125
6130
  }
6126
6131
  renderEachWhen(stack, iterInfo, view, nid) {
6127
6132
  const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
6128
6133
  const r = [];
6129
6134
  const it = stack.it;
6130
- const { iterData, start, end } = unpackLoopResult(loopWith.call(it, seq), seq);
6131
- getSeqInfo(seq)(seq, (key, value, attrName) => {
6132
- if (filter.call(it, key, value, iterData)) {
6133
- const cachePath = enricher ? [view, it, value] : [view, value];
6134
- const binds = { key, value };
6135
- const cacheKey = `${nid}-${key}`;
6136
- if (enricher)
6137
- enricher.call(it, binds, key, value, iterData);
6138
- const cachedNode = this.cache.get(cachePath, cacheKey);
6139
- if (cachedNode)
6140
- this.pushEachEntry(r, nid, attrName, key, cachedNode);
6141
- else {
6142
- const dom = this.renderView(view, stack.enter(value, binds, false));
6143
- this.pushEachEntry(r, nid, attrName, key, dom);
6144
- this.cache.set(cachePath, cacheKey, dom);
6145
- }
6135
+ const { iterData, start, end, keys } = unpackLoopResult(loopWith.call(it, seq, makeLoopCtx(stack, filter)), seq);
6136
+ const renderOne = (key, value, attrName) => {
6137
+ const cachePath = enricher ? [view, it, value] : [view, value];
6138
+ const binds = { key, value };
6139
+ const cacheKey = `${nid}-${key}`;
6140
+ if (enricher)
6141
+ enricher.call(it, binds, key, value, iterData);
6142
+ const cachedNode = this.cache.get(cachePath, cacheKey);
6143
+ if (cachedNode)
6144
+ this.pushEachEntry(r, nid, attrName, key, cachedNode);
6145
+ else {
6146
+ const dom = this.renderView(view, stack.enter(value, binds, false));
6147
+ this.pushEachEntry(r, nid, attrName, key, dom);
6148
+ this.cache.set(cachePath, cacheKey, dom);
6146
6149
  }
6147
- }, start, end);
6150
+ };
6151
+ if (keys)
6152
+ imKeysIter(seq, renderOne, keys);
6153
+ else
6154
+ getSeqInfo(seq)(seq, (key, value, attrName) => {
6155
+ if (filter.call(it, key, value, iterData))
6156
+ renderOne(key, value, attrName);
6157
+ }, start, end);
6148
6158
  return r;
6149
6159
  }
6150
6160
  renderView(view, stack) {
@@ -6180,8 +6190,17 @@ var filterAlwaysTrue = (_v, _k, _seq) => true;
6180
6190
  var nullLoopWith = (seq) => ({ iterData: { seq } });
6181
6191
  var unpackLoopResult = (result, seq) => {
6182
6192
  const r = result ?? {};
6183
- return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end };
6193
+ return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end, keys: r.keys };
6184
6194
  };
6195
+ var imKeysIter = (seq, visit, keys) => {
6196
+ const attrName = isIndexed(seq) ? "si" : "sk";
6197
+ for (const key of keys)
6198
+ visit(key, seq.get(key), attrName);
6199
+ };
6200
+ var makeLoopCtx = (stack, filter) => ({
6201
+ lookup: (name) => stack.lookupBind(name),
6202
+ filter: (key, value, iterData) => filter.call(stack.it, key, value, iterData)
6203
+ });
6185
6204
  var imIndexedIter = (seq, visit, start, end) => {
6186
6205
  const [s, e] = normalizeRange(start, end, seq.size);
6187
6206
  for (let i = s;i < e; i++)
@@ -6729,11 +6748,11 @@ class IterInfo {
6729
6748
  return { seq, filter, loopWith, enricher };
6730
6749
  }
6731
6750
  enrichBinds(stack, key) {
6732
- const { seq, loopWith, enricher } = this.eval(stack);
6751
+ const { seq, filter, loopWith, enricher } = this.eval(stack);
6733
6752
  const value = seq?.get ? seq.get(key, null) : null;
6734
6753
  const binds = { key, value };
6735
6754
  if (enricher) {
6736
- const { iterData } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
6755
+ const { iterData } = unpackLoopResult(loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)), seq);
6737
6756
  enricher.call(stack.it, binds, key, value, iterData);
6738
6757
  }
6739
6758
  return binds;
@@ -8028,6 +8047,13 @@ function phaseOps(phase) {
8028
8047
  function resolveArgs(args, self) {
8029
8048
  return typeof args === "function" ? args(self) ?? [] : args ?? [];
8030
8049
  }
8050
+ function phaseHasBubble(phase) {
8051
+ if (!phase)
8052
+ return false;
8053
+ if (phase.bubble?.length)
8054
+ return true;
8055
+ return (phase.do ?? []).some((op) => op.type === "bubble");
8056
+ }
8031
8057
  function dispatchPhase(dispatcher, targetPath, phase, self) {
8032
8058
  if (!phase)
8033
8059
  return;
@@ -8320,7 +8346,8 @@ class FieldSet extends Field {
8320
8346
  }
8321
8347
  function mkCompField(field, scope, args) {
8322
8348
  const Comp = scope?.lookupComponent(field.type) ?? null;
8323
- console.assert(!scope || Comp !== null, "component not found", { field });
8349
+ if (Comp === null)
8350
+ console.warn(scope ? `component field "${field.name}": component "${field.type}" not found in scope` : `component field "${field.name}": cannot resolve component "${field.type}" — built without a registered scope (use ${field.type}.make({}) as the default, or build via a registered component)`);
8324
8351
  return Comp?.make({ ...field.args, ...args }, { scope }) ?? null;
8325
8352
  }
8326
8353
 
@@ -8469,6 +8496,7 @@ export {
8469
8496
  removeIn,
8470
8497
  remove,
8471
8498
  phaseOps,
8499
+ phaseHasBubble,
8472
8500
  mergeWith$1 as mergeWith,
8473
8501
  mergeDeepWith$1 as mergeDeepWith,
8474
8502
  mergeDeep$1 as mergeDeep,