Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fbp-graph

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fbp-graph - npm Package Compare versions

Comparing version 0.6.3 to 0.7.0

68

lib/Graph.d.ts

@@ -24,38 +24,39 @@ /// <reference types="node" />

getPortName(port?: string): string;
startTransaction(id: string, metadata?: JournalMetadata): void;
endTransaction(id: string, metadata?: JournalMetadata): void;
checkTransactionStart(): void;
checkTransactionEnd(): void;
setProperties(properties: PropertyMap): void;
addInport(publicPort: string, nodeKey: GraphNodeID, portKey: string, metadata?: GraphNodeMetadata): void;
removeInport(publicPort: string): void;
renameInport(oldPort: string, newPort: string): void;
setInportMetadata(publicPort: string, metadata: GraphNodeMetadata): void;
addOutport(publicPort: string, nodeKey: GraphNodeID, portKey: string, metadata?: GraphNodeMetadata): void;
removeOutport(publicPort: string): void;
renameOutport(oldPort: string, newPort: string): void;
setOutportMetadata(publicPort: string, metadata: GraphNodeMetadata): void;
addGroup(group: string, nodes: Array<GraphNodeID>, metadata: GraphGroupMetadata): GraphGroup;
renameGroup(oldName: string, newName: string): void;
removeGroup(groupName: string): void;
setGroupMetadata(groupName: string, metadata: GraphGroupMetadata): void;
addNode(id: GraphNodeID, component: string, metadata?: GraphNodeMetadata): GraphNode;
removeNode(id: GraphNodeID): void;
startTransaction(id: string, metadata?: JournalMetadata): Graph;
endTransaction(id: string, metadata?: JournalMetadata): Graph;
checkTransactionStart(): Graph;
checkTransactionEnd(): Graph;
setProperties(properties: PropertyMap): Graph;
addInport(publicPort: string, nodeKey: GraphNodeID, portKey: string, metadata?: GraphNodeMetadata): Graph;
removeInport(publicPort: string): Graph;
renameInport(oldPort: string, newPort: string): Graph;
setInportMetadata(publicPort: string, metadata: GraphNodeMetadata): Graph;
addOutport(publicPort: string, nodeKey: GraphNodeID, portKey: string, metadata?: GraphNodeMetadata): Graph;
removeOutport(publicPort: string): Graph;
renameOutport(oldPort: string, newPort: string): Graph;
setOutportMetadata(publicPort: string, metadata: GraphNodeMetadata): Graph;
addGroup(group: string, nodes: Array<GraphNodeID>, metadata: GraphGroupMetadata): Graph;
renameGroup(oldName: string, newName: string): Graph;
removeGroup(groupName: string): Graph;
setGroupMetadata(groupName: string, metadata: GraphGroupMetadata): Graph;
addNode(id: GraphNodeID, component: string, metadata?: GraphNodeMetadata): Graph;
removeNode(id: GraphNodeID): Graph;
getNode(id: GraphNodeID): GraphNode | null;
renameNode(oldId: GraphNodeID, newId: GraphNodeID): void;
setNodeMetadata(id: GraphNodeID, metadata: GraphNodeMetadata): void;
addEdge(outNode: GraphNodeID, outPort: string, inNode: GraphNodeID, inPort: string, metadata?: GraphEdgeMetadata): GraphEdge | null;
addEdgeIndex(outNode: GraphNodeID, outPort: string, outIndex: number | undefined, inNode: GraphNodeID, inPort: string, inIndex: number | undefined, metadata?: GraphEdgeMetadata): GraphEdge | null;
removeEdge(node: GraphNodeID, port: string, node2: GraphNodeID, port2: string): void;
renameNode(oldId: GraphNodeID, newId: GraphNodeID): Graph;
setNodeMetadata(id: GraphNodeID, metadata: GraphNodeMetadata): Graph;
addEdge(outNode: GraphNodeID, outPort: string, inNode: GraphNodeID, inPort: string, metadata?: GraphEdgeMetadata): Graph;
addEdgeIndex(outNode: GraphNodeID, outPort: string, outIndex: number | undefined, inNode: GraphNodeID, inPort: string, inIndex: number | undefined, metadata?: GraphEdgeMetadata): Graph;
removeEdge(node: GraphNodeID, port: string, node2: GraphNodeID, port2: string): Graph;
getEdge(node: GraphNodeID, port: string, node2: GraphNodeID, port2: string): GraphEdge | null;
setEdgeMetadata(node: GraphNodeID, port: string, node2: GraphNodeID, port2: string, metadata: GraphEdgeMetadata): void;
addInitial(data: any, node: GraphNodeID, port: string, metadata?: GraphIIPMetadata): GraphIIP | null;
addInitialIndex(data: any, node: GraphNodeID, port: string, index: number, metadata?: GraphIIPMetadata): GraphIIP | null;
addGraphInitial(data: any, node: string, metadata?: GraphIIPMetadata): GraphIIP | null;
addGraphInitialIndex(data: any, node: string, index: number, metadata?: GraphIIPMetadata): GraphIIP | null;
removeInitial(node: GraphNodeID, port: string): void;
removeGraphInitial(node: string): void;
setEdgeMetadata(node: GraphNodeID, port: string, node2: GraphNodeID, port2: string, metadata: GraphEdgeMetadata): Graph;
addInitial(data: any, node: GraphNodeID, port: string, metadata?: GraphIIPMetadata): Graph;
addInitialIndex(data: any, node: GraphNodeID, port: string, index: number, metadata?: GraphIIPMetadata): Graph;
addGraphInitial(data: any, node: string, metadata?: GraphIIPMetadata): Graph;
addGraphInitialIndex(data: any, node: string, index: number, metadata?: GraphIIPMetadata): Graph;
removeInitial(node: GraphNodeID, port: string): Graph;
removeGraphInitial(node: string): Graph;
toDOT(): string;
toYUML(): string;
toJSON(): GraphJson;
save(file: string): Promise<string>;
save(file: string, callback: (err: Error | null, filename?: string) => void): void;

@@ -67,4 +68,7 @@ }

}
declare function loadJSON(passedDefinition: string | GraphJson): Promise<Graph>;
declare function loadJSON(passedDefinition: string | GraphJson, callback: GraphLoadingCallback, metadata?: JournalMetadata): void;
declare function loadFBP(fbpData: string, callback: GraphLoadingCallback, metadata?: JournalMetadata, caseSensitive?: boolean): void;
declare function loadFBP(fbpData: string): Promise<Graph>;
declare function loadFBP(fbpData: string, callback: GraphLoadingCallback, metadata?: JournalMetadata): void;
declare function loadFile(file: string): Promise<Graph>;
declare function loadFile(file: string, callback: GraphLoadingCallback, metadata?: JournalMetadata, caseSensitive?: boolean): void;

@@ -71,0 +75,0 @@ declare function mergeResolveTheirsNaive(base: Graph, to: Graph): void;

@@ -14,2 +14,3 @@ "use strict";

const clone = require("clone");
const fs_1 = require("fs");
const Platform_1 = require("./Platform");

@@ -56,2 +57,3 @@ // This class represents an abstract FBP graph containing nodes

this.emit('startTransaction', id, metadata);
return this;
}

@@ -65,2 +67,3 @@ endTransaction(id, metadata = {}) {

this.emit('endTransaction', id, metadata);
return this;
}

@@ -74,2 +77,3 @@ checkTransactionStart() {

}
return this;
}

@@ -83,2 +87,3 @@ checkTransactionEnd() {

}
return this;
}

@@ -97,2 +102,3 @@ // ## Modifying Graph properties

this.checkTransactionEnd();
return this;
}

@@ -102,3 +108,3 @@ addInport(publicPort, nodeKey, portKey, metadata = {}) {

if (!this.getNode(nodeKey)) {
return;
return this;
}

@@ -114,2 +120,3 @@ const portName = this.getPortName(publicPort);

this.checkTransactionEnd();
return this;
}

@@ -119,3 +126,3 @@ removeInport(publicPort) {

if (!this.inports[portName]) {
return;
return this;
}

@@ -128,2 +135,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -134,6 +142,6 @@ renameInport(oldPort, newPort) {

if (!this.inports[oldPortName]) {
return;
return this;
}
if (newPortName === oldPortName) {
return;
return this;
}

@@ -145,2 +153,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -150,3 +159,3 @@ setInportMetadata(publicPort, metadata) {

if (!this.inports[portName]) {
return;
return this;
}

@@ -173,2 +182,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -178,3 +188,3 @@ addOutport(publicPort, nodeKey, portKey, metadata = {}) {

if (!this.getNode(nodeKey)) {
return;
return this;
}

@@ -190,2 +200,3 @@ const portName = this.getPortName(publicPort);

this.checkTransactionEnd();
return this;
}

@@ -195,3 +206,3 @@ removeOutport(publicPort) {

if (!this.outports[portName]) {
return;
return this;
}

@@ -204,2 +215,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -210,3 +222,3 @@ renameOutport(oldPort, newPort) {

if (!this.outports[oldPortName]) {
return;
return this;
}

@@ -218,2 +230,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -223,3 +236,3 @@ setOutportMetadata(publicPort, metadata) {

if (!this.outports[portName]) {
return;
return this;
}

@@ -246,2 +259,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -260,3 +274,3 @@ // ## Grouping nodes in a graph

this.checkTransactionEnd();
return g;
return this;
}

@@ -277,2 +291,3 @@ renameGroup(oldName, newName) {

this.checkTransactionEnd();
return this;
}

@@ -293,2 +308,3 @@ removeGroup(groupName) {

this.checkTransactionEnd();
return this;
}

@@ -321,2 +337,3 @@ setGroupMetadata(groupName, metadata) {

this.checkTransactionEnd();
return this;
}

@@ -346,3 +363,3 @@ // ## Adding a node to the graph

this.checkTransactionEnd();
return node;
return this;
}

@@ -361,3 +378,3 @@ // ## Removing a node from the graph

if (!node) {
return;
return this;
}

@@ -405,2 +422,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -426,3 +444,3 @@ // ## Getting a node

if (!node) {
return;
return this;
}

@@ -476,2 +494,3 @@ node.id = newId;

this.checkTransactionEnd();
return this;
}

@@ -484,3 +503,3 @@ // ## Changing a node's metadata

if (!node) {
return;
return this;
}

@@ -506,2 +525,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -530,9 +550,9 @@ // ## Connecting nodes

})) {
return null;
return this;
}
if (!this.getNode(outNode)) {
return null;
return this;
}
if (!this.getNode(inNode)) {
return null;
return this;
}

@@ -554,3 +574,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return edge;
return this;
}

@@ -575,9 +595,9 @@ // Adding an edge will emit the `addEdge` event.

})) {
return null;
return this;
}
if (!this.getNode(outNode)) {
return null;
return this;
}
if (!this.getNode(inNode)) {
return null;
return this;
}

@@ -601,3 +621,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return edge;
return this;
}

@@ -614,3 +634,3 @@ // ## Disconnected nodes

if (!this.getEdge(node, port, node2, port2)) {
return;
return this;
}

@@ -640,2 +660,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -673,3 +694,3 @@ // ## Getting an edge

if (!edge) {
return;
return this;
}

@@ -695,2 +716,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -718,3 +740,3 @@ // ## Adding Initial Information Packets

if (!this.getNode(node)) {
return null;
return this;
}

@@ -736,7 +758,7 @@ const portName = this.getPortName(port);

this.checkTransactionEnd();
return initializer;
return this;
}
addInitialIndex(data, node, port, index, metadata = {}) {
if (!this.getNode(node)) {
return null;
return this;
}

@@ -760,3 +782,3 @@ const indexVal = (index === null) ? undefined : index;

this.checkTransactionEnd();
return initializer;
return this;
}

@@ -766,3 +788,3 @@ addGraphInitial(data, node, metadata = {}) {

if (!inport) {
return null;
return this;
}

@@ -774,3 +796,3 @@ return this.addInitial(data, inport.process, inport.port, metadata);

if (!inport) {
return null;
return this;
}

@@ -803,2 +825,3 @@ return this.addInitialIndex(data, inport.process, inport.port, index, metadata);

this.checkTransactionEnd();
return this;
}

@@ -808,5 +831,6 @@ removeGraphInitial(node) {

if (!inport) {
return;
return this;
}
this.removeInitial(inport.process, inport.port);
return this;
}

@@ -938,19 +962,29 @@ toDOT() {

save(file, callback) {
let promise;
if (Platform_1.isBrowser()) {
callback(new Error('Saving graphs not supported on browser'));
promise = Promise.reject(new Error('Saving graphs not supported on browser'));
}
else {
promise = new Promise((resolve, reject) => {
const json = JSON.stringify(this.toJSON(), null, 4);
let filename = file;
if (!filename.match(/\.json$/)) {
filename = `${file}.json`;
}
fs_1.writeFile(filename, json, 'utf-8', (err) => {
if (err) {
reject(err);
return;
}
resolve(filename);
});
});
}
if (callback) {
promise.then((filename) => {
callback(null, filename);
}, callback);
return;
}
const json = JSON.stringify(this.toJSON(), null, 4);
let filename = file;
if (!filename.match(/\.json$/)) {
filename = `${file}.json`;
}
// eslint-disable-next-line global-require
require('fs').writeFile(filename, json, 'utf-8', (err) => {
if (err) {
callback(err);
return;
}
callback(null, filename);
});
return promise;
}

@@ -965,150 +999,166 @@ }

