@xylabs/threads
Version:
Web workers & worker threads as simple as a function call
69 lines (55 loc) • 2.2 kB
text/typescript
/* 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 }