effect 3.17.13 → 3.18.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 (65) hide show
  1. package/Graph/package.json +6 -0
  2. package/dist/cjs/Context.js +11 -3
  3. package/dist/cjs/Context.js.map +1 -1
  4. package/dist/cjs/Effect.js.map +1 -1
  5. package/dist/cjs/ExecutionPlan.js +4 -4
  6. package/dist/cjs/Graph.js +2964 -0
  7. package/dist/cjs/Graph.js.map +1 -0
  8. package/dist/cjs/Predicate.js +2 -3
  9. package/dist/cjs/Predicate.js.map +1 -1
  10. package/dist/cjs/Tracer.js.map +1 -1
  11. package/dist/cjs/index.js +4 -2
  12. package/dist/cjs/index.js.map +1 -1
  13. package/dist/cjs/internal/core-effect.js +1 -1
  14. package/dist/cjs/internal/core-effect.js.map +1 -1
  15. package/dist/cjs/internal/effect/circular.js +12 -2
  16. package/dist/cjs/internal/effect/circular.js.map +1 -1
  17. package/dist/cjs/internal/metric/hook.js +6 -1
  18. package/dist/cjs/internal/metric/hook.js.map +1 -1
  19. package/dist/cjs/internal/version.js +1 -1
  20. package/dist/cjs/internal/version.js.map +1 -1
  21. package/dist/dts/Context.d.ts +27 -3
  22. package/dist/dts/Context.d.ts.map +1 -1
  23. package/dist/dts/Effect.d.ts +4 -0
  24. package/dist/dts/Effect.d.ts.map +1 -1
  25. package/dist/dts/ExecutionPlan.d.ts +8 -8
  26. package/dist/dts/Graph.d.ts +1652 -0
  27. package/dist/dts/Graph.d.ts.map +1 -0
  28. package/dist/dts/Predicate.d.ts +2 -3
  29. package/dist/dts/Predicate.d.ts.map +1 -1
  30. package/dist/dts/Tracer.d.ts +1 -1
  31. package/dist/dts/Tracer.d.ts.map +1 -1
  32. package/dist/dts/index.d.ts +5 -0
  33. package/dist/dts/index.d.ts.map +1 -1
  34. package/dist/dts/internal/core-effect.d.ts.map +1 -1
  35. package/dist/esm/Context.js +10 -2
  36. package/dist/esm/Context.js.map +1 -1
  37. package/dist/esm/Effect.js.map +1 -1
  38. package/dist/esm/ExecutionPlan.js +4 -4
  39. package/dist/esm/Graph.js +2905 -0
  40. package/dist/esm/Graph.js.map +1 -0
  41. package/dist/esm/Predicate.js +2 -3
  42. package/dist/esm/Predicate.js.map +1 -1
  43. package/dist/esm/Tracer.js.map +1 -1
  44. package/dist/esm/index.js +5 -0
  45. package/dist/esm/index.js.map +1 -1
  46. package/dist/esm/internal/core-effect.js +1 -1
  47. package/dist/esm/internal/core-effect.js.map +1 -1
  48. package/dist/esm/internal/effect/circular.js +12 -2
  49. package/dist/esm/internal/effect/circular.js.map +1 -1
  50. package/dist/esm/internal/metric/hook.js +6 -1
  51. package/dist/esm/internal/metric/hook.js.map +1 -1
  52. package/dist/esm/internal/version.js +1 -1
  53. package/dist/esm/internal/version.js.map +1 -1
  54. package/package.json +9 -1
  55. package/src/Context.ts +28 -3
  56. package/src/Effect.ts +5 -0
  57. package/src/ExecutionPlan.ts +8 -8
  58. package/src/Graph.ts +3564 -0
  59. package/src/Predicate.ts +2 -3
  60. package/src/Tracer.ts +2 -1
  61. package/src/index.ts +6 -0
  62. package/src/internal/core-effect.ts +2 -1
  63. package/src/internal/effect/circular.ts +31 -17
  64. package/src/internal/metric/hook.ts +6 -1
  65. package/src/internal/version.ts +1 -1
