UNPKG

@elemental-concept/rx-persist

Version:
118 lines (110 loc) 3.76 kB
import { Observable, from, of } from 'rxjs'; import { take, map, switchMap, filter, concatMap, takeLast } from 'rxjs/operators'; class DOMStorageDriver { constructor(storage) { this.storage = storage; } get(key) { try { const value = this.storage.getItem(key); if (typeof value === 'string') { return JSON.parse(value); } } catch (e) { } return null; } set(key, value) { this.storage.setItem(key, JSON.stringify(value)); return; } remove(key) { this.storage.removeItem(key); return; } } const sessionStorageDriver = new DOMStorageDriver(sessionStorage); const localStorageDriver = new DOMStorageDriver(localStorage); function load(key, next, storage) { const result = storage.get(key); if (result instanceof Observable) { result.pipe(take(1)).subscribe(v => next(v)); return; } if (typeof result?.then === 'function') { result.then(v => next(v)); return; } if (result !== null && result !== undefined) { next(result); } } function loadAsObservable(key, storage) { const result = storage.get(key); if (result instanceof Observable) { return result.pipe(take(1)); } if (typeof result?.then === 'function') { return from(result); } return of(result); } function save(key, storage, value) { const result = storage.set(key, value); if (result instanceof Observable) { return result.pipe(take(1)); } if (typeof result?.then === 'function') { return from(result); } return of(true); } function getStorageKey(key) { return typeof key === 'string' ? key : key.join('.'); } class StorageAccessMock { constructor() { this.storage = {}; this.length = 0; } clear() { } getItem(key) { return this.storage[key] === undefined ? null : this.storage[key]; } key(index) { return null; } removeItem(key) { delete this.storage[key]; } setItem(key, value) { this.storage[key] = value; } } function persistent(subject, key, storage = localStorageDriver) { const next = subject.next.bind(subject); const storageKey = getStorageKey(key); load(storageKey, next, storage); subject.next = (value) => save(storageKey, storage, value).subscribe(() => next(value)); return subject; } function persistentAndVersioned(subject, key, options) { const next = subject.next.bind(subject); const storage = options.storage !== undefined ? options.storage : localStorageDriver; const storageKey = getStorageKey(key); const versionKey = getStorageKey(options.versionKey); loadAsObservable(versionKey, storage) .pipe(map(version => typeof version === 'number' ? version : 0), switchMap(version => from([...Array(options.currentVersion).keys()]) .pipe(filter(v => v >= version))), concatMap(version => loadAsObservable(storageKey, storage) .pipe(map(value => options.migrate(version, value)), concatMap(value => save(storageKey, storage, value)), concatMap(() => save(versionKey, storage, version + 1)))), takeLast(1)) .subscribe({ complete: () => load(storageKey, next, storage) }); subject.next = (value) => save(storageKey, storage, value).subscribe(() => next(value)); return subject; } /** * Generated bundle index. Do not edit. */ export { DOMStorageDriver, localStorageDriver, persistent, persistentAndVersioned, sessionStorageDriver }; //# sourceMappingURL=elemental-concept-rx-persist.mjs.map