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

graphology

Package Overview
Dependencies
Maintainers
1
Versions
65
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

graphology - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

6

CHANGELOG.md
# Changelog
## 0.4.0
* Adding `#.removeNodeAttribute` & `#.removeEdgeAttribute` that was actually missing from earlier versions.
* Adding graph attributes.
* `nodeUpdated` & `edgeUpdated` changing to `nodeAttributesUpdated` & `edgeAttributesUpdated` respectively.
## 0.3.0

@@ -4,0 +10,0 @@

76

dist/attributes.js

@@ -179,3 +179,3 @@ 'use strict';

function attachAttributeSetter(Class, method, key, elementName, checker, finder) {
var eventName = elementName === 'node' ? 'nodeUpdated' : 'edgeUpdated';
var eventName = elementName === 'node' ? 'nodeAttributesUpdated' : 'edgeAttributesUpdated';

@@ -247,3 +247,3 @@ /**

function attachAttributeUpdater(Class, method, key, elementName, checker, finder) {
var eventName = elementName === 'node' ? 'nodeUpdated' : 'edgeUpdated';
var eventName = elementName === 'node' ? 'nodeAttributesUpdated' : 'edgeAttributesUpdated';

@@ -306,2 +306,65 @@ /**

/**
* Attach an attribute remover method onto the provided class.
*
* @param {function} Class - Target class.
* @param {string} method - Method name.
* @param {string} key - Key of the element's storage on instance.
* @param {string} elementName - Name of target element for messages.
* @param {string} checker - Name of the checker method to use.
* @param {string} [finder] - Name of the finder method to use.
*/
function attachAttributeRemover(Class, method, key, elementName, checker, finder) {
var eventName = elementName === 'node' ? 'nodeAttributesUpdated' : 'edgeAttributesUpdated';
/**
* Remove the desired attribute for the given element (node or edge).
*
* Arity 2:
* @param {any} element - Target element.
* @param {string} name - Attribute's name.
*
* Arity 3 (only for edges):
* @param {any} source - Source element.
* @param {any} target - Target element.
* @param {string} name - Attribute's name.
*
* @return {Graph} - Returns itself for chaining.
*
* @throws {Error} - Will throw if too many arguments are provided.
* @throws {Error} - Will throw if any of the elements is not found.
*/
Class.prototype[method] = function (element, name) {
if (arguments.length > 2) {
if (!finder) throw new _errors.InvalidArgumentsGraphError('Graph.' + method + ': too many arguments provided.');
var source = element,
target = name;
name = arguments[2];
if (!this[checker](source, target)) throw new _errors.NotFoundGraphError('Graph.' + method + ': could not find an edge for the given path ("' + source + '" - "' + target + '").');
element = this[finder](source, target);
}
if (!this[checker](element)) throw new _errors.NotFoundGraphError('Graph.' + method + ': could not find the "' + element + '" ' + elementName + ' in the graph.');
var data = this[key].get(element);
delete data.attributes[name];
// Emitting
this.emit(eventName, {
key: element,
type: 'remove',
meta: {
name: name
}
});
return this;
};
}
/**
* Attach an attribute replacer method onto the provided class.

@@ -317,3 +380,3 @@ *

function attachAttributesReplacer(Class, method, key, elementName, checker, finder) {
var eventName = elementName === 'node' ? 'nodeUpdated' : 'edgeUpdated';
var eventName = elementName === 'node' ? 'nodeAttributesUpdated' : 'edgeAttributesUpdated';

@@ -386,3 +449,3 @@ /**

function attachAttributesMerger(Class, method, key, elementName, checker, finder) {
var eventName = elementName === 'node' ? 'nodeUpdated' : 'edgeUpdated';
var eventName = elementName === 'node' ? 'nodeAttributesUpdated' : 'edgeAttributesUpdated';

@@ -471,2 +534,7 @@ /**

name: function name(element) {
return 'remove' + element + 'Attribute';
},
attacher: attachAttributeRemover
}, {
name: function name(element) {
return 'replace' + element + 'Attributes';

@@ -473,0 +541,0 @@ },

@@ -250,2 +250,5 @@ 'use strict';

// Storing whether the id was generated
if (mustGenerateId) data.generatedId = true;
// Adding the edge to the internal register

@@ -366,2 +369,3 @@ graph._edges.set(edge, data);

// Indexes
(0, _utils.privateProperty)(_this, '_attributes', {});
(0, _utils.privateProperty)(_this, '_nodes', (0, _utils.createInternalMap)());

@@ -413,2 +417,162 @@ (0, _utils.privateProperty)(_this, '_edges', (0, _utils.createInternalMap)());

/**
* Method returning the desired graph's attribute.
*
* @param {string} name - Name of the attribute.
* @return {any}
*/
Graph.prototype.getAttribute = function getAttribute(name) {
return this._attributes[name];
};
/**
* Method returning the graph's attributes.
*
* @return {object}
*/
Graph.prototype.getAttributes = function getAttributes() {
return this._attributes;
};
/**
* Method returning whether the graph has the desired attribute.
*
* @param {string} name - Name of the attribute.
* @return {boolean}
*/
Graph.prototype.hasAttribute = function hasAttribute(name) {
return this._attributes.hasOwnProperty(name);
};
/**
* Method setting a value for the desired graph's attribute.
*
* @param {string} name - Name of the attribute.
* @param {any} value - Value for the attribute.
* @return {Graph}
*/
Graph.prototype.setAttribute = function setAttribute(name, value) {
this._attributes[name] = value;
// Emitting
this.emit('attributesUpdated', {
type: 'set',
meta: {
name: name,
value: value
}
});
return this;
};
/**
* Method using a function to update the desired graph's attribute's value.
*
* @param {string} name - Name of the attribute.
* @param {function} updater - Function use to update the attribute's value.
* @return {Graph}
*/
Graph.prototype.updateAttribute = function updateAttribute(name, updater) {
this._attributes[name] = updater(this._attributes[name]);
// Emitting
this.emit('attributesUpdated', {
type: 'set',
meta: {
name: name,
value: this._attributes[name]
}
});
return this;
};
/**
* Method removing the desired graph's attribute.
*
* @param {string} name - Name of the attribute.
* @return {Graph}
*/
Graph.prototype.removeAttribute = function removeAttribute(name) {
delete this._attributes[name];
// Emitting
this.emit('attributesUpdated', {
type: 'remove',
meta: {
name: name
}
});
return this;
};
/**
* Method replacing the graph's attributes.
*
* @param {object} attributes - New attributes.
* @return {Graph}
*
* @throws {Error} - Will throw if given attributes are not a plain object.
*/
Graph.prototype.replaceAttributes = function replaceAttributes(attributes) {
if (!(0, _utils.isPlainObject)(attributes)) throw new _errors.InvalidArgumentsGraphError('Graph.replaceAttributes: provided attributes are not a plain object.');
var before = this._attributes;
this._attributes = attributes;
// Emitting
this.emit('attributesUpdated', {
type: 'replace',
meta: {
before: before,
after: attributes
}
});
return this;
};
/**
* Method merging the graph's attributes.
*
* @param {object} attributes - Attributes to merge.
* @return {Graph}
*
* @throws {Error} - Will throw if given attributes are not a plain object.
*/
Graph.prototype.mergeAttributes = function mergeAttributes(attributes) {
if (!(0, _utils.isPlainObject)(attributes)) throw new _errors.InvalidArgumentsGraphError('Graph.mergeAttributes: provided attributes are not a plain object.');
this._attributes = (0, _utils.assign)(this._attributes, attributes);
// Emitting
this.emit('attributesUpdated', {
type: 'merge',
meta: {
data: attributes
}
});
return this;
};
/**
* Method returning whether the given node is found in the graph.

@@ -1504,6 +1668,12 @@ *

// Importing a serialized graph
if (!(0, _utils.isPlainObject)(data) || !data.nodes) throw new _errors.InvalidArgumentsGraphError('Graph.import: invalid argument. Expecting an object with at least a "nodes" property or, alternatively, a Graph instance.');
if (!(0, _utils.isPlainObject)(data)) throw new _errors.InvalidArgumentsGraphError('Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.');
this.importNodes(data.nodes, merge);
if (data.attributes) {
if (!(0, _utils.isPlainObject)(data.attributes)) throw new _errors.InvalidArgumentsGraphError('Graph.import: invalid attributes. Expecting a plain object.');
if (merge) this.mergeAttributes(data.attributes);else this.replaceAttributes(data.attributes);
}
if (data.nodes) this.importNodes(data.nodes, merge);
if (data.edges) this.importEdges(data.edges, merge);

@@ -1636,18 +1806,18 @@

Graph.prototype.inspect = function inspect() {
var nodes = Object.create(null);
var nodes = {};
this._nodes.forEach(function (data, key) {
nodes[key] = data.attributes;
});
this._nodes.forEach(function (value, key) {
var attributes = value.attributes;
var edges = {};
this._edges.forEach(function (data, key) {
var direction = data.undirected ? '<->' : '->';
nodes[key] = Object.keys(attributes).length ? attributes : '<empty>';
});
var label = '';
var edges = [];
this._edges.forEach(function (value, key) {
if (!data.generatedId) label += '[' + key + ']: ';
var formatted = [key, value.source, value.undirected ? '<->' : '->', value.target];
label += '(' + data.source + ')' + direction + '(' + data.target + ')';
if (Object.keys(value.attributes).length) formatted.push(value.attributes);
edges.push(formatted);
edges[label] = data.attributes;
});

@@ -1661,2 +1831,3 @@

dummy.attributes = this._attributes;
dummy.nodes = nodes;

@@ -1663,0 +1834,0 @@ dummy.edges = edges;

2

package.json
{
"name": "graphology",
"version": "0.3.0",
"version": "0.4.0",
"description": "A robust and multipurpose Graph object for JavaScript.",

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

@@ -24,3 +24,3 @@ 'use strict';

var METHODS = ['getNodeAttribute', 'getNodeAttributes', 'hasNodeAttribute', 'getEdgeAttribute', 'getEdgeAttributes', 'hasEdgeAttribute', 'setNodeAttribute', 'setEdgeAttribute', 'updateNodeAttribute', 'updateEdgeAttribute', 'replaceNodeAttributes', 'replaceEdgeAttributes', 'mergeNodeAttributes', 'mergeEdgeAttributes'];
var METHODS = ['getNodeAttribute', 'getNodeAttributes', 'hasNodeAttribute', 'getEdgeAttribute', 'getEdgeAttributes', 'hasEdgeAttribute', 'setNodeAttribute', 'setEdgeAttribute', 'updateNodeAttribute', 'updateEdgeAttribute', 'removeNodeAttribute', 'removeEdgeAttribute', 'replaceNodeAttributes', 'replaceEdgeAttributes', 'mergeNodeAttributes', 'mergeEdgeAttributes'];

@@ -61,2 +61,17 @@ function attributes(Graph, checkers) {

return (0, _helpers.deepMerge)(tests, {
'#.getAttribute': {
'it should return the correct value.': function itShouldReturnTheCorrectValue() {
var graph = new Graph();
graph.setAttribute('name', 'graph');
_assert2.default.strictEqual(graph.getAttribute('name'), 'graph');
},
'it should return undefined if the attribute does not exist.': function itShouldReturnUndefinedIfTheAttributeDoesNotExist() {
var graph = new Graph();
_assert2.default.strictEqual(graph.getAttribute('name'), undefined);
}
},
'#.getNodeAttribute': {

@@ -99,2 +114,18 @@

'#.getAttributes': {
'it should return the correct value.': function itShouldReturnTheCorrectValue() {
var graph = new Graph();
graph.setAttribute('name', 'graph');
_assert2.default.deepEqual(graph.getAttributes(), { name: 'graph' });
},
'it should return an empty object if the node does not have attributes.': function itShouldReturnAnEmptyObjectIfTheNodeDoesNotHaveAttributes() {
var graph = new Graph();
_assert2.default.deepEqual(graph.getAttributes(), {});
}
},
'#.getNodeAttributes': {

@@ -137,2 +168,19 @@

'#.hasAttribute': {
'it should correctly return whether the attribute is set.': function itShouldCorrectlyReturnWhetherTheAttributeIsSet() {
var graph = new Graph();
graph.setAttribute('name', 'graph');
_assert2.default.strictEqual(graph.hasAttribute('name'), true);
_assert2.default.strictEqual(graph.hasAttribute('info'), false);
},
'it does not fail with typical prototypal properties.': function itDoesNotFailWithTypicalPrototypalProperties() {
var graph = new Graph();
_assert2.default.strictEqual(graph.hasAttribute('toString'), false);
}
},
'#.hasNodeAttribute': {

@@ -176,2 +224,12 @@

'#.setAttribute': {
'it should correctly set the graph\'s attribute.': function itShouldCorrectlySetTheGraphSAttribute() {
var graph = new Graph();
graph.setAttribute('name', 'graph');
_assert2.default.strictEqual(graph.getAttribute('name'), 'graph');
}
},
'#.setNodeAttribute': {

@@ -202,2 +260,27 @@

'#.updateAttribute': {
'it should correctly set the graph\'s attribute.': function itShouldCorrectlySetTheGraphSAttribute() {
var graph = new Graph();
graph.setAttribute('name', 'graph');
graph.updateAttribute('name', function (name) {
return name + '1';
});
_assert2.default.strictEqual(graph.getAttribute('name'), 'graph1');
},
'the given value should be undefined if not found.': function theGivenValueShouldBeUndefinedIfNotFound() {
var graph = new Graph();
var updater = function updater(x) {
_assert2.default.strictEqual(x, undefined);
return 'graph';
};
graph.updateAttribute('name', updater);
_assert2.default.strictEqual(graph.getAttribute('name'), 'graph');
}
},
'#.updateNodeAttribute': {

@@ -261,2 +344,60 @@

'#.removeAttribute': {
'it should correctly remove the attribute.': function itShouldCorrectlyRemoveTheAttribute() {
var graph = new Graph();
graph.setAttribute('name', 'graph');
graph.removeAttribute('name');
_assert2.default.strictEqual(graph.hasAttribute('name'), false);
_assert2.default.deepEqual(graph.getAttributes(), {});
}
},
'#.removeNodeAttribute': {
'it should correctly remove the attribute.': function itShouldCorrectlyRemoveTheAttribute() {
var graph = new Graph();
graph.addNode('Martha', { age: 34 });
graph.removeNodeAttribute('Martha', 'age');
_assert2.default.strictEqual(graph.hasNodeAttribute('Martha', 'age'), false);
_assert2.default.deepEqual(graph.getNodeAttributes('Martha'), {});
}
},
'#.removeEdgeAttribute': {
'it should correclty remove the attribute.': function itShouldCorrecltyRemoveTheAttribute() {
var graph = new Graph();
var edge = graph.mergeEdge('John', 'Martha', { weight: 1, size: 3 });
graph.removeEdgeAttribute('John', 'Martha', 'weight');
graph.removeEdgeAttribute(edge, 'size');
_assert2.default.strictEqual(graph.hasEdgeAttribute(edge, 'weight'), false);
_assert2.default.strictEqual(graph.hasEdgeAttribute(edge, 'size'), false);
_assert2.default.deepEqual(graph.getEdgeAttributes(edge), {});
}
},
'#.replaceAttribute': {
'it should throw if given attributes are not a plain object.': function itShouldThrowIfGivenAttributesAreNotAPlainObject() {
var graph = new Graph();
_assert2.default.throws(function () {
graph.replaceAttributes(true);
}, invalid());
},
'it should correctly replace attributes.': function itShouldCorrectlyReplaceAttributes() {
var graph = new Graph();
graph.setAttribute('name', 'graph');
graph.replaceAttributes({ name: 'other graph' });
_assert2.default.deepEqual(graph.getAttributes(), { name: 'other graph' });
}
},
'#.replaceNodeAttributes': {

@@ -304,2 +445,21 @@ 'it should throw if given attributes are not a plain object.': function itShouldThrowIfGivenAttributesAreNotAPlainObject() {

'#.mergeAttributes': {
'it should throw if given attributes are not a plain object.': function itShouldThrowIfGivenAttributesAreNotAPlainObject() {
var graph = new Graph();
_assert2.default.throws(function () {
graph.mergeAttributes(true);
}, invalid());
},
'it should correctly merge attributes.': function itShouldCorrectlyMergeAttributes() {
var graph = new Graph();
graph.setAttribute('name', 'graph');
graph.mergeAttributes({ color: 'blue' });
_assert2.default.deepEqual(graph.getAttributes(), { name: 'graph', color: 'blue' });
}
},
'#.mergeNodeAttributes': {

@@ -306,0 +466,0 @@ 'it should throw if given attributes are not a plain object.': function itShouldThrowIfGivenAttributesAreNotAPlainObject() {

@@ -22,3 +22,3 @@ 'use strict';

*/
var VALID_TYPES = new Set(['set', 'merge', 'replace']);
var VALID_TYPES = new Set(['set', 'merge', 'replace', 'remove']);

@@ -119,3 +119,3 @@ function events(Graph) {

'nodeUpdated': {
'nodeAttributesUpdated': {
'it should fire when a node is updated.': function itShouldFireWhenANodeIsUpdated() {

@@ -140,2 +140,4 @@ var graph = new Graph();

_assert2.default.deepEqual(meta.after, { age: 56 });
} else if (type === 'remove') {
_assert2.default.strictEqual(meta.name, 'eyes');
} else {

@@ -146,3 +148,3 @@ _assert2.default.deepEqual(meta.data, { eyes: 'blue' });

graph.on('nodeUpdated', handler);
graph.on('nodeAttributesUpdated', handler);

@@ -153,8 +155,9 @@ graph.addNode('John');

graph.mergeNodeAttributes('John', { eyes: 'blue' });
graph.removeNodeAttribute('John', 'eyes');
_assert2.default.strictEqual(handler.times, 3);
_assert2.default.strictEqual(handler.times, 4);
}
},
'edgeUpdated': {
'edgeAttributesUpdated': {
'it should fire when a node is updated.': function itShouldFireWhenANodeIsUpdated() {

@@ -179,2 +182,4 @@ var graph = new Graph();

_assert2.default.deepEqual(meta.after, { weight: 56 });
} else if (type === 'remove') {
_assert2.default.strictEqual(meta.name, 'type');
} else {

@@ -185,3 +190,3 @@ _assert2.default.deepEqual(meta.data, { type: 'KNOWS' });

graph.on('edgeUpdated', handler);
graph.on('edgeAttributesUpdated', handler);

@@ -193,4 +198,5 @@ graph.addNodesFrom(['John', 'Thomas']);

graph.mergeEdgeAttributes('J->T', { type: 'KNOWS' });
graph.removeEdgeAttribute('J->T', 'type');
_assert2.default.strictEqual(handler.times, 3);
_assert2.default.strictEqual(handler.times, 4);
}

@@ -197,0 +203,0 @@ }

@@ -374,6 +374,2 @@ 'use strict';

}, invalid());
_assert2.default.throws(function () {
graph.import({ hello: 'world' });
}, invalid());
},

@@ -402,2 +398,26 @@

_assert2.default.strictEqual(graph.hasEdge('John', 'Thomas'), true);
},
'it should be possible to import only edges when merging.': function itShouldBePossibleToImportOnlyEdgesWhenMerging() {
var graph = new Graph();
graph.import({
edges: [{ source: 'John', target: 'Thomas' }]
}, true);
_assert2.default.deepEqual(graph.nodes(), ['John', 'Thomas']);
_assert2.default.strictEqual(graph.size, 1);
_assert2.default.strictEqual(graph.hasEdge('John', 'Thomas'), true);
},
'it should be possible to import attributes.': function itShouldBePossibleToImportAttributes() {
var graph = new Graph();
graph.import({
attributes: {
name: 'graph'
}
});
_assert2.default.deepEqual(graph.getAttributes(), { name: 'graph' });
}

@@ -404,0 +424,0 @@ },

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