From 30834c211859e6ddb93eb1ae3808286c8b69cfb3 Mon Sep 17 00:00:00 2001
From: Michael Behrisch <m.behrisch@uu.nl>
Date: Thu, 10 Feb 2022 23:11:40 +0100
Subject: [PATCH] fix(store): :bug: fixes some problems with data loading and
 parsing

---
 .vscode/launch.json                           |  17 +
 .vscode/settings.json                         |   6 +-
 .../src/components/schema/schema.tsx          |  40 ++-
 libs/schema/schema-usecases/src/index.ts      |   2 +-
 .../src/lib/mockdata/moviesSchema.json        |  96 ++++++
 .../src/lib/mockdata/northwindSchema.json     | 284 ++++++++++++++++
 .../src/lib/mockdata/simple.json              | 101 ++++++
 .../src/lib/mockdata/twitterSchema.json       | 313 ++++++++++++++++++
 .../src/lib/schema-schema-usecases.spec.ts    |   7 -
 .../src/lib/schema-schema-usecases.ts         | 221 -------------
 .../src/lib/schema-usecases.spec.ts           |  72 ++++
 .../src/lib/schema-usecases.ts                | 212 ++++++++++++
 libs/schema/schema-usecases/tsconfig.json     |   3 +-
 .../store/src/lib/schemaSlice.spec.ts         |  94 ++++++
 .../data-access/store/src/lib/schemaSlice.ts  |  64 ++--
 package.json                                  |   4 +-
 yarn.lock                                     |  26 +-
 17 files changed, 1271 insertions(+), 291 deletions(-)
 create mode 100644 .vscode/launch.json
 create mode 100644 libs/schema/schema-usecases/src/lib/mockdata/moviesSchema.json
 create mode 100644 libs/schema/schema-usecases/src/lib/mockdata/northwindSchema.json
 create mode 100644 libs/schema/schema-usecases/src/lib/mockdata/simple.json
 create mode 100644 libs/schema/schema-usecases/src/lib/mockdata/twitterSchema.json
 delete mode 100644 libs/schema/schema-usecases/src/lib/schema-schema-usecases.spec.ts
 delete mode 100644 libs/schema/schema-usecases/src/lib/schema-schema-usecases.ts
 create mode 100644 libs/schema/schema-usecases/src/lib/schema-usecases.spec.ts
 create mode 100644 libs/schema/schema-usecases/src/lib/schema-usecases.ts
 create mode 100644 libs/shared/data-access/store/src/lib/schemaSlice.spec.ts

diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 000000000..663259f3f
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,17 @@
+{
+  "configurations": [
+    {
+      "name": "Debug Jest Tests",
+      "type": "node",
+      "request": "launch",
+      "runtimeArgs": [
+        "--inspect-brk",
+        "${workspaceRoot}/node_modules/jest/bin/jest.js",
+        "--runInBand"
+      ],
+      "console": "integratedTerminal",
+      "internalConsoleOptions": "neverOpen",
+      "port": 9229
+    }
+  ]
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 033495ac5..84265c462 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -20,6 +20,8 @@
     "vis-nl",
     "vis-paoh",
     "vis-schema",
-    "storybook"
-  ]
+    "storybook",
+    "store"
+  ],
+  "jest.jestCommandLine": "nx affected:test"
 }
diff --git a/apps/web-graphpolaris/src/components/schema/schema.tsx b/apps/web-graphpolaris/src/components/schema/schema.tsx
index e005a8543..2114a9722 100644
--- a/apps/web-graphpolaris/src/components/schema/schema.tsx
+++ b/apps/web-graphpolaris/src/components/schema/schema.tsx
@@ -1,35 +1,49 @@
 import { useSchema } from '@graphpolaris/shared/data-access/store';
 //import { useEffect } from 'react';
 import ReactFlow from 'react-flow-renderer';
-import styled from 'styled-components';
 import { createReactFlowElements } from '@graphpolaris/schema/schema-usecases';
+import { useEffect, useState } from 'react';
 
 interface Props {
   content: string;
 }
 
-const Div = styled.div`
-  background-color: red;
-  font: 'Arial';
-  width: 300px;
-  height: 600px;
-`;
+const initialElements = [
+  {
+    id: '1',
+    type: 'input',
+    data: { label: 'Input Node' },
+    position: { x: 250, y: 25 },
+  },
+  {
+    id: '2',
+    data: { label: 'Another Node' },
+    position: { x: 100, y: 125 },
+  },
+];
 
 const Schema = (props: Props) => {
   const dbschema = useSchema();
+  // const [dbschema, setSchema] = useState(useSchema());
+
+  // const [flowElements, setFlowElements] = useState(initialElements);
 
   // In case the schema is updated
   // useEffect(() => {
+  //   const flowElements = createReactFlowElements(dbschema);
   //   console.log('update schema useEffect');
   // }, [dbschema]);
 
-  console.log(dbschema);
+  // console.log(dbschema);
   return (
-    <Div>
-      <p>hey</p>
-        <ReactFlow elements={createReactFlowElements(dbschema)} />
-      <p>hoi</p>
-    </Div>
+    <div
+      style={{
+        width: '100%',
+        height: '100%',
+      }}
+    >
+      <ReactFlow elements={createReactFlowElements(dbschema)} />
+    </div>
   );
 };
 
