@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,50 @@
1
+ import { Bimap } from "./internals/types.mjs";
2
+ import { Edges, Graph, Node, NodeIdentifier, NodeOfType, NodeType } from "./types.mjs";
3
+
4
+ //#region src/Graph/getNeighbor.d.ts
5
+ /**
6
+ * # getNeighbor
7
+ *
8
+ * ```ts
9
+ * function Graph.getNeighbor(
10
+ * graph: Graph,
11
+ * node: [NodeType, NodeId] | { type: NodeType, id: NodeId },
12
+ * type: NodeType,
13
+ * ): Node | undefined
14
+ * ```
15
+ *
16
+ * Retrieves the first neighbor node of a specific type connected to the source node. Returns `undefined` if no neighbor of the specified type exists.
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 };
27
+ *
28
+ * type Edges = {
29
+ * Project: { Task: void };
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", title: "Task 1" });
36
+ * g = Graph.setNode(g, { type: "Task", id: "2", title: "Task 2" });
37
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "1"]);
38
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "2"]);
39
+ *
40
+ * const firstTask = Graph.getNeighbor(g, ["Project", "1"], "Task");
41
+ * // firstTask: { type: "Task", id: "1", title: "Task 1" }
42
+ *
43
+ * const noSection = Graph.getNeighbor(g, ["Project", "1"], "Section");
44
+ * // noSection: undefined
45
+ * ```
46
+ *
47
+ */
48
+ declare function getNeighbor<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): NodeOfType<N, N2> | undefined;
49
+ //#endregion
50
+ export { getNeighbor };
@@ -0,0 +1,56 @@
1
+ import { getNode } from "./getNode.mjs";
2
+
3
+ //#region src/Graph/getNeighbor.ts
4
+ /**
5
+ * # getNeighbor
6
+ *
7
+ * ```ts
8
+ * function Graph.getNeighbor(
9
+ * graph: Graph,
10
+ * node: [NodeType, NodeId] | { type: NodeType, id: NodeId },
11
+ * type: NodeType,
12
+ * ): Node | undefined
13
+ * ```
14
+ *
15
+ * Retrieves the first neighbor node of a specific type connected to the source node. Returns `undefined` if no neighbor of the specified type exists.
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: "Project", id: "1" });
34
+ * g = Graph.setNode(g, { type: "Task", id: "1", title: "Task 1" });
35
+ * g = Graph.setNode(g, { type: "Task", id: "2", title: "Task 2" });
36
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "1"]);
37
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "2"]);
38
+ *
39
+ * const firstTask = Graph.getNeighbor(g, ["Project", "1"], "Task");
40
+ * // firstTask: { type: "Task", id: "1", title: "Task 1" }
41
+ *
42
+ * const noSection = Graph.getNeighbor(g, ["Project", "1"], "Section");
43
+ * // noSection: undefined
44
+ * ```
45
+ *
46
+ */
47
+ function getNeighbor(graph, node, type) {
48
+ const sourceNode = getNode(graph, node);
49
+ if (!sourceNode) return void 0;
50
+ const nodeMap = graph.get("nodes")?.get(type);
51
+ if (!nodeMap) return void 0;
52
+ for (const targetId of graph.get("edges")?.get(sourceNode.type)?.get(sourceNode.id)?.get(type)?.keys() ?? []) return nodeMap.get(targetId);
53
+ }
54
+
55
+ //#endregion
56
+ export { getNeighbor };
@@ -0,0 +1,47 @@
1
+ import { Bimap } from "./internals/types.mjs";
2
+ import { Edges, Graph, Node, NodeIdentifier, NodeOfType, NodeType } from "./types.mjs";
3
+
4
+ //#region src/Graph/getNeighbors.d.ts
5
+ /**
6
+ * # getNeighbors
7
+ *
8
+ * ```ts
9
+ * function Graph.getNeighbors(
10
+ * graph: Graph,
11
+ * node: [NodeType, NodeId] | { type: NodeType, id: NodeId },
12
+ * type: NodeType,
13
+ * ): Node[]
14
+ * ```
15
+ *
16
+ * Retrieves all neighbor nodes of a specific type connected to the source node.
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 };
27
+ *
28
+ * type Edges = {
29
+ * Project: { Task: void };
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", title: "Task 1" });
36
+ * g = Graph.setNode(g, { type: "Task", id: "2", title: "Task 2" });
37
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "1"]);
38
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "2"]);
39
+ *
40
+ * const tasks = Graph.getNeighbors(g, ["Project", "1"], "Task");
41
+ * // tasks: [{ type: "Task", id: "1", title: "Task 1" }, { type: "Task", id: "2", title: "Task 2" }]
42
+ * ```
43
+ *
44
+ */
45
+ declare function getNeighbors<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): NodeOfType<N, N2>[];
46
+ //#endregion
47
+ export { getNeighbors };
@@ -0,0 +1,58 @@
1
+ import { getNode } from "./getNode.mjs";
2
+
3
+ //#region src/Graph/getNeighbors.ts
4
+ /**
5
+ * # getNeighbors
6
+ *
7
+ * ```ts
8
+ * function Graph.getNeighbors(
9
+ * graph: Graph,
10
+ * node: [NodeType, NodeId] | { type: NodeType, id: NodeId },
11
+ * type: NodeType,
12
+ * ): Node[]
13
+ * ```
14
+ *
15
+ * Retrieves all neighbor nodes of a specific type connected to the source node.
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: "Project", id: "1" });
34
+ * g = Graph.setNode(g, { type: "Task", id: "1", title: "Task 1" });
35
+ * g = Graph.setNode(g, { type: "Task", id: "2", title: "Task 2" });
36
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "1"]);
37
+ * g = Graph.setEdge(g, ["Project", "1"], ["Task", "2"]);
38
+ *
39
+ * const tasks = Graph.getNeighbors(g, ["Project", "1"], "Task");
40
+ * // tasks: [{ type: "Task", id: "1", title: "Task 1" }, { type: "Task", id: "2", title: "Task 2" }]
41
+ * ```
42
+ *
43
+ */
44
+ function getNeighbors(graph, node, type) {
45
+ const result = [];
46
+ const sourceNode = getNode(graph, node);
47
+ if (!sourceNode) return result;
48
+ const nodeMap = graph.get("nodes")?.get(type);
49
+ if (!nodeMap) return result;
50
+ for (const targetId of graph.get("edges")?.get(sourceNode.type)?.get(sourceNode.id)?.get(type)?.keys() ?? []) {
51
+ const targetNode = nodeMap.get(targetId);
52
+ result.push(targetNode);
53
+ }
54
+ return result;
55
+ }
56
+
57
+ //#endregion
58
+ export { getNeighbors };
@@ -0,0 +1,48 @@
1
+ import { Edges, Graph, Node, NodeIdentifier, NodeOfType, NodeType } from "./types.mjs";
2
+
3
+ //#region src/Graph/getNode.d.ts
4
+ /**
5
+ * # getNode
6
+ *
7
+ * ```ts
8
+ * function Graph.getNode(
9
+ * graph: Graph,
10
+ * node: [NodeType, NodeId] | { type: NodeType, id: NodeId },
11
+ * ): Node | undefined
12
+ * ```
13
+ *
14
+ * Retrieves a node from the graph. Returns `undefined` if the node doesn't exist.
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 graph = Graph.create<Nodes, Edges>();
32
+ * const withNode = Graph.setNode(graph, {
33
+ * type: "Task",
34
+ * id: "1",
35
+ * title: "My Task",
36
+ * });
37
+ *
38
+ * const task = Graph.getNode(withNode, ["Task", "1"]);
39
+ * // task: { type: "Task", id: "1", title: "My Task" }
40
+ *
41
+ * const missing = Graph.getNode(withNode, ["Task", "2"]);
42
+ * // missing: undefined
43
+ * ```
44
+ *
45
+ */
46
+ declare function getNode<N extends Node, E extends Edges<N>, U extends NodeType<N>>(graph: Graph<N, E>, node: NodeIdentifier<N, U>): NodeOfType<N, U> | undefined;
47
+ //#endregion
48
+ export { getNode };
@@ -0,0 +1,52 @@
1
+ import { parseNodeIdentifier } from "./internals/parseNodeIdentifier.mjs";
2
+
3
+ //#region src/Graph/getNode.ts
4
+ /**
5
+ * # getNode
6
+ *
7
+ * ```ts
8
+ * function Graph.getNode(
9
+ * graph: Graph,
10
+ * node: [NodeType, NodeId] | { type: NodeType, id: NodeId },
11
+ * ): Node | undefined
12
+ * ```
13
+ *
14
+ * Retrieves a node from the graph. Returns `undefined` if the node doesn't exist.
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 graph = Graph.create<Nodes, Edges>();
32
+ * const withNode = Graph.setNode(graph, {
33
+ * type: "Task",
34
+ * id: "1",
35
+ * title: "My Task",
36
+ * });
37
+ *
38
+ * const task = Graph.getNode(withNode, ["Task", "1"]);
39
+ * // task: { type: "Task", id: "1", title: "My Task" }
40
+ *
41
+ * const missing = Graph.getNode(withNode, ["Task", "2"]);
42
+ * // missing: undefined
43
+ * ```
44
+ *
45
+ */
46
+ function getNode(graph, node) {
47
+ const [type, id] = parseNodeIdentifier(node);
48
+ return graph.get("nodes")?.get(type)?.get(id);
49
+ }
50
+
51
+ //#endregion
52
+ export { getNode };
@@ -0,0 +1,46 @@
1
+ import { Edges, Graph, Node, NodeOfType, NodeType } from "./types.mjs";
2
+
3
+ //#region src/Graph/getNodes.d.ts
4
+ /**
5
+ * # getNodes
6
+ *
7
+ * ```ts
8
+ * function Graph.getNodes(
9
+ * graph: Graph,
10
+ * type: NodeType,
11
+ * ): Node[]
12
+ * ```
13
+ *
14
+ * Retrieves all nodes of a specific type from the graph.
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 graph = Graph.create<Nodes, Edges>();
32
+ * let g = Graph.setNode(graph, { type: "Task", id: "1", title: "Task 1" });
33
+ * g = Graph.setNode(g, { type: "Task", id: "2", title: "Task 2" });
34
+ * g = Graph.setNode(g, { type: "Project", id: "1" });
35
+ *
36
+ * const tasks = Graph.getNodes(g, "Task");
37
+ * // tasks: [{ type: "Task", id: "1", title: "Task 1" }, { type: "Task", id: "2", title: "Task 2" }]
38
+ *
39
+ * const projects = Graph.getNodes(g, "Project");
40
+ * // projects: [{ type: "Project", id: "1" }]
41
+ * ```
42
+ *
43
+ */
44
+ declare function getNodes<N extends Node, E extends Edges<N>, U extends NodeType<N>>(graph: Graph<N, E>, type: U): NodeOfType<N, U>[];
45
+ //#endregion
46
+ export { getNodes };
@@ -0,0 +1,48 @@
1
+ //#region src/Graph/getNodes.ts
2
+ /**
3
+ * # getNodes
4
+ *
5
+ * ```ts
6
+ * function Graph.getNodes(
7
+ * graph: Graph,
8
+ * type: NodeType,
9
+ * ): Node[]
10
+ * ```
11
+ *
12
+ * Retrieves all nodes of a specific type from the graph.
13
+ *
14
+ * ## Example
15
+ *
16
+ * ```ts
17
+ * import { Graph } from "@monstermann/graph";
18
+ *
19
+ * type Nodes =
20
+ * | { type: "Task"; id: string; title: string }
21
+ * | { type: "Section"; id: string }
22
+ * | { type: "Project"; id: string };
23
+ *
24
+ * type Edges = {
25
+ * Project: { Task: void };
26
+ * Section: { Task: void };
27
+ * };
28
+ *
29
+ * const graph = Graph.create<Nodes, Edges>();
30
+ * let g = Graph.setNode(graph, { type: "Task", id: "1", title: "Task 1" });
31
+ * g = Graph.setNode(g, { type: "Task", id: "2", title: "Task 2" });
32
+ * g = Graph.setNode(g, { type: "Project", id: "1" });
33
+ *
34
+ * const tasks = Graph.getNodes(g, "Task");
35
+ * // tasks: [{ type: "Task", id: "1", title: "Task 1" }, { type: "Task", id: "2", title: "Task 2" }]
36
+ *
37
+ * const projects = Graph.getNodes(g, "Project");
38
+ * // projects: [{ type: "Project", id: "1" }]
39
+ * ```
40
+ *
41
+ */
42
+ function getNodes(graph, type) {
43
+ const nodeMap = graph.get("nodes")?.get(type);
44
+ return nodeMap ? [...nodeMap.values()] : [];
45
+ }
46
+
47
+ //#endregion
48
+ export { getNodes };
@@ -0,0 +1,46 @@
1
+ import { Bimap } from "./internals/types.mjs";
2
+ import { Edges, Graph, Node, NodeIdentifier, NodeType } from "./types.mjs";
3
+
4
+ //#region src/Graph/hasEdge.d.ts
5
+ /**
6
+ * # hasEdge
7
+ *
8
+ * ```ts
9
+ * function Graph.hasEdge(
10
+ * graph: Graph,
11
+ * source: [NodeType, NodeId] | { type: NodeType, id: NodeId },
12
+ * target: [NodeType, NodeId] | { type: NodeType, id: NodeId },
13
+ * ): boolean
14
+ * ```
15
+ *
16
+ * Checks if an edge exists between two nodes in the graph.
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: void };
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
+ *
38
+ * Graph.hasEdge(g, ["Project", "1"], ["Task", "1"]); // true
39
+ * Graph.hasEdge(g, ["Task", "1"], ["Project", "1"]); // true (bidirectional)
40
+ * Graph.hasEdge(g, ["Project", "1"], ["Task", "2"]); // false
41
+ * ```
42
+ *
43
+ */
44
+ declare function hasEdge<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>): boolean;
45
+ //#endregion
46
+ export { hasEdge };
@@ -0,0 +1,50 @@
1
+ import { parseNodeIdentifier } from "./internals/parseNodeIdentifier.mjs";
2
+
3
+ //#region src/Graph/hasEdge.ts
4
+ /**
5
+ * # hasEdge
6
+ *
7
+ * ```ts
8
+ * function Graph.hasEdge(
9
+ * graph: Graph,
10
+ * source: [NodeType, NodeId] | { type: NodeType, id: NodeId },
11
+ * target: [NodeType, NodeId] | { type: NodeType, id: NodeId },
12
+ * ): boolean
13
+ * ```
14
+ *
15
+ * Checks if an edge exists between two nodes in the graph.
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: void };
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
+ *
37
+ * Graph.hasEdge(g, ["Project", "1"], ["Task", "1"]); // true
38
+ * Graph.hasEdge(g, ["Task", "1"], ["Project", "1"]); // true (bidirectional)
39
+ * Graph.hasEdge(g, ["Project", "1"], ["Task", "2"]); // false
40
+ * ```
41
+ *
42
+ */
43
+ function hasEdge(graph, source, target) {
44
+ const [sourceType, sourceId] = parseNodeIdentifier(source);
45
+ const [targetType, targetId] = parseNodeIdentifier(target);
46
+ return graph.get("edges")?.get(sourceType)?.get(sourceId)?.get(targetType)?.has(targetId) ?? false;
47
+ }
48
+
49
+ //#endregion
50
+ export { hasEdge };
@@ -0,0 +1,42 @@
1
+ import { Edges, Graph, Node, NodeIdentifier, NodeType } from "./types.mjs";
2
+
3
+ //#region src/Graph/hasNode.d.ts
4
+ /**
5
+ * # hasNode
6
+ *
7
+ * ```ts
8
+ * function Graph.hasNode(
9
+ * graph: Graph,
10
+ * node: [NodeType, NodeId] | { type: NodeType, id: NodeId },
11
+ * ): boolean
12
+ * ```
13
+ *
14
+ * Checks if a node exists in the graph.
15
+ *
16
+ * ## Example
17
+ *
18
+ * ```ts
19
+ * import { Graph } from "@monstermann/graph";
20
+ *
21
+ * type Nodes =
22
+ * | { type: "Task"; id: 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 graph = Graph.create<Nodes, Edges>();
32
+ * const withNode = Graph.setNode(graph, { type: "Task", id: "1" });
33
+ *
34
+ * Graph.hasNode(withNode, ["Task", "1"]); // true
35
+ * Graph.hasNode(withNode, { type: "Task", id: "1" }); // true
36
+ * Graph.hasNode(withNode, ["Task", "2"]); // false
37
+ * ```
38
+ *
39
+ */
40
+ declare function hasNode<N extends Node, E extends Edges<N>, U extends NodeType<N>>(graph: Graph<N, E>, node: NodeIdentifier<N, U>): boolean;
41
+ //#endregion
42
+ export { hasNode };
@@ -0,0 +1,46 @@
1
+ import { parseNodeIdentifier } from "./internals/parseNodeIdentifier.mjs";
2
+
3
+ //#region src/Graph/hasNode.ts
4
+ /**
5
+ * # hasNode
6
+ *
7
+ * ```ts
8
+ * function Graph.hasNode(
9
+ * graph: Graph,
10
+ * node: [NodeType, NodeId] | { type: NodeType, id: NodeId },
11
+ * ): boolean
12
+ * ```
13
+ *
14
+ * Checks if a node exists in the graph.
15
+ *
16
+ * ## Example
17
+ *
18
+ * ```ts
19
+ * import { Graph } from "@monstermann/graph";
20
+ *
21
+ * type Nodes =
22
+ * | { type: "Task"; id: 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 graph = Graph.create<Nodes, Edges>();
32
+ * const withNode = Graph.setNode(graph, { type: "Task", id: "1" });
33
+ *
34
+ * Graph.hasNode(withNode, ["Task", "1"]); // true
35
+ * Graph.hasNode(withNode, { type: "Task", id: "1" }); // true
36
+ * Graph.hasNode(withNode, ["Task", "2"]); // false
37
+ * ```
38
+ *
39
+ */
40
+ function hasNode(graph, node) {
41
+ const [type, id] = parseNodeIdentifier(node);
42
+ return graph.get("nodes")?.get(type)?.has(id) ?? false;
43
+ }
44
+
45
+ //#endregion
46
+ export { hasNode };
@@ -0,0 +1,68 @@
1
+ import { batch } from "./batch.mjs";
2
+ import { create } from "./create.mjs";
3
+ import { findEdge } from "./findEdge.mjs";
4
+ import { findEdges } from "./findEdges.mjs";
5
+ import { findNeighbor } from "./findNeighbor.mjs";
6
+ import { findNeighbors } from "./findNeighbors.mjs";
7
+ import { findNode } from "./findNode.mjs";
8
+ import { findNodes } from "./findNodes.mjs";
9
+ import { forEachEdge } from "./forEachEdge.mjs";
10
+ import { forEachNeighbor } from "./forEachNeighbor.mjs";
11
+ import { forEachNode } from "./forEachNode.mjs";
12
+ import { fromJS } from "./fromJS.mjs";
13
+ import { getEdge } from "./getEdge.mjs";
14
+ import { getEdges } from "./getEdges.mjs";
15
+ import { getNeighbor } from "./getNeighbor.mjs";
16
+ import { getNeighbors } from "./getNeighbors.mjs";
17
+ import { getNode } from "./getNode.mjs";
18
+ import { getNodes } from "./getNodes.mjs";
19
+ import { hasEdge } from "./hasEdge.mjs";
20
+ import { hasNode } from "./hasNode.mjs";
21
+ import { mapEdge } from "./mapEdge.mjs";
22
+ import { mapNode } from "./mapNode.mjs";
23
+ import { mergeEdge } from "./mergeEdge.mjs";
24
+ import { mergeNode } from "./mergeNode.mjs";
25
+ import { removeEdge } from "./removeEdge.mjs";
26
+ import { removeNode } from "./removeNode.mjs";
27
+ import { setEdge } from "./setEdge.mjs";
28
+ import { setNode } from "./setNode.mjs";
29
+ import { toJS } from "./toJS.mjs";
30
+
31
+ //#region src/Graph/index.d.ts
32
+ type NodeId = PropertyKey;
33
+ type Node = {
34
+ id: NodeId;
35
+ type: string;
36
+ };
37
+ type NodeType<T extends Node> = T["type"];
38
+ type NodeOfType<T extends Node, U extends NodeType<T>> = Extract<T, {
39
+ type: U;
40
+ }>;
41
+ type NodeIdentifier<T extends Node, U = NodeType<T>> = {
42
+ id: Extract<T, {
43
+ type: U;
44
+ }>["id"];
45
+ type: U;
46
+ } | [U, id: Extract<T, {
47
+ type: U;
48
+ }>["id"]];
49
+ type Edge = Record<string, unknown> | void;
50
+ type Edges<N extends Node> = Partial<Record<NodeType<N>, Partial<Record<NodeType<N>, Edge>>>>;
51
+ type SourceTypesMap = ReadonlyMap<any, SourceIdsMap>;
52
+ type SourceIdsMap = ReadonlyMap<NodeId, TargetTypesMap>;
53
+ type TargetTypesMap = ReadonlyMap<any, TargetIdsMap>;
54
+ type TargetIdsMap = ReadonlyMap<NodeId, Edge>;
55
+ type NodeIdsMap<T extends Node, U extends NodeType<T> = NodeType<T>> = ReadonlyMap<NodeId, NodeOfType<T, U>>;
56
+ interface NodeTypesMap<T extends Node> extends ReadonlyMap<NodeType<T>, NodeIdsMap<T, NodeType<T>>> {
57
+ get: <V extends NodeType<T>>(type: V) => NodeIdsMap<T, V> | undefined;
58
+ }
59
+ interface Graph<N extends Node, _E extends Edges<N>> extends Map<"nodes" | "edges" | "clones", NodeTypesMap<N> | SourceTypesMap | Set<any>> {
60
+ delete: (key: "clones") => boolean;
61
+ get: ((key: "nodes") => NodeTypesMap<N> | undefined) & ((key: "edges") => SourceTypesMap | undefined) & ((key: "clones") => Set<any> | undefined);
62
+ set: (key: "clones", value: Set<any>) => this;
63
+ }
64
+ declare namespace Graph {
65
+ export { batch, create, findEdge, findEdges, findNeighbor, findNeighbors, findNode, findNodes, forEachEdge, forEachNeighbor, forEachNode, fromJS, getEdge, getEdges, getNeighbor, getNeighbors, getNode, getNodes, hasEdge, hasNode, mapEdge, mapNode, mergeEdge, mergeNode, removeEdge, removeNode, setEdge, setNode, toJS };
66
+ }
67
+ //#endregion
68
+ export { Edge, Edges, Graph, Node, NodeId, NodeIdentifier, NodeIdsMap, NodeOfType, NodeType, NodeTypesMap, SourceIdsMap, SourceTypesMap, TargetIdsMap, TargetTypesMap };