Проверка готовности библиотеки к работе

Работа с localForage начинается не с записи данных, а с проверки того, какие механизмы хранения доступны в текущей среде. Библиотека абстрагирует различия между IndexedDB, WebSQL и localStorage, однако сама среда браузера может ограничивать или полностью отключать некоторые из них.

Ключевой момент заключается в том, что доступность хранилища нельзя считать гарантированной даже при наличии API в браузере. Режимы приватного просмотра, корпоративные политики, устаревшие движки или ограничения безопасности могут блокировать IndexedDB или localStorage.

Базовая проверка начинается с определения поддержки окружения:

import localforage from "localforage";

if (!localforage.supports(localforage.INDEXEDDB)) {
  console.warn("IndexedDB недоступен");
}

if (!localforage.supports(localforage.WEBSQL)) {
  console.warn("WebSQL недоступен");
}

if (!localforage.supports(localforage.LOCALSTORAGE)) {
  console.warn("localStorage недоступен");
}

Метод supports позволяет получить предварительное понимание возможностей среды, однако он не гарантирует успешную инициализацию драйвера.


Инициализация состояния библиотеки

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

Для контроля готовности используется метод ready(), возвращающий Promise:

localforage.ready().then(() => {
  console.log("localForage полностью инициализирован");
});

Этот момент критичен в архитектуре приложений, где доступ к хранилищу требуется сразу после запуска. Игнорирование ready() приводит к гонкам состояния, особенно в сложных SPA, где модули могут обращаться к storage до завершения конфигурации.

Асинхронная природа ready() позволяет выстраивать гарантированную последовательность:

async function initStorage() {
  await localforage.ready();
  await localforage.setItem("boot", true);
}

Контроль выбранного драйвера

После инициализации важно понимать, какой драйвер был выбран системой автоматически. localForage использует приоритет:

  1. IndexedDB
  2. WebSQL
  3. localStorage

Фактический активный драйвер можно получить через:

console.log(localforage.driver());

Это значение позволяет диагностировать поведение приложения в разных окружениях. Например, в Safari приватного режима IndexedDB может быть недоступен, и система переключится на localStorage.


Принудительное назначение драйвера и проверка результата

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

localforage.setDriver([
  localforage.INDEXEDDB,
  localforage.LOCALSTORAGE
]).then(() => {
  console.log("Драйвер установлен");
});

Этот подход особенно важен при необходимости исключить WebSQL или обеспечить использование только IndexedDB.

Однако сам факт вызова setDriver не означает успешное применение. Проверка выполняется через комбинацию ready() и driver():

await localforage.setDriver([
  localforage.INDEXEDDB,
  localforage.LOCALSTORAGE
]);

await localforage.ready();

const activeDriver = localforage.driver();
if (activeDriver !== localforage.INDEXEDDB) {
  console.warn("Работа идет не через IndexedDB");
}

Создание изолированных экземпляров и их готовность

В приложениях с несколькими зонами хранения важно разделять конфигурации через createInstance. Каждый экземпляр имеет собственное состояние и собственный процесс инициализации.

const userStore = localforage.createInstance({
  name: "userData"
});

await userStore.ready();

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


Обработка ошибок и деградация функциональности

Готовность библиотеки включает не только успешную инициализацию, но и корректную обработку отказов. Ошибки могут возникать при:

  • блокировке IndexedDB
  • поврежденном профиле браузера
  • исчерпании квоты
  • запрещенных cookie / storage политиками

Пример обработки:

try {
  await localforage.setDriver([localforage.INDEXEDDB]);
  await localforage.ready();
} catch (err) {
  console.error("Ошибка инициализации storage:", err);
}

В таких случаях часто используется стратегия деградации, когда приложение автоматически переключается на более простой драйвер:

async function safeInit() {
  try {
    await localforage.setDriver([
      localforage.INDEXEDDB,
      localforage.LOCALSTORAGE
    ]);
    await localforage.ready();
  } catch {
    await localforage.setDriver(localforage.LOCALSTORAGE);
  }
}

Особенности проверки в SSR и Node-окружениях

localForage ориентирован на браузерную среду. При серверном рендеринге или выполнении в Node.js отсутствует доступ к IndexedDB и localStorage, поэтому проверка готовности должна учитывать наличие глобального объекта window.

const isBrowser = typeof window !== "undefined";

if (isBrowser) {
  await localforage.ready();
}

Без такой проверки попытка инициализации может приводить к ошибкам импорта или выполнению неподдерживаемых операций.


Синхронизация доступа перед первым использованием

Наиболее частая проблема — обращение к storage до завершения инициализации. Для устранения этого создаётся единая точка ожидания готовности:

const storageReady = localforage.ready();

export async function getStorageItem(key) {
  await storageReady;
  return localforage.getItem(key);
}

Такой подход устраняет множественные вызовы ready() и гарантирует, что все операции используют уже инициализированный драйвер.


Проверка устойчивости конфигурации

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

async function verifyStorage() {
  await localforage.ready();

  const driver = localforage.driver();
  const testKey = "__test__";

  await localforage.setItem(testKey, true);
  const value = await localforage.getItem(testKey);

  return value === true && driver != null;
}

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