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

react-idb-cache

v1.4.1

Published

Cache for React

Downloads

15

Readme

action-release codecov

react-idb-cache

This library helps on one of the trickier parts of writing React components: How to render on ansynchronously fetched data and cache such data effectively.

Install

$ yarn add react-idb-cache

Usage

import { useCached } from 'react-idb-cache'

function MyComponent() {
  const { get, set } = useCached()

  // Get value from IndexedDB if it exists - the state will be updated if a value is received
  const value = get('indexKeyForValue')

  // Load a value from an API endpoint if it does not exist in the cache or IndexedDB
  const otherValue = get('indexKeyForOtherValue', () => someRequest().then(({theRequiredValue, someOtherValue}) => {
      // set the value in state and IndexedDB
      set('indexKeyForOtherValue', theRequiredValue, {someMetaField: 123})
  }))

  // The component can render without blocking anything.
  // It will be updated once values are available.
  return <div>
    <div>{value}</div>
    <div>{otherValue}</div>
  </div>
}

Setup

  const api = useCached({dbName: 'my-database', storeName: 'my-store'})

Per default the hook uses a store keyval in database Cached.

Context

The hooks cache values in a shared context. You can isolate some of the components so the cache is removed with the components by wrapping them with a Provider.

  import { CacheProvider, useCached } from 'react-idb-cache'

  function MyWrapperComponent() {
    return <CacheProvider>
      <MyComponentA/>
      <MyComponentB/>
    </CacheProvider>
  }
  function MyComponentA() {
    const api = useCached()
  }
  function MyComponentB() {
    const api = useCached()
  }

You can also make a component use its own local cache:

  const api = useCached({context: false})

DBDriver

This library defaults to use IndexedDB as device level cache per idb-keyval.

You can switch out the driver used for local cache in the context of a CacheProvider.

import { CacheProvider } from 'react-idb-cache'
import NullDB from 'react-idb-cache/driver/NullDB'

function MyWrapperComponent() {
  return <CacheProvider dbDriverFactory={NullDB}>
    <MyComponent/>
  </CacheProvider>
}

Supplying your own driver is possible but considered experimental as the DBDriver API might be subject to change in minor versions. If you'd like to add another local DB implementation, PRs are very much welcome!

Get

Get a single value

  const { get } = useCached()
  get('indexKeyForValue')

In TypeScript you can declare the data type you get:

  const { get } = useCached()
  get<string, 'data', number>('indexKeyForValue') // is expected to be a number

Get multiple values

  const { get } = useCached()
  get(['keyOne', 'keyTwo'])

  // returns a record of key-value pairs
  {
    keyOne: 'foo',
    keyTwo: 'bar',
  }

Load data from the backend

  const { get } = useCached()
  get(['keyOne', 'keyTwo'], myLoader)

  // if the cache/idb has a value for some of the keys, they are returned
  {
    keyOne: 'foo',
    keyTwo: undefined,
  }

The loader is called - for multiple key requests with an array of missing keys - and should return a Promise that should resolve once the transaction is done.

Reload outdated entries

Callback

You can discard entries from cache/idb per expire callback. If a loader is present, it will be called with the missing keys and those keys for which expire returned true.

  const { get } = useCached()
  get('someKey', myLoader, ({data, meta}) => meta.someMetaField > 123)
Age

You can discard entries from cache/idb that are older than expire milliseconds. If a loader is present, it will be called with the missing keys and those keys for which expire returned true.

  const { get } = useCached()
  get('someKey', myLoader, 5000) // discard cached entry if meta.date is older that 5 seconds
}

Get meta data

  const { get } = useCached()
  get('indexKeyForValue', undefined, undefined, 'obj')

  // returns the cached data alongside the meta
  // also includes the result of the validation according to expire parameter
  {
    data: 'foo',
    meta: {
      date: '2021-01-15T18:21:00.152Z',
    },
    valid: true,
  }

Automatic rerender

If a component calls get() for some keys it subscribes to further changes to that entry. When this or any other components alters that entry through one of the writing methods described below, the component automatically rerenders.

Set

Set a single value

  const { set } = useCached()
  set('someKey', 'someValue')

The value can be anything that can be stored into IndexedDB.

You can also store some meta data for the entry.

  const { set } = useCached()
  set('someKey', 'someValue', {someMetaKey: new Date()})

Set multiple values

  const { set } = useCached()
  set({
    keyOne: 'someValue',
    keyTwo: 'otherValue',
  }, {
    keyOne: {
      someMetaKey: 'metaValue',
    },
  })

Unset values

You can also unset values in bulk action.

  const { set } = useCached()
  set({
    keyOne: 'someValue',
    keyTwo: 'whatever',
  }, {
    keyTwo: null, // this will remove the entry for 'keyTwo'
  })

Skip idb

You can set values in the react cache but not in IndexedDB:

  const { set } = useCached()
  set('foo', 'bar', undefined, {skipIdb: true})
  //or
  set({foo: 'bar'}, undefined, {skipIdb: true})

Delete

  const { del } = useCached()
  del('someKey')

Clear

Whole cache and idb-store

  const { clear } = useCached()
  clear()

Filter entries per callback

Deletes some data from cache and IndexedDB.

  const { clear } = useCached()
  clear(({data, meta}) => meta.someMetaField > 2) // this will remove all entries with meta.someMetaField > 2

Entries

You can get all entries cached in context or local DB:

  const { entries } = useCached()
  entries().map([key, data] => {
    // ...
  })

The component will automatically rerender if an entry in the cache is updated/deleted.