@proscom/prostore-local-storage
TypeScript icon, indicating that this package has built-in type declarations

0.2.12 • Public • Published

prostore-local-storage

Адаптер для связи между внешними хранилищами (например, localStorage) и prostore.

В библиотеке представлено несколько классов:

  1. Класс стора WebStorageValueStore, стейт которого синхронизирован с localStorage (или sessionStorage).
  2. Более абстрактный вариант StorageValueStore для связи с произвольным внешним хранилищем через адаптер.
  3. Адаптер для localStorage: WebStorageAdapter (StorageValueStore + WebStorageAdapter = WebStorageValueStore)
  4. Класс стора 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();

См. в CodeSandbox

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.

Readme

Keywords

none

Package Sidebar

Install

npm i @proscom/prostore-local-storage

Weekly Downloads

23

Version

0.2.12

License

ISC

Unpacked Size

82.4 kB

Total Files

44

Last publish

Collaborators

  • alexeyshilyaev
  • mayorandrew
  • sviryukov
  • a.derbenev