175 lines
3.8 KiB
JavaScript
175 lines
3.8 KiB
JavaScript
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) );
|
|
|
|
}
|
|
|
|
} |