@theoremjs/studio 0.3.4-next.454.gaa3f549 → 0.3.4-next.458.gbf7b487
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/package.json +4 -4
- package/page/assets/{Banner-QCiHVb5K.js → Banner-C4MPbvft.js} +2 -2
- package/page/assets/{ConsoleFrame-DqN62wL7.js → ConsoleFrame-BkzieVRC.js} +1 -1
- package/page/assets/{ContextMenu-DIzJdlQ5.js → ContextMenu-BGP2gdee.js} +2 -2
- package/page/assets/{ToolResultCharts-CjuviquY.js → ToolResultCharts-xDwNDd-T.js} +1 -1
- package/page/assets/{TraceInspector-CwGSe8Oe.js → TraceInspector-CHpdhiVX.js} +1 -1
- package/page/assets/{TraceOverview-isg4ubrd.js → TraceOverview-DCGew7UN.js} +1 -1
- package/page/assets/{browser-engine-DA4ZywPN.js → browser-engine-Ca2pvYX0.js} +1 -1
- package/page/assets/{browser-transport-B0zaH_Aw.js → browser-transport-DYgEItHi.js} +3 -3
- package/page/assets/{export-agent-vV5u7tzN.js → export-agent-5rXmF-g1.js} +1 -1
- package/page/assets/{guardrail-tester-D70vg-Zv.js → guardrail-tester-B-ZfQFVu.js} +1 -1
- package/page/assets/{index-CvrD0wqP.js → index-Dajtrq_Z.js} +6 -6
- package/page/assets/{studio-code-pane-CPon5udY.js → studio-code-pane-CKYRitdD.js} +1 -1
- package/page/assets/{studio-console-BSV-XHe9.js → studio-console-DwhqnNyw.js} +1 -1
- package/page/assets/{studio-decision-Dk1Tsfah.js → studio-decision-Ckj4UNNt.js} +1 -1
- package/page/assets/{studio-embedding-BkBuVy1T.js → studio-embedding-8qL_dVlz.js} +1 -1
- package/page/assets/{studio-host-console-C6f389Xp.js → studio-host-console-BXwwloN4.js} +2 -2
- package/page/assets/{studio-labels-DEEMSKuk.js → studio-labels-C1pvg0JC.js} +1 -1
- package/page/assets/{studio-live-uDkVyN2h.js → studio-live-26srJ74m.js} +1 -1
- package/page/assets/{studio-map-BVIl4fqd.js → studio-map-C5zsJusF.js} +1 -1
- package/page/assets/{studio-trace-replay-DG90ujMk.js → studio-trace-replay-B38TicvO.js} +1 -1
- package/page/assets/{use-one-call-DIEEQ4qF.js → use-one-call-DjVkallj.js} +1 -1
- package/page/index.html +5 -5
- package/ui/pan.js +5 -1
- package/ui/studio-map.js +7 -7
- package/ui/tree-map.css +43 -0
- package/ui/tree-map.d.ts +7 -1
- package/ui/tree-map.js +10 -5
package/ui/pan.js
CHANGED
|
@@ -21,6 +21,7 @@ export function fieldStart(field, scroller) {
|
|
|
21
21
|
top: box.top - port.top + scroller.scrollTop,
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
+
const clamp = (value, most) => Math.min(Math.max(value, 0), Math.max(most, 0));
|
|
24
25
|
/**
|
|
25
26
|
* Scroll the box around `field` to `at`, once it can: a field that is still opening has no box that
|
|
26
27
|
* scrolls yet, so it tries again each frame until the scroll lands. Returns what stops the tries.
|
|
@@ -32,7 +33,10 @@ export function scrollOnce(field, at) {
|
|
|
32
33
|
tries -= 1;
|
|
33
34
|
const scroller = scrollerOf(field);
|
|
34
35
|
if (scroller && scroller.scrollWidth > scroller.clientWidth) {
|
|
35
|
-
const
|
|
36
|
+
const wanted = at(scroller);
|
|
37
|
+
// A place past either end lands at that end.
|
|
38
|
+
const left = clamp(wanted.left, scroller.scrollWidth - scroller.clientWidth);
|
|
39
|
+
const top = clamp(wanted.top, scroller.scrollHeight - scroller.clientHeight);
|
|
36
40
|
scroller.scrollTo({ left, top, behavior: 'instant' });
|
|
37
41
|
if (Math.abs(scroller.scrollLeft - left) < 1 && Math.abs(scroller.scrollTop - top) < 1)
|
|
38
42
|
return;
|
package/ui/studio-map.js
CHANGED
|
@@ -212,14 +212,15 @@ function useLit(layout) {
|
|
|
212
212
|
return { lit, on, onLines, lights };
|
|
213
213
|
}
|
|
214
214
|
/**
|
|
215
|
-
* A family
|
|
216
|
-
*
|
|
215
|
+
* A family starts from the top left. The map, opened or turned to or from detail, centres the node
|
|
216
|
+
* that is open, or starts from the top left when none is.
|
|
217
217
|
*/
|
|
218
218
|
function useStart(field, family, open) {
|
|
219
219
|
const latest = useRef(open.place);
|
|
220
220
|
latest.current = open.place;
|
|
221
221
|
// invariant: the sizes are one of two constants, so they change exactly when the detail does.
|
|
222
222
|
const { sizes } = open;
|
|
223
|
+
// why: Not on a click: the node clicked is already in view, and the map stays where the reader put it.
|
|
223
224
|
useEffect(() => {
|
|
224
225
|
const node = field.current;
|
|
225
226
|
if (!node)
|
|
@@ -228,13 +229,12 @@ function useStart(field, family, open) {
|
|
|
228
229
|
const at = family === undefined ? place : undefined;
|
|
229
230
|
// The field starts past the room around it.
|
|
230
231
|
return scrollOnce(node, (scroller) => {
|
|
231
|
-
const hidden = at !== undefined &&
|
|
232
|
-
(at.x + sizes.node.width > scroller.clientWidth ||
|
|
233
|
-
at.y + at.height > scroller.clientHeight);
|
|
234
232
|
const { left, top } = fieldStart(node, scroller);
|
|
233
|
+
if (at === undefined)
|
|
234
|
+
return { left, top };
|
|
235
235
|
return {
|
|
236
|
-
left: left +
|
|
237
|
-
top: top +
|
|
236
|
+
left: left + at.x + sizes.node.width / 2 - scroller.clientWidth / 2,
|
|
237
|
+
top: top + at.y + at.height / 2 - scroller.clientHeight / 2,
|
|
238
238
|
};
|
|
239
239
|
});
|
|
240
240
|
}, [field, family, sizes]);
|
package/ui/tree-map.css
CHANGED
|
@@ -13,3 +13,46 @@
|
|
|
13
13
|
.studio-tree-map-lines .map-line {
|
|
14
14
|
stroke: color-mix(in srgb, var(--color-border-emphasized) 60%, var(--color-background-surface));
|
|
15
15
|
}
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* Feeds draw in as the loader's map draws (read-map.css), one after another: the line from the
|
|
19
|
+
* tree, then the token at its end. Hidden, they leave in the reverse order.
|
|
20
|
+
* invariant: Transitions, not keyframes, so drawing and leaving both ease, and a turn mid-draw
|
|
21
|
+
* goes back from where it is.
|
|
22
|
+
*/
|
|
23
|
+
.studio-tree-map {
|
|
24
|
+
--feed-step: 70ms;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.studio-tree-map-lines [data-feed] {
|
|
28
|
+
stroke-dasharray: 1;
|
|
29
|
+
stroke-dashoffset: 0;
|
|
30
|
+
transition: stroke-dashoffset var(--duration-medium, 240ms) var(--ease-standard, ease-out)
|
|
31
|
+
calc(var(--feed-i) * var(--feed-step));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.studio-tree-map > [data-feed] {
|
|
35
|
+
transition: opacity var(--duration-medium, 240ms) var(--ease-standard, ease-out)
|
|
36
|
+
calc(var(--feed-i) * var(--feed-step) + var(--duration-medium, 240ms));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.studio-tree-map[data-feeds="hidden"] > [data-feed] {
|
|
40
|
+
opacity: 0;
|
|
41
|
+
transition-delay: calc((var(--feed-n) - var(--feed-i)) * var(--feed-step));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.studio-tree-map[data-feeds="hidden"] .studio-tree-map-lines [data-feed] {
|
|
45
|
+
stroke-dashoffset: var(--feed-from);
|
|
46
|
+
transition-delay: calc(
|
|
47
|
+
(var(--feed-n) - var(--feed-i)) *
|
|
48
|
+
var(--feed-step) +
|
|
49
|
+
var(--duration-medium, 240ms)
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@media (prefers-reduced-motion: reduce) {
|
|
54
|
+
.studio-tree-map-lines [data-feed],
|
|
55
|
+
.studio-tree-map > [data-feed] {
|
|
56
|
+
transition: none;
|
|
57
|
+
}
|
|
58
|
+
}
|
package/ui/tree-map.d.ts
CHANGED
|
@@ -3,5 +3,11 @@ export interface StudioTreeMapProps {
|
|
|
3
3
|
workspace: StudioWorkspace;
|
|
4
4
|
/** The keys of the agents to draw, in the workspace's order; every agent when unset. */
|
|
5
5
|
agents?: readonly string[] | undefined;
|
|
6
|
+
/**
|
|
7
|
+
* Whether what feeds the tree is drawn beside it. Turned on, each feed draws in after the one
|
|
8
|
+
* before, its line from the tree first, as the loader's map draws; turned off, they leave in the
|
|
9
|
+
* reverse order. Shown when unset.
|
|
10
|
+
*/
|
|
11
|
+
feeds?: 'shown' | 'hidden' | undefined;
|
|
6
12
|
}
|
|
7
|
-
export declare function StudioTreeMap({ workspace, agents }: StudioTreeMapProps): import("react").JSX.Element;
|
|
13
|
+
export declare function StudioTreeMap({ workspace, agents, feeds: shown }: StudioTreeMapProps): import("react").JSX.Element;
|
package/ui/tree-map.js
CHANGED
|
@@ -142,7 +142,9 @@ function linePath(from, to) {
|
|
|
142
142
|
const x = from.x + TRUNK;
|
|
143
143
|
return `M ${x} ${from.y + HALF} V ${to.y - TURN} Q ${x} ${to.y} ${x + TURN} ${to.y} H ${to.x - LINE_GAP}`;
|
|
144
144
|
}
|
|
145
|
-
|
|
145
|
+
/** The order a feed draws in, and which end its line starts from: 1 the path's start, -1 its end. */
|
|
146
|
+
const feedStyle = (index, from = 1) => ({ '--feed-i': index, '--feed-from': from });
|
|
147
|
+
export function StudioTreeMap({ workspace, agents, feeds: shown = 'shown' }) {
|
|
146
148
|
const root = useRef(null);
|
|
147
149
|
const rows = rowsOf(workspace, agents);
|
|
148
150
|
const feeds = feedsOf(workspace, rows);
|
|
@@ -166,12 +168,14 @@ export function StudioTreeMap({ workspace, agents }) {
|
|
|
166
168
|
return above && feed.depth <= above.depth ? [railFor(feed, above)] : [];
|
|
167
169
|
});
|
|
168
170
|
const width = Math.max(GUESS, ...feeds.map(feedRight), ...rails) + PAD;
|
|
169
|
-
|
|
171
|
+
const order = new Map(feeds.map((feed, index) => [feed.id, index]));
|
|
172
|
+
return (_jsxs("div", { ref: root, className: "studio-tree-map", "data-feeds": shown, style: { width, height, '--feed-n': feeds.length }, children: [_jsxs("svg", { className: "studio-tree-map-lines", width: width, height: height, "aria-hidden": "true", children: [rows.map((row) => row.parent && (_jsx("path", { className: "map-line", d: linePath(row.parent, row) }, rowId(row)))), feeds.flatMap((feed) => feed.into.map((id) => {
|
|
170
173
|
const row = byId.get(id);
|
|
171
174
|
if (!row)
|
|
172
175
|
return null;
|
|
173
176
|
const { d } = mapCurve({ x: feedX - LINE_GAP, y: feed.y }, { x: right(row) + LINE_GAP, y: row.y });
|
|
174
|
-
|
|
177
|
+
// The line runs from the feed to the row; it draws from the row.
|
|
178
|
+
return (_jsx("path", { className: "map-line", d: d, pathLength: 1, "data-feed": "", style: feedStyle(order.get(feed.id) ?? 0, -1) }, `${feed.id}>${id}`));
|
|
175
179
|
})), feeds.map((feed) => {
|
|
176
180
|
const above = feed.under === undefined ? undefined : feedById.get(feed.under);
|
|
177
181
|
if (above === undefined)
|
|
@@ -182,9 +186,10 @@ export function StudioTreeMap({ workspace, agents }) {
|
|
|
182
186
|
const d = feed.depth > above.depth
|
|
183
187
|
? linePath(from, { x: feedLeft(feed), y: feed.y })
|
|
184
188
|
: sidePath({ x: feedRight(feed) + LINE_GAP, y: feed.y }, { x: feedRight(above) + LINE_GAP, y: above.y }, railFor(feed, above));
|
|
185
|
-
|
|
189
|
+
// A turn in runs from the feed above; a line round the side runs from this one.
|
|
190
|
+
return (_jsx("path", { className: "map-line", d: d, pathLength: 1, "data-feed": "", style: feedStyle(order.get(feed.id) ?? 0, feed.depth > above.depth ? 1 : -1) }, `${feed.id}^`));
|
|
186
191
|
})] }), rows.map((row) => {
|
|
187
192
|
const draft = drafts.get(row.agent) ?? createBlankDraft();
|
|
188
193
|
return (_jsx(MapToken, { id: rowId(row), label: row.node.label, icon: nodeIcon(draft, row.node.ref), x: row.x, y: row.y }, rowId(row)));
|
|
189
|
-
}), feeds.map((feed) => (_jsx(MapToken, { id: feed.id, label: feed.label, icon: feed.icon, x: feedLeft(feed), y: feed.y }, feed.id)))] }));
|
|
194
|
+
}), feeds.map((feed) => (_jsx(MapToken, { id: feed.id, label: feed.label, icon: feed.icon, x: feedLeft(feed), y: feed.y, "data-feed": "", style: feedStyle(order.get(feed.id) ?? 0) }, feed.id)))] }));
|
|
190
195
|
}
|