Skip to content

Commit 4c05e41

Browse files
committed
ft: save posts storage
1 parent 87c85a3 commit 4c05e41

2 files changed

Lines changed: 48 additions & 6 deletions

File tree

src/lib/forum.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getFile, putFile, listFiles } from './github';
1+
import { getFile, putFile, listFiles, isFileCached } from './github';
22
import { parseFrontmatter, stringifyFrontmatter, generateId, transliterate, normalizeText, slugify } from './utils';
33

44
export interface Forum {
@@ -45,12 +45,22 @@ function matchesSearch(item: { author: string; body: string }, options?: { autho
4545
return true;
4646
}
4747

48+
const cacheFilePaths = async (files: Array<{ name: string; path?: string }>) => {
49+
await Promise.all(
50+
files
51+
.filter(file => file.name.endsWith('.md') && file.path && !isFileCached(file.path))
52+
.map(file => getFile(file.path!))
53+
);
54+
};
55+
4856
export async function listForums(): Promise<Forum[]> {
4957
const files = await listFiles('forums');
5058
const forums: Forum[] = [];
5159

60+
await cacheFilePaths(files);
61+
5262
for (const file of files) {
53-
if (file.name.endsWith('.md')) {
63+
if (file.name.endsWith('.md') && file.path) {
5464
const fileData = await getFile(file.path);
5565
if (fileData) {
5666
const { data } = parseFrontmatter<Forum>(fileData.content);
@@ -88,8 +98,10 @@ export async function listTopics(forumSlug: string, options?: { author?: string;
8898
const files = await listFiles('topics');
8999
const topics: Topic[] = [];
90100

101+
await cacheFilePaths(files);
102+
91103
for (const file of files) {
92-
if (file.name.endsWith('.md')) {
104+
if (file.name.endsWith('.md') && file.path) {
93105
const fileData = await getFile(file.path);
94106
if (fileData) {
95107
const { data, content } = parseFrontmatter<Topic>(fileData.content);
@@ -148,8 +160,10 @@ export async function listPosts(topicId: string, options?: { author?: string; te
148160
const files = await listFiles('posts');
149161
const posts: Post[] = [];
150162

163+
await cacheFilePaths(files);
164+
151165
for (const file of files) {
152-
if (file.name.endsWith('.md')) {
166+
if (file.name.endsWith('.md') && file.path) {
153167
const fileData = await getFile(file.path);
154168
if (fileData) {
155169
const { data, content } = parseFrontmatter<Post>(fileData.content);

src/lib/github.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,24 @@ const headers: Record<string, string> = {
99
'Content-Type': 'application/json'
1010
};
1111

12+
const fileCache = new Map<string, { content: string; sha?: string }>();
13+
14+
export function getCachedFile(path: string) {
15+
return fileCache.get(path) || null;
16+
}
17+
18+
export function isFileCached(path: string) {
19+
return fileCache.has(path);
20+
}
21+
22+
export function clearFileCache(path?: string) {
23+
if (path) {
24+
fileCache.delete(path);
25+
} else {
26+
fileCache.clear();
27+
}
28+
}
29+
1230
// Remove token from headers - it will be added by service worker
1331
// if (token) {
1432
// headers.Authorization = `Bearer ${token}`;
@@ -58,6 +76,11 @@ async function createGitHubError(res: Response): Promise<Error> {
5876
}
5977

6078
export async function getFile(path: string) {
79+
const cached = fileCache.get(path);
80+
if (cached) {
81+
return { content: cached.content, sha: cached.sha };
82+
}
83+
6184
try {
6285
const res = await fetch(
6386
`${BASE}/repos/${owner}/${repo}/contents/${path}?ref=${branch}`,
@@ -70,7 +93,9 @@ export async function getFile(path: string) {
7093
const data = await res.json();
7194
if (data.content && !Array.isArray(data)) {
7295
const content = b64_to_utf8(data.content.replace(/\n/g, ''));
73-
return { content, sha: data.sha as string };
96+
const fileData = { content, sha: data.sha as string };
97+
fileCache.set(path, fileData);
98+
return fileData;
7499
}
75100
return null;
76101
} catch (error: any) {
@@ -102,7 +127,9 @@ sha?: string)
102127
if (!res.ok) {
103128
throw await createGitHubError(res);
104129
}
105-
return res.json();
130+
const data = await res.json();
131+
fileCache.set(path, { content, sha: data.content?.sha });
132+
return data;
106133
} catch (error: any) {
107134
handleApiError(error, 'putFile');
108135
}
@@ -137,6 +164,7 @@ export async function deleteFile(path: string, message: string, sha: string) {
137164
if (!res.ok) {
138165
throw await createGitHubError(res);
139166
}
167+
fileCache.delete(path);
140168
} catch (error: any) {
141169
handleApiError(error, 'deleteFile');
142170
}

0 commit comments

Comments
 (0)