npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

json-stringifier

v0.1.0

Published

Alternative to JSON.stringify() that supports altering the behavior of the stringification process at string level

Downloads

2,286

Readme

json-stringifier npm version Build Status

Alternative to JSON.stringify() that supports altering the behavior of the stringification process at string level.

Rationale

It's common to use objects in immutable fashion. We could optimize the serialization of these objects by caching their JSON representation. However, there's no way to achieve this using built-in JSON.stringify() function: its replacer parameter only allows substituting serialized values, but not resulting strings. stringify() function provided by this library accepts a stringifier parameter that lets us override the stringification of values in the object tree. See Memoization example.

Another use case is when you have a strict schema for some objects inside your object tree. With this library you can use fast-json-stringify for these objects and the regular stringification for the rest.

Installation

$ npm install json-stringifier

Examples

Memoization

Custom stringifier that memoizes JSON representations of objects:

import {stringify} from 'json-stringifier';

const cache = new WeakMap();

function memoizedStringify(value) {
  if (value !== null && typeof value === 'object') {
    if (cache.has(value)) {
      return cache.get(value);
    } else {
      const json = stringify(value, memoizedStringify);

      cache.set(value, json);

      return json;
    }
  }

  return stringify(value, memoizedStringify);
}

let state = {
  obj: {a: 1},
  arr: [1, 2, 3],
};

memoizedStringify(state); // '{"obj":{"a":1},"arr":[1,2,3]}'

state = {
  ...state,
  arr: [4, 5, 6],
};

memoizedStringify(state); // state.obj stringification is bypassed

Handling Circular References

Custom stringifier that handles circular references:

function safeStringify(value, seen) {
  if (value !== null && typeof value === 'object') {
    if (seen && seen.has(value)) {
      return '"<circular>"';
    }

    if (seen == null) {
      seen = new Set();
    }
    seen.add(value);

    const json = stringify(value, child => safeStringify(child, seen));

    seen.delete(value);

    return json;
  }

  return stringify(value);
}

const obj = {};
obj.self = obj;
obj.child = {parent: obj};

safeStringify(obj); // '{"self":"<circular>","child":{"parent":"<circular>"}}'

Support Additional Structures

Custom stringifier that supports Sets and Maps:

function customStringify(value) {
  if (value instanceof Set) {
    return stringify({'@@type': 'Set', values: [...value]}, customStringify);
  }

  if (value instanceof Map) {
    return stringify({'@@type': 'Map', entries: [...value]}, customStringify);
  }

  return stringify(value, customStringify);
}

customStringify({
  set: new Set([1, 2, 3]),
  map: new Map([[1, 'a'], [2, 'b'], [3, 'c']])),
});
// '{"set":{"@@type":"Set","values":[1,2,3]},"map":{"@@type":"Map","entries":[[1,"a"],[2,"b"],[3,"c"]]}}'

API

stringifier(value, stringify = stringifier)

  • value — The value to convert to a JSON string.
  • stringify (optional) — A function that is called to get the JSON string for each property value when value is an object, or each element when value is an array. stringify is called with a single argument — the property value or array element and must return a string or undefined. Note that stringify is not called with the value itself. Defaults to stringifier, which gives recursive stringification.
  • Returns a JSON string representing the given value or undefined if value is undefined, a function or a symbol.

Comparison with JSON.stringify()

stringify(value) behaves mostly the same as JSON.stringify(value) with few exceptions:

  • toJSON() is always called with no arguments.
  • Primitive wrapper types Boolean, Number and String are not supported (yet).