@push.rocks/smartrust 1.4.1 → 1.6.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/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.rustbridge.d.ts +19 -8
- package/dist_ts/classes.rustbridge.js +302 -78
- package/dist_ts/classes.sockettransport.d.ts +16 -2
- package/dist_ts/classes.sockettransport.js +234 -61
- package/dist_ts/classes.stdiotransport.d.ts +15 -3
- package/dist_ts/classes.stdiotransport.js +253 -59
- package/dist_ts/interfaces/config.d.ts +8 -0
- package/dist_ts/interfaces/transport.d.ts +9 -0
- package/package.json +1 -1
- package/readme.md +30 -5
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.rustbridge.ts +363 -83
- package/ts/classes.sockettransport.ts +304 -60
- package/ts/classes.stdiotransport.ts +345 -58
- package/ts/interfaces/config.ts +9 -0
- package/ts/interfaces/transport.ts +12 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import { LineScanner } from './classes.linescanner.js';
|
|
3
|
+
const DEFAULT_DISCONNECT_GRACE_PERIOD_MS = 5000;
|
|
4
|
+
const MAX_TIMER_DELAY_MS = 2_147_483_647;
|
|
3
5
|
/**
|
|
4
6
|
* Transport that spawns a child process and communicates via stdin/stdout.
|
|
5
7
|
* Extracted from the original RustBridge process management logic.
|
|
@@ -7,8 +9,8 @@ import { LineScanner } from './classes.linescanner.js';
|
|
|
7
9
|
export class StdioTransport extends plugins.events.EventEmitter {
|
|
8
10
|
options;
|
|
9
11
|
childProcess = null;
|
|
12
|
+
generation = null;
|
|
10
13
|
lineScanner;
|
|
11
|
-
stderrRemainder = '';
|
|
12
14
|
_connected = false;
|
|
13
15
|
constructor(options) {
|
|
14
16
|
super();
|
|
@@ -21,16 +23,49 @@ export class StdioTransport extends plugins.events.EventEmitter {
|
|
|
21
23
|
/**
|
|
22
24
|
* Spawn the child process. Resolves when the process is running (not necessarily ready).
|
|
23
25
|
*/
|
|
24
|
-
|
|
26
|
+
connect() {
|
|
27
|
+
if (this.generation && !this.generation.closed) {
|
|
28
|
+
return Promise.reject(new Error('Stdio transport cannot connect until the previous child has closed'));
|
|
29
|
+
}
|
|
25
30
|
const env = this.options.env
|
|
26
31
|
? { ...process.env, ...this.options.env }
|
|
27
32
|
: { ...process.env };
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.
|
|
33
|
+
let childProcess;
|
|
34
|
+
try {
|
|
35
|
+
childProcess = plugins.childProcess.spawn(this.options.binaryPath, this.options.cliArgs, { stdio: ['pipe', 'pipe', 'pipe'], env });
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
return Promise.reject(this.toError(error, 'Failed to spawn child process'));
|
|
39
|
+
}
|
|
40
|
+
let resolveClose;
|
|
41
|
+
const closePromise = new Promise((resolve) => {
|
|
42
|
+
resolveClose = resolve;
|
|
43
|
+
});
|
|
44
|
+
const generation = {
|
|
45
|
+
childProcess,
|
|
46
|
+
stderrRemainder: '',
|
|
47
|
+
exited: false,
|
|
48
|
+
closed: false,
|
|
49
|
+
closePromise,
|
|
50
|
+
resolveClose,
|
|
51
|
+
disconnectPromise: null,
|
|
52
|
+
rejectDisconnect: null,
|
|
53
|
+
forceKillTimer: null,
|
|
54
|
+
sigtermAttempted: false,
|
|
55
|
+
sigkillAttempted: false,
|
|
56
|
+
sigtermError: null,
|
|
57
|
+
stdioDestroyError: null,
|
|
58
|
+
};
|
|
59
|
+
this.generation = generation;
|
|
60
|
+
this.childProcess = childProcess;
|
|
61
|
+
// Handle stderr with cross-chunk buffering.
|
|
62
|
+
childProcess.stderr?.on('data', (data) => {
|
|
63
|
+
if (this.generation !== generation || generation.closed) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
generation.stderrRemainder += data.toString();
|
|
67
|
+
const lines = generation.stderrRemainder.split('\n');
|
|
68
|
+
generation.stderrRemainder = lines.pop();
|
|
34
69
|
for (const line of lines) {
|
|
35
70
|
const trimmed = line.trim();
|
|
36
71
|
if (trimmed) {
|
|
@@ -38,99 +73,258 @@ export class StdioTransport extends plugins.events.EventEmitter {
|
|
|
38
73
|
}
|
|
39
74
|
}
|
|
40
75
|
});
|
|
41
|
-
// Handle stdout via LineScanner
|
|
42
|
-
|
|
76
|
+
// Handle stdout via LineScanner.
|
|
77
|
+
childProcess.stdout.on('data', (chunk) => {
|
|
78
|
+
if (this.generation !== generation || generation.closed) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
43
81
|
this.lineScanner.push(chunk, (line) => {
|
|
44
|
-
this.
|
|
82
|
+
if (this.generation === generation && !generation.closed) {
|
|
83
|
+
this.emit('line', line);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
childProcess.on('exit', () => {
|
|
88
|
+
generation.exited = true;
|
|
89
|
+
if (this.generation === generation) {
|
|
90
|
+
this._connected = false;
|
|
91
|
+
}
|
|
92
|
+
// A descendant may inherit the child's stdio descriptors and otherwise
|
|
93
|
+
// keep ChildProcess 'close' from ever firing after the owned child exits.
|
|
94
|
+
// Allow already-queued data events through this poll turn, then close our
|
|
95
|
+
// endpoints so confirmation cannot retain that pipe graph indefinitely.
|
|
96
|
+
setImmediate(() => {
|
|
97
|
+
if (generation.closed) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
this.destroyOwnedStdioEndpoint(generation, 'stdin');
|
|
101
|
+
this.destroyOwnedStdioEndpoint(generation, 'stdout');
|
|
102
|
+
this.destroyOwnedStdioEndpoint(generation, 'stderr');
|
|
45
103
|
});
|
|
46
104
|
});
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
|
|
105
|
+
// ChildProcess 'close' is the termination confirmation: the process has exited
|
|
106
|
+
// and its stdio streams have closed.
|
|
107
|
+
childProcess.on('close', (code, signal) => {
|
|
108
|
+
if (generation.closed) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
// Flush stderr while this generation is still considered active so a
|
|
112
|
+
// synchronous listener cannot start a replacement child mid-cleanup.
|
|
113
|
+
if (this.generation === generation
|
|
114
|
+
&& generation.stderrRemainder.trim()) {
|
|
115
|
+
this.emit('stderr', generation.stderrRemainder.trim());
|
|
116
|
+
}
|
|
117
|
+
generation.stderrRemainder = '';
|
|
118
|
+
generation.exited = true;
|
|
119
|
+
generation.closed = true;
|
|
120
|
+
if (generation.forceKillTimer) {
|
|
121
|
+
clearTimeout(generation.forceKillTimer);
|
|
122
|
+
generation.forceKillTimer = null;
|
|
123
|
+
}
|
|
124
|
+
generation.resolveClose();
|
|
125
|
+
if (this.generation !== generation) {
|
|
126
|
+
return;
|
|
52
127
|
}
|
|
53
128
|
this._connected = false;
|
|
129
|
+
this.childProcess = null;
|
|
54
130
|
this.lineScanner.clear();
|
|
55
|
-
this.stderrRemainder = '';
|
|
56
131
|
this.emit('close', code, signal);
|
|
57
132
|
});
|
|
58
|
-
|
|
133
|
+
childProcess.on('error', (error) => {
|
|
134
|
+
if (this.generation !== generation || generation.closed) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
59
137
|
this._connected = false;
|
|
60
|
-
|
|
138
|
+
if (generation.sigkillAttempted && generation.rejectDisconnect) {
|
|
139
|
+
generation.rejectDisconnect(this.toError(error, 'Unable to confirm child termination after SIGKILL'));
|
|
140
|
+
}
|
|
141
|
+
if (this.listenerCount('error') > 0) {
|
|
142
|
+
this.emit('error', error);
|
|
143
|
+
}
|
|
144
|
+
else if (generation.disconnectPromise) {
|
|
145
|
+
this.options.logger.log('error', 'Stdio transport error during disconnect: ' + error.message);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
this.emit('error', error);
|
|
149
|
+
}
|
|
61
150
|
});
|
|
62
151
|
this._connected = true;
|
|
152
|
+
return Promise.resolve();
|
|
63
153
|
}
|
|
64
154
|
/**
|
|
65
155
|
* Write data to stdin with backpressure support.
|
|
66
156
|
*/
|
|
67
|
-
|
|
157
|
+
write(data) {
|
|
68
158
|
return new Promise((resolve, reject) => {
|
|
69
|
-
|
|
159
|
+
const generation = this.generation;
|
|
160
|
+
if (!generation
|
|
161
|
+
|| generation.closed
|
|
162
|
+
|| generation.childProcess !== this.childProcess
|
|
163
|
+
|| !this._connected
|
|
164
|
+
|| !generation.childProcess.stdin) {
|
|
70
165
|
reject(new Error('stdin not available'));
|
|
71
166
|
return;
|
|
72
167
|
}
|
|
73
|
-
const canContinue =
|
|
74
|
-
if (
|
|
75
|
-
reject(
|
|
168
|
+
const canContinue = generation.childProcess.stdin.write(data, 'utf8', (error) => {
|
|
169
|
+
if (error) {
|
|
170
|
+
reject(error);
|
|
76
171
|
}
|
|
77
172
|
});
|
|
78
173
|
if (canContinue) {
|
|
79
174
|
resolve();
|
|
80
175
|
}
|
|
81
176
|
else {
|
|
82
|
-
|
|
177
|
+
generation.childProcess.stdin.once('drain', () => {
|
|
83
178
|
resolve();
|
|
84
179
|
});
|
|
85
180
|
}
|
|
86
181
|
});
|
|
87
182
|
}
|
|
88
183
|
/**
|
|
89
|
-
* Kill the child process
|
|
184
|
+
* Kill the child process without waiting for confirmation.
|
|
90
185
|
*/
|
|
91
186
|
disconnect() {
|
|
92
|
-
if (!this.childProcess)
|
|
93
|
-
return;
|
|
94
|
-
const proc = this.childProcess;
|
|
95
|
-
this.childProcess = null;
|
|
96
|
-
this._connected = false;
|
|
97
|
-
this.lineScanner.clear();
|
|
98
|
-
this.stderrRemainder = '';
|
|
99
|
-
// Remove all listeners
|
|
100
|
-
proc.removeAllListeners();
|
|
101
|
-
proc.stdout?.removeAllListeners();
|
|
102
|
-
proc.stderr?.removeAllListeners();
|
|
103
|
-
proc.stdin?.removeAllListeners();
|
|
104
|
-
// Kill the process
|
|
105
187
|
try {
|
|
106
|
-
|
|
188
|
+
void this.disconnectAndWait().catch((error) => {
|
|
189
|
+
this.options.logger.log('error', 'Failed to disconnect stdio transport: ' + this.getErrorMessage(error));
|
|
190
|
+
});
|
|
107
191
|
}
|
|
108
|
-
catch {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
192
|
+
catch (error) {
|
|
193
|
+
this.options.logger.log('error', 'Failed to disconnect stdio transport: ' + this.getErrorMessage(error));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Send SIGTERM, escalate to SIGKILL after the grace period, and wait for
|
|
198
|
+
* ChildProcess 'close' to confirm termination.
|
|
199
|
+
*/
|
|
200
|
+
disconnectAndWait(options = {}) {
|
|
201
|
+
const gracePeriodMs = options.gracePeriodMs ?? DEFAULT_DISCONNECT_GRACE_PERIOD_MS;
|
|
202
|
+
if (!Number.isSafeInteger(gracePeriodMs) || gracePeriodMs < 0) {
|
|
203
|
+
throw new RangeError('StdioTransport gracePeriodMs must be a non-negative safe integer');
|
|
204
|
+
}
|
|
205
|
+
const generation = this.generation;
|
|
206
|
+
if (!generation) {
|
|
207
|
+
return Promise.resolve();
|
|
208
|
+
}
|
|
209
|
+
if (generation.disconnectPromise) {
|
|
210
|
+
return generation.disconnectPromise;
|
|
211
|
+
}
|
|
212
|
+
if (generation.stdioDestroyError) {
|
|
213
|
+
generation.disconnectPromise = Promise.reject(generation.stdioDestroyError);
|
|
214
|
+
return generation.disconnectPromise;
|
|
215
|
+
}
|
|
216
|
+
if (generation.closed) {
|
|
217
|
+
generation.disconnectPromise = generation.closePromise;
|
|
218
|
+
return generation.disconnectPromise;
|
|
219
|
+
}
|
|
220
|
+
let rejectDisconnect;
|
|
221
|
+
const disconnectPromise = new Promise((resolve, reject) => {
|
|
222
|
+
rejectDisconnect = reject;
|
|
223
|
+
void generation.closePromise.then(resolve);
|
|
224
|
+
});
|
|
225
|
+
generation.disconnectPromise = disconnectPromise;
|
|
226
|
+
generation.rejectDisconnect = rejectDisconnect;
|
|
227
|
+
this._connected = false;
|
|
228
|
+
if (this.hasExited(generation)) {
|
|
229
|
+
return disconnectPromise;
|
|
230
|
+
}
|
|
231
|
+
generation.sigtermAttempted = true;
|
|
232
|
+
generation.sigtermError = this.sendSignal(generation, 'SIGTERM');
|
|
233
|
+
if (generation.closed || this.hasExited(generation)) {
|
|
234
|
+
return disconnectPromise;
|
|
112
235
|
}
|
|
113
|
-
|
|
236
|
+
if (gracePeriodMs === 0) {
|
|
237
|
+
this.forceKill(generation);
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
this.scheduleForceKill(generation, gracePeriodMs);
|
|
241
|
+
}
|
|
242
|
+
return disconnectPromise;
|
|
243
|
+
}
|
|
244
|
+
scheduleForceKill(generation, remainingMs) {
|
|
245
|
+
if (generation.closed || this.hasExited(generation)) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const delayMs = Math.min(remainingMs, MAX_TIMER_DELAY_MS);
|
|
249
|
+
const scheduledAt = Date.now();
|
|
114
250
|
try {
|
|
115
|
-
|
|
251
|
+
generation.forceKillTimer = setTimeout(() => {
|
|
252
|
+
generation.forceKillTimer = null;
|
|
253
|
+
if (generation.closed || this.hasExited(generation)) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const elapsedMs = Math.max(1, Date.now() - scheduledAt);
|
|
257
|
+
const nextRemainingMs = remainingMs - elapsedMs;
|
|
258
|
+
if (nextRemainingMs > 0) {
|
|
259
|
+
this.scheduleForceKill(generation, nextRemainingMs);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
this.forceKill(generation);
|
|
263
|
+
}
|
|
264
|
+
}, delayMs);
|
|
116
265
|
}
|
|
117
|
-
catch {
|
|
266
|
+
catch (error) {
|
|
267
|
+
generation.rejectDisconnect?.(this.toError(error, 'Unable to schedule SIGKILL escalation'));
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
forceKill(generation) {
|
|
271
|
+
if (generation.closed
|
|
272
|
+
|| generation.sigkillAttempted
|
|
273
|
+
|| this.hasExited(generation)) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
generation.sigkillAttempted = true;
|
|
277
|
+
const sigkillError = this.sendSignal(generation, 'SIGKILL');
|
|
278
|
+
if (sigkillError && !generation.closed && !this.hasExited(generation)) {
|
|
279
|
+
const sigtermDetail = generation.sigtermError
|
|
280
|
+
? ' SIGTERM also failed: ' + generation.sigtermError.message + '.'
|
|
281
|
+
: '';
|
|
282
|
+
generation.rejectDisconnect?.(new Error(sigkillError.message + '.' + sigtermDetail));
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
sendSignal(generation, signal) {
|
|
118
286
|
try {
|
|
119
|
-
|
|
287
|
+
const delivered = generation.childProcess.kill(signal);
|
|
288
|
+
if (delivered || generation.closed || this.hasExited(generation)) {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
return new Error('Failed to send ' + signal + ' to child process');
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
if (generation.closed || this.hasExited(generation)) {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
return this.toError(error, 'Failed to send ' + signal + ' to child process');
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
hasExited(generation) {
|
|
301
|
+
return (generation.exited
|
|
302
|
+
|| generation.childProcess.exitCode !== null
|
|
303
|
+
|| generation.childProcess.signalCode !== null);
|
|
304
|
+
}
|
|
305
|
+
destroyOwnedStdioEndpoint(generation, endpointName) {
|
|
306
|
+
const endpoint = generation.childProcess[endpointName];
|
|
307
|
+
if (!endpoint || endpoint.destroyed) {
|
|
308
|
+
return;
|
|
120
309
|
}
|
|
121
|
-
catch { /* ignore */ }
|
|
122
|
-
// Unref so Node doesn't wait
|
|
123
310
|
try {
|
|
124
|
-
|
|
311
|
+
endpoint.destroy();
|
|
125
312
|
}
|
|
126
|
-
catch {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
313
|
+
catch (error) {
|
|
314
|
+
const endpointError = this.toError(error, 'Failed to close inherited child ' + endpointName);
|
|
315
|
+
generation.stdioDestroyError ??= endpointError;
|
|
316
|
+
generation.rejectDisconnect?.(endpointError);
|
|
317
|
+
this.options.logger.log('error', endpointError.message);
|
|
318
|
+
if (this.listenerCount('error') > 0) {
|
|
319
|
+
this.emit('error', endpointError);
|
|
131
320
|
}
|
|
132
|
-
|
|
133
|
-
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
toError(error, prefix) {
|
|
324
|
+
return new Error(prefix + ': ' + this.getErrorMessage(error));
|
|
325
|
+
}
|
|
326
|
+
getErrorMessage(error) {
|
|
327
|
+
return error instanceof Error ? error.message : String(error);
|
|
134
328
|
}
|
|
135
329
|
}
|
|
136
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zdGRpb3RyYW5zcG9ydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuc3RkaW90cmFuc3BvcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBWXZEOzs7R0FHRztBQUNILE1BQU0sT0FBTyxjQUFlLFNBQVEsT0FBTyxDQUFDLE1BQU0sQ0FBQyxZQUFZO0lBQ3JELE9BQU8sQ0FBeUI7SUFDaEMsWUFBWSxHQUE2QyxJQUFJLENBQUM7SUFDOUQsV0FBVyxDQUFjO0lBQ3pCLGVBQWUsR0FBVyxFQUFFLENBQUM7SUFDN0IsVUFBVSxHQUFZLEtBQUssQ0FBQztJQUVwQyxZQUFZLE9BQStCO1FBQ3pDLEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM3RSxDQUFDO0lBRUQsSUFBVyxTQUFTO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsT0FBTztRQUNsQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUc7WUFDMUIsQ0FBQyxDQUFDLEVBQUUsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDekMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFdkIsSUFBSSxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FDNUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxV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
|
|
330
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zdGRpb3RyYW5zcG9ydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuc3RkaW90cmFuc3BvcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBT3ZELE1BQU0sa0NBQWtDLEdBQUcsSUFBSSxDQUFDO0FBQ2hELE1BQU0sa0JBQWtCLEdBQUcsYUFBYSxDQUFDO0FBMEJ6Qzs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sY0FBZSxTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtJQUNyRCxPQUFPLENBQXlCO0lBQ2hDLFlBQVksR0FBNkMsSUFBSSxDQUFDO0lBQzlELFVBQVUsR0FBcUMsSUFBSSxDQUFDO0lBQ3BELFdBQVcsQ0FBYztJQUN6QixVQUFVLEdBQVksS0FBSyxDQUFDO0lBRXBDLFlBQVksT0FBK0I7UUFDekMsS0FBSyxFQUFFLENBQUM7UUFDUixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFFRCxJQUFXLFNBQVM7UUFDbEIsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQ3pCLENBQUM7SUFFRDs7T0FFRztJQUNJLE9BQU87UUFDWixJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQy9DLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FDbkIsSUFBSSxLQUFLLENBQUMsb0VBQW9FLENBQUMsQ0FDaEYsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUc7WUFD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
|
|
@@ -13,6 +13,14 @@ export interface IRustBridgeRequestOptions {
|
|
|
13
13
|
/** Override the bridge request timeout for this call, in milliseconds. */
|
|
14
14
|
timeoutMs?: number;
|
|
15
15
|
}
|
|
16
|
+
/** Options for confirmed bridge termination. */
|
|
17
|
+
export interface IRustBridgeTerminateOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Time to allow an owned stdio child to exit after SIGTERM before SIGKILL.
|
|
20
|
+
* Zero requests immediate SIGKILL. Defaults to 5000 milliseconds.
|
|
21
|
+
*/
|
|
22
|
+
gracePeriodMs?: number;
|
|
23
|
+
}
|
|
16
24
|
/**
|
|
17
25
|
* Options for locating a Rust binary.
|
|
18
26
|
*/
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type * as plugins from '../plugins.js';
|
|
2
|
+
/** Options for confirmed transport disconnection. */
|
|
3
|
+
export interface IRustTransportDisconnectOptions {
|
|
4
|
+
/** Grace period before escalating process termination, in milliseconds. */
|
|
5
|
+
gracePeriodMs?: number;
|
|
6
|
+
}
|
|
2
7
|
/**
|
|
3
8
|
* Abstract transport for communicating with a Rust process.
|
|
4
9
|
* Both stdio and socket transports implement this interface.
|
|
@@ -17,6 +22,10 @@ export interface IRustTransport extends plugins.events.EventEmitter {
|
|
|
17
22
|
write(data: string): Promise<void>;
|
|
18
23
|
/** Disconnect the transport. For stdio: kills the process. For socket: closes the connection. */
|
|
19
24
|
disconnect(): void;
|
|
25
|
+
/** Disconnect and resolve only after the local transport has confirmed closure. */
|
|
26
|
+
disconnectAndWait?(options?: IRustTransportDisconnectOptions): Promise<void>;
|
|
20
27
|
/** Whether the transport is currently connected and writable. */
|
|
21
28
|
readonly connected: boolean;
|
|
29
|
+
/** Whether the transport is preserving its lifecycle for an automatic reconnect. */
|
|
30
|
+
readonly reconnecting?: boolean;
|
|
22
31
|
}
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -99,8 +99,8 @@ bridge.on('management:configChanged', (data) => {
|
|
|
99
99
|
console.log('Config was changed:', data);
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
-
//
|
|
103
|
-
bridge.
|
|
102
|
+
// Confirmed shutdown (SIGTERM → SIGKILL after 5s)
|
|
103
|
+
await bridge.terminate();
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
### Per-Command Deadlines and Cancellation
|
|
@@ -154,6 +154,25 @@ programmatic handling:
|
|
|
154
154
|
| `ERR_RUST_BRIDGE_REQUEST_TRANSPORT` | The transport exited, disconnected, or was killed |
|
|
155
155
|
| `ERR_RUST_BRIDGE_REQUEST_RUST_RESPONSE` | Rust returned `success: false` |
|
|
156
156
|
|
|
157
|
+
### Confirmed Termination
|
|
158
|
+
|
|
159
|
+
Use `await bridge.terminate()` when later work must not overlap the current
|
|
160
|
+
worker. In stdio mode it sends SIGTERM, escalates to SIGKILL after five seconds,
|
|
161
|
+
and resolves only after the child process and its stdio handles have closed.
|
|
162
|
+
The grace period can be changed per termination; zero requests immediate
|
|
163
|
+
SIGKILL:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
await bridge.terminate({ gracePeriodMs: 250 });
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Concurrent calls share one termination operation, and calls after confirmed
|
|
170
|
+
closure are no-ops. The first concurrent caller's grace period applies. In
|
|
171
|
+
socket mode, termination confirms only the local socket closure; the remote
|
|
172
|
+
daemon is never signaled. `kill()` remains available for compatibility as a
|
|
173
|
+
fire-and-forget wrapper, but callers that require confirmed ownership release
|
|
174
|
+
must await `terminate()`.
|
|
175
|
+
|
|
157
176
|
### Socket Mode — Connect to a Running Daemon 🔗
|
|
158
177
|
|
|
159
178
|
When the Rust binary runs as a system service (e.g., via `systemd`, `launchd`, or a Windows Service), use `connect()` to talk to it over a Unix socket or named pipe:
|
|
@@ -174,8 +193,8 @@ if (!ok) {
|
|
|
174
193
|
const { pid } = await bridge.sendCommand('start', { port: 8080, host: '0.0.0.0' });
|
|
175
194
|
const metrics = await bridge.sendCommand('getMetrics', {});
|
|
176
195
|
|
|
177
|
-
//
|
|
178
|
-
bridge.
|
|
196
|
+
// terminate() confirms local socket closure — it does NOT kill the daemon
|
|
197
|
+
await bridge.terminate();
|
|
179
198
|
```
|
|
180
199
|
|
|
181
200
|
#### Auto-Reconnect
|
|
@@ -539,7 +558,8 @@ fn main() {
|
|
|
539
558
|
| `connect(socketPath, options?)` | `Promise<boolean>` | **Socket mode**: Connect to a running daemon; returns `false` on failure |
|
|
540
559
|
| `sendCommand(method, params, options?)` | `Promise<TCommands[K]['result']>` | Send a typed command with an optional per-call timeout or abort signal |
|
|
541
560
|
| `sendCommandStreaming(method, params)` | `StreamingResponse<TChunk, TResult>` | Send a streaming command; returns immediately |
|
|
542
|
-
| `
|
|
561
|
+
| `terminate(options?)` | `Promise<void>` | Confirm stdio child exit or local socket closure; `gracePeriodMs` controls SIGKILL escalation |
|
|
562
|
+
| `kill()` | `void` | Fire-and-forget compatibility wrapper around `terminate()` |
|
|
543
563
|
| `running` | `boolean` | Whether the bridge is currently connected and ready |
|
|
544
564
|
|
|
545
565
|
### `StreamingResponse<TChunk, TResult>`
|
|
@@ -565,6 +585,7 @@ fn main() {
|
|
|
565
585
|
| `connect()` | `Promise<void>` | Spawn the child process |
|
|
566
586
|
| `write(data)` | `Promise<void>` | Write to stdin with backpressure handling |
|
|
567
587
|
| `disconnect()` | `void` | Kill the process (SIGTERM → SIGKILL after 5s) |
|
|
588
|
+
| `disconnectAndWait(options?)` | `Promise<void>` | Confirm child close after SIGTERM/SIGKILL escalation |
|
|
568
589
|
| `connected` | `boolean` | Whether the process is running |
|
|
569
590
|
|
|
570
591
|
### `SocketTransport`
|
|
@@ -575,7 +596,9 @@ fn main() {
|
|
|
575
596
|
| `connect()` | `Promise<void>` | Connect to the Unix socket / named pipe |
|
|
576
597
|
| `write(data)` | `Promise<void>` | Write to socket with backpressure handling |
|
|
577
598
|
| `disconnect()` | `void` | Close the socket (does not kill the daemon) |
|
|
599
|
+
| `disconnectAndWait()` | `Promise<void>` | Confirm local socket closure without signaling the daemon |
|
|
578
600
|
| `connected` | `boolean` | Whether the socket is connected |
|
|
601
|
+
| `reconnecting` | `boolean` | Whether an automatic reconnect timer or attempt owns the socket lifecycle |
|
|
579
602
|
|
|
580
603
|
### `LineScanner`
|
|
581
604
|
|
|
@@ -591,6 +614,8 @@ fn main() {
|
|
|
591
614
|
|---|---|
|
|
592
615
|
| `IRustBridgeOptions` | Full configuration for `RustBridge` |
|
|
593
616
|
| `IRustBridgeRequestOptions` | Per-command options: `{ signal?, timeoutMs? }` |
|
|
617
|
+
| `IRustBridgeTerminateOptions` | Confirmed termination options: `{ gracePeriodMs? }` |
|
|
618
|
+
| `IRustTransportDisconnectOptions` | Optional confirmed-disconnect grace period for owned process transports |
|
|
594
619
|
| `IBinaryLocatorOptions` | Configuration for `RustBinaryLocator` |
|
|
595
620
|
| `ISocketConnectOptions` | Socket connection options (reconnect settings) |
|
|
596
621
|
| `IRustBridgeLogger` | Logger interface: `{ log(level, message, data?) }` |
|