@typerighter/rpc-client 0.25.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -46,6 +46,9 @@ export class JsonRpcClient {
46
46
  return;
47
47
  this.disposed = true;
48
48
  this.rejectAllPending('Connection disposed');
49
+ // Close the streams so the server detects the disconnect
50
+ this.reader.destroy();
51
+ this.writer.destroy();
49
52
  }
50
53
  // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/connection.ts#L565
51
54
  onClose(listener) {
@@ -74,9 +77,18 @@ export class JsonRpcClient {
74
77
  }
75
78
  // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/connection.ts#L557
76
79
  onNotification(method, handler) {
77
- this.notificationHandlers.set(method, handler);
80
+ const handlers = this.notificationHandlers.get(method) ?? [];
81
+ handlers.push(handler);
82
+ this.notificationHandlers.set(method, handlers);
78
83
  return {
79
- dispose: () => this.notificationHandlers.delete(method),
84
+ dispose: () => {
85
+ const list = this.notificationHandlers.get(method);
86
+ if (list) {
87
+ const idx = list.indexOf(handler);
88
+ if (idx !== -1)
89
+ list.splice(idx, 1);
90
+ }
91
+ },
80
92
  };
81
93
  }
82
94
  // Accumulate chunk and parse as many complete messages as possible
@@ -136,14 +148,16 @@ export class JsonRpcClient {
136
148
  }
137
149
  }
138
150
  handleNotification(notification) {
139
- const handler = this.notificationHandlers.get(notification.method);
140
- if (!handler)
151
+ const handlers = this.notificationHandlers.get(notification.method);
152
+ if (!handlers?.length)
141
153
  return;
142
- try {
143
- handler(notification.params);
144
- }
145
- catch (error) {
146
- console.error(`[jsonrpc] Notification handler for '${notification.method}' threw:`, error);
154
+ for (const handler of handlers) {
155
+ try {
156
+ handler(notification.params);
157
+ }
158
+ catch (error) {
159
+ console.error(`[jsonrpc] Notification handler for '${notification.method}' threw:`, error);
160
+ }
147
161
  }
148
162
  }
149
163
  // Cleanup
package/dist/index.d.ts CHANGED
@@ -109,6 +109,8 @@ export declare class RpcClient {
109
109
  private constructor();
110
110
  static connectTcp(host: string, port: number): Promise<RpcClient>;
111
111
  static connectStdio(stdin: Readable, stdout: Writable): RpcClient;
112
+ /** Send exit notification and close the connection
113
+ * The detached server will detect the disconnect and save its cache */
112
114
  dispose(): void;
113
115
  onClose(callback: () => void): {
114
116
  dispose: () => void;
package/dist/index.js CHANGED
@@ -49,7 +49,10 @@ export class RpcClient {
49
49
  static connectStdio(stdin, stdout) {
50
50
  return new RpcClient(JsonRpcClient.connectStdio(stdin, stdout));
51
51
  }
52
+ /** Send exit notification and close the connection
53
+ * The detached server will detect the disconnect and save its cache */
52
54
  dispose() {
55
+ this.rpc.sendNotification('exit');
53
56
  this.rpc.dispose();
54
57
  }
55
58
  onClose(callback) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@typerighter/rpc-client",
4
- "version": "0.25.0",
4
+ "version": "0.27.0",
5
5
  "description": "JSON-RPC client for Typedown over TCP/stdio.",
6
6
  "repository": {
7
7
  "type": "git",
@@ -47,7 +47,7 @@ export class JsonRpcClient implements MessageConnection {
47
47
  // Request/response matching
48
48
  private sequenceNumber = 1;
49
49
  private responsePromises = new Map<number, PendingRequest>();
50
- private notificationHandlers = new Map<string, (params: unknown) => void>();
50
+ private notificationHandlers = new Map<string, Array<(params: unknown) => void>>();
51
51
 
52
52
  // Inbound buffer, raw chunks to avoid corrupting multi-byte UTF-8
53
53
  private chunks: Buffer[] = [];
@@ -86,6 +86,9 @@ export class JsonRpcClient implements MessageConnection {
86
86
  this.disposed = true;
87
87
 
88
88
  this.rejectAllPending('Connection disposed');
89
+ // Close the streams so the server detects the disconnect
90
+ this.reader.destroy();
91
+ this.writer.destroy();
89
92
  }
90
93
 
91
94
  // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/connection.ts#L565
@@ -118,9 +121,17 @@ export class JsonRpcClient implements MessageConnection {
118
121
 
119
122
  // https://github.com/microsoft/vscode-languageserver-node/blob/5010cdf9822e1038a30ee7eb6ee5d7aaa79acc4a/jsonrpc/src/common/connection.ts#L557
120
123
  onNotification (method: string, handler: (params: any) => void): Disposable {
121
- this.notificationHandlers.set(method, handler);
124
+ const handlers = this.notificationHandlers.get(method) ?? [];
125
+ handlers.push(handler);
126
+ this.notificationHandlers.set(method, handlers);
122
127
  return {
123
- dispose: () => this.notificationHandlers.delete(method),
128
+ dispose: () => {
129
+ const list = this.notificationHandlers.get(method);
130
+ if (list) {
131
+ const idx = list.indexOf(handler);
132
+ if (idx !== -1) list.splice(idx, 1);
133
+ }
134
+ },
124
135
  };
125
136
  }
126
137
 
@@ -190,14 +201,16 @@ export class JsonRpcClient implements MessageConnection {
190
201
  }
191
202
 
192
203
  private handleNotification (notification: NotificationMessage): void {
193
- const handler = this.notificationHandlers.get(notification.method);
204
+ const handlers = this.notificationHandlers.get(notification.method);
194
205
 
195
- if (!handler) return;
206
+ if (!handlers?.length) return;
196
207
 
197
- try {
198
- handler(notification.params);
199
- } catch (error) {
200
- console.error(`[jsonrpc] Notification handler for '${notification.method}' threw:`, error);
208
+ for (const handler of handlers) {
209
+ try {
210
+ handler(notification.params);
211
+ } catch (error) {
212
+ console.error(`[jsonrpc] Notification handler for '${notification.method}' threw:`, error);
213
+ }
201
214
  }
202
215
  }
203
216
 
package/src/index.ts CHANGED
@@ -166,7 +166,10 @@ export class RpcClient {
166
166
  return new RpcClient(JsonRpcClient.connectStdio(stdin, stdout));
167
167
  }
168
168
 
169
+ /** Send exit notification and close the connection
170
+ * The detached server will detect the disconnect and save its cache */
169
171
  dispose (): void {
172
+ this.rpc.sendNotification('exit');
170
173
  this.rpc.dispose();
171
174
  }
172
175