tutuca 0.10.0 → 0.11.0

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.
Files changed (48) hide show
  1. package/README.md +14 -14
  2. package/dist/immer.js +1261 -0
  3. package/dist/tutuca-cli.js +1603 -4573
  4. package/dist/tutuca-components.js +194 -424
  5. package/dist/tutuca-dev.ext.js +483 -757
  6. package/dist/tutuca-dev.js +1172 -4999
  7. package/dist/tutuca-dev.min.js +3 -3
  8. package/dist/tutuca-extra.ext.js +460 -547
  9. package/dist/tutuca-extra.js +1136 -4790
  10. package/dist/tutuca-extra.min.js +2 -2
  11. package/dist/tutuca-storybook.js +152 -143
  12. package/dist/tutuca.ext.js +460 -547
  13. package/dist/tutuca.js +1136 -4790
  14. package/dist/tutuca.min.js +2 -2
  15. package/package.json +7 -11
  16. package/skill/tutuca/SKILL.md +0 -4
  17. package/skill/tutuca/advanced.md +12 -4
  18. package/skill/tutuca/cli.md +8 -9
  19. package/skill/tutuca/component-design.md +18 -19
  20. package/skill/tutuca/core.md +83 -81
  21. package/skill/tutuca/iteration.md +2 -2
  22. package/skill/tutuca/macros.md +1 -1
  23. package/skill/tutuca/messages-and-intents.md +24 -23
  24. package/skill/tutuca/patterns/bind-text-and-attributes.md +1 -1
  25. package/skill/tutuca/patterns/conditional-attribute-value.md +1 -1
  26. package/skill/tutuca/patterns/coordinate-components.md +10 -8
  27. package/skill/tutuca/patterns/file-input.md +6 -6
  28. package/skill/tutuca/patterns/filter-and-paginate.md +1 -1
  29. package/skill/tutuca/patterns/handle-events.md +10 -8
  30. package/skill/tutuca/patterns/switch-between-views.md +1 -1
  31. package/skill/tutuca/patterns/tabbed-interface.md +10 -5
  32. package/skill/tutuca/testing.md +37 -28
  33. package/skill/tutuca-source/tutuca.ext.js +460 -547
  34. package/dist/immutable.js +0 -4331
  35. package/skill/immutable-js/SKILL.md +0 -78
  36. package/skill/immutable-js/references/collection.md +0 -346
  37. package/skill/immutable-js/references/conversions.md +0 -99
  38. package/skill/immutable-js/references/deep-updates.md +0 -172
  39. package/skill/immutable-js/references/equality.md +0 -95
  40. package/skill/immutable-js/references/list.md +0 -266
  41. package/skill/immutable-js/references/map.md +0 -300
  42. package/skill/immutable-js/references/predicates.md +0 -93
  43. package/skill/immutable-js/references/range-repeat.md +0 -55
  44. package/skill/immutable-js/references/record.md +0 -196
  45. package/skill/immutable-js/references/seq.md +0 -248
  46. package/skill/immutable-js/references/set.md +0 -270
  47. package/skill/immutable-js/references/shallow-functional.md +0 -99
  48. package/skill/immutable-js/references/stack.md +0 -210
@@ -1,8 +1,80 @@
1
- // src/value.js
2
- import { is } from "immutable";
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __copyProps = (to, from, except, desc) => {
6
+ if (from && typeof from === "object" || typeof from === "function") {
7
+ for (let key of __getOwnPropNames(from))
8
+ if (!__hasOwnProp.call(to, key) && key !== except)
9
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
10
+ }
11
+ return to;
12
+ };
13
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
14
+
15
+ // src/collection.js
16
+ var isPlainObject = (value) => {
17
+ if (value === null || typeof value !== "object") return false;
18
+ const proto = Object.getPrototypeOf(value);
19
+ return proto === Object.prototype || proto === null;
20
+ };
21
+ var seqSize = (seq) => {
22
+ if (seq == null) return 0;
23
+ if (typeof seq.length === "number") return seq.length;
24
+ if (typeof seq.size === "number") return seq.size;
25
+ return isPlainObject(seq) ? Object.keys(seq).length : 0;
26
+ };
27
+ var seqGet = (seq, key, dval = null) => {
28
+ if (seq == null) return dval;
29
+ if (seq instanceof Map) return seq.has(key) ? seq.get(key) : dval;
30
+ if (seq instanceof Set) return seq.has(key) ? key : dval;
31
+ if (Object.hasOwn(seq, key)) return seq[key];
32
+ if (typeof seq.get === "function") return seq.get(key, dval);
33
+ return dval;
34
+ };
35
+ var isIndexedSeq = (seq) => Array.isArray(seq);
36
+ var isKeyedSeq = (seq) => seq instanceof Map || isPlainObject(seq);
37
+ var isSetSeq = (seq) => seq instanceof Set;
38
+ function* seqEntries(seq) {
39
+ if (seq instanceof Map) yield* seq.entries();
40
+ else if (seq instanceof Set) for (const value of seq) yield [value, value];
41
+ else if (isPlainObject(seq)) yield* Object.entries(seq);
42
+ else if (Array.isArray(seq)) for (let i = 0; i < seq.length; i++) yield [i, seq[i]];
43
+ }
44
+
45
+ // src/immer.js
46
+ var immer_exports = {};
47
+ __reExport(immer_exports, immer_star);
48
+ import { enableMapSet } from "immer";
49
+ import * as immer_star from "immer";
50
+ enableMapSet();
3
51
 
4
52
  // src/path.js
5
53
  var NONE = /* @__PURE__ */ Symbol("NONE");
