precise-copy v0.2.3
precise-copy • 

Installation
$ npm install precise-copy --saveUsage
precise-copy consists of 2 main parts: TypeList which tells how to handle each type and copy function that actullay preforms the precies copy
TypeList Items
Each item in type list must follow this structure
let typeListArrayItem = {
type: Array,
copy: (x) => x.slice()
}Value of the type field must be the prototype elements would be matched with it using instanceof
Value of the copy should be function that takes instance as an argument and returns a shallow copy of it
NOTE: most js types (Object, Array, Date, Set, Map) are already added to the lib You can access them this way
let arrayType = require('precise-copy/typeLib/array') //equals to the typeListArrayItem in the previous exampleTypeList API
This is an example of basic type list that would allow Array, Date and Object copy
const arrayType = require('precise-copy/typeLib/array')
const objectType = require('precise-copy/typeLib/object')
const dateType = require('precise-copy/typeLib/date')
const TypeList = require('precise-copy').TypeList
let myTypeList = new TypeList([dateType, arrayType, objectType])You can add items to the existing type list
let setType = require('precise-copy/typeLib/set')
myTypeList.add(setType)
//it is recommended to rearrange TypeList in this case to insure that element would not be matched with no parent type are before it's children
myTypeList.arrange().arrange() changes type order so instanceof would always trigger on child types first for example it puts myDate that inherits from date in before Date and as all js complex types are childs of Object it goes after those.
Other TypeList methods are for internal usage by precise-copy
Copy
Imagine this is a redux project your state is something like
let state = {
filters: {...}, //some filer data
user: {...}, //some user date
articles: []
}And each article is something like
{
title: 'Title',
content: '...', //some long text
publishDate: new Date(),
tags: {
global: ['a', 'b', 'c'],
personal: []
}
}And now, adding a tag is really painful, because we need to change state.articles[index].tags.global without affecting previous state
Let's use our myTypeList and copy here to precisely copy all the way to the global tags of the 3rd article
let index = 2
let path = ['articles', index, 'tags', 'global'] //keys, which values would be shallow copied
let statePreciseCopy = preciseCopy.copy(myTypeList, source, path)
//as we intially wanted to push something there
statePreciseCopy.articles[index].tags.global.push("it's still pure!")And that's it! The most important thing is that state.filters every other article and even 3rd article's personal tags are still being passed by reference which saves a lot of CPU load and memory compared to deepCopy and a lot of your time compared to rewriting this copying each time.
Tip
If you are using lodash this might be a good idea myPreciseCopy.js
const _ = require('lodash')
const arrayType = require('precise-copy/typeLib/array')
const objectType = require('precise-copy/typeLib/object')
const dateType = require('precise-copy/typeLib/date')
const preciseCopy = require('precise-copy')
let myTypeList = new preciseCopy.TypeList([dateType, arrayType, objectType])
module.exports = _.curry(preciseCopy.copy)(myTypeList)someReducer.js
const preciseCopy = require('./myPreciseCopy')
let newState = preciseCopy(state, path)