also looking at this
refactor(safari): migrate the safari pipeline to the framework buddy commands
#3
4 files
+28
-6
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | import { normalizeHostname } from '../shared/domain' |
| 2 | import { formatBytes, formatMinutes } from '../shared/metrics' | |
| 2 | import { formatBytes, formatMinutes, localDayKey } from '../shared/metrics' | |
| 3 | 3 | import type { DashboardState, RuntimeMessage } from '../shared/types' |
| 4 | 4 | import { byId, downloadJson, relativeTime, renderBars, sendMessage } from './dom' |
| 5 | 5 | import { sourceLabel } from './labels' |
| @@ -187,7 +187,7 @@ function render(next: DashboardState): void { | ||
| 187 | 187 | elements.blocked.textContent = next.lifetime.adsBlocked.toLocaleString() |
| 188 | 188 | elements.data.textContent = formatBytes(next.lifetime.bytesSaved) |
| 189 | 189 | elements.video.textContent = formatMinutes(next.lifetime.videoSecondsSaved) |
| 190 | const todayKey = new Date().toISOString().slice(0, 10) | |
| 190 | const todayKey = localDayKey() | |
| 191 | 191 | const today = next.local.daily.find(bucket => bucket.key === todayKey) |
| 192 | 192 | elements.today.textContent = (today?.adsBlocked ?? 0).toLocaleString() |
| 193 | 193 | elements.enabled.checked = next.settings.enabled |
| @@ -1,5 +1,5 @@ | ||
| 1 | 1 | import { describe, expect, it } from 'bun:test' |
| 2 | import { categoryForRequestType, estimateBytesSaved, estimateVideoAdBytes, estimateVideoSecondsSaved, eventTotals, formatBytes, formatMinutes } from '../src/shared/metrics' | |
| 2 | import { categoryForRequestType, estimateBytesSaved, estimateVideoAdBytes, estimateVideoSecondsSaved, eventTotals, formatBytes, formatMinutes, localDayKey } from '../src/shared/metrics' | |
| 3 | 3 | |
| 4 | 4 | describe('metrics', () => { |
| 5 | 5 | it('formats estimated savings', () => { |
| @@ -32,6 +32,14 @@ describe('metrics', () => { | ||
| 32 | 32 | expect(categoryForRequestType('something-else')).toBe('other') |
| 33 | 33 | }) |
| 34 | 34 | |
| 35 | it('keys days by the local calendar, not UTC', () => { | |
| 36 | // 23:30 local must stay on the local day regardless of the host timezone — | |
| 37 | // this is what makes "Blocked today" roll over at local midnight. | |
| 38 | expect(localDayKey(new Date(2026, 6, 5, 23, 30))).toBe('2026-07-05') | |
| 39 | expect(localDayKey(new Date(2026, 0, 1, 0, 30))).toBe('2026-01-01') | |
| 40 | expect(localDayKey()).toMatch(/^\d{4}-\d{2}-\d{2}$/) | |
| 41 | }) | |
| 42 | ||
| 35 | 43 | it('rolls up block events', () => { |
| 36 | 44 | const totals = eventTotals([ |
| 37 | 45 | { |