@@ -0,0 +1,1652 @@
1
+ /**
2
+ * @experimental
3
+ * @since 3.18.0
4
+ */
5
+ import * as Data from "./Data.js";
6
+ import * as Equal from "./Equal.js";
7
+ import type { Inspectable } from "./Inspectable.js";
8
+ import * as Option from "./Option.js";
9
+ import type { Pipeable } from "./Pipeable.js";
10
+ /**
11
+ * Unique identifier for Graph instances.
12
+ *
13
+ * @since 3.18.0
14
+ * @category symbol
15
+ */
16
+ export declare const TypeId: "~effect/Graph";
17
+ /**
18
+ * Type identifier for Graph instances.
19
+ *
20
+ * @since 3.18.0
21
+ * @category symbol
22
+ */
23
+ export type TypeId = typeof TypeId;
24
+ /**
25
+ * Node index for node identification using plain numbers.
26
+ *
27
+ * @since 3.18.0
28
+ * @category models
29
+ */
30
+ export type NodeIndex = number;
31
+ /**
32
+ * Edge index for edge identification using plain numbers.
33
+ *
34
+ * @since 3.18.0
35
+ * @category models
36
+ */
37
+ export type EdgeIndex = number;
38
+ /**
39
+ * Edge data containing source, target, and user data.
40
+ *
41
+ * @since 3.18.0
42
+ * @category models
43
+ */
44
+ export declare class Edge<E> extends Data.Class<{
45
+ readonly source: NodeIndex;
46
+ readonly target: NodeIndex;
47
+ readonly data: E;
48
+ }> {
49
+ }
50
+ /**
51
+ * Graph type for distinguishing directed and undirected graphs.
52
+ *
53
+ * @since 3.18.0
54
+ * @category models
55
+ */
56
+ export type Kind = "directed" | "undirected";
57
+ /**
58
+ * Graph prototype interface.
59
+ *
60
+ * @since 3.18.0
61
+ * @category models
62
+ */
63
+ export interface Proto<out N, out E> extends Iterable<readonly [NodeIndex, N]>, Equal.Equal, Pipeable, Inspectable {
64
+ readonly [TypeId]: TypeId;
65
+ readonly nodes: Map<NodeIndex, N>;
66
+ readonly edges: Map<EdgeIndex, Edge<E>>;
67
+ readonly adjacency: Map<NodeIndex, Array<EdgeIndex>>;
68
+ readonly reverseAdjacency: Map<NodeIndex, Array<EdgeIndex>>;
69
+ nextNodeIndex: NodeIndex;
70
+ nextEdgeIndex: EdgeIndex;
71
+ isAcyclic: Option.Option<boolean>;
72
+ }
73
+ /**
74
+ * Immutable graph interface.
75
+ *
76
+ * @since 3.18.0
77
+ * @category models
78
+ */
79
+ export interface Graph<out N, out E, T extends Kind = "directed"> extends Proto<N, E> {
80
+ readonly type: T;
81
+ readonly mutable: false;
82
+ }
83
+ /**
84
+ * Mutable graph interface.
85
+ *
86
+ * @since 3.18.0
87
+ * @category models
88
+ */
89
+ export interface MutableGraph<out N, out E, T extends Kind = "directed"> extends Proto<N, E> {
90
+ readonly type: T;
91
+ readonly mutable: true;
92
+ }
93
+ /**
94
+ * Directed graph type alias.
95
+ *
96
+ * @since 3.18.0
97
+ * @category models
98
+ */
99
+ export type DirectedGraph<N, E> = Graph<N, E, "directed">;
100
+ /**
101
+ * Undirected graph type alias.
102
+ *
103
+ * @since 3.18.0
104
+ * @category models
105
+ */
106
+ export type UndirectedGraph<N, E> = Graph<N, E, "undirected">;
107
+ /**
108
+ * Mutable directed graph type alias.
109
+ *
110
+ * @since 3.18.0
111
+ * @category models
112
+ */
113
+ export type MutableDirectedGraph<N, E> = MutableGraph<N, E, "directed">;
114
+ /**
115
+ * Mutable undirected graph type alias.
116
+ *
117
+ * @since 3.18.0
118
+ * @category models
119
+ */
120
+ export type MutableUndirectedGraph<N, E> = MutableGraph<N, E, "undirected">;
121
+ /**
122
+ * Creates a directed graph, optionally with initial mutations.
123
+ *
124
+ * @example
125
+ * ```ts
126
+ * import { Graph } from "effect"
127
+ *
128
+ * // Directed graph with initial nodes and edges
129
+ * const graph = Graph.directed<string, string>((mutable) => {
130
+ * const a = Graph.addNode(mutable, "A")
131
+ * const b = Graph.addNode(mutable, "B")
132
+ * const c = Graph.addNode(mutable, "C")
133
+ * Graph.addEdge(mutable, a, b, "A->B")
134
+ * Graph.addEdge(mutable, b, c, "B->C")
135
+ * })
136
+ * ```
137
+ *
138
+ * @since 3.18.0
139
+ * @category constructors
140
+ */
141
+ export declare const directed: <N, E>(mutate?: (mutable: MutableDirectedGraph<N, E>) => void) => DirectedGraph<N, E>;
142
+ /**
143
+ * Creates an undirected graph, optionally with initial mutations.
144
+ *
145
+ * @example
146
+ * ```ts
147
+ * import { Graph } from "effect"
148
+ *
149
+ * // Undirected graph with initial nodes and edges
150
+ * const graph = Graph.undirected<string, string>((mutable) => {
151
+ * const a = Graph.addNode(mutable, "A")
152
+ * const b = Graph.addNode(mutable, "B")
153
+ * const c = Graph.addNode(mutable, "C")
154
+ * Graph.addEdge(mutable, a, b, "A-B")
155
+ * Graph.addEdge(mutable, b, c, "B-C")
156
+ * })
157
+ * ```
158
+ *
159
+ * @since 3.18.0
160
+ * @category constructors
161
+ */
162
+ export declare const undirected: <N, E>(mutate?: (mutable: MutableUndirectedGraph<N, E>) => void) => UndirectedGraph<N, E>;
163
+ /**
164
+ * Creates a mutable scope for safe graph mutations by copying the data structure.
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * import { Graph } from "effect"
169
+ *
170
+ * const graph = Graph.directed<string, number>()
171
+ * const mutable = Graph.beginMutation(graph)
172
+ * // Now mutable can be safely modified without affecting original graph
173
+ * ```
174
+ *
175
+ * @since 3.18.0
176
+ * @category mutations
177
+ */
178
+ export declare const beginMutation: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T>) => MutableGraph<N, E, T>;
179
+ /**
180
+ * Converts a mutable graph back to an immutable graph, ending the mutation scope.
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * import { Graph } from "effect"
185
+ *
186
+ * const graph = Graph.directed<string, number>()
187
+ * const mutable = Graph.beginMutation(graph)
188
+ * // ... perform mutations on mutable ...
189
+ * const newGraph = Graph.endMutation(mutable)
190
+ * ```
191
+ *
192
+ * @since 3.18.0
193
+ * @category mutations
194
+ */
195
+ export declare const endMutation: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>) => Graph<N, E, T>;
196
+ /**
197
+ * Performs scoped mutations on a graph, automatically managing the mutation lifecycle.
198
+ *
199
+ * @example
200
+ * ```ts
201
+ * import { Graph } from "effect"
202
+ *
203
+ * const graph = Graph.directed<string, number>()
204
+ * const newGraph = Graph.mutate(graph, (mutable) => {
205
+ * // Safe mutations go here
206
+ * // mutable gets automatically converted back to immutable
207
+ * })
208
+ * ```
209
+ *
210
+ * @since 3.18.0
211
+ * @category mutations
212
+ */
213
+ export declare const mutate: {
214
+ /**
215
+ * Performs scoped mutations on a graph, automatically managing the mutation lifecycle.
216
+ *
217
+ * @example
218
+ * ```ts
219
+ * import { Graph } from "effect"
220
+ *
221
+ * const graph = Graph.directed<string, number>()
222
+ * const newGraph = Graph.mutate(graph, (mutable) => {
223
+ * // Safe mutations go here
224
+ * // mutable gets automatically converted back to immutable
225
+ * })
226
+ * ```
227
+ *
228
+ * @since 3.18.0
229
+ * @category mutations
230
+ */
231
+ <N, E, T extends Kind = "directed">(f: (mutable: MutableGraph<N, E, T>) => void): (graph: Graph<N, E, T>) => Graph<N, E, T>;
232
+ /**
233
+ * Performs scoped mutations on a graph, automatically managing the mutation lifecycle.
234
+ *
235
+ * @example
236
+ * ```ts
237
+ * import { Graph } from "effect"
238
+ *
239
+ * const graph = Graph.directed<string, number>()
240
+ * const newGraph = Graph.mutate(graph, (mutable) => {
241
+ * // Safe mutations go here
242
+ * // mutable gets automatically converted back to immutable
243
+ * })
244
+ * ```
245
+ *
246
+ * @since 3.18.0
247
+ * @category mutations
248
+ */
249
+ <N, E, T extends Kind = "directed">(graph: Graph<N, E, T>, f: (mutable: MutableGraph<N, E, T>) => void): Graph<N, E, T>;
250
+ };
251
+ /**
252
+ * Adds a new node to a mutable graph and returns its index.
253
+ *
254
+ * @example
255
+ * ```ts
256
+ * import { Graph } from "effect"
257
+ *
258
+ * const result = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
259
+ * const nodeA = Graph.addNode(mutable, "Node A")
260
+ * const nodeB = Graph.addNode(mutable, "Node B")
261
+ * console.log(nodeA) // NodeIndex with value 0
262
+ * console.log(nodeB) // NodeIndex with value 1
263
+ * })
264
+ * ```
265
+ *
266
+ * @since 3.18.0
267
+ * @category mutations
268
+ */
269
+ export declare const addNode: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, data: N) => NodeIndex;
270
+ /**
271
+ * Gets the data associated with a node index, if it exists.
272
+ *
273
+ * @example
274
+ * ```ts
275
+ * import { Graph, Option } from "effect"
276
+ *
277
+ * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
278
+ * Graph.addNode(mutable, "Node A")
279
+ * })
280
+ *
281
+ * const nodeIndex = 0
282
+ * const nodeData = Graph.getNode(graph, nodeIndex)
283
+ *
284
+ * if (Option.isSome(nodeData)) {
285
+ * console.log(nodeData.value) // "Node A"
286
+ * }
287
+ * ```
288
+ *
289
+ * @since 3.18.0
290
+ * @category getters
291
+ */
292
+ export declare const getNode: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, nodeIndex: NodeIndex) => Option.Option<N>;
293
+ /**
294
+ * Checks if a node with the given index exists in the graph.
295
+ *
296
+ * @example
297
+ * ```ts
298
+ * import { Graph } from "effect"
299
+ *
300
+ * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
301
+ * Graph.addNode(mutable, "Node A")
302
+ * })
303
+ *
304
+ * const nodeIndex = 0
305
+ * const exists = Graph.hasNode(graph, nodeIndex)
306
+ * console.log(exists) // true
307
+ *
308
+ * const nonExistentIndex = 999
309
+ * const notExists = Graph.hasNode(graph, nonExistentIndex)
310
+ * console.log(notExists) // false
311
+ * ```
312
+ *
313
+ * @since 3.18.0
314
+ * @category getters
315
+ */
316
+ export declare const hasNode: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, nodeIndex: NodeIndex) => boolean;
317
+ /**
318
+ * Returns the number of nodes in the graph.
319
+ *
320
+ * @example
321
+ * ```ts
322
+ * import { Graph } from "effect"
323
+ *
324
+ * const emptyGraph = Graph.directed<string, number>()
325
+ * console.log(Graph.nodeCount(emptyGraph)) // 0
326
+ *
327
+ * const graphWithNodes = Graph.mutate(emptyGraph, (mutable) => {
328
+ * Graph.addNode(mutable, "Node A")
329
+ * Graph.addNode(mutable, "Node B")
330
+ * Graph.addNode(mutable, "Node C")
331
+ * })
332
+ *
333
+ * console.log(Graph.nodeCount(graphWithNodes)) // 3
334
+ * ```
335
+ *
336
+ * @since 3.18.0
337
+ * @category getters
338
+ */
339
+ export declare const nodeCount: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => number;
340
+ /**
341
+ * Finds the first node that matches the given predicate.
342
+ *
343
+ * @example
344
+ * ```ts
345
+ * import { Graph, Option } from "effect"
346
+ *
347
+ * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
348
+ * Graph.addNode(mutable, "Node A")
349
+ * Graph.addNode(mutable, "Node B")
350
+ * Graph.addNode(mutable, "Node C")
351
+ * })
352
+ *
353
+ * const result = Graph.findNode(graph, (data) => data.startsWith("Node B"))
354
+ * console.log(result) // Option.some(1)
355
+ *
356
+ * const notFound = Graph.findNode(graph, (data) => data === "Node D")
357
+ * console.log(notFound) // Option.none()
358
+ * ```
359
+ *
360
+ * @since 3.18.0
361
+ * @category getters
362
+ */
363
+ export declare const findNode: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, predicate: (data: N) => boolean) => Option.Option<NodeIndex>;
364
+ /**
365
+ * Finds all nodes that match the given predicate.
366
+ *
367
+ * @example
368
+ * ```ts
369
+ * import { Graph } from "effect"
370
+ *
371
+ * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
372
+ * Graph.addNode(mutable, "Start A")
373
+ * Graph.addNode(mutable, "Node B")
374
+ * Graph.addNode(mutable, "Start C")
375
+ * })
376
+ *
377
+ * const result = Graph.findNodes(graph, (data) => data.startsWith("Start"))
378
+ * console.log(result) // [0, 2]
379
+ *
380
+ * const empty = Graph.findNodes(graph, (data) => data === "Not Found")
381
+ * console.log(empty) // []
382
+ * ```
383
+ *
384
+ * @since 3.18.0
385
+ * @category getters
386
+ */
387
+ export declare const findNodes: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, predicate: (data: N) => boolean) => Array<NodeIndex>;
388
+ /**
389
+ * Finds the first edge that matches the given predicate.
390
+ *
391
+ * @example
392
+ * ```ts
393
+ * import { Graph, Option } from "effect"
394
+ *
395
+ * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
396
+ * const nodeA = Graph.addNode(mutable, "Node A")
397
+ * const nodeB = Graph.addNode(mutable, "Node B")
398
+ * const nodeC = Graph.addNode(mutable, "Node C")
399
+ * Graph.addEdge(mutable, nodeA, nodeB, 10)
400
+ * Graph.addEdge(mutable, nodeB, nodeC, 20)
401
+ * })
402
+ *
403
+ * const result = Graph.findEdge(graph, (data) => data > 15)
404
+ * console.log(result) // Option.some(1)
405
+ *
406
+ * const notFound = Graph.findEdge(graph, (data) => data > 100)
407
+ * console.log(notFound) // Option.none()
408
+ * ```
409
+ *
410
+ * @since 3.18.0
411
+ * @category getters
412
+ */
413
+ export declare const findEdge: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, predicate: (data: E, source: NodeIndex, target: NodeIndex) => boolean) => Option.Option<EdgeIndex>;
414
+ /**
415
+ * Finds all edges that match the given predicate.
416
+ *
417
+ * @example
418
+ * ```ts
419
+ * import { Graph } from "effect"
420
+ *
421
+ * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
422
+ * const nodeA = Graph.addNode(mutable, "Node A")
423
+ * const nodeB = Graph.addNode(mutable, "Node B")
424
+ * const nodeC = Graph.addNode(mutable, "Node C")
425
+ * Graph.addEdge(mutable, nodeA, nodeB, 10)
426
+ * Graph.addEdge(mutable, nodeB, nodeC, 20)
427
+ * Graph.addEdge(mutable, nodeC, nodeA, 30)
428
+ * })
429
+ *
430
+ * const result = Graph.findEdges(graph, (data) => data >= 20)
431
+ * console.log(result) // [1, 2]
432
+ *
433
+ * const empty = Graph.findEdges(graph, (data) => data > 100)
434
+ * console.log(empty) // []
435
+ * ```
436
+ *
437
+ * @since 3.18.0
438
+ * @category getters
439
+ */
440
+ export declare const findEdges: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, predicate: (data: E, source: NodeIndex, target: NodeIndex) => boolean) => Array<EdgeIndex>;
441
+ /**
442
+ * Updates a single node's data by applying a transformation function.
443
+ *
444
+ * @example
445
+ * ```ts
446
+ * import { Graph } from "effect"
447
+ *
448
+ * const graph = Graph.directed<string, number>((mutable) => {
449
+ * Graph.addNode(mutable, "Node A")
450
+ * Graph.addNode(mutable, "Node B")
451
+ * Graph.updateNode(mutable, 0, (data) => data.toUpperCase())
452
+ * })
453
+ *
454
+ * const nodeData = Graph.getNode(graph, 0)
455
+ * console.log(nodeData) // Option.some("NODE A")
456
+ * ```
457
+ *
458
+ * @since 3.18.0
459
+ * @category transformations
460
+ */
461
+ export declare const updateNode: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, index: NodeIndex, f: (data: N) => N) => void;
462
+ /**
463
+ * Updates a single edge's data by applying a transformation function.
464
+ *
465
+ * @example
466
+ * ```ts
467
+ * import { Graph } from "effect"
468
+ *
469
+ * const result = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
470
+ * const nodeA = Graph.addNode(mutable, "Node A")
471
+ * const nodeB = Graph.addNode(mutable, "Node B")
472
+ * const edgeIndex = Graph.addEdge(mutable, nodeA, nodeB, 10)
473
+ * Graph.updateEdge(mutable, edgeIndex, (data) => data * 2)
474
+ * })
475
+ *
476
+ * const edgeData = Graph.getEdge(result, 0)
477
+ * console.log(edgeData) // Option.some({ source: 0, target: 1, data: 20 })
478
+ * ```
479
+ *
480
+ * @since 3.18.0
481
+ * @category mutations
482
+ */
483
+ export declare const updateEdge: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, edgeIndex: EdgeIndex, f: (data: E) => E) => void;
484
+ /**
485
+ * Creates a new graph with transformed node data using the provided mapping function.
486
+ *
487
+ * @example
488
+ * ```ts
489
+ * import { Graph } from "effect"
490
+ *
491
+ * const graph = Graph.directed<string, number>((mutable) => {
492
+ * Graph.addNode(mutable, "node a")
493
+ * Graph.addNode(mutable, "node b")
494
+ * Graph.addNode(mutable, "node c")
495
+ * Graph.mapNodes(mutable, (data) => data.toUpperCase())
496
+ * })
497
+ *
498
+ * const nodeData = Graph.getNode(graph, 0)
499
+ * console.log(nodeData) // Option.some("NODE A")
500
+ * ```
501
+ *
502
+ * @since 3.18.0
503
+ * @category transformations
504
+ */
505
+ export declare const mapNodes: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, f: (data: N) => N) => void;
506
+ /**
507
+ * Transforms all edge data in a mutable graph using the provided mapping function.
508
+ *
509
+ * @example
510
+ * ```ts
511
+ * import { Graph } from "effect"
512
+ *
513
+ * const graph = Graph.directed<string, number>((mutable) => {
514
+ * const a = Graph.addNode(mutable, "A")
515
+ * const b = Graph.addNode(mutable, "B")
516
+ * const c = Graph.addNode(mutable, "C")
517
+ * Graph.addEdge(mutable, a, b, 10)
518
+ * Graph.addEdge(mutable, b, c, 20)
519
+ * Graph.mapEdges(mutable, (data) => data * 2)
520
+ * })
521
+ *
522
+ * const edgeData = Graph.getEdge(graph, 0)
523
+ * console.log(edgeData) // Option.some({ source: 0, target: 1, data: 20 })
524
+ * ```
525
+ *
526
+ * @since 3.18.0
527
+ * @category transformations
528
+ */
529
+ export declare const mapEdges: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, f: (data: E) => E) => void;
530
+ /**
531
+ * Reverses all edge directions in a mutable graph by swapping source and target nodes.
532
+ *
533
+ * @example
534
+ * ```ts
535
+ * import { Graph } from "effect"
536
+ *
537
+ * const graph = Graph.directed<string, number>((mutable) => {
538
+ * const a = Graph.addNode(mutable, "A")
539
+ * const b = Graph.addNode(mutable, "B")
540
+ * const c = Graph.addNode(mutable, "C")
541
+ * Graph.addEdge(mutable, a, b, 1) // A -> B
542
+ * Graph.addEdge(mutable, b, c, 2) // B -> C
543
+ * Graph.reverse(mutable) // Now B -> A, C -> B
544
+ * })
545
+ *
546
+ * const edge0 = Graph.getEdge(graph, 0)
547
+ * console.log(edge0) // Option.some({ source: 1, target: 0, data: 1 }) - B -> A
548
+ * ```
549
+ *
550
+ * @since 3.18.0
551
+ * @category transformations
552
+ */
553
+ export declare const reverse: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>) => void;
554
+ /**
555
+ * Filters and optionally transforms nodes in a mutable graph using a predicate function.
556
+ * Nodes that return Option.none are removed along with all their connected edges.
557
+ *
558
+ * @example
559
+ * ```ts
560
+ * import { Graph, Option } from "effect"
561
+ *
562
+ * const graph = Graph.directed<string, number>((mutable) => {
563
+ * const a = Graph.addNode(mutable, "active")
564
+ * const b = Graph.addNode(mutable, "inactive")
565
+ * const c = Graph.addNode(mutable, "active")
566
+ * Graph.addEdge(mutable, a, b, 1)
567
+ * Graph.addEdge(mutable, b, c, 2)
568
+ *
569
+ * // Keep only "active" nodes and transform to uppercase
570
+ * Graph.filterMapNodes(mutable, (data) =>
571
+ * data === "active" ? Option.some(data.toUpperCase()) : Option.none()
572
+ * )
573
+ * })
574
+ *
575
+ * console.log(Graph.nodeCount(graph)) // 2 (only "active" nodes remain)
576
+ * ```
577
+ *
578
+ * @since 3.18.0
579
+ * @category transformations
580
+ */
581
+ export declare const filterMapNodes: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, f: (data: N) => Option.Option<N>) => void;
582
+ /**
583
+ * Filters and optionally transforms edges in a mutable graph using a predicate function.
584
+ * Edges that return Option.none are removed from the graph.
585
+ *
586
+ * @example
587
+ * ```ts
588
+ * import { Graph, Option } from "effect"
589
+ *
590
+ * const graph = Graph.directed<string, number>((mutable) => {
591
+ * const a = Graph.addNode(mutable, "A")
592
+ * const b = Graph.addNode(mutable, "B")
593
+ * const c = Graph.addNode(mutable, "C")
594
+ * Graph.addEdge(mutable, a, b, 5)
595
+ * Graph.addEdge(mutable, b, c, 15)
596
+ * Graph.addEdge(mutable, c, a, 25)
597
+ *
598
+ * // Keep only edges with weight >= 10 and double their weight
599
+ * Graph.filterMapEdges(mutable, (data) =>
600
+ * data >= 10 ? Option.some(data * 2) : Option.none()
601
+ * )
602
+ * })
603
+ *
604
+ * console.log(Graph.edgeCount(graph)) // 2 (edges with weight 5 removed)
605
+ * ```
606
+ *
607
+ * @since 3.18.0
608
+ * @category transformations
609
+ */
610
+ export declare const filterMapEdges: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, f: (data: E) => Option.Option<E>) => void;
611
+ /**
612
+ * Filters nodes by removing those that don't match the predicate.
613
+ * This function modifies the mutable graph in place.
614
+ *
615
+ * @example
616
+ * ```ts
617
+ * import { Graph } from "effect"
618
+ *
619
+ * const graph = Graph.directed<string, number>((mutable) => {
620
+ * Graph.addNode(mutable, "active")
621
+ * Graph.addNode(mutable, "inactive")
622
+ * Graph.addNode(mutable, "pending")
623
+ * Graph.addNode(mutable, "active")
624
+ *
625
+ * // Keep only "active" nodes
626
+ * Graph.filterNodes(mutable, (data) => data === "active")
627
+ * })
628
+ *
629
+ * console.log(Graph.nodeCount(graph)) // 2 (only "active" nodes remain)
630
+ * ```
631
+ *
632
+ * @since 3.18.0
633
+ * @category transformations
634
+ */
635
+ export declare const filterNodes: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, predicate: (data: N) => boolean) => void;
636
+ /**
637
+ * Filters edges by removing those that don't match the predicate.
638
+ * This function modifies the mutable graph in place.
639
+ *
640
+ * @example
641
+ * ```ts
642
+ * import { Graph } from "effect"
643
+ *
644
+ * const graph = Graph.directed<string, number>((mutable) => {
645
+ * const a = Graph.addNode(mutable, "A")
646
+ * const b = Graph.addNode(mutable, "B")
647
+ * const c = Graph.addNode(mutable, "C")
648
+ *
649
+ * Graph.addEdge(mutable, a, b, 5)
650
+ * Graph.addEdge(mutable, b, c, 15)
651
+ * Graph.addEdge(mutable, c, a, 25)
652
+ *
653
+ * // Keep only edges with weight >= 10
654
+ * Graph.filterEdges(mutable, (data) => data >= 10)
655
+ * })
656
+ *
657
+ * console.log(Graph.edgeCount(graph)) // 2 (edge with weight 5 removed)
658
+ * ```
659
+ *
660
+ * @since 3.18.0
661
+ * @category transformations
662
+ */
663
+ export declare const filterEdges: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, predicate: (data: E) => boolean) => void;
664
+ /**
665
+ * Adds a new edge to a mutable graph and returns its index.
666
+ *
667
+ * @example
668
+ * ```ts
669
+ * import { Graph } from "effect"
670
+ *
671
+ * const result = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
672
+ * const nodeA = Graph.addNode(mutable, "Node A")
673
+ * const nodeB = Graph.addNode(mutable, "Node B")
674
+ * const edge = Graph.addEdge(mutable, nodeA, nodeB, 42)
675
+ * console.log(edge) // EdgeIndex with value 0
676
+ * })
677
+ * ```
678
+ *
679
+ * @since 3.18.0
680
+ * @category mutations
681
+ */
682
+ export declare const addEdge: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, source: NodeIndex, target: NodeIndex, data: E) => EdgeIndex;
683
+ /**
684
+ * Removes a node and all its incident edges from a mutable graph.
685
+ *
686
+ * @example
687
+ * ```ts
688
+ * import { Graph } from "effect"
689
+ *
690
+ * const result = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
691
+ * const nodeA = Graph.addNode(mutable, "Node A")
692
+ * const nodeB = Graph.addNode(mutable, "Node B")
693
+ * Graph.addEdge(mutable, nodeA, nodeB, 42)
694
+ *
695
+ * // Remove nodeA and all edges connected to it
696
+ * Graph.removeNode(mutable, nodeA)
697
+ * })
698
+ * ```
699
+ *
700
+ * @since 3.18.0
701
+ * @category mutations
702
+ */
703
+ export declare const removeNode: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, nodeIndex: NodeIndex) => void;
704
+ /**
705
+ * Removes an edge from a mutable graph.
706
+ *
707
+ * @example
708
+ * ```ts
709
+ * import { Graph } from "effect"
710
+ *
711
+ * const result = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
712
+ * const nodeA = Graph.addNode(mutable, "Node A")
713
+ * const nodeB = Graph.addNode(mutable, "Node B")
714
+ * const edge = Graph.addEdge(mutable, nodeA, nodeB, 42)
715
+ *
716
+ * // Remove the edge
717
+ * Graph.removeEdge(mutable, edge)
718
+ * })
719
+ * ```
720
+ *
721
+ * @since 3.18.0
722
+ * @category mutations
723
+ */
724
+ export declare const removeEdge: <N, E, T extends Kind = "directed">(mutable: MutableGraph<N, E, T>, edgeIndex: EdgeIndex) => void;
725
+ /**
726
+ * Gets the edge data associated with an edge index, if it exists.
727
+ *
728
+ * @example
729
+ * ```ts
730
+ * import { Graph, Option } from "effect"
731
+ *
732
+ * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
733
+ * const nodeA = Graph.addNode(mutable, "Node A")
734
+ * const nodeB = Graph.addNode(mutable, "Node B")
735
+ * Graph.addEdge(mutable, nodeA, nodeB, 42)
736
+ * })
737
+ *
738
+ * const edgeIndex = 0
739
+ * const edgeData = Graph.getEdge(graph, edgeIndex)
740
+ *
741
+ * if (Option.isSome(edgeData)) {
742
+ * console.log(edgeData.value.data) // 42
743
+ * console.log(edgeData.value.source) // NodeIndex(0)
744
+ * console.log(edgeData.value.target) // NodeIndex(1)
745
+ * }
746
+ * ```
747
+ *
748
+ * @since 3.18.0
749
+ * @category getters
750
+ */
751
+ export declare const getEdge: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, edgeIndex: EdgeIndex) => Option.Option<Edge<E>>;
752
+ /**
753
+ * Checks if an edge exists between two nodes in the graph.
754
+ *
755
+ * @example
756
+ * ```ts
757
+ * import { Graph } from "effect"
758
+ *
759
+ * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
760
+ * const nodeA = Graph.addNode(mutable, "Node A")
761
+ * const nodeB = Graph.addNode(mutable, "Node B")
762
+ * const nodeC = Graph.addNode(mutable, "Node C")
763
+ * Graph.addEdge(mutable, nodeA, nodeB, 42)
764
+ * })
765
+ *
766
+ * const nodeA = 0
767
+ * const nodeB = 1
768
+ * const nodeC = 2
769
+ *
770
+ * const hasAB = Graph.hasEdge(graph, nodeA, nodeB)
771
+ * console.log(hasAB) // true
772
+ *
773
+ * const hasAC = Graph.hasEdge(graph, nodeA, nodeC)
774
+ * console.log(hasAC) // false
775
+ * ```
776
+ *
777
+ * @since 3.18.0
778
+ * @category getters
779
+ */
780
+ export declare const hasEdge: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, source: NodeIndex, target: NodeIndex) => boolean;
781
+ /**
782
+ * Returns the number of edges in the graph.
783
+ *
784
+ * @example
785
+ * ```ts
786
+ * import { Graph } from "effect"
787
+ *
788
+ * const emptyGraph = Graph.directed<string, number>()
789
+ * console.log(Graph.edgeCount(emptyGraph)) // 0
790
+ *
791
+ * const graphWithEdges = Graph.mutate(emptyGraph, (mutable) => {
792
+ * const nodeA = Graph.addNode(mutable, "Node A")
793
+ * const nodeB = Graph.addNode(mutable, "Node B")
794
+ * const nodeC = Graph.addNode(mutable, "Node C")
795
+ * Graph.addEdge(mutable, nodeA, nodeB, 1)
796
+ * Graph.addEdge(mutable, nodeB, nodeC, 2)
797
+ * Graph.addEdge(mutable, nodeC, nodeA, 3)
798
+ * })
799
+ *
800
+ * console.log(Graph.edgeCount(graphWithEdges)) // 3
801
+ * ```
802
+ *
803
+ * @since 3.18.0
804
+ * @category getters
805
+ */
806
+ export declare const edgeCount: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => number;
807
+ /**
808
+ * Returns the neighboring nodes (targets of outgoing edges) for a given node.
809
+ *
810
+ * @example
811
+ * ```ts
812
+ * import { Graph } from "effect"
813
+ *
814
+ * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
815
+ * const nodeA = Graph.addNode(mutable, "Node A")
816
+ * const nodeB = Graph.addNode(mutable, "Node B")
817
+ * const nodeC = Graph.addNode(mutable, "Node C")
818
+ * Graph.addEdge(mutable, nodeA, nodeB, 1)
819
+ * Graph.addEdge(mutable, nodeA, nodeC, 2)
820
+ * })
821
+ *
822
+ * const nodeA = 0
823
+ * const nodeB = 1
824
+ * const nodeC = 2
825
+ *
826
+ * const neighborsA = Graph.neighbors(graph, nodeA)
827
+ * console.log(neighborsA) // [NodeIndex(1), NodeIndex(2)]
828
+ *
829
+ * const neighborsB = Graph.neighbors(graph, nodeB)
830
+ * console.log(neighborsB) // []
831
+ * ```
832
+ *
833
+ * @since 3.18.0
834
+ * @category getters
835
+ */
836
+ export declare const neighbors: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, nodeIndex: NodeIndex) => Array<NodeIndex>;
837
+ /**
838
+ * Get neighbors of a node in a specific direction for bidirectional traversal.
839
+ *
840
+ * @example
841
+ * ```ts
842
+ * import { Graph } from "effect"
843
+ *
844
+ * const graph = Graph.directed<string, string>((mutable) => {
845
+ * const a = Graph.addNode(mutable, "A")
846
+ * const b = Graph.addNode(mutable, "B")
847
+ * Graph.addEdge(mutable, a, b, "A->B")
848
+ * })
849
+ *
850
+ * const nodeA = 0
851
+ * const nodeB = 1
852
+ *
853
+ * // Get outgoing neighbors (nodes that nodeA points to)
854
+ * const outgoing = Graph.neighborsDirected(graph, nodeA, "outgoing")
855
+ *
856
+ * // Get incoming neighbors (nodes that point to nodeB)
857
+ * const incoming = Graph.neighborsDirected(graph, nodeB, "incoming")
858
+ * ```
859
+ *
860
+ * @since 3.18.0
861
+ * @category queries
862
+ */
863
+ export declare const neighborsDirected: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, nodeIndex: NodeIndex, direction: Direction) => Array<NodeIndex>;
864
+ /**
865
+ * Exports a graph to GraphViz DOT format for visualization.
866
+ *
867
+ * @example
868
+ * ```ts
869
+ * import { Graph } from "effect"
870
+ *
871
+ * const graph = Graph.mutate(Graph.directed<string, number>(), (mutable) => {
872
+ * const nodeA = Graph.addNode(mutable, "Node A")
873
+ * const nodeB = Graph.addNode(mutable, "Node B")
874
+ * const nodeC = Graph.addNode(mutable, "Node C")
875
+ * Graph.addEdge(mutable, nodeA, nodeB, 1)
876
+ * Graph.addEdge(mutable, nodeB, nodeC, 2)
877
+ * Graph.addEdge(mutable, nodeC, nodeA, 3)
878
+ * })
879
+ *
880
+ * const dot = Graph.toGraphViz(graph)
881
+ * console.log(dot)
882
+ * // digraph G {
883
+ * // "0" [label="Node A"];
884
+ * // "1" [label="Node B"];
885
+ * // "2" [label="Node C"];
886
+ * // "0" -> "1" [label="1"];
887
+ * // "1" -> "2" [label="2"];
888
+ * // "2" -> "0" [label="3"];
889
+ * // }
890
+ * ```
891
+ *
892
+ * @since 3.18.0
893
+ * @category utils
894
+ */
895
+ export declare const toGraphViz: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, options?: {
896
+ readonly nodeLabel?: (data: N) => string;
897
+ readonly edgeLabel?: (data: E) => string;
898
+ readonly graphName?: string;
899
+ }) => string;
900
+ /**
901
+ * Direction for graph traversal, indicating which edges to follow.
902
+ *
903
+ * @example
904
+ * ```ts
905
+ * import { Graph } from "effect"
906
+ *
907
+ * const graph = Graph.directed<string, string>((mutable) => {
908
+ * const a = Graph.addNode(mutable, "A")
909
+ * const b = Graph.addNode(mutable, "B")
910
+ * Graph.addEdge(mutable, a, b, "A->B")
911
+ * })
912
+ *
913
+ * // Follow outgoing edges (normal direction)
914
+ * const outgoingNodes = Array.from(Graph.indices(Graph.dfs(graph, { startNodes: [0], direction: "outgoing" })))
915
+ *
916
+ * // Follow incoming edges (reverse direction)
917
+ * const incomingNodes = Array.from(Graph.indices(Graph.dfs(graph, { startNodes: [1], direction: "incoming" })))
918
+ * ```
919
+ *
920
+ * @since 3.18.0
921
+ * @category models
922
+ */
923
+ export type Direction = "outgoing" | "incoming";
924
+ /**
925
+ * Checks if the graph is acyclic (contains no cycles).
926
+ *
927
+ * Uses depth-first search to detect back edges, which indicate cycles.
928
+ * For directed graphs, any back edge creates a cycle. For undirected graphs,
929
+ * a back edge that doesn't go to the immediate parent creates a cycle.
930
+ *
931
+ * @example
932
+ * ```ts
933
+ * import { Graph } from "effect"
934
+ *
935
+ * // Acyclic directed graph (DAG)
936
+ * const dag = Graph.directed<string, string>((mutable) => {
937
+ * const a = Graph.addNode(mutable, "A")
938
+ * const b = Graph.addNode(mutable, "B")
939
+ * const c = Graph.addNode(mutable, "C")
940
+ * Graph.addEdge(mutable, a, b, "A->B")
941
+ * Graph.addEdge(mutable, b, c, "B->C")
942
+ * })
943
+ * console.log(Graph.isAcyclic(dag)) // true
944
+ *
945
+ * // Cyclic directed graph
946
+ * const cyclic = Graph.directed<string, string>((mutable) => {
947
+ * const a = Graph.addNode(mutable, "A")
948
+ * const b = Graph.addNode(mutable, "B")
949
+ * Graph.addEdge(mutable, a, b, "A->B")
950
+ * Graph.addEdge(mutable, b, a, "B->A") // Creates cycle
951
+ * })
952
+ * console.log(Graph.isAcyclic(cyclic)) // false
953
+ * ```
954
+ *
955
+ * @since 3.18.0
956
+ * @category algorithms
957
+ */
958
+ export declare const isAcyclic: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => boolean;
959
+ /**
960
+ * Checks if an undirected graph is bipartite.
961
+ *
962
+ * A bipartite graph is one whose vertices can be divided into two disjoint sets
963
+ * such that no two vertices within the same set are adjacent. Uses BFS coloring
964
+ * to determine bipartiteness.
965
+ *
966
+ * @example
967
+ * ```ts
968
+ * import { Graph } from "effect"
969
+ *
970
+ * // Bipartite graph (alternating coloring possible)
971
+ * const bipartite = Graph.undirected<string, string>((mutable) => {
972
+ * const a = Graph.addNode(mutable, "A")
973
+ * const b = Graph.addNode(mutable, "B")
974
+ * const c = Graph.addNode(mutable, "C")
975
+ * const d = Graph.addNode(mutable, "D")
976
+ * Graph.addEdge(mutable, a, b, "edge") // Set 1: {A, C}, Set 2: {B, D}
977
+ * Graph.addEdge(mutable, b, c, "edge")
978
+ * Graph.addEdge(mutable, c, d, "edge")
979
+ * })
980
+ * console.log(Graph.isBipartite(bipartite)) // true
981
+ *
982
+ * // Non-bipartite graph (odd cycle)
983
+ * const triangle = Graph.undirected<string, string>((mutable) => {
984
+ * const a = Graph.addNode(mutable, "A")
985
+ * const b = Graph.addNode(mutable, "B")
986
+ * const c = Graph.addNode(mutable, "C")
987
+ * Graph.addEdge(mutable, a, b, "edge")
988
+ * Graph.addEdge(mutable, b, c, "edge")
989
+ * Graph.addEdge(mutable, c, a, "edge") // Triangle (3-cycle)
990
+ * })
991
+ * console.log(Graph.isBipartite(triangle)) // false
992
+ * ```
993
+ *
994
+ * @since 3.18.0
995
+ * @category algorithms
996
+ */
997
+ export declare const isBipartite: <N, E>(graph: Graph<N, E, "undirected"> | MutableGraph<N, E, "undirected">) => boolean;
998
+ /**
999
+ * Find connected components in an undirected graph.
1000
+ * Each component is represented as an array of node indices.
1001
+ *
1002
+ * @example
1003
+ * ```ts
1004
+ * import { Graph } from "effect"
1005
+ *
1006
+ * const graph = Graph.undirected<string, string>((mutable) => {
1007
+ * const a = Graph.addNode(mutable, "A")
1008
+ * const b = Graph.addNode(mutable, "B")
1009
+ * const c = Graph.addNode(mutable, "C")
1010
+ * const d = Graph.addNode(mutable, "D")
1011
+ * Graph.addEdge(mutable, a, b, "edge") // Component 1: A-B
1012
+ * Graph.addEdge(mutable, c, d, "edge") // Component 2: C-D
1013
+ * })
1014
+ *
1015
+ * const components = Graph.connectedComponents(graph)
1016
+ * console.log(components) // [[0, 1], [2, 3]]
1017
+ * ```
1018
+ *
1019
+ * @since 3.18.0
1020
+ * @category algorithms
1021
+ */
1022
+ export declare const connectedComponents: <N, E>(graph: Graph<N, E, "undirected"> | MutableGraph<N, E, "undirected">) => Array<Array<NodeIndex>>;
1023
+ /**
1024
+ * Find strongly connected components in a directed graph using Kosaraju's algorithm.
1025
+ * Each SCC is represented as an array of node indices.
1026
+ *
1027
+ * @example
1028
+ * ```ts
1029
+ * import { Graph } from "effect"
1030
+ *
1031
+ * const graph = Graph.directed<string, string>((mutable) => {
1032
+ * const a = Graph.addNode(mutable, "A")
1033
+ * const b = Graph.addNode(mutable, "B")
1034
+ * const c = Graph.addNode(mutable, "C")
1035
+ * Graph.addEdge(mutable, a, b, "A->B")
1036
+ * Graph.addEdge(mutable, b, c, "B->C")
1037
+ * Graph.addEdge(mutable, c, a, "C->A") // Creates SCC: A-B-C
1038
+ * })
1039
+ *
1040
+ * const sccs = Graph.stronglyConnectedComponents(graph)
1041
+ * console.log(sccs) // [[0, 1, 2]]
1042
+ * ```
1043
+ *
1044
+ * @since 3.18.0
1045
+ * @category algorithms
1046
+ */
1047
+ export declare const stronglyConnectedComponents: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => Array<Array<NodeIndex>>;
1048
+ /**
1049
+ * Result of a shortest path computation containing the path and total distance.
1050
+ *
1051
+ * @since 3.18.0
1052
+ * @category models
1053
+ */
1054
+ export interface PathResult<E> {
1055
+ readonly path: Array<NodeIndex>;
1056
+ readonly distance: number;
1057
+ readonly edgeWeights: Array<E>;
1058
+ }
1059
+ /**
1060
+ * Find the shortest path between two nodes using Dijkstra's algorithm.
1061
+ *
1062
+ * Dijkstra's algorithm works with non-negative edge weights and finds the shortest
1063
+ * path from a source node to a target node in O((V + E) log V) time complexity.
1064
+ *
1065
+ * @example
1066
+ * ```ts
1067
+ * import { Graph, Option } from "effect"
1068
+ *
1069
+ * const graph = Graph.directed<string, number>((mutable) => {
1070
+ * const a = Graph.addNode(mutable, "A")
1071
+ * const b = Graph.addNode(mutable, "B")
1072
+ * const c = Graph.addNode(mutable, "C")
1073
+ * Graph.addEdge(mutable, a, b, 5)
1074
+ * Graph.addEdge(mutable, a, c, 10)
1075
+ * Graph.addEdge(mutable, b, c, 2)
1076
+ * })
1077
+ *
1078
+ * const result = Graph.dijkstra(graph, 0, 2, (edgeData) => edgeData)
1079
+ * if (Option.isSome(result)) {
1080
+ * console.log(result.value.path) // [0, 1, 2] - shortest path A->B->C
1081
+ * console.log(result.value.distance) // 7 - total distance
1082
+ * }
1083
+ * ```
1084
+ *
1085
+ * @since 3.18.0
1086
+ * @category algorithms
1087
+ */
1088
+ export declare const dijkstra: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, source: NodeIndex, target: NodeIndex, edgeWeight: (edgeData: E) => number) => Option.Option<PathResult<E>>;
1089
+ /**
1090
+ * Result of all-pairs shortest path computation.
1091
+ *
1092
+ * @since 3.18.0
1093
+ * @category models
1094
+ */
1095
+ export interface AllPairsResult<E> {
1096
+ readonly distances: Map<NodeIndex, Map<NodeIndex, number>>;
1097
+ readonly paths: Map<NodeIndex, Map<NodeIndex, Array<NodeIndex> | null>>;
1098
+ readonly edgeWeights: Map<NodeIndex, Map<NodeIndex, Array<E>>>;
1099
+ }
1100
+ /**
1101
+ * Find shortest paths between all pairs of nodes using Floyd-Warshall algorithm.
1102
+ *
1103
+ * Floyd-Warshall algorithm computes shortest paths between all pairs of nodes in O(V³) time.
1104
+ * It can handle negative edge weights and detect negative cycles.
1105
+ *
1106
+ * @example
1107
+ * ```ts
1108
+ * import { Graph } from "effect"
1109
+ *
1110
+ * const graph = Graph.directed<string, number>((mutable) => {
1111
+ * const a = Graph.addNode(mutable, "A")
1112
+ * const b = Graph.addNode(mutable, "B")
1113
+ * const c = Graph.addNode(mutable, "C")
1114
+ * Graph.addEdge(mutable, a, b, 3)
1115
+ * Graph.addEdge(mutable, b, c, 2)
1116
+ * Graph.addEdge(mutable, a, c, 7)
1117
+ * })
1118
+ *
1119
+ * const result = Graph.floydWarshall(graph, (edgeData) => edgeData)
1120
+ * const distanceAToC = result.distances.get(0)?.get(2) // 5 (A->B->C)
1121
+ * const pathAToC = result.paths.get(0)?.get(2) // [0, 1, 2]
1122
+ * ```
1123
+ *
1124
+ * @since 3.18.0
1125
+ * @category algorithms
1126
+ */
1127
+ export declare const floydWarshall: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, edgeWeight: (edgeData: E) => number) => AllPairsResult<E>;
1128
+ /**
1129
+ * Find the shortest path between two nodes using A* pathfinding algorithm.
1130
+ *
1131
+ * A* is an extension of Dijkstra's algorithm that uses a heuristic function to guide
1132
+ * the search towards the target, potentially finding paths faster than Dijkstra's.
1133
+ * The heuristic must be admissible (never overestimate the actual cost).
1134
+ *
1135
+ * @example
1136
+ * ```ts
1137
+ * import { Graph, Option } from "effect"
1138
+ *
1139
+ * const graph = Graph.directed<{x: number, y: number}, number>((mutable) => {
1140
+ * const a = Graph.addNode(mutable, {x: 0, y: 0})
1141
+ * const b = Graph.addNode(mutable, {x: 1, y: 0})
1142
+ * const c = Graph.addNode(mutable, {x: 2, y: 0})
1143
+ * Graph.addEdge(mutable, a, b, 1)
1144
+ * Graph.addEdge(mutable, b, c, 1)
1145
+ * })
1146
+ *
1147
+ * // Manhattan distance heuristic
1148
+ * const heuristic = (nodeData: {x: number, y: number}, targetData: {x: number, y: number}) =>
1149
+ * Math.abs(nodeData.x - targetData.x) + Math.abs(nodeData.y - targetData.y)
1150
+ *
1151
+ * const result = Graph.astar(graph, 0, 2, (edgeData) => edgeData, heuristic)
1152
+ * if (Option.isSome(result)) {
1153
+ * console.log(result.value.path) // [0, 1, 2] - shortest path
1154
+ * console.log(result.value.distance) // 2 - total distance
1155
+ * }
1156
+ * ```
1157
+ *
1158
+ * @since 3.18.0
1159
+ * @category algorithms
1160
+ */
1161
+ export declare const astar: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, source: NodeIndex, target: NodeIndex, edgeWeight: (edgeData: E) => number, heuristic: (sourceNodeData: N, targetNodeData: N) => number) => Option.Option<PathResult<E>>;
1162
+ /**
1163
+ * Find the shortest path between two nodes using Bellman-Ford algorithm.
1164
+ *
1165
+ * Bellman-Ford algorithm can handle negative edge weights and detects negative cycles.
1166
+ * It has O(VE) time complexity, slower than Dijkstra's but more versatile.
1167
+ * Returns Option.none() if a negative cycle is detected that affects the path.
1168
+ *
1169
+ * @example
1170
+ * ```ts
1171
+ * import { Graph, Option } from "effect"
1172
+ *
1173
+ * const graph = Graph.directed<string, number>((mutable) => {
1174
+ * const a = Graph.addNode(mutable, "A")
1175
+ * const b = Graph.addNode(mutable, "B")
1176
+ * const c = Graph.addNode(mutable, "C")
1177
+ * Graph.addEdge(mutable, a, b, -1) // Negative weight allowed
1178
+ * Graph.addEdge(mutable, b, c, 3)
1179
+ * Graph.addEdge(mutable, a, c, 5)
1180
+ * })
1181
+ *
1182
+ * const result = Graph.bellmanFord(graph, 0, 2, (edgeData) => edgeData)
1183
+ * if (Option.isSome(result)) {
1184
+ * console.log(result.value.path) // [0, 1, 2] - shortest path A->B->C
1185
+ * console.log(result.value.distance) // 2 - total distance
1186
+ * }
1187
+ * ```
1188
+ *
1189
+ * @since 3.18.0
1190
+ * @category algorithms
1191
+ */
1192
+ export declare const bellmanFord: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, source: NodeIndex, target: NodeIndex, edgeWeight: (edgeData: E) => number) => Option.Option<PathResult<E>>;
1193
+ /**
1194
+ * Concrete class for iterables that produce [NodeIndex, NodeData] tuples.
1195
+ *
1196
+ * This class provides a common abstraction for all iterables that return node data,
1197
+ * including traversal iterators (DFS, BFS, etc.) and element iterators (nodes, externals).
1198
+ * It uses a mapEntry function pattern for flexible iteration and transformation.
1199
+ *
1200
+ * @example
1201
+ * ```ts
1202
+ * import { Graph } from "effect"
1203
+ *
1204
+ * const graph = Graph.directed<string, number>((mutable) => {
1205
+ * const a = Graph.addNode(mutable, "A")
1206
+ * const b = Graph.addNode(mutable, "B")
1207
+ * Graph.addEdge(mutable, a, b, 1)
1208
+ * })
1209
+ *
1210
+ * // Both traversal and element iterators return NodeWalker
1211
+ * const dfsNodes: Graph.NodeWalker<string> = Graph.dfs(graph, { startNodes: [0] })
1212
+ * const allNodes: Graph.NodeWalker<string> = Graph.nodes(graph)
1213
+ *
1214
+ * // Common interface for working with node iterables
1215
+ * function processNodes<N>(nodeIterable: Graph.NodeWalker<N>): Array<number> {
1216
+ * return Array.from(Graph.indices(nodeIterable))
1217
+ * }
1218
+ *
1219
+ * // Access node data using values() or entries()
1220
+ * const nodeData = Array.from(Graph.values(dfsNodes)) // ["A", "B"]
1221
+ * const nodeEntries = Array.from(Graph.entries(allNodes)) // [[0, "A"], [1, "B"]]
1222
+ * ```
1223
+ *
1224
+ * @since 3.18.0
1225
+ * @category models
1226
+ */
1227
+ export declare class Walker<T, N> implements Iterable<[T, N]> {
1228
+ readonly [Symbol.iterator]: () => Iterator<[T, N]>;
1229
+ /**
1230
+ * Visits each element and maps it to a value using the provided function.
1231
+ *
1232
+ * Takes a function that receives the index and data,
1233
+ * and returns an iterable of the mapped values. Skips elements that
1234
+ * no longer exist in the graph.
1235
+ *
1236
+ * @example
1237
+ * ```ts
1238
+ * import { Graph } from "effect"
1239
+ *
1240
+ * const graph = Graph.directed<string, number>((mutable) => {
1241
+ * const a = Graph.addNode(mutable, "A")
1242
+ * const b = Graph.addNode(mutable, "B")
1243
+ * Graph.addEdge(mutable, a, b, 1)
1244
+ * })
1245
+ *
1246
+ * const dfs = Graph.dfs(graph, { startNodes: [0] })
1247
+ *
1248
+ * // Map to just the node data
1249
+ * const values = Array.from(dfs.visit((index, data) => data))
1250
+ * console.log(values) // ["A", "B"]
1251
+ *
1252
+ * // Map to custom objects
1253
+ * const custom = Array.from(dfs.visit((index, data) => ({ id: index, name: data })))
1254
+ * console.log(custom) // [{ id: 0, name: "A" }, { id: 1, name: "B" }]
1255
+ * ```
1256
+ *
1257
+ * @since 3.18.0
1258
+ * @category iterators
1259
+ */
1260
+ readonly visit: <U>(f: (index: T, data: N) => U) => Iterable<U>;
1261
+ constructor(
1262
+ /**
1263
+ * Visits each element and maps it to a value using the provided function.
1264
+ *
1265
+ * Takes a function that receives the index and data,
1266
+ * and returns an iterable of the mapped values. Skips elements that
1267
+ * no longer exist in the graph.
1268
+ *
1269
+ * @example
1270
+ * ```ts
1271
+ * import { Graph } from "effect"
1272
+ *
1273
+ * const graph = Graph.directed<string, number>((mutable) => {
1274
+ * const a = Graph.addNode(mutable, "A")
1275
+ * const b = Graph.addNode(mutable, "B")
1276
+ * Graph.addEdge(mutable, a, b, 1)
1277
+ * })
1278
+ *
1279
+ * const dfs = Graph.dfs(graph, { startNodes: [0] })
1280
+ *
1281
+ * // Map to just the node data
1282
+ * const values = Array.from(dfs.visit((index, data) => data))
1283
+ * console.log(values) // ["A", "B"]
1284
+ *
1285
+ * // Map to custom objects
1286
+ * const custom = Array.from(dfs.visit((index, data) => ({ id: index, name: data })))
1287
+ * console.log(custom) // [{ id: 0, name: "A" }, { id: 1, name: "B" }]
1288
+ * ```
1289
+ *
1290
+ * @since 3.18.0
1291
+ * @category iterators
1292
+ */
1293
+ visit: <U>(f: (index: T, data: N) => U) => Iterable<U>);
1294
+ }
1295
+ /**
1296
+ * Type alias for node iteration using Walker.
1297
+ * NodeWalker is represented as Walker<NodeIndex, N>.
1298
+ *
1299
+ * @since 3.18.0
1300
+ * @category models
1301
+ */
1302
+ export type NodeWalker<N> = Walker<NodeIndex, N>;
1303
+ /**
1304
+ * Type alias for edge iteration using Walker.
1305
+ * EdgeWalker is represented as Walker<EdgeIndex, Edge<E>>.
1306
+ *
1307
+ * @since 3.18.0
1308
+ * @category models
1309
+ */
1310
+ export type EdgeWalker<E> = Walker<EdgeIndex, Edge<E>>;
1311
+ /**
1312
+ * Returns an iterator over the indices in the walker.
1313
+ *
1314
+ * @example
1315
+ * ```ts
1316
+ * import { Graph } from "effect"
1317
+ *
1318
+ * const graph = Graph.directed<string, number>((mutable) => {
1319
+ * const a = Graph.addNode(mutable, "A")
1320
+ * const b = Graph.addNode(mutable, "B")
1321
+ * Graph.addEdge(mutable, a, b, 1)
1322
+ * })
1323
+ *
1324
+ * const dfs = Graph.dfs(graph, { startNodes: [0] })
1325
+ * const indices = Array.from(Graph.indices(dfs))
1326
+ * console.log(indices) // [0, 1]
1327
+ * ```
1328
+ *
1329
+ * @since 3.18.0
1330
+ * @category utilities
1331
+ */
1332
+ export declare const indices: <T, N>(walker: Walker<T, N>) => Iterable<T>;
1333
+ /**
1334
+ * Returns an iterator over the values (data) in the walker.
1335
+ *
1336
+ * @example
1337
+ * ```ts
1338
+ * import { Graph } from "effect"
1339
+ *
1340
+ * const graph = Graph.directed<string, number>((mutable) => {
1341
+ * const a = Graph.addNode(mutable, "A")
1342
+ * const b = Graph.addNode(mutable, "B")
1343
+ * Graph.addEdge(mutable, a, b, 1)
1344
+ * })
1345
+ *
1346
+ * const dfs = Graph.dfs(graph, { startNodes: [0] })
1347
+ * const values = Array.from(Graph.values(dfs))
1348
+ * console.log(values) // ["A", "B"]
1349
+ * ```
1350
+ *
1351
+ * @since 3.18.0
1352
+ * @category utilities
1353
+ */
1354
+ export declare const values: <T, N>(walker: Walker<T, N>) => Iterable<N>;
1355
+ /**
1356
+ * Returns an iterator over [index, data] entries in the walker.
1357
+ *
1358
+ * @example
1359
+ * ```ts
1360
+ * import { Graph } from "effect"
1361
+ *
1362
+ * const graph = Graph.directed<string, number>((mutable) => {
1363
+ * const a = Graph.addNode(mutable, "A")
1364
+ * const b = Graph.addNode(mutable, "B")
1365
+ * Graph.addEdge(mutable, a, b, 1)
1366
+ * })
1367
+ *
1368
+ * const dfs = Graph.dfs(graph, { startNodes: [0] })
1369
+ * const entries = Array.from(Graph.entries(dfs))
1370
+ * console.log(entries) // [[0, "A"], [1, "B"]]
1371
+ * ```
1372
+ *
1373
+ * @since 3.18.0
1374
+ * @category utilities
1375
+ */
1376
+ export declare const entries: <T, N>(walker: Walker<T, N>) => Iterable<[T, N]>;
1377
+ /**
1378
+ * Configuration options for DFS iterator.
1379
+ *
1380
+ * @since 3.18.0
1381
+ * @category models
1382
+ */
1383
+ export interface DfsConfig {
1384
+ readonly startNodes?: Array<NodeIndex>;
1385
+ readonly direction?: Direction;
1386
+ }
1387
+ /**
1388
+ * Creates a new DFS iterator with optional configuration.
1389
+ *
1390
+ * The iterator maintains a stack of nodes to visit and tracks discovered nodes.
1391
+ * It provides lazy evaluation of the depth-first search.
1392
+ *
1393
+ * @example
1394
+ * ```ts
1395
+ * import { Graph } from "effect"
1396
+ *
1397
+ * const graph = Graph.directed<string, number>((mutable) => {
1398
+ * const a = Graph.addNode(mutable, "A")
1399
+ * const b = Graph.addNode(mutable, "B")
1400
+ * const c = Graph.addNode(mutable, "C")
1401
+ * Graph.addEdge(mutable, a, b, 1)
1402
+ * Graph.addEdge(mutable, b, c, 1)
1403
+ * })
1404
+ *
1405
+ * // Start from a specific node
1406
+ * const dfs1 = Graph.dfs(graph, { startNodes: [0] })
1407
+ * for (const nodeIndex of Graph.indices(dfs1)) {
1408
+ * console.log(nodeIndex) // Traverses in DFS order: 0, 1, 2
1409
+ * }
1410
+ *
1411
+ * // Empty iterator (no starting nodes)
1412
+ * const dfs2 = Graph.dfs(graph)
1413
+ * // Can be used programmatically
1414
+ * ```
1415
+ *
1416
+ * @since 3.18.0
1417
+ * @category iterators
1418
+ */
1419
+ export declare const dfs: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: DfsConfig) => NodeWalker<N>;
1420
+ /**
1421
+ * Configuration options for BFS iterator.
1422
+ *
1423
+ * @since 3.18.0
1424
+ * @category models
1425
+ */
1426
+ export interface BfsConfig {
1427
+ readonly startNodes?: Array<NodeIndex>;
1428
+ readonly direction?: Direction;
1429
+ }
1430
+ /**
1431
+ * Creates a new BFS iterator with optional configuration.
1432
+ *
1433
+ * The iterator maintains a queue of nodes to visit and tracks discovered nodes.
1434
+ * It provides lazy evaluation of the breadth-first search.
1435
+ *
1436
+ * @example
1437
+ * ```ts
1438
+ * import { Graph } from "effect"
1439
+ *
1440
+ * const graph = Graph.directed<string, number>((mutable) => {
1441
+ * const a = Graph.addNode(mutable, "A")
1442
+ * const b = Graph.addNode(mutable, "B")
1443
+ * const c = Graph.addNode(mutable, "C")
1444
+ * Graph.addEdge(mutable, a, b, 1)
1445
+ * Graph.addEdge(mutable, b, c, 1)
1446
+ * })
1447
+ *
1448
+ * // Start from a specific node
1449
+ * const bfs1 = Graph.bfs(graph, { startNodes: [0] })
1450
+ * for (const nodeIndex of Graph.indices(bfs1)) {
1451
+ * console.log(nodeIndex) // Traverses in BFS order: 0, 1, 2
1452
+ * }
1453
+ *
1454
+ * // Empty iterator (no starting nodes)
1455
+ * const bfs2 = Graph.bfs(graph)
1456
+ * // Can be used programmatically
1457
+ * ```
1458
+ *
1459
+ * @since 3.18.0
1460
+ * @category iterators
1461
+ */
1462
+ export declare const bfs: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: BfsConfig) => NodeWalker<N>;
1463
+ /**
1464
+ * Configuration options for topological sort iterator.
1465
+ *
1466
+ * @since 3.18.0
1467
+ * @category models
1468
+ */
1469
+ export interface TopoConfig {
1470
+ readonly initials?: Array<NodeIndex>;
1471
+ }
1472
+ /**
1473
+ * Creates a new topological sort iterator with optional configuration.
1474
+ *
1475
+ * The iterator uses Kahn's algorithm to lazily produce nodes in topological order.
1476
+ * Throws an error if the graph contains cycles.
1477
+ *
1478
+ * @example
1479
+ * ```ts
1480
+ * import { Graph } from "effect"
1481
+ *
1482
+ * const graph = Graph.directed<string, number>((mutable) => {
1483
+ * const a = Graph.addNode(mutable, "A")
1484
+ * const b = Graph.addNode(mutable, "B")
1485
+ * const c = Graph.addNode(mutable, "C")
1486
+ * Graph.addEdge(mutable, a, b, 1)
1487
+ * Graph.addEdge(mutable, b, c, 1)
1488
+ * })
1489
+ *
1490
+ * // Standard topological sort
1491
+ * const topo1 = Graph.topo(graph)
1492
+ * for (const nodeIndex of Graph.indices(topo1)) {
1493
+ * console.log(nodeIndex) // 0, 1, 2 (topological order)
1494
+ * }
1495
+ *
1496
+ * // With initial nodes
1497
+ * const topo2 = Graph.topo(graph, { initials: [0] })
1498
+ *
1499
+ * // Throws error for cyclic graph
1500
+ * const cyclicGraph = Graph.directed<string, number>((mutable) => {
1501
+ * const a = Graph.addNode(mutable, "A")
1502
+ * const b = Graph.addNode(mutable, "B")
1503
+ * Graph.addEdge(mutable, a, b, 1)
1504
+ * Graph.addEdge(mutable, b, a, 2) // Creates cycle
1505
+ * })
1506
+ *
1507
+ * try {
1508
+ * Graph.topo(cyclicGraph) // Throws: "Cannot perform topological sort on cyclic graph"
1509
+ * } catch (error) {
1510
+ * console.log((error as Error).message)
1511
+ * }
1512
+ * ```
1513
+ *
1514
+ * @since 3.18.0
1515
+ * @category iterators
1516
+ */
1517
+ export declare const topo: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: TopoConfig) => NodeWalker<N>;
1518
+ /**
1519
+ * Configuration options for DFS postorder iterator.
1520
+ *
1521
+ * @since 3.18.0
1522
+ * @category models
1523
+ */
1524
+ export interface DfsPostOrderConfig {
1525
+ readonly startNodes?: Array<NodeIndex>;
1526
+ readonly direction?: Direction;
1527
+ }
1528
+ /**
1529
+ * Creates a new DFS postorder iterator with optional configuration.
1530
+ *
1531
+ * The iterator maintains a stack with visit state tracking and emits nodes
1532
+ * in postorder (after all descendants have been processed). Essential for
1533
+ * dependency resolution and tree destruction algorithms.
1534
+ *
1535
+ * @example
1536
+ * ```ts
1537
+ * import { Graph } from "effect"
1538
+ *
1539
+ * const graph = Graph.directed<string, number>((mutable) => {
1540
+ * const root = Graph.addNode(mutable, "root")
1541
+ * const child1 = Graph.addNode(mutable, "child1")
1542
+ * const child2 = Graph.addNode(mutable, "child2")
1543
+ * Graph.addEdge(mutable, root, child1, 1)
1544
+ * Graph.addEdge(mutable, root, child2, 1)
1545
+ * })
1546
+ *
1547
+ * // Postorder: children before parents
1548
+ * const postOrder = Graph.dfsPostOrder(graph, { startNodes: [0] })
1549
+ * for (const node of postOrder) {
1550
+ * console.log(node) // 1, 2, 0
1551
+ * }
1552
+ * ```
1553
+ *
1554
+ * @since 3.18.0
1555
+ * @category iterators
1556
+ */
1557
+ export declare const dfsPostOrder: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: DfsPostOrderConfig) => NodeWalker<N>;
1558
+ /**
1559
+ * Creates an iterator over all node indices in the graph.
1560
+ *
1561
+ * The iterator produces node indices in the order they were added to the graph.
1562
+ * This provides access to all nodes regardless of connectivity.
1563
+ *
1564
+ * @example
1565
+ * ```ts
1566
+ * import { Graph } from "effect"
1567
+ *
1568
+ * const graph = Graph.directed<string, number>((mutable) => {
1569
+ * const a = Graph.addNode(mutable, "A")
1570
+ * const b = Graph.addNode(mutable, "B")
1571
+ * const c = Graph.addNode(mutable, "C")
1572
+ * Graph.addEdge(mutable, a, b, 1)
1573
+ * })
1574
+ *
1575
+ * const indices = Array.from(Graph.indices(Graph.nodes(graph)))
1576
+ * console.log(indices) // [0, 1, 2]
1577
+ * ```
1578
+ *
1579
+ * @since 3.18.0
1580
+ * @category iterators
1581
+ */
1582
+ export declare const nodes: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => NodeWalker<N>;
1583
+ /**
1584
+ * Creates an iterator over all edge indices in the graph.
1585
+ *
1586
+ * The iterator produces edge indices in the order they were added to the graph.
1587
+ * This provides access to all edges regardless of connectivity.
1588
+ *
1589
+ * @example
1590
+ * ```ts
1591
+ * import { Graph } from "effect"
1592
+ *
1593
+ * const graph = Graph.directed<string, number>((mutable) => {
1594
+ * const a = Graph.addNode(mutable, "A")
1595
+ * const b = Graph.addNode(mutable, "B")
1596
+ * const c = Graph.addNode(mutable, "C")
1597
+ * Graph.addEdge(mutable, a, b, 1)
1598
+ * Graph.addEdge(mutable, b, c, 2)
1599
+ * })
1600
+ *
1601
+ * const indices = Array.from(Graph.indices(Graph.edges(graph)))
1602
+ * console.log(indices) // [0, 1]
1603
+ * ```
1604
+ *
1605
+ * @since 3.18.0
1606
+ * @category iterators
1607
+ */
1608
+ export declare const edges: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>) => EdgeWalker<E>;
1609
+ /**
1610
+ * Configuration for externals iterator.
1611
+ *
1612
+ * @since 3.18.0
1613
+ * @category models
1614
+ */
1615
+ export interface ExternalsConfig {
1616
+ readonly direction?: Direction;
1617
+ }
1618
+ /**
1619
+ * Creates an iterator over external nodes (nodes without edges in specified direction).
1620
+ *
1621
+ * External nodes are nodes that have no outgoing edges (direction="outgoing") or
1622
+ * no incoming edges (direction="incoming"). These are useful for finding
1623
+ * sources, sinks, or isolated nodes.
1624
+ *
1625
+ * @example
1626
+ * ```ts
1627
+ * import { Graph } from "effect"
1628
+ *
1629
+ * const graph = Graph.directed<string, number>((mutable) => {
1630
+ * const source = Graph.addNode(mutable, "source") // 0 - no incoming
1631
+ * const middle = Graph.addNode(mutable, "middle") // 1 - has both
1632
+ * const sink = Graph.addNode(mutable, "sink") // 2 - no outgoing
1633
+ * const isolated = Graph.addNode(mutable, "isolated") // 3 - no edges
1634
+ *
1635
+ * Graph.addEdge(mutable, source, middle, 1)
1636
+ * Graph.addEdge(mutable, middle, sink, 2)
1637
+ * })
1638
+ *
1639
+ * // Nodes with no outgoing edges (sinks + isolated)
1640
+ * const sinks = Array.from(Graph.indices(Graph.externals(graph, { direction: "outgoing" })))
1641
+ * console.log(sinks) // [2, 3]
1642
+ *
1643
+ * // Nodes with no incoming edges (sources + isolated)
1644
+ * const sources = Array.from(Graph.indices(Graph.externals(graph, { direction: "incoming" })))
1645
+ * console.log(sources) // [0, 3]
1646
+ * ```
1647
+ *
1648
+ * @since 3.18.0
1649
+ * @category iterators
1650
+ */
1651
+ export declare const externals: <N, E, T extends Kind = "directed">(graph: Graph<N, E, T> | MutableGraph<N, E, T>, config?: ExternalsConfig) => NodeWalker<N>;
1652
+ //# sourceMappingURL=Graph.d.ts.map