tutuca 0.9.97 → 0.9.98
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 +190 -59
- package/dist/tutuca-dev.ext.js +76 -29
- package/dist/tutuca-dev.js +76 -29
- package/dist/tutuca-dev.min.js +2 -2
- package/dist/tutuca-extra.ext.js +56 -28
- package/dist/tutuca-extra.js +56 -28
- package/dist/tutuca-extra.min.js +2 -2
- package/dist/tutuca-storybook.js +11 -4
- package/dist/tutuca.ext.js +56 -28
- package/dist/tutuca.js +56 -28
- package/dist/tutuca.min.js +2 -2
- package/package.json +3 -3
- package/skill/tutuca/advanced.md +14 -5
- package/skill/tutuca/core.md +78 -15
- package/skill/tutuca/margaui.md +25 -13
- package/skill/tutuca/patterns/README.md +1 -0
- package/skill/tutuca/patterns/filter-a-list.md +3 -1
- package/skill/tutuca/patterns/filter-and-paginate.md +116 -0
- package/skill/tutuca/patterns/paginate-a-list.md +3 -1
- package/skill/tutuca/storybook.md +7 -2
- package/skill/tutuca/testing.md +11 -0
- package/skill/tutuca-source/tutuca.ext.js +56 -28
package/dist/tutuca-extra.ext.js
CHANGED
|
@@ -1744,37 +1744,47 @@ class Renderer {
|
|
|
1744
1744
|
renderEach(stack, iterInfo, node, viewName) {
|
|
1745
1745
|
const { seq, filter, loopWith } = iterInfo.eval(stack);
|
|
1746
1746
|
const r = [];
|
|
1747
|
-
const { iterData, start, end } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1747
|
+
const { iterData, start, end, keys } = unpackLoopResult(loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)), seq);
|
|
1748
|
+
const renderOne = (key, value, attrName) => {
|
|
1749
|
+
const dom = this.renderIt(stack.enter(value, { key }, true), node, key, viewName);
|
|
1750
|
+
this.pushEachEntry(r, node.nodeId, attrName, key, dom);
|
|
1751
|
+
};
|
|
1752
|
+
if (keys)
|
|
1753
|
+
imKeysIter(seq, renderOne, keys);
|
|
1754
|
+
else
|
|
1755
|
+
getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
1756
|
+
if (filter.call(stack.it, key, value, iterData))
|
|
1757
|
+
renderOne(key, value, attrName);
|
|
1758
|
+
}, start, end);
|
|
1754
1759
|
return r;
|
|
1755
1760
|
}
|
|
1756
1761
|
renderEachWhen(stack, iterInfo, view, nid) {
|
|
1757
1762
|
const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
|
|
1758
1763
|
const r = [];
|
|
1759
1764
|
const it = stack.it;
|
|
1760
|
-
const { iterData, start, end } = unpackLoopResult(loopWith.call(it, seq), seq);
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
this.cache.set(cachePath, cacheKey, dom);
|
|
1775
|
-
}
|
|
1765
|
+
const { iterData, start, end, keys } = unpackLoopResult(loopWith.call(it, seq, makeLoopCtx(stack, filter)), seq);
|
|
1766
|
+
const renderOne = (key, value, attrName) => {
|
|
1767
|
+
const cachePath = enricher ? [view, it, value] : [view, value];
|
|
1768
|
+
const binds = { key, value };
|
|
1769
|
+
const cacheKey = `${nid}-${key}`;
|
|
1770
|
+
if (enricher)
|
|
1771
|
+
enricher.call(it, binds, key, value, iterData);
|
|
1772
|
+
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
1773
|
+
if (cachedNode)
|
|
1774
|
+
this.pushEachEntry(r, nid, attrName, key, cachedNode);
|
|
1775
|
+
else {
|
|
1776
|
+
const dom = this.renderView(view, stack.enter(value, binds, false));
|
|
1777
|
+
this.pushEachEntry(r, nid, attrName, key, dom);
|
|
1778
|
+
this.cache.set(cachePath, cacheKey, dom);
|
|
1776
1779
|
}
|
|
1777
|
-
}
|
|
1780
|
+
};
|
|
1781
|
+
if (keys)
|
|
1782
|
+
imKeysIter(seq, renderOne, keys);
|
|
1783
|
+
else
|
|
1784
|
+
getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
1785
|
+
if (filter.call(it, key, value, iterData))
|
|
1786
|
+
renderOne(key, value, attrName);
|
|
1787
|
+
}, start, end);
|
|
1778
1788
|
return r;
|
|
1779
1789
|
}
|
|
1780
1790
|
renderView(view, stack) {
|
|
@@ -1810,8 +1820,17 @@ var filterAlwaysTrue = (_v, _k, _seq) => true;
|
|
|
1810
1820
|
var nullLoopWith = (seq) => ({ iterData: { seq } });
|
|
1811
1821
|
var unpackLoopResult = (result, seq) => {
|
|
1812
1822
|
const r = result ?? {};
|
|
1813
|
-
return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end };
|
|
1823
|
+
return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end, keys: r.keys };
|
|
1824
|
+
};
|
|
1825
|
+
var imKeysIter = (seq, visit, keys) => {
|
|
1826
|
+
const attrName = isIndexed(seq) ? "si" : "sk";
|
|
1827
|
+
for (const key of keys)
|
|
1828
|
+
visit(key, seq.get(key), attrName);
|
|
1814
1829
|
};
|
|
1830
|
+
var makeLoopCtx = (stack, filter) => ({
|
|
1831
|
+
lookup: (name) => stack.lookupBind(name),
|
|
1832
|
+
filter: (key, value, iterData) => filter.call(stack.it, key, value, iterData)
|
|
1833
|
+
});
|
|
1815
1834
|
var imIndexedIter = (seq, visit, start, end) => {
|
|
1816
1835
|
const [s, e] = normalizeRange(start, end, seq.size);
|
|
1817
1836
|
for (let i = s;i < e; i++)
|
|
@@ -2359,11 +2378,11 @@ class IterInfo {
|
|
|
2359
2378
|
return { seq, filter, loopWith, enricher };
|
|
2360
2379
|
}
|
|
2361
2380
|
enrichBinds(stack, key) {
|
|
2362
|
-
const { seq, loopWith, enricher } = this.eval(stack);
|
|
2381
|
+
const { seq, filter, loopWith, enricher } = this.eval(stack);
|
|
2363
2382
|
const value = seq?.get ? seq.get(key, null) : null;
|
|
2364
2383
|
const binds = { key, value };
|
|
2365
2384
|
if (enricher) {
|
|
2366
|
-
const { iterData } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
|
|
2385
|
+
const { iterData } = unpackLoopResult(loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)), seq);
|
|
2367
2386
|
enricher.call(stack.it, binds, key, value, iterData);
|
|
2368
2387
|
}
|
|
2369
2388
|
return binds;
|
|
@@ -3783,6 +3802,13 @@ function phaseOps(phase) {
|
|
|
3783
3802
|
function resolveArgs(args, self) {
|
|
3784
3803
|
return typeof args === "function" ? args(self) ?? [] : args ?? [];
|
|
3785
3804
|
}
|
|
3805
|
+
function phaseHasBubble(phase) {
|
|
3806
|
+
if (!phase)
|
|
3807
|
+
return false;
|
|
3808
|
+
if (phase.bubble?.length)
|
|
3809
|
+
return true;
|
|
3810
|
+
return (phase.do ?? []).some((op) => op.type === "bubble");
|
|
3811
|
+
}
|
|
3786
3812
|
function dispatchPhase(dispatcher, targetPath, phase, self) {
|
|
3787
3813
|
if (!phase)
|
|
3788
3814
|
return;
|
|
@@ -4076,7 +4102,8 @@ class FieldSet extends Field {
|
|
|
4076
4102
|
}
|
|
4077
4103
|
function mkCompField(field, scope, args) {
|
|
4078
4104
|
const Comp = scope?.lookupComponent(field.type) ?? null;
|
|
4079
|
-
|
|
4105
|
+
if (Comp === null)
|
|
4106
|
+
console.warn(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)`);
|
|
4080
4107
|
return Comp?.make({ ...field.args, ...args }, { scope }) ?? null;
|
|
4081
4108
|
}
|
|
4082
4109
|
|
|
@@ -4239,6 +4266,7 @@ export {
|
|
|
4239
4266
|
removeIn,
|
|
4240
4267
|
remove,
|
|
4241
4268
|
phaseOps,
|
|
4269
|
+
phaseHasBubble,
|
|
4242
4270
|
mergeWith,
|
|
4243
4271
|
mergeDeepWith,
|
|
4244
4272
|
mergeDeep,
|
package/dist/tutuca-extra.js
CHANGED
|
@@ -6114,37 +6114,47 @@ class Renderer {
|
|
|
6114
6114
|
renderEach(stack, iterInfo, node, viewName) {
|
|
6115
6115
|
const { seq, filter, loopWith } = iterInfo.eval(stack);
|
|
6116
6116
|
const r = [];
|
|
6117
|
-
const { iterData, start, end } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
|
|
6118
|
-
|
|
6119
|
-
|
|
6120
|
-
|
|
6121
|
-
|
|
6122
|
-
|
|
6123
|
-
|
|
6117
|
+
const { iterData, start, end, keys } = unpackLoopResult(loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)), seq);
|
|
6118
|
+
const renderOne = (key, value, attrName) => {
|
|
6119
|
+
const dom = this.renderIt(stack.enter(value, { key }, true), node, key, viewName);
|
|
6120
|
+
this.pushEachEntry(r, node.nodeId, attrName, key, dom);
|
|
6121
|
+
};
|
|
6122
|
+
if (keys)
|
|
6123
|
+
imKeysIter(seq, renderOne, keys);
|
|
6124
|
+
else
|
|
6125
|
+
getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
6126
|
+
if (filter.call(stack.it, key, value, iterData))
|
|
6127
|
+
renderOne(key, value, attrName);
|
|
6128
|
+
}, start, end);
|
|
6124
6129
|
return r;
|
|
6125
6130
|
}
|
|
6126
6131
|
renderEachWhen(stack, iterInfo, view, nid) {
|
|
6127
6132
|
const { seq, filter, loopWith, enricher } = iterInfo.eval(stack);
|
|
6128
6133
|
const r = [];
|
|
6129
6134
|
const it = stack.it;
|
|
6130
|
-
const { iterData, start, end } = unpackLoopResult(loopWith.call(it, seq), seq);
|
|
6131
|
-
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
this.cache.set(cachePath, cacheKey, dom);
|
|
6145
|
-
}
|
|
6135
|
+
const { iterData, start, end, keys } = unpackLoopResult(loopWith.call(it, seq, makeLoopCtx(stack, filter)), seq);
|
|
6136
|
+
const renderOne = (key, value, attrName) => {
|
|
6137
|
+
const cachePath = enricher ? [view, it, value] : [view, value];
|
|
6138
|
+
const binds = { key, value };
|
|
6139
|
+
const cacheKey = `${nid}-${key}`;
|
|
6140
|
+
if (enricher)
|
|
6141
|
+
enricher.call(it, binds, key, value, iterData);
|
|
6142
|
+
const cachedNode = this.cache.get(cachePath, cacheKey);
|
|
6143
|
+
if (cachedNode)
|
|
6144
|
+
this.pushEachEntry(r, nid, attrName, key, cachedNode);
|
|
6145
|
+
else {
|
|
6146
|
+
const dom = this.renderView(view, stack.enter(value, binds, false));
|
|
6147
|
+
this.pushEachEntry(r, nid, attrName, key, dom);
|
|
6148
|
+
this.cache.set(cachePath, cacheKey, dom);
|
|
6146
6149
|
}
|
|
6147
|
-
}
|
|
6150
|
+
};
|
|
6151
|
+
if (keys)
|
|
6152
|
+
imKeysIter(seq, renderOne, keys);
|
|
6153
|
+
else
|
|
6154
|
+
getSeqInfo(seq)(seq, (key, value, attrName) => {
|
|
6155
|
+
if (filter.call(it, key, value, iterData))
|
|
6156
|
+
renderOne(key, value, attrName);
|
|
6157
|
+
}, start, end);
|
|
6148
6158
|
return r;
|
|
6149
6159
|
}
|
|
6150
6160
|
renderView(view, stack) {
|
|
@@ -6180,8 +6190,17 @@ var filterAlwaysTrue = (_v, _k, _seq) => true;
|
|
|
6180
6190
|
var nullLoopWith = (seq) => ({ iterData: { seq } });
|
|
6181
6191
|
var unpackLoopResult = (result, seq) => {
|
|
6182
6192
|
const r = result ?? {};
|
|
6183
|
-
return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end };
|
|
6193
|
+
return { iterData: r.iterData ?? { seq }, start: r.start, end: r.end, keys: r.keys };
|
|
6184
6194
|
};
|
|
6195
|
+
var imKeysIter = (seq, visit, keys) => {
|
|
6196
|
+
const attrName = isIndexed(seq) ? "si" : "sk";
|
|
6197
|
+
for (const key of keys)
|
|
6198
|
+
visit(key, seq.get(key), attrName);
|
|
6199
|
+
};
|
|
6200
|
+
var makeLoopCtx = (stack, filter) => ({
|
|
6201
|
+
lookup: (name) => stack.lookupBind(name),
|
|
6202
|
+
filter: (key, value, iterData) => filter.call(stack.it, key, value, iterData)
|
|
6203
|
+
});
|
|
6185
6204
|
var imIndexedIter = (seq, visit, start, end) => {
|
|
6186
6205
|
const [s, e] = normalizeRange(start, end, seq.size);
|
|
6187
6206
|
for (let i = s;i < e; i++)
|
|
@@ -6729,11 +6748,11 @@ class IterInfo {
|
|
|
6729
6748
|
return { seq, filter, loopWith, enricher };
|
|
6730
6749
|
}
|
|
6731
6750
|
enrichBinds(stack, key) {
|
|
6732
|
-
const { seq, loopWith, enricher } = this.eval(stack);
|
|
6751
|
+
const { seq, filter, loopWith, enricher } = this.eval(stack);
|
|
6733
6752
|
const value = seq?.get ? seq.get(key, null) : null;
|
|
6734
6753
|
const binds = { key, value };
|
|
6735
6754
|
if (enricher) {
|
|
6736
|
-
const { iterData } = unpackLoopResult(loopWith.call(stack.it, seq), seq);
|
|
6755
|
+
const { iterData } = unpackLoopResult(loopWith.call(stack.it, seq, makeLoopCtx(stack, filter)), seq);
|
|
6737
6756
|
enricher.call(stack.it, binds, key, value, iterData);
|
|
6738
6757
|
}
|
|
6739
6758
|
return binds;
|
|
@@ -8097,6 +8116,13 @@ function phaseOps(phase) {
|
|
|
8097
8116
|
function resolveArgs(args, self) {
|
|
8098
8117
|
return typeof args === "function" ? args(self) ?? [] : args ?? [];
|
|
8099
8118
|
}
|
|
8119
|
+
function phaseHasBubble(phase) {
|
|
8120
|
+
if (!phase)
|
|
8121
|
+
return false;
|
|
8122
|
+
if (phase.bubble?.length)
|
|
8123
|
+
return true;
|
|
8124
|
+
return (phase.do ?? []).some((op) => op.type === "bubble");
|
|
8125
|
+
}
|
|
8100
8126
|
function dispatchPhase(dispatcher, targetPath, phase, self) {
|
|
8101
8127
|
if (!phase)
|
|
8102
8128
|
return;
|
|
@@ -8389,7 +8415,8 @@ class FieldSet extends Field {
|
|
|
8389
8415
|
}
|
|
8390
8416
|
function mkCompField(field, scope, args) {
|
|
8391
8417
|
const Comp = scope?.lookupComponent(field.type) ?? null;
|
|
8392
|
-
|
|
8418
|
+
if (Comp === null)
|
|
8419
|
+
console.warn(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)`);
|
|
8393
8420
|
return Comp?.make({ ...field.args, ...args }, { scope }) ?? null;
|
|
8394
8421
|
}
|
|
8395
8422
|
|
|
@@ -8552,6 +8579,7 @@ export {
|
|
|
8552
8579
|
removeIn,
|
|
8553
8580
|
remove,
|
|
8554
8581
|
phaseOps,
|
|
8582
|
+
phaseHasBubble,
|
|
8555
8583
|
mergeWith$1 as mergeWith,
|
|
8556
8584
|
mergeDeepWith$1 as mergeDeepWith,
|
|
8557
8585
|
mergeDeep$1 as mergeDeep,
|