@idxdb/promised
Version:
@idxdb/promised wraps the IndexedDB API. It allows you to easily store and retrieve data in an indexed db database using async/await syntax, making it easier to integrate with your existing codebase.
100 lines (99 loc) • 4.09 kB
JavaScript
import { Transaction } from './component/transaction.js';
import { Database } from './component/database.js';
export class DatabaseFactory {
static _factory;
static factory = () => {
if (this._factory) {
return this._factory;
}
/* istanbul ignore next */
this._factory =
globalThis.indexedDB ||
globalThis.mozIndexedDB ||
globalThis.webkitIndexedDB ||
globalThis.msIndexedDB;
/* istanbul ignore next */
if (!this._factory) {
throw new Error('IndexedDB is not supported in your environment');
}
return this._factory;
};
static cmp(a, b) {
return this.factory().cmp(a, b);
}
static databases() {
return this.factory().databases();
}
static deleteDatabase(name) {
return new Promise((resolve, reject) => {
const request = this.factory().deleteDatabase(name);
request.addEventListener('success', () => {
resolve();
});
/* istanbul ignore next */
request.addEventListener('blocked', () => {
reject('blocked');
});
/* istanbul ignore next */
request.addEventListener('error', (event) => {
const target = event.target;
reject(target.error);
});
});
}
static open(name, version = 1, migrations = [], onBlocked) {
return new Promise((resolve, reject) => {
const request = this.factory().open(name, version);
request.addEventListener('success', (event) => {
const target = event.target;
resolve(new Database({ db: target.result }));
});
/* istanbul ignore next */
request.addEventListener('error', (event) => {
const target = event.target;
reject(target.error);
});
request.addEventListener('blocked', async (event) => {
const oldVersion = event.oldVersion;
const newVersion = event.newVersion;
if (!onBlocked) {
const error = new Error(`You are not allowed to upgrade the database when it is already active. Prevented from reopening the ${name} database in version ${newVersion} when the current version is ${oldVersion}.`);
reject(error);
return;
}
onBlocked({ oldVersion, newVersion })
.then((result) => {
reject(result);
})
.catch((error) => {
reject(error);
});
});
request.addEventListener('upgradeneeded', async (event) => {
const target = event.target;
const db = target.result;
const transaction = target.transaction;
migrations = migrations.sort((a, b) => a.version - b.version);
for (const migration of migrations) {
if (event.oldVersion < migration.version &&
migration.version <= version) {
/* istanbul ignore next */
const handleReject = (event) => {
const target = event.target;
reject(target.error);
};
db.addEventListener('error', handleReject);
await migration.migration({
db: new Database({ db }),
transaction: new Transaction({ transaction }),
dbOldVersion: event.oldVersion,
dbNewVersion: event.newVersion,
migrationVersion: migration.version,
});
db.removeEventListener('error', handleReject);
}
}
});
});
}
}