pynect 0.0.0-stage → 0.2.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 +478 -2
- package/SECURITY.md +34 -0
- package/binding.gyp +60 -0
- package/dist/cli/codegen.d.ts +3 -0
- package/dist/cli/codegen.d.ts.map +1 -0
- package/dist/cli/codegen.js +543 -0
- package/dist/cli/codegen.js.map +1 -0
- package/dist/cli/sync.d.ts +3 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +48 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/config/project.d.ts +57 -0
- package/dist/config/project.d.ts.map +1 -0
- package/dist/config/project.js +176 -0
- package/dist/config/project.js.map +1 -0
- package/dist/core/IsolatedWorker.d.ts +39 -0
- package/dist/core/IsolatedWorker.d.ts.map +1 -0
- package/dist/core/IsolatedWorker.js +178 -0
- package/dist/core/IsolatedWorker.js.map +1 -0
- package/dist/core/PyCallable.d.ts +67 -0
- package/dist/core/PyCallable.d.ts.map +1 -0
- package/dist/core/PyCallable.js +104 -0
- package/dist/core/PyCallable.js.map +1 -0
- package/dist/core/PyContext.d.ts +76 -0
- package/dist/core/PyContext.d.ts.map +1 -0
- package/dist/core/PyContext.js +239 -0
- package/dist/core/PyContext.js.map +1 -0
- package/dist/core/PyIterator.d.ts +84 -0
- package/dist/core/PyIterator.d.ts.map +1 -0
- package/dist/core/PyIterator.js +243 -0
- package/dist/core/PyIterator.js.map +1 -0
- package/dist/core/PyModule.d.ts +53 -0
- package/dist/core/PyModule.d.ts.map +1 -0
- package/dist/core/PyModule.js +162 -0
- package/dist/core/PyModule.js.map +1 -0
- package/dist/core/PyProxy.d.ts +75 -0
- package/dist/core/PyProxy.d.ts.map +1 -0
- package/dist/core/PyProxy.js +563 -0
- package/dist/core/PyProxy.js.map +1 -0
- package/dist/core/PyRuntime.d.ts +112 -0
- package/dist/core/PyRuntime.d.ts.map +1 -0
- package/dist/core/PyRuntime.js +546 -0
- package/dist/core/PyRuntime.js.map +1 -0
- package/dist/env/PackageInstaller.d.ts +232 -0
- package/dist/env/PackageInstaller.d.ts.map +1 -0
- package/dist/env/PackageInstaller.js +628 -0
- package/dist/env/PackageInstaller.js.map +1 -0
- package/dist/env/ProjectEnvironment.d.ts +63 -0
- package/dist/env/ProjectEnvironment.d.ts.map +1 -0
- package/dist/env/ProjectEnvironment.js +379 -0
- package/dist/env/ProjectEnvironment.js.map +1 -0
- package/dist/env/PyfigAdapter.d.ts +32 -0
- package/dist/env/PyfigAdapter.d.ts.map +1 -0
- package/dist/env/PyfigAdapter.js +10 -0
- package/dist/env/PyfigAdapter.js.map +1 -0
- package/dist/env/PythonDetector.d.ts +48 -0
- package/dist/env/PythonDetector.d.ts.map +1 -0
- package/dist/env/PythonDetector.js +182 -0
- package/dist/env/PythonDetector.js.map +1 -0
- package/dist/env/PythonProvisioner.d.ts +16 -0
- package/dist/env/PythonProvisioner.d.ts.map +1 -0
- package/dist/env/PythonProvisioner.js +42 -0
- package/dist/env/PythonProvisioner.js.map +1 -0
- package/dist/env/VenvManager.d.ts +55 -0
- package/dist/env/VenvManager.d.ts.map +1 -0
- package/dist/env/VenvManager.js +153 -0
- package/dist/env/VenvManager.js.map +1 -0
- package/dist/env/executables.d.ts +3 -0
- package/dist/env/executables.d.ts.map +1 -0
- package/dist/env/executables.js +14 -0
- package/dist/env/executables.js.map +1 -0
- package/dist/index.d.ts +182 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +393 -0
- package/dist/index.js.map +1 -0
- package/dist/native/NativeAddonLoader.d.ts +11 -0
- package/dist/native/NativeAddonLoader.d.ts.map +1 -0
- package/dist/native/NativeAddonLoader.js +75 -0
- package/dist/native/NativeAddonLoader.js.map +1 -0
- package/dist/plugins/Plugin.interface.d.ts +41 -0
- package/dist/plugins/Plugin.interface.d.ts.map +1 -0
- package/dist/plugins/Plugin.interface.js +12 -0
- package/dist/plugins/Plugin.interface.js.map +1 -0
- package/dist/plugins/PluginManager.d.ts +26 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -0
- package/dist/plugins/PluginManager.js +174 -0
- package/dist/plugins/PluginManager.js.map +1 -0
- package/dist/plugins/builtin/NumpyPlugin.d.ts +17 -0
- package/dist/plugins/builtin/NumpyPlugin.d.ts.map +1 -0
- package/dist/plugins/builtin/NumpyPlugin.js +41 -0
- package/dist/plugins/builtin/NumpyPlugin.js.map +1 -0
- package/dist/plugins/builtin/PandasPlugin.d.ts +19 -0
- package/dist/plugins/builtin/PandasPlugin.d.ts.map +1 -0
- package/dist/plugins/builtin/PandasPlugin.js +57 -0
- package/dist/plugins/builtin/PandasPlugin.js.map +1 -0
- package/dist/plugins/builtin/TorchPlugin.d.ts +23 -0
- package/dist/plugins/builtin/TorchPlugin.d.ts.map +1 -0
- package/dist/plugins/builtin/TorchPlugin.js +50 -0
- package/dist/plugins/builtin/TorchPlugin.js.map +1 -0
- package/dist/plugins/index.d.ts +7 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +12 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/serialization/DataFrameBridge.d.ts +141 -0
- package/dist/serialization/DataFrameBridge.d.ts.map +1 -0
- package/dist/serialization/DataFrameBridge.js +355 -0
- package/dist/serialization/DataFrameBridge.js.map +1 -0
- package/dist/serialization/MsgPackSerializer.d.ts +45 -0
- package/dist/serialization/MsgPackSerializer.d.ts.map +1 -0
- package/dist/serialization/MsgPackSerializer.js +242 -0
- package/dist/serialization/MsgPackSerializer.js.map +1 -0
- package/dist/serialization/NumpyBridge.d.ts +96 -0
- package/dist/serialization/NumpyBridge.d.ts.map +1 -0
- package/dist/serialization/NumpyBridge.js +323 -0
- package/dist/serialization/NumpyBridge.js.map +1 -0
- package/dist/serialization/Serializer.d.ts +78 -0
- package/dist/serialization/Serializer.d.ts.map +1 -0
- package/dist/serialization/Serializer.js +281 -0
- package/dist/serialization/Serializer.js.map +1 -0
- package/dist/types/addon.d.ts +131 -0
- package/dist/types/addon.d.ts.map +1 -0
- package/dist/types/addon.js +32 -0
- package/dist/types/addon.js.map +1 -0
- package/dist/types/config.d.ts +233 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +60 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +12 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/python.d.ts +235 -0
- package/dist/types/python.d.ts.map +1 -0
- package/dist/types/python.js +7 -0
- package/dist/types/python.js.map +1 -0
- package/dist/utils/ErrorTranslator.d.ts +83 -0
- package/dist/utils/ErrorTranslator.d.ts.map +1 -0
- package/dist/utils/ErrorTranslator.js +210 -0
- package/dist/utils/ErrorTranslator.js.map +1 -0
- package/dist/utils/Locking.d.ts +3 -0
- package/dist/utils/Locking.d.ts.map +1 -0
- package/dist/utils/Locking.js +10 -0
- package/dist/utils/Locking.js.map +1 -0
- package/dist/utils/Logger.d.ts +27 -0
- package/dist/utils/Logger.d.ts.map +1 -0
- package/dist/utils/Logger.js +115 -0
- package/dist/utils/Logger.js.map +1 -0
- package/dist/utils/MemoryMonitor.d.ts +43 -0
- package/dist/utils/MemoryMonitor.d.ts.map +1 -0
- package/dist/utils/MemoryMonitor.js +143 -0
- package/dist/utils/MemoryMonitor.js.map +1 -0
- package/package.json +114 -4
- package/python/ast_inspector.py +248 -0
- package/python/error_handler.py +432 -0
- package/python/isolated_worker.py +94 -0
- package/python/pynect_dispatcher.py +382 -0
- package/python/pynect_runtime.py +574 -0
- package/python/serializer.py +373 -0
- package/python/type_inspector.py +315 -0
- package/scripts/build-native.js +50 -0
- package/scripts/cli.js +21 -0
- package/scripts/ensure-native.js +85 -0
- package/scripts/postinstall.js +40 -0
- package/scripts/pyfig.js +113 -0
- package/scripts/python-provisioner.js +23 -0
- package/scripts/smoke-python-boundary.js +103 -0
- package/src/native/NativeAddonLoader.ts +98 -0
- package/src/native/gil_guard.cpp +25 -0
- package/src/native/gil_guard.h +174 -0
- package/src/native/pynect_addon.cpp +942 -0
- package/src/native/python_bridge.cpp +904 -0
- package/src/native/python_bridge.h +263 -0
- package/src/native/thread_pool.cpp +375 -0
- package/src/native/thread_pool.h +185 -0
- package/src/native/type_converter.cpp +906 -0
- package/src/native/type_converter.h +271 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pynect - Type Converter Header
|
|
3
|
+
* Converts between Python objects and JavaScript/JSON representations.
|
|
4
|
+
*
|
|
5
|
+
* Conversion strategy:
|
|
6
|
+
* - Primitive types (int, float, bool, str, None) -> JSON
|
|
7
|
+
* - Large arrays (numpy, lists) -> MessagePack binary
|
|
8
|
+
* - numpy arrays -> binary buffer with metadata
|
|
9
|
+
* - pandas DataFrames -> Arrow/binary with schema metadata
|
|
10
|
+
* - Complex Python objects -> opaque references (PyObjectId)
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
#pragma once
|
|
14
|
+
|
|
15
|
+
#include <Python.h>
|
|
16
|
+
#include <napi.h>
|
|
17
|
+
#include <string>
|
|
18
|
+
#include <vector>
|
|
19
|
+
#include <cstdint>
|
|
20
|
+
#include <optional>
|
|
21
|
+
|
|
22
|
+
namespace pynect {
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Wire format identifiers (must match TypeScript SerializedFormat enum)
|
|
26
|
+
*/
|
|
27
|
+
enum class SerializedFormat : uint8_t {
|
|
28
|
+
JSON = 0,
|
|
29
|
+
MSGPACK = 1,
|
|
30
|
+
NUMPY_ARRAY = 2,
|
|
31
|
+
PANDAS_DATAFRAME = 3,
|
|
32
|
+
PANDAS_SERIES = 4,
|
|
33
|
+
TORCH_TENSOR = 5,
|
|
34
|
+
PYTHON_REF = 6,
|
|
35
|
+
BYTES = 7,
|
|
36
|
+
NONE = 8,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Metadata for serialized values.
|
|
41
|
+
*/
|
|
42
|
+
struct SerializedMetadata {
|
|
43
|
+
// For NUMPY_ARRAY
|
|
44
|
+
std::string dtype;
|
|
45
|
+
std::vector<int64_t> shape;
|
|
46
|
+
std::vector<int64_t> strides;
|
|
47
|
+
bool isC_contiguous = true;
|
|
48
|
+
|
|
49
|
+
// For PANDAS_DATAFRAME
|
|
50
|
+
std::vector<std::string> columns;
|
|
51
|
+
std::vector<std::string> columnDtypes;
|
|
52
|
+
|
|
53
|
+
// For PYTHON_REF
|
|
54
|
+
uint32_t objectId = 0;
|
|
55
|
+
|
|
56
|
+
// General
|
|
57
|
+
int64_t length = 0;
|
|
58
|
+
int64_t size_bytes = 0;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* A serialized value ready to be sent to JavaScript.
|
|
63
|
+
*/
|
|
64
|
+
struct SerializedValue {
|
|
65
|
+
SerializedFormat format = SerializedFormat::NONE;
|
|
66
|
+
std::string jsonData; // For JSON format
|
|
67
|
+
std::vector<uint8_t> binaryData; // For binary formats
|
|
68
|
+
SerializedMetadata metadata;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* TypeConverter - stateless utility class for Python <-> JavaScript conversions.
|
|
73
|
+
*
|
|
74
|
+
* All methods are static and thread-safe (GIL must be held by caller).
|
|
75
|
+
*/
|
|
76
|
+
class TypeConverter {
|
|
77
|
+
public:
|
|
78
|
+
TypeConverter() = delete;
|
|
79
|
+
|
|
80
|
+
// Python -> SerializedValue
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Convert any Python object to a SerializedValue for JavaScript consumption.
|
|
84
|
+
* @param obj - Python object (borrowed reference)
|
|
85
|
+
* @param depth - current recursion depth (prevents infinite loops)
|
|
86
|
+
* @returns SerializedValue
|
|
87
|
+
*/
|
|
88
|
+
static SerializedValue pythonToSerialized(PyObject* obj, int depth = 0);
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Convert Python primitive to JSON string.
|
|
92
|
+
* Returns std::nullopt if obj is not a primitive.
|
|
93
|
+
*/
|
|
94
|
+
static std::optional<std::string> primitiveToJson(PyObject* obj);
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Convert Python list/tuple to JSON array string.
|
|
98
|
+
*/
|
|
99
|
+
static std::string listToJson(PyObject* seq, int depth);
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Convert Python dict to JSON object string.
|
|
103
|
+
*/
|
|
104
|
+
static std::string dictToJson(PyObject* mapping, int depth);
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Serialize numpy ndarray to binary buffer + metadata.
|
|
108
|
+
*/
|
|
109
|
+
static SerializedValue numpyArrayToBuffer(PyObject* array);
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Serialize pandas DataFrame to binary + metadata.
|
|
113
|
+
*/
|
|
114
|
+
static SerializedValue dataFrameToBuffer(PyObject* df);
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Serialize pandas Series to binary + metadata.
|
|
118
|
+
*/
|
|
119
|
+
static SerializedValue seriesToBuffer(PyObject* series);
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Check if a Python object is a numpy array.
|
|
123
|
+
*/
|
|
124
|
+
static bool isNumpyArray(PyObject* obj);
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Check if a Python object is a pandas DataFrame.
|
|
128
|
+
*/
|
|
129
|
+
static bool isDataFrame(PyObject* obj);
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Check if a Python object is a pandas Series.
|
|
133
|
+
*/
|
|
134
|
+
static bool isSeries(PyObject* obj);
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Check if a Python object is a PyTorch Tensor.
|
|
138
|
+
*/
|
|
139
|
+
static bool isTorchTensor(PyObject* obj);
|
|
140
|
+
|
|
141
|
+
// JavaScript/JSON -> Python
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Convert a JSON string to a Python object.
|
|
145
|
+
* @returns new Python reference, or nullptr on error
|
|
146
|
+
*/
|
|
147
|
+
static PyObject* jsonToPython(const std::string& json);
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Convert a MessagePack binary to a Python object.
|
|
151
|
+
*/
|
|
152
|
+
static PyObject* msgpackToPython(const std::vector<uint8_t>& data);
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Convert a typed array buffer to a numpy array.
|
|
156
|
+
*/
|
|
157
|
+
static PyObject* bufferToNumpyArray(
|
|
158
|
+
const std::vector<uint8_t>& data,
|
|
159
|
+
const std::string& dtype,
|
|
160
|
+
const std::vector<int64_t>& shape
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
// Type Inspection
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Get the Python type name of an object.
|
|
167
|
+
*/
|
|
168
|
+
static std::string getTypeName(PyObject* obj);
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Get the full qualified type name (module.class).
|
|
172
|
+
*/
|
|
173
|
+
static std::string getQualifiedTypeName(PyObject* obj);
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Check if the object is callable.
|
|
177
|
+
*/
|
|
178
|
+
static bool isCallable(PyObject* obj);
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Check if the object is iterable.
|
|
182
|
+
*/
|
|
183
|
+
static bool isIterable(PyObject* obj);
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Check if the object is async iterable.
|
|
187
|
+
*/
|
|
188
|
+
static bool isAsyncIterable(PyObject* obj);
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Check if the object is a Python module.
|
|
192
|
+
*/
|
|
193
|
+
static bool isModule(PyObject* obj);
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Check if the object is a Python class.
|
|
197
|
+
*/
|
|
198
|
+
static bool isClass(PyObject* obj);
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Get string representation (repr) of an object.
|
|
202
|
+
*/
|
|
203
|
+
static std::string getRepr(PyObject* obj);
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Get string representation (str) of an object.
|
|
207
|
+
*/
|
|
208
|
+
static std::string getStr(PyObject* obj);
|
|
209
|
+
|
|
210
|
+
// Error Handling
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Capture current Python exception state as strings.
|
|
214
|
+
* Clears the exception after capturing.
|
|
215
|
+
* @returns tuple of (type, message, traceback)
|
|
216
|
+
*/
|
|
217
|
+
static std::tuple<std::string, std::string, std::string> captureException();
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Convert a Python exception to JSON for transmission to JS.
|
|
221
|
+
*/
|
|
222
|
+
static std::string exceptionToJson();
|
|
223
|
+
|
|
224
|
+
// Object Registry
|
|
225
|
+
// Python objects that can't be serialized are stored in a registry
|
|
226
|
+
// and referenced by ID from JavaScript.
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Register a Python object and return its ID.
|
|
230
|
+
* Increments reference count.
|
|
231
|
+
*/
|
|
232
|
+
static uint32_t registerObject(PyObject* obj);
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Get a Python object by ID.
|
|
236
|
+
* Returns borrowed reference (do not decref).
|
|
237
|
+
*/
|
|
238
|
+
static PyObject* getObject(uint32_t id);
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Increment reference count of a registered object.
|
|
242
|
+
*/
|
|
243
|
+
static void incRef(uint32_t id);
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Decrement reference count of a registered object.
|
|
247
|
+
* If refcount reaches 0, removes from registry.
|
|
248
|
+
*/
|
|
249
|
+
static void decRef(uint32_t id);
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Get count of registered objects (for monitoring).
|
|
253
|
+
*/
|
|
254
|
+
static size_t getRegisteredCount();
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Clear all registered objects (during shutdown).
|
|
258
|
+
*/
|
|
259
|
+
static void clearRegistry();
|
|
260
|
+
|
|
261
|
+
private:
|
|
262
|
+
// JSON escape a string
|
|
263
|
+
static std::string jsonEscape(const std::string& s);
|
|
264
|
+
|
|
265
|
+
// Maximum depth for recursive conversion
|
|
266
|
+
static constexpr int MAX_DEPTH = 32;
|
|
267
|
+
// Maximum list/dict size to serialize as JSON
|
|
268
|
+
static constexpr size_t MAX_INLINE_SIZE = 10000;
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
} // namespace pynect
|