feat: cache not found relay lists to avoid redundant queries
This commit is contained in:
@@ -723,7 +723,7 @@ class ClientService extends EventTarget {
|
|||||||
const relayEvents = await indexedDb.getManyReplaceableEvents(pubkeys, kinds.RelayList)
|
const relayEvents = await indexedDb.getManyReplaceableEvents(pubkeys, kinds.RelayList)
|
||||||
const nonExistingPubkeyIndexMap = new Map<string, number>()
|
const nonExistingPubkeyIndexMap = new Map<string, number>()
|
||||||
pubkeys.forEach((pubkey, i) => {
|
pubkeys.forEach((pubkey, i) => {
|
||||||
if (!relayEvents[i]) {
|
if (relayEvents[i] === undefined) {
|
||||||
nonExistingPubkeyIndexMap.set(pubkey, i)
|
nonExistingPubkeyIndexMap.set(pubkey, i)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -1024,7 +1024,14 @@ class ClientService extends EventTarget {
|
|||||||
eventsMap.set(pubkey, event)
|
eventsMap.set(pubkey, event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Array.from(eventsMap.values()).forEach((evt) => indexedDb.putReplaceableEvent(evt))
|
pubkeys.forEach((pubkey) => {
|
||||||
|
const event = eventsMap.get(pubkey)
|
||||||
|
if (event) {
|
||||||
|
indexedDb.putReplaceableEvent(event)
|
||||||
|
} else {
|
||||||
|
indexedDb.putNullReplaceableEvent(pubkey, kinds.RelayList)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return pubkeys.map((pubkey) => eventsMap.get(pubkey))
|
return pubkeys.map((pubkey) => eventsMap.get(pubkey))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,45 @@ class IndexedDbService {
|
|||||||
return this.initPromise
|
return this.initPromise
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async putNullReplaceableEvent(pubkey: string, kind: number) {
|
||||||
|
const storeName = this.getStoreNameByKind(kind)
|
||||||
|
if (!storeName) {
|
||||||
|
return Promise.reject('store name not found')
|
||||||
|
}
|
||||||
|
await this.initPromise
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!this.db) {
|
||||||
|
return reject('database not initialized')
|
||||||
|
}
|
||||||
|
const transaction = this.db.transaction(storeName, 'readwrite')
|
||||||
|
const store = transaction.objectStore(storeName)
|
||||||
|
|
||||||
|
const getRequest = store.get(pubkey)
|
||||||
|
getRequest.onsuccess = () => {
|
||||||
|
const oldValue = getRequest.result as TValue<Event> | undefined
|
||||||
|
if (oldValue) {
|
||||||
|
transaction.commit()
|
||||||
|
return resolve(oldValue.value)
|
||||||
|
}
|
||||||
|
const putRequest = store.put(this.formatValue(pubkey, null))
|
||||||
|
putRequest.onsuccess = () => {
|
||||||
|
transaction.commit()
|
||||||
|
resolve(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
putRequest.onerror = (event) => {
|
||||||
|
transaction.commit()
|
||||||
|
reject(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getRequest.onerror = (event) => {
|
||||||
|
transaction.commit()
|
||||||
|
reject(event)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
async putReplaceableEvent(event: Event): Promise<Event> {
|
async putReplaceableEvent(event: Event): Promise<Event> {
|
||||||
const storeName = this.getStoreNameByKind(event.kind)
|
const storeName = this.getStoreNameByKind(event.kind)
|
||||||
if (!storeName) {
|
if (!storeName) {
|
||||||
@@ -154,7 +193,7 @@ class IndexedDbService {
|
|||||||
async getManyReplaceableEvents(
|
async getManyReplaceableEvents(
|
||||||
pubkeys: readonly string[],
|
pubkeys: readonly string[],
|
||||||
kind: number
|
kind: number
|
||||||
): Promise<(Event | undefined)[]> {
|
): Promise<(Event | undefined | null)[]> {
|
||||||
const storeName = this.getStoreNameByKind(kind)
|
const storeName = this.getStoreNameByKind(kind)
|
||||||
if (!storeName) {
|
if (!storeName) {
|
||||||
return Promise.reject('store name not found')
|
return Promise.reject('store name not found')
|
||||||
@@ -166,14 +205,14 @@ class IndexedDbService {
|
|||||||
}
|
}
|
||||||
const transaction = this.db.transaction(storeName, 'readonly')
|
const transaction = this.db.transaction(storeName, 'readonly')
|
||||||
const store = transaction.objectStore(storeName)
|
const store = transaction.objectStore(storeName)
|
||||||
const events: Event[] = new Array(pubkeys.length).fill(undefined)
|
const events: (Event | null)[] = new Array(pubkeys.length).fill(undefined)
|
||||||
let count = 0
|
let count = 0
|
||||||
pubkeys.forEach((pubkey, i) => {
|
pubkeys.forEach((pubkey, i) => {
|
||||||
const request = store.get(pubkey)
|
const request = store.get(pubkey)
|
||||||
|
|
||||||
request.onsuccess = () => {
|
request.onsuccess = () => {
|
||||||
const event = (request.result as TValue<Event>)?.value
|
const event = (request.result as TValue<Event | null>)?.value
|
||||||
if (event) {
|
if (event || event === null) {
|
||||||
events[i] = event
|
events[i] = event
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,8 +423,7 @@ class IndexedDbService {
|
|||||||
const cursor = (event.target as IDBRequest).result
|
const cursor = (event.target as IDBRequest).result
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
const value: TValue = cursor.value
|
const value: TValue = cursor.value
|
||||||
// 10% chance to delete
|
if (value.addedAt < expirationTimestamp) {
|
||||||
if (value.addedAt < expirationTimestamp && Math.random() < 0.1) {
|
|
||||||
cursor.delete()
|
cursor.delete()
|
||||||
}
|
}
|
||||||
cursor.continue()
|
cursor.continue()
|
||||||
|
|||||||
Reference in New Issue
Block a user