Skip to content

Commit

Permalink
added serialisation and deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
aexol committed Jan 25, 2019
1 parent 869192e commit 2ccf1f2
Show file tree
Hide file tree
Showing 9 changed files with 415 additions and 25 deletions.
214 changes: 193 additions & 21 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@
"start": "tsc --watch",
"build": "tsc",
"sandbox": "webpack-dev-server --config ./sandbox/webpack.sandbox.config.js --content-base ./sandbox/ --hot --inline --open",
"docs": "typedoc --mode file --out docs --theme minimal src ; open ./docs/index.html"
"docs": "typedoc --mode file --out docs --theme minimal src ; open ./docs/index.html",
"test": "mocha -r ts-node/register src/**/*.spec.ts"
},
"devDependencies": {
"@types/chai": "^4.1.7",
"@types/mocha": "^5.2.5",
"awesome-typescript-loader": "^5.2.1",
"chai": "^4.2.0",
"mocha": "^5.2.0",
"ts-node": "^8.0.1",
"typedoc": "^0.14.1"
}
}
2 changes: 1 addition & 1 deletion sandbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class App extends React.Component {
const builtInScalarObjects: NodeDefinition[] = ["scalar"].map(
name =>
({
node: { ...createOND(name), inputs: undefined },
node: { ...createOND(name), inputs: null, outputs: null },
type: name,
help: help[name],
object: true,
Expand Down
9 changes: 9 additions & 0 deletions src/Serialization/Format.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { NodeSerialized } from "./Node";
import { LinkSerialized } from "./Link";
import { DiagramTheme } from "../Models/index";

export interface Format{
nodes:NodeSerialized[],
links:LinkSerialized[],
theme?:DiagramTheme;
}
21 changes: 21 additions & 0 deletions src/Serialization/Link.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Link } from "../Models/Link";
import { Node } from "../Models/Node";

export interface LinkSerialized extends Pick<Link, "centerPoint"> {
iId: string;
oId: string;
}

export const serializeLink = ({ centerPoint, i, o }: Link): LinkSerialized => ({
centerPoint,
iId: i.id,
oId: o.id
});
export const deserializeLink = (
{ centerPoint, iId, oId }: LinkSerialized,
nodes: Node[]
): Link => ({
centerPoint,
i: nodes.find(n => n.id === iId)!,
o: nodes.find(n => n.id === oId)!
});
86 changes: 86 additions & 0 deletions src/Serialization/Node.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Node } from "../Models/Node";
import { NodeDefinition } from "../Models/NodeDefinition";

export interface NodeDefinitionSerialized
extends Pick<NodeDefinition, "type" | "object" | "main"> {}

export interface NodeSerialized
extends Pick<
Node,
"id" | "name" | "description" | "x" | "y" | "options" | "readonly"
> {
definition: Pick<NodeDefinition, "type" | "object" | "main">;
editsDefinition?: Pick<NodeDefinition, "type" | "object" | "main">;
}

export const serializeNodeDefinition = ({
type,
object,
main
}: NodeDefinition): NodeDefinitionSerialized => ({
main,
object,
type
});

export const deserializeNodeDefinition = (
{ type, object, main }: NodeDefinitionSerialized,
definitions: NodeDefinition[]
): NodeDefinition => {
return definitions.find(
d => d.type === type && d.object === object && d.main === main
)!;
};

export const serializeNode = ({
id,
name,
description,
x,
y,
options,
readonly,
definition,
editsDefinition
}: Node): NodeSerialized => ({
id,
name,
description,
x,
y,
options,
readonly,
definition: serializeNodeDefinition(definition),
editsDefinition: editsDefinition
? serializeNodeDefinition(editsDefinition)
: undefined
});

export const deserializeNode = (
{
id,
x,
y,
name,
options,
definition,
description,
editsDefinition,
readonly
}: NodeSerialized,
definitions: NodeDefinition[]
): Node => {
return {
id,
x,
y,
name,
options,
description,
readonly,
definition: deserializeNodeDefinition(definition, definitions),
editsDefinition: editsDefinition
? deserializeNodeDefinition(editsDefinition, definitions)
: undefined
};
};
63 changes: 63 additions & 0 deletions src/Serialization/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { expect } from "chai";
import "mocha";
import { NodeDefinition } from "../Models/NodeDefinition";
import { Utils } from "../Utils/index";
import { Node } from "../Models/Node";
import { Link } from "../Models/Link";
import { Serializer } from "./index";

// TODO: This test case should be improved to test more complicated schemas

describe("Serialize and Deserialize", () => {
it("should serialize and deserialize", () => {
const nodeDefinitions: NodeDefinition[] = [
{
id: Utils.generateId(),
type: "dummy",
node: {
name: "dummy"
}
}
];
nodeDefinitions[0].acceptsInputs = [nodeDefinitions[0]];
const nodes: Node[] = [
{
definition: nodeDefinitions[0],
name: "dummy",
id: Utils.generateId(),
options: ["required"],
x: 0,
y: 0,
description: "Hello world",
editsDefinition: undefined,
readonly: undefined
},
{
definition: nodeDefinitions[0],
name: "dummy",
id: Utils.generateId(),
options: ["required"],
x: 0,
y: 0,
description: "Hello world 2",
editsDefinition: undefined,
readonly: undefined
}
];
const links: Link[] = [
{
centerPoint: 0.5,
i: nodes[0],
o: nodes[1]
}
];
const serialized = Serializer.serialize({
nodes,
links
});
const deserialize = Serializer.deserialize(serialized, nodeDefinitions);
expect(JSON.stringify(serialized)).equal(
JSON.stringify(Serializer.serialize(deserialize))
);
});
});
25 changes: 25 additions & 0 deletions src/Serialization/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { DiagramState } from "../Models/index";
import { Format } from "./Format";
import { serializeNode, deserializeNode } from "./Node";
import { serializeLink, deserializeLink } from "./Link";
import { NodeDefinition } from "../Models/NodeDefinition";

export class Serializer {
static serialize(state: Pick<DiagramState, "nodes" | "links">): Format {
return {
nodes: state.nodes.map(serializeNode),
links: state.links.map(serializeLink)
};
}
static deserialize(
state: Format,
definitions: NodeDefinition[]
): Pick<DiagramState, "nodes" | "links"> {
const nodes = state.nodes.map(n => deserializeNode(n, definitions));
const links = state.links.map(l => deserializeLink(l, nodes));
return {
nodes,
links
};
}
}
12 changes: 10 additions & 2 deletions src/Utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,22 @@ import { ScreenPosition } from "../IO/ScreenPosition";
import { NodeDefinition } from "../Models/NodeDefinition";

export { MinimapUtils } from "./minimapUtils";

function uuidv4() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
var r = (Math.random() * 16) | 0,
v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}

/**
* Utils
*
* Various utils.
*/
export class Utils {
static generateId = () =>
new Array(crypto.getRandomValues(new Uint8Array(4))).join("-");
static generateId = () => uuidv4();
static between = (a: number, b: number) => (c: number) => c >= a && c <= b;
static clamp = (v: number, min: number, max: number) =>
Math.max(Math.min(v, max), min);
Expand Down

0 comments on commit 2ccf1f2

Please sign in to comment.