RpcProvider.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. var microevent_ts_1 = require("microevent.ts");
  4. var MSG_RESOLVE_TRANSACTION = "resolve_transaction", MSG_REJECT_TRANSACTION = "reject_transaction", MSG_ERROR = "error";
  5. var RpcProvider = /** @class */ (function () {
  6. function RpcProvider(_dispatch, _rpcTimeout) {
  7. if (_rpcTimeout === void 0) { _rpcTimeout = 0; }
  8. this._dispatch = _dispatch;
  9. this._rpcTimeout = _rpcTimeout;
  10. this.error = new microevent_ts_1.Event();
  11. this._rpcHandlers = {};
  12. this._signalHandlers = {};
  13. this._pendingTransactions = {};
  14. this._nextTransactionId = 0;
  15. }
  16. RpcProvider.prototype.dispatch = function (payload) {
  17. var message = payload;
  18. switch (message.type) {
  19. case RpcProvider.MessageType.signal:
  20. return this._handleSignal(message);
  21. case RpcProvider.MessageType.rpc:
  22. return this._handeRpc(message);
  23. case RpcProvider.MessageType.internal:
  24. return this._handleInternal(message);
  25. default:
  26. this._raiseError("invalid message type " + message.type);
  27. }
  28. };
  29. RpcProvider.prototype.rpc = function (id, payload, transfer) {
  30. var _this = this;
  31. var transactionId = this._nextTransactionId++;
  32. this._dispatch({
  33. type: RpcProvider.MessageType.rpc,
  34. transactionId: transactionId,
  35. id: id,
  36. payload: payload
  37. }, transfer ? transfer : undefined);
  38. return new Promise(function (resolve, reject) {
  39. var transaction = _this._pendingTransactions[transactionId] = {
  40. id: transactionId,
  41. resolve: resolve,
  42. reject: reject
  43. };
  44. if (_this._rpcTimeout > 0) {
  45. _this._pendingTransactions[transactionId].timeoutHandle =
  46. setTimeout(function () { return _this._transactionTimeout(transaction); }, _this._rpcTimeout);
  47. }
  48. });
  49. };
  50. ;
  51. RpcProvider.prototype.signal = function (id, payload, transfer) {
  52. this._dispatch({
  53. type: RpcProvider.MessageType.signal,
  54. id: id,
  55. payload: payload,
  56. }, transfer ? transfer : undefined);
  57. return this;
  58. };
  59. RpcProvider.prototype.registerRpcHandler = function (id, handler) {
  60. if (this._rpcHandlers[id]) {
  61. throw new Error("rpc handler for " + id + " already registered");
  62. }
  63. this._rpcHandlers[id] = handler;
  64. return this;
  65. };
  66. ;
  67. RpcProvider.prototype.registerSignalHandler = function (id, handler) {
  68. if (!this._signalHandlers[id]) {
  69. this._signalHandlers[id] = [];
  70. }
  71. this._signalHandlers[id].push(handler);
  72. return this;
  73. };
  74. RpcProvider.prototype.deregisterRpcHandler = function (id, handler) {
  75. if (this._rpcHandlers[id]) {
  76. delete this._rpcHandlers[id];
  77. }
  78. return this;
  79. };
  80. ;
  81. RpcProvider.prototype.deregisterSignalHandler = function (id, handler) {
  82. if (this._signalHandlers[id]) {
  83. this._signalHandlers[id] = this._signalHandlers[id].filter(function (h) { return handler !== h; });
  84. }
  85. return this;
  86. };
  87. RpcProvider.prototype._raiseError = function (error) {
  88. this.error.dispatch(new Error(error));
  89. this._dispatch({
  90. type: RpcProvider.MessageType.internal,
  91. id: MSG_ERROR,
  92. payload: error
  93. });
  94. };
  95. RpcProvider.prototype._handleSignal = function (message) {
  96. if (!this._signalHandlers[message.id]) {
  97. return this._raiseError("invalid signal " + message.id);
  98. }
  99. this._signalHandlers[message.id].forEach(function (handler) { return handler(message.payload); });
  100. };
  101. RpcProvider.prototype._handeRpc = function (message) {
  102. var _this = this;
  103. if (!this._rpcHandlers[message.id]) {
  104. return this._raiseError("invalid rpc " + message.id);
  105. }
  106. Promise.resolve(this._rpcHandlers[message.id](message.payload))
  107. .then(function (result) { return _this._dispatch({
  108. type: RpcProvider.MessageType.internal,
  109. id: MSG_RESOLVE_TRANSACTION,
  110. transactionId: message.transactionId,
  111. payload: result
  112. }); }, function (reason) { return _this._dispatch({
  113. type: RpcProvider.MessageType.internal,
  114. id: MSG_REJECT_TRANSACTION,
  115. transactionId: message.transactionId,
  116. payload: reason
  117. }); });
  118. };
  119. RpcProvider.prototype._handleInternal = function (message) {
  120. switch (message.id) {
  121. case MSG_RESOLVE_TRANSACTION:
  122. if (!this._pendingTransactions[message.transactionId]) {
  123. return this._raiseError("no pending transaction with id " + message.transactionId);
  124. }
  125. this._pendingTransactions[message.transactionId].resolve(message.payload);
  126. this._clearTransaction(this._pendingTransactions[message.transactionId]);
  127. break;
  128. case MSG_REJECT_TRANSACTION:
  129. if (!this._pendingTransactions[message.transactionId]) {
  130. return this._raiseError("no pending transaction with id " + message.transactionId);
  131. }
  132. this._pendingTransactions[message.transactionId].reject(message.payload);
  133. this._clearTransaction(this._pendingTransactions[message.transactionId]);
  134. break;
  135. case MSG_ERROR:
  136. this.error.dispatch(new Error("remote error: " + message.payload));
  137. break;
  138. default:
  139. this._raiseError("unhandled internal message " + message.id);
  140. break;
  141. }
  142. };
  143. RpcProvider.prototype._transactionTimeout = function (transaction) {
  144. transaction.reject('transaction timed out');
  145. this._raiseError("transaction " + transaction.id + " timed out");
  146. delete this._pendingTransactions[transaction.id];
  147. return;
  148. };
  149. RpcProvider.prototype._clearTransaction = function (transaction) {
  150. if (typeof (transaction.timeoutHandle) !== 'undefined') {
  151. clearTimeout(transaction.timeoutHandle);
  152. }
  153. delete this._pendingTransactions[transaction.id];
  154. };
  155. return RpcProvider;
  156. }());
  157. (function (RpcProvider) {
  158. var MessageType;
  159. (function (MessageType) {
  160. MessageType[MessageType["signal"] = 0] = "signal";
  161. MessageType[MessageType["rpc"] = 1] = "rpc";
  162. MessageType[MessageType["internal"] = 2] = "internal";
  163. })(MessageType = RpcProvider.MessageType || (RpcProvider.MessageType = {}));
  164. ;
  165. })(RpcProvider || (RpcProvider = {}));
  166. exports.default = RpcProvider;