Last active
March 22, 2019 22:59
-
-
Save betocantu93/fd843d8c57bf6368fb070842e28ff3f8 to your computer and use it in GitHub Desktop.
Bucket Storage. Fast util for persisting and retrieving from local or session storage it's also bucket oriented
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const DEFAULT_BUCKET_NAME = "general"; | |
const DEFAULT_TYPE = "local"; | |
/* | |
* Storage class should be used as follow: | |
* | |
* @param string "session" || "local" //default local | |
* @param string Bucket Name, where following objects will be stored, it's like a namespace. | |
* | |
* const storage = Storage("local", "tables"); | |
* | |
* storage.update("reports-table-p2", { | |
* columns: { | |
* updatedAt: { filterString: "2018/03/21", isHidden: true } | |
* } | |
* }); | |
* | |
* You can chain methods like | |
* | |
* storage.update("new-table", { | |
* someData: "Alberto" | |
* }).update("new-table", { | |
* someNewData: "Juan" | |
* }); | |
* | |
* storage.get("new-table")) // { someData: "Alberto", newData: "Juan" } | |
* | |
* To completely replace use set. | |
* | |
* storage.set("new-table", { }); // {} | |
* | |
* storage.remove("new-table").get("new-table"); // false | |
* | |
* | |
* | |
* You can merge objects like | |
* | |
* const obj1 = { | |
* name: "Alberto", | |
* age: 35 | |
* }; | |
* | |
* const obj2 = { | |
* favoriteMeal: "hamburger", | |
* age: 18 | |
* }; | |
* | |
* storage.set("new-table", obj1).update("new-table", obj2); // { name: "Alberto", age: 18, favoriteMeal: "hamburger" } | |
* | |
* | |
* To remove a bucket just use | |
* | |
* storage.deleteBucket(); | |
* | |
* */ | |
export class Storage { | |
constructor(type = DEFAULT_TYPE, bucket = DEFAULT_BUCKET_NAME){ | |
if(type === "local") { | |
this.retrieve = this.localStorageRetrieve.bind(this, bucket); | |
this.persist = this.localStoragePersist.bind(this, bucket); | |
this.deleteBucket = this.localStorageDeleteBucket.bind(this, bucket); | |
} else { | |
this.retrieve = this.sessionStorageRetrieve.bind(this, bucket); | |
this.persist = this.sessionStoragePersist.bind(this, bucket); | |
this.deleteBucket = this.sessionStorageDeleteBucket.bind(this, bucket); | |
} | |
this.canUseStorage = this.canUseStorage.bind(this, type); | |
} | |
} | |
/* | |
* Retrieve key from localStorage or sessionStorage | |
* */ | |
Storage.prototype.get = function(key) { | |
if(this.canUseStorage()) { | |
return this._getElement(key); | |
} | |
}; | |
//Push to elements array if the key doesn't exists | |
Storage.prototype.create = function(key = null, data = {}){ | |
if(!key) { | |
return this; | |
} | |
let element = this._getElement(key); | |
if(!element) { | |
let elements = this.retrieve(); | |
if(elements) { | |
elements[key] = data; | |
} else { | |
elements = { | |
[key]: data | |
}; | |
} | |
this.persist(elements); | |
} | |
return this; | |
}; | |
/* | |
Update key with the data provided | |
*/ | |
Storage.prototype.update = function(key = null, data = {}, merge = true) { | |
if(key) { | |
let element = this._getElement(key); | |
if(element){ | |
if (merge) { | |
Object.assign(element, mergeDeep(element, data)); | |
} else { | |
Object.assign(element, data) | |
} | |
let elements = this.retrieve(); | |
elements[key] = element; | |
this.persist(elements); | |
} else { | |
return this.create(key, data); | |
} | |
} | |
return this; | |
}; | |
/* | |
Set the key with the data provided | |
*/ | |
Storage.prototype.set = function(key = null, data = {}) { | |
if(key) { | |
//if null is sent, place an empty object. | |
data = data || {}; | |
let element = this._getElement(key); | |
if(element){ | |
let elements = this.retrieve(); | |
elements[key] = data; | |
this.persist(elements); | |
} else { | |
return this.create(key, data); | |
} | |
} | |
return this; | |
}; | |
/* | |
* Remove the element by key inside a bucket | |
* */ | |
Storage.prototype.remove = function(key){ | |
if(key){ | |
let elements = this.retrieve(); | |
delete elements[key]; | |
this.persist(elements); | |
} | |
return this; | |
}; | |
/* | |
* Delete bucket in localStorage | |
* */ | |
Storage.prototype.localStorageDeleteBucket = function(bucket = DEFAULT_BUCKET_NAME ){ | |
if(this.canUseStorage()) { | |
window.localStorage.removeItem(bucket); | |
} | |
}; | |
/* | |
* Persist bucket data in localStorage | |
* */ | |
Storage.prototype.localStoragePersist = function(bucket = DEFAULT_BUCKET_NAME, dataToPersist){ | |
if(this.canUseStorage()) { | |
window.localStorage.setItem(bucket, JSON.stringify(dataToPersist)); | |
} | |
}; | |
/* | |
* Load bucket data from localStorage | |
* */ | |
Storage.prototype.localStorageRetrieve = function(bucket = DEFAULT_BUCKET_NAME){ | |
if(this.canUseStorage()) { | |
let elements = window.localStorage.getItem(bucket); | |
return JSON.parse(elements); | |
} | |
}; | |
/* | |
* Persist bucket data to sessionStorage | |
* */ | |
Storage.prototype.sessionStoragePersist = function(bucket = DEFAULT_BUCKET_NAME, dataToPersist){ | |
if(this.canUseStorage()) { | |
window.sessionStorage.setItem(bucket, JSON.stringify(dataToPersist)); | |
} | |
}; | |
/* | |
* Load bucket data from sessionStorage | |
* */ | |
Storage.prototype.sessionStorageRetrieve = function(bucket = DEFAULT_BUCKET_NAME){ | |
if(this.canUseStorage()) { | |
let elements = window.sessionStorage.getItem(bucket); | |
return JSON.parse(elements); | |
} | |
}; | |
/* | |
* Delete bucket in localStorage | |
* */ | |
Storage.prototype.sessionStorageDeleteBucket = function(bucket = DEFAULT_BUCKET_NAME ){ | |
if(this.canUseStorage()) { | |
window.sessionStorage.removeItem(bucket); | |
} | |
}; | |
/* | |
* Check if we can use local or session storage | |
* */ | |
Storage.prototype.canUseStorage = function(type = DEFAULT_TYPE){ | |
return ( | |
type === "local" && typeof window.localStorage !== "undefined" | |
|| | |
type === "session" && typeof window.sessionStorage !== "undefined" | |
); | |
}; | |
/* | |
* Get the element with a key from the bucket | |
* */ | |
Storage.prototype._getElement = function(key) { | |
let elements = this.retrieve(); | |
return elements && elements.hasOwnProperty(key) ? elements[key] : false; | |
}; | |
function isObject(item) { | |
return (item && typeof item === 'object' && !Array.isArray(item)); | |
} | |
export function mergeDeep(target, source) { | |
let output = Object.assign({}, target); | |
if (isObject(target) && isObject(source)) { | |
Object.keys(source).forEach(key => { | |
if (isObject(source[key])) { | |
if (!(key in target)) | |
Object.assign(output, { [key]: source[key] }); | |
else | |
output[key] = mergeDeep(target[key], source[key]); | |
} else { | |
Object.assign(output, { [key]: source[key] }); | |
} | |
}); | |
} | |
return output; | |
} | |
/* | |
* Convenience function to initialize Storage object. | |
* */ | |
export default function(type = DEFAULT_TYPE, bucket = DEFAULT_BUCKET_NAME) { | |
type = ( | |
typeof type !== "string" || (type !== "local" && type !== "session") | |
) ? DEFAULT_TYPE : type; | |
bucket = typeof type !== "string" ? DEFAULT_BUCKET_NAME : bucket; | |
return new Storage(type, bucket); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment