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.ext.js
CHANGED
|
@@ -5264,16 +5264,16 @@ function parseXOpVal(opName, value, px, parserFn) {
|
|
|
5264
5264
|
return val;
|
|
5265
5265
|
}
|
|
5266
5266
|
function processXExtras(node, attrs, opName, startIdx, px) {
|
|
5267
|
-
const consumed =
|
|
5268
|
-
const wrappable = X_OP_WRAPPABLE.has(opName);
|
|
5267
|
+
const { consumed, wrappable } = X_OPS[opName];
|
|
5269
5268
|
const wrappers = [];
|
|
5270
5269
|
for (let i = startIdx;i < attrs.length; i++) {
|
|
5271
5270
|
const a = attrs[i];
|
|
5272
5271
|
const aName = a.name;
|
|
5273
5272
|
if (consumed.has(aName))
|
|
5274
5273
|
continue;
|
|
5275
|
-
|
|
5276
|
-
|
|
5274
|
+
const wrapper = wrappable ? X_OPS[aName]?.wrapper : null;
|
|
5275
|
+
if (wrapper) {
|
|
5276
|
+
wrappers.push([wrapper, vp.parseBool(a.value, px)]);
|
|
5277
5277
|
continue;
|
|
5278
5278
|
}
|
|
5279
5279
|
const issueInfo = { op: opName, name: aName, value: a.value };
|
|
@@ -5365,6 +5365,12 @@ class RenderViewId extends ANode {
|
|
|
5365
5365
|
}
|
|
5366
5366
|
setDataAttr(_key, _val) {}
|
|
5367
5367
|
}
|
|
5368
|
+
function dynRenderStep(comp, name, key) {
|
|
5369
|
+
const p = resolveDynProducer(comp, name);
|
|
5370
|
+
if (!p)
|
|
5371
|
+
return null;
|
|
5372
|
+
return key === undefined ? new DynStep(p.producerCompId, p.producerSteps) : new DynEachStep(p.producerCompId, p.producerSteps, key);
|
|
5373
|
+
}
|
|
5368
5374
|
|
|
5369
5375
|
class RenderNode extends RenderViewId {
|
|
5370
5376
|
render(stack, rx) {
|
|
@@ -5372,10 +5378,8 @@ class RenderNode extends RenderViewId {
|
|
|
5372
5378
|
return rx.renderIt(newStack, this, "", this.viewId);
|
|
5373
5379
|
}
|
|
5374
5380
|
toPathStep(ctx) {
|
|
5375
|
-
if (this.val instanceof DynVal)
|
|
5376
|
-
|
|
5377
|
-
return p ? new DynStep(p.producerCompId, p.producerSteps) : null;
|
|
5378
|
-
}
|
|
5381
|
+
if (this.val instanceof DynVal)
|
|
5382
|
+
return dynRenderStep(ctx.comp, this.val.name);
|
|
5379
5383
|
return super.toPathStep(ctx);
|
|
5380
5384
|
}
|
|
5381
5385
|
}
|
|
@@ -5391,10 +5395,8 @@ class RenderItNode extends RenderViewId {
|
|
|
5391
5395
|
return null;
|
|
5392
5396
|
const nextNode = next.resolveNode();
|
|
5393
5397
|
if (nextNode instanceof EachNode && next.hasKey) {
|
|
5394
|
-
if (nextNode.val instanceof DynVal)
|
|
5395
|
-
|
|
5396
|
-
return p ? new DynEachStep(p.producerCompId, p.producerSteps, next.key) : null;
|
|
5397
|
-
}
|
|
5398
|
+
if (nextNode.val instanceof DynVal)
|
|
5399
|
+
return dynRenderStep(ctx.comp, nextNode.val.name, next.key);
|
|
5398
5400
|
return new EachRenderItStep(nextNode.val.name, next.key);
|
|
5399
5401
|
}
|
|
5400
5402
|
return null;
|
|
@@ -5410,12 +5412,8 @@ class RenderEachNode extends RenderViewId {
|
|
|
5410
5412
|
return rx.renderEach(stack, this.iterInfo, this, this.viewId);
|
|
5411
5413
|
}
|
|
5412
5414
|
toPathStep(ctx) {
|
|
5413
|
-
if (this.val instanceof DynVal)
|
|
5414
|
-
|
|
5415
|
-
return null;
|
|
5416
|
-
const p = resolveDynProducer(ctx.comp, this.val.name);
|
|
5417
|
-
return p ? new DynEachStep(p.producerCompId, p.producerSteps, ctx.key) : null;
|
|
5418
|
-
}
|
|
5415
|
+
if (this.val instanceof DynVal)
|
|
5416
|
+
return ctx.hasKey ? dynRenderStep(ctx.comp, this.val.name, ctx.key) : null;
|
|
5419
5417
|
return super.toPathStep(ctx);
|
|
5420
5418
|
}
|
|
5421
5419
|
static parse(px, vp2, s, as, attrs) {
|
|
@@ -5545,17 +5543,18 @@ class IterInfo {
|
|
|
5545
5543
|
}
|
|
5546
5544
|
var filterAlwaysTrue = (_v, _k, _seq) => true;
|
|
5547
5545
|
var nullLoopWith = (seq) => ({ iterData: { seq } });
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
}
|
|
5557
|
-
|
|
5558
|
-
|
|
5546
|
+
function xOp(consumed = [], { wrappable = false, wrapper = null } = {}) {
|
|
5547
|
+
return { consumed: new Set(consumed), wrappable, wrapper };
|
|
5548
|
+
}
|
|
5549
|
+
var X_OPS = {
|
|
5550
|
+
slot: xOp(),
|
|
5551
|
+
text: xOp([], { wrappable: true }),
|
|
5552
|
+
render: xOp(["as"], { wrappable: true }),
|
|
5553
|
+
"render-it": xOp(["as"], { wrappable: true }),
|
|
5554
|
+
"render-each": xOp(["as", "when", "loop-with"], { wrappable: true }),
|
|
5555
|
+
show: xOp([], { wrapper: ShowNode }),
|
|
5556
|
+
hide: xOp([], { wrapper: HideNode })
|
|
5557
|
+
};
|
|
5559
5558
|
var WRAPPER_NODES = {
|
|
5560
5559
|
slot: SlotNode,
|
|
5561
5560
|
show: ShowNode,
|
|
@@ -5643,29 +5642,30 @@ var isBlockDomNode = (n) => {
|
|
|
5643
5642
|
const node = n instanceof FragmentNode ? n.childs[0] : n;
|
|
5644
5643
|
return node instanceof DomNode && HTML_BLOCK_TAGS.has(node.tagName);
|
|
5645
5644
|
};
|
|
5645
|
+
var isEmptyText = (c) => c instanceof TextNode && c.val === "";
|
|
5646
|
+
function trimEdgeWhite(node) {
|
|
5647
|
+
if (!node.isWhiteSpace?.())
|
|
5648
|
+
return false;
|
|
5649
|
+
node.condenseWhiteSpace();
|
|
5650
|
+
return true;
|
|
5651
|
+
}
|
|
5646
5652
|
function condenseChildsWhites(childs) {
|
|
5647
5653
|
if (childs.length === 0)
|
|
5648
5654
|
return childs;
|
|
5649
|
-
let changed = false;
|
|
5650
|
-
if (childs[0].isWhiteSpace?.()) {
|
|
5651
|
-
childs[0].condenseWhiteSpace();
|
|
5652
|
-
changed = true;
|
|
5653
|
-
}
|
|
5654
5655
|
const last = childs.length - 1;
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
}
|
|
5656
|
+
let emptied = trimEdgeWhite(childs[0]);
|
|
5657
|
+
if (last > 0 && trimEdgeWhite(childs[last]))
|
|
5658
|
+
emptied = true;
|
|
5659
5659
|
for (let i = 1;i < last; i++) {
|
|
5660
5660
|
const cur = childs[i];
|
|
5661
|
-
if (cur.isWhiteSpace?.() && cur.hasNewLine())
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
5661
|
+
if (!(cur.isWhiteSpace?.() && cur.hasNewLine()))
|
|
5662
|
+
continue;
|
|
5663
|
+
const bothBlock = isBlockDomNode(childs[i - 1]) && isBlockDomNode(childs[i + 1]);
|
|
5664
|
+
cur.condenseWhiteSpace(bothBlock ? "" : " ");
|
|
5665
|
+
if (bothBlock)
|
|
5666
|
+
emptied = true;
|
|
5667
5667
|
}
|
|
5668
|
-
return
|
|
5668
|
+
return emptied ? childs.filter((c) => !isEmptyText(c)) : childs;
|
|
5669
5669
|
}
|
|
5670
5670
|
|
|
5671
5671
|
class View {
|
|
@@ -8180,12 +8180,6 @@ var REDUNDANT_TEMPLATE_STRING = "REDUNDANT_TEMPLATE_STRING";
|
|
|
8180
8180
|
var PLACEHOLDERLESS_TEMPLATE_STRING = "PLACEHOLDERLESS_TEMPLATE_STRING";
|
|
8181
8181
|
var UNKNOWN_COMPONENT_SPEC_KEY = "UNKNOWN_COMPONENT_SPEC_KEY";
|
|
8182
8182
|
var COMP_FIELD_BAD_SHAPE = "COMP_FIELD_BAD_SHAPE";
|
|
8183
|
-
var PARSE_ISSUE_KIND_TO_LINT_ID = {
|
|
8184
|
-
"unknown-directive": UNKNOWN_DIRECTIVE,
|
|
8185
|
-
"unknown-x-op": UNKNOWN_X_OP,
|
|
8186
|
-
"unknown-x-attr": UNKNOWN_X_ATTR,
|
|
8187
|
-
"bad-value": BAD_VALUE
|
|
8188
|
-
};
|
|
8189
8183
|
var X_KNOWN_OP_NAMES = new Set([
|
|
8190
8184
|
"slot",
|
|
8191
8185
|
"text",
|
|
@@ -8196,17 +8190,18 @@ var X_KNOWN_OP_NAMES = new Set([
|
|
|
8196
8190
|
"hide"
|
|
8197
8191
|
]);
|
|
8198
8192
|
var X_KNOWN_ATTR_NAMES = new Set(["as", "when", "loop-with", "show", "hide"]);
|
|
8199
|
-
var AT_PREFIX_HINT_KNOWN_BY_KIND = {
|
|
8200
|
-
"unknown-x-op": X_KNOWN_OP_NAMES,
|
|
8201
|
-
"unknown-x-attr": X_KNOWN_ATTR_NAMES
|
|
8202
|
-
};
|
|
8203
8193
|
var LEVEL_WARN2 = "warn";
|
|
8204
8194
|
var LEVEL_ERROR2 = "error";
|
|
8205
8195
|
var LEVEL_HINT = "hint";
|
|
8206
|
-
var
|
|
8207
|
-
"unknown-directive": KNOWN_DIRECTIVE_NAMES,
|
|
8208
|
-
"unknown-x-op": X_KNOWN_OP_NAMES,
|
|
8209
|
-
"unknown-x-attr":
|
|
8196
|
+
var PARSE_ISSUES = {
|
|
8197
|
+
"unknown-directive": { id: UNKNOWN_DIRECTIVE, candidates: KNOWN_DIRECTIVE_NAMES },
|
|
8198
|
+
"unknown-x-op": { id: UNKNOWN_X_OP, candidates: X_KNOWN_OP_NAMES, atPrefix: X_KNOWN_OP_NAMES },
|
|
8199
|
+
"unknown-x-attr": {
|
|
8200
|
+
id: UNKNOWN_X_ATTR,
|
|
8201
|
+
candidates: X_KNOWN_ATTR_NAMES,
|
|
8202
|
+
atPrefix: X_KNOWN_ATTR_NAMES
|
|
8203
|
+
},
|
|
8204
|
+
"bad-value": { id: BAD_VALUE }
|
|
8210
8205
|
};
|
|
8211
8206
|
function collectProtoMethodNames(proto) {
|
|
8212
8207
|
const out = [];
|
|
@@ -8301,9 +8296,10 @@ function checkParseIssues(lx, view) {
|
|
|
8301
8296
|
if (!issues)
|
|
8302
8297
|
return;
|
|
8303
8298
|
for (const { kind, info } of issues) {
|
|
8304
|
-
const
|
|
8305
|
-
if (!
|
|
8299
|
+
const rule = PARSE_ISSUES[kind];
|
|
8300
|
+
if (!rule)
|
|
8306
8301
|
continue;
|
|
8302
|
+
const id = rule.id;
|
|
8307
8303
|
if (kind === "bad-value") {
|
|
8308
8304
|
const detected = classifyBadValue(info.value);
|
|
8309
8305
|
if (detected) {
|
|
@@ -8311,15 +8307,13 @@ function checkParseIssues(lx, view) {
|
|
|
8311
8307
|
continue;
|
|
8312
8308
|
}
|
|
8313
8309
|
}
|
|
8314
|
-
const atPrefixKnown =
|
|
8310
|
+
const atPrefixKnown = rule.atPrefix;
|
|
8315
8311
|
const isAtPrefixedTypo = atPrefixKnown && info.name?.startsWith("@") && atPrefixKnown.has(info.name.slice(1));
|
|
8316
8312
|
let suggestion = null;
|
|
8317
8313
|
if (isAtPrefixedTypo) {
|
|
8318
8314
|
suggestion = { kind: "drop-prefix", from: info.name, to: info.name.slice(1) };
|
|
8319
|
-
} else {
|
|
8320
|
-
|
|
8321
|
-
if (candidates)
|
|
8322
|
-
suggestion = replaceNameSuggestion(info.name, candidates);
|
|
8315
|
+
} else if (rule.candidates) {
|
|
8316
|
+
suggestion = replaceNameSuggestion(info.name, rule.candidates);
|
|
8323
8317
|
}
|
|
8324
8318
|
lx.error(id, info, suggestion);
|
|
8325
8319
|
if (isAtPrefixedTypo) {
|
|
@@ -8489,70 +8483,83 @@ function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
|
|
|
8489
8483
|
});
|
|
8490
8484
|
}
|
|
8491
8485
|
}
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
|
|
8495
|
-
|
|
8486
|
+
var fixTo = (from, to) => ({ kind: "rewrite", from, to });
|
|
8487
|
+
function reportUnknownName(lx, code, name, candidates, info) {
|
|
8488
|
+
lx.error(code, { ...info, name }, replaceNameSuggestion(name, candidates));
|
|
8489
|
+
}
|
|
8490
|
+
var ATTR_VAL_CHECKERS = {
|
|
8491
|
+
FieldVal({ lx, val, env, errCtx }) {
|
|
8492
|
+
const { fields, proto } = env;
|
|
8496
8493
|
const { name } = val;
|
|
8497
|
-
if (fields[name]
|
|
8498
|
-
|
|
8499
|
-
|
|
8500
|
-
}
|
|
8501
|
-
|
|
8502
|
-
}
|
|
8503
|
-
|
|
8504
|
-
|
|
8494
|
+
if (fields[name] !== undefined)
|
|
8495
|
+
return;
|
|
8496
|
+
if (proto[name] !== undefined)
|
|
8497
|
+
lx.error(FIELD_VAL_IS_METHOD, { ...errCtx, val, name }, fixTo(`.${name}`, `$${name}`));
|
|
8498
|
+
else
|
|
8499
|
+
reportUnknownName(lx, FIELD_VAL_NOT_DEFINED, name, Object.keys(fields), { ...errCtx, val });
|
|
8500
|
+
},
|
|
8501
|
+
MethodVal({ lx, val, env, errCtx }) {
|
|
8502
|
+
const { fields, proto } = env;
|
|
8505
8503
|
const { name } = val;
|
|
8506
|
-
if (proto[name]
|
|
8507
|
-
|
|
8508
|
-
|
|
8509
|
-
}
|
|
8510
|
-
|
|
8511
|
-
|
|
8512
|
-
|
|
8513
|
-
|
|
8514
|
-
|
|
8515
|
-
|
|
8516
|
-
|
|
8517
|
-
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
if (scope.
|
|
8522
|
-
lx
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
if (
|
|
8526
|
-
lx
|
|
8527
|
-
|
|
8528
|
-
|
|
8504
|
+
if (proto[name] !== undefined)
|
|
8505
|
+
return;
|
|
8506
|
+
if (fields[name] !== undefined)
|
|
8507
|
+
lx.error(METHOD_VAL_IS_FIELD, { ...errCtx, val, name }, fixTo(`$${name}`, `.${name}`));
|
|
8508
|
+
else
|
|
8509
|
+
reportUnknownName(lx, METHOD_VAL_NOT_DEFINED, name, collectProtoMethodNames(proto), {
|
|
8510
|
+
...errCtx,
|
|
8511
|
+
val
|
|
8512
|
+
});
|
|
8513
|
+
},
|
|
8514
|
+
SeqAccessVal({ val, recurse }) {
|
|
8515
|
+
recurse(val.seqVal);
|
|
8516
|
+
recurse(val.keyVal);
|
|
8517
|
+
},
|
|
8518
|
+
RequestVal({ lx, val, env, errCtx }) {
|
|
8519
|
+
if (env.scope.lookupRequest(val.name) === null)
|
|
8520
|
+
reportUnknownName(lx, UNKNOWN_REQUEST_NAME, val.name, scopeKeysAlong(env.scope, "reqsByName"), errCtx);
|
|
8521
|
+
},
|
|
8522
|
+
TypeVal({ lx, val, env, errCtx }) {
|
|
8523
|
+
if (env.scope.lookupComponent(val.name) === null)
|
|
8524
|
+
reportUnknownName(lx, UNKNOWN_COMPONENT_NAME, val.name, scopeKeysAlong(env.scope, "byName"), errCtx);
|
|
8525
|
+
},
|
|
8526
|
+
NameVal({ lx, val, errCtx, skipNameVal }) {
|
|
8527
|
+
if (!skipNameVal && !isKnownHandlerName(val.name))
|
|
8528
|
+
reportUnknownName(lx, UNKNOWN_HANDLER_ARG_NAME, val.name, KNOWN_HANDLER_NAMES, errCtx);
|
|
8529
|
+
},
|
|
8530
|
+
StrTplVal({ lx, val, errCtx, recurse }) {
|
|
8529
8531
|
const vs = val.vals;
|
|
8530
8532
|
const literal = val.toLiteralSource();
|
|
8531
8533
|
if (literal !== null) {
|
|
8532
|
-
lx.hint(PLACEHOLDERLESS_TEMPLATE_STRING, { ...errCtx, literal },
|
|
8534
|
+
lx.hint(PLACEHOLDERLESS_TEMPLATE_STRING, { ...errCtx, literal }, fixTo(`$${literal}`, literal));
|
|
8533
8535
|
} else if (vs.length === 1) {
|
|
8534
8536
|
const simpler = String(vs[0]);
|
|
8535
|
-
lx.warn(REDUNDANT_TEMPLATE_STRING, { ...errCtx, simpler },
|
|
8537
|
+
lx.warn(REDUNDANT_TEMPLATE_STRING, { ...errCtx, simpler }, fixTo(`$'{${simpler}}'`, simpler));
|
|
8536
8538
|
}
|
|
8537
|
-
for (const subVal of vs)
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
|
|
8539
|
+
for (const subVal of vs)
|
|
8540
|
+
recurse(subVal);
|
|
8541
|
+
},
|
|
8542
|
+
HandlerNameVal({ lx, val, env, errCtx }) {
|
|
8541
8543
|
env.referencedAlters?.add(val.name);
|
|
8542
|
-
if (alter[val.name] === undefined)
|
|
8543
|
-
lx
|
|
8544
|
-
|
|
8545
|
-
|
|
8544
|
+
if (env.alter[val.name] === undefined)
|
|
8545
|
+
reportUnknownName(lx, ALT_HANDLER_NOT_DEFINED, val.name, Object.keys(env.alter), errCtx);
|
|
8546
|
+
},
|
|
8547
|
+
PredicateVal({ val, recurse }) {
|
|
8546
8548
|
for (const arg of val.args)
|
|
8547
|
-
|
|
8548
|
-
}
|
|
8549
|
+
recurse(arg);
|
|
8550
|
+
},
|
|
8551
|
+
DynVal({ lx, val, env, errCtx }) {
|
|
8549
8552
|
env.referencedDynamics?.add(val.name);
|
|
8550
|
-
if (env.dynamicMap[val.name] === undefined)
|
|
8551
|
-
lx
|
|
8552
|
-
}
|
|
8553
|
-
} else if (valName !== "ConstVal" && valName !== "BindVal") {
|
|
8554
|
-
console.log(val);
|
|
8553
|
+
if (env.dynamicMap[val.name] === undefined)
|
|
8554
|
+
reportUnknownName(lx, DYN_VAL_NOT_DEFINED, val.name, Object.keys(env.dynamicMap), errCtx);
|
|
8555
8555
|
}
|
|
8556
|
+
};
|
|
8557
|
+
function checkConsistentAttrVal(lx, val, env, skipNameVal = false, errCtx = null) {
|
|
8558
|
+
const check = ATTR_VAL_CHECKERS[val?.constructor.name];
|
|
8559
|
+
if (check === undefined)
|
|
8560
|
+
return;
|
|
8561
|
+
const recurse = (sub) => checkConsistentAttrVal(lx, sub, env, skipNameVal, errCtx);
|
|
8562
|
+
check({ lx, val, env, errCtx, skipNameVal, recurse });
|
|
8556
8563
|
}
|
|
8557
8564
|
var NODE_KIND_TO_CTX = {
|
|
8558
8565
|
RenderTextNode: { originAttr: "<x text>" },
|