Merged in feat/common-package (pull request #2333)
feat: Add common package * Add isEdge, safeTry and dataCache to new common package * Add eslint and move prettier config * Fix yarn lock * Clean up tests * Add lint-staged config to common * Add missing dependencies Approved-by: Joakim Jäderberg
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
export const cacheMap = new Map<
|
||||
string,
|
||||
{
|
||||
/** Absolute expiration timestamp (`Date.now()`) */
|
||||
expiresAt: number
|
||||
/** The cached data */
|
||||
data: unknown
|
||||
}
|
||||
>()
|
||||
@@ -0,0 +1,48 @@
|
||||
import {
|
||||
type CacheOrGetOptions,
|
||||
shouldGetFromCache,
|
||||
} from "../../cacheOrGetOptions"
|
||||
import { cacheLogger } from "../../logger"
|
||||
import { get } from "./get"
|
||||
import { set } from "./set"
|
||||
|
||||
import type { CacheTime, DataCache } from "../../Cache"
|
||||
|
||||
export const cacheOrGet: DataCache["cacheOrGet"] = async <T>(
|
||||
key: string | string[],
|
||||
callback: (overrideTTL?: (cacheTime: CacheTime) => void) => Promise<T>,
|
||||
ttl: CacheTime,
|
||||
opts?: CacheOrGetOptions
|
||||
): Promise<T> => {
|
||||
if (Array.isArray(key)) {
|
||||
key = key.join("-")
|
||||
}
|
||||
|
||||
let realTTL = ttl
|
||||
const overrideTTL = function (cacheTime: CacheTime) {
|
||||
realTTL = cacheTime
|
||||
}
|
||||
|
||||
let cached: Awaited<T> | undefined = undefined
|
||||
if (shouldGetFromCache(opts)) {
|
||||
cached = await get(key)
|
||||
if (cached) {
|
||||
return cached
|
||||
}
|
||||
|
||||
cacheLogger.debug(`Miss for key '${key}'`)
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await callback(overrideTTL)
|
||||
await set(key, data, realTTL)
|
||||
|
||||
return data
|
||||
} catch (e) {
|
||||
cacheLogger.error(
|
||||
`Error while fetching data for key '${key}', avoid caching`,
|
||||
e
|
||||
)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { cacheLogger } from "../../logger"
|
||||
import { cacheMap } from "./cacheMap"
|
||||
|
||||
export async function deleteKey(key: string, opts?: { fuzzy?: boolean }) {
|
||||
cacheLogger.debug("Deleting key", key)
|
||||
if (opts?.fuzzy) {
|
||||
cacheMap.forEach((_, k) => {
|
||||
if (k.includes(key)) {
|
||||
cacheMap.delete(k)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
cacheMap.delete(key)
|
||||
}
|
||||
22
packages/common/dataCache/MemoryCache/InMemoryCache/get.ts
Normal file
22
packages/common/dataCache/MemoryCache/InMemoryCache/get.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { cacheLogger } from "../../logger"
|
||||
import { cacheMap } from "./cacheMap"
|
||||
|
||||
export async function get<T>(key: string): Promise<T | undefined> {
|
||||
const cached = cacheMap.get(key)
|
||||
if (!cached) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (cached.expiresAt < Date.now()) {
|
||||
cacheLogger.debug(`Expired for key '${key}'`)
|
||||
cacheMap.delete(key)
|
||||
return undefined
|
||||
}
|
||||
if (cached.data === undefined) {
|
||||
cacheLogger.debug(`Data is undefined for key '${key}'`)
|
||||
cacheMap.delete(key)
|
||||
return undefined
|
||||
}
|
||||
|
||||
return cached.data as T
|
||||
}
|
||||
10
packages/common/dataCache/MemoryCache/InMemoryCache/index.ts
Normal file
10
packages/common/dataCache/MemoryCache/InMemoryCache/index.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { cacheOrGet } from "./cacheOrGet"
|
||||
import { deleteKey } from "./deleteKey"
|
||||
import { get } from "./get"
|
||||
import { set } from "./set"
|
||||
|
||||
import type { DataCache } from "../../Cache"
|
||||
|
||||
export async function createInMemoryCache(): Promise<DataCache> {
|
||||
return { type: "in-memory", cacheOrGet, deleteKey, get, set }
|
||||
}
|
||||
13
packages/common/dataCache/MemoryCache/InMemoryCache/set.ts
Normal file
13
packages/common/dataCache/MemoryCache/InMemoryCache/set.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { type CacheTime, getCacheTimeInSeconds } from "../../Cache"
|
||||
import { cacheMap } from "./cacheMap"
|
||||
|
||||
export async function set<T>(
|
||||
key: string,
|
||||
data: T,
|
||||
ttl: CacheTime
|
||||
): Promise<void> {
|
||||
cacheMap.set(key, {
|
||||
data: data,
|
||||
expiresAt: Date.now() + getCacheTimeInSeconds(ttl) * 1000,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { type DataCache } from "../Cache"
|
||||
import { createInMemoryCache } from "./InMemoryCache"
|
||||
|
||||
export function createMemoryCache(): Promise<DataCache> {
|
||||
return createInMemoryCache()
|
||||
}
|
||||
Reference in New Issue
Block a user