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

with-cache-normalization

v1.0.3

Published

🗜️ normalize your cache -> get automatic cache updates ✨

Downloads

51

Readme

with-cache-normalization

🗜️ normalize your cache -> get automatic cache updates ✨

install

npm install with-cache-normalization

use

lets say you're starting with a cache that stores references to ships

without normalization, it will operate something like this

const value = {
  ships: [
    new Ship({ id: 1, name: 'boaty mcboatface' }),
    new Ship({ id: 2, name: 'sea biscuit' }),
    new Ship({ id: 1, name: 'boaty mcboatface' })
  ],
};
cache.set('__key__', value);
expect(cache.get('__key__')).toEqual(value) // true, like we would expect

and the cache store would now contain something like this

{
  '__key__': {
    ships: [
      new Ship({ id: 1, name: 'boaty mcboatface' }),
      new Ship({ id: 2, name: 'sea biscuit' }),
      new Ship({ id: 1, name: 'boaty mcboatface' }
    ]
  }
}

🗜️ add normalization to a cache

we can leverage normalization to reference those ships via foreign key, like in a relational database

with normalization, it will operate like this

import { withNormalization, normalizeDomainObjectReferences } from 'with-cache-normalization';

const value = {
  ships: [
    new Ship({ id: 1, name: 'boaty mcboatface' }),
    new Ship({ id: 2, name: 'sea biscuit' }),
    new Ship({ id: 1, name: 'boaty mcboatface' })
  ],
};
const cacheWithNormalization = withNormalization(
  cache,
  {
    normalize: normalizeDomainObjectReferences,
  }
)
cacheWithNormalization.set('__key__', value);
expect(cacheWithNormalization.get('__key__')).toEqual(value) // still true, as the .get automatically denormalizes the results

and the cache store would now contain something like this

 {
   '__key__': {
     ships: [
       '.cache.ref.Ship.1',
       '.cache.ref.Ship.2',
       '.cache.ref.Ship.1',
     ]
   },
  '.cache.ref.Ship.1}': new Ship({ id: 1, name: 'boaty mcboatface' ),
  '.cache.ref.Ship.2}': new Ship({ id: 2, name: 'sea biscuit' )
 }

this provides the following advantages

  • 🗜️ smaller cache size: when the same entities are referenced more than once, only the reference is duplicated
  • ✨ automatic cache updates: when any cache.set updates the same referenced entity, all will dereference the latest value

note: the normalizeDomainObjectReferences method comes out of the box with this library, since domain-object normalization is a common usecase

🎈 add only denormalization to a cache

you may find a scenario where you want to denormalize values from a cache that you are not writing to (e.g., with-cache-normalization)

in this scenario, you likely wont have access to the method used to normalize the values

not a problem, you can denormalize entries in the cache without needing to know this method

for example, lets say you're accessing the same cache state as with the normalized ships from above

const cacheWithDenormalization = withNormalization(cache)
cacheWithDenormalization.get('__key__');

the above would return the fully hydrated, denormalized value

{
  ships: [
    new Ship({ id: 1, name: 'boaty mcboatface' }),
    new Ship({ id: 2, name: 'sea biscuit' }),
    new Ship({ id: 1, name: 'boaty mcboatface' })
  ],
};

🌀 add serialization to a string only cache

a common situation you may find yourself in is attempting to add normalization to a cache which only accepts strings

since normalization requires object input in order to recursively traverse the data you're attempting to cache, it can't operate directly on a cache that only accepts strings

to solve for this, simply add serialization to the cache with the withSerialization utility

for example

const ship = new Ship({ id: 3, name: 'nacho boat' })

// lets say your original cache only accepts strings
cache.set('__key__', ship) // 🚫 type error

// easily add serialization
const cacheWithSerialization = withSerialization(cache) // defaults to JSON.stringify + JSON.parse

// now, you can write any data to this cache
cacheWithSerialization.set('__key__', ship) // ✅ serialized when setting

// and, when you read it, it will be deserialized
const cached = cacheWithSerialization.get('__key__')
expect(cached).toEqual(ship) // ✅ deserialized when getting