@difizen/mana-core
Version:
82 lines (71 loc) • 2.38 kB
text/typescript
import type { MaybePromise, Event } from '@difizen/mana-common';
import { Emitter } from '@difizen/mana-common';
import type { DebugService } from './debug';
import { debug } from './debug';
import type { LocalStorage, StorageService } from './storage-protocol';
export class LocalStorageService implements StorageService {
public usePathInPrefix = false;
private storage: LocalStorage = {};
protected logger: DebugService;
protected onDiskQuotaExceededEmitter = new Emitter<void>();
get onDiskQuotaExceeded(): Event<void> {
return this.onDiskQuotaExceededEmitter.event;
}
constructor() {
this.logger = debug;
if (typeof window !== 'undefined' && window.localStorage) {
this.storage = window.localStorage;
this.testLocalStorage();
} else {
this.logger.log("The browser doesn't support localStorage.");
this.storage = {};
}
}
setData<T>(key: string, data?: T): MaybePromise<void> {
if (data !== undefined) {
try {
const value = JSON.stringify(data);
this.storage[this.prefix(key)] = value;
} catch (e) {
this.onDiskQuotaExceededEmitter.fire();
}
} else {
delete this.storage[this.prefix(key)];
}
return;
}
getData<T>(key: string, defaultValue?: T): MaybePromise<T> {
const result = this.storage[this.prefix(key)];
if (result === undefined) {
return defaultValue as any;
}
try {
return JSON.parse(result) as any;
} catch (e) {
return result;
}
}
protected prefix(key: string): string {
const pathname = typeof window === 'undefined' ? '' : window.location.pathname;
const prefix = this.usePathInPrefix ? `mana:${pathname}` : 'mana';
return `${prefix}:${key}`;
}
/**
* Verify if there is still some spaces left to save another workspace configuration into the local storage of your browser.
* If we are close to the limit, use a dialog to notify the user.
*/
private testLocalStorage(): void {
const keyTest = this.prefix('Test');
try {
this.storage[keyTest] = JSON.stringify(new Array(60000));
} catch (error) {
this.onDiskQuotaExceededEmitter.fire();
} finally {
this.storage.removeItem?.(keyTest);
}
}
clearStorage(): void {
this.storage.clear?.();
}
}
export const localStorageService = new LocalStorageService();