@procwire/transport 0.1.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/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,234 @@
|
|
|
1
|
+
import * as childProcess from "node:child_process";
|
|
2
|
+
import { EventEmitter } from "../utils/events.js";
|
|
3
|
+
import { TransportError, TimeoutError } from "../utils/errors.js";
|
|
4
|
+
/**
|
|
5
|
+
* Stdio-based transport for parent-child process communication.
|
|
6
|
+
*
|
|
7
|
+
* Spawns a child process and communicates via stdin/stdout.
|
|
8
|
+
* Stderr is exposed via separate 'stderr' event.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* const transport = new StdioTransport({
|
|
13
|
+
* executablePath: 'node',
|
|
14
|
+
* args: ['worker.js']
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* await transport.connect(); // Spawns process
|
|
18
|
+
* await transport.write(Buffer.from('hello'));
|
|
19
|
+
* transport.onData(data => console.log('received:', data));
|
|
20
|
+
* transport.on('stderr', line => console.error('stderr:', line));
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export class StdioTransport {
|
|
24
|
+
emitter = new EventEmitter();
|
|
25
|
+
options;
|
|
26
|
+
process = null;
|
|
27
|
+
_state = "disconnected";
|
|
28
|
+
startupTimer = null;
|
|
29
|
+
stdoutBytesReceived = 0;
|
|
30
|
+
stderrBytesReceived = 0;
|
|
31
|
+
constructor(options) {
|
|
32
|
+
this.options = {
|
|
33
|
+
executablePath: options.executablePath,
|
|
34
|
+
args: options.args ?? [],
|
|
35
|
+
cwd: options.cwd ?? process.cwd(),
|
|
36
|
+
env: options.env ?? process.env,
|
|
37
|
+
startupTimeout: options.startupTimeout ?? 10000,
|
|
38
|
+
maxStdoutBuffer: options.maxStdoutBuffer ?? 10 * 1024 * 1024, // 10MB
|
|
39
|
+
maxStderrBuffer: options.maxStderrBuffer ?? 1 * 1024 * 1024, // 1MB
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
get state() {
|
|
43
|
+
return this._state;
|
|
44
|
+
}
|
|
45
|
+
async connect() {
|
|
46
|
+
if (this._state === "connected") {
|
|
47
|
+
throw new TransportError("Already connected");
|
|
48
|
+
}
|
|
49
|
+
if (this._state === "connecting") {
|
|
50
|
+
throw new TransportError("Connection already in progress");
|
|
51
|
+
}
|
|
52
|
+
this._state = "connecting";
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
try {
|
|
55
|
+
const proc = childProcess.spawn(this.options.executablePath, this.options.args, {
|
|
56
|
+
cwd: this.options.cwd,
|
|
57
|
+
env: this.options.env,
|
|
58
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
59
|
+
});
|
|
60
|
+
this.process = proc;
|
|
61
|
+
// Startup timeout
|
|
62
|
+
this.startupTimer = setTimeout(() => {
|
|
63
|
+
proc.kill();
|
|
64
|
+
this._state = "error";
|
|
65
|
+
const error = new TransportError(`Process startup timeout after ${this.options.startupTimeout}ms`, new TimeoutError(`Startup timeout`));
|
|
66
|
+
this.emitter.emit("error", error);
|
|
67
|
+
reject(error);
|
|
68
|
+
}, this.options.startupTimeout);
|
|
69
|
+
// Wait for spawn event (process started successfully)
|
|
70
|
+
proc.once("spawn", () => {
|
|
71
|
+
if (this.startupTimer) {
|
|
72
|
+
clearTimeout(this.startupTimer);
|
|
73
|
+
this.startupTimer = null;
|
|
74
|
+
}
|
|
75
|
+
this._state = "connected";
|
|
76
|
+
this.setupProcessListeners(proc);
|
|
77
|
+
this.emitter.emit("connect", undefined);
|
|
78
|
+
resolve();
|
|
79
|
+
});
|
|
80
|
+
// Handle spawn errors
|
|
81
|
+
proc.once("error", (err) => {
|
|
82
|
+
if (this.startupTimer) {
|
|
83
|
+
clearTimeout(this.startupTimer);
|
|
84
|
+
this.startupTimer = null;
|
|
85
|
+
}
|
|
86
|
+
this._state = "error";
|
|
87
|
+
const error = new TransportError(`Failed to spawn process: ${err.message}`, err);
|
|
88
|
+
this.emitter.emit("error", error);
|
|
89
|
+
reject(error);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
this._state = "error";
|
|
94
|
+
const error = new TransportError(`Failed to create process: ${err.message}`, err);
|
|
95
|
+
reject(error);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
async disconnect() {
|
|
100
|
+
if (this._state === "disconnected") {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (this.startupTimer) {
|
|
104
|
+
clearTimeout(this.startupTimer);
|
|
105
|
+
this.startupTimer = null;
|
|
106
|
+
}
|
|
107
|
+
if (this.process) {
|
|
108
|
+
return new Promise((resolve) => {
|
|
109
|
+
const proc = this.process;
|
|
110
|
+
// Close stdin first (graceful signal)
|
|
111
|
+
if (proc.stdin && !proc.stdin.destroyed) {
|
|
112
|
+
proc.stdin.end();
|
|
113
|
+
}
|
|
114
|
+
// Wait for exit
|
|
115
|
+
proc.once("exit", () => {
|
|
116
|
+
this.cleanup();
|
|
117
|
+
resolve();
|
|
118
|
+
});
|
|
119
|
+
// Force kill after timeout
|
|
120
|
+
setTimeout(() => {
|
|
121
|
+
if (!proc.killed) {
|
|
122
|
+
proc.kill("SIGKILL");
|
|
123
|
+
}
|
|
124
|
+
}, 2000);
|
|
125
|
+
// Try graceful first
|
|
126
|
+
proc.kill();
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
this.cleanup();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async write(data) {
|
|
134
|
+
if (this._state !== "connected" || !this.process || !this.process.stdin) {
|
|
135
|
+
throw new TransportError("Not connected");
|
|
136
|
+
}
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
const stdin = this.process.stdin;
|
|
139
|
+
if (stdin.destroyed) {
|
|
140
|
+
reject(new TransportError("Stdin is closed"));
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const canContinue = stdin.write(data, (err) => {
|
|
144
|
+
if (err) {
|
|
145
|
+
const error = new TransportError(`Write to stdin failed: ${err.message}`, err);
|
|
146
|
+
this.emitter.emit("error", error);
|
|
147
|
+
reject(error);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
resolve();
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
// Handle backpressure
|
|
154
|
+
if (!canContinue) {
|
|
155
|
+
stdin.once("drain", () => {
|
|
156
|
+
// Buffer drained, can continue writing
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
onData(handler) {
|
|
162
|
+
return this.emitter.on("data", handler);
|
|
163
|
+
}
|
|
164
|
+
on(event, handler) {
|
|
165
|
+
return this.emitter.on(event, handler);
|
|
166
|
+
}
|
|
167
|
+
setupProcessListeners(proc) {
|
|
168
|
+
// Stdout data
|
|
169
|
+
if (proc.stdout) {
|
|
170
|
+
proc.stdout.on("data", (data) => {
|
|
171
|
+
this.stdoutBytesReceived += data.length;
|
|
172
|
+
if (this.stdoutBytesReceived > this.options.maxStdoutBuffer) {
|
|
173
|
+
const error = new TransportError(`Stdout buffer exceeded limit of ${this.options.maxStdoutBuffer} bytes`);
|
|
174
|
+
this.emitter.emit("error", error);
|
|
175
|
+
this.disconnect();
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
this.emitter.emit("data", data);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
// Stderr data (as strings/lines)
|
|
182
|
+
if (proc.stderr) {
|
|
183
|
+
proc.stderr.setEncoding("utf8");
|
|
184
|
+
proc.stderr.on("data", (data) => {
|
|
185
|
+
this.stderrBytesReceived += Buffer.byteLength(data);
|
|
186
|
+
if (this.stderrBytesReceived > this.options.maxStderrBuffer) {
|
|
187
|
+
const error = new TransportError(`Stderr buffer exceeded limit of ${this.options.maxStderrBuffer} bytes`);
|
|
188
|
+
this.emitter.emit("error", error);
|
|
189
|
+
this.disconnect();
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
this.emitter.emit("stderr", data);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
// Process exit
|
|
196
|
+
proc.on("exit", (code, signal) => {
|
|
197
|
+
this.emitter.emit("exit", { code, signal });
|
|
198
|
+
this.cleanup();
|
|
199
|
+
});
|
|
200
|
+
// Process errors
|
|
201
|
+
proc.on("error", (err) => {
|
|
202
|
+
this._state = "error";
|
|
203
|
+
const error = new TransportError(`Process error: ${err.message}`, err);
|
|
204
|
+
this.emitter.emit("error", error);
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
cleanup() {
|
|
208
|
+
if (this.process) {
|
|
209
|
+
this.process.removeAllListeners();
|
|
210
|
+
// Close streams
|
|
211
|
+
if (this.process.stdin && !this.process.stdin.destroyed) {
|
|
212
|
+
this.process.stdin.destroy();
|
|
213
|
+
}
|
|
214
|
+
if (this.process.stdout && !this.process.stdout.destroyed) {
|
|
215
|
+
this.process.stdout.destroy();
|
|
216
|
+
}
|
|
217
|
+
if (this.process.stderr && !this.process.stderr.destroyed) {
|
|
218
|
+
this.process.stderr.destroy();
|
|
219
|
+
}
|
|
220
|
+
// Kill if still alive
|
|
221
|
+
if (!this.process.killed) {
|
|
222
|
+
this.process.kill();
|
|
223
|
+
}
|
|
224
|
+
this.process = null;
|
|
225
|
+
}
|
|
226
|
+
if (this._state !== "disconnected") {
|
|
227
|
+
this._state = "disconnected";
|
|
228
|
+
this.emitter.emit("disconnect", undefined);
|
|
229
|
+
}
|
|
230
|
+
this.stdoutBytesReceived = 0;
|
|
231
|
+
this.stderrBytesReceived = 0;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=stdio-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio-transport.js","sourceRoot":"","sources":["../../src/transport/stdio-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAgElE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,cAAc;IACR,OAAO,GAAG,IAAI,YAAY,EAAwB,CAAC;IACnD,OAAO,CAAkC;IAClD,OAAO,GAAqC,IAAI,CAAC;IACjD,MAAM,GAAmB,cAAc,CAAC;IACxC,YAAY,GAA0B,IAAI,CAAC;IAC3C,mBAAmB,GAAG,CAAC,CAAC;IACxB,mBAAmB,GAAG,CAAC,CAAC;IAEhC,YAAY,OAA8B;QACxC,IAAI,CAAC,OAAO,GAAG;YACb,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE;YACxB,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE;YACjC,GAAG,EAAE,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAA6B;YACzD,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,KAAK;YAC/C,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,OAAO;YACrE,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,MAAM;SACpE,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,MAAM,GAAG,YAAY,CAAC;QAE3B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;oBAC9E,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG;oBACrB,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG;oBACrB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;iBAChC,CAAC,CAAC;gBAEH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;gBAEpB,kBAAkB;gBAClB,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;oBAClC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACZ,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;oBACtB,MAAM,KAAK,GAAG,IAAI,cAAc,CAC9B,iCAAiC,IAAI,CAAC,OAAO,CAAC,cAAc,IAAI,EAChE,IAAI,YAAY,CAAC,iBAAiB,CAAC,CACpC,CAAC;oBACF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;oBAClC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChB,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;gBAEhC,sDAAsD;gBACtD,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;oBACtB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;wBACtB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;wBAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;oBAC3B,CAAC;oBAED,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;oBAC1B,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;oBACjC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;oBACxC,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;gBAEH,sBAAsB;gBACtB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;oBACzB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;wBACtB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;wBAChC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;oBAC3B,CAAC;oBAED,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;oBACtB,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,4BAA4B,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;oBACjF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;oBAClC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChB,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;gBACtB,MAAM,KAAK,GAAG,IAAI,cAAc,CAC9B,6BAA8B,GAAa,CAAC,OAAO,EAAE,EACrD,GAAY,CACb,CAAC;gBACF,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QAED,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,OAAO,EAAE,CAAC;YACjB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAQ,CAAC;gBAE3B,sCAAsC;gBACtC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;oBACxC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;gBACnB,CAAC;gBAED,gBAAgB;gBAChB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;oBACrB,IAAI,CAAC,OAAO,EAAE,CAAC;oBACf,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;gBAEH,2BAA2B;gBAC3B,UAAU,CAAC,GAAG,EAAE;oBACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;wBACjB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACvB,CAAC;gBACH,CAAC,EAAE,IAAI,CAAC,CAAC;gBAET,qBAAqB;gBACrB,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,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,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACxE,MAAM,IAAI,cAAc,CAAC,eAAe,CAAC,CAAC;QAC5C,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAQ,CAAC,KAAM,CAAC;YAEnC,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBACpB,MAAM,CAAC,IAAI,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBAC9C,OAAO;YACT,CAAC;YAED,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC5C,IAAI,GAAG,EAAE,CAAC;oBACR,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,0BAA0B,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;oBAC/E,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,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;oBACvB,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,OAAgD;QAEhD,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAEO,qBAAqB,CAAC,IAA+B;QAC3D,cAAc;QACd,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACtC,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,MAAM,CAAC;gBAExC,IAAI,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;oBAC5D,MAAM,KAAK,GAAG,IAAI,cAAc,CAC9B,mCAAmC,IAAI,CAAC,OAAO,CAAC,eAAe,QAAQ,CACxE,CAAC;oBACF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;oBAClC,IAAI,CAAC,UAAU,EAAE,CAAC;oBAClB,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,iCAAiC;QACjC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAChC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAE,EAAE;gBACtC,IAAI,CAAC,mBAAmB,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBAEpD,IAAI,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;oBAC5D,MAAM,KAAK,GAAG,IAAI,cAAc,CAC9B,mCAAmC,IAAI,CAAC,OAAO,CAAC,eAAe,QAAQ,CACxE,CAAC;oBACF,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;oBAClC,IAAI,CAAC,UAAU,EAAE,CAAC;oBAClB,OAAO;gBACT,CAAC;gBAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACpC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,eAAe;QACf,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;YAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;QAEH,iBAAiB;QACjB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACvB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;YACtB,MAAM,KAAK,GAAG,IAAI,cAAc,CAAC,kBAAkB,GAAG,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,CAAC;YACvE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,OAAO;QACb,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;YAElC,gBAAgB;YAChB,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;gBACxD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAC/B,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC1D,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAChC,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC1D,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAChC,CAAC;YAED,sBAAsB;YACtB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;gBACzB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACtB,CAAC;YAED,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,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;QAED,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;IAC/B,CAAC;CACF"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import type { EventMap } from "../utils/events.js";
|
|
2
|
+
import type { Unsubscribe } from "../utils/disposables.js";
|
|
3
|
+
/**
|
|
4
|
+
* Transport connection state.
|
|
5
|
+
*/
|
|
6
|
+
export type TransportState = "disconnected" | "connecting" | "connected" | "error";
|
|
7
|
+
/**
|
|
8
|
+
* Transport events map.
|
|
9
|
+
*/
|
|
10
|
+
export interface TransportEvents extends EventMap {
|
|
11
|
+
/**
|
|
12
|
+
* Fired when transport successfully connects.
|
|
13
|
+
*/
|
|
14
|
+
connect: void;
|
|
15
|
+
/**
|
|
16
|
+
* Fired when transport disconnects (graceful or error).
|
|
17
|
+
*/
|
|
18
|
+
disconnect: void;
|
|
19
|
+
/**
|
|
20
|
+
* Fired when an error occurs.
|
|
21
|
+
*/
|
|
22
|
+
error: Error;
|
|
23
|
+
/**
|
|
24
|
+
* Fired when data is received.
|
|
25
|
+
*/
|
|
26
|
+
data: Buffer;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Base transport interface for bidirectional byte streams.
|
|
30
|
+
* Implementations: stdio, named pipes, unix sockets, TCP, etc.
|
|
31
|
+
*/
|
|
32
|
+
export interface Transport {
|
|
33
|
+
/**
|
|
34
|
+
* Current connection state.
|
|
35
|
+
*/
|
|
36
|
+
readonly state: TransportState;
|
|
37
|
+
/**
|
|
38
|
+
* Initiates connection.
|
|
39
|
+
* @throws {TransportError} if already connected or invalid state
|
|
40
|
+
*/
|
|
41
|
+
connect(): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Closes the connection gracefully.
|
|
44
|
+
* @throws {TransportError} if not connected
|
|
45
|
+
*/
|
|
46
|
+
disconnect(): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Writes data to the transport.
|
|
49
|
+
* @throws {TransportError} if not connected or write fails
|
|
50
|
+
*/
|
|
51
|
+
write(data: Buffer): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Subscribes to data events.
|
|
54
|
+
* @returns Unsubscribe function
|
|
55
|
+
*/
|
|
56
|
+
onData(handler: (data: Buffer) => void): Unsubscribe;
|
|
57
|
+
/**
|
|
58
|
+
* Subscribes to transport events.
|
|
59
|
+
* @returns Unsubscribe function
|
|
60
|
+
*/
|
|
61
|
+
on<K extends keyof TransportEvents>(event: K, handler: (data: TransportEvents[K]) => void): Unsubscribe;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Server address information.
|
|
65
|
+
*/
|
|
66
|
+
export interface ServerAddress {
|
|
67
|
+
/**
|
|
68
|
+
* Address type (pipe name, unix socket path, TCP port, etc.)
|
|
69
|
+
*/
|
|
70
|
+
type: "pipe" | "unix" | "tcp";
|
|
71
|
+
/**
|
|
72
|
+
* Address value (platform-specific).
|
|
73
|
+
*/
|
|
74
|
+
value: string | number;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Transport server events map.
|
|
78
|
+
*/
|
|
79
|
+
export interface TransportServerEvents extends EventMap {
|
|
80
|
+
/**
|
|
81
|
+
* Fired when server starts listening.
|
|
82
|
+
*/
|
|
83
|
+
listening: ServerAddress;
|
|
84
|
+
/**
|
|
85
|
+
* Fired when new client connection is established.
|
|
86
|
+
*/
|
|
87
|
+
connection: Transport;
|
|
88
|
+
/**
|
|
89
|
+
* Fired when server closes.
|
|
90
|
+
*/
|
|
91
|
+
close: void;
|
|
92
|
+
/**
|
|
93
|
+
* Fired when server error occurs.
|
|
94
|
+
*/
|
|
95
|
+
error: Error;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Transport server interface for accepting client connections.
|
|
99
|
+
* Implementations: named pipe server, unix socket server, TCP server.
|
|
100
|
+
*/
|
|
101
|
+
export interface TransportServer {
|
|
102
|
+
/**
|
|
103
|
+
* Returns true if server is currently listening.
|
|
104
|
+
*/
|
|
105
|
+
readonly isListening: boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Server address (only available when listening).
|
|
108
|
+
*/
|
|
109
|
+
readonly address: ServerAddress | null;
|
|
110
|
+
/**
|
|
111
|
+
* Starts listening for connections.
|
|
112
|
+
* @param address - Platform-specific address (pipe name, socket path, port)
|
|
113
|
+
* @throws {TransportError} if already listening
|
|
114
|
+
*/
|
|
115
|
+
listen(address: string | number): Promise<ServerAddress>;
|
|
116
|
+
/**
|
|
117
|
+
* Stops the server and closes all active connections.
|
|
118
|
+
*/
|
|
119
|
+
close(): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* Subscribes to new connection events.
|
|
122
|
+
* @returns Unsubscribe function
|
|
123
|
+
*/
|
|
124
|
+
onConnection(handler: (transport: Transport) => void): Unsubscribe;
|
|
125
|
+
/**
|
|
126
|
+
* Subscribes to server events.
|
|
127
|
+
* @returns Unsubscribe function
|
|
128
|
+
*/
|
|
129
|
+
on<K extends keyof TransportServerEvents>(event: K, handler: (data: TransportServerEvents[K]) => void): Unsubscribe;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/transport/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,OAAO,CAAC;AAEnF;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,QAAQ;IAC/C;;OAEG;IACH,OAAO,EAAE,IAAI,CAAC;IAEd;;OAEG;IACH,UAAU,EAAE,IAAI,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC;IAEb;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAE/B;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB;;;OAGG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC;;;OAGG;IACH,MAAM,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,WAAW,CAAC;IAErD;;;OAGG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,eAAe,EAChC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,KAAK,IAAI,GAC1C,WAAW,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IAE9B;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAsB,SAAQ,QAAQ;IACrD;;OAEG;IACH,SAAS,EAAE,aAAa,CAAC;IAEzB;;OAEG;IACH,UAAU,EAAE,SAAS,CAAC;IAEtB;;OAEG;IACH,KAAK,EAAE,IAAI,CAAC;IAEZ;;OAEG;IACH,KAAK,EAAE,KAAK,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IAEvC;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAEzD;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,IAAI,GAAG,WAAW,CAAC;IAEnE;;;OAGG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,qBAAqB,EACtC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC,CAAC,KAAK,IAAI,GAChD,WAAW,CAAC;CAChB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/transport/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { TransportState } from "../transport/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Asserts that current state is one of the allowed states.
|
|
4
|
+
* Throws TransportError if not.
|
|
5
|
+
*/
|
|
6
|
+
export declare function assertState(current: TransportState, allowed: TransportState[]): void;
|
|
7
|
+
/**
|
|
8
|
+
* Map of allowed state transitions.
|
|
9
|
+
*/
|
|
10
|
+
export declare const TRANSPORT_STATE_TRANSITIONS: Record<TransportState, TransportState[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Validates and returns next state if transition is allowed.
|
|
13
|
+
* Throws TransportError if transition is invalid.
|
|
14
|
+
*/
|
|
15
|
+
export declare function transitionState(current: TransportState, next: TransportState): TransportState;
|
|
16
|
+
//# sourceMappingURL=assert.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert.d.ts","sourceRoot":"","sources":["../../src/utils/assert.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI,CAMpF;AAED;;GAEG;AACH,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,cAAc,EAAE,cAAc,EAAE,CAKhF,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,GAAG,cAAc,CAQ7F"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { TransportError } from "./errors.js";
|
|
2
|
+
/**
|
|
3
|
+
* Asserts that current state is one of the allowed states.
|
|
4
|
+
* Throws TransportError if not.
|
|
5
|
+
*/
|
|
6
|
+
export function assertState(current, allowed) {
|
|
7
|
+
if (!allowed.includes(current)) {
|
|
8
|
+
throw new TransportError(`Invalid state: expected one of [${allowed.join(", ")}], got '${current}'`);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Map of allowed state transitions.
|
|
13
|
+
*/
|
|
14
|
+
export const TRANSPORT_STATE_TRANSITIONS = {
|
|
15
|
+
disconnected: ["connecting"],
|
|
16
|
+
connecting: ["connected", "error", "disconnected"],
|
|
17
|
+
connected: ["disconnected", "error"],
|
|
18
|
+
error: ["disconnected"],
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Validates and returns next state if transition is allowed.
|
|
22
|
+
* Throws TransportError if transition is invalid.
|
|
23
|
+
*/
|
|
24
|
+
export function transitionState(current, next) {
|
|
25
|
+
const allowed = TRANSPORT_STATE_TRANSITIONS[current];
|
|
26
|
+
if (!allowed.includes(next)) {
|
|
27
|
+
throw new TransportError(`Invalid state transition: '${current}' -> '${next}'. Allowed: [${allowed.join(", ")}]`);
|
|
28
|
+
}
|
|
29
|
+
return next;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=assert.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assert.js","sourceRoot":"","sources":["../../src/utils/assert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAuB,EAAE,OAAyB;IAC5E,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,cAAc,CACtB,mCAAmC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,OAAO,GAAG,CAC3E,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAA6C;IACnF,YAAY,EAAE,CAAC,YAAY,CAAC;IAC5B,UAAU,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,cAAc,CAAC;IAClD,SAAS,EAAE,CAAC,cAAc,EAAE,OAAO,CAAC;IACpC,KAAK,EAAE,CAAC,cAAc,CAAC;CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,OAAuB,EAAE,IAAoB;IAC3E,MAAM,OAAO,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;IACrD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,cAAc,CACtB,8BAA8B,OAAO,SAAS,IAAI,gBAAgB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACxF,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Function that performs cleanup/unsubscribe when called.
|
|
3
|
+
*/
|
|
4
|
+
export type Unsubscribe = () => void;
|
|
5
|
+
/**
|
|
6
|
+
* Object that can be disposed (has dispose method).
|
|
7
|
+
*/
|
|
8
|
+
export interface DisposableLike {
|
|
9
|
+
dispose(): void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Converts a function to an Unsubscribe function.
|
|
13
|
+
* Ensures idempotency (can be called multiple times safely).
|
|
14
|
+
*/
|
|
15
|
+
export declare function createUnsubscribe(fn: () => void): Unsubscribe;
|
|
16
|
+
/**
|
|
17
|
+
* Collects multiple unsubscribe functions and disposes them all at once.
|
|
18
|
+
* Useful for cleanup in components/channels that manage multiple subscriptions.
|
|
19
|
+
*/
|
|
20
|
+
export declare class CompositeDisposable {
|
|
21
|
+
private readonly disposables;
|
|
22
|
+
private disposed;
|
|
23
|
+
/**
|
|
24
|
+
* Adds an unsubscribe function to the composite.
|
|
25
|
+
* If already disposed, calls it immediately.
|
|
26
|
+
*/
|
|
27
|
+
add(unsubscribe: Unsubscribe): void;
|
|
28
|
+
/**
|
|
29
|
+
* Disposes all collected unsubscribe functions.
|
|
30
|
+
* Safe to call multiple times (idempotent).
|
|
31
|
+
*/
|
|
32
|
+
dispose(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Returns true if already disposed.
|
|
35
|
+
*/
|
|
36
|
+
isDisposed(): boolean;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=disposables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disposables.d.ts","sourceRoot":"","sources":["../../src/utils/disposables.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,WAAW,CAQ7D;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;OAGG;IACH,GAAG,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAQnC;;;OAGG;IACH,OAAO,IAAI,IAAI;IAgBf;;OAEG;IACH,UAAU,IAAI,OAAO;CAGtB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a function to an Unsubscribe function.
|
|
3
|
+
* Ensures idempotency (can be called multiple times safely).
|
|
4
|
+
*/
|
|
5
|
+
export function createUnsubscribe(fn) {
|
|
6
|
+
let disposed = false;
|
|
7
|
+
return () => {
|
|
8
|
+
if (!disposed) {
|
|
9
|
+
disposed = true;
|
|
10
|
+
fn();
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Collects multiple unsubscribe functions and disposes them all at once.
|
|
16
|
+
* Useful for cleanup in components/channels that manage multiple subscriptions.
|
|
17
|
+
*/
|
|
18
|
+
export class CompositeDisposable {
|
|
19
|
+
disposables = [];
|
|
20
|
+
disposed = false;
|
|
21
|
+
/**
|
|
22
|
+
* Adds an unsubscribe function to the composite.
|
|
23
|
+
* If already disposed, calls it immediately.
|
|
24
|
+
*/
|
|
25
|
+
add(unsubscribe) {
|
|
26
|
+
if (this.disposed) {
|
|
27
|
+
unsubscribe();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
this.disposables.push(unsubscribe);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Disposes all collected unsubscribe functions.
|
|
34
|
+
* Safe to call multiple times (idempotent).
|
|
35
|
+
*/
|
|
36
|
+
dispose() {
|
|
37
|
+
if (this.disposed) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
this.disposed = true;
|
|
41
|
+
for (const unsubscribe of this.disposables) {
|
|
42
|
+
try {
|
|
43
|
+
unsubscribe();
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
// Log but don't throw - we want to dispose all
|
|
47
|
+
console.error("Error during disposal:", error);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
this.disposables.length = 0;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Returns true if already disposed.
|
|
54
|
+
*/
|
|
55
|
+
isDisposed() {
|
|
56
|
+
return this.disposed;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=disposables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disposables.js","sourceRoot":"","sources":["../../src/utils/disposables.ts"],"names":[],"mappings":"AAYA;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAc;IAC9C,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,OAAO,GAAG,EAAE;QACV,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG,IAAI,CAAC;YAChB,EAAE,EAAE,CAAC;QACP,CAAC;IACH,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,mBAAmB;IACb,WAAW,GAAkB,EAAE,CAAC;IACzC,QAAQ,GAAG,KAAK,CAAC;IAEzB;;;OAGG;IACH,GAAG,CAAC,WAAwB;QAC1B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,WAAW,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACrC,CAAC;IAED;;;OAGG;IACH,OAAO;QACL,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACH,WAAW,EAAE,CAAC;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,+CAA+C;gBAC/C,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all Aspect IPC errors.
|
|
3
|
+
*/
|
|
4
|
+
export declare class AspectIpcError extends Error {
|
|
5
|
+
readonly code: string;
|
|
6
|
+
constructor(message: string, code: string, cause?: unknown);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Transport-layer error (connection, I/O, etc.)
|
|
10
|
+
*/
|
|
11
|
+
export declare class TransportError extends AspectIpcError {
|
|
12
|
+
constructor(message: string, cause?: unknown);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Protocol-layer error (parsing, validation, etc.)
|
|
16
|
+
*/
|
|
17
|
+
export declare class ProtocolError extends AspectIpcError {
|
|
18
|
+
constructor(message: string, cause?: unknown);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Timeout error (request timeout, connection timeout, etc.)
|
|
22
|
+
*/
|
|
23
|
+
export declare class TimeoutError extends AspectIpcError {
|
|
24
|
+
constructor(message: string, cause?: unknown);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Serialization error (encode/decode failures)
|
|
28
|
+
*/
|
|
29
|
+
export declare class SerializationError extends AspectIpcError {
|
|
30
|
+
constructor(message: string, cause?: unknown);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Framing error (invalid frame format, buffer overflow, etc.)
|
|
34
|
+
*/
|
|
35
|
+
export declare class FramingError extends AspectIpcError {
|
|
36
|
+
constructor(message: string, cause?: unknown);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Converts unknown value to Error instance.
|
|
40
|
+
* Useful for catch blocks and error normalization.
|
|
41
|
+
*/
|
|
42
|
+
export declare function toError(value: unknown): Error;
|
|
43
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAgB,IAAI,EAAE,MAAM,CAAC;gBAEjB,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAU3D;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,cAAc;gBACpC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,cAAc;gBACnC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,cAAc;gBAClC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,cAAc;gBACxC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,cAAc;gBAClC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAG7C;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CAQ7C"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for all Aspect IPC errors.
|
|
3
|
+
*/
|
|
4
|
+
export class AspectIpcError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
constructor(message, code, cause) {
|
|
7
|
+
super(message, { cause });
|
|
8
|
+
this.name = this.constructor.name;
|
|
9
|
+
this.code = code;
|
|
10
|
+
// Maintain proper stack trace in V8 engines
|
|
11
|
+
if (Error.captureStackTrace) {
|
|
12
|
+
Error.captureStackTrace(this, this.constructor);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Transport-layer error (connection, I/O, etc.)
|
|
18
|
+
*/
|
|
19
|
+
export class TransportError extends AspectIpcError {
|
|
20
|
+
constructor(message, cause) {
|
|
21
|
+
super(message, "TRANSPORT_ERROR", cause);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Protocol-layer error (parsing, validation, etc.)
|
|
26
|
+
*/
|
|
27
|
+
export class ProtocolError extends AspectIpcError {
|
|
28
|
+
constructor(message, cause) {
|
|
29
|
+
super(message, "PROTOCOL_ERROR", cause);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Timeout error (request timeout, connection timeout, etc.)
|
|
34
|
+
*/
|
|
35
|
+
export class TimeoutError extends AspectIpcError {
|
|
36
|
+
constructor(message, cause) {
|
|
37
|
+
super(message, "TIMEOUT_ERROR", cause);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Serialization error (encode/decode failures)
|
|
42
|
+
*/
|
|
43
|
+
export class SerializationError extends AspectIpcError {
|
|
44
|
+
constructor(message, cause) {
|
|
45
|
+
super(message, "SERIALIZATION_ERROR", cause);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Framing error (invalid frame format, buffer overflow, etc.)
|
|
50
|
+
*/
|
|
51
|
+
export class FramingError extends AspectIpcError {
|
|
52
|
+
constructor(message, cause) {
|
|
53
|
+
super(message, "FRAMING_ERROR", cause);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Converts unknown value to Error instance.
|
|
58
|
+
* Useful for catch blocks and error normalization.
|
|
59
|
+
*/
|
|
60
|
+
export function toError(value) {
|
|
61
|
+
if (value instanceof Error) {
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
if (typeof value === "string") {
|
|
65
|
+
return new Error(value);
|
|
66
|
+
}
|
|
67
|
+
return new Error(String(value));
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=errors.js.map
|