@zuzjs/pm 0.0.6 → 0.0.8

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,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'),$=require('chokidar'),R=require('fs'),_=require('os'),p=require('path'),b=require('ws'),E=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 $__default=/*#__PURE__*/_interopDefault($);var R__default=/*#__PURE__*/_interopDefault(R);var ___default=/*#__PURE__*/_interopDefault(_);var p__default=/*#__PURE__*/_interopDefault(p);var b__default=/*#__PURE__*/_interopDefault(b);var E__default=/*#__PURE__*/_interopDefault(E);/* ZuzJS Process Manager */
2
+ var f=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)}},h=new f;function C(n,t){return new Promise(e=>{let o=(n.startsWith("https")?y__default.default:S__default.default).get(n,{timeout:t},s=>{e((s.statusCode??500)<500);});o.on("error",()=>e(false)),o.on("timeout",()=>{o.destroy(),e(false);});})}function x(n,t){let[e,r]=n.split(":"),o=Number(r);return new Promise(s=>{let a=W__default.default.createConnection({host:e,port:o},()=>{a.destroy(),s(true);});a.setTimeout(t),a.on("timeout",()=>{a.destroy(),s(false);}),a.on("error",()=>s(false));})}function F(n,t){return new Promise(e=>{let r=setTimeout(()=>e(false),t);child_process.exec(n,o=>{clearTimeout(r),e(!o);});})}async function w(n){let t=(n.timeoutSeconds??5)*1e3;switch(n.type){case "http":return C(n.target,t);case "tcp":return x(n.target,t);case "exec":return F(n.target,t);default:return false}}var m=5e3,A=16e3,k=1e3,D=5e3;async function N(n){return new Promise(t=>{W__default.default.createServer().once("error",()=>t(false)).once("listening",function(){this.close(()=>t(true));}).listen(n);})}async function K(n){await N(n)||(chunkI6PNOIS2_cjs.d.warn("port",`Port ${n} busy \u2013 attempting fuser kill`),await new Promise(t=>child_process.exec(`fuser -k -9 ${n}/tcp 2>/dev/null; true`,()=>t())),await new Promise(t=>setTimeout(t,500)));}async function u(n,t){let e=n.process?.pid??n.pid;if(e)return new Promise(r=>{let o=false,s=()=>{o||(o=true,clearTimeout(a),r());};n.once?.("exit",s),n.once?.("exit",s);try{process.kill(e,"SIGTERM");}catch{return s()}let a=setTimeout(()=>{try{process.kill(e,"SIGKILL"),setTimeout(s,100);}catch{s();}},t),c=setInterval(()=>{try{process.kill(e,0);}catch{clearInterval(c),s();}},500);})}var d=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();if(t.status!=="stopping"){this.patch({status:"stopping",isRestarting:false}),chunkI6PNOIS2_cjs.d.info(this.name,`Stopping ${t.children.length} instances...`),this.clearTimers(),this.stopProbe(),this.stopWatcher();try{await Promise.race([Promise.all(t.children.map(e=>u(e,this.cfg.killTimeout??m))),new Promise((e,r)=>setTimeout(()=>r(new Error("Termination timeout")),1e4))]);}catch(e){chunkI6PNOIS2_cjs.d.error(this.name,`Stop timed out, forcing state reset: ${e.message||"UNKNOWN"}`);}this.patch({children:[],status:"stopped",startTime:null}),this.stopWatcher(),chunkI6PNOIS2_cjs.d.success(this.name,"Stopped.");}}async _stop(){let t=this.mp();this.patch({status:"stopping",isRestarting:false}),this.clearTimers(),this.stopProbe();for(let e of t.children)u(e,this.cfg.killTimeout??m);this.stopWatcher(),this.patch({children:[],status:"stopped",startTime:null}),chunkI6PNOIS2_cjs.d.info(this.name,"Stopped.");}async restart(){let t=this.mp();t.isRestarting||(chunkI6PNOIS2_cjs.d.info(this.name,"Restarting..."),this.patch({isRestarting:true,status:"stopping"}),this.clearTimers(),this.stopProbe(),await Promise.all(t.children.map(e=>u(e,this.cfg.killTimeout??m))),this.patch({isRestarting:false,children:[]}));}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)u(e,this.cfg.killTimeout??m);}async getStats(){let t=this.mp(),e=t.children[0]?.pid??null,r=null,o=null,s=null;if(e&&t.status==="running")try{let a=await E__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:s,mode:this.cfg.mode??"fork",instances:t.children.length}}async spawnAll(){if(!R__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 K(this.cfg.port);let t=this.cfg.mode??"fork",e=t==="cluster"?this.cfg.instances??___default.default.cpus().length:1,r=[];for(let s=0;s<e;s++){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 o=setTimeout(()=>{this.mp().status==="running"&&(this.patch({backoffTime:k,restartCount:0}),chunkI6PNOIS2_cjs.d.success(this.name,"Process is stable."));},D);this.patch({stabilityTimer:o}),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,{cwd:p__default.default.dirname(p__default.default.resolve(this.cfg.scriptPath,"..")),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 o=Date.now();return r.on("error",s=>{chunkI6PNOIS2_cjs.d.error(this.name,"Spawn error:",s);}),r.on("exit",(s,a)=>{let c=Date.now()-o;this.onChildExit(r,s,a,c);}),r}catch(t){return chunkI6PNOIS2_cjs.d.error(this.name,"Failed to fork child:",t),null}}onChildExit(t,e,r,o){let s=this.mp(),a=s.children.filter(c=>c!==t);if(this.patch({children:a}),s.status!=="stopping"){if(chunkI6PNOIS2_cjs.d.warn(this.name,`Process exited (code=${e}, signal=${r}, uptime=${o}ms)`),s.isRestarting){a.length===0&&(this.patch({isRestarting:false}),this.spawnAll());return}if(e!==0&&e!==null){if(this.patch({status:"crashed"}),o<1500){chunkI6PNOIS2_cjs.d.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;chunkI6PNOIS2_cjs.d.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,s=setInterval(async()=>{let a=this.mp();if(a.status!=="running")return;if(await w(t)){a.probeFailures>0&&this.patch({probeFailures:0});return}let l=a.probeFailures+1;this.patch({probeFailures:l}),chunkI6PNOIS2_cjs.d.warn(this.name,`Liveness probe failed (${l}/${r})`),l>=r&&(chunkI6PNOIS2_cjs.d.error(this.name,"Liveness probe threshold exceeded \u2013 restarting."),this.patch({probeFailures:0}),await this.restart());},e);this.patch({probeTimer:s});}stopProbe(){let{probeTimer:t}=this.mp();t&&(clearInterval(t),this.patch({probeTimer:null,probeFailures:0}));}watchFiles(){this.stopWatcher();let t=p__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")&&(chunkI6PNOIS2_cjs.d.info(this.name,`File ${e}: ${p__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(){h.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 h.get(this.name)}patch(t){h.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 b__default.default(e),r.on("open",()=>chunkI6PNOIS2_cjs.d.debug(this.name,"Connected to log collector")),r.on("error",s=>chunkI6PNOIS2_cjs.d.error(this.name,"Log Collector WS Error",s.message)));let o=s=>{let a=s.toString();this.cfg.devMode&&process.stdout.write(`[${this.name}] ${a}`),r&&r.readyState===b__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)){chunkI6PNOIS2_cjs.d.warn("PM",`Worker "${t.name}" already registered \u2013 use restart()`);return}let e=new d(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),h.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=h;exports.b=w;exports.c=d;exports.d=P;
@@ -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 M from'chokidar';import L from'fs';import E from'os';import p from'path';import k from'ws';import A from'pidusage';var f=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)}},h=new f;function x(n,t){return new Promise(e=>{let o=(n.startsWith("https")?W:y).get(n,{timeout:t},s=>{e((s.statusCode??500)<500);});o.on("error",()=>e(false)),o.on("timeout",()=>{o.destroy(),e(false);});})}function F(n,t){let[e,r]=n.split(":"),o=Number(r);return new Promise(s=>{let a=C.createConnection({host:e,port:o},()=>{a.destroy(),s(true);});a.setTimeout(t),a.on("timeout",()=>{a.destroy(),s(false);}),a.on("error",()=>s(false));})}function $(n,t){return new Promise(e=>{let r=setTimeout(()=>e(false),t);exec(n,o=>{clearTimeout(r),e(!o);});})}async function b(n){let t=(n.timeoutSeconds??5)*1e3;switch(n.type){case "http":return x(n.target,t);case "tcp":return F(n.target,t);case "exec":return $(n.target,t);default:return false}}var m=5e3,D=16e3,P=1e3,N=5e3;async function K(n){return new Promise(t=>{C.createServer().once("error",()=>t(false)).once("listening",function(){this.close(()=>t(true));}).listen(n);})}async function O(n){await K(n)||(d$1.warn("port",`Port ${n} busy \u2013 attempting fuser kill`),await new Promise(t=>exec(`fuser -k -9 ${n}/tcp 2>/dev/null; true`,()=>t())),await new Promise(t=>setTimeout(t,500)));}async function u(n,t){let e=n.process?.pid??n.pid;if(e)return new Promise(r=>{let o=false,s=()=>{o||(o=true,clearTimeout(a),r());};n.once?.("exit",s),n.once?.("exit",s);try{process.kill(e,"SIGTERM");}catch{return s()}let a=setTimeout(()=>{try{process.kill(e,"SIGKILL"),setTimeout(s,100);}catch{s();}},t),c=setInterval(()=>{try{process.kill(e,0);}catch{clearInterval(c),s();}},500);})}var d=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();if(t.status!=="stopping"){this.patch({status:"stopping",isRestarting:false}),d$1.info(this.name,`Stopping ${t.children.length} instances...`),this.clearTimers(),this.stopProbe(),this.stopWatcher();try{await Promise.race([Promise.all(t.children.map(e=>u(e,this.cfg.killTimeout??m))),new Promise((e,r)=>setTimeout(()=>r(new Error("Termination timeout")),1e4))]);}catch(e){d$1.error(this.name,`Stop timed out, forcing state reset: ${e.message||"UNKNOWN"}`);}this.patch({children:[],status:"stopped",startTime:null}),this.stopWatcher(),d$1.success(this.name,"Stopped.");}}async _stop(){let t=this.mp();this.patch({status:"stopping",isRestarting:false}),this.clearTimers(),this.stopProbe();for(let e of t.children)u(e,this.cfg.killTimeout??m);this.stopWatcher(),this.patch({children:[],status:"stopped",startTime:null}),d$1.info(this.name,"Stopped.");}async restart(){let t=this.mp();t.isRestarting||(d$1.info(this.name,"Restarting..."),this.patch({isRestarting:true,status:"stopping"}),this.clearTimers(),this.stopProbe(),await Promise.all(t.children.map(e=>u(e,this.cfg.killTimeout??m))),this.patch({isRestarting:false,children:[]}));}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)u(e,this.cfg.killTimeout??m);}async getStats(){let t=this.mp(),e=t.children[0]?.pid??null,r=null,o=null,s=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:s,mode:this.cfg.mode??"fork",instances:t.children.length}}async spawnAll(){if(!L.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 O(this.cfg.port);let t=this.cfg.mode??"fork",e=t==="cluster"?this.cfg.instances??E.cpus().length:1,r=[];for(let s=0;s<e;s++){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:P,restartCount:0}),d$1.success(this.name,"Process is stable."));},N);this.patch({stabilityTimer:o}),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,{cwd:p.dirname(p.resolve(this.cfg.scriptPath,"..")),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 o=Date.now();return r.on("error",s=>{d$1.error(this.name,"Spawn error:",s);}),r.on("exit",(s,a)=>{let c=Date.now()-o;this.onChildExit(r,s,a,c);}),r}catch(t){return d$1.error(this.name,"Failed to fork child:",t),null}}onChildExit(t,e,r,o){let s=this.mp(),a=s.children.filter(c=>c!==t);if(this.patch({children:a}),s.status!=="stopping"){if(d$1.warn(this.name,`Process exited (code=${e}, signal=${r}, uptime=${o}ms)`),s.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,s=setInterval(async()=>{let a=this.mp();if(a.status!=="running")return;if(await b(t)){a.probeFailures>0&&this.patch({probeFailures:0});return}let l=a.probeFailures+1;this.patch({probeFailures:l}),d$1.warn(this.name,`Liveness probe failed (${l}/${r})`),l>=r&&(d$1.error(this.name,"Liveness probe threshold exceeded \u2013 restarting."),this.patch({probeFailures:0}),await this.restart());},e);this.patch({probeTimer:s});}stopProbe(){let{probeTimer:t}=this.mp();t&&(clearInterval(t),this.patch({probeTimer:null,probeFailures:0}));}watchFiles(){this.stopWatcher();let t=p.dirname(this.cfg.scriptPath);this.watcher=M.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}: ${p.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(){h.set(this.name,{config:this.cfg,children:[],status:"stopped",startTime:null,restartCount:0,backoffTime:P,restartTimer:null,stabilityTimer:null,probeTimer:null,probeFailures:0,isRestarting:false});}mp(){return h.get(this.name)}patch(t){h.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 k(e),r.on("open",()=>d$1.debug(this.name,"Connected to log collector")),r.on("error",s=>d$1.error(this.name,"Log Collector WS Error",s.message)));let o=s=>{let a=s.toString();this.cfg.devMode&&process.stdout.write(`[${this.name}] ${a}`),r&&r.readyState===k.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 d(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),h.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{h as a,b,d as c,T as d};
package/dist/daemon.cjs CHANGED
@@ -1,2 +1,2 @@
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);});
1
+ 'use strict';var chunk2LEY6YM2_cjs=require('./chunk-2LEY6YM2.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 chunk2LEY6YM2_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-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);});
1
+ import {d as d$2}from'./chunk-6W2QFG74.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 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}});
1
+ 'use strict';var chunkUVQRIGIE_cjs=require('./chunk-UVQRIGIE.cjs'),chunk2LEY6YM2_cjs=require('./chunk-2LEY6YM2.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 chunk2LEY6YM2_cjs.d}});Object.defineProperty(exports,"Worker",{enumerable:true,get:function(){return chunk2LEY6YM2_cjs.c}});Object.defineProperty(exports,"processStore",{enumerable:true,get:function(){return chunk2LEY6YM2_cjs.a}});Object.defineProperty(exports,"runProbe",{enumerable:true,get:function(){return chunk2LEY6YM2_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.d.cts CHANGED
@@ -128,7 +128,9 @@ declare class Worker {
128
128
  constructor(config: WorkerConfig);
129
129
  start(): Promise<void>;
130
130
  stop(): Promise<void>;
131
+ _stop(): Promise<void>;
131
132
  restart(): Promise<void>;
133
+ _restart(): Promise<void>;
132
134
  getStats(): Promise<WorkerStats>;
133
135
  private spawnAll;
134
136
  private forkChild;
package/dist/index.d.ts CHANGED
@@ -128,7 +128,9 @@ declare class Worker {
128
128
  constructor(config: WorkerConfig);
129
129
  start(): Promise<void>;
130
130
  stop(): Promise<void>;
131
+ _stop(): Promise<void>;
131
132
  restart(): Promise<void>;
133
+ _restart(): Promise<void>;
132
134
  getStats(): Promise<WorkerStats>;
133
135
  private spawnAll;
134
136
  private forkChild;
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-PZ4XUM44.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-6W2QFG74.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.6",
3
+ "version": "0.0.8",
4
4
  "keywords": [
5
5
  "core",
6
6
  "zuz",
@@ -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 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,2 +0,0 @@
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;