@push.rocks/smartrust 1.5.0 → 1.6.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.
@@ -1,6 +1,6 @@
1
1
  import * as plugins from './plugins.js';
2
2
  import type { IRustBridgeLogger } from './interfaces/index.js';
3
- import type { IRustTransport } from './interfaces/transport.js';
3
+ import type { IRustTransport, IRustTransportDisconnectOptions } from './interfaces/transport.js';
4
4
  export interface ISocketTransportOptions {
5
5
  /** Path to Unix socket (Linux/macOS) or named pipe path (Windows) */
6
6
  socketPath: string;
@@ -24,13 +24,18 @@ export interface ISocketTransportOptions {
24
24
  export declare class SocketTransport extends plugins.events.EventEmitter implements IRustTransport {
25
25
  private options;
26
26
  private socket;
27
+ private generation;
27
28
  private lineScanner;
28
29
  private _connected;
29
30
  private intentionalDisconnect;
30
31
  private reconnectAttempts;
31
32
  private reconnectTimer;
33
+ private lifecycleToken;
34
+ private _reconnecting;
35
+ private reconnectFailed;
32
36
  constructor(options: ISocketTransportOptions);
33
37
  get connected(): boolean;
38
+ get reconnecting(): boolean;
34
39
  /**
35
40
  * Connect to the socket. Resolves when the TCP/Unix connection is established.
36
41
  */
@@ -42,7 +47,16 @@ export declare class SocketTransport extends plugins.events.EventEmitter impleme
42
47
  */
43
48
  write(data: string): Promise<void>;
44
49
  /**
45
- * Close the socket connection. Does NOT kill the remote daemon.
50
+ * Close the local socket without waiting for confirmation.
51
+ * This does not kill the remote daemon.
46
52
  */
47
53
  disconnect(): void;
54
+ /**
55
+ * Destroy the local socket and wait until its 'close' event confirms closure.
56
+ * This does not signal or otherwise terminate the remote daemon.
57
+ */
58
+ disconnectAndWait(_options?: IRustTransportDisconnectOptions): Promise<void>;
59
+ private cancelReconnectTimer;
60
+ private toError;
61
+ private getErrorMessage;
48
62
  }
@@ -7,11 +7,15 @@ import { LineScanner } from './classes.linescanner.js';
7
7
  export class SocketTransport extends plugins.events.EventEmitter {
8
8
  options;
9
9
  socket = null;
10
+ generation = null;
10
11
  lineScanner;
11
12
  _connected = false;
12
13
  intentionalDisconnect = false;
13
14
  reconnectAttempts = 0;
14
15
  reconnectTimer = null;
16
+ lifecycleToken = 0;
17
+ _reconnecting = false;
18
+ reconnectFailed = false;
15
19
  constructor(options) {
16
20
  super();
17
21
  this.options = {
@@ -26,113 +30,287 @@ export class SocketTransport extends plugins.events.EventEmitter {
26
30
  get connected() {
27
31
  return this._connected;
28
32
  }
33
+ get reconnecting() {
34
+ return !this.intentionalDisconnect && this._reconnecting;
35
+ }
29
36
  /**
30
37
  * Connect to the socket. Resolves when the TCP/Unix connection is established.
31
38
  */
32
- async connect() {
39
+ connect() {
40
+ if (this.generation && !this.generation.closed) {
41
+ return Promise.reject(new Error('Socket transport already has an active connection attempt or connection'));
42
+ }
43
+ this.cancelReconnectTimer();
44
+ const lifecycleToken = ++this.lifecycleToken;
33
45
  this.intentionalDisconnect = false;
46
+ this._reconnecting = false;
47
+ this.reconnectFailed = false;
34
48
  this.reconnectAttempts = 0;
35
- return this.doConnect();
49
+ return this.doConnect(lifecycleToken, false);
36
50
  }
37
- doConnect() {
38
- return new Promise((resolve, reject) => {
39
- let settled = false;
40
- this.socket = plugins.net.connect({ path: this.options.socketPath });
41
- this.socket.on('connect', () => {
42
- if (!settled) {
43
- settled = true;
44
- this._connected = true;
45
- this.reconnectAttempts = 0;
46
- resolve();
47
- }
48
- });
49
- this.socket.on('data', (chunk) => {
50
- this.lineScanner.push(chunk, (line) => {
51
+ doConnect(lifecycleToken, reconnectAttempt) {
52
+ if (lifecycleToken !== this.lifecycleToken
53
+ || this.intentionalDisconnect) {
54
+ return Promise.reject(new Error('Socket connection attempt was cancelled'));
55
+ }
56
+ if (this.generation && !this.generation.closed) {
57
+ return Promise.reject(new Error('Socket transport already has an active connection attempt or connection'));
58
+ }
59
+ const socket = new plugins.net.Socket();
60
+ let resolveConnect;
61
+ let rejectConnect;
62
+ const connectPromise = new Promise((resolve, reject) => {
63
+ resolveConnect = resolve;
64
+ rejectConnect = reject;
65
+ });
66
+ let resolveClose;
67
+ const closePromise = new Promise((resolve) => {
68
+ resolveClose = resolve;
69
+ });
70
+ const generation = {
71
+ socket,
72
+ lifecycleToken,
73
+ reconnectAttempt,
74
+ everConnected: false,
75
+ connectSettled: false,
76
+ closed: false,
77
+ closePromise,
78
+ resolveClose,
79
+ disconnectPromise: null,
80
+ };
81
+ this.generation = generation;
82
+ this.socket = socket;
83
+ socket.on('connect', () => {
84
+ if (this.generation !== generation || generation.closed) {
85
+ return;
86
+ }
87
+ generation.everConnected = true;
88
+ this._connected = true;
89
+ if (generation.reconnectAttempt) {
90
+ this._reconnecting = false;
91
+ }
92
+ this.reconnectAttempts = 0;
93
+ if (!generation.connectSettled) {
94
+ generation.connectSettled = true;
95
+ resolveConnect();
96
+ }
97
+ });
98
+ socket.on('data', (chunk) => {
99
+ if (this.generation !== generation || generation.closed) {
100
+ return;
101
+ }
102
+ this.lineScanner.push(chunk, (line) => {
103
+ if (this.generation === generation && !generation.closed) {
51
104
  this.emit('line', line);
52
- });
53
- });
54
- this.socket.on('close', () => {
55
- const wasConnected = this._connected;
56
- this._connected = false;
57
- this.lineScanner.clear();
58
- if (!this.intentionalDisconnect && wasConnected && this.options.autoReconnect) {
59
- this.attemptReconnect();
60
- }
61
- this.emit('close');
62
- });
63
- this.socket.on('error', (err) => {
64
- this._connected = false;
65
- if (!settled) {
66
- settled = true;
67
- reject(err);
68
- }
69
- else if (!this.intentionalDisconnect) {
70
- this.emit('error', err);
71
105
  }
72
106
  });
73
107
  });
108
+ socket.on('close', () => {
109
+ if (generation.closed) {
110
+ return;
111
+ }
112
+ generation.closed = true;
113
+ if (!generation.connectSettled) {
114
+ generation.connectSettled = true;
115
+ rejectConnect(new Error('Socket closed before connection was established'));
116
+ }
117
+ generation.resolveClose();
118
+ if (this.generation !== generation) {
119
+ return;
120
+ }
121
+ this._connected = false;
122
+ this.socket = null;
123
+ this.lineScanner.clear();
124
+ const shouldReconnect = (!this.intentionalDisconnect
125
+ && generation.lifecycleToken === this.lifecycleToken
126
+ && this.options.autoReconnect
127
+ && (generation.everConnected || generation.reconnectAttempt));
128
+ if (shouldReconnect) {
129
+ this._reconnecting = true;
130
+ }
131
+ this.emit('close');
132
+ // A close listener may intentionally disconnect or start a new generation.
133
+ // Only the still-current closed generation may schedule the retry.
134
+ if (shouldReconnect
135
+ && this.generation === generation
136
+ && !this.intentionalDisconnect
137
+ && generation.lifecycleToken === this.lifecycleToken) {
138
+ this.attemptReconnect(generation.lifecycleToken);
139
+ }
140
+ });
141
+ socket.on('error', (error) => {
142
+ if (this.generation !== generation || generation.closed) {
143
+ return;
144
+ }
145
+ this._connected = false;
146
+ if (!generation.connectSettled) {
147
+ generation.connectSettled = true;
148
+ rejectConnect(error);
149
+ }
150
+ else if (!this.intentionalDisconnect) {
151
+ this.emit('error', error);
152
+ }
153
+ });
154
+ try {
155
+ socket.connect({ path: this.options.socketPath });
156
+ }
157
+ catch (error) {
158
+ const connectError = this.toError(error, 'Failed to initiate socket connection');
159
+ generation.closed = true;
160
+ if (!generation.connectSettled) {
161
+ generation.connectSettled = true;
162
+ rejectConnect(connectError);
163
+ }
164
+ generation.resolveClose();
165
+ if (this.generation === generation) {
166
+ this._connected = false;
167
+ this.socket = null;
168
+ this.lineScanner.clear();
169
+ }
170
+ if (reconnectAttempt
171
+ && !this.intentionalDisconnect
172
+ && lifecycleToken === this.lifecycleToken) {
173
+ this.attemptReconnect(lifecycleToken);
174
+ }
175
+ }
176
+ return connectPromise;
74
177
  }
75
- attemptReconnect() {
178
+ attemptReconnect(lifecycleToken) {
179
+ if (lifecycleToken !== this.lifecycleToken
180
+ || this.intentionalDisconnect
181
+ || this.reconnectFailed
182
+ || this.reconnectTimer
183
+ || (this.generation && !this.generation.closed)) {
184
+ return;
185
+ }
76
186
  if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {
77
- this.options.logger.log('error', `Max reconnect attempts (${this.options.maxReconnectAttempts}) reached`);
187
+ this._reconnecting = false;
188
+ this.reconnectFailed = true;
189
+ ++this.lifecycleToken;
190
+ this.options.logger.log('error', 'Max reconnect attempts (' + this.options.maxReconnectAttempts + ') reached');
78
191
  this.emit('reconnect_failed');
79
192
  return;
80
193
  }
194
+ this._reconnecting = true;
81
195
  const delay = Math.min(this.options.reconnectBaseDelayMs * Math.pow(2, this.reconnectAttempts), this.options.reconnectMaxDelayMs);
82
196
  this.reconnectAttempts++;
83
- this.options.logger.log('info', `Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts}/${this.options.maxReconnectAttempts})`);
84
- this.reconnectTimer = setTimeout(async () => {
197
+ this.options.logger.log('info', 'Reconnecting in '
198
+ + delay
199
+ + 'ms (attempt '
200
+ + this.reconnectAttempts
201
+ + '/'
202
+ + this.options.maxReconnectAttempts
203
+ + ')');
204
+ this.reconnectTimer = setTimeout(() => {
85
205
  this.reconnectTimer = null;
86
- try {
87
- await this.doConnect();
88
- this.emit('reconnected');
89
- }
90
- catch {
91
- // doConnect rejected — the 'close' handler on the new socket will trigger another attempt
206
+ if (lifecycleToken !== this.lifecycleToken
207
+ || this.intentionalDisconnect) {
208
+ return;
92
209
  }
210
+ void this.doConnect(lifecycleToken, true).then(() => {
211
+ if (lifecycleToken === this.lifecycleToken
212
+ && !this.intentionalDisconnect) {
213
+ this.emit('reconnected');
214
+ }
215
+ }).catch(() => {
216
+ // The generation's close handler schedules the next reconnect attempt.
217
+ });
93
218
  }, delay);
94
219
  }
95
220
  /**
96
221
  * Write data to the socket with backpressure support.
97
222
  */
98
- async write(data) {
223
+ write(data) {
99
224
  return new Promise((resolve, reject) => {
100
- if (!this.socket || !this._connected) {
225
+ const generation = this.generation;
226
+ if (!generation
227
+ || generation.closed
228
+ || generation.socket !== this.socket
229
+ || !this._connected) {
101
230
  reject(new Error('Socket not connected'));
102
231
  return;
103
232
  }
104
- const canContinue = this.socket.write(data, 'utf8', (err) => {
105
- if (err) {
106
- reject(err);
233
+ const canContinue = generation.socket.write(data, 'utf8', (error) => {
234
+ if (error) {
235
+ reject(error);
107
236
  }
108
237
  });
109
238
  if (canContinue) {
110
239
  resolve();
111
240
  }
112
241
  else {
113
- this.socket.once('drain', () => {
242
+ generation.socket.once('drain', () => {
114
243
  resolve();
115
244
  });
116
245
  }
117
246
  });
118
247
  }
119
248
  /**
120
- * Close the socket connection. Does NOT kill the remote daemon.
249
+ * Close the local socket without waiting for confirmation.
250
+ * This does not kill the remote daemon.
121
251
  */
122
252
  disconnect() {
253
+ try {
254
+ void this.disconnectAndWait().catch((error) => {
255
+ this.options.logger.log('error', 'Failed to disconnect socket transport: ' + this.getErrorMessage(error));
256
+ });
257
+ }
258
+ catch (error) {
259
+ this.options.logger.log('error', 'Failed to disconnect socket transport: ' + this.getErrorMessage(error));
260
+ }
261
+ }
262
+ /**
263
+ * Destroy the local socket and wait until its 'close' event confirms closure.
264
+ * This does not signal or otherwise terminate the remote daemon.
265
+ */
266
+ disconnectAndWait(_options = {}) {
123
267
  this.intentionalDisconnect = true;
268
+ this._reconnecting = false;
269
+ ++this.lifecycleToken;
270
+ this.cancelReconnectTimer();
271
+ const generation = this.generation;
272
+ if (!generation) {
273
+ return Promise.resolve();
274
+ }
275
+ if (generation.disconnectPromise) {
276
+ return generation.disconnectPromise;
277
+ }
278
+ if (generation.closed) {
279
+ generation.disconnectPromise = generation.closePromise;
280
+ return generation.disconnectPromise;
281
+ }
282
+ this._connected = false;
283
+ let rejectDisconnect;
284
+ const disconnectPromise = new Promise((resolve, reject) => {
285
+ rejectDisconnect = reject;
286
+ void generation.closePromise.then(resolve);
287
+ });
288
+ generation.disconnectPromise = disconnectPromise;
289
+ void disconnectPromise.then(() => { }, () => {
290
+ if (generation.disconnectPromise === disconnectPromise) {
291
+ generation.disconnectPromise = null;
292
+ }
293
+ });
294
+ // The close waiter above must exist before destroy() can cause 'close'.
295
+ try {
296
+ generation.socket.destroy();
297
+ }
298
+ catch (error) {
299
+ rejectDisconnect(this.toError(error, 'Failed to destroy local socket'));
300
+ }
301
+ return disconnectPromise;
302
+ }
303
+ cancelReconnectTimer() {
124
304
  if (this.reconnectTimer) {
125
305
  clearTimeout(this.reconnectTimer);
126
306
  this.reconnectTimer = null;
127
307
  }
128
- if (this.socket) {
129
- const sock = this.socket;
130
- this.socket = null;
131
- this._connected = false;
132
- this.lineScanner.clear();
133
- sock.removeAllListeners();
134
- sock.destroy();
135
- }
308
+ }
309
+ toError(error, prefix) {
310
+ return new Error(prefix + ': ' + this.getErrorMessage(error));
311
+ }
312
+ getErrorMessage(error) {
313
+ return error instanceof Error ? error.message : String(error);
136
314
  }
137
315
  }
138
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zb2NrZXR0cmFuc3BvcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnNvY2tldHRyYW5zcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUErQnZEOzs7R0FHRztBQUNILE1BQU0sT0FBTyxlQUFnQixTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtJQUN0RCxPQUFPLENBQWtDO0lBQ3pDLE1BQU0sR0FBOEIsSUFBSSxDQUFDO0lBQ3pDLFdBQVcsQ0FBYztJQUN6QixVQUFVLEdBQVksS0FBSyxDQUFDO0lBQzVCLHFCQUFxQixHQUFZLEtBQUssQ0FBQztJQUN2QyxpQkFBaUIsR0FBVyxDQUFDLENBQUM7SUFDOUIsY0FBYyxHQUF5QyxJQUFJLENBQUM7SUFFcEUsWUFBWSxPQUFnQztRQUMxQyxLQUFLLEVBQUUsQ0FBQztRQUNSLElBQUksQ0FBQyxPQUFPLEdBQUc7WUFDYixhQUFhLEVBQUUsS0FBSztZQUNwQixvQkFBb0IsRUFBRSxHQUFHO1lBQ3pCLG1CQUFtQixFQUFFLEtBQUs7WUFDMUIsb0JBQW9CLEVBQUUsRUFBRTtZQUN4QixHQUFHLE9BQU87U0FDWCxDQUFDO1FBQ0YsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM3RSxDQUFDO0lBRUQsSUFBVyxTQUFTO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsT0FBTztRQUNsQixJQUFJLENBQUMscUJBQXFCLEdBQUcsS0FBSyxDQUFDO1FBQ25DLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLENBQUM7UUFDM0IsT0FBTyxJQUFJ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
316
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zb2NrZXR0cmFuc3BvcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnNvY2tldHRyYW5zcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUE4Q3ZEOzs7R0FHRztBQUNILE1BQU0sT0FBTyxlQUFnQixTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtJQUN0RCxPQUFPLENBQWtDO0lBQ3pDLE1BQU0sR0FBOEIsSUFBSSxDQUFDO0lBQ3pDLFVBQVUsR0FBc0MsSUFBSSxDQUFDO0lBQ3JELFdBQVcsQ0FBYztJQUN6QixVQUFVLEdBQVksS0FBSyxDQUFDO0lBQzVCLHFCQUFxQixHQUFZLEtBQUssQ0FBQztJQUN2QyxpQkFBaUIsR0FBVyxDQUFDLENBQUM7SUFDOUIsY0FBYyxHQUF5QyxJQUFJLENBQUM7SUFDNUQsY0FBYyxHQUFXLENBQUMsQ0FBQztJQUMzQixhQUFhLEdBQVksS0FBSyxDQUFDO0lBQy9CLGVBQWUsR0FBWSxLQUFLLENBQUM7SUFFekMsWUFBWSxPQUFnQztRQUMxQyxLQUFLLEVBQUUsQ0FBQztRQUNSLElBQUksQ0FBQyxPQUFPLEdBQUc7WUFDYixhQUFhLEVBQUUsS0FBSztZQUNwQixvQkFBb0IsRUFBRSxHQUFHO1lBQ3pCLG1CQUFtQixFQUFFLEtBQUs7WUFDMUIsb0JBQW9CLEVBQUUsRUFBRTtZQUN4QixHQUFHLE9BQU87U0FDWCxDQUFDO1FBQ0YsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM3RSxDQUFDO0lBRUQsSUFBVyxTQUFTO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBRUQsSUFBVyxZQUFZO1FBQ3JCLE9BQU8sQ0FBQyxJQUFJLENBQUMscUJBQXFCLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUMzRCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxPQUFPO1FBQ1osSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUMvQyxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQ25CLElBQUksS0FBSyxDQUFDLHlFQUF5RSxDQUFDLENBQ3JGLENBQUM7UUFDSixDQUFDO1FBRUQsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDNUIsTUFBTSxjQUFjLEdBQUcsRUFBRSxJQUFJLENBQUMsY0FBYyxDQUFDO1FBQzdDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUM7UUFDbkMsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFDM0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7UUFDN0IsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsQ0FBQztRQUMzQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFTyxTQUFTLENBQ2YsY0FBc0IsRUFDdEIsZ0JBQXlCO1FBRXpCLElBQ0UsY0FBYyxLQUFLLElBQUksQ0FBQyxjQUFjO2VBQ25DLElBQUksQ0FBQyxxQkFBcUIsRUFDN0IsQ0FBQztZQUNELE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDLENBQUM7UUFDOUUsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDL0MsT0FBTyxPQUFPLENBQUMsTUFBTSxDQUNuQixJQUFJLEtBQUssQ0FBQyx5RUFBeUUsQ0FBQyxDQUNyRixDQUFDO1FBQ0osQ0FBQztRQUVELE1BQU0sTUFBTSxHQUFHLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN4QyxJQUFJLGNBQTJCLENBQUM7UUFDaEMsSUFBSSxhQUFzQyxDQUFDO1FBQzNDLE1BQU0sY0FBYyxHQUFHLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQzNELGNBQWMsR0FBRyxPQUFPLENBQUM7WUFDekIsYUFBYSxHQUFHLE1BQU0sQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztRQUNILElBQUksWUFBeUIsQ0FBQztRQUM5QixNQUFNLFlBQVksR0FBRyxJQUFJLE9BQU8sQ0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ2pELFlBQVksR0FBRyxPQUFPLENBQUM7UUFDekIsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLFVBQVUsR0FBK0I7WUFDN0MsTUFBTTtZQUNOLGNBQWM7WUFDZCxnQkFBZ0I7WUFDaEIsYUFBYSxFQUFFLEtBQUs7WUFDcEIsY0FBYyxFQUFFLEtBQUs7WUFDckIsTUFBTSxFQUFFLEtBQUs7WUFDYixZQUFZO1lBQ1osWUFBWTtZQUNaLGlCQUFpQixFQUFFLElBQUk7U0FDeEIsQ0FBQztRQUVGLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQzdCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBRXJCLE1BQU0sQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRTtZQUN4QixJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssVUFBVSxJQUFJLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDeEQsT0FBTztZQUNULENBQUM7WUFFRCxVQUFVLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztZQUNoQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztZQUN2QixJQUFJLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO2dCQUNoQyxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztZQUM3QixDQUFDO1lBQ0QsSUFBSSxDQUFDLGlCQUFpQixHQUFHLENBQUMsQ0FBQztZQUMzQixJQUFJLENBQUMsVUFBVSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUMvQixVQUFVLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztnQkFDakMsY0FBYyxFQUFFLENBQUM7WUFDbkIsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxLQUFhLEVBQUUsRUFBRTtZQUNsQyxJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssVUFBVSxJQUFJLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDeEQsT0FBTztZQUNULENBQUM7WUFFRCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRTtnQkFDcEMsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLFVBQVUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQkFDekQsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQzFCLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO1lBQ3RCLElBQUksVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUN0QixPQUFPO1lBQ1QsQ0FBQztZQUVELFVBQVUsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQy9CLFVBQVUsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO2dCQUNqQyxhQUFhLENBQUMsSUFBSSxLQUFLLENBQUMsaURBQWlELENBQUMsQ0FBQyxDQUFDO1lBQzlFLENBQUM7WUFDRCxVQUFVLENBQUMsWUFBWSxFQUFFLENBQUM7WUFFMUIsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLFVBQVUsRUFBRSxDQUFDO2dCQUNuQyxPQUFPO1lBQ1QsQ0FBQztZQUVELElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1lBQ3hCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1lBQ25CLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7WUFFekIsTUFBTSxlQUFlLEdBQUcsQ0FDdEIsQ0FBQyxJQUFJLENBQUMscUJBQXFCO21CQUN4QixVQUFVLENBQUMsY0FBYyxLQUFLLElBQUksQ0FBQyxjQUFjO21CQUNqRCxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWE7bUJBQzFCLENBQUMsVUFBVSxDQUFDLGFBQWEsSUFBSSxVQUFVLENBQUMsZ0JBQWdCLENBQUMsQ0FDN0QsQ0FBQztZQUNGLElBQUksZUFBZSxFQUFFLENBQUM7Z0JBQ3BCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1lBQzVCLENBQUM7WUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBRW5CLDJFQUEyRTtZQUMzRSxtRUFBbUU7WUFDbkUsSUFDRSxlQUFlO21CQUNaLElBQUksQ0FBQyxVQUFVLEtBQUssVUFBVTttQkFDOUIsQ0FBQyxJQUFJLENBQUMscUJBQXFCO21CQUMzQixVQUFVLENBQUMsY0FBYyxLQUFLLElBQUksQ0FBQyxjQUFjLEVBQ3BELENBQUM7Z0JBQ0QsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUNuRCxDQUFDO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLEtBQVksRUFBRSxFQUFFO1lBQ2xDLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxVQUFVLElBQUksVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUN4RCxPQUFPO1lBQ1QsQ0FBQztZQUVELElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1lBQ3hCLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQy9CLFVBQVUsQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO2dCQUNqQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkIsQ0FBQztpQkFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7Z0JBQ3ZDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzVCLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQztZQUNILE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFBQyxPQUFPLEtBQWMsRUFBRSxDQUFDO1lBQ3hCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLHNDQUFzQyxDQUFDLENBQUM7WUFDakYsVUFBVSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7WUFDekIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDL0IsVUFBVSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7Z0JBQ2pDLGFBQWEsQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUM5QixDQUFDO1lBQ0QsVUFBVSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQzFCLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxVQUFVLEVBQUUsQ0FBQztnQkFDbkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO2dCQUNuQixJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzNCLENBQUM7WUFDRCxJQUNFLGdCQUFnQjttQkFDYixDQUFDLElBQUksQ0FBQyxxQkFBcUI7bUJBQzNCLGNBQWMsS0FBSyxJQUFJLENBQUMsY0FBYyxFQUN6QyxDQUFDO2dCQUNELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUN4QyxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sY0FBYyxDQUFDO0lBQ3hCLENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxjQUFzQjtRQUM3QyxJQUNFLGNBQWMsS0FBSyxJQUFJLENBQUMsY0FBYztlQUNuQyxJQUFJLENBQUMscUJBQXFCO2VBQzFCLElBQUksQ0FBQyxlQUFlO2VBQ3BCLElBQUksQ0FBQyxjQUFjO2VBQ25CLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQy9DLENBQUM7WUFDRCxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLGlCQUFpQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUNoRSxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztZQUMzQixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztZQUM1QixFQUFFLElBQUksQ0FBQyxjQUFjLENBQUM7WUFDdEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUNyQixPQUFPLEVBQ1AsMEJBQTBCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsR0FBRyxXQUFXLENBQzdFLENBQUM7WUFDRixJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7WUFDOUIsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQztRQUUxQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsR0FBRyxDQUNwQixJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxFQUN2RSxJQUFJLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUNqQyxDQUFDO1FBQ0YsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFFekIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUNyQixNQUFNLEVBQ04sa0JBQWtCO2NBQ2QsS0FBSztjQUNMLGNBQWM7Y0FDZCxJQUFJLENBQUMsaUJBQWlCO2NBQ3RCLEdBQUc7Y0FDSCxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQjtjQUNqQyxHQUFHLENBQ1IsQ0FBQztRQUVGLElBQUksQ0FBQyxjQUFjLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNwQyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztZQUMzQixJQUNFLGNBQWMsS0FBSyxJQUFJLENBQUMsY0FBYzttQkFDbkMsSUFBSSxDQUFDLHFCQUFxQixFQUM3QixDQUFDO2dCQUNELE9BQU87WUFDVCxDQUFDO1lBRUQsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO2dCQUNsRCxJQUNFLGNBQWMsS0FBSyxJQUFJLENBQUMsY0FBYzt1QkFDbkMsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQzlCLENBQUM7b0JBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDM0IsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ1osdUVBQXVFO1lBQ3pFLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ1osQ0FBQztJQUVEOztPQUVHO0lBQ0ksS0FBSyxDQUFDLElBQVk7UUFDdkIsT0FBTyxJQUFJLE9BQU8sQ0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUMzQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQ25DLElBQ0UsQ0FBQyxVQUFVO21CQUNSLFVBQVUsQ0FBQyxNQUFNO21CQUNqQixVQUFVLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxNQUFNO21CQUNqQyxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQ25CLENBQUM7Z0JBQ0QsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUMsQ0FBQztnQkFDMUMsT0FBTztZQUNULENBQUM7WUFFRCxNQUFNLFdBQVcsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQ2xFLElBQUksS0FBSyxFQUFFLENBQUM7b0JBQ1YsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUNoQixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUM7WUFFSCxJQUFJLFdBQVcsRUFBRSxDQUFDO2dCQUNoQixPQUFPLEVBQUUsQ0FBQztZQUNaLENBQUM7aUJBQU0sQ0FBQztnQkFDTixVQUFVLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO29CQUNuQyxPQUFPLEVBQUUsQ0FBQztnQkFDWixDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7O09BR0c7SUFDSSxVQUFVO1FBQ2YsSUFBSSxDQUFDO1lBQ0gsS0FBSyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFjLEVBQUUsRUFBRTtnQkFDckQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUNyQixPQUFPLEVBQ1AseUNBQXlDLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FDeEUsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUFDLE9BQU8sS0FBYyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUNyQixPQUFPLEVBQ1AseUNBQXlDLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FDeEUsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksaUJBQWlCLENBQ3RCLFdBQTRDLEVBQUU7UUFFOUMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQztRQUNsQyxJQUFJLENBQUMsYUFBYSxHQUFHLEtBQUssQ0FBQztRQUMzQixFQUFFLElBQUksQ0FBQyxjQUFjLENBQUM7UUFDdEIsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFFNUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUNuQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsT0FBTyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDM0IsQ0FBQztRQUNELElBQUksVUFBVSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDakMsT0FBTyxVQUFVLENBQUMsaUJBQWlCLENBQUM7UUFDdEMsQ0FBQztRQUNELElBQUksVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3RCLFVBQVUsQ0FBQyxpQkFBaUIsR0FBRyxVQUFVLENBQUMsWUFBWSxDQUFDO1lBQ3ZELE9BQU8sVUFBVSxDQUFDLGlCQUFpQixDQUFDO1FBQ3RDLENBQUM7UUFFRCxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztRQUN4QixJQUFJLGdCQUF5QyxDQUFDO1FBQzlDLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxPQUFPLENBQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDOUQsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDO1lBQzFCLEtBQUssVUFBVSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDN0MsQ0FBQyxDQUFDLENBQUM7UUFDSCxVQUFVLENBQUMsaUJBQWlCLEdBQUcsaUJBQWlCLENBQUM7UUFDakQsS0FBSyxpQkFBaUIsQ0FBQyxJQUFJLENBQ3pCLEdBQUcsRUFBRSxHQUFFLENBQUMsRUFDUixHQUFHLEVBQUU7WUFDSCxJQUFJLFVBQVUsQ0FBQyxpQkFBaUIsS0FBSyxpQkFBaUIsRUFBRSxDQUFDO2dCQUN2RCxVQUFVLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO1lBQ3RDLENBQUM7UUFDSCxDQUFDLENBQ0YsQ0FBQztRQUVGLHdFQUF3RTtRQUN4RSxJQUFJLENBQUM7WUFDSCxVQUFVLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzlCLENBQUM7UUFBQyxPQUFPLEtBQWMsRUFBRSxDQUFDO1lBQ3hCLGdCQUFnQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLGdDQUFnQyxDQUFDLENBQUMsQ0FBQztRQUMxRSxDQUFDO1FBRUQsT0FBTyxpQkFBaUIsQ0FBQztJQUMzQixDQUFDO0lBRU8sb0JBQW9CO1FBQzFCLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ3hCLFlBQVksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDbEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDN0IsQ0FBQztJQUNILENBQUM7SUFFTyxPQUFPLENBQUMsS0FBYyxFQUFFLE1BQWM7UUFDNUMsT0FBTyxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRU8sZUFBZSxDQUFDLEtBQWM7UUFDcEMsT0FBTyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEUsQ0FBQztDQUNGIn0=
@@ -1,6 +1,6 @@
1
1
  import * as plugins from './plugins.js';
2
2
  import type { IRustBridgeLogger } from './interfaces/index.js';
3
- import type { IRustTransport } from './interfaces/transport.js';
3
+ import type { IRustTransport, IRustTransportDisconnectOptions } from './interfaces/transport.js';
4
4
  export interface IStdioTransportOptions {
5
5
  binaryPath: string;
6
6
  cliArgs: string[];
@@ -15,8 +15,8 @@ export interface IStdioTransportOptions {
15
15
  export declare class StdioTransport extends plugins.events.EventEmitter implements IRustTransport {
16
16
  private options;
17
17
  private childProcess;
18
+ private generation;
18
19
  private lineScanner;
19
- private stderrRemainder;
20
20
  private _connected;
21
21
  constructor(options: IStdioTransportOptions);
22
22
  get connected(): boolean;
@@ -29,7 +29,19 @@ export declare class StdioTransport extends plugins.events.EventEmitter implemen
29
29
  */
30
30
  write(data: string): Promise<void>;
31
31
  /**
32
- * Kill the child process. Sends SIGTERM, then SIGKILL after 5s.
32
+ * Kill the child process without waiting for confirmation.
33
33
  */
34
34
  disconnect(): void;
35
+ /**
36
+ * Send SIGTERM, escalate to SIGKILL after the grace period, and wait for
37
+ * ChildProcess 'close' to confirm termination.
38
+ */
39
+ disconnectAndWait(options?: IRustTransportDisconnectOptions): Promise<void>;
40
+ private scheduleForceKill;
41
+ private forceKill;
42
+ private sendSignal;
43
+ private hasExited;
44
+ private destroyOwnedStdioEndpoint;
45
+ private toError;
46
+ private getErrorMessage;
35
47
  }