diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 74049d94d..f6fa03932 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -813,12 +813,17 @@ class AtomEnvironment extends Model saveState: -> return Promise.resolve() unless @enablePersistence - state = @serialize() - if storageKey = @getStateKey(@project?.getPaths()) - @stateStore.save(storageKey, state) - else - @applicationDelegate.setTemporaryWindowState(state) + new Promise (resolve, reject) => + window.requestIdleCallback => + state = @serialize() + savePromise = + if storageKey = @getStateKey(@project?.getPaths()) + @stateStore.save(storageKey, state) + else + @applicationDelegate.setTemporaryWindowState(state) + savePromise.catch(reject).then(resolve) + loadState: -> if @enablePersistence diff --git a/src/state-store.js b/src/state-store.js index 53998d802..13c9a0462 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -24,18 +24,19 @@ class StateStore { } save (key, value) { + // Serialize values using JSON.stringify, as it seems way faster than IndexedDB structured clone. + // (Ref.: https://bugs.chromium.org/p/chromium/issues/detail?id=536620) + let jsonValue = JSON.stringify(value) return new Promise((resolve, reject) => { - window.requestIdleCallback(deadline => { - this.dbPromise.then(db => { - if (db == null) resolve() + this.dbPromise.then(db => { + if (db == null) resolve() - var request = db.transaction(['states'], 'readwrite') - .objectStore('states') - .put({value: value, storedAt: new Date().toString()}, key) + var request = db.transaction(['states'], 'readwrite') + .objectStore('states') + .put({value: jsonValue, storedAt: new Date().toString(), isJSON: true}, key) - request.onsuccess = resolve - request.onerror = reject - }) + request.onsuccess = resolve + request.onerror = reject }) }) } @@ -51,7 +52,12 @@ class StateStore { request.onsuccess = (event) => { let result = event.target.result - resolve(result ? result.value : null) + if (result) { + // TODO: remove this when state will be serialized only via JSON. + resolve(result.isJSON ? JSON.parse(result.value) : result.value) + } else { + resolve(null) + } } request.onerror = (event) => reject(event)