@zuzjs/pm 0.0.5 → 0.0.6

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.
@@ -0,0 +1,7 @@
1
+ 'use strict';var p=require('fs'),R=require('net'),k=require('os'),w=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var p__default=/*#__PURE__*/_interopDefault(p);var R__default=/*#__PURE__*/_interopDefault(R);var k__default=/*#__PURE__*/_interopDefault(k);var w__default=/*#__PURE__*/_interopDefault(w);/* ZuzJS Process Manager */
2
+ var h=()=>typeof document>"u"?new URL(`file:${__filename}`).href:document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?document.currentScript.src:new URL("main.js",document.baseURI).href,d=h();var P=(s=>(s.Fork="fork",s.Cluster="cluster",s))(P||{}),x=(o=>(o.Stopped="stopped",o.Starting="starting",o.Running="running",o.Stopping="stopping",o.Crashed="crashed",o.Errored="errored",o))(x||{});var y={info:"\x1B[36m",warn:"\x1B[33m",error:"\x1B[31m",debug:"\x1B[90m",success:"\x1B[32m"},v="\x1B[0m",$="\x1B[1m";function I(){return new Date().toISOString()}function l(e,r,...s){let n=y[e],t=`${$}${n}[ZPM/${r.toUpperCase()}]${v} ${I()}`;console[e==="success"?"log":e](`${t} \u2192`,...s);}var f={info:(e,...r)=>l("info",e,...r),warn:(e,...r)=>l("warn",e,...r),error:(e,...r)=>l("error",e,...r),debug:(e,...r)=>l("debug",e,...r),success:(e,...r)=>l("success",e,...r)};function L(e="zuz-pm"){return k__default.default.platform()==="win32"?w__default.default.join("\\\\.\\pipe",e):w__default.default.join(k__default.default.tmpdir(),`${e}.sock`)}function j(e){let r=L();p__default.default.existsSync(r)&&p__default.default.unlinkSync(r);let s=R__default.default.createServer(n=>{let t="";n.on("data",i=>{t+=i.toString();let o=t.split(`
3
+ `);t=o.pop()??"";for(let u of o)u.trim()&&T(e,n,u);}),n.on("error",i=>{f.error("IPC","Socket error:",i.message);});});return s.listen(r,()=>{if(k__default.default.platform()!=="win32")try{p__default.default.chmodSync(r,"777");}catch(n){console.error("Failed to set socket permissions:",n);}f.success("IPC",`Listening on ${r}`);}),s.on("error",n=>{f.error("IPC","Server error:",n);}),s}async function T(e,r,s){let n;try{n=JSON.parse(s);}catch{b(r,{ok:false,error:"Invalid JSON"});return}try{let t=null;switch(n.cmd){case "ping":t="pong";break;case "start":await e.start(n.config),t=`Started "${n.name}"`;break;case "stop":await e.stop(n.name),t=`Stopped "${n.name}"`;break;case "restart":await e.restart(n.name),t=`Restarted "${n.name}"`;break;case "delete":await e.delete(n.name),t=`Deleted "${n.name}"`;break;case "stats":t=await e.getStats(n.name);break;case "list":t=e.list();break;case "logs":let i=n.name,o=[];if(i){let a=e.getWorker(i);if(!a){r.write(JSON.stringify({ok:!1,error:`Worker "${i}" not found`})+`
4
+ `);return}o.push(a);}else {let a=e.list();for(let m of a){let c=e.getWorker(m);c&&o.push(c);}}if(o.length===0){r.write(JSON.stringify({ok:!1,error:"No active workers to stream logs from"})+`
5
+ `);return}let u=[];for(let a of o){let m=a.mp();for(let c of m.children){let g=S=>{let C=i?"":`[${a.name}] `;r.write(JSON.stringify({ok:!0,data:`${C}${S.toString()}`})+`
6
+ `);};c.stdout?.on("data",g),c.stderr?.on("data",g),u.push({child:c,onData:g});}}r.on("close",()=>{for(let{child:a,onData:m}of u)a.stdout?.off("data",m),a.stderr?.off("data",m);});break;default:throw new Error(`Unknown command: ${n.cmd}`)}b(r,{ok:!0,data:t});}catch(t){b(r,{ok:false,error:String(t.message??t)});}}function b(e,r){e.writable&&e.write(JSON.stringify(r)+`
7
+ `);}exports.a=d;exports.b=P;exports.c=x;exports.d=f;exports.e=L;exports.f=j;
@@ -0,0 +1 @@
1
+ import {d as d$1}from'./chunk-2PXF47OQ.js';import v from'events';import {spawn,exec}from'child_process';import y from'http';import W from'https';import C from'net';import $ from'chokidar';import I from'fs';import _ from'os';import g from'path';import w from'ws';import A from'pidusage';var p=class extends v{map=new Map;set(t,e){this.map.set(t,e),this.emit("change",t,e);}get(t){return this.map.get(t)}has(t){return this.map.has(t)}delete(t){this.map.delete(t),this.emit("delete",t);}all(){return new Map(this.map)}onchange(t){return this.on("change",t)}offchange(t){return this.off("change",t)}},c=new p;function F(s,t){return new Promise(e=>{let n=(s.startsWith("https")?W:y).get(s,{timeout:t},i=>{e((i.statusCode??500)<500);});n.on("error",()=>e(false)),n.on("timeout",()=>{n.destroy(),e(false);});})}function x(s,t){let[e,r]=s.split(":"),n=Number(r);return new Promise(i=>{let a=C.createConnection({host:e,port:n},()=>{a.destroy(),i(true);});a.setTimeout(t),a.on("timeout",()=>{a.destroy(),i(false);}),a.on("error",()=>i(false));})}function M(s,t){return new Promise(e=>{let r=setTimeout(()=>e(false),t);exec(s,n=>{clearTimeout(r),e(!n);});})}async function d(s){let t=(s.timeoutSeconds??5)*1e3;switch(s.type){case "http":return F(s.target,t);case "tcp":return x(s.target,t);case "exec":return M(s.target,t);default:return false}}var b=5e3,D=16e3,k=1e3,N=5e3;async function O(s){return new Promise(t=>{C.createServer().once("error",()=>t(false)).once("listening",function(){this.close(()=>t(true));}).listen(s);})}async function q(s){await O(s)||(d$1.warn("port",`Port ${s} busy \u2013 attempting fuser kill`),await new Promise(t=>exec(`fuser -k -9 ${s}/tcp 2>/dev/null; true`,()=>t())),await new Promise(t=>setTimeout(t,500)));}function P(s,t){let e=s.process?.pid??s.pid;if(!e)return;try{process.kill(e,"SIGTERM");}catch{return}let r=setTimeout(()=>{try{process.kill(e,"SIGKILL");}catch{}},t);s.once?.("exit",()=>clearTimeout(r)),s.once?.("exit",()=>clearTimeout(r));}var h=class{cfg;name;watcher=null;constructor(t){this.cfg={mode:"fork",instances:1,...t},this.name=t.name,this.initStore();}async start(){let t=this.mp();if(t.status==="running"||t.status==="starting"){d$1.warn(this.name,"Already running \u2013 ignoring start()");return}this.patch({status:"starting"}),await this.spawnAll(),this.cfg.devMode&&this.watchFiles();}async stop(){let t=this.mp();this.patch({status:"stopping",isRestarting:false}),this.clearTimers(),this.stopProbe();for(let e of t.children)P(e,this.cfg.killTimeout??b);this.stopWatcher(),this.patch({children:[],status:"stopped",startTime:null}),d$1.info(this.name,"Stopped.");}async restart(){d$1.info(this.name,"Restarting...");let t=this.mp();this.patch({isRestarting:true}),this.clearTimers(),this.stopProbe();for(let e of t.children)P(e,this.cfg.killTimeout??b);}async getStats(){let t=this.mp(),e=t.children[0]?.pid??null,r=null,n=null,i=null;if(e&&t.status==="running")try{let a=await A(e);r=a.cpu,n=a.memory;}catch{}return {name:this.name,status:t.status,pid:e,uptime:t.startTime?Date.now()-t.startTime:null,restartCount:t.restartCount,cpu:r,memoryRss:n,memoryHeap:i,mode:this.cfg.mode??"fork",instances:t.children.length}}async spawnAll(){if(!I.existsSync(this.cfg.scriptPath)){d$1.error(this.name,`Script not found: ${this.cfg.scriptPath}. Waiting for build...`),this.patch({status:"errored"});return}this.cfg.port&&await q(this.cfg.port);let t=this.cfg.mode??"fork",e=t==="cluster"?this.cfg.instances??_.cpus().length:1,r=[];for(let i=0;i<e;i++){let a=this.forkChild();a&&r.push(a);}this.patch({children:r,startTime:Date.now(),status:"running"}),d$1.success(this.name,`Started ${r.length} instance(s) [${t}]`);let n=setTimeout(()=>{this.mp().status==="running"&&(this.patch({backoffTime:k,restartCount:0}),d$1.success(this.name,"Process is stable."));},N);this.patch({stabilityTimer:n}),this.cfg.probe&&this.startProbe();}forkChild(){try{let t=this.cfg.scriptPath.endsWith(".js")?"node":this.cfg.scriptPath,e=this.cfg.scriptPath.endsWith(".js")?[this.cfg.scriptPath,...this.cfg.args??[]]:[...this.cfg.args??[]],r=spawn(t,e,{stdio:["ignore","pipe","pipe"],env:{...process.env,...this.cfg.env??{},NODE_ENV:this.cfg.devMode?"development":"production"},detached:!1,shell:!1});this.setupLogging(r);let n=Date.now();return r.on("error",i=>{d$1.error(this.name,"Spawn error:",i);}),r.on("exit",(i,a)=>{let l=Date.now()-n;this.onChildExit(r,i,a,l);}),r}catch(t){return d$1.error(this.name,"Failed to fork child:",t),null}}onChildExit(t,e,r,n){let i=this.mp(),a=i.children.filter(l=>l!==t);if(this.patch({children:a}),i.status!=="stopping"){if(d$1.warn(this.name,`Process exited (code=${e}, signal=${r}, uptime=${n}ms)`),i.isRestarting){a.length===0&&(this.patch({isRestarting:false}),this.spawnAll());return}if(e!==0&&e!==null){if(this.patch({status:"crashed"}),n<1500){d$1.error(this.name,`Immediate crash (${n}ms) \u2013 likely a syntax/build error. Waiting for next file change.`);return}this.scheduleRestart();}}}scheduleRestart(){let t=this.mp(),e=t.backoffTime,r=this.cfg.maxBackoff??D;d$1.warn(this.name,`Scheduling restart in ${e}ms (attempt #${t.restartCount+1})`);let n=setTimeout(async()=>{this.patch({restartCount:t.restartCount+1,backoffTime:Math.min(e*2,r)}),await this.spawnAll();},e);this.patch({restartTimer:n});}startProbe(){let t=this.cfg.probe,e=(t.intervalSeconds??10)*1e3,r=t.failureThreshold??3,i=setInterval(async()=>{let a=this.mp();if(a.status!=="running")return;if(await d(t)){a.probeFailures>0&&this.patch({probeFailures:0});return}let m=a.probeFailures+1;this.patch({probeFailures:m}),d$1.warn(this.name,`Liveness probe failed (${m}/${r})`),m>=r&&(d$1.error(this.name,"Liveness probe threshold exceeded \u2013 restarting."),this.patch({probeFailures:0}),await this.restart());},e);this.patch({probeTimer:i});}stopProbe(){let{probeTimer:t}=this.mp();t&&(clearInterval(t),this.patch({probeTimer:null,probeFailures:0}));}watchFiles(){this.stopWatcher();let t=g.dirname(this.cfg.scriptPath);this.watcher=$.watch(t,{ignored:[/node_modules/,/\.pid$/],persistent:true,ignoreInitial:true,awaitWriteFinish:{stabilityThreshold:1500,pollInterval:500}}),this.watcher.on("all",(e,r)=>{(e==="change"||e==="add")&&(d$1.info(this.name,`File ${e}: ${g.basename(r)} \u2013 restarting`),this.restart());}),this.watcher.on("error",e=>d$1.error(this.name,"Watcher error:",e)),this.watcher.on("ready",()=>d$1.info(this.name,`Watching ${t}`));}stopWatcher(){this.watcher&&(this.watcher.close(),this.watcher=null);}initStore(){c.set(this.name,{config:this.cfg,children:[],status:"stopped",startTime:null,restartCount:0,backoffTime:k,restartTimer:null,stabilityTimer:null,probeTimer:null,probeFailures:0,isRestarting:false});}mp(){return c.get(this.name)}patch(t){c.set(this.name,{...this.mp(),...t});}clearTimers(){let{restartTimer:t,stabilityTimer:e}=this.mp();t&&clearTimeout(t),e&&clearTimeout(e),this.patch({restartTimer:null,stabilityTimer:null});}setupLogging(t){let e=this.cfg.logs?.wsUrl,r=null;e&&(r=new w(e),r.on("open",()=>d$1.debug(this.name,"Connected to log collector")),r.on("error",i=>d$1.error(this.name,"Log Collector WS Error",i.message)));let n=i=>{let a=i.toString();this.cfg.devMode&&process.stdout.write(`[${this.name}] ${a}`),r&&r.readyState===w.OPEN&&r.send(JSON.stringify({app:this.name,timestamp:Date.now(),log:a}));};t.stdout?.on("data",n),t.stderr?.on("data",n);}};var T=class{workers=new Map;async start(t){if(this.workers.has(t.name)){d$1.warn("PM",`Worker "${t.name}" already registered \u2013 use restart()`);return}let e=new h(t);this.workers.set(t.name,e),await e.start();}async stop(t){await this.require(t).stop();}async restart(t){await this.require(t).restart();}async delete(t){await this.require(t).stop(),this.workers.delete(t),c.delete(t),d$1.info("PM",`Deleted worker "${t}"`);}async getStats(t){return t?[await this.require(t).getStats()]:await Promise.all([...this.workers.values()].map(r=>r.getStats()))}list(){return [...this.workers.keys()]}async stopAll(){d$1.info("PM","Stopping all workers..."),await Promise.all([...this.workers.values()].map(t=>t.stop())),d$1.info("PM","All workers stopped.");}getWorker(t){let e=this.workers.get(t);return e||null}require(t){let e=this.workers.get(t);if(!e)throw new Error(`Worker "${t}" not found`);return e}};export{c as a,d as b,h as c,T as d};
@@ -1,4 +1,4 @@
1
- 'use strict';var chunkQ6CPX4WT_cjs=require('./chunk-Q6CPX4WT.cjs'),child_process=require('child_process'),p=require('fs'),h=require('net'),y=require('os'),P=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var p__default=/*#__PURE__*/_interopDefault(p);var h__default=/*#__PURE__*/_interopDefault(h);var y__default=/*#__PURE__*/_interopDefault(y);var P__default=/*#__PURE__*/_interopDefault(P);/* ZuzJS Process Manager */
2
- function i(d,n="zuz-pm"){return new Promise((t,r)=>{let e=h__default.default.createConnection(chunkQ6CPX4WT_cjs.d(n)),o="";e.on("connect",()=>{e.write(JSON.stringify(d)+`
1
+ 'use strict';var chunkI6PNOIS2_cjs=require('./chunk-I6PNOIS2.cjs'),child_process=require('child_process'),p=require('fs'),h=require('net'),y=require('os'),P=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var p__default=/*#__PURE__*/_interopDefault(p);var h__default=/*#__PURE__*/_interopDefault(h);var y__default=/*#__PURE__*/_interopDefault(y);var P__default=/*#__PURE__*/_interopDefault(P);/* ZuzJS Process Manager */
2
+ function i(d,n="zuz-pm"){return new Promise((t,r)=>{let e=h__default.default.createConnection(chunkI6PNOIS2_cjs.e(n)),o="";e.on("connect",()=>{e.write(JSON.stringify(d)+`
3
3
  `);}),e.on("data",s=>{o+=s.toString();let m=o.split(`
4
- `);o=m.pop()??"";for(let l of m)if(l.trim())try{let a=JSON.parse(l);e.destroy(),a.ok?t(a.data):r(new Error(a.error));}catch(a){e.destroy(),r(a);}}),e.on("error",s=>r(s)),e.setTimeout(1e4,()=>{e.destroy(),r(new Error("IPC timeout"));});})}var u=class{daemonScript;namespace;constructor(n){this.namespace=n?.namespace??"zuz-pm",this.daemonScript=n?.daemonScript??P__default.default.join(__dirname,"daemon.js");}async isDaemonRunning(){try{return chunkQ6CPX4WT_cjs.c.info("[ZPM]","Daemon is Running :?"),await i({cmd:"ping"},this.namespace),!0}catch{return chunkQ6CPX4WT_cjs.c.info("[ZPM]","Daemon is not running."),false}}async ensureDaemon(){if(await this.isDaemonRunning())return;chunkQ6CPX4WT_cjs.c.info("Starting ZPM daemon...");let t=process.env.NODE_ENV!=="production";child_process.spawn(process.execPath,[this.daemonScript],{detached:true,stdio:t?"inherit":"ignore"}).unref(),await this.waitForDaemon(8e3);}async killDaemon(){let n=P__default.default.join(y__default.default.tmpdir(),"zuz-pm.pid");if(!p__default.default.existsSync(n))throw new Error("Daemon PID file not found \u2013 is the daemon running?");let t=Number(p__default.default.readFileSync(n,"utf8").trim());try{process.kill(t,"SIGTERM"),console.log(`[ZPM] Sent SIGTERM to daemon (PID ${t})`);}catch(r){throw new Error(`Failed to kill daemon: ${r.message}`)}finally{p__default.default.unlinkSync(n);}}async start(n){return i({cmd:"start",name:n.name,config:n},this.namespace)}async stop(n){return i({cmd:"stop",name:n},this.namespace)}async restart(n){return i({cmd:"restart",name:n},this.namespace)}async delete(n){return i({cmd:"delete",name:n},this.namespace)}async stats(n){return i({cmd:"stats",name:n},this.namespace)}async list(){return i({cmd:"list"},this.namespace)}waitForDaemon(n){let t=Date.now(),r=200;return new Promise((e,o)=>{let s=()=>{this.isDaemonRunning().then(m=>{if(m)return e();if(Date.now()-t>n)return o(new Error("Daemon did not start in time"));setTimeout(s,r);});};setTimeout(s,r);})}},C=new u;exports.a=u;exports.b=C;
4
+ `);o=m.pop()??"";for(let l of m)if(l.trim())try{let a=JSON.parse(l);e.destroy(),a.ok?t(a.data):r(new Error(a.error));}catch(a){e.destroy(),r(a);}}),e.on("error",s=>r(s)),e.setTimeout(1e4,()=>{e.destroy(),r(new Error("IPC timeout"));});})}var u=class{daemonScript;namespace;constructor(n){this.namespace=n?.namespace??"zuz-pm",this.daemonScript=n?.daemonScript??P__default.default.join(__dirname,"daemon.js");}async isDaemonRunning(){try{return chunkI6PNOIS2_cjs.d.info("[ZPM]","Daemon is Running :?"),await i({cmd:"ping"},this.namespace),!0}catch{return chunkI6PNOIS2_cjs.d.info("[ZPM]","Daemon is not running."),false}}async ensureDaemon(){if(await this.isDaemonRunning())return;chunkI6PNOIS2_cjs.d.info("Starting ZPM daemon...");let t=process.env.NODE_ENV!=="production";child_process.spawn(process.execPath,[this.daemonScript],{detached:true,stdio:t?"inherit":"ignore"}).unref(),await this.waitForDaemon(8e3);}async killDaemon(){let n=P__default.default.join(y__default.default.tmpdir(),"zuz-pm.pid");if(!p__default.default.existsSync(n))throw new Error("Daemon PID file not found \u2013 is the daemon running?");let t=Number(p__default.default.readFileSync(n,"utf8").trim());try{process.kill(t,"SIGTERM"),console.log(`[ZPM] Sent SIGTERM to daemon (PID ${t})`);}catch(r){throw new Error(`Failed to kill daemon: ${r.message}`)}finally{p__default.default.unlinkSync(n);}}async start(n){return i({cmd:"start",name:n.name,config:n},this.namespace)}async stop(n){return i({cmd:"stop",name:n},this.namespace)}async restart(n){return i({cmd:"restart",name:n},this.namespace)}async delete(n){return i({cmd:"delete",name:n},this.namespace)}async stats(n){return i({cmd:"stats",name:n},this.namespace)}async list(){return i({cmd:"list"},this.namespace)}waitForDaemon(n){let t=Date.now(),r=200;return new Promise((e,o)=>{let s=()=>{this.isDaemonRunning().then(m=>{if(m)return e();if(Date.now()-t>n)return o(new Error("Daemon did not start in time"));setTimeout(s,r);});};setTimeout(s,r);})}},C=new u;exports.a=u;exports.b=C;
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkI6PNOIS2_cjs=require('./chunk-I6PNOIS2.cjs'),T=require('events'),child_process=require('child_process'),S=require('http'),y=require('https'),W=require('net'),M=require('chokidar'),E=require('fs'),R=require('os'),d=require('path'),g=require('ws'),_=require('pidusage');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var T__default=/*#__PURE__*/_interopDefault(T);var S__default=/*#__PURE__*/_interopDefault(S);var y__default=/*#__PURE__*/_interopDefault(y);var W__default=/*#__PURE__*/_interopDefault(W);var M__default=/*#__PURE__*/_interopDefault(M);var E__default=/*#__PURE__*/_interopDefault(E);var R__default=/*#__PURE__*/_interopDefault(R);var d__default=/*#__PURE__*/_interopDefault(d);var g__default=/*#__PURE__*/_interopDefault(g);var ___default=/*#__PURE__*/_interopDefault(_);/* ZuzJS Process Manager */
2
+ var p=class extends T__default.default{map=new Map;set(t,e){this.map.set(t,e),this.emit("change",t,e);}get(t){return this.map.get(t)}has(t){return this.map.has(t)}delete(t){this.map.delete(t),this.emit("delete",t);}all(){return new Map(this.map)}onchange(t){return this.on("change",t)}offchange(t){return this.off("change",t)}},c=new p;function C(s,t){return new Promise(e=>{let n=(s.startsWith("https")?y__default.default:S__default.default).get(s,{timeout:t},i=>{e((i.statusCode??500)<500);});n.on("error",()=>e(false)),n.on("timeout",()=>{n.destroy(),e(false);});})}function F(s,t){let[e,r]=s.split(":"),n=Number(r);return new Promise(i=>{let a=W__default.default.createConnection({host:e,port:n},()=>{a.destroy(),i(true);});a.setTimeout(t),a.on("timeout",()=>{a.destroy(),i(false);}),a.on("error",()=>i(false));})}function x(s,t){return new Promise(e=>{let r=setTimeout(()=>e(false),t);child_process.exec(s,n=>{clearTimeout(r),e(!n);});})}async function f(s){let t=(s.timeoutSeconds??5)*1e3;switch(s.type){case "http":return C(s.target,t);case "tcp":return F(s.target,t);case "exec":return x(s.target,t);default:return false}}var w=5e3,A=16e3,b=1e3,D=5e3;async function N(s){return new Promise(t=>{W__default.default.createServer().once("error",()=>t(false)).once("listening",function(){this.close(()=>t(true));}).listen(s);})}async function O(s){await N(s)||(chunkI6PNOIS2_cjs.d.warn("port",`Port ${s} busy \u2013 attempting fuser kill`),await new Promise(t=>child_process.exec(`fuser -k -9 ${s}/tcp 2>/dev/null; true`,()=>t())),await new Promise(t=>setTimeout(t,500)));}function k(s,t){let e=s.process?.pid??s.pid;if(!e)return;try{process.kill(e,"SIGTERM");}catch{return}let r=setTimeout(()=>{try{process.kill(e,"SIGKILL");}catch{}},t);s.once?.("exit",()=>clearTimeout(r)),s.once?.("exit",()=>clearTimeout(r));}var h=class{cfg;name;watcher=null;constructor(t){this.cfg={mode:"fork",instances:1,...t},this.name=t.name,this.initStore();}async start(){let t=this.mp();if(t.status==="running"||t.status==="starting"){chunkI6PNOIS2_cjs.d.warn(this.name,"Already running \u2013 ignoring start()");return}this.patch({status:"starting"}),await this.spawnAll(),this.cfg.devMode&&this.watchFiles();}async stop(){let t=this.mp();this.patch({status:"stopping",isRestarting:false}),this.clearTimers(),this.stopProbe();for(let e of t.children)k(e,this.cfg.killTimeout??w);this.stopWatcher(),this.patch({children:[],status:"stopped",startTime:null}),chunkI6PNOIS2_cjs.d.info(this.name,"Stopped.");}async restart(){chunkI6PNOIS2_cjs.d.info(this.name,"Restarting...");let t=this.mp();this.patch({isRestarting:true}),this.clearTimers(),this.stopProbe();for(let e of t.children)k(e,this.cfg.killTimeout??w);}async getStats(){let t=this.mp(),e=t.children[0]?.pid??null,r=null,n=null,i=null;if(e&&t.status==="running")try{let a=await ___default.default(e);r=a.cpu,n=a.memory;}catch{}return {name:this.name,status:t.status,pid:e,uptime:t.startTime?Date.now()-t.startTime:null,restartCount:t.restartCount,cpu:r,memoryRss:n,memoryHeap:i,mode:this.cfg.mode??"fork",instances:t.children.length}}async spawnAll(){if(!E__default.default.existsSync(this.cfg.scriptPath)){chunkI6PNOIS2_cjs.d.error(this.name,`Script not found: ${this.cfg.scriptPath}. Waiting for build...`),this.patch({status:"errored"});return}this.cfg.port&&await O(this.cfg.port);let t=this.cfg.mode??"fork",e=t==="cluster"?this.cfg.instances??R__default.default.cpus().length:1,r=[];for(let i=0;i<e;i++){let a=this.forkChild();a&&r.push(a);}this.patch({children:r,startTime:Date.now(),status:"running"}),chunkI6PNOIS2_cjs.d.success(this.name,`Started ${r.length} instance(s) [${t}]`);let n=setTimeout(()=>{this.mp().status==="running"&&(this.patch({backoffTime:b,restartCount:0}),chunkI6PNOIS2_cjs.d.success(this.name,"Process is stable."));},D);this.patch({stabilityTimer:n}),this.cfg.probe&&this.startProbe();}forkChild(){try{let t=this.cfg.scriptPath.endsWith(".js")?"node":this.cfg.scriptPath,e=this.cfg.scriptPath.endsWith(".js")?[this.cfg.scriptPath,...this.cfg.args??[]]:[...this.cfg.args??[]],r=child_process.spawn(t,e,{stdio:["ignore","pipe","pipe"],env:{...process.env,...this.cfg.env??{},NODE_ENV:this.cfg.devMode?"development":"production"},detached:!1,shell:!1});this.setupLogging(r);let n=Date.now();return r.on("error",i=>{chunkI6PNOIS2_cjs.d.error(this.name,"Spawn error:",i);}),r.on("exit",(i,a)=>{let l=Date.now()-n;this.onChildExit(r,i,a,l);}),r}catch(t){return chunkI6PNOIS2_cjs.d.error(this.name,"Failed to fork child:",t),null}}onChildExit(t,e,r,n){let i=this.mp(),a=i.children.filter(l=>l!==t);if(this.patch({children:a}),i.status!=="stopping"){if(chunkI6PNOIS2_cjs.d.warn(this.name,`Process exited (code=${e}, signal=${r}, uptime=${n}ms)`),i.isRestarting){a.length===0&&(this.patch({isRestarting:false}),this.spawnAll());return}if(e!==0&&e!==null){if(this.patch({status:"crashed"}),n<1500){chunkI6PNOIS2_cjs.d.error(this.name,`Immediate crash (${n}ms) \u2013 likely a syntax/build error. Waiting for next file change.`);return}this.scheduleRestart();}}}scheduleRestart(){let t=this.mp(),e=t.backoffTime,r=this.cfg.maxBackoff??A;chunkI6PNOIS2_cjs.d.warn(this.name,`Scheduling restart in ${e}ms (attempt #${t.restartCount+1})`);let n=setTimeout(async()=>{this.patch({restartCount:t.restartCount+1,backoffTime:Math.min(e*2,r)}),await this.spawnAll();},e);this.patch({restartTimer:n});}startProbe(){let t=this.cfg.probe,e=(t.intervalSeconds??10)*1e3,r=t.failureThreshold??3,i=setInterval(async()=>{let a=this.mp();if(a.status!=="running")return;if(await f(t)){a.probeFailures>0&&this.patch({probeFailures:0});return}let m=a.probeFailures+1;this.patch({probeFailures:m}),chunkI6PNOIS2_cjs.d.warn(this.name,`Liveness probe failed (${m}/${r})`),m>=r&&(chunkI6PNOIS2_cjs.d.error(this.name,"Liveness probe threshold exceeded \u2013 restarting."),this.patch({probeFailures:0}),await this.restart());},e);this.patch({probeTimer:i});}stopProbe(){let{probeTimer:t}=this.mp();t&&(clearInterval(t),this.patch({probeTimer:null,probeFailures:0}));}watchFiles(){this.stopWatcher();let t=d__default.default.dirname(this.cfg.scriptPath);this.watcher=M__default.default.watch(t,{ignored:[/node_modules/,/\.pid$/],persistent:true,ignoreInitial:true,awaitWriteFinish:{stabilityThreshold:1500,pollInterval:500}}),this.watcher.on("all",(e,r)=>{(e==="change"||e==="add")&&(chunkI6PNOIS2_cjs.d.info(this.name,`File ${e}: ${d__default.default.basename(r)} \u2013 restarting`),this.restart());}),this.watcher.on("error",e=>chunkI6PNOIS2_cjs.d.error(this.name,"Watcher error:",e)),this.watcher.on("ready",()=>chunkI6PNOIS2_cjs.d.info(this.name,`Watching ${t}`));}stopWatcher(){this.watcher&&(this.watcher.close(),this.watcher=null);}initStore(){c.set(this.name,{config:this.cfg,children:[],status:"stopped",startTime:null,restartCount:0,backoffTime:b,restartTimer:null,stabilityTimer:null,probeTimer:null,probeFailures:0,isRestarting:false});}mp(){return c.get(this.name)}patch(t){c.set(this.name,{...this.mp(),...t});}clearTimers(){let{restartTimer:t,stabilityTimer:e}=this.mp();t&&clearTimeout(t),e&&clearTimeout(e),this.patch({restartTimer:null,stabilityTimer:null});}setupLogging(t){let e=this.cfg.logs?.wsUrl,r=null;e&&(r=new g__default.default(e),r.on("open",()=>chunkI6PNOIS2_cjs.d.debug(this.name,"Connected to log collector")),r.on("error",i=>chunkI6PNOIS2_cjs.d.error(this.name,"Log Collector WS Error",i.message)));let n=i=>{let a=i.toString();this.cfg.devMode&&process.stdout.write(`[${this.name}] ${a}`),r&&r.readyState===g__default.default.OPEN&&r.send(JSON.stringify({app:this.name,timestamp:Date.now(),log:a}));};t.stdout?.on("data",n),t.stderr?.on("data",n);}};var P=class{workers=new Map;async start(t){if(this.workers.has(t.name)){chunkI6PNOIS2_cjs.d.warn("PM",`Worker "${t.name}" already registered \u2013 use restart()`);return}let e=new h(t);this.workers.set(t.name,e),await e.start();}async stop(t){await this.require(t).stop();}async restart(t){await this.require(t).restart();}async delete(t){await this.require(t).stop(),this.workers.delete(t),c.delete(t),chunkI6PNOIS2_cjs.d.info("PM",`Deleted worker "${t}"`);}async getStats(t){return t?[await this.require(t).getStats()]:await Promise.all([...this.workers.values()].map(r=>r.getStats()))}list(){return [...this.workers.keys()]}async stopAll(){chunkI6PNOIS2_cjs.d.info("PM","Stopping all workers..."),await Promise.all([...this.workers.values()].map(t=>t.stop())),chunkI6PNOIS2_cjs.d.info("PM","All workers stopped.");}getWorker(t){let e=this.workers.get(t);return e||null}require(t){let e=this.workers.get(t);if(!e)throw new Error(`Worker "${t}" not found`);return e}};exports.a=c;exports.b=f;exports.c=h;exports.d=P;
package/dist/cli.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- 'use strict';var chunkVDYHM6XJ_cjs=require('./chunk-VDYHM6XJ.cjs'),chunkQ6CPX4WT_cjs=require('./chunk-Q6CPX4WT.cjs'),commander=require('commander'),y=require('net'),u=require('path'),i=require('picocolors');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var y__default=/*#__PURE__*/_interopDefault(y);var u__default=/*#__PURE__*/_interopDefault(u);var i__default=/*#__PURE__*/_interopDefault(i);/* ZuzJS Process Manager */
3
- var d={version:"0.0.4"};var t=new commander.Command;t.option("-s, --namespace <name>","Internal daemon namespace","zuz-pm");t.parseOptions(process.argv);var x=t.opts(),g=x.namespace,r=new chunkVDYHM6XJ_cjs.a(g);t.name("zpm").description("Production grade process manager for the @zuzjs ecosystem").version(d.version,"-v, --version","output the current version");t.command("start <script>").description("Start a new process").option("-n, --name <name>","Unique name for the process").option("-p, --port <port>","Port the app listens on",parseInt).option("-i, --instances <number>","Number of instances (cluster mode)",parseInt,1).option("-d, --dev","Enable development mode (auto-restart)",false).option("-c, --cluster","Use cluster mode instead of fork",false).option("--ws <url>","WebSocket URL to stream logs (e.g. for ZPanel)","http://127.0.0.1:2082/_/wss/zpm").option("--save-logs","Save logs to a local file",false).action(async(o,s)=>{try{await r.ensureDaemon();let e=u__default.default.resolve(process.cwd(),o),n=await r.start({name:s.name??u__default.default.basename(o),scriptPath:e,port:s.port,instances:s.instances,devMode:s.dev,mode:s.cluster?"cluster":"fork",logs:{wsUrl:s.ws,saveToFile:s.saveLogs}});console.log(i__default.default.cyan("[ZPM]"),n);}catch(e){console.log(i__default.default.cyan("[ZPM]"),i__default.default.red("[ERROR]"),e.message);}});t.command("logs [name]").description("Stream real-time logs (omit name for all logs)").action(async o=>{try{if(!await r.isDaemonRunning())throw new Error("Daemon is not running.");let e=o?`"${o}"`:"all workers";console.log(i__default.default.cyan("[ZPM]"),`Streaming logs for "${i__default.default.green(e)}" (Ctrl+C to stop)`);let n=y__default.default.createConnection(chunkQ6CPX4WT_cjs.d(g));n.write(JSON.stringify({cmd:"logs",name:o})+`
4
- `),n.on("data",a=>{let f=a.toString().split(`
5
- `);for(let m of f)if(m.trim())try{let c=JSON.parse(m);c.ok?process.stdout.write(c.data):(console.error(`\x1B[31m${c.error}\x1B[0m`),process.exit(1));}catch{}}),n.on("error",a=>{console.error(`\x1B[31m[IPC Error]\x1B[0m ${a.message}`),process.exit(1);}),process.on("SIGINT",()=>{n.destroy(),console.log(`
6
- \x1B[90mDisconnected from logs.\x1B[0m`),process.exit();});}catch(s){console.error(`\x1B[31m[Error]\x1B[0m ${s.message}`);}});t.command("list").description("List all managed processes").action(async()=>{let o=await r.list();if(o.length===0){console.log("No workers registered.");return}console.log("\x1B[1mManaged Processes:\x1B[0m"),o.forEach(s=>console.log(` \u2022 ${s}`));});t.command("stats [name]").description("Show telemetry for processes").action(async o=>{let s=await r.stats(o);if(s.length===0){console.log("No stats available.");return}s.forEach(e=>{let n=e.uptime?`${Math.round(e.uptime/1e3)}s`:"0s",a=e.status==="running"?"\x1B[32m":"\x1B[31m";console.log(`${a}[${e.status.toUpperCase()}]\x1B[0m \x1B[1m${e.name.padEnd(15)}\x1B[0m PID: ${String(e.pid??"N/A").padEnd(6)} CPU: ${String(e.cpu??0).padStart(3)}% MEM: ${Math.round((e.memoryRss??0)/1024/1024)}MB Uptime: ${n}`);});});["stop","restart","delete"].forEach(o=>{t.command(`${o} <name>`).description(`${o.charAt(0).toUpperCase()+o.slice(1)} a process`).action(async s=>{try{let e=await r[o](s);console.log(`\x1B[32m[ZPM]\x1B[0m ${e}`);}catch(e){console.error(`\x1B[31m[Error]\x1B[0m ${e.message}`);}});});t.command("kill-daemon").description("Stop the background ZPM daemon").action(async()=>{await r.killDaemon(),console.log("\x1B[33mDaemon killed.\x1B[0m");});t.parse(process.argv);
2
+ 'use strict';var chunkUVQRIGIE_cjs=require('./chunk-UVQRIGIE.cjs'),chunkI6PNOIS2_cjs=require('./chunk-I6PNOIS2.cjs'),commander=require('commander'),h=require('fs'),y=require('net'),i=require('path'),url=require('url'),c=require('picocolors');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var h__default=/*#__PURE__*/_interopDefault(h);var y__default=/*#__PURE__*/_interopDefault(y);var i__default=/*#__PURE__*/_interopDefault(i);var c__default=/*#__PURE__*/_interopDefault(c);/* ZuzJS Process Manager */
3
+ var t=new commander.Command;t.option("-s, --namespace <name>","Internal daemon namespace","zuz-pm");t.parseOptions(process.argv);var v=t.opts(),b=v.namespace,n=new chunkUVQRIGIE_cjs.a(b),w=i__default.default.dirname(url.fileURLToPath(chunkI6PNOIS2_cjs.a)),S=i__default.default.resolve(w,"../package.json"),$=JSON.parse(h__default.default.readFileSync(S,"utf8"));t.name("zpm").description("Production grade process manager for the @zuzjs ecosystem").version($.version,"-v, --version","output the current version");t.command("start <script>").description("Start a new process").option("-n, --name <name>","Unique name for the process").option("-p, --port <port>","Port the app listens on",parseInt).option("-i, --instances <number>","Number of instances (cluster mode)",parseInt,1).option("-d, --dev","Enable development mode (auto-restart)",false).option("-c, --cluster","Use cluster mode instead of fork",false).option("--ws <url>","WebSocket URL to stream logs (e.g. for ZPanel)","http://127.0.0.1:2082/_/wss/zpm").option("--save-logs","Save logs to a local file",false).option("--args <string>",'Arguments to pass to the script (e.g. "dev -p 3000")').option("--probe-type <type>","Type of probe: http, tcp, or exec").option("--probe-target <target>","URL, host:port, or command").option("--probe-interval <sec>","Seconds between probes",parseInt,30).option("--probe-threshold <count>","Failures before restart",parseInt,3).action(async(r,e)=>{try{await n.ensureDaemon();let o=i__default.default.resolve(process.cwd(),r),s=await n.start({name:e.name??i__default.default.basename(r),scriptPath:o,port:e.port,instances:e.instances,devMode:e.dev,mode:e.cluster?"cluster":"fork",args:e.args?e.args.split(" "):[],probe:e.probeTarget?{type:e.probeType,target:e.probeTarget||(e.probeType==="http"?"http://localhost:3000":"localhost:3000"),intervalSeconds:e.probeInterval,failureThreshold:e.probeThreshold,timeoutSeconds:5}:void 0,logs:{wsUrl:e.ws,saveToFile:e.saveLogs}});console.log(c__default.default.cyan("[ZPM]"),s);}catch(o){console.log(c__default.default.cyan("[ZPM]"),c__default.default.red("[ERROR]"),o.message);}});t.command("logs [name]").description("Stream real-time logs (omit name for all logs)").action(async r=>{try{if(!await n.isDaemonRunning())throw new Error("Daemon is not running.");let o=r?`"${r}"`:"all workers";console.log(c__default.default.cyan("[ZPM]"),`Streaming logs for "${c__default.default.green(o)}" (Ctrl+C to stop)`);let s=y__default.default.createConnection(chunkI6PNOIS2_cjs.e(b));s.write(JSON.stringify({cmd:"logs",name:r})+`
4
+ `),s.on("data",a=>{let u=a.toString().split(`
5
+ `);for(let p of u)if(p.trim())try{let m=JSON.parse(p);m.ok?process.stdout.write(m.data):(console.error(`\x1B[31m${m.error}\x1B[0m`),process.exit(1));}catch{}}),s.on("error",a=>{console.error(`\x1B[31m[IPC Error]\x1B[0m ${a.message}`),process.exit(1);}),process.on("SIGINT",()=>{s.destroy(),console.log(`
6
+ \x1B[90mDisconnected from logs.\x1B[0m`),process.exit();});}catch(e){console.error(`\x1B[31m[Error]\x1B[0m ${e.message}`);}});t.command("list").description("List all managed processes").action(async()=>{let r=await n.list();if(r.length===0){console.log("No workers registered.");return}console.log("\x1B[1mManaged Processes:\x1B[0m"),r.forEach(e=>console.log(` \u2022 ${e}`));});t.command("stats [name]").description("Show telemetry for processes").action(async r=>{let e=await n.stats(r);if(e.length===0){console.log("No stats available.");return}e.forEach(o=>{let s=o.uptime?`${Math.round(o.uptime/1e3)}s`:"0s",a=o.status==="running"?"\x1B[32m":"\x1B[31m";console.log(`${a}[${o.status.toUpperCase()}]\x1B[0m \x1B[1m${o.name.padEnd(15)}\x1B[0m PID: ${String(o.pid??"N/A").padEnd(6)} CPU: ${String(o.cpu??0).padStart(3)}% MEM: ${Math.round((o.memoryRss??0)/1024/1024)}MB Uptime: ${s}`);});});["stop","restart","delete"].forEach(r=>{t.command(`${r} <name>`).description(`${r.charAt(0).toUpperCase()+r.slice(1)} a process`).action(async e=>{try{let o=await n[r](e);console.log(`\x1B[32m[ZPM]\x1B[0m ${o}`);}catch(o){console.error(`\x1B[31m[Error]\x1B[0m ${o.message}`);}});});t.command("kill-daemon").description("Stop the background ZPM daemon").action(async()=>{await n.killDaemon(),console.log("\x1B[33mDaemon killed.\x1B[0m");});t.parse(process.argv);
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import {a}from'./chunk-3VIK6Q3M.js';import {e}from'./chunk-2PXF47OQ.js';import {Command}from'commander';import y from'net';import u from'path';import i from'picocolors';var d={version:"0.0.4"};var t=new Command;t.option("-s, --namespace <name>","Internal daemon namespace","zuz-pm");t.parseOptions(process.argv);var x=t.opts(),g=x.namespace,r=new a(g);t.name("zpm").description("Production grade process manager for the @zuzjs ecosystem").version(d.version,"-v, --version","output the current version");t.command("start <script>").description("Start a new process").option("-n, --name <name>","Unique name for the process").option("-p, --port <port>","Port the app listens on",parseInt).option("-i, --instances <number>","Number of instances (cluster mode)",parseInt,1).option("-d, --dev","Enable development mode (auto-restart)",false).option("-c, --cluster","Use cluster mode instead of fork",false).option("--ws <url>","WebSocket URL to stream logs (e.g. for ZPanel)","http://127.0.0.1:2082/_/wss/zpm").option("--save-logs","Save logs to a local file",false).action(async(o,s)=>{try{await r.ensureDaemon();let e=u.resolve(process.cwd(),o),n=await r.start({name:s.name??u.basename(o),scriptPath:e,port:s.port,instances:s.instances,devMode:s.dev,mode:s.cluster?"cluster":"fork",logs:{wsUrl:s.ws,saveToFile:s.saveLogs}});console.log(i.cyan("[ZPM]"),n);}catch(e){console.log(i.cyan("[ZPM]"),i.red("[ERROR]"),e.message);}});t.command("logs [name]").description("Stream real-time logs (omit name for all logs)").action(async o=>{try{if(!await r.isDaemonRunning())throw new Error("Daemon is not running.");let e$1=o?`"${o}"`:"all workers";console.log(i.cyan("[ZPM]"),`Streaming logs for "${i.green(e$1)}" (Ctrl+C to stop)`);let n=y.createConnection(e(g));n.write(JSON.stringify({cmd:"logs",name:o})+`
3
- `),n.on("data",a=>{let f=a.toString().split(`
4
- `);for(let m of f)if(m.trim())try{let c=JSON.parse(m);c.ok?process.stdout.write(c.data):(console.error(`\x1B[31m${c.error}\x1B[0m`),process.exit(1));}catch{}}),n.on("error",a=>{console.error(`\x1B[31m[IPC Error]\x1B[0m ${a.message}`),process.exit(1);}),process.on("SIGINT",()=>{n.destroy(),console.log(`
5
- \x1B[90mDisconnected from logs.\x1B[0m`),process.exit();});}catch(s){console.error(`\x1B[31m[Error]\x1B[0m ${s.message}`);}});t.command("list").description("List all managed processes").action(async()=>{let o=await r.list();if(o.length===0){console.log("No workers registered.");return}console.log("\x1B[1mManaged Processes:\x1B[0m"),o.forEach(s=>console.log(` \u2022 ${s}`));});t.command("stats [name]").description("Show telemetry for processes").action(async o=>{let s=await r.stats(o);if(s.length===0){console.log("No stats available.");return}s.forEach(e=>{let n=e.uptime?`${Math.round(e.uptime/1e3)}s`:"0s",a=e.status==="running"?"\x1B[32m":"\x1B[31m";console.log(`${a}[${e.status.toUpperCase()}]\x1B[0m \x1B[1m${e.name.padEnd(15)}\x1B[0m PID: ${String(e.pid??"N/A").padEnd(6)} CPU: ${String(e.cpu??0).padStart(3)}% MEM: ${Math.round((e.memoryRss??0)/1024/1024)}MB Uptime: ${n}`);});});["stop","restart","delete"].forEach(o=>{t.command(`${o} <name>`).description(`${o.charAt(0).toUpperCase()+o.slice(1)} a process`).action(async s=>{try{let e=await r[o](s);console.log(`\x1B[32m[ZPM]\x1B[0m ${e}`);}catch(e){console.error(`\x1B[31m[Error]\x1B[0m ${e.message}`);}});});t.command("kill-daemon").description("Stop the background ZPM daemon").action(async()=>{await r.killDaemon(),console.log("\x1B[33mDaemon killed.\x1B[0m");});t.parse(process.argv);
2
+ import {a}from'./chunk-3VIK6Q3M.js';import {e}from'./chunk-2PXF47OQ.js';import {Command}from'commander';import f from'fs';import h from'net';import i from'path';import {fileURLToPath}from'url';import c from'picocolors';var t=new Command;t.option("-s, --namespace <name>","Internal daemon namespace","zuz-pm");t.parseOptions(process.argv);var x=t.opts(),g=x.namespace,n=new a(g),v=i.dirname(fileURLToPath(import.meta.url)),w=i.resolve(v,"../package.json"),S=JSON.parse(f.readFileSync(w,"utf8"));t.name("zpm").description("Production grade process manager for the @zuzjs ecosystem").version(S.version,"-v, --version","output the current version");t.command("start <script>").description("Start a new process").option("-n, --name <name>","Unique name for the process").option("-p, --port <port>","Port the app listens on",parseInt).option("-i, --instances <number>","Number of instances (cluster mode)",parseInt,1).option("-d, --dev","Enable development mode (auto-restart)",false).option("-c, --cluster","Use cluster mode instead of fork",false).option("--ws <url>","WebSocket URL to stream logs (e.g. for ZPanel)","http://127.0.0.1:2082/_/wss/zpm").option("--save-logs","Save logs to a local file",false).option("--args <string>",'Arguments to pass to the script (e.g. "dev -p 3000")').option("--probe-type <type>","Type of probe: http, tcp, or exec").option("--probe-target <target>","URL, host:port, or command").option("--probe-interval <sec>","Seconds between probes",parseInt,30).option("--probe-threshold <count>","Failures before restart",parseInt,3).action(async(r,e)=>{try{await n.ensureDaemon();let o=i.resolve(process.cwd(),r),s=await n.start({name:e.name??i.basename(r),scriptPath:o,port:e.port,instances:e.instances,devMode:e.dev,mode:e.cluster?"cluster":"fork",args:e.args?e.args.split(" "):[],probe:e.probeTarget?{type:e.probeType,target:e.probeTarget||(e.probeType==="http"?"http://localhost:3000":"localhost:3000"),intervalSeconds:e.probeInterval,failureThreshold:e.probeThreshold,timeoutSeconds:5}:void 0,logs:{wsUrl:e.ws,saveToFile:e.saveLogs}});console.log(c.cyan("[ZPM]"),s);}catch(o){console.log(c.cyan("[ZPM]"),c.red("[ERROR]"),o.message);}});t.command("logs [name]").description("Stream real-time logs (omit name for all logs)").action(async r=>{try{if(!await n.isDaemonRunning())throw new Error("Daemon is not running.");let o=r?`"${r}"`:"all workers";console.log(c.cyan("[ZPM]"),`Streaming logs for "${c.green(o)}" (Ctrl+C to stop)`);let s=h.createConnection(e(g));s.write(JSON.stringify({cmd:"logs",name:r})+`
3
+ `),s.on("data",a=>{let b=a.toString().split(`
4
+ `);for(let p of b)if(p.trim())try{let m=JSON.parse(p);m.ok?process.stdout.write(m.data):(console.error(`\x1B[31m${m.error}\x1B[0m`),process.exit(1));}catch{}}),s.on("error",a=>{console.error(`\x1B[31m[IPC Error]\x1B[0m ${a.message}`),process.exit(1);}),process.on("SIGINT",()=>{s.destroy(),console.log(`
5
+ \x1B[90mDisconnected from logs.\x1B[0m`),process.exit();});}catch(e){console.error(`\x1B[31m[Error]\x1B[0m ${e.message}`);}});t.command("list").description("List all managed processes").action(async()=>{let r=await n.list();if(r.length===0){console.log("No workers registered.");return}console.log("\x1B[1mManaged Processes:\x1B[0m"),r.forEach(e=>console.log(` \u2022 ${e}`));});t.command("stats [name]").description("Show telemetry for processes").action(async r=>{let e=await n.stats(r);if(e.length===0){console.log("No stats available.");return}e.forEach(o=>{let s=o.uptime?`${Math.round(o.uptime/1e3)}s`:"0s",a=o.status==="running"?"\x1B[32m":"\x1B[31m";console.log(`${a}[${o.status.toUpperCase()}]\x1B[0m \x1B[1m${o.name.padEnd(15)}\x1B[0m PID: ${String(o.pid??"N/A").padEnd(6)} CPU: ${String(o.cpu??0).padStart(3)}% MEM: ${Math.round((o.memoryRss??0)/1024/1024)}MB Uptime: ${s}`);});});["stop","restart","delete"].forEach(r=>{t.command(`${r} <name>`).description(`${r.charAt(0).toUpperCase()+r.slice(1)} a process`).action(async e=>{try{let o=await n[r](e);console.log(`\x1B[32m[ZPM]\x1B[0m ${o}`);}catch(o){console.error(`\x1B[31m[Error]\x1B[0m ${o.message}`);}});});t.command("kill-daemon").description("Stop the background ZPM daemon").action(async()=>{await n.killDaemon(),console.log("\x1B[33mDaemon killed.\x1B[0m");});t.parse(process.argv);
package/dist/daemon.cjs CHANGED
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkP7YR7QX3_cjs=require('./chunk-P7YR7QX3.cjs'),chunkQ6CPX4WT_cjs=require('./chunk-Q6CPX4WT.cjs'),r=require('fs'),m=require('os'),p=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var r__default=/*#__PURE__*/_interopDefault(r);var m__default=/*#__PURE__*/_interopDefault(m);var p__default=/*#__PURE__*/_interopDefault(p);/* ZuzJS Process Manager */
2
- var i=p__default.default.join(m__default.default.tmpdir(),"zuz-pm.pid");function d(){r__default.default.writeFileSync(i,String(process.pid));}function u(){r__default.default.existsSync(i)&&r__default.default.unlinkSync(i);}var f=p__default.default.join(m__default.default.tmpdir(),"zuz-pm.snapshot.json");function l(o){try{let s=o.list();r__default.default.writeFileSync(f,JSON.stringify(s,null,2));}catch{}}async function S(){chunkQ6CPX4WT_cjs.c.success("daemon",`Booting ZPM daemon (PID ${process.pid})`),d();let o=new chunkP7YR7QX3_cjs.d,s=chunkQ6CPX4WT_cjs.e(o);async function t(e){chunkQ6CPX4WT_cjs.c.info("daemon",`Received ${e} \u2013 shutting down\u2026`),l(o),s.close(),await o.stopAll(),u(),process.exit(0);}process.on("SIGINT",()=>t("SIGINT")),process.on("SIGTERM",()=>t("SIGTERM")),process.on("uncaughtException",e=>chunkQ6CPX4WT_cjs.c.error("daemon","Uncaught exception:",e)),process.on("unhandledRejection",e=>chunkQ6CPX4WT_cjs.c.error("daemon","Unhandled rejection:",e)),chunkQ6CPX4WT_cjs.c.success("daemon","Ready \u2013 waiting for IPC commands.");}S().catch(o=>{chunkQ6CPX4WT_cjs.c.error("daemon","Fatal startup error:",o),process.exit(1);});
1
+ 'use strict';var chunkZC56ZMKZ_cjs=require('./chunk-ZC56ZMKZ.cjs'),chunkI6PNOIS2_cjs=require('./chunk-I6PNOIS2.cjs'),r=require('fs'),m=require('os'),p=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var r__default=/*#__PURE__*/_interopDefault(r);var m__default=/*#__PURE__*/_interopDefault(m);var p__default=/*#__PURE__*/_interopDefault(p);/* ZuzJS Process Manager */
2
+ var i=p__default.default.join(m__default.default.tmpdir(),"zuz-pm.pid");function d(){r__default.default.writeFileSync(i,String(process.pid));}function u(){r__default.default.existsSync(i)&&r__default.default.unlinkSync(i);}var f=p__default.default.join(m__default.default.tmpdir(),"zuz-pm.snapshot.json");function l(o){try{let s=o.list();r__default.default.writeFileSync(f,JSON.stringify(s,null,2));}catch{}}async function S(){chunkI6PNOIS2_cjs.d.success("daemon",`Booting ZPM daemon (PID ${process.pid})`),d();let o=new chunkZC56ZMKZ_cjs.d,s=chunkI6PNOIS2_cjs.f(o);async function t(e){chunkI6PNOIS2_cjs.d.info("daemon",`Received ${e} \u2013 shutting down\u2026`),l(o),s.close(),await o.stopAll(),u(),process.exit(0);}process.on("SIGINT",()=>t("SIGINT")),process.on("SIGTERM",()=>t("SIGTERM")),process.on("uncaughtException",e=>chunkI6PNOIS2_cjs.d.error("daemon","Uncaught exception:",e)),process.on("unhandledRejection",e=>chunkI6PNOIS2_cjs.d.error("daemon","Unhandled rejection:",e)),chunkI6PNOIS2_cjs.d.success("daemon","Ready \u2013 waiting for IPC commands.");}S().catch(o=>{chunkI6PNOIS2_cjs.d.error("daemon","Fatal startup error:",o),process.exit(1);});
package/dist/daemon.js CHANGED
@@ -1 +1 @@
1
- import {d as d$2}from'./chunk-WNF7UADB.js';import {d as d$1,f as f$1}from'./chunk-2PXF47OQ.js';import r from'fs';import m from'os';import p from'path';var i=p.join(m.tmpdir(),"zuz-pm.pid");function d(){r.writeFileSync(i,String(process.pid));}function u(){r.existsSync(i)&&r.unlinkSync(i);}var f=p.join(m.tmpdir(),"zuz-pm.snapshot.json");function l(o){try{let s=o.list();r.writeFileSync(f,JSON.stringify(s,null,2));}catch{}}async function S(){d$1.success("daemon",`Booting ZPM daemon (PID ${process.pid})`),d();let o=new d$2,s=f$1(o);async function t(e){d$1.info("daemon",`Received ${e} \u2013 shutting down\u2026`),l(o),s.close(),await o.stopAll(),u(),process.exit(0);}process.on("SIGINT",()=>t("SIGINT")),process.on("SIGTERM",()=>t("SIGTERM")),process.on("uncaughtException",e=>d$1.error("daemon","Uncaught exception:",e)),process.on("unhandledRejection",e=>d$1.error("daemon","Unhandled rejection:",e)),d$1.success("daemon","Ready \u2013 waiting for IPC commands.");}S().catch(o=>{d$1.error("daemon","Fatal startup error:",o),process.exit(1);});
1
+ import {d as d$2}from'./chunk-PZ4XUM44.js';import {d as d$1,f as f$1}from'./chunk-2PXF47OQ.js';import r from'fs';import m from'os';import p from'path';var i=p.join(m.tmpdir(),"zuz-pm.pid");function d(){r.writeFileSync(i,String(process.pid));}function u(){r.existsSync(i)&&r.unlinkSync(i);}var f=p.join(m.tmpdir(),"zuz-pm.snapshot.json");function l(o){try{let s=o.list();r.writeFileSync(f,JSON.stringify(s,null,2));}catch{}}async function S(){d$1.success("daemon",`Booting ZPM daemon (PID ${process.pid})`),d();let o=new d$2,s=f$1(o);async function t(e){d$1.info("daemon",`Received ${e} \u2013 shutting down\u2026`),l(o),s.close(),await o.stopAll(),u(),process.exit(0);}process.on("SIGINT",()=>t("SIGINT")),process.on("SIGTERM",()=>t("SIGTERM")),process.on("uncaughtException",e=>d$1.error("daemon","Uncaught exception:",e)),process.on("unhandledRejection",e=>d$1.error("daemon","Unhandled rejection:",e)),d$1.success("daemon","Ready \u2013 waiting for IPC commands.");}S().catch(o=>{d$1.error("daemon","Fatal startup error:",o),process.exit(1);});
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- 'use strict';var chunkVDYHM6XJ_cjs=require('./chunk-VDYHM6XJ.cjs'),chunkP7YR7QX3_cjs=require('./chunk-P7YR7QX3.cjs'),chunkQ6CPX4WT_cjs=require('./chunk-Q6CPX4WT.cjs');Object.defineProperty(exports,"ZPMClient",{enumerable:true,get:function(){return chunkVDYHM6XJ_cjs.a}});Object.defineProperty(exports,"zpm",{enumerable:true,get:function(){return chunkVDYHM6XJ_cjs.b}});Object.defineProperty(exports,"ProcessManager",{enumerable:true,get:function(){return chunkP7YR7QX3_cjs.d}});Object.defineProperty(exports,"Worker",{enumerable:true,get:function(){return chunkP7YR7QX3_cjs.c}});Object.defineProperty(exports,"processStore",{enumerable:true,get:function(){return chunkP7YR7QX3_cjs.a}});Object.defineProperty(exports,"runProbe",{enumerable:true,get:function(){return chunkP7YR7QX3_cjs.b}});Object.defineProperty(exports,"WorkerMode",{enumerable:true,get:function(){return chunkQ6CPX4WT_cjs.a}});Object.defineProperty(exports,"WorkerStatus",{enumerable:true,get:function(){return chunkQ6CPX4WT_cjs.b}});Object.defineProperty(exports,"getSocketPath",{enumerable:true,get:function(){return chunkQ6CPX4WT_cjs.d}});Object.defineProperty(exports,"logger",{enumerable:true,get:function(){return chunkQ6CPX4WT_cjs.c}});
1
+ 'use strict';var chunkUVQRIGIE_cjs=require('./chunk-UVQRIGIE.cjs'),chunkZC56ZMKZ_cjs=require('./chunk-ZC56ZMKZ.cjs'),chunkI6PNOIS2_cjs=require('./chunk-I6PNOIS2.cjs');Object.defineProperty(exports,"ZPMClient",{enumerable:true,get:function(){return chunkUVQRIGIE_cjs.a}});Object.defineProperty(exports,"zpm",{enumerable:true,get:function(){return chunkUVQRIGIE_cjs.b}});Object.defineProperty(exports,"ProcessManager",{enumerable:true,get:function(){return chunkZC56ZMKZ_cjs.d}});Object.defineProperty(exports,"Worker",{enumerable:true,get:function(){return chunkZC56ZMKZ_cjs.c}});Object.defineProperty(exports,"processStore",{enumerable:true,get:function(){return chunkZC56ZMKZ_cjs.a}});Object.defineProperty(exports,"runProbe",{enumerable:true,get:function(){return chunkZC56ZMKZ_cjs.b}});Object.defineProperty(exports,"WorkerMode",{enumerable:true,get:function(){return chunkI6PNOIS2_cjs.b}});Object.defineProperty(exports,"WorkerStatus",{enumerable:true,get:function(){return chunkI6PNOIS2_cjs.c}});Object.defineProperty(exports,"getSocketPath",{enumerable:true,get:function(){return chunkI6PNOIS2_cjs.e}});Object.defineProperty(exports,"logger",{enumerable:true,get:function(){return chunkI6PNOIS2_cjs.d}});
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export{a as ZPMClient,b as zpm}from'./chunk-3VIK6Q3M.js';export{d as ProcessManager,c as Worker,a as processStore,b as runProbe}from'./chunk-WNF7UADB.js';export{b as WorkerMode,c as WorkerStatus,e as getSocketPath,d as logger}from'./chunk-2PXF47OQ.js';
1
+ export{a as ZPMClient,b as zpm}from'./chunk-3VIK6Q3M.js';export{d as ProcessManager,c as Worker,a as processStore,b as runProbe}from'./chunk-PZ4XUM44.js';export{b as WorkerMode,c as WorkerStatus,e as getSocketPath,d as logger}from'./chunk-2PXF47OQ.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuzjs/pm",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "keywords": [
5
5
  "core",
