Skip to content
File

Blob: src/client/lib/doc-cache-registry.ts

typescript69 lines
1import { getCachedCanvasKey, getCachedDocKey, STORAGE_KEYS } from "./constants";
2import { readVersionedStorageJson, writeVersionedStorageJson, removeStorageItem } from "./storage";
3 
4const VERSION = 1;
5 
6function parsePageIds(value: unknown): string[] | null {
7 if (!Array.isArray(value)) return null;
8 return value.filter((item): item is string => typeof item === "string" && item.length > 0);
9}
10 
11function getSet(): Set<string> {
12 const pageIds = readVersionedStorageJson(STORAGE_KEYS.CACHED_DOCS, VERSION, parsePageIds) ?? [];
13 return new Set(pageIds);
14}
15 
16function persist(set: Set<string>) {
17 writeVersionedStorageJson(STORAGE_KEYS.CACHED_DOCS, VERSION, [...set]);
18}
19 
20function dropIndexedDbCaches(pageIds: string[]): void {
21 if (pageIds.length === 0) return;
22 import("y-indexeddb")
23 .then((m) => {
24 for (const id of pageIds) {
25 m.clearDocument(getCachedDocKey(id)).catch(() => {});
26 m.clearDocument(getCachedCanvasKey(id)).catch(() => {});
27 }
28 })
29 .catch(() => {});
30}
31 
32/**
33 * Authoritative registry for "this page's Yjs state is persisted locally." Owns
34 * both the localStorage hint set and the `y-indexeddb` lifecycle for the doc
35 * and canvas namespaces of listed pages. Callers should not import
36 * `y-indexeddb` directly for eviction — use {@link docCache.remove} instead,
37 * so a single call clears every persisted namespace for the page id.
38 *
39 * Cleanup is fire-and-forget: IDB purges are dispatched but not awaited, so
40 * callers don't block user flows on storage housekeeping.
41 */
42export const docCache = {
43 has(pageId: string): boolean {
44 return getSet().has(pageId);
45 },
46 
47 mark(pageId: string): void {
48 const set = getSet();
49 if (!set.has(pageId)) {
50 set.add(pageId);
51 persist(set);
52 }
53 },
54 
55 remove(pageId: string): void {
56 const set = getSet();
57 if (set.delete(pageId)) {
58 persist(set);
59 }
60 dropIndexedDbCaches([pageId]);
61 },
62 
63 clearAll(): void {
64 const pageIds = [...getSet()];
65 removeStorageItem(STORAGE_KEYS.CACHED_DOCS);
66 dropIndexedDbCaches(pageIds);
67 },
68};