UNPKG

@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.77 kB
import{r as v}from"../packem_shared/admin-token-VdUnvnKW.mjs";import{r as y}from"../packem_shared/admin-url-BhF5ufg1.mjs";import{d as M}from"../packem_shared/command-Mmxzxyr5.mjs";import{EXIT_CODE as d,exitCodeForStatus as T}from"../packem_shared/EXIT_CODE-08cwt3MK.mjs";import{a as x}from"../packem_shared/resolve-target-C_ZloTvd.mjs";const I="__lunora_admin__:getFunctionStats",E=10,f=(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}),O=(r,o)=>{const t=r.filter(e=>(e.conflicts??0)>0).map(e=>f(e,e.calls===0?0:(e.conflicts??0)/e.calls)).toSorted((e,s)=>s.rate-e.rate||s.conflicts-e.conflicts).slice(0,o),n=r.filter(e=>e.errors>0).map(e=>f(e,e.calls===0?0:e.errors/e.calls)).toSorted((e,s)=>s.rate-e.rate||s.errors-e.errors).slice(0,o),a=r.map(e=>f(e,0)).toSorted((e,s)=>s.maxDurationMs-e.maxDurationMs).slice(0,o);return{errorHotspots:n,latencyOutliers:a,totalFunctions:r.length,writeContention:t}},p=r=>`${(r*100).toFixed(1)}%`,$=r=>r<1e3?`${Math.round(r).toString()}ms`:`${(r/1e3).toFixed(2)}s`,m=(r,o,t,n)=>[r,...o.length===0?[` ${t}`]:o.map(a=>` ${n(a)}`)],_=r=>{const o=t=>t.lastErrorMessage?` — ${t.lastErrorMessage}`:"";return[`Insights over ${r.totalFunctions.toString()} function${r.totalFunctions===1?"":"s"}`,"",...m("Write-conflict hot-spots (OCC contention — candidates for sharding):",r.writeContention,"none — no write conflicts observed",t=>`${t.path} ${t.conflicts.toString()}/${t.calls.toString()} calls (${p(t.rate)})`),"",...m("Error hot-spots:",r.errorHotspots,"none — no errors observed",t=>`${t.path} ${t.errors.toString()}/${t.calls.toString()} calls (${p(t.rate)})${o(t)}`),"",...m("Latency outliers (slowest single call):",r.latencyOutliers,"none — no functions have run",t=>`${t.path} max ${$(t.maxDurationMs)}, mean ${$(t.meanDurationMs)} over ${t.calls.toString()} calls`)].join(` `)},i=(r,o,t)=>(r.error(o),{code:t,error:o}),k=r=>r===void 0||!Number.isFinite(r)||r<=0?E:Math.floor(r),A=async r=>{const{logger:o}=r;if(r.prod&&r.url===void 0)return i(o,"--prod requires an explicit --url (refusing to report from the implicit localhost worker)",d.USAGE);const t=y(r.url,o,r.cwd);if(t===void 0)return{code:d.USAGE,error:"could not resolve a usable worker URL"};const{token:n}=v({cwd:r.cwd??process.cwd(),token:r.token,url:t});if(!n)return i(o,"admin token required — pass --token, set LUNORA_ADMIN_TOKEN, or add it to .dev.vars (local targets only)",d.AUTH);const a=`${t}/_lunora/rpc`,e=globalThis.fetch;if(typeof e!="function")throw new TypeError("no fetch implementation available — pass fetchImpl or run on Node >= 18");const s={args:{},functionPath:I};r.shard!==void 0&&(s.shardKey=r.shard),o.info(`POST ${a} -> insights`);const l=await e(a,{body:JSON.stringify(s),headers:{authorization:`Bearer ${n}`,"content-type":"application/json"},method:"POST"}),c=await l.text();if(!l.ok)return i(o,`insights failed: HTTP ${String(l.status)}: ${c}`,T(l.status));let u;try{u=JSON.parse(c)}catch{return i(o,`insights failed: worker returned non-JSON: ${c}`,1)}const S=u.result??u,{functions:h}=S;if(!Array.isArray(h))return i(o,"insights failed: response carried no `functions` array",1);const g=O(h,k(r.limit));return r.format!=="json"&&o.info(_(g)),{code:0,report:g}},C=M(async({cwd:r,format:o,logger:t,options:n})=>{const a=n.limit===void 0?void 0:Number.parseInt(n.limit,10),e=await A({cwd:r,fetchImpl:void 0,format:o,limit:a,logger:t,prod:n.prod,shard:n.shard,token:n.token,url:x({cwd:r,prod:n.prod===!0,url:n.url})});return{code:e.code,data:e.report,error:e.error}});export{O as buildInsightsReport,C as execute,_ as formatInsightsReport,A as runInsightsCommand};