### Install bun-threads Package Source: https://github.com/taylorsreid/bun-threads/blob/main/README.md Installs the bun-threads library using the Bun package manager. This is the first step to integrating multithreading capabilities into your Bun projects. ```bash bun add bun-threads ``` -------------------------------- ### Example Usage of listeners - JavaScript Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Demonstrates how to use the `listeners` method to retrieve and log the array of listeners for a specific event ('connection' in this case). ```javascript server.on('connection', (stream) => { console.log('someone connected!'); }); console.log(util.inspect(server.listeners('connection'))); // Prints: [ [Function] ] ``` -------------------------------- ### Bun Thread Quick Multithreading Proof Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/index.html A simple example demonstrating how to create a Bun Thread and check if it's running on the main thread using Bun.isMainThread. This showcases basic thread instantiation and execution. ```typescript import { Thread } from "bun-threads"; const proof = new Thread(() => Bun.isMainThread) console.log('Thread isMainThread:', await proof.run([])) // no arguments so pass an empty array console.log('Main process isMainThread:', Bun.isMainThread) ``` -------------------------------- ### Bun ThreadPool vs Single Thread Example Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/ThreadPool.html Compares the performance of running tasks sequentially with a single Thread versus concurrently using a ThreadPool. Demonstrates how ThreadPool significantly reduces execution time for parallelizable tasks. Requires the 'bun-threads' package. ```typescript import { Thread, ThreadPool } from "bun-threads"; const thread = new Thread((wait: number) => Bun.sleepSync(wait)) // simulate some synchronous work const threadPool = new ThreadPool((wait: number) => Bun.sleepSync(wait)) // simulate some synchronous work let start = performance.now() await Promise.all([ thread.run([1_000]), thread.run([1_000]), thread.run([1_000]) ]) // a single Thread can only execute synchronous tasks one at a time console.log('Thread completed in:', performance.now() - start, 'ms') // ~ 3000 ms start = performance.now() await Promise.all([ threadPool.run([1_000]), threadPool.run([1_000]), threadPool.run([1_000]) ]) // ThreadPool runs each task in a separate Thread in parallel console.log('ThreadPool completed in:', performance.now() - start, 'ms') // ~ 1000 ms thread.close() threadPool.close() ``` -------------------------------- ### Simple Thread Example: Add Two Numbers Source: https://github.com/taylorsreid/bun-threads/blob/main/README.md Illustrates creating a `Thread` to perform a simple addition. The `run()` method takes an array of arguments to be passed to the thread's callback function. The result is handled asynchronously using a Promise. ```typescript import { Thread } from "bun-threads"; const addThread = new Thread((a: number, b: number) => { return a + b }) addThread.run([21, 21]).then((result) => console.log(result)) ``` -------------------------------- ### Initialize Thread with Imports (TypeScript) Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Demonstrates creating a new `Thread` instance in TypeScript. The callback function can dynamically import modules like 'bun:sqlite' and perform operations. Arguments passed to the thread must be serializable via `structuredClone()`. This example shows database interaction within a worker thread. ```typescript import { Thread } from "bun-threads"; const threadWithImports = new Thread(async (num: number) => { const sqlite = await import('bun:sqlite') const db = new sqlite.Database('./db.sqlite') db.run("INSERT INTO answers VALUES(?)", [ num ]) }) ``` -------------------------------- ### Thread Constructor Example (TypeScript) Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Illustrates the `Thread` constructor in TypeScript, which creates a new `Thread` to run tasks on a separate Bun worker thread. It accepts a callback function (`fn`) and optional `ThreadOptions`. The callback function's arguments must be serializable, and it cannot rely on top-level imports or closures. ```typescript new Thread(fn: T, options?: ThreadOptions): Thread ``` -------------------------------- ### Basic Thread Example: Check if Main Thread Source: https://github.com/taylorsreid/bun-threads/blob/main/README.md Demonstrates the basic usage of the `Thread` class to create a worker thread. It runs a simple function that checks if the current thread is the main thread and logs the result. An empty array is passed as arguments, as required by the `run()` method. ```typescript import { Thread } from "bun-threads"; const proof = new Thread(() => Bun.isMainThread) console.log('Thread isMainThread:', await proof.run([])) // no arguments so pass an empty array console.log('Main process isMainThread:', Bun.isMainThread) ``` -------------------------------- ### Configure ThreadPool Scaling and Behavior Source: https://context7.com/taylorsreid/bun-threads/llms.txt Configures the ThreadPool's scaling behavior using `minThreads`, `maxThreads`, and `idleTimeout` options. `minThreads` keeps threads warm, `maxThreads` sets the upper limit, and `idleTimeout` determines how long idle threads persist. This example demonstrates accessing these properties and waiting for tasks to complete. ```typescript import { ThreadPool } from "bun-threads"; const dataProcessor = new ThreadPool((chunk: number[]) => { return chunk.reduce((sum, val) => sum + val, 0); }, { minThreads: 2, maxThreads: 8, idleTimeout: 5000 }); console.log(`Pool has ${dataProcessor.maxThreads} max threads`); console.log(`Pool keeps ${dataProcessor.minThreads} threads warm`); const chunks = Array.from({ length: 20 }, () => Array.from({ length: 1000 }, () => Math.random()) ); const results = await Promise.all(chunks.map(chunk => dataProcessor.run([chunk]))); console.log(`Active threads: ${dataProcessor.busy}`); await dataProcessor.idle; console.log(`All tasks complete. Active threads: ${dataProcessor.busy}`); await dataProcessor.close(); ``` -------------------------------- ### Bun ThreadPool Busy Threads Example Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/ThreadPool.html Demonstrates how to check the number of busy threads in a ThreadPool. The 'busy' accessor returns the count of threads currently executing tasks. This is useful for determining when the pool is idle and safe to close. Requires the 'bun-threads' package. ```typescript import { ThreadPool } from "bun-threads"; const tp = new ThreadPool(() => { return 'hello world' }) tp.run([]) console.log(`${tp.busy} thread in the ThreadPool is busy.`) tp.run([]) console.log(`${tp.busy} threads in the ThreadPool are busy.`) await tp.idle console.log(`${tp.busy} threads in the ThreadPool are busy.`) tp.close() ``` -------------------------------- ### Execute Tasks on a Worker Thread with bun-threads Source: https://context7.com/taylorsreid/bun-threads/llms.txt Illustrates using the `Thread.run()` method to execute a data processing task on a separate worker thread. This example shows passing multiple arguments and handling potential errors during thread execution. It requires 'bun-threads' and includes graceful shutdown. ```typescript import { Thread } from "bun-threads"; const processData = new Thread((data: string[], delimiter: string) => { return data.map(item => item.toUpperCase()).join(delimiter); }); try { const result = await processData.run([ ["apple", "banana", "cherry"], " | " ]); console.log(result); } catch (error) { console.error("Thread execution failed:", error); } finally { await processData.close(); } ``` -------------------------------- ### Create and Run a Bun Thread with Dynamic Imports Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html Demonstrates creating a Bun thread using the `Thread` class from the `bun-threads` library. The callback function within the thread utilizes dynamic imports to access external modules like 'bun:sqlite'. This showcases how threads can fetch and use packages not available in their initial environment. Arguments passed to the thread must be serializable. ```typescript import { Thread } from "bun-threads"; const threadWithImports = new Thread(async (num: number) => { const sqlite = await import('bun:sqlite'); const db = new sqlite.Database('./db.sqlite'); db.run("INSERT INTO answers VALUES(?)", [ num ]); }); // Example of how to run the thread (not provided in the original text but inferred for completeness) // threadWithImports.run(123); ``` -------------------------------- ### GET /listenerCount Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Retrieves the number of listeners for a specified event on an EventEmitter. This is a utility function provided for inspecting event listeners. ```APIDOC ## GET /listenerCount ### Description Returns the number of listeners for the given `eventName` registered on the given `emitter`. ### Method GET ### Endpoint /listenerCount ### Parameters #### Query Parameters - **emitter** (EventEmitter) - Required - The EventEmitter instance to query. - **eventName** (string | symbol) - Required - The name of the event for which to count listeners. ### Request Example ``` GET /listenerCount?emitter=&eventName=myEvent ``` ### Response #### Success Response (200) - **listeners** (number[]) - An array containing the number of listeners for the specified event. #### Response Example ```json { "listeners": [ 2 ] } ``` ### Deprecated Since v3.2.0 - Use `EventEmitter.listenerCount` instead. ``` -------------------------------- ### Initialize Theme and Show Page with Delay Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html This snippet initializes the document's theme from local storage and then hides the body content. A timeout is used to either display the application's page or remove the display style from the body after a 500ms delay, ensuring content is shown only after initialization or a brief wait. ```javascript document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os"; document.body.style.display="none"; setTimeout(() => window.app ? app.showPage() : document.body.style.removeProperty("display"), 500); ``` -------------------------------- ### Get Listeners Array - TypeScript Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Returns a copy of the array containing all listener functions registered for a given event name. Inherited from EventEmitter. ```typescript listeners(eventName: string | symbol): Function[] ``` -------------------------------- ### Get Listener Count - TypeScript Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Returns the number of listeners for a specific event. If a listener function is provided, it counts occurrences of that specific listener. Inherited from EventEmitter. ```typescript listenerCount(eventName: string | symbol, listener?: Function): number[] ``` -------------------------------- ### Create and Run a Single Worker Thread with bun-threads Source: https://context7.com/taylorsreid/bun-threads/llms.txt Demonstrates creating a single worker thread using the `Thread` constructor to execute a factorial computation. It shows how to run the task with arguments and gracefully close the thread. Dependencies include 'bun-threads'. ```typescript import { Thread } from "bun-threads"; const computeFactorial = new Thread((n: number) => { let result = 1; for (let i = 2; i <= n; i++) { result *= i; } return result; }, { idleTimeout: 5000 }); const result = await computeFactorial.run([10]); console.log(`Factorial of 10: ${result}`); await computeFactorial.close(); ``` -------------------------------- ### Get Max Listeners (Node.js Events) Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html Returns the maximum number of listeners allowed for an EventEmitter instance. This value is configurable via `setMaxListeners` or defaults to `EventEmitter.defaultMaxListeners`. Inherited from Node.js's EventEmitter. ```javascript import { EventEmitter } from 'node:events'; // Assuming 'emitter' is an instance of EventEmitter // const maxListeners = emitter.getMaxListeners(); // console.log(maxListeners); // Example demonstrating the concept (without a specific emitter instance): console.log(EventEmitter.defaultMaxListeners); ``` -------------------------------- ### Get Event Names with Listeners (Node.js Events) Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html Retrieves an array of event names for which the EventEmitter has registered listeners. Event names can be strings or Symbols. This method is inherited from Node.js's EventEmitter. ```javascript import { EventEmitter } from 'node:events'; const myEE = new EventEmitter(); myEE.on('foo', () => {}); myEE.on('bar', () => {}); const sym = Symbol('symbol'); myEE.on(sym, () => {}); console.log(myEE.eventNames()); // Prints: [ 'foo', 'bar', Symbol(symbol) ] ``` -------------------------------- ### Get Queued Task Count Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html The `queued` property returns the number of tasks currently waiting in the queue to be processed by the thread. This count increments each time `run()` is called and decrements when a task completes. ```typescript import { Thread } from "bun-threads"; const thread = new Thread(() => {}); console.log(`Initial queued tasks: ${thread.queued}`); // Output: Initial queued tasks: 0 thread.run([]); console.log(`Queued tasks after run: ${thread.queued}`); // Output: Queued tasks after run: 1 // After the task completes, queued will decrement. ``` -------------------------------- ### Thread with Dynamic Imports Source: https://context7.com/taylorsreid/bun-threads/llms.txt Demonstrates how to use dynamic `import()` within a thread's callback to load modules at runtime, enabling access to external libraries like `bun:sqlite`. ```APIDOC ## Thread with Dynamic Imports ### Description Use dynamic imports inside thread callbacks to access external modules. ### Method `new Thread(async (param1, param2) => { await import('module'); ... })` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body (See Thread Constructor and Thread.run() for details on callback and arguments) ### Request Example ```typescript import { Thread } from "bun-threads"; const databaseWorker = new Thread(async (query: string, params: any[]) => { const sqlite = await import('bun:sqlite'); const db = new sqlite.Database('./data.db'); const stmt = db.query(query); const results = stmt.all(...params); db.close(); return results; }); const users = await databaseWorker.run([ "SELECT * FROM users WHERE age > ?", [18] ]); console.log(users); await databaseWorker.close(); ``` ### Response #### Success Response (200) - **results** (Array) - The data retrieved from the database based on the query. #### Response Example ```json { "results": [ { "id": 1, "name": "Alice", "age": 25 }, { "id": 2, "name": "Bob", "age": 30 } ] } ``` ``` -------------------------------- ### Cancel EventEmitter Iteration with AbortSignal (Node.js) Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html This example shows how to use an AbortSignal to cancel the AsyncIterator created by the 'on' function. An AbortController is used to trigger the abort signal, which stops the iteration. Events are emitted asynchronously. ```typescript import { on, EventEmitter } from 'node:events'; import process from 'node:process'; const ac = new AbortController(); (async () => { const ee = new EventEmitter(); // Emit later on process.nextTick(() => { ee.emit('foo', 'bar'); ee.emit('foo', 42); }); for await (const event of on(ee, 'foo', { signal: ac.signal })) { // The execution of this inner block is synchronous and it // processes one event at a time (even with await). Do not use // if concurrent execution is required. console.log(event); // prints ['bar'] [42] } // Unreachable here })(); process.nextTick(() => ac.abort()); ``` -------------------------------- ### Set Theme and Initial Display (JavaScript) Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/hierarchy.html This snippet sets the document's theme based on local storage and hides the body initially, showing the application or removing the display style after a timeout. It's likely used for initial page loading and theme persistence. ```javascript document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os"; document.body.style.display="none"; setTimeout(() => window.app?app.showPage():document.body.style.removeProperty("display"),500) ``` -------------------------------- ### Get Event Listeners for EventEmitter or EventTarget (Node.js) Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Retrieves a copy of the listeners for a specified event name from an EventEmitter or EventTarget. For EventTargets, this is the primary method for inspecting listeners, useful for debugging. Available since v15.2.0. ```javascript import { getEventListeners, EventEmitter } from 'node:events'; // For EventEmitter const ee = new EventEmitter(); const listener = () => console.log('Events are fun'); ee.on('foo', listener); console.log(getEventListeners(ee, 'foo')); // [ [Function: listener] ] // For EventTarget const et = new EventTarget(); et.addEventListener('foo', listener); console.log(getEventListeners(et, 'foo')); // [ [Function: listener] ] ``` -------------------------------- ### Get Listener Count for an Event (Node.js) Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html This function returns the number of listeners registered for a specific event on an EventEmitter. It takes the EventEmitter instance and the event name as input. The output is an array of numbers representing the listener counts. ```javascript import { EventEmitter, listenerCount } from 'node:events'; const myEmitter = new EventEmitter(); myEmitter.on('event', () => {}); myEmitter.on('event', () => {}); console.log(listenerCount(myEmitter, 'event')); // Prints: 2 ``` -------------------------------- ### Get Raw Event Listeners from EventEmitter Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Retrieves a copy of the array containing all listeners for a given event, including any wrapper functions. This is useful for inspecting the current listeners without modifying them. The returned array is a copy, so modifications to it will not affect the original listeners. ```javascript import { EventEmitter } from 'node:events'; const emitter = new EventEmitter(); emitter.once('log', () => console.log('log once')); // Returns a new Array with a function `onceWrapper` which has a property // `listener` which contains the original listener bound above const listeners = emitter.rawListeners('log'); const logFnWrapper = listeners[0]; // Logs "log once" to the console and does not unbind the `once` event logFnWrapper.listener(); // Logs "log once" to the console and removes the listener logFnWrapper(); emitter.on('log', () => console.log('log persistently')); // Will return a new Array with a single function bound by `.on()` above const newListeners = emitter.rawListeners('log'); // Logs "log persistently" twice newListeners[0](); emitter.emit('log'); ``` -------------------------------- ### ThreadPool Configuration and Scaling Source: https://context7.com/taylorsreid/bun-threads/llms.txt Configure thread pool behavior with min/max threads and idle timeout settings. Access properties like `maxThreads` and `minThreads` to inspect the pool's configuration. ```APIDOC ## ThreadPool Configuration and Scaling ### Description Allows configuration of the thread pool's behavior using `minThreads`, `maxThreads`, and `idleTimeout` options during instantiation. You can also inspect these properties after creation. ### Properties - `maxThreads` (number) - The maximum number of threads the pool can manage. - `minThreads` (number) - The minimum number of threads the pool maintains. - `busy` (number) - The current number of active worker threads. ### Request Example ```typescript import { ThreadPool } from "bun-threads"; const dataProcessor = new ThreadPool((chunk: number[]) => { return chunk.reduce((sum, val) => sum + val, 0); }, { minThreads: 2, maxThreads: 8, idleTimeout: 5000 }); console.log(`Pool has ${dataProcessor.maxThreads} max threads`); console.log(`Pool keeps ${dataProcessor.minThreads} threads warm`); const chunks = Array.from({ length: 20 }, () => Array.from({ length: 1000 }, () => Math.random()) ); const results = await Promise.all(chunks.map(chunk => dataProcessor.run([chunk]))); console.log(`Active threads: ${dataProcessor.busy}`); await dataProcessor.idle; console.log(`All tasks complete. Active threads: ${dataProcessor.busy}`); await dataProcessor.close(); ``` ``` -------------------------------- ### ThreadPool Constructor in Bun.js Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/ThreadPool.html Initializes a new ThreadPool instance. It takes a callback function and optional options for managing thread behavior. The callback function must be serializable and cannot rely on external scope. Requires the 'bun-threads' package. ```typescript new ThreadPool(fn: T, options?: ThreadPoolOptions): ThreadPool ``` -------------------------------- ### Get Max Listeners from Node EventEmitter Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Illustrates the `getMaxListeners` method from Node.js's `EventEmitter`. This method retrieves the current maximum number of listeners allowed for any single event on the EventEmitter instance. This value can be set using `setMaxListeners` or defaults to `EventEmitter.defaultMaxListeners`. ```javascript import { EventEmitter } from 'node:events'; const emitter = new EventEmitter(); console.log(emitter.getMaxListeners()); // Example output: 10 (default) ``` -------------------------------- ### ThreadPoolOptions Interface Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/interfaces/ThreadPoolOptions.html Defines the options available for configuring a ThreadPool in the bun-threads library. ```APIDOC ## Interface: ThreadPoolOptions ### Description An interface that extends `ThreadOptions` and provides specific configurations for a `ThreadPool`. ### Properties #### `idleTimeout` (number) - Optional How long (in milliseconds) to keep the `Thread` or `ThreadPool` active after completing a task before terminating it. Keeping the `Thread` or `ThreadPool` open will decrease repeat startup times, but will cause the program to hang and not exit if the `Thread.close` method is not called. Default is `0` (close immediately). * **Default**: `0` * **Inherited from**: `ThreadOptions.idleTimeout` * **Defined in**: `threadpool.ts:9` #### `maxThreads` (number) - Optional The maximum number of `Threads` that are allowed to be running at once. Once this limit is reached, any further calls will be enqueued in a promise until a `Thread` becomes available. By default, the maximum is set to `os.availableParallelism() - 1`, which generally should not be exceeded, as it should not offer any performance gains. Setting this value to less than `minThreads` will cause `minThreads` to be lowered to the same value. * **Defined in**: `threadpool.ts:13` #### `minThreads` (number) - Optional The number of `Threads` to keep active with a `Thread.idleTimeout` of `Infinity` (never close automatically). By default, one `Thread` will be kept warm for fast startup times. Additional `Threads` in the range of `minThreads + 1` and `maxThreads` (inclusive) will have their `Thread.idleTimeout` set to `idleTimeout`. Setting this value to greater than `maxThreads` will cause `maxThreads` to be raised to the same value. * **Defined in**: `threadpool.ts:11` ### Hierarchy * [ThreadOptions](ThreadOptions.html) * ThreadPoolOptions ### Example Usage (Conceptual) ```typescript import { ThreadPool } from 'bun-threads'; const pool = new ThreadPool({ minThreads: 2, maxThreads: 5, idleTimeout: 60000 // 1 minute }); ``` ``` -------------------------------- ### Get and Set Max Listeners for Event Emitters and Targets Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html Returns the current maximum number of listeners allowed for an EventEmitter or EventTarget. It also demonstrates how to set this maximum using setMaxListeners. This is crucial for managing potential memory leaks and is available since v19.9.0. ```typescript import { getMaxListeners, setMaxListeners, EventEmitter } from 'node:events'; // For EventEmitter const ee = new EventEmitter(); console.log(getMaxListeners(ee)); // 10 setMaxListeners(11, ee); console.log(getMaxListeners(ee)); // 11 // For EventTarget const et = new EventTarget(); console.log(getMaxListeners(et)); // 10 setMaxListeners(11, et); console.log(getMaxListeners(et)); // 11 ``` -------------------------------- ### Thread Class Constructor Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Initializes a new Thread instance to run tasks on a separate Bun worker thread. It accepts a callback function and optional thread options. ```APIDOC ## new Thread(fn: T, options?: ThreadOptions): Thread ### Description Create a new `Thread` to run tasks on a separate Bun worker thread. ### Method `new` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **fn** (T) - Required - The callback function to be executed in parallel upon calling the asynchronous `run` method. Argument types must be serializable using the `structuredClone()` algorithm. Callback functions can not be closures or rely upon top level imports, as they do not have access to variables or imports outside of their isolated worker thread environment. They can however use dynamic imports using the `const myPackage = await import('some_package')` syntax. - **options** (ThreadOptions) - Optional - A `ThreadOptions` configuration object for the thread. ### Request Example ```typescript import { Thread } from "bun-threads"; const threadWithImports = new Thread(async (num: number) => { const sqlite = await import('bun:sqlite'); const db = new sqlite.Database('./db.sqlite'); db.run("INSERT INTO answers VALUES(?)", [ num ]); }); ``` ### Response #### Success Response (200) Returns an instance of `Thread`. #### Response Example ```json { "message": "Thread instance created successfully" } ``` ### Overrides EventEmitter.constructor ``` -------------------------------- ### Get Event Listeners for EventEmitter and EventTarget Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html Retrieves a copy of the array of listeners for a specified event name on an EventEmitter or EventTarget. This is particularly useful for debugging and diagnostics, especially for EventTargets where direct listener access is otherwise unavailable. Available since v15.2.0 and v14.17.0. ```typescript import { getEventListeners, EventEmitter } from 'node:events'; // For EventEmitter const ee = new EventEmitter(); const listener = () => console.log('Events are fun'); ee.on('foo', listener); console.log(getEventListeners(ee, 'foo')); // [ [Function: listener] ] // For EventTarget const et = new EventTarget(); const listener2 = () => console.log('Events are fun'); et.addEventListener('foo', listener2); console.log(getEventListeners(et, 'foo')); // [ [Function: listener] ] ``` -------------------------------- ### Thread Instance Accessors Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html Details about the accessor properties available on a Thread instance. ```APIDOC ## Thread Instance Accessors ### `busy` - **Type**: `boolean` - **Description**: Indicates whether the `Thread` is currently busy running a task. This status is checked on the main thread while the task runs on the worker. To wait until the `Thread` is not busy, await the `idle` property. - **Defined in**: [thread.ts:60](https://github.com/taylorsreid/bun-threadpool/blob/0eb7b7111bd4c450de2fd29a8d9b956207b5774f/thread.ts#L60) ### `closed` - **Type**: `boolean` - **Description**: Indicates whether the `Thread`'s underlying worker is currently instantiated or not. - **Defined in**: [thread.ts:112](https://github.com/taylorsreid/bun-threadpool/blob/0eb7b7111bd4c450de2fd29a8d9b956207b5774f/thread.ts#L112) ### `id` - **Type**: `undefined | number` - **Description**: A unique integer identifier for the referenced `Thread`. May be `undefined` if the underlying worker is currently closed. - **Defined in**: [thread.ts:67](https://github.com/taylorsreid/bun-threadpool/blob/0eb7b7111bd4c450de2fd29a8d9b956207b5774f/thread.ts#L67) ``` -------------------------------- ### Get Listener Count for an Event Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html The `listenerCount` method returns the number of listeners registered for a specific event. If an optional listener function is provided, it returns the count of how many times that specific listener is registered for the event. This is useful for monitoring event handler activity. ```typescript /** * Returns the number of listeners listening for the event named `eventName`. * If `listener` is provided, it will return how many times the listener is found in the list of the listeners of the event. * @param eventName The name of the event being listened for * @param listener The event handler function (optional) * @returns The number of listeners. * @since v3.2.0 */ listenerCount(eventName: string | symbol, listener?: Function): number; ``` -------------------------------- ### Thread vs ThreadPool Performance Comparison Source: https://context7.com/taylorsreid/bun-threads/llms.txt Demonstrate the performance benefits of using ThreadPool for parallel execution compared to single Threads, especially when handling multiple concurrent tasks. ```APIDOC ## Thread vs ThreadPool Performance Comparison ### Description Compares the performance of executing multiple tasks using a single `Thread` versus a `ThreadPool`. `ThreadPool` generally offers better performance for concurrent tasks due to its ability to manage and reuse threads efficiently. ### Method `new Thread(workerFunction)` and `new ThreadPool(workerFunction, options)` ### Request Example ```typescript import { Thread, ThreadPool } from "bun-threads"; const simulateWork = (duration: number) => Bun.sleepSync(duration); const singleThread = new Thread(simulateWork); const threadPool = new ThreadPool(simulateWork, { maxThreads: 3 }); let start = performance.now(); await Promise.all([ singleThread.run([1000]), singleThread.run([1000]), singleThread.run([1000]) ]); console.log(`Single Thread: ${performance.now() - start}ms`); start = performance.now(); await Promise.all([ threadPool.run([1000]), threadPool.run([1000]), threadPool.run([1000]) ]); console.log(`ThreadPool: ${performance.now() - start}ms`); await singleThread.close(); await threadPool.close(); ``` ``` -------------------------------- ### Thread Constructor Source: https://context7.com/taylorsreid/bun-threads/llms.txt Initializes a new `Thread` instance to execute a callback function in a separate worker thread. Optional configuration like `idleTimeout` can be provided. ```APIDOC ## Thread Constructor ### Description Create a single worker thread to execute a callback function in parallel. ### Method `new Thread(callback: Function, options?: { idleTimeout?: number })` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **callback** (Function) - The function to execute in the worker thread. - **options** (Object) - Optional configuration object. - **idleTimeout** (number) - The time in milliseconds after which an idle thread will be terminated. (Optional) ### Request Example ```typescript import { Thread } from "bun-threads"; const computeFactorial = new Thread((n: number) => { let result = 1; for (let i = 2; i <= n; i++) { result *= i; } return result; }, { idleTimeout: 5000 }); const result = await computeFactorial.run([10]); console.log(`Factorial of 10: ${result}`); await computeFactorial.close(); ``` ### Response #### Success Response (200) Returns the result of the callback function executed in the worker thread. #### Response Example ```json { "result": 3628800 } ``` ``` -------------------------------- ### Get Thread Idle State Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html The `idle` property returns a promise that resolves when a `Thread` has finished its task and is idle. This is primarily used internally by the `ThreadPool` class. If the thread is not busy, the promise resolves immediately. It can be used to determine which thread finishes a task first. ```typescript import { Thread } from "bun-threads"; const countUp = new Thread((countUpTo: number) => { let current: number = 0; for (let i = 0; i <= countUpTo; i++) { current = i; } return current; }); const countDown = new Thread((countDownFrom: number) => { let current: number = countDownFrom; for (let i = countDownFrom; i >= 0; i--) { current = i; } return current; }); countUp.run([1_000_000]); countDown.run([1_000_000]); // Use idle property to get the thread that finishes first Promise.race([countUp.idle, countDown.idle]).then((winner) => { // do it again winner.run([1_000_000]).then(async (value: number) => { if (value === 0) { console.log('countDown was the winner'); } else { console.log('countUp was the winner'); } }).then(() => { countUp.close(); countDown.close(); }); }); ``` -------------------------------- ### Thread with Dynamic Imports in bun-threads Source: https://context7.com/taylorsreid/bun-threads/llms.txt Shows how to use dynamic imports within a thread's callback function to load external modules like 'bun:sqlite'. This enables threads to access databases or other resources dynamically. It requires 'bun-threads' and 'bun:sqlite'. ```typescript import { Thread } from "bun-threads"; const databaseWorker = new Thread(async (query: string, params: any[]) => { const sqlite = await import('bun:sqlite'); const db = new sqlite.Database('./data.db'); const stmt = db.query(query); const results = stmt.all(...params); db.close(); return results; }); const users = await databaseWorker.run([ "SELECT * FROM users WHERE age > ?", [18] ]); console.log(users); await databaseWorker.close(); ``` -------------------------------- ### Get Thread Identifier (TypeScript) Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Shows how to retrieve the unique integer identifier for a `Thread` object using the `id` accessor. This identifier may be `undefined` if the underlying worker is currently closed. This is useful for tracking and debugging individual threads within a multi-threaded application. ```typescript import { Thread } from './thread'; // Assuming Thread is imported from a local file const thread = new Thread(); const threadId = thread.id; if (threadId !== undefined) { console.log(`Thread ID: ${threadId}`); } else { console.log('Thread ID is undefined as the worker is closed.'); } ``` -------------------------------- ### Compare Thread vs ThreadPool Performance Source: https://context7.com/taylorsreid/bun-threads/llms.txt Demonstrates the performance difference between using a single `Thread` and a `ThreadPool` for executing repetitive tasks. The `ThreadPool` typically offers better performance due to its ability to manage and reuse multiple threads, especially when tasks are short-lived or numerous. ```typescript import { Thread, ThreadPool } from "bun-threads"; const simulateWork = (duration: number) => Bun.sleepSync(duration); const singleThread = new Thread(simulateWork); const threadPool = new ThreadPool(simulateWork, { maxThreads: 3 }); let start = performance.now(); await Promise.all([ singleThread.run([1000]), singleThread.run([1000]), singleThread.run([1000]) ]); console.log(`Single Thread: ${performance.now() - start}ms`); start = performance.now(); await Promise.all([ threadPool.run([1000]), threadPool.run([1000]), threadPool.run([1000]) ]); console.log(`ThreadPool: ${performance.now() - start}ms`); await singleThread.close(); await threadPool.close(); ``` -------------------------------- ### Thread Idle State Promise Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html Provides a promise that resolves when a Thread finishes its task and becomes idle. This is useful for managing thread completion, especially within a ThreadPool. It resolves immediately if the thread is not currently busy. The example demonstrates using Promise.race to determine which of two threads finishes first. ```typescript import { Thread } from "bun-threads"; const countUp = new Thread((countUpTo: number) => { let current: number = 0; for (let i = 0; i <= countUpTo; i++) { current = i; } return current; }); const countDown = new Thread((countDownFrom: number) => { let current: number = countDownFrom; for (let i = countDownFrom; i >= 0; i--) { current = i; } return current; }); countUp.run([1_000_000]); countDown.run([1_000_000]); // you can use the idle property to get the **thread** that finishes first, not the result Promise.race([countUp.idle, countDown.idle]).then((winner) => { // do it again winner.run([1_000_000]).then(async (value: number) => { if (value === 0) { console.log('countDown was the winner'); } else { console.log('countUp was the winner'); } }).then(() => { countUp.close(); countDown.close(); }); ``` -------------------------------- ### Iterate EventTarget Events with AsyncIterator (Web API) Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html This code shows how to use the 'on' function to create an AsyncIterator for a standard web EventTarget. It iterates over 'eventName' events and logs their arguments. Note that this is distinct from the Node.js EventEmitter version, though the usage is similar. ```typescript import { on } from 'node:events'; // Assuming 'on' is polyfilled or available // This example assumes an EventTarget is available, e.g., an HTML element or a custom EventTarget. // For demonstration, we'll mock a simple EventTarget. class MockEventTarget { private listeners: Map = new Map(); addEventListener(type: string, listener: Function) { if (!this.listeners.has(type)) { this.listeners.set(type, []); } this.listeners.get(type)!.push(listener); } removeEventListener(type: string, listener: Function) { if (this.listeners.has(type)) { const listeners = this.listeners.get(type)!; const index = listeners.indexOf(listener); if (index > -1) { listeners.splice(index, 1); } } } dispatchEvent(event: Event) { if (this.listeners.has(event.type)) { this.listeners.get(event.type)!.forEach(listener => listener(event)); } return true; } } const et = new MockEventTarget(); // Emit later on setTimeout(() => { et.dispatchEvent(new Event('foo')); et.dispatchEvent(new Event('foo')); }, 0); (async () => { for await (const event of on(et, 'foo')) { console.log(event); // prints arguments passed to dispatchEvent, typically an array of events or custom data } })(); // Note: In a real browser environment, you would use an actual EventTarget like document.body or a custom element. ``` -------------------------------- ### Iterate EventEmitter Events with AsyncIterator (Node.js) Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html This code snippet demonstrates how to use the 'on' function to create an AsyncIterator for 'node:events' EventEmitter. It iterates over 'foo' events and logs their arguments. The loop processes events synchronously, one at a time. It handles emitting events later using process.nextTick. ```typescript import { on, EventEmitter } from 'node:events'; import process from 'node:process'; const ee = new EventEmitter(); // Emit later on process.nextTick(() => { ee.emit('foo', 'bar'); ee.emit('foo', 42); }); for await (const event of on(ee, 'foo')) { // The execution of this inner block is synchronous and it // processes one event at a time (even with await). Do not use // if concurrent execution is required. console.log(event); // prints ['bar'] [42] } // Unreachable here ``` -------------------------------- ### Bun Thread vs ThreadPool Performance Comparison (TypeScript) Source: https://github.com/taylorsreid/bun-threads/blob/main/README.md Compares the performance of Bun's Thread and ThreadPool when running multiple synchronous tasks. A single Thread executes tasks sequentially, taking approximately 3000ms for three tasks. A ThreadPool, utilizing parallel execution, completes the same tasks in about 1000ms. Requires the 'bun-threads' package. ```typescript import { Thread, ThreadPool } from "bun-threads"; const thread = new Thread((wait: number) => Bun.sleepSync(wait)) // simulate some synchronous work const threadPool = new ThreadPool((wait: number) => Bun.sleepSync(wait)) // simulate some synchronous work let start = performance.now() await Promise.all([ thread.run([1_000]), thread.run([1_000]), thread.run([1_000]) ]) // a single Thread can only execute synchronous tasks one at a time console.log('Thread completed in:', performance.now() - start, 'ms') // ~ 3000 ms start = performance.now() await Promise.all([ threadPool.run([1_000]), threadPool.run([1_000]), threadPool.run([1_000]) ]) // ThreadPool runs each task in a separate Thread in parallel console.log('ThreadPool completed in:', performance.now() - start, 'ms') // ~ 1000 ms thread.close() threadPool.close() ``` -------------------------------- ### EventEmitter Static Properties Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/media/Thread.html Information about static properties related to EventEmitter, inherited by Thread. ```APIDOC ## Static Properties (Inherited from EventEmitter) ### `defaultMaxListeners` - **Type**: `number` - **Description**: By default, a maximum of `10` listeners can be registered for any single event. This limit can be changed globally for all `EventEmitter` instances using this property. If this value is not a positive number, a `RangeError` is thrown. Be cautious as changes affect all `EventEmitter` instances. Calling `emitter.setMaxListeners(n)` still takes precedence. - **Since**: v0.11.2 ### `errorMonitor` - **Type**: `typeof errorMonitor` - **Description**: This symbol is used to install a listener for monitoring `'error'` events. Listeners installed using this symbol are called before regular `'error'` listeners. Installing a listener here does not change the behavior if no regular `'error'` listener is installed; the process will still crash. - **Since**: v13.6.0, v12.17.0 ``` -------------------------------- ### Thread Class Properties Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Details on the properties available for a Thread instance, including the callback function and static properties related to error handling. ```APIDOC ## Thread Properties ### `fn` - **Type**: T - **Description**: The callback function to be executed in parallel upon calling the asynchronous `run` method. ### `Static` `captureRejections` - **Type**: boolean - **Description**: Change the default `captureRejections` option on all new `EventEmitter` objects. - **Since**: v13.4.0, v12.16.0 - **Inherited from**: EventEmitter.captureRejections ### `Static` `Readonly` `captureRejectionSymbol` - **Type**: typeof Symbol.for('nodejs.rejection') - **Description**: A symbol used to identify rejection handlers. - **Since**: v13.4.0, v12.16.0 - **Inherited from**: EventEmitter.captureRejectionSymbol ``` -------------------------------- ### Check Thread Busy Status (TypeScript) Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Provides a TypeScript example for checking if a `Thread` object is currently executing a task. The `busy` property returns a boolean indicating the thread's activity status. It's important to note that this check can be performed while a task is still running, and for waiting until the thread is idle, the `idle` property should be awaited. ```typescript import { Thread } from './thread'; // Assuming Thread is imported from a local file const thread = new Thread(); const isBusy = thread.busy; console.log(`Thread is busy: ${isBusy}`); ``` -------------------------------- ### Run String Scramble in Bun Thread Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html This code snippet defines a new thread using `bun-threads`. The thread's worker function takes a string, splits it into characters, randomly reorders them, and returns the scrambled string. It's configured with an `idleTimeout` and demonstrates running the thread with an input string. ```typescript import { Thread } from "bun-threads"; const scramble = new Thread((toScramble: string) => { const randomNumber = (min: number, max: number) => { return Math.random() * (max - min) + min; } const oldArr: string[] = toScramble.split('') const newArr: string[] = [] while (oldArr.length > 0) { const rand: number = randomNumber(0, oldArr.length) newArr.push(oldArr.splice(rand, 1)[0]!) } return newArr.join('') }, { idleTimeout: 500 }) scramble.on('close', () => { console.log(`Scramble thread has completed its work and has closed after its idleTimeout of ${scramble.idleTimeout} milliseconds. `) }) console.log(await scramble.run(['hello world'])) // outputs a randomly rearranged 'hello world' ``` -------------------------------- ### Remove Event Listener using Node.js EventEmitter Source: https://github.com/taylorsreid/bun-threads/blob/main/docs/classes/Thread.html Removes a specified listener function from the event emitter for a given event name. It removes at most one instance of the listener per call. If a listener is added multiple times, it must be removed multiple times. Listeners removed after an event has started emitting will not affect the current emission. ```typescript import { EventEmitter } from 'node:events'; class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); const callbackA = () => { console.log('A'); myEmitter.removeListener('event', callbackB); }; const callbackB = () => { console.log('B'); }; myEmitter.on('event', callbackA); myEmitter.on('event', callbackB); myEmitter.emit('event'); // Prints: A, B myEmitter.emit('event'); // Prints: A ``` ```typescript import { EventEmitter } from 'node:events'; const ee = new EventEmitter(); function pong() { console.log('pong'); } ee.on('ping', pong); ee.once('ping', pong); ee.removeListener('ping', pong); ee.emit('ping'); // Prints: pong ee.emit('ping'); // Prints: pong ```