UNPKG

@xylabs/threads

Version:

Web workers & worker threads as simple as a function call

69 lines (55 loc) 2.2 kB
/* eslint-disable import-x/no-internal-modules */ /* eslint-disable @typescript-eslint/no-explicit-any */ // tslint:disable no-shadowed-variable import type { MessagePort, TransferListItem } from 'node:worker_threads' import { parentPort as optionalParentPort } from 'node:worker_threads' import { assertEx } from '@xylabs/assert' import type { AbstractedWorkerAPI } from '../types/worker.ts' import { createExpose } from './expose.ts' const parentPort = assertEx(optionalParentPort, () => 'Invariant violation: MessagePort to parent is not available.') function assertMessagePort(port: MessagePort | null | undefined): MessagePort { if (!port) { throw new Error('Invariant violation: MessagePort to parent is not available.') } return port } const isWorkerRuntime: AbstractedWorkerAPI['isWorkerRuntime'] = function isWorkerRuntime() { return true // isMainThread } const postMessageToMaster: AbstractedWorkerAPI['postMessageToMaster'] = function postMessageToMaster(data, transferList) { assertMessagePort(parentPort).postMessage(data, transferList as TransferListItem[]) } const subscribeToMasterMessages: AbstractedWorkerAPI['subscribeToMasterMessages'] = function subscribeToMasterMessages(onMessage) { if (!parentPort) { throw new Error('Invariant violation: MessagePort to parent is not available.') } const messageHandler = (message: any) => { onMessage(message) } const unsubscribe = () => { assertMessagePort(parentPort).off('message', messageHandler) } assertMessagePort(parentPort).on('message', messageHandler) return unsubscribe } const addEventListener = parentPort?.on.bind(parentPort) const postMessage = parentPort?.postMessage.bind(parentPort) const removeEventListener = parentPort?.off.bind(parentPort) export { addEventListener, postMessage, removeEventListener, } const expose = createExpose({ isWorkerRuntime, postMessageToMaster, subscribeToMasterMessages, }, { addEventListener, postMessage, removeEventListener, }) export { isWorkerRuntime, postMessageToMaster, subscribeToMasterMessages, } export { registerSerializer } from '../common.ts' export { Transfer } from '../transferable.ts' export { expose }