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.
- package/README.md +14 -14
- package/dist/immer.js +1261 -0
- package/dist/tutuca-cli.js +1603 -4573
- package/dist/tutuca-components.js +194 -424
- package/dist/tutuca-dev.ext.js +483 -757
- package/dist/tutuca-dev.js +1172 -4999
- package/dist/tutuca-dev.min.js +3 -3
- package/dist/tutuca-extra.ext.js +460 -547
- package/dist/tutuca-extra.js +1136 -4790
- package/dist/tutuca-extra.min.js +2 -2
- package/dist/tutuca-storybook.js +152 -143
- package/dist/tutuca.ext.js +460 -547
- package/dist/tutuca.js +1136 -4790
- package/dist/tutuca.min.js +2 -2
- package/package.json +7 -11
- package/skill/tutuca/SKILL.md +0 -4
- package/skill/tutuca/advanced.md +12 -4
- package/skill/tutuca/cli.md +8 -9
- package/skill/tutuca/component-design.md +18 -19
- package/skill/tutuca/core.md +83 -81
- package/skill/tutuca/iteration.md +2 -2
- package/skill/tutuca/macros.md +1 -1
- package/skill/tutuca/messages-and-intents.md +24 -23
- package/skill/tutuca/patterns/bind-text-and-attributes.md +1 -1
- package/skill/tutuca/patterns/conditional-attribute-value.md +1 -1
- package/skill/tutuca/patterns/coordinate-components.md +10 -8
- package/skill/tutuca/patterns/file-input.md +6 -6
- package/skill/tutuca/patterns/filter-and-paginate.md +1 -1
- package/skill/tutuca/patterns/handle-events.md +10 -8
- package/skill/tutuca/patterns/switch-between-views.md +1 -1
- package/skill/tutuca/patterns/tabbed-interface.md +10 -5
- package/skill/tutuca/testing.md +37 -28
- package/skill/tutuca-source/tutuca.ext.js +460 -547
- package/dist/immutable.js +0 -4331
- package/skill/immutable-js/SKILL.md +0 -78
- package/skill/immutable-js/references/collection.md +0 -346
- package/skill/immutable-js/references/conversions.md +0 -99
- package/skill/immutable-js/references/deep-updates.md +0 -172
- package/skill/immutable-js/references/equality.md +0 -95
- package/skill/immutable-js/references/list.md +0 -266
- package/skill/immutable-js/references/map.md +0 -300
- package/skill/immutable-js/references/predicates.md +0 -93
- package/skill/immutable-js/references/range-repeat.md +0 -55
- package/skill/immutable-js/references/record.md +0 -196
- package/skill/immutable-js/references/seq.md +0 -248
- package/skill/immutable-js/references/set.md +0 -270
- package/skill/immutable-js/references/shallow-functional.md +0 -99
- package/skill/immutable-js/references/stack.md +0 -210
package/dist/tutuca-extra.ext.js
CHANGED
|
@@ -1,8 +1,80 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
|
151
|
+
return readKey(v, this.field, dval);
|
|
78
152
|
}
|
|
79
153
|
setValue(root, v) {
|
|
80
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
104
|
-
|
|
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
|
|
121
|
-
const key = v
|
|
122
|
-
return key !== NONE && seq
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
|
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
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
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
|
-
|
|
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 &
|
|
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
|
|
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)
|
|
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)
|
|
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) =>
|
|
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
|
|
1730
|
-
const attrName =
|
|
1731
|
-
for (const key of keys) visit(key, seq
|
|
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
|
|
1738
|
-
const [s, e] = normalizeRange(start, end, seq
|
|
1739
|
-
for (let i = s; i < e; i++) visit(i, seq
|
|
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
|
|
1742
|
-
const [s, e] = normalizeRange(start, end, seq
|
|
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
|
|
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
|
|
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
|
|
2846
|
+
let has = false;
|
|
2763
2847
|
for (const k in provide) {
|
|
2764
2848
|
dynObj[provide[k].symbol] = provide[k].val.eval(this);
|
|
2765
|
-
|
|
2849
|
+
has = true;
|
|
2766
2850
|
}
|
|
2767
|
-
if (!
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
};
|