Socket
Socket
Sign inDemoInstall

collections

Package Overview
Dependencies
Maintainers
5
Versions
76
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

collections - npm Package Compare versions

Comparing version 3.0.0 to 5.0.0

_dict.js

11

CHANGES.md

@@ -0,1 +1,12 @@

## v5.0.0
- Some backward compatibility breaking changes:
- Native Maps, WeakMaps and Sets are now used when available
- Aligns Map with latest standard with PR #137
- Use of a second argument for default value in get() is deprecated
- keys(), values() and entries() now return an iterator per standards,
methods returning an array are now keysArray(), valuesArray(), entriesArray()
- It's not possible to create a Map by passing an anonymous object to the constructor, that feature is now available as Map.from();
- Introduces .from() method on constructors.
## v3.0.0

@@ -2,0 +13,0 @@

3

deque.js

@@ -31,2 +31,4 @@ "use strict";

Deque.from = GenericCollection.from;
Deque.prototype.maxCapacity = (1 << 30) | 0;

@@ -443,2 +445,1 @@ Deque.prototype.minCapacity = 16;

}
"use strict";
var Shim = require("./shim");
var GenericCollection = require("./generic-collection");
var GenericMap = require("./generic-map");
var Dict = require("./_dict");
var PropertyChanges = require("./listen/property-changes");
var MapChanges = require("./listen/map-changes");

@@ -11,194 +10,3 @@ // Burgled from https://github.com/domenic/dict

module.exports = Dict;
function Dict(values, getDefault) {
if (!(this instanceof Dict)) {
return new Dict(values, getDefault);
}
getDefault = getDefault || Function.noop;
this.getDefault = getDefault;
this.store = Object.create(null);
this.length = 0;
this.addEach(values);
}
Dict.Dict = Dict; // hack so require("dict").Dict will work in MontageJS.
Object.addEach(Dict.prototype, GenericCollection.prototype);
Object.addEach(Dict.prototype, GenericMap.prototype);
Object.addEach(Dict.prototype, PropertyChanges.prototype);
Dict.prototype.constructClone = function (values) {
return new this.constructor(values, this.getDefault);
};
Dict.prototype.assertString = function (key) {
if (typeof key !== "string") {
throw new TypeError("key must be a string but Got " + key);
}
}
Object.defineProperty(Dict.prototype,"$__proto__",{writable:true});
Object.defineProperty(Dict.prototype,"_hasProto",{
get:function() {
return this.hasOwnProperty("$__proto__") && typeof this._protoValue !== "undefined";
}
});
Object.defineProperty(Dict.prototype,"_protoValue",{
get:function() {
return this["$__proto__"];
},
set: function(value) {
this["$__proto__"] = value;
}
});
Dict.prototype.get = function (key, defaultValue) {
this.assertString(key);
if (key === "__proto__") {
if (this._hasProto) {
return this._protoValue;
} else if (arguments.length > 1) {
return defaultValue;
} else {
return this.getDefault(key);
}
}
else {
if (key in this.store) {
return this.store[key];
} else if (arguments.length > 1) {
return defaultValue;
} else {
return this.getDefault(key);
}
}
};
Dict.prototype.set = function (key, value) {
this.assertString(key);
var isProtoKey = (key === "__proto__");
if (isProtoKey ? this._hasProto : key in this.store) { // update
if (this.dispatchesMapChanges) {
this.dispatchBeforeMapChange(key, isProtoKey ? this._protoValue : this.store[key]);
}
isProtoKey
? this._protoValue = value
: this.store[key] = value;
if (this.dispatchesMapChanges) {
this.dispatchMapChange(key, value);
}
return false;
} else { // create
if (this.dispatchesMapChanges) {
this.dispatchBeforeMapChange(key, undefined);
}
this.length++;
isProtoKey
? this._protoValue = value
: this.store[key] = value;
if (this.dispatchesMapChanges) {
this.dispatchMapChange(key, value);
}
return true;
}
};
Dict.prototype.has = function (key) {
this.assertString(key);
return key === "__proto__" ? this._hasProto : key in this.store;
};
Dict.prototype["delete"] = function (key) {
this.assertString(key);
if (key === "__proto__") {
if (this._hasProto) {
if (this.dispatchesMapChanges) {
this.dispatchBeforeMapChange(key, this._protoValue);
}
this._protoValue = undefined;
this.length--;
if (this.dispatchesMapChanges) {
this.dispatchMapChange(key, undefined);
}
return true;
}
return false;
}
else {
if (key in this.store) {
if (this.dispatchesMapChanges) {
this.dispatchBeforeMapChange(key, this.store[key]);
}
delete this.store[key];
this.length--;
if (this.dispatchesMapChanges) {
this.dispatchMapChange(key, undefined);
}
return true;
}
return false;
}
};
Dict.prototype.clear = function () {
var key;
if (this._hasProto) {
if (this.dispatchesMapChanges) {
this.dispatchBeforeMapChange("__proto__", this._protoValue);
}
this._protoValue = undefined;
if (this.dispatchesMapChanges) {
this.dispatchMapChange("__proto__", undefined);
}
}
for (key in this.store) {
if (this.dispatchesMapChanges) {
this.dispatchBeforeMapChange(key, this.store[key]);
}
delete this.store[key];
if (this.dispatchesMapChanges) {
this.dispatchMapChange(key, undefined);
}
}
this.length = 0;
};
Dict.prototype.reduce = function (callback, basis, thisp) {
if(this._hasProto) {
basis = callback.call(thisp, basis, "$__proto__", "__proto__", this);
}
var store = this.store;
for (var key in this.store) {
basis = callback.call(thisp, basis, store[key], key, this);
}
return basis;
};
Dict.prototype.reduceRight = function (callback, basis, thisp) {
var self = this;
var store = this.store;
basis = Object.keys(this.store).reduceRight(function (basis, key) {
return callback.call(thisp, basis, store[key], key, self);
}, basis);
if(this._hasProto) {
return callback.call(thisp, basis, this._protoValue, "__proto__", self);
}
return basis;
};
Dict.prototype.one = function () {
var key;
for (key in this.store) {
return this.store[key];
}
return this._protoValue;
};
Dict.prototype.toJSON = function () {
return this.toObject();
};
Object.addEach(Dict.prototype, MapChanges.prototype);

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

var PropertyChanges = require("./listen/property-changes");
var MapChanges = require("./listen/map-changes");

@@ -40,3 +41,5 @@ module.exports = FastMap;

