socketio drop in for bsock
This commit is contained in:
Generated
+377
-7
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "rpclibrary",
|
||||
"version": "1.9.2",
|
||||
"version": "1.10.2",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -247,6 +247,14 @@
|
||||
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/engine.io": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/engine.io/-/engine.io-3.1.4.tgz",
|
||||
"integrity": "sha512-98rXVukLD6/ozrQ2O80NAlWDGA4INg+tqsEReWJldqyi2fulC9V7Use/n28SWgROXKm6003ycWV4gZHoF8GA6w==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/expect": {
|
||||
"version": "1.20.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz",
|
||||
@@ -275,8 +283,21 @@
|
||||
"@types/node": {
|
||||
"version": "11.15.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.15.2.tgz",
|
||||
"integrity": "sha512-BqCU9uIFkUH9Sgo2uLYbmIiFB1T+VBiM8AI/El3LIAI5KzwtckeSG+3WOYZr9aMoX4UIvRFBWBeSaOu6hFue2Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-BqCU9uIFkUH9Sgo2uLYbmIiFB1T+VBiM8AI/El3LIAI5KzwtckeSG+3WOYZr9aMoX4UIvRFBWBeSaOu6hFue2Q=="
|
||||
},
|
||||
"@types/socket.io": {
|
||||
"version": "2.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-2.1.8.tgz",
|
||||
"integrity": "sha512-NIQfh9WwJuJKlgmby4NgwMpoBOmNPCDgaRNPiLYZBtkbHkszK/9R52B5yGkd5a34rbVdAADuo8FhOS/5AZDemw==",
|
||||
"requires": {
|
||||
"@types/engine.io": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/socket.io-client": {
|
||||
"version": "1.4.33",
|
||||
"resolved": "https://registry.npmjs.org/@types/socket.io-client/-/socket.io-client-1.4.33.tgz",
|
||||
"integrity": "sha512-m4LnxkljsI9fMsjwpW5QhRpMixo2BeeLpFmg0AE+sS4H1pzAd/cs/ftTiL60FLZgfFa8PFRPx5KsHu8O0bADKQ=="
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
"version": "1.8.5",
|
||||
@@ -466,12 +487,26 @@
|
||||
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
|
||||
"dev": true
|
||||
},
|
||||
"accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
|
||||
"requires": {
|
||||
"mime-types": "~2.1.24",
|
||||
"negotiator": "0.6.2"
|
||||
}
|
||||
},
|
||||
"acorn": {
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
|
||||
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
|
||||
"dev": true
|
||||
},
|
||||
"after": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
|
||||
"integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
|
||||
},
|
||||
"aggregate-error": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
|
||||
@@ -602,6 +637,11 @@
|
||||
"integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
|
||||
"dev": true
|
||||
},
|
||||
"arraybuffer.slice": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
|
||||
"integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog=="
|
||||
},
|
||||
"arrify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
|
||||
@@ -658,6 +698,11 @@
|
||||
"integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
|
||||
"dev": true
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
|
||||
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
|
||||
},
|
||||
"atob": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
|
||||
@@ -673,6 +718,11 @@
|
||||
"underscore": ">=1.8.3"
|
||||
}
|
||||
},
|
||||
"backo2": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
|
||||
"integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
@@ -734,12 +784,30 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"base64-arraybuffer": {
|
||||
"version": "0.1.5",
|
||||
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
|
||||
"integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
|
||||
},
|
||||
"base64-js": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
||||
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
|
||||
"dev": true
|
||||
},
|
||||
"base64id": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
|
||||
},
|
||||
"better-assert": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
|
||||
"integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
|
||||
"requires": {
|
||||
"callsite": "1.0.0"
|
||||
}
|
||||
},
|
||||
"big.js": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
|
||||
@@ -752,6 +820,11 @@
|
||||
"integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
|
||||
"dev": true
|
||||
},
|
||||
"blob": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
|
||||
"integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||
@@ -1013,6 +1086,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"callsite": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
|
||||
"integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA="
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
@@ -1191,11 +1269,20 @@
|
||||
"integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
|
||||
"dev": true
|
||||
},
|
||||
"component-bind": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
|
||||
"integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
|
||||
},
|
||||
"component-emitter": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||
},
|
||||
"component-inherit": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
|
||||
"integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
@@ -1236,6 +1323,11 @@
|
||||
"safe-buffer": "~5.1.1"
|
||||
}
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
|
||||
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
|
||||
},
|
||||
"copy-concurrently": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
|
||||
@@ -1517,6 +1609,77 @@
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"engine.io": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.2.tgz",
|
||||
"integrity": "sha512-b4Q85dFkGw+TqgytGPrGgACRUhsdKc9S9ErRAXpPGy/CXKs4tYoHDkvIRdsseAF7NjfVwjRFIn6KTnbw7LwJZg==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.4",
|
||||
"base64id": "2.0.0",
|
||||
"cookie": "0.3.1",
|
||||
"debug": "~4.1.0",
|
||||
"engine.io-parser": "~2.2.0",
|
||||
"ws": "^7.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"engine.io-client": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.3.tgz",
|
||||
"integrity": "sha512-0NGY+9hioejTEJCaSJZfWZLk4FPI9dN+1H1C4+wj2iuFba47UgZbJzfWs4aNFajnX/qAaYKbe2lLTfEEWzCmcw==",
|
||||
"requires": {
|
||||
"component-emitter": "~1.3.0",
|
||||
"component-inherit": "0.0.3",
|
||||
"debug": "~4.1.0",
|
||||
"engine.io-parser": "~2.2.0",
|
||||
"has-cors": "1.1.0",
|
||||
"indexof": "0.0.1",
|
||||
"parseqs": "0.0.5",
|
||||
"parseuri": "0.0.5",
|
||||
"ws": "~6.1.0",
|
||||
"xmlhttprequest-ssl": "~1.5.4",
|
||||
"yeast": "0.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
|
||||
"integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
|
||||
"requires": {
|
||||
"async-limiter": "~1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"engine.io-parser": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz",
|
||||
"integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==",
|
||||
"requires": {
|
||||
"after": "0.8.2",
|
||||
"arraybuffer.slice": "~0.0.7",
|
||||
"base64-arraybuffer": "0.1.5",
|
||||
"blob": "0.0.5",
|
||||
"has-binary2": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"enhanced-resolve": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz",
|
||||
@@ -2694,6 +2857,26 @@
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"has-binary2": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
|
||||
"integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
|
||||
"requires": {
|
||||
"isarray": "2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
|
||||
"integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
|
||||
}
|
||||
}
|
||||
},
|
||||
"has-cors": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
|
||||
"integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
@@ -2865,6 +3048,11 @@
|
||||
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
|
||||
"dev": true
|
||||
},
|
||||
"indexof": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
|
||||
"integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
|
||||
},
|
||||
"infer-owner": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
|
||||
@@ -3585,6 +3773,19 @@
|
||||
"brorand": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.44.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
|
||||
"integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.27",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
|
||||
"integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
|
||||
"requires": {
|
||||
"mime-db": "1.44.0"
|
||||
}
|
||||
},
|
||||
"mimic-fn": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
@@ -3714,8 +3915,7 @@
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.14.0",
|
||||
@@ -3743,6 +3943,11 @@
|
||||
"to-regex": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
},
|
||||
"neo-async": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
|
||||
@@ -4084,6 +4289,11 @@
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true
|
||||
},
|
||||
"object-component": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
|
||||
"integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE="
|
||||
},
|
||||
"object-copy": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
|
||||
@@ -4309,6 +4519,22 @@
|
||||
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
|
||||
"dev": true
|
||||
},
|
||||
"parseqs": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
|
||||
"integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
|
||||
"requires": {
|
||||
"better-assert": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"parseuri": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
|
||||
"integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
|
||||
"requires": {
|
||||
"better-assert": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"pascalcase": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
|
||||
@@ -4922,6 +5148,130 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"socket.io": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz",
|
||||
"integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==",
|
||||
"requires": {
|
||||
"debug": "~4.1.0",
|
||||
"engine.io": "~3.4.0",
|
||||
"has-binary2": "~1.0.2",
|
||||
"socket.io-adapter": "~1.1.0",
|
||||
"socket.io-client": "2.3.0",
|
||||
"socket.io-parser": "~3.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"socket.io-adapter": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz",
|
||||
"integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g=="
|
||||
},
|
||||
"socket.io-client": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz",
|
||||
"integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==",
|
||||
"requires": {
|
||||
"backo2": "1.0.2",
|
||||
"base64-arraybuffer": "0.1.5",
|
||||
"component-bind": "1.0.0",
|
||||
"component-emitter": "1.2.1",
|
||||
"debug": "~4.1.0",
|
||||
"engine.io-client": "~3.4.0",
|
||||
"has-binary2": "~1.0.2",
|
||||
"has-cors": "1.1.0",
|
||||
"indexof": "0.0.1",
|
||||
"object-component": "0.0.3",
|
||||
"parseqs": "0.0.5",
|
||||
"parseuri": "0.0.5",
|
||||
"socket.io-parser": "~3.3.0",
|
||||
"to-array": "0.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"component-emitter": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
|
||||
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"isarray": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
|
||||
"integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
|
||||
},
|
||||
"socket.io-parser": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz",
|
||||
"integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==",
|
||||
"requires": {
|
||||
"component-emitter": "1.2.1",
|
||||
"debug": "~3.1.0",
|
||||
"isarray": "2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"socket.io-parser": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz",
|
||||
"integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==",
|
||||
"requires": {
|
||||
"component-emitter": "1.2.1",
|
||||
"debug": "~4.1.0",
|
||||
"isarray": "2.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"component-emitter": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
|
||||
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"isarray": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
|
||||
"integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
|
||||
}
|
||||
}
|
||||
},
|
||||
"source-list-map": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
|
||||
@@ -5282,6 +5632,11 @@
|
||||
"setimmediate": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"to-array": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
|
||||
"integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
|
||||
},
|
||||
"to-arraybuffer": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
|
||||
@@ -5958,6 +6313,16 @@
|
||||
"typedarray-to-buffer": "^3.1.5"
|
||||
}
|
||||
},
|
||||
"ws": {
|
||||
"version": "7.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz",
|
||||
"integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w=="
|
||||
},
|
||||
"xmlhttprequest-ssl": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
|
||||
"integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
@@ -6043,6 +6408,11 @@
|
||||
"yargs": "^13.3.0"
|
||||
}
|
||||
},
|
||||
"yeast": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
|
||||
"integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
|
||||
},
|
||||
"yn": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",
|
||||
|
||||
+5
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "rpclibrary",
|
||||
"version": "1.10.2",
|
||||
"version": "1.11.0",
|
||||
"description": "rpclibrary is a websocket on steroids!",
|
||||
"main": "./js/Index.js",
|
||||
"repository": {
|
||||
@@ -50,9 +50,13 @@
|
||||
"why-is-node-running": "^2.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/socket.io": "^2.1.8",
|
||||
"@types/socket.io-client": "^1.4.33",
|
||||
"bsock": "^0.1.9",
|
||||
"crypto-js": "^4.0.0",
|
||||
"http": "0.0.0",
|
||||
"socket.io": "^2.3.0",
|
||||
"socket.io-client": "^2.3.0",
|
||||
"uuid": "^3.3.3"
|
||||
},
|
||||
"files": [
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import { RPCSocket, RPCServer } from "./Index"
|
||||
|
||||
|
||||
// TL;DR
|
||||
const echo = (text: string) => {throw new Error("XD")}
|
||||
const add = (a: number, b: number) : number => a + b
|
||||
const getAsync = async () : Promise<{topic: string, message:string}>=> await new Promise((res, _) => {
|
||||
setTimeout(() => {
|
||||
res({
|
||||
topic: "Hey!!",
|
||||
message: "Hello World Async!"
|
||||
})
|
||||
}, 250)
|
||||
})
|
||||
const getCallback = (cbb: Function) : string => {
|
||||
setTimeout(() => {
|
||||
try{
|
||||
cbb({
|
||||
topic: "Hey!!",
|
||||
message: "Hello World Callback!"
|
||||
})
|
||||
}catch(e){
|
||||
console.log(String(e))
|
||||
}
|
||||
}, 250)
|
||||
return "Please wait for a callback :)"
|
||||
}
|
||||
new RPCServer(20000, [{
|
||||
name: 'MyRPCGroup1',
|
||||
exportRPCs: () => [
|
||||
echo,
|
||||
add,
|
||||
getAsync,
|
||||
{
|
||||
name: 'getCallback',
|
||||
hook: getCallback,
|
||||
onClose: (response, rpc) => { },
|
||||
onCallback: (...callbackArgs) => { }
|
||||
}
|
||||
]
|
||||
}])
|
||||
|
||||
|
||||
new RPCSocket(20000, 'localhost').connect()
|
||||
.then(async sock => {
|
||||
try{
|
||||
const val = await sock.call('ABCD', 12345)
|
||||
console.log("VAL",val);
|
||||
|
||||
}catch(e){
|
||||
console.log("RPC error "+e)
|
||||
}
|
||||
}).catch(e => console.log("connect err: "+e))
|
||||
+14
-24
@@ -1,17 +1,17 @@
|
||||
'use strict'
|
||||
|
||||
import http = require('http');
|
||||
import bsock = require('bsock');
|
||||
import { PromiseIO } from "./PromiseIO/Server";
|
||||
import * as T from './Types';
|
||||
import * as U from './Utils';
|
||||
import * as I from './Interfaces';
|
||||
|
||||
export class RPCServer<
|
||||
InterfaceT extends T.RPCInterface = T.RPCInterface,
|
||||
> implements I.Destroyable {
|
||||
> {
|
||||
|
||||
private ws = http.createServer()
|
||||
private io = bsock.createServer()
|
||||
private pio = PromiseIO.createServer()
|
||||
private visibility: T.Visibility
|
||||
private closeHandler: T.CloseHandler
|
||||
private errorHandler: T.ErrorHandler
|
||||
@@ -42,7 +42,7 @@ export class RPCServer<
|
||||
})
|
||||
|
||||
|
||||
this.errorHandler = (socket: I.Socket) => (error: any, rpcName: string, args: any[]) => {
|
||||
this.errorHandler = (socket: I.Socket | PromiseIO) => (error: any, rpcName: string, args: any[]) => {
|
||||
if (conf.errorHandler) conf.errorHandler(socket, error, rpcName, args)
|
||||
else throw error
|
||||
}
|
||||
@@ -72,20 +72,24 @@ export class RPCServer<
|
||||
|
||||
private startWebsocket() {
|
||||
try {
|
||||
this.io.attach(this.ws)
|
||||
this.io.on('socket', (socket: I.Socket) => {
|
||||
this.pio.attach(this.ws)
|
||||
|
||||
this.pio.on('socket', (socket: I.Socket) => {
|
||||
socket.on('error', (err) => this.errorHandler(socket, err, "system", []))
|
||||
socket.on('close', () => this.closeHandler(socket))
|
||||
this.connectionHandler(socket)
|
||||
this.initRPCs(socket)
|
||||
})
|
||||
this.ws = this.ws.listen(this.port, this.visibility)
|
||||
|
||||
this.pio.listen(this.port)
|
||||
|
||||
} catch (e) {
|
||||
this.errorHandler(this.io, e, 'system', [])
|
||||
this.errorHandler(this.pio, e, 'system', [])
|
||||
}
|
||||
}
|
||||
|
||||
protected initRPCs(socket: I.Socket) {
|
||||
|
||||
socket.hook('info', async (sesame?: string) => {
|
||||
const rpcs = await Promise.all(this.exporters.map(async exp => {
|
||||
const allowed = await this.accessFilter(sesame, exp)
|
||||
@@ -96,22 +100,8 @@ export class RPCServer<
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Publishes a new list of Exporters. This destroys and restarts the socket
|
||||
* @param exporters the exporters to publish
|
||||
public setExporters(exporters: T.ExporterArray<InterfaceT>): any {
|
||||
exporters.forEach(U.fixNames)
|
||||
this.destroy()
|
||||
this.ws = http.createServer()
|
||||
this.io = bsock.createServer()
|
||||
this.exporters = exporters
|
||||
this.startWebsocket()
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
destroy(): void {
|
||||
this.io.close()
|
||||
close(): void {
|
||||
this.pio.close()
|
||||
this.ws.close()
|
||||
}
|
||||
}
|
||||
+42
-23
@@ -1,7 +1,6 @@
|
||||
'use strict'
|
||||
|
||||
import bsock = require('bsock');
|
||||
|
||||
import { PromiseIOClient } from './PromiseIO/Client'
|
||||
import * as T from './Types';
|
||||
import * as I from './Interfaces';
|
||||
import { stripAfterEquals, appendComma } from './Utils';
|
||||
@@ -18,8 +17,12 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
||||
}
|
||||
|
||||
private socket: I.Socket
|
||||
private closeHandlers: T.FrontEndHandlerType['close'][] = []
|
||||
private errorHandlers: T.FrontEndHandlerType['error'][] = []
|
||||
private handlers : {
|
||||
[name in string]: T.AnyFunction[]
|
||||
} = {
|
||||
error: [],
|
||||
close: []
|
||||
}
|
||||
private hooks : {[name in string]: T.AnyFunction} = {}
|
||||
|
||||
/**
|
||||
@@ -45,6 +48,19 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks a handler to a function name. Use {@link call} to trigger it.
|
||||
* @param name The function name to listen on
|
||||
* @param handler The handler to attach
|
||||
*/
|
||||
public bind(name: string, handler: (...args:any[]) => any | Promise<any>){
|
||||
if(!this.socket){
|
||||
this.hooks[name] = handler
|
||||
}else{
|
||||
this.socket.bind(name, handler)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a {@link hook} listener by name.
|
||||
* @param name The function name
|
||||
@@ -62,13 +78,12 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
||||
* @param type 'error' or 'close'
|
||||
* @param f The listener to attach
|
||||
*/
|
||||
public on<T extends "error" | "close">(type: T, f: T.FrontEndHandlerType[T]){
|
||||
public on(type: string, f: T.AnyFunction){
|
||||
if(!this.socket){
|
||||
switch(type){
|
||||
case "error": this.errorHandlers.push(<T.FrontEndHandlerType['error']> f); break;
|
||||
case "close": this.closeHandlers.push(<T.FrontEndHandlerType['close']> f); break;
|
||||
default: throw new Error('socket.on only supports ´error´ and ´close´ as first parameter. Got: ´'+type+'´')
|
||||
}
|
||||
if(!this.handlers[type])
|
||||
this.handlers[type] = []
|
||||
|
||||
this.handlers[type].push(f)
|
||||
}else{
|
||||
this.socket.on(type, f)
|
||||
}
|
||||
@@ -84,14 +99,6 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
||||
this.socket.emit(eventName, data)
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the socket
|
||||
*/
|
||||
public destroy(){
|
||||
if(!this.socket) return;
|
||||
this.socket.destroy()
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the socket. It may attempt to reconnect.
|
||||
*/
|
||||
@@ -108,7 +115,8 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
||||
public async call (rpcname: string, ...args: any[]) : Promise<any>{
|
||||
if(!this.socket) throw new Error("The socket is not connected! Use socket.connect() first")
|
||||
try{
|
||||
return await this.socket.call.apply(this.socket, [rpcname, ...args])
|
||||
const val = await this.socket.call.apply(this.socket, [rpcname, ...args])
|
||||
return val
|
||||
}catch(e){
|
||||
this.emit('error', e)
|
||||
throw e
|
||||
@@ -129,14 +137,23 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
||||
* Connects to the server and attaches available RPCs to this object
|
||||
*/
|
||||
public async connect( sesame?: string ) : Promise<T.ConnectedSocket<Ifc>> {
|
||||
this.socket = await bsock.connect(this.port, this.server, this.conf.tls?this.conf.tls:false)
|
||||
this.errorHandlers.forEach(h => this.socket.on('error', h))
|
||||
this.closeHandlers.forEach(h => this.socket.on('close', h))
|
||||
|
||||
try{
|
||||
this.socket = await PromiseIOClient.connect(this.port, this.server, /*this.conf.tls?this.conf.tls:false*/)
|
||||
}catch(e){
|
||||
this.handlers['error'].forEach(h => h(e))
|
||||
throw e
|
||||
}
|
||||
|
||||
Object.entries(this.handlers).forEach(([k,v])=>{
|
||||
v.forEach(h => this.socket.on(k, h))
|
||||
})
|
||||
|
||||
Object.entries(this.hooks).forEach((kv: [string, T.AnyFunction]) => {
|
||||
this.socket.hook(kv[0], kv[1])
|
||||
})
|
||||
|
||||
const info:T.ExtendedRpcInfo[] = await this.info(sesame)
|
||||
|
||||
info.forEach(i => {
|
||||
let f: any
|
||||
|
||||
@@ -153,6 +170,8 @@ export class RPCSocket<Ifc extends T.RPCInterface = T.RPCInterface> implements I
|
||||
this[i.owner][i.name] = f
|
||||
this[i.owner][i.name].bind(this)
|
||||
})
|
||||
|
||||
|
||||
return <T.ConnectedSocket<Ifc>> (this as any)
|
||||
}
|
||||
|
||||
|
||||
+11
-16
@@ -12,20 +12,15 @@ export type RPCExporter<
|
||||
exportRPCs() : T.RPCDefinitions<Ifc>[Name]
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic socket interface that can apply to bsock as well as RPCSocket
|
||||
*/
|
||||
export interface Socket extends Destroyable {
|
||||
port: number
|
||||
hook: (rpcname: string, handler: T.AnyFunction) => void
|
||||
unhook: (rpcname:string) => void
|
||||
call: (rpcname:string, ...args: any[]) => Promise<any>
|
||||
fire: (rpcname:string, ...args: any[]) => Promise<any>
|
||||
on: T.OnFunction
|
||||
emit: (eventName: string, data:any) => void
|
||||
close() : void
|
||||
}
|
||||
export interface Socket {
|
||||
id?: string
|
||||
bind: (name: string, listener: T.PioBindListener) => void
|
||||
|
||||
export interface Destroyable{
|
||||
destroy() : void
|
||||
}
|
||||
hook: (rpcname: string, handler: T.PioHookListener) => void
|
||||
unhook: (rpcname: string, listener?:T.AnyFunction) => void
|
||||
call: (rpcname: string, ...args: any[]) => Promise<any>
|
||||
fire: (rpcname: string, ...args: any[]) => Promise<any>
|
||||
on: (type: string, f: T.AnyFunction)=>any
|
||||
emit: (eventName: string, data: any) => void
|
||||
close(): void
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Socket } from "socket.io"
|
||||
import * as U from '../Utils'
|
||||
import * as I from '../Interfaces'
|
||||
import * as socketio from 'socket.io-client'
|
||||
|
||||
export class PromiseIOClient {
|
||||
|
||||
static connect = (port: number, host = "localhost"): Promise<I.Socket> => new Promise((res, rej) => {
|
||||
try {
|
||||
const socket = socketio(`http://${host}:${port}`, {
|
||||
reconnectionAttempts: 2,
|
||||
reconnectionDelay: 200,
|
||||
timeout: 450,
|
||||
reconnection: false
|
||||
})
|
||||
socket.on('connect_error', e => {
|
||||
sock.emit('error', e)
|
||||
rej(e)
|
||||
})
|
||||
|
||||
const sock = U.makePioSocket(socket)
|
||||
socket.on('connect', ()=>{ res(sock) })
|
||||
|
||||
|
||||
/*
|
||||
socket.on('connect_timeout', ()=>console.log('connect_timeout'))
|
||||
socket.on('disconnect', ()=>console.log('disconnect'))
|
||||
socket.on('reconnect', ()=>console.log('reconnect'))
|
||||
socket.on('reconnect_attempt', ()=>console.log('reconnect_attempt'))
|
||||
socket.on('reconnecting', ()=>console.log('reconnecting'));
|
||||
socket.on('reconnect_failed', ()=>console.log('reconnect_failed'));
|
||||
socket.on('reconnecting', ()=>console.log('reconnecting'));
|
||||
*/
|
||||
} catch (e) {
|
||||
rej(e)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
import { Server, Socket } from "socket.io"
|
||||
import { Server as httpServer } from "http"
|
||||
import * as U from '../Utils'
|
||||
import * as T from '../Types'
|
||||
const socketio = require('socket.io')
|
||||
|
||||
export class PromiseIO {
|
||||
io?: Server
|
||||
private listeners: { [eventName in string]: ((...args: any) => void)[] } = {
|
||||
socket: [],
|
||||
connect: []
|
||||
}
|
||||
|
||||
static createServer(): PromiseIO {
|
||||
return new PromiseIO();
|
||||
}
|
||||
|
||||
attach(httpServer: httpServer) {
|
||||
this.io = socketio(httpServer)
|
||||
}
|
||||
|
||||
listen(port: number) {
|
||||
this.io!.on('connection', (sock: Socket) => {
|
||||
const pioSock = U.makePioSocket(sock)
|
||||
this.listeners['socket'].forEach(listener => listener(pioSock))
|
||||
this.listeners['connect'].forEach(listener => listener(pioSock))
|
||||
/*
|
||||
pioSock.on('error', ()=>console.log('error'));
|
||||
|
||||
pioSock.on('connect_timeout', ()=>console.log('connect_timeout'))
|
||||
pioSock.on('disconnect', ()=>console.log('disconnect'))
|
||||
pioSock.on('reconnect', ()=>console.log('reconnect'))
|
||||
pioSock.on('reconnect_attempt', ()=>console.log('reconnect_attempt'))
|
||||
pioSock.on('reconnecting', ()=>console.log('reconnecting'));
|
||||
pioSock.on('reconnect_failed', ()=>console.log('reconnect_failed'));
|
||||
pioSock.on('reconnecting', ()=>console.log('reconnecting'));
|
||||
*/
|
||||
})
|
||||
this.io!.listen(port)
|
||||
}
|
||||
|
||||
on(eventName: string, listener: T.AnyFunction) {
|
||||
if (this.listeners[eventName] == null) {
|
||||
this.listeners[eventName] = []
|
||||
}
|
||||
this.listeners[eventName].push(listener)
|
||||
}
|
||||
|
||||
close = () => {
|
||||
if(this.io){
|
||||
this.io.engine.ws.close()
|
||||
this.io.close()
|
||||
this.io = undefined
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+7
-1
@@ -1,12 +1,18 @@
|
||||
import * as I from "./Interfaces";
|
||||
import { RPCSocket } from "./Frontend";
|
||||
import { PromiseIO } from "./PromiseIO/Server";
|
||||
|
||||
export type PioBindListener = (...args: any) => void
|
||||
export type PioHookListener = AnyFunction
|
||||
|
||||
|
||||
|
||||
export type AnyFunction = (...args:any) => any
|
||||
export type HookFunction = AnyFunction
|
||||
export type AccessFilter<InterfaceT extends RPCInterface = RPCInterface> = (sesame:string|undefined, exporter: I.RPCExporter<InterfaceT, keyof InterfaceT>) => Promise<boolean> | boolean
|
||||
export type Visibility = "127.0.0.1" | "0.0.0.0"
|
||||
export type ConnectionHandler = (socket:I.Socket) => void
|
||||
export type ErrorHandler = (socket:I.Socket, error:any, rpcName: string, args: any[]) => void
|
||||
export type ErrorHandler = (socket:I.Socket | PromiseIO, error:any, rpcName: string, args: any[]) => void
|
||||
export type CloseHandler = (socket:I.Socket) => void
|
||||
export type SesameFunction = (sesame : string) => boolean
|
||||
export type SesameConf = {
|
||||
|
||||
+121
-36
@@ -2,6 +2,8 @@ import * as uuidv4 from "uuid/v4"
|
||||
|
||||
import * as T from "./Types";
|
||||
import * as I from "./Interfaces";
|
||||
import { Server as ioServer, Socket as ioSocket, Socket } from "socket.io"
|
||||
import { Socket as ioClientSocket } from "socket.io-client"
|
||||
|
||||
/**
|
||||
* Translate an RPC to RPCInfo for serialization.
|
||||
@@ -11,18 +13,18 @@ import * as I from "./Interfaces";
|
||||
* @param sesame optional sesame phrase to prepend before all RPC arguments
|
||||
* @throws Error on RPC without name property
|
||||
*/
|
||||
export const rpcToRpcinfo = (socket: I.Socket, rpc : T.RPC<any, any>, owner: string, errorHandler: T.ErrorHandler, sesame?:T.SesameFunction):T.RpcInfo => {
|
||||
switch (typeof rpc){
|
||||
export const rpcToRpcinfo = (socket: I.Socket, rpc: T.RPC<any, any>, owner: string, errorHandler: T.ErrorHandler, sesame?: T.SesameFunction): T.RpcInfo => {
|
||||
switch (typeof rpc) {
|
||||
case "object":
|
||||
if(rpc['call']){
|
||||
if (rpc['call']) {
|
||||
return {
|
||||
owner: owner,
|
||||
argNames: extractArgs(rpc['call']),
|
||||
type: "Call",
|
||||
name: rpc.name,
|
||||
call: sesame?async (_sesame, ...args) => {if(sesame(_sesame)) return await rpc['call'].apply({}, args); socket.destroy()}:rpc['call'], // check & remove sesame
|
||||
call: sesame ? async (_sesame, ...args) => { if (sesame(_sesame)) return await rpc['call'].apply({}, args); socket.close() } : rpc['call'], // check & remove sesame
|
||||
}
|
||||
}else{
|
||||
} else {
|
||||
const generator = hookGenerator(<T.HookRPC<any, any>>rpc, errorHandler, sesame)
|
||||
return {
|
||||
owner: owner,
|
||||
@@ -33,7 +35,7 @@ export const rpcToRpcinfo = (socket: I.Socket, rpc : T.RPC<any, any>, owner: str
|
||||
}
|
||||
}
|
||||
case "function":
|
||||
if(!rpc.name) throw new Error(`
|
||||
if (!rpc.name) throw new Error(`
|
||||
RPC did not provide a name.
|
||||
\nUse 'funtion name(..){ .. }' syntax instead.
|
||||
\n
|
||||
@@ -41,14 +43,14 @@ RPC did not provide a name.
|
||||
\n${rpc.toString()}
|
||||
\n>------------OFFENDING RPC`)
|
||||
return {
|
||||
owner : owner,
|
||||
owner: owner,
|
||||
argNames: extractArgs(rpc),
|
||||
type: "Call",
|
||||
name: rpc.name,
|
||||
call: sesame?async (_sesame, ...args) => {if(sesame(_sesame)) return await rpc.apply({}, args); throw makeError(rpc.name)}:rpc, // check & remove sesame
|
||||
call: sesame ? async (_sesame, ...args) => { if (sesame(_sesame)) return await rpc.apply({}, args); throw makeError(rpc.name) } : rpc, // check & remove sesame
|
||||
}
|
||||
}
|
||||
throw new Error("Bad socketIORPC type "+ typeof rpc)
|
||||
throw new Error("Bad socketIORPC type " + typeof rpc)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,16 +59,16 @@ RPC did not provide a name.
|
||||
* @param exporter The exporter
|
||||
* @param makeUnique @default true Attach a suffix to RPC names
|
||||
*/
|
||||
export function rpcHooker(socket: I.Socket, exporter:I.RPCExporter<any, any>, errorHandler: T.ErrorHandler, sesame?:T.SesameFunction, makeUnique = true):T.ExtendedRpcInfo[]{
|
||||
export function rpcHooker(socket: I.Socket, exporter: I.RPCExporter<any, any>, errorHandler: T.ErrorHandler, sesame?: T.SesameFunction, makeUnique = true): T.ExtendedRpcInfo[] {
|
||||
const owner = exporter.name
|
||||
const RPCs = exporter.exportRPCs()
|
||||
|
||||
return RPCs.map(rpc => rpcToRpcinfo(socket, rpc, owner, errorHandler, sesame))
|
||||
.map(info => {
|
||||
const suffix = makeUnique?"-"+uuidv4().substr(0,4):""
|
||||
const ret:any = info
|
||||
ret.uniqueName = info.name+suffix
|
||||
let rpcFunction = info.type === 'Hook'? info.generator(socket)
|
||||
const suffix = makeUnique ? "-" + uuidv4().substr(0, 4) : ""
|
||||
const ret: any = info
|
||||
ret.uniqueName = info.name + suffix
|
||||
let rpcFunction = info.type === 'Hook' ? info.generator(socket)
|
||||
: info.call
|
||||
|
||||
socket.hook(ret.uniqueName, callGenerator(info.name, socket, rpcFunction, errorHandler))
|
||||
@@ -78,16 +80,16 @@ export function rpcHooker(socket: I.Socket, exporter:I.RPCExporter<any, any>, er
|
||||
* Decorate an RPC with the error handler
|
||||
* @param rpcFunction the function to decorate
|
||||
*/
|
||||
const callGenerator = (rpcName : string, socket: I.Socket, rpcFunction : T.AnyFunction, errorHandler: T.ErrorHandler) : T.AnyFunction => {
|
||||
const callGenerator = (rpcName: string, socket: I.Socket, rpcFunction: T.AnyFunction, errorHandler: T.ErrorHandler): T.AnyFunction => {
|
||||
const argsArr = extractArgs(rpcFunction)
|
||||
const args = argsArr.join(',')
|
||||
const argsStr = argsArr.map(stripAfterEquals).join(',')
|
||||
|
||||
return eval(`async (`+args+`) => {
|
||||
return eval(`async (` + args + `) => {
|
||||
try{
|
||||
return await rpcFunction(`+argsStr+`)
|
||||
return await rpcFunction(`+ argsStr + `)
|
||||
}catch(e){
|
||||
errorHandler(socket)(e, rpcName, [`+args+`])
|
||||
errorHandler(socket)(e, rpcName, [`+ args + `])
|
||||
}
|
||||
}`)
|
||||
}
|
||||
@@ -96,7 +98,7 @@ const callGenerator = (rpcName : string, socket: I.Socket, rpcFunction : T.AnyFu
|
||||
* Utility function to strip parameters like "a = 3" of their defaults
|
||||
* @param str The parameter to modify
|
||||
*/
|
||||
export function stripAfterEquals(str:string):string{
|
||||
export function stripAfterEquals(str: string): string {
|
||||
return str.split("=")[0]
|
||||
}
|
||||
|
||||
@@ -105,13 +107,14 @@ export function stripAfterEquals(str:string):string{
|
||||
* @param rpc The RPC to transform
|
||||
* @returns A {@link HookFunction}
|
||||
*/
|
||||
const hookGenerator = (rpc:T.HookRPC<any, any>, /*not unused!*/ errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction): T.HookInfo['generator'] => {
|
||||
const hookGenerator = (rpc: T.HookRPC<any, any>, /*not unused!*/ errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction): T.HookInfo['generator'] => {
|
||||
|
||||
let argsArr = extractArgs(rpc.hook)
|
||||
argsArr.pop() //remove 'callback' from the end
|
||||
let callArgs = argsArr.join(',')
|
||||
|
||||
const args = sesameFn?(['sesame', ...argsArr].join(','))
|
||||
:callArgs
|
||||
const args = sesameFn ? (['sesame', ...argsArr].join(','))
|
||||
: callArgs
|
||||
|
||||
callArgs = appendComma(callArgs, false)
|
||||
|
||||
@@ -139,35 +142,35 @@ const hookGenerator = (rpc:T.HookRPC<any, any>, /*not unused!*/ errorHandler: T.
|
||||
}
|
||||
|
||||
const makeError = (callName: string) => {
|
||||
return new Error("Call not found: "+callName+". ; Zone: <root> ; Task: Promise.then ; Value: Error: Call not found: "+callName)
|
||||
return new Error("Call not found: " + callName + ". ; Zone: <root> ; Task: Promise.then ; Value: Error: Call not found: " + callName)
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a string list of parameters from a function
|
||||
* @param f The source function
|
||||
*/
|
||||
const extractArgs = (f:Function):string[] => {
|
||||
let fn:string
|
||||
fn = (fn = String(f)).substr(0, fn.indexOf(")")).substr(fn.indexOf("(")+1)
|
||||
return fn!==""?fn.split(',') : []
|
||||
const extractArgs = (f: Function): string[] => {
|
||||
let fn: string
|
||||
fn = (fn = String(f)).substr(0, fn.indexOf(")")).substr(fn.indexOf("(") + 1)
|
||||
return fn !== "" ? fn.split(',') : []
|
||||
}
|
||||
|
||||
|
||||
export function makeSesameFunction (sesame : T.SesameFunction | string) : T.SesameFunction {
|
||||
if(typeof sesame === 'function'){
|
||||
export function makeSesameFunction(sesame: T.SesameFunction | string): T.SesameFunction {
|
||||
if (typeof sesame === 'function') {
|
||||
return sesame
|
||||
}
|
||||
|
||||
return (testSesame : string) => {
|
||||
return (testSesame: string) => {
|
||||
return testSesame === sesame
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function appendComma(s?:string, turnToString = true):string{
|
||||
if(turnToString)
|
||||
return s?`'${s}',`:""
|
||||
return s?`${s},`:""
|
||||
export function appendComma(s?: string, turnToString = true): string {
|
||||
if (turnToString)
|
||||
return s ? `'${s}',` : ""
|
||||
return s ? `${s},` : ""
|
||||
}
|
||||
|
||||
|
||||
@@ -176,12 +179,94 @@ export function appendComma(s?:string, turnToString = true):string{
|
||||
* This was supposedly fixed (https://github.com/microsoft/TypeScript/issues/5611) but it still is the case.
|
||||
* This function sets the name value for all object members that are functions.
|
||||
*/
|
||||
export function fixNames(o:Object):void{
|
||||
export function fixNames(o: Object): void {
|
||||
Object.keys(o).forEach(key => {
|
||||
if(typeof o[key] === 'function' && !o[key].name){
|
||||
if (typeof o[key] === 'function' && !o[key].name) {
|
||||
Object.defineProperty(o[key], 'name', {
|
||||
value: key
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const makePioSocket = (socket: any): I.Socket => {
|
||||
return {
|
||||
bind: (name: string, listener: T.PioBindListener) => socket.on(name, (...args: any) => {
|
||||
const ack = args.pop()
|
||||
listener.apply(null, args)
|
||||
ack()
|
||||
}),
|
||||
|
||||
hook: (name: string, listener: T.PioHookListener) => {
|
||||
const args = extractArgs(listener)
|
||||
let argNames
|
||||
let restParam = args.find(e => e.includes('...'))
|
||||
if(!restParam){
|
||||
argNames = [...args, '...__args__'].join(',')
|
||||
restParam = '__args__'
|
||||
}else{
|
||||
argNames = [...args].join(',')
|
||||
restParam = restParam.replace('...','')
|
||||
}
|
||||
|
||||
const decoratedListener = eval(`(() => async (${argNames}) => {
|
||||
const __ack__ = ${restParam}.pop()
|
||||
try{
|
||||
const response = await listener.apply(null, [${argNames}])
|
||||
__ack__(response)
|
||||
}catch(e){
|
||||
__ack__({
|
||||
...e,
|
||||
stack: e.stack,
|
||||
message: e.message,
|
||||
name: e.name,
|
||||
})
|
||||
}
|
||||
})()`)
|
||||
socket.on(name, decoratedListener)
|
||||
},
|
||||
|
||||
call: (name: string, ...args: any) => {
|
||||
return new Promise((res, rej) => {
|
||||
const params: any = [name, ...args, (resp) => {
|
||||
if(isError(resp)){
|
||||
const err = new Error()
|
||||
err.stack = resp.stack
|
||||
err.name = resp.name
|
||||
err.message = resp.message
|
||||
return rej(err)
|
||||
}
|
||||
res(resp)
|
||||
}]
|
||||
socket.emit.apply(socket, params)
|
||||
})
|
||||
},
|
||||
|
||||
fire: (name: string, ...args: any) => new Promise((res, rej) => {
|
||||
const params: any = [name, ...args]
|
||||
socket.emit.apply(socket, params)
|
||||
res()
|
||||
}),
|
||||
|
||||
unhook: (name: string, listener?: T.AnyFunction) => {
|
||||
if (listener) {
|
||||
socket.removeListener(name, listener)
|
||||
} else {
|
||||
socket.removeAllListeners(name)
|
||||
}
|
||||
},
|
||||
|
||||
id: socket.id,
|
||||
on: (...args) => socket.on.apply(socket, args),
|
||||
emit: (...args) => socket.emit.apply(socket, args),
|
||||
close: () => {
|
||||
socket
|
||||
socket.disconnect(true)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const isError = function(e){
|
||||
return e && e.stack && e.message && typeof e.stack === 'string'
|
||||
&& typeof e.message === 'string';
|
||||
}
|
||||
|
||||
+46
-33
@@ -68,8 +68,8 @@ describe('RPCServer', () => {
|
||||
})
|
||||
|
||||
after(done => {
|
||||
client.destroy()
|
||||
server.destroy()
|
||||
client.close()
|
||||
server.close()
|
||||
|
||||
done()
|
||||
})
|
||||
@@ -116,8 +116,8 @@ describe('RPCSocket', () => {
|
||||
})
|
||||
|
||||
after(() => {
|
||||
client.destroy()
|
||||
server.destroy()
|
||||
client.close()
|
||||
server.close()
|
||||
})
|
||||
|
||||
|
||||
@@ -221,8 +221,8 @@ describe('It should do unhook', () => {
|
||||
})
|
||||
|
||||
after(() => {
|
||||
client.destroy()
|
||||
server.destroy()
|
||||
client.close()
|
||||
server.close()
|
||||
})
|
||||
|
||||
it('Subscribe with param', (done) => {
|
||||
@@ -314,8 +314,8 @@ describe('Sesame should unlock the socket', () => {
|
||||
})
|
||||
|
||||
after(() => {
|
||||
client.destroy()
|
||||
server.destroy()
|
||||
client.close()
|
||||
server.close()
|
||||
})
|
||||
|
||||
it('should work with sesame', (done) => {
|
||||
@@ -337,8 +337,8 @@ describe('Sesame should unlock the socket', () => {
|
||||
else {
|
||||
done(new Error("Function supposed to be removed without sesame"))
|
||||
}
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
cli.close()
|
||||
sock.close()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -350,8 +350,8 @@ describe('Sesame should unlock the socket', () => {
|
||||
else {
|
||||
done(new Error("Function supposed to be removed without sesame"))
|
||||
}
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
cli.close()
|
||||
sock.close()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -405,9 +405,9 @@ describe('Error handling', () => {
|
||||
done(e)
|
||||
})
|
||||
.finally(() => {
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
server.destroy()
|
||||
cli.close()
|
||||
sock.close()
|
||||
server.close()
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -440,9 +440,9 @@ describe('Error handling', () => {
|
||||
done(e)
|
||||
})
|
||||
.finally(() => {
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
server.destroy()
|
||||
cli.close()
|
||||
sock.close()
|
||||
server.close()
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -484,9 +484,9 @@ describe("Errorhandler functionality", () => {
|
||||
done(new Error("UNEXPECTED CLIENT ERROR " + e.message))
|
||||
})
|
||||
.finally(() => {
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
server.destroy()
|
||||
cli.close()
|
||||
sock.close()
|
||||
server.close()
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -523,9 +523,9 @@ describe("Errorhandler functionality", () => {
|
||||
done(e)
|
||||
})
|
||||
.finally(() => {
|
||||
cli.destroy()
|
||||
sock.destroy()
|
||||
server.destroy()
|
||||
cli.close()
|
||||
sock.close()
|
||||
server.close()
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -595,12 +595,12 @@ describe("Class binding", () => {
|
||||
})
|
||||
|
||||
afterEach((done) => {
|
||||
sock.destroy()
|
||||
sock.close()
|
||||
done()
|
||||
})
|
||||
|
||||
after(() => {
|
||||
serv.destroy()
|
||||
serv.close()
|
||||
})
|
||||
|
||||
/* The server-side socket will enter a 30s timeout if destroyed by a RPC.
|
||||
@@ -663,26 +663,38 @@ describe("attaching handlers before connecting", () => {
|
||||
}).catch(e => {
|
||||
//catch clause fires second
|
||||
if (errorHandleCount != 1) {
|
||||
console.log("catch clause didn't fire second");
|
||||
console.log("catch clause didn't fire second", errorHandleCount);
|
||||
} else {
|
||||
sock.destroy()
|
||||
sock.close()
|
||||
done()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
/*
|
||||
* ## 1.11.0 breaking ##
|
||||
*
|
||||
* API change: Move from bsock to socketio changes underlying API for when errors are thrown.
|
||||
* socketio does not throw on unknown listener. This behaviour is considered more consistent with the design
|
||||
* goals of RPClibrary and was thus adopted
|
||||
*
|
||||
|
||||
|
||||
it("fires error if call is unknown", (done) => {
|
||||
const serv = new RPCServer(21004)
|
||||
const sock = new RPCSocket(21004, 'localhost')
|
||||
|
||||
sock.on('error', (err) => {
|
||||
sock.destroy()
|
||||
serv.destroy()
|
||||
sock.close()
|
||||
serv.close()
|
||||
done()
|
||||
})
|
||||
|
||||
sock.connect().then(_ => {
|
||||
sock.call("unknownRPC123", "AAAAA").catch(e => { /* ignore */ })
|
||||
sock.call("unknownRPC123", "AAAAA").catch(e => { }).then(x => {
|
||||
console.log("X",x);
|
||||
|
||||
})
|
||||
}).catch(e => {
|
||||
console.log("unexpected connect catch clause");
|
||||
done(e)
|
||||
@@ -695,8 +707,8 @@ describe("attaching handlers before connecting", () => {
|
||||
|
||||
sock.connect().then(_ => {
|
||||
sock.call("unknownRPC123", "AAAAA").catch(e => {
|
||||
sock.destroy()
|
||||
serv.destroy()
|
||||
sock.close()
|
||||
serv.close()
|
||||
done()
|
||||
})
|
||||
}).catch(e => {
|
||||
@@ -704,6 +716,7 @@ describe("attaching handlers before connecting", () => {
|
||||
done(e)
|
||||
})
|
||||
})
|
||||
*/
|
||||
|
||||
})
|
||||
|
||||
|
||||
+1
-1
@@ -9,6 +9,6 @@
|
||||
"strict": true,
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "test/**/*.ts", "Index.ts", "demo.ts"],
|
||||
"include": ["src/**/*.ts", "test/**/*.ts", "Index.ts", "demo.ts", "scratchpad.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
Reference in New Issue
Block a user