54
+ var readKey = (value, key, dval = null) => {
55
+ if (value == null) return dval;
56
+ if (value instanceof Map) return value.has(key) ? value.get(key) : dval;
57
+ if (value instanceof Set) return value.has(key) ? key : dval;
58
+ return Object.hasOwn(value, key) ? value[key] : dval;
59
+ };
60
+ var writeKey = (value, key, next) => {
61
+ if (value instanceof Map) value.set(key, next);
62
+ else if (value instanceof Set) {
63
+ value.delete(key);
64
+ value.add(next);
65
+ } else value[key] = next;
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
+ var writeSeqKey = (value, key, next) => {
73
+ if (value instanceof Map || value instanceof Set || Array.isArray(value) || Object.hasOwn(value, key))
74
+ writeKey(value, key, next);
75
+ else if (typeof value?.set === "function") value.set(key, next);
76
+ else writeKey(value, key, next);
77
+ };
6
78
  var Step = class {
7
79
  lookup(_v, dval = null) {
8
80
  return dval;
@@ -10,6 +82,8 @@ var Step = class {
10
82
  setValue(root, _v) {
11
83
  return root;
12
84
  }
85
+ setDraftValue(_root, _v) {
86
+ }
13
87
  enterFrame(stack, _prev, next) {
14
88
  return stack.enter(next, {}, true);
15
89
  }
@@ -74,10 +148,13 @@ var FieldStep = class extends Step {
74
148
  this.field = field;
75
149
  }
76
150
  lookup(v, dval = null) {
77
- return v?.get ? v.get(this.field, dval) : dval;
151
+ return readKey(v, this.field, dval);
78
152
  }
79
153
  setValue(root, v) {
80
- return root.set(this.field, v);
154
+ return (0, immer_exports.produce)(root, (draft) => this.setDraftValue(draft, v));
155
+ }
156
+ setDraftValue(root, v) {
157
+ writeKey(root, this.field, v);
81
158
  }
82
159
  withIndex(i) {
83
160
  return new SeqStep(this.field, i);
@@ -96,12 +173,14 @@ var SeqStep = class extends Step {
96
173
  this.key = key;
97
174
  }
98
175
  lookup(v, dval = null) {
99
- const o = v?.get(this.field, null);
100
- return o?.get ? o.get(this.key, dval) : dval;
176
+ return readSeqKey(readKey(v, this.field, null), this.key, dval);
101
177
  }
102
178
  setValue(root, v) {
103
- const seq = root?.get(this.field, null);
104
- return seq ? root.set(this.field, seq.set(this.key, v)) : root;
179
+ return (0, immer_exports.produce)(root, (draft) => this.setDraftValue(draft, v));
180
+ }
181
+ setDraftValue(root, v) {
182
+ const seq = readKey(root, this.field, null);
183
+ if (seq != null) writeSeqKey(seq, this.key, v);
105
184
  }
106
185
  enterFrame(stack, _prev, next) {
107
186
  return stack.enter(next, { key: this.key }, true);
@@ -117,19 +196,22 @@ var SeqAccessStep = class extends Step {
117
196
  this.keyField = keyField;
118
197
  }
119
198
  lookup(v, dval = null) {
120
- const seq = v?.get(this.seqField, NONE);
121
- const key = v?.get(this.keyField, NONE);
122
- return key !== NONE && seq?.get ? seq.get(key, dval) : dval;
199
+ const seq = readKey(v, this.seqField, NONE);
200
+ const key = readKey(v, this.keyField, NONE);
201
+ return key !== NONE && seq !== NONE ? readSeqKey(seq, key, dval) : dval;
123
202
  }
124
203
  setValue(root, v) {
125
- const seq = root?.get(this.seqField, NONE);
126
- const key = root?.get(this.keyField, NONE);
127
- return seq === NONE || key === NONE ? root : root.set(this.seqField, seq.set(key, v));
204
+ return (0, immer_exports.produce)(root, (draft) => this.setDraftValue(draft, v));
205
+ }
206
+ setDraftValue(root, v) {
207
+ const seq = readKey(root, this.seqField, NONE);
208
+ const key = readKey(root, this.keyField, NONE);
209
+ if (seq !== NONE && key !== NONE) writeSeqKey(seq, key, v);
128
210
  }
129
211
  // Resolve `keyField` against `v` now and freeze it as a literal-key `SeqStep`, so a
130
212
  // later lookup/setValue lands on this same item even if `keyField` changes meanwhile.
131
213
  pinKey(v) {
132
- const key = v?.get(this.keyField, NONE);
214
+ const key = readKey(v, this.keyField, NONE);
133
215
  return key === NONE ? this : new SeqStep(this.seqField, key);
134
216
  }
135
217
  // The key is a *field reference* resolved live, so it is unknown without a value;
@@ -310,19 +392,15 @@ var Path = class _Path {
310
392
  return out;
311
393
  }
312
394
  setValue(root, v) {
313
- const intermediates = new Array(this.steps.length);
314
- let curVal = root;
315
- for (let i = 0; i < this.steps.length; i++) {
316
- intermediates[i] = curVal;
317
- curVal = this.steps[i].lookup(curVal, NONE);
318
- if (curVal === NONE) return root;
319
- }
320
- let newVal = v;
321
- for (let i = this.steps.length - 1; i >= 0; i--) {
322
- newVal = this.steps[i].setValue(intermediates[i], newVal);
323
- intermediates[i] = newVal;
324
- }
325
- return newVal;
395
+ if (this.steps.length === 0) return v;
396
+ return (0, immer_exports.produce)(root, (draft) => {
397
+ let parent = draft;
398
+ for (let i = 0; i < this.steps.length - 1; i++) {
399
+ parent = this.steps[i].lookup(parent, NONE);
400
+ if (parent === NONE) return;
401
+ }
402
+ this.steps.at(-1).setDraftValue(parent, v);
403
+ });
326
404
  }
327
405
  buildStack(stack) {
328
406
  let prev = stack.it;
@@ -519,7 +597,8 @@ function sizeOf(v) {
519
597
  const s = v.size;
520
598
  if (typeof s === "number") return s;
521
599
  const l = v.length;
522
- return typeof l === "number" ? l : null;
600
+ if (typeof l === "number") return l;
601
+ return isPlainObject(v) ? Object.keys(v).length : null;
523
602
  }
524
603
  var predTruthy = (v) => {
525
604
  const n = sizeOf(v);
@@ -530,7 +609,7 @@ var PREDICATES = {
530
609
  "truthy?": { name: "truthy?", arity: 1, fn: predTruthy },
531
610
  "falsy?": { name: "falsy?", arity: 1, fn: (v) => !predTruthy(v) },
532
611
  "null?": { name: "null?", arity: 1, fn: (v) => v == null },
533
- "equals?": { name: "equals?", arity: 2, fn: (a, b) => is(a, b) }
612
+ "equals?": { name: "equals?", arity: 2, fn: (a, b) => Object.is(a, b) }
534
613
  };
535
614
  function parseToken(s, px) {
536
615
  const c0 = s.charCodeAt(0);
@@ -616,20 +695,28 @@ function parseMacroAttr(s, px) {
616
695
  return _parseSingle(s, px, G_ALL);
617
696
  }
618
697
  function parseReceiveHandler(s, px) {
619
- return _parseHandler(s, px, "receive", true, true);
698
+ return _parseHandler(s, px, "receive", true, true, false);
620
699
  }
621
700
  function parseAlterHandler(s, px) {
622
- const r = _parseHandler(s, px, "alter", false, false);
701
+ const r = _parseHandler(s, px, "alter", false, false, true);
623
702
  return r === null ? null : r.handlerVal;
624
703
  }
625
- function _parseHandler(s, px, namespace, allowArgs, report) {
704
+ function _parseHandler(s, px, namespace, allowArgs, report, allowMethod) {
626
705
  const tokens = tokenizeValue(s.trim());
627
706
  const headTok = tokens[0] ?? "";
628
707
  const head = headTok === "" ? null : parseToken(headTok, px);
629
708
  const hk = kindOf(head);
630
709
  let handlerVal;
631
- if (hk & K_METHOD) handlerVal = head;
632
- else if (hk & K_NAME) handlerVal = new HandlerNameVal(head.name, namespace);
710
+ if (hk & K_METHOD && allowMethod) handlerVal = head;
711
+ else if (hk & K_METHOD) {
712
+ if (report)
713
+ px.onParseIssue("event-method-handler", {
714
+ name: head.name,
715
+ role: "handler-name",
716
+ value: headTok
717
+ });
718
+ return null;
719
+ } else if (hk & K_NAME) handlerVal = new HandlerNameVal(head.name, namespace);
633
720
  else {
634
721
  if (report) px.onParseIssue("bad-value", { role: "handler-name", value: headTok });
635
722
  return null;
@@ -843,7 +930,7 @@ var BindMemberVal = class extends BindVal {
843
930
  }
844
931
  eval(stack) {
845
932
  const v = stack.lookupBind(this.name);
846
- return typeof v?.get === "function" ? v.get(this.member, null) : v?.[this.member] ?? null;
933
+ return seqGet(v, this.member, null);
847
934
  }
848
935
  toString() {
849
936
  return `@${this.name}.${this.member}`;
@@ -890,7 +977,7 @@ var SeqAccessVal = class extends RenderVal {
890
977
  }
891
978
  eval(stack) {
892
979
  const key = this.keyVal.eval(stack);
893
- return this.seqVal.eval(stack)?.get(key, null);
980
+ return seqGet(this.seqVal.eval(stack), key, null);
894
981
  }
895
982
  toString() {
896
983
  return `${this.seqVal}[${this.keyVal}]`;
@@ -1170,9 +1257,6 @@ var IntentHandler = class {
1170
1257
  }
1171
1258
  };
1172
1259
 
1173
- // src/renderer.js
1174
- import { isIndexed, isKeyed } from "immutable";
1175
-
1176
1260
  // src/cache.js
1177
1261
  var isWeakKey = (k) => k !== null && (typeof k === "object" || typeof k === "function");
1178
1262
  var NullDomCache = class {
@@ -1669,7 +1753,7 @@ var Renderer = class {
1669
1753
  this.cache.set(cachePath, cacheKey, dom);
1670
1754
  }
1671
1755
  };
1672
- if (keys) imKeysIter(seq, renderOne, keys);
1756
+ if (keys) keysIter(seq, renderOne, keys);
1673
1757
  else
1674
1758
  getSeqInfo(seq)(
1675
1759
  seq,
@@ -1703,7 +1787,7 @@ var Renderer = class {
1703
1787
  return new VFragment([this._renderMetadata({ $: "Scope", nid }), dom]);
1704
1788
  }
1705
1789
  };
1706
- var getSeqInfo = (seq) => isIndexed(seq) ? imIndexedIter : isKeyed(seq) ? imKeyedIter : seq?.[SEQ_INFO] ?? unkIter;
1790
+ var getSeqInfo = (seq) => isIndexedSeq(seq) ? nativeIndexedIter : isKeyedSeq(seq) || isSetSeq(seq) ? nativeKeyedIter : seq?.[SEQ_INFO] ?? unkIter;
1707
1791
  var normalizeRange = (start, end, size) => {
1708
1792
  let s = start == null ? 0 : start < 0 ? size + start : start;
1709
1793
  let e = end == null ? size : end < 0 ? size + end : end;
@@ -1726,22 +1810,22 @@ var unpackLoopResult = (result, seq) => {
1726
1810
  const r = result ?? {};
1727
1811
  return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end, keys: r.keys };
1728
1812
  };
1729
- var imKeysIter = (seq, visit, keys) => {
1730
- const attrName = isIndexed(seq) ? "si" : "sk";
1731
- for (const key of keys) visit(key, seq.get(key), attrName);
1813
+ var keysIter = (seq, visit, keys) => {
1814
+ const attrName = isIndexedSeq(seq) ? "si" : "sk";
1815
+ for (const key of keys) visit(key, seqGet(seq, key), attrName);
1732
1816
  };
1733
1817
  var makeLoopCtx = (stack, filter) => ({
1734
1818
  lookup: (name) => stack.lookupBind(name),
1735
1819
  filter: (key, value, iterData) => filter.call(stack.it, key, value, iterData)
1736
1820
  });
1737
- var imIndexedIter = (seq, visit, start, end) => {
1738
- const [s, e] = normalizeRange(start, end, seq.size);
1739
- for (let i = s; i < e; i++) visit(i, seq.get(i), "si");
1821
+ var nativeIndexedIter = (seq, visit, start, end) => {
1822
+ const [s, e] = normalizeRange(start, end, seqSize(seq));
1823
+ for (let i = s; i < e; i++) visit(i, seq[i], "si");
1740
1824
  };
1741
- var imKeyedIter = (seq, visit, start, end) => {
1742
- const [s, e] = normalizeRange(start, end, seq.size);
1825
+ var nativeKeyedIter = (seq, visit, start, end) => {
1826
+ const [s, e] = normalizeRange(start, end, seqSize(seq));
1743
1827
  let i = 0;
1744
- for (const [k, v] of seq.toSeq().entries()) {
1828
+ for (const [k, v] of seqEntries(seq)) {
1745
1829
  if (i >= e) break;
1746
1830
  if (i >= s) visit(k, v, "sk");
1747
1831
  i++;
@@ -2261,7 +2345,7 @@ var IterInfo = class {
2261
2345
  // { key, value }, then run @enrich-with (with @loop-with's iterData) if any.
2262
2346
  enrichBinds(stack, key) {
2263
2347
  const { seq, filter, loopWith, enricher } = this.eval(stack);
2264
- const value = seq?.get ? seq.get(key, null) : null;
2348
+ const value = seqGet(seq, key, null);
2265
2349
  const binds = { key, value };
2266
2350
  if (enricher) {
2267
2351
  const { iterData } = unpackLoopResult(
@@ -2759,12 +2843,12 @@ var Stack = class _Stack {
2759
2843
  const provide = this.comps.getCompFor(this.it)?.provide;
2760
2844
  if (provide == null) return this;
2761
2845
  const dynObj = {};
2762
- let has2 = false;
2846
+ let has = false;
2763
2847
  for (const k in provide) {
2764
2848
  dynObj[provide[k].symbol] = provide[k].val.eval(this);
2765
- has2 = true;
2849
+ has = true;
2766
2850
  }
2767
- if (!has2) return this;
2851
+ if (!has) return this;
2768
2852
  const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
2769
2853
  const { comps, it, binds, views, viewsId, ctx } = this;
2770
2854
  return new _Stack(comps, it, binds, newDynBinds, views, viewsId, ctx);
@@ -2835,6 +2919,316 @@ var Stack = class _Stack {
2835
2919
  }
2836
2920
  };
2837
2921
 
2922
+ // src/oo.js
2923
+ var BAD_VALUE = /* @__PURE__ */ Symbol("BadValue");
2924
+ var nullCoercer = (v) => v;
2925
+ var isPlainObject2 = (v) => {
2926
+ if (v === null || typeof v !== "object") return false;
2927
+ const proto = Object.getPrototypeOf(v);
2928
+ return proto === Object.prototype || proto === null;
2929
+ };
2930
+ function defaultToData(v) {
2931
+ if (v instanceof Map) return [...v.entries()];
2932
+ if (v instanceof Set) return [...v.values()];
2933
+ return v;
2934
+ }
2935
+ var Field = class {
2936
+ constructor(type, name, typeCheck, coercer, defaultValue = null) {
2937
+ this.type = type;
2938
+ this.name = name;
2939
+ this.typeCheck = typeCheck;
2940
+ this.coercer = coercer;
2941
+ this.checks = [];
2942
+ this.defaultValue = defaultValue;
2943
+ }
2944
+ toDataDef() {
2945
+ return { type: this.type, defaultValue: defaultToData(this.defaultValue) };
2946
+ }
2947
+ getFirstFailingCheck(v) {
2948
+ if (!this.typeCheck.isValid(v)) return this.typeCheck;
2949
+ for (const check3 of this.checks) if (!check3.isValid(v)) return check3;
2950
+ return null;
2951
+ }
2952
+ isValid(v) {
2953
+ return this.getFirstFailingCheck(v) === null;
2954
+ }
2955
+ addCheck(check3) {
2956
+ this.checks.push(check3);
2957
+ return this;
2958
+ }
2959
+ coerceOr(v, defaultValue = null) {
2960
+ if (this.isValid(v)) return v;
2961
+ const v1 = this.coercer(v);
2962
+ return this.isValid(v1) ? v1 : defaultValue;
2963
+ }
2964
+ coerceOrDefault(v) {
2965
+ return this.coerceOr(v, this.defaultValue);
2966
+ }
2967
+ };
2968
+ var Check = class {
2969
+ isValid(_v) {
2970
+ return true;
2971
+ }
2972
+ getMessage(_v) {
2973
+ return "Invalid";
2974
+ }
2975
+ };
2976
+ var CheckTypeAny = class extends Check {
2977
+ };
2978
+ var CHECK_TYPE_ANY = new CheckTypeAny();
2979
+ var FnCheck = class extends Check {
2980
+ constructor(isValidFn, getMessageFn) {
2981
+ super();
2982
+ this._isValid = isValidFn;
2983
+ this._getMessage = getMessageFn;
2984
+ }
2985
+ isValid(v) {
2986
+ return this._isValid(v);
2987
+ }
2988
+ getMessage(v) {
2989
+ return this._getMessage(v);
2990
+ }
2991
+ };
2992
+ var check = (fn, message) => new FnCheck(fn, () => message);
2993
+ var CHECK_TYPE_INT = check(Number.isInteger, "Integer expected");
2994
+ var CHECK_TYPE_FLOAT = check(Number.isFinite, "Float expected");
2995
+ var CHECK_TYPE_BOOL = check((v) => typeof v === "boolean", "Boolean expected");
2996
+ var CHECK_TYPE_STRING = check((v) => typeof v === "string", "String expected");
2997
+ var CHECK_TYPE_LIST = check(Array.isArray, "Array expected");
2998
+ var CHECK_TYPE_OBJECT = check(isPlainObject2, "Plain object expected");
2999
+ var CHECK_TYPE_MAP = check((v) => v instanceof Map, "Map expected");
3000
+ var CHECK_TYPE_SET = check((v) => v instanceof Set, "Set expected");
3001
+ var FieldBool = class extends Field {
3002
+ constructor(name, defaultValue = false) {
3003
+ super("bool", name, CHECK_TYPE_BOOL, (v) => !!v, defaultValue);
3004
+ }
3005
+ };
3006
+ var FieldAny = class extends Field {
3007
+ constructor(name, defaultValue = null) {
3008
+ super("any", name, CHECK_TYPE_ANY, nullCoercer, defaultValue);
3009
+ }
3010
+ toDataDef() {
3011
+ return { type: getTypeName(this.defaultValue) ?? "any", defaultValue: this.defaultValue };
3012
+ }
3013
+ };
3014
+ var FieldString = class extends Field {
3015
+ constructor(name, defaultValue = "") {
3016
+ super("text", name, CHECK_TYPE_STRING, (v) => v?.toString?.() ?? "", defaultValue);
3017
+ }
3018
+ };
3019
+ var FieldInt = class extends Field {
3020
+ constructor(name, defaultValue = 0) {
3021
+ super(
3022
+ "int",
3023
+ name,
3024
+ CHECK_TYPE_INT,
3025
+ (v) => Number.isFinite(v) ? Math.trunc(v) : null,
3026
+ defaultValue
3027
+ );
3028
+ }
3029
+ };
3030
+ var FieldFloat = class extends Field {
3031
+ constructor(name, defaultValue = 0) {
3032
+ super("float", name, CHECK_TYPE_FLOAT, (_) => null, defaultValue);
3033
+ }
3034
+ };
3035
+ var getTypeName = (v) => v?.constructor?.getMetaClass?.()?.name;
3036
+ var CheckTypeName = class {
3037
+ constructor(typeName) {
3038
+ this.typeName = typeName;
3039
+ }
3040
+ isValid(v) {
3041
+ return getTypeName(v) === this.typeName;
3042
+ }
3043
+ getMessage(v) {
3044
+ return `Expected "${this.typeName}", got "${getTypeName(v)}"`;
3045
+ }
3046
+ };
3047
+ var FieldComp = class extends Field {
3048
+ constructor(type, name, args) {
3049
+ super(type, name, new CheckTypeName(type), nullCoercer, null);
3050
+ this.args = args;
3051
+ }
3052
+ toDataDef() {
3053
+ return { component: this.type, args: this.args };
3054
+ }
3055
+ };
3056
+ var FieldList = class extends Field {
3057
+ constructor(name, defaultValue = []) {
3058
+ super("list", name, CHECK_TYPE_LIST, (v) => Array.isArray(v) ? [...v] : null, defaultValue);
3059
+ }
3060
+ };
3061
+ var FieldObject = class extends Field {
3062
+ constructor(name, defaultValue = {}) {
3063
+ super(
3064
+ "object",
3065
+ name,
3066
+ CHECK_TYPE_OBJECT,
3067
+ (v) => isPlainObject2(v) ? { ...v } : null,
3068
+ defaultValue
3069
+ );
3070
+ }
3071
+ };
3072
+ var FieldMap = class extends Field {
3073
+ constructor(name, defaultValue = /* @__PURE__ */ new Map()) {
3074
+ super(
3075
+ "map",
3076
+ name,
3077
+ CHECK_TYPE_MAP,
3078
+ (v) => {
3079
+ if (v instanceof Map) return new Map(v);
3080
+ if (Array.isArray(v) || isPlainObject2(v))
3081
+ return new Map(Array.isArray(v) ? v : Object.entries(v));
3082
+ return null;
3083
+ },
3084
+ defaultValue
3085
+ );
3086
+ }
3087
+ };
3088
+ var FieldSet = class extends Field {
3089
+ constructor(name, defaultValue = /* @__PURE__ */ new Set()) {
3090
+ super(
3091
+ "set",
3092
+ name,
3093
+ CHECK_TYPE_SET,
3094
+ (v) => v instanceof Set || Array.isArray(v) ? new Set(v) : null,
3095
+ defaultValue
3096
+ );
3097
+ }
3098
+ };
3099
+ function mkCompField(field, scope, args) {
3100
+ const Comp = scope?.lookupComponent(field.type) ?? null;
3101
+ if (Comp === null)
3102
+ console.warn(
3103
+ scope ? `component field "${field.name}": component "${field.type}" not found in scope` : `component field "${field.name}": cannot resolve component "${field.type}" — built without a registered scope (use ${field.type}.make({}) as the default, or build via a registered component)`
3104
+ );
3105
+ return Comp?.make({ ...field.args, ...args }, { scope }) ?? null;
3106
+ }
3107
+ var ClassBuilder = class {
3108
+ constructor(name) {
3109
+ this.name = name;
3110
+ this.fields = {};
3111
+ this.compFields = /* @__PURE__ */ new Set();
3112
+ this._methods = {};
3113
+ this._statics = {};
3114
+ }
3115
+ build() {
3116
+ const { name, fields, compFields, _methods } = this;
3117
+ const defaults = Object.fromEntries(
3118
+ Object.entries(fields).map(([fieldName, field]) => [fieldName, field.defaultValue])
3119
+ );
3120
+ const Class = {
3121
+ [name]: class {
3122
+ constructor(values = {}) {
3123
+ Object.assign(this, defaults, values);
3124
+ }
3125
+ }
3126
+ }[name];
3127
+ Class[immer_exports.immerable] = true;
3128
+ Object.assign(Class.prototype, _methods);
3129
+ const metaClass = { fields, name, methods: _methods };
3130
+ Object.assign(
3131
+ Class,
3132
+ {
3133
+ getMetaClass: () => metaClass,
3134
+ make(inArgs = {}, opts = {}) {
3135
+ const args = {};
3136
+ const scope = opts.scope ?? this.scope;
3137
+ for (const key in inArgs) {
3138
+ const field = fields[key];
3139
+ if (compFields.has(key)) args[key] = mkCompField(field, scope, inArgs[key]);
3140
+ else if (field === void 0)
3141
+ console.warn("extra argument to constructor:", name, key, inArgs);
3142
+ else args[key] = field.coerceOrDefault(inArgs[key]);
3143
+ }
3144
+ for (const key of compFields)
3145
+ if (args[key] === void 0) args[key] = mkCompField(fields[key], scope, inArgs[key]);
3146
+ return (0, immer_exports.freeze)(new this(args), true);
3147
+ }
3148
+ },
3149
+ this._statics
3150
+ );
3151
+ return Class;
3152
+ }
3153
+ methods(proto) {
3154
+ for (const k in proto) this._methods[k] = proto[k];
3155
+ }
3156
+ statics(proto) {
3157
+ for (const k in proto) this._statics[k] = proto[k];
3158
+ }
3159
+ addField(name, dval, FieldCls) {
3160
+ const field = new FieldCls(name, dval);
3161
+ this.fields[name] = field;
3162
+ return field;
3163
+ }
3164
+ addCompField(name, type, args) {
3165
+ const field = new FieldComp(type, name, args);
3166
+ this.compFields.add(name);
3167
+ this.fields[name] = field;
3168
+ return field;
3169
+ }
3170
+ };
3171
+ var FIELD_CLASS = /* @__PURE__ */ Symbol.for("tutuca.fieldClass");
3172
+ var fieldsByTypeName = {
3173
+ text: FieldString,
3174
+ int: FieldInt,
3175
+ float: FieldFloat,
3176
+ bool: FieldBool,
3177
+ list: FieldList,
3178
+ object: FieldObject,
3179
+ map: FieldMap,
3180
+ set: FieldSet,
3181
+ any: FieldAny
3182
+ };
3183
+ function fieldFromDescriptor(name, value) {
3184
+ const FieldCls = fieldsByTypeName[value.type] ?? FieldAny;
3185
+ const probe = new FieldCls(name);
3186
+ return [FieldCls, probe.coerceOr(value.defaultValue, probe.defaultValue)];
3187
+ }
3188
+ function classFromData(name, { fields = {}, methods, statics }) {
3189
+ const b = new ClassBuilder(name);
3190
+ for (const field in fields) {
3191
+ const value = fields[field];
3192
+ const type = typeof value;
3193
+ if (type === "string") b.addField(field, value, FieldString);
3194
+ else if (type === "number")
3195
+ b.addField(field, value, Number.isInteger(value) ? FieldInt : FieldFloat);
3196
+ else if (type === "boolean") b.addField(field, value, FieldBool);
3197
+ else if (Array.isArray(value)) b.addField(field, [...value], FieldList);
3198
+ else if (value instanceof Set) b.addField(field, new Set(value), FieldSet);
3199
+ else if (value instanceof Map) b.addField(field, new Map(value), FieldMap);
3200
+ else if (value?.type && Object.hasOwn(value, "defaultValue")) {
3201
+ const [FieldCls, dval] = fieldFromDescriptor(field, value);
3202
+ b.addField(field, dval, FieldCls);
3203
+ } else if (value?.component && value?.args !== void 0)
3204
+ b.addCompField(field, value.component, value.args);
3205
+ else if (isPlainObject2(value)) b.addField(field, { ...value }, FieldObject);
3206
+ else {
3207
+ const FieldCls = value?.[FIELD_CLASS] ?? FieldAny;
3208
+ b.addField(field, value, FieldCls);
3209
+ }
3210
+ }
3211
+ if (methods) b.methods(methods);
3212
+ if (statics) b.statics(statics);
3213
+ return b.build();
3214
+ }
3215
+ function validateDraftFields(current, draft) {
3216
+ const meta = current?.constructor?.getMetaClass?.();
3217
+ if (!meta) return;
3218
+ for (const [name, field] of Object.entries(meta.fields)) {
3219
+ const value = draft[name];
3220
+ if (field.isValid(value)) continue;
3221
+ const coerced = field.coerceOr(value, BAD_VALUE);
3222
+ if (coerced !== BAD_VALUE) draft[name] = coerced;
3223
+ else {
3224
+ console.warn(`invalid value for ${meta.name}.${name}`, value);
3225
+ draft[name] = current[name];
3226
+ }
3227
+ }
3228
+ }
3229
+ Component.fromSpec = (opts) => new Component(classFromData(opts.name, opts), opts);
3230
+ var component = (opts) => Component.fromSpec(opts);
3231
+
2838
3232
  // src/transactor.js
2839
3233
  var State = class {
2840
3234
  constructor(val) {
@@ -3022,10 +3416,10 @@ var Transaction = class {
3022
3416
  get observeName() {
3023
3417
  return null;
3024
3418
  }
3025
- callHandler(root, instance, comps) {
3419
+ callHandler(root, instance, draft, comps) {
3026
3420
  const [handler, args] = this.getHandlerAndArgs(root, instance, comps);
3027
3421
  this._resolvedHandler = handler;
3028
- return handler.apply(instance, args);
3422
+ return handler.apply(instance, [draft, ...args]);
3029
3423
  }
3030
3424
  getHandlerAndArgs(_root, _instance, _comps) {
3031
3425
  return null;
@@ -3034,12 +3428,16 @@ var Transaction = class {
3034
3428
  // the data's real location (the dispatch `this.path` keeps intermediates). A subclass
3035
3429
  // may override to supply a pre-resolved path (see ResponseEvent's pinned keys).
3036
3430
  getTransactionPath() {
3037
- return this.path.toTransactionPath();
3431
+ return this.path.toTransactionPath().compact();
3038
3432
  }
3039
3433
  updateRootValue(curRoot, comps) {
3040
3434
  const txnPath = this.getTransactionPath();
3041
3435
  const curLeaf = txnPath.lookup(curRoot);
3042
- const newLeaf = this.callHandler(curRoot, curLeaf, comps);
3436
+ const newLeaf = (0, immer_exports.produce)(curLeaf, (draft) => {
3437
+ const result = this.callHandler(curRoot, curLeaf, draft, comps);
3438
+ if (result === void 0 || result === draft) validateDraftFields(curLeaf, draft);
3439
+ return result;
3440
+ });
3043
3441
  this._before = curLeaf;
3044
3442
  this._after = newLeaf;
3045
3443
  this._completion?.markSelfSettled({ value: newLeaf, old: curLeaf });
@@ -3846,61 +4244,6 @@ function collectAppClassesInSet(app) {
3846
4244
  return classes;
3847
4245
  }
3848
4246
 
3849
- // index.js
3850
- import {
3851
- Collection,
3852
- fromJS,
3853
- get,
3854
- getIn,
3855
- has,
3856
- hash,
3857
- hasIn,
3858
- is as is2,
3859
- isAssociative,
3860
- isCollection,
3861
- isImmutable,
3862
- isIndexed as isIndexed2,
3863
- isKeyed as isKeyed2,
3864
- isList,
3865
- isMap,
3866
- isMap as isMap2,
3867
- isOrdered,
3868
- isOrderedMap,
3869
- isOrderedMap as isOrderedMap2,
3870
- isOrderedSet,
3871
- isPlainObject,
3872
- isRecord,
3873
- isSeq,
3874
- isSet,
3875
- isStack,
3876
- isValueObject,
3877
- List as List2,
3878
- Map as Map2,
3879
- Map as Map3,
3880
- merge,
3881
- mergeDeep,
3882
- mergeDeepWith,
3883
- mergeWith,
3884
- OrderedMap as OrderedMap2,
3885
- OrderedMap as OrderedMap3,
3886
- OrderedSet,
3887
- PairSorting,
3888
- Range,
3889
- Record as Record2,
3890
- Repeat,
3891
- remove,
3892
- removeIn,
3893
- Seq,
3894
- Set as Set2,
3895
- Set as Set3,
3896
- Stack as Stack2,
3897
- set,
3898
- setIn,
3899
- update,
3900
- updateIn,
3901
- version
3902
- } from "immutable";
3903
-
3904
4247
  // src/on.js
3905
4248
  var OP_KINDS = ["send", "intent"];
3906
4249
  function phaseOps(phase) {
@@ -3927,390 +4270,11 @@ function dispatchPhase(dispatcher, targetPath, phase, self) {
3927
4270
  }
3928
4271
  }
3929
4272
 
3930
- // src/oo.js
3931
- import { Map as IMap, Set as ISet, List, OrderedMap, Record } from "immutable";
3932
- var BAD_VALUE = /* @__PURE__ */ Symbol("BadValue");
3933
- var nullCoercer = (v) => v;
3934
- var Field = class {
3935
- constructor(type, name, typeCheck, coercer, defaultValue = null) {
3936
- this.type = type;
3937
- this.name = name;
3938
- this.typeCheck = typeCheck;
3939
- this.coercer = coercer;
3940
- this.checks = [];
3941
- this.defaultValue = defaultValue;
3942
- }
3943
- toDataDef() {
3944
- const { type, defaultValue: dv } = this;
3945
- return { type, defaultValue: dv?.toJS ? dv.toJS() : dv };
3946
- }
3947
- getFirstFailingCheck(v) {
3948
- if (!this.typeCheck.isValid(v)) return this.typeCheck;
3949
- for (const check2 of this.checks) if (!check2.isValid(v)) return check2;
3950
- return null;
3951
- }
3952
- isValid(v) {
3953
- return this.getFirstFailingCheck(v) === null;
3954
- }
3955
- addCheck(check2) {
3956
- this.checks.push(check2);
3957
- return this;
3958
- }
3959
- coerceOr(v, defaultValue = null) {
3960
- if (this.isValid(v)) return v;
3961
- const v1 = this.coercer(v);
3962
- return this.isValid(v1) ? v1 : defaultValue;
3963
- }
3964
- coerceOrDefault(v) {
3965
- return this.coerceOr(v, this.defaultValue);
3966
- }
3967
- extendProtoForType(_proto, _uname) {
3968
- }
3969
- extendProto(proto) {
3970
- const { name } = this;
3971
- const uname = name[0].toUpperCase() + name.slice(1);
3972
- const setName = `set${uname}`;
3973
- const that = this;
3974
- proto[setName] = function(v) {
3975
- const v1 = that.coerceOr(v, BAD_VALUE);
3976
- if (v1 === BAD_VALUE) {
3977
- console.warn("invalid value", v);
3978
- return this;
3979
- }
3980
- return this.set(name, v1);
3981
- };
3982
- proto[`update${uname}`] = function(fn) {
3983
- return this[setName](fn(this.get(name)));
3984
- };
3985
- proto[`reset${uname}`] = function() {
3986
- return this.set(name, that.defaultValue);
3987
- };
3988
- this.extendProtoForType(proto, uname);
3989
- }
3990
- };
3991
- var Check = class {
3992
- isValid(_v) {
3993
- return true;
3994
- }
3995
- getMessage(_v) {
3996
- return "Invalid";
3997
- }
3998
- };
3999
- var CheckTypeAny = class extends Check {
4000
- };
4001
- var CHECK_TYPE_ANY = new CheckTypeAny();
4002
- var FnCheck = class extends Check {
4003
- constructor(isValidFn, getMessageFn) {
4004
- super();
4005
- this._isValid = isValidFn;
4006
- this._getMessage = getMessageFn;
4007
- }
4008
- isValid(v) {
4009
- return this._isValid(v);
4010
- }
4011
- getMessage(v) {
4012
- return this._getMessage(v);
4013
- }
4014
- };
4015
- var CHECK_TYPE_INT = new FnCheck(
4016
- (v) => Number.isInteger(v),
4017
- () => "Integer expected"
4018
- );
4019
- var CHECK_TYPE_FLOAT = new FnCheck(
4020
- (v) => Number.isFinite(v),
4021
- () => "Float expected"
4022
- );
4023
- var CHECK_TYPE_BOOL = new FnCheck(
4024
- (v) => typeof v === "boolean",
4025
- () => "Boolean expected"
4026
- );
4027
- var CHECK_TYPE_STRING = new FnCheck(
4028
- (v) => typeof v === "string",
4029
- () => "String expected"
4030
- );
4031
- var CHECK_TYPE_LIST = new FnCheck(
4032
- (v) => List.isList(v),
4033
- () => "List expected"
4034
- );
4035
- var CHECK_TYPE_MAP = new FnCheck(
4036
- (v) => IMap.isMap(v),
4037
- () => "Map expected"
4038
- );
4039
- var CHECK_TYPE_OMAP = new FnCheck(
4040
- (v) => OrderedMap.isOrderedMap(v),
4041
- () => "OrderedMap expected"
4042
- );
4043
- var CHECK_TYPE_SET = new FnCheck(
4044
- (v) => ISet.isSet(v),
4045
- () => "Set expected"
4046
- );
4047
- var boolCoercer = (v) => !!v;
4048
- var FieldBool = class extends Field {
4049
- constructor(name, defaultValue = false) {
4050
- super("bool", name, CHECK_TYPE_BOOL, boolCoercer, defaultValue);
4051
- }
4052
- extendProtoForType(proto, uname) {
4053
- const { name } = this;
4054
- proto[`toggle${uname}`] = function() {
4055
- return this.set(name, !this.get(name, false));
4056
- };
4057
- proto[`set${uname}`] = function(v) {
4058
- return this.set(name, !!v);
4059
- };
4060
- }
4061
- };
4062
- var FieldAny = class extends Field {
4063
- constructor(name, defaultValue = null) {
4064
- super("any", name, CHECK_TYPE_ANY, nullCoercer, defaultValue);
4065
- }
4066
- toDataDef() {
4067
- const { defaultValue: dv } = this;
4068
- const type = getTypeName(dv) ?? "any";
4069
- return { type, defaultValue: dv?.toJS ? dv.toJS() : dv };
4070
- }
4071
- };
4072
- var stringCoercer = (v) => v?.toString?.() ?? "";
4073
- var FieldString = class extends Field {
4074
- constructor(name, defaultValue = "") {
4075
- super("text", name, CHECK_TYPE_STRING, stringCoercer, defaultValue);
4076
- }
4077
- extendProtoForType(proto, _uname) {
4078
- extendProtoSized(proto, this.name, "", "length");
4079
- }
4080
- };
4081
- var intCoercer = (v) => Number.isFinite(v) ? Math.trunc(v) : null;
4082
- var FieldInt = class extends Field {
4083
- constructor(name, defaultValue = 0) {
4084
- super("int", name, CHECK_TYPE_INT, intCoercer, defaultValue);
4085
- }
4086
- };
4087
- var floatCoercer = (_) => null;
4088
- var FieldFloat = class extends Field {
4089
- constructor(name, defaultValue = 0) {
4090
- super("float", name, CHECK_TYPE_FLOAT, floatCoercer, defaultValue);
4091
- }
4092
- };
4093
- var getTypeName = (v) => v?.constructor?.getMetaClass?.()?.name;
4094
- var CheckTypeName = class {
4095
- constructor(typeName) {
4096
- this.typeName = typeName;
4097
- }
4098
- isValid(v) {
4099
- return getTypeName(v) === this.typeName;
4100
- }
4101
- getMessage(v) {
4102
- const got = getTypeName(v);
4103
- return `Expected "${this.typeName}", got "${got}"`;
4104
- }
4105
- };
4106
- var FieldComp = class extends Field {
4107
- constructor(type, name, args) {
4108
- super(type, name, new CheckTypeName(type), nullCoercer, null);
4109
- this.args = args;
4110
- }
4111
- toDataDef() {
4112
- return { component: this.typeName, args: this.args };
4113
- }
4114
- };
4115
- var NONE2 = /* @__PURE__ */ Symbol("NONE");
4116
- function extendProtoForKeyed(proto, name, uname) {
4117
- extendProtoSized(proto, name, EMPTY_LIST);
4118
- proto[`setIn${uname}At`] = function(i, v) {
4119
- return this.set(name, this.get(name).set(i, v));
4120
- };
4121
- proto[`getIn${uname}At`] = function(i, dval) {
4122
- return this.get(name).get(i, dval);
4123
- };
4124
- proto[`updateIn${uname}At`] = function(i, fn) {
4125
- const col = this.get(name);
4126
- const v = col.get(i, NONE2);
4127
- if (v !== NONE2) return this.set(name, col.set(i, fn(v)));
4128
- console.warn("key", i, "not found in", name, col);
4129
- return this;
4130
- };
4131
- extendDeleteInAt(proto, name, `${uname}At`);
4132
- }
4133
- function extendDeleteInAt(proto, name, uname) {
4134
- proto[`deleteIn${uname}`] = function(v) {
4135
- return this.set(name, this.get(name).delete(v));
4136
- };
4137
- proto[`removeIn${uname}`] = proto[`deleteIn${uname}`];
4138
- }
4139
- var EMPTY_LIST = List();
4140
- var listCoercer = (v) => Array.isArray(v) ? List(v) : null;
4141
- var FieldList = class extends Field {
4142
- constructor(name, defaultValue = EMPTY_LIST) {
4143
- super("list", name, CHECK_TYPE_LIST, listCoercer, defaultValue);
4144
- }
4145
- extendProtoForType(proto, uname) {
4146
- const { name } = this;
4147
- extendProtoForKeyed(proto, name, uname);
4148
- proto[`pushIn${uname}`] = function(v) {
4149
- return this.set(name, this.get(name).push(v));
4150
- };
4151
- proto[`insertIn${uname}At`] = function(i, v) {
4152
- return this.set(name, this.get(name).insert(i, v));
4153
- };
4154
- }
4155
- };
4156
- var imapCoercer = (v) => IMap(v);
4157
- var FieldMap = class extends Field {
4158
- constructor(name, defaultValue = IMap()) {
4159
- super("map", name, CHECK_TYPE_MAP, imapCoercer, defaultValue);
4160
- }
4161
- extendProtoForType(proto, uname) {
4162
- extendProtoForKeyed(proto, this.name, uname);
4163
- }
4164
- };
4165
- var omapCoercer = (v) => OrderedMap(v);
4166
- var FieldOMap = class extends Field {
4167
- constructor(name, defaultValue = OrderedMap()) {
4168
- super("omap", name, CHECK_TYPE_OMAP, omapCoercer, defaultValue);
4169
- }
4170
- extendProtoForType(proto, uname) {
4171
- extendProtoForKeyed(proto, this.name, uname);
4172
- }
4173
- };
4174
- function extendProtoSized(proto, name, defaultEmpty, propName = "size") {
4175
- proto[`${name}Len`] = function() {
4176
- return this.get(name, defaultEmpty)[propName];
4177
- };
4178
- }
4179
- var EMPTY_SET = ISet();
4180
- var isetCoercer = (v) => Array.isArray(v) ? ISet(v) : v instanceof Set ? ISet(v) : null;
4181
- var FieldSet = class extends Field {
4182
- constructor(name, defaultValue = EMPTY_SET) {
4183
- super("set", name, CHECK_TYPE_SET, isetCoercer, defaultValue);
4184
- }
4185
- extendProtoForType(proto, uname) {
4186
- const { name } = this;
4187
- extendProtoSized(proto, name, EMPTY_SET);
4188
- proto[`addIn${uname}`] = function(v) {
4189
- return this.set(name, this.get(name).add(v));
4190
- };
4191
- extendDeleteInAt(proto, name, uname);
4192
- proto[`hasIn${uname}`] = function(v) {
4193
- return this.get(name).has(v);
4194
- };
4195
- proto[`toggleIn${uname}`] = function(v) {
4196
- const current = this.get(name);
4197
- return this.set(name, current.has(v) ? current.delete(v) : current.add(v));
4198
- };
4199
- }
4200
- };
4201
- function mkCompField(field, scope, args) {
4202
- const Comp = scope?.lookupComponent(field.type) ?? null;
4203
- if (Comp === null)
4204
- console.warn(
4205
- scope ? `component field "${field.name}": component "${field.type}" not found in scope` : `component field "${field.name}": cannot resolve component "${field.type}" — built without a registered scope (use ${field.type}.make({}) as the default, or build via a registered component)`
4206
- );
4207
- return Comp?.make({ ...field.args, ...args }, { scope }) ?? null;
4208
- }
4209
- var ClassBuilder = class {
4210
- constructor(name) {
4211
- const fields = {};
4212
- const compFields = /* @__PURE__ */ new Set();
4213
- this.name = name;
4214
- this.fields = fields;
4215
- this.compFields = compFields;
4216
- this._methods = {};
4217
- this._statics = {
4218
- make: function(inArgs = {}, opts = {}) {
4219
- const args = {};
4220
- const scope = opts.scope ?? this.scope;
4221
- for (const key in inArgs) {
4222
- const field = fields[key];
4223
- if (compFields.has(key)) args[key] = mkCompField(field, scope, inArgs[key]);
4224
- else if (field === void 0)
4225
- console.warn("extra argument to constructor:", name, key, inArgs);
4226
- else args[key] = field.coerceOrDefault(inArgs[key]);
4227
- }
4228
- for (const key of compFields)
4229
- if (args[key] === void 0) args[key] = mkCompField(fields[key], scope, inArgs[key]);
4230
- return this(args);
4231
- }
4232
- };
4233
- }
4234
- build() {
4235
- const fieldVals = {};
4236
- const proto = {};
4237
- const { name, _methods, fields } = this;
4238
- for (const fieldName in fields) {
4239
- const field = fields[fieldName];
4240
- fieldVals[fieldName] = field.defaultValue;
4241
- field.extendProto(proto);
4242
- }
4243
- const Class = { [name]: Record(fieldVals, name) }[name];
4244
- Object.assign(Class.prototype, proto, _methods);
4245
- const metaClass = { fields, name, methods: _methods };
4246
- Object.assign(Class, this._statics, { getMetaClass: () => metaClass });
4247
- return Class;
4248
- }
4249
- methods(proto) {
4250
- for (const k in proto) this._methods[k] = proto[k];
4251
- }
4252
- statics(proto) {
4253
- for (const k in proto) this._statics[k] = proto[k];
4254
- }
4255
- addField(name, dval, FieldCls) {
4256
- const field = new FieldCls(name, dval);
4257
- this.fields[name] = field;
4258
- return field;
4259
- }
4260
- addCompField(name, type, args) {
4261
- const field = new FieldComp(type, name, args);
4262
- this.compFields.add(name);
4263
- this.fields[name] = field;
4264
- return field;
4265
- }
4266
- };
4267
- var FIELD_CLASS = /* @__PURE__ */ Symbol.for("tutuca.fieldClass");
4268
- var fieldsByTypeName = {
4269
- text: FieldString,
4270
- int: FieldInt,
4271
- float: FieldFloat,
4272
- bool: FieldBool,
4273
- list: FieldList,
4274
- map: FieldMap,
4275
- omap: FieldOMap,
4276
- set: FieldSet,
4277
- any: FieldAny
4278
- };
4279
- function classFromData(name, { fields = {}, methods, statics }) {
4280
- const b = new ClassBuilder(name);
4281
- for (const field in fields) {
4282
- const value = fields[field];
4283
- const type = typeof value;
4284
- if (type === "string") b.addField(field, value, FieldString);
4285
- else if (type === "number") b.addField(field, value, FieldFloat);
4286
- else if (type === "boolean") b.addField(field, value, FieldBool);
4287
- else if (List.isList(value) || Array.isArray(value)) b.addField(field, List(value), FieldList);
4288
- else if (ISet.isSet(value) || value instanceof Set) b.addField(field, ISet(value), FieldSet);
4289
- else if (OrderedMap.isOrderedMap(value)) b.addField(field, value, FieldOMap);
4290
- else if (value?.type && value?.defaultValue !== void 0) {
4291
- const Field2 = fieldsByTypeName[value.type] ?? FieldAny;
4292
- b.addField(field, new Field2().coerceOr(value.defaultValue), Field2);
4293
- } else if (value?.component && value?.args !== void 0)
4294
- b.addCompField(field, value.component, value.args);
4295
- else if (IMap.isMap(value) || value?.constructor === Object)
4296
- b.addField(field, IMap(value), FieldMap);
4297
- else {
4298
- const Field2 = value?.[FIELD_CLASS] ?? FieldAny;
4299
- b.addField(field, value, Field2);
4300
- }
4301
- }
4302
- if (methods) b.methods(methods);
4303
- if (statics) b.statics(statics);
4304
- return b.build();
4305
- }
4306
- Component.fromSpec = (opts) => new Component(classFromData(opts.name, opts), opts);
4307
- var component = (opts) => Component.fromSpec(opts);
4308
-
4309
4273
  // index.js
4310
4274
  var css = String.raw;
4311
4275
  var html = String.raw;
4312
4276
  var macro = (defaults, rawView) => new Macro(defaults, rawView);
4313
- function check(_app) {
4277
+ function check2(_app) {
4314
4278
  return { error: 0, warn: 0, hint: 0, dummyCheck: true };
4315
4279
  }
4316
4280
  async function test(_opts) {
@@ -4343,74 +4307,23 @@ async function compileClassesToStyleText(app, compileClasses, Ctx = ParseCtxClas
4343
4307
  return await compileClasses(Array.from(collectAppClassesInSet(app)));
4344
4308
  }
4345
4309
  export {
4346
- Collection,
4347
4310
  FIELD_CLASS,
4348
- Map3 as IMap,
4349
- Set3 as ISet,
4350
- List2 as List,
4351
- Map2 as Map,
4352
- OrderedMap3 as OMap,
4353
- OrderedMap2 as OrderedMap,
4354
- OrderedSet,
4355
4311
  PASS,
4356
- PairSorting,
4357
4312
  ParseContext,
4358
- Range,
4359
- Record2 as Record,
4360
- Repeat,
4361
4313
  SEQ_INFO,
4362
- Seq,
4363
- Set2 as Set,
4364
- Stack2 as Stack,
4365
- check,
4314
+ check2 as check,
4366
4315
  collectIterBindings,
4367
4316
  compileClassesToStyle,
4368
4317
  compileClassesToStyleText,
4369
4318
  component,
4370
4319
  css,
4371
4320
  dispatchPhase,
4372
- fromJS,
4373
- get,
4374
- getIn,
4375
- has,
4376
- hasIn,
4377
- hash,
4378
4321
  html,
4379
4322
  injectCss,
4380
- is2 as is,
4381
- isAssociative,
4382
- isCollection,
4383
- isMap2 as isIMap,
4384
- isImmutable,
4385
- isIndexed2 as isIndexed,
4386
- isKeyed2 as isKeyed,
4387
- isList,
4388
- isMap,
4389
- isOrderedMap2 as isOMap,
4390
- isOrdered,
4391
- isOrderedMap,
4392
- isOrderedSet,
4393
- isPlainObject,
4394
- isRecord,
4395
- isSeq,
4396
- isSet,
4397
- isStack,
4398
- isValueObject,
4399
4323
  macro,
4400
- merge,
4401
- mergeDeep,
4402
- mergeDeepWith,
4403
- mergeWith,
4404
4324
  phaseOps,
4405
- remove,
4406
- removeIn,
4407
4325
  resolveArgs,
4408
4326
  rootDispatcher,
4409
- set,
4410
- setIn,
4411
4327
  test,
4412
- tutuca,
4413
- update,
4414
- updateIn,
4415
- version
4328
+ tutuca
4416
4329
  };