@statelyai/layout 0.1.3 → 0.2.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/NOTICE.md +43 -0
- package/README.md +82 -4
- package/dist/elkjs/index.cjs +8 -0
- package/dist/elkjs/index.d.cts +146 -0
- package/dist/elkjs/index.d.mts +42 -39
- package/dist/elkjs/index.mjs +2 -1483
- package/dist/elkjs/main.cjs +17 -0
- package/dist/elkjs/main.d.cts +10 -0
- package/dist/elkjs/main.d.mts +11 -0
- package/dist/elkjs/main.mjs +17 -0
- package/dist/elkjs/worker-api.cjs +3 -0
- package/dist/elkjs/worker-api.d.cts +3 -0
- package/dist/elkjs/worker-api.d.mts +3 -0
- package/dist/elkjs/worker-api.mjs +3 -0
- package/dist/elkjs/worker.cjs +86 -0
- package/dist/elkjs/worker.d.cts +17 -0
- package/dist/elkjs/worker.d.mts +17 -0
- package/dist/elkjs/worker.mjs +86 -0
- package/dist/elkjs-BVnDwnBQ.cjs +1551 -0
- package/dist/elkjs-CFlfkEBz.mjs +1528 -0
- package/dist/{index-8xYkohbz.d.mts → index-BSH2bloA.d.mts} +77 -3
- package/dist/index-CG712jzV.d.cts +1286 -0
- package/dist/index.cjs +188 -0
- package/dist/index.d.cts +77 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +24 -25
- package/dist/layered/index.cjs +38 -0
- package/dist/layered/index.d.cts +2 -0
- package/dist/layered/index.d.mts +1 -1
- package/dist/layered/index.mjs +1 -1
- package/dist/{layered-CoeH9LRO.mjs → layered-Bz2nWmVp.mjs} +2261 -47
- package/dist/layered-Cf9Rn8l7.cjs +12061 -0
- package/dist/layout-engine-BNex9jxg.cjs +712 -0
- package/dist/{spore-BtTSZbb6.mjs → layout-engine-WbC0YjjT.mjs} +159 -5
- package/dist/public-types-B8rAALJq.d.mts +109 -0
- package/dist/public-types-CVB0hXGk.d.cts +109 -0
- package/dist/worker-client-D3HMK33r.cjs +98 -0
- package/dist/worker-client-DAT_z2OR.d.mts +19 -0
- package/dist/worker-client-DVhklF6A.d.cts +19 -0
- package/dist/worker-client-DkwS4sHx.mjs +92 -0
- package/package.json +39 -9
- package/src/authoring/coordinates.ts +106 -0
- package/src/authoring/partial.ts +584 -0
- package/src/authoring/routing.ts +211 -0
- package/src/box.ts +22 -0
- package/src/constraints.ts +222 -0
- package/src/elkjs/index.ts +100 -37
- package/src/elkjs/main.ts +19 -0
- package/src/elkjs/public-types.ts +125 -0
- package/src/elkjs/worker-api.ts +29 -0
- package/src/elkjs/worker-client.ts +138 -0
- package/src/elkjs/worker.ts +117 -0
- package/src/index.ts +13 -0
- package/src/internal/elkjs-compatibility.ts +17 -0
- package/src/internal/layout-engine.ts +126 -0
- package/src/layered/index.ts +31 -3
- package/src/layout.ts +35 -28
- package/src/packing.ts +22 -0
- package/src/random.ts +75 -3
- package/src/types.ts +17 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { B as JavaRandom, I as placePorts, k as getPolylineMidpoint, n as layeredAlgorithm } from "./layered-Bz2nWmVp.mjs";
|
|
2
2
|
import { getNodeSize } from "@statelyai/graph/layout";
|
|
3
3
|
|
|
4
4
|
//#region src/fixed.ts
|
|
@@ -68,6 +68,14 @@ const fixedAlgorithm = {
|
|
|
68
68
|
}
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
+
//#endregion
|
|
72
|
+
//#region src/internal/elkjs-compatibility.ts
|
|
73
|
+
const elkjs0111ResultPolicy = Symbol("elkjs0111ResultPolicy");
|
|
74
|
+
function setElkjs0111ResultPolicy(graph, policy) {
|
|
75
|
+
Object.defineProperty(graph, elkjs0111ResultPolicy, { value: policy });
|
|
76
|
+
return graph;
|
|
77
|
+
}
|
|
78
|
+
|
|
71
79
|
//#endregion
|
|
72
80
|
//#region src/box.ts
|
|
73
81
|
function getPadding$3(value) {
|
|
@@ -193,6 +201,25 @@ const boxAlgorithm = {
|
|
|
193
201
|
return getBoxLayout(graph, options ?? {});
|
|
194
202
|
}
|
|
195
203
|
};
|
|
204
|
+
/** Pinned behavior used only by the elkjs 0.11.1 compatibility adapter. */
|
|
205
|
+
const elkjs0111BoxAlgorithm = {
|
|
206
|
+
...boxAlgorithm,
|
|
207
|
+
layout(graph, options = {}) {
|
|
208
|
+
const result = getBoxLayout(graph, options);
|
|
209
|
+
const padding = getPadding$3(options.padding);
|
|
210
|
+
return setElkjs0111ResultPolicy(result, {
|
|
211
|
+
providerBounds: result.nodes.length === 0 ? {
|
|
212
|
+
width: 0,
|
|
213
|
+
height: 0
|
|
214
|
+
} : {
|
|
215
|
+
width: Math.max(...result.nodes.map((node) => node.x + node.width)) + padding.right,
|
|
216
|
+
height: Math.max(...result.nodes.map((node) => node.y + node.height)) + padding.bottom
|
|
217
|
+
},
|
|
218
|
+
preserveEdgeSections: true,
|
|
219
|
+
skipBoundsNormalization: true
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
};
|
|
196
223
|
|
|
197
224
|
//#endregion
|
|
198
225
|
//#region src/packing.ts
|
|
@@ -259,9 +286,36 @@ const rectanglePackingAlgorithm = {
|
|
|
259
286
|
return getRectanglePackingLayout(graph, options ?? {});
|
|
260
287
|
}
|
|
261
288
|
};
|
|
289
|
+
/** Pinned output policy used only by the elkjs 0.11.1 compatibility adapter. */
|
|
290
|
+
const elkjs0111RectanglePackingAlgorithm = {
|
|
291
|
+
...rectanglePackingAlgorithm,
|
|
292
|
+
layout(graph, options = {}) {
|
|
293
|
+
const result = getRectanglePackingLayout(graph, options);
|
|
294
|
+
const padding = getPadding$2(options.padding);
|
|
295
|
+
return setElkjs0111ResultPolicy(result, {
|
|
296
|
+
providerBounds: result.nodes.length === 0 ? {
|
|
297
|
+
width: 0,
|
|
298
|
+
height: 0
|
|
299
|
+
} : {
|
|
300
|
+
width: Math.max(...result.nodes.map((node) => node.x + node.width)) + padding.right,
|
|
301
|
+
height: Math.max(...result.nodes.map((node) => node.y + node.height)) + padding.bottom
|
|
302
|
+
},
|
|
303
|
+
preserveEdgeSections: true,
|
|
304
|
+
skipBoundsNormalization: true
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
};
|
|
262
308
|
|
|
263
309
|
//#endregion
|
|
264
310
|
//#region src/random.ts
|
|
311
|
+
const nativeBehavior = {
|
|
312
|
+
elkjs0111EdgeTargetBug: false,
|
|
313
|
+
preserveProviderBounds: false
|
|
314
|
+
};
|
|
315
|
+
const elkjs0111Behavior = {
|
|
316
|
+
elkjs0111EdgeTargetBug: true,
|
|
317
|
+
preserveProviderBounds: true
|
|
318
|
+
};
|
|
265
319
|
function getPadding$1(value) {
|
|
266
320
|
if (typeof value === "number") return {
|
|
267
321
|
top: value,
|
|
@@ -299,6 +353,9 @@ function borderPoint(source, target) {
|
|
|
299
353
|
}
|
|
300
354
|
/** Seeded random distribution using Java's 48-bit `Random` sequence. */
|
|
301
355
|
function getRandomLayout(graph, options = {}) {
|
|
356
|
+
return getRandomLayoutWithBehavior(graph, options, nativeBehavior);
|
|
357
|
+
}
|
|
358
|
+
function getRandomLayoutWithBehavior(graph, options, behavior) {
|
|
302
359
|
if (graph.nodes.length === 0) return getFixedLayout(graph, options);
|
|
303
360
|
const random = new JavaRandom(options.seed && options.seed !== 0 ? options.seed : Date.now());
|
|
304
361
|
const aspectRatio = Math.fround(options.aspectRatio ?? 1.6);
|
|
@@ -328,10 +385,49 @@ function getRandomLayout(graph, options = {}) {
|
|
|
328
385
|
const nodeById = new Map(nodes.map((node) => [node.id, node]));
|
|
329
386
|
const totalWidth = drawWidth + padding.left + padding.right;
|
|
330
387
|
const totalHeight = drawHeight + padding.top + padding.bottom;
|
|
331
|
-
const
|
|
388
|
+
const layoutEdge = (edge) => {
|
|
332
389
|
const source = nodeById.get(edge.sourceId);
|
|
333
390
|
const target = nodeById.get(edge.targetId);
|
|
334
391
|
if (!source || !target) return edge;
|
|
392
|
+
if (behavior.elkjs0111EdgeTargetBug) {
|
|
393
|
+
const start$1 = {
|
|
394
|
+
x: source.x + source.width,
|
|
395
|
+
y: source.y + source.height / 2
|
|
396
|
+
};
|
|
397
|
+
const end$1 = {
|
|
398
|
+
x: source.x + source.width / 2,
|
|
399
|
+
y: source.y + source.height
|
|
400
|
+
};
|
|
401
|
+
const bendCount$1 = random.nextInt(5) + 1;
|
|
402
|
+
const xDifference = end$1.x - start$1.x;
|
|
403
|
+
const yDifference = end$1.y - start$1.y;
|
|
404
|
+
const maximumDeviation$1 = Math.hypot(xDifference, yDifference) * Math.fround(.2);
|
|
405
|
+
const xIncrement = xDifference / (bendCount$1 + 1);
|
|
406
|
+
const yIncrement = yDifference / (bendCount$1 + 1);
|
|
407
|
+
let x = start$1.x;
|
|
408
|
+
let y = start$1.y;
|
|
409
|
+
const points$1 = [start$1];
|
|
410
|
+
for (let index = 0; index < bendCount$1; index++) {
|
|
411
|
+
x += xIncrement;
|
|
412
|
+
y += yIncrement;
|
|
413
|
+
let randomX = x + random.nextFloat() * maximumDeviation$1 - maximumDeviation$1 / 2;
|
|
414
|
+
if (randomX < 0) randomX = 1;
|
|
415
|
+
else if (randomX > totalWidth) randomX = totalWidth - 1;
|
|
416
|
+
let randomY = y + random.nextFloat() * maximumDeviation$1 - maximumDeviation$1 / 2;
|
|
417
|
+
if (randomY < 0) randomY = 1;
|
|
418
|
+
else if (randomY > totalHeight) randomY = totalHeight - 1;
|
|
419
|
+
points$1.push({
|
|
420
|
+
x: randomX,
|
|
421
|
+
y: randomY
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
points$1.push(end$1);
|
|
425
|
+
return {
|
|
426
|
+
...edge,
|
|
427
|
+
points: points$1,
|
|
428
|
+
routing: "polyline"
|
|
429
|
+
};
|
|
430
|
+
}
|
|
335
431
|
const start = borderPoint(source, target);
|
|
336
432
|
const end = borderPoint(target, source);
|
|
337
433
|
const bendCount = random.nextInt(5) + (source === target ? 1 : 0);
|
|
@@ -350,12 +446,18 @@ function getRandomLayout(graph, options = {}) {
|
|
|
350
446
|
points,
|
|
351
447
|
routing: "polyline"
|
|
352
448
|
};
|
|
353
|
-
}
|
|
354
|
-
|
|
449
|
+
};
|
|
450
|
+
const edges = behavior.elkjs0111EdgeTargetBug ? graph.nodes.flatMap((node) => graph.edges.filter((edge) => edge.sourceId === node.id).map(layoutEdge)) : graph.edges.map(layoutEdge);
|
|
451
|
+
const result = getFixedLayout({
|
|
355
452
|
...graph,
|
|
356
453
|
nodes,
|
|
357
454
|
edges
|
|
358
455
|
}, { direction: options.direction ?? graph.direction });
|
|
456
|
+
if (behavior.preserveProviderBounds) setElkjs0111ResultPolicy(result, { providerBounds: {
|
|
457
|
+
width: drawWidth + 2 * (padding.left + padding.right),
|
|
458
|
+
height: drawHeight + 2 * (padding.top + padding.bottom)
|
|
459
|
+
} });
|
|
460
|
+
return result;
|
|
359
461
|
}
|
|
360
462
|
const randomAlgorithm = {
|
|
361
463
|
id: "random",
|
|
@@ -371,6 +473,13 @@ const randomAlgorithm = {
|
|
|
371
473
|
return getRandomLayout(graph, options ?? {});
|
|
372
474
|
}
|
|
373
475
|
};
|
|
476
|
+
/** Pinned behavior used only by the elkjs 0.11.1 compatibility adapter. */
|
|
477
|
+
const elkjs0111RandomAlgorithm = {
|
|
478
|
+
...randomAlgorithm,
|
|
479
|
+
layout(graph, options) {
|
|
480
|
+
return getRandomLayoutWithBehavior(graph, options ?? {}, elkjs0111Behavior);
|
|
481
|
+
}
|
|
482
|
+
};
|
|
374
483
|
|
|
375
484
|
//#endregion
|
|
376
485
|
//#region src/spore.ts
|
|
@@ -454,4 +563,49 @@ const sporeCompactionAlgorithm = algorithm("sporeCompaction", true);
|
|
|
454
563
|
const sporeOverlapRemovalAlgorithm = algorithm("sporeOverlap", false);
|
|
455
564
|
|
|
456
565
|
//#endregion
|
|
457
|
-
|
|
566
|
+
//#region src/internal/layout-engine.ts
|
|
567
|
+
const builtInLayoutAlgorithms = {
|
|
568
|
+
box: boxAlgorithm,
|
|
569
|
+
fixed: fixedAlgorithm,
|
|
570
|
+
layered: layeredAlgorithm,
|
|
571
|
+
random: randomAlgorithm,
|
|
572
|
+
rectpacking: rectanglePackingAlgorithm,
|
|
573
|
+
sporeCompaction: sporeCompactionAlgorithm,
|
|
574
|
+
sporeOverlap: sporeOverlapRemovalAlgorithm
|
|
575
|
+
};
|
|
576
|
+
const elkjs0111LayoutAlgorithms = {
|
|
577
|
+
...builtInLayoutAlgorithms,
|
|
578
|
+
box: elkjs0111BoxAlgorithm,
|
|
579
|
+
random: elkjs0111RandomAlgorithm,
|
|
580
|
+
rectpacking: elkjs0111RectanglePackingAlgorithm
|
|
581
|
+
};
|
|
582
|
+
function getBuiltInLayoutAlgorithm(id) {
|
|
583
|
+
if (!Object.hasOwn(builtInLayoutAlgorithms, id)) return void 0;
|
|
584
|
+
return builtInLayoutAlgorithms[id];
|
|
585
|
+
}
|
|
586
|
+
/** Execute one algorithm through the shared engine seam. */
|
|
587
|
+
function executeLayoutAlgorithm({ algorithm: algorithm$1, graph, options, context }) {
|
|
588
|
+
return algorithm$1.layout(graph, options, context);
|
|
589
|
+
}
|
|
590
|
+
function createDirectExecutionContext() {
|
|
591
|
+
return {
|
|
592
|
+
scope: { mode: "full" },
|
|
593
|
+
diagnostics: [],
|
|
594
|
+
measurePhase(_id, run) {
|
|
595
|
+
return run();
|
|
596
|
+
},
|
|
597
|
+
throwIfAborted() {}
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
/** Execute through the pinned elkjs 0.11.1 compatibility policy. */
|
|
601
|
+
function executeElkjs0111Layout({ algorithm: algorithm$1, graph, options }) {
|
|
602
|
+
return executeLayoutAlgorithm({
|
|
603
|
+
algorithm: elkjs0111LayoutAlgorithms[algorithm$1],
|
|
604
|
+
graph,
|
|
605
|
+
options,
|
|
606
|
+
context: createDirectExecutionContext()
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
//#endregion
|
|
611
|
+
export { getFixedLayout as _, getSporeCompactionLayout as a, sporeOverlapRemovalAlgorithm as c, getRectanglePackingLayout as d, rectanglePackingAlgorithm as f, fixedAlgorithm as g, elkjs0111ResultPolicy as h, getBuiltInLayoutAlgorithm as i, getRandomLayout as l, getBoxLayout as m, executeElkjs0111Layout as n, getSporeOverlapRemovalLayout as o, boxAlgorithm as p, executeLayoutAlgorithm as r, sporeCompactionAlgorithm as s, builtInLayoutAlgorithms as t, randomAlgorithm as u };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
//#region src/elkjs/public-types.d.ts
|
|
2
|
+
/*******************************************************************************
|
|
3
|
+
* Copyright (c) 2019 TypeFox and others.
|
|
4
|
+
*
|
|
5
|
+
* Adapted from elkjs 0.11.1 typings/elk-api.d.ts.
|
|
6
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
7
|
+
*******************************************************************************/
|
|
8
|
+
interface LayoutOptions {
|
|
9
|
+
[key: string]: string;
|
|
10
|
+
}
|
|
11
|
+
interface ElkPoint {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
}
|
|
15
|
+
interface ElkGraphElement {
|
|
16
|
+
id?: string;
|
|
17
|
+
labels?: ElkLabel[];
|
|
18
|
+
layoutOptions?: LayoutOptions;
|
|
19
|
+
}
|
|
20
|
+
interface ElkShape extends ElkGraphElement {
|
|
21
|
+
x?: number;
|
|
22
|
+
y?: number;
|
|
23
|
+
width?: number;
|
|
24
|
+
height?: number;
|
|
25
|
+
}
|
|
26
|
+
interface ElkNode extends ElkShape {
|
|
27
|
+
id: string;
|
|
28
|
+
children?: ElkNode[];
|
|
29
|
+
ports?: ElkPort[];
|
|
30
|
+
edges?: ElkExtendedEdge[];
|
|
31
|
+
}
|
|
32
|
+
interface ElkPort extends ElkShape {
|
|
33
|
+
id: string;
|
|
34
|
+
}
|
|
35
|
+
interface ElkLabel extends ElkShape {
|
|
36
|
+
text?: string;
|
|
37
|
+
}
|
|
38
|
+
/** @deprecated Use ElkExtendedEdge directly. */
|
|
39
|
+
interface ElkEdge extends ElkGraphElement {
|
|
40
|
+
id: string;
|
|
41
|
+
container?: string;
|
|
42
|
+
junctionPoints?: ElkPoint[];
|
|
43
|
+
}
|
|
44
|
+
/** @deprecated Use ElkExtendedEdge instead. */
|
|
45
|
+
interface ElkPrimitiveEdge extends ElkEdge {
|
|
46
|
+
source: string;
|
|
47
|
+
sourcePort?: string;
|
|
48
|
+
target: string;
|
|
49
|
+
targetPort?: string;
|
|
50
|
+
sourcePoint?: ElkPoint;
|
|
51
|
+
targetPoint?: ElkPoint;
|
|
52
|
+
bendPoints?: ElkPoint[];
|
|
53
|
+
}
|
|
54
|
+
interface ElkExtendedEdge extends ElkEdge {
|
|
55
|
+
sources: string[];
|
|
56
|
+
targets: string[];
|
|
57
|
+
sections?: ElkEdgeSection[];
|
|
58
|
+
}
|
|
59
|
+
interface ElkEdgeSection extends ElkGraphElement {
|
|
60
|
+
id: string;
|
|
61
|
+
startPoint: ElkPoint;
|
|
62
|
+
endPoint: ElkPoint;
|
|
63
|
+
bendPoints?: ElkPoint[];
|
|
64
|
+
incomingShape?: string;
|
|
65
|
+
outgoingShape?: string;
|
|
66
|
+
incomingSections?: string[];
|
|
67
|
+
outgoingSections?: string[];
|
|
68
|
+
}
|
|
69
|
+
interface ElkLayoutArguments {
|
|
70
|
+
layoutOptions?: LayoutOptions;
|
|
71
|
+
logging?: boolean;
|
|
72
|
+
measureExecutionTime?: boolean;
|
|
73
|
+
}
|
|
74
|
+
interface ElkCommonDescription {
|
|
75
|
+
id?: string;
|
|
76
|
+
name?: string;
|
|
77
|
+
description?: string;
|
|
78
|
+
}
|
|
79
|
+
interface ElkLayoutAlgorithmDescription extends ElkCommonDescription {
|
|
80
|
+
category?: string;
|
|
81
|
+
knownOptions?: string[];
|
|
82
|
+
supportedFeatures?: string[];
|
|
83
|
+
}
|
|
84
|
+
interface ElkLayoutOptionDescription extends ElkCommonDescription {
|
|
85
|
+
group?: string;
|
|
86
|
+
type?: string;
|
|
87
|
+
targets?: string[];
|
|
88
|
+
}
|
|
89
|
+
interface ElkLayoutCategoryDescription extends ElkCommonDescription {
|
|
90
|
+
knownLayouters?: string[];
|
|
91
|
+
}
|
|
92
|
+
type LaidOutElkNode<T extends ElkNode> = Omit<T, "children"> & {
|
|
93
|
+
children?: Array<NonNullable<T["children"]>[number] & ElkNode>;
|
|
94
|
+
};
|
|
95
|
+
interface ELK {
|
|
96
|
+
layout<T extends ElkNode>(graph: T, args?: ElkLayoutArguments): Promise<LaidOutElkNode<T>>;
|
|
97
|
+
knownLayoutAlgorithms(): Promise<ElkLayoutAlgorithmDescription[]>;
|
|
98
|
+
knownLayoutOptions(): Promise<ElkLayoutOptionDescription[]>;
|
|
99
|
+
knownLayoutCategories(): Promise<ElkLayoutCategoryDescription[]>;
|
|
100
|
+
terminateWorker(): void;
|
|
101
|
+
}
|
|
102
|
+
interface ELKConstructorArguments {
|
|
103
|
+
defaultLayoutOptions?: LayoutOptions;
|
|
104
|
+
algorithms?: string[];
|
|
105
|
+
workerUrl?: string;
|
|
106
|
+
workerFactory?: (url?: string) => Worker;
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
export { ElkShape as _, ElkEdgeSection as a, ElkLabel as c, ElkLayoutCategoryDescription as d, ElkLayoutOptionDescription as f, ElkPrimitiveEdge as g, ElkPort as h, ElkEdge as i, ElkLayoutAlgorithmDescription as l, ElkPoint as m, ELKConstructorArguments as n, ElkExtendedEdge as o, ElkNode as p, ElkCommonDescription as r, ElkGraphElement as s, ELK as t, ElkLayoutArguments as u, LaidOutElkNode as v, LayoutOptions as y };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
//#region src/elkjs/public-types.d.ts
|
|
2
|
+
/*******************************************************************************
|
|
3
|
+
* Copyright (c) 2019 TypeFox and others.
|
|
4
|
+
*
|
|
5
|
+
* Adapted from elkjs 0.11.1 typings/elk-api.d.ts.
|
|
6
|
+
* SPDX-License-Identifier: EPL-2.0
|
|
7
|
+
*******************************************************************************/
|
|
8
|
+
interface LayoutOptions {
|
|
9
|
+
[key: string]: string;
|
|
10
|
+
}
|
|
11
|
+
interface ElkPoint {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
}
|
|
15
|
+
interface ElkGraphElement {
|
|
16
|
+
id?: string;
|
|
17
|
+
labels?: ElkLabel[];
|
|
18
|
+
layoutOptions?: LayoutOptions;
|
|
19
|
+
}
|
|
20
|
+
interface ElkShape extends ElkGraphElement {
|
|
21
|
+
x?: number;
|
|
22
|
+
y?: number;
|
|
23
|
+
width?: number;
|
|
24
|
+
height?: number;
|
|
25
|
+
}
|
|
26
|
+
interface ElkNode extends ElkShape {
|
|
27
|
+
id: string;
|
|
28
|
+
children?: ElkNode[];
|
|
29
|
+
ports?: ElkPort[];
|
|
30
|
+
edges?: ElkExtendedEdge[];
|
|
31
|
+
}
|
|
32
|
+
interface ElkPort extends ElkShape {
|
|
33
|
+
id: string;
|
|
34
|
+
}
|
|
35
|
+
interface ElkLabel extends ElkShape {
|
|
36
|
+
text?: string;
|
|
37
|
+
}
|
|
38
|
+
/** @deprecated Use ElkExtendedEdge directly. */
|
|
39
|
+
interface ElkEdge extends ElkGraphElement {
|
|
40
|
+
id: string;
|
|
41
|
+
container?: string;
|
|
42
|
+
junctionPoints?: ElkPoint[];
|
|
43
|
+
}
|
|
44
|
+
/** @deprecated Use ElkExtendedEdge instead. */
|
|
45
|
+
interface ElkPrimitiveEdge extends ElkEdge {
|
|
46
|
+
source: string;
|
|
47
|
+
sourcePort?: string;
|
|
48
|
+
target: string;
|
|
49
|
+
targetPort?: string;
|
|
50
|
+
sourcePoint?: ElkPoint;
|
|
51
|
+
targetPoint?: ElkPoint;
|
|
52
|
+
bendPoints?: ElkPoint[];
|
|
53
|
+
}
|
|
54
|
+
interface ElkExtendedEdge extends ElkEdge {
|
|
55
|
+
sources: string[];
|
|
56
|
+
targets: string[];
|
|
57
|
+
sections?: ElkEdgeSection[];
|
|
58
|
+
}
|
|
59
|
+
interface ElkEdgeSection extends ElkGraphElement {
|
|
60
|
+
id: string;
|
|
61
|
+
startPoint: ElkPoint;
|
|
62
|
+
endPoint: ElkPoint;
|
|
63
|
+
bendPoints?: ElkPoint[];
|
|
64
|
+
incomingShape?: string;
|
|
65
|
+
outgoingShape?: string;
|
|
66
|
+
incomingSections?: string[];
|
|
67
|
+
outgoingSections?: string[];
|
|
68
|
+
}
|
|
69
|
+
interface ElkLayoutArguments {
|
|
70
|
+
layoutOptions?: LayoutOptions;
|
|
71
|
+
logging?: boolean;
|
|
72
|
+
measureExecutionTime?: boolean;
|
|
73
|
+
}
|
|
74
|
+
interface ElkCommonDescription {
|
|
75
|
+
id?: string;
|
|
76
|
+
name?: string;
|
|
77
|
+
description?: string;
|
|
78
|
+
}
|
|
79
|
+
interface ElkLayoutAlgorithmDescription extends ElkCommonDescription {
|
|
80
|
+
category?: string;
|
|
81
|
+
knownOptions?: string[];
|
|
82
|
+
supportedFeatures?: string[];
|
|
83
|
+
}
|
|
84
|
+
interface ElkLayoutOptionDescription extends ElkCommonDescription {
|
|
85
|
+
group?: string;
|
|
86
|
+
type?: string;
|
|
87
|
+
targets?: string[];
|
|
88
|
+
}
|
|
89
|
+
interface ElkLayoutCategoryDescription extends ElkCommonDescription {
|
|
90
|
+
knownLayouters?: string[];
|
|
91
|
+
}
|
|
92
|
+
type LaidOutElkNode<T extends ElkNode> = Omit<T, "children"> & {
|
|
93
|
+
children?: Array<NonNullable<T["children"]>[number] & ElkNode>;
|
|
94
|
+
};
|
|
95
|
+
interface ELK {
|
|
96
|
+
layout<T extends ElkNode>(graph: T, args?: ElkLayoutArguments): Promise<LaidOutElkNode<T>>;
|
|
97
|
+
knownLayoutAlgorithms(): Promise<ElkLayoutAlgorithmDescription[]>;
|
|
98
|
+
knownLayoutOptions(): Promise<ElkLayoutOptionDescription[]>;
|
|
99
|
+
knownLayoutCategories(): Promise<ElkLayoutCategoryDescription[]>;
|
|
100
|
+
terminateWorker(): void;
|
|
101
|
+
}
|
|
102
|
+
interface ELKConstructorArguments {
|
|
103
|
+
defaultLayoutOptions?: LayoutOptions;
|
|
104
|
+
algorithms?: string[];
|
|
105
|
+
workerUrl?: string;
|
|
106
|
+
workerFactory?: (url?: string) => Worker;
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
export { ElkShape as _, ElkEdgeSection as a, ElkLabel as c, ElkLayoutCategoryDescription as d, ElkLayoutOptionDescription as f, ElkPrimitiveEdge as g, ElkPort as h, ElkEdge as i, ElkLayoutAlgorithmDescription as l, ElkPoint as m, ELKConstructorArguments as n, ElkExtendedEdge as o, ElkNode as p, ElkCommonDescription as r, ElkGraphElement as s, ELK as t, ElkLayoutArguments as u, LaidOutElkNode as v, LayoutOptions as y };
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
|
|
2
|
+
//#region src/elkjs/worker-client.ts
|
|
3
|
+
var PromisedWorker = class {
|
|
4
|
+
#worker;
|
|
5
|
+
#resolvers = /* @__PURE__ */ new Map();
|
|
6
|
+
#id = 0;
|
|
7
|
+
#failure;
|
|
8
|
+
constructor(worker) {
|
|
9
|
+
this.#worker = worker;
|
|
10
|
+
worker.onmessage = (event) => {
|
|
11
|
+
const resolver = this.#resolvers.get(event.data.id);
|
|
12
|
+
if (!resolver) return;
|
|
13
|
+
this.#resolvers.delete(event.data.id);
|
|
14
|
+
if (event.data.error !== void 0) resolver.reject(event.data.error);
|
|
15
|
+
else resolver.resolve(event.data.data);
|
|
16
|
+
};
|
|
17
|
+
worker.onerror = (event) => this.#rejectAll(event.error ?? event.message);
|
|
18
|
+
worker.onmessageerror = (event) => this.#rejectAll(event.data);
|
|
19
|
+
}
|
|
20
|
+
postMessage(message) {
|
|
21
|
+
if (this.#failure) return Promise.reject(this.#failure);
|
|
22
|
+
const id = this.#id++;
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
this.#resolvers.set(id, {
|
|
25
|
+
resolve,
|
|
26
|
+
reject
|
|
27
|
+
});
|
|
28
|
+
this.#worker.postMessage({
|
|
29
|
+
...message,
|
|
30
|
+
id
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
terminate() {
|
|
35
|
+
this.#worker.terminate();
|
|
36
|
+
}
|
|
37
|
+
#rejectAll(reason) {
|
|
38
|
+
const error = reason instanceof Error ? reason : new Error(String(reason ?? "Worker failed"));
|
|
39
|
+
this.#failure = error;
|
|
40
|
+
for (const resolver of this.#resolvers.values()) resolver.reject(error);
|
|
41
|
+
this.#resolvers.clear();
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var WorkerELK = class {
|
|
45
|
+
#defaultLayoutOptions;
|
|
46
|
+
#worker;
|
|
47
|
+
#ready;
|
|
48
|
+
constructor({ defaultLayoutOptions = {}, algorithms, workerFactory, workerUrl } = {}) {
|
|
49
|
+
if (workerUrl === void 0 && workerFactory === void 0) throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'.");
|
|
50
|
+
const worker = (workerFactory ?? ((url) => new globalThis.Worker(url)))(workerUrl);
|
|
51
|
+
if (!worker || typeof worker.postMessage !== "function") throw new TypeError("Created worker does not provide the required 'postMessage' function.");
|
|
52
|
+
this.#defaultLayoutOptions = defaultLayoutOptions;
|
|
53
|
+
this.#worker = new PromisedWorker(worker);
|
|
54
|
+
this.#ready = this.#worker.postMessage({
|
|
55
|
+
cmd: "register",
|
|
56
|
+
algorithms
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
async layout(graph, args = {}) {
|
|
60
|
+
if (!graph) throw new Error("Missing mandatory parameter 'graph'.");
|
|
61
|
+
await this.#ready;
|
|
62
|
+
return this.#worker.postMessage({
|
|
63
|
+
cmd: "layout",
|
|
64
|
+
graph,
|
|
65
|
+
layoutOptions: {
|
|
66
|
+
...this.#defaultLayoutOptions,
|
|
67
|
+
...args.layoutOptions
|
|
68
|
+
},
|
|
69
|
+
options: {
|
|
70
|
+
logging: args.logging ?? false,
|
|
71
|
+
measureExecutionTime: args.measureExecutionTime ?? false
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async knownLayoutAlgorithms() {
|
|
76
|
+
await this.#ready;
|
|
77
|
+
return this.#worker.postMessage({ cmd: "algorithms" });
|
|
78
|
+
}
|
|
79
|
+
async knownLayoutOptions() {
|
|
80
|
+
await this.#ready;
|
|
81
|
+
return this.#worker.postMessage({ cmd: "options" });
|
|
82
|
+
}
|
|
83
|
+
async knownLayoutCategories() {
|
|
84
|
+
await this.#ready;
|
|
85
|
+
return this.#worker.postMessage({ cmd: "categories" });
|
|
86
|
+
}
|
|
87
|
+
terminateWorker() {
|
|
88
|
+
this.#worker.terminate();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
//#endregion
|
|
93
|
+
Object.defineProperty(exports, 'WorkerELK', {
|
|
94
|
+
enumerable: true,
|
|
95
|
+
get: function () {
|
|
96
|
+
return WorkerELK;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { d as ElkLayoutCategoryDescription, f as ElkLayoutOptionDescription, l as ElkLayoutAlgorithmDescription, n as ELKConstructorArguments, p as ElkNode, t as ELK, u as ElkLayoutArguments, v as LaidOutElkNode } from "./public-types-B8rAALJq.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/elkjs/worker-client.d.ts
|
|
4
|
+
declare class WorkerELK implements ELK {
|
|
5
|
+
#private;
|
|
6
|
+
constructor({
|
|
7
|
+
defaultLayoutOptions,
|
|
8
|
+
algorithms,
|
|
9
|
+
workerFactory,
|
|
10
|
+
workerUrl
|
|
11
|
+
}?: ELKConstructorArguments);
|
|
12
|
+
layout<T extends ElkNode>(graph: T, args?: ElkLayoutArguments): Promise<LaidOutElkNode<T>>;
|
|
13
|
+
knownLayoutAlgorithms(): Promise<ElkLayoutAlgorithmDescription[]>;
|
|
14
|
+
knownLayoutOptions(): Promise<ElkLayoutOptionDescription[]>;
|
|
15
|
+
knownLayoutCategories(): Promise<ElkLayoutCategoryDescription[]>;
|
|
16
|
+
terminateWorker(): void;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { WorkerELK as t };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { d as ElkLayoutCategoryDescription, f as ElkLayoutOptionDescription, l as ElkLayoutAlgorithmDescription, n as ELKConstructorArguments, p as ElkNode, t as ELK, u as ElkLayoutArguments, v as LaidOutElkNode } from "./public-types-CVB0hXGk.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/elkjs/worker-client.d.ts
|
|
4
|
+
declare class WorkerELK implements ELK {
|
|
5
|
+
#private;
|
|
6
|
+
constructor({
|
|
7
|
+
defaultLayoutOptions,
|
|
8
|
+
algorithms,
|
|
9
|
+
workerFactory,
|
|
10
|
+
workerUrl
|
|
11
|
+
}?: ELKConstructorArguments);
|
|
12
|
+
layout<T extends ElkNode>(graph: T, args?: ElkLayoutArguments): Promise<LaidOutElkNode<T>>;
|
|
13
|
+
knownLayoutAlgorithms(): Promise<ElkLayoutAlgorithmDescription[]>;
|
|
14
|
+
knownLayoutOptions(): Promise<ElkLayoutOptionDescription[]>;
|
|
15
|
+
knownLayoutCategories(): Promise<ElkLayoutCategoryDescription[]>;
|
|
16
|
+
terminateWorker(): void;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { WorkerELK as t };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
//#region src/elkjs/worker-client.ts
|
|
2
|
+
var PromisedWorker = class {
|
|
3
|
+
#worker;
|
|
4
|
+
#resolvers = /* @__PURE__ */ new Map();
|
|
5
|
+
#id = 0;
|
|
6
|
+
#failure;
|
|
7
|
+
constructor(worker) {
|
|
8
|
+
this.#worker = worker;
|
|
9
|
+
worker.onmessage = (event) => {
|
|
10
|
+
const resolver = this.#resolvers.get(event.data.id);
|
|
11
|
+
if (!resolver) return;
|
|
12
|
+
this.#resolvers.delete(event.data.id);
|
|
13
|
+
if (event.data.error !== void 0) resolver.reject(event.data.error);
|
|
14
|
+
else resolver.resolve(event.data.data);
|
|
15
|
+
};
|
|
16
|
+
worker.onerror = (event) => this.#rejectAll(event.error ?? event.message);
|
|
17
|
+
worker.onmessageerror = (event) => this.#rejectAll(event.data);
|
|
18
|
+
}
|
|
19
|
+
postMessage(message) {
|
|
20
|
+
if (this.#failure) return Promise.reject(this.#failure);
|
|
21
|
+
const id = this.#id++;
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
this.#resolvers.set(id, {
|
|
24
|
+
resolve,
|
|
25
|
+
reject
|
|
26
|
+
});
|
|
27
|
+
this.#worker.postMessage({
|
|
28
|
+
...message,
|
|
29
|
+
id
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
terminate() {
|
|
34
|
+
this.#worker.terminate();
|
|
35
|
+
}
|
|
36
|
+
#rejectAll(reason) {
|
|
37
|
+
const error = reason instanceof Error ? reason : new Error(String(reason ?? "Worker failed"));
|
|
38
|
+
this.#failure = error;
|
|
39
|
+
for (const resolver of this.#resolvers.values()) resolver.reject(error);
|
|
40
|
+
this.#resolvers.clear();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
var WorkerELK = class {
|
|
44
|
+
#defaultLayoutOptions;
|
|
45
|
+
#worker;
|
|
46
|
+
#ready;
|
|
47
|
+
constructor({ defaultLayoutOptions = {}, algorithms, workerFactory, workerUrl } = {}) {
|
|
48
|
+
if (workerUrl === void 0 && workerFactory === void 0) throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'.");
|
|
49
|
+
const worker = (workerFactory ?? ((url) => new globalThis.Worker(url)))(workerUrl);
|
|
50
|
+
if (!worker || typeof worker.postMessage !== "function") throw new TypeError("Created worker does not provide the required 'postMessage' function.");
|
|
51
|
+
this.#defaultLayoutOptions = defaultLayoutOptions;
|
|
52
|
+
this.#worker = new PromisedWorker(worker);
|
|
53
|
+
this.#ready = this.#worker.postMessage({
|
|
54
|
+
cmd: "register",
|
|
55
|
+
algorithms
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
async layout(graph, args = {}) {
|
|
59
|
+
if (!graph) throw new Error("Missing mandatory parameter 'graph'.");
|
|
60
|
+
await this.#ready;
|
|
61
|
+
return this.#worker.postMessage({
|
|
62
|
+
cmd: "layout",
|
|
63
|
+
graph,
|
|
64
|
+
layoutOptions: {
|
|
65
|
+
...this.#defaultLayoutOptions,
|
|
66
|
+
...args.layoutOptions
|
|
67
|
+
},
|
|
68
|
+
options: {
|
|
69
|
+
logging: args.logging ?? false,
|
|
70
|
+
measureExecutionTime: args.measureExecutionTime ?? false
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async knownLayoutAlgorithms() {
|
|
75
|
+
await this.#ready;
|
|
76
|
+
return this.#worker.postMessage({ cmd: "algorithms" });
|
|
77
|
+
}
|
|
78
|
+
async knownLayoutOptions() {
|
|
79
|
+
await this.#ready;
|
|
80
|
+
return this.#worker.postMessage({ cmd: "options" });
|
|
81
|
+
}
|
|
82
|
+
async knownLayoutCategories() {
|
|
83
|
+
await this.#ready;
|
|
84
|
+
return this.#worker.postMessage({ cmd: "categories" });
|
|
85
|
+
}
|
|
86
|
+
terminateWorker() {
|
|
87
|
+
this.#worker.terminate();
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
export { WorkerELK as t };
|