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

@airportyh/jsonr

v1.1.6

Published

JSONR is the JSON serialization language plus refs.

Downloads

50

Readme

JSONR - JSON with Refs

JSONR is the JSON serialization language plus refs.

"What is refs?" You might ask.

A ref allows the same object to be referenced multiple times within a file, so that referential equality will be preserved by the serialization. The syntax of refs follow the refs feature in YAML.

Install

npm install @airportyh/jsonr

Example

Let's say you want to model a family of people and the relationships between them.

const dad = { name: "Toby" };
const mom = { name: "Wendy" };
dad.spouse = mom;
mom.spouse = dad;

const marty = { name: "Marty" };
const linus = { name: "Linus" };
const emma = { name: "Emma" };

const children = [
    marty, linus, emma
];

dad.children = children;
mom.children = children;

for (let child of children) {
    child.father = dad;
    child.mother = mom;
}

marty.siblings = [linus, emma];
linus.siblings = [marty, emma];
emma.siblings = [linus, marty];

const family = {
    mom, dad, marty, linus, emma
};

You shall note that if you traverse the object graph starting at the variable family, you will encounter the same objects multiple times. For example, marty can be reached by any of the following: family.marty, family.dad.children[0], family.linus.siblings[0].

If we try to serialize this object graph using JSON.stringify(family), you'll get a

TypeError: Converting circular structure to JSON

But if you do it with JSONR:

const jsonr = require("@airportyh/jsonr");
console.log(jsonr.stringify(family, "  "));

You get (output):

{
  "mom": &1 {
    "name": "Wendy",
    "spouse": &2 {
      "name": "Toby",
      "spouse": *1,
      "children": &3 [
        &4 {
          "name": "Marty",
          "father": *2,
          "mother": *1,
          "siblings": [
            &5 {
              "name": "Linus",
              "father": *2,
              "mother": *1,
              "siblings": [
                *4,
                &6 {
                  "name": "Emma",
                  "father": *2,
                  "mother": *1,
                  "siblings": [
                    *5,
                    *4
                  ]
                }
              ]
            },
            *6
          ]
        },
        *5,
        *6
      ]
    },
    "children": *3
  },
  "dad": *2,
  "marty": *4,
  "linus": *5,
  "emma": *6
}

The &<NUMBER> tag (ex. &1) defines the ref ID of an object or array which follows that tag. The *<NUMBER> syntax (ex. *1) refers the the object that was defined with the given ref ID.

In this JSONR output, dad was given the ref ID of 2, mom was given 1, marty was given 4, linus 5, and emma 6. The children array which was shared by mom and dad was given the ref ID of 3.

Another benefit of refs, other than allowing the serialization of objects graphs with circular references, is the saving of file size when there exists shared references. One application of this concept is the serialization of immutable data structures which make heavy use of structural sharing.

API

JSONR, like JSON has 2 API methods:

  • parse(jsonrString) - takes a JSONR string, and returns a JavaScript data structure
  • stringify(data, indent) - takes a JavaScript data structure, a string representing indentation amount such as a tab or 2 spaces, and returns a string in JSONR format.

Todo

  • load tests
  • learn about the Lempel-Ziv-Welch algorithm and maybe use it instead
  • add refs for strings?
  • maybe rewrite _stringify
  • publish to npm (done)
  • clean up code (done)
  • add data deserialization to parser (done)
  • Investigate weird performance bug (done)
  • implement ref feature to parser (done)
  • add serializer(done)
  • fix bug with family round trip (done)
  • top level jsonr.js file (done)
  • documentation (done)
  • use family as example (done)
  • fix the family round trip props getting re-ordered (done)