Skip to content

Instantly share code, notes, and snippets.

@lichrot
Last active February 26, 2024 14:20
Show Gist options
  • Save lichrot/bdb22fc8a535ad4d934362a82c3e62e4 to your computer and use it in GitHub Desktop.
Save lichrot/bdb22fc8a535ad4d934362a82c3e62e4 to your computer and use it in GitHub Desktop.
Quick-n-dirty IDBFactory.prototype.databases (a.k.a. indexedDB.databases) polyfill for Firefox to get all the IndexedDB database names
if (!globalThis.IDBFactory.prototype.databases) {
const KEY = 'IDB_DATABASES_POLYFILL';
globalThis.IDBFactory.prototype.databases = function databases() {
const serialized = globalThis.localStorage.getItem(KEY);
return Promise.resolve(serialized ? JSON.parse(serialized) : []);
};
const listener = async (event) => {
const { name, version } = event.target.result;
const entries = await globalThis.indexedDB.databases();
const foundEntry = entries.find((entry) => entry.name === name);
if (!foundEntry) entries.push({ name, version });
else foundEntry.version = version;
globalThis.localStorage.setItem(KEY, JSON.stringify(entries));
};
const boundOpen = globalThis.indexedDB.open.bind(globalThis.indexedDB);
globalThis.indexedDB.open = function open(name, version) {
const request = boundOpen(name, version);
request.addEventListener('success', listener);
return request;
};
const boundDeleteDatabase = globalThis.indexedDB.deleteDatabase.bind(globalThis.indexedDB);
globalThis.indexedDB.deleteDatabase = function deleteDatabase(name) {
const request = boundDeleteDatabase(name);
request.addEventListener('success', async () => {
const entries = await globalThis.indexedDB.databases();
const idx = entries.findIndex((entry) => entry.name === name);
if (idx === -1) return;
entries.splice(idx, 1);
globalThis.localStorage.setItem(KEY, JSON.stringify(entries));
});
return request;
};
}
if (!globalThis.IDBFactory.prototype.databases) {
const KEY = 'IDB_DATABASES_POLYFILL';
globalThis.IDBFactory.prototype.databases = function databases(): Promise<IDBDatabaseInfo[]> {
const serialized = globalThis.localStorage.getItem(KEY);
return Promise.resolve(serialized ? JSON.parse(serialized) : []);
};
const listener = (async (event: Event & { target: IDBOpenDBRequest }) => {
const { name, version } = event.target.result;
const entries = await globalThis.indexedDB.databases();
const foundEntry = entries.find((entry) => entry.name === name);
if (!foundEntry) entries.push({ name, version });
else foundEntry.version = version;
globalThis.localStorage.setItem(KEY, JSON.stringify(entries));
}) as (event: Event) => Promise<void>;
const boundOpen = globalThis.indexedDB.open.bind(globalThis.indexedDB);
globalThis.indexedDB.open = function open(name: string, version?: number): IDBOpenDBRequest {
const request = boundOpen(name, version);
request.addEventListener('success', listener);
return request;
};
const boundDeleteDatabase = globalThis.indexedDB.deleteDatabase.bind(globalThis.indexedDB);
globalThis.indexedDB.deleteDatabase = function deleteDatabase(name: string): IDBOpenDBRequest {
const request = boundDeleteDatabase(name);
request.addEventListener('success', async () => {
const entries = await globalThis.indexedDB.databases();
const idx = entries.findIndex((entry) => entry.name === name);
if (idx === -1) return;
entries.splice(idx, 1);
globalThis.localStorage.setItem(KEY, JSON.stringify(entries));
});
return request;
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment