198
*/
199
export function stableStringify(value: unknown): string {
201
>
return 'undefined';
202
>
}
203
>
try {
204
>
return _stableStringify(value, new WeakSet());
205
>
} catch {
206
return '';
207
}
209
210
>
function _stableStringify(value: unknown, seen: WeakSet<object>): string {
objects.ts
211
>
if (value === null || typeof value !== 'object') {
212
>
return JSON.stringify(value) ?? 'null';
213
>
}
214
>
if (seen.has(value as object)) {
215
>
return '"[Circular]"';
216
>
}
217
>
seen.add(value as object);
218
>
if (Array.isArray(value)) {
219
>
return '[' + value.map(v => _stableStringify(v, seen)).join(',') + ']';
220
>
}
221
>
const keys = Object.keys(value as object).sort();
222
>
const parts: string[] = [];
223
>
for (const k of keys) {
224
>
const v = (value as Record<string, unknown>)[k];
225
>
if (v === undefined) {
226
>
continue;
227
>
}
228
>
parts.push(JSON.stringify(k) + ':' + _stableStringify(v, seen));
229
>
}
230
>
return '{' + parts.join(',') + '}';
231
>
}
232
233
type obj = { [key: string]: any };