tywrap 0.1.1 → 0.2.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/README.md +32 -5
- package/dist/cli.js +70 -3
- package/dist/cli.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +47 -11
- package/dist/config/index.js.map +1 -1
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/core/generator.js +6 -2
- package/dist/core/generator.js.map +1 -1
- package/dist/core/mapper.d.ts.map +1 -1
- package/dist/core/mapper.js +16 -4
- package/dist/core/mapper.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/runtime/bridge-core.d.ts +64 -0
- package/dist/runtime/bridge-core.d.ts.map +1 -0
- package/dist/runtime/bridge-core.js +344 -0
- package/dist/runtime/bridge-core.js.map +1 -0
- package/dist/runtime/node.d.ts +161 -15
- package/dist/runtime/node.d.ts.map +1 -1
- package/dist/runtime/node.js +542 -218
- package/dist/runtime/node.js.map +1 -1
- package/dist/runtime/optimized-node.d.ts +19 -128
- package/dist/runtime/optimized-node.d.ts.map +1 -1
- package/dist/runtime/optimized-node.js +19 -627
- package/dist/runtime/optimized-node.js.map +1 -1
- package/dist/runtime/timed-out-request-tracker.d.ts +20 -0
- package/dist/runtime/timed-out-request-tracker.d.ts.map +1 -0
- package/dist/runtime/timed-out-request-tracker.js +48 -0
- package/dist/runtime/timed-out-request-tracker.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/tywrap.d.ts +17 -4
- package/dist/tywrap.d.ts.map +1 -1
- package/dist/tywrap.js +68 -35
- package/dist/tywrap.js.map +1 -1
- package/dist/utils/codec.d.ts +22 -0
- package/dist/utils/codec.d.ts.map +1 -1
- package/dist/utils/codec.js +245 -55
- package/dist/utils/codec.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +1 -0
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/python.d.ts.map +1 -1
- package/dist/utils/python.js.map +1 -1
- package/package.json +11 -2
- package/runtime/python_bridge.py +450 -69
- package/src/cli.ts +75 -3
- package/src/config/index.ts +58 -15
- package/src/core/generator.ts +6 -2
- package/src/core/mapper.ts +16 -4
- package/src/index.ts +2 -1
- package/src/runtime/bridge-core.ts +454 -0
- package/src/runtime/node.ts +725 -253
- package/src/runtime/optimized-node.ts +19 -844
- package/src/runtime/timed-out-request-tracker.ts +58 -0
- package/src/types/index.ts +3 -0
- package/src/tywrap.ts +91 -36
- package/src/utils/codec.ts +299 -82
- package/src/utils/logger.ts +1 -0
- package/src/utils/python.ts +0 -1
package/dist/index.js
CHANGED
|
@@ -18,9 +18,9 @@ export { tywrap } from './tywrap.js';
|
|
|
18
18
|
export { generate } from './tywrap.js';
|
|
19
19
|
// Runtime detection utilities
|
|
20
20
|
export { detectRuntime, isNodejs, isDeno, isBun, isBrowser } from './utils/runtime.js';
|
|
21
|
-
export { decodeValue, decodeValueAsync, registerArrowDecoder, clearArrowDecoder, } from './utils/codec.js';
|
|
21
|
+
export { decodeValue, decodeValueAsync, autoRegisterArrowDecoder, registerArrowDecoder, clearArrowDecoder, } from './utils/codec.js';
|
|
22
22
|
// Version info
|
|
23
|
-
export const VERSION = '0.
|
|
23
|
+
export const VERSION = '0.2.0';
|
|
24
24
|
/**
|
|
25
25
|
* Quick setup function for getting started
|
|
26
26
|
*/
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE5F,2BAA2B;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAsC/C,WAAW;AACX,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,8BAA8B;AAC9B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACvF,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,eAAe;AACf,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B;;GAEG;AACH,iCAAiC;AACjC,eAAe,MAAM,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE5F,2BAA2B;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAsC/C,WAAW;AACX,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,8BAA8B;AAC9B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACvF,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B,eAAe;AACf,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B;;GAEG;AACH,iCAAiC;AACjC,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { BridgeProtocolError, BridgeTimeoutError } from './errors.js';
|
|
2
|
+
export type RpcMethod = 'call' | 'instantiate' | 'call_method' | 'dispose_instance' | 'meta';
|
|
3
|
+
export interface RpcRequest {
|
|
4
|
+
id: number;
|
|
5
|
+
protocol: string;
|
|
6
|
+
method: RpcMethod;
|
|
7
|
+
params: unknown;
|
|
8
|
+
}
|
|
9
|
+
export interface RpcResponse<T = unknown> {
|
|
10
|
+
id: number;
|
|
11
|
+
protocol: string;
|
|
12
|
+
result?: T;
|
|
13
|
+
error?: {
|
|
14
|
+
type: string;
|
|
15
|
+
message: string;
|
|
16
|
+
traceback?: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export interface BridgeCoreTransport {
|
|
20
|
+
write: (data: string) => void;
|
|
21
|
+
}
|
|
22
|
+
export interface BridgeCoreOptions {
|
|
23
|
+
timeoutMs: number;
|
|
24
|
+
maxLineLength?: number;
|
|
25
|
+
maxStderrBytes?: number;
|
|
26
|
+
protocol?: string;
|
|
27
|
+
protocolVersion?: number;
|
|
28
|
+
decodeValue?: (value: unknown) => Promise<unknown>;
|
|
29
|
+
onFatalError?: (error: BridgeProtocolError) => void;
|
|
30
|
+
onTimeout?: (error: BridgeTimeoutError) => void;
|
|
31
|
+
}
|
|
32
|
+
export declare class BridgeCore {
|
|
33
|
+
private readonly transport;
|
|
34
|
+
private readonly options;
|
|
35
|
+
private readonly timedOutRequests;
|
|
36
|
+
private readonly pending;
|
|
37
|
+
private nextId;
|
|
38
|
+
private stdoutBuffer;
|
|
39
|
+
private stderrBuffer;
|
|
40
|
+
private protocolError;
|
|
41
|
+
constructor(transport: BridgeCoreTransport, options: BridgeCoreOptions);
|
|
42
|
+
getStderrTail(): string;
|
|
43
|
+
getPendingCount(): number;
|
|
44
|
+
clear(): void;
|
|
45
|
+
send<T>(payload: Omit<RpcRequest, 'id' | 'protocol'>): Promise<T>;
|
|
46
|
+
handleStdoutData(chunk: Buffer | string): void;
|
|
47
|
+
handleStderrData(chunk: Buffer | string): void;
|
|
48
|
+
handleProcessExit(): void;
|
|
49
|
+
handleProcessError(err: Error): void;
|
|
50
|
+
private handleResponseLine;
|
|
51
|
+
private errorFrom;
|
|
52
|
+
private normalizeErrorPayload;
|
|
53
|
+
private failRequest;
|
|
54
|
+
private rejectAll;
|
|
55
|
+
private handleProtocolError;
|
|
56
|
+
private handleFatalError;
|
|
57
|
+
}
|
|
58
|
+
export declare function validateBridgeInfo(info: unknown): void;
|
|
59
|
+
export declare function getPathKey(...envs: Array<Record<string, string | undefined>>): string;
|
|
60
|
+
export declare function ensurePythonEncoding(env: NodeJS.ProcessEnv): void;
|
|
61
|
+
export declare function ensureJsonFallback(env: NodeJS.ProcessEnv, enabled: boolean): void;
|
|
62
|
+
export declare function getMaxLineLengthFromEnv(env: NodeJS.ProcessEnv): number | undefined;
|
|
63
|
+
export declare function normalizeEnv(baseEnv: Record<string, string | undefined>, overrides: Record<string, string | undefined>): NodeJS.ProcessEnv;
|
|
64
|
+
//# sourceMappingURL=bridge-core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge-core.d.ts","sourceRoot":"","sources":["../../src/runtime/bridge-core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import { BridgeExecutionError, BridgeProtocolError, BridgeTimeoutError } from './errors.js';
|
|
2
|
+
import { TYWRAP_PROTOCOL, TYWRAP_PROTOCOL_VERSION } from './protocol.js';
|
|
3
|
+
import { TimedOutRequestTracker } from './timed-out-request-tracker.js';
|
|
4
|
+
// Why: keep stdout lines bounded to prevent unbounded memory growth on malformed output.
|
|
5
|
+
const DEFAULT_MAX_LINE_LENGTH = 1024 * 1024; // 1MB
|
|
6
|
+
// Why: keep stderr snapshots small but useful for diagnostics on timeouts/exits.
|
|
7
|
+
const DEFAULT_MAX_STDERR_BYTES = 8 * 1024; // 8KB
|
|
8
|
+
const defaultDecodeValue = async (value) => value;
|
|
9
|
+
const noop = () => { };
|
|
10
|
+
const ANSI_ESCAPE_RE = new RegExp('\\u001b\\[[0-9;]*[A-Za-z]', 'g');
|
|
11
|
+
const CONTROL_CHARS_RE = new RegExp('[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F\\u0080-\\u009F]', 'g');
|
|
12
|
+
const sanitizeStderr = (value) => value.replace(ANSI_ESCAPE_RE, '').replace(CONTROL_CHARS_RE, '');
|
|
13
|
+
export class BridgeCore {
|
|
14
|
+
transport;
|
|
15
|
+
options;
|
|
16
|
+
timedOutRequests;
|
|
17
|
+
pending = new Map();
|
|
18
|
+
nextId = 1;
|
|
19
|
+
stdoutBuffer = '';
|
|
20
|
+
stderrBuffer = '';
|
|
21
|
+
protocolError = false;
|
|
22
|
+
constructor(transport, options) {
|
|
23
|
+
this.transport = transport;
|
|
24
|
+
this.options = {
|
|
25
|
+
timeoutMs: options.timeoutMs,
|
|
26
|
+
maxLineLength: options.maxLineLength ?? DEFAULT_MAX_LINE_LENGTH,
|
|
27
|
+
maxStderrBytes: options.maxStderrBytes ?? DEFAULT_MAX_STDERR_BYTES,
|
|
28
|
+
protocol: options.protocol ?? TYWRAP_PROTOCOL,
|
|
29
|
+
protocolVersion: options.protocolVersion ?? TYWRAP_PROTOCOL_VERSION,
|
|
30
|
+
decodeValue: options.decodeValue ?? defaultDecodeValue,
|
|
31
|
+
onFatalError: options.onFatalError ?? noop,
|
|
32
|
+
onTimeout: options.onTimeout ?? noop,
|
|
33
|
+
};
|
|
34
|
+
this.timedOutRequests = new TimedOutRequestTracker({
|
|
35
|
+
ttlMs: Math.max(1000, this.options.timeoutMs * 2),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
getStderrTail() {
|
|
39
|
+
return this.stderrBuffer.trim();
|
|
40
|
+
}
|
|
41
|
+
getPendingCount() {
|
|
42
|
+
return this.pending.size;
|
|
43
|
+
}
|
|
44
|
+
clear() {
|
|
45
|
+
for (const [, pending] of this.pending) {
|
|
46
|
+
if (pending.timer) {
|
|
47
|
+
clearTimeout(pending.timer);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
this.pending.clear();
|
|
51
|
+
this.timedOutRequests.clear();
|
|
52
|
+
this.stdoutBuffer = '';
|
|
53
|
+
this.stderrBuffer = '';
|
|
54
|
+
this.protocolError = false;
|
|
55
|
+
}
|
|
56
|
+
async send(payload) {
|
|
57
|
+
const id = this.nextId++;
|
|
58
|
+
const message = { ...payload, id, protocol: this.options.protocol };
|
|
59
|
+
let text;
|
|
60
|
+
try {
|
|
61
|
+
text = JSON.stringify(message);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
throw new BridgeProtocolError(`Failed to serialize request: ${err instanceof Error ? err.message : String(err)}`);
|
|
65
|
+
}
|
|
66
|
+
let timer;
|
|
67
|
+
const promise = new Promise((resolve, reject) => {
|
|
68
|
+
timer = setTimeout(() => {
|
|
69
|
+
this.pending.delete(id);
|
|
70
|
+
this.timedOutRequests.mark(id);
|
|
71
|
+
const stderrTail = this.getStderrTail();
|
|
72
|
+
const msg = stderrTail
|
|
73
|
+
? `Python call timed out. Recent stderr from Python:\n${stderrTail}`
|
|
74
|
+
: 'Python call timed out';
|
|
75
|
+
const timeoutError = new BridgeTimeoutError(msg);
|
|
76
|
+
reject(timeoutError);
|
|
77
|
+
this.options.onTimeout(timeoutError);
|
|
78
|
+
}, this.options.timeoutMs);
|
|
79
|
+
const resolveWrapped = (value) => {
|
|
80
|
+
resolve(value);
|
|
81
|
+
};
|
|
82
|
+
this.pending.set(id, { resolve: resolveWrapped, reject, timer });
|
|
83
|
+
});
|
|
84
|
+
try {
|
|
85
|
+
this.transport.write(`${text}\n`);
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
const failure = new BridgeProtocolError(`IPC failure: ${err instanceof Error ? err.message : String(err)}`);
|
|
89
|
+
this.failRequest(id, failure);
|
|
90
|
+
this.handleFatalError(failure);
|
|
91
|
+
}
|
|
92
|
+
return promise;
|
|
93
|
+
}
|
|
94
|
+
handleStdoutData(chunk) {
|
|
95
|
+
this.stdoutBuffer += chunk.toString();
|
|
96
|
+
if (this.stdoutBuffer.length > this.options.maxLineLength &&
|
|
97
|
+
!this.stdoutBuffer.includes('\n')) {
|
|
98
|
+
const snippet = this.stdoutBuffer.slice(0, this.options.maxLineLength);
|
|
99
|
+
this.stdoutBuffer = '';
|
|
100
|
+
this.handleProtocolError(`Response line exceeded ${this.options.maxLineLength} bytes`, snippet);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
let idx;
|
|
104
|
+
while ((idx = this.stdoutBuffer.indexOf('\n')) !== -1) {
|
|
105
|
+
const line = this.stdoutBuffer.slice(0, idx);
|
|
106
|
+
this.stdoutBuffer = this.stdoutBuffer.slice(idx + 1);
|
|
107
|
+
if (!line.trim()) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (line.length > this.options.maxLineLength) {
|
|
111
|
+
const snippet = line.slice(0, this.options.maxLineLength);
|
|
112
|
+
this.handleProtocolError(`Response line exceeded ${this.options.maxLineLength} bytes`, snippet);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
this.handleResponseLine(line);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
handleStderrData(chunk) {
|
|
119
|
+
try {
|
|
120
|
+
this.stderrBuffer += sanitizeStderr(chunk.toString());
|
|
121
|
+
if (this.stderrBuffer.length > this.options.maxStderrBytes) {
|
|
122
|
+
this.stderrBuffer = this.stderrBuffer.slice(this.stderrBuffer.length - this.options.maxStderrBytes);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Ignore stderr buffering errors
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
handleProcessExit() {
|
|
130
|
+
const stderrTail = this.getStderrTail();
|
|
131
|
+
const msg = stderrTail
|
|
132
|
+
? `Python process exited. Stderr:\n${stderrTail}`
|
|
133
|
+
: 'Python process exited';
|
|
134
|
+
this.rejectAll(new BridgeProtocolError(msg));
|
|
135
|
+
}
|
|
136
|
+
handleProcessError(err) {
|
|
137
|
+
const msg = `Python process error: ${err.message}`;
|
|
138
|
+
const error = new BridgeProtocolError(msg);
|
|
139
|
+
this.rejectAll(error);
|
|
140
|
+
this.handleFatalError(error);
|
|
141
|
+
}
|
|
142
|
+
handleResponseLine(line) {
|
|
143
|
+
let msg;
|
|
144
|
+
try {
|
|
145
|
+
const parsed = JSON.parse(line);
|
|
146
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
147
|
+
this.handleProtocolError('Invalid response payload', line);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
msg = parsed;
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
const parseMessage = err instanceof Error ? err.message : String(err);
|
|
154
|
+
this.handleProtocolError(`Invalid JSON: ${parseMessage}`, line);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (msg.protocol !== this.options.protocol) {
|
|
158
|
+
this.handleProtocolError(`Invalid protocol. Expected ${this.options.protocol} but received ${String(msg.protocol)}`, line);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (typeof msg.id !== 'number') {
|
|
162
|
+
this.handleProtocolError('Invalid response id', line);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const pending = this.pending.get(msg.id);
|
|
166
|
+
if (!pending) {
|
|
167
|
+
if (this.timedOutRequests.consume(msg.id)) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
this.handleProtocolError(`Unexpected response id ${msg.id}`, line);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
this.pending.delete(msg.id);
|
|
174
|
+
if (pending.timer) {
|
|
175
|
+
clearTimeout(pending.timer);
|
|
176
|
+
}
|
|
177
|
+
if ('error' in msg) {
|
|
178
|
+
const errorPayload = this.normalizeErrorPayload(msg.error);
|
|
179
|
+
pending.reject(this.errorFrom(errorPayload));
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
Promise.resolve(this.options.decodeValue(msg.result))
|
|
183
|
+
.then(decoded => pending.resolve(decoded))
|
|
184
|
+
.catch(err => {
|
|
185
|
+
pending.reject(new BridgeProtocolError(`Failed to decode Python response: ${err instanceof Error ? err.message : String(err)}`));
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
errorFrom(err) {
|
|
189
|
+
const error = new BridgeExecutionError(`${err.type}: ${err.message}`);
|
|
190
|
+
error.traceback = err.traceback;
|
|
191
|
+
return error;
|
|
192
|
+
}
|
|
193
|
+
normalizeErrorPayload(err) {
|
|
194
|
+
if (err && typeof err === 'object') {
|
|
195
|
+
const candidate = err;
|
|
196
|
+
if (typeof candidate.type === 'string' && typeof candidate.message === 'string') {
|
|
197
|
+
const normalized = {
|
|
198
|
+
type: candidate.type,
|
|
199
|
+
message: candidate.message,
|
|
200
|
+
};
|
|
201
|
+
if (typeof candidate.traceback === 'string') {
|
|
202
|
+
normalized.traceback = candidate.traceback;
|
|
203
|
+
}
|
|
204
|
+
return normalized;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return { type: 'UnknownError', message: String(err) };
|
|
208
|
+
}
|
|
209
|
+
failRequest(id, error) {
|
|
210
|
+
const pending = this.pending.get(id);
|
|
211
|
+
if (!pending) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
this.pending.delete(id);
|
|
215
|
+
if (pending.timer) {
|
|
216
|
+
clearTimeout(pending.timer);
|
|
217
|
+
}
|
|
218
|
+
pending.reject(error);
|
|
219
|
+
}
|
|
220
|
+
rejectAll(error) {
|
|
221
|
+
for (const [, pending] of this.pending) {
|
|
222
|
+
if (pending.timer) {
|
|
223
|
+
clearTimeout(pending.timer);
|
|
224
|
+
}
|
|
225
|
+
pending.reject(error);
|
|
226
|
+
}
|
|
227
|
+
this.pending.clear();
|
|
228
|
+
this.timedOutRequests.clear();
|
|
229
|
+
}
|
|
230
|
+
handleProtocolError(details, line) {
|
|
231
|
+
if (this.protocolError) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
this.protocolError = true;
|
|
235
|
+
const snippet = line ? (line.length > 500 ? `${line.slice(0, 500)}...` : line) : undefined;
|
|
236
|
+
const hint = 'Ensure your Python code does not print to stdout and that the bridge outputs only JSON lines.';
|
|
237
|
+
const msg = snippet
|
|
238
|
+
? `Protocol error from Python bridge. ${details}\n${hint}\nOffending line: ${snippet}`
|
|
239
|
+
: `Protocol error from Python bridge. ${details}\n${hint}`;
|
|
240
|
+
const error = new BridgeProtocolError(msg);
|
|
241
|
+
this.rejectAll(error);
|
|
242
|
+
this.handleFatalError(error);
|
|
243
|
+
}
|
|
244
|
+
handleFatalError(error) {
|
|
245
|
+
try {
|
|
246
|
+
this.options.onFatalError(error);
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
// Ignore callback failures
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
export function validateBridgeInfo(info) {
|
|
254
|
+
if (!info || typeof info !== 'object') {
|
|
255
|
+
throw new BridgeProtocolError('Invalid bridge info payload');
|
|
256
|
+
}
|
|
257
|
+
const candidate = info;
|
|
258
|
+
if (candidate.protocol !== TYWRAP_PROTOCOL ||
|
|
259
|
+
candidate.protocolVersion !== TYWRAP_PROTOCOL_VERSION) {
|
|
260
|
+
throw new BridgeProtocolError('Invalid bridge info payload');
|
|
261
|
+
}
|
|
262
|
+
if (candidate.bridge !== 'python-subprocess') {
|
|
263
|
+
throw new BridgeProtocolError(`Unexpected bridge identifier: ${candidate.bridge}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
export function getPathKey(...envs) {
|
|
267
|
+
for (const env of envs) {
|
|
268
|
+
const key = findPathKey(env);
|
|
269
|
+
if (key) {
|
|
270
|
+
return key;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return 'PATH';
|
|
274
|
+
}
|
|
275
|
+
export function ensurePythonEncoding(env) {
|
|
276
|
+
if (env.PYTHONUTF8 === undefined || env.PYTHONUTF8 === null || env.PYTHONUTF8 === '') {
|
|
277
|
+
env.PYTHONUTF8 = '1';
|
|
278
|
+
}
|
|
279
|
+
if (env.PYTHONIOENCODING === undefined ||
|
|
280
|
+
env.PYTHONIOENCODING === null ||
|
|
281
|
+
env.PYTHONIOENCODING === '') {
|
|
282
|
+
env.PYTHONIOENCODING = 'UTF-8';
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
export function ensureJsonFallback(env, enabled) {
|
|
286
|
+
if (enabled && !env.TYWRAP_CODEC_FALLBACK) {
|
|
287
|
+
env.TYWRAP_CODEC_FALLBACK = 'json';
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
export function getMaxLineLengthFromEnv(env) {
|
|
291
|
+
const raw = env.TYWRAP_CODEC_MAX_BYTES?.trim();
|
|
292
|
+
if (!raw) {
|
|
293
|
+
return undefined;
|
|
294
|
+
}
|
|
295
|
+
if (!/^\d+$/.test(raw)) {
|
|
296
|
+
return undefined;
|
|
297
|
+
}
|
|
298
|
+
const parsed = Number(raw);
|
|
299
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
300
|
+
return undefined;
|
|
301
|
+
}
|
|
302
|
+
return parsed;
|
|
303
|
+
}
|
|
304
|
+
export function normalizeEnv(baseEnv, overrides) {
|
|
305
|
+
// Why: normalize PATH casing (Windows) and drop undefined values to avoid spawn surprises.
|
|
306
|
+
const overridePathKey = findPathKey(overrides);
|
|
307
|
+
const basePathKey = findPathKey(baseEnv);
|
|
308
|
+
const pathKey = basePathKey ?? overridePathKey ?? 'PATH';
|
|
309
|
+
let pathValue;
|
|
310
|
+
if (overridePathKey !== null) {
|
|
311
|
+
// eslint-disable-next-line security/detect-object-injection -- env keys are dynamic by design
|
|
312
|
+
pathValue = overrides[overridePathKey];
|
|
313
|
+
}
|
|
314
|
+
else if (basePathKey) {
|
|
315
|
+
// eslint-disable-next-line security/detect-object-injection -- env keys are dynamic by design
|
|
316
|
+
pathValue = baseEnv[basePathKey];
|
|
317
|
+
}
|
|
318
|
+
const merged = { ...baseEnv, ...overrides };
|
|
319
|
+
const result = {};
|
|
320
|
+
if (pathValue !== undefined) {
|
|
321
|
+
// eslint-disable-next-line security/detect-object-injection -- env keys are dynamic by design
|
|
322
|
+
result[pathKey] = pathValue;
|
|
323
|
+
}
|
|
324
|
+
for (const [key, value] of Object.entries(merged)) {
|
|
325
|
+
if (value === undefined) {
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
if (key.toLowerCase() === 'path') {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
// eslint-disable-next-line security/detect-object-injection -- env keys are dynamic by design
|
|
332
|
+
result[key] = value;
|
|
333
|
+
}
|
|
334
|
+
return result;
|
|
335
|
+
}
|
|
336
|
+
function findPathKey(env) {
|
|
337
|
+
for (const key of Object.keys(env)) {
|
|
338
|
+
if (key.toLowerCase() === 'path') {
|
|
339
|
+
return key;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=bridge-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge-core.js","sourceRoot":"","sources":["../../src/runtime/bridge-core.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/node.d.ts
CHANGED
|
@@ -1,36 +1,115 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Node.js
|
|
2
|
+
* Node.js Runtime Bridge with Optional Connection Pooling
|
|
3
|
+
*
|
|
4
|
+
* NodeBridge is the unified Node.js runtime bridge that supports both single-process
|
|
5
|
+
* (correctness-first) and multi-process (pooled) configurations. By default, it runs
|
|
6
|
+
* in single-process mode for maximum compatibility with the original NodeBridge behavior.
|
|
7
|
+
*
|
|
8
|
+
* For high-throughput workloads, configure pooling via minProcesses/maxProcesses options.
|
|
3
9
|
*/
|
|
4
10
|
import type { BridgeInfo } from '../types/index.js';
|
|
5
11
|
import { RuntimeBridge } from './base.js';
|
|
12
|
+
/**
|
|
13
|
+
* Configuration options for NodeBridge.
|
|
14
|
+
*
|
|
15
|
+
* By default, NodeBridge runs in single-process mode (minProcesses=1, maxProcesses=1).
|
|
16
|
+
* For high-throughput workloads, increase these values to enable process pooling.
|
|
17
|
+
*/
|
|
6
18
|
export interface NodeBridgeOptions {
|
|
19
|
+
/** Minimum number of Python processes to keep alive. Default: 1 */
|
|
20
|
+
minProcesses?: number;
|
|
21
|
+
/** Maximum number of Python processes to spawn. Default: 1 (single-process mode) */
|
|
22
|
+
maxProcesses?: number;
|
|
23
|
+
/** Time in ms to keep idle processes alive before termination. Default: 300000 (5 min) */
|
|
24
|
+
maxIdleTime?: number;
|
|
25
|
+
/** Restart process after this many requests. Default: 1000 */
|
|
26
|
+
maxRequestsPerProcess?: number;
|
|
27
|
+
/** Path to Python executable. Auto-detected if not specified. */
|
|
7
28
|
pythonPath?: string;
|
|
29
|
+
/** Path to python_bridge.py script. Auto-detected if not specified. */
|
|
8
30
|
scriptPath?: string;
|
|
31
|
+
/** Path to Python virtual environment. */
|
|
9
32
|
virtualEnv?: string;
|
|
33
|
+
/** Working directory for Python process. Default: process.cwd() */
|
|
10
34
|
cwd?: string;
|
|
35
|
+
/** Timeout in ms for Python calls. Default: 30000 */
|
|
11
36
|
timeoutMs?: number;
|
|
37
|
+
/** Maximum line length for JSONL protocol. */
|
|
38
|
+
maxLineLength?: number;
|
|
39
|
+
/** Inherit all environment variables from parent process. Default: false */
|
|
40
|
+
inheritProcessEnv?: boolean;
|
|
12
41
|
/**
|
|
13
42
|
* When true, sets TYWRAP_CODEC_FALLBACK=json for the Python process to prefer JSON encoding
|
|
14
43
|
* for rich types (ndarray/dataframe/series). Default: false for fast-fail on Arrow path issues.
|
|
15
44
|
*/
|
|
16
45
|
enableJsonFallback?: boolean;
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
|
|
46
|
+
/** Enable result caching for pure functions. Default: false */
|
|
47
|
+
enableCache?: boolean;
|
|
48
|
+
/** Optional extra environment variables to pass to the Python subprocess. */
|
|
20
49
|
env?: Record<string, string | undefined>;
|
|
50
|
+
/** Commands to run on each process at startup for warming up. */
|
|
51
|
+
warmupCommands?: Array<{
|
|
52
|
+
method: string;
|
|
53
|
+
params: unknown;
|
|
54
|
+
}>;
|
|
55
|
+
}
|
|
56
|
+
interface BridgeStats {
|
|
57
|
+
totalRequests: number;
|
|
58
|
+
totalTime: number;
|
|
59
|
+
cacheHits: number;
|
|
60
|
+
poolHits: number;
|
|
61
|
+
poolMisses: number;
|
|
62
|
+
processSpawns: number;
|
|
63
|
+
processDeaths: number;
|
|
64
|
+
memoryPeak: number;
|
|
65
|
+
averageTime: number;
|
|
66
|
+
cacheHitRate: number;
|
|
67
|
+
}
|
|
68
|
+
interface BridgeStatsSnapshot extends BridgeStats {
|
|
69
|
+
poolSize: number;
|
|
70
|
+
busyWorkers: number;
|
|
71
|
+
memoryUsage: NodeJS.MemoryUsage;
|
|
72
|
+
workerStats: Array<{
|
|
73
|
+
id: string;
|
|
74
|
+
requestCount: number;
|
|
75
|
+
averageTime: number;
|
|
76
|
+
errorCount: number;
|
|
77
|
+
busy: boolean;
|
|
78
|
+
pendingRequests: number;
|
|
79
|
+
}>;
|
|
21
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* Node.js runtime bridge for executing Python code.
|
|
83
|
+
*
|
|
84
|
+
* By default, runs in single-process mode for correctness-first behavior.
|
|
85
|
+
* Configure minProcesses/maxProcesses for process pooling in high-throughput scenarios.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* // Single-process mode (default)
|
|
90
|
+
* const bridge = new NodeBridge();
|
|
91
|
+
*
|
|
92
|
+
* // Multi-process pooling for high throughput
|
|
93
|
+
* const pooledBridge = new NodeBridge({
|
|
94
|
+
* minProcesses: 2,
|
|
95
|
+
* maxProcesses: 8,
|
|
96
|
+
* enableCache: true,
|
|
97
|
+
* });
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
22
100
|
export declare class NodeBridge extends RuntimeBridge {
|
|
23
|
-
private
|
|
24
|
-
private
|
|
25
|
-
private
|
|
26
|
-
private
|
|
27
|
-
private
|
|
101
|
+
private processPool;
|
|
102
|
+
private roundRobinIndex;
|
|
103
|
+
private cleanupTimer?;
|
|
104
|
+
private options;
|
|
105
|
+
private emitter;
|
|
28
106
|
private disposed;
|
|
29
|
-
private protocolError;
|
|
30
|
-
private initPromise?;
|
|
31
107
|
private bridgeInfo?;
|
|
108
|
+
private initPromise?;
|
|
109
|
+
private stats;
|
|
32
110
|
constructor(options?: NodeBridgeOptions);
|
|
33
111
|
init(): Promise<void>;
|
|
112
|
+
private doInit;
|
|
34
113
|
getBridgeInfo(options?: {
|
|
35
114
|
refresh?: boolean;
|
|
36
115
|
}): Promise<BridgeInfo>;
|
|
@@ -38,11 +117,78 @@ export declare class NodeBridge extends RuntimeBridge {
|
|
|
38
117
|
instantiate<T = unknown>(module: string, className: string, args: unknown[], kwargs?: Record<string, unknown>): Promise<T>;
|
|
39
118
|
callMethod<T = unknown>(handle: string, methodName: string, args: unknown[], kwargs?: Record<string, unknown>): Promise<T>;
|
|
40
119
|
disposeInstance(handle: string): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* Execute request with intelligent process selection
|
|
122
|
+
*/
|
|
123
|
+
private executeRequest;
|
|
124
|
+
/**
|
|
125
|
+
* Select optimal worker based on load and performance
|
|
126
|
+
*/
|
|
127
|
+
private selectOptimalWorker;
|
|
128
|
+
/**
|
|
129
|
+
* Wait for any worker to become available
|
|
130
|
+
*/
|
|
131
|
+
private waitForAvailableWorker;
|
|
132
|
+
/**
|
|
133
|
+
* Send request to specific worker
|
|
134
|
+
*/
|
|
135
|
+
private sendToWorker;
|
|
136
|
+
private quarantineWorker;
|
|
137
|
+
/**
|
|
138
|
+
* Spawn new worker process with optimizations
|
|
139
|
+
*/
|
|
140
|
+
private spawnProcess;
|
|
141
|
+
/**
|
|
142
|
+
* Setup event handlers for worker process
|
|
143
|
+
*/
|
|
144
|
+
private setupProcessHandlers;
|
|
145
|
+
/**
|
|
146
|
+
* Handle worker process exit
|
|
147
|
+
*/
|
|
148
|
+
private handleWorkerExit;
|
|
149
|
+
/**
|
|
150
|
+
* Warm up processes with configured commands
|
|
151
|
+
*/
|
|
152
|
+
private warmupProcesses;
|
|
153
|
+
private safeCacheKey;
|
|
154
|
+
/**
|
|
155
|
+
* Heuristic to determine if function result should be cached
|
|
156
|
+
*/
|
|
157
|
+
private isPureFunctionCandidate;
|
|
158
|
+
/**
|
|
159
|
+
* Update performance statistics
|
|
160
|
+
*/
|
|
161
|
+
private updateStats;
|
|
162
|
+
/**
|
|
163
|
+
* Get performance statistics
|
|
164
|
+
*/
|
|
165
|
+
getStats(): BridgeStatsSnapshot;
|
|
166
|
+
/**
|
|
167
|
+
* Cleanup idle processes
|
|
168
|
+
*/
|
|
169
|
+
private cleanup;
|
|
170
|
+
/**
|
|
171
|
+
* Gracefully terminate a worker
|
|
172
|
+
*/
|
|
173
|
+
private terminateWorker;
|
|
174
|
+
/**
|
|
175
|
+
* Start cleanup scheduler
|
|
176
|
+
*/
|
|
177
|
+
private startCleanupScheduler;
|
|
178
|
+
/**
|
|
179
|
+
* Dispose all resources
|
|
180
|
+
*/
|
|
41
181
|
dispose(): Promise<void>;
|
|
42
|
-
private
|
|
43
|
-
private errorFrom;
|
|
44
|
-
private handleProtocolError;
|
|
45
|
-
private startProcess;
|
|
182
|
+
private buildEnv;
|
|
46
183
|
private refreshBridgeInfo;
|
|
47
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* @deprecated Use NodeBridge with minProcesses/maxProcesses options instead.
|
|
187
|
+
* This alias is provided for backward compatibility.
|
|
188
|
+
*/
|
|
189
|
+
export { NodeBridge as OptimizedNodeBridge };
|
|
190
|
+
/**
|
|
191
|
+
* @deprecated Use NodeBridgeOptions instead.
|
|
192
|
+
*/
|
|
193
|
+
export type { NodeBridgeOptions as ProcessPoolOptions };
|
|
48
194
|
//# sourceMappingURL=node.d.ts.map
|