diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..f73ba1c65a316af0257f5848efd24817d1086185 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,33 @@ +{ + "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 + }, + { + // Requires the extension Debugger for Chrome: https://marketplace.visualstudio.com/items?itemName=msjsdiag.debugger-for-chrome + "type": "chrome", + "request": "launch", + "name": "Storybook Debug", + "breakOnLoad": true, + "url": "http://localhost:4400/?path=/story/", + "sourceMaps": true, + "webRoot": "${workspaceFolder}", + "sourceMapPathOverrides": { + "webpack:///*": "${webRoot}/*", + "webpack:///./*": "${webRoot}/*", + "webpack:///src/*": "${webRoot}/*", + "webpack:///./~/*": "${webRoot}/node_modules/*" + } + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index 033495ac56c3906b2b695131f4126cac283b90be..84265c46268a3170e5b69a61d4f9838bf3d234fa 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.stories.tsx b/apps/web-graphpolaris/src/components/schema/schema.stories.tsx index 4eb22a1ea0aebd2992b35da61d977480d5b3f782..7441b44b91d816ada3599968372bb2c1dfdb890b 100644 --- a/apps/web-graphpolaris/src/components/schema/schema.stories.tsx +++ b/apps/web-graphpolaris/src/components/schema/schema.stories.tsx @@ -1,5 +1,5 @@ import { - handleSchemaLayout, + // handleSchemaLayout, parseSchemaFromBackend } from '@graphpolaris/schema/schema-usecases'; import { @@ -143,5 +143,5 @@ TestWithSchema.play = async () => { }); //dispatch(setSchema(schema)); - handleSchemaLayout(schema); + // handleSchemaLayout(schema); }; diff --git a/apps/web-graphpolaris/src/components/schema/schema.tsx b/apps/web-graphpolaris/src/components/schema/schema.tsx index e005a8543bb79779c7765d5e1ba71f6bfa6df0c0..1023e2e3a6d10feb38e6cd304a754b782ba0fde8 100644 --- a/apps/web-graphpolaris/src/components/schema/schema.tsx +++ b/apps/web-graphpolaris/src/components/schema/schema.tsx @@ -1,35 +1,54 @@ 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(); + console.log(dbschema); + + const flowElements = createReactFlowElements(dbschema); + console.log(flowElements); + + // 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/apps/web-graphpolaris/src/components/visualisations/semanticsubstrates/semanticsubstrates.stories.tsx b/apps/web-graphpolaris/src/components/visualisations/semanticsubstrates/semanticsubstrates.stories.tsx index 5cb0c4c84ee1df4dd153d3f0dd9a2d84e66c4875..9746eb45ade6e414fb16beb0aed0d9fa02d05391 100644 --- a/apps/web-graphpolaris/src/components/visualisations/semanticsubstrates/semanticsubstrates.stories.tsx +++ b/apps/web-graphpolaris/src/components/visualisations/semanticsubstrates/semanticsubstrates.stories.tsx @@ -10,7 +10,7 @@ export default { * See https://storybook.js.org/docs/react/configure/overview#configure-story-loading * to learn how to generate automatic titles */ - title: 'SemanticSubstrates', + title: 'SemanticSubstrates', component: SemanticSubstrates, decorators: [ (story) => <div style={{ padding: '3rem' }}>{story()}</div>, @@ -23,25 +23,25 @@ export default { ], } as ComponentMeta<typeof SemanticSubstrates>; -declare module '@mui/material/styles' { - interface Theme { - graphpolaris: { - danger: string; - dataPointColors: string[]; - }; - } - // allow configuration using `createTheme` - interface ThemeOptions { - graphpolaris: { - danger: string; - dataPointColors: string[]; - }; - } -} +// declare module '@mui/material/styles' { +// interface Theme { +// palette: { +// primary: string; +// dataPointColors: string[]; +// }; +// } +// // allow configuration using `createTheme` +// interface ThemeOptions { +// palette: { +// danger: string; +// dataPointColors: string[]; +// }; +// } +// } const mockTheme = createTheme({ - graphpolaris: { - danger: 'orange', + palette: { + // danger: 'orange', dataPointColors: ['blue', 'green'], }, }); diff --git a/apps/web-graphpolaris/src/components/visualisations/semanticsubstrates/semanticsubstrates.tsx b/apps/web-graphpolaris/src/components/visualisations/semanticsubstrates/semanticsubstrates.tsx index 12f850c74fde2d9bd8787b1c72c7c9ed6e0c56b5..fd201b5e7a87626e888af8e55786bc2dc2262939 100644 --- a/apps/web-graphpolaris/src/components/visualisations/semanticsubstrates/semanticsubstrates.tsx +++ b/apps/web-graphpolaris/src/components/visualisations/semanticsubstrates/semanticsubstrates.tsx @@ -24,8 +24,7 @@ const SemanticSubstrates = () => { <Box sx={{ // Using our custom palette dataPointColors property, cast theme to any because Theme doesn't know of this custom property - backgroundColor: (theme: Theme) => - theme.graphpolaris.dataPointColors[0], + backgroundColor: (theme: Theme) => theme.palette.dataPointColors[0], }} > <h1>semantic substrates h1</h1> @@ -44,30 +43,30 @@ const SemanticSubstrates = () => { dispatch( changeDataPointColors([ v.currentTarget.value, - ...theme.graphpolaris.dataPointColors.slice(1), + ...theme.palette.dataPointColors.slice(1), ]) ) } type="color" id="head" name="head" - value={theme.graphpolaris.dataPointColors[0]} + value={theme.palette.dataPointColors[0]} /> Change dataPointColors reflects to local <input onChange={(v) => dispatch( changeDataPointColors([ - theme.graphpolaris.dataPointColors[0], + theme.palette.dataPointColors[0], v.currentTarget.value, - ...theme.graphpolaris.dataPointColors.slice(2), + ...theme.palette.dataPointColors.slice(2), ]) ) } type="color" id="head" name="head" - value={theme.graphpolaris.dataPointColors[1]} + value={theme.palette.dataPointColors[1]} /> Change dataPointColors reflects to global </> diff --git a/libs/schema/schema-usecases/src/index.ts b/libs/schema/schema-usecases/src/index.ts index 5d984685980c34d4a947c278f84a8ea4b755a323..098e236f2c4c443007039e25c7509588a3fce07b 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'; \ 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 f2130094ed2bbfa865b7f61af9d6c130eb32dfe2..0000000000000000000000000000000000000000 --- 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 e12f733f038d0303da9cd95657b46d98c96a5d56..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..a466f310151f9e8a39af521c66d4487032795662 --- /dev/null +++ b/libs/schema/schema-usecases/src/lib/schema-usecases.spec.ts @@ -0,0 +1,70 @@ +import { SchemaFromBackend } from '@graphpolaris/shared/data-access/store'; +import { MultiGraph } from 'graphology'; +import { parse } from 'path/posix'; +import { parseSchemaFromBackend } from '..'; +import { Attributes } from 'graphology-types'; +import { + movieSchema, + northWindSchema, + simpleSchema, + twitterSchema, +} from 'libs/shared/mock-data/src'; + +describe('SchemaUsecases', () => { + test.each([ + { data: simpleSchema }, + { data: movieSchema }, + { 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([ + { data: simpleSchema }, + { data: movieSchema }, + { 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 0000000000000000000000000000000000000000..ea3fdc0fadfcfa9edf4b318ee1bf2ab0de50ccdc --- /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 355f7fda9792f1426646744fb60198b3dd36560b..6ebadfb9de07f71cd20ee1102f3512550505ad2a 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 0000000000000000000000000000000000000000..3a6b17a5275478904fd98b29d47ab2a6708062eb --- /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 b44303d1cb77b4b501360d90f251d4ea388f2b0c..eb8fdb5627d94c45a5445e45e2e18f6386efefb9 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/libs/shared/mock-data/.eslintrc.json b/libs/shared/mock-data/.eslintrc.json new file mode 100644 index 0000000000000000000000000000000000000000..3456be9b9036a42c593c82b050281230e4ca0ae4 --- /dev/null +++ b/libs/shared/mock-data/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/shared/mock-data/README.md b/libs/shared/mock-data/README.md new file mode 100644 index 0000000000000000000000000000000000000000..3e701fff79d7765684c78442e3bf3e84c4a12322 --- /dev/null +++ b/libs/shared/mock-data/README.md @@ -0,0 +1,7 @@ +# shared-mock-data + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test shared-mock-data` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/shared/mock-data/jest.config.js b/libs/shared/mock-data/jest.config.js new file mode 100644 index 0000000000000000000000000000000000000000..4e791eac5390d85f4736399f4f238f6db90e02ae --- /dev/null +++ b/libs/shared/mock-data/jest.config.js @@ -0,0 +1,14 @@ +module.exports = { + displayName: 'shared-mock-data', + preset: '../../../jest.preset.js', + globals: { + 'ts-jest': { + tsconfig: '<rootDir>/tsconfig.spec.json', + }, + }, + transform: { + '^.+\\.[tj]s$': 'ts-jest', + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../../coverage/libs/shared/mock-data', +}; diff --git a/libs/shared/mock-data/project.json b/libs/shared/mock-data/project.json new file mode 100644 index 0000000000000000000000000000000000000000..0a0ec6c23a302fa25f3782cc9443a60d0b895857 --- /dev/null +++ b/libs/shared/mock-data/project.json @@ -0,0 +1,29 @@ +{ + "root": "libs/shared/mock-data", + "sourceRoot": "libs/shared/mock-data/src", + "projectType": "library", + "targets": { + "lint": { + "executor": "@nrwl/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["libs/shared/mock-data/**/*.ts"] + } + }, + "test": { + "executor": "@nrwl/jest:jest", + "outputs": ["coverage/libs/shared/mock-data"], + "options": { + "jestConfig": "libs/shared/mock-data/jest.config.js", + "passWithNoTests": true + } + }, + "version": { + "executor": "@jscutlery/semver:version", + "options": { + "commitMessageFormat": "chore(${projectName}): release version ${version}" + } + } + }, + "tags": [] +} diff --git a/libs/shared/mock-data/src/index.ts b/libs/shared/mock-data/src/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..56efd8b1107de967cc6a20114df6dcea57ac2e93 --- /dev/null +++ b/libs/shared/mock-data/src/index.ts @@ -0,0 +1,4 @@ +export * from './schema/simple'; +export * from './schema/moviesSchema'; +export * from './schema/northwindSchema'; +export * from './schema/twitterSchema'; diff --git a/libs/shared/mock-data/src/schema/moviesSchema.ts b/libs/shared/mock-data/src/schema/moviesSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..67bdc012962a1c69de55d8b3bd90b8866e5de90d --- /dev/null +++ b/libs/shared/mock-data/src/schema/moviesSchema.ts @@ -0,0 +1,96 @@ +export const movieSchema = { + "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/shared/mock-data/src/schema/northwindSchema.ts b/libs/shared/mock-data/src/schema/northwindSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..8cf2e965595dcfdc1374b3e573c124812468a31c --- /dev/null +++ b/libs/shared/mock-data/src/schema/northwindSchema.ts @@ -0,0 +1,284 @@ +export const northWindSchema = { + "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/shared/mock-data/src/schema/simple.ts b/libs/shared/mock-data/src/schema/simple.ts new file mode 100644 index 0000000000000000000000000000000000000000..13c5a91e08a4f6341c5be1255f1428d8e69c677e --- /dev/null +++ b/libs/shared/mock-data/src/schema/simple.ts @@ -0,0 +1,101 @@ + export const simpleSchema = { + "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/shared/mock-data/src/schema/twitterSchema.ts b/libs/shared/mock-data/src/schema/twitterSchema.ts new file mode 100644 index 0000000000000000000000000000000000000000..98a73b9ab4ee84b24275a65c647d26e15612e7cb --- /dev/null +++ b/libs/shared/mock-data/src/schema/twitterSchema.ts @@ -0,0 +1,313 @@ +export const twitterSchema = { + 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: [], + }, + ], +}; diff --git a/libs/shared/mock-data/tsconfig.json b/libs/shared/mock-data/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..355f7fda9792f1426646744fb60198b3dd36560b --- /dev/null +++ b/libs/shared/mock-data/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + } +} diff --git a/libs/shared/mock-data/tsconfig.lib.json b/libs/shared/mock-data/tsconfig.lib.json new file mode 100644 index 0000000000000000000000000000000000000000..6eb3eb9eabd5e4bb38ac7c366304f7ba7a6a491c --- /dev/null +++ b/libs/shared/mock-data/tsconfig.lib.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "types": [], + "composite": true + }, + "include": ["**/*.ts"], + "exclude": ["**/*.spec.ts"] +} diff --git a/libs/shared/mock-data/tsconfig.spec.json b/libs/shared/mock-data/tsconfig.spec.json new file mode 100644 index 0000000000000000000000000000000000000000..d8716fecfa3b7929f162b71e7a966c579a63c071 --- /dev/null +++ b/libs/shared/mock-data/tsconfig.spec.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "**/*.test.ts", + "**/*.spec.ts", + "**/*.test.tsx", + "**/*.spec.tsx", + "**/*.test.js", + "**/*.spec.js", + "**/*.test.jsx", + "**/*.spec.jsx", + "**/*.d.ts" + ] +} diff --git a/package.json b/package.json index 7665ebfc7f03d5eca4d7ea6174933dae27eb38a0..5761ede300a8d00a537e76649b9c4bc1321289a9 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-cookie": "^4.1.1", "react-dom": "17.0.2", diff --git a/tsconfig.base.json b/tsconfig.base.json index ac6b15170da814b379cec144deafff5b91b2ece1..ef27660ff70684e6b80eadc0c7653584321f52e8 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -26,6 +26,9 @@ ], "@graphpolaris/shared/data-access/theme": [ "libs/shared/data-access/theme/src/index.ts" + ], + "@graphpolaris/shared/mock-data": [ + "libs/shared/mock-data/src/index.ts" ] } }, diff --git a/workspace.json b/workspace.json index 66837864c2722a33d3536b08716bd3ff66c0c93f..97e8805f921e5c0d0d72f6684fca76a56c42603d 100644 --- a/workspace.json +++ b/workspace.json @@ -4,6 +4,7 @@ "schema-schema-usecases": "libs/schema/schema-usecases", "shared-data-access-store": "libs/shared/data-access/store", "shared-data-access-theme": "libs/shared/data-access/theme", + "shared-mock-data": "libs/shared/mock-data", "web-graphpolaris": "apps/web-graphpolaris", "web-graphpolaris-e2e": "apps/web-graphpolaris-e2e", "shared-data-access-authorization": "libs/shared/data-access/authorization" diff --git a/yarn.lock b/yarn.lock index bea04f6c621888b8f16757ede49a1e322f2bff4a..3f1a610ee19e64498dfe57fd18a7e3c4b09d675d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9643,18 +9643,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" @@ -12857,10 +12857,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"