Allow check intervals as low as 10 seconds

- Switch from Chrome alarms (30s min) to setTimeout loops
- Config now uses checkIntervalSeconds instead of minutes
- Default: 15 seconds, minimum: 10 seconds
- Prevents overlapping checks with isChecking flag
- Updated popup UI to show seconds

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-03-24 18:24:38 -04:00
parent 8f526976bc
commit d03f963e7b
3 changed files with 62 additions and 30 deletions
+55 -24
View File
@@ -2,7 +2,7 @@
const DEFAULT_CONFIG = {
discordWebhook: "",
checkIntervalMinutes: 1,
checkIntervalSeconds: 15, // Now in SECONDS, not minutes!
enabled: true,
urls: [
"https://www.pokemoncenter.com/category/tcg-cards?sort=relevance"
@@ -16,37 +16,62 @@ const DEFAULT_CONFIG = {
let knownProducts = {};
let config = DEFAULT_CONFIG;
let persistentTabId = null; // Keep tab open for faster refreshes
let checkLoopRunning = false; // Prevent multiple loops
let isChecking = false; // Prevent overlapping checks
// Initialize
chrome.runtime.onInstalled.addListener(() => {
console.log("Pokemon Stock Monitor installed");
loadConfig();
loadConfig().then(() => {
loadProducts();
setupAlarm();
startCheckLoop();
});
});
// Load on startup
chrome.runtime.onStartup.addListener(() => {
loadConfig();
loadConfig().then(() => {
loadProducts();
setupAlarm();
});
// Handle alarm
chrome.alarms.onAlarm.addListener((alarm) => {
if (alarm.name === "stockCheck") {
runStockCheck();
}
});
// Setup periodic alarm
function setupAlarm() {
// Chrome minimum is 0.5 minutes (30 seconds) for packed extensions
const interval = Math.max(0.5, config.checkIntervalMinutes);
chrome.alarms.create("stockCheck", {
periodInMinutes: interval
startCheckLoop();
});
console.log(`Alarm set for every ${interval} minute(s) (${interval * 60} seconds)`);
});
// Start the check loop (uses setTimeout to bypass Chrome's 30-sec alarm minimum)
function startCheckLoop() {
if (checkLoopRunning) {
console.log("Check loop already running");
return;
}
checkLoopRunning = true;
console.log(`Starting check loop: every ${config.checkIntervalSeconds} seconds`);
scheduleNextCheck();
}
function scheduleNextCheck() {
if (!config.enabled || !checkLoopRunning) {
checkLoopRunning = false;
console.log("Check loop stopped");
return;
}
const intervalMs = Math.max(10, config.checkIntervalSeconds) * 1000; // Min 10 seconds
setTimeout(async () => {
if (!isChecking && config.enabled) {
isChecking = true;
try {
await runStockCheck();
} finally {
isChecking = false;
}
}
scheduleNextCheck();
}, intervalMs);
}
function stopCheckLoop() {
checkLoopRunning = false;
console.log("Check loop stopped");
}
// Load config from storage
@@ -61,7 +86,11 @@ async function loadConfig() {
// Save config to storage
async function saveConfig() {
await chrome.storage.local.set({ config });
setupAlarm(); // Reset alarm with new interval
// Restart loop with new interval
stopCheckLoop();
if (config.enabled) {
startCheckLoop();
}
}
// Load known products from storage
@@ -381,9 +410,11 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
setTimeout(() => {
loadConfig().then(() => {
loadProducts().then(() => {
if (config.enabled && config.discordWebhook) {
if (config.enabled) {
console.log(`Check interval: ${config.checkIntervalSeconds} seconds`);
runStockCheck();
startCheckLoop();
}
});
});
}, 5000);
}, 3000);
+3 -2
View File
@@ -214,8 +214,9 @@
<div class="row">
<div>
<label>Check Interval (min)</label>
<input type="number" id="interval" min="1" max="60" value="1">
<label>Check Interval (seconds)</label>
<input type="number" id="interval" min="10" max="300" value="15">
<small>Min 10 sec. Recommended: 15-30 sec</small>
</div>
</div>
+2 -2
View File
@@ -9,7 +9,7 @@ document.addEventListener("DOMContentLoaded", async () => {
document.getElementById("webhook").value = config.discordWebhook || "";
document.getElementById("urls").value = (config.urls || []).join("\n");
document.getElementById("keywords").value = (config.keywords || []).join(", ");
document.getElementById("interval").value = config.checkIntervalMinutes || 1;
document.getElementById("interval").value = config.checkIntervalSeconds || 15;
document.getElementById("enabled").checked = config.enabled !== false;
document.getElementById("notifyNew").checked = config.notifyNewProducts !== false;
document.getElementById("notifyRestock").checked = config.notifyRestocks !== false;
@@ -27,7 +27,7 @@ document.addEventListener("DOMContentLoaded", async () => {
discordWebhook: document.getElementById("webhook").value.trim(),
urls: urlsText.split("\n").map(u => u.trim()).filter(u => u),
keywords: keywordsText.split(",").map(k => k.trim()).filter(k => k),
checkIntervalMinutes: parseInt(document.getElementById("interval").value) || 1,
checkIntervalSeconds: parseInt(document.getElementById("interval").value) || 15,
enabled: document.getElementById("enabled").checked,
notifyNewProducts: document.getElementById("notifyNew").checked,
notifyRestocks: document.getElementById("notifyRestock").checked