// @flow // This file is intended for use in the GL-JS test suite // It implements a MessageBus main thread interface for use in Node environments // In a browser environment, this file is replaced with ./src/util/browser/web_worker.js // when Rollup builds the main bundle. // See package.json#browser import Worker from '../source/worker'; import type {WorkerSource} from '../source/worker_source'; type MessageListener = ({data: Object}) => mixed; // The main thread interface. Provided by Worker in a browser environment, // and MessageBus below in a node environment. export interface WorkerInterface { addEventListener(type: 'message', listener: MessageListener): void; removeEventListener(type: 'message', listener: MessageListener): void; postMessage(message: any): void; terminate(): void; } export interface WorkerGlobalScopeInterface { importScripts(...urls: Array): void; registerWorkerSource: (string, Class) => void, registerRTLTextPlugin: (_: any) => void } class MessageBus implements WorkerInterface, WorkerGlobalScopeInterface { addListeners: Array; postListeners: Array; target: MessageBus; registerWorkerSource: *; registerRTLTextPlugin: *; constructor(addListeners: Array, postListeners: Array) { this.addListeners = addListeners; this.postListeners = postListeners; } addEventListener(event: 'message', callback: MessageListener) { if (event === 'message') { this.addListeners.push(callback); } } removeEventListener(event: 'message', callback: MessageListener) { const i = this.addListeners.indexOf(callback); if (i >= 0) { this.addListeners.splice(i, 1); } } postMessage(data: Object) { setImmediate(() => { try { for (const listener of this.postListeners) { listener({data, target: this.target}); } } catch (e) { console.error(e); } }); } terminate() { this.addListeners.splice(0, this.addListeners.length); this.postListeners.splice(0, this.postListeners.length); } importScripts() {} } export default function WebWorker(): WorkerInterface { const parentListeners = [], workerListeners = [], parentBus = new MessageBus(workerListeners, parentListeners), workerBus = new MessageBus(parentListeners, workerListeners); parentBus.target = workerBus; workerBus.target = parentBus; new WebWorker.Worker(workerBus); return parentBus; } // expose to allow stubbing in unit tests WebWorker.Worker = Worker;