-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathextension-store.ts
More file actions
66 lines (58 loc) · 1.81 KB
/
Copy pathextension-store.ts
File metadata and controls
66 lines (58 loc) · 1.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import DataLoader from "dataloader";
import type { Cache } from "./cache";
export type ExtensionId = string | number;
export class ExtensionStore<TGqlExtension extends Gql.Extension> {
private dataloader: DataLoader<ExtensionId, TGqlExtension>;
constructor(
readonly options: {
cacheKeyPrefix: string;
fetch: (id: ExtensionId) => Promise<TGqlExtension | undefined>;
cache: Cache;
},
) {
this.dataloader = new DataLoader<ExtensionId, TGqlExtension>(
async (ids): Promise<Array<TGqlExtension | Error>> => {
const results = await Promise.allSettled(
ids.map(async (id) => {
const cacheKey = options.cacheKeyPrefix + id;
const cached = await options.cache.get(cacheKey);
if (cached) return cached;
const result = await options.fetch(id);
if (result) await options.cache.set(cacheKey, result);
return result;
}),
);
return results.map((res) =>
res.status === "fulfilled" ? res.value : res.reason,
);
},
);
}
/**
* Get an extension by it's ID.
*/
getExtension(extensionId: ExtensionId): Promise<TGqlExtension> {
return this.dataloader.load(extensionId);
}
/**
* Get multiple extensions by their IDs.
*/
async getExtensions(
extensionIds: ExtensionId[],
): Promise<(TGqlExtension | Error)[]> {
return this.dataloader.loadMany(extensionIds);
}
/**
* Get a screenshot given an index.
*/
async getScreenshotUrl(
extensionId: ExtensionId,
screenshotIndex: number,
): Promise<string | undefined> {
const extension = await this.getExtension(extensionId);
const screenshot = extension.screenshots.find(
(screenshot) => screenshot.index == screenshotIndex,
);
return screenshot?.rawUrl;
}
}