UNPKG

@bigmi/client

Version:

Reactive primitives for Bitcoin apps.

82 lines (81 loc) 2.7 kB
//#region src/utils/serialize.ts /** * Get the reference key for the circular value * * @param keys the keys to build the reference key from * @param cutoff the maximum number of keys to include * @returns the reference key */ function getReferenceKey(keys, cutoff) { return keys.slice(0, cutoff).join(".") || "."; } /** * Faster `Array.prototype.indexOf` implementation build for slicing / splicing * * @param array the array to match the value in * @param value the value to match * @returns the matching index, or -1 */ function getCutoff(array, value) { const { length } = array; for (let index = 0; index < length; ++index) if (array[index] === value) return index + 1; return 0; } /** * Create a replacer method that handles circular values * * @param [replacer] a custom replacer to use for non-circular values * @param [circularReplacer] a custom replacer to use for circular methods * @returns the value to stringify */ function createReplacer(replacer, circularReplacer) { const hasReplacer = typeof replacer === "function"; const hasCircularReplacer = typeof circularReplacer === "function"; const cache = []; const keys = []; return function replace(key, value) { if (typeof value === "object") if (cache.length) { const thisCutoff = getCutoff(cache, this); if (thisCutoff === 0) cache[cache.length] = this; else { cache.splice(thisCutoff); keys.splice(thisCutoff); } keys[keys.length] = key; const valueCutoff = getCutoff(cache, value); if (valueCutoff !== 0) return hasCircularReplacer ? circularReplacer.call(this, key, value, getReferenceKey(keys, valueCutoff)) : `[ref=${getReferenceKey(keys, valueCutoff)}]`; } else { cache[0] = value; keys[0] = key; } return hasReplacer ? replacer.call(this, key, value) : value; }; } /** * Stringifier that handles circular values * * Forked from https://github.com/planttheidea/fast-stringify * * @param value to stringify * @param [replacer] a custom replacer function for handling standard values * @param [indent] the number of spaces to indent the output by * @param [circularReplacer] a custom replacer function for handling circular values * @returns the stringified output */ function serialize(value, replacer, indent, circularReplacer) { return JSON.stringify(value, createReplacer((key, value_) => { let value = value_; if (typeof value === "bigint") value = { __type: "bigint", value: value_.toString() }; if (value instanceof Map) value = { __type: "Map", value: Array.from(value_.entries()) }; return replacer?.(key, value) ?? value; }, circularReplacer), indent ?? void 0); } //#endregion export { serialize }; //# sourceMappingURL=serialize.js.map