serialize-anything
Version:
serialize and de-serialize any JavaScript data
1 lines • 9.16 kB
JavaScript
const deepCopy=require("deep-copy-all"),defaultOptions={maxDepth:20,pretty:!1};function namedConstructor(e){let r="undefined"!=typeof global&&global[e]||"undefined"!=typeof window&&window[e]||"undefined"!=typeof WorkerGlobalScope&&WorkerGlobalScope[e];return"function"!=typeof r&&(r=null),r}function serializeObject(e,r,t){if(++t>r.maxDepth)throw"Error maximum depth exceeded - possible circular reference";let a=" ";for(let e=0;e<t;e++)a+=" ";const i=objectType(e),n=objectBehaviors[i],o=n.serialize,s=n.iterate,l=n.setValue;return s&&s(e,a=>{const i=a.type,n=objectBehaviors[i],o=n.serialize,s=n.iterate,y=a.value;s?a.value=serializeObject(a.value,r,t):o&&(a.value=o(a.value)),a.value!==y&&l(e,a)}),o&&(e=o(e)),e}function serialize(e,r){void 0===(r=r||defaultOptions).maxDepth&&(r.maxDepth=defaultOptions.maxDepth),void 0===r.pretty&&(r.pretty=defaultOptions.pretty);let t=deepCopy(e);const a={_Serialize_Any_Encoded:!0,_SA_Content:t=serializeObject(t,r,0)};return r.pretty?JSON.stringify(a,null,2):JSON.stringify(a)}const deserializeChildren=(e,r,t,a)=>{const i=a.iterate;if(!i)return;const n=a.setValue;i(e,a=>{const i=a.type,o=objectBehaviors[i],s=o.deserialize;o.iterate?a.value=deserializeObject(a.value,r,t):s&&(a.value=s(a.value,r),n(e,a))})};function deserializeObject(e,r,t){t++;let a=objectType(e),i=objectBehaviors[a];const n=i.deserialize;return n&&(e=n(e,r),a=objectType(e),i=objectBehaviors[a]),deserializeChildren(e,r,t,i),e}function deserialize(e,r){let t=JSON.parse(e);if("Object"!==objectType(t)||!t._Serialize_Any_Encoded)throw"Error: object was not serialized by serialize-any";return deserializeObject(t=t._SA_Content,r,0)}const isPrimitive=e=>{let r=typeof e;return"number"===r||"string"===r||"boolean"===r||"symbol"===r||null===e},objectType=e=>{let r=null;const t=e&&e.constructor&&e.constructor.name;return r=isPrimitive(e)||!e instanceof Object?"primitive":void 0===e?"undef":"bigint"==typeof e?"BigInt":e._SAType&&e._SAType.includes("_SACustom")?e._SAType:void 0!==e._SAType?e._SAType+"_Serialized":"string"==typeof t&&t.length&&objectBehaviors[t]?t:e instanceof Array&&"Array"!==t?"CustomArray":e instanceof Object&&"Object"!==t?"CustomObject":e instanceof Array?"CustomObject":"Object"},arrayIterate=(e,r)=>{const t=e.length;for(let a=0;a<t;a++){const t=e[a];r({key:a,value:t,type:objectType(t)})}},objectBehaviors={Array:{type:Array,serialize:e=>"Array"!==e.constructor.name?{_SAType:"_SACustomArray",_SAconstructorName:e.constructor.name,_SAvalues:Array.from(e)}:e,iterate:arrayIterate,setValue:(e,r)=>{e[r.key]=r.value}},Date:{type:Date,serialize:e=>({_SAType:"Date",_SAtimestamp:e.getTime()})},Date_Serialized:{deserialize:e=>new Date(e._SAtimestamp)},RegExp:{type:RegExp,serialize:e=>({_SAType:"RegExp",_SAsource:e.source,_SAflags:e.flags})},RegExp_Serialized:{deserialize:e=>new RegExp(e._SAsource,e._SAflags||"")},Function:{type:Function,serialize:e=>({_SAType:"Function",_SAfunction:e.toString()})},Function_Serialized:{deserialize:e=>new Function("return "+e._SAfunction)()},undef:{serialize:()=>({_SAType:"undef"})},undef_Serialized:{deserialize:()=>{}}};"undefined"!=typeof BigInt&&Object.assign(objectBehaviors,{BigInt:{type:BigInt,serialize:e=>({_SAType:"BigInt",_SAnum:e.toString()})},BigInt_Serialized:{deserialize:e=>BigInt(e._SAnum)}}),"undefined"!=typeof Int8Array&&Object.assign(objectBehaviors,{Int8Array:{type:Int8Array,serialize:e=>({_SAType:"Int8Array",_SAvalues:Array.from(e)})},Int8Array_Serialized:{deserialize:e=>Int8Array.from(e._SAvalues)}}),"undefined"!=typeof Uint8Array&&Object.assign(objectBehaviors,{Uint8Array:{type:Uint8Array,serialize:e=>({_SAType:"Uint8Array",_SAvalues:Array.from(e)})},Uint8Array_Serialized:{deserialize:e=>Uint8Array.from(e._SAvalues)}}),"undefined"!=typeof Uint8ClampedArray&&Object.assign(objectBehaviors,{Uint8ClampedArray:{type:Uint8ClampedArray,serialize:e=>({_SAType:"Uint8ClampedArray",_SAvalues:Array.from(e)})},Uint8ClampedArray_Serialized:{deserialize:e=>Uint8ClampedArray.from(e._SAvalues)}}),"undefined"!=typeof Int16Array&&Object.assign(objectBehaviors,{Int16Array:{type:Int16Array,serialize:e=>({_SAType:"Int16Array",_SAvalues:Array.from(e)})},Int16Array_Serialized:{deserialize:e=>Int16Array.from(e._SAvalues)}}),"undefined"!=typeof Uint16Array&&Object.assign(objectBehaviors,{Uint16Array:{type:Uint16Array,serialize:e=>({_SAType:"Uint16Array",_SAvalues:Array.from(e)})},Uint16Array_Serialized:{deserialize:e=>Uint16Array.from(e._SAvalues)}}),"undefined"!=typeof Int32Array&&Object.assign(objectBehaviors,{Int32Array:{type:Int32Array,serialize:e=>({_SAType:"Int32Array",_SAvalues:Array.from(e)})},Int32Array_Serialized:{deserialize:e=>Int32Array.from(e._SAvalues)}}),"undefined"!=typeof Uint32Array&&Object.assign(objectBehaviors,{Uint32Array:{type:Uint32Array,serialize:e=>({_SAType:"Uint32Array",_SAvalues:Array.from(e)})},Uint32Array_Serialized:{deserialize:e=>Uint32Array.from(e._SAvalues)}}),"undefined"!=typeof Float32Array&&Object.assign(objectBehaviors,{Float32Array:{type:Float32Array,serialize:e=>({_SAType:"Float32Array",_SAvalues:Array.from(e)})},Float32Array_Serialized:{deserialize:e=>Float32Array.from(e._SAvalues)}}),"undefined"!=typeof Float64Array&&Object.assign(objectBehaviors,{Float64Array:{type:Float64Array,serialize:e=>{let r=[];return e.forEach(e=>r.push(e.toString())),{_SAType:"Float64Array",_SAvalues:r}}},Float64Array_Serialized:{deserialize:e=>Float64Array.from(e._SAvalues)}}),"undefined"!=typeof BigInt64Array&&Object.assign(objectBehaviors,{BigInt64Array:{type:BigInt64Array,serialize:e=>{let r=[];return e.forEach(e=>r.push(e.toString())),{_SAType:"BigInt64Array",_SAvalues:r}}},BigInt64Array_Serialized:{deserialize:e=>BigInt64Array.from(e._SAvalues)}}),"undefined"!=typeof BigUint64Array&&Object.assign(objectBehaviors,{BigUint64Array:{type:BigUint64Array,serialize:e=>{let r=[];return e.forEach(e=>r.push(e.toString())),{_SAType:"BigUint64Array",_SAvalues:r}}},BigUint64Array_Serialized:{deserialize:e=>BigUint64Array.from(e._SAvalues)}}),"undefined"!=typeof ArrayBuffer&&Object.assign(objectBehaviors,{ArrayBuffer:{type:ArrayBuffer,serialize:e=>{const r=new Uint8Array(e);let t=[];return r.forEach(e=>{t.push(e)}),{_SAType:"ArrayBuffer",_SAvalues:t}}},ArrayBuffer_Serialized:{deserialize:e=>{const r=e._SAvalues,t=new ArrayBuffer(r.length);return new Uint8Array(t).set(r),t}}}),"undefined"!=typeof Map&&Object.assign(objectBehaviors,{Map:{type:Map,serialize:e=>{let r=[];return e.forEach((e,t)=>{r.push([t,e])}),{_SAType:"Map",_SAkvPairs:r}},iterate:(e,r)=>{e.forEach((e,t)=>{const a={key:t,value:e,type:objectType(e)};r(a)})},setValue:(e,r)=>{e.set(r.key,r.value)}},Map_Serialized:{deserialize:e=>{const r=e._SAkvPairs,t=new Map;return r.forEach(([e,r])=>{t.set(e,r)}),t}}}),"undefined"!=typeof Set&&Object.assign(objectBehaviors,{Set:{type:Set,serialize:e=>{let r=[];return e.forEach(e=>r.push(e)),{_SAType:"Set",_SAvalues:r}},iterate:(e,r)=>{e.forEach(e=>{const t={key:null,value:e,originalValue:e,type:objectType(e)};r(t)})},setValue:(e,r)=>{e.delete(r.originalValue),e.add(r.value),r.originalValue=r.value}},Set_Serialized:{deserialize:e=>new Set(e._SAvalues)}}),"undefined"!=typeof WeakSet&&Object.assign(objectBehaviors,{WeakSet:{type:WeakSet,serialize:()=>{throw"Error: serialize WeakSet not supported"}}}),"undefined"!=typeof WeakMap&&Object.assign(objectBehaviors,{WeakMap:{type:WeakMap,serialize:()=>{throw"Error: serialize WeakMap not supported"}}}),"undefined"!=typeof Buffer&&Object.assign(objectBehaviors,{Buffer:{type:Buffer,serialize:e=>({_SAType:"Buffer",_SAutf8String:e.toString()})},Buffer_Serialized:{deserialize:e=>Buffer.from(e._SAutf8String)}}),"undefined"!=typeof Error&&Object.assign(objectBehaviors,{Error:{type:Error,serialize:e=>({_SAType:"Error",_SAmessage:e.message,_SAstack:e.stack})},Error_Serialized:{deserialize:e=>{const r=Error(e._SAmessage);return r.stack=e._SAstack,r}}});const objectIterate=(e,r)=>{const t=Object.keys(e),a=t.length;for(let i=0;i<a;i++){const a=t[i],n=e[a];r({key:a,value:n,type:objectType(n)})}};Object.assign(objectBehaviors,{CustomArray:{serialize:e=>({_SAType:"_SACustomArray",_SAconstructorName:e.constructor.name,_SAvalues:Array.from(e)}),iterate:arrayIterate,setValue:(e,r)=>{e[r.key]=r.value}},CustomObject:{serialize:e=>({_SAType:"_SACustomObject",_SAconstructorName:e.constructor.name,_SAobject:Object.assign({},e)}),iterate:objectIterate,setValue:(e,r)=>{e[r.key]=r.value}},Object:{type:Object,iterate:objectIterate,setValue:(e,r)=>{e[r.key]=r.value}},_SACustomObject:{deserialize:(e,r)=>{const t=e._SAconstructorName,a=e._SAobject,i=namedConstructor(t);let n;if(i)n=new i;else{if(!r)throw"Error: deserialize _SACustomObject - getCustomObject missing";n=r(t)}if(!n)throw'Error: unable to deserialize - "'+t+'" undefined';return Object.assign(n,a),n}},_SACustomArray:{deserialize:(e,r)=>{const t=e._SAconstructorName;let a=e._SAvalues;const i=namedConstructor(t);let n;if(i)n=new i(t);else{if(!r)throw"Error: deserialize _SACustomArray - getCustomObject missing";n=r(t)}if(!n)throw'Error: deserialize _SACustomArray - "'+t+'" undefined';return n=n.concat(n,a)}},unknown:{},primitive:{}}),module.exports={serialize:serialize,deserialize:deserialize};