// LinkSync Background Script // Handles bookmark synchronization with LinkSyncServer const Background = { syncInterval: null, SYNC_CHECK_INTERVAL: 300000, async init() { console.log("LinkSync: Initializing background script"); await API.init(); browser.runtime.onInstalled.addListener(() => { console.log("LinkSync: Extension installed"); this.startAutoSync(); }); browser.runtime.onMessage.addListener(this.handleMessage.bind(this)); browser.bookmarks.onCreated.addListener(this.onBookmarkChanged.bind(this)); browser.bookmarks.onChanged.addListener(this.onBookmarkChanged.bind(this)); browser.bookmarks.onRemoved.addListener(this.onBookmarkChanged.bind(this)); const settings = await browser.storage.local.get(["linksync_auto_sync"]); if (settings.linksync_auto_sync) { this.startAutoSync(); } }, startAutoSync() { if (this.syncInterval) { clearInterval(this.syncInterval); } this.syncInterval = setInterval(() => this.runSync(), this.SYNC_CHECK_INTERVAL); console.log("LinkSync: Auto-sync started (every 5 minutes)"); }, stopAutoSync() { if (this.syncInterval) { clearInterval(this.syncInterval); this.syncInterval = null; } }, async onBookmarkChanged(id, changeInfo) { const settings = await browser.storage.local.get(["linksync_auto_sync"]); if (settings.linksync_auto_sync) { await browser.storage.local.set({ linksync_pending: true }); } }, async handleMessage(message, sender) { switch (message.type) { case "SYNC_NOW": return this.runSync(); case "GET_SETTINGS": return browser.storage.local.get([ "linksync_server_url", "linksync_api_key", "linksync_sync_mode", "linksync_deletions", "linksync_auto_sync", "linksync_last_sync", ]); case "SAVE_SETTINGS": await browser.storage.local.set(message.data); await API.init(); if (message.data.linksync_auto_sync) { this.startAutoSync(); } else { this.stopAutoSync(); } return { success: true }; case "TEST_CONNECTION": try { await API.testConnection(); return { success: true }; } catch (e) { return { success: false, error: e.message }; } case "LOGIN": try { const data = await API.login(message.data.username, message.data.password); return { success: true, token: data.access_token }; } catch (e) { return { success: false, error: e.message }; } case "GET_BOOKMARKS": return API.getLinks(message.data || {}); case "CREATE_BOOKMARK": return API.createLink(message.data); case "UPDATE_BOOKMARK": return API.updateLink(message.data.id, message.data); case "DELETE_BOOKMARK": return API.deleteLink(message.data.id); case "GET_COLLECTIONS": return CollectionManager.listCollections(); case "EXECUTE_QUERY": return CollectionManager.executeQuery(message.data.expression, message.data.limit); case "PARSE_QUERY": return CollectionManager.parseQuery(message.data.expression); default: return null; } }, async runSync() { try { await browser.storage.local.set({ linksync_syncing: true }); const actions = await SyncEngine.runSync(); await browser.storage.local.set({ linksync_syncing: false, linksync_last_sync: new Date().toISOString(), linksync_pending: false, linksync_sync_result: actions, }); console.log(`LinkSync: Sync completed with ${actions.length} actions`); return { success: true, actions }; } catch (error) { console.error("LinkSync: Sync failed:", error); await browser.storage.local.set({ linksync_syncing: false, linksync_sync_error: error.message, }); return { success: false, error: error.message }; } }, }; document.addEventListener("DOMContentLoaded", () => Background.init());