tywrap 0.1.2 → 0.2.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.
Files changed (93) hide show
  1. package/README.md +11 -4
  2. package/dist/index.d.ts +20 -4
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +22 -2
  5. package/dist/index.js.map +1 -1
  6. package/dist/runtime/base.d.ts +17 -7
  7. package/dist/runtime/base.d.ts.map +1 -1
  8. package/dist/runtime/base.js +18 -1
  9. package/dist/runtime/base.js.map +1 -1
  10. package/dist/runtime/bounded-context.d.ts +252 -0
  11. package/dist/runtime/bounded-context.d.ts.map +1 -0
  12. package/dist/runtime/bounded-context.js +454 -0
  13. package/dist/runtime/bounded-context.js.map +1 -0
  14. package/dist/runtime/bridge-protocol.d.ts +167 -0
  15. package/dist/runtime/bridge-protocol.d.ts.map +1 -0
  16. package/dist/runtime/bridge-protocol.js +247 -0
  17. package/dist/runtime/bridge-protocol.js.map +1 -0
  18. package/dist/runtime/disposable.d.ts +40 -0
  19. package/dist/runtime/disposable.d.ts.map +1 -0
  20. package/dist/runtime/disposable.js +49 -0
  21. package/dist/runtime/disposable.js.map +1 -0
  22. package/dist/runtime/http-io.d.ts +91 -0
  23. package/dist/runtime/http-io.d.ts.map +1 -0
  24. package/dist/runtime/http-io.js +195 -0
  25. package/dist/runtime/http-io.js.map +1 -0
  26. package/dist/runtime/http.d.ts +47 -13
  27. package/dist/runtime/http.d.ts.map +1 -1
  28. package/dist/runtime/http.js +55 -74
  29. package/dist/runtime/http.js.map +1 -1
  30. package/dist/runtime/node.d.ts +142 -28
  31. package/dist/runtime/node.d.ts.map +1 -1
  32. package/dist/runtime/node.js +321 -168
  33. package/dist/runtime/node.js.map +1 -1
  34. package/dist/runtime/optimized-node.d.ts +19 -125
  35. package/dist/runtime/optimized-node.d.ts.map +1 -1
  36. package/dist/runtime/optimized-node.js +19 -550
  37. package/dist/runtime/optimized-node.js.map +1 -1
  38. package/dist/runtime/pooled-transport.d.ts +131 -0
  39. package/dist/runtime/pooled-transport.d.ts.map +1 -0
  40. package/dist/runtime/pooled-transport.js +175 -0
  41. package/dist/runtime/pooled-transport.js.map +1 -0
  42. package/dist/runtime/process-io.d.ts +204 -0
  43. package/dist/runtime/process-io.d.ts.map +1 -0
  44. package/dist/runtime/process-io.js +695 -0
  45. package/dist/runtime/process-io.js.map +1 -0
  46. package/dist/runtime/pyodide-io.d.ts +155 -0
  47. package/dist/runtime/pyodide-io.d.ts.map +1 -0
  48. package/dist/runtime/pyodide-io.js +397 -0
  49. package/dist/runtime/pyodide-io.js.map +1 -0
  50. package/dist/runtime/pyodide.d.ts +51 -19
  51. package/dist/runtime/pyodide.d.ts.map +1 -1
  52. package/dist/runtime/pyodide.js +57 -186
  53. package/dist/runtime/pyodide.js.map +1 -1
  54. package/dist/runtime/safe-codec.d.ts +81 -0
  55. package/dist/runtime/safe-codec.d.ts.map +1 -0
  56. package/dist/runtime/safe-codec.js +345 -0
  57. package/dist/runtime/safe-codec.js.map +1 -0
  58. package/dist/runtime/transport.d.ts +186 -0
  59. package/dist/runtime/transport.d.ts.map +1 -0
  60. package/dist/runtime/transport.js +86 -0
  61. package/dist/runtime/transport.js.map +1 -0
  62. package/dist/runtime/validators.d.ts +131 -0
  63. package/dist/runtime/validators.d.ts.map +1 -0
  64. package/dist/runtime/validators.js +219 -0
  65. package/dist/runtime/validators.js.map +1 -0
  66. package/dist/runtime/worker-pool.d.ts +196 -0
  67. package/dist/runtime/worker-pool.d.ts.map +1 -0
  68. package/dist/runtime/worker-pool.js +371 -0
  69. package/dist/runtime/worker-pool.js.map +1 -0
  70. package/dist/utils/codec.d.ts.map +1 -1
  71. package/dist/utils/codec.js +120 -1
  72. package/dist/utils/codec.js.map +1 -1
  73. package/package.json +2 -2
  74. package/runtime/python_bridge.py +30 -3
  75. package/runtime/safe_codec.py +344 -0
  76. package/src/index.ts +48 -5
  77. package/src/runtime/base.ts +18 -26
  78. package/src/runtime/bounded-context.ts +608 -0
  79. package/src/runtime/bridge-protocol.ts +319 -0
  80. package/src/runtime/disposable.ts +65 -0
  81. package/src/runtime/http-io.ts +244 -0
  82. package/src/runtime/http.ts +71 -117
  83. package/src/runtime/node.ts +460 -217
  84. package/src/runtime/optimized-node.ts +19 -761
  85. package/src/runtime/pooled-transport.ts +252 -0
  86. package/src/runtime/process-io.ts +902 -0
  87. package/src/runtime/pyodide-io.ts +485 -0
  88. package/src/runtime/pyodide.ts +75 -215
  89. package/src/runtime/safe-codec.ts +443 -0
  90. package/src/runtime/transport.ts +273 -0
  91. package/src/runtime/validators.ts +241 -0
  92. package/src/runtime/worker-pool.ts +498 -0
  93. package/src/utils/codec.ts +126 -1
