tutuca 0.9.96 → 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.
@@ -8973,6 +8973,8 @@ class RequestHandler {
8973
8973
  }
8974
8974
 
8975
8975
  // src/cache.js
8976
+ var isWeakKey = (k) => k !== null && (typeof k === "object" || typeof k === "function");
8977
+
8976
8978
  class NullDomCache {
8977
8979
  get(_keys, _cacheKey) {}
8978
8980
  set(_keys, _cacheKey, _v) {}
@@ -9016,7 +9018,7 @@ class WeakMapDomCache {
9016
9018
  const key = keys[i];
9017
9019
  let next = cur.get(key);
9018
9020
  if (!next) {
9019
- if (typeof key !== "object") {
9021
+ if (!isWeakKey(key)) {
9020
9022
  this.badKey += 1;
9021
9023
  return;
9022
9024
  }
@@ -9029,7 +9031,7 @@ class WeakMapDomCache {
9029
9031
  const leaf = cur.get(lastKey);
9030
9032
  if (leaf)
9031
9033
  leaf[cacheKey] = v;
9032
- else if (typeof lastKey === "object")
9034
+ else if (isWeakKey(lastKey))
9033
9035
  cur.set(lastKey, { [cacheKey]: v });
9034
9036
  else
9035
9037
  this.badKey += 1;
@@ -9491,37 +9493,47 @@ class Renderer {
9491
9493
  renderEach(stack, iterInfo, node, viewName) {
9492
9494
  const { seq, filter, loopWith } = iterInfo.eval(stack);
9493
9495
  const r = [];
9494
- const { iterData, start, end } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
9495
- getSeqInfo(seq)(seq, (key, value, attrName) => {
9496
- if (filter.call(stack.it, key, value, iterData)) {
9497
- const dom = this.renderIt(stack.enter(value, { key }, true), node, key, viewName);
9498
- this.pushEachEntry(r, node.nodeId, attrName, key, dom);
9499
- }
9500
- }, start, end);
9496
+ const { iterData, start, end, keys } = unpackLoopResult(loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)), seq);
9497
+ const renderOne = (key, value, attrName) => {
9498
+ const dom = this.renderIt(stack.enter(value, { key }, true), node, key, viewName);
9499
+ this.pushEachEntry(r, node.nodeId, attrName, key, dom);
9500
+ };
9501
+ if (keys)
9502
+ imKeysIter(seq, renderOne, keys);
9503
+ else
9504
+ getSeqInfo(seq)(seq, (key, value, attrName) => {
9505
+ if (filter.call(stack.it, key, value, iterData))
9506
+ renderOne(key, value, attrName);
9507
+ }, start, end);
9501
9508
  return r;
9502
9509
  }
9503
9510
  renderEachWhen(stack, iterInfo, view, nid) {
9504
9511
  const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
9505
9512
  const r = [];
9506
9513
  const it = stack.it;
9507
- const { iterData, start, end } = unpackLoopResult(loopWith.call(it, seq), seq);
9508
- getSeqInfo(seq)(seq, (key, value, attrName) => {
9509
- if (filter.call(it, key, value, iterData)) {
9510
- const cachePath = enricher ? [view, it, value] : [view, value];
9511
- const binds = { key, value };
9512
- const cacheKey = `${nid}-${key}`;
9513
- if (enricher)
9514
- enricher.call(it, binds, key, value, iterData);
9515
- const cachedNode = this.cache.get(cachePath, cacheKey);
9516
- if (cachedNode)
9517
- this.pushEachEntry(r, nid, attrName, key, cachedNode);
9518
- else {
9519
- const dom = this.renderView(view, stack.enter(value, binds, false));
9520
- this.pushEachEntry(r, nid, attrName, key, dom);
9521
- this.cache.set(cachePath, cacheKey, dom);
9522
- }
9514
+ const { iterData, start, end, keys } = unpackLoopResult(loopWith.call(it, seq, makeLoopCtx(stack, filter)), seq);
9515
+ const renderOne = (key, value, attrName) => {
9516
+ const cachePath = enricher ? [view, it, value] : [view, value];
9517
+ const binds = { key, value };
9518
+ const cacheKey = `${nid}-${key}`;
9519
+ if (enricher)
9520
+ enricher.call(it, binds, key, value, iterData);
9521
+ const cachedNode = this.cache.get(cachePath, cacheKey);
9522
+ if (cachedNode)
9523
+ this.pushEachEntry(r, nid, attrName, key, cachedNode);
9524
+ else {
9525
+ const dom = this.renderView(view, stack.enter(value, binds, false));
9526
+ this.pushEachEntry(r, nid, attrName, key, dom);
9527
+ this.cache.set(cachePath, cacheKey, dom);
9523
9528
  }
9524
- }, start, end);
9529
+ };
9530
+ if (keys)
9531
+ imKeysIter(seq, renderOne, keys);
9532
+ else
9533
+ getSeqInfo(seq)(seq, (key, value, attrName) => {
9534
+ if (filter.call(it, key, value, iterData))
9535
+ renderOne(key, value, attrName);
9536
+ }, start, end);
9525
9537
  return r;
9526
9538
  }
9527
9539
  renderView(view, stack) {
@@ -9557,8 +9569,17 @@ var filterAlwaysTrue = (_v, _k, _seq) => true;
9557
9569
  var nullLoopWith = (seq) => ({ iterData: { seq } });
9558
9570
  var unpackLoopResult = (result, seq) => {
9559
9571
  const r = result ?? {};
9560
- return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end };
9572
+ return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end, keys: r.keys };
9573
+ };
9574
+ var imKeysIter = (seq, visit, keys) => {
9575
+ const attrName = isIndexed(seq) ? "si" : "sk";
9576
+ for (const key of keys)
9577
+ visit(key, seq.get(key), attrName);
9561
9578
  };
9579
+ var makeLoopCtx = (stack, filter) => ({
9580
+ lookup: (name) => stack.lookupBind(name),
9581
+ filter: (key, value, iterData) => filter.call(stack.it, key, value, iterData)
9582
+ });
9562
9583
  var imIndexedIter = (seq, visit, start, end) => {
9563
9584
  const [s, e] = normalizeRange(start, end, seq.size);
9564
9585
  for (let i = s;i < e; i++)
@@ -10106,11 +10127,11 @@ class IterInfo {
10106
10127
  return { seq, filter, loopWith, enricher };
10107
10128
  }
10108
10129
  enrichBinds(stack, key) {
10109
- const { seq, loopWith, enricher } = this.eval(stack);
10130
+ const { seq, filter, loopWith, enricher } = this.eval(stack);
10110
10131
  const value = seq?.get ? seq.get(key, null) : null;
10111
10132
  const binds = { key, value };
10112
10133
  if (enricher) {
10113
- const { iterData } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
10134
+ const { iterData } = unpackLoopResult(loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)), seq);
10114
10135
  enricher.call(stack.it, binds, key, value, iterData);
10115
10136
  }
10116
10137
  return binds;
@@ -13689,6 +13710,13 @@ function phaseOps(phase) {
13689
13710
  function resolveArgs(args, self) {
13690
13711
  return typeof args === "function" ? args(self) ?? [] : args ?? [];
13691
13712
  }
13713
+ function phaseHasBubble(phase) {
13714
+ if (!phase)
13715
+ return false;
13716
+ if (phase.bubble?.length)
13717
+ return true;
13718
+ return (phase.do ?? []).some((op) => op.type === "bubble");
13719
+ }
13692
13720
  function dispatchPhase(dispatcher, targetPath, phase, self) {
13693
13721
  if (!phase)
13694
13722
  return;
@@ -14625,6 +14653,8 @@ async function driveStack(stack, value, phase, opts = {}) {
14625
14653
  const t = info?.transaction;
14626
14654
  opts.onMessage({ kind: t?.handlerProp ?? "input", name: t?.name, args: t?.args, path: t?.path }, old, val);
14627
14655
  });
14656
+ if (phaseHasBubble(phase))
14657
+ console.warn("drive(): a `bubble` action is a no-op here — drive originates at the root and bubbles travel child→parent, so there is no ancestor to receive it (and the root's own bubble handler is skipped). To exercise a bubble handler, call it directly.");
14628
14658
  dispatchPhase(rootDispatcher(transactor), new Path([]), phase, value);
14629
14659
  await transactor.settle();
14630
14660
  return transactor.state.val;
@@ -15556,7 +15586,8 @@ class FieldSet extends Field {
15556
15586
  }
15557
15587
  function mkCompField(field, scope, args) {
15558
15588
  const Comp = scope?.lookupComponent(field.type) ?? null;
15559
- console.assert(!scope || Comp !== null, "component not found", { field });
15589
+ if (Comp === null)
15590
+ 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)`);
15560
15591
  return Comp?.make({ ...field.args, ...args }, { scope }) ?? null;
15561
15592
  }
15562
15593
 
@@ -15730,13 +15761,30 @@ function resolveAlter(Comp, name) {
15730
15761
  }
15731
15762
  return fn;
15732
15763
  }
15764
+ var seqGet = (seq, key) => Array.isArray(seq) ? seq[key] : seq.get ? seq.get(key) : seq[key];
15733
15765
  function collectIterBindings(Comp, compInstance, seq, opts = {}) {
15734
15766
  const whenFn = resolveAlter(Comp, opts.when) ?? filterAlwaysTrue;
15735
15767
  const loopWithFn = resolveAlter(Comp, opts.loopWith) ?? nullLoopWith;
15736
15768
  const enrichFn = resolveAlter(Comp, opts.enrichWith);
15769
+ const scopeEnrichFn = resolveAlter(Comp, opts.scopeEnrich);
15737
15770
  const it = compInstance;
15738
- const { iterData, start, end } = unpackLoopResult(loopWithFn.call(it, seq), seq);
15771
+ const scope = scopeEnrichFn ? scopeEnrichFn.call(it) ?? {} : opts.scope ?? {};
15772
+ const ctx = {
15773
+ lookup: (name) => scope[name],
15774
+ filter: (key, value, iterData2) => whenFn.call(it, key, value, iterData2)
15775
+ };
15776
+ const { iterData, start, end, keys } = unpackLoopResult(loopWithFn.call(it, seq, ctx), seq);
15739
15777
  const out = [];
15778
+ if (keys) {
15779
+ for (const key of keys) {
15780
+ const value = seqGet(seq, key);
15781
+ const binds = { key, value };
15782
+ if (enrichFn)
15783
+ enrichFn.call(it, binds, key, value, iterData);
15784
+ out.push(binds);
15785
+ }
15786
+ return out;
15787
+ }
15740
15788
  const iter = pickIter(seq);
15741
15789
  iter(seq, (key, value) => {
15742
15790
  if (!whenFn.call(it, key, value, iterData))
@@ -16000,6 +16048,7 @@ export {
16000
16048
  removeIn,
16001
16049
  remove,
16002
16050
  phaseOps,
16051
+ phaseHasBubble,
16003
16052
  mergeWith$1 as mergeWith,
16004
16053
  mergeDeepWith$1 as mergeDeepWith,
16005
16054
  mergeDeep$1 as mergeDeep,