import '../webextension-polyfill'; import { RpcServer } from 'webextension-rpc'; import type { WebAnnotation } from 'web-annotation-utils'; import { Annotation, IAnnotation, IAnnotationWithSource } from '../storage/Annotation'; import { AnnotationSource, AnnotationSourceDescriptor, } from '../storage/AnnotationSource'; import './detect-annotation'; import './context-menu'; const backgroundRpcServer = new RpcServer({ async getAnnotationsForTargetUrls(urls: string[]): Promise { const annotations = await Annotation.getAnnotationsForUrls(urls); const annotationsWithSources = await Promise.all(annotations.map(async (a) => a.expand())); return annotationsWithSources }, refreshAnnotationSource: async ( source: AnnotationSourceDescriptor, force = false, ) => { const sourceObj = await AnnotationSource.getByUrl(source.url); await sourceObj.refresh(force); }, refreshAnnotationSources, addAnnotationSource: async (source: AnnotationSourceDescriptor) => AnnotationSource.addSource(source), isSourceSubscribed: async (source: AnnotationSourceDescriptor) => AnnotationSource.exists(source), removeSource: async (sourceDescriptor: AnnotationSourceDescriptor) => { const sourceObj = await AnnotationSource.getByUrl(sourceDescriptor.url); await sourceObj.delete(); }, async createAnnotation(annotationStub: Partial) { const annotation = await AnnotationSource.createAnnotation(annotationStub); return await annotation.expand(); }, async updateAnnotation(id: IAnnotation['_id'], webAnnotation: WebAnnotation) { const annotation = await Annotation.get(id); await annotation.update(webAnnotation); }, async deleteAnnotation(id: IAnnotation['_id']) { const annotation = await Annotation.get(id); await annotation.delete(); }, }); export type { backgroundRpcServer }; async function refreshAnnotationSources({ forceAll = false, }: { forceAll?: boolean } = {}) { const sourcesToUpdate = await (forceAll ? AnnotationSource.getActiveSources() : AnnotationSource.getSourcesNeedingUpdate()); console.log(`Will update ${sourcesToUpdate.length} sources.`); await Promise.all( sourcesToUpdate.map(async (source) => { try { await source.refresh(); } catch (error) { console.log( `Failed to refresh source “${source.data.title}” <${source.data.url}>`, error, ); } }), ); } main(); async function main() { await refreshAnnotationSources(); await browser.alarms.clearAll(); browser.alarms.create('annotationPeriodicRefresh', { periodInMinutes: 1 }); if (!browser.alarms.onAlarm.hasListener(handleAlarm)) { browser.alarms.onAlarm.addListener(handleAlarm); } } async function handleAlarm(alarm: browser.alarms.Alarm) { if (alarm.name !== 'annotationPeriodicRefresh') return; await refreshAnnotationSources(); }