|
1 | | -import { getFile, putFile, listFiles, isFileCached } from './github'; |
| 1 | +import { getFile, putFile, listFiles } from './github'; |
2 | 2 | import { parseFrontmatter, stringifyFrontmatter, generateId, transliterate, normalizeText, slugify } from './utils'; |
3 | 3 |
|
4 | 4 | export interface Forum { |
@@ -45,30 +45,25 @@ function matchesSearch(item: { author: string; body: string }, options?: { autho |
45 | 45 | return true; |
46 | 46 | } |
47 | 47 |
|
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 | | - |
56 | 48 | export async function listForums(): Promise<Forum[]> { |
57 | 49 | try { |
58 | 50 | const files = await listFiles('forums'); |
59 | 51 | const forums: Forum[] = []; |
60 | 52 |
|
61 | | - await cacheFilePaths(files); |
62 | | - |
63 | | - for (const file of files) { |
64 | | - if (file.name.endsWith('.md') && file.path) { |
65 | | - const fileData = await getFile(file.path); |
66 | | - if (fileData) { |
67 | | - const { data } = parseFrontmatter<Forum>(fileData.content); |
68 | | - forums.push({ ...data, slug: file.name.replace('.md', '') }); |
69 | | - } |
| 53 | + // Load all files in parallel, cache them, no duplicate requests |
| 54 | + const fileDataPromises = files |
| 55 | + .filter(file => file.name.endsWith('.md') && file.path) |
| 56 | + .map(file => getFile(file.path!)); |
| 57 | + |
| 58 | + const fileDataArray = await Promise.all(fileDataPromises); |
| 59 | + |
| 60 | + fileDataArray.forEach((fileData, index) => { |
| 61 | + if (fileData) { |
| 62 | + const file = files[index]; |
| 63 | + const { data } = parseFrontmatter<Forum>(fileData.content); |
| 64 | + forums.push({ ...data, slug: file.name.replace('.md', '') }); |
70 | 65 | } |
71 | | - } |
| 66 | + }); |
72 | 67 |
|
73 | 68 | return forums.sort((a, b) => Number(a.order || 0) - Number(b.order || 0)); |
74 | 69 | } catch (error: any) { |
@@ -114,26 +109,29 @@ export async function listTopics(forumSlug: string, options?: { author?: string; |
114 | 109 | const files = await listFiles('topics'); |
115 | 110 | const topics: Topic[] = []; |
116 | 111 |
|
117 | | - await cacheFilePaths(files); |
118 | | - |
119 | | - for (const file of files) { |
120 | | - if (file.name.endsWith('.md') && file.path) { |
121 | | - const fileData = await getFile(file.path); |
122 | | - if (fileData) { |
123 | | - const { data, content } = parseFrontmatter<Topic>(fileData.content); |
124 | | - if (data.forumSlug === forumSlug) { |
125 | | - const topic = { |
126 | | - ...data, |
127 | | - id: file.name.replace('.md', ''), |
128 | | - body: content |
129 | | - }; |
130 | | - if (matchesSearch(topic, options)) { |
131 | | - topics.push(topic); |
132 | | - } |
| 112 | + // Load all files in parallel, cache them, no duplicate requests |
| 113 | + const fileDataPromises = files |
| 114 | + .filter(file => file.name.endsWith('.md') && file.path) |
| 115 | + .map(file => getFile(file.path!)); |
| 116 | + |
| 117 | + const fileDataArray = await Promise.all(fileDataPromises); |
| 118 | + const mdFiles = files.filter(file => file.name.endsWith('.md') && file.path); |
| 119 | + |
| 120 | + fileDataArray.forEach((fileData, index) => { |
| 121 | + if (fileData) { |
| 122 | + const { data, content } = parseFrontmatter<Topic>(fileData.content); |
| 123 | + if (data.forumSlug === forumSlug) { |
| 124 | + const topic = { |
| 125 | + ...data, |
| 126 | + id: mdFiles[index].name.replace('.md', ''), |
| 127 | + body: content |
| 128 | + }; |
| 129 | + if (matchesSearch(topic, options)) { |
| 130 | + topics.push(topic); |
133 | 131 | } |
134 | 132 | } |
135 | 133 | } |
136 | | - } |
| 134 | + }); |
137 | 135 |
|
138 | 136 | return topics.sort( |
139 | 137 | (a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime() |
@@ -188,26 +186,29 @@ export async function listPosts(topicId: string, options?: { author?: string; te |
188 | 186 | const files = await listFiles('posts'); |
189 | 187 | const posts: Post[] = []; |
190 | 188 |
|
191 | | - await cacheFilePaths(files); |
192 | | - |
193 | | - for (const file of files) { |
194 | | - if (file.name.endsWith('.md') && file.path) { |
195 | | - const fileData = await getFile(file.path); |
196 | | - if (fileData) { |
197 | | - const { data, content } = parseFrontmatter<Post>(fileData.content); |
198 | | - if (data.topicId === topicId) { |
199 | | - const post = { |
200 | | - ...data, |
201 | | - id: file.name.replace('.md', ''), |
202 | | - body: content |
203 | | - }; |
204 | | - if (matchesSearch(post, options)) { |
205 | | - posts.push(post); |
206 | | - } |
| 189 | + // Load all files in parallel, cache them, no duplicate requests |
| 190 | + const fileDataPromises = files |
| 191 | + .filter(file => file.name.endsWith('.md') && file.path) |
| 192 | + .map(file => getFile(file.path!)); |
| 193 | + |
| 194 | + const fileDataArray = await Promise.all(fileDataPromises); |
| 195 | + const mdFiles = files.filter(file => file.name.endsWith('.md') && file.path); |
| 196 | + |
| 197 | + fileDataArray.forEach((fileData, index) => { |
| 198 | + if (fileData) { |
| 199 | + const { data, content } = parseFrontmatter<Post>(fileData.content); |
| 200 | + if (data.topicId === topicId) { |
| 201 | + const post = { |
| 202 | + ...data, |
| 203 | + id: mdFiles[index].name.replace('.md', ''), |
| 204 | + body: content |
| 205 | + }; |
| 206 | + if (matchesSearch(post, options)) { |
| 207 | + posts.push(post); |
207 | 208 | } |
208 | 209 | } |
209 | 210 | } |
210 | | - } |
| 211 | + }); |
211 | 212 |
|
212 | 213 | return posts.sort( |
213 | 214 | (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime() |
|
0 commit comments