@davidsouther/agathon 0.0.0-stage → 0.0.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.
Files changed (62) hide show
  1. package/package.json +19 -4
  2. package/src/assert.ts +67 -0
  3. package/src/geometry/box.ts +76 -0
  4. package/src/geometry/circle.ts +296 -0
  5. package/src/geometry/geometry.ts +318 -0
  6. package/src/geometry/path.ts +315 -0
  7. package/src/geometry/quadtree.ts +321 -0
  8. package/src/geometry/rectangle.ts +129 -0
  9. package/src/geometry/rngon.ts +132 -0
  10. package/src/geometry/types.ts +102 -0
  11. package/src/geometry.ts +61 -0
  12. package/src/highlight/highlight.ts +85 -0
  13. package/src/index.ts +5 -0
  14. package/src/layout/grid/manager.ts +55 -0
  15. package/src/layout/grid.ts +1 -0
  16. package/src/layout/hierarchic/README.md +21 -0
  17. package/src/layout/hierarchic/acyclic.ts +249 -0
  18. package/src/layout/hierarchic/children.ts +169 -0
  19. package/src/layout/hierarchic/debug.ts +186 -0
  20. package/src/layout/hierarchic/layout.ts +266 -0
  21. package/src/layout/hierarchic/manager.ts +65 -0
  22. package/src/layout/hierarchic/normalize.ts +177 -0
  23. package/src/layout/hierarchic/order.ts +321 -0
  24. package/src/layout/hierarchic/position.ts +514 -0
  25. package/src/layout/hierarchic/rank.ts +629 -0
  26. package/src/layout/hierarchic.ts +2 -0
  27. package/src/layout/hulls/arrange.ts +94 -0
  28. package/src/layout/hulls/hulls.ts +243 -0
  29. package/src/layout/hulls/segments.ts +174 -0
  30. package/src/layout/hulls.ts +3 -0
  31. package/src/layout/manager/child_manager.ts +42 -0
  32. package/src/layout/manager/drag_manager.ts +112 -0
  33. package/src/layout/manager/manager.ts +425 -0
  34. package/src/layout/manager/pan_manager.ts +146 -0
  35. package/src/layout/manager/visibility_manager.ts +84 -0
  36. package/src/layout/manager/zoom_manager.ts +263 -0
  37. package/src/layout/manager.ts +6 -0
  38. package/src/layout/properties/defaults.ts +99 -0
  39. package/src/layout/properties/symbol.ts +99 -0
  40. package/src/layout/properties/weak_map.ts +73 -0
  41. package/src/layout/properties.ts +111 -0
  42. package/src/layout/types.ts +470 -0
  43. package/src/layout/util.ts +444 -0
  44. package/src/layout.ts +6 -0
  45. package/src/samples/diff_graph.ts +15 -0
  46. package/src/samples/edge_cases.ts +168 -0
  47. package/src/samples/gansner_with_states.ts +67 -0
  48. package/src/samples/load_generator.ts +213 -0
  49. package/src/samples/search_graph.ts +35 -0
  50. package/src/tsabre/algo.ts +126 -0
  51. package/src/tsabre/builder.ts +97 -0
  52. package/src/tsabre/compress.ts +15 -0
  53. package/src/tsabre/dijkstra/dijkstra.ts +76 -0
  54. package/src/tsabre/dijkstra/heap.ts +83 -0
  55. package/src/tsabre/graph.ts +808 -0
  56. package/src/tsabre/parse.ts +634 -0
  57. package/src/tsabre/print.ts +188 -0
  58. package/src/tsabre/sourcebuilder/code_content_buffer.ts +275 -0
  59. package/src/tsabre/sourcebuilder/printable.ts +33 -0
  60. package/src/tsabre.ts +6 -0
  61. package/src/types.ts +424 -0
  62. package/README.md +0 -3
