mediawiki-extensions-Discus.../modules/MemoryStorage.js

76 lines
2 KiB
JavaScript
Raw Normal View History

/**
* MemoryStorage is a wrapper around mw.SafeStorage objects.
*
* It provides two mechanisms to improve their behavior when the underlying storage mechanism fails
* (e.g. quota exceeded):
*
* - Duplicating their contents in memory, so that the storage can be relied on before the page has
* been reloaded.
* - Storing all keys in a single underlying key, to make the stores are atomic: either all values
* are stored or none.
*
* This has two additional consequences which are convenient for our use case:
*
* - All keys share the same expiry time, removing the need to specify it repeatedly.
* - When multiple processes try to write the same keys, all keys are overwritten, so that we don't
* have to worry about inconsistent data.
*
* @example
* var sessionStorage = new MemoryStorage( mw.storage.session, 'myprefix' );
* var localStorage = new MemoryStorage( mw.storage, 'myprefix' );
*/
class MemoryStorage {
/**
* @param {mw.SafeStorage} backend
* @param {string} key Key name to store under
* @param {number} [expiry] Number of seconds after which this item can be deleted
*/
constructor( backend, key, expiry ) {
this.backend = backend;
this.key = key;
this.expiry = expiry;
this.data = this.backend.getObject( this.key ) || {};
}
get( key ) {
if ( Object.prototype.hasOwnProperty.call( this.data, key ) ) {
return this.data[ key ];
}
return null;
}
set( key, value ) {
this.data[ key ] = value;
this.backend.setObject( this.key, this.data, this.expiry );
return true;
}
remove( key ) {
delete this.data[ key ];
if ( Object.keys( this.data ).length === 0 ) {
this.backend.remove( this.key );
} else {
this.backend.setObject( this.key, this.data, this.expiry );
}
return true;
}
clear() {
this.data = {};
this.backend.remove( this.key );
}
// For compatibility with mw.SafeStorage API
getObject( key ) {
return this.get( key );
}
// For compatibility with mw.SafeStorage API
setObject( key, value ) {
return this.set( key, value );
}
}
module.exports = MemoryStorage;