fnlb 1.1.4 → 1.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -42,10 +42,11 @@ declare class FNLB {
42
42
  private readonly packageName;
43
43
  private isLoaded;
44
44
  private shouldRestart;
45
+ private runId;
45
46
  constructor(config?: FNLBConfig);
46
47
  start(config: StartConfig): Promise<void>;
47
48
  stop(): Promise<void>;
48
- startShard(config: StartConfig, id: string): Promise<import("child_process").ChildProcess>;
49
+ startShard(config: StartConfig, id: string, currentRunId: number): Promise<import("child_process").ChildProcess>;
49
50
  update(): Promise<void>;
50
51
  private log;
51
52
  private success;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{fork as g}from"node:child_process";import{createHash as f}from"node:crypto";import{mkdir as u,readFile as m,writeFile as w}from"node:fs/promises";import{resolve as S}from"node:path";class l{static wait(t){return new Promise((e)=>setTimeout(e,t))}}class d{config;activeProcesses=new Map;packageName=`${process.versions.bun?"zenith-bun":"zenith"}`;isLoaded=!1;shouldRestart=!0;constructor(t){this.config=t}async start(t){if(await this.stop(),this.shouldRestart=!0,!t?.apiToken)throw new Error("[FNLB ShardingManager] Please provide a FNLB API token.");await this.update();let e=t.numberOfShards??1,i=(~~(Math.random()*1e4)).toString(36)+"fnlb"+(~~(Date.now()/1000)).toString(36);for(let s=0;s<e;s++){let o=`${i}-${s.toString().padStart(2,"0")}`,n=await this.startShard(t,o);this.activeProcesses.set(o,n)}}async stop(){if(this.shouldRestart=!1,this.activeProcesses.size===0)return;this.log("Stopping all active processes...");for(let[t,e]of this.activeProcesses)this.log(`Stopping process with ID: ${t}`),e.kill();this.activeProcesses.clear(),this.log("All processes stopped.")}async startShard(t,e){if(await this.update(),!t?.apiToken||t.apiToken.length<10)throw new Error("[FNLB ShardingManager] Please provide a valid FNLB API token.");this.log("Starting shard with ID:",e);let i=g(`./.fnlb/${this.packageName}.mjs`,[],{env:{...process.env,FORCE_COLOR:"1",SHARD_ID:e,API_TOKEN:t.apiToken,CATEGORIES:t.categories?.join(","),BOTS_PER_SHARD:(t.botsPerShard??1).toString(),HIDE_USERNAMES:t.hideUsernames?"true":"false",HIDE_EMAILS:t.hideEmails?"true":"false",LOG_LEVEL:t.logLevel,CLUSTER_ID:this.config?.clusterName?.trim().replace(/ +(?= )/g,"").toLowerCase().replaceAll(" ","-")??"unknown",CLUSTER_NAME:this.config?.clusterName?.trim()},stdio:["inherit","pipe","pipe","ipc"]});if(!this.config?.disableSubProcessLogs)i.stdout?.on("data",(s)=>{let o=s.toString("utf8");process.stdout.write(o),this.config?.onSubProcessLogMessage?.({timestamp:Date.now(),content:o,format:0})});if(!this.config?.disableSubProcessErrorLogs)i.stderr?.on("data",(s)=>{let o=s.toString("utf8");process.stderr.write(o),this.config?.onSubProcessLogMessage?.({timestamp:Date.now(),content:o,format:4})});return i.on("close",async(s)=>{if(this.activeProcesses.delete(e),this.shouldRestart){if(s===0)this.warn("Child process exited with code:",s,"(OK)");else this.error("Child process exited with code:",s?.toString()??"none");await l.wait(1e4);let o=await this.startShard(t,e);this.activeProcesses.set(e,o)}else this.log(`Child process ${e} stopped.`)}),i}async update(){if(this.isLoaded)return;let t=S(`./.fnlb/${this.packageName}.mjs`),e=await m(t,"utf-8").catch(()=>null),i=this.config?.maxDownloadRetries||1/0,s=this.config?.maxBackoffMs||60000;this.log(e?"Checking for updates...":"Downloading FNLB...");let o=`https://dist.fnlb.net/packages/${this.packageName}/release`,n,c=0,h=1000;while(c<i)try{let r=await fetch(o);if(!r.ok)throw new Error(`Status code: ${r.status}`);n=await r.json();break}catch(r){let a=Math.min(h*2,s);if(c++,this.error("Update error:",r),this.warn(`Check for updates attempt ${c} failed: ${r.message}. Retrying in ${a>=60000?`${~~(a/60000)}m`:`${~~(a/1000)}s`}...`),c>=i)break;await new Promise((p)=>setTimeout(p,h)),h=a}if(!n){if(e){this.warn("Failed to check for updates. Using existing local version."),this.isLoaded=!0,this.success("Loaded existing FNLB version");return}throw new Error("[FNLB ShardingManager] Failed to check for updates and no local file found.")}if(e){if(f("sha256").update(e).digest("hex")===n.hash){this.success(`FNLB v${n.version} is up to date`),this.isLoaded=!0,this.success(`Finished loading FNLB v${n.version}`);return}this.log(`Downloading update for FNLB v${n.version}`)}c=0,h=1000;while(c<i)try{let r=await fetch(n.url);if(!r.ok)throw new Error(`Download failed with status ${r.status}`);let a=await r.text();if(f("sha256").update(a).digest("hex")!==n.hash)throw new Error("Downloaded file hash mismatch...");await u(".fnlb",{recursive:!0}),await w(t,a),this.isLoaded=!0,this.success(`Finished loading FNLB v${n.version}`);return}catch(r){let a=Math.min(h*2,s);c++,this.error("Download error:",r),this.warn(`Download attempt ${c} failed: ${r.message}. Retrying in ${a>=60000?`${~~(a/60000)}m`:`${~~(a/1000)}s`}...`),await l.wait(h),h=a}if(e){this.warn("Max retries reached. Using existing local version."),this.isLoaded=!0,this.success("Loaded existing FNLB version");return}throw new Error(`[FNLB ShardingManager] Failed to download and verify update after ${c} attempts`)}log(...t){if(!this.config?.disableLogs)console.log("[FNLB ShardingManager]",...t),this.config?.onLogMessage?.({timestamp:Date.now(),content:t.join(" "),format:0})}success(...t){if(!this.config?.disableLogs)console.log("[FNLB ShardingManager] [OK]",...t),this.config?.onLogMessage?.({timestamp:Date.now(),content:t.join(" "),format:1})}warn(...t){if(!this.config?.disableErrorLogs)console.warn("[FNLB ShardingManager] [WRN]",...t),this.config?.onLogMessage?.({timestamp:Date.now(),content:t.join(" "),format:3})}error(...t){if(!this.config?.disableErrorLogs)console.error("[FNLB ShardingManager] [ERR]",...t),this.config?.onLogMessage?.({timestamp:Date.now(),content:t.join(" "),format:4})}}var L;((i)=>{i.Info="INFO";i.Debug="DEBUG"})(L||={});var M=d;export{M as default,L as LogLevel};
1
+ import{fork as u}from"node:child_process";import{createHash as f}from"node:crypto";import{mkdir as g,readFile as m,writeFile as w}from"node:fs/promises";import{resolve as S}from"node:path";class d{static wait(t){return new Promise((r)=>setTimeout(r,t))}}class l{config;activeProcesses=new Map;packageName=`${process.versions.bun?"zenith-bun":"zenith"}`;isLoaded=!1;shouldRestart=!0;runId=0;constructor(t){this.config=t}async start(t){await this.stop(),this.shouldRestart=!0,this.runId++;let r=this.runId;if(!t?.apiToken)throw new Error("[FNLB ShardingManager] Please provide a FNLB API token.");await this.update();let o=t.numberOfShards??1,h=(~~(Math.random()*1e4)).toString(36)+"fnlb"+(~~(Date.now()/1000)).toString(36);for(let i=0;i<o;i++){let e=`${h}-${i.toString().padStart(2,"0")}`,n=await this.startShard(t,e,r);this.activeProcesses.set(e,n)}}async stop(){if(this.shouldRestart=!1,this.runId++,this.activeProcesses.size===0)return;this.log("Stopping all active shards...");for(let[t,r]of this.activeProcesses)this.log(`Stopping shard with ID: ${t}`),r.kill();this.activeProcesses.clear(),this.log("All shards stopped.")}async startShard(t,r,o){if(await this.update(),!t?.apiToken||t.apiToken.length<10)throw new Error("[FNLB ShardingManager] Please provide a valid FNLB API token.");this.log("Starting shard with ID:",r);let h=u(`./.fnlb/${this.packageName}.mjs`,[],{env:{...process.env,FORCE_COLOR:"1",SHARD_ID:r,API_TOKEN:t.apiToken,CATEGORIES:t.categories?.join(","),BOTS_PER_SHARD:(t.botsPerShard??1).toString(),HIDE_USERNAMES:t.hideUsernames?"true":"false",HIDE_EMAILS:t.hideEmails?"true":"false",LOG_LEVEL:t.logLevel,CLUSTER_ID:this.config?.clusterName?.trim().replace(/ +(?= )/g,"").toLowerCase().replaceAll(" ","-")??"unknown",CLUSTER_NAME:this.config?.clusterName?.trim()},stdio:["inherit","pipe","pipe","ipc"]});if(!this.config?.disableSubProcessLogs)h.stdout?.on("data",(i)=>{let e=i.toString("utf8");process.stdout.write(e),this.config?.onSubProcessLogMessage?.({timestamp:Date.now(),content:e,format:0})});if(!this.config?.disableSubProcessErrorLogs)h.stderr?.on("data",(i)=>{let e=i.toString("utf8");process.stderr.write(e),this.config?.onSubProcessLogMessage?.({timestamp:Date.now(),content:e,format:4})});return h.on("close",async(i)=>{if(this.activeProcesses.delete(r),this.shouldRestart&&o===this.runId){if(i===0)this.warn("Shard exited with code:",i);else this.error("Shard exited with code:",i?.toString()??"none");this.log("Trying to restart shard..."),await d.wait(1e4);let e=await this.startShard(t,r,o);this.activeProcesses.set(r,e)}else this.log(`Shard ${r} stopped.`)}),h}async update(){if(this.isLoaded)return;let t=S(`./.fnlb/${this.packageName}.mjs`),r=await m(t,"utf-8").catch(()=>null),o=this.config?.maxDownloadRetries||1/0,h=this.config?.maxBackoffMs||60000;this.log(r?"Checking for updates...":"Downloading FNLB...");let i=`https://dist.fnlb.net/packages/${this.packageName}/release`,e,n=0,c=1000;while(n<o)try{let s=await fetch(i);if(!s.ok)throw new Error(`Status code: ${s.status}`);e=await s.json();break}catch(s){let a=Math.min(c*2,h);if(n++,this.error("Update error:",s),this.warn(`Check for updates attempt ${n} failed: ${s.message}. Retrying in ${a>=60000?`${~~(a/60000)}m`:`${~~(a/1000)}s`}...`),n>=o)break;await new Promise((p)=>setTimeout(p,c)),c=a}if(!e){if(r){this.warn("Failed to check for updates. Using existing local version."),this.isLoaded=!0,this.success("Loaded existing FNLB version");return}throw new Error("[FNLB ShardingManager] Failed to check for updates and no local file found.")}if(r){if(f("sha256").update(r).digest("hex")===e.hash){this.success(`FNLB v${e.version} is up to date`),this.isLoaded=!0,this.success(`Finished loading FNLB v${e.version}`);return}this.log(`Downloading update for FNLB v${e.version}`)}n=0,c=1000;while(n<o)try{let s=await fetch(e.url);if(!s.ok)throw new Error(`Download failed with status ${s.status}`);let a=await s.text();if(f("sha256").update(a).digest("hex")!==e.hash)throw new Error("Downloaded file hash mismatch...");await g(".fnlb",{recursive:!0}),await w(t,a),this.isLoaded=!0,this.success(`Finished loading FNLB v${e.version}`);return}catch(s){let a=Math.min(c*2,h);n++,this.error("Download error:",s),this.warn(`Download attempt ${n} failed: ${s.message}. Retrying in ${a>=60000?`${~~(a/60000)}m`:`${~~(a/1000)}s`}...`),await d.wait(c),c=a}if(r){this.warn("Max retries reached. Using existing local version."),this.isLoaded=!0,this.success("Loaded existing FNLB version");return}throw new Error(`[FNLB ShardingManager] Failed to download and verify update after ${n} attempts`)}log(...t){if(!this.config?.disableLogs)console.log("[FNLB ShardingManager]",...t),this.config?.onLogMessage?.({timestamp:Date.now(),content:t.join(" "),format:0})}success(...t){if(!this.config?.disableLogs)console.log("[FNLB ShardingManager] [OK]",...t),this.config?.onLogMessage?.({timestamp:Date.now(),content:t.join(" "),format:1})}warn(...t){if(!this.config?.disableErrorLogs)console.warn("[FNLB ShardingManager] [WRN]",...t),this.config?.onLogMessage?.({timestamp:Date.now(),content:t.join(" "),format:3})}error(...t){if(!this.config?.disableErrorLogs)console.error("[FNLB ShardingManager] [ERR]",...t),this.config?.onLogMessage?.({timestamp:Date.now(),content:t.join(" "),format:4})}}var L;((o)=>{o.Info="INFO";o.Debug="DEBUG"})(L||={});var M=l;export{M as default,L as LogLevel};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fnlb",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
4
4
  "author": "FNLB",
5
5
  "main": "dist/index.js",
6
6
  "homepage": "https://fnlb.net",