Приоритет выбора драйвера по умолчанию

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

При инициализации создаётся список потенциальных драйверов. Каждый из них представляет собой отдельный адаптер к конкретному механизму хранения:

  • IndexedDB (асинхронное объектное хранилище)
  • WebSQL (устаревшая, но всё ещё встречающаяся реализация)
  • localStorage (синхронное ключ-значение хранилище)

Каждый драйвер содержит набор характеристик:

  • поддержка текущим браузером
  • асинхронная или синхронная модель доступа
  • ограничения по объёму данных
  • особенности сериализации

Процесс выбора начинается с проверки доступности API в глобальном контексте браузера. Однако наличие API не означает его пригодность: драйвер должен пройти дополнительную валидацию через тестовую запись и чтение.

Последовательность приоритета и её смысл

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

Первым кандидатом обычно выступает IndexedDB. Причины приоритета:

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

Если IndexedDB недоступен или работает нестабильно, происходит переход к следующему уровню.

WebSQL рассматривается как промежуточный вариант. Несмотря на де-факто устаревание стандарта, он всё ещё присутствует в некоторых WebView и старых версиях браузеров. Его особенности:

  • SQL-подобный интерфейс
  • синхронность внутри транзакций (в реализации браузеров — частично асинхронная обёртка)
  • ограниченная поддержка платформами

При отсутствии WebSQL используется localStorage как последний fallback-вариант. Его характеристики существенно отличаются:

  • синхронный доступ к данным
  • ограничение по объёму (обычно около 5–10 МБ)
  • хранение только строковых значений
  • блокировка UI-потока при операциях записи и чтения

Такой порядок отражает компромисс: от наиболее современного и масштабируемого к максимально совместимому, но ограниченному варианту.

Механизм автоматического тестирования драйверов

Каждый драйвер проходит проверку на корректность работы. Она включает несколько этапов:

  1. Инициализация хранилища
  2. Запись тестового значения
  3. Чтение записанного значения
  4. Сравнение результата с исходными данными
  5. Удаление тестового ключа

Если хотя бы один этап завершается ошибкой, драйвер считается неподходящим и исключается из цепочки выбора.

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

Роль конфигурации и переопределения порядка

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

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

Такой подход используется в специфических сценариях:

  • работа в ограниченных WebView
  • отладка поведения приложения
  • обеспечение предсказуемости поведения в старых окружениях

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

Асинхронная и синхронная природа драйверов

Выбор драйвера напрямую влияет на модель выполнения операций.

IndexedDB и WebSQL реализуют асинхронное поведение. Это означает:

  • операции не блокируют основной поток
  • используется Promise-подобная модель
  • возможна параллельная работа с несколькими транзакциями

localStorage, напротив, работает синхронно:

  • каждая операция блокирует выполнение JavaScript
  • отсутствует механизм транзакций
  • данные сериализуются в строковый формат

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

Поведение при частичной поддержке API

Существуют браузеры, где API формально присутствует, но работает с ограничениями. Это может выражаться в следующих сценариях:

  • IndexedDB доступен, но квота хранения равна нулю
  • транзакции завершаются с непредсказуемыми ошибками
  • WebSQL доступен, но не поддерживает запись больших объектов
  • localStorage ограничен политиками приватного режима

В таких случаях драйвер может быть технически “обнаружен”, но не проходит тестовую проверку. Это приводит к автоматическому понижению приоритета и переходу к следующему варианту.

Система fallback-цепочки

Логика выбора формирует цепочку fallback-уровней. Она функционирует как последовательный обход:

IndexedDB → WebSQL → localStorage

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

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

Влияние createInstance на выбор драйвера

Создание отдельного экземпляра хранилища приводит к независимому процессу определения драйвера. Каждый экземпляр:

  • выполняет собственную проверку окружения
  • может иметь индивидуальный порядок приоритетов
  • изолирует настройки от глобальной конфигурации

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

Поведение в приватных режимах браузеров

В некоторых браузерах приватный режим накладывает ограничения на IndexedDB и WebSQL. В таких случаях:

  • API может существовать, но возвращать ошибки при записи
  • квоты памяти резко уменьшаются
  • данные могут очищаться после закрытия сессии

Алгоритм приоритета учитывает эти сценарии через тестовую запись. Если проверка завершается неуспешно, происходит переход к localStorage, несмотря на его ограничения.

Стабильность выбранного драйвера

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

Это обеспечивает:

  • предсказуемость поведения
  • отсутствие миграции данных в рантайме
  • снижение риска потери информации при переключении API

Изменение драйвера возможно только через явный вызов переинициализации экземпляра.

Влияние сериализации на выбор

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

Это означает, что при использовании localStorage накладываются дополнительные расходы:

  • преобразование объектов в JSON
  • обратная десериализация при чтении
  • потенциальные ошибки при циклических структурах

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

Поведение при отсутствии всех драйверов

В крайне редких случаях ни один механизм хранения не проходит проверку. Это может происходить в:

  • строго ограниченных окружениях
  • тестовых средах без storage API
  • повреждённых браузерных конфигурациях

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

Итоговая логика принятия решения

Процесс выбора драйвера представляет собой последовательную систему фильтрации, основанную на трёх ключевых принципах:

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

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