tutuca 0.9.51 → 0.9.53
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 +44 -13
- package/dist/tutuca-dev.js +99 -13
- package/dist/tutuca-dev.min.js +3 -3
- package/dist/tutuca-extra.js +18 -6
- package/dist/tutuca-extra.min.js +3 -3
- package/dist/tutuca.js +18 -6
- package/dist/tutuca.min.js +3 -3
- package/package.json +1 -1
- package/skill/tutuca/SKILL.md +5 -3
- package/skill/tutuca/core.md +9 -4
- package/skill/tutuca/testing.md +266 -0
package/dist/tutuca-cli.js
CHANGED
|
@@ -4317,7 +4317,15 @@ var init_value = __esm(() => {
|
|
|
4317
4317
|
vals[i] = val;
|
|
4318
4318
|
allConsts &&= val instanceof ConstVal;
|
|
4319
4319
|
}
|
|
4320
|
-
|
|
4320
|
+
if (allConsts)
|
|
4321
|
+
return new ConstVal(vals.map((v) => v.val).join(""));
|
|
4322
|
+
let lo = 0;
|
|
4323
|
+
let hi = vals.length;
|
|
4324
|
+
while (lo < hi && vals[lo] instanceof ConstVal && vals[lo].val === "")
|
|
4325
|
+
lo++;
|
|
4326
|
+
while (hi > lo && vals[hi - 1] instanceof ConstVal && vals[hi - 1].val === "")
|
|
4327
|
+
hi--;
|
|
4328
|
+
return new StrTplVal(lo === 0 && hi === vals.length ? vals : vals.slice(lo, hi));
|
|
4321
4329
|
}
|
|
4322
4330
|
};
|
|
4323
4331
|
NameVal = class NameVal extends VarVal {
|
|
@@ -5472,8 +5480,10 @@ class ComponentStack {
|
|
|
5472
5480
|
function defaultOnStackEnter() {
|
|
5473
5481
|
return null;
|
|
5474
5482
|
}
|
|
5483
|
+
var _rawSpecKeys = "name view style commonStyle globalStyle input receive bubble response alter on views dynamic fields methods statics", KNOWN_SPEC_KEYS;
|
|
5475
5484
|
var init_components = __esm(() => {
|
|
5476
5485
|
init_attribute();
|
|
5486
|
+
KNOWN_SPEC_KEYS = new Set(_rawSpecKeys.split(" "));
|
|
5477
5487
|
});
|
|
5478
5488
|
|
|
5479
5489
|
// tools/core/html-tokenizer.js
|
|
@@ -7771,8 +7781,9 @@ function classifyBadValue(value) {
|
|
|
7771
7781
|
return "call-with-args";
|
|
7772
7782
|
return null;
|
|
7773
7783
|
}
|
|
7774
|
-
function checkComponent(Comp, lx = new LintContext) {
|
|
7784
|
+
function checkComponent(Comp, lx = new LintContext, { wellKnownExtras = EMPTY_SET } = {}) {
|
|
7775
7785
|
return lx.push({ componentName: Comp.name }, () => {
|
|
7786
|
+
checkUnknownSpecKeys(lx, Comp, wellKnownExtras);
|
|
7776
7787
|
const referencedAlters = new Set;
|
|
7777
7788
|
const referencedInputs = new Set;
|
|
7778
7789
|
checkEventHandlersHaveImpls(lx, Comp, referencedInputs);
|
|
@@ -7993,7 +8004,12 @@ function checkConsistentAttrVal(lx, val, fields, proto, scope, alter, referenced
|
|
|
7993
8004
|
lx.error(UNKNOWN_HANDLER_ARG_NAME, { ...errCtx, name: val.name }, replaceNameSuggestion(val.name, KNOWN_HANDLER_NAMES));
|
|
7994
8005
|
}
|
|
7995
8006
|
} else if (valName === "StrTplVal") {
|
|
7996
|
-
|
|
8007
|
+
const vs = val.vals;
|
|
8008
|
+
if (vs.length === 1) {
|
|
8009
|
+
const simpler = String(vs[0]);
|
|
8010
|
+
lx.warn(REDUNDANT_TEMPLATE_STRING, { ...errCtx, simpler }, { kind: "rewrite", from: `{${simpler}}`, to: simpler });
|
|
8011
|
+
}
|
|
8012
|
+
for (const subVal of vs) {
|
|
7997
8013
|
checkConsistentAttrVal(lx, subVal, fields, proto, scope, alter, referencedAlters, skipNameVal, errCtx);
|
|
7998
8014
|
}
|
|
7999
8015
|
} else if (valName === "AlterHandlerNameVal") {
|
|
@@ -8107,6 +8123,18 @@ function checkConsistentAttrs(lx, Comp, referencedAlters) {
|
|
|
8107
8123
|
});
|
|
8108
8124
|
}
|
|
8109
8125
|
}
|
|
8126
|
+
function checkUnknownSpecKeys(lx, Comp, wellKnownExtras) {
|
|
8127
|
+
const extra = Comp.extra;
|
|
8128
|
+
if (!extra)
|
|
8129
|
+
return;
|
|
8130
|
+
let candidates = null;
|
|
8131
|
+
for (const key of Object.keys(extra)) {
|
|
8132
|
+
if (wellKnownExtras.has(key))
|
|
8133
|
+
continue;
|
|
8134
|
+
candidates ??= [...KNOWN_COMPONENT_SPEC_KEYS, ...wellKnownExtras];
|
|
8135
|
+
lx.warn(UNKNOWN_COMPONENT_SPEC_KEY, { key }, replaceNameSuggestion(key, candidates));
|
|
8136
|
+
}
|
|
8137
|
+
}
|
|
8110
8138
|
function checkUnreferencedAlterHandlers(lx, Comp, referencedAlters) {
|
|
8111
8139
|
for (const name in Comp.alter) {
|
|
8112
8140
|
if (!referencedAlters.has(name)) {
|
|
@@ -8149,10 +8177,12 @@ class LintContext {
|
|
|
8149
8177
|
this.reports.push({ id, info, level, context: { ...this.frame }, suggestion });
|
|
8150
8178
|
}
|
|
8151
8179
|
}
|
|
8152
|
-
var KNOWN_DIRECTIVE_NAMES, ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED", ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED", RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP", UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER", UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME", INPUT_HANDLER_NOT_IMPLEMENTED = "INPUT_HANDLER_NOT_IMPLEMENTED", INPUT_HANDLER_NOT_REFERENCED = "INPUT_HANDLER_NOT_REFERENCED", INPUT_HANDLER_METHOD_NOT_IMPLEMENTED = "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED", INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD = "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD", INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER", FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED", DUPLICATE_ATTR_DEFINITION = "DUPLICATE_ATTR_DEFINITION", IF_NO_BRANCH_SET = "IF_NO_BRANCH_SET", UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME", UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME", UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG", UNKNOWN_DIRECTIVE = "UNKNOWN_DIRECTIVE", UNKNOWN_X_OP = "UNKNOWN_X_OP", UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR", MAYBE_DROP_AT_PREFIX = "MAYBE_DROP_AT_PREFIX", BAD_VALUE = "BAD_VALUE", UNSUPPORTED_EXPR_SYNTAX = "UNSUPPORTED_EXPR_SYNTAX", PARSE_ISSUE_KIND_TO_LINT_ID, X_KNOWN_OP_NAMES, X_KNOWN_ATTR_NAMES, AT_PREFIX_HINT_KNOWN_BY_KIND, LEVEL_WARN2 = "warn", LEVEL_ERROR2 = "error", LEVEL_HINT = "hint", PARSE_ISSUE_KIND_TO_KNOWN_NAMES, UNSUPPORTED_EXPR_GUIDANCE, HTML_LINT_OPTS, NO_WRAPPERS, KNOWN_HANDLER_NAMES, NODE_KIND_TO_CTX, LintParseContext;
|
|
8180
|
+
var KNOWN_COMPONENT_SPEC_KEYS, EMPTY_SET, KNOWN_DIRECTIVE_NAMES, ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED", ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED", RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP", UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER", UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME", INPUT_HANDLER_NOT_IMPLEMENTED = "INPUT_HANDLER_NOT_IMPLEMENTED", INPUT_HANDLER_NOT_REFERENCED = "INPUT_HANDLER_NOT_REFERENCED", INPUT_HANDLER_METHOD_NOT_IMPLEMENTED = "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED", INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD = "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD", INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER", FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED", DUPLICATE_ATTR_DEFINITION = "DUPLICATE_ATTR_DEFINITION", IF_NO_BRANCH_SET = "IF_NO_BRANCH_SET", UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME", UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME", UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG", UNKNOWN_DIRECTIVE = "UNKNOWN_DIRECTIVE", UNKNOWN_X_OP = "UNKNOWN_X_OP", UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR", MAYBE_DROP_AT_PREFIX = "MAYBE_DROP_AT_PREFIX", BAD_VALUE = "BAD_VALUE", UNSUPPORTED_EXPR_SYNTAX = "UNSUPPORTED_EXPR_SYNTAX", REDUNDANT_TEMPLATE_STRING = "REDUNDANT_TEMPLATE_STRING", UNKNOWN_COMPONENT_SPEC_KEY = "UNKNOWN_COMPONENT_SPEC_KEY", PARSE_ISSUE_KIND_TO_LINT_ID, X_KNOWN_OP_NAMES, X_KNOWN_ATTR_NAMES, AT_PREFIX_HINT_KNOWN_BY_KIND, LEVEL_WARN2 = "warn", LEVEL_ERROR2 = "error", LEVEL_HINT = "hint", PARSE_ISSUE_KIND_TO_KNOWN_NAMES, UNSUPPORTED_EXPR_GUIDANCE, HTML_LINT_OPTS, NO_WRAPPERS, KNOWN_HANDLER_NAMES, NODE_KIND_TO_CTX, LintParseContext;
|
|
8153
8181
|
var init_lint_check = __esm(() => {
|
|
8154
8182
|
init_anode();
|
|
8155
8183
|
init_htmllinter();
|
|
8184
|
+
KNOWN_COMPONENT_SPEC_KEYS = new Set("name view style commonStyle globalStyle input receive bubble response alter on views dynamic fields methods statics".split(" "));
|
|
8185
|
+
EMPTY_SET = new Set;
|
|
8156
8186
|
KNOWN_DIRECTIVE_NAMES = new Set([
|
|
8157
8187
|
"dangerouslysetinnerhtml",
|
|
8158
8188
|
"slot",
|
|
@@ -8249,7 +8279,7 @@ var init_lint_check = __esm(() => {
|
|
|
8249
8279
|
});
|
|
8250
8280
|
|
|
8251
8281
|
// tools/core/lint.js
|
|
8252
|
-
function lintComponents(normalized, { name = null, LintParseContextClass }) {
|
|
8282
|
+
function lintComponents(normalized, { name = null, LintParseContextClass, wellKnownExtras = new Set }) {
|
|
8253
8283
|
const comps = normalized.components;
|
|
8254
8284
|
const picked = name === null ? comps : comps.filter((c) => c.name === name);
|
|
8255
8285
|
const stack = new ComponentStack;
|
|
@@ -8261,7 +8291,7 @@ function lintComponents(normalized, { name = null, LintParseContextClass }) {
|
|
|
8261
8291
|
const results = [];
|
|
8262
8292
|
for (const comp of picked) {
|
|
8263
8293
|
comp.compile(LintParseContextClass);
|
|
8264
|
-
const lx = checkComponent(comp);
|
|
8294
|
+
const lx = checkComponent(comp, undefined, { wellKnownExtras });
|
|
8265
8295
|
results.push(new LintComponentResult({
|
|
8266
8296
|
componentName: comp.name,
|
|
8267
8297
|
findings: lx.reports.map((r) => new LintFinding(r))
|
|
@@ -11177,7 +11207,7 @@ var keyMapper = (v, k) => k, entryMapper = (v, k) => [k, v], not = (predicate) =
|
|
|
11177
11207
|
const iter = SetCollection(value);
|
|
11178
11208
|
assertNotInfinite(iter.size);
|
|
11179
11209
|
iter.forEach((v) => set3.add(v));
|
|
11180
|
-
}), SetImpl, makeSet = (map, ownerID) => new SetImpl(map, ownerID),
|
|
11210
|
+
}), SetImpl, makeSet = (map, ownerID) => new SetImpl(map, ownerID), EMPTY_SET2, emptySet = () => EMPTY_SET2 || (EMPTY_SET2 = makeSet(emptyMap())), OrderedSet = (value) => value === undefined || value === null ? emptyOrderedSet() : isOrderedSet(value) ? value : emptyOrderedSet().withMutations((set3) => {
|
|
11181
11211
|
const iter = SetCollection(value);
|
|
11182
11212
|
assertNotInfinite(iter.size);
|
|
11183
11213
|
iter.forEach((v) => set3.add(v));
|
|
@@ -13600,9 +13630,6 @@ class Renderer {
|
|
|
13600
13630
|
this.comps = comps;
|
|
13601
13631
|
this.cache = new WeakMapDomCache;
|
|
13602
13632
|
}
|
|
13603
|
-
getSeqInfo(seq) {
|
|
13604
|
-
return isIndexed(seq) ? imIndexedIter : isKeyed(seq) ? imKeyedIter : seq?.[SEQ_INFO] ?? unkIter;
|
|
13605
|
-
}
|
|
13606
13633
|
renderTag(tag, attrs, childs) {
|
|
13607
13634
|
return h(tag, attrs, childs);
|
|
13608
13635
|
}
|
|
@@ -13660,7 +13687,7 @@ class Renderer {
|
|
|
13660
13687
|
const { seq, filter, loopWith } = iterInfo.eval(stack);
|
|
13661
13688
|
const r = [];
|
|
13662
13689
|
const iterData = loopWith.call(stack.it, seq);
|
|
13663
|
-
|
|
13690
|
+
getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
13664
13691
|
if (filter.call(stack.it, key, value, iterData)) {
|
|
13665
13692
|
const dom = this.renderIt(stack.enter(value, { key }, true), nodeId, key, viewName);
|
|
13666
13693
|
this.pushEachEntry(r, nodeId, attrName, key, dom);
|
|
@@ -13673,7 +13700,7 @@ class Renderer {
|
|
|
13673
13700
|
const r = [];
|
|
13674
13701
|
const it = stack.it;
|
|
13675
13702
|
const iterData = loopWith.call(it, seq);
|
|
13676
|
-
|
|
13703
|
+
getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
13677
13704
|
if (filter.call(it, key, value, iterData)) {
|
|
13678
13705
|
const cachePath = enricher ? [it, value] : [value];
|
|
13679
13706
|
const binds = { key, value };
|
|
@@ -13710,7 +13737,7 @@ class Renderer {
|
|
|
13710
13737
|
return new VComment(`§${JSON.stringify(info)}§`);
|
|
13711
13738
|
}
|
|
13712
13739
|
}
|
|
13713
|
-
var DATASET_ATTRS, imIndexedIter = (seq, visit) => {
|
|
13740
|
+
var DATASET_ATTRS, getSeqInfo = (seq) => isIndexed(seq) ? imIndexedIter : isKeyed(seq) ? imKeyedIter : seq?.[SEQ_INFO] ?? unkIter, imIndexedIter = (seq, visit) => {
|
|
13714
13741
|
let i = 0;
|
|
13715
13742
|
for (const v of seq)
|
|
13716
13743
|
visit(i++, v, "si");
|
|
@@ -14622,6 +14649,10 @@ function lintIdToMessage(id, info) {
|
|
|
14622
14649
|
return `${badValueMessage(info)}${fmtTagSuffix(info)}`;
|
|
14623
14650
|
case "UNSUPPORTED_EXPR_SYNTAX":
|
|
14624
14651
|
return `${unsupportedExprMessage(info)}${fmtTagSuffix(info)}`;
|
|
14652
|
+
case "REDUNDANT_TEMPLATE_STRING":
|
|
14653
|
+
return `Redundant template string — '{${info.simpler}}' should be just '${info.simpler}'${fmtOriginSuffix(info)}`;
|
|
14654
|
+
case "UNKNOWN_COMPONENT_SPEC_KEY":
|
|
14655
|
+
return `Unknown component spec key '${info.key}' — value will be ignored at runtime`;
|
|
14625
14656
|
case "HTML_TAG_NAME_HAS_UPPERCASE":
|
|
14626
14657
|
return `Tag <${info.raw}> will be lowercased to <${info.lowercased}>${fmtLocationSuffix(info)}`;
|
|
14627
14658
|
case "HTML_SVG_TAG_WILL_LOWERCASE":
|
package/dist/tutuca-dev.js
CHANGED
|
@@ -3792,7 +3792,15 @@ class StrTplVal extends VarVal {
|
|
|
3792
3792
|
vals[i] = val;
|
|
3793
3793
|
allConsts &&= val instanceof ConstVal;
|
|
3794
3794
|
}
|
|
3795
|
-
|
|
3795
|
+
if (allConsts)
|
|
3796
|
+
return new ConstVal(vals.map((v) => v.val).join(""));
|
|
3797
|
+
let lo = 0;
|
|
3798
|
+
let hi = vals.length;
|
|
3799
|
+
while (lo < hi && vals[lo] instanceof ConstVal && vals[lo].val === "")
|
|
3800
|
+
lo++;
|
|
3801
|
+
while (hi > lo && vals[hi - 1] instanceof ConstVal && vals[hi - 1].val === "")
|
|
3802
|
+
hi--;
|
|
3803
|
+
return new StrTplVal(lo === 0 && hi === vals.length ? vals : vals.slice(lo, hi));
|
|
3796
3804
|
}
|
|
3797
3805
|
}
|
|
3798
3806
|
|
|
@@ -7275,6 +7283,8 @@ function closestName(name, candidates, maxDistance = 2) {
|
|
|
7275
7283
|
}
|
|
7276
7284
|
|
|
7277
7285
|
// tools/core/lint-check.js
|
|
7286
|
+
var KNOWN_COMPONENT_SPEC_KEYS = new Set("name view style commonStyle globalStyle input receive bubble response alter on views dynamic fields methods statics".split(" "));
|
|
7287
|
+
var EMPTY_SET = new Set;
|
|
7278
7288
|
var KNOWN_DIRECTIVE_NAMES = new Set([
|
|
7279
7289
|
"dangerouslysetinnerhtml",
|
|
7280
7290
|
"slot",
|
|
@@ -7311,6 +7321,8 @@ var UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR";
|
|
|
7311
7321
|
var MAYBE_DROP_AT_PREFIX = "MAYBE_DROP_AT_PREFIX";
|
|
7312
7322
|
var BAD_VALUE = "BAD_VALUE";
|
|
7313
7323
|
var UNSUPPORTED_EXPR_SYNTAX = "UNSUPPORTED_EXPR_SYNTAX";
|
|
7324
|
+
var REDUNDANT_TEMPLATE_STRING = "REDUNDANT_TEMPLATE_STRING";
|
|
7325
|
+
var UNKNOWN_COMPONENT_SPEC_KEY = "UNKNOWN_COMPONENT_SPEC_KEY";
|
|
7314
7326
|
var PARSE_ISSUE_KIND_TO_LINT_ID = {
|
|
7315
7327
|
"unknown-directive": UNKNOWN_DIRECTIVE,
|
|
7316
7328
|
"unknown-x-op": UNKNOWN_X_OP,
|
|
@@ -7389,8 +7401,9 @@ var UNSUPPORTED_EXPR_GUIDANCE = {
|
|
|
7389
7401
|
logical: "Logical operators aren't supported in dynamic attributes. Combine the conditions in a method on the component and reference it as '.methodName'.",
|
|
7390
7402
|
"call-with-args": "Method calls with arguments aren't supported here. Reference a no-arg method ('.methodName') and read what you need from component state, or split into per-case methods."
|
|
7391
7403
|
};
|
|
7392
|
-
function checkComponent(Comp, lx = new LintContext) {
|
|
7404
|
+
function checkComponent(Comp, lx = new LintContext, { wellKnownExtras = EMPTY_SET } = {}) {
|
|
7393
7405
|
return lx.push({ componentName: Comp.name }, () => {
|
|
7406
|
+
checkUnknownSpecKeys(lx, Comp, wellKnownExtras);
|
|
7394
7407
|
const referencedAlters = new Set;
|
|
7395
7408
|
const referencedInputs = new Set;
|
|
7396
7409
|
checkEventHandlersHaveImpls(lx, Comp, referencedInputs);
|
|
@@ -7636,7 +7649,12 @@ function checkConsistentAttrVal(lx, val, fields, proto, scope, alter, referenced
|
|
|
7636
7649
|
lx.error(UNKNOWN_HANDLER_ARG_NAME, { ...errCtx, name: val.name }, replaceNameSuggestion(val.name, KNOWN_HANDLER_NAMES));
|
|
7637
7650
|
}
|
|
7638
7651
|
} else if (valName === "StrTplVal") {
|
|
7639
|
-
|
|
7652
|
+
const vs = val.vals;
|
|
7653
|
+
if (vs.length === 1) {
|
|
7654
|
+
const simpler = String(vs[0]);
|
|
7655
|
+
lx.warn(REDUNDANT_TEMPLATE_STRING, { ...errCtx, simpler }, { kind: "rewrite", from: `{${simpler}}`, to: simpler });
|
|
7656
|
+
}
|
|
7657
|
+
for (const subVal of vs) {
|
|
7640
7658
|
checkConsistentAttrVal(lx, subVal, fields, proto, scope, alter, referencedAlters, skipNameVal, errCtx);
|
|
7641
7659
|
}
|
|
7642
7660
|
} else if (valName === "AlterHandlerNameVal") {
|
|
@@ -7759,6 +7777,18 @@ function checkConsistentAttrs(lx, Comp, referencedAlters) {
|
|
|
7759
7777
|
});
|
|
7760
7778
|
}
|
|
7761
7779
|
}
|
|
7780
|
+
function checkUnknownSpecKeys(lx, Comp, wellKnownExtras) {
|
|
7781
|
+
const extra = Comp.extra;
|
|
7782
|
+
if (!extra)
|
|
7783
|
+
return;
|
|
7784
|
+
let candidates = null;
|
|
7785
|
+
for (const key of Object.keys(extra)) {
|
|
7786
|
+
if (wellKnownExtras.has(key))
|
|
7787
|
+
continue;
|
|
7788
|
+
candidates ??= [...KNOWN_COMPONENT_SPEC_KEYS, ...wellKnownExtras];
|
|
7789
|
+
lx.warn(UNKNOWN_COMPONENT_SPEC_KEY, { key }, replaceNameSuggestion(key, candidates));
|
|
7790
|
+
}
|
|
7791
|
+
}
|
|
7762
7792
|
function checkUnreferencedAlterHandlers(lx, Comp, referencedAlters) {
|
|
7763
7793
|
for (const name in Comp.alter) {
|
|
7764
7794
|
if (!referencedAlters.has(name)) {
|
|
@@ -8372,6 +8402,10 @@ function lintIdToMessage(id, info) {
|
|
|
8372
8402
|
return `${badValueMessage(info)}${fmtTagSuffix(info)}`;
|
|
8373
8403
|
case "UNSUPPORTED_EXPR_SYNTAX":
|
|
8374
8404
|
return `${unsupportedExprMessage(info)}${fmtTagSuffix(info)}`;
|
|
8405
|
+
case "REDUNDANT_TEMPLATE_STRING":
|
|
8406
|
+
return `Redundant template string — '{${info.simpler}}' should be just '${info.simpler}'${fmtOriginSuffix(info)}`;
|
|
8407
|
+
case "UNKNOWN_COMPONENT_SPEC_KEY":
|
|
8408
|
+
return `Unknown component spec key '${info.key}' — value will be ignored at runtime`;
|
|
8375
8409
|
case "HTML_TAG_NAME_HAS_UPPERCASE":
|
|
8376
8410
|
return `Tag <${info.raw}> will be lowercased to <${info.lowercased}>${fmtLocationSuffix(info)}`;
|
|
8377
8411
|
case "HTML_SVG_TAG_WILL_LOWERCASE":
|
|
@@ -8578,6 +8612,8 @@ class DynamicAlias extends Dynamic {
|
|
|
8578
8612
|
}
|
|
8579
8613
|
}
|
|
8580
8614
|
var isString = (v) => typeof v === "string";
|
|
8615
|
+
var _rawSpecKeys = "name view style commonStyle globalStyle input receive bubble response alter on views dynamic fields methods statics";
|
|
8616
|
+
var KNOWN_SPEC_KEYS = new Set(_rawSpecKeys.split(" "));
|
|
8581
8617
|
var _compId = 0;
|
|
8582
8618
|
|
|
8583
8619
|
class Component {
|
|
@@ -8602,6 +8638,10 @@ class Component {
|
|
|
8602
8638
|
this._rawDynamic = o.dynamic ?? {};
|
|
8603
8639
|
this.dynamic = {};
|
|
8604
8640
|
this.scope = null;
|
|
8641
|
+
this.extra = {};
|
|
8642
|
+
for (const key of Object.keys(o))
|
|
8643
|
+
if (!KNOWN_SPEC_KEYS.has(key))
|
|
8644
|
+
this.extra[key] = o[key];
|
|
8605
8645
|
}
|
|
8606
8646
|
compile(ParseContext2) {
|
|
8607
8647
|
for (const key in this._rawDynamic) {
|
|
@@ -13491,8 +13531,8 @@ class SetImpl extends SetCollectionImpl {
|
|
|
13491
13531
|
}
|
|
13492
13532
|
Set2.isSet = isSet;
|
|
13493
13533
|
var makeSet = (map, ownerID) => new SetImpl(map, ownerID);
|
|
13494
|
-
var
|
|
13495
|
-
var emptySet = () =>
|
|
13534
|
+
var EMPTY_SET2;
|
|
13535
|
+
var emptySet = () => EMPTY_SET2 || (EMPTY_SET2 = makeSet(emptyMap()));
|
|
13496
13536
|
function filterByIters(set3, iters, shouldRemove) {
|
|
13497
13537
|
if (iters.length === 0) {
|
|
13498
13538
|
return set3;
|
|
@@ -14339,16 +14379,16 @@ function extendProtoTruthy(proto, name, uname) {
|
|
|
14339
14379
|
return !this.get(name);
|
|
14340
14380
|
};
|
|
14341
14381
|
}
|
|
14342
|
-
var
|
|
14382
|
+
var EMPTY_SET3 = Set2();
|
|
14343
14383
|
var isetCoercer = (v) => Array.isArray(v) ? Set2(v) : v instanceof Set ? Set2(v) : null;
|
|
14344
14384
|
|
|
14345
14385
|
class FieldSet extends Field {
|
|
14346
|
-
constructor(name, defaultValue =
|
|
14386
|
+
constructor(name, defaultValue = EMPTY_SET3) {
|
|
14347
14387
|
super("set", name, CHECK_TYPE_SET, isetCoercer, defaultValue);
|
|
14348
14388
|
}
|
|
14349
14389
|
extendProtoForType(proto, uname) {
|
|
14350
14390
|
const { name } = this;
|
|
14351
|
-
extendProtoSized(proto, name, uname,
|
|
14391
|
+
extendProtoSized(proto, name, uname, EMPTY_SET3);
|
|
14352
14392
|
proto[`addIn${uname}`] = function(v) {
|
|
14353
14393
|
return this.set(name, this.get(name).add(v));
|
|
14354
14394
|
};
|
|
@@ -14561,9 +14601,6 @@ class Renderer {
|
|
|
14561
14601
|
this.comps = comps;
|
|
14562
14602
|
this.cache = new WeakMapDomCache;
|
|
14563
14603
|
}
|
|
14564
|
-
getSeqInfo(seq) {
|
|
14565
|
-
return isIndexed(seq) ? imIndexedIter : isKeyed(seq) ? imKeyedIter : seq?.[SEQ_INFO] ?? unkIter;
|
|
14566
|
-
}
|
|
14567
14604
|
renderTag(tag, attrs, childs) {
|
|
14568
14605
|
return h(tag, attrs, childs);
|
|
14569
14606
|
}
|
|
@@ -14621,7 +14658,7 @@ class Renderer {
|
|
|
14621
14658
|
const { seq, filter, loopWith } = iterInfo.eval(stack);
|
|
14622
14659
|
const r = [];
|
|
14623
14660
|
const iterData = loopWith.call(stack.it, seq);
|
|
14624
|
-
|
|
14661
|
+
getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
14625
14662
|
if (filter.call(stack.it, key, value, iterData)) {
|
|
14626
14663
|
const dom = this.renderIt(stack.enter(value, { key }, true), nodeId, key, viewName);
|
|
14627
14664
|
this.pushEachEntry(r, nodeId, attrName, key, dom);
|
|
@@ -14634,7 +14671,7 @@ class Renderer {
|
|
|
14634
14671
|
const r = [];
|
|
14635
14672
|
const it = stack.it;
|
|
14636
14673
|
const iterData = loopWith.call(it, seq);
|
|
14637
|
-
|
|
14674
|
+
getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
14638
14675
|
if (filter.call(it, key, value, iterData)) {
|
|
14639
14676
|
const cachePath = enricher ? [it, value] : [value];
|
|
14640
14677
|
const binds = { key, value };
|
|
@@ -14671,6 +14708,7 @@ class Renderer {
|
|
|
14671
14708
|
return new VComment(`§${JSON.stringify(info)}§`);
|
|
14672
14709
|
}
|
|
14673
14710
|
}
|
|
14711
|
+
var getSeqInfo = (seq) => isIndexed(seq) ? imIndexedIter : isKeyed(seq) ? imKeyedIter : seq?.[SEQ_INFO] ?? unkIter;
|
|
14674
14712
|
var imIndexedIter = (seq, visit) => {
|
|
14675
14713
|
let i = 0;
|
|
14676
14714
|
for (const v of seq)
|
|
@@ -14996,6 +15034,51 @@ function docComponents(normalized, { name = null } = {}) {
|
|
|
14996
15034
|
const picked = name === null ? comps : comps.filter((c) => c.name === name);
|
|
14997
15035
|
return new ComponentDocs({ items: getComponentsDocs(picked) });
|
|
14998
15036
|
}
|
|
15037
|
+
// src/util/testing.js
|
|
15038
|
+
var filterAlwaysTrue2 = () => true;
|
|
15039
|
+
var nullLoopWith2 = (seq) => ({ seq });
|
|
15040
|
+
var plainArrayIter = (seq, visit) => {
|
|
15041
|
+
for (let i = 0;i < seq.length; i++)
|
|
15042
|
+
visit(i, seq[i]);
|
|
15043
|
+
};
|
|
15044
|
+
var plainMapIter = (seq, visit) => {
|
|
15045
|
+
for (const [k, v] of seq.entries())
|
|
15046
|
+
visit(k, v);
|
|
15047
|
+
};
|
|
15048
|
+
function pickIter(seq) {
|
|
15049
|
+
if (Array.isArray(seq))
|
|
15050
|
+
return plainArrayIter;
|
|
15051
|
+
if (seq instanceof Map)
|
|
15052
|
+
return plainMapIter;
|
|
15053
|
+
return getSeqInfo(seq);
|
|
15054
|
+
}
|
|
15055
|
+
function resolveAlter(Comp, name) {
|
|
15056
|
+
if (name == null)
|
|
15057
|
+
return null;
|
|
15058
|
+
const fn = Comp.alter?.[name];
|
|
15059
|
+
if (typeof fn !== "function") {
|
|
15060
|
+
throw new Error(`alter handler '${name}' not found on component '${Comp.name}'`);
|
|
15061
|
+
}
|
|
15062
|
+
return fn;
|
|
15063
|
+
}
|
|
15064
|
+
function collectIterBindings(Comp, compInstance, seq, opts = {}) {
|
|
15065
|
+
const whenFn = resolveAlter(Comp, opts.when) ?? filterAlwaysTrue2;
|
|
15066
|
+
const loopWithFn = resolveAlter(Comp, opts.loopWith) ?? nullLoopWith2;
|
|
15067
|
+
const enrichFn = resolveAlter(Comp, opts.enrichWith);
|
|
15068
|
+
const it = compInstance;
|
|
15069
|
+
const iterData = loopWithFn.call(it, seq);
|
|
15070
|
+
const out = [];
|
|
15071
|
+
const iter = pickIter(seq);
|
|
15072
|
+
iter(seq, (key, value) => {
|
|
15073
|
+
if (!whenFn.call(it, key, value, iterData))
|
|
15074
|
+
return;
|
|
15075
|
+
const binds = { key, value };
|
|
15076
|
+
if (enrichFn)
|
|
15077
|
+
enrichFn.call(it, binds, key, value, iterData);
|
|
15078
|
+
out.push(binds);
|
|
15079
|
+
});
|
|
15080
|
+
return out;
|
|
15081
|
+
}
|
|
14999
15082
|
|
|
15000
15083
|
// dev.js
|
|
15001
15084
|
async function test3(opts = {}) {
|
|
@@ -15116,6 +15199,7 @@ export {
|
|
|
15116
15199
|
component,
|
|
15117
15200
|
compileClassesToStyleText,
|
|
15118
15201
|
compileClassesToStyle,
|
|
15202
|
+
collectIterBindings,
|
|
15119
15203
|
checkComponent,
|
|
15120
15204
|
check,
|
|
15121
15205
|
UNSUPPORTED_EXPR_SYNTAX,
|
|
@@ -15126,6 +15210,7 @@ export {
|
|
|
15126
15210
|
UNKNOWN_HANDLER_ARG_NAME,
|
|
15127
15211
|
UNKNOWN_EVENT_MODIFIER,
|
|
15128
15212
|
UNKNOWN_DIRECTIVE,
|
|
15213
|
+
UNKNOWN_COMPONENT_SPEC_KEY,
|
|
15129
15214
|
UNKNOWN_COMPONENT_NAME,
|
|
15130
15215
|
TestResult,
|
|
15131
15216
|
TestReport,
|
|
@@ -15142,6 +15227,7 @@ export {
|
|
|
15142
15227
|
Record,
|
|
15143
15228
|
Range,
|
|
15144
15229
|
RENDER_IT_OUTSIDE_OF_LOOP,
|
|
15230
|
+
REDUNDANT_TEMPLATE_STRING,
|
|
15145
15231
|
ParseContext,
|
|
15146
15232
|
PairSorting,
|
|
15147
15233
|
OrderedSet,
|