@proscom/prostore-local-storage
v0.2.12
Published
Adapter for prostore and localStorage. Allows usage of localStorage to store application state
Downloads
8
Keywords
Readme
prostore-local-storage
Адаптер для связи между внешними хранилищами (например, localStorage
) и prostore
.
В библиотеке представлено несколько классов:
- Класс стора
WebStorageValueStore
, стейт которого синхронизирован сlocalStorage
(илиsessionStorage
). - Более абстрактный вариант
StorageValueStore
для связи с произвольным внешним хранилищем через адаптер. - Адаптер для
localStorage
:WebStorageAdapter
(StorageValueStore + WebStorageAdapter = WebStorageValueStore
) - Класс стора
LocalStorageStore
для синхронизации сразу нескольких ключей сlocalStorage
.
Подписка на изменение значений localStorage
/ sessionStorage
происходит
через браузерное событие storage.
Значения автоматически сериализуются в JSON при записи и парсятся при чтении.
WebStorageValueStore
Используйте WebStorageValueStore
, чтобы синхронизировать значение с localStorage
.
Инстанциируйте класс, передав в него инстанс localStorage
, имя ключа и трансформер значения.
Трансформер принимает значение после парсинга из формата JSON.
Его можно использовать для обработки некорректных значений.
Например, если требуется определенная структура объекта в localStorage
, то в функции парсинга можно
проверить имеющийся объект и вернуть null
, если он некорректный.
import { WebStorageValueStore } from '@proscom/prostore-local-storage';
const LOCAL_STORAGE_KEY_SCORE = 'score';
// Синхронизированный стор
const scoreStore = new WebStorageValueStore<number>(
localStorage,
LOCAL_STORAGE_KEY_SCORE,
// Трансформер значения. Так как внешнее хранилище может изменяться извне,
// то нет гарантии что значение имеет определенный тип.
// С помощью трансформера можно привести значение к нужному типу
(value) => +value || 0
);
// Регистрируем обработчик события storage
scoreStore.registerListener();
// При изменении значения во внешнем хранилище, оно изменится и в сторе.
// Подписываемся на изменение значения как на любой обзервабл
const sub = scoreStore.state$.subscribe((score) => {
// После первоначальной загрузки данных из внешнего хранилища loaded=true
// score.value содержит непосредственно значение
console.log(score.loaded, score.value);
});
// Значение стора можно изменить, тогда оно меняется и во внешнем хранилище
scoreStore.setValue(5);
// Отписаться от обновлений стора можно так
sub.unsubscribe();
// Перед удалением scoreStore обработчик событий надо снять
scoreStore.destroy();
StorageValueStore
Класс StorageValueStore
- это более абстрактная версия WebStorageValueStore
,
которая может работать с любым внешним хранилищем.
Для её использования необходимо реализовать адаптер доступа к значению,
удовлетворяющий интерфейсу IStorageValueAdapter
:
export interface IStorageValueAdapter<T> {
// Обзервабл значения во внешнем хранилище
// При подписке он должен выдавать текущее значение (синхронно или асинхронно)
value$: Observable<T | null>;
// Функция для изменения значения во внешнем хранилище
setValue(value: T | null): void;
}
В библиотеке представлен адаптер WebStorageAdapter
для работы с localStorage
и sessionStorage
.
Ниже представлен пример создания собственного адаптера:
import {
StorageValueStore,
IStorageValueAdapter
} from '@proscom/prostore-local-storage';
import { BehaviorSubject } from 'rxjs';
// Бесполезный адаптер, который вместо внешнего хранилища сохраняет значение в BehaviorSubject
class MyAdapter<T> implements IStorageValueAdapter<T> {
value$ = new BehaviorSubject<T | null>();
setValue(value: T | null) {
this.value$.next(value);
}
}
// Создаём StorageValueStore используя собственный адаптер
const myStore = new StorageValueStore<string>(new MyAdapter<string>(), (x) =>
String(x)
);
WebStorageAdapter
Адаптер для связи StorageValueStore
с localStorage
и sessionStorage
.
В большинстве случаев вместо него следует использовать WebStorageValueStore
.
import {
StorageValueStore,
WebStorageAdapter
} from '@proscom/prostore-local-storage';
const adapter = new WebStorageAdapter(localStorage, 'test');
const sub = adapter.value$.subscribe((value) => console.log(value));
adapter.setValue('newValue');
sub.unsubscribe();
const store = new StorageValueStore(adapter);
LocalStorageStore
@deprecated
- рекомендуется использовать несколько WebStorageValueStore
вместо одного LocalStorageStore
.
Чтобы использовать LocalStorageStore, просто инстанциируйте его, передав массив строк-ключей, значения которых необходимо прочитать и отслеживать.
const LOCAL_STORAGE_KEY_ACCESS_TOKEN = 'accessToken';
const localStorageStore = new LocalStorageStore(localStorage, [
LOCAL_STORAGE_KEY_ACCESS_TOKEN
]);
// Вызов этой функции необходим для подписки на изменения
// Можно ее не вызывать, тогда значения будут прочитаны только один раз
localStorageStore.registerListener();
Теперь можно подписаться на все данные сразу:
localStorageStore.state$.subscribe((state) => {
/*
* state = {
* accessToken: 'myAccessToken'
* }
*/
});
Или только на конкретный ключ:
localStorageStore.get$(LOCAL_STORAGE_KEY_ACCESS_TOKEN).subscribe((state) => {
// state = 'myAccessToken'
});
Если требуется подписаться на несколько ключей, то можно использовать combineLatest:
combineLatest(
localStorageStore.get$(LOCAL_STORAGE_KEY_ACCESS_TOKEN),
localStorageStore.get$(LOCAL_STORAGE_KEY_REFRESH_TOKEN)
).subscribe(([accessToken, refreshToken]) => {
// ...
});
Чтобы записать значение в стор и в localStorage, можно воспользоваться методом setItem
:
localStorageStore.setItem(LOCAL_STORAGE_KEY_ACCESS_TOKEN, 'differentToken');
Чтобы получить текущее значение ключа без подписки, можно обратиться к состоянию стора:
console.log(localStorageStore.state[LOCAL_STORAGE_KEY_ACCESS_TOKEN]);
Сериализация в JSON
LocalStorageStore
и WebStorageValueStore
автоматически сериализуют все переданные значения в JSON при записи и пытаются парсить JSON при чтении:
const LOCAL_STORAGE_KEY_DATA = 'data';
localStorageStore.setItem(LOCAL_STORAGE_KEY_DATA, { data: 2 });
// В data запишется строка: '{ "data": 2 }'
Если значение в localStorage
не является валидным JSON, то LocalStorageStore
и WebStorageValueStore
возвращают null
.