184 lines
4.5 KiB
TypeScript
184 lines
4.5 KiB
TypeScript
/**
|
|
* Stores key-value pairs.
|
|
*/
|
|
export interface Storage {
|
|
/**
|
|
* Removes the data from storage.
|
|
*/
|
|
clear(): void
|
|
|
|
/**
|
|
* Retrieves an array from storage.
|
|
*
|
|
* @param name the name of the array to retrieve
|
|
* @param def the value to return if no array is stored with the given name
|
|
*/
|
|
getArray(name: string, def: any[]): any[]
|
|
|
|
/**
|
|
* Stores an array.
|
|
*
|
|
* @param name the name of the array to store
|
|
* @param value the array to store under the given name
|
|
* @protected
|
|
*/
|
|
setArray(name: string, value: any[]): void
|
|
|
|
/**
|
|
* Retrieves a boolean from storage.
|
|
*
|
|
* @param name the name of the boolean to retrieve
|
|
* @param def the value to return if no boolean is stored with the given name
|
|
* @protected
|
|
*/
|
|
getBoolean(name: string, def: boolean): boolean
|
|
|
|
/**
|
|
* Stores a boolean.
|
|
*
|
|
* @param name the name of the boolean to store
|
|
* @param value the boolean to store under the given name
|
|
* @protected
|
|
*/
|
|
setBoolean(name: string, value: boolean): void
|
|
|
|
/**
|
|
* Retrieves a number from storage.
|
|
*
|
|
* @param name the name of the number to retrieve
|
|
* @param def the value to return if no number is stored with the given name
|
|
* @protected
|
|
*/
|
|
getNumber(name: string, def: number): number
|
|
|
|
/**
|
|
* Stores a number.
|
|
*
|
|
* @param name the name of the number to store
|
|
* @param value the number to store under the given name
|
|
* @protected
|
|
*/
|
|
setNumber(name: string, value: number): void
|
|
}
|
|
|
|
/**
|
|
* Stores key-value pairs in a single entry in `localStorage`.
|
|
*/
|
|
export class LocalStorage implements Storage {
|
|
private readonly key: string;
|
|
private cache: { [key: string]: string } | null = null;
|
|
|
|
|
|
/**
|
|
* Constructs a new persistent storage item under the given key.
|
|
*
|
|
* @param key the unique identifier to store the data under
|
|
*/
|
|
constructor(key: string) {
|
|
this.key = key;
|
|
}
|
|
|
|
|
|
/**
|
|
* Reads the object stored in local storage.
|
|
*
|
|
* @return the object stored in local storage, or an empty object if there is nothing in the local storage
|
|
* @private
|
|
*/
|
|
private read(): { [key: string]: string } {
|
|
if (this.cache === null)
|
|
this.cache = JSON.parse(localStorage.getItem(this.key) ?? "{}");
|
|
|
|
return this.cache!;
|
|
}
|
|
|
|
/**
|
|
* Writes the given object to local storage.
|
|
*
|
|
* @param item the object to write to local storage
|
|
* @private
|
|
*/
|
|
private write(item: { [key: string]: string }): void {
|
|
this.cache = item;
|
|
localStorage.setItem(this.key, JSON.stringify(item));
|
|
}
|
|
|
|
|
|
clear(): void {
|
|
this.cache = null;
|
|
localStorage.removeItem(this.key);
|
|
}
|
|
|
|
getArray(name: string, def: any[] = []): any[] {
|
|
const array = this.read()[name];
|
|
return array === undefined ? def : JSON.parse(array);
|
|
}
|
|
|
|
setArray(name: string, value: any[]): void {
|
|
const item = this.read();
|
|
item[name] = JSON.stringify(value);
|
|
this.write(item);
|
|
}
|
|
|
|
getBoolean(name: string, def: boolean = false): boolean {
|
|
return (this.read()[name] ?? `${def}`) === "true";
|
|
}
|
|
|
|
setBoolean(name: string, value: boolean): void {
|
|
const item = this.read();
|
|
item[name] = "" + value;
|
|
this.write(item);
|
|
}
|
|
|
|
getNumber(name: string, def: number = 0): number {
|
|
return +(this.read()[name] ?? def);
|
|
}
|
|
|
|
setNumber(name: string, value: number): void {
|
|
const item = this.read();
|
|
item[name] = "" + value;
|
|
this.write(item);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Stores key-value pairs in an object.
|
|
*/
|
|
export class MemoryStorage implements Storage {
|
|
private storage: { [key: string]: any } = {};
|
|
|
|
|
|
clear(): void {
|
|
this.storage = {};
|
|
}
|
|
|
|
setArray(name: string, value: any[] = []): void {
|
|
this.storage[name] = value;
|
|
}
|
|
|
|
getArray(name: string, def: any[]): any[] {
|
|
return this.storage[name] ?? def;
|
|
}
|
|
|
|
setBoolean(name: string, value: boolean): void {
|
|
this.storage[name] = value;
|
|
}
|
|
|
|
getBoolean(name: string, def: boolean): boolean {
|
|
return this.storage[name] ?? def;
|
|
}
|
|
|
|
setNumber(name: string, value: number): void {
|
|
this.storage[name] = value;
|
|
}
|
|
|
|
getNumber(name: string, def: number): number {
|
|
return this.storage[name] ?? def;
|
|
}
|
|
}
|
|
|
|
|
|
// Export to `window`
|
|
(window as any).fwdekker = (window as any).fwdekker ?? {};
|
|
(window as any).fwdekker.storage = {Storage, LocalStorage, MemoryStorage};
|