@@ -54,7 +54,8 @@ const stats = calculateStreak(
5454export function calculateStreak (
5555 calendar : ContributionCalendar ,
5656 timezone : string = 'UTC' ,
57- now : Date = new Date ( )
57+ now : Date = new Date ( ) ,
58+ grace : number = 1
5859) : StreakStats {
5960 const weeks = calendar . weeks ;
6061 const days = weeks . flatMap ( ( week ) => week . contributionDays ) ;
@@ -92,19 +93,25 @@ export function calculateStreak(
9293 } ;
9394 }
9495
95- const today = days [ todayIndex ] ;
96- const yesterday = todayIndex > 0 ? days [ todayIndex - 1 ] : null ;
97-
98- // If I committed today, the streak is alive.
99- // If I haven't committed today, but I committed yesterday,
100- // the streak is STILL alive (Grace Period).
101- const isStreakAlive = today . contributionCount > 0 || ( yesterday ?. contributionCount ?? 0 ) > 0 ;
96+ // If I committed today, or any day within the grace period (e.g. yesterday for grace=1),
97+ // the streak is STILL alive.
98+ let isStreakAlive = false ;
99+ for ( let i = 0 ; i <= grace ; i ++ ) {
100+ const checkIndex = todayIndex - i ;
101+ if ( checkIndex >= 0 && days [ checkIndex ] . contributionCount > 0 ) {
102+ isStreakAlive = true ;
103+ break ;
104+ }
105+ }
102106
103107 if ( isStreakAlive ) {
104- // Count backwards from the first day that has a contribution
105- // starting from either today or yesterday.
106- let i = today . contributionCount > 0 ? todayIndex : todayIndex - 1 ;
108+ // Find the most recent day with a contribution within the grace period
109+ let i = todayIndex ;
110+ while ( i >= todayIndex - grace && i >= 0 && days [ i ] . contributionCount === 0 ) {
111+ i -- ;
112+ }
107113
114+ // Count backwards from the first day that has a contribution
108115 while ( i >= 0 && days [ i ] . contributionCount > 0 ) {
109116 currentStreak ++ ;
110117 i -- ;
0 commit comments