discord-client/webpack/lib/local-storage-interface.js

175 lines
3.8 KiB
JavaScript
Raw Permalink Normal View History

export default class LocalStorageInterface{
/* (1) Constructs a localStorage Interface
*
* @_prefix<String> localStorage Interface Prefix (prefix)
* @_ttl<int> Seconds default valid time for stored data
* @_session<bool> Whether to use sessionStorage (default is localStorage)
*
---------------------------------------------------------*/
constructor(_prefix, _ttl, _session=false){
/* (1) Initialise private attributes */
this._prefix = 'root';
this._ttl = null;
this._driver = !!_session ? sessionStorage : localStorage;
/* (2) Initialise public attributes */
this.keys = [];
/* (3) Set given _prefix if valid */
if( typeof _prefix === 'string' )
this._prefix = _prefix;
/* (4) Set given _ttl if valid */
if( !isNaN(_ttl) )
this._ttl = _ttl;
/* (5) Synchronize keys */
this.synchronise();
}
/* (1) Synchronise keys from this._driver
*
---------------------------------------------------------*/
synchronise(){
// 1. Get this._driver key list
let keys = Object.keys(this._driver);
// 2. Local copy of prefix
let prefix = `${this._prefix}.`;
// 3. Only keep prefixed keys
let prefixed = keys.filter( (k) => ( k.substr(0, prefix.length) === prefix ) );
// 4. Remove prefix
let unprefixed = prefixed.map( (k) => k.substr(prefix.length) );
// X. Update keys
this.keys = unprefixed;
}
/* (2) Store data
*
* @_name<String> Object key
* @_data<String> Object key
* @_ttl<int> [OPT] Seconds valid time for this data
*
---------------------------------------------------------*/
push(_name, _data, _ttl=null){
/* (1) Manage argument
---------------------------------------------------------*/
/* (1) Invalid _name type */
if( typeof _name !== 'string' )
return false;
/* (2) Default value for _ttl */
let ttl = isNaN(_ttl) || _ttl === null ? this._ttl : parseInt(_ttl);
/* (2) Store data
---------------------------------------------------------*/
/* (1) Build storage object */
let storage_object = {
expires: ttl ? new Date().getTime() + ttl*1000 : null,
data: _data
};
/* (2) Store storage object */
this._driver.setItem(`${this._prefix}.${_name}`, JSON.stringify(storage_object));
/* (3) Synchronize keys */
this.keys.push(_name);
/* (4) Return status */
return true;
}
/* (3) Fetch data
*
* @_name<String> Object key
*
* @return outName<Object> Object data (NULL on error or not found)
*
---------------------------------------------------------*/
fetch(_name){
/* (1) Manage argument
---------------------------------------------------------*/
/* (1) Invalid _name type */
if( typeof _name !== 'string' )
return null;
/* (2) invalid key */
if( this.keys.indexOf(_name) < 0 )
return null;
/* (2) Fetch data
---------------------------------------------------------*/
/* (1) Try to get data */
let fetched = this._driver.getItem(`${this._prefix}.${_name}`);
/* (2) Try to parse */
try{
var storage_object = JSON.parse(fetched);
/* (3) If cannot parse -> remove */
}catch(e){
this.pop(_name);
return null;
}
/* (4) If not valid anymore -> delete + return NULL */
if( !isNaN(storage_object.expires) && storage_object.expires < new Date().getTime() ){
this.pop(_name);
return null;
}
/* (5) Return data */
return storage_object.data;
}
/* (4) Remove data
*
* @_name<String> Object key
*
---------------------------------------------------------*/
pop(_name){
/* (1) Invalid _name type */
if( typeof _name !== 'string' )
return null;
/* (2) invalid key */
if( this.keys.indexOf(_name) < 0 )
return null;
/* (3) Remove from this._driver */
this._driver.removeItem(`${this._prefix}.${_name}`);
/* (4) Update keys */
this.keys = this.keys.filter( (k) => (k!==_name) );
}
}