import { browser, Runtime } from "webextension-polyfill-ts"; import { Communicator, commandList, commandFunction } from "../communicator"; import { newPromise } from "../utils"; interface BackgroundCommands extends commandList { translationFinished: TranslationMessage; languageList: LanguageListMessage; } interface ContentScriptCommands extends commandList { translationRequest: TranslationRequest; } interface TranslationMessage extends commandFunction { args: Translation; } interface LanguageListMessage extends commandFunction { args: Array<Language>; } interface TranslationRequest extends commandFunction { args: string; } export class BackgroundMessenger extends Communicator< BackgroundCommands, ContentScriptCommands > { conn: Promise<Runtime.Port>; private resolvConn: (p: Runtime.Port) => void; constructor() { super(); [this.conn, this.resolvConn] = newPromise<Runtime.Port>(); browser.runtime.onConnect.addListener((p) => { if (p.name != "gtranslate_scraper_conn") return; this.resolvConn(p); p.onDisconnect.addListener( () => ([this.conn, this.resolvConn] = newPromise<Runtime.Port>()) ); p.onMessage.addListener((m) => this.onMessage(m, p.sender!)); }); } async runCommand<K extends keyof ContentScriptCommands>( command: K, args: ContentScriptCommands[K]["args"] ) { const msg = this.getCommandMessage(command, args); (await this.conn).postMessage(msg); } } export class ContentScriptMessenger extends Communicator< ContentScriptCommands, BackgroundCommands > { conn: Runtime.Port; constructor() { super(); this.conn = browser.runtime.connect({ name: "gtranslate_scraper_conn", // eslint-disable-next-line @typescript-eslint/no-explicit-any } as any); //The declaration file is wrong this.conn.onMessage.addListener((m) => this.onMessage(m)); } async runCommand<K extends keyof BackgroundCommands>( command: K, args: BackgroundCommands[K]["args"] ) { const msg = this.getCommandMessage(command, args); return this.conn.postMessage(msg); } }