{"_id":"@casfa/port-rpc","name":"@casfa/port-rpc","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@casfa/port-rpc","version":"0.1.0","description":"Type-safe request/response RPC over MessagePort with timeout, Transferable auto-extraction, and namespace proxying","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"bun":"./src/index.ts","types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"bun ../../scripts/build-pkg.ts","test":"bun run test:unit","test:unit":"bun test src/","typecheck":"tsc --noEmit","lint":"biome check .","lint:fix":"biome check --write .","check":"tsc --noEmit && biome check .","prepublishOnly":"bun run build"},"dependencies":{},"devDependencies":{"typescript":"^5.8.0"},"publishConfig":{"access":"public"},"gitHead":"9a8e9e662ad7ccc16658af6525cb2082e1d78eb9","_id":"@casfa/port-rpc@0.1.0","_nodeVersion":"25.6.1","_npmVersion":"11.9.0","dist":{"integrity":"sha512-Ls9poTKYQLJKWmtBNQDghz27MBHzoZuyAFUXWBgZMs6XPfZ+NjcoRVN+q/7dgb6aGXucnmk4f2TNfzXh9c/XnA==","shasum":"83a16f61382ac5732a787abfaf4109c75096df11","tarball":"https://registry.npmjs.org/@casfa/port-rpc/-/port-rpc-0.1.0.tgz","fileCount":14,"unpackedSize":29082,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEV2dAofSI53nAPyW7Lt9tL7AQsPeVxUM/WUCGKXmwDbAiBVNZLj4QmI3WW40q6jaQTBd2syL4CsuYKQkpYtmJmFkA=="}]},"_npmUser":{"name":"shazhou.ww","email":"shazhou.ww@gmail.com"},"directories":{},"maintainers":[{"name":"shazhou.ww","email":"shazhou.ww@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/port-rpc_0.1.0_1771817106474_0.1084110630223829"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-23T03:25:06.378Z","0.1.0":"2026-02-23T03:25:06.628Z","modified":"2026-02-23T03:25:06.853Z"},"maintainers":[{"name":"shazhou.ww","email":"shazhou.ww@gmail.com"}],"description":"Type-safe request/response RPC over MessagePort with timeout, Transferable auto-extraction, and namespace proxying","readme":"# @casfa/port-rpc\n\nType-safe request/response RPC over `MessagePort` with timeout, automatic `Transferable` extraction, and namespace proxying.\n\nDesigned for **Main Thread ↔ Service Worker** communication but works with any `MessagePort`-based channel (Worker, iframe, etc.).\n\n## Features\n\n- **Request/response matching** — auto-incrementing `id` with pending-map resolution\n- **Timeout** — configurable per-client, defaults to 30 s\n- **Transferable auto-extraction** — `ArrayBuffer` / `Uint8Array` args are automatically transferred (zero-copy)\n- **Namespace proxy** — `Proxy`-based method routing for typed remote APIs\n- **Handler utilities** — `respond()`, `respondError()`, `dispatchNamespaceRPC()` for the receiver side\n- **Zero dependencies** — pure TypeScript, no runtime deps\n\n## Usage\n\n### Caller side (main thread)\n\n```ts\nimport { createRPC, createNamespaceProxy } from \"@casfa/port-rpc\";\n\nconst { port1, port2 } = new MessageChannel();\nport1.start();\n\n// Send port2 to the service worker\nsw.postMessage({ type: \"connect\" }, [port2]);\n\nconst rpc = createRPC(port1, { timeoutMs: 10_000 });\n\n// Type-safe namespace proxy\ntype MathService = {\n  add(a: number, b: number): Promise<number>;\n  multiply(a: number, b: number): Promise<number>;\n};\n\nconst math = createNamespaceProxy<MathService>(rpc, \"math\");\nconst sum = await math.add(1, 2); // → 3\n```\n\n### Handler side (service worker)\n\n```ts\nimport { respond, respondError, dispatchNamespaceRPC } from \"@casfa/port-rpc\";\n\nconst mathService = {\n  add: (a: number, b: number) => a + b,\n  multiply: (a: number, b: number) => a * b,\n};\n\nport.onmessage = async (e) => {\n  const msg = e.data;\n  switch (msg.type) {\n    case \"rpc\":\n      await dispatchNamespaceRPC({\n        target: mathService,\n        method: msg.method,\n        args: msg.args,\n        port,\n        id: msg.id,\n      });\n      break;\n    case \"ping\":\n      respond(port, msg.id, \"pong\");\n      break;\n  }\n};\n```\n\n## API\n\n### `createRPC<TMsg>(port, options?)`\n\nCreate an RPC client. Returns `RPCFn<TMsg>` — a function that sends a message and returns a `Promise<unknown>`.\n\n### `createNamespaceProxy<T>(rpc, namespace)`\n\nCreate a `Proxy` that routes method calls through RPC as `{ type: \"rpc\", target, method, args }` messages.\n\n### `respond(port, id, result, transfers?)`\n\nSend a successful RPC response.\n\n### `respondError(port, id, code, err)`\n\nSend an error RPC response.\n\n### `dispatchNamespaceRPC(opts)`\n\nInvoke `target[method](...args)`, await the result, and send the response. Auto-extracts `Transferable` buffers from `{ ok: true, data: Uint8Array }` result patterns.\n\n### `extractTransferables(args)`\n\nExtract `ArrayBuffer` / `Uint8Array.buffer` from an args array.\n\n## Testing\n\n```sh\nbun test src/\n```\n","readmeFilename":"README.md","_rev":"1-0f4bebb428e6bb45c71c0dc7d0acdd17"}