tutuca 0.9.106 → 0.9.108
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 +355 -140
- package/dist/tutuca-components.js +134 -8
- package/dist/tutuca-dev.ext.js +336 -135
- package/dist/tutuca-dev.js +336 -135
- package/dist/tutuca-dev.min.js +3 -3
- package/dist/tutuca-extra.ext.js +217 -120
- package/dist/tutuca-extra.js +217 -120
- package/dist/tutuca-extra.min.js +2 -2
- package/dist/tutuca-storybook.js +47 -6
- package/dist/tutuca.ext.js +217 -120
- package/dist/tutuca.js +217 -120
- package/dist/tutuca.min.js +2 -2
- package/package.json +1 -1
- package/skill/tutuca/core.md +10 -8
- package/skill/tutuca/iteration.md +3 -3
- package/skill/tutuca/patterns/filter-a-list.md +1 -1
- package/skill/tutuca/patterns/show-or-hide-content.md +1 -1
- package/skill/tutuca/request-response.md +3 -5
- package/skill/tutuca/semantics.md +1 -1
- package/skill/tutuca-source/tutuca.ext.js +217 -120
|
@@ -1343,8 +1343,8 @@ var SchemaViewer = component4({
|
|
|
1343
1343
|
@on.click="$toggleShowRaw"
|
|
1344
1344
|
@text="$toggleLabel"
|
|
1345
1345
|
></button>
|
|
1346
|
-
<x render=".value" hide=".showRaw"></x>
|
|
1347
|
-
<x render=".raw" show=".showRaw"></x>
|
|
1346
|
+
<x render=".value" @hide=".showRaw"></x>
|
|
1347
|
+
<x render=".raw" @show=".showRaw"></x>
|
|
1348
1348
|
</div>`
|
|
1349
1349
|
});
|
|
1350
1350
|
function hasObjectKeywords(schema) {
|
|
@@ -1402,6 +1402,12 @@ function getComponents4() {
|
|
|
1402
1402
|
];
|
|
1403
1403
|
}
|
|
1404
1404
|
|
|
1405
|
+
// src/components/tutuca/activity-inspector.js
|
|
1406
|
+
import { component as component9, html as html9 } from "tutuca";
|
|
1407
|
+
|
|
1408
|
+
// src/components/tutuca/instance-inspector.js
|
|
1409
|
+
import { component as component8, html as html8, isRecord } from "tutuca";
|
|
1410
|
+
|
|
1405
1411
|
// src/components/tutuca/component-inspector.js
|
|
1406
1412
|
import { component as component5, html as html5 } from "tutuca";
|
|
1407
1413
|
function introspectComponent(comp) {
|
|
@@ -1579,9 +1585,6 @@ function getComponents5() {
|
|
|
1579
1585
|
return [ComponentInspector, CompSection, CompField, CompName, CompView, ...getComponents2()];
|
|
1580
1586
|
}
|
|
1581
1587
|
|
|
1582
|
-
// src/components/tutuca/instance-inspector.js
|
|
1583
|
-
import { component as component8, html as html8, isRecord } from "tutuca";
|
|
1584
|
-
|
|
1585
1588
|
// src/components/tutuca/lint-inspector.js
|
|
1586
1589
|
import { component as component6, html as html6 } from "tutuca";
|
|
1587
1590
|
var tagDisplay = (tag) => tag ? String(tag).toLowerCase() : "";
|
|
@@ -1648,6 +1651,8 @@ function lintMessage(id, info = {}) {
|
|
|
1648
1651
|
return `Redundant template string — '{${info.simpler}}' should be just '${info.simpler}'${originSuffix(info)}`;
|
|
1649
1652
|
case "PLACEHOLDERLESS_TEMPLATE_STRING":
|
|
1650
1653
|
return `Template string has no dynamic parts — use the literal ${info.literal} instead${originSuffix(info)}`;
|
|
1654
|
+
case "CONSTANT_CONDITION":
|
|
1655
|
+
return `Constant condition ${info.literal} — reference a field ('.name') or method ('$name')${originSuffix(info)}`;
|
|
1651
1656
|
case "ASYNC_HANDLER":
|
|
1652
1657
|
return `Handler '${info.name}' in '${info.channel}' is async — handlers must be synchronous`;
|
|
1653
1658
|
case "UNKNOWN_COMPONENT_SPEC_KEY":
|
|
@@ -2235,6 +2240,120 @@ function getComponents8() {
|
|
|
2235
2240
|
});
|
|
2236
2241
|
}
|
|
2237
2242
|
|
|
2243
|
+
// src/components/tutuca/activity-inspector.js
|
|
2244
|
+
var ACTIVITY_CAP = 50;
|
|
2245
|
+
var ActivityEntry = component9({
|
|
2246
|
+
name: "ActivityEntry",
|
|
2247
|
+
fields: {
|
|
2248
|
+
kind: "",
|
|
2249
|
+
name: "",
|
|
2250
|
+
handlerName: "",
|
|
2251
|
+
matched: "",
|
|
2252
|
+
pathLabel: "",
|
|
2253
|
+
time: "",
|
|
2254
|
+
before: null,
|
|
2255
|
+
after: null,
|
|
2256
|
+
hasAfter: true
|
|
2257
|
+
},
|
|
2258
|
+
view: html9`<div
|
|
2259
|
+
class="rounded border border-base-content/15 p-2 text-sm flex flex-col gap-1"
|
|
2260
|
+
>
|
|
2261
|
+
<div class="flex items-center gap-2 flex-wrap">
|
|
2262
|
+
<span
|
|
2263
|
+
title="How this was dispatched: receive (send), bubble, response, input, or request"
|
|
2264
|
+
class="badge badge-sm badge-neutral"
|
|
2265
|
+
@text=".kind"
|
|
2266
|
+
></span>
|
|
2267
|
+
<span
|
|
2268
|
+
title="Message name dispatched — for a DOM input, the event type (click, input, change, keydown, …)"
|
|
2269
|
+
class="font-mono font-semibold"
|
|
2270
|
+
@text=".name"
|
|
2271
|
+
></span>
|
|
2272
|
+
<span
|
|
2273
|
+
title="Actual handler that ran — shown only when it differs from the name (e.g. a $unknown fallback)"
|
|
2274
|
+
class="text-xs opacity-60 font-mono"
|
|
2275
|
+
@show="truthy? .handlerName"
|
|
2276
|
+
@text=".handlerName"
|
|
2277
|
+
></span>
|
|
2278
|
+
<span
|
|
2279
|
+
title="Path to the target component"
|
|
2280
|
+
class="text-xs opacity-40 font-mono"
|
|
2281
|
+
@text=".pathLabel"
|
|
2282
|
+
></span>
|
|
2283
|
+
<span
|
|
2284
|
+
title="Handler resolution — exact: matched by name · unknown: $unknown fallback · none: no handler (no-op)"
|
|
2285
|
+
class="badge badge-xs badge-ghost"
|
|
2286
|
+
@show="truthy? .matched"
|
|
2287
|
+
@text=".matched"
|
|
2288
|
+
></span>
|
|
2289
|
+
<span
|
|
2290
|
+
title="Time this event ran (HH:MM:SS.mmm)"
|
|
2291
|
+
class="ml-auto text-xs opacity-40 font-mono tabular-nums"
|
|
2292
|
+
@text=".time"
|
|
2293
|
+
></span>
|
|
2294
|
+
</div>
|
|
2295
|
+
<div class="flex gap-3 items-start font-mono text-xs">
|
|
2296
|
+
<div class="flex-1 min-w-0">
|
|
2297
|
+
<div class="opacity-50" title="Target state before the handler ran">before</div>
|
|
2298
|
+
<x render=".before"></x>
|
|
2299
|
+
</div>
|
|
2300
|
+
<div class="flex-1 min-w-0" @show=".hasAfter">
|
|
2301
|
+
<div class="opacity-50" title="Target state after the handler ran">after</div>
|
|
2302
|
+
<x render=".after"></x>
|
|
2303
|
+
</div>
|
|
2304
|
+
</div>
|
|
2305
|
+
</div>`
|
|
2306
|
+
});
|
|
2307
|
+
var ActivityLog = component9({
|
|
2308
|
+
name: "ActivityLog",
|
|
2309
|
+
fields: { events: [], hasEvents: false },
|
|
2310
|
+
methods: {
|
|
2311
|
+
appendEntry(entry) {
|
|
2312
|
+
return this.setEvents(this.events.unshift(entry).slice(0, ACTIVITY_CAP)).setHasEvents(true);
|
|
2313
|
+
}
|
|
2314
|
+
},
|
|
2315
|
+
view: html9`<div class="p-3 flex flex-col gap-2 max-h-[60vh] overflow-y-auto">
|
|
2316
|
+
<div class="text-xs opacity-40" @hide=".hasEvents">
|
|
2317
|
+
No activity yet — interact with the component.
|
|
2318
|
+
</div>
|
|
2319
|
+
<x render-each=".events"></x>
|
|
2320
|
+
</div>`
|
|
2321
|
+
});
|
|
2322
|
+
function fmtActivityTime(ts) {
|
|
2323
|
+
const d = new Date(ts);
|
|
2324
|
+
const p = (n, w = 2) => String(n).padStart(w, "0");
|
|
2325
|
+
return `${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}.${p(d.getMilliseconds(), 3)}`;
|
|
2326
|
+
}
|
|
2327
|
+
function pathKeysLabel(pathKeys) {
|
|
2328
|
+
return pathKeys.map((k) => k.key === undefined ? k.field : `${k.field}[${k.key}]`).join(".");
|
|
2329
|
+
}
|
|
2330
|
+
function makeInspect(app) {
|
|
2331
|
+
return (value) => {
|
|
2332
|
+
const comp = isComponentInstance(value) ? app.comps.getCompFor(value) : null;
|
|
2333
|
+
return InstanceInspector.Class.fromData(value, comp);
|
|
2334
|
+
};
|
|
2335
|
+
}
|
|
2336
|
+
function recordToEntry(record, { inspect, pathLabel = pathKeysLabel } = {}) {
|
|
2337
|
+
const hasAfter = record.after !== undefined;
|
|
2338
|
+
const primary = record.name ?? record.handlerName ?? "?";
|
|
2339
|
+
const handler = record.handlerName ?? "";
|
|
2340
|
+
const handlerLabel = handler && handler !== primary ? `→ ${handler}` : "";
|
|
2341
|
+
return ActivityEntry.make({
|
|
2342
|
+
kind: record.kind ?? "",
|
|
2343
|
+
name: primary,
|
|
2344
|
+
handlerName: handlerLabel,
|
|
2345
|
+
matched: record.matched ?? "",
|
|
2346
|
+
pathLabel: pathLabel(record.pathKeys),
|
|
2347
|
+
time: fmtActivityTime(record.timestamp),
|
|
2348
|
+
before: inspect(record.before),
|
|
2349
|
+
after: hasAfter ? inspect(record.after) : null,
|
|
2350
|
+
hasAfter
|
|
2351
|
+
});
|
|
2352
|
+
}
|
|
2353
|
+
function getComponents9() {
|
|
2354
|
+
return [ActivityLog, ActivityEntry];
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2238
2357
|
// src/components/build-views.js
|
|
2239
2358
|
async function buildInspectorViews(value, scope, { getTests = null, components = [], dev = null, name } = {}) {
|
|
2240
2359
|
const comp = isComponentInstance(value) ? scope.getCompFor(value) : null;
|
|
@@ -2273,8 +2392,9 @@ async function buildInspectorViews(value, scope, { getTests = null, components =
|
|
|
2273
2392
|
}
|
|
2274
2393
|
|
|
2275
2394
|
// src/components/index.js
|
|
2276
|
-
function
|
|
2395
|
+
function getComponents10() {
|
|
2277
2396
|
const all = [
|
|
2397
|
+
...getComponents9(),
|
|
2278
2398
|
...getComponents5(),
|
|
2279
2399
|
...getComponents8(),
|
|
2280
2400
|
...getComponents6(),
|
|
@@ -2294,13 +2414,17 @@ function getComponents9() {
|
|
|
2294
2414
|
}
|
|
2295
2415
|
export {
|
|
2296
2416
|
valueWrapperMethods,
|
|
2417
|
+
recordToEntry,
|
|
2418
|
+
pathKeysLabel,
|
|
2297
2419
|
makeValueInspector,
|
|
2420
|
+
makeInspect,
|
|
2298
2421
|
makeCompositeView,
|
|
2299
2422
|
lintMessage,
|
|
2300
2423
|
isComponentInstance,
|
|
2301
2424
|
introspectComponent,
|
|
2302
|
-
|
|
2425
|
+
getComponents10 as getComponents,
|
|
2303
2426
|
fmtAnyKey,
|
|
2427
|
+
fmtActivityTime,
|
|
2304
2428
|
compositeView,
|
|
2305
2429
|
compositeMethods,
|
|
2306
2430
|
compositeFields,
|
|
@@ -2369,5 +2493,7 @@ export {
|
|
|
2369
2493
|
CompView,
|
|
2370
2494
|
CompSection,
|
|
2371
2495
|
CompName,
|
|
2372
|
-
CompField
|
|
2496
|
+
CompField,
|
|
2497
|
+
ActivityLog,
|
|
2498
|
+
ActivityEntry
|
|
2373
2499
|
};
|