Browse Source

socketio drop in for bsock

master
peter 3 years ago
parent
commit
2a67927306
12 changed files with 782 additions and 152 deletions
  1. 377
    7
      package-lock.json
  2. 5
    1
      package.json
  3. 53
    0
      scratchpad.ts
  4. 14
    24
      src/Backend.ts
  5. 42
    23
      src/Frontend.ts
  6. 12
    17
      src/Interfaces.ts
  7. 38
    0
      src/PromiseIO/Client.ts
  8. 57
    0
      src/PromiseIO/Server.ts
  9. 7
    1
      src/Types.ts
  10. 130
    45
      src/Utils.ts
  11. 46
    33
      test/Test.ts
  12. 1
    1
      tsconfig.json

+ 377
- 7
package-lock.json View File

1
 {
1
 {
2
   "name": "rpclibrary",
2
   "name": "rpclibrary",
3
-  "version": "1.9.2",
3
+  "version": "1.10.2",
4
   "lockfileVersion": 1,
4
   "lockfileVersion": 1,
5
   "requires": true,
5
   "requires": true,
6
   "dependencies": {
6
   "dependencies": {
247
       "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
247
       "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
248
       "dev": true
248
       "dev": true
249
     },
249
     },
250
+    "@types/engine.io": {
251
+      "version": "3.1.4",
252
+      "resolved": "https://registry.npmjs.org/@types/engine.io/-/engine.io-3.1.4.tgz",
253
+      "integrity": "sha512-98rXVukLD6/ozrQ2O80NAlWDGA4INg+tqsEReWJldqyi2fulC9V7Use/n28SWgROXKm6003ycWV4gZHoF8GA6w==",
254
+      "requires": {
255
+        "@types/node": "*"
256
+      }
257
+    },
250
     "@types/expect": {
258
     "@types/expect": {
251
       "version": "1.20.4",
259
       "version": "1.20.4",
252
       "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz",
260
       "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz",
275
     "@types/node": {
283
     "@types/node": {
276
       "version": "11.15.2",
284
       "version": "11.15.2",
277
       "resolved": "https://registry.npmjs.org/@types/node/-/node-11.15.2.tgz",
285
       "resolved": "https://registry.npmjs.org/@types/node/-/node-11.15.2.tgz",
278
-      "integrity": "sha512-BqCU9uIFkUH9Sgo2uLYbmIiFB1T+VBiM8AI/El3LIAI5KzwtckeSG+3WOYZr9aMoX4UIvRFBWBeSaOu6hFue2Q==",
279
-      "dev": true
286
+      "integrity": "sha512-BqCU9uIFkUH9Sgo2uLYbmIiFB1T+VBiM8AI/El3LIAI5KzwtckeSG+3WOYZr9aMoX4UIvRFBWBeSaOu6hFue2Q=="
287
+    },
288
+    "@types/socket.io": {
289
+      "version": "2.1.8",
290
+      "resolved": "https://registry.npmjs.org/@types/socket.io/-/socket.io-2.1.8.tgz",
291
+      "integrity": "sha512-NIQfh9WwJuJKlgmby4NgwMpoBOmNPCDgaRNPiLYZBtkbHkszK/9R52B5yGkd5a34rbVdAADuo8FhOS/5AZDemw==",
292
+      "requires": {
293
+        "@types/engine.io": "*",
294
+        "@types/node": "*"
295
+      }
296
+    },
297
+    "@types/socket.io-client": {
298
+      "version": "1.4.33",
299
+      "resolved": "https://registry.npmjs.org/@types/socket.io-client/-/socket.io-client-1.4.33.tgz",
300
+      "integrity": "sha512-m4LnxkljsI9fMsjwpW5QhRpMixo2BeeLpFmg0AE+sS4H1pzAd/cs/ftTiL60FLZgfFa8PFRPx5KsHu8O0bADKQ=="
280
     },
301
     },
281
     "@webassemblyjs/ast": {
302
     "@webassemblyjs/ast": {
282
       "version": "1.8.5",
303
       "version": "1.8.5",
466
       "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
487
       "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
467
       "dev": true
488
       "dev": true
468
     },
489
     },
490
+    "accepts": {
491
+      "version": "1.3.7",
492
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
493
+      "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
494
+      "requires": {
495
+        "mime-types": "~2.1.24",
496
+        "negotiator": "0.6.2"
497
+      }
498
+    },
469
     "acorn": {
499
     "acorn": {
470
       "version": "6.4.1",
500
       "version": "6.4.1",
471
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
501
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz",
472
       "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
502
       "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==",
473
       "dev": true
503
       "dev": true
474
     },
504
     },
505
+    "after": {
506
+      "version": "0.8.2",
507
+      "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
508
+      "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
509
+    },
475
     "aggregate-error": {
510
     "aggregate-error": {
476
       "version": "3.0.1",
511
       "version": "3.0.1",
477
       "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
512
       "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
602
       "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
637
       "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
603
       "dev": true
638
       "dev": true
604
     },
639
     },
640
+    "arraybuffer.slice": {
641
+      "version": "0.0.7",
642
+      "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
643
+      "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog=="
644
+    },
605
     "arrify": {
645
     "arrify": {
606
       "version": "1.0.1",
646
       "version": "1.0.1",
607
       "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
647
       "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
658
       "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
698
       "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
659
       "dev": true
699
       "dev": true
660
     },
700
     },
701
+    "async-limiter": {
702
+      "version": "1.0.1",
703
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
704
+      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
705
+    },
661
     "atob": {
706
     "atob": {
662
       "version": "2.1.2",
707
       "version": "2.1.2",
663
       "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
708
       "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
673
         "underscore": ">=1.8.3"
718
         "underscore": ">=1.8.3"
674
       }
719
       }
675
     },
720
     },
721
+    "backo2": {
722
+      "version": "1.0.2",
723
+      "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
724
+      "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
725
+    },
676
     "balanced-match": {
726
     "balanced-match": {
677
       "version": "1.0.0",
727
       "version": "1.0.0",
678
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
728
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
734
         }
784
         }
735
       }
785
       }
736
     },
786
     },
787
+    "base64-arraybuffer": {
788
+      "version": "0.1.5",
789
+      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
790
+      "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
791
+    },
737
     "base64-js": {
792
     "base64-js": {
738
       "version": "1.3.1",
793
       "version": "1.3.1",
739
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
794
       "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
740
       "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
795
       "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
741
       "dev": true
796
       "dev": true
742
     },
797
     },
798
+    "base64id": {
799
+      "version": "2.0.0",
800
+      "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
801
+      "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
802
+    },
803
+    "better-assert": {
804
+      "version": "1.0.2",
805
+      "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
806
+      "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
807
+      "requires": {
808
+        "callsite": "1.0.0"
809
+      }
810
+    },
743
     "big.js": {
811
     "big.js": {
744
       "version": "5.2.2",
812
       "version": "5.2.2",
745
       "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
813
       "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
752
       "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
820
       "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
753
       "dev": true
821
       "dev": true
754
     },
822
     },
823
+    "blob": {
824
+      "version": "0.0.5",
825
+      "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
826
+      "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
827
+    },
755
     "bluebird": {
828
     "bluebird": {
756
       "version": "3.7.2",
829
       "version": "3.7.2",
757
       "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
830
       "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
1013
         }
1086
         }
1014
       }
1087
       }
1015
     },
1088
     },
1089
+    "callsite": {
1090
+      "version": "1.0.0",
1091
+      "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
1092
+      "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA="
1093
+    },
1016
     "camelcase": {
1094
     "camelcase": {
1017
       "version": "5.3.1",
1095
       "version": "5.3.1",
1018
       "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
1096
       "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
1191
       "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
1269
       "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
1192
       "dev": true
1270
       "dev": true
1193
     },
1271
     },
1272
+    "component-bind": {
1273
+      "version": "1.0.0",
1274
+      "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
1275
+      "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
1276
+    },
1194
     "component-emitter": {
1277
     "component-emitter": {
1195
       "version": "1.3.0",
1278
       "version": "1.3.0",
1196
       "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
1279
       "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
1197
-      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
1198
-      "dev": true
1280
+      "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
1281
+    },
1282
+    "component-inherit": {
1283
+      "version": "0.0.3",
1284
+      "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
1285
+      "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
1199
     },
1286
     },
