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

dead-easy-json

v2.0.3

Published

Dead-easy JSON serialization for JavaScript. Bidirectional object synchronizaiton with async support

Downloads

24

Readme

JSON is easy

“Dead-easy JSON serialization for JavaScript. Bidirectional object synchronization with async support„

ci badge Coverage Status Dev badge

NPM

Showcase

GIF

v2 should be the latest drastic change. v2 is not compatible with v1

Quickstart

const myFile = require(`dead-easy-json`)(`./myJson.json`).file;
// // myFile = {} This is implied. You can override this behavior
// myFile.a.b = 3; // ERROR; because a is undefined
myFile.a = {};  // Ok; written to file system SYNCHRONOUSLY by default
myFile.a.b = 3; // Ok; written to file system SYNCHRONOUSLY by default
/*
The json file will look like this
{
 a: {
  b: 3
 }
}
*/
console.log(myFile.a.b); // 3
console.log(myFile.a.c); // undefined
// console.log(myFile.d.e); // ERROR

A more controlled example

const JSONrequire = require(`dead-easy-json`);
const handler = JSONrequire(`${__dirname}/myJson.json`, 
  {} //The default object. Can be set to {"ur property":{"values":[]}} or [1,{2:3}] for example.
  , {
  writeInterval: 100, // When this value is set, the object tracks changes and writes those changes at once every interval. Don't worry, it doesn't write when there are no changes. Read # writeInterval section for more

  // Options for JSON.stringify
  replacer: null,
  space: 2,

  // Writes the JSON to the variable asynchronously
  // You must call handler.close() to exit properly
  watch: true
});
const { file: myFile } = handler;

handler.watchCallback = () => console.log("detected file change")

myFile.a = [1,2,3];

console.log(myFile.a); // undefined
// This obviously should be inside an async function
await handler.writeAwait; //  type: ignore
console.log(myFile.a); // [1, 2, 3]

// You can also immediately write the file
handler.write();

// and asynchronously write the file as well
await handler.writeAsync();

// Taking a sub-property object is also supported
myFile[1] = {}
const myObj = myFile[1]
myObj.b = 2 // Written in disk

handler.close(); // MUST if watch: true

How writeInterval works

The changes are queued for the next writeInterval ms and then the callback is called. This change listener does not check whether the properties are actually the same e.g) setting a.b = 3 and then setting it to a.b = 3. Even though they are two same values, the file will still be written

Specifications

All the properties of the main file proxy is a proxy itself as well

const { file } = require(`dead-easy-json`)(`data.json`);
file.property = {} // Written in disk
const prop = file.property;
prop.a = 42 // Also written in disk

// This is a no brainer but rewriting the property itself doesn't work
let prop = file.property;
prop = 3 // This just sets prop to a new reference

When saving the json file, all references are PRESERVED

const prop = file.property
setTimeout(() => {
  console.log(prop.a) // prints 42; reference is PRESERVED
}, 10000)
// Save the file to be
/*
{
  "property": { "a": 42 }
}
*/

When saving the json file, type {} should be matched with type {} and [] with []


file.property = {}
// Save the file to be
/*
{
  "property": []
}
*/
// ^ ERROR because the reference preservation system forbids this
// Also I do NOT see any reason for anyone to use [] and {} interchangably

// Doing
file.property = [] 
// In the code however, is allowed

Some gatchas

  • Default objs can be nested, but they are written in sync regardless of writeInterval.

  • Even if there is a writeInterval the variable is immediately accessible. Its just written in memory before disk

  • The reader will rewrite the file when initially loaded if it is a blank file ex) "". If it is a blank, the file be defaultObj or {} apon constructing the proxy. This is done SYNCHRONOUSLY

  • Setting the .file to a new object will invoke another proxy. This will ALWAYS rewrite the file synchronously (note: this was an elaborate design choice ) (must be like myObj.file = {} not file = {} <- this will not invoke the new proxy)

  • Watch writes to the json variable. This will not reset the write timer

  • Because the reference is preserved, myArray[3] for example will point to the [3] when the file changes. If you do not want this behavior, do something like const val = myArray[3] then only use val.

  • Object assignments will give you a proxy on nested objects. This might be confusing

const handler = require(`dead-easy-json`)(`./file.json`, {});
const file = handler.file;

let obj = {
 prop:[],
};
file.test = obj;
// obj.prop = [1,2]; // doesn't work
obj.prop.push(42); // works

obj = file.test;
obj.prop = 42; // works
obj.someattr = `hi`; // works

Donations

If this project helped you save time developing prototypes, consider donating 😄