@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.
- package/README.md +1383 -0
- package/dist/Graph/batch.d.mts +47 -0
- package/dist/Graph/batch.mjs +57 -0
- package/dist/Graph/create.d.mts +36 -0
- package/dist/Graph/create.mjs +37 -0
- package/dist/Graph/findEdge.d.mts +60 -0
- package/dist/Graph/findEdge.mjs +10 -0
- package/dist/Graph/findEdges.d.mts +65 -0
- package/dist/Graph/findEdges.mjs +12 -0
- package/dist/Graph/findNeighbor.d.mts +54 -0
- package/dist/Graph/findNeighbor.mjs +16 -0
- package/dist/Graph/findNeighbors.d.mts +59 -0
- package/dist/Graph/findNeighbors.mjs +18 -0
- package/dist/Graph/findNode.d.mts +67 -0
- package/dist/Graph/findNode.mjs +7 -0
- package/dist/Graph/findNodes.d.mts +63 -0
- package/dist/Graph/findNodes.mjs +9 -0
- package/dist/Graph/forEachEdge.d.mts +52 -0
- package/dist/Graph/forEachEdge.mjs +56 -0
- package/dist/Graph/forEachNeighbor.d.mts +52 -0
- package/dist/Graph/forEachNeighbor.mjs +59 -0
- package/dist/Graph/forEachNode.d.mts +49 -0
- package/dist/Graph/forEachNode.mjs +51 -0
- package/dist/Graph/fromJS.d.mts +55 -0
- package/dist/Graph/fromJS.mjs +62 -0
- package/dist/Graph/getEdge.d.mts +50 -0
- package/dist/Graph/getEdge.mjs +54 -0
- package/dist/Graph/getEdges.d.mts +47 -0
- package/dist/Graph/getEdges.mjs +51 -0
- package/dist/Graph/getNeighbor.d.mts +50 -0
- package/dist/Graph/getNeighbor.mjs +56 -0
- package/dist/Graph/getNeighbors.d.mts +47 -0
- package/dist/Graph/getNeighbors.mjs +58 -0
- package/dist/Graph/getNode.d.mts +48 -0
- package/dist/Graph/getNode.mjs +52 -0
- package/dist/Graph/getNodes.d.mts +46 -0
- package/dist/Graph/getNodes.mjs +48 -0
- package/dist/Graph/hasEdge.d.mts +46 -0
- package/dist/Graph/hasEdge.mjs +50 -0
- package/dist/Graph/hasNode.d.mts +42 -0
- package/dist/Graph/hasNode.mjs +46 -0
- package/dist/Graph/index.d.mts +68 -0
- package/dist/Graph/index.mjs +65 -0
- package/dist/Graph/internals/core.mjs +51 -0
- package/dist/Graph/internals/parseNodeIdentifier.mjs +7 -0
- package/dist/Graph/internals/types.d.mts +16 -0
- package/dist/Graph/mapEdge.d.mts +52 -0
- package/dist/Graph/mapEdge.mjs +60 -0
- package/dist/Graph/mapNode.d.mts +65 -0
- package/dist/Graph/mapNode.mjs +83 -0
- package/dist/Graph/mergeEdge.d.mts +52 -0
- package/dist/Graph/mergeEdge.mjs +63 -0
- package/dist/Graph/mergeNode.d.mts +50 -0
- package/dist/Graph/mergeNode.mjs +60 -0
- package/dist/Graph/removeEdge.d.mts +49 -0
- package/dist/Graph/removeEdge.mjs +71 -0
- package/dist/Graph/removeNode.d.mts +46 -0
- package/dist/Graph/removeNode.mjs +71 -0
- package/dist/Graph/setEdge.d.mts +52 -0
- package/dist/Graph/setEdge.mjs +78 -0
- package/dist/Graph/setNode.d.mts +43 -0
- package/dist/Graph/setNode.mjs +50 -0
- package/dist/Graph/toJS.d.mts +59 -0
- package/dist/Graph/toJS.mjs +82 -0
- package/dist/Graph/types.d.mts +29 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +3 -0
- 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 };
|