diff --git a/libs/schema/schema-usecases/src/index.ts b/libs/schema/schema-usecases/src/index.ts
index 5d9846859..1aa537795 100644
--- a/libs/schema/schema-usecases/src/index.ts
+++ b/libs/schema/schema-usecases/src/index.ts
@@ -1 +1 @@
-export * from './lib/schema-schema-usecases';
+export * from './lib/schema-usecases';
diff --git a/libs/schema/schema-usecases/src/lib/mockdata/moviesSchema.json b/libs/schema/schema-usecases/src/lib/mockdata/moviesSchema.json
new file mode 100644
index 000000000..00b4bb2ec
--- /dev/null
+++ b/libs/schema/schema-usecases/src/lib/mockdata/moviesSchema.json
@@ -0,0 +1,96 @@
+{
+	"nodes": [
+		{
+			"name": "Movie",
+			"attributes": [
+				{
+					"name": "tagline",
+					"type": "string"
+				},
+				{
+					"name": "title",
+					"type": "string"
+				},
+				{
+					"name": "released",
+					"type": "int"
+				},
+				{
+					"name": "votes",
+					"type": "int"
+				}
+			]
+		},
+		{
+			"name": "Person",
+			"attributes": [
+				{
+					"name": "born",
+					"type": "int"
+				},
+				{
+					"name": "name",
+					"type": "string"
+				}
+			]
+		}
+	],
+	"edges": [
+		{
+			"name": "ACTED_IN",
+			"collection": "ACTED_IN",
+			"from": "Person",
+			"to": "Movie",
+			"attributes": [
+				{
+					"name": "roles",
+					"type": "string"
+				}
+			]
+		},
+		{
+			"name": "REVIEWED",
+			"collection": "REVIEWED",
+			"from": "Person",
+			"to": "Movie",
+			"attributes": [
+				{
+					"name": "summary",
+					"type": "string"
+				},
+				{
+					"name": "rating",
+					"type": "int"
+				}
+			]
+		},
+		{
+			"name": "PRODUCED",
+			"collection": "PRODUCED",
+			"from": "Person",
+			"to": "Movie",
+			"attributes": []
+		},
+		{
+			"name": "WROTE",
+			"collection": "WROTE",
+			"from": "Person",
+			"to": "Movie",
+			"attributes": []
+		},
+		{
+			"name": "FOLLOWS",
+			"collection": "FOLLOWS",
+			"from": "Person",
+			"to": "Person",
+			"attributes": []
+		},
+		{
+			"name": "DIRECTED",
+			"collection": "DIRECTED",
+			"from": "Person",
+			"to": "Movie",
+			"attributes": []
+		}
+	]
+}
\ No newline at end of file
diff --git a/libs/schema/schema-usecases/src/lib/mockdata/northwindSchema.json b/libs/schema/schema-usecases/src/lib/mockdata/northwindSchema.json
new file mode 100644
index 000000000..d3f92c47d
--- /dev/null
+++ b/libs/schema/schema-usecases/src/lib/mockdata/northwindSchema.json
@@ -0,0 +1,284 @@
+{
+	"nodes": [
+		{
+			"name": "Order",
+			"attributes": [
+				{
+					"name": "customerID",
+					"type": "string"
+				},
+				{
+					"name": "shipCity",
+					"type": "string"
+				},
+				{
+					"name": "orderID",
+					"type": "string"
+				},
+				{
+					"name": "freight",
+					"type": "string"
+				},
+				{
+					"name": "requiredDate",
+					"type": "string"
+				},
+				{
+					"name": "employeeID",
+					"type": "string"
+				},
+				{
+					"name": "shipName",
+					"type": "string"
+				},
+				{
+					"name": "shipPostalCode",
+					"type": "string"
+				},
+				{
+					"name": "orderDate",
+					"type": "string"
+				},
+				{
+					"name": "shipRegion",
+					"type": "string"
+				},
+				{
+					"name": "shipCountry",
+					"type": "string"
+				},
+				{
+					"name": "shippedDate",
+					"type": "string"
+				},
+				{
+					"name": "shipVia",
+					"type": "string"
+				},
+				{
+					"name": "shipAddress",
+					"type": "string"
+				}
+			]
+		},
+		{
+			"name": "Category",
+			"attributes": [
+				{
+					"name": "categoryID",
+					"type": "string"
+				},
+				{
+					"name": "description",
+					"type": "string"
+				},
+				{
+					"name": "categoryName",
+					"type": "string"
+				},
+				{
+					"name": "picture",
+					"type": "string"
+				}
+			]
+		},
+		{
+			"name": "Customer",
+			"attributes": [
+				{
+					"name": "country",
+					"type": "string"
+				},
+				{
+					"name": "address",
+					"type": "string"
+				},
+				{
+					"name": "contactTitle",
+					"type": "string"
+				},
+				{
+					"name": "city",
+					"type": "string"
+				},
+				{
+					"name": "phone",
+					"type": "string"
+				},
+				{
+					"name": "contactName",
+					"type": "string"
+				},
+				{
+					"name": "postalCode",
+					"type": "string"
+				},
+				{
+					"name": "companyName",
+					"type": "string"
+				},
+				{
+					"name": "fax",
+					"type": "string"
+				},
+				{
+					"name": "region",
+					"type": "string"
+				},
+				{
+					"name": "customerID",
+					"type": "string"
+				}
+			]
+		},
+		{
+			"name": "Product",
+			"attributes": [
+				{
+					"name": "reorderLevel",
+					"type": "int"
+				},
+				{
+					"name": "unitsInStock",
+					"type": "int"
+				},
+				{
+					"name": "unitPrice",
+					"type": "float"
+				},
+				{
+					"name": "supplierID",
+					"type": "string"
+				},
+				{
+					"name": "productID",
+					"type": "string"
+				},
+				{
+					"name": "discontinued",
+					"type": "bool"
+				},
+				{
+					"name": "quantityPerUnit",
+					"type": "string"
+				},
+				{
+					"name": "categoryID",
+					"type": "string"
+				},
+				{
+					"name": "unitsOnOrder",
+					"type": "int"
+				},
+				{
+					"name": "productName",
+					"type": "string"
+				}
+			]
+		},
+		{
+			"name": "Supplier",
+			"attributes": [
+				{
+					"name": "supplierID",
+					"type": "string"
+				},
+				{
+					"name": "country",
+					"type": "string"
+				},
+				{
+					"name": "address",
+					"type": "string"
+				},
+				{
+					"name": "contactTitle",
+					"type": "string"
+				},
+				{
+					"name": "city",
+					"type": "string"
+				},
+				{
+					"name": "phone",
+					"type": "string"
+				},
+				{
+					"name": "contactName",
+					"type": "string"
+				},
+				{
+					"name": "postalCode",
+					"type": "string"
+				},
+				{
+					"name": "companyName",
+					"type": "string"
+				},
+				{
+					"name": "fax",
+					"type": "string"
+				},
+				{
+					"name": "region",
+					"type": "string"
+				},
+				{
+					"name": "homePage",
+					"type": "string"
+				}
+			]
+		}
+	],
+	"edges": [
+		{
+			"name": "ORDERS",
+			"collection": "ORDERS",
+			"from": "Order",
+			"to": "Product",
+			"attributes": [
+				{
+					"name": "unitPrice",
+					"type": "string"
+				},
+				{
+					"name": "productID",
+					"type": "string"
+				},
+				{
+					"name": "orderID",
+					"type": "string"
+				},
+				{
+					"name": "discount",
+					"type": "string"
+				},
+				{
+					"name": "quantity",
+					"type": "int"
+				}
+			]
+		},
+		{
+			"name": "PART_OF",
+			"collection": "PART_OF",
+			"from": "Product",
+			"to": "Category",
+			"attributes": []
+		},
+		{
+			"name": "SUPPLIES",
+			"collection": "SUPPLIES",
+			"from": "Supplier",
+			"to": "Product",
+			"attributes": []
+		},
+		{
+			"name": "PURCHASED",
+			"collection": "PURCHASED",
+			"from": "Customer",
+			"to": "Order",
+			"attributes": []
+		}
+	]
+}
\ No newline at end of file
diff --git a/libs/schema/schema-usecases/src/lib/mockdata/simple.json b/libs/schema/schema-usecases/src/lib/mockdata/simple.json
new file mode 100644
index 000000000..826dbe483
--- /dev/null
+++ b/libs/schema/schema-usecases/src/lib/mockdata/simple.json
@@ -0,0 +1,101 @@
+{
+  "nodes": [
+    {
+      "name": "Thijs",
+      "attributes": []
+    },
+    {
+      "name": "Airport",
+      "attributes": [
+        { "name": "city", "type": "string" },
+        { "name": "vip", "type": "bool" },
+        { "name": "state", "type": "string" }
+      ]
+    },
+    {
+      "name": "Airport2",
+      "attributes": [
+        { "name": "city", "type": "string" },
+        { "name": "vip", "type": "bool" },
+        { "name": "state", "type": "string" }
+      ]
+    },
+    {
+      "name": "Plane",
+      "attributes": [
+        { "name": "type", "type": "string" },
+        { "name": "maxFuelCapacity", "type": "int" }
+      ]
+    },
+    { "name": "Staff", "attributes": [] }
+  ],
+  "edges": [
+    {
+      "name": "Airport2:Airport",
+      "from": "Airport2",
+      "to": "Airport",
+      "collection": "flights",
+      "attributes": [
+        { "name": "arrivalTime", "type": "int" },
+        { "name": "departureTime", "type": "int" }
+      ]
+    },
+    {
+      "name": "Airport:Staff",
+      "from": "Airport",
+      "to": "Staff",
+      "collection": "flights",
+      "attributes": [{ "name": "salary", "type": "int" }]
+    },
+    {
+      "name": "Plane:Airport",
+      "from": "Plane",
+      "to": "Airport",
+      "collection": "flights",
+      "attributes": []
+    },
+    {
+      "name": "Airport:Thijs",
+      "from": "Airport",
+      "to": "Thijs",
+      "collection": "flights",
+      "attributes": [{ "name": "hallo", "type": "string" }]
+    },
+    {
+      "name": "Thijs:Airport",
+      "from": "Thijs",
+      "to": "Airport",
+      "collection": "flights",
+      "attributes": [{ "name": "hallo", "type": "string" }]
+    },
+    {
+      "name": "Staff:Plane",
+      "from": "Staff",
+      "to": "Plane",
+      "collection": "flights",
+      "attributes": [{ "name": "hallo", "type": "string" }]
+    },
+    {
+      "name": "Staff:Airport2",
+      "from": "Staff",
+      "to": "Airport2",
+      "collection": "flights",
+      "attributes": [{ "name": "hallo", "type": "string" }]
+    },
+    {
+      "name": "Airport2:Plane",
+      "from": "Airport2",
+      "to": "Plane",
+      "collection": "flights",
+      "attributes": [{ "name": "hallo", "type": "string" }]
+    },
+
+    {
+      "name": "Airport:Airport",
+      "from": "Airport",
+      "to": "Airport",
+      "collection": "flights",
+      "attributes": [{ "name": "test", "type": "string" }]
+    }
+  ]
+}
diff --git a/libs/schema/schema-usecases/src/lib/mockdata/twitterSchema.json b/libs/schema/schema-usecases/src/lib/mockdata/twitterSchema.json
new file mode 100644
index 000000000..2ec7e5fb9
--- /dev/null
+++ b/libs/schema/schema-usecases/src/lib/mockdata/twitterSchema.json
@@ -0,0 +1,313 @@
+{
+	"nodes": [
+		{
+			"name": "Me",
+			"attributes": [
+				{
+					"name": "screen_name",
+					"type": "string"
+				},
+				{
+					"name": "name",
+					"type": "string"
+				},
+				{
+					"name": "location",
+					"type": "string"
+				},
+				{
+					"name": "followers",
+					"type": "int"
+				},
+				{
+					"name": "following",
+					"type": "int"
+				},
+				{
+					"name": "url",
+					"type": "string"
+				},
+				{
+					"name": "profile_image_url",
+					"type": "string"
+				}
+			]
+		},
+		{
+			"name": "Link",
+			"attributes": [
+				{
+					"name": "url",
+					"type": "string"
+				}
+			]
+		},
+		{
+			"name": "Source",
+			"attributes": [
+				{
+					"name": "name",
+					"type": "string"
+				}
+			]
+		},
+		{
+			"name": "Hashtag",
+			"attributes": [
+				{
+					"name": "name",
+					"type": "string"
+				}
+			]
+		},
+		{
+			"name": "User",
+			"attributes": [
+				{
+					"name": "screen_name",
+					"type": "string"
+				},
+				{
+					"name": "name",
+					"type": "string"
+				},
+				{
+					"name": "location",
+					"type": "string"
+				},
+				{
+					"name": "followers",
+					"type": "int"
+				},
+				{
+					"name": "following",
+					"type": "int"
+				},
+				{
+					"name": "url",
+					"type": "string"
+				},
+				{
+					"name": "profile_image_url",
+					"type": "string"
+				},
+				{
+					"name": "screen_name",
+					"type": "string"
+				},
+				{
+					"name": "name",
+					"type": "string"
+				},
+				{
+					"name": "location",
+					"type": "string"
+				},
+				{
+					"name": "followers",
+					"type": "int"
+				},
+				{
+					"name": "following",
+					"type": "int"
+				},
+				{
+					"name": "statuses",
+					"type": "int"
+				},
+				{
+					"name": "url",
+					"type": "string"
+				},
+				{
+					"name": "profile_image_url",
+					"type": "string"
+				}
+			]
+		},
+		{
+			"name": "Tweet",
+			"attributes": [
+				{
+					"name": "id",
+					"type": "int"
+				},
+				{
+					"name": "id_str",
+					"type": "string"
+				},
+				{
+					"name": "text",
+					"type": "string"
+				},
+				{
+					"name": "favorites",
+					"type": "int"
+				},
+				{
+					"name": "import_method",
+					"type": "string"
+				}
+			]
+		}
+	],
+	"edges": [
+		{
+			"name": "USING",
+			"collection": "USING",
+			"from": "Tweet",
+			"to": "Source",
+			"attributes": []
+		},
+		{
+			"name": "SIMILAR_TO",
+			"collection": "SIMILAR_TO",
+			"from": "User",
+			"to": "User",
+			"attributes": [
+				{
+					"name": "score",
+					"type": "float"
+				}
+			]
+		},
+		{
+			"name": "SIMILAR_TO",
+			"collection": "SIMILAR_TO",
+			"from": "User",
+			"to": "Me",
+			"attributes": [
+				{
+					"name": "score",
+					"type": "float"
+				}
+			]
+		},
+		{
+			"name": "AMPLIFIES",
+			"collection": "AMPLIFIES",
+			"from": "Me",
+			"to": "User",
+			"attributes": []
+		},
+		{
+			"name": "AMPLIFIES",
+			"collection": "AMPLIFIES",
+			"from": "User",
+			"to": "User",
+			"attributes": []
+		},
+		{
+			"name": "RT_MENTIONS",
+			"collection": "RT_MENTIONS",
+			"from": "Me",
+			"to": "User",
+			"attributes": []
+		},
+		{
+			"name": "RT_MENTIONS",
+			"collection": "RT_MENTIONS",
+			"from": "User",
+			"to": "User",
+			"attributes": []
+		},
+		{
+			"name": "FOLLOWS",
+			"collection": "FOLLOWS",
+			"from": "User",
+			"to": "Me",
+			"attributes": []
+		},
+		{
+			"name": "FOLLOWS",
+			"collection": "FOLLOWS",
+			"from": "Me",
+			"to": "User",
+			"attributes": []
+		},
+		{
+			"name": "FOLLOWS",
+			"collection": "FOLLOWS",
+			"from": "User",
+			"to": "User",
+			"attributes": []
+		},
+		{
+			"name": "FOLLOWS",
+			"collection": "FOLLOWS",
+			"from": "Me",
+			"to": "Me",
+			"attributes": []
+		},
+		{
+			"name": "INTERACTS_WITH",
+			"collection": "INTERACTS_WITH",
+			"from": "User",
+			"to": "User",
+			"attributes": []
+		},
+		{
+			"name": "INTERACTS_WITH",
+			"collection": "INTERACTS_WITH",
+			"from": "Me",
+			"to": "User",
+			"attributes": []
+		},
+		{
+			"name": "RETWEETS",
+			"collection": "RETWEETS",
+			"from": "Tweet",
+			"to": "Tweet",
+			"attributes": []
+		},
+		{
+			"name": "REPLY_TO",
+			"collection": "REPLY_TO",
+			"from": "Tweet",
+			"to": "Tweet",
+			"attributes": []
+		},
+		{
+			"name": "CONTAINS",
+			"collection": "CONTAINS",
+			"from": "Tweet",
+			"to": "Link",
+			"attributes": []
+		},
+		{
+			"name": "MENTIONS",
+			"collection": "MENTIONS",
+			"from": "Tweet",
+			"to": "User",
+			"attributes": []
+		},
+		{
+			"name": "MENTIONS",
+			"collection": "MENTIONS",
+			"from": "Tweet",
+			"to": "Me",
+			"attributes": []
+		},
+		{
+			"name": "TAGS",
+			"collection": "TAGS",
+			"from": "Tweet",
+			"to": "Hashtag",
+			"attributes": []
+		},
+		{
+			"name": "POSTS",
+			"collection": "POSTS",
+			"from": "User",
+			"to": "Tweet",
+			"attributes": []
+		},
+		{
+			"name": "POSTS",
+			"collection": "POSTS",
+			"from": "Me",
+			"to": "Tweet",
+			"attributes": []
+		}
+	]
+}
\ No newline at end of file
diff --git a/libs/schema/schema-usecases/src/lib/schema-schema-usecases.spec.ts b/libs/schema/schema-usecases/src/lib/schema-schema-usecases.spec.ts
deleted file mode 100644
index f2130094e..000000000
--- a/libs/schema/schema-usecases/src/lib/schema-schema-usecases.spec.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-import { schemaSchemaUsecases } from './schema-schema-usecases';
-
-describe('schemaSchemaUsecases', () => {
-  it('should work', () => {
-    expect(schemaSchemaUsecases()).toEqual('schema-schema-usecases');
-  });
-});
diff --git a/libs/schema/schema-usecases/src/lib/schema-schema-usecases.ts b/libs/schema/schema-usecases/src/lib/schema-schema-usecases.ts
deleted file mode 100644
index e12f733f0..000000000
--- a/libs/schema/schema-usecases/src/lib/schema-schema-usecases.ts
+++ /dev/null
@@ -1,221 +0,0 @@
-import Graph from 'graphology';
-import cytoscape from 'cytoscape'; // eslint-disable-line
-import { setSchema, store } from '@graphpolaris/shared/data-access/store';
-import { Elements, Node, Edge } from 'react-flow-renderer';
-import { SchemaFromBackend } from '@graphpolaris/shared/data-access/store';
-
-type CytoNode = {
-  data: {
-    id: string;
-    type: string;
-    source?: string;
-    target?: string;
-    position?: {
-      x: number;
-      y: number;
-    };
-  };
-};
-
-// Layouts a given schema
-export function handleSchemaLayout(graph: Graph): void {
-  const layout = createSchemaLayout(graph);
-
-  layout.then((cy) => {
-    //cy.cy.elements().forEach((elem) => {
-    cy.cy.nodes().forEach((elem) => {
-      const position = elem.position();
-      console.log(elem.id());
-
-      graph.setNodeAttribute(elem.id(), 'x', position.x);
-      graph.setNodeAttribute(elem.id(), 'y', position.y);
-    });
-
-    store.dispatch(setSchema(graph));
-  });
-}
-
-// Creates a schema layout (async)
-function createSchemaLayout(graph: Graph): Promise<cytoscape.EventObject> {
-  const cytonodes: CytoNode[] = trimSchema(graph);
-
-  const cy = cytoscape({
-    elements: cytonodes,
-  });
-
-  const options = {
-    name: 'cose',
-
-    // Whether to animate while running the layout
-    // true : Animate continuously as the layout is running
-    // false : Just show the end result
-    // 'end' : Animate with the end result, from the initial positions to the end positions
-    animate: true,
-
-    // Easing of the animation for animate:'end'
-    animationEasing: undefined,
-
-    // The duration of the animation for animate:'end'
-    animationDuration: undefined,
-
-    // A function that determines whether the node should be animated
-    // All nodes animated by default on animate enabled
-    // Non-animated nodes are positioned immediately when the layout starts
-    // animateFilter: function (node: any, i: any) {
-    //   return true;
-    // },
-
-    // The layout animates only after this many milliseconds for animate:true
-    // (prevents flashing on fast runs)
-    animationThreshold: 250,
-
-    // Number of iterations between consecutive screen positions update
-    refresh: 20,
-
-    // Whether to fit the network view after when done
-    fit: true,
-
-    // Padding on fit
-    padding: 30,
-
-    // Constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
-    boundingBox: undefined,
-
-    // Excludes the label when calculating node bounding boxes for the layout algorithm
-    nodeDimensionsIncludeLabels: false,
-
-    // Randomize the initial positions of the nodes (true) or use existing positions (false)
-    randomize: false,
-
-    // Extra spacing between components in non-compound graphs
-    componentSpacing: 200, // 40
-
-    // Node repulsion (non overlapping) multiplier
-    nodeRepulsion: function (node: any) {
-      return 2048;
-    },
-
-    // Node repulsion (overlapping) multiplier
-    nodeOverlap: 4,
-
-    // Ideal edge (non nested) length
-    idealEdgeLength: function (edge: any) {
-      return 32;
-    },
-
-    // Divisor to compute edge forces
-    edgeElasticity: function (edge: any) {
-      return 32;
-    },
-
-    // Nesting factor (multiplier) to compute ideal edge length for nested edges
-    nestingFactor: 1.2,
-
-    // Gravity force (constant)
-    gravity: 1,
-
-    // Maximum number of iterations to perform
-    numIter: 1000,
-
-    // Initial temperature (maximum node displacement)
-    initialTemp: 1000,
-
-    // Cooling factor (how the temperature is reduced between consecutive iterations
-    coolingFactor: 0.99,
-
-    // Lower temperature threshold (below this point the layout will end)
-    minTemp: 1.0,
-  };
-
-  const layout = cy.layout(options);
-
-  layout.run();
-
-  return layout.pon('layoutstop');
-}
-
-// Takes the schema as input and creates a list of nodes and edges in a format that the layouting algorithm can use.
-function trimSchema(graph: Graph): CytoNode[] {
-  const cytonodes: CytoNode[] = [];
-
-  graph.forEachNode((node) => {
-    cytonodes.push({
-      data: { id: node, type: 'node' },
-    });
-  });
-
-  graph.forEachEdge((edge, _attributes, source, target) => {
-    cytonodes.push({
-      data: { id: edge, type: 'edge', source: source, target: target },
-    });
-  });
-
-  return cytonodes;
-}
-
-// Takes the schema as an imput and creates basic react flow elements for them.
-export function createReactFlowElements(graph: Graph): Elements<Node | Edge> {
-  const initialElements: Elements<Node | Edge> = [];
-
-  graph.forEachNode((node, attributes) => {
-    const newNode: Node = {
-      id: node,
-      data: {
-        label: attributes.name,
-      },
-      position: { x: attributes.x, y: attributes.y },
-    };
-    initialElements.push(newNode);
-  });
-
-  graph.forEachEdge((edge, _attributes, source, target) => {
-    const newEdge: Edge = {
-      id: edge,
-      source: source,
-      target: target,
-    };
-    initialElements.push(newEdge);
-  });
-
-  return initialElements;
-}
-
-export function parseSchemaFromBackend(
-  schemaFromBackend: SchemaFromBackend
-): Graph {
-  const { nodes, edges } = schemaFromBackend;
-  // Instantiate a directed graph that allows self loops and parallel edges
-  const schema = new Graph({ allowSelfLoops: true, multi: true });
-  console.log('Updating schema');
-  // The graph schema needs a node for each node AND edge. These need then be connected
-
-  nodes.forEach((node) => {
-    schema.addNode(node.name, {
-      name: node.name,
-      attributes: node.attributes,
-      x: 0,
-      y: 0,
-    });
-  });
-
-  // The name of the edge will be name + from + to, since edge names are not unique
-  edges.forEach((edge) => {
-    const edgeID = edge.name + edge.from + edge.to;
-
-    // This node is the actual edge
-    schema.addNode(edgeID, {
-      name: edge.name,
-      attributes: edge.attributes,
-      from: edge.from,
-      to: edge.to,
-      collection: edge.collection,
-      x: 0,
-      y: 0,
-    });
-
-    // These lines are simply for keeping the schema together
-    schema.addDirectedEdgeWithKey(edgeID + 'f', edge.from, edgeID);
-    schema.addDirectedEdgeWithKey(edgeID + 't', edgeID, edge.to);
-  });
-  return schema;
-}
diff --git a/libs/schema/schema-usecases/src/lib/schema-usecases.spec.ts b/libs/schema/schema-usecases/src/lib/schema-usecases.spec.ts
new file mode 100644
index 000000000..de75d0433
--- /dev/null
+++ b/libs/schema/schema-usecases/src/lib/schema-usecases.spec.ts
@@ -0,0 +1,72 @@
+import { SchemaFromBackend } from '@graphpolaris/shared/data-access/store';
+import { MultiGraph } from 'graphology';
+import { parse } from 'path/posix';
+import { parseSchemaFromBackend } from '..';
+import * as simpleSchema from './mockdata/simple.json';
+import * as moviewSchema from './mockdata/moviesSchema.json';
+import * as northwindSchema from './mockdata/northwindSchema.json';
+import * as twitterSchema from './mockdata/twitterSchema.json';
+import { Attributes } from 'graphology-types';
+
+describe('SchemaUsecases', () => {
+  test.each([
+    { data: simpleSchema },
+    { data: moviewSchema },
+    { data: northwindSchema },
+    { data: twitterSchema },
+  ])('parseSchemaFromBackend parsing should work', ({ data }) => {
+    // console.log('testinput', input);
+
+    const parsed = parseSchemaFromBackend(data as SchemaFromBackend);
+    expect(parsed).toBeDefined();
+
+    let parsedNodeAttributes: Attributes[] = []; 
+    parsed.forEachNode((node, attr) => {
+      // console.log('Node', node, attr);
+      parsedNodeAttributes.push(attr.attributes);
+    });
+
+    let parsedEdgeAttributes: Attributes = [];
+    parsed.forEachEdge((edge, attr, source, target, sa, ta, undirected) => {
+      // console.log('Edge', edge, attr, source, target, sa, ta, undirected);
+      parsedEdgeAttributes.push(attr.attribute);
+    });
+
+    expect(data.nodes.length).toEqual(parsed.order);
+    expect(data.edges.length).toEqual(parsed.size);
+
+    let inputNodeAttributes: Attributes = [];
+    data.nodes.forEach((node) => {
+      inputNodeAttributes.push(node.attributes as Attributes);
+    });
+
+    let inputEdgeAttributes: Attributes = [];
+    data.edges.forEach((edge) => {
+      inputEdgeAttributes.push(edge.attributes as Attributes);
+    });
+
+    expect(inputNodeAttributes).toEqual(parsedNodeAttributes);
+    expect(inputEdgeAttributes).toEqual(parsedEdgeAttributes);
+  });
+
+  it('should export and reimport', () => {
+    const parsed = parseSchemaFromBackend(simpleSchema as SchemaFromBackend);
+    const reload = MultiGraph.from(parsed.export());
+
+    expect(parsed).toStrictEqual(reload);
+  });
+
+  test.each([
+    //     import * as simpleSchema from './mockdata/simple.json';
+    // import * as moviewSchema from './mockdata/moviesSchema.json';
+    // import * as northwindSchema from './mockdata/northwindSchema.json';
+    // import * as twitterSchema from './mockdata/twitterSchema.json';
+    { data: simpleSchema },
+    { data: moviewSchema },
+    { data: northwindSchema },
+    { data: twitterSchema },
+  ])('should load my test json $data', ({ data }) => {
+    expect(data).toBeDefined();
+    expect(data.nodes).toBeDefined();
+  });
+});
diff --git a/libs/schema/schema-usecases/src/lib/schema-usecases.ts b/libs/schema/schema-usecases/src/lib/schema-usecases.ts
new file mode 100644
index 000000000..ea3fdc0fa
--- /dev/null
+++ b/libs/schema/schema-usecases/src/lib/schema-usecases.ts
@@ -0,0 +1,212 @@
+import Graph, { MultiGraph } from 'graphology';
+// import cytoscape from 'cytoscape'; // eslint-disable-line
+import { setSchema, store } from '@graphpolaris/shared/data-access/store';
+import { Elements, Node, Edge } from 'react-flow-renderer';
+import { SchemaFromBackend } from '@graphpolaris/shared/data-access/store';
+import { Attributes } from 'graphology-types';
+
+type CytoNode = {
+  data: {
+    id: string;
+    type: string;
+    source?: string;
+    target?: string;
+    position?: {
+      x: number;
+      y: number;
+    };
+  };
+};
+
+// // Layouts a given schema
+// export function handleSchemaLayout(graph: Graph): void {
+//   const layout = createSchemaLayout(graph);
+
+//   layout.then((cy) => {
+//     //cy.cy.elements().forEach((elem) => {
+//     cy.cy.nodes().forEach((elem: any) => {
+//       const position = elem.position();
+//       console.log(elem.id());
+
+//       graph.setNodeAttribute(elem.id(), 'x', position.x);
+//       graph.setNodeAttribute(elem.id(), 'y', position.y);
+//     });
+
+//     store.dispatch(setSchema(graph));
+//   });
+// }
+
+// // Creates a schema layout (async)
+// function createSchemaLayout(graph: Graph): Promise<cytoscape.EventObject> {
+//   const cytonodes: CytoNode[] = trimSchema(graph);
+
+//   const cy = cytoscape({
+//     elements: cytonodes,
+//   });
+
+//   const options = {
+//     name: 'cose',
+
+//     // Whether to animate while running the layout
+//     // true : Animate continuously as the layout is running
+//     // false : Just show the end result
+//     // 'end' : Animate with the end result, from the initial positions to the end positions
+//     animate: true,
+
+//     // Easing of the animation for animate:'end'
+//     animationEasing: undefined,
+
+//     // The duration of the animation for animate:'end'
+//     animationDuration: undefined,
+
+//     // A function that determines whether the node should be animated
+//     // All nodes animated by default on animate enabled
+//     // Non-animated nodes are positioned immediately when the layout starts
+//     // animateFilter: function (node: any, i: any) {
+//     //   return true;
+//     // },
+
+//     // The layout animates only after this many milliseconds for animate:true
+//     // (prevents flashing on fast runs)
+//     animationThreshold: 250,
+
+//     // Number of iterations between consecutive screen positions update
+//     refresh: 20,
+
+//     // Whether to fit the network view after when done
+//     fit: true,
+
+//     // Padding on fit
+//     padding: 30,
+
+//     // Constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
+//     boundingBox: undefined,
+
+//     // Excludes the label when calculating node bounding boxes for the layout algorithm
+//     nodeDimensionsIncludeLabels: false,
+
+//     // Randomize the initial positions of the nodes (true) or use existing positions (false)
+//     randomize: false,
+
+//     // Extra spacing between components in non-compound graphs
+//     componentSpacing: 200, // 40
+
+//     // Node repulsion (non overlapping) multiplier
+//     nodeRepulsion: function (node: any) {
+//       return 2048;
+//     },
+
+//     // Node repulsion (overlapping) multiplier
+//     nodeOverlap: 4,
+
+//     // Ideal edge (non nested) length
+//     idealEdgeLength: function (edge: any) {
+//       return 32;
+//     },
+
+//     // Divisor to compute edge forces
+//     edgeElasticity: function (edge: any) {
+//       return 32;
+//     },
+
+//     // Nesting factor (multiplier) to compute ideal edge length for nested edges
+//     nestingFactor: 1.2,
+
+//     // Gravity force (constant)
+//     gravity: 1,
+
+//     // Maximum number of iterations to perform
+//     numIter: 1000,
+
+//     // Initial temperature (maximum node displacement)
+//     initialTemp: 1000,
+
+//     // Cooling factor (how the temperature is reduced between consecutive iterations
+//     coolingFactor: 0.99,
+
+//     // Lower temperature threshold (below this point the layout will end)
+//     minTemp: 1.0,
+//   };
+
+//   const layout = cy.layout(options);
+
+//   layout.run();
+
+//   return layout.pon('layoutstop');
+// }
+
+// Takes the schema as input and creates a list of nodes and edges in a format that the layouting algorithm can use.
+function trimSchema(graph: Graph): CytoNode[] {
+  const cytonodes: CytoNode[] = [];
+
+  graph.forEachNode((node) => {
+    cytonodes.push({
+      data: { id: node, type: 'node' },
+    });
+  });
+
+  graph.forEachEdge((edge, _attributes, source, target) => {
+    cytonodes.push({
+      data: { id: edge, type: 'edge', source: source, target: target },
+    });
+  });
+
+  return cytonodes;
+}
+
+// Takes the schema as an imput and creates basic react flow elements for them.
+export function createReactFlowElements(graph: Graph): Elements<Node | Edge> {
+  const initialElements: Elements<Node | Edge> = [];
+
+  graph.forEachNode((node: string, attributes: Attributes): void => {
+    const newNode: Node = {
+      id: node,
+      data: {
+        label: attributes.name,
+      },
+      position: { x: attributes.x, y: attributes.y },
+    };
+    initialElements.push(newNode);
+  });
+
+  graph.forEachEdge((edge, _attributes, source, target): void => {
+    const newEdge: Edge = {
+      id: edge,
+      source: source,
+      target: target,
+    };
+    initialElements.push(newEdge);
+  });
+
+  return initialElements;
+}
+
+export function parseSchemaFromBackend(
+  schemaFromBackend: SchemaFromBackend
+): Graph {
+  const { nodes, edges } = schemaFromBackend;
+  // Instantiate a directed graph that allows self loops and parallel edges
+  const schemaGraph = new MultiGraph({ allowSelfLoops: true });
+  // console.log('parsing schema');
+  // The graph schema needs a node for each node AND edge. These need then be connected
+
+  nodes.forEach((node) => {
+    schemaGraph.addNode(node.name, {
+      name: node.name,
+      attributes: node.attributes,
+      x: 0,
+      y: 0,
+    });
+  });
+
+  // The name of the edge will be name + from + to, since edge names are not unique
+  edges.forEach((edge) => {
+    const edgeID = [edge.name, '_', edge.from, edge.to].join(''); //ensure that all interpreted as string
+
+    // This node is the actual edge
+    schemaGraph.addDirectedEdgeWithKey(edgeID, edge.from, edge.to, {
+      attribute: edge.attributes,
+    });
+  });
+  return schemaGraph;
+}
diff --git a/libs/schema/schema-usecases/tsconfig.json b/libs/schema/schema-usecases/tsconfig.json
index 355f7fda9..6ebadfb9d 100644
--- a/libs/schema/schema-usecases/tsconfig.json
+++ b/libs/schema/schema-usecases/tsconfig.json
@@ -14,6 +14,7 @@
     "forceConsistentCasingInFileNames": true,
     "strict": true,
     "noImplicitReturns": true,
