diff --git a/spec/state-store-spec.js b/spec/state-store-spec.js index f505cf607..955ceb767 100644 --- a/spec/state-store-spec.js +++ b/spec/state-store-spec.js @@ -1,11 +1,14 @@ /** @babel */ -import {it, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers' +import {it, fit, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers' const StateStore = require('../src/state-store.js') describe("StateStore", () => { + let databaseName = `test-database-${Date.now()}` + let version = 1 + it("can save and load states", () => { - const store = new StateStore() + const store = new StateStore(databaseName, version) return store.save('key', {foo:'bar'}) .then(() => store.load('key')) .then((state) => { @@ -13,9 +16,16 @@ describe("StateStore", () => { }) }) + it("resolves with null when a non-existent key is loaded", () => { + const store = new StateStore(databaseName, version) + return store.load('no-such-key').then((value) => { + expect(value).toBeNull() + }) + }); + describe("when there is an error reading from the database", () => { it("rejects the promise returned by load", () => { - const store = new StateStore() + const store = new StateStore(databaseName, version) const fakeErrorEvent = {target: {errorCode: "Something bad happened"}} diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 141c1c112..c02ac59c7 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -127,7 +127,7 @@ class AtomEnvironment extends Model @emitter = new Emitter @disposables = new CompositeDisposable - @stateStore = new StateStore + @stateStore = new StateStore('AtomEnvironments', 1) @deserializers = new DeserializerManager(this) @deserializeTimings = {} diff --git a/src/state-store.js b/src/state-store.js index f07560038..817d4282f 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -2,28 +2,33 @@ module.exports = class StateStore { - constructor () { - this.dbPromise = new Promise((resolve, reject) => { - let dbOpenRequest = indexedDB.open('AtomEnvironments', 1) + constructor (databaseName, version) { + this.dbPromise = new Promise((resolve) => { + let dbOpenRequest = indexedDB.open(databaseName, version) dbOpenRequest.onupgradeneeded = (event) => { let db = event.target.result db.createObjectStore('states') - resolve(db) } dbOpenRequest.onsuccess = () => { resolve(dbOpenRequest.result) } - dbOpenRequest.onerror = reject + dbOpenRequest.onerror = (error) => { + console.error("Could not connect to indexedDB", error) + resolve(null) + } }) } save (key, value) { return this.dbPromise.then(db => { - value.storedAt = new Date().toString() + if (!db) { + return + } + return new Promise((resolve, reject) => { var request = db.transaction(['states'], 'readwrite') .objectStore('states') - .put(value, key) + .put({value: value, storedAt: new Date().toString()}, key) request.onsuccess = resolve request.onerror = reject @@ -33,12 +38,20 @@ class StateStore { load (key) { return this.dbPromise.then(db => { + if (!db) { + return null + } + return new Promise((resolve, reject) => { var request = db.transaction(['states']) .objectStore('states') .get(key) - request.onsuccess = (event) => resolve(event.target.result) + request.onsuccess = (event) => { + let result = event.target.result + resolve(result ? result.value : null) + } + request.onerror = (event) => reject(event) }) })