@lunora/cli
Version:
The Lunora CLI: init, dev, deploy, codegen, migrate, seed, doctor, insights, logs, registry, and the rest of the project commands
3 lines (2 loc) • 3.49 kB
JavaScript
import{r as $}from"../packem_shared/admin-url-Cil3Or6N.mjs";import{d as p}from"../packem_shared/command-DwC11Cwe.mjs";import{a as S}from"../packem_shared/resolve-target-C_ZloTvd.mjs";const v="__lunora_admin__:getFunctionStats",M=10,d=(r,o)=>({calls:r.calls,conflicts:r.conflicts??0,errors:r.errors,lastErrorMessage:r.lastErrorMessage,maxDurationMs:r.maxDurationMs,meanDurationMs:r.calls===0?0:r.totalDurationMs/r.calls,path:r.path,rate:o}),y=(r,o)=>{const e=r.filter(t=>(t.conflicts??0)>0).map(t=>d(t,t.calls===0?0:(t.conflicts??0)/t.calls)).toSorted((t,n)=>n.rate-t.rate||n.conflicts-t.conflicts).slice(0,o),s=r.filter(t=>t.errors>0).map(t=>d(t,t.calls===0?0:t.errors/t.calls)).toSorted((t,n)=>n.rate-t.rate||n.errors-t.errors).slice(0,o),l=r.map(t=>d(t,0)).toSorted((t,n)=>n.maxDurationMs-t.maxDurationMs).slice(0,o);return{errorHotspots:s,latencyOutliers:l,totalFunctions:r.length,writeContention:e}},f=r=>`${(r*100).toFixed(1)}%`,h=r=>r<1e3?`${Math.round(r).toString()}ms`:`${(r/1e3).toFixed(2)}s`,u=(r,o,e,s)=>[r,...o.length===0?[` ${e}`]:o.map(l=>` ${s(l)}`)],N=r=>{const o=e=>e.lastErrorMessage?` — ${e.lastErrorMessage}`:"";return[`Insights over ${r.totalFunctions.toString()} function${r.totalFunctions===1?"":"s"}`,"",...u("Write-conflict hot-spots (OCC contention — candidates for sharding):",r.writeContention,"none — no write conflicts observed",e=>`${e.path} ${e.conflicts.toString()}/${e.calls.toString()} calls (${f(e.rate)})`),"",...u("Error hot-spots:",r.errorHotspots,"none — no errors observed",e=>`${e.path} ${e.errors.toString()}/${e.calls.toString()} calls (${f(e.rate)})${o(e)}`),"",...u("Latency outliers (slowest single call):",r.latencyOutliers,"none — no functions have run",e=>`${e.path} max ${h(e.maxDurationMs)}, mean ${h(e.meanDurationMs)} over ${e.calls.toString()} calls`)].join(`
`)},O=r=>r===void 0||!Number.isFinite(r)||r<=0?M:Math.floor(r),T=async r=>{if(r.prod&&r.url===void 0)return r.logger.error("--prod requires an explicit --url (refusing to report from the implicit localhost worker)"),{code:1};const o=r.token??process.env.LUNORA_ADMIN_TOKEN;if(!o)return r.logger.error("admin token required — pass --token or set LUNORA_ADMIN_TOKEN"),{code:1};const e=$(r.url,r.logger,r.cwd);if(e===void 0)return{code:1};const s=`${e}/_lunora/rpc`,l=globalThis.fetch;if(typeof l!="function")throw new TypeError("no fetch implementation available — pass fetchImpl or run on Node >= 18");const t={args:{},functionPath:v};r.shard!==void 0&&(t.shardKey=r.shard),r.logger.info(`POST ${s} -> insights`);const n=await l(s,{body:JSON.stringify(t),headers:{authorization:`Bearer ${o}`,"content-type":"application/json"},method:"POST"}),a=await n.text();if(!n.ok)return r.logger.error(`insights failed: HTTP ${String(n.status)}: ${a}`),{code:1};let i;try{i=JSON.parse(a)}catch{return r.logger.error(`insights failed: worker returned non-JSON: ${a}`),{code:1}}const m=i.result??i,{functions:g}=m;if(!Array.isArray(g))return r.logger.error("insights failed: response carried no `functions` array"),{code:1};const c=y(g,O(r.limit));return r.logger.info(r.json?JSON.stringify(c,void 0,2):N(c)),{code:0,report:c}},D=p(({cwd:r,logger:o,options:e})=>{const s=e.limit===void 0?void 0:Number.parseInt(e.limit,10);return T({cwd:r,fetchImpl:void 0,json:e.json,limit:s,logger:o,prod:e.prod,shard:e.shard,token:e.token,url:S({cwd:r,prod:e.prod===!0,url:e.url})})});export{y as buildInsightsReport,D as execute,N as formatInsightsReport,T as runInsightsCommand};