@camstack/kernel 0.1.2 → 0.1.3

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.
@@ -5,12 +5,8 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __esm = (fn, res) => function __init() {
9
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
- };
11
- var __export = (target, all) => {
12
- for (var name in all)
13
- __defProp(target, name, { get: all[name], enumerable: true });
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
14
10
  };
15
11
  var __copyProps = (to, from, except, desc) => {
16
12
  if (from && typeof from === "object" || typeof from === "function") {
@@ -29,110 +25,395 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
25
  mod
30
26
  ));
31
27
 
32
- // src/fs-utils.ts
33
- function ensureDir(dirPath) {
34
- fs.mkdirSync(dirPath, { recursive: true });
35
- }
36
- function copyDirRecursive(src, dest) {
37
- ensureDir(dest);
38
- const entries = fs.readdirSync(src, { withFileTypes: true });
39
- for (const entry of entries) {
40
- const srcPath = path.join(src, entry.name);
41
- const destPath = path.join(dest, entry.name);
42
- if (entry.isDirectory()) {
43
- copyDirRecursive(srcPath, destPath);
44
- } else {
45
- fs.copyFileSync(srcPath, destPath);
46
- }
28
+ // src/worker/worker-process-manager.js
29
+ var require_worker_process_manager = __commonJS({
30
+ "src/worker/worker-process-manager.js"(exports2) {
31
+ "use strict";
32
+ Object.defineProperty(exports2, "__esModule", { value: true });
33
+ exports2.WorkerProcessManager = void 0;
34
+ var node_child_process_1 = require("child_process");
35
+ var WorkerProcessManager2 = class {
36
+ sendToMain;
37
+ processes = /* @__PURE__ */ new Map();
38
+ constructor(sendToMain) {
39
+ this.sendToMain = sendToMain;
40
+ }
41
+ async spawn(config) {
42
+ const child = (0, node_child_process_1.spawn)(config.command, [...config.args ?? []], {
43
+ cwd: config.cwd,
44
+ env: config.env ? { ...process.env, ...config.env } : void 0,
45
+ stdio: ["pipe", "pipe", "pipe"]
46
+ });
47
+ const managed = new ManagedProcess(child, config, this.sendToMain);
48
+ this.processes.set(child.pid, managed);
49
+ this.sendToMain({
50
+ type: "SUB_PROCESS_SPAWNED",
51
+ pid: child.pid,
52
+ name: config.name,
53
+ command: config.command
54
+ });
55
+ child.on("exit", (code) => {
56
+ this.sendToMain({
57
+ type: "SUB_PROCESS_EXITED",
58
+ pid: child.pid,
59
+ code
60
+ });
61
+ if (config.autoRestart && managed.restartCount < (config.maxRestarts ?? 3)) {
62
+ managed.restartCount++;
63
+ setTimeout(() => {
64
+ this.spawn(config).catch(() => {
65
+ });
66
+ }, 2e3);
67
+ }
68
+ });
69
+ return managed;
70
+ }
71
+ listProcesses() {
72
+ return [...this.processes.values()].map((p) => p.toInfo());
73
+ }
74
+ getWorkerStats() {
75
+ const mem = process.memoryUsage();
76
+ const cpu = process.cpuUsage();
77
+ return {
78
+ pid: process.pid,
79
+ cpuPercent: (cpu.user + cpu.system) / 1e6,
80
+ memoryRss: mem.rss,
81
+ heapUsed: mem.heapUsed,
82
+ uptimeSeconds: Math.round(process.uptime()),
83
+ restartCount: 0,
84
+ state: "running"
85
+ };
86
+ }
87
+ async killAll() {
88
+ for (const [, proc] of this.processes) {
89
+ proc.kill("SIGTERM");
90
+ }
91
+ this.processes.clear();
92
+ }
93
+ };
94
+ exports2.WorkerProcessManager = WorkerProcessManager2;
95
+ var ManagedProcess = class {
96
+ child;
97
+ config;
98
+ sendToMain;
99
+ pid;
100
+ name;
101
+ restartCount = 0;
102
+ startedAt = Date.now();
103
+ exitHandlers = [];
104
+ errorHandlers = [];
105
+ constructor(child, config, sendToMain) {
106
+ this.child = child;
107
+ this.config = config;
108
+ this.sendToMain = sendToMain;
109
+ this.pid = child.pid;
110
+ this.name = config.name;
111
+ child.on("exit", (code) => {
112
+ for (const handler of this.exitHandlers)
113
+ handler(code);
114
+ });
115
+ child.on("error", (err) => {
116
+ for (const handler of this.errorHandlers)
117
+ handler(err);
118
+ });
119
+ }
120
+ getStats() {
121
+ return {
122
+ pid: this.pid,
123
+ cpuPercent: 0,
124
+ memoryRss: 0,
125
+ uptimeSeconds: Math.round((Date.now() - this.startedAt) / 1e3),
126
+ restartCount: this.restartCount,
127
+ state: this.child.exitCode !== null ? "stopped" : "running"
128
+ };
129
+ }
130
+ write(data) {
131
+ this.child.stdin?.write(data);
132
+ }
133
+ get stdout() {
134
+ return this.child.stdout;
135
+ }
136
+ get stderr() {
137
+ return this.child.stderr;
138
+ }
139
+ kill(signal = "SIGTERM") {
140
+ this.child.kill(signal);
141
+ }
142
+ wait() {
143
+ if (this.child.exitCode !== null) {
144
+ return Promise.resolve({ code: this.child.exitCode, signal: null });
145
+ }
146
+ return new Promise((resolve2) => {
147
+ this.child.on("exit", (code, signal) => {
148
+ resolve2({ code, signal });
149
+ });
150
+ });
151
+ }
152
+ onExit(handler) {
153
+ this.exitHandlers.push(handler);
154
+ }
155
+ onError(handler) {
156
+ this.errorHandlers.push(handler);
157
+ }
158
+ toInfo() {
159
+ return {
160
+ pid: this.pid,
161
+ name: this.name,
162
+ command: this.config.command,
163
+ state: this.child.exitCode !== null ? "stopped" : "running",
164
+ cpuPercent: 0,
165
+ memoryRss: 0,
166
+ uptimeSeconds: Math.round((Date.now() - this.startedAt) / 1e3)
167
+ };
168
+ }
169
+ };
47
170
  }
48
- }
49
- function stripCamstackDeps(pkg) {
50
- const result = { ...pkg };
51
- for (const depType of ["dependencies", "peerDependencies", "devDependencies"]) {
52
- const deps = result[depType];
53
- if (deps) {
54
- const filtered = {};
55
- for (const [name, version] of Object.entries(deps)) {
56
- if (!name.startsWith("@camstack/")) {
57
- filtered[name] = version;
171
+ });
172
+
173
+ // src/fs-utils.js
174
+ var require_fs_utils = __commonJS({
175
+ "src/fs-utils.js"(exports2) {
176
+ "use strict";
177
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
178
+ if (k2 === void 0) k2 = k;
179
+ var desc = Object.getOwnPropertyDescriptor(m, k);
180
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
181
+ desc = { enumerable: true, get: function() {
182
+ return m[k];
183
+ } };
184
+ }
185
+ Object.defineProperty(o, k2, desc);
186
+ }) : (function(o, m, k, k2) {
187
+ if (k2 === void 0) k2 = k;
188
+ o[k2] = m[k];
189
+ }));
190
+ var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
191
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
192
+ }) : function(o, v) {
193
+ o["default"] = v;
194
+ });
195
+ var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ (function() {
196
+ var ownKeys = function(o) {
197
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
198
+ var ar = [];
199
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
200
+ return ar;
201
+ };
202
+ return ownKeys(o);
203
+ };
204
+ return function(mod) {
205
+ if (mod && mod.__esModule) return mod;
206
+ var result = {};
207
+ if (mod != null) {
208
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
209
+ }
210
+ __setModuleDefault(result, mod);
211
+ return result;
212
+ };
213
+ })();
214
+ Object.defineProperty(exports2, "__esModule", { value: true });
215
+ exports2.ensureDir = ensureDir;
216
+ exports2.copyDirRecursive = copyDirRecursive;
217
+ exports2.stripCamstackDeps = stripCamstackDeps;
218
+ exports2.copyExtraFileDirs = copyExtraFileDirs;
219
+ exports2.symlinkAddonsToNodeModules = symlinkAddonsToNodeModules;
220
+ exports2.isSourceNewer = isSourceNewer;
221
+ exports2.ensureLibraryBuilt = ensureLibraryBuilt;
222
+ exports2.installPackageFromNpmSync = installPackageFromNpmSync;
223
+ var node_child_process_1 = require("child_process");
224
+ var fs2 = __importStar(require("fs"));
225
+ var path2 = __importStar(require("path"));
226
+ function ensureDir(dirPath) {
227
+ fs2.mkdirSync(dirPath, { recursive: true });
228
+ }
229
+ function copyDirRecursive(src, dest) {
230
+ ensureDir(dest);
231
+ const entries = fs2.readdirSync(src, { withFileTypes: true });
232
+ for (const entry of entries) {
233
+ const srcPath = path2.join(src, entry.name);
234
+ const destPath = path2.join(dest, entry.name);
235
+ if (entry.isDirectory()) {
236
+ copyDirRecursive(srcPath, destPath);
237
+ } else {
238
+ fs2.copyFileSync(srcPath, destPath);
58
239
  }
59
240
  }
60
- result[depType] = Object.keys(filtered).length > 0 ? filtered : void 0;
61
241
  }
62
- }
63
- delete result.devDependencies;
64
- return result;
65
- }
66
- function copyExtraFileDirs(pkgJson, sourceDir, destDir) {
67
- const files = pkgJson.files;
68
- if (!files) return;
69
- for (const fileEntry of files) {
70
- if (fileEntry === "dist" || fileEntry.includes("*")) continue;
71
- const srcPath = path.join(sourceDir, fileEntry);
72
- if (!fs.existsSync(srcPath)) continue;
73
- const destPath = path.join(destDir, fileEntry);
74
- const stat = fs.statSync(srcPath);
75
- if (stat.isDirectory()) {
76
- copyDirRecursive(srcPath, destPath);
77
- } else if (stat.isFile()) {
78
- ensureDir(path.dirname(destPath));
79
- fs.copyFileSync(srcPath, destPath);
242
+ function stripCamstackDeps(pkg) {
243
+ const result = { ...pkg };
244
+ for (const depType of ["dependencies", "peerDependencies", "devDependencies"]) {
245
+ const deps = result[depType];
246
+ if (deps) {
247
+ const filtered = {};
248
+ for (const [name, version] of Object.entries(deps)) {
249
+ if (!name.startsWith("@camstack/")) {
250
+ filtered[name] = version;
251
+ }
252
+ }
253
+ result[depType] = Object.keys(filtered).length > 0 ? filtered : void 0;
254
+ }
255
+ }
256
+ delete result.devDependencies;
257
+ return result;
80
258
  }
81
- }
82
- }
83
- function isSourceNewer(packageDir) {
84
- const srcDir = path.join(packageDir, "src");
85
- const distDir = path.join(packageDir, "dist");
86
- if (!fs.existsSync(srcDir) || !fs.existsSync(distDir)) return true;
87
- try {
88
- const distMtime = fs.statSync(distDir).mtimeMs;
89
- const entries = fs.readdirSync(srcDir, { withFileTypes: true, recursive: true });
90
- for (const entry of entries) {
91
- if (!entry.isFile()) continue;
92
- const filePath = path.join(entry.parentPath ?? entry.path, entry.name);
93
- if (fs.statSync(filePath).mtimeMs > distMtime) return true;
259
+ function copyExtraFileDirs(pkgJson, sourceDir, destDir) {
260
+ const files = pkgJson.files;
261
+ if (!files)
262
+ return;
263
+ for (const fileEntry of files) {
264
+ if (fileEntry === "dist" || fileEntry.includes("*"))
265
+ continue;
266
+ const srcPath = path2.join(sourceDir, fileEntry);
267
+ if (!fs2.existsSync(srcPath))
268
+ continue;
269
+ const destPath = path2.join(destDir, fileEntry);
270
+ const stat = fs2.statSync(srcPath);
271
+ if (stat.isDirectory()) {
272
+ copyDirRecursive(srcPath, destPath);
273
+ } else if (stat.isFile()) {
274
+ ensureDir(path2.dirname(destPath));
275
+ fs2.copyFileSync(srcPath, destPath);
276
+ }
277
+ }
278
+ }
279
+ function symlinkAddonsToNodeModules(addonsDir, nodeModulesDir) {
280
+ const camstackDir = path2.join(nodeModulesDir, "@camstack");
281
+ ensureDir(camstackDir);
282
+ const packagesToLink = ["core"];
283
+ for (const pkg of packagesToLink) {
284
+ const addonDir = path2.join(addonsDir, "@camstack", pkg);
285
+ const linkPath = path2.join(camstackDir, pkg);
286
+ if (!fs2.existsSync(addonDir))
287
+ continue;
288
+ try {
289
+ const stat = fs2.lstatSync(linkPath);
290
+ if (stat.isSymbolicLink() || stat.isDirectory()) {
291
+ fs2.rmSync(linkPath, { recursive: true, force: true });
292
+ }
293
+ } catch {
294
+ }
295
+ fs2.symlinkSync(addonDir, linkPath, "dir");
296
+ console.log(`[symlink] node_modules/@camstack/${pkg} -> ${addonDir}`);
297
+ }
298
+ }
299
+ function isSourceNewer(packageDir) {
300
+ const srcDir = path2.join(packageDir, "src");
301
+ const distDir = path2.join(packageDir, "dist");
302
+ if (!fs2.existsSync(srcDir) || !fs2.existsSync(distDir))
303
+ return true;
304
+ try {
305
+ const distMtime = fs2.statSync(distDir).mtimeMs;
306
+ const entries = fs2.readdirSync(srcDir, { withFileTypes: true, recursive: true });
307
+ for (const entry of entries) {
308
+ if (!entry.isFile())
309
+ continue;
310
+ const filePath = path2.join(entry.parentPath ?? entry.path, entry.name);
311
+ if (fs2.statSync(filePath).mtimeMs > distMtime)
312
+ return true;
313
+ }
314
+ return false;
315
+ } catch {
316
+ return true;
317
+ }
318
+ }
319
+ function ensureLibraryBuilt(packageName, packagesDir) {
320
+ const dirName = packageName.replace("@camstack/", "");
321
+ const sourceDir = path2.join(packagesDir, dirName);
322
+ if (!fs2.existsSync(sourceDir))
323
+ return;
324
+ const distDir = path2.join(sourceDir, "dist");
325
+ const hasIndex = fs2.existsSync(path2.join(distDir, "index.js")) || fs2.existsSync(path2.join(distDir, "index.mjs"));
326
+ if (hasIndex)
327
+ return;
328
+ console.warn(`[ensureLibraryBuilt] ${packageName} has no dist/ \u2014 run 'npm run build' first`);
329
+ }
330
+ function installPackageFromNpmSync(packageName, targetDir) {
331
+ const os2 = require("os");
332
+ const tmpDir = fs2.mkdtempSync(path2.join(os2.tmpdir(), "camstack-install-"));
333
+ try {
334
+ const stdout = (0, node_child_process_1.execFileSync)("npm", ["pack", packageName, "--pack-destination", tmpDir], {
335
+ timeout: 12e4,
336
+ encoding: "utf-8"
337
+ });
338
+ const tgzFilename = stdout.trim().split("\n").pop()?.trim();
339
+ if (!tgzFilename)
340
+ throw new Error("npm pack produced no output");
341
+ const tgzPath = path2.join(tmpDir, tgzFilename);
342
+ const extractDir = path2.join(tmpDir, "extracted");
343
+ ensureDir(extractDir);
344
+ (0, node_child_process_1.execFileSync)("tar", ["-xzf", tgzPath, "-C", extractDir], { timeout: 3e4 });
345
+ const packageSubDir = path2.join(extractDir, "package");
346
+ const srcPkgJsonDir = fs2.existsSync(path2.join(packageSubDir, "package.json")) ? packageSubDir : extractDir;
347
+ fs2.rmSync(targetDir, { recursive: true, force: true });
348
+ ensureDir(targetDir);
349
+ fs2.copyFileSync(path2.join(srcPkgJsonDir, "package.json"), path2.join(targetDir, "package.json"));
350
+ const distSrc = path2.join(srcPkgJsonDir, "dist");
351
+ if (fs2.existsSync(distSrc)) {
352
+ copyDirRecursive(distSrc, path2.join(targetDir, "dist"));
353
+ }
354
+ try {
355
+ const npmPkg = JSON.parse(fs2.readFileSync(path2.join(srcPkgJsonDir, "package.json"), "utf-8"));
356
+ copyExtraFileDirs(npmPkg, srcPkgJsonDir, targetDir);
357
+ } catch {
358
+ }
359
+ } finally {
360
+ fs2.rmSync(tmpDir, { recursive: true, force: true });
361
+ }
94
362
  }
95
- return false;
96
- } catch {
97
- return true;
98
- }
99
- }
100
- function ensureLibraryBuilt(packageName, packagesDir) {
101
- const dirName = packageName.replace("@camstack/", "");
102
- const sourceDir = path.join(packagesDir, dirName);
103
- if (!fs.existsSync(sourceDir)) return;
104
- const distDir = path.join(sourceDir, "dist");
105
- const hasIndex = fs.existsSync(path.join(distDir, "index.js")) || fs.existsSync(path.join(distDir, "index.mjs"));
106
- if (hasIndex) return;
107
- console.warn(`[ensureLibraryBuilt] ${packageName} has no dist/ \u2014 run 'npm run build' first`);
108
- }
109
- var import_node_child_process2, fs, path;
110
- var init_fs_utils = __esm({
111
- "src/fs-utils.ts"() {
112
- "use strict";
113
- import_node_child_process2 = require("child_process");
114
- fs = __toESM(require("fs"));
115
- path = __toESM(require("path"));
116
363
  }
117
364
  });
118
365
 
119
- // src/addon-installer.ts
120
- var addon_installer_exports = {};
121
- __export(addon_installer_exports, {
122
- AddonInstaller: () => AddonInstaller
123
- });
124
- var import_node_child_process3, import_node_util, fs2, path2, os, execFileAsync, AddonInstaller;
125
- var init_addon_installer = __esm({
126
- "src/addon-installer.ts"() {
366
+ // src/addon-installer.js
367
+ var require_addon_installer = __commonJS({
368
+ "src/addon-installer.js"(exports2) {
127
369
  "use strict";
128
- import_node_child_process3 = require("child_process");
129
- import_node_util = require("util");
130
- fs2 = __toESM(require("fs"));
131
- path2 = __toESM(require("path"));
132
- os = __toESM(require("os"));
133
- init_fs_utils();
134
- execFileAsync = (0, import_node_util.promisify)(import_node_child_process3.execFile);
135
- AddonInstaller = class _AddonInstaller {
370
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
371
+ if (k2 === void 0) k2 = k;
372
+ var desc = Object.getOwnPropertyDescriptor(m, k);
373
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
374
+ desc = { enumerable: true, get: function() {
375
+ return m[k];
376
+ } };
377
+ }
378
+ Object.defineProperty(o, k2, desc);
379
+ }) : (function(o, m, k, k2) {
380
+ if (k2 === void 0) k2 = k;
381
+ o[k2] = m[k];
382
+ }));
383
+ var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
384
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
385
+ }) : function(o, v) {
386
+ o["default"] = v;
387
+ });
388
+ var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ (function() {
389
+ var ownKeys = function(o) {
390
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
391
+ var ar = [];
392
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
393
+ return ar;
394
+ };
395
+ return ownKeys(o);
396
+ };
397
+ return function(mod) {
398
+ if (mod && mod.__esModule) return mod;
399
+ var result = {};
400
+ if (mod != null) {
401
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
402
+ }
403
+ __setModuleDefault(result, mod);
404
+ return result;
405
+ };
406
+ })();
407
+ Object.defineProperty(exports2, "__esModule", { value: true });
408
+ exports2.AddonInstaller = void 0;
409
+ var node_child_process_1 = require("child_process");
410
+ var node_util_1 = require("util");
411
+ var fs2 = __importStar(require("fs"));
412
+ var path2 = __importStar(require("path"));
413
+ var os2 = __importStar(require("os"));
414
+ var fs_utils_js_1 = require_fs_utils();
415
+ var execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
416
+ var AddonInstaller = class _AddonInstaller {
136
417
  addonsDir;
137
418
  registry;
138
419
  workspacePackagesDir;
@@ -154,18 +435,18 @@ var init_addon_installer = __esm({
154
435
  ];
155
436
  /** Ensure the addons directory exists */
156
437
  async initialize() {
157
- ensureDir(this.addonsDir);
438
+ (0, fs_utils_js_1.ensureDir)(this.addonsDir);
158
439
  }
159
440
  /**
160
441
  * Ensure all required packages are installed in the addons directory.
161
442
  * This replaces the standalone first-boot-installer.ts.
162
443
  */
163
444
  async ensureRequiredPackages() {
164
- ensureDir(this.addonsDir);
445
+ (0, fs_utils_js_1.ensureDir)(this.addonsDir);
165
446
  if (this.workspacePackagesDir) {
166
447
  console.log(`[AddonInstaller] Workspace detected: ${this.workspacePackagesDir}`);
167
- ensureLibraryBuilt("@camstack/kernel", this.workspacePackagesDir);
168
- ensureLibraryBuilt("@camstack/types", this.workspacePackagesDir);
448
+ (0, fs_utils_js_1.ensureLibraryBuilt)("@camstack/kernel", this.workspacePackagesDir);
449
+ (0, fs_utils_js_1.ensureLibraryBuilt)("@camstack/types", this.workspacePackagesDir);
169
450
  }
170
451
  for (const packageName of _AddonInstaller.REQUIRED_PACKAGES) {
171
452
  const addonDir = path2.join(this.addonsDir, packageName);
@@ -177,7 +458,7 @@ var init_addon_installer = __esm({
177
458
  continue;
178
459
  }
179
460
  const srcPkgDir = this.findWorkspacePackage(packageName);
180
- if (srcPkgDir && !isSourceNewer(srcPkgDir)) {
461
+ if (srcPkgDir && !(0, fs_utils_js_1.isSourceNewer)(srcPkgDir)) {
181
462
  continue;
182
463
  }
183
464
  }
@@ -200,14 +481,16 @@ var init_addon_installer = __esm({
200
481
  }
201
482
  }
202
483
  findWorkspacePackage(packageName) {
203
- if (!this.workspacePackagesDir) return null;
484
+ if (!this.workspacePackagesDir)
485
+ return null;
204
486
  const shortName = packageName.replace("@camstack/", "");
205
487
  for (const dirName of [shortName, `addon-${shortName}`, shortName.replace("addon-", "")]) {
206
488
  const candidate = path2.join(this.workspacePackagesDir, dirName);
207
489
  if (fs2.existsSync(path2.join(candidate, "package.json"))) {
208
490
  try {
209
491
  const pkg = JSON.parse(fs2.readFileSync(path2.join(candidate, "package.json"), "utf-8"));
210
- if (pkg.name === packageName) return candidate;
492
+ if (pkg.name === packageName)
493
+ return candidate;
211
494
  } catch {
212
495
  }
213
496
  }
@@ -216,7 +499,7 @@ var init_addon_installer = __esm({
216
499
  }
217
500
  /** Install addon from a tgz file (uploaded or downloaded) */
218
501
  async installFromTgz(tgzPath) {
219
- const tmpDir = fs2.mkdtempSync(path2.join(os.tmpdir(), "camstack-addon-install-"));
502
+ const tmpDir = fs2.mkdtempSync(path2.join(os2.tmpdir(), "camstack-addon-install-"));
220
503
  try {
221
504
  await execFileAsync("tar", ["-xzf", tgzPath, "-C", tmpDir], { timeout: 3e4 });
222
505
  const extractedDir = path2.join(tmpDir, "package");
@@ -230,14 +513,14 @@ var init_addon_installer = __esm({
230
513
  }
231
514
  const targetDir = path2.join(this.addonsDir, pkgJson.name);
232
515
  fs2.rmSync(targetDir, { recursive: true, force: true });
233
- ensureDir(targetDir);
516
+ (0, fs_utils_js_1.ensureDir)(targetDir);
234
517
  const sourceDir = path2.dirname(pkgJsonPath);
235
518
  fs2.copyFileSync(pkgJsonPath, path2.join(targetDir, "package.json"));
236
519
  const sourceDist = path2.join(sourceDir, "dist");
237
520
  if (fs2.existsSync(sourceDist)) {
238
- copyDirRecursive(sourceDist, path2.join(targetDir, "dist"));
521
+ (0, fs_utils_js_1.copyDirRecursive)(sourceDist, path2.join(targetDir, "dist"));
239
522
  }
240
- copyExtraFileDirs(pkgJson, sourceDir, targetDir);
523
+ (0, fs_utils_js_1.copyExtraFileDirs)(pkgJson, sourceDir, targetDir);
241
524
  return { name: pkgJson.name, version: pkgJson.version };
242
525
  } finally {
243
526
  fs2.rmSync(tmpDir, { recursive: true, force: true });
@@ -277,12 +560,12 @@ var init_addon_installer = __esm({
277
560
  }
278
561
  const targetDir = path2.join(this.addonsDir, packageName);
279
562
  fs2.rmSync(targetDir, { recursive: true, force: true });
280
- ensureDir(targetDir);
563
+ (0, fs_utils_js_1.ensureDir)(targetDir);
281
564
  const pkgData = JSON.parse(fs2.readFileSync(sourcePkgJson, "utf-8"));
282
- const strippedPkg = stripCamstackDeps(pkgData);
565
+ const strippedPkg = (0, fs_utils_js_1.stripCamstackDeps)(pkgData);
283
566
  fs2.writeFileSync(path2.join(targetDir, "package.json"), JSON.stringify(strippedPkg, null, 2));
284
- copyDirRecursive(distDir, path2.join(targetDir, "dist"));
285
- copyExtraFileDirs(pkgData, sourceDir, targetDir);
567
+ (0, fs_utils_js_1.copyDirRecursive)(distDir, path2.join(targetDir, "dist"));
568
+ (0, fs_utils_js_1.copyExtraFileDirs)(pkgData, sourceDir, targetDir);
286
569
  try {
287
570
  await execFileAsync("npm", ["install", "--omit=dev", "--ignore-scripts=false"], {
288
571
  cwd: targetDir,
@@ -294,7 +577,7 @@ var init_addon_installer = __esm({
294
577
  }
295
578
  /** Install addon from npm (download tgz, then extract) */
296
579
  async installFromNpm(packageName, version) {
297
- const tmpDir = fs2.mkdtempSync(path2.join(os.tmpdir(), "camstack-addon-npm-"));
580
+ const tmpDir = fs2.mkdtempSync(path2.join(os2.tmpdir(), "camstack-addon-npm-"));
298
581
  const packageSpec = version ? `${packageName}@${version}` : packageName;
299
582
  const args = ["pack", packageSpec, "--pack-destination", tmpDir];
300
583
  if (this.registry) {
@@ -329,13 +612,16 @@ var init_addon_installer = __esm({
329
612
  }
330
613
  /** List installed addons (directories with package.json containing camstack.addons) */
331
614
  listInstalled() {
332
- if (!fs2.existsSync(this.addonsDir)) return [];
615
+ if (!fs2.existsSync(this.addonsDir))
616
+ return [];
333
617
  return fs2.readdirSync(this.addonsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => {
334
618
  const pkgPath = path2.join(this.addonsDir, d.name, "package.json");
335
- if (!fs2.existsSync(pkgPath)) return null;
619
+ if (!fs2.existsSync(pkgPath))
620
+ return null;
336
621
  try {
337
622
  const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
338
- if (!pkg.camstack?.addons) return null;
623
+ if (!pkg.camstack?.addons)
624
+ return null;
339
625
  return { name: pkg.name, version: pkg.version, dir: path2.join(this.addonsDir, d.name) };
340
626
  } catch {
341
627
  return null;
@@ -344,7 +630,8 @@ var init_addon_installer = __esm({
344
630
  }
345
631
  /** Check if an addon is installed */
346
632
  isInstalled(packageName) {
347
- if (fs2.existsSync(path2.join(this.addonsDir, packageName, "package.json"))) return true;
633
+ if (fs2.existsSync(path2.join(this.addonsDir, packageName, "package.json")))
634
+ return true;
348
635
  const legacy = packageName.replace(/^@[^/]+\//, "");
349
636
  return fs2.existsSync(path2.join(this.addonsDir, legacy, "package.json"));
350
637
  }
@@ -354,7 +641,8 @@ var init_addon_installer = __esm({
354
641
  if (!fs2.existsSync(pkgPath)) {
355
642
  pkgPath = path2.join(this.addonsDir, packageName.replace(/^@[^/]+\//, ""), "package.json");
356
643
  }
357
- if (!fs2.existsSync(pkgPath)) return null;
644
+ if (!fs2.existsSync(pkgPath))
645
+ return null;
358
646
  try {
359
647
  const pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
360
648
  return { name: pkg.name, version: pkg.version, dir: path2.dirname(pkgPath) };
@@ -363,146 +651,15 @@ var init_addon_installer = __esm({
363
651
  }
364
652
  }
365
653
  };
654
+ exports2.AddonInstaller = AddonInstaller;
366
655
  }
367
656
  });
368
657
 
369
658
  // src/worker/addon-worker-entry.ts
370
- var os2 = __toESM(require("os"));
371
- var fs3 = __toESM(require("fs"));
372
- var path3 = __toESM(require("path"));
373
-
374
- // src/worker/worker-process-manager.ts
375
- var import_node_child_process = require("child_process");
376
- var WorkerProcessManager = class {
377
- constructor(sendToMain) {
378
- this.sendToMain = sendToMain;
379
- }
380
- processes = /* @__PURE__ */ new Map();
381
- async spawn(config) {
382
- const child = (0, import_node_child_process.spawn)(config.command, [...config.args ?? []], {
383
- cwd: config.cwd,
384
- env: config.env ? { ...process.env, ...config.env } : void 0,
385
- stdio: ["pipe", "pipe", "pipe"]
386
- });
387
- const managed = new ManagedProcess(child, config, this.sendToMain);
388
- this.processes.set(child.pid, managed);
389
- this.sendToMain({
390
- type: "SUB_PROCESS_SPAWNED",
391
- pid: child.pid,
392
- name: config.name,
393
- command: config.command
394
- });
395
- child.on("exit", (code) => {
396
- this.sendToMain({
397
- type: "SUB_PROCESS_EXITED",
398
- pid: child.pid,
399
- code
400
- });
401
- if (config.autoRestart && managed.restartCount < (config.maxRestarts ?? 3)) {
402
- managed.restartCount++;
403
- setTimeout(() => {
404
- this.spawn(config).catch(() => {
405
- });
406
- }, 2e3);
407
- }
408
- });
409
- return managed;
410
- }
411
- listProcesses() {
412
- return [...this.processes.values()].map((p) => p.toInfo());
413
- }
414
- getWorkerStats() {
415
- const mem = process.memoryUsage();
416
- const cpu = process.cpuUsage();
417
- return {
418
- pid: process.pid,
419
- cpuPercent: (cpu.user + cpu.system) / 1e6,
420
- memoryRss: mem.rss,
421
- heapUsed: mem.heapUsed,
422
- uptimeSeconds: Math.round(process.uptime()),
423
- restartCount: 0,
424
- state: "running"
425
- };
426
- }
427
- async killAll() {
428
- for (const [, proc] of this.processes) {
429
- proc.kill("SIGTERM");
430
- }
431
- this.processes.clear();
432
- }
433
- };
434
- var ManagedProcess = class {
435
- constructor(child, config, sendToMain) {
436
- this.child = child;
437
- this.config = config;
438
- this.sendToMain = sendToMain;
439
- this.pid = child.pid;
440
- this.name = config.name;
441
- child.on("exit", (code) => {
442
- for (const handler of this.exitHandlers) handler(code);
443
- });
444
- child.on("error", (err) => {
445
- for (const handler of this.errorHandlers) handler(err);
446
- });
447
- }
448
- pid;
449
- name;
450
- restartCount = 0;
451
- startedAt = Date.now();
452
- exitHandlers = [];
453
- errorHandlers = [];
454
- getStats() {
455
- return {
456
- pid: this.pid,
457
- cpuPercent: 0,
458
- memoryRss: 0,
459
- uptimeSeconds: Math.round((Date.now() - this.startedAt) / 1e3),
460
- restartCount: this.restartCount,
461
- state: this.child.exitCode !== null ? "stopped" : "running"
462
- };
463
- }
464
- write(data) {
465
- this.child.stdin?.write(data);
466
- }
467
- get stdout() {
468
- return this.child.stdout;
469
- }
470
- get stderr() {
471
- return this.child.stderr;
472
- }
473
- kill(signal = "SIGTERM") {
474
- this.child.kill(signal);
475
- }
476
- wait() {
477
- if (this.child.exitCode !== null) {
478
- return Promise.resolve({ code: this.child.exitCode, signal: null });
479
- }
480
- return new Promise((resolve2) => {
481
- this.child.on("exit", (code, signal) => {
482
- resolve2({ code, signal });
483
- });
484
- });
485
- }
486
- onExit(handler) {
487
- this.exitHandlers.push(handler);
488
- }
489
- onError(handler) {
490
- this.errorHandlers.push(handler);
491
- }
492
- toInfo() {
493
- return {
494
- pid: this.pid,
495
- name: this.name,
496
- command: this.config.command,
497
- state: this.child.exitCode !== null ? "stopped" : "running",
498
- cpuPercent: 0,
499
- memoryRss: 0,
500
- uptimeSeconds: Math.round((Date.now() - this.startedAt) / 1e3)
501
- };
502
- }
503
- };
504
-
505
- // src/worker/addon-worker-entry.ts
659
+ var os = __toESM(require("os"));
660
+ var fs = __toESM(require("fs"));
661
+ var path = __toESM(require("path"));
662
+ var import_worker_process_manager = __toESM(require_worker_process_manager());
506
663
  async function boot() {
507
664
  const hubUrl = process.env.CAMSTACK_WORKER_HUB_URL;
508
665
  const token = process.env.CAMSTACK_WORKER_TOKEN ?? "";
@@ -530,14 +687,14 @@ async function boot() {
530
687
  id: workerId,
531
688
  name: addonId,
532
689
  capabilities: [],
533
- platform: os2.platform(),
534
- arch: os2.arch(),
535
- cpuCores: os2.cpus().length,
536
- memoryMB: Math.round(os2.totalmem() / 1024 / 1024),
690
+ platform: os.platform(),
691
+ arch: os.arch(),
692
+ cpuCores: os.cpus().length,
693
+ memoryMB: Math.round(os.totalmem() / 1024 / 1024),
537
694
  pythonRuntimes: [],
538
695
  installedAddons: [addonId],
539
696
  taskTypes: [],
540
- host: os2.hostname(),
697
+ host: os.hostname(),
541
698
  port: 0,
542
699
  httpPort: 0
543
700
  });
@@ -567,10 +724,10 @@ async function boot() {
567
724
  };
568
725
  }
569
726
  const logger = createScopedLogger([addonId]);
570
- const processManager = new WorkerProcessManager(() => {
727
+ const processManager = new import_worker_process_manager.WorkerProcessManager(() => {
571
728
  });
572
- const pkgJsonPath = path3.join(addonDir, "package.json");
573
- const pkgJson = JSON.parse(fs3.readFileSync(pkgJsonPath, "utf-8"));
729
+ const pkgJsonPath = path.join(addonDir, "package.json");
730
+ const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
574
731
  const manifest = pkgJson.camstack;
575
732
  if (!manifest?.addons?.length) {
576
733
  console.error(`[worker:${addonId}] No camstack addon manifest in ${pkgJsonPath}`);
@@ -582,10 +739,10 @@ async function boot() {
582
739
  process.exit(1);
583
740
  }
584
741
  const entryFile = declaration.entry.replace(/^\.\//, "").replace(/^src\//, "dist/").replace(/\.ts$/, ".js");
585
- let entryPath = path3.resolve(addonDir, entryFile);
586
- if (!fs3.existsSync(entryPath)) {
742
+ let entryPath = path.resolve(addonDir, entryFile);
743
+ if (!fs.existsSync(entryPath)) {
587
744
  const cjsPath = entryPath.replace(/\.js$/, ".cjs");
588
- if (fs3.existsSync(cjsPath)) entryPath = cjsPath;
745
+ if (fs.existsSync(cjsPath)) entryPath = cjsPath;
589
746
  }
590
747
  const mod = await import(entryPath);
591
748
  const firstKey = Object.keys(mod)[0];
@@ -642,8 +799,8 @@ async function boot() {
642
799
  try {
643
800
  let result;
644
801
  if (task.taskType === "addon.install") {
645
- const { AddonInstaller: AddonInstaller2 } = await Promise.resolve().then(() => (init_addon_installer(), addon_installer_exports));
646
- const installer = new AddonInstaller2({ addonsDir: path3.dirname(addonDir) });
802
+ const { AddonInstaller } = await Promise.resolve().then(() => __toESM(require_addon_installer()));
803
+ const installer = new AddonInstaller({ addonsDir: path.dirname(addonDir) });
647
804
  const payload = task.payload;
648
805
  result = await installer.installFromNpm(payload.package, payload.version);
649
806
  } else if (typeof addon.handleTask === "function") {