1.0.1 • Published 2 years ago

object-deep-recreate v1.0.1

Weekly downloads
-
License
ISC
Repository
github
Last release
2 years ago

Object-deep-recreate

This library compares inputs deeply and creates new memory references when a value or its children inside the input change, but makes sure not to create new memory references where unnecessary.

It works by comparing 2 inputs - the new altered object/array and a previous cloned snapshot.

import { deepRecreate } from "object-deep-recreate";

const snapshot = [{ id: 1, name: 'Post1' }, { id: 2, name: 'Post2' }]
const posts = JSON.parse(JSON.stringify(snapshot))

posts[0].name = 'New name'

const result = deepRecreate(posts, snapshot);

expect(result[0] === posts[0]).toBe(false); // first post is changed inside, new memory reference
expect(result[1] === posts[1]).toBe(true); // second post stayed untouched, original memory reference

More test cases can be found below, or in the __tests__ folder:


  let oldValue = {
    posts: [
      { id: 1, name: 'Post 1' },
      { id: 2, name: 'Post 2' },
      { id: 3, name: 'Post 3' }
    ],
    likes: [{ id: 1, count: 10 }]
  };

  const newValue = JSON.parse(JSON.stringify(oldValue));

  const result1 = deepRecreate(newValue, oldValue);

  expect(result1).toEqual(newValue);
  expect(result1).toEqual(oldValue);
  expect(result1 === newValue).toBe(true); // the result object is unchanged

  // remove the last post
  newValue.posts.splice(2, 1);
  const result2 = deepRecreate(newValue, oldValue)

  expect(result2).toEqual(newValue);  // the data has the same format
  expect(result2).not.toEqual(oldValue);
  expect(result2 === newValue).toBe(false); // the result object is re-created due to deep change

  expect(result2.likes === newValue.likes).toBe(true); // likes array is unchanged
  expect(result2.posts === newValue.posts).toBe(false); // posts array is re-created

  // however the first and second post remained the same
  expect(result2.posts[0] === newValue.posts[0]).toBe(true); // post 1 is unchanged
  expect(result2.posts[1] === newValue.posts[1]).toBe(true); // post 2 is unchanged

  // changing an object inside the array but keeping the array's length

  oldValue = JSON.parse(JSON.stringify(newValue)); // create new snapshot before modifying the memory value
  newValue.posts[0].name = 'New name'; // rename first post

  const result3 = deepRecreate(newValue, oldValue)

  // changing only the first post
  expect(result3 === newValue).toBe(false); // result object is is re-created due to deep change

  expect(result3.posts === newValue.posts).toBe(false); // posts array is re-created
  expect(result3.likes === newValue.likes).toBe(true); // likes array is unchanged

  expect(result3.posts[0] === newValue.posts[0]).toBe(false); // first post is re-created
  expect(result3.posts[0].name).toEqual('New name');

  expect(result3.posts[1] === newValue.posts[1]).toBe(true); // second post is unchanged