"use strict" ;
const defaultValue = require ( "default-value" ) ;
const nanoid = require ( "nanoid" ) ;
const jsonStringifyPreReplacer = require ( "../json-stringify-pre-replacer" ) ;
module . exports = function serialize ( instance , options = { } ) {
let customSerializer = defaultValue ( options . serializer , ( value ) => value ) ;
/* FIXME: Remove `serializer` argument and let this be specified on fields / type aliases instead? */
let seenItems = new Map ( ) ;
let data = jsonStringifyPreReplacer ( instance , ( key , value ) => {
if ( value == null ) {
return value ;
} else if ( value . _guardedCollectionType === "set" ) {
return {
_d _sT : "gS" ,
entries : Array . from ( value . _source . values ( ) )
} ;
} else if ( value . _guardedCollectionType === "map" ) {
return {
_d _sT : "gM" ,
entries : Array . from ( value . _source . entries ( ) )
} ;
} else if ( value . _guardedCollectionType === "array" ) {
return {
_d _sT : "gA" ,
/* We shallow-clone the array here for now, because otherwise the stringifier will infinitely recurse into `entries` properties; shallow-cloning the array results in a *real* array, that doesn't have the `_guardedCollectionType` property. */
entries : value . slice ( )
} ;
} else if ( value . _type != null && value . _type . _isCustomType === true ) {
if ( ! seenItems . has ( value ) ) {
let objectID = nanoid ( ) ;
seenItems . set ( value , objectID ) ;
value . _type . _ensureHash ( ) ;
return {
_d _sT : "cT" ,
type : value . _type . _typeHash ,
data : value . _data ,
id : objectID
} ;
} else {
return {
_d _sT : "cTR" ,
id : seenItems . get ( value )
} ;
}
} else {
return customSerializer ( value ) ;
}
} ) ;
return data ;
} ;