@open-rpc/client-js
Advanced tools
Comparing version 1.3.3 to 1.4.0
@@ -7,5 +7,5 @@ export declare const ERR_TIMEOUT = 7777; | ||
code: number; | ||
data: any; | ||
data?: unknown; | ||
constructor(message: string, code: number, data?: any); | ||
} | ||
export declare const convertJSONToRPCError: (payload: any) => JSONRPCError; |
@@ -6,4 +6,4 @@ "use strict"; | ||
var c = new _1.Client(new _1.RequestManager([t])); | ||
c.request("addition", [2, 2]).then(function (result) { | ||
c.request({ method: "addition", params: [2, 2] }).then(function (result) { | ||
console.log('addition result: ', result); // tslint:disable-line | ||
}); |
@@ -8,63 +8,4 @@ import RequestManager from "./RequestManager"; | ||
import { JSONRPCError } from "./Error"; | ||
interface IClient { | ||
request(method: string, params: any): Promise<any>; | ||
} | ||
/** | ||
* OpenRPC Client JS is a browser-compatible JSON-RPC client with multiple transports and | ||
* multiple request managers to enable features like round-robin or fallback-by-position. | ||
* | ||
* @example | ||
* ```typescript | ||
* import { RequestManager, HTTPTransport, Client } from '@open-rpc/client-js'; | ||
* const transport = new HTTPTransport('http://localhost:3333'); | ||
* const client = new Client(new RequestManager([transport])); | ||
* const result = await client.request(‘addition’, [2, 2]); | ||
* // => { jsonrpc: '2.0', id: 1, result: 4 } | ||
* ``` | ||
* | ||
*/ | ||
declare class Client implements IClient { | ||
requestManager: RequestManager; | ||
constructor(requestManager: RequestManager); | ||
/** | ||
* Initiates [[RequestManager.startBatch]] in order to build a batch call. | ||
* | ||
* Subsequent calls to [[Client.request]] will be added to the batch. Once [[Client.stopBatch]] is called, the | ||
* promises for the [[Client.request]] will then be resolved. If the [[RequestManager]] already has a batch in | ||
* progress, this method is a noop. | ||
* | ||
* @example | ||
* myClient.startBatch(); | ||
* myClient.request("foo", ["bar"]).then(() => console.log('foobar')); | ||
* myClient.request("foo", ["baz"]).then(() => console.log('foobaz')); | ||
* myClient.stopBatch(); | ||
*/ | ||
startBatch(): void; | ||
/** | ||
* Initiates [[RequestManager.stopBatch]] in order to finalize and send the batch to the underlying transport. | ||
* | ||
* [[Client.stopBatch]] will send the [[Client.request]] calls made since the last [[Client.startBatch]] call. For | ||
* that reason, [[Client.startBatch]] MUST be called before [[Client.stopBatch]]. | ||
* | ||
* @example | ||
* myClient.startBatch(); | ||
* myClient.request("foo", ["bar"]).then(() => console.log('foobar')); | ||
* myClient.request("foo", ["baz"]).then(() => console.log('foobaz')); | ||
* myClient.stopBatch(); | ||
*/ | ||
stopBatch(): void; | ||
/** | ||
* A JSON-RPC call is represented by sending a Request object to a Server. | ||
* | ||
* @param method A String containing the name of the method to be invoked. Method names that begin with the word rpc | ||
* followed by a period character (U+002E or ASCII 46) are reserved for rpc-internal methods and extensions and | ||
* MUST NOT be used for anything else. | ||
* @param params A Structured value that holds the parameter values to be used during the invocation of the method. | ||
*/ | ||
request(method: string, params: any, timeout?: number): Promise<any>; | ||
notify(method: string, params: any): Promise<any>; | ||
onNotification(callback: (data: any) => void): void; | ||
onError(callback: (data: JSONRPCError) => void): void; | ||
} | ||
import Client from "./Client"; | ||
export default Client; | ||
export { Client, RequestManager, HTTPTransport, EventEmitterTransport, WebSocketTransport, JSONRPCError, PostMessageWindowTransport, PostMessageIframeTransport, }; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -57,92 +21,4 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "JSONRPCError", { enumerable: true, get: function () { return Error_1.JSONRPCError; } }); | ||
/** | ||
* OpenRPC Client JS is a browser-compatible JSON-RPC client with multiple transports and | ||
* multiple request managers to enable features like round-robin or fallback-by-position. | ||
* | ||
* @example | ||
* ```typescript | ||
* import { RequestManager, HTTPTransport, Client } from '@open-rpc/client-js'; | ||
* const transport = new HTTPTransport('http://localhost:3333'); | ||
* const client = new Client(new RequestManager([transport])); | ||
* const result = await client.request(‘addition’, [2, 2]); | ||
* // => { jsonrpc: '2.0', id: 1, result: 4 } | ||
* ``` | ||
* | ||
*/ | ||
var Client = /** @class */ (function () { | ||
function Client(requestManager) { | ||
this.requestManager = requestManager; | ||
} | ||
/** | ||
* Initiates [[RequestManager.startBatch]] in order to build a batch call. | ||
* | ||
* Subsequent calls to [[Client.request]] will be added to the batch. Once [[Client.stopBatch]] is called, the | ||
* promises for the [[Client.request]] will then be resolved. If the [[RequestManager]] already has a batch in | ||
* progress, this method is a noop. | ||
* | ||
* @example | ||
* myClient.startBatch(); | ||
* myClient.request("foo", ["bar"]).then(() => console.log('foobar')); | ||
* myClient.request("foo", ["baz"]).then(() => console.log('foobaz')); | ||
* myClient.stopBatch(); | ||
*/ | ||
Client.prototype.startBatch = function () { | ||
return this.requestManager.startBatch(); | ||
}; | ||
/** | ||
* Initiates [[RequestManager.stopBatch]] in order to finalize and send the batch to the underlying transport. | ||
* | ||
* [[Client.stopBatch]] will send the [[Client.request]] calls made since the last [[Client.startBatch]] call. For | ||
* that reason, [[Client.startBatch]] MUST be called before [[Client.stopBatch]]. | ||
* | ||
* @example | ||
* myClient.startBatch(); | ||
* myClient.request("foo", ["bar"]).then(() => console.log('foobar')); | ||
* myClient.request("foo", ["baz"]).then(() => console.log('foobaz')); | ||
* myClient.stopBatch(); | ||
*/ | ||
Client.prototype.stopBatch = function () { | ||
return this.requestManager.stopBatch(); | ||
}; | ||
/** | ||
* A JSON-RPC call is represented by sending a Request object to a Server. | ||
* | ||
* @param method A String containing the name of the method to be invoked. Method names that begin with the word rpc | ||
* followed by a period character (U+002E or ASCII 46) are reserved for rpc-internal methods and extensions and | ||
* MUST NOT be used for anything else. | ||
* @param params A Structured value that holds the parameter values to be used during the invocation of the method. | ||
*/ | ||
Client.prototype.request = function (method, params, timeout) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.requestManager.connectPromise]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/, this.requestManager.request(method, params, false, timeout)]; | ||
} | ||
}); | ||
}); | ||
}; | ||
Client.prototype.notify = function (method, params) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, this.requestManager.connectPromise]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/, this.requestManager.request(method, params, true)]; | ||
} | ||
}); | ||
}); | ||
}; | ||
Client.prototype.onNotification = function (callback) { | ||
this.requestManager.requestChannel.addListener("notification", callback); | ||
}; | ||
Client.prototype.onError = function (callback) { | ||
this.requestManager.requestChannel.addListener("error", callback); | ||
}; | ||
return Client; | ||
}()); | ||
exports.Client = Client; | ||
exports.default = Client; | ||
var Client_1 = __importDefault(require("./Client")); | ||
exports.Client = Client_1.default; | ||
exports.default = Client_1.default; |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var _1 = __importDefault(require(".")); | ||
var _1 = require("."); | ||
var RequestManager_1 = __importDefault(require("./RequestManager")); | ||
@@ -16,3 +16,3 @@ var EventEmitterTransport_1 = __importDefault(require("./transports/EventEmitterTransport")); | ||
var emitter = new events_1.EventEmitter(); | ||
var c = new _1.default(new RequestManager_1.default([new EventEmitterTransport_1.default(emitter, "from1", "to1")])); | ||
var c = new _1.Client(new RequestManager_1.default([new EventEmitterTransport_1.default(emitter, "from1", "to1")])); | ||
expect(!!c).toEqual(true); | ||
@@ -22,15 +22,15 @@ }); | ||
var emitter = new events_1.EventEmitter(); | ||
var c = new _1.default(new RequestManager_1.default([new EventEmitterTransport_1.default(emitter, "from1", "to1")])); | ||
var c = new _1.Client(new RequestManager_1.default([new EventEmitterTransport_1.default(emitter, "from1", "to1")])); | ||
expect(typeof c.request).toEqual("function"); | ||
expect(typeof c.request("my_method", null).then).toEqual("function"); | ||
expect(typeof c.request({ method: "my_method" }).then).toEqual("function"); | ||
}); | ||
it("has a notify method that returns a promise", function () { | ||
var emitter = new events_1.EventEmitter(); | ||
var c = new _1.default(new RequestManager_1.default([new EventEmitterTransport_1.default(emitter, "from1", "to1")])); | ||
var c = new _1.Client(new RequestManager_1.default([new EventEmitterTransport_1.default(emitter, "from1", "to1")])); | ||
expect(typeof c.request).toEqual("function"); | ||
expect(typeof c.notify("my_method", null).then).toEqual("function"); | ||
expect(typeof c.notify({ method: "my_method" }).then).toEqual("function"); | ||
}); | ||
it("can recieve notifications", function (done) { | ||
var emitter = new events_1.EventEmitter(); | ||
var c = new _1.default(new RequestManager_1.default([new EventEmitterTransport_1.default(emitter, "from1", "to1")])); | ||
var c = new _1.Client(new RequestManager_1.default([new EventEmitterTransport_1.default(emitter, "from1", "to1")])); | ||
eventEmitter_1.addMockServerTransport(emitter, "from1", "to1://asdf/rpc-notification"); | ||
@@ -42,3 +42,3 @@ c.onNotification(function () { return done(); }); | ||
var emitter = new events_1.EventEmitter(); | ||
var c = new _1.default(new RequestManager_1.default([new EventEmitterTransport_1.default(emitter, "from1", "to1")])); | ||
var c = new _1.Client(new RequestManager_1.default([new EventEmitterTransport_1.default(emitter, "from1", "to1")])); | ||
// tslint:disable-next-line:no-empty | ||
@@ -53,3 +53,3 @@ c.onError(function (err) { }); | ||
var rm = new RequestManager_1.default([new EventEmitterTransport_1.default(emitter, "from1", "to1")]); | ||
var c = new _1.default(rm); | ||
var c = new _1.Client(rm); | ||
c.startBatch(); | ||
@@ -62,3 +62,3 @@ // expect(mockedRequestManager.mock.instances[0].startBatch).toHaveBeenCalled(); | ||
var rm = new RequestManager_1.default([new EventEmitterTransport_1.default(emitter, "from1", "to1")]); | ||
var c = new _1.default(rm); | ||
var c = new _1.Client(rm); | ||
c.startBatch(); | ||
@@ -65,0 +65,0 @@ c.stopBatch(); |
@@ -7,2 +7,3 @@ /// <reference types="node" /> | ||
import { EventEmitter } from "events"; | ||
import { JSONRPCMessage } from "./ClientInterface"; | ||
export declare type RequestChannel = StrictEventEmitter<EventEmitter, IRequestEvents>; | ||
@@ -24,3 +25,3 @@ export interface IRequestEvents { | ||
getPrimaryTransport(): Transport; | ||
request(method: string, params: any[], notification?: boolean, timeout?: number): Promise<any>; | ||
request(requestObject: JSONRPCMessage, notification?: boolean, timeout?: number): Promise<any>; | ||
close(): void; | ||
@@ -27,0 +28,0 @@ /** |
@@ -74,3 +74,3 @@ "use strict"; | ||
}; | ||
RequestManager.prototype.request = function (method, params, notification, timeout) { | ||
RequestManager.prototype.request = function (requestObject, notification, timeout) { | ||
if (notification === void 0) { notification = false; } | ||
@@ -83,3 +83,3 @@ return __awaiter(this, void 0, void 0, function () { | ||
id = notification ? null : internalID; | ||
payload = { request: this.makeRequest(method, params, id), internalID: internalID }; | ||
payload = { request: this.makeRequest(requestObject.method, requestObject.params || [], id), internalID: internalID }; | ||
if (this.batchStarted) { | ||
@@ -86,0 +86,0 @@ result = new Promise(function (resolve, reject) { |
@@ -68,3 +68,3 @@ "use strict"; | ||
c = new RequestManager_1.default([transport]); | ||
return [4 /*yield*/, c.request("foo", ["bar"])]; | ||
return [4 /*yield*/, c.request({ method: "foo", params: ["bar"] })]; | ||
case 1: | ||
@@ -87,3 +87,3 @@ result = _a.sent(); | ||
c = new RequestManager_1.default([transport]); | ||
return [4 /*yield*/, expect(c.request("foo", ["bar"])).rejects.toThrowError("Error message")]; | ||
return [4 /*yield*/, expect(c.request({ method: "foo", params: ["bar"] })).rejects.toThrowError("Error message")]; | ||
case 1: | ||
@@ -109,3 +109,3 @@ _a.sent(); | ||
}); | ||
return [4 /*yield*/, expect(c.request("foo", ["bar"], false, 1000)) | ||
return [4 /*yield*/, expect(c.request({ method: "foo", params: ["bar"] }, false, 1000)) | ||
.rejects.toThrowError("Request timeout request took longer than 1000 ms to resolve")]; | ||
@@ -143,4 +143,4 @@ case 1: | ||
requests = [ | ||
c.request("foo", ["bar"]), | ||
c.request("foo", ["bar"]), | ||
c.request({ method: "foo", params: ["bar"] }), | ||
c.request({ method: "foo", params: ["bar"] }), | ||
]; | ||
@@ -166,4 +166,4 @@ c.stopBatch(); | ||
requests = [ | ||
c.request("foo", []), | ||
c.request("foo", ["bar"]), | ||
c.request({ method: "foo", params: [] }), | ||
c.request({ method: "foo", params: ["bar"] }) | ||
]; | ||
@@ -193,4 +193,4 @@ c.stopBatch(); | ||
requests = [ | ||
c.request("foo", [], true), | ||
c.request("foo", ["bar"], true), | ||
c.request({ method: "foo", params: [] }, true), | ||
c.request({ method: "foo", params: ["bar"] }, true), | ||
]; | ||
@@ -229,6 +229,6 @@ c.stopBatch(); | ||
c.startBatch(); | ||
c.request("foo", []); | ||
c.request({ method: "foo", params: [] }); | ||
expect(c.batch.length).toBe(1); | ||
c.startBatch(); | ||
c.request("foo", []); | ||
c.request({ method: "foo", params: [] }); | ||
expect(c.batch.length).toBe(2); | ||
@@ -235,0 +235,0 @@ return [2 /*return*/]; |
@@ -0,1 +1,21 @@ | ||
# [1.4.0](https://github.com/open-rpc/client-js/compare/1.3.3...1.4.0) (2020-07-27) | ||
### Bug Fixes | ||
* **provider:** rename to ClientInterface ([3bfe849](https://github.com/open-rpc/client-js/commit/3bfe84981aa6e37395a732269085d744cef05f68)) | ||
* **provider:** type ([2124382](https://github.com/open-rpc/client-js/commit/21243827b0f6a8b035a117c86ef6a4946fef442b)) | ||
* add default export back ([d2b4dc2](https://github.com/open-rpc/client-js/commit/d2b4dc2d4b7e12d38b6b9947467e3a11d7f6ca22)) | ||
* remove duplicate JSONRpcError type ([be1669f](https://github.com/open-rpc/client-js/commit/be1669fc548b5e542c2b92a24730dfeecbefc4fe)) | ||
* **README:** change example interfaces ([6904bab](https://github.com/open-rpc/client-js/commit/6904bab4b534336778e117dd0a41abb22700b147)) | ||
* **README:** consistent naming ([40242fe](https://github.com/open-rpc/client-js/commit/40242fec0c4c4126744e748fe526bccea729ecb3)) | ||
* **README:** transport ordering ([5b52a17](https://github.com/open-rpc/client-js/commit/5b52a17a4c4271b1856b9abede7343ef5f1cc922)) | ||
* **typdoc:** add typedoc.jsosn and use library mode ([7f7c94c](https://github.com/open-rpc/client-js/commit/7f7c94cd793ca7441087ef1ddc91db8bef87205c)) | ||
* request manager requestObject type should be JSONRPCMessage ([5a3c194](https://github.com/open-rpc/client-js/commit/5a3c1949a7e03363c4c5809082ea304274817245)) | ||
### Features | ||
* change public `request` interface to match provider ([bd33563](https://github.com/open-rpc/client-js/commit/bd33563e40e40464d94028f567f76bb5b297bd22)) | ||
## [1.3.3](https://github.com/open-rpc/client-js/compare/1.3.2...1.3.3) (2020-07-17) | ||
@@ -2,0 +22,0 @@ |
{ | ||
"name": "@open-rpc/client-js", | ||
"version": "1.3.3", | ||
"version": "1.4.0", | ||
"description": " A browser-compatible JSON-RPC client with multiple transports.", | ||
"main": "build/index.js", | ||
"scripts": { | ||
"build": "tsc && typedoc --out docs", | ||
"build": "tsc && typedoc src/index.ts", | ||
"lint": "tslint --fix -p .", | ||
@@ -32,3 +32,3 @@ "test": "npm run lint && jest --coverage" | ||
"tslint": "^6.0.0", | ||
"typedoc": "^0.17.0", | ||
"typedoc": "^0.17.0-3", | ||
"typescript": "^3.4.5" | ||
@@ -35,0 +35,0 @@ }, |
@@ -17,6 +17,7 @@ # OpenRPC Client JS | ||
- EventEmitter | ||
- HTTP/HTTPS | ||
- WebSocket | ||
- Event Emitter | ||
```javascript | ||
@@ -26,3 +27,3 @@ import { RequestManager, HTTPTransport, Client } from "@open-rpc/client-js"; | ||
const client = new Client(new RequestManager([transport])); | ||
const result = await client.request("addition", [2, 2]); | ||
const result = await client.request({method: "addition", params: [2, 2]}); | ||
// => { jsonrpc: '2.0', id: 1, result: 4 } | ||
@@ -59,3 +60,3 @@ ``` | ||
const main = async () => { | ||
const result = await client.request("addition", [2, 2]); | ||
const result = await client.request({method: "addition", params: [2, 2]}); | ||
console.log(result); | ||
@@ -76,6 +77,4 @@ }; | ||
```javascript | ||
import { EventEmitter } from "events"; | ||
import { RequestManager, Client, HTTPTransport } from "@open-rpc/client-js"; | ||
const emitter = new EventEmitter(); | ||
const transport = new HTTPTransport("http://localhost:3333"); | ||
@@ -86,3 +85,3 @@ const requestManager = new RequestManager([transport]); | ||
const main = async () => { | ||
const result = await client.request("addition", [2, 2]); | ||
const result = await client.request({method: "addition", params: [2, 2]}); | ||
console.log(result); | ||
@@ -100,3 +99,3 @@ }; | ||
<details> | ||
<summary>Websocket</summary> | ||
<summary>WebSocket</summary> | ||
@@ -111,3 +110,3 @@ ```javascript | ||
const main = async () => { | ||
const result = await client.request("addition", [2, 2]); | ||
const result = await client.request({method: "addition", params: [2, 2]}); | ||
console.log(result); | ||
@@ -114,0 +113,0 @@ }; |
@@ -8,3 +8,3 @@ export const ERR_TIMEOUT = 7777; | ||
public code: number; | ||
public data: any; | ||
public data?: unknown; | ||
constructor(message: string, code: number, data?: any) { | ||
@@ -11,0 +11,0 @@ super(message); |
@@ -5,4 +5,4 @@ import { Client, RequestManager, HTTPTransport } from "."; | ||
c.request("addition", [2, 2]).then((result: any) => { | ||
c.request({method: "addition", params: [2, 2]}).then((result: any) => { | ||
console.log('addition result: ', result); // tslint:disable-line | ||
}); |
@@ -1,2 +0,2 @@ | ||
import Client from "."; | ||
import { Client } from "."; | ||
import RequestManager from "./RequestManager"; | ||
@@ -19,3 +19,3 @@ import EventEmitterTransport from "./transports/EventEmitterTransport"; | ||
expect(typeof c.request).toEqual("function"); | ||
expect(typeof c.request("my_method", null).then).toEqual("function"); | ||
expect(typeof c.request({ method: "my_method" }).then).toEqual("function"); | ||
}); | ||
@@ -27,3 +27,3 @@ | ||
expect(typeof c.request).toEqual("function"); | ||
expect(typeof c.notify("my_method", null).then).toEqual("function"); | ||
expect(typeof c.notify({ method: "my_method" }).then).toEqual("function"); | ||
}); | ||
@@ -30,0 +30,0 @@ |
@@ -8,87 +8,4 @@ import RequestManager from "./RequestManager"; | ||
import { JSONRPCError } from "./Error"; | ||
import Client from "./Client"; | ||
interface IClient { | ||
request(method: string, params: any): Promise<any>; | ||
} | ||
/** | ||
* OpenRPC Client JS is a browser-compatible JSON-RPC client with multiple transports and | ||
* multiple request managers to enable features like round-robin or fallback-by-position. | ||
* | ||
* @example | ||
* ```typescript | ||
* import { RequestManager, HTTPTransport, Client } from '@open-rpc/client-js'; | ||
* const transport = new HTTPTransport('http://localhost:3333'); | ||
* const client = new Client(new RequestManager([transport])); | ||
* const result = await client.request(‘addition’, [2, 2]); | ||
* // => { jsonrpc: '2.0', id: 1, result: 4 } | ||
* ``` | ||
* | ||
*/ | ||
class Client implements IClient { | ||
public requestManager: RequestManager; | ||
constructor(requestManager: RequestManager) { | ||
this.requestManager = requestManager; | ||
} | ||
/** | ||
* Initiates [[RequestManager.startBatch]] in order to build a batch call. | ||
* | ||
* Subsequent calls to [[Client.request]] will be added to the batch. Once [[Client.stopBatch]] is called, the | ||
* promises for the [[Client.request]] will then be resolved. If the [[RequestManager]] already has a batch in | ||
* progress, this method is a noop. | ||
* | ||
* @example | ||
* myClient.startBatch(); | ||
* myClient.request("foo", ["bar"]).then(() => console.log('foobar')); | ||
* myClient.request("foo", ["baz"]).then(() => console.log('foobaz')); | ||
* myClient.stopBatch(); | ||
*/ | ||
public startBatch(): void { | ||
return this.requestManager.startBatch(); | ||
} | ||
/** | ||
* Initiates [[RequestManager.stopBatch]] in order to finalize and send the batch to the underlying transport. | ||
* | ||
* [[Client.stopBatch]] will send the [[Client.request]] calls made since the last [[Client.startBatch]] call. For | ||
* that reason, [[Client.startBatch]] MUST be called before [[Client.stopBatch]]. | ||
* | ||
* @example | ||
* myClient.startBatch(); | ||
* myClient.request("foo", ["bar"]).then(() => console.log('foobar')); | ||
* myClient.request("foo", ["baz"]).then(() => console.log('foobaz')); | ||
* myClient.stopBatch(); | ||
*/ | ||
public stopBatch(): void { | ||
return this.requestManager.stopBatch(); | ||
} | ||
/** | ||
* A JSON-RPC call is represented by sending a Request object to a Server. | ||
* | ||
* @param method A String containing the name of the method to be invoked. Method names that begin with the word rpc | ||
* followed by a period character (U+002E or ASCII 46) are reserved for rpc-internal methods and extensions and | ||
* MUST NOT be used for anything else. | ||
* @param params A Structured value that holds the parameter values to be used during the invocation of the method. | ||
*/ | ||
public async request(method: string, params: any, timeout?: number) { | ||
await this.requestManager.connectPromise; | ||
return this.requestManager.request(method, params, false, timeout); | ||
} | ||
public async notify(method: string, params: any) { | ||
await this.requestManager.connectPromise; | ||
return this.requestManager.request(method, params, true); | ||
} | ||
public onNotification(callback: (data: any) => void) { | ||
this.requestManager.requestChannel.addListener("notification", callback); | ||
} | ||
public onError(callback: (data: JSONRPCError) => void) { | ||
this.requestManager.requestChannel.addListener("error", callback); | ||
} | ||
} | ||
export default Client; | ||
@@ -95,0 +12,0 @@ export { |
@@ -28,3 +28,3 @@ import RequestManager from "./RequestManager"; | ||
const c = new RequestManager([transport]); | ||
const result = await c.request("foo", ["bar"]); | ||
const result = await c.request({ method: "foo", params: ["bar"] }); | ||
expect(result.method).toEqual("foo"); | ||
@@ -39,4 +39,4 @@ expect(result.params).toEqual(["bar"]); | ||
const c = new RequestManager([transport]); | ||
await expect(c.request("foo", ["bar"])).rejects.toThrowError("Error message"); | ||
}); | ||
await expect(c.request({ method: "foo", params: ["bar"] })).rejects.toThrowError("Error message"); | ||
}); | ||
@@ -53,3 +53,3 @@ it("can error on malformed response and recieve error", async () => { | ||
}); | ||
await expect(c.request("foo", ["bar"], false, 1000)) | ||
await expect(c.request({ method: "foo", params: ["bar"] }, false, 1000)) | ||
.rejects.toThrowError("Request timeout request took longer than 1000 ms to resolve"); | ||
@@ -75,4 +75,4 @@ const formatError = await unknownError as JSONRPCError; | ||
const requests = [ | ||
c.request("foo", ["bar"]), | ||
c.request("foo", ["bar"]), | ||
c.request({ method: "foo", params: ["bar"] }), | ||
c.request({ method: "foo", params: ["bar"] }), | ||
]; | ||
@@ -92,4 +92,4 @@ c.stopBatch(); | ||
const requests = [ | ||
c.request("foo", []), | ||
c.request("foo", ["bar"]), | ||
c.request({ method: "foo", params: [] }), | ||
c.request({ method: "foo", params: ["bar"] }) | ||
]; | ||
@@ -113,4 +113,4 @@ c.stopBatch(); | ||
const requests = [ | ||
c.request("foo", [], true), | ||
c.request("foo", ["bar"], true), | ||
c.request({ method: "foo", params: [] }, true), | ||
c.request({ method: "foo", params: ["bar"] }, true), | ||
]; | ||
@@ -140,6 +140,6 @@ c.stopBatch(); | ||
c.startBatch(); | ||
c.request("foo", []); | ||
c.request({ method: "foo", params: [] }); | ||
expect(c.batch.length).toBe(1); | ||
c.startBatch(); | ||
c.request("foo", []); | ||
c.request({ method: "foo", params: [] }); | ||
expect(c.batch.length).toBe(2); | ||
@@ -146,0 +146,0 @@ }); |
@@ -6,2 +6,3 @@ import { Transport } from "./transports/Transport"; | ||
import { EventEmitter } from "events"; | ||
import { JSONRPCMessage } from "./ClientInterface"; | ||
@@ -47,7 +48,7 @@ export type RequestChannel = StrictEventEmitter<EventEmitter, IRequestEvents>; | ||
public async request(method: string, params: any[], notification: boolean = false, timeout?: number): Promise<any> { | ||
public async request(requestObject: JSONRPCMessage, notification: boolean = false, timeout?: number): Promise<any> { | ||
const internalID = (++this.lastId).toString(); | ||
const id = notification ? null : internalID; | ||
// naively grab first transport and use it | ||
const payload = {request: this.makeRequest(method, params, id) , internalID}; | ||
const payload = {request: this.makeRequest(requestObject.method, requestObject.params || [], id) , internalID}; | ||
if (this.batchStarted) { | ||
@@ -54,0 +55,0 @@ const result = new Promise((resolve, reject) => { |
265399
101
4719
120