aboutsummaryrefslogtreecommitdiff
path: root/src/util.ts
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2022-05-17 22:39:57 -0500
committermat <github@matdoes.dev>2022-05-17 22:39:57 -0500
commitb5ed021b6ba1dcfaf3162a5e1f686187c209a815 (patch)
tree4565366ea1ee37ad5c415214a45775873faef462 /src/util.ts
parent31b2b2bcc411c6bffb925eaff50731f9aefb5a82 (diff)
downloadskyblock-api-b5ed021b6ba1dcfaf3162a5e1f686187c209a815.tar.gz
skyblock-api-b5ed021b6ba1dcfaf3162a5e1f686187c209a815.tar.bz2
skyblock-api-b5ed021b6ba1dcfaf3162a5e1f686187c209a815.zip
improve caching logic
Diffstat (limited to 'src/util.ts')
-rw-r--r--src/util.ts50
1 files changed, 49 insertions, 1 deletions
diff --git a/src/util.ts b/src/util.ts
index 91f202d..9af95c7 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -103,4 +103,52 @@ export type RecursivePartial<T> = {
T[P] extends (infer U)[] ? RecursivePartial<U>[] :
T[P] extends object ? RecursivePartial<T[P]> :
T[P]
-} \ No newline at end of file
+}
+
+let caches: Map<string, {
+ data: any
+ isFetching: boolean
+ nextUpdate: Date
+}> = new Map()
+
+export async function withCache<T>(key: string, ttl: number | ((arg: T) => Date), task: () => Promise<T>): Promise<T> {
+ if (caches.get(key)?.data && caches.get(key)!.nextUpdate > new Date())
+ return caches.get(key)!.data
+
+ // if it's currently fetching the election data and it doesn't have it,
+ // wait until we do have the election data
+ if (caches.get(key)?.isFetching && !caches.get(key)?.data) {
+ await new Promise(resolve => {
+ const interval = setInterval(() => {
+ if (caches.get(key)?.data) {
+ clearInterval(interval)
+ resolve(caches.get(key)!.data)
+ }
+ }, 100)
+ })
+ }
+
+ caches.set(key, {
+ ...(caches.get(key) ?? { data: undefined, nextUpdate: new Date(0) }),
+ isFetching: true,
+ })
+ const data = await task()
+ caches.set(key, {
+ ...caches.get(key)!,
+ isFetching: false,
+ })
+ if (!data) return undefined as any
+
+ caches.set(key, {
+ ...caches.get(key)!,
+ data
+ })
+
+ const nextUpdate = typeof ttl === 'number' ? new Date(Date.now() + ttl) : ttl(data)
+
+ caches.set(key, {
+ ...caches.get(key)!,
+ nextUpdate
+ })
+ return data
+}