tutuca 0.9.68 → 0.9.70
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 +137 -132
- package/dist/tutuca-dev.ext.js +125 -118
- package/dist/tutuca-dev.js +125 -118
- package/dist/tutuca-dev.min.js +1 -1
- package/dist/tutuca-extra.ext.js +44 -44
- package/dist/tutuca-extra.js +44 -44
- package/dist/tutuca-extra.min.js +1 -1
- package/dist/tutuca.ext.js +44 -44
- package/dist/tutuca.js +44 -44
- package/dist/tutuca.min.js +1 -1
- package/package.json +1 -1
- package/skill/tutuca/core.md +47 -105
- package/skill/tutuca/testing.md +8 -1
- package/skill/tutuca-source/tutuca.ext.js +44 -44
package/dist/tutuca-dev.js
CHANGED
|
@@ -9470,16 +9470,16 @@ function parseXOpVal(opName, value, px, parserFn) {
|
|
|
9470
9470
|
return val;
|
|
9471
9471
|
}
|
|
9472
9472
|
function processXExtras(node, attrs, opName, startIdx, px) {
|
|
9473
|
-
const consumed =
|
|
9474
|
-
const wrappable = X_OP_WRAPPABLE.has(opName);
|
|
9473
|
+
const { consumed, wrappable } = X_OPS[opName];
|
|
9475
9474
|
const wrappers = [];
|
|
9476
9475
|
for (let i = startIdx;i < attrs.length; i++) {
|
|
9477
9476
|
const a = attrs[i];
|
|
9478
9477
|
const aName = a.name;
|
|
9479
9478
|
if (consumed.has(aName))
|
|
9480
9479
|
continue;
|
|
9481
|
-
|
|
9482
|
-
|
|
9480
|
+
const wrapper = wrappable ? X_OPS[aName]?.wrapper : null;
|
|
9481
|
+
if (wrapper) {
|
|
9482
|
+
wrappers.push([wrapper, vp.parseBool(a.value, px)]);
|
|
9483
9483
|
continue;
|
|
9484
9484
|
}
|
|
9485
9485
|
const issueInfo = { op: opName, name: aName, value: a.value };
|
|
@@ -9571,6 +9571,12 @@ class RenderViewId extends ANode {
|
|
|
9571
9571
|
}
|
|
9572
9572
|
setDataAttr(_key, _val) {}
|
|
9573
9573
|
}
|
|
9574
|
+
function dynRenderStep(comp, name, key) {
|
|
9575
|
+
const p = resolveDynProducer(comp, name);
|
|
9576
|
+
if (!p)
|
|
9577
|
+
return null;
|
|
9578
|
+
return key === undefined ? new DynStep(p.producerCompId, p.producerSteps) : new DynEachStep(p.producerCompId, p.producerSteps, key);
|
|
9579
|
+
}
|
|
9574
9580
|
|
|
9575
9581
|
class RenderNode extends RenderViewId {
|
|
9576
9582
|
render(stack, rx) {
|
|
@@ -9578,10 +9584,8 @@ class RenderNode extends RenderViewId {
|
|
|
9578
9584
|
return rx.renderIt(newStack, this, "", this.viewId);
|
|
9579
9585
|
}
|
|
9580
9586
|
toPathStep(ctx) {
|
|
9581
|
-
if (this.val instanceof DynVal)
|
|
9582
|
-
|
|
9583
|
-
return p ? new DynStep(p.producerCompId, p.producerSteps) : null;
|
|
9584
|
-
}
|
|
9587
|
+
if (this.val instanceof DynVal)
|
|
9588
|
+
return dynRenderStep(ctx.comp, this.val.name);
|
|
9585
9589
|
return super.toPathStep(ctx);
|
|
9586
9590
|
}
|
|
9587
9591
|
}
|
|
@@ -9597,10 +9601,8 @@ class RenderItNode extends RenderViewId {
|
|
|
9597
9601
|
return null;
|
|
9598
9602
|
const nextNode = next.resolveNode();
|
|
9599
9603
|
if (nextNode instanceof EachNode && next.hasKey) {
|
|
9600
|
-
if (nextNode.val instanceof DynVal)
|
|
9601
|
-
|
|
9602
|
-
return p ? new DynEachStep(p.producerCompId, p.producerSteps, next.key) : null;
|
|
9603
|
-
}
|
|
9604
|
+
if (nextNode.val instanceof DynVal)
|
|
9605
|
+
return dynRenderStep(ctx.comp, nextNode.val.name, next.key);
|
|
9604
9606
|
return new EachRenderItStep(nextNode.val.name, next.key);
|
|
9605
9607
|
}
|
|
9606
9608
|
return null;
|
|
@@ -9616,12 +9618,8 @@ class RenderEachNode extends RenderViewId {
|
|
|
9616
9618
|
return rx.renderEach(stack, this.iterInfo, this, this.viewId);
|
|
9617
9619
|
}
|
|
9618
9620
|
toPathStep(ctx) {
|
|
9619
|
-
if (this.val instanceof DynVal)
|
|
9620
|
-
|
|
9621
|
-
return null;
|
|
9622
|
-
const p = resolveDynProducer(ctx.comp, this.val.name);
|
|
9623
|
-
return p ? new DynEachStep(p.producerCompId, p.producerSteps, ctx.key) : null;
|
|
9624
|
-
}
|
|
9621
|
+
if (this.val instanceof DynVal)
|
|
9622
|
+
return ctx.hasKey ? dynRenderStep(ctx.comp, this.val.name, ctx.key) : null;
|
|
9625
9623
|
return super.toPathStep(ctx);
|
|
9626
9624
|
}
|
|
9627
9625
|
static parse(px, vp2, s, as, attrs) {
|
|
@@ -9751,17 +9749,18 @@ class IterInfo {
|
|
|
9751
9749
|
}
|
|
9752
9750
|
var filterAlwaysTrue = (_v, _k, _seq) => true;
|
|
9753
9751
|
var nullLoopWith = (seq) => ({ iterData: { seq } });
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
|
|
9758
|
-
|
|
9759
|
-
|
|
9760
|
-
|
|
9761
|
-
|
|
9762
|
-
}
|
|
9763
|
-
|
|
9764
|
-
|
|
9752
|
+
function xOp(consumed = [], { wrappable = false, wrapper = null } = {}) {
|
|
9753
|
+
return { consumed: new Set(consumed), wrappable, wrapper };
|
|
9754
|
+
}
|
|
9755
|
+
var X_OPS = {
|
|
9756
|
+
slot: xOp(),
|
|
9757
|
+
text: xOp([], { wrappable: true }),
|
|
9758
|
+
render: xOp(["as"], { wrappable: true }),
|
|
9759
|
+
"render-it": xOp(["as"], { wrappable: true }),
|
|
9760
|
+
"render-each": xOp(["as", "when", "loop-with"], { wrappable: true }),
|
|
9761
|
+
show: xOp([], { wrapper: ShowNode }),
|
|
9762
|
+
hide: xOp([], { wrapper: HideNode })
|
|
9763
|
+
};
|
|
9765
9764
|
var WRAPPER_NODES = {
|
|
9766
9765
|
slot: SlotNode,
|
|
9767
9766
|
show: ShowNode,
|
|
@@ -9849,29 +9848,30 @@ var isBlockDomNode = (n) => {
|
|
|
9849
9848
|
const node = n instanceof FragmentNode ? n.childs[0] : n;
|
|
9850
9849
|
return node instanceof DomNode && HTML_BLOCK_TAGS.has(node.tagName);
|
|
9851
9850
|
};
|
|
9851
|
+
var isEmptyText = (c) => c instanceof TextNode && c.val === "";
|
|
9852
|
+
function trimEdgeWhite(node) {
|
|
9853
|
+
if (!node.isWhiteSpace?.())
|
|
9854
|
+
return false;
|
|
9855
|
+
node.condenseWhiteSpace();
|
|
9856
|
+
return true;
|
|
9857
|
+
}
|
|
9852
9858
|
function condenseChildsWhites(childs) {
|
|
9853
9859
|
if (childs.length === 0)
|
|
9854
9860
|
return childs;
|
|
9855
|
-
let changed = false;
|
|
9856
|
-
if (childs[0].isWhiteSpace?.()) {
|
|
9857
|
-
childs[0].condenseWhiteSpace();
|
|
9858
|
-
changed = true;
|
|
9859
|
-
}
|
|
9860
9861
|
const last = childs.length - 1;
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
|
|
9864
|
-
}
|
|
9862
|
+
let emptied = trimEdgeWhite(childs[0]);
|
|
9863
|
+
if (last > 0 && trimEdgeWhite(childs[last]))
|
|
9864
|
+
emptied = true;
|
|
9865
9865
|
for (let i = 1;i < last; i++) {
|
|
9866
9866
|
const cur = childs[i];
|
|
9867
|
-
if (cur.isWhiteSpace?.() && cur.hasNewLine())
|
|
9868
|
-
|
|
9869
|
-
|
|
9870
|
-
|
|
9871
|
-
|
|
9872
|
-
|
|
9867
|
+
if (!(cur.isWhiteSpace?.() && cur.hasNewLine()))
|
|
9868
|
+
continue;
|
|
9869
|
+
const bothBlock = isBlockDomNode(childs[i - 1]) && isBlockDomNode(childs[i + 1]);
|
|
9870
|
+
cur.condenseWhiteSpace(bothBlock ? "" : " ");
|
|
9871
|
+
if (bothBlock)
|
|
9872
|
+
emptied = true;
|
|
9873
9873
|
}
|
|
9874
|
-
return
|
|
9874
|
+
return emptied ? childs.filter((c) => !isEmptyText(c)) : childs;
|
|
9875
9875
|
}
|
|
9876
9876
|
|
|
9877
9877
|
class View {
|
|
@@ -12330,12 +12330,6 @@ var REDUNDANT_TEMPLATE_STRING = "REDUNDANT_TEMPLATE_STRING";
|
|
|
12330
12330
|
var PLACEHOLDERLESS_TEMPLATE_STRING = "PLACEHOLDERLESS_TEMPLATE_STRING";
|
|
12331
12331
|
var UNKNOWN_COMPONENT_SPEC_KEY = "UNKNOWN_COMPONENT_SPEC_KEY";
|
|
12332
12332
|
var COMP_FIELD_BAD_SHAPE = "COMP_FIELD_BAD_SHAPE";
|
|
12333
|
-
var PARSE_ISSUE_KIND_TO_LINT_ID = {
|
|
12334
|
-
"unknown-directive": UNKNOWN_DIRECTIVE,
|
|
12335
|
-
"unknown-x-op": UNKNOWN_X_OP,
|
|
12336
|
-
"unknown-x-attr": UNKNOWN_X_ATTR,
|
|
12337
|
-
"bad-value": BAD_VALUE
|
|
12338
|
-
};
|
|
12339
12333
|
var X_KNOWN_OP_NAMES = new Set([
|
|
12340
12334
|
"slot",
|
|
12341
12335
|
"text",
|
|
@@ -12346,17 +12340,18 @@ var X_KNOWN_OP_NAMES = new Set([
|
|
|
12346
12340
|
"hide"
|
|
12347
12341
|
]);
|
|
12348
12342
|
var X_KNOWN_ATTR_NAMES = new Set(["as", "when", "loop-with", "show", "hide"]);
|
|
12349
|
-
var AT_PREFIX_HINT_KNOWN_BY_KIND = {
|
|
12350
|
-
"unknown-x-op": X_KNOWN_OP_NAMES,
|
|
12351
|
-
"unknown-x-attr": X_KNOWN_ATTR_NAMES
|
|
12352
|
-
};
|
|
12353
12343
|
var LEVEL_WARN2 = "warn";
|
|
12354
12344
|
var LEVEL_ERROR2 = "error";
|
|
12355
12345
|
var LEVEL_HINT = "hint";
|
|
12356
|
-
var
|
|
12357
|
-
"unknown-directive": KNOWN_DIRECTIVE_NAMES,
|
|
12358
|
-
"unknown-x-op": X_KNOWN_OP_NAMES,
|
|
12359
|
-
"unknown-x-attr":
|
|
12346
|
+
var PARSE_ISSUES = {
|
|
12347
|
+
"unknown-directive": { id: UNKNOWN_DIRECTIVE, candidates: KNOWN_DIRECTIVE_NAMES },
|
|
12348
|
+
"unknown-x-op": { id: UNKNOWN_X_OP, candidates: X_KNOWN_OP_NAMES, atPrefix: X_KNOWN_OP_NAMES },
|
|
12349
|
+
"unknown-x-attr": {
|
|
12350
|
+
id: UNKNOWN_X_ATTR,
|
|
12351
|
+
candidates: X_KNOWN_ATTR_NAMES,
|
|
12352
|
+
atPrefix: X_KNOWN_ATTR_NAMES
|
|
12353
|
+
},
|
|
12354
|
+
"bad-value": { id: BAD_VALUE }
|
|
12360
12355
|
};
|
|
12361
12356
|
function collectProtoMethodNames(proto) {
|
|
12362
12357
|
const out = [];
|
|
@@ -12451,9 +12446,10 @@ function checkParseIssues(lx, view) {
|
|
|
12451
12446
|
if (!issues)
|
|
12452
12447
|
return;
|
|
12453
12448
|
for (const { kind, info } of issues) {
|
|
12454
|
-
const
|
|
12455
|
-
if (!
|
|
12449
|
+
const rule = PARSE_ISSUES[kind];
|
|
12450
|
+
if (!rule)
|
|
12456
12451
|
continue;
|
|
12452
|
+
const id = rule.id;
|
|
12457
12453
|
if (kind === "bad-value") {
|
|
12458
12454
|
const detected = classifyBadValue(info.value);
|
|
12459
12455
|
if (detected) {
|
|
@@ -12461,15 +12457,13 @@ function checkParseIssues(lx, view) {
|
|
|
12461
12457
|
continue;
|
|
12462
12458
|
}
|
|
12463
12459
|
}
|
|
12464
|
-
const atPrefixKnown =
|
|
12460
|
+
const atPrefixKnown = rule.atPrefix;
|
|
12465
12461
|
const isAtPrefixedTypo = atPrefixKnown && info.name?.startsWith("@") && atPrefixKnown.has(info.name.slice(1));
|
|
12466
12462
|
let suggestion = null;
|
|
12467
12463
|
if (isAtPrefixedTypo) {
|
|
12468
12464
|
suggestion = { kind: "drop-prefix", from: info.name, to: info.name.slice(1) };
|
|
12469
|
-
} else {
|
|
12470
|
-
|
|
12471
|
-
if (candidates)
|
|
12472
|
-
suggestion = replaceNameSuggestion(info.name, candidates);
|
|
12465
|
+
} else if (rule.candidates) {
|
|
12466
|
+
suggestion = replaceNameSuggestion(info.name, rule.candidates);
|
|
12473
12467
|
}
|
|
12474
12468
|
lx.error(id, info, suggestion);
|
|
12475
12469
|
if (isAtPrefixedTypo) {
|
|
@@ -12639,70 +12633,83 @@ function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
|
|
|
12639
12633
|
});
|
|
12640
12634
|
}
|
|
12641
12635
|
}
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12645
|
-
|
|
12636
|
+
var fixTo = (from, to) => ({ kind: "rewrite", from, to });
|
|
12637
|
+
function reportUnknownName(lx, code, name, candidates, info) {
|
|
12638
|
+
lx.error(code, { ...info, name }, replaceNameSuggestion(name, candidates));
|
|
12639
|
+
}
|
|
12640
|
+
var ATTR_VAL_CHECKERS = {
|
|
12641
|
+
FieldVal({ lx, val, env, errCtx }) {
|
|
12642
|
+
const { fields, proto } = env;
|
|
12646
12643
|
const { name } = val;
|
|
12647
|
-
if (fields[name]
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
}
|
|
12651
|
-
|
|
12652
|
-
}
|
|
12653
|
-
|
|
12654
|
-
|
|
12644
|
+
if (fields[name] !== undefined)
|
|
12645
|
+
return;
|
|
12646
|
+
if (proto[name] !== undefined)
|
|
12647
|
+
lx.error(FIELD_VAL_IS_METHOD, { ...errCtx, val, name }, fixTo(`.${name}`, `$${name}`));
|
|
12648
|
+
else
|
|
12649
|
+
reportUnknownName(lx, FIELD_VAL_NOT_DEFINED, name, Object.keys(fields), { ...errCtx, val });
|
|
12650
|
+
},
|
|
12651
|
+
MethodVal({ lx, val, env, errCtx }) {
|
|
12652
|
+
const { fields, proto } = env;
|
|
12655
12653
|
const { name } = val;
|
|
12656
|
-
if (proto[name]
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
}
|
|
12660
|
-
|
|
12661
|
-
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
if (scope.
|
|
12672
|
-
lx
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
if (
|
|
12676
|
-
lx
|
|
12677
|
-
|
|
12678
|
-
|
|
12654
|
+
if (proto[name] !== undefined)
|
|
12655
|
+
return;
|
|
12656
|
+
if (fields[name] !== undefined)
|
|
12657
|
+
lx.error(METHOD_VAL_IS_FIELD, { ...errCtx, val, name }, fixTo(`$${name}`, `.${name}`));
|
|
12658
|
+
else
|
|
12659
|
+
reportUnknownName(lx, METHOD_VAL_NOT_DEFINED, name, collectProtoMethodNames(proto), {
|
|
12660
|
+
...errCtx,
|
|
12661
|
+
val
|
|
12662
|
+
});
|
|
12663
|
+
},
|
|
12664
|
+
SeqAccessVal({ val, recurse }) {
|
|
12665
|
+
recurse(val.seqVal);
|
|
12666
|
+
recurse(val.keyVal);
|
|
12667
|
+
},
|
|
12668
|
+
RequestVal({ lx, val, env, errCtx }) {
|
|
12669
|
+
if (env.scope.lookupRequest(val.name) === null)
|
|
12670
|
+
reportUnknownName(lx, UNKNOWN_REQUEST_NAME, val.name, scopeKeysAlong(env.scope, "reqsByName"), errCtx);
|
|
12671
|
+
},
|
|
12672
|
+
TypeVal({ lx, val, env, errCtx }) {
|
|
12673
|
+
if (env.scope.lookupComponent(val.name) === null)
|
|
12674
|
+
reportUnknownName(lx, UNKNOWN_COMPONENT_NAME, val.name, scopeKeysAlong(env.scope, "byName"), errCtx);
|
|
12675
|
+
},
|
|
12676
|
+
NameVal({ lx, val, errCtx, skipNameVal }) {
|
|
12677
|
+
if (!skipNameVal && !isKnownHandlerName(val.name))
|
|
12678
|
+
reportUnknownName(lx, UNKNOWN_HANDLER_ARG_NAME, val.name, KNOWN_HANDLER_NAMES, errCtx);
|
|
12679
|
+
},
|
|
12680
|
+
StrTplVal({ lx, val, errCtx, recurse }) {
|
|
12679
12681
|
const vs = val.vals;
|
|
12680
12682
|
const literal = val.toLiteralSource();
|
|
12681
12683
|
if (literal !== null) {
|
|
12682
|
-
lx.hint(PLACEHOLDERLESS_TEMPLATE_STRING, { ...errCtx, literal },
|
|
12684
|
+
lx.hint(PLACEHOLDERLESS_TEMPLATE_STRING, { ...errCtx, literal }, fixTo(`$${literal}`, literal));
|
|
12683
12685
|
} else if (vs.length === 1) {
|
|
12684
12686
|
const simpler = String(vs[0]);
|
|
12685
|
-
lx.warn(REDUNDANT_TEMPLATE_STRING, { ...errCtx, simpler },
|
|
12687
|
+
lx.warn(REDUNDANT_TEMPLATE_STRING, { ...errCtx, simpler }, fixTo(`$'{${simpler}}'`, simpler));
|
|
12686
12688
|
}
|
|
12687
|
-
for (const subVal of vs)
|
|
12688
|
-
|
|
12689
|
-
|
|
12690
|
-
|
|
12689
|
+
for (const subVal of vs)
|
|
12690
|
+
recurse(subVal);
|
|
12691
|
+
},
|
|
12692
|
+
HandlerNameVal({ lx, val, env, errCtx }) {
|
|
12691
12693
|
env.referencedAlters?.add(val.name);
|
|
12692
|
-
if (alter[val.name] === undefined)
|
|
12693
|
-
lx
|
|
12694
|
-
|
|
12695
|
-
|
|
12694
|
+
if (env.alter[val.name] === undefined)
|
|
12695
|
+
reportUnknownName(lx, ALT_HANDLER_NOT_DEFINED, val.name, Object.keys(env.alter), errCtx);
|
|
12696
|
+
},
|
|
12697
|
+
PredicateVal({ val, recurse }) {
|
|
12696
12698
|
for (const arg of val.args)
|
|
12697
|
-
|
|
12698
|
-
}
|
|
12699
|
+
recurse(arg);
|
|
12700
|
+
},
|
|
12701
|
+
DynVal({ lx, val, env, errCtx }) {
|
|
12699
12702
|
env.referencedDynamics?.add(val.name);
|
|
12700
|
-
if (env.dynamicMap[val.name] === undefined)
|
|
12701
|
-
lx
|
|
12702
|
-
}
|
|
12703
|
-
} else if (valName !== "ConstVal" && valName !== "BindVal") {
|
|
12704
|
-
console.log(val);
|
|
12703
|
+
if (env.dynamicMap[val.name] === undefined)
|
|
12704
|
+
reportUnknownName(lx, DYN_VAL_NOT_DEFINED, val.name, Object.keys(env.dynamicMap), errCtx);
|
|
12705
12705
|
}
|
|
12706
|
+
};
|
|
12707
|
+
function checkConsistentAttrVal(lx, val, env, skipNameVal = false, errCtx = null) {
|
|
12708
|
+
const check = ATTR_VAL_CHECKERS[val?.constructor.name];
|
|
12709
|
+
if (check === undefined)
|
|
12710
|
+
return;
|
|
12711
|
+
const recurse = (sub) => checkConsistentAttrVal(lx, sub, env, skipNameVal, errCtx);
|
|
12712
|
+
check({ lx, val, env, errCtx, skipNameVal, recurse });
|
|
12706
12713
|
}
|
|
12707
12714
|
var NODE_KIND_TO_CTX = {
|
|
12708
12715
|
RenderTextNode: { originAttr: "<x text>" },
|