// interface MyJsonObject { // id: string; // name: string; // email: string; // } // Efficiently storing data in indexdb: https://stackoverflow.com/a/62975917 const postStoreName = "posts"; const tombStoneStoreName = "tombstones"; const followingStoreName = "following"; let keyBase = "dandelion_posts_v1_"; let key = ""; let version = 1; function upgrade_0to1(db) { let postsStore = db.createObjectStore(postStoreName, { keyPath: "id", autoIncrement: true }); postsStore.createIndex("datetimeIndex", "post_timestamp", { unique: false }); postsStore.createIndex("postIDIndex", "data.post_id", { unique: true }); } function upgrade_1to2(db) { let followingStore = db.createObjectStore(followingStoreName, { keyPath: "id", autoIncrement: true }); } let upgrades = new Map([ [0, upgrade_0to1], [1, upgrade_1to2] ]); export function openDatabase(userID) { const dbName = `user_${userID}`; return new Promise((resolve, reject) => { const request = indexedDB.open(dbName, version); request.onerror = (event) => { const errorEvent = event; reject(`Database error: ${errorEvent.target.error?.message}`); }; request.onupgradeneeded = (event) => { const db = event.target.result; let upgradeFunction = upgrades.get(event.oldVersion); if (!upgradeFunction) { throw new Error(`db: Don't have an upgrade function to go from version ${event.oldVersion} to version ${event.newVersion}`); } upgradeFunction(db); }; request.onsuccess = (event) => { const db = event.target.result; resolve(db); }; }); } async function getDBTransactionStore(userID, mode = "readonly") { const db = await openDatabase(userID); const transaction = db.transaction(postStoreName, mode); const store = transaction.objectStore(postStoreName); return { db, transaction, store }; } export async function addData(userID, data) { try { const { db, transaction, store } = await getDBTransactionStore(userID, "readwrite"); const addRequest = store.add({ post_timestamp: data.post_timestamp, data: data }); addRequest.onsuccess = (e) => { // console.log('Data has been added:', (e.target as IDBRequest).result); }; addRequest.onerror = (event) => { // Use a type assertion to access the specific properties of IDBRequest error event const errorEvent = event; console.error('Error in adding data:', errorEvent.target.error?.message); }; } catch (error) { console.error('Error in opening database:', error); } } export async function deleteData(userID, postID) { try { const { db, transaction, store } = await getDBTransactionStore(userID, "readwrite"); const index = store.index("postIDIndex"); const getRequest = index.getKey(postID); getRequest.onerror = e => console.log(e.target.error); getRequest.onsuccess = e => { const key = e.target.result; if (key === undefined) { console.error("Post not found"); return null; } const deleteRequest = store.delete(key); deleteRequest.onerror = e => { console.error(e.target.error); return false; }; deleteRequest.onsuccess = () => true; }; } catch (error) { console.error('Error in opening database:', error); } } export async function clearData(userID) { try { const { db, transaction, store } = await getDBTransactionStore(userID, "readwrite"); const clearRequest = store.clear(); clearRequest.onsuccess = (e) => { // console.log('Data has been added:', (e.target as IDBRequest).result); }; clearRequest.onerror = (event) => { // Use a type assertion to access the specific properties of IDBRequest error event const errorEvent = event; console.error('Error in clearing data:', errorEvent.target.error?.message); }; } catch (error) { console.error('Error in opening database:', error); } } export async function addDataArray(userID, array) { try { const { db, transaction, store } = await getDBTransactionStore(userID, "readwrite"); transaction.onerror = (event) => { console.error('Error in adding data:', event); }; // let count = 0; array.reverse(); for (let data of array) { const addRequest = store.add({ post_timestamp: data.post_timestamp, data: data }); // addRequest.onsuccess = (e: Event) => { // // console.log('Data has been added:', (e.target as IDBRequest).result); // }; // addRequest.onerror = (event: Event) => { // // Use a type assertion to access the specific properties of IDBRequest error event // const errorEvent = event as IDBRequestEvent; // console.error('Error in adding data:', errorEvent.target.error?.message); // }; // count++; // if (count % 100 === 0) { // console.log(`Added ${count} posts...`); // } } } catch (error) { console.error('Error in opening database:', error); } } export async function checkPostIds(userID, post_ids) { try { const { db, transaction, store } = await getDBTransactionStore(userID); const index = store.index("postIDIndex"); transaction.oncomplete = () => { // console.log("Transaction completed successfully"); db.close(); }; transaction.onerror = (event) => { console.error("Transaction error:", event.target.error); db.close(); }; let postIdsNeeded = []; for (let id of post_ids) { try { let havePost = await new Promise((resolve, reject) => { const getRequest = index.getKey(id); getRequest.onerror = (e) => { console.log(e.target.error); reject(e); }; getRequest.onsuccess = async (e) => { const key = e.target.result; resolve(key !== undefined); }; }); // console.log(post.post_id, havePost); if (!havePost) { postIdsNeeded.push(id); } } catch (error) { console.error("Error processing post:", error); } } console.log(`checkPostIds need ${postIdsNeeded.length} posts`); return postIdsNeeded; } catch (error) { console.error("Error in opening database:", error); } } export async function mergeDataArray(userID, array) { try { const { db, transaction, store } = await getDBTransactionStore(userID, "readwrite"); const index = store.index("postIDIndex"); transaction.oncomplete = () => { // console.log("Transaction completed successfully"); db.close(); }; transaction.onerror = (event) => { console.error("Transaction error:", event.target.error); db.close(); }; let postsToWrite = []; for (let post of array) { try { let havePost = await new Promise((resolve, reject) => { const getRequest = index.getKey(post.post_id); getRequest.onerror = (e) => { console.log(e.target.error); reject(e); }; getRequest.onsuccess = async (e) => { const key = e.target.result; resolve(key !== undefined); }; }); // console.log(post.post_id, havePost); if (!havePost) { postsToWrite.push(post); } } catch (error) { console.error("Error processing post:", error); } } console.log(`Writing ${postsToWrite.length} posts`); await addDataArray(userID, postsToWrite); } catch (error) { console.error("Error in opening database:", error); } } export async function getPostForUser(userID, postID) { } export async function getData(userID, lowerID, upperID) { const { store } = await getDBTransactionStore(userID); const keyRangeValue = IDBKeyRange.bound(lowerID, upperID); const index = store.index("datetimeIndex"); return new Promise((resolve, reject) => { const getAllRequest = index.getAll(keyRangeValue); getAllRequest.onsuccess = () => { const records = getAllRequest.result.map((item) => item.data); resolve(records); }; getAllRequest.onerror = () => { console.error('Transaction failed:', getAllRequest.error?.message); reject(getAllRequest.error); }; }); } export async function getAllData(userID) { const { store } = await getDBTransactionStore(userID); return new Promise((resolve, reject) => { const getRequest = store.getAll(); getRequest.onsuccess = () => { if (getRequest.result) { // console.log('Retrieved data:', getRequest.result.jsonData); // resolve(getRequest.result.jsonData as any); resolve(getRequest.result); } else { console.log('No data record found for key', key); resolve(undefined); // explicitly resolve with undefined when no data is found } }; getRequest.onerror = (event) => { // Use a type assertion to access the specific properties of IDBRequest error event const errorEvent = event; console.error('Transaction failed:', errorEvent.target.error?.message); reject(errorEvent.target.error); // reject the promise if there's an error }; }); } export async function getAllIds(userID) { const { store } = await getDBTransactionStore(userID); const index = store.index("postIDIndex"); let keys = []; return new Promise((resolve, reject) => { let request = index.openKeyCursor(); request.onsuccess = (event) => { let cursor = event.target.result; if (cursor) { keys.push(cursor.key); cursor.continue(); } else { resolve(keys); } }; request.onerror = (event) => { reject(event); }; }); } export async function getPostsByIds(userID, postIDs) { const { store } = await getDBTransactionStore(userID); const index = store.index("postIDIndex"); let posts = []; for (const postID of postIDs) { const post = await new Promise((resolve, reject) => { let request = index.get(postID); request.onsuccess = (event) => { resolve(event.target.result); // Resolve with the post }; request.onerror = (event) => { reject(event); // Reject if any error occurs }; }); if (post) { posts.push(post); // Add the post to the result array if found } } return posts; // Return the array of posts } //# sourceMappingURL=db.js.map