diff --git a/definitions/environments/node/flow_v0.155.x-/node.js b/definitions/environments/node/flow_v0.155.x-/node.js index 59a9ff7cb1..1c23ccf9f1 100644 --- a/definitions/environments/node/flow_v0.155.x-/node.js +++ b/definitions/environments/node/flow_v0.155.x-/node.js @@ -47,3 +47,146 @@ declare module 'node:util' { declare module 'node:url' { declare module.exports: $Exports<'url'>; } + +declare module 'worker_threads' { + declare var isMainThread: boolean; + declare var parentPort: null | MessagePort; + declare var threadId: number; + declare var workerData: any; + + declare class MessageChannel { + +port1: MessagePort; + +port2: MessagePort; + } + + declare class MessagePort extends events$EventEmitter { + close(): void; + postMessage(value: any, transferList?: Array): void; + ref(): void; + unref(): void; + start(): void; + + addListener(event: "close", listener: () => void): this; + addListener(event: "message", listener: (value: any) => void): this; + addListener(event: string | Symbol, listener: (...args: any[]) => void): this; + + emit(event: "close"): boolean; + emit(event: "message", value: any): boolean; + emit(event: string | Symbol, ...args: any[]): boolean; + + on(event: "close", listener: () => void): this; + on(event: "message", listener: (value: any) => void): this; + on(event: string | Symbol, listener: (...args: any[]) => void): this; + + once(event: "close", listener: () => void): this; + once(event: "message", listener: (value: any) => void): this; + once(event: string | Symbol, listener: (...args: any[]) => void): this; + + prependListener(event: "close", listener: () => void): this; + prependListener(event: "message", listener: (value: any) => void): this; + prependListener(event: string | Symbol, listener: (...args: any[]) => void): this; + + prependOnceListener(event: "close", listener: () => void): this; + prependOnceListener(event: "message", listener: (value: any) => void): this; + prependOnceListener(event: string | Symbol, listener: (...args: any[]) => void): this; + + removeListener(event: "close", listener: () => void): this; + removeListener(event: "message", listener: (value: any) => void): this; + removeListener(event: string | Symbol, listener: (...args: any[]) => void): this; + + off(event: "close", listener: () => void): this; + off(event: "message", listener: (value: any) => void): this; + off(event: string | Symbol, listener: (...args: any[]) => void): this; + } + + declare type WorkerOptions = {| + env?: Object, + eval?: boolean, + workerData?: any, + stdin?: boolean, + stdout?: boolean, + stderr?: boolean, + execArgv?: string[] + |} + + declare class Worker extends events$EventEmitter { + +stdin: stream$Writable | null; + +stdout: stream$Readable; + +stderr: stream$Readable; + +threadId: number; + + constructor(filename: string, options?: WorkerOptions): void; + + postMessage(value: any, transferList?: Array): void; + ref(): void; + unref(): void; + terminate(callback?: (err: Error, exitCode: number) => void): void; + /** + * Transfer a `MessagePort` to a different `vm` Context. The original `port` + * object will be rendered unusable, and the returned `MessagePort` instance will + * take its place. + * + * The returned `MessagePort` will be an object in the target context, and will + * inherit from its global `Object` class. Objects passed to the + * `port.onmessage()` listener will also be created in the target context + * and inherit from its global `Object` class. + * + * However, the created `MessagePort` will no longer inherit from + * `EventEmitter`, and only `port.onmessage()` can be used to receive + * events using it. + */ + moveMessagePortToContext(port: MessagePort, context: vm$Context): MessagePort; + + addListener(event: "error", listener: (err: Error) => void): this; + addListener(event: "exit", listener: (exitCode: number) => void): this; + addListener(event: "message", listener: (value: any) => void): this; + addListener(event: "online", listener: () => void): this; + addListener(event: string | Symbol, listener: (...args: any[]) => void): this; + + emit(event: "error", err: Error): boolean; + emit(event: "exit", exitCode: number): boolean; + emit(event: "message", value: any): boolean; + emit(event: "online"): boolean; + emit(event: string | Symbol, ...args: any[]): boolean; + + on(event: "error", listener: (err: Error) => void): this; + on(event: "exit", listener: (exitCode: number) => void): this; + on(event: "message", listener: (value: any) => void): this; + on(event: "online", listener: () => void): this; + on(event: string | Symbol, listener: (...args: any[]) => void): this; + + once(event: "error", listener: (err: Error) => void): this; + once(event: "exit", listener: (exitCode: number) => void): this; + once(event: "message", listener: (value: any) => void): this; + once(event: "online", listener: () => void): this; + once(event: string | Symbol, listener: (...args: any[]) => void): this; + + prependListener(event: "error", listener: (err: Error) => void): this; + prependListener(event: "exit", listener: (exitCode: number) => void): this; + prependListener(event: "message", listener: (value: any) => void): this; + prependListener(event: "online", listener: () => void): this; + prependListener(event: string | Symbol, listener: (...args: any[]) => void): this; + + prependOnceListener(event: "error", listener: (err: Error) => void): this; + prependOnceListener(event: "exit", listener: (exitCode: number) => void): this; + prependOnceListener(event: "message", listener: (value: any) => void): this; + prependOnceListener(event: "online", listener: () => void): this; + prependOnceListener(event: string | Symbol, listener: (...args: any[]) => void): this; + + removeListener(event: "error", listener: (err: Error) => void): this; + removeListener(event: "exit", listener: (exitCode: number) => void): this; + removeListener(event: "message", listener: (value: any) => void): this; + removeListener(event: "online", listener: () => void): this; + removeListener(event: string | Symbol, listener: (...args: any[]) => void): this; + + off(event: "error", listener: (err: Error) => void): this; + off(event: "exit", listener: (exitCode: number) => void): this; + off(event: "message", listener: (value: any) => void): this; + off(event: "online", listener: () => void): this; + off(event: string | Symbol, listener: (...args: any[]) => void): this; + } +} + +declare module 'node:worker_threads' { + declare module.exports: $Exports<'worker_threads'>; +} diff --git a/definitions/environments/node/flow_v0.155.x-/test_node.js b/definitions/environments/node/flow_v0.155.x-/test_node.js index 8aee4acb72..3ffe61db12 100644 --- a/definitions/environments/node/flow_v0.155.x-/test_node.js +++ b/definitions/environments/node/flow_v0.155.x-/test_node.js @@ -1,5 +1,5 @@ // @flow -import { describe, it } from 'flow-typed-test'; +import { describe, it, test } from 'flow-typed-test'; import assert from 'assert'; import events from 'events'; @@ -8,6 +8,10 @@ import os from 'os'; import path from 'path'; import util from 'util'; import url from 'url'; +import { + Worker, + isMainThread, +} from 'worker_threads'; import nodeAssert from 'node:assert'; import nodeAssertStrict from 'node:assert/strict'; @@ -21,6 +25,10 @@ import nodeOs from 'node:os'; import nodePath from 'node:path'; import nodeUtil from 'node:util'; import nodeUrl from 'node:url'; +import { + Worker as nodeWorker, + isMainThread as nodeIsMainThread, +} from 'node:worker_threads'; describe('node', () => { describe('node:assert', () => { @@ -110,4 +118,36 @@ describe('node', () => { (nodeUrl.pathToFileURL: typeof url.pathToFileURL); }); }); + + describe('worker_threads', () => { + test('Worker', () => { + const worker = new Worker('filename', { + workerData: 'test', + }); + worker.on('message', () => {}); + worker.on('error', () => {}); + }); + + test('isMainThread', () => { + (isMainThread: boolean); + // $FlowExpectedError[incompatible-cast] + (isMainThread: string); + }); + }); + + describe('node:worker_threads', () => { + test('Worker', () => { + const worker = new nodeWorker('filename', { + workerData: 'test', + }); + worker.on('message', () => {}); + worker.on('error', () => {}); + }); + + test('isMainThread', () => { + (nodeIsMainThread: boolean); + // $FlowExpectedError[incompatible-cast] + (nodeIsMainThread: string); + }); + }); });