copykitten.js
/\/\
( =( ^-^)=
\( ⊃C⊃
Copy Kitten
Tiny immutable JSON data structures (< 1kb gzip)
This is a minimal library, designed specifically for JSON-compatible values: Strings, Numbers, Booleans, null, Objects, and Arrays. For a wider selection of immutable data structures with less naive implementations, see Immutable.js.
Copy Kitten manipulates JSON data and returns an updated copy; the original data is preserved. A reference to a Copy Kitten result will always return the same value. Use this to write easy-to-understand code and optimise top-down rendering (e.g. Redux).
Data conversion
// JSON value -> immutable
var immutable = copykitten.toImmutable({example: 'value'})
// Immutable value -> JSON string
JSON.stringify(immutable)
// Immutable value -> JSON object
immutable.toJSON();
API
- toImmutable
- isImmutable
- FrozenObject
-
FrozenArray
- push(element1, ..., elementN)
- pop()
- unshift(element1, ..., elementN)
- shift()
- sort()
- splice(start, deleteCount, item1, item2, ...)
- slice(begin, end)
- every(callback)
- filter(callback)
- forEach(callback)
- indexOf(searchElement)
- join()
- lastIndexOf(searchElement)
- map(callback)
- reduce(callback)
- reduceRight(callback)
- some(callback)
toImmutable(value)
Converts value
to an immutable value. Basic types (string, number,
boolean, null) are untouched, objects and arrays are converted to
FrozenObject and FrozenArray types respectively.
var data = copykitten.toImmutable({
name: 'Kitten'
});
isImmutable(value)
Returns true for string, number, boolean, null, undefined, FrozenObject and FrozenArray. Otherwise returns false.
copykitten.isImmutable("string") // true
copykitten.isImmutable(1234) // true
copykitten.isImmutable(true) // true
copykitten.isImmutable(null) // true
copykitten.isImmutable({name: 'Kitten'}) // false
var data = copykitten.toImmutable({name: 'Kitten'});
copykitten.isImmutable(data) // true
FrozenObject
Represents a JSON-style object (e.g. {hello: 'world'}) which has been frozen and made immutable.
This constructor should not be called directly.
set(key, value)
Returns a new copy of the FrozenObject with the property key
set to
value
. The value is first converted to an immutable (including deep
references) before being set on the newly returned FrozenObject.
var a = copykitten.toImmutable({name: 'Kitten'});
var b = data.set('status', 'sleepy');
// a is now {name: 'Kitten'}
// b is now {name: 'Kitten', status: 'sleepy'}
remove(key)
Returns a new copy of the FrozenObject with the property key
removed.
var a = copykitten.toImmutable({name: 'Kitten', toy: 'ball'});
var b = a.remove('toy');
// a is now {name: 'Kitten', toy: 'ball'}
// b is now {name: 'Kitten'}
merge(props)
Returns a new copy of the FrozenObject including the properties and
values from the props
object. Any values defined on props
will be
converted to immutables first (including deep references).
var a = copykitten.toImmutable({name: 'Kitten'});
var b = a.merge({status: 'hungry'});
// a is now {name: 'Kitten'}
// b is now {name: 'Kitten', status: 'hungry'}
deepMerge(props)
Like merge(props) but will recursively merge nested objects.
var a = copykitten.toImmutable({animal: {name: 'Kitten'}});
var b = a.deepMerge({animal: {status: 'hungry'}});
// a is now {animal: {name: 'Kitten'}}
// b is now {animal: {name: 'Kitten', status: 'hungry'}}
update(f)
Calls the function f
with a mutable copy of the current
FrozenObject, then returns an immutable version including any
modifications made by f
.
var a = copykitten.toImmutable({name: 'Kitten'});
var b = a.update(function (obj) {
delete obj.name;
obj.type = 'animal';
});
// a is now {name: 'Kitten'}
// b is now {type: 'animal'}
Only the current object is mutable, any nested properties will remain
immutable while f
is being called.
thaw()
Returns a mutable JSON data type for the current object. Any nested properties will remain immutable.
var obj = copykitten.toImmutable({name: 'Kitten'});
obj.thaw() // => {name: 'Kitten'}
toJSON()
Converts the current object and all nested properties to their mutable JSON data type representations.
var obj = copykitten.toImmutable({name: 'Kitten'});
obj.toJSON() // => {name: 'Kitten'}
FrozenArray
FrozenArray extends FrozenObject. In addition to the FrozenObject methods, it provides immutable implementations of most Array methods. Some descriptions borrowed from the [MDN Array documentation][mdn-arra].
This constructor should not be called directly.
push(element1, ..., elementN)
Returns a new FrozenArray with value
appended.
var a = copykitten.toImmutable(['yarn', 'ball']);
var b = a.push('mouse');
// a is now ['yarn', 'ball']
// b is now ['yarn', 'ball', 'mouse']
pop()
Returns a new FrozenArray with the last item removed.
var a = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
var b = a.pop();
// a is now ['yarn', 'ball', 'mouse']
// b is now ['yarn', 'ball']
Note: does not return the popped element, just the updated array.
unshift([element1[, ...[, elementN]]])
Returns a new FrozenArray with value
prepended.
var a = copykitten.toImmutable(['yarn', 'ball']);
var b = a.unshift('mouse');
// a is now ['yarn', 'ball']
// b is now ['mouse', 'yarn', 'ball']
shift()
Returns a new FrozenArray with the first item removed.
var a = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
var b = a.shift();
// a is now ['yarn', 'ball', 'mouse']
// b is now ['ball', 'mouse']
Note: does not return the shifted element, just the updated array.
sort([compareFunction])
Returns a new, sorted FrozenArray.
var a = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
var b = a.sort();
// a is now ['yarn', 'ball', 'mouse']
// b is now ['ball', 'mouse', 'yarn']
splice(start, deleteCount[, item1[, item2[, ...]]])
Works as the Array.splice method. Returns a new FrozenArray updated by adding and/or removing elements from the original.
var a = copykitten.toImmutable(['yarn', 'ball']);
var b = a.splice(1, 1, 'mouse');
// a is now ['yarn', 'ball']
// b is now ['yarn', 'mouse']
slice([begin[, end]])
Returns a new FrozenArray including a portion of the original.
var a = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
var b = a.slice(1)
// a is now ['yarn', 'ball', 'mouse']
// b is now ['ball', 'mouse']
every(callback[, thisArg])
Tests whether all elements in the FrozenArray pass the test implemented by the provided function. Returns boolean.
var toys = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
var small = toys.every(function (toy) {
return toy.length < 10;
});
// small == true
filter(callback[, thisArg])
Creates a new FrozenArray with all elements that pass the test implemented by the provided function.
var toys = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
var tiny = toys.filter(function (toy) {
return toy.length < 4;
});
// tiny is now ['ball']
forEach(callback[, thisArg])
Executes a provided function once per FrozenArray element.
var toys = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
toys.forEach(function (toy) {
console.log(toy);
});
indexOf(searchElement[, fromIndex = 0])
Returns the first index at which a given element can be found in the FrozenArray, or -1 if it is not present.
var toys = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
toys.indexOf('ball'); // => 1
join([separator = ','])
Joins all elements of a FrozenArray into a string.
var toys = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
toys.join(' and '); // => 'yarn and ball and mouse'
lastIndexOf(searchElement[, fromIndex = arr.length - 1])
Returns the last index at which a given element can be found in the FrozenArray, or -1 if it is not present. The FrozenArray is searched backwards, starting at fromIndex.
var toys = copykitten.toImmutable(['yarn', 'ball', 'mouse', 'ball']);
toys.lastIndexOf('ball'); // => 3
map(callback[, thisArg])
Creates a new FrozenArray with the results of calling a provided function on every element in this FrozenArray.
var toys = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
var caps = toys.map(function (toy) {
return toy.toUpperCase();
});
// caps is now ['YARN', 'BALL', 'MOUSE']
reduce(callback[, initialValue])
Applies a function against an accumulator and each value of the FrozenArray (from left-to-right) to reduce it to a single value.
var toys = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
var size = toys.reduce(function (count, toy) {
return count + toy.length;
}, 0);
// size is now 13
reduceRight(callback[, initialValue])
Applies a function against an accumulator and each value of the FrozenArray (from right-to-left) has to reduce it to a single value.
var toys = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
var smallest = toys.reduceRight(function (min, toy) {
if (toy.length < min.length) {
return toy;
}
return min;
});
// smallest is now 'ball'
some(callback[, thisArg])
Tests whether some element in the FrozenArray passes the test implemented by the provided function.
var toys = copykitten.toImmutable(['yarn', 'ball', 'mouse']);
var got_ball = toys.some(function (toy) {
return toy === 'ball';
});
// got_ball == true