Использование в Service Worker

Idb-keyval — это минималистичная библиотека для работы с IndexedDB в JavaScript, предоставляющая простые методы get, set, del, clear и keys для асинхронного хранения данных. В контексте Service Worker она особенно полезна для кэширования ресурсов, хранения состояния офлайн-приложений и управления данными между сессиями.

Service Worker работает в отдельном потоке от основного интерфейса страницы, поэтому IndexedDB становится удобным механизмом для долговременного хранения данных. Idb-keyval оборачивает все низкоуровневые операции IndexedDB в промисы, что делает взаимодействие с базой данных безопасным и лаконичным.


Подключение и инициализация

Для использования в Service Worker библиотека обычно подключается через модуль:

import { get, set, del, clear, keys } from 'idb-keyval';

Создание собственной базы или хранилища с кастомными именами объектов:

import { Store, get, set } from 'idb-keyval';

const myStore = new Store('my-database', 'my-store');

// Пример сохранения данных
set('user-settings', { theme: 'dark', notifications: true }, myStore)
  .then(() => console.log('Настройки сохранены'));

По умолчанию idb-keyval использует хранилище с именем keyval-store в базе keyval-db. При необходимости можно создавать отдельные Store для изоляции разных типов данных.


Сохранение и получение данных в Service Worker

Service Worker часто нужен для кэширования и офлайн-доступа. Например, можно хранить ответы API:

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(cachedResponse => {
      if (cachedResponse) return cachedResponse;

      return fetch(event.request).then(response => {
        const responseClone = response.clone();
        responseClone.json().then(data => {
          set(event.request.url, data); // Сохраняем данные в IndexedDB
        }).catch(() => {});
        return response;
      });
    })
  );
});

Для получения данных из хранилища используется get:

get(event.request.url).then(cachedData => {
  if (cachedData) {
    // Используем данные из IndexedDB
    return new Response(JSON.stringify(cachedData), {
      headers: { 'Content-Type': 'application/json' }
    });
  }
});

Удаление и очистка данных

Удаление конкретного ключа:

del('user-settings').then(() => console.log('Настройки удалены'));

Полная очистка хранилища:

clear(myStore).then(() => console.log('Все данные очищены'));

Эти операции полезны, когда необходимо сбросить устаревшие данные или при обновлении версии приложения.


Управление ключами и обход данных

Для перебора всех ключей используется keys:

keys(myStore).then(allKeys => {
  allKeys.forEach(key => {
    get(key, myStore).then(value => console.log(key, value));
  });
});

Такой подход позволяет динамически проверять содержимое IndexedDB и обновлять кэш в зависимости от текущей логики Service Worker.


Асинхронность и обработка ошибок

Все методы idb-keyval возвращают промисы, что обеспечивает корректное использование в асинхронных Service Worker обработчиках. Например:

set('token', 'abc123')
  .then(() => console.log('Токен сохранён'))
  .catch(err => console.error('Ошибка сохранения токена', err));

Важно учитывать, что IndexedDB может быть временно недоступна, и обработка ошибок обязательна для надёжного офлайн-кэширования.


Интеграция с кэшированием ресурсов

Сочетание idb-keyval и Cache API позволяет реализовать гибкую стратегию кэширования. Например, кэширование JSON и медиафайлов:

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.json')) {
    event.respondWith(
      get(event.request.url).then(cachedData => {
        if (cachedData) return new Response(JSON.stringify(cachedData));
        return fetch(event.request).then(response => {
          response.clone().json().then(data => set(event.request.url, data));
          return response;
        });
      })
    );
  } else {
    event.respondWith(
      caches.match(event.request).then(cachedResponse => cachedResponse || fetch(event.request))
    );
  }
});

Это позволяет обеспечивать быстрый офлайн-доступ к часто используемым данным без повторного сетевого запроса.


Особенности использования в Service Worker

  • Работа в отдельном потоке: операции с IndexedDB не блокируют основной поток интерфейса.
  • Промисы: все методы асинхронные, что идеально подходит для событий fetch, install и activate.
  • Изоляция данных: можно создавать несколько хранилищ через Store, чтобы разделять различные типы кэшей и пользовательских данных.
  • Совместимость с офлайн-режимом: данные сохраняются на устройстве и доступны даже при отсутствии сети.

Использование idb-keyval в Service Worker позволяет создать лёгкую и безопасную систему хранения данных, минимизируя сложность работы с IndexedDB напрямую и обеспечивая высокую производительность офлайн-приложений.