From cee3dc6ec5870330c21dbfd845723e188de2edd5 Mon Sep 17 00:00:00 2001 From: Matt Norris Date: Wed, 21 Sep 2016 15:53:30 -0700 Subject: [PATCH] feat(storage-adapter-indexeddb): implement get, put, del implement initial get, put, del functions https://github.com/ciscospark/spark-js-sdk/issues/146 --- packages/storage-adapter-indexeddb/README.md | 62 +++++++++ .../storage-adapter-indexeddb/package.json | 1 + .../storage-adapter-indexeddb/src/index.js | 129 ++++++++++++++++++ 3 files changed, 192 insertions(+) diff --git a/packages/storage-adapter-indexeddb/README.md b/packages/storage-adapter-indexeddb/README.md index 8b137891791..69a989a255c 100644 --- a/packages/storage-adapter-indexeddb/README.md +++ b/packages/storage-adapter-indexeddb/README.md @@ -1 +1,63 @@ +# index +IndexedDB adapter for spark-core storage layer + +# constructor + +**Parameters** + +- `basekey` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** localforage key under which + all namespaces will be stored + +# bind + +Returns an adapter bound to the specified namespace + +**Parameters** + +- `namespace` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** + +Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<[Bound](#bound)>** + +# Bound + +localforage binding + +## constructor + +**Parameters** + +- `namespace` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `options` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** + +## del + +Removes the specified key + +**Parameters** + +- `key` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** + +Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** + +## get + +Retrieves the data at the specified key + +**Parameters** + +- `key` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** + +Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<mixed>** + +## put + +Stores the specified value at the specified key + +**Parameters** + +- `key` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `value` **mixed** + +Returns **[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)** diff --git a/packages/storage-adapter-indexeddb/package.json b/packages/storage-adapter-indexeddb/package.json index 6b2d085d5cb..abc0e62c211 100644 --- a/packages/storage-adapter-indexeddb/package.json +++ b/packages/storage-adapter-indexeddb/package.json @@ -11,6 +11,7 @@ "@ciscospark/common": "^0.7.0-alpha", "@ciscospark/spark-core": "^0.7.0-alpha", "babel-runtime": "^6.3.19", + "localforage": "^1.4.2", "lodash": "^4.5.1" }, "devDependencies": { diff --git a/packages/storage-adapter-indexeddb/src/index.js b/packages/storage-adapter-indexeddb/src/index.js index fe2fd4096ed..3bea5699b54 100644 --- a/packages/storage-adapter-indexeddb/src/index.js +++ b/packages/storage-adapter-indexeddb/src/index.js @@ -3,3 +3,132 @@ * Copyright (c) 2015-2016 Cisco Systems, Inc. See LICENSE file. * @private */ + + /* eslint-env browser */ + +import localforage from 'localforage'; + +import {NotFoundError} from '@ciscospark/spark-core'; + +const namespaces = new WeakMap(); +const loggers = new WeakMap(); + +/** +* IndexedDB adapter for spark-core storage layer +*/ +export default class StorageAdapterIndexedDB { + /** + * @constructs {StorageAdapterIndexedDB} + * @param {string} basekey localforage key under which + * all namespaces will be stored + */ + constructor(basekey) { + /** + * localforage binding + */ + this.Bound = class { + /** + * @constructs {Bound} + * @param {string} namespace + * @param {Object} options + */ + constructor(namespace, options) { + namespaces.set(this, namespace); + loggers.set(this, options.logger); + } + + /** + * @private + * @returns {mixed} + */ + _load() { + const rawData = localforage.getItem(basekey); + const allData = rawData ? JSON.parse(rawData) : {}; + return allData[namespaces.get(this)] || {}; + } + + /** + * @param {Object} data + * @private + * @returns {undefined} + */ + _save(data) { + const rawData = localforage.getItem(basekey); + const allData = rawData ? JSON.parse(rawData) : {}; + allData[namespaces.get(this)] = data; + + localforage.setItem(basekey, JSON.stringify(allData)); + } + + /** + * Removes the specified key + * @param {string} key + * @returns {Promise} + */ + del(key) { + return new Promise((resolve) => { + loggers.get(this).info(`indexeddb-store-adapter: deleting \`${key}\``); + const data = this._load(); + Reflect.deleteProperty(data, key); + this._save(data); + resolve(); + }); + } + + /** + * Retrieves the data at the specified key + * @param {string} key + * @returns {Promise} + */ + get(key) { + return new Promise((resolve, reject) => { + loggers.get(this).info(`indexeddb-store-adapter: reading \`${key}\``); + const data = this._load(); + const value = data[key]; + if (value) { + return resolve(value); + } + + return reject(new NotFoundError(`No value found for ${key}`)); + }); + } + + /** + * Stores the specified value at the specified key + * @param {string} key + * @param {mixed} value + * @returns {Promise} + */ + put(key, value) { + return new Promise((resolve) => { + loggers.get(this).info(`indexeddb-store-adapter: writing \`${key}\``); + const data = this._load(); + data[key] = value; + this._save(data); + resolve(); + }); + } + }; + } + + /** + * Returns an adapter bound to the specified namespace + * @param {string} namespace + * @param {Object} options + * @returns {Promise} + */ + bind(namespace, options) { + options = options || {}; + if (!namespace) { + return Promise.reject(new Error(`\`namespace\` is required`)); + } + + if (!options.logger) { + return Promise.reject(new Error(`\`options.logger\` is required`)); + } + + options.logger.info(`local-storage-indexeddb: returning binding`); + + return Promise.resolve(new this.Bound(namespace, options)); + } +}