mirror of
https://github.com/FranP-code/Baileys.git
synced 2025-10-13 00:32:22 +00:00
feat: add makeCacheableSignalKeyStore util
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { Boom } from '@hapi/boom'
|
import { Boom } from '@hapi/boom'
|
||||||
import makeWASocket, { AnyMessageContent, delay, DisconnectReason, fetchLatestBaileysVersion, makeInMemoryStore, MessageRetryMap, useMultiFileAuthState } from '../src'
|
import makeWASocket, { AnyMessageContent, delay, DisconnectReason, fetchLatestBaileysVersion, makeCacheableSignalKeyStore, makeInMemoryStore, MessageRetryMap, useMultiFileAuthState } from '../src'
|
||||||
import MAIN_LOGGER from '../src/Utils/logger'
|
import MAIN_LOGGER from '../src/Utils/logger'
|
||||||
|
|
||||||
const logger = MAIN_LOGGER.child({ })
|
const logger = MAIN_LOGGER.child({ })
|
||||||
@@ -32,7 +32,11 @@ const startSock = async() => {
|
|||||||
version,
|
version,
|
||||||
logger,
|
logger,
|
||||||
printQRInTerminal: true,
|
printQRInTerminal: true,
|
||||||
auth: state,
|
auth: {
|
||||||
|
creds: state.creds,
|
||||||
|
/** caching makes the store faster to send/recv messages */
|
||||||
|
keys: makeCacheableSignalKeyStore(state.keys, logger),
|
||||||
|
},
|
||||||
msgRetryCounterMap,
|
msgRetryCounterMap,
|
||||||
generateHighQualityLinkPreview: true,
|
generateHighQualityLinkPreview: true,
|
||||||
// implement to handle retries
|
// implement to handle retries
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ type Awaitable<T> = T | Promise<T>
|
|||||||
export type SignalKeyStore = {
|
export type SignalKeyStore = {
|
||||||
get<T extends keyof SignalDataTypeMap>(type: T, ids: string[]): Awaitable<{ [id: string]: SignalDataTypeMap[T] }>
|
get<T extends keyof SignalDataTypeMap>(type: T, ids: string[]): Awaitable<{ [id: string]: SignalDataTypeMap[T] }>
|
||||||
set(data: SignalDataSet): Awaitable<void>
|
set(data: SignalDataSet): Awaitable<void>
|
||||||
|
/** clear all the data in the store */
|
||||||
|
clear?(): Awaitable<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SignalKeyStoreWithTransaction = SignalKeyStore & {
|
export type SignalKeyStoreWithTransaction = SignalKeyStore & {
|
||||||
|
|||||||
@@ -1,10 +1,78 @@
|
|||||||
import { Boom } from '@hapi/boom'
|
import { Boom } from '@hapi/boom'
|
||||||
import { randomBytes } from 'crypto'
|
import { randomBytes } from 'crypto'
|
||||||
|
import NodeCache from 'node-cache'
|
||||||
import type { Logger } from 'pino'
|
import type { Logger } from 'pino'
|
||||||
import type { AuthenticationCreds, SignalDataSet, SignalDataTypeMap, SignalKeyStore, SignalKeyStoreWithTransaction, TransactionCapabilityOptions } from '../Types'
|
import type { AuthenticationCreds, SignalDataSet, SignalDataTypeMap, SignalKeyStore, SignalKeyStoreWithTransaction, TransactionCapabilityOptions } from '../Types'
|
||||||
import { Curve, signedKeyPair } from './crypto'
|
import { Curve, signedKeyPair } from './crypto'
|
||||||
import { delay, generateRegistrationId } from './generics'
|
import { delay, generateRegistrationId } from './generics'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds caching capability to a SignalKeyStore
|
||||||
|
* @param store the store to add caching to
|
||||||
|
* @param logger to log trace events
|
||||||
|
* @param opts NodeCache options
|
||||||
|
*/
|
||||||
|
export function makeCacheableSignalKeyStore(
|
||||||
|
store: SignalKeyStore,
|
||||||
|
logger: Logger,
|
||||||
|
opts?: NodeCache.Options
|
||||||
|
): SignalKeyStore {
|
||||||
|
const cache = new NodeCache({
|
||||||
|
...opts || { },
|
||||||
|
useClones: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
function getUniqueId(type: string, id: string) {
|
||||||
|
return `${type}.${id}`
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
async get(type, ids) {
|
||||||
|
const data: { [_: string]: SignalDataTypeMap[typeof type] } = { }
|
||||||
|
const idsToFetch: string[] = []
|
||||||
|
for(const id of ids) {
|
||||||
|
const item = cache.get<SignalDataTypeMap[typeof type]>(getUniqueId(type, id))
|
||||||
|
if(typeof item !== 'undefined') {
|
||||||
|
data[id] = item
|
||||||
|
} else {
|
||||||
|
idsToFetch.push(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(idsToFetch.length) {
|
||||||
|
logger.trace({ items: idsToFetch.length }, 'loading from store')
|
||||||
|
const fetched = await store.get(type, idsToFetch)
|
||||||
|
for(const id of idsToFetch) {
|
||||||
|
const item = fetched[id]
|
||||||
|
if(item) {
|
||||||
|
data[id] = item
|
||||||
|
cache.set(getUniqueId(type, id), item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
async set(data) {
|
||||||
|
let keys = 0
|
||||||
|
for(const type in data) {
|
||||||
|
for(const id in data[type]) {
|
||||||
|
cache.set(getUniqueId(type, id), data[type][id])
|
||||||
|
keys += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.trace({ keys }, 'updated cache')
|
||||||
|
|
||||||
|
await store.set(data)
|
||||||
|
},
|
||||||
|
async clear() {
|
||||||
|
cache.flushAll()
|
||||||
|
await store.clear?.()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds DB like transaction capability (https://en.wikipedia.org/wiki/Database_transaction) to the SignalKeyStore,
|
* Adds DB like transaction capability (https://en.wikipedia.org/wiki/Database_transaction) to the SignalKeyStore,
|
||||||
* this allows batch read & write operations & improves the performance of the lib
|
* this allows batch read & write operations & improves the performance of the lib
|
||||||
@@ -12,7 +80,11 @@ import { delay, generateRegistrationId } from './generics'
|
|||||||
* @param logger logger to log events
|
* @param logger logger to log events
|
||||||
* @returns SignalKeyStore with transaction capability
|
* @returns SignalKeyStore with transaction capability
|
||||||
*/
|
*/
|
||||||
export const addTransactionCapability = (state: SignalKeyStore, logger: Logger, { maxCommitRetries, delayBetweenTriesMs }: TransactionCapabilityOptions): SignalKeyStoreWithTransaction => {
|
export const addTransactionCapability = (
|
||||||
|
state: SignalKeyStore,
|
||||||
|
logger: Logger,
|
||||||
|
{ maxCommitRetries, delayBetweenTriesMs }: TransactionCapabilityOptions
|
||||||
|
): SignalKeyStoreWithTransaction => {
|
||||||
let inTransaction = false
|
let inTransaction = false
|
||||||
// number of queries made to the DB during the transaction
|
// number of queries made to the DB during the transaction
|
||||||
// only there for logging purposes
|
// only there for logging purposes
|
||||||
|
|||||||
Reference in New Issue
Block a user