UNPKG

web-worker-helper

Version:

Utilities for running tasks on worker threads

72 lines (61 loc) 2.46 kB
import type { WorkerMessageData, WorkerMessageType, WorkerMessagePayload } from '../types'; import { getTransferList } from '../utils/worker-utils/get-transfer-list'; const onMessageWrapperMap = new Map(); /** * Type safe wrapper for worker code */ export default class WorkerBody { /* * (type: WorkerMessageType, payload: WorkerMessagePayload) => any */ static set onmessage(onMessage: (type: WorkerMessageType, payload: WorkerMessagePayload) => any) { self.onmessage = (message: MessageEvent<any>) => { if (!isKnownMessage(message)) { return; } // Confusingly the message itself also has a 'type' field which is always set to 'message' const { type, payload } = message.data; onMessage(type, payload); }; } static addEventListener(onMessage: (type: WorkerMessageType, payload: WorkerMessagePayload) => any) { let onMessageWrapper = onMessageWrapperMap.get(onMessage); if (!onMessageWrapper) { onMessageWrapper = (message: MessageEvent<any>) => { if (!isKnownMessage(message)) { return; } // Confusingly the message itself also has a 'type' field which is always set to 'message' const { type, payload } = message.data; onMessage(type, payload); }; } self.addEventListener('message', onMessageWrapper); } static removeEventListener(onMessage: (type: WorkerMessageType, payload: WorkerMessagePayload) => any) { const onMessageWrapper = onMessageWrapperMap.get(onMessage); onMessageWrapperMap.delete(onMessage); self.removeEventListener('message', onMessageWrapper); } /** * Send a message from a worker to creating thread (main thread) * 从 worker 线程发送消息到主线程 * @param type * @param payload */ static postMessage(type: WorkerMessageType, payload: WorkerMessagePayload): void { if (self) { const data: WorkerMessageData = { source: 'Worker thread', type, payload }; const transferList = getTransferList(payload); // TODO: targetOrigin, transferList // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore self.postMessage(data, transferList); } } } // Filter out noise messages sent to workers function isKnownMessage(message: MessageEvent<any>) { const { type, data } = message; return type === 'message' && data && typeof data.source === 'string' && data.source === 'Main thread'; }