import type { CachePort, KachelPort, MarksPort } from "./types"; export function createMemoryCache(initial: string[] = []): CachePort { const ids = new Set(initial); return { async ids() { return [...ids]; }, async put(id) { ids.add(id); }, async delete(drop) { for (const id of drop) ids.delete(id); }, }; } export function createMemoryMarks(initial: string[] = []): MarksPort { let heruntergeladen = [...initial]; let ziele: string[] = []; return { async read() { return { heruntergeladen: [...heruntergeladen], ziele: [...ziele] }; }, async write(state) { heruntergeladen = [...state.heruntergeladen]; ziele = [...state.ziele]; }, }; } type Job = { resolve: (bytes: Uint8Array) => void; reject: (error: unknown) => void; settled: boolean; }; /** Completes the oldest in-flight Kachel fetch when `tick` is called. */ export function createFetchClock(): KachelPort & { tick: () => Promise } { const queue: Job[] = []; return { fetch(_id, signal) { return new Promise((resolve, reject) => { const job: Job = { resolve, reject, settled: false }; const abort = () => { if (job.settled) return; job.settled = true; const index = queue.indexOf(job); if (index >= 0) queue.splice(index, 1); reject(new DOMException("The operation was aborted.", "AbortError")); }; if (signal.aborted) { abort(); return; } signal.addEventListener("abort", abort, { once: true }); queue.push(job); }); }, async tick() { const job = queue.shift(); if (!job || job.settled) return; job.settled = true; job.resolve(new Uint8Array([7])); for (let step = 0; step < 20; step += 1) await Promise.resolve(); }, }; }