{"_id":"@bluehotdog/reworker","_rev":"3-bb768e485080f393b774cc81349e0e8b","name":"@bluehotdog/reworker","dist-tags":{"latest":"0.0.3"},"versions":{"0.0.1":{"name":"@bluehotdog/reworker","version":"0.0.1","keywords":["rescript","chrome-extension","webworker","serviceworker","wxt","browser-extension","message-passing","messaging","gadt","type-safe","chunking","framework-agnostic","zero-dependencies"],"author":{"name":"BlueHotDog"},"license":"MIT","_id":"@bluehotdog/reworker@0.0.1","maintainers":[{"name":"bluehotdog","email":"dannifriedland@gmail.com"}],"homepage":"https://github.com/BlueHotDog/reworker#readme","bugs":{"url":"https://github.com/BlueHotDog/reworker/issues"},"dist":{"shasum":"c167d78b32ab0c7b082033180dae7b2520be7ff4","tarball":"https://registry.npmjs.org/@bluehotdog/reworker/-/reworker-0.0.1.tgz","fileCount":22,"integrity":"sha512-+0OL4g18DilSMgmX6VySZVQmXKSIPZdwEOcKge+xVQM4sw0hO+4rXzsFDJvVoUhAPclO4QRdcimtMvtnn8xTBw==","signatures":[{"sig":"MEYCIQCGbJZc+l1KZElkQlqDupVtfak10VQPdwh9aF9DFTJqhwIhAJ7I3ZefeLigTqUr4WkfZNgOAKY9YuYyJwYECXPG6tL4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":67432},"engines":{"node":">=18.0.0"},"gitHead":"62013493c6d1463f010b3af81398514ae449d74b","_npmUser":{"name":"bluehotdog","email":"dannifriedland@gmail.com"},"repository":{"url":"git+https://github.com/BlueHotDog/reworker.git","type":"git"},"_npmVersion":"11.6.0","description":"Type-safe, chunked message passing for WebWorkers, ServiceWorkers, and browser extensions using GADTs with zero runtime dependencies","directories":{},"sideEffects":false,"_nodeVersion":"23.10.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rescript":"^12.0.0-beta.12"},"peerDependencies":{"rescript":"^12.0.0-beta.12"},"_npmOperationalInternal":{"tmp":"tmp/reworker_0.0.1_1758659244250_0.8926140558187172","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@bluehotdog/reworker","version":"0.0.2","keywords":["rescript","chrome-extension","webworker","serviceworker","wxt","browser-extension","message-passing","messaging","gadt","type-safe","chunking","framework-agnostic","zero-dependencies"],"author":{"name":"BlueHotDog"},"license":"MIT","_id":"@bluehotdog/reworker@0.0.2","maintainers":[{"name":"bluehotdog","email":"dannifriedland@gmail.com"}],"homepage":"https://github.com/BlueHotDog/reworker#readme","bugs":{"url":"https://github.com/BlueHotDog/reworker/issues"},"dist":{"shasum":"2cdabc6cd442c0210c32c9cfa90e446a222ae967","tarball":"https://registry.npmjs.org/@bluehotdog/reworker/-/reworker-0.0.2.tgz","fileCount":22,"integrity":"sha512-qL8bsH0xBZug7BlpGKARCkF4iPVi+w5n9NG6qkZ3XhFHMNV0v4p1TtV43f6mcOxzmNikL+1BwK8P6VsRUBHfdA==","signatures":[{"sig":"MEUCIGec0HCSQor3LrqLHWhoeEIsGGc6Rl1a0HGt8zvt1q0ZAiEA6rogfk3jtbxSg6nAxfwooGd6Wz9fs9fHfUZQsW+pA2c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":67114},"engines":{"node":">=18.0.0"},"gitHead":"85494fd07556d4f26a99d2b98169a87bfd7c9a7c","_npmUser":{"name":"bluehotdog","email":"dannifriedland@gmail.com"},"repository":{"url":"git+https://github.com/BlueHotDog/reworker.git","type":"git"},"_npmVersion":"11.6.0","description":"Type-safe, chunked message passing for WebWorkers, ServiceWorkers, and browser extensions using GADTs with zero runtime dependencies","directories":{},"sideEffects":false,"_nodeVersion":"23.10.0","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"rescript":"^12.0.0-beta.12"},"peerDependencies":{"rescript":"^12.0.0-beta.12"},"_npmOperationalInternal":{"tmp":"tmp/reworker_0.0.2_1758659528246_0.7672278425111039","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@bluehotdog/reworker","version":"0.0.3","description":"Type-safe, chunked message passing for WebWorkers, ServiceWorkers, and browser extensions using GADTs with zero runtime dependencies","keywords":["rescript","chrome-extension","webworker","serviceworker","wxt","browser-extension","message-passing","messaging","gadt","type-safe","chunking","framework-agnostic","zero-dependencies"],"author":{"name":"BlueHotDog"},"license":"MIT","homepage":"https://github.com/BlueHotDog/reworker#readme","repository":{"type":"git","url":"git+https://github.com/BlueHotDog/reworker.git"},"bugs":{"url":"https://github.com/BlueHotDog/reworker/issues"},"engines":{"node":">=20.11.0"},"sideEffects":false,"peerDependencies":{"rescript":"^12.0.0"},"devDependencies":{"esbuild":"^0.28.1","playwright":"^1.62.1","rescript":"^12.3.0"},"publishConfig":{"access":"public"},"_id":"@bluehotdog/reworker@0.0.3","gitHead":"9d6807a51ec5616e9e31bb6ab93727476b5faa5c","_nodeVersion":"23.10.0","_npmVersion":"11.6.0","dist":{"integrity":"sha512-76cXAHyAv9l1GQKr02VVMQ9aNKH2wuYHwb0eRtmFAXse92MnwU7Jxr5jXtELSVOSqYOHc24vSDJszrbKPhAvYQ==","shasum":"252d7146f17152cd35af639ef7152c019b2a054d","tarball":"https://registry.npmjs.org/@bluehotdog/reworker/-/reworker-0.0.3.tgz","fileCount":31,"unpackedSize":50015,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDeDcL/QGXjskhCvOY5a/LpOpssYU8szAsiLX6RJO3jqAIhAM69RFmEiXsTxHmlE5wVsq0Ggb/WYIxiYpRYKu53up5T"}]},"_npmUser":{"name":"bluehotdog","email":"danni@thedanni.com"},"directories":{},"maintainers":[{"name":"bluehotdog","email":"danni@thedanni.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/reworker_0.0.3_1786475370112_0.2534133366168607"},"_hasShrinkwrap":false}},"time":{"created":"2025-09-23T20:27:24.194Z","modified":"2026-08-11T19:09:30.427Z","0.0.1":"2025-09-23T20:27:24.451Z","0.0.2":"2025-09-23T20:32:08.443Z","0.0.3":"2026-08-11T19:09:30.281Z"},"bugs":{"url":"https://github.com/BlueHotDog/reworker/issues"},"author":{"name":"BlueHotDog"},"license":"MIT","homepage":"https://github.com/BlueHotDog/reworker#readme","keywords":["rescript","chrome-extension","webworker","serviceworker","wxt","browser-extension","message-passing","messaging","gadt","type-safe","chunking","framework-agnostic","zero-dependencies"],"repository":{"type":"git","url":"git+https://github.com/BlueHotDog/reworker.git"},"description":"Type-safe, chunked message passing for WebWorkers, ServiceWorkers, and browser extensions using GADTs with zero runtime dependencies","maintainers":[{"name":"bluehotdog","email":"danni@thedanni.com"}],"readme":"# ReWorker\n\nType-safe message passing for Chrome extensions with automatic chunking. Zero dependencies.\n\n## Install\n\n```bash\nnpm install @bluehotdog/reworker\n```\n\n## Usage\n\nDefine messages with GADTs:\n```rescript\ntype Types.message<_> +=\n  | GetUser(string): Types.message<User.t>\n  | SaveData(data): Types.message<Result.t<unit, string>>\n```\n\nSend messages:\n```rescript\nmodule Runtime = Runtime.Make(WxtRuntime)\n\n// Promise-based API\nRuntime.sendMessage(GetUser(\"123\"))->Promise.then(user => Console.log(user))\n\n// With async/await\nlet user = await Runtime.sendMessage(GetUser(\"123\"))\nConsole.log(user)\n\n// Fire-and-forget\nRuntime.cast(SaveData(userData))\n```\n\nHandle messages:\n```rescript\nlet handler = (msg, _sender) => {\n  switch msg {\n  | GetUser(id) => Response.now(Database.getUser(id))\n  | SaveData(data) => Response.now(Database.save(data))\n  | _ => Response.none\n  }\n}\nRuntime.OnMessage.addListener(handler)\n```\n\nBindings passed to `Runtime.Make` provide an ordered duplex transport. Reworker owns request correlation, timeouts, remote errors, casts, and chunking:\n\n```rescript\nmodule type MyBindings = {\n  type sender\n  let requestTimeoutMs: int\n  let postMessage: 'a => result<unit, string>\n  module OnMessage: {\n    let addListener: (('a, sender) => unit) => unit\n    let removeListener: (('a, sender) => unit) => unit\n  }\n  module OnClose: {\n    let addListener: (string => unit) => unit\n  }\n  let isOpen: unit => bool\n  let close: unit => unit\n}\n```\n\n`postMessage` must return `Error` when structured clone fails. `OnClose` must fire when the remote endpoint becomes unavailable so pending requests reject immediately.\n\n## Cross-Origin Iframes\n\n`WindowTransport` bootstraps a cross-origin iframe with `window.postMessage`, validates the exact origin and source window, and transfers a `MessagePort`. All Reworker messages then use that port.\n\nCreate the parent binding with the iframe's non-null `contentWindow` and an explicit origin:\n\n```rescript\nmodule FrameBindings = WindowTransport.Parent.Make({\n  type targetWindow = Webapi.Dom.Window.t\n  type loadEvent = Webapi.Dom.Event.t\n  let targetOrigin = \"https://frame.example.com\"\n  let targetWindow = () => iframe->contentWindow\n  let addLoadListener = listener => iframe->addEventListener(\"load\", listener)\n  let removeLoadListener = listener => iframe->removeEventListener(\"load\", listener)\n  let requestTimeoutMs = 5000\n})\n\nmodule FrameRuntime = Runtime.Make(FrameBindings)\n\nawait FrameBindings.connect()\nlet title = await FrameRuntime.sendMessage(GetPageTitle)\n```\n\nInstall the cooperating endpoint in the iframe before the parent connects:\n\n```rescript\nmodule ParentBindings = WindowTransport.Child.Make({\n  type parentWindow = Webapi.Dom.Window.t\n  let parentWindow = Webapi.Dom.window->Webapi.Dom.Window.parent\n  let parentOrigin = \"https://parent.example.com\"\n  let requestTimeoutMs = 5000\n})\n\nmodule ParentRuntime = Runtime.Make(ParentBindings)\n\nParentRuntime.OnMessage.addListener(handler)\nParentBindings.listen()->Result.getOrThrow\n```\n\nBoth origins are mandatory and `\"*\"` is rejected. The parent binding reconnects with a new port after iframe navigation. Call `Runtime.close()` to reject pending requests and tear down the endpoint.\n\nBuild a nice wrapper:\nIn your background.res:\n```rescript\nlet getUser = (userid)=> Runtime.sendMessage(GetUser(userid))\n```\nThis allows callers to just do `let user = await Background.getUser(\"123\")`\nSimple. Clear.\n\n## Features\n\n- **Type safety**: GADTs ensure request/response type matching\n- **Promise-based**: Native Manifest V3 promise support with async/await\n- **Auto-chunking**: Handles Chrome's 64MB message limits transparently\n- **Framework agnostic**: Works with any Chrome extension framework\n- **Zero deps**: Pure ReScript library\n\n## Requirements\n\n- ReScript ^12.0.0\n- Manifest V3 extensions only\n\n## License\n\nMIT\n\n## Thanks\n\n[@diogomqbm](https://github.com/diogomqbm) for foundational work.\n","readmeFilename":"README.md"}