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.
@@ -4967,11 +4967,6 @@ var writeKey = (value, key, next) => {
4967
4967
  value.add(next);
4968
4968
  } else value[key] = next;
4969
4969
  };
4970
- var readSeqKey = (value, key, dval = null) => {
4971
- const direct = readKey(value, key, NONE);
4972
- if (direct !== NONE) return direct;
4973
- return typeof value?.get === "function" ? value.get(key, dval) : dval;
4974
- };
4975
4970
  var writeSeqKey = (value, key, next) => {
4976
4971
  if (value instanceof Map || value instanceof Set || Array.isArray(value) || Object.hasOwn(value, key))
4977
4972
  writeKey(value, key, next);
@@ -4984,7 +4979,7 @@ var Step = class {
4984
4979
  }
4985
4980
  setDraftValue(_root, _v) {
4986
4981
  }
4987
- enterFrame(stack, _prev, next) {
4982
+ enterFrame(stack, next) {
4988
4983
  return stack.enter(next, {}, true);
4989
4984
  }
4990
4985
  toAbstractPathStep() {
@@ -5010,7 +5005,7 @@ var BindStep = class _BindStep extends Step {
5010
5005
  lookup(v, _dval) {
5011
5006
  return v;
5012
5007
  }
5013
- enterFrame(stack, _prev, next) {
5008
+ enterFrame(stack, next) {
5014
5009
  return stack.enter(next, { ...this.binds }, false);
5015
5010
  }
5016
5011
  withIndex(i) {
@@ -5028,7 +5023,7 @@ var ScopeBindStep = class _ScopeBindStep extends BindStep {
5028
5023
  super(binds);
5029
5024
  this.val = val;
5030
5025
  }
5031
- enterFrame(stack, _prev, next) {
5026
+ enterFrame(stack, next) {
5032
5027
  const dyn = this.val.evalAsHandler(stack)?.call(stack.it) ?? {};
5033
5028
  return stack.enter(next, { ...this.binds, ...dyn }, false);
5034
5029
  }
@@ -5067,13 +5062,13 @@ var SeqStep = class extends Step {
5067
5062
  this.key = key;
5068
5063
  }
5069
5064
  lookup(v, dval = null) {
5070
- return readSeqKey(readKey(v, this.field, null), this.key, dval);
5065
+ return seqGet(readKey(v, this.field, null), this.key, dval);
5071
5066
  }
5072
5067
  setDraftValue(root, v) {
5073
5068
  const seq = readKey(root, this.field, null);
5074
5069
  if (seq != null) writeSeqKey(seq, this.key, v);
5075
5070
  }
5076
- enterFrame(stack, _prev, next) {
5071
+ enterFrame(stack, next) {
5077
5072
  return stack.enter(next, { key: this.key }, true);
5078
5073
  }
5079
5074
  toKey() {
@@ -5089,7 +5084,7 @@ var SeqAccessStep = class extends Step {
5089
5084
  lookup(v, dval = null) {
5090
5085
  const seq = readKey(v, this.seqField, NONE);
5091
5086
  const key = readKey(v, this.keyField, NONE);
5092
- return key !== NONE && seq !== NONE ? readSeqKey(seq, key, dval) : dval;
5087
+ return key !== NONE && seq !== NONE ? seqGet(seq, key, dval) : dval;
5093
5088
  }
5094
5089
  setDraftValue(root, v) {
5095
5090
  const seq = readKey(root, this.seqField, NONE);
@@ -5120,7 +5115,7 @@ var EachBindStep = class extends Step {
5120
5115
  }
5121
5116
  // Replay the renderer's per-item binds (key, value + any @enrich-with binds)
5122
5117
  // so a rebuilt stack matches the one @each rendered with.
5123
- enterFrame(stack, _prev, next) {
5118
+ enterFrame(stack, next) {
5124
5119
  return stack.enter(next, this.iterInfo.enrichBinds(stack, this.key), false);
5125
5120
  }
5126
5121
  toAbstractPathStep() {
@@ -5128,7 +5123,7 @@ var EachBindStep = class extends Step {
5128
5123
  }
5129
5124
  };
5130
5125
  var EachRenderItStep = class extends SeqStep {
5131
- enterFrame(stack, _prev, next) {
5126
+ enterFrame(stack, next) {
5132
5127
  return stack.enter(next, { key: this.key, value: next }, false).enter(next, {}, true);
5133
5128
  }
5134
5129
  toAbstractPathStep() {
@@ -5153,7 +5148,7 @@ var DynStep = class extends Step {
5153
5148
  warnRawDynStep("lookup", this);
5154
5149
  return dval;
5155
5150
  }
5156
- enterFrame(stack, _prev, _next) {
5151
+ enterFrame(stack, _next) {
5157
5152
  warnRawDynStep("enterFrame", this);
5158
5153
  return stack;
5159
5154
  }
@@ -5291,7 +5286,7 @@ var Path = class _Path {
5291
5286
  console.warn("bad PathItem", { root: stack.it, step, path: this });
5292
5287
  return null;
5293
5288
  }
5294
- stack = step.enterFrame(stack, prev, next);
5289
+ stack = step.enterFrame(stack, next);
5295
5290
  prev = next;
5296
5291
  }
5297
5292
  return stack;
@@ -5361,10 +5356,6 @@ var Path = class _Path {
5361
5356
  console.warn("event reconstruction: dynamic-var producer not found", pendingDyns);
5362
5357
  return [new _Path(pathSteps.reverse()), handlers];
5363
5358
  }
5364
- static fromEvent(e, rNode, maxDepth, comps, stopOnNoEvent = true) {
5365
- const { type: type3, target } = e;
5366
- return _Path.fromNodeAndEventName(target, type3, rNode, maxDepth, comps, stopOnNoEvent);
5367
- }
5368
5359
  };
5369
5360
  function metaChain(n) {
5370
5361
  const out = [];
@@ -5924,7 +5915,7 @@ var Attributes = class {
5924
5915
  this.items = items;
5925
5916
  }
5926
5917
  static parse(attributes, px, parseAll = false) {
5927
- return getAttrParser(px).parse(attributes, parseAll);
5918
+ return new AttrParser(px).parse(attributes, parseAll);
5928
5919
  }
5929
5920
  isConstant() {
5930
5921
  return false;
@@ -6170,9 +6161,6 @@ var IfAttr = class extends BaseAttr {
6170
6161
  return this.condVal.eval(stack) ? this.thenVal.eval(stack) : this.elseVal.eval(stack);
6171
6162
  }
6172
6163
  };
6173
- function getAttrParser(px) {
6174
- return new AttrParser(px);
6175
- }
6176
6164
  var EventHandler = class _EventHandler {
6177
6165
  constructor(handlerVal, args = []) {
6178
6166
  this.handlerVal = handlerVal;
@@ -6188,12 +6176,6 @@ var EventHandler = class _EventHandler {
6188
6176
  return r === null ? null : new _EventHandler(r.handlerVal, r.args);
6189
6177
  }
6190
6178
  };
6191
- var IntentHandler = class {
6192
- constructor(name, fn) {
6193
- this.name = name;
6194
- this.fn = fn;
6195
- }
6196
- };
6197
6179
 
6198
6180
  // src/iteration.js
6199
6181
  var SEQ_INFO = /* @__PURE__ */ Symbol.for("tutuca.seqInfo");
@@ -6244,6 +6226,15 @@ var callEnricher = (enricher, it, binds, key, value, iterData) => {
6244
6226
  binds.key = key;
6245
6227
  binds.value = value;
6246
6228
  };
6229
+ function bindsForKey({ seq, it, loopWith, enricher, ctx }, key) {
6230
+ const value = seqGet(seq, key, null);
6231
+ const binds = { key, value };
6232
+ if (enricher) {
6233
+ const { iterData } = unpackLoopResult(loopWith.call(it, seq, ctx), seq);
6234
+ callEnricher(enricher, it, binds, key, value, iterData);
6235
+ }
6236
+ return binds;
6237
+ }
6247
6238
  var visitKeys = (seq, keys, visit) => {
6248
6239
  const attrName = isIndexedSeq(seq) ? "si" : "sk";
6249
6240
  for (const key of keys) visit(key, seqGet(seq, key), attrName);
@@ -7088,20 +7079,11 @@ var IterInfo = class {
7088
7079
  const enricher = this.enrichWithVal?.evalAsHandler(stack) ?? null;
7089
7080
  return { seq, filter, loopWith, enricher };
7090
7081
  }
7091
- // Rebuild the per-item binds for `key`, mirroring renderEachWhen: seed
7092
- // { key, value }, then run @enrich-with (with @loop-with's iterData) if any.
7082
+ // Rebuild the per-item binds for `key` (see iteration.js bindsForKey).
7093
7083
  enrichBinds(stack, key) {
7094
7084
  const { seq, filter, loopWith, enricher } = this.eval(stack);
7095
- const value = seqGet(seq, key, null);
7096
- const binds = { key, value };
7097
- if (enricher) {
7098
- const { iterData } = unpackLoopResult(
7099
- loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)),
7100
- seq
7101
- );
7102
- callEnricher(enricher, stack.it, binds, key, value, iterData);
7103
- }
7104
- return binds;
7085
+ const ctx = makeLoopCtx(stack, filter);
7086
+ return bindsForKey({ seq, it: stack.it, loopWith, enricher, ctx }, key);
7105
7087
  }
7106
7088
  };
7107
7089
  function xOp(consumed = [], { wrappable = false, wrapper = null, ignoresChildren = false } = {}) {
@@ -7297,10 +7279,11 @@ var NodeEvent = class {
7297
7279
  }
7298
7280
  };
7299
7281
  var fwdIfCtxPred = (pred) => (w) => (that, f, args, ctx) => pred(ctx) ? w(that, f, args, ctx) : that;
7300
- var fwdIfKey = (keyName) => fwdIfCtxPred((ctx) => ctx.e.key === keyName);
7301
- var fwdCtrl = fwdIfCtxPred(({ e }) => isMac && e.metaKey || e.ctrlKey);
7302
- var fwdMeta = fwdIfCtxPred(({ e }) => e.metaKey);
7303
- var fwdAlt = fwdIfCtxPred(({ e }) => e.altKey);
7282
+ var fwdIfEventPred = (pred) => fwdIfCtxPred(({ e }) => pred(e));
7283
+ var fwdIfKey = (keyName) => fwdIfEventPred(keyIs(keyName));
7284
+ var fwdCtrl = fwdIfEventPred(macCtrl);
7285
+ var fwdMeta = fwdIfEventPred((e) => e.metaKey);
7286
+ var fwdAlt = fwdIfEventPred((e) => e.altKey);
7304
7287
  var MOD_WRAPPERS_FOR_ANY_EVENT = {
7305
7288
  ctrl: fwdCtrl,
7306
7289
  cmd: fwdCtrl,
@@ -7485,13 +7468,15 @@ var ComponentStack = class _ComponentStack {
7485
7468
  getCompFor(v) {
7486
7469
  return this.comps.getCompFor(v);
7487
7470
  }
7488
- // Handlers that answer an intent's `lex` leg. A name maps to a LIST, because the leg
7489
- // walks: a handler that returns PASS declines and hands the intent to the next one.
7490
- // A bare function is accepted as a one-element list.
7471
+ // Handlers that answer an intent's `lex` leg. A name maps to a LIST of plain
7472
+ // functions, because the leg walks: a handler that returns PASS declines and hands
7473
+ // the intent to the next one. Each runs with no `this` and takes a dispatcher
7474
+ // context as its final argument; resolving answers, throwing fails. A bare function
7475
+ // is accepted as a one-element list.
7491
7476
  registerIntentHandlers(handlers) {
7492
7477
  for (const name in handlers) {
7493
- const fns = Array.isArray(handlers[name]) ? handlers[name] : [handlers[name]];
7494
- this.intentsByName[name] = fns.map((fn) => new IntentHandler(name, fn));
7478
+ const fns = handlers[name];
7479
+ this.intentsByName[name] = Array.isArray(fns) ? fns : [fns];
7495
7480
  }
7496
7481
  }
7497
7482
  // Innermost scope first, then outward. Concatenated rather than first-match, so a
@@ -7521,14 +7506,12 @@ var ComponentStack = class _ComponentStack {
7521
7506
  }
7522
7507
  };
7523
7508
  var ProvideInfo = class {
7524
- constructor(name, val) {
7525
- this.name = name;
7509
+ constructor(val) {
7526
7510
  this.val = val;
7527
7511
  }
7528
7512
  };
7529
7513
  var LookupInfo = class {
7530
- constructor(name, val) {
7531
- this.name = name;
7514
+ constructor(val) {
7532
7515
  this.val = val;
7533
7516
  }
7534
7517
  };
@@ -7576,13 +7559,13 @@ var Component = class {
7576
7559
  continue;
7577
7560
  }
7578
7561
  const val = parseProvide(this._rawProvide[key], ctx);
7579
- if (val) this.provide[key] = new ProvideInfo(key, val);
7562
+ if (val) this.provide[key] = new ProvideInfo(val);
7580
7563
  }
7581
7564
  for (const entry of this._rawLookup) {
7582
7565
  const name = isString(entry) ? entry : isString(entry?.name) ? entry.name : null;
7583
7566
  if (name === null) continue;
7584
7567
  const defStr = isString(entry?.default) ? entry.default : null;
7585
- this.lookup[name] = new LookupInfo(name, defStr === null ? null : parseField(defStr, ctx));
7568
+ this.lookup[name] = new LookupInfo(defStr === null ? null : parseField(defStr, ctx));
7586
7569
  }
7587
7570
  for (const key in this.lookup)
7588
7571
  if (this.provide[key] !== void 0)
@@ -10405,10 +10388,10 @@ var ATTR_VAL_CHECKERS = {
10405
10388
  }
10406
10389
  };
10407
10390
  function checkConsistentAttrVal(lx, val, env, skipNameVal = false, errCtx = null, isRoot = true) {
10408
- const check3 = ATTR_VAL_CHECKERS[val?.constructor.name];
10409
- if (check3 === void 0) return;
10391
+ const check2 = ATTR_VAL_CHECKERS[val?.constructor.name];
10392
+ if (check2 === void 0) return;
10410
10393
  const recurse = (sub) => checkConsistentAttrVal(lx, sub, env, skipNameVal, errCtx, false);
10411
- check3({ lx, val, env, errCtx, skipNameVal, recurse, isRoot });
10394
+ check2({ lx, val, env, errCtx, skipNameVal, recurse, isRoot });
10412
10395
  }
10413
10396
  var NODE_KIND_TO_CTX = {
10414
10397
  RenderTextNode: { originAttr: "<x text>" },
@@ -10854,34 +10837,16 @@ function dispatchPhase(dispatcher, targetPath, phase, self) {
10854
10837
  // src/oo.js
10855
10838
  var BAD_VALUE2 = /* @__PURE__ */ Symbol("BadValue");
10856
10839
  var nullCoercer = (v) => v;
10857
- function defaultToData(v) {
10858
- if (v instanceof Map) return [...v.entries()];
10859
- if (v instanceof Set) return [...v.values()];
10860
- return v;
10861
- }
10862
10840
  var Field = class {
10863
10841
  constructor(type3, name, typeCheck, coercer, defaultValue = null) {
10864
10842
  this.type = type3;
10865
10843
  this.name = name;
10866
10844
  this.typeCheck = typeCheck;
10867
10845
  this.coercer = coercer;
10868
- this.checks = [];
10869
10846
  this.defaultValue = defaultValue;
10870
10847
  }
10871
- toDataDef() {
10872
- return { type: this.type, defaultValue: defaultToData(this.defaultValue) };
10873
- }
10874
- getFirstFailingCheck(v) {
10875
- if (!this.typeCheck.isValid(v)) return this.typeCheck;
10876
- for (const check3 of this.checks) if (!check3.isValid(v)) return check3;
10877
- return null;
10878
- }
10879
10848
  isValid(v) {
10880
- return this.getFirstFailingCheck(v) === null;
10881
- }
10882
- addCheck(check3) {
10883
- this.checks.push(check3);
10884
- return this;
10849
+ return this.typeCheck(v);
10885
10850
  }
10886
10851
  coerceOr(v, defaultValue = null) {
10887
10852
  if (this.isValid(v)) return v;
@@ -10892,39 +10857,15 @@ var Field = class {
10892
10857
  return this.coerceOr(v, this.defaultValue);
10893
10858
  }
10894
10859
  };
10895
- var Check = class {
10896
- isValid(_v) {
10897
- return true;
10898
- }
10899
- getMessage(_v) {
10900
- return "Invalid";
10901
- }
10902
- };
10903
- var CheckTypeAny = class extends Check {
10904
- };
10905
- var CHECK_TYPE_ANY = new CheckTypeAny();
10906
- var FnCheck = class extends Check {
10907
- constructor(isValidFn, getMessageFn) {
10908
- super();
10909
- this._isValid = isValidFn;
10910
- this._getMessage = getMessageFn;
10911
- }
10912
- isValid(v) {
10913
- return this._isValid(v);
10914
- }
10915
- getMessage(v) {
10916
- return this._getMessage(v);
10917
- }
10918
- };
10919
- var check = (fn, message) => new FnCheck(fn, () => message);
10920
- var CHECK_TYPE_INT = check(Number.isInteger, "Integer expected");
10921
- var CHECK_TYPE_FLOAT = check(Number.isFinite, "Float expected");
10922
- var CHECK_TYPE_BOOL = check((v) => typeof v === "boolean", "Boolean expected");
10923
- var CHECK_TYPE_STRING = check((v) => typeof v === "string", "String expected");
10924
- var CHECK_TYPE_LIST = check(Array.isArray, "Array expected");
10925
- var CHECK_TYPE_OBJECT = check(isPlainObject, "Plain object expected");
10926
- var CHECK_TYPE_MAP = check((v) => v instanceof Map, "Map expected");
10927
- var CHECK_TYPE_SET = check((v) => v instanceof Set, "Set expected");
10860
+ var CHECK_TYPE_ANY = (_v) => true;
10861
+ var CHECK_TYPE_INT = Number.isInteger;
10862
+ var CHECK_TYPE_FLOAT = Number.isFinite;
10863
+ var CHECK_TYPE_BOOL = (v) => typeof v === "boolean";
10864
+ var CHECK_TYPE_STRING = (v) => typeof v === "string";
10865
+ var CHECK_TYPE_LIST = Array.isArray;
10866
+ var CHECK_TYPE_OBJECT = isPlainObject;
10867
+ var CHECK_TYPE_MAP = (v) => v instanceof Map;
10868
+ var CHECK_TYPE_SET = (v) => v instanceof Set;
10928
10869
  var FieldBool = class extends Field {
10929
10870
  constructor(name, defaultValue = false) {
10930
10871
  super("bool", name, CHECK_TYPE_BOOL, (v) => !!v, defaultValue);
@@ -10934,9 +10875,6 @@ var FieldAny = class extends Field {
10934
10875
  constructor(name, defaultValue = null) {
10935
10876
  super("any", name, CHECK_TYPE_ANY, nullCoercer, defaultValue);
10936
10877
  }
10937
- toDataDef() {
10938
- return { type: getTypeName(this.defaultValue) ?? "any", defaultValue: this.defaultValue };
10939
- }
10940
10878
  };
10941
10879
  var FieldString = class extends Field {
10942
10880
  constructor(name, defaultValue = "") {
@@ -10959,26 +10897,13 @@ var FieldFloat = class extends Field {
10959
10897
  super("float", name, CHECK_TYPE_FLOAT, (_) => null, defaultValue);
10960
10898
  }
10961
10899
  };
10962
- var getTypeName = (v) => v?.constructor?.[COMPONENT]?.name ?? v?.constructor?.getMetaClass?.()?.name ?? null;
10963
- var CheckTypeName = class {
10964
- constructor(typeName) {
10965
- this.typeName = typeName;
10966
- }
10967
- isValid(v) {
10968
- return getTypeName(v) === this.typeName;
10969
- }
10970
- getMessage(v) {
10971
- return `Expected "${this.typeName}", got "${getTypeName(v)}"`;
10972
- }
10973
- };
10900
+ var metaOf = (v) => v?.constructor?.[COMPONENT] ?? v?.constructor?.getMetaClass?.();
10901
+ var getTypeName = (v) => metaOf(v)?.name ?? null;
10974
10902
  var FieldComp = class extends Field {
10975
10903
  constructor(type3, name, args) {
10976
- super(type3, name, new CheckTypeName(type3), nullCoercer, null);
10904
+ super(type3, name, (v) => getTypeName(v) === type3, nullCoercer, null);
10977
10905
  this.args = args;
10978
10906
  }
10979
- toDataDef() {
10980
- return { component: this.type, args: this.args };
10981
- }
10982
10907
  };
10983
10908
  var FieldList = class extends Field {
10984
10909
  constructor(name, defaultValue = []) {
@@ -11140,7 +11065,7 @@ function classFromData(name, { fields = {}, methods, statics }) {
11140
11065
  return b.build();
11141
11066
  }
11142
11067
  function validateDraftFields(current2, draft) {
11143
- const meta = current2?.constructor?.[COMPONENT] ?? current2?.constructor?.getMetaClass?.();
11068
+ const meta = metaOf(current2);
11144
11069
  if (!meta) return;
11145
11070
  for (const [name, field] of Object.entries(meta.fields)) {
11146
11071
  const value = draft[name];
@@ -11199,7 +11124,7 @@ var component = (opts) => Component.fromSpec(opts);
11199
11124
  // src/stack.js
11200
11125
  var STOP = /* @__PURE__ */ Symbol("STOP");
11201
11126
  var NEXT = /* @__PURE__ */ Symbol("NEXT");
11202
- var DEFAULT_LOOKUP_ROUTE = ["dyn", "lex"];
11127
+ var DEFAULT_ROUTE = ["dyn", "lex"];
11203
11128
  function routeLookup(route, lex, dyn) {
11204
11129
  for (let i = 0; i < route.length; i++) {
11205
11130
  const leg = route[i];
@@ -11321,20 +11246,6 @@ var Stack = class _Stack {
11321
11246
  lookupBind(name) {
11322
11247
  return lookup(this.binds, name);
11323
11248
  }
11324
- // The `lex` leg: what a name means in the registration scope of the component being
11325
- // rendered. The scope chain holds components, so this leg only ever answers for a
11326
- // type name — for a value name it is a miss, which is why one default route serves
11327
- // both. Guarded: a non-component `it` has no scope to ask.
11328
- _lookupLex(name) {
11329
- return this.comps.getCompFor(this.it)?.scope.lookupComponent(name) ?? null;
11330
- }
11331
- lookupRouted(name, route = DEFAULT_LOOKUP_ROUTE) {
11332
- return routeLookup(
11333
- route,
11334
- () => this._lookupLex(name),
11335
- () => this.lookupDynamic(name)
11336
- );
11337
- }
11338
11249
  lookupFieldRaw(name) {
11339
11250
  return this.it[name] ?? null;
11340
11251
  }
@@ -11435,28 +11346,46 @@ var Transactor = class {
11435
11346
  if (i !== -1) this._refusalObservers.splice(i, 1);
11436
11347
  };
11437
11348
  }
11438
- // Build and dispatch the observer record for a settled transaction. The
11439
- // resolved handler (`_resolvedHandler`/`_matched`) and per-leaf before/after
11440
- // (`_before`/`_after`) were captured while the handler ran (see callHandler /
11441
- // Transaction.run). No-op when nobody is observing.
11349
+ // Build and dispatch one observer record. Pins field-resolved keys (e.g. a
11350
+ // `.a[.selId]` render target reconstructed from a DOM event) against the root the
11351
+ // handler read, so pathKeys carries concrete keys instead of dropping the dynamic
11352
+ // step. No-op when nobody is observing.
11353
+ _emitRecord(root, { kind, name, args, path, targetPath, handler, handlerName, matched, before, after, parent }) {
11354
+ if (this._observers.length === 0) return;
11355
+ const pinned = path.pinKeys(root);
11356
+ this._emit({
11357
+ kind,
11358
+ name,
11359
+ args: args ?? null,
11360
+ path: pinned,
11361
+ pathKeys: pinned.toKeys(),
11362
+ targetPath,
11363
+ handler: handler ?? null,
11364
+ handlerName: handlerName ?? (handler?.name || null),
11365
+ matched: matched ?? null,
11366
+ before,
11367
+ after,
11368
+ parent,
11369
+ timestamp: Date.now()
11370
+ });
11371
+ }
11372
+ // The observer record for a settled transaction. The resolved handler
11373
+ // (`_resolvedHandler`/`_matched`) and per-leaf before/after (`_before`/`_after`)
11374
+ // were captured while the handler ran (see callHandler / Transaction.run).
11442
11375
  _emitTransaction(transaction, root) {
11443
11376
  if (this._observers.length === 0) return;
11444
11377
  if (transaction._resolvedHandler === void 0) return;
11445
- const path = transaction.getTransactionPath().pinKeys(root);
11446
- this._emit({
11378
+ this._emitRecord(root, {
11447
11379
  kind: transaction.observeKind,
11448
11380
  name: transaction.observeName,
11449
- args: transaction.args ?? null,
11450
- path,
11451
- pathKeys: path.toKeys(),
11381
+ args: transaction.args,
11382
+ path: transaction.getTransactionPath(),
11452
11383
  targetPath: transaction.targetPath ?? transaction.path,
11453
- handler: transaction._resolvedHandler ?? null,
11454
- handlerName: transaction._resolvedHandler?.name || null,
11455
- matched: transaction._matched ?? null,
11384
+ handler: transaction._resolvedHandler,
11385
+ matched: transaction._matched,
11456
11386
  before: transaction._before,
11457
11387
  after: transaction._after,
11458
- parent: transaction.parentTransaction,
11459
- timestamp: Date.now()
11388
+ parent: transaction.parentTransaction
11460
11389
  });
11461
11390
  }
11462
11391
  // Make `child` a tracked unit of `parent`'s subtree: the parent's completion stays open
@@ -11554,7 +11483,7 @@ var Transaction = class {
11554
11483
  // rather than throwing, so a stray call from the wrong place is a message and not a
11555
11484
  // crash. `walk` is undefined here, which is how ctx.reply/ctx.fail tell the two apart.
11556
11485
  stop() {
11557
- console.warn('ctx.stop() is only meaningful in an "intent" handler - ignored');
11486
+ warnNotIntent("stop");
11558
11487
  }
11559
11488
  forward(_opts) {
11560
11489
  console.warn('ctx.forward() needs a "receive" or "intent" handler - ignored');
@@ -11639,11 +11568,8 @@ var InputEvent = class extends Transaction {
11639
11568
  }
11640
11569
  this.transactor.pushIntent(this.dispatchPath, name, args, rest, this);
11641
11570
  }
11642
- buildStack(root, comps) {
11643
- return this.path.toTransactionPath().buildStack(Stack.root(comps, root, this));
11644
- }
11645
11571
  getHandlerAndArgs(root, _instance, comps) {
11646
- const stack = this.buildStack(root, comps);
11572
+ const stack = this.path.toTransactionPath().buildStack(Stack.root(comps, root, this));
11647
11573
  const [handler, args] = this.handler.getHandlerAndArgs(stack, this);
11648
11574
  this._handlerArgs = [...args];
11649
11575
  const path = this.dispatchPath;
@@ -11745,7 +11671,6 @@ var IntentEvent = class extends NameArgsTransaction {
11745
11671
  };
11746
11672
  var PASS = /* @__PURE__ */ Symbol.for("tutuca.intent.pass");
11747
11673
  var REFUSAL_RING_CAP = 200;
11748
- var DEFAULT_ROUTE = ["dyn", "lex"];
11749
11674
  var INTENT_DEPTH = 64;
11750
11675
  var IntentWalk = class {
11751
11676
  constructor(transactor, path, name, args, opts, parent, release) {
@@ -11794,24 +11719,19 @@ var IntentWalk = class {
11794
11719
  const txnPath = this.origin.toTransactionPath();
11795
11720
  const leaf = txnPath.lookup(root);
11796
11721
  const chain = this.transactor.comps.getIntentChainFor(leaf, this.name);
11797
- if (this.transactor._observers.length > 0) {
11798
- const path = txnPath.pinKeys(root);
11799
- this.transactor._emit({
11800
- kind: "intent",
11801
- name: this.name,
11802
- args: this.args,
11803
- path,
11804
- pathKeys: path.toKeys(),
11805
- targetPath: this.origin,
11806
- handler: chain[0]?.fn ?? null,
11807
- handlerName: chain[0]?.fn?.name || this.name,
11808
- matched: chain.length > 0 ? "exact" : "none",
11809
- before: leaf,
11810
- after: void 0,
11811
- parent: this.parent,
11812
- timestamp: Date.now()
11813
- });
11814
- }
11722
+ this.transactor._emitRecord(root, {
11723
+ kind: "intent",
11724
+ name: this.name,
11725
+ args: this.args,
11726
+ path: txnPath,
11727
+ targetPath: this.origin,
11728
+ handler: chain[0],
11729
+ handlerName: chain[0]?.name || this.name,
11730
+ matched: chain.length > 0 ? "exact" : "none",
11731
+ before: leaf,
11732
+ after: void 0,
11733
+ parent: this.parent
11734
+ });
11815
11735
  if (chain.length === 0) return this.advance();
11816
11736
  const p = this._runLex(chain, 0);
11817
11737
  this.transactor._inflight.add(p);
@@ -11822,7 +11742,7 @@ var IntentWalk = class {
11822
11742
  if (i >= chain.length) return this.advance();
11823
11743
  const ctx = new Dispatcher(this.origin, this.transactor, this.parent);
11824
11744
  try {
11825
- const res = await chain[i].fn.apply(null, [...this.args, ctx]);
11745
+ const res = await chain[i].apply(null, [...this.args, ctx]);
11826
11746
  if (res === PASS) return this._runLex(chain, i + 1);
11827
11747
  this.answer("Ok", res);
11828
11748
  } catch (error) {
@@ -11975,9 +11895,8 @@ var Dispatcher = class {
11975
11895
  // the same spelling as `ctx.intent` — `["dyn"]` the render ancestry, `["lex"]` the
11976
11896
  // registration scope, default both.
11977
11897
  lookup(name, opts) {
11978
- const route = opts?.route ?? DEFAULT_LOOKUP_ROUTE;
11979
11898
  return routeLookup(
11980
- route,
11899
+ opts?.route ?? DEFAULT_ROUTE,
11981
11900
  () => this._lookupLex(name),
11982
11901
  () => this._stack()?.lookupDynamic(name) ?? null
11983
11902
  );
@@ -11996,12 +11915,10 @@ var Dispatcher = class {
11996
11915
  // can only ever answer with one; the `dyn` leg reads a binding an ancestor
11997
11916
  // published, so it is the leg that has to be checked.
11998
11917
  lookupType(name, opts) {
11999
- const v = this.lookup(name, opts);
11918
+ const route = opts?.route ?? DEFAULT_ROUTE;
11919
+ const v = this.lookup(name, { route });
12000
11920
  if (v == null) {
12001
- this.transactor.refuse("TYPE_NOT_FOUND", {
12002
- name,
12003
- route: opts?.route ?? DEFAULT_LOOKUP_ROUTE
12004
- });
11921
+ this.transactor.refuse("TYPE_NOT_FOUND", { name, route });
12005
11922
  return null;
12006
11923
  }
12007
11924
  if (v?.[COMPONENT] == null) {
@@ -12803,7 +12720,14 @@ var App = class {
12803
12720
  const { type: type3 } = e;
12804
12721
  const isDrag = type3 === "dragover" || type3 === "dragstart" || type3 === "dragend" || type3 === "drop";
12805
12722
  const { rootNode: root, maxEventNodeDepth: maxDepth, comps, transactor } = this;
12806
- const [path, handlers] = Path.fromEvent(e, root, maxDepth, comps, !isDrag);
12723
+ const [path, handlers] = Path.fromNodeAndEventName(
12724
+ e.target,
12725
+ type3,
12726
+ root,
12727
+ maxDepth,
12728
+ comps,
12729
+ !isDrag
12730
+ );
12807
12731
  if (isDrag) this._handleDragEvent(e, type3, path);
12808
12732
  if (path !== null && handlers !== null)
12809
12733
  for (const handler of handlers) transactor.transactInputNow(path, e, handler, this.dragInfo);
@@ -12865,7 +12789,7 @@ var App = class {
12865
12789
  const value = txnPath.lookup(rootValue);
12866
12790
  const dragType = e.target.dataset.dragtype ?? "?";
12867
12791
  const stack = path.toTransactionPath().buildStack(this.makeStack(rootValue));
12868
- this.dragInfo = new DragInfo(txnPath, stack, e, value, dragType, e.target);
12792
+ this.dragInfo = new DragInfo(stack, value, dragType, e.target);
12869
12793
  } else if (type3 === "drop") {
12870
12794
  e.preventDefault();
12871
12795
  this._cleanDragOverAttrs();
@@ -13002,10 +12926,8 @@ function getClosestDropTarget(target, rootNode, count) {
13002
12926
  return null;
13003
12927
  }
13004
12928
  var DragInfo = class {
13005
- constructor(path, stack, e, val, type3, node) {
13006
- this.path = path;
12929
+ constructor(stack, val, type3, node) {
13007
12930
  this.stack = stack;
13008
- this.e = e;
13009
12931
  this.val = val;
13010
12932
  this.type = type3;
13011
12933
  this.node = node;
@@ -13097,6 +13019,8 @@ var Renderer = class {
13097
13019
  setNullCache() {
13098
13020
  this.cache = new NullDomCache();
13099
13021
  }
13022
+ // Library utilities for consumers embedding tutuca: render a value to a detached
13023
+ // DOM node / an HTML string. Not called by the framework itself.
13100
13024
  renderToDOM(stack, val) {
13101
13025
  const rootNode = document.createElement("div");
13102
13026
  const rOpts = { document };
@@ -13314,7 +13238,7 @@ function shadowCheckComponent(Comp) {
13314
13238
  });
13315
13239
  return checkComponent(shadowComp).reports;
13316
13240
  }
13317
- function check2(app) {
13241
+ function check(app) {
13318
13242
  const counts = { error: 0, warn: 0, hint: 0 };
13319
13243
  for (const Comp of app.comps.byId.values()) {
13320
13244
  const reports = shadowCheckComponent(Comp);
@@ -13438,7 +13362,7 @@ export {
13438
13362
  UNKNOWN_X_OP,
13439
13363
  UNSUPPORTED_EXPR_SYNTAX,
13440
13364
  X_OP_IGNORES_CHILDREN,
13441
- check2 as check,
13365
+ check,
13442
13366
  checkComponent,
13443
13367
  collectIterBindings,
13444
13368
  compileClassesToStyle,