blob: 09f6fabe52f5468f94b959f6f3a9e180678e1744 [file]
// Copyright 2012 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import {lib} from './lib.js';
/**
* Helper to retry operations when exceeding write quota.
*
* @param {function(): !Promise<void>} callback The operation to (re)try.
* @param {number=} delay How long (in msec) to sleep after quota error.
*/
async function retryQuotaErrors(callback, delay = 1000) {
while (1) {
try {
await callback();
break;
} catch (e) {
// Doesn't seem to be any better way of handling this.
// https://crbug.com/764759
if (e.message.indexOf('MAX_WRITE_OPERATIONS')) {
console.warn(`Will retry write after exceeding quota:`, e);
await new Promise((resolve) => setTimeout(resolve, delay));
} else {
throw e;
}
}
}
}
/**
* chrome.storage based class with an async interface that is interchangeable
* with other lib.Storage.* implementations.
*/
lib.Storage.Chrome = class extends lib.Storage {
/**
* @param {!StorageArea} storage The backing storage.
*/
constructor(storage) {
super();
this.storage_ = storage;
this.quotaRetryDelay_ = 1000;
storage.onChanged.addListener(this.onChanged_.bind(this));
}
/**
* Called by the storage implementation when the storage is modified.
*
* @param {!Object<string, !StorageChange>} changes Object mapping each key
* that changed to its corresponding StorageChange for that item.
*/
onChanged_(changes) {
this.observers_.forEach((o) => o(changes));
}
/**
* @return {!Promise<void>}
* @override
*/
async clear() {
return this.storage_.clear();
}
/**
* @param {?Array<string>} keys
* @return {!Promise<!Object<string, *>>}
* @override
*/
async getItems(keys) {
return this.storage_.get(keys);
}
/**
* @param {string} key
* @param {*} value
* @return {!Promise<void>}
* @override
*/
async setItem(key, value) {
return this.setItems({[key]: value});
}
/**
* @param {!Object} obj
* @return {!Promise<void>}
* @override
*/
async setItems(obj) {
return retryQuotaErrors(
() => this.storage_.set(obj),
this.quotaRetryDelay_);
}
/**
* @param {!Array<string>} keys
* @return {!Promise<void>}
* @override
*/
async removeItems(keys) {
return retryQuotaErrors(
() => this.storage_.remove(keys),
this.quotaRetryDelay_);
}
};