Files
5chan/src/lib/utils/thread-refresh-cache-utils.ts
T
Tommaso CasaburiandGitHub 371de88e22 chore(architecture): finish refactor audit
Merge the architecture audit refactors and follow-up UX fixes: remove release notes from generated LLM context, keep author edit controls delete-only, stabilize board refresh rendering, and address review feedback for role loading, refresh holds, moderation actions, and P2P stats polling.
2026-06-23 18:48:47 +07:00

80 lines
3.1 KiB
TypeScript

import type { Comment, RepliesPages } from '@bitsocial/bitsocial-react-hooks';
import { repliesPagesStore } from '../bitsocial-internals/stores';
import { localForageLru } from '../bitsocial-internals/utils';
const commentsDatabase = localForageLru.createInstance({ name: 'bitsocialReactHooks-comments' });
const repliesPagesDatabase = localForageLru.createInstance({ name: 'bitsocialReactHooks-repliesPages' });
const getReplyPageSortTypes = (comment: Comment): string[] => {
const pageCids = comment.replies?.pageCids && typeof comment.replies.pageCids === 'object' ? comment.replies.pageCids : {};
const pages = comment.replies?.pages && typeof comment.replies.pages === 'object' ? comment.replies.pages : {};
return [...new Set([...Object.keys(pageCids), ...Object.keys(pages)])];
};
const getPersistedReplyPageStartCids = (comment: Comment, sortType: string): string[] => {
const pageCids = new Set<string>();
const firstPageCid = comment.replies?.pageCids?.[sortType];
const preloadedNextCid = comment.replies?.pages?.[sortType]?.nextCid;
if (typeof firstPageCid === 'string') pageCids.add(firstPageCid);
if (typeof preloadedNextCid === 'string') pageCids.add(preloadedNextCid);
return [...pageCids];
};
const collectReplyPageCids = (comment: Comment, repliesPages: RepliesPages): string[] => {
const pageCids = new Set<string>();
for (const sortType of getReplyPageSortTypes(comment)) {
for (const startPageCid of getPersistedReplyPageStartCids(comment, sortType)) {
let pageCid: string | undefined = startPageCid;
while (pageCid && !pageCids.has(pageCid)) {
pageCids.add(pageCid);
pageCid = repliesPages[pageCid]?.nextCid;
}
}
}
return [...pageCids];
};
const removeReplyPagesFromStore = (pageCids: string[]) => {
repliesPagesStore.setState((state) => {
const repliesPages = { ...state.repliesPages };
const comments = { ...state.comments };
let changed = false;
for (const pageCid of pageCids) {
const page = repliesPages[pageCid];
if (!page) continue;
for (const comment of page.comments || []) {
if (comment?.cid && comments[comment.cid]) {
delete comments[comment.cid];
}
}
delete repliesPages[pageCid];
changed = true;
}
return changed ? { repliesPages, comments } : {};
});
};
export const evictThreadRefreshCaches = async (comments: Array<Comment | undefined>) => {
const commentsToRefresh = comments.filter((comment): comment is Comment => Boolean(comment?.cid));
if (commentsToRefresh.length === 0) return;
const commentCids = [...new Set(commentsToRefresh.map((comment) => comment.cid as string))];
const currentReplyPages = repliesPagesStore.getState().repliesPages;
const replyPageCids = [...new Set(commentsToRefresh.flatMap((comment) => collectReplyPageCids(comment, currentReplyPages)))];
removeReplyPagesFromStore(replyPageCids);
await Promise.all([
...commentCids.map((commentCid) => commentsDatabase.removeItem(commentCid)),
...replyPageCids.map((pageCid) => repliesPagesDatabase.removeItem(pageCid)),
]);
};