pinafore/routes/_utils/database/statuses.js

75 lines
2.2 KiB
JavaScript

import cloneDeep from 'lodash/cloneDeep'
import padStart from 'lodash/padStart'
const STORE = 'statuses'
function toPaddedBigInt(id) {
return padStart(id, 30, '0')
}
function toReversePaddedBigInt(id) {
let bigInt = toPaddedBigInt(id)
let res = ''
for (let i = 0; i < bigInt.length; i++) {
res += (9 - parseInt(bigInt.charAt(i), 10)).toString(10)
}
return res
}
function transformStatusForStorage(status) {
status = cloneDeep(status)
status.pinafore_id_as_big_int = toPaddedBigInt(status.id)
status.pinafore_id_as_negative_big_int = toReversePaddedBigInt(status.id)
status.pinafore_stale = true
return status
}
const dbPromise = new Promise((resolve, reject) => {
let req = indexedDB.open(STORE, 1)
req.onerror = reject
req.onblocked = () => {
console.log('idb blocked')
}
req.onupgradeneeded = () => {
let db = req.result;
let oStore = db.createObjectStore(STORE, {
keyPath: 'id'
})
oStore.createIndex('created_at', 'created_at')
oStore.createIndex('pinafore_id_as_negative_big_int', 'pinafore_id_as_negative_big_int')
oStore.createIndex('pinafore_id_as_big_int', 'pinafore_id_as_big_int')
}
req.onsuccess = () => resolve(req.result)
})
export async function getTimelineAfter(max_id = null, limit = 20) {
const db = await dbPromise
return await new Promise((resolve, reject) => {
const tx = db.transaction(STORE, 'readonly')
const store = tx.objectStore(STORE)
const index = store.index('pinafore_id_as_negative_big_int')
let sinceAsNegativeBigInt = max_id === null ? null : toReversePaddedBigInt(max_id)
let query = sinceAsNegativeBigInt === null ? null : IDBKeyRange.lowerBound(sinceAsNegativeBigInt, false)
let res
index.getAll(query, limit).onsuccess = (e) => {
res = e.target.result
}
tx.oncomplete = () => resolve(res)
tx.onerror = reject
})
}
export async function insertStatuses(statuses) {
const db = await dbPromise
return await new Promise((resolve, reject) => {
const tx = db.transaction(STORE, 'readwrite')
const store = tx.objectStore(STORE)
for (let status of statuses) {
store.put(transformStatusForStorage(status))
}
tx.oncomplete = resolve
tx.onerror = reject
})
}