@zuzjs/pm 0.0.23 → 0.0.24
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-T65SM3EP.js → chunk-ALFXH7VX.js} +2 -2
- package/dist/{chunk-IYE76WJZ.cjs → chunk-ZOQDQOTG.cjs} +3 -3
- package/dist/daemon.cjs +2 -2
- package/dist/daemon.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {d as d$1,e}from'./chunk-FXEDN7ZZ.js';import {spawn,exec}from'child_process';import
|
|
2
|
-
${l||h||n.message}`);return}d$1.success(this.name,"Build successful. Triggering restart..."),this.restart();});}else this.restart();}),this.watcher.on("error",
|
|
1
|
+
import {d as d$1,e}from'./chunk-FXEDN7ZZ.js';import {spawn,exec}from'child_process';import E from'http';import R from'https';import _ from'net';import L from'chokidar';import u from'fs';import T from'os';import c from'path';import f from'picocolors';import k from'ws';import B from'pidusage';function I(a,t){return new Promise(e=>{let i=(a.startsWith("https")?R:E).get(a,{timeout:t},o=>{e((o.statusCode??500)<500);});i.on("error",()=>e(false)),i.on("timeout",()=>{i.destroy(),e(false);});})}function M(a,t){let[e,s]=a.split(":"),i=Number(s);return new Promise(o=>{let n=_.createConnection({host:e,port:i},()=>{n.destroy(),o(true);});n.setTimeout(t),n.on("timeout",()=>{n.destroy(),o(false);}),n.on("error",()=>o(false));})}function N(a,t){return new Promise(e=>{let s=setTimeout(()=>e(false),t);exec(a,i=>{clearTimeout(s),e(!i);});})}async function b(a){let t=(a.timeoutSeconds??5)*1e3;switch(a.type){case "http":return I(a.target,t);case "tcp":return M(a.target,t);case "exec":return N(a.target,t);default:return false}}var S=5e3,j=16e3,d=1e3,H=5e3;async function q(a){return new Promise(t=>{_.createServer().once("error",()=>t(false)).once("listening",function(){this.close(()=>t(true));}).listen(a);})}async function K(a){if(await q(a))return;let t=T.platform()==="darwin"?`lsof -ti :${a} | xargs kill -9 2>/dev/null || true`:`fuser -k -9 ${a}/tcp 2>/dev/null; true`;await new Promise(e=>exec(t,()=>e())),await new Promise(e=>setTimeout(e,800));}async function y(a,t){let e=a.process?.pid??a.pid;if(e)return new Promise(s=>{let i=false,o=()=>{i||(i=true,clearTimeout(n),s());};a.once?.("exit",o),a.once?.("exit",o);try{process.kill(e,"SIGTERM");}catch{return o()}let n=setTimeout(()=>{try{process.kill(e,"SIGKILL"),setTimeout(o,100);}catch{o();}},t),h=setInterval(()=>{try{process.kill(e,0);}catch{clearInterval(h),o();}},500);})}var p=class{cfg;name;watcher=null;isBuilding=false;constructor(t){this.cfg={mode:"fork",instances:1,...t},this.name=t.name,this.initStore();}getConfig(){return this.cfg}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",isRestarting:false,children:[],restartCount:0,backoffTime:d,probeFailures:0,startTime:null}),this.clearTimers(),this.stopProbe(),d$1.info(this.name,"Initializing fresh start...");try{await this.spawnAll(),this.cfg.devMode&&this.watchFiles();}catch(e){this.patch({status:"errored"}),d$1.error(this.name,`Start failed: ${e.message}`);}}async stop(){let t=this.mp();if(t.status==="stopping"){d$1.info(this.name,"Already stopping...");return}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=>y(e,this.cfg.killTimeout??S))),new Promise((e,s)=>setTimeout(()=>s(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 restart(){let t=this.mp();t.isRestarting||(d$1.info(this.name,"Restarting.."),this.patch({isRestarting:true,status:"starting"}),this.clearTimers(),this.stopProbe(),await Promise.all(t.children.map(e=>y(e,this.cfg.killTimeout??S))));}async getStats(){let t=this.mp(),e=t.children[0]?.pid??null,s=null,i=null,o=null;if(e&&t.status==="running")try{let n=await B(e);s=n.cpu,i=n.memory;}catch{}return {name:this.name,status:t.status,pid:e,uptime:t.startTime?Date.now()-t.startTime:null,restartCount:t.restartCount,cpu:s,memoryRss:i,memoryHeap:o,mode:this.cfg.mode??"fork",instances:t.children.length}}async spawnAll(){if(!u.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 K(this.cfg.port);let t=this.cfg.mode??"fork",e=t==="cluster"?this.cfg.instances??T.cpus().length:1,s=[];for(let o=0;o<e;o++){let n=this.forkChild();n&&s.push(n);}if(s.length===0){d$1.error(this.name,"Failed to spawn any instances."),this.patch({status:"stopped"});return}this.patch({children:s,startTime:Date.now(),status:"running"}),d$1.success(this.name,`Started ${s.length} instance(s) [${t}]`);let i=setTimeout(()=>{this.mp().status==="running"&&(this.patch({backoffTime:d,restartCount:0}),d$1.success(this.name,"Process is stable."));},H);this.patch({stabilityTimer:i}),this.cfg.probe&&this.startProbe();}forkChild(){try{let t=this.cfg.scriptPath.endsWith(".js"),e=c.isAbsolute(this.cfg.scriptPath),s,i,o;t?(s=process.execPath,i=[this.cfg.scriptPath,...this.cfg.args??[]],o=c.dirname(c.resolve(this.cfg.scriptPath,".."))):(s=this.cfg.scriptPath,i=[...this.cfg.args??[]],o=e?c.dirname(this.cfg.scriptPath):process.cwd());let n=spawn(s,i,{cwd:o,stdio:["ignore","pipe","pipe"],env:{...process.env,...this.cfg.env??{},NODE_ENV:this.cfg.devMode?"development":"production",PATH:`${c.resolve(process.cwd(),"node_modules/.bin")}${c.delimiter}${process.env.PATH}`},detached:!1,shell:!t});this.setupLogging(n);let h=Date.now();return n.on("error",l=>{d$1.error(this.name,`Spawn error (${s}):`,l.message);}),n.on("exit",(l,F)=>{let x=Date.now()-h;this.onChildExit(n,l,F,x);}),n}catch(t){return d$1.error(this.name,"Failed to fork child:",t.message),null}}_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??[]],s=spawn(t,e,{cwd:c.dirname(c.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(s);let i=Date.now();return s.on("error",o=>{d$1.error(this.name,"Spawn error:",o);}),s.on("exit",(o,n)=>{let h=Date.now()-i;this.onChildExit(s,o,n,h);}),s}catch(t){return d$1.error(this.name,"Failed to fork child:",t),null}}onChildExit(t,e,s,i){let o=this.mp(),n=o.children.filter(h=>h!==t);if(this.patch({children:n}),o.isRestarting){n.length===0?(d$1.info(this.name,"All instances stopped. Spawning new ones..."),this.patch({isRestarting:false}),this.spawnAll()):d$1.info(this.name,`Restart in progress... waiting for ${n.length} instance(s) to stop.`);return}if(o.status==="stopping"){n.length===0?(d$1.info(this.name,"All instances dead. Spawning new ones..."),this.patch({isRestarting:false}),this.spawnAll()):d$1.info(this.name,`Stop in progress... waiting for ${n.length} instance(s) to stop.`);return}d$1.warn(this.name,`Process exited (code=${e}, signal=${s}, uptime=${i}ms)`),e!==0&&e!==null&&(this.patch({status:"crashed"}),i<1500&&d$1.error(this.name,`Immediate crash (${i}ms) \u2013 likely a syntax/build error. Waiting for next file change.`),this.scheduleRestart());}scheduleRestart(){let t=this.mp(),e=t.backoffTime,s=this.cfg.maxBackoff??j;d$1.warn(this.name,`Scheduling restart in ${e}ms (attempt #${t.restartCount+1})`);let i=setTimeout(async()=>{this.patch({restartCount:t.restartCount+1,backoffTime:Math.min(e*2,s)}),await this.spawnAll();},e);this.patch({restartTimer:i});}startProbe(){let t=this.cfg.probe,e=(t.intervalSeconds??10)*1e3,s=t.failureThreshold??3,o=setInterval(async()=>{let n=this.mp();if(n.status!=="running")return;if(await b(t)){n.probeFailures>0&&this.patch({probeFailures:0});return}let l=n.probeFailures+1;this.patch({probeFailures:l}),d$1.warn(this.name,`Liveness probe failed (${l}/${s})`),l>=s&&(d$1.error(this.name,"Liveness probe threshold exceeded \u2013 restarting."),this.patch({probeFailures:0}),await this.restart());},e);this.patch({probeTimer:o});}stopProbe(){let{probeTimer:t}=this.mp();t&&(clearInterval(t),this.patch({probeTimer:null,probeFailures:0}));}findProjectRoot(t){let e=c.resolve(t);for(u.existsSync(e)&&u.statSync(e).isFile()&&(e=c.dirname(e));e!==c.parse(e).root;){if(u.existsSync(c.join(e,"package.json")))return e;e=c.dirname(e);}return process.cwd()}watchFiles(){this.stopWatcher();let t=this.findProjectRoot(this.cfg.scriptPath),e=c.resolve(t,"src");d$1.info(this.name,f.gray(`Watcher active on: ${e}`)),this.watcher=L.watch(e,{ignored:[/node_modules/,/\.pid$/],persistent:true,ignoreInitial:true,awaitWriteFinish:{stabilityThreshold:1500,pollInterval:500}}),this.watcher.on("all",async(s,i)=>{if(!this.isBuilding&&(s==="change"||s==="add"))if(d$1.info(this.name,f.yellow(`File ${s}: ${c.basename(i)} \u2013 restarting`)),this.cfg.reloadCommand){this.isBuilding=true,d$1.info(this.name,f.blue(`Executing: ${this.cfg.reloadCommand}`));let{exec:o}=await import('child_process');o(this.cfg.reloadCommand,{cwd:t,env:{...process.env,PATH:`${c.resolve(t,"node_modules/.bin")}${c.delimiter}${process.env.PATH}`}},(n,h,l)=>{if(this.isBuilding=false,n){d$1.error(this.name,`Build Failed:
|
|
2
|
+
${l||h||n.message}`);return}d$1.success(this.name,"Build successful. Triggering restart..."),this.restart();});}else this.restart();}),this.watcher.on("error",s=>d$1.error(this.name,"Watcher error:",s)),this.watcher.on("ready",()=>d$1.info(this.name,`Watching ${t}`));}stopWatcher(){this.watcher&&(this.watcher.close(),this.watcher=null);}initStore(){e.set(this.name,{config:this.cfg,children:[],status:"stopped",startTime:null,restartCount:0,backoffTime:d,restartTimer:null,stabilityTimer:null,probeTimer:null,probeFailures:0,isRestarting:false});}mp(){return e.get(this.name)}_patch(t){e.set(this.name,{...this.mp(),...t});}patch(t){let e$1=this.mp();t.status&&t.status!==e$1.status&&d$1.info(this.name,`[STATE] ${e$1.status} \u2794 ${t.status}${t.isRestarting?" (Restarting)":""}`),t.lastError&&d$1.error(this.name,`[REASON] ${t.lastError}`),e.set(this.name,{...e$1,...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,s=null;e&&(s=new k(e),s.on("open",()=>d$1.debug(this.name,"Connected to log collector")),s.on("error",o=>d$1.error(this.name,"Log Collector WS Error",o.message)));let i=o=>{let n=o.toString();this.cfg.devMode&&process.stdout.write(`[${this.name}] ${n}`),s&&s.readyState===k.OPEN&&s.send(JSON.stringify({app:this.name,timestamp:Date.now(),log:n}));};t.stdout?.on("data",i),t.stderr?.on("data",i);}};var $=class{workers=new Map;SNAPSHOT_FILE=c.join(T.homedir(),".zpm","snapshot.json");async start(t){let e$1=this.workers.get(t.name);if(e$1){let i=e.get(t.name);if(i?.status==="stopped"||i?.status==="crashed"||i?.status==="errored"){d$1.info("ZPM",`Resuming existing worker "${t.name}"`),await e$1.start();return}d$1.warn("ZPM",`Worker "${f.cyan(t.name)}" is ${f.cyan(i?.status)} - use restart()`);return}let s=new p(t);this.workers.set(t.name,s),await s.start(),this.saveSnapshot();}async stop(t){let e=this.require(t);e&&(await e.stop(),this.saveSnapshot());}async restart(t){let e=this.require(t);e&&(await e.restart(),this.saveSnapshot());}async delete(t){let e$1=this.require(t);e$1&&(await e$1.stop(),this.workers.delete(t),e.delete(t),this.saveSnapshot(),d$1.info("PM",`Deleted worker "${t}"`));}async getStats(t){if(t){let s=this.require(t);return s?[await s.getStats()]:[]}return await Promise.all([...this.workers.values()].map(s=>s.getStats()))}list(){return [...this.workers.keys()]}getAllConfigs(){return Array.from(this.workers.values()).map(t=>t.getConfig())}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."),this.saveSnapshot();}getWorker(t){let e=this.workers.get(t);return e||(d$1.error(t,"Worker Not Found"),null)}async addWorker(t,e){let s=new p(t);this.workers.set(t.name,s),e&&await s.start(),this.saveSnapshot();}require(t){let e=this.workers.get(t);return e||(d$1.error(t,"Worker Not Found"),null)}saveSnapshot(){try{let t=c.dirname(this.SNAPSHOT_FILE);u.existsSync(t)||u.mkdirSync(t,{recursive:!0});let e=this.getAllConfigs();u.writeFileSync(this.SNAPSHOT_FILE,JSON.stringify(e,null,2)),d$1.info("daemon",`Saved snapshot of ${e.length} workers.`);}catch(t){d$1.error("daemon","Failed to save snapshot:",t.message);}}};export{b as a,p as b,$ as c};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var chunkWPWZGJN5_cjs=require('./chunk-WPWZGJN5.cjs'),child_process=require('child_process'),
|
|
2
|
-
function
|
|
3
|
-
${l||h||n.message}`);return}chunkWPWZGJN5_cjs.d.success(this.name,"Build successful. Triggering restart..."),this.restart();});}else this.restart();}),this.watcher.on("error",
|
|
1
|
+
'use strict';var chunkWPWZGJN5_cjs=require('./chunk-WPWZGJN5.cjs'),child_process=require('child_process'),A=require('http'),E=require('https'),R=require('net'),N=require('chokidar'),u=require('fs'),y=require('os'),c=require('path'),f=require('picocolors'),v=require('ws'),O=require('pidusage');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var A__default=/*#__PURE__*/_interopDefault(A);var E__default=/*#__PURE__*/_interopDefault(E);var R__default=/*#__PURE__*/_interopDefault(R);var N__default=/*#__PURE__*/_interopDefault(N);var u__default=/*#__PURE__*/_interopDefault(u);var y__default=/*#__PURE__*/_interopDefault(y);var c__default=/*#__PURE__*/_interopDefault(c);var f__default=/*#__PURE__*/_interopDefault(f);var v__default=/*#__PURE__*/_interopDefault(v);var O__default=/*#__PURE__*/_interopDefault(O);/* ZuzJS Process Manager */
|
|
2
|
+
function _(a,t){return new Promise(e=>{let i=(a.startsWith("https")?E__default.default:A__default.default).get(a,{timeout:t},o=>{e((o.statusCode??500)<500);});i.on("error",()=>e(false)),i.on("timeout",()=>{i.destroy(),e(false);});})}function I(a,t){let[e,s]=a.split(":"),i=Number(s);return new Promise(o=>{let n=R__default.default.createConnection({host:e,port:i},()=>{n.destroy(),o(true);});n.setTimeout(t),n.on("timeout",()=>{n.destroy(),o(false);}),n.on("error",()=>o(false));})}function M(a,t){return new Promise(e=>{let s=setTimeout(()=>e(false),t);child_process.exec(a,i=>{clearTimeout(s),e(!i);});})}async function P(a){let t=(a.timeoutSeconds??5)*1e3;switch(a.type){case "http":return _(a.target,t);case "tcp":return I(a.target,t);case "exec":return M(a.target,t);default:return false}}var k=5e3,B=16e3,d=1e3,j=5e3;async function H(a){return new Promise(t=>{R__default.default.createServer().once("error",()=>t(false)).once("listening",function(){this.close(()=>t(true));}).listen(a);})}async function q(a){if(await H(a))return;let t=y__default.default.platform()==="darwin"?`lsof -ti :${a} | xargs kill -9 2>/dev/null || true`:`fuser -k -9 ${a}/tcp 2>/dev/null; true`;await new Promise(e=>child_process.exec(t,()=>e())),await new Promise(e=>setTimeout(e,800));}async function S(a,t){let e=a.process?.pid??a.pid;if(e)return new Promise(s=>{let i=false,o=()=>{i||(i=true,clearTimeout(n),s());};a.once?.("exit",o),a.once?.("exit",o);try{process.kill(e,"SIGTERM");}catch{return o()}let n=setTimeout(()=>{try{process.kill(e,"SIGKILL"),setTimeout(o,100);}catch{o();}},t),h=setInterval(()=>{try{process.kill(e,0);}catch{clearInterval(h),o();}},500);})}var p=class{cfg;name;watcher=null;isBuilding=false;constructor(t){this.cfg={mode:"fork",instances:1,...t},this.name=t.name,this.initStore();}getConfig(){return this.cfg}async start(){let t=this.mp();if(t.status==="running"||t.status==="starting"){chunkWPWZGJN5_cjs.d.warn(this.name,"Already running \u2013 ignoring start()");return}this.patch({status:"starting",isRestarting:false,children:[],restartCount:0,backoffTime:d,probeFailures:0,startTime:null}),this.clearTimers(),this.stopProbe(),chunkWPWZGJN5_cjs.d.info(this.name,"Initializing fresh start...");try{await this.spawnAll(),this.cfg.devMode&&this.watchFiles();}catch(e){this.patch({status:"errored"}),chunkWPWZGJN5_cjs.d.error(this.name,`Start failed: ${e.message}`);}}async stop(){let t=this.mp();if(t.status==="stopping"){chunkWPWZGJN5_cjs.d.info(this.name,"Already stopping...");return}this.patch({status:"stopping",isRestarting:false}),chunkWPWZGJN5_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=>S(e,this.cfg.killTimeout??k))),new Promise((e,s)=>setTimeout(()=>s(new Error("Termination timeout")),1e4))]);}catch(e){chunkWPWZGJN5_cjs.d.error(this.name,`Stop timed out, forcing state reset: ${e.message||"UNKNOWN"}`);}this.patch({children:[],status:"stopped",startTime:null}),this.stopWatcher(),chunkWPWZGJN5_cjs.d.success(this.name,"Stopped.");}async restart(){let t=this.mp();t.isRestarting||(chunkWPWZGJN5_cjs.d.info(this.name,"Restarting.."),this.patch({isRestarting:true,status:"starting"}),this.clearTimers(),this.stopProbe(),await Promise.all(t.children.map(e=>S(e,this.cfg.killTimeout??k))));}async getStats(){let t=this.mp(),e=t.children[0]?.pid??null,s=null,i=null,o=null;if(e&&t.status==="running")try{let n=await O__default.default(e);s=n.cpu,i=n.memory;}catch{}return {name:this.name,status:t.status,pid:e,uptime:t.startTime?Date.now()-t.startTime:null,restartCount:t.restartCount,cpu:s,memoryRss:i,memoryHeap:o,mode:this.cfg.mode??"fork",instances:t.children.length}}async spawnAll(){if(!u__default.default.existsSync(this.cfg.scriptPath)){chunkWPWZGJN5_cjs.d.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??y__default.default.cpus().length:1,s=[];for(let o=0;o<e;o++){let n=this.forkChild();n&&s.push(n);}if(s.length===0){chunkWPWZGJN5_cjs.d.error(this.name,"Failed to spawn any instances."),this.patch({status:"stopped"});return}this.patch({children:s,startTime:Date.now(),status:"running"}),chunkWPWZGJN5_cjs.d.success(this.name,`Started ${s.length} instance(s) [${t}]`);let i=setTimeout(()=>{this.mp().status==="running"&&(this.patch({backoffTime:d,restartCount:0}),chunkWPWZGJN5_cjs.d.success(this.name,"Process is stable."));},j);this.patch({stabilityTimer:i}),this.cfg.probe&&this.startProbe();}forkChild(){try{let t=this.cfg.scriptPath.endsWith(".js"),e=c__default.default.isAbsolute(this.cfg.scriptPath),s,i,o;t?(s=process.execPath,i=[this.cfg.scriptPath,...this.cfg.args??[]],o=c__default.default.dirname(c__default.default.resolve(this.cfg.scriptPath,".."))):(s=this.cfg.scriptPath,i=[...this.cfg.args??[]],o=e?c__default.default.dirname(this.cfg.scriptPath):process.cwd());let n=child_process.spawn(s,i,{cwd:o,stdio:["ignore","pipe","pipe"],env:{...process.env,...this.cfg.env??{},NODE_ENV:this.cfg.devMode?"development":"production",PATH:`${c__default.default.resolve(process.cwd(),"node_modules/.bin")}${c__default.default.delimiter}${process.env.PATH}`},detached:!1,shell:!t});this.setupLogging(n);let h=Date.now();return n.on("error",l=>{chunkWPWZGJN5_cjs.d.error(this.name,`Spawn error (${s}):`,l.message);}),n.on("exit",(l,$)=>{let F=Date.now()-h;this.onChildExit(n,l,$,F);}),n}catch(t){return chunkWPWZGJN5_cjs.d.error(this.name,"Failed to fork child:",t.message),null}}_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??[]],s=child_process.spawn(t,e,{cwd:c__default.default.dirname(c__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(s);let i=Date.now();return s.on("error",o=>{chunkWPWZGJN5_cjs.d.error(this.name,"Spawn error:",o);}),s.on("exit",(o,n)=>{let h=Date.now()-i;this.onChildExit(s,o,n,h);}),s}catch(t){return chunkWPWZGJN5_cjs.d.error(this.name,"Failed to fork child:",t),null}}onChildExit(t,e,s,i){let o=this.mp(),n=o.children.filter(h=>h!==t);if(this.patch({children:n}),o.isRestarting){n.length===0?(chunkWPWZGJN5_cjs.d.info(this.name,"All instances stopped. Spawning new ones..."),this.patch({isRestarting:false}),this.spawnAll()):chunkWPWZGJN5_cjs.d.info(this.name,`Restart in progress... waiting for ${n.length} instance(s) to stop.`);return}if(o.status==="stopping"){n.length===0?(chunkWPWZGJN5_cjs.d.info(this.name,"All instances dead. Spawning new ones..."),this.patch({isRestarting:false}),this.spawnAll()):chunkWPWZGJN5_cjs.d.info(this.name,`Stop in progress... waiting for ${n.length} instance(s) to stop.`);return}chunkWPWZGJN5_cjs.d.warn(this.name,`Process exited (code=${e}, signal=${s}, uptime=${i}ms)`),e!==0&&e!==null&&(this.patch({status:"crashed"}),i<1500&&chunkWPWZGJN5_cjs.d.error(this.name,`Immediate crash (${i}ms) \u2013 likely a syntax/build error. Waiting for next file change.`),this.scheduleRestart());}scheduleRestart(){let t=this.mp(),e=t.backoffTime,s=this.cfg.maxBackoff??B;chunkWPWZGJN5_cjs.d.warn(this.name,`Scheduling restart in ${e}ms (attempt #${t.restartCount+1})`);let i=setTimeout(async()=>{this.patch({restartCount:t.restartCount+1,backoffTime:Math.min(e*2,s)}),await this.spawnAll();},e);this.patch({restartTimer:i});}startProbe(){let t=this.cfg.probe,e=(t.intervalSeconds??10)*1e3,s=t.failureThreshold??3,o=setInterval(async()=>{let n=this.mp();if(n.status!=="running")return;if(await P(t)){n.probeFailures>0&&this.patch({probeFailures:0});return}let l=n.probeFailures+1;this.patch({probeFailures:l}),chunkWPWZGJN5_cjs.d.warn(this.name,`Liveness probe failed (${l}/${s})`),l>=s&&(chunkWPWZGJN5_cjs.d.error(this.name,"Liveness probe threshold exceeded \u2013 restarting."),this.patch({probeFailures:0}),await this.restart());},e);this.patch({probeTimer:o});}stopProbe(){let{probeTimer:t}=this.mp();t&&(clearInterval(t),this.patch({probeTimer:null,probeFailures:0}));}findProjectRoot(t){let e=c__default.default.resolve(t);for(u__default.default.existsSync(e)&&u__default.default.statSync(e).isFile()&&(e=c__default.default.dirname(e));e!==c__default.default.parse(e).root;){if(u__default.default.existsSync(c__default.default.join(e,"package.json")))return e;e=c__default.default.dirname(e);}return process.cwd()}watchFiles(){this.stopWatcher();let t=this.findProjectRoot(this.cfg.scriptPath),e=c__default.default.resolve(t,"src");chunkWPWZGJN5_cjs.d.info(this.name,f__default.default.gray(`Watcher active on: ${e}`)),this.watcher=N__default.default.watch(e,{ignored:[/node_modules/,/\.pid$/],persistent:true,ignoreInitial:true,awaitWriteFinish:{stabilityThreshold:1500,pollInterval:500}}),this.watcher.on("all",async(s,i)=>{if(!this.isBuilding&&(s==="change"||s==="add"))if(chunkWPWZGJN5_cjs.d.info(this.name,f__default.default.yellow(`File ${s}: ${c__default.default.basename(i)} \u2013 restarting`)),this.cfg.reloadCommand){this.isBuilding=true,chunkWPWZGJN5_cjs.d.info(this.name,f__default.default.blue(`Executing: ${this.cfg.reloadCommand}`));let{exec:o}=await import('child_process');o(this.cfg.reloadCommand,{cwd:t,env:{...process.env,PATH:`${c__default.default.resolve(t,"node_modules/.bin")}${c__default.default.delimiter}${process.env.PATH}`}},(n,h,l)=>{if(this.isBuilding=false,n){chunkWPWZGJN5_cjs.d.error(this.name,`Build Failed:
|
|
3
|
+
${l||h||n.message}`);return}chunkWPWZGJN5_cjs.d.success(this.name,"Build successful. Triggering restart..."),this.restart();});}else this.restart();}),this.watcher.on("error",s=>chunkWPWZGJN5_cjs.d.error(this.name,"Watcher error:",s)),this.watcher.on("ready",()=>chunkWPWZGJN5_cjs.d.info(this.name,`Watching ${t}`));}stopWatcher(){this.watcher&&(this.watcher.close(),this.watcher=null);}initStore(){chunkWPWZGJN5_cjs.e.set(this.name,{config:this.cfg,children:[],status:"stopped",startTime:null,restartCount:0,backoffTime:d,restartTimer:null,stabilityTimer:null,probeTimer:null,probeFailures:0,isRestarting:false});}mp(){return chunkWPWZGJN5_cjs.e.get(this.name)}_patch(t){chunkWPWZGJN5_cjs.e.set(this.name,{...this.mp(),...t});}patch(t){let e=this.mp();t.status&&t.status!==e.status&&chunkWPWZGJN5_cjs.d.info(this.name,`[STATE] ${e.status} \u2794 ${t.status}${t.isRestarting?" (Restarting)":""}`),t.lastError&&chunkWPWZGJN5_cjs.d.error(this.name,`[REASON] ${t.lastError}`),chunkWPWZGJN5_cjs.e.set(this.name,{...e,...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,s=null;e&&(s=new v__default.default(e),s.on("open",()=>chunkWPWZGJN5_cjs.d.debug(this.name,"Connected to log collector")),s.on("error",o=>chunkWPWZGJN5_cjs.d.error(this.name,"Log Collector WS Error",o.message)));let i=o=>{let n=o.toString();this.cfg.devMode&&process.stdout.write(`[${this.name}] ${n}`),s&&s.readyState===v__default.default.OPEN&&s.send(JSON.stringify({app:this.name,timestamp:Date.now(),log:n}));};t.stdout?.on("data",i),t.stderr?.on("data",i);}};var W=class{workers=new Map;SNAPSHOT_FILE=c__default.default.join(y__default.default.homedir(),".zpm","snapshot.json");async start(t){let e=this.workers.get(t.name);if(e){let i=chunkWPWZGJN5_cjs.e.get(t.name);if(i?.status==="stopped"||i?.status==="crashed"||i?.status==="errored"){chunkWPWZGJN5_cjs.d.info("ZPM",`Resuming existing worker "${t.name}"`),await e.start();return}chunkWPWZGJN5_cjs.d.warn("ZPM",`Worker "${f__default.default.cyan(t.name)}" is ${f__default.default.cyan(i?.status)} - use restart()`);return}let s=new p(t);this.workers.set(t.name,s),await s.start(),this.saveSnapshot();}async stop(t){let e=this.require(t);e&&(await e.stop(),this.saveSnapshot());}async restart(t){let e=this.require(t);e&&(await e.restart(),this.saveSnapshot());}async delete(t){let e=this.require(t);e&&(await e.stop(),this.workers.delete(t),chunkWPWZGJN5_cjs.e.delete(t),this.saveSnapshot(),chunkWPWZGJN5_cjs.d.info("PM",`Deleted worker "${t}"`));}async getStats(t){if(t){let s=this.require(t);return s?[await s.getStats()]:[]}return await Promise.all([...this.workers.values()].map(s=>s.getStats()))}list(){return [...this.workers.keys()]}getAllConfigs(){return Array.from(this.workers.values()).map(t=>t.getConfig())}async stopAll(){chunkWPWZGJN5_cjs.d.info("PM","Stopping all workers..."),await Promise.all([...this.workers.values()].map(t=>t.stop())),chunkWPWZGJN5_cjs.d.info("PM","All workers stopped."),this.saveSnapshot();}getWorker(t){let e=this.workers.get(t);return e||(chunkWPWZGJN5_cjs.d.error(t,"Worker Not Found"),null)}async addWorker(t,e){let s=new p(t);this.workers.set(t.name,s),e&&await s.start(),this.saveSnapshot();}require(t){let e=this.workers.get(t);return e||(chunkWPWZGJN5_cjs.d.error(t,"Worker Not Found"),null)}saveSnapshot(){try{let t=c__default.default.dirname(this.SNAPSHOT_FILE);u__default.default.existsSync(t)||u__default.default.mkdirSync(t,{recursive:!0});let e=this.getAllConfigs();u__default.default.writeFileSync(this.SNAPSHOT_FILE,JSON.stringify(e,null,2)),chunkWPWZGJN5_cjs.d.info("daemon",`Saved snapshot of ${e.length} workers.`);}catch(t){chunkWPWZGJN5_cjs.d.error("daemon","Failed to save snapshot:",t.message);}}};exports.a=P;exports.b=p;exports.c=W;
|
package/dist/daemon.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var
|
|
2
|
-
var
|
|
1
|
+
'use strict';var chunkZOQDQOTG_cjs=require('./chunk-ZOQDQOTG.cjs'),chunkWPWZGJN5_cjs=require('./chunk-WPWZGJN5.cjs'),n=require('fs'),f=require('os'),S=require('path');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var n__default=/*#__PURE__*/_interopDefault(n);var f__default=/*#__PURE__*/_interopDefault(f);var S__default=/*#__PURE__*/_interopDefault(S);/* ZuzJS Process Manager */
|
|
2
|
+
var t=S__default.default.join(f__default.default.tmpdir(),"zuz-pm.pid");function g(){n__default.default.writeFileSync(t,String(process.pid));}function u(){n__default.default.existsSync(t)&&n__default.default.unlinkSync(t);}async function h(){chunkWPWZGJN5_cjs.d.success("daemon",`Booting ZPM daemon (PID ${process.pid})`),g();let r=new chunkZOQDQOTG_cjs.c,d=chunkWPWZGJN5_cjs.g(r);if(n__default.default.existsSync(r.SNAPSHOT_FILE))try{let e=n__default.default.readFileSync(r.SNAPSHOT_FILE,"utf-8"),s=JSON.parse(e);if(Array.isArray(s)&&s.length>0){chunkWPWZGJN5_cjs.d.info("daemon",`Restoring ${s.length} workers from snapshot...`);for(let a of s)r.start(a).catch(p=>{chunkWPWZGJN5_cjs.d.error("daemon",`Failed to restore worker "${a.name}":`,p.message);});}}catch(e){chunkWPWZGJN5_cjs.d.error("daemon","Snapshot restoration failed:",e.message);}async function i(e){chunkWPWZGJN5_cjs.d.info("daemon",`Received ${e} \u2013 shutting down\u2026`),r.saveSnapshot(),d.close(),await r.stopAll(),u(),process.exit(0);}process.on("SIGINT",()=>i("SIGINT")),process.on("SIGTERM",()=>i("SIGTERM")),process.on("uncaughtException",e=>chunkWPWZGJN5_cjs.d.error("daemon","Uncaught exception:",e)),process.on("unhandledRejection",e=>chunkWPWZGJN5_cjs.d.error("daemon","Unhandled rejection:",e)),chunkWPWZGJN5_cjs.d.success("daemon","Ready \u2013 waiting for IPC commands.");}h().catch(r=>{chunkWPWZGJN5_cjs.d.error("daemon","Fatal startup error:",r),process.exit(1);});
|
package/dist/daemon.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {c}from'./chunk-
|
|
1
|
+
import {c}from'./chunk-ALFXH7VX.js';import {d,g as g$1}from'./chunk-FXEDN7ZZ.js';import n from'fs';import f from'os';import S from'path';var t=S.join(f.tmpdir(),"zuz-pm.pid");function g(){n.writeFileSync(t,String(process.pid));}function u(){n.existsSync(t)&&n.unlinkSync(t);}async function h(){d.success("daemon",`Booting ZPM daemon (PID ${process.pid})`),g();let r=new c,d$1=g$1(r);if(n.existsSync(r.SNAPSHOT_FILE))try{let e=n.readFileSync(r.SNAPSHOT_FILE,"utf-8"),s=JSON.parse(e);if(Array.isArray(s)&&s.length>0){d.info("daemon",`Restoring ${s.length} workers from snapshot...`);for(let a of s)r.start(a).catch(p=>{d.error("daemon",`Failed to restore worker "${a.name}":`,p.message);});}}catch(e){d.error("daemon","Snapshot restoration failed:",e.message);}async function i(e){d.info("daemon",`Received ${e} \u2013 shutting down\u2026`),r.saveSnapshot(),d$1.close(),await r.stopAll(),u(),process.exit(0);}process.on("SIGINT",()=>i("SIGINT")),process.on("SIGTERM",()=>i("SIGTERM")),process.on("uncaughtException",e=>d.error("daemon","Uncaught exception:",e)),process.on("unhandledRejection",e=>d.error("daemon","Unhandled rejection:",e)),d.success("daemon","Ready \u2013 waiting for IPC commands.");}h().catch(r=>{d.error("daemon","Fatal startup error:",r),process.exit(1);});
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var chunk3BHYRI7Z_cjs=require('./chunk-3BHYRI7Z.cjs'),
|
|
1
|
+
'use strict';var chunk3BHYRI7Z_cjs=require('./chunk-3BHYRI7Z.cjs'),chunkZOQDQOTG_cjs=require('./chunk-ZOQDQOTG.cjs'),chunkWPWZGJN5_cjs=require('./chunk-WPWZGJN5.cjs');Object.defineProperty(exports,"ZPMClient",{enumerable:true,get:function(){return chunk3BHYRI7Z_cjs.a}});Object.defineProperty(exports,"zpm",{enumerable:true,get:function(){return chunk3BHYRI7Z_cjs.b}});Object.defineProperty(exports,"ProcessManager",{enumerable:true,get:function(){return chunkZOQDQOTG_cjs.c}});Object.defineProperty(exports,"Worker",{enumerable:true,get:function(){return chunkZOQDQOTG_cjs.b}});Object.defineProperty(exports,"runProbe",{enumerable:true,get:function(){return chunkZOQDQOTG_cjs.a}});Object.defineProperty(exports,"WorkerMode",{enumerable:true,get:function(){return chunkWPWZGJN5_cjs.b}});Object.defineProperty(exports,"WorkerStatus",{enumerable:true,get:function(){return chunkWPWZGJN5_cjs.c}});Object.defineProperty(exports,"getSocketPath",{enumerable:true,get:function(){return chunkWPWZGJN5_cjs.f}});Object.defineProperty(exports,"logger",{enumerable:true,get:function(){return chunkWPWZGJN5_cjs.d}});Object.defineProperty(exports,"processStore",{enumerable:true,get:function(){return chunkWPWZGJN5_cjs.e}});
|
package/dist/index.d.cts
CHANGED
|
@@ -174,16 +174,25 @@ declare class Worker {
|
|
|
174
174
|
|
|
175
175
|
declare class ProcessManager {
|
|
176
176
|
private workers;
|
|
177
|
+
readonly SNAPSHOT_FILE: string;
|
|
177
178
|
start(config: WorkerConfig): Promise<void>;
|
|
178
179
|
stop(name: string): Promise<void>;
|
|
179
180
|
restart(name: string): Promise<void>;
|
|
180
181
|
delete(name: string): Promise<void>;
|
|
181
182
|
getStats(name?: string): Promise<WorkerStats[]>;
|
|
183
|
+
/**
|
|
184
|
+
* Returns a list of all worker names.
|
|
185
|
+
*/
|
|
182
186
|
list(): string[];
|
|
187
|
+
/**
|
|
188
|
+
* Returns a list of all worker with their configs and statuses. Used for snapshot persistence.
|
|
189
|
+
*/
|
|
190
|
+
getAllConfigs(): WorkerConfig[];
|
|
183
191
|
stopAll(): Promise<void>;
|
|
184
192
|
getWorker(name: string): Worker | null;
|
|
185
193
|
addWorker(config: WorkerConfig, autoStart: boolean): Promise<void>;
|
|
186
194
|
private require;
|
|
195
|
+
saveSnapshot(): void;
|
|
187
196
|
}
|
|
188
197
|
|
|
189
198
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -174,16 +174,25 @@ declare class Worker {
|
|
|
174
174
|
|
|
175
175
|
declare class ProcessManager {
|
|
176
176
|
private workers;
|
|
177
|
+
readonly SNAPSHOT_FILE: string;
|
|
177
178
|
start(config: WorkerConfig): Promise<void>;
|
|
178
179
|
stop(name: string): Promise<void>;
|
|
179
180
|
restart(name: string): Promise<void>;
|
|
180
181
|
delete(name: string): Promise<void>;
|
|
181
182
|
getStats(name?: string): Promise<WorkerStats[]>;
|
|
183
|
+
/**
|
|
184
|
+
* Returns a list of all worker names.
|
|
185
|
+
*/
|
|
182
186
|
list(): string[];
|
|
187
|
+
/**
|
|
188
|
+
* Returns a list of all worker with their configs and statuses. Used for snapshot persistence.
|
|
189
|
+
*/
|
|
190
|
+
getAllConfigs(): WorkerConfig[];
|
|
183
191
|
stopAll(): Promise<void>;
|
|
184
192
|
getWorker(name: string): Worker | null;
|
|
185
193
|
addWorker(config: WorkerConfig, autoStart: boolean): Promise<void>;
|
|
186
194
|
private require;
|
|
195
|
+
saveSnapshot(): void;
|
|
187
196
|
}
|
|
188
197
|
|
|
189
198
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export{a as ZPMClient,b as zpm}from'./chunk-GQ7YGUB7.js';export{c as ProcessManager,b as Worker,a as runProbe}from'./chunk-
|
|
1
|
+
export{a as ZPMClient,b as zpm}from'./chunk-GQ7YGUB7.js';export{c as ProcessManager,b as Worker,a as runProbe}from'./chunk-ALFXH7VX.js';export{b as WorkerMode,c as WorkerStatus,f as getSocketPath,d as logger,e as processStore}from'./chunk-FXEDN7ZZ.js';
|