Socket
Socket
Sign inDemoInstall

linkd

Package Overview
Dependencies
4
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.0.1 to 2.0.0

1226

lib/Linkd.js
!function() {
'use strict';
'use strict';

@@ -7,7 +7,7 @@

var Class = require('ee-class')
, log = require('ee-log')
, EventEmitter = require('ee-event-emitter')
, Node = require('./Node')
;
const log = require('ee-log');
const EventEmitter = require('ee-event-emitter');
const Node = require('./Node');

@@ -18,19 +18,15 @@

/**
* A fast and extendable doubly linked list.
*/
/**
* A fast and extendable doubly linked list.
*/
var classDefinition = {
inherits: EventEmitter
module.exports = class Linkd extends EventEmitter {
// the lenght property returns how many items are currently
// stored in the linked list
, length: {
get: function() {return this.map.size;}
, set: function() {throw new Error('The length property is readonly!')}
}
// the lenght property returns how many items are currently
// stored in the linked list
get length() {return this.map.size;}

@@ -41,66 +37,67 @@

/**
* initilize the linked list, set up storage and pointer. class constructor.
*
* @param {CustomNodeType} CustomNodeType A custom item implementation
* used for storing items
*/
, init: function(CustomType) {
/**
* initilize the linked list, set up storage and pointer. class constructor.
*
* @param {CustomNodeType} CustomNodeType A custom item implementation
* used for storing items
*/
constructor(CustomType) {
super();
// the map hoofding the linked list
Class.define(this, 'map', Class(new Map()).Writable());
// the map hoofding the linked list
Class.define(this, 'map', Class(new Map()).Writable());
// reference to the first item
Class.define(this, 'firsNode', Class(null).Writable().Configurable());
// reference to the first item
Class.define(this, 'firsNode', Class(null).Writable().Configurable());
// reference to the last item
Class.define(this, 'lastNode', Class(null).Writable().Configurable());
// reference to the last item
Class.define(this, 'lastNode', Class(null).Writable().Configurable());
// the user may pass a custom type for the map items
if (CustomType){
if (new CustomType().identifier === Node.identifier) throw new Error('The custom type must inherit from the LinkedList.Node class!');
Class.define(this, 'Node', Class(CustomType));
}
else {
Class.define(this, 'Node', Class(Node));
}
// the user may pass a custom type for the map items
if (CustomType){
if (new CustomType().identifier === Node.identifier) throw new Error('The custom type must inherit from the LinkedList.Node class!');
Class.define(this, 'Node', Class(CustomType));
}
else {
Class.define(this, 'Node', Class(Node));
}
// emit the drain event if the list is empty
this.on('remove', () => {
if (!this.length) this.emit('drain');
})
}
// emit the drain event if the list is empty
this.on('remove', () => {
if (!this.length) this.emit('drain');
})
}
/**
* returns a node by its hash or null if the
* node was not found
*
* @private
* @param {*} hash a hash identifying an item, may be of any type
* @returns {node|null} node or null
*/
, _getNode: function(hash) {
return this.has(hash) ? this.map.get(hash) : null;
}
/**
* returns a node by its hash or null if the
* node was not found
*
* @private
* @param {*} hash a hash identifying an item, may be of any type
* @returns {node|null} node or null
*/
_getNode(hash) {
return this.has(hash) ? this.map.get(hash) : null;
}
/**
* returns an item by its hash or undefined if the
* item was not found.
*
* @param {*} hash a hash identifying an item, may be of any type
* @returns {*|undefined} value value of any type
*/
, get: function(hash) {
var node = this.getNode(hash);
/**
* returns an item by its hash or undefined if the
* item was not found.
*
* @param {*} hash a hash identifying an item, may be of any type
* @returns {*|undefined} value value of any type
*/
get(hash) {
let node = this.getNode(hash);
return node ? node.value : undefined;
}
return node ? node.value : undefined;
}

@@ -110,21 +107,21 @@

/**
* returns a node by its hash or null if the
* node was not found
*
* @param {*} hash a hash identifying an item, may be of any type
* @returns {node|null} node or null
*/
, getNode: function(hash) {
var node = this._getNode(hash);
/**
* returns a node by its hash or null if the
* node was not found
*
* @param {*} hash a hash identifying an item, may be of any type
* @returns {node|null} node or null
*/
getNode(hash) {
let node = this._getNode(hash);
if (node) {
// emit events
this.emit('get', node.value);
this.emit('getNode', node);
if (node) {
// emit events
this.emit('get', node.value);
this.emit('getNode', node);
return node;
}
else return null;
}
return node;
}
else return null;
}

@@ -134,45 +131,45 @@

/**
* returns the first item or undefined
*
*
*
* @returns {*|undefined} item or undefined
*/
, getFirst: function(noEvents) {
return this.firstNode ? this.getFirstNode(noEvents).value : undefined;
}
/**
* returns the first item or undefined
*
*
*
* @returns {*|undefined} item or undefined
*/
getFirst(noEvents) {
return this.firstNode ? this.getFirstNode(noEvents).value : undefined;
}
/**
* returns the last item or undefined
*
* @returns {*|undefined} item or undefined
*/
, getLast: function(noEvents) {
return this.lastNode ? this.getLastNode(noEvents).value : undefined;
}
/**
* returns the last item or undefined
*
* @returns {*|undefined} item or undefined
*/
getLast(noEvents) {
return this.lastNode ? this.getLastNode(noEvents).value : undefined;
}
/**
* returns the first node or null
*
* @returns {Node|null} node or null
*/
, getFirstNode: function(noEvents) {
return this.firstNode ? (noEvents ? this._getNode(this.firstNode.hash) : this.getNode(this.firstNode.hash)) : null;
}
/**
* returns the first node or null
*
* @returns {Node|null} node or null
*/
getFirstNode(noEvents) {
return this.firstNode ? (noEvents ? this._getNode(this.firstNode.hash) : this.getNode(this.firstNode.hash)) : null;
}
/**
* returns the last node or null
*
* @returns {Node|null} item or null
*/
, getLastNode: function(noEvents) {
return this.lastNode ? (noEvents ? this._getNode(this.lastNode.hash) : this.getNode(this.lastNode.hash)) : null;
}
/**
* returns the last node or null
*
* @returns {Node|null} item or null
*/
getLastNode(noEvents) {
return this.lastNode ? (noEvents ? this._getNode(this.lastNode.hash) : this.getNode(this.lastNode.hash)) : null;
}

@@ -183,11 +180,11 @@

/**
* checks if a certain hash is present in the linked list
*
* @param {*} hash a hash identifying an item, may be of any type
* @returns {bool} true if the hash was found inside the list
*/
, has: function(hash) {
return this.map.has(hash);
}
/**
* checks if a certain hash is present in the linked list
*
* @param {*} hash a hash identifying an item, may be of any type
* @returns {bool} true if the hash was found inside the list
*/
has(hash) {
return this.map.has(hash);
}

@@ -197,125 +194,125 @@

/**
* Moves an item so that its placed after another item
*
* @param {*|Node} hash the hash of the item to move or the node
* @param {*|Node} afterHash the hash to move the item after or the node
*
* @returns {Node} the node that was moved
*/
, moveAfter: function(hash, afterHash) {
var node;
/**
* Moves an item so that its placed after another item
*
* @param {*|Node} hash the hash of the item to move or the node
* @param {*|Node} afterHash the hash to move the item after or the node
*
* @returns {Node} the node that was moved
*/
moveAfter(hash, afterHash) {
let node;
// check the input
if (hash instanceof this.Node) hash = hash.hash;
if (afterHash instanceof this.Node) afterHash = afterHash.hash;
// check the input
if (hash instanceof this.Node) hash = hash.hash;
if (afterHash instanceof this.Node) afterHash = afterHash.hash;
// the items need to exist
if (this.has(hash)) {
if (this.has(afterHash)) {
// remove the node
node = this._removeNode(hash);
// the items need to exist
if (this.has(hash)) {
if (this.has(afterHash)) {
// remove the node
node = this._removeNode(hash);
// addd again
this._addAfter(node, afterHash);
// addd again
this._addAfter(node, afterHash);
// return the node
return node;
}
else throw new Error('The node cannot be moved after the node with the hash «'+hash+'». It could not be found!');
}
else throw new Error('The node cannot be moved, the hash «'+hash+'» could not be found!');
}
// return the node
return node;
}
else throw new Error('The node cannot be moved after the node with the hash «'+hash+'». It could not be found!');
}
else throw new Error('The node cannot be moved, the hash «'+hash+'» could not be found!');
}
/**
* Moves an item so that its placed before another item
*
* @param {*|Node} hash the hash of the item to move or the node
* @param {*|Node} beforeHash the hash to move the item before or the node
*
* @returns {Node} the node that was moved
*/
, moveBefore: function(hash, beforeHash) {
var node;
/**
* Moves an item so that its placed before another item
*
* @param {*|Node} hash the hash of the item to move or the node
* @param {*|Node} beforeHash the hash to move the item before or the node
*
* @returns {Node} the node that was moved
*/
moveBefore(hash, beforeHash) {
let node;
// check the input
if (hash instanceof this.Node) hash = hash.hash;
if (beforeHash instanceof this.Node) beforeHash = beforeHash.hash;
// check the input
if (hash instanceof this.Node) hash = hash.hash;
if (beforeHash instanceof this.Node) beforeHash = beforeHash.hash;
// the items need to exist
if (this.has(hash)) {
if (this.has(beforeHash)) {
// remove the node
node = this._removeNode(hash);
// the items need to exist
if (this.has(hash)) {
if (this.has(beforeHash)) {
// remove the node
node = this._removeNode(hash);
// addd again
this._addBefore(node, beforeHash);
// addd again
this._addBefore(node, beforeHash);
// return the node
return node;
}
else throw new Error('The node cannot be moved after the node with the hash «'+hash+'». It could not be found!');
}
else throw new Error('The node cannot be moved, the hash «'+hash+'» could not be found!');
}
// return the node
return node;
}
else throw new Error('The node cannot be moved after the node with the hash «'+hash+'». It could not be found!');
}
else throw new Error('The node cannot be moved, the hash «'+hash+'» could not be found!');
}
/**
* Moves an item so that its placed at the beginning of the list
*
* @param {*|Node} hash the hash of the item to move or the node
*
* @returns {Node} the node that was moved
*/
, moveToBegin: function(hash) {
var node;
/**
* Moves an item so that its placed at the beginning of the list
*
* @param {*|Node} hash the hash of the item to move or the node
*
* @returns {Node} the node that was moved
*/
moveToBegin(hash) {
let node;
// check the input
if (hash instanceof this.Node) hash = hash.hash;
// check the input
if (hash instanceof this.Node) hash = hash.hash;
// the items need to exist
if (this.has(hash)) {
// remove the node
node = this._removeNode(hash);
// the items need to exist
if (this.has(hash)) {
// remove the node
node = this._removeNode(hash);
// addd again
this._push(node);
// addd again
this._push(node);
// return the node
return node;
}
else throw new Error('The node cannot be moved, the hash «'+hash+'» could not be found!');
}
// return the node
return node;
}
else throw new Error('The node cannot be moved, the hash «'+hash+'» could not be found!');
}
/**
* Moves an item so that its placed at the beginning of the list
*
* @param {*|Node} hash the hash of the item to move or the node
*
* @returns {Node} the node that was moved
*/
, moveToEnd: function(hash) {
var node;
/**
* Moves an item so that its placed at the beginning of the list
*
* @param {*|Node} hash the hash of the item to move or the node
*
* @returns {Node} the node that was moved
*/
moveToEnd(hash) {
let node;
// check the input
if (hash instanceof this.Node) hash = hash.hash;
// check the input
if (hash instanceof this.Node) hash = hash.hash;
// the items need to exist
if (this.has(hash)) {
// remove the node
node = this._removeNode(hash);
// the items need to exist
if (this.has(hash)) {
// remove the node
node = this._removeNode(hash);
// addd again
this._unshift(node);
// addd again
this._unshift(node);
// return the node
return node;
}
else throw new Error('The node cannot be moved, the hash «'+hash+'» could not be found!');
}
// return the node
return node;
}
else throw new Error('The node cannot be moved, the hash «'+hash+'» could not be found!');
}

@@ -325,116 +322,116 @@

/**
* add an element after another item in the list
*
* @param {*|node} hash a hash identifying an item, may be of any type or a node
* @param {*} the value to store. undefiend is the only unacceptable
* @param {*} hash the hash of the item this should be placed after
* value
* @returns {Node} the noded added
*/
, addAfter: function(hash, value, afterHash) {
/**
* add an element after another item in the list
*
* @param {*|node} hash a hash identifying an item, may be of any type or a node
* @param {*} the value to store. undefiend is the only unacceptable
* @param {*} hash the hash of the item this should be placed after
* value
* @returns {Node} the noded added
*/
addAfter(hash, value, afterHash) {
var node = this._addAfter(hash, value, afterHash);
let node = this._addAfter(hash, value, afterHash);
// emit events
this.emit('add', node.value);
this.emit('addNode', node);
this.emit('addAfter', node.value);
this.emit('addAfterNode', node);
// emit events
this.emit('add', node.value);
this.emit('addNode', node);
this.emit('addAfter', node.value);
this.emit('addAfterNode', node);
return node;
}
return node;
}
/**
* add an element after another item in the list
*
* @private
* @param {*|node} hash a hash identifying an item, may be of any type or a node
* @param {*} the value to store. undefiend is the only unacceptable
* @param {*} hash the hash of the item this should be placed after
* value
* @returns {Linkd} this
*/
, _addAfter: function(hash, value, afterHash) {
var node, afterNode, existingNode = false;
/**
* add an element after another item in the list
*
* @private
* @param {*|node} hash a hash identifying an item, may be of any type or a node
* @param {*} the value to store. undefiend is the only unacceptable
* @param {*} hash the hash of the item this should be placed after
* value
* @returns {Linkd} this
*/
_addAfter(hash, value, afterHash) {
let node, afterNode, existingNode = false;
// clean up variables
if (hash instanceof this.Node) {
node = hash;
hash = node.hash;
afterHash = value;
existingNode = true;
}
// clean up letiables
if (hash instanceof this.Node) {
node = hash;
hash = node.hash;
afterHash = value;
existingNode = true;
}
// convert nodes to hashes
if (afterHash instanceof this.Node) afterHash = afterHash.hash;
// convert nodes to hashes
if (afterHash instanceof this.Node) afterHash = afterHash.hash;
// the node to insert after needds to exits!
if (!this.has(afterHash)) throw new Error('Cannot add node after hash «'+afterHash+'», the node referenced node does not exist!');
else afterNode = this.map.get(afterHash);
// the node to insert after needds to exits!
if (!this.has(afterHash)) throw new Error('Cannot add node after hash «'+afterHash+'», the node referenced node does not exist!');
else afterNode = this.map.get(afterHash);
// set up node
if (existingNode) {
node.nextNode = afterNode;
node.previousNode = null;
}
else node = new this.Node(hash, value, null, afterNode);
// set up node
if (existingNode) {
node.nextNode = afterNode;
node.previousNode = null;
}
else node = new this.Node(hash, value, null, afterNode);
// remove existing instances
if (this.has(hash)) this._removeNode(hash);
// remove existing instances
if (this.has(hash)) this._removeNode(hash);
// store the node
this.map.set(hash, node);
// store the node
this.map.set(hash, node);
// set this node between the afterNode and its previous node
if (afterNode.previousNode) {
afterNode.previousNode.nextNode = node;
node.previousNode = afterNode.previousNode;
}
else {
// this is the last node
this.lastNode = node;
}
// set this node between the afterNode and its previous node
if (afterNode.previousNode) {
afterNode.previousNode.nextNode = node;
node.previousNode = afterNode.previousNode;
}
else {
// this is the last node
this.lastNode = node;
}
// set link
afterNode.previousNode = node;
// set link
afterNode.previousNode = node;
// return this class for daisy chaning
return node;
}
// return this class for daisy chaning
return node;
}
/**
* add an element before another item in the list
*
* @param {*|node} hash a hash identifying an item, may be of any type or a node
* @param {*} the value to store. undefiend is the only unacceptable
* @param {*} hash the hash of the item this should be placed before
* value
* @returns {Linkd} this
*/
, addBefore: function(hash, value, beforeHash) {
/**
* add an element before another item in the list
*
* @param {*|node} hash a hash identifying an item, may be of any type or a node
* @param {*} the value to store. undefiend is the only unacceptable
* @param {*} hash the hash of the item this should be placed before
* value
* @returns {Linkd} this
*/
addBefore(hash, value, beforeHash) {
var node = this._addBefore(hash, value, beforeHash);
let node = this._addBefore(hash, value, beforeHash);
// emit events
this.emit('add', node.value);
this.emit('addNode', node);
this.emit('addBefore', node.value);
this.emit('addBeforeNode', node);
// emit events
this.emit('add', node.value);
this.emit('addNode', node);
this.emit('addBefore', node.value);
this.emit('addBeforeNode', node);
return this;
}
return this;
}

@@ -446,67 +443,67 @@

/**
* add an element before another item in the list
* @private
* @param {*|node} hash a hash identifying an item, may be of any type or a node
* @param {*} the value to store. undefiend is the only unacceptable
* @param {*} hash the hash of the item this should be placed before
* value
* @returns {Linkd} this
*/
, _addBefore: function(hash, value, beforeHash) {
var node, beforeNode, existingNode = false;
/**
* add an element before another item in the list
* @private
* @param {*|node} hash a hash identifying an item, may be of any type or a node
* @param {*} the value to store. undefiend is the only unacceptable
* @param {*} hash the hash of the item this should be placed before
* value
* @returns {Linkd} this
*/
_addBefore(hash, value, beforeHash) {
let node, beforeNode, existingNode = false;
// clean up variables
if (hash instanceof this.Node) {
node = hash;
hash = node.hash;
beforeHash = value;
existingNode = true;
}
// clean up letiables
if (hash instanceof this.Node) {
node = hash;
hash = node.hash;
beforeHash = value;
existingNode = true;
}
// convert nodes to hashes
if (beforeHash instanceof this.Node) beforeHash = beforeHash.hash;
// convert nodes to hashes
if (beforeHash instanceof this.Node) beforeHash = beforeHash.hash;
// the node to insert before needds to exits!
if (!this.has(beforeHash)) throw new Error('Cannot add node before hash «'+beforeHash+'», the node referenced node does not exist!');
else beforeNode = this.map.get(beforeHash);
// the node to insert before needds to exits!
if (!this.has(beforeHash)) throw new Error('Cannot add node before hash «'+beforeHash+'», the node referenced node does not exist!');
else beforeNode = this.map.get(beforeHash);
// set up node
if (existingNode) {
node.nextNode = null;
node.previousNode = beforeNode;
}
else node = new this.Node(hash, value, beforeNode);
// set up node
if (existingNode) {
node.nextNode = null;
node.previousNode = beforeNode;
}
else node = new this.Node(hash, value, beforeNode);
// remove existing instances
if (this.has(hash)) this._removeNode(hash);
// remove existing instances
if (this.has(hash)) this._removeNode(hash);
// store the node
this.map.set(hash, node);
// store the node
this.map.set(hash, node);
// set this node between the beforeNode and its previous node
if (beforeNode.nextNode) {
beforeNode.nextNode.previousNode = node;
node.nextNode = beforeNode.nextNode;
}
else {
// this is the first node
this.firstNode = node;
}
// set this node between the beforeNode and its previous node
if (beforeNode.nextNode) {
beforeNode.nextNode.previousNode = node;
node.nextNode = beforeNode.nextNode;
}
else {
// this is the first node
this.firstNode = node;
}
// set link
beforeNode.nextNode = node;
// set link
beforeNode.nextNode = node;
// return this class for daisy chaning
return node;
}
// return this class for daisy chaning
return node;
}

@@ -516,22 +513,22 @@

/**
* add an element to the beginning of the list
*
* @param {*|node} hash a hash identifying an item, may be of any type or a node
* @param {*} the value to store. undefiend is the only unacceptable
* value
* @returns {Node} the created node
*/
, push: function(hash, value) {
/**
* add an element to the beginning of the list
*
* @param {*|node} hash a hash identifying an item, may be of any type or a node
* @param {*} the value to store. undefiend is the only unacceptable
* value
* @returns {Node} the created node
*/
push(hash, value) {
var node = this._push(hash, value);
let node = this._push(hash, value);
// emit events
this.emit('add', node.value);
this.emit('addNode', node);
this.emit('push', node.value);
this.emit('pushNode', node);
// emit events
this.emit('add', node.value);
this.emit('addNode', node);
this.emit('push', node.value);
this.emit('pushNode', node);
return node;
}
return node;
}

@@ -541,39 +538,39 @@

/**
* add an element to the beginning of the list
*
* @private
* @param {*|node} hash a hash identifying an item, may be of any type or a node
* @param {*} the value to store. undefiend is the only unacceptable
* value
* @returns {Node} the created node
*/
, _push: function(hash, value) {
var node;
/**
* add an element to the beginning of the list
*
* @private
* @param {*|node} hash a hash identifying an item, may be of any type or a node
* @param {*} the value to store. undefiend is the only unacceptable
* value
* @returns {Node} the created node
*/
_push(hash, value) {
let node;
// set up node
if (hash instanceof this.Node) {
node = hash;
hash = node.hash;
// set up node
if (hash instanceof this.Node) {
node = hash;
hash = node.hash;
node.nextNode = null;
node.previousNode = this.firstNode;
}
else node = new this.Node(hash, value, this.firstNode);
node.nextNode = null;
node.previousNode = this.firstNode;
}
else node = new this.Node(hash, value, this.firstNode);
// remove existing instances
if (this.has(hash)) this._removeNode(hash);
// remove existing instances
if (this.has(hash)) this._removeNode(hash);
// store the node
this.map.set(hash, node);
// store the node
this.map.set(hash, node);
// set myself as nextnode
if (this.firstNode) this.firstNode.nextNode = node;
// set myself as nextnode
if (this.firstNode) this.firstNode.nextNode = node;
// set as first node
this.firstNode = node;
// set as first node
this.firstNode = node;

@@ -585,5 +582,5 @@

// return this class for daisy chaning
return node;
}
// return this class for daisy chaning
return node;
}

@@ -593,22 +590,22 @@

/**
* add an element to the end of the list
*
* @param {*} hash a hash identifying an item, may be of any type
* @param {any} the value to store. undefiend is the only unacceptable
* value
* @returns {Node} the created node
*/
, unshift: function(hash, value) {
/**
* add an element to the end of the list
*
* @param {*} hash a hash identifying an item, may be of any type
* @param {any} the value to store. undefiend is the only unacceptable
* value
* @returns {Node} the created node
*/
unshift(hash, value) {
var node = this._unshift(hash, value);
let node = this._unshift(hash, value);
// emit events
this.emit('add', node.value);
this.emit('addNode', node);
this.emit('unshift', node.value);
this.emit('unshiftNode', node);
// emit events
this.emit('add', node.value);
this.emit('addNode', node);
this.emit('unshift', node.value);
this.emit('unshiftNode', node);
return node;
}
return node;
}

@@ -619,39 +616,39 @@

/**
* add an element to the end of the list
*
* @private
* @param {*} hash a hash identifying an item, may be of any type
* @param {any} the value to store. undefiend is the only unacceptable
* value
* @returns {Node} the created node
*/
, _unshift: function(hash, value) {
var node;
/**
* add an element to the end of the list
*
* @private
* @param {*} hash a hash identifying an item, may be of any type
* @param {any} the value to store. undefiend is the only unacceptable
* value
* @returns {Node} the created node
*/
_unshift(hash, value) {
let node;
// set up node
if (hash instanceof this.Node) {
node = hash;
hash = node.hash;
// set up node
if (hash instanceof this.Node) {
node = hash;
hash = node.hash;
node.nextNode = this.lastNode;
node.previousNode = null;
}
else node = new this.Node(hash, value, null, this.lastNode);
node.nextNode = this.lastNode;
node.previousNode = null;
}
else node = new this.Node(hash, value, null, this.lastNode);
// remove existing instances
if (this.has(hash)) this._removeNode(hash);
// remove existing instances
if (this.has(hash)) this._removeNode(hash);
// store the node
this.map.set(hash, node);
// store the node
this.map.set(hash, node);
// set myself as nextnode
if (this.lastNode) this.lastNode.previousNode = node;
// set myself as nextnode
if (this.lastNode) this.lastNode.previousNode = node;
// set as first node
this.lastNode = node;
// set as first node
this.lastNode = node;

@@ -662,5 +659,5 @@

// return this class for daisy chaning
return node;
}
// return this class for daisy chaning
return node;
}

@@ -670,37 +667,37 @@

/**
* remove an element from the beginning of the list
*
* @returns {Node} the removed node
*/
, popNode: function() {
var node;
/**
* remove an element from the beginning of the list
*
* @returns {Node} the removed node
*/
popNode() {
let node;
if (this.firstNode) {
node = this._removeNode(this.firstNode.hash);
if (this.firstNode) {
node = this._removeNode(this.firstNode.hash);
if (node) {
this.emit('remove', node.value);
this.emit('removeNode', node);
this.emit('pop', node.value);
this.emit('popNode', node);
}
if (node) {
this.emit('remove', node.value);
this.emit('removeNode', node);
this.emit('pop', node.value);
this.emit('popNode', node);
}
return node;
}
return undefined;
}
return node;
}
return undefined;
}
/**
* remove an element from the beginning of the list
*
* @returns {*} the removed item
*/
, pop: function() {
var node = this.popNode();
/**
* remove an element from the beginning of the list
*
* @returns {*} the removed item
*/
pop() {
let node = this.popNode();
return node ? node.value : node;
}
return node ? node.value : node;
}

@@ -710,24 +707,24 @@

/**
* remove an element from the beginning of the list
*
* @returns {Node} the removed item
*/
, shiftNode: function() {
var node;
/**
* remove an element from the beginning of the list
*
* @returns {Node} the removed item
*/
shiftNode() {
let node;
if (this.lastNode) {
node = this._removeNode(this.lastNode.hash);
if (this.lastNode) {
node = this._removeNode(this.lastNode.hash);
if (node) {
this.emit('remove', node.value);
this.emit('removeNode', node);
this.emit('shift', node.value);
this.emit('shiftNode', node);
}
if (node) {
this.emit('remove', node.value);
this.emit('removeNode', node);
this.emit('shift', node.value);
this.emit('shiftNode', node);
}
return node;
}
return undefined;
}
return node;
}
return undefined;
}

@@ -737,12 +734,12 @@

/**
* remove an element from the beginning of the list
*
* @returns {*} the removed item
*/
, shift: function() {
var node = this.shiftNode();
/**
* remove an element from the beginning of the list
*
* @returns {*} the removed item
*/
shift() {
let node = this.shiftNode();
return node ? node.value : node;
}
return node ? node.value : node;
}

@@ -754,21 +751,21 @@

/**
* remove an element from the list
*
* @param {*|Node} hash a hash identifying an item, may be of any type or node
* @returns {Node} the removed node
*/
, removeNode: function(hash) {
var node;
/**
* remove an element from the list
*
* @param {*|Node} hash a hash identifying an item, may be of any type or node
* @returns {Node} the removed node
*/
removeNode(hash) {
let node;
if (hash instanceof this.Node) node = this._removeNode(hash.hash);
else node = this._removeNode(hash);
if (hash instanceof this.Node) node = this._removeNode(hash.hash);
else node = this._removeNode(hash);
if (node) {
this.emit('remove', node.value);
this.emit('removeNode', node);
}
if (node) {
this.emit('remove', node.value);
this.emit('removeNode', node);
}
return node;
}
return node;
}

@@ -779,13 +776,13 @@

/**
* remove an element from the list
*
* @param {*|Node} hash a hash identifying an item, may be of any type or node
* @returns {*} the removed item
*/
, remove: function(hash) {
var node = this.removeNode(hash);
/**
* remove an element from the list
*
* @param {*|Node} hash a hash identifying an item, may be of any type or node
* @returns {*} the removed item
*/
remove(hash) {
let node = this.removeNode(hash);
return node ? node.value : node;
}
return node ? node.value : node;
}

@@ -796,10 +793,10 @@

/**
* returns all the hashes that are stored in the list
*
* @returns {Iterable*} with all hashes
*/
, keys: function() {
return this.map.keys();
}
/**
* returns all the hashes that are stored in the list
*
* @returns {Iterable*} with all hashes
*/
keys() {
return this.map.keys();
}

@@ -809,18 +806,18 @@

/**
* clears all values from the linked list, re-initilizes
* the class isntance
*/
, clear: function() {
/**
* clears all values from the linked list, re-initilizes
* the class isntance
*/
clear() {
// create a new map
Class.define(this, 'map', Class(new Map()).Writable());
// create a new map
Class.define(this, 'map', Class(new Map()).Writable());
// clear nodes
this.lastNode = null;
this.firstNode = null;
// clear nodes
this.lastNode = null;
this.firstNode = null;
this.emit('clear');
}
this.emit('clear');
}

@@ -830,51 +827,50 @@

/**
* removes a node from the lsit
*
* @private
* @param {*} hash the hash of the node to remove
* @returns {Node} node
*/
, _removeNode: function(hash) {
var toBeRemovedNode = this.map.has(hash) ? this.map.get(hash) : null;
/**
* removes a node from the lsit
*
* @private
* @param {*} hash the hash of the node to remove
* @returns {Node} node
*/
_removeNode(hash) {
let toBeRemovedNode = this.map.has(hash) ? this.map.get(hash) : null;
if (toBeRemovedNode) {
if (toBeRemovedNode.nextNode) {
if (toBeRemovedNode.previousNode) {
// this node is in between of two nodes
toBeRemovedNode.nextNode.previousNode = toBeRemovedNode.previousNode;
toBeRemovedNode.previousNode.nextNode = toBeRemovedNode.nextNode;
}
else {
// this is the last node
toBeRemovedNode.nextNode.previousNode = null;
this.lastNode = toBeRemovedNode.nextNode;
}
}
else {
if (toBeRemovedNode.previousNode) {
// this is the first node
toBeRemovedNode.previousNode.nextNode = null;
this.firstNode = toBeRemovedNode.previousNode;
}
else {
// this was the last node
this.lastNode = null;
this.firstNode = null;
}
}
if (toBeRemovedNode) {
if (toBeRemovedNode.nextNode) {
if (toBeRemovedNode.previousNode) {
// this node is in between of two nodes
toBeRemovedNode.nextNode.previousNode = toBeRemovedNode.previousNode;
toBeRemovedNode.previousNode.nextNode = toBeRemovedNode.nextNode;
}
else {
// this is the last node
toBeRemovedNode.nextNode.previousNode = null;
this.lastNode = toBeRemovedNode.nextNode;
}
}
else {
if (toBeRemovedNode.previousNode) {
// this is the first node
toBeRemovedNode.previousNode.nextNode = null;
this.firstNode = toBeRemovedNode.previousNode;
}
else {
// this was the last node
this.lastNode = null;
this.firstNode = null;
}
}
// remove from map
this.map.delete(hash);
// remove from map
this.map.delete(hash);
// remove links
toBeRemovedNode.nextNode = null;
toBeRemovedNode.previousNode = null;
// remove links
toBeRemovedNode.nextNode = null;
toBeRemovedNode.previousNode = null;
// return the deleted node
return toBeRemovedNode;
}
else throw new Error('Cannot remove the node «'+(hash && hash.toString ? hash.toString() : hash)+'», the node doesn\'t exist!');
}
};
// return the deleted node
return toBeRemovedNode;
}
else throw new Error('Cannot remove the node «'+(hash && hash.toString ? hash.toString() : hash)+'», the node doesn\'t exist!');
}

@@ -886,30 +882,20 @@

[Symbol.iterator]() {
let currentNode = this.firstNode;
/**
* returns an ES6 iterator object
*
* @returns {Iterator} Iterator object
*/
classDefinition[Symbol.iterator] = function() {
var currentNode = this.firstNode;
return {
next: function() {
let returnNode;
return {
next: function() {
var returnNode;
if (currentNode) {
returnNode = currentNode;
currentNode = currentNode.previousNode || null;
if (currentNode) {
returnNode = currentNode;
currentNode = currentNode.previousNode || null;
return {value: returnNode.value, done: false};
}
else return {done: true};
}
};
};
// make a class
module.exports = new Class(classDefinition);
return {value: returnNode.value, done: false};
}
else return {done: true};
}
};
}
};
}();
!function() {
'use strict';
var Class = require('ee-class')
, log = require('ee-log')
, EventEmitter = require('ee-event-emitter');
const log = require('ee-log');
const EventEmitter = require('ee-event-emitter');
module.exports = new Class({
inherits: EventEmitter
module.exports = class Node extends EventEmitter {
, identifier: Symbol('Linkd.Node')
/**
* initilize the linked list node
*
* @param {Item} customType a custom item implementation used for storing
* ittems
*/
constructor(hash, value, previousNode, nextNode) {
super();
/**
* initilize the linked list node
*
* @param {Item} customType a custom item implementation used for storing
* ittems
*/
, init: function(hash, value, previousNode, nextNode) {
this.identifier = Symbol('Linkd.Node');
// we may need the hash later on
this.hash = hash;
// we may need the hash later on
this.hash = hash;

@@ -35,65 +35,65 @@ // save the value

Class.define(this, 'nextNode', Class(nextNode || null).Writable().Configurable().Enumerable());
}
}
/**
* returns true if there is a next node in the list
*
* @returns {bool} true if there is a next node in the list
*/
, hasNext: function() {
return !!this.nextNode;
}
/**
* returns true if there is a next node in the list
*
* @returns {bool} true if there is a next node in the list
*/
hasNext() {
return !!this.nextNode;
}
/**
* returns true if there is a previous node in the list
*
* @returns {bool} true if there is a previous node in the list
*/
, hasPrevious: function() {
return !!this.previousNode;
}
/**
* returns true if there is a previous node in the list
*
* @returns {bool} true if there is a previous node in the list
*/
hasPrevious() {
return !!this.previousNode;
}
/**
* returns true if this is the last node in the list
*
* @returns {bool} true if this is the last node in the list
*/
, isLast: function() {
return !this.previousNode;
}
/**
* returns true if this is the last node in the list
*
* @returns {bool} true if this is the last node in the list
*/
isLast() {
return !this.previousNode;
}
/**
* returns true if this is the first node in the list
*
* @returns {bool} true if this is the first node in the list
*/
, isFrist: function() {
return !this.nextNode;
}
/**
* returns true if this is the first node in the list
*
* @returns {bool} true if this is the first node in the list
*/
isFrist() {
return !this.nextNode;
}
/**
* returns the next node or null
*
* @returns {Node|null} the next node or null
*/
, getNext: function() {
return this.nextNode || null;
}
/**
* returns the next node or null
*
* @returns {Node|null} the next node or null
*/
getNext() {
return this.nextNode || null;
}
/**
* returns the previous node or null
*
* @returns {Node|null} the previous node or null
*/
, getPrevious: function() {
return this.previousNode || null;
}
});
/**
* returns the previous node or null
*
* @returns {Node|null} the previous node or null
*/
getPrevious() {
return this.previousNode || null;
}
};
}();
{
"name" : "linkd"
, "description" : "A fast and extendable doubly linked list"
, "version" : "1.0.1"
, "version" : "2.0.0"
, "homepage" : "https://github.com/eventEmitter/linkd"

@@ -13,3 +13,3 @@ , "author" : "Michael van der Weg <michael@joinbox.com> (http://joinbox.com/)"

, "engines": {
"node" : ">=v4"
"node" : ">=v6"
}

@@ -20,8 +20,7 @@ , "bugs": {

, "dependencies": {
"ee-class" : "1.x"
, "ee-event-emitter" : "0.3.x"
, "ee-log" : "0.3.x"
"ee-event-emitter" : "0.3.x"
, "ee-log" : "1.x"
}
, "devDependencies": {
"mocha" : "2.x"
"mocha" : "3.x"
}

@@ -28,0 +27,0 @@ , "optionalDependencies": {}

@@ -27,2 +27,6 @@ # linkd

Attention: many methods work have similar names as those on native arrays but may actually work not the same: the push method on an array adds an element to the end of the array, he push method on the linkd list adds an element to the beginning of the list.
### Method Overview

@@ -29,0 +33,0 @@

@@ -51,2 +51,20 @@

it('should corrently save unshifted and push nodes', function() {
var list = new LinkedList()
, arr = [];
list.push(10, 'x');
list.unshift(1, 'a');
list.unshift(2, 'b');
list.unshift(3, 'c');
list.unshift(4, 'd');
list.push(11, 'y');
list.unshift(5, 'e');
for (var x of list) arr.push(x);
assert.deepEqual(arr, ['e', 'd', 'c', 'b', 'a', 'x', 'y'].reverse());
});
it('should corrently save addAfter nodes', function() {

@@ -53,0 +71,0 @@ var list = new LinkedList()

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc