Skip to content

Commit

Permalink
Updating readme, version, and dist.
Browse files Browse the repository at this point in the history
  • Loading branch information
jakearchibald committed Mar 21, 2018
1 parent 7b0f18e commit 3edd130
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 172 deletions.
50 changes: 36 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

This is a super-simple-small promise-based keyval store implemented with IndexedDB, largely based on [async-storage by Mozilla](https://github.com/mozilla-b2g/gaia/blob/master/shared/js/async_storage.js).

[localForage](https://github.com/localForage/localForage) offers similar functionality, but supports older browsers with broken/absent IDB implementations. Because of that, it's 6k, whereas idb-keyval is less than 500 bytes. Pick whichever works best for you!
[localForage](https://github.com/localForage/localForage) offers similar functionality, but supports older browsers with broken/absent IDB implementations. Because of that, it's 7.4k, whereas idb-keyval is ~550 bytes. Also, it's tree-shaking friendly, so you'll probably end up using few than Pick whichever works best for you!

This is only a keyval store. If you need to do more complex things like iteration & indexing, check out [IDB on NPM](https://www.npmjs.com/package/idb) (a little heavier at 1.7k). The first example in its README is how to recreate this library.

Expand All @@ -14,53 +14,76 @@ This is only a keyval store. If you need to do more complex things like iteratio
### set:

```js
idbKeyval.set('hello', 'world');
idbKeyval.set('foo', 'bar');
import { set } from 'idb-keyval';

set('hello', 'world');
set('foo', 'bar');
```

Since this is IDB-backed, you can store anything structured-clonable (numbers, arrays, objects, dates, blobs etc).

All methods return promises:

```js
idbKeyval.set('hello', 'world')
import { set } from 'idb-keyval';

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

### get:

```js
import { get } from 'idb-keyval';

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

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

### keys:

```js
import { keys } from 'idb-keyval';

// logs: ["hello", "foo"]
idbKeyval.keys().then(keys => console.log(keys));
keys().then(keys => console.log(keys));
```

### delete:
### del:

```js
idbKeyval.delete('hello');
import { del } from 'idb-keyval';

del('hello');
```

### clear:

```js
idbKeyval.clear();
import { clear } from 'idb-keyval';

clear();
```

### Custom stores:

By default, the methods above use an IndexedDB database named `keyval-store` and an object store named `keyval`. You can create your own store, and pass it as an additional parameter to any of the above methods:

```js
import { Store, set } from 'idb-keyval';

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

That's it!

## Installing

### Via npm
### Via npm + webpack/rollup

```sh
npm install idb-keyval
Expand All @@ -69,11 +92,10 @@ npm install idb-keyval
Now you can require/import `idb-keyval`:

```js
const idbKeyval = require('idb-keyval');
import { get, set } from 'idb-keyval';
```

### Via `<script>`

`idb-keyval.js` is a valid JS module.

`dist/idb-keyval.iffe.js` can be used in browsers that don't support modules. `idbKeyval` is created as a global.
* `dist/idb-keyval.mjs` is a valid JS module.
* `dist/idb-keyval-iife.js` can be used in browsers that don't support modules. `idbKeyval` is created as a global.
145 changes: 68 additions & 77 deletions dist/idb-keyval-cjs.js
Original file line number Diff line number Diff line change
@@ -1,82 +1,73 @@
'use strict';

var db;
Object.defineProperty(exports, '__esModule', { value: true });

function getDB() {
if (!db) {
db = new Promise(function(resolve, reject) {
var openreq = indexedDB.open('keyval-store', 1);

openreq.onerror = function() {
reject(openreq.error);
};

openreq.onupgradeneeded = function() {
// First time setup: create an empty object store
openreq.result.createObjectStore('keyval');
};

openreq.onsuccess = function() {
resolve(openreq.result);
};
});
}
return db;
class Store {
constructor(dbName = 'keyval-store', storeName = 'keyval') {
this.storeName = storeName;
this._dbp = new Promise((resolve, reject) => {
const openreq = indexedDB.open(dbName, 1);
openreq.onerror = () => reject(openreq.error);
openreq.onsuccess = () => resolve(openreq.result);
// First time setup: create an empty object store
openreq.onupgradeneeded = () => {
openreq.result.createObjectStore(storeName);
};
});
}
_withIDBStore(type, callback) {
return this._dbp.then(db => new Promise((resolve, reject) => {
const transaction = db.transaction(this.storeName, type);
transaction.oncomplete = () => resolve();
transaction.onabort = transaction.onerror = () => reject(transaction.error);
callback(transaction.objectStore(this.storeName));
}));
}
}
let store;
function getDefaultStore() {
if (!store)
store = new Store();
return store;
}
function get(key, store = getDefaultStore()) {
let req;
return store._withIDBStore('readonly', store => {
req = store.get(key);
}).then(() => req.result);
}
function set(key, value, store = getDefaultStore()) {
return store._withIDBStore('readwrite', store => {
store.put(value, key);
});
}
function del(key, store = getDefaultStore()) {
return store._withIDBStore('readwrite', store => {
store.delete(key);
});
}
function clear(store = getDefaultStore()) {
return store._withIDBStore('readwrite', store => {
store.clear();
});
}
function keys(store = getDefaultStore()) {
const keys = [];
return store._withIDBStore('readonly', store => {
// This would be store.getAllKeys(), but it isn't supported by Edge or Safari.
// And openKeyCursor isn't supported by Safari.
(store.openKeyCursor || store.openCursor).call(store).onsuccess = function () {
if (!this.result)
return;
keys.push(this.result.key);
this.result.continue();
};
}).then(() => keys);
}

function withStore(type, callback) {
return getDB().then(function(db) {
return new Promise(function(resolve, reject) {
var transaction = db.transaction('keyval', type);
transaction.oncomplete = function() {
resolve();
};
transaction.onerror = function() {
reject(transaction.error);
};
callback(transaction.objectStore('keyval'));
});
});
}

var idbKeyval = {
get: function(key) {
var req;
return withStore('readonly', function(store) {
req = store.get(key);
}).then(function() {
return req.result;
});
},
set: function(key, value) {
return withStore('readwrite', function(store) {
store.put(value, key);
});
},
delete: function(key) {
return withStore('readwrite', function(store) {
store.delete(key);
});
},
clear: function() {
return withStore('readwrite', function(store) {
store.clear();
});
},
keys: function() {
var keys = [];
return withStore('readonly', function(store) {
// This would be store.getAllKeys(), but it isn't supported by Edge or Safari.
// And openKeyCursor isn't supported by Safari.
(store.openKeyCursor || store.openCursor).call(store).onsuccess = function() {
if (!this.result) return;
keys.push(this.result.key);
this.result.continue();
};
}).then(function() {
return keys;
});
}
};

module.exports = idbKeyval;
exports.Store = Store;
exports.get = get;
exports.set = set;
exports.del = del;
exports.clear = clear;
exports.keys = keys;
Loading

0 comments on commit 3edd130

Please sign in to comment.