tutuca 0.9.115 → 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 +16 -16
- package/dist/immer.js +1261 -0
- package/dist/tutuca-cli.js +2056 -4798
- package/dist/tutuca-components.js +206 -442
- package/dist/tutuca-dev.ext.js +878 -944
- package/dist/tutuca-dev.js +1679 -5298
- package/dist/tutuca-dev.min.js +5 -5
- package/dist/tutuca-extra.ext.js +740 -695
- package/dist/tutuca-extra.js +1403 -4925
- package/dist/tutuca-extra.min.js +3 -3
- package/dist/tutuca-storybook.js +226 -210
- package/dist/tutuca.ext.js +740 -695
- package/dist/tutuca.js +1403 -4925
- package/dist/tutuca.min.js +3 -3
- package/package.json +7 -11
- package/skill/tutuca/SKILL.md +4 -8
- package/skill/tutuca/advanced.md +13 -5
- package/skill/tutuca/cli.md +8 -9
- package/skill/tutuca/component-design.md +50 -47
- package/skill/tutuca/core.md +134 -117
- package/skill/tutuca/iteration.md +2 -2
- package/skill/tutuca/macros.md +1 -1
- package/skill/tutuca/messages-and-intents.md +399 -0
- package/skill/tutuca/patterns/README.md +1 -1
- package/skill/tutuca/patterns/add-a-story.md +2 -2
- 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 +41 -18
- package/skill/tutuca/patterns/file-input.md +8 -8
- package/skill/tutuca/patterns/filter-and-paginate.md +1 -1
- package/skill/tutuca/patterns/handle-events.md +11 -9
- package/skill/tutuca/patterns/switch-between-views.md +1 -1
- package/skill/tutuca/patterns/tabbed-interface.md +10 -5
- package/skill/tutuca/semantics.md +41 -35
- package/skill/tutuca/storybook.md +34 -27
- package/skill/tutuca/testing.md +75 -64
- package/skill/tutuca-source/tutuca.ext.js +740 -695
- 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/skill/tutuca/request-response.md +0 -341
package/dist/tutuca-dev.ext.js
CHANGED
|
@@ -170,11 +170,69 @@ __reExport(chai_exports, chai_star);
|
|
|
170
170
|
import * as chai_star from "chai";
|
|
171
171
|
chai.use(jestMatchers);
|
|
172
172
|
|
|
173
|
-
// src/
|
|
174
|
-
|
|
173
|
+
// src/collection.js
|
|
174
|
+
var isPlainObject = (value) => {
|
|
175
|
+
if (value === null || typeof value !== "object") return false;
|
|
176
|
+
const proto = Object.getPrototypeOf(value);
|
|
177
|
+
return proto === Object.prototype || proto === null;
|
|
178
|
+
};
|
|
179
|
+
var seqSize = (seq) => {
|
|
180
|
+
if (seq == null) return 0;
|
|
181
|
+
if (typeof seq.length === "number") return seq.length;
|
|
182
|
+
if (typeof seq.size === "number") return seq.size;
|
|
183
|
+
return isPlainObject(seq) ? Object.keys(seq).length : 0;
|
|
184
|
+
};
|
|
185
|
+
var seqGet = (seq, key, dval = null) => {
|
|
186
|
+
if (seq == null) return dval;
|
|
187
|
+
if (seq instanceof Map) return seq.has(key) ? seq.get(key) : dval;
|
|
188
|
+
if (seq instanceof Set) return seq.has(key) ? key : dval;
|
|
189
|
+
if (Object.hasOwn(seq, key)) return seq[key];
|
|
190
|
+
if (typeof seq.get === "function") return seq.get(key, dval);
|
|
191
|
+
return dval;
|
|
192
|
+
};
|
|
193
|
+
var isIndexedSeq = (seq) => Array.isArray(seq);
|
|
194
|
+
var isKeyedSeq = (seq) => seq instanceof Map || isPlainObject(seq);
|
|
195
|
+
var isSetSeq = (seq) => seq instanceof Set;
|
|
196
|
+
function* seqEntries(seq) {
|
|
197
|
+
if (seq instanceof Map) yield* seq.entries();
|
|
198
|
+
else if (seq instanceof Set) for (const value of seq) yield [value, value];
|
|
199
|
+
else if (isPlainObject(seq)) yield* Object.entries(seq);
|
|
200
|
+
else if (Array.isArray(seq)) for (let i = 0; i < seq.length; i++) yield [i, seq[i]];
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// src/immer.js
|
|
204
|
+
var immer_exports = {};
|
|
205
|
+
__reExport(immer_exports, immer_star);
|
|
206
|
+
import { enableMapSet } from "immer";
|
|
207
|
+
import * as immer_star from "immer";
|
|
208
|
+
enableMapSet();
|
|
175
209
|
|
|
176
210
|
// src/path.js
|
|
177
211
|
var NONE = /* @__PURE__ */ Symbol("NONE");
|
|
212
|
+
var readKey = (value, key, dval = null) => {
|
|
213
|
+
if (value == null) return dval;
|
|
214
|
+
if (value instanceof Map) return value.has(key) ? value.get(key) : dval;
|
|
215
|
+
if (value instanceof Set) return value.has(key) ? key : dval;
|
|
216
|
+
return Object.hasOwn(value, key) ? value[key] : dval;
|
|
217
|
+
};
|
|
218
|
+
var writeKey = (value, key, next) => {
|
|
219
|
+
if (value instanceof Map) value.set(key, next);
|
|
220
|
+
else if (value instanceof Set) {
|
|
221
|
+
value.delete(key);
|
|
222
|
+
value.add(next);
|
|
223
|
+
} else value[key] = next;
|
|
224
|
+
};
|
|
225
|
+
var readSeqKey = (value, key, dval = null) => {
|
|
226
|
+
const direct = readKey(value, key, NONE);
|
|
227
|
+
if (direct !== NONE) return direct;
|
|
228
|
+
return typeof value?.get === "function" ? value.get(key, dval) : dval;
|
|
229
|
+
};
|
|
230
|
+
var writeSeqKey = (value, key, next) => {
|
|
231
|
+
if (value instanceof Map || value instanceof Set || Array.isArray(value) || Object.hasOwn(value, key))
|
|
232
|
+
writeKey(value, key, next);
|
|
233
|
+
else if (typeof value?.set === "function") value.set(key, next);
|
|
234
|
+
else writeKey(value, key, next);
|
|
235
|
+
};
|
|
178
236
|
var Step = class {
|
|
179
237
|
lookup(_v, dval = null) {
|
|
180
238
|
return dval;
|
|
@@ -182,6 +240,8 @@ var Step = class {
|
|
|
182
240
|
setValue(root, _v) {
|
|
183
241
|
return root;
|
|
184
242
|
}
|
|
243
|
+
setDraftValue(_root, _v) {
|
|
244
|
+
}
|
|
185
245
|
enterFrame(stack, _prev, next) {
|
|
186
246
|
return stack.enter(next, {}, true);
|
|
187
247
|
}
|
|
@@ -246,10 +306,13 @@ var FieldStep = class extends Step {
|
|
|
246
306
|
this.field = field;
|
|
247
307
|
}
|
|
248
308
|
lookup(v, dval = null) {
|
|
249
|
-
return v
|
|
309
|
+
return readKey(v, this.field, dval);
|
|
250
310
|
}
|
|
251
311
|
setValue(root, v) {
|
|
252
|
-
return
|
|
312
|
+
return (0, immer_exports.produce)(root, (draft) => this.setDraftValue(draft, v));
|
|
313
|
+
}
|
|
314
|
+
setDraftValue(root, v) {
|
|
315
|
+
writeKey(root, this.field, v);
|
|
253
316
|
}
|
|
254
317
|
withIndex(i) {
|
|
255
318
|
return new SeqStep(this.field, i);
|
|
@@ -268,12 +331,14 @@ var SeqStep = class extends Step {
|
|
|
268
331
|
this.key = key;
|
|
269
332
|
}
|
|
270
333
|
lookup(v, dval = null) {
|
|
271
|
-
|
|
272
|
-
return o?.get ? o.get(this.key, dval) : dval;
|
|
334
|
+
return readSeqKey(readKey(v, this.field, null), this.key, dval);
|
|
273
335
|
}
|
|
274
336
|
setValue(root, v) {
|
|
275
|
-
|
|
276
|
-
|
|
337
|
+
return (0, immer_exports.produce)(root, (draft) => this.setDraftValue(draft, v));
|
|
338
|
+
}
|
|
339
|
+
setDraftValue(root, v) {
|
|
340
|
+
const seq = readKey(root, this.field, null);
|
|
341
|
+
if (seq != null) writeSeqKey(seq, this.key, v);
|
|
277
342
|
}
|
|
278
343
|
enterFrame(stack, _prev, next) {
|
|
279
344
|
return stack.enter(next, { key: this.key }, true);
|
|
@@ -289,19 +354,22 @@ var SeqAccessStep = class extends Step {
|
|
|
289
354
|
this.keyField = keyField;
|
|
290
355
|
}
|
|
291
356
|
lookup(v, dval = null) {
|
|
292
|
-
const seq = v
|
|
293
|
-
const key = v
|
|
294
|
-
return key !== NONE && seq
|
|
357
|
+
const seq = readKey(v, this.seqField, NONE);
|
|
358
|
+
const key = readKey(v, this.keyField, NONE);
|
|
359
|
+
return key !== NONE && seq !== NONE ? readSeqKey(seq, key, dval) : dval;
|
|
295
360
|
}
|
|
296
361
|
setValue(root, v) {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
362
|
+
return (0, immer_exports.produce)(root, (draft) => this.setDraftValue(draft, v));
|
|
363
|
+
}
|
|
364
|
+
setDraftValue(root, v) {
|
|
365
|
+
const seq = readKey(root, this.seqField, NONE);
|
|
366
|
+
const key = readKey(root, this.keyField, NONE);
|
|
367
|
+
if (seq !== NONE && key !== NONE) writeSeqKey(seq, key, v);
|
|
300
368
|
}
|
|
301
369
|
// Resolve `keyField` against `v` now and freeze it as a literal-key `SeqStep`, so a
|
|
302
370
|
// later lookup/setValue lands on this same item even if `keyField` changes meanwhile.
|
|
303
371
|
pinKey(v) {
|
|
304
|
-
const key = v
|
|
372
|
+
const key = readKey(v, this.keyField, NONE);
|
|
305
373
|
return key === NONE ? this : new SeqStep(this.seqField, key);
|
|
306
374
|
}
|
|
307
375
|
// The key is a *field reference* resolved live, so it is unknown without a value;
|
|
@@ -482,19 +550,15 @@ var Path = class _Path {
|
|
|
482
550
|
return out;
|
|
483
551
|
}
|
|
484
552
|
setValue(root, v) {
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
newVal = this.steps[i].setValue(intermediates[i], newVal);
|
|
495
|
-
intermediates[i] = newVal;
|
|
496
|
-
}
|
|
497
|
-
return newVal;
|
|
553
|
+
if (this.steps.length === 0) return v;
|
|
554
|
+
return (0, immer_exports.produce)(root, (draft) => {
|
|
555
|
+
let parent = draft;
|
|
556
|
+
for (let i = 0; i < this.steps.length - 1; i++) {
|
|
557
|
+
parent = this.steps[i].lookup(parent, NONE);
|
|
558
|
+
if (parent === NONE) return;
|
|
559
|
+
}
|
|
560
|
+
this.steps.at(-1).setDraftValue(parent, v);
|
|
561
|
+
});
|
|
498
562
|
}
|
|
499
563
|
buildStack(stack) {
|
|
500
564
|
let prev = stack.it;
|
|
@@ -691,7 +755,8 @@ function sizeOf(v) {
|
|
|
691
755
|
const s = v.size;
|
|
692
756
|
if (typeof s === "number") return s;
|
|
693
757
|
const l = v.length;
|
|
694
|
-
|
|
758
|
+
if (typeof l === "number") return l;
|
|
759
|
+
return isPlainObject(v) ? Object.keys(v).length : null;
|
|
695
760
|
}
|
|
696
761
|
var predTruthy = (v) => {
|
|
697
762
|
const n = sizeOf(v);
|
|
@@ -702,7 +767,7 @@ var PREDICATES = {
|
|
|
702
767
|
"truthy?": { name: "truthy?", arity: 1, fn: predTruthy },
|
|
703
768
|
"falsy?": { name: "falsy?", arity: 1, fn: (v) => !predTruthy(v) },
|
|
704
769
|
"null?": { name: "null?", arity: 1, fn: (v) => v == null },
|
|
705
|
-
"equals?": { name: "equals?", arity: 2, fn: (a, b) => is(a, b) }
|
|
770
|
+
"equals?": { name: "equals?", arity: 2, fn: (a, b) => Object.is(a, b) }
|
|
706
771
|
};
|
|
707
772
|
function parseToken(s, px) {
|
|
708
773
|
const c0 = s.charCodeAt(0);
|
|
@@ -787,21 +852,29 @@ function parseProvide(s, px) {
|
|
|
787
852
|
function parseMacroAttr(s, px) {
|
|
788
853
|
return _parseSingle(s, px, G_ALL);
|
|
789
854
|
}
|
|
790
|
-
function
|
|
791
|
-
return _parseHandler(s, px, "
|
|
855
|
+
function parseReceiveHandler(s, px) {
|
|
856
|
+
return _parseHandler(s, px, "receive", true, true, false);
|
|
792
857
|
}
|
|
793
858
|
function parseAlterHandler(s, px) {
|
|
794
|
-
const r = _parseHandler(s, px, "alter", false, false);
|
|
859
|
+
const r = _parseHandler(s, px, "alter", false, false, true);
|
|
795
860
|
return r === null ? null : r.handlerVal;
|
|
796
861
|
}
|
|
797
|
-
function _parseHandler(s, px, namespace, allowArgs, report) {
|
|
862
|
+
function _parseHandler(s, px, namespace, allowArgs, report, allowMethod) {
|
|
798
863
|
const tokens = tokenizeValue(s.trim());
|
|
799
864
|
const headTok = tokens[0] ?? "";
|
|
800
865
|
const head = headTok === "" ? null : parseToken(headTok, px);
|
|
801
866
|
const hk = kindOf(head);
|
|
802
867
|
let handlerVal;
|
|
803
|
-
if (hk & K_METHOD) handlerVal = head;
|
|
804
|
-
else if (hk &
|
|
868
|
+
if (hk & K_METHOD && allowMethod) handlerVal = head;
|
|
869
|
+
else if (hk & K_METHOD) {
|
|
870
|
+
if (report)
|
|
871
|
+
px.onParseIssue("event-method-handler", {
|
|
872
|
+
name: head.name,
|
|
873
|
+
role: "handler-name",
|
|
874
|
+
value: headTok
|
|
875
|
+
});
|
|
876
|
+
return null;
|
|
877
|
+
} else if (hk & K_NAME) handlerVal = new HandlerNameVal(head.name, namespace);
|
|
805
878
|
else {
|
|
806
879
|
if (report) px.onParseIssue("bad-value", { role: "handler-name", value: headTok });
|
|
807
880
|
return null;
|
|
@@ -1015,7 +1088,7 @@ var BindMemberVal = class extends BindVal {
|
|
|
1015
1088
|
}
|
|
1016
1089
|
eval(stack) {
|
|
1017
1090
|
const v = stack.lookupBind(this.name);
|
|
1018
|
-
return
|
|
1091
|
+
return seqGet(v, this.member, null);
|
|
1019
1092
|
}
|
|
1020
1093
|
toString() {
|
|
1021
1094
|
return `@${this.name}.${this.member}`;
|
|
@@ -1062,7 +1135,7 @@ var SeqAccessVal = class extends RenderVal {
|
|
|
1062
1135
|
}
|
|
1063
1136
|
eval(stack) {
|
|
1064
1137
|
const key = this.keyVal.eval(stack);
|
|
1065
|
-
return this.seqVal.eval(stack)
|
|
1138
|
+
return seqGet(this.seqVal.eval(stack), key, null);
|
|
1066
1139
|
}
|
|
1067
1140
|
toString() {
|
|
1068
1141
|
return `${this.seqVal}[${this.keyVal}]`;
|
|
@@ -1331,20 +1404,17 @@ var EventHandler = class _EventHandler {
|
|
|
1331
1404
|
return [this.handlerVal.evalAsHandler(stack), argValues];
|
|
1332
1405
|
}
|
|
1333
1406
|
static parse(s, px) {
|
|
1334
|
-
const r =
|
|
1407
|
+
const r = parseReceiveHandler(s, px);
|
|
1335
1408
|
return r === null ? null : new _EventHandler(r.handlerVal, r.args);
|
|
1336
1409
|
}
|
|
1337
1410
|
};
|
|
1338
|
-
var
|
|
1411
|
+
var IntentHandler = class {
|
|
1339
1412
|
constructor(name, fn) {
|
|
1340
1413
|
this.name = name;
|
|
1341
1414
|
this.fn = fn;
|
|
1342
1415
|
}
|
|
1343
1416
|
};
|
|
1344
1417
|
|
|
1345
|
-
// src/renderer.js
|
|
1346
|
-
import { isIndexed, isKeyed } from "immutable";
|
|
1347
|
-
|
|
1348
1418
|
// src/cache.js
|
|
1349
1419
|
var isWeakKey = (k) => k !== null && (typeof k === "object" || typeof k === "function");
|
|
1350
1420
|
var NullDomCache = class {
|
|
@@ -1841,7 +1911,7 @@ var Renderer = class {
|
|
|
1841
1911
|
this.cache.set(cachePath, cacheKey, dom);
|
|
1842
1912
|
}
|
|
1843
1913
|
};
|
|
1844
|
-
if (keys)
|
|
1914
|
+
if (keys) keysIter(seq, renderOne, keys);
|
|
1845
1915
|
else
|
|
1846
1916
|
getSeqInfo(seq)(
|
|
1847
1917
|
seq,
|
|
@@ -1875,7 +1945,7 @@ var Renderer = class {
|
|
|
1875
1945
|
return new VFragment([this._renderMetadata({ $: "Scope", nid }), dom]);
|
|
1876
1946
|
}
|
|
1877
1947
|
};
|
|
1878
|
-
var getSeqInfo = (seq) =>
|
|
1948
|
+
var getSeqInfo = (seq) => isIndexedSeq(seq) ? nativeIndexedIter : isKeyedSeq(seq) || isSetSeq(seq) ? nativeKeyedIter : seq?.[SEQ_INFO] ?? unkIter;
|
|
1879
1949
|
var normalizeRange = (start, end, size) => {
|
|
1880
1950
|
let s = start == null ? 0 : start < 0 ? size + start : start;
|
|
1881
1951
|
let e = end == null ? size : end < 0 ? size + end : end;
|
|
@@ -1898,22 +1968,22 @@ var unpackLoopResult = (result, seq) => {
|
|
|
1898
1968
|
const r = result ?? {};
|
|
1899
1969
|
return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end, keys: r.keys };
|
|
1900
1970
|
};
|
|
1901
|
-
var
|
|
1902
|
-
const attrName =
|
|
1903
|
-
for (const key of keys) visit(key, seq
|
|
1971
|
+
var keysIter = (seq, visit, keys) => {
|
|
1972
|
+
const attrName = isIndexedSeq(seq) ? "si" : "sk";
|
|
1973
|
+
for (const key of keys) visit(key, seqGet(seq, key), attrName);
|
|
1904
1974
|
};
|
|
1905
1975
|
var makeLoopCtx = (stack, filter) => ({
|
|
1906
1976
|
lookup: (name) => stack.lookupBind(name),
|
|
1907
1977
|
filter: (key, value, iterData) => filter.call(stack.it, key, value, iterData)
|
|
1908
1978
|
});
|
|
1909
|
-
var
|
|
1910
|
-
const [s, e] = normalizeRange(start, end, seq
|
|
1911
|
-
for (let i = s; i < e; i++) visit(i, seq
|
|
1979
|
+
var nativeIndexedIter = (seq, visit, start, end) => {
|
|
1980
|
+
const [s, e] = normalizeRange(start, end, seqSize(seq));
|
|
1981
|
+
for (let i = s; i < e; i++) visit(i, seq[i], "si");
|
|
1912
1982
|
};
|
|
1913
|
-
var
|
|
1914
|
-
const [s, e] = normalizeRange(start, end, seq
|
|
1983
|
+
var nativeKeyedIter = (seq, visit, start, end) => {
|
|
1984
|
+
const [s, e] = normalizeRange(start, end, seqSize(seq));
|
|
1915
1985
|
let i = 0;
|
|
1916
|
-
for (const [k, v] of seq
|
|
1986
|
+
for (const [k, v] of seqEntries(seq)) {
|
|
1917
1987
|
if (i >= e) break;
|
|
1918
1988
|
if (i >= s) visit(k, v, "sk");
|
|
1919
1989
|
i++;
|
|
@@ -2433,7 +2503,7 @@ var IterInfo = class {
|
|
|
2433
2503
|
// { key, value }, then run @enrich-with (with @loop-with's iterData) if any.
|
|
2434
2504
|
enrichBinds(stack, key) {
|
|
2435
2505
|
const { seq, filter, loopWith, enricher } = this.eval(stack);
|
|
2436
|
-
const value = seq
|
|
2506
|
+
const value = seqGet(seq, key, null);
|
|
2437
2507
|
const binds = { key, value };
|
|
2438
2508
|
if (enricher) {
|
|
2439
2509
|
const { iterData } = unpackLoopResult(
|
|
@@ -5031,7 +5101,7 @@ var KNOWN_COMPONENT_SPEC_KEYS = new Set(
|
|
|
5031
5101
|
)
|
|
5032
5102
|
);
|
|
5033
5103
|
var EMPTY_SET = /* @__PURE__ */ new Set();
|
|
5034
|
-
var FRAMEWORK_WELL_KNOWN_EXTRAS = /* @__PURE__ */ new Set(["
|
|
5104
|
+
var FRAMEWORK_WELL_KNOWN_EXTRAS = /* @__PURE__ */ new Set(["intentOverridesField"]);
|
|
5035
5105
|
var KNOWN_DIRECTIVE_NAMES = /* @__PURE__ */ new Set([
|
|
5036
5106
|
"dangerouslysetinnerhtml",
|
|
5037
5107
|
"slot",
|
|
@@ -5056,11 +5126,11 @@ var LOOKUP_TARGET_MALFORMED = "LOOKUP_TARGET_MALFORMED";
|
|
|
5056
5126
|
var RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP";
|
|
5057
5127
|
var UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER";
|
|
5058
5128
|
var UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME";
|
|
5059
|
-
var
|
|
5060
|
-
var
|
|
5061
|
-
var
|
|
5062
|
-
var
|
|
5063
|
-
var
|
|
5129
|
+
var RECEIVE_HANDLER_NOT_IMPLEMENTED = "RECEIVE_HANDLER_NOT_IMPLEMENTED";
|
|
5130
|
+
var EVENT_HANDLER_METHOD_NOT_ALLOWED = "EVENT_HANDLER_METHOD_NOT_ALLOWED";
|
|
5131
|
+
var RETIRED_HANDLER_BUCKET = "RETIRED_HANDLER_BUCKET";
|
|
5132
|
+
var RETIRED_CTX_VERB = "RETIRED_CTX_VERB";
|
|
5133
|
+
var HANDLER_NAME_COLLISION = "HANDLER_NAME_COLLISION";
|
|
5064
5134
|
var FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED";
|
|
5065
5135
|
var FIELD_VAL_IS_METHOD = "FIELD_VAL_IS_METHOD";
|
|
5066
5136
|
var METHOD_VAL_NOT_DEFINED = "METHOD_VAL_NOT_DEFINED";
|
|
@@ -5088,8 +5158,7 @@ var COMP_FIELD_BAD_SHAPE = "COMP_FIELD_BAD_SHAPE";
|
|
|
5088
5158
|
var ASYNC_HANDLER = "ASYNC_HANDLER";
|
|
5089
5159
|
var TOP_LEVEL_AT_RULE_IN_SCOPED_STYLE = "TOP_LEVEL_AT_RULE_IN_SCOPED_STYLE";
|
|
5090
5160
|
var GLOBAL_SELECTOR_IN_SCOPED_STYLE = "GLOBAL_SELECTOR_IN_SCOPED_STYLE";
|
|
5091
|
-
var
|
|
5092
|
-
var RECORD_FIELD_NAME_COLLISIONS = /* @__PURE__ */ new Set(["entries", "hashCode"]);
|
|
5161
|
+
var FIELD_METHOD_NAME_COLLISION = "FIELD_METHOD_NAME_COLLISION";
|
|
5093
5162
|
var X_KNOWN_OP_NAMES = /* @__PURE__ */ new Set([
|
|
5094
5163
|
"slot",
|
|
5095
5164
|
"text",
|
|
@@ -5112,7 +5181,8 @@ var PARSE_ISSUES = {
|
|
|
5112
5181
|
candidates: X_KNOWN_ATTR_NAMES,
|
|
5113
5182
|
atPrefix: X_KNOWN_ATTR_NAMES
|
|
5114
5183
|
},
|
|
5115
|
-
"bad-value": { id: BAD_VALUE }
|
|
5184
|
+
"bad-value": { id: BAD_VALUE },
|
|
5185
|
+
"event-method-handler": { id: EVENT_HANDLER_METHOD_NOT_ALLOWED }
|
|
5116
5186
|
};
|
|
5117
5187
|
function protoHasMethod(proto, name) {
|
|
5118
5188
|
return protoMethodValue(proto, name) !== null;
|
|
@@ -5174,10 +5244,13 @@ function checkComponent(Comp, lx = new LintContext(), { wellKnownExtras = EMPTY_
|
|
|
5174
5244
|
return lx.push({ componentName: Comp.name }, () => {
|
|
5175
5245
|
checkUnknownSpecKeys(lx, Comp, wellKnownExtras);
|
|
5176
5246
|
checkFieldDeclarations(lx, Comp);
|
|
5177
|
-
|
|
5247
|
+
checkFieldMethodNameCollisions(lx, Comp);
|
|
5178
5248
|
checkProvidesAreAddressable(lx, Comp);
|
|
5179
5249
|
checkLookupShapes(lx, Comp);
|
|
5180
5250
|
checkHandlersNotAsync(lx, Comp);
|
|
5251
|
+
checkRetiredBuckets(lx, Comp);
|
|
5252
|
+
checkRetiredCtxVerbs(lx, Comp);
|
|
5253
|
+
checkHandlerNameCollisions(lx, Comp);
|
|
5181
5254
|
checkScopedStyleTopLevel(lx, Comp);
|
|
5182
5255
|
const referencedAlters = /* @__PURE__ */ new Set();
|
|
5183
5256
|
const referencedInputs = /* @__PURE__ */ new Set();
|
|
@@ -5191,7 +5264,6 @@ function checkComponent(Comp, lx = new LintContext(), { wellKnownExtras = EMPTY_
|
|
|
5191
5264
|
);
|
|
5192
5265
|
}
|
|
5193
5266
|
checkUnreferencedAlterHandlers(lx, Comp, referencedAlters);
|
|
5194
|
-
checkUnreferencedInputHandlers(lx, Comp, referencedInputs);
|
|
5195
5267
|
checkUnreferencedDynamics(lx, Comp, referencedDynamics);
|
|
5196
5268
|
return lx;
|
|
5197
5269
|
});
|
|
@@ -5235,6 +5307,14 @@ function checkParseIssues(lx, view) {
|
|
|
5235
5307
|
lx.warn(X_OP_IGNORES_CHILDREN, info, { kind: "remove", what: "the ignored children" });
|
|
5236
5308
|
continue;
|
|
5237
5309
|
}
|
|
5310
|
+
if (kind === "event-method-handler") {
|
|
5311
|
+
lx.error(EVENT_HANDLER_METHOD_NOT_ALLOWED, info, {
|
|
5312
|
+
kind: "rephrase",
|
|
5313
|
+
from: info.value,
|
|
5314
|
+
text: `Move '${info.name}' to receive and reference it as '${info.name}'.`
|
|
5315
|
+
});
|
|
5316
|
+
continue;
|
|
5317
|
+
}
|
|
5238
5318
|
const rule = PARSE_ISSUES[kind];
|
|
5239
5319
|
if (!rule) continue;
|
|
5240
5320
|
const id = rule.id;
|
|
@@ -5461,7 +5541,7 @@ function mkAttrValEnv(Comp, referencedAlters, referencedDynamics) {
|
|
|
5461
5541
|
return { fields, proto, scope, alter, referencedAlters, dynamicMap, referencedDynamics };
|
|
5462
5542
|
}
|
|
5463
5543
|
function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
|
|
5464
|
-
const { input, views, Class } = Comp;
|
|
5544
|
+
const { receive: input, views, Class } = Comp;
|
|
5465
5545
|
const { prototype: proto } = Class;
|
|
5466
5546
|
for (const viewName in views) {
|
|
5467
5547
|
lx.push({ viewName }, () => {
|
|
@@ -5469,44 +5549,22 @@ function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
|
|
|
5469
5549
|
for (const event of view.ctx.events) {
|
|
5470
5550
|
for (const handler of event.handlers) {
|
|
5471
5551
|
const { handlerVal } = handler.handlerCall;
|
|
5472
|
-
const hvName = handlerVal?.constructor.name;
|
|
5473
5552
|
const eventName = handler.name;
|
|
5474
5553
|
const originAttr = `@on.${eventName}`;
|
|
5475
|
-
if (
|
|
5554
|
+
if (handlerVal?.constructor.name === "HandlerNameVal") {
|
|
5476
5555
|
referencedInputs?.add(handlerVal.name);
|
|
5477
5556
|
const { name } = handlerVal;
|
|
5478
5557
|
if (input[name] === void 0) {
|
|
5479
|
-
const
|
|
5558
|
+
const suggestion = protoHasMethod(proto, name) ? {
|
|
5559
|
+
kind: "rephrase",
|
|
5560
|
+
from: name,
|
|
5561
|
+
text: `Move '${name}' from methods to receive; event handlers are receive handlers.`
|
|
5562
|
+
} : replaceNameSuggestion(name, Object.keys(input));
|
|
5480
5563
|
lx.error(
|
|
5481
|
-
|
|
5564
|
+
RECEIVE_HANDLER_NOT_IMPLEMENTED,
|
|
5482
5565
|
{ name, handler, event, eventName, originAttr },
|
|
5483
|
-
|
|
5566
|
+
suggestion
|
|
5484
5567
|
);
|
|
5485
|
-
if (isMethodFix) {
|
|
5486
|
-
lx.hint(
|
|
5487
|
-
INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER,
|
|
5488
|
-
{ name, handler, event, eventName, originAttr },
|
|
5489
|
-
{ kind: "add-prefix", from: name, to: `$${name}` }
|
|
5490
|
-
);
|
|
5491
|
-
}
|
|
5492
|
-
}
|
|
5493
|
-
} else if (hvName === "MethodVal") {
|
|
5494
|
-
referencedInputs?.add(handlerVal.name);
|
|
5495
|
-
const { name } = handlerVal;
|
|
5496
|
-
if (!protoHasMethod(proto, name)) {
|
|
5497
|
-
const isInputFix = input[name] !== void 0;
|
|
5498
|
-
lx.error(
|
|
5499
|
-
INPUT_HANDLER_METHOD_NOT_IMPLEMENTED,
|
|
5500
|
-
{ name, handler, event, eventName, originAttr },
|
|
5501
|
-
isInputFix ? { kind: "drop-prefix", from: `$${name}`, to: name } : replaceNameSuggestion(name, collectProtoMethodNames(proto))
|
|
5502
|
-
);
|
|
5503
|
-
if (isInputFix) {
|
|
5504
|
-
lx.hint(
|
|
5505
|
-
INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD,
|
|
5506
|
-
{ name, handler, event, eventName, originAttr },
|
|
5507
|
-
{ kind: "drop-prefix", from: `$${name}`, to: name }
|
|
5508
|
-
);
|
|
5509
|
-
}
|
|
5510
5568
|
}
|
|
5511
5569
|
}
|
|
5512
5570
|
}
|
|
@@ -5610,10 +5668,10 @@ var ATTR_VAL_CHECKERS = {
|
|
|
5610
5668
|
}
|
|
5611
5669
|
};
|
|
5612
5670
|
function checkConsistentAttrVal(lx, val, env, skipNameVal = false, errCtx = null, isRoot = true) {
|
|
5613
|
-
const
|
|
5614
|
-
if (
|
|
5671
|
+
const check3 = ATTR_VAL_CHECKERS[val?.constructor.name];
|
|
5672
|
+
if (check3 === void 0) return;
|
|
5615
5673
|
const recurse = (sub) => checkConsistentAttrVal(lx, sub, env, skipNameVal, errCtx, false);
|
|
5616
|
-
|
|
5674
|
+
check3({ lx, val, env, errCtx, skipNameVal, recurse, isRoot });
|
|
5617
5675
|
}
|
|
5618
5676
|
var NODE_KIND_TO_CTX = {
|
|
5619
5677
|
RenderTextNode: { originAttr: "<x text>" },
|
|
@@ -5751,12 +5809,83 @@ function checkConsistentAttrs(lx, Comp, referencedAlters, referencedDynamics) {
|
|
|
5751
5809
|
});
|
|
5752
5810
|
}
|
|
5753
5811
|
}
|
|
5812
|
+
var isPlainObj = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
5813
|
+
var RETIRED_BUCKETS = {
|
|
5814
|
+
input: {
|
|
5815
|
+
to: "receive",
|
|
5816
|
+
how: "rename the bucket to `receive` - a view's own @on.* name and a parent's ctx.send are the same message now, and nothing can tell them apart"
|
|
5817
|
+
},
|
|
5818
|
+
bubble: {
|
|
5819
|
+
to: "intent",
|
|
5820
|
+
how: "rename the bucket to `intent` - and note the walk changed: a handler that calls ctx.reply() ENDS it, where ctx.stopPropagation() used to be the only way to stop"
|
|
5821
|
+
},
|
|
5822
|
+
response: {
|
|
5823
|
+
to: "receive",
|
|
5824
|
+
how: "split each arm into `receive` arms named after the intent: <name>Ok takes the result alone, <name>Error takes the error alone, and the optional <name>Unhandled means nothing claimed it"
|
|
5825
|
+
}
|
|
5826
|
+
};
|
|
5827
|
+
function checkRetiredBuckets(lx, Comp) {
|
|
5828
|
+
const extra = Comp.extra;
|
|
5829
|
+
if (!extra) return;
|
|
5830
|
+
for (const key of Object.keys(extra)) {
|
|
5831
|
+
if (!Object.hasOwn(RETIRED_BUCKETS, key)) continue;
|
|
5832
|
+
const retired = RETIRED_BUCKETS[key];
|
|
5833
|
+
const names = isPlainObj(extra[key]) ? Object.keys(extra[key]) : [];
|
|
5834
|
+
lx.error(RETIRED_HANDLER_BUCKET, { key, to: retired.to, how: retired.how, names });
|
|
5835
|
+
}
|
|
5836
|
+
}
|
|
5837
|
+
var RETIRED_CTX_VERBS = {
|
|
5838
|
+
bubble: 'ctx.intent(name, args, { route: ["dyn"] }) - the route says it walks the ancestors, where the verb used to',
|
|
5839
|
+
request: 'ctx.intent(name, args, { route: ["lex"] }) - and the outcome comes back as a `receive` arm named <name>Ok / <name>Error / <name>Unhandled, so onOkName and onErrorName are gone',
|
|
5840
|
+
stopPropagation: "ctx.stop()",
|
|
5841
|
+
inputAtPath: "ctx.sendAtPath(path, name, args)",
|
|
5842
|
+
requestAtPath: 'ctx.intentAtPath(path, name, args, { route: ["lex"] })'
|
|
5843
|
+
};
|
|
5844
|
+
var RETIRED_CTX_RE = new RegExp(
|
|
5845
|
+
`\\bctx\\.(${Object.keys(RETIRED_CTX_VERBS).join("|")})\\s*\\(`,
|
|
5846
|
+
"g"
|
|
5847
|
+
);
|
|
5848
|
+
function checkRetiredCtxVerbs(lx, Comp) {
|
|
5849
|
+
for (const bucket of ["receive", "intent", "alter", "methods", "statics"]) {
|
|
5850
|
+
const block = bucket === "methods" || bucket === "statics" ? Comp.spec?.[bucket] : Comp[bucket];
|
|
5851
|
+
if (!isPlainObj(block)) continue;
|
|
5852
|
+
for (const name in block) {
|
|
5853
|
+
const fn = block[name];
|
|
5854
|
+
if (typeof fn !== "function") continue;
|
|
5855
|
+
const src = String(fn);
|
|
5856
|
+
for (const m of src.matchAll(RETIRED_CTX_RE)) {
|
|
5857
|
+
const verb = m[1];
|
|
5858
|
+
lx.error(RETIRED_CTX_VERB, { verb, to: RETIRED_CTX_VERBS[verb], bucket, name });
|
|
5859
|
+
}
|
|
5860
|
+
}
|
|
5861
|
+
}
|
|
5862
|
+
}
|
|
5863
|
+
function checkHandlerNameCollisions(lx, Comp) {
|
|
5864
|
+
const receive = Comp.receive ?? {};
|
|
5865
|
+
const intent = Comp.intent ?? {};
|
|
5866
|
+
for (const name in intent)
|
|
5867
|
+
if (receive[name] !== void 0)
|
|
5868
|
+
lx.error(HANDLER_NAME_COLLISION, {
|
|
5869
|
+
name,
|
|
5870
|
+
problem: `"${name}" is declared in both \`receive\` and \`intent\``,
|
|
5871
|
+
fix: "one is addressed and one is routed; give them different names so a reader can tell which a call site meant"
|
|
5872
|
+
});
|
|
5873
|
+
for (const name in receive)
|
|
5874
|
+
for (const suffix of ["Ok", "Error", "Unhandled"])
|
|
5875
|
+
if (receive[name + suffix] !== void 0 && intent[name] === void 0)
|
|
5876
|
+
lx.warn(HANDLER_NAME_COLLISION, {
|
|
5877
|
+
name,
|
|
5878
|
+
problem: `\`receive\` declares both "${name}" and its answer name "${name + suffix}"`,
|
|
5879
|
+
fix: `an intent named "${name}" would dispatch its answer to "${name + suffix}" - rename one unless that is what you meant`
|
|
5880
|
+
});
|
|
5881
|
+
}
|
|
5754
5882
|
function checkUnknownSpecKeys(lx, Comp, wellKnownExtras) {
|
|
5755
5883
|
const extra = Comp.extra;
|
|
5756
5884
|
if (!extra) return;
|
|
5757
5885
|
let candidates = null;
|
|
5758
5886
|
for (const key of Object.keys(extra)) {
|
|
5759
5887
|
if (FRAMEWORK_WELL_KNOWN_EXTRAS.has(key) || wellKnownExtras.has(key)) continue;
|
|
5888
|
+
if (Object.hasOwn(RETIRED_BUCKETS, key)) continue;
|
|
5760
5889
|
candidates ??= [
|
|
5761
5890
|
...KNOWN_COMPONENT_SPEC_KEYS,
|
|
5762
5891
|
...FRAMEWORK_WELL_KNOWN_EXTRAS,
|
|
@@ -5788,14 +5917,11 @@ function checkFieldDeclarations(lx, Comp) {
|
|
|
5788
5917
|
}
|
|
5789
5918
|
}
|
|
5790
5919
|
}
|
|
5791
|
-
function
|
|
5792
|
-
const
|
|
5793
|
-
if (!
|
|
5794
|
-
for (const name in fields)
|
|
5795
|
-
if (
|
|
5796
|
-
lx.error(FIELD_NAME_RESERVED_BY_RECORD, { name });
|
|
5797
|
-
}
|
|
5798
|
-
}
|
|
5920
|
+
function checkFieldMethodNameCollisions(lx, Comp) {
|
|
5921
|
+
const meta = Comp.Class?.getMetaClass?.();
|
|
5922
|
+
if (!meta) return;
|
|
5923
|
+
for (const name in meta.fields)
|
|
5924
|
+
if (Object.hasOwn(meta.methods, name)) lx.error(FIELD_METHOD_NAME_COLLISION, { name });
|
|
5799
5925
|
}
|
|
5800
5926
|
function checkUnreferencedAlterHandlers(lx, Comp, referencedAlters) {
|
|
5801
5927
|
for (const name in Comp.alter) {
|
|
@@ -5804,15 +5930,8 @@ function checkUnreferencedAlterHandlers(lx, Comp, referencedAlters) {
|
|
|
5804
5930
|
}
|
|
5805
5931
|
}
|
|
5806
5932
|
}
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
if (!referencedInputs.has(name)) {
|
|
5810
|
-
lx.hint(INPUT_HANDLER_NOT_REFERENCED, { name });
|
|
5811
|
-
}
|
|
5812
|
-
}
|
|
5813
|
-
}
|
|
5814
|
-
var HANDLER_CHANNELS = ["input", "receive", "bubble", "response", "alter"];
|
|
5815
|
-
var ASYNC_HANDLER_HELP = "Move the async work into a request handler and trigger it with ctx.request('name', args), then handle the result in a synchronous response handler. To coordinate other components, keep the handler synchronous and use ctx.send to deliver a message or ctx.bubble to raise an event.";
|
|
5933
|
+
var HANDLER_CHANNELS = ["receive", "intent", "alter"];
|
|
5934
|
+
var ASYNC_HANDLER_HELP = `Move the async work into a scope-registered intent handler and trigger it with ctx.intent("name", args, { route: ["lex"] }), then read the outcome in the synchronous \`receive\` arms named after it: <name>Ok, <name>Error and <name>Unhandled. To coordinate other components, keep the handler synchronous and use ctx.send to address one, or ctx.intent to let a route find one.`;
|
|
5816
5935
|
function checkHandlersNotAsync(lx, Comp) {
|
|
5817
5936
|
for (const channel of HANDLER_CHANNELS) {
|
|
5818
5937
|
const block = Comp[channel];
|
|
@@ -6008,8 +6127,11 @@ var Components = class {
|
|
|
6008
6127
|
getHandlerFor(v, name, key) {
|
|
6009
6128
|
return this.getCompFor(v)?.[key][name] ?? null;
|
|
6010
6129
|
}
|
|
6011
|
-
|
|
6012
|
-
|
|
6130
|
+
// The `lex` leg of an intent's route: the handlers registered on the scope chain of
|
|
6131
|
+
// the component that raised it, innermost first. A list, not a first match — see
|
|
6132
|
+
// ComponentStack.lookupIntentChain.
|
|
6133
|
+
getIntentChainFor(v, name) {
|
|
6134
|
+
return this.getCompFor(v)?.scope.lookupIntentChain(name) ?? [];
|
|
6013
6135
|
}
|
|
6014
6136
|
compileStyles() {
|
|
6015
6137
|
const styles = [];
|
|
@@ -6022,7 +6144,7 @@ var ComponentStack = class _ComponentStack {
|
|
|
6022
6144
|
this.comps = comps;
|
|
6023
6145
|
this.parent = parent;
|
|
6024
6146
|
this.byName = {};
|
|
6025
|
-
this.
|
|
6147
|
+
this.intentsByName = {};
|
|
6026
6148
|
this.macros = {};
|
|
6027
6149
|
}
|
|
6028
6150
|
enter() {
|
|
@@ -6054,11 +6176,21 @@ var ComponentStack = class _ComponentStack {
|
|
|
6054
6176
|
getCompFor(v) {
|
|
6055
6177
|
return this.comps.getCompFor(v);
|
|
6056
6178
|
}
|
|
6057
|
-
|
|
6058
|
-
|
|
6179
|
+
// Handlers that answer an intent's `lex` leg. A name maps to a LIST, because the leg
|
|
6180
|
+
// walks: a handler that returns PASS declines and hands the intent to the next one.
|
|
6181
|
+
// A bare function is accepted as a one-element list.
|
|
6182
|
+
registerIntentHandlers(handlers) {
|
|
6183
|
+
for (const name in handlers) {
|
|
6184
|
+
const fns = Array.isArray(handlers[name]) ? handlers[name] : [handlers[name]];
|
|
6185
|
+
this.intentsByName[name] = fns.map((fn) => new IntentHandler(name, fn));
|
|
6186
|
+
}
|
|
6059
6187
|
}
|
|
6060
|
-
|
|
6061
|
-
|
|
6188
|
+
// Innermost scope first, then outward. Concatenated rather than first-match, so a
|
|
6189
|
+
// declining handler can hand the intent to one further up.
|
|
6190
|
+
lookupIntentChain(name) {
|
|
6191
|
+
const here = this.intentsByName[name] ?? [];
|
|
6192
|
+
const up = this.parent?.lookupIntentChain(name) ?? [];
|
|
6193
|
+
return up.length === 0 ? here : here.concat(up);
|
|
6062
6194
|
}
|
|
6063
6195
|
lookupComponent(name) {
|
|
6064
6196
|
return this.byName[name] ?? this.parent?.lookupComponent(name) ?? null;
|
|
@@ -6089,7 +6221,7 @@ var LookupInfo = class {
|
|
|
6089
6221
|
}
|
|
6090
6222
|
};
|
|
6091
6223
|
var isString = (v) => typeof v === "string";
|
|
6092
|
-
var _rawSpecKeys = "name view style commonStyle globalStyle
|
|
6224
|
+
var _rawSpecKeys = "name view style commonStyle globalStyle receive intent alter views provide lookup fields methods statics";
|
|
6093
6225
|
var KNOWN_SPEC_KEYS = new Set(_rawSpecKeys.split(" "));
|
|
6094
6226
|
var _compId = 0;
|
|
6095
6227
|
var Component = class {
|
|
@@ -6100,10 +6232,8 @@ var Component = class {
|
|
|
6100
6232
|
this.views = { main: new View("main", o.view, o.style) };
|
|
6101
6233
|
this.commonStyle = o.commonStyle ?? "";
|
|
6102
6234
|
this.globalStyle = o.globalStyle ?? "";
|
|
6103
|
-
this.input = o.input ?? {};
|
|
6104
6235
|
this.receive = o.receive ?? {};
|
|
6105
|
-
this.
|
|
6106
|
-
this.response = o.response ?? {};
|
|
6236
|
+
this.intent = o.intent ?? {};
|
|
6107
6237
|
this.alter = o.alter ?? {};
|
|
6108
6238
|
for (const name in o.views ?? {}) {
|
|
6109
6239
|
const v = o.views[name];
|
|
@@ -6165,7 +6295,7 @@ var Component = class {
|
|
|
6165
6295
|
};
|
|
6166
6296
|
|
|
6167
6297
|
// src/on.js
|
|
6168
|
-
var OP_KINDS = ["send", "
|
|
6298
|
+
var OP_KINDS = ["send", "intent"];
|
|
6169
6299
|
function phaseOps(phase) {
|
|
6170
6300
|
const ops = [];
|
|
6171
6301
|
for (const type of OP_KINDS) for (const a of phase[type] ?? []) ops.push({ type, ...a });
|
|
@@ -6175,11 +6305,6 @@ function phaseOps(phase) {
|
|
|
6175
6305
|
function resolveArgs(args, self) {
|
|
6176
6306
|
return typeof args === "function" ? args(self) ?? [] : args ?? [];
|
|
6177
6307
|
}
|
|
6178
|
-
function phaseHasBubble(phase) {
|
|
6179
|
-
if (!phase) return false;
|
|
6180
|
-
if (phase.bubble?.length) return true;
|
|
6181
|
-
return (phase.do ?? []).some((op) => op.type === "bubble");
|
|
6182
|
-
}
|
|
6183
6308
|
function dispatchPhase(dispatcher, targetPath, phase, self) {
|
|
6184
6309
|
if (!phase) return;
|
|
6185
6310
|
for (const op of phaseOps(phase)) {
|
|
@@ -6188,23 +6313,323 @@ function dispatchPhase(dispatcher, targetPath, phase, self) {
|
|
|
6188
6313
|
case "send":
|
|
6189
6314
|
dispatcher.sendAtPath(targetPath, op.name, args, op.opts);
|
|
6190
6315
|
break;
|
|
6191
|
-
case "
|
|
6192
|
-
dispatcher.
|
|
6193
|
-
skipSelf: true,
|
|
6194
|
-
bubbles: true,
|
|
6195
|
-
...op.opts
|
|
6196
|
-
});
|
|
6197
|
-
break;
|
|
6198
|
-
case "request":
|
|
6199
|
-
dispatcher.requestAtPath(targetPath, op.name, args, op.opts);
|
|
6200
|
-
break;
|
|
6201
|
-
case "input":
|
|
6202
|
-
dispatcher.inputAtPath(targetPath, op.name, args, op.opts);
|
|
6316
|
+
case "intent":
|
|
6317
|
+
dispatcher.intentAtPath(targetPath, op.name, args, op.opts);
|
|
6203
6318
|
break;
|
|
6204
6319
|
}
|
|
6205
6320
|
}
|
|
6206
6321
|
}
|
|
6207
6322
|
|
|
6323
|
+
// src/oo.js
|
|
6324
|
+
var BAD_VALUE2 = /* @__PURE__ */ Symbol("BadValue");
|
|
6325
|
+
var nullCoercer = (v) => v;
|
|
6326
|
+
var isPlainObject2 = (v) => {
|
|
6327
|
+
if (v === null || typeof v !== "object") return false;
|
|
6328
|
+
const proto = Object.getPrototypeOf(v);
|
|
6329
|
+
return proto === Object.prototype || proto === null;
|
|
6330
|
+
};
|
|
6331
|
+
function defaultToData(v) {
|
|
6332
|
+
if (v instanceof Map) return [...v.entries()];
|
|
6333
|
+
if (v instanceof Set) return [...v.values()];
|
|
6334
|
+
return v;
|
|
6335
|
+
}
|
|
6336
|
+
var Field = class {
|
|
6337
|
+
constructor(type, name, typeCheck, coercer, defaultValue = null) {
|
|
6338
|
+
this.type = type;
|
|
6339
|
+
this.name = name;
|
|
6340
|
+
this.typeCheck = typeCheck;
|
|
6341
|
+
this.coercer = coercer;
|
|
6342
|
+
this.checks = [];
|
|
6343
|
+
this.defaultValue = defaultValue;
|
|
6344
|
+
}
|
|
6345
|
+
toDataDef() {
|
|
6346
|
+
return { type: this.type, defaultValue: defaultToData(this.defaultValue) };
|
|
6347
|
+
}
|
|
6348
|
+
getFirstFailingCheck(v) {
|
|
6349
|
+
if (!this.typeCheck.isValid(v)) return this.typeCheck;
|
|
6350
|
+
for (const check3 of this.checks) if (!check3.isValid(v)) return check3;
|
|
6351
|
+
return null;
|
|
6352
|
+
}
|
|
6353
|
+
isValid(v) {
|
|
6354
|
+
return this.getFirstFailingCheck(v) === null;
|
|
6355
|
+
}
|
|
6356
|
+
addCheck(check3) {
|
|
6357
|
+
this.checks.push(check3);
|
|
6358
|
+
return this;
|
|
6359
|
+
}
|
|
6360
|
+
coerceOr(v, defaultValue = null) {
|
|
6361
|
+
if (this.isValid(v)) return v;
|
|
6362
|
+
const v1 = this.coercer(v);
|
|
6363
|
+
return this.isValid(v1) ? v1 : defaultValue;
|
|
6364
|
+
}
|
|
6365
|
+
coerceOrDefault(v) {
|
|
6366
|
+
return this.coerceOr(v, this.defaultValue);
|
|
6367
|
+
}
|
|
6368
|
+
};
|
|
6369
|
+
var Check = class {
|
|
6370
|
+
isValid(_v) {
|
|
6371
|
+
return true;
|
|
6372
|
+
}
|
|
6373
|
+
getMessage(_v) {
|
|
6374
|
+
return "Invalid";
|
|
6375
|
+
}
|
|
6376
|
+
};
|
|
6377
|
+
var CheckTypeAny = class extends Check {
|
|
6378
|
+
};
|
|
6379
|
+
var CHECK_TYPE_ANY = new CheckTypeAny();
|
|
6380
|
+
var FnCheck = class extends Check {
|
|
6381
|
+
constructor(isValidFn, getMessageFn) {
|
|
6382
|
+
super();
|
|
6383
|
+
this._isValid = isValidFn;
|
|
6384
|
+
this._getMessage = getMessageFn;
|
|
6385
|
+
}
|
|
6386
|
+
isValid(v) {
|
|
6387
|
+
return this._isValid(v);
|
|
6388
|
+
}
|
|
6389
|
+
getMessage(v) {
|
|
6390
|
+
return this._getMessage(v);
|
|
6391
|
+
}
|
|
6392
|
+
};
|
|
6393
|
+
var check = (fn, message) => new FnCheck(fn, () => message);
|
|
6394
|
+
var CHECK_TYPE_INT = check(Number.isInteger, "Integer expected");
|
|
6395
|
+
var CHECK_TYPE_FLOAT = check(Number.isFinite, "Float expected");
|
|
6396
|
+
var CHECK_TYPE_BOOL = check((v) => typeof v === "boolean", "Boolean expected");
|
|
6397
|
+
var CHECK_TYPE_STRING = check((v) => typeof v === "string", "String expected");
|
|
6398
|
+
var CHECK_TYPE_LIST = check(Array.isArray, "Array expected");
|
|
6399
|
+
var CHECK_TYPE_OBJECT = check(isPlainObject2, "Plain object expected");
|
|
6400
|
+
var CHECK_TYPE_MAP = check((v) => v instanceof Map, "Map expected");
|
|
6401
|
+
var CHECK_TYPE_SET = check((v) => v instanceof Set, "Set expected");
|
|
6402
|
+
var FieldBool = class extends Field {
|
|
6403
|
+
constructor(name, defaultValue = false) {
|
|
6404
|
+
super("bool", name, CHECK_TYPE_BOOL, (v) => !!v, defaultValue);
|
|
6405
|
+
}
|
|
6406
|
+
};
|
|
6407
|
+
var FieldAny = class extends Field {
|
|
6408
|
+
constructor(name, defaultValue = null) {
|
|
6409
|
+
super("any", name, CHECK_TYPE_ANY, nullCoercer, defaultValue);
|
|
6410
|
+
}
|
|
6411
|
+
toDataDef() {
|
|
6412
|
+
return { type: getTypeName(this.defaultValue) ?? "any", defaultValue: this.defaultValue };
|
|
6413
|
+
}
|
|
6414
|
+
};
|
|
6415
|
+
var FieldString = class extends Field {
|
|
6416
|
+
constructor(name, defaultValue = "") {
|
|
6417
|
+
super("text", name, CHECK_TYPE_STRING, (v) => v?.toString?.() ?? "", defaultValue);
|
|
6418
|
+
}
|
|
6419
|
+
};
|
|
6420
|
+
var FieldInt = class extends Field {
|
|
6421
|
+
constructor(name, defaultValue = 0) {
|
|
6422
|
+
super(
|
|
6423
|
+
"int",
|
|
6424
|
+
name,
|
|
6425
|
+
CHECK_TYPE_INT,
|
|
6426
|
+
(v) => Number.isFinite(v) ? Math.trunc(v) : null,
|
|
6427
|
+
defaultValue
|
|
6428
|
+
);
|
|
6429
|
+
}
|
|
6430
|
+
};
|
|
6431
|
+
var FieldFloat = class extends Field {
|
|
6432
|
+
constructor(name, defaultValue = 0) {
|
|
6433
|
+
super("float", name, CHECK_TYPE_FLOAT, (_) => null, defaultValue);
|
|
6434
|
+
}
|
|
6435
|
+
};
|
|
6436
|
+
var getTypeName = (v) => v?.constructor?.getMetaClass?.()?.name;
|
|
6437
|
+
var CheckTypeName = class {
|
|
6438
|
+
constructor(typeName) {
|
|
6439
|
+
this.typeName = typeName;
|
|
6440
|
+
}
|
|
6441
|
+
isValid(v) {
|
|
6442
|
+
return getTypeName(v) === this.typeName;
|
|
6443
|
+
}
|
|
6444
|
+
getMessage(v) {
|
|
6445
|
+
return `Expected "${this.typeName}", got "${getTypeName(v)}"`;
|
|
6446
|
+
}
|
|
6447
|
+
};
|
|
6448
|
+
var FieldComp = class extends Field {
|
|
6449
|
+
constructor(type, name, args) {
|
|
6450
|
+
super(type, name, new CheckTypeName(type), nullCoercer, null);
|
|
6451
|
+
this.args = args;
|
|
6452
|
+
}
|
|
6453
|
+
toDataDef() {
|
|
6454
|
+
return { component: this.type, args: this.args };
|
|
6455
|
+
}
|
|
6456
|
+
};
|
|
6457
|
+
var FieldList = class extends Field {
|
|
6458
|
+
constructor(name, defaultValue = []) {
|
|
6459
|
+
super("list", name, CHECK_TYPE_LIST, (v) => Array.isArray(v) ? [...v] : null, defaultValue);
|
|
6460
|
+
}
|
|
6461
|
+
};
|
|
6462
|
+
var FieldObject = class extends Field {
|
|
6463
|
+
constructor(name, defaultValue = {}) {
|
|
6464
|
+
super(
|
|
6465
|
+
"object",
|
|
6466
|
+
name,
|
|
6467
|
+
CHECK_TYPE_OBJECT,
|
|
6468
|
+
(v) => isPlainObject2(v) ? { ...v } : null,
|
|
6469
|
+
defaultValue
|
|
6470
|
+
);
|
|
6471
|
+
}
|
|
6472
|
+
};
|
|
6473
|
+
var FieldMap = class extends Field {
|
|
6474
|
+
constructor(name, defaultValue = /* @__PURE__ */ new Map()) {
|
|
6475
|
+
super(
|
|
6476
|
+
"map",
|
|
6477
|
+
name,
|
|
6478
|
+
CHECK_TYPE_MAP,
|
|
6479
|
+
(v) => {
|
|
6480
|
+
if (v instanceof Map) return new Map(v);
|
|
6481
|
+
if (Array.isArray(v) || isPlainObject2(v))
|
|
6482
|
+
return new Map(Array.isArray(v) ? v : Object.entries(v));
|
|
6483
|
+
return null;
|
|
6484
|
+
},
|
|
6485
|
+
defaultValue
|
|
6486
|
+
);
|
|
6487
|
+
}
|
|
6488
|
+
};
|
|
6489
|
+
var FieldSet = class extends Field {
|
|
6490
|
+
constructor(name, defaultValue = /* @__PURE__ */ new Set()) {
|
|
6491
|
+
super(
|
|
6492
|
+
"set",
|
|
6493
|
+
name,
|
|
6494
|
+
CHECK_TYPE_SET,
|
|
6495
|
+
(v) => v instanceof Set || Array.isArray(v) ? new Set(v) : null,
|
|
6496
|
+
defaultValue
|
|
6497
|
+
);
|
|
6498
|
+
}
|
|
6499
|
+
};
|
|
6500
|
+
function mkCompField(field, scope, args) {
|
|
6501
|
+
const Comp = scope?.lookupComponent(field.type) ?? null;
|
|
6502
|
+
if (Comp === null)
|
|
6503
|
+
console.warn(
|
|
6504
|
+
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)`
|
|
6505
|
+
);
|
|
6506
|
+
return Comp?.make({ ...field.args, ...args }, { scope }) ?? null;
|
|
6507
|
+
}
|
|
6508
|
+
var ClassBuilder = class {
|
|
6509
|
+
constructor(name) {
|
|
6510
|
+
this.name = name;
|
|
6511
|
+
this.fields = {};
|
|
6512
|
+
this.compFields = /* @__PURE__ */ new Set();
|
|
6513
|
+
this._methods = {};
|
|
6514
|
+
this._statics = {};
|
|
6515
|
+
}
|
|
6516
|
+
build() {
|
|
6517
|
+
const { name, fields, compFields, _methods } = this;
|
|
6518
|
+
const defaults = Object.fromEntries(
|
|
6519
|
+
Object.entries(fields).map(([fieldName, field]) => [fieldName, field.defaultValue])
|
|
6520
|
+
);
|
|
6521
|
+
const Class = {
|
|
6522
|
+
[name]: class {
|
|
6523
|
+
constructor(values = {}) {
|
|
6524
|
+
Object.assign(this, defaults, values);
|
|
6525
|
+
}
|
|
6526
|
+
}
|
|
6527
|
+
}[name];
|
|
6528
|
+
Class[immer_exports.immerable] = true;
|
|
6529
|
+
Object.assign(Class.prototype, _methods);
|
|
6530
|
+
const metaClass = { fields, name, methods: _methods };
|
|
6531
|
+
Object.assign(
|
|
6532
|
+
Class,
|
|
6533
|
+
{
|
|
6534
|
+
getMetaClass: () => metaClass,
|
|
6535
|
+
make(inArgs = {}, opts = {}) {
|
|
6536
|
+
const args = {};
|
|
6537
|
+
const scope = opts.scope ?? this.scope;
|
|
6538
|
+
for (const key in inArgs) {
|
|
6539
|
+
const field = fields[key];
|
|
6540
|
+
if (compFields.has(key)) args[key] = mkCompField(field, scope, inArgs[key]);
|
|
6541
|
+
else if (field === void 0)
|
|
6542
|
+
console.warn("extra argument to constructor:", name, key, inArgs);
|
|
6543
|
+
else args[key] = field.coerceOrDefault(inArgs[key]);
|
|
6544
|
+
}
|
|
6545
|
+
for (const key of compFields)
|
|
6546
|
+
if (args[key] === void 0) args[key] = mkCompField(fields[key], scope, inArgs[key]);
|
|
6547
|
+
return (0, immer_exports.freeze)(new this(args), true);
|
|
6548
|
+
}
|
|
6549
|
+
},
|
|
6550
|
+
this._statics
|
|
6551
|
+
);
|
|
6552
|
+
return Class;
|
|
6553
|
+
}
|
|
6554
|
+
methods(proto) {
|
|
6555
|
+
for (const k in proto) this._methods[k] = proto[k];
|
|
6556
|
+
}
|
|
6557
|
+
statics(proto) {
|
|
6558
|
+
for (const k in proto) this._statics[k] = proto[k];
|
|
6559
|
+
}
|
|
6560
|
+
addField(name, dval, FieldCls) {
|
|
6561
|
+
const field = new FieldCls(name, dval);
|
|
6562
|
+
this.fields[name] = field;
|
|
6563
|
+
return field;
|
|
6564
|
+
}
|
|
6565
|
+
addCompField(name, type, args) {
|
|
6566
|
+
const field = new FieldComp(type, name, args);
|
|
6567
|
+
this.compFields.add(name);
|
|
6568
|
+
this.fields[name] = field;
|
|
6569
|
+
return field;
|
|
6570
|
+
}
|
|
6571
|
+
};
|
|
6572
|
+
var FIELD_CLASS = /* @__PURE__ */ Symbol.for("tutuca.fieldClass");
|
|
6573
|
+
var fieldsByTypeName = {
|
|
6574
|
+
text: FieldString,
|
|
6575
|
+
int: FieldInt,
|
|
6576
|
+
float: FieldFloat,
|
|
6577
|
+
bool: FieldBool,
|
|
6578
|
+
list: FieldList,
|
|
6579
|
+
object: FieldObject,
|
|
6580
|
+
map: FieldMap,
|
|
6581
|
+
set: FieldSet,
|
|
6582
|
+
any: FieldAny
|
|
6583
|
+
};
|
|
6584
|
+
function fieldFromDescriptor(name, value) {
|
|
6585
|
+
const FieldCls = fieldsByTypeName[value.type] ?? FieldAny;
|
|
6586
|
+
const probe = new FieldCls(name);
|
|
6587
|
+
return [FieldCls, probe.coerceOr(value.defaultValue, probe.defaultValue)];
|
|
6588
|
+
}
|
|
6589
|
+
function classFromData(name, { fields = {}, methods, statics }) {
|
|
6590
|
+
const b = new ClassBuilder(name);
|
|
6591
|
+
for (const field in fields) {
|
|
6592
|
+
const value = fields[field];
|
|
6593
|
+
const type = typeof value;
|
|
6594
|
+
if (type === "string") b.addField(field, value, FieldString);
|
|
6595
|
+
else if (type === "number")
|
|
6596
|
+
b.addField(field, value, Number.isInteger(value) ? FieldInt : FieldFloat);
|
|
6597
|
+
else if (type === "boolean") b.addField(field, value, FieldBool);
|
|
6598
|
+
else if (Array.isArray(value)) b.addField(field, [...value], FieldList);
|
|
6599
|
+
else if (value instanceof Set) b.addField(field, new Set(value), FieldSet);
|
|
6600
|
+
else if (value instanceof Map) b.addField(field, new Map(value), FieldMap);
|
|
6601
|
+
else if (value?.type && Object.hasOwn(value, "defaultValue")) {
|
|
6602
|
+
const [FieldCls, dval] = fieldFromDescriptor(field, value);
|
|
6603
|
+
b.addField(field, dval, FieldCls);
|
|
6604
|
+
} else if (value?.component && value?.args !== void 0)
|
|
6605
|
+
b.addCompField(field, value.component, value.args);
|
|
6606
|
+
else if (isPlainObject2(value)) b.addField(field, { ...value }, FieldObject);
|
|
6607
|
+
else {
|
|
6608
|
+
const FieldCls = value?.[FIELD_CLASS] ?? FieldAny;
|
|
6609
|
+
b.addField(field, value, FieldCls);
|
|
6610
|
+
}
|
|
6611
|
+
}
|
|
6612
|
+
if (methods) b.methods(methods);
|
|
6613
|
+
if (statics) b.statics(statics);
|
|
6614
|
+
return b.build();
|
|
6615
|
+
}
|
|
6616
|
+
function validateDraftFields(current, draft) {
|
|
6617
|
+
const meta = current?.constructor?.getMetaClass?.();
|
|
6618
|
+
if (!meta) return;
|
|
6619
|
+
for (const [name, field] of Object.entries(meta.fields)) {
|
|
6620
|
+
const value = draft[name];
|
|
6621
|
+
if (field.isValid(value)) continue;
|
|
6622
|
+
const coerced = field.coerceOr(value, BAD_VALUE2);
|
|
6623
|
+
if (coerced !== BAD_VALUE2) draft[name] = coerced;
|
|
6624
|
+
else {
|
|
6625
|
+
console.warn(`invalid value for ${meta.name}.${name}`, value);
|
|
6626
|
+
draft[name] = current[name];
|
|
6627
|
+
}
|
|
6628
|
+
}
|
|
6629
|
+
}
|
|
6630
|
+
Component.fromSpec = (opts) => new Component(classFromData(opts.name, opts), opts);
|
|
6631
|
+
var component = (opts) => Component.fromSpec(opts);
|
|
6632
|
+
|
|
6208
6633
|
// src/stack.js
|
|
6209
6634
|
var STOP = /* @__PURE__ */ Symbol("STOP");
|
|
6210
6635
|
var NEXT = /* @__PURE__ */ Symbol("NEXT");
|
|
@@ -6263,12 +6688,12 @@ var Stack = class _Stack {
|
|
|
6263
6688
|
const provide = this.comps.getCompFor(this.it)?.provide;
|
|
6264
6689
|
if (provide == null) return this;
|
|
6265
6690
|
const dynObj = {};
|
|
6266
|
-
let
|
|
6691
|
+
let has = false;
|
|
6267
6692
|
for (const k in provide) {
|
|
6268
6693
|
dynObj[provide[k].symbol] = provide[k].val.eval(this);
|
|
6269
|
-
|
|
6694
|
+
has = true;
|
|
6270
6695
|
}
|
|
6271
|
-
if (!
|
|
6696
|
+
if (!has) return this;
|
|
6272
6697
|
const newDynBinds = [new ObjectFrame(dynObj), this.dynBinds];
|
|
6273
6698
|
const { comps, it, binds, views, viewsId, ctx } = this;
|
|
6274
6699
|
return new _Stack(comps, it, binds, newDynBinds, views, viewsId, ctx);
|
|
@@ -6371,8 +6796,11 @@ var Transactor = class {
|
|
|
6371
6796
|
this.transactions.push(t);
|
|
6372
6797
|
this.onTransactionPushed(t);
|
|
6373
6798
|
}
|
|
6374
|
-
// Subscribe to a normalized record for every handler invocation
|
|
6375
|
-
//
|
|
6799
|
+
// Subscribe to a normalized record for every handler invocation. `kind` is the
|
|
6800
|
+
// handler bucket (`receive` / `intent`), plus `answer` — an observation-only kind for
|
|
6801
|
+
// a message the runtime wrote to answer an intent. The BUCKET does not know about
|
|
6802
|
+
// that distinction, and must not: a handler cannot tell an answer from a message its
|
|
6803
|
+
// parent sent. Returns an unsubscribe function. Records
|
|
6376
6804
|
// carry: kind, name, args, path, pathKeys, targetPath, handler, handlerName,
|
|
6377
6805
|
// matched, before, after, parent, timestamp. Purely observational.
|
|
6378
6806
|
observe(cb) {
|
|
@@ -6425,23 +6853,14 @@ var Transactor = class {
|
|
|
6425
6853
|
this.pushTransaction(t);
|
|
6426
6854
|
return this._link(t, parent);
|
|
6427
6855
|
}
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
}
|
|
6433
|
-
pushBubble(path, name, args = [], opts = {}, parent = null, targetPath = null) {
|
|
6434
|
-
const newOpts = opts.skipSelf ? { ...opts, skipSelf: false } : opts;
|
|
6435
|
-
const t = new BubbleEvent(path, this, name, args, parent, newOpts, targetPath);
|
|
6436
|
-
this.pushTransaction(t);
|
|
6437
|
-
return this._link(t, parent);
|
|
6438
|
-
}
|
|
6439
|
-
pushRequest(path, name, args = [], opts = {}, parent = null) {
|
|
6856
|
+
// Raise an intent: a job the sender did not address, walked along a route until
|
|
6857
|
+
// something answers. `opts.route` is a list of legs (see DEFAULT_ROUTE) and
|
|
6858
|
+
// `opts.livePath` opts out of pinning the answer's destination keys.
|
|
6859
|
+
pushIntent(path, name, args = [], opts = {}, parent = null) {
|
|
6440
6860
|
const release = parent ? parent.completion.track() : null;
|
|
6441
|
-
const
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
return p;
|
|
6861
|
+
const walk = new IntentWalk(this, path, name, args, opts, parent, release);
|
|
6862
|
+
walk.advance();
|
|
6863
|
+
return walk;
|
|
6445
6864
|
}
|
|
6446
6865
|
// Drain queued transactions and await in-flight requests until quiescent. Each
|
|
6447
6866
|
// awaited request enqueues a ResponseEvent, which may dispatch more work, so we
|
|
@@ -6452,57 +6871,6 @@ var Transactor = class {
|
|
|
6452
6871
|
if (this._inflight.size) await Promise.allSettled([...this._inflight]);
|
|
6453
6872
|
}
|
|
6454
6873
|
}
|
|
6455
|
-
async _runRequest(path, name, args = [], opts = {}, parent = null, release = null) {
|
|
6456
|
-
let released = false;
|
|
6457
|
-
const transfer = (t) => {
|
|
6458
|
-
if (release) {
|
|
6459
|
-
released = true;
|
|
6460
|
-
t.completion.whenSubtreeSettled().then(release);
|
|
6461
|
-
}
|
|
6462
|
-
};
|
|
6463
|
-
try {
|
|
6464
|
-
const curRoot = this.state.val;
|
|
6465
|
-
const txnPath = path.toTransactionPath();
|
|
6466
|
-
const curLeaf = txnPath.lookup(curRoot);
|
|
6467
|
-
const found = this.comps.getRequestFor(curLeaf, name);
|
|
6468
|
-
const handler = found ?? mkReq404(name);
|
|
6469
|
-
if (this._observers.length > 0) {
|
|
6470
|
-
const reqPath = txnPath.pinKeys(curRoot);
|
|
6471
|
-
this._emit({
|
|
6472
|
-
kind: "request",
|
|
6473
|
-
name,
|
|
6474
|
-
args,
|
|
6475
|
-
path: reqPath,
|
|
6476
|
-
pathKeys: reqPath.toKeys(),
|
|
6477
|
-
targetPath: path,
|
|
6478
|
-
handler: found?.fn ?? null,
|
|
6479
|
-
handlerName: found?.fn?.name || name,
|
|
6480
|
-
matched: found ? "exact" : "none",
|
|
6481
|
-
before: curLeaf,
|
|
6482
|
-
after: void 0,
|
|
6483
|
-
parent,
|
|
6484
|
-
timestamp: Date.now()
|
|
6485
|
-
});
|
|
6486
|
-
}
|
|
6487
|
-
const reqCtx = new RequestContext(path, this, parent, curRoot);
|
|
6488
|
-
const resHandlerName = opts?.onResName ?? name;
|
|
6489
|
-
const resPath = opts?.livePath ? null : txnPath.pinKeys(curRoot);
|
|
6490
|
-
const push = (specificName, baseName, singleArg, result, error) => {
|
|
6491
|
-
const resArgs = specificName ? [singleArg] : [result, error];
|
|
6492
|
-
const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent, resPath);
|
|
6493
|
-
transfer(t);
|
|
6494
|
-
this.pushTransaction(t);
|
|
6495
|
-
};
|
|
6496
|
-
try {
|
|
6497
|
-
const result = await handler.fn.apply(null, [...args, reqCtx]);
|
|
6498
|
-
push(opts?.onOkName, resHandlerName, result, result, null);
|
|
6499
|
-
} catch (error) {
|
|
6500
|
-
push(opts?.onErrorName, resHandlerName, error, null, error);
|
|
6501
|
-
}
|
|
6502
|
-
} finally {
|
|
6503
|
-
if (release && !released) release();
|
|
6504
|
-
}
|
|
6505
|
-
}
|
|
6506
6874
|
get hasPendingTransactions() {
|
|
6507
6875
|
return this.transactions.length > 0;
|
|
6508
6876
|
}
|
|
@@ -6519,6 +6887,7 @@ var Transactor = class {
|
|
|
6519
6887
|
this._emitTransaction(transaction, curState);
|
|
6520
6888
|
} else console.warn("undefined new state", { curState, transaction });
|
|
6521
6889
|
} finally {
|
|
6890
|
+
transaction.ensureWalkAdvanced?.();
|
|
6522
6891
|
transaction._completion?.ensureSelfSettled();
|
|
6523
6892
|
transaction._completion?.releaseSelf();
|
|
6524
6893
|
}
|
|
@@ -6527,12 +6896,6 @@ var Transactor = class {
|
|
|
6527
6896
|
this.transact(new InputEvent(path, event, eventHandler, this, dragInfo));
|
|
6528
6897
|
}
|
|
6529
6898
|
};
|
|
6530
|
-
function mkReq404(name) {
|
|
6531
|
-
const fn = () => {
|
|
6532
|
-
throw new Error(`Request not found: ${name}`);
|
|
6533
|
-
};
|
|
6534
|
-
return { fn };
|
|
6535
|
-
}
|
|
6536
6899
|
function nullHandler() {
|
|
6537
6900
|
return this;
|
|
6538
6901
|
}
|
|
@@ -6563,6 +6926,15 @@ var Transaction = class {
|
|
|
6563
6926
|
}
|
|
6564
6927
|
afterTransaction() {
|
|
6565
6928
|
}
|
|
6929
|
+
// Ending a walk and forwarding belong to the two dispatch buckets; the base warns
|
|
6930
|
+
// rather than throwing, so a stray call from the wrong place is a message and not a
|
|
6931
|
+
// crash. `walk` is undefined here, which is how ctx.reply/ctx.fail tell the two apart.
|
|
6932
|
+
stop() {
|
|
6933
|
+
console.warn('ctx.stop() is only meaningful in an "intent" handler - ignored');
|
|
6934
|
+
}
|
|
6935
|
+
forward(_opts) {
|
|
6936
|
+
console.warn('ctx.forward() needs a "receive" or "intent" handler - ignored');
|
|
6937
|
+
}
|
|
6566
6938
|
buildRootStack(root, comps) {
|
|
6567
6939
|
return Stack.root(comps, root);
|
|
6568
6940
|
}
|
|
@@ -6579,10 +6951,10 @@ var Transaction = class {
|
|
|
6579
6951
|
get observeName() {
|
|
6580
6952
|
return null;
|
|
6581
6953
|
}
|
|
6582
|
-
callHandler(root, instance, comps) {
|
|
6954
|
+
callHandler(root, instance, draft, comps) {
|
|
6583
6955
|
const [handler, args] = this.getHandlerAndArgs(root, instance, comps);
|
|
6584
6956
|
this._resolvedHandler = handler;
|
|
6585
|
-
return handler.apply(instance, args);
|
|
6957
|
+
return handler.apply(instance, [draft, ...args]);
|
|
6586
6958
|
}
|
|
6587
6959
|
getHandlerAndArgs(_root, _instance, _comps) {
|
|
6588
6960
|
return null;
|
|
@@ -6591,12 +6963,16 @@ var Transaction = class {
|
|
|
6591
6963
|
// the data's real location (the dispatch `this.path` keeps intermediates). A subclass
|
|
6592
6964
|
// may override to supply a pre-resolved path (see ResponseEvent's pinned keys).
|
|
6593
6965
|
getTransactionPath() {
|
|
6594
|
-
return this.path.toTransactionPath();
|
|
6966
|
+
return this.path.toTransactionPath().compact();
|
|
6595
6967
|
}
|
|
6596
6968
|
updateRootValue(curRoot, comps) {
|
|
6597
6969
|
const txnPath = this.getTransactionPath();
|
|
6598
6970
|
const curLeaf = txnPath.lookup(curRoot);
|
|
6599
|
-
const newLeaf =
|
|
6971
|
+
const newLeaf = (0, immer_exports.produce)(curLeaf, (draft) => {
|
|
6972
|
+
const result = this.callHandler(curRoot, curLeaf, draft, comps);
|
|
6973
|
+
if (result === void 0 || result === draft) validateDraftFields(curLeaf, draft);
|
|
6974
|
+
return result;
|
|
6975
|
+
});
|
|
6600
6976
|
this._before = curLeaf;
|
|
6601
6977
|
this._after = newLeaf;
|
|
6602
6978
|
this._completion?.markSelfSettled({ value: newLeaf, old: curLeaf });
|
|
@@ -6624,18 +7000,40 @@ var InputEvent = class extends Transaction {
|
|
|
6624
7000
|
this._dispatchPath ??= this.path.compact();
|
|
6625
7001
|
return this._dispatchPath;
|
|
6626
7002
|
}
|
|
7003
|
+
// A DOM event is an ADDRESSED message like any other — it reaches the component that
|
|
7004
|
+
// owns the view and stops. It keeps its own class only because it resolves its handler
|
|
7005
|
+
// from the compiled view and runs synchronously, not because it is a different channel.
|
|
6627
7006
|
get observeKind() {
|
|
6628
|
-
return "
|
|
7007
|
+
return "receive";
|
|
6629
7008
|
}
|
|
6630
7009
|
get observeName() {
|
|
6631
7010
|
return this.e?.type ?? null;
|
|
6632
7011
|
}
|
|
7012
|
+
// A view's name is a message. `forward` is where that name can LEAVE the component:
|
|
7013
|
+
// it becomes an intent with the same name and the same arguments, so a view that says
|
|
7014
|
+
// `@on.click="saveDraft .text"` never has to change when an ancestor takes the job over.
|
|
7015
|
+
// (A `$method` handler has a name too, so forwarding one raises an intent under it.)
|
|
7016
|
+
forward(opts) {
|
|
7017
|
+
this._forward = opts ?? {};
|
|
7018
|
+
}
|
|
7019
|
+
afterTransaction() {
|
|
7020
|
+
const f = this._forward;
|
|
7021
|
+
if (f === void 0) return;
|
|
7022
|
+
this._forward = void 0;
|
|
7023
|
+
const { args = this._handlerArgs ?? [], ...rest } = f;
|
|
7024
|
+
const hv = this.handler?.handlerCall?.handlerVal ?? this.handler?.handlerVal;
|
|
7025
|
+
const name = hv?.name;
|
|
7026
|
+
if (name === void 0)
|
|
7027
|
+
return console.warn("ctx.forward() from a handler with no name - ignored");
|
|
7028
|
+
this.transactor.pushIntent(this.dispatchPath, name, args, rest, this);
|
|
7029
|
+
}
|
|
6633
7030
|
buildRootStack(root, comps) {
|
|
6634
7031
|
return Stack.root(comps, root, this);
|
|
6635
7032
|
}
|
|
6636
7033
|
getHandlerAndArgs(root, _instance, comps) {
|
|
6637
7034
|
const stack = this.buildStack(root, comps);
|
|
6638
7035
|
const [handler, args] = this.handler.getHandlerAndArgs(stack, this);
|
|
7036
|
+
this._handlerArgs = [...args];
|
|
6639
7037
|
const path = this.dispatchPath;
|
|
6640
7038
|
args.push(new EventContext(path, this.transactor, this));
|
|
6641
7039
|
return [handler, args];
|
|
@@ -6720,39 +7118,190 @@ var NameArgsTransaction = class extends Transaction {
|
|
|
6720
7118
|
return [handler, [...this.args, new EventContext(this.path, this.transactor, this)]];
|
|
6721
7119
|
}
|
|
6722
7120
|
};
|
|
6723
|
-
var ResponseEvent = class extends NameArgsTransaction {
|
|
6724
|
-
handlerProp = "response";
|
|
6725
|
-
constructor(path, transactor, name, args, parent, txnPath = null) {
|
|
6726
|
-
super(path, transactor, name, args, parent);
|
|
6727
|
-
this._txnPath = txnPath;
|
|
6728
|
-
}
|
|
6729
|
-
getTransactionPath() {
|
|
6730
|
-
return this._txnPath ?? super.getTransactionPath();
|
|
6731
|
-
}
|
|
6732
|
-
};
|
|
6733
7121
|
var SendEvent = class extends NameArgsTransaction {
|
|
6734
7122
|
handlerProp = "receive";
|
|
6735
|
-
|
|
6736
|
-
|
|
7123
|
+
// `receive` is the ADDRESSED bucket, and it is the only one: a view's `@on.click`,
|
|
7124
|
+
// a parent's ctx.send, the host's sendAtRoot and an answer to an intent all arrive
|
|
7125
|
+
// here, and a handler cannot tell them apart. Splitting on where a message came from
|
|
7126
|
+
// would let the view's name through and turn the parent's away, though the two say
|
|
7127
|
+
// the same thing — and neither a test nor a parent could drive the component.
|
|
7128
|
+
get observeKind() {
|
|
7129
|
+
return this._isAnswer ? "answer" : "receive";
|
|
7130
|
+
}
|
|
7131
|
+
// `forward` in a RECEIVE body starts a walk: the message that arrived becomes an
|
|
7132
|
+
// intent, keeping its name and payload. This is what lets a view's name leave the
|
|
7133
|
+
// component without the view changing.
|
|
7134
|
+
forward(opts) {
|
|
7135
|
+
this._forward = opts ?? {};
|
|
6737
7136
|
}
|
|
6738
7137
|
afterTransaction() {
|
|
6739
|
-
const
|
|
6740
|
-
if (
|
|
6741
|
-
|
|
7138
|
+
const f = this._forward;
|
|
7139
|
+
if (f === void 0) return;
|
|
7140
|
+
this._forward = void 0;
|
|
7141
|
+
const { args = this.args, ...rest } = f;
|
|
7142
|
+
this.transactor.pushIntent(this.path, this.name, args, rest, this);
|
|
6742
7143
|
}
|
|
6743
7144
|
};
|
|
6744
|
-
var
|
|
6745
|
-
handlerProp = "
|
|
6746
|
-
constructor(path, transactor,
|
|
6747
|
-
super(path, transactor, name, args, parent,
|
|
6748
|
-
this.
|
|
7145
|
+
var IntentEvent = class extends NameArgsTransaction {
|
|
7146
|
+
handlerProp = "intent";
|
|
7147
|
+
constructor(path, transactor, walk) {
|
|
7148
|
+
super(path, transactor, walk.name, walk.args, walk.parent, {});
|
|
7149
|
+
this.walk = walk;
|
|
7150
|
+
this.targetPath = walk.origin;
|
|
7151
|
+
}
|
|
7152
|
+
// `forward` in an INTENT body amends the hop about to be pushed — it does not push
|
|
7153
|
+
// one itself, because a walk advances on its own.
|
|
7154
|
+
forward(opts) {
|
|
7155
|
+
this.walk.amend(opts, this.path);
|
|
7156
|
+
}
|
|
7157
|
+
stop() {
|
|
7158
|
+
this.walk.finish(null, null);
|
|
7159
|
+
}
|
|
7160
|
+
afterTransaction() {
|
|
7161
|
+
this.ensureWalkAdvanced();
|
|
6749
7162
|
}
|
|
6750
|
-
|
|
6751
|
-
|
|
7163
|
+
// Idempotent, because both afterTransaction and the transactor's `finally` call it —
|
|
7164
|
+
// whichever gets there first advances the walk exactly once.
|
|
7165
|
+
ensureWalkAdvanced() {
|
|
7166
|
+
if (this._advanced) return;
|
|
7167
|
+
this._advanced = true;
|
|
7168
|
+
this.walk.advance();
|
|
6752
7169
|
}
|
|
6753
7170
|
};
|
|
6754
|
-
var
|
|
6755
|
-
|
|
7171
|
+
var PASS = /* @__PURE__ */ Symbol.for("tutuca.intent.pass");
|
|
7172
|
+
var DEFAULT_ROUTE = ["dyn", "lex"];
|
|
7173
|
+
var INTENT_DEPTH = 64;
|
|
7174
|
+
var IntentWalk = class {
|
|
7175
|
+
constructor(transactor, path, name, args, opts, parent, release) {
|
|
7176
|
+
this.transactor = transactor;
|
|
7177
|
+
this.name = name;
|
|
7178
|
+
this.args = args;
|
|
7179
|
+
this.route = opts?.route ?? DEFAULT_ROUTE;
|
|
7180
|
+
this.parent = parent;
|
|
7181
|
+
this.release = release;
|
|
7182
|
+
this.origin = path;
|
|
7183
|
+
this.answerPath = opts?.livePath ? null : path.toTransactionPath().pinKeys(transactor.state.val);
|
|
7184
|
+
this.legIndex = 0;
|
|
7185
|
+
this.dynAt = path;
|
|
7186
|
+
this.hops = 0;
|
|
7187
|
+
this.ended = false;
|
|
7188
|
+
}
|
|
7189
|
+
// Offer the intent to the next hop. Called once at dispatch, and again by every hop
|
|
7190
|
+
// that ran without answering.
|
|
7191
|
+
advance() {
|
|
7192
|
+
if (this.ended) return;
|
|
7193
|
+
if (this.hops++ >= INTENT_DEPTH) return this.exhaust("intentDepth");
|
|
7194
|
+
while (this.legIndex < this.route.length) {
|
|
7195
|
+
const leg = this.route[this.legIndex];
|
|
7196
|
+
if (leg === "dyn") {
|
|
7197
|
+
if (this.dynAt.steps.length === 0) {
|
|
7198
|
+
this.legIndex++;
|
|
7199
|
+
continue;
|
|
7200
|
+
}
|
|
7201
|
+
this.dynAt = this.dynAt.popStep();
|
|
7202
|
+
this.transactor.pushTransaction(new IntentEvent(this.dynAt, this.transactor, this));
|
|
7203
|
+
return;
|
|
7204
|
+
}
|
|
7205
|
+
if (leg === "lex") {
|
|
7206
|
+
this.legIndex++;
|
|
7207
|
+
return this._tryLex();
|
|
7208
|
+
}
|
|
7209
|
+
console.warn("unknown intent route leg", leg, '- expected "dyn" or "lex"');
|
|
7210
|
+
this.legIndex++;
|
|
7211
|
+
}
|
|
7212
|
+
this.exhaust("noHandler");
|
|
7213
|
+
}
|
|
7214
|
+
// The `lex` leg: the handlers registered on the scope chain of the component that
|
|
7215
|
+
// raised the intent, in order.
|
|
7216
|
+
_tryLex() {
|
|
7217
|
+
const root = this.transactor.state.val;
|
|
7218
|
+
const txnPath = this.origin.toTransactionPath();
|
|
7219
|
+
const leaf = txnPath.lookup(root);
|
|
7220
|
+
const chain = this.transactor.comps.getIntentChainFor(leaf, this.name);
|
|
7221
|
+
if (this.transactor._observers.length > 0) {
|
|
7222
|
+
const path = txnPath.pinKeys(root);
|
|
7223
|
+
this.transactor._emit({
|
|
7224
|
+
kind: "intent",
|
|
7225
|
+
name: this.name,
|
|
7226
|
+
args: this.args,
|
|
7227
|
+
path,
|
|
7228
|
+
pathKeys: path.toKeys(),
|
|
7229
|
+
targetPath: this.origin,
|
|
7230
|
+
handler: chain[0]?.fn ?? null,
|
|
7231
|
+
handlerName: chain[0]?.fn?.name || this.name,
|
|
7232
|
+
matched: chain.length > 0 ? "exact" : "none",
|
|
7233
|
+
before: leaf,
|
|
7234
|
+
after: void 0,
|
|
7235
|
+
parent: this.parent,
|
|
7236
|
+
timestamp: Date.now()
|
|
7237
|
+
});
|
|
7238
|
+
}
|
|
7239
|
+
if (chain.length === 0) return this.advance();
|
|
7240
|
+
const p = this._runLex(chain, 0);
|
|
7241
|
+
this.transactor._inflight.add(p);
|
|
7242
|
+
p.finally(() => this.transactor._inflight.delete(p));
|
|
7243
|
+
}
|
|
7244
|
+
async _runLex(chain, i) {
|
|
7245
|
+
if (this.ended) return;
|
|
7246
|
+
if (i >= chain.length) return this.advance();
|
|
7247
|
+
const ctx = new IntentContext(this.origin, this.transactor, this.parent);
|
|
7248
|
+
try {
|
|
7249
|
+
const res = await chain[i].fn.apply(null, [...this.args, ctx]);
|
|
7250
|
+
if (res === PASS) return this._runLex(chain, i + 1);
|
|
7251
|
+
this.answer("Ok", res);
|
|
7252
|
+
} catch (error) {
|
|
7253
|
+
this.answer("Error", error);
|
|
7254
|
+
}
|
|
7255
|
+
}
|
|
7256
|
+
// A hop answered. Ends the walk.
|
|
7257
|
+
answer(suffix, value) {
|
|
7258
|
+
this.finish(`${this.name}${suffix}`, [value]);
|
|
7259
|
+
}
|
|
7260
|
+
// `forward` from an intent body: keep walking, optionally with new arguments or a
|
|
7261
|
+
// narrowed route.
|
|
7262
|
+
amend(opts, from) {
|
|
7263
|
+
if (opts?.args !== void 0) this.args = opts.args;
|
|
7264
|
+
if (opts?.route !== void 0) {
|
|
7265
|
+
this.route = opts.route;
|
|
7266
|
+
this.legIndex = 0;
|
|
7267
|
+
this.dynAt = from ?? this.dynAt;
|
|
7268
|
+
}
|
|
7269
|
+
}
|
|
7270
|
+
// The route ran out. What the sender hears depends only on what it DECLARES, which is
|
|
7271
|
+
// how "a sender expects an answer if and only if it declares an answer arm" becomes
|
|
7272
|
+
// code — nobody writes it down twice, and there is no schema to keep in step.
|
|
7273
|
+
exhaust(reason) {
|
|
7274
|
+
if (this.ended) return;
|
|
7275
|
+
const { name, args } = this;
|
|
7276
|
+
const comp = this.transactor.comps.getCompFor(
|
|
7277
|
+
this.origin.toTransactionPath().lookup(this.transactor.state.val)
|
|
7278
|
+
);
|
|
7279
|
+
const declares = (n) => comp?.receive?.[n] !== void 0;
|
|
7280
|
+
if (declares(`${name}Unhandled`)) {
|
|
7281
|
+
this.finish(`${name}Unhandled`, args);
|
|
7282
|
+
} else if (declares(`${name}Error`)) {
|
|
7283
|
+
this.finish(`${name}Error`, [reason]);
|
|
7284
|
+
} else {
|
|
7285
|
+
if (declares(`${name}Ok`))
|
|
7286
|
+
console.warn(
|
|
7287
|
+
`intent "${name}" was not answered (${reason}) and this component declares only "${name}Ok" - add "${name}Unhandled" or "${name}Error" to handle it`
|
|
7288
|
+
);
|
|
7289
|
+
this.finish(null, null);
|
|
7290
|
+
}
|
|
7291
|
+
}
|
|
7292
|
+
// End the walk. `name === null` means no answer goes out, which is what `stop` and a
|
|
7293
|
+
// fire-and-forget notification both are — the tracked unit is released here instead
|
|
7294
|
+
// of following an answer's subtree.
|
|
7295
|
+
finish(name, args) {
|
|
7296
|
+
if (this.ended) return;
|
|
7297
|
+
this.ended = true;
|
|
7298
|
+
if (name === null) return this.release?.();
|
|
7299
|
+
const path = this.answerPath ?? this.origin;
|
|
7300
|
+
const t = new SendEvent(path, this.transactor, name, args, this.parent, {});
|
|
7301
|
+
t._isAnswer = true;
|
|
7302
|
+
this.transactor.pushTransaction(t);
|
|
7303
|
+
if (this.release) t.completion.whenSubtreeSettled().then(this.release);
|
|
7304
|
+
}
|
|
6756
7305
|
};
|
|
6757
7306
|
var Completion = class {
|
|
6758
7307
|
constructor() {
|
|
@@ -6833,23 +7382,21 @@ var Dispatcher = class {
|
|
|
6833
7382
|
get at() {
|
|
6834
7383
|
return new PathChanges(this);
|
|
6835
7384
|
}
|
|
7385
|
+
// A message is ADDRESSED: it names one component and stops there.
|
|
6836
7386
|
send(name, args, opts) {
|
|
6837
7387
|
return this.sendAtPath(this.path, name, args, opts);
|
|
6838
7388
|
}
|
|
6839
|
-
bubble(name, args, opts) {
|
|
6840
|
-
return this.send(name, args, { skipSelf: true, bubbles: true, ...opts });
|
|
6841
|
-
}
|
|
6842
7389
|
sendAtPath(path, name, args, opts) {
|
|
6843
7390
|
return this.transactor.pushSend(path, name, args, opts, this.parent);
|
|
6844
7391
|
}
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
return this.
|
|
7392
|
+
// An intent is ROUTED: it names a job and walks until something answers. The verb
|
|
7393
|
+
// does not decide which scope answers — `opts.route` does, written here at the call
|
|
7394
|
+
// site, which is where the decision actually is.
|
|
7395
|
+
intent(name, args, opts) {
|
|
7396
|
+
return this.intentAtPath(this.path, name, args, opts);
|
|
6850
7397
|
}
|
|
6851
|
-
|
|
6852
|
-
return this.transactor.
|
|
7398
|
+
intentAtPath(path, name, args, opts) {
|
|
7399
|
+
return this.transactor.pushIntent(path, name, args, opts, this.parent);
|
|
6853
7400
|
}
|
|
6854
7401
|
lookupTypeFor(name, inst) {
|
|
6855
7402
|
return this.transactor.comps.getCompFor(inst).scope.lookupComponent(name);
|
|
@@ -6862,12 +7409,30 @@ var EventContext = class extends Dispatcher {
|
|
|
6862
7409
|
get targetPath() {
|
|
6863
7410
|
return this.parent.targetPath;
|
|
6864
7411
|
}
|
|
6865
|
-
|
|
6866
|
-
|
|
7412
|
+
// Answer the intent being handled, with a result or with an error. Either ENDS the
|
|
7413
|
+
// walk. Legal only in an `intent` handler: a message has no sender waiting on it.
|
|
7414
|
+
reply(value) {
|
|
7415
|
+
return this.parent.walk === void 0 ? warnNotIntent("reply") : this.parent.walk.answer("Ok", value);
|
|
7416
|
+
}
|
|
7417
|
+
fail(error) {
|
|
7418
|
+
return this.parent.walk === void 0 ? warnNotIntent("fail") : this.parent.walk.answer("Error", error);
|
|
7419
|
+
}
|
|
7420
|
+
// End the walk answering nothing — "served, and no answer".
|
|
7421
|
+
stop() {
|
|
7422
|
+
return this.parent.stop();
|
|
7423
|
+
}
|
|
7424
|
+
// From an `intent` body: hand the intent to the next hop, optionally amending it.
|
|
7425
|
+
// From a `receive` body: turn the message that arrived into an intent. One word from
|
|
7426
|
+
// both ends of a walk; which one you get depends on which bucket you are in.
|
|
7427
|
+
forward(opts) {
|
|
7428
|
+
return this.parent.forward(opts);
|
|
6867
7429
|
}
|
|
6868
7430
|
};
|
|
6869
|
-
var
|
|
7431
|
+
var IntentContext = class extends Dispatcher {
|
|
6870
7432
|
};
|
|
7433
|
+
function warnNotIntent(verb) {
|
|
7434
|
+
console.warn(`ctx.${verb}() is only meaningful in an "intent" handler - ignored`);
|
|
7435
|
+
}
|
|
6871
7436
|
var PathChanges = class extends PathBuilder {
|
|
6872
7437
|
constructor(dispatcher) {
|
|
6873
7438
|
super();
|
|
@@ -6876,8 +7441,8 @@ var PathChanges = class extends PathBuilder {
|
|
|
6876
7441
|
send(name, args, opts) {
|
|
6877
7442
|
return this.dispatcher.sendAtPath(this.buildPath(), name, args, opts);
|
|
6878
7443
|
}
|
|
6879
|
-
|
|
6880
|
-
return this.
|
|
7444
|
+
intent(name, args, opts) {
|
|
7445
|
+
return this.dispatcher.intentAtPath(this.buildPath(), name, args, opts);
|
|
6881
7446
|
}
|
|
6882
7447
|
buildPath() {
|
|
6883
7448
|
return this.dispatcher.path.concat(this.pathChanges);
|
|
@@ -7149,29 +7714,24 @@ function captureError(e) {
|
|
|
7149
7714
|
if ("actual" in e) out.actual = e.actual;
|
|
7150
7715
|
return out;
|
|
7151
7716
|
}
|
|
7152
|
-
function buildStack({ components = [], macros = null,
|
|
7717
|
+
function buildStack({ components = [], macros = null, intentHandlers = null } = {}) {
|
|
7153
7718
|
const stack = new ComponentStack();
|
|
7154
7719
|
stack.registerComponents(components);
|
|
7155
7720
|
if (macros) stack.registerMacros(macros);
|
|
7156
|
-
if (
|
|
7721
|
+
if (intentHandlers) stack.registerIntentHandlers(intentHandlers);
|
|
7157
7722
|
return stack;
|
|
7158
7723
|
}
|
|
7159
7724
|
async function driveStack(stack, value, phase, opts = {}) {
|
|
7160
|
-
const warn = opts.warn ?? console.warn;
|
|
7161
7725
|
const transactor = new Transactor(stack.comps, value);
|
|
7162
7726
|
if (opts.onMessage)
|
|
7163
7727
|
transactor.state.onChange(({ val, old, info }) => {
|
|
7164
7728
|
const t = info?.transaction;
|
|
7165
7729
|
opts.onMessage(
|
|
7166
|
-
{ kind: t?.handlerProp ?? "
|
|
7730
|
+
{ kind: t?.handlerProp ?? "receive", name: t?.name, args: t?.args, path: t?.path },
|
|
7167
7731
|
old,
|
|
7168
7732
|
val
|
|
7169
7733
|
);
|
|
7170
7734
|
});
|
|
7171
|
-
if (phaseHasBubble(phase))
|
|
7172
|
-
warn(
|
|
7173
|
-
"drive(): a `bubble` action is a no-op here — drive originates at the root and bubbles travel child→parent, so there is no ancestor to receive it (and the root's own bubble handler is skipped). To exercise a bubble handler, call it directly."
|
|
7174
|
-
);
|
|
7175
7735
|
dispatchPhase(rootDispatcher(transactor), new Path([]), phase, value);
|
|
7176
7736
|
await transactor.settle();
|
|
7177
7737
|
return transactor.state.val;
|
|
@@ -7187,7 +7747,7 @@ async function runTests({
|
|
|
7187
7747
|
name = null,
|
|
7188
7748
|
grep = null,
|
|
7189
7749
|
bail = false,
|
|
7190
|
-
|
|
7750
|
+
intentHandlers = null,
|
|
7191
7751
|
macros = null
|
|
7192
7752
|
} = {}) {
|
|
7193
7753
|
const counts = { pass: 0, fail: 0, skip: 0, total: 0 };
|
|
@@ -7201,7 +7761,7 @@ async function runTests({
|
|
|
7201
7761
|
}
|
|
7202
7762
|
const { describe, test: test2, moduleTests } = makeCollector({ path, components });
|
|
7203
7763
|
let _stack = null;
|
|
7204
|
-
const getStack = () => _stack ??= buildStack({ components, macros,
|
|
7764
|
+
const getStack = () => _stack ??= buildStack({ components, macros, intentHandlers });
|
|
7205
7765
|
const driveLocal = (value, phase, opts = {}) => driveStack(getStack(), value, phase, opts);
|
|
7206
7766
|
await getTests({ describe, test: test2, expect: expect3, drive: driveLocal });
|
|
7207
7767
|
let bailed = false;
|
|
@@ -7267,7 +7827,7 @@ async function runTests({
|
|
|
7267
7827
|
}
|
|
7268
7828
|
|
|
7269
7829
|
// tools/format/console.js
|
|
7270
|
-
var
|
|
7830
|
+
var PASS2 = "color: #0a0; font-weight: bold";
|
|
7271
7831
|
var FAIL = "color: #c00; font-weight: bold";
|
|
7272
7832
|
var SKIP = "color: #888";
|
|
7273
7833
|
var DIM = "color: #888";
|
|
@@ -7282,7 +7842,7 @@ function reportTestNode(node) {
|
|
|
7282
7842
|
}
|
|
7283
7843
|
const dur = node.status === "skip" ? "" : ` (${Math.round(node.durationMs)}ms)`;
|
|
7284
7844
|
if (node.status === "pass") {
|
|
7285
|
-
console.log(`%c✓%c ${node.title}%c${dur}`,
|
|
7845
|
+
console.log(`%c✓%c ${node.title}%c${dur}`, PASS2, RESET, DIM);
|
|
7286
7846
|
} else if (node.status === "skip") {
|
|
7287
7847
|
console.log(`%c○ ${node.title}%c (skipped)`, SKIP, RESET);
|
|
7288
7848
|
} else {
|
|
@@ -7309,7 +7869,7 @@ function reportTestReportToConsole(report) {
|
|
|
7309
7869
|
const summary = `${c.pass} passed, ${c.fail} failed, ${c.skip} skipped (${c.total} total)`;
|
|
7310
7870
|
if (c.fail > 0) console.error(`%c${summary}`, FAIL);
|
|
7311
7871
|
else if (c.total === 0) console.log(`%c${summary}`, DIM);
|
|
7312
|
-
else console.log(`%c${summary}`,
|
|
7872
|
+
else console.log(`%c${summary}`, PASS2);
|
|
7313
7873
|
console.groupEnd();
|
|
7314
7874
|
}
|
|
7315
7875
|
return report;
|
|
@@ -7399,18 +7959,20 @@ function lintIdToMessage(id, info) {
|
|
|
7399
7959
|
}
|
|
7400
7960
|
case "UNKNOWN_HANDLER_ARG_NAME":
|
|
7401
7961
|
return `Unknown handler argument '${info.name}'${fmtOriginSuffix(info)}`;
|
|
7402
|
-
case "
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
case "
|
|
7407
|
-
return `
|
|
7408
|
-
case "
|
|
7409
|
-
return
|
|
7410
|
-
case "
|
|
7411
|
-
return `
|
|
7412
|
-
case "
|
|
7413
|
-
return `
|
|
7962
|
+
case "RETIRED_HANDLER_BUCKET": {
|
|
7963
|
+
const which = info.names?.length ? ` (${info.names.join(", ")})` : "";
|
|
7964
|
+
return `\`${info.key}\` is no longer a handler bucket${which} — ${info.how}`;
|
|
7965
|
+
}
|
|
7966
|
+
case "RETIRED_CTX_VERB":
|
|
7967
|
+
return `ctx.${info.verb}() no longer exists — use ${info.to} (in \`${info.bucket}.${info.name}\`)`;
|
|
7968
|
+
case "HANDLER_NAME_COLLISION":
|
|
7969
|
+
return `${info.problem} — ${info.fix}`;
|
|
7970
|
+
case "RECEIVE_HANDLER_NOT_IMPLEMENTED":
|
|
7971
|
+
return `Receive handler '${info.name}' is not implemented${fmtEventSuffix(info)}`;
|
|
7972
|
+
case "EVENT_HANDLER_METHOD_NOT_ALLOWED":
|
|
7973
|
+
return `Event handler '$${info.name}' is a method reference — move it to receive and use '${info.name}'`;
|
|
7974
|
+
case "FIELD_METHOD_NAME_COLLISION":
|
|
7975
|
+
return `Field '${info.name}' shadows a method with the same name — rename either the field or method`;
|
|
7414
7976
|
case "FIELD_VAL_NOT_DEFINED":
|
|
7415
7977
|
return `Field '.${info.name}' is not defined${fmtOriginSuffix(info)}`;
|
|
7416
7978
|
case "FIELD_VAL_IS_METHOD":
|
|
@@ -7821,440 +8383,6 @@ var DragInfo = class {
|
|
|
7821
8383
|
}
|
|
7822
8384
|
};
|
|
7823
8385
|
|
|
7824
|
-
// index.js
|
|
7825
|
-
import {
|
|
7826
|
-
Collection,
|
|
7827
|
-
fromJS,
|
|
7828
|
-
get,
|
|
7829
|
-
getIn,
|
|
7830
|
-
has,
|
|
7831
|
-
hash,
|
|
7832
|
-
hasIn,
|
|
7833
|
-
is as is2,
|
|
7834
|
-
isAssociative,
|
|
7835
|
-
isCollection,
|
|
7836
|
-
isImmutable,
|
|
7837
|
-
isIndexed as isIndexed2,
|
|
7838
|
-
isKeyed as isKeyed2,
|
|
7839
|
-
isList,
|
|
7840
|
-
isMap,
|
|
7841
|
-
isMap as isMap2,
|
|
7842
|
-
isOrdered,
|
|
7843
|
-
isOrderedMap,
|
|
7844
|
-
isOrderedMap as isOrderedMap2,
|
|
7845
|
-
isOrderedSet,
|
|
7846
|
-
isPlainObject,
|
|
7847
|
-
isRecord,
|
|
7848
|
-
isSeq,
|
|
7849
|
-
isSet,
|
|
7850
|
-
isStack,
|
|
7851
|
-
isValueObject,
|
|
7852
|
-
List as List2,
|
|
7853
|
-
Map as Map2,
|
|
7854
|
-
Map as Map3,
|
|
7855
|
-
merge,
|
|
7856
|
-
mergeDeep,
|
|
7857
|
-
mergeDeepWith,
|
|
7858
|
-
mergeWith,
|
|
7859
|
-
OrderedMap as OrderedMap2,
|
|
7860
|
-
OrderedMap as OrderedMap3,
|
|
7861
|
-
OrderedSet,
|
|
7862
|
-
PairSorting,
|
|
7863
|
-
Range,
|
|
7864
|
-
Record as Record2,
|
|
7865
|
-
Repeat,
|
|
7866
|
-
remove,
|
|
7867
|
-
removeIn,
|
|
7868
|
-
Seq,
|
|
7869
|
-
Set as Set2,
|
|
7870
|
-
Set as Set3,
|
|
7871
|
-
Stack as Stack2,
|
|
7872
|
-
set,
|
|
7873
|
-
setIn,
|
|
7874
|
-
update,
|
|
7875
|
-
updateIn,
|
|
7876
|
-
version
|
|
7877
|
-
} from "immutable";
|
|
7878
|
-
|
|
7879
|
-
// src/oo.js
|
|
7880
|
-
import { Map as IMap, Set as ISet, List, OrderedMap, Record } from "immutable";
|
|
7881
|
-
var BAD_VALUE2 = /* @__PURE__ */ Symbol("BadValue");
|
|
7882
|
-
var nullCoercer = (v) => v;
|
|
7883
|
-
var Field = class {
|
|
7884
|
-
constructor(type, name, typeCheck, coercer, defaultValue = null) {
|
|
7885
|
-
this.type = type;
|
|
7886
|
-
this.name = name;
|
|
7887
|
-
this.typeCheck = typeCheck;
|
|
7888
|
-
this.coercer = coercer;
|
|
7889
|
-
this.checks = [];
|
|
7890
|
-
this.defaultValue = defaultValue;
|
|
7891
|
-
}
|
|
7892
|
-
toDataDef() {
|
|
7893
|
-
const { type, defaultValue: dv } = this;
|
|
7894
|
-
return { type, defaultValue: dv?.toJS ? dv.toJS() : dv };
|
|
7895
|
-
}
|
|
7896
|
-
getFirstFailingCheck(v) {
|
|
7897
|
-
if (!this.typeCheck.isValid(v)) return this.typeCheck;
|
|
7898
|
-
for (const check2 of this.checks) if (!check2.isValid(v)) return check2;
|
|
7899
|
-
return null;
|
|
7900
|
-
}
|
|
7901
|
-
isValid(v) {
|
|
7902
|
-
return this.getFirstFailingCheck(v) === null;
|
|
7903
|
-
}
|
|
7904
|
-
addCheck(check2) {
|
|
7905
|
-
this.checks.push(check2);
|
|
7906
|
-
return this;
|
|
7907
|
-
}
|
|
7908
|
-
coerceOr(v, defaultValue = null) {
|
|
7909
|
-
if (this.isValid(v)) return v;
|
|
7910
|
-
const v1 = this.coercer(v);
|
|
7911
|
-
return this.isValid(v1) ? v1 : defaultValue;
|
|
7912
|
-
}
|
|
7913
|
-
coerceOrDefault(v) {
|
|
7914
|
-
return this.coerceOr(v, this.defaultValue);
|
|
7915
|
-
}
|
|
7916
|
-
extendProtoForType(_proto, _uname) {
|
|
7917
|
-
}
|
|
7918
|
-
extendProto(proto) {
|
|
7919
|
-
const { name } = this;
|
|
7920
|
-
const uname = name[0].toUpperCase() + name.slice(1);
|
|
7921
|
-
const setName = `set${uname}`;
|
|
7922
|
-
const that = this;
|
|
7923
|
-
proto[setName] = function(v) {
|
|
7924
|
-
const v1 = that.coerceOr(v, BAD_VALUE2);
|
|
7925
|
-
if (v1 === BAD_VALUE2) {
|
|
7926
|
-
console.warn("invalid value", v);
|
|
7927
|
-
return this;
|
|
7928
|
-
}
|
|
7929
|
-
return this.set(name, v1);
|
|
7930
|
-
};
|
|
7931
|
-
proto[`update${uname}`] = function(fn) {
|
|
7932
|
-
return this[setName](fn(this.get(name)));
|
|
7933
|
-
};
|
|
7934
|
-
proto[`reset${uname}`] = function() {
|
|
7935
|
-
return this.set(name, that.defaultValue);
|
|
7936
|
-
};
|
|
7937
|
-
this.extendProtoForType(proto, uname);
|
|
7938
|
-
}
|
|
7939
|
-
};
|
|
7940
|
-
var Check = class {
|
|
7941
|
-
isValid(_v) {
|
|
7942
|
-
return true;
|
|
7943
|
-
}
|
|
7944
|
-
getMessage(_v) {
|
|
7945
|
-
return "Invalid";
|
|
7946
|
-
}
|
|
7947
|
-
};
|
|
7948
|
-
var CheckTypeAny = class extends Check {
|
|
7949
|
-
};
|
|
7950
|
-
var CHECK_TYPE_ANY = new CheckTypeAny();
|
|
7951
|
-
var FnCheck = class extends Check {
|
|
7952
|
-
constructor(isValidFn, getMessageFn) {
|
|
7953
|
-
super();
|
|
7954
|
-
this._isValid = isValidFn;
|
|
7955
|
-
this._getMessage = getMessageFn;
|
|
7956
|
-
}
|
|
7957
|
-
isValid(v) {
|
|
7958
|
-
return this._isValid(v);
|
|
7959
|
-
}
|
|
7960
|
-
getMessage(v) {
|
|
7961
|
-
return this._getMessage(v);
|
|
7962
|
-
}
|
|
7963
|
-
};
|
|
7964
|
-
var CHECK_TYPE_INT = new FnCheck(
|
|
7965
|
-
(v) => Number.isInteger(v),
|
|
7966
|
-
() => "Integer expected"
|
|
7967
|
-
);
|
|
7968
|
-
var CHECK_TYPE_FLOAT = new FnCheck(
|
|
7969
|
-
(v) => Number.isFinite(v),
|
|
7970
|
-
() => "Float expected"
|
|
7971
|
-
);
|
|
7972
|
-
var CHECK_TYPE_BOOL = new FnCheck(
|
|
7973
|
-
(v) => typeof v === "boolean",
|
|
7974
|
-
() => "Boolean expected"
|
|
7975
|
-
);
|
|
7976
|
-
var CHECK_TYPE_STRING = new FnCheck(
|
|
7977
|
-
(v) => typeof v === "string",
|
|
7978
|
-
() => "String expected"
|
|
7979
|
-
);
|
|
7980
|
-
var CHECK_TYPE_LIST = new FnCheck(
|
|
7981
|
-
(v) => List.isList(v),
|
|
7982
|
-
() => "List expected"
|
|
7983
|
-
);
|
|
7984
|
-
var CHECK_TYPE_MAP = new FnCheck(
|
|
7985
|
-
(v) => IMap.isMap(v),
|
|
7986
|
-
() => "Map expected"
|
|
7987
|
-
);
|
|
7988
|
-
var CHECK_TYPE_OMAP = new FnCheck(
|
|
7989
|
-
(v) => OrderedMap.isOrderedMap(v),
|
|
7990
|
-
() => "OrderedMap expected"
|
|
7991
|
-
);
|
|
7992
|
-
var CHECK_TYPE_SET = new FnCheck(
|
|
7993
|
-
(v) => ISet.isSet(v),
|
|
7994
|
-
() => "Set expected"
|
|
7995
|
-
);
|
|
7996
|
-
var boolCoercer = (v) => !!v;
|
|
7997
|
-
var FieldBool = class extends Field {
|
|
7998
|
-
constructor(name, defaultValue = false) {
|
|
7999
|
-
super("bool", name, CHECK_TYPE_BOOL, boolCoercer, defaultValue);
|
|
8000
|
-
}
|
|
8001
|
-
extendProtoForType(proto, uname) {
|
|
8002
|
-
const { name } = this;
|
|
8003
|
-
proto[`toggle${uname}`] = function() {
|
|
8004
|
-
return this.set(name, !this.get(name, false));
|
|
8005
|
-
};
|
|
8006
|
-
proto[`set${uname}`] = function(v) {
|
|
8007
|
-
return this.set(name, !!v);
|
|
8008
|
-
};
|
|
8009
|
-
}
|
|
8010
|
-
};
|
|
8011
|
-
var FieldAny = class extends Field {
|
|
8012
|
-
constructor(name, defaultValue = null) {
|
|
8013
|
-
super("any", name, CHECK_TYPE_ANY, nullCoercer, defaultValue);
|
|
8014
|
-
}
|
|
8015
|
-
toDataDef() {
|
|
8016
|
-
const { defaultValue: dv } = this;
|
|
8017
|
-
const type = getTypeName(dv) ?? "any";
|
|
8018
|
-
return { type, defaultValue: dv?.toJS ? dv.toJS() : dv };
|
|
8019
|
-
}
|
|
8020
|
-
};
|
|
8021
|
-
var stringCoercer = (v) => v?.toString?.() ?? "";
|
|
8022
|
-
var FieldString = class extends Field {
|
|
8023
|
-
constructor(name, defaultValue = "") {
|
|
8024
|
-
super("text", name, CHECK_TYPE_STRING, stringCoercer, defaultValue);
|
|
8025
|
-
}
|
|
8026
|
-
extendProtoForType(proto, _uname) {
|
|
8027
|
-
extendProtoSized(proto, this.name, "", "length");
|
|
8028
|
-
}
|
|
8029
|
-
};
|
|
8030
|
-
var intCoercer = (v) => Number.isFinite(v) ? Math.trunc(v) : null;
|
|
8031
|
-
var FieldInt = class extends Field {
|
|
8032
|
-
constructor(name, defaultValue = 0) {
|
|
8033
|
-
super("int", name, CHECK_TYPE_INT, intCoercer, defaultValue);
|
|
8034
|
-
}
|
|
8035
|
-
};
|
|
8036
|
-
var floatCoercer = (_) => null;
|
|
8037
|
-
var FieldFloat = class extends Field {
|
|
8038
|
-
constructor(name, defaultValue = 0) {
|
|
8039
|
-
super("float", name, CHECK_TYPE_FLOAT, floatCoercer, defaultValue);
|
|
8040
|
-
}
|
|
8041
|
-
};
|
|
8042
|
-
var getTypeName = (v) => v?.constructor?.getMetaClass?.()?.name;
|
|
8043
|
-
var CheckTypeName = class {
|
|
8044
|
-
constructor(typeName) {
|
|
8045
|
-
this.typeName = typeName;
|
|
8046
|
-
}
|
|
8047
|
-
isValid(v) {
|
|
8048
|
-
return getTypeName(v) === this.typeName;
|
|
8049
|
-
}
|
|
8050
|
-
getMessage(v) {
|
|
8051
|
-
const got = getTypeName(v);
|
|
8052
|
-
return `Expected "${this.typeName}", got "${got}"`;
|
|
8053
|
-
}
|
|
8054
|
-
};
|
|
8055
|
-
var FieldComp = class extends Field {
|
|
8056
|
-
constructor(type, name, args) {
|
|
8057
|
-
super(type, name, new CheckTypeName(type), nullCoercer, null);
|
|
8058
|
-
this.args = args;
|
|
8059
|
-
}
|
|
8060
|
-
toDataDef() {
|
|
8061
|
-
return { component: this.typeName, args: this.args };
|
|
8062
|
-
}
|
|
8063
|
-
};
|
|
8064
|
-
var NONE2 = /* @__PURE__ */ Symbol("NONE");
|
|
8065
|
-
function extendProtoForKeyed(proto, name, uname) {
|
|
8066
|
-
extendProtoSized(proto, name, EMPTY_LIST);
|
|
8067
|
-
proto[`setIn${uname}At`] = function(i, v) {
|
|
8068
|
-
return this.set(name, this.get(name).set(i, v));
|
|
8069
|
-
};
|
|
8070
|
-
proto[`getIn${uname}At`] = function(i, dval) {
|
|
8071
|
-
return this.get(name).get(i, dval);
|
|
8072
|
-
};
|
|
8073
|
-
proto[`updateIn${uname}At`] = function(i, fn) {
|
|
8074
|
-
const col = this.get(name);
|
|
8075
|
-
const v = col.get(i, NONE2);
|
|
8076
|
-
if (v !== NONE2) return this.set(name, col.set(i, fn(v)));
|
|
8077
|
-
console.warn("key", i, "not found in", name, col);
|
|
8078
|
-
return this;
|
|
8079
|
-
};
|
|
8080
|
-
extendDeleteInAt(proto, name, `${uname}At`);
|
|
8081
|
-
}
|
|
8082
|
-
function extendDeleteInAt(proto, name, uname) {
|
|
8083
|
-
proto[`deleteIn${uname}`] = function(v) {
|
|
8084
|
-
return this.set(name, this.get(name).delete(v));
|
|
8085
|
-
};
|
|
8086
|
-
proto[`removeIn${uname}`] = proto[`deleteIn${uname}`];
|
|
8087
|
-
}
|
|
8088
|
-
var EMPTY_LIST = List();
|
|
8089
|
-
var listCoercer = (v) => Array.isArray(v) ? List(v) : null;
|
|
8090
|
-
var FieldList = class extends Field {
|
|
8091
|
-
constructor(name, defaultValue = EMPTY_LIST) {
|
|
8092
|
-
super("list", name, CHECK_TYPE_LIST, listCoercer, defaultValue);
|
|
8093
|
-
}
|
|
8094
|
-
extendProtoForType(proto, uname) {
|
|
8095
|
-
const { name } = this;
|
|
8096
|
-
extendProtoForKeyed(proto, name, uname);
|
|
8097
|
-
proto[`pushIn${uname}`] = function(v) {
|
|
8098
|
-
return this.set(name, this.get(name).push(v));
|
|
8099
|
-
};
|
|
8100
|
-
proto[`insertIn${uname}At`] = function(i, v) {
|
|
8101
|
-
return this.set(name, this.get(name).insert(i, v));
|
|
8102
|
-
};
|
|
8103
|
-
}
|
|
8104
|
-
};
|
|
8105
|
-
var imapCoercer = (v) => IMap(v);
|
|
8106
|
-
var FieldMap = class extends Field {
|
|
8107
|
-
constructor(name, defaultValue = IMap()) {
|
|
8108
|
-
super("map", name, CHECK_TYPE_MAP, imapCoercer, defaultValue);
|
|
8109
|
-
}
|
|
8110
|
-
extendProtoForType(proto, uname) {
|
|
8111
|
-
extendProtoForKeyed(proto, this.name, uname);
|
|
8112
|
-
}
|
|
8113
|
-
};
|
|
8114
|
-
var omapCoercer = (v) => OrderedMap(v);
|
|
8115
|
-
var FieldOMap = class extends Field {
|
|
8116
|
-
constructor(name, defaultValue = OrderedMap()) {
|
|
8117
|
-
super("omap", name, CHECK_TYPE_OMAP, omapCoercer, defaultValue);
|
|
8118
|
-
}
|
|
8119
|
-
extendProtoForType(proto, uname) {
|
|
8120
|
-
extendProtoForKeyed(proto, this.name, uname);
|
|
8121
|
-
}
|
|
8122
|
-
};
|
|
8123
|
-
function extendProtoSized(proto, name, defaultEmpty, propName = "size") {
|
|
8124
|
-
proto[`${name}Len`] = function() {
|
|
8125
|
-
return this.get(name, defaultEmpty)[propName];
|
|
8126
|
-
};
|
|
8127
|
-
}
|
|
8128
|
-
var EMPTY_SET2 = ISet();
|
|
8129
|
-
var isetCoercer = (v) => Array.isArray(v) ? ISet(v) : v instanceof Set ? ISet(v) : null;
|
|
8130
|
-
var FieldSet = class extends Field {
|
|
8131
|
-
constructor(name, defaultValue = EMPTY_SET2) {
|
|
8132
|
-
super("set", name, CHECK_TYPE_SET, isetCoercer, defaultValue);
|
|
8133
|
-
}
|
|
8134
|
-
extendProtoForType(proto, uname) {
|
|
8135
|
-
const { name } = this;
|
|
8136
|
-
extendProtoSized(proto, name, EMPTY_SET2);
|
|
8137
|
-
proto[`addIn${uname}`] = function(v) {
|
|
8138
|
-
return this.set(name, this.get(name).add(v));
|
|
8139
|
-
};
|
|
8140
|
-
extendDeleteInAt(proto, name, uname);
|
|
8141
|
-
proto[`hasIn${uname}`] = function(v) {
|
|
8142
|
-
return this.get(name).has(v);
|
|
8143
|
-
};
|
|
8144
|
-
proto[`toggleIn${uname}`] = function(v) {
|
|
8145
|
-
const current = this.get(name);
|
|
8146
|
-
return this.set(name, current.has(v) ? current.delete(v) : current.add(v));
|
|
8147
|
-
};
|
|
8148
|
-
}
|
|
8149
|
-
};
|
|
8150
|
-
function mkCompField(field, scope, args) {
|
|
8151
|
-
const Comp = scope?.lookupComponent(field.type) ?? null;
|
|
8152
|
-
if (Comp === null)
|
|
8153
|
-
console.warn(
|
|
8154
|
-
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)`
|
|
8155
|
-
);
|
|
8156
|
-
return Comp?.make({ ...field.args, ...args }, { scope }) ?? null;
|
|
8157
|
-
}
|
|
8158
|
-
var ClassBuilder = class {
|
|
8159
|
-
constructor(name) {
|
|
8160
|
-
const fields = {};
|
|
8161
|
-
const compFields = /* @__PURE__ */ new Set();
|
|
8162
|
-
this.name = name;
|
|
8163
|
-
this.fields = fields;
|
|
8164
|
-
this.compFields = compFields;
|
|
8165
|
-
this._methods = {};
|
|
8166
|
-
this._statics = {
|
|
8167
|
-
make: function(inArgs = {}, opts = {}) {
|
|
8168
|
-
const args = {};
|
|
8169
|
-
const scope = opts.scope ?? this.scope;
|
|
8170
|
-
for (const key in inArgs) {
|
|
8171
|
-
const field = fields[key];
|
|
8172
|
-
if (compFields.has(key)) args[key] = mkCompField(field, scope, inArgs[key]);
|
|
8173
|
-
else if (field === void 0)
|
|
8174
|
-
console.warn("extra argument to constructor:", name, key, inArgs);
|
|
8175
|
-
else args[key] = field.coerceOrDefault(inArgs[key]);
|
|
8176
|
-
}
|
|
8177
|
-
for (const key of compFields)
|
|
8178
|
-
if (args[key] === void 0) args[key] = mkCompField(fields[key], scope, inArgs[key]);
|
|
8179
|
-
return this(args);
|
|
8180
|
-
}
|
|
8181
|
-
};
|
|
8182
|
-
}
|
|
8183
|
-
build() {
|
|
8184
|
-
const fieldVals = {};
|
|
8185
|
-
const proto = {};
|
|
8186
|
-
const { name, _methods, fields } = this;
|
|
8187
|
-
for (const fieldName in fields) {
|
|
8188
|
-
const field = fields[fieldName];
|
|
8189
|
-
fieldVals[fieldName] = field.defaultValue;
|
|
8190
|
-
field.extendProto(proto);
|
|
8191
|
-
}
|
|
8192
|
-
const Class = { [name]: Record(fieldVals, name) }[name];
|
|
8193
|
-
Object.assign(Class.prototype, proto, _methods);
|
|
8194
|
-
const metaClass = { fields, name, methods: _methods };
|
|
8195
|
-
Object.assign(Class, this._statics, { getMetaClass: () => metaClass });
|
|
8196
|
-
return Class;
|
|
8197
|
-
}
|
|
8198
|
-
methods(proto) {
|
|
8199
|
-
for (const k in proto) this._methods[k] = proto[k];
|
|
8200
|
-
}
|
|
8201
|
-
statics(proto) {
|
|
8202
|
-
for (const k in proto) this._statics[k] = proto[k];
|
|
8203
|
-
}
|
|
8204
|
-
addField(name, dval, FieldCls) {
|
|
8205
|
-
const field = new FieldCls(name, dval);
|
|
8206
|
-
this.fields[name] = field;
|
|
8207
|
-
return field;
|
|
8208
|
-
}
|
|
8209
|
-
addCompField(name, type, args) {
|
|
8210
|
-
const field = new FieldComp(type, name, args);
|
|
8211
|
-
this.compFields.add(name);
|
|
8212
|
-
this.fields[name] = field;
|
|
8213
|
-
return field;
|
|
8214
|
-
}
|
|
8215
|
-
};
|
|
8216
|
-
var FIELD_CLASS = /* @__PURE__ */ Symbol.for("tutuca.fieldClass");
|
|
8217
|
-
var fieldsByTypeName = {
|
|
8218
|
-
text: FieldString,
|
|
8219
|
-
int: FieldInt,
|
|
8220
|
-
float: FieldFloat,
|
|
8221
|
-
bool: FieldBool,
|
|
8222
|
-
list: FieldList,
|
|
8223
|
-
map: FieldMap,
|
|
8224
|
-
omap: FieldOMap,
|
|
8225
|
-
set: FieldSet,
|
|
8226
|
-
any: FieldAny
|
|
8227
|
-
};
|
|
8228
|
-
function classFromData(name, { fields = {}, methods, statics }) {
|
|
8229
|
-
const b = new ClassBuilder(name);
|
|
8230
|
-
for (const field in fields) {
|
|
8231
|
-
const value = fields[field];
|
|
8232
|
-
const type = typeof value;
|
|
8233
|
-
if (type === "string") b.addField(field, value, FieldString);
|
|
8234
|
-
else if (type === "number") b.addField(field, value, FieldFloat);
|
|
8235
|
-
else if (type === "boolean") b.addField(field, value, FieldBool);
|
|
8236
|
-
else if (List.isList(value) || Array.isArray(value)) b.addField(field, List(value), FieldList);
|
|
8237
|
-
else if (ISet.isSet(value) || value instanceof Set) b.addField(field, ISet(value), FieldSet);
|
|
8238
|
-
else if (OrderedMap.isOrderedMap(value)) b.addField(field, value, FieldOMap);
|
|
8239
|
-
else if (value?.type && value?.defaultValue !== void 0) {
|
|
8240
|
-
const Field2 = fieldsByTypeName[value.type] ?? FieldAny;
|
|
8241
|
-
b.addField(field, new Field2().coerceOr(value.defaultValue), Field2);
|
|
8242
|
-
} else if (value?.component && value?.args !== void 0)
|
|
8243
|
-
b.addCompField(field, value.component, value.args);
|
|
8244
|
-
else if (IMap.isMap(value) || value?.constructor === Object)
|
|
8245
|
-
b.addField(field, IMap(value), FieldMap);
|
|
8246
|
-
else {
|
|
8247
|
-
const Field2 = value?.[FIELD_CLASS] ?? FieldAny;
|
|
8248
|
-
b.addField(field, value, Field2);
|
|
8249
|
-
}
|
|
8250
|
-
}
|
|
8251
|
-
if (methods) b.methods(methods);
|
|
8252
|
-
if (statics) b.statics(statics);
|
|
8253
|
-
return b.build();
|
|
8254
|
-
}
|
|
8255
|
-
Component.fromSpec = (opts) => new Component(classFromData(opts.name, opts), opts);
|
|
8256
|
-
var component = (opts) => Component.fromSpec(opts);
|
|
8257
|
-
|
|
8258
8386
|
// index.js
|
|
8259
8387
|
var css = String.raw;
|
|
8260
8388
|
var html = String.raw;
|
|
@@ -8307,7 +8435,6 @@ function resolveAlter(Comp, name) {
|
|
|
8307
8435
|
}
|
|
8308
8436
|
return fn;
|
|
8309
8437
|
}
|
|
8310
|
-
var seqGet = (seq, key) => Array.isArray(seq) ? seq[key] : seq.get ? seq.get(key) : seq[key];
|
|
8311
8438
|
function collectIterBindings(Comp, compInstance, seq, opts = {}) {
|
|
8312
8439
|
const whenFn = resolveAlter(Comp, opts.when) ?? filterAlwaysTrue;
|
|
8313
8440
|
const loopWithFn = resolveAlter(Comp, opts.loopWith) ?? nullLoopWith;
|
|
@@ -8352,157 +8479,10 @@ function getSignature(name, fn) {
|
|
|
8352
8479
|
const params = m ? m[1].trim() : "";
|
|
8353
8480
|
return `${name}(${params})`;
|
|
8354
8481
|
}
|
|
8355
|
-
function getFieldMethods(field) {
|
|
8356
|
-
const { name, type } = field;
|
|
8357
|
-
const uname = name[0].toUpperCase() + name.slice(1);
|
|
8358
|
-
const methods = [
|
|
8359
|
-
{ name: `set${uname}`, sig: `set${uname}(v)`, desc: "Set value" },
|
|
8360
|
-
{
|
|
8361
|
-
name: `update${uname}`,
|
|
8362
|
-
sig: `update${uname}(fn)`,
|
|
8363
|
-
desc: "Update value with function"
|
|
8364
|
-
},
|
|
8365
|
-
{
|
|
8366
|
-
name: `reset${uname}`,
|
|
8367
|
-
sig: `reset${uname}()`,
|
|
8368
|
-
desc: "Reset to default value"
|
|
8369
|
-
}
|
|
8370
|
-
];
|
|
8371
|
-
switch (type) {
|
|
8372
|
-
case "bool":
|
|
8373
|
-
methods[0].desc = "Set value (coerces to boolean)";
|
|
8374
|
-
methods.push({
|
|
8375
|
-
name: `toggle${uname}`,
|
|
8376
|
-
sig: `toggle${uname}()`,
|
|
8377
|
-
desc: "Toggle boolean value"
|
|
8378
|
-
});
|
|
8379
|
-
break;
|
|
8380
|
-
case "int":
|
|
8381
|
-
case "float":
|
|
8382
|
-
case "any":
|
|
8383
|
-
break;
|
|
8384
|
-
case "text":
|
|
8385
|
-
methods.push({
|
|
8386
|
-
name: `${name}Len`,
|
|
8387
|
-
sig: `${name}Len()`,
|
|
8388
|
-
desc: "Get string length"
|
|
8389
|
-
});
|
|
8390
|
-
break;
|
|
8391
|
-
case "list":
|
|
8392
|
-
methods.push(
|
|
8393
|
-
{ name: `${name}Len`, sig: `${name}Len()`, desc: "Get list size" },
|
|
8394
|
-
{
|
|
8395
|
-
name: `setIn${uname}At`,
|
|
8396
|
-
sig: `setIn${uname}At(i, v)`,
|
|
8397
|
-
desc: "Set item at index"
|
|
8398
|
-
},
|
|
8399
|
-
{
|
|
8400
|
-
name: `getIn${uname}At`,
|
|
8401
|
-
sig: `getIn${uname}At(i, defaultValue)`,
|
|
8402
|
-
desc: "Get item at index"
|
|
8403
|
-
},
|
|
8404
|
-
{
|
|
8405
|
-
name: `updateIn${uname}At`,
|
|
8406
|
-
sig: `updateIn${uname}At(i, fn)`,
|
|
8407
|
-
desc: "Update item at index with function"
|
|
8408
|
-
},
|
|
8409
|
-
{
|
|
8410
|
-
name: `deleteIn${uname}At`,
|
|
8411
|
-
sig: `deleteIn${uname}At(i)`,
|
|
8412
|
-
desc: "Delete item at index"
|
|
8413
|
-
},
|
|
8414
|
-
{
|
|
8415
|
-
name: `removeIn${uname}At`,
|
|
8416
|
-
sig: `removeIn${uname}At(i)`,
|
|
8417
|
-
desc: "Delete item at index (alias)"
|
|
8418
|
-
},
|
|
8419
|
-
{
|
|
8420
|
-
name: `pushIn${uname}`,
|
|
8421
|
-
sig: `pushIn${uname}(v)`,
|
|
8422
|
-
desc: "Push item to end"
|
|
8423
|
-
},
|
|
8424
|
-
{
|
|
8425
|
-
name: `insertIn${uname}At`,
|
|
8426
|
-
sig: `insertIn${uname}At(i, v)`,
|
|
8427
|
-
desc: "Insert item at index"
|
|
8428
|
-
}
|
|
8429
|
-
);
|
|
8430
|
-
break;
|
|
8431
|
-
case "map":
|
|
8432
|
-
case "omap": {
|
|
8433
|
-
const label = type === "omap" ? "ordered map" : "map";
|
|
8434
|
-
methods.push(
|
|
8435
|
-
{
|
|
8436
|
-
name: `${name}Len`,
|
|
8437
|
-
sig: `${name}Len()`,
|
|
8438
|
-
desc: `Get ${label} size`
|
|
8439
|
-
},
|
|
8440
|
-
{
|
|
8441
|
-
name: `setIn${uname}At`,
|
|
8442
|
-
sig: `setIn${uname}At(key, v)`,
|
|
8443
|
-
desc: "Set value at key"
|
|
8444
|
-
},
|
|
8445
|
-
{
|
|
8446
|
-
name: `getIn${uname}At`,
|
|
8447
|
-
sig: `getIn${uname}At(key, defaultValue)`,
|
|
8448
|
-
desc: "Get value at key"
|
|
8449
|
-
},
|
|
8450
|
-
{
|
|
8451
|
-
name: `updateIn${uname}At`,
|
|
8452
|
-
sig: `updateIn${uname}At(key, fn)`,
|
|
8453
|
-
desc: "Update value at key with function"
|
|
8454
|
-
},
|
|
8455
|
-
{
|
|
8456
|
-
name: `deleteIn${uname}At`,
|
|
8457
|
-
sig: `deleteIn${uname}At(key)`,
|
|
8458
|
-
desc: "Delete entry at key"
|
|
8459
|
-
},
|
|
8460
|
-
{
|
|
8461
|
-
name: `removeIn${uname}At`,
|
|
8462
|
-
sig: `removeIn${uname}At(key)`,
|
|
8463
|
-
desc: "Delete entry at key (alias)"
|
|
8464
|
-
}
|
|
8465
|
-
);
|
|
8466
|
-
break;
|
|
8467
|
-
}
|
|
8468
|
-
case "set":
|
|
8469
|
-
methods.push(
|
|
8470
|
-
{ name: `${name}Len`, sig: `${name}Len()`, desc: "Get set size" },
|
|
8471
|
-
{
|
|
8472
|
-
name: `addIn${uname}`,
|
|
8473
|
-
sig: `addIn${uname}(v)`,
|
|
8474
|
-
desc: "Add value to set"
|
|
8475
|
-
},
|
|
8476
|
-
{
|
|
8477
|
-
name: `deleteIn${uname}`,
|
|
8478
|
-
sig: `deleteIn${uname}(v)`,
|
|
8479
|
-
desc: "Remove value from set"
|
|
8480
|
-
},
|
|
8481
|
-
{
|
|
8482
|
-
name: `removeIn${uname}`,
|
|
8483
|
-
sig: `removeIn${uname}(v)`,
|
|
8484
|
-
desc: "Remove value from set (alias)"
|
|
8485
|
-
},
|
|
8486
|
-
{
|
|
8487
|
-
name: `hasIn${uname}`,
|
|
8488
|
-
sig: `hasIn${uname}(v)`,
|
|
8489
|
-
desc: "Check if value is in set"
|
|
8490
|
-
},
|
|
8491
|
-
{
|
|
8492
|
-
name: `toggleIn${uname}`,
|
|
8493
|
-
sig: `toggleIn${uname}(v)`,
|
|
8494
|
-
desc: "Toggle value in set"
|
|
8495
|
-
}
|
|
8496
|
-
);
|
|
8497
|
-
break;
|
|
8498
|
-
default:
|
|
8499
|
-
break;
|
|
8500
|
-
}
|
|
8501
|
-
return methods;
|
|
8502
|
-
}
|
|
8503
8482
|
function serializeDefault(v) {
|
|
8504
8483
|
if (v === null || v === void 0) return v;
|
|
8505
|
-
if (v
|
|
8484
|
+
if (v instanceof Map) return Object.fromEntries(v);
|
|
8485
|
+
if (v instanceof Set) return [...v];
|
|
8506
8486
|
return v;
|
|
8507
8487
|
}
|
|
8508
8488
|
function getComponentDoc(comp) {
|
|
@@ -8512,10 +8492,9 @@ function getComponentDoc(comp) {
|
|
|
8512
8492
|
name: k,
|
|
8513
8493
|
sig: getSignature(k, methods[k])
|
|
8514
8494
|
}));
|
|
8515
|
-
const
|
|
8516
|
-
|
|
8517
|
-
|
|
8518
|
-
}));
|
|
8495
|
+
const sigs = (bucket) => Object.keys(bucket ?? {}).map((k) => ({ name: k, sig: getSignature(k, bucket[k]) }));
|
|
8496
|
+
const receiveHandlers = sigs(comp.receive);
|
|
8497
|
+
const intentHandlers = sigs(comp.intent);
|
|
8519
8498
|
const fieldDocs = [];
|
|
8520
8499
|
for (const fieldName in fields) {
|
|
8521
8500
|
const field = fields[fieldName];
|
|
@@ -8523,10 +8502,16 @@ function getComponentDoc(comp) {
|
|
|
8523
8502
|
name: fieldName,
|
|
8524
8503
|
type: field.type,
|
|
8525
8504
|
default: serializeDefault(field.defaultValue),
|
|
8526
|
-
methods:
|
|
8505
|
+
methods: []
|
|
8527
8506
|
});
|
|
8528
8507
|
}
|
|
8529
|
-
return {
|
|
8508
|
+
return {
|
|
8509
|
+
name,
|
|
8510
|
+
methods: userMethods,
|
|
8511
|
+
receive: receiveHandlers,
|
|
8512
|
+
intent: intentHandlers,
|
|
8513
|
+
fields: fieldDocs
|
|
8514
|
+
};
|
|
8530
8515
|
}
|
|
8531
8516
|
function docComponents(normalized, { name = null } = {}) {
|
|
8532
8517
|
const comps = normalized.components;
|
|
@@ -8553,7 +8538,7 @@ function shadowCheckComponent(Comp) {
|
|
|
8553
8538
|
shadowComp.views = shadowViews;
|
|
8554
8539
|
return checkComponent(shadowComp).reports;
|
|
8555
8540
|
}
|
|
8556
|
-
function
|
|
8541
|
+
function check2(app) {
|
|
8557
8542
|
const counts = { error: 0, warn: 0, hint: 0 };
|
|
8558
8543
|
for (const Comp of app.comps.byId.values()) {
|
|
8559
8544
|
const reports = shadowCheckComponent(Comp);
|
|
@@ -8618,7 +8603,6 @@ export {
|
|
|
8618
8603
|
BINDING_MEMBER_TOO_DEEP,
|
|
8619
8604
|
COMP_FIELD_BAD_SHAPE,
|
|
8620
8605
|
CONSTANT_CONDITION,
|
|
8621
|
-
Collection,
|
|
8622
8606
|
ComponentDocs,
|
|
8623
8607
|
ComponentList,
|
|
8624
8608
|
ComponentSummary,
|
|
@@ -8628,20 +8612,15 @@ export {
|
|
|
8628
8612
|
DYN_VAL_NOT_DEFINED,
|
|
8629
8613
|
Describe,
|
|
8630
8614
|
DescribeResult,
|
|
8615
|
+
EVENT_HANDLER_METHOD_NOT_ALLOWED,
|
|
8631
8616
|
ExampleIndex,
|
|
8632
8617
|
FIELD_CLASS,
|
|
8633
|
-
|
|
8618
|
+
FIELD_METHOD_NAME_COLLISION,
|
|
8634
8619
|
FIELD_VAL_IS_METHOD,
|
|
8635
8620
|
FIELD_VAL_NOT_DEFINED,
|
|
8636
8621
|
GLOBAL_SELECTOR_IN_SCOPED_STYLE,
|
|
8622
|
+
HANDLER_NAME_COLLISION,
|
|
8637
8623
|
IF_NO_BRANCH_SET,
|
|
8638
|
-
Map3 as IMap,
|
|
8639
|
-
INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD,
|
|
8640
|
-
INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER,
|
|
8641
|
-
INPUT_HANDLER_METHOD_NOT_IMPLEMENTED,
|
|
8642
|
-
INPUT_HANDLER_NOT_IMPLEMENTED,
|
|
8643
|
-
INPUT_HANDLER_NOT_REFERENCED,
|
|
8644
|
-
Set3 as ISet,
|
|
8645
8624
|
LOOKUP_BAD_SHAPE,
|
|
8646
8625
|
LOOKUP_TARGET_MALFORMED,
|
|
8647
8626
|
LintClassCollectorCtx,
|
|
@@ -8650,35 +8629,27 @@ export {
|
|
|
8650
8629
|
LintFinding,
|
|
8651
8630
|
LintParseContext,
|
|
8652
8631
|
LintReport,
|
|
8653
|
-
List2 as List,
|
|
8654
8632
|
MAYBE_ADD_AT_PREFIX,
|
|
8655
8633
|
MAYBE_DROP_AT_PREFIX,
|
|
8656
8634
|
METHOD_VAL_IS_FIELD,
|
|
8657
8635
|
METHOD_VAL_NOT_DEFINED,
|
|
8658
|
-
Map2 as Map,
|
|
8659
8636
|
ModuleInfo,
|
|
8660
8637
|
ModuleTestReport,
|
|
8661
8638
|
ModuleTests,
|
|
8662
|
-
|
|
8663
|
-
OrderedMap2 as OrderedMap,
|
|
8664
|
-
OrderedSet,
|
|
8639
|
+
PASS,
|
|
8665
8640
|
PLACEHOLDERLESS_TEMPLATE_STRING,
|
|
8666
8641
|
PROVIDE_NOT_ADDRESSABLE,
|
|
8667
|
-
PairSorting,
|
|
8668
8642
|
ParseContext,
|
|
8643
|
+
RECEIVE_HANDLER_NOT_IMPLEMENTED,
|
|
8669
8644
|
REDUNDANT_TEMPLATE_STRING,
|
|
8670
8645
|
RENDER_IT_OUTSIDE_OF_LOOP,
|
|
8671
|
-
|
|
8672
|
-
|
|
8646
|
+
RETIRED_CTX_VERB,
|
|
8647
|
+
RETIRED_HANDLER_BUCKET,
|
|
8673
8648
|
RenderBatch,
|
|
8674
8649
|
RenderedExample,
|
|
8675
8650
|
RenderedSection,
|
|
8676
|
-
Repeat,
|
|
8677
8651
|
SEQ_INFO,
|
|
8678
8652
|
SUGGEST_BINDING_MEMBER,
|
|
8679
|
-
Seq,
|
|
8680
|
-
Set2 as Set,
|
|
8681
|
-
Stack2 as Stack,
|
|
8682
8653
|
TOP_LEVEL_AT_RULE_IN_SCOPED_STYLE,
|
|
8683
8654
|
Test,
|
|
8684
8655
|
TestReport,
|
|
@@ -8693,7 +8664,7 @@ export {
|
|
|
8693
8664
|
UNKNOWN_X_OP,
|
|
8694
8665
|
UNSUPPORTED_EXPR_SYNTAX,
|
|
8695
8666
|
X_OP_IGNORES_CHILDREN,
|
|
8696
|
-
check,
|
|
8667
|
+
check2 as check,
|
|
8697
8668
|
checkComponent,
|
|
8698
8669
|
collectIterBindings,
|
|
8699
8670
|
compileClassesToStyle,
|
|
@@ -8704,55 +8675,18 @@ export {
|
|
|
8704
8675
|
docComponents,
|
|
8705
8676
|
drive,
|
|
8706
8677
|
export_expect as expect,
|
|
8707
|
-
fromJS,
|
|
8708
|
-
get,
|
|
8709
|
-
getIn,
|
|
8710
|
-
has,
|
|
8711
|
-
hasIn,
|
|
8712
|
-
hash,
|
|
8713
8678
|
html,
|
|
8714
8679
|
injectCss,
|
|
8715
|
-
is2 as is,
|
|
8716
|
-
isAssociative,
|
|
8717
|
-
isCollection,
|
|
8718
|
-
isMap2 as isIMap,
|
|
8719
|
-
isImmutable,
|
|
8720
|
-
isIndexed2 as isIndexed,
|
|
8721
|
-
isKeyed2 as isKeyed,
|
|
8722
|
-
isList,
|
|
8723
|
-
isMap,
|
|
8724
|
-
isOrderedMap2 as isOMap,
|
|
8725
|
-
isOrdered,
|
|
8726
|
-
isOrderedMap,
|
|
8727
|
-
isOrderedSet,
|
|
8728
|
-
isPlainObject,
|
|
8729
|
-
isRecord,
|
|
8730
|
-
isSeq,
|
|
8731
|
-
isSet,
|
|
8732
|
-
isStack,
|
|
8733
|
-
isValueObject,
|
|
8734
8680
|
lintIdToMessage,
|
|
8735
8681
|
macro,
|
|
8736
8682
|
makeCollector,
|
|
8737
|
-
merge,
|
|
8738
|
-
mergeDeep,
|
|
8739
|
-
mergeDeepWith,
|
|
8740
|
-
mergeWith,
|
|
8741
|
-
phaseHasBubble,
|
|
8742
8683
|
phaseOps,
|
|
8743
|
-
remove,
|
|
8744
|
-
removeIn,
|
|
8745
8684
|
reportTestReportToConsole,
|
|
8746
8685
|
resolveArgs,
|
|
8747
8686
|
rootDispatcher,
|
|
8748
8687
|
runTests,
|
|
8749
|
-
set,
|
|
8750
|
-
setIn,
|
|
8751
8688
|
shadowCheckComponent,
|
|
8752
8689
|
suggestionToMessage,
|
|
8753
8690
|
test,
|
|
8754
|
-
tutuca
|
|
8755
|
-
update,
|
|
8756
|
-
updateIn,
|
|
8757
|
-
version
|
|
8691
|
+
tutuca
|
|
8758
8692
|
};
|