{"id":19066504,"url":"https://github.com/geut/nanomessage-rpc","last_synced_at":"2025-06-14T21:06:30.390Z","repository":{"id":57307987,"uuid":"246697207","full_name":"geut/nanomessage-rpc","owner":"geut","description":"Tiny :hatched_chick: RPC on top of nanomessage","archived":false,"fork":false,"pushed_at":"2022-10-23T13:52:51.000Z","size":2423,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-28T12:40:41.618Z","etag":null,"topics":["nanomessage","rpc"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/geut.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-03-11T23:02:30.000Z","updated_at":"2022-12-09T11:14:31.000Z","dependencies_parsed_at":"2022-09-12T11:44:14.083Z","dependency_job_id":null,"html_url":"https://github.com/geut/nanomessage-rpc","commit_stats":null,"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/geut/nanomessage-rpc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geut%2Fnanomessage-rpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geut%2Fnanomessage-rpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geut%2Fnanomessage-rpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geut%2Fnanomessage-rpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/geut","download_url":"https://codeload.github.com/geut/nanomessage-rpc/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/geut%2Fnanomessage-rpc/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259884468,"owners_count":22926444,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["nanomessage","rpc"],"created_at":"2024-11-09T00:57:05.715Z","updated_at":"2025-06-14T21:06:30.363Z","avatar_url":"https://github.com/geut.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nanomessage-rpc (aka nrpc)\n\n![Test Status](https://github.com/geut/nanomessage-rpc/actions/workflows/test.yml/badge.svg)\n[![Coverage](https://raw.githubusercontent.com/geut/nanomessage-rpc/gh-pages/badges/coverage.svg?raw=true)](https://geut.github.io/nanomessage-rpc/)\n[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n[![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)\n\n\u003e Tiny :hatched_chick: RPC on top of nanomessage\n\n## \u003ca name=\"install\"\u003e\u003c/a\u003e Install\n\n```\n$ npm install nanomessage-rpc\n```\n\n## \u003ca name=\"usage\"\u003e\u003c/a\u003e Usage\n\n```javascript\nimport { NanomessageRPC } from 'nanomessage-rpc'\n\n;(async () =\u003e {\n  const rpc = new NanomessageRPC({\n    send(buf) {\n      // implement how to send the message\n    },\n    subscribe(next) {\n      // subscribe for incoming messages\n    }\n  })\n\n  await rpc\n    .action('sum', ({ a, b }) =\u003e a + b)\n    .action('subtract', ({ a, b }) =\u003e a - b)\n    .open()\n\n  // from the other rpc socket side\n  const result = await rpc.call('sum', { a: 2, b: 2 }) // 4\n})()\n```\n\nWe provide a socket helper:\n\n```javascript\nimport { NanomessageRPC, useSocket } from 'nanomessage-rpc'\n\n;(async () =\u003e {\n  const rpc = new NanomessageRPC({ ...useSocket(socket) })\n\n  // ...\n})()\n```\n\nAlso it has an [EventEmitter2](https://github.com/EventEmitter2/EventEmitter2) instance to emit events through the socket.\n\n```javascript\n;(async () =\u003e {\n  const rpc = new NanomessageRPC(socket, opts)\n\n  await rpc.open()\n\n  rpc.on('ping', () =\u003e {\n    console.log('ping')\n  })\n\n  // from the other rpc socket side\n  const result = await rpc.emitAsync('ping') // 4\n})()\n```\n\nAnd it has support for [nanoerror](https://github.com/geut/nanoerror).\n\n```javascript\nimport { NanomessageRPC } from 'nanomessage-rpc'\nimport nanoerror from 'nanoerror'\n\nconst BAD_REQUEST = nanoerror('BAD_REQUEST', 'the request %s is wrong')\n\n;(async () =\u003e {\n  const rpc = new NanomessageRPC(socket, opts)\n\n  await rpc\n    .action('badrequest', () =\u003e {\n      throw new BAD_REQUEST(1)\n    })\n    .open()\n\n  // from the other rpc socket side\n  try {\n    const result = await rpc.call('badrequest', { a: 2, b: 2 }) // 4\n  } catch (err) {\n    // will throw BAD_REQUEST: the request 1 is wrong\n  }\n})()\n```\n\n## API\n\n#### `const rpc = new NanomessageRPC(options)`\n\nCreate a new nanomessage-rpc.\n\nOptions include:\n\n- `send: (buf: Buffer) =\u003e (Promise|undefined)`: Define a hook to specify how to send the data. `Required`.\n- `subscribe: (next: function) =\u003e UnsubscribeFunction`: Define a handler to listen for incoming messages.\n- `timeout: 10000`: Time (ms) to wait for the response of a request.\n- `concurrency: { incoming: 256, outgoing: 256 }`: Defines how many requests do you want to run in concurrent.\n- `valueEncoding: msgpackr`: Defines an [abstract-encoding](https://github.com/mafintosh/abstract-encoding) to encode/decode messages in nanomessage.\n\n#### `rpc.open() =\u003e Promise`\n\nOpens nanomessage and start listening for incoming data.\n\n#### `rpc.close() =\u003e Promise`\n\nCloses nanomessage and unsubscribe from incoming data.\n\n#### `rpc.action(actionName, handler)`\n\nDefines a rpc action and handler for incoming requests.\n\n- `actionName: string`: Name of the action.\n- `handler: function`: Handler, could be `async`.\n\n#### `rpc.actions(actions)`\n\nShortcut to define multiple actions.\n\n- `actions: { actionName: handler, ... }`: List of actions.\n\n#### `rpc.call(actionName, data, [opts]) =\u003e Promise\u003cResponse\u003e`\n\nCall an action an wait for the response.\n\n- `actionName: string`: Action name.\n- `data: (Buffer|Object|String)`: Request data.\n- `opts.timeout: number`: Define a custom timeout for the current request.\n- `opts.signal: AbortSignal`: Set an abort signal object to cancel the request.\n\n### Events\n\n#### `rpc.emit(eventName, data, [opts])`\n\nEmit an event in the remote side.\n\n- `actionName: string`: Event name.\n- `data: (Buffer|Object|String)`: Event data.\n\n#### `rpc.emitAsync(eventName, data, [opts]) -\u003e Promise`\n\n- `actionName: string`: Event name.\n- `data: (Buffer|Object|String)`: Event data.\n- `opts.timeout: number`: Define a custom timeout for the current request. Use timeout = 0 to not wait for a response.\n- `opts.signal: AbortSignal`: Set an abort signal object to cancel the request.\n\nEmit an event in the remote side and wait for a response.\n\n#### `rpc.on(eventName, handler) =\u003e unsubscribe`\n\nSubscribe to a RPC event.\n\nReturns an unsubscribe method.\n\n#### `rpc.once(eventName)`\n\nSubscribe to a RPC event only once. It will be unsubscribed after the first event.\n\n#### `rpc.waitFor(eventName) -\u003e Promise`\n\nSubscribe to a RPC event only once and return a `Promise` to wait for the event.\n\n\u003e Alternative: NanomessageRPC.once(rpc, eventName)\n\n#### `rpc.off(eventName)`\n\nRemove a RPC event subscription.\n```\n\n### System events\n\nYou can listen for internal events:\n\n- `on('nrpc.open', () =\u003e {})`: When the RPC was opened.\n- `on('nrpc.opening', () =\u003e {})`: When the RPC is opening.\n- `on('nrpc.close', () =\u003e {})`: When the RPC was closed.\n- `on('nrpc.closing', () =\u003e {})`: When the RPC is closing.\n- `on('nrpc.message', (message, info: RequestInfo) =\u003e {})`: When it comes a new message.\n- `on('nrpc.error-message', (err, info: RequestInfo) =\u003e {})`: When the internal RPC gets an error message.\n- `on('nrpc.error-subscribe', (err) =\u003e {})`: When the internal RPC gets an error subscription.\n- `on('nrpc.error-socket', (err) =\u003e {})`: When the internal RPC gets an error socket.\n- `on('nrpc.error*', (err) =\u003e {})`: Listen for all RPC errors.\n\n## \u003ca name=\"issues\"\u003e\u003c/a\u003e Issues\n\n:bug: If you found an issue we encourage you to report it on [github](https://github.com/geut/nanomessage-rpc/issues). Please specify your OS and the actions to reproduce it.\n\n## \u003ca name=\"contribute\"\u003e\u003c/a\u003e Contributing\n\n:busts_in_silhouette: Ideas and contributions to the project are welcome. You must follow this [guideline](https://github.com/geut/nanomessage-rpc/blob/main/CONTRIBUTING.md).\n\n## License\n\nMIT © A [**GEUT**](http://geutstudio.com/) project\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeut%2Fnanomessage-rpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeut%2Fnanomessage-rpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeut%2Fnanomessage-rpc/lists"}