npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

constant.js

v1.1.0

Published

Immutable/Constant JS-Object

Downloads

15

Readme

Constant.JS Build Status

A minimalistic javascript constant object library. It utilises Object.freeze to prevent mutations, however it does deep-freeze objects making them truly constant.

The constant object is identical (obj === constant(obj)), so it does in fact freeze the original objects. Accessing properties can therefore be done in the standard JS way (obj.prop or obj[propname]).

There are also convenience access methods and mutation methods supported making handling of constant object hierarchies easy.

In general this library shares common tree branches in hierarchies. This goes so far as to return the same object from alteration methods that do not actually modify the object where this is easily detected.

Installation

npm install --save constant.js
npm test

This library has 100% test coverage. Pull requests are always welcome, however they will only be accepted if the test-coverage remains at 100%.

Static Functions

constant(object)

Converts an object to an constant version.

constant.parse(string)

Parses a JSON string into an constant object.

constant.is(object)

Tests if an object has been made constant.

constant.isArray(object)

Tests if an object is an Array and has been made constant.

constant.isObject(object)

Tests if an object is a plain Object and has been made constant.

constant.isDate(object)

Tests if an object is a Date and has been made constant.

constant.isRegExp(object)

Tests if an object is a RegExp and has been made constant.

Common Methods

These methods a available on all constant objects whether they be plain Objects, Arrays or Dates. All prototype methods remain available, but using modifying methods (if they have not been implemented here) will throw in strict mode or not have an effect in non-strict mode.

constantObject.mutate(path, method[, arg, ...])

This method performs a deep mutation on an object by calling one of its child's methods.

Example:

var obj = constant({ a: { b: [ new Date(0) ] } });
var res = obj.mutate([ 'a', 'b', '0' ], 'setFullYear', 1900);
JSON.stringify(res); // { "a": { "b": [ "1900-01-01T00:00:00.000Z"] } }

constantObject.get()

This method gets a value deep inside an object hierarchy.

Example:

var obj = constant({ a: { b: { c: 'value' } } });
obj.get('a', 'b', 'c'); // 'value'

constantObject.set()

This method sets a value deep inside an object hierarchy and returns a new constant object containing the change. The original constant remains unchanged. This method ensures that all values that remain unchanged will be reused. If the "change" isn't actually a change the return value will be the same object.

Example:

var obj = constant({ a: { b: { c: 'value' } }, d: { other: 'branch' } });
var chg = obj.set('a', 'b', 'c', 'new-value');
chg.d === obj.d; // true
chg.a.b.c; // 'new-value'
obj.a.b.c; // 'value'
chg = obj.set('a', 'b', 'c', 'value');
chg === obj; // true

constantObject.mutable()

Creates a shallow mutable version of the object. It's children in the hierarchy remain constant.

Example:

var obj = constant({ a: { b: { c: 'value' } }, d: { other: 'branch' } });
var mut = obj.mutable();
constant.isObject(mut); // false
constant.isObject(mut.a); // true
constant.isObject(mut.d); // true
mut.f = 'hallo';
mut.f; // 'hallo';

constantObject.toJS()

Creates a deep mutable version of the object. This means that the entire hierarchy will be mutable. It will retain cyclical integrity provided there is the global Map builtin.

If that is not the case, then a call on a cyclical constant object will loop indefinitely!

Only use cyclical structures if you have a modern environment!

Example:

var obj = constant({ a: { b: { c: 'value' } }, d: { other: 'branch' } });
var mut = obj.mutable();
constant.isObject(mut); // false
constant.isObject(mut.a); // false
constant.isObject(mut.d); // false
mut.f = 'hallo';
mut.f; // 'hallo';

Object Methods

constantObject.assign(obj[, obj[, ...]])

Similar to Object.assign in that it merges object into a constant object. It then returns a new constant object where the properties of the argument objects have been merged in.

