@zuzjs/pm 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-2PXF47OQ.js +6 -0
- package/dist/chunk-3VIK6Q3M.js +3 -0
- package/dist/chunk-P7YR7QX3.cjs +2 -0
- package/dist/chunk-Q6CPX4WT.cjs +7 -0
- package/dist/chunk-VDYHM6XJ.cjs +4 -0
- package/dist/chunk-WNF7UADB.js +1 -0
- package/dist/cli.cjs +5 -13
- package/dist/cli.js +4 -12
- package/dist/daemon.cjs +2 -2
- package/dist/daemon.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +40 -25
- package/dist/index.d.ts +40 -25
- package/dist/index.js +1 -1
- package/package.json +4 -2
- package/dist/chunk-5RMT5B2R.js +0 -3
- package/dist/chunk-BBXSSJFF.cjs +0 -4
- package/dist/chunk-IIKD4V5E.js +0 -1
- package/dist/chunk-J6AZRPZZ.js +0 -3
- package/dist/chunk-LM53EFPZ.cjs +0 -4
- package/dist/chunk-RDE2YGL7.cjs +0 -2
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import S from'path';import {fileURLToPath}from'url';import p from'fs';import O from'net';import k from'os';var y=()=>fileURLToPath(import.meta.url),v=()=>S.dirname(y()),d=v();var $=(s=>(s.Fork="fork",s.Cluster="cluster",s))($||{}),I=(o=>(o.Stopped="stopped",o.Starting="starting",o.Running="running",o.Stopping="stopping",o.Crashed="crashed",o.Errored="errored",o))(I||{});var T={info:"\x1B[36m",warn:"\x1B[33m",error:"\x1B[31m",debug:"\x1B[90m",success:"\x1B[32m"},L="\x1B[0m",N="\x1B[1m";function R(){return new Date().toISOString()}function l(r,e,...s){let n=T[r],t=`${N}${n}[ZPM/${e.toUpperCase()}]${L} ${R()}`;console[r==="success"?"log":r](`${t} \u2192`,...s);}var f={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 J(r="zuz-pm"){return k.platform()==="win32"?S.join("\\\\.\\pipe",r):S.join(k.tmpdir(),`${r}.sock`)}function q(r){let e=J();p.existsSync(e)&&p.unlinkSync(e);let s=O.createServer(n=>{let t="";n.on("data",i=>{t+=i.toString();let o=t.split(`
|
|
2
|
+
`);t=o.pop()??"";for(let u of o)u.trim()&&D(r,n,u);}),n.on("error",i=>{f.error("IPC","Socket error:",i.message);});});return s.listen(e,()=>{if(k.platform()!=="win32")try{p.chmodSync(e,"777");}catch(n){console.error("Failed to set socket permissions:",n);}f.success("IPC",`Listening on ${e}`);}),s.on("error",n=>{f.error("IPC","Server error:",n);}),s}async function D(r,e,s){let n;try{n=JSON.parse(s);}catch{b(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`})+`
|
|
3
|
+
`);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"})+`
|
|
4
|
+
`);return}let u=[];for(let a of o){let m=a.mp();for(let c of m.children){let g=C=>{let h=i?"":`[${a.name}] `;e.write(JSON.stringify({ok:!0,data:`${h}${C.toString()}`})+`
|
|
5
|
+
`);};c.stdout?.on("data",g),c.stderr?.on("data",g),u.push({child:c,onData:g});}}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}`)}b(e,{ok:!0,data:t});}catch(t){b(e,{ok:false,error:String(t.message??t)});}}function b(r,e){r.writable&&r.write(JSON.stringify(e)+`
|
|
6
|
+
`);}export{d as a,$ as b,I as c,f as d,J as e,q as f};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {a,d,e}from'./chunk-2PXF47OQ.js';import {spawn}from'child_process';import p from'fs';import y from'net';import w from'os';import f from'path';function i(d,n="zuz-pm"){return new Promise((t,r)=>{let e$1=y.createConnection(e(n)),o="";e$1.on("connect",()=>{e$1.write(JSON.stringify(d)+`
|
|
2
|
+
`);}),e$1.on("data",s=>{o+=s.toString();let m=o.split(`
|
|
3
|
+
`);o=m.pop()??"";for(let l of m)if(l.trim())try{let a=JSON.parse(l);e$1.destroy(),a.ok?t(a.data):r(new Error(a.error));}catch(a){e$1.destroy(),r(a);}}),e$1.on("error",s=>r(s)),e$1.setTimeout(1e4,()=>{e$1.destroy(),r(new Error("IPC timeout"));});})}var u=class{daemonScript;namespace;constructor(n){this.namespace=n?.namespace??"zuz-pm",this.daemonScript=n?.daemonScript??f.join(a,"daemon.js");}async isDaemonRunning(){try{return d.info("[ZPM]","Daemon is Running :?"),await i({cmd:"ping"},this.namespace),!0}catch{return d.info("[ZPM]","Daemon is not running."),false}}async ensureDaemon(){if(await this.isDaemonRunning())return;d.info("Starting ZPM daemon...");let t=process.env.NODE_ENV!=="production";spawn(process.execPath,[this.daemonScript],{detached:true,stdio:t?"inherit":"ignore"}).unref(),await this.waitForDaemon(8e3);}async killDaemon(){let n=f.join(w.tmpdir(),"zuz-pm.pid");if(!p.existsSync(n))throw new Error("Daemon PID file not found \u2013 is the daemon running?");let t=Number(p.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.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);})}},I=new u;export{u as a,I as b};
|
|
@@ -0,0 +1,2 @@
|
|
|
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;
|
|
@@ -0,0 +1,7 @@
|
|
|
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;
|
|
@@ -0,0 +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)+`
|
|
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;
|
|
@@ -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 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};
|
package/dist/cli.cjs
CHANGED
|
@@ -1,14 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
'use strict';var
|
|
3
|
-
var
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
zpm start <script> [--name <n>] [--port <p>] [--instances <i>] [--dev] [--cluster]
|
|
8
|
-
zpm stop <name>
|
|
9
|
-
zpm restart <name>
|
|
10
|
-
zpm delete <name>
|
|
11
|
-
zpm list
|
|
12
|
-
zpm stats [name]
|
|
13
|
-
zpm kill-daemon
|
|
14
|
-
`);}}d().catch(e=>{console.error("[ZPM] Error:",e.message??e),process.exit(1);});
|
|
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);
|
package/dist/cli.js
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {a
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
zpm start <script> [--name <n>] [--port <p>] [--instances <i>] [--dev] [--cluster]
|
|
7
|
-
zpm stop <name>
|
|
8
|
-
zpm restart <name>
|
|
9
|
-
zpm delete <name>
|
|
10
|
-
zpm list
|
|
11
|
-
zpm stats [name]
|
|
12
|
-
zpm kill-daemon
|
|
13
|
-
`);}}d().catch(e=>{console.error("[ZPM] Error:",e.message??e),process.exit(1);});
|
|
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);
|
package/dist/daemon.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var
|
|
2
|
-
var i=p__default.default.join(m__default.default.tmpdir(),"
|
|
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);});
|
package/dist/daemon.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {d as d$2}from'./chunk-
|
|
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);});
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var
|
|
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}});
|
package/dist/index.d.cts
CHANGED
|
@@ -36,6 +36,14 @@ interface WorkerConfig {
|
|
|
36
36
|
maxBackoff?: number;
|
|
37
37
|
/** Liveness probe configuration */
|
|
38
38
|
probe?: LivenessProbeConfig;
|
|
39
|
+
/** Logs Setup */
|
|
40
|
+
logs?: {
|
|
41
|
+
/** Websocket Url to send logs
|
|
42
|
+
* e.g., "ws://localhost:4000/logs" */
|
|
43
|
+
wsUrl?: string;
|
|
44
|
+
/** Either to save logs to file or not */
|
|
45
|
+
saveToFile?: boolean;
|
|
46
|
+
};
|
|
39
47
|
}
|
|
40
48
|
interface LivenessProbeConfig {
|
|
41
49
|
/** "http" polls a URL | "tcp" opens a socket | "exec" runs a command */
|
|
@@ -81,6 +89,9 @@ type IPCCommand = {
|
|
|
81
89
|
cmd: "list";
|
|
82
90
|
} | {
|
|
83
91
|
cmd: "ping";
|
|
92
|
+
} | {
|
|
93
|
+
cmd: "logs";
|
|
94
|
+
name?: string;
|
|
84
95
|
};
|
|
85
96
|
type IPCResponse = {
|
|
86
97
|
ok: true;
|
|
@@ -103,24 +114,6 @@ interface ManagedProcess {
|
|
|
103
114
|
isRestarting: boolean;
|
|
104
115
|
}
|
|
105
116
|
|
|
106
|
-
/**
|
|
107
|
-
* process-manager.ts
|
|
108
|
-
* Top-level controller. Owns a registry of Worker instances and
|
|
109
|
-
* exposes the unified API used by both the IPC daemon and programmatic callers.
|
|
110
|
-
*/
|
|
111
|
-
|
|
112
|
-
declare class ProcessManager {
|
|
113
|
-
private workers;
|
|
114
|
-
start(config: WorkerConfig): Promise<void>;
|
|
115
|
-
stop(name: string): Promise<void>;
|
|
116
|
-
restart(name: string): Promise<void>;
|
|
117
|
-
delete(name: string): Promise<void>;
|
|
118
|
-
getStats(name?: string): Promise<WorkerStats[]>;
|
|
119
|
-
list(): string[];
|
|
120
|
-
stopAll(): Promise<void>;
|
|
121
|
-
private require;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
117
|
/**
|
|
125
118
|
* worker.ts
|
|
126
119
|
* Manages the full lifecycle of one application entry:
|
|
@@ -130,7 +123,7 @@ declare class ProcessManager {
|
|
|
130
123
|
|
|
131
124
|
declare class Worker {
|
|
132
125
|
private readonly cfg;
|
|
133
|
-
|
|
126
|
+
readonly name: string;
|
|
134
127
|
private watcher;
|
|
135
128
|
constructor(config: WorkerConfig);
|
|
136
129
|
start(): Promise<void>;
|
|
@@ -146,9 +139,29 @@ declare class Worker {
|
|
|
146
139
|
private watchFiles;
|
|
147
140
|
private stopWatcher;
|
|
148
141
|
private initStore;
|
|
149
|
-
|
|
142
|
+
mp(): ManagedProcess;
|
|
150
143
|
private patch;
|
|
151
144
|
private clearTimers;
|
|
145
|
+
private setupLogging;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* process-manager.ts
|
|
150
|
+
* Top-level controller. Owns a registry of Worker instances and
|
|
151
|
+
* exposes the unified API used by both the IPC daemon and programmatic callers.
|
|
152
|
+
*/
|
|
153
|
+
|
|
154
|
+
declare class ProcessManager {
|
|
155
|
+
private workers;
|
|
156
|
+
start(config: WorkerConfig): Promise<void>;
|
|
157
|
+
stop(name: string): Promise<void>;
|
|
158
|
+
restart(name: string): Promise<void>;
|
|
159
|
+
delete(name: string): Promise<void>;
|
|
160
|
+
getStats(name?: string): Promise<WorkerStats[]>;
|
|
161
|
+
list(): string[];
|
|
162
|
+
stopAll(): Promise<void>;
|
|
163
|
+
getWorker(name: string): Worker | null;
|
|
164
|
+
private require;
|
|
152
165
|
}
|
|
153
166
|
|
|
154
167
|
/**
|
|
@@ -166,13 +179,15 @@ declare class Worker {
|
|
|
166
179
|
|
|
167
180
|
declare class ZPMClient {
|
|
168
181
|
private readonly daemonScript;
|
|
169
|
-
|
|
182
|
+
private namespace;
|
|
183
|
+
constructor(conf?: {
|
|
184
|
+
daemonScript?: string;
|
|
185
|
+
namespace?: string;
|
|
186
|
+
});
|
|
170
187
|
/** Returns true if daemon is reachable */
|
|
171
188
|
isDaemonRunning(): Promise<boolean>;
|
|
172
189
|
/** Spawn the daemon detached if it is not already running */
|
|
173
|
-
ensureDaemon(
|
|
174
|
-
devMode?: boolean;
|
|
175
|
-
}): Promise<void>;
|
|
190
|
+
ensureDaemon(): Promise<void>;
|
|
176
191
|
/** Kill the daemon by PID */
|
|
177
192
|
killDaemon(): Promise<void>;
|
|
178
193
|
start(config: WorkerConfig): Promise<string>;
|
|
@@ -191,7 +206,7 @@ declare const zpm: ZPMClient;
|
|
|
191
206
|
* Each message is a newline-delimited JSON string.
|
|
192
207
|
*/
|
|
193
208
|
|
|
194
|
-
declare function getSocketPath(): string;
|
|
209
|
+
declare function getSocketPath(namespace?: string): string;
|
|
195
210
|
|
|
196
211
|
declare const logger: {
|
|
197
212
|
info: (tag: string, ...a: unknown[]) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,14 @@ interface WorkerConfig {
|
|
|
36
36
|
maxBackoff?: number;
|
|
37
37
|
/** Liveness probe configuration */
|
|
38
38
|
probe?: LivenessProbeConfig;
|
|
39
|
+
/** Logs Setup */
|
|
40
|
+
logs?: {
|
|
41
|
+
/** Websocket Url to send logs
|
|
42
|
+
* e.g., "ws://localhost:4000/logs" */
|
|
43
|
+
wsUrl?: string;
|
|
44
|
+
/** Either to save logs to file or not */
|
|
45
|
+
saveToFile?: boolean;
|
|
46
|
+
};
|
|
39
47
|
}
|
|
40
48
|
interface LivenessProbeConfig {
|
|
41
49
|
/** "http" polls a URL | "tcp" opens a socket | "exec" runs a command */
|
|
@@ -81,6 +89,9 @@ type IPCCommand = {
|
|
|
81
89
|
cmd: "list";
|
|
82
90
|
} | {
|
|
83
91
|
cmd: "ping";
|
|
92
|
+
} | {
|
|
93
|
+
cmd: "logs";
|
|
94
|
+
name?: string;
|
|
84
95
|
};
|
|
85
96
|
type IPCResponse = {
|
|
86
97
|
ok: true;
|
|
@@ -103,24 +114,6 @@ interface ManagedProcess {
|
|
|
103
114
|
isRestarting: boolean;
|
|
104
115
|
}
|
|
105
116
|
|
|
106
|
-
/**
|
|
107
|
-
* process-manager.ts
|
|
108
|
-
* Top-level controller. Owns a registry of Worker instances and
|
|
109
|
-
* exposes the unified API used by both the IPC daemon and programmatic callers.
|
|
110
|
-
*/
|
|
111
|
-
|
|
112
|
-
declare class ProcessManager {
|
|
113
|
-
private workers;
|
|
114
|
-
start(config: WorkerConfig): Promise<void>;
|
|
115
|
-
stop(name: string): Promise<void>;
|
|
116
|
-
restart(name: string): Promise<void>;
|
|
117
|
-
delete(name: string): Promise<void>;
|
|
118
|
-
getStats(name?: string): Promise<WorkerStats[]>;
|
|
119
|
-
list(): string[];
|
|
120
|
-
stopAll(): Promise<void>;
|
|
121
|
-
private require;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
117
|
/**
|
|
125
118
|
* worker.ts
|
|
126
119
|
* Manages the full lifecycle of one application entry:
|
|
@@ -130,7 +123,7 @@ declare class ProcessManager {
|
|
|
130
123
|
|
|
131
124
|
declare class Worker {
|
|
132
125
|
private readonly cfg;
|
|
133
|
-
|
|
126
|
+
readonly name: string;
|
|
134
127
|
private watcher;
|
|
135
128
|
constructor(config: WorkerConfig);
|
|
136
129
|
start(): Promise<void>;
|
|
@@ -146,9 +139,29 @@ declare class Worker {
|
|
|
146
139
|
private watchFiles;
|
|
147
140
|
private stopWatcher;
|
|
148
141
|
private initStore;
|
|
149
|
-
|
|
142
|
+
mp(): ManagedProcess;
|
|
150
143
|
private patch;
|
|
151
144
|
private clearTimers;
|
|
145
|
+
private setupLogging;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* process-manager.ts
|
|
150
|
+
* Top-level controller. Owns a registry of Worker instances and
|
|
151
|
+
* exposes the unified API used by both the IPC daemon and programmatic callers.
|
|
152
|
+
*/
|
|
153
|
+
|
|
154
|
+
declare class ProcessManager {
|
|
155
|
+
private workers;
|
|
156
|
+
start(config: WorkerConfig): Promise<void>;
|
|
157
|
+
stop(name: string): Promise<void>;
|
|
158
|
+
restart(name: string): Promise<void>;
|
|
159
|
+
delete(name: string): Promise<void>;
|
|
160
|
+
getStats(name?: string): Promise<WorkerStats[]>;
|
|
161
|
+
list(): string[];
|
|
162
|
+
stopAll(): Promise<void>;
|
|
163
|
+
getWorker(name: string): Worker | null;
|
|
164
|
+
private require;
|
|
152
165
|
}
|
|
153
166
|
|
|
154
167
|
/**
|
|
@@ -166,13 +179,15 @@ declare class Worker {
|
|
|
166
179
|
|
|
167
180
|
declare class ZPMClient {
|
|
168
181
|
private readonly daemonScript;
|
|
169
|
-
|
|
182
|
+
private namespace;
|
|
183
|
+
constructor(conf?: {
|
|
184
|
+
daemonScript?: string;
|
|
185
|
+
namespace?: string;
|
|
186
|
+
});
|
|
170
187
|
/** Returns true if daemon is reachable */
|
|
171
188
|
isDaemonRunning(): Promise<boolean>;
|
|
172
189
|
/** Spawn the daemon detached if it is not already running */
|
|
173
|
-
ensureDaemon(
|
|
174
|
-
devMode?: boolean;
|
|
175
|
-
}): Promise<void>;
|
|
190
|
+
ensureDaemon(): Promise<void>;
|
|
176
191
|
/** Kill the daemon by PID */
|
|
177
192
|
killDaemon(): Promise<void>;
|
|
178
193
|
start(config: WorkerConfig): Promise<string>;
|
|
@@ -191,7 +206,7 @@ declare const zpm: ZPMClient;
|
|
|
191
206
|
* Each message is a newline-delimited JSON string.
|
|
192
207
|
*/
|
|
193
208
|
|
|
194
|
-
declare function getSocketPath(): string;
|
|
209
|
+
declare function getSocketPath(namespace?: string): string;
|
|
195
210
|
|
|
196
211
|
declare const logger: {
|
|
197
212
|
info: (tag: string, ...a: unknown[]) => void;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{a as ZPMClient,b as zpm}from'./chunk-
|
|
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';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zuzjs/pm",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"core",
|
|
6
6
|
"zuz",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"reflect-metadata"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
+
"@types/ws": "^8.18.1",
|
|
39
40
|
"chokidar": "^5.0.0",
|
|
40
41
|
"commander": "^14.0.3",
|
|
41
42
|
"date-fns": "^4.1.0",
|
|
@@ -43,6 +44,7 @@
|
|
|
43
44
|
"moment": "^2.30.1",
|
|
44
45
|
"nanoid": "^5.1.6",
|
|
45
46
|
"picocolors": "^1.1.1",
|
|
46
|
-
"pidusage": "^4.0.1"
|
|
47
|
+
"pidusage": "^4.0.1",
|
|
48
|
+
"ws": "^8.19.0"
|
|
47
49
|
}
|
|
48
50
|
}
|
package/dist/chunk-5RMT5B2R.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import f from'path';import {fileURLToPath}from'url';import I from'net';import l from'os';import d from'fs';var k=()=>fileURLToPath(import.meta.url),S=()=>f.dirname(k()),c=S();var w=(o=>(o.Fork="fork",o.Cluster="cluster",o))(w||{}),P=(s=>(s.Stopped="stopped",s.Starting="starting",s.Running="running",s.Stopping="stopping",s.Crashed="crashed",s.Errored="errored",s))(P||{});var x={info:"\x1B[36m",warn:"\x1B[33m",error:"\x1B[31m",debug:"\x1B[90m",success:"\x1B[32m"},h="\x1B[0m",v="\x1B[1m";function y(){return new Date().toISOString()}function i(e,r,...o){let n=x[e],t=`${v}${n}[ZPM/${r.toUpperCase()}]${h} ${y()}`;console[e==="success"?"log":e](`${t} \u2192`,...o);}var a={info:(e,...r)=>i("info",e,...r),warn:(e,...r)=>i("warn",e,...r),error:(e,...r)=>i("error",e,...r),debug:(e,...r)=>i("debug",e,...r),success:(e,...r)=>i("success",e,...r)};function L(){return l.platform()==="win32"?f.join("\\\\.\\pipe","zuzjs-pm"):f.join(l.tmpdir(),"zuzjs-pm.sock")}function U(e){let r=L();d.existsSync(r)&&d.unlinkSync(r);let o=I.createServer(n=>{let t="";n.on("data",m=>{t+=m.toString();let s=t.split(`
|
|
2
|
-
`);t=s.pop()??"";for(let g of s)g.trim()&&R(e,n,g);}),n.on("error",m=>{a.error("IPC","Socket error:",m.message);});});return o.listen(r,()=>{a.success("IPC",`Listening on ${r}`);}),o.on("error",n=>{a.error("IPC","Server error:",n);}),o}async function R(e,r,o){let n;try{n=JSON.parse(o);}catch{u(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;default:throw new Error(`Unknown command: ${n.cmd}`)}u(r,{ok:!0,data:t});}catch(t){u(r,{ok:false,error:String(t.message??t)});}}function u(e,r){e.writable&&e.write(JSON.stringify(r)+`
|
|
3
|
-
`);}export{c as a,w as b,P as c,a as d,L as e,U as f};
|
package/dist/chunk-BBXSSJFF.cjs
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
'use strict';var chunkLM53EFPZ_cjs=require('./chunk-LM53EFPZ.cjs'),child_process=require('child_process'),l=require('fs'),f=require('net'),h=require('os'),g=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var l__default=/*#__PURE__*/_interopDefault(l);var f__default=/*#__PURE__*/_interopDefault(f);var h__default=/*#__PURE__*/_interopDefault(h);var g__default=/*#__PURE__*/_interopDefault(g);/* ZuzJS Process Manager */
|
|
2
|
-
function o(u){return new Promise((r,t)=>{let n=f__default.default.createConnection(chunkLM53EFPZ_cjs.d()),e="";n.on("connect",()=>{n.write(JSON.stringify(u)+`
|
|
3
|
-
`);}),n.on("data",i=>{e+=i.toString();let s=e.split(`
|
|
4
|
-
`);e=s.pop()??"";for(let m of s)if(m.trim())try{let a=JSON.parse(m);n.destroy(),a.ok?r(a.data):t(new Error(a.error));}catch(a){n.destroy(),t(a);}}),n.on("error",i=>t(i)),n.setTimeout(1e4,()=>{n.destroy(),t(new Error("IPC timeout"));});})}var d=class{daemonScript;constructor(r){this.daemonScript=r??g__default.default.join(__dirname,"daemon.js");}async isDaemonRunning(){try{return chunkLM53EFPZ_cjs.c.info("[ZPM]","Daemon is Running :?"),await o({cmd:"ping"}),!0}catch{return chunkLM53EFPZ_cjs.c.info("[ZPM]","Daemon is not running."),false}}async ensureDaemon(r){if(await this.isDaemonRunning())return;chunkLM53EFPZ_cjs.c.info("Starting ZPM daemon...");let n=r?.devMode??process.env.NODE_ENV!=="production";child_process.spawn(process.execPath,[this.daemonScript],{detached:true,stdio:n?"inherit":"ignore"}).unref(),await this.waitForDaemon(8e3);}async killDaemon(){let r=g__default.default.join(h__default.default.tmpdir(),"zuzjs-pm.pid");if(!l__default.default.existsSync(r))throw new Error("Daemon PID file not found \u2013 is the daemon running?");let t=Number(l__default.default.readFileSync(r,"utf8").trim());try{process.kill(t,"SIGTERM"),console.log(`[ZPM] Sent SIGTERM to daemon (PID ${t})`);}catch(n){throw new Error(`Failed to kill daemon: ${n.message}`)}}async start(r){return o({cmd:"start",name:r.name,config:r})}async stop(r){return o({cmd:"stop",name:r})}async restart(r){return o({cmd:"restart",name:r})}async delete(r){return o({cmd:"delete",name:r})}async stats(r){return o({cmd:"stats",name:r})}async list(){return o({cmd:"list"})}waitForDaemon(r){let t=Date.now(),n=200;return new Promise((e,i)=>{let s=()=>{this.isDaemonRunning().then(m=>{if(m)return e();if(Date.now()-t>r)return i(new Error("Daemon did not start in time"));setTimeout(s,n);});};setTimeout(s,n);})}},R=new d;exports.a=d;exports.b=R;
|
package/dist/chunk-IIKD4V5E.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import {d as d$1}from'./chunk-5RMT5B2R.js';import T from'events';import {spawn,exec}from'child_process';import y from'http';import S from'https';import C from'net';import M from'chokidar';import R from'fs';import _ from'os';import g from'path';import A from'pidusage';var m=class extends T{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")?S:y).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.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 x(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 W(s.target,t);case "tcp":return F(s.target,t);case "exec":return x(s.target,t);default:return false}}var w=5e3,E=16e3,b=1e3,D=5e3;async function q(s){return new Promise(t=>{C.createServer().once("error",()=>t(false)).once("listening",function(){this.close(()=>t(true));}).listen(s);})}async function N(s){await q(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 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"){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)k(e,this.cfg.killTimeout??w);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)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 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(!R.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 N(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:b,restartCount:0}),d$1.success(this.name,"Process is stable."));},D);this.patch({stabilityTimer:o}),this.cfg.probe&&this.startProbe();}forkChild(){try{let t=spawn("node",[this.cfg.scriptPath,...this.cfg.args??[]],{stdio:"inherit",env:{...process.env,...this.cfg.env??{},NODE_ENV:this.cfg.devMode?"development":"production"},detached:!1,shell:!1}),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??E;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=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}: ${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: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});}};var P=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.");}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,P as d};
|
package/dist/chunk-J6AZRPZZ.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import {a,d,e}from'./chunk-5RMT5B2R.js';import {spawn}from'child_process';import g from'fs';import h from'net';import w from'os';import P from'path';function o(d){return new Promise((r,t)=>{let n=h.createConnection(e()),e$1="";n.on("connect",()=>{n.write(JSON.stringify(d)+`
|
|
2
|
-
`);}),n.on("data",i=>{e$1+=i.toString();let s=e$1.split(`
|
|
3
|
-
`);e$1=s.pop()??"";for(let m of s)if(m.trim())try{let a=JSON.parse(m);n.destroy(),a.ok?r(a.data):t(new Error(a.error));}catch(a){n.destroy(),t(a);}}),n.on("error",i=>t(i)),n.setTimeout(1e4,()=>{n.destroy(),t(new Error("IPC timeout"));});})}var u=class{daemonScript;constructor(r){this.daemonScript=r??P.join(a,"daemon.js");}async isDaemonRunning(){try{return d.info("[ZPM]","Daemon is Running :?"),await o({cmd:"ping"}),!0}catch{return d.info("[ZPM]","Daemon is not running."),false}}async ensureDaemon(r){if(await this.isDaemonRunning())return;d.info("Starting ZPM daemon...");let n=r?.devMode??process.env.NODE_ENV!=="production";spawn(process.execPath,[this.daemonScript],{detached:true,stdio:n?"inherit":"ignore"}).unref(),await this.waitForDaemon(8e3);}async killDaemon(){let r=P.join(w.tmpdir(),"zuzjs-pm.pid");if(!g.existsSync(r))throw new Error("Daemon PID file not found \u2013 is the daemon running?");let t=Number(g.readFileSync(r,"utf8").trim());try{process.kill(t,"SIGTERM"),console.log(`[ZPM] Sent SIGTERM to daemon (PID ${t})`);}catch(n){throw new Error(`Failed to kill daemon: ${n.message}`)}}async start(r){return o({cmd:"start",name:r.name,config:r})}async stop(r){return o({cmd:"stop",name:r})}async restart(r){return o({cmd:"restart",name:r})}async delete(r){return o({cmd:"delete",name:r})}async stats(r){return o({cmd:"stats",name:r})}async list(){return o({cmd:"list"})}waitForDaemon(r){let t=Date.now(),n=200;return new Promise((e,i)=>{let s=()=>{this.isDaemonRunning().then(m=>{if(m)return e();if(Date.now()-t>r)return i(new Error("Daemon did not start in time"));setTimeout(s,n);});};setTimeout(s,n);})}},C=new u;export{u as a,C as b};
|
package/dist/chunk-LM53EFPZ.cjs
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
'use strict';var P=require('net'),p=require('os'),l=require('fs'),d=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var P__default=/*#__PURE__*/_interopDefault(P);var p__default=/*#__PURE__*/_interopDefault(p);var l__default=/*#__PURE__*/_interopDefault(l);var d__default=/*#__PURE__*/_interopDefault(d);/* ZuzJS Process Manager */
|
|
2
|
-
var f=(o=>(o.Fork="fork",o.Cluster="cluster",o))(f||{}),b=(s=>(s.Stopped="stopped",s.Starting="starting",s.Running="running",s.Stopping="stopping",s.Crashed="crashed",s.Errored="errored",s))(b||{});var C={info:"\x1B[36m",warn:"\x1B[33m",error:"\x1B[31m",debug:"\x1B[90m",success:"\x1B[32m"},k="\x1B[0m",S="\x1B[1m";function w(){return new Date().toISOString()}function i(e,r,...o){let n=C[e],t=`${S}${n}[ZPM/${r.toUpperCase()}]${k} ${w()}`;console[e==="success"?"log":e](`${t} \u2192`,...o);}var a={info:(e,...r)=>i("info",e,...r),warn:(e,...r)=>i("warn",e,...r),error:(e,...r)=>i("error",e,...r),debug:(e,...r)=>i("debug",e,...r),success:(e,...r)=>i("success",e,...r)};function x(){return p__default.default.platform()==="win32"?d__default.default.join("\\\\.\\pipe","zuzjs-pm"):d__default.default.join(p__default.default.tmpdir(),"zuzjs-pm.sock")}function J(e){let r=x();l__default.default.existsSync(r)&&l__default.default.unlinkSync(r);let o=P__default.default.createServer(n=>{let t="";n.on("data",m=>{t+=m.toString();let s=t.split(`
|
|
3
|
-
`);t=s.pop()??"";for(let u of s)u.trim()&&h(e,n,u);}),n.on("error",m=>{a.error("IPC","Socket error:",m.message);});});return o.listen(r,()=>{a.success("IPC",`Listening on ${r}`);}),o.on("error",n=>{a.error("IPC","Server error:",n);}),o}async function h(e,r,o){let n;try{n=JSON.parse(o);}catch{c(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;default:throw new Error(`Unknown command: ${n.cmd}`)}c(r,{ok:!0,data:t});}catch(t){c(r,{ok:false,error:String(t.message??t)});}}function c(e,r){e.writable&&e.write(JSON.stringify(r)+`
|
|
4
|
-
`);}exports.a=f;exports.b=b;exports.c=a;exports.d=x;exports.e=J;
|
package/dist/chunk-RDE2YGL7.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
'use strict';var chunkLM53EFPZ_cjs=require('./chunk-LM53EFPZ.cjs'),P=require('events'),child_process=require('child_process'),v=require('http'),y=require('https'),S=require('net'),x=require('chokidar'),I=require('fs'),L=require('os'),d=require('path'),_=require('pidusage');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var P__default=/*#__PURE__*/_interopDefault(P);var v__default=/*#__PURE__*/_interopDefault(v);var y__default=/*#__PURE__*/_interopDefault(y);var S__default=/*#__PURE__*/_interopDefault(S);var x__default=/*#__PURE__*/_interopDefault(x);var I__default=/*#__PURE__*/_interopDefault(I);var L__default=/*#__PURE__*/_interopDefault(L);var d__default=/*#__PURE__*/_interopDefault(d);var ___default=/*#__PURE__*/_interopDefault(_);/* ZuzJS Process Manager */
|
|
2
|
-
var m=class extends P__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 C(s,t){return new Promise(e=>{let o=(s.startsWith("https")?y__default.default:v__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 W(s,t){let[e,r]=s.split(":"),o=Number(r);return new Promise(n=>{let a=S__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 F(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 C(s.target,t);case "tcp":return W(s.target,t);case "exec":return F(s.target,t);default:return false}}var g=5e3,A=16e3,w=1e3,E=5e3;async function D(s){return new Promise(t=>{S__default.default.createServer().once("error",()=>t(false)).once("listening",function(){this.close(()=>t(true));}).listen(s);})}async function q(s){await D(s)||(chunkLM53EFPZ_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 b(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"){chunkLM53EFPZ_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)b(e,this.cfg.killTimeout??g);this.stopWatcher(),this.patch({children:[],status:"stopped",startTime:null}),chunkLM53EFPZ_cjs.c.info(this.name,"Stopped.");}async restart(){chunkLM53EFPZ_cjs.c.info(this.name,"Restarting...");let t=this.mp();this.patch({isRestarting:true}),this.clearTimers(),this.stopProbe();for(let e of t.children)b(e,this.cfg.killTimeout??g);}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(!I__default.default.existsSync(this.cfg.scriptPath)){chunkLM53EFPZ_cjs.c.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??L__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"}),chunkLM53EFPZ_cjs.c.success(this.name,`Started ${r.length} instance(s) [${t}]`);let o=setTimeout(()=>{this.mp().status==="running"&&(this.patch({backoffTime:w,restartCount:0}),chunkLM53EFPZ_cjs.c.success(this.name,"Process is stable."));},E);this.patch({stabilityTimer:o}),this.cfg.probe&&this.startProbe();}forkChild(){try{let t=child_process.spawn("node",[this.cfg.scriptPath,...this.cfg.args??[]],{stdio:"inherit",env:{...process.env,...this.cfg.env??{},NODE_ENV:this.cfg.devMode?"development":"production"},detached:!1,shell:!1}),e=Date.now();return t.on("error",r=>{chunkLM53EFPZ_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 chunkLM53EFPZ_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(chunkLM53EFPZ_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){chunkLM53EFPZ_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;chunkLM53EFPZ_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}),chunkLM53EFPZ_cjs.c.warn(this.name,`Liveness probe failed (${h}/${r})`),h>=r&&(chunkLM53EFPZ_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=x__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")&&(chunkLM53EFPZ_cjs.c.info(this.name,`File ${e}: ${d__default.default.basename(r)} \u2013 restarting`),this.restart());}),this.watcher.on("error",e=>chunkLM53EFPZ_cjs.c.error(this.name,"Watcher error:",e)),this.watcher.on("ready",()=>chunkLM53EFPZ_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:w,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});}};var k=class{workers=new Map;async start(t){if(this.workers.has(t.name)){chunkLM53EFPZ_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),chunkLM53EFPZ_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(){chunkLM53EFPZ_cjs.c.info("PM","Stopping all workers..."),await Promise.all([...this.workers.values()].map(t=>t.stop())),chunkLM53EFPZ_cjs.c.info("PM","All workers stopped.");}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=k;
|