@ts-graphviz/common 0.0.0-pr956-20240225073457

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/src/models.ts ADDED
@@ -0,0 +1,789 @@
1
+ import type {
2
+ Attribute,
3
+ AttributeKey,
4
+ ClusterSubgraphAttributeKey,
5
+ EdgeAttributeKey,
6
+ GraphAttributeKey,
7
+ NodeAttributeKey,
8
+ SubgraphAttributeKey,
9
+ } from './attribute.js';
10
+ import { ModelsContext } from './models-context.js';
11
+ import type { Compass } from './types.js';
12
+
13
+ /**
14
+ * ASTType is an enumeration of the different types of nodes that can be found in an AST(Abstract Syntax Tree ).
15
+ * @group Models
16
+ */
17
+ export type ASTType =
18
+ | 'Literal'
19
+ | 'Dot'
20
+ | 'Graph'
21
+ | 'Attribute'
22
+ | 'Comment'
23
+ | 'AttributeList'
24
+ | 'NodeRef'
25
+ | 'NodeRefGroup'
26
+ | 'Edge'
27
+ | 'Node'
28
+ | 'Subgraph';
29
+
30
+ /**
31
+ * Objects that can be Edge destinations satisfy this interface.
32
+ * @group Models
33
+ */
34
+ export type NodeRef = NodeModel | ForwardRefNode;
35
+
36
+ /**
37
+ * @group Models
38
+ */
39
+ export type NodeRefGroup = NodeRef[];
40
+
41
+ /**
42
+ * string or an object implementing EdgeTarget.
43
+ * @group Models
44
+ */
45
+ export type NodeRefLike = NodeRef | string;
46
+
47
+ /**
48
+ * @group Models
49
+ */
50
+ export type NodeRefGroupLike = NodeRefLike[];
51
+
52
+ /**
53
+ * @group Models
54
+ */
55
+ export type EdgeTarget = NodeRef | NodeRefGroup;
56
+
57
+ /**
58
+ * @group Models
59
+ */
60
+ export type EdgeTargetLike = NodeRefLike | NodeRefGroupLike;
61
+
62
+ /**
63
+ * @group Models
64
+ */
65
+ export type EdgeTargetTuple = [
66
+ from: EdgeTarget,
67
+ to: EdgeTarget,
68
+ ...rest: EdgeTarget[],
69
+ ];
70
+
71
+ /**
72
+ * @group Models
73
+ */
74
+ export type EdgeTargetLikeTuple = [
75
+ from: EdgeTargetLike,
76
+ to: EdgeTargetLike,
77
+ ...rest: EdgeTargetLike[],
78
+ ];
79
+
80
+ /**
81
+ * An objects of attribute key/value pairs.
82
+ * @group Models
83
+ */
84
+ export type AttributesObject<T extends AttributeKey> = {
85
+ [K in T]?: Attribute<K>;
86
+ };
87
+
88
+ /**
89
+ * @group Models
90
+ */
91
+ export type AttributeValue = Attribute<AttributeKey>;
92
+
93
+ /**
94
+ * An array of attribute key/value tuple.
95
+ * @group Models
96
+ */
97
+ export type AttributesEntities<T extends AttributeKey> = readonly [
98
+ T,
99
+ Attribute<T>,
100
+ ][];
101
+
102
+ /**
103
+ * Attribute object that can be set to Edge.
104
+ * @group Models
105
+ */
106
+ export type EdgeAttributesObject = AttributesObject<EdgeAttributeKey>;
107
+
108
+ /**
109
+ * Attribute object that can be set to Node.
110
+ * @group Models
111
+ */
112
+ export type NodeAttributesObject = AttributesObject<NodeAttributeKey>;
113
+
114
+ /**
115
+ * Attribute object that can be set to Graph.
116
+ * @group Models
117
+ */
118
+ export type GraphAttributesObject = AttributesObject<GraphAttributeKey>;
119
+
120
+ /**
121
+ * Attribute object that can be set to Subgraph.
122
+ * @group Models
123
+ */
124
+ export type SubgraphAttributesObject = AttributesObject<
125
+ ClusterSubgraphAttributeKey | SubgraphAttributeKey
126
+ >;
127
+
128
+ /**
129
+ * @group Models
130
+ */
131
+ export type DotObjectType =
132
+ | 'AttributeList'
133
+ | 'Node'
134
+ | 'Edge'
135
+ | 'Subgraph'
136
+ | 'Graph';
137
+
138
+ /**
139
+ * DotObjectModel is an interface that defines a generic type for a {@link DotObjectType}.
140
+ *
141
+ * @template T The type of the {@link DotObjectType}.
142
+ * @group Models
143
+ */
144
+ export interface DotObjectModel<T extends DotObjectType = DotObjectType> {
145
+ /**
146
+ * The type of the DotObjectType.
147
+ */
148
+ $$type: T;
149
+ }
150
+
151
+ /**
152
+ * @group Models
153
+ */
154
+ export interface HasComment {
155
+ /** Comments to include when outputting with toDot. */
156
+ comment?: string;
157
+ }
158
+
159
+ /**
160
+ * @group Models
161
+ */
162
+ export interface HasAttributes<T extends AttributeKey> {
163
+ readonly attributes: AttributesGroupModel<T>;
164
+ }
165
+
166
+ /**
167
+ * @group Models
168
+ */
169
+ export interface ForwardRefNode extends Partial<Port> {
170
+ readonly id: string;
171
+ }
172
+
173
+ /**
174
+ * DOT object with the property
175
+ * that attributes can be held as a set of keys and values.
176
+ *
177
+ * @typeParam T - The attribute keys to set DOT object.
178
+ * @group Models
179
+ */
180
+ export interface Attributes<T extends AttributeKey> {
181
+ /** Size of the set of keys and values held by the DOT object. */
182
+ readonly size: number;
183
+ /** The key/value tuples of the object attributes. */
184
+ readonly values: ReadonlyArray<[T, Attribute<T>]>;
185
+ /**
186
+ * Get the value of an attribute by a DOT object by specifying its key.
187
+ *
188
+ * If the value corresponding to the key does not exist, undefined is returned.
189
+ */
190
+ get<K extends T>(key: K): Attribute<K> | undefined;
191
+ /** Set a value, by specifying the key of the attributes in the DOT object. */
192
+ set<K extends T>(key: K, value: Attribute<K>): void;
193
+ /**
194
+ * Apply keys and values that can be specified for DOT objects collectively.
195
+ *
196
+ * @param attributes - An array of objects or tuples of attribute key/value pairs.
197
+ */
198
+ apply(attributes: AttributesObject<T> | AttributesEntities<T>): void;
199
+ /** Delete the value of an attribute from a DOT object by specifying a key. */
200
+ delete(key: T): void;
201
+ /** Delete all attributes specified for the DOT object. */
202
+ clear(): void;
203
+ }
204
+
205
+ /**
206
+ * @group Models
207
+ */
208
+ export interface AttributesGroupModel<T extends AttributeKey>
209
+ extends Attributes<T>,
210
+ HasComment {}
211
+
212
+ /**
213
+ * @group Models
214
+ */
215
+ export type AttributeListKind = 'Graph' | 'Edge' | 'Node';
216
+
217
+ /**
218
+ * A list object of attributes commonly specified for nodes, subgraphs, and edges
219
+ * under graph and subgraph.
220
+ *
221
+ * @typeParam K - The type of object is being specified.
222
+ * @typeParam T - The attribute keys to set DOT object.
223
+ * @group Models
224
+ */
225
+ export interface AttributeListModel<
226
+ K extends AttributeListKind = AttributeListKind,
227
+ T extends AttributeKey = AttributeKey,
228
+ > extends Attributes<T>,
229
+ HasComment,
230
+ DotObjectModel<'AttributeList'> {
231
+ $$kind: K;
232
+ }
233
+
234
+ /**
235
+ * Port on an edge node.
236
+ * @group Models
237
+ */
238
+ export interface Port {
239
+ port: string;
240
+ compass: Compass;
241
+ }
242
+
243
+ /**
244
+ * Model that can be converted to Node in DOT language.
245
+ * @group Models
246
+ */
247
+ export interface NodeModel
248
+ extends HasComment,
249
+ HasAttributes<NodeAttributeKey>,
250
+ DotObjectModel<'Node'> {
251
+ /** ID of the node */
252
+ readonly id: string;
253
+ /** Returns ForwardRefNode with port and compass specified. */
254
+ port(port: string | Partial<Port>): ForwardRefNode;
255
+ }
256
+
257
+ /**
258
+ * Model that can be converted to Edge in DOT language.
259
+ * @group Models
260
+ */
261
+ export interface EdgeModel
262
+ extends HasComment,
263
+ HasAttributes<EdgeAttributeKey>,
264
+ DotObjectModel<'Edge'> {
265
+ readonly targets: EdgeTargetTuple;
266
+ }
267
+
268
+ /**
269
+ * Cluster common attribute interface.
270
+ * @group Models
271
+ */
272
+ export interface GraphCommonAttributes {
273
+ /** Manage common attributes of graphs in a graph. */
274
+ graph: AttributeListModel<
275
+ 'Graph',
276
+ SubgraphAttributeKey | ClusterSubgraphAttributeKey
277
+ >;
278
+ /** Manage common attributes of edges in a graph. */
279
+ edge: AttributeListModel<'Edge', EdgeAttributeKey>;
280
+ /** Manage common attributes of nodes in a graph. */
281
+ node: AttributeListModel<'Node', NodeAttributeKey>;
282
+ }
283
+
284
+ /**
285
+ * DOT model representing a graph/digraph/subgraph.
286
+ * @group Models
287
+ */
288
+ export interface GraphBaseModel<T extends AttributeKey = AttributeKey>
289
+ extends HasComment,
290
+ Attributes<T> {
291
+ readonly id?: string;
292
+ readonly attributes: Readonly<GraphCommonAttributes>;
293
+ /** Node objects in the graph. */
294
+ readonly nodes: ReadonlyArray<NodeModel>;
295
+ /** Edge objects in the graph. */
296
+ readonly edges: ReadonlyArray<EdgeModel>;
297
+ /** Subgraph objects in the graph. */
298
+ readonly subgraphs: ReadonlyArray<SubgraphModel>;
299
+
300
+ with(models: Partial<ModelsContext>): void;
301
+
302
+ /**
303
+ * Add a Node to the graph.
304
+ */
305
+ addNode(node: NodeModel): void;
306
+ /**
307
+ * Add Edge to the graph.
308
+ */
309
+ addEdge(edge: EdgeModel): void;
310
+ /**
311
+ * Add a Subgraph to the graph.
312
+ */
313
+ addSubgraph(subgraph: SubgraphModel): void;
314
+ /**
315
+ * Check if the Node exists in the graph.
316
+ */
317
+ existNode(nodeId: string): boolean;
318
+ /**
319
+ * Check if the Edge exists in the graph.
320
+ */
321
+ existEdge(edge: EdgeModel): boolean;
322
+ /**
323
+ * Check if the Subgraph exists in the graph.
324
+ */
325
+ existSubgraph(subgraph: SubgraphModel): boolean;
326
+ /**
327
+ * Remove Node from the graph.
328
+ */
329
+ removeNode(node: NodeModel | string): void;
330
+ /**
331
+ * Remove Edge from the graph.
332
+ */
333
+ removeEdge(edge: EdgeModel): void;
334
+ /**
335
+ * Remove Subgraph from the graph.
336
+ */
337
+ removeSubgraph(subgraph: SubgraphModel): void;
338
+ /**
339
+ * Create a Node in the graph.
340
+ */
341
+ createNode(id: string, attributes?: NodeAttributesObject): NodeModel;
342
+ /**
343
+ * Create a Subgraph and add it to the graph.
344
+ *
345
+ * @param id - Subgraph ID
346
+ * @param attributes - Subgraph attribute object
347
+ */
348
+ createSubgraph(
349
+ id?: string,
350
+ attributes?: SubgraphAttributesObject,
351
+ ): SubgraphModel;
352
+ createSubgraph(attributes?: SubgraphAttributesObject): SubgraphModel;
353
+ /**
354
+ * Get Subgraph in cluster by specifying id.
355
+ *
356
+ * If there is no Subgraph with the specified id in the graph, return undefined.
357
+ */
358
+ getSubgraph(id: string): SubgraphModel | undefined;
359
+
360
+ /**
361
+ * Get Node in cluster by specifying id.
362
+ *
363
+ * @description
364
+ * If there is no Node with the specified id in the graph, return undefined.
365
+ */
366
+ getNode(id: string): NodeModel | undefined;
367
+ /** Create Edge and add it to the graph. */
368
+ createEdge(
369
+ targets: EdgeTargetLikeTuple,
370
+ attributes?: EdgeAttributesObject,
371
+ ): EdgeModel;
372
+
373
+ /**
374
+ * Create a subgraph by specifying its id (or get it if it already exists).
375
+ *
376
+ * By specifying a callback function, the target subgraph can be received and manipulated as an argument.
377
+ *
378
+ * ```ts
379
+ * const G = digraph('G', (g) => {
380
+ * // Create a cluster with id as A.
381
+ * g.subgraph('A', (A) => {
382
+ * // Create a node with id as A1 in cluster A.
383
+ * A.node('A1');
384
+ * });
385
+ * });
386
+ *
387
+ * console.log(toDot(G));
388
+ * // digraph "G" {
389
+ * // subgraph "A" {
390
+ * // "A1";
391
+ * // }
392
+ * // }
393
+ * ```
394
+ *
395
+ * @param id Subgraph ID.
396
+ * @param callback Callbacks for manipulating created or retrieved subgraph.
397
+ */
398
+ subgraph(
399
+ id: string,
400
+ callback?: (subgraph: SubgraphModel) => void,
401
+ ): SubgraphModel;
402
+ /**
403
+ * Create a subgraph (or get one if it already exists) and adapt the attributes.
404
+ *
405
+ * By specifying a callback function, the target subgraph can be received and manipulated as an argument.
406
+ *
407
+ * ```ts
408
+ * const G = digraph('G', (g) => {
409
+ * // Create a cluster with id as A and specifying its attributes.
410
+ * g.subgraph('A', { [attribute.color]: 'red', [attribute.label]: 'my label' }, (A) => {
411
+ * // Create a node with id as A1 in cluster A.
412
+ * A.node('A1');
413
+ * });
414
+ * });
415
+ *
416
+ * console.log(toDot(G));
417
+ * // digraph "G" {
418
+ * // subgraph "A" {
419
+ * // color = "red";
420
+ * // label = "my label";
421
+ * // "A1";
422
+ * // }
423
+ * // }
424
+ * ```
425
+ *
426
+ * @param id Subgraph ID.
427
+ * @param attributes Object of attributes to be adapted to the subgraph.
428
+ * @param callback Callbacks for manipulating created or retrieved subgraph.
429
+ */
430
+ subgraph(
431
+ id: string,
432
+ attributes: SubgraphAttributesObject,
433
+ callback?: (subgraph: SubgraphModel) => void,
434
+ ): SubgraphModel;
435
+ /**
436
+ * Create anonymous subgraphs and and adapt the attributes.
437
+ *
438
+ * By specifying a callback function, the target subgraph can be received and manipulated as an argument.
439
+ *
440
+ * ```ts
441
+ * const G = digraph('G', (g) => {
442
+ * // Create a anonymous cluster and specifying its attributes.
443
+ * g.subgraph({ [attribute.color]: 'red', [attribute.label]: 'my label' }, (A) => {
444
+ * // Create a node with id as A1 in anonymous cluster.
445
+ * A.node('A1');
446
+ * });
447
+ * });
448
+ *
449
+ * console.log(toDot(G));
450
+ * // digraph "G" {
451
+ * // subgraph {
452
+ * // color = "red";
453
+ * // label = "my label";
454
+ * // "A1";
455
+ * // }
456
+ * // }
457
+ * ```
458
+ *
459
+ * @param attributes Object of attributes to be adapted to the subgraph.
460
+ * @param callback Callbacks for manipulating created or retrieved subgraph.
461
+ */
462
+ subgraph(
463
+ attributes: SubgraphAttributesObject,
464
+ callback?: (subgraph: SubgraphModel) => void,
465
+ ): SubgraphModel;
466
+ /**
467
+ * Create anonymous subgraphs and manipulate them with callback functions.
468
+ *
469
+ * By specifying a callback function, the target subgraph can be received and manipulated as an argument.
470
+ *
471
+ * @param callback Callbacks for manipulating created or retrieved subgraph.
472
+ */
473
+ subgraph(callback?: (subgraph: SubgraphModel) => void): SubgraphModel;
474
+
475
+ /**
476
+ * Create a node by specifying its id (or get it if it already exists).
477
+ *
478
+ * By specifying a callback function, the target node can be received and manipulated as an argument.
479
+ *
480
+ * ```ts
481
+ * const G = digraph('G', (g) => {
482
+ * // Create a node with id as A.
483
+ * g.node('A');
484
+ * });
485
+ *
486
+ * console.log(toDot(G));
487
+ * // digraph "G" {
488
+ * // "A";
489
+ * // }
490
+ * ```
491
+ *
492
+ * @param id Node ID.
493
+ * @param callback Callbacks for manipulating created or retrieved node.
494
+ */
495
+ node(id: string, callback?: (node: NodeModel) => void): NodeModel;
496
+ /**
497
+ * Create a node (or get one if it already exists) and adapt the attributes.
498
+ *
499
+ * By specifying a callback function, the target node can be received and manipulated as an argument.
500
+ *
501
+ * ```ts
502
+ * const G = digraph('G', (g) => {
503
+ * // Create a node by specifying its id and specifying its attributes.
504
+ * g.node('A', {
505
+ * [attribute.color]: 'red',
506
+ * [attribute.label]: 'my label',
507
+ * });
508
+ * });
509
+ *
510
+ * console.log(toDot(G));
511
+ * // digraph "G" {
512
+ * // "A" [
513
+ * // color = "red",
514
+ * // label = "my label",
515
+ * // ];
516
+ * // }
517
+ * ```
518
+ *
519
+ * @param id Node ID.
520
+ * @param attributes Object of attributes to be adapted to the node.
521
+ * @param callback Callbacks for manipulating created or retrieved node.
522
+ */
523
+ node(
524
+ id: string,
525
+ attributes: NodeAttributesObject,
526
+ callback?: (node: NodeModel) => void,
527
+ ): NodeModel;
528
+ /**
529
+ * Set a common attribute for the nodes in the graph.
530
+ *
531
+ * ```ts
532
+ * const G = digraph('G', (g) => {
533
+ * // Set a common attribute for the nodes in the graph.
534
+ * g.node({
535
+ * [attribute.color]: 'red',
536
+ * [attribute.label]: 'my label',
537
+ * });
538
+ * });
539
+ *
540
+ * console.log(toDot(G));
541
+ * // digraph "G" {
542
+ * // node [
543
+ * // color = "red",
544
+ * // label = "my label",
545
+ * // ];
546
+ * // }
547
+ * ```
548
+ *
549
+ * @param attributes Object of attributes to be adapted to the nodes.
550
+ */
551
+ node(attributes: NodeAttributesObject): void;
552
+ /**
553
+ * Create a edge.
554
+ *
555
+ * By specifying a callback function, the target edge can be received and manipulated as an argument.
556
+ *
557
+ * ```ts
558
+ * const G = digraph('G', (g) => {
559
+ * // Create a edge.
560
+ * g.edge(['a', 'b']);
561
+ * });
562
+ *
563
+ * console.log(toDot(G));
564
+ * // digraph "G" {
565
+ * // "a" -> "b";
566
+ * // }
567
+ * ```
568
+ * @param targets Nodes.
569
+ * @param callback Callbacks for manipulating created or retrieved edge.
570
+ */
571
+ edge(
572
+ targets: EdgeTargetLikeTuple,
573
+ callback?: (edge: EdgeModel) => void,
574
+ ): EdgeModel;
575
+ /**
576
+ * Create a edge and adapt the attributes.
577
+ *
578
+ * By specifying a callback function, the target edge can be received and manipulated as an argument.
579
+ *
580
+ * ```ts
581
+ * const G = digraph('G', (g) => {
582
+ * // Create a edge and specifying its attributes.
583
+ * g.edge(['a', 'b'], {
584
+ * [attribute.color]: 'red',
585
+ * [attribute.label]: 'my label',
586
+ * });
587
+ * });
588
+ *
589
+ * console.log(toDot(G));
590
+ * // digraph "G" {
591
+ * // "a" -> "b" [
592
+ * // color = "red",
593
+ * // label = "my label",
594
+ * // ];
595
+ * // }
596
+ * ```
597
+ *
598
+ * @param attributes Object of attributes to be adapted to the edge.
599
+ * @param callback Callbacks for manipulating created or retrieved edge.
600
+ */
601
+ edge(
602
+ targets: EdgeTargetLikeTuple,
603
+ attributes: EdgeAttributesObject,
604
+ callback?: (edge: EdgeModel) => void,
605
+ ): EdgeModel;
606
+ /**
607
+ * Set a common attribute for the edges in the graph.
608
+ *
609
+ *
610
+ * ```ts
611
+ * const G = digraph('G', (g) => {
612
+ * // Set a common attribute for the edges in the graph.
613
+ * g.edge({
614
+ * [attribute.color]: 'red',
615
+ * [attribute.label]: 'my label',
616
+ * });
617
+ * });
618
+ *
619
+ * console.log(toDot(G));
620
+ * // digraph "G" {
621
+ * // edge [
622
+ * // color = "red",
623
+ * // label = "my label",
624
+ * // ];
625
+ * // }
626
+ * ```
627
+ * @param attributes Object of attributes to be adapted to the edges.
628
+ */
629
+ edge(attributes: EdgeAttributesObject): void;
630
+
631
+ /**
632
+ * Set a common attribute for the graph in the graph.
633
+ *
634
+ * ```ts
635
+ * const G = digraph('G', (g) => {
636
+ * g.graph({
637
+ * [attribute.color]: 'red',
638
+ * [attribute.label]: 'my label',
639
+ * });
640
+ * });
641
+ *
642
+ * console.log(toDot(G));
643
+ * // digraph "G" {
644
+ * // graph [
645
+ * // color = "red",
646
+ * // label = "my label",
647
+ * // ];
648
+ * // }
649
+ * ```
650
+ * @param attributes Object of attributes to be adapted to the graph.
651
+ */
652
+ graph(attributes: SubgraphAttributesObject): void;
653
+ }
654
+
655
+ /**
656
+ * DOT model representing a subgraph.
657
+ * @group Models
658
+ */
659
+ export interface SubgraphModel
660
+ extends GraphBaseModel<SubgraphAttributeKey | ClusterSubgraphAttributeKey>,
661
+ DotObjectModel<'Subgraph'> {
662
+ /** Determines whether the Subgraph is a SubgraphCluster. */
663
+ isSubgraphCluster(): boolean;
664
+ }
665
+
666
+ /**
667
+ * DOT model representing a root graphs(digraph and graph).
668
+ * @group Models
669
+ */
670
+ export interface RootGraphModel
671
+ extends GraphBaseModel<GraphAttributeKey>,
672
+ DotObjectModel<'Graph'> {
673
+ directed: boolean;
674
+
675
+ /**
676
+ * Strict mode.
677
+ *
678
+ * @description
679
+ * A graph may also be described as strict.
680
+ * This forbids the creation of multi-edges, i.e., there can be at most one edge with a given tail node and head node in the directed case.
681
+ * For undirected graphs, there can be at most one edge connected to the same two nodes.
682
+ * Subsequent edge statements using the same two nodes will identify the edge with the previously defined one and apply any attributes given in the edge statement.
683
+ */
684
+ strict: boolean;
685
+ }
686
+
687
+ /**
688
+ * @group Models
689
+ */
690
+ export interface RootGraphConstructor {
691
+ new (id?: string, attributes?: GraphAttributesObject): RootGraphModel;
692
+ new (
693
+ id?: string,
694
+ strict?: boolean,
695
+ attributes?: GraphAttributesObject,
696
+ ): RootGraphModel;
697
+ new (strict?: boolean, attributes?: GraphAttributesObject): RootGraphModel;
698
+ new (attributes?: GraphAttributesObject): RootGraphModel;
699
+ new (...args: any[]): RootGraphModel;
700
+ }
701
+
702
+ /**
703
+ * @group Models
704
+ */
705
+ export interface SubgraphConstructor {
706
+ new (id?: string, attributes?: SubgraphAttributesObject): SubgraphModel;
707
+ new (attributes?: SubgraphAttributesObject): SubgraphModel;
708
+ new (...args: any[]): SubgraphModel;
709
+ }
710
+
711
+ /**
712
+ * @group Models
713
+ */
714
+ export interface NodeConstructor {
715
+ new (id: string, attributes?: NodeAttributesObject): NodeModel;
716
+ new (...args: any[]): NodeModel;
717
+ }
718
+
719
+ /**
720
+ * @group Models
721
+ */
722
+ export interface EdgeConstructor {
723
+ new (targets: EdgeTargetTuple, attributes?: EdgeAttributesObject): EdgeModel;
724
+ new (...args: any[]): EdgeModel;
725
+ }
726
+
727
+ /** @hidden */
728
+ export function isForwardRefNode(object: unknown): object is ForwardRefNode {
729
+ return (
730
+ typeof object === 'object' &&
731
+ object !== null &&
732
+ typeof (object as ForwardRefNode).id === 'string'
733
+ );
734
+ }
735
+
736
+ /** @hidden */
737
+ export function isNodeModel(object: unknown): object is NodeModel {
738
+ return (
739
+ typeof object === 'object' &&
740
+ object !== null &&
741
+ (object as NodeModel).$$type === 'Node' &&
742
+ typeof (object as NodeModel).id === 'string'
743
+ );
744
+ }
745
+
746
+ /** @hidden */
747
+ export function isNodeRef(node: unknown): node is NodeRef {
748
+ return isNodeModel(node) || isForwardRefNode(node);
749
+ }
750
+
751
+ /** @hidden */
752
+ export function isNodeRefLike(node: unknown): node is NodeRefLike {
753
+ return typeof node === 'string' || isNodeRef(node);
754
+ }
755
+
756
+ /** @hidden */
757
+ export function isNodeRefGroupLike(
758
+ target: NodeRefLike | NodeRefGroupLike,
759
+ ): target is NodeRefGroupLike {
760
+ return Array.isArray(target) && target.every(isNodeRefLike);
761
+ }
762
+
763
+ /** @hidden */
764
+ export function isCompass(c: string): c is Compass {
765
+ return ['n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'c'].includes(c);
766
+ }
767
+
768
+ /** @hidden */
769
+ export function toNodeRef(target: NodeRefLike): NodeRef {
770
+ if (isNodeRef(target)) {
771
+ return target;
772
+ }
773
+ const [id, port, compass] = target.split(':');
774
+ if (isCompass(compass)) {
775
+ return { id, port, compass };
776
+ }
777
+ return { id, port };
778
+ }
779
+
780
+ /** @hidden */
781
+ export function toNodeRefGroup(targets: NodeRefGroupLike): NodeRefGroup {
782
+ if (
783
+ targets.length < 2 &&
784
+ (isNodeRefLike(targets[0]) && isNodeRefLike(targets[1])) === false
785
+ ) {
786
+ throw Error('EdgeTargets must have at least 2 elements.');
787
+ }
788
+ return targets.map((t) => toNodeRef(t));
789
+ }