{"_id":"express-ipc","_rev":"4-73b0e2d9f06b67f7bdd9cf4e9b194d3d","name":"express-ipc","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"express-ipc","version":"1.0.0","description":"A simple IPC server with express-like request and route handling that also supports broadcasting to multiple channels.","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"prebuild":"npm test","build":"webpack","prepare":"husky install","test:watch":"jest --watch","test":"jest --passWithNoTests","test:coverage":"jest --coverage","prepublishOnly":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/h-sifat/express-ipc.git"},"keywords":[],"author":{"name":"Muhammad Sifat Hossain"},"license":"MIT","bugs":{"url":"https://github.com/h-sifat/express-ipc/issues"},"homepage":"https://github.com/h-sifat/express-ipc#readme","devDependencies":{"@types/jest":"^29.2.0","@types/node":"^18.11.6","husky":"^8.0.0","ts-jest":"^29.0.3","ts-loader":"^9.4.1","webpack":"^5.74.0","webpack-cli":"^4.10.0"},"dependencies":{"handy-types":"^2.0.0","path-to-regexp":"^6.2.1"},"gitHead":"14ded5d0c7798c4be13003ef41b0985d3adafaf4","_id":"express-ipc@1.0.0","_nodeVersion":"16.16.0","_npmVersion":"8.11.0","dist":{"integrity":"sha512-+EhwF6BzzDmbnQYUdd5lqZ5gQt0NFRZJ7mFrp0qjaKRvcVLH/ToUUK5AarYe8DNwnYD52tNmIVa6wnNxPLC6GQ==","shasum":"2d60f54dea7540a1e5afcc63bcd9bc0776d95491","tarball":"https://registry.npmjs.org/express-ipc/-/express-ipc-1.0.0.tgz","fileCount":23,"unpackedSize":108256,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGlE+d3fWEWvbDMs38RrDYsyhcAkGFK4T/I3SVSwmaZhAiAouzXejBnmZ+c530YRwu1SycEiNWfsLRQAnpOgKYOi/A=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjaTqJACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo42Q/+KrQjcUCYG7sAVNKcaN1gpKQtxkLr8Y5FOCCkEVzf/sx0mIdv\r\nnCAegqUTNB06hYdaOeweslpfgSBXvzy9rTg0dOGTTIXwRuzZLJRY4U8zGvAo\r\nfj5e6K89guIBrN8gTSIy+S2c3PduNB4LUZVq4/OKnoG5EhBKga7lPRUnQXKa\r\nNtz+nDiLRZiHiaqAXzvLhY7zPxwdeP6q3X+ANduXQMN6JolSARMe37gPcI9j\r\n9I4wCWO9QzPrl6cHlLkBkv9gKDJvx9uMA8+XkyNFOpqQzxpfDYGG7AzIpdki\r\nN23LN3ogz4ImPl08f4qPZQvxfVdEZcmCiEPGOSS7UzMmLQOCiCFQYXoojko/\r\nKQjiKd2hxHtex/KHoN+lIEMv5HE6Elhc3eOzNeb20usWvOe45jqHvR1+RG5G\r\n+rRAyUFX8kB9xdsDZ/OiBP9oX+AqLGYDpLMa45aamTZRjCgzzTwXYHbSLX4v\r\nld1E5QRBMfQH9Nk1/J6gLpvRV+JoiQEwbn60tRTUbDAwrxzu1u72hrlQwR4B\r\n/hvw9/M2sPdzvxf5GW4o3kGyMXK67Ndb6niJJxNB7Jx+JOVaA6ByiczUt7iL\r\nHn+ZPGR5nO2uf1PIyIz9iKK1bQKGXjTjMrlrJEI/eCUUTiJfh4LqJtJzhX2b\r\nDsSK+T2eFu7TheBmYzYyZ6lBi21vmozj0t0=\r\n=bAZM\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"h_sifat","email":"hsifat@protonmail.com"},"directories":{},"maintainers":[{"name":"h_sifat","email":"hsifat@protonmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/express-ipc_1.0.0_1667840649181_0.27541247809784286"},"_hasShrinkwrap":false},"1.0.1":{"name":"express-ipc","version":"1.0.1","description":"A simple IPC server with express-like request and route handling that also supports broadcasting to multiple channels.","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"prebuild":"npm test","build":"webpack","prepare":"husky install","test:watch":"jest --watch","test":"jest --passWithNoTests","test:coverage":"jest --coverage","prepublishOnly":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/h-sifat/express-ipc.git"},"keywords":["IPC","TCP","axios","pubsub","express","node-ipc","socket.io","websocket","express-ipc","unix domain socket","windows named pipe","jayson"],"author":{"name":"Muhammad Sifat Hossain"},"license":"MIT","bugs":{"url":"https://github.com/h-sifat/express-ipc/issues"},"homepage":"https://github.com/h-sifat/express-ipc#readme","devDependencies":{"@types/jest":"^29.2.0","@types/node":"^18.11.6","husky":"^8.0.0","ts-jest":"^29.0.3","ts-loader":"^9.4.1","webpack":"^5.74.0","webpack-cli":"^4.10.0"},"dependencies":{"handy-types":"^2.0.0","path-to-regexp":"^6.2.1"},"gitHead":"f5e3ae22e9a59e9ccfe1ea294188c6b344f08839","_id":"express-ipc@1.0.1","_nodeVersion":"16.16.0","_npmVersion":"8.11.0","dist":{"integrity":"sha512-zl5fDelvv8pm9V9MdKX5D+Xb1F+oNB1A52hdAgdlymPPp7IcJwRm3xwDWkCQU1VCUrdnQ0cZNAgbMMZ5xpyCpQ==","shasum":"963c81e6fe6e05d058deb3a9de120f795b954947","tarball":"https://registry.npmjs.org/express-ipc/-/express-ipc-1.0.1.tgz","fileCount":23,"unpackedSize":108883,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGYJRDPDpj+9wYV5+XbZamhmK5+9zhNrkmjUUddM/l1SAiEAmCGG3ubLcWZQ40tjwlUNMSGfqUF8doaE4Wer3Lz2gtA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjacPFACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrZBBAAiCMq07Z/CDgwiSiBji424v/UsSx3US9jqusGgcj9lCwZC+FD\r\n2WXlnC/Y5TFWxpgIJrf+GItREWdHTvXqUtdVoG3sYkU5QdwMDVaKI997EWnq\r\nUglkwwUEOvM4hA6G5gU515406hKMrUMo+B72+mttAvyh9U2XNViNAK7FW7cC\r\n9kcjJGdNG3D0upCLOqD2WxVdc6zN0juiWfczQe6dByMQVBnuDE6fyqLTp8G0\r\n6ZV5iZP5bCQdCVFDqXVzEghXf0gVXgAALZS1KimlNp30eMmR4Xt2h+CJpWlm\r\nT9Ef4a8jw0D8/QZWKWca4C/viSPMAHyQfziUOi1OqDmJSVIEuMwIS46T9Rya\r\nzoYffxTdOR159z5LVmDFUdc/vzSVdfMpROERthUlmXf3MsyxiTlYL06HC7Hu\r\nih7mIXCVyQDB7r2dAQyCLCXyn2nD9z/OoINYZbwAFE+soM/gJExyWS28va3n\r\nVLy7k21Tauxsq/1JqMeGvIH4kFYVbAUrXWOoAz0E2ona1PeZylMDmd8BpzL7\r\nFUxE4zDy+gYqGB5hnsCSzI1bNBUnAhbAChD+Xo6UorrZ66jn184Ymzunhl+B\r\nHvUF+za1tX0nB6aYb8YOb5IC8RNDlzsn862vILtq+8IHqE4Od6rPuwIp1Uzc\r\nRiuCZkkhqrO77qyVTP2aePD/gHBOMIeoTTE=\r\n=K8+G\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"h_sifat","email":"hsifat@protonmail.com"},"directories":{},"maintainers":[{"name":"h_sifat","email":"hsifat@protonmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/express-ipc_1.0.1_1667875781495_0.6176347961156687"},"_hasShrinkwrap":false},"1.0.2":{"name":"express-ipc","version":"1.0.2","description":"A simple IPC server with express-like request and route handling that also supports broadcasting to multiple channels.","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"prebuild":"npm test","build":"webpack","prepare":"husky install","test:watch":"jest --watch","test":"jest --passWithNoTests","test:coverage":"jest --coverage","prepublishOnly":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/h-sifat/express-ipc.git"},"keywords":["IPC","TCP","axios","pubsub","express","node-ipc","socket.io","websocket","express-ipc","unix domain socket","windows named pipe","jayson"],"author":{"name":"Muhammad Sifat Hossain"},"license":"MIT","bugs":{"url":"https://github.com/h-sifat/express-ipc/issues"},"homepage":"https://github.com/h-sifat/express-ipc#readme","devDependencies":{"@types/jest":"^29.2.0","@types/node":"^18.11.6","husky":"^8.0.0","ts-jest":"^29.0.3","ts-loader":"^9.4.1","webpack":"^5.74.0","webpack-cli":"^4.10.0"},"dependencies":{"handy-types":"^2.0.0","path-to-regexp":"^6.2.1"},"gitHead":"47ec1ee9caa41f07571189813efb27b020572740","_id":"express-ipc@1.0.2","_nodeVersion":"18.14.0","_npmVersion":"9.3.1","dist":{"integrity":"sha512-qkjRqM4yihxukp/ujUVuwwds2qtwyQBBZa+F79f6+aUMMdC+cYpOHZ8pO4JJSp4YJO1fh4c9/Endswl4iJvs5g==","shasum":"bc54c12b3434f76c5915d33f74196f2e1563832c","tarball":"https://registry.npmjs.org/express-ipc/-/express-ipc-1.0.2.tgz","fileCount":23,"unpackedSize":108605,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA0lzJGPnjNXMPjQqW+uLaMoAzag99ZkfxllDoVQEyjlAiAs8PecybeK1imElr8E2wLr+/d3/2V5mh4zCZmsGs31oQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkCC1WACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqOOhAAmCowIxLLRm3VHFr5eq8h1NtOzRLxpWgj8qtGNeLJYpIls2fr\r\nq4V8SWmO7ImdF8MrYeog0VSLK+S+yLzz5QuBLIueZKMkKo+E6TlnDDbeAEr9\r\nkLHizQUd4BwRzrnuEzlceqEO7JewBOTUSQVFT68+kSu63Vt0QFRH+l9AMT96\r\nFKKewjDFZgk5myrUZCNAc395vSoNWhpIb8/eojVofY+0u2Ca0yT12WJU65DW\r\nShsGug3dGtWC/Bu35Fmp6++YEQPvBDS7aH672ZJmuC8/ttIulz/1Vgaje2CR\r\nT0A0GJmrgZGzwkrQT8yDfKWqlK0I/s6Cs6YvppXaMg5ctVti6YMtVvmqjwP/\r\neRGP1fomyNmaGRGcSkv+c/+aA1Pdr55uF3N1N+MQ6hNwrQW4WKo2Xfj5MTby\r\nzxcjzCf5IRKAzDAMxcNTzdNOqhX+o/JT/GBh9R05JmOP5EgICTjvv9JbcS2T\r\nHc1EaFRWpQYi3/lBX3GfsAoIph8pm2QfLiy/d47+QLMN9Uy1yGhNfbxDhqY2\r\nlKNAJHhRpU+DYKJUQaF945ENLRCGiDUjCynN+52HrJyI/8mT5kDuFEZI0pI6\r\n4rA+O8fa02iyZBYzHq+22zQDS+E3NdNDv8Y8Q3ROcDnVcZ4Ip1+okP9uk+yH\r\nnrlBGsoy/Bh3rST2A67TfGokVPyQuJ2fXXY=\r\n=mgBb\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"h_sifat","email":"hsifat@protonmail.com"},"directories":{},"maintainers":[{"name":"h_sifat","email":"hsifat@protonmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/express-ipc_1.0.2_1678257494573_0.7139697447270266"},"_hasShrinkwrap":false},"1.0.3":{"name":"express-ipc","version":"1.0.3","description":"A simple IPC server with express-like request and route handling that also supports broadcasting to multiple channels.","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"prebuild":"npm test","build":"webpack","prepare":"husky install","test:watch":"jest --watch","test":"jest --passWithNoTests","test:coverage":"jest --coverage","prepublishOnly":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/h-sifat/express-ipc.git"},"keywords":["IPC","TCP","axios","pubsub","express","node-ipc","socket.io","websocket","express-ipc","unix domain socket","windows named pipe","jayson"],"author":{"name":"Muhammad Sifat Hossain"},"license":"MIT","bugs":{"url":"https://github.com/h-sifat/express-ipc/issues"},"homepage":"https://github.com/h-sifat/express-ipc#readme","devDependencies":{"@types/jest":"^29.2.0","@types/node":"^18.11.6","husky":"^8.0.0","ts-jest":"^29.0.3","ts-loader":"^9.4.1","webpack":"^5.74.0","webpack-cli":"^4.10.0"},"dependencies":{"handy-types":"^2.0.0","path-to-regexp":"^6.2.1"},"gitHead":"98841026285f7144b86a504569bfdb5bc6cb7eb8","_id":"express-ipc@1.0.3","_nodeVersion":"18.14.0","_npmVersion":"9.3.1","dist":{"integrity":"sha512-IJPJwDZPUqbImak47Ueklx7rAAZgMnD+r5ikSZvw87bQGuKdmMWCXGHlUVxTXE7vPvww5J5i0/6LYX3KfUyBew==","shasum":"ad71b6a81dec93fb70fa6ff61490f90c65307676","tarball":"https://registry.npmjs.org/express-ipc/-/express-ipc-1.0.3.tgz","fileCount":23,"unpackedSize":108901,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCl1oEqe/zvr3Embgz/c3PXyo6ifImnEixy1oipSZXSWAIgB7/qLTb1ChA+tqQ7nGG+P2Ykh+iGzfqg9JdL/B2OhuI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkHO08ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqupRAAgRA3Uo9j68yEFp1rv+vgX6e+/RYqmvL6S/C24A99MIWCYoW0\r\nVkcMB/AMgdBLM//B/xzNyBW7PyEbaxAioKoNRJfRqidZQYfYPfF5OADE4q4p\r\nsOOSnoziZGhy8j+HdIfywVseDRanToFnZakJeV+PPr3LJcP9iSRrXgBL36im\r\nT3InGt7KPX9F77xVT3ltIc7plsKKTKtv2K2WR88u6XRHjoJiWqpIeb0A34k4\r\niwlLr7GoIND8x6GPgsQNVjIREmxNvfmrLzg2zuBuH/HrvkPGjqbHTPY4OKiX\r\n/U8nPkQjF56MppqOYnTKRGOTe7MMGJmtvJmpOu1OpAjGtGOyKnkX21DyGSK8\r\nBBcHPDNT0/mZ/avOg1MY4bZ/jRrhreWYwumko2Fy4IAwgpj+39dQ5Dfnu4Of\r\niJo3pQJFL9QrmfL+ilVCc1SxzMfVgh32ClEPIoQIQrrVnt1jqnof77EJaMnH\r\ntDpagwHcP7y8WgauNMU2LDgXFVA1BpV/cAsUHjc9en9t2M0nrvka3gycRQMy\r\nljiJWzUaVhFD6LyOys1ishXkSfWZE39HtfwfowGCaioSFQ5w9YqJHHMQvD/l\r\nUk15IXEb/arJWdvf56GM90sHysGnh/QbTn2XObHpgkxu3hHHPNqMBgrH2KsM\r\n5kpcTyCVTms5OSkBOgC2JFstN+u5iJRW2nE=\r\n=rQ/b\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"h_sifat","email":"hsifat@protonmail.com"},"directories":{},"maintainers":[{"name":"h_sifat","email":"hsifat@protonmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/express-ipc_1.0.3_1679617339887_0.5114935365890894"},"_hasShrinkwrap":false},"1.1.0":{"name":"express-ipc","version":"1.1.0","description":"A simple IPC server with express-like request and route handling that also supports broadcasting to multiple channels.","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"prebuild":"npm test","build":"webpack","prepare":"husky install","test:watch":"jest --watch","test":"jest --passWithNoTests","test:coverage":"jest --coverage","prepublishOnly":"npm run build"},"repository":{"type":"git","url":"git+https://github.com/h-sifat/express-ipc.git"},"keywords":["IPC","TCP","axios","pubsub","express","node-ipc","socket.io","websocket","express-ipc","unix domain socket","windows named pipe","jayson"],"author":{"name":"Muhammad Sifat Hossain"},"license":"MIT","bugs":{"url":"https://github.com/h-sifat/express-ipc/issues"},"homepage":"https://github.com/h-sifat/express-ipc#readme","devDependencies":{"@types/jest":"^29.2.0","@types/node":"^18.11.6","husky":"^8.0.0","ts-jest":"^29.0.3","ts-loader":"^9.4.1","webpack":"^5.74.0","webpack-cli":"^4.10.0"},"dependencies":{"handy-types":"^2.0.0","path-to-regexp":"^6.2.1"},"_id":"express-ipc@1.1.0","gitHead":"ce64ea1eef2ddb46e2789f9a6e6e59cc60a70406","_nodeVersion":"20.10.0","_npmVersion":"10.2.3","dist":{"integrity":"sha512-ahViwI1DtqhTIDq/bWoKlI1AM7zhdRsg7irZMcAg+qwK5JLKaWF0nZcYJaOLud/YTEOv3uinJCk3MdgnyhwVvA==","shasum":"0938a57ad81312fcd0df5a9abab31c4301b3f6be","tarball":"https://registry.npmjs.org/express-ipc/-/express-ipc-1.1.0.tgz","fileCount":23,"unpackedSize":111998,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGNt/Uh5fdVSRiG/W6mpBklRx4n31vGZkeFpaK2AhwnyAiAL4Amx6oRVyKes8c7YCzkLHLuJ5TZHaP9pSwBbe64QRA=="}]},"_npmUser":{"name":"h_sifat","email":"hsifat@protonmail.com"},"directories":{},"maintainers":[{"name":"h_sifat","email":"hsifat@protonmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/express-ipc_1.1.0_1703248511303_0.6929661942128797"},"_hasShrinkwrap":false}},"time":{"created":"2022-11-07T17:04:09.180Z","1.0.0":"2022-11-07T17:04:09.389Z","modified":"2023-12-22T12:35:11.688Z","1.0.1":"2022-11-08T02:49:41.668Z","1.0.2":"2023-03-08T06:38:14.847Z","1.0.3":"2023-03-24T00:22:20.063Z","1.1.0":"2023-12-22T12:35:11.515Z"},"maintainers":[{"name":"h_sifat","email":"hsifat@protonmail.com"}],"description":"A simple IPC server with express-like request and route handling that also supports broadcasting to multiple channels.","homepage":"https://github.com/h-sifat/express-ipc#readme","keywords":["IPC","TCP","axios","pubsub","express","node-ipc","socket.io","websocket","express-ipc","unix domain socket","windows named pipe","jayson"],"repository":{"type":"git","url":"git+https://github.com/h-sifat/express-ipc.git"},"author":{"name":"Muhammad Sifat Hossain"},"bugs":{"url":"https://github.com/h-sifat/express-ipc/issues"},"license":"MIT","readme":"# Express-IPC\n\n![Module Type](https://img.shields.io/badge/Module%20Type-UMD-brightgreen)\n![Npm Version](https://img.shields.io/npm/v/express-ipc)\n![GitHub Tag](https://img.shields.io/github/v/tag/h-sifat/express-ipc)\n![GitHub Issues](https://img.shields.io/github/issues/h-sifat/express-ipc)\n\nA simple [IPC (Inter Process\nCommunication)](https://en.wikipedia.org/wiki/Inter-process_communication)\nserver with [Express](https://www.npmjs.com/package/express)-like request and\nroute handling that also supports broadcasting to multiple channels. It also\nprovides an easy to use axios like client to communicate with the server.\n\nIt usages **unix domain socket** on Unix OS and **windows named pipe** on\nWindows OS. Which results in very fast communication speed (e.g., `< 5ms`\nlatency for a `300Kb` payload). Though it runs on the TCP protocol, it's request\nand response objects are designed like the HTTP's, meaning a request has\nproperties like `method`, `headers`, `query`, `body` and so on. It is\nspecifically designed to perform\n[CRUD](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete) operations\nwith plain **JSON** objects (request and response) and where the server has the\nability to broadcast arbitrary JSON data to multiple channels (which clients\nmust subscribe to, to receive the data).\n\n### Quick Links\n\n1. [Installing](#installation)\n1. [Importing](#importing)\n1. [API Documentation](#api-documentation)\n1. [Todo](#todo)\n1. [Development](#development)\n\n## Example Usages\n\n#### Request and Response\n\n**server.js**\n\n```js\nconst { Server } = require(\"express-ipc\");\n\nconst socketPath = \"./pipe\";\nconst server = new Server();\n\nconst users = [\n  { id: 1, name: \"Alex\" },\n  { id: 2, name: \"Alexa\" },\n];\n\nserver.get(\"/users/:id\", ({ req, res }) => {\n  const id = Number(req.params.id);\n  const user = users.find((user) => user.id === id);\n\n  if (user) res.send(user);\n  else res.send({ message: `No user found with id: ${id}` }, { isError: true });\n});\n\nserver.listen({\n  path: socketPath,\n  deleteSocketBeforeListening: true,\n  callback() {\n    console.log(`Server running on socket: ${server.socketPath}`);\n  },\n});\n```\n\n**client.js**\n\n```js\nconst { Client } = require(\"express-ipc\");\nconst socketPath = \"./pipe\";\n\nmain();\n\nasync function main() {\n  const client = new Client({ path: socketPath });\n\n  try {\n    const response = await client.get(\"/users/1\");\n    console.log(response);\n  } catch (ex) {\n    console.log(ex);\n  }\n\n  client.close();\n}\n```\n\n#### Data Broadcasting\n\n**server.js**\n\n```js\nconst { Server } = require(\"express-ipc\");\n\nconst socketPath = \"./pipe\";\nconst server = new Server();\n\nserver.createChannels(\"test\");\n\nlet count = 1;\nsetInterval(() => {\n  server.broadcast({ channel: \"test\", data: { count: count++ } });\n}, 1000);\n\nserver.listen({ path: socketPath, deleteSocketBeforeListening: true });\n```\n\n**client.js**\n\n```js\nconst { Client } = require(\"express-ipc\");\nconst socketPath = \"./pipe\";\n\nmain();\n\nasync function main() {\n  const client = new Client({ path: socketPath });\n\n  await client.subscribe(\"test\");\n\n  client.on(\"broadcast\", console.log);\n}\n```\n\n## Installation\n\n```bash\nnpm install express-ipc\n```\n\n## Importing\n\nIt uses the **UMD** module system so it supports all JavaScript module systems\n(es6, commonjs, and so on).\n\n**commonjs**\n\n```js\nconst { Server, Client } = require(\"express-ipc\");\n```\n\n**es6**\n\n```js\nimport { Server, Client } from \"express-ipc\";\n```\n\n### Partial Importing\n\nIn case you only want to import the `Server` or the `Client` and don't want to\ncarry extra baggage in your application. If you're using a module bundler, it's\nprobably not necessary as unused code gets tree-shaken.\n\n**server**\n\n```js\n// es6\nimport { default as expressIpc } from \"express-ipc/dist/server.js\";\nconst Server = expressIpc.Server;\n\n// or commonjs:\nconst { Server } = require(\"express-ipc/dist/server\");\n```\n\n**client**\n\n```js\nimport { default as expressIpc } from \"express-ipc/dist/client.js\";\nconst Client = expressIpc.Client;\n\n// or commonjs\nconst { Client } = require(\"express-ipc/dist/client\");\n```\n\n## API Documentation\n\nBefore we start, it is assumed that you are familiar with\n[Express.js](https://www.npmjs.com/package/express) because the route handling\nand path pattern work exactly like Express with very little difference. So, I\nwould highly recommend you to read the\n[documentation](https://expressjs.com/en/starter/installing.html) of Express\nfirst.\n\n#### Table Of Contents\n\n1. [Server](#server)\n\n   1. [`Constructor: Server()`](#constructor-server)\n   1. [`server.socketPath`](#serversocketpath)\n   1. [`server.listen()`](#serverlisten)\n   1. [`server.close()`](#serverclose)\n   1. [`server.createChannels()`](#servercreatechannels)\n   1. [`server.deleteChannels()`](#serverdeletechannels)\n   1. [`server.broadcast()`](#serverbroadcast)\n   1. [`server.on()`](#serveron)\n\n1. [Routing](#routing)\n\n   1. [Method](#method)\n   1. [Path](#path)\n   1. [Handler/Middleware](#handler--middleware)\n   1. [Request Object (`req`)](#request-object-req)\n   1. [Response Object (`res`)](#response-object-res)\n   1. [Next Function (`next`)](#the-next-function)\n   1. [Error Handling](#error-handling)\n\n1. [Client](#client)\n\n   1. [`Constructor: Client()`](#constructor-client)\n   1. [`client.subscribe()`](#clientsubscribe)\n   1. [`client.unsubscribe()`](#clientunsubscribe)\n   1. [`client.request()`](#clientrequest)\n   1. [`client.get()`](#clientget)\n   1. [`client.delete()`](#clientdelete)\n   1. [`client.post()`](#clientpost)\n   1. [`client.patch()`](#clientpatch)\n   1. [`client.on()`](#clienton)\n      1. [Receiving Broadcasts](#receiving-broadcasts)\n      1. [Handling Client Errors](#handling-errors)\n   1. [`client.close()`](#clientclose)\n\n### Server\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### Constructor: `Server()`\n\nThe `Server` class constructor takes an **optional** object argument with two\noptional properties. It has the following interface:\n\n```ts\ninterface ServerConstructor_Argument {\n  delimiter?: string;\n  socketRoot?: string;\n}\n```\n\n| property   | default value | description                                                                                                                                  |\n| ---------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |\n| delimiter  | `\"\\f\"`        | This character is used to indicate the end a of serialized request or response data in the socket.                                           |\n| socketRoot | `os.tmpdir()` | If no absolute `path` is provided for the socket in the `server.listen` method's argument then the socket will be created in this directory. |\n\n**Example:**\n\n```js\nconst server = new Server({ delimiter: \"\\n\", socketRoot: \"./sockets\" });\n```\n\n#### `server.socketPath`\n\nA **getter** which returns the active `socket` path (a string). If the server is\nnot running it returns `undefined`.\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `server.listen()`\n\nListens on the given socket path for requests. It takes a single object argument\nthat has the following interface:\n\n```ts\ninterface Listen_Argument {\n  callback?: () => void;\n  deleteSocketBeforeListening?: boolean;\n  path: string | { namespace: string; id: string };\n}\n```\n\n| property                      | description                                                                                                                                                                                                                                 |\n| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `path`                        | If path is a `string` than it should refer to a socket's absolute path. Otherwise, if it is an object of type `{namespace: string; id: string}` then the socketPath will be constructed from: `path.join(socketRoot, namespace + \"_\" + id)` |\n| `deleteSocketBeforeListening` | If the socket file already exists and we try to listen on it, an exception with the code `\"EADDRINUSE\"` will be thrown. To avoid this we can set this flag to `true`.                                                                       |\n| `callback`                    | If provided then it'll be called when the server starts listening.                                                                                                                                                                          |\n\n**Example:**\n\n```js\nserver.listen({\n  deleteSocketBeforeListening: true,\n  path: { namespace: \"test_app\", id: \"v1\" },\n  callback() {\n    console.log(\"Server running on socket: \", server.socketPath);\n  },\n});\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `server.close()`\n\nCloses a server. It takes an optional callback function.\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `server.createChannels()`\n\nCreates broadcast channels. It takes a **rest** argument or `string` or an\n**array** of `string`s.\n\n**Example:**\n\n```js\nserver.createChannels(\"a\", \"b\", [\"c\", \"d\"], \"e\");\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `server.deleteChannels()`\n\nDeletes broadcast channels. It's signature is the same as\n`server.createChannels`.\n\n**Example:**\n\n```js\nserver.deleteChannels([\"a\", \"b\", \"e\"], \"c\", \"d\");\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `server.broadcast()`\n\nBroadcasts data to a channel. It takes a single object argument with the\nfollowing interface:\n\n```ts\ninterface Broadcast_Argument {\n  data: object;\n  channel: string;\n  blacklist?: number[];\n}\n```\n\n| property  | description                                                                                      |\n| --------- | ------------------------------------------------------------------------------------------------ |\n| data      | The data to broadcast.                                                                           |\n| channel   | The channel name.                                                                                |\n| blacklist | An array of `connectionId`s. This can used to stop some connection from receiving the broadcast. |\n\n**Tip:** We can get the `connectionId` from a response object.\n\n**Example:**\n\n```js\nserver.post(\"/exciting-news\", ({ req, res }) => {\n  // as this connection itself brought the news,\n  // we don't need to echo the news back to it.\n  // I know it's not a good example but it shows the functionality\n\n  server.broadcast({\n    data: req.body,\n    channel: \"exciting-news\",\n    blacklist: [res.connectionId],\n  });\n});\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `server.on()`\n\nWith this method we can add event listeners on the underlying socket server\ncreated with the `net.createServer` function.\n\n**Example:**\n\n```js\nserver.on(\"error\", (err) => {});\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n### Routing\n\nRouting works similar to Express.js. It takes the following structure:\n\n```js\nserver.method(path, handler | middleware);\n\n// example\nserver.get(\"/users/:id\", ({ req, res, next }) => {});\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### Method\n\nRequest methods. express-ipc only supports these four methods:\n\n1. `get`\n1. `post`\n1. `patch`\n1. `delete`\n\nAdditionally We can use `all` and `use` to define routes on paths that runs for\nany request method. Though `all` and `use` methods are similar but we can use\nthe `use` method to define **application level** ( runs regardless of the\nrequest path)\n[middlewares](https://expressjs.com/en/guide/writing-middleware.html).\n\n**Example: Application level middleware**\n\n```js\nserver.use(({ req, res, next }) => {\n  // ... do something with the request object\n\n  next(); // pass the request to the next middleware\n});\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### Path\n\nThe route path works exactly like express because it uses the same\n[path-to-regexp](https://www.npmjs.com/package/path-to-regexp) package to parse\nroute paths, that express uses. See the express documentation for [Route\nPath](https://expressjs.com/en/guide/routing.html).\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### Handler / Middleware\n\nThe handler/middleware functions' signature is a little different from express.\nIn Express, a middleware function has the following signature:\n\n```js\nfunction (req, res, next) {}\n```\n\nIt takes three arguments. In contrast, express-ipc packs these three arguments\ninto an object.\n\n```js\nfunction (arg) {arg.req; arg.res; arg.next}\n\n// or better, if we destructure them\nfunction ({req, res, next}) {}\n\n// we can only the pick  properties that we are interested in\nfunction ({req, next}) {}\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n##### Error Handler / Middleware\n\nIn Express, an error handler takes four arguments:\n\n```js\nfunction (err, req, res, next) {}\n```\n\nOn the other hand, express-ipc takes two arguments:\n\n```js\nfunction (reqResNextObject, err) {}\n\n// only picking the required properties\nfunction ({res}, err) {}\n```\n\nHandlers / Middlewares can be defined in various ways. Suppose that, we have two\nhandlers named `handler_a`, `handler_b` and an error handler named\n`error_handler`. Then all the following examples are equivalent.\n\n**Example: 1**\n\n```js\nserver.post(\"/users\", handler_a, handler_b, error_handler);\n// or\nserver.post(\"/users\", [handler_a, error_handler, handler_b]);\n// or\nserver.post(\"/users\", handler_a, [handler_b, error_handler]);\n// or\nserver.post(\"/users\", [handler_a, handler_b], error_handler);\n// or\nserver.post(\"/users\", handler_a, error_handler, [handler_b]);\n```\n\n**Example: 2**\n\n```js\nserver.post(\"/users\", handler_a, handler_b);\nserver.post(\"/users\", error_handler);\n```\n\n**Example: 3**\n\n```js\nserver.post(\"/users\", error_handler);\nserver.post(\"/users\", handler_a, handler_b);\n```\n\n**Note:** Error handlers are stored in different stacks than general request\nhandlers or middlewares. So, it's ok if we mix them up.\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### Request Object (`req`)\n\nThe request object or the `req` property in a handler's / middleware's first\nargument has the following interface.\n\n```ts\ninterface Request {\n  path: string;\n  params: object;\n  readonly url: string;\n  readonly query: object;\n  readonly headers: object;\n  readonly body: object | null;\n  readonly method: \"get\" | \"post\" | \"delete\" | \"patch\";\n}\n```\n\nAll the properties are **readonly** except **path** and **params**. Meaning we\ncannot reassign the readonly properties with new values. But, if the property is\nan object, we can modify it.\n\n**Example:**\n\n```js\nserver.get(\"/users/:id\", ({ req }) => {\n  // reassigning: forbidden\n  req.body = null; // will throw an error in strict mode\n\n  // modifying: allowed\n  req.body.test = \"new property\";\n});\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### Response Object (`res`)\n\nThe response object (`res` from a handler's / middleware's first argument) has\nthe following interface:\n\n```ts\ninterface Response {\n  get isSent(): boolean;\n  get headers(): object;\n  get connectionId(): number;\n  send(\n    body?: object | null,\n    options?: { endConnection?: boolean; isError?: boolean }\n  ): void;\n}\n```\n\n| property       | description                                                                                                                                                                                                                                                                                      |\n| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `isSent`       | a getter; returns a boolean value indicating whether the `send` method has already been called.                                                                                                                                                                                                  |\n| `headers`      | a getter; returns the headers object of the response. Its properties are modifiable.                                                                                                                                                                                                             |\n| `connectionId` | a getter; returns the `connectionId` of the underlying socket. Can be used to blacklist a connection when broadcasting data                                                                                                                                                                      |\n| `send`         | A method to send the response. It takes two optional arguments: first `body` and second `options`. If no argument is provided then the response body will be null. We can use the `isError` flag to mark the response as an error response and the `endConnection` to end the underlying socket. |\n\n**Example**\n\n```js\nserver.get(\"/users/:id\", ({ req, res }) => {\n  const id = Number(req.params.id);\n\n  if (Number.isNaN(id)) {\n    res.headers.statusCode = 400;\n    return res.send({ message: \"Invalid id\" }, { isError: true });\n  }\n\n  const user = /* get the user somehow */;\n\n  // res.isSent: false\n  res.send(user);\n  // res.isSent: true\n});\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### The `next` function\n\nThe `next` function from a handler's / middleware's first argument can be used\nto pass control to the next middleware or error handler.\n\n**Example:**\n\n```js\nserver.get(\n  \"/users\",\n  ({ next }) => {\n    next(); // pass control to the next handler\n  },\n  ({ res }) => {\n    res.send(/* users */);\n  }\n);\n```\n\n```js\nserver.get(\n  \"/users\",\n  ({ next }) => {\n    // pass control to the next error handler\n    next(new Error(\"failed\"));\n  },\n  ({ res }, error) => {\n    res.send(/* error response */, {isError: true});\n  }\n);\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### Error Handling\n\nIf a handler / middleware throws an exception or rejects a promise it'll be\nautomatically caught and passed to the next error handler or the default error\nhandler (if no error handler is defined). But in any other cases, we've to pass\nan error manually to the `next` function to move to the error handlers.\n\n**Example:**\n\nSuppose that, we have a `getUsers` function that takes a callback function. In\nthis case we can handle the error as shown in the following snippet.\n\n```js\nserver.get(\"/users\", ({ next, res }) => {\n  getUsers((error, users) => {\n    if (error) next(error);\n    else res.send(users);\n  });\n});\n\nserver.get(\"/users\", ({ res }, error) => {\n  // do something with the error\n});\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n### Client\n\nBefore we start, we need to know the request and response object's shape.\n\nGo to [Table Of Contents](#table-of-contents)\n\n##### RequestPayload\n\n```ts\ninterface RequestPayload {\n  url: string;\n  query: object;\n  headers: object;\n  body: object | null;\n  method: \"get\" | \"post\" | \"delete\" | \"patch\";\n}\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n##### ResponsePayload\n\n```ts\ninterface ResponsePayload {\n  headers: object;\n  body: object | null;\n}\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### Constructor: `Client()`\n\nThe `Client` constructor takes a single object as it's argument which has the\nfollowing interface:\n\n```ts\ninterface ClientConstructor_Argument {\n  delimiter?: string;\n  socketRoot?: string;\n  path: Listen_Argument[\"path\"];\n}\n```\n\n| property   | default value | description                                                      |\n| ---------- | ------------- | ---------------------------------------------------------------- |\n| delimiter  | `\"\\f\"`        | See [ServerConstructor_Argument.delimiter](#constructor-server)  |\n| socketRoot | `os.tmpdir()` | See [ServerConstructor_Argument.socketRoot](#constructor-server) |\n| path       |               | See [Listen_Argument.path](#serverlisten)                        |\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `client.subscribe()`\n\nSubscribe to channels. It has the following signature:\n\n```ts\nsubscribe(\n  ...channelsRestArg: (string | string[])[]\n): Promise<ResponsePayload>\n```\n\nSee [ResponsePayload](#responsepayload)\n\n**Example:**\n\n```ts\nawait client.subscribe(\"a\", \"b\", [\"c\", \"d\"], \"e\");\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `client.unsubscribe()`\n\nUnsubscribe to channels. It has the following signature:\n\n```ts\nunsubscribe(\n  ...channelsRestArg: (string | string[])[]\n): Promise<ResponsePayload>\n```\n\nSee [ResponsePayload](#responsepayload)\n\n**Example:**\n\n```ts\nawait client.unsubscribe([\"a\", \"b\"], \"c\", \"d\", \"e\");\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `client.request()`\n\nThis method can be used to make request to the server. It has the following\nsignature:\n\n```typescript\ninterface Request_Argument {\n  url: string;\n  query?: object;\n  headers?: object;\n  body?: object | null;\n  method: \"get\" | \"post\" | \"delete\" | \"patch\";\n}\n\ntype request = (\n  arg: Request_Argument,\n  options?: { timeout?: number }\n) => Promise<ResponsePayload>;\n```\n\nSee [ResponsePayload](#responsepayload)\n\nOnly the `url` and `method` property is required and the rest are optional.\n\n**Example:**\n\n```js\nconst users = await client.request({ url: \"/users\", method: \"get\" });\n```\n\nWe can also provide a timeout (in **milliseconds**) for the request. If the\nserver doesn't respond within time then the request will be rejected with a\ntimeout error.\n\n```js\nconst users = await client.request(\n  { url: \"/users\", method: \"get\" },\n  { timeout: 1000 }\n);\n```\n\n**Note:** If the response does arrive after the request has been timed out,\nan `\"unhandled_response\"` event will be emitted.\n\n**Tip:** All the request methods (`request`, `get`, ...) are generic, so you can\nspecify the body and headers type. I'm really busy to document them right now.\n\n```ts\ninterface User {\n  name: string;\n  email: string;\n}\n\nconst users = await client.request<User[]>({\n  url: \"/users\",\n  method: \"get\",\n});\n// typeof users: Users[]\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `client.get()`\n\nThe get method is similar to the `client.request` method. It just sets the\n`method` property to `\"get\"` for us.\n\nIt has the following signature:\n\n```ts\ntype get = (\n  url: string,\n  other?: {\n    query?: object;\n    headers?: object;\n    timeout?: number;\n    body?: object | null;\n  }\n) => Promise<ResponsePayload>;\n```\n\nSee [ResponsePayload](#responsepayload)\n\nThe `other` parameter is optional, so are all of its properties.\n\n**Example:**\n\n```js\nconst users = await client.get(\"/users\", {\n  headers: { \"x-auth-token\": \"aa9fa6d82308\" },\n});\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `client.delete()`\n\nSends a request with the request-method set to `\"delete\"`. It has exactly\nthe same signature as the [`client.get()`](#clientget) method.\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `client.post()`\n\nSends a request with the request-method set to `\"post\"`. Signature:\n\n```ts\ntype post = (\n  url: string,\n  other: {\n    query?: object;\n    headers?: object;\n    timeout?: number;\n    body: object | null;\n  }\n) => Promise<ResponsePayload>;\n```\n\nSee [ResponsePayload](#responsepayload)\n\nFor the `client.post` method the second parameter is required and it's `body`\nproperty is also required.\n\n**Example:**\n\n```js\nconst user = { id: 1, name: \"Alex\" };\nconst response = await client.post(\"/users\", { body: user });\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `client.patch()`\n\nSends a request with the request-method set to `\"patch\"`. It has exactly\nthe same signature as [`client.post()`](#clientpost) method.\n\n**Example:**\n\n```js\nconst edited = await client.patch(\"/users/1\", {\n  body: { name: \"Alex Smith\" },\n});\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `client.on()`\n\nThe `Client` class inherits from the `EventEmitter` class. It emits the\nfollowing events.\n\n1. `\"error\"`: mostly for socket errors\n1. `\"broadcast`: for receiving broadcast\n1. `\"unhandled_response\"`: for timed out requests\n\nWe can use the `client.on` method to subscribe to these events.\n\nGo to [Table Of Contents](#table-of-contents)\n\n##### Receiving Broadcasts\n\nWe can receive broadcasts by adding an event listener on the `\"broadcast\"`\nevent. The broadcast data has the following interface:\n\n```ts\ninterface Broadcast {\n  data: any;\n  channel: string;\n}\n```\n\n**Example:**\n\n```js\nclient.on(\"broadcast\", (data) => {});\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n##### Handling Errors\n\nSubscribe to the `\"socket_error\"` event to get notified about any errors on the\nunderlying socket. With this event you can get notified if the server quits or\ncloses your client connection.\n\n**Example:**\n\n```js\nclient.on(\"socket_error\", (error) => {});\n```\n\nGo to [Table Of Contents](#table-of-contents)\n\n#### `client.close()`\n\nCloses the underlying socket and no requests can be sent after the socket is\nclosed.\n\n## Todo\n\n- [ ] Do thorough testing (currently coverage is `90%`).\n- [ ] Support data formats other than JSON (e.g., Buffer)\n\n## Development\n\n```bash\n# Run tests\nnpm test\n# Run tests in watch mode\nnpm test:watch\n# Run tests with coverage\nnpm test:coverage\n\n# Build / Bundle\nnpm run build\n```\n\nIf you find a bug or want to improve something please feel free to open an\nissue. Pull requests are also welcomed 💝. Finally, if you appreciate me writing\na docs of 900 lines, please give this project a ⭐ on github. So that, I can\nfeel a little better about the time I spent/wasted on this project.\n","readmeFilename":"README.md"}