var obj = constant({ a: 'test', b: { c: true } });
var mut = obj.assign({ a: 'hallo', d: { e: 5 } });
constant.isObject(mut); // true
constant.isObject(mut.b); // true
constant.isObject(mut.d); // true
obj.b === mut.b; // true
JSON.stringify(mut); // {"a":"hallo","b":{"c":true},"d":{"e":5}}

constantObject.transform(transformFn, thisPointer)

Works just like Array.prototype.map except on an object and that it returns a new constant object and allows removal of an element by returning undefined.

Example:

var obj = constant({ a: 1, b: 2, c: 3, d: 4, e: 5 });
mut = obj.transform(function(val, key) {
  return key === 'b' ? undefined : (val * 2);
});
constant.isObject(mut); // true
JSON.stringify(mut); // {"a": 2,"c":6,"d":8,"e":10}

mut = obj.transform(function(val) {
    return val;
});
obj === mut; //true

Array Methods

All methods available trough Array.prototype are available on constant Array objects as well except that modifying methods have been replaced with ones returning a new constant Array object instead.

constantArray.splice(idx, delcnt, insitem)

Just like the regular Array.prototype.splice method except that rather than returning the deleted elements, It returns a new constant Array with the changes applied. Also inserted elements will become constant.

Example:

var arr = constant([1, 2, 3, 4, 5]);
var mut = arr.splice(1,3, 'element');
constant.isArray(mut); // true
JSON.stringify(mut); // '[ 1, "element", 5 ]'

constantArray.concat(array)

Just like the regular Array.prototype.concat method except that the resulting array is constant.

Example:

var arr = constant([1, 2, 3 ]);
var mut = arr.concat([ 4, 5, 6 ]);
constant.isArray(mut); // true
JSON.stringify(mut); // '[ 1, 2, 3, 4, 5, 6 ]'

constantArray.reverse()

Just like the regular Array.prototype.reverse method except that the resulting array is constant.

Example:

var arr = constant([1, 2, 3, 4, 5, 6 ]);
var mut = arr.reverse();
constant.isArray(mut); // true
JSON.stringify(mut); // '[ 6, 5, 4, 3, 2, 1 ]'

constantArray.sort(sortFunction)

Just like the regular Array.prototype.sort method except that the resulting array is constant.

Example:

var arr = constant([ 6, 5, 4, 3, 2, 1 ]);
var mut = arr.reverse();
constant.isArray(mut); // true
JSON.stringify(mut); // '[1, 2, 3, 4, 5, 6 ]'

constantArray.insert(idx, element)

Inserts a new element at a specified index. If element isn't constant it will be on insertion.

Example:

var arr = constant([ 1, 2, 4, 5 ]);
var mut = arr.insert(2, 3);
constant.isArray(mut); // true
JSON.stringify(mut); // '[1, 2, 3, 4, 5 ]'

constantArray.delete()

Removes an element from an array and returns the constant changed array.

Example:

var arr = constant([ 1, 2, 3, 4, 5 ]);
var mut = arr.delete(2);
constant.isArray(mut); // true
JSON.stringify(mut); // '[1, 2, 4, 5 ]'

constantArray.shift()

Removes the first element of an array and returns the changed constant array.

Example:

var arr = constant([ 1, 2, 3, 4, 5 ]);
var mut = arr.shift();
constant.isArray(mut); // true
JSON.stringify(mut); // '[ 2, 3, 4, 5  ]'

constantArray.unshift(element)

Adds an element at the beginning of an array. Returns a new constant array with that element.

Example:

var arr = constant([ 1, 2, 3 ]);
var mut = arr.unshift(0);
constant.isArray(mut); // true
JSON.stringify(mut); // '[ 0, 1, 2, 3 ]'

constantArray.pop()

Removes the last element of an array and returns the changed constant array.

Example:

var arr = constant([ 1, 2, 3, 4, 5 ]);
var mut = arr.pop();
constant.isArray(mut); // true
JSON.stringify(mut); // '[ 1, 2, 3, 4 ]'

constantArray.push(element)

Adds an element at the end of an array. Returns a new constant array with that element.

Example:

var arr = constant([ 1, 2, 3 ]);
var mut = arr.push(4);
constant.isArray(mut); // true
JSON.stringify(mut); // '[ 1, 2, 3, 4 ]'

constantArray.transform(transformFn, thisPointer)

Works just like Array.prototype.map except that it returns a new constant array and allows removal of an element by returning undefined.

Example:

var arr = constant([ 0, 1, 2, 3, 4 ]);
var mut = arr.transform(function(val) {
  return val ? (val * 2) : undefined;
});
constant.isArray(mut); // true
JSON.stringify(mut); // '[ 2, 4, 6, 8 ]'

constantArray.first and constantArray.last

.first ist the first element in an array and .last is the last element in an array.

Example:

var arr = constant([ 1, 2, 3]);
arr.first; // 1
arr.last; // 3

Date Methods

All methods available trough Date.prototype are available on constant Date objects as well except that modifying methods have been replaced with ones returning a new constant Date object instead.

constantDate.setDate()

Works just like Date.prototype.setDate except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setFullYear()

Works just like Date.prototype.setFullYear except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setHours()

Works just like Date.prototype.setHours except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setMilliseconds()

Works just like Date.prototype.setMilliseconds except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setMinutes()

Works just like Date.prototype.setMinutes except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setMonth()

Works just like Date.prototype.setMonth except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setSeconds()

Works just like Date.prototype.setSeconds except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setTime()

Works just like Date.prototype.setTime except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setUTCDate()

Works just like Date.prototype.setUTCDate except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setUTCFullYear()

Works just like Date.prototype.setUTCFullYear except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setUTCHours()

Works just like Date.prototype.setUTCHours except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setUTCMilliseconds()

Works just like Date.prototype.setUTCMilliseconds except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setUTCMinutes()

Works just like Date.prototype.setUTCMinutes except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setUTCMonth()

Works just like Date.prototype.setUTCMonth except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setUTCSeconds()

Works just like Date.prototype.setUTCSeconds except that rather than modifying the date, it returns a new constant date with the change applied.

constantDate.setYear()

Works just like Date.prototype.setYear except that rather than modifying the date, it returns a new constant date with the change applied.

Map Methods

constantMap.set(key, val)

Works just like Map.prototype.set except it returns a contant Map instance that is the altered map.

constantMap.delete(key)

Works just like Map.prototype.delete except it returns a constant Map instance that is the altered map.

constantMap.clear()

Works just like Map.prototype.clear except it returns a constant Map instance that is empty.

Set Methods

constantSet.add(val)

Works just like Set.prototype.add except it returns a constant Map instance that is empty.

constantSet.delete(val)

Works just like Set.prototype.delete except it returns a constant Map instance that is empty.

constantSet.get(idx)

Gets the value of an element of a Set by its index. This utilizes the @@iterator so for large sets this will be expensive depending on the value of idx.

constantSet.clear()

Works just like Set.prototype.clear except it returns a constant Map instance that is empty.

Custom Object Types

Some object types require more information to properly handle. This can be done by placing a property on the prototype.

function MyClass() {}
MyClass.prototype[constant.COPY] = function() {
    var copy = new MyClass();
    copy.setValue(this.getValue());
    return copy;
};
MyClass.prototype[constant.COPY].proto = {};
MyClass.prototype[constant.COPY].proto.setValue = function(val) {
    var mut = this.mutable();
    mut.setValue(val);
    return constant(mut);
};
MyClass.isConstant = function(obj) {
    return constant.is(obj) && (obj[constant.COPY] === MyClass.prototype[constant.COPY]);
};

In this fashion it is possible to support any arbitrary object as a constant object and add custom methods for getting mutated versions of them.