Object.addEach(FastMap.prototype, PropertyChanges.prototype);
Object.addEach(FastMap.prototype, MapChanges.prototype);
FastMap.from = GenericCollection.from;
FastMap.prototype.constructClone = function (values) {

@@ -59,2 +62,1 @@ return new this.constructor(

}
"use strict";
var Shim = require("./shim");
var Dict = require("./dict");
var List = require("./list");
var GenericCollection = require("./generic-collection");
var GenericSet = require("./generic-set");
var TreeLog = require("./tree-log");
var FastSet = require("./_fast-set");
var PropertyChanges = require("./listen/property-changes");
var object_has = Object.prototype.hasOwnProperty;
module.exports = FastSet;
function FastSet(values, equals, hash, getDefault) {
if (!(this instanceof FastSet)) {
return new FastSet(values, equals, hash, getDefault);
}
equals = equals || Object.equals;
hash = hash || Object.hash;
getDefault = getDefault || Function.noop;
this.contentEquals = equals;
this.contentHash = hash;
this.getDefault = getDefault;
var self = this;
this.buckets = new this.Buckets(null, function getDefaultBucket() {
return new self.Bucket();
});
this.length = 0;
this.addEach(values);
}
FastSet.FastSet = FastSet; // hack so require("fast-set").FastSet will work in MontageJS
Object.addEach(FastSet.prototype, GenericCollection.prototype);
Object.addEach(FastSet.prototype, GenericSet.prototype);
Object.addEach(FastSet.prototype, PropertyChanges.prototype);
FastSet.prototype.Buckets = Dict;
FastSet.prototype.Bucket = List;
FastSet.prototype.constructClone = function (values) {
return new this.constructor(
values,
this.contentEquals,
this.contentHash,
this.getDefault
);
};
FastSet.prototype.has = function (value) {
var hash = this.contentHash(value);
return this.buckets.get(hash).has(value);
};
FastSet.prototype.get = function (value, equals) {
if (equals) {
throw new Error("FastSet#get does not support second argument: equals");
}
var hash = this.contentHash(value);
var buckets = this.buckets;
if (buckets.has(hash)) {
return buckets.get(hash).get(value);
} else {
return this.getDefault(value);
}
};
FastSet.prototype["delete"] = function (value, equals) {
if (equals) {
throw new Error("FastSet#delete does not support second argument: equals");
}
var hash = this.contentHash(value);
var buckets = this.buckets;
if (buckets.has(hash)) {
var bucket = buckets.get(hash);
if (bucket["delete"](value)) {
this.length--;
if (bucket.length === 0) {
buckets["delete"](hash);
}
return true;
}
}
return false;
};
FastSet.prototype.clear = function () {
this.buckets.clear();
this.length = 0;
};
FastSet.prototype.add = function (value) {
var hash = this.contentHash(value);
var buckets = this.buckets;
if (!buckets.has(hash)) {
buckets.set(hash, new this.Bucket(null, this.contentEquals));
}
if (!buckets.get(hash).has(value)) {
buckets.get(hash).add(value);
this.length++;
return true;
}
return false;
};
FastSet.prototype.reduce = function (callback, basis /*, thisp*/) {
var thisp = arguments[2];
var buckets = this.buckets;
var index = 0;
return buckets.reduce(function (basis, bucket) {
return bucket.reduce(function (basis, value) {
return callback.call(thisp, basis, value, index++, this);
}, basis, this);
}, basis, this);
};
FastSet.prototype.one = function () {
if (this.length > 0) {
return this.buckets.one().one();
}
};
FastSet.prototype.iterate = function () {
return this.buckets.values().flatten().iterate();
};
FastSet.prototype.log = function (charmap, logNode, callback, thisp) {
charmap = charmap || TreeLog.unicodeSharp;
logNode = logNode || this.logNode;
if (!callback) {
callback = console.log;
thisp = console;
}
callback = callback.bind(thisp);
var buckets = this.buckets;
var hashes = buckets.keys();
hashes.forEach(function (hash, index) {
var branch;
var leader;
if (index === hashes.length - 1) {
branch = charmap.fromAbove;
leader = ' ';
} else if (index === 0) {
branch = charmap.branchDown;
leader = charmap.strafe;
} else {
branch = charmap.fromBoth;
leader = charmap.strafe;
}
var bucket = buckets.get(hash);
callback.call(thisp, branch + charmap.through + charmap.branchDown + ' ' + hash);
bucket.forEach(function (value, node) {
var branch, below;
if (node === bucket.head.prev) {
branch = charmap.fromAbove;
below = ' ';
} else {
branch = charmap.fromBoth;
below = charmap.strafe;
}
var written;
logNode(
node,
function (line) {
if (!written) {
callback.call(thisp, leader + ' ' + branch + charmap.through + charmap.through + line);
written = true;
} else {
callback.call(thisp, leader + ' ' + below + ' ' + line);
}
},
function (line) {
callback.call(thisp, leader + ' ' + charmap.strafe + ' ' + line);
}
);
});
});
};
FastSet.prototype.logNode = function (node, write) {
var value = node.value;
if (Object(value) === value) {
JSON.stringify(value, null, 4).split("\n").forEach(function (line) {
write(" " + line);
});
} else {
write(" " + value);
}
};

@@ -8,6 +8,15 @@ "use strict";

var DOMTokenList = global.DOMTokenList || function(){};
GenericCollection.EmptyArray = Object.freeze([]);
/* TODO: optimize for DOMTokenList and Array to use for() instead of forEach */
GenericCollection.prototype.addEach = function (values) {
if (values && Object(values) === values) {
//We want to eliminate everything but array like: Strings, Arrays, DOMTokenList
if(values && (values instanceof Array || (values instanceof DOMTokenList) || values instanceof String)) {
for (var i = 0; i < values.length; i++) {
this.add(values[i], i);
}
}
else if (values && Object(values) === values) {
if (typeof values.forEach === "function") {

@@ -26,7 +35,2 @@ values.forEach(this.add, this);

}
} else if (values && typeof values.length === "number") {
// Strings
for (var i = 0; i < values.length; i++) {
this.add(values[i], i);
}
}

@@ -111,2 +115,6 @@ return this;

GenericCollection.from = function () {
return this.apply(this,arguments);
};
GenericCollection.prototype.filter = function (callback /*, thisp*/) {

@@ -113,0 +121,0 @@ var thisp = arguments[1];

"use strict";
var Object = require("./shim-object");
var MapChanges = require("./listen/map-changes");
var PropertyChanges = require("./listen/property-changes");
var Iterator = require("./iterator");

@@ -12,5 +11,2 @@ module.exports = GenericMap;

Object.addEach(GenericMap.prototype, MapChanges.prototype);
Object.addEach(GenericMap.prototype, PropertyChanges.prototype);
// all of these methods depend on the constructor providing a `store` set

@@ -21,2 +17,3 @@

GenericMap.prototype.addEach = function (values) {
var i;
if (values && Object(values) === values) {

@@ -38,3 +35,3 @@ if (typeof values.forEach === "function") {

// Arguments
for (var i = 0; i < values.length; i++) {
for (i = 0; i < values.length; i++) {
this.add(values[i], i);

@@ -50,3 +47,3 @@ }

// String
for (var i = 0; i < values.length; i++) {
for (i = 0; i < values.length; i++) {
this.add(values[i], i);

@@ -56,3 +53,3 @@ }

return this;
}
};

@@ -64,2 +61,3 @@ GenericMap.prototype.get = function (key, defaultValue) {

} else if (arguments.length > 1) {
console.log("Use of a second argument as default value is deprecated to match standards");
return defaultValue;

@@ -124,3 +122,3 @@ } else {

GenericMap.prototype.clear = function () {
var keys;
var keys, key;
if (this.dispatchesMapChanges) {

@@ -130,3 +128,3 @@ this.forEach(function (value, key) {

}, this);
keys = this.keys();
keys = this.keysArray();
}

@@ -136,5 +134,8 @@ this.store.clear();

if (this.dispatchesMapChanges) {
keys.forEach(function (key) {
for(var i=0;(key = keys[i]);i++) {
this.dispatchMapChange(key);
}, this);
}
// keys.forEach(function (key) {
// this.dispatchMapChange(key);
// }, this);
}

@@ -155,3 +156,3 @@ };

GenericMap.prototype.keys = function () {
GenericMap.prototype.keysArray = function () {
return this.map(function (value, key) {

@@ -161,8 +162,14 @@ return key;

};
GenericMap.prototype.keys = function () {
return new Iterator(this.keysArray());
};
GenericMap.prototype.values = function () {
GenericMap.prototype.valuesArray = function () {
return this.map(Function.identity);
};
GenericMap.prototype.values = function () {
return new Iterator(this.valuesArray());
};
GenericMap.prototype.entries = function () {
GenericMap.prototype.entriesArray = function () {
return this.map(function (value, key) {

@@ -172,6 +179,9 @@ return [key, value];

};
GenericMap.prototype.entries = function () {
return new Iterator(this.entriesArray());
};
// XXX deprecated
GenericMap.prototype.items = function () {
return this.entries();
return this.entriesArray();
};

@@ -196,5 +206,6 @@

GenericMap.prototype.toJSON = function () {
return this.entries();
return this.entriesArray();
};
GenericMap.prototype.Item = Item;

@@ -214,2 +225,1 @@

};

@@ -51,2 +51,11 @@

GenericSet.prototype.forEach = function (callback /*, thisp*/) {
var thisp = arguments[1];
return this.reduce(function (undefined, value, key, object, depth) {
//ECMASCRIPT Sets send value twice in callback to forEach
callback.call(thisp, value, value, object, depth);
}, undefined);
};
GenericSet.prototype.toJSON = function () {

@@ -74,1 +83,9 @@ return this.toArray();

var _valuesArrayFunction = function(value,key) {return value;};
GenericSet.prototype.valuesArray = function() {
return this.map(_valuesArrayFunction);
}
var _entriesArrayFunction = function(value,key) {return [key,value];};
GenericSet.prototype.entriesArray = function() {
return this.map(_entriesArrayFunction);
}

@@ -34,2 +34,4 @@

Heap.from = GenericCollection.from;
Heap.prototype.constructClone = function (values) {

@@ -245,2 +247,1 @@ return new this.constructor(

};

@@ -11,2 +11,7 @@ "use strict";

var values = iterable && iterable.values && iterable.values();
if(values && typeof values.next === "function" ) {
return values;
}
if (!(this instanceof Iterator)) {

@@ -13,0 +18,0 @@ return new Iterator(iterable);

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

var PropertyChanges = require("./listen/property-changes");
var MapChanges = require("./listen/map-changes");

@@ -41,3 +42,7 @@ module.exports = LfuMap;

Object.addEach(LfuMap.prototype, PropertyChanges.prototype);
Object.addEach(LfuMap.prototype, MapChanges.prototype);
Object.defineProperty(LfuMap.prototype,"size",GenericCollection._sizePropertyDescriptor);
LfuMap.from = GenericCollection.from;
LfuMap.prototype.constructClone = function (values) {

@@ -79,4 +84,3 @@ return new this.constructor(

}
GenericMap.prototype.addMapChangeListener.apply(this, arguments);
MapChanges.prototype.addMapChangeListener.apply(this, arguments);
};

@@ -6,3 +6,3 @@ "use strict";

var Shim = require("./shim");
var Set = require("./set");
var Set = require("./set").CollectionsSet;
var GenericCollection = require("./generic-collection");

@@ -50,2 +50,4 @@ var GenericSet = require("./generic-set");

Object.addEach(LfuSet.prototype, RangeChanges.prototype);
Object.defineProperty(LfuSet.prototype,"size",GenericCollection._sizePropertyDescriptor);
LfuSet.from = GenericCollection.from;

@@ -248,2 +250,1 @@ LfuSet.prototype.constructClone = function (values) {

}
"use strict";
module.exports = List;
var Shim = require("./shim");
var GenericCollection = require("./generic-collection");
var GenericOrder = require("./generic-order");
var _List = require("./_list");
var PropertyChanges = require("./listen/property-changes");
var RangeChanges = require("./listen/range-changes");
module.exports = List;
function List(values, equals, getDefault) {
if (!(this instanceof List)) {
return new List(values, equals, getDefault);
}
var head = this.head = new this.Node();
head.next = head;
head.prev = head;
this.contentEquals = equals || Object.equals;
this.getDefault = getDefault || Function.noop;
this.length = 0;
this.addEach(values);
return _List._init(List, this, values, equals, getDefault);
}
List.prototype = new _List();
List.prototype.constructor = List;
List.List = List; // hack so require("list").List will work in MontageJS
List.from = _List.from;
Object.addEach(List.prototype, GenericCollection.prototype);
Object.addEach(List.prototype, GenericOrder.prototype);
Object.addEach(List.prototype, PropertyChanges.prototype);
Object.addEach(List.prototype, RangeChanges.prototype);
List.prototype.constructClone = function (values) {
return new this.constructor(values, this.contentEquals, this.getDefault);
List.prototype.makeObservable = function () {
this.head.index = -1;
this.updateIndexes(this.head.next, 0);
this.dispatchesRangeChanges = true;
};
List.prototype.find = function (value, equals, index) {
equals = equals || this.contentEquals;
var head = this.head;
var at = this.scan(index, head.next);
while (at !== head) {
if (equals(at.value, value)) {
return at;
}
at = at.next;
Object.defineProperties(List.prototype, {
"_dispatchEmptyArray": {
value: []
}
};
});
List.prototype.findLast = function (value, equals, index) {
equals = equals || this.contentEquals;
var head = this.head;
var at = this.scan(index, head.prev);
while (at !== head) {
if (equals(at.value, value)) {
return at;
}
at = at.prev;
}
};
/*
var list_clear = _List.prototype.clear,
set_add = GlobalSet.prototype.add,
set_delete = GlobalSet.prototype.delete;
*/
List.prototype.has = function (value, equals) {
return !!this.find(value, equals);
};
List.prototype.get = function (value, equals) {
var found = this.find(value, equals);
if (found) {
return found.value;
}
return this.getDefault(value);
};
// LIFO (delete removes the most recently added equivalent value)

@@ -91,18 +59,8 @@ List.prototype["delete"] = function (value, equals) {

List.prototype.deleteAll = function (value, equals) {
equals = equals || this.contentEquals;
var head = this.head;
var at = head.next;
var count = 0;
while (at !== head) {
if (equals(value, at.value)) {
at["delete"]();
count++;
}
at = at.next;
}
this.length -= count;
return count;
};
Object.defineProperty(List.prototype, "superClear", {
value: _List.prototype.clear,
enumerable: false,
configurable: true,
writable:true
});
List.prototype.clear = function () {

@@ -115,4 +73,3 @@ var plus, minus;

}
this.head.next = this.head.prev = this.head;
this.length = 0;
this.superClear();
if (this.dispatchesRangeChanges) {

@@ -129,4 +86,5 @@ this.dispatchRangeChange(plus, minus, 0);

}
this.head.addBefore(node);
this.length++;
this._addNode(node);
if (this.dispatchesRangeChanges) {

@@ -138,4 +96,10 @@ this.dispatchRangeChange([value], [], node.index);

Object.defineProperty(List.prototype, "superPush", {
value: _List.prototype.push,
enumerable: false,
configurable: true,
writable:true
});
List.prototype.push = function () {
var head = this.head;
if (this.dispatchesRangeChanges) {

@@ -148,8 +112,9 @@ var plus = Array.prototype.slice.call(arguments);

}
for (var i = 0; i < arguments.length; i++) {
var value = arguments[i];
var node = new this.Node(value);
head.addBefore(node);
}
this.length += arguments.length;
arguments.length === 1
? this.superPush.call(this, arguments[0])
: (arguments.length === 2)
? this.superPush.call(this, arguments[0], arguments[1])
: this.superPush.apply(this, arguments);
if (this.dispatchesRangeChanges) {

@@ -161,2 +126,9 @@ this.updateIndexes(start.next, start.index === undefined ? 0 : start.index + 1);

Object.defineProperty(List.prototype, "superUnshift", {
value: _List.prototype.unshift,
enumerable: false,
configurable: true,
writable:true
});
List.prototype.unshift = function () {

@@ -168,10 +140,9 @@ if (this.dispatchesRangeChanges) {

}
var at = this.head;
for (var i = 0; i < arguments.length; i++) {
var value = arguments[i];
var node = new this.Node(value);
at.addAfter(node);
at = node;
}
this.length += arguments.length;
arguments.length === 1
? this.superUnshift.call(this, arguments[0])
: (arguments.length === 2)
? this.superUnshift.call(this, arguments[0], arguments[1])
: this.superUnshift.apply(this, arguments);
if (this.dispatchesRangeChanges) {

@@ -183,179 +154,114 @@ this.updateIndexes(this.head.next, 0);

List.prototype.pop = function () {
var value;
var head = this.head;
if (head.prev !== head) {
value = head.prev.value;
Object.defineProperty(List.prototype, "_beforePop", {
value: function(value, index) {
var popDispatchValueArray;
if (this.dispatchesRangeChanges) {
var plus = [];
var minus = [value];
var index = this.length - 1;
this.dispatchBeforeRangeChange(plus, minus, index);
popDispatchValueArray = [value];
this.dispatchBeforeRangeChange(/*plus*/this._dispatchEmptyArray, /*minus*/popDispatchValueArray, index);
}
head.prev['delete']();
this.length--;
return popDispatchValueArray;
},
enumerable: false,
configurable: true,
writable:true
});
Object.defineProperty(List.prototype, "_afterPop", {
value: function(value, index, popDispatchValueArray) {
if (this.dispatchesRangeChanges) {
this.dispatchRangeChange(plus, minus, index);
this.dispatchRangeChange(/*plus*/this._dispatchEmptyArray, /*minus*/popDispatchValueArray, index);
}
}
return value;
},
enumerable: false,
configurable: true,
writable:true
});
Object.defineProperty(List.prototype, "superPop", {
value: _List.prototype.pop,
enumerable: false,
configurable: true,
writable:true
});
List.prototype.pop = function () {
return this.superPop(this._beforePop,this._afterPop);
};
List.prototype.shift = function () {
var value;
var head = this.head;
if (head.prev !== head) {
value = head.next.value;
Object.defineProperty(List.prototype, "_beforeShift", {
value: function(value, index) {
var dispatchValueArray;
if (this.dispatchesRangeChanges) {
var plus = [];
var minus = [value];
this.dispatchBeforeRangeChange(plus, minus, 0);
dispatchValueArray = [value];
this.dispatchBeforeRangeChange(/*plus*/this._dispatchEmptyArray, /*minus*/dispatchValueArray, index);
}
head.next['delete']();
this.length--;
return dispatchValueArray;
},
enumerable: false,
configurable: true,
writable:true
});
Object.defineProperty(List.prototype, "_afterShift", {
value: function(value, index, dispatchValueArray) {
if (this.dispatchesRangeChanges) {
this.updateIndexes(this.head.next, 0);
this.dispatchRangeChange(plus, minus, 0);
this.updateIndexes(this.head.next, index);
this.dispatchRangeChange(/*plus*/this._dispatchEmptyArray, /*minus*/dispatchValueArray, index);
}
}
return value;
},
enumerable: false,
configurable: true,
writable:true
});
Object.defineProperty(List.prototype, "superShift", {
value: _List.prototype.shift,
enumerable: false,
configurable: true,
writable:true
});
List.prototype.shift = function () {
return this.superShift(this._beforeShift,this._afterShift);
};
List.prototype.peek = function () {
if (this.head !== this.head.next) {
return this.head.next.value;
}
};
List.prototype.poke = function (value) {
if (this.head !== this.head.next) {
this.head.next.value = value;
} else {
this.push(value);
}
};
List.prototype.one = function () {
return this.peek();
};
// TODO
// List.prototype.indexOf = function (value) {
// };
// TODO
// List.prototype.lastIndexOf = function (value) {
// };
// an internal utility for coercing index offsets to nodes
List.prototype.scan = function (at, fallback) {
var head = this.head;
if (typeof at === "number") {
var count = at;
if (count >= 0) {
at = head.next;
while (count) {
count--;
at = at.next;
if (at == head) {
break;
}
}
} else {
at = head;
while (count < 0) {
count++;
at = at.prev;
if (at == head) {
break;
}
}
}
return at;
} else {
return at || fallback;
}
};
// at and end may both be positive or negative numbers (in which cases they
// correspond to numeric indicies, or nodes)
List.prototype.slice = function (at, end) {
var sliced = [];
var head = this.head;
at = this.scan(at, head.next);
end = this.scan(end, head);
while (at !== end && at !== head) {
sliced.push(at.value);
at = at.next;
}
return sliced;
};
List.prototype.splice = function (at, length /*...plus*/) {
return this.swap(at, length, Array.prototype.slice.call(arguments, 2));
};
Object.defineProperty(List.prototype, "superSwap", {
value: _List.prototype.swap,
enumerable: false,
configurable: true,
writable:true
});
List.prototype.swap = function (start, length, plus) {
var initial = start;
// start will be head if start is null or -1 (meaning from the end), but
// will be head.next if start is 0 (meaning from the beginning)
start = this.scan(start, this.head);
if (length == null) {
length = Infinity;
}
plus = Array.from(plus);
// collect the minus array
var minus = [];
var at = start;
while (length-- && length >= 0 && at !== this.head) {
minus.push(at.value);
at = at.next;
}
// before range change
var index, startNode;
if (this.dispatchesRangeChanges) {
if (start === this.head) {
index = this.length;
} else if (start.prev === this.head) {
index = 0;
} else {
index = start.index;
var _beforeSwap = function(start, plus, minus) {
if (this.dispatchesRangeChanges) {
if (start === this.head) {
index = this.length;
} else if (start.prev === this.head) {
index = 0;
} else {
index = start.index;
}
startNode = start.prev;
this.dispatchBeforeRangeChange(plus, minus, index);
}
startNode = start.prev;
this.dispatchBeforeRangeChange(plus, minus, index);
}
// delete minus
var at = start;
for (var i = 0, at = start; i < minus.length; i++, at = at.next) {
at["delete"]();
}
// add plus
if (initial == null && at === this.head) {
at = this.head.next;
}
for (var i = 0; i < plus.length; i++) {
var node = new this.Node(plus[i]);
at.addBefore(node);
}
// adjust length
this.length += plus.length - minus.length;
// after range change
if (this.dispatchesRangeChanges) {
if (start === this.head) {
this.updateIndexes(this.head.next, 0);
} else {
this.updateIndexes(startNode.next, startNode.index + 1);
};
var _afterSwap = function(start, plus, minus) {
// after range change
if (this.dispatchesRangeChanges) {
if (start === this.head) {
this.updateIndexes(this.head.next, 0);
} else {
this.updateIndexes(startNode.next, startNode.index + 1);
}
this.dispatchRangeChange(plus, minus, index);
}
this.dispatchRangeChange(plus, minus, index);
}
};
return minus;
return this.superSwap(start, length, plus, _beforeSwap, _afterSwap);
};
Object.defineProperty(List.prototype, "superReverse", {
value: _List.prototype.reverse,
enumerable: false,
configurable: true,
writable:true
});
List.prototype.reverse = function () {

@@ -367,9 +273,3 @@ if (this.dispatchesRangeChanges) {

}
var at = this.head;
do {
var temp = at.next;
at.next = at.prev;
at.prev = temp;
at = at.next;
} while (at !== this.head);
this.superReverse();
if (this.dispatchesRangeChanges) {

@@ -380,99 +280,1 @@ this.dispatchRangeChange(plus, minus, 0);

};
List.prototype.sort = function () {
this.swap(0, this.length, this.sorted());
};
// TODO account for missing basis argument
List.prototype.reduce = function (callback, basis /*, thisp*/) {
var thisp = arguments[2];
var head = this.head;
var at = head.next;
while (at !== head) {
basis = callback.call(thisp, basis, at.value, at, this);
at = at.next;
}
return basis;
};
List.prototype.reduceRight = function (callback, basis /*, thisp*/) {
var thisp = arguments[2];
var head = this.head;
var at = head.prev;
while (at !== head) {
basis = callback.call(thisp, basis, at.value, at, this);
at = at.prev;
}
return basis;
};
List.prototype.updateIndexes = function (node, index) {
while (node !== this.head) {
node.index = index++;
node = node.next;
}
};
List.prototype.makeObservable = function () {
this.head.index = -1;
this.updateIndexes(this.head.next, 0);
this.dispatchesRangeChanges = true;
};
List.prototype.iterate = function () {
return new ListIterator(this.head);
};
function ListIterator(head) {
this.head = head;
this.at = head.next;
};
ListIterator.prototype.__iterationObject = null;
Object.defineProperty(ListIterator.prototype,"_iterationObject", {
get: function() {
return this.__iterationObject || (this.__iterationObject = { done: false, value:null});
}
});
ListIterator.prototype.next = function () {
if (this.at === this.head) {
this._iterationObject.done = true;
this._iterationObject.value = void 0;
} else {
var value = this.at.value;
this.at = this.at.next;
this._iterationObject.value = value;
}
return this._iterationObject;
};
List.prototype.Node = Node;
function Node(value) {
this.value = value;
this.prev = null;
this.next = null;
};
Node.prototype["delete"] = function () {
this.prev.next = this.next;
this.next.prev = this.prev;
};
Node.prototype.addBefore = function (node) {
var prev = this.prev;
this.prev = node;
node.prev = prev;
prev.next = node;
node.next = this;
};
Node.prototype.addAfter = function (node) {
var next = this.next;
this.next = node;
node.next = next;
next.prev = node;
node.prev = this;
};

@@ -16,7 +16,4 @@ /*

require("../shim");
var List = require("../list");
var PropertyChanges = require("./property-changes");
var RangeChanges = require("./range-changes");
var MapChanges = require("./map-changes");
var array_splice = Array.prototype.splice;
var array_spliceOne = Array.prototype.spliceOne;
var array_slice = Array.prototype.slice;

@@ -49,15 +46,2 @@ var array_reverse = Array.prototype.reverse;

function defineEach(prototype) {
for (var name in prototype) {
Object.defineProperty(Array.prototype, name, {
value: prototype[name],
writable: true,
configurable: true,
enumerable: false
});
}
}
defineEach(PropertyChanges.prototype);
//This is a no-op test in property-changes.js - PropertyChanges.prototype.makePropertyObservable, so might as well not pay the price every time....

@@ -71,5 +55,2 @@ Object.defineProperty(Array.prototype, "makePropertyObservable", {

defineEach(RangeChanges.prototype);
defineEach(MapChanges.prototype);
var observableArrayProperties = {

@@ -148,3 +129,3 @@

value: function swap(start, length, plus) {
var hasOwnPropertyChangeDescriptor, i, j;
var hasOwnPropertyChangeDescriptor, i, j, plusLength;
if (plus) {

@@ -157,2 +138,3 @@ if (!Array.isArray(plus)) {

}
plusLength = plus.length;

@@ -163,4 +145,4 @@ if (start < 0) {

var holes = start - this.length;
var newPlus = Array(holes + plus.length);
for (i = 0, j = holes; i < plus.length; i++, j++) {
var newPlus = Array(holes + plusLength);
for (i = 0, j = holes; i < plusLength; i++, j++) {
if (i in plus) {

@@ -171,2 +153,3 @@ newPlus[j] = plus[i];

plus = newPlus;
plusLength = plus.length;
start = this.length;

@@ -178,3 +161,3 @@ }

// minus will be empty
if (plus.length === 0) {
if (plusLength === 0) {
// at this point if plus is empty there is nothing to do.

@@ -187,7 +170,6 @@ return []; // [], but spare us an instantiation

}
var diff = plus.length - minus.length;
var diff = plusLength - minus.length;
var oldLength = this.length;
var newLength = Math.max(this.length + diff, start + plus.length);
var longest = Math.max(oldLength, newLength);
var newLength = Math.max(this.length + diff, start + plusLength);
var longest = (oldLength > newLength) ? oldLength : newLength;
// dispatch before change events

@@ -199,3 +181,3 @@ if (diff) {

if (diff === 0) { // substring replacement
this._dispatchBeforeOwnPropertyChange(start, plus.length);
this._dispatchBeforeOwnPropertyChange(start, plusLength);
} else if ((hasOwnPropertyChangeDescriptor = PropertyChanges.hasOwnPropertyChangeDescriptor(this))) {

@@ -216,3 +198,3 @@ // all subsequent values changed or shifted.

if (diff === 0) { // substring replacement
this._dispatchOwnPropertyChange(start,plus.length);
this._dispatchOwnPropertyChange(start,plusLength);
} else if (hasOwnPropertyChangeDescriptor) {

@@ -252,5 +234,70 @@ // all subsequent values changed or shifted.

spliceOne: {
value: function splice(start,itemToAdd) {
//Nothhing to add so length will go down by one.
var plus, minus, oldLength = this.length, newLength, longest, argumentsLength = arguments.length, hasOwnPropertyChangeDescriptor;
if(argumentsLength === 1) {
PropertyChanges.dispatchBeforeOwnPropertyChange(this, "length", this.length);
newLength = this.length - 1;
plus = Array.empty;
}
//Care about 2 only
else {
plus = [itemToAdd];
newLength = this.length;
}
minus = [this[start]];
longest = (oldLength > newLength) ? oldLength : newLength;
this.dispatchBeforeRangeChange(plus, minus, start);
if (argumentsLength === 2) { // substring replacement
this._dispatchBeforeOwnPropertyChange(start, 1);
} else if ((hasOwnPropertyChangeDescriptor = PropertyChanges.hasOwnPropertyChangeDescriptor(this))) {
// all subsequent values changed or shifted.
// avoid (longest - start) long walks if there are no
// registered descriptors.
this._dispatchBeforeOwnPropertyChange(start, longest-start);
}
if (argumentsLength === 1) { // substring replacement
array_spliceOne.call(this,start);
}
else {
array_spliceOne.call(this,start,itemToAdd);
}
// dispatch after change events
if (argumentsLength === 2) { // substring replacement
this._dispatchOwnPropertyChange(start,1);
} else if (hasOwnPropertyChangeDescriptor) {
// all subsequent values changed or shifted.
// avoid (longest - start) long walks if there are no
// registered descriptors.
this._dispatchOwnPropertyChange(start,longest-start);
}
this.dispatchRangeChange(plus, minus, start);
if(argumentsLength === 1) {
this.dispatchOwnPropertyChange("length", this.length);
}
},
writable: true,
configurable: true
},
_setSwapBuffer: {
get: function() {
return this.__setSwapBuffer || (Object.defineProperty(this,"__setSwapBuffer",{
value: [],
writable: true,
configurable: true,
enumerable: false
})).__setSwapBuffer;
},
enumerable: false
},
set: {
value: function set(index, value) {
this.swap(index, index >= this.length ? 0 : 1, [value]);
this._setSwapBuffer[0] = value
this.swap(index, index >= this.length ? 0 : 1, this._setSwapBuffer);
return true;

@@ -339,1 +386,8 @@ },

var PropertyChanges = require("./property-changes");
var RangeChanges = require("./range-changes");
var MapChanges = require("./map-changes");
Object.defineEach(Array.prototype, PropertyChanges.prototype, false, /*configurable*/true, /*enumerable*/ false, /*writable*/true);
Object.defineEach(Array.prototype, RangeChanges.prototype, false, /*configurable*/true, /*enumerable*/ false, /*writable*/true);
Object.defineEach(Array.prototype, MapChanges.prototype, false, /*configurable*/true, /*enumerable*/ false, /*writable*/true);
"use strict";
var WeakMap = require("weak-map");
var List = require("../list");
var WeakMap = require("weak-map"),
Map = require("../_map"),
ChangeDescriptor = require("./change-descriptor"),
ObjectChangeDescriptor = ChangeDescriptor.ObjectChangeDescriptor,
ChangeListenersRecord = ChangeDescriptor.ChangeListenersRecord,
ListenerGhost = ChangeDescriptor.ListenerGhost;

@@ -20,3 +24,3 @@ module.exports = MapChanges;

{
willChangeListeners:Array(Function)
willChangeListeners:Array(Fgunction)
changeListeners:Array(Function)

@@ -27,10 +31,56 @@ }

var mapChangeDescriptors = new WeakMap();
var Dict = null;
function MapChangeDescriptor(name) {
this.name = name;
this.isActive = false;
this._willChangeListeners = null;
this._changeListeners = null;
};
MapChangeDescriptor.prototype = new ObjectChangeDescriptor();
MapChangeDescriptor.prototype.constructor = MapChangeDescriptor;
MapChangeDescriptor.prototype.changeListenersRecordConstructor = MapChangeListenersRecord;
MapChangeDescriptor.prototype.willChangeListenersRecordConstructor = MapWillChangeListenersRecord;
var MapChangeListenersSpecificHandlerMethodName = new Map();
function MapChangeListenersRecord(name) {
var specificHandlerMethodName = MapChangeListenersSpecificHandlerMethodName.get(name);
if(!specificHandlerMethodName) {
specificHandlerMethodName = "handle";
specificHandlerMethodName += name.slice(0, 1).toUpperCase();
specificHandlerMethodName += name.slice(1);
specificHandlerMethodName += "MapChange";
MapChangeListenersSpecificHandlerMethodName.set(name,specificHandlerMethodName);
}
this.specificHandlerMethodName = specificHandlerMethodName;
return this;
}
MapChangeListenersRecord.prototype = new ChangeListenersRecord();
MapChangeListenersRecord.prototype.constructor = MapChangeListenersRecord;
MapChangeListenersRecord.prototype.genericHandlerMethodName = "handleMapChange";
var MapWillChangeListenersSpecificHandlerMethodName = new Map();
function MapWillChangeListenersRecord(name) {
var specificHandlerMethodName = MapWillChangeListenersSpecificHandlerMethodName.get(name);
if(!specificHandlerMethodName) {
specificHandlerMethodName = "handle";
specificHandlerMethodName += name.slice(0, 1).toUpperCase();
specificHandlerMethodName += name.slice(1);
specificHandlerMethodName += "MapWillChange";
MapWillChangeListenersSpecificHandlerMethodName.set(name,specificHandlerMethodName);
}
this.specificHandlerMethodName = specificHandlerMethodName;
return this;
}
MapWillChangeListenersRecord.prototype = new ChangeListenersRecord();
MapWillChangeListenersRecord.prototype.constructor = MapWillChangeListenersRecord;
MapWillChangeListenersRecord.prototype.genericHandlerMethodName = "handleMapWillChange";
MapChanges.prototype.getAllMapChangeDescriptors = function () {
if (!mapChangeDescriptors.has(this)) {
if (!Dict) {
Dict = require("../dict");
}
mapChangeDescriptors.set(this, Dict());
mapChangeDescriptors.set(this, new Map());
}

@@ -44,6 +94,3 @@ return mapChangeDescriptors.get(this);

if (!tokenChangeDescriptors.has(token)) {
tokenChangeDescriptors.set(token, {
willChangeListeners: new List(),
changeListeners: new List()
});
tokenChangeDescriptors.set(token, new MapChangeDescriptor(token));
}

@@ -53,3 +100,20 @@ return tokenChangeDescriptors.get(token);

MapChanges.prototype.addMapChangeListener = function (listener, token, beforeChange) {
var ObjectsDispatchesMapChanges = new WeakMap(),
dispatchesMapChangesGetter = function() {
return ObjectsDispatchesMapChanges.get(this);
},
dispatchesMapChangesSetter = function(value) {
return ObjectsDispatchesMapChanges.set(this,value);
},
dispatchesChangesMethodName = "dispatchesMapChanges",
dispatchesChangesPropertyDescriptor = {
get: dispatchesMapChangesGetter,
set: dispatchesMapChangesSetter,
configurable: true,
enumerable: false
};
MapChanges.prototype.addMapChangeListener = function addMapChangeListener(listener, token, beforeChange) {
//console.log("this:",this," addMapChangeListener(",listener,",",token,",",beforeChange);
if (!this.isObservable && this.makeObservable) {

@@ -66,10 +130,21 @@ // for Array

}
listeners.push(listener);
Object.defineProperty(this, "dispatchesMapChanges", {
value: true,
writable: true,
configurable: true,
enumerable: false
});
// console.log("addMapChangeListener()",listener, token);
//console.log("this:",this," addMapChangeListener() listeners._current is ",listeners._current);
if(!listeners._current) {
listeners._current = listener;
}
else if(!Array.isArray(listeners._current)) {
listeners._current = [listeners._current,listener]
}
else {
listeners._current.push(listener);
}
if(Object.getOwnPropertyDescriptor((this.__proto__||Object.getPrototypeOf(this)),dispatchesChangesMethodName) === void 0) {
Object.defineProperty((this.__proto__||Object.getPrototypeOf(this)), dispatchesChangesMethodName, dispatchesChangesPropertyDescriptor);
}
this.dispatchesMapChanges = true;
var self = this;

@@ -96,12 +171,30 @@ return function cancelMapChangeListener() {

var node = listeners.findLast(listener);
if (!node) {
throw new Error("Can't remove map change listener: does not exist: token " + JSON.stringify(token));
if(listeners._current) {
if(listeners._current === listener) {
listeners._current = null;
}
else {
var index = listeners._current.lastIndexOf(listener);
if (index === -1) {
throw new Error("Can't remove map change listener: does not exist: token " + JSON.stringify(token));
}
else {
if(descriptor.isActive) {
listeners.ghostCount = listeners.ghostCount+1
listeners._current[index]=ListenerGhost
}
else {
listeners._current.spliceOne(index);
}
}
}
}
node["delete"]();
};
MapChanges.prototype.dispatchMapChange = function (key, value, beforeChange) {
var descriptors = this.getAllMapChangeDescriptors();
var changeName = "Map" + (beforeChange ? "WillChange" : "Change");
var descriptors = this.getAllMapChangeDescriptors(),
Ghost = ListenerGhost;
descriptors.forEach(function (descriptor, token) {

@@ -111,31 +204,50 @@

return;
} else {
descriptor.isActive = true;
}
var listeners;
if (beforeChange) {
listeners = descriptor.willChangeListeners;
} else {
listeners = descriptor.changeListeners;
}
var listeners = beforeChange ? descriptor.willChangeListeners : descriptor.changeListeners;
if(listeners && listeners._current) {
var tokenName = "handle" + (
token.slice(0, 1).toUpperCase() +
token.slice(1)
) + changeName;
var tokenName = listeners.specificHandlerMethodName;
if(Array.isArray(listeners._current) && listeners._current.length) {
try {
// dispatch to each listener
listeners.forEach(function (listener) {
if (listener[tokenName]) {
listener[tokenName](value, key, this);
} else if (listener.call) {
listener.call(listener, value, key, this);
} else {
throw new Error("Handler " + listener + " has no method " + tokenName + " and is not callable");
//removeGostListenersIfNeeded returns listeners.current or a new filtered one when conditions are met
var currentListeners = listeners.removeCurrentGostListenersIfNeeded(),
i, countI, listener;
descriptor.isActive = true;
try {
for(i=0, countI = currentListeners.length;i<countI;i++) {
// dispatch to each listener
if ((listener = currentListeners[i]) !== Ghost) {
if (listener[tokenName]) {
listener[tokenName](value, key, this);
} else if (listener.call) {
listener.call(listener, value, key, this);
} else {
throw new Error("Handler " + listener + " has no method " + tokenName + " and is not callable");
}
}
}
} finally {
descriptor.isActive = false;
}
}, this);
} finally {
descriptor.isActive = false;
}
else {
descriptor.isActive = true;
// dispatch each listener
try {
listener = listeners._current;
if (listener[tokenName]) {
listener[tokenName](value, key, this);
} else if (listener.call) {
listener.call(listener, value, key, this);
} else {
throw new Error("Handler " + listener + " has no method " + tokenName + " and is not callable");
}
} finally {
descriptor.isActive = false;
}
}
}

@@ -157,2 +269,1 @@

};

@@ -15,4 +15,4 @@ /*

require("../shim");
// objectHasOwnProperty.call(myObject, key) will be used instead of

@@ -66,38 +66,40 @@ // myObject.hasOwnProperty(key) to allow myObject have defined

require("../shim");
var Map = require("../_map");
var WeakMap = require("../weak-map");
var ChangeDescriptor = require("./change-descriptor"),
ObjectChangeDescriptor = ChangeDescriptor.ObjectChangeDescriptor,
ListenerGhost = ChangeDescriptor.ListenerGhost;
PropertyChanges.debug = true;
var ObjectsPropertyChangeListeners = new WeakMap();
var ObjectChangeDescriptorName = new Map();
PropertyChanges.ObjectChangeDescriptor = function() {
}
PropertyChanges.prototype.getOwnPropertyChangeDescriptor = function (key) {
if (!this.__propertyChangeListeners__) {
Object.defineProperty(this, "__propertyChangeListeners__", {
value: {},
enumerable: false,
configurable: true,
writable: true
});
var objectPropertyChangeDescriptors = ObjectsPropertyChangeListeners.get(this), keyChangeDescriptor;
if (!objectPropertyChangeDescriptors) {
objectPropertyChangeDescriptors = Object.create(null);
ObjectsPropertyChangeListeners.set(this,objectPropertyChangeDescriptors);
}
var objectPropertyChangeDescriptors = this.__propertyChangeListeners__;
if (!objectHasOwnProperty.call(objectPropertyChangeDescriptors, key)) {
var propertyName = String(key);
propertyName = propertyName && propertyName[0].toUpperCase() + propertyName.slice(1);
objectPropertyChangeDescriptors[key] = {
willChangeListeners: {
current: [],
active: [],
specificHandlerMethodName: "handle" + propertyName + "WillChange",
genericHandlerMethodName: "handlePropertyWillChange"
},
changeListeners: {
current: [],
active: [],
specificHandlerMethodName: "handle" + propertyName + "Change",
genericHandlerMethodName: "handlePropertyChange"
}
};
if ( (keyChangeDescriptor = objectPropertyChangeDescriptors[key]) === void 0) {
var propertyName = ObjectChangeDescriptorName.get(key);
if(!propertyName) {
propertyName = String(key);
propertyName = propertyName && propertyName[0].toUpperCase() + propertyName.slice(1);
ObjectChangeDescriptorName.set(key,propertyName);
}
return objectPropertyChangeDescriptors[key] = new ObjectChangeDescriptor(propertyName);
}
return objectPropertyChangeDescriptors[key];
return keyChangeDescriptor;
};
PropertyChanges.prototype.hasOwnPropertyChangeDescriptor = function (key) {
if (!this.__propertyChangeListeners__) {
var objectPropertyChangeDescriptors = ObjectsPropertyChangeListeners.get(this);
if (!objectPropertyChangeDescriptors) {
return false;

@@ -108,4 +110,3 @@ }

}
var objectPropertyChangeDescriptors = this.__propertyChangeListeners__;
if (!objectHasOwnProperty.call(objectPropertyChangeDescriptors, key)) {
if (objectPropertyChangeDescriptors[key] === void 0) {
return false;

@@ -121,12 +122,17 @@ }

}
var descriptor = PropertyChanges.getOwnPropertyChangeDescriptor(this, key);
var listeners;
if (beforeChange) {
listeners = descriptor.willChangeListeners;
} else {
listeners = descriptor.changeListeners;
}
var descriptor = PropertyChanges.getOwnPropertyChangeDescriptor(this, key),
listeners = beforeChange ? descriptor.willChangeListeners : descriptor.changeListeners;
PropertyChanges.makePropertyObservable(this, key);
listeners.current.push(listener);
if(!listeners._current) {
listeners._current = listener;
}
else if(!Array.isArray(listeners._current)) {
listeners._current = [listeners._current,listener]
}
else {
listeners._current.push(listener);
}
var self = this;

@@ -143,3 +149,3 @@ return function cancelOwnPropertyChangeListener() {

PropertyChanges.prototype.removeOwnPropertyChangeListener = function (key, listener, beforeChange) {
PropertyChanges.prototype.removeOwnPropertyChangeListener = function removeOwnPropertyChangeListener(key, listener, beforeChange) {
var descriptor = PropertyChanges.getOwnPropertyChangeDescriptor(this, key);

@@ -149,13 +155,30 @@

if (beforeChange) {
listeners = descriptor.willChangeListeners;
listeners = descriptor._willChangeListeners;
} else {
listeners = descriptor.changeListeners;
listeners = descriptor._changeListeners;
}
var index = listeners.current.lastIndexOf(listener);
if (index === -1) {
throw new Error("Can't remove property change listener: does not exist: property name" + JSON.stringify(key));
if(listeners) {
if(listeners._current) {
if(listeners._current === listener) {
listeners._current = null;
}
else {
var index = listeners._current.lastIndexOf(listener);
if (index === -1) {
throw new Error("Can't remove property change listener: does not exist: property name" + JSON.stringify(key));
}
if(descriptor.isActive) {
listeners.ghostCount = listeners.ghostCount+1;
listeners._current[index]=removeOwnPropertyChangeListener.ListenerGhost;
}
else {
listeners._current.spliceOne(index);
}
}
}
}
listeners.current.splice(index, 1);
};
PropertyChanges.prototype.removeOwnPropertyChangeListener.ListenerGhost = ListenerGhost;

@@ -166,3 +189,3 @@ PropertyChanges.prototype.removeBeforeOwnPropertyChangeListener = function (key, listener) {

PropertyChanges.prototype.dispatchOwnPropertyChange = function (key, value, beforeChange) {
PropertyChanges.prototype.dispatchOwnPropertyChange = function dispatchOwnPropertyChange(key, value, beforeChange) {
var descriptor = PropertyChanges.getOwnPropertyChangeDescriptor(this, key),

@@ -173,9 +196,5 @@ listeners;

descriptor.isActive = true;
if (beforeChange) {
listeners = descriptor.willChangeListeners;
} else {
listeners = descriptor.changeListeners;
}
listeners = beforeChange ? descriptor._willChangeListeners: descriptor._changeListeners;
try {
dispatchEach(listeners, key, value, this);
dispatchOwnPropertyChange.dispatchEach(listeners, key, value, this);
} finally {

@@ -186,23 +205,40 @@ descriptor.isActive = false;

};
PropertyChanges.prototype.dispatchOwnPropertyChange.dispatchEach = dispatchEach;
function dispatchEach(listeners, key, value, object) {
// copy snapshot of current listeners to active listeners
var active = listeners.active;
var current = listeners.current;
var index = current.length;
var listener, length = index, i, thisp;
if(listeners && listeners._current) {
// copy snapshot of current listeners to active listeners
var current,
listener,
i,
countI,
thisp,
specificHandlerMethodName = listeners.specificHandlerMethodName,
genericHandlerMethodName = listeners.genericHandlerMethodName,
Ghost = ListenerGhost;
if (active.length > index) {
active.length = index;
}
while (index--) {
active[index] = current[index];
}
for (i = 0; i < length; i++) {
thisp = active[i];
//This is fixing the issue causing a regression in Montage's repetition
if (!i || current.indexOf(thisp) >= 0) {
if(Array.isArray(listeners._current)) {
//removeGostListenersIfNeeded returns listeners.current or a new filtered one when conditions are met
current = listeners.removeCurrentGostListenersIfNeeded();
//We use a for to guarantee we won't dispatch to listeners that would be added after we started
for(i=0, countI = current.length;i<countI;i++) {
if ((thisp = current[i]) !== Ghost) {
//This is fixing the issue causing a regression in Montage's repetition
listener = (
thisp[specificHandlerMethodName] ||
thisp[genericHandlerMethodName] ||
thisp
);
if (!listener.call) {
throw new Error("No event listener for " + listeners.specificHandlerName + " or " + listeners.genericHandlerName + " or call on " + listener);
}
listener.call(thisp, value, key, object);
}
}
}
else {
thisp = listeners._current;
listener = (
thisp[listeners.specificHandlerMethodName] ||
thisp[listeners.genericHandlerMethodName] ||
thisp[specificHandlerMethodName] ||
thisp[genericHandlerMethodName] ||
thisp

@@ -219,2 +255,5 @@ );

dispatchEach.ListenerGhost = ListenerGhost;
PropertyChanges.prototype.dispatchBeforeOwnPropertyChange = function (key, listener) {

@@ -224,2 +263,11 @@ return PropertyChanges.dispatchOwnPropertyChange(this, key, listener, true);

var ObjectsOverriddenPropertyDescriptors = new WeakMap(),
Objects__state__ = new WeakMap(),
propertyListener = {
get: void 0,
set: void 0,
configurable: true,
enumerable: false
};
PropertyChanges.prototype.makePropertyObservable = function (key) {

@@ -232,3 +280,8 @@ // arrays are special. we do not support direct setting of properties

var overriddenPropertyDescriptors = this.__overriddenPropertyDescriptors__;
var overriddenPropertyDescriptors = ObjectsOverriddenPropertyDescriptors.get(this);
if (overriddenPropertyDescriptors && overriddenPropertyDescriptors.get(key) !== void 0) {
// if we have already recorded an overridden property descriptor,
// we have already installed the observer, so short-here
return;
}

@@ -243,29 +296,11 @@ // memoize overridden property descriptor table

}
overriddenPropertyDescriptors = {};
Object.defineProperty(this, "__overriddenPropertyDescriptors__", {
value: overriddenPropertyDescriptors,
enumerable: false,
writable: true,
configurable: true
});
} else {
if (objectHasOwnProperty.call(overriddenPropertyDescriptors, key)) {
// if we have already recorded an overridden property descriptor,
// we have already installed the observer, so short-here
return;
}
overriddenPropertyDescriptors = new Map();
ObjectsOverriddenPropertyDescriptors.set(this,overriddenPropertyDescriptors);
}
var state;
if (typeof this.__state__ === "object") {
state = this.__state__;
} else {
state = {};
Object.defineProperty(this, "__state__", {
value: state,
writable: true,
enumerable: false
});
}
state[key] = this[key];
// var state = Objects__state__.get(this);
// if (typeof state !== "object") {
// Objects__state__.set(this,(state = {}));
// }
// state[key] = this[key];

@@ -288,3 +323,3 @@

overriddenDescriptor = {
value: undefined,
value: void 0,
enumerable: true,

@@ -305,3 +340,3 @@ writable: true,

// and so we can reuse the overridden descriptor when uninstalling
overriddenPropertyDescriptors[key] = overriddenDescriptor;
overriddenPropertyDescriptors.set(key,overriddenDescriptor);

@@ -311,3 +346,2 @@

var propertyListener;
// in both of these new descriptor variants, we reuse the overridden

@@ -320,56 +354,66 @@ // descriptor to either store the current value or apply getters

if ('value' in overriddenDescriptor) {
propertyListener = {
get: function () {
return overriddenDescriptor.value;
},
set: function (value) {
var descriptor,
isActive;
propertyListener.get = function () {
return overriddenDescriptor.value;
};
propertyListener.set = function dispatchingSetter(value) {
var descriptor,
isActive,
overriddenDescriptor = dispatchingSetter.overriddenDescriptor;
if (value !== overriddenDescriptor.value) {
descriptor = this.__propertyChangeListeners__[key];
isActive = descriptor.isActive;
if (!isActive) {
descriptor.isActive = true;
try {
dispatchEach(descriptor.willChangeListeners, key, overriddenDescriptor.value, this);
} finally {}
if (value !== overriddenDescriptor.value) {
descriptor = dispatchingSetter.descriptor;
if (!(isActive = descriptor.isActive)) {
descriptor.isActive = true;
try {
dispatchingSetter.dispatchEach(descriptor._willChangeListeners, key, overriddenDescriptor.value, this);
} finally {}
}
overriddenDescriptor.value = value;
if (!isActive) {
try {
dispatchingSetter.dispatchEach(descriptor._changeListeners, key, value, this);
} finally {
descriptor.isActive = false;
}
overriddenDescriptor.value = value;
state[key] = value;
if (!isActive) {
try {
dispatchEach(descriptor.changeListeners, key, value, this);
} finally {
descriptor.isActive = false;
}
}
}
},
enumerable: overriddenDescriptor.enumerable,
configurable: true
}
};
propertyListener.set.dispatchEach = dispatchEach;
propertyListener.set.overriddenDescriptor = overriddenDescriptor;
propertyListener.set.descriptor = ObjectsPropertyChangeListeners.get(this)[key];
propertyListener.enumerable = overriddenDescriptor.enumerable;
propertyListener.configurable = true
} else { // 'get' or 'set', but not necessarily both
propertyListener = {
get: overriddenDescriptor.get,
set: function (value) {
var formerValue = this[key],
propertyListener.get = overriddenDescriptor.get;
propertyListener.set = function dispatchingSetter() {
var formerValue = dispatchingSetter.overriddenGetter.call(this),
descriptor,
isActive;
isActive,
newValue;
overriddenDescriptor.set.call(this, value);
value = this[key];
if (value !== formerValue) {
descriptor = this.__propertyChangeListeners__[key];
isActive = descriptor.isActive;
if (!isActive) {
if(arguments.length === 1) {
dispatchingSetter.overriddenSetter.call(this,arguments[0]);
}
else if(arguments.length === 2) {
dispatchingSetter.overriddenSetter.call(this,arguments[0],arguments[1]);
}
else {
dispatchingSetter.overriddenSetter.apply(this, arguments);
}
if ((newValue = dispatchingSetter.overriddenGetter.call(this)) !== formerValue) {
descriptor = dispatchingSetter.descriptor;
if (!(isActive = descriptor.isActive)) {
descriptor.isActive = true;
try {
dispatchEach(descriptor.willChangeListeners, key, formerValue, this);
dispatchingSetter.dispatchEach(descriptor._willChangeListeners, key, formerValue, this);
} finally {}
}
state[key] = value;
if (!isActive) {
try {
dispatchEach(descriptor.changeListeners, key, value, this);
dispatchingSetter.dispatchEach(descriptor._changeListeners, key, newValue, this);
} finally {

@@ -380,6 +424,9 @@ descriptor.isActive = false;

}
},
enumerable: overriddenDescriptor.enumerable,
configurable: true
};
};
propertyListener.enumerable = overriddenDescriptor.enumerable;
propertyListener.configurable = true;
propertyListener.set.dispatchEach = dispatchEach;
propertyListener.set.overriddenSetter = overriddenDescriptor.set;
propertyListener.set.overriddenGetter = overriddenDescriptor.get;
propertyListener.set.descriptor = ObjectsPropertyChangeListeners.get(this)[key];
}

@@ -409,7 +456,6 @@

PropertyChanges.addOwnPropertyChangeListener = function (object, key, listener, beforeChange) {
if (!Object.isObject(object)) {
} else if (object.addOwnPropertyChangeListener) {
return object.addOwnPropertyChangeListener(key, listener, beforeChange);
} else {
return PropertyChanges.prototype.addOwnPropertyChangeListener.call(object, key, listener, beforeChange);
if (Object.isObject(object)) {
return object.addOwnPropertyChangeListener
? object.addOwnPropertyChangeListener(key, listener, beforeChange)
: this.prototype.addOwnPropertyChangeListener.call(object, key, listener, beforeChange);
}

@@ -416,0 +462,0 @@ };

"use strict";
var WeakMap = require("weak-map");
var Dict = require("../dict");
//TODO:
// Remove Dict and use native Map as much as possible here
//Use ObjectChangeDescriptor to avoid creating useless arrays and benefit from similar gains made in property-changes
var WeakMap = require("weak-map"),
Map = require("../_map"),
ChangeDescriptor = require("./change-descriptor"),
ObjectChangeDescriptor = ChangeDescriptor.ObjectChangeDescriptor,
ChangeListenersRecord = ChangeDescriptor.ChangeListenersRecord,
ListenerGhost = ChangeDescriptor.ListenerGhost;
var rangeChangeDescriptors = new WeakMap(); // {isActive, willChangeListeners, changeListeners}
//
function RangeChangeDescriptor(name) {
this.name = name;
this.isActive = false;
this._willChangeListeners = null;
this._changeListeners = null;
};
RangeChangeDescriptor.prototype = new ObjectChangeDescriptor();
RangeChangeDescriptor.prototype.constructor = RangeChangeDescriptor;
RangeChangeDescriptor.prototype.changeListenersRecordConstructor = RangeChangeListenersRecord;
RangeChangeDescriptor.prototype.willChangeListenersRecordConstructor = RangeWillChangeListenersRecord;
Object.defineProperty(RangeChangeDescriptor.prototype,"active",{
get: function() {
return this._active || (this._active = this._current ? this._current.slice():[]);
}
});
var RangeChangeListenersSpecificHandlerMethodName = new Map();
function RangeChangeListenersRecord(name) {
var specificHandlerMethodName = RangeChangeListenersSpecificHandlerMethodName.get(name);
if(!specificHandlerMethodName) {
specificHandlerMethodName = "handle";
specificHandlerMethodName += name.slice(0, 1).toUpperCase();
specificHandlerMethodName += name.slice(1);
specificHandlerMethodName += "RangeChange";
RangeChangeListenersSpecificHandlerMethodName.set(name,specificHandlerMethodName);
}
this.specificHandlerMethodName = specificHandlerMethodName;
return this;
}
RangeChangeListenersRecord.prototype = new ChangeListenersRecord();
RangeChangeListenersRecord.prototype.constructor = RangeChangeListenersRecord;
var RangeWillChangeListenersSpecificHandlerMethodName = new Map();
function RangeWillChangeListenersRecord(name) {
var specificHandlerMethodName = RangeWillChangeListenersSpecificHandlerMethodName.get(name);
if(!specificHandlerMethodName) {
specificHandlerMethodName = "handle";
specificHandlerMethodName += name.slice(0, 1).toUpperCase();
specificHandlerMethodName += name.slice(1);
specificHandlerMethodName += "RangeWillChange";
RangeWillChangeListenersSpecificHandlerMethodName.set(name,specificHandlerMethodName);
}
this.specificHandlerMethodName = specificHandlerMethodName;
return this;
}
RangeWillChangeListenersRecord.prototype = new ChangeListenersRecord();
RangeWillChangeListenersRecord.prototype.constructor = RangeWillChangeListenersRecord;
module.exports = RangeChanges;

@@ -15,3 +79,3 @@ function RangeChanges() {

if (!rangeChangeDescriptors.has(this)) {
rangeChangeDescriptors.set(this, Dict());
rangeChangeDescriptors.set(this, new Map());
}

@@ -25,7 +89,3 @@ return rangeChangeDescriptors.get(this);

if (!tokenChangeDescriptors.has(token)) {
tokenChangeDescriptors.set(token, {
isActive: false,
changeListeners: [],
willChangeListeners: []
});
tokenChangeDescriptors.set(token, new RangeChangeDescriptor(token));
}

@@ -35,3 +95,18 @@ return tokenChangeDescriptors.get(token);

RangeChanges.prototype.addRangeChangeListener = function (listener, token, beforeChange) {
var ObjectsDispatchesRangeChanges = new WeakMap(),
dispatchesRangeChangesGetter = function() {
return ObjectsDispatchesRangeChanges.get(this);
},
dispatchesRangeChangesSetter = function(value) {
return ObjectsDispatchesRangeChanges.set(this,value);
},
dispatchesChangesMethodName = "dispatchesRangeChanges",
dispatchesChangesPropertyDescriptor = {
get: dispatchesRangeChangesGetter,
set: dispatchesRangeChangesSetter,
configurable: true,
enumerable: false
};
RangeChanges.prototype.addRangeChangeListener = function addRangeChangeListener(listener, token, beforeChange) {
// a concession for objects like Array that are not inherently observable

@@ -52,10 +127,17 @@ if (!this.isObservable && this.makeObservable) {

// even if already registered
listeners.push(listener);
Object.defineProperty(this, "dispatchesRangeChanges", {
value: true,
writable: true,
configurable: true,
enumerable: false
});
if(!listeners._current) {
listeners._current = listener;
}
else if(!Array.isArray(listeners._current)) {
listeners._current = [listeners._current,listener]
}
else {
listeners._current.push(listener);
}
if(Object.getOwnPropertyDescriptor((this.__proto__||Object.getPrototypeOf(this)),dispatchesChangesMethodName) === void 0) {
Object.defineProperty((this.__proto__||Object.getPrototypeOf(this)), dispatchesChangesMethodName, dispatchesChangesPropertyDescriptor);
}
this.dispatchesRangeChanges = true;
var self = this;

@@ -72,2 +154,3 @@ return function cancelRangeChangeListener() {

RangeChanges.prototype.removeRangeChangeListener = function (listener, token, beforeChange) {

@@ -78,12 +161,28 @@ var descriptor = this.getRangeChangeDescriptor(token);

if (beforeChange) {
listeners = descriptor.willChangeListeners;
listeners = descriptor._willChangeListeners;
} else {
listeners = descriptor.changeListeners;
listeners = descriptor._changeListeners;
}
var index = listeners.lastIndexOf(listener);
if (index === -1) {
throw new Error("Can't remove range change listener: does not exist: token " + JSON.stringify(token));
if(listeners._current) {
if(listeners._current === listener) {
listeners._current = null;
}
else {
var index = listeners._current.lastIndexOf(listener);
if (index === -1) {
throw new Error("Can't remove range change listener: does not exist: token " + JSON.stringify(token));
}
else {
if(descriptor.isActive) {
listeners.ghostCount = listeners.ghostCount+1
listeners._current[index]=ListenerGhost
}
else {
listeners._current.spliceOne(index);
}
}
}
}
listeners.splice(index, 1);
};

@@ -93,43 +192,60 @@

var descriptors = this.getAllRangeChangeDescriptors();
var changeName = "Range" + (beforeChange ? "WillChange" : "Change");
descriptors.forEach(function (descriptor, token) {
descriptors.dispatchBeforeChange = beforeChange;
descriptors.forEach(function (descriptor, token, descriptors) {
if (descriptor.isActive) {
return;
} else {
descriptor.isActive = true;
}
// before or after
var listeners;
if (beforeChange) {
listeners = descriptor.willChangeListeners;
} else {
listeners = descriptor.changeListeners;
}
var listeners = beforeChange ? descriptor._willChangeListeners : descriptor._changeListeners;
if(listeners && listeners._current) {
var tokenName = listeners.specificHandlerMethodName;
if(Array.isArray(listeners._current) && listeners._current.length) {
// notably, defaults to "handleRangeChange" or "handleRangeWillChange"
// if token is "" (the default)
var tokenName = "handle" + (
token.slice(0, 1).toUpperCase() +
token.slice(1)
) + changeName;
// notably, defaults to "handleRangeChange" or "handleRangeWillChange"
// if token is "" (the default)
// dispatch each listener
try {
listeners.slice().forEach(function (listener) {
if (listeners.indexOf(listener) < 0) {
return;
descriptor.isActive = true;
// dispatch each listener
try {
var i,
countI,
listener,
//removeGostListenersIfNeeded returns listeners.current or a new filtered one when conditions are met
currentListeners = listeners.removeCurrentGostListenersIfNeeded(),
Ghost = ListenerGhost;
for(i=0, countI = currentListeners.length;i<countI;i++) {
if ((listener = currentListeners[i]) !== Ghost) {
if (listener[tokenName]) {
listener[tokenName](plus, minus, index, this, beforeChange);
} else if (listener.call) {
listener.call(this, plus, minus, index, this, beforeChange);
} else {
throw new Error("Handler " + listener + " has no method " + tokenName + " and is not callable");
}
}
}
} finally {
descriptor.isActive = false;
}
if (listener[tokenName]) {
listener[tokenName](plus, minus, index, this, beforeChange);
} else if (listener.call) {
listener.call(this, plus, minus, index, this, beforeChange);
} else {
throw new Error("Handler " + listener + " has no method " + tokenName + " and is not callable");
}
else {
descriptor.isActive = true;
// dispatch each listener
try {
listener = listeners._current;
if (listener[tokenName]) {
listener[tokenName](plus, minus, index, this, beforeChange);
} else if (listener.call) {
listener.call(this, plus, minus, index, this, beforeChange);
} else {
throw new Error("Handler " + listener + " has no method " + tokenName + " and is not callable");
}
} finally {
descriptor.isActive = false;
}
}, this);
} finally {
descriptor.isActive = false;
}
}
}, this);

@@ -149,2 +265,1 @@ };

};

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

var PropertyChanges = require("./listen/property-changes");
var MapChanges = require("./listen/map-changes");

@@ -41,3 +42,7 @@ module.exports = LruMap;

Object.addEach(LruMap.prototype, PropertyChanges.prototype);
Object.addEach(LruMap.prototype, MapChanges.prototype);
Object.defineProperty(LruMap.prototype,"size",GenericCollection._sizePropertyDescriptor);
LruMap.from = GenericCollection.from;
LruMap.prototype.constructClone = function (values) {

@@ -79,4 +84,3 @@ return new this.constructor(

}
GenericMap.prototype.addMapChangeListener.apply(this, arguments);
MapChanges.prototype.addMapChangeListener.apply(this, arguments);
};
"use strict";
var Shim = require("./shim");
var Set = require("./set");
var Set = require("./set").CollectionsSet;
var GenericCollection = require("./generic-collection");

@@ -35,2 +35,4 @@ var GenericSet = require("./generic-set");

Object.addEach(LruSet.prototype, RangeChanges.prototype);
Object.defineProperty(LruSet.prototype,"size",GenericCollection._sizePropertyDescriptor);
LruSet.from = GenericCollection.from;

@@ -149,2 +151,1 @@ LruSet.prototype.constructClone = function (values) {

};
"use strict";
var Shim = require("./shim");
var Set = require("./set");
var GenericCollection = require("./generic-collection");
var GenericMap = require("./generic-map");
var Map = require("./_map");
var PropertyChanges = require("./listen/property-changes");
var MapChanges = require("./listen/map-changes");
module.exports = Map;
function Map(values, equals, hash, getDefault) {
if (!(this instanceof Map)) {
return new Map(values, equals, hash, getDefault);
}
equals = equals || Object.equals;
hash = hash || Object.hash;
getDefault = getDefault || Function.noop;
this.contentEquals = equals;
this.contentHash = hash;
this.getDefault = getDefault;
this.store = new Set(
undefined,
function keysEqual(a, b) {
return equals(a.key, b.key);
},
function keyHash(item) {
return hash(item.key);
}
);
this.length = 0;
this.addEach(values);
if(global.Map === void 0) {
Object.addEach(Map.prototype, PropertyChanges.prototype);
Object.addEach(Map.prototype, MapChanges.prototype);
}
else {
Map.Map = Map; // hack so require("map").Map will work in MontageJS
Object.addEach(Map.prototype, GenericCollection.prototype);
Object.addEach(Map.prototype, GenericMap.prototype); // overrides GenericCollection
Object.addEach(Map.prototype, PropertyChanges.prototype);
Object.defineProperty(Map.prototype,"size",GenericCollection._sizePropertyDescriptor);
Map.prototype.constructClone = function (values) {
return new this.constructor(
values,
this.contentEquals,
this.contentHash,
this.getDefault
);
};
Map.prototype.log = function (charmap, logNode, callback, thisp) {
logNode = logNode || this.logNode;
this.store.log(charmap, function (node, log, logBefore) {
logNode(node.value.value, log, logBefore);
}, callback, thisp);
};
Map.prototype.logNode = function (node, log) {
log(' key: ' + node.key);
log(' value: ' + node.value);
};
Object.defineEach(Map.prototype, PropertyChanges.prototype, false, /*configurable*/true, /*enumerable*/ false, /*writable*/true);
Object.defineEach(Map.prototype, MapChanges.prototype, false, /*configurable*/true, /*enumerable*/ false, /*writable*/true);
}
"use strict";
var Map = require("./map");
var Map = require("./map").CollectionsMap;

@@ -41,2 +41,1 @@ module.exports = MultiMap;

};
{
"name": "collections",
"version": "3.0.0",
"version": "5.0.0",
"description": "data structures with idiomatic JavaScript collection interfaces",

@@ -34,3 +34,3 @@ "homepage": "http://www.collectionsjs.com",

"devDependencies": {
"jasmine-node": "~1.14.x",
"jasmine-node": "montagestudio/jasmine-node#master",
"istanbul": "*",

@@ -37,0 +37,0 @@ "opener": "*"

"use strict";
var Shim = require("./shim");
var List = require("./list");
var FastSet = require("./fast-set");
var GenericCollection = require("./generic-collection");
var GenericSet = require("./generic-set");
var Set = require("./_set");
var PropertyChanges = require("./listen/property-changes");
var RangeChanges = require("./listen/range-changes");
var Iterator = require("./iterator");
var MapChanges = require("./listen/map-changes");
var GlobalSet;
module.exports = Set;
function Set(values, equals, hash, getDefault) {
if (!(this instanceof Set)) {
return new Set(values, equals, hash, getDefault);
if(global.Set !== void 0) {
GlobalSet = global.Set;
module.exports = Set
// use different strategies for making sets observable between Internet
// Explorer and other browsers.
var protoIsSupported = {}.__proto__ === Object.prototype,
set_makeObservable;
if (protoIsSupported) {
set_makeObservable = function () {
this.__proto__ = ChangeDispatchSet;
};
} else {
set_makeObservable = function () {
Object.defineProperties(this, observableSetProperties);
};
}
equals = equals || Object.equals;
hash = hash || Object.hash;
getDefault = getDefault || Function.noop;
this.contentEquals = equals;
this.contentHash = hash;
this.getDefault = getDefault;
// a list of values in insertion order, used for all operations that depend
// on iterating in insertion order
this.order = new this.Order(undefined, equals);
// a set of nodes from the order list, indexed by the corresponding value,
// used for all operations that need to quickly seek value in the list
this.store = new this.Store(
undefined,
function (a, b) {
return equals(a.value, b.value);
Object.defineProperty(GlobalSet.prototype, "makeObservable", {
value: set_makeObservable,
writable: true,
configurable: true,
enumerable: false
});
var set_clear = GlobalSet.prototype.clear,
set_add = GlobalSet.prototype.add,
set_delete = GlobalSet.prototype.delete;
var observableSetProperties = {
"_dispatchEmptyArray": {
value: []
},
function (node) {
return hash(node.value);
}
);
this.length = 0;
this.addEach(values);
}
clear : {
value: function () {
var clearing;
if (this.dispatchesRangeChanges) {
clearing = this.toArray();
this.dispatchBeforeRangeChange(this._dispatchEmptyArray, clearing, 0);
}
Set.Set = Set; // hack so require("set").Set will work in MontageJS
set_clear.call(this);
Object.addEach(Set.prototype, GenericCollection.prototype);
Object.addEach(Set.prototype, GenericSet.prototype);
Object.addEach(Set.prototype, PropertyChanges.prototype);
Object.addEach(Set.prototype, RangeChanges.prototype);
if (this.dispatchesRangeChanges) {
this.dispatchRangeChange(this._dispatchEmptyArray, clearing, 0);
}
},
writable: true,
configurable: true
Object.defineProperty(Set.prototype,"size",GenericCollection._sizePropertyDescriptor);
},
add : {
value: function (value) {
if (!this.has(value)) {
var index = this.size;
var dispatchValueArray = [value];
if (this.dispatchesRangeChanges) {
this.dispatchBeforeRangeChange(dispatchValueArray, this._dispatchEmptyArray, index);
}
Set.prototype.Order = List;
Set.prototype.Store = FastSet;
set_add.call(this,value);
Set.prototype.constructClone = function (values) {
return new this.constructor(values, this.contentEquals, this.contentHash, this.getDefault);
};
if (this.dispatchesRangeChanges) {
this.dispatchRangeChange(dispatchValueArray, this._dispatchEmptyArray, index);
}
return true;
}
return false;
},
writable: true,
configurable: true
},
Set.prototype.has = function (value) {
var node = new this.order.Node(value);
return this.store.has(node);
};
"delete": {
value: function (value,index) {
if (this.has(value)) {
if(index === undefined) {
var setIterator = this.values();
index = 0
while(setIterator.next().value !== value) {
index++;
}
}
var dispatchValueArray = [value];
if (this.dispatchesRangeChanges) {
this.dispatchBeforeRangeChange(this._dispatchEmptyArray, dispatchValueArray, index);
}
Set.prototype.get = function (value, equals) {
if (equals) {
throw new Error("Set#get does not support second argument: equals");
}
var node = new this.order.Node(value);
node = this.store.get(node);
if (node) {
return node.value;
} else {
return this.getDefault(value);
}
};
set_delete.call(this,value);
Set.prototype.add = function (value) {
var node = new this.order.Node(value);
if (!this.store.has(node)) {
var index = this.length;
if (this.dispatchesRangeChanges) {
this.dispatchBeforeRangeChange([value], [], index);
if (this.dispatchesRangeChanges) {
this.dispatchRangeChange(this._dispatchEmptyArray, dispatchValueArray, index);
}
return true;
}
return false;
}
}
this.order.add(value);
node = this.order.head.prev;
this.store.add(node);
this.length++;
if (this.dispatchesRangeChanges) {
this.dispatchRangeChange([value], [], index);
}
return true;
}
return false;
};
};
Set.prototype["delete"] = function (value, equals) {
if (equals) {
throw new Error("Set#delete does not support second argument: equals");
}
var node = new this.order.Node(value);
if (this.store.has(node)) {
node = this.store.get(node);
if (this.dispatchesRangeChanges) {
this.dispatchBeforeRangeChange([], [value], node.index);
}
this.store["delete"](node); // removes from the set
this.order.splice(node, 1); // removes the node from the list
this.length--;
if (this.dispatchesRangeChanges) {
this.dispatchRangeChange([], [value], node.index);
}
return true;
}
return false;
};
var ChangeDispatchSet = Object.create(GlobalSet.prototype, observableSetProperties);
Set.prototype.pop = function () {
if (this.length) {
var result = this.order.head.prev.value;
this["delete"](result);
return result;
}
};
Set.prototype.shift = function () {
if (this.length) {
var result = this.order.head.next.value;
this["delete"](result);
return result;
}
};
Object.defineEach(Set.prototype, PropertyChanges.prototype, false, /*configurable*/true, /*enumerable*/ false, /*writable*/true);
//This is a no-op test in property-changes.js - PropertyChanges.prototype.makePropertyObservable, so might as well not pay the price every time....
Object.defineProperty(Set.prototype, "makePropertyObservable", {
value: function(){},
writable: true,
configurable: true,
enumerable: false
});
Set.prototype.one = function () {
if (this.length > 0) {
return this.store.one().value;
}
};
Object.defineEach(Set.prototype, RangeChanges.prototype, false, /*configurable*/true, /*enumerable*/ false, /*writable*/true);
Object.defineEach(Set.prototype, MapChanges.prototype, false, /*configurable*/true, /*enumerable*/ false, /*writable*/true);
Set.prototype.clear = function () {
var clearing;
if (this.dispatchesRangeChanges) {
clearing = this.toArray();
this.dispatchBeforeRangeChange([], clearing, 0);
}
var _CollectionsSet = Set.CollectionsSet;
function CollectionsSet(values, equals, hash, getDefault) {
return _CollectionsSet._init(CollectionsSet, this, values, equals, hash, getDefault);
}
this.store.clear();
this.order.clear();
this.length = 0;
if (this.dispatchesRangeChanges) {
this.dispatchRangeChange([], clearing, 0);
}
};
Set.prototype.reduce = function (callback, basis /*, thisp*/) {
var thisp = arguments[2];
var list = this.order;
var index = 0;
return list.reduce(function (basis, value) {
return callback.call(thisp, basis, value, index++, this);
}, basis, this);
};
// hack so require("set").Set will work in MontageJS
CollectionsSet.Set = CollectionsSet;
CollectionsSet.from = _CollectionsSet.from;
Set.CollectionsSet = CollectionsSet;
Set.prototype.reduceRight = function (callback, basis /*, thisp*/) {
var thisp = arguments[2];
var list = this.order;
var index = this.length - 1;
return list.reduceRight(function (basis, value) {
return callback.call(thisp, basis, value, index--, this);
}, basis, this);
};
CollectionsSet.prototype = new _CollectionsSet();
CollectionsSet.prototype.constructor = CollectionsSet;
Set.prototype.iterate = function () {
return this.order.iterate();
};
var List = require("./list");
var FastSet = require("./fast-set");
CollectionsSet.prototype.Order = List;
CollectionsSet.prototype.Store = FastSet;
Set.prototype.values = function () {
return new Iterator(this);
};
Object.defineProperty(CollectionsSet.prototype,"_dispatchEmptyArray", {
value: []
});
Set.prototype.log = function () {
var set = this.store;
return set.log.apply(set, arguments);
};
CollectionsSet.prototype.add = function (value) {
var node = new this.order.Node(value);
if (!this.store.has(node)) {
var index = this.length;
var dispatchValueArray = [value];
if (this.dispatchesRangeChanges) {
this.dispatchBeforeRangeChange(dispatchValueArray, this._dispatchEmptyArray, index);
}
this.order.add(value);
node = this.order.head.prev;
this.store.add(node);
this.length++;
if (this.dispatchesRangeChanges) {
this.dispatchRangeChange(dispatchValueArray, this._dispatchEmptyArray, index);
}
return true;
}
return false;
};
CollectionsSet.prototype["delete"] = function (value, equals) {
if (equals) {
throw new Error("Set#delete does not support second argument: equals");
}
var node = new this.order.Node(value);
if (this.store.has(node)) {
node = this.store.get(node);
var dispatchValueArray = [value];
if (this.dispatchesRangeChanges) {
this.dispatchBeforeRangeChange(this._dispatchEmptyArray, dispatchValueArray, node.index);
}
this.store["delete"](node); // removes from the set
this.order.splice(node, 1); // removes the node from the list
this.length--;
if (this.dispatchesRangeChanges) {
this.dispatchRangeChange(this._dispatchEmptyArray, dispatchValueArray, node.index);
}
return true;
}
return false;
};
CollectionsSet.prototype.clear = function () {
var clearing;
if (this.dispatchesRangeChanges) {
clearing = this.toArray();
this.dispatchBeforeRangeChange(this._dispatchEmptyArray, clearing, 0);
}
this._clear();
if (this.dispatchesRangeChanges) {
this.dispatchRangeChange(this._dispatchEmptyArray, clearing, 0);
}
};
Set.prototype.makeObservable = function () {
if(global.Set === void 0) {
module.exports = CollectionsSet
}
Object.addEach(Set.CollectionsSet.prototype, PropertyChanges.prototype);
Object.addEach(Set.CollectionsSet.prototype, RangeChanges.prototype);
Set.CollectionsSet.prototype.makeObservable = function () {
this.order.makeObservable();
};

@@ -115,3 +115,3 @@ "use strict";

if (index !== -1) {
this.splice(index, 1);
this.spliceOne(index);
return true;

@@ -258,3 +258,3 @@ }

length = Math.min(this.length, that.length);
length = (this.length < that.length) ? this.length : that.length;

@@ -340,2 +340,19 @@ for (i = 0; i < length; i++) {

if(Array.prototype.spliceOne === void 0) {
define("spliceOne", function (index,itemToAdd) {
var len=this.length;
if (!len) { return }
if(arguments.length === 1) {
while (index<len) {
this[index] = this[index+1];
index++
}
this.length--;
}
else {
this[index] = itemToAdd;
}
});
}
define("Iterator", ArrayIterator);

@@ -342,0 +359,0 @@

@@ -194,3 +194,4 @@ "use strict";

Object.addEach = function (target, source) {
Object.addEach = function (target, source, overrides) {
var overridesExistingProperty = arguments.length === 3 ? overrides : true;
if (!source) {

@@ -216,5 +217,7 @@ } else if (typeof source.forEach === "function" && !source.hasOwnProperty("forEach")) {

// copy other objects as map-alikes
Object.keys(source).forEach(function (key) {
target[key] = source[key];
});
for(var keys = Object.keys(source), i = 0, key;(key = keys[i]); i++) {
if(overridesExistingProperty || !Object.owns(target,key)) {
target[key] = source[key];
}
}
}

@@ -224,2 +227,73 @@ return target;

/*
var defineEach = function defineEach(target, prototype) {
// console.log("Map defineEach: ",Object.keys(prototype));
var proto = Map.prototype;
for (var name in prototype) {
if(!proto.hasOwnProperty(name)) {
Object.defineProperty(proto, name, {
value: prototype[name],
writable: writable,
configurable: configurable,
enumerable: enumerable
});
}
}
}
*/
Object.defineEach = function (target, source, overrides, configurable, enumerable, writable) {
var overridesExistingProperty = arguments.length === 3 ? overrides : true;
if (!source) {
} else if (typeof source.forEach === "function" && !source.hasOwnProperty("forEach")) {
// copy map-alikes
if (source.isMap === true) {
source.forEach(function (value, key) {
Object.defineProperty(target, key, {
value: value,
writable: writable,
configurable: configurable,
enumerable: enumerable
});
});
// iterate key value pairs of other iterables
} else {
source.forEach(function (pair) {
Object.defineProperty(target, pair[0], {
value: pair[1],
writable: writable,
configurable: configurable,
enumerable: enumerable
});
});
}
} else if (typeof source.length === "number") {
// arguments, strings
for (var index = 0; index < source.length; index++) {
Object.defineProperty(target, index, {
value: source[index],
writable: writable,
configurable: configurable,
enumerable: enumerable
});
}
} else {
// copy other objects as map-alikes
for(var keys = Object.keys(source), i = 0, key;(key = keys[i]); i++) {
if(overridesExistingProperty || !Object.owns(target,key)) {
Object.defineProperty(target, key, {
value: source[key],
writable: writable,
configurable: configurable,
enumerable: enumerable
});
}
}
}
return target;
};
/**

@@ -355,2 +429,3 @@ Iterates over the owned properties of an object.

equals = equals || Object.equals;
//console.log("Object.equals: a:",a, "b:",b, "equals:",equals);
// unbox objects, but do not confuse object literals

@@ -357,0 +432,0 @@ a = Object.getValueOf(a);

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

var PropertyChanges = require("./listen/property-changes");
var MapChanges = require("./listen/map-changes");

@@ -41,3 +42,6 @@ module.exports = SortedArrayMap;

Object.addEach(SortedArrayMap.prototype, PropertyChanges.prototype);
Object.addEach(SortedArrayMap.prototype, MapChanges.prototype);
SortedArrayMap.from = GenericCollection.from;
SortedArrayMap.prototype.isSorted = true;

@@ -53,2 +57,1 @@

};

@@ -27,2 +27,4 @@ "use strict";

SortedArraySet.from = SortedArray.from;
SortedArraySet.prototype.isSorted = true;

@@ -54,2 +56,1 @@

};

@@ -31,2 +31,4 @@ "use strict";

SortedArray.from = GenericCollection.from;
Object.addEach(SortedArray.prototype, GenericCollection.prototype);

@@ -132,3 +134,3 @@ Object.addEach(SortedArray.prototype, PropertyChanges.prototype);

if (this.dispatchesRangeChanges) {
this.dispatchBeforeRangeChange([value], [], index);
this.dispatchBeforeRangeChange([value], Array.empty, index);
}

@@ -138,3 +140,3 @@ this.array.splice(index, 0, value);

if (this.dispatchesRangeChanges) {
this.dispatchRangeChange([value], [], index);
this.dispatchRangeChange([value], Array.empty, index);
}

@@ -151,8 +153,8 @@ return true;

if (this.dispatchesRangeChanges) {
this.dispatchBeforeRangeChange([], [value], index);
this.dispatchBeforeRangeChange(Array.empty, [value], index);
}
this.array.splice(index, 1);
this.array.spliceOne(index);
this.length--;
if (this.dispatchesRangeChanges) {
this.dispatchRangeChange([], [value], index);
this.dispatchRangeChange(Array.empty, [value], index);
}

@@ -179,3 +181,3 @@ return true;

if (this.dispatchesRangeChanges) {
this.dispatchBeforeRangeChange([], minus, start);
this.dispatchBeforeRangeChange(Array.empty, minus, start);
}

@@ -185,3 +187,3 @@ this.array.splice(start, minus.length);

if (this.dispatchesRangeChanges) {
this.dispatchRangeChange([], minus, start);
this.dispatchRangeChange(Array.empty, minus, start);
}

@@ -258,3 +260,3 @@ return minus.length;

if (index === undefined && length === undefined) {
return [];
return Array.empty;
}

@@ -275,3 +277,3 @@ index = index || 0;

if (this.dispatchesRangeChanges) {
this.dispatchRangeChange([], minus, index);
this.dispatchRangeChange(Array.empty, minus, index);
}

@@ -316,3 +318,3 @@ this.addEach(plus);

minus = this.array.slice();
this.dispatchBeforeRangeChange([], minus, 0);
this.dispatchBeforeRangeChange(Array.empty, minus, 0);
}

@@ -322,3 +324,3 @@ this.length = 0;

if (this.dispatchesRangeChanges) {
this.dispatchRangeChange([], minus, 0);
this.dispatchRangeChange(Array.empty, minus, 0);
}

@@ -325,0 +327,0 @@ };

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

var PropertyChanges = require("./listen/property-changes");
var MapChanges = require("./listen/map-changes");

@@ -38,5 +39,9 @@ module.exports = SortedMap;

SortedMap.from = GenericCollection.from;
Object.addEach(SortedMap.prototype, GenericCollection.prototype);
Object.addEach(SortedMap.prototype, GenericMap.prototype);
Object.addEach(SortedMap.prototype, PropertyChanges.prototype);
Object.addEach(SortedMap.prototype, MapChanges.prototype);
Object.defineProperty(SortedMap.prototype,"size",GenericCollection._sizePropertyDescriptor);

@@ -51,2 +56,5 @@ SortedMap.prototype.constructClone = function (values) {

};
SortedMap.prototype.iterate = function () {
return this.store.iterate();
};

@@ -64,2 +72,1 @@ SortedMap.prototype.log = function (charmap, logNode, callback, thisp) {

};

@@ -31,2 +31,4 @@ "use strict";

Object.addEach(SortedSet.prototype, RangeChanges.prototype);
Object.defineProperty(SortedSet.prototype,"size",GenericCollection._sizePropertyDescriptor);
SortedSet.from = GenericCollection.from;

@@ -33,0 +35,0 @@ SortedSet.prototype.isSorted = true;

@@ -1,1 +0,1 @@

module.exports = require("weak-map");
module.exports = (global.WeakMap !== void 0) ? global.WeakMap : require("weak-map");
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