tywrap 0.4.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.
Files changed (75) hide show
  1. package/README.md +1 -0
  2. package/dist/index.d.ts +3 -3
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +6 -6
  5. package/dist/index.js.map +1 -1
  6. package/dist/runtime/base.d.ts +7 -7
  7. package/dist/runtime/base.js +8 -8
  8. package/dist/runtime/bounded-context.d.ts +15 -31
  9. package/dist/runtime/bounded-context.d.ts.map +1 -1
  10. package/dist/runtime/bounded-context.js +16 -15
  11. package/dist/runtime/bounded-context.js.map +1 -1
  12. package/dist/runtime/http.d.ts +24 -5
  13. package/dist/runtime/http.d.ts.map +1 -1
  14. package/dist/runtime/http.js +57 -12
  15. package/dist/runtime/http.js.map +1 -1
  16. package/dist/runtime/node.d.ts +33 -7
  17. package/dist/runtime/node.d.ts.map +1 -1
  18. package/dist/runtime/node.js +139 -151
  19. package/dist/runtime/node.js.map +1 -1
  20. package/dist/runtime/pooled-transport.d.ts +2 -18
  21. package/dist/runtime/pooled-transport.d.ts.map +1 -1
  22. package/dist/runtime/pooled-transport.js +2 -29
  23. package/dist/runtime/pooled-transport.js.map +1 -1
  24. package/dist/runtime/process-io.d.ts +2 -18
  25. package/dist/runtime/process-io.d.ts.map +1 -1
  26. package/dist/runtime/process-io.js +3 -30
  27. package/dist/runtime/process-io.js.map +1 -1
  28. package/dist/runtime/pyodide-bootstrap-core.generated.d.ts +12 -0
  29. package/dist/runtime/pyodide-bootstrap-core.generated.d.ts.map +1 -0
  30. package/dist/runtime/pyodide-bootstrap-core.generated.js +12 -0
  31. package/dist/runtime/pyodide-bootstrap-core.generated.js.map +1 -0
  32. package/dist/runtime/pyodide-io.d.ts +7 -37
  33. package/dist/runtime/pyodide-io.d.ts.map +1 -1
  34. package/dist/runtime/pyodide-io.js +90 -214
  35. package/dist/runtime/pyodide-io.js.map +1 -1
  36. package/dist/runtime/pyodide.d.ts +25 -5
  37. package/dist/runtime/pyodide.d.ts.map +1 -1
  38. package/dist/runtime/pyodide.js +59 -10
  39. package/dist/runtime/pyodide.js.map +1 -1
  40. package/dist/runtime/{bridge-protocol.d.ts → rpc-client.d.ts} +59 -46
  41. package/dist/runtime/rpc-client.d.ts.map +1 -0
  42. package/dist/runtime/{bridge-protocol.js → rpc-client.js} +60 -42
  43. package/dist/runtime/rpc-client.js.map +1 -0
  44. package/dist/runtime/worker-pool.d.ts +2 -19
  45. package/dist/runtime/worker-pool.d.ts.map +1 -1
  46. package/dist/runtime/worker-pool.js +2 -30
  47. package/dist/runtime/worker-pool.js.map +1 -1
  48. package/dist/types/index.d.ts +8 -3
  49. package/dist/types/index.d.ts.map +1 -1
  50. package/package.json +10 -10
  51. package/runtime/__pycache__/safe_codec.cpython-311.pyc +0 -0
  52. package/runtime/__pycache__/tywrap_bridge_core.cpython-311.pyc +0 -0
  53. package/runtime/python_bridge.py +85 -702
  54. package/runtime/safe_codec.py +10 -2
  55. package/runtime/tywrap_bridge_core.py +875 -0
  56. package/src/index.ts +6 -6
  57. package/src/runtime/base.ts +8 -8
  58. package/src/runtime/bounded-context.ts +17 -56
  59. package/src/runtime/http.ts +85 -13
  60. package/src/runtime/node.ts +165 -217
  61. package/src/runtime/pooled-transport.ts +2 -57
  62. package/src/runtime/process-io.ts +3 -55
  63. package/src/runtime/pyodide-bootstrap-core.generated.ts +12 -0
  64. package/src/runtime/pyodide-io.ts +92 -243
  65. package/src/runtime/pyodide.ts +87 -10
  66. package/src/runtime/{bridge-protocol.ts → rpc-client.ts} +76 -49
  67. package/src/runtime/worker-pool.ts +2 -58
  68. package/src/types/index.ts +20 -4
  69. package/dist/runtime/bridge-core.d.ts +0 -65
  70. package/dist/runtime/bridge-core.d.ts.map +0 -1
  71. package/dist/runtime/bridge-core.js +0 -379
  72. package/dist/runtime/bridge-core.js.map +0 -1
  73. package/dist/runtime/bridge-protocol.d.ts.map +0 -1
  74. package/dist/runtime/bridge-protocol.js.map +0 -1
  75. package/src/runtime/bridge-core.ts +0 -494
@@ -1,24 +1,26 @@
1
1
  /**
2
- * BridgeProtocol - Unified abstraction for JS<->Python communication.
2
+ * RpcClient - the single correlated-RPC client for JS<->Python communication.
3
3
  *
4
- * Combines BoundedContext + SafeCodec + Transport into a single base class
5
- * that handles all cross-boundary concerns:
6
- * - Lifecycle management (init/dispose state machine)
7
- * - Request/response encoding with validation
8
- * - Transport-agnostic message passing
9
- * - Bounded execution (timeout, retry, abort)
4
+ * It HOLDS a Transport and a codec (SafeCodec) and is, in turn, HELD by the
5
+ * bridge facades (NodeBridge/HttpBridge/PyodideBridge) via composition — it is
6
+ * NOT a base class bridges extend. It owns the one place where the wire frame
7
+ * is built and correlated: id generation, {id, protocol} stamping, codec
8
+ * encode/decode, and transport.send. It composes DisposableBase to obtain its
9
+ * lifecycle (init/dispose) and bounded execution (timeout/retry/abort), but it
10
+ * carries no PythonRuntime contract obligation — the facade implements
11
+ * PythonRuntime and delegates the four RPC methods to this client.
10
12
  *
11
- * Subclasses (NodeBridge, HttpBridge, PyodideBridge) only need to:
12
- * 1. Create their transport in their constructor
13
- * 2. Pass it to super() via BridgeProtocolOptions
14
- * 3. Optionally override doInit() and doDispose() for additional setup/teardown
13
+ * Why composition (not inheritance): inheritance previously forced the RPC
14
+ * contract onto a lifecycle base, leaking throwing RPC stubs into transports.
15
+ * Holding one RpcClient keeps exactly one encode/decode/correlation site and
16
+ * lets transports stay pure byte-movers.
15
17
  *
16
18
  * @see https://github.com/bbopen/tywrap/issues/149
17
19
  */
18
20
 
19
21
  import type { BridgeInfo } from '../types/index.js';
20
22
 
21
- import { BoundedContext, type ExecuteOptions } from './bounded-context.js';
23
+ import { DisposableBase, type ExecuteOptions } from './bounded-context.js';
22
24
  import { BridgeProtocolError } from './errors.js';
23
25
  import { SafeCodec, type CodecOptions } from './safe-codec.js';
24
26
  import { TYWRAP_PROTOCOL_VERSION } from './protocol.js';
@@ -37,9 +39,9 @@ export interface GetBridgeInfoOptions {
37
39
  }
38
40
 
39
41
  /**
40
- * Configuration options for BridgeProtocol.
42
+ * Configuration options for RpcClient.
41
43
  */
42
- export interface BridgeProtocolOptions {
44
+ export interface RpcClientOptions {
43
45
  /** The transport to use for communication */
44
46
  transport: Transport;
45
47
 
@@ -174,43 +176,37 @@ function validateBridgeInfoPayload(value: unknown): BridgeInfo {
174
176
  }
175
177
 
176
178
  // =============================================================================
177
- // BRIDGE PROTOCOL BASE CLASS
179
+ // RPC CLIENT
178
180
  // =============================================================================
179
181
 
180
182
  /**
181
- * BridgeProtocol combines BoundedContext + SafeCodec + Transport
182
- * into a unified abstraction for all JS<->Python communication.
183
- *
184
- * This class provides:
185
- * - Automatic transport lifecycle management
186
- * - Request encoding with guardrails (special float rejection, key validation)
187
- * - Response decoding with Arrow support
188
- * - Full RuntimeExecution interface implementation
189
- *
190
- * Subclasses should:
191
- * 1. Create their transport in their constructor
192
- * 2. Pass it to super() via BridgeProtocolOptions
193
- * 3. Optionally override doInit() and doDispose() for additional setup/teardown
183
+ * RpcClient holds a SafeCodec + Transport and composes DisposableBase for
184
+ * lifecycle/bounded-execution. It is the one correlated-RPC client; bridge
185
+ * facades HOLD an instance and delegate their PythonRuntime methods to it.
194
186
  *
195
187
  * @example
196
188
  * ```typescript
197
- * class NodeBridge extends BridgeProtocol {
189
+ * class NodeBridge extends DisposableBase implements PythonRuntime {
190
+ * private readonly rpc: RpcClient;
198
191
  * constructor(options: NodeBridgeOptions) {
192
+ * super();
199
193
  * const transport = new ProcessIO(options);
200
- * super({ transport, defaultTimeoutMs: options.timeout });
194
+ * this.rpc = new RpcClient({ transport, defaultTimeoutMs: options.timeout });
195
+ * this.trackResource(this.rpc);
201
196
  * }
197
+ * // call/instantiate/callMethod/disposeInstance delegate to this.rpc.*
202
198
  * }
203
199
  * ```
204
200
  */
205
- export class BridgeProtocol extends BoundedContext {
201
+ export class RpcClient extends DisposableBase {
206
202
  /** Codec instance for validation and serialization */
207
- protected readonly codec: SafeCodec;
203
+ readonly codec: SafeCodec;
208
204
 
209
205
  /** Transport instance for message passing */
210
- protected readonly transport: Transport;
206
+ readonly transport: Transport;
211
207
 
212
208
  /** Default timeout for operations in milliseconds */
213
- protected readonly defaultTimeoutMs: number;
209
+ readonly defaultTimeoutMs: number;
214
210
 
215
211
  /** Counter for generating unique request IDs */
216
212
  private requestId = 0;
@@ -219,11 +215,11 @@ export class BridgeProtocol extends BoundedContext {
219
215
  private bridgeInfoCache?: BridgeInfo;
220
216
 
221
217
  /**
222
- * Create a new BridgeProtocol instance.
218
+ * Create a new RpcClient instance.
223
219
  *
224
220
  * @param options - Configuration options including transport and codec settings
225
221
  */
226
- constructor(options: BridgeProtocolOptions) {
222
+ constructor(options: RpcClientOptions) {
227
223
  super();
228
224
  this.codec = new SafeCodec(options.codec);
229
225
  this.transport = options.transport;
@@ -238,26 +234,22 @@ export class BridgeProtocol extends BoundedContext {
238
234
  // ===========================================================================
239
235
 
240
236
  /**
241
- * Initialize the protocol.
242
- *
243
- * Initializes the underlying transport. Subclasses can override this
244
- * to add additional initialization logic, but must call super.doInit().
237
+ * Initialize the client by initializing the underlying transport.
238
+ * Driven by the holding facade's lifecycle (facade.init() -> rpc.init()).
245
239
  */
246
240
  protected async doInit(): Promise<void> {
247
241
  await this.transport.init();
248
242
  }
249
243
 
250
244
  /**
251
- * Dispose the protocol.
245
+ * Dispose the client.
252
246
  *
253
- * The transport is tracked as a resource and will be disposed automatically
254
- * by BoundedContext. Subclasses can override this to add additional cleanup,
255
- * but should not need to dispose the transport manually.
247
+ * The transport is tracked as a resource and is disposed automatically by
248
+ * DisposableBase. Here we only clear the cached bridge info.
256
249
  */
257
250
  protected async doDispose(): Promise<void> {
258
251
  this.bridgeInfoCache = undefined;
259
- // Transport is tracked and will be disposed by BoundedContext
260
- // Subclasses can override to add additional cleanup
252
+ // Transport is tracked and will be disposed by DisposableBase.
261
253
  }
262
254
 
263
255
  // ===========================================================================
@@ -281,7 +273,7 @@ export class BridgeProtocol extends BoundedContext {
281
273
  * @throws BridgeExecutionError if Python returns an error
282
274
  * @throws BridgeTimeoutError if the operation times out
283
275
  */
284
- protected async sendMessage<T>(
276
+ async sendMessage<T>(
285
277
  message: Omit<ProtocolMessage, 'id' | 'protocol'>,
286
278
  options?: ExecuteOptions<T>
287
279
  ): Promise<T> {
@@ -321,7 +313,7 @@ export class BridgeProtocol extends BoundedContext {
321
313
  * @throws BridgeExecutionError if Python returns an error
322
314
  * @throws BridgeTimeoutError if the operation times out
323
315
  */
324
- protected async sendMessageAsync<T>(
316
+ async sendMessageAsync<T>(
325
317
  message: Omit<ProtocolMessage, 'id' | 'protocol'>,
326
318
  options?: ExecuteOptions<T>
327
319
  ): Promise<T> {
@@ -347,6 +339,41 @@ export class BridgeProtocol extends BoundedContext {
347
339
  }, options);
348
340
  }
349
341
 
342
+ /**
343
+ * Send a message over an EXPLICIT transport (not this.transport) with the
344
+ * same id-generation + codec encode/decode as the normal send path, but
345
+ * WITHOUT this.execute() and WITHOUT auto-init.
346
+ *
347
+ * This is the warmup path: NodeBridge runs warmup commands inside
348
+ * transport.init() (worker spawn -> onWorkerReady), which happens DURING
349
+ * rpc.init(). Routing those through this.execute() would auto-init this same
350
+ * client and re-await the in-flight init() that is itself waiting on warmup,
351
+ * deadlocking. So sendOn deliberately skips lifecycle: it only unifies the
352
+ * id counter + codec, never the state machine.
353
+ *
354
+ * @param transport - The specific worker transport to send on
355
+ * @param message - The protocol message (without id/protocol; stamped here)
356
+ * @param opts - Optional timeout / abort signal
357
+ */
358
+ async sendOn<T>(
359
+ transport: Transport,
360
+ message: Omit<ProtocolMessage, 'id' | 'protocol'>,
361
+ opts?: { timeoutMs?: number; signal?: AbortSignal }
362
+ ): Promise<T> {
363
+ const fullMessage: ProtocolMessage = {
364
+ ...message,
365
+ id: this.generateId(),
366
+ protocol: PROTOCOL_ID,
367
+ };
368
+ const encoded = this.codec.encodeRequest(fullMessage);
369
+ const responseStr = await transport.send(
370
+ encoded,
371
+ opts?.timeoutMs ?? this.defaultTimeoutMs,
372
+ opts?.signal
373
+ );
374
+ return this.codec.decodeResponseAsync<T>(responseStr);
375
+ }
376
+
350
377
  /**
351
378
  * Generate a unique request ID.
352
379
  *
@@ -358,7 +385,7 @@ export class BridgeProtocol extends BoundedContext {
358
385
  }
359
386
 
360
387
  // ===========================================================================
361
- // RUNTIME EXECUTION INTERFACE
388
+ // RPC METHODS (delegated to by the facade's PythonRuntime implementation)
362
389
  // ===========================================================================
363
390
 
364
391
  /**
@@ -7,7 +7,7 @@
7
7
  * @see https://github.com/bbopen/tywrap/issues/149
8
8
  */
9
9
 
10
- import { BoundedContext } from './bounded-context.js';
10
+ import { DisposableBase } from './bounded-context.js';
11
11
  import { BridgeTimeoutError, BridgeExecutionError, BridgeProtocolError } from './errors.js';
12
12
  import type { Transport } from './transport.js';
13
13
 
@@ -105,7 +105,7 @@ interface QueuedWaiter {
105
105
  * await pool.dispose();
106
106
  * ```
107
107
  */
108
- export class WorkerPool extends BoundedContext {
108
+ export class WorkerPool extends DisposableBase {
109
109
  private readonly options: Omit<
110
110
  Required<WorkerPoolOptions>,
111
111
  'onWorkerReady' | 'onReplacementWorkerReady'
@@ -535,60 +535,4 @@ export class WorkerPool extends BoundedContext {
535
535
  this.waitQueue.push({ resolve, reject, timer });
536
536
  });
537
537
  }
538
-
539
- // ===========================================================================
540
- // RUNTIME EXECUTION (Not implemented - WorkerPool is just for worker management)
541
- // ===========================================================================
542
-
543
- /**
544
- * Not implemented - WorkerPool does not execute Python calls directly.
545
- * Use the BridgeProtocol layer with a pooled worker's transport.
546
- */
547
- async call<T = unknown>(
548
- _module: string,
549
- _functionName: string,
550
- _args: unknown[],
551
- _kwargs?: Record<string, unknown>
552
- ): Promise<T> {
553
- throw new BridgeExecutionError(
554
- 'WorkerPool does not implement call() - use withWorker() to get a transport'
555
- );
556
- }
557
-
558
- /**
559
- * Not implemented - WorkerPool does not execute Python calls directly.
560
- */
561
- async instantiate<T = unknown>(
562
- _module: string,
563
- _className: string,
564
- _args: unknown[],
565
- _kwargs?: Record<string, unknown>
566
- ): Promise<T> {
567
- throw new BridgeExecutionError(
568
- 'WorkerPool does not implement instantiate() - use withWorker() to get a transport'
569
- );
570
- }
571
-
572
- /**
573
- * Not implemented - WorkerPool does not execute Python calls directly.
574
- */
575
- async callMethod<T = unknown>(
576
- _handle: string,
577
- _methodName: string,
578
- _args: unknown[],
579
- _kwargs?: Record<string, unknown>
580
- ): Promise<T> {
581
- throw new BridgeExecutionError(
582
- 'WorkerPool does not implement callMethod() - use withWorker() to get a transport'
583
- );
584
- }
585
-
586
- /**
587
- * Not implemented - WorkerPool does not execute Python calls directly.
588
- */
589
- async disposeInstance(_handle: string): Promise<void> {
590
- throw new BridgeExecutionError(
591
- 'WorkerPool does not implement disposeInstance() - use withWorker() to get a transport'
592
- );
593
- }
594
538
  }
@@ -364,12 +364,16 @@ export interface TypeMappingConfig {
364
364
  presets?: TypePreset[];
365
365
  }
366
366
 
367
+ /** Known bridge backends. Each speaks the identical "tywrap/1" protocol. */
368
+ export type BridgeBackend = 'python-subprocess' | 'pyodide' | 'http';
369
+
367
370
  export interface BridgeInfo {
368
371
  protocol: string;
369
372
  protocolVersion: number;
370
- bridge: 'python-subprocess';
373
+ bridge: BridgeBackend;
371
374
  pythonVersion: string;
372
- pid: number;
375
+ /** OS process id for subprocess backends; null for in-WASM (Pyodide). */
376
+ pid: number | null;
373
377
  codecFallback: 'json' | 'none';
374
378
  arrowAvailable: boolean;
375
379
  scipyAvailable: boolean;
@@ -424,8 +428,14 @@ export interface GenerationMetadata {
424
428
  optimizations: string[];
425
429
  }
426
430
 
427
- // Runtime bridge interface
428
- export interface RuntimeExecution {
431
+ // PythonRuntime the four cross-boundary RPC methods generated wrappers call.
432
+ // This is the contract that, after the composition rework, is implemented ONLY
433
+ // by the bridge facades (NodeBridge/HttpBridge/PyodideBridge); the facades
434
+ // satisfy it by delegating to an owned RpcClient. It deliberately carries NO
435
+ // lifecycle method — dispose() is a separate lifecycle concern (see Disposable
436
+ // in runtime/disposable.ts), so transports and the lifecycle base class
437
+ // (DisposableBase) never have to stub these methods.
438
+ export interface PythonRuntime {
429
439
  call<T = unknown>(
430
440
  module: string,
431
441
  functionName: string,
@@ -448,7 +458,13 @@ export interface RuntimeExecution {
448
458
  ): Promise<T>;
449
459
 
450
460
  disposeInstance(handle: string): Promise<void>;
461
+ }
451
462
 
463
+ // Runtime bridge interface — the four RPC methods plus lifecycle dispose().
464
+ // Kept as PythonRuntime + dispose() so getRuntimeBridge() and every existing
465
+ // `RuntimeExecution` reference (registry, dev.ts) compile with zero churn. The
466
+ // RuntimeExecution -> PythonRuntime symbol rename is deferred to the T9 pass.
467
+ export interface RuntimeExecution extends PythonRuntime {
452
468
  dispose(): Promise<void>;
453
469
  }
454
470
 
@@ -1,65 +0,0 @@
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 describeInvalidErrorPayload;
54
- private failRequest;
55
- private rejectAll;
56
- private handleProtocolError;
57
- private handleFatalError;
58
- }
59
- export declare function validateBridgeInfo(info: unknown): void;
60
- export declare function getPathKey(...envs: Array<Record<string, string | undefined>>): string;
61
- export declare function ensurePythonEncoding(env: NodeJS.ProcessEnv): void;
62
- export declare function ensureJsonFallback(env: NodeJS.ProcessEnv, enabled: boolean): void;
63
- export declare function getMaxLineLengthFromEnv(env: NodeJS.ProcessEnv): number | undefined;
64
- export declare function normalizeEnv(baseEnv: Record<string, string | undefined>, overrides: Record<string, string | undefined>): NodeJS.ProcessEnv;
65
- //# sourceMappingURL=bridge-core.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bridge-core.d.ts","sourceRoot":"","sources":["../../src/runtime/bridge-core.ts"],"names":[],"mappings":"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"}