Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@broofa/merge

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@broofa/merge - npm Package Compare versions

Comparing version 1.0.1 to 1.0.2

53

index.js

@@ -1,45 +0,46 @@

function merge(a, b) {
/**
* @param {primitive} before
* @param {primitive} after
*/
function merge(before, after) {
// Identical?
if (a === b) return a;
if (before === after) return before;
// Undefined or null?
if (a == null || b == null) return b;
if (before == null || after == null) return after;
// Different types?
if (a.constructor !== b.constructor) return b;
if (before.constructor !== after.constructor) return after;
let type = typeof(a);
if (a.getTime) type = 'date' // Not JSON, but useful
if (Array.isArray(a)) type = 'array';
let type = before.constructor.name;
switch (type) {
// '===' comparable tyeps
case 'boolean':
case 'number':
case 'string': // Not strictly JSON but useful
return a === b ? a : b;
case 'Boolean':
case 'Number':
case 'String':
case 'Symbol':
return before === after ? before : after;
case 'date':
return a.getTime() === b.getTime() ? a : b;
case 'Date': // Not strictly JSON but useful
return before.getTime() === after.getTime() ? before : after;
case 'object': {
case 'Object': {
let isEqual = true;
const merged = {};
for (const k of new Set([...Object.keys(a), ...Object.keys(b)])) {
const val = merge(a[k], b[k]);
isEqual = isEqual && val === a[k];
for (const k of new Set([...Object.keys(before), ...Object.keys(after)])) {
const val = merge(before[k], after[k]);
isEqual = isEqual && val === before[k];
if (val !== undefined) merged[k] = val;
}
return isEqual ? a : merged;
return isEqual ? before : merged;
}
case 'array': {
let isEqual = a.length === b.length;
const merged = new Array(Math.max(a.length, b.length));
case 'Array': {
let isEqual = before.length === after.length;
const merged = new Array(Math.max(before.length, after.length));
for (let k = 0, l = merged.length; k < l; k++) {
const val = merge(a[k], b[k]);
isEqual = isEqual && val === a[k];
const val = merge(before[k], after[k]);
isEqual = isEqual && val === before[k];
if (val !== undefined) merged[k] = val;
}
return isEqual ? a : merged;
return isEqual ? before : merged;
}

@@ -46,0 +47,0 @@

{
"name": "@broofa/merge",
"version": "1.0.1",
"version": "1.0.2",
"description": "Merge immutable JSON data structures to allow for identity (===) comparisons on deeply-equal subtrees",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -7,5 +7,13 @@ <!--

Merge immutable JSON data structures to allow for identity (===) comparisons on
deeply-equal subtrees.
Merge immutable model state (or any data structure, really), preserving references to unchanged nodes. This
allows for `===` operation to determine where state has changed. (Useful when
dealing with immutable data models such as React+Redux, where `===` is used for
exactly this purpose.)
In practical terms, where `state = merge(before, after)` the returned `state` object has the following properties:
* `assert.deepEqual(state, after)` will always be true
* `state[X] === before[X]` will be true where `deepEqual(before[X], after[X])`
* `state[X] === after[X]` will be true where `after[X]` replaces all `before[X]` state
## Installation

@@ -23,35 +31,28 @@

const obj0 = {
const before = {
a: 'hello',
b: 123,
c: {
ca: 'zig',
cb: [{a:1}, {b:2}]
},
c: {ca: ['zig'], cb: [{a:1}, {b:2}]},
};
const obj1 = {
const after = {
a: 'world',
c: {
ca: {a: 1},
cb: [{a:99}, {b:2}]
},
b: 123,
c: {ca: ['zig'], cb: [{a:99}, {b:2}]},
};
const result = merge(obj0, obj1);
const state = merge(before, after);
// Result will always be deepEqual to right-most argument
assert.deepEqual(obj1, result);
assert.deepEqual(after, state); // Always true
// root.c has changed, so is not identical
result.c === obj0.c; // ⇨ false
// Where state HAS changed
state === before; // ⇨ false
state.c === before.c; // ⇨ false
state.c.cb === before.c.cb; // ⇨ false
state.c.cb[0] === before.c.cb[0]; // ⇨ false
// ... same goes for root.c.ca and root.c.cb and root.c.cb[0]
result.c.ca === obj0.c.ca; // ⇨ false
result.c.cb === obj0.c.cb; // ⇨ false
result.c.cb[0] === obj0.c.cb[0]; // ⇨ false
// Where state HAS NOT changed
state.c.ca === before.c.ca; // ⇨ true
state.c.cb[1] === before.c.cb[1]; // ⇨ true
// 'But root.c.cb[1] hasn't, so `===` works!
result.c.cb[1] === obj0.c.cb[1]; // ⇨ true
```

@@ -58,0 +59,0 @@

@@ -7,5 +7,13 @@ ```javascript --hide

Merge immutable JSON data structures to allow for identity (===) comparisons on
deeply-equal subtrees.
Merge immutable model state (or any data structure, really), preserving references to unchanged nodes. This
allows for `===` operation to determine where state has changed. (Useful when
dealing with immutable data models such as React+Redux, where `===` is used for
exactly this purpose.)
In practical terms, where `state = merge(before, after)` the returned `state` object has the following properties:
* `assert.deepEqual(state, after)` will always be true
* `state[X] === before[X]` will be true where `deepEqual(before[X], after[X])`
* `state[X] === after[X]` will be true where `after[X]` replaces all `before[X]` state
## Installation

@@ -23,34 +31,27 @@

const obj0 = {
const before = {
a: 'hello',
b: 123,
c: {
ca: 'zig',
cb: [{a:1}, {b:2}]
},
c: {ca: ['zig'], cb: [{a:1}, {b:2}]},
};
const obj1 = {
const after = {
a: 'world',
c: {
ca: {a: 1},
cb: [{a:99}, {b:2}]
},
b: 123,
c: {ca: ['zig'], cb: [{a:99}, {b:2}]},
};
const result = merge(obj0, obj1);
const state = merge(before, after);
// Result will always be deepEqual to right-most argument
assert.deepEqual(obj1, result);
assert.deepEqual(after, state); // Always true
// root.c has changed, so is not identical
result.c === obj0.c; // RESULT
// Where state HAS changed
state === before; // RESULT
state.c === before.c; // RESULT
state.c.cb === before.c.cb; // RESULT
state.c.cb[0] === before.c.cb[0]; // RESULT
// ... same goes for root.c.ca and root.c.cb and root.c.cb[0]
result.c.ca === obj0.c.ca; // RESULT
result.c.cb === obj0.c.cb; // RESULT
result.c.cb[0] === obj0.c.cb[0]; // RESULT
// 'But root.c.cb[1] hasn't, so `===` works!
result.c.cb[1] === obj0.c.cb[1]; // RESULT
// Where state HAS NOT changed
state.c.ca === before.c.ca; // RESULT
state.c.cb[1] === before.c.cb[1]; // RESULT
```
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc