Skip to content

Instantly share code, notes, and snippets.

@colelawrence
Last active January 11, 2024 21:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save colelawrence/e230ac02da14afa8dc9fa5ba20cfd3c5 to your computer and use it in GitHub Desktop.
Save colelawrence/e230ac02da14afa8dc9fa5ba20cfd3c5 to your computer and use it in GitHub Desktop.
Tight JSON and JavaScript stringify
function jsReplacer() {
const seen = new WeakSet();
return (key: string, value: any) => {
if (typeof value === "object" && value !== null) {
if (seen.has(value)) return "[Circular]";
seen.add(value);
}
if (value instanceof RegExp) return { regexp: value.toString() };
if (value instanceof Function) return { function: value.toString() };
if (value instanceof Error) return { error: value.toString() };
if (value instanceof Set) return [...value];
if (value instanceof Map) return Object.fromEntries(value);
if (typeof window !== "undefined" && value instanceof window.Node)
return { node: `<${value.nodeName}/>` };
return value;
};
}
export function tightJsonStringify(
obj: any,
replacer?: ((this: any, key: string, value: any) => any) | undefined,
) {
if (obj === undefined) return undefined;
return JSON.stringify(obj, replacer, 2)
.replace(/^([{[])\n (\s+)/, "$1$2")
.replace(/(\n[ ]+[{[])\n\s+/g, "$1 ")
.replace(/\n\s*([\]}])/g, " $1");
}
export function tightJavaScriptify(value: any): string {
return javaScriptifyJSON(tightJsonStringify(value, jsReplacer()));
}
export function lineJavaScriptify(value: any): string {
if (value == null) return String(value);
return javaScriptifyJSON(JSON.stringify(value, jsReplacer()));
}
function javaScriptifyJSON(json: string | undefined | null): string {
if (json == null) return String(json);
return json
.replace(/([^\\"])"((:?[^"\\]+|\\[^"]|\\")+)"/g, (full, init, inner) => {
if (inner.includes("\\n")) {
return `${init}\`${inner
.replace(/`/g, "\\`")
.replace(/\\"/g, '"')
.replace(/([^\\])\\n/g, "$1\n")}\``;
}
return full;
})
.replace(/(\\?")((?:[^\\"\s-]|\\\1)+)\1:/g, "$2:");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment