Files
cost-dev/src/background.ts
T

63 lines
2.0 KiB
TypeScript

import { loadState, saveState, sumMonthUsages, projectedMonthEnd } from './storage'
const ALARM_NAME = 'costdev_budget_check'
chrome.runtime.onInstalled.addListener(async () => {
await chrome.alarms.create(ALARM_NAME, { periodInMinutes: 60 })
})
chrome.alarms.onAlarm.addListener(async (alarm) => {
if (alarm.name !== ALARM_NAME) return
const state = await loadState()
if (!state.budget.enabled || state.budget.monthlyLimit <= 0) return
const spent = sumMonthUsages(state.usages)
const limit = state.budget.monthlyLimit
const threshold = limit * state.budget.alertThreshold
if (spent >= threshold && spent < limit) {
const last = state.lastAlertAt ?? 0
if (Date.now() - last > 24 * 60 * 60 * 1000) {
chrome.notifications.create('costdev-warning', {
type: 'basic',
iconUrl: 'icons/icon128.png',
title: 'Cost.dev — Budget Alert',
message: `You've spent $${spent.toFixed(2)} of your $${limit.toFixed(2)} monthly budget.`,
priority: 1,
})
state.lastAlertAt = Date.now()
await saveState(state)
}
}
if (spent >= limit) {
const last = state.lastAlertAt ?? 0
if (Date.now() - last > 24 * 60 * 60 * 1000) {
chrome.notifications.create('costdev-over', {
type: 'basic',
iconUrl: 'icons/icon128.png',
title: 'Cost.dev — Budget Overrun',
message: `You've exceeded your $${limit.toFixed(2)} monthly budget! Current spend: $${spent.toFixed(2)}.`,
priority: 2,
})
state.lastAlertAt = Date.now()
await saveState(state)
}
}
})
chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
;(async () => {
if (message.type === 'budget-check') {
const state = await loadState()
const spent = sumMonthUsages(state.usages)
const limit = state.budget.monthlyLimit
const projected = projectedMonthEnd(spent)
sendResponse({ spent, limit, projected, enabled: state.budget.enabled })
} else {
sendResponse({ ok: false })
}
})()
return true
})