seamless-immutable
Advanced tools
Comparing version 2.4.2 to 3.0.0
{ | ||
"name": "seamless-immutable", | ||
"main": "seamless-immutable.js", | ||
"version": "2.4.2", | ||
"version": "3.0.0", | ||
"homepage": "https://github.com/rtfeldman/seamless-immutable", | ||
@@ -6,0 +6,0 @@ "authors": [ |
{ | ||
"name": "seamless-immutable", | ||
"version": "2.4.2", | ||
"version": "3.0.0", | ||
"description": "Immutable data structures for JavaScript which are backwards-compatible with normal JS Arrays and Objects.", | ||
@@ -5,0 +5,0 @@ "main": "seamless-immutable.development.js", |
@@ -72,4 +72,4 @@ seamless-immutable | ||
Like a regular Array, but immutable! You can construct these either by passing | ||
an array to `Immutable()`, or simply by passing it multiple arguments: | ||
Like a regular Array, but immutable! You can construct these by passing | ||
an array to `Immutable()`: | ||
@@ -79,8 +79,2 @@ ```javascript | ||
// An immutable array containing 1, 2, and 3. | ||
Immutable(1, 2, 3) | ||
// Also an immutable array containing 1, 2, and 3. | ||
Immutable(1) | ||
// Just the number 1 (not an array), as numbers are already immutable in JS. | ||
``` | ||
@@ -149,2 +143,15 @@ | ||
To construct an Immutable Object with a custom prototype, simply specify the | ||
prototype in `options` (while useful for preserving prototypes, please note | ||
that custom mutator methods will not work as the object will be immutable): | ||
``` | ||
function Square(length) { this.length = length }; | ||
Square.prototype.area = function() { return Math.pow(this.length, 2) }; | ||
Immutable(new Square(2), {prototype: Square.prototype}).area(); | ||
// An immutable object, with prototype Square, | ||
// containing the key "length" and method `area()` returning 4 | ||
``` | ||
Beyond [the usual Object fare](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Methods_of_Object_instances), the following methods have been added. | ||
@@ -204,2 +211,7 @@ | ||
#### 3.0.0 | ||
Add support for optional prototyping. | ||
#### 2.4.2 | ||
@@ -206,0 +218,0 @@ |
@@ -160,3 +160,3 @@ (function(){ | ||
var result = {}; | ||
var result = this.instantiateEmptyObject(); | ||
@@ -169,3 +169,4 @@ for (var key in this) { | ||
return makeImmutableObject(result); | ||
return makeImmutableObject(result, | ||
{instantiateEmptyObject: this.instantiateEmptyObject}); | ||
} | ||
@@ -253,3 +254,3 @@ | ||
var anyChanges = false, | ||
result = quickCopy(this, {}), // A shallow clone of this object. | ||
result = quickCopy(this, this.instantiateEmptyObject()), // A shallow clone of this object. | ||
receivedArray = (other instanceof Array), | ||
@@ -306,3 +307,4 @@ deep = config && config.deep, | ||
if (anyChanges) { | ||
return makeImmutableObject(result); | ||
return makeImmutableObject(result, | ||
{instantiateEmptyObject: this.instantiateEmptyObject}); | ||
} else { | ||
@@ -314,3 +316,3 @@ return this; | ||
function asMutableObject(opts) { | ||
var result = {}, key; | ||
var result = this.instantiateEmptyObject(), key; | ||
@@ -334,7 +336,18 @@ if(opts && opts.deep) { | ||
// Creates plain object to be used for cloning | ||
function instantiatePlainObject() { | ||
return {}; | ||
} | ||
// Finalizes an object with immutable methods, freezes it, and returns it. | ||
function makeImmutableObject(obj) { | ||
function makeImmutableObject(obj, options) { | ||
var instantiateEmptyObject = | ||
(options && options.instantiateEmptyObject) | ||
? options.instantiateEmptyObject | ||
: instantiatePlainObject; | ||
addPropertyTo(obj, "merge", merge); | ||
addPropertyTo(obj, "without", without); | ||
addPropertyTo(obj, "asMutable", asMutableObject); | ||
addPropertyTo(obj, "instantiateEmptyObject", instantiateEmptyObject); | ||
@@ -344,7 +357,4 @@ return makeImmutable(obj, mutatingObjectMethods); | ||
function Immutable(obj) { | ||
// If the user passes multiple arguments, assume what they want is an array. | ||
if (arguments.length > 1) { | ||
return makeImmutableArray(Array.prototype.slice.call(arguments)); | ||
} else if (isImmutable(obj)) { | ||
function Immutable(obj, options) { | ||
if (isImmutable(obj)) { | ||
return obj; | ||
@@ -357,3 +367,8 @@ } else if (obj instanceof Array) { | ||
// Don't freeze the object we were given; make a clone and use that. | ||
var clone = {}; | ||
var prototype = options && options.prototype; | ||
var instantiateEmptyObject = | ||
(!prototype || prototype === Object.prototype) | ||
? instantiatePlainObject | ||
: (function() { return Object.create(prototype); }); | ||
var clone = instantiateEmptyObject(); | ||
@@ -366,3 +381,4 @@ for (var key in obj) { | ||
return makeImmutableObject(clone); | ||
return makeImmutableObject(clone, | ||
{instantiateEmptyObject: instantiateEmptyObject}); | ||
} | ||
@@ -369,0 +385,0 @@ } |
@@ -1,1 +0,1 @@ | ||
!function(){"use strict";function a(a,b,c){Object.defineProperty(a,b,{enumerable:!1,configurable:!1,writable:!1,value:c})}function b(b){a(b,s,!0)}function c(a){return"object"==typeof a?null===a||a.hasOwnProperty(s):!0}function d(a){return!(null===a||"object"!=typeof a||a instanceof Array||a instanceof Date)}function e(a){var b=new Error(a);return b.__proto__=e,b}function f(a,c){b(a);return a}function g(b,c){var d=b[c];a(b,c,function(){return r(d.apply(b,arguments))})}function h(b){for(var c in w)if(w.hasOwnProperty(c)){var d=w[c];g(b,d)}a(b,"flatMap",i),a(b,"asObject",l),a(b,"asMutable",k);for(var e=0,h=b.length;h>e;e++)b[e]=r(b[e]);return f(b,v)}function i(a){if(0===arguments.length)return this;var b,c=[],d=this.length;for(b=0;d>b;b++){var e=a(this[b],b,this);e instanceof Array?c.push.apply(c,e):c.push(e)}return h(c)}function j(a){if(0===arguments.length)return this;a instanceof Array||(a=Array.prototype.slice.call(arguments));var b={};for(var c in this)this.hasOwnProperty(c)&&-1===a.indexOf(c)&&(b[c]=this[c]);return q(b)}function k(a){var b,c,d=[];if(a&&a.deep)for(b=0,c=this.length;c>b;b++)d.push(m(this[b]));else for(b=0,c=this.length;c>b;b++)d.push(this[b]);return d}function l(a){"function"!=typeof a&&(a=function(a){return a});var b,c={},d=this.length;for(b=0;d>b;b++){var e=a(this[b],b,this),f=e[0],g=e[1];c[f]=g}return q(c)}function m(a){return!a||!a.hasOwnProperty(s)||a instanceof Date?a:a.asMutable({deep:!0})}function n(a,b){for(var c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b}function o(a,b){function c(a,c,e){var h=r(c[e]),k=j&&j(a[e],h,b);j&&k&&k===a[e]||(f=f||void 0!==k||!a.hasOwnProperty(e)||h!==a[e]&&h===h,g[e]=k?k:i&&d(a[e])&&d(h)?a[e].merge(h,b):h)}if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#merge can only be invoked with objects or arrays, not "+JSON.stringify(a));var e,f=!1,g=n(this,{}),h=a instanceof Array,i=b&&b.deep,j=b&&b.merger;if(h)for(var k=0;k<a.length;k++){var l=a[k];for(e in l)l.hasOwnProperty(e)&&c(this,l,e)}else for(e in a)a.hasOwnProperty(e)&&c(this,a,e);return f?q(g):this}function p(a){var b,c={};if(a&&a.deep)for(b in this)this.hasOwnProperty(b)&&(c[b]=m(this[b]));else for(b in this)this.hasOwnProperty(b)&&(c[b]=this[b]);return c}function q(b){return a(b,"merge",o),a(b,"without",j),a(b,"asMutable",p),f(b,t)}function r(a){if(arguments.length>1)return h(Array.prototype.slice.call(arguments));if(c(a))return a;if(a instanceof Array)return h(a.slice());if(a instanceof Date)return f(new Date(a.getTime()));var b={};for(var d in a)a.hasOwnProperty(d)&&(b[d]=r(a[d]));return q(b)}var s="__immutable_invariants_hold",t=["setPrototypeOf"],u=["keys"],v=t.concat(["push","pop","sort","splice","shift","unshift","reverse"]),w=u.concat(["map","filter","slice","concat","reduce","reduceRight"]);e.prototype=Error.prototype,r.isImmutable=c,r.ImmutableError=e,Object.freeze(r),"object"==typeof module?module.exports=r:"object"==typeof exports?exports.Immutable=r:"object"==typeof window?window.Immutable=r:"object"==typeof global&&(global.Immutable=r)}(); | ||
!function(){"use strict";function a(a,b,c){Object.defineProperty(a,b,{enumerable:!1,configurable:!1,writable:!1,value:c})}function b(b){a(b,t,!0)}function c(a){return"object"==typeof a?null===a||a.hasOwnProperty(t):!0}function d(a){return!(null===a||"object"!=typeof a||a instanceof Array||a instanceof Date)}function e(a){var b=new Error(a);return b.__proto__=e,b}function f(a,c){b(a);return a}function g(b,c){var d=b[c];a(b,c,function(){return s(d.apply(b,arguments))})}function h(b){for(var c in x)if(x.hasOwnProperty(c)){var d=x[c];g(b,d)}a(b,"flatMap",i),a(b,"asObject",l),a(b,"asMutable",k);for(var e=0,h=b.length;h>e;e++)b[e]=s(b[e]);return f(b,w)}function i(a){if(0===arguments.length)return this;var b,c=[],d=this.length;for(b=0;d>b;b++){var e=a(this[b],b,this);e instanceof Array?c.push.apply(c,e):c.push(e)}return h(c)}function j(a){if(0===arguments.length)return this;a instanceof Array||(a=Array.prototype.slice.call(arguments));var b=this.instantiateEmptyObject();for(var c in this)this.hasOwnProperty(c)&&-1===a.indexOf(c)&&(b[c]=this[c]);return r(b,{instantiateEmptyObject:this.instantiateEmptyObject})}function k(a){var b,c,d=[];if(a&&a.deep)for(b=0,c=this.length;c>b;b++)d.push(m(this[b]));else for(b=0,c=this.length;c>b;b++)d.push(this[b]);return d}function l(a){"function"!=typeof a&&(a=function(a){return a});var b,c={},d=this.length;for(b=0;d>b;b++){var e=a(this[b],b,this),f=e[0],g=e[1];c[f]=g}return r(c)}function m(a){return!a||!a.hasOwnProperty(t)||a instanceof Date?a:a.asMutable({deep:!0})}function n(a,b){for(var c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b}function o(a,b){function c(a,c,e){var h=s(c[e]),k=j&&j(a[e],h,b);j&&k&&k===a[e]||(f=f||void 0!==k||!a.hasOwnProperty(e)||h!==a[e]&&h===h,g[e]=k?k:i&&d(a[e])&&d(h)?a[e].merge(h,b):h)}if(0===arguments.length)return this;if(null===a||"object"!=typeof a)throw new TypeError("Immutable#merge can only be invoked with objects or arrays, not "+JSON.stringify(a));var e,f=!1,g=n(this,this.instantiateEmptyObject()),h=a instanceof Array,i=b&&b.deep,j=b&&b.merger;if(h)for(var k=0;k<a.length;k++){var l=a[k];for(e in l)l.hasOwnProperty(e)&&c(this,l,e)}else for(e in a)a.hasOwnProperty(e)&&c(this,a,e);return f?r(g,{instantiateEmptyObject:this.instantiateEmptyObject}):this}function p(a){var b,c=this.instantiateEmptyObject();if(a&&a.deep)for(b in this)this.hasOwnProperty(b)&&(c[b]=m(this[b]));else for(b in this)this.hasOwnProperty(b)&&(c[b]=this[b]);return c}function q(){return{}}function r(b,c){var d=c&&c.instantiateEmptyObject?c.instantiateEmptyObject:q;return a(b,"merge",o),a(b,"without",j),a(b,"asMutable",p),a(b,"instantiateEmptyObject",d),f(b,u)}function s(a,b){if(c(a))return a;if(a instanceof Array)return h(a.slice());if(a instanceof Date)return f(new Date(a.getTime()));var d=b&&b.prototype,e=d&&d!==Object.prototype?function(){return Object.create(d)}:q,g=e();for(var i in a)a.hasOwnProperty(i)&&(g[i]=s(a[i]));return r(g,{instantiateEmptyObject:e})}var t="__immutable_invariants_hold",u=["setPrototypeOf"],v=["keys"],w=u.concat(["push","pop","sort","splice","shift","unshift","reverse"]),x=v.concat(["map","filter","slice","concat","reduce","reduceRight"]);e.prototype=Error.prototype,s.isImmutable=c,s.ImmutableError=e,Object.freeze(s),"object"==typeof module?module.exports=s:"object"==typeof exports?exports.Immutable=s:"object"==typeof window?window.Immutable=s:"object"==typeof global&&(global.Immutable=s)}(); |
@@ -160,3 +160,3 @@ (function(){ | ||
var result = {}; | ||
var result = this.instantiateEmptyObject(); | ||
@@ -169,3 +169,4 @@ for (var key in this) { | ||
return makeImmutableObject(result); | ||
return makeImmutableObject(result, | ||
{instantiateEmptyObject: this.instantiateEmptyObject}); | ||
} | ||
@@ -253,3 +254,3 @@ | ||
var anyChanges = false, | ||
result = quickCopy(this, {}), // A shallow clone of this object. | ||
result = quickCopy(this, this.instantiateEmptyObject()), // A shallow clone of this object. | ||
receivedArray = (other instanceof Array), | ||
@@ -306,3 +307,4 @@ deep = config && config.deep, | ||
if (anyChanges) { | ||
return makeImmutableObject(result); | ||
return makeImmutableObject(result, | ||
{instantiateEmptyObject: this.instantiateEmptyObject}); | ||
} else { | ||
@@ -314,3 +316,3 @@ return this; | ||
function asMutableObject(opts) { | ||
var result = {}, key; | ||
var result = this.instantiateEmptyObject(), key; | ||
@@ -334,7 +336,18 @@ if(opts && opts.deep) { | ||
// Creates plain object to be used for cloning | ||
function instantiatePlainObject() { | ||
return {}; | ||
} | ||
// Finalizes an object with immutable methods, freezes it, and returns it. | ||
function makeImmutableObject(obj) { | ||
function makeImmutableObject(obj, options) { | ||
var instantiateEmptyObject = | ||
(options && options.instantiateEmptyObject) | ||
? options.instantiateEmptyObject | ||
: instantiatePlainObject; | ||
addPropertyTo(obj, "merge", merge); | ||
addPropertyTo(obj, "without", without); | ||
addPropertyTo(obj, "asMutable", asMutableObject); | ||
addPropertyTo(obj, "instantiateEmptyObject", instantiateEmptyObject); | ||
@@ -344,7 +357,4 @@ return makeImmutable(obj, mutatingObjectMethods); | ||
function Immutable(obj) { | ||
// If the user passes multiple arguments, assume what they want is an array. | ||
if (arguments.length > 1) { | ||
return makeImmutableArray(Array.prototype.slice.call(arguments)); | ||
} else if (isImmutable(obj)) { | ||
function Immutable(obj, options) { | ||
if (isImmutable(obj)) { | ||
return obj; | ||
@@ -357,3 +367,8 @@ } else if (obj instanceof Array) { | ||
// Don't freeze the object we were given; make a clone and use that. | ||
var clone = {}; | ||
var prototype = options && options.prototype; | ||
var instantiateEmptyObject = | ||
(!prototype || prototype === Object.prototype) | ||
? instantiatePlainObject | ||
: (function() { return Object.create(prototype); }); | ||
var clone = instantiateEmptyObject(); | ||
@@ -366,3 +381,4 @@ for (var key in obj) { | ||
return makeImmutableObject(clone); | ||
return makeImmutableObject(clone, | ||
{instantiateEmptyObject: instantiateEmptyObject}); | ||
} | ||
@@ -369,0 +385,0 @@ } |
@@ -17,16 +17,3 @@ var JSC = require("jscheck"); | ||
describe("Immutable", function () { | ||
it("converts multiple arguments into an array, but leaves single arguments alone", function () { | ||
TestUtils.check(100, [JSC.array()], function (args) { | ||
var immutable = Immutable.apply(Immutable, args); | ||
if (args.length > 1) { | ||
assert.deepEqual(immutable, Immutable(args)); | ||
} else if (isNaN(immutable) && isNaN(args[0])) { | ||
assert.ok(true); | ||
} else { | ||
assert.strictEqual(immutable, args[0]); | ||
} | ||
}) | ||
}); | ||
it("makes an Immutable Array when passed a mutable array", function () { | ||
@@ -68,3 +55,13 @@ TestUtils.check(100, [JSC.array()], function (mutable) { | ||
}); | ||
it("returns an object with the given optional prototype", function() { | ||
function TestClass(o) { _.extend(this, o); }; | ||
var data = new TestClass({a: 1, b: 2}); | ||
var immutable = Immutable(data, {prototype: TestClass.prototype}); | ||
assert.deepEqual(immutable, data); | ||
TestUtils.assertHasPrototype(immutable, TestClass.prototype); | ||
}); | ||
// These are already immutable, and should pass through Immutable() untouched. | ||
@@ -81,2 +78,5 @@ _.each({ | ||
assert.strictEqual(Immutable(value), value); | ||
// should still pass through with a faulty prototype option | ||
assert.strictEqual(Immutable(value, {prototype: Object.prototype}), value); | ||
}); | ||
@@ -83,0 +83,0 @@ }); |
@@ -5,2 +5,3 @@ var testMerge = require("./ImmutableObject/test-merge.js"); | ||
var testAsMutable = require("./ImmutableObject/test-asMutable.js"); | ||
var testInstantiateEmptyObject = require("./ImmutableObject/test-instantiateEmptyObject.js"); | ||
var devBuild = require("../seamless-immutable.development.js"); | ||
@@ -23,4 +24,5 @@ var prodBuild = require("../seamless-immutable.production.min.js"); | ||
testAsMutable(config); | ||
testInstantiateEmptyObject(config); | ||
}); | ||
}); | ||
}); |
@@ -34,9 +34,21 @@ var JSC = require("jscheck"); | ||
it("does not throw an error when asMutable deep = true is called on an Immutable with a nested date", function() { | ||
check(100, [ TestUtils.TraversableObjectSpecifier ], function(obj) { | ||
var test = Immutable({ testDate: new Date()}); | ||
test.asMutable({deep: true}); | ||
}); | ||
it("does not throw an error when asMutable deep = true is called on an Immutable with a nested date", function() { | ||
check(100, [ TestUtils.TraversableObjectSpecifier ], function(obj) { | ||
var test = Immutable({ testDate: new Date()}); | ||
test.asMutable({deep: true}); | ||
}); | ||
}); | ||
it("preserves prototypes after call to asMutable", function() { | ||
function TestClass(o) { _.extend(this, o); }; | ||
var data = new TestClass({a: 1, b: 2}); | ||
var immutable = Immutable(data, {prototype: TestClass.prototype}); | ||
var result = immutable.asMutable(); | ||
assert.deepEqual(result, data); | ||
TestUtils.assertHasPrototype(result, TestClass.prototype); | ||
}); | ||
}); | ||
}; |
@@ -145,3 +145,10 @@ var JSC = require("jscheck"); | ||
}); | ||
it("supports handling dates without using prototype option", function() { | ||
var date = new Date(); | ||
var immutableDate = Immutable(date, {prototype: Object.prototype}); | ||
assert.isTrue(immutableDate instanceof Date); | ||
}); | ||
it("makes nested content immutable as well", function() { | ||
@@ -148,0 +155,0 @@ checkImmutableMutable(function(immutable, mutable, innerArray, obj) { |
@@ -245,2 +245,14 @@ var JSC = require("jscheck"); | ||
it("preserves prototypes across merges", function() { | ||
function TestClass(o) { _.extend(this, o); }; | ||
var data = new TestClass({a: 1, b: 2}); | ||
var mergeData = {b: 3, c: 4}; | ||
var immutable = Immutable(data, {prototype: TestClass.prototype}); | ||
var result = immutable.merge(mergeData); | ||
assert.deepEqual(result, _.extend({}, data, mergeData)); | ||
TestUtils.assertHasPrototype(result, TestClass.prototype); | ||
}); | ||
describe("when passed a single object", function() { | ||
@@ -247,0 +259,0 @@ generateMergeTestsFor([TestUtils.ComplexObjectSpecifier()]); |
@@ -89,3 +89,14 @@ var JSC = require("jscheck"); | ||
}); | ||
it("preserves prototypes after call to without", function() { | ||
function TestClass(o) { _.extend(this, o); }; | ||
var data = new TestClass({a: 1, b: 2}); | ||
var immutable = Immutable(data, {prototype: TestClass.prototype}); | ||
var result = immutable.without('b'); | ||
assert.deepEqual(result, _.omit(data, 'b')); | ||
TestUtils.assertHasPrototype(result, TestClass.prototype); | ||
}); | ||
describe("when passed a single key", function() { | ||
@@ -92,0 +103,0 @@ generateWithoutTestsFor([JSC.string()]); |
@@ -26,2 +26,6 @@ var JSC = require("jscheck"); | ||
function assertHasPrototype(obj, expectedPrototype) { | ||
assert.strictEqual(Object.getPrototypeOf(obj), expectedPrototype); | ||
} | ||
function withoutItengerKeys(obj) { | ||
@@ -116,2 +120,3 @@ return _.object(_.map(obj, function(value, key) { | ||
assertIsDeeplyImmutable: wrapAssertIsDeeplyImmutable(Immutable), | ||
assertHasPrototype: assertHasPrototype, | ||
ImmutableArraySpecifier: wrapImmutableArraySpecifier(Immutable), | ||
@@ -118,0 +123,0 @@ ComplexObjectSpecifier: ComplexObjectSpecifier, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
105441
25
1799
279