feat: add Deduplicator class for managing unique promises and implement icon library generator
This commit is contained in:
+6
-2
@@ -3,11 +3,13 @@ import { join } from "node:path";
|
||||
import { file, hash, write } from "bun";
|
||||
import { TTLCache } from "enka.ts";
|
||||
import { AvatarStore, EnkaLocs, RelicStore, WeaponStore } from "@/type/enka";
|
||||
import { Deduplicator } from "./dedupe";
|
||||
|
||||
export const cache = new TTLCache();
|
||||
|
||||
export class AssetManager {
|
||||
private cache = new Map<string, ArrayBuffer>();
|
||||
private deduper = new Deduplicator<ArrayBuffer>();
|
||||
|
||||
async getMissingAssets() {
|
||||
const avatars = await getEnkaAvatarStore();
|
||||
@@ -51,8 +53,10 @@ export class AssetManager {
|
||||
const local = file(join("store", hash(path).toString(36)));
|
||||
if (await local.exists()) return local.arrayBuffer();
|
||||
|
||||
const data = await fetch(new URL(path, "https://enka.network")).then(
|
||||
(res) => res.arrayBuffer(),
|
||||
const data = await this.deduper.acquire(path, () =>
|
||||
fetch(new URL(path, "https://enka.network")).then((res) =>
|
||||
res.arrayBuffer(),
|
||||
),
|
||||
);
|
||||
this.cache.set(path, data);
|
||||
queueMicrotask(() => write(local, data));
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
export class Deduplicator<T> {
|
||||
// biome-ignore lint/suspicious/noExplicitAny: This is a generic class, so we need to use any here.
|
||||
private map: Map<string, Promise<any>> = new Map();
|
||||
|
||||
has(key: string): boolean {
|
||||
return this.map.has(key);
|
||||
}
|
||||
|
||||
get<C = T>(key: string): Promise<C> | undefined {
|
||||
return this.map.get(key);
|
||||
}
|
||||
|
||||
acquire<C = T>(key: string, factory: () => Promise<C>): Promise<C> {
|
||||
if (this.map.has(key)) {
|
||||
return this.map.get(key)!;
|
||||
}
|
||||
const value = factory();
|
||||
this.map.set(key, value);
|
||||
value.finally(() => {
|
||||
this.map.delete(key);
|
||||
});
|
||||
return value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user