name: string
reject: (value: any) => void
resolve: (value: any) => void
- data: any[]
+ data: any
results: any[]
}
job: null
}
thread.worker.addEventListener('message', message => {
- const data: string = new TextDecoder().decode(message.data)
- let result: any = JSON.parse(data || "[]")
+ let result = (message.data instanceof ArrayBuffer)
+ ? new Uint8Array(message.data)
+ : JSON.parse(new TextDecoder().decode(message.data) || "[]")
if (!Array.isArray(result)) result = [result]
this.#report(thread, result)
})
}
static #assign (thread: Thread, job: Job): void {
- const chunk: number = 1 + (job.data.length / this.#cores)
- const next = job.data.slice(0, chunk)
- job.data = job.data.slice(chunk)
- if (job.data.length === 0) this.#queue.shift()
- if (next?.length > 0) {
- if (this.#isTransferable(next)) {
- thread.worker.postMessage({ name: job.name, next }, [next])
- } else if (this.#isTransferable(next[0])) {
- thread.worker.postMessage({ name: job.name, next }, next)
- } else {
+ if (job.data instanceof ArrayBuffer) {
+ if (job.data.byteLength > 0) {
+ thread.job = job
+ thread.worker.postMessage({ name: job.name, buffer: job.data }, [job.data])
+ }
+ } else {
+ const chunk: number = 1 + (job.data.length / this.#cores)
+ const next = job.data.slice(0, chunk)
+ job.data = job.data.slice(chunk)
+ if (job.data.length === 0) this.#queue.shift()
+ if (next?.length > 0) {
const buffer = new TextEncoder().encode(JSON.stringify(next)).buffer
thread.job = job
thread.worker.postMessage({ name: job.name, buffer }, [buffer])
return true
}
- static #isTransferable (obj: any): boolean {
- return obj instanceof ArrayBuffer
- //@ts-expect-error
- || obj instanceof AudioData
- || obj instanceof ImageBitmap
- || obj instanceof MIDIAccess
- || obj instanceof OffscreenCanvas
- || obj instanceof ReadableStream
- || obj instanceof RTCDataChannel
- || obj instanceof TransformStream
- || obj instanceof VideoFrame
- //@ts-expect-error
- || obj instanceof WebTransportReceiveStream
- //@ts-expect-error
- || obj instanceof WebTransportSendStream
- || obj instanceof WritableStream
- }
-
static #report (thread: Thread, results: any[]): void {
if (thread.job == null) {
throw new Error('Thread returned results but had nowhere to report it.')
}
}
- static async work (name: string, data: object[]): Promise<any> {
- if (!Array.isArray(data)) data = [data]
+ static async work (name: string, data: any): Promise<any> {
+ if (!(data instanceof ArrayBuffer || Array.isArray(data))) data = [data]
return new Promise((resolve, reject) => {
const job: Job = {
id: performance.now(),