IndexedDB — это встроенное хранилище в браузерах, предоставляющее возможность сохранять большие объемы структурированных данных на стороне клиента. Оно работает асинхронно и поддерживает транзакции, что делает его удобным для сложных веб-приложений. Однако при попытке использовать IndexedDB вне браузера, например в Node.js или при тестировании с помощью Jest, возникают серьёзные ограничения и специфические проблемы.
Node.js изначально не поддерживает API браузерного IndexedDB. Любой
прямой вызов функций, таких как indexedDB.open(), приведёт
к ошибке, так как объект indexedDB не существует в среде
сервера. Это ограничение создаёт препятствия для библиотек, построенных
на IndexedDB, включая idb-keyval, которая использует
IndexedDB для хранения ключ-значение пар.
Чтобы обойти эту проблему, применяются эмуляторы IndexedDB, такие как:
fake-indexeddb — реализует интерфейс IndexedDB в
Node.js.fake-indexeddb/lib/FDBFactory — предоставляет фабрику
для создания экземпляров базы данных.Пример подключения fake-indexeddb в Node.js:
const FDBFactory = require('fake-indexeddb/lib/FDBFactory');
global.indexedDB = new FDBFactory();
После этой настройки библиотека idb-keyval может
работать так, как будто она находится в браузере, используя глобальный
объект indexedDB.
При тестировании с Jest добавляются дополнительные нюансы:
onsuccess / onerror.Для стабильной работы рекомендуется:
// jest.setup.js
const FDBFactory = require('fake-indexeddb/lib/FDBFactory');
global.indexedDB = new FDBFactory();
И в jest.config.js указать:
setupFiles: ["<rootDir>/jest.setup.js"]
Это гарантирует, что перед запуском тестов indexedDB
будет доступен и idb-keyval сможет корректно сохранять и извлекать
данные.
Библиотека idb-keyval построена поверх IndexedDB и предоставляет простой API для операций ключ-значение. Основные функции:
set(key, value) — сохраняет значение по ключу.get(key) — извлекает значение по ключу.del(key) — удаляет значение по ключу.clear() — очищает всю базу.keys() — возвращает список всех ключей.Пример работы с idb-keyval в Node.js с использованием
fake-indexeddb:
const { set, get, del, keys } = require('idb-keyval');
const FDBFactory = require('fake-indexeddb/lib/FDBFactory');
global.indexedDB = new FDBFactory();
async function testStorage() {
await set('name', 'NodeJS');
const value = await get('name');
console.log(value); // NodeJS
await del('name');
const remainingKeys = await keys();
console.log(remainingKeys); // []
}
testStorage();
IndexedDB работает с транзакциями, которые асинхронны. В Node.js через fake-indexeddb эти транзакции симулируются, но с некоторыми ограничениями:
get после set в одном блоке может
потребовать дополнительного await.onerror и
onsuccess также может отличаться от поведения в
браузере.async/await или
done коллбэки.await результаты.fake-indexeddb.indexedDB.async/await.Эта схема позволяет использовать все возможности idb-keyval в среде Node.js и при автоматизированном тестировании с Jest, не сталкиваясь с ограничениями браузерного IndexedDB.