package/src/types.ts ADDED
@@ -0,0 +1,424 @@
1
+ /** An ID for a node. */
2
+ export type NodeId = string;
3
+ /** An nominal ID type for an Edge. */
4
+ export type EdgeId = string;
5
+ /** An nominal ID type for a Segment. */
6
+ export type SegmentId = string;
7
+
8
+ /** The height/width of the currently displayed graph area */
9
+ export interface Bounds {
10
+ width: number;
11
+ height: number;
12
+ }
13
+
14
+ /** An x/y position in 2d space. */
15
+ export interface Point {
16
+ x: number;
17
+ y: number;
18
+ }
19
+
20
+ /**
21
+ * A point object that is just a tuple of 2 numbers. Used throughout graph_utils
22
+ * (which thinks about points as vectors)
23
+ */
24
+ export type PointTuple = [number, number];
25
+
26
+ /**
27
+ * A circle has a center <x, y> and a radius <r>.
28
+ */
29
+ export interface Circle extends Point {
30
+ r: number;
31
+ }
32
+
33
+ /**
34
+ * A stripped-down version of NodeCircle, used for calculations that require a
35
+ * map of node id's to their radii.
36
+ */
37
+ export interface NodeRadius {
38
+ id: NodeId;
39
+ r: number;
40
+ }
41
+
42
+ /**
43
+ * A circle that has an ID of the node it represents
44
+ */
45
+ export interface NodeCircle extends Circle {
46
+ id: NodeId;
47
+ }
48
+
49
+ /**
50
+ * An axis-aligned box is a point in 2d space with an associated height and
51
+ * width of area to cover.
52
+ */
53
+ export interface Box extends Point, Bounds {}
54
+
55
+ /**
56
+ * An incoming set of data to be expanded into a Graph.
57
+ */
58
+ export interface GraphData<N extends Node, E extends Edge> {
59
+ nodes: Iterable<N>;
60
+ edges: Iterable<E>;
61
+ }
62
+
63
+ /**
64
+ * A graph specifically using Node and Edge, rather than {} {}.
65
+ */
66
+ export type FullGraph = SmartGraph<Node, Edge>;
67
+
68
+ /**
69
+ * A graph contains a set of Nodes and Edges, as well as providing a variety of
70
+ * convenient accessors. Graphs are directed, are allowed multiple edges, and
71
+ * are compound. Implicitly, then, undirected graphs should set both edges;
72
+ * non-compound graphs simply don't use the `parent` functionality, and simple
73
+ * graphs don't use the `name` field of edges. SmartGraphs track Topology
74
+ * segments, which are bundles of edges following the nested graph hierarchy.
75
+ *
76
+ * For definitions of descendants, ancestors, parents, siblings, etc, see
77
+ * https://sebastian.expert/ancestor-descendant-sibling-parent-child-explained/
78
+ * https://en.wikipedia.org/wiki/Tree_(data_structure)#Terminology_used_in_trees
79
+ */
80
+ export interface ReadonlySmartGraph<NodeValue, EdgeValue> {
81
+ readonly nodeCount: number;
82
+ readonly edgeCount: number;
83
+ readonly segmentCount: number;
84
+
85
+ readonly nodes: Set<NodeId>;
86
+ readonly allNodes: Iterable<NodeValue>;
87
+ readonly allEdges: Iterable<EdgeValue>;
88
+ readonly allSegments: Iterable<Segment<EdgeValue>>;
89
+ readonly topSegments: Iterable<Segment<EdgeValue>>;
90
+ readonly sinks: Set<NodeId>;
91
+ readonly sources: Set<NodeId>;
92
+
93
+ node(id?: NodeId): NodeValue | undefined;
94
+ hasNode(id?: NodeId): boolean;
95
+
96
+ edge(edge: Edge): EdgeValue | undefined;
97
+ hasEdge(edge: Edge): boolean;
98
+ hasSegment(segment: Segment): boolean;
99
+
100
+ /**
101
+ * Return all edges for a given node to a given neighbor. If no neighbor is
102
+ * specified, returns all edges for the given node. If no node specified,
103
+ * returns all edges in the graph.
104
+ */
105
+ edges(id?: NodeId, neighbor?: NodeId): Iterable<Edge>;
106
+ inEdges(id: NodeId, source?: NodeId): Iterable<Edge>;
107
+ outEdges(id: NodeId, target?: NodeId): Iterable<Edge>;
108
+
109
+ /**
110
+ * Returns the ID of the parent node. Graph implementations should include a
111
+ * root parent node ID that is not a member of the node set. To validate that
112
+ * a parent is part of the graph, callers can use `hasParent` on a node, or
113
+ * `hasNode` on the id returned from `parent`.
114
+ */
115
+ parent(id: NodeId): NodeId;
116
+
117
+ /**
118
+ * Returns children of the given node. If no node ID is given, returns all top
119
+ * level nodes (nodes without a parent).
120
+ */
121
+ children(id?: NodeId): Set<NodeId>;
122
+ hasChildren(id?: NodeId): boolean;
123
+ hasParent(id: NodeId): boolean;
124
+
125
+ /**
126
+ * Returns all descendants of the given node. If no ID specified, will return
127
+ * all nodes in the entire graph.
128
+ *
129
+ * This will not include the starting node, to avoid double counting the ID
130
+ * when combining ancestors and descendants.
131
+ */
132
+ descendants(id?: NodeId): Set<NodeId>;
133
+
134
+ /**
135
+ * A list of NodeIds from the given ID to the root, starting from the node.
136
+ * If no node is given, returns an empty array.
137
+ */
138
+ ancestors(id?: NodeId): NodeId[];
139
+
140
+ /**
141
+ * The predecessors of a node are all nodes which are the source of an edge
142
+ * with that node as a target. That is, the nodes at the other end of inEdges.
143
+ */
144
+ predecessors(id: NodeId): Set<NodeId>;
145
+
146
+ /**
147
+ * The successors of a node are all nodes which are the target of an edge
148
+ * with that node as a source. That is, the nodes at the other end of
149
+ * outEdges.
150
+ */
151
+ successors(id: NodeId): Set<NodeId>;
152
+ neighbors(id: NodeId): Set<NodeId>;
153
+ isLeaf(id: NodeId): boolean;
154
+
155
+ /**
156
+ * Find the top-level segment between a and b, if it exists. If there is no
157
+ * segment between a and b, or if a or be are not top-level nodes, this
158
+ * returns undefined.
159
+ */
160
+ topSegment(a: NodeId, b: NodeId): Segment<EdgeValue> | undefined;
161
+
162
+ /**
163
+ * Returns true if the segment exists in the graph and if it is between two
164
+ * top-level nodes.
165
+ */
166
+ isTopSegment(s: Segment<EdgeValue>): boolean;
167
+
168
+ /**
169
+ * All segments with id as either their source or target.
170
+ */
171
+ nodeSegments(id: NodeId): Iterable<Segment<EdgeValue>>;
172
+
173
+ /**
174
+ * Returns all segments with the given edge in their bundle.
175
+ */
176
+ edgeSegments(edge: Edge): Iterable<Segment<EdgeValue>>;
177
+
178
+ /**
179
+ * Returns segments for successor edges from this node.
180
+ * If no edges start from this node itself (as opposed to its children), this
181
+ * will be empty. This is equivalent to calling edgeSegments on every outgoing
182
+ * edge from a node.
183
+ */
184
+ successorSegments(id?: NodeId): Iterable<Segment<EdgeValue>>;
185
+
186
+ /**
187
+ * Returns all sibling segments between children of the given node.
188
+ */
189
+ childSegments(id?: NodeId): Iterable<Segment<EdgeValue>>;
190
+
191
+ /**
192
+ * Returns segments for predecessor edges from this node.
193
+ * If no edges point to this node itself (as opposed to its children), this
194
+ * will be empty. This is equivalent to calling edgeSegments on every incoming
195
+ * edge to a node.
196
+ */
197
+ predecessorSegments(id?: NodeId): Iterable<Segment<EdgeValue>>;
198
+
199
+ /**
200
+ * Returns the combination of predecessor and successor segments. This
201
+ * includes all segments for all edges on this node.
202
+ */
203
+ segmentNeighborhood(id?: NodeId): Iterable<Segment<EdgeValue>>;
204
+
205
+ /**
206
+ * Return all segments that either point from a child to that node, or point
207
+ * between two children of that node. If no nodeId is provided, find segments
208
+ * between top level nodes only.
209
+ */
210
+ segmentsUnderNode(nodeId?: NodeId): Iterable<Segment<EdgeValue>>;
211
+
212
+ /**
213
+ * Given an edge and a segment, return the direction the edge follows along
214
+ * the segment. Because segments are stored in a normalized fashion, it is
215
+ * necessary to recover the underlying edge direction(s) when computing
216
+ * display values for edges. See discussion in EdgeDirectionAlongSegment for
217
+ * further details.
218
+ */
219
+ edgeDirectionAlongSegment(edge: Edge, segment: Segment<EdgeValue>): EdgeDirectionAlongSegment;
220
+ }
221
+
222
+ /**
223
+ * A graph contains a set of Nodes and Edges, as well as providing a variety of
224
+ * convenient accessors. Graphs are directed, are allowed multiple edges, and
225
+ * are compound. Implicitly, then, undirected graphs should set both edges;
226
+ * non-compound graphs simply don't use the `parent` functionality, and simple
227
+ * graphs don't use the `name` field of edges. SmartGraphs track Topology
228
+ * segments, which are bundles of edges following the nested graph hierarchy.
229
+ */
230
+ export interface SmartGraph<NodeValue, EdgeValue> extends ReadonlySmartGraph<NodeValue, EdgeValue> {
231
+ readonly violations: ReadonlyArray<GraphViolation>;
232
+
233
+ setNode(id: NodeId, value: NodeValue): this;
234
+ removeNode(id: NodeId): this;
235
+ setParent(id: NodeId, parent: NodeId | undefined): this;
236
+
237
+ setEdge(edge: Edge, value: EdgeValue): this;
238
+ removeEdge(edge: Edge): this;
239
+ }
240
+
241
+ /**
242
+ * A node is required to have an ID, and may optionally have a parent to
243
+ * specify hierarchies aside from edge connections.
244
+ */
245
+ export type Node<T = unknown> = T & {
246
+ id: NodeId;
247
+ parent?: NodeId;
248
+ };
249
+
250
+ /**
251
+ * An edge connects two nodes. Pairs of nodes may be connected by multiple
252
+ * edges by naming them uniquely.
253
+ */
254
+ export type Edge<T = unknown> = T & {
255
+ source: NodeId;
256
+ target: NodeId;
257
+ name?: string;
258
+ };
259
+
260
+ /**
261
+ * Segments are bundles of graph edges along parent hierarchies. For any given
262
+ * edge, the source and target nodes may not share a parent. In this case, the
263
+ * graph creates `segments` up the source parent hierarchy, across to the
264
+ * sibling ancestor of the target node, and back down. Segments are always
265
+ * directed up the tree, except when crossing siblings, in which case source
266
+ * and target are set consistently. Segments contain a set of all edges which
267
+ * pass through them, as well as a link to the next segment up the chain (except
268
+ * segments between sibling nodes) as well as a set of all segments which
269
+ * contain it as their `next` link.
270
+ */
271
+ export interface Segment<TEdge = unknown> extends DiffableGraphElement {
272
+ source: NodeId;
273
+ target: NodeId;
274
+ next?: Segment<TEdge>;
275
+ previous: Set<Segment<TEdge>>;
276
+ edges: Set<TEdge>;
277
+ }
278
+
279
+ /**
280
+ * An edge can cross a segment Source to Target or Target to Source (from the
281
+ * segment's perspective).
282
+ *
283
+ * ```
284
+ * digraph {
285
+ * A { A_A; }
286
+ * B { B_B; }
287
+ * B_B -> A_A;
288
+ * A -> B;
289
+ * }
290
+ * ```
291
+ *
292
+ * The edge `A -> B` crosses segment `A ~ B` S to T, while `B_B -> A_A` crosses
293
+ * `A ~ B` T to S. Similarly, `B_B -> A_A` crosses `A_A ~ A` T to S and `B_B ~
294
+ * B` S to T.
295
+ */
296
+ export const EdgeDirectionAlongSegment = {
297
+ NOT_CROSSING: "NOT_CROSSING",
298
+ SOURCE_TARGET: "SOURCE_TARGET",
299
+ TARGET_SOURCE: "TARGET_SOURCE",
300
+ } as const;
301
+ export type EdgeDirectionAlongSegment =
302
+ (typeof EdgeDirectionAlongSegment)[keyof typeof EdgeDirectionAlongSegment];
303
+
304
+ /**
305
+ * When mutating a graph, many operations result in invalid states. Adding an
306
+ * edge with a non-existent neighbor, setting a parent to a missing node, or
307
+ * removing a node that hasn't been added are all "errors", but might happen
308
+ * from unexpected data integrity issues. Rather than throwing an error and
309
+ * possibly failing the entire batch operation for a missing edge, SmartGraph
310
+ * instead will perform a noop and log the constraint which was violated.
311
+ */
312
+ export type GraphViolation = NodeViolation | ParentViolation | EdgeViolation;
313
+
314
+ /**
315
+ * The types of possible graph constraint violations.
316
+ */
317
+ export const GraphViolationType = {
318
+ /** Violation when attempting to remove a node that isn't present. */
319
+ REMOVE_NODE_VIOLATION: "REMOVE_NODE_VIOLATION",
320
+ /**
321
+ * Violation when attempting to set the parent of a node that isn't present.
322
+ */
323
+ CHILD_NODE_VIOLATION: "CHILD_NODE_VIOLATION",
324
+ /**
325
+ * Violation when attempting to set a node as a child of a node that isn't
326
+ * present.
327
+ */
328
+ PARENT_NODE_VIOLATION: "PARENT_NODE_VIOLATION",
329
+ /**
330
+ * Violation when attempting to create an edge where either the source or the
331
+ * target isn't present.
332
+ */
333
+ EDGE_VIOLATION: "EDGE_VIOLATION",
334
+ /** Violation when attempting to create an edge that isn't present. */
335
+ REMOVE_EDGE_VIOLATION: "REMOVE_EDGE_VIOLATION",
336
+ } as const;
337
+ export type GraphViolationType = (typeof GraphViolationType)[keyof typeof GraphViolationType];
338
+
339
+ /**
340
+ * A violation of a single node constraint.
341
+ */
342
+ export interface NodeViolation {
343
+ violation:
344
+ | typeof GraphViolationType.CHILD_NODE_VIOLATION
345
+ | typeof GraphViolationType.REMOVE_NODE_VIOLATION;
346
+ node: NodeId;
347
+ }
348
+
349
+ /**
350
+ * A violation of a node / parent constraint.
351
+ */
352
+ export interface ParentViolation {
353
+ violation: typeof GraphViolationType.PARENT_NODE_VIOLATION;
354
+ node: NodeId;
355
+ parent: NodeId;
356
+ }
357
+
358
+ /**
359
+ * A violation of an edge constraint.
360
+ */
361
+ export interface EdgeViolation {
362
+ violation:
363
+ | typeof GraphViolationType.EDGE_VIOLATION
364
+ | typeof GraphViolationType.REMOVE_EDGE_VIOLATION;
365
+ source: NodeId;
366
+ target: NodeId;
367
+ name?: string;
368
+ }
369
+
370
+ /**
371
+ * An attribute set maintains a map of name -> value, with utilities to get
372
+ * values as strings, numbers, and boolean. Attribute names are case
373
+ * insensitive.
374
+ */
375
+ export interface AttributeSet {
376
+ hasAttribute(attribute: string): boolean;
377
+ asNumber(attribute: string): number;
378
+ asNumber(attribute: string, defaultValue: number): number;
379
+ asBoolean(attribute: string): boolean;
380
+ asBoolean(attribute: string, defaultValue: boolean): boolean;
381
+ asString(attribute: string): string;
382
+ asString(attribute: string, defaultValue: string): string;
383
+ asJson<T>(attribute: string): T | undefined;
384
+ asJson<T>(attribute: string, defaultValue: T): T;
385
+ }
386
+
387
+ /**
388
+ * Simple enum to identify which time interval an element is from (left, right,
389
+ * or both).
390
+ */
391
+ export const ElementDiffPresence = {
392
+ LEFT: "left",
393
+ RIGHT: "right",
394
+ BOTH: "both",
395
+ } as const;
396
+ export type ElementDiffPresence = (typeof ElementDiffPresence)[keyof typeof ElementDiffPresence];
397
+
398
+ /**
399
+ * Basic interface describing graph elements that can have a left/right diff
400
+ * state.
401
+ */
402
+ export interface DiffableGraphElement {
403
+ presence?: ElementDiffPresence;
404
+ }
405
+
406
+ /**
407
+ * Any additional link related data we should take into consideration when
408
+ * fetching metrics for that link.
409
+ */
410
+ export interface EdgeContext<T = {}, TEdge = {}> {
411
+ scopeNode: Node<T>;
412
+ sourceNode: Node<T>;
413
+ targetNode: Node<T>;
414
+ segments?: Array<Segment<TEdge>>;
415
+ }
416
+
417
+ /**
418
+ * Object that specifies a metric value to be added to an edge between 2 nodes
419
+ */
420
+ export interface EdgeAnnotation<V, T = {}> {
421
+ source: Node<T>;
422
+ target: Node<T>;
423
+ value?: V;
424
+ }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.