Files
kiss-translator/src/libs/cache.js
2025-10-15 14:40:58 +08:00

160 lines
3.4 KiB
JavaScript

import {
CACHE_NAME,
DEFAULT_CACHE_TIMEOUT,
MSG_CLEAR_CACHES,
MSG_GET_HTTPCACHE,
MSG_PUT_HTTPCACHE,
} from "../config";
import { kissLog } from "./log";
import { isExt } from "./client";
import { isBg } from "./browser";
import { sendBgMsg } from "./msg";
import { blobToBase64 } from "./utils";
/**
* 清除缓存数据
*/
export const tryClearCaches = async () => {
try {
if (isExt && !isBg) {
await sendBgMsg(MSG_CLEAR_CACHES);
} else {
await caches.delete(CACHE_NAME);
}
} catch (err) {
kissLog("clean caches", err);
}
};
/**
* 构造缓存 request
* @param {*} input
* @param {*} init
* @returns
*/
const newCacheReq = async (input, init) => {
let request = new Request(input, init);
if (request.method !== "GET") {
const body = await request.text();
const cacheUrl = new URL(request.url);
cacheUrl.pathname += body;
request = new Request(cacheUrl.toString(), { method: "GET" });
}
return request;
};
/**
* 查询 caches
* @param {*} input
* @param {*} init
* @returns
*/
export const getHttpCache = async ({ input, init }) => {
try {
const request = await newCacheReq(input, init);
const cache = await caches.open(CACHE_NAME);
const response = await cache.match(request);
if (response) {
const res = await parseResponse(response);
return res;
}
} catch (err) {
kissLog("get cache", err);
}
return null;
};
/**
* 插入 caches
* @param {*} input
* @param {*} init
* @param {*} data
*/
export const putHttpCache = async ({
input,
init,
data,
maxAge = DEFAULT_CACHE_TIMEOUT, // todo: 从设置里面读取最大缓存时间
}) => {
try {
const req = await newCacheReq(input, init);
const cache = await caches.open(CACHE_NAME);
const res = new Response(JSON.stringify(data), {
status: 200,
headers: {
"Content-Type": "application/json",
"Cache-Control": `max-age=${maxAge}`,
},
});
// res.headers.set("Cache-Control", `max-age=${maxAge}`);
await cache.put(req, res);
} catch (err) {
kissLog("put cache", err);
}
};
/**
* 解析 response
* @param {*} res
* @returns
*/
export const parseResponse = async (res) => {
if (!res) {
throw new Error("Response object does not exist");
}
if (!res.ok) {
const msg = {
url: res.url,
status: res.status,
};
if (res.headers.get("Content-Type")?.includes("json")) {
msg.response = await res.json();
}
throw new Error(JSON.stringify(msg));
}
const contentType = res.headers.get("Content-Type");
if (contentType?.includes("json")) {
return res.json();
} else if (contentType?.includes("audio")) {
const blob = await res.blob();
return blobToBase64(blob);
}
return res.text();
};
/**
* getHttpCache 兼容性封装
* @param {*} input
* @param {*} init
* @returns
*/
export const getHttpCachePolyfill = (input, init) => {
// 插件
if (isExt && !isBg()) {
return sendBgMsg(MSG_GET_HTTPCACHE, { input, init });
}
// 油猴/网页/BackgroundPage
return getHttpCache({ input, init });
};
/**
* putHttpCache 兼容性封装
* @param {*} input
* @param {*} init
* @param {*} data
* @returns
*/
export const putHttpCachePolyfill = (input, init, data) => {
// 插件
if (isExt && !isBg()) {
return sendBgMsg(MSG_PUT_HTTPCACHE, { input, init, data });
}
// 油猴/网页/BackgroundPage
return putHttpCache({ input, init, data });
};