Skip to content

Storage Kit

v0.2.7Состояние и данныеVueReact

Реактивные localStorage, sessionStorage, IndexedDB и cookies для Vue 3 (и React) — TTL, шифрование, миграции схемы, undo/redo и синхронизация между вкладками.

Storage Kit
Начать знакомство →
npm install vue-storage-kit@latest
01 — Назначение

Когда это пригодится

localStorage хранит только строки, тихо переполняется без предупреждения и ничего не знает про другие открытые вкладки — vue-storage-kit берёт эти особенности на себя и добавляет то, чего в самом localStorage никогда не было: срок жизни записи, шифрование, синхронизацию между вкладками и миграции формата.

Открыты две вкладки с одним и тем же приложением

Пользователь добавил товар в корзину в одной вкладке и должен увидеть это в другой без перезагрузки страницы. Изменения в хранилище распространяются между вкладками мгновенно, а не только после обновления страницы.

Черновик не должен храниться вечно

Забытая форма или временный токен доступа не должны лежать в хранилище до конца времён — срок жизни записи истекает сам, и устаревшие данные удаляются при следующем обращении.

Личные данные в браузере не должны быть видны как есть

Любой может открыть инструменты разработчика и посмотреть содержимое хранилища обычным текстом — конфиденциальные значения можно держать зашифрованными, а не полагаться на то, что туда никто не заглянет.

Старый формат данных встречает новую версию приложения

После обновления приложения в хранилище пользователя может лежать структура данных из прошлой версии — она приводится к актуальному виду автоматически, вместо падения или молчаливой потери данных.

02 — Фичи

Коротко о главном

Единое реактивное API для всех хранилищ

Единое реактивное API для всех хранилищ

useStorage работает с localStorage, sessionStorage, IndexedDB и in‑memory через единый интерфейс. Реактивные Ref для Vue и useSyncExternalStore для React автоматически синхронизируют состояние с выбранным бекендом. Поддерживаются TTL, миграции схем, шифрование, сжатие, подпись, debounce/throttle и история изменений.

Миграции схем, TTL и шифрование AES-GCM

Миграции схем, TTL и шифрование AES-GCM

Версионируйте данные и автоматически применяйте цепочки миграций (up/down) при изменении структуры. Устанавливайте TTL для автоматического удаления устаревших записей при чтении. Шифруйте данные через Web Crypto API (AES-GCM) с выводом ключа из пароля (PBKDF2) или готовым CryptoKey, включая ротацию ключей.

Синхронизация между вкладками, Undo/redo и throttle

Синхронизация между вкладками, Undo/redo и throttle

Включите sync для мгновенного распространения изменений через BroadcastChannel (с fallback на storage event). Опциональный лидер (navigator.locks) разрешает конфликты по принципу last‑write‑wins. Встроенная история (history: n) даёт undo/redo без дополнительного кода, а debounce/throttle контролируют частоту записи.

Глубокая интеграция с экосистемой Vue и React

Глубокая интеграция с экосистемой Vue и React

Vue-плагин задаёт глобальный префикс, target, сериализатор и обработчик ошибок. Nuxt-модуль автоимпортирует все композаблы и делает useCookie SSR‑совместимым (с H3 на сервере). React‑версия использует useSyncExternalStore, разделяя один движок с Vue. Отдельные entry points для Pinia, DevTools и тестирования.

Производительность, SSR и DevTools

Производительность, SSR и DevTools

Асинхронные адаптеры (включая IndexedDB) не блокируют рендеринг; isReady позволяет показать скелетон до загрузки. На сервере используется in‑memory fallback. Встроенный DevTools-инспектор показывает все экземпляры, их значения, TTL и историю, а таймлайн логирует каждое изменение, миграцию и ошибку.

Устойчивость к переполнению и проверка целостности

Устойчивость к переполнению и проверка целостности

При превышении квоты хранилища библиотека сама зачищает устаревшие по TTL записи и повторяет запись, а evictOnQuota вытесняет наименее используемые ключи вместо ручной обработки QuotaExceededError. Подпись данных через HMAC обнаруживает изменение записи в обход библиотеки — напрямую через DevTools.

03 — Быстрый пример

Как это работает

Кэш, который сам протухает

TTL хранит время истечения прямо в конверте значения — просроченный ключ удаляется автоматически при следующем чтении, без ручных таймеров.

otp-cache.ts
import { useStorage } from 'vue-storage-kit'

const {
  value: otp,
  expiry,
  remove,
} = useStorage('otp', {
  defaultValue: '',
  ttl: 5 * 60 * 1000, // 5 minutes
  onExpire: () => router.push('/login'),
})

console.log(expiry.value) // Date | null — when this key expires

Синхронизация между вкладками

С sync: true изменение в одной вкладке мгновенно долетает до всех остальных открытых вкладок — без сервера и без ручной подписки.

cart-sync.ts
import { useStorage } from 'vue-storage-kit'

const { value: cart } = useStorage('cart', {
  defaultValue: [] as CartItem[],
  sync: true,
})

// cart.value stays in sync across every open tab automatically

Данные сами переезжают на новую схему при апдейте

Пользователь на старой версии открывает приложение — цепочка миграций сама доводит сохранённые данные до текущей схемы и сразу сохраняет результат, без ручного if/else по версии.

migrations.ts
import { useStorage } from 'vue-storage-kit'

interface SettingsV3 {
  theme: 'light' | 'dark'
  locale: string
}

const { value: settings } = useStorage<SettingsV3>('settings', {
  defaultValue: { theme: 'light', locale: 'en' },
  version: 3,
  migrations: [
    { version: 2, up: (d: any) => ({ ...d, theme: d.darkMode ? 'dark' : 'light' }) },
    { version: 3, up: (d: any) => ({ ...d, locale: d.lang ?? 'en' }) },
  ],
  onMigrate: (from, to) => console.log(`Migrated settings ${from} → ${to}`),
})

// A v1 user with { darkMode: true } in storage reads
// { darkMode: true, theme: 'dark', locale: 'en' } — the migration chain
// runs and persists automatically, on the very first read.