@@ -100,13 +100,15 @@ interface ProcessedRelease {
100100function fetchWithRetry (
101101 url : string ,
102102 options : RequestInit ,
103- maxRetries = 3
103+ maxRetries = 5
104104) : Promise < Response > {
105105 async function attemptFetch ( attempt : number ) : Promise < Response > {
106106 const response = await fetch ( url , options ) ;
107107
108+ // GitHub stats endpoints return 202 when computing - wait longer
108109 if ( response . status === 202 && attempt < maxRetries ) {
109- await new Promise ( ( resolve ) => setTimeout ( resolve , 1000 ) ) ;
110+ const delay = Math . min ( 1000 * attempt , 5000 ) ; // Exponential backoff up to 5s
111+ await new Promise ( ( resolve ) => setTimeout ( resolve , delay ) ) ;
110112 return attemptFetch ( attempt + 1 ) ;
111113 }
112114
@@ -175,14 +177,28 @@ async function fetchCommitActivity(
175177 ) ;
176178
177179 if ( response . ok ) {
178- const data : GitHubCommitActivity [ ] = await response . json ( ) ;
179- if ( Array . isArray ( data ) ) {
180- return data . map ( ( week ) => ( {
181- week : new Date ( week . week * 1000 ) . toISOString ( ) . split ( 'T' ) [ 0 ] ,
182- commits : week . total ,
183- date : new Date ( week . week * 1000 ) ,
184- } ) ) ;
180+ const data = await response . json ( ) ;
181+ if ( Array . isArray ( data ) && data . length > 0 ) {
182+ return data
183+ . filter (
184+ ( week : unknown ) : week is GitHubCommitActivity =>
185+ week !== null &&
186+ typeof week === 'object' &&
187+ 'week' in week &&
188+ 'total' in week &&
189+ typeof ( week as GitHubCommitActivity ) . week === 'number' &&
190+ typeof ( week as GitHubCommitActivity ) . total === 'number'
191+ )
192+ . map ( ( week : GitHubCommitActivity ) => ( {
193+ week : new Date ( week . week * 1000 ) . toISOString ( ) . split ( 'T' ) [ 0 ] ,
194+ commits : week . total ,
195+ date : new Date ( week . week * 1000 ) ,
196+ } ) ) ;
185197 }
198+ } else {
199+ console . warn (
200+ `GitHub API returned ${ response . status } for commit activity`
201+ ) ;
186202 }
187203 } catch ( error ) {
188204 console . error ( 'Failed to fetch commit activity:' , error ) ;
@@ -200,15 +216,19 @@ async function fetchCodeFrequency(
200216 ) ;
201217
202218 if ( response . ok ) {
203- const data : GitHubCodeFrequency [ ] = await response . json ( ) ;
204- if ( Array . isArray ( data ) ) {
205- return data . map ( ( week ) => ( {
206- week : new Date ( week [ 0 ] * 1000 ) . toISOString ( ) . split ( 'T' ) [ 0 ] ,
207- additions : week [ 1 ] ,
208- deletions : Math . abs ( week [ 2 ] ) , // Make deletions positive for display
209- date : new Date ( week [ 0 ] * 1000 ) ,
210- } ) ) ;
219+ const data = await response . json ( ) ;
220+ if ( Array . isArray ( data ) && data . length > 0 ) {
221+ return data
222+ . filter ( ( week : unknown ) => Array . isArray ( week ) && week . length === 3 )
223+ . map ( ( week : GitHubCodeFrequency ) => ( {
224+ week : new Date ( week [ 0 ] * 1000 ) . toISOString ( ) . split ( 'T' ) [ 0 ] ,
225+ additions : week [ 1 ] ,
226+ deletions : Math . abs ( week [ 2 ] ) , // Make deletions positive for display
227+ date : new Date ( week [ 0 ] * 1000 ) ,
228+ } ) ) ;
211229 }
230+ } else {
231+ console . warn ( `GitHub API returned ${ response . status } for code frequency` ) ;
212232 }
213233 } catch ( error ) {
214234 console . error ( 'Failed to fetch code frequency:' , error ) ;
@@ -226,16 +246,20 @@ async function fetchPunchCard(
226246 ) ;
227247
228248 if ( response . ok ) {
229- const data : GitHubPunchCard [ ] = await response . json ( ) ;
230- if ( Array . isArray ( data ) ) {
249+ const data = await response . json ( ) ;
250+ if ( Array . isArray ( data ) && data . length > 0 ) {
231251 const dayNames = [ 'Sun' , 'Mon' , 'Tue' , 'Wed' , 'Thu' , 'Fri' , 'Sat' ] ;
232- return data . map ( ( item ) => ( {
233- day : item [ 0 ] ,
234- hour : item [ 1 ] ,
235- commits : item [ 2 ] ,
236- dayName : dayNames [ item [ 0 ] ] ,
237- } ) ) ;
252+ return data
253+ . filter ( ( item : unknown ) => Array . isArray ( item ) && item . length === 3 )
254+ . map ( ( item : GitHubPunchCard ) => ( {
255+ day : item [ 0 ] ,
256+ hour : item [ 1 ] ,
257+ commits : item [ 2 ] ,
258+ dayName : dayNames [ item [ 0 ] ] || 'Unknown' ,
259+ } ) ) ;
238260 }
261+ } else {
262+ console . warn ( `GitHub API returned ${ response . status } for punch card` ) ;
239263 }
240264 } catch ( error ) {
241265 console . error ( 'Failed to fetch punch card:' , error ) ;
@@ -274,19 +298,24 @@ async function fetchReleases(
274298}
275299
276300async function fetchGitHubData ( ) {
277- const headers = {
301+ const headers : Record < string , string > = {
278302 Accept : 'application/vnd.github.v3+json' ,
279303 'User-Agent' : 'Databuddy-Docs' ,
280304 } ;
281305
306+ // Add GitHub token if available for higher rate limits
307+ if ( process . env . GITHUB_TOKEN ) {
308+ headers . Authorization = `Bearer ${ process . env . GITHUB_TOKEN } ` ;
309+ }
310+
282311 const requestInit : RequestInit = {
283312 headers,
284- next : { revalidate : 600 } , // 10 minutes
313+ next : { revalidate : 900 } , // 15 minutes - more consistent timing
285314 } ;
286315
287316 const statsRequestInit : RequestInit = {
288317 headers,
289- next : { revalidate : 3600 } , // 1 hour for stats
318+ next : { revalidate : 900 } , // Same timing to avoid race conditions
290319 } ;
291320
292321 try {
0 commit comments