You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
1.6 KiB
JavaScript

"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;
};