@@ -1,22 +1,56 @@
1
1
  /**
2
- * HTTP runtime bridge
2
+ * HTTP runtime bridge for BridgeProtocol.
3
+ *
4
+ * HttpBridge extends BridgeProtocol and uses HttpIO transport for
5
+ * stateless HTTP POST-based communication with a Python server.
6
+ *
7
+ * @see https://github.com/bbopen/tywrap/issues/149
8
+ */
9
+ import { BridgeProtocol } from './bridge-protocol.js';
10
+ import type { CodecOptions } from './safe-codec.js';
11
+ /**
12
+ * Configuration options for HttpBridge.
3
13
  */
4
- import { RuntimeBridge } from './base.js';
5
14
  export interface HttpBridgeOptions {
15
+ /** Base URL for the Python server (e.g., 'http://localhost:8000') */
6
16
  baseURL: string;
17
+ /** Additional headers to include in each request */
7
18
  headers?: Record<string, string>;
19
+ /** Timeout in ms for requests. Default: 30000 (30 seconds) */
8
20
  timeoutMs?: number;
21
+ /** Codec options for validation/serialization */
22
+ codec?: CodecOptions;
9
23
  }
10
- export declare class HttpBridge extends RuntimeBridge {
11
- private readonly baseURL;
12
- private readonly headers;
13
- private readonly timeoutMs;
14
- constructor(options?: HttpBridgeOptions);
15
- call<T = unknown>(module: string, functionName: string, args: unknown[], kwargs?: Record<string, unknown>): Promise<T>;
16
- instantiate<T = unknown>(module: string, className: string, args: unknown[], kwargs?: Record<string, unknown>): Promise<T>;
17
- callMethod<T = unknown>(handle: string, methodName: string, args: unknown[], kwargs?: Record<string, unknown>): Promise<T>;
18
- disposeInstance(handle: string): Promise<void>;
19
- dispose(): Promise<void>;
20
- private post;
24
+ /**
25
+ * HTTP-based runtime bridge for executing Python code.
26
+ *
27
+ * HttpBridge provides a stateless HTTP transport for communication with
28
+ * a Python server. Each request is independent - no connection state is
29
+ * maintained between calls.
30
+ *
31
+ * Features:
32
+ * - Stateless HTTP POST communication
33
+ * - Timeout handling via AbortController
34
+ * - Full SafeCodec validation (NaN/Infinity rejection, key validation)
35
+ * - Automatic Arrow decoding for DataFrames/ndarrays
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const bridge = new HttpBridge({ baseURL: 'http://localhost:8000' });
40
+ * await bridge.init();
41
+ *
42
+ * const result = await bridge.call('math', 'sqrt', [16]);
43
+ * console.log(result); // 4.0
44
+ *
45
+ * await bridge.dispose();
46
+ * ```
47
+ */
48
+ export declare class HttpBridge extends BridgeProtocol {
49
+ /**
50
+ * Create a new HttpBridge instance.
51
+ *
52
+ * @param options - Configuration options for the bridge
53
+ */
54
+ constructor(options: HttpBridgeOptions);
21
55
  }
22
56
  //# sourceMappingURL=http.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/runtime/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2BD,qBAAa,UAAW,SAAQ,aAAa;IAC3C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,GAAE,iBAAwD;IAOvE,IAAI,CAAC,CAAC,GAAG,OAAO,EACpB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,OAAO,EAAE,EACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,CAAC,CAAC;IAMP,WAAW,CAAC,CAAC,GAAG,OAAO,EAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO,EAAE,EACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,CAAC,CAAC;IAMP,UAAU,CAAC,CAAC,GAAG,OAAO,EAC1B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,OAAO,EAAE,EACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,CAAC,CAAC;IAMP,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAIhB,IAAI;CA8BnB"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/runtime/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAA8B,MAAM,sBAAsB,CAAC;AAElF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAMpD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAEhB,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,iDAAiD;IACjD,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,UAAW,SAAQ,cAAc;IAC5C;;;;OAIG;gBACS,OAAO,EAAE,iBAAiB;CAiBvC"}
@@ -1,79 +1,60 @@
1
1
  /**
2
- * HTTP runtime bridge
2
+ * HTTP runtime bridge for BridgeProtocol.
3
+ *
4
+ * HttpBridge extends BridgeProtocol and uses HttpIO transport for
5
+ * stateless HTTP POST-based communication with a Python server.
6
+ *
7
+ * @see https://github.com/bbopen/tywrap/issues/149
3
8
  */
4
- import { decodeValueAsync } from '../utils/codec.js';
5
- import { RuntimeBridge } from './base.js';
6
- export class HttpBridge extends RuntimeBridge {
7
- baseURL;
8
- headers;
9
- timeoutMs;
10
- constructor(options = { baseURL: 'http://localhost:8000' }) {
11
- super();
12
- this.baseURL = options.baseURL.replace(/\/$/, '');
13
- this.headers = { 'content-type': 'application/json', ...(options.headers ?? {}) };
14
- this.timeoutMs = options.timeoutMs ?? 30000;
15
- }
16
- async call(module, functionName, args, kwargs) {
17
- const payload = { module, functionName, args, kwargs };
18
- const res = await this.post(`${this.baseURL}/call`, payload);
19
- return (await decodeValueAsync(res));
20
- }
21
- async instantiate(module, className, args, kwargs) {
22
- const payload = { module, className, args, kwargs };
23
- const res = await this.post(`${this.baseURL}/instantiate`, payload);
24
- return (await decodeValueAsync(res));
25
- }
26
- async callMethod(handle, methodName, args, kwargs) {
27
- const payload = { handle, methodName, args, kwargs };
28
- const res = await this.post(`${this.baseURL}/call_method`, payload);
29
- return (await decodeValueAsync(res));
30
- }
31
- async disposeInstance(handle) {
32
- const payload = { handle };
33
- await this.post(`${this.baseURL}/dispose_instance`, payload);
34
- }
35
- async dispose() {
36
- // stateless
37
- }
38
- async post(url, body) {
39
- const controller = typeof AbortController !== 'undefined' ? new AbortController() : undefined;
40
- const timer = controller ? setTimeout(() => controller.abort(), this.timeoutMs) : undefined;
41
- try {
42
- const resp = await fetch(url, {
43
- method: 'POST',
44
- headers: this.headers,
45
- body: JSON.stringify(body),
46
- signal: controller?.signal,
47
- });
48
- if (!resp.ok) {
49
- const text = await safeText(resp);
50
- throw new Error(`HTTP ${resp.status}: ${text || resp.statusText}`);
51
- }
52
- const ct = resp.headers.get('content-type') ?? '';
53
- if (ct.includes('application/json')) {
54
- return (await resp.json());
55
- }
56
- const text = await resp.text();
57
- try {
58
- return JSON.parse(text);
59
- }
60
- catch {
61
- return text;
62
- }
63
- }
64
- finally {
65
- if (timer) {
66
- clearTimeout(timer);
67
- }
68
- }
69
- }
70
- }
71
- async function safeText(resp) {
72
- try {
73
- return await resp.text();
74
- }
75
- catch {
76
- return '';
9
+ import { BridgeProtocol } from './bridge-protocol.js';
10
+ import { HttpIO } from './http-io.js';
11
+ // =============================================================================
12
+ // HTTP BRIDGE
13
+ // =============================================================================
14
+ /**
15
+ * HTTP-based runtime bridge for executing Python code.
16
+ *
17
+ * HttpBridge provides a stateless HTTP transport for communication with
18
+ * a Python server. Each request is independent - no connection state is
19
+ * maintained between calls.
20
+ *
21
+ * Features:
22
+ * - Stateless HTTP POST communication
23
+ * - Timeout handling via AbortController
24
+ * - Full SafeCodec validation (NaN/Infinity rejection, key validation)
25
+ * - Automatic Arrow decoding for DataFrames/ndarrays
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const bridge = new HttpBridge({ baseURL: 'http://localhost:8000' });
30
+ * await bridge.init();
31
+ *
32
+ * const result = await bridge.call('math', 'sqrt', [16]);
33
+ * console.log(result); // 4.0
34
+ *
35
+ * await bridge.dispose();
36
+ * ```
37
+ */
38
+ export class HttpBridge extends BridgeProtocol {
39
+ /**
40
+ * Create a new HttpBridge instance.
41
+ *
42
+ * @param options - Configuration options for the bridge
43
+ */
44
+ constructor(options) {
45
+ // Create HTTP transport
46
+ const transport = new HttpIO({
47
+ baseURL: options.baseURL,
48
+ headers: options.headers,
49
+ defaultTimeoutMs: options.timeoutMs,
50
+ });
51
+ // Initialize BridgeProtocol with transport and codec options
52
+ const protocolOptions = {
53
+ transport,
54
+ codec: options.codec,
55
+ defaultTimeoutMs: options.timeoutMs,
56
+ };
57
+ super(protocolOptions);
77
58
  }
78
59
  }
79
60
  //# sourceMappingURL=http.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/runtime/http.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/runtime/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAA8B,MAAM,sBAAsB,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAwBtC,gFAAgF;AAChF,cAAc;AACd,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,OAAO,UAAW,SAAQ,cAAc;IAC5C;;;;OAIG;IACH,YAAY,OAA0B;QACpC,wBAAwB;QACxB,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC;YAC3B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,gBAAgB,EAAE,OAAO,CAAC,SAAS;SACpC,CAAC,CAAC;QAEH,6DAA6D;QAC7D,MAAM,eAAe,GAA0B;YAC7C,SAAS;YACT,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,gBAAgB,EAAE,OAAO,CAAC,SAAS;SACpC,CAAC;QAEF,KAAK,CAAC,eAAe,CAAC,CAAC;IACzB,CAAC;CACF"}
@@ -1,47 +1,161 @@
1
1
  /**
2
- * Node.js runtime bridge (minimal MVP)
2
+ * Node.js runtime bridge for BridgeProtocol.
3
+ *
4
+ * NodeBridge extends BridgeProtocol and uses ProcessIO transports with
5
+ * optional pooling for concurrent Python execution.
6
+ *
7
+ * @see https://github.com/bbopen/tywrap/issues/149
8
+ */
9
+ import { BridgeProtocol } from './bridge-protocol.js';
10
+ import type { CodecOptions } from './safe-codec.js';
11
+ /**
12
+ * Configuration options for NodeBridge.
3
13
  */
4
- import type { BridgeInfo } from '../types/index.js';
5
- import { RuntimeBridge } from './base.js';
6
14
  export interface NodeBridgeOptions {
15
+ /** Minimum number of Python processes to keep alive. Default: 1 */
16
+ minProcesses?: number;
17
+ /** Maximum number of Python processes to spawn. Default: 1 (single-process mode) */
18
+ maxProcesses?: number;
19
+ /** Maximum concurrent requests per process. Default: 10 */
20
+ maxConcurrentPerProcess?: number;
21
+ /** Path to Python executable. Auto-detected if not specified. */
7
22
  pythonPath?: string;
23
+ /** Path to python_bridge.py script. Auto-detected if not specified. */
8
24
  scriptPath?: string;
25
+ /** Path to Python virtual environment. */
9
26
  virtualEnv?: string;
27
+ /** Working directory for Python process. Default: process.cwd() */
10
28
  cwd?: string;
29
+ /** Timeout in ms for Python calls. Default: 30000 */
11
30
  timeoutMs?: number;
12
- maxLineLength?: number;
31
+ /** Timeout in ms for waiting in pool queue. Default: 30000 */
32
+ queueTimeoutMs?: number;
33
+ /** Inherit all environment variables from parent process. Default: false */
13
34
  inheritProcessEnv?: boolean;
35
+ /** Enable result caching for pure functions. Default: false */
36
+ enableCache?: boolean;
37
+ /** Optional extra environment variables to pass to the Python subprocess. */
38
+ env?: Record<string, string | undefined>;
39
+ /** Codec options for validation/serialization */
40
+ codec?: CodecOptions;
41
+ /** Commands to run on each process at startup for warming up. */
42
+ warmupCommands?: Array<{
43
+ module: string;
44
+ functionName: string;
45
+ args?: unknown[];
46
+ } | {
47
+ method: string;
48
+ params: unknown;
49
+ }>;
14
50
  /**
15
- * When true, sets TYWRAP_CODEC_FALLBACK=json for the Python process to prefer JSON encoding
16
- * for rich types (ndarray/dataframe/series). Default: false for fast-fail on Arrow path issues.
51
+ * @deprecated No longer used. Pool idle time is managed by WorkerPool.
52
+ */
53
+ maxIdleTime?: number;
54
+ /**
55
+ * @deprecated No longer used. Process restart is managed by ProcessIO.
56
+ */
57
+ maxRequestsPerProcess?: number;
58
+ /**
59
+ * @deprecated Use codec.bytesHandling option instead.
17
60
  */
18
61
  enableJsonFallback?: boolean;
19
62
  /**
20
- * Optional extra environment variables to pass to the Python subprocess.
63
+ * @deprecated Use ProcessIO options instead.
21
64
  */
22
- env?: Record<string, string | undefined>;
65
+ maxLineLength?: number;
23
66
  }
24
- export declare class NodeBridge extends RuntimeBridge {
25
- private child?;
26
- private core?;
27
- private readonly options;
28
- private disposed;
29
- private initPromise?;
30
- private bridgeInfo?;
67
+ /**
68
+ * Node.js runtime bridge for executing Python code.
69
+ *
70
+ * NodeBridge provides subprocess-based Python execution with optional pooling
71
+ * for high-throughput workloads. By default, it runs in single-process mode.
72
+ *
73
+ * Features:
74
+ * - Single or multi-process execution via process pooling
75
+ * - Virtual environment support
76
+ * - Full SafeCodec validation (NaN/Infinity rejection, key validation)
77
+ * - Automatic Arrow decoding for DataFrames/ndarrays
78
+ * - Optional result caching for pure functions
79
+ * - Process warmup commands
80
+ *
81
+ * @example
82
+ * ```typescript
83
+ * // Single-process mode (default)
84
+ * const bridge = new NodeBridge();
85
+ * await bridge.init();
86
+ *
87
+ * const result = await bridge.call('math', 'sqrt', [16]);
88
+ * console.log(result); // 4.0
89
+ *
90
+ * await bridge.dispose();
91
+ * ```
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * // Multi-process pooling for high throughput
96
+ * const pooledBridge = new NodeBridge({
97
+ * maxProcesses: 4,
98
+ * maxConcurrentPerProcess: 2,
99
+ * enableCache: true,
100
+ * });
101
+ * await pooledBridge.init();
102
+ * ```
103
+ */
104
+ export declare class NodeBridge extends BridgeProtocol {
105
+ private readonly resolvedOptions;
106
+ private readonly pooledTransport;
107
+ /**
108
+ * Create a new NodeBridge instance.
109
+ *
110
+ * @param options - Configuration options for the bridge
111
+ */
31
112
  constructor(options?: NodeBridgeOptions);
32
- init(): Promise<void>;
33
- getBridgeInfo(options?: {
34
- refresh?: boolean;
35
- }): Promise<BridgeInfo>;
113
+ /**
114
+ * Initialize the bridge.
115
+ *
116
+ * Validates the bridge script exists, registers Arrow decoder,
117
+ * and initializes the transport pool (which runs warmup commands per-worker).
118
+ */
119
+ protected doInit(): Promise<void>;
120
+ /**
121
+ * Override call() to add optional caching.
122
+ */
36
123
  call<T = unknown>(module: string, functionName: string, args: unknown[], kwargs?: Record<string, unknown>): Promise<T>;
37
- instantiate<T = unknown>(module: string, className: string, args: unknown[], kwargs?: Record<string, unknown>): Promise<T>;
38
- callMethod<T = unknown>(handle: string, methodName: string, args: unknown[], kwargs?: Record<string, unknown>): Promise<T>;
39
- disposeInstance(handle: string): Promise<void>;
40
- dispose(): Promise<void>;
41
- private send;
42
- private startProcess;
43
- private buildEnv;
44
- private resetProcess;
45
- private refreshBridgeInfo;
124
+ /**
125
+ * Get current pool statistics.
126
+ */
127
+ getPoolStats(): {
128
+ workerCount: number;
129
+ queueLength: number;
130
+ totalInFlight: number;
131
+ };
132
+ /**
133
+ * Get bridge statistics.
134
+ *
135
+ * @deprecated Use getPoolStats() instead. This method is provided for
136
+ * backwards compatibility and returns a subset of the previous stats.
137
+ */
138
+ getStats(): {
139
+ totalRequests: number;
140
+ totalTime: number;
141
+ cacheHits: number;
142
+ poolHits: number;
143
+ poolMisses: number;
144
+ processSpawns: number;
145
+ processDeaths: number;
146
+ memoryPeak: number;
147
+ averageTime: number;
148
+ cacheHitRate: number;
149
+ poolSize: number;
150
+ busyWorkers: number;
151
+ };
152
+ /**
153
+ * Generate a cache key, returning null if generation fails.
154
+ */
155
+ private safeCacheKey;
156
+ /**
157
+ * Heuristic to determine if function result should be cached.
158
+ */
159
+ private isPureFunctionCandidate;
46
160
  }
47
161
  //# sourceMappingURL=node.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/runtime/node.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAa1C,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC1C;AAoCD,qBAAa,UAAW,SAAQ,aAAa;IAC3C,OAAO,CAAC,KAAK,CAAC,CAAuC;IACrD,OAAO,CAAC,IAAI,CAAC,CAAa;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAC,CAAgB;IACpC,OAAO,CAAC,UAAU,CAAC,CAAa;gBAEpB,OAAO,GAAE,iBAAsB;IAoBrC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkBrB,aAAa,CAAC,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAWvE,IAAI,CAAC,CAAC,GAAG,OAAO,EACpB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,OAAO,EAAE,EACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,CAAC,CAAC;IAKP,WAAW,CAAC,CAAC,GAAG,OAAO,EAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,OAAO,EAAE,EACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,CAAC,CAAC;IAKP,UAAU,CAAC,CAAC,GAAG,OAAO,EAC1B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,OAAO,EAAE,EACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC,CAAC,CAAC;IAKP,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9C,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;YAMhB,IAAI;YAUJ,YAAY;IAwE1B,OAAO,CAAC,QAAQ;IAyChB,OAAO,CAAC,YAAY;YAiBN,iBAAiB;CAKhC"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/runtime/node.ts"],"names":[],"mappings":"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"}