{"id":13452493,"url":"https://github.com/pshihn/byproxy","last_synced_at":"2025-04-15T19:09:33.919Z","repository":{"id":34314415,"uuid":"176933389","full_name":"pshihn/byproxy","owner":"pshihn","description":"A different way of thinking of web client-server RPC","archived":false,"fork":false,"pushed_at":"2022-12-09T16:58:11.000Z","size":1034,"stargazers_count":41,"open_issues_count":20,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-15T19:09:27.780Z","etag":null,"topics":["javascript-proxy","proxy","rpc"],"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/pshihn.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}},"created_at":"2019-03-21T11:44:27.000Z","updated_at":"2022-11-21T01:55:45.000Z","dependencies_parsed_at":"2023-01-15T06:16:05.457Z","dependency_job_id":null,"html_url":"https://github.com/pshihn/byproxy","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pshihn%2Fbyproxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pshihn%2Fbyproxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pshihn%2Fbyproxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pshihn%2Fbyproxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pshihn","download_url":"https://codeload.github.com/pshihn/byproxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249135809,"owners_count":21218365,"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":["javascript-proxy","proxy","rpc"],"created_at":"2024-07-31T07:01:25.743Z","updated_at":"2025-04-15T19:09:33.900Z","avatar_url":"https://github.com/pshihn.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# ByProxy\n\nByProxy allows the client to access an object or module on the server as if it were a local object. The object's API can then be invoked directly on the client.\n\nFor example, a *calculator* server:\n\n**On the server:**\n```javascript\nclass Calculator {\n  constructor() {\n    this.opCount = 0;\n  }\n  add(a, b) {\n    this.opCount++;\n    return a + b;\n  }\n  subtract(a, b) {\n    this.opCount++;\n    return a - b;\n  }\n}\n// Serve an instance of Calculator via Express\nbyproxy.serve(app, '/calculator', new Calculator()); \n```\n\n**On the client:**\n```javascript\nconst calculator = byproxy.link('/calculator');\n\nconst sum = await calculator.add(2, 6);       // 8\nconst diff = await calculator.subtract(6, 2); // 4\nconsole.log(await calculator.opCount);        // 2\n```\n\n## Advantages\n* Tiny in size. The client lib is only 506 bytes gzipped.\n* No need to configure different rest methods for each function call. It is handled automatically. \n* When you want to add a new feature, just add a new method. Since the client is interacting with a *proxy* of the object on the server, no other setup is needed. \n* If using types, both the server and client will have the same interfaces - avoids bugs and duplication of definitions. \n\n## Other features\n\n#### Proxy a whole module\n```javascript\nconst mymod = require('my-awesome-mod');\nbyproxy.serve(app, '/updater', mymod);\n```\n\n### Proxy just a function\nServer:\n```javascript\nbyproxy.serve(app, '/hello', function (name) {\n  return 'Hello ' + name + '!';\n});\n```\nClient:\n```javascript\nconst hello = byproxy.link('/hello');\nconsole.log(await hello('John'));     // Hello John!\n```\n\n#### Seamlessly deal with async functions\nServer: \n```javascript\nbyproxy.serve(app, '/updater', {\n  async delayedUpdate() {\n    return new Promise(........);\n  }\n}); \n```\nClient:\n```javascript\nconst result = await updater.delayedUpdate();\n```\n\n\n\n## Error handling\n\nSince everything is a promise, the promise is rejected when the server returns and error code. The body of the response is in the error message and `error.code` will give you the status code of the rest call. \n\nFor most cases, when using `async-await`, simply catch the error\n\n```javascript\nconst calculator = byproxy.link('/calculator');\ntry {\n  const x = await calculator.divide(10, 0); // div by 0 error\n} catch (err) {\n  console.error(err);\n}\n```\n\n## Setup\n\nByProxy is composed of two modules `byproxy-serve` for the server and `byproxy-link` for the client. \nThey are both available on NPM.\n\n```\nnpm install --save byproxy-serve\nnpm install --save byproxy-link\n```\n\n*Note: ByProxy is not a rest library. It integrates with Express on the server. There is no dependency required on the client.*\n\n## Examples\n[ByProxy demo project](https://github.com/pshihn/byproxy-demo) is a simple example.\n\n## License\n[MIT License](https://github.com/pshihn/byproxy/blob/master/LICENSE) (c) [Preet Shihn](https://twitter.com/preetster)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpshihn%2Fbyproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpshihn%2Fbyproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpshihn%2Fbyproxy/lists"}