tywrap 0.3.0 → 0.5.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 +40 -5
- package/dist/cli.js +24 -6
- package/dist/cli.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +19 -13
- package/dist/config/index.js.map +1 -1
- package/dist/core/analyzer.d.ts.map +1 -1
- package/dist/core/analyzer.js +0 -1
- package/dist/core/analyzer.js.map +1 -1
- package/dist/dev.d.ts +57 -0
- package/dist/dev.d.ts.map +1 -0
- package/dist/dev.js +743 -0
- package/dist/dev.js.map +1 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/runtime/base.d.ts +7 -7
- package/dist/runtime/base.js +8 -8
- package/dist/runtime/bounded-context.d.ts +15 -31
- package/dist/runtime/bounded-context.d.ts.map +1 -1
- package/dist/runtime/bounded-context.js +16 -15
- package/dist/runtime/bounded-context.js.map +1 -1
- package/dist/runtime/http.d.ts +24 -5
- package/dist/runtime/http.d.ts.map +1 -1
- package/dist/runtime/http.js +57 -12
- package/dist/runtime/http.js.map +1 -1
- package/dist/runtime/node.d.ts +33 -7
- package/dist/runtime/node.d.ts.map +1 -1
- package/dist/runtime/node.js +144 -120
- package/dist/runtime/node.js.map +1 -1
- package/dist/runtime/optimized-node.d.ts +5 -4
- package/dist/runtime/optimized-node.d.ts.map +1 -1
- package/dist/runtime/optimized-node.js +5 -4
- package/dist/runtime/optimized-node.js.map +1 -1
- package/dist/runtime/pooled-transport.d.ts +2 -18
- package/dist/runtime/pooled-transport.d.ts.map +1 -1
- package/dist/runtime/pooled-transport.js +2 -29
- package/dist/runtime/pooled-transport.js.map +1 -1
- package/dist/runtime/process-io.d.ts +2 -18
- package/dist/runtime/process-io.d.ts.map +1 -1
- package/dist/runtime/process-io.js +3 -30
- package/dist/runtime/process-io.js.map +1 -1
- package/dist/runtime/pyodide-bootstrap-core.generated.d.ts +12 -0
- package/dist/runtime/pyodide-bootstrap-core.generated.d.ts.map +1 -0
- package/dist/runtime/pyodide-bootstrap-core.generated.js +12 -0
- package/dist/runtime/pyodide-bootstrap-core.generated.js.map +1 -0
- package/dist/runtime/pyodide-io.d.ts +7 -37
- package/dist/runtime/pyodide-io.d.ts.map +1 -1
- package/dist/runtime/pyodide-io.js +90 -214
- package/dist/runtime/pyodide-io.js.map +1 -1
- package/dist/runtime/pyodide.d.ts +25 -5
- package/dist/runtime/pyodide.d.ts.map +1 -1
- package/dist/runtime/pyodide.js +59 -10
- package/dist/runtime/pyodide.js.map +1 -1
- package/dist/runtime/{bridge-protocol.d.ts → rpc-client.d.ts} +59 -46
- package/dist/runtime/rpc-client.d.ts.map +1 -0
- package/dist/runtime/{bridge-protocol.js → rpc-client.js} +60 -42
- package/dist/runtime/rpc-client.js.map +1 -0
- package/dist/runtime/worker-pool.d.ts +8 -20
- package/dist/runtime/worker-pool.d.ts.map +1 -1
- package/dist/runtime/worker-pool.js +58 -59
- package/dist/runtime/worker-pool.js.map +1 -1
- package/dist/types/index.d.ts +8 -10
- package/dist/types/index.d.ts.map +1 -1
- package/dist/tywrap.d.ts +6 -0
- package/dist/tywrap.d.ts.map +1 -1
- package/dist/tywrap.js +10 -3
- package/dist/tywrap.js.map +1 -1
- package/package.json +22 -18
- package/runtime/__pycache__/safe_codec.cpython-311.pyc +0 -0
- package/runtime/__pycache__/tywrap_bridge_core.cpython-311.pyc +0 -0
- package/runtime/python_bridge.py +85 -702
- package/runtime/safe_codec.py +10 -2
- package/runtime/tywrap_bridge_core.py +875 -0
- package/src/cli.ts +27 -6
- package/src/config/index.ts +28 -15
- package/src/core/analyzer.ts +1 -2
- package/src/dev.ts +983 -0
- package/src/index.ts +7 -7
- package/src/runtime/base.ts +8 -8
- package/src/runtime/bounded-context.ts +17 -56
- package/src/runtime/http.ts +85 -13
- package/src/runtime/node.ts +172 -178
- package/src/runtime/optimized-node.ts +5 -4
- package/src/runtime/pooled-transport.ts +2 -57
- package/src/runtime/process-io.ts +3 -55
- package/src/runtime/pyodide-bootstrap-core.generated.ts +12 -0
- package/src/runtime/pyodide-io.ts +92 -243
- package/src/runtime/pyodide.ts +87 -10
- package/src/runtime/{bridge-protocol.ts → rpc-client.ts} +76 -49
- package/src/runtime/worker-pool.ts +67 -88
- package/src/types/index.ts +20 -12
- package/src/tywrap.ts +17 -3
- package/dist/runtime/bridge-core.d.ts +0 -65
- package/dist/runtime/bridge-core.d.ts.map +0 -1
- package/dist/runtime/bridge-core.js +0 -379
- package/dist/runtime/bridge-core.js.map +0 -1
- package/dist/runtime/bridge-protocol.d.ts.map +0 -1
- package/dist/runtime/bridge-protocol.js.map +0 -1
- package/src/runtime/bridge-core.ts +0 -494
package/src/index.ts
CHANGED
|
@@ -9,14 +9,14 @@ import { tywrap } from './tywrap.js';
|
|
|
9
9
|
|
|
10
10
|
export type { TywrapConfig, ResolvedTywrapConfig } from './config/index.js';
|
|
11
11
|
export { defineConfig, resolveConfig } from './config/index.js';
|
|
12
|
-
//
|
|
12
|
+
// DisposableBase - lifecycle/resource base for cross-boundary components
|
|
13
13
|
export {
|
|
14
|
-
|
|
14
|
+
DisposableBase,
|
|
15
15
|
type ContextState,
|
|
16
16
|
type ExecuteOptions,
|
|
17
17
|
} from './runtime/bounded-context.js';
|
|
18
|
-
//
|
|
19
|
-
export {
|
|
18
|
+
// RpcClient - the single correlated-RPC client (codec + transport), held by bridges
|
|
19
|
+
export { RpcClient, type RpcClientOptions } from './runtime/rpc-client.js';
|
|
20
20
|
// SafeCodec - validation and serialization for JS<->Python boundary
|
|
21
21
|
export { SafeCodec, type CodecOptions } from './runtime/safe-codec.js';
|
|
22
22
|
// Transport - abstract I/O channel interface
|
|
@@ -63,7 +63,7 @@ export {
|
|
|
63
63
|
} from './runtime/validators.js';
|
|
64
64
|
|
|
65
65
|
/**
|
|
66
|
-
* @deprecated Use
|
|
66
|
+
* @deprecated Use DisposableBase instead. RuntimeBridge will be removed in the next major version.
|
|
67
67
|
*/
|
|
68
68
|
export { RuntimeBridge } from './runtime/base.js';
|
|
69
69
|
|
|
@@ -77,7 +77,7 @@ export {
|
|
|
77
77
|
} from './runtime/errors.js';
|
|
78
78
|
export { getRuntimeBridge, setRuntimeBridge, clearRuntimeBridge } from './runtime/index.js';
|
|
79
79
|
|
|
80
|
-
// Runtime-specific exports (
|
|
80
|
+
// Runtime-specific exports (Bridge facades that HOLD an RpcClient)
|
|
81
81
|
export { NodeBridge, type NodeBridgeOptions } from './runtime/node.js';
|
|
82
82
|
export { PyodideBridge, type PyodideBridgeOptions } from './runtime/pyodide.js';
|
|
83
83
|
export { HttpBridge, type HttpBridgeOptions } from './runtime/http.js';
|
|
@@ -121,7 +121,6 @@ export type {
|
|
|
121
121
|
NodeConfig,
|
|
122
122
|
HttpConfig,
|
|
123
123
|
PerformanceConfig,
|
|
124
|
-
DevelopmentConfig,
|
|
125
124
|
TypeMappingConfig,
|
|
126
125
|
TypePreset,
|
|
127
126
|
BridgeInfo,
|
|
@@ -135,6 +134,7 @@ export type {
|
|
|
135
134
|
// Main API
|
|
136
135
|
export { tywrap } from './tywrap.js';
|
|
137
136
|
export { generate } from './tywrap.js';
|
|
137
|
+
export type { GenerateFailure, GenerateResult, GenerateRunOptions } from './tywrap.js';
|
|
138
138
|
|
|
139
139
|
// Runtime detection utilities
|
|
140
140
|
export { detectRuntime, isNodejs, isDeno, isBun, isBrowser } from './utils/runtime.js';
|
package/src/runtime/base.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Base runtime bridge
|
|
3
3
|
*
|
|
4
|
-
* @deprecated Use
|
|
4
|
+
* @deprecated Use DisposableBase instead. RuntimeBridge will be removed in the next major version.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { DisposableBase } from './bounded-context.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* @deprecated Use
|
|
10
|
+
* @deprecated Use DisposableBase instead. RuntimeBridge will be removed in the next major version.
|
|
11
11
|
*
|
|
12
|
-
* All bridges now
|
|
12
|
+
* All bridges now build on DisposableBase which provides:
|
|
13
13
|
* - Lifecycle management (init/dispose state machine)
|
|
14
14
|
* - Validation helpers
|
|
15
15
|
* - Error classification
|
|
16
16
|
* - Bounded execution (timeout, retry)
|
|
17
17
|
* - Resource ownership tracking
|
|
18
18
|
*
|
|
19
|
-
* @see
|
|
19
|
+
* @see DisposableBase
|
|
20
20
|
*/
|
|
21
|
-
export abstract class RuntimeBridge extends
|
|
21
|
+
export abstract class RuntimeBridge extends DisposableBase {}
|
|
22
22
|
|
|
23
|
-
// Re-export
|
|
24
|
-
export {
|
|
23
|
+
// Re-export DisposableBase for backwards compatibility
|
|
24
|
+
export { DisposableBase };
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* DisposableBase - Lifecycle-and-resource base for cross-boundary components.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* -
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* Provides ONLY: init/dispose state machine, validation helpers, error
|
|
5
|
+
* classification, bounded execution (timeout/retry/abort), and resource
|
|
6
|
+
* ownership tracking. It carries ZERO RPC methods by design — the
|
|
7
|
+
* cross-boundary RPC contract (call/instantiate/callMethod/disposeInstance)
|
|
8
|
+
* is PythonRuntime, implemented only by the bridge facades, never by a base
|
|
9
|
+
* class or a transport. This separation is what keeps transports (ProcessIO,
|
|
10
|
+
* PooledTransport, WorkerPool, PyodideIO) and RpcClient from having to stub
|
|
11
|
+
* RPC methods they do not implement.
|
|
10
12
|
*
|
|
11
|
-
*
|
|
13
|
+
* Reused by RpcClient and all transports.
|
|
12
14
|
*
|
|
13
15
|
* @see https://github.com/bbopen/tywrap/issues/149
|
|
14
16
|
*/
|
|
15
17
|
|
|
16
|
-
import type { RuntimeExecution } from '../types/index.js';
|
|
17
18
|
import {
|
|
18
19
|
BridgeDisposedError,
|
|
19
20
|
BridgeError,
|
|
@@ -36,7 +37,7 @@ import {
|
|
|
36
37
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
|
-
* Lifecycle states for a
|
|
40
|
+
* Lifecycle states for a DisposableBase.
|
|
40
41
|
*
|
|
41
42
|
* State transitions:
|
|
42
43
|
* - idle → initializing → ready (on successful init)
|
|
@@ -63,16 +64,15 @@ export interface ExecuteOptions<T = unknown> {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
66
|
-
//
|
|
67
|
+
// DISPOSABLE BASE CLASS
|
|
67
68
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
68
69
|
|
|
69
70
|
/**
|
|
70
|
-
* Abstract base
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* bounded execution, and resource tracking.
|
|
71
|
+
* Abstract lifecycle/resource base. Provides lifecycle management, validation,
|
|
72
|
+
* error classification, bounded execution, and resource tracking — and nothing
|
|
73
|
+
* about RPC. See the file header for the DisposableBase vs PythonRuntime split.
|
|
74
74
|
*/
|
|
75
|
-
export abstract class
|
|
75
|
+
export abstract class DisposableBase {
|
|
76
76
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
77
77
|
// STATE
|
|
78
78
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -103,7 +103,7 @@ export abstract class BoundedContext implements RuntimeExecution {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
106
|
-
// LIFECYCLE
|
|
106
|
+
// LIFECYCLE
|
|
107
107
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
108
108
|
|
|
109
109
|
/**
|
|
@@ -566,43 +566,4 @@ export abstract class BoundedContext implements RuntimeExecution {
|
|
|
566
566
|
protected get resourceCount(): number {
|
|
567
567
|
return this._resources.size;
|
|
568
568
|
}
|
|
569
|
-
|
|
570
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
571
|
-
// ABSTRACT METHODS (RuntimeExecution interface)
|
|
572
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
573
|
-
|
|
574
|
-
/**
|
|
575
|
-
* Call a Python function.
|
|
576
|
-
*/
|
|
577
|
-
abstract call<T = unknown>(
|
|
578
|
-
module: string,
|
|
579
|
-
functionName: string,
|
|
580
|
-
args: unknown[],
|
|
581
|
-
kwargs?: Record<string, unknown>
|
|
582
|
-
): Promise<T>;
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
* Instantiate a Python class.
|
|
586
|
-
*/
|
|
587
|
-
abstract instantiate<T = unknown>(
|
|
588
|
-
module: string,
|
|
589
|
-
className: string,
|
|
590
|
-
args: unknown[],
|
|
591
|
-
kwargs?: Record<string, unknown>
|
|
592
|
-
): Promise<T>;
|
|
593
|
-
|
|
594
|
-
/**
|
|
595
|
-
* Call a method on a Python instance.
|
|
596
|
-
*/
|
|
597
|
-
abstract callMethod<T = unknown>(
|
|
598
|
-
handle: string,
|
|
599
|
-
methodName: string,
|
|
600
|
-
args: unknown[],
|
|
601
|
-
kwargs?: Record<string, unknown>
|
|
602
|
-
): Promise<T>;
|
|
603
|
-
|
|
604
|
-
/**
|
|
605
|
-
* Dispose a Python instance.
|
|
606
|
-
*/
|
|
607
|
-
abstract disposeInstance(handle: string): Promise<void>;
|
|
608
569
|
}
|
package/src/runtime/http.ts
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* HTTP runtime bridge
|
|
2
|
+
* HTTP runtime bridge.
|
|
3
3
|
*
|
|
4
|
-
* HttpBridge
|
|
5
|
-
*
|
|
4
|
+
* HttpBridge is a thin facade: it extends DisposableBase (lifecycle/resources)
|
|
5
|
+
* and implements PythonRuntime by HOLDING an RpcClient over an HttpIO transport
|
|
6
|
+
* for stateless HTTP POST-based communication with a Python server.
|
|
6
7
|
*
|
|
7
8
|
* @see https://github.com/bbopen/tywrap/issues/149
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
|
-
import {
|
|
11
|
+
import type { PythonRuntime, BridgeInfo } from '../types/index.js';
|
|
12
|
+
import { autoRegisterArrowDecoder } from '../utils/codec.js';
|
|
13
|
+
|
|
14
|
+
import { DisposableBase } from './bounded-context.js';
|
|
15
|
+
import { RpcClient, type GetBridgeInfoOptions } from './rpc-client.js';
|
|
11
16
|
import { HttpIO } from './http-io.js';
|
|
12
17
|
import type { CodecOptions } from './safe-codec.js';
|
|
13
|
-
import { autoRegisterArrowDecoder } from '../utils/codec.js';
|
|
14
18
|
|
|
15
19
|
// =============================================================================
|
|
16
20
|
// OPTIONS
|
|
@@ -61,33 +65,101 @@ export interface HttpBridgeOptions {
|
|
|
61
65
|
* await bridge.dispose();
|
|
62
66
|
* ```
|
|
63
67
|
*/
|
|
64
|
-
export class HttpBridge extends
|
|
68
|
+
export class HttpBridge extends DisposableBase implements PythonRuntime {
|
|
69
|
+
private readonly rpc: RpcClient;
|
|
70
|
+
|
|
65
71
|
/**
|
|
66
72
|
* Create a new HttpBridge instance.
|
|
67
73
|
*
|
|
68
74
|
* @param options - Configuration options for the bridge
|
|
69
75
|
*/
|
|
70
76
|
constructor(options: HttpBridgeOptions) {
|
|
71
|
-
|
|
77
|
+
super();
|
|
78
|
+
|
|
72
79
|
const transport = new HttpIO({
|
|
73
80
|
baseURL: options.baseURL,
|
|
74
81
|
headers: options.headers,
|
|
75
82
|
defaultTimeoutMs: options.timeoutMs,
|
|
76
83
|
});
|
|
77
84
|
|
|
78
|
-
|
|
79
|
-
const protocolOptions: BridgeProtocolOptions = {
|
|
85
|
+
this.rpc = new RpcClient({
|
|
80
86
|
transport,
|
|
81
87
|
codec: options.codec,
|
|
82
88
|
defaultTimeoutMs: options.timeoutMs,
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
|
|
89
|
+
});
|
|
90
|
+
// One disposal chain: facade -> rpc -> transport.
|
|
91
|
+
this.trackResource(this.rpc);
|
|
86
92
|
}
|
|
87
93
|
|
|
94
|
+
// ===========================================================================
|
|
95
|
+
// LIFECYCLE
|
|
96
|
+
// ===========================================================================
|
|
97
|
+
|
|
88
98
|
protected async doInit(): Promise<void> {
|
|
89
99
|
// Best-effort: keep apache-arrow optional and avoid breaking non-Node runtimes.
|
|
90
100
|
await autoRegisterArrowDecoder();
|
|
91
|
-
await
|
|
101
|
+
await this.rpc.init();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* No facade-specific teardown: the RpcClient (and its transport) is tracked
|
|
106
|
+
* as a resource and disposed automatically by DisposableBase.
|
|
107
|
+
*/
|
|
108
|
+
protected async doDispose(): Promise<void> {
|
|
109
|
+
// Intentionally empty; tracked resources handle disposal.
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// ===========================================================================
|
|
113
|
+
// RPC METHODS (delegate to the held RpcClient)
|
|
114
|
+
// ===========================================================================
|
|
115
|
+
|
|
116
|
+
async call<T = unknown>(
|
|
117
|
+
module: string,
|
|
118
|
+
functionName: string,
|
|
119
|
+
args: unknown[],
|
|
120
|
+
kwargs?: Record<string, unknown>
|
|
121
|
+
): Promise<T> {
|
|
122
|
+
await this.ensureReady();
|
|
123
|
+
return this.rpc.call<T>(module, functionName, args, kwargs);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async instantiate<T = unknown>(
|
|
127
|
+
module: string,
|
|
128
|
+
className: string,
|
|
129
|
+
args: unknown[],
|
|
130
|
+
kwargs?: Record<string, unknown>
|
|
131
|
+
): Promise<T> {
|
|
132
|
+
await this.ensureReady();
|
|
133
|
+
return this.rpc.instantiate<T>(module, className, args, kwargs);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async callMethod<T = unknown>(
|
|
137
|
+
handle: string,
|
|
138
|
+
methodName: string,
|
|
139
|
+
args: unknown[],
|
|
140
|
+
kwargs?: Record<string, unknown>
|
|
141
|
+
): Promise<T> {
|
|
142
|
+
await this.ensureReady();
|
|
143
|
+
return this.rpc.callMethod<T>(handle, methodName, args, kwargs);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async disposeInstance(handle: string): Promise<void> {
|
|
147
|
+
await this.ensureReady();
|
|
148
|
+
return this.rpc.disposeInstance(handle);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async getBridgeInfo(options?: GetBridgeInfoOptions): Promise<BridgeInfo> {
|
|
152
|
+
await this.ensureReady();
|
|
153
|
+
return this.rpc.getBridgeInfo(options);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Ensure the facade is initialized before delegating an RPC, replicating the
|
|
158
|
+
* auto-init that the bounded execute path provided pre-composition.
|
|
159
|
+
*/
|
|
160
|
+
private async ensureReady(): Promise<void> {
|
|
161
|
+
if (!this.isReady) {
|
|
162
|
+
await this.init();
|
|
163
|
+
}
|
|
92
164
|
}
|
|
93
165
|
}
|