@gtkx/mcp 0.20.0 → 1.0.0-rc.1
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.
- package/README.md +122 -55
- package/bin/gtkx-mcp.js +8 -1
- package/dist/app-router.d.ts +35 -0
- package/dist/app-router.d.ts.map +1 -0
- package/dist/app-router.js +130 -0
- package/dist/app-router.js.map +1 -0
- package/dist/connection-registry.d.ts +12 -0
- package/dist/connection-registry.d.ts.map +1 -0
- package/dist/connection-registry.js +38 -0
- package/dist/connection-registry.js.map +1 -0
- package/dist/internal.d.ts +4 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +4 -0
- package/dist/internal.js.map +1 -0
- package/dist/protocol/errors.d.ts +24 -87
- package/dist/protocol/errors.d.ts.map +1 -1
- package/dist/protocol/errors.js +27 -91
- package/dist/protocol/errors.js.map +1 -1
- package/dist/protocol/schemas.d.ts +89 -0
- package/dist/protocol/schemas.d.ts.map +1 -0
- package/dist/protocol/schemas.js +56 -0
- package/dist/protocol/schemas.js.map +1 -0
- package/dist/reference.d.ts +13 -0
- package/dist/reference.d.ts.map +1 -0
- package/dist/reference.js +250 -0
- package/dist/reference.js.map +1 -0
- package/dist/server.d.ts +14 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +220 -0
- package/dist/server.js.map +1 -0
- package/dist/socket-server.d.ts +4 -38
- package/dist/socket-server.d.ts.map +1 -1
- package/dist/socket-server.js +26 -109
- package/dist/socket-server.js.map +1 -1
- package/dist/tool.d.ts +22 -0
- package/dist/tool.d.ts.map +1 -0
- package/dist/tool.js +36 -0
- package/dist/tool.js.map +1 -0
- package/dist/transport.d.ts +41 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +121 -0
- package/dist/transport.js.map +1 -0
- package/package.json +17 -11
- package/src/app-router.ts +172 -0
- package/src/connection-registry.ts +42 -0
- package/src/internal.ts +17 -0
- package/src/protocol/errors.ts +44 -100
- package/src/protocol/schemas.ts +148 -0
- package/src/reference.ts +340 -0
- package/src/server.ts +281 -0
- package/src/socket-server.ts +30 -154
- package/src/tool.ts +66 -0
- package/src/transport.ts +165 -0
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -399
- package/dist/cli.js.map +0 -1
- package/dist/connection-manager.d.ts +0 -48
- package/dist/connection-manager.d.ts.map +0 -1
- package/dist/connection-manager.js +0 -185
- package/dist/connection-manager.js.map +0 -1
- package/dist/index.d.ts +0 -5
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -5
- package/dist/index.js.map +0 -1
- package/dist/protocol/types.d.ts +0 -132
- package/dist/protocol/types.d.ts.map +0 -1
- package/dist/protocol/types.js +0 -46
- package/dist/protocol/types.js.map +0 -1
- package/src/cli.ts +0 -449
- package/src/connection-manager.ts +0 -247
- package/src/index.ts +0 -27
- package/src/protocol/types.ts +0 -153
package/src/socket-server.ts
CHANGED
|
@@ -1,99 +1,61 @@
|
|
|
1
|
-
import EventEmitter from "node:events";
|
|
2
1
|
import * as fs from "node:fs";
|
|
3
2
|
import * as net from "node:net";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
disconnection: [AppConnection];
|
|
17
|
-
request: [AppConnection, IpcRequest];
|
|
18
|
-
response: [AppConnection, IpcResponse];
|
|
19
|
-
error: [Error];
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Represents a connected application.
|
|
24
|
-
*/
|
|
25
|
-
export type AppConnection = {
|
|
26
|
-
/** Unique connection identifier */
|
|
27
|
-
id: string;
|
|
28
|
-
/** The underlying socket */
|
|
29
|
-
socket: net.Socket;
|
|
30
|
-
/** Buffer for incomplete messages */
|
|
31
|
-
buffer: string;
|
|
32
|
-
};
|
|
3
|
+
import type { ConnectionRegistry } from "./connection-registry.js";
|
|
4
|
+
import { DEFAULT_SOCKET_PATH } from "./protocol/schemas.js";
|
|
5
|
+
|
|
6
|
+
const isSocketLive = (socketPath: string): Promise<boolean> =>
|
|
7
|
+
new Promise((resolve) => {
|
|
8
|
+
const probe = net.connect(socketPath);
|
|
9
|
+
probe.once("connect", () => {
|
|
10
|
+
probe.destroy();
|
|
11
|
+
resolve(true);
|
|
12
|
+
});
|
|
13
|
+
probe.once("error", () => resolve(false));
|
|
14
|
+
});
|
|
33
15
|
|
|
34
|
-
|
|
35
|
-
* Unix domain socket server for MCP communication.
|
|
36
|
-
*
|
|
37
|
-
* Manages connections from GTKX applications and handles IPC messaging.
|
|
38
|
-
*/
|
|
39
|
-
export class SocketServer extends EventEmitter<SocketServerEventMap> {
|
|
16
|
+
export class SocketServer {
|
|
40
17
|
private server: net.Server | null = null;
|
|
41
|
-
private connections: Map<string, AppConnection> = new Map();
|
|
42
18
|
private socketPath: string;
|
|
19
|
+
private registry: ConnectionRegistry;
|
|
43
20
|
|
|
44
|
-
constructor(socketPath: string = DEFAULT_SOCKET_PATH) {
|
|
45
|
-
|
|
21
|
+
constructor(registry: ConnectionRegistry, socketPath: string = DEFAULT_SOCKET_PATH) {
|
|
22
|
+
this.registry = registry;
|
|
46
23
|
this.socketPath = socketPath;
|
|
47
24
|
}
|
|
48
25
|
|
|
49
|
-
get path(): string {
|
|
50
|
-
return this.socketPath;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
get isListening(): boolean {
|
|
54
|
-
return this.server?.listening ?? false;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
getConnections(): AppConnection[] {
|
|
58
|
-
return Array.from(this.connections.values());
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
getConnection(id: string): AppConnection | undefined {
|
|
62
|
-
return this.connections.get(id);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
26
|
async start(): Promise<void> {
|
|
66
|
-
if (this.server)
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
27
|
+
if (this.server) return;
|
|
69
28
|
|
|
70
29
|
if (fs.existsSync(this.socketPath)) {
|
|
30
|
+
if (await isSocketLive(this.socketPath)) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`Another GTKX MCP server already owns ${this.socketPath}. ` +
|
|
33
|
+
"Stop the other server (for example, the gtkx MCP server of another active session) and reconnect.",
|
|
34
|
+
);
|
|
35
|
+
}
|
|
71
36
|
fs.unlinkSync(this.socketPath);
|
|
72
37
|
}
|
|
73
38
|
|
|
74
39
|
return new Promise((resolve, reject) => {
|
|
75
|
-
this.server = net.createServer((socket) => this.
|
|
40
|
+
this.server = net.createServer((socket) => this.registry.register(socket));
|
|
76
41
|
|
|
42
|
+
let listening = false;
|
|
77
43
|
this.server.on("error", (error) => {
|
|
78
|
-
this.emit("error", error);
|
|
79
|
-
reject(error);
|
|
44
|
+
this.registry.emit("error", error);
|
|
45
|
+
if (!listening) reject(error);
|
|
80
46
|
});
|
|
81
47
|
|
|
82
48
|
this.server.listen(this.socketPath, () => {
|
|
49
|
+
listening = true;
|
|
83
50
|
resolve();
|
|
84
51
|
});
|
|
85
52
|
});
|
|
86
53
|
}
|
|
87
54
|
|
|
88
55
|
async stop(): Promise<void> {
|
|
89
|
-
if (!this.server)
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
56
|
+
if (!this.server) return;
|
|
92
57
|
|
|
93
|
-
|
|
94
|
-
connection.socket.destroy();
|
|
95
|
-
}
|
|
96
|
-
this.connections.clear();
|
|
58
|
+
this.registry.dispose("Server stopping");
|
|
97
59
|
|
|
98
60
|
return new Promise((resolve) => {
|
|
99
61
|
this.server?.close(() => {
|
|
@@ -105,90 +67,4 @@ export class SocketServer extends EventEmitter<SocketServerEventMap> {
|
|
|
105
67
|
});
|
|
106
68
|
});
|
|
107
69
|
}
|
|
108
|
-
|
|
109
|
-
send(connectionId: string, message: IpcMessage): boolean {
|
|
110
|
-
const connection = this.connections.get(connectionId);
|
|
111
|
-
if (!connection || !connection.socket.writable) {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const data = `${JSON.stringify(message)}\n`;
|
|
116
|
-
connection.socket.write(data);
|
|
117
|
-
return true;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
private handleConnection(socket: net.Socket): void {
|
|
121
|
-
const connectionId = crypto.randomUUID();
|
|
122
|
-
const connection: AppConnection = {
|
|
123
|
-
id: connectionId,
|
|
124
|
-
socket,
|
|
125
|
-
buffer: "",
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
this.connections.set(connectionId, connection);
|
|
129
|
-
this.emit("connection", connection);
|
|
130
|
-
|
|
131
|
-
socket.on("data", (data: Buffer) => this.handleData(connection, data));
|
|
132
|
-
|
|
133
|
-
socket.on("close", () => {
|
|
134
|
-
this.connections.delete(connectionId);
|
|
135
|
-
this.emit("disconnection", connection);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
socket.on("error", (error) => {
|
|
139
|
-
this.emit("error", error);
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
private handleData(connection: AppConnection, data: Buffer): void {
|
|
144
|
-
connection.buffer += data.toString();
|
|
145
|
-
|
|
146
|
-
let newlineIndex = connection.buffer.indexOf("\n");
|
|
147
|
-
while (newlineIndex !== -1) {
|
|
148
|
-
const line = connection.buffer.slice(0, newlineIndex);
|
|
149
|
-
connection.buffer = connection.buffer.slice(newlineIndex + 1);
|
|
150
|
-
|
|
151
|
-
if (line.trim()) {
|
|
152
|
-
this.processMessage(connection, line);
|
|
153
|
-
}
|
|
154
|
-
newlineIndex = connection.buffer.indexOf("\n");
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
private processMessage(connection: AppConnection, line: string): void {
|
|
159
|
-
let parsed: unknown;
|
|
160
|
-
try {
|
|
161
|
-
parsed = JSON.parse(line);
|
|
162
|
-
} catch {
|
|
163
|
-
const response: IpcResponse = {
|
|
164
|
-
id: "unknown",
|
|
165
|
-
error: invalidRequestError("Invalid JSON").toIpcError(),
|
|
166
|
-
};
|
|
167
|
-
this.send(connection.id, response);
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const message = parsed as Record<string, unknown>;
|
|
172
|
-
const hasMethod = typeof message.method === "string";
|
|
173
|
-
|
|
174
|
-
if (hasMethod) {
|
|
175
|
-
const requestResult = IpcRequestSchema.safeParse(parsed);
|
|
176
|
-
if (requestResult.success) {
|
|
177
|
-
this.emit("request", connection, requestResult.data);
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
} else {
|
|
181
|
-
const responseResult = IpcResponseSchema.safeParse(parsed);
|
|
182
|
-
if (responseResult.success) {
|
|
183
|
-
this.emit("response", connection, responseResult.data);
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const response: IpcResponse = {
|
|
189
|
-
id: (message.id as string | undefined) ?? "unknown",
|
|
190
|
-
error: invalidRequestError("Invalid message format").toIpcError(),
|
|
191
|
-
};
|
|
192
|
-
this.send(connection.id, response);
|
|
193
|
-
}
|
|
194
70
|
}
|
package/src/tool.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { McpServer, ToolCallback } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
import type { z } from "zod";
|
|
4
|
+
import { ProtocolError } from "./protocol/errors.js";
|
|
5
|
+
|
|
6
|
+
export const textContent = (text: string): CallToolResult => ({ content: [{ type: "text", text }] });
|
|
7
|
+
|
|
8
|
+
export const textError = (text: string): CallToolResult => ({
|
|
9
|
+
content: [{ type: "text", text }],
|
|
10
|
+
isError: true,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
export const imageContent = (data: string, mimeType: string): CallToolResult => ({
|
|
14
|
+
content: [{ type: "image", data, mimeType }],
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export type ToolArgs<Shape extends Record<string, z.ZodType>> = { [K in keyof Shape]: z.output<Shape[K]> };
|
|
18
|
+
|
|
19
|
+
type ToolKind = "readOnly" | "action";
|
|
20
|
+
|
|
21
|
+
export type Tool<Shape extends Record<string, z.ZodType> = Record<string, z.ZodType>> = {
|
|
22
|
+
name: string;
|
|
23
|
+
title: string;
|
|
24
|
+
kind: ToolKind;
|
|
25
|
+
description: string;
|
|
26
|
+
inputSchema: Shape;
|
|
27
|
+
handler: (args: ToolArgs<Shape>) => Promise<CallToolResult>;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const hasStringHint = (data: unknown): data is { hint: string } =>
|
|
31
|
+
typeof data === "object" && data !== null && "hint" in data && typeof data.hint === "string";
|
|
32
|
+
|
|
33
|
+
const runTool = async (
|
|
34
|
+
handler: (args: ToolArgs<Record<string, z.ZodType>>) => Promise<CallToolResult>,
|
|
35
|
+
args: ToolArgs<Record<string, z.ZodType>>,
|
|
36
|
+
): Promise<CallToolResult> => {
|
|
37
|
+
try {
|
|
38
|
+
return await handler(args);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
if (error instanceof ProtocolError) {
|
|
41
|
+
return textError(hasStringHint(error.data) ? `${error.message}\n${error.data.hint}` : error.message);
|
|
42
|
+
}
|
|
43
|
+
return textError(error instanceof Error ? error.message : String(error));
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const defineTool = <Shape extends Record<string, z.ZodType>>(tool: Tool<Shape>): Tool => tool as Tool;
|
|
48
|
+
|
|
49
|
+
export const registerTool = (server: McpServer, tool: Tool): void => {
|
|
50
|
+
const callback = ((args: ToolArgs<Record<string, z.ZodType>>, _extra: unknown) =>
|
|
51
|
+
runTool(tool.handler, args)) as ToolCallback<Record<string, z.ZodType>>;
|
|
52
|
+
server.registerTool(
|
|
53
|
+
tool.name,
|
|
54
|
+
{
|
|
55
|
+
description: tool.description,
|
|
56
|
+
inputSchema: tool.inputSchema,
|
|
57
|
+
annotations: {
|
|
58
|
+
title: tool.title,
|
|
59
|
+
readOnlyHint: tool.kind === "readOnly",
|
|
60
|
+
destructiveHint: tool.kind === "action",
|
|
61
|
+
openWorldHint: true,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
callback,
|
|
65
|
+
);
|
|
66
|
+
};
|
package/src/transport.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import EventEmitter from "node:events";
|
|
2
|
+
import type { Socket } from "node:net";
|
|
3
|
+
import type { Duplex } from "node:stream";
|
|
4
|
+
import { ErrorCode, invalidRequestError, isErrorCode, ProtocolError, requestTimeoutError } from "./protocol/errors.js";
|
|
5
|
+
import { type Message, type Request, RequestSchema, type Response, ResponseSchema } from "./protocol/schemas.js";
|
|
6
|
+
|
|
7
|
+
export type ProtocolConnectionEvents = {
|
|
8
|
+
request: [Request];
|
|
9
|
+
invalid: [{ id: string; error: ProtocolError }];
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type PendingRequest = {
|
|
13
|
+
resolve: (result: unknown) => void;
|
|
14
|
+
reject: (error: Error) => void;
|
|
15
|
+
timeout: NodeJS.Timeout;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export class ConnectionClosedError extends Error {
|
|
19
|
+
constructor() {
|
|
20
|
+
super("Connection stream is not writable");
|
|
21
|
+
this.name = "ConnectionClosedError";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export class ProtocolConnection extends EventEmitter<ProtocolConnectionEvents> {
|
|
26
|
+
id: string = crypto.randomUUID();
|
|
27
|
+
private buffer = "";
|
|
28
|
+
private pending: Map<string, PendingRequest> = new Map();
|
|
29
|
+
private writer: Duplex;
|
|
30
|
+
|
|
31
|
+
constructor(writer: Duplex) {
|
|
32
|
+
super();
|
|
33
|
+
this.writer = writer;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
feed(data: Buffer | string): void {
|
|
37
|
+
this.buffer += typeof data === "string" ? data : data.toString();
|
|
38
|
+
|
|
39
|
+
let newlineIndex = this.buffer.indexOf("\n");
|
|
40
|
+
while (newlineIndex !== -1) {
|
|
41
|
+
const line = this.buffer.slice(0, newlineIndex);
|
|
42
|
+
this.buffer = this.buffer.slice(newlineIndex + 1);
|
|
43
|
+
|
|
44
|
+
if (line.trim()) {
|
|
45
|
+
this.processLine(line);
|
|
46
|
+
}
|
|
47
|
+
newlineIndex = this.buffer.indexOf("\n");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
write(message: Message): void {
|
|
52
|
+
if (!this.writer.writable) return;
|
|
53
|
+
this.writer.write(`${JSON.stringify(message)}\n`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static fromSocket(
|
|
57
|
+
socket: Socket,
|
|
58
|
+
options: {
|
|
59
|
+
onClose?: () => void;
|
|
60
|
+
onError?: (error: Error) => void;
|
|
61
|
+
} = {},
|
|
62
|
+
): ProtocolConnection {
|
|
63
|
+
const connection = new ProtocolConnection(socket);
|
|
64
|
+
socket.on("data", (data: Buffer) => connection.feed(data));
|
|
65
|
+
socket.on("close", () => {
|
|
66
|
+
connection.rejectPending(new Error("Connection closed"));
|
|
67
|
+
options.onClose?.();
|
|
68
|
+
});
|
|
69
|
+
if (options.onError) {
|
|
70
|
+
socket.on("error", options.onError);
|
|
71
|
+
}
|
|
72
|
+
return connection;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
send<T = unknown>(method: string, params: unknown, timeout: number): Promise<T> {
|
|
76
|
+
return new Promise<T>((resolve, reject) => {
|
|
77
|
+
if (!this.writer.writable) {
|
|
78
|
+
reject(new ConnectionClosedError());
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const id = crypto.randomUUID();
|
|
83
|
+
const timeoutHandle = setTimeout(() => {
|
|
84
|
+
this.pending.delete(id);
|
|
85
|
+
reject(requestTimeoutError(timeout));
|
|
86
|
+
}, timeout);
|
|
87
|
+
|
|
88
|
+
this.pending.set(id, {
|
|
89
|
+
resolve: resolve as (result: unknown) => void,
|
|
90
|
+
reject,
|
|
91
|
+
timeout: timeoutHandle,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
this.write({ id, method, params });
|
|
95
|
+
if (!this.writer.writable) {
|
|
96
|
+
clearTimeout(timeoutHandle);
|
|
97
|
+
this.pending.delete(id);
|
|
98
|
+
reject(new ConnectionClosedError());
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
rejectPending(error: Error): void {
|
|
104
|
+
for (const entry of this.pending.values()) {
|
|
105
|
+
clearTimeout(entry.timeout);
|
|
106
|
+
entry.reject(error);
|
|
107
|
+
}
|
|
108
|
+
this.pending.clear();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
private processLine(line: string): void {
|
|
112
|
+
let parsed: unknown;
|
|
113
|
+
try {
|
|
114
|
+
parsed = JSON.parse(line);
|
|
115
|
+
} catch {
|
|
116
|
+
this.emit("invalid", { id: "unknown", error: invalidRequestError("Invalid JSON") });
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const message = parsed as Record<string, unknown>;
|
|
121
|
+
if (typeof message.method === "string") {
|
|
122
|
+
const requestResult = RequestSchema.safeParse(parsed);
|
|
123
|
+
if (requestResult.success) {
|
|
124
|
+
this.emit("request", requestResult.data);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
const responseResult = ResponseSchema.safeParse(parsed);
|
|
129
|
+
if (responseResult.success) {
|
|
130
|
+
this.handleResponse(responseResult.data);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const id = typeof message.id === "string" ? message.id : "unknown";
|
|
136
|
+
this.emit("invalid", { id, error: invalidRequestError("Invalid message format") });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private handleResponse(response: Response): void {
|
|
140
|
+
const entry = this.pending.get(response.id);
|
|
141
|
+
if (!entry) return;
|
|
142
|
+
|
|
143
|
+
clearTimeout(entry.timeout);
|
|
144
|
+
this.pending.delete(response.id);
|
|
145
|
+
|
|
146
|
+
if (response.error) {
|
|
147
|
+
const err = response.error;
|
|
148
|
+
entry.reject(
|
|
149
|
+
new ProtocolError(isErrorCode(err.code) ? err.code : ErrorCode.INTERNAL_ERROR, err.message, err.data),
|
|
150
|
+
);
|
|
151
|
+
} else {
|
|
152
|
+
entry.resolve(response.result);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export type AppConnectionEvents = {
|
|
158
|
+
disconnection: [ProtocolConnection];
|
|
159
|
+
request: [ProtocolConnection, Request];
|
|
160
|
+
error: [Error];
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export interface AppConnections extends EventEmitter<AppConnectionEvents> {
|
|
164
|
+
send(connectionId: string, message: Message): void;
|
|
165
|
+
}
|
package/dist/cli.d.ts
DELETED
package/dist/cli.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|