import {Meta} from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/ru/functional-basic/Classes/DataStorage - Обёртка Local и Session Storage'/>

# Класс DataStorage

Универсальный класс для взаимодействия с `localStorage` и `sessionStorage` браузера. Включает в себя автоматическое создание префиксов, ограничение срока действия кэша (возраст), кэширование в памяти для активных экземпляров и автоматическую сериализацию JSON.

> `DataStorage` является **вспомогательным классом**, предназначенным для низкоуровневого взаимодействия с хранилищем браузера. В большинстве случаев рекомендуется использовать специализированные классы, такие как `Cookie` или `Api`, для конкретных задач.

## Основные возможности

- **Автоматическая сериализация** — легко справляется с разбором и преобразованием в JSON-строку при хранении конфигураций и объектов.
- **Хранение с учётом времени** — позволяет сохранять объекты с временными метками и учитывать ограничения по возрасту значения во время его извлечения.
- **Управление префиксами** — поддерживает глобальные и специфичные для каждого экземпляра префиксы, позволяющие изолировать и группировать ключи в рамках `localStorage`.
- **Эффективная память** — создает паттерн singleton для идентичных ключей, чтобы избежать одновременного чтения непосредственно с диска.
- **Поддержка SSR** — использует изоляцию на уровне запросов при серверном рендеринге, предотвращая утечку данных между параллельными сессиями.

## Инициализация

Для инициализации объекта вызовите конструктор `DataStorage(name, isSession)`.

### Ограничения дженериков (Generic Constraints)

Класс поддерживает следующий дженерик для обеспечения строгой типизации сохраняемого значения:
- `T` — Тип данных, хранящихся в хранилище.

**Параметры:**
- `name: string` — название ключа в хранилище.
- `isSession: boolean = false` — нужно ли использовать `sessionStorage` (по умолчанию `localStorage`).

```typescript
import { DataStorage } from '@dxtmisha/functional-basic'

// 1. Создание экземпляра для localStorage
const settings = new DataStorage('settings')

// 2. Создание экземпляра для sessionStorage
const session = new DataStorage('user_session', true)
```

## Методы

### Доступ к хранилищу

- `get(defaultValue?: T | (() => T), cache?: number): T | undefined` — Извлекает текущее сохраненное значение. Если указано время кэширования, возвращает `undefined`, если данные устарели.
- `set(value?: T | (() => T)): T | undefined` — Устанавливает или обновляет значение в хранилище. Передача `undefined` удаляет элемент.
- `remove(): this` — Удаляет соответствующий ключ из хранилища и очищает экземпляр в памяти.
- `update(): this` — Принудительно синхронизирует экземпляр памяти с актуальными данными из Storage API.

### Конфигурация

- `static setPrefix(newPrefix: string): void` — Изменяет глобальный префикс, применяемый ко всем новым экземплярам. Префикс по умолчанию — `ui-storage`.

## SSR и Гидратация

Класс `DataStorage` полностью совместим с серверным рендерингом (SSR). Он использует специальный реестр для изоляции экземпляров между различными HTTP-запросами на сервере.

> Чтобы избежать ошибок гидратации (когда HTML от сервера не совпадает с клиентским), рекомендуется вызывать метод `get()` внутри `useEffect` или других клиентских хуков. На сервере `get()` всегда будет возвращать `undefined` (или `defaultValue`), так как `localStorage` недоступен.

## Примеры

### Использование значений по умолчанию и кэша
```javascript
const settings = new DataStorage('user_settings')

// Получение данных с откатом к пустому объекту, если они не найдены
const currentSettings = settings.get({})

// Получение данных, только если они были сохранены в течение последних 60 секунд
const cachedItem = settings.get(undefined, 60)
```

### Ручная синхронизация
```javascript
const storage = new DataStorage('shared_data')

// ... данные могли быть изменены в другой вкладке или части приложения
storage.update() // Синхронизируем память с диском
console.log(storage.get())
```
