{"id":13603095,"url":"https://github.com/timonson/gentle_rpc","last_synced_at":"2026-05-13T13:01:03.777Z","repository":{"id":43204495,"uuid":"245918803","full_name":"timonson/gentle_rpc","owner":"timonson","description":"JSON-RPC 2.0 library with HTTP and WebSockets support for deno and the browser","archived":false,"fork":false,"pushed_at":"2024-05-18T17:27:46.000Z","size":233,"stargazers_count":45,"open_issues_count":2,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-10-30T01:22:30.620Z","etag":null,"topics":["browser","deno","esmodules","fetch","javascript","json-rpc2","rpc","typescript","websocket","websockets"],"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/timonson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-09T01:34:30.000Z","updated_at":"2024-05-18T17:27:49.000Z","dependencies_parsed_at":"2024-06-21T16:48:03.183Z","dependency_job_id":"68f20b83-c05a-427b-a533-22b63b19738c","html_url":"https://github.com/timonson/gentle_rpc","commit_stats":{"total_commits":209,"total_committers":6,"mean_commits":"34.833333333333336","dds":"0.10526315789473684","last_synced_commit":"7eb9df3fdc4035346c534845ad92371e0a5b92ca"},"previous_names":["timonson/gentlerpc"],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timonson%2Fgentle_rpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timonson%2Fgentle_rpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timonson%2Fgentle_rpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timonson%2Fgentle_rpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timonson","download_url":"https://codeload.github.com/timonson/gentle_rpc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238147601,"owners_count":19424291,"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":["browser","deno","esmodules","fetch","javascript","json-rpc2","rpc","typescript","websocket","websockets"],"created_at":"2024-08-01T18:01:50.225Z","updated_at":"2025-10-25T13:31:17.996Z","avatar_url":"https://github.com/timonson.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","browser","Modules"],"sub_categories":["Web utils"],"readme":"# gentle_rpc\n\nJSON-RPC 2.0 library (server and client) with HTTP and WebSockets support for\n[deno](https://github.com/denoland/deno) and the browser.\n\n### Important Notice\n\nThe **gentle_rpc** library is no longer maintained. Please switch to our new and\nimproved RPC library, **schicksal**, available at\n[schicksal on GitHub](https://github.com/Zaubrik/schicksal).\n\n## Server\n\n### respond\n\nTakes `Methods`, `ServerRequest` and `Options`. Look\n[here](https://github.com/timonson/gentle_rpc/blob/master/server/response.ts)\nfor more information about `Options`.\n\n```typescript\nimport { serve } from \"https://deno.land/std@0.117.0/http/server.ts\";\nimport { respond } from \"https://deno.land/x/gentle_rpc/mod.ts\";\n\nconst rpcMethods = {\n  sayHello: ([w]: [string]) =\u003e `Hello ${w}`,\n  callNamedParameters: ({ a, b, c }: { a: number; b: number; c: string }) =\u003e\n    `${c} ${a * b}`,\n  animalsMakeNoise: (noise: string[]) =\u003e\n    noise.map((el) =\u003e el.toUpperCase()).join(\" \"),\n};\n\nserve((req) =\u003e respond(rpcMethods, req), { addr: \":8000\" });\n\nconsole.log(\"Listening on http://localhost:8000\");\n```\n\n#### CustomError\n\nThrow a `CustomError` to send a server-defined error response.\n\n```typescript\nimport { CustomError, respond } from \"https://deno.land/x/gentle_rpc/mod.ts\";\n\n//..\nawait respond(\n  {\n    throwError: () =\u003e {\n      throw new CustomError(\n        -32040, // the JSON-RPC error code. Note, must be -32040 to -32099\n        \"An error occurred\", // the error message, a short sentence\n        { details: \"...\" }, // optional additional details, can be any `JsonValue`\n      );\n    },\n  },\n  req,\n);\n//..\n```\n\n## Client\n\n#### createRemote\n\nTakes a `Resource` for HTTP or a `WebSocket` for WebSockets and returns\n`Remote`.\n\n```typescript\nimport { createRemote } from \"https://deno.land/x/gentle_rpc/mod.ts\";\n// Or import directly into the browser with:\nimport { createRemote } from \"https://cdn.jsdelivr.net/gh/timonson/gentle_rpc@v3.3/client/dist/remote.js\";\n\n// HTTP:\nconst remote = createRemote(\"http://0.0.0.0:8000\");\n\n// WebSocket:\nconst remote = await createRemote(new WebSocket(\"ws://0.0.0.0:8000\"));\n```\n\n### HTTP\n\n#### call\n\nTakes a string and an `Array\u003cJsonValue\u003e` or `Record\u003cstring, JsonValue\u003e` object\nand returns `Promise\u003cJsonValue\u003e`.\n\n```typescript\nconst greeting = await remote.call(\"sayHello\", [\"World\"]);\n// Hello World\n\nconst namedParams = await remote.call(\"callNamedParameters\", {\n  a: 5,\n  b: 10,\n  c: \"result:\",\n});\n// result: 50\n```\n\n##### notification\n\nUsing the option `{ isNotification: true }` will retun `Promise\u003cundefined\u003e`.\n\n```typescript\nconst notification = await remote.call(\"sayHello\", [\"World\"], {\n  isNotification: true,\n});\n// undefined\n```\n\n##### jwt\n\nAdding the option `{jwt: string}` will set the `Authorization` header to\n`` `Bearer ${jwt}` ``.\n\n```typescript\nconst user = await remote.call(\"login\", undefined, { jwt });\n// Bob\n```\n\n#### batch\n\n```typescript\nconst noise1 = await remote.batch([\n  {\n    animalsMakeNoise: [\n      [\"miaaow\"],\n      [\"wuuuufu\", \"wuuuufu\"],\n      [\"iaaaiaia\", \"iaaaiaia\", \"iaaaiaia\"],\n      [\"fiiiiire\"],\n    ],\n    sayHello: [[\"World\"], undefined, [\"World\"]],\n  },\n]);\n// [ \"MIAAOW\", \"WUUUUFU WUUUUFU\", \"IAAAIAIA IAAAIAIA IAAAIAIA\", \"FIIIIIRE\", \"Hello World\", \"Hello \", \"Hello World\" ]\n```\n\nThe following example uses the object keys `cat`, `dog`, `donkey`, `dragon` as\nRPC _request object ids_ under the hood. The returned _RPC result_ values will\nbe assigned to these keys.\n\n```typescript\nlet noise2 = await remote.batch({\n  cat: [\"sayHello\", [\"miaaow\"]],\n  dog: [\"animalsMakeNoise\", [\"wuuuufu\"]],\n  donkey: [\"sayHello\"],\n  dragon: [\"animalsMakeNoise\", [\"fiiiiire\", \"fiiiiire\"]],\n});\n// { cat: \"Hello miaaow\", dog: \"WUUUUFU\", donkey: \"Hello \", dragon: \"FIIIIIRE FIIIIIRE\" }\n```\n\n### WebSockets\n\n#### call\n\nTakes a string and an `Array\u003cJsonValue\u003e` or `Record\u003cstring, JsonValue\u003e` object\nand returns `Promise\u003cJsonValue\u003e`.\n\n```typescript\nconst noise = await remote.call(\"callNamedParameters\", {\n  a: 10,\n  b: 20,\n  c: \"The result is:\",\n});\n// The result is: 200\n\nremote.socket.close();\n```\n\nNotifications return `Promise\u003cundefined\u003e`.\n\n##### notification\n\n```typescript\nconst notification = await remote.call(\"animalsMakeNoise\", [\"wuufff\"], {\n  isNotification: true,\n});\n// undefined\n```\n\n##### messaging between multiple clients\n\nBy using the `subscribe` method you can send messages between multiple clients.\nIt returns an object with a generator property\n`{ generator: AsyncGenerator\u003cJsonValue\u003e}` and the methods `emit` and\n`unsubscribe`.\n\nOther clients can _listen to_ and _emit_ messages by _subscribing_ to the same\nmethod.\n\n```typescript\nconst firstClient = await createRemote(new WebSocket(\"ws://0.0.0.0:8000\"));\nconst secondClient = await createRemote(new WebSocket(\"ws://0.0.0.0:8000\"));\n\nasync function run(iter: AsyncGenerator\u003cunknown\u003e) {\n  try {\n    for await (let x of iter) {\n      console.log(x);\n    }\n  } catch (err) {\n    console.log(err.message, err.code, err.data);\n  }\n}\n\nconst greetingFirst = firstClient.subscribe(\"sayHello\");\nconst greetingSecond = secondClient.subscribe(\"sayHello\");\n\nrun(greetingFirst.generator);\nrun(greetingSecond.generator);\ngreetingFirst.emit([\"first\"]);\ngreetingSecond.emit([\"second\"]);\n// Hello first\n// Hello first\n// Hello second\n// Hello second\n```\n\n## Proxy API\n\nOptionally, you can import _syntactical sugar_ and use a more friendly API\nsupported by `Proxy` objects.\n\n```typescript\nimport {\n  createRemote,\n  HttpProxy,\n  httpProxyHandler,\n} from \"https://deno.land/x/gentle_rpc/mod.ts\";\n\nconst remote = new Proxy\u003cHttpProxy\u003e(\n  createRemote(\"http://0.0.0.0:8000\"),\n  httpProxyHandler,\n);\n\nlet greeting = await remote.sayHello([\"World\"]);\n// Hello World\n\nconst namedParams = await remote.callNamedParameters({\n  a: 5,\n  b: 10,\n  c: \"result:\",\n});\n// result: 50\n```\n\n## Examples and Tests\n\nPlease checkout the\n[examples](https://github.com/timonson/gentle_rpc/tree/master/examples) and\n[tests](https://github.com/timonson/gentle_rpc/tree/master/tests) folders for\nmore detailed examples.\n\n## Contribution\n\nEvery kind of contribution to this project is highly appreciated.\\\nPlease run `deno fmt` on the changed files before making a pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimonson%2Fgentle_rpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimonson%2Fgentle_rpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimonson%2Fgentle_rpc/lists"}