@kit-data-manager/pid-component
Version:
The PID-Component is a web component that can be used to evaluate and display FAIR Digital Objects, PIDs, ORCiDs, and possibly other identifiers in a user-friendly way. It is easily extensible to support other identifier types.
137 lines (136 loc) • 5.9 kB
JavaScript
/*!
*
* Copyright 2024 Karlsruhe Institute of Technology.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { Parser } from "./Parser";
import { renderers } from "./utils";
import { openDB } from "@tempfix/idb";
const dbName = 'pid-component';
const dbVersion = undefined;
export class Database {
constructor() {
this.dbPromise = openDB(dbName, dbVersion, {
upgrade(db) {
const entityStore = db.createObjectStore('entities', {
keyPath: 'value',
});
entityStore.createIndex('by-context', 'context', { unique: false });
const relationStore = db.createObjectStore('relations', {
autoIncrement: true,
});
relationStore.createIndex('by-start', 'start', { unique: false });
relationStore.createIndex('by-description', 'description', { unique: false });
relationStore.createIndex('by-end', 'end', { unique: false });
},
});
}
async addEntity(renderer) {
const context = document.documentURI;
const db = await this.dbPromise;
await db
.add('entities', {
value: renderer.value,
rendererKey: renderer.getSettingsKey(),
context: context,
lastAccess: new Date(),
lastData: renderer.data,
})
.catch(reason => {
if (reason.name === 'ConstraintError') {
console.debug('Entity already exists', reason);
}
else
console.error('Could not add entity', reason);
});
console.debug('added entity', renderer);
const tx = db.transaction('relations', 'readwrite');
const promises = [];
for (const item of renderer.items) {
const relation = {
start: renderer.value,
description: item.keyTitle,
end: item.value,
};
const index = tx.store.index('by-start');
let cursor = await index.openCursor();
while (cursor) {
if (cursor.value.start === relation.start && cursor.value.end === relation.end && cursor.value.description === relation.description) {
return;
}
cursor = await cursor.continue();
}
promises.push(tx.store.add(relation));
}
promises.push(tx.done);
await Promise.all(promises);
console.debug('added relations', promises);
}
async getEntity(value, settings) {
var _a, _b;
try {
const db = await this.dbPromise;
const entity = await db.get('entities', value);
if (entity !== undefined) {
console.debug('Found entity for value in db', entity, value);
const entitySettings = (_a = settings.find(value => value.type === entity.rendererKey)) === null || _a === void 0 ? void 0 : _a.values;
const ttl = entitySettings === null || entitySettings === void 0 ? void 0 : entitySettings.find(value => value.name === 'ttl');
if (ttl != undefined && ttl.value != undefined && (new Date().getTime() - entity.lastAccess.getTime() > ttl.value || ttl.value === 0)) {
console.log('TTL expired! Deleting entry in db', ttl.value, new Date().getTime() - entity.lastAccess.getTime());
await this.deleteEntity(value);
}
else {
console.log('TTL not expired or undefined', new Date().getTime() - entity.lastAccess.getTime());
const renderer = new (renderers.find(renderer => renderer.key === entity.rendererKey).constructor)(value, entitySettings);
renderer.settings = entitySettings;
await renderer.init(entity.lastData);
return renderer;
}
}
}
catch (error) {
console.error('Could not get entity from db', error);
}
console.debug('No valid entity found for value in db', value);
const renderer = await Parser.getBestFit(value, settings);
renderer.settings = (_b = settings.find(value => value.type === renderer.getSettingsKey())) === null || _b === void 0 ? void 0 : _b.values;
await renderer.init();
await this.addEntity(renderer);
console.debug('added entity to db', value, renderer);
return renderer;
}
async deleteEntity(value) {
const db = await this.dbPromise;
await db.delete('entities', value);
const tx = db.transaction('relations', 'readwrite');
const index = tx.store.index('by-start');
let cursor = await index.openCursor();
while (cursor) {
if (cursor.value.start === value || cursor.value.end === value) {
await tx.store.delete(cursor.primaryKey);
}
cursor = await cursor.continue();
}
console.log('deleted entity', value);
await tx.done;
}
async clearEntities() {
const db = await this.dbPromise;
await db.clear('entities');
await db.clear('relations');
console.log('cleared entities');
}
}
//# sourceMappingURL=IndexedDBUtil.js.map