Библиотека localForage предоставляет унифицированный API поверх нескольких механизмов хранения данных в браузере. Основные драйверы включают IndexedDB, WebSQL (устаревший, но всё ещё поддерживаемый в некоторых средах) и localStorage как fallback. Ключевая особенность архитектуры заключается в том, что логический слой хранения отделён от физического механизма, что позволяет динамически переключать драйверы.
Каждый драйвер использует собственный формат хранения, собственные ограничения по объёму и особенности сериализации. Именно это становится источником потенциальной потери данных при смене драйвера.
Каждый драйвер использует независимое хранилище:
При смене драйвера localForage не выполняет автоматическую миграцию данных между этими системами. Фактически происходит переключение на другое «пространство данных», где прежние ключи могут отсутствовать.
При вызове:
localforage.setDriver([
localforage.INDEXEDDB,
localforage.LOCALSTORAGE
]);
или:
localforage.setDriver(localforage.LOCALSTORAGE);
библиотека лишь перенастраивает слой доступа. Содержимое предыдущего драйвера:
Это приводит к эффекту «пустого хранилища» после переключения.
localForage сериализует данные в зависимости от драйвера:
Если данные были записаны в одном формате, а затем происходит смена драйвера, возможны следующие проблемы:
null или undefined при
чтенииТипичный сценарий:
В этом случае данные, записанные в fallback-драйвере, остаются в localStorage и не переносятся обратно.
В некоторых браузерах приватный режим:
localForage автоматически переключается на доступный драйвер. При выходе из инкогнито режим может измениться, но данные останутся разрозненными между хранилищами.
localForage работает асинхронно. Возможна ситуация:
setDriverЭто приводит к состоянию гонки, когда:
Вызовы вида:
localforage.config({
driver: localforage.INDEXEDDB
});
после уже выполненных операций могут привести к:
localForage поддерживает цепочку драйверов:
localforage.setDriver([
localforage.INDEXEDDB,
localforage.WEBSQL,
localforage.LOCALSTORAGE
]);
При этом:
Проблема возникает, если:
Каждый драйвер имеет собственное изолированное пространство ключей. Даже при одинаковой конфигурации:
"user" в IndexedDB не связан с "user"
в localStorageЭто приводит к эффекту «исчезновения данных», хотя фактически они остаются в старом хранилище.
IndexedDB может быть недоступен в следующих случаях:
localForage при этом автоматически переключается на fallback. Если запись происходила до падения, данные оказываются в IndexedDB, но чтение идёт из localStorage, создавая видимость потери.
При изменении логики приложения:
Старые данные могут:
localForage не включает автоматические механизмы:
Единственный уровень абстракции — единый API, а не единое физическое хранилище.
После выбора стабильного драйвера переключение в runtime создаёт риск рассинхронизации состояния. Использование фиксированного драйвера снижает вероятность расхождения данных между средами выполнения.
При необходимости смены драйвера требуется ручной процесс:
localForage предоставляет методы:
iteratekeysgetItemsetItemкоторые позволяют реализовать перенос данных на уровне приложения.
Инициализация:
localforage.setDriver([...])
должна завершаться до начала операций записи. В противном случае возможно расхождение между выбранным драйвером и фактическим местом записи.
Разделение логики хранения по средам:
позволяет избежать смешивания данных между несовместимыми драйверами.
При переходе на другой драйвер типичны следующие эффекты:
getItem(key) возвращает nulllength() резко уменьшаетсяkeys() возвращает пустой массивЭто состояние часто ошибочно интерпретируется как удаление данных, хотя фактически происходит смена контекста доступа.
Основной источник проблемы — различие в моделях хранения:
localForage не унифицирует их физически, а только логически. Поэтому смена драйвера равносильна смене базы данных без миграции схемы.
Вызов setDriver:
Это создаёт окно состояния, в котором часть операций выполняется в старом драйвере, а часть — в новом, что усиливает риск расхождения данных.
Потеря данных при смене драйвера возникает из комбинации факторов:
Эта совокупность формирует состояние, при котором данные не уничтожаются, но становятся недоступными в новом контексте доступа.