@@ -112,18 +112,26 @@ export interface SectionRevision {
112112 path : string ;
113113}
114114
115+ const publicFileCache = new Map < string , Promise < string > > ( ) ;
115116async function readPublicFile ( path : string ) : Promise < string > {
116117 try {
117118 if ( isCloudflare ( ) ) {
118- const cfAssets = getCloudflareContext ( ) . env . ASSETS ;
119- const res = await cfAssets ! . fetch ( `https://assets.local/${ path } ` ) ;
120- if ( ! res . ok ) {
121- console . error (
122- `Failed to fetch ${ path } : ${ res . status } ${ await res . text ( ) } `
123- ) ;
124- notFound ( ) ;
119+ if ( publicFileCache . has ( path ) ) {
120+ return publicFileCache . get ( path ) ! ;
125121 }
126- return await res . text ( ) ;
122+ const p = ( async ( ) => {
123+ const cfAssets = getCloudflareContext ( ) . env . ASSETS ;
124+ const res = await cfAssets ! . fetch ( `https://assets.local/${ path } ` ) ;
125+ if ( ! res . ok ) {
126+ console . error (
127+ `Failed to fetch ${ path } : ${ res . status } ${ await res . text ( ) } `
128+ ) ;
129+ notFound ( ) ;
130+ }
131+ return await res . text ( ) ;
132+ } ) ( ) ;
133+ publicFileCache . set ( path , p ) ;
134+ return p ;
127135 } else {
128136 return await readFile ( join ( process . cwd ( ) , "public" , path ) , "utf-8" ) ;
129137 }
@@ -167,15 +175,27 @@ export async function getPagesList(): Promise<LanguageEntry[]> {
167175 ) ;
168176}
169177
170- export async function getSectionsList (
178+ export async function getRevisions (
179+ sectionId : SectionId
180+ ) : Promise < RevisionYmlEntry | undefined > {
181+ const revisionsYml = await readPublicFile ( `docs/revisions.yml` ) ;
182+ return ( yaml . load ( revisionsYml ) as Record < string , RevisionYmlEntry > ) [
183+ sectionId
184+ ] ;
185+ }
186+
187+ /**
188+ * public/docs/{lang}/{pageId}/ 以下のmdファイルを結合して MarkdownSection[] を返す。
189+ */
190+ export async function getMarkdownSections (
171191 lang : LangId ,
172192 page : PageSlug
173- ) : Promise < string [ ] > {
193+ ) : Promise < MarkdownSection [ ] > {
174194 if ( isCloudflare ( ) ) {
175195 const sectionsJson = await readPublicFile (
176196 `docs/${ lang } /${ page } /sections.json`
177197 ) ;
178- return JSON . parse ( sectionsJson ) as string [ ] ;
198+ return JSON . parse ( sectionsJson ) as MarkdownSection [ ] ;
179199 } else {
180200 function naturalSortMdFiles ( a : string , b : string ) : number {
181201 // -intro.md always comes first
@@ -191,48 +211,31 @@ export async function getSectionsList(
191211 }
192212 return a . localeCompare ( b ) ;
193213 }
194- return ( await readdir ( join ( process . cwd ( ) , "public" , "docs" , lang , page ) ) )
214+ const files = (
215+ await readdir ( join ( process . cwd ( ) , "public" , "docs" , lang , page ) )
216+ )
195217 . filter ( ( f ) => f . endsWith ( ".md" ) )
196218 . sort ( naturalSortMdFiles ) ;
197- }
198- }
199219
200- export async function getRevisions (
201- sectionId : SectionId
202- ) : Promise < RevisionYmlEntry | undefined > {
203- const revisionsYml = await readPublicFile ( `docs/revisions.yml` ) ;
204- return ( yaml . load ( revisionsYml ) as Record < string , RevisionYmlEntry > ) [
205- sectionId
206- ] ;
207- }
208-
209- /**
210- * public/docs/{lang}/{pageId}/ 以下のmdファイルを結合して MarkdownSection[] を返す。
211- */
212- export async function getMarkdownSections (
213- lang : LangId ,
214- page : PageSlug
215- ) : Promise < MarkdownSection [ ] > {
216- const files = await getSectionsList ( lang , page ) ;
217-
218- const sections : MarkdownSection [ ] = [ ] ;
219- for ( const file of files ) {
220- const raw = await readPublicFile ( `docs/${ lang } /${ page } /${ file } ` ) ;
221- if ( file === "-intro.md" ) {
222- // イントロセクションはフロントマターなし・見出しなし
223- sections . push ( {
224- file,
225- id : introSectionId ( { lang, page } ) ,
226- level : 1 ,
227- title : "" ,
228- rawContent : raw ,
229- md5 : crypto . createHash ( "md5" ) . update ( raw ) . digest ( "base64" ) ,
230- } ) ;
231- } else {
232- sections . push ( parseFrontmatter ( raw , file ) ) ;
220+ const sections : MarkdownSection [ ] = [ ] ;
221+ for ( const file of files ) {
222+ const raw = await readPublicFile ( `docs/${ lang } /${ page } /${ file } ` ) ;
223+ if ( file === "-intro.md" ) {
224+ // イントロセクションはフロントマターなし・見出しなし
225+ sections . push ( {
226+ file,
227+ id : introSectionId ( { lang, page } ) ,
228+ level : 1 ,
229+ title : "" ,
230+ rawContent : raw ,
231+ md5 : crypto . createHash ( "md5" ) . update ( raw ) . digest ( "base64" ) ,
232+ } ) ;
233+ } else {
234+ sections . push ( parseFrontmatter ( raw , file ) ) ;
235+ }
233236 }
237+ return sections ;
234238 }
235- return sections ;
236239}
237240export function introSectionId ( path : PagePath ) {
238241 return `${ path . lang } -${ path . page } -intro` as SectionId ;
0 commit comments