6
6
  "zuz",
@@ -1,2 +0,0 @@
1
- 'use strict';var chunkQ6CPX4WT_cjs=require('./chunk-Q6CPX4WT.cjs'),T=require('events'),child_process=require('child_process'),S=require('http'),y=require('https'),C=require('net'),$=require('chokidar'),E=require('fs'),R=require('os'),d=require('path'),g=require('ws'),_=require('pidusage');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var T__default=/*#__PURE__*/_interopDefault(T);var S__default=/*#__PURE__*/_interopDefault(S);var y__default=/*#__PURE__*/_interopDefault(y);var C__default=/*#__PURE__*/_interopDefault(C);var $__default=/*#__PURE__*/_interopDefault($);var E__default=/*#__PURE__*/_interopDefault(E);var R__default=/*#__PURE__*/_interopDefault(R);var d__default=/*#__PURE__*/_interopDefault(d);var g__default=/*#__PURE__*/_interopDefault(g);var ___default=/*#__PURE__*/_interopDefault(_);/* ZuzJS Process Manager */
2
- var m=class extends T__default.default{map=new Map;set(t,e){this.map.set(t,e),this.emit("change",t,e);}get(t){return this.map.get(t)}has(t){return this.map.has(t)}delete(t){this.map.delete(t),this.emit("delete",t);}all(){return new Map(this.map)}onchange(t){return this.on("change",t)}offchange(t){return this.off("change",t)}},c=new m;function W(s,t){return new Promise(e=>{let o=(s.startsWith("https")?y__default.default:S__default.default).get(s,{timeout:t},n=>{e((n.statusCode??500)<500);});o.on("error",()=>e(false)),o.on("timeout",()=>{o.destroy(),e(false);});})}function F(s,t){let[e,r]=s.split(":"),o=Number(r);return new Promise(n=>{let a=C__default.default.createConnection({host:e,port:o},()=>{a.destroy(),n(true);});a.setTimeout(t),a.on("timeout",()=>{a.destroy(),n(false);}),a.on("error",()=>n(false));})}function M(s,t){return new Promise(e=>{let r=setTimeout(()=>e(false),t);child_process.exec(s,o=>{clearTimeout(r),e(!o);});})}async function f(s){let t=(s.timeoutSeconds??5)*1e3;switch(s.type){case "http":return W(s.target,t);case "tcp":return F(s.target,t);case "exec":return M(s.target,t);default:return false}}var w=5e3,A=16e3,b=1e3,D=5e3;async function N(s){return new Promise(t=>{C__default.default.createServer().once("error",()=>t(false)).once("listening",function(){this.close(()=>t(true));}).listen(s);})}async function O(s){await N(s)||(chunkQ6CPX4WT_cjs.c.warn("port",`Port ${s} busy \u2013 attempting fuser kill`),await new Promise(t=>child_process.exec(`fuser -k -9 ${s}/tcp 2>/dev/null; true`,()=>t())),await new Promise(t=>setTimeout(t,500)));}function k(s,t){let e=s.process?.pid??s.pid;if(!e)return;try{process.kill(e,"SIGTERM");}catch{return}let r=setTimeout(()=>{try{process.kill(e,"SIGKILL");}catch{}},t);s.once?.("exit",()=>clearTimeout(r)),s.once?.("exit",()=>clearTimeout(r));}var l=class{cfg;name;watcher=null;constructor(t){this.cfg={mode:"fork",instances:1,...t},this.name=t.name,this.initStore();}async start(){let t=this.mp();if(t.status==="running"||t.status==="starting"){chunkQ6CPX4WT_cjs.c.warn(this.name,"Already running \u2013 ignoring start()");return}this.patch({status:"starting"}),await this.spawnAll(),this.cfg.devMode&&this.watchFiles();}async stop(){let t=this.mp();this.patch({status:"stopping",isRestarting:false}),this.clearTimers(),this.stopProbe();for(let e of t.children)k(e,this.cfg.killTimeout??w);this.stopWatcher(),this.patch({children:[],status:"stopped",startTime:null}),chunkQ6CPX4WT_cjs.c.info(this.name,"Stopped.");}async restart(){chunkQ6CPX4WT_cjs.c.info(this.name,"Restarting...");let t=this.mp();this.patch({isRestarting:true}),this.clearTimers(),this.stopProbe();for(let e of t.children)k(e,this.cfg.killTimeout??w);}async getStats(){let t=this.mp(),e=t.children[0]?.pid??null,r=null,o=null,n=null;if(e&&t.status==="running")try{let a=await ___default.default(e);r=a.cpu,o=a.memory;}catch{}return {name:this.name,status:t.status,pid:e,uptime:t.startTime?Date.now()-t.startTime:null,restartCount:t.restartCount,cpu:r,memoryRss:o,memoryHeap:n,mode:this.cfg.mode??"fork",instances:t.children.length}}async spawnAll(){if(!E__default.default.existsSync(this.cfg.scriptPath)){chunkQ6CPX4WT_cjs.c.error(this.name,`Script not found: ${this.cfg.scriptPath}. Waiting for build...`),this.patch({status:"errored"});return}this.cfg.port&&await O(this.cfg.port);let t=this.cfg.mode??"fork",e=t==="cluster"?this.cfg.instances??R__default.default.cpus().length:1,r=[];for(let n=0;n<e;n++){let a=this.forkChild();a&&r.push(a);}this.patch({children:r,startTime:Date.now(),status:"running"}),chunkQ6CPX4WT_cjs.c.success(this.name,`Started ${r.length} instance(s) [${t}]`);let o=setTimeout(()=>{this.mp().status==="running"&&(this.patch({backoffTime:b,restartCount:0}),chunkQ6CPX4WT_cjs.c.success(this.name,"Process is stable."));},D);this.patch({stabilityTimer:o}),this.cfg.probe&&this.startProbe();}forkChild(){try{let t=child_process.spawn("node",[this.cfg.scriptPath,...this.cfg.args??[]],{stdio:["ignore","pipe","pipe"],env:{...process.env,...this.cfg.env??{},NODE_ENV:this.cfg.devMode?"development":"production"},detached:!1,shell:!1});this.setupLogging(t);let e=Date.now();return t.on("error",r=>{chunkQ6CPX4WT_cjs.c.error(this.name,"Spawn error:",r);}),t.on("exit",(r,o)=>{let n=Date.now()-e;this.onChildExit(t,r,o,n);}),t}catch(t){return chunkQ6CPX4WT_cjs.c.error(this.name,"Failed to fork child:",t),null}}onChildExit(t,e,r,o){let n=this.mp(),a=n.children.filter(u=>u!==t);if(this.patch({children:a}),n.status!=="stopping"){if(chunkQ6CPX4WT_cjs.c.warn(this.name,`Process exited (code=${e}, signal=${r}, uptime=${o}ms)`),n.isRestarting){a.length===0&&(this.patch({isRestarting:false}),this.spawnAll());return}if(e!==0&&e!==null){if(this.patch({status:"crashed"}),o<1500){chunkQ6CPX4WT_cjs.c.error(this.name,`Immediate crash (${o}ms) \u2013 likely a syntax/build error. Waiting for next file change.`);return}this.scheduleRestart();}}}scheduleRestart(){let t=this.mp(),e=t.backoffTime,r=this.cfg.maxBackoff??A;chunkQ6CPX4WT_cjs.c.warn(this.name,`Scheduling restart in ${e}ms (attempt #${t.restartCount+1})`);let o=setTimeout(async()=>{this.patch({restartCount:t.restartCount+1,backoffTime:Math.min(e*2,r)}),await this.spawnAll();},e);this.patch({restartTimer:o});}startProbe(){let t=this.cfg.probe,e=(t.intervalSeconds??10)*1e3,r=t.failureThreshold??3,n=setInterval(async()=>{let a=this.mp();if(a.status!=="running")return;if(await f(t)){a.probeFailures>0&&this.patch({probeFailures:0});return}let h=a.probeFailures+1;this.patch({probeFailures:h}),chunkQ6CPX4WT_cjs.c.warn(this.name,`Liveness probe failed (${h}/${r})`),h>=r&&(chunkQ6CPX4WT_cjs.c.error(this.name,"Liveness probe threshold exceeded \u2013 restarting."),this.patch({probeFailures:0}),await this.restart());},e);this.patch({probeTimer:n});}stopProbe(){let{probeTimer:t}=this.mp();t&&(clearInterval(t),this.patch({probeTimer:null,probeFailures:0}));}watchFiles(){this.stopWatcher();let t=d__default.default.dirname(this.cfg.scriptPath);this.watcher=$__default.default.watch(t,{ignored:[/node_modules/,/\.pid$/],persistent:true,ignoreInitial:true,awaitWriteFinish:{stabilityThreshold:1500,pollInterval:500}}),this.watcher.on("all",(e,r)=>{(e==="change"||e==="add")&&(chunkQ6CPX4WT_cjs.c.info(this.name,`File ${e}: ${d__default.default.basename(r)} \u2013 restarting`),this.restart());}),this.watcher.on("error",e=>chunkQ6CPX4WT_cjs.c.error(this.name,"Watcher error:",e)),this.watcher.on("ready",()=>chunkQ6CPX4WT_cjs.c.info(this.name,`Watching ${t}`));}stopWatcher(){this.watcher&&(this.watcher.close(),this.watcher=null);}initStore(){c.set(this.name,{config:this.cfg,children:[],status:"stopped",startTime:null,restartCount:0,backoffTime:b,restartTimer:null,stabilityTimer:null,probeTimer:null,probeFailures:0,isRestarting:false});}mp(){return c.get(this.name)}patch(t){c.set(this.name,{...this.mp(),...t});}clearTimers(){let{restartTimer:t,stabilityTimer:e}=this.mp();t&&clearTimeout(t),e&&clearTimeout(e),this.patch({restartTimer:null,stabilityTimer:null});}setupLogging(t){let e=this.cfg.logs?.wsUrl,r=null;e&&(r=new g__default.default(e),r.on("open",()=>chunkQ6CPX4WT_cjs.c.debug(this.name,"Connected to log collector")),r.on("error",n=>chunkQ6CPX4WT_cjs.c.error(this.name,"Log Collector WS Error",n.message)));let o=n=>{let a=n.toString();this.cfg.devMode&&process.stdout.write(`[${this.name}] ${a}`),r&&r.readyState===g__default.default.OPEN&&r.send(JSON.stringify({app:this.name,timestamp:Date.now(),log:a}));};t.stdout?.on("data",o),t.stderr?.on("data",o);}};var P=class{workers=new Map;async start(t){if(this.workers.has(t.name)){chunkQ6CPX4WT_cjs.c.warn("PM",`Worker "${t.name}" already registered \u2013 use restart()`);return}let e=new l(t);this.workers.set(t.name,e),await e.start();}async stop(t){await this.require(t).stop();}async restart(t){await this.require(t).restart();}async delete(t){await this.require(t).stop(),this.workers.delete(t),c.delete(t),chunkQ6CPX4WT_cjs.c.info("PM",`Deleted worker "${t}"`);}async getStats(t){return t?[await this.require(t).getStats()]:await Promise.all([...this.workers.values()].map(r=>r.getStats()))}list(){return [...this.workers.keys()]}async stopAll(){chunkQ6CPX4WT_cjs.c.info("PM","Stopping all workers..."),await Promise.all([...this.workers.values()].map(t=>t.stop())),chunkQ6CPX4WT_cjs.c.info("PM","All workers stopped.");}getWorker(t){let e=this.workers.get(t);return e||null}require(t){let e=this.workers.get(t);if(!e)throw new Error(`Worker "${t}" not found`);return e}};exports.a=c;exports.b=f;exports.c=l;exports.d=P;
@@ -1,7 +0,0 @@
1
- 'use strict';var d=require('fs'),I=require('net'),b=require('os'),w=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var d__default=/*#__PURE__*/_interopDefault(d);var I__default=/*#__PURE__*/_interopDefault(I);var b__default=/*#__PURE__*/_interopDefault(b);var w__default=/*#__PURE__*/_interopDefault(w);/* ZuzJS Process Manager */
2
- var h=(s=>(s.Fork="fork",s.Cluster="cluster",s))(h||{}),P=(o=>(o.Stopped="stopped",o.Starting="starting",o.Running="running",o.Stopping="stopping",o.Crashed="crashed",o.Errored="errored",o))(P||{});var x={info:"\x1B[36m",warn:"\x1B[33m",error:"\x1B[31m",debug:"\x1B[90m",success:"\x1B[32m"},y="\x1B[0m",v="\x1B[1m";function $(){return new Date().toISOString()}function l(r,e,...s){let n=x[r],t=`${v}${n}[ZPM/${e.toUpperCase()}]${y} ${$()}`;console[r==="success"?"log":r](`${t} \u2192`,...s);}var g={info:(r,...e)=>l("info",r,...e),warn:(r,...e)=>l("warn",r,...e),error:(r,...e)=>l("error",r,...e),debug:(r,...e)=>l("debug",r,...e),success:(r,...e)=>l("success",r,...e)};function T(r="zuz-pm"){return b__default.default.platform()==="win32"?w__default.default.join("\\\\.\\pipe",r):w__default.default.join(b__default.default.tmpdir(),`${r}.sock`)}function F(r){let e=T();d__default.default.existsSync(e)&&d__default.default.unlinkSync(e);let s=I__default.default.createServer(n=>{let t="";n.on("data",i=>{t+=i.toString();let o=t.split(`
3
- `);t=o.pop()??"";for(let u of o)u.trim()&&L(r,n,u);}),n.on("error",i=>{g.error("IPC","Socket error:",i.message);});});return s.listen(e,()=>{if(b__default.default.platform()!=="win32")try{d__default.default.chmodSync(e,"777");}catch(n){console.error("Failed to set socket permissions:",n);}g.success("IPC",`Listening on ${e}`);}),s.on("error",n=>{g.error("IPC","Server error:",n);}),s}async function L(r,e,s){let n;try{n=JSON.parse(s);}catch{p(e,{ok:false,error:"Invalid JSON"});return}try{let t=null;switch(n.cmd){case "ping":t="pong";break;case "start":await r.start(n.config),t=`Started "${n.name}"`;break;case "stop":await r.stop(n.name),t=`Stopped "${n.name}"`;break;case "restart":await r.restart(n.name),t=`Restarted "${n.name}"`;break;case "delete":await r.delete(n.name),t=`Deleted "${n.name}"`;break;case "stats":t=await r.getStats(n.name);break;case "list":t=r.list();break;case "logs":let i=n.name,o=[];if(i){let a=r.getWorker(i);if(!a){e.write(JSON.stringify({ok:!1,error:`Worker "${i}" not found`})+`
4
- `);return}o.push(a);}else {let a=r.list();for(let m of a){let c=r.getWorker(m);c&&o.push(c);}}if(o.length===0){e.write(JSON.stringify({ok:!1,error:"No active workers to stream logs from"})+`
5
- `);return}let u=[];for(let a of o){let m=a.mp();for(let c of m.children){let f=S=>{let C=i?"":`[${a.name}] `;e.write(JSON.stringify({ok:!0,data:`${C}${S.toString()}`})+`
6
- `);};c.stdout?.on("data",f),c.stderr?.on("data",f),u.push({child:c,onData:f});}}e.on("close",()=>{for(let{child:a,onData:m}of u)a.stdout?.off("data",m),a.stderr?.off("data",m);});break;default:throw new Error(`Unknown command: ${n.cmd}`)}p(e,{ok:!0,data:t});}catch(t){p(e,{ok:false,error:String(t.message??t)});}}function p(r,e){r.writable&&r.write(JSON.stringify(e)+`
7
- `);}exports.a=h;exports.b=P;exports.c=g;exports.d=T;exports.e=F;
@@ -1 +0,0 @@
1
- import {d as d$1}from'./chunk-2PXF47OQ.js';import v from'events';import {spawn,exec}from'child_process';import y from'http';import C from'https';import W from'net';import x from'chokidar';import I from'fs';import _ from'os';import g from'path';import w from'ws';import A from'pidusage';var m=class extends v{map=new Map;set(t,e){this.map.set(t,e),this.emit("change",t,e);}get(t){return this.map.get(t)}has(t){return this.map.has(t)}delete(t){this.map.delete(t),this.emit("delete",t);}all(){return new Map(this.map)}onchange(t){return this.on("change",t)}offchange(t){return this.off("change",t)}},c=new m;function F(s,t){return new Promise(e=>{let o=(s.startsWith("https")?C:y).get(s,{timeout:t},n=>{e((n.statusCode??500)<500);});o.on("error",()=>e(false)),o.on("timeout",()=>{o.destroy(),e(false);});})}function M(s,t){let[e,r]=s.split(":"),o=Number(r);return new Promise(n=>{let a=W.createConnection({host:e,port:o},()=>{a.destroy(),n(true);});a.setTimeout(t),a.on("timeout",()=>{a.destroy(),n(false);}),a.on("error",()=>n(false));})}function $(s,t){return new Promise(e=>{let r=setTimeout(()=>e(false),t);exec(s,o=>{clearTimeout(r),e(!o);});})}async function d(s){let t=(s.timeoutSeconds??5)*1e3;switch(s.type){case "http":return F(s.target,t);case "tcp":return M(s.target,t);case "exec":return $(s.target,t);default:return false}}var b=5e3,D=16e3,k=1e3,N=5e3;async function O(s){return new Promise(t=>{W.createServer().once("error",()=>t(false)).once("listening",function(){this.close(()=>t(true));}).listen(s);})}async function q(s){await O(s)||(d$1.warn("port",`Port ${s} busy \u2013 attempting fuser kill`),await new Promise(t=>exec(`fuser -k -9 ${s}/tcp 2>/dev/null; true`,()=>t())),await new Promise(t=>setTimeout(t,500)));}function P(s,t){let e=s.process?.pid??s.pid;if(!e)return;try{process.kill(e,"SIGTERM");}catch{return}let r=setTimeout(()=>{try{process.kill(e,"SIGKILL");}catch{}},t);s.once?.("exit",()=>clearTimeout(r)),s.once?.("exit",()=>clearTimeout(r));}var l=class{cfg;name;watcher=null;constructor(t){this.cfg={mode:"fork",instances:1,...t},this.name=t.name,this.initStore();}async start(){let t=this.mp();if(t.status==="running"||t.status==="starting"){d$1.warn(this.name,"Already running \u2013 ignoring start()");return}this.patch({status:"starting"}),await this.spawnAll(),this.cfg.devMode&&this.watchFiles();}async stop(){let t=this.mp();this.patch({status:"stopping",isRestarting:false}),this.clearTimers(),this.stopProbe();for(let e of t.children)P(e,this.cfg.killTimeout??b);this.stopWatcher(),this.patch({children:[],status:"stopped",startTime:null}),d$1.info(this.name,"Stopped.");}async restart(){d$1.info(this.name,"Restarting...");let t=this.mp();this.patch({isRestarting:true}),this.clearTimers(),this.stopProbe();for(let e of t.children)P(e,this.cfg.killTimeout??b);}async getStats(){let t=this.mp(),e=t.children[0]?.pid??null,r=null,o=null,n=null;if(e&&t.status==="running")try{let a=await A(e);r=a.cpu,o=a.memory;}catch{}return {name:this.name,status:t.status,pid:e,uptime:t.startTime?Date.now()-t.startTime:null,restartCount:t.restartCount,cpu:r,memoryRss:o,memoryHeap:n,mode:this.cfg.mode??"fork",instances:t.children.length}}async spawnAll(){if(!I.existsSync(this.cfg.scriptPath)){d$1.error(this.name,`Script not found: ${this.cfg.scriptPath}. Waiting for build...`),this.patch({status:"errored"});return}this.cfg.port&&await q(this.cfg.port);let t=this.cfg.mode??"fork",e=t==="cluster"?this.cfg.instances??_.cpus().length:1,r=[];for(let n=0;n<e;n++){let a=this.forkChild();a&&r.push(a);}this.patch({children:r,startTime:Date.now(),status:"running"}),d$1.success(this.name,`Started ${r.length} instance(s) [${t}]`);let o=setTimeout(()=>{this.mp().status==="running"&&(this.patch({backoffTime:k,restartCount:0}),d$1.success(this.name,"Process is stable."));},N);this.patch({stabilityTimer:o}),this.cfg.probe&&this.startProbe();}forkChild(){try{let t=spawn("node",[this.cfg.scriptPath,...this.cfg.args??[]],{stdio:["ignore","pipe","pipe"],env:{...process.env,...this.cfg.env??{},NODE_ENV:this.cfg.devMode?"development":"production"},detached:!1,shell:!1});this.setupLogging(t);let e=Date.now();return t.on("error",r=>{d$1.error(this.name,"Spawn error:",r);}),t.on("exit",(r,o)=>{let n=Date.now()-e;this.onChildExit(t,r,o,n);}),t}catch(t){return d$1.error(this.name,"Failed to fork child:",t),null}}onChildExit(t,e,r,o){let n=this.mp(),a=n.children.filter(f=>f!==t);if(this.patch({children:a}),n.status!=="stopping"){if(d$1.warn(this.name,`Process exited (code=${e}, signal=${r}, uptime=${o}ms)`),n.isRestarting){a.length===0&&(this.patch({isRestarting:false}),this.spawnAll());return}if(e!==0&&e!==null){if(this.patch({status:"crashed"}),o<1500){d$1.error(this.name,`Immediate crash (${o}ms) \u2013 likely a syntax/build error. Waiting for next file change.`);return}this.scheduleRestart();}}}scheduleRestart(){let t=this.mp(),e=t.backoffTime,r=this.cfg.maxBackoff??D;d$1.warn(this.name,`Scheduling restart in ${e}ms (attempt #${t.restartCount+1})`);let o=setTimeout(async()=>{this.patch({restartCount:t.restartCount+1,backoffTime:Math.min(e*2,r)}),await this.spawnAll();},e);this.patch({restartTimer:o});}startProbe(){let t=this.cfg.probe,e=(t.intervalSeconds??10)*1e3,r=t.failureThreshold??3,n=setInterval(async()=>{let a=this.mp();if(a.status!=="running")return;if(await d(t)){a.probeFailures>0&&this.patch({probeFailures:0});return}let h=a.probeFailures+1;this.patch({probeFailures:h}),d$1.warn(this.name,`Liveness probe failed (${h}/${r})`),h>=r&&(d$1.error(this.name,"Liveness probe threshold exceeded \u2013 restarting."),this.patch({probeFailures:0}),await this.restart());},e);this.patch({probeTimer:n});}stopProbe(){let{probeTimer:t}=this.mp();t&&(clearInterval(t),this.patch({probeTimer:null,probeFailures:0}));}watchFiles(){this.stopWatcher();let t=g.dirname(this.cfg.scriptPath);this.watcher=x.watch(t,{ignored:[/node_modules/,/\.pid$/],persistent:true,ignoreInitial:true,awaitWriteFinish:{stabilityThreshold:1500,pollInterval:500}}),this.watcher.on("all",(e,r)=>{(e==="change"||e==="add")&&(d$1.info(this.name,`File ${e}: ${g.basename(r)} \u2013 restarting`),this.restart());}),this.watcher.on("error",e=>d$1.error(this.name,"Watcher error:",e)),this.watcher.on("ready",()=>d$1.info(this.name,`Watching ${t}`));}stopWatcher(){this.watcher&&(this.watcher.close(),this.watcher=null);}initStore(){c.set(this.name,{config:this.cfg,children:[],status:"stopped",startTime:null,restartCount:0,backoffTime:k,restartTimer:null,stabilityTimer:null,probeTimer:null,probeFailures:0,isRestarting:false});}mp(){return c.get(this.name)}patch(t){c.set(this.name,{...this.mp(),...t});}clearTimers(){let{restartTimer:t,stabilityTimer:e}=this.mp();t&&clearTimeout(t),e&&clearTimeout(e),this.patch({restartTimer:null,stabilityTimer:null});}setupLogging(t){let e=this.cfg.logs?.wsUrl,r=null;e&&(r=new w(e),r.on("open",()=>d$1.debug(this.name,"Connected to log collector")),r.on("error",n=>d$1.error(this.name,"Log Collector WS Error",n.message)));let o=n=>{let a=n.toString();this.cfg.devMode&&process.stdout.write(`[${this.name}] ${a}`),r&&r.readyState===w.OPEN&&r.send(JSON.stringify({app:this.name,timestamp:Date.now(),log:a}));};t.stdout?.on("data",o),t.stderr?.on("data",o);}};var T=class{workers=new Map;async start(t){if(this.workers.has(t.name)){d$1.warn("PM",`Worker "${t.name}" already registered \u2013 use restart()`);return}let e=new l(t);this.workers.set(t.name,e),await e.start();}async stop(t){await this.require(t).stop();}async restart(t){await this.require(t).restart();}async delete(t){await this.require(t).stop(),this.workers.delete(t),c.delete(t),d$1.info("PM",`Deleted worker "${t}"`);}async getStats(t){return t?[await this.require(t).getStats()]:await Promise.all([...this.workers.values()].map(r=>r.getStats()))}list(){return [...this.workers.keys()]}async stopAll(){d$1.info("PM","Stopping all workers..."),await Promise.all([...this.workers.values()].map(t=>t.stop())),d$1.info("PM","All workers stopped.");}getWorker(t){let e=this.workers.get(t);return e||null}require(t){let e=this.workers.get(t);if(!e)throw new Error(`Worker "${t}" not found`);return e}};export{c as a,d as b,l as c,T as d};