js/domreplay/storage.js
import Logger from './logger';
import { stateIsRecord } from './state';
import { createStorageError } from './error';
import { dispatchStorageUpdateEvent } from './dispatcher';
/**
* Stores information about the events recorded into local storage.
* @access public
*/
class Storage {
static storageKey;
static instance;
constructor() {
if (!this.instance) {
this.instance = this;
this.storageKey = 'DOMREPLAY_EVENT_STORAGE';
}
return this.instance;
}
/**
* Clears the event storage.
*/
clear() {
window.localStorage.removeItem(this.storageKey);
Logger.debug('Event storage cleared!');
}
/**
* Updates storage
* @param {Object} eventObject
*/
updateStorage(eventObject) {
window.localStorage.setItem(this.storageKey, JSON.stringify(eventObject));
dispatchStorageUpdateEvent(this.getLastStored());
}
/**
* Merge updates last stored event
* @param {Object} updates
*/
updateLastStored(updates) {
let events = this.events;
events.events[events.count - 1] = {...this.getLastStored(), ...updates};
this.updateStorage(events);
}
/**
* Gets the last stored event in storage.
* @returns {Object} - last stored event.
*/
getLastStored() {
const events = this.events;
if (!events) {
return null;
}
return events.events[events.count - 1];
}
/**
* Appends event to storage and increment storage count.
* @param {Object} object - Object to append.
* @access private
*/
_appendEvent(object) {
let events = this.events;
if (!events) {
events = {};
events.count = 0;
events.events = []
}
events.events.push(object);
events.count++;
Logger.debug(`Count: ${events.count}, Event: type(${object.type}) id(${object.id}) value(${object.value})`);
this.updateStorage(events);
}
/**
* Gets stored event by index.
* @param {Number} index
* @returns {Object} - event object
*/
getItem(index) {
return this.events.events[index];
}
/**
* Gets storage object
* @returns {Object}
*/
get events() {
return JSON.parse(window.localStorage.getItem(this.storageKey));
}
/**
* returns the size of Storage by event count.
* @returns {Number}
*/
get size() {
return this.events.count;
}
/**
* store event object in storage.
* @param type
* @param eventObject
* @returns {Promise<Error> | Promise<Object>}
*/
store(type, eventObject) {
return new Promise((resolve, reject) => {
if (!stateIsRecord()) {
Logger.error('Tried to add event to localstorage, but domreplay is not in record state');
reject(createStorageError('Tried to add event to localstorage, but domreplay is not in record state'));
}
const objectToStore = {
location: window.location.href,
type,
...eventObject
};
this._appendEvent(objectToStore);
resolve(objectToStore);
});
}
}
export default new Storage();