Skip to content

Commit

Permalink
refactor(core/biblio-db): Move from indexedDB to idb (#2228)
Browse files Browse the repository at this point in the history
* Starting to refactor

* fix requirejs error

* Fixed issue with tests, refactoring completed

* lint fix

* fix idb import on xref

* Apply suggested corrections

* async and lint fixes

* Removed redundant promises

* Applied suggested changes

* lint fix

* karma test workaround

* use new importIdb()

* return await
  • Loading branch information
Swapnilr1 authored and saschanaz committed Aug 3, 2019
1 parent e086ddd commit f05ad79
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 142 deletions.
176 changes: 45 additions & 131 deletions src/core/biblio-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,63 +8,27 @@
*
*/
import { flatten } from "./utils.js";
import { importIdb } from "./idb.js";
import { pub } from "./pubsubhub.js";
export const name = "core/biblio-db";

const ALLOWED_TYPES = new Set(["alias", "reference"]);
/**
* Database initialization tracker
* @type {Promise<IDBDatabase>}
*/
const readyPromise = new Promise((resolve, reject) => {
let request;
try {
request = window.indexedDB.open("respec-biblio2", 12);
} catch (err) {
return reject(err);
}
request.onerror = () => {
reject(new DOMException(request.error.message, request.error.name));
};
request.onsuccess = () => {
resolve(request.result);
};
request.onupgradeneeded = async () => {
const db = request.result;
Array.from(db.objectStoreNames).map(storeName =>
db.deleteObjectStore(storeName)
);
const promisesToCreateSchema = [
new Promise((resolve, reject) => {
try {
const store = db.createObjectStore("alias", { keyPath: "id" });
store.createIndex("aliasOf", "aliasOf", { unique: false });
store.transaction.oncomplete = resolve;
store.transaction.onerror = reject;
} catch (err) {
reject(err);
}
}),
new Promise((resolve, reject) => {
try {
const transaction = db.createObjectStore("reference", {
keyPath: "id",
}).transaction;
transaction.oncomplete = resolve;
transaction.onerror = reject;
} catch (err) {
reject(err);
}
}),
];
try {
await Promise.all(promisesToCreateSchema);
resolve();
} catch (err) {
reject(err);
}
};
});
/* Database initialization tracker */
const readyPromise = openIdb();

async function openIdb() {
const { openDB } = await importIdb();
return await openDB("respec-biblio2", 12, {
upgrade(db) {
Array.from(db.objectStoreNames).map(storeName =>
db.deleteObjectStore(storeName)
);
const store = db.createObjectStore("alias", { keyPath: "id" });
store.createIndex("aliasOf", "aliasOf", { unique: false });
db.createObjectStore("reference", { keyPath: "id" });
},
});
}

export const biblioDB = {
get ready() {
Expand All @@ -81,7 +45,7 @@ export const biblioDB = {
if (await this.isAlias(id)) {
id = await this.resolveAlias(id);
}
return this.get("reference", id);
return await this.get("reference", id);
},
/**
* Checks if the database has an id for a given type.
Expand All @@ -98,17 +62,10 @@ export const biblioDB = {
throw new TypeError("id is required");
}
const db = await this.ready;
return new Promise((resolve, reject) => {
const objectStore = db.transaction([type], "readonly").objectStore(type);
const range = IDBKeyRange.only(id);
const request = objectStore.openCursor(range);
request.onsuccess = () => {
resolve(!!request.result);
};
request.onerror = () => {
reject(new DOMException(request.error.message, request.error.name));
};
});
const objectStore = db.transaction([type], "readonly").objectStore(type);
const range = IDBKeyRange.only(id);
const result = await objectStore.openCursor(range);
return !!result;
},
/**
* Checks if a given id is an alias.
Expand All @@ -121,19 +78,12 @@ export const biblioDB = {
throw new TypeError("id is required");
}
const db = await this.ready;
return new Promise((resolve, reject) => {
const objectStore = db
.transaction(["alias"], "readonly")
.objectStore("alias");
const range = IDBKeyRange.only(id);
const request = objectStore.openCursor(range);
request.onsuccess = () => {
resolve(!!request.result);
};
request.onerror = () => {
reject(new DOMException(request.error.message, request.error.name));
};
});
const objectStore = db
.transaction(["alias"], "readonly")
.objectStore("alias");
const range = IDBKeyRange.only(id);
const result = await objectStore.openCursor(range);
return !!result;
},
/**
* Resolves an alias to its corresponding reference id.
Expand All @@ -146,22 +96,13 @@ export const biblioDB = {
throw new TypeError("id is required");
}
const db = await this.ready;
return new Promise((resolve, reject) => {
const objectStore = db
.transaction("alias", "readonly")
.objectStore("alias");
const range = IDBKeyRange.only(id);
const request = objectStore.openCursor(range);
request.onsuccess = () => {
if (request.result === null) {
return resolve(null);
}
resolve(request.result.value.aliasOf);
};
request.onerror = () => {
reject(new DOMException(request.error.message, request.error.name));
};
});

const objectStore = db
.transaction("alias", "readonly")
.objectStore("alias");
const range = IDBKeyRange.only(id);
const result = await objectStore.openCursor(range);
return result ? result.value.aliasOf : result;
},
/**
* Get a reference or alias out of the database.
Expand All @@ -178,20 +119,10 @@ export const biblioDB = {
throw new TypeError("id is required");
}
const db = await this.ready;
return new Promise((resolve, reject) => {
const objectStore = db.transaction([type], "readonly").objectStore(type);
const range = IDBKeyRange.only(id);
const request = objectStore.openCursor(range);
request.onsuccess = () => {
if (request.result === null) {
return resolve(null);
}
resolve(request.result.value);
};
request.onerror = () => {
reject(new DOMException(request.error.message, request.error.name));
};
});
const objectStore = db.transaction([type], "readonly").objectStore(type);
const range = IDBKeyRange.only(id);
const result = await objectStore.openCursor(range);
return result ? result.value : result;
},
/**
* Adds references and aliases to database. This is usually the data from
Expand Down Expand Up @@ -253,15 +184,9 @@ export const biblioDB = {
}
const db = await this.ready;
const isInDB = await this.has(type, details.id);
return new Promise((resolve, reject) => {
const store = db.transaction([type], "readwrite").objectStore(type);
// update or add, depending of already having it in db
const request = isInDB ? store.put(details) : store.add(details);
request.onsuccess = resolve;
request.onerror = () => {
reject(new DOMException(request.error.message, request.error.name));
};
});
const store = db.transaction([type], "readwrite").objectStore(type);
// update or add, depending of already having it in db
return isInDB ? await store.put(details) : await store.add(details);
},
/**
* Closes the underlying database.
Expand All @@ -279,21 +204,10 @@ export const biblioDB = {
async clear() {
const db = await this.ready;
const storeNames = [...ALLOWED_TYPES];
const stores = await new Promise((resolve, reject) => {
const transaction = db.transaction(storeNames, "readwrite");
transaction.onerror = () => {
reject(
new DOMException(transaction.error.message, transaction.error.name)
);
};
resolve(transaction);
});
const stores = await db.transaction(storeNames, "readwrite");
const clearStorePromises = storeNames.map(name => {
return new Promise(resolve => {
const request = stores.objectStore(name).clear();
request.onsuccess = resolve;
});
return stores.objectStore(name).clear();
});
Promise.all(clearStorePromises);
await Promise.all(clearStorePromises);
},
};
10 changes: 10 additions & 0 deletions src/core/idb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Temporary workaround until browsers get import-maps
*/
export async function importIdb() {
try {
return await import("idb");
} catch {
return await import("../../node_modules/idb/build/esm/index.js");
}
}
12 changes: 1 addition & 11 deletions src/core/xref-db.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @ts-check
import { IDBKeyVal } from "./utils.js";
import { importIdb } from "./idb.js";

/**
* @typedef {import('core/xref').RequestEntry} RequestEntry
Expand All @@ -9,17 +10,6 @@ import { IDBKeyVal } from "./utils.js";

const CACHE_MAX_AGE = 86400000; // 24 hours

/**
* Temporary workaround until browsers get import-maps
*/
async function importIdb() {
try {
return await import("idb");
} catch {
return await import("../../node_modules/idb/build/esm/index.js");
}
}

async function getIdbCache() {
const { openDB } = await importIdb();
const idb = await openDB("xref", 1, {
Expand Down

0 comments on commit f05ad79

Please sign in to comment.