tywrap 0.1.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/LICENSE +21 -0
- package/README.md +319 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +263 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/index.d.ts +41 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +234 -0
- package/dist/config/index.js.map +1 -0
- package/dist/core/analyzer.d.ts +63 -0
- package/dist/core/analyzer.d.ts.map +1 -0
- package/dist/core/analyzer.js +676 -0
- package/dist/core/analyzer.js.map +1 -0
- package/dist/core/discovery.d.ts +85 -0
- package/dist/core/discovery.d.ts.map +1 -0
- package/dist/core/discovery.js +344 -0
- package/dist/core/discovery.js.map +1 -0
- package/dist/core/generator.d.ts +37 -0
- package/dist/core/generator.d.ts.map +1 -0
- package/dist/core/generator.js +368 -0
- package/dist/core/generator.js.map +1 -0
- package/dist/core/mapper.d.ts +40 -0
- package/dist/core/mapper.d.ts.map +1 -0
- package/dist/core/mapper.js +401 -0
- package/dist/core/mapper.js.map +1 -0
- package/dist/core/validation.d.ts +79 -0
- package/dist/core/validation.d.ts.map +1 -0
- package/dist/core/validation.js +486 -0
- package/dist/core/validation.js.map +1 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/base.d.ts +12 -0
- package/dist/runtime/base.d.ts.map +1 -0
- package/dist/runtime/base.js +6 -0
- package/dist/runtime/base.js.map +1 -0
- package/dist/runtime/errors.d.ts +17 -0
- package/dist/runtime/errors.d.ts.map +1 -0
- package/dist/runtime/errors.js +21 -0
- package/dist/runtime/errors.js.map +1 -0
- package/dist/runtime/http.d.ts +22 -0
- package/dist/runtime/http.d.ts.map +1 -0
- package/dist/runtime/http.js +79 -0
- package/dist/runtime/http.js.map +1 -0
- package/dist/runtime/index.d.ts +8 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +17 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/node.d.ts +48 -0
- package/dist/runtime/node.d.ts.map +1 -0
- package/dist/runtime/node.js +328 -0
- package/dist/runtime/node.js.map +1 -0
- package/dist/runtime/optimized-node.d.ts +131 -0
- package/dist/runtime/optimized-node.d.ts.map +1 -0
- package/dist/runtime/optimized-node.js +622 -0
- package/dist/runtime/optimized-node.js.map +1 -0
- package/dist/runtime/protocol.d.ts +3 -0
- package/dist/runtime/protocol.d.ts.map +1 -0
- package/dist/runtime/protocol.js +3 -0
- package/dist/runtime/protocol.js.map +1 -0
- package/dist/runtime/pyodide.d.ts +27 -0
- package/dist/runtime/pyodide.d.ts.map +1 -0
- package/dist/runtime/pyodide.js +191 -0
- package/dist/runtime/pyodide.js.map +1 -0
- package/dist/tools/python_suite.js +173 -0
- package/dist/tools/python_suite.js.map +1 -0
- package/dist/types/index.d.ts +299 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/tywrap.d.ts +29 -0
- package/dist/tywrap.d.ts.map +1 -0
- package/dist/tywrap.js +589 -0
- package/dist/tywrap.js.map +1 -0
- package/dist/utils/bundle-optimizer.d.ts +182 -0
- package/dist/utils/bundle-optimizer.d.ts.map +1 -0
- package/dist/utils/bundle-optimizer.js +680 -0
- package/dist/utils/bundle-optimizer.js.map +1 -0
- package/dist/utils/cache.d.ts +149 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +492 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/codec.d.ts +94 -0
- package/dist/utils/codec.d.ts.map +1 -0
- package/dist/utils/codec.js +150 -0
- package/dist/utils/codec.js.map +1 -0
- package/dist/utils/logger.d.ts +42 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +140 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/memory-profiler.d.ts +123 -0
- package/dist/utils/memory-profiler.d.ts.map +1 -0
- package/dist/utils/memory-profiler.js +426 -0
- package/dist/utils/memory-profiler.js.map +1 -0
- package/dist/utils/parallel-processor.d.ts +146 -0
- package/dist/utils/parallel-processor.d.ts.map +1 -0
- package/dist/utils/parallel-processor.js +636 -0
- package/dist/utils/parallel-processor.js.map +1 -0
- package/dist/utils/python.d.ts +8 -0
- package/dist/utils/python.d.ts.map +1 -0
- package/dist/utils/python.js +56 -0
- package/dist/utils/python.js.map +1 -0
- package/dist/utils/runtime.d.ts +153 -0
- package/dist/utils/runtime.d.ts.map +1 -0
- package/dist/utils/runtime.js +519 -0
- package/dist/utils/runtime.js.map +1 -0
- package/package.json +136 -0
- package/runtime/python_bridge.py +476 -0
- package/src/cli.ts +331 -0
- package/src/config/index.ts +289 -0
- package/src/core/analyzer.ts +788 -0
- package/src/core/discovery.ts +415 -0
- package/src/core/generator.ts +447 -0
- package/src/core/mapper.ts +504 -0
- package/src/core/validation.ts +693 -0
- package/src/index.ts +83 -0
- package/src/runtime/base.ts +32 -0
- package/src/runtime/errors.ts +19 -0
- package/src/runtime/http.ts +132 -0
- package/src/runtime/index.ts +24 -0
- package/src/runtime/node.ts +431 -0
- package/src/runtime/optimized-node.ts +838 -0
- package/src/runtime/protocol.ts +2 -0
- package/src/runtime/pyodide.ts +228 -0
- package/src/types/global.d.ts +60 -0
- package/src/types/index.ts +410 -0
- package/src/tywrap.ts +669 -0
- package/src/utils/bundle-optimizer.ts +876 -0
- package/src/utils/cache.ts +634 -0
- package/src/utils/codec.ts +275 -0
- package/src/utils/logger.ts +201 -0
- package/src/utils/memory-profiler.ts +582 -0
- package/src/utils/parallel-processor.ts +879 -0
- package/src/utils/python.ts +79 -0
- package/src/utils/runtime.ts +616 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 tywrap contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# tywrap
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/tywrap)
|
|
4
|
+
[](https://github.com/bbopen/tywrap/actions/workflows/ci.yml)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
|
|
7
|
+
TypeScript wrapper for Python libraries with full type safety.
|
|
8
|
+
|
|
9
|
+
> **Warning: Experimental Software**
|
|
10
|
+
> **Version 0.1.0** - This project is in early experimental development. APIs may change significantly between versions. Not recommended for production use until version 1.0.0.
|
|
11
|
+
|
|
12
|
+
TypeScript is great, but many robust libraries exist only in Python, especially for data science and machine learning. Wouldn't it be great if you could use those libraries in your TypeScript project?
|
|
13
|
+
|
|
14
|
+
tywrap is a build-time code generation system that creates TypeScript wrappers for Python libraries, giving you type safety and IDE autocomplete for Python code.
|
|
15
|
+
|
|
16
|
+
## Features
|
|
17
|
+
|
|
18
|
+
- **Full Type Safety** - TypeScript type definitions generated from Python source analysis
|
|
19
|
+
- **Multi-Runtime Support** - Works in Node.js (subprocess) and browsers (via Pyodide)
|
|
20
|
+
- **IR-First Generation** - Python Intermediate Representation (IR) extractor analyzes modules and emits structured type information
|
|
21
|
+
- **Rich Data Type Support** - Native handling for numpy, pandas, scipy, torch, sklearn, and Python stdlib types
|
|
22
|
+
- **Efficient Serialization** - Apache Arrow binary format for high-performance data transfer (with JSON fallback)
|
|
23
|
+
- **Optional Caching** - Intelligent result caching system (opt-in via config)
|
|
24
|
+
|
|
25
|
+
## Requirements
|
|
26
|
+
|
|
27
|
+
- Node.js 20+ (or Bun 1.1+ / Deno 1.46+)
|
|
28
|
+
- Python 3.10+
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install tywrap
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Initialize a Config
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx tywrap init
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
This creates a `tywrap.config.ts` file. Edit it to specify which Python modules to wrap.
|
|
43
|
+
|
|
44
|
+
### Generate Wrappers
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx tywrap generate
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Basic Usage
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { NodeBridge } from 'tywrap/node';
|
|
54
|
+
import { setRuntimeBridge } from 'tywrap/runtime';
|
|
55
|
+
import * as math from './generated/math.generated.js';
|
|
56
|
+
|
|
57
|
+
// Create a "bridge" - the runtime adapter that executes Python code
|
|
58
|
+
const bridge = new NodeBridge({
|
|
59
|
+
pythonPath: 'python3',
|
|
60
|
+
virtualEnv: './venv'
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Set as the active bridge for generated wrappers
|
|
64
|
+
setRuntimeBridge(bridge);
|
|
65
|
+
|
|
66
|
+
// Call Python functions with full type safety
|
|
67
|
+
const result = await math.sqrt(16);
|
|
68
|
+
console.log(result); // 4
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Runtime Support
|
|
72
|
+
|
|
73
|
+
tywrap provides **bridge** implementations—runtime adapters that handle communication between TypeScript and Python.
|
|
74
|
+
|
|
75
|
+
### Node.js (Primary)
|
|
76
|
+
|
|
77
|
+
The Node.js bridge spawns a Python subprocess and communicates via JSON-RPC:
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { NodeBridge } from 'tywrap/node';
|
|
81
|
+
import { setRuntimeBridge } from 'tywrap/runtime';
|
|
82
|
+
|
|
83
|
+
const bridge = new NodeBridge({
|
|
84
|
+
pythonPath: 'python3',
|
|
85
|
+
virtualEnv: './venv',
|
|
86
|
+
timeout: 30000 // Optional: request timeout in ms
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
setRuntimeBridge(bridge);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Browser (Pyodide)
|
|
93
|
+
|
|
94
|
+
The browser bridge uses [Pyodide](https://pyodide.org/) to run Python in WebAssembly:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { PyodideBridge } from 'tywrap/pyodide';
|
|
98
|
+
import { setRuntimeBridge } from 'tywrap/runtime';
|
|
99
|
+
|
|
100
|
+
const bridge = new PyodideBridge({
|
|
101
|
+
indexURL: 'https://cdn.jsdelivr.net/pyodide/v0.24.1/full/'
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
await bridge.init();
|
|
105
|
+
setRuntimeBridge(bridge);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Deno / Bun
|
|
109
|
+
|
|
110
|
+
Deno and Bun can use the Node.js bridge. Import via npm specifier:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
// Deno
|
|
114
|
+
import { NodeBridge, setRuntimeBridge } from 'npm:tywrap';
|
|
115
|
+
|
|
116
|
+
// Bun (same as Node.js)
|
|
117
|
+
import { NodeBridge, setRuntimeBridge } from 'tywrap';
|
|
118
|
+
|
|
119
|
+
const bridge = new NodeBridge({ pythonPath: 'python3' });
|
|
120
|
+
setRuntimeBridge(bridge);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Working with Classes
|
|
124
|
+
|
|
125
|
+
Generated class wrappers use async factory methods:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
import { Counter } from './generated/collections.generated';
|
|
129
|
+
|
|
130
|
+
// Create instance (async because it calls Python)
|
|
131
|
+
const counter = await Counter.create(['a', 'b', 'b', 'c', 'b']);
|
|
132
|
+
|
|
133
|
+
// Call methods
|
|
134
|
+
const mostCommon = await counter.mostCommon(2);
|
|
135
|
+
console.log(mostCommon); // [['b', 3], ['c', 1]]
|
|
136
|
+
|
|
137
|
+
// Clean up when done
|
|
138
|
+
await counter.disposeHandle();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Configuration
|
|
142
|
+
|
|
143
|
+
Create a `tywrap.config.ts` file:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { defineConfig } from 'tywrap';
|
|
147
|
+
|
|
148
|
+
export default defineConfig({
|
|
149
|
+
pythonModules: {
|
|
150
|
+
'pandas': {
|
|
151
|
+
version: '2.1.0',
|
|
152
|
+
classes: ['DataFrame'],
|
|
153
|
+
functions: ['read_csv', 'concat']
|
|
154
|
+
},
|
|
155
|
+
'numpy': {
|
|
156
|
+
version: '1.24.0',
|
|
157
|
+
alias: 'np'
|
|
158
|
+
},
|
|
159
|
+
'./custom_module.py': {
|
|
160
|
+
// Local modules work too
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
output: {
|
|
165
|
+
dir: './src/generated',
|
|
166
|
+
format: 'esm',
|
|
167
|
+
declaration: true
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
performance: {
|
|
171
|
+
caching: true, // Enable result caching
|
|
172
|
+
batching: true // Batch multiple calls
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
debug: false // Set true for verbose logging
|
|
176
|
+
});
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Config file resolution: `tywrap.config.ts`, `.mts`, `.js`, `.mjs`, `.cjs`, `.json`.
|
|
180
|
+
|
|
181
|
+
See the [Configuration Guide](./docs/configuration.md) for all options.
|
|
182
|
+
|
|
183
|
+
## How It Works
|
|
184
|
+
|
|
185
|
+
1. **Python IR Extraction** - The `tywrap_ir` tool analyzes Python modules using AST parsing and emits a versioned JSON Intermediate Representation (IR) containing function signatures, class definitions, and type annotations.
|
|
186
|
+
|
|
187
|
+
2. **Type Mapping** - The IR is transformed into TypeScript types. Python's `int` becomes `number`, `List[str]` becomes `string[]`, etc.
|
|
188
|
+
|
|
189
|
+
3. **Code Generation** - TypeScript wrapper code is generated with proper async handling and bridge integration.
|
|
190
|
+
|
|
191
|
+
4. **Runtime Execution** - At runtime, the bridge serializes calls to Python and deserializes results back to JavaScript.
|
|
192
|
+
|
|
193
|
+
## Documentation
|
|
194
|
+
|
|
195
|
+
- [Getting Started Guide](./docs/getting-started.md) - Detailed setup instructions
|
|
196
|
+
- [Configuration Reference](./docs/configuration.md) - All configuration options
|
|
197
|
+
- [Node.js Runtime](./docs/runtimes/nodejs.md) - Node.js bridge details
|
|
198
|
+
- [Browser Runtime](./docs/runtimes/browser.md) - Pyodide integration
|
|
199
|
+
- [API Reference](./docs/api/README.md) - Complete API documentation
|
|
200
|
+
- [Examples](./docs/examples/README.md) - Real-world usage examples
|
|
201
|
+
- [Troubleshooting](./docs/troubleshooting/README.md) - Common issues and solutions
|
|
202
|
+
- [Release Notes](./docs/release.md) - Version history and upgrade guides
|
|
203
|
+
|
|
204
|
+
## Data Type Support
|
|
205
|
+
|
|
206
|
+
tywrap automatically serializes Python data types to JavaScript. The Python bridge wraps complex types in **envelopes**—metadata wrappers that preserve type information.
|
|
207
|
+
|
|
208
|
+
### Supported Types
|
|
209
|
+
|
|
210
|
+
| Python Type | JS/TS Type | Encoding | Notes |
|
|
211
|
+
|-------------|-----------|----------|-------|
|
|
212
|
+
| `numpy.ndarray` | `Uint8Array` or `array` | Arrow or JSON | Shape preserved |
|
|
213
|
+
| `pandas.DataFrame` | Arrow Table or `object[]` | Arrow or JSON | Column types preserved |
|
|
214
|
+
| `pandas.Series` | Arrow Table or `array` | Arrow or JSON | Name preserved |
|
|
215
|
+
| `scipy.sparse.*` | `SparseMatrix` | JSON | CSR, CSC, COO formats |
|
|
216
|
+
| `torch.Tensor` | `TorchTensor` | ndarray wrapper | CPU only by default |
|
|
217
|
+
| `sklearn estimator` | `SklearnEstimator` | JSON | Params only (no pickle) |
|
|
218
|
+
| `datetime.*` | `string` | ISO format | datetime, date, time |
|
|
219
|
+
| `timedelta` | `number` | seconds | Total seconds as float |
|
|
220
|
+
| `Decimal` | `string` | string | Preserves precision |
|
|
221
|
+
| `UUID` | `string` | string | Standard format |
|
|
222
|
+
| `Path` | `string` | string | Platform-neutral |
|
|
223
|
+
|
|
224
|
+
### Arrow Encoding (Recommended)
|
|
225
|
+
|
|
226
|
+
For numpy/pandas data, Arrow binary format is more efficient than JSON. Register a decoder at app startup:
|
|
227
|
+
|
|
228
|
+
```typescript
|
|
229
|
+
import { registerArrowDecoder } from 'tywrap';
|
|
230
|
+
import { tableFromIPC } from 'apache-arrow';
|
|
231
|
+
|
|
232
|
+
registerArrowDecoder(bytes => tableFromIPC(bytes));
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Environment Variables
|
|
236
|
+
|
|
237
|
+
| Variable | Purpose |
|
|
238
|
+
|----------|---------|
|
|
239
|
+
| `TYWRAP_CODEC_FALLBACK=json` | Use JSON instead of Arrow (for dev or constrained environments) |
|
|
240
|
+
| `TYWRAP_TORCH_ALLOW_COPY=1` | Allow GPU→CPU transfer and non-contiguous tensor copying |
|
|
241
|
+
|
|
242
|
+
### Envelope Format
|
|
243
|
+
|
|
244
|
+
```json
|
|
245
|
+
{"__tywrap__": "dataframe", "encoding": "arrow", "b64": "..."}
|
|
246
|
+
{"__tywrap__": "ndarray", "encoding": "json", "data": [...], "shape": [3, 4]}
|
|
247
|
+
{"__tywrap__": "scipy.sparse", "format": "csr", "data": [...], "indices": [...]}
|
|
248
|
+
{"__tywrap__": "torch.tensor", "value": {...}, "dtype": "float32", "device": "cpu"}
|
|
249
|
+
{"__tywrap__": "sklearn.estimator", "className": "LinearRegression", "params": {...}}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
See [codec-roadmap.md](./docs/codec-roadmap.md) for encoding details and planned features.
|
|
253
|
+
|
|
254
|
+
## Roadmap
|
|
255
|
+
|
|
256
|
+
### Implemented
|
|
257
|
+
- [x] Core TypeScript generation from Python IR
|
|
258
|
+
- [x] Node.js runtime bridge (subprocess)
|
|
259
|
+
- [x] Browser runtime bridge (Pyodide)
|
|
260
|
+
- [x] Python AST analysis and type extraction
|
|
261
|
+
- [x] Codec support: numpy, pandas, scipy sparse, torch tensors, sklearn estimators
|
|
262
|
+
- [x] Apache Arrow binary encoding (with JSON fallback)
|
|
263
|
+
- [x] Python stdlib type conversions (datetime, Decimal, UUID, Path)
|
|
264
|
+
- [x] Result caching system (opt-in)
|
|
265
|
+
|
|
266
|
+
### Planned
|
|
267
|
+
- [ ] Build tool plugins (Vite, Webpack, Rollup)
|
|
268
|
+
- [ ] Hot reload / watch mode
|
|
269
|
+
- [ ] Source map generation
|
|
270
|
+
- [ ] IDE extensions
|
|
271
|
+
- [ ] SharedArrayBuffer for zero-copy transfers
|
|
272
|
+
- [ ] Streaming results for large datasets
|
|
273
|
+
|
|
274
|
+
## Versioning
|
|
275
|
+
|
|
276
|
+
tywrap follows [Semantic Versioning](https://semver.org/):
|
|
277
|
+
|
|
278
|
+
- **0.x.x** - Experimental releases. Breaking changes may occur in any release.
|
|
279
|
+
- **1.x.x** - Stable API. Breaking changes only in major versions.
|
|
280
|
+
|
|
281
|
+
### Current Status (v0.1.0)
|
|
282
|
+
|
|
283
|
+
| Feature | Status |
|
|
284
|
+
|---------|--------|
|
|
285
|
+
| TypeScript generation | ✅ Working |
|
|
286
|
+
| Node.js bridge | ✅ Working |
|
|
287
|
+
| Pyodide bridge | ✅ Working |
|
|
288
|
+
| Type safety | ✅ Working |
|
|
289
|
+
| numpy/pandas codecs | ✅ Working |
|
|
290
|
+
| scipy/torch/sklearn codecs | ✅ Working |
|
|
291
|
+
| Deno/Bun | ⚠️ Uses Node bridge |
|
|
292
|
+
| API stability | ⚠️ May change |
|
|
293
|
+
|
|
294
|
+
## Contributing
|
|
295
|
+
|
|
296
|
+
We welcome contributions! See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
297
|
+
|
|
298
|
+
To run tests locally:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
npm install
|
|
302
|
+
npm test
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
For the full test matrix including Python library integration:
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
npm run test:python:suite:core
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## License
|
|
312
|
+
|
|
313
|
+
MIT © [tywrap contributors](LICENSE)
|
|
314
|
+
|
|
315
|
+
## Links
|
|
316
|
+
|
|
317
|
+
- [GitHub Repository](https://github.com/bbopen/tywrap)
|
|
318
|
+
- [npm Package](https://www.npmjs.com/package/tywrap)
|
|
319
|
+
- [Issue Tracker](https://github.com/bbopen/tywrap/issues)
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { writeFile } from 'node:fs/promises';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
import yargs from 'yargs';
|
|
6
|
+
import { hideBin } from 'yargs/helpers';
|
|
7
|
+
import { resolveConfig } from './config/index.js';
|
|
8
|
+
import { getComponentLogger } from './utils/logger.js';
|
|
9
|
+
const log = getComponentLogger('CLI');
|
|
10
|
+
const DEFAULT_CONFIG_FILES = [
|
|
11
|
+
'tywrap.config.ts',
|
|
12
|
+
'tywrap.config.mts',
|
|
13
|
+
'tywrap.config.js',
|
|
14
|
+
'tywrap.config.mjs',
|
|
15
|
+
'tywrap.config.cjs',
|
|
16
|
+
'tywrap.config.json',
|
|
17
|
+
];
|
|
18
|
+
function resolveConfigPath(explicitPath) {
|
|
19
|
+
const cwd = process.cwd();
|
|
20
|
+
if (explicitPath) {
|
|
21
|
+
const resolved = resolve(cwd, explicitPath);
|
|
22
|
+
return { configPath: resolved, explicit: true };
|
|
23
|
+
}
|
|
24
|
+
for (const name of DEFAULT_CONFIG_FILES) {
|
|
25
|
+
const candidate = resolve(cwd, name);
|
|
26
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- config discovery uses user-controlled paths
|
|
27
|
+
if (existsSync(candidate)) {
|
|
28
|
+
return { configPath: candidate, explicit: false };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { configPath: undefined, explicit: false };
|
|
32
|
+
}
|
|
33
|
+
function parseModules(modulesList) {
|
|
34
|
+
if (!modulesList) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
return modulesList
|
|
38
|
+
.split(',')
|
|
39
|
+
.map(m => m.trim())
|
|
40
|
+
.filter(Boolean);
|
|
41
|
+
}
|
|
42
|
+
function buildModulesConfig(modules, runtime) {
|
|
43
|
+
return Object.fromEntries(modules.map(name => [name, { runtime, typeHints: 'strict' }]));
|
|
44
|
+
}
|
|
45
|
+
function renderConfigTemplate(options) {
|
|
46
|
+
const modules = options.modules.length > 0 ? options.modules : ['math'];
|
|
47
|
+
if (options.format === 'json') {
|
|
48
|
+
const config = {
|
|
49
|
+
pythonModules: buildModulesConfig(modules, options.runtime),
|
|
50
|
+
output: { dir: options.outputDir, format: 'esm', declaration: false, sourceMap: false },
|
|
51
|
+
runtime: { node: { pythonPath: 'python3' } },
|
|
52
|
+
types: { presets: ['stdlib'] },
|
|
53
|
+
};
|
|
54
|
+
return `${JSON.stringify(config, null, 2)}\n`;
|
|
55
|
+
}
|
|
56
|
+
const moduleLines = modules
|
|
57
|
+
.map(name => ` ${JSON.stringify(name)}: { runtime: '${options.runtime}', typeHints: 'strict' },`)
|
|
58
|
+
.join('\n');
|
|
59
|
+
return `import { defineConfig } from 'tywrap';
|
|
60
|
+
|
|
61
|
+
export default defineConfig({
|
|
62
|
+
pythonModules: {
|
|
63
|
+
${moduleLines}
|
|
64
|
+
},
|
|
65
|
+
output: {
|
|
66
|
+
dir: '${options.outputDir}',
|
|
67
|
+
format: 'esm',
|
|
68
|
+
declaration: false,
|
|
69
|
+
sourceMap: false
|
|
70
|
+
},
|
|
71
|
+
runtime: {
|
|
72
|
+
node: {
|
|
73
|
+
pythonPath: 'python3'
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
types: {
|
|
77
|
+
presets: ['stdlib']
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
`;
|
|
81
|
+
}
|
|
82
|
+
async function main() {
|
|
83
|
+
await yargs(hideBin(process.argv))
|
|
84
|
+
.scriptName('tywrap')
|
|
85
|
+
.command('generate', 'Generate TypeScript wrappers', (y) => y
|
|
86
|
+
.option('config', {
|
|
87
|
+
alias: 'c',
|
|
88
|
+
type: 'string',
|
|
89
|
+
describe: 'Path to config file (defaults to tywrap.config.* if present)',
|
|
90
|
+
})
|
|
91
|
+
.option('modules', {
|
|
92
|
+
type: 'string',
|
|
93
|
+
describe: 'Comma-separated list of Python modules to wrap',
|
|
94
|
+
})
|
|
95
|
+
.option('runtime', {
|
|
96
|
+
type: 'string',
|
|
97
|
+
choices: ['node', 'pyodide', 'http', 'auto'],
|
|
98
|
+
default: 'node',
|
|
99
|
+
describe: 'Runtime to use when --modules is provided',
|
|
100
|
+
})
|
|
101
|
+
.option('python', {
|
|
102
|
+
type: 'string',
|
|
103
|
+
describe: 'Path to Python executable',
|
|
104
|
+
})
|
|
105
|
+
.option('output-dir', {
|
|
106
|
+
type: 'string',
|
|
107
|
+
describe: 'Directory for generated wrappers',
|
|
108
|
+
})
|
|
109
|
+
.option('format', {
|
|
110
|
+
type: 'string',
|
|
111
|
+
choices: ['esm', 'cjs', 'both'],
|
|
112
|
+
describe: 'Output module format',
|
|
113
|
+
})
|
|
114
|
+
.option('declaration', {
|
|
115
|
+
type: 'boolean',
|
|
116
|
+
describe: 'Emit TypeScript declaration files',
|
|
117
|
+
})
|
|
118
|
+
.option('source-map', {
|
|
119
|
+
type: 'boolean',
|
|
120
|
+
describe: 'Emit source maps for generated files',
|
|
121
|
+
})
|
|
122
|
+
.option('use-cache', {
|
|
123
|
+
alias: 'cache',
|
|
124
|
+
type: 'boolean',
|
|
125
|
+
describe: 'Enable on-disk caching (use --no-cache to disable)',
|
|
126
|
+
})
|
|
127
|
+
.option('debug', {
|
|
128
|
+
type: 'boolean',
|
|
129
|
+
describe: 'Enable debug logging',
|
|
130
|
+
})
|
|
131
|
+
.option('fail-on-warn', {
|
|
132
|
+
type: 'boolean',
|
|
133
|
+
default: false,
|
|
134
|
+
describe: 'Exit with code 2 if generation emits warnings',
|
|
135
|
+
})
|
|
136
|
+
.strict(), async (argv) => {
|
|
137
|
+
const { configPath, explicit } = resolveConfigPath(argv.config);
|
|
138
|
+
const modules = parseModules(argv.modules);
|
|
139
|
+
const overrides = {};
|
|
140
|
+
if (modules.length > 0) {
|
|
141
|
+
overrides.pythonModules = buildModulesConfig(modules, argv.runtime);
|
|
142
|
+
}
|
|
143
|
+
if (argv.outputDir ||
|
|
144
|
+
argv.format ||
|
|
145
|
+
typeof argv.declaration === 'boolean' ||
|
|
146
|
+
typeof argv.sourceMap === 'boolean') {
|
|
147
|
+
overrides.output = {
|
|
148
|
+
...(argv.outputDir ? { dir: argv.outputDir } : {}),
|
|
149
|
+
...(argv.format ? { format: argv.format } : {}),
|
|
150
|
+
...(typeof argv.declaration === 'boolean' ? { declaration: argv.declaration } : {}),
|
|
151
|
+
...(typeof argv.sourceMap === 'boolean' ? { sourceMap: argv.sourceMap } : {}),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
if (typeof argv.useCache === 'boolean') {
|
|
155
|
+
overrides.performance = {
|
|
156
|
+
caching: argv.useCache,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (argv.python) {
|
|
160
|
+
overrides.runtime = {
|
|
161
|
+
node: { pythonPath: argv.python },
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if (typeof argv.debug === 'boolean') {
|
|
165
|
+
overrides.debug = argv.debug;
|
|
166
|
+
}
|
|
167
|
+
if (!configPath && modules.length === 0) {
|
|
168
|
+
log.error('No config file found and no modules provided. Create a config with `tywrap init` or pass --modules.');
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
const { generate } = await import('./tywrap.js');
|
|
172
|
+
try {
|
|
173
|
+
const options = await resolveConfig({
|
|
174
|
+
configFile: configPath,
|
|
175
|
+
overrides,
|
|
176
|
+
requireConfig: explicit,
|
|
177
|
+
});
|
|
178
|
+
if (!options.pythonModules || Object.keys(options.pythonModules).length === 0) {
|
|
179
|
+
log.error('No pythonModules configured. Use --modules or update your config.');
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
const res = await generate(options);
|
|
183
|
+
process.stdout.write(`Generated: ${res.written.join(', ')}\n`);
|
|
184
|
+
if (argv.failOnWarn && res.warnings.length > 0) {
|
|
185
|
+
log.error(`Warnings encountered (count ${res.warnings.length}). Failing due to --fail-on-warn.`);
|
|
186
|
+
process.exit(2);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
191
|
+
log.error('Generation failed', { error: message });
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
})
|
|
195
|
+
.command('init', 'Create a starter tywrap.config file', (y) => y
|
|
196
|
+
.option('config', {
|
|
197
|
+
alias: 'c',
|
|
198
|
+
type: 'string',
|
|
199
|
+
describe: 'Path for the new config file',
|
|
200
|
+
})
|
|
201
|
+
.option('format', {
|
|
202
|
+
type: 'string',
|
|
203
|
+
choices: ['ts', 'json'],
|
|
204
|
+
default: 'ts',
|
|
205
|
+
describe: 'Config file format',
|
|
206
|
+
})
|
|
207
|
+
.option('modules', {
|
|
208
|
+
type: 'string',
|
|
209
|
+
describe: 'Comma-separated list of Python modules to wrap',
|
|
210
|
+
})
|
|
211
|
+
.option('runtime', {
|
|
212
|
+
type: 'string',
|
|
213
|
+
choices: ['node', 'pyodide', 'http', 'auto'],
|
|
214
|
+
default: 'node',
|
|
215
|
+
describe: 'Runtime for generated module entries',
|
|
216
|
+
})
|
|
217
|
+
.option('output-dir', {
|
|
218
|
+
type: 'string',
|
|
219
|
+
default: './generated',
|
|
220
|
+
describe: 'Output directory for generated wrappers',
|
|
221
|
+
})
|
|
222
|
+
.option('force', {
|
|
223
|
+
type: 'boolean',
|
|
224
|
+
default: false,
|
|
225
|
+
describe: 'Overwrite existing config file',
|
|
226
|
+
})
|
|
227
|
+
.strict(), async (argv) => {
|
|
228
|
+
const modules = parseModules(argv.modules);
|
|
229
|
+
const defaultName = argv.format === 'json' ? 'tywrap.config.json' : 'tywrap.config.ts';
|
|
230
|
+
const targetPath = resolve(process.cwd(), argv.config ?? defaultName);
|
|
231
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- config path is user-controlled
|
|
232
|
+
if (!argv.force && existsSync(targetPath)) {
|
|
233
|
+
log.error('Config file already exists. Use --force to overwrite.', { path: targetPath });
|
|
234
|
+
process.exit(1);
|
|
235
|
+
}
|
|
236
|
+
const content = renderConfigTemplate({
|
|
237
|
+
format: argv.format,
|
|
238
|
+
modules,
|
|
239
|
+
runtime: argv.runtime,
|
|
240
|
+
outputDir: argv.outputDir,
|
|
241
|
+
});
|
|
242
|
+
try {
|
|
243
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- config path is user-controlled
|
|
244
|
+
await writeFile(targetPath, content, 'utf-8');
|
|
245
|
+
process.stdout.write(`Created ${targetPath}\n`);
|
|
246
|
+
}
|
|
247
|
+
catch (err) {
|
|
248
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
249
|
+
log.error('Failed to write config', { error: message });
|
|
250
|
+
process.exit(1);
|
|
251
|
+
}
|
|
252
|
+
})
|
|
253
|
+
.demandCommand(1, 'Please specify a command')
|
|
254
|
+
.strict()
|
|
255
|
+
.help()
|
|
256
|
+
.version()
|
|
257
|
+
.parse();
|
|
258
|
+
}
|
|
259
|
+
main().catch(err => {
|
|
260
|
+
log.error('Unexpected error', { error: err instanceof Error ? err.message : String(err) });
|
|
261
|
+
process.exit(1);
|
|
262
|
+
});
|
|
263
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration system
|
|
3
|
+
*
|
|
4
|
+
* Loads configuration from defaults, optional config file and CLI overrides
|
|
5
|
+
* with basic validation of known options.
|
|
6
|
+
*/
|
|
7
|
+
import type { TywrapOptions } from '../types/index.js';
|
|
8
|
+
/**
|
|
9
|
+
* Public configuration type. Currently identical to {@link TywrapOptions}.
|
|
10
|
+
*/
|
|
11
|
+
export type TywrapConfig = TywrapOptions;
|
|
12
|
+
type DeepPartial<T> = {
|
|
13
|
+
[K in keyof T]?: T[K] extends Array<infer U> ? Array<U> : T[K] extends object ? DeepPartial<T[K]> : T[K];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Create a configuration object by merging defaults with overrides.
|
|
17
|
+
*
|
|
18
|
+
* @param overrides CLI or programmatic overrides
|
|
19
|
+
*/
|
|
20
|
+
export declare function createConfig(overrides?: DeepPartial<TywrapOptions>): TywrapConfig;
|
|
21
|
+
export interface ResolveConfigOptions {
|
|
22
|
+
configFile?: string;
|
|
23
|
+
overrides?: DeepPartial<TywrapOptions>;
|
|
24
|
+
cwd?: string;
|
|
25
|
+
requireConfig?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resolve configuration by loading a config file (JSON/JS/TS) and merging
|
|
29
|
+
* defaults with any overrides.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveConfig(options?: ResolveConfigOptions): Promise<TywrapConfig>;
|
|
32
|
+
/**
|
|
33
|
+
* Load a tywrap config file. Supports JSON, JS/CJS/ESM, and TS files.
|
|
34
|
+
*/
|
|
35
|
+
export declare function loadConfigFile(configFile: string): Promise<Partial<TywrapOptions>>;
|
|
36
|
+
/**
|
|
37
|
+
* Type helper for authoring tywrap configs with full type inference.
|
|
38
|
+
*/
|
|
39
|
+
export declare function defineConfig(config: TywrapConfig): TywrapConfig;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EACV,aAAa,EAKd,MAAM,mBAAmB,CAAC;AAG3B;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,aAAa,CAAC;AAEzC,KAAK,WAAW,CAAC,CAAC,IAAI;KACnB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GACxC,KAAK,CAAC,CAAC,CAAC,GACR,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GACjB,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACjB,CAAC,CAAC,CAAC,CAAC;CACX,CAAC;AA2IF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,GAAE,WAAW,CAAC,aAAa,CAAM,GAAG,YAAY,CAIrF;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,YAAY,CAAC,CAmB7F;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CA2DxF;AAOD;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,YAAY,CAE/D"}
|