Библиотека localForage строится вокруг отложенной инициализации хранилища. Внутри она выбирает подходящий драйвер (IndexedDB, WebSQL или localStorage), создаёт пространство хранения и кэширует выбранную конфигурацию. Именно поэтому момент вызова конфигурации критически влияет на поведение всей системы.
До выполнения первой операции чтения или записи localForage находится в состоянии ленивой подготовки. В этот период происходит:
Любое изменение конфигурации после запуска этого процесса уже не всегда приводит к переинициализации внутреннего состояния.
Метод config задаёт глобальные параметры экземпляра
localForage, которые используются при создании драйвера и формировании
пространства хранения:
name — имя базы данных;storeName — имя хранилища внутри базы;version — версия структуры (актуально преимущественно
для IndexedDB);driver — приоритетный список драйверов.Эти параметры участвуют в формировании ключевых идентификаторов хранилища и влияют на:
После инициализации драйвера многие из этих параметров становятся частью уже созданного контекста и перестают быть динамически изменяемыми.
localForage использует ленивую стратегию: реальная инициализация
происходит при первом вызове любой операции (setItem,
getItem, keys и т.д.). До этого момента
конфигурация ещё может быть учтена в полном объёме.
После первого обращения запускается цепочка:
Если config вызывается после этого этапа, поведение
зависит от внутреннего состояния драйвера:
Таким образом, граница между «до» и «после» первой операции фактически определяет валидность конфигурации.
Изменение конфигурации после начала работы приводит к ряду неочевидных эффектов:
Если изменяется name или storeName,
логически ожидается переключение на другое хранилище. Однако уже
созданный драйвер продолжает работать с ранее инициализированной базой,
что приводит к ситуации, когда:
При изменении driver после инициализации переключение
может не произойти без явного пересоздания внутреннего адаптера. В
результате:
Параметр version особенно чувствителен в IndexedDB. Он
влияет на схему базы и триггер обновления структуры. При позднем
изменении:
После первой операции localForage сохраняет:
Этот кэш делает работу быстрой, но одновременно фиксирует
конфигурационные решения. Повторный вызов config не
приводит к пересборке всех компонентов, потому что это нарушило бы
стабильность соединений и могло бы привести к потере данных.
Поэтому архитектурно localForage ориентирован на «конфигурацию до старта работы», а не на динамическую перенастройку.
В современных JavaScript-приложениях localForage часто импортируется как единый singleton:
В таких условиях порядок исполнения модулей становится критически важным фактором.
Если один модуль вызывает setItem раньше, чем другой
модуль успевает выполнить config, происходит следующая
ситуация:
config не меняют уже активный
контекст;localForage работает асинхронно, но конфигурация — синхронная операция. Это создаёт потенциальные гонки:
config;getItem;В результате возникает состояние, при котором:
Такие ситуации особенно характерны для приложений с ленивой загрузкой модулей.
В архитектурно сложных приложениях localForage часто оборачивается в отдельный слой инициализации. Причина в том, что централизованное управление конфигурацией позволяет зафиксировать момент её применения до любых операций с данными.
При отсутствии такого слоя конфигурация может быть разнесена по разным частям системы, что приводит к:
В тестовых средах порядок вызова конфигурации приобретает дополнительное значение:
Особенно чувствительно это проявляется при параллельном запуске тестов, где разные конфигурации пересекаются в одном процессе.
Повторные вызовы config не эквивалентны повторной
инициализации библиотеки. Они:
Таким образом, конфигурация в localForage носит характер «одноразового контракта» перед стартом работы, а не динамического управления состоянием.