Библиотека localForage построена вокруг идеи унифицированного асинхронного хранилища, которое скрывает различия между IndexedDB, WebSQL и localStorage. Одним из ключевых механизмов её архитектуры является поддержка нескольких независимых экземпляров, каждый из которых может иметь собственную конфигурацию и полностью изолированное пространство данных.
Изоляция в данном контексте означает невозможность пересечения ключей, настроек драйверов и внутреннего состояния между разными экземплярами, даже если они используются в одном и том же приложении и в рамках одного домена.
При подключении localForage создаётся дефолтный экземпляр, использующий глобальную конфигурацию:
name — имя базы данных (для IndexedDB)storeName — имя хранилищаdriver — приоритет используемых драйверовЭтот экземпляр является общим состоянием библиотеки и используется, если явно не создаются дополнительные экземпляры.
Ключевая особенность заключается в том, что изменение конфигурации
через config() влияет только на текущий глобальный
экземпляр и не затрагивает уже созданные изолированные экземпляры.
Механизм полной изоляции реализуется через метод
createInstance().
Каждый вызов формирует независимый объект со своей конфигурацией:
При использовании IndexedDB изоляция достигается через создание отдельной базы данных или отдельного object store внутри одной базы, в зависимости от параметров конфигурации.
Пример логики изоляции:
storeName: "cache"storeName: "session"Несмотря на использование одного и того же драйвера, данные физически разделены.
В IndexedDB изоляция достигается через комбинацию:
name)storeName)Каждый экземпляр формирует собственную логическую область хранения. Даже при совпадении ключей данные не пересекаются, так как принадлежат разным store.
Важно учитывать, что IndexedDB не допускает динамического изменения структуры object store без миграции версии базы, поэтому localForage управляет этим через внутренние версии и пересоздание соединений.
В WebSQL изоляция реализуется через:
Каждый экземпляр использует собственную таблицу или логическую сегментацию таблиц, что предотвращает коллизии ключей.
В localStorage отсутствует полноценная многобазовая модель, поэтому изоляция достигается через:
name + storeName + keyКаждый экземпляр формирует уникальный namespace, который добавляется к каждому ключу при записи и чтении данных.
Таким образом, даже при одинаковом ключе "user", данные
будут различаться:
appA_userappB_userОдним из ключевых аспектов изоляции является формирование уникального пространства ключей.
localForage использует внутренний механизм нормализации ключей, который включает:
name)storeName)В результате формируется составной идентификатор, исключающий пересечение данных между экземплярами.
Это особенно важно при использовании микрофронтендов, где несколько независимых приложений работают в одном origin.
Каждый экземпляр может иметь собственный приоритет драйверов:
Изоляция проявляется не только в данных, но и в выборе механизма хранения. Один экземпляр может работать исключительно через IndexedDB, тогда как другой — использовать localStorage как fallback.
Это приводит к различным характеристикам:
Каждый экземпляр localForage поддерживает собственное состояние:
Это означает, что операции одного экземпляра не блокируют и не влияют на другой, даже если физически они используют один и тот же backend.
При этом инициализация (ready()) выполняется отдельно
для каждого экземпляра, что исключает гонки состояний.
Один экземпляр используется для временного кэша:
Другой — для постоянных пользовательских данных:
Такое разделение позволяет безопасно очищать кэш без риска потери критических данных.
В модульных системах каждый модуль может иметь собственный экземпляр:
Каждый из них работает в своём namespace, не пересекаясь по ключам и структурам данных.
При работе нескольких независимых фронтенд-приложений в одном домене изоляция предотвращает:
Каждое приложение использует собственный
createInstance() с уникальным name.
Несмотря на встроенные механизмы, ошибки конфигурации могут приводить к пересечению данных:
name и storeName у разных
экземпляровОсобенно критичным является сценарий, когда несколько экземпляров используют один и тот же namespace, но ожидают независимого состояния.
Изоляция в localForage не является физической виртуализацией хранилища. Все экземпляры всё равно работают в рамках одного origin и подчиняются ограничениям браузера:
Поэтому изоляция гарантирует логическое разделение, но не физическое выделение ресурсов.
После создания экземпляра изменение конфигурации через
config() не влияет на уже существующие экземпляры. Это
обеспечивает стабильность поведения, но требует внимательного
проектирования:
Изоляция данных между экземплярами формируется за счёт нескольких уровней:
Комбинация этих уровней обеспечивает независимое поведение каждого
createInstance(), предотвращая пересечение данных и
позволяя строить модульные системы хранения внутри одного
приложения.