Comparing version 0.4.1 to 0.5.0
@@ -67,3 +67,8 @@ /** | ||
function freezeIfNeeded(coll) { | ||
if (weCareAbout(coll) && !Object.isFrozen(coll)) { | ||
if ( | ||
weCareAbout(coll) && | ||
( | ||
!Object.isFrozen(coll) && | ||
process.env.NODE_ENV !== "production" | ||
)) { | ||
return baseFreeze(coll, []); | ||
@@ -74,2 +79,9 @@ } | ||
function _freeze(coll) { | ||
if (process.env.NODE_ENV === "production") { | ||
return coll; | ||
} | ||
return Object.freeze(coll); | ||
} | ||
function baseFreeze(coll, prevNodes) { | ||
@@ -99,2 +111,5 @@ if (prevNodes.some(function (node) { return node === coll; })) { | ||
exports.freeze = function freeze(coll) { | ||
if (process.env.NODE_ENV === "production") { | ||
return coll; | ||
} | ||
return baseFreeze(coll, []); | ||
@@ -104,2 +119,18 @@ }; | ||
/** | ||
* recursively un-freeze an object, by cloning frozen collections | ||
* @param {[type]} coll [description] | ||
* @return {[type]} [description] | ||
*/ | ||
exports.thaw = function thaw(coll) { | ||
if (weCareAbout(coll) && Object.isFrozen(coll)) { | ||
var newColl = clone(coll); | ||
Object.keys(newColl).forEach(function (key) { | ||
newColl[key] = thaw(newColl[key]); | ||
}); | ||
return newColl; | ||
} | ||
return coll; | ||
}; | ||
/** | ||
* set a value on an object or array | ||
@@ -116,3 +147,3 @@ * @param {Object|Array} coll | ||
return Object.freeze(newObj); | ||
return _freeze(newObj); | ||
@@ -132,3 +163,3 @@ }; | ||
return Object.freeze(newObj); | ||
return _freeze(newObj); | ||
}; | ||
@@ -151,3 +182,3 @@ | ||
// and the result of assocIn with the rest of the keys | ||
return i.assoc(coll, key0, assocIn(coll[key0], path.slice(1), value)); | ||
return i.assoc(coll, key0, assocIn(coll[key0] || {}, path.slice(1), value)); | ||
} | ||
@@ -163,4 +194,5 @@ }; | ||
function baseGet(coll, path) { | ||
return (path || []).reduce(function (val, key) { | ||
return val[key]; | ||
return (path || []).reduce(function (curr, key) { | ||
if (!curr) { return; } | ||
return curr[key]; | ||
}, coll); | ||
@@ -193,3 +225,3 @@ } | ||
return Object.freeze(newArr); | ||
return _freeze(newArr); | ||
}; | ||
@@ -207,3 +239,3 @@ | ||
return Object.freeze(newArr); | ||
return _freeze(newArr); | ||
}; | ||
@@ -215,3 +247,3 @@ | ||
return Object.freeze(newArr); | ||
return _freeze(newArr); | ||
}; | ||
@@ -223,3 +255,3 @@ | ||
return Object.freeze(newArr); | ||
return _freeze(newArr); | ||
}; | ||
@@ -234,3 +266,3 @@ | ||
return Object.freeze(newObj); | ||
return _freeze(newObj); | ||
}; | ||
@@ -256,4 +288,6 @@ | ||
// if they are both frozen and reference equal, assume they are deep equal | ||
if (Object.isFrozen(sourceVal) && | ||
Object.isFrozen(targetVal) && | ||
if (( | ||
(Object.isFrozen(sourceVal) && Object.isFrozen(targetVal)) || | ||
process.env.NODE_ENV === "production" | ||
) && | ||
sourceVal === targetVal) { | ||
@@ -260,0 +294,0 @@ return obj; |
@@ -42,2 +42,25 @@ /* jshint elision:true */ | ||
describe("thaw", function () { | ||
function Foo () {} | ||
it("should thaw objects", function () { | ||
var o = i.freeze({ | ||
a: {}, | ||
b: 1, | ||
c: new Foo(), | ||
d: [{e: 1}] | ||
}); | ||
var thawed = i.thaw(o); | ||
expect(thawed).to.eql(o); | ||
expect(Object.isFrozen(thawed)).to.be(false); | ||
expect(Object.isFrozen(thawed.a)).to.be(false); | ||
expect(o.a).to.not.equal(thawed.a); | ||
expect(o.d).to.not.equal(thawed.d); | ||
expect(o.d[0]).to.not.equal(thawed.d[0]); | ||
expect(o.c).to.equal(thawed.c); | ||
}); | ||
}); | ||
describe("assoc", function () { | ||
@@ -147,2 +170,7 @@ it("should work with objects", function () { | ||
}); | ||
it("should create collections if they don't exist", function () { | ||
var result = i.assocIn({}, ["a", "b", "c"], 1); | ||
expect(result).to.eql({a: {b: {c: 1}}}); | ||
}); | ||
}); | ||
@@ -153,3 +181,3 @@ | ||
var o = i.freeze({ | ||
a: 1, | ||
a: 0, | ||
b: {a: 2}, | ||
@@ -162,2 +190,3 @@ c: [ | ||
expect(i.getIn(o, ["c", 0, "b"])).to.equal(4); | ||
expect(i.getIn(o, ["a"])).to.equal(0); | ||
}); | ||
@@ -169,2 +198,24 @@ | ||
}); | ||
it("should return undefined for a non-existant path", function () { | ||
var o = i.freeze({ | ||
a: 1, | ||
b: {a: 2}, | ||
c: [ | ||
{a: 3, b: 4}, | ||
{a: 4} | ||
] | ||
}); | ||
expect(i.getIn(o, ["q"])).to.equal(undefined); | ||
expect(i.getIn(o, ["a", "s", "d"])).to.equal(undefined); | ||
}); | ||
it("should return undefined for a non-existant path (null)", function () { | ||
var o = i.freeze({ | ||
a: null | ||
}); | ||
expect(i.getIn(o, ["a", "b"])).to.equal(undefined); | ||
}); | ||
}); | ||
@@ -182,2 +233,10 @@ | ||
}); | ||
it("should create collections if they don't exist", function () { | ||
var result = i.updateIn({}, ["a", 1, "c"], function (val) { | ||
expect(val).to.be(undefined); | ||
return 1; | ||
}); | ||
expect(result).to.eql({a: {"1": {c: 1}}}); | ||
}); | ||
}); | ||
@@ -347,2 +406,33 @@ | ||
describe("production mode", function () { | ||
var oldEnv; | ||
before(function () { | ||
oldEnv = process.env.NODE_ENV; | ||
process.env.NODE_ENV = "production"; | ||
}); | ||
after(function () { | ||
process.env.NODE_ENV = oldEnv; | ||
}); | ||
it("should not freeze objects", function () { | ||
var result = i.freeze({}); | ||
expect(Object.isFrozen(result)).to.be(false); | ||
}); | ||
it("should not freeze objects that are assoc'd", function () { | ||
var result = i.assoc({}, "a", {}); | ||
expect(Object.isFrozen(result)).to.be(false); | ||
expect(Object.isFrozen(result.a)).to.be(false); | ||
}); | ||
it("merge should keep references the same if nothing changes", function () { | ||
var o1 = i.freeze({a: 1, b: {c: 1, d: 1, e: [1]}}); | ||
var o2 = i.freeze({a: 1, b: {c: 1, d: 1, e: o1.b.e}}); | ||
var result = i.merge(o1, o2); | ||
expect(result).to.equal(o1); | ||
expect(result.b).to.equal(o1.b); | ||
}); | ||
}); | ||
describe("internals", function () { | ||
@@ -349,0 +439,0 @@ describe("_weCareAbout", function () { |
{ | ||
"name": "icepick", | ||
"version": "0.4.1", | ||
"version": "0.5.0", | ||
"description": "Utilities for working with frozen objects", | ||
@@ -5,0 +5,0 @@ "main": "icepick.js", |
@@ -19,3 +19,3 @@ # icepick [![Build Status via Travis CI](https://travis-ci.org/aearly/icepick.svg?branch=master)](https://travis-ci.org/aearly/icepick) [![NPM version](http://img.shields.io/npm/v/icepick.svg)](https://www.npmjs.org/package/icepick) [![Coverage Status](https://coveralls.io/repos/aearly/icepick/badge.svg?branch=)](https://coveralls.io/r/aearly/icepick?branch=) | ||
`icepick` is provided as a CommonJS module with no dependencies. It is designed for use in Node, or with module loaders like Browserify or Webpack. To use as a global or with require.js, you will have to shim it or wrap it with `browserify --standalone`. | ||
`icepick` is provided as a CommonJS module with no dependencies. It is designed for use in Node, or with module loaders like Browserify or Webpack. To use as a global or with require.js, you will have to shim it or wrap it with `browserify icepick.js --standalone icepick`. | ||
@@ -34,2 +34,4 @@ ```bash | ||
If you set `process.env.NODE_ENV` to `"production"` in your build, using `envify` or its equivalent, freezing objects will be skipped. This can improve performance for your production build. | ||
### freeze(collection) | ||
@@ -58,3 +60,17 @@ | ||
### thaw(collection) | ||
Recursively un-freeze a collection by creating a partial clone. Object that are not frozen or that have custom prototypes are left as-is. This is useful when interfacing with other libraries. | ||
```javascript | ||
var coll = i.freeze({a: "foo", b: [1, 2, 3], c: {d: "bar"}, e: new Foo() }); | ||
var thawed = i.thaw(coll); | ||
assert(!Object.isFrozen(thawed)); | ||
assert(!Object.isFrozen(thawed.c)); | ||
assert(thawed.c !== coll.c); | ||
assert(thawed.e === coll.e); | ||
``` | ||
### assoc(collection, key, value) | ||
@@ -93,3 +109,3 @@ | ||
Set a value inside a hierarchical collection. `path` is an array of keys inside the object. Returns a partial copy of the original collection. If not all of the collections exist, an error will be thrown. | ||
Set a value inside a hierarchical collection. `path` is an array of keys inside the object. Returns a partial copy of the original collection. Intermediate objects will be created if they don't exist. | ||
@@ -109,2 +125,6 @@ ```javascript | ||
assert(newColl.b === coll.b); | ||
var coll = {}; | ||
var newColl = i.assocIn(coll, ["a", "b", "c"], 1); | ||
assert(newColl.a.b.c === 1); | ||
``` | ||
@@ -114,3 +134,3 @@ | ||
Get a value inside a hierarchical collection using a path of keys. A convenience method -- in most cases plain JS syntax will be simpler. | ||
Get a value inside a hierarchical collection using a path of keys. Returns `undefined` if the value does not exist. A convenience method -- in most cases plain JS syntax will be simpler. | ||
@@ -117,0 +137,0 @@ ```javascript |
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
35177
641
254
3