tutuca 0.9.82 → 0.9.83

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.
@@ -3293,6 +3293,90 @@ function use(fn) {
3293
3293
  }
3294
3294
  __name(use, "use");
3295
3295
 
3296
+ // src/chai-jest.js
3297
+ function jestMatchers(chai, utils) {
3298
+ const A = chai.Assertion;
3299
+ const m = (name, fn) => A.addMethod(name, fn);
3300
+ m("toBe", function(expected) {
3301
+ this.assert(Object.is(this._obj, expected), "expected #{this} to be #{exp}", "expected #{this} not to be #{exp}", expected, this._obj);
3302
+ });
3303
+ m("toEqual", function(expected) {
3304
+ this.assert(utils.eql(this._obj, expected), "expected #{this} to deeply equal #{exp}", "expected #{this} not to deeply equal #{exp}", expected, this._obj, true);
3305
+ });
3306
+ m("toBeTruthy", function() {
3307
+ this.assert(Boolean(this._obj), "expected #{this} to be truthy", "expected #{this} not to be truthy");
3308
+ });
3309
+ m("toBeFalsy", function() {
3310
+ this.assert(!this._obj, "expected #{this} to be falsy", "expected #{this} not to be falsy");
3311
+ });
3312
+ m("toBeNull", function() {
3313
+ this.assert(this._obj === null, "expected #{this} to be null", "expected #{this} not to be null");
3314
+ });
3315
+ m("toBeUndefined", function() {
3316
+ this.assert(this._obj === undefined, "expected #{this} to be undefined", "expected #{this} not to be undefined");
3317
+ });
3318
+ m("toBeDefined", function() {
3319
+ this.assert(this._obj !== undefined, "expected #{this} to be defined", "expected #{this} to be undefined");
3320
+ });
3321
+ m("toBeNaN", function() {
3322
+ this.assert(Number.isNaN(this._obj), "expected #{this} to be NaN", "expected #{this} not to be NaN");
3323
+ });
3324
+ const compare = (name, op, word) => m(name, function(expected) {
3325
+ this.assert(op(this._obj, expected), `expected #{this} to be ${word} #{exp}`, `expected #{this} not to be ${word} #{exp}`, expected);
3326
+ });
3327
+ compare("toBeGreaterThan", (a, b) => a > b, "greater than");
3328
+ compare("toBeGreaterThanOrEqual", (a, b) => a >= b, "greater than or equal to");
3329
+ compare("toBeLessThan", (a, b) => a < b, "less than");
3330
+ compare("toBeLessThanOrEqual", (a, b) => a <= b, "less than or equal to");
3331
+ m("toBeCloseTo", function(expected, numDigits = 2) {
3332
+ const pass = Math.abs(expected - this._obj) < 10 ** -numDigits / 2;
3333
+ this.assert(pass, `expected #{this} to be close to #{exp} (${numDigits} digits)`, `expected #{this} not to be close to #{exp} (${numDigits} digits)`, expected);
3334
+ });
3335
+ m("toContain", function(item) {
3336
+ const obj = this._obj;
3337
+ const ok = typeof obj === "string" ? obj.includes(item) : Array.from(obj).includes(item);
3338
+ this.assert(ok, "expected #{this} to contain #{exp}", "expected #{this} not to contain #{exp}", item);
3339
+ });
3340
+ m("toHaveLength", function(length) {
3341
+ const actual = this._obj == null ? undefined : this._obj.length;
3342
+ this.assert(actual === length, "expected #{this} to have length #{exp}", "expected #{this} not to have length #{exp}", length, actual);
3343
+ });
3344
+ m("toMatch", function(expected) {
3345
+ const obj = this._obj;
3346
+ const ok = expected instanceof RegExp ? expected.test(obj) : String(obj).includes(expected);
3347
+ this.assert(ok, "expected #{this} to match #{exp}", "expected #{this} not to match #{exp}", expected);
3348
+ });
3349
+ m("toHaveProperty", function(path, ...rest) {
3350
+ const keys = Array.isArray(path) ? path : String(path).split(".");
3351
+ let cur = this._obj;
3352
+ let found = true;
3353
+ for (const k of keys) {
3354
+ if (cur != null && k in Object(cur))
3355
+ cur = cur[k];
3356
+ else {
3357
+ found = false;
3358
+ break;
3359
+ }
3360
+ }
3361
+ const pass = found && (rest.length === 0 || utils.eql(cur, rest[0]));
3362
+ this.assert(pass, "expected #{this} to have property #{exp}", "expected #{this} not to have property #{exp}", path);
3363
+ });
3364
+ m("toBeInstanceOf", function(ctor) {
3365
+ this.assert(this._obj instanceof ctor, "expected #{this} to be an instance of #{exp}", "expected #{this} not to be an instance of #{exp}", ctor.name ?? ctor);
3366
+ });
3367
+ m("toThrow", function(expected) {
3368
+ const a = new chai.Assertion(this._obj);
3369
+ if (utils.flag(this, "negate")) {
3370
+ expected === undefined ? a.to.not.throw() : a.to.not.throw(expected);
3371
+ } else {
3372
+ expected === undefined ? a.to.throw() : a.to.throw(expected);
3373
+ }
3374
+ });
3375
+ }
3376
+
3377
+ // deps/chai.js
3378
+ use(jestMatchers);
3379
+
3296
3380
  // deps/immutable.js
