tutuca 0.13.0 → 0.13.2

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.
@@ -64,11 +64,6 @@ var writeKey = (value, key, next) => {
64
64
  value.add(next);
65
65
  } else value[key] = next;
66
66
  };
67
- var readSeqKey = (value, key, dval = null) => {
68
- const direct = readKey(value, key, NONE);
69
- if (direct !== NONE) return direct;
70
- return typeof value?.get === "function" ? value.get(key, dval) : dval;
71
- };
72
67
  var writeSeqKey = (value, key, next) => {
73
68
  if (value instanceof Map || value instanceof Set || Array.isArray(value) || Object.hasOwn(value, key))
74
69
  writeKey(value, key, next);
@@ -81,7 +76,7 @@ var Step = class {
81
76
  }
82
77
  setDraftValue(_root, _v) {
83
78
  }
84
- enterFrame(stack, _prev, next) {
79
+ enterFrame(stack, next) {
85
80
  return stack.enter(next, {}, true);
86
81
  }
87
82
  toAbstractPathStep() {
@@ -107,7 +102,7 @@ var BindStep = class _BindStep extends Step {
107
102
  lookup(v, _dval) {
108
103
  return v;
109
104
  }
110
- enterFrame(stack, _prev, next) {
105
+ enterFrame(stack, next) {
111
106
  return stack.enter(next, { ...this.binds }, false);
112
107
  }
113
108
  withIndex(i) {
@@ -125,7 +120,7 @@ var ScopeBindStep = class _ScopeBindStep extends BindStep {
125
120
  super(binds);
126
121
  this.val = val;
127
122
  }
128
- enterFrame(stack, _prev, next) {
123
+ enterFrame(stack, next) {
129
124
  const dyn = this.val.evalAsHandler(stack)?.call(stack.it) ?? {};
130
125
  return stack.enter(next, { ...this.binds, ...dyn }, false);
131
126
  }
@@ -164,13 +159,13 @@ var SeqStep = class extends Step {
164
159
  this.key = key;
165
160
  }
166
161
  lookup(v, dval = null) {
167
- return readSeqKey(readKey(v, this.field, null), this.key, dval);
162
+ return seqGet(readKey(v, this.field, null), this.key, dval);
168
163
  }
169
164
  setDraftValue(root, v) {
170
165
  const seq = readKey(root, this.field, null);
171
166
  if (seq != null) writeSeqKey(seq, this.key, v);
172
167
  }
173
- enterFrame(stack, _prev, next) {
168
+ enterFrame(stack, next) {
174
169
  return stack.enter(next, { key: this.key }, true);
175
170
  }
176
171
  toKey() {
@@ -186,7 +181,7 @@ var SeqAccessStep = class extends Step {
186
181
  lookup(v, dval = null) {
187
182
  const seq = readKey(v, this.seqField, NONE);
188
183
  const key = readKey(v, this.keyField, NONE);
189
- return key !== NONE && seq !== NONE ? readSeqKey(seq, key, dval) : dval;
184
+ return key !== NONE && seq !== NONE ? seqGet(seq, key, dval) : dval;
190
185
  }
191
186
  setDraftValue(root, v) {
192
187
  const seq = readKey(root, this.seqField, NONE);
@@ -217,7 +212,7 @@ var EachBindStep = class extends Step {
217
212
  }
218
213
  // Replay the renderer's per-item binds (key, value + any @enrich-with binds)
219
214
  // so a rebuilt stack matches the one @each rendered with.
220
- enterFrame(stack, _prev, next) {
215
+ enterFrame(stack, next) {
221
216
  return stack.enter(next, this.iterInfo.enrichBinds(stack, this.key), false);
222
217
  }
223
218
  toAbstractPathStep() {
@@ -225,7 +220,7 @@ var EachBindStep = class extends Step {
225
220
  }
226
221
  };
227
222
  var EachRenderItStep = class extends SeqStep {
228
- enterFrame(stack, _prev, next) {
223
+ enterFrame(stack, next) {
229
224
  return stack.enter(next, { key: this.key, value: next }, false).enter(next, {}, true);
230
225
  }
231
226
  toAbstractPathStep() {
@@ -250,7 +245,7 @@ var DynStep = class extends Step {
250
245
  warnRawDynStep("lookup", this);
251
246
  return dval;
252
247
  }
253
- enterFrame(stack, _prev, _next) {
248
+ enterFrame(stack, _next) {
254
249
  warnRawDynStep("enterFrame", this);
255
250
  return stack;
256
251
  }
@@ -388,7 +383,7 @@ var Path = class _Path {
388
383
  console.warn("bad PathItem", { root: stack.it, step, path: this });
389
384
  return null;
390
385
  }
391
- stack = step.enterFrame(stack, prev, next);
386
+ stack = step.enterFrame(stack, next);
392
387
  prev = next;
393
388
  }
394
389
  return stack;
@@ -458,10 +453,6 @@ var Path = class _Path {
458
453
  console.warn("event reconstruction: dynamic-var producer not found", pendingDyns);
459
454
  return [new _Path(pathSteps.reverse()), handlers];
460
455
  }
461
- static fromEvent(e, rNode, maxDepth, comps, stopOnNoEvent = true) {
462
- const { type, target } = e;
463
- return _Path.fromNodeAndEventName(target, type, rNode, maxDepth, comps, stopOnNoEvent);
464
- }
465
456
  };
466
457
  function metaChain(n) {
467
458
  const out = [];
@@ -1021,7 +1012,7 @@ var Attributes = class {
1021
1012
  this.items = items;
1022
1013
  }
1023
1014
  static parse(attributes, px, parseAll = false) {
1024
- return getAttrParser(px).parse(attributes, parseAll);
1015
+ return new AttrParser(px).parse(attributes, parseAll);
1025
1016
  }
1026
1017
  isConstant() {
1027
1018
  return false;
@@ -1267,9 +1258,6 @@ var IfAttr = class extends BaseAttr {
1267
1258
  return this.condVal.eval(stack) ? this.thenVal.eval(stack) : this.elseVal.eval(stack);
1268
1259
  }
1269
1260
  };
1270
- function getAttrParser(px) {
1271
- return new AttrParser(px);
1272
- }
1273
1261
  var EventHandler = class _EventHandler {
1274
1262
  constructor(handlerVal, args = []) {
1275
1263
  this.handlerVal = handlerVal;
@@ -1285,12 +1273,6 @@ var EventHandler = class _EventHandler {
1285
1273
  return r === null ? null : new _EventHandler(r.handlerVal, r.args);
1286
1274
  }
1287
1275
  };
1288
- var IntentHandler = class {
1289
- constructor(name, fn) {
1290
- this.name = name;
1291
- this.fn = fn;
1292
- }
1293
- };
1294
1276
 
1295
1277
  // src/iteration.js
1296
1278
  var SEQ_INFO = /* @__PURE__ */ Symbol.for("tutuca.seqInfo");
@@ -1341,6 +1323,15 @@ var callEnricher = (enricher, it, binds, key, value, iterData) => {
1341
1323
  binds.key = key;
1342
1324
  binds.value = value;
1343
1325
  };
1326
+ function bindsForKey({ seq, it, loopWith, enricher, ctx }, key) {
1327
+ const value = seqGet(seq, key, null);
1328
+ const binds = { key, value };
1329
+ if (enricher) {
1330
+ const { iterData } = unpackLoopResult(loopWith.call(it, seq, ctx), seq);
1331
+ callEnricher(enricher, it, binds, key, value, iterData);
1332
+ }
1333
+ return binds;
1334
+ }
1344
1335
  var visitKeys = (seq, keys, visit) => {
1345
1336
  const attrName = isIndexedSeq(seq) ? "si" : "sk";
1346
1337
  for (const key of keys) visit(key, seqGet(seq, key), attrName);
@@ -2185,20 +2176,11 @@ var IterInfo = class {
2185
2176
  const enricher = this.enrichWithVal?.evalAsHandler(stack) ?? null;
2186
2177
  return { seq, filter, loopWith, enricher };
2187
2178
  }
2188
- // Rebuild the per-item binds for `key`, mirroring renderEachWhen: seed
2189
- // { key, value }, then run @enrich-with (with @loop-with's iterData) if any.
2179
+ // Rebuild the per-item binds for `key` (see iteration.js bindsForKey).
2190
2180
  enrichBinds(stack, key) {
2191
2181
  const { seq, filter, loopWith, enricher } = this.eval(stack);
2192
- const value = seqGet(seq, key, null);
2193
- const binds = { key, value };
2194
- if (enricher) {
2195
- const { iterData } = unpackLoopResult(
2196
- loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)),
2197
- seq
2198
- );
2199
- callEnricher(enricher, stack.it, binds, key, value, iterData);
2200
- }
2201
- return binds;
2182
+ const ctx = makeLoopCtx(stack, filter);
2183
+ return bindsForKey({ seq, it: stack.it, loopWith, enricher, ctx }, key);
2202
2184
  }
2203
2185
  };
2204
2186
  function xOp(consumed = [], { wrappable = false, wrapper = null, ignoresChildren = false } = {}) {
@@ -2394,10 +2376,11 @@ var NodeEvent = class {
2394
2376
  }
2395
2377
  };
2396
2378
  var fwdIfCtxPred = (pred) => (w) => (that, f, args, ctx) => pred(ctx) ? w(that, f, args, ctx) : that;
2397
- var fwdIfKey = (keyName) => fwdIfCtxPred((ctx) => ctx.e.key === keyName);
2398
- var fwdCtrl = fwdIfCtxPred(({ e }) => isMac && e.metaKey || e.ctrlKey);
2399
- var fwdMeta = fwdIfCtxPred(({ e }) => e.metaKey);
2400
- var fwdAlt = fwdIfCtxPred(({ e }) => e.altKey);
2379
+ var fwdIfEventPred = (pred) => fwdIfCtxPred(({ e }) => pred(e));
2380
+ var fwdIfKey = (keyName) => fwdIfEventPred(keyIs(keyName));
2381
+ var fwdCtrl = fwdIfEventPred(macCtrl);
2382
+ var fwdMeta = fwdIfEventPred((e) => e.metaKey);
2383
+ var fwdAlt = fwdIfEventPred((e) => e.altKey);
2401
2384
  var MOD_WRAPPERS_FOR_ANY_EVENT = {
2402
2385
  ctrl: fwdCtrl,
2403
2386
  cmd: fwdCtrl,
@@ -2504,13 +2487,15 @@ var ComponentStack = class _ComponentStack {
2504
2487
  getCompFor(v) {
2505
2488
  return this.comps.getCompFor(v);
2506
2489
  }
2507
- // Handlers that answer an intent's `lex` leg. A name maps to a LIST, because the leg
2508
- // walks: a handler that returns PASS declines and hands the intent to the next one.
2509
- // A bare function is accepted as a one-element list.
2490
+ // Handlers that answer an intent's `lex` leg. A name maps to a LIST of plain
2491
+ // functions, because the leg walks: a handler that returns PASS declines and hands
2492
+ // the intent to the next one. Each runs with no `this` and takes a dispatcher
2493
+ // context as its final argument; resolving answers, throwing fails. A bare function
2494
+ // is accepted as a one-element list.
2510
2495
  registerIntentHandlers(handlers) {
2511
2496
  for (const name in handlers) {
2512
- const fns = Array.isArray(handlers[name]) ? handlers[name] : [handlers[name]];
2513
- this.intentsByName[name] = fns.map((fn) => new IntentHandler(name, fn));
2497
+ const fns = handlers[name];
2498
+ this.intentsByName[name] = Array.isArray(fns) ? fns : [fns];
2514
2499
  }
2515
2500
  }
2516
2501
  // Innermost scope first, then outward. Concatenated rather than first-match, so a
@@ -2540,14 +2525,12 @@ var ComponentStack = class _ComponentStack {
2540
2525
  }
2541
2526
  };
2542
2527
  var ProvideInfo = class {
2543
- constructor(name, val) {
2544
- this.name = name;
2528
+ constructor(val) {
2545
2529
  this.val = val;
2546
2530
  }
2547
2531
  };
2548
2532
  var LookupInfo = class {
2549
- constructor(name, val) {
2550
- this.name = name;
2533
+ constructor(val) {
2551
2534
  this.val = val;
2552
2535
  }
2553
2536
  };
@@ -2595,13 +2578,13 @@ var Component = class {
2595
2578
  continue;
2596
2579
  }
2597
2580
  const val = parseProvide(this._rawProvide[key], ctx);
2598
- if (val) this.provide[key] = new ProvideInfo(key, val);
2581
+ if (val) this.provide[key] = new ProvideInfo(val);
2599
2582
  }
2600
2583
  for (const entry of this._rawLookup) {
2601
2584
  const name = isString(entry) ? entry : isString(entry?.name) ? entry.name : null;
2602
2585
  if (name === null) continue;
2603
2586
  const defStr = isString(entry?.default) ? entry.default : null;
2604
- this.lookup[name] = new LookupInfo(name, defStr === null ? null : parseField(defStr, ctx));
2587
+ this.lookup[name] = new LookupInfo(defStr === null ? null : parseField(defStr, ctx));
2605
2588
  }
2606
2589
  for (const key in this.lookup)
2607
2590
  if (this.provide[key] !== void 0)
@@ -2631,7 +2614,7 @@ var Component = class {
2631
2614
  // src/stack.js
2632
2615
  var STOP = /* @__PURE__ */ Symbol("STOP");
2633
2616
  var NEXT = /* @__PURE__ */ Symbol("NEXT");
2634
- var DEFAULT_LOOKUP_ROUTE = ["dyn", "lex"];
2617
+ var DEFAULT_ROUTE = ["dyn", "lex"];
2635
2618
  function routeLookup(route, lex, dyn) {
2636
2619
  for (let i = 0; i < route.length; i++) {
2637
2620
  const leg = route[i];
@@ -2753,20 +2736,6 @@ var Stack = class _Stack {
2753
2736
  lookupBind(name) {
2754
2737
  return lookup(this.binds, name);
2755
2738
  }
2756
- // The `lex` leg: what a name means in the registration scope of the component being
2757
- // rendered. The scope chain holds components, so this leg only ever answers for a
2758
- // type name — for a value name it is a miss, which is why one default route serves
2759
- // both. Guarded: a non-component `it` has no scope to ask.
2760
- _lookupLex(name) {
2761
- return this.comps.getCompFor(this.it)?.scope.lookupComponent(name) ?? null;
2762
- }
2763
- lookupRouted(name, route = DEFAULT_LOOKUP_ROUTE) {
2764
- return routeLookup(
2765
- route,
2766
- () => this._lookupLex(name),
2767
- () => this.lookupDynamic(name)
2768
- );
2769
- }
2770
2739
  lookupFieldRaw(name) {
2771
2740
  return this.it[name] ?? null;
2772
2741
  }
@@ -2799,34 +2768,16 @@ var Stack = class _Stack {
2799
2768
  // src/oo.js
2800
2769
  var BAD_VALUE = /* @__PURE__ */ Symbol("BadValue");
2801
2770
  var nullCoercer = (v) => v;
2802
- function defaultToData(v) {
2803
- if (v instanceof Map) return [...v.entries()];
2804
- if (v instanceof Set) return [...v.values()];
2805
- return v;
2806
- }
2807
2771
  var Field = class {
2808
2772
  constructor(type, name, typeCheck, coercer, defaultValue = null) {
2809
2773
  this.type = type;
2810
2774
  this.name = name;
2811
2775
  this.typeCheck = typeCheck;
2812
2776
  this.coercer = coercer;
2813
- this.checks = [];
2814
2777
  this.defaultValue = defaultValue;
2815
2778
  }
2816
- toDataDef() {
2817
- return { type: this.type, defaultValue: defaultToData(this.defaultValue) };
2818
- }
2819
- getFirstFailingCheck(v) {
2820
- if (!this.typeCheck.isValid(v)) return this.typeCheck;
2821
- for (const check3 of this.checks) if (!check3.isValid(v)) return check3;
2822
- return null;
2823
- }
2824
2779
  isValid(v) {
2825
- return this.getFirstFailingCheck(v) === null;
2826
- }
2827
- addCheck(check3) {
2828
- this.checks.push(check3);
2829
- return this;
2780
+ return this.typeCheck(v);
2830
2781
  }
2831
2782
  coerceOr(v, defaultValue = null) {
2832
2783
  if (this.isValid(v)) return v;
@@ -2837,39 +2788,15 @@ var Field = class {
2837
2788
  return this.coerceOr(v, this.defaultValue);
2838
2789
  }
2839
2790
  };
2840
- var Check = class {
2841
- isValid(_v) {
2842
- return true;
2843
- }
2844
- getMessage(_v) {
2845
- return "Invalid";
2846
- }
2847
- };
2848
- var CheckTypeAny = class extends Check {
2849
- };
2850
- var CHECK_TYPE_ANY = new CheckTypeAny();
2851
- var FnCheck = class extends Check {
2852
- constructor(isValidFn, getMessageFn) {
2853
- super();
2854
- this._isValid = isValidFn;
2855
- this._getMessage = getMessageFn;
2856
- }
2857
- isValid(v) {
2858
- return this._isValid(v);
2859
- }
2860
- getMessage(v) {
2861
- return this._getMessage(v);
2862
- }
2863
- };
2864
- var check = (fn, message) => new FnCheck(fn, () => message);
2865
- var CHECK_TYPE_INT = check(Number.isInteger, "Integer expected");
2866
- var CHECK_TYPE_FLOAT = check(Number.isFinite, "Float expected");
2867
- var CHECK_TYPE_BOOL = check((v) => typeof v === "boolean", "Boolean expected");
2868
- var CHECK_TYPE_STRING = check((v) => typeof v === "string", "String expected");
2869
- var CHECK_TYPE_LIST = check(Array.isArray, "Array expected");
2870
- var CHECK_TYPE_OBJECT = check(isPlainObject, "Plain object expected");
2871
- var CHECK_TYPE_MAP = check((v) => v instanceof Map, "Map expected");
2872
- var CHECK_TYPE_SET = check((v) => v instanceof Set, "Set expected");
2791
+ var CHECK_TYPE_ANY = (_v) => true;
2792
+ var CHECK_TYPE_INT = Number.isInteger;
2793
+ var CHECK_TYPE_FLOAT = Number.isFinite;
2794
+ var CHECK_TYPE_BOOL = (v) => typeof v === "boolean";
2795
+ var CHECK_TYPE_STRING = (v) => typeof v === "string";
2796
+ var CHECK_TYPE_LIST = Array.isArray;
2797
+ var CHECK_TYPE_OBJECT = isPlainObject;
2798
+ var CHECK_TYPE_MAP = (v) => v instanceof Map;
2799
+ var CHECK_TYPE_SET = (v) => v instanceof Set;
2873
2800
  var FieldBool = class extends Field {
2874
2801
  constructor(name, defaultValue = false) {
2875
2802
  super("bool", name, CHECK_TYPE_BOOL, (v) => !!v, defaultValue);
@@ -2879,9 +2806,6 @@ var FieldAny = class extends Field {
2879
2806
  constructor(name, defaultValue = null) {
2880
2807
  super("any", name, CHECK_TYPE_ANY, nullCoercer, defaultValue);
2881
2808
  }
2882
- toDataDef() {
2883
- return { type: getTypeName(this.defaultValue) ?? "any", defaultValue: this.defaultValue };
2884
- }
2885
2809
  };
2886
2810
  var FieldString = class extends Field {
2887
2811
  constructor(name, defaultValue = "") {
@@ -2904,26 +2828,13 @@ var FieldFloat = class extends Field {
2904
2828
  super("float", name, CHECK_TYPE_FLOAT, (_) => null, defaultValue);
2905
2829
  }
2906
2830
  };
2907
- var getTypeName = (v) => v?.constructor?.[COMPONENT]?.name ?? v?.constructor?.getMetaClass?.()?.name ?? null;
2908
- var CheckTypeName = class {
2909
- constructor(typeName) {
2910
- this.typeName = typeName;
2911
- }
2912
- isValid(v) {
2913
- return getTypeName(v) === this.typeName;
2914
- }
2915
- getMessage(v) {
2916
- return `Expected "${this.typeName}", got "${getTypeName(v)}"`;
2917
- }
2918
- };
2831
+ var metaOf = (v) => v?.constructor?.[COMPONENT] ?? v?.constructor?.getMetaClass?.();
2832
+ var getTypeName = (v) => metaOf(v)?.name ?? null;
2919
2833
  var FieldComp = class extends Field {
2920
2834
  constructor(type, name, args) {
2921
- super(type, name, new CheckTypeName(type), nullCoercer, null);
2835
+ super(type, name, (v) => getTypeName(v) === type, nullCoercer, null);
2922
2836
  this.args = args;
2923
2837
  }
2924
- toDataDef() {
2925
- return { component: this.type, args: this.args };
2926
- }
2927
2838
  };
2928
2839
  var FieldList = class extends Field {
2929
2840
  constructor(name, defaultValue = []) {
@@ -3085,7 +2996,7 @@ function classFromData(name, { fields = {}, methods, statics }) {
3085
2996
  return b.build();
3086
2997
  }
3087
2998
  function validateDraftFields(current, draft) {
3088
- const meta = current?.constructor?.[COMPONENT] ?? current?.constructor?.getMetaClass?.();
2999
+ const meta = metaOf(current);
3089
3000
  if (!meta) return;
3090
3001
  for (const [name, field] of Object.entries(meta.fields)) {
3091
3002
  const value = draft[name];
@@ -3212,28 +3123,46 @@ var Transactor = class {
3212
3123
  if (i !== -1) this._refusalObservers.splice(i, 1);
3213
3124
  };
3214
3125
  }
3215
- // Build and dispatch the observer record for a settled transaction. The
3216
- // resolved handler (`_resolvedHandler`/`_matched`) and per-leaf before/after
3217
- // (`_before`/`_after`) were captured while the handler ran (see callHandler /
3218
- // Transaction.run). No-op when nobody is observing.
3126
+ // Build and dispatch one observer record. Pins field-resolved keys (e.g. a
3127
+ // `.a[.selId]` render target reconstructed from a DOM event) against the root the
3128
+ // handler read, so pathKeys carries concrete keys instead of dropping the dynamic
3129
+ // step. No-op when nobody is observing.
3130
+ _emitRecord(root, { kind, name, args, path, targetPath, handler, handlerName, matched, before, after, parent }) {
3131
+ if (this._observers.length === 0) return;
3132
+ const pinned = path.pinKeys(root);
3133
+ this._emit({
3134
+ kind,
3135
+ name,
3136
+ args: args ?? null,
3137
+ path: pinned,
3138
+ pathKeys: pinned.toKeys(),
3139
+ targetPath,
3140
+ handler: handler ?? null,
3141
+ handlerName: handlerName ?? (handler?.name || null),
3142
+ matched: matched ?? null,
3143
+ before,
3144
+ after,
3145
+ parent,
3146
+ timestamp: Date.now()
3147
+ });
3148
+ }
3149
+ // The observer record for a settled transaction. The resolved handler
3150
+ // (`_resolvedHandler`/`_matched`) and per-leaf before/after (`_before`/`_after`)
3151
+ // were captured while the handler ran (see callHandler / Transaction.run).
3219
3152
  _emitTransaction(transaction, root) {
3220
3153
  if (this._observers.length === 0) return;
3221
3154
  if (transaction._resolvedHandler === void 0) return;
3222
- const path = transaction.getTransactionPath().pinKeys(root);
3223
- this._emit({
3155
+ this._emitRecord(root, {
3224
3156
  kind: transaction.observeKind,
3225
3157
  name: transaction.observeName,
3226
- args: transaction.args ?? null,
3227
- path,
3228
- pathKeys: path.toKeys(),
3158
+ args: transaction.args,
3159
+ path: transaction.getTransactionPath(),
3229
3160
  targetPath: transaction.targetPath ?? transaction.path,
3230
- handler: transaction._resolvedHandler ?? null,
3231
- handlerName: transaction._resolvedHandler?.name || null,
3232
- matched: transaction._matched ?? null,
3161
+ handler: transaction._resolvedHandler,
3162
+ matched: transaction._matched,
3233
3163
  before: transaction._before,
3234
3164
  after: transaction._after,
3235
- parent: transaction.parentTransaction,
3236
- timestamp: Date.now()
3165
+ parent: transaction.parentTransaction
3237
3166
  });
3238
3167
  }
3239
3168
  // Make `child` a tracked unit of `parent`'s subtree: the parent's completion stays open
@@ -3331,7 +3260,7 @@ var Transaction = class {
3331
3260
  // rather than throwing, so a stray call from the wrong place is a message and not a
3332
3261
  // crash. `walk` is undefined here, which is how ctx.reply/ctx.fail tell the two apart.
3333
3262
  stop() {
3334
- console.warn('ctx.stop() is only meaningful in an "intent" handler - ignored');
3263
+ warnNotIntent("stop");
3335
3264
  }
3336
3265
  forward(_opts) {
3337
3266
  console.warn('ctx.forward() needs a "receive" or "intent" handler - ignored');
@@ -3416,11 +3345,8 @@ var InputEvent = class extends Transaction {
3416
3345
  }
3417
3346
  this.transactor.pushIntent(this.dispatchPath, name, args, rest, this);
3418
3347
  }
3419
- buildStack(root, comps) {
3420
- return this.path.toTransactionPath().buildStack(Stack.root(comps, root, this));
3421
- }
3422
3348
  getHandlerAndArgs(root, _instance, comps) {
3423
- const stack = this.buildStack(root, comps);
3349
+ const stack = this.path.toTransactionPath().buildStack(Stack.root(comps, root, this));
3424
3350
  const [handler, args] = this.handler.getHandlerAndArgs(stack, this);
3425
3351
  this._handlerArgs = [...args];
3426
3352
  const path = this.dispatchPath;
@@ -3522,7 +3448,6 @@ var IntentEvent = class extends NameArgsTransaction {
3522
3448
  };
3523
3449
  var PASS = /* @__PURE__ */ Symbol.for("tutuca.intent.pass");
3524
3450
  var REFUSAL_RING_CAP = 200;
3525
- var DEFAULT_ROUTE = ["dyn", "lex"];
3526
3451
  var INTENT_DEPTH = 64;
3527
3452
  var IntentWalk = class {
3528
3453
  constructor(transactor, path, name, args, opts, parent, release) {
@@ -3571,24 +3496,19 @@ var IntentWalk = class {
3571
3496
  const txnPath = this.origin.toTransactionPath();
3572
3497
  const leaf = txnPath.lookup(root);
3573
3498
  const chain = this.transactor.comps.getIntentChainFor(leaf, this.name);
3574
- if (this.transactor._observers.length > 0) {
3575
- const path = txnPath.pinKeys(root);
3576
- this.transactor._emit({
3577
- kind: "intent",
3578
- name: this.name,
3579
- args: this.args,
3580
- path,
3581
- pathKeys: path.toKeys(),
3582
- targetPath: this.origin,
3583
- handler: chain[0]?.fn ?? null,
3584
- handlerName: chain[0]?.fn?.name || this.name,
3585
- matched: chain.length > 0 ? "exact" : "none",
3586
- before: leaf,
3587
- after: void 0,
3588
- parent: this.parent,
3589
- timestamp: Date.now()
3590
- });
3591
- }
3499
+ this.transactor._emitRecord(root, {
3500
+ kind: "intent",
3501
+ name: this.name,
3502
+ args: this.args,
3503
+ path: txnPath,
3504
+ targetPath: this.origin,
3505
+ handler: chain[0],
3506
+ handlerName: chain[0]?.name || this.name,
3507
+ matched: chain.length > 0 ? "exact" : "none",
3508
+ before: leaf,
3509
+ after: void 0,
3510
+ parent: this.parent
3511
+ });
3592
3512
  if (chain.length === 0) return this.advance();
3593
3513
  const p = this._runLex(chain, 0);
3594
3514
  this.transactor._inflight.add(p);
@@ -3599,7 +3519,7 @@ var IntentWalk = class {
3599
3519
  if (i >= chain.length) return this.advance();
3600
3520
  const ctx = new Dispatcher(this.origin, this.transactor, this.parent);
3601
3521
  try {
3602
- const res = await chain[i].fn.apply(null, [...this.args, ctx]);
3522
+ const res = await chain[i].apply(null, [...this.args, ctx]);
3603
3523
  if (res === PASS) return this._runLex(chain, i + 1);
3604
3524
  this.answer("Ok", res);
3605
3525
  } catch (error) {
@@ -3752,9 +3672,8 @@ var Dispatcher = class {
3752
3672
  // the same spelling as `ctx.intent` — `["dyn"]` the render ancestry, `["lex"]` the
3753
3673
  // registration scope, default both.
3754
3674
  lookup(name, opts) {
3755
- const route = opts?.route ?? DEFAULT_LOOKUP_ROUTE;
3756
3675
  return routeLookup(
3757
- route,
3676
+ opts?.route ?? DEFAULT_ROUTE,
3758
3677
  () => this._lookupLex(name),
3759
3678
  () => this._stack()?.lookupDynamic(name) ?? null
3760
3679
  );
@@ -3773,12 +3692,10 @@ var Dispatcher = class {
3773
3692
  // can only ever answer with one; the `dyn` leg reads a binding an ancestor
3774
3693
  // published, so it is the leg that has to be checked.
3775
3694
  lookupType(name, opts) {
3776
- const v = this.lookup(name, opts);
3695
+ const route = opts?.route ?? DEFAULT_ROUTE;
3696
+ const v = this.lookup(name, { route });
3777
3697
  if (v == null) {
3778
- this.transactor.refuse("TYPE_NOT_FOUND", {
3779
- name,
3780
- route: opts?.route ?? DEFAULT_LOOKUP_ROUTE
3781
- });
3698
+ this.transactor.refuse("TYPE_NOT_FOUND", { name, route });
3782
3699
  return null;
3783
3700
  }
3784
3701
  if (v?.[COMPONENT] == null) {
@@ -3903,7 +3820,14 @@ var App = class {
3903
3820
  const { type } = e;
3904
3821
  const isDrag = type === "dragover" || type === "dragstart" || type === "dragend" || type === "drop";
3905
3822
  const { rootNode: root, maxEventNodeDepth: maxDepth, comps, transactor } = this;
3906
- const [path, handlers] = Path.fromEvent(e, root, maxDepth, comps, !isDrag);
3823
+ const [path, handlers] = Path.fromNodeAndEventName(
3824
+ e.target,
3825
+ type,
3826
+ root,
3827
+ maxDepth,
3828
+ comps,
3829
+ !isDrag
3830
+ );
3907
3831
  if (isDrag) this._handleDragEvent(e, type, path);
3908
3832
  if (path !== null && handlers !== null)
3909
3833
  for (const handler of handlers) transactor.transactInputNow(path, e, handler, this.dragInfo);
@@ -3965,7 +3889,7 @@ var App = class {
3965
3889
  const value = txnPath.lookup(rootValue);
3966
3890
  const dragType = e.target.dataset.dragtype ?? "?";
3967
3891
  const stack = path.toTransactionPath().buildStack(this.makeStack(rootValue));
3968
- this.dragInfo = new DragInfo(txnPath, stack, e, value, dragType, e.target);
3892
+ this.dragInfo = new DragInfo(stack, value, dragType, e.target);
3969
3893
  } else if (type === "drop") {
3970
3894
  e.preventDefault();
3971
3895
  this._cleanDragOverAttrs();
@@ -4102,10 +4026,8 @@ function getClosestDropTarget(target, rootNode, count) {
4102
4026
  return null;
4103
4027
  }
4104
4028
  var DragInfo = class {
4105
- constructor(path, stack, e, val, type, node) {
4106
- this.path = path;
4029
+ constructor(stack, val, type, node) {
4107
4030
  this.stack = stack;
4108
- this.e = e;
4109
4031
  this.val = val;
4110
4032
  this.type = type;
4111
4033
  this.node = node;
@@ -4275,6 +4197,8 @@ var Renderer = class {
4275
4197
  setNullCache() {
4276
4198
  this.cache = new NullDomCache();
4277
4199
  }
4200
+ // Library utilities for consumers embedding tutuca: render a value to a detached
4201
+ // DOM node / an HTML string. Not called by the framework itself.
4278
4202
  renderToDOM(stack, val) {
4279
4203
  const rootNode = document.createElement("div");
4280
4204
  const rOpts = { document };
@@ -4399,7 +4323,7 @@ function dispatchPhase(dispatcher, targetPath, phase, self) {
4399
4323
  var css = String.raw;
4400
4324
  var html = String.raw;
4401
4325
  var macro = (defaults, rawView) => new Macro(defaults, rawView);
4402
- function check2(_app) {
4326
+ function check(_app) {
4403
4327
  return { error: 0, warn: 0, hint: 0, dummyCheck: true };
4404
4328
  }
4405
4329
  async function test(_opts) {
@@ -4437,7 +4361,7 @@ export {
4437
4361
  PASS,
4438
4362
  ParseContext,
4439
4363
  SEQ_INFO,
4440
- check2 as check,
4364
+ check,
4441
4365
  collectIterBindings,
4442
4366
  compileClassesToStyle,
4443
4367
  compileClassesToStyleText,