1200
     "concat-map": {
1287
     "concat-map": {
1201
       "version": "0.0.1",
1288
       "version": "0.0.1",
1236
         "safe-buffer": "~5.1.1"
1323
         "safe-buffer": "~5.1.1"
1237
       }
1324
       }
1238
     },
1325
     },
1326
+    "cookie": {
1327
+      "version": "0.3.1",
1328
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
1329
+      "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
1330
+    },
1239
     "copy-concurrently": {
1331
     "copy-concurrently": {
1240
       "version": "1.0.5",
1332
       "version": "1.0.5",
1241
       "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
1333
       "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
1517
         "once": "^1.4.0"
1609
         "once": "^1.4.0"
1518
       }
1610
       }
1519
     },
1611
     },
1612
+    "engine.io": {
1613
+      "version": "3.4.2",
1614
+      "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.2.tgz",
1615
+      "integrity": "sha512-b4Q85dFkGw+TqgytGPrGgACRUhsdKc9S9ErRAXpPGy/CXKs4tYoHDkvIRdsseAF7NjfVwjRFIn6KTnbw7LwJZg==",
1616
+      "requires": {
1617
+        "accepts": "~1.3.4",
1618
+        "base64id": "2.0.0",
1619
+        "cookie": "0.3.1",
1620
+        "debug": "~4.1.0",
1621
+        "engine.io-parser": "~2.2.0",
1622
+        "ws": "^7.1.2"
1623
+      },
1624
+      "dependencies": {
1625
+        "debug": {
1626
+          "version": "4.1.1",
1627
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
1628
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
1629
+          "requires": {
1630
+            "ms": "^2.1.1"
1631
+          }
1632
+        }
1633
+      }
1634
+    },
1635
+    "engine.io-client": {
1636
+      "version": "3.4.3",
1637
+      "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.3.tgz",
1638
+      "integrity": "sha512-0NGY+9hioejTEJCaSJZfWZLk4FPI9dN+1H1C4+wj2iuFba47UgZbJzfWs4aNFajnX/qAaYKbe2lLTfEEWzCmcw==",
1639
+      "requires": {
1640
+        "component-emitter": "~1.3.0",
1641
+        "component-inherit": "0.0.3",
1642
+        "debug": "~4.1.0",
1643
+        "engine.io-parser": "~2.2.0",
1644
+        "has-cors": "1.1.0",
1645
+        "indexof": "0.0.1",
1646
+        "parseqs": "0.0.5",
1647
+        "parseuri": "0.0.5",
1648
+        "ws": "~6.1.0",
1649
+        "xmlhttprequest-ssl": "~1.5.4",
1650
+        "yeast": "0.1.2"
1651
+      },
1652
+      "dependencies": {
1653
+        "debug": {
1654
+          "version": "4.1.1",
1655
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
1656
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
1657
+          "requires": {
1658
+            "ms": "^2.1.1"
1659
+          }
1660
+        },
1661
+        "ws": {
1662
+          "version": "6.1.4",
1663
+          "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
1664
+          "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
1665
+          "requires": {
1666
+            "async-limiter": "~1.0.0"
1667
+          }
1668
+        }
1669
+      }
1670
+    },
1671
+    "engine.io-parser": {
1672
+      "version": "2.2.0",
1673
+      "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz",
1674
+      "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==",
1675
+      "requires": {
1676
+        "after": "0.8.2",
1677
+        "arraybuffer.slice": "~0.0.7",
1678
+        "base64-arraybuffer": "0.1.5",
1679
+        "blob": "0.0.5",
1680
+        "has-binary2": "~1.0.2"
1681
+      }
1682
+    },
1520
     "enhanced-resolve": {
1683
     "enhanced-resolve": {
1521
       "version": "4.1.1",
1684
       "version": "4.1.1",
1522
       "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz",
1685
       "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz",
2694
         "function-bind": "^1.1.1"
2857
         "function-bind": "^1.1.1"
2695
       }
2858
       }
2696
     },
2859
     },
2860
+    "has-binary2": {
2861
+      "version": "1.0.3",
2862
+      "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
2863
+      "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
2864
+      "requires": {
2865
+        "isarray": "2.0.1"
2866
+      },
2867
+      "dependencies": {
2868
+        "isarray": {
2869
+          "version": "2.0.1",
2870
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
2871
+          "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
2872
+        }
2873
+      }
2874
+    },
2875
+    "has-cors": {
2876
+      "version": "1.1.0",
2877
+      "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
2878
+      "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
2879
+    },
2697
     "has-flag": {
2880
     "has-flag": {
2698
       "version": "3.0.0",
2881
       "version": "3.0.0",
2699
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
2882
       "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
2865
       "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
3048
       "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
2866
       "dev": true
3049
       "dev": true
2867
     },
3050
     },
3051
+    "indexof": {
3052
+      "version": "0.0.1",
3053
+      "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
3054
+      "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
3055
+    },
2868
     "infer-owner": {
3056
     "infer-owner": {
2869
       "version": "1.0.4",
3057
       "version": "1.0.4",
2870
       "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
3058
       "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
3585
         "brorand": "^1.0.1"
3773
         "brorand": "^1.0.1"
3586
       }
3774
       }
3587
     },
3775
     },
3776
+    "mime-db": {
3777
+      "version": "1.44.0",
3778
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
3779
+      "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg=="
3780
+    },
3781
+    "mime-types": {
3782
+      "version": "2.1.27",
3783
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
3784
+      "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
3785
+      "requires": {
3786
+        "mime-db": "1.44.0"
3787
+      }
3788
+    },
3588
     "mimic-fn": {
3789
     "mimic-fn": {
3589
       "version": "2.1.0",
3790
       "version": "2.1.0",
3590
       "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
3791
       "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
3714
     "ms": {
3915
     "ms": {
3715
       "version": "2.1.1",
3916
       "version": "2.1.1",
3716
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
3917
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
3717
-      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
3718
-      "dev": true
3918
+      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
3719
     },
3919
     },
3720
     "nan": {
3920
     "nan": {
3721
       "version": "2.14.0",
3921
       "version": "2.14.0",
3743
         "to-regex": "^3.0.1"
3943
         "to-regex": "^3.0.1"
3744
       }
3944
       }
3745
     },
3945
     },
3946
+    "negotiator": {
3947
+      "version": "0.6.2",
3948
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
3949
+      "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
3950
+    },
3746
     "neo-async": {
3951
     "neo-async": {
3747
       "version": "2.6.1",
3952
       "version": "2.6.1",
3748
       "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
3953
       "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
4084
       "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
4289
       "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
4085
       "dev": true
4290
       "dev": true
4086
     },
4291
     },
4292
+    "object-component": {
4293
+      "version": "0.0.3",
4294
+      "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
4295
+      "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE="
4296
+    },
4087
     "object-copy": {
4297
     "object-copy": {
4088
       "version": "0.1.0",
4298
       "version": "0.1.0",
4089
       "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
4299
       "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
4309
       "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
4519
       "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
4310
       "dev": true
4520
       "dev": true
4311
     },
4521
     },
4522
+    "parseqs": {
4523
+      "version": "0.0.5",
4524
+      "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
4525
+      "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
4526
+      "requires": {
4527
+        "better-assert": "~1.0.0"
4528
+      }
4529
+    },
4530
+    "parseuri": {
4531
+      "version": "0.0.5",
4532
+      "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
4533
+      "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
4534
+      "requires": {
4535
+        "better-assert": "~1.0.0"
4536
+      }
4537
+    },
4312
     "pascalcase": {
4538
     "pascalcase": {
4313
       "version": "0.1.1",
4539
       "version": "0.1.1",
4314
       "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
4540
       "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
4922
         }
5148
         }
4923
       }
5149
       }
4924
     },
5150
     },
