{"_id":"sync-message-port","_rev":"3985184","name":"sync-message-port","description":"A Node.js communication port that can pass messages synchronously between workers","dist-tags":{"latest":"1.1.3"},"maintainers":[{"name":"nex3","email":"nex342@gmail.com"}],"time":{"modified":"2025-09-01T02:04:20.000Z","created":"2024-10-29T22:45:20.662Z","1.1.3":"2024-11-04T21:02:36.924Z","1.1.2":"2024-11-04T20:11:09.823Z","1.1.1":"2024-11-04T19:55:33.033Z","1.1.0":"2024-11-01T23:04:10.961Z","1.0.0":"2024-10-29T22:45:20.662Z"},"users":{},"author":{"name":"Google Inc."},"repository":{"type":"git","url":"git+https://github.com/sass/sync-message-port.git"},"versions":{"1.1.3":{"name":"sync-message-port","version":"1.1.3","description":"A Node.js communication port that can pass messages synchronously between workers","repository":{"type":"git","url":"git+https://github.com/sass/sync-message-port.git"},"author":{"name":"Google Inc."},"license":"MIT","exports":{"types":"./dist/lib/index.d.ts","default":"./dist/lib/index.js"},"main":"dist/lib/index.js","types":"dist/lib/index.d.ts","engines":{"node":">=16.0.0"},"scripts":{"check":"npm-run-all check:gts check:tsc","check:gts":"gts check","check:tsc":"tsc --noEmit","clean":"gts clean","compile":"tsc -p tsconfig.build.json","doc":"typedoc lib/index.ts","fix":"gts fix","test":"jest"},"devDependencies":{"@types/jest":"^29.4.0","@types/node":"^22.0.0","gts":"^6.0.2","jest":"^29.4.1","minipass":"7.1.2","npm-run-all":"^4.1.5","ts-jest":"^29.0.5","ts-node":"^10.2.1","typedoc":"^0.26.11","typescript":"^5.0.2"},"_id":"sync-message-port@1.1.3","gitHead":"072994797e04d15070c058580c3f2b09adf0a828","bugs":{"url":"https://github.com/sass/sync-message-port/issues"},"homepage":"https://github.com/sass/sync-message-port#readme","_nodeVersion":"22.11.0","_npmVersion":"10.9.0","dist":{"shasum":"6055c565ee8c81d2f9ee5aae7db757e6d9088c0c","size":19681,"noattachment":false,"key":"/sync-message-port/-/sync-message-port-1.1.3.tgz","tarball":"http://registry.cnpm.dingdandao.com/sync-message-port/download/sync-message-port-1.1.3.tgz"},"_npmUser":{"name":"nex3","email":"nex342@gmail.com"},"directories":{},"maintainers":[{"name":"nex3","email":"nex342@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/sync-message-port_1.1.3_1730754156743_0.613563892031356"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2024-11-04T21:02:36.924Z","publish_time":1730754156924,"_source_registry_name":"default","_cnpm_publish_time":1730754156924},"1.1.2":{"name":"sync-message-port","version":"1.1.2","description":"A Node.js communication port that can pass messages synchronously between workers","repository":{"type":"git","url":"git+https://github.com/sass/sync-message-port.git"},"author":{"name":"Google Inc."},"license":"MIT","exports":{"types":"./dist/lib/index.d.ts","default":"./dist/lib/index.js"},"main":"dist/lib/index.js","types":"dist/lib/index.d.ts","engines":{"node":">=16.0.0"},"scripts":{"check":"npm-run-all check:gts check:tsc","check:gts":"gts check","check:tsc":"tsc --noEmit","clean":"gts clean","compile":"tsc -p tsconfig.build.json","doc":"typedoc lib/index.ts","fix":"gts fix","test":"jest"},"devDependencies":{"@types/jest":"^29.4.0","@types/node":"^22.0.0","gts":"^6.0.2","jest":"^29.4.1","minipass":"7.1.2","npm-run-all":"^4.1.5","ts-jest":"^29.0.5","ts-node":"^10.2.1","typedoc":"^0.26.11","typescript":"^5.0.2"},"_id":"sync-message-port@1.1.2","gitHead":"00db35dac55b1b9780bb69ba1ddc4f7c1ca4f3b3","bugs":{"url":"https://github.com/sass/sync-message-port/issues"},"homepage":"https://github.com/sass/sync-message-port#readme","_nodeVersion":"22.11.0","_npmVersion":"10.9.0","dist":{"shasum":"32c80243fc694c9c3708726555114a60b7140a19","size":19607,"noattachment":false,"key":"/sync-message-port/-/sync-message-port-1.1.2.tgz","tarball":"http://registry.cnpm.dingdandao.com/sync-message-port/download/sync-message-port-1.1.2.tgz"},"_npmUser":{"name":"nex3","email":"nex342@gmail.com"},"directories":{},"maintainers":[{"name":"nex3","email":"nex342@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/sync-message-port_1.1.2_1730751069629_0.3551925876499371"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2024-11-04T20:11:09.823Z","publish_time":1730751069823,"_source_registry_name":"default","_cnpm_publish_time":1730751069823},"1.1.1":{"name":"sync-message-port","version":"1.1.1","author":{"name":"Google Inc."},"license":"MIT","_id":"sync-message-port@1.1.1","maintainers":[{"name":"nex3","email":"nex342@gmail.com"}],"homepage":"https://github.com/sass/sync-message-port#readme","bugs":{"url":"https://github.com/sass/sync-message-port/issues"},"dist":{"shasum":"5097d813cfa597a6b20eb784a63407594181cc29","size":19608,"noattachment":false,"key":"/sync-message-port/-/sync-message-port-1.1.1.tgz","tarball":"http://registry.cnpm.dingdandao.com/sync-message-port/download/sync-message-port-1.1.1.tgz"},"main":"dist/lib/index.js","types":"dist/lib/index.d.ts","engines":{"node":">=16.0.0"},"exports":{"types":"./dist/lib/index.d.ts","default":"./dist/lib/index.js"},"gitHead":"bc3534c73b6b9f85cb07a0c803a12aa320c946b0","scripts":{"doc":"typedoc lib/index.ts","fix":"gts fix","test":"jest","check":"npm-run-all check:gts check:tsc","clean":"gts clean","compile":"tsc -p tsconfig.build.json","check:gts":"gts check","check:tsc":"tsc --noEmit"},"_npmUser":{"name":"nex3","email":"nex342@gmail.com"},"repository":{"url":"git+https://github.com/sass/sync-message-port.git","type":"git"},"_npmVersion":"10.9.0","description":"A Node.js communication port that can pass messages synchronously between workers","directories":{},"_nodeVersion":"22.11.0","_hasShrinkwrap":false,"devDependencies":{"gts":"^6.0.2","jest":"^29.4.1","ts-jest":"^29.0.5","ts-node":"^10.2.1","typedoc":"^0.26.11","minipass":"7.1.2","typescript":"^5.0.2","@types/jest":"^29.4.0","@types/node":"^22.0.0","npm-run-all":"^4.1.5"},"_npmOperationalInternal":{"tmp":"tmp/sync-message-port_1.1.1_1730750132826_0.028641847195662873","host":"s3://npm-registry-packages"},"_cnpmcore_publish_time":"2024-11-04T19:55:33.033Z","publish_time":1730750133033,"_source_registry_name":"default","_cnpm_publish_time":1730750133033},"1.1.0":{"name":"sync-message-port","version":"1.1.0","description":"A Node.js communication port that can pass messages synchronously between workers","repository":{"type":"git","url":"git+https://github.com/sass/sync-message-port.git"},"author":{"name":"Google Inc."},"license":"MIT","exports":{"types":"./dist/lib/index.d.ts","default":"./dist/lib/index.js"},"main":"dist/lib/index.js","types":"dist/lib/index.d.ts","engines":{"node":">=16.0.0"},"scripts":{"check":"npm-run-all check:gts check:tsc","check:gts":"gts check","check:tsc":"tsc --noEmit","clean":"gts clean","compile":"tsc -p tsconfig.build.json","fix":"gts fix","test":"jest"},"devDependencies":{"@types/jest":"^29.4.0","@types/node":"^22.0.0","gts":"^6.0.2","jest":"^29.4.1","minipass":"7.1.2","npm-run-all":"^4.1.5","ts-jest":"^29.0.5","ts-node":"^10.2.1","typescript":"^5.0.2"},"_id":"sync-message-port@1.1.0","gitHead":"b9dd1c92f9e36fb8c99c3cae5e539e4871b94f46","bugs":{"url":"https://github.com/sass/sync-message-port/issues"},"homepage":"https://github.com/sass/sync-message-port#readme","_nodeVersion":"20.18.0","_npmVersion":"10.8.2","dist":{"shasum":"0132ff2669da7ddaa8401052ca7cd5c7e58f16a2","size":3508,"noattachment":false,"key":"/sync-message-port/-/sync-message-port-1.1.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/sync-message-port/download/sync-message-port-1.1.0.tgz"},"_npmUser":{"name":"nex3","email":"nex342@gmail.com"},"directories":{},"maintainers":[{"name":"nex3","email":"nex342@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/sync-message-port_1.1.0_1730502250744_0.06908267944131308"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2024-11-01T23:04:10.961Z","publish_time":1730502250961,"_source_registry_name":"default","_cnpm_publish_time":1730502250961},"1.0.0":{"name":"sync-message-port","version":"1.0.0","description":"A Node.js communication port that can pass messages synchronously between workers","repository":{"type":"git","url":"git+https://github.com/sass/sync-message-port.git"},"author":{"name":"Google Inc."},"license":"MIT","exports":{"types":"./dist/lib/index.d.ts","default":"./dist/lib/index.js"},"main":"dist/lib/index.js","types":"dist/lib/index.d.ts","engines":{"node":">=16.0.0"},"scripts":{"check":"npm-run-all check:gts check:tsc","check:gts":"gts check","check:tsc":"tsc --noEmit","clean":"gts clean","compile":"tsc -p tsconfig.build.json","fix":"gts fix","test":"jest"},"devDependencies":{"@types/jest":"^29.4.0","@types/node":"^22.0.0","gts":"^6.0.2","jest":"^29.4.1","minipass":"7.1.2","npm-run-all":"^4.1.5","ts-jest":"^29.0.5","ts-node":"^10.2.1","typescript":"^5.0.2"},"_id":"sync-message-port@1.0.0","gitHead":"13e5d5ca743384d266df815766de9285c25110ab","bugs":{"url":"https://github.com/sass/sync-message-port/issues"},"homepage":"https://github.com/sass/sync-message-port#readme","_nodeVersion":"22.2.0","_npmVersion":"10.7.0","dist":{"shasum":"22f66d17a2ca12510c862eeed7b2a0f7ac2e1ca0","size":18643,"noattachment":false,"key":"/sync-message-port/-/sync-message-port-1.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/sync-message-port/download/sync-message-port-1.0.0.tgz"},"_npmUser":{"name":"nex3","email":"nex342@gmail.com"},"directories":{},"maintainers":[{"name":"nex3","email":"nex342@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/sync-message-port_1.0.0_1730241920416_0.2298782986730925"},"_hasShrinkwrap":false,"_cnpmcore_publish_time":"2024-10-29T22:45:20.662Z","publish_time":1730241920662,"_source_registry_name":"default","_cnpm_publish_time":1730241920662}},"readme":"# `sync-message-port`\n\nThis package exposes a utility class that encapsulates the ability to send and\nreceive messages with arbitrary structure across Node.js worker boundaries. It\ncan be used as the building block for synchronous versions of APIs that are\ntraditionally only available asynchronously in the Node.js ecosystem by running\nthe asynchronous APIs in a worker and accessing their results synchronously from\nthe main thread.\n\nSee [the `sync-child-process` package] for an example of `sync-message-port` in\naction.\n\n[the `sync-child-process` package]: https://github.com/sass/sync-child-process\n\n[**API Docs**]\n\n[**API Docs**]: https://sass.github.io/sync-message-port/classes/SyncMessagePort.html\n\n## Usage\n\n1. Use [`SyncMessagePort.createChannel()`] to create a message channel that's\n   set up to be compatible with `SyncMessagePort`s. A normal `MessageChannel`\n   won't work!\n\n2. You can send this `MessageChannel`'s ports across worker boundaries just like\n   any other `MessagePort`. Send one to the worker you want to communicate with\n   synchronously.\n\n3. Once you're ready to start sending and receiving messages, wrap *both* ports\n   in [`new SyncMessagePort()`], even if one is only ever going to be sending\n   messages and not receiving them.\n\n4. Use [`SyncMessagePort.postMessage()`] to send messages and\n   `SyncMessagePort.receiveMessage()` to receive them synchronously.\n\n[`SyncMessagePort.createChannel()`]: https://sass.github.io/sync-message-port/classes/SyncMessagePort.html#createChannel\n[`new SyncMessagePort()`]: https://sass.github.io/sync-message-port/classes/SyncMessagePort.html#constructor\n[`SyncMessagePort.postMessage()`]: https://sass.github.io/sync-message-port/classes/SyncMessagePort.html#postMessage\n[`SyncMessagePort.receiveMessage()`]: https://sass.github.io/sync-message-port/classes/SyncMessagePort.html#receiveMessage\n\n```js\nimport {Worker} from 'node:worker_threads';\nimport {SyncMessagePort} from 'sync-message-port;\n// or\n// const {SyncMessagePort} = require('sync-message-port');\n\n// Channels must be created using this function. A MessageChannel created by\n// hand won't work.\nconst channel = SyncMessagePort.createChannel();\nconst localPort = new SyncMessagePort(channel.port1);\n\nconst worker = new Worker(`\n  import {workerData} = require('node:worker_threads');\n  import {SyncMessagePort} from 'sync-message-port';\n\n  const remotePort = new SyncMessagePort(workerData.port);\n\n  setTimeout(() => {\n    remotePort.postMessage(\"hello from worker!\");\n  }, 2000);\n`, {\n  workerData: {port: channel.port2},\n  transferList: [channel.port2],\n  eval: true,\n});\n\n// Note that because workers report errors asynchronously, this won't report an\n// error if the worker fails to load because the main thread will be\n// synchronously waiting for its first message.\nworker.on('error', console.error);\n\nconsole.log(localPort.receiveMessage());\n```\n\n## Why synchrony?\n\nAlthough JavaScript in general and Node.js in particular are typically designed\nto embrace asynchrony, there are a number of reasons why a synchronous API may\nbe preferable or even necessary.\n\n### No a/synchronous polymorphism\n\nAlthough `async`/`await` and the `Promise` API has substantially improved the\nusability of writing asynchronous code in JavaScript, it doesn't address one\ncore issue: there's no way to write code that's *polymorphic* over asynchrony.\nPut in simpler terms, there's no language-level way to write a complex function\nthat takes a callback and to run that functions synchronously if the callback is\nsynchronous and asynchronously otherwise. The only option is to write the\nfunction twice.\n\nThis poses a real, practical problem when interacting with libraries. Suppose\nyou have a library that takes a callback option—for example, an HTML\nsanitization library that takes a callback to determine how to handle a given\n`<a href=\"...\">`. The library doesn't need to do any IO itself, so it's written\nsynchronously. But what if your callback wants to make an HTTP request to\ndetermine how to handle a tag? You're stuck unless you can make that request\nsynchronous. This library makes that possible.\n\n### Performance considerations\n\nAsynchrony is generally more performant in situations where there's a large\namount of concurrent IO happening. But when performance is CPU-bound, it's often\nsubstantially worse due to the overhead of bouncing back and forth between the\nevent loop and user code.\n\nAs a real-world example, the Sass compiler API supports both synchronous and\nasynchronous code paths to work around the polymorphism problem described above.\nThe logic of these paths is exactly the same—the only difference is that the\nasynchronous path's functions all return `Promise`s instead of synchronous\nvalues. Compiling with the asynchronous path often takes 2-3x longer than with\nthe synchronous path. This means that being able to run plugins synchronously\ncan provide a substantial overall performance gain, even if the plugins\nthemselves lose the benefit of concurrency.\n\n## How does it work?\n\nThis uses [`Atomics`] and [`SharedArrayBuffer`] under the covers to signal\nacross threads when messages are available, and\n[`worker_threads.receiveMessageOnPort()`] to actually retrieve messages.\n\n[`Atomics`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics\n[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer\n[`worker_threads.receiveMessageOnPort()`]: https://nodejs.org/api/worker_threads.html#workerreceivemessageonportport\n\n### Can I use this in a browser?\n\nUnfortunately, no. Browsers don't support any equivalent of\n`worker_threads.receiveMessageOnPort()`, even within worker threads. You could\nmake a similar package that can transmit only binary data (or data that can be\nencoded as binary) using only `SharedArrayBuffer`, but that's outside the scope\nof this package.\n\nDisclaimer: this is not an official Google product.\n","_attachments":{},"homepage":"https://github.com/sass/sync-message-port#readme","bugs":{"url":"https://github.com/sass/sync-message-port/issues"},"license":"MIT"}