@browser-storage/core
Version:
417 lines (327 loc) • 10 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
(function (BrowserStorageEventTypes) {
BrowserStorageEventTypes[BrowserStorageEventTypes["Default"] = 0] = "Default";
BrowserStorageEventTypes[BrowserStorageEventTypes["SetItem"] = 1] = "SetItem";
BrowserStorageEventTypes[BrowserStorageEventTypes["RemoveItem"] = 2] = "RemoveItem";
BrowserStorageEventTypes[BrowserStorageEventTypes["Clear"] = 3] = "Clear";
})(exports.BrowserStorageEventTypes || (exports.BrowserStorageEventTypes = {}));
function getEventFromJSON(json) {
switch (json.type) {
case exports.BrowserStorageEventTypes.Clear:
return new ClearBrowserStorageEvent(json);
case exports.BrowserStorageEventTypes.SetItem:
return new SetItemBrowserStorageEvent(json);
case exports.BrowserStorageEventTypes.RemoveItem:
return new RemoveItemBrowserStorageEvent(json);
default:
return new BrowserStorageEvent(json);
}
}
class BrowserStorageEvent {
constructor({
name,
storeName,
version,
key,
oldValue,
newValue,
isCrossTab = false
}) {
this.type = exports.BrowserStorageEventTypes.Default;
this.name = name;
this.storeName = storeName;
this.version = version;
this.key = key;
this.oldValue = oldValue;
this.newValue = newValue;
this.isCrossTab = isCrossTab;
}
static deserialize(event) {
const json = JSON.parse(event);
return getEventFromJSON(json);
}
static serialize(event) {
return JSON.stringify(event);
}
copyWith({
name = this.name,
storeName = this.storeName,
version = this.version,
key = this.key,
oldValue = this.oldValue,
newValue = this.newValue,
isCrossTab = this.isCrossTab
}) {
return getEventFromJSON({
type: this.type,
name,
storeName,
version,
key,
oldValue,
newValue,
isCrossTab
});
}
}
class SetItemBrowserStorageEvent extends BrowserStorageEvent {
constructor() {
super(...arguments);
this.type = exports.BrowserStorageEventTypes.SetItem;
}
}
class RemoveItemBrowserStorageEvent extends BrowserStorageEvent {
constructor() {
super(...arguments);
this.type = exports.BrowserStorageEventTypes.RemoveItem;
}
}
class ClearBrowserStorageEvent extends BrowserStorageEvent {
constructor() {
super(...arguments);
this.type = exports.BrowserStorageEventTypes.Clear;
}
}
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function () {
var self = this,
args = arguments;
return new Promise(function (resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
var __decorate = undefined && undefined.__decorate || function (decorators, target, key, desc) {
var c = arguments.length,
r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc,
d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
function whenReady(target, propertyKey, descriptor) {
const original = descriptor.value;
descriptor.value =
/*#__PURE__*/
function () {
var _value = _asyncToGenerator(function* (...args) {
yield this.ready();
return original.apply(this, args);
});
function value() {
return _value.apply(this, arguments);
}
return value;
}();
}
const EVENT_KEY = '__browser_storage_event_';
class BrowserStorage {
constructor(options) {
this._handlerStore = new Set();
this._storageChange = evt => {
if (evt.key !== EVENT_KEY) {
return;
}
const serializeEvent = localStorage.getItem(EVENT_KEY);
const event = BrowserStorageEvent.deserialize(serializeEvent);
if (event.name !== this.options.name || event.storeName !== this.options.storeName) {
return;
}
this._applyHandlers(event);
};
this._driver = (Array.isArray(options.drivers) ? options.drivers : [options.drivers]).find(driver => driver.isSupported);
this.options = Object.assign({}, options);
delete this.options.drivers;
this.init(options);
}
get isSupported() {
return !!this._driver && this._driver.isSupported;
}
ready() {
var _this = this;
return _asyncToGenerator(function* () {
return !!_this._driver && _this._driver.isSupported && _this._driver.ready();
})();
}
clear() {
var _this2 = this;
return _asyncToGenerator(function* () {
yield _this2._driver.clear();
const event = new ClearBrowserStorageEvent({
name: _this2.options.name,
storeName: _this2.options.storeName,
version: _this2.options.version,
key: null,
oldValue: null,
newValue: null
});
_this2._triggerEvent(event);
})();
}
getItem(key) {
var _this3 = this;
return _asyncToGenerator(function* () {
return _this3._driver.getItem(key);
})();
}
iterate(iterator) {
var _this4 = this;
return _asyncToGenerator(function* () {
return _this4._driver.iterate(iterator);
})();
}
key(index) {
var _this5 = this;
return _asyncToGenerator(function* () {
return _this5._driver.key(index);
})();
}
keys() {
var _this6 = this;
return _asyncToGenerator(function* () {
return _this6._driver.keys();
})();
}
length() {
var _this7 = this;
return _asyncToGenerator(function* () {
return _this7._driver.length();
})();
}
removeItem(key) {
var _this8 = this;
return _asyncToGenerator(function* () {
const oldValue = (yield _this8.hasItem(key)) ? yield _this8.getItem(key) : undefined;
yield _this8._driver.removeItem(key);
const event = new RemoveItemBrowserStorageEvent({
name: _this8.options.name,
storeName: _this8.options.storeName,
version: _this8.options.version,
key,
oldValue,
newValue: null
});
_this8._triggerEvent(event);
})();
}
setItem(key, item) {
var _this9 = this;
return _asyncToGenerator(function* () {
const oldValue = (yield _this9.hasItem(key)) ? yield _this9.getItem(key) : undefined;
const result = yield _this9._driver.setItem(key, item);
const event = new SetItemBrowserStorageEvent({
name: _this9.options.name,
storeName: _this9.options.storeName,
version: _this9.options.version,
key,
oldValue,
newValue: item
});
_this9._triggerEvent(event);
return result;
})();
}
init(dbOptions) {
this._initCrossTabNotification();
return !!this._driver && this._driver.init(dbOptions);
}
hasItem(key) {
var _this10 = this;
return _asyncToGenerator(function* () {
return _this10._driver.hasItem(key);
})();
}
getDriver() {
var _this11 = this;
return _asyncToGenerator(function* () {
return _this11._driver;
})();
}
destroy() {
var _this12 = this;
return _asyncToGenerator(function* () {
window.removeEventListener('storage', _this12._storageChange);
_this12._handlerStore.clear();
return _this12._driver.destroy();
})();
}
addEventListener(fn) {
this._handlerStore.add(fn);
return () => this.removeEventListener(fn);
}
removeEventListener(fn) {
this._handlerStore.delete(fn);
}
_triggerEvent(event) {
this._applyHandlers(event);
this._triggerCrossTabEvent(event);
}
_triggerCrossTabEvent(event) {
if (this.options.crossTabNotification) {
localStorage.setItem(EVENT_KEY, BrowserStorageEvent.serialize(event.copyWith({
isCrossTab: true
})));
}
}
_applyHandlers(event) {
this._handlerStore.forEach(fn => fn(event));
}
_initCrossTabNotification() {
window.addEventListener('storage', this._storageChange);
}
}
__decorate([whenReady], BrowserStorage.prototype, "clear", null);
__decorate([whenReady], BrowserStorage.prototype, "getItem", null);
__decorate([whenReady], BrowserStorage.prototype, "iterate", null);
__decorate([whenReady], BrowserStorage.prototype, "key", null);
__decorate([whenReady], BrowserStorage.prototype, "keys", null);
__decorate([whenReady], BrowserStorage.prototype, "length", null);
__decorate([whenReady], BrowserStorage.prototype, "removeItem", null);
__decorate([whenReady], BrowserStorage.prototype, "setItem", null);
__decorate([whenReady], BrowserStorage.prototype, "hasItem", null);
__decorate([whenReady], BrowserStorage.prototype, "getDriver", null);
class Defer {
constructor() {
this._promise = new Promise((resolve, reject) => {
this._reject = reject;
this._resolve = resolve;
});
}
get promise() {
return this._promise;
}
resolve(result) {
return this._resolve(result);
}
reject(result) {
return this._reject(result);
}
}
exports.BrowserStorage = BrowserStorage;
exports.BrowserStorageEvent = BrowserStorageEvent;
exports.ClearBrowserStorageEvent = ClearBrowserStorageEvent;
exports.Defer = Defer;
exports.EVENT_KEY = EVENT_KEY;
exports.RemoveItemBrowserStorageEvent = RemoveItemBrowserStorageEvent;
exports.SetItemBrowserStorageEvent = SetItemBrowserStorageEvent;