-    "noFallthroughCasesInSwitch": true
+    "noFallthroughCasesInSwitch": true,
+    "resolveJsonModule": true
   }
 }
diff --git a/libs/shared/data-access/store/src/lib/schemaSlice.spec.ts b/libs/shared/data-access/store/src/lib/schemaSlice.spec.ts
new file mode 100644
index 000000000..3a6b17a52
--- /dev/null
+++ b/libs/shared/data-access/store/src/lib/schemaSlice.spec.ts
@@ -0,0 +1,94 @@
+import Graph from 'graphology';
+import AbstractGraph, { DirectedGraph, MultiGraph } from 'graphology';
+import { useSchema } from '..';
+import reducer, { selectSchema, setSchema, initialState } from './schemaSlice';
+// import { deleteBook, updateBook, addNewBook } from '../redux/bookSlice';
+import { store } from './store';
+
+describe('SchemaSlice Tests', () => {
+  it('should make a graphology graph', () => {
+    const graph = new MultiGraph({ allowSelfLoops: true });
+    expect(graph);
+
+    const graph2 = new MultiGraph();
+    expect(graph2);
+
+    const exported = graph.export();
+    expect(exported);
+  });
+
+  it('export and reimport equality check for graphology graph', () => {
+    const graph = new MultiGraph({ allowSelfLoops: true });
+    expect(graph);
+    const exported = graph.export();
+    expect(exported);
+
+    const graphReloaded = MultiGraph.from(exported);
+    expect(graphReloaded).toStrictEqual(graph);
+  });
+
+  it('get the initial state', () => {
+    expect(initialState);
+  });
+
+  it('should return the initial state', () => {
+    let state = store.getState();
+
+    const schema = state.schema;
+    expect(schema);
+
+    const graph = MultiGraph.from(schema.graphologySerialized);
+
+    // console.log(graph);
+    // console.log(initialState);
+    expect(graph);
+  });
+
+  //   it('should handle a todo being added to an empty list', () => {
+  //     let state = store.getState().schema;
+  //     let schema = useSchema();
+
+  //     // const unchangedBook = state.bookList.find((book) => book.id === '1');
+  //     // expect(unchangedBook?.title).toBe('1984');
+  //     // expect(unchangedBook?.author).toBe('George Orwell');
+
+  //     // store.dispatch(updateBook({ id: '1', title: '1985', author: 'George Bush' }));
+  //     // state = store.getState().book;
+  //     // let changeBook = state.bookList.find((book) => book.id === '1');
+  //     // expect(changeBook?.title).toBe('1985');
+  //     // expect(changeBook?.author).toBe('George Bush');
+
+  //     // store.dispatch(
+  //     //     updateBook({ id: '1', title: '1984', author: 'George Orwell' })
+  //     // );
+  //     // state = store.getState().book;
+  //     // const backToUnchangedBook = state.bookList.find((book) => book.id === '1');
+
+  //     // expect(backToUnchangedBook).toEqual(unchangedBook);
+  //     // ]);
+  //   });
+});
+
+// test('Deletes a book from list with id', () => {
+//   let state = store.getState().book;
+//   const initialBookCount = state.bookList.length;
+
+//   store.dispatch(deleteBook({ id: '1' }));
+//   state = store.getState().book;
+
+//   expect(state.bookList.length).toBeLessThan(initialBookCount); // Checking if new length smaller than inital length, which is 3
+// });
+
+// test('Adds a new book', () => {
+//   let state = store.getState().book;
+//   const initialBookCount = state.bookList.length;
+
+//   store.dispatch(
+//     addNewBook({ id: '4', author: 'Tester', title: 'Testers manual' })
+//   );
+//   state = store.getState().book;
+//   const newlyAddedBook = state.bookList.find((book) => book.id === '4');
+//   expect(newlyAddedBook?.author).toBe('Tester');
+//   expect(newlyAddedBook?.title).toBe('Testers manual');
+//   expect(state.bookList.length).toBeGreaterThan(initialBookCount);
+// });
diff --git a/libs/shared/data-access/store/src/lib/schemaSlice.ts b/libs/shared/data-access/store/src/lib/schemaSlice.ts
index b44303d1c..eb8fdb562 100644
--- a/libs/shared/data-access/store/src/lib/schemaSlice.ts
+++ b/libs/shared/data-access/store/src/lib/schemaSlice.ts
@@ -1,6 +1,6 @@
 import { createSlice, PayloadAction } from '@reduxjs/toolkit';
 import type { RootState } from './store';
