Skip to content

Commit b8458a5

Browse files
authored
Merge pull request #290 from bbopen/docs/0.9-261-type-coverage
docs: describe type coverage accurately in docs and metadata
2 parents 2a41293 + 31e077c commit b8458a5

11 files changed

Lines changed: 272 additions & 233 deletions

File tree

README.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,25 @@
99
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)
1010
[![Docs](https://img.shields.io/badge/docs-bbopen.github.io%2Ftywrap-blue)](https://bbopen.github.io/tywrap)
1111

12-
TypeScript wrapper for Python libraries with full type safety.
12+
TypeScript bindings for Python libraries, with precise types for fully
13+
annotated, in-module, serializable Python returns and fallbacks where tywrap
14+
cannot resolve a type.
1315

1416
> **⚠️ Experimental** — APIs may change before v1.0.0. See the
1517
> [releases page](https://github.com/bbopen/tywrap/releases) for breaking
1618
> changes.
1719
1820
## Features
1921

20-
- **Full Type Safety** - TypeScript definitions generated from Python source
21-
analysis
22+
- **Accurate Type Coverage** - Precise TypeScript types for fully annotated,
23+
in-module, serializable Python returns, with fallbacks where resolution is not
24+
possible
2225
- **Development Hot Reload** - Real Node watch sessions regenerate wrappers and
2326
swap the active bridge without re-importing generated modules
2427
- **Generic-Aware Declarations** - Preserves simple `TypeVar` and callable
2528
`ParamSpec` generics in generated `.ts` and `.d.ts` output
26-
- **Multi-Runtime** - Node.js (subprocess) and browsers (Pyodide)
29+
- **Multi-Runtime** - Node.js and Bun (subprocess), browsers (Pyodide), and
30+
experimental, untested-in-CI Deno subprocess support
2731
- **Rich Data Types** - numpy, pandas, scipy, torch, sklearn, and stdlib types
2832
- **Efficient Serialization** - Apache Arrow binary format with JSON fallback
2933
- **Large-Payload Transport** - the Node subprocess bridge chunks results that
@@ -42,7 +46,8 @@ TypeScript wrapper for Python libraries with full type safety.
4246

4347
## Requirements
4448

45-
- Node.js 20+ (or Bun 1.1+ / Deno 1.46+)
49+
- Node.js 20+ (or Bun 1.1+ / Deno 1.46+; Deno subprocess support is experimental
50+
and untested in CI)
4651
- Python 3.10+ with `tywrap-ir`:
4752

4853
```bash
@@ -121,7 +126,8 @@ Raise `codec.maxPayloadBytes` to carry genuinely large results. You can still
121126
bound JSONL traffic explicitly with `TYWRAP_CODEC_MAX_BYTES` (responses) and
122127
`TYWRAP_REQUEST_MAX_BYTES` (requests). See the
123128
[transport framing](https://bbopen.github.io/tywrap/transport-framing) and
124-
[capability matrix](https://bbopen.github.io/tywrap/transport-capabilities) docs.
129+
[capability matrix](https://bbopen.github.io/tywrap/transport-capabilities)
130+
docs.
125131

126132
## Development Hot Reload
127133

@@ -160,6 +166,8 @@ await bridge.init();
160166

161167
### Deno / Bun
162168

169+
Deno subprocess support is experimental and untested in CI.
170+
163171
```typescript
164172
import { NodeBridge } from 'npm:tywrap'; // Deno
165173
import { NodeBridge } from 'tywrap'; // Bun
@@ -219,6 +227,11 @@ registerArrowDecoder(bytes => tableFromIPC(bytes));
219227
- [Troubleshooting](https://bbopen.github.io/tywrap/troubleshooting/)
220228
- [Roadmap](./ROADMAP.md)
221229

230+
## Security
231+
232+
See [SECURITY.md](./SECURITY.md) for the bridge trust model and vulnerability
233+
reporting.
234+
222235
## Contributing
223236

224237
```bash

docs/.vitepress/config.ts

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { defineConfig } from 'vitepress'
1+
import { defineConfig } from 'vitepress';
22

33
export default defineConfig({
44
title: 'tywrap',
5-
description: 'Generate type-safe TypeScript wrappers for any Python library — Node.js, Deno, Bun, and browsers via Pyodide.',
5+
description:
6+
'Generate TypeScript bindings with precise types for fully annotated, in-module, serializable Python returns, with fallbacks where tywrap cannot resolve a type.',
67
base: '/tywrap/',
78
appearance: 'force-dark',
89
cleanUrls: true,
@@ -53,25 +54,19 @@ export default defineConfig({
5354
},
5455
{
5556
text: 'Examples',
56-
items: [
57-
{ text: 'Quick Examples', link: '/examples/' },
58-
],
57+
items: [{ text: 'Quick Examples', link: '/examples/' }],
5958
},
6059
{
6160
text: 'Help',
62-
items: [
63-
{ text: 'Troubleshooting', link: '/troubleshooting/' },
64-
],
61+
items: [{ text: 'Troubleshooting', link: '/troubleshooting/' }],
6562
},
6663
],
6764

6865
search: {
6966
provider: 'local',
7067
},
7168

72-
socialLinks: [
73-
{ icon: 'github', link: 'https://github.com/bbopen/tywrap' },
74-
],
69+
socialLinks: [{ icon: 'github', link: 'https://github.com/bbopen/tywrap' }],
7570

7671
editLink: {
7772
pattern: 'https://github.com/bbopen/tywrap/edit/main/docs/:path',
@@ -83,4 +78,4 @@ export default defineConfig({
8378
copyright: 'Copyright © tywrap contributors',
8479
},
8580
},
86-
})
81+
});

docs/guide/getting-started.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ TypeScript wrapper for a Python library.
55

66
## Prerequisites
77

8-
- Node.js ≥20.0.0, Deno ≥1.46.0, or Bun ≥1.1.0
8+
- Node.js ≥20.0.0, Bun ≥1.1.0, or Deno ≥1.46.0 (Deno subprocess support is
9+
experimental and untested in CI)
910
- Python 3.10+ with target libraries installed
1011
- Basic TypeScript knowledge
1112

@@ -105,7 +106,7 @@ import * as math from './generated/math.generated.js';
105106
const bridge = new NodeBridge({ pythonPath: 'python3' });
106107
setRuntimeBridge(bridge);
107108

108-
// Use with full type safety
109+
// Types are precise where tywrap can resolve them.
109110
async function example() {
110111
const result = await math.sqrt(16); // TypeScript knows this returns Promise<number>
111112
const power = await math.pow(2, 3); // Full autocompletion and type checking
@@ -296,9 +297,8 @@ const session = await startNodeWatchSession({
296297
});
297298
```
298299

299-
For Pyodide, use `createBridgeReloader(...)` from `tywrap/dev` for manual
300-
bridge replacement. For HTTP, restart or redeploy the remote server outside
301-
tywrap.
300+
For Pyodide, use `createBridgeReloader(...)` from `tywrap/dev` for manual bridge
301+
replacement. For HTTP, restart or redeploy the remote server outside tywrap.
302302

303303
`startNodeWatchSession(...)` watches local package directories as directory
304304
trees, refreshes those trees when nested directories change, and keeps the last

docs/guide/runtimes/comparison.md

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,33 @@ tywrap supports five runtime configurations. Choose based on your environment.
44

55
## Feature Matrix
66

7-
| Feature | Node.js | Bun | Deno (local) | Browser (Pyodide) | HTTP |
8-
|---------|:-------:|:---:|:------------:|:-----------------:|:----:|
9-
| Python subprocess ||||| |
10-
| Deno Deploy / serverless ||||| |
11-
| Apache Arrow transport ||||| |
12-
| Virtual environment support |||| | Server-side |
13-
| Process pooling (experimental) | |||| |
14-
| Development hot reload |||| Manual bridge reload | External |
15-
| Tested in CI ||| Mocked || |
7+
| Feature | Node.js | Bun | Deno (experimental) | Browser (Pyodide) | HTTP |
8+
| ------------------------------ | :-----: | :-: | :-----------------: | :------------------: | :---------: |
9+
| Python subprocess || ||| |
10+
| Deno Deploy / serverless || ||| |
11+
| Apache Arrow transport || ||| |
12+
| Virtual environment support || || | Server-side |
13+
| Process pooling (experimental) | | ||| |
14+
| Development hot reload || || Manual bridge reload | External |
15+
| Tested in CI || | ❌ (untested) || |
1616

1717
## Import Paths
1818

19-
| Runtime | Import |
20-
|---------|--------|
21-
| Node.js | `import { NodeBridge } from 'tywrap/node'` |
22-
| Bun | `import { NodeBridge } from 'tywrap/node'` |
23-
| Deno | `import { NodeBridge } from 'npm:tywrap'` |
24-
| Browser | `import { PyodideBridge } from 'tywrap/pyodide'` |
25-
| HTTP | `import { HttpBridge } from 'tywrap/http'` |
19+
| Runtime | Import |
20+
| ----------------------------- | ------------------------------------------------ |
21+
| Node.js | `import { NodeBridge } from 'tywrap/node'` |
22+
| Bun | `import { NodeBridge } from 'tywrap/node'` |
23+
| Deno (experimental, untested) | `import { NodeBridge } from 'npm:tywrap'` |
24+
| Browser | `import { PyodideBridge } from 'tywrap/pyodide'` |
25+
| HTTP | `import { HttpBridge } from 'tywrap/http'` |
2626

2727
## Decision Guide
2828

2929
```
3030
Do you need subprocess-based Python execution?
3131
├── Yes → Does your environment support subprocess?
3232
│ ├── Node.js or Bun → Use NodeBridge (import from 'tywrap/node' or 'tywrap')
33-
│ ├── Deno (local) → Use NodeBridge with --allow-run=python3
33+
│ ├── Deno (experimental, untested) → Use NodeBridge with --allow-run=python3
3434
│ └── Deno Deploy / serverless → Continue ↓
3535
└── No (browser, edge, serverless) →
3636
├── Can you load ~50MB WebAssembly? → Use PyodideBridge
@@ -39,8 +39,8 @@ Do you need subprocess-based Python execution?
3939

4040
## Bridge Reference
4141

42-
| Bridge | Export | Guide |
43-
|--------|--------|-------|
44-
| `NodeBridge` | `tywrap/node` | [Node.js](./node) · [Bun](./bun) · [Deno](./deno) |
45-
| `PyodideBridge` | `tywrap/pyodide` | [Browser](./browser) |
46-
| `HttpBridge` | `tywrap/http` | [HTTP](./http) |
42+
| Bridge | Export | Guide |
43+
| --------------- | ---------------- | ------------------------------------------------- |
44+
| `NodeBridge` | `tywrap/node` | [Node.js](./node) · [Bun](./bun) · [Deno](./deno) |
45+
| `PyodideBridge` | `tywrap/pyodide` | [Browser](./browser) |
46+
| `HttpBridge` | `tywrap/http` | [HTTP](./http) |

docs/guide/runtimes/deno.md

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
# Deno Runtime Guide
22

3-
tywrap works with [Deno](https://deno.land/) 1.46+ using the same `NodeBridge` as Node.js. Deno requires the `npm:` prefix for npm imports.
3+
tywrap's Deno subprocess support is experimental and untested in CI. It uses the
4+
same `NodeBridge` as Node.js, and Deno requires the `npm:` prefix for npm
5+
imports.
46

57
## ⚠️ Deno Deploy Limitation
68

7-
**Deno Deploy does NOT support subprocess execution.** Because `NodeBridge` spawns a Python subprocess, it cannot run in Deno Deploy.
9+
**Deno Deploy does NOT support subprocess execution.** Because `NodeBridge`
10+
spawns a Python subprocess, it cannot run in Deno Deploy.
811

912
**Alternatives for Deno Deploy:**
10-
- Use [`PyodideBridge`](/guide/runtimes/browser) — runs Python in-browser via WebAssembly (no subprocess)
11-
- Use [`HttpBridge`](/guide/runtimes/http) — connects to a remote Python server over HTTP
13+
14+
- Use [`PyodideBridge`](/guide/runtimes/browser) — runs Python in-browser via
15+
WebAssembly (no subprocess)
16+
- Use [`HttpBridge`](/guide/runtimes/http) — connects to a remote Python server
17+
over HTTP
1218

1319
## Installation
1420

@@ -23,10 +29,12 @@ pip install tywrap-ir
2329
import { NodeBridge } from 'npm:tywrap';
2430
import { setRuntimeBridge } from 'npm:tywrap/runtime';
2531

26-
setRuntimeBridge(new NodeBridge({
27-
pythonPath: 'python3',
28-
timeoutMs: 30000,
29-
}));
32+
setRuntimeBridge(
33+
new NodeBridge({
34+
pythonPath: 'python3',
35+
timeoutMs: 30000,
36+
})
37+
);
3038
```
3139

3240
## Required Permissions
@@ -41,11 +49,11 @@ deno run \
4149
your-script.ts
4250
```
4351

44-
| Flag | Reason |
45-
|------|--------|
46-
| `--allow-run=python3` | Spawn the Python subprocess |
47-
| `--allow-read` | Read Python scripts and config files |
48-
| `--allow-env` | Read `TYWRAP_*` and `PATH` environment variables |
52+
| Flag | Reason |
53+
| --------------------- | ------------------------------------------------ |
54+
| `--allow-run=python3` | Spawn the Python subprocess |
55+
| `--allow-read` | Read Python scripts and config files |
56+
| `--allow-env` | Read `TYWRAP_*` and `PATH` environment variables |
4957

5058
## Type Checking
5159

@@ -55,24 +63,29 @@ deno check src/index.ts
5563

5664
## Configuration Options
5765

58-
See the [Node.js guide](./node) for the full `NodeBridgeOptions` reference — all options work identically in Deno.
66+
See the [Node.js guide](./node) for the full `NodeBridgeOptions` reference — all
67+
options work identically in Deno.
5968

6069
## When to Use Each Bridge in Deno
6170

62-
| Scenario | Bridge | Notes |
63-
|----------|--------|-------|
64-
| Local Deno script | `NodeBridge` | Needs `--allow-run` |
65-
| Deno Deploy | `PyodideBridge` | WebAssembly, no subprocess |
66-
| Deno Deploy + heavy Python libs | `HttpBridge` | Python runs on a separate server |
71+
| Scenario | Bridge | Notes |
72+
| ------------------------------- | --------------- | -------------------------------- |
73+
| Local Deno script | `NodeBridge` | Needs `--allow-run` |
74+
| Deno Deploy | `PyodideBridge` | WebAssembly, no subprocess |
75+
| Deno Deploy + heavy Python libs | `HttpBridge` | Python runs on a separate server |
6776

6877
## Environment Variables
6978

70-
The same `TYWRAP_*` env vars work under Deno. See the [environment variables reference](/reference/env-vars).
79+
The same `TYWRAP_*` env vars work under Deno. See the
80+
[environment variables reference](/reference/env-vars).
7181

7282
## Troubleshooting
7383

74-
**`PermissionDenied: Requires run access to "python3"`** — Add `--allow-run=python3` to your `deno run` command.
84+
**`PermissionDenied: Requires run access to "python3"`** — Add
85+
`--allow-run=python3` to your `deno run` command.
7586

76-
**`NotSupported: Subprocess access is not allowed`** — You are running in Deno Deploy. Switch to [`PyodideBridge`](/guide/runtimes/browser) or [`HttpBridge`](/guide/runtimes/http).
87+
**`NotSupported: Subprocess access is not allowed`** — You are running in Deno
88+
Deploy. Switch to [`PyodideBridge`](/guide/runtimes/browser) or
89+
[`HttpBridge`](/guide/runtimes/http).
7790

7891
See the [Node.js troubleshooting guide](./node) for additional patterns.

docs/guide/runtimes/node.md

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ The Node.js runtime:
1818
## Bridge Selection
1919

2020
- **NodeBridge (default)**: the public Node bridge. It supports both
21-
single-process execution and pooled execution through its constructor
22-
options.
21+
single-process execution and pooled execution through its constructor options.
2322
- **OptimizedNodeBridge**: deprecated compatibility alias for older deep
2423
imports. It is not part of the package exports and should not be used in new
2524
code.
@@ -29,8 +28,8 @@ stderr buffering.
2928

3029
## Development Hot Reload
3130

32-
Node hot reload in tywrap means wrapper regeneration plus bridge replacement.
33-
It lives in `tywrap/dev`, not in `tywrap.config.*`.
31+
Node hot reload in tywrap means wrapper regeneration plus bridge replacement. It
32+
lives in `tywrap/dev`, not in `tywrap.config.*`.
3433

3534
```typescript
3635
import { startNodeWatchSession } from 'tywrap/dev';
@@ -148,27 +147,27 @@ const bridge = new NodeBridge({
148147
});
149148
```
150149

151-
| Option | Type | Default | Description |
152-
| ------------------------- | ---------------------------------------- | --------------- | ---------------------------------------- |
153-
| `pythonPath` | `string` | auto-detect | Path to the Python executable |
154-
| `scriptPath` | `string` | built-in bridge | Custom `python_bridge.py` path |
155-
| `virtualEnv` | `string` || Virtual environment root |
156-
| `cwd` | `string` | `process.cwd()` | Working directory for the subprocess |
157-
| `timeoutMs` | `number` | `30000` | Per-call timeout |
158-
| `queueTimeoutMs` | `number` | `30000` | Queue timeout when the pool is saturated |
159-
| `minProcesses` | `number` | `1` | Minimum worker count |
160-
| `maxProcesses` | `number` | `1` | Maximum worker count |
161-
| `maxConcurrentPerProcess` | `number` | `1` | Concurrent requests per serial Python worker |
162-
| `inheritProcessEnv` | `boolean` | `false` | Pass the full parent environment through |
163-
| `env` | `Record<string, string \| undefined>` | `{}` | Extra subprocess env vars |
164-
| `codec` | `CodecOptions` || Codec validation and byte handling |
165-
| `warmupCommands` | `Array<{ module, functionName, args? }>` | `[]` | Commands to run when each worker starts |
150+
| Option | Type | Default | Description |
151+
| ------------------------- | ---------------------------------------- | --------------- | --------------------------------------------------------------------------------------- |
152+
| `pythonPath` | `string` | auto-detect | Path to the Python executable |
153+
| `scriptPath` | `string` | built-in bridge | Custom `python_bridge.py` path |
154+
| `virtualEnv` | `string` || Virtual environment root |
155+
| `cwd` | `string` | `process.cwd()` | Working directory for the subprocess |
156+
| `timeoutMs` | `number` | `30000` | Per-call timeout |
157+
| `queueTimeoutMs` | `number` | `30000` | Queue timeout when the pool is saturated |
158+
| `minProcesses` | `number` | `1` | Minimum worker count |
159+
| `maxProcesses` | `number` | `1` | Maximum worker count |
160+
| `maxConcurrentPerProcess` | `number` | `1` | Concurrent requests per serial Python worker; use more worker processes for concurrency |
161+
| `inheritProcessEnv` | `boolean` | `false` | Pass the full parent environment through |
162+
| `env` | `Record<string, string \| undefined>` | `{}` | Extra subprocess env vars |
163+
| `codec` | `CodecOptions` || Codec validation and byte handling |
164+
| `warmupCommands` | `Array<{ module, functionName, args? }>` | `[]` | Commands to run when each worker starts |
166165

167166
Deprecated compatibility fields still exist on the interface: `maxIdleTime`,
168167
`maxRequestsPerProcess`, `enableJsonFallback`, and `maxLineLength`. Avoid them
169-
in new code.
170-
By default, the subprocess environment is minimal (PATH/PYTHON*/TYWRAP\_* only).
171-
Set `inheritProcessEnv: true` to pass through the full environment when needed.
168+
in new code. By default, the subprocess environment is minimal
169+
(PATH/PYTHON*/TYWRAP\_* only). Set `inheritProcessEnv: true` to pass through the
170+
full environment when needed.
172171

173172
## Python Environment Setup
174173

0 commit comments

Comments
 (0)