@lensmcp/core 1.25.13 → 1.25.14

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.
@@ -64,6 +64,8 @@ export declare function trimFlowEvent(event: BaseEvent, opts?: FlowShapeOptions)
64
64
  stream?: string | undefined;
65
65
  logger?: string | undefined;
66
66
  level?: string | undefined;
67
+ parentSpanId?: string | undefined;
68
+ spanId?: string | undefined;
67
69
  role?: string | undefined;
68
70
  captured?: string[] | undefined;
69
71
  error?: string | undefined;
@@ -133,6 +135,8 @@ export declare function buildFlowDetail(rawEvents: BaseEvent[], opts?: FlowShape
133
135
  stream?: string | undefined;
134
136
  logger?: string | undefined;
135
137
  level?: string | undefined;
138
+ parentSpanId?: string | undefined;
139
+ spanId?: string | undefined;
136
140
  role?: string | undefined;
137
141
  captured?: string[] | undefined;
138
142
  error?: string | undefined;
package/lib/flow-shape.js CHANGED
@@ -1 +1 @@
1
- "use strict";var kt=Object.defineProperty;var T=(a,p)=>kt(a,"name",{value:p,configurable:!0});var vt=Object.defineProperty,$=T((a,p)=>vt(a,"name",{value:p,configurable:!0}),"g");import{redactDeep as wt,redactText as ot,redactUrlParams as qt}from"./redact.js";import{templatisePath as ct}from"./route-template.js";import{SQL_ACCOUNT_KIND as Mt,sqlAccountingOf as It}from"./flow-segments.js";import{boundedClone as xt}from"@lensmcp/protocol-types";export function areaOf(a){const{source:p,category:o,title:v,kind:m}=a;return p==="ai"?"ai":m?.startsWith("memory")||m==="db-query"?"data":p==="gateway"||m==="gateway-request"?"gateway":m==="queue-process"||m==="queue-active"||m==="queue-completed"||m==="queue-failed"?"services":p==="db"||p==="redis"||p==="queue"||m==="redis-op"||m?.startsWith("queue-")?"data":p==="external"||m==="egress"?"network":p==="nestjs"||p==="nest"?/(?:Repository|Repo|Dao|Store)\./.test(v)?"data":"services":p==="valtio"?"state":o==="network"?"network":"browser"}T(areaOf,"areaOf"),$(areaOf,"areaOf");const lt=240,bt=new Set(["systemPrompt","prompt","prompts","messages","completion","completions","input","output","draft","text","content","result","arguments","params"]),jt=new Set(["tenantId","caller","userId","accountId","email","subject"]),Bt=8;function ft(a){const p=tt(a,0);return xt(wt({redacted:!0,...p}),{rawByteLimit:16*1024}).value}T(ft,"bt"),$(ft,"aiProjection");function tt(a,p){if(typeof a=="string")return pt(a);if(a===null||typeof a!="object")return a;if(p>=Bt)return;if(Array.isArray(a))return a.slice(0,32).map(v=>tt(v,p+1));const o={};for(const[v,m]of Object.entries(a))if(!jt.has(v)){if(bt.has(v)){typeof m=="string"?o[`${v}Chars`]=m.length:Array.isArray(m)?o[`${v}Count`]=m.length:m!=null&&(o[`${v}Present`]=!0);continue}o[v]=tt(m,p+1)}return o}T(tt,"ot"),$(tt,"projectAi");function pt(a){return a.length<=lt?ot(a):`${ot(a.slice(0,lt))}\u2026`}T(pt,"jt"),$(pt,"clipText");export function httpFacts(a,p){const o=$(q=>typeof q=="string"&&q.length>0?q:void 0,"str"),v=typeof p.status=="number"?p.status:void 0,m=$(q=>qt(q.split("?")[0]??q)||"/","pathOf"),D=$((q,w,b={})=>({...q?{method:q.toUpperCase()}:{},...w?{rawPath:w,route:ct(w)}:{},...v!==void 0?{status:v}:{},...b}),"facts");if(a==="gateway-request"){const q=o(p.url);return D(o(p.method),q?m(q):void 0,{...o(p.host)?{host:o(p.host)}:{},...o(p.caller)?{caller:o(p.caller)}:{}})}if(a==="egress"){const q=o(p.path),w=o(p.exchangeId);return D(o(p.method)??"GET",q?m(q):void 0,{...o(p.host)?{host:o(p.host)}:{},...w?{exchangeId:w}:{}})}if(a==="fetch-start"||a==="fetch-done"||a==="fetch-error"){const q=o(p.href)??o(p.url);let w,b;if(q)try{const f=new URL(q,"http://relative.invalid");w=m(f.pathname),f.hostname!=="relative.invalid"&&(b=f.hostname)}catch{}return D(o(p.method)??"GET",w,b?{host:b}:{})}if(a==="ai-call")return{...v!==void 0?{status:v}:{},...p.stream===!0?{streamed:!0}:{}};const l=p.request;if(l&&typeof l=="object"){const q=l,w=o(q.route),b=o(q.method);if(!w&&!b)return{};const f=typeof q.status=="number"?q.status:void 0,C=w?m(w):void 0;return{...b?{method:b.toUpperCase()}:{},...C?{rawPath:C,route:C.includes(":")?C:ct(C)}:{},...f!==void 0?{status:f}:{}}}return{}}T(httpFacts,"httpFacts"),$(httpFacts,"httpFacts");export function trimFlowEvent(a,p={}){const o=a.raw??{},v=o.render??{},m=o.span??{},D=o.request??{},l=$(i=>typeof i=="number"?i:void 0,"num"),q=o.loop??{},w=o.effect??{},b=l(o.durationMs)??l(m.durationMs)??l(D.durationMs)??l(q.durationMs)??l(v.actualDurationMs)??l(w.durationMs),f=typeof o.kind=="string"?o.kind:void 0,C=f==="fetch-done"||f==="fetch-error",X=l(v.commitTime),et=f==="render"&&X!==void 0&&Math.abs(X-a.timestamp)<6e4,N=C?a.timestamp:et?X:l(o.startedAt)??l(m.startTime)??l(D.startedAt)??l(q.startedAt)??(b!==void 0?a.timestamp-b:a.timestamp);let j;if(typeof o.query=="string"){const i=Array.isArray(o.params)?` [${o.params.join(", ")}]`:"",y=typeof o.result=="string"?` \u2192 ${o.result}`:"";j=o.query+i+y}else if(typeof o.command=="string"){const i=typeof o.value=="string"?` \u2192 ${o.value}`:o.hit===!1?" \u2192 (miss)":"";j=o.command+i}else if(f==="state-update"){const i=o.update??{};let y="";try{y=JSON.stringify(i.preview)}catch{}j=`${i.storeId??""}.${i.path??""} = ${y}`}else if(f==="queue-completed"&&typeof o.returned=="string")j=`returned ${o.returned}`;else if(f==="queue-enqueued")j=`${o.job??"job"}#${o.jobId??"?"} \u2192 ${o.queue??""}${typeof o.data=="string"?" "+o.data:""}`;else if(f==="log"){const i=D.error??{},y=typeof i.stack=="string"?i.stack:typeof o.text=="string"?o.text:void 0;y&&y!==a.title&&(j=y)}let F,K,O,E;if(f==="span"){const i=m.outcome;if(F=i==="threw"||i==="returned"?i:m.status==="error"?"threw":m.status==="ok"?"returned":void 0,F==="threw"){const R=m.error??{},P=typeof R.name=="string"?R.name:void 0,V=typeof R.message=="string"?R.message:typeof a.message=="string"?a.message:void 0;O=P,K=ot([P,V].filter(Boolean).join(": "))||void 0}const y=typeof m.args=="string"?m.args:void 0,A=typeof m.result=="string"?m.result:void 0;if(y!==void 0||A!==void 0){E=[...y!==void 0?["args"]:[],...A!==void 0?["result"]:[]];const R=$(P=>P.length>mt?`${P.slice(0,mt)}\u2026`:P,"short");j=[y!==void 0?`args ${R(y)}`:"",A!==void 0?`returned ${R(A)}`:""].filter(Boolean).join(" \u2192 ")}}let U;if(f==="gateway-request")U=`${o.host??""}${String(o.url??"").split("?")[0]}`;else if(f==="fetch-start"||f==="fetch-done"||f==="fetch-error")try{const i=new URL(String(o.href??o.url??""));U=`${i.hostname}${i.pathname}`}catch{}let W;if(f==="gateway-request"&&Array.isArray(o.steps))W=o.steps.map(i=>{const y=[String(i.step)];return i.project&&y.push(String(i.project)),i.prefix&&y.push(String(i.prefix)),i.mode&&y.push(String(i.mode)+(i.ok===!1?" \u2717":i.ok===!0?" \u2713":"")),i.caller&&y.push("by "+String(i.caller)),i.pod&&y.push(String(i.pod)),typeof i.atMs=="number"&&y.push(`@${i.atMs}ms`),y.join(" ")}),j=W.map(i=>i.replace(/ @\d+ms$/,"")).join(" \u2192 ");else if(f==="egress")j=`${o.method??"GET"} ${o.host??""} \u2192 ${o.status??"?"}`;else if(a.source==="ai"){if(f==="ai-call"){const i=o.usage??{},y=i.promptTokens!==void 0||i.completionTokens!==void 0?` \xB7 ${l(i.promptTokens)??"?"}\u2192${l(i.completionTokens)??"?"} tok`:"",A=o.status!==void 0?` \xB7 ${String(o.status)}`:o.error?" \xB7 failed":"",R=l(o.toolCallCount)?` \xB7 ${l(o.toolCallCount)} tool call${l(o.toolCallCount)===1?"":"s"}`:"",P=l(o.durationMs)!==void 0?` \xB7 ${(l(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${o.provider??""}/${o.model??"?"}${y}${A}${R}${P}${o.stream===!0?" \xB7 stream":""}`}else if(f==="ai-round"){const i=o.model??{},y=o.usage??{},A=Array.isArray(o.toolCalls)?o.toolCalls:[],R=`${l(y.promptTokens)??"?"}\u2192${l(y.completionTokens)??"?"} tok`,P=A.length?` \xB7 ${A.length} tool call${A.length===1?"":"s"}`:"",V=l(o.durationMs)!==void 0?` \xB7 ${(l(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${i.provider??""}/${i.model??""} \xB7 ${R}${P}${V}`}else if(f==="ai-turn-start"){const i=Array.isArray(o.tools)?o.tools:[];j=`skill ${o.skill??""} \xB7 ${o.output??""}${i.length?" \xB7 tools: "+i.join(", "):""}`}else if(f==="ai-tool-call"){const i=o.call??{},y=o.result??{},A=l(o.durationMs)!==void 0?` \xB7 ${(l(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${i.name??"tool"} ${y.error!=null?"\u2717 "+String(y.error):"\u2713"}${A}`}else if(f==="ai-turn-end"){const i=o.usage??{},y=l(o.rounds)!==void 0?` \xB7 ${l(o.rounds)} round${l(o.rounds)===1?"":"s"}`:"",A=l(o.durationMs)!==void 0?` \xB7 ${(l(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${o.ok===!1?"FAILED":"ok"} \xB7 ${l(i.promptTokens)??"?"}+${l(i.completionTokens)??"?"} tok${y}${A}`}}let g;f==="db-query"&&typeof o.query=="string"?g=o.query:f==="redis-op"?g=`${o.op??""} ${String(o.key??"").replace(/\d+/g,"#")}`:f==="egress"?g=`${o.method??"GET"} ${o.host??""}`:f==="ai-call"?g=`ai ${o.provider??""} ${o.model??""} ${o.api??""}`:f==="queue-enqueued"?g=`enqueue ${o.queue??""}`:f==="span"&&typeof m.name=="string"?g=m.name:f==="memory-mutation"&&(g=a.title);const L=a.context??{},z=v.commitId??w.commitId??o.commitId,H=Array.isArray(v.why)?v.why.map(i=>typeof i?.type=="string"?i.type:void 0).filter(i=>!!i):[];return{id:a.id,t:a.timestamp,start:N,...g?{sig:g}:{},...U?{urlKey:U}:{},...httpFacts(f,o),...typeof o.queue=="string"?{queue:o.queue}:{},...o.jobId!=null?{jobId:String(o.jobId)}:{},source:a.source,category:a.category,severity:a.severity,title:F==="threw"&&typeof m.name=="string"?`${m.name} \u2014 threw${O?` ${O}`:""}${b!==void 0?` after ${b}ms`:""}`:a.title,kind:f,area:areaOf({source:a.source,category:a.category,title:a.title,kind:f}),...F?{outcome:F}:{},...K?{error:K}:{},...E?{captured:E}:{},...typeof m.role=="string"?{role:m.role}:{},...f==="log"&&typeof o.level=="string"?{level:o.level}:{},...f==="log"&&typeof o.logger=="string"?{logger:o.logger}:{},...f==="log"&&typeof o.stream=="string"?{stream:o.stream}:{},...typeof L.requestId=="string"?{requestId:L.requestId}:{},...typeof L.parentRequestId=="string"?{parentRequestId:L.parentRequestId}:{},...typeof z=="string"?{commitId:z}:{},...typeof v.componentName=="string"?{component:v.componentName}:{},...typeof v.phase=="string"?{phase:v.phase}:{},...H.length?{why:H}:{},...f==="effect-run"&&typeof w.hookLogicalId=="string"?{hook:w.hookLogicalId}:{},...f==="effect-run"&&w.cleanupRan===!0?{cleanup:!0}:{},...f==="render-commit-truncated"?{renderTotal:l(o.total),renderPublished:l(o.published),...l(o.walkStoppedAt)!==void 0?{renderWalkStoppedAt:l(o.walkStoppedAt)}:{}}:{},...typeof L.projectName=="string"?{project:L.projectName}:typeof o.project=="string"?{project:o.project}:{},...b!==void 0?{durationMs:b}:{},...C&&l(o.startedAt)!==void 0?{fetchStartedAt:l(o.startedAt)}:{},...a.source==="ai"?{ai:p.includeRaw?o:ft(o)}:{},...j?{detail:j}:{},...W?{steps:W}:{}}}T(trimFlowEvent,"trimFlowEvent"),$(trimFlowEvent,"trimFlowEvent");const mt=300;export const OUTLIVED_PARENT_MIN_MS=250;const St=new Set(["egress","db-query","redis-op","ai-call","span","gateway-request","server-request"]),ht=1;function gt(a){return a==="flow-origin"?0:a?.endsWith("-start")?1:a==="gateway-request"?2:a==="server-request"?3:a==="span"?4:a==="render"||a==="render-commit-truncated"?6:a==="effect-run"?7:5}T(gt,"St"),$(gt,"kindRank");function J(a){return a.kind==="span"&&a.role==="controller"?3.5:a.kind==="queue-process"?3:gt(a.kind)}T(J,"Z"),$(J,"causalRank");export function buildFlowDetail(a,p={}){const o=It(a),v=a.slice().filter(t=>{const e=t.raw??{},r=typeof e.kind=="string"?e.kind:"";if(r==="subscription-added"||r==="subscription-removed"||r==="hook-run"||r==="store-created"||r==="singleton-instance"||r===Mt)return!1;const n=e.span;return!(typeof n?.name=="string"&&n.name.startsWith("nest.request "))}).map(t=>trimFlowEvent(t,p)),m=new Set;for(let t=v.length-1;t>=0;t--)m.has(v[t].id)?v.splice(t,1):m.add(v[t].id);const D=new Map;for(const t of v)(t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&!D.has(t.requestId)&&D.set(t.requestId,t.start);const l=$(t=>t.source!=="react"&&t.source!=="valtio"&&t.requestId&&D.has(t.requestId)?D.get(t.requestId):t.start,"anchorOf");v.sort((t,e)=>l(t)-l(e)||t.start-e.start||J(t)-J(e)||(e.durationMs??0)-(t.durationMs??0)||t.t-e.t);const q=$(t=>(t.kind==="span"||t.kind==="server-request"||t.kind==="gateway-request"||t.kind==="queue-process")&&(t.durationMs??0)>0,"spanLike"),w=v;for(const t of w)t.group=t.source==="react"||t.source==="valtio"||t.source==="client-runtime"||t.source==="visual"?"browser":"server";const b=new Map;for(const t of w)if((t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&t.project){const e=b.get(t.requestId)??[];e.push({project:t.project,start:t.start,end:t.start+(t.durationMs??0)}),b.set(t.requestId,e)}const f=$((t,e)=>{const r=b.get(t);if(r?.length)return r.every(n=>n.project===r[0].project)?r[0].project:r.filter(n=>n.start<=e+1&&n.end>=e-1).sort((n,s)=>s.start-n.start)[0]?.project},"projectOf");for(const t of w)if(!t.project&&t.source==="nestjs"&&t.requestId){const e=f(t.requestId,t.start);e&&(t.project=e)}for(const t of w){let e;const r=t.requestId;for(const n of w){if(n===t||!q(n)||n.group!==t.group||n.requestId!==r)continue;const s=n.project,c=t.project;if(n.kind!=="gateway-request"&&t.kind!=="gateway-request"&&s!==void 0&&c!==void 0&&s!==c)continue;const k=n.durationMs??0,M=t.durationMs??0,u=Math.abs(n.start-t.start)<=ht,d=J(n),h=J(t),I=n.start<=t.start;if(!(n.start+k>t.start&&(I||u&&d<h)&&(!u||(d!==h?d<h:I&&k>M))))continue;const S=e?J(e):-1,x=e?Math.abs(n.start-e.start)<=ht:!1;(!e||!x&&n.start>e.start||x&&d>S||x&&d===S&&(n.durationMs??0)<(e.durationMs??0))&&(e=n)}e&&(t.parent=e.id)}const C=new Map;for(const t of w){if(!t.requestId)continue;const e=C.get(t.requestId);e?e.push(t):C.set(t.requestId,[t])}const X=new Map(w.map(t=>[t.id,t])),et=$((t,e)=>{const r=(C.get(t)??[]).filter(n=>q(n)&&n.start<=e&&n.start+(n.durationMs??0)>=e);if(r.length!==0)return r.sort((n,s)=>s.start-n.start||(n.durationMs??0)-(s.durationMs??0)),r[0]},"callerNodeFor");for(const t of w){if(!t.parentRequestId||t.kind!=="server-request"&&t.kind!=="gateway-request")continue;const e=t.parent?X.get(t.parent):void 0;if(e&&e.requestId===t.requestId)continue;const r=et(t.parentRequestId,t.start);r&&r!==t&&r.start<=t.start&&(t.parent=r.id)}const N=w,j=new Map;for(const t of N)t.kind==="gateway-request"&&t.requestId&&!j.has(t.requestId)&&j.set(t.requestId,t);for(const t of N)if(t.group==="server"&&!t.parent&&t.requestId&&t.kind!=="gateway-request"){const e=j.get(t.requestId);e&&e!==t&&e.start<=t.start&&(t.parent=e.id)}const F=new Set,K=new Set,O=[];for(const t of N){if(t.kind!=="gateway-request")continue;if(!t.requestId){O.push(t);continue}const e=C.get(t.requestId)??[];if(e.filter(s=>s.kind==="gateway-request").sort((s,c)=>s.start-c.start)[0]!==t)continue;const r=e.find(s=>s.kind==="fetch-start"),n=e.find(s=>s.kind==="fetch-done"||s.kind==="fetch-error");if(!r&&!n){O.push(t);continue}r&&(t.fetchStartId=r.id,F.add(r.id)),n&&(t.fetchDoneId=n.id,K.add(n.id))}const E=new Map;for(const t of N){if(!t.urlKey)continue;const e=E.get(t.urlKey)??{gws:[],starts:[],dones:[]};t.kind==="gateway-request"?O.includes(t)&&e.gws.push(t):t.kind==="fetch-start"?F.has(t.id)||e.starts.push(t):(t.kind==="fetch-done"||t.kind==="fetch-error")&&(K.has(t.id)||e.dones.push(t)),E.set(t.urlKey,e)}for(const{gws:t,starts:e,dones:r}of E.values()){t.sort((s,c)=>s.start-c.start),e.sort((s,c)=>s.start-c.start);const n=new Set;t.forEach((s,c)=>{const k=e[c];k&&(s.fetchStartId=k.id);const M=k?k.t:s.start;let u,d=1/0;for(const h of r){if(n.has(h.id))continue;const I=h.fetchStartedAt??h.start-(h.durationMs??0),S=Math.abs(I-M);S<d&&(d=S,u=h)}u&&(s.fetchDoneId=u.id,n.add(u.id))})}const U=new Map,W=new Map;for(const t of N)!t.queue||!t.jobId||(t.kind==="queue-enqueued"&&U.set(`${t.queue}#${t.jobId}`,t),t.kind==="queue-process"&&W.set(`${t.queue}#${t.jobId}`,t));for(const t of N){if(!t.queue||!t.jobId)continue;const e=`${t.queue}#${t.jobId}`;if(t.kind==="queue-process"&&!t.parent){const r=U.get(e);r&&r!==t&&r.start<=t.start&&(t.parent=r.id)}else if(t.kind==="queue-active"||t.kind==="queue-completed"||t.kind==="queue-failed"){const r=W.get(e);r&&r!==t&&r.start<=t.start&&(t.parent=r.id)}}{const t=new Map(w.map(e=>[e.id,e]));for(const e of w){if(!e.parent||!St.has(e.kind??"")||e.durationMs===void 0)continue;const r=t.get(e.parent);if(!r||r.kind!=="span"||!((r.durationMs??0)>0))continue;const n=Math.round(e.start+e.durationMs-(r.start+r.durationMs));if(n<OUTLIVED_PARENT_MIN_MS)continue;e.outlivedParentMs=n;const s=r.leftRunning??{count:0,longestMs:0};r.leftRunning={count:s.count+1,longestMs:Math.max(s.longestMs,n)}}for(const e of w){const r=[];e.leftRunning&&r.push(`ended before ${e.leftRunning.count===1?"a call":`${e.leftRunning.count} calls`} it started had finished \u2014 ${e.leftRunning.count===1?"it":"the longest"} ran on ${e.leftRunning.longestMs}ms (a timeout that gave up, or work not awaited)`),e.outlivedParentMs!==void 0&&r.push(`ran on ${e.outlivedParentMs}ms after the span that started it had ended`),r.length>0&&(e.detail=[e.detail,...r].filter(Boolean).join(" \xB7 "))}}let g=w;{const t=new Map;for(const r of g)r.kind==="fetch-start"&&t.set(r.id,r);const e=new Map;for(const r of g){if(r.kind!=="fetch-done"&&r.kind!=="fetch-error")continue;const n=[...t.values()].find(k=>k.requestId&&k.requestId===r.requestId)?.id,s=n?t.get(n):void 0;if(!s)continue;const c=r.fetchStartedAt??s.start;s.title=r.title,s.severity=r.severity,s.durationMs=r.durationMs??Math.max(0,r.t-c),s.kind="fetch",r.detail&&!s.detail&&(s.detail=r.detail),e.set(r.id,s.id)}if(e.size>0){g=g.filter(r=>!e.has(r.id));for(const r of g)for(r.fetchDoneId&&e.has(r.fetchDoneId)&&(r.fetchDoneId=e.get(r.fetchDoneId));r.parent&&e.has(r.parent);)r.parent=e.get(r.parent)}}const L=$(t=>!!t.commitId&&(t.kind==="render"||t.kind==="effect-run"||t.kind==="render-commit-truncated"),"commitMember"),z=$(t=>[...new Set(t)],"uniq"),H=$(t=>z(t.map(e=>e.component).filter(e=>!!e)),"named"),i=$(t=>t.length<=2?t.join(" + "):`${t[0]} + ${t.length-1} more`,"nameList"),y=$(t=>{const e=new Map;for(const r of t)r.component&&e.set(r.component,(e.get(r.component)??0)+1);return[...e].map(([r,n])=>n>1?`${r} \xD7${n}`:r).join(", ")},"tally"),A=$(t=>{if(!t)return"effect";const e=/([^/\\]+?):(\d+)(?::\d+)?$/.exec(t);return e?`${e[1]}:${e[2]}`:t},"shortHook"),R=$(t=>`${A(t.hook)}${t.cleanup?" (cleanup)":""}`,"hookLabel"),P=$(t=>{const e=Math.min(...t.map(n=>n.start)),r=Math.max(...t.map(n=>n.start+(n.durationMs??0)));return{start:e,durationMs:r-e}},"extent"),V=$(t=>(delete t.component,delete t.why,delete t.phase,delete t.hook,delete t.cleanup,delete t.renderTotal,delete t.renderPublished,t),"asGroup");function nt(t){const e=t[0],r=t.filter(B=>B.kind==="render"),n=t.filter(B=>B.kind==="effect-run"),s=t.find(B=>B.kind==="render-commit-truncated"),c=[...r].sort((B,Y)=>(Y.durationMs??0)-(B.durationMs??0)),k=c.filter(B=>(B.why??[]).some(Y=>Y!=="parent-render")),M=z(k.flatMap(B=>(B.why??[]).filter(Y=>Y!=="parent-render"))),u=H(k),d=r.filter(B=>B.phase==="mount"),h=r.filter(B=>B.phase!=="mount"&&!k.includes(B)),I=c[0]?.component??"view",S=r.length>0&&d.length===r.length,x=M.length?M.join(" + "):void 0,G=S?"mount":"update",_=u.length?`view update \xB7 ${i(u)} \u2190 ${x}`:S?`view mount \xB7 ${I}`:`view update \xB7 ${I}`,rt=s?.renderTotal??r.length,yt=[d.length?`mounted ${y(d)}`:"",h.length?`re-rendered ${y(h)}`:"",!u.length&&!S&&r.length?"trigger not recorded \u2014 every captured render came from its parent":"",s?.renderWalkStoppedAt!==void 0?`at least ${rt} renders (the walk stopped at ${s.renderWalkStoppedAt} fibers), ${s.renderPublished??r.length} recorded`:s?`${rt} renders, ${s.renderPublished??r.length} recorded (per-commit cap)`:`${r.length} render${r.length===1?"":"s"}`,n.length?`${n.length} effect${n.length===1?"":"s"}: ${n.map(R).join(", ")}`:""].filter(Boolean).join(" \xB7 "),dt=H(r);return V({...e,...P(t),kind:"view-update",title:_,detail:yt,commitId:e.commitId,viewPhase:G,...x?{cause:x}:{},causeComponents:u,components:dt,mounted:H(d),renderCount:rt,...s?.renderWalkStoppedAt!==void 0?{renderCountAtLeast:!0}:{},recordedRenders:r.length,effects:n.length,effectHooks:n.map(R),memberIds:t.map(B=>B.id),sig:`commit:${G}:${x??"-"}:${u.join(",")}:${dt.slice().sort().join(",")}`,severity:t.some(B=>B.severity==="error")?"error":e.severity})}T(nt,"ft"),$(nt,"viewUpdateNode");function st(t){const e=t[0],r=t.map(R);return V({...e,...P(t),kind:"commit-effects",title:t.length===1?`effect \xB7 ${r[0]}`:`effects \xB7 ${r[0]} + ${t.length-1} more`,detail:r.join(", "),commitId:e.commitId,effects:t.length,effectHooks:r,memberIds:t.map(n=>n.id),sig:`effects:${r.slice().sort().join(",")}`})}T(st,"lt"),$(st,"effectsNode");const $t=$(t=>z(t.map(e=>e==="state-update"?"state update":e==="fetch-start"?"request":e==="flow-origin"?"interaction":"response")).join(" + "),"describeInputs");function at(t,e){const r=t[0],n=t[t.length-1],s=t.length,c=r.detail,k=Math.min(...t.map(h=>h.start)),M=Math.max(...t.map(h=>h.start+(h.durationMs??0))),u=Math.round(t.reduce((h,I)=>h+(I.durationMs??0),0)/s*10)/10,d=Math.round((M-k)*10)/10;r.count=s,r.avgMs=u,r.wallMs=d,r.durationMs=M-k,r.items=t.slice(0,12).map(h=>({start:h.start-k,...h.durationMs!=null?{durationMs:h.durationMs}:{}})),r.memberIds=t.flatMap(h=>h.memberIds??[h.id]),r.title=`\xD7${s} ${r.title}`,t.some(h=>h.severity==="error")&&(r.severity="error"),r.kind==="view-update"?r.detail=[`${s} commits, ${e.length?`one per ${$t(e)}`:"back to back"}`,`avg ${u}ms \xB7 wall ${d}ms`,c??""].filter(Boolean).join(" \xB7 "):r.kind==="state-update"&&c&&n.detail?r.detail=`${s} updates in a row \xB7 wall ${d}ms \xB7 first ${c} \xB7 last ${n.detail}`:r.detail=[`${s} in a row \xB7 wall ${d}ms`,c??""].filter(Boolean).join(" \xB7 ")}T(at,"mt"),$(at,"collapseRepeat");const Q=[],Z=new Map,it=new Set;for(let t=0;t<g.length;t++){if(it.has(t))continue;const e=g[t];if(!L(e)){Q.push(e);continue}const r=[t];for(let c=t+1;c<g.length;c++){const k=g[c];if(k.group==="browser"){if(!L(k)||k.commitId!==e.commitId)break;r.push(c)}}for(const c of r)it.add(c);const n=r.map(c=>g[c]),s=n.some(c=>c.kind!=="effect-run")?nt(n):st(n);for(const c of n)c.id!==s.id&&Z.set(c.id,s.id);Q.push(s)}if(Z.size>0||Q.some(t=>t.kind==="view-update"||t.kind==="commit-effects")){g=Q;for(const t of g)for(;t.parent&&Z.has(t.parent);)t.parent=Z.get(t.parent)}{const t=new Map;for(const e of g)e.kind==="view-update"&&e.commitId&&!t.has(e.commitId)&&t.set(e.commitId,e);for(const e of g){if(e.kind!=="commit-effects"||e.parent||!e.commitId)continue;const r=t.get(e.commitId);r&&r.start<=e.start&&(e.parent=r.id)}}{const t=new Set(["state-update","fetch","fetch-start","fetch-done","fetch-error","flow-origin"]),e=g.map((u,d)=>u.group==="browser"?d:-1).filter(u=>u>=0),r=$(u=>`${u.kind}|${u.sig??u.title}`,"keyOf"),n=e.map(u=>r(g[u])),s=$((u,d,h)=>{for(let I=0;I<h;I++)if(n[u+I]!==n[d+I])return!1;return!0},"sameBlock"),c=$(u=>n[u].split("|")[0],"kindAt"),k=$(u=>{let d=0,h=1;for(let I=1;I<=4&&u+I<=n.length;I++){let S=1;for(;u+(S+1)*I<=n.length&&s(u,u+S*I,I);)S+=1;S>=3&&I*S>d*h&&(d=I,h=S)}return{k:d,r:h}},"bestBlockAt"),M=new Map;for(let u=0;u<n.length;){const{k:d,r:h}=k(u);if(d===0){u+=1;continue}const I=[...Array(d).keys()].find(x=>t.has(c(u+x)));if(I!==void 0&&I>0){const x=k(u+I);if(x.k===d&&x.r>=3&&x.r>=h-1){u+=I;continue}}const S=n.slice(u,u+d).map(x=>x.split("|")[0]).filter(x=>t.has(x));for(let x=0;x<d;x++){const G=[];for(let _=0;_<h;_++)G.push(g[e[u+x+_*d]]);at(G,S);for(const _ of G.slice(1))M.set(_.id,G[0].id)}u+=d*h}if(M.size>0){g=g.filter(u=>!M.has(u.id));for(const u of g)for(;u.parent&&M.has(u.parent);)u.parent=M.get(u.parent)}}{const t=new Map(g.map(e=>[e.id,e]));for(const e of g){const r=new Set([e.id]);let n=e;for(;n?.parent;){if(r.has(n.parent)){n.parent=void 0;break}r.add(n.parent),n=t.get(n.parent)}}}const ut=$(t=>{const e=new Map;for(const n of g){if(!n.sig||q(n)!==t||n.kind==="server-request"||n.kind==="gateway-request"||n.group==="browser")continue;const s=`${n.parent??"root"}|${n.kind}|${n.sig}`,c=e.get(s);c?c.push(n):e.set(s,[n])}const r=new Map;for(const n of e.values()){if(n.length<3)continue;n.sort((d,h)=>d.start-h.start);const s=n[0];let c=!1;for(let d=0;d+1<n.length;d++)if(n[d+1].start<n[d].start+(n[d].durationMs??0)){c=!0;break}const k=s.start,M=Math.max(...n.map(d=>d.start+(d.durationMs??0))),u=n.reduce((d,h)=>d+(h.durationMs??0),0);s.count=n.length,s.parallel=c,s.avgMs=Math.round(u/n.length*10)/10,s.wallMs=M-k,s.durationMs=M-k,s.title=`\xD7${n.length} ${s.title.replace(/\s*\((?:\d+ rows?, )?\d+ms\)$/,"")}`,s.detail=`${s.sig} \xD7${n.length} ${c?"\u2016 parallel":"\u21BB sequential loop"} \xB7 avg ${s.avgMs}ms \xB7 wall ${s.wallMs}ms`,s.items=n.slice(0,12).map(d=>({start:d.start-k,...d.durationMs!=null?{durationMs:d.durationMs}:{}})),s.memberIds=n.flatMap(d=>d.memberIds??[d.id]),n.some(d=>d.severity==="error")&&(s.severity="error");for(const d of n.slice(1))r.set(d.id,s.id)}if(r.size!==0){g=g.filter(n=>!r.has(n.id));for(const n of g)for(;n.parent&&r.has(n.parent);)n.parent=r.get(n.parent)}},"aggregatePass");ut(!0),ut(!1);for(const t of g){if(!q(t))continue;const e=t.durationMs??0;if(e<40)continue;const r=g.filter(M=>M.parent===t.id&&(M.durationMs??0)>0).map(M=>[M.start,M.start+(M.durationMs??0)]).sort((M,u)=>M[0]-u[0]);let n=0,s=-1,c=-1;for(const[M,u]of r)M>c?(c>s&&(n+=c-s),s=M,c=u):u>c&&(c=u);c>s&&(n+=c-s);const k=Math.max(0,e-n);(k>=50||k/e>=.7&&e>=40)&&(t.selfMs=k,t.detail=`\u26A0 cpu-heavy: ${k}ms self-time of ${e}ms${t.detail?" \xB7 "+t.detail:""}`)}return{events:g,...o?{sql:o}:{}}}T(buildFlowDetail,"buildFlowDetail"),$(buildFlowDetail,"buildFlowDetail");
1
+ "use strict";var wt=Object.defineProperty;var C=(i,h)=>wt(i,"name",{value:h,configurable:!0});var qt=Object.defineProperty,y=C((i,h)=>qt(i,"name",{value:h,configurable:!0}),"y");import{redactDeep as Mt,redactText as ot,redactUrlParams as It}from"./redact.js";import{templatisePath as pt}from"./route-template.js";import{SQL_ACCOUNT_KIND as xt,sqlAccountingOf as bt}from"./flow-segments.js";import{boundedClone as jt}from"@lensmcp/protocol-types";export function areaOf(i){const{source:h,category:o,title:w,kind:l}=i;return h==="ai"?"ai":l?.startsWith("memory")||l==="db-query"?"data":h==="gateway"||l==="gateway-request"?"gateway":l==="queue-process"||l==="queue-active"||l==="queue-completed"||l==="queue-failed"?"services":h==="db"||h==="redis"||h==="queue"||l==="redis-op"||l?.startsWith("queue-")?"data":h==="external"||l==="egress"?"network":h==="nestjs"||h==="nest"?/(?:Repository|Repo|Dao|Store|EntityManager|DataSource|QueryRunner|OrmClient)\./.test(w)?"data":"services":h==="valtio"?"state":o==="network"?"network":"browser"}C(areaOf,"areaOf"),y(areaOf,"areaOf");const ft=240,St=new Set(["systemPrompt","prompt","prompts","messages","completion","completions","input","output","draft","text","content","result","arguments","params"]),Bt=new Set(["tenantId","caller","userId","accountId","email","subject"]),At=8;function mt(i){const h=tt(i,0);return jt(Mt({redacted:!0,...h}),{rawByteLimit:16*1024}).value}C(mt,"jt"),y(mt,"aiProjection");function tt(i,h){if(typeof i=="string")return ht(i);if(i===null||typeof i!="object")return i;if(h>=At)return;if(Array.isArray(i))return i.slice(0,32).map(w=>tt(w,h+1));const o={};for(const[w,l]of Object.entries(i))if(!Bt.has(w)){if(St.has(w)){typeof l=="string"?o[`${w}Chars`]=l.length:Array.isArray(l)?o[`${w}Count`]=l.length:l!=null&&(o[`${w}Present`]=!0);continue}o[w]=tt(l,h+1)}return o}C(tt,"rt"),y(tt,"projectAi");function ht(i){return i.length<=ft?ot(i):`${ot(i.slice(0,ft))}\u2026`}C(ht,"vt"),y(ht,"clipText");export function httpFacts(i,h){const o=y(M=>typeof M=="string"&&M.length>0?M:void 0,"str"),w=typeof h.status=="number"?h.status:void 0,l=y(M=>It(M.split("?")[0]??M)||"/","pathOf"),D=y((M,$,b={})=>({...M?{method:M.toUpperCase()}:{},...$?{rawPath:$,route:pt($)}:{},...w!==void 0?{status:w}:{},...b}),"facts");if(i==="gateway-request"){const M=o(h.url);return D(o(h.method),M?l(M):void 0,{...o(h.host)?{host:o(h.host)}:{},...o(h.caller)?{caller:o(h.caller)}:{}})}if(i==="egress"){const M=o(h.path),$=o(h.exchangeId);return D(o(h.method)??"GET",M?l(M):void 0,{...o(h.host)?{host:o(h.host)}:{},...$?{exchangeId:$}:{}})}if(i==="fetch-start"||i==="fetch-done"||i==="fetch-error"){const M=o(h.href)??o(h.url);let $,b;if(M)try{const m=new URL(M,"http://relative.invalid");$=l(m.pathname),m.hostname!=="relative.invalid"&&(b=m.hostname)}catch{}return D(o(h.method)??"GET",$,b?{host:b}:{})}if(i==="ai-call")return{...w!==void 0?{status:w}:{},...h.stream===!0?{streamed:!0}:{}};const f=h.request;if(f&&typeof f=="object"){const M=f,$=o(M.route),b=o(M.method);if(!$&&!b)return{};const m=typeof M.status=="number"?M.status:void 0,T=$?l($):void 0;return{...b?{method:b.toUpperCase()}:{},...T?{rawPath:T,route:T.includes(":")?T:pt(T)}:{},...m!==void 0?{status:m}:{}}}return{}}C(httpFacts,"httpFacts"),y(httpFacts,"httpFacts");export function trimFlowEvent(i,h={}){const o=i.raw??{},w=o.render??{},l=o.span??{},D=o.request??{},f=y(u=>typeof u=="number"?u:void 0,"num"),M=o.loop??{},$=o.effect??{},b=f(o.durationMs)??f(l.durationMs)??f(D.durationMs)??f(M.durationMs)??f(w.actualDurationMs)??f($.durationMs),m=typeof o.kind=="string"?o.kind:void 0,T=m==="fetch-done"||m==="fetch-error",_=f(w.commitTime),z=m==="render"&&_!==void 0&&Math.abs(_-i.timestamp)<6e4,et=T?i.timestamp:z?_:f(o.startedAt)??f(l.startTime)??f(D.startedAt)??f(M.startedAt)??(b!==void 0?i.timestamp-b:i.timestamp);let S;if(typeof o.query=="string"){const u=Array.isArray(o.params)?` [${o.params.join(", ")}]`:"",k=typeof o.result=="string"?` \u2192 ${o.result}`:"";S=o.query+u+k}else if(typeof o.command=="string"){const u=typeof o.value=="string"?` \u2192 ${o.value}`:o.hit===!1?" \u2192 (miss)":"";S=o.command+u}else if(m==="state-update"){const u=o.update??{};let k="";try{k=JSON.stringify(u.preview)}catch{}S=`${u.storeId??""}.${u.path??""} = ${k}`}else if(m==="queue-completed"&&typeof o.returned=="string")S=`returned ${o.returned}`;else if(m==="queue-enqueued")S=`${o.job??"job"}#${o.jobId??"?"} \u2192 ${o.queue??""}${typeof o.data=="string"?" "+o.data:""}`;else if(m==="log"){const u=D.error??{},k=typeof u.stack=="string"?u.stack:typeof o.text=="string"?o.text:void 0;k&&k!==i.title&&(S=k)}let P,G,H,Q;if(m==="span"){const u=l.outcome;if(P=u==="threw"||u==="returned"?u:l.status==="error"?"threw":l.status==="ok"?"returned":void 0,P==="threw"){const R=l.error??{},O=typeof R.name=="string"?R.name:void 0,K=typeof R.message=="string"?R.message:typeof i.message=="string"?i.message:void 0;H=O,G=ot([O,K].filter(Boolean).join(": "))||void 0}const k=typeof l.args=="string"?l.args:void 0,A=typeof l.result=="string"?l.result:void 0;if(k!==void 0||A!==void 0){Q=[...k!==void 0?["args"]:[],...A!==void 0?["result"]:[]];const R=y(O=>O.length>gt?`${O.slice(0,gt)}\u2026`:O,"short");S=[k!==void 0?`args ${R(k)}`:"",A!==void 0?`returned ${R(A)}`:""].filter(Boolean).join(" \u2192 ")}}let W;if(m==="gateway-request")W=`${o.host??""}${String(o.url??"").split("?")[0]}`;else if(m==="fetch-start"||m==="fetch-done"||m==="fetch-error")try{const u=new URL(String(o.href??o.url??""));W=`${u.hostname}${u.pathname}`}catch{}let U;if(m==="gateway-request"&&Array.isArray(o.steps))U=o.steps.map(u=>{const k=[String(u.step)];return u.project&&k.push(String(u.project)),u.prefix&&k.push(String(u.prefix)),u.mode&&k.push(String(u.mode)+(u.ok===!1?" \u2717":u.ok===!0?" \u2713":"")),u.caller&&k.push("by "+String(u.caller)),u.pod&&k.push(String(u.pod)),typeof u.atMs=="number"&&k.push(`@${u.atMs}ms`),k.join(" ")}),S=U.map(u=>u.replace(/ @\d+ms$/,"")).join(" \u2192 ");else if(m==="egress")S=`${o.method??"GET"} ${o.host??""} \u2192 ${o.status??"?"}`;else if(i.source==="ai"){if(m==="ai-call"){const u=o.usage??{},k=u.promptTokens!==void 0||u.completionTokens!==void 0?` \xB7 ${f(u.promptTokens)??"?"}\u2192${f(u.completionTokens)??"?"} tok`:"",A=o.status!==void 0?` \xB7 ${String(o.status)}`:o.error?" \xB7 failed":"",R=f(o.toolCallCount)?` \xB7 ${f(o.toolCallCount)} tool call${f(o.toolCallCount)===1?"":"s"}`:"",O=f(o.durationMs)!==void 0?` \xB7 ${(f(o.durationMs)/1e3).toFixed(1)}s`:"";S=`${o.provider??""}/${o.model??"?"}${k}${A}${R}${O}${o.stream===!0?" \xB7 stream":""}`}else if(m==="ai-round"){const u=o.model??{},k=o.usage??{},A=Array.isArray(o.toolCalls)?o.toolCalls:[],R=`${f(k.promptTokens)??"?"}\u2192${f(k.completionTokens)??"?"} tok`,O=A.length?` \xB7 ${A.length} tool call${A.length===1?"":"s"}`:"",K=f(o.durationMs)!==void 0?` \xB7 ${(f(o.durationMs)/1e3).toFixed(1)}s`:"";S=`${u.provider??""}/${u.model??""} \xB7 ${R}${O}${K}`}else if(m==="ai-turn-start"){const u=Array.isArray(o.tools)?o.tools:[];S=`skill ${o.skill??""} \xB7 ${o.output??""}${u.length?" \xB7 tools: "+u.join(", "):""}`}else if(m==="ai-tool-call"){const u=o.call??{},k=o.result??{},A=f(o.durationMs)!==void 0?` \xB7 ${(f(o.durationMs)/1e3).toFixed(1)}s`:"";S=`${u.name??"tool"} ${k.error!=null?"\u2717 "+String(k.error):"\u2713"}${A}`}else if(m==="ai-turn-end"){const u=o.usage??{},k=f(o.rounds)!==void 0?` \xB7 ${f(o.rounds)} round${f(o.rounds)===1?"":"s"}`:"",A=f(o.durationMs)!==void 0?` \xB7 ${(f(o.durationMs)/1e3).toFixed(1)}s`:"";S=`${o.ok===!1?"FAILED":"ok"} \xB7 ${f(u.promptTokens)??"?"}+${f(u.completionTokens)??"?"} tok${k}${A}`}}let L;m==="db-query"&&typeof o.query=="string"?L=o.query:m==="redis-op"?L=`${o.op??""} ${String(o.key??"").replace(/\d+/g,"#")}`:m==="egress"?L=`${o.method??"GET"} ${o.host??""}`:m==="ai-call"?L=`ai ${o.provider??""} ${o.model??""} ${o.api??""}`:m==="queue-enqueued"?L=`enqueue ${o.queue??""}`:m==="span"&&typeof l.name=="string"?L=l.name:m==="memory-mutation"&&(L=i.title);const N=i.context??{},q=w.commitId??$.commitId??o.commitId,V=Array.isArray(w.why)?w.why.map(u=>typeof u?.type=="string"?u.type:void 0).filter(u=>!!u):[];return{id:i.id,t:i.timestamp,start:et,...L?{sig:L}:{},...W?{urlKey:W}:{},...httpFacts(m,o),...typeof o.queue=="string"?{queue:o.queue}:{},...o.jobId!=null?{jobId:String(o.jobId)}:{},source:i.source,category:i.category,severity:i.severity,title:P==="threw"&&typeof l.name=="string"?`${l.name} \u2014 threw${H?` ${H}`:""}${b!==void 0?` after ${b}ms`:""}`:i.title,kind:m,area:areaOf({source:i.source,category:i.category,title:i.title,kind:m}),...P?{outcome:P}:{},...G?{error:G}:{},...Q?{captured:Q}:{},...typeof l.role=="string"?{role:l.role}:{},...typeof l.spanId=="string"?{spanId:l.spanId}:{},...typeof l.parentSpanId=="string"?{parentSpanId:l.parentSpanId}:{},...m==="log"&&typeof o.level=="string"?{level:o.level}:{},...m==="log"&&typeof o.logger=="string"?{logger:o.logger}:{},...m==="log"&&typeof o.stream=="string"?{stream:o.stream}:{},...typeof N.requestId=="string"?{requestId:N.requestId}:{},...typeof N.parentRequestId=="string"?{parentRequestId:N.parentRequestId}:{},...typeof q=="string"?{commitId:q}:{},...typeof w.componentName=="string"?{component:w.componentName}:{},...typeof w.phase=="string"?{phase:w.phase}:{},...V.length?{why:V}:{},...m==="effect-run"&&typeof $.hookLogicalId=="string"?{hook:$.hookLogicalId}:{},...m==="effect-run"&&$.cleanupRan===!0?{cleanup:!0}:{},...m==="render-commit-truncated"?{renderTotal:f(o.total),renderPublished:f(o.published),...f(o.walkStoppedAt)!==void 0?{renderWalkStoppedAt:f(o.walkStoppedAt)}:{}}:{},...typeof N.projectName=="string"?{project:N.projectName}:typeof o.project=="string"?{project:o.project}:{},...b!==void 0?{durationMs:b}:{},...T&&f(o.startedAt)!==void 0?{fetchStartedAt:f(o.startedAt)}:{},...i.source==="ai"?{ai:h.includeRaw?o:mt(o)}:{},...S?{detail:S}:{},...U?{steps:U}:{}}}C(trimFlowEvent,"trimFlowEvent"),y(trimFlowEvent,"trimFlowEvent");const gt=300;export const OUTLIVED_PARENT_MIN_MS=250;const Rt=new Set(["egress","db-query","redis-op","ai-call","span","gateway-request","server-request"]),$t=1;function yt(i){return i==="flow-origin"?0:i?.endsWith("-start")?1:i==="gateway-request"?2:i==="server-request"?3:i==="span"?4:i==="render"||i==="render-commit-truncated"?6:i==="effect-run"?7:5}C(yt,"Rt"),y(yt,"kindRank");function J(i){return i.kind==="span"&&i.role==="controller"?3.5:i.kind==="queue-process"?3:yt(i.kind)}C(J,"Z"),y(J,"causalRank");export function buildFlowDetail(i,h={}){const o=bt(i),w=i.slice().filter(t=>{const r=t.raw??{},e=typeof r.kind=="string"?r.kind:"";if(e==="subscription-added"||e==="subscription-removed"||e==="hook-run"||e==="store-created"||e==="singleton-instance"||e===xt)return!1;const n=r.span;return!(typeof n?.name=="string"&&n.name.startsWith("nest.request "))}).map(t=>trimFlowEvent(t,h)),l=new Set;for(let t=w.length-1;t>=0;t--)l.has(w[t].id)?w.splice(t,1):l.add(w[t].id);const D=new Map;for(const t of w)(t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&!D.has(t.requestId)&&D.set(t.requestId,t.start);const f=y(t=>t.source!=="react"&&t.source!=="valtio"&&t.requestId&&D.has(t.requestId)?D.get(t.requestId):t.start,"anchorOf");w.sort((t,r)=>f(t)-f(r)||t.start-r.start||J(t)-J(r)||(r.durationMs??0)-(t.durationMs??0)||t.t-r.t);const M=y(t=>(t.kind==="span"||t.kind==="server-request"||t.kind==="gateway-request"||t.kind==="queue-process")&&(t.durationMs??0)>0,"spanLike"),$=w;for(const t of $)t.group=t.source==="react"||t.source==="valtio"||t.source==="client-runtime"||t.source==="visual"?"browser":"server";const b=new Map;for(const t of $)if((t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&t.project){const r=b.get(t.requestId)??[];r.push({project:t.project,start:t.start,end:t.start+(t.durationMs??0)}),b.set(t.requestId,r)}const m=y((t,r)=>{const e=b.get(t);if(e?.length)return e.every(n=>n.project===e[0].project)?e[0].project:e.filter(n=>n.start<=r+1&&n.end>=r-1).sort((n,s)=>s.start-n.start)[0]?.project},"projectOf");for(const t of $)if(!t.project&&t.source==="nestjs"&&t.requestId){const r=m(t.requestId,t.start);r&&(t.project=r)}const T=new Map;for(const t of $)t.spanId&&T.set(t.spanId,t);const _=y((t,r)=>{let e=t.parentSpanId?T.get(t.parentSpanId):void 0;for(let n=0;e&&n<64;n++){if(e===r)return!0;e=e.parentSpanId?T.get(e.parentSpanId):void 0}return!1},"inside");for(const t of $){const r=t.parentSpanId?T.get(t.parentSpanId):void 0;if(r&&r!==t&&r.group===t.group&&r.requestId===t.requestId){t.parent=r.id;continue}let e;const n=t.requestId;for(const s of $){if(s===t||!M(s)||s.group!==t.group||s.requestId!==n)continue;const a=s.project,g=t.project;if(s.kind!=="gateway-request"&&t.kind!=="gateway-request"&&a!==void 0&&g!==void 0&&a!==g)continue;const v=s.durationMs??0,d=t.durationMs??0,c=Math.abs(s.start-t.start)<=$t,p=J(s),I=J(t),B=s.start<=t.start;if(!(s.start+v>t.start&&(B||c&&p<I)&&(!c||(p!==I?p<I:B&&v>d))))continue;const x=e?J(e):-1,E=e?Math.abs(s.start-e.start)<=$t:!1,F=e&&E&&p===x?_(s,e)?1:_(e,s)?-1:0:0;(!e||!E&&s.start>e.start||E&&p>x||F>0||F===0&&E&&p===x&&(s.durationMs??0)<(e.durationMs??0))&&(e=s)}e&&(t.parent=e.id)}for(const t of $)delete t.spanId,delete t.parentSpanId;{const t=new Set($.map(a=>a.id)),r=new Set,e=new Map,n=[],s=y(a=>{const g=[a];for(;g.length;){const v=g.pop();n.push(v),r.add(v.id);const d=e.get(v.id);if(d){e.delete(v.id);for(let c=d.length-1;c>=0;c--)g.push(d[c])}}},"place");for(const a of $)if(a.parent&&a.parent!==a.id&&t.has(a.parent)&&!r.has(a.parent)){const g=e.get(a.parent)??[];g.push(a),e.set(a.parent,g)}else s(a);for(const a of $)r.has(a.id)||(n.push(a),r.add(a.id));for(let a=0;a<n.length;a++)$[a]=n[a]}const z=new Map;for(const t of $){if(!t.requestId)continue;const r=z.get(t.requestId);r?r.push(t):z.set(t.requestId,[t])}const et=new Map($.map(t=>[t.id,t])),S=y((t,r)=>{const e=(z.get(t)??[]).filter(n=>M(n)&&n.start<=r&&n.start+(n.durationMs??0)>=r);if(e.length!==0)return e.sort((n,s)=>s.start-n.start||(n.durationMs??0)-(s.durationMs??0)),e[0]},"callerNodeFor");for(const t of $){if(!t.parentRequestId||t.kind!=="server-request"&&t.kind!=="gateway-request")continue;const r=t.parent?et.get(t.parent):void 0;if(r&&r.requestId===t.requestId)continue;const e=S(t.parentRequestId,t.start);e&&e!==t&&e.start<=t.start&&(t.parent=e.id)}const P=$,G=new Map;for(const t of P)t.kind==="gateway-request"&&t.requestId&&!G.has(t.requestId)&&G.set(t.requestId,t);for(const t of P)if(t.group==="server"&&!t.parent&&t.requestId&&t.kind!=="gateway-request"){const r=G.get(t.requestId);r&&r!==t&&r.start<=t.start&&(t.parent=r.id)}const H=new Set,Q=new Set,W=[];for(const t of P){if(t.kind!=="gateway-request")continue;if(!t.requestId){W.push(t);continue}const r=z.get(t.requestId)??[];if(r.filter(s=>s.kind==="gateway-request").sort((s,a)=>s.start-a.start)[0]!==t)continue;const e=r.find(s=>s.kind==="fetch-start"),n=r.find(s=>s.kind==="fetch-done"||s.kind==="fetch-error");if(!e&&!n){W.push(t);continue}e&&(t.fetchStartId=e.id,H.add(e.id)),n&&(t.fetchDoneId=n.id,Q.add(n.id))}const U=new Map;for(const t of P){if(!t.urlKey)continue;const r=U.get(t.urlKey)??{gws:[],starts:[],dones:[]};t.kind==="gateway-request"?W.includes(t)&&r.gws.push(t):t.kind==="fetch-start"?H.has(t.id)||r.starts.push(t):(t.kind==="fetch-done"||t.kind==="fetch-error")&&(Q.has(t.id)||r.dones.push(t)),U.set(t.urlKey,r)}for(const{gws:t,starts:r,dones:e}of U.values()){t.sort((s,a)=>s.start-a.start),r.sort((s,a)=>s.start-a.start);const n=new Set;t.forEach((s,a)=>{const g=r[a];g&&(s.fetchStartId=g.id);const v=g?g.t:s.start;let d,c=1/0;for(const p of e){if(n.has(p.id))continue;const I=p.fetchStartedAt??p.start-(p.durationMs??0),B=Math.abs(I-v);B<c&&(c=B,d=p)}d&&(s.fetchDoneId=d.id,n.add(d.id))})}const L=new Map,N=new Map;for(const t of P)!t.queue||!t.jobId||(t.kind==="queue-enqueued"&&L.set(`${t.queue}#${t.jobId}`,t),t.kind==="queue-process"&&N.set(`${t.queue}#${t.jobId}`,t));for(const t of P){if(!t.queue||!t.jobId)continue;const r=`${t.queue}#${t.jobId}`;if(t.kind==="queue-process"&&!t.parent){const e=L.get(r);e&&e!==t&&e.start<=t.start&&(t.parent=e.id)}else if(t.kind==="queue-active"||t.kind==="queue-completed"||t.kind==="queue-failed"){const e=N.get(r);e&&e!==t&&e.start<=t.start&&(t.parent=e.id)}}{const t=new Map($.map(r=>[r.id,r]));for(const r of $){if(!r.parent||!Rt.has(r.kind??"")||r.durationMs===void 0)continue;const e=t.get(r.parent);if(!e||e.kind!=="span"||!((e.durationMs??0)>0))continue;const n=Math.round(r.start+r.durationMs-(e.start+e.durationMs));if(n<OUTLIVED_PARENT_MIN_MS)continue;r.outlivedParentMs=n;const s=e.leftRunning??{count:0,longestMs:0};e.leftRunning={count:s.count+1,longestMs:Math.max(s.longestMs,n)}}for(const r of $){const e=[];r.leftRunning&&e.push(`ended before ${r.leftRunning.count===1?"a call":`${r.leftRunning.count} calls`} it started had finished \u2014 ${r.leftRunning.count===1?"it":"the longest"} ran on ${r.leftRunning.longestMs}ms (a timeout that gave up, or work not awaited)`),r.outlivedParentMs!==void 0&&e.push(`ran on ${r.outlivedParentMs}ms after the span that started it had ended`),e.length>0&&(r.detail=[r.detail,...e].filter(Boolean).join(" \xB7 "))}}let q=$;{const t=new Map;for(const e of q)e.kind==="fetch-start"&&t.set(e.id,e);const r=new Map;for(const e of q){if(e.kind!=="fetch-done"&&e.kind!=="fetch-error")continue;const n=[...t.values()].find(g=>g.requestId&&g.requestId===e.requestId)?.id,s=n?t.get(n):void 0;if(!s)continue;const a=e.fetchStartedAt??s.start;s.title=e.title,s.severity=e.severity,s.durationMs=e.durationMs??Math.max(0,e.t-a),s.kind="fetch",e.detail&&!s.detail&&(s.detail=e.detail),r.set(e.id,s.id)}if(r.size>0){q=q.filter(e=>!r.has(e.id));for(const e of q)for(e.fetchDoneId&&r.has(e.fetchDoneId)&&(e.fetchDoneId=r.get(e.fetchDoneId));e.parent&&r.has(e.parent);)e.parent=r.get(e.parent)}}const V=y(t=>!!t.commitId&&(t.kind==="render"||t.kind==="effect-run"||t.kind==="render-commit-truncated"),"commitMember"),u=y(t=>[...new Set(t)],"uniq"),k=y(t=>u(t.map(r=>r.component).filter(r=>!!r)),"named"),A=y(t=>t.length<=2?t.join(" + "):`${t[0]} + ${t.length-1} more`,"nameList"),R=y(t=>{const r=new Map;for(const e of t)e.component&&r.set(e.component,(r.get(e.component)??0)+1);return[...r].map(([e,n])=>n>1?`${e} \xD7${n}`:e).join(", ")},"tally"),O=y(t=>{if(!t)return"effect";const r=/([^/\\]+?):(\d+)(?::\d+)?$/.exec(t);return r?`${r[1]}:${r[2]}`:t},"shortHook"),K=y(t=>`${O(t.hook)}${t.cleanup?" (cleanup)":""}`,"hookLabel"),nt=y(t=>{const r=Math.min(...t.map(n=>n.start)),e=Math.max(...t.map(n=>n.start+(n.durationMs??0)));return{start:r,durationMs:e-r}},"extent"),st=y(t=>(delete t.component,delete t.why,delete t.phase,delete t.hook,delete t.cleanup,delete t.renderTotal,delete t.renderPublished,t),"asGroup");function at(t){const r=t[0],e=t.filter(j=>j.kind==="render"),n=t.filter(j=>j.kind==="effect-run"),s=t.find(j=>j.kind==="render-commit-truncated"),a=[...e].sort((j,Y)=>(Y.durationMs??0)-(j.durationMs??0)),g=a.filter(j=>(j.why??[]).some(Y=>Y!=="parent-render")),v=u(g.flatMap(j=>(j.why??[]).filter(Y=>Y!=="parent-render"))),d=k(g),c=e.filter(j=>j.phase==="mount"),p=e.filter(j=>j.phase!=="mount"&&!g.includes(j)),I=a[0]?.component??"view",B=e.length>0&&c.length===e.length,x=v.length?v.join(" + "):void 0,E=B?"mount":"update",F=d.length?`view update \xB7 ${A(d)} \u2190 ${x}`:B?`view mount \xB7 ${I}`:`view update \xB7 ${I}`,rt=s?.renderTotal??e.length,kt=[c.length?`mounted ${R(c)}`:"",p.length?`re-rendered ${R(p)}`:"",!d.length&&!B&&e.length?"trigger not recorded \u2014 every captured render came from its parent":"",s?.renderWalkStoppedAt!==void 0?`at least ${rt} renders (the walk stopped at ${s.renderWalkStoppedAt} fibers), ${s.renderPublished??e.length} recorded`:s?`${rt} renders, ${s.renderPublished??e.length} recorded (per-commit cap)`:`${e.length} render${e.length===1?"":"s"}`,n.length?`${n.length} effect${n.length===1?"":"s"}: ${n.map(K).join(", ")}`:""].filter(Boolean).join(" \xB7 "),lt=k(e);return st({...r,...nt(t),kind:"view-update",title:F,detail:kt,commitId:r.commitId,viewPhase:E,...x?{cause:x}:{},causeComponents:d,components:lt,mounted:k(c),renderCount:rt,...s?.renderWalkStoppedAt!==void 0?{renderCountAtLeast:!0}:{},recordedRenders:e.length,effects:n.length,effectHooks:n.map(K),memberIds:t.map(j=>j.id),sig:`commit:${E}:${x??"-"}:${d.join(",")}:${lt.slice().sort().join(",")}`,severity:t.some(j=>j.severity==="error")?"error":r.severity})}C(at,"pt"),y(at,"viewUpdateNode");function it(t){const r=t[0],e=t.map(K);return st({...r,...nt(t),kind:"commit-effects",title:t.length===1?`effect \xB7 ${e[0]}`:`effects \xB7 ${e[0]} + ${t.length-1} more`,detail:e.join(", "),commitId:r.commitId,effects:t.length,effectHooks:e,memberIds:t.map(n=>n.id),sig:`effects:${e.slice().sort().join(",")}`})}C(it,"mt"),y(it,"effectsNode");const vt=y(t=>u(t.map(r=>r==="state-update"?"state update":r==="fetch-start"?"request":r==="flow-origin"?"interaction":"response")).join(" + "),"describeInputs");function dt(t,r){const e=t[0],n=t[t.length-1],s=t.length,a=e.detail,g=Math.min(...t.map(p=>p.start)),v=Math.max(...t.map(p=>p.start+(p.durationMs??0))),d=Math.round(t.reduce((p,I)=>p+(I.durationMs??0),0)/s*10)/10,c=Math.round((v-g)*10)/10;e.count=s,e.avgMs=d,e.wallMs=c,e.durationMs=v-g,e.items=t.slice(0,12).map(p=>({start:p.start-g,...p.durationMs!=null?{durationMs:p.durationMs}:{}})),e.memberIds=t.flatMap(p=>p.memberIds??[p.id]),e.title=`\xD7${s} ${e.title}`,t.some(p=>p.severity==="error")&&(e.severity="error"),e.kind==="view-update"?e.detail=[`${s} commits, ${r.length?`one per ${vt(r)}`:"back to back"}`,`avg ${d}ms \xB7 wall ${c}ms`,a??""].filter(Boolean).join(" \xB7 "):e.kind==="state-update"&&a&&n.detail?e.detail=`${s} updates in a row \xB7 wall ${c}ms \xB7 first ${a} \xB7 last ${n.detail}`:e.detail=[`${s} in a row \xB7 wall ${c}ms`,a??""].filter(Boolean).join(" \xB7 ")}C(dt,"ht"),y(dt,"collapseRepeat");const Z=[],X=new Map,ut=new Set;for(let t=0;t<q.length;t++){if(ut.has(t))continue;const r=q[t];if(!V(r)){Z.push(r);continue}const e=[t];for(let a=t+1;a<q.length;a++){const g=q[a];if(g.group==="browser"){if(!V(g)||g.commitId!==r.commitId)break;e.push(a)}}for(const a of e)ut.add(a);const n=e.map(a=>q[a]),s=n.some(a=>a.kind!=="effect-run")?at(n):it(n);for(const a of n)a.id!==s.id&&X.set(a.id,s.id);Z.push(s)}if(X.size>0||Z.some(t=>t.kind==="view-update"||t.kind==="commit-effects")){q=Z;for(const t of q)for(;t.parent&&X.has(t.parent);)t.parent=X.get(t.parent)}{const t=new Map;for(const r of q)r.kind==="view-update"&&r.commitId&&!t.has(r.commitId)&&t.set(r.commitId,r);for(const r of q){if(r.kind!=="commit-effects"||r.parent||!r.commitId)continue;const e=t.get(r.commitId);e&&e.start<=r.start&&(r.parent=e.id)}}{const t=new Set(["state-update","fetch","fetch-start","fetch-done","fetch-error","flow-origin"]),r=q.map((d,c)=>d.group==="browser"?c:-1).filter(d=>d>=0),e=y(d=>`${d.kind}|${d.sig??d.title}`,"keyOf"),n=r.map(d=>e(q[d])),s=y((d,c,p)=>{for(let I=0;I<p;I++)if(n[d+I]!==n[c+I])return!1;return!0},"sameBlock"),a=y(d=>n[d].split("|")[0],"kindAt"),g=y(d=>{let c=0,p=1;for(let I=1;I<=4&&d+I<=n.length;I++){let B=1;for(;d+(B+1)*I<=n.length&&s(d,d+B*I,I);)B+=1;B>=3&&I*B>c*p&&(c=I,p=B)}return{k:c,r:p}},"bestBlockAt"),v=new Map;for(let d=0;d<n.length;){const{k:c,r:p}=g(d);if(c===0){d+=1;continue}const I=[...Array(c).keys()].find(x=>t.has(a(d+x)));if(I!==void 0&&I>0){const x=g(d+I);if(x.k===c&&x.r>=3&&x.r>=p-1){d+=I;continue}}const B=n.slice(d,d+c).map(x=>x.split("|")[0]).filter(x=>t.has(x));for(let x=0;x<c;x++){const E=[];for(let F=0;F<p;F++)E.push(q[r[d+x+F*c]]);dt(E,B);for(const F of E.slice(1))v.set(F.id,E[0].id)}d+=c*p}if(v.size>0){q=q.filter(d=>!v.has(d.id));for(const d of q)for(;d.parent&&v.has(d.parent);)d.parent=v.get(d.parent)}}{const t=new Map(q.map(r=>[r.id,r]));for(const r of q){const e=new Set([r.id]);let n=r;for(;n?.parent;){if(e.has(n.parent)){n.parent=void 0;break}e.add(n.parent),n=t.get(n.parent)}}}const ct=y(t=>{const r=new Map;for(const n of q){if(!n.sig||M(n)!==t||n.kind==="server-request"||n.kind==="gateway-request"||n.group==="browser")continue;const s=`${n.parent??"root"}|${n.kind}|${n.sig}`,a=r.get(s);a?a.push(n):r.set(s,[n])}const e=new Map;for(const n of r.values()){if(n.length<3)continue;n.sort((c,p)=>c.start-p.start);const s=n[0];let a=!1;for(let c=0;c+1<n.length;c++)if(n[c+1].start<n[c].start+(n[c].durationMs??0)){a=!0;break}const g=s.start,v=Math.max(...n.map(c=>c.start+(c.durationMs??0))),d=n.reduce((c,p)=>c+(p.durationMs??0),0);s.count=n.length,s.parallel=a,s.avgMs=Math.round(d/n.length*10)/10,s.wallMs=v-g,s.durationMs=v-g,s.title=`\xD7${n.length} ${s.title.replace(/\s*\((?:\d+ rows?, )?\d+ms\)$/,"")}`,s.detail=`${s.sig} \xD7${n.length} ${a?"\u2016 parallel":"\u21BB sequential loop"} \xB7 avg ${s.avgMs}ms \xB7 wall ${s.wallMs}ms`,s.items=n.slice(0,12).map(c=>({start:c.start-g,...c.durationMs!=null?{durationMs:c.durationMs}:{}})),s.memberIds=n.flatMap(c=>c.memberIds??[c.id]),n.some(c=>c.severity==="error")&&(s.severity="error");for(const c of n.slice(1))e.set(c.id,s.id)}if(e.size!==0){q=q.filter(n=>!e.has(n.id));for(const n of q)for(;n.parent&&e.has(n.parent);)n.parent=e.get(n.parent)}},"aggregatePass");ct(!0),ct(!1);for(const t of q){if(!M(t))continue;const r=t.durationMs??0;if(r<40)continue;const e=q.filter(v=>v.parent===t.id&&(v.durationMs??0)>0).map(v=>[v.start,v.start+(v.durationMs??0)]).sort((v,d)=>v[0]-d[0]);let n=0,s=-1,a=-1;for(const[v,d]of e)v>a?(a>s&&(n+=a-s),s=v,a=d):d>a&&(a=d);a>s&&(n+=a-s);const g=Math.max(0,r-n);(g>=50||g/r>=.7&&r>=40)&&(t.selfMs=g,t.detail=`\u26A0 cpu-heavy: ${g}ms self-time of ${r}ms${t.detail?" \xB7 "+t.detail:""}`)}return{events:q,...o?{sql:o}:{}}}C(buildFlowDetail,"buildFlowDetail"),y(buildFlowDetail,"buildFlowDetail");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/core",
3
- "version": "1.25.13",
3
+ "version": "1.25.14",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "module": "./index.js",
@@ -64,7 +64,7 @@
64
64
  }
65
65
  },
66
66
  "dependencies": {
67
- "@lensmcp/protocol-types": "1.25.13",
67
+ "@lensmcp/protocol-types": "1.25.14",
68
68
  "tslib": "^2.3.0"
69
69
  },
70
70
  "license": "Apache-2.0",