69 lines
1.8 KiB
TypeScript
69 lines
1.8 KiB
TypeScript
import { mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
import { existsSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
|
|
export interface Cache {
|
|
get(key: string): Promise<Uint8Array | undefined>;
|
|
put(
|
|
key: string,
|
|
value: Uint8Array,
|
|
options?: { ttl?: number },
|
|
): Promise<void>;
|
|
delete(key: string): Promise<void>;
|
|
}
|
|
|
|
export interface CloudflareCacheLike {
|
|
match(request: Request): Promise<Response | undefined>;
|
|
put(request: Request, response: Response): Promise<void>;
|
|
delete(request: Request): Promise<boolean>;
|
|
}
|
|
|
|
function cacheKey(key: string): string {
|
|
return encodeURIComponent(key);
|
|
}
|
|
|
|
export function filesystemCache(dir: string): Cache {
|
|
return {
|
|
async get(key) {
|
|
const path = join(dir, cacheKey(key));
|
|
if (!existsSync(path)) return undefined;
|
|
return new Uint8Array(await readFile(path));
|
|
},
|
|
async put(key, value) {
|
|
await mkdir(dir, { recursive: true });
|
|
const path = join(dir, cacheKey(key));
|
|
const staged = `${path}.next`;
|
|
await writeFile(staged, value);
|
|
await rename(staged, path);
|
|
},
|
|
async delete(key) {
|
|
const path = join(dir, cacheKey(key));
|
|
if (existsSync(path)) await rename(path, `${path}.deleted`);
|
|
},
|
|
};
|
|
}
|
|
|
|
export function cloudflareCache(
|
|
cache: CloudflareCacheLike,
|
|
origin = "https://muddle.cache",
|
|
): Cache {
|
|
const request = (key: string) =>
|
|
new Request(new URL(`/${encodeURIComponent(key)}`, origin).toString());
|
|
return {
|
|
async get(key) {
|
|
const response = await cache.match(request(key));
|
|
return response
|
|
? new Uint8Array(await response.arrayBuffer())
|
|
: undefined;
|
|
},
|
|
async put(key, value, options) {
|
|
const headers = options?.ttl
|
|
? { "cache-control": `max-age=${options.ttl}` }
|
|
: undefined;
|
|
await cache.put(request(key), new Response(value, { headers }));
|
|
},
|
|
async delete(key) {
|
|
await cache.delete(request(key));
|
|
},
|
|
};
|
|
}
|