diff --git a/chrome-extension/background.js b/chrome-extension/background.js index dbf2907..fda5394 100644 --- a/chrome-extension/background.js +++ b/chrome-extension/background.js @@ -15,6 +15,7 @@ const DEFAULT_CONFIG = { // Store known products let knownProducts = {}; let config = DEFAULT_CONFIG; +let persistentTabId = null; // Keep tab open for faster refreshes // Initialize chrome.runtime.onInstalled.addListener(() => { @@ -129,53 +130,82 @@ async function runStockCheck() { async function fetchAndParseProducts(url) { return new Promise(async (resolve, reject) => { try { - // Create a tab to load the page - const tab = await chrome.tabs.create({ url, active: false }); + let tabId; + let isNewTab = false; - console.log(`Created tab ${tab.id} for ${url}`); + // Reuse existing tab or create new one + if (persistentTabId) { + try { + const tab = await chrome.tabs.get(persistentTabId); + tabId = tab.id; + console.log(`Reusing tab ${tabId}, refreshing...`); + await chrome.tabs.update(tabId, { url }); + } catch (e) { + // Tab was closed, create new one + persistentTabId = null; + } + } + + if (!persistentTabId) { + const tab = await chrome.tabs.create({ url, active: false }); + tabId = tab.id; + persistentTabId = tabId; + isNewTab = true; + console.log(`Created new tab ${tabId}`); + } // Wait for tab to finish loading const waitForLoad = () => { return new Promise((res) => { - const listener = (tabId, changeInfo) => { - if (tabId === tab.id && changeInfo.status === "complete") { + const listener = (tid, changeInfo) => { + if (tid === tabId && changeInfo.status === "complete") { chrome.tabs.onUpdated.removeListener(listener); res(); } }; chrome.tabs.onUpdated.addListener(listener); - - // Timeout after 30 seconds setTimeout(() => { chrome.tabs.onUpdated.removeListener(listener); res(); - }, 30000); + }, 20000); }); }; await waitForLoad(); - console.log(`Tab ${tab.id} loaded`); + console.log(`Tab ${tabId} loaded`); - // Give extra time for dynamic content to load - console.log("Waiting for dynamic content..."); - await new Promise(r => setTimeout(r, 10000)); // 10 seconds for slow loads - - // Send message to content script to extract products + // Smart wait: poll for products instead of fixed wait let products = []; - try { - const response = await chrome.tabs.sendMessage(tab.id, { type: "extractProducts" }); - products = response || []; - console.log(`Content script returned ${products.length} products`); - } catch (e) { - console.log("Content script not ready, injecting manually..."); - // Inject content script if not already there - await chrome.scripting.executeScript({ - target: { tabId: tab.id }, - files: ["content.js"] - }); - await new Promise(r => setTimeout(r, 500)); - const response = await chrome.tabs.sendMessage(tab.id, { type: "extractProducts" }); - products = response || []; + const startTime = Date.now(); + const maxWait = 8000; // Max 8 seconds + const pollInterval = 500; // Check every 500ms + + while (Date.now() - startTime < maxWait) { + try { + // Inject content script if needed + try { + await chrome.scripting.executeScript({ + target: { tabId }, + files: ["content.js"] + }); + } catch (e) { /* Already injected */ } + + await new Promise(r => setTimeout(r, pollInterval)); + + const response = await chrome.tabs.sendMessage(tabId, { type: "extractProducts" }); + products = response || []; + + if (products.length > 0) { + console.log(`Found ${products.length} products after ${Date.now() - startTime}ms`); + break; + } + } catch (e) { + // Content script not ready yet + } + } + + if (products.length === 0) { + console.log(`No products found after ${maxWait}ms`); } // Apply keyword filter @@ -187,13 +217,11 @@ async function fetchAndParseProducts(url) { console.log(`After keyword filter: ${products.length} products`); } - // Close the tab - await chrome.tabs.remove(tab.id); - console.log(`Closed tab ${tab.id}`); - + // Don't close tab - keep for reuse resolve(products); } catch (error) { + persistentTabId = null; // Reset on error reject(error); } });