tywrap 0.6.1 → 0.8.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 +15 -5
- package/dist/core/annotation-parser.d.ts.map +1 -1
- package/dist/core/annotation-parser.js.map +1 -1
- package/dist/core/emit-call.d.ts.map +1 -1
- package/dist/core/emit-call.js +1 -1
- package/dist/core/emit-call.js.map +1 -1
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/core/generator.js +40 -9
- package/dist/core/generator.js.map +1 -1
- package/dist/dev.d.ts.map +1 -1
- package/dist/dev.js +1 -3
- package/dist/dev.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/runtime/base-bridge.d.ts +57 -0
- package/dist/runtime/base-bridge.d.ts.map +1 -0
- package/dist/runtime/base-bridge.js +72 -0
- package/dist/runtime/base-bridge.js.map +1 -0
- package/dist/runtime/frame-codec.d.ts +111 -0
- package/dist/runtime/frame-codec.d.ts.map +1 -0
- package/dist/runtime/frame-codec.js +352 -0
- package/dist/runtime/frame-codec.js.map +1 -0
- package/dist/runtime/http-transport.d.ts +11 -1
- package/dist/runtime/http-transport.d.ts.map +1 -1
- package/dist/runtime/http-transport.js +19 -0
- package/dist/runtime/http-transport.js.map +1 -1
- package/dist/runtime/http.d.ts +5 -12
- package/dist/runtime/http.d.ts.map +1 -1
- package/dist/runtime/http.js +6 -29
- package/dist/runtime/http.js.map +1 -1
- package/dist/runtime/index.d.ts +2 -2
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/node.d.ts +25 -19
- package/dist/runtime/node.d.ts.map +1 -1
- package/dist/runtime/node.js +19 -34
- package/dist/runtime/node.js.map +1 -1
- package/dist/runtime/pooled-transport.d.ts +21 -2
- package/dist/runtime/pooled-transport.d.ts.map +1 -1
- package/dist/runtime/pooled-transport.js +16 -0
- package/dist/runtime/pooled-transport.js.map +1 -1
- package/dist/runtime/pyodide-bootstrap-core.generated.d.ts.map +1 -1
- package/dist/runtime/pyodide-bootstrap-core.generated.js +1 -1
- package/dist/runtime/pyodide-bootstrap-core.generated.js.map +1 -1
- package/dist/runtime/pyodide-transport.d.ts +12 -1
- package/dist/runtime/pyodide-transport.d.ts.map +1 -1
- package/dist/runtime/pyodide-transport.js +20 -0
- package/dist/runtime/pyodide-transport.js.map +1 -1
- package/dist/runtime/pyodide.d.ts +5 -12
- package/dist/runtime/pyodide.d.ts.map +1 -1
- package/dist/runtime/pyodide.js +6 -29
- package/dist/runtime/pyodide.js.map +1 -1
- package/dist/runtime/rpc-client.d.ts +14 -1
- package/dist/runtime/rpc-client.d.ts.map +1 -1
- package/dist/runtime/rpc-client.js +68 -6
- package/dist/runtime/rpc-client.js.map +1 -1
- package/dist/runtime/subprocess-transport.d.ts +177 -3
- package/dist/runtime/subprocess-transport.d.ts.map +1 -1
- package/dist/runtime/subprocess-transport.js +526 -26
- package/dist/runtime/subprocess-transport.js.map +1 -1
- package/dist/runtime/transport.d.ts +141 -0
- package/dist/runtime/transport.d.ts.map +1 -1
- package/dist/runtime/transport.js +21 -0
- package/dist/runtime/transport.js.map +1 -1
- package/dist/types/index.d.ts +59 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/tywrap.d.ts.map +1 -1
- package/dist/tywrap.js +204 -149
- package/dist/tywrap.js.map +1 -1
- package/dist/utils/codec.d.ts +2 -0
- package/dist/utils/codec.d.ts.map +1 -1
- package/dist/utils/codec.js +205 -6
- package/dist/utils/codec.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +7 -1
- package/runtime/__pycache__/_tywrap_conformance_chunking_fixtures.cpython-311.pyc +0 -0
- package/runtime/__pycache__/_tywrap_member_fixtures.cpython-311.pyc +0 -0
- package/runtime/__pycache__/_tywrap_w4_chunking_fixture.cpython-311.pyc +0 -0
- package/runtime/__pycache__/_tywrap_w5_request_chunking_fixture.cpython-311.pyc +0 -0
- package/runtime/__pycache__/_tywrap_w6_pool_chunking_fixture.cpython-311.pyc +0 -0
- package/runtime/__pycache__/frame_codec.cpython-311.pyc +0 -0
- package/runtime/__pycache__/safe_codec.cpython-311.pyc +0 -0
- package/runtime/__pycache__/tywrap_bridge_core.cpython-311.pyc +0 -0
- package/runtime/frame_codec.py +424 -0
- package/runtime/python_bridge.py +241 -42
- package/runtime/tywrap_bridge_core.py +152 -13
- package/src/core/annotation-parser.ts +2 -1
- package/src/core/emit-call.ts +1 -7
- package/src/core/generator.ts +50 -11
- package/src/dev.ts +1 -3
- package/src/index.ts +1 -0
- package/src/runtime/base-bridge.ts +106 -0
- package/src/runtime/frame-codec.ts +469 -0
- package/src/runtime/http-transport.ts +21 -1
- package/src/runtime/http.ts +7 -51
- package/src/runtime/index.ts +2 -6
- package/src/runtime/node.ts +42 -53
- package/src/runtime/pooled-transport.ts +25 -2
- package/src/runtime/pyodide-bootstrap-core.generated.ts +1 -1
- package/src/runtime/pyodide-transport.ts +22 -0
- package/src/runtime/pyodide.ts +7 -52
- package/src/runtime/rpc-client.ts +91 -7
- package/src/runtime/subprocess-transport.ts +629 -30
- package/src/runtime/transport.ts +169 -0
- package/src/types/index.ts +62 -0
- package/src/tywrap.ts +265 -162
- package/src/utils/codec.ts +245 -7
- package/src/version.ts +1 -1
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* @see https://github.com/bbopen/tywrap/issues/149
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
import type { BridgeInfo } from '../types/index.js';
|
|
21
|
+
import type { BridgeBackend, BridgeInfo, BridgeTransportInfo } from '../types/index.js';
|
|
22
22
|
|
|
23
23
|
import { DisposableBase, type ExecuteOptions } from './bounded-context.js';
|
|
24
24
|
import { BridgeProtocolError } from './errors.js';
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
PROTOCOL_ID,
|
|
28
28
|
TYWRAP_PROTOCOL_VERSION,
|
|
29
29
|
type Transport,
|
|
30
|
+
type TransportCapabilities,
|
|
30
31
|
type ProtocolMessage,
|
|
31
32
|
} from './transport.js';
|
|
32
33
|
|
|
@@ -74,8 +75,12 @@ function validateBridgeInfoPayload(value: unknown): BridgeInfo {
|
|
|
74
75
|
torchAvailable?: unknown;
|
|
75
76
|
sklearnAvailable?: unknown;
|
|
76
77
|
instances?: unknown;
|
|
78
|
+
transport?: unknown;
|
|
77
79
|
}
|
|
78
80
|
|
|
81
|
+
/** Honest set of backend identities a `meta` payload may report. */
|
|
82
|
+
const KNOWN_BRIDGES: readonly BridgeBackend[] = ['python-subprocess', 'pyodide', 'http'];
|
|
83
|
+
|
|
79
84
|
const formatValue = (val: unknown): string => {
|
|
80
85
|
try {
|
|
81
86
|
const serialized = JSON.stringify(val);
|
|
@@ -101,10 +106,16 @@ function validateBridgeInfoPayload(value: unknown): BridgeInfo {
|
|
|
101
106
|
);
|
|
102
107
|
}
|
|
103
108
|
|
|
109
|
+
// Accept the honest BridgeBackend union (subprocess/pyodide/http). All
|
|
110
|
+
// backends speak the identical "tywrap/1" protocol; relaxing this from the
|
|
111
|
+
// old hardcoded 'python-subprocess' lets the Pyodide/HTTP facades route
|
|
112
|
+
// getBridgeInfo() through this same validator without being rejected.
|
|
104
113
|
const bridge = obj.bridge;
|
|
105
|
-
if (bridge !== '
|
|
114
|
+
if (typeof bridge !== 'string' || !KNOWN_BRIDGES.includes(bridge as BridgeBackend)) {
|
|
106
115
|
throw new BridgeProtocolError(
|
|
107
|
-
`Invalid bridge info payload: bridge expected
|
|
116
|
+
`Invalid bridge info payload: bridge expected one of ${KNOWN_BRIDGES.map(b => `"${b}"`).join(
|
|
117
|
+
', '
|
|
118
|
+
)}, got ${formatValue(bridge)}`
|
|
108
119
|
);
|
|
109
120
|
}
|
|
110
121
|
|
|
@@ -115,10 +126,14 @@ function validateBridgeInfoPayload(value: unknown): BridgeInfo {
|
|
|
115
126
|
);
|
|
116
127
|
}
|
|
117
128
|
|
|
129
|
+
// pid is OPTIONAL across backends: subprocess reports a real OS pid (positive
|
|
130
|
+
// integer); in-WASM Pyodide (and HTTP) have no local process and report null.
|
|
131
|
+
// Accept a positive integer OR null; reject any other shape (e.g. 0, negative,
|
|
132
|
+
// non-integer, string).
|
|
118
133
|
const pid = obj.pid;
|
|
119
|
-
if (typeof pid !== 'number' || !Number.isInteger(pid) || pid <= 0) {
|
|
134
|
+
if (pid !== null && (typeof pid !== 'number' || !Number.isInteger(pid) || pid <= 0)) {
|
|
120
135
|
throw new BridgeProtocolError(
|
|
121
|
-
`Invalid bridge info payload: pid expected positive integer, got ${formatValue(pid)}`
|
|
136
|
+
`Invalid bridge info payload: pid expected positive integer or null, got ${formatValue(pid)}`
|
|
122
137
|
);
|
|
123
138
|
}
|
|
124
139
|
|
|
@@ -164,10 +179,59 @@ function validateBridgeInfoPayload(value: unknown): BridgeInfo {
|
|
|
164
179
|
);
|
|
165
180
|
}
|
|
166
181
|
|
|
167
|
-
|
|
182
|
+
// OPTIONAL chunked-transport negotiation block. Absent on old bridges and on
|
|
183
|
+
// HTTP/Pyodide (single-frame in 0.8.0) — absence is backward compatible. When
|
|
184
|
+
// present, validate every field and CARRY IT THROUGH so negotiation data
|
|
185
|
+
// survives the rebuild below (the old validator silently dropped unknown
|
|
186
|
+
// fields, which would have discarded this block).
|
|
187
|
+
let transport: BridgeTransportInfo | undefined;
|
|
188
|
+
const rawTransport = obj.transport;
|
|
189
|
+
if (rawTransport !== undefined) {
|
|
190
|
+
if (!rawTransport || typeof rawTransport !== 'object' || Array.isArray(rawTransport)) {
|
|
191
|
+
const kind =
|
|
192
|
+
rawTransport === null
|
|
193
|
+
? 'null'
|
|
194
|
+
: Array.isArray(rawTransport)
|
|
195
|
+
? 'array'
|
|
196
|
+
: typeof rawTransport;
|
|
197
|
+
throw new BridgeProtocolError(
|
|
198
|
+
`Invalid bridge info payload: transport expected object, got ${kind}`
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
const t = rawTransport as {
|
|
202
|
+
frameProtocol?: unknown;
|
|
203
|
+
supportsChunking?: unknown;
|
|
204
|
+
maxFrameBytes?: unknown;
|
|
205
|
+
};
|
|
206
|
+
const frameProtocol = t.frameProtocol;
|
|
207
|
+
if (typeof frameProtocol !== 'string' || frameProtocol.length === 0) {
|
|
208
|
+
throw new BridgeProtocolError(
|
|
209
|
+
`Invalid bridge info payload: transport.frameProtocol expected non-empty string, got ${formatValue(frameProtocol)}`
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
const supportsChunking = t.supportsChunking;
|
|
213
|
+
if (typeof supportsChunking !== 'boolean') {
|
|
214
|
+
throw new BridgeProtocolError(
|
|
215
|
+
`Invalid bridge info payload: transport.supportsChunking expected boolean, got ${formatValue(supportsChunking)}`
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
const maxFrameBytes = t.maxFrameBytes;
|
|
219
|
+
if (
|
|
220
|
+
typeof maxFrameBytes !== 'number' ||
|
|
221
|
+
!Number.isInteger(maxFrameBytes) ||
|
|
222
|
+
maxFrameBytes <= 0
|
|
223
|
+
) {
|
|
224
|
+
throw new BridgeProtocolError(
|
|
225
|
+
`Invalid bridge info payload: transport.maxFrameBytes expected positive integer, got ${formatValue(maxFrameBytes)}`
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
transport = { frameProtocol, supportsChunking, maxFrameBytes };
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const info: BridgeInfo = {
|
|
168
232
|
protocol: PROTOCOL_ID,
|
|
169
233
|
protocolVersion: TYWRAP_PROTOCOL_VERSION,
|
|
170
|
-
bridge:
|
|
234
|
+
bridge: bridge as BridgeBackend,
|
|
171
235
|
pythonVersion,
|
|
172
236
|
pid,
|
|
173
237
|
codecFallback,
|
|
@@ -177,6 +241,10 @@ function validateBridgeInfoPayload(value: unknown): BridgeInfo {
|
|
|
177
241
|
sklearnAvailable,
|
|
178
242
|
instances,
|
|
179
243
|
};
|
|
244
|
+
if (transport !== undefined) {
|
|
245
|
+
info.transport = transport;
|
|
246
|
+
}
|
|
247
|
+
return info;
|
|
180
248
|
}
|
|
181
249
|
|
|
182
250
|
// =============================================================================
|
|
@@ -518,4 +586,20 @@ export class RpcClient extends DisposableBase {
|
|
|
518
586
|
this.bridgeInfoCache = info;
|
|
519
587
|
return info;
|
|
520
588
|
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Report the underlying transport's static capability descriptor.
|
|
592
|
+
*
|
|
593
|
+
* This returns the transport-level flags (Arrow/binary carriage, framing,
|
|
594
|
+
* chunking/streaming, max frame size) WITHOUT any network round-trip — the
|
|
595
|
+
* descriptor is authoritative for what the wire channel can do. It is
|
|
596
|
+
* deliberately distinct from {@link getBridgeInfo}, which reports the *Python
|
|
597
|
+
* environment* (which optional libraries are importable). Callers that need
|
|
598
|
+
* both — "can this transport carry Arrow AND does this Python have pyarrow?" —
|
|
599
|
+
* should consult both: the transport descriptor for the channel, the bridge
|
|
600
|
+
* info for library availability.
|
|
601
|
+
*/
|
|
602
|
+
capabilities(): TransportCapabilities {
|
|
603
|
+
return this.transport.capabilities();
|
|
604
|
+
}
|
|
521
605
|
}
|