• Stars
    star
    335
  • Rank 125,904 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 8 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Safely and quickly serialize JavaScript objects

fast-safe-stringify

Safe and fast serialization alternative to JSON.stringify.

Gracefully handles circular structures instead of throwing in most cases. It could return an error string if the circular object is too complex to analyze, e.g. in case there are proxies involved.

Provides a deterministic ("stable") version as well that will also gracefully handle circular structures. See the example below for further information.

Usage

The same as JSON.stringify.

stringify(value[, replacer[, space[, options]]])

const safeStringify = require('fast-safe-stringify')
const o = { a: 1 }
o.o = o

console.log(safeStringify(o))
// '{"a":1,"o":"[Circular]"}'
console.log(JSON.stringify(o))
// TypeError: Converting circular structure to JSON

function replacer(key, value) {
  console.log('Key:', JSON.stringify(key), 'Value:', JSON.stringify(value))
  // Remove the circular structure
  if (value === '[Circular]') {
    return
  }
  return value
}

// those are also defaults limits when no options object is passed into safeStringify
// configure it to lower the limit.
const options = {
  depthLimit: Number.MAX_SAFE_INTEGER,
  edgesLimit: Number.MAX_SAFE_INTEGER
};

const serialized = safeStringify(o, replacer, 2, options)
// Key: "" Value: {"a":1,"o":"[Circular]"}
// Key: "a" Value: 1
// Key: "o" Value: "[Circular]"
console.log(serialized)
// {
//  "a": 1
// }

Using the deterministic version also works the same:

const safeStringify = require('fast-safe-stringify')
const o = { b: 1, a: 0 }
o.o = o

console.log(safeStringify(o))
// '{"b":1,"a":0,"o":"[Circular]"}'
console.log(safeStringify.stableStringify(o))
// '{"a":0,"b":1,"o":"[Circular]"}'
console.log(JSON.stringify(o))
// TypeError: Converting circular structure to JSON

A faster and side-effect free implementation is available in the [safe-stable-stringify][] module. However it is still considered experimental due to a new and more complex implementation.

Replace strings constants

  • [Circular] - when same reference is found
  • [...] - when some limit from options object is reached

Differences to JSON.stringify

In general the behavior is identical to JSON.stringify. The replacer and space options are also available.

A few exceptions exist to JSON.stringify while using toJSON or replacer:

Regular safe stringify

  • Manipulating a circular structure of the passed in value in a toJSON or the replacer is not possible! It is possible for any other value and property.

  • In case a circular structure is detected and the replacer is used it will receive the string [Circular] as the argument instead of the circular object itself.

Deterministic ("stable") safe stringify

  • Manipulating the input object either in a toJSON or the replacer function will not have any effect on the output. The output entirely relies on the shape the input value had at the point passed to the stringify function!

  • In case a circular structure is detected and the replacer is used it will receive the string [Circular] as the argument instead of the circular object itself.

A side effect free variation without these limitations can be found as well (safe-stable-stringify). It is also faster than the current implementation. It is still considered experimental due to a new and more complex implementation.

Benchmarks

Although not JSON, the Node.js util.inspect method can be used for similar purposes (e.g. logging) and also handles circular references.

Here we compare fast-safe-stringify with some alternatives: (Lenovo T450s with a i7-5600U CPU using Node.js 8.9.4)

fast-safe-stringify:   simple object x 1,121,497 ops/sec ±0.75% (97 runs sampled)
fast-safe-stringify:   circular      x 560,126 ops/sec ±0.64% (96 runs sampled)
fast-safe-stringify:   deep          x 32,472 ops/sec ±0.57% (95 runs sampled)
fast-safe-stringify:   deep circular x 32,513 ops/sec ±0.80% (92 runs sampled)

util.inspect:          simple object x 272,837 ops/sec ±1.48% (90 runs sampled)
util.inspect:          circular      x 116,896 ops/sec ±1.19% (95 runs sampled)
util.inspect:          deep          x 19,382 ops/sec ±0.66% (92 runs sampled)
util.inspect:          deep circular x 18,717 ops/sec ±0.63% (96 runs sampled)

json-stringify-safe:   simple object x 233,621 ops/sec ±0.97% (94 runs sampled)
json-stringify-safe:   circular      x 110,409 ops/sec ±1.85% (95 runs sampled)
json-stringify-safe:   deep          x 8,705 ops/sec ±0.87% (96 runs sampled)
json-stringify-safe:   deep circular x 8,336 ops/sec ±2.20% (93 runs sampled)

For stable stringify comparisons, see the performance benchmarks in the safe-stable-stringify readme.

Protip

Whether fast-safe-stringify or alternatives are used: if the use case consists of deeply nested objects without circular references the following pattern will give best results. Shallow or one level nested objects on the other hand will slow down with it. It is entirely dependant on the use case.

const stringify = require('fast-safe-stringify')

function tryJSONStringify (obj) {
  try { return JSON.stringify(obj) } catch (_) {}
}

const serializedString = tryJSONStringify(deep) || stringify(deep)

Acknowledgements

Sponsored by nearForm

License

MIT

More Repositories

1

0x

🔥 single-command flamegraph profiling 🔥
JavaScript
2,915
star
2

rfdc

Really Fast Deep Clone
JavaScript
636
star
3

flatstr

Flattens the underlying C structures of a concatenated JavaScript string
JavaScript
346
star
4

v8-perf

Exploring v8 performance characteristics in Node across v8 versions 5.1, 5.8, 5.9, 6.0 and 6.1
JavaScript
278
star
5

fast-redact

very fast object redaction
JavaScript
274
star
6

overload-protection

Load detection and shedding capabilities for http, express, restify and koa
JavaScript
200
star
7

