Giter Club home page Giter Club logo

idb-keyval's Introduction

IDB-Keyval

npm

This is a super-simple promise-based keyval store implemented with IndexedDB, originally based on async-storage by Mozilla.

It's small and tree-shakeable. If you only use get/set, the library is ~250 bytes (brotli'd), if you use all methods it's ~450 bytes.

localForage offers similar functionality, but supports older browsers with broken/absent IDB implementations. Because of that, it's orders of magnitude bigger (~7k).

This is only a keyval store. If you need to do more complex things like iteration & indexing, check out IDB on NPM (a little heavier at 1k). The first example in its README is how to create a keyval store.

Installing

Recommended: Via npm + webpack/rollup/parcel/etc

npm install idb-keyval

Now you can require/import idb-keyval:

import { get, set } from 'idb-keyval';

If you're targeting IE10/11, use the compat version, and import a Promise polyfill.

// Import a Promise polyfill
import 'es6-promise/auto';
import { get, set } from 'idb-keyval/dist/esm-compat';

All bundles

  • dist/cjs/index.js CommonJS module.
  • dist/cjs-compat/index.js CommonJS module, transpiled for older browsers.
  • dist/esm/index.js EcmaScript module.
  • dist/esm-compat/index.js EcmaScript module, transpiled for older browsers.
  • dist/iife/index-min.js Minified plain JS, which creates an idbKeyval global containing all methods.
  • dist/iife-compat/index-min.js As above, but transpiled for older browsers.

These built versions are also available on jsDelivr, e.g.:

<script src="https://cdn.jsdelivr.net/npm/idb-keyval@5/dist/iife/index-min.js"></script>
<!-- Or in modern browsers: -->
<script type="module">
  import {
    get,
    set,
  } from 'https://cdn.jsdelivr.net/npm/idb-keyval@5/dist/esm/index.js';
</script>

Usage

set:

import { set } from 'idb-keyval';

set('hello', 'world');

Since this is IDB-backed, you can store anything structured-clonable (numbers, arrays, objects, dates, blobs etc), although old Edge doesn't support null. Keys can be numbers, strings, Dates, (IDB also allows arrays of those values, but IE doesn't support it).

All methods return promises:

import { set } from 'idb-keyval';

set('hello', 'world')
  .then(() => console.log('It worked!'))
  .catch((err) => console.log('It failed!', err));

get:

import { get } from 'idb-keyval';

// logs: "world"
get('hello').then((val) => console.log(val));

If there is no 'hello' key, then val will be undefined.

setMany:

Set many keyval pairs at once. This is faster than calling set multiple times.

import { set, setMany } from 'idb-keyval';

// Instead of:
Promise.all([set(123, 456), set('hello', 'world')])
  .then(() => console.log('It worked!'))
  .catch((err) => console.log('It failed!', err));

// It's faster to do:
setMany([
  [123, 456],
  ['hello', 'world'],
])
  .then(() => console.log('It worked!'))
  .catch((err) => console.log('It failed!', err));

This operation is also atomic โ€“ if one of the pairs can't be added, none will be added.

getMany:

Get many keys at once. This is faster than calling get multiple times. Resolves with an array of values.

import { get, getMany } from 'idb-keyval';

// Instead of:
Promise.all([get(123), get('hello')]).then(([firstVal, secondVal]) =>
  console.log(firstVal, secondVal),
);

// It's faster to do:
getMany([123, 'hello']).then(([firstVal, secondVal]) =>
  console.log(firstVal, secondVal),
);

update:

Transforming a value (eg incrementing a number) using get and set is risky, as both get and set are async and non-atomic:

// Don't do this:
import { get, set } from 'idb-keyval';

get('counter').then((val) =>
  set('counter', (val || 0) + 1);
);

get('counter').then((val) =>
  set('counter', (val || 0) + 1);
);

With the above, both get operations will complete first, each returning undefined, then each set operation will be setting 1. You could fix the above by queuing the second get on the first set, but that isn't always feasible across multiple pieces of code. Instead:

// Instead:
import { update } from 'idb-keyval';

update('counter', (val) => (val || 0) + 1);
update('counter', (val) => (val || 0) + 1);

This will queue the updates automatically, so the first update set the counter to 1, and the second update sets it to 2.

del:

Delete a particular key from the store.

import { del } from 'idb-keyval';

del('hello');

clear:

Clear all values in the store.

import { clear } from 'idb-keyval';

clear();

entries:

Get all entries in the store. Each entry is an array of [key, value].

import { entries } from 'idb-keyval';

// logs: [[123, 456], ['hello', 'world']]
entries().then((entries) => console.log(entries));

keys:

Get all keys in the store.

import { keys } from 'idb-keyval';

// logs: [123, 'hello']
keys().then((keys) => console.log(keys));

values:

Get all values in the store.

import { values } from 'idb-keyval';

// logs: [456, 'world']
values().then((values) => console.log(values));

Custom stores:

By default, the methods above use an IndexedDB database named keyval-store and an object store named keyval. If you want to use something different, see custom stores.

Updating

Updating from 3.x

The changes between 3.x and 5.x related to custom stores.

(4.x was abandoned due to a Safari bug)

Old way:

// This no longer works in 4.x
import { Store, set } from 'idb-keyval';

const customStore = new Store('custom-db-name', 'custom-store-name');
set('foo', 'bar', customStore);

New way:

import { createStore, set } from 'idb-keyval';

const customStore = createStore('custom-db-name', 'custom-store-name');
set('foo', 'bar', customStore);

For more details, see custom stores.

Updating from 2.x

2.x exported an object with methods:

// This no longer works in 3.x
import idbKeyval from 'idb-keyval';

idbKeyval.set('foo', 'bar');

Whereas in 3.x you import the methods directly:

import { set } from 'idb-keyval';

set('foo', 'bar');

This is better for minification, and allows tree shaking.

idb-keyval's People

Contributors

acutmore avatar bennypowers avatar dependabot[bot] avatar diogocorrea avatar forabi avatar hazolsky avatar isidrok avatar jakearchibald avatar josduj avatar lukasdrgon avatar maug avatar odradek71 avatar outdooricon avatar remko avatar sidvishnoi avatar styfle avatar tarjei avatar tisvasconcelos avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.