Security News
Cloudflare Adds Security.txt Setup Wizard
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
immutable-ops
Advanced tools
A collection of functions to perform immutable operations on plain JavaScript objects
A collection of functions to perform immutable operations on plain JavaScript objects and arrays.
Like updeep but with batched mutations and no freezing.
Like icepick, but with batched mutations and a curried API that puts the target object as the last argument. No freezing.
npm install immutable-ops
import compose from 'ramda/src/compose';
import getOps from 'immutable-ops';
// These are all the available functions.
const {
// Functions operating on objects.
merge,
mergeDeep,
omit,
setIn,
// Functions operating on arrays.
insert,
splice,
push,
filter,
// Functions operating on both
set,
// Batch mutations
// Run a function batched
batched,
// Wrap a function to be executed as a batch
batch,
// Open a batch
open,
// Close a batch
close,
// Placeholder for currying.
__,
} = getOps({
// These are the default options.
curried: true
});
const arr = [1, 2, 3];
const pushFour = ops.push(4);
const pushFive = ops.push(5);
// All functions are curried. These functions
// still need the final argument, the array to
// operate on.
expect(pushFive).to.be.a('function');
const pushFourAndFive = compose(pushFive, pushFour);
const result = pushFourAndFive(arr);
// Two new arrays were created during `pushFourAndFive` eecution.
expect(result).to.deep.equal([1, 2, 3, 4, 5]);
const batchedPushFourAndFive = ops.batch(pushFourAndFive);
const sameResult = batchedPushFourAndFive(arr);
// Only one new array is created during `batchedPushFourAndFive` execution.
// `immutable-ops` keeps track of objects mutated during the wrapped
// function, and applies the same operations with mutations to those objects.
expect(result).to.deep.equal([1, 2, 3, 4, 5]);
You can run operations in a mutation batch by calling ops.batched(func)
with a function, and you can create a batch-wrapped function with const batchedFunc = ops.batch(funcToWrap)
.
When immutable-ops
creates a new object or array during batched mutations to preserve immutability, it tags it as a mutable object (by adding an unenumerable @@_____canMutate
property) and pushes its reference to an array of mutatedObjects
. All consecutive functions applied will execute a mutating operations for objects that have the tag. This applies for tagged objects found in nested structures too.
When the function finishes executing, immutable-ops
loops through the mutatedObjects
array, removing the tag properties from each object, and clearing the mutatedObjects
array.
The overhead of keeping track of mutated objects should be a sufficient tradeoff to creating lots of new objects to applyi multiple consecutive operations, unless you're working on a really big set of data.
All operations are curried by default. If you don't want them to be curried, pass { curried: false }
to getImmutableOps()
. Functions are curried with ramda.curry
. In addition to normal currying behaviour, you can use the ramda
placeholder variable available in ops.__
to specify parameters you want to pass arguments for later. Example:
const removeNFromHead = ops.splice(/* startIndex */ 0, /* deleteCount */ops.__, /* valsToAdd */[]);
const removeTwoFromHead = removeNFromHead(2);
const arr = [1, 2, 3];
console.log(removeTwoFromHead(arr));
// [3];
Executes functionToRun
as a batched mutation and returns the return value of functionToRun
.functionToRun
will be called without arguments. During functionToRun
execution, immutable-ops
will keep track of new objects created during operations, and apply further operations with mutations to those objects.
Like batched
, but returns a function that wraps functionToWrap
to be executed as a batch. functionToWrap
is also curried. When functionToWrap
is executed (all arguments are passed), all operations run during its execution will apply mutations instead of creating new objects whenever possible.
Opens a batch session. From this point on, any operations done through the ops
instance that open
was called from will be applied mutatively if the object it's operating on was created after opening the session.
Closes the current batch session.
Performs a shallow merge on targetObj
. mergeObj
can be a single object to merge, or a list of objects. If a list is passed as mergeObj
, objects to the right in the list will have priority when determining final attributes.
Returns the merged object, which will be a different object if an actual change was detected during the merge.
const result = ops.merge(
// mergeObj
{
a: 'theA',
b: {
c: 'nestedC',
},
},
// targetObj
{
a: 'theA2',
b: {
d: 'nestedD',
},
c: 'theC',
}
);
console.log(result);
// {
// {
// a: 'theA',
// b: {
// c: 'nestedC'
// },
// c: 'theC',
// },
// }
Same as merge
, but performs merge
recursively on attributes that are objects (not arrays).
const result = ops.deepMerge(
// mergeObj
{
a: 'theA',
b: {
c: 'nestedC',
},
},
// targetObj
{
a: 'theA2',
b: {
d: 'nestedD',
},
c: 'theC',
}
);
console.log(result);
// {
// {
// a: 'theA',
// b: {
// c: 'nestedC',
// d: 'nestedD',
// },
// c: 'theC',
// },
// }
Returns an object, with the value at path
set to value
. path
can be a dot-separated list of attribute values or an array of attribute names to traverse.
const obj = {
location: {
city: 'San Francisco',
},
};
const newObj = ops.setIn(['location', 'city'], 'Helsinki', obj);
console.log(newObj);
// {
// location: {
// city: 'Helsinki',
// },
// };
Returns a shallow copy of targetObj
without the keys specified in keysToOmit
. keysToOmit
can be a single key name or an array of key names.
const obj = {
a: true,
b: true,
};
const result = ops.omit('a', obj);
console.log(result);
// {
// b: true,
// }
Returns a new array with values
inserted at starting at index startIndex
to targetArray
.
const arr = [1, 2, 4];
const result = ops.insert(2, [3], arr);
console.log(result);
// [1, 2, 3, 4]
Returns a shallow copy of targetArray
with value
added to the end. value
can be a single value or an array of values to push.
const arr = [1, 2, 3];
const result = ops.push(4, arr);
console.log(result);
// [1, 2, 3, 4]
Returns a shallow copy of targetArray
with items that func
returns true
for, when calling it with the item.
const arr = [1, 2, 3, 4];
const result = ops.filter(item => item % 2 === 0, arr);
console.log(result);
// [2, 4]
Like Array.prototype.splice
, but operates on a shallow copy of targetArray
and returns the shallow copy.
const arr = [1, 2, 3, 3, 3, 4];
const result = ops.splice(2, 2, [], arr);
console.log(result);
// [1, 2, 3, 4]
Returns a shallow copy of target
with its value at index or key key
set to value
.
const arr = [1, 2, 5];
const result = ops.set(2, 3, arr);
console.log(result);
// [1, 2, 3]
const obj = {
a: 'X',
b: 'theB',
};
const resultObj = ops.set('a', 'theA', obj);
console.log(resultObj);
// {
// a: 'theA',
// b: 'theB',
// }
MIT. See LICENSE
FAQs
A collection of functions to perform immutable operations on plain JavaScript objects
The npm package immutable-ops receives a total of 2,318 weekly downloads. As such, immutable-ops popularity was classified as popular.
We found that immutable-ops demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Cloudflare has launched a setup wizard allowing users to easily create and manage a security.txt file for vulnerability disclosure on their websites.
Security News
The Socket Research team breaks down a malicious npm package targeting the legitimate DOMPurify library. It uses obfuscated code to hide that it is exfiltrating browser and crypto wallet data.
Security News
ENISA’s 2024 report highlights the EU’s top cybersecurity threats, including rising DDoS attacks, ransomware, supply chain vulnerabilities, and weaponized AI.