@push.rocks/smartrust 1.2.1 → 1.3.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/changelog.md +11 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.linescanner.d.ts +18 -0
- package/dist_ts/classes.linescanner.js +43 -0
- package/dist_ts/classes.rustbridge.d.ts +19 -16
- package/dist_ts/classes.rustbridge.js +86 -152
- package/dist_ts/classes.sockettransport.d.ts +48 -0
- package/dist_ts/classes.sockettransport.js +138 -0
- package/dist_ts/classes.stdiotransport.d.ts +35 -0
- package/dist_ts/classes.stdiotransport.js +136 -0
- package/dist_ts/index.d.ts +3 -0
- package/dist_ts/index.js +4 -1
- package/dist_ts/interfaces/config.d.ts +13 -0
- package/dist_ts/interfaces/index.d.ts +1 -0
- package/dist_ts/interfaces/index.js +2 -1
- package/dist_ts/interfaces/transport.d.ts +22 -0
- package/dist_ts/interfaces/transport.js +2 -0
- package/dist_ts/plugins.d.ts +2 -1
- package/dist_ts/plugins.js +3 -2
- package/package.json +1 -1
- package/test/helpers/mock-socket-server.mjs +124 -0
- package/test/test.linescanner.node.ts +89 -0
- package/test/test.sockettransport.node.ts +312 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.linescanner.ts +51 -0
- package/ts/classes.rustbridge.ts +93 -147
- package/ts/classes.sockettransport.ts +187 -0
- package/ts/classes.stdiotransport.ts +149 -0
- package/ts/index.ts +3 -0
- package/ts/interfaces/config.ts +14 -0
- package/ts/interfaces/index.ts +1 -0
- package/ts/interfaces/transport.ts +26 -0
- package/ts/plugins.ts +2 -1
package/changelog.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-02-26 - 1.3.0 - feat(transport)
|
|
4
|
+
introduce transport abstraction and socket-mode support for RustBridge
|
|
5
|
+
|
|
6
|
+
- Add IRustTransport interface and two transport implementations: StdioTransport (spawns child process and uses stdin/stdout) and SocketTransport (connects to Unix socket / Windows named pipe).
|
|
7
|
+
- Refactor RustBridge to use a transport abstraction (connectWithTransport) and add connect(socketPath) to attach to an existing daemon via socket.
|
|
8
|
+
- Introduce LineScanner: a buffer-based newline scanner used by both transports to handle large/newline-delimited messages and avoid OOMs.
|
|
9
|
+
- Add socket connection options (autoReconnect, reconnectBaseDelayMs, reconnectMaxDelayMs, maxReconnectAttempts) and implement auto-reconnect/backoff behavior in SocketTransport.
|
|
10
|
+
- Implement backpressure-aware write semantics and proper disconnect/cleanup for both transports; RustBridge.kill() now disconnects the transport instead of directly managing processes.
|
|
11
|
+
- Add tests and tooling: socket transport tests, line scanner tests, and a mock-socket-server.mjs helper script for testing socket mode.
|
|
12
|
+
- Export new symbols (StdioTransport, SocketTransport, LineScanner) and update plugins to expose net; update interfaces to export transport types.
|
|
13
|
+
|
|
3
14
|
## 2026-02-12 - 1.2.1 - fix(rust-binary-locator)
|
|
4
15
|
auto-fix missing execute permission for located Rust binaries
|
|
5
16
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@push.rocks/smartrust',
|
|
6
|
-
version: '1.
|
|
6
|
+
version: '1.3.0',
|
|
7
7
|
description: 'a bridge between JS engines and rust'
|
|
8
8
|
};
|
|
9
9
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx1QkFBdUI7SUFDN0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHNDQUFzQztDQUNwRCxDQUFBIn0=
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IRustBridgeLogger } from './interfaces/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Buffer-based newline scanner for streaming binary data.
|
|
4
|
+
* Accumulates chunks and emits complete lines via callback.
|
|
5
|
+
* Used by both StdioTransport and SocketTransport.
|
|
6
|
+
*/
|
|
7
|
+
export declare class LineScanner {
|
|
8
|
+
private buffer;
|
|
9
|
+
private maxPayloadSize;
|
|
10
|
+
private logger;
|
|
11
|
+
constructor(maxPayloadSize: number, logger: IRustBridgeLogger);
|
|
12
|
+
/**
|
|
13
|
+
* Feed a chunk of data. Calls onLine for each complete newline-terminated line found.
|
|
14
|
+
*/
|
|
15
|
+
push(chunk: Buffer, onLine: (line: string) => void): void;
|
|
16
|
+
/** Reset the internal buffer. */
|
|
17
|
+
clear(): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Buffer-based newline scanner for streaming binary data.
|
|
3
|
+
* Accumulates chunks and emits complete lines via callback.
|
|
4
|
+
* Used by both StdioTransport and SocketTransport.
|
|
5
|
+
*/
|
|
6
|
+
export class LineScanner {
|
|
7
|
+
buffer = Buffer.alloc(0);
|
|
8
|
+
maxPayloadSize;
|
|
9
|
+
logger;
|
|
10
|
+
constructor(maxPayloadSize, logger) {
|
|
11
|
+
this.maxPayloadSize = maxPayloadSize;
|
|
12
|
+
this.logger = logger;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Feed a chunk of data. Calls onLine for each complete newline-terminated line found.
|
|
16
|
+
*/
|
|
17
|
+
push(chunk, onLine) {
|
|
18
|
+
this.buffer = Buffer.concat([this.buffer, chunk]);
|
|
19
|
+
let newlineIndex;
|
|
20
|
+
while ((newlineIndex = this.buffer.indexOf(0x0A)) !== -1) {
|
|
21
|
+
const lineBuffer = this.buffer.subarray(0, newlineIndex);
|
|
22
|
+
this.buffer = this.buffer.subarray(newlineIndex + 1);
|
|
23
|
+
if (lineBuffer.length > this.maxPayloadSize) {
|
|
24
|
+
this.logger.log('error', `Inbound message exceeds maxPayloadSize (${lineBuffer.length} bytes), dropping`);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
const line = lineBuffer.toString('utf8').trim();
|
|
28
|
+
if (line) {
|
|
29
|
+
onLine(line);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Prevent OOM if sender never sends newline
|
|
33
|
+
if (this.buffer.length > this.maxPayloadSize) {
|
|
34
|
+
this.logger.log('error', `Buffer exceeded maxPayloadSize (${this.buffer.length} bytes) without newline, clearing`);
|
|
35
|
+
this.buffer = Buffer.alloc(0);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** Reset the internal buffer. */
|
|
39
|
+
clear() {
|
|
40
|
+
this.buffer = Buffer.alloc(0);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5saW5lc2Nhbm5lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMubGluZXNjYW5uZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUE7Ozs7R0FJRztBQUNILE1BQU0sT0FBTyxXQUFXO0lBQ2QsTUFBTSxHQUFXLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakMsY0FBYyxDQUFTO0lBQ3ZCLE1BQU0sQ0FBb0I7SUFFbEMsWUFBWSxjQUFzQixFQUFFLE1BQXlCO1FBQzNELElBQUksQ0FBQyxjQUFjLEdBQUcsY0FBYyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNJLElBQUksQ0FBQyxLQUFhLEVBQUUsTUFBOEI7UUFDdkQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBRWxELElBQUksWUFBb0IsQ0FBQztRQUN6QixPQUFPLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUN6RCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFDekQsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFFckQsSUFBSSxVQUFVLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDNUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLDJDQUEyQyxVQUFVLENBQUMsTUFBTSxtQkFBbUIsQ0FBQyxDQUFDO2dCQUMxRyxTQUFTO1lBQ1gsQ0FBQztZQUVELE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDaEQsSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDVCxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDZixDQUFDO1FBQ0gsQ0FBQztRQUVELDRDQUE0QztRQUM1QyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUM3QyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsbUNBQW1DLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxtQ0FBbUMsQ0FBQyxDQUFDO1lBQ25ILElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoQyxDQUFDO0lBQ0gsQ0FBQztJQUVELGlDQUFpQztJQUMxQixLQUFLO1FBQ1YsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7Q0FDRiJ9
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import { StreamingResponse } from './classes.streamingresponse.js';
|
|
3
|
-
import type { IRustBridgeOptions, TCommandMap, TStreamingCommandKeys, TExtractChunk } from './interfaces/index.js';
|
|
3
|
+
import type { IRustBridgeOptions, ISocketConnectOptions, TCommandMap, TStreamingCommandKeys, TExtractChunk } from './interfaces/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Generic bridge between TypeScript and a Rust binary.
|
|
6
|
-
* Communicates via JSON-over-stdin/stdout IPC protocol
|
|
6
|
+
* Communicates via JSON-over-stdin/stdout IPC protocol (stdio mode)
|
|
7
|
+
* or JSON-over-Unix-socket/named-pipe (socket mode).
|
|
7
8
|
*
|
|
8
9
|
* @typeParam TCommands - Map of command names to their param/result types
|
|
9
10
|
*/
|
|
@@ -11,9 +12,7 @@ export declare class RustBridge<TCommands extends TCommandMap = TCommandMap> ext
|
|
|
11
12
|
private locator;
|
|
12
13
|
private options;
|
|
13
14
|
private logger;
|
|
14
|
-
private
|
|
15
|
-
private stdoutBuffer;
|
|
16
|
-
private stderrRemainder;
|
|
15
|
+
private transport;
|
|
17
16
|
private pendingRequests;
|
|
18
17
|
private requestCounter;
|
|
19
18
|
private isRunning;
|
|
@@ -24,6 +23,18 @@ export declare class RustBridge<TCommands extends TCommandMap = TCommandMap> ext
|
|
|
24
23
|
* Returns true if the binary was found and spawned successfully.
|
|
25
24
|
*/
|
|
26
25
|
spawn(): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Connect to an already-running Rust daemon via Unix socket or named pipe.
|
|
28
|
+
* Returns true if the connection was established and the daemon signaled readiness.
|
|
29
|
+
*
|
|
30
|
+
* @param socketPath - Path to Unix socket or Windows named pipe
|
|
31
|
+
* @param socketOptions - Optional socket connection options (reconnect, etc.)
|
|
32
|
+
*/
|
|
33
|
+
connect(socketPath: string, socketOptions?: ISocketConnectOptions): Promise<boolean>;
|
|
34
|
+
/**
|
|
35
|
+
* Internal: wire up any transport and wait for the ready handshake.
|
|
36
|
+
*/
|
|
37
|
+
private connectWithTransport;
|
|
27
38
|
/**
|
|
28
39
|
* Send a typed command to the Rust process and wait for the response.
|
|
29
40
|
*/
|
|
@@ -35,23 +46,15 @@ export declare class RustBridge<TCommands extends TCommandMap = TCommandMap> ext
|
|
|
35
46
|
*/
|
|
36
47
|
sendCommandStreaming<K extends string & TStreamingCommandKeys<TCommands>>(method: K, params: TCommands[K]['params']): StreamingResponse<TExtractChunk<TCommands[K]>, TCommands[K]['result']>;
|
|
37
48
|
/**
|
|
38
|
-
* Kill the
|
|
49
|
+
* Kill the connection and clean up all resources.
|
|
50
|
+
* For stdio: kills the child process (SIGTERM, then SIGKILL).
|
|
51
|
+
* For socket: closes the socket connection (does NOT kill the daemon).
|
|
39
52
|
*/
|
|
40
53
|
kill(): void;
|
|
41
54
|
/**
|
|
42
55
|
* Whether the bridge is currently running.
|
|
43
56
|
*/
|
|
44
57
|
get running(): boolean;
|
|
45
|
-
/**
|
|
46
|
-
* Buffer-based newline scanner for stdout chunks.
|
|
47
|
-
* Replaces readline to handle large payloads without buffering entire lines in a separate abstraction.
|
|
48
|
-
*/
|
|
49
|
-
private handleStdoutChunk;
|
|
50
|
-
/**
|
|
51
|
-
* Write data to stdin with backpressure support.
|
|
52
|
-
* Waits for drain if the internal buffer is full.
|
|
53
|
-
*/
|
|
54
|
-
private writeToStdin;
|
|
55
58
|
private handleLine;
|
|
56
59
|
private cleanup;
|
|
57
60
|
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import { RustBinaryLocator } from './classes.rustbinarylocator.js';
|
|
3
3
|
import { StreamingResponse } from './classes.streamingresponse.js';
|
|
4
|
+
import { StdioTransport } from './classes.stdiotransport.js';
|
|
5
|
+
import { SocketTransport } from './classes.sockettransport.js';
|
|
4
6
|
const defaultLogger = {
|
|
5
7
|
log() { },
|
|
6
8
|
};
|
|
7
9
|
/**
|
|
8
10
|
* Generic bridge between TypeScript and a Rust binary.
|
|
9
|
-
* Communicates via JSON-over-stdin/stdout IPC protocol
|
|
11
|
+
* Communicates via JSON-over-stdin/stdout IPC protocol (stdio mode)
|
|
12
|
+
* or JSON-over-Unix-socket/named-pipe (socket mode).
|
|
10
13
|
*
|
|
11
14
|
* @typeParam TCommands - Map of command names to their param/result types
|
|
12
15
|
*/
|
|
@@ -14,9 +17,7 @@ export class RustBridge extends plugins.events.EventEmitter {
|
|
|
14
17
|
locator;
|
|
15
18
|
options;
|
|
16
19
|
logger;
|
|
17
|
-
|
|
18
|
-
stdoutBuffer = Buffer.alloc(0);
|
|
19
|
-
stderrRemainder = '';
|
|
20
|
+
transport = null;
|
|
20
21
|
pendingRequests = new Map();
|
|
21
22
|
requestCounter = 0;
|
|
22
23
|
isRunning = false;
|
|
@@ -43,65 +44,83 @@ export class RustBridge extends plugins.events.EventEmitter {
|
|
|
43
44
|
if (!this.binaryPath) {
|
|
44
45
|
return false;
|
|
45
46
|
}
|
|
47
|
+
const transport = new StdioTransport({
|
|
48
|
+
binaryPath: this.binaryPath,
|
|
49
|
+
cliArgs: this.options.cliArgs,
|
|
50
|
+
env: this.options.env,
|
|
51
|
+
maxPayloadSize: this.options.maxPayloadSize,
|
|
52
|
+
logger: this.logger,
|
|
53
|
+
});
|
|
54
|
+
return this.connectWithTransport(transport);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Connect to an already-running Rust daemon via Unix socket or named pipe.
|
|
58
|
+
* Returns true if the connection was established and the daemon signaled readiness.
|
|
59
|
+
*
|
|
60
|
+
* @param socketPath - Path to Unix socket or Windows named pipe
|
|
61
|
+
* @param socketOptions - Optional socket connection options (reconnect, etc.)
|
|
62
|
+
*/
|
|
63
|
+
async connect(socketPath, socketOptions) {
|
|
64
|
+
const transport = new SocketTransport({
|
|
65
|
+
socketPath,
|
|
66
|
+
maxPayloadSize: this.options.maxPayloadSize,
|
|
67
|
+
logger: this.logger,
|
|
68
|
+
autoReconnect: socketOptions?.autoReconnect,
|
|
69
|
+
reconnectBaseDelayMs: socketOptions?.reconnectBaseDelayMs,
|
|
70
|
+
reconnectMaxDelayMs: socketOptions?.reconnectMaxDelayMs,
|
|
71
|
+
maxReconnectAttempts: socketOptions?.maxReconnectAttempts,
|
|
72
|
+
});
|
|
73
|
+
return this.connectWithTransport(transport);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Internal: wire up any transport and wait for the ready handshake.
|
|
77
|
+
*/
|
|
78
|
+
connectWithTransport(transport) {
|
|
46
79
|
return new Promise((resolve) => {
|
|
47
80
|
try {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
});
|
|
55
|
-
// Handle stderr with cross-chunk buffering
|
|
56
|
-
this.childProcess.stderr?.on('data', (data) => {
|
|
57
|
-
this.stderrRemainder += data.toString();
|
|
58
|
-
const lines = this.stderrRemainder.split('\n');
|
|
59
|
-
// Keep the last element (incomplete line) as remainder
|
|
60
|
-
this.stderrRemainder = lines.pop();
|
|
61
|
-
for (const line of lines) {
|
|
62
|
-
const trimmed = line.trim();
|
|
63
|
-
if (trimmed) {
|
|
64
|
-
this.logger.log('debug', `[${this.options.binaryName}] ${trimmed}`);
|
|
65
|
-
this.emit('stderr', trimmed);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
// Handle stdout via Buffer-based newline scanner
|
|
70
|
-
this.childProcess.stdout.on('data', (chunk) => {
|
|
71
|
-
this.handleStdoutChunk(chunk);
|
|
81
|
+
this.transport = transport;
|
|
82
|
+
// Wire transport events
|
|
83
|
+
transport.on('line', (line) => this.handleLine(line));
|
|
84
|
+
transport.on('stderr', (line) => {
|
|
85
|
+
this.logger.log('debug', `[${this.options.binaryName}] ${line}`);
|
|
86
|
+
this.emit('stderr', line);
|
|
72
87
|
});
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this.logger.log('info', `Process exited (code=${code}, signal=${signal})`);
|
|
76
|
-
// Flush any remaining stderr
|
|
77
|
-
if (this.stderrRemainder.trim()) {
|
|
78
|
-
this.logger.log('debug', `[${this.options.binaryName}] ${this.stderrRemainder.trim()}`);
|
|
79
|
-
this.emit('stderr', this.stderrRemainder.trim());
|
|
80
|
-
}
|
|
88
|
+
transport.on('close', (...args) => {
|
|
89
|
+
this.logger.log('info', `Transport closed`);
|
|
81
90
|
this.cleanup();
|
|
82
|
-
this.emit('exit',
|
|
91
|
+
this.emit('exit', ...args);
|
|
83
92
|
});
|
|
84
|
-
|
|
85
|
-
this.logger.log('error', `
|
|
93
|
+
transport.on('error', (err) => {
|
|
94
|
+
this.logger.log('error', `Transport error: ${err.message}`);
|
|
86
95
|
this.cleanup();
|
|
87
96
|
resolve(false);
|
|
88
97
|
});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
this.
|
|
92
|
-
|
|
98
|
+
transport.on('reconnected', () => {
|
|
99
|
+
this.logger.log('info', 'Transport reconnected, waiting for ready event');
|
|
100
|
+
this.emit('reconnected');
|
|
101
|
+
});
|
|
102
|
+
// Connect the transport
|
|
103
|
+
transport.connect().then(() => {
|
|
104
|
+
// Wait for the ready event from the protocol layer
|
|
105
|
+
const readyTimeout = setTimeout(() => {
|
|
106
|
+
this.logger.log('error', `Process did not send ready event within ${this.options.readyTimeoutMs}ms`);
|
|
107
|
+
this.kill();
|
|
108
|
+
resolve(false);
|
|
109
|
+
}, this.options.readyTimeoutMs);
|
|
110
|
+
this.once(`management:${this.options.readyEventName}`, () => {
|
|
111
|
+
clearTimeout(readyTimeout);
|
|
112
|
+
this.isRunning = true;
|
|
113
|
+
this.logger.log('info', `Bridge connected to ${this.options.binaryName}`);
|
|
114
|
+
this.emit('ready');
|
|
115
|
+
resolve(true);
|
|
116
|
+
});
|
|
117
|
+
}).catch((err) => {
|
|
118
|
+
this.logger.log('error', `Transport connect failed: ${err.message}`);
|
|
93
119
|
resolve(false);
|
|
94
|
-
}, this.options.readyTimeoutMs);
|
|
95
|
-
this.once(`management:${this.options.readyEventName}`, () => {
|
|
96
|
-
clearTimeout(readyTimeout);
|
|
97
|
-
this.isRunning = true;
|
|
98
|
-
this.logger.log('info', `Bridge connected to ${this.options.binaryName}`);
|
|
99
|
-
this.emit('ready');
|
|
100
|
-
resolve(true);
|
|
101
120
|
});
|
|
102
121
|
}
|
|
103
122
|
catch (err) {
|
|
104
|
-
this.logger.log('error', `Failed to
|
|
123
|
+
this.logger.log('error', `Failed to connect: ${err.message}`);
|
|
105
124
|
resolve(false);
|
|
106
125
|
}
|
|
107
126
|
});
|
|
@@ -110,7 +129,7 @@ export class RustBridge extends plugins.events.EventEmitter {
|
|
|
110
129
|
* Send a typed command to the Rust process and wait for the response.
|
|
111
130
|
*/
|
|
112
131
|
async sendCommand(method, params) {
|
|
113
|
-
if (!this.
|
|
132
|
+
if (!this.transport?.connected || !this.isRunning) {
|
|
114
133
|
throw new Error(`${this.options.binaryName} bridge is not running`);
|
|
115
134
|
}
|
|
116
135
|
const id = `req_${++this.requestCounter}`;
|
|
@@ -127,10 +146,10 @@ export class RustBridge extends plugins.events.EventEmitter {
|
|
|
127
146
|
reject(new Error(`Command '${method}' timed out after ${this.options.requestTimeoutMs}ms`));
|
|
128
147
|
}, this.options.requestTimeoutMs);
|
|
129
148
|
this.pendingRequests.set(id, { resolve, reject, timer });
|
|
130
|
-
this.
|
|
149
|
+
this.transport.write(json + '\n').catch((err) => {
|
|
131
150
|
clearTimeout(timer);
|
|
132
151
|
this.pendingRequests.delete(id);
|
|
133
|
-
reject(new Error(`Failed to write to
|
|
152
|
+
reject(new Error(`Failed to write to transport: ${err.message}`));
|
|
134
153
|
});
|
|
135
154
|
});
|
|
136
155
|
}
|
|
@@ -141,7 +160,7 @@ export class RustBridge extends plugins.events.EventEmitter {
|
|
|
141
160
|
*/
|
|
142
161
|
sendCommandStreaming(method, params) {
|
|
143
162
|
const streaming = new StreamingResponse();
|
|
144
|
-
if (!this.
|
|
163
|
+
if (!this.transport?.connected || !this.isRunning) {
|
|
145
164
|
streaming.fail(new Error(`${this.options.binaryName} bridge is not running`));
|
|
146
165
|
return streaming;
|
|
147
166
|
}
|
|
@@ -164,65 +183,31 @@ export class RustBridge extends plugins.events.EventEmitter {
|
|
|
164
183
|
timer,
|
|
165
184
|
streaming,
|
|
166
185
|
});
|
|
167
|
-
this.
|
|
186
|
+
this.transport.write(json + '\n').catch((err) => {
|
|
168
187
|
clearTimeout(timer);
|
|
169
188
|
this.pendingRequests.delete(id);
|
|
170
|
-
streaming.fail(new Error(`Failed to write to
|
|
189
|
+
streaming.fail(new Error(`Failed to write to transport: ${err.message}`));
|
|
171
190
|
});
|
|
172
191
|
return streaming;
|
|
173
192
|
}
|
|
174
193
|
/**
|
|
175
|
-
* Kill the
|
|
194
|
+
* Kill the connection and clean up all resources.
|
|
195
|
+
* For stdio: kills the child process (SIGTERM, then SIGKILL).
|
|
196
|
+
* For socket: closes the socket connection (does NOT kill the daemon).
|
|
176
197
|
*/
|
|
177
198
|
kill() {
|
|
178
|
-
if (this.
|
|
179
|
-
const
|
|
180
|
-
this.
|
|
199
|
+
if (this.transport) {
|
|
200
|
+
const transport = this.transport;
|
|
201
|
+
this.transport = null;
|
|
181
202
|
this.isRunning = false;
|
|
182
|
-
// Clear buffers
|
|
183
|
-
this.stdoutBuffer = Buffer.alloc(0);
|
|
184
|
-
this.stderrRemainder = '';
|
|
185
203
|
// Reject pending requests
|
|
186
204
|
for (const [, pending] of this.pendingRequests) {
|
|
187
205
|
clearTimeout(pending.timer);
|
|
188
206
|
pending.reject(new Error(`${this.options.binaryName} process killed`));
|
|
189
207
|
}
|
|
190
208
|
this.pendingRequests.clear();
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
proc.stdout?.removeAllListeners();
|
|
194
|
-
proc.stderr?.removeAllListeners();
|
|
195
|
-
proc.stdin?.removeAllListeners();
|
|
196
|
-
// Kill the process
|
|
197
|
-
try {
|
|
198
|
-
proc.kill('SIGTERM');
|
|
199
|
-
}
|
|
200
|
-
catch { /* already dead */ }
|
|
201
|
-
// Destroy stdio pipes
|
|
202
|
-
try {
|
|
203
|
-
proc.stdin?.destroy();
|
|
204
|
-
}
|
|
205
|
-
catch { /* ignore */ }
|
|
206
|
-
try {
|
|
207
|
-
proc.stdout?.destroy();
|
|
208
|
-
}
|
|
209
|
-
catch { /* ignore */ }
|
|
210
|
-
try {
|
|
211
|
-
proc.stderr?.destroy();
|
|
212
|
-
}
|
|
213
|
-
catch { /* ignore */ }
|
|
214
|
-
// Unref so Node doesn't wait
|
|
215
|
-
try {
|
|
216
|
-
proc.unref();
|
|
217
|
-
}
|
|
218
|
-
catch { /* ignore */ }
|
|
219
|
-
// Force kill after 5 seconds
|
|
220
|
-
setTimeout(() => {
|
|
221
|
-
try {
|
|
222
|
-
proc.kill('SIGKILL');
|
|
223
|
-
}
|
|
224
|
-
catch { /* already dead */ }
|
|
225
|
-
}, 5000).unref();
|
|
209
|
+
transport.removeAllListeners();
|
|
210
|
+
transport.disconnect();
|
|
226
211
|
}
|
|
227
212
|
}
|
|
228
213
|
/**
|
|
@@ -231,55 +216,6 @@ export class RustBridge extends plugins.events.EventEmitter {
|
|
|
231
216
|
get running() {
|
|
232
217
|
return this.isRunning;
|
|
233
218
|
}
|
|
234
|
-
/**
|
|
235
|
-
* Buffer-based newline scanner for stdout chunks.
|
|
236
|
-
* Replaces readline to handle large payloads without buffering entire lines in a separate abstraction.
|
|
237
|
-
*/
|
|
238
|
-
handleStdoutChunk(chunk) {
|
|
239
|
-
this.stdoutBuffer = Buffer.concat([this.stdoutBuffer, chunk]);
|
|
240
|
-
let newlineIndex;
|
|
241
|
-
while ((newlineIndex = this.stdoutBuffer.indexOf(0x0A)) !== -1) {
|
|
242
|
-
const lineBuffer = this.stdoutBuffer.subarray(0, newlineIndex);
|
|
243
|
-
this.stdoutBuffer = this.stdoutBuffer.subarray(newlineIndex + 1);
|
|
244
|
-
if (lineBuffer.length > this.options.maxPayloadSize) {
|
|
245
|
-
this.logger.log('error', `Inbound message exceeds maxPayloadSize (${lineBuffer.length} bytes), dropping`);
|
|
246
|
-
continue;
|
|
247
|
-
}
|
|
248
|
-
const line = lineBuffer.toString('utf8').trim();
|
|
249
|
-
this.handleLine(line);
|
|
250
|
-
}
|
|
251
|
-
// If accumulated buffer exceeds maxPayloadSize (sender never sends newline), clear to prevent OOM
|
|
252
|
-
if (this.stdoutBuffer.length > this.options.maxPayloadSize) {
|
|
253
|
-
this.logger.log('error', `Stdout buffer exceeded maxPayloadSize (${this.stdoutBuffer.length} bytes) without newline, clearing`);
|
|
254
|
-
this.stdoutBuffer = Buffer.alloc(0);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Write data to stdin with backpressure support.
|
|
259
|
-
* Waits for drain if the internal buffer is full.
|
|
260
|
-
*/
|
|
261
|
-
writeToStdin(data) {
|
|
262
|
-
return new Promise((resolve, reject) => {
|
|
263
|
-
if (!this.childProcess?.stdin) {
|
|
264
|
-
reject(new Error('stdin not available'));
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
const canContinue = this.childProcess.stdin.write(data, 'utf8', (err) => {
|
|
268
|
-
if (err) {
|
|
269
|
-
reject(err);
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
if (canContinue) {
|
|
273
|
-
resolve();
|
|
274
|
-
}
|
|
275
|
-
else {
|
|
276
|
-
// Wait for drain before resolving
|
|
277
|
-
this.childProcess.stdin.once('drain', () => {
|
|
278
|
-
resolve();
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
219
|
handleLine(line) {
|
|
284
220
|
if (!line)
|
|
285
221
|
return;
|
|
@@ -330,9 +266,7 @@ export class RustBridge extends plugins.events.EventEmitter {
|
|
|
330
266
|
}
|
|
331
267
|
cleanup() {
|
|
332
268
|
this.isRunning = false;
|
|
333
|
-
this.
|
|
334
|
-
this.stdoutBuffer = Buffer.alloc(0);
|
|
335
|
-
this.stderrRemainder = '';
|
|
269
|
+
this.transport = null;
|
|
336
270
|
// Reject all pending requests
|
|
337
271
|
for (const [, pending] of this.pendingRequests) {
|
|
338
272
|
clearTimeout(pending.timer);
|
|
@@ -341,4 +275,4 @@ export class RustBridge extends plugins.events.EventEmitter {
|
|
|
341
275
|
this.pendingRequests.clear();
|
|
342
276
|
}
|
|
343
277
|
}
|
|
344
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5ydXN0YnJpZGdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5ydXN0YnJpZGdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBWW5FLE1BQU0sYUFBYSxHQUFzQjtJQUN2QyxHQUFHLEtBQUksQ0FBQztDQUNULENBQUM7QUFFRjs7Ozs7R0FLRztBQUNILE1BQU0sT0FBTyxVQUF3RCxTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtJQUM5RixPQUFPLENBQW9CO0lBQzNCLE9BQU8sQ0FBbUo7SUFDMUosTUFBTSxDQUFvQjtJQUMxQixZQUFZLEdBQTZDLElBQUksQ0FBQztJQUM5RCxZQUFZLEdBQVcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2QyxlQUFlLEdBQVcsRUFBRSxDQUFDO0lBQzdCLGVBQWUsR0FBRyxJQUFJLEdBQUcsRUFLN0IsQ0FBQztJQUNHLGNBQWMsR0FBRyxDQUFDLENBQUM7SUFDbkIsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUNsQixVQUFVLEdBQWtCLElBQUksQ0FBQztJQUV6QyxZQUFZLE9BQTJCO1FBQ3JDLEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLGFBQWEsQ0FBQztRQUM5QyxJQUFJLENBQUMsT0FBTyxHQUFHO1lBQ2IsT0FBTyxFQUFFLENBQUMsY0FBYyxDQUFDO1lBQ3pCLGdCQUFnQixFQUFFLEtBQUs7WUFDdkIsY0FBYyxFQUFFLEtBQUs7WUFDckIsY0FBYyxFQUFFLE9BQU87WUFDdkIsY0FBYyxFQUFFLEVBQUUsR0FBRyxJQUFJLEdBQUcsSUFBSTtZQUNoQyxH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
|
|
278
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5ydXN0YnJpZGdlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5ydXN0YnJpZGdlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUM3RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFjL0QsTUFBTSxhQUFhLEdBQXNCO0lBQ3ZDLEdBQUcsS0FBSSxDQUFDO0NBQ1QsQ0FBQztBQUVGOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxVQUF3RCxTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtJQUM5RixPQUFPLENBQW9CO0lBQzNCLE9BQU8sQ0FBbUo7SUFDMUosTUFBTSxDQUFvQjtJQUMxQixTQUFTLEdBQTBCLElBQUksQ0FBQztJQUN4QyxlQUFlLEdBQUcsSUFBSSxHQUFHLEVBSzdCLENBQUM7SUFDRyxjQUFjLEdBQUcsQ0FBQyxDQUFDO0lBQ25CLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDbEIsVUFBVSxHQUFrQixJQUFJLENBQUM7SUFFekMsWUFBWSxPQUEyQjtRQUNyQyxLQUFLLEVBQUUsQ0FBQztRQUNSLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sSUFBSSxhQUFhLENBQUM7UUFDOUMsSUFBSSxDQUFDLE9BQU8sR0FBRztZQUNiLE9BQU8sRUFBRSxDQUFDLGNBQWMsQ0FBQztZQUN6QixnQkFBZ0IsRUFBRSxLQUFLO1lBQ3ZCLGNBQWMsRUFBRSxLQUFLO1lBQ3JCLGNBQWMsRUFBRSxPQUFPO1lBQ3ZCLGNBQWMsRUFBRSxFQUFFLEdBQUcsSUFBSSxHQUFHLElB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
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as plugins from './plugins.js';
|
|
2
|
+
import type { IRustBridgeLogger } from './interfaces/index.js';
|
|
3
|
+
import type { IRustTransport } from './interfaces/transport.js';
|
|
4
|
+
export interface ISocketTransportOptions {
|
|
5
|
+
/** Path to Unix socket (Linux/macOS) or named pipe path (Windows) */
|
|
6
|
+
socketPath: string;
|
|
7
|
+
/** Maximum inbound message size in bytes */
|
|
8
|
+
maxPayloadSize: number;
|
|
9
|
+
/** Logger instance */
|
|
10
|
+
logger: IRustBridgeLogger;
|
|
11
|
+
/** Enable auto-reconnect on unexpected disconnect (default: false) */
|
|
12
|
+
autoReconnect?: boolean;
|
|
13
|
+
/** Initial delay between reconnect attempts in ms (default: 100) */
|
|
14
|
+
reconnectBaseDelayMs?: number;
|
|
15
|
+
/** Maximum delay between reconnect attempts in ms (default: 30000) */
|
|
16
|
+
reconnectMaxDelayMs?: number;
|
|
17
|
+
/** Maximum number of reconnect attempts before giving up (default: 10) */
|
|
18
|
+
maxReconnectAttempts?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Transport that connects to an already-running process via Unix socket or Windows named pipe.
|
|
22
|
+
* The JSON-over-newline protocol is identical to stdio; only the transport changes.
|
|
23
|
+
*/
|
|
24
|
+
export declare class SocketTransport extends plugins.events.EventEmitter implements IRustTransport {
|
|
25
|
+
private options;
|
|
26
|
+
private socket;
|
|
27
|
+
private lineScanner;
|
|
28
|
+
private _connected;
|
|
29
|
+
private intentionalDisconnect;
|
|
30
|
+
private reconnectAttempts;
|
|
31
|
+
private reconnectTimer;
|
|
32
|
+
constructor(options: ISocketTransportOptions);
|
|
33
|
+
get connected(): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Connect to the socket. Resolves when the TCP/Unix connection is established.
|
|
36
|
+
*/
|
|
37
|
+
connect(): Promise<void>;
|
|
38
|
+
private doConnect;
|
|
39
|
+
private attemptReconnect;
|
|
40
|
+
/**
|
|
41
|
+
* Write data to the socket with backpressure support.
|
|
42
|
+
*/
|
|
43
|
+
write(data: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Close the socket connection. Does NOT kill the remote daemon.
|
|
46
|
+
*/
|
|
47
|
+
disconnect(): void;
|
|
48
|
+
}
|