3297
3381
  function invariant(condition, error) {
3298
3382
  if (!condition)
@@ -8518,9 +8602,6 @@ class DynVal extends RenderNameVal {
8518
8602
  eval(stack) {
8519
8603
  return stack.lookupDynamic(this.name);
8520
8604
  }
8521
- toPathItem() {
8522
- return null;
8523
- }
8524
8605
  toString() {
8525
8606
  return `*${this.name}`;
8526
8607
  }
@@ -8758,7 +8839,7 @@ class ConstAttrs extends Attributes {
8758
8839
  toMacroVars() {
8759
8840
  const r = {};
8760
8841
  for (const name in this.items)
8761
- r[name] = `'${this.items[name]}'`;
8842
+ r[name] = new ConstVal(`${this.items[name]}`).toString();
8762
8843
  return r;
8763
8844
  }
8764
8845
  isConstant() {
@@ -8864,6 +8945,76 @@ class RequestHandler {
8864
8945
  }
8865
8946
  }
8866
8947
 
8948
+ // src/cache.js
8949
+ class NullDomCache {
8950
+ get(_keys, _cacheKey) {}
8951
+ set(_keys, _cacheKey, _v) {}
8952
+ evict() {
8953
+ return { hit: 0, miss: 0, badKey: 0 };
8954
+ }
8955
+ }
8956
+
8957
+ class WeakMapDomCache {
8958
+ constructor() {
8959
+ this.hit = this.miss = this.badKey = 0;
8960
+ this.keysByLen = new Map;
8961
+ }
8962
+ _returnValue(r) {
8963
+ if (r === undefined)
8964
+ this.miss += 1;
8965
+ else
8966
+ this.hit += 1;
8967
+ return r;
8968
+ }
8969
+ get(keys, cacheKey) {
8970
+ const len = keys.length;
8971
+ let cur = this.keysByLen.get(len);
8972
+ if (!cur)
8973
+ return this._returnValue(undefined);
8974
+ for (let i = 0;i < len - 1; i++) {
8975
+ cur = cur.get(keys[i]);
8976
+ if (!cur)
8977
+ return this._returnValue(undefined);
8978
+ }
8979
+ return this._returnValue(cur.get(keys[len - 1])?.[cacheKey]);
8980
+ }
8981
+ set(keys, cacheKey, v) {
8982
+ const len = keys.length;
8983
+ let cur = this.keysByLen.get(len);
8984
+ if (!cur) {
8985
+ cur = new WeakMap;
8986
+ this.keysByLen.set(len, cur);
8987
+ }
8988
+ for (let i = 0;i < len - 1; i++) {
8989
+ const key = keys[i];
8990
+ let next = cur.get(key);
8991
+ if (!next) {
8992
+ if (typeof key !== "object") {
8993
+ this.badKey += 1;
8994
+ return;
8995
+ }
8996
+ next = new WeakMap;
8997
+ cur.set(key, next);
8998
+ }
8999
+ cur = next;
9000
+ }
9001
+ const lastKey = keys[len - 1];
9002
+ const leaf = cur.get(lastKey);
9003
+ if (leaf)
9004
+ leaf[cacheKey] = v;
9005
+ else if (typeof lastKey === "object")
9006
+ cur.set(lastKey, { [cacheKey]: v });
9007
+ else
9008
+ this.badKey += 1;
9009
+ }
9010
+ evict() {
9011
+ const { hit, miss, badKey } = this;
9012
+ this.hit = this.miss = this.badKey = 0;
9013
+ this.keysByLen = new Map;
9014
+ return { hit, miss, badKey };
9015
+ }
9016
+ }
9017
+
8867
9018
  // src/vdom.js
8868
9019
  var HTML_NS = "http://www.w3.org/1999/xhtml";
8869
9020
  var SVG_NS = "http://www.w3.org/2000/svg";
@@ -8891,6 +9042,7 @@ var NEVER_ASSIGN = new Set([
8891
9042
  "role",
8892
9043
  "popover"
8893
9044
  ]);
9045
+ var PROP_ATTR_NAME = { className: "class", htmlFor: "for" };
8894
9046
  function applyProperties(node, props) {
8895
9047
  const namespaced = isNamespaced(node);
8896
9048
  for (const name in props)
@@ -8909,15 +9061,22 @@ function setProp2(node, name, value, namespaced) {
8909
9061
  }
8910
9062
  if (typeof value === "function")
8911
9063
  return;
8912
- if (!namespaced && !NEVER_ASSIGN.has(name) && name in node) {
9064
+ const usesProp = !namespaced && !NEVER_ASSIGN.has(name) && name in node;
9065
+ if (usesProp && value != null) {
8913
9066
  try {
8914
- node[name] = value == null ? "" : value;
9067
+ node[name] = value;
8915
9068
  return;
8916
9069
  } catch {}
8917
9070
  }
8918
- if (value == null || value === false && name[4] !== "-")
8919
- node.removeAttribute(name);
8920
- else
9071
+ if (value == null || value === false && name[4] !== "-") {
9072
+ if (usesProp) {
9073
+ try {
9074
+ node[name] = "";
9075
+ } catch {}
9076
+ node.removeAttribute(PROP_ATTR_NAME[name] ?? name);
9077
+ } else
9078
+ node.removeAttribute(name);
9079
+ } else
8921
9080
  node.setAttribute(name, value);
8922
9081
  }
8923
9082
  function applyValueLast(node, value) {
@@ -9098,22 +9257,12 @@ function morphNode(domNode, source, target, opts) {
9098
9257
  }
9099
9258
  if (type3 === 1 && source.isSameKind(target)) {
9100
9259
  const propsDiff = diffProps(source.attrs, target.attrs);
9101
- let pendingValue;
9102
- let pendingChecked;
9103
- let applyValue = false;
9104
- let applyChecked = false;
9260
+ const hasValue = propsDiff != null && "value" in propsDiff;
9261
+ const hasChecked = propsDiff != null && "checked" in propsDiff;
9105
9262
  if (propsDiff) {
9106
- if ("value" in propsDiff || "checked" in propsDiff) {
9107
- const { value, checked, ...rest } = propsDiff;
9263
+ if (hasValue || hasChecked) {
9264
+ const { value: _v, checked: _c, ...rest } = propsDiff;
9108
9265
  applyProperties(domNode, rest);
9109
- if ("value" in propsDiff) {
9110
- pendingValue = value;
9111
- applyValue = true;
9112
- }
9113
- if ("checked" in propsDiff) {
9114
- pendingChecked = checked;
9115
- applyChecked = true;
9116
- }
9117
9266
  } else
9118
9267
  applyProperties(domNode, propsDiff);
9119
9268
  }
@@ -9121,14 +9270,12 @@ function morphNode(domNode, source, target, opts) {
9121
9270
  const ns = effectiveNs(target, opts);
9122
9271
  morphChildren(domNode, source.childs, target.childs, childOpts(target, ns, opts));
9123
9272
  }
9124
- if (!applyValue && source.tag === "SELECT" && target.attrs.value !== undefined) {
9125
- pendingValue = target.attrs.value;
9126
- applyValue = true;
9127
- }
9128
- if (applyValue)
9129
- applyValueLast(domNode, pendingValue);
9130
- if (applyChecked)
9131
- setProp2(domNode, "checked", pendingChecked, false);
9273
+ if (hasValue)
9274
+ applyValueLast(domNode, propsDiff.value);
9275
+ else if (source.tag === "SELECT" && target.attrs.value !== undefined)
9276
+ applyValueLast(domNode, target.attrs.value);
9277
+ if (hasChecked)
9278
+ setProp2(domNode, "checked", propsDiff.checked, false);
9132
9279
  return domNode;
9133
9280
  }
9134
9281
  if (type3 === 11) {
@@ -9249,74 +9396,229 @@ function h(tagName, properties, children, namespace) {
9249
9396
  return new VNode2(tag, props, normalizedChildren, key, namespace);
9250
9397
  }
9251
9398
 
9252
- // src/anode.js
9253
- function resolveDynProducer(comp, name) {
9254
- let producerComp, producerProvide;
9255
- const lk = comp?.lookup?.[name];
9256
- if (lk != null) {
9257
- producerComp = comp.scope?.lookupComponent(lk.compName);
9258
- producerProvide = producerComp?.provide?.[lk.provideName];
9259
- } else {
9260
- const p = comp?.provide?.[name];
9261
- if (p == null)
9262
- return null;
9263
- producerComp = comp;
9264
- producerProvide = p;
9265
- }
9266
- if (producerComp == null || producerProvide == null)
9267
- return null;
9268
- const pi = producerProvide.val?.toPathItem?.() ?? null;
9269
- return { producerCompId: producerComp.id, producerSteps: pi ? [pi] : [] };
9270
- }
9399
+ // src/renderer.js
9400
+ var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk"];
9271
9401
 
9272
- class BaseNode {
9273
- render(_stack, _rx) {
9274
- return null;
9275
- }
9276
- setDataAttr(key, val) {
9277
- console.warn("setDataAttr not implemented for", this, { key, val });
9402
+ class Renderer {
9403
+ constructor(comps) {
9404
+ this.comps = comps;
9405
+ this.cache = new WeakMapDomCache;
9406
+ this.renderTag = h;
9278
9407
  }
9279
- isConstant() {
9280
- return false;
9408
+ renderFragment(childs) {
9409
+ return new VFragment(childs);
9281
9410
  }
9282
- optimize() {}
9283
- }
9284
-
9285
- class TextNode extends BaseNode {
9286
- constructor(val) {
9287
- super();
9288
- this.val = val;
9411
+ renderComment(text) {
9412
+ return new VComment(text);
9289
9413
  }
9290
- render(_stack, _rx) {
9291
- return this.val;
9414
+ setNullCache() {
9415
+ this.cache = new NullDomCache;
9292
9416
  }
9293
- isWhiteSpace() {
9294
- for (let i = 0;i < this.val.length; i++) {
9295
- const c = this.val.charCodeAt(i);
9296
- if (!(c === 32 || c === 10 || c === 9 || c === 13))
9297
- return false;
9298
- }
9299
- return true;
9417
+ renderToDOM(stack, val) {
9418
+ const rootNode = document.createElement("div");
9419
+ const rOpts = { document };
9420
+ render(h("DIV", null, [this.renderRoot(stack, val)]), rootNode, rOpts);
9421
+ return rootNode.childNodes[0];
9300
9422
  }
9301
- hasNewLine() {
9302
- for (let i = 0;i < this.val.length; i++) {
9303
- const c = this.val.charCodeAt(i);
9304
- if (c === 10 || c === 13)
9305
- return true;
9423
+ renderToString(stack, val, cleanAttrs = true) {
9424
+ const dom = this.renderToDOM(stack, val);
9425
+ if (cleanAttrs) {
9426
+ const nodes = dom.querySelectorAll("[data-nid],[data-cid],[data-eid]");
9427
+ for (const { dataset } of nodes)
9428
+ for (const name of DATASET_ATTRS)
9429
+ delete dataset[name];
9306
9430
  }
9307
- return false;
9431
+ return dom.innerHTML;
9308
9432
  }
9309
- condenseWhiteSpace(replacement = "") {
9310
- this.val = replacement;
9433
+ renderRoot(stack, val, viewName = null) {
9434
+ const comp = this.comps.getCompFor(val);
9435
+ if (comp === null)
9436
+ return null;
9437
+ return this._rValComp(stack, val, comp, comp.getView(viewName).anode, "ROOT", viewName);
9311
9438
  }
9312
- isConstant() {
9313
- return true;
9439
+ renderIt(stack, node, key, viewName) {
9440
+ const comp = this.comps.getCompFor(stack.it);
9441
+ return comp ? this._rValComp(stack, stack.it, comp, node, key, viewName) : null;
9314
9442
  }
9315
- setDataAttr(_key, _val) {}
9316
- }
9317
-
9318
- class CommentNode extends TextNode {
9319
- render(_stack, rx) {
9443
+ _rValComp(stack, val, comp, node, key, viewName) {
9444
+ const cacheKey = `${viewName ?? stack.viewsId ?? ""}-${key}`;
9445
+ const cachePath = [node, val];
9446
+ stack._pushDynBindValuesToArray(cachePath, comp);
9447
+ const cachedNode = this.cache.get(cachePath, cacheKey);
9448
+ if (cachedNode)
9449
+ return cachedNode;
9450
+ const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
9451
+ const meta = this._renderMetadata({
9452
+ $: "Comp",
9453
+ nid: node?.nodeId ?? null,
9454
+ cid: comp.id,
9455
+ vid: view.name
9456
+ });
9457
+ const dom = new VFragment([meta, this.renderView(view, stack)]);
9458
+ this.cache.set(cachePath, cacheKey, dom);
9459
+ return dom;
9460
+ }
9461
+ pushEachEntry(r, nid, attrName, key, dom) {
9462
+ r.push(this._renderMetadata({ $: "Each", nid, [attrName]: key }), dom);
9463
+ }
9464
+ renderEach(stack, iterInfo, node, viewName) {
9465
+ const { seq, filter, loopWith } = iterInfo.eval(stack);
9466
+ const r = [];
9467
+ const { iterData, start, end } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
9468
+ getSeqInfo(seq)(seq, (key, value, attrName) => {
9469
+ if (filter.call(stack.it, key, value, iterData)) {
9470
+ const dom = this.renderIt(stack.enter(value, { key }, true), node, key, viewName);
9471
+ this.pushEachEntry(r, node.nodeId, attrName, key, dom);
9472
+ }
9473
+ }, start, end);
9474
+ return r;
9475
+ }
9476
+ renderEachWhen(stack, iterInfo, view, nid) {
9477
+ const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
9478
+ const r = [];
9479
+ const it = stack.it;
9480
+ const { iterData, start, end } = unpackLoopResult(loopWith.call(it, seq), seq);
9481
+ getSeqInfo(seq)(seq, (key, value, attrName) => {
9482
+ if (filter.call(it, key, value, iterData)) {
9483
+ const cachePath = enricher ? [view, it, value] : [view, value];
9484
+ const binds = { key, value };
9485
+ const cacheKey = `${nid}-${key}`;
9486
+ if (enricher)
9487
+ enricher.call(it, binds, key, value, iterData);
9488
+ const cachedNode = this.cache.get(cachePath, cacheKey);
9489
+ if (cachedNode)
9490
+ this.pushEachEntry(r, nid, attrName, key, cachedNode);
9491
+ else {
9492
+ const dom = this.renderView(view, stack.enter(value, binds, false));
9493
+ this.pushEachEntry(r, nid, attrName, key, dom);
9494
+ this.cache.set(cachePath, cacheKey, dom);
9495
+ }
9496
+ }
9497
+ }, start, end);
9498
+ return r;
9499
+ }
9500
+ renderView(view, stack) {
9501
+ let n = stack.binds[1];
9502
+ while (n !== null) {
9503
+ const b = n[0];
9504
+ if (b.isFrame) {
9505
+ if (stack.it !== b.it)
9506
+ break;
9507
+ console.error("recursion detected", stack.it, b.it);
9508
+ return new VComment("RECURSION AVOIDED");
9509
+ }
9510
+ n = n[1];
9511
+ }
9512
+ return view.render(stack, this);
9513
+ }
9514
+ _renderMetadata(info) {
9515
+ return new VComment(`§${JSON.stringify(info)}§`);
9516
+ }
9517
+ }
9518
+ var getSeqInfo = (seq) => isIndexed(seq) ? imIndexedIter : isKeyed(seq) ? imKeyedIter : seq?.[SEQ_INFO] ?? unkIter;
9519
+ var normalizeRange = (start, end, size) => {
9520
+ let s = start == null ? 0 : start < 0 ? size + start : start;
9521
+ let e = end == null ? size : end < 0 ? size + end : end;
9522
+ s = s < 0 ? 0 : s > size ? size : s;
9523
+ e = e < 0 ? 0 : e > size ? size : e;
9524
+ return [s, e < s ? s : e];
9525
+ };
9526
+ var filterAlwaysTrue = (_v, _k, _seq) => true;
9527
+ var nullLoopWith = (seq) => ({ iterData: { seq } });
9528
+ var unpackLoopResult = (result, seq) => {
9529
+ const r = result ?? {};
9530
+ return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end };
9531
+ };
9532
+ var imIndexedIter = (seq, visit, start, end) => {
9533
+ const [s, e] = normalizeRange(start, end, seq.size);
9534
+ for (let i = s;i < e; i++)
9535
+ visit(i, seq.get(i), "si");
9536
+ };
9537
+ var imKeyedIter = (seq, visit, start, end) => {
9538
+ const [s, e] = normalizeRange(start, end, seq.size);
9539
+ let i = 0;
9540
+ for (const [k, v] of seq.toSeq().entries()) {
9541
+ if (i >= e)
9542
+ break;
9543
+ if (i >= s)
9544
+ visit(k, v, "sk");
9545
+ i++;
9546
+ }
9547
+ };
9548
+ var unkIter = () => {};
9549
+ var SEQ_INFO = Symbol.for("tutuca.seqInfo");
9550
+
9551
+ // src/util/env.js
9552
+ var isMac = (globalThis.navigator?.userAgent ?? "").toLowerCase().includes("mac");
9553
+
9554
+ // src/anode.js
9555
+ function resolveDynProducer(comp, name) {
9556
+ let producerComp, producerProvide;
9557
+ const lk = comp?.lookup?.[name];
9558
+ if (lk != null) {
9559
+ producerComp = comp.scope?.lookupComponent(lk.compName);
9560
+ producerProvide = producerComp?.provide?.[lk.provideName];
9561
+ } else {
9562
+ const p = comp?.provide?.[name];
9563
+ if (p == null)
9564
+ return null;
9565
+ producerComp = comp;
9566
+ producerProvide = p;
9567
+ }
9568
+ if (producerComp == null || producerProvide == null)
9569
+ return null;
9570
+ const pi = producerProvide.val?.toPathItem?.() ?? null;
9571
+ return { producerCompId: producerComp.id, producerSteps: pi ? [pi] : [] };
9572
+ }
9573
+
9574
+ class BaseNode {
9575
+ render(_stack, _rx) {
9576
+ return null;
9577
+ }
9578
+ setDataAttr(key, val) {
9579
+ console.warn("setDataAttr not implemented for", this, { key, val });
9580
+ }
9581
+ isConstant() {
9582
+ return false;
9583
+ }
9584
+ optimize() {}
9585
+ }
9586
+
9587
+ class TextNode extends BaseNode {
9588
+ constructor(val) {
9589
+ super();
9590
+ this.val = val;
9591
+ }
9592
+ render(_stack, _rx) {
9593
+ return this.val;
9594
+ }
9595
+ isWhiteSpace() {
9596
+ for (let i = 0;i < this.val.length; i++) {
9597
+ const c = this.val.charCodeAt(i);
9598
+ if (!(c === 32 || c === 10 || c === 9 || c === 13))
9599
+ return false;
9600
+ }
9601
+ return true;
9602
+ }
9603
+ hasNewLine() {
9604
+ for (let i = 0;i < this.val.length; i++) {
9605
+ const c = this.val.charCodeAt(i);
9606
+ if (c === 10 || c === 13)
9607
+ return true;
9608
+ }
9609
+ return false;
9610
+ }
9611
+ condenseWhiteSpace(replacement = "") {
9612
+ this.val = replacement;
9613
+ }
9614
+ isConstant() {
9615
+ return true;
9616
+ }
9617
+ setDataAttr(_key, _val) {}
9618
+ }
9619
+
9620
+ class CommentNode extends TextNode {
9621
+ render(_stack, rx) {
9320
9622
  return rx.renderComment(this.val);
9321
9623
  }
9322
9624
  }
@@ -9452,7 +9754,7 @@ class ANode extends BaseNode {
9452
9754
  }
9453
9755
  }
9454
9756
  function parseXOp(attrs, childs, opIdx, px) {
9455
- if (attrs.length === 0)
9757
+ if (attrs.length <= opIdx)
9456
9758
  return maybeFragment(childs);
9457
9759
  const { name, value } = attrs[opIdx];
9458
9760
  const as = attrs.getNamedItem("as")?.value ?? null;
@@ -9773,8 +10075,6 @@ class IterInfo {
9773
10075
  return { seq, filter, loopWith, enricher };
9774
10076
  }
9775
10077
  }
9776
- var filterAlwaysTrue = (_v, _k, _seq) => true;
9777
- var nullLoopWith = (seq) => ({ iterData: { seq } });
9778
10078
  function xOp(consumed = [], { wrappable = false, wrapper = null } = {}) {
9779
10079
  return { consumed: new Set(consumed), wrappable, wrapper };
9780
10080
  }
@@ -9961,7 +10261,6 @@ class NodeEvent {
9961
10261
  return r;
9962
10262
  }
9963
10263
  }
9964
- var isMac = (globalThis.navigator?.userAgent ?? "").toLowerCase().includes("mac");
9965
10264
  var fwdIfCtxPred = (pred) => (w) => (that, f, args, ctx) => pred(ctx) ? w(that, f, args, ctx) : that;
9966
10265
  var fwdIfKey = (keyName) => fwdIfCtxPred((ctx) => ctx.e.key === keyName);
9967
10266
  var fwdCtrl = fwdIfCtxPred(({ e }) => isMac && e.metaKey || e.ctrlKey);
@@ -9992,96 +10291,15 @@ function compileModifiers(eventName, names) {
9992
10291
  };
9993
10292
  }
9994
10293
 
9995
- // src/chai-jest.js
9996
- function jestMatchers(chai, utils) {
9997
- const A = chai.Assertion;
9998
- const m = (name, fn) => A.addMethod(name, fn);
9999
- m("toBe", function(expected) {
10000
- this.assert(Object.is(this._obj, expected), "expected #{this} to be #{exp}", "expected #{this} not to be #{exp}", expected, this._obj);
10001
- });
10002
- m("toEqual", function(expected) {
10003
- this.assert(utils.eql(this._obj, expected), "expected #{this} to deeply equal #{exp}", "expected #{this} not to deeply equal #{exp}", expected, this._obj, true);
10004
- });
10005
- m("toBeTruthy", function() {
10006
- this.assert(Boolean(this._obj), "expected #{this} to be truthy", "expected #{this} not to be truthy");
10007
- });
10008
- m("toBeFalsy", function() {
10009
- this.assert(!this._obj, "expected #{this} to be falsy", "expected #{this} not to be falsy");
10010
- });
10011
- m("toBeNull", function() {
10012
- this.assert(this._obj === null, "expected #{this} to be null", "expected #{this} not to be null");
10013
- });
10014
- m("toBeUndefined", function() {
10015
- this.assert(this._obj === undefined, "expected #{this} to be undefined", "expected #{this} not to be undefined");
10016
- });
10017
- m("toBeDefined", function() {
10018
- this.assert(this._obj !== undefined, "expected #{this} to be defined", "expected #{this} to be undefined");
10019
- });
10020
- m("toBeNaN", function() {
10021
- this.assert(Number.isNaN(this._obj), "expected #{this} to be NaN", "expected #{this} not to be NaN");
10022
- });
10023
- const compare = (name, op, word) => m(name, function(expected) {
10024
- this.assert(op(this._obj, expected), `expected #{this} to be ${word} #{exp}`, `expected #{this} not to be ${word} #{exp}`, expected);
10025
- });
10026
- compare("toBeGreaterThan", (a, b) => a > b, "greater than");
10027
- compare("toBeGreaterThanOrEqual", (a, b) => a >= b, "greater than or equal to");
10028
- compare("toBeLessThan", (a, b) => a < b, "less than");
10029
- compare("toBeLessThanOrEqual", (a, b) => a <= b, "less than or equal to");
10030
- m("toBeCloseTo", function(expected, numDigits = 2) {
10031
- const pass = Math.abs(expected - this._obj) < 10 ** -numDigits / 2;
10032
- this.assert(pass, `expected #{this} to be close to #{exp} (${numDigits} digits)`, `expected #{this} not to be close to #{exp} (${numDigits} digits)`, expected);
10033
- });
10034
- m("toContain", function(item) {
10035
- const obj = this._obj;
10036
- const ok = typeof obj === "string" ? obj.includes(item) : Array.from(obj).includes(item);
10037
- this.assert(ok, "expected #{this} to contain #{exp}", "expected #{this} not to contain #{exp}", item);
10038
- });
10039
- m("toHaveLength", function(length) {
10040
- const actual = this._obj == null ? undefined : this._obj.length;
10041
- this.assert(actual === length, "expected #{this} to have length #{exp}", "expected #{this} not to have length #{exp}", length, actual);
10042
- });
10043
- m("toMatch", function(expected) {
10044
- const obj = this._obj;
10045
- const ok = expected instanceof RegExp ? expected.test(obj) : String(obj).includes(expected);
10046
- this.assert(ok, "expected #{this} to match #{exp}", "expected #{this} not to match #{exp}", expected);
10047
- });
10048
- m("toHaveProperty", function(path, ...rest) {
10049
- const keys = Array.isArray(path) ? path : String(path).split(".");
10050
- let cur = this._obj;
10051
- let found = true;
10052
- for (const k of keys) {
10053
- if (cur != null && k in Object(cur))
10054
- cur = cur[k];
10055
- else {
10056
- found = false;
10057
- break;
10058
- }
10059
- }
10060
- const pass = found && (rest.length === 0 || utils.eql(cur, rest[0]));
10061
- this.assert(pass, "expected #{this} to have property #{exp}", "expected #{this} not to have property #{exp}", path);
10062
- });
10063
- m("toBeInstanceOf", function(ctor) {
10064
- this.assert(this._obj instanceof ctor, "expected #{this} to be an instance of #{exp}", "expected #{this} not to be an instance of #{exp}", ctor.name ?? ctor);
10065
- });
10066
- m("toThrow", function(expected) {
10067
- const a = new chai.Assertion(this._obj);
10068
- if (utils.flag(this, "negate")) {
10069
- expected === undefined ? a.to.not.throw() : a.to.not.throw(expected);
10070
- } else {
10071
- expected === undefined ? a.to.throw() : a.to.throw(expected);
10072
- }
10073
- });
10074
- }
10075
-
10076
- // src/util/parsectx.js
10077
- class ParseCtxClassSetCollector extends ParseContext {
10078
- constructor(...args) {
10079
- super(...args);
10080
- this.classes = new Set;
10081
- }
10082
- _addClasses(s) {
10083
- for (const v of s.split(/\s+/)) {
10084
- this.classes.add(v);
10294
+ // src/util/parsectx.js
10295
+ class ParseCtxClassSetCollector extends ParseContext {
10296
+ constructor(...args) {
10297
+ super(...args);
10298
+ this.classes = new Set;
10299
+ }
10300
+ _addClasses(s) {
10301
+ for (const v of s.split(/\s+/)) {
10302
+ this.classes.add(v);
10085
10303
  }
10086
10304
  }
10087
10305
  enterMacro(macroName, macroVars, macroSlots) {
@@ -10129,6 +10347,18 @@ class ParseCtxClassSetCollector extends ParseContext {
10129
10347
  return false;
10130
10348
  }
10131
10349
  }
10350
+ function collectAppClassesInSet(app) {
10351
+ const classes = new Set;
10352
+ for (const Comp of app.comps.byId.values()) {
10353
+ for (const key in Comp.views) {
10354
+ const view = Comp.views[key];
10355
+ for (const name of view.ctx.classes) {
10356
+ classes.add(name);
10357
+ }
10358
+ }
10359
+ }
10360
+ return classes;
10361
+ }
10132
10362
 
10133
10363
  // tools/core/html-tokenizer.js
10134
10364
  var CharCodes = {
@@ -12465,6 +12695,16 @@ var PARSE_ISSUES = {
12465
12695
  },
12466
12696
  "bad-value": { id: BAD_VALUE }
12467
12697
  };
12698
+ function protoHasMethod(proto, name) {
12699
+ let cursor = proto;
12700
+ while (cursor && cursor !== Object.prototype) {
12701
+ const desc = Object.getOwnPropertyDescriptor(cursor, name);
12702
+ if (desc !== undefined)
12703
+ return typeof desc.value === "function";
12704
+ cursor = Object.getPrototypeOf(cursor);
12705
+ }
12706
+ return false;
12707
+ }
12468
12708
  function collectProtoMethodNames(proto) {
12469
12709
  const out = [];
12470
12710
  let cursor = proto;
@@ -12723,7 +12963,7 @@ function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
12723
12963
  referencedInputs?.add(handlerVal.name);
12724
12964
  const { name } = handlerVal;
12725
12965
  if (input[name] === undefined) {
12726
- const isMethodFix = proto[name] !== undefined;
12966
+ const isMethodFix = protoHasMethod(proto, name);
12727
12967
  lx.error(INPUT_HANDLER_NOT_IMPLEMENTED, { name, handler, event, eventName, originAttr }, isMethodFix ? { kind: "add-prefix", from: name, to: `$${name}` } : replaceNameSuggestion(name, Object.keys(input)));
12728
12968
  if (isMethodFix) {
12729
12969
  lx.hint(INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER, { name, handler, event, eventName, originAttr }, { kind: "add-prefix", from: name, to: `$${name}` });
@@ -12732,7 +12972,7 @@ function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
12732
12972
  } else if (hvName === "MethodVal") {
12733
12973
  referencedInputs?.add(handlerVal.name);
12734
12974
  const { name } = handlerVal;
12735
- if (proto[name] === undefined) {
12975
+ if (!protoHasMethod(proto, name)) {
12736
12976
  const isInputFix = input[name] !== undefined;
12737
12977
  lx.error(INPUT_HANDLER_METHOD_NOT_IMPLEMENTED, { name, handler, event, eventName, originAttr }, isInputFix ? { kind: "drop-prefix", from: `$${name}`, to: name } : replaceNameSuggestion(name, collectProtoMethodNames(proto)));
12738
12978
  if (isInputFix) {
@@ -12755,7 +12995,7 @@ var ATTR_VAL_CHECKERS = {
12755
12995
  const { name } = val;
12756
12996
  if (fields[name] !== undefined)
12757
12997
  return;
12758
- if (proto[name] !== undefined)
12998
+ if (protoHasMethod(proto, name))
12759
12999
  lx.error(FIELD_VAL_IS_METHOD, { ...errCtx, val, name }, fixTo(`.${name}`, `$${name}`));
12760
13000
  else
12761
13001
  reportUnknownName(lx, FIELD_VAL_NOT_DEFINED, name, Object.keys(fields), { ...errCtx, val });
@@ -12763,7 +13003,7 @@ var ATTR_VAL_CHECKERS = {
12763
13003
  MethodVal({ lx, val, env, errCtx }) {
12764
13004
  const { fields, proto } = env;
12765
13005
  const { name } = val;
12766
- if (proto[name] !== undefined)
13006
+ if (protoHasMethod(proto, name))
12767
13007
  return;
12768
13008
  if (fields[name] !== undefined)
12769
13009
  lx.error(METHOD_VAL_IS_FIELD, { ...errCtx, val, name }, fixTo(`$${name}`, `.${name}`));
@@ -14261,7 +14501,6 @@ class Transaction {
14261
14501
  return null;
14262
14502
  }
14263
14503
  }
14264
- var isMac2 = (globalThis.navigator?.userAgent ?? "").toLowerCase().includes("mac");
14265
14504
  var toNullIfNaN = (v) => Number.isNaN(v) ? null : v;
14266
14505
  function getValue(e) {
14267
14506
  return e.target.type === "checkbox" ? e.target.checked : (e instanceof CustomEvent ? e.detail : e.target.value) ?? null;
@@ -14315,7 +14554,7 @@ class InputEvent extends Transaction {
14315
14554
  return e.shiftKey;
14316
14555
  case "isCtrl":
14317
14556
  case "isCmd":
14318
- return isMac2 && e.metaKey || e.ctrlKey;
14557
+ return isMac && e.metaKey || e.ctrlKey;
14319
14558
  case "key":
14320
14559
  return e.key;
14321
14560
  case "keyCode":
@@ -14738,7 +14977,6 @@ class DragInfo {
14738
14977
  return this.stack.lookupBind(name);
14739
14978
  }
14740
14979
  }
14741
-
14742
14980
  // src/oo.js
14743
14981
  var BAD_VALUE2 = Symbol("BadValue");
14744
14982
  var nullCoercer = (v) => v;
@@ -15005,8 +15243,8 @@ class FieldSet extends Field {
15005
15243
  }
15006
15244
  }
15007
15245
  function mkCompField(field, scope, args) {
15008
- const Comp = scope.lookupComponent(field.type);
15009
- console.assert(Comp !== null, "component not found", { field });
15246
+ const Comp = scope?.lookupComponent(field.type) ?? null;
15247
+ console.assert(!scope || Comp !== null, "component not found", { field });
15010
15248
  return Comp?.make({ ...field.args, ...args }, { scope }) ?? null;
15011
15249
  }
15012
15250
 
@@ -15123,321 +15361,6 @@ function classFromData(name, { fields = {}, methods, statics }) {
15123
15361
  Component.fromSpec = (opts) => new Component(classFromData(opts.name, opts), opts);
15124
15362
  var component = (opts) => Component.fromSpec(opts);
15125
15363
 
15126
- // src/cache.js
15127
- class NullDomCache {
15128
- get(_keys, _cacheKey) {}
15129
- set(_keys, _cacheKey, _v) {}
15130
- evict() {
15131
- return { hit: 0, miss: 0, badKey: 0 };
15132
- }
15133
- }
15134
-
15135
- class WeakMapDomCache {
15136
- constructor() {
15137
- this.hit = this.miss = this.badKey = 0;
15138
- this.keysByLen = new Map;
15139
- }
15140
- _returnValue(r) {
15141
- if (r === undefined)
15142
- this.miss += 1;
15143
- else
15144
- this.hit += 1;
15145
- return r;
15146
- }
15147
- get(keys, cacheKey) {
15148
- const len = keys.length;
15149
- let cur = this.keysByLen.get(len);
15150
- if (!cur)
15151
- return this._returnValue(undefined);
15152
- for (let i = 0;i < len - 1; i++) {
15153
- cur = cur.get(keys[i]);
15154
- if (!cur)
15155
- return this._returnValue(undefined);
15156
- }
15157
- return this._returnValue(cur.get(keys[len - 1])?.[cacheKey]);
15158
- }
15159
- set(keys, cacheKey, v) {
15160
- const len = keys.length;
15161
- let cur = this.keysByLen.get(len);
15162
- if (!cur) {
15163
- cur = new WeakMap;
15164
- this.keysByLen.set(len, cur);
15165
- }
15166
- for (let i = 0;i < len - 1; i++) {
15167
- const key = keys[i];
15168
- let next = cur.get(key);
15169
- if (!next) {
15170
- if (typeof key !== "object") {
15171
- this.badKey += 1;
15172
- return;
15173
- }
15174
- next = new WeakMap;
15175
- cur.set(key, next);
15176
- }
15177
- cur = next;
15178
- }
15179
- const lastKey = keys[len - 1];
15180
- const leaf = cur.get(lastKey);
15181
- if (leaf)
15182
- leaf[cacheKey] = v;
15183
- else if (typeof lastKey === "object")
15184
- cur.set(lastKey, { [cacheKey]: v });
15185
- else
15186
- this.badKey += 1;
15187
- }
15188
- evict() {
15189
- const { hit, miss, badKey } = this;
15190
- this.hit = this.miss = this.badKey = 0;
15191
- this.keysByLen = new Map;
15192
- return { hit, miss, badKey };
15193
- }
15194
- }
15195
-
15196
- // src/renderer.js
15197
- var DATASET_ATTRS = ["nid", "cid", "eid", "vid", "si", "sk"];
15198
-
15199
- class Renderer {
15200
- constructor(comps) {
15201
- this.comps = comps;
15202
- this.cache = new WeakMapDomCache;
15203
- this.renderTag = h;
15204
- }
15205
- renderFragment(childs) {
15206
- return new VFragment(childs);
15207
- }
15208
- renderComment(text) {
15209
- return new VComment(text);
15210
- }
15211
- setNullCache() {
15212
- this.cache = new NullDomCache;
15213
- }
15214
- renderToDOM(stack, val) {
15215
- const rootNode = document.createElement("div");
15216
- const rOpts = { document };
15217
- render(h("DIV", null, [this.renderRoot(stack, val)]), rootNode, rOpts);
15218
- return rootNode.childNodes[0];
15219
- }
15220
- renderToString(stack, val, cleanAttrs = true) {
15221
- const dom = this.renderToDOM(stack, val);
15222
- if (cleanAttrs) {
15223
- const nodes = dom.querySelectorAll("[data-nid],[data-cid],[data-eid]");
15224
- for (const { dataset } of nodes)
15225
- for (const name of DATASET_ATTRS)
15226
- delete dataset[name];
15227
- }
15228
- return dom.innerHTML;
15229
- }
15230
- renderRoot(stack, val, viewName = null) {
15231
- const comp = this.comps.getCompFor(val);
15232
- if (comp === null)
15233
- return null;
15234
- return this._rValComp(stack, val, comp, comp.getView(viewName).anode, "ROOT", viewName);
15235
- }
15236
- renderIt(stack, node, key, viewName) {
15237
- const comp = this.comps.getCompFor(stack.it);
15238
- return comp ? this._rValComp(stack, stack.it, comp, node, key, viewName) : null;
15239
- }
15240
- _rValComp(stack, val, comp, node, key, viewName) {
15241
- const cacheKey = `${viewName ?? stack.viewsId ?? ""}-${key}`;
15242
- const cachePath = [node, val];
15243
- stack._pushDynBindValuesToArray(cachePath, comp);
15244
- const cachedNode = this.cache.get(cachePath, cacheKey);
15245
- if (cachedNode)
15246
- return cachedNode;
15247
- const view = viewName ? comp.getView(viewName) : stack.lookupBestView(comp.views, "main");
15248
- const meta = this._renderMetadata({
15249
- $: "Comp",
15250
- nid: node?.nodeId ?? null,
15251
- cid: comp.id,
15252
- vid: view.name
15253
- });
15254
- const dom = new VFragment([meta, this.renderView(view, stack)]);
15255
- this.cache.set(cachePath, cacheKey, dom);
15256
- return dom;
15257
- }
15258
- pushEachEntry(r, nid, attrName, key, dom) {
15259
- r.push(this._renderMetadata({ $: "Each", nid, [attrName]: key }), dom);
15260
- }
15261
- renderEach(stack, iterInfo, node, viewName) {
15262
- const { seq, filter, loopWith } = iterInfo.eval(stack);
15263
- const r = [];
15264
- const { iterData, start, end } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
15265
- getSeqInfo(seq)(seq, (key, value, attrName) => {
15266
- if (filter.call(stack.it, key, value, iterData)) {
15267
- const dom = this.renderIt(stack.enter(value, { key }, true), node, key, viewName);
15268
- this.pushEachEntry(r, node.nodeId, attrName, key, dom);
15269
- }
15270
- }, start, end);
15271
- return r;
15272
- }
15273
- renderEachWhen(stack, iterInfo, view, nid) {
15274
- const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
15275
- const r = [];
15276
- const it = stack.it;
15277
- const { iterData, start, end } = unpackLoopResult(loopWith.call(it, seq), seq);
15278
- getSeqInfo(seq)(seq, (key, value, attrName) => {
15279
- if (filter.call(it, key, value, iterData)) {
15280
- const cachePath = enricher ? [view, it, value] : [view, value];
15281
- const binds = { key, value };
15282
- const cacheKey = `${nid}-${key}`;
15283
- if (enricher)
15284
- enricher.call(it, binds, key, value, iterData);
15285
- const cachedNode = this.cache.get(cachePath, cacheKey);
15286
- if (cachedNode)
15287
- this.pushEachEntry(r, nid, attrName, key, cachedNode);
15288
- else {
15289
- const dom = this.renderView(view, stack.enter(value, binds, false));
15290
- this.pushEachEntry(r, nid, attrName, key, dom);
15291
- this.cache.set(cachePath, cacheKey, dom);
15292
- }
15293
- }
15294
- }, start, end);
15295
- return r;
15296
- }
15297
- renderView(view, stack) {
15298
- let n = stack.binds[1];
15299
- while (n !== null) {
15300
- const b = n[0];
15301
- if (b.isFrame) {
15302
- if (stack.it !== b.it)
15303
- break;
15304
- console.error("recursion detected", stack.it, b.it);
15305
- return new VComment("RECURSION AVOIDED");
15306
- }
15307
- n = n[1];
15308
- }
15309
- return view.render(stack, this);
15310
- }
15311
- _renderMetadata(info) {
15312
- return new VComment(`§${JSON.stringify(info)}§`);
15313
- }
15314
- }
15315
- var getSeqInfo = (seq) => isIndexed(seq) ? imIndexedIter : isKeyed(seq) ? imKeyedIter : seq?.[SEQ_INFO] ?? unkIter;
15316
- var normalizeRange = (start, end, size) => {
15317
- let s = start == null ? 0 : start < 0 ? size + start : start;
15318
- let e = end == null ? size : end < 0 ? size + end : end;
15319
- s = s < 0 ? 0 : s > size ? size : s;
15320
- e = e < 0 ? 0 : e > size ? size : e;
15321
- return [s, e < s ? s : e];
15322
- };
15323
- var unpackLoopResult = (result, seq) => {
15324
- const r = result ?? {};
15325
- return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end };
15326
- };
15327
- var imIndexedIter = (seq, visit, start, end) => {
15328
- const [s, e] = normalizeRange(start, end, seq.size);
15329
- for (let i = s;i < e; i++)
15330
- visit(i, seq.get(i), "si");
15331
- };
15332
- var imKeyedIter = (seq, visit, start, end) => {
15333
- const [s, e] = normalizeRange(start, end, seq.size);
15334
- let i = 0;
15335
- for (const [k, v] of seq.toSeq().entries()) {
15336
- if (i >= e)
15337
- break;
15338
- if (i >= s)
15339
- visit(k, v, "sk");
15340
- i++;
15341
- }
15342
- };
15343
- var unkIter = () => {};
15344
- var SEQ_INFO = Symbol.for("tutuca.seqInfo");
15345
-
15346
- // extra/klist.js
15347
- class KList {
15348
- constructor(items = Map2(), order = List()) {
15349
- this.items = items;
15350
- this.order = order;
15351
- this.$ = 0;
15352
- }
15353
- _clonish(items, order) {
15354
- return new KList(items, order, this.$);
15355
- }
15356
- toJS() {
15357
- return this.order.toArray().map((k) => this.items.get(k));
15358
- }
15359
- set(k, v) {
15360
- const newOrder = this.items.has(k) ? this.order : this.order.push(k);
15361
- return this._clonish(this.items.set(k, v), newOrder, this.$);
15362
- }
15363
- get(k, dval = null) {
15364
- return this.items.get(k, dval);
15365
- }
15366
- _nextFreeKey() {
15367
- let cur = this.$;
15368
- while (true) {
15369
- const key = `§${cur}§`;
15370
- if (!this.items.has(key)) {
15371
- return [key, cur];
15372
- }
15373
- cur += 1;
15374
- }
15375
- }
15376
- push(v) {
15377
- const [key, next$] = this._nextFreeKey();
15378
- const newKList = this.set(key, v);
15379
- newKList.$ = next$;
15380
- return newKList;
15381
- }
15382
- get size() {
15383
- return this.items.size;
15384
- }
15385
- delete(k) {
15386
- if (this.items.has(k)) {
15387
- const newOrder = this.order.delete(this.order.indexOf(k));
15388
- return this._clonish(this.items.delete(k), newOrder);
15389
- }
15390
- return this;
15391
- }
15392
- moveKeyBeforeKey(k1, k2) {
15393
- const { order } = this;
15394
- return this.moveKeyIndexToIndex(order.indexOf(k1), order.indexOf(k2), 0);
15395
- }
15396
- moveKeyAfterKey(k1, k2) {
15397
- const { order } = this;
15398
- return this.moveKeyIndexToIndex(order.indexOf(k1), order.indexOf(k2), 1);
15399
- }
15400
- moveKeyIndexToIndex(source, target, offset) {
15401
- if (source === -1 || target === -1 || source === target) {
15402
- return this;
15403
- }
15404
- const { order } = this;
15405
- const newPos = target + offset;
15406
- const oldPos = newPos < source ? source + 1 : source;
15407
- const newOrder = order.insert(newPos, order.get(source)).delete(oldPos);
15408
- return this._clonish(this.items, newOrder);
15409
- }
15410
- }
15411
- var klistCoercer = (_) => null;
15412
-
15413
- class CheckTypeKList {
15414
- isValid(v) {
15415
- return v instanceof KList;
15416
- }
15417
- getMessage(_v) {
15418
- return "KList expected";
15419
- }
15420
- }
15421
- var CHECK_TYPE_KLIST = new CheckTypeKList;
15422
-
15423
- class FieldKList extends Field {
15424
- constructor(name, defaultValue = new KList) {
15425
- super("KList", name, CHECK_TYPE_KLIST, klistCoercer, defaultValue);
15426
- }
15427
- extendProtoForType(proto, uname) {
15428
- extendProtoForKeyed(proto, this.name, uname);
15429
- const { name } = this;
15430
- extendProtoForKeyed(proto, name, uname);
15431
- proto[`pushIn${uname}`] = function(v) {
15432
- return this.set(name, this.get(name).push(v));
15433
- };
15434
- }
15435
- }
15436
- KList.prototype[FIELD_CLASS] = FieldKList;
15437
- KList.prototype[SEQ_INFO] = (seq, visit) => {
15438
- for (const k of seq.order)
15439
- visit(k, seq.items.get(k), "data-sk");
15440
- };
15441
15364
  // index.js
15442
15365
  var css = String.raw;
15443
15366
  var html = String.raw;
@@ -15460,15 +15383,58 @@ async function compileClassesToStyle(app, compileClasses, styleId = "margaui-css
15460
15383
  async function compileClassesToStyleText(app, compileClasses, Ctx = ParseCtxClassSetCollector) {
15461
15384
  app.ParseContext = Ctx;
15462
15385
  app.compile();
15463
- const classes = new Set;
15464
- for (const Comp of app.comps.byId.values()) {
15465
- for (const key in Comp.views) {
15466
- const view = Comp.views[key];
15467
- for (const name of view.ctx.classes)
15468
- classes.add(name);
15469
- }
15386
+ return await compileClasses(Array.from(collectAppClassesInSet(app)));
15387
+ }
15388
+ // src/util/testing.js
15389
+ var plainArrayIter = (seq, visit, start, end) => {
15390
+ const [s, e] = normalizeRange(start, end, seq.length);
15391
+ for (let i = s;i < e; i++)
15392
+ visit(i, seq[i]);
15393
+ };
15394
+ var plainMapIter = (seq, visit, start, end) => {
15395
+ const [s, e] = normalizeRange(start, end, seq.size);
15396
+ let i = 0;
15397
+ for (const [k, v] of seq.entries()) {
15398
+ if (i >= e)
15399
+ break;
15400
+ if (i >= s)
15401
+ visit(k, v);
15402
+ i++;
15470
15403
  }
15471
- return await compileClasses(Array.from(classes));
15404
+ };
15405
+ function pickIter(seq) {
15406
+ if (Array.isArray(seq))
15407
+ return plainArrayIter;
15408
+ if (seq instanceof Map)
15409
+ return plainMapIter;
15410
+ return getSeqInfo(seq);
15411
+ }
15412
+ function resolveAlter(Comp, name) {
15413
+ if (name == null)
15414
+ return null;
15415
+ const fn = Comp.alter?.[name];
15416
+ if (typeof fn !== "function") {
15417
+ throw new Error(`alter handler '${name}' not found on component '${Comp.name}'`);
15418
+ }
15419
+ return fn;
15420
+ }
15421
+ function collectIterBindings(Comp, compInstance, seq, opts = {}) {
15422
+ const whenFn = resolveAlter(Comp, opts.when) ?? filterAlwaysTrue;
15423
+ const loopWithFn = resolveAlter(Comp, opts.loopWith) ?? nullLoopWith;
15424
+ const enrichFn = resolveAlter(Comp, opts.enrichWith);
15425
+ const it = compInstance;
15426
+ const { iterData, start, end } = unpackLoopResult(loopWithFn.call(it, seq), seq);
15427
+ const out = [];
15428
+ const iter = pickIter(seq);
15429
+ iter(seq, (key, value) => {
15430
+ if (!whenFn.call(it, key, value, iterData))
15431
+ return;
15432
+ const binds = { key, value };
15433
+ if (enrichFn)
15434
+ enrichFn.call(it, binds, key, value, iterData);
15435
+ out.push(binds);
15436
+ }, start, end);
15437
+ return out;
15472
15438
  }
15473
15439
  // tools/core/docs.js
15474
15440
  function getSignature(name, fn) {
@@ -15640,62 +15606,8 @@ function docComponents(normalized, { name = null } = {}) {
15640
15606
  const picked = name === null ? comps : comps.filter((c) => c.name === name);
15641
15607
  return new ComponentDocs({ items: getComponentsDocs(picked) });
15642
15608
  }
15643
- // src/util/testing.js
15644
- var filterAlwaysTrue2 = () => true;
15645
- var nullLoopWith2 = (seq) => ({ iterData: { seq } });
15646
- var plainArrayIter = (seq, visit, start, end) => {
15647
- const [s, e] = normalizeRange(start, end, seq.length);
15648
- for (let i = s;i < e; i++)
15649
- visit(i, seq[i]);
15650
- };
15651
- var plainMapIter = (seq, visit, start, end) => {
15652
- const [s, e] = normalizeRange(start, end, seq.size);
15653
- let i = 0;
15654
- for (const [k, v] of seq.entries()) {
15655
- if (i >= e)
15656
- break;
15657
- if (i >= s)
15658
- visit(k, v);
15659
- i++;
15660
- }
15661
- };
15662
- function pickIter(seq) {
15663
- if (Array.isArray(seq))
15664
- return plainArrayIter;
15665
- if (seq instanceof Map)
15666
- return plainMapIter;
15667
- return getSeqInfo(seq);
15668
- }
15669
- function resolveAlter(Comp, name) {
15670
- if (name == null)
15671
- return null;
15672
- const fn = Comp.alter?.[name];
15673
- if (typeof fn !== "function") {
15674
- throw new Error(`alter handler '${name}' not found on component '${Comp.name}'`);
15675
- }
15676
- return fn;
15677
- }
15678
- function collectIterBindings(Comp, compInstance, seq, opts = {}) {
15679
- const whenFn = resolveAlter(Comp, opts.when) ?? filterAlwaysTrue2;
15680
- const loopWithFn = resolveAlter(Comp, opts.loopWith) ?? nullLoopWith2;
15681
- const enrichFn = resolveAlter(Comp, opts.enrichWith);
15682
- const it = compInstance;
15683
- const { iterData, start, end } = unpackLoopResult(loopWithFn.call(it, seq), seq);
15684
- const out = [];
15685
- const iter = pickIter(seq);
15686
- iter(seq, (key, value) => {
15687
- if (!whenFn.call(it, key, value, iterData))
15688
- return;
15689
- const binds = { key, value };
15690
- if (enrichFn)
15691
- enrichFn.call(it, binds, key, value, iterData);
15692
- out.push(binds);
15693
- }, start, end);
15694
- return out;
15695
- }
15696
15609
 
15697
15610
  // dev.js
15698
- use(jestMatchers);
15699
15611
  async function test3(opts = {}) {
15700
15612
  const report = await runTests({ expect, ...opts });
15701
15613
  reportTestReportToConsole(report);
@@ -15867,7 +15779,6 @@ export {
15867
15779
  LintClassCollectorCtx,
15868
15780
  LOOKUP_TARGET_MALFORMED,
15869
15781
  LOOKUP_BAD_SHAPE,
15870
- KList,
15871
15782
  Set2 as ISet,
15872
15783
  INPUT_HANDLER_NOT_REFERENCED,
15873
15784
  INPUT_HANDLER_NOT_IMPLEMENTED,