From 0155c8109edf1ffc6508de3125072afc418de8b4 Mon Sep 17 00:00:00 2001 From: shanejonas Date: Mon, 19 Oct 2020 11:12:27 -0700 Subject: [PATCH 1/2] feat: add `close` method Client to close connection and cleanup event listeners --- README.md | 1 + src/Client.ts | 10 +++++++++- src/ClientInterface.ts | 4 ++++ src/RequestManager.ts | 2 ++ src/transports/Transport.ts | 8 ++++++++ 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 658df8c..2f1e605 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ const main = async () => { main().then(() => { console.log("DONE"); + client.close(); }); ``` diff --git a/src/Client.ts b/src/Client.ts index 24c5502..57618e2 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -1,6 +1,7 @@ import RequestManager from "./RequestManager"; import { JSONRPCError } from "./Error"; import { IClient, RequestArguments, NotificationArguments } from "./ClientInterface"; +import { IJSONRPCNotification } from "./Request"; /** * OpenRPC Client JS is a browser-compatible JSON-RPC client with multiple transports and @@ -80,13 +81,20 @@ class Client implements IClient { return this.requestManager.request(requestObject, true); } - public onNotification(callback: (data: any) => void) { + public onNotification(callback: (data: IJSONRPCNotification) => void) { this.requestManager.requestChannel.addListener("notification", callback); } public onError(callback: (data: JSONRPCError) => void) { this.requestManager.requestChannel.addListener("error", callback); } + + /** + * Close connection + */ + public close() { + this.requestManager.close(); + } } export default Client; diff --git a/src/ClientInterface.ts b/src/ClientInterface.ts index 2c40f34..1c2d166 100644 --- a/src/ClientInterface.ts +++ b/src/ClientInterface.ts @@ -1,3 +1,5 @@ +import { IJSONRPCNotification } from "./Request"; + interface Arguments { readonly method: string; readonly params?: readonly unknown[] | object; @@ -12,4 +14,6 @@ export type JSONRPCMessage = RequestArguments | NotificationArguments; export interface IClient { request(args: RequestArguments): Promise; notify(args: NotificationArguments): Promise; + close(): void; + onNotification(callback: (data: IJSONRPCNotification) => void): void; } diff --git a/src/RequestManager.ts b/src/RequestManager.ts index 285f95c..348f699 100644 --- a/src/RequestManager.ts +++ b/src/RequestManager.ts @@ -59,7 +59,9 @@ class RequestManager { } public close(): void { + this.requestChannel.removeAllListeners(); this.transports.forEach((transport) => { + transport.unsubscribe(); transport.close(); }); } diff --git a/src/transports/Transport.ts b/src/transports/Transport.ts index 894982d..afd44b1 100644 --- a/src/transports/Transport.ts +++ b/src/transports/Transport.ts @@ -35,6 +35,14 @@ export abstract class Transport { public subscribe(event: TransportEventName, handler: ITransportEvents[TransportEventName]) { this.transportRequestManager.transportEventChannel.addListener(event, handler); } + public unsubscribe(event?: TransportEventName, handler?: ITransportEvents[TransportEventName]) { + if (!event) { + return this.transportRequestManager.transportEventChannel.removeAllListeners(); + } + if (event && handler) { + this.transportRequestManager.transportEventChannel.removeListener(event, handler); + } + } protected parseData(data: JSONRPCRequestData) { if (data instanceof Array) { return data.map((batch) => batch.request.request); From 01393916731d12195a7719784467aee8ef48cb4c Mon Sep 17 00:00:00 2001 From: shanejonas Date: Mon, 19 Oct 2020 13:43:20 -0700 Subject: [PATCH 2/2] fix(Client): add close test --- src/index.test.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/index.test.ts b/src/index.test.ts index 28b1a99..4b08155 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -61,4 +61,11 @@ describe("client-js", () => { c.stopBatch(); }); + describe("can close", () => { + const emitter = new EventEmitter(); + const rm = new RequestManager([new EventEmitterTransport(emitter, "from1", "to1")]); + const c = new Client(rm); + c.close(); + }); + });