function loadJSON(passedDefinition, callback, metadata = {}) {
let definition;
if (typeof passedDefinition === 'string') {
definition = JSON.parse(passedDefinition);
}
else {
definition = clone(passedDefinition);
}
if (!definition.properties) {
definition.properties = {};
}
if (!definition.processes) {
definition.processes = {};
}
if (!definition.connections) {
definition.connections = [];
}
const graph = new Graph(definition.properties.name, {
caseSensitive: definition.caseSensitive || false,
});
graph.startTransaction('loadJSON', metadata);
const properties = {};
Object.keys(definition.properties).forEach((property) => {
if (property === 'name') {
return;
const promise = new Promise((resolve) => {
let definition;
if (typeof passedDefinition === 'string') {
definition = JSON.parse(passedDefinition);
}
else {
definition = clone(passedDefinition);
}
if (!definition.properties) {
return;
definition.properties = {};
}
const value = definition.properties[property];
properties[property] = value;
});
graph.setProperties(properties);
Object.keys(definition.processes).forEach((id) => {
if (!definition.processes) {
return;
definition.processes = {};
}
const def = definition.processes[id];
if (!def.metadata) {
def.metadata = {};
if (!definition.connections) {
definition.connections = [];
}
graph.addNode(id, def.component, def.metadata);
});
definition.connections.forEach((conn) => {
const meta = conn.metadata ? conn.metadata : {};
if (typeof conn.data !== 'undefined') {
if (typeof conn.tgt.index === 'number') {
graph.addInitialIndex(conn.data, conn.tgt.process, graph.getPortName(conn.tgt.port), conn.tgt.index, meta);
const graph = new Graph(definition.properties.name, {
caseSensitive: definition.caseSensitive || false,
});
graph.startTransaction('loadJSON', metadata);
const properties = {};
Object.keys(definition.properties).forEach((property) => {
if (property === 'name') {
return;
}
else {
graph.addInitial(conn.data, conn.tgt.process, graph.getPortName(conn.tgt.port), meta);
if (!definition.properties) {
return;
}
return;
}
if (typeof conn.src === 'undefined') {
return;
}
if ((typeof conn.src.index === 'number') || (typeof conn.tgt.index === 'number')) {
graph.addEdgeIndex(conn.src.process, graph.getPortName(conn.src.port), conn.src.index, conn.tgt.process, graph.getPortName(conn.tgt.port), conn.tgt.index, meta);
return;
}
graph.addEdge(conn.src.process, graph.getPortName(conn.src.port), conn.tgt.process, graph.getPortName(conn.tgt.port), meta);
});
if (definition.inports) {
Object.keys(definition.inports).forEach((pub) => {
if (!definition.inports || !definition.inports[pub]) {
const value = definition.properties[property];
properties[property] = value;
});
graph.setProperties(properties);
Object.keys(definition.processes).forEach((id) => {
if (!definition.processes) {
return;
}
const priv = definition.inports[pub];
graph.addInport(pub, priv.process, graph.getPortName(priv.port), priv.metadata || {});
const def = definition.processes[id];
if (!def.metadata) {
def.metadata = {};
}
graph.addNode(id, def.component, def.metadata);
});
}
if (definition.outports) {
Object.keys(definition.outports).forEach((pub) => {
if (!definition.outports || !definition.outports[pub]) {
definition.connections.forEach((conn) => {
const meta = conn.metadata ? conn.metadata : {};
if (typeof conn.data !== 'undefined') {
if (typeof conn.tgt.index === 'number') {
graph.addInitialIndex(conn.data, conn.tgt.process, graph.getPortName(conn.tgt.port), conn.tgt.index, meta);
}
else {
graph.addInitial(conn.data, conn.tgt.process, graph.getPortName(conn.tgt.port), meta);
}
return;
}
const priv = definition.outports[pub];
graph.addOutport(pub, priv.process, graph.getPortName(priv.port), priv.metadata || {});
if (typeof conn.src === 'undefined') {
return;
}
if ((typeof conn.src.index === 'number') || (typeof conn.tgt.index === 'number')) {
graph.addEdgeIndex(conn.src.process, graph.getPortName(conn.src.port), conn.src.index, conn.tgt.process, graph.getPortName(conn.tgt.port), conn.tgt.index, meta);
return;
}
graph.addEdge(conn.src.process, graph.getPortName(conn.src.port), conn.tgt.process, graph.getPortName(conn.tgt.port), meta);
});
if (definition.inports) {
Object.keys(definition.inports).forEach((pub) => {
if (!definition.inports || !definition.inports[pub]) {
return;
}
const priv = definition.inports[pub];
graph.addInport(pub, priv.process, graph.getPortName(priv.port), priv.metadata || {});
});
}
if (definition.outports) {
Object.keys(definition.outports).forEach((pub) => {
if (!definition.outports || !definition.outports[pub]) {
return;
}
const priv = definition.outports[pub];
graph.addOutport(pub, priv.process, graph.getPortName(priv.port), priv.metadata || {});
});
}
if (definition.groups) {
definition.groups.forEach((group) => {
graph.addGroup(group.name, group.nodes, group.metadata || {});
});
}
graph.endTransaction('loadJSON');
resolve(graph);
});
if (callback) {
promise.then((graph) => {
callback(null, graph);
}, callback);
}
if (definition.groups) {
definition.groups.forEach((group) => {
graph.addGroup(group.name, group.nodes, group.metadata || {});
});
}
graph.endTransaction('loadJSON');
return callback(null, graph);
return promise;
}
exports.loadJSON = loadJSON;
function loadFBP(fbpData, callback, metadata = {}, caseSensitive = false) {
let definition;
try {
const promise = new Promise((resolve) => {
// eslint-disable-next-line global-require
definition = require('fbp').parse(fbpData, { caseSensitive });
resolve(require('fbp').parse(fbpData, { caseSensitive }));
})
.then((def) => loadJSON(def));
if (callback) {
promise.then((graph) => {
callback(null, graph);
}, callback);
}
catch (e) {
return callback(e);
}
return loadJSON(definition, callback, metadata);
return promise;
}
exports.loadFBP = loadFBP;
function loadHTTP(url, callback) {
const req = new XMLHttpRequest();
req.onreadystatechange = () => {
if (req.readyState !== 4) {
return;
}
if (req.status !== 200) {
callback(new Error(`Failed to load ${url}: HTTP ${req.status}`));
}
callback(null, req.responseText);
};
req.open('GET', url, true);
req.send();
const promise = new Promise((resolve, reject) => {
const req = new XMLHttpRequest();
req.onreadystatechange = () => {
if (req.readyState !== 4) {
return;
}
if (req.status !== 200) {
reject(new Error(`Failed to load ${url}: HTTP ${req.status}`));
return;
}
resolve(req.responseText);
};
req.open('GET', url, true);
req.send();
});
if (callback) {
promise.then((content) => {
callback(null, content);
}, callback);
}
return promise;
}
function loadFile(file, callback, metadata = {}, caseSensitive = false) {
let ioPromise;
if (Platform_1.isBrowser()) {
// On browser we can try getting the file via AJAX
loadHTTP(file, (err, data) => {
if (err) {
callback(err);
return;
}
if (!data) {
callback(new Error('No data received'));
return;
}
if (file.split('.').pop() === 'fbp') {
loadFBP(data, callback, metadata);
return;
}
loadJSON(data, callback, metadata);
ioPromise = loadHTTP(file);
}
else {
ioPromise = new Promise((resolve, reject) => {
// Node.js graph file
fs_1.readFile(file, 'utf-8', (err, data) => {
if (err) {
reject(err);
return;
}
resolve(data);
});
});
return;
}
// Node.js graph file
// eslint-disable-next-line global-require
require('fs').readFile(file, 'utf-8', (err, data) => {
if (err) {
callback(err);
return;
}
const promise = ioPromise.then((content) => {
if (file.split('.').pop() === 'fbp') {
loadFBP(data, callback, {}, caseSensitive);
return;
return loadFBP(content);
}
loadJSON(data, callback, {});
return loadJSON(content);
});
if (callback) {
promise.then((content) => {
callback(null, content);
}, callback);
}
return promise;
}

@@ -1115,0 +1165,0 @@ exports.loadFile = loadFile;

@@ -26,4 +26,5 @@ /// <reference types="node" />

toJSON(startRev?: number, endRevParam?: null): string[];
save(file: string): Promise<void>;
save(file: string, callback: (err: NodeJS.ErrnoException | null) => void): void;
}
export { Journal, JournalStore, MemoryJournalStore, };

@@ -503,6 +503,20 @@ "use strict";

save(file, callback) {
const json = JSON.stringify(this.toJSON(), null, 4);
const { writeFile } = require('fs');
// eslint-disable-next-line global-require
writeFile(`${file}.json`, json, 'utf-8', callback);
const promise = new Promise((resolve, reject) => {
const json = JSON.stringify(this.toJSON(), null, 4);
const { writeFile } = require('fs');
writeFile(`${file}.json`, json, 'utf-8', (err) => {
if (err) {
reject(err);
return;
}
resolve();
});
});
if (callback) {
promise.then(() => {
callback(null);
}, callback);
return;
}
return promise;
}

@@ -509,0 +523,0 @@ }

{
"name": "fbp-graph",
"version": "0.6.3",
"version": "0.7.0",
"description": "JavaScript FBP graph library",

@@ -5,0 +5,0 @@ "main": "lib/index.js",

@@ -30,2 +30,5 @@ FBP Graph library for JavaScript

* 0.7.0 (December 08th 2020)
- All graph modification methods are now chainable, allowing you to do things like `graph.addNode().addEdge().toJSON()`
- Graph I/O methods (like `loadFile` and `save`) now return Promises in case no callback is supplied
* 0.6.3 (December 03rd 2020)

@@ -32,0 +35,0 @@ - Fixed exporting of base Graph and Journal types in index

@@ -264,19 +264,11 @@ "use strict";

let g;
it('should produce a Graph when input is string', (done) => lib.graph.loadJSON(jsonString, (err, instance) => {
if (err) {
done(err);
return;
}
it('should produce a Graph when input is string', () => lib.graph.loadJSON(jsonString)
.then((instance) => {
g = instance;
chai.expect(g).to.be.an('object');
done();
}));
it('should produce a Graph when input is json', (done) => lib.graph.loadJSON(json, (err, instance) => {
if (err) {
done(err);
return;
}
it('should produce a Graph when input is JSON', () => lib.graph.loadJSON(json)
.then((instance) => {
g = instance;
chai.expect(g).to.be.an('object');
done();
}));

@@ -703,20 +695,33 @@ it('should not mutate the inputted json object', (done) => {

});
it('should be possible to save a graph to a file', (done) => {
it('should be possible to save a graph to a file', () => {
const g = new lib.graph.Graph();
g.addNode('Foo', 'Bar');
originalGraph = g.toJSON();
return g.save(graphPath);
});
it('should be possible to save a graph to a file with a callback', (done) => {
const g = new lib.graph.Graph();
g.addNode('Foo', 'Bar');
originalGraph = g.toJSON();
g.save(graphPath, done);
});
it('should be possible to load a graph from a file', (done) => lib.graph.loadFile(graphPath, (err, g) => {
if (err) {
done(err);
return;
}
if (!g) {
done(new Error('No graph'));
return;
}
it('should be possible to load a graph from a file', () => lib.graph.loadFile(graphPath)
.then((g) => {
chai.expect(g).to.be.an('object');
chai.expect(g.toJSON()).to.eql(originalGraph);
done();
}));
it('should be possible to load a graph from a file with a callback', (done) => {
lib.graph.loadFile(graphPath, (err, g) => {
if (err) {
done(err);
return;
}
if (!g) {
done(new Error('No graph'));
return;
}
chai.expect(g.toJSON()).to.eql(originalGraph);
done();
});
});
});

@@ -723,0 +728,0 @@ describe('without .json suffix', () => {

@@ -267,21 +267,13 @@ import * as lib from '../lib/index';

it('should produce a Graph when input is string', (done) => lib.graph.loadJSON(jsonString, (err, instance) => {
if (err) {
done(err);
return;
}
g = instance;
chai.expect(g).to.be.an('object');
done();
}));
it('should produce a Graph when input is string', () => lib.graph.loadJSON(jsonString)
.then((instance) => {
g = instance;
chai.expect(g).to.be.an('object');
}));
it('should produce a Graph when input is json', (done) => lib.graph.loadJSON(json, (err, instance) => {
if (err) {
done(err);
return;
}
g = instance;
chai.expect(g).to.be.an('object');
done();
}));
it('should produce a Graph when input is JSON', () => lib.graph.loadJSON(json)
.then((instance) => {
g = instance;
chai.expect(g).to.be.an('object');
}));

@@ -697,20 +689,33 @@ it('should not mutate the inputted json object', (done) => {

});
it('should be possible to save a graph to a file', (done) => {
it('should be possible to save a graph to a file', () => {
const g = new lib.graph.Graph();
g.addNode('Foo', 'Bar');
originalGraph = g.toJSON();
return g.save(graphPath);
});
it('should be possible to save a graph to a file with a callback', (done) => {
const g = new lib.graph.Graph();
g.addNode('Foo', 'Bar');
originalGraph = g.toJSON();
g.save(graphPath, done);
});
it('should be possible to load a graph from a file', (done) => lib.graph.loadFile(graphPath, (err, g) => {
if (err) {
done(err);
return;
}
if (!g) {
done(new Error('No graph'));
return;
}
chai.expect(g.toJSON()).to.eql(originalGraph);
done();
}));
it('should be possible to load a graph from a file', () => lib.graph.loadFile(graphPath)
.then((g) => {
chai.expect(g).to.be.an('object');
chai.expect(g.toJSON()).to.eql(originalGraph);
}));
it('should be possible to load a graph from a file with a callback', (done) => {
lib.graph.loadFile(graphPath, (err, g) => {
if (err) {
done(err);
return;
}
if (!g) {
done(new Error('No graph'));
return;
}
chai.expect(g.toJSON()).to.eql(originalGraph);
done();
});
});
});

@@ -717,0 +722,0 @@ describe('without .json suffix', () => {

@@ -11,2 +11,3 @@ // FBP Graph

import * as clone from 'clone';
import { writeFile, readFile } from 'fs';
import { isBrowser } from './Platform';

@@ -90,3 +91,3 @@ import {

// the graph API will implicitly create a transaction for that change
startTransaction(id: string, metadata: JournalMetadata = {}) {
startTransaction(id: string, metadata: JournalMetadata = {}): Graph {
if (this.transaction.id) {

@@ -99,5 +100,6 @@ throw Error('Nested transactions not supported');

this.emit('startTransaction', id, metadata);
return this;
}
endTransaction(id: string, metadata: JournalMetadata = {}) {
endTransaction(id: string, metadata: JournalMetadata = {}): Graph {
if (!this.transaction.id) {

@@ -110,5 +112,6 @@ throw Error('Attempted to end non-existing transaction');

this.emit('endTransaction', id, metadata);
return this;
}
checkTransactionStart() {
checkTransactionStart(): Graph {
if (!this.transaction.id) {

@@ -119,5 +122,6 @@ this.startTransaction('implicit');

}
return this;
}
checkTransactionEnd() {
checkTransactionEnd(): Graph {
if (this.transaction.id === 'implicit') {

@@ -129,2 +133,3 @@ this.transaction.depth -= 1;

}
return this;
}

@@ -135,3 +140,3 @@

// This method allows changing properties of the graph.
setProperties(properties: PropertyMap) {
setProperties(properties: PropertyMap): Graph {
this.checkTransactionStart();

@@ -145,7 +150,10 @@ const before = clone(this.properties);

this.checkTransactionEnd();
return this;
}
addInport(publicPort: string, nodeKey: GraphNodeID, portKey: string, metadata: GraphNodeMetadata = {}) {
addInport(publicPort: string, nodeKey: GraphNodeID, portKey: string, metadata: GraphNodeMetadata = {}): Graph {
// Check that node exists
if (!this.getNode(nodeKey)) { return; }
if (!this.getNode(nodeKey)) {
return this;
}

@@ -161,7 +169,10 @@ const portName = this.getPortName(publicPort);

this.checkTransactionEnd();
return this;
}
removeInport(publicPort: string) {
removeInport(publicPort: string): Graph {
const portName = this.getPortName(publicPort);
if (!this.inports[portName]) { return; }
if (!this.inports[portName]) {
return this;
}

@@ -174,9 +185,14 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}
renameInport(oldPort: string, newPort: string) {
renameInport(oldPort: string, newPort: string): Graph {
const oldPortName = this.getPortName(oldPort);
const newPortName = this.getPortName(newPort);
if (!this.inports[oldPortName]) { return; }
if (newPortName === oldPortName) { return; }
if (!this.inports[oldPortName]) {
return this;
}
if (newPortName === oldPortName) {
return this;
}

@@ -188,7 +204,10 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}
setInportMetadata(publicPort:string, metadata: GraphNodeMetadata) {
setInportMetadata(publicPort:string, metadata: GraphNodeMetadata): Graph {
const portName = this.getPortName(publicPort);
if (!this.inports[portName]) { return; }
if (!this.inports[portName]) {
return this;
}

@@ -214,7 +233,10 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}
addOutport(publicPort: string, nodeKey: GraphNodeID, portKey: string, metadata: GraphNodeMetadata = {}) {
addOutport(publicPort: string, nodeKey: GraphNodeID, portKey: string, metadata: GraphNodeMetadata = {}): Graph {
// Check that node exists
if (!this.getNode(nodeKey)) { return; }
if (!this.getNode(nodeKey)) {
return this;
}

@@ -231,7 +253,10 @@ const portName = this.getPortName(publicPort);

this.checkTransactionEnd();
return this;
}
removeOutport(publicPort: string) {
removeOutport(publicPort: string): Graph {
const portName = this.getPortName(publicPort);
if (!this.outports[portName]) { return; }
if (!this.outports[portName]) {
return this;
}

@@ -246,8 +271,11 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}
renameOutport(oldPort: string, newPort: string) {
renameOutport(oldPort: string, newPort: string): Graph {
const oldPortName = this.getPortName(oldPort);
const newPortName = this.getPortName(newPort);
if (!this.outports[oldPortName]) { return; }
if (!this.outports[oldPortName]) {
return this;
}

@@ -259,7 +287,10 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}
setOutportMetadata(publicPort: string, metadata: GraphNodeMetadata) {
setOutportMetadata(publicPort: string, metadata: GraphNodeMetadata): Graph {
const portName = this.getPortName(publicPort);
if (!this.outports[portName]) { return; }
if (!this.outports[portName]) {
return this;
}

@@ -285,2 +316,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -290,3 +322,3 @@

//
addGroup(group: string, nodes: Array<GraphNodeID>, metadata: GraphGroupMetadata): GraphGroup {
addGroup(group: string, nodes: Array<GraphNodeID>, metadata: GraphGroupMetadata): Graph {
this.checkTransactionStart();

@@ -304,6 +336,6 @@

return g;
return this;
}
renameGroup(oldName: string, newName: string) {
renameGroup(oldName: string, newName: string): Graph {
this.checkTransactionStart();

@@ -318,5 +350,6 @@ this.groups.forEach((group) => {

this.checkTransactionEnd();
return this;
}
removeGroup(groupName: string) {
removeGroup(groupName: string): Graph {
this.checkTransactionStart();

@@ -331,5 +364,6 @@ this.groups = this.groups.filter((group) => {

this.checkTransactionEnd();
return this;
}
setGroupMetadata(groupName: string, metadata: GraphGroupMetadata) {
setGroupMetadata(groupName: string, metadata: GraphGroupMetadata): Graph {
this.checkTransactionStart();

@@ -355,2 +389,3 @@ this.groups.forEach((group) => {

this.checkTransactionEnd();
return this;
}

@@ -371,3 +406,3 @@

// Addition of a node will emit the `addNode` event.
addNode(id: GraphNodeID, component: string, metadata: GraphNodeMetadata = {}): GraphNode {
addNode(id: GraphNodeID, component: string, metadata: GraphNodeMetadata = {}): Graph {
this.checkTransactionStart();

@@ -383,3 +418,3 @@ const node = {

this.checkTransactionEnd();
return node;
return this;
}

@@ -396,6 +431,6 @@

// emitted.
removeNode(id: GraphNodeID) {
removeNode(id: GraphNodeID): Graph {
const node = this.getNode(id);
if (!node) {
return;
return this;
}

@@ -445,2 +480,3 @@

this.checkTransactionEnd();
return this;
}

@@ -464,7 +500,9 @@

// Nodes IDs can be changed by calling this method.
renameNode(oldId: GraphNodeID, newId: GraphNodeID) {
renameNode(oldId: GraphNodeID, newId: GraphNodeID): Graph {
this.checkTransactionStart();
const node = this.getNode(oldId);
if (!node) { return; }
if (!node) {
return this;
}
node.id = newId;

@@ -514,2 +552,3 @@

this.checkTransactionEnd();
return this;
}

@@ -520,5 +559,7 @@

// Node metadata can be set or changed by calling this method.
setNodeMetadata(id: GraphNodeID, metadata: GraphNodeMetadata) {
setNodeMetadata(id: GraphNodeID, metadata: GraphNodeMetadata): Graph {
const node = this.getNode(id);
if (!node) { return; }
if (!node) {
return this;
}

@@ -546,2 +587,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -558,3 +600,3 @@

// Adding an edge will emit the `addEdge` event.
addEdge(outNode: GraphNodeID, outPort: string, inNode: GraphNodeID, inPort: string, metadata: GraphEdgeMetadata = {}): GraphEdge | null {
addEdge(outNode: GraphNodeID, outPort: string, inNode: GraphNodeID, inPort: string, metadata: GraphEdgeMetadata = {}): Graph {
const outPortName = this.getPortName(outPort);

@@ -572,9 +614,9 @@ const inPortName = this.getPortName(inPort);

})) {
return null;
return this;
}
if (!this.getNode(outNode)) {
return null;
return this;
}
if (!this.getNode(inNode)) {
return null;
return this;
}

@@ -599,7 +641,7 @@

this.checkTransactionEnd();
return edge;
return this;
}
// Adding an edge will emit the `addEdge` event.
addEdgeIndex(outNode: GraphNodeID, outPort: string, outIndex: number | undefined, inNode: GraphNodeID, inPort: string, inIndex: number | undefined, metadata: GraphEdgeMetadata = {}): GraphEdge | null {
addEdgeIndex(outNode: GraphNodeID, outPort: string, outIndex: number | undefined, inNode: GraphNodeID, inPort: string, inIndex: number | undefined, metadata: GraphEdgeMetadata = {}): Graph {
const outPortName = this.getPortName(outPort);

@@ -621,9 +663,9 @@ const inPortName = this.getPortName(inPort);

})) {
return null;
return this;
}
if (!this.getNode(outNode)) {
return null;
return this;
}
if (!this.getNode(inNode)) {
return null;
return this;
}

@@ -650,3 +692,3 @@

this.checkTransactionEnd();
return edge;
return this;
}

@@ -662,5 +704,5 @@

// Removing a connection will emit the `removeEdge` event.
removeEdge(node: GraphNodeID, port: string, node2: GraphNodeID, port2: string) {
removeEdge(node: GraphNodeID, port: string, node2: GraphNodeID, port2: string): Graph {
if (!this.getEdge(node, port, node2, port2)) {
return;
return this;
}

@@ -690,2 +732,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -722,5 +765,7 @@

// Edge metadata can be set or changed by calling this method.
setEdgeMetadata(node: GraphNodeID, port: string, node2: GraphNodeID, port2: string, metadata: GraphEdgeMetadata) {
setEdgeMetadata(node: GraphNodeID, port: string, node2: GraphNodeID, port2: string, metadata: GraphEdgeMetadata): Graph {
const edge = this.getEdge(node, port, node2, port2);
if (!edge) { return; }
if (!edge) {
return this;
}

@@ -745,2 +790,3 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}

@@ -767,5 +813,5 @@

// Adding an IIP will emit a `addInitial` event.
addInitial(data: any, node: GraphNodeID, port: string, metadata: GraphIIPMetadata = {}): GraphIIP | null {
addInitial(data: any, node: GraphNodeID, port: string, metadata: GraphIIPMetadata = {}): Graph {
if (!this.getNode(node)) {
return null;
return this;
}

@@ -789,7 +835,9 @@ const portName = this.getPortName(port);

this.checkTransactionEnd();
return initializer;
return this;
}
addInitialIndex(data: any, node: GraphNodeID, port: string, index: number, metadata: GraphIIPMetadata = {}): GraphIIP | null {
if (!this.getNode(node)) { return null; }
addInitialIndex(data: any, node: GraphNodeID, port: string, index: number, metadata: GraphIIPMetadata = {}): Graph {
if (!this.getNode(node)) {
return this;
}

@@ -815,14 +863,14 @@ const indexVal = (index === null) ? undefined : index;

this.checkTransactionEnd();
return initializer;
return this;
}
addGraphInitial(data: any, node: string, metadata: GraphIIPMetadata = {}): GraphIIP | null {
addGraphInitial(data: any, node: string, metadata: GraphIIPMetadata = {}): Graph {
const inport = this.inports[node];
if (!inport) { return null; }
if (!inport) { return this; }
return this.addInitial(data, inport.process, inport.port, metadata);
}
addGraphInitialIndex(data: any, node: string, index: number, metadata: GraphIIPMetadata = {}): GraphIIP | null {
addGraphInitialIndex(data: any, node: string, index: number, metadata: GraphIIPMetadata = {}): Graph {
const inport = this.inports[node];
if (!inport) { return null; }
if (!inport) { return this; }
return this.addInitialIndex(data, inport.process, inport.port, index, metadata);

@@ -844,3 +892,3 @@ }

// Remove an IIP will emit a `removeInitial` event.
removeInitial(node: GraphNodeID, port: string) {
removeInitial(node: GraphNodeID, port: string): Graph {
const portName = this.getPortName(port);

@@ -858,8 +906,12 @@ this.checkTransactionStart();

this.checkTransactionEnd();
return this;
}
removeGraphInitial(node: string) {
removeGraphInitial(node: string): Graph {
const inport = this.inports[node];
if (!inport) { return; }
if (!inport) {
return this;
}
this.removeInitial(inport.process, inport.port);
return this;
}

@@ -1006,21 +1058,31 @@

save(file: string, callback: (err: Error | null, filename?: string) => void) {
save(file: string): Promise<string>;
save(file: string, callback: (err: Error | null, filename?: string) => void): void;
save(file: string, callback?: (err: Error | null, filename?: string) => void): void|Promise<string> {
let promise;
if (isBrowser()) {
callback(new Error('Saving graphs not supported on browser'));
promise = Promise.reject(new Error('Saving graphs not supported on browser'));
} else {
promise = new Promise<string>((resolve, reject) => {
const json = JSON.stringify(this.toJSON(), null, 4);
let filename = file;
if (!filename.match(/\.json$/)) {
filename = `${file}.json`;
}
writeFile(filename, json, 'utf-8', (err: Error | null) => {
if (err) {
reject(err);
return;
}
resolve(filename);
});
});
}
if (callback) {
promise.then((filename) => {
callback(null, filename);
}, callback);
return;
}
const json = JSON.stringify(this.toJSON(), null, 4);
let filename = file;
if (!filename.match(/\.json$/)) {
filename = `${file}.json`;
}
// eslint-disable-next-line global-require
require('fs').writeFile(filename, json, 'utf-8', (err: Error | null) => {
if (err) {
callback(err);
return;
}
callback(null, filename);
});
return promise;
}

@@ -1040,47 +1102,73 @@ }

function loadJSON(passedDefinition: string | GraphJson, callback: GraphLoadingCallback, metadata: JournalMetadata = {}) {
let definition: GraphJson;
if (typeof passedDefinition === 'string') {
definition = JSON.parse(passedDefinition);
} else {
definition = clone(passedDefinition);
}
function loadJSON(passedDefinition: string | GraphJson): Promise<Graph>;
function loadJSON(passedDefinition: string | GraphJson, callback: GraphLoadingCallback, metadata?: JournalMetadata): void;
function loadJSON(passedDefinition: string | GraphJson, callback?: GraphLoadingCallback, metadata: JournalMetadata = {}): void|Promise<Graph> {
const promise = new Promise<Graph>((resolve) => {
let definition: GraphJson;
if (typeof passedDefinition === 'string') {
definition = JSON.parse(passedDefinition);
} else {
definition = clone(passedDefinition);
}
if (!definition.properties) { definition.properties = {}; }
if (!definition.processes) { definition.processes = {}; }
if (!definition.connections) { definition.connections = []; }
if (!definition.properties) { definition.properties = {}; }
if (!definition.processes) { definition.processes = {}; }
if (!definition.connections) { definition.connections = []; }
const graph = new Graph(definition.properties.name, {
caseSensitive: definition.caseSensitive || false,
});
const graph = new Graph(definition.properties.name, {
caseSensitive: definition.caseSensitive || false,
});
graph.startTransaction('loadJSON', metadata);
const properties: PropertyMap = {};
Object.keys(definition.properties).forEach((property) => {
if (property === 'name') {
return;
}
if (!definition.properties) {
return;
}
const value: any = definition.properties[property];
properties[property] = value;
});
graph.setProperties(properties);
graph.startTransaction('loadJSON', metadata);
const properties: PropertyMap = {};
Object.keys(definition.properties).forEach((property) => {
if (property === 'name') {
return;
}
if (!definition.properties) {
return;
}
const value: any = definition.properties[property];
properties[property] = value;
});
graph.setProperties(properties);
Object.keys(definition.processes).forEach((id) => {
if (!definition.processes) {
return;
}
const def = definition.processes[id];
if (!def.metadata) { def.metadata = {}; }
graph.addNode(id, def.component, def.metadata);
});
Object.keys(definition.processes).forEach((id) => {
if (!definition.processes) {
return;
}
const def = definition.processes[id];
if (!def.metadata) { def.metadata = {}; }
graph.addNode(id, def.component, def.metadata);
});
definition.connections.forEach((conn) => {
const meta = conn.metadata ? conn.metadata : {};
if (typeof conn.data !== 'undefined') {
if (typeof conn.tgt.index === 'number') {
graph.addInitialIndex(
conn.data,
definition.connections.forEach((conn) => {
const meta = conn.metadata ? conn.metadata : {};
if (typeof conn.data !== 'undefined') {
if (typeof conn.tgt.index === 'number') {
graph.addInitialIndex(
conn.data,
conn.tgt.process,
graph.getPortName(conn.tgt.port),
conn.tgt.index,
meta,
);
} else {
graph.addInitial(
conn.data,
conn.tgt.process,
graph.getPortName(conn.tgt.port),
meta,
);
}
return;
}
if (typeof conn.src === 'undefined') {
return;
}
if ((typeof conn.src.index === 'number') || (typeof conn.tgt.index === 'number')) {
graph.addEdgeIndex(
conn.src.process,
graph.getPortName(conn.src.port),
conn.src.index,
conn.tgt.process,

@@ -1091,125 +1179,121 @@ graph.getPortName(conn.tgt.port),

);
} else {
graph.addInitial(
conn.data,
conn.tgt.process,
graph.getPortName(conn.tgt.port),
meta,
);
return;
}
return;
}
if (typeof conn.src === 'undefined') {
return;
}
if ((typeof conn.src.index === 'number') || (typeof conn.tgt.index === 'number')) {
graph.addEdgeIndex(
graph.addEdge(
conn.src.process,
graph.getPortName(conn.src.port),
conn.src.index,
conn.tgt.process,
graph.getPortName(conn.tgt.port),
conn.tgt.index,
meta,
);
return;
});
if (definition.inports) {
Object.keys(definition.inports).forEach((pub) => {
if (!definition.inports || !definition.inports[pub]) {
return;
}
const priv = definition.inports[pub];
graph.addInport(pub, priv.process, graph.getPortName(priv.port), priv.metadata || {});
});
}
graph.addEdge(
conn.src.process,
graph.getPortName(conn.src.port),
conn.tgt.process,
graph.getPortName(conn.tgt.port),
meta,
);
});
if (definition.outports) {
Object.keys(definition.outports).forEach((pub) => {
if (!definition.outports || !definition.outports[pub]) {
return;
}
const priv = definition.outports[pub];
graph.addOutport(pub, priv.process, graph.getPortName(priv.port), priv.metadata || {});
});
}
if (definition.inports) {
Object.keys(definition.inports).forEach((pub) => {
if (!definition.inports || !definition.inports[pub]) {
return;
}
const priv = definition.inports[pub];
graph.addInport(pub, priv.process, graph.getPortName(priv.port), priv.metadata || {});
});
}
if (definition.outports) {
Object.keys(definition.outports).forEach((pub) => {
if (!definition.outports || !definition.outports[pub]) {
return;
}
const priv = definition.outports[pub];
graph.addOutport(pub, priv.process, graph.getPortName(priv.port), priv.metadata || {});
});
}
if (definition.groups) {
definition.groups.forEach((group) => {
graph.addGroup(group.name, group.nodes, group.metadata || {});
});
}
if (definition.groups) {
definition.groups.forEach((group) => {
graph.addGroup(group.name, group.nodes, group.metadata || {});
});
graph.endTransaction('loadJSON');
resolve(graph);
});
if (callback) {
promise.then((graph) => {
callback(null, graph);
}, callback);
}
graph.endTransaction('loadJSON');
return callback(null, graph);
return promise;
}
function loadFBP(fbpData: string, callback: GraphLoadingCallback, metadata: JournalMetadata = {}, caseSensitive = false) {
let definition;
try {
function loadFBP(fbpData: string): Promise<Graph>;
function loadFBP(fbpData: string, callback: GraphLoadingCallback, metadata?: JournalMetadata): void;
function loadFBP(fbpData: string, callback?: GraphLoadingCallback, metadata: JournalMetadata = {}, caseSensitive = false): void|Promise<Graph> {
const promise = new Promise<GraphJson>((resolve) => {
// eslint-disable-next-line global-require
definition = require('fbp').parse(fbpData, { caseSensitive });
} catch (e) {
return callback(e);
resolve(require('fbp').parse(fbpData, { caseSensitive }));
})
.then((def) => loadJSON(def));
if (callback) {
promise.then((graph) => {
callback(null, graph);
}, callback);
}
return loadJSON(definition, callback, metadata);
return promise;
}
function loadHTTP(url: string, callback: StringLoadingCallback) {
const req = new XMLHttpRequest();
req.onreadystatechange = () => {
if (req.readyState !== 4) { return; }
if (req.status !== 200) {
callback(new Error(`Failed to load ${url}: HTTP ${req.status}`));
}
callback(null, req.responseText);
};
req.open('GET', url, true);
req.send();
function loadHTTP(url: string): Promise<string>
function loadHTTP(url: string, callback: StringLoadingCallback): void;
function loadHTTP(url: string, callback?: StringLoadingCallback): void|Promise<string> {
const promise = new Promise<string>((resolve, reject) => {
const req = new XMLHttpRequest();
req.onreadystatechange = () => {
if (req.readyState !== 4) { return; }
if (req.status !== 200) {
reject(new Error(`Failed to load ${url}: HTTP ${req.status}`));
return;
}
resolve(req.responseText);
};
req.open('GET', url, true);
req.send();
});
if (callback) {
promise.then((content) => {
callback(null, content);
}, callback);
}
return promise;
}
function loadFile(file: string, callback: GraphLoadingCallback, metadata: JournalMetadata = {}, caseSensitive = false) {
function loadFile(file: string): Promise<Graph>;
function loadFile(file: string, callback: GraphLoadingCallback, metadata?: JournalMetadata, caseSensitive?: boolean): void;
function loadFile(file: string, callback?: GraphLoadingCallback, metadata: JournalMetadata = {}, caseSensitive = false) {
let ioPromise: Promise<string>;
if (isBrowser()) {
// On browser we can try getting the file via AJAX
loadHTTP(file, (err: Error | null, data?: string) => {
if (err) {
callback(err);
return;
}
if (!data) {
callback(new Error('No data received'));
return;
}
if (file.split('.').pop() === 'fbp') {
loadFBP(data, callback, metadata);
return;
}
loadJSON(data, callback, metadata);
ioPromise = loadHTTP(file);
} else {
ioPromise = new Promise((resolve, reject) => {
// Node.js graph file
readFile(file, 'utf-8', (err: null|Error, data: string) => {
if (err) {
reject(err);
return;
}
resolve(data);
});
});
return;
}
// Node.js graph file
// eslint-disable-next-line global-require
require('fs').readFile(file, 'utf-8', (err: Error, data: string) => {
if (err) {
callback(err);
return;
}
const promise = ioPromise.then((content) => {
if (file.split('.').pop() === 'fbp') {
loadFBP(data, callback, {}, caseSensitive);
return;
return loadFBP(content);
}
loadJSON(data, callback, {});
return loadJSON(content);
});
if (callback) {
promise.then((content) => {
callback(null, content);
}, callback);
}
return promise;
}

@@ -1216,0 +1300,0 @@

@@ -529,7 +529,23 @@ // FBP Graph Journal

save(file: string, callback: (err: NodeJS.ErrnoException | null) => void) {
const json = JSON.stringify(this.toJSON(), null, 4);
const { writeFile } = require('fs');
// eslint-disable-next-line global-require
writeFile(`${file}.json`, json, 'utf-8', callback);
save(file: string): Promise<void>;
save(file: string, callback: (err: NodeJS.ErrnoException | null) => void): void;
save(file: string, callback?: (err: NodeJS.ErrnoException | null) => void): void | Promise<void> {
const promise = new Promise<void>((resolve, reject) => {
const json = JSON.stringify(this.toJSON(), null, 4);
const { writeFile } = require('fs');
writeFile(`${file}.json`, json, 'utf-8', (err: NodeJS.ErrnoException) => {
if (err) {
reject(err);
return;
}
resolve();
});
});
if (callback) {
promise.then(() => {
callback(null);
}, callback);
return;
}
return promise;
}

@@ -536,0 +552,0 @@ }

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc