@coldtea/pr-lens-renderer 0.1.0
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/LICENSE +21 -0
- package/README.md +91 -0
- package/dist/bounds.d.ts +23 -0
- package/dist/bounds.d.ts.map +1 -0
- package/dist/bounds.js +39 -0
- package/dist/bounds.js.map +1 -0
- package/dist/corrections.d.ts +12 -0
- package/dist/corrections.d.ts.map +1 -0
- package/dist/corrections.js +122 -0
- package/dist/corrections.js.map +1 -0
- package/dist/design.d.ts +112 -0
- package/dist/design.d.ts.map +1 -0
- package/dist/design.js +112 -0
- package/dist/design.js.map +1 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +9 -0
- package/dist/errors.js.map +1 -0
- package/dist/geometry.d.ts +20 -0
- package/dist/geometry.d.ts.map +1 -0
- package/dist/geometry.js +15 -0
- package/dist/geometry.js.map +1 -0
- package/dist/glob.d.ts +7 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +17 -0
- package/dist/glob.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/architecture.d.ts +78 -0
- package/dist/layout/architecture.d.ts.map +1 -0
- package/dist/layout/architecture.js +207 -0
- package/dist/layout/architecture.js.map +1 -0
- package/dist/layout/congestion.d.ts +18 -0
- package/dist/layout/congestion.d.ts.map +1 -0
- package/dist/layout/congestion.js +50 -0
- package/dist/layout/congestion.js.map +1 -0
- package/dist/layout/dataflow.d.ts +85 -0
- package/dist/layout/dataflow.d.ts.map +1 -0
- package/dist/layout/dataflow.js +184 -0
- package/dist/layout/dataflow.js.map +1 -0
- package/dist/layout/edges.d.ts +48 -0
- package/dist/layout/edges.d.ts.map +1 -0
- package/dist/layout/edges.js +843 -0
- package/dist/layout/edges.js.map +1 -0
- package/dist/layout/labels.d.ts +9 -0
- package/dist/layout/labels.d.ts.map +1 -0
- package/dist/layout/labels.js +149 -0
- package/dist/layout/labels.js.map +1 -0
- package/dist/layout/rank.d.ts +16 -0
- package/dist/layout/rank.d.ts.map +1 -0
- package/dist/layout/rank.js +80 -0
- package/dist/layout/rank.js.map +1 -0
- package/dist/layout/seating.d.ts +29 -0
- package/dist/layout/seating.d.ts.map +1 -0
- package/dist/layout/seating.js +131 -0
- package/dist/layout/seating.js.map +1 -0
- package/dist/manifest.d.ts +39 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +99 -0
- package/dist/manifest.js.map +1 -0
- package/dist/render.d.ts +49 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +125 -0
- package/dist/render.js.map +1 -0
- package/dist/scope.d.ts +21 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +57 -0
- package/dist/scope.js.map +1 -0
- package/dist/svg/architecture.d.ts +15 -0
- package/dist/svg/architecture.d.ts.map +1 -0
- package/dist/svg/architecture.js +197 -0
- package/dist/svg/architecture.js.map +1 -0
- package/dist/svg/dataflow.d.ts +9 -0
- package/dist/svg/dataflow.d.ts.map +1 -0
- package/dist/svg/dataflow.js +284 -0
- package/dist/svg/dataflow.js.map +1 -0
- package/dist/svg/document.d.ts +37 -0
- package/dist/svg/document.d.ts.map +1 -0
- package/dist/svg/document.js +148 -0
- package/dist/svg/document.js.map +1 -0
- package/dist/svg/icons.d.ts +3 -0
- package/dist/svg/icons.d.ts.map +1 -0
- package/dist/svg/icons.js +106 -0
- package/dist/svg/icons.js.map +1 -0
- package/dist/svg/primitives.d.ts +13 -0
- package/dist/svg/primitives.d.ts.map +1 -0
- package/dist/svg/primitives.js +34 -0
- package/dist/svg/primitives.js.map +1 -0
- package/dist/svg/pulse.d.ts +24 -0
- package/dist/svg/pulse.d.ts.map +1 -0
- package/dist/svg/pulse.js +33 -0
- package/dist/svg/pulse.js.map +1 -0
- package/dist/text.d.ts +18 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +70 -0
- package/dist/text.js.map +1 -0
- package/dist/theme.d.ts +44 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +72 -0
- package/dist/theme.js.map +1 -0
- package/dist/version.d.ts +9 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +9 -0
- package/dist/version.js.map +1 -0
- package/package.json +56 -0
- package/src/bounds.ts +50 -0
- package/src/corrections.ts +166 -0
- package/src/design.ts +124 -0
- package/src/errors.ts +21 -0
- package/src/geometry.ts +22 -0
- package/src/glob.ts +20 -0
- package/src/index.ts +30 -0
- package/src/layout/architecture.ts +324 -0
- package/src/layout/congestion.ts +76 -0
- package/src/layout/dataflow.ts +307 -0
- package/src/layout/edges.ts +1061 -0
- package/src/layout/labels.ts +192 -0
- package/src/layout/rank.ts +95 -0
- package/src/layout/seating.ts +189 -0
- package/src/manifest.ts +118 -0
- package/src/render.ts +190 -0
- package/src/scope.ts +67 -0
- package/src/svg/architecture.ts +293 -0
- package/src/svg/dataflow.ts +408 -0
- package/src/svg/document.ts +198 -0
- package/src/svg/icons.ts +121 -0
- package/src/svg/primitives.ts +50 -0
- package/src/svg/pulse.ts +48 -0
- package/src/text.ts +92 -0
- package/src/theme.ts +107 -0
- package/src/version.ts +9 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { CARD_HEIGHT, CARD_HEIGHT_WITH_SUBTITLE, CARD_PADDING_X, DIAGRAM_MARGIN, ICON_CHIP_GAP, ICON_CHIP_SIZE, SUBTITLE_SIZE, TITLE_SIZE, } from "../design.js";
|
|
2
|
+
import { measure } from "../text.js";
|
|
3
|
+
export const PARTICIPANT_TOP = 18;
|
|
4
|
+
/** The lifeline hangs just clear of the card that heads its column. */
|
|
5
|
+
export const LIFELINE_GAP = 2;
|
|
6
|
+
/** Where the first message sits below the top of the lifelines. */
|
|
7
|
+
export const FIRST_MESSAGE_DROP = 41;
|
|
8
|
+
export const MESSAGE_PITCH = 38;
|
|
9
|
+
export const SELF_MESSAGE_PITCH = 54;
|
|
10
|
+
export const FLOW_BOTTOM_PADDING = 24;
|
|
11
|
+
export const FLOW_GAP = 40;
|
|
12
|
+
export const COLUMN_MIN_WIDTH = 150;
|
|
13
|
+
export const COLUMN_GAP = 80;
|
|
14
|
+
/**
|
|
15
|
+
* How far a column's band reaches beyond its cards, echoing the padding a
|
|
16
|
+
* lane keeps around the cards it holds.
|
|
17
|
+
*/
|
|
18
|
+
export const FLOW_BAND_PAD_X = 12;
|
|
19
|
+
export const FLOW_BAND_PAD_Y = 12;
|
|
20
|
+
/** Half the width of an activation bar, and how far it holds arrows off the lifeline. */
|
|
21
|
+
export const ACTIVATION_HALF_WIDTH = 6;
|
|
22
|
+
export const MARKER_INSET = 5;
|
|
23
|
+
export const SELF_LOOP_REACH = 52;
|
|
24
|
+
export const SELF_LOOP_DROP = 6;
|
|
25
|
+
export const SELF_LOOP_CORNER = 7;
|
|
26
|
+
/** How far below its own row a self-message loop reaches. */
|
|
27
|
+
export const SELF_LOOP_EXTENT = SELF_LOOP_DROP + SELF_LOOP_CORNER * 2;
|
|
28
|
+
const messagePitch = (message) => message.kind === "self" ? SELF_MESSAGE_PITCH : MESSAGE_PITCH;
|
|
29
|
+
/**
|
|
30
|
+
* How many turns a message takes in the cycle: one per repeat, up to the cap,
|
|
31
|
+
* so a repeated step crosses its own arrow several times running rather than
|
|
32
|
+
* once.
|
|
33
|
+
*
|
|
34
|
+
* A step the document leaves unanimated takes none. Reserving a turn for one
|
|
35
|
+
* that draws nothing would put a hole in the relay — the drawing would go
|
|
36
|
+
* dark for the length of it, which is the very thing sharing a cycle is meant
|
|
37
|
+
* to avoid. This is the one place that count is decided, so the schedule and
|
|
38
|
+
* the painting cannot disagree about it.
|
|
39
|
+
*/
|
|
40
|
+
export const pulseCount = (message, cap) => message.animated ? Math.min(message.repeat ?? 1, cap) : 0;
|
|
41
|
+
const labelFor = (message) => message.repeat === undefined || message.repeat === 1
|
|
42
|
+
? message.label
|
|
43
|
+
: `${message.label} ×${message.repeat}`;
|
|
44
|
+
/**
|
|
45
|
+
* A synchronous call is the one kind whose sender waits, so it is the one
|
|
46
|
+
* kind that activates its receiver: the bar starts where the call arrives and
|
|
47
|
+
* runs to the return that answers it — the first later `return` back to the
|
|
48
|
+
* caller not already claimed by an earlier call. A call no return answers
|
|
49
|
+
* keeps its receiver active through the receiver's last involvement, because
|
|
50
|
+
* the diagram never shows the work finishing. Async and self messages
|
|
51
|
+
* activate nothing: neither implies anyone is waiting.
|
|
52
|
+
*/
|
|
53
|
+
const activationsFor = (node, messages) => {
|
|
54
|
+
const claimed = new Set();
|
|
55
|
+
const bars = [];
|
|
56
|
+
messages.forEach((placed, index) => {
|
|
57
|
+
if (placed.message.kind !== "sync" || placed.message.to !== node)
|
|
58
|
+
return;
|
|
59
|
+
const answer = messages.findIndex((candidate, position) => position > index &&
|
|
60
|
+
!claimed.has(position) &&
|
|
61
|
+
candidate.message.kind === "return" &&
|
|
62
|
+
candidate.message.from === node &&
|
|
63
|
+
candidate.message.to === placed.message.from);
|
|
64
|
+
const answered = messages[answer];
|
|
65
|
+
if (answer !== -1 && answered !== undefined) {
|
|
66
|
+
claimed.add(answer);
|
|
67
|
+
bars.push({ top: placed.y, bottom: answered.y });
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const last = messages.reduce((lowest, candidate, position) => position >= index &&
|
|
71
|
+
(candidate.message.from === node || candidate.message.to === node)
|
|
72
|
+
? Math.max(lowest, candidate.y)
|
|
73
|
+
: lowest, placed.y);
|
|
74
|
+
bars.push({ top: placed.y, bottom: last + MESSAGE_PITCH / 3 });
|
|
75
|
+
});
|
|
76
|
+
return mergedBars(bars);
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Nested or unanswered calls can hand one column overlapping spans; a single
|
|
80
|
+
* bar per busy stretch keeps the drawing readable. Bars arrive ordered by
|
|
81
|
+
* top, because message y only ever grows.
|
|
82
|
+
*/
|
|
83
|
+
const mergedBars = (bars) => {
|
|
84
|
+
const merged = [];
|
|
85
|
+
for (const bar of bars) {
|
|
86
|
+
const current = merged[merged.length - 1];
|
|
87
|
+
if (current !== undefined && bar.top <= current.bottom)
|
|
88
|
+
current.bottom = Math.max(current.bottom, bar.bottom);
|
|
89
|
+
else
|
|
90
|
+
merged.push({ ...bar });
|
|
91
|
+
}
|
|
92
|
+
return merged;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* The node a column stands for, as the card will show it: the column's own
|
|
96
|
+
* shorter label wins over the node's, and a participant the graph no longer
|
|
97
|
+
* carries still needs a card, so a placeholder node stands in for one.
|
|
98
|
+
*/
|
|
99
|
+
const participantNode = (participant, byId) => {
|
|
100
|
+
const node = byId.get(participant.node);
|
|
101
|
+
if (node === undefined)
|
|
102
|
+
return {
|
|
103
|
+
id: participant.node,
|
|
104
|
+
label: participant.label ?? participant.node,
|
|
105
|
+
kind: "other",
|
|
106
|
+
delta: "unchanged",
|
|
107
|
+
lane: "",
|
|
108
|
+
files: [],
|
|
109
|
+
badges: [],
|
|
110
|
+
};
|
|
111
|
+
return participant.label === undefined ? node : { ...node, label: participant.label };
|
|
112
|
+
};
|
|
113
|
+
const cardHeight = (node) => node.subtitle === undefined ? CARD_HEIGHT : CARD_HEIGHT_WITH_SUBTITLE;
|
|
114
|
+
/** The width a column's card asks for: chip, title, and mono subtitle. */
|
|
115
|
+
const cardContentWidth = (node) => CARD_PADDING_X * 2 +
|
|
116
|
+
ICON_CHIP_SIZE +
|
|
117
|
+
ICON_CHIP_GAP +
|
|
118
|
+
Math.max(measure(node.label, "sans-bold", TITLE_SIZE), node.subtitle === undefined ? 0 : measure(node.subtitle, "mono", SUBTITLE_SIZE));
|
|
119
|
+
export const layoutDataFlow = (flows, nodes, pulseCap) => {
|
|
120
|
+
const byId = new Map(nodes.map((node) => [node.id, node]));
|
|
121
|
+
// A whole pixel: adding measured widths leaves floating-point dust, and a
|
|
122
|
+
// card handed back exactly the width its title measured would round into
|
|
123
|
+
// truncating that title.
|
|
124
|
+
const columnWidth = Math.ceil(Math.max(COLUMN_MIN_WIDTH, ...flows.flatMap((flow) => flow.participants.map((participant) => cardContentWidth(participantNode(participant, byId))))));
|
|
125
|
+
let slotCount = 0;
|
|
126
|
+
for (const flow of flows)
|
|
127
|
+
for (const message of flow.messages)
|
|
128
|
+
slotCount += pulseCount(message, pulseCap);
|
|
129
|
+
let cursorY = 0;
|
|
130
|
+
let slotCursor = 0;
|
|
131
|
+
let width = 0;
|
|
132
|
+
const placed = flows.map((flow) => {
|
|
133
|
+
const columnNodes = flow.participants.map((participant) => participantNode(participant, byId));
|
|
134
|
+
const centres = flow.participants.map((_, index) => DIAGRAM_MARGIN + columnWidth / 2 + index * (columnWidth + COLUMN_GAP));
|
|
135
|
+
const centreOf = new Map(flow.participants.map((participant, index) => [participant.node, centres[index] ?? 0]));
|
|
136
|
+
const lifelineTop = cursorY + PARTICIPANT_TOP + Math.max(...columnNodes.map(cardHeight)) + LIFELINE_GAP;
|
|
137
|
+
let messageY = lifelineTop + FIRST_MESSAGE_DROP;
|
|
138
|
+
const messages = flow.messages.map((message) => {
|
|
139
|
+
const y = messageY;
|
|
140
|
+
messageY += messagePitch(message);
|
|
141
|
+
const count = pulseCount(message, pulseCap);
|
|
142
|
+
const slot = { start: slotCursor, count };
|
|
143
|
+
slotCursor += count;
|
|
144
|
+
return {
|
|
145
|
+
message,
|
|
146
|
+
label: labelFor(message),
|
|
147
|
+
y,
|
|
148
|
+
fromX: centreOf.get(message.from) ?? 0,
|
|
149
|
+
toX: centreOf.get(message.to) ?? 0,
|
|
150
|
+
slot,
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
const participants = columnNodes.map((node, index) => {
|
|
154
|
+
const centreX = centres[index] ?? 0;
|
|
155
|
+
return {
|
|
156
|
+
node,
|
|
157
|
+
centreX,
|
|
158
|
+
card: {
|
|
159
|
+
x: centreX - columnWidth / 2,
|
|
160
|
+
y: cursorY + PARTICIPANT_TOP,
|
|
161
|
+
width: columnWidth,
|
|
162
|
+
height: cardHeight(node),
|
|
163
|
+
},
|
|
164
|
+
activations: activationsFor(node.id, messages),
|
|
165
|
+
};
|
|
166
|
+
});
|
|
167
|
+
const drawn = messages.reduce((lowest, placedMessage) => Math.max(lowest, placedMessage.y + (placedMessage.message.kind === "self" ? SELF_LOOP_EXTENT : 0)), lifelineTop + FIRST_MESSAGE_DROP);
|
|
168
|
+
const bottom = drawn + FLOW_BOTTOM_PADDING;
|
|
169
|
+
const height = bottom - cursorY;
|
|
170
|
+
const top = cursorY;
|
|
171
|
+
cursorY = bottom + FLOW_GAP;
|
|
172
|
+
width = Math.max(width, (centres[centres.length - 1] ?? 0) + columnWidth / 2 + DIAGRAM_MARGIN);
|
|
173
|
+
return { flow, top, height, lifelineTop, participants, messages };
|
|
174
|
+
});
|
|
175
|
+
return {
|
|
176
|
+
// Whole numbers, for the same reason the architecture canvas uses them.
|
|
177
|
+
width: Math.ceil(width),
|
|
178
|
+
height: Math.ceil(cursorY - FLOW_GAP + DIAGRAM_MARGIN),
|
|
179
|
+
columnWidth,
|
|
180
|
+
flows: placed,
|
|
181
|
+
slotCount,
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
//# sourceMappingURL=dataflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataflow.js","sourceRoot":"","sources":["../../src/layout/dataflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { GraphEdge } from "@coldtea/pr-lens-schema";
|
|
2
|
+
import { type Box, type Point } from "../geometry.js";
|
|
3
|
+
import type { ArchitectureLayout } from "./architecture.js";
|
|
4
|
+
/**
|
|
5
|
+
* A route, kept as its own segments rather than as a path string, because the
|
|
6
|
+
* label pill has to be placed on a point of it after the fact.
|
|
7
|
+
*/
|
|
8
|
+
type Segment = {
|
|
9
|
+
kind: "line";
|
|
10
|
+
to: Point;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "cubic";
|
|
13
|
+
first: Point;
|
|
14
|
+
second: Point;
|
|
15
|
+
to: Point;
|
|
16
|
+
};
|
|
17
|
+
export type Curve = {
|
|
18
|
+
from: Point;
|
|
19
|
+
segments: Segment[];
|
|
20
|
+
};
|
|
21
|
+
export type RoutedEdge = {
|
|
22
|
+
edge: GraphEdge;
|
|
23
|
+
path: string;
|
|
24
|
+
curve: Curve;
|
|
25
|
+
/** Centre of the longest straight run — where this edge's label pill sits. */
|
|
26
|
+
labelAnchor: Point | undefined;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* A box the route cannot leave. A cubic stays inside the hull of its own
|
|
30
|
+
* control points, so taking every point of every segment is a bound rather
|
|
31
|
+
* than an estimate — which is what the canvas needs, since a route that ran
|
|
32
|
+
* off the edge would simply be clipped.
|
|
33
|
+
*/
|
|
34
|
+
export declare const curveBounds: (curve: Curve) => Box;
|
|
35
|
+
export declare const routeEdges: (edges: readonly GraphEdge[], layout: ArchitectureLayout) => RoutedEdge[];
|
|
36
|
+
export type ChannelTraffic = {
|
|
37
|
+
corridors: ReadonlyMap<number, number>;
|
|
38
|
+
bands: ReadonlyMap<number, number>;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* How many runs each gap of this layout would carry, counted from the same
|
|
42
|
+
* routing that would be drawn — braid guard included. This is what decides
|
|
43
|
+
* whether a gap is wide enough for its traffic before anything is drawn
|
|
44
|
+
* into it.
|
|
45
|
+
*/
|
|
46
|
+
export declare const channelTraffic: (edges: readonly GraphEdge[], layout: ArchitectureLayout) => ChannelTraffic;
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=edges.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edges.d.ts","sourceRoot":"","sources":["../../src/layout/edges.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AASzD,OAAO,EAAoB,KAAK,GAAG,EAAE,KAAK,KAAK,EAAa,MAAM,gBAAgB,CAAC;AACnF,OAAO,KAAK,EAAE,kBAAkB,EAAsC,MAAM,mBAAmB,CAAC;AAEhG;;;GAGG;AACH,KAAK,OAAO,GACR;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,KAAK,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC;AAE9D,MAAM,MAAM,KAAK,GAAG;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC;AAEzD,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,8EAA8E;IAC9E,WAAW,EAAE,KAAK,GAAG,SAAS,CAAC;CAChC,CAAC;AAoDF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,UAAW,KAAK,KAAG,GAoB1C,CAAC;AAgfF,eAAO,MAAM,UAAU,UACd,SAAS,SAAS,EAAE,UACnB,kBAAkB,KACzB,UAAU,EAAqC,CAAC;AAEnD,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,UAClB,SAAS,SAAS,EAAE,UACnB,kBAAkB,KACzB,cAgBF,CAAC"}
|