@monstermann/graph 0.0.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +1383 -0
  2. package/dist/Graph/batch.d.mts +47 -0
  3. package/dist/Graph/batch.mjs +57 -0
  4. package/dist/Graph/create.d.mts +36 -0
  5. package/dist/Graph/create.mjs +37 -0
  6. package/dist/Graph/findEdge.d.mts +60 -0
  7. package/dist/Graph/findEdge.mjs +10 -0
  8. package/dist/Graph/findEdges.d.mts +65 -0
  9. package/dist/Graph/findEdges.mjs +12 -0
  10. package/dist/Graph/findNeighbor.d.mts +54 -0
  11. package/dist/Graph/findNeighbor.mjs +16 -0
  12. package/dist/Graph/findNeighbors.d.mts +59 -0
  13. package/dist/Graph/findNeighbors.mjs +18 -0
  14. package/dist/Graph/findNode.d.mts +67 -0
  15. package/dist/Graph/findNode.mjs +7 -0
  16. package/dist/Graph/findNodes.d.mts +63 -0
  17. package/dist/Graph/findNodes.mjs +9 -0
  18. package/dist/Graph/forEachEdge.d.mts +52 -0
  19. package/dist/Graph/forEachEdge.mjs +56 -0
  20. package/dist/Graph/forEachNeighbor.d.mts +52 -0
  21. package/dist/Graph/forEachNeighbor.mjs +59 -0
  22. package/dist/Graph/forEachNode.d.mts +49 -0
  23. package/dist/Graph/forEachNode.mjs +51 -0
  24. package/dist/Graph/fromJS.d.mts +55 -0
  25. package/dist/Graph/fromJS.mjs +62 -0
  26. package/dist/Graph/getEdge.d.mts +50 -0
  27. package/dist/Graph/getEdge.mjs +54 -0
  28. package/dist/Graph/getEdges.d.mts +47 -0
  29. package/dist/Graph/getEdges.mjs +51 -0
  30. package/dist/Graph/getNeighbor.d.mts +50 -0
  31. package/dist/Graph/getNeighbor.mjs +56 -0
  32. package/dist/Graph/getNeighbors.d.mts +47 -0
  33. package/dist/Graph/getNeighbors.mjs +58 -0
  34. package/dist/Graph/getNode.d.mts +48 -0
  35. package/dist/Graph/getNode.mjs +52 -0
  36. package/dist/Graph/getNodes.d.mts +46 -0
  37. package/dist/Graph/getNodes.mjs +48 -0
  38. package/dist/Graph/hasEdge.d.mts +46 -0
  39. package/dist/Graph/hasEdge.mjs +50 -0
  40. package/dist/Graph/hasNode.d.mts +42 -0
  41. package/dist/Graph/hasNode.mjs +46 -0
  42. package/dist/Graph/index.d.mts +68 -0
  43. package/dist/Graph/index.mjs +65 -0
  44. package/dist/Graph/internals/core.mjs +51 -0
  45. package/dist/Graph/internals/parseNodeIdentifier.mjs +7 -0
  46. package/dist/Graph/internals/types.d.mts +16 -0
  47. package/dist/Graph/mapEdge.d.mts +52 -0
  48. package/dist/Graph/mapEdge.mjs +60 -0
  49. package/dist/Graph/mapNode.d.mts +65 -0
  50. package/dist/Graph/mapNode.mjs +83 -0
  51. package/dist/Graph/mergeEdge.d.mts +52 -0
  52. package/dist/Graph/mergeEdge.mjs +63 -0
  53. package/dist/Graph/mergeNode.d.mts +50 -0
  54. package/dist/Graph/mergeNode.mjs +60 -0
  55. package/dist/Graph/removeEdge.d.mts +49 -0
  56. package/dist/Graph/removeEdge.mjs +71 -0
  57. package/dist/Graph/removeNode.d.mts +46 -0
  58. package/dist/Graph/removeNode.mjs +71 -0
  59. package/dist/Graph/setEdge.d.mts +52 -0
  60. package/dist/Graph/setEdge.mjs +78 -0
  61. package/dist/Graph/setNode.d.mts +43 -0
  62. package/dist/Graph/setNode.mjs +50 -0
  63. package/dist/Graph/toJS.d.mts +59 -0
  64. package/dist/Graph/toJS.mjs +82 -0
  65. package/dist/Graph/types.d.mts +29 -0
  66. package/dist/index.d.mts +2 -0
  67. package/dist/index.mjs +3 -0
  68. package/package.json +1 -1
@@ -0,0 +1,52 @@
1
+ import { Bimap } from "./internals/types.mjs";
2
+ import { Edges, Graph, Node, NodeIdentifier, NodeType } from "./types.mjs";
3
+
4
+ //#region src/Graph/forEachEdge.d.ts
5
+ /**
6
+ * # forEachEdge
7
+ *
8
+ * ```ts
9
+ * function Graph.forEachEdge(
10
+ * graph: Graph,
11
+ * source: [NodeType, NodeId] | { type: NodeType, id: NodeId },
12
+ * type: NodeType,
13
+ * fn: (edge: EdgeData) => void,
14
+ * ): Graph
15
+ * ```
16
+ *
17
+ * Iterates over all edges of a specific type from a source node, executing a function for each edge. Returns the graph unchanged (for chaining).
18
+ *
19
+ * ## Example
20
+ *
21
+ * ```ts
22
+ * import { Graph } from "@monstermann/graph";
23
+ *
24
+ * type Nodes =
25
+ * | { type: "Task"; id: string }
26
+ * | { type: "Section"; id: string }
27
+ * | { type: "Project"; id: string };
28
+ *
29
+ * type Edges = {
30
+ * Project: { Task: { priority: number } };
31
+ * Section: { Task: void };
32
+ * };
33
+ *
34
+ * const graph = Graph.create<Nodes, Edges>();
35
+ * let g = Graph.setNode(graph, { type: "Project", id: "1" });
36
+ * g = Graph.setNode(g, { type: "Task", id: "1" });
37
+ * g = Graph.setNode(g, { type: "Task", id: "2" });
38
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "1"], { priority: 1 });
39
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "2"], { priority: 2 });
40
+ *
41
+ * Graph.forEachEdge(g, ["Project", "1"], "Task", (edge) => {
42
+ * console.log(edge.priority);
43
+ * });
44
+ * // Logs:
45
+ * // 1
46
+ * // 2
47
+ * ```
48
+ *
49
+ */
50
+ declare function forEachEdge<N extends Node, E extends Edges<N>, N1 extends keyof Bimap<E> & NodeType<N>, N2 extends keyof Bimap<E>[N1] & NodeType<N>>(graph: Graph<N, E>, source: NodeIdentifier<N, N1>, type: N2, fn: (edge: NoInfer<Bimap<E>[N1][N2]>) => void): Graph<N, E>;
51
+ //#endregion
52
+ export { forEachEdge };
@@ -0,0 +1,56 @@
1
+ import { parseNodeIdentifier } from "./internals/parseNodeIdentifier.mjs";
2
+
3
+ //#region src/Graph/forEachEdge.ts
4
+ /**
5
+ * # forEachEdge
6
+ *
7
+ * ```ts
8
+ * function Graph.forEachEdge(
9
+ * graph: Graph,
10
+ * source: [NodeType, NodeId] | { type: NodeType, id: NodeId },
11
+ * type: NodeType,
12
+ * fn: (edge: EdgeData) => void,
13
+ * ): Graph
14
+ * ```
15
+ *
16
+ * Iterates over all edges of a specific type from a source node, executing a function for each edge. Returns the graph unchanged (for chaining).
17
+ *
18
+ * ## Example
19
+ *
20
+ * ```ts
21
+ * import { Graph } from "@monstermann/graph";
22
+ *
23
+ * type Nodes =
24
+ * | { type: "Task"; id: string }
25
+ * | { type: "Section"; id: string }
26
+ * | { type: "Project"; id: string };
27
+ *
28
+ * type Edges = {
29
+ * Project: { Task: { priority: number } };
30
+ * Section: { Task: void };
31
+ * };
32
+ *
33
+ * const graph = Graph.create<Nodes, Edges>();
34
+ * let g = Graph.setNode(graph, { type: "Project", id: "1" });
35
+ * g = Graph.setNode(g, { type: "Task", id: "1" });
36
+ * g = Graph.setNode(g, { type: "Task", id: "2" });
37
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "1"], { priority: 1 });
38
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "2"], { priority: 2 });
39
+ *
40
+ * Graph.forEachEdge(g, ["Project", "1"], "Task", (edge) => {
41
+ * console.log(edge.priority);
42
+ * });
43
+ * // Logs:
44
+ * // 1
45
+ * // 2
46
+ * ```
47
+ *
48
+ */
49
+ function forEachEdge(graph, source, type, fn) {
50
+ const [sourceType, sourceId] = parseNodeIdentifier(source);
51
+ for (const edge of graph.get("edges")?.get(sourceType)?.get(sourceId)?.get(type)?.values() ?? []) fn(edge);
52
+ return graph;
53
+ }
54
+
55
+ //#endregion
56
+ export { forEachEdge };
@@ -0,0 +1,52 @@
1
+ import { Bimap } from "./internals/types.mjs";
2
+ import { Edges, Graph, Node, NodeIdentifier, NodeOfType, NodeType } from "./types.mjs";
3
+
4
+ //#region src/Graph/forEachNeighbor.d.ts
5
+ /**
6
+ * # forEachNeighbor
7
+ *
8
+ * ```ts
9
+ * function Graph.forEachNeighbor(
10
+ * graph: Graph,
11
+ * node: [NodeType, NodeId] | { type: NodeType, id: NodeId },
12
+ * type: NodeType,
13
+ * fn: (target: Node, edge: EdgeData, source: Node) => void,
14
+ * ): Graph
15
+ * ```
16
+ *
17
+ * Iterates over all neighbor nodes of a specific type, executing a function for each neighbor. The function receives the target node, edge data, and source node. Returns the graph unchanged (for chaining).
18
+ *
19
+ * ## Example
20
+ *
21
+ * ```ts
22
+ * import { Graph } from "@monstermann/graph";
23
+ *
24
+ * type Nodes =
25
+ * | { type: "Task"; id: string; title: string }
26
+ * | { type: "Section"; id: string }
27
+ * | { type: "Project"; id: string; name: string };
28
+ *
29
+ * type Edges = {
30
+ * Project: { Task: { priority: number } };
31
+ * Section: { Task: void };
32
+ * };
33
+ *
34
+ * const graph = Graph.create<Nodes, Edges>();
35
+ * let g = Graph.setNode(graph, { type: "Project", id: "1", name: "My Project" });
36
+ * g = Graph.setNode(g, { type: "Task", id: "1", title: "First Task" });
37
+ * g = Graph.setNode(g, { type: "Task", id: "2", title: "Second Task" });
38
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "1"], { priority: 1 });
39
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "2"], { priority: 2 });
40
+ *
41
+ * Graph.forEachNeighbor(g, ["Project", "1"], "Task", (task, edge, project) => {
42
+ * console.log(`${project.name}: ${task.title} (priority: ${edge.priority})`);
43
+ * });
44
+ * // Logs:
45
+ * // "My Project: First Task (priority: 1)"
46
+ * // "My Project: Second Task (priority: 2)"
47
+ * ```
48
+ *
49
+ */
50
+ declare function forEachNeighbor<N extends Node, E extends Edges<N>, N1 extends NodeType<N>, N2 extends keyof Bimap<E>[N1] & NodeType<N>>(graph: Graph<N, E>, node: NodeIdentifier<N, N1>, type: N2, fn: (target: NoInfer<NodeOfType<N, N2>>, edge: NoInfer<Bimap<E>[N1][N2]>, source: NoInfer<NodeOfType<N, N1>>) => void): Graph<N, E>;
51
+ //#endregion
52
+ export { forEachNeighbor };
@@ -0,0 +1,59 @@
1
+ import { getNode } from "./getNode.mjs";
2
+
3
+ //#region src/Graph/forEachNeighbor.ts
4
+ /**
5
+ * # forEachNeighbor
6
+ *
7
+ * ```ts
8
+ * function Graph.forEachNeighbor(
9
+ * graph: Graph,
10
+ * node: [NodeType, NodeId] | { type: NodeType, id: NodeId },
11
+ * type: NodeType,
12
+ * fn: (target: Node, edge: EdgeData, source: Node) => void,
13
+ * ): Graph
14
+ * ```
15
+ *
16
+ * Iterates over all neighbor nodes of a specific type, executing a function for each neighbor. The function receives the target node, edge data, and source node. Returns the graph unchanged (for chaining).
17
+ *
18
+ * ## Example
19
+ *
20
+ * ```ts
21
+ * import { Graph } from "@monstermann/graph";
22
+ *
23
+ * type Nodes =
24
+ * | { type: "Task"; id: string; title: string }
25
+ * | { type: "Section"; id: string }
26
+ * | { type: "Project"; id: string; name: string };
27
+ *
28
+ * type Edges = {
29
+ * Project: { Task: { priority: number } };
30
+ * Section: { Task: void };
31
+ * };
32
+ *
33
+ * const graph = Graph.create<Nodes, Edges>();
34
+ * let g = Graph.setNode(graph, { type: "Project", id: "1", name: "My Project" });
35
+ * g = Graph.setNode(g, { type: "Task", id: "1", title: "First Task" });
36
+ * g = Graph.setNode(g, { type: "Task", id: "2", title: "Second Task" });
37
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "1"], { priority: 1 });
38
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "2"], { priority: 2 });
39
+ *
40
+ * Graph.forEachNeighbor(g, ["Project", "1"], "Task", (task, edge, project) => {
41
+ * console.log(`${project.name}: ${task.title} (priority: ${edge.priority})`);
42
+ * });
43
+ * // Logs:
44
+ * // "My Project: First Task (priority: 1)"
45
+ * // "My Project: Second Task (priority: 2)"
46
+ * ```
47
+ *
48
+ */
49
+ function forEachNeighbor(graph, node, type, fn) {
50
+ const sourceNode = getNode(graph, node);
51
+ if (!sourceNode) return graph;
52
+ const nodeMap = graph.get("nodes")?.get(type);
53
+ if (!nodeMap) return graph;
54
+ for (const [targetId, edge] of graph.get("edges")?.get(sourceNode.type)?.get(sourceNode.id)?.get(type) ?? []) fn(nodeMap.get(targetId), edge, sourceNode);
55
+ return graph;
56
+ }
57
+
58
+ //#endregion
59
+ export { forEachNeighbor };
@@ -0,0 +1,49 @@
1
+ import { Edges, Graph, Node, NodeOfType, NodeType } from "./types.mjs";
2
+
3
+ //#region src/Graph/forEachNode.d.ts
4
+ /**
5
+ * # forEachNode
6
+ *
7
+ * ```ts
8
+ * function Graph.forEachNode(
9
+ * graph: Graph,
10
+ * type: NodeType,
11
+ * fn: (node: Node) => void,
12
+ * ): Graph
13
+ * ```
14
+ *
15
+ * Iterates over all nodes of a specific type, executing a function for each node. Returns the graph unchanged (for chaining).
16
+ *
17
+ * ## Example
18
+ *
19
+ * ```ts
20
+ * import { Graph } from "@monstermann/graph";
21
+ *
22
+ * type Nodes =
23
+ * | { type: "Task"; id: string; title: string }
24
+ * | { type: "Section"; id: string }
25
+ * | { type: "Project"; id: string };
26
+ *
27
+ * type Edges = {
28
+ * Project: { Task: void };
29
+ * Section: { Task: void };
30
+ * };
31
+ *
32
+ * const graph = Graph.create<Nodes, Edges>();
33
+ * let g = Graph.setNode(graph, { type: "Task", id: "1", title: "First Task" });
34
+ * g = Graph.setNode(g, { type: "Task", id: "2", title: "Second Task" });
35
+ * g = Graph.setNode(g, { type: "Task", id: "3", title: "Third Task" });
36
+ *
37
+ * Graph.forEachNode(g, "Task", (task) => {
38
+ * console.log(task.title);
39
+ * });
40
+ * // Logs:
41
+ * // "First Task"
42
+ * // "Second Task"
43
+ * // "Third Task"
44
+ * ```
45
+ *
46
+ */
47
+ declare function forEachNode<N extends Node, E extends Edges<N>, U extends NodeType<N>>(graph: Graph<N, E>, type: U, fn: (node: NoInfer<NodeOfType<N, U>>) => void): Graph<N, E>;
48
+ //#endregion
49
+ export { forEachNode };
@@ -0,0 +1,51 @@
1
+ //#region src/Graph/forEachNode.ts
2
+ /**
3
+ * # forEachNode
4
+ *
5
+ * ```ts
6
+ * function Graph.forEachNode(
7
+ * graph: Graph,
8
+ * type: NodeType,
9
+ * fn: (node: Node) => void,
10
+ * ): Graph
11
+ * ```
12
+ *
13
+ * Iterates over all nodes of a specific type, executing a function for each node. Returns the graph unchanged (for chaining).
14
+ *
15
+ * ## Example
16
+ *
17
+ * ```ts
18
+ * import { Graph } from "@monstermann/graph";
19
+ *
20
+ * type Nodes =
21
+ * | { type: "Task"; id: string; title: string }
22
+ * | { type: "Section"; id: string }
23
+ * | { type: "Project"; id: string };
24
+ *
25
+ * type Edges = {
26
+ * Project: { Task: void };
27
+ * Section: { Task: void };
28
+ * };
29
+ *
30
+ * const graph = Graph.create<Nodes, Edges>();
31
+ * let g = Graph.setNode(graph, { type: "Task", id: "1", title: "First Task" });
32
+ * g = Graph.setNode(g, { type: "Task", id: "2", title: "Second Task" });
33
+ * g = Graph.setNode(g, { type: "Task", id: "3", title: "Third Task" });
34
+ *
35
+ * Graph.forEachNode(g, "Task", (task) => {
36
+ * console.log(task.title);
37
+ * });
38
+ * // Logs:
39
+ * // "First Task"
40
+ * // "Second Task"
41
+ * // "Third Task"
42
+ * ```
43
+ *
44
+ */
45
+ function forEachNode(graph, type, fn) {
46
+ for (const node of graph.get("nodes")?.get(type)?.values() ?? []) fn(node);
47
+ return graph;
48
+ }
49
+
50
+ //#endregion
51
+ export { forEachNode };
@@ -0,0 +1,55 @@
1
+ import { Edge, Edges, Graph, Node, NodeId } from "./types.mjs";
2
+
3
+ //#region src/Graph/fromJS.d.ts
4
+ /**
5
+ * # fromJS
6
+ *
7
+ * ```ts
8
+ * function Graph.fromJS(data: {
9
+ * nodes: Node[];
10
+ * edges: [NodeType, NodeId, NodeType, NodeId, EdgeData][];
11
+ * }): Graph
12
+ * ```
13
+ *
14
+ * Creates a graph from a plain JavaScript object representation. Useful for deserializing graphs from JSON or other storage formats.
15
+ *
16
+ * ## Example
17
+ *
18
+ * ```ts
19
+ * import { Graph } from "@monstermann/graph";
20
+ *
21
+ * type Nodes =
22
+ * | { type: "Task"; id: string; title: string }
23
+ * | { type: "Section"; id: string }
24
+ * | { type: "Project"; id: string };
25
+ *
26
+ * type Edges = {
27
+ * Project: { Task: void };
28
+ * Section: { Task: void };
29
+ * };
30
+ *
31
+ * const data = {
32
+ * nodes: [
33
+ * { type: "Project", id: "1" },
34
+ * { type: "Task", id: "1", title: "My Task" },
35
+ * { type: "Task", id: "2", title: "Another Task" },
36
+ * ],
37
+ * edges: [
38
+ * ["Project", "1", "Task", "1", undefined],
39
+ * ["Project", "1", "Task", "2", undefined],
40
+ * ],
41
+ * };
42
+ *
43
+ * const graph = Graph.fromJS<Nodes, Edges>(data);
44
+ *
45
+ * Graph.hasNode(graph, ["Project", "1"]); // true
46
+ * Graph.hasEdge(graph, ["Project", "1"], ["Task", "1"]); // true
47
+ * ```
48
+ *
49
+ */
50
+ declare function fromJS<N extends Node, E extends Edges<N>>(data: {
51
+ edges: [string, NodeId, string, NodeId, Edge][];
52
+ nodes: Node[];
53
+ }): Graph<N, E>;
54
+ //#endregion
55
+ export { fromJS };
@@ -0,0 +1,62 @@
1
+ import { batch } from "./batch.mjs";
2
+ import { create } from "./create.mjs";
3
+ import { setEdge } from "./setEdge.mjs";
4
+ import { setNode } from "./setNode.mjs";
5
+
6
+ //#region src/Graph/fromJS.ts
7
+ /**
8
+ * # fromJS
9
+ *
10
+ * ```ts
11
+ * function Graph.fromJS(data: {
12
+ * nodes: Node[];
13
+ * edges: [NodeType, NodeId, NodeType, NodeId, EdgeData][];
14
+ * }): Graph
15
+ * ```
16
+ *
17
+ * Creates a graph from a plain JavaScript object representation. Useful for deserializing graphs from JSON or other storage formats.
18
+ *
19
+ * ## Example
20
+ *
21
+ * ```ts
22
+ * import { Graph } from "@monstermann/graph";
23
+ *
24
+ * type Nodes =
25
+ * | { type: "Task"; id: string; title: string }
26
+ * | { type: "Section"; id: string }
27
+ * | { type: "Project"; id: string };
28
+ *
29
+ * type Edges = {
30
+ * Project: { Task: void };
31
+ * Section: { Task: void };
32
+ * };
33
+ *
34
+ * const data = {
35
+ * nodes: [
36
+ * { type: "Project", id: "1" },
37
+ * { type: "Task", id: "1", title: "My Task" },
38
+ * { type: "Task", id: "2", title: "Another Task" },
39
+ * ],
40
+ * edges: [
41
+ * ["Project", "1", "Task", "1", undefined],
42
+ * ["Project", "1", "Task", "2", undefined],
43
+ * ],
44
+ * };
45
+ *
46
+ * const graph = Graph.fromJS<Nodes, Edges>(data);
47
+ *
48
+ * Graph.hasNode(graph, ["Project", "1"]); // true
49
+ * Graph.hasEdge(graph, ["Project", "1"], ["Task", "1"]); // true
50
+ * ```
51
+ *
52
+ */
53
+ function fromJS(data) {
54
+ return batch(create(), (graph) => {
55
+ for (const node of data.nodes) graph = setNode(graph, node);
56
+ for (const [sourceType, sourceId, targetType, targetId, edge] of data.edges) graph = setEdge(graph, [sourceType, sourceId], [targetType, targetId], edge);
57
+ return graph;
58
+ });
59
+ }
60
+
61
+ //#endregion
62
+ export { fromJS };
@@ -0,0 +1,50 @@
1
+ import { Bimap } from "./internals/types.mjs";
2
+ import { Edges, Graph, Node, NodeIdentifier, NodeType } from "./types.mjs";
3
+
4
+ //#region src/Graph/getEdge.d.ts
5
+ /**
6
+ * # getEdge
7
+ *
8
+ * ```ts
9
+ * function Graph.getEdge(
10
+ * graph: Graph,
11
+ * source: [NodeType, NodeId] | { type: NodeType, id: NodeId },
12
+ * target: [NodeType, NodeId] | { type: NodeType, id: NodeId },
13
+ * ): EdgeData | undefined
14
+ * ```
15
+ *
16
+ * Retrieves the edge data between two nodes. Returns `undefined` if the edge doesn't exist.
17
+ *
18
+ * ## Example
19
+ *
20
+ * ```ts
21
+ * import { Graph } from "@monstermann/graph";
22
+ *
23
+ * type Nodes =
24
+ * | { type: "Task"; id: string }
25
+ * | { type: "Section"; id: string }
26
+ * | { type: "Project"; id: string };
27
+ *
28
+ * type Edges = {
29
+ * Project: { Task: { assignedAt: Date } };
30
+ * Section: { Task: void };
31
+ * };
32
+ *
33
+ * const graph = Graph.create<Nodes, Edges>();
34
+ * let g = Graph.setNode(graph, { type: "Project", id: "1" });
35
+ * g = Graph.setNode(g, { type: "Task", id: "1" });
36
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "1"], {
37
+ * assignedAt: new Date(),
38
+ * });
39
+ *
40
+ * const edge = Graph.getEdge(g, ["Project", "1"], ["Task", "1"]);
41
+ * // edge: { assignedAt: Date }
42
+ *
43
+ * const missing = Graph.getEdge(g, ["Project", "1"], ["Task", "2"]);
44
+ * // missing: undefined
45
+ * ```
46
+ *
47
+ */
48
+ declare function getEdge<N extends Node, E extends Edges<N>, N1 extends keyof Bimap<E> & NodeType<N>, N2 extends keyof Bimap<E>[N1] & NodeType<N>>(graph: Graph<N, E>, source: NodeIdentifier<N, N1>, target: NodeIdentifier<N, N2>): Bimap<E>[N1][N2] | undefined;
49
+ //#endregion
50
+ export { getEdge };
@@ -0,0 +1,54 @@
1
+ import { parseNodeIdentifier } from "./internals/parseNodeIdentifier.mjs";
2
+
3
+ //#region src/Graph/getEdge.ts
4
+ /**
5
+ * # getEdge
6
+ *
7
+ * ```ts
8
+ * function Graph.getEdge(
9
+ * graph: Graph,
10
+ * source: [NodeType, NodeId] | { type: NodeType, id: NodeId },
11
+ * target: [NodeType, NodeId] | { type: NodeType, id: NodeId },
12
+ * ): EdgeData | undefined
13
+ * ```
14
+ *
15
+ * Retrieves the edge data between two nodes. Returns `undefined` if the edge doesn't exist.
16
+ *
17
+ * ## Example
18
+ *
19
+ * ```ts
20
+ * import { Graph } from "@monstermann/graph";
21
+ *
22
+ * type Nodes =
23
+ * | { type: "Task"; id: string }
24
+ * | { type: "Section"; id: string }
25
+ * | { type: "Project"; id: string };
26
+ *
27
+ * type Edges = {
28
+ * Project: { Task: { assignedAt: Date } };
29
+ * Section: { Task: void };
30
+ * };
31
+ *
32
+ * const graph = Graph.create<Nodes, Edges>();
33
+ * let g = Graph.setNode(graph, { type: "Project", id: "1" });
34
+ * g = Graph.setNode(g, { type: "Task", id: "1" });
35
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "1"], {
36
+ * assignedAt: new Date(),
37
+ * });
38
+ *
39
+ * const edge = Graph.getEdge(g, ["Project", "1"], ["Task", "1"]);
40
+ * // edge: { assignedAt: Date }
41
+ *
42
+ * const missing = Graph.getEdge(g, ["Project", "1"], ["Task", "2"]);
43
+ * // missing: undefined
44
+ * ```
45
+ *
46
+ */
47
+ function getEdge(graph, source, target) {
48
+ const [sourceType, sourceId] = parseNodeIdentifier(source);
49
+ const [targetType, targetId] = parseNodeIdentifier(target);
50
+ return graph.get("edges")?.get(sourceType)?.get(sourceId)?.get(targetType)?.get(targetId);
51
+ }
52
+
53
+ //#endregion
54
+ export { getEdge };
@@ -0,0 +1,47 @@
1
+ import { Bimap } from "./internals/types.mjs";
2
+ import { Edges, Graph, Node, NodeIdentifier, NodeType } from "./types.mjs";
3
+
4
+ //#region src/Graph/getEdges.d.ts
5
+ /**
6
+ * # getEdges
7
+ *
8
+ * ```ts
9
+ * function Graph.getEdges(
10
+ * graph: Graph,
11
+ * source: [NodeType, NodeId] | { type: NodeType, id: NodeId },
12
+ * type: NodeType,
13
+ * ): EdgeData[]
14
+ * ```
15
+ *
16
+ * Retrieves all edges of a specific type from a source node.
17
+ *
18
+ * ## Example
19
+ *
20
+ * ```ts
21
+ * import { Graph } from "@monstermann/graph";
22
+ *
23
+ * type Nodes =
24
+ * | { type: "Task"; id: string }
25
+ * | { type: "Section"; id: string }
26
+ * | { type: "Project"; id: string };
27
+ *
28
+ * type Edges = {
29
+ * Project: { Task: { priority: number } };
30
+ * Section: { Task: void };
31
+ * };
32
+ *
33
+ * const graph = Graph.create<Nodes, Edges>();
34
+ * let g = Graph.setNode(graph, { type: "Project", id: "1" });
35
+ * g = Graph.setNode(g, { type: "Task", id: "1" });
36
+ * g = Graph.setNode(g, { type: "Task", id: "2" });
37
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "1"], { priority: 1 });
38
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "2"], { priority: 2 });
39
+ *
40
+ * const edges = Graph.getEdges(g, ["Project", "1"], "Task");
41
+ * // edges: [{ priority: 1 }, { priority: 2 }]
42
+ * ```
43
+ *
44
+ */
45
+ declare function getEdges<N extends Node, E extends Edges<N>, N1 extends keyof Bimap<E> & NodeType<N>, N2 extends keyof Bimap<E>[N1] & NodeType<N>>(graph: Graph<N, E>, source: NodeIdentifier<N, N1>, type: N2): Bimap<E>[N1][N2][];
46
+ //#endregion
47
+ export { getEdges };
@@ -0,0 +1,51 @@
1
+ import { parseNodeIdentifier } from "./internals/parseNodeIdentifier.mjs";
2
+
3
+ //#region src/Graph/getEdges.ts
4
+ /**
5
+ * # getEdges
6
+ *
7
+ * ```ts
8
+ * function Graph.getEdges(
9
+ * graph: Graph,
10
+ * source: [NodeType, NodeId] | { type: NodeType, id: NodeId },
11
+ * type: NodeType,
12
+ * ): EdgeData[]
13
+ * ```
14
+ *
15
+ * Retrieves all edges of a specific type from a source node.
16
+ *
17
+ * ## Example
18
+ *
19
+ * ```ts
20
+ * import { Graph } from "@monstermann/graph";
21
+ *
22
+ * type Nodes =
23
+ * | { type: "Task"; id: string }
24
+ * | { type: "Section"; id: string }
25
+ * | { type: "Project"; id: string };
26
+ *
27
+ * type Edges = {
28
+ * Project: { Task: { priority: number } };
29
+ * Section: { Task: void };
30
+ * };
31
+ *
32
+ * const graph = Graph.create<Nodes, Edges>();
33
+ * let g = Graph.setNode(graph, { type: "Project", id: "1" });
34
+ * g = Graph.setNode(g, { type: "Task", id: "1" });
35
+ * g = Graph.setNode(g, { type: "Task", id: "2" });
36
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "1"], { priority: 1 });
37
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "2"], { priority: 2 });
38
+ *
39
+ * const edges = Graph.getEdges(g, ["Project", "1"], "Task");
40
+ * // edges: [{ priority: 1 }, { priority: 2 }]
41
+ * ```
42
+ *
43
+ */
44
+ function getEdges(graph, source, type) {
45
+ const [sourceType, sourceId] = parseNodeIdentifier(source);
46
+ const edgeMap = graph.get("edges")?.get(sourceType)?.get(sourceId)?.get(type);
47
+ return edgeMap ? [...edgeMap.values()] : [];
48
+ }
49
+
50
+ //#endregion
51
+ export { getEdges };