nodepyx 1.0.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 (184) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +399 -0
  3. package/binding.gyp +73 -0
  4. package/dist/core/PyCallable.d.ts +65 -0
  5. package/dist/core/PyCallable.d.ts.map +1 -0
  6. package/dist/core/PyCallable.js +109 -0
  7. package/dist/core/PyCallable.js.map +1 -0
  8. package/dist/core/PyContext.d.ts +76 -0
  9. package/dist/core/PyContext.d.ts.map +1 -0
  10. package/dist/core/PyContext.js +228 -0
  11. package/dist/core/PyContext.js.map +1 -0
  12. package/dist/core/PyIterator.d.ts +84 -0
  13. package/dist/core/PyIterator.d.ts.map +1 -0
  14. package/dist/core/PyIterator.js +243 -0
  15. package/dist/core/PyIterator.js.map +1 -0
  16. package/dist/core/PyModule.d.ts +55 -0
  17. package/dist/core/PyModule.d.ts.map +1 -0
  18. package/dist/core/PyModule.js +172 -0
  19. package/dist/core/PyModule.js.map +1 -0
  20. package/dist/core/PyProxy.d.ts +65 -0
  21. package/dist/core/PyProxy.d.ts.map +1 -0
  22. package/dist/core/PyProxy.js +483 -0
  23. package/dist/core/PyProxy.js.map +1 -0
  24. package/dist/core/PyRuntime.d.ts +105 -0
  25. package/dist/core/PyRuntime.d.ts.map +1 -0
  26. package/dist/core/PyRuntime.js +438 -0
  27. package/dist/core/PyRuntime.js.map +1 -0
  28. package/dist/env/CondaManager.d.ts +118 -0
  29. package/dist/env/CondaManager.d.ts.map +1 -0
  30. package/dist/env/CondaManager.js +401 -0
  31. package/dist/env/CondaManager.js.map +1 -0
  32. package/dist/env/PackageInstaller.d.ts +233 -0
  33. package/dist/env/PackageInstaller.d.ts.map +1 -0
  34. package/dist/env/PackageInstaller.js +609 -0
  35. package/dist/env/PackageInstaller.js.map +1 -0
  36. package/dist/env/PythonDetector.d.ts +103 -0
  37. package/dist/env/PythonDetector.d.ts.map +1 -0
  38. package/dist/env/PythonDetector.js +381 -0
  39. package/dist/env/PythonDetector.js.map +1 -0
  40. package/dist/env/VenvManager.d.ts +117 -0
  41. package/dist/env/VenvManager.d.ts.map +1 -0
  42. package/dist/env/VenvManager.js +331 -0
  43. package/dist/env/VenvManager.js.map +1 -0
  44. package/dist/index.d.ts +169 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +393 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/plugins/Plugin.interface.d.ts +41 -0
  49. package/dist/plugins/Plugin.interface.d.ts.map +1 -0
  50. package/dist/plugins/Plugin.interface.js +12 -0
  51. package/dist/plugins/Plugin.interface.js.map +1 -0
  52. package/dist/plugins/PluginManager.d.ts +26 -0
  53. package/dist/plugins/PluginManager.d.ts.map +1 -0
  54. package/dist/plugins/PluginManager.js +174 -0
  55. package/dist/plugins/PluginManager.js.map +1 -0
  56. package/dist/plugins/builtin/NumpyPlugin.d.ts +17 -0
  57. package/dist/plugins/builtin/NumpyPlugin.d.ts.map +1 -0
  58. package/dist/plugins/builtin/NumpyPlugin.js +41 -0
  59. package/dist/plugins/builtin/NumpyPlugin.js.map +1 -0
  60. package/dist/plugins/builtin/PandasPlugin.d.ts +19 -0
  61. package/dist/plugins/builtin/PandasPlugin.d.ts.map +1 -0
  62. package/dist/plugins/builtin/PandasPlugin.js +57 -0
  63. package/dist/plugins/builtin/PandasPlugin.js.map +1 -0
  64. package/dist/plugins/builtin/TorchPlugin.d.ts +23 -0
  65. package/dist/plugins/builtin/TorchPlugin.d.ts.map +1 -0
  66. package/dist/plugins/builtin/TorchPlugin.js +50 -0
  67. package/dist/plugins/builtin/TorchPlugin.js.map +1 -0
  68. package/dist/plugins/index.d.ts +7 -0
  69. package/dist/plugins/index.d.ts.map +1 -0
  70. package/dist/plugins/index.js +12 -0
  71. package/dist/plugins/index.js.map +1 -0
  72. package/dist/serialization/DataFrameBridge.d.ts +141 -0
  73. package/dist/serialization/DataFrameBridge.d.ts.map +1 -0
  74. package/dist/serialization/DataFrameBridge.js +355 -0
  75. package/dist/serialization/DataFrameBridge.js.map +1 -0
  76. package/dist/serialization/MsgPackSerializer.d.ts +45 -0
  77. package/dist/serialization/MsgPackSerializer.d.ts.map +1 -0
  78. package/dist/serialization/MsgPackSerializer.js +242 -0
  79. package/dist/serialization/MsgPackSerializer.js.map +1 -0
  80. package/dist/serialization/NumpyBridge.d.ts +96 -0
  81. package/dist/serialization/NumpyBridge.d.ts.map +1 -0
  82. package/dist/serialization/NumpyBridge.js +323 -0
  83. package/dist/serialization/NumpyBridge.js.map +1 -0
  84. package/dist/serialization/Serializer.d.ts +78 -0
  85. package/dist/serialization/Serializer.d.ts.map +1 -0
  86. package/dist/serialization/Serializer.js +281 -0
  87. package/dist/serialization/Serializer.js.map +1 -0
  88. package/dist/types/PythonTypeMapper.d.ts +87 -0
  89. package/dist/types/PythonTypeMapper.d.ts.map +1 -0
  90. package/dist/types/PythonTypeMapper.js +449 -0
  91. package/dist/types/PythonTypeMapper.js.map +1 -0
  92. package/dist/types/StubCache.d.ts +109 -0
  93. package/dist/types/StubCache.d.ts.map +1 -0
  94. package/dist/types/StubCache.js +333 -0
  95. package/dist/types/StubCache.js.map +1 -0
  96. package/dist/types/TypeGenerator.d.ts +139 -0
  97. package/dist/types/TypeGenerator.d.ts.map +1 -0
  98. package/dist/types/TypeGenerator.js +372 -0
  99. package/dist/types/TypeGenerator.js.map +1 -0
  100. package/dist/types/addon.d.ts +114 -0
  101. package/dist/types/addon.d.ts.map +1 -0
  102. package/dist/types/addon.js +32 -0
  103. package/dist/types/addon.js.map +1 -0
  104. package/dist/types/config.d.ts +175 -0
  105. package/dist/types/config.d.ts.map +1 -0
  106. package/dist/types/config.js +35 -0
  107. package/dist/types/config.js.map +1 -0
  108. package/dist/types/index.d.ts +10 -0
  109. package/dist/types/index.d.ts.map +1 -0
  110. package/dist/types/index.js +12 -0
  111. package/dist/types/index.js.map +1 -0
  112. package/dist/types/python.d.ts +235 -0
  113. package/dist/types/python.d.ts.map +1 -0
  114. package/dist/types/python.js +7 -0
  115. package/dist/types/python.js.map +1 -0
  116. package/dist/utils/ErrorTranslator.d.ts +83 -0
  117. package/dist/utils/ErrorTranslator.d.ts.map +1 -0
  118. package/dist/utils/ErrorTranslator.js +210 -0
  119. package/dist/utils/ErrorTranslator.js.map +1 -0
  120. package/dist/utils/Logger.d.ts +27 -0
  121. package/dist/utils/Logger.d.ts.map +1 -0
  122. package/dist/utils/Logger.js +115 -0
  123. package/dist/utils/Logger.js.map +1 -0
  124. package/dist/utils/MemoryMonitor.d.ts +44 -0
  125. package/dist/utils/MemoryMonitor.d.ts.map +1 -0
  126. package/dist/utils/MemoryMonitor.js +143 -0
  127. package/dist/utils/MemoryMonitor.js.map +1 -0
  128. package/package.json +177 -0
  129. package/python/error_handler.py +433 -0
  130. package/python/nodepyx_runtime.py +575 -0
  131. package/python/serializer.py +379 -0
  132. package/python/type_inspector.py +288 -0
  133. package/scripts/build-native.js +68 -0
  134. package/scripts/download-prebuilds.js +99 -0
  135. package/scripts/generate-stubs.js +405 -0
  136. package/scripts/install.js +260 -0
  137. package/src/core/PyCallable.ts +137 -0
  138. package/src/core/PyContext.ts +296 -0
  139. package/src/core/PyIterator.ts +294 -0
  140. package/src/core/PyModule.ts +194 -0
  141. package/src/core/PyProxy.ts +605 -0
  142. package/src/core/PyRuntime.ts +504 -0
  143. package/src/env/CondaManager.ts +451 -0
  144. package/src/env/PackageInstaller.ts +738 -0
  145. package/src/env/PythonDetector.ts +414 -0
  146. package/src/env/VenvManager.ts +396 -0
  147. package/src/index.ts +425 -0
  148. package/src/native/gil_guard.cpp +26 -0
  149. package/src/native/gil_guard.h +175 -0
  150. package/src/native/nodepyx_addon.cpp +886 -0
  151. package/src/native/python_bridge.cpp +790 -0
  152. package/src/native/python_bridge.h +257 -0
  153. package/src/native/thread_pool.cpp +336 -0
  154. package/src/native/thread_pool.h +175 -0
  155. package/src/native/type_converter.cpp +901 -0
  156. package/src/native/type_converter.h +272 -0
  157. package/src/nextjs/PyProvider.tsx +123 -0
  158. package/src/nextjs/index.ts +21 -0
  159. package/src/nextjs/usePython.ts +106 -0
  160. package/src/nextjs/withnodepyx.ts +88 -0
  161. package/src/plugins/Plugin.interface.ts +51 -0
  162. package/src/plugins/PluginManager.ts +155 -0
  163. package/src/plugins/builtin/NumpyPlugin.ts +36 -0
  164. package/src/plugins/builtin/PandasPlugin.ts +49 -0
  165. package/src/plugins/builtin/TorchPlugin.ts +56 -0
  166. package/src/plugins/index.ts +7 -0
  167. package/src/serialization/DataFrameBridge.ts +398 -0
  168. package/src/serialization/MsgPackSerializer.ts +220 -0
  169. package/src/serialization/NumpyBridge.ts +332 -0
  170. package/src/serialization/Serializer.ts +320 -0
  171. package/src/types/PythonTypeMapper.ts +495 -0
  172. package/src/types/StubCache.ts +340 -0
  173. package/src/types/TypeGenerator.ts +491 -0
  174. package/src/types/addon.ts +170 -0
  175. package/src/types/config.ts +226 -0
  176. package/src/types/index.ts +55 -0
  177. package/src/types/python.ts +309 -0
  178. package/src/types/stubs/numpy.d.ts +441 -0
  179. package/src/types/stubs/pandas.d.ts +575 -0
  180. package/src/types/stubs/sklearn.d.ts +728 -0
  181. package/src/types/stubs/torch.d.ts +694 -0
  182. package/src/utils/ErrorTranslator.ts +220 -0
  183. package/src/utils/Logger.ts +119 -0
  184. package/src/utils/MemoryMonitor.ts +175 -0
@@ -0,0 +1,438 @@
1
+ "use strict";
2
+ /**
3
+ * nodepyx — PyRuntime
4
+ * The central manager for the Python interpreter lifecycle.
5
+ * Creates, configures, and shuts down the embedded CPython instance.
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ var __importDefault = (this && this.__importDefault) || function (mod) {
41
+ return (mod && mod.__esModule) ? mod : { "default": mod };
42
+ };
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.PyRuntime = void 0;
45
+ const path_1 = __importDefault(require("path"));
46
+ const addon_1 = require("../types/addon");
47
+ const config_1 = require("../types/config");
48
+ const PyProxy_1 = require("./PyProxy");
49
+ const PyModule_1 = require("./PyModule");
50
+ const PyContext_1 = require("./PyContext");
51
+ const Serializer_1 = require("../serialization/Serializer");
52
+ const TypeGenerator_1 = require("../types/TypeGenerator");
53
+ const PluginManager_1 = require("../plugins/PluginManager");
54
+ const VenvManager_1 = require("../env/VenvManager");
55
+ const PythonDetector_1 = require("../env/PythonDetector");
56
+ const PackageInstaller_1 = require("../env/PackageInstaller");
57
+ const MemoryMonitor_1 = require("../utils/MemoryMonitor");
58
+ const Logger_1 = require("../utils/Logger");
59
+ const ErrorTranslator_1 = require("../utils/ErrorTranslator");
60
+ const logger = new Logger_1.Logger('PyRuntime');
61
+ /**
62
+ * PyRuntime — manages the lifecycle of the embedded Python interpreter.
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * const runtime = await PyRuntime.create({
67
+ * virtualenv: { path: '.venv', packages: ['pandas'], autoInstall: true },
68
+ * });
69
+ *
70
+ * const pd = await runtime.import('pandas');
71
+ * const df = await pd.read_csv('data.csv');
72
+ * const result = await df.to_dict('records');
73
+ *
74
+ * await runtime.shutdown();
75
+ * ```
76
+ */
77
+ class PyRuntime {
78
+ _config;
79
+ _addon;
80
+ _serializer;
81
+ _typeGenerator;
82
+ _pluginManager;
83
+ _memoryMonitor;
84
+ _moduleCache = new Map();
85
+ _running = false;
86
+ constructor(config, addon) {
87
+ this._config = config;
88
+ this._addon = addon;
89
+ this._serializer = Serializer_1.Serializer.getInstance();
90
+ this._typeGenerator = new TypeGenerator_1.TypeGenerator({ stubsDir: config.stubsDir });
91
+ this._pluginManager = new PluginManager_1.PluginManager();
92
+ this._memoryMonitor = new MemoryMonitor_1.MemoryMonitor({
93
+ gcThreshold: this._parseBytes(config.gcThreshold),
94
+ });
95
+ this._memoryMonitor.attach(addon);
96
+ }
97
+ /**
98
+ * Create and initialize a PyRuntime instance.
99
+ */
100
+ static async create(config = {}) {
101
+ const resolved = (0, config_1.resolveConfig)(config);
102
+ // Set log level
103
+ Logger_1.Logger.setGlobalLevel(resolved.logLevel);
104
+ logger.info('Creating PyRuntime...');
105
+ // Load the native addon
106
+ let addon;
107
+ try {
108
+ addon = (0, addon_1.loadNativeAddon)();
109
+ logger.debug('Native addon loaded');
110
+ }
111
+ catch (err) {
112
+ logger.error('Failed to load native addon. Make sure nodepyx is built.', err);
113
+ throw new Error('nodepyx native addon not found. Run "npm install" or "npm run build:native".\n' +
114
+ `Original error: ${err.message}`);
115
+ }
116
+ const runtime = new PyRuntime(resolved, addon);
117
+ await runtime._initialize(config);
118
+ return runtime;
119
+ }
120
+ // ─── Initialization ────────────────────────────────────────────────────────
121
+ async _initialize(config) {
122
+ const startTime = performance.now();
123
+ // 1. Detect/setup Python environment
124
+ const pythonExecutable = await this._setupPythonEnvironment(config);
125
+ // 2. Initialize Python interpreter via C++ addon
126
+ logger.debug(`Initializing Python interpreter: ${pythonExecutable}`);
127
+ await this._addon.initializePython({
128
+ pythonHome: this._config.pythonHome || '',
129
+ pythonExecutable,
130
+ threadPoolSize: this._config.threadPoolSize,
131
+ maxQueueSize: this._config.maxQueueSize,
132
+ gilReleaseInterval: this._config.gil.releaseInterval,
133
+ callTimeout: this._config.callTimeout,
134
+ pythonPathExtra: [
135
+ path_1.default.join(__dirname, '..', '..', 'python'),
136
+ ...this._config.pythonPathExtra,
137
+ ],
138
+ env: this._config.env,
139
+ enableProfiling: this._config.profilingEnabled,
140
+ });
141
+ logger.debug('Python interpreter initialized');
142
+ // 3. Bootstrap Python runtime helpers
143
+ await this._bootstrapPythonRuntime();
144
+ // 4. Register built-in plugins
145
+ await this._pluginManager.registerBuiltins();
146
+ // 5. Start memory monitoring
147
+ this._memoryMonitor.startMonitoring(10000);
148
+ this._running = true;
149
+ const elapsed = (performance.now() - startTime).toFixed(0);
150
+ logger.success(`PyRuntime ready in ${elapsed}ms (Python: ${pythonExecutable})`);
151
+ }
152
+ async _setupPythonEnvironment(config) {
153
+ let pythonExecutable = this._config.pythonExecutable;
154
+ if (config.conda) {
155
+ // Conda environment
156
+ const { CondaManager } = await Promise.resolve().then(() => __importStar(require('../env/CondaManager')));
157
+ const condaManager = new CondaManager({ conda: config.conda });
158
+ pythonExecutable = await condaManager.getPythonExecutable(config.conda.envName) ?? pythonExecutable;
159
+ logger.info(`Using conda environment: ${config.conda.envName}`);
160
+ }
161
+ else if (config.virtualenv) {
162
+ // Virtualenv
163
+ const venvManager = new VenvManager_1.VenvManager({ virtualenv: config.virtualenv });
164
+ const venvResult = await venvManager.setup();
165
+ pythonExecutable = typeof venvResult === 'string' ? venvResult : venvResult.pythonExecutable ?? pythonExecutable;
166
+ logger.info(`Using virtualenv: ${config.virtualenv.path}`);
167
+ }
168
+ else if (config.pythonPath) {
169
+ // Explicit Python path
170
+ pythonExecutable = config.pythonPath;
171
+ }
172
+ else {
173
+ // Auto-detect
174
+ const detector = new PythonDetector_1.PythonDetector();
175
+ try {
176
+ const detected = await detector.detect();
177
+ pythonExecutable = detected.executable;
178
+ logger.info(`Auto-detected Python: ${detected.executable} (${detected.version})`);
179
+ }
180
+ catch {
181
+ logger.warn('No Python detected — using system default "python3"');
182
+ pythonExecutable = 'python3';
183
+ }
184
+ }
185
+ return pythonExecutable;
186
+ }
187
+ async _bootstrapPythonRuntime() {
188
+ try {
189
+ // Initialize nodepyx Python runtime helpers
190
+ const bootstrapCode = `
191
+ import sys
192
+ import os
193
+
194
+ # Add nodepyx runtime to path
195
+ _nodepyx_runtime_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'python')
196
+ if _nodepyx_runtime_dir not in sys.path:
197
+ sys.path.insert(0, _nodepyx_runtime_dir)
198
+
199
+ # Initialize runtime
200
+ try:
201
+ import nodepyx_runtime
202
+ nodepyx_runtime.initialize()
203
+ except ImportError:
204
+ pass # Runtime helpers not available, basic operation only
205
+ `;
206
+ await this._addon.runPythonCode(bootstrapCode);
207
+ logger.debug('Python runtime helpers bootstrapped');
208
+ }
209
+ catch (err) {
210
+ // Non-fatal — runtime helpers are optional
211
+ logger.warn('Failed to bootstrap Python runtime helpers', err);
212
+ }
213
+ }
214
+ // ─── Module Import ──────────────────────────────────────────────────────────
215
+ /**
216
+ * Import a Python module and return a PyProxy.
217
+ *
218
+ * @example
219
+ * ```typescript
220
+ * const pd = await runtime.import('pandas');
221
+ * const df = await pd.read_csv('data.csv');
222
+ * ```
223
+ */
224
+ async import(moduleName) {
225
+ this._ensureRunning();
226
+ // Check cache
227
+ if (this._moduleCache.has(moduleName)) {
228
+ return this._moduleCache.get(moduleName);
229
+ }
230
+ logger.debug(`Importing Python module: ${moduleName}`);
231
+ const result = await this._addon.importModule(moduleName);
232
+ if (!result.success) {
233
+ if (result.error) {
234
+ throw (0, ErrorTranslator_1.translatePythonError)({
235
+ type: result.error.type,
236
+ message: result.error.message,
237
+ traceback: result.error.traceback || '',
238
+ });
239
+ }
240
+ throw new Error(`Failed to import Python module '${moduleName}'`);
241
+ }
242
+ if (!result.objectId) {
243
+ throw new Error(`Module '${moduleName}' imported but no object ID returned`);
244
+ }
245
+ // Run plugin hooks
246
+ await this._pluginManager.onModuleImported(moduleName, result.objectId);
247
+ // Create PyModule
248
+ const module = PyModule_1.PyModule.fromRef(result.objectId, moduleName, this._addon, this._config.callTimeout);
249
+ // Generate TypeScript stubs (background, non-blocking)
250
+ // TypeScript stub generation (non-blocking, background)
251
+ if (this._config.proxyCache) {
252
+ this._typeGenerator.generateStub(moduleName, { name: moduleName, functions: [], classes: [], constants: [], submodules: [] }).catch((err) => {
253
+ logger.debug(`Stub generation for ${moduleName} failed (non-fatal)`, err);
254
+ });
255
+ }
256
+ // Cache
257
+ this._moduleCache.set(moduleName, module);
258
+ logger.debug(`Module '${moduleName}' imported (id=${result.objectId})`);
259
+ return module;
260
+ }
261
+ /**
262
+ * Import multiple modules at once (concurrent).
263
+ */
264
+ async importAll(moduleNames) {
265
+ const modules = await Promise.all(moduleNames.map(async (name) => [name, await this.import(name)]));
266
+ return Object.fromEntries(modules);
267
+ }
268
+ // ─── Code Execution ────────────────────────────────────────────────────────
269
+ /**
270
+ * Evaluate a Python expression.
271
+ */
272
+ async eval(expression) {
273
+ this._ensureRunning();
274
+ const result = await this._addon.evalPython(expression);
275
+ if (!result.success) {
276
+ if (result.error) {
277
+ throw (0, ErrorTranslator_1.translatePythonError)({
278
+ type: result.error.type,
279
+ message: result.error.message,
280
+ traceback: result.error.traceback || '',
281
+ });
282
+ }
283
+ throw new Error('Python eval failed');
284
+ }
285
+ if (result.isObject && result.objectId) {
286
+ return PyProxy_1.PyProxy._createFromObjectId(result.objectId, [], this._addon, this._config.callTimeout);
287
+ }
288
+ if (result.resultJson !== undefined) {
289
+ try {
290
+ return JSON.parse(result.resultJson);
291
+ }
292
+ catch {
293
+ return result.resultJson;
294
+ }
295
+ }
296
+ return null;
297
+ }
298
+ /**
299
+ * Execute Python statements.
300
+ */
301
+ async exec(code) {
302
+ this._ensureRunning();
303
+ const result = await this._addon.runPythonCode(code);
304
+ if (!result.success && result.error) {
305
+ throw (0, ErrorTranslator_1.translatePythonError)({
306
+ type: result.error.type,
307
+ message: result.error.message,
308
+ traceback: result.error.traceback || '',
309
+ });
310
+ }
311
+ }
312
+ /**
313
+ * Run a Python script file.
314
+ */
315
+ async runFile(filePath) {
316
+ this._ensureRunning();
317
+ const result = await this._addon.runPythonFile(filePath);
318
+ if (!result.success) {
319
+ if (result.error) {
320
+ throw (0, ErrorTranslator_1.translatePythonError)({
321
+ type: result.error.type,
322
+ message: result.error.message,
323
+ traceback: result.error.traceback || '',
324
+ });
325
+ }
326
+ throw new Error('Failed to run Python file');
327
+ }
328
+ return null;
329
+ }
330
+ // ─── Context Management ─────────────────────────────────────────────────────
331
+ /**
332
+ * Create an isolated Python execution context.
333
+ */
334
+ async createContext() {
335
+ this._ensureRunning();
336
+ return PyContext_1.PyContext.create(this._addon);
337
+ }
338
+ // ─── Package Management ────────────────────────────────────────────────────
339
+ /**
340
+ * Install Python packages into the active environment.
341
+ */
342
+ async installPackages(packages) {
343
+ this._ensureRunning();
344
+ const installer = new PackageInstaller_1.PackageInstaller({ pythonExecutable: this._config.pythonExecutable });
345
+ await installer.install(packages);
346
+ // Clear module cache so re-imports work
347
+ this._moduleCache.clear();
348
+ }
349
+ // ─── Memory Management ─────────────────────────────────────────────────────
350
+ /**
351
+ * Get current memory statistics.
352
+ */
353
+ getMemoryStats() {
354
+ this._ensureRunning();
355
+ return this._addon.getMemoryStats();
356
+ }
357
+ /**
358
+ * Trigger Python garbage collection.
359
+ */
360
+ async collectGarbage() {
361
+ this._ensureRunning();
362
+ await this._addon.collectGarbage();
363
+ }
364
+ // ─── Direct Addon Access ───────────────────────────────────────────────────
365
+ /**
366
+ * Get the underlying native addon.
367
+ * Advanced use only.
368
+ */
369
+ getAddon() {
370
+ return this._addon;
371
+ }
372
+ // ─── State ─────────────────────────────────────────────────────────────────
373
+ isRunning() {
374
+ return this._running;
375
+ }
376
+ getConfig() {
377
+ return { ...this._config };
378
+ }
379
+ // ─── Shutdown ──────────────────────────────────────────────────────────────
380
+ /**
381
+ * Gracefully shut down the Python runtime.
382
+ * Releases all Python objects and finalizes the interpreter.
383
+ */
384
+ async shutdown() {
385
+ if (!this._running) {
386
+ return;
387
+ }
388
+ logger.info('Shutting down PyRuntime...');
389
+ this._running = false;
390
+ // Stop memory monitoring
391
+ this._memoryMonitor.stopMonitoring();
392
+ // Clear caches
393
+ this._moduleCache.clear();
394
+ // Finalize Python interpreter
395
+ try {
396
+ await this._addon.finalizePython();
397
+ logger.success('PyRuntime shut down');
398
+ }
399
+ catch (err) {
400
+ logger.error('Error during Python finalization', err);
401
+ throw err;
402
+ }
403
+ }
404
+ /**
405
+ * Synchronous shutdown (for process.on('exit') handler).
406
+ * Best-effort only — may not complete all cleanup.
407
+ */
408
+ shutdownSync() {
409
+ if (!this._running) {
410
+ return;
411
+ }
412
+ this._running = false;
413
+ this._memoryMonitor.stopMonitoring();
414
+ this._moduleCache.clear();
415
+ // Cannot await here — best effort
416
+ logger.debug('Synchronous shutdown initiated');
417
+ }
418
+ // ─── Private Helpers ───────────────────────────────────────────────────────
419
+ _ensureRunning() {
420
+ if (!this._running) {
421
+ throw new ErrorTranslator_1.nodepyxShutdownError('PyRuntime has been shut down. Create a new runtime with PyRuntime.create().');
422
+ }
423
+ }
424
+ _parseBytes(str) {
425
+ const match = str.match(/^(\d+(?:\.\d+)?)\s*(B|KB|MB|GB|TB)?$/i);
426
+ if (!match) {
427
+ return 1_073_741_824;
428
+ }
429
+ const value = parseFloat(match[1]);
430
+ const unit = (match[2] ?? 'B').toUpperCase();
431
+ const units = {
432
+ B: 1, KB: 1024, MB: 1024 ** 2, GB: 1024 ** 3, TB: 1024 ** 4,
433
+ };
434
+ return Math.floor(value * (units[unit] ?? 1));
435
+ }
436
+ }
437
+ exports.PyRuntime = PyRuntime;
438
+ //# sourceMappingURL=PyRuntime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PyRuntime.js","sourceRoot":"","sources":["../../src/core/PyRuntime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * nodepyx — CondaManager
3
+ * Manages Conda environments for Python package isolation.
4
+ *
5
+ * Supports:
6
+ * - Detecting an existing conda environment by name
7
+ * - Creating new conda environments
8
+ * - Installing packages into a conda environment (conda + pip fallback)
9
+ * - Returning the Python executable path inside a conda env
10
+ *
11
+ * Detection order for conda executable:
12
+ * 1. CONDA_EXE environment variable
13
+ * 2. MAMBA_EXE (uses mamba as a drop-in replacement)
14
+ * 3. condaPath from config
15
+ * 4. 'conda' on PATH
16
+ * 5. Common installation locations
17
+ */
18
+ import type { CondaConfig } from '../types/config';
19
+ export interface CondaEnvInfo {
20
+ /** Environment name */
21
+ name: string;
22
+ /** Absolute prefix path of the environment */
23
+ prefix: string;
24
+ /** Python executable inside the env */
25
+ pythonExecutable: string;
26
+ /** Whether this is the currently active environment */
27
+ isActive: boolean;
28
+ }
29
+ export interface CondaSetupResult {
30
+ /** Absolute path to Python executable */
31
+ pythonExecutable: string;
32
+ /** Whether the env was newly created */
33
+ created: boolean;
34
+ /** Whether packages were installed */
35
+ packagesInstalled: boolean;
36
+ /** Environment info */
37
+ envInfo: CondaEnvInfo;
38
+ }
39
+ export interface CondaManagerOptions {
40
+ /** Conda config from nodepyxConfig */
41
+ conda: CondaConfig;
42
+ /** Timeout for conda operations (ms). Default: 300000 (5 min) */
43
+ timeout?: number;
44
+ /** Use mamba instead of conda if available. Default: true */
45
+ preferMamba?: boolean;
46
+ }
47
+ /**
48
+ * CondaManager — manages Conda environments.
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * const manager = new CondaManager({
53
+ * conda: {
54
+ * envName: 'my-ml-env',
55
+ * packages: ['numpy', 'pandas', 'scikit-learn'],
56
+ * channels: ['conda-forge', 'defaults'],
57
+ * }
58
+ * });
59
+ *
60
+ * const result = await manager.setup();
61
+ * console.log(result.pythonExecutable); // /opt/conda/envs/my-ml-env/bin/python3
62
+ * ```
63
+ */
64
+ export declare class CondaManager {
65
+ private readonly _config;
66
+ private readonly _timeout;
67
+ private readonly _preferMamba;
68
+ private _condaExec;
69
+ constructor(options: CondaManagerOptions);
70
+ /**
71
+ * Set up the Conda environment.
72
+ * Creates the environment if it doesn't exist, then installs packages.
73
+ */
74
+ setup(): Promise<CondaSetupResult>;
75
+ /**
76
+ * List all conda environments.
77
+ */
78
+ listEnvironments(): Promise<CondaEnvInfo[]>;
79
+ /**
80
+ * Check if a conda environment exists.
81
+ */
82
+ environmentExists(envName: string): Promise<boolean>;
83
+ /**
84
+ * Get the Python executable for a conda environment.
85
+ */
86
+ getPythonExecutable(envName: string): Promise<string | null>;
87
+ /**
88
+ * Install packages into an existing environment.
89
+ */
90
+ installPackages(envName: string, packages: string[]): Promise<void>;
91
+ /**
92
+ * Remove a conda environment.
93
+ */
94
+ removeEnvironment(envName: string): Promise<void>;
95
+ /**
96
+ * Return the conda executable path (or null if not found).
97
+ */
98
+ get condaExecutable(): string | null;
99
+ private _findCondaExecutable;
100
+ private _ensureCondaExec;
101
+ private _findEnv;
102
+ private _getEnvInfo;
103
+ private _createEnv;
104
+ private _installPackages;
105
+ private _pythonInPrefix;
106
+ private _which;
107
+ }
108
+ export declare class CondaNotFoundError extends Error {
109
+ constructor(message: string);
110
+ }
111
+ export declare class CondaEnvError extends Error {
112
+ constructor(message: string);
113
+ }
114
+ export declare class CondaPackageInstallError extends Error {
115
+ readonly packages: string[];
116
+ constructor(packages: string[], detail: string);
117
+ }
118
+ //# sourceMappingURL=CondaManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CondaManager.d.ts","sourceRoot":"","sources":["../../src/env/CondaManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAMnD,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,gBAAgB,EAAE,MAAM,CAAC;IACzB,uDAAuD;IACvD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,gBAAgB,EAAE,MAAM,CAAC;IACzB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,sCAAsC;IACtC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uBAAuB;IACvB,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,KAAK,EAAE,WAAW,CAAC;IACnB,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA2BD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,UAAU,CAAuB;gBAE7B,OAAO,EAAE,mBAAmB;IAQxC;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,gBAAgB,CAAC;IA6CxC;;OAEG;IACG,gBAAgB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAmCjD;;OAEG;IACG,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1D;;OAEG;IACG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKlE;;OAEG;IACG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQzE;;OAEG;IACG,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAevD;;OAEG;IACH,IAAI,eAAe,IAAI,MAAM,GAAG,IAAI,CAEnC;IAID,OAAO,CAAC,oBAAoB;IA8B5B,OAAO,CAAC,gBAAgB;YAMV,QAAQ;YAUR,WAAW;YASX,UAAU;YA8BV,gBAAgB;IAmE9B,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,MAAM;CASf;AAID,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;gBAChB,QAAQ,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM;CAK/C"}