thurview 0.17.0 → 0.17.2
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/cli.js +7 -3
- package/dist/cli.js.map +1 -1
- package/dist/presence.js +37 -7
- package/dist/presence.js.map +1 -1
- package/dist/ui/app.css +18 -1
- package/dist/ui/app.js +72 -26
- package/dist/ui/app.js.map +3 -3
- package/package.json +1 -1
- package/skills/thurview/SKILL.md +3 -2
- package/skills/thurview/references/components.md +45 -0
- package/skills/thurview/references/document-authoring.md +7 -11
- package/skills/thurview/references/lifecycle.md +7 -4
- package/skills/thurview-design/SKILL.md +24 -3
package/dist/ui/app.js
CHANGED
|
@@ -980,13 +980,48 @@
|
|
|
980
980
|
if (a) openAnchorPeek(a);
|
|
981
981
|
}
|
|
982
982
|
function sequenceDiagram(b) {
|
|
983
|
-
const
|
|
984
|
-
const
|
|
985
|
-
const
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
983
|
+
const charW = 12 * 0.605;
|
|
984
|
+
const lineH = 15;
|
|
985
|
+
const wrap = (text, room) => {
|
|
986
|
+
const max = Math.max(8, Math.floor(room / charW));
|
|
987
|
+
const lines = [];
|
|
988
|
+
for (const word of text.split(" ")) {
|
|
989
|
+
const last = lines.length - 1;
|
|
990
|
+
if (last >= 0 && lines[last].length + 1 + word.length <= max) lines[last] += ` ${word}`;
|
|
991
|
+
else lines.push(word);
|
|
992
|
+
}
|
|
993
|
+
return lines;
|
|
994
|
+
};
|
|
995
|
+
const widest = (lines) => Math.max(...lines.map((l) => l.length)) * charW;
|
|
996
|
+
const names = b.actors.map((a) => wrap(a.label, 20 * charW));
|
|
997
|
+
const nameLines = Math.max(...names.map((l) => l.length));
|
|
998
|
+
const boxH2 = 13 + nameLines * lineH;
|
|
999
|
+
const top = 6 + boxH2 + 10;
|
|
1000
|
+
const boxes = names.map((l) => Math.max(120, widest(l) + 20));
|
|
1001
|
+
const cols = boxes.map((w) => Math.max(150, w + 16));
|
|
1002
|
+
const centres = cols.map((w, i) => cols.slice(0, i).reduce((s, c) => s + c, 0) + w / 2);
|
|
1003
|
+
const x = (id) => centres[b.actors.findIndex((a) => a.id === id)];
|
|
1004
|
+
let y = top;
|
|
1005
|
+
const rows = b.messages.map((m2, i) => {
|
|
1006
|
+
const x1 = x(m2.from);
|
|
1007
|
+
const x2 = x(m2.to);
|
|
1008
|
+
const self = x1 === x2;
|
|
1009
|
+
const start = self ? x1 + 36 : Math.min(x1, x2) + 8;
|
|
1010
|
+
const lines = wrap(`${i + 1}. ${m2.label}`, Math.max(180, Math.abs(x2 - x1) - 16));
|
|
1011
|
+
y += 20 + lines.length * lineH;
|
|
1012
|
+
return { x1, x2, self, start, lines, y, end: start + widest(lines) };
|
|
1013
|
+
});
|
|
1014
|
+
const width = Math.ceil(
|
|
1015
|
+
Math.max(
|
|
1016
|
+
320,
|
|
1017
|
+
cols.reduce((s, c) => s + c, 0),
|
|
1018
|
+
...rows.map((r) => r.end + 12)
|
|
1019
|
+
)
|
|
1020
|
+
);
|
|
1021
|
+
const height = y + 24;
|
|
989
1022
|
const el = svg("svg", { viewBox: `0 0 ${width} ${height}`, class: "seq" });
|
|
1023
|
+
el.style.maxWidth = `${width}px`;
|
|
1024
|
+
el.style.minWidth = `${Math.ceil(width * 0.9)}px`;
|
|
990
1025
|
el.appendChild(
|
|
991
1026
|
svg(
|
|
992
1027
|
"defs",
|
|
@@ -1006,39 +1041,35 @@
|
|
|
1006
1041
|
)
|
|
1007
1042
|
)
|
|
1008
1043
|
);
|
|
1009
|
-
const
|
|
1010
|
-
b.actors.forEach((
|
|
1011
|
-
const cx = i
|
|
1044
|
+
const tspans = (at, baseline, text) => text.map((l, i) => svg("tspan", { x: at, y: baseline - (text.length - 1 - i) * lineH }, l));
|
|
1045
|
+
b.actors.forEach((_, i) => {
|
|
1046
|
+
const cx = centres[i];
|
|
1047
|
+
const w = boxes[i];
|
|
1048
|
+
const name = names[i];
|
|
1012
1049
|
const g = svg("g", { class: "actor" });
|
|
1013
|
-
g.appendChild(svg("rect", { x: cx -
|
|
1014
|
-
|
|
1015
|
-
g.appendChild(svg("
|
|
1050
|
+
g.appendChild(svg("rect", { x: cx - w / 2, y: 6, width: w, height: boxH2, rx: 6 }));
|
|
1051
|
+
const baseline = 6 + (boxH2 + name.length * lineH) / 2 - 4;
|
|
1052
|
+
g.appendChild(svg("text", { "text-anchor": "middle" }, ...tspans(cx, baseline, name)));
|
|
1053
|
+
g.appendChild(svg("line", { class: "life", x1: cx, y1: 6 + boxH2, x2: cx, y2: height - 6 }));
|
|
1016
1054
|
el.appendChild(g);
|
|
1017
1055
|
});
|
|
1018
1056
|
b.messages.forEach((m2, i) => {
|
|
1019
|
-
const
|
|
1020
|
-
const x1 = x(m2.from);
|
|
1021
|
-
const x2 = x(m2.to);
|
|
1057
|
+
const { x1, x2, self, start, y: y2 } = rows[i];
|
|
1022
1058
|
const g = svg("g", { class: "msg" });
|
|
1023
|
-
const self = x1 === x2;
|
|
1024
1059
|
if (self) {
|
|
1025
1060
|
g.appendChild(
|
|
1026
1061
|
svg("path", {
|
|
1027
|
-
d: `M${x1},${
|
|
1062
|
+
d: `M${x1},${y2 - 10} h30 v20 h-30`,
|
|
1028
1063
|
fill: "none",
|
|
1029
1064
|
stroke: "currentColor",
|
|
1030
1065
|
"marker-end": "url(#arr)"
|
|
1031
1066
|
})
|
|
1032
1067
|
);
|
|
1033
1068
|
} else {
|
|
1034
|
-
g.appendChild(svg("line", { x1, y1:
|
|
1069
|
+
g.appendChild(svg("line", { x1, y1: y2, x2: x2 + (x2 > x1 ? -4 : 4), y2 }));
|
|
1035
1070
|
}
|
|
1036
|
-
const label2 = svg(
|
|
1037
|
-
|
|
1038
|
-
{ x: self ? x1 + 36 : (x1 + x2) / 2, y: y - 6, "text-anchor": self ? "start" : "middle" },
|
|
1039
|
-
`${i + 1}. ${m2.label}`
|
|
1040
|
-
);
|
|
1041
|
-
label2.addEventListener("click", (e) => {
|
|
1071
|
+
const label2 = svg("text", {}, ...tspans(start, y2 - 6, rows[i].lines));
|
|
1072
|
+
const open = (at) => {
|
|
1042
1073
|
if (m2.anchor) openAnchor(m2.anchor);
|
|
1043
1074
|
else if (m2.code)
|
|
1044
1075
|
popover(
|
|
@@ -1047,13 +1078,28 @@
|
|
|
1047
1078
|
{ class: "def-popover" },
|
|
1048
1079
|
h("pre", { style: { margin: "0", border: "none" } }, m2.code.text)
|
|
1049
1080
|
),
|
|
1050
|
-
|
|
1081
|
+
at
|
|
1051
1082
|
);
|
|
1083
|
+
};
|
|
1084
|
+
label2.addEventListener("click", (e) => open({ x: e.pageX, y: e.pageY + 8 }));
|
|
1085
|
+
label2.setAttribute("role", "button");
|
|
1086
|
+
label2.setAttribute("tabindex", "0");
|
|
1087
|
+
label2.addEventListener("keydown", (e) => {
|
|
1088
|
+
const k = e.key;
|
|
1089
|
+
if (k !== "Enter" && k !== " ") return;
|
|
1090
|
+
e.preventDefault();
|
|
1091
|
+
const r = label2.getBoundingClientRect();
|
|
1092
|
+
open({ x: r.left + window.scrollX, y: r.bottom + window.scrollY + 8 });
|
|
1052
1093
|
});
|
|
1053
1094
|
g.appendChild(label2);
|
|
1054
1095
|
el.appendChild(g);
|
|
1055
1096
|
});
|
|
1056
|
-
return h(
|
|
1097
|
+
return h(
|
|
1098
|
+
"div",
|
|
1099
|
+
{ class: "diagram" },
|
|
1100
|
+
h("div", { class: "dhead" }, b.label),
|
|
1101
|
+
h("div", { class: "seq-scroll" }, el)
|
|
1102
|
+
);
|
|
1057
1103
|
}
|
|
1058
1104
|
function callstackDiff(b, doc) {
|
|
1059
1105
|
const rows = b.rows.map((r, i) => {
|