[READ-ONLY] a fast, modern browser for the npm registry
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: restore default date range for weekly download chart (#181)

authored by

Alec Lloyd Probert and committed by
GitHub
0d28eb47 baf79a98

+36 -49
+36 -49
app/composables/useCharts.ts
··· 122 122 .map(([day, downloads]) => ({ day, downloads })) 123 123 } 124 124 125 - function getIsoWeekStartDateFromWeekKey(weekKey: string): Date | null { 126 - const match = /^(\d{4})-W(\d{2})$/.exec(weekKey) 127 - if (!match) return null 128 - 129 - const year = Number(match[1]) 130 - const week = Number(match[2]) 131 - 132 - const januaryFourth = new Date(Date.UTC(year, 0, 4)) 133 - const januaryFourthIsoDay = januaryFourth.getUTCDay() || 7 134 - const weekOneMonday = new Date(Date.UTC(year, 0, 4 - (januaryFourthIsoDay - 1))) 135 - 136 - const weekMonday = new Date(weekOneMonday) 137 - weekMonday.setUTCDate(weekOneMonday.getUTCDate() + (week - 1) * 7) 138 - return weekMonday 139 - } 140 - 141 - function toIsoWeekKey(isoDay: string): string { 142 - const date = new Date(`${isoDay}T00:00:00.000Z`) 143 - const isoDayOfWeek = date.getUTCDay() || 7 144 - 145 - const thursday = new Date(date) 146 - thursday.setUTCDate(date.getUTCDate() + 4 - isoDayOfWeek) 147 - 148 - const isoYear = thursday.getUTCFullYear() 149 - const isoYearStart = new Date(Date.UTC(isoYear, 0, 1)) 150 - const weekNumber = Math.ceil(((+thursday - +isoYearStart) / 86400000 + 1) / 7) 151 - 152 - return `${isoYear}-W${String(weekNumber).padStart(2, '0')}` 153 - } 154 - 155 125 function buildDailyEvolutionFromDaily( 156 126 daily: Array<{ day: string; downloads: number }>, 157 127 ): DailyDownloadPoint[] { ··· 161 131 .map(item => ({ day: item.day, downloads: item.downloads })) 162 132 } 163 133 164 - function buildWeeklyEvolutionFromDaily( 134 + function buildRollingWeeklyEvolutionFromDaily( 165 135 daily: Array<{ day: string; downloads: number }>, 136 + rangeStartIso: string, 137 + rangeEndIso: string, 166 138 ): WeeklyDownloadPoint[] { 167 139 const sorted = daily.slice().sort((a, b) => a.day.localeCompare(b.day)) 168 - const downloadsByWeekKey = new Map<string, number>() 140 + const rangeStartDate = parseIsoDateOnly(rangeStartIso) 141 + const rangeEndDate = parseIsoDateOnly(rangeEndIso) 142 + 143 + const groupedByIndex = new Map<number, number>() 169 144 170 145 for (const item of sorted) { 171 - const weekKey = toIsoWeekKey(item.day) 172 - downloadsByWeekKey.set(weekKey, (downloadsByWeekKey.get(weekKey) ?? 0) + item.downloads) 146 + const itemDate = parseIsoDateOnly(item.day) 147 + const dayOffset = Math.floor((itemDate.getTime() - rangeStartDate.getTime()) / 86400000) 148 + if (dayOffset < 0) continue 149 + 150 + const weekIndex = Math.floor(dayOffset / 7) 151 + groupedByIndex.set(weekIndex, (groupedByIndex.get(weekIndex) ?? 0) + item.downloads) 173 152 } 174 153 175 - return Array.from(downloadsByWeekKey.entries()) 176 - .sort(([a], [b]) => a.localeCompare(b)) 177 - .map(([weekKey, downloads]) => { 178 - const weekStartDate = getIsoWeekStartDateFromWeekKey(weekKey) 179 - if (!weekStartDate) return { weekKey, downloads, weekStart: '-', weekEnd: '-' } 154 + return Array.from(groupedByIndex.entries()) 155 + .sort(([a], [b]) => a - b) 156 + .map(([weekIndex, downloads]) => { 157 + const weekStartDate = addDays(rangeStartDate, weekIndex * 7) 158 + const weekEndDate = addDays(weekStartDate, 6) 159 + 160 + // Clamp weekEnd to the actual data range end date 161 + const clampedWeekEndDate = 162 + weekEndDate.getTime() > rangeEndDate.getTime() ? rangeEndDate : weekEndDate 180 163 181 - const weekEndDate = addDays(weekStartDate, 6) 164 + const weekStartIso = toIsoDateString(weekStartDate) 165 + const weekEndIso = toIsoDateString(clampedWeekEndDate) 182 166 183 167 return { 184 - weekKey, 185 168 downloads, 186 - weekStart: toIsoDateString(weekStartDate), 187 - weekEnd: toIsoDateString(weekEndDate), 169 + weekKey: `${weekStartIso}_${weekEndIso}`, 170 + weekStart: weekStartIso, 171 + weekEnd: weekEndIso, 188 172 } 189 173 }) 190 174 } ··· 341 325 ) 342 326 } else if (downloadEvolutionOptions.granularity === 'week') { 343 327 const weekCount = downloadEvolutionOptions.weeks ?? 52 328 + 329 + // Full rolling weeks ending on `end` (yesterday by default) 330 + // Range length is exactly weekCount * 7 days (inclusive) 344 331 start = addDays(end, -(weekCount * 7) + 1) 345 332 } else { 346 333 start = addDays(end, -30 + 1) ··· 362 349 363 350 const { start, end } = resolveDateRange(resolvedOptions, resolvedCreatedIso) 364 351 365 - const sortedDaily = await fetchDailyRangeChunked( 366 - resolvedPackageName, 367 - toIsoDateString(start), 368 - toIsoDateString(end), 369 - ) 352 + const startIso = toIsoDateString(start) 353 + const endIso = toIsoDateString(end) 354 + 355 + const sortedDaily = await fetchDailyRangeChunked(resolvedPackageName, startIso, endIso) 370 356 371 357 if (resolvedOptions.granularity === 'day') return buildDailyEvolutionFromDaily(sortedDaily) 372 - if (resolvedOptions.granularity === 'week') return buildWeeklyEvolutionFromDaily(sortedDaily) 358 + if (resolvedOptions.granularity === 'week') 359 + return buildRollingWeeklyEvolutionFromDaily(sortedDaily, startIso, endIso) 373 360 if (resolvedOptions.granularity === 'month') return buildMonthlyEvolutionFromDaily(sortedDaily) 374 361 return buildYearlyEvolutionFromDaily(sortedDaily) 375 362 }