Files
quick-access-hono/src/services/cache.ts
T
qwsdcvghyu89 363d894c79 Initial commit
2026-06-17 07:19:25 +10:00

82 lines
2.3 KiB
TypeScript

import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
import path from 'path';
import os from 'os';
import type { ChapterFile, ChapterView, TextFragment } from '../types.ts';
const TOC_FILENAME = 'toc.links';
function looksLikeFragments(content: string): boolean {
try {
const parsed = JSON.parse(content);
return (
Array.isArray(parsed) &&
parsed.length > 0 &&
typeof parsed[0] === 'object' &&
parsed[0] !== null &&
'body' in (parsed[0] as object)
);
} catch {
return false;
}
}
export class Cache {
private readonly base: string;
constructor(basePath: string) {
this.base = basePath.replace(/^~/, os.homedir());
}
private chapterPath(id: number, index: number): string {
return path.join(this.base, String(id), String(index));
}
private tocPath(id: number): string {
return path.join(this.base, String(id), TOC_FILENAME);
}
private ensureDir(id: number): void {
const dir = path.join(this.base, String(id));
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
}
tryGetChapters(id: number, from: number, to: number): ChapterView | null {
if (from > to) return null;
const chapters: ChapterFile[] = [];
for (let i = from; i <= to; i++) {
const p = this.chapterPath(id, i);
if (!existsSync(p)) return null;
const content = readFileSync(p, 'utf-8');
if (content.length < 10) return null;
chapters.push({ path: p, hasStyle: looksLikeFragments(content) });
}
return { id, min: from, max: to, chapters };
}
tryGetToc(id: number): string[] | null {
const p = this.tocPath(id);
if (!existsSync(p)) return null;
const lines = readFileSync(p, 'utf-8')
.split('\n')
.map(l => l.trim())
.filter(Boolean);
if (lines.length === 0) return null;
return lines;
}
saveChapters(id: number, chapters: { index: number; content: string }[]): ChapterFile[] {
this.ensureDir(id);
return chapters.map(({ index, content }) => {
const p = this.chapterPath(id, index);
writeFileSync(p, content, 'utf-8');
return { path: p, hasStyle: looksLikeFragments(content) };
});
}
saveToc(id: number, urls: string[]): void {
this.ensureDir(id);
writeFileSync(this.tocPath(id), urls.join('\n'), 'utf-8');
}
}