{"id":42490333,"url":"https://github.com/w4g1/multithreading","last_synced_at":"2026-01-28T12:00:38.558Z","repository":{"id":212966022,"uuid":"732151165","full_name":"W4G1/multithreading","owner":"W4G1","description":"The missing standard library for multithreading in JavaScript (Works in the browser, Node.js, Deno, Bun)","archived":false,"fork":false,"pushed_at":"2025-12-19T23:02:46.000Z","size":440,"stargazers_count":1348,"open_issues_count":0,"forks_count":21,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-12-22T09:35:08.290Z","etag":null,"topics":["atomics","bun","concurrency","deno","javascript","multi-threading","multithreading","nodejs","parallel-processing","shared-array-buffer","shared-worker","sharedarraybuffer","thread-pool","threads","typescript","web-worker","web-workers","webworkers","worker-pool","worker-threads"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/W4G1.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-12-15T19:17:53.000Z","updated_at":"2025-12-22T09:11:35.000Z","dependencies_parsed_at":"2024-01-07T12:40:01.946Z","dependency_job_id":null,"html_url":"https://github.com/W4G1/multithreading","commit_stats":null,"previous_names":["w4g1/multithreading"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/W4G1/multithreading","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/W4G1%2Fmultithreading","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/W4G1%2Fmultithreading/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/W4G1%2Fmultithreading/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/W4G1%2Fmultithreading/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/W4G1","download_url":"https://codeload.github.com/W4G1/multithreading/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/W4G1%2Fmultithreading/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28845103,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-28T10:53:21.605Z","status":"ssl_error","status_checked_at":"2026-01-28T10:53:20.789Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atomics","bun","concurrency","deno","javascript","multi-threading","multithreading","nodejs","parallel-processing","shared-array-buffer","shared-worker","sharedarraybuffer","thread-pool","threads","typescript","web-worker","web-workers","webworkers","worker-pool","worker-threads"],"created_at":"2026-01-28T12:00:34.131Z","updated_at":"2026-01-28T12:00:38.543Z","avatar_url":"https://github.com/W4G1.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n  ![Logo](https://github.com/user-attachments/assets/0981b64a-8c55-48b5-b369-0c765757a162)\n\n  \u003ch1\u003eMultithreading.js\u003c/h1\u003e\n\n  \u003cp\u003e\n    \u003cstrong\u003eRobust, Rust-inspired concurrency primitives for the JavaScript ecosystem.\u003c/strong\u003e\n  \u003c/p\u003e\n\n  [![License](https://img.shields.io/github/license/W4G1/multithreading)](https://github.com/W4G1/multithreading/blob/main/LICENSE.md)\n  [![Downloads](https://img.shields.io/npm/dw/multithreading?color=%238956FF)](https://www.npmjs.com/package/multithreading)\n  [![NPM version](https://img.shields.io/npm/v/multithreading)](https://www.npmjs.com/package/multithreading?activeTab=versions)\n  [![GitHub Repo stars](https://img.shields.io/github/stars/W4G1/multithreading?logo=github\u0026label=Star\u0026labelColor=rgb(26%2C%2030%2C%2035)\u0026color=rgb(13%2C%2017%2C%2023))](https://github.com/W4G1/multithreading)\n\u003c/div\u003e\n\n\u003cbr /\u003e\n\n**Multithreading** is a TypeScript library that brings robust, Rust-inspired concurrency primitives to the JavaScript ecosystem. It provides a thread-pool architecture, strict memory safety semantics, and synchronization primitives like Mutexes, Semaphores, Read-Write Locks, and Condition Variables.\n\nThis library is designed to abstract away the complexity of managing `WebWorkers`, serialization, and `SharedArrayBuffer` complexities, allowing developers to write multi-threaded code that looks and feels like standard asynchronous JavaScript.\n\n## Installation\n\n```bash\nnpm install multithreading\n```\n\nSee: [Browser compatibility](#browser-compatibility)\n\n## Core Concepts\n\nJavaScript is traditionally single-threaded. To achieve true parallelism, this library uses Web Workers. However, unlike standard Workers, this library offers:\n\n1.  **Managed Worker Pool**: Automatically manages a pool of threads based on hardware concurrency.\n2.  **Shared Memory Primitives**: Tools to safely share state between threads without race conditions.\n3.  **Scoped Imports**: Support for importing external modules and relative files directly within worker tasks.\n4.  **Move Semantics**: Explicit data ownership transfer to prevent cloning overhead.\n\n## Quick Start\n\nThe entry point for most operations is the `spawn` function. This submits a task to the thread pool and returns a handle to await the result.\n\n```typescript\nimport { spawn } from \"multithreading\";\n\n// Spawn a task on a background thread\nconst handle = spawn(() =\u003e {\n  // This code runs in a separate worker\n  const result = Math.random();\n  return result;\n});\n\n// Wait for the result\nconst result = await handle.join();\n\nif (result.ok) {\n  console.log(\"Result:\", result.value); // 0.6378467071314606\n} else {\n  console.error(\"Worker error:\", result.error);\n}\n```\n\n-----\n\n## Passing Data: The `move()` Function\n\nBecause Web Workers run in a completely isolated context, functions passed to `spawn` cannot capture variables from their outer scope. If you attempt to use a variable inside the worker that was defined outside of it, the code will fail.\n\nTo get data from your main thread into the worker, you have to use the `move()` function.\n\nThe `move` function accepts a variable number of arguments. These arguments are passed to the worker function in the order they were provided. Despite the name, `move` handles data in two ways:\n\n1.  **Transferable Objects (e.g., `ArrayBuffer`, `Uint32Array`):** These are \"moved\" (zero-copy). Ownership transfers to the worker, and the original becomes unusable in the main thread.\n2.  **Non-Transferable Objects (e.g., JSON, numbers, strings):** These are cloned via structured cloning. They remain usable in the main thread.\n\n\u003c!-- end list --\u003e\n\n```typescript\nimport { spawn, move } from \"multithreading\";\n\n// Will be transferred\nconst largeData = new Uint8Array(1024 * 1024 * 10); // 10MB\n// Will be cloned\nconst metaData = { id: 1 };\n\nconst handle = spawn(move(largeData, metaData), (data, meta) =\u003e {\n  console.log(\"Processing ID:\", meta.id);\n  return data.byteLength;\n});\n\nawait handle.join();\n```\n\n-----\n\n## SharedJsonBuffer: Complex Objects in Shared Memory\n\n`SharedJsonBuffer` enables Mutex-protected shared memory for JSON objects, eliminating the overhead of `postMessage` data copying. It supports partial updates by utilizing [Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) under the hood, reserializing only changed bytes rather than the entire object tree for high-performance state synchronization, especially with large JSON objects.\n\n**Note:** Initializing a `SharedJsonBuffer` has a performance cost. For single-use transfers, `SharedJsonBuffer` is slower than cloning. This data structure is optimized for incremental updates to a large persistent shared object or array that will be accessed frequently between multiple threads.\n\n```typescript\nimport { spawn, move, Mutex, SharedJsonBuffer } from \"multithreading\";\n\nconst sharedState = new Mutex(new SharedJsonBuffer({\n  score: 0,\n  players: [\"Main Thread\"],\n  level: {\n    id: 1,\n    title: \"Start\",\n  },\n}));\n\nawait spawn(move(sharedState), async (sharedState) =\u003e {\n  using guard = await sharedState.lock();\n\n  const state = guard.value;\n\n  console.log(`Current Score: ${state.score}`);\n\n  // Modify the data\n  state.score += 100;\n  state.players.push(\"Worker1\");\n\n  // End of scope: Lock is automatically released here\n}).join();\n\n// Verify on main thread\nusing guard = await sharedState.lock();\n\nconsole.log(guard.value); // { score: 100, players: [\"Main Thread\", \"Worker1\"], ... }\n```\n\n-----\n\n## Synchronization Primitives\n\nWhen multiple threads access shared memory (via `SharedArrayBuffer`), race conditions occur. This library provides primitives to synchronize access safely.\n\n**Best Practice:** It is highly recommended to use the asynchronous methods (e.g., `acquire`, `read`, `write`, `wait`) rather than their synchronous counterparts. Synchronous blocking halts the entire Worker thread, potentially pausing other tasks sharing that worker.\n\n### 1\\. Mutex (Mutual Exclusion)\n\nA `Mutex` ensures that only one thread can access a specific piece of data at a time.\n\n#### Option A: Automatic Management (Recommended)\n\nThis library has support for the [Explicit Resource Management](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/using) proposal (`using` keyword). When you acquire a lock, it returns a guard. When that guard goes out of scope, the lock is automatically released.\n\n```typescript\nimport { spawn, move, Mutex } from \"multithreading\";\n\nconst buffer = new SharedArrayBuffer(4);\nconst counterMutex = new Mutex(new Int32Array(buffer));\n\nspawn(move(counterMutex), async (mutex) =\u003e {\n  // 'using' automatically disposes the lock at the end of the scope\n  using guard = await mutex.lock();\n  \n  guard.value[0]++;\n  \n  // End of scope: Lock is released here\n});\n```\n\n#### Option B: Manual Management (Bun / Standard JS)\n\nIf you are using **Bun** or prefer standard JavaScript syntax, you must manually release the lock using `.dispose()`.\n\n**Note on Bun:** While Bun is supported, it's runtime automatically polyfills the `using` keyword whenever a function is stringified. This transpiled code relies on specific internal globals made available in the context where the function is serialized. Because the worker runs in a different isolated context where these globals are not registered, code with `using` will fail to execute.\n\nAlways use a `try...finally` block to ensure the lock is released even if an error occurs.\n\n```typescript\nimport { spawn, move, Mutex } from \"multithreading\";\n\nconst counterMutex = new Mutex(new Int32Array(new SharedArrayBuffer(4)));\n\nspawn(move(counterMutex), async (mutex) =\u003e {\n  // 1. Acquire the lock manually\n  const guard = await mutex.lock();\n\n  try {\n    // 2. Critical Section\n    guard.value[0]++;\n  } finally {\n    // 3. Explicitly release the lock\n    guard.dispose();\n  }\n});\n```\n\n### 2\\. RwLock (Read-Write Lock)\n\nA `RwLock` is optimized for scenarios where data is read often but written rarely. It allows **multiple** simultaneous readers but only **one** writer.\n\n```typescript\nimport { spawn, move, RwLock } from \"multithreading\";\n\nconst lock = new RwLock(new Int32Array(new SharedArrayBuffer(4)));\n\n// Spawning a Writer\nspawn(move(lock), async (l) =\u003e {\n  // Blocks until all readers are finished (asynchronously)\n  using guard = await l.write(); \n  guard.value[0] = 42;\n});\n\n// Spawning Readers\nspawn(move(lock), async (l) =\u003e {\n  // Multiple threads can hold this lock simultaneously\n  using guard = await l.read(); \n  console.log(guard.value[0]);\n});\n```\n\n### 3\\. Semaphore\n\nA `Semaphore` limits the number of threads that can access a resource simultaneously. Unlike a Mutex (which allows exactly 1 owner), a Semaphore allows `N` owners. This is essential for rate limiting, managing connection pools, or bounding concurrency.\n\n```typescript\nimport { spawn, move, Semaphore } from \"multithreading\";\n\n// Initialize with 3 permits (allowing 3 concurrent tasks)\nconst semaphore = new Semaphore(3);\n\nfor (let i = 0; i \u003c 10; i++) {\n  spawn(move(semaphore), async (sem) =\u003e {\n    console.log(\"Waiting for permit...\");\n    \n    // Will wait (async) if 3 threads are already working\n    using _permit = await sem.acquire(); \n    \n    console.log(\"Acquired permit! Working...\");\n\n    await new Promise(r =\u003e setTimeout(r, 1000));\n    \n    // Permit is released here automatically because of `using`\n  });\n}\n```\n\n#### Manual Release\n\nLike the Mutex, if you cannot use the `using` keyword, you can manually manage the lifecycle.\n\n```typescript\nspawn(move(semaphore), async (sem) =\u003e {\n  // Acquire 2 permits at once\n  const permits = await sem.acquire(2);\n  \n  try {\n    // Critical Section\n  } finally {\n    // Release the 2 permits\n    permits.dispose();\n  }\n});\n```\n\n### 4\\. Condvar (Condition Variable)\n\nA `Condvar` allows threads to wait for a specific condition to become true. It saves CPU resources by putting the task to sleep until it is notified, rather than constantly checking a value.\n\n```typescript\nimport { spawn, move, Mutex, Condvar } from \"multithreading\";\n\nconst mutex = new Mutex(new Int32Array(new SharedArrayBuffer(4)));\nconst cv = new Condvar();\n\nspawn(move(mutex, cv), async (mutex, cv) =\u003e {\n  using guard = await mutex.lock();\n  \n  // Wait until value is not 0\n  while (guard.value[0] === 0) {\n    // wait() unlocks the mutex, waits for notification, then re-locks\n    await cv.wait(guard);\n  }\n  \n  console.log(\"Received signal, value is:\", guard.value[0]);\n});\n```\n\n### 5\\. Barrier\n\nA `Barrier` acts as a synchronization checkpoint. It blocks all participating threads until a specific number (`N`) of threads have reached the barrier. Once the last thread arrives, all threads are released simultaneously.\n\nBarriers are **cyclic**, meaning they automatically reset and can be reused immediately for subsequent phases of work (e.g., in iterative algorithms like simulations).\n\n**Leader Election:** The `wait()` method returns an object `{ isLeader: boolean }`. Exactly **one** thread is guaranteed to be the leader per cycle. This is useful for performing single-threaded setup or cleanup tasks between parallel phases.\n\n```typescript\nimport { spawn, move, Barrier } from \"multithreading\";\n\nconst N = 4;\nconst barrier = new Barrier(N);\n\nfor (let i = 0; i \u003c N; i++) {\n  spawn(move(barrier), async (b) =\u003e {\n    // Phase 1\n    console.log(\"Working on Phase 1...\");\n    \n    // Wait for all 4 threads to reach this point\n    const res = await b.wait();\n    \n    // Only one thread runs this code\n    if (res.isLeader) {\n      console.log(\"All threads finished Phase 1. preparing Phase 2...\");\n    }\n    \n    // Phase 2 (All threads start this simultaneously)\n    console.log(\"Working on Phase 2...\");\n  });\n}\n```\n\n-----\n\n## Channels (MPMC)\n\nFor higher-level communication, this library provides a **Multi-Producer, Multi-Consumer (MPMC)** bounded channel. This primitive acts as a **work-stealing queue**: it handles backpressure (blocking senders when full) and load-balances messages across receivers (blocking receivers when empty).\n\nUnlike an event emitter where all listeners hear every event, a Channel ensures that **each message is delivered to exactly one consumer**. This makes them the preferred way to coordinate complex workflows, such as distributing jobs across a pool of workers.\n\n### Key Features\n\n  * **Arbitrary JSON Data:** Channels are backed by `SharedJsonBuffer`, allowing you to send any JSON-serializable value (objects, arrays, strings, numbers, booleans) through the channel, not just raw integers.\n  * **Bounded:** You define a capacity. If the channel is full, `send()` waits. If empty, `recv()` waits.\n  * **Clonable:** Both `Sender` and `Receiver` can be cloned and moved to different workers.\n  * **Reference Counted:** The channel automatically closes when all Senders are dropped (indicating no more data will arrive) or all Receivers are dropped.\n\n### Example: Worker Pipeline with Objects\n\n```typescript\nimport { spawn, move, channel } from \"multithreading\";\n\nconst [tx, rx] = channel();\n\n// Producer\nspawn(move(tx), async (sender) =\u003e {\n  await sender.send({ hello: \"world\" });\n  await sender.send({ hello: \"multithreading\" });\n  // Sender is destroyed here, automatically closing the channel\n  // because the last tx goes out of scope here.\n});\n\n// Consumer\nawait spawn(move(rx.clone()), async (receiver) =\u003e {\n  // Manually take the first item from the queue\n  const result = await receiver.recv();\n  console.log(\"Worker got:\", result.value); // { hello: \"world\" }\n}).join();\n\n// Because we cloned rx, the main thread also still has a rx handle\nfor await (const value of rx) {\n  console.log(\"Main thread got:\", value); // { hello: \"multithreading\" }\n}\n```\n\n## Importing Modules in Workers\n\nThis library simplifies module loading within Web Workers by supporting standard dynamic `await import()` calls. It automatically handles path resolution, allowing you to import dependencies relative to the file calling `spawn`, rather than the worker's internal location.\n\nYou can import:\n\n1.  **External Libraries:** Packages from npm or CDNs (depending on your environment).\n2.  **Relative Files:** Local modules relative to the file where `spawn` is executed.\n\n**Note:** The function passed to `spawn` must be self-contained or explicitly import what it needs. It cannot access variables from the outer scope unless they are passed via `move()`.\n\n### Example: Importing Relative Files and External Libraries\n\nAssume you have a file structure:\n\n  - `main.ts`\n  - `utils.ts` (contains `export const magicNumber = 42;`)\n\n\u003c!-- end list --\u003e\n\n```typescript\n// main.ts\nimport { spawn } from \"multithreading\";\n\nspawn(async () =\u003e {\n  // Importing relative files\n  const utils = await import(\"./utils.ts\");\n  // Importing external libraries\n  const { v4: uuiv4 } = await import(\"uuid\");\n\n  console.log(\"Magic number from relative file:\", utils.magicNumber);\n  console.log(\"Random UUID:\", uuiv4());\n  \n  return utils.magicNumber;\n});\n```\n\n-----\n\n## Browser Compatibility\n\n**Core features** (like `spawn` and `move`) work in all modern browsers without special configuration.\n\n**Synchronization primitives** (`Mutex`, `RwLock`, `SharedJsonBuffer`, etc.) rely on `SharedArrayBuffer`, which requires your page to be **Cross-Origin Isolated**. To use these specific features, your server must send the following headers:\n\n```http\nCross-Origin-Opener-Policy: same-origin\nCross-Origin-Embedder-Policy: require-corp\n```\n\nIf these headers are missing, basic threading will work, but attempting to use synchronization primitives will result in an error.\n\n### Content Security Policy (CSP)\n\nThis library utilizes dynamic imports via `data:` and `blob:`  URLs to generate worker entry points from inline functions.\n\nIf your application uses a Content Security Policy (CSP), you must ensure that your `script-src` directive allows the `data:` scheme and your `worker-src` directive allows the `blob:` scheme.\n\n**Required CSP Headers:**\n\n```http\nContent-Security-Policy: default-src 'self'; worker-src 'self' blob:; script-src 'self' data: https:;\n```\n\n-----\n\n## API Reference\n\n### Runtime\n\n  * **`spawn(fn)`**: Runs a function in a worker.\n  * **`spawn(move(arg1, arg2, ...), fn)`**: Runs a function in a worker with specific arguments transferred or cloned.\n  * **`initRuntime(config)`**: Initializes the thread pool (optional, lazy loaded by default).\n  * **`shutdown()`**: Terminates all workers in the pool.\n\n### Memory Management\n\n  * **`move(...args)`**: Marks arguments for transfer (ownership move) or clone, depending on the data type. Accepts a variable number of arguments which map to the arguments of the worker function.\n  * **`drop(resource)`**: Explicitly disposes of a resource (calls `[Symbol.dispose]`).\n  * **`SharedJsonBuffer`**: A class for storing JSON objects in shared memory.\n\n### Channels (MPMC)\n\n  * **`channel\u003cT\u003e(capacity)`**: Creates a new channel. Returns `[Sender\u003cT\u003e, Receiver\u003cT\u003e]`.\n  * **`Sender\u003cT\u003e`**:\n      * `send(value)`: Async. Returns `Promise\u003cResult\u003cvoid, Error\u003e\u003e`.\n      * `blockingSend(value)`: Blocking. Returns `Result\u003cvoid, Error\u003e`.\n      * `clone()`: Creates a new handle to the same channel (increments ref count).\n      * `close()`: Manually closes the channel for everyone.\n  * **`Receiver\u003cT\u003e`**:\n      * `recv()`: Async. Returns `Promise\u003cResult\u003cT, Error\u003e\u003e`.\n      * `blockingRecv()`: Blocking. Returns `Result\u003cT, Error\u003e`.\n      * `clone()`: Creates a new handle to the same channel.\n      * `close()`: Manually drops this handle.\n\n### Synchronization\n\n  * **`Mutex\u003cT\u003e`**:\n      * `lock()`: Async lock (Recommended). Returns `Promise\u003cMutexGuard\u003e`.\n      * `tryLock()`: Non-blocking attempt. Returns boolean.\n      * `blockingLock()`: Blocking lock (Halts Worker). Returns `MutexGuard`.\n  * **`RwLock\u003cT\u003e`**:\n      * `read()`: Async shared read access (Recommended).\n      * `write()`: Async exclusive write access (Recommended).\n      * `blockingRead()` / `blockingWrite()`: Synchronous/Blocking variants.\n  * **`Semaphore`**:\n      * `acquire(amount?)`: Async wait for `n` permits (Recommended). Returns `Promise\u003cSemaphoreGuard\u003e`.\n      * `tryAcquire(amount?)`: Non-blocking. Returns `SemaphoreGuard` or `null`.\n      * `blockingAcquire(amount?)`: Blocking wait. Returns `SemaphoreGuard`.\n  * **`Condvar`**:\n      * `wait(guard)`: Async wait (Recommended). Yields execution.\n      * `notifyOne()`: Wake one waiting thread.\n      * `notifyAll()`: Wake all waiting threads.\n      * `blockingWait(guard)`: Blocking wait (Halts Worker).\n  * **`Barrier`**:\n      * `wait()`: Async wait (Recommended). Returns `Promise\u003c{ isLeader: boolean }\u003e`.\n      * `blockingWait()`: Blocking wait (Halts Worker). Returns `{ isLeader: boolean }`.\n\n-----\n\n## Technical Implementation Details\n\nFor advanced users interested in the internal mechanics:\n\n  * **Serialization Protocol**: The library uses a custom \"Envelope\" protocol (`PayloadType.RAW` vs `PayloadType.LIB`). This allows complex objects like `Mutex` handles to be serialized, sent to a worker, and rehydrated into a functional object connected to the same `SharedArrayBuffer` on the other side.\n  * **Atomics**: Synchronization is built on `Int32Array` backed by `SharedArrayBuffer` using `Atomics.wait` and `Atomics.notify`.\n  * **Import Patching**: The `spawn` function analyzes the stack trace to determine the caller's file path. It then regex-patches `import()` statements within the worker code string to ensure relative paths resolve correctly against the caller's location, rather than the worker's location.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fw4g1%2Fmultithreading","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fw4g1%2Fmultithreading","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fw4g1%2Fmultithreading/lists"}