@statelyai/graph 0.12.0 → 1.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 (56) hide show
  1. package/README.md +26 -16
  2. package/dist/{adjacency-list-Ca0VjKIf.mjs → adjacency-list-VsUaH9SJ.mjs} +2 -2
  3. package/dist/{algorithms-BHHg7lGq.mjs → algorithms-Ba7o7niK.mjs} +35 -31
  4. package/dist/{algorithms-BlM-qoJb.d.mts → algorithms-fTqmvhzP.d.mts} +1 -1
  5. package/dist/algorithms.d.mts +1 -1
  6. package/dist/algorithms.mjs +1 -1
  7. package/dist/{converter-Dspillnn.mjs → converter-udLITX36.mjs} +2 -2
  8. package/dist/{edge-list-gKe8-iRa.mjs → edge-list-DP4otyPU.mjs} +1 -1
  9. package/dist/format-support.d.mts +6 -0
  10. package/dist/format-support.mjs +68 -33
  11. package/dist/formats/adjacency-list/index.d.mts +1 -1
  12. package/dist/formats/adjacency-list/index.mjs +1 -1
  13. package/dist/formats/converter/index.d.mts +1 -60
  14. package/dist/formats/converter/index.mjs +1 -1
  15. package/dist/formats/cytoscape/index.d.mts +1 -1
  16. package/dist/formats/cytoscape/index.mjs +19 -3
  17. package/dist/formats/d2/index.d.mts +109 -0
  18. package/dist/formats/d2/index.mjs +1086 -0
  19. package/dist/formats/d3/index.d.mts +8 -1
  20. package/dist/formats/d3/index.mjs +35 -7
  21. package/dist/formats/dot/index.d.mts +1 -1
  22. package/dist/formats/dot/index.mjs +3 -3
  23. package/dist/formats/edge-list/index.d.mts +1 -1
  24. package/dist/formats/edge-list/index.mjs +1 -1
  25. package/dist/formats/elk/index.d.mts +1 -1
  26. package/dist/formats/elk/index.mjs +86 -23
  27. package/dist/formats/gexf/index.d.mts +1 -1
  28. package/dist/formats/gexf/index.mjs +102 -4
  29. package/dist/formats/gml/index.d.mts +1 -1
  30. package/dist/formats/gml/index.mjs +43 -16
  31. package/dist/formats/graphml/index.d.mts +1 -1
  32. package/dist/formats/graphml/index.mjs +11 -4
  33. package/dist/formats/jgf/index.d.mts +1 -1
  34. package/dist/formats/jgf/index.mjs +19 -3
  35. package/dist/formats/mermaid/index.d.mts +2 -1
  36. package/dist/formats/mermaid/index.mjs +48 -18
  37. package/dist/formats/tgf/index.d.mts +1 -1
  38. package/dist/formats/tgf/index.mjs +2 -2
  39. package/dist/formats/xyflow/index.d.mts +2 -1
  40. package/dist/formats/xyflow/index.mjs +97 -40
  41. package/dist/index-CHoriXZD.d.mts +638 -0
  42. package/dist/index-D9Kj6Fe3.d.mts +61 -0
  43. package/dist/index.d.mts +6 -631
  44. package/dist/index.mjs +8 -7
  45. package/dist/{indexing-CJc-ul8e.mjs → indexing-DR8M1vBy.mjs} +18 -4
  46. package/dist/mode-D8OnHFBk.mjs +15 -0
  47. package/dist/queries-BlkA1HAN.d.mts +516 -0
  48. package/dist/queries.d.mts +1 -514
  49. package/dist/queries.mjs +17 -15
  50. package/dist/schemas.d.mts +29 -17
  51. package/dist/schemas.mjs +139 -6
  52. package/dist/{types-CnZ01raw.d.mts → types-3-FS9NV2.d.mts} +30 -7
  53. package/package.json +2 -1
  54. package/schemas/edge.schema.json +11 -0
  55. package/schemas/graph.schema.json +25 -3
  56. package/schemas/node.schema.json +7 -0
@@ -1,21 +1,21 @@
1
- import { g as GraphNode, p as GraphEdge, u as Graph, y as GraphPort } from "./types-CnZ01raw.mjs";
1
+ import { _ as GraphNode, b as GraphPort, p as GraphEdge, u as Graph } from "./types-3-FS9NV2.mjs";
2
2
  import * as z from "zod";
3
3
 
4
4
  //#region src/schemas.d.ts
5
5
  declare const PortSchema: z.ZodObject<{
6
6
  name: z.ZodString;
7
- direction: z.ZodOptional<z.ZodEnum<{
7
+ direction: z.ZodEnum<{
8
8
  in: "in";
9
9
  out: "out";
10
10
  inout: "inout";
11
- }>>;
11
+ }>;
12
12
  label: z.ZodOptional<z.ZodString>;
13
13
  data: z.ZodAny;
14
14
  x: z.ZodOptional<z.ZodNumber>;
15
15
  y: z.ZodOptional<z.ZodNumber>;
16
16
  width: z.ZodOptional<z.ZodNumber>;
17
17
  height: z.ZodOptional<z.ZodNumber>;
18
- style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
18
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
19
19
  }, z.core.$strip>;
20
20
  declare const NodeSchema: z.ZodObject<{
21
21
  type: z.ZodLiteral<"node">;
@@ -30,21 +30,21 @@ declare const NodeSchema: z.ZodObject<{
30
30
  height: z.ZodOptional<z.ZodNumber>;
31
31
  shape: z.ZodOptional<z.ZodString>;
32
32
  color: z.ZodOptional<z.ZodString>;
33
- style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
33
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
34
34
  ports: z.ZodOptional<z.ZodArray<z.ZodObject<{
35
35
  name: z.ZodString;
36
- direction: z.ZodOptional<z.ZodEnum<{
36
+ direction: z.ZodEnum<{
37
37
  in: "in";
38
38
  out: "out";
39
39
  inout: "inout";
40
- }>>;
40
+ }>;
41
41
  label: z.ZodOptional<z.ZodString>;
42
42
  data: z.ZodAny;
43
43
  x: z.ZodOptional<z.ZodNumber>;
44
44
  y: z.ZodOptional<z.ZodNumber>;
45
45
  width: z.ZodOptional<z.ZodNumber>;
46
46
  height: z.ZodOptional<z.ZodNumber>;
47
- style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
47
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
48
48
  }, z.core.$strip>>>;
49
49
  }, z.core.$strip>;
50
50
  declare const EdgeSchema: z.ZodObject<{
@@ -56,19 +56,25 @@ declare const EdgeSchema: z.ZodObject<{
56
56
  weight: z.ZodOptional<z.ZodNumber>;
57
57
  sourcePort: z.ZodOptional<z.ZodString>;
58
58
  targetPort: z.ZodOptional<z.ZodString>;
59
+ mode: z.ZodOptional<z.ZodEnum<{
60
+ directed: "directed";
61
+ undirected: "undirected";
62
+ bidirectional: "bidirectional";
63
+ }>>;
59
64
  data: z.ZodAny;
60
65
  x: z.ZodOptional<z.ZodNumber>;
61
66
  y: z.ZodOptional<z.ZodNumber>;
62
67
  width: z.ZodOptional<z.ZodNumber>;
63
68
  height: z.ZodOptional<z.ZodNumber>;
64
69
  color: z.ZodOptional<z.ZodString>;
65
- style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
70
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
66
71
  }, z.core.$strip>;
67
72
  declare const GraphSchema: z.ZodObject<{
68
73
  id: z.ZodString;
69
- type: z.ZodEnum<{
74
+ mode: z.ZodEnum<{
70
75
  directed: "directed";
71
76
  undirected: "undirected";
77
+ bidirectional: "bidirectional";
72
78
  }>;
73
79
  initialNodeId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
74
80
  nodes: z.ZodArray<z.ZodObject<{
@@ -84,21 +90,21 @@ declare const GraphSchema: z.ZodObject<{
84
90
  height: z.ZodOptional<z.ZodNumber>;
85
91
  shape: z.ZodOptional<z.ZodString>;
86
92
  color: z.ZodOptional<z.ZodString>;
87
- style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
93
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
88
94
  ports: z.ZodOptional<z.ZodArray<z.ZodObject<{
89
95
  name: z.ZodString;
90
- direction: z.ZodOptional<z.ZodEnum<{
96
+ direction: z.ZodEnum<{
91
97
  in: "in";
92
98
  out: "out";
93
99
  inout: "inout";
94
- }>>;
100
+ }>;
95
101
  label: z.ZodOptional<z.ZodString>;
96
102
  data: z.ZodAny;
97
103
  x: z.ZodOptional<z.ZodNumber>;
98
104
  y: z.ZodOptional<z.ZodNumber>;
99
105
  width: z.ZodOptional<z.ZodNumber>;
100
106
  height: z.ZodOptional<z.ZodNumber>;
101
- style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
107
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
102
108
  }, z.core.$strip>>>;
103
109
  }, z.core.$strip>>;
104
110
  edges: z.ZodArray<z.ZodObject<{
@@ -110,13 +116,18 @@ declare const GraphSchema: z.ZodObject<{
110
116
  weight: z.ZodOptional<z.ZodNumber>;
111
117
  sourcePort: z.ZodOptional<z.ZodString>;
112
118
  targetPort: z.ZodOptional<z.ZodString>;
119
+ mode: z.ZodOptional<z.ZodEnum<{
120
+ directed: "directed";
121
+ undirected: "undirected";
122
+ bidirectional: "bidirectional";
123
+ }>>;
113
124
  data: z.ZodAny;
114
125
  x: z.ZodOptional<z.ZodNumber>;
115
126
  y: z.ZodOptional<z.ZodNumber>;
116
127
  width: z.ZodOptional<z.ZodNumber>;
117
128
  height: z.ZodOptional<z.ZodNumber>;
118
129
  color: z.ZodOptional<z.ZodString>;
119
- style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
130
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
120
131
  }, z.core.$strip>>;
121
132
  data: z.ZodAny;
122
133
  direction: z.ZodOptional<z.ZodEnum<{
@@ -125,7 +136,7 @@ declare const GraphSchema: z.ZodObject<{
125
136
  left: "left";
126
137
  right: "right";
127
138
  }>>;
128
- style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
139
+ style: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
129
140
  }, z.core.$strip>;
130
141
  interface GraphValidationIssue {
131
142
  code: string;
@@ -140,5 +151,6 @@ declare function getGraphPortIssues(value: unknown): GraphValidationIssue[];
140
151
  declare function getGraphNodeIssues(value: unknown): GraphValidationIssue[];
141
152
  declare function getGraphEdgeIssues(value: unknown): GraphValidationIssue[];
142
153
  declare function getGraphIssues(value: unknown): GraphValidationIssue[];
154
+ declare function validateGraph(value: unknown): GraphValidationIssue[];
143
155
  //#endregion
144
- export { EdgeSchema, GraphSchema, GraphValidationIssue, NodeSchema, PortSchema, getGraphEdgeIssues, getGraphIssues, getGraphNodeIssues, getGraphPortIssues, isGraph, isGraphEdge, isGraphNode, isGraphPort };
156
+ export { EdgeSchema, GraphSchema, GraphValidationIssue, NodeSchema, PortSchema, getGraphEdgeIssues, getGraphIssues, getGraphNodeIssues, getGraphPortIssues, isGraph, isGraphEdge, isGraphNode, isGraphPort, validateGraph };
package/dist/schemas.mjs CHANGED
@@ -1,7 +1,16 @@
1
1
  import * as z from "zod";
2
2
 
3
3
  //#region src/schemas.ts
4
- const StyleSchema = z.record(z.string(), z.union([z.string(), z.number()]));
4
+ const StyleSchema = z.record(z.string(), z.union([
5
+ z.string(),
6
+ z.number(),
7
+ z.boolean()
8
+ ]));
9
+ const ModeSchema = z.enum([
10
+ "directed",
11
+ "undirected",
12
+ "bidirectional"
13
+ ]);
5
14
  const PortDirectionSchema = z.enum([
6
15
  "in",
7
16
  "out",
@@ -9,7 +18,7 @@ const PortDirectionSchema = z.enum([
9
18
  ]);
10
19
  const PortSchema = z.object({
11
20
  name: z.string(),
12
- direction: PortDirectionSchema.optional(),
21
+ direction: PortDirectionSchema,
13
22
  label: z.string().optional(),
14
23
  data: z.any(),
15
24
  x: z.number().optional(),
@@ -43,6 +52,7 @@ const EdgeSchema = z.object({
43
52
  weight: z.number().optional(),
44
53
  sourcePort: z.string().optional(),
45
54
  targetPort: z.string().optional(),
55
+ mode: ModeSchema.optional(),
46
56
  data: z.any(),
47
57
  x: z.number().optional(),
48
58
  y: z.number().optional(),
@@ -53,7 +63,7 @@ const EdgeSchema = z.object({
53
63
  });
54
64
  const GraphSchema = z.object({
55
65
  id: z.string(),
56
- type: z.enum(["directed", "undirected"]),
66
+ mode: ModeSchema,
57
67
  initialNodeId: z.string().nullable().optional(),
58
68
  nodes: z.array(NodeSchema),
59
69
  edges: z.array(EdgeSchema),
@@ -85,7 +95,7 @@ function isGraphEdge(value) {
85
95
  return EdgeSchema.safeParse(value).success;
86
96
  }
87
97
  function isGraph(value) {
88
- return GraphSchema.safeParse(value).success;
98
+ return validateGraph(value).length === 0;
89
99
  }
90
100
  function getGraphPortIssues(value) {
91
101
  return getValidationIssues(PortSchema, value);
@@ -97,8 +107,131 @@ function getGraphEdgeIssues(value) {
97
107
  return getValidationIssues(EdgeSchema, value);
98
108
  }
99
109
  function getGraphIssues(value) {
100
- return getValidationIssues(GraphSchema, value);
110
+ return validateGraph(value);
111
+ }
112
+ function createIssue(code, message, path) {
113
+ return {
114
+ code,
115
+ message,
116
+ path
117
+ };
118
+ }
119
+ function getDuplicateIndexes(items, getKey) {
120
+ const indexesByKey = /* @__PURE__ */ new Map();
121
+ items.forEach((item, index) => {
122
+ const key = getKey(item);
123
+ if (key == null) return;
124
+ const indexes = indexesByKey.get(key) ?? [];
125
+ indexes.push(index);
126
+ indexesByKey.set(key, indexes);
127
+ });
128
+ for (const [key, indexes] of indexesByKey) if (indexes.length < 2) indexesByKey.delete(key);
129
+ return indexesByKey;
130
+ }
131
+ function getGraphInvariantIssues(graph) {
132
+ const issues = [];
133
+ const nodeIndexes = /* @__PURE__ */ new Map();
134
+ const nodesById = /* @__PURE__ */ new Map();
135
+ for (const [id, indexes] of getDuplicateIndexes(graph.nodes, (node) => node.id)) for (const index of indexes) issues.push(createIssue("duplicate_node_id", `Duplicate node id "${id}"`, [
136
+ "nodes",
137
+ index,
138
+ "id"
139
+ ]));
140
+ for (const [id, indexes] of getDuplicateIndexes(graph.edges, (edge) => edge.id)) for (const index of indexes) issues.push(createIssue("duplicate_edge_id", `Duplicate edge id "${id}"`, [
141
+ "edges",
142
+ index,
143
+ "id"
144
+ ]));
145
+ graph.nodes.forEach((node, index) => {
146
+ nodeIndexes.set(node.id, index);
147
+ nodesById.set(node.id, node);
148
+ });
149
+ if (graph.initialNodeId && !nodeIndexes.has(graph.initialNodeId)) issues.push(createIssue("missing_initial_node", `Initial node "${graph.initialNodeId}" does not exist`, ["initialNodeId"]));
150
+ graph.nodes.forEach((node, index) => {
151
+ if (node.id === "") issues.push(createIssue("empty_node_id", "Node id must be a non-empty string", [
152
+ "nodes",
153
+ index,
154
+ "id"
155
+ ]));
156
+ if (node.parentId === "") issues.push(createIssue("empty_parent_id", "Node parentId must be a non-empty string", [
157
+ "nodes",
158
+ index,
159
+ "parentId"
160
+ ]));
161
+ else if (node.parentId != null && !nodeIndexes.has(node.parentId)) issues.push(createIssue("missing_parent", `Parent node "${node.parentId}" does not exist`, [
162
+ "nodes",
163
+ index,
164
+ "parentId"
165
+ ]));
166
+ if (node.initialNodeId && !nodeIndexes.has(node.initialNodeId)) issues.push(createIssue("missing_node_initial", `Initial node "${node.initialNodeId}" does not exist`, [
167
+ "nodes",
168
+ index,
169
+ "initialNodeId"
170
+ ]));
171
+ for (const [name, indexes] of getDuplicateIndexes(node.ports ?? [], (port) => port.name)) for (const portIndex of indexes) issues.push(createIssue("duplicate_port_name", `Duplicate port name "${name}" on node "${node.id}"`, [
172
+ "nodes",
173
+ index,
174
+ "ports",
175
+ portIndex,
176
+ "name"
177
+ ]));
178
+ });
179
+ for (const node of graph.nodes) {
180
+ const seen = /* @__PURE__ */ new Set();
181
+ let current = node.parentId;
182
+ while (current != null) {
183
+ if (current === node.id || seen.has(current)) {
184
+ issues.push(createIssue("parent_cycle", `Node "${node.id}" is part of a parent cycle`, [
185
+ "nodes",
186
+ nodeIndexes.get(node.id) ?? 0,
187
+ "parentId"
188
+ ]));
189
+ break;
190
+ }
191
+ seen.add(current);
192
+ current = nodesById.get(current)?.parentId;
193
+ }
194
+ }
195
+ graph.edges.forEach((edge, index) => {
196
+ if (edge.id === "") issues.push(createIssue("empty_edge_id", "Edge id must be a non-empty string", [
197
+ "edges",
198
+ index,
199
+ "id"
200
+ ]));
201
+ const source = nodesById.get(edge.sourceId);
202
+ const target = nodesById.get(edge.targetId);
203
+ if (!source) issues.push(createIssue("missing_source_node", `Source node "${edge.sourceId}" does not exist`, [
204
+ "edges",
205
+ index,
206
+ "sourceId"
207
+ ]));
208
+ if (!target) issues.push(createIssue("missing_target_node", `Target node "${edge.targetId}" does not exist`, [
209
+ "edges",
210
+ index,
211
+ "targetId"
212
+ ]));
213
+ if (source && edge.sourcePort !== void 0 && !source.ports?.some((port) => port.name === edge.sourcePort)) issues.push(createIssue("missing_source_port", `Port "${edge.sourcePort}" does not exist on source node "${edge.sourceId}"`, [
214
+ "edges",
215
+ index,
216
+ "sourcePort"
217
+ ]));
218
+ if (target && edge.targetPort !== void 0 && !target.ports?.some((port) => port.name === edge.targetPort)) issues.push(createIssue("missing_target_port", `Port "${edge.targetPort}" does not exist on target node "${edge.targetId}"`, [
219
+ "edges",
220
+ index,
221
+ "targetPort"
222
+ ]));
223
+ });
224
+ return issues;
225
+ }
226
+ function validateGraph(value) {
227
+ const shapeResult = GraphSchema.safeParse(value);
228
+ if (!shapeResult.success) return shapeResult.error.issues.map((issue) => ({
229
+ code: issue.code,
230
+ message: issue.message,
231
+ path: issue.path.map((segment) => typeof segment === "symbol" ? String(segment) : segment)
232
+ }));
233
+ return getGraphInvariantIssues(shapeResult.data);
101
234
  }
102
235
 
103
236
  //#endregion
104
- export { EdgeSchema, GraphSchema, NodeSchema, PortSchema, getGraphEdgeIssues, getGraphIssues, getGraphNodeIssues, getGraphPortIssues, isGraph, isGraphEdge, isGraphNode, isGraphPort };
237
+ export { EdgeSchema, GraphSchema, NodeSchema, PortSchema, getGraphEdgeIssues, getGraphIssues, getGraphNodeIssues, getGraphPortIssues, isGraph, isGraphEdge, isGraphNode, isGraphPort, validateGraph };
@@ -1,4 +1,15 @@
1
1
  //#region src/types.d.ts
2
+ /**
3
+ * Directedness of a graph or an individual edge.
4
+ *
5
+ * - `'directed'` — edge points from source to target.
6
+ * - `'undirected'` — edge has no direction; traversable both ways.
7
+ * - `'bidirectional'` — edge points both ways (arrows on both ends).
8
+ *
9
+ * Set at the graph level as the default ({@link Graph.mode}); individual edges
10
+ * may override it ({@link GraphEdge.mode}).
11
+ */
12
+ type GraphMode = 'directed' | 'undirected' | 'bidirectional';
2
13
  interface EntityRect {
3
14
  x: number;
4
15
  y: number;
@@ -11,7 +22,7 @@ interface GraphEntity {
11
22
  y?: number;
12
23
  width?: number;
13
24
  height?: number;
14
- style?: Record<string, string | number>;
25
+ style?: Record<string, string | number | boolean>;
15
26
  }
16
27
  /** Visual entity base — required position/size. */
17
28
  interface VisualGraphEntity {
@@ -19,7 +30,7 @@ interface VisualGraphEntity {
19
30
  y: number;
20
31
  width: number;
21
32
  height: number;
22
- style?: Record<string, string | number>;
33
+ style?: Record<string, string | number | boolean>;
23
34
  }
24
35
  type PortDirection = 'in' | 'out' | 'inout';
25
36
  interface PortConfig<TPortData = any> extends GraphEntity {
@@ -42,13 +53,14 @@ interface VisualPort<TPortData = any> extends GraphPort<TPortData> {
42
53
  }
43
54
  interface GraphConfig<TNodeData = any, TEdgeData = any, TGraphData = any, TPortData = any> {
44
55
  id?: string;
45
- type?: 'directed' | 'undirected';
56
+ /** Default directedness for all edges. Defaults to `'directed'`. */
57
+ mode?: GraphMode;
46
58
  initialNodeId?: string;
47
59
  nodes?: NodeConfig<TNodeData, TPortData>[];
48
60
  edges?: EdgeConfig<TEdgeData>[];
49
61
  data?: TGraphData;
50
62
  direction?: 'up' | 'down' | 'left' | 'right';
51
- style?: Record<string, string | number>;
63
+ style?: Record<string, string | number | boolean>;
52
64
  }
53
65
  interface NodeConfig<TNodeData = any, TPortData = any> extends GraphEntity {
54
66
  id: string;
@@ -87,18 +99,24 @@ interface EdgeConfig<TEdgeData = any> extends GraphEntity {
87
99
  sourcePort?: string;
88
100
  /** Port name on the target node this edge connects to. */
89
101
  targetPort?: string;
102
+ /**
103
+ * Per-edge directedness override. When absent, the edge inherits the graph's
104
+ * {@link GraphConfig.mode}.
105
+ */
106
+ mode?: GraphMode;
90
107
  data?: TEdgeData;
91
108
  color?: string;
92
109
  }
93
110
  interface Graph<TNodeData = any, TEdgeData = any, TGraphData = any, TPortData = any> {
94
111
  id: string;
95
- type: 'directed' | 'undirected';
112
+ /** Default directedness for all edges. */
113
+ mode: GraphMode;
96
114
  initialNodeId?: string | null;
97
115
  nodes: GraphNode<TNodeData, TPortData>[];
98
116
  edges: GraphEdge<TEdgeData>[];
99
117
  data: TGraphData;
100
118
  direction?: 'up' | 'down' | 'left' | 'right';
101
- style?: Record<string, string | number>;
119
+ style?: Record<string, string | number | boolean>;
102
120
  }
103
121
  interface GraphNode<TNodeData = any, TPortData = any> extends GraphEntity {
104
122
  type: 'node';
@@ -127,6 +145,11 @@ interface GraphEdge<TEdgeData = any> extends GraphEntity {
127
145
  sourcePort?: string;
128
146
  /** Port name on the target node this edge connects to. */
129
147
  targetPort?: string;
148
+ /**
149
+ * Per-edge directedness override. When absent, the edge inherits the graph's
150
+ * {@link Graph.mode}.
151
+ */
152
+ mode?: GraphMode;
130
153
  data: TEdgeData;
131
154
  color?: string;
132
155
  }
@@ -352,4 +375,4 @@ interface TransitionOptions<TState, TEvent> {
352
375
  id?: string;
353
376
  }
354
377
  //#endregion
355
- export { VisualEdge as A, NodeConfig as C, SinglePathOptions as D, PortDirection as E, VisualNode as F, VisualPort as I, WalkContext as L, VisualGraphConfig as M, VisualGraphEntity as N, TransitionOptions as O, VisualGraphFormatConverter as P, WalkOptions as R, NodeChange as S, PortConfig as T, GraphPatch as _, EdgeChange as a, GraphStep as b, EntitiesUpdate as c, GraphConfig as d, GraphDiff as f, GraphNode as g, GraphFormatConverter as h, DeleteNodeOptions as i, VisualGraph as j, TraversalOptions as k, EntityRect as l, GraphEntity as m, AllPairsShortestPathsOptions as n, EdgeConfig as o, GraphEdge as p, CoverageStats as r, EntitiesConfig as s, AStarOptions as t, Graph as u, GraphPath as v, PathOptions as w, MSTOptions as x, GraphPort as y, WeightedWalkOptions as z };
378
+ export { TraversalOptions as A, WeightedWalkOptions as B, NodeChange as C, PortDirection as D, PortConfig as E, VisualGraphFormatConverter as F, VisualNode as I, VisualPort as L, VisualGraph as M, VisualGraphConfig as N, SinglePathOptions as O, VisualGraphEntity as P, WalkContext as R, MSTOptions as S, PathOptions as T, GraphNode as _, EdgeChange as a, GraphPort as b, EntitiesUpdate as c, GraphConfig as d, GraphDiff as f, GraphMode as g, GraphFormatConverter as h, DeleteNodeOptions as i, VisualEdge as j, TransitionOptions as k, EntityRect as l, GraphEntity as m, AllPairsShortestPathsOptions as n, EdgeConfig as o, GraphEdge as p, CoverageStats as r, EntitiesConfig as s, AStarOptions as t, Graph as u, GraphPatch as v, NodeConfig as w, GraphStep as x, GraphPath as y, WalkOptions as z };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@statelyai/graph",
3
3
  "type": "module",
4
- "version": "0.12.0",
4
+ "version": "1.0.0",
5
5
  "description": "A TypeScript-first graph library with plain JSON-serializable objects",
6
6
  "author": "David Khourshid <david@stately.ai>",
7
7
  "license": "MIT",
@@ -28,6 +28,7 @@
28
28
  "./adjacency-list": "./dist/formats/adjacency-list/index.mjs",
29
29
  "./converter": "./dist/formats/converter/index.mjs",
30
30
  "./cytoscape": "./dist/formats/cytoscape/index.mjs",
31
+ "./d2": "./dist/formats/d2/index.mjs",
31
32
  "./d3": "./dist/formats/d3/index.mjs",
32
33
  "./dot": "./dist/formats/dot/index.mjs",
33
34
  "./edge-list": "./dist/formats/edge-list/index.mjs",
@@ -34,6 +34,14 @@
34
34
  "targetPort": {
35
35
  "type": "string"
36
36
  },
37
+ "mode": {
38
+ "type": "string",
39
+ "enum": [
40
+ "directed",
41
+ "undirected",
42
+ "bidirectional"
43
+ ]
44
+ },
37
45
  "data": {},
38
46
  "x": {
39
47
  "type": "number"
@@ -62,6 +70,9 @@
62
70
  },
63
71
  {
64
72
  "type": "number"
73
+ },
74
+ {
75
+ "type": "boolean"
65
76
  }
66
77
  ]
67
78
  }
@@ -5,11 +5,12 @@
5
5
  "id": {
6
6
  "type": "string"
7
7
  },
8
- "type": {
8
+ "mode": {
9
9
  "type": "string",
10
10
  "enum": [
11
11
  "directed",
12
- "undirected"
12
+ "undirected",
13
+ "bidirectional"
13
14
  ]
14
15
  },
15
16
  "initialNodeId": {
@@ -95,6 +96,9 @@
95
96
  },
96
97
  {
97
98
  "type": "number"
99
+ },
100
+ {
101
+ "type": "boolean"
98
102
  }
99
103
  ]
100
104
  }
@@ -143,6 +147,9 @@
143
147
  },
144
148
  {
145
149
  "type": "number"
150
+ },
151
+ {
152
+ "type": "boolean"
146
153
  }
147
154
  ]
148
155
  }
@@ -150,6 +157,7 @@
150
157
  },
151
158
  "required": [
152
159
  "name",
160
+ "direction",
153
161
  "data"
154
162
  ],
155
163
  "additionalProperties": false
@@ -201,6 +209,14 @@
201
209
  "targetPort": {
202
210
  "type": "string"
203
211
  },
212
+ "mode": {
213
+ "type": "string",
214
+ "enum": [
215
+ "directed",
216
+ "undirected",
217
+ "bidirectional"
218
+ ]
219
+ },
204
220
  "data": {},
205
221
  "x": {
206
222
  "type": "number"
@@ -229,6 +245,9 @@
229
245
  },
230
246
  {
231
247
  "type": "number"
248
+ },
249
+ {
250
+ "type": "boolean"
232
251
  }
233
252
  ]
234
253
  }
@@ -266,6 +285,9 @@
266
285
  },
267
286
  {
268
287
  "type": "number"
288
+ },
289
+ {
290
+ "type": "boolean"
269
291
  }
270
292
  ]
271
293
  }
@@ -273,7 +295,7 @@
273
295
  },
274
296
  "required": [
275
297
  "id",
276
- "type",
298
+ "mode",
277
299
  "nodes",
278
300
  "edges",
279
301
  "data"
@@ -70,6 +70,9 @@
70
70
  },
71
71
  {
72
72
  "type": "number"
73
+ },
74
+ {
75
+ "type": "boolean"
73
76
  }
74
77
  ]
75
78
  }
@@ -118,6 +121,9 @@
118
121
  },
119
122
  {
120
123
  "type": "number"
124
+ },
125
+ {
126
+ "type": "boolean"
121
127
  }
122
128
  ]
123
129
  }
@@ -125,6 +131,7 @@
125
131
  },
126
132
  "required": [
127
133
  "name",
134
+ "direction",
128
135
  "data"
129
136
  ],
130
137
  "additionalProperties": false