JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • 0
  • Score
    100M100P100Q61098F
  • License MIT

IndexedDb-backed cache for react application

Package Exports

  • @vlsergey/react-indexdb-cache
  • @vlsergey/react-indexdb-cache/lib/cjs/index.js
  • @vlsergey/react-indexdb-cache/lib/esm/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@vlsergey/react-indexdb-cache) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

react-indexdb-cache

Flexible indexeddb-backed cache for react application

  • Uses IndexedDb to store cached data, thus it can be used even if user reloads page or reopen browser window.
  • Tries to reduce number of component render calls as much as possible. For example changing key order in arguments from ['first', 'second'] to ['second', 'first'] will return same Record<string,...> object instance. Thus it's safe to use cache result as useMemo or React.memo argument.

NPM version Build Status Downloads

Usage

Cache definition

Create new file and define loader, cache instance and access helpers (hooks and components):

import {cacheValueProviderFactory, cacheValuesProviderFactory, CacheWithIndexedDb,
  cacheValueHookFactory, cacheValuesHookFactory} from '@vlsergey/react-indexdb-cache';

type Key = string;
type Value = number;

async function loader(key : Key) : Promise<Value | undefined> {
  // place actual key to value resolving here
  return 42;
}

export const cache = new CacheWithIndexedDb<string, number, number>({
  loader,
  databaseName: 'testDatabase', // name of IndexedDb database name
});

export const CacheValueProvider = cacheValueProviderFactory(testCache, true);
export const CacheValuesProvider = cacheValuesProviderFactory(testCache);
export const useCacheValue = cacheValueHookFactory(propertiesDataCache);
export const useCacheValues = cacheValuesHookFactory(propertiesDataCache);

export default cache

It is advised to use batching function (like one from @vlsergey/batcher) to group multiple async calls into batches.

import Batcher from '@vlsergey/batcher';

async function batchLoader(keys : Key[]) : Promise<(Value | undefined)[]> {
  // place actual key to value resolving here
  return keys.map( key => 42 );
}

const batcher = new Batcher<string, number>(batchLoader, {
  maxBatchSize: 50
});

export const cache = new CacheWithIndexedDb<string, number, number>({
  loader: key => batcher.queue(key),
  databaseName: 'testDatabase', // name of IndexedDb database name
});

Cache usage

Use cache values in functional of class components.

import {CacheValueProvider, CacheValuesProvider, useCacheValue, useCacheValues} from "./myCache.ts"
interface MyComponentProps {
  entityId?: string
}

function MyComponent({
  entityId
} : MyComponentProps) => {
  const valueFromCache : number | undefined = useCacheValue( entityId );
  return valueFromCache ? <span>{valueFromCache}</span> : <span>Loading...</span>
}
interface MyComponentProps {
  entityId?: string
}

function MyComponent({
  entityId
} : MyComponentProps) => <CacheValueProvider cacheKey={entityId}>{ (valueFromCache : number | undefined) =>
  valueFromCache ? <span>{valueFromCache}</span> : <span>Loading...</span>
}</CacheValueProvider>
interface MyComponentProps {
  entityIds: readonly string[]
}

function MyComponent({
  entityIds
} : MyComponentProps) => {
  const valuesFromCache : Record<string, number> = useCacheValues( entityIds );
  return JSON.stringify(valuesFromCache)
}
interface MyComponentProps {
  entityIds: readonly string[]
}

function MyComponent({
  entityIds
} : MyComponentProps) => <CacheValuesProvider cacheKeys={entityIds}>{ (valuesFromCache : Record<string, number>) =>
  valueFromCache ? <span>{valueFromCache}</span> : <span>Loading...</span>
}</CacheValuesProvider>