-import Graph from 'graphology';
+import Graph, { MultiGraph } from 'graphology';
 
 /*************** schema format from the backend *************** */
 // TODO: should probably not live here
@@ -34,7 +34,7 @@ export type Edge = {
 
 // Define the initial state using that type
 export const initialState = {
-  graphologySerialized: new Graph().export(),
+  graphologySerialized: new MultiGraph().export(),
 };
 
 export const schemaSlice = createSlice({
@@ -43,6 +43,8 @@ export const schemaSlice = createSlice({
   initialState,
   reducers: {
     setSchema: (state, action: PayloadAction<Graph>) => {
+      console.log('setSchema', action);
+
       state.graphologySerialized = action.payload.export();
     },
 
@@ -52,38 +54,38 @@ export const schemaSlice = createSlice({
     ) => {
       const { nodes, edges } = action.payload;
       // Instantiate a directed graph that allows self loops and parallel edges
-      const schema = new Graph({ allowSelfLoops: true, multi: true });
+      const schema = new MultiGraph({ allowSelfLoops: true });
       console.log('Updating schema');
       // The graph schema needs a node for each node AND edge. These need then be connected
 
-      nodes.forEach((node) => {
-        schema.addNode(node.name, {
-          name: node.name,
-          attributes: node.attributes,
-          x: 0,
-          y: 0,
-        });
-      });
-
-      // The name of the edge will be name + from + to, since edge names are not unique
-      edges.forEach((edge) => {
-        const edgeID = edge.name + edge.from + edge.to;
-
-        // This node is the actual edge
-        schema.addNode(edgeID, {
-          name: edge.name,
-          attributes: edge.attributes,
-          from: edge.from,
-          to: edge.to,
-          collection: edge.collection,
-          x: 0,
-          y: 0,
-        });
-
-        // These lines are simply for keeping the schema together
-        schema.addDirectedEdgeWithKey(edgeID + 'f', edge.from, edgeID);
-        schema.addDirectedEdgeWithKey(edgeID + 't', edgeID, edge.to);
-      });
+      // nodes.forEach((node) => {
+      //   schema.addNode(node.name, {
+      //     name: node.name,
+      //     attributes: node.attributes,
+      //     x: 0,
+      //     y: 0,
+      //   });
+      // });
+
+      // // The name of the edge will be name + from + to, since edge names are not unique
+      // edges.forEach((edge) => {
+      //   const edgeID = edge.name + edge.from + edge.to;
+
+      //   // This node is the actual edge
+      //   schema.addNode(edgeID, {
+      //     name: edge.name,
+      //     attributes: edge.attributes,
+      //     from: edge.from,
+      //     to: edge.to,
+      //     collection: edge.collection,
+      //     x: 0,
+      //     y: 0,
+      //   });
+
+      //   // These lines are simply for keeping the schema together
+      //   schema.addDirectedEdgeWithKey(edgeID + 'f', edge.from, edgeID);
+      //   schema.addDirectedEdgeWithKey(edgeID + 't', edgeID, edge.to);
+      // });
 
       state.graphologySerialized = schema.export();
     },
diff --git a/package.json b/package.json
index d8191b152..efd91bb4a 100644
--- a/package.json
+++ b/package.json
@@ -21,8 +21,8 @@
     "@types/styled-components": "^5.1.21",
     "core-js": "^3.6.5",
     "cytoscape": "^3.21.0",
-    "graphology": "^0.23.2",
-    "graphology-types": "^0.23.0",
+    "graphology": "^0.24.0",
+    "graphology-types": "^0.24.0",
     "react": "17.0.2",
     "react-dom": "17.0.2",
     "react-flow-renderer": "^9.7.4",
diff --git a/yarn.lock b/yarn.lock
index 4b4bf132a..1f11be6a3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -9634,18 +9634,18 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6
   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
   integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
 
-graphology-types@^0.23.0:
-  version "0.23.0"
-  resolved "https://registry.yarnpkg.com/graphology-types/-/graphology-types-0.23.0.tgz#76a0564baf31891044a7b0cc6cd028810541bb7a"
-  integrity sha512-6Je1NWU3el7YmybAhRzrOEi79Blhx05EU3wGUCvP5ikaxRXEflrW/5unfw5q/wqfwjryM9tcwUv4M7TZ8yTBYQ==
+graphology-types@^0.24.0:
+  version "0.24.0"
+  resolved "https://registry.yarnpkg.com/graphology-types/-/graphology-types-0.24.0.tgz#81aaef55226edb692dd63a9ce5eaecc80694cd93"
+  integrity sha512-3qSanRtucm6rwBjpwuAc18GQcl68NqIRE4OA3wFUzdB2HRVXYoCAUsUJVS898bW+byEgd+BTcwR26CbltNvSWQ==
 
-graphology@^0.23.2:
-  version "0.23.2"
-  resolved "https://registry.yarnpkg.com/graphology/-/graphology-0.23.2.tgz#b09a33a9408a7615c3c9cff98e7404cc70a21820"
-  integrity sha512-RHcLpAP4M+KPShLQEvgkT1Y4vxl+FFbmmy3D0mupO+VXIuYC8zdmMcHs40D9m3mmN067zGS+lUaHjDq06Td7PQ==
+graphology@^0.24.0:
+  version "0.24.0"
+  resolved "https://registry.yarnpkg.com/graphology/-/graphology-0.24.0.tgz#c3c78b197f8ff6d8d3422a2d705c16e637b295f6"
+  integrity sha512-tEtz8n+rrx19l7muKh9VJwiRcFPu3FL9brJk4ilQR6tt+yoYsgomQHYnJaebkldIZPOXZ1mP8DEEnF0rpk8eNQ==
   dependencies:
     events "^3.3.0"
-    obliterator "^2.0.0"
+    obliterator "^2.0.2"
 
 handle-thing@^2.0.0:
   version "2.0.1"
@@ -12848,10 +12848,10 @@ objectorarray@^1.0.5:
   resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.5.tgz#2c05248bbefabd8f43ad13b41085951aac5e68a5"
   integrity sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==
 
-obliterator@^2.0.0:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.1.tgz#fbdd873bf39fc4f365a53b1fc86617a22526987c"
-  integrity sha512-XnkiCrrBcIZQitJPAI36mrrpEUvatbte8hLcTcQwKA1v9NkCKasSi+UAguLsLDs/out7MoRzAlmz7VXvY6ph6w==
+obliterator@^2.0.2:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.2.tgz#25f50dc92e1181371b9d8209d11890f1a3c2fc21"
+  integrity sha512-g0TrA7SbUggROhDPK8cEu/qpItwH2LSKcNl4tlfBNT54XY+nOsqrs0Q68h1V9b3HOSpIWv15jb1lax2hAggdIg==
 
 obuf@^1.0.0, obuf@^1.1.2:
   version "1.1.2"
-- 
GitLab