Skip to content

Commit deae0b4

Browse files
authored
Merge pull request #42 from takker99/feature-cache
✨ Implemented functions operating cache storages
2 parents f7923be + ff84776 commit deae0b4

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

browser/dom/cache.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/// <reference no-default-lib="true"/>
2+
/// <reference lib="esnext"/>
3+
/// <reference lib="dom" />
4+
5+
/** scrapbox.ioが管理しているcache storageから、最新のresponseを取得する
6+
*
7+
* ほぼ https://scrapbox.io/daiiz/ScrapboxでのServiceWorkerとCacheの活用#5d2efaffadf4e70000651173 のパクリ
8+
*
9+
* @param request このrequestに対応するresponseが欲しい
10+
* @param options search paramsを無視したいときとかに使う
11+
* @return cacheがあればそのresponseを、なければ`undefined`を返す
12+
*/
13+
export const findLatestCache = async (
14+
request: Request,
15+
options?: CacheQueryOptions,
16+
): Promise<Response | undefined> => {
17+
const cacheNames = await globalThis.caches.keys();
18+
19+
for (const date of cacheNames.sort().reverse()) {
20+
const cache = await caches.open(date);
21+
const res = await cache.match(request, options);
22+
if (res) return res;
23+
}
24+
};
25+
26+
/** prefetchを実行する
27+
*
28+
* prefetchしたデータは`"prefetch"`と`"api-yyyy-MM-dd"`に格納される
29+
*
30+
* `"prefetch"`に格納されたデータは、次回のリクエストで返却されたときに削除される
31+
*
32+
* 回線が遅いときは例外を投げる
33+
*
34+
* @param urls prefetchしたいAPIのURLのリスト
35+
*/
36+
export const prefetch = async (
37+
urls: (string | URL)[],
38+
): Promise<void> => {
39+
await postMessage({
40+
title: "prefetch",
41+
body: { urls: urls.map((url) => url.toString()) },
42+
});
43+
};
44+
45+
/** 指定したAPIのcacheの更新を依頼する
46+
*
47+
* 更新は10秒ごとに1つずつ実行される
48+
*
49+
* @param cacheしたいAPIのURL
50+
*/
51+
export const fetchApiCache = async (
52+
url: string,
53+
): Promise<void> => {
54+
await postMessage({ title: "fetchApiCache", body: { url } });
55+
};
56+
57+
const postMessage = <T, U = unknown>(
58+
data: { title: string; body: T },
59+
): Promise<U> => {
60+
const { controller } = navigator.serviceWorker;
61+
if (!controller) {
62+
const error = new Error();
63+
error.name = "ServiceWorkerNotActiveYetError";
64+
error.message = "Service worker is not active yet";
65+
throw error;
66+
}
67+
68+
return new Promise<U>((resolve, reject) => {
69+
const channel = new MessageChannel();
70+
channel.port1.addEventListener(
71+
"message",
72+
(event) =>
73+
event.data?.error ? reject(event.data.error) : resolve(event.data),
74+
);
75+
controller.postMessage(data, [channel.port2]);
76+
});
77+
};

browser/dom/mod.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export * from "./statusBar.ts";
77
export * from "./caret.ts";
88
export * from "./dom.ts";
99
export * from "./openInTheSameTab.ts";
10+
export * from "./cache.ts";

0 commit comments

Comments
 (0)