5151
+    "socket.io": {
5152
+      "version": "2.3.0",
5153
+      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz",
5154
+      "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==",
5155
+      "requires": {
5156
+        "debug": "~4.1.0",
5157
+        "engine.io": "~3.4.0",
5158
+        "has-binary2": "~1.0.2",
5159
+        "socket.io-adapter": "~1.1.0",
5160
+        "socket.io-client": "2.3.0",
5161
+        "socket.io-parser": "~3.4.0"
5162
+      },
5163
+      "dependencies": {
5164
+        "debug": {
5165
+          "version": "4.1.1",
5166
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
5167
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
5168
+          "requires": {
5169
+            "ms": "^2.1.1"
5170
+          }
5171
+        }
5172
+      }
5173
+    },
5174
+    "socket.io-adapter": {
5175
+      "version": "1.1.2",
5176
+      "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz",
5177
+      "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g=="
5178
+    },
5179
+    "socket.io-client": {
5180
+      "version": "2.3.0",
5181
+      "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz",
5182
+      "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==",
5183
+      "requires": {
5184
+        "backo2": "1.0.2",
5185
+        "base64-arraybuffer": "0.1.5",
5186
+        "component-bind": "1.0.0",
5187
+        "component-emitter": "1.2.1",
5188
+        "debug": "~4.1.0",
5189
+        "engine.io-client": "~3.4.0",
5190
+        "has-binary2": "~1.0.2",
5191
+        "has-cors": "1.1.0",
5192
+        "indexof": "0.0.1",
5193
+        "object-component": "0.0.3",
5194
+        "parseqs": "0.0.5",
5195
+        "parseuri": "0.0.5",
5196
+        "socket.io-parser": "~3.3.0",
5197
+        "to-array": "0.1.4"
5198
+      },
5199
+      "dependencies": {
5200
+        "component-emitter": {
5201
+          "version": "1.2.1",
5202
+          "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
5203
+          "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
5204
+        },
5205
+        "debug": {
5206
+          "version": "4.1.1",
5207
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
5208
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
5209
+          "requires": {
5210
+            "ms": "^2.1.1"
5211
+          }
5212
+        },
5213
+        "isarray": {
5214
+          "version": "2.0.1",
5215
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
5216
+          "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
5217
+        },
5218
+        "socket.io-parser": {
5219
+          "version": "3.3.0",
5220
+          "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz",
5221
+          "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==",
5222
+          "requires": {
5223
+            "component-emitter": "1.2.1",
5224
+            "debug": "~3.1.0",
5225
+            "isarray": "2.0.1"
5226
+          },
5227
+          "dependencies": {
5228
+            "debug": {
5229
+              "version": "3.1.0",
5230
+              "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
5231
+              "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
5232
+              "requires": {
5233
+                "ms": "2.0.0"
5234
+              }
5235
+            },
5236
+            "ms": {
5237
+              "version": "2.0.0",
5238
+              "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
5239
+              "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
5240
+            }
5241
+          }
5242
+        }
5243
+      }
5244
+    },
5245
+    "socket.io-parser": {
5246
+      "version": "3.4.1",
5247
+      "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz",
5248
+      "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==",
5249
+      "requires": {
5250
+        "component-emitter": "1.2.1",
5251
+        "debug": "~4.1.0",
5252
+        "isarray": "2.0.1"
5253
+      },
5254
+      "dependencies": {
5255
+        "component-emitter": {
5256
+          "version": "1.2.1",
5257
+          "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
5258
+          "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
5259
+        },
5260
+        "debug": {
5261
+          "version": "4.1.1",
5262
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
5263
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
5264
+          "requires": {
5265
+            "ms": "^2.1.1"
5266
+          }
5267
+        },
5268
+        "isarray": {
5269
+          "version": "2.0.1",
5270
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
5271
+          "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
5272
+        }
5273
+      }
5274
+    },
4925
     "source-list-map": {
5275
     "source-list-map": {
4926
       "version": "2.0.1",
5276
       "version": "2.0.1",
4927
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
5277
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
5282
         "setimmediate": "^1.0.4"
5632
         "setimmediate": "^1.0.4"
5283
       }
5633
       }
5284
     },
5634
     },
5635
+    "to-array": {
5636
+      "version": "0.1.4",
5637
+      "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
5638
+      "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
5639
+    },
5285
     "to-arraybuffer": {
5640
     "to-arraybuffer": {
5286
       "version": "1.0.1",
5641
       "version": "1.0.1",
5287
       "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
5642
       "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
5958
         "typedarray-to-buffer": "^3.1.5"
6313
         "typedarray-to-buffer": "^3.1.5"
5959
       }
6314
       }
5960
     },
6315
     },
6316
+    "ws": {
6317
+      "version": "7.3.0",
6318
+      "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz",
6319
+      "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w=="
6320
+    },
6321
+    "xmlhttprequest-ssl": {
6322
+      "version": "1.5.5",
6323
+      "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
6324
+      "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
6325
+    },
5961
     "xtend": {
6326
     "xtend": {
5962
       "version": "4.0.2",
6327
       "version": "4.0.2",
5963
       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
6328
       "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
6043
         "yargs": "^13.3.0"
6408
         "yargs": "^13.3.0"
6044
       }
6409
       }
6045
     },
6410
     },
