tutuca 0.13.0 → 0.13.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tutuca-cli.js +136 -214
- package/dist/tutuca-dev.ext.js +123 -199
- package/dist/tutuca-dev.js +123 -199
- package/dist/tutuca-dev.min.js +4 -4
- package/dist/tutuca-extra.ext.js +120 -196
- package/dist/tutuca-extra.js +120 -196
- package/dist/tutuca-extra.min.js +3 -3
- package/dist/tutuca.ext.js +120 -196
- package/dist/tutuca.js +120 -196
- package/dist/tutuca.min.js +3 -3
- package/package.json +1 -1
- package/skill/tutuca/core.md +4 -2
- package/skill/tutuca/testing.md +1 -1
- package/skill/tutuca-source/tutuca.ext.js +120 -196
package/dist/tutuca-extra.js
CHANGED
|
@@ -767,11 +767,6 @@ var writeKey = (value, key, next) => {
|
|
|
767
767
|
value.add(next);
|
|
768
768
|
} else value[key] = next;
|
|
769
769
|
};
|
|
770
|
-
var readSeqKey = (value, key, dval = null) => {
|
|
771
|
-
const direct = readKey(value, key, NONE);
|
|
772
|
-
if (direct !== NONE) return direct;
|
|
773
|
-
return typeof value?.get === "function" ? value.get(key, dval) : dval;
|
|
774
|
-
};
|
|
775
770
|
var writeSeqKey = (value, key, next) => {
|
|
776
771
|
if (value instanceof Map || value instanceof Set || Array.isArray(value) || Object.hasOwn(value, key))
|
|
777
772
|
writeKey(value, key, next);
|
|
@@ -784,7 +779,7 @@ var Step = class {
|
|
|
784
779
|
}
|
|
785
780
|
setDraftValue(_root, _v) {
|
|
786
781
|
}
|
|
787
|
-
enterFrame(stack,
|
|
782
|
+
enterFrame(stack, next) {
|
|
788
783
|
return stack.enter(next, {}, true);
|
|
789
784
|
}
|
|
790
785
|
toAbstractPathStep() {
|
|
@@ -810,7 +805,7 @@ var BindStep = class _BindStep extends Step {
|
|
|
810
805
|
lookup(v, _dval) {
|
|
811
806
|
return v;
|
|
812
807
|
}
|
|
813
|
-
enterFrame(stack,
|
|
808
|
+
enterFrame(stack, next) {
|
|
814
809
|
return stack.enter(next, { ...this.binds }, false);
|
|
815
810
|
}
|
|
816
811
|
withIndex(i) {
|
|
@@ -828,7 +823,7 @@ var ScopeBindStep = class _ScopeBindStep extends BindStep {
|
|
|
828
823
|
super(binds);
|
|
829
824
|
this.val = val;
|
|
830
825
|
}
|
|
831
|
-
enterFrame(stack,
|
|
826
|
+
enterFrame(stack, next) {
|
|
832
827
|
const dyn = this.val.evalAsHandler(stack)?.call(stack.it) ?? {};
|
|
833
828
|
return stack.enter(next, { ...this.binds, ...dyn }, false);
|
|
834
829
|
}
|
|
@@ -867,13 +862,13 @@ var SeqStep = class extends Step {
|
|
|
867
862
|
this.key = key;
|
|
868
863
|
}
|
|
869
864
|
lookup(v, dval = null) {
|
|
870
|
-
return
|
|
865
|
+
return seqGet(readKey(v, this.field, null), this.key, dval);
|
|
871
866
|
}
|
|
872
867
|
setDraftValue(root, v) {
|
|
873
868
|
const seq = readKey(root, this.field, null);
|
|
874
869
|
if (seq != null) writeSeqKey(seq, this.key, v);
|
|
875
870
|
}
|
|
876
|
-
enterFrame(stack,
|
|
871
|
+
enterFrame(stack, next) {
|
|
877
872
|
return stack.enter(next, { key: this.key }, true);
|
|
878
873
|
}
|
|
879
874
|
toKey() {
|
|
@@ -889,7 +884,7 @@ var SeqAccessStep = class extends Step {
|
|
|
889
884
|
lookup(v, dval = null) {
|
|
890
885
|
const seq = readKey(v, this.seqField, NONE);
|
|
891
886
|
const key = readKey(v, this.keyField, NONE);
|
|
892
|
-
return key !== NONE && seq !== NONE ?
|
|
887
|
+
return key !== NONE && seq !== NONE ? seqGet(seq, key, dval) : dval;
|
|
893
888
|
}
|
|
894
889
|
setDraftValue(root, v) {
|
|
895
890
|
const seq = readKey(root, this.seqField, NONE);
|
|
@@ -920,7 +915,7 @@ var EachBindStep = class extends Step {
|
|
|
920
915
|
}
|
|
921
916
|
// Replay the renderer's per-item binds (key, value + any @enrich-with binds)
|
|
922
917
|
// so a rebuilt stack matches the one @each rendered with.
|
|
923
|
-
enterFrame(stack,
|
|
918
|
+
enterFrame(stack, next) {
|
|
924
919
|
return stack.enter(next, this.iterInfo.enrichBinds(stack, this.key), false);
|
|
925
920
|
}
|
|
926
921
|
toAbstractPathStep() {
|
|
@@ -928,7 +923,7 @@ var EachBindStep = class extends Step {
|
|
|
928
923
|
}
|
|
929
924
|
};
|
|
930
925
|
var EachRenderItStep = class extends SeqStep {
|
|
931
|
-
enterFrame(stack,
|
|
926
|
+
enterFrame(stack, next) {
|
|
932
927
|
return stack.enter(next, { key: this.key, value: next }, false).enter(next, {}, true);
|
|
933
928
|
}
|
|
934
929
|
toAbstractPathStep() {
|
|
@@ -953,7 +948,7 @@ var DynStep = class extends Step {
|
|
|
953
948
|
warnRawDynStep("lookup", this);
|
|
954
949
|
return dval;
|
|
955
950
|
}
|
|
956
|
-
enterFrame(stack,
|
|
951
|
+
enterFrame(stack, _next) {
|
|
957
952
|
warnRawDynStep("enterFrame", this);
|
|
958
953
|
return stack;
|
|
959
954
|
}
|
|
@@ -1091,7 +1086,7 @@ var Path = class _Path {
|
|
|
1091
1086
|
console.warn("bad PathItem", { root: stack.it, step, path: this });
|
|
1092
1087
|
return null;
|
|
1093
1088
|
}
|
|
1094
|
-
stack = step.enterFrame(stack,
|
|
1089
|
+
stack = step.enterFrame(stack, next);
|
|
1095
1090
|
prev = next;
|
|
1096
1091
|
}
|
|
1097
1092
|
return stack;
|
|
@@ -1161,10 +1156,6 @@ var Path = class _Path {
|
|
|
1161
1156
|
console.warn("event reconstruction: dynamic-var producer not found", pendingDyns);
|
|
1162
1157
|
return [new _Path(pathSteps.reverse()), handlers];
|
|
1163
1158
|
}
|
|
1164
|
-
static fromEvent(e, rNode, maxDepth, comps, stopOnNoEvent = true) {
|
|
1165
|
-
const { type, target } = e;
|
|
1166
|
-
return _Path.fromNodeAndEventName(target, type, rNode, maxDepth, comps, stopOnNoEvent);
|
|
1167
|
-
}
|
|
1168
1159
|
};
|
|
1169
1160
|
function metaChain(n) {
|
|
1170
1161
|
const out = [];
|
|
@@ -1724,7 +1715,7 @@ var Attributes = class {
|
|
|
1724
1715
|
this.items = items;
|
|
1725
1716
|
}
|
|
1726
1717
|
static parse(attributes, px, parseAll = false) {
|
|
1727
|
-
return
|
|
1718
|
+
return new AttrParser(px).parse(attributes, parseAll);
|
|
1728
1719
|
}
|
|
1729
1720
|
isConstant() {
|
|
1730
1721
|
return false;
|
|
@@ -1970,9 +1961,6 @@ var IfAttr = class extends BaseAttr {
|
|
|
1970
1961
|
return this.condVal.eval(stack) ? this.thenVal.eval(stack) : this.elseVal.eval(stack);
|
|
1971
1962
|
}
|
|
1972
1963
|
};
|
|
1973
|
-
function getAttrParser(px) {
|
|
1974
|
-
return new AttrParser(px);
|
|
1975
|
-
}
|
|
1976
1964
|
var EventHandler = class _EventHandler {
|
|
1977
1965
|
constructor(handlerVal, args = []) {
|
|
1978
1966
|
this.handlerVal = handlerVal;
|
|
@@ -1988,12 +1976,6 @@ var EventHandler = class _EventHandler {
|
|
|
1988
1976
|
return r === null ? null : new _EventHandler(r.handlerVal, r.args);
|
|
1989
1977
|
}
|
|
1990
1978
|
};
|
|
1991
|
-
var IntentHandler = class {
|
|
1992
|
-
constructor(name, fn) {
|
|
1993
|
-
this.name = name;
|
|
1994
|
-
this.fn = fn;
|
|
1995
|
-
}
|
|
1996
|
-
};
|
|
1997
1979
|
|
|
1998
1980
|
// src/iteration.js
|
|
1999
1981
|
var SEQ_INFO = /* @__PURE__ */ Symbol.for("tutuca.seqInfo");
|
|
@@ -2044,6 +2026,15 @@ var callEnricher = (enricher, it, binds, key, value, iterData) => {
|
|
|
2044
2026
|
binds.key = key;
|
|
2045
2027
|
binds.value = value;
|
|
2046
2028
|
};
|
|
2029
|
+
function bindsForKey({ seq, it, loopWith, enricher, ctx }, key) {
|
|
2030
|
+
const value = seqGet(seq, key, null);
|
|
2031
|
+
const binds = { key, value };
|
|
2032
|
+
if (enricher) {
|
|
2033
|
+
const { iterData } = unpackLoopResult(loopWith.call(it, seq, ctx), seq);
|
|
2034
|
+
callEnricher(enricher, it, binds, key, value, iterData);
|
|
2035
|
+
}
|
|
2036
|
+
return binds;
|
|
2037
|
+
}
|
|
2047
2038
|
var visitKeys = (seq, keys, visit) => {
|
|
2048
2039
|
const attrName = isIndexedSeq(seq) ? "si" : "sk";
|
|
2049
2040
|
for (const key of keys) visit(key, seqGet(seq, key), attrName);
|
|
@@ -2888,20 +2879,11 @@ var IterInfo = class {
|
|
|
2888
2879
|
const enricher = this.enrichWithVal?.evalAsHandler(stack) ?? null;
|
|
2889
2880
|
return { seq, filter, loopWith, enricher };
|
|
2890
2881
|
}
|
|
2891
|
-
// Rebuild the per-item binds for `key
|
|
2892
|
-
// { key, value }, then run @enrich-with (with @loop-with's iterData) if any.
|
|
2882
|
+
// Rebuild the per-item binds for `key` (see iteration.js bindsForKey).
|
|
2893
2883
|
enrichBinds(stack, key) {
|
|
2894
2884
|
const { seq, filter, loopWith, enricher } = this.eval(stack);
|
|
2895
|
-
const
|
|
2896
|
-
|
|
2897
|
-
if (enricher) {
|
|
2898
|
-
const { iterData } = unpackLoopResult(
|
|
2899
|
-
loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)),
|
|
2900
|
-
seq
|
|
2901
|
-
);
|
|
2902
|
-
callEnricher(enricher, stack.it, binds, key, value, iterData);
|
|
2903
|
-
}
|
|
2904
|
-
return binds;
|
|
2885
|
+
const ctx = makeLoopCtx(stack, filter);
|
|
2886
|
+
return bindsForKey({ seq, it: stack.it, loopWith, enricher, ctx }, key);
|
|
2905
2887
|
}
|
|
2906
2888
|
};
|
|
2907
2889
|
function xOp(consumed = [], { wrappable = false, wrapper = null, ignoresChildren = false } = {}) {
|
|
@@ -3097,10 +3079,11 @@ var NodeEvent = class {
|
|
|
3097
3079
|
}
|
|
3098
3080
|
};
|
|
3099
3081
|
var fwdIfCtxPred = (pred) => (w) => (that, f, args, ctx) => pred(ctx) ? w(that, f, args, ctx) : that;
|
|
3100
|
-
var
|
|
3101
|
-
var
|
|
3102
|
-
var
|
|
3103
|
-
var
|
|
3082
|
+
var fwdIfEventPred = (pred) => fwdIfCtxPred(({ e }) => pred(e));
|
|
3083
|
+
var fwdIfKey = (keyName) => fwdIfEventPred(keyIs(keyName));
|
|
3084
|
+
var fwdCtrl = fwdIfEventPred(macCtrl);
|
|
3085
|
+
var fwdMeta = fwdIfEventPred((e) => e.metaKey);
|
|
3086
|
+
var fwdAlt = fwdIfEventPred((e) => e.altKey);
|
|
3104
3087
|
var MOD_WRAPPERS_FOR_ANY_EVENT = {
|
|
3105
3088
|
ctrl: fwdCtrl,
|
|
3106
3089
|
cmd: fwdCtrl,
|
|
@@ -3207,13 +3190,15 @@ var ComponentStack = class _ComponentStack {
|
|
|
3207
3190
|
getCompFor(v) {
|
|
3208
3191
|
return this.comps.getCompFor(v);
|
|
3209
3192
|
}
|
|
3210
|
-
// Handlers that answer an intent's `lex` leg. A name maps to a LIST
|
|
3211
|
-
// walks: a handler that returns PASS declines and hands
|
|
3212
|
-
//
|
|
3193
|
+
// Handlers that answer an intent's `lex` leg. A name maps to a LIST of plain
|
|
3194
|
+
// functions, because the leg walks: a handler that returns PASS declines and hands
|
|
3195
|
+
// the intent to the next one. Each runs with no `this` and takes a dispatcher
|
|
3196
|
+
// context as its final argument; resolving answers, throwing fails. A bare function
|
|
3197
|
+
// is accepted as a one-element list.
|
|
3213
3198
|
registerIntentHandlers(handlers) {
|
|
3214
3199
|
for (const name in handlers) {
|
|
3215
|
-
const fns =
|
|
3216
|
-
this.intentsByName[name] =
|
|
3200
|
+
const fns = handlers[name];
|
|
3201
|
+
this.intentsByName[name] = Array.isArray(fns) ? fns : [fns];
|
|
3217
3202
|
}
|
|
3218
3203
|
}
|
|
3219
3204
|
// Innermost scope first, then outward. Concatenated rather than first-match, so a
|
|
@@ -3243,14 +3228,12 @@ var ComponentStack = class _ComponentStack {
|
|
|
3243
3228
|
}
|
|
3244
3229
|
};
|
|
3245
3230
|
var ProvideInfo = class {
|
|
3246
|
-
constructor(
|
|
3247
|
-
this.name = name;
|
|
3231
|
+
constructor(val) {
|
|
3248
3232
|
this.val = val;
|
|
3249
3233
|
}
|
|
3250
3234
|
};
|
|
3251
3235
|
var LookupInfo = class {
|
|
3252
|
-
constructor(
|
|
3253
|
-
this.name = name;
|
|
3236
|
+
constructor(val) {
|
|
3254
3237
|
this.val = val;
|
|
3255
3238
|
}
|
|
3256
3239
|
};
|
|
@@ -3298,13 +3281,13 @@ var Component = class {
|
|
|
3298
3281
|
continue;
|
|
3299
3282
|
}
|
|
3300
3283
|
const val = parseProvide(this._rawProvide[key], ctx);
|
|
3301
|
-
if (val) this.provide[key] = new ProvideInfo(
|
|
3284
|
+
if (val) this.provide[key] = new ProvideInfo(val);
|
|
3302
3285
|
}
|
|
3303
3286
|
for (const entry of this._rawLookup) {
|
|
3304
3287
|
const name = isString(entry) ? entry : isString(entry?.name) ? entry.name : null;
|
|
3305
3288
|
if (name === null) continue;
|
|
3306
3289
|
const defStr = isString(entry?.default) ? entry.default : null;
|
|
3307
|
-
this.lookup[name] = new LookupInfo(
|
|
3290
|
+
this.lookup[name] = new LookupInfo(defStr === null ? null : parseField(defStr, ctx));
|
|
3308
3291
|
}
|
|
3309
3292
|
for (const key in this.lookup)
|
|
3310
3293
|
if (this.provide[key] !== void 0)
|
|
@@ -3334,7 +3317,7 @@ var Component = class {
|
|
|
3334
3317
|
// src/stack.js
|
|
3335
3318
|
var STOP = /* @__PURE__ */ Symbol("STOP");
|
|
3336
3319
|
var NEXT = /* @__PURE__ */ Symbol("NEXT");
|
|
3337
|
-
var
|
|
3320
|
+
var DEFAULT_ROUTE = ["dyn", "lex"];
|
|
3338
3321
|
function routeLookup(route, lex, dyn) {
|
|
3339
3322
|
for (let i = 0; i < route.length; i++) {
|
|
3340
3323
|
const leg = route[i];
|
|
@@ -3456,20 +3439,6 @@ var Stack = class _Stack {
|
|
|
3456
3439
|
lookupBind(name) {
|
|
3457
3440
|
return lookup(this.binds, name);
|
|
3458
3441
|
}
|
|
3459
|
-
// The `lex` leg: what a name means in the registration scope of the component being
|
|
3460
|
-
// rendered. The scope chain holds components, so this leg only ever answers for a
|
|
3461
|
-
// type name — for a value name it is a miss, which is why one default route serves
|
|
3462
|
-
// both. Guarded: a non-component `it` has no scope to ask.
|
|
3463
|
-
_lookupLex(name) {
|
|
3464
|
-
return this.comps.getCompFor(this.it)?.scope.lookupComponent(name) ?? null;
|
|
3465
|
-
}
|
|
3466
|
-
lookupRouted(name, route = DEFAULT_LOOKUP_ROUTE) {
|
|
3467
|
-
return routeLookup(
|
|
3468
|
-
route,
|
|
3469
|
-
() => this._lookupLex(name),
|
|
3470
|
-
() => this.lookupDynamic(name)
|
|
3471
|
-
);
|
|
3472
|
-
}
|
|
3473
3442
|
lookupFieldRaw(name) {
|
|
3474
3443
|
return this.it[name] ?? null;
|
|
3475
3444
|
}
|
|
@@ -3502,34 +3471,16 @@ var Stack = class _Stack {
|
|
|
3502
3471
|
// src/oo.js
|
|
3503
3472
|
var BAD_VALUE = /* @__PURE__ */ Symbol("BadValue");
|
|
3504
3473
|
var nullCoercer = (v) => v;
|
|
3505
|
-
function defaultToData(v) {
|
|
3506
|
-
if (v instanceof Map) return [...v.entries()];
|
|
3507
|
-
if (v instanceof Set) return [...v.values()];
|
|
3508
|
-
return v;
|
|
3509
|
-
}
|
|
3510
3474
|
var Field = class {
|
|
3511
3475
|
constructor(type, name, typeCheck, coercer, defaultValue = null) {
|
|
3512
3476
|
this.type = type;
|
|
3513
3477
|
this.name = name;
|
|
3514
3478
|
this.typeCheck = typeCheck;
|
|
3515
3479
|
this.coercer = coercer;
|
|
3516
|
-
this.checks = [];
|
|
3517
3480
|
this.defaultValue = defaultValue;
|
|
3518
3481
|
}
|
|
3519
|
-
toDataDef() {
|
|
3520
|
-
return { type: this.type, defaultValue: defaultToData(this.defaultValue) };
|
|
3521
|
-
}
|
|
3522
|
-
getFirstFailingCheck(v) {
|
|
3523
|
-
if (!this.typeCheck.isValid(v)) return this.typeCheck;
|
|
3524
|
-
for (const check3 of this.checks) if (!check3.isValid(v)) return check3;
|
|
3525
|
-
return null;
|
|
3526
|
-
}
|
|
3527
3482
|
isValid(v) {
|
|
3528
|
-
return this.
|
|
3529
|
-
}
|
|
3530
|
-
addCheck(check3) {
|
|
3531
|
-
this.checks.push(check3);
|
|
3532
|
-
return this;
|
|
3483
|
+
return this.typeCheck(v);
|
|
3533
3484
|
}
|
|
3534
3485
|
coerceOr(v, defaultValue = null) {
|
|
3535
3486
|
if (this.isValid(v)) return v;
|
|
@@ -3540,39 +3491,15 @@ var Field = class {
|
|
|
3540
3491
|
return this.coerceOr(v, this.defaultValue);
|
|
3541
3492
|
}
|
|
3542
3493
|
};
|
|
3543
|
-
var
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
var
|
|
3552
|
-
};
|
|
3553
|
-
var CHECK_TYPE_ANY = new CheckTypeAny();
|
|
3554
|
-
var FnCheck = class extends Check {
|
|
3555
|
-
constructor(isValidFn, getMessageFn) {
|
|
3556
|
-
super();
|
|
3557
|
-
this._isValid = isValidFn;
|
|
3558
|
-
this._getMessage = getMessageFn;
|
|
3559
|
-
}
|
|
3560
|
-
isValid(v) {
|
|
3561
|
-
return this._isValid(v);
|
|
3562
|
-
}
|
|
3563
|
-
getMessage(v) {
|
|
3564
|
-
return this._getMessage(v);
|
|
3565
|
-
}
|
|
3566
|
-
};
|
|
3567
|
-
var check = (fn, message) => new FnCheck(fn, () => message);
|
|
3568
|
-
var CHECK_TYPE_INT = check(Number.isInteger, "Integer expected");
|
|
3569
|
-
var CHECK_TYPE_FLOAT = check(Number.isFinite, "Float expected");
|
|
3570
|
-
var CHECK_TYPE_BOOL = check((v) => typeof v === "boolean", "Boolean expected");
|
|
3571
|
-
var CHECK_TYPE_STRING = check((v) => typeof v === "string", "String expected");
|
|
3572
|
-
var CHECK_TYPE_LIST = check(Array.isArray, "Array expected");
|
|
3573
|
-
var CHECK_TYPE_OBJECT = check(isPlainObject, "Plain object expected");
|
|
3574
|
-
var CHECK_TYPE_MAP = check((v) => v instanceof Map, "Map expected");
|
|
3575
|
-
var CHECK_TYPE_SET = check((v) => v instanceof Set, "Set expected");
|
|
3494
|
+
var CHECK_TYPE_ANY = (_v) => true;
|
|
3495
|
+
var CHECK_TYPE_INT = Number.isInteger;
|
|
3496
|
+
var CHECK_TYPE_FLOAT = Number.isFinite;
|
|
3497
|
+
var CHECK_TYPE_BOOL = (v) => typeof v === "boolean";
|
|
3498
|
+
var CHECK_TYPE_STRING = (v) => typeof v === "string";
|
|
3499
|
+
var CHECK_TYPE_LIST = Array.isArray;
|
|
3500
|
+
var CHECK_TYPE_OBJECT = isPlainObject;
|
|
3501
|
+
var CHECK_TYPE_MAP = (v) => v instanceof Map;
|
|
3502
|
+
var CHECK_TYPE_SET = (v) => v instanceof Set;
|
|
3576
3503
|
var FieldBool = class extends Field {
|
|
3577
3504
|
constructor(name, defaultValue = false) {
|
|
3578
3505
|
super("bool", name, CHECK_TYPE_BOOL, (v) => !!v, defaultValue);
|
|
@@ -3582,9 +3509,6 @@ var FieldAny = class extends Field {
|
|
|
3582
3509
|
constructor(name, defaultValue = null) {
|
|
3583
3510
|
super("any", name, CHECK_TYPE_ANY, nullCoercer, defaultValue);
|
|
3584
3511
|
}
|
|
3585
|
-
toDataDef() {
|
|
3586
|
-
return { type: getTypeName(this.defaultValue) ?? "any", defaultValue: this.defaultValue };
|
|
3587
|
-
}
|
|
3588
3512
|
};
|
|
3589
3513
|
var FieldString = class extends Field {
|
|
3590
3514
|
constructor(name, defaultValue = "") {
|
|
@@ -3607,26 +3531,13 @@ var FieldFloat = class extends Field {
|
|
|
3607
3531
|
super("float", name, CHECK_TYPE_FLOAT, (_) => null, defaultValue);
|
|
3608
3532
|
}
|
|
3609
3533
|
};
|
|
3610
|
-
var
|
|
3611
|
-
var
|
|
3612
|
-
constructor(typeName) {
|
|
3613
|
-
this.typeName = typeName;
|
|
3614
|
-
}
|
|
3615
|
-
isValid(v) {
|
|
3616
|
-
return getTypeName(v) === this.typeName;
|
|
3617
|
-
}
|
|
3618
|
-
getMessage(v) {
|
|
3619
|
-
return `Expected "${this.typeName}", got "${getTypeName(v)}"`;
|
|
3620
|
-
}
|
|
3621
|
-
};
|
|
3534
|
+
var metaOf = (v) => v?.constructor?.[COMPONENT] ?? v?.constructor?.getMetaClass?.();
|
|
3535
|
+
var getTypeName = (v) => metaOf(v)?.name ?? null;
|
|
3622
3536
|
var FieldComp = class extends Field {
|
|
3623
3537
|
constructor(type, name, args) {
|
|
3624
|
-
super(type, name,
|
|
3538
|
+
super(type, name, (v) => getTypeName(v) === type, nullCoercer, null);
|
|
3625
3539
|
this.args = args;
|
|
3626
3540
|
}
|
|
3627
|
-
toDataDef() {
|
|
3628
|
-
return { component: this.type, args: this.args };
|
|
3629
|
-
}
|
|
3630
3541
|
};
|
|
3631
3542
|
var FieldList = class extends Field {
|
|
3632
3543
|
constructor(name, defaultValue = []) {
|
|
@@ -3788,7 +3699,7 @@ function classFromData(name, { fields = {}, methods, statics }) {
|
|
|
3788
3699
|
return b.build();
|
|
3789
3700
|
}
|
|
3790
3701
|
function validateDraftFields(current2, draft) {
|
|
3791
|
-
const meta = current2
|
|
3702
|
+
const meta = metaOf(current2);
|
|
3792
3703
|
if (!meta) return;
|
|
3793
3704
|
for (const [name, field] of Object.entries(meta.fields)) {
|
|
3794
3705
|
const value = draft[name];
|
|
@@ -3915,28 +3826,46 @@ var Transactor = class {
|
|
|
3915
3826
|
if (i !== -1) this._refusalObservers.splice(i, 1);
|
|
3916
3827
|
};
|
|
3917
3828
|
}
|
|
3918
|
-
// Build and dispatch
|
|
3919
|
-
//
|
|
3920
|
-
//
|
|
3921
|
-
//
|
|
3829
|
+
// Build and dispatch one observer record. Pins field-resolved keys (e.g. a
|
|
3830
|
+
// `.a[.selId]` render target reconstructed from a DOM event) against the root the
|
|
3831
|
+
// handler read, so pathKeys carries concrete keys instead of dropping the dynamic
|
|
3832
|
+
// step. No-op when nobody is observing.
|
|
3833
|
+
_emitRecord(root, { kind, name, args, path, targetPath, handler, handlerName, matched, before, after, parent }) {
|
|
3834
|
+
if (this._observers.length === 0) return;
|
|
3835
|
+
const pinned = path.pinKeys(root);
|
|
3836
|
+
this._emit({
|
|
3837
|
+
kind,
|
|
3838
|
+
name,
|
|
3839
|
+
args: args ?? null,
|
|
3840
|
+
path: pinned,
|
|
3841
|
+
pathKeys: pinned.toKeys(),
|
|
3842
|
+
targetPath,
|
|
3843
|
+
handler: handler ?? null,
|
|
3844
|
+
handlerName: handlerName ?? (handler?.name || null),
|
|
3845
|
+
matched: matched ?? null,
|
|
3846
|
+
before,
|
|
3847
|
+
after,
|
|
3848
|
+
parent,
|
|
3849
|
+
timestamp: Date.now()
|
|
3850
|
+
});
|
|
3851
|
+
}
|
|
3852
|
+
// The observer record for a settled transaction. The resolved handler
|
|
3853
|
+
// (`_resolvedHandler`/`_matched`) and per-leaf before/after (`_before`/`_after`)
|
|
3854
|
+
// were captured while the handler ran (see callHandler / Transaction.run).
|
|
3922
3855
|
_emitTransaction(transaction, root) {
|
|
3923
3856
|
if (this._observers.length === 0) return;
|
|
3924
3857
|
if (transaction._resolvedHandler === void 0) return;
|
|
3925
|
-
|
|
3926
|
-
this._emit({
|
|
3858
|
+
this._emitRecord(root, {
|
|
3927
3859
|
kind: transaction.observeKind,
|
|
3928
3860
|
name: transaction.observeName,
|
|
3929
|
-
args: transaction.args
|
|
3930
|
-
path,
|
|
3931
|
-
pathKeys: path.toKeys(),
|
|
3861
|
+
args: transaction.args,
|
|
3862
|
+
path: transaction.getTransactionPath(),
|
|
3932
3863
|
targetPath: transaction.targetPath ?? transaction.path,
|
|
3933
|
-
handler: transaction._resolvedHandler
|
|
3934
|
-
|
|
3935
|
-
matched: transaction._matched ?? null,
|
|
3864
|
+
handler: transaction._resolvedHandler,
|
|
3865
|
+
matched: transaction._matched,
|
|
3936
3866
|
before: transaction._before,
|
|
3937
3867
|
after: transaction._after,
|
|
3938
|
-
parent: transaction.parentTransaction
|
|
3939
|
-
timestamp: Date.now()
|
|
3868
|
+
parent: transaction.parentTransaction
|
|
3940
3869
|
});
|
|
3941
3870
|
}
|
|
3942
3871
|
// Make `child` a tracked unit of `parent`'s subtree: the parent's completion stays open
|
|
@@ -4034,7 +3963,7 @@ var Transaction = class {
|
|
|
4034
3963
|
// rather than throwing, so a stray call from the wrong place is a message and not a
|
|
4035
3964
|
// crash. `walk` is undefined here, which is how ctx.reply/ctx.fail tell the two apart.
|
|
4036
3965
|
stop() {
|
|
4037
|
-
|
|
3966
|
+
warnNotIntent("stop");
|
|
4038
3967
|
}
|
|
4039
3968
|
forward(_opts) {
|
|
4040
3969
|
console.warn('ctx.forward() needs a "receive" or "intent" handler - ignored');
|
|
@@ -4119,11 +4048,8 @@ var InputEvent = class extends Transaction {
|
|
|
4119
4048
|
}
|
|
4120
4049
|
this.transactor.pushIntent(this.dispatchPath, name, args, rest, this);
|
|
4121
4050
|
}
|
|
4122
|
-
buildStack(root, comps) {
|
|
4123
|
-
return this.path.toTransactionPath().buildStack(Stack.root(comps, root, this));
|
|
4124
|
-
}
|
|
4125
4051
|
getHandlerAndArgs(root, _instance, comps) {
|
|
4126
|
-
const stack = this.buildStack(root,
|
|
4052
|
+
const stack = this.path.toTransactionPath().buildStack(Stack.root(comps, root, this));
|
|
4127
4053
|
const [handler, args] = this.handler.getHandlerAndArgs(stack, this);
|
|
4128
4054
|
this._handlerArgs = [...args];
|
|
4129
4055
|
const path = this.dispatchPath;
|
|
@@ -4225,7 +4151,6 @@ var IntentEvent = class extends NameArgsTransaction {
|
|
|
4225
4151
|
};
|
|
4226
4152
|
var PASS = /* @__PURE__ */ Symbol.for("tutuca.intent.pass");
|
|
4227
4153
|
var REFUSAL_RING_CAP = 200;
|
|
4228
|
-
var DEFAULT_ROUTE = ["dyn", "lex"];
|
|
4229
4154
|
var INTENT_DEPTH = 64;
|
|
4230
4155
|
var IntentWalk = class {
|
|
4231
4156
|
constructor(transactor, path, name, args, opts, parent, release) {
|
|
@@ -4274,24 +4199,19 @@ var IntentWalk = class {
|
|
|
4274
4199
|
const txnPath = this.origin.toTransactionPath();
|
|
4275
4200
|
const leaf = txnPath.lookup(root);
|
|
4276
4201
|
const chain = this.transactor.comps.getIntentChainFor(leaf, this.name);
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
this.
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
after: void 0,
|
|
4291
|
-
parent: this.parent,
|
|
4292
|
-
timestamp: Date.now()
|
|
4293
|
-
});
|
|
4294
|
-
}
|
|
4202
|
+
this.transactor._emitRecord(root, {
|
|
4203
|
+
kind: "intent",
|
|
4204
|
+
name: this.name,
|
|
4205
|
+
args: this.args,
|
|
4206
|
+
path: txnPath,
|
|
4207
|
+
targetPath: this.origin,
|
|
4208
|
+
handler: chain[0],
|
|
4209
|
+
handlerName: chain[0]?.name || this.name,
|
|
4210
|
+
matched: chain.length > 0 ? "exact" : "none",
|
|
4211
|
+
before: leaf,
|
|
4212
|
+
after: void 0,
|
|
4213
|
+
parent: this.parent
|
|
4214
|
+
});
|
|
4295
4215
|
if (chain.length === 0) return this.advance();
|
|
4296
4216
|
const p = this._runLex(chain, 0);
|
|
4297
4217
|
this.transactor._inflight.add(p);
|
|
@@ -4302,7 +4222,7 @@ var IntentWalk = class {
|
|
|
4302
4222
|
if (i >= chain.length) return this.advance();
|
|
4303
4223
|
const ctx = new Dispatcher(this.origin, this.transactor, this.parent);
|
|
4304
4224
|
try {
|
|
4305
|
-
const res = await chain[i].
|
|
4225
|
+
const res = await chain[i].apply(null, [...this.args, ctx]);
|
|
4306
4226
|
if (res === PASS) return this._runLex(chain, i + 1);
|
|
4307
4227
|
this.answer("Ok", res);
|
|
4308
4228
|
} catch (error) {
|
|
@@ -4455,9 +4375,8 @@ var Dispatcher = class {
|
|
|
4455
4375
|
// the same spelling as `ctx.intent` — `["dyn"]` the render ancestry, `["lex"]` the
|
|
4456
4376
|
// registration scope, default both.
|
|
4457
4377
|
lookup(name, opts) {
|
|
4458
|
-
const route = opts?.route ?? DEFAULT_LOOKUP_ROUTE;
|
|
4459
4378
|
return routeLookup(
|
|
4460
|
-
route,
|
|
4379
|
+
opts?.route ?? DEFAULT_ROUTE,
|
|
4461
4380
|
() => this._lookupLex(name),
|
|
4462
4381
|
() => this._stack()?.lookupDynamic(name) ?? null
|
|
4463
4382
|
);
|
|
@@ -4476,12 +4395,10 @@ var Dispatcher = class {
|
|
|
4476
4395
|
// can only ever answer with one; the `dyn` leg reads a binding an ancestor
|
|
4477
4396
|
// published, so it is the leg that has to be checked.
|
|
4478
4397
|
lookupType(name, opts) {
|
|
4479
|
-
const
|
|
4398
|
+
const route = opts?.route ?? DEFAULT_ROUTE;
|
|
4399
|
+
const v = this.lookup(name, { route });
|
|
4480
4400
|
if (v == null) {
|
|
4481
|
-
this.transactor.refuse("TYPE_NOT_FOUND", {
|
|
4482
|
-
name,
|
|
4483
|
-
route: opts?.route ?? DEFAULT_LOOKUP_ROUTE
|
|
4484
|
-
});
|
|
4401
|
+
this.transactor.refuse("TYPE_NOT_FOUND", { name, route });
|
|
4485
4402
|
return null;
|
|
4486
4403
|
}
|
|
4487
4404
|
if (v?.[COMPONENT] == null) {
|
|
@@ -4606,7 +4523,14 @@ var App = class {
|
|
|
4606
4523
|
const { type } = e;
|
|
4607
4524
|
const isDrag = type === "dragover" || type === "dragstart" || type === "dragend" || type === "drop";
|
|
4608
4525
|
const { rootNode: root, maxEventNodeDepth: maxDepth, comps, transactor } = this;
|
|
4609
|
-
const [path, handlers] = Path.
|
|
4526
|
+
const [path, handlers] = Path.fromNodeAndEventName(
|
|
4527
|
+
e.target,
|
|
4528
|
+
type,
|
|
4529
|
+
root,
|
|
4530
|
+
maxDepth,
|
|
4531
|
+
comps,
|
|
4532
|
+
!isDrag
|
|
4533
|
+
);
|
|
4610
4534
|
if (isDrag) this._handleDragEvent(e, type, path);
|
|
4611
4535
|
if (path !== null && handlers !== null)
|
|
4612
4536
|
for (const handler of handlers) transactor.transactInputNow(path, e, handler, this.dragInfo);
|
|
@@ -4668,7 +4592,7 @@ var App = class {
|
|
|
4668
4592
|
const value = txnPath.lookup(rootValue);
|
|
4669
4593
|
const dragType = e.target.dataset.dragtype ?? "?";
|
|
4670
4594
|
const stack = path.toTransactionPath().buildStack(this.makeStack(rootValue));
|
|
4671
|
-
this.dragInfo = new DragInfo(
|
|
4595
|
+
this.dragInfo = new DragInfo(stack, value, dragType, e.target);
|
|
4672
4596
|
} else if (type === "drop") {
|
|
4673
4597
|
e.preventDefault();
|
|
4674
4598
|
this._cleanDragOverAttrs();
|
|
@@ -4805,10 +4729,8 @@ function getClosestDropTarget(target, rootNode, count) {
|
|
|
4805
4729
|
return null;
|
|
4806
4730
|
}
|
|
4807
4731
|
var DragInfo = class {
|
|
4808
|
-
constructor(
|
|
4809
|
-
this.path = path;
|
|
4732
|
+
constructor(stack, val, type, node) {
|
|
4810
4733
|
this.stack = stack;
|
|
4811
|
-
this.e = e;
|
|
4812
4734
|
this.val = val;
|
|
4813
4735
|
this.type = type;
|
|
4814
4736
|
this.node = node;
|
|
@@ -4978,6 +4900,8 @@ var Renderer = class {
|
|
|
4978
4900
|
setNullCache() {
|
|
4979
4901
|
this.cache = new NullDomCache();
|
|
4980
4902
|
}
|
|
4903
|
+
// Library utilities for consumers embedding tutuca: render a value to a detached
|
|
4904
|
+
// DOM node / an HTML string. Not called by the framework itself.
|
|
4981
4905
|
renderToDOM(stack, val) {
|
|
4982
4906
|
const rootNode = document.createElement("div");
|
|
4983
4907
|
const rOpts = { document };
|
|
@@ -5102,7 +5026,7 @@ function dispatchPhase(dispatcher, targetPath, phase, self) {
|
|
|
5102
5026
|
var css = String.raw;
|
|
5103
5027
|
var html = String.raw;
|
|
5104
5028
|
var macro = (defaults, rawView) => new Macro(defaults, rawView);
|
|
5105
|
-
function
|
|
5029
|
+
function check(_app) {
|
|
5106
5030
|
return { error: 0, warn: 0, hint: 0, dummyCheck: true };
|
|
5107
5031
|
}
|
|
5108
5032
|
async function test(_opts) {
|
|
@@ -5140,7 +5064,7 @@ export {
|
|
|
5140
5064
|
PASS,
|
|
5141
5065
|
ParseContext,
|
|
5142
5066
|
SEQ_INFO,
|
|
5143
|
-
|
|
5067
|
+
check,
|
|
5144
5068
|
collectIterBindings,
|
|
5145
5069
|
compileClassesToStyle,
|
|
5146
5070
|
compileClassesToStyleText,
|