@procwire/transport 1.0.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.
- package/LICENSE +21 -0
- package/README.md +844 -0
- package/dist/channel/builder.d.ts +68 -0
- package/dist/channel/builder.d.ts.map +1 -0
- package/dist/channel/builder.js +120 -0
- package/dist/channel/builder.js.map +1 -0
- package/dist/channel/index.d.ts +6 -0
- package/dist/channel/index.d.ts.map +1 -0
- package/dist/channel/index.js +6 -0
- package/dist/channel/index.js.map +1 -0
- package/dist/channel/quickstart.d.ts +94 -0
- package/dist/channel/quickstart.d.ts.map +1 -0
- package/dist/channel/quickstart.js +104 -0
- package/dist/channel/quickstart.js.map +1 -0
- package/dist/channel/request-channel.d.ts +119 -0
- package/dist/channel/request-channel.d.ts.map +1 -0
- package/dist/channel/request-channel.js +476 -0
- package/dist/channel/request-channel.js.map +1 -0
- package/dist/channel/types.d.ts +226 -0
- package/dist/channel/types.d.ts.map +1 -0
- package/dist/channel/types.js +2 -0
- package/dist/channel/types.js.map +1 -0
- package/dist/framing/index.d.ts +4 -0
- package/dist/framing/index.d.ts.map +1 -0
- package/dist/framing/index.js +4 -0
- package/dist/framing/index.js.map +1 -0
- package/dist/framing/length-prefixed.d.ts +55 -0
- package/dist/framing/length-prefixed.d.ts.map +1 -0
- package/dist/framing/length-prefixed.js +102 -0
- package/dist/framing/length-prefixed.js.map +1 -0
- package/dist/framing/line-delimited.d.ts +61 -0
- package/dist/framing/line-delimited.d.ts.map +1 -0
- package/dist/framing/line-delimited.js +94 -0
- package/dist/framing/line-delimited.js.map +1 -0
- package/dist/framing/types.d.ts +35 -0
- package/dist/framing/types.d.ts.map +1 -0
- package/dist/framing/types.js +2 -0
- package/dist/framing/types.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/process/handle.d.ts +64 -0
- package/dist/process/handle.d.ts.map +1 -0
- package/dist/process/handle.js +107 -0
- package/dist/process/handle.js.map +1 -0
- package/dist/process/index.d.ts +37 -0
- package/dist/process/index.d.ts.map +1 -0
- package/dist/process/index.js +37 -0
- package/dist/process/index.js.map +1 -0
- package/dist/process/manager.d.ts +58 -0
- package/dist/process/manager.d.ts.map +1 -0
- package/dist/process/manager.js +360 -0
- package/dist/process/manager.js.map +1 -0
- package/dist/process/types.d.ts +322 -0
- package/dist/process/types.d.ts.map +1 -0
- package/dist/process/types.js +2 -0
- package/dist/process/types.js.map +1 -0
- package/dist/protocol/index.d.ts +4 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +6 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/jsonrpc.d.ts +146 -0
- package/dist/protocol/jsonrpc.d.ts.map +1 -0
- package/dist/protocol/jsonrpc.js +288 -0
- package/dist/protocol/jsonrpc.js.map +1 -0
- package/dist/protocol/simple.d.ts +139 -0
- package/dist/protocol/simple.d.ts.map +1 -0
- package/dist/protocol/simple.js +297 -0
- package/dist/protocol/simple.js.map +1 -0
- package/dist/protocol/types.d.ts +117 -0
- package/dist/protocol/types.d.ts.map +1 -0
- package/dist/protocol/types.js +2 -0
- package/dist/protocol/types.js.map +1 -0
- package/dist/serialization/index.d.ts +5 -0
- package/dist/serialization/index.d.ts.map +1 -0
- package/dist/serialization/index.js +5 -0
- package/dist/serialization/index.js.map +1 -0
- package/dist/serialization/json.d.ts +66 -0
- package/dist/serialization/json.d.ts.map +1 -0
- package/dist/serialization/json.js +66 -0
- package/dist/serialization/json.js.map +1 -0
- package/dist/serialization/raw.d.ts +38 -0
- package/dist/serialization/raw.d.ts.map +1 -0
- package/dist/serialization/raw.js +41 -0
- package/dist/serialization/raw.js.map +1 -0
- package/dist/serialization/registry.d.ts +91 -0
- package/dist/serialization/registry.d.ts.map +1 -0
- package/dist/serialization/registry.js +119 -0
- package/dist/serialization/registry.js.map +1 -0
- package/dist/serialization/types.d.ts +27 -0
- package/dist/serialization/types.d.ts.map +1 -0
- package/dist/serialization/types.js +2 -0
- package/dist/serialization/types.js.map +1 -0
- package/dist/transport/factory.d.ts +139 -0
- package/dist/transport/factory.d.ts.map +1 -0
- package/dist/transport/factory.js +162 -0
- package/dist/transport/factory.js.map +1 -0
- package/dist/transport/index.d.ts +6 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +9 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/socket-server.d.ts +48 -0
- package/dist/transport/socket-server.d.ts.map +1 -0
- package/dist/transport/socket-server.js +215 -0
- package/dist/transport/socket-server.js.map +1 -0
- package/dist/transport/socket-transport.d.ts +67 -0
- package/dist/transport/socket-transport.d.ts.map +1 -0
- package/dist/transport/socket-transport.js +193 -0
- package/dist/transport/socket-transport.js.map +1 -0
- package/dist/transport/stdio-transport.d.ts +94 -0
- package/dist/transport/stdio-transport.d.ts.map +1 -0
- package/dist/transport/stdio-transport.js +234 -0
- package/dist/transport/stdio-transport.js.map +1 -0
- package/dist/transport/types.d.ts +131 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +2 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/utils/assert.d.ts +16 -0
- package/dist/utils/assert.d.ts.map +1 -0
- package/dist/utils/assert.js +31 -0
- package/dist/utils/assert.js.map +1 -0
- package/dist/utils/disposables.d.ts +38 -0
- package/dist/utils/disposables.d.ts.map +1 -0
- package/dist/utils/disposables.js +59 -0
- package/dist/utils/disposables.js.map +1 -0
- package/dist/utils/errors.d.ts +43 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +69 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/events.d.ts +58 -0
- package/dist/utils/events.d.ts.map +1 -0
- package/dist/utils/events.js +95 -0
- package/dist/utils/events.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/pipe-path.d.ts +48 -0
- package/dist/utils/pipe-path.d.ts.map +1 -0
- package/dist/utils/pipe-path.js +89 -0
- package/dist/utils/pipe-path.js.map +1 -0
- package/dist/utils/platform.d.ts +16 -0
- package/dist/utils/platform.d.ts.map +1 -0
- package/dist/utils/platform.js +22 -0
- package/dist/utils/platform.js.map +1 -0
- package/dist/utils/time.d.ts +38 -0
- package/dist/utils/time.d.ts.map +1 -0
- package/dist/utils/time.js +55 -0
- package/dist/utils/time.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import * as net from "node:net";
|
|
2
|
+
import { EventEmitter } from "../utils/events.js";
|
|
3
|
+
import { TransportError } from "../utils/errors.js";
|
|
4
|
+
import { PipePath } from "../utils/pipe-path.js";
|
|
5
|
+
import { isWindows } from "../utils/platform.js";
|
|
6
|
+
/**
|
|
7
|
+
* Socket server implementation for Named Pipes (Windows) and Unix Domain Sockets.
|
|
8
|
+
*
|
|
9
|
+
* Accepts client connections and creates Transport instances for each connection.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* const server = new SocketServer();
|
|
14
|
+
* const address = await server.listen('/tmp/my-server.sock');
|
|
15
|
+
*
|
|
16
|
+
* server.onConnection(transport => {
|
|
17
|
+
* console.log('Client connected');
|
|
18
|
+
* transport.onData(data => {
|
|
19
|
+
* console.log('received:', data);
|
|
20
|
+
* transport.write(data); // Echo back
|
|
21
|
+
* });
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export class SocketServer {
|
|
26
|
+
emitter = new EventEmitter();
|
|
27
|
+
options;
|
|
28
|
+
server = null;
|
|
29
|
+
_address = null;
|
|
30
|
+
connections = new Set();
|
|
31
|
+
constructor(options = {}) {
|
|
32
|
+
this.options = {
|
|
33
|
+
cleanupBeforeListen: options.cleanupBeforeListen ?? true,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
get isListening() {
|
|
37
|
+
return this.server !== null && this.server.listening;
|
|
38
|
+
}
|
|
39
|
+
get address() {
|
|
40
|
+
return this._address;
|
|
41
|
+
}
|
|
42
|
+
async listen(address) {
|
|
43
|
+
if (this.isListening) {
|
|
44
|
+
throw new TransportError("Server is already listening");
|
|
45
|
+
}
|
|
46
|
+
// Address must be string (path) for socket server
|
|
47
|
+
if (typeof address !== "string") {
|
|
48
|
+
throw new TransportError("Socket server requires path address (string)");
|
|
49
|
+
}
|
|
50
|
+
const path = address;
|
|
51
|
+
// Cleanup stale socket file (Unix only)
|
|
52
|
+
if (this.options.cleanupBeforeListen) {
|
|
53
|
+
await PipePath.cleanup(path);
|
|
54
|
+
}
|
|
55
|
+
return new Promise((resolve, reject) => {
|
|
56
|
+
const server = net.createServer((socket) => {
|
|
57
|
+
this.handleConnection(socket);
|
|
58
|
+
});
|
|
59
|
+
this.server = server;
|
|
60
|
+
server.once("listening", () => {
|
|
61
|
+
const type = isWindows() ? "pipe" : "unix";
|
|
62
|
+
this._address = { type, value: path };
|
|
63
|
+
this.emitter.emit("listening", this._address);
|
|
64
|
+
resolve(this._address);
|
|
65
|
+
});
|
|
66
|
+
server.once("error", (err) => {
|
|
67
|
+
const error = new TransportError(`Failed to listen: ${err.message}`, err);
|
|
68
|
+
this.emitter.emit("error", error);
|
|
69
|
+
reject(error);
|
|
70
|
+
});
|
|
71
|
+
server.on("error", (err) => {
|
|
72
|
+
const error = new TransportError(`Server error: ${err.message}`, err);
|
|
73
|
+
this.emitter.emit("error", error);
|
|
74
|
+
});
|
|
75
|
+
server.listen(path);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async close() {
|
|
79
|
+
if (!this.server) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
const server = this.server;
|
|
84
|
+
// Close all active connections
|
|
85
|
+
const closePromises = Array.from(this.connections).map((transport) => transport.disconnect().catch(() => {
|
|
86
|
+
// Ignore errors during connection cleanup
|
|
87
|
+
}));
|
|
88
|
+
Promise.all(closePromises).finally(() => {
|
|
89
|
+
server.close((err) => {
|
|
90
|
+
if (err) {
|
|
91
|
+
const error = new TransportError(`Failed to close server: ${err.message}`, err);
|
|
92
|
+
this.emitter.emit("error", error);
|
|
93
|
+
reject(error);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
this.cleanup();
|
|
97
|
+
resolve();
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
onConnection(handler) {
|
|
104
|
+
return this.emitter.on("connection", handler);
|
|
105
|
+
}
|
|
106
|
+
on(event, handler) {
|
|
107
|
+
return this.emitter.on(event, handler);
|
|
108
|
+
}
|
|
109
|
+
handleConnection(socket) {
|
|
110
|
+
const transport = new ConnectedSocketTransport(socket);
|
|
111
|
+
this.connections.add(transport);
|
|
112
|
+
// Remove from set when disconnected
|
|
113
|
+
transport.on("disconnect", () => {
|
|
114
|
+
this.connections.delete(transport);
|
|
115
|
+
});
|
|
116
|
+
this.emitter.emit("connection", transport);
|
|
117
|
+
}
|
|
118
|
+
cleanup() {
|
|
119
|
+
this.server?.removeAllListeners();
|
|
120
|
+
this.server = null;
|
|
121
|
+
this._address = null;
|
|
122
|
+
this.connections.clear();
|
|
123
|
+
this.emitter.emit("close", undefined);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Transport wrapper for an already-connected socket (used by server for incoming connections).
|
|
128
|
+
* Implements Transport interface for server-accepted connections.
|
|
129
|
+
*/
|
|
130
|
+
class ConnectedSocketTransport {
|
|
131
|
+
emitter = new EventEmitter();
|
|
132
|
+
socket;
|
|
133
|
+
_state = "connected";
|
|
134
|
+
constructor(socket) {
|
|
135
|
+
this.socket = socket;
|
|
136
|
+
this.setupSocketListeners();
|
|
137
|
+
}
|
|
138
|
+
get state() {
|
|
139
|
+
return this._state;
|
|
140
|
+
}
|
|
141
|
+
async connect() {
|
|
142
|
+
throw new TransportError("Already connected (server-accepted connection)");
|
|
143
|
+
}
|
|
144
|
+
async disconnect() {
|
|
145
|
+
if (this._state === "disconnected") {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
return new Promise((resolve) => {
|
|
149
|
+
this.socket.once("close", () => {
|
|
150
|
+
this.cleanup();
|
|
151
|
+
resolve();
|
|
152
|
+
});
|
|
153
|
+
this.socket.end();
|
|
154
|
+
// Force close after timeout
|
|
155
|
+
setTimeout(() => {
|
|
156
|
+
if (!this.socket.destroyed) {
|
|
157
|
+
this.socket.destroy();
|
|
158
|
+
}
|
|
159
|
+
}, 1000);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
async write(data) {
|
|
163
|
+
if (this._state !== "connected") {
|
|
164
|
+
throw new TransportError("Not connected");
|
|
165
|
+
}
|
|
166
|
+
return new Promise((resolve, reject) => {
|
|
167
|
+
const canContinue = this.socket.write(data, (err) => {
|
|
168
|
+
if (err) {
|
|
169
|
+
const error = new TransportError(`Write failed: ${err.message}`, err);
|
|
170
|
+
this.emitter.emit("error", error);
|
|
171
|
+
reject(error);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
resolve();
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
// Handle backpressure
|
|
178
|
+
if (!canContinue) {
|
|
179
|
+
this.socket.once("drain", () => {
|
|
180
|
+
// Buffer drained
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
onData(handler) {
|
|
186
|
+
return this.emitter.on("data", handler);
|
|
187
|
+
}
|
|
188
|
+
on(event, handler) {
|
|
189
|
+
return this.emitter.on(event, handler);
|
|
190
|
+
}
|
|
191
|
+
setupSocketListeners() {
|
|
192
|
+
this.socket.on("data", (data) => {
|
|
193
|
+
this.emitter.emit("data", data);
|
|
194
|
+
});
|
|
195
|
+
this.socket.on("close", () => {
|
|
196
|
+
this.cleanup();
|
|
197
|
+
});
|
|
198
|
+
this.socket.on("error", (err) => {
|
|
199
|
+
this._state = "error";
|
|
200
|
+
const error = new TransportError(`Socket error: ${err.message}`, err);
|
|
201
|
+
this.emitter.emit("error", error);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
cleanup() {
|
|
205
|
+
this.socket.removeAllListeners();
|
|
206
|
+
if (!this.socket.destroyed) {
|
|
207
|
+
this.socket.destroy();
|
|
208
|
+
}
|
|
209
|
+
if (this._state !== "disconnected") {
|
|
210
|
+
this._state = "disconnected";
|
|
211
|
+
this.emitter.emit("disconnect", undefined);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=socket-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket-server.js","sourceRoot":"","sources":["../../src/transport/socket-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Transport, TransportState, TransportEvents } from "./types.js";
|
|
2
|
+
import type { Unsubscribe } from "../utils/disposables.js";
|
|
3
|
+
/**
|
|
4
|
+
* Socket transport options (Named Pipes on Windows, Unix Domain Sockets on Unix).
|
|
5
|
+
*/
|
|
6
|
+
export interface SocketTransportOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Pipe/socket path to connect to.
|
|
9
|
+
* Windows: `\\.\pipe\<name>`
|
|
10
|
+
* Unix: `/tmp/<name>.sock`
|
|
11
|
+
*/
|
|
12
|
+
path: string;
|
|
13
|
+
/**
|
|
14
|
+
* Connection timeout in milliseconds.
|
|
15
|
+
* @default 5000
|
|
16
|
+
*/
|
|
17
|
+
connectionTimeout?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Enable automatic reconnection on disconnect.
|
|
20
|
+
* @default false
|
|
21
|
+
*/
|
|
22
|
+
autoReconnect?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Initial reconnect delay in milliseconds.
|
|
25
|
+
* @default 1000
|
|
26
|
+
*/
|
|
27
|
+
reconnectDelay?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Maximum reconnect delay in milliseconds (for exponential backoff).
|
|
30
|
+
* @default 30000
|
|
31
|
+
*/
|
|
32
|
+
maxReconnectDelay?: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Socket-based transport implementation for Named Pipes (Windows) and Unix Domain Sockets.
|
|
36
|
+
*
|
|
37
|
+
* Provides bidirectional byte stream communication over local sockets.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* const transport = new SocketTransport({ path: '/tmp/my-socket.sock' });
|
|
42
|
+
* await transport.connect();
|
|
43
|
+
* await transport.write(Buffer.from('hello'));
|
|
44
|
+
* transport.onData(data => console.log('received:', data));
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare class SocketTransport implements Transport {
|
|
48
|
+
private readonly emitter;
|
|
49
|
+
private readonly options;
|
|
50
|
+
private socket;
|
|
51
|
+
private _state;
|
|
52
|
+
private connectTimer;
|
|
53
|
+
private reconnectTimer;
|
|
54
|
+
private reconnectAttempts;
|
|
55
|
+
private manualDisconnect;
|
|
56
|
+
constructor(options: SocketTransportOptions);
|
|
57
|
+
get state(): TransportState;
|
|
58
|
+
connect(): Promise<void>;
|
|
59
|
+
disconnect(): Promise<void>;
|
|
60
|
+
write(data: Buffer): Promise<void>;
|
|
61
|
+
onData(handler: (data: Buffer) => void): Unsubscribe;
|
|
62
|
+
on<K extends keyof TransportEvents>(event: K, handler: (data: TransportEvents[K]) => void): Unsubscribe;
|
|
63
|
+
private setupSocketListeners;
|
|
64
|
+
private scheduleReconnect;
|
|
65
|
+
private cleanup;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=socket-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket-transport.d.ts","sourceRoot":"","sources":["../../src/transport/socket-transport.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,gBAAgB,CAAS;gBAErB,OAAO,EAAE,sBAAsB;IAU3C,IAAI,KAAK,IAAI,cAAc,CAE1B;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA2DxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwC3B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BxC,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,WAAW;IAIpD,EAAE,CAAC,CAAC,SAAS,MAAM,eAAe,EAChC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,GAC1C,WAAW;IAId,OAAO,CAAC,oBAAoB;IAqB5B,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,OAAO;CAchB"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import * as net from "node:net";
|
|
2
|
+
import { EventEmitter } from "../utils/events.js";
|
|
3
|
+
import { TransportError } from "../utils/errors.js";
|
|
4
|
+
/**
|
|
5
|
+
* Socket-based transport implementation for Named Pipes (Windows) and Unix Domain Sockets.
|
|
6
|
+
*
|
|
7
|
+
* Provides bidirectional byte stream communication over local sockets.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* const transport = new SocketTransport({ path: '/tmp/my-socket.sock' });
|
|
12
|
+
* await transport.connect();
|
|
13
|
+
* await transport.write(Buffer.from('hello'));
|
|
14
|
+
* transport.onData(data => console.log('received:', data));
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export class SocketTransport {
|
|
18
|
+
emitter = new EventEmitter();
|
|
19
|
+
options;
|
|
20
|
+
socket = null;
|
|
21
|
+
_state = "disconnected";
|
|
22
|
+
connectTimer = null;
|
|
23
|
+
reconnectTimer = null;
|
|
24
|
+
reconnectAttempts = 0;
|
|
25
|
+
manualDisconnect = false;
|
|
26
|
+
constructor(options) {
|
|
27
|
+
this.options = {
|
|
28
|
+
path: options.path,
|
|
29
|
+
connectionTimeout: options.connectionTimeout ?? 5000,
|
|
30
|
+
autoReconnect: options.autoReconnect ?? false,
|
|
31
|
+
reconnectDelay: options.reconnectDelay ?? 1000,
|
|
32
|
+
maxReconnectDelay: options.maxReconnectDelay ?? 30000,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
get state() {
|
|
36
|
+
return this._state;
|
|
37
|
+
}
|
|
38
|
+
async connect() {
|
|
39
|
+
if (this._state === "connected") {
|
|
40
|
+
throw new TransportError("Already connected");
|
|
41
|
+
}
|
|
42
|
+
if (this._state === "connecting") {
|
|
43
|
+
throw new TransportError("Connection already in progress");
|
|
44
|
+
}
|
|
45
|
+
this.manualDisconnect = false;
|
|
46
|
+
this._state = "connecting";
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
const socket = net.createConnection({ path: this.options.path });
|
|
49
|
+
this.socket = socket;
|
|
50
|
+
// Connection timeout
|
|
51
|
+
this.connectTimer = setTimeout(() => {
|
|
52
|
+
socket.destroy();
|
|
53
|
+
this._state = "error";
|
|
54
|
+
const error = new TransportError(`Connection timeout after ${this.options.connectionTimeout}ms`);
|
|
55
|
+
this.emitter.emit("error", error);
|
|
56
|
+
reject(error);
|
|
57
|
+
}, this.options.connectionTimeout);
|
|
58
|
+
socket.once("connect", () => {
|
|
59
|
+
if (this.connectTimer) {
|
|
60
|
+
clearTimeout(this.connectTimer);
|
|
61
|
+
this.connectTimer = null;
|
|
62
|
+
}
|
|
63
|
+
this._state = "connected";
|
|
64
|
+
this.reconnectAttempts = 0;
|
|
65
|
+
this.setupSocketListeners(socket);
|
|
66
|
+
this.emitter.emit("connect", undefined);
|
|
67
|
+
resolve();
|
|
68
|
+
});
|
|
69
|
+
socket.once("error", (err) => {
|
|
70
|
+
if (this.connectTimer) {
|
|
71
|
+
clearTimeout(this.connectTimer);
|
|
72
|
+
this.connectTimer = null;
|
|
73
|
+
}
|
|
74
|
+
this._state = "error";
|
|
75
|
+
const error = new TransportError(`Connection failed: ${err.message}`, err);
|
|
76
|
+
this.emitter.emit("error", error);
|
|
77
|
+
reject(error);
|
|
78
|
+
// Try reconnecting if enabled and not manual disconnect
|
|
79
|
+
if (this.options.autoReconnect && !this.manualDisconnect) {
|
|
80
|
+
this.scheduleReconnect();
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
async disconnect() {
|
|
86
|
+
if (this._state === "disconnected") {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
this.manualDisconnect = true;
|
|
90
|
+
if (this.connectTimer) {
|
|
91
|
+
clearTimeout(this.connectTimer);
|
|
92
|
+
this.connectTimer = null;
|
|
93
|
+
}
|
|
94
|
+
if (this.reconnectTimer) {
|
|
95
|
+
clearTimeout(this.reconnectTimer);
|
|
96
|
+
this.reconnectTimer = null;
|
|
97
|
+
}
|
|
98
|
+
if (this.socket) {
|
|
99
|
+
return new Promise((resolve) => {
|
|
100
|
+
const socket = this.socket;
|
|
101
|
+
socket.once("close", () => {
|
|
102
|
+
this.cleanup();
|
|
103
|
+
resolve();
|
|
104
|
+
});
|
|
105
|
+
socket.end();
|
|
106
|
+
// Force close after timeout
|
|
107
|
+
setTimeout(() => {
|
|
108
|
+
if (!socket.destroyed) {
|
|
109
|
+
socket.destroy();
|
|
110
|
+
}
|
|
111
|
+
}, 1000);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
this.cleanup();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async write(data) {
|
|
119
|
+
if (this._state !== "connected" || !this.socket) {
|
|
120
|
+
throw new TransportError("Not connected");
|
|
121
|
+
}
|
|
122
|
+
return new Promise((resolve, reject) => {
|
|
123
|
+
const socket = this.socket;
|
|
124
|
+
const canContinue = socket.write(data, (err) => {
|
|
125
|
+
if (err) {
|
|
126
|
+
const error = new TransportError(`Write failed: ${err.message}`, err);
|
|
127
|
+
this.emitter.emit("error", error);
|
|
128
|
+
reject(error);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
resolve();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
// Handle backpressure
|
|
135
|
+
if (!canContinue) {
|
|
136
|
+
socket.once("drain", () => {
|
|
137
|
+
// Buffer drained, can continue writing
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
onData(handler) {
|
|
143
|
+
return this.emitter.on("data", handler);
|
|
144
|
+
}
|
|
145
|
+
on(event, handler) {
|
|
146
|
+
return this.emitter.on(event, handler);
|
|
147
|
+
}
|
|
148
|
+
setupSocketListeners(socket) {
|
|
149
|
+
socket.on("data", (data) => {
|
|
150
|
+
this.emitter.emit("data", data);
|
|
151
|
+
});
|
|
152
|
+
socket.on("close", () => {
|
|
153
|
+
this.cleanup();
|
|
154
|
+
// Try reconnecting if enabled and not manual disconnect
|
|
155
|
+
if (this.options.autoReconnect && !this.manualDisconnect) {
|
|
156
|
+
this.scheduleReconnect();
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
socket.on("error", (err) => {
|
|
160
|
+
this._state = "error";
|
|
161
|
+
const error = new TransportError(`Socket error: ${err.message}`, err);
|
|
162
|
+
this.emitter.emit("error", error);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
scheduleReconnect() {
|
|
166
|
+
if (this.reconnectTimer || this.manualDisconnect) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
// Exponential backoff: min(reconnectDelay * 2^attempts, maxReconnectDelay)
|
|
170
|
+
const delay = Math.min(this.options.reconnectDelay * Math.pow(2, this.reconnectAttempts), this.options.maxReconnectDelay);
|
|
171
|
+
this.reconnectTimer = setTimeout(() => {
|
|
172
|
+
this.reconnectTimer = null;
|
|
173
|
+
this.reconnectAttempts++;
|
|
174
|
+
this.connect().catch(() => {
|
|
175
|
+
// Error already emitted, will schedule next attempt
|
|
176
|
+
});
|
|
177
|
+
}, delay);
|
|
178
|
+
}
|
|
179
|
+
cleanup() {
|
|
180
|
+
if (this.socket) {
|
|
181
|
+
this.socket.removeAllListeners();
|
|
182
|
+
if (!this.socket.destroyed) {
|
|
183
|
+
this.socket.destroy();
|
|
184
|
+
}
|
|
185
|
+
this.socket = null;
|
|
186
|
+
}
|
|
187
|
+
if (this._state !== "disconnected") {
|
|
188
|
+
this._state = "disconnected";
|
|
189
|
+
this.emitter.emit("disconnect", undefined);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=socket-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"socket-transport.js","sourceRoot":"","sources":["../../src/transport/socket-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAwCpD;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,eAAe;IACT,OAAO,GAAG,IAAI,YAAY,EAAmB,CAAC;IAC9C,OAAO,CAAmC;IACnD,MAAM,GAAsB,IAAI,CAAC;IACjC,MAAM,GAAmB,cAAc,CAAC;IACxC,YAAY,GAA0B,IAAI,CAAC;IAC3C,cAAc,GAA0B,IAAI,CAAC;IAC7C,iBAAiB,GAAG,CAAC,CAAC;IACtB,gBAAgB,GAAG,KAAK,CAAC;IAEjC,YAAY,OAA+B;QACzC,IAAI,CAAC,OAAO,GAAG;YACb,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,IAAI;YACpD,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,KAAK;YAC7C,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,IAAI;YAC9C,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,KAAK;SACtD,CAAC;IACJ,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAChC,MAAM,IAAI,cAAc,CAAC,mBAAmB,CAAC,CAAC;QAChD,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;YACjC,MAAM,IAAI,cAAc,CAAC,gCAAgC,CAAC,CAAC;QAC7D,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC;QAE3B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG,GAAG,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;YACjE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;YAErB,qBAAqB;YACrB,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;gBAClC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;gBACtB,MAAM,KAAK,GAAG,IAAI,cAAc,CAC9B,4BAA4B,IAAI,CAAC,OAAO,CAAC,iBAAiB,IAAI,CAC/D,CAAC;gBACF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAClC,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;YAEnC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;gBAC1B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;oBAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;gBAC3B,CAAC;gBAED,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;gBAC1B,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;gBAC3B,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;gBAClC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;gBACxC,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;YAEH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC3B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;oBAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;gBAC3B,CAAC;gBAED,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;gBACtB,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,sBAAsB,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;gBAC3E,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAClC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAEd,wDAAwD;gBACxD,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACzD,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC3B,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAE7B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC;QAED,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAClC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAO,CAAC;gBAE5B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;oBACxB,IAAI,CAAC,OAAO,EAAE,CAAC;oBACf,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;gBAEH,MAAM,CAAC,GAAG,EAAE,CAAC;gBAEb,4BAA4B;gBAC5B,UAAU,CAAC,GAAG,EAAE;oBACd,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;wBACtB,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,CAAC;gBACH,CAAC,EAAE,IAAI,CAAC,CAAC;YACX,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAY;QACtB,IAAI,IAAI,CAAC,MAAM,KAAK,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YAChD,MAAM,IAAI,cAAc,CAAC,eAAe,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAO,CAAC;YAE5B,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC7C,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,iBAAiB,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;oBACtE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;oBAClC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChB,CAAC;qBAAM,CAAC;oBACN,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,sBAAsB;YACtB,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;oBACxB,uCAAuC;gBACzC,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,OAA+B;QACpC,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IAED,EAAE,CACA,KAAQ,EACR,OAA2C;QAE3C,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAEO,oBAAoB,CAAC,MAAkB;QAC7C,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;YACjC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACtB,IAAI,CAAC,OAAO,EAAE,CAAC;YAEf,wDAAwD;YACxD,IAAI,IAAI,CAAC,OAAO,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACzD,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;YACtB,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,iBAAiB,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;YACtE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,iBAAiB;QACvB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACjD,OAAO;QACT,CAAC;QAED,2EAA2E;QAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,IAAI,CAAC,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,CAAC,EACjE,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAC/B,CAAC;QAEF,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC,GAAG,EAAE;YACpC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE;gBACxB,oDAAoD;YACtD,CAAC,CAAC,CAAC;QACL,CAAC,EAAE,KAAK,CAAC,CAAC;IACZ,CAAC;IAEO,OAAO;QACb,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC3B,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACxB,CAAC;YACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC;YAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { Transport, TransportState, TransportEvents } from "./types.js";
|
|
2
|
+
import type { Unsubscribe } from "../utils/disposables.js";
|
|
3
|
+
/**
|
|
4
|
+
* Stdio transport options for child process communication.
|
|
5
|
+
*/
|
|
6
|
+
export interface StdioTransportOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Path to executable to spawn.
|
|
9
|
+
*/
|
|
10
|
+
executablePath: string;
|
|
11
|
+
/**
|
|
12
|
+
* Command line arguments.
|
|
13
|
+
*/
|
|
14
|
+
args?: string[];
|
|
15
|
+
/**
|
|
16
|
+
* Working directory for child process.
|
|
17
|
+
*/
|
|
18
|
+
cwd?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Environment variables.
|
|
21
|
+
*/
|
|
22
|
+
env?: Record<string, string>;
|
|
23
|
+
/**
|
|
24
|
+
* Timeout for process startup in milliseconds.
|
|
25
|
+
* @default 10000
|
|
26
|
+
*/
|
|
27
|
+
startupTimeout?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Maximum stdout buffer size in bytes.
|
|
30
|
+
* If exceeded, transport will emit error and disconnect.
|
|
31
|
+
* @default 10MB
|
|
32
|
+
*/
|
|
33
|
+
maxStdoutBuffer?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Maximum stderr buffer size in bytes.
|
|
36
|
+
* If exceeded, transport will emit error and disconnect.
|
|
37
|
+
* @default 1MB
|
|
38
|
+
*/
|
|
39
|
+
maxStderrBuffer?: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Extended transport events for stdio transport (includes stderr and exit events).
|
|
43
|
+
*/
|
|
44
|
+
export interface StdioTransportEvents extends TransportEvents {
|
|
45
|
+
/**
|
|
46
|
+
* Fired when stderr data is received.
|
|
47
|
+
*/
|
|
48
|
+
stderr: string;
|
|
49
|
+
/**
|
|
50
|
+
* Fired when child process exits.
|
|
51
|
+
*/
|
|
52
|
+
exit: {
|
|
53
|
+
code: number | null;
|
|
54
|
+
signal: NodeJS.Signals | null;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Stdio-based transport for parent-child process communication.
|
|
59
|
+
*
|
|
60
|
+
* Spawns a child process and communicates via stdin/stdout.
|
|
61
|
+
* Stderr is exposed via separate 'stderr' event.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* const transport = new StdioTransport({
|
|
66
|
+
* executablePath: 'node',
|
|
67
|
+
* args: ['worker.js']
|
|
68
|
+
* });
|
|
69
|
+
*
|
|
70
|
+
* await transport.connect(); // Spawns process
|
|
71
|
+
* await transport.write(Buffer.from('hello'));
|
|
72
|
+
* transport.onData(data => console.log('received:', data));
|
|
73
|
+
* transport.on('stderr', line => console.error('stderr:', line));
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export declare class StdioTransport implements Transport {
|
|
77
|
+
private readonly emitter;
|
|
78
|
+
private readonly options;
|
|
79
|
+
private process;
|
|
80
|
+
private _state;
|
|
81
|
+
private startupTimer;
|
|
82
|
+
private stdoutBytesReceived;
|
|
83
|
+
private stderrBytesReceived;
|
|
84
|
+
constructor(options: StdioTransportOptions);
|
|
85
|
+
get state(): TransportState;
|
|
86
|
+
connect(): Promise<void>;
|
|
87
|
+
disconnect(): Promise<void>;
|
|
88
|
+
write(data: Buffer): Promise<void>;
|
|
89
|
+
onData(handler: (data: Buffer) => void): Unsubscribe;
|
|
90
|
+
on<K extends keyof StdioTransportEvents>(event: K, handler: (data: StdioTransportEvents[K]) => void): Unsubscribe;
|
|
91
|
+
private setupProcessListeners;
|
|
92
|
+
private cleanup;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=stdio-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio-transport.d.ts","sourceRoot":"","sources":["../../src/transport/stdio-transport.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE7B;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAC3D;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAA;KAAE,CAAC;CAC9D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,cAAe,YAAW,SAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4C;IACpE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,mBAAmB,CAAK;gBAEpB,OAAO,EAAE,qBAAqB;IAY1C,IAAI,KAAK,IAAI,cAAc,CAE1B;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAqExB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAwC3B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCxC,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,WAAW;IAIpD,EAAE,CAAC,CAAC,SAAS,MAAM,oBAAoB,EACrC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC,CAAC,KAAK,IAAI,GAC/C,WAAW;IAId,OAAO,CAAC,qBAAqB;IAoD7B,OAAO,CAAC,OAAO;CA+BhB"}
|