From cf86b7c42a3c94afc302fb52a6078c71f4155f46 Mon Sep 17 00:00:00 2001 From: younesaassila <47226184+younesaassila@users.noreply.github.com> Date: Mon, 29 Apr 2024 11:49:30 +0200 Subject: [PATCH] Fix #319 --- src/page/getFetch.ts | 8 ++++---- src/page/page.ts | 26 +++++++++++++------------- src/page/sendMessage.ts | 38 ++++++++++++++++++++++---------------- src/page/types.ts | 15 ++++++--------- src/page/worker.ts | 15 ++++++++------- tsconfig.json | 2 +- 6 files changed, 54 insertions(+), 50 deletions(-) diff --git a/src/page/getFetch.ts b/src/page/getFetch.ts index 4702060..32b507c 100644 --- a/src/page/getFetch.ts +++ b/src/page/getFetch.ts @@ -46,10 +46,10 @@ export function getFetch(pageState: PageState): typeof fetch { type: MessageType.NewPlaybackAccessTokenResponse, newPlaybackAccessToken, }; - pageState.twitchWorker?.postMessage({ - type: MessageType.WorkerScriptMessage, - message, - }); + pageState.sendMessageToWorkerScripts( + pageState.twitchWorkers, + message + ); break; } }); diff --git a/src/page/page.ts b/src/page/page.ts index 4b647d9..7929adf 100644 --- a/src/page/page.ts +++ b/src/page/page.ts @@ -7,8 +7,8 @@ import { getSendMessageToContentScriptAndWaitForResponse, getSendMessageToPageScript, getSendMessageToPageScriptAndWaitForResponse, - getSendMessageToWorkerScript, - getSendMessageToWorkerScriptAndWaitForResponse, + getSendMessageToWorkerScripts, + getSendMessageToWorkerScriptsAndWaitForResponse, } from "./sendMessage"; import type { PageState } from "./types"; @@ -22,21 +22,21 @@ const sendMessageToContentScriptAndWaitForResponse = const sendMessageToPageScript = getSendMessageToPageScript(); const sendMessageToPageScriptAndWaitForResponse = getSendMessageToPageScriptAndWaitForResponse(); -const sendMessageToWorkerScript = getSendMessageToWorkerScript(); -const sendMessageToWorkerScriptAndWaitForResponse = - getSendMessageToWorkerScriptAndWaitForResponse(); +const sendMessageToWorkerScripts = getSendMessageToWorkerScripts(); +const sendMessageToWorkerScriptsAndWaitForResponse = + getSendMessageToWorkerScriptsAndWaitForResponse(); const pageState: PageState = { isChromium: params.isChromium, scope: "page", state: undefined, - twitchWorker: undefined, + twitchWorkers: [], sendMessageToContentScript, sendMessageToContentScriptAndWaitForResponse, sendMessageToPageScript, sendMessageToPageScriptAndWaitForResponse, - sendMessageToWorkerScript, - sendMessageToWorkerScriptAndWaitForResponse, + sendMessageToWorkerScripts, + sendMessageToWorkerScriptsAndWaitForResponse, }; const NATIVE_FETCH = window.fetch; @@ -94,7 +94,7 @@ window.Worker = class Worker extends window.Worker { new Blob([wrapperScript], { type: "text/javascript" }) ); super(wrapperScriptURL, options); - pageState.twitchWorker = this; + pageState.twitchWorkers.push(this); this.addEventListener("message", event => { if ( event.data?.type === MessageType.ContentScriptMessage || @@ -112,7 +112,7 @@ let sendStoreStateToWorker = false; window.addEventListener("message", event => { // Relay messages from the content script to the worker script. if (event.data?.type === MessageType.WorkerScriptMessage) { - sendMessageToWorkerScript(pageState.twitchWorker, event.data.message); + sendMessageToWorkerScripts(pageState.twitchWorkers, event.data.message); return; } @@ -124,7 +124,7 @@ window.addEventListener("message", event => { switch (message.type) { case MessageType.GetStoreState: // From Worker if (pageState.state != null) { - sendMessageToWorkerScript(pageState.twitchWorker, { + sendMessageToWorkerScripts(pageState.twitchWorkers, { type: MessageType.GetStoreStateResponse, state: pageState.state, }); @@ -142,7 +142,7 @@ window.addEventListener("message", event => { const state = message.state; pageState.state = state; if (sendStoreStateToWorker) { - sendMessageToWorkerScript(pageState.twitchWorker, { + sendMessageToWorkerScripts(pageState.twitchWorkers, { type: MessageType.GetStoreStateResponse, state, }); @@ -211,7 +211,7 @@ onChannelChange((_channelName, oldChannelName) => { type: MessageType.ClearStats, channelName: oldChannelName, }); - sendMessageToWorkerScript(pageState.twitchWorker, { + sendMessageToWorkerScripts(pageState.twitchWorkers, { type: MessageType.ClearStats, channelName: oldChannelName, }); diff --git a/src/page/sendMessage.ts b/src/page/sendMessage.ts index 41159e3..91b1f98 100644 --- a/src/page/sendMessage.ts +++ b/src/page/sendMessage.ts @@ -1,9 +1,9 @@ import { MessageType } from "../types"; import type { SendMessageAndWaitForResponseFn, - SendMessageAndWaitForResponseWorkerFn, + SendMessageAndWaitForResponseWorkersFn, SendMessageFn, - SendMessageWorkerFn, + SendMessageWorkersFn, } from "./types"; // TODO: Secure communication between content, page, and worker scripts. @@ -104,28 +104,34 @@ export function getSendMessageToPageScriptAndWaitForResponse(): SendMessageAndWa }; } -export function getSendMessageToWorkerScript(): SendMessageWorkerFn { - return (worker: Worker | undefined, message: any) => - sendMessage(worker, MessageType.WorkerScriptMessage, message); +export function getSendMessageToWorkerScripts(): SendMessageWorkersFn { + return (workers: Worker[], message: any) => + workers.forEach(worker => + sendMessage(worker, MessageType.WorkerScriptMessage, message) + ); } -export function getSendMessageToWorkerScriptAndWaitForResponse(): SendMessageAndWaitForResponseWorkerFn { +export function getSendMessageToWorkerScriptsAndWaitForResponse(): SendMessageAndWaitForResponseWorkersFn { return async ( - worker: Worker | undefined, + workers: Worker[], message: any, responseMessageType: MessageType, scope: "page" | "worker", responseTimeout: number = 5000 ) => { - return sendMessageAndWaitForResponse( - worker, - MessageType.WorkerScriptMessage, - message, - scope === "page" - ? MessageType.PageScriptMessage - : MessageType.WorkerScriptMessage, - responseMessageType, - responseTimeout + return Promise.any( + workers.map(worker => + sendMessageAndWaitForResponse( + worker, + MessageType.WorkerScriptMessage, + message, + scope === "page" + ? MessageType.PageScriptMessage + : MessageType.WorkerScriptMessage, + responseMessageType, + responseTimeout + ) + ) ); }; } diff --git a/src/page/types.ts b/src/page/types.ts index 2c8187f..a782b75 100644 --- a/src/page/types.ts +++ b/src/page/types.ts @@ -2,18 +2,15 @@ import type { State } from "../store/types"; import { MessageType } from "../types"; export type SendMessageFn = (message: any) => void; -export type SendMessageWorkerFn = ( - worker: Worker | undefined, - message: any -) => void; +export type SendMessageWorkersFn = (workers: Worker[], message: any) => void; export type SendMessageAndWaitForResponseFn = ( scope: "page" | "worker", message: any, responseMessageType: MessageType, responseTimeout?: number ) => Promise; -export type SendMessageAndWaitForResponseWorkerFn = ( - worker: Worker | undefined, +export type SendMessageAndWaitForResponseWorkersFn = ( + workers: Worker[], message: any, responseMessageType: MessageType, scope: "page" | "worker", @@ -24,13 +21,13 @@ export interface PageState { isChromium: boolean; scope: "page" | "worker"; state?: State; - twitchWorker?: Worker; + twitchWorkers: Worker[]; sendMessageToContentScript: SendMessageFn; sendMessageToContentScriptAndWaitForResponse: SendMessageAndWaitForResponseFn; sendMessageToPageScript: SendMessageFn; sendMessageToPageScriptAndWaitForResponse: SendMessageAndWaitForResponseFn; - sendMessageToWorkerScript: SendMessageWorkerFn; - sendMessageToWorkerScriptAndWaitForResponse: SendMessageAndWaitForResponseWorkerFn; + sendMessageToWorkerScripts: SendMessageWorkersFn; + sendMessageToWorkerScriptsAndWaitForResponse: SendMessageAndWaitForResponseWorkersFn; } export interface UsherManifest { diff --git a/src/page/worker.ts b/src/page/worker.ts index f8a52f1..a970f05 100644 --- a/src/page/worker.ts +++ b/src/page/worker.ts @@ -5,8 +5,8 @@ import { getSendMessageToContentScriptAndWaitForResponse, getSendMessageToPageScript, getSendMessageToPageScriptAndWaitForResponse, - getSendMessageToWorkerScript, - getSendMessageToWorkerScriptAndWaitForResponse, + getSendMessageToWorkerScripts, + getSendMessageToWorkerScriptsAndWaitForResponse, } from "./sendMessage"; import type { PageState } from "./types"; @@ -27,21 +27,22 @@ const sendMessageToContentScriptAndWaitForResponse = const sendMessageToPageScript = getSendMessageToPageScript(); const sendMessageToPageScriptAndWaitForResponse = getSendMessageToPageScriptAndWaitForResponse(); -const sendMessageToWorkerScript = getSendMessageToWorkerScript(); +const sendMessageToWorkerScript = getSendMessageToWorkerScripts(); const sendMessageToWorkerScriptAndWaitForResponse = - getSendMessageToWorkerScriptAndWaitForResponse(); + getSendMessageToWorkerScriptsAndWaitForResponse(); const pageState: PageState = { isChromium: params.isChromium, scope: "worker", state: undefined, - twitchWorker: undefined, // Can't get the worker instance from inside the worker. + twitchWorkers: [], // FIXME: Always empty in workers. (Could be problematic for Usher manifests in Worker) sendMessageToContentScript, sendMessageToContentScriptAndWaitForResponse, sendMessageToPageScript, sendMessageToPageScriptAndWaitForResponse, - sendMessageToWorkerScript, - sendMessageToWorkerScriptAndWaitForResponse, + sendMessageToWorkerScripts: sendMessageToWorkerScript, + sendMessageToWorkerScriptsAndWaitForResponse: + sendMessageToWorkerScriptAndWaitForResponse, }; self.fetch = getFetch(pageState); diff --git a/tsconfig.json b/tsconfig.json index 17d825d..62d942a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2021", "moduleResolution": "Node", "allowSyntheticDefaultImports": true, "noEmit": true,