@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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.rustbridge.d.ts +19 -8
- package/dist_ts/classes.rustbridge.js +307 -78
- package/dist_ts/classes.sockettransport.d.ts +16 -2
- package/dist_ts/classes.sockettransport.js +239 -61
- package/dist_ts/classes.stdiotransport.d.ts +15 -3
- package/dist_ts/classes.stdiotransport.js +268 -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 +35 -5
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.rustbridge.ts +368 -83
- package/ts/classes.sockettransport.ts +312 -60
- package/ts/classes.stdiotransport.ts +362 -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,48 @@ 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
|
+
};
|
|
58
|
+
this.generation = generation;
|
|
59
|
+
this.childProcess = childProcess;
|
|
60
|
+
// Handle stderr with cross-chunk buffering.
|
|
61
|
+
childProcess.stderr?.on('data', (data) => {
|
|
62
|
+
if (this.generation !== generation || generation.closed) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
generation.stderrRemainder += data.toString();
|
|
66
|
+
const lines = generation.stderrRemainder.split('\n');
|
|
67
|
+
generation.stderrRemainder = lines.pop();
|
|
34
68
|
for (const line of lines) {
|
|
35
69
|
const trimmed = line.trim();
|
|
36
70
|
if (trimmed) {
|
|
@@ -38,99 +72,274 @@ export class StdioTransport extends plugins.events.EventEmitter {
|
|
|
38
72
|
}
|
|
39
73
|
}
|
|
40
74
|
});
|
|
41
|
-
// Handle stdout via LineScanner
|
|
42
|
-
|
|
75
|
+
// Handle stdout via LineScanner.
|
|
76
|
+
childProcess.stdout.on('data', (chunk) => {
|
|
77
|
+
if (this.generation !== generation || generation.closed) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
43
80
|
this.lineScanner.push(chunk, (line) => {
|
|
44
|
-
this.
|
|
81
|
+
if (this.generation === generation && !generation.closed) {
|
|
82
|
+
this.emit('line', line);
|
|
83
|
+
}
|
|
45
84
|
});
|
|
46
85
|
});
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
86
|
+
childProcess.on('exit', () => {
|
|
87
|
+
generation.exited = true;
|
|
88
|
+
if (this.generation === generation) {
|
|
89
|
+
this._connected = false;
|
|
90
|
+
}
|
|
91
|
+
// A descendant may inherit the child's stdio descriptors and otherwise
|
|
92
|
+
// keep ChildProcess 'close' from ever firing after the owned child exits.
|
|
93
|
+
// Allow already-queued data events through this poll turn, then close our
|
|
94
|
+
// endpoints so confirmation cannot retain that pipe graph indefinitely.
|
|
95
|
+
setImmediate(() => {
|
|
96
|
+
if (generation.closed) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
this.destroyOwnedStdioEndpoint(generation, 'stdin');
|
|
100
|
+
this.destroyOwnedStdioEndpoint(generation, 'stdout');
|
|
101
|
+
this.destroyOwnedStdioEndpoint(generation, 'stderr');
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
// ChildProcess 'close' is the termination confirmation: the process has exited
|
|
105
|
+
// and its stdio streams have closed.
|
|
106
|
+
childProcess.on('close', (code, signal) => {
|
|
107
|
+
if (generation.closed) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// Flush stderr while this generation is still considered active so a
|
|
111
|
+
// synchronous listener cannot start a replacement child mid-cleanup.
|
|
112
|
+
if (this.generation === generation
|
|
113
|
+
&& generation.stderrRemainder.trim()) {
|
|
114
|
+
this.emit('stderr', generation.stderrRemainder.trim());
|
|
115
|
+
}
|
|
116
|
+
generation.stderrRemainder = '';
|
|
117
|
+
generation.exited = true;
|
|
118
|
+
generation.closed = true;
|
|
119
|
+
if (generation.forceKillTimer) {
|
|
120
|
+
clearTimeout(generation.forceKillTimer);
|
|
121
|
+
generation.forceKillTimer = null;
|
|
122
|
+
}
|
|
123
|
+
generation.resolveClose();
|
|
124
|
+
if (this.generation !== generation) {
|
|
125
|
+
return;
|
|
52
126
|
}
|
|
53
127
|
this._connected = false;
|
|
128
|
+
this.childProcess = null;
|
|
54
129
|
this.lineScanner.clear();
|
|
55
|
-
this.stderrRemainder = '';
|
|
56
130
|
this.emit('close', code, signal);
|
|
57
131
|
});
|
|
58
|
-
|
|
132
|
+
childProcess.on('error', (error) => {
|
|
133
|
+
if (this.generation !== generation || generation.closed) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
59
136
|
this._connected = false;
|
|
60
|
-
|
|
137
|
+
if (generation.sigkillAttempted && generation.rejectDisconnect) {
|
|
138
|
+
generation.rejectDisconnect(this.toError(error, 'Unable to confirm child termination after SIGKILL'));
|
|
139
|
+
}
|
|
140
|
+
if (this.listenerCount('error') > 0) {
|
|
141
|
+
this.emit('error', error);
|
|
142
|
+
}
|
|
143
|
+
else if (generation.disconnectPromise) {
|
|
144
|
+
this.options.logger.log('error', 'Stdio transport error during disconnect: ' + error.message);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
this.emit('error', error);
|
|
148
|
+
}
|
|
61
149
|
});
|
|
62
150
|
this._connected = true;
|
|
151
|
+
return Promise.resolve();
|
|
63
152
|
}
|
|
64
153
|
/**
|
|
65
154
|
* Write data to stdin with backpressure support.
|
|
66
155
|
*/
|
|
67
|
-
|
|
156
|
+
write(data) {
|
|
68
157
|
return new Promise((resolve, reject) => {
|
|
69
|
-
|
|
158
|
+
const generation = this.generation;
|
|
159
|
+
if (!generation
|
|
160
|
+
|| generation.closed
|
|
161
|
+
|| generation.childProcess !== this.childProcess
|
|
162
|
+
|| !this._connected
|
|
163
|
+
|| !generation.childProcess.stdin) {
|
|
70
164
|
reject(new Error('stdin not available'));
|
|
71
165
|
return;
|
|
72
166
|
}
|
|
73
|
-
const canContinue =
|
|
74
|
-
if (
|
|
75
|
-
reject(
|
|
167
|
+
const canContinue = generation.childProcess.stdin.write(data, 'utf8', (error) => {
|
|
168
|
+
if (error) {
|
|
169
|
+
reject(error);
|
|
76
170
|
}
|
|
77
171
|
});
|
|
78
172
|
if (canContinue) {
|
|
79
173
|
resolve();
|
|
80
174
|
}
|
|
81
175
|
else {
|
|
82
|
-
|
|
176
|
+
generation.childProcess.stdin.once('drain', () => {
|
|
83
177
|
resolve();
|
|
84
178
|
});
|
|
85
179
|
}
|
|
86
180
|
});
|
|
87
181
|
}
|
|
88
182
|
/**
|
|
89
|
-
* Kill the child process
|
|
183
|
+
* Kill the child process without waiting for confirmation.
|
|
90
184
|
*/
|
|
91
185
|
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
186
|
try {
|
|
106
|
-
|
|
187
|
+
void this.disconnectAndWait().catch((error) => {
|
|
188
|
+
this.options.logger.log('error', 'Failed to disconnect stdio transport: ' + this.getErrorMessage(error));
|
|
189
|
+
});
|
|
107
190
|
}
|
|
108
|
-
catch {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
191
|
+
catch (error) {
|
|
192
|
+
this.options.logger.log('error', 'Failed to disconnect stdio transport: ' + this.getErrorMessage(error));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Send SIGTERM, escalate to SIGKILL after the grace period, and wait for
|
|
197
|
+
* ChildProcess 'close' to confirm termination.
|
|
198
|
+
*/
|
|
199
|
+
disconnectAndWait(options = {}) {
|
|
200
|
+
const gracePeriodMs = options.gracePeriodMs ?? DEFAULT_DISCONNECT_GRACE_PERIOD_MS;
|
|
201
|
+
if (!Number.isSafeInteger(gracePeriodMs) || gracePeriodMs < 0) {
|
|
202
|
+
throw new RangeError('StdioTransport gracePeriodMs must be a non-negative safe integer');
|
|
203
|
+
}
|
|
204
|
+
const generation = this.generation;
|
|
205
|
+
if (!generation) {
|
|
206
|
+
return Promise.resolve();
|
|
112
207
|
}
|
|
113
|
-
|
|
208
|
+
if (generation.disconnectPromise) {
|
|
209
|
+
return generation.disconnectPromise;
|
|
210
|
+
}
|
|
211
|
+
if (generation.closed) {
|
|
212
|
+
generation.disconnectPromise = generation.closePromise;
|
|
213
|
+
return generation.disconnectPromise;
|
|
214
|
+
}
|
|
215
|
+
let rejectDisconnect;
|
|
216
|
+
const disconnectPromise = new Promise((resolve, reject) => {
|
|
217
|
+
rejectDisconnect = reject;
|
|
218
|
+
void generation.closePromise.then(resolve);
|
|
219
|
+
});
|
|
220
|
+
generation.disconnectPromise = disconnectPromise;
|
|
221
|
+
generation.rejectDisconnect = rejectDisconnect;
|
|
222
|
+
this._connected = false;
|
|
223
|
+
void disconnectPromise.then(() => {
|
|
224
|
+
if (generation.disconnectPromise === disconnectPromise) {
|
|
225
|
+
generation.rejectDisconnect = null;
|
|
226
|
+
}
|
|
227
|
+
}, () => {
|
|
228
|
+
if (generation.disconnectPromise !== disconnectPromise) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (generation.forceKillTimer) {
|
|
232
|
+
clearTimeout(generation.forceKillTimer);
|
|
233
|
+
generation.forceKillTimer = null;
|
|
234
|
+
}
|
|
235
|
+
generation.disconnectPromise = null;
|
|
236
|
+
generation.rejectDisconnect = null;
|
|
237
|
+
generation.sigtermAttempted = false;
|
|
238
|
+
generation.sigkillAttempted = false;
|
|
239
|
+
generation.sigtermError = null;
|
|
240
|
+
});
|
|
241
|
+
if (this.hasExited(generation)) {
|
|
242
|
+
this.destroyOwnedStdioEndpoint(generation, 'stdin');
|
|
243
|
+
this.destroyOwnedStdioEndpoint(generation, 'stdout');
|
|
244
|
+
this.destroyOwnedStdioEndpoint(generation, 'stderr');
|
|
245
|
+
return disconnectPromise;
|
|
246
|
+
}
|
|
247
|
+
generation.sigtermAttempted = true;
|
|
248
|
+
generation.sigtermError = this.sendSignal(generation, 'SIGTERM');
|
|
249
|
+
if (generation.closed || this.hasExited(generation)) {
|
|
250
|
+
return disconnectPromise;
|
|
251
|
+
}
|
|
252
|
+
if (gracePeriodMs === 0) {
|
|
253
|
+
this.forceKill(generation);
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
this.scheduleForceKill(generation, gracePeriodMs);
|
|
257
|
+
}
|
|
258
|
+
return disconnectPromise;
|
|
259
|
+
}
|
|
260
|
+
scheduleForceKill(generation, remainingMs) {
|
|
261
|
+
if (generation.closed || this.hasExited(generation)) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const delayMs = Math.min(remainingMs, MAX_TIMER_DELAY_MS);
|
|
265
|
+
const scheduledAt = Date.now();
|
|
114
266
|
try {
|
|
115
|
-
|
|
267
|
+
generation.forceKillTimer = setTimeout(() => {
|
|
268
|
+
generation.forceKillTimer = null;
|
|
269
|
+
if (generation.closed || this.hasExited(generation)) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const elapsedMs = Math.max(1, Date.now() - scheduledAt);
|
|
273
|
+
const nextRemainingMs = remainingMs - elapsedMs;
|
|
274
|
+
if (nextRemainingMs > 0) {
|
|
275
|
+
this.scheduleForceKill(generation, nextRemainingMs);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
this.forceKill(generation);
|
|
279
|
+
}
|
|
280
|
+
}, delayMs);
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
generation.rejectDisconnect?.(this.toError(error, 'Unable to schedule SIGKILL escalation'));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
forceKill(generation) {
|
|
287
|
+
if (generation.closed
|
|
288
|
+
|| generation.sigkillAttempted
|
|
289
|
+
|| this.hasExited(generation)) {
|
|
290
|
+
return;
|
|
116
291
|
}
|
|
117
|
-
|
|
292
|
+
generation.sigkillAttempted = true;
|
|
293
|
+
const sigkillError = this.sendSignal(generation, 'SIGKILL');
|
|
294
|
+
if (sigkillError && !generation.closed && !this.hasExited(generation)) {
|
|
295
|
+
const sigtermDetail = generation.sigtermError
|
|
296
|
+
? ' SIGTERM also failed: ' + generation.sigtermError.message + '.'
|
|
297
|
+
: '';
|
|
298
|
+
generation.rejectDisconnect?.(new Error(sigkillError.message + '.' + sigtermDetail));
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
sendSignal(generation, signal) {
|
|
118
302
|
try {
|
|
119
|
-
|
|
303
|
+
const delivered = generation.childProcess.kill(signal);
|
|
304
|
+
if (delivered || generation.closed || this.hasExited(generation)) {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
return new Error('Failed to send ' + signal + ' to child process');
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
if (generation.closed || this.hasExited(generation)) {
|
|
311
|
+
return null;
|
|
312
|
+
}
|
|
313
|
+
return this.toError(error, 'Failed to send ' + signal + ' to child process');
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
hasExited(generation) {
|
|
317
|
+
return (generation.exited
|
|
318
|
+
|| generation.childProcess.exitCode !== null
|
|
319
|
+
|| generation.childProcess.signalCode !== null);
|
|
320
|
+
}
|
|
321
|
+
destroyOwnedStdioEndpoint(generation, endpointName) {
|
|
322
|
+
const endpoint = generation.childProcess[endpointName];
|
|
323
|
+
if (!endpoint || endpoint.destroyed) {
|
|
324
|
+
return;
|
|
120
325
|
}
|
|
121
|
-
catch { /* ignore */ }
|
|
122
|
-
// Unref so Node doesn't wait
|
|
123
326
|
try {
|
|
124
|
-
|
|
327
|
+
endpoint.destroy();
|
|
125
328
|
}
|
|
126
|
-
catch {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
329
|
+
catch (error) {
|
|
330
|
+
const endpointError = this.toError(error, 'Failed to close inherited child ' + endpointName);
|
|
331
|
+
generation.rejectDisconnect?.(endpointError);
|
|
332
|
+
this.options.logger.log('error', endpointError.message);
|
|
333
|
+
if (this.listenerCount('error') > 0) {
|
|
334
|
+
this.emit('error', endpointError);
|
|
131
335
|
}
|
|
132
|
-
|
|
133
|
-
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
toError(error, prefix) {
|
|
339
|
+
return new Error(prefix + ': ' + this.getErrorMessage(error));
|
|
340
|
+
}
|
|
341
|
+
getErrorMessage(error) {
|
|
342
|
+
return error instanceof Error ? error.message : String(error);
|
|
134
343
|
}
|
|
135
344
|
}
|
|
136
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zdGRpb3RyYW5zcG9ydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuc3RkaW90cmFuc3BvcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBWXZEOzs7R0FHRztBQUNILE1BQU0sT0FBTyxjQUFlLFNBQVEsT0FBTyxDQUFDLE1BQU0sQ0FBQyxZQUFZO0lBQ3JELE9BQU8sQ0FBeUI7SUFDaEMsWUFBWSxHQUE2QyxJQUFJLENBQUM7SUFDOUQsV0FBVyxDQUFjO0lBQ3pCLGVBQWUsR0FBVyxFQUFFLENBQUM7SUFDN0IsVUFBVSxHQUFZLEtBQUssQ0FBQztJQUVwQyxZQUFZLE9BQStCO1FBQ3pDLEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLFdBQVcsQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUM3RSxDQUFDO0lBRUQsSUFBVyxTQUFTO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsT0FBTztRQUNsQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUc7WUFDMUIsQ0FBQyxDQUFDLEVBQUUsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDekMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFdkIsSUFBSSxDQUFDLFlBQVksR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FDNUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxV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
|
|
345
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5zdGRpb3RyYW5zcG9ydC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuc3RkaW90cmFuc3BvcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBT3ZELE1BQU0sa0NBQWtDLEdBQUcsSUFBSSxDQUFDO0FBQ2hELE1BQU0sa0JBQWtCLEdBQUcsYUFBYSxDQUFDO0FBeUJ6Qzs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sY0FBZSxTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtJQUNyRCxPQUFPLENBQXlCO0lBQ2hDLFlBQVksR0FBNkMsSUFBSSxDQUFDO0lBQzlELFVBQVUsR0FBcUMsSUFBSSxDQUFDO0lBQ3BELFdBQVcsQ0FBYztJQUN6QixVQUFVLEdBQVksS0FBSyxDQUFDO0lBRXBDLFlBQVksT0FBK0I7UUFDekMsS0FBSyxFQUFFLENBQUM7UUFDUixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztRQUN2QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksV0FBVyxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzdFLENBQUM7SUFFRCxJQUFXLFNBQVM7UUFDbEIsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQ3pCLENBQUM7SUFFRDs7T0FFRztJQUNJLE9BQU87UUFDWixJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQy9DLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FDbkIsSUFBSSxLQUFLLENBQUMsb0VBQW9FLENBQUMsQ0FDaEYsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUc7WUFD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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,30 @@ 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
|
+
|
|
176
|
+
If termination rejects, the bridge retains the transport and remains in its
|
|
177
|
+
stopping state because closure was not confirmed. A later `terminate()` call
|
|
178
|
+
starts a fresh cleanup attempt; activation remains unavailable until one of
|
|
179
|
+
those attempts confirms closure.
|
|
180
|
+
|
|
157
181
|
### Socket Mode — Connect to a Running Daemon 🔗
|
|
158
182
|
|
|
159
183
|
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 +198,8 @@ if (!ok) {
|
|
|
174
198
|
const { pid } = await bridge.sendCommand('start', { port: 8080, host: '0.0.0.0' });
|
|
175
199
|
const metrics = await bridge.sendCommand('getMetrics', {});
|
|
176
200
|
|
|
177
|
-
//
|
|
178
|
-
bridge.
|
|
201
|
+
// terminate() confirms local socket closure — it does NOT kill the daemon
|
|
202
|
+
await bridge.terminate();
|
|
179
203
|
```
|
|
180
204
|
|
|
181
205
|
#### Auto-Reconnect
|
|
@@ -539,7 +563,8 @@ fn main() {
|
|
|
539
563
|
| `connect(socketPath, options?)` | `Promise<boolean>` | **Socket mode**: Connect to a running daemon; returns `false` on failure |
|
|
540
564
|
| `sendCommand(method, params, options?)` | `Promise<TCommands[K]['result']>` | Send a typed command with an optional per-call timeout or abort signal |
|
|
541
565
|
| `sendCommandStreaming(method, params)` | `StreamingResponse<TChunk, TResult>` | Send a streaming command; returns immediately |
|
|
542
|
-
| `
|
|
566
|
+
| `terminate(options?)` | `Promise<void>` | Confirm stdio child exit or local socket closure; `gracePeriodMs` controls SIGKILL escalation |
|
|
567
|
+
| `kill()` | `void` | Fire-and-forget compatibility wrapper around `terminate()` |
|
|
543
568
|
| `running` | `boolean` | Whether the bridge is currently connected and ready |
|
|
544
569
|
|
|
545
570
|
### `StreamingResponse<TChunk, TResult>`
|
|
@@ -565,6 +590,7 @@ fn main() {
|
|
|
565
590
|
| `connect()` | `Promise<void>` | Spawn the child process |
|
|
566
591
|
| `write(data)` | `Promise<void>` | Write to stdin with backpressure handling |
|
|
567
592
|
| `disconnect()` | `void` | Kill the process (SIGTERM → SIGKILL after 5s) |
|
|
593
|
+
| `disconnectAndWait(options?)` | `Promise<void>` | Confirm child close after SIGTERM/SIGKILL escalation |
|
|
568
594
|
| `connected` | `boolean` | Whether the process is running |
|
|
569
595
|
|
|
570
596
|
### `SocketTransport`
|
|
@@ -575,7 +601,9 @@ fn main() {
|
|
|
575
601
|
| `connect()` | `Promise<void>` | Connect to the Unix socket / named pipe |
|
|
576
602
|
| `write(data)` | `Promise<void>` | Write to socket with backpressure handling |
|
|
577
603
|
| `disconnect()` | `void` | Close the socket (does not kill the daemon) |
|
|
604
|
+
| `disconnectAndWait()` | `Promise<void>` | Confirm local socket closure without signaling the daemon |
|
|
578
605
|
| `connected` | `boolean` | Whether the socket is connected |
|
|
606
|
+
| `reconnecting` | `boolean` | Whether an automatic reconnect timer or attempt owns the socket lifecycle |
|
|
579
607
|
|
|
580
608
|
### `LineScanner`
|
|
581
609
|
|
|
@@ -591,6 +619,8 @@ fn main() {
|
|
|
591
619
|
|---|---|
|
|
592
620
|
| `IRustBridgeOptions` | Full configuration for `RustBridge` |
|
|
593
621
|
| `IRustBridgeRequestOptions` | Per-command options: `{ signal?, timeoutMs? }` |
|
|
622
|
+
| `IRustBridgeTerminateOptions` | Confirmed termination options: `{ gracePeriodMs? }` |
|
|
623
|
+
| `IRustTransportDisconnectOptions` | Optional confirmed-disconnect grace period for owned process transports |
|
|
594
624
|
| `IBinaryLocatorOptions` | Configuration for `RustBinaryLocator` |
|
|
595
625
|
| `ISocketConnectOptions` | Socket connection options (reconnect settings) |
|
|
596
626
|
| `IRustBridgeLogger` | Logger interface: `{ log(level, message, data?) }` |
|