Инициализация хранилища в localForage начинается не с непосредственного открытия базы данных, а с построения цепочки выбора драйвера, конфигурации экземпляра и подготовки параметров будущего соединения. Важная особенность архитектуры заключается в том, что момент «открытия базы» откладывается до первого обращения к API, что позволяет минимизировать накладные расходы при создании экземпляра.
Каждый экземпляр localForage связан с набором параметров, определяющих контекст хранения:
Создание экземпляра через createInstance не инициирует
обращение к IndexedDB или другим механизмам хранения. Вместо этого
формируется изолированный конфиг, который позднее используется при
ленивом открытии.
Ключевой момент заключается в том, что разные экземпляры localForage
изолируются через комбинацию name + storeName. Это
позволяет им существовать параллельно без конфликтов ключей, даже если
они используют один и тот же драйвер.
Перед открытием базы выполняется последовательный перебор доступных
драйверов. Порядок определяется конфигурацией driver:
Каждый драйвер обязан реализовывать метод проверки совместимости
_support. Он выполняется синхронно или асинхронно и
возвращает подтверждение возможности использования хранилища в текущей
среде.
Если первый драйвер в списке не проходит проверку, происходит переход к следующему. Этот процесс продолжается до тех пор, пока не будет найден подходящий вариант или не будут исчерпаны все возможности.
Фактическое открытие происходит при первом вызове операций
getItem, setItem или аналогичных методов. В
этот момент запускается процедура инициализации драйвера.
_initStorageПосле завершения инициализации последующие вызовы используют уже существующее соединение, что исключает повторные затраты на открытие базы.
Наиболее сложный процесс происходит при использовании
IndexedDB-драйвера. Здесь localForage опирается на стандартный механизм
indexedDB.open, где версия базы играет ключевую роль.
При открытии выполняется:
config.nameindexedDB.open(name, version)Если версия базы, указанная в запросе, выше существующей, браузер
инициирует событие onupgradeneeded. Именно в этом
обработчике происходит создание object store.
config.storeNamekeyPath: 'key' или
аналогичная структура)После завершения upgrade соединение считается готовым к работе и передается в кэш драйвера.
localForage не реализует сложную доменную систему миграций поверх IndexedDB. Версионирование ограничивается уровнем:
Изменение структуры данных не сопровождается автоматическими
миграциями пользовательских данных. Повышение версии базы влияет только
на возможность изменения схемы object store в
onupgradeneeded.
Это означает, что:
В случае WebSQL открытие базы происходит через
openDatabase, где также присутствует версия. Однако
механика обновления отличается:
onupgradeneededlocalForage использует упрощённый слой абстракции, где таблица создается при первом обращении, если она отсутствует. Версионирование носит декларативный характер и не управляет миграциями.
localStorage не предоставляет встроенной модели баз данных, поэтому версия реализуется косвенно. В localForage это выражается через:
Версионность в этом контексте становится логической, а не технической. Изменения структуры данных требуют ручного контроля через изменение ключей или очистку пространства.
Так как открытие базы является асинхронным процессом, localForage использует внутреннюю очередь операций. Любой вызов до завершения инициализации:
Это предотвращает гонки состояний, особенно в IndexedDB, где операции могут быть отклонены при отсутствии активной транзакции.
После успешного открытия драйвера создается кэш:
openЭтот механизм существенно снижает накладные расходы при частых обращениях к хранилищу.
Каждый экземпляр localForage имеет собственный контекст:
Это означает, что разные экземпляры не разделяют соединение IndexedDB, даже если используют одинаковые параметры. Каждое имя базы приводит к отдельному физическому хранилищу.
Если ни один драйвер не проходит проверку _support,
процесс инициализации завершается ошибкой. Типичные причины:
В нормальном сценарии происходит деградация до более простого хранилища, но при полном отсутствии поддержки выполнение операций становится невозможным.
Если драйвер уже открыт, повторный вызов инициализации игнорируется. Однако изменение конфигурации после первого обращения не влияет на текущее соединение. Для применения новых параметров требуется создание нового экземпляра.
Версионная логика при этом не пересчитывается, так как она
фиксируется в момент первого open.