deep-clone-and-serialize
Version:
Deep clone and/or serialize almost any JavaScript object tree (Map/Set, RegExp, DataView, etc.) while preserving circular references.
135 lines (120 loc) • 3.05 kB
JavaScript
//test
var packer=new Dupify()
var buffer=new ArrayBuffer(7)
var arrBuff=new Uint8Array(buffer)
var arrBuff2=new Uint8Array(buffer)
var data=new DataView(buffer)
arrBuff[1]=1;
arrBuff[2]=2;
arrBuff[3]=3;
arrBuff[4]=4;
arrBuff[5]=5;
/*
alright then, in cloning, when you come accross an arraybuffer, you register it and clone it just like normal
when you come accross a typed array, you check if its buffer is in the registry, if not you clone it and add it to the registry,
then initialize the new array with the buffer. and offset and bytelength it doesn't need to have a separate home on the object tree, just in memory
*/
var Scout=function(){
this.eagle='grins'
this.dollar='agin'
}
var scout=new Scout()
var key={daisies:'tulips'}
var value={marmalade:'jam'}
var key2={the:'dukes'}
var value2={of:'hazard'}
var t={
obj:{
insideobj:{variable:1}
},
arr:[1,2,3,4,5],
map:new Map(),
insidemap:new Map(),
set:new Set([6,7,8,value2,9]),
date:new Date(),
reg:/ert(ab){3}/g,
nan:'ert'/4,
inf:Infinity,
null:'geg',
undefined:'ggeg',
arrBuff,
arrBuff2,
func:packer.deepClone,
err:new TypeError('ertoi'),
buffer,
data,
scout,
str:'sdfgh',
// arrBuff,
}
t.map.set(key2,undefined)
t.insidemap.set(key2,t.map)
t.obj.circle=t//t.mark1.round=t.mark1
t.set.add(t.mark1)
t.set.add(t.map)
t.set.add(t.set)
t.map.set(key,value)
t.arr.enum=t.obj
t.map.enum=t.obj
t.set.enum=t.obj
t.date.enum=t.obj
t.reg.enum=t.obj
t.arrBuff.enum=t.obj
t.func.enum=t.obj
t.err.enum=t.obj
t.scout.enum=t.obj
t.data.enum=t.obj
t.buffer.enum=t.obj
//t.map.set(key2,t.mark1)
var arrayWrap=function(thing){
if(Object.prototype.toString.call(thing)!=='[object Array]'){
return [thing]
}else{return thing}
}
/////////////tests
var transform=function(obj){
if (obj &&obj.constructor===Map){return{time:'will tell',and:{bealtle:'hhuice'},circ:t}}
return obj
}
var revive=function(obj){
if (obj &&obj.time){return {Icarus:'wants his wings back'}}
return obj
}
var overrevive=function(obj){
if (obj &&obj.time){return {Icarus:'flew too close'}}
return obj
}
packer.addFilters(
(p)=>{
var val=p.next.value
if(val &&val.constructor===DataView){return false}
}
)
//packer.setTransform(transform)
packer.setRevival(revive)
var wrapper=data
wrapper.enum=t
//*clone
//var ct=packer.clone({obj:t,suppressTransform:1})
var ct=packer.clone({obj:wrapper,suppressFilters:true})
console.log(ct)
console.log(ct.enum===wrapper.enum,'y')
/*/
t.copy=true
var ct=packer.pack({obj:wrapper})
ct=packer.unpack({obj:ct,revival:overrevive})
//console.log(ct.arrBuff.buffer===ct.arrBuff2.buffer)
console.log(ct)
//*/
/*
var Replicator = require('replicator');
var replicator = new Replicator();
var str = replicator.encode(wrapper);
var obj = replicator.decode(str);
console.log('repl',obj)
var mine=packer.pack({obj:t})
mine=packer.unpack(mine)
console.log('mine',mine)
//*/
var handle={}
export {handle}