react-functional

Add life cycle methods to stateless functional components, without the class noise
JavaScript
91
star
8

cute-stack

Cute up your stack traces in Node
JavaScript
82
star
9

atomic-sleep

⏱️Zero CPU overhead, zero dependency, true event-loop blocking sleep ⏱️
JavaScript
78
star
10

brittle

Brittle TAP test framework
JavaScript
57
star
11

Respondu

An Extendible Deferred Asset Responsive Framework
JavaScript
32
star
12

keepings-node.js-fast

Repository accompanying the Keeping Node.js Fast article
JavaScript
31
star
13

screenres

Get and set screen resolutions
C++
20
star
14

decofun

Debug tool. Names anonymous functions according to their surrounding context
JavaScript
18
star
15

lazaretto

Run esm and/or cjs code in a separate V8 isolate with code-injection capabilities
JavaScript
17
star
16

a-new-way-to-profile-node-js

HTML
15
star
17

async-tracer

Trace all async operations, output as newline delimited JSON logs, with minimal overhead.
JavaScript
15
star
18

proffer

Realtime V8 Tick Profiler
JavaScript
13
star
19

websocket-pull-stream

websockets with pull-streams
JavaScript
13
star
20

hsl-to-hex

JavaScript
12
star
21

is-file-esm

Determines whether a Node file is a Module (`import`) or a Script (`require`)
JavaScript
11
star
22

hrepl

Hydrate a REPL with new globals from a file's exports.
JavaScript
11
star
23

d3-fg

Flamegraph visualization for d3 v5
JavaScript
11
star
24

events.once

Polyfill for Node core events.once
JavaScript
11
star
25

nw-shot

Create screenshots using nw.js
JavaScript
10
star
26

core-dump

Generate node core dumps with having to abort, regardless of ulimit -c setting
JavaScript
10
star
27

does-it-fit

Determine whether an HTTP endpoints TCP response fits within minimum constraints
JavaScript
9
star
28

fast-date

Fast UTC Date Timestamps
JavaScript
9
star
29

fastify-react

seamlessly integrate fastify and react, for high performance SSR
JavaScript
9
star
30

nodux

nodux
JavaScript
8
star
31

perf-sym

Map Symbols Generated By --perf-basic-prof to JavaScript names
JavaScript
8
star
32

nonsynchronous

async/await callback fusioning utilities
JavaScript
8
star
33

ubuntu-dev-ec2

Ubuntu EC2 Machine intended for development/profiling usage.
JavaScript
7
star
34

rifi

rifi - distributed single state application self registering components - proof of concept
JavaScript
7
star
35

hash-phrase

A human readable hash function
JavaScript
6
star
36

inclusion

Dynamic imports for all
JavaScript
6
star
37

mockalicious

Keep on mocking in the free world
JavaScript
6
star
38

stateful-hooks

Give your react hooks state on the server side
JavaScript
6
star
39

bespoke-pdf

PDF generating for Bespoke.js
JavaScript
6
star
40

npm-dependents

Command line tool to view the dependents of a module on npm
JavaScript
5
star
41

react-shallow-renderer

Simple wrapper for react-addons-test-utils createRenderer method.
JavaScript
5
star
42

generator-classes

Generator and AsyncGenerator functions|constructors|classes as a module
JavaScript
5
star
43

aquatap

fullstack TAP with a modern API
JavaScript
5
star
44

hyperpdf

Convert Markdown or HTML into PDF's
JavaScript
5
star
45

hn-latest-stream

hackernews stream of latest stories as JSON or HTML
JavaScript
4
star
46

dr-mark

Generate summary docs from repurposed markdown
CSS
4
star
47

pino-trace

Trace all async operations performantly with pino the fast logger
JavaScript
4
star
48

docs-readability

Visual studio code extension for indicating markdown docs readability
JavaScript
4
star
49

nodux-core

nodux-core
JavaScript
3
star
50

bespoke-to-pdf

Generate a PDF file from your bespoke presentation
JavaScript
3
star
51

seneca-scheduler

Seneca scheduler plugin
JavaScript
3
star
52

bespoke-synchro

Synchronize the slide index of bespoke presentation instances
JavaScript
3
star
53

tunl

Securely proxy remote ports to local ports with SSH.
JavaScript
3
star
54

events.on

polyfill for events.on
JavaScript
2
star
55

unijoin

ESM and CJS support for `path.join` of both file paths and file URLs
JavaScript
2
star
56

lucius

Seneca Microservices in the Browser
JavaScript
2
star
57

necropsy

dissect dead node service core dumps with llnode using a single command
Python
2
star
58

react-resolve-render

awaitable React renderToString for stateful Server Side Rendering
JavaScript
2
star
59

qodaa

Quick and Dirty Async/Await for Node 6
JavaScript
1
star
60

vex

A Schema Validator
JavaScript
1
star
61

xmas-gmar

A christmas card I made for my grandmother
HTML
1
star
62

seneca-couchbase-store

Node.js Seneca data storage plugin for Couchbase
JavaScript
1
star
63

proffer-stream-to-realtime-tree

takes proffer data, returns continually updating d3 trees
JavaScript
1
star
64

proc-cpuinfo

Get /proc/cpuinfo as an object
JavaScript
1
star
65

guard-timeout

Guard against sleep mode timeouts firing on wake
JavaScript
1
star
66

graphql-hooks-workshop

HTML
1
star
67

spacey-standard

like standard, but looser line spacing
JavaScript
1
star
68

prompt-sync-history

History manager for `prompt-sync`
JavaScript
1
star
69

postcss-class-whitelist

Remove any class selector not in a provided whitelist
JavaScript
1
star