6411
+    "yeast": {
6412
+      "version": "0.1.2",
6413
+      "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
6414
+      "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
6415
+    },
6046
     "yn": {
6416
     "yn": {
6047
       "version": "2.0.0",
6417
       "version": "2.0.0",
6048
       "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",
6418
       "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz",

+ 5
- 1
package.json View File

1
 {
1
 {
2
   "name": "rpclibrary",
2
   "name": "rpclibrary",
3
-  "version": "1.10.2",
3
+  "version": "1.11.0",
4
   "description": "rpclibrary is a websocket on steroids!",
4
   "description": "rpclibrary is a websocket on steroids!",
5
   "main": "./js/Index.js",
5
   "main": "./js/Index.js",
6
   "repository": {
6
   "repository": {
50
     "why-is-node-running": "^2.1.2"
50
     "why-is-node-running": "^2.1.2"
51
   },
51
   },
52
   "dependencies": {
52
   "dependencies": {
53
+    "@types/socket.io": "^2.1.8",
54
+    "@types/socket.io-client": "^1.4.33",
53
     "bsock": "^0.1.9",
55
     "bsock": "^0.1.9",
54
     "crypto-js": "^4.0.0",
56
     "crypto-js": "^4.0.0",
55
     "http": "0.0.0",
57
     "http": "0.0.0",
58
+    "socket.io": "^2.3.0",
59
+    "socket.io-client": "^2.3.0",
56
     "uuid": "^3.3.3"
60
     "uuid": "^3.3.3"
57
   },
61
   },
58
   "files": [
62
   "files": [

+ 53
- 0
scratchpad.ts View File

1
+import { RPCSocket, RPCServer } from "./Index"
2
+
3
+
4
+// TL;DR
5
+const echo = (text: string) => {throw new Error("XD")}
6
+const add = (a: number, b: number) : number => a + b
7
+const getAsync = async () : Promise<{topic: string, message:string}>=> await new Promise((res, _) => {
8
+    setTimeout(() => {
9
+        res({
10
+            topic: "Hey!!",
11
+            message: "Hello World Async!"
12
+        })
13
+    }, 250)
14
+})
15
+const getCallback = (cbb: Function) : string => {
16
+    setTimeout(() => {
17
+        try{
18
+            cbb({
19
+                topic: "Hey!!",
20
+                message: "Hello World Callback!"
21
+            })
22
+        }catch(e){
23
+            console.log(String(e))
24
+        }
25
+    }, 250)
26
+    return "Please wait for a callback :)"
27
+}
28
+new RPCServer(20000, [{
29
+    name: 'MyRPCGroup1',
30
+    exportRPCs: () => [
31
+        echo,
32
+        add,
33
+        getAsync,
34
+        {
35
+            name: 'getCallback',
36
+            hook: getCallback,
37
+            onClose: (response, rpc) => { },
38
+            onCallback: (...callbackArgs) => { }
39
+        }
40
+    ]
41
+}])
42
+
43
+
44
+new RPCSocket(20000, 'localhost').connect()
45
+.then(async sock => {
46
+    try{
47
+        const val = await sock.call('ABCD', 12345)
48
+        console.log("VAL",val);
49
+        
50
+    }catch(e){
51
+        console.log("RPC error "+e)
52
+    }
53
+}).catch(e => console.log("connect err: "+e))

+ 14
- 24
src/Backend.ts View File

1
 'use strict'
1
 'use strict'
2
 
2
 
3
 import http = require('http');
3
 import http = require('http');
4
-import bsock = require('bsock');
4
+import { PromiseIO } from "./PromiseIO/Server";
5
 import * as T from './Types';
5
 import * as T from './Types';
6
 import * as U from './Utils';
6
 import * as U from './Utils';
7
 import * as I from './Interfaces';
7
 import * as I from './Interfaces';
8
 
8
 
9
 export class RPCServer<
9
 export class RPCServer<
10
     InterfaceT extends T.RPCInterface = T.RPCInterface,
10
     InterfaceT extends T.RPCInterface = T.RPCInterface,
11
-> implements I.Destroyable {
11
+> {
12
 
12
 
13
     private ws = http.createServer()
13
     private ws = http.createServer()
14
-    private io = bsock.createServer()
14
+    private pio = PromiseIO.createServer()
15
     private visibility: T.Visibility
15
     private visibility: T.Visibility
16
     private closeHandler: T.CloseHandler
16
     private closeHandler: T.CloseHandler
17
     private errorHandler: T.ErrorHandler
17
     private errorHandler: T.ErrorHandler
42
         })
42
         })
43
 
43
 
44
 
44
 
45
-        this.errorHandler = (socket: I.Socket) => (error: any, rpcName: string, args: any[]) => {
45
+        this.errorHandler = (socket: I.Socket | PromiseIO) => (error: any, rpcName: string, args: any[]) => {
46
             if (conf.errorHandler) conf.errorHandler(socket, error, rpcName, args)
46
             if (conf.errorHandler) conf.errorHandler(socket, error, rpcName, args)
47
             else throw error
47
             else throw error
48
         }
48
         }
72
 
72
 
73
     private startWebsocket() {
73
     private startWebsocket() {
74
         try {
74
         try {
75
-            this.io.attach(this.ws)
76
-            this.io.on('socket', (socket: I.Socket) => {
75
+            this.pio.attach(this.ws)
76
+            
77
+            this.pio.on('socket', (socket: I.Socket) => {
77
                 socket.on('error', (err) => this.errorHandler(socket, err, "system", []))
78
                 socket.on('error', (err) => this.errorHandler(socket, err, "system", []))
78
                 socket.on('close', () => this.closeHandler(socket))
79
                 socket.on('close', () => this.closeHandler(socket))
79
                 this.connectionHandler(socket)
80
                 this.connectionHandler(socket)
80
                 this.initRPCs(socket)
81
                 this.initRPCs(socket)
81
             })
82
             })
82
-            this.ws = this.ws.listen(this.port, this.visibility)
83
+
84
+            this.pio.listen(this.port)
85
+
83
         } catch (e) {
86
         } catch (e) {
84
-            this.errorHandler(this.io, e, 'system', [])
87
+            this.errorHandler(this.pio, e, 'system', [])
85
         }
88
         }
86
     }
89
     }
87
 
90
 
88
     protected initRPCs(socket: I.Socket) {
91
     protected initRPCs(socket: I.Socket) {
92
+        
89
         socket.hook('info', async (sesame?: string) => {
93
         socket.hook('info', async (sesame?: string) => {
90
             const rpcs = await Promise.all(this.exporters.map(async exp => {
94
             const rpcs = await Promise.all(this.exporters.map(async exp => {
91
                 const allowed = await this.accessFilter(sesame, exp)
95
                 const allowed = await this.accessFilter(sesame, exp)
96
         })
100
         })
97
     }
101
     }
98
 
102
 
99
-    /**
100
-     * Publishes a new list of Exporters. This destroys and restarts the socket
101
-     * @param exporters the exporters to publish
102
-    public setExporters(exporters: T.ExporterArray<InterfaceT>): any {
103
-        exporters.forEach(U.fixNames)
104
-        this.destroy()
105
-        this.ws = http.createServer()
106
-        this.io = bsock.createServer()
107
-        this.exporters = exporters
108
-        this.startWebsocket()
109
-    }
110
-    */
111
-
112
-
113
-    destroy(): void {
114
-        this.io.close()
103
+    close(): void {
104
+        this.pio.close()
115
         this.ws.close()
105
         this.ws.close()
116
     }
106
     }
117
 }
107
 }

+ 42
- 23
src/Frontend.ts View File

1
 'use strict'
1
 'use strict'
2
 
2
 
3
-import bsock = require('bsock');
4
-
3
+import { PromiseIOClient } from './PromiseIO/Client'
5
 import * as T from './Types'; 
4
 import * as T from './Types'; 
6
 import * as I from './Interfaces';
5
 import * as I from './Interfaces';
7
 import { stripAfterEquals, appendComma } from './Utils';
6
 import { stripAfterEquals, appendComma } from './Utils';
18
     }
17
     }
19
 
18
 
20
     private socket: I.Socket
19
     private socket: I.Socket
21
-    private closeHandlers: T.FrontEndHandlerType['close'][] = []
22
-    private errorHandlers: T.FrontEndHandlerType['error'][] = []
20
+    private handlers : {
21
+        [name in string]: T.AnyFunction[]
22
+    } = {
23
+        error: [],
24
+        close: []
25
+    }
23
     private hooks : {[name in string]: T.AnyFunction} = {} 
26
     private hooks : {[name in string]: T.AnyFunction} = {} 
24
 
27
 
25
     /**
28
     /**
45
         }
48
         }
46
     }
49
     }
47
 
50
 
51
+    /**
52
+     * Hooks a handler to a function name. Use {@link call} to trigger it.
53
+     * @param name The function name to listen on
54
+     * @param handler The handler to attach
55
+     */
56
+    public bind(name: string, handler: (...args:any[]) => any | Promise<any>){
57
+        if(!this.socket){
58
+            this.hooks[name] = handler
59
+        }else{
60
+            this.socket.bind(name, handler)
61
+        }
62
+    }
63
+
48
     /**
64
     /**
49
      * Removes a {@link hook} listener by name.
65
      * Removes a {@link hook} listener by name.
50
      * @param name The function name 
66
      * @param name The function name 
62
      * @param type 'error' or 'close'
78
      * @param type 'error' or 'close'
63
      * @param f The listener to attach
79
      * @param f The listener to attach
64
      */
80
      */
65
-    public on<T extends "error" | "close">(type: T, f: T.FrontEndHandlerType[T]){
81
+    public on(type: string, f: T.AnyFunction){
66
         if(!this.socket){
82
         if(!this.socket){
67
-            switch(type){
68
-                case "error": this.errorHandlers.push(<T.FrontEndHandlerType['error']> f); break;
69
-                case "close": this.closeHandlers.push(<T.FrontEndHandlerType['close']> f); break;
70
-                default: throw new Error('socket.on only supports ´error´ and ´close´ as first parameter. Got: ´'+type+'´')
71
-            }
83
+            if(!this.handlers[type]) 
84
+                this.handlers[type] = []
85
+
86
+            this.handlers[type].push(f)
72
         }else{
87
         }else{
73
             this.socket.on(type, f)
88
             this.socket.on(type, f)
74
         }
89
         }
84
         this.socket.emit(eventName, data)
99
         this.socket.emit(eventName, data)
85
     }
100
     }
86
 
101
 
87
-    /**
88
-     * Destroys the socket
89
-     */
90
-    public destroy(){
91
-        if(!this.socket) return;
92
-        this.socket.destroy()
93
-    }
94
-
95
     /**
102
     /**
96
      * Closes the socket. It may attempt to reconnect.
103
      * Closes the socket. It may attempt to reconnect.
97
      */
104
      */
108
     public async call (rpcname: string, ...args: any[]) : Promise<any>{
115
     public async call (rpcname: string, ...args: any[]) : Promise<any>{
109
         if(!this.socket) throw new Error("The socket is not connected! Use socket.connect() first")
116
         if(!this.socket) throw new Error("The socket is not connected! Use socket.connect() first")
110
         try{
117
         try{
111
-            return await this.socket.call.apply(this.socket, [rpcname, ...args])
118
+            const val = await this.socket.call.apply(this.socket, [rpcname, ...args])
119
+            return val
112
         }catch(e){
120
         }catch(e){
113
             this.emit('error', e)
121
             this.emit('error', e)
114
             throw e
122
             throw e
129
      * Connects to the server and attaches available RPCs to this object
137
      * Connects to the server and attaches available RPCs to this object
130
      */
138
      */
131
     public async connect( sesame?: string ) : Promise<T.ConnectedSocket<Ifc>> {
139
     public async connect( sesame?: string ) : Promise<T.ConnectedSocket<Ifc>> {
132
-        this.socket = await bsock.connect(this.port, this.server, this.conf.tls?this.conf.tls:false)
133
-        this.errorHandlers.forEach(h => this.socket.on('error', h))
134
-        this.closeHandlers.forEach(h => this.socket.on('close', h))
140
+
141
+        try{
142
+            this.socket = await PromiseIOClient.connect(this.port, this.server, /*this.conf.tls?this.conf.tls:false*/)
143
+        }catch(e){
144
+            this.handlers['error'].forEach(h => h(e))
145
+            throw e
146
+        }
147
+
148
+        Object.entries(this.handlers).forEach(([k,v])=>{
149
+            v.forEach(h => this.socket.on(k, h))
150
+        })
151
+
135
         Object.entries(this.hooks).forEach((kv: [string, T.AnyFunction]) => {
152
         Object.entries(this.hooks).forEach((kv: [string, T.AnyFunction]) => {
136
             this.socket.hook(kv[0], kv[1])
153
             this.socket.hook(kv[0], kv[1])
137
         })
154
         })
138
-
139
         const info:T.ExtendedRpcInfo[] = await this.info(sesame)
155
         const info:T.ExtendedRpcInfo[] = await this.info(sesame)
156
+
140
         info.forEach(i => {
157
         info.forEach(i => {
141
             let f: any
158
             let f: any
142
             
159
             
153
             this[i.owner][i.name] = f
170
             this[i.owner][i.name] = f
154
             this[i.owner][i.name].bind(this)
171
             this[i.owner][i.name].bind(this)
155
         })
172
         })
173
+        
174
+        
156
         return <T.ConnectedSocket<Ifc>> (this as any) 
175
         return <T.ConnectedSocket<Ifc>> (this as any) 
157
     }
176
     }
158
 
177
 

+ 12
- 17
src/Interfaces.ts View File

12
     exportRPCs() : T.RPCDefinitions<Ifc>[Name]
12
     exportRPCs() : T.RPCDefinitions<Ifc>[Name]
13
 }
13
 }
14
 
14
 
15
-/**
16
- * Generic socket interface that can apply to bsock as well as RPCSocket
17
- */
18
-export interface Socket extends Destroyable {
19
-    port: number
20
-    hook: (rpcname: string, handler: T.AnyFunction) => void
21
-    unhook: (rpcname:string) => void
22
-    call: (rpcname:string, ...args: any[]) => Promise<any>
23
-    fire: (rpcname:string, ...args: any[]) => Promise<any>
24
-    on: T.OnFunction
25
-    emit: (eventName: string, data:any) => void    
26
-    close() : void
27
-}
28
-
29
-export interface Destroyable{
30
-    destroy() : void
31
-}
15
+export interface Socket {
16
+    id?: string
17
+    bind: (name: string, listener: T.PioBindListener) => void
18
+  
19
+    hook: (rpcname: string, handler: T.PioHookListener) => void
20
+    unhook: (rpcname: string, listener?:T.AnyFunction) => void
21
+    call: (rpcname: string, ...args: any[]) => Promise<any>
22
+    fire: (rpcname: string, ...args: any[]) => Promise<any>
23
+    on: (type: string, f: T.AnyFunction)=>any
24
+    emit: (eventName: string, data: any) => void
25
+    close(): void
26
+  }

+ 38
- 0
src/PromiseIO/Client.ts View File

1
+import { Socket } from "socket.io"
2
+import * as U from '../Utils'
3
+import * as I from '../Interfaces'
4
+import * as socketio from 'socket.io-client'
5
+
6
+export class PromiseIOClient {
7
+    
8
+    static connect = (port: number, host = "localhost"): Promise<I.Socket> => new Promise((res, rej) => {
9
+        try {
10
+            const socket = socketio(`http://${host}:${port}`, {
11
+                reconnectionAttempts: 2,
12
+                reconnectionDelay: 200,
13
+                timeout: 450,
14
+                reconnection: false
15
+            })
16
+            socket.on('connect_error', e => {
17
+                sock.emit('error', e)
18
+                rej(e) 
19
+            })
20
+
21
+            const sock = U.makePioSocket(socket)
22
+            socket.on('connect', ()=>{ res(sock) })
23
+
24
+
25
+            /*
26
+            socket.on('connect_timeout', ()=>console.log('connect_timeout'))
27
+            socket.on('disconnect', ()=>console.log('disconnect'))
28
+            socket.on('reconnect', ()=>console.log('reconnect'))
29
+            socket.on('reconnect_attempt', ()=>console.log('reconnect_attempt'))
30
+            socket.on('reconnecting', ()=>console.log('reconnecting'));
31
+            socket.on('reconnect_failed', ()=>console.log('reconnect_failed'));
32
+            socket.on('reconnecting', ()=>console.log('reconnecting'));
33
+            */
34
+        } catch (e) {
35
+            rej(e)
36
+        }
37
+    })
38
+}

+ 57
- 0
src/PromiseIO/Server.ts View File

1
+import { Server, Socket } from "socket.io"
2
+import { Server as httpServer } from "http"
3
+import * as U from '../Utils'
4
+import * as T from '../Types'
5
+const socketio = require('socket.io')
6
+
7
+export class PromiseIO {
8
+    io?: Server
9
+    private listeners: { [eventName in string]: ((...args: any) => void)[] } = {
10
+        socket: [],
11
+        connect: []
12
+    }
13
+
14
+    static createServer(): PromiseIO {
15
+        return new PromiseIO();
16
+    }
17
+
18
+    attach(httpServer: httpServer) {
19
+        this.io = socketio(httpServer)
20
+    }
21
+
22
+    listen(port: number) {
23
+        this.io!.on('connection', (sock: Socket) => {
24
+            const pioSock = U.makePioSocket(sock)
25
+            this.listeners['socket'].forEach(listener => listener(pioSock))
26
+            this.listeners['connect'].forEach(listener => listener(pioSock))
27
+            /*
28
+            pioSock.on('error', ()=>console.log('error'));
29
+
30
+            pioSock.on('connect_timeout', ()=>console.log('connect_timeout'))
31
+            pioSock.on('disconnect', ()=>console.log('disconnect'))
32
+            pioSock.on('reconnect', ()=>console.log('reconnect'))
33
+            pioSock.on('reconnect_attempt', ()=>console.log('reconnect_attempt'))
34
+            pioSock.on('reconnecting', ()=>console.log('reconnecting'));
35
+            pioSock.on('reconnect_failed', ()=>console.log('reconnect_failed'));
36
+            pioSock.on('reconnecting', ()=>console.log('reconnecting'));
37
+            */
38
+        })
39
+        this.io!.listen(port)
40
+    }
41
+
42
+    on(eventName: string, listener: T.AnyFunction) {
43
+        if (this.listeners[eventName] == null) {
44
+            this.listeners[eventName] = []
45
+        }
46
+        this.listeners[eventName].push(listener)
47
+    }
48
+
49
+    close = () => {
50
+        if(this.io){
51
+            this.io.engine.ws.close()
52
+            this.io.close()
53
+            this.io = undefined
54
+        }
55
+    }
56
+
57
+}

+ 7
- 1
src/Types.ts View File

1
 import * as I from "./Interfaces";
1
 import * as I from "./Interfaces";
2
 import { RPCSocket } from "./Frontend";
2
 import { RPCSocket } from "./Frontend";
3
+import { PromiseIO } from "./PromiseIO/Server";
4
+
5
+export type PioBindListener = (...args: any) => void
6
+export type PioHookListener = AnyFunction
7
+
8
+
3
 
9
 
4
 export type AnyFunction = (...args:any) => any
10
 export type AnyFunction = (...args:any) => any
5
 export type HookFunction = AnyFunction
11
 export type HookFunction = AnyFunction
6
 export type AccessFilter<InterfaceT extends RPCInterface = RPCInterface> = (sesame:string|undefined, exporter: I.RPCExporter<InterfaceT, keyof InterfaceT>) => Promise<boolean> | boolean
12
 export type AccessFilter<InterfaceT extends RPCInterface = RPCInterface> = (sesame:string|undefined, exporter: I.RPCExporter<InterfaceT, keyof InterfaceT>) => Promise<boolean> | boolean
7
 export type Visibility = "127.0.0.1" | "0.0.0.0"
13
 export type Visibility = "127.0.0.1" | "0.0.0.0"
8
 export type ConnectionHandler = (socket:I.Socket) => void
14
 export type ConnectionHandler = (socket:I.Socket) => void
9
-export type ErrorHandler = (socket:I.Socket, error:any, rpcName: string, args: any[]) => void
15
+export type ErrorHandler = (socket:I.Socket | PromiseIO, error:any, rpcName: string, args: any[]) => void
10
 export type CloseHandler = (socket:I.Socket) =>  void
16
 export type CloseHandler = (socket:I.Socket) =>  void
11
 export type SesameFunction = (sesame : string) => boolean
17
 export type SesameFunction = (sesame : string) => boolean
12
 export type SesameConf = {
18
 export type SesameConf = {

+ 130
- 45
src/Utils.ts View File

2
 
2
 
3
 import * as T from "./Types";
3
 import * as T from "./Types";
4
 import * as I from "./Interfaces";
4
 import * as I from "./Interfaces";
5
+import { Server as ioServer, Socket as ioSocket, Socket } from "socket.io"
6
+import { Socket as ioClientSocket } from "socket.io-client"
5
 
7
 
6
 /**
8
 /**
7
  * Translate an RPC to RPCInfo for serialization.
9
  * Translate an RPC to RPCInfo for serialization.
11
  * @param sesame optional sesame phrase to prepend before all RPC arguments 
13
  * @param sesame optional sesame phrase to prepend before all RPC arguments 
12
  * @throws Error on RPC without name property
14
  * @throws Error on RPC without name property
13
  */
15
  */
14
-export const rpcToRpcinfo = (socket: I.Socket, rpc : T.RPC<any, any>, owner: string, errorHandler: T.ErrorHandler, sesame?:T.SesameFunction):T.RpcInfo => {
15
-    switch (typeof rpc){
16
-        case  "object":
17
-            if(rpc['call']){
16
+export const rpcToRpcinfo = (socket: I.Socket, rpc: T.RPC<any, any>, owner: string, errorHandler: T.ErrorHandler, sesame?: T.SesameFunction): T.RpcInfo => {
17
+    switch (typeof rpc) {
18
+        case "object":
19
+            if (rpc['call']) {
18
                 return {
20
                 return {
19
                     owner: owner,
21
                     owner: owner,
20
                     argNames: extractArgs(rpc['call']),
22
                     argNames: extractArgs(rpc['call']),
21
                     type: "Call",
23
                     type: "Call",
22
                     name: rpc.name,
24
                     name: rpc.name,
23
-                    call: sesame?async (_sesame, ...args) => {if(sesame(_sesame)) return await rpc['call'].apply({}, args); socket.destroy()}:rpc['call'], // check & remove sesame 
25
+                    call: sesame ? async (_sesame, ...args) => { if (sesame(_sesame)) return await rpc['call'].apply({}, args); socket.close() } : rpc['call'], // check & remove sesame 
24
                 }
26
                 }
25
-            }else{
27
+            } else {
26
                 const generator = hookGenerator(<T.HookRPC<any, any>>rpc, errorHandler, sesame)
28
                 const generator = hookGenerator(<T.HookRPC<any, any>>rpc, errorHandler, sesame)
27
                 return {
29
                 return {
28
                     owner: owner,
30
                     owner: owner,
33
                 }
35
                 }
34
             }
36
             }
35
         case "function":
37
         case "function":
36
-            if(!rpc.name) throw new Error(`
38
+            if (!rpc.name) throw new Error(`
37
 RPC did not provide a name. 
39
 RPC did not provide a name. 
38
 \nUse 'funtion name(..){ .. }' syntax instead.
40
 \nUse 'funtion name(..){ .. }' syntax instead.
39
 \n
41
 \n
41
 \n${rpc.toString()}
43
 \n${rpc.toString()}
42
 \n>------------OFFENDING RPC`)
44
 \n>------------OFFENDING RPC`)
43
             return {
45
             return {
44
-                owner : owner,
46
+                owner: owner,
45
                 argNames: extractArgs(rpc),
47
                 argNames: extractArgs(rpc),
46
                 type: "Call",
48
                 type: "Call",
47
                 name: rpc.name,
49
                 name: rpc.name,
48
-                call: sesame?async (_sesame, ...args) => {if(sesame(_sesame)) return await rpc.apply({}, args); throw makeError(rpc.name)}:rpc, // check & remove sesame 
50
+                call: sesame ? async (_sesame, ...args) => { if (sesame(_sesame)) return await rpc.apply({}, args); throw makeError(rpc.name) } : rpc, // check & remove sesame 
49
             }
51
             }
50
     }
52
     }
51
-    throw new Error("Bad socketIORPC type "+ typeof rpc)
53
+    throw new Error("Bad socketIORPC type " + typeof rpc)
52
 }
54
 }
53
 
55
 
54
 /**
56
 /**
57
  * @param exporter The exporter
59
  * @param exporter The exporter
58
  * @param makeUnique @default true Attach a suffix to RPC names
60
  * @param makeUnique @default true Attach a suffix to RPC names
59
  */
61
  */
60
-export function rpcHooker(socket: I.Socket, exporter:I.RPCExporter<any, any>, errorHandler: T.ErrorHandler, sesame?:T.SesameFunction, makeUnique = true):T.ExtendedRpcInfo[]{
62
+export function rpcHooker(socket: I.Socket, exporter: I.RPCExporter<any, any>, errorHandler: T.ErrorHandler, sesame?: T.SesameFunction, makeUnique = true): T.ExtendedRpcInfo[] {
61
     const owner = exporter.name
63
     const owner = exporter.name
62
     const RPCs = exporter.exportRPCs()
64
     const RPCs = exporter.exportRPCs()
63
 
65
 
64
     return RPCs.map(rpc => rpcToRpcinfo(socket, rpc, owner, errorHandler, sesame))
66
     return RPCs.map(rpc => rpcToRpcinfo(socket, rpc, owner, errorHandler, sesame))
65
-    .map(info => {
66
-        const suffix = makeUnique?"-"+uuidv4().substr(0,4):""
67
-        const ret:any = info
68
-        ret.uniqueName = info.name+suffix
69
-        let rpcFunction = info.type === 'Hook'? info.generator(socket)
70
-                                              : info.call
71
-
72
-        socket.hook(ret.uniqueName, callGenerator(info.name, socket, rpcFunction, errorHandler))
73
-        return ret
74
-    })
67
+        .map(info => {
68
+            const suffix = makeUnique ? "-" + uuidv4().substr(0, 4) : ""
69
+            const ret: any = info
70
+            ret.uniqueName = info.name + suffix
71
+            let rpcFunction = info.type === 'Hook' ? info.generator(socket)
72
+                : info.call
73
+
74
+            socket.hook(ret.uniqueName, callGenerator(info.name, socket, rpcFunction, errorHandler))
75
+            return ret
76
+        })
75
 }
77
 }
76
 
78
 
77
 /**
79
 /**
78
  * Decorate an RPC with the error handler
80
  * Decorate an RPC with the error handler
79
  * @param rpcFunction the function to decorate
81
  * @param rpcFunction the function to decorate
80
  */
82
  */
81
-const callGenerator = (rpcName : string, socket: I.Socket, rpcFunction : T.AnyFunction, errorHandler: T.ErrorHandler) : T.AnyFunction => {
83
+const callGenerator = (rpcName: string, socket: I.Socket, rpcFunction: T.AnyFunction, errorHandler: T.ErrorHandler): T.AnyFunction => {
82
     const argsArr = extractArgs(rpcFunction)
84
     const argsArr = extractArgs(rpcFunction)
83
     const args = argsArr.join(',')
85
     const args = argsArr.join(',')
84
     const argsStr = argsArr.map(stripAfterEquals).join(',')
86
     const argsStr = argsArr.map(stripAfterEquals).join(',')
85
 
87
 
86
-    return eval(`async (`+args+`) => {
88
+    return eval(`async (` + args + `) => {
87
         try{
89
         try{
88
-            return await rpcFunction(`+argsStr+`)
90
+            return await rpcFunction(`+ argsStr + `)
89
         }catch(e){
91
         }catch(e){
90
-            errorHandler(socket)(e, rpcName, [`+args+`])
92
+            errorHandler(socket)(e, rpcName, [`+ args + `])
91
         }
93
         }
92
     }`)
94
     }`)
93
 }
95
 }
96
  * Utility function to strip parameters like "a = 3" of their defaults
98
  * Utility function to strip parameters like "a = 3" of their defaults
97
  * @param str The parameter to modify
99
  * @param str The parameter to modify
98
  */
100
  */
99
-export function stripAfterEquals(str:string):string{
101
+export function stripAfterEquals(str: string): string {
100
     return str.split("=")[0]
102
     return str.split("=")[0]
101
 }
103
 }
102
 
104
 
105
  * @param rpc The RPC to transform
107
  * @param rpc The RPC to transform
106
  * @returns A {@link HookFunction}
108
  * @returns A {@link HookFunction}
107
  */
109
  */
108
-const hookGenerator = (rpc:T.HookRPC<any, any>, /*not unused!*/ errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction): T.HookInfo['generator'] => { 
110
+const hookGenerator = (rpc: T.HookRPC<any, any>, /*not unused!*/ errorHandler: T.ErrorHandler, sesameFn?: T.SesameFunction): T.HookInfo['generator'] => {
111
+
109
     let argsArr = extractArgs(rpc.hook)
112
     let argsArr = extractArgs(rpc.hook)
110
     argsArr.pop() //remove 'callback' from the end
113
     argsArr.pop() //remove 'callback' from the end
111
     let callArgs = argsArr.join(',')
114
     let callArgs = argsArr.join(',')
112
 
115
 
113
-    const args = sesameFn?(['sesame', ...argsArr].join(','))
114
-                         :callArgs
116
+    const args = sesameFn ? (['sesame', ...argsArr].join(','))
117
+        : callArgs
115
 
118
 
116
     callArgs = appendComma(callArgs, false)
119
     callArgs = appendComma(callArgs, false)
117
 
120
 
139
 }
142
 }
140
 
143
 
141
 const makeError = (callName: string) => {
144
 const makeError = (callName: string) => {
142
-    return new Error("Call not found: "+callName+". ; Zone: <root> ; Task: Promise.then ; Value: Error: Call not found: "+callName)
145
+    return new Error("Call not found: " + callName + ". ; Zone: <root> ; Task: Promise.then ; Value: Error: Call not found: " + callName)
143
 }
146
 }
144
 
147
 
145
 /**
148
 /**
146
  * Extract a string list of parameters from a function
149
  * Extract a string list of parameters from a function
147
  * @param f The source function
150
  * @param f The source function
148
  */
151
  */
149
-const extractArgs = (f:Function):string[] => {
150
-    let fn:string
151
-    fn = (fn = String(f)).substr(0, fn.indexOf(")")).substr(fn.indexOf("(")+1)
152
-    return fn!==""?fn.split(',') : []
152
+const extractArgs = (f: Function): string[] => {
153
+    let fn: string
154
+    fn = (fn = String(f)).substr(0, fn.indexOf(")")).substr(fn.indexOf("(") + 1)
155
+    return fn !== "" ? fn.split(',') : []
153
 }
156
 }
154
 
157
 
155
 
158
 
156
-export function makeSesameFunction (sesame : T.SesameFunction | string) : T.SesameFunction {
157
-    if(typeof sesame === 'function'){
159
+export function makeSesameFunction(sesame: T.SesameFunction | string): T.SesameFunction {
160
+    if (typeof sesame === 'function') {
158
         return sesame
161
         return sesame
159
     }
162
     }
160
 
163
 
161
-    return (testSesame : string) => {
162
-        return testSesame === sesame 
164
+    return (testSesame: string) => {
165
+        return testSesame === sesame
163
     }
166
     }
164
 }
167
 }
165
 
168
 
166
 
169
 
167
-export function appendComma(s?:string, turnToString = true):string{
168
-    if(turnToString)   
169
-        return s?`'${s}',`:"" 
170
-        return s?`${s},`:"" 
170
+export function appendComma(s?: string, turnToString = true): string {
171
+    if (turnToString)
172
+        return s ? `'${s}',` : ""
173
+    return s ? `${s},` : ""
171
 }
174
 }
172
 
175
 
173
 
176
 
176
  * This was supposedly fixed (https://github.com/microsoft/TypeScript/issues/5611) but it still is the case.
179
  * This was supposedly fixed (https://github.com/microsoft/TypeScript/issues/5611) but it still is the case.
177
  * This function sets the name value for all object members that are functions.
180
  * This function sets the name value for all object members that are functions.
178
 */
181
 */
179
-export function fixNames(o:Object):void{
182
+export function fixNames(o: Object): void {
180
     Object.keys(o).forEach(key => {
183
     Object.keys(o).forEach(key => {
181
-        if(typeof o[key] === 'function' && !o[key].name){
184
+        if (typeof o[key] === 'function' && !o[key].name) {
182
             Object.defineProperty(o[key], 'name', {
185
             Object.defineProperty(o[key], 'name', {
183
                 value: key
186
                 value: key
184
             })
187
             })
185
         }
188
         }
186
     })
189
     })
187
-}
190
+}
191
+
192
+export const makePioSocket = (socket: any): I.Socket => {
193
+    return {
194
+        bind: (name: string, listener: T.PioBindListener) => socket.on(name, (...args: any) => {
195
+            const ack = args.pop()
196
+            listener.apply(null, args)
197
+            ack()
198
+        }),
199
+
200
+        hook: (name: string, listener: T.PioHookListener) => {
201
+            const args = extractArgs(listener)
202
+            let argNames
203
+            let restParam = args.find(e => e.includes('...'))
204
+            if(!restParam){
205
+                argNames = [...args, '...__args__'].join(',')
206
+                restParam = '__args__'
207
+            }else{
208
+                argNames = [...args].join(',')
209
+                restParam = restParam.replace('...','')
210
+            }
211
+
212
+            const decoratedListener = eval(`(() => async (${argNames}) => {
213
+                const __ack__ = ${restParam}.pop()
214
+                try{
215
+                    const response = await listener.apply(null, [${argNames}])
216
+                    __ack__(response)
217
+                }catch(e){
218
+                    __ack__({
219
+                        ...e,
220
+                        stack: e.stack,
221
+                        message: e.message,
222
+                        name: e.name,
223
+                    })
224
+                }
225
+            })()`)
226
+            socket.on(name, decoratedListener)
227
+        },
228
+
229
+        call: (name: string, ...args: any) => {
230
+            return new Promise((res, rej) => {
231
+                const params: any = [name, ...args, (resp) => {
232
+                    if(isError(resp)){
233
+                        const err = new Error()
234
+                        err.stack = resp.stack
235
+                        err.name = resp.name
236
+                        err.message = resp.message
237
+                        return rej(err)
238
+                    }
239
+                    res(resp)
240
+                }]
241
+                socket.emit.apply(socket, params)                    
242
+            })
243
+        },
244
+
245
+        fire: (name: string, ...args: any) => new Promise((res, rej) => {
246
+            const params: any = [name, ...args]
247
+            socket.emit.apply(socket, params)
248
+            res()
249
+        }),
250
+
251
+        unhook: (name: string, listener?: T.AnyFunction) => {
252
+            if (listener) {
253
+                socket.removeListener(name, listener)
254
+            } else {
255
+                socket.removeAllListeners(name)
256
+            }
257
+        },
258
+
259
+        id: socket.id,
260
+        on: (...args) => socket.on.apply(socket, args),
261
+        emit: (...args) => socket.emit.apply(socket, args),
262
+        close: () => {
263
+            socket
264
+            socket.disconnect(true)
265
+        },
266
+    }
267
+}
268
+
269
+export const isError = function(e){
270
+    return e && e.stack && e.message && typeof e.stack === 'string' 
271
+           && typeof e.message === 'string';
272
+   }

+ 46
- 33
test/Test.ts View File

68
     })
68
     })
69
     
69
     
70
     after(done => {
70
     after(done => {
71
-        client.destroy()
72
-        server.destroy()
71
+        client.close()
72
+        server.close()
73
 
73
 
74
         done()
74
         done()
75
     })
75
     })
116
     })
116
     })
117
 
117
 
118
     after(() => {
118
     after(() => {
119
-        client.destroy()
120
-        server.destroy()
119
+        client.close()
120
+        server.close()
121
     })
121
     })
122
 
122
 
123
 
123
 
221
     })
221
     })
222
 
222
 
223
     after(() => {
223
     after(() => {
224
-        client.destroy()
225
-        server.destroy()
224
+        client.close()
225
+        server.close()
226
     })
226
     })
227
 
227
 
228
     it('Subscribe with param', (done) => {
228
     it('Subscribe with param', (done) => {
314
     })
314
     })
315
 
315
 
316
     after(() => {
316
     after(() => {
317
-        client.destroy()
318
-        server.destroy()
317
+        client.close()
318
+        server.close()
319
     })
319
     })
320
 
320
 
321
     it('should work with sesame', (done) => {
321
     it('should work with sesame', (done) => {
337
             else {
337
             else {
338
                 done(new Error("Function supposed to be removed without sesame"))
338
                 done(new Error("Function supposed to be removed without sesame"))
339
             }
339
             }
340
-            cli.destroy()
341
-            sock.destroy()
340
+            cli.close()
341
+            sock.close()
342
         })
342
         })
343
     })
343
     })
344
 
344
 
350
             else {
350
             else {
351
                 done(new Error("Function supposed to be removed without sesame"))
351
                 done(new Error("Function supposed to be removed without sesame"))
352
             }
352
             }
353
-            cli.destroy()
354
-            sock.destroy()
353
+            cli.close()
354
+            sock.close()
355
         })
355
         })
356
     })
356
     })
357
 
357
 
405
                         done(e)
405
                         done(e)
406
                 })
406
                 })
407
                 .finally(() => {
407
                 .finally(() => {
408
-                    cli.destroy()
409
-                    sock.destroy()
410
-                    server.destroy()
408
+                    cli.close()
409
+                    sock.close()
410
+                    server.close()
411
                 })
411
                 })
412
         })
412
         })
413
     })
413
     })
440
                     done(e)
440
                     done(e)
441
                 })
441
                 })
442
                 .finally(() => {
442
                 .finally(() => {
443
-                    cli.destroy()
444
-                    sock.destroy()
445
-                    server.destroy()
443
+                    cli.close()
444
+                    sock.close()
445
+                    server.close()
446
                 })
446
                 })
447
         })
447
         })
448
     })
448
     })
484
                     done(new Error("UNEXPECTED CLIENT ERROR " + e.message))
484
                     done(new Error("UNEXPECTED CLIENT ERROR " + e.message))
485
                 })
485
                 })
486
                 .finally(() => {
486
                 .finally(() => {
487
-                    cli.destroy()
488
-                    sock.destroy()
489
-                    server.destroy()
487
+                    cli.close()
488
+                    sock.close()
489
+                    server.close()
490
                 })
490
                 })
491
         })
491
         })
492
     })
492
     })
523
                     done(e)
523
                     done(e)
524
                 })
524
                 })
525
                 .finally(() => {
525
                 .finally(() => {
526
-                    cli.destroy()
527
-                    sock.destroy()
528
-                    server.destroy()
526
+                    cli.close()
527
+                    sock.close()
528
+                    server.close()
529
                 })
529
                 })
530
         })
530
         })
531
     })
531
     })
595
     })
595
     })
596
 
596
 
597
     afterEach((done) => {
597
     afterEach((done) => {
598
-        sock.destroy()
598
+        sock.close()
599
         done()
599
         done()
600
     })
600
     })
601
 
601
 
602
     after(() => {
602
     after(() => {
603
-        serv.destroy()
603
+        serv.close()
604
     })
604
     })
605
 
605
 
606
     /* The server-side socket will enter a 30s timeout if destroyed by a RPC.
606
     /* The server-side socket will enter a 30s timeout if destroyed by a RPC.
663
         }).catch(e => {
663
         }).catch(e => {
664
             //catch clause fires second
664
             //catch clause fires second
665
             if (errorHandleCount != 1) {
665
             if (errorHandleCount != 1) {
666
-                console.log("catch clause didn't fire second");
666
+                console.log("catch clause didn't fire second", errorHandleCount);
667
             } else {
667
             } else {
668
-                sock.destroy()
668
+                sock.close()
669
                 done()
669
                 done()
670
             }
670
             }
671
         })
671
         })
672
     })
672
     })
673
 
673
 
674
+    /*
675
+     * ## 1.11.0 breaking ##
676
+     * 
677
+     * API change: Move from bsock to socketio changes underlying API for when errors are thrown.
678
+     * socketio does not throw on unknown listener. This behaviour is considered more consistent with the design 
679
+     * goals of RPClibrary and was thus adopted 
680
+     *
681
+          
682
+     
674
     it("fires error if call is unknown", (done) => {
683
     it("fires error if call is unknown", (done) => {
675
         const serv = new RPCServer(21004)
684
         const serv = new RPCServer(21004)
676
         const sock = new RPCSocket(21004, 'localhost')
685
         const sock = new RPCSocket(21004, 'localhost')
677
 
686
 
678
         sock.on('error', (err) => {
687
         sock.on('error', (err) => {
679
-            sock.destroy()
680
-            serv.destroy()
688
+            sock.close()
689
+            serv.close()
681
             done()
690
             done()
682
         })
691
         })
683
 
692
 
684
         sock.connect().then(_ => {
693
         sock.connect().then(_ => {
685
-            sock.call("unknownRPC123", "AAAAA").catch(e => { /* ignore */ })
694
+            sock.call("unknownRPC123", "AAAAA").catch(e => {  }).then(x => {
695
+                console.log("X",x);
696
+                
697
+            })
686
         }).catch(e => {
698
         }).catch(e => {
687
             console.log("unexpected connect catch clause");
699
             console.log("unexpected connect catch clause");
688
             done(e)
700
             done(e)
695
 
707
 
696
         sock.connect().then(_ => {
708
         sock.connect().then(_ => {
697
             sock.call("unknownRPC123", "AAAAA").catch(e => {
709
             sock.call("unknownRPC123", "AAAAA").catch(e => {
698
-                sock.destroy()
699
-                serv.destroy()
710
+                sock.close()
711
+                serv.close()
700
                 done()
712
                 done()
701
             })
713
             })
702
         }).catch(e => {
714
         }).catch(e => {
704
             done(e)
716
             done(e)
705
         })
717
         })
706
     })
718
     })
719
+    */
707
 
720
 
708
 })
721
 })
709
 
722
 

+ 1
- 1
tsconfig.json View File

9
       "strict": true,
9
       "strict": true,
10
       "experimentalDecorators": true
10
       "experimentalDecorators": true
11
     },
11
     },
12
-    "include": ["src/**/*.ts", "test/**/*.ts", "Index.ts", "demo.ts"],
12
+    "include": ["src/**/*.ts", "test/**/*.ts", "Index.ts", "demo.ts", "scratchpad.ts"],
13
     "exclude": ["node_modules"]
13
     "exclude": ["node_modules"]
14
   }
14
   }

Loading…
Cancel
Save