@skydesign/tf 0.2.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.
@@ -0,0 +1,394 @@
1
+ import * as d3_2 from 'd3';
2
+ import { ForwardRefExoticComponent } from 'react';
3
+ import { JSX } from 'react/jsx-runtime';
4
+ import { RefAttributes } from 'react';
5
+
6
+ /**
7
+ * Create a custom layout config by merging with defaults.
8
+ * @param overrides - Partial config to override defaults
9
+ * @returns Complete LayoutConfig with overrides applied
10
+ */
11
+ export declare function createLayoutConfig(overrides?: Partial<LayoutConfig>): LayoutConfig;
12
+
13
+ /**
14
+ * Decode a JSON string that may be single or double-encoded.
15
+ * Tries direct parse first, then falls back to double-parse for double-encoded strings.
16
+ * @param str - The JSON string (either single or double-encoded)
17
+ * @returns The parsed object
18
+ */
19
+ export declare function decodeDotString<T>(str: string): T;
20
+
21
+ /**
22
+ * Default layout configuration with sensible values.
23
+ */
24
+ export declare const DEFAULT_LAYOUT_CONFIG: LayoutConfig;
25
+
26
+ declare interface DrawOp {
27
+ op: string;
28
+ grad?: string;
29
+ color?: string;
30
+ points?: number[][];
31
+ rect?: number[];
32
+ pt?: number[];
33
+ align?: string;
34
+ width?: number;
35
+ size?: number;
36
+ face?: string;
37
+ text?: string;
38
+ style?: string;
39
+ }
40
+
41
+ /**
42
+ * Content structure for graph edges
43
+ */
44
+ export declare interface EdgeContent {
45
+ /** Index of the edge */
46
+ index: number;
47
+ /** Color of the edge */
48
+ color: string;
49
+ /** Text elements on the edge */
50
+ elems: TextElem[];
51
+ /** Optional group identifier for the edge */
52
+ group?: string;
53
+ }
54
+
55
+ /**
56
+ * Lightweight edge metadata returned to consumers after rendering.
57
+ * Provides the essential identifiers needed for edge navigation.
58
+ */
59
+ export declare interface EdgeInfo {
60
+ /** Internal Graphviz ID */
61
+ id: number;
62
+ /** Edge index from EdgeContent (used for selection and navigation) */
63
+ index: number;
64
+ /** Source node name */
65
+ sourceNodeId: string;
66
+ /** Target node name */
67
+ targetNodeId: string;
68
+ /** Displayable label text (null if no label) */
69
+ label: string | null;
70
+ }
71
+
72
+ /**
73
+ * Encode an object by double JSON.stringify for use in DOT string labels.
74
+ * This escapes special characters that would break DOT syntax.
75
+ * @param obj - The object to encode
76
+ * @returns Double-stringified JSON string
77
+ */
78
+ export declare function encodeDotString<T>(obj: T): string;
79
+
80
+ export declare interface GraphvizJson {
81
+ name: string;
82
+ directed: boolean;
83
+ strict: boolean;
84
+ bb?: string;
85
+ objects?: GraphvizObject[];
86
+ edges?: GraphvizObject[];
87
+ }
88
+
89
+ declare interface GraphvizObject {
90
+ _gvid: number;
91
+ name: string;
92
+ _draw_?: DrawOp[];
93
+ _ldraw_?: DrawOp[];
94
+ _hdraw_?: DrawOp[];
95
+ _tdraw_?: DrawOp[];
96
+ bb?: string;
97
+ pos?: string;
98
+ width?: string;
99
+ height?: string;
100
+ label?: string;
101
+ head?: number;
102
+ tail?: number;
103
+ }
104
+
105
+ /**
106
+ * GraphvizRenderer - Component that renders DOT strings using Web Worker
107
+ * and automatically renders them with custom layout.
108
+ *
109
+ * Supports both declarative (props) and imperative (ref) APIs for zoom control.
110
+ *
111
+ * @example
112
+ * ```tsx
113
+ * const rendererRef = useRef<GraphvizRendererRef>(null);
114
+ *
115
+ * <GraphvizRenderer
116
+ * ref={rendererRef}
117
+ * dotString={example.dot}
118
+ * nodeMapping={example.nodeMapping}
119
+ * maxDepth={2}
120
+ * className="w-full h-full"
121
+ * />
122
+ *
123
+ * // Use ref API
124
+ * rendererRef.current?.zoomIn();
125
+ * rendererRef.current?.zoomOut(15);
126
+ * rendererRef.current?.toggleZoom();
127
+ * ```
128
+ */
129
+ export declare const GraphvizRenderer: ForwardRefExoticComponent<GraphvizRendererProps & RefAttributes<GraphvizRendererRef>>;
130
+
131
+ export declare interface GraphvizRendererProps {
132
+ /** DOT string to render */
133
+ dotString: string;
134
+ /** Node mapping for custom rendering */
135
+ nodeMapping?: Record<string, NodeMapping>;
136
+ /** SVG font size */
137
+ svgFontSize?: number;
138
+ /** Optional custom loading indicator component */
139
+ loadingIndicator?: React.ReactNode;
140
+ /** Callback when rendering succeeds */
141
+ onSuccess?: (result: {
142
+ json: GraphvizJson;
143
+ svgElement: SVGSVGElement;
144
+ edges: EdgeInfo[];
145
+ }) => void;
146
+ /** Callback when rendering fails */
147
+ onError?: (error: Error) => void;
148
+ /** Callback on zoom with font size information */
149
+ onZoom?: (info: {
150
+ baseFontSize: number;
151
+ actualFontSize: number;
152
+ scale: number;
153
+ }) => void;
154
+ /** Callback for render progress with elapsed time in milliseconds */
155
+ onRenderProgress?: (elapsedMs: number) => void;
156
+ /** Callback when rendering is cancelled by user */
157
+ onCancel?: () => void;
158
+ /** Callback when large graph warning is triggered. Receives node and edge count. */
159
+ onWarning?: (info: {
160
+ nodeCount: number;
161
+ edgeCount: number;
162
+ }) => void;
163
+ /** Additional class name for the container */
164
+ className?: string;
165
+ /** Show loading indicator (default: true) */
166
+ showLoading?: boolean;
167
+ /** Enable large graph warning dialog - shows warning before rendering graphs with edge count > threshold (default: true) */
168
+ enableLargeGraphWarning?: boolean;
169
+ /** Custom threshold for large graph warning (default: LARGE_GRAPH_THRESHOLD = 500) */
170
+ largeGraphThreshold?: number;
171
+ /** Enable debug visual indicators (yellow border and center dot) */
172
+ debug?: boolean;
173
+ /** Currently selected edge ID (controlled component) */
174
+ selectedEdgeId?: number | null;
175
+ /** Callback when an edge is selected or deselected */
176
+ onEdgeSelect?: (edgeId: number | null) => void;
177
+ /** Use native Graphviz rendering instead of custom rendering (default: false) */
178
+ useNativeRendering?: boolean;
179
+ /** Custom node width in points (default: 240) */
180
+ nodeWidth?: number;
181
+ /** Custom node height in points (default: 64) */
182
+ nodeHeight?: number;
183
+ /** Custom spacing between node columns in points */
184
+ nodeColumnSpacing?: number;
185
+ /** Forward click events to elements beneath the SVG (while preserving zoom/pan) */
186
+ clickPassthrough?: boolean;
187
+ /** Enable zoom via mouse wheel (default: true) */
188
+ enableWheelZoom?: boolean;
189
+ /**
190
+ * Initial pan/zoom transform to apply instead of the default getBBox fit.
191
+ * Pass the `initialTransform` returned by `@skydesign/tf/server`'s
192
+ * `renderToString` so the hydrated interactive graph matches the SSR'd
193
+ * static SVG pixel-for-pixel (no jump on handover).
194
+ */
195
+ initialTransform?: InitialTransform;
196
+ }
197
+
198
+ /**
199
+ * Ref API for programmatic control of GraphvizRenderer
200
+ */
201
+ export declare interface GraphvizRendererRef {
202
+ /**
203
+ * Zoom in by increasing the effective font size
204
+ * @param percentage - Percentage to increase (default: 10)
205
+ */
206
+ zoomIn: (percentage?: number) => void;
207
+ /**
208
+ * Zoom out by decreasing the effective font size
209
+ * @param percentage - Percentage to decrease (default: 10)
210
+ */
211
+ zoomOut: (percentage?: number) => void;
212
+ /**
213
+ * Toggle between full overview and centered view with normal font size (16px)
214
+ */
215
+ toggleZoom: () => void;
216
+ /**
217
+ * Stop the current rendering operation and terminate the worker
218
+ */
219
+ stopRendering: () => void;
220
+ /**
221
+ * Navigate to the previous edge in the rendered edge list.
222
+ * Selects it, centers it in the viewport with smooth animation.
223
+ * Wraps to the last edge when at the beginning. Starts from last if no edge is selected.
224
+ * Fires onEdgeSelect with the new edge index.
225
+ */
226
+ highlightPrevEdge: () => void;
227
+ /**
228
+ * Navigate to the next edge in the rendered edge list.
229
+ * Selects it, centers it in the viewport with smooth animation.
230
+ * Wraps to the first edge when at the end. Starts from first if no edge is selected.
231
+ * Fires onEdgeSelect with the new edge index.
232
+ */
233
+ highlightNextEdge: () => void;
234
+ }
235
+
236
+ /**
237
+ * Render graph using custom SVG based on Graphviz JSON output
238
+ * @param maxDepth - Edge depth to filter by (null = show all)
239
+ * @param includeLesserDepths - If true, show depth <= maxDepth; if false, show only exact depth
240
+ * @param config - Layout configuration
241
+ * @returns Object containing zoom behavior and SVG references for imperative control
242
+ */
243
+ /** Pan/zoom transform: g = translate(x,y) scale(k). */
244
+ export declare interface InitialTransform {
245
+ x: number;
246
+ y: number;
247
+ k: number;
248
+ }
249
+
250
+ export declare const LARGE_GRAPH_THRESHOLD = 500;
251
+
252
+ /**
253
+ * Layout configuration for the Graphviz custom layout renderer.
254
+ * All layout-related constants are consolidated here for easy customization.
255
+ */
256
+ export declare interface LayoutConfig {
257
+ /** Horizontal extension at start/end of edges (in pixels) */
258
+ horizontalExtension: number;
259
+ /** Minimum distance between edge midY values (in pixels) */
260
+ minEdgeDistance: number;
261
+ /** Threshold for skipping vertical segments (in pixels) */
262
+ minVerticalSegment: number;
263
+ /** Radius for self-loop edges (in pixels) */
264
+ loopRadius: number;
265
+ /** Spacing between edges (in pixels) */
266
+ edgeSpacing: number;
267
+ /** Corner radius for edge paths (in pixels) */
268
+ cornerRadius: number;
269
+ /** Width of arrowhead (in pixels) */
270
+ arrowWidth: number;
271
+ /** Height of arrowhead (in pixels) */
272
+ arrowHeight: number;
273
+ /** Extra height for edge labels (in pixels) */
274
+ labelHeight: number;
275
+ /** Font size for edge labels (in pixels) */
276
+ labelFontSize: number;
277
+ /** Padding around label text (in pixels) */
278
+ labelPadding: number;
279
+ /** Corner radius for label background (in pixels) */
280
+ labelCornerRadius: number;
281
+ /** Spacing between nodes (in pixels) */
282
+ nodeSpacing: number;
283
+ /** Threshold for considering edges as nearly horizontal (in pixels) */
284
+ nearlyHorizontalThreshold: number;
285
+ /** Threshold for nearly aligned edges in 3seg path (in pixels) */
286
+ nearlyAlignedThreshold: number;
287
+ }
288
+
289
+ /**
290
+ * Content structure for graph nodes
291
+ */
292
+ export declare interface NodeContent {
293
+ /** Unique key for the node */
294
+ key?: string;
295
+ /** Tags associated with the node */
296
+ tags: string[];
297
+ /** Display label for the node */
298
+ label?: string;
299
+ /** Text content of the node */
300
+ text: string;
301
+ /** Optional text color */
302
+ color?: string;
303
+ /** Optional background color for the node */
304
+ background?: string;
305
+ }
306
+
307
+ export declare interface NodeMapping {
308
+ sourceNodeId: string;
309
+ targetNodeId: string;
310
+ }
311
+
312
+ declare interface NodeMapping_2 {
313
+ sourceNodeId: string;
314
+ targetNodeId: string;
315
+ }
316
+
317
+ export declare function renderCustomGraph(container: HTMLDivElement, json: GraphvizJson, _nodeMapping?: Record<string, NodeMapping_2>, maxDepth?: number | null, includeLesserDepths?: boolean, config?: LayoutConfig, useOrthogonalRendering?: boolean, svgFontSize?: number, debug?: boolean, selectedEdgeId?: number | null, onEdgeSelect?: (edgeIndex: number | null) => void, nodeWidth?: number, nodeHeight?: number, nodeColumnSpacing?: number, enableWheelZoom?: boolean, extra?: RenderExtraOptions): {
318
+ zoomBehavior: d3_2.ZoomBehavior<SVGSVGElement, unknown>;
319
+ svgElement: SVGSVGElement;
320
+ gElement: SVGGElement;
321
+ baseFontSize: number;
322
+ viewBoxWidth: number;
323
+ edges: EdgeInfo[];
324
+ initialTransform: InitialTransform;
325
+ };
326
+
327
+ export declare interface RenderExtraOptions {
328
+ /**
329
+ * Headless (Node / SSR) mode. Skips the d3-zoom attachment and never calls
330
+ * `getBBox`/`getComputedTextLength`; bakes a deterministic initial transform
331
+ * straight onto `<g>` so the SVG can be serialized to a string. Geometry is
332
+ * fully determined by the graphviz JSON, so it matches the browser render.
333
+ */
334
+ headless?: boolean;
335
+ /**
336
+ * Use this exact initial transform instead of measuring the fit via
337
+ * `getBBox`. Pass the `initialTransform` returned from a headless render so
338
+ * the hydrated interactive graph lines up with the SSR'd SVG pixel-for-pixel
339
+ * (no jump on handover). When omitted in non-headless mode, the legacy
340
+ * getBBox-based fit is used (unchanged behavior for existing callers).
341
+ */
342
+ initialTransform?: InitialTransform;
343
+ }
344
+
345
+ /**
346
+ * Setup zoom and pan for graphviz native SVG rendering
347
+ */
348
+ export declare function setupZoomPan(container: HTMLDivElement): void;
349
+
350
+ /**
351
+ * Text element with optional color and background
352
+ */
353
+ export declare interface TextElem {
354
+ /** Text content */
355
+ text: string;
356
+ /** Optional color for the text */
357
+ color?: string;
358
+ /** Optional background color */
359
+ background?: string;
360
+ }
361
+
362
+ export declare function useGraphvizWorker(): UseGraphvizWorkerResult;
363
+
364
+ declare interface UseGraphvizWorkerResult {
365
+ layout: (dot: string) => Promise<string>;
366
+ cancel: () => void;
367
+ isLoading: boolean;
368
+ error: string | null;
369
+ }
370
+
371
+ /**
372
+ * Loading indicator shown during graph layout processing.
373
+ *
374
+ * Uses CSS variables from color.css for theming support.
375
+ */
376
+ export declare function WorkerLoadingIndicator({ onCancel }: WorkerLoadingIndicatorProps): JSX.Element;
377
+
378
+ export declare interface WorkerLoadingIndicatorProps {
379
+ onCancel: () => void;
380
+ }
381
+
382
+ export declare interface WorkerRequest {
383
+ id: string;
384
+ dot: string;
385
+ }
386
+
387
+ export declare interface WorkerResponse {
388
+ id: string;
389
+ success: boolean;
390
+ json?: string;
391
+ error?: string;
392
+ }
393
+
394
+ export { }