refactor: 프론트엔드 리펙토링
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
import type {
|
||||
PublicCacheAsset,
|
||||
PublicCacheReleaseManifest,
|
||||
} from "../../src/application/ports/browser-file-storage/cache-storage-ports.ts";
|
||||
import {
|
||||
createDefaultPublicCachePolicy,
|
||||
type PublicCacheRuntimePolicy,
|
||||
} from "../../src/adapters/cache-storage/public-cache-policy.ts";
|
||||
import {
|
||||
computePublicCacheManifestDigestHex,
|
||||
type PublicCacheMutationLock,
|
||||
} from "../../src/adapters/cache-storage/public-response-cache-adapter.ts";
|
||||
|
||||
export class MemoryCache {
|
||||
readonly responses: Array<Readonly<{
|
||||
request: Request;
|
||||
response: Response;
|
||||
}>> = [];
|
||||
|
||||
async match(request: RequestInfo | URL): Promise<Response | undefined> {
|
||||
const url =
|
||||
request instanceof Request ? request.url : new URL(String(request)).href;
|
||||
const nativeRequest =
|
||||
request instanceof Request ? request : new Request(url);
|
||||
return this.responses
|
||||
.find(
|
||||
(entry) =>
|
||||
entry.request.url === url &&
|
||||
varyMatches(entry.request, nativeRequest, entry.response),
|
||||
)
|
||||
?.response.clone();
|
||||
}
|
||||
|
||||
async put(request: RequestInfo | URL, response: Response): Promise<void> {
|
||||
const url =
|
||||
request instanceof Request ? request.url : new URL(String(request)).href;
|
||||
const nativeRequest =
|
||||
request instanceof Request ? request.clone() : new Request(url);
|
||||
const existing = this.responses.findIndex(
|
||||
(entry) =>
|
||||
entry.request.url === url &&
|
||||
varyMatches(entry.request, nativeRequest, response),
|
||||
);
|
||||
const entry = {
|
||||
request: nativeRequest,
|
||||
response: response.clone(),
|
||||
};
|
||||
if (existing >= 0) this.responses.splice(existing, 1, entry);
|
||||
else this.responses.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
function varyMatches(
|
||||
storedRequest: Request,
|
||||
incomingRequest: Request,
|
||||
response: Response,
|
||||
): boolean {
|
||||
const vary = response.headers.get("vary");
|
||||
if (!vary) return true;
|
||||
return vary
|
||||
.split(",")
|
||||
.map((name) => name.trim().toLowerCase())
|
||||
.every(
|
||||
(name) =>
|
||||
storedRequest.headers.get(name) ===
|
||||
incomingRequest.headers.get(name),
|
||||
);
|
||||
}
|
||||
|
||||
export class MemoryCacheStorage {
|
||||
readonly caches = new Map<string, MemoryCache>();
|
||||
|
||||
async open(name: string): Promise<Cache> {
|
||||
let cache = this.caches.get(name);
|
||||
if (!cache) {
|
||||
cache = new MemoryCache();
|
||||
this.caches.set(name, cache);
|
||||
}
|
||||
return cache as unknown as Cache;
|
||||
}
|
||||
|
||||
async keys(): Promise<string[]> {
|
||||
return [...this.caches.keys()];
|
||||
}
|
||||
|
||||
async delete(name: string): Promise<boolean> {
|
||||
return this.caches.delete(name);
|
||||
}
|
||||
}
|
||||
|
||||
export const immediateLock: PublicCacheMutationLock = {
|
||||
async run(_signal, task) {
|
||||
return await task();
|
||||
},
|
||||
};
|
||||
|
||||
export function deferred<Value>() {
|
||||
let settle: ((value: Value) => void) | undefined;
|
||||
const promise = new Promise<Value>((resolve) => {
|
||||
settle = resolve;
|
||||
});
|
||||
return Object.freeze({
|
||||
promise,
|
||||
resolve(value: Value): void {
|
||||
settle?.(value);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export async function digestHex(bytes: Uint8Array): Promise<string> {
|
||||
const digest = await globalThis.crypto.subtle.digest(
|
||||
"SHA-256",
|
||||
Uint8Array.from(bytes),
|
||||
);
|
||||
return [...new Uint8Array(digest)]
|
||||
.map((byte) => byte.toString(16).padStart(2, "0"))
|
||||
.join("");
|
||||
}
|
||||
|
||||
export async function manifestFor(
|
||||
releaseRegistryId: string,
|
||||
assets: readonly PublicCacheAsset[],
|
||||
policy: PublicCacheRuntimePolicy = createDefaultPublicCachePolicy(
|
||||
"https://assets.example.test",
|
||||
),
|
||||
): Promise<PublicCacheReleaseManifest> {
|
||||
return {
|
||||
releaseRegistryId,
|
||||
assets,
|
||||
manifestDigestHex: await computePublicCacheManifestDigestHex(
|
||||
globalThis.crypto,
|
||||
releaseRegistryId,
|
||||
assets,
|
||||
policy,
|
||||
),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user