mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/DiscussionTools
synced 2024-11-28 02:00:57 +00:00
76 lines
2 KiB
JavaScript
76 lines
2 KiB
JavaScript
|
/**
|
||
|
* 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;
|