@lensmcp/core 1.25.24 → 1.25.25

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/index.d.ts CHANGED
@@ -18,4 +18,5 @@ export * from './lib/headless-flow.js';
18
18
  export * from './lib/flows-config.js';
19
19
  export * from './lib/patterns.js';
20
20
  export * from './lib/thresholds.js';
21
+ export * from './lib/event-loop.js';
21
22
  export * from './lib/graph-from-events.js';
package/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";export*from"./lib/common.js";export*from"./lib/ulid.js";export*from"./lib/event-bus.js";export*from"./lib/event-redactor.js";export*from"./lib/resource-store.js";export*from"./lib/answer-budget.js";export*from"./lib/graph-store.js";export*from"./lib/fingerprint.js";export*from"./lib/reducer-registry.js";export*from"./lib/story.js";export*from"./lib/route-template.js";export*from"./lib/sql-shape.js";export*from"./lib/http-shape.js";export*from"./lib/flow-shape.js";export*from"./lib/flow-segments.js";export*from"./lib/flow-categories.js";export*from"./lib/headless-flow.js";export*from"./lib/flows-config.js";export*from"./lib/patterns.js";export*from"./lib/thresholds.js";export*from"./lib/graph-from-events.js";
1
+ "use strict";export*from"./lib/common.js";export*from"./lib/ulid.js";export*from"./lib/event-bus.js";export*from"./lib/event-redactor.js";export*from"./lib/resource-store.js";export*from"./lib/answer-budget.js";export*from"./lib/graph-store.js";export*from"./lib/fingerprint.js";export*from"./lib/reducer-registry.js";export*from"./lib/story.js";export*from"./lib/route-template.js";export*from"./lib/sql-shape.js";export*from"./lib/http-shape.js";export*from"./lib/flow-shape.js";export*from"./lib/flow-segments.js";export*from"./lib/flow-categories.js";export*from"./lib/headless-flow.js";export*from"./lib/flows-config.js";export*from"./lib/patterns.js";export*from"./lib/thresholds.js";export*from"./lib/event-loop.js";export*from"./lib/graph-from-events.js";
@@ -9,6 +9,6 @@ export declare function aiContentDir(busFile: string): string;
9
9
  export declare function aiContentFile(busFile: string, id: string): string;
10
10
  /**
11
11
  * Read one captured call. Returns `undefined` for a malformed id, a missing file (never captured, or
12
- * rotated away), or unreadable JSON — a reader must treat all three as "not available", not as a fault.
12
+ * explicitly removed), or unreadable JSON — a reader must treat all three as "not available", not as a fault.
13
13
  */
14
14
  export declare function readAiContent(busFile: string, id: string): AiCallContent | undefined;
@@ -0,0 +1,18 @@
1
+ import type { BaseEvent, EventLoopIdentity, EventLoopIncident, EventLoopStatus } from '@lensmcp/protocol-types';
2
+ export declare function eventLoopIdentity(v: unknown): EventLoopIdentity | undefined;
3
+ /** Strictly project producer data. No raw request/response or AI content is copied into incident evidence. */
4
+ export declare function eventLoopIncident(e: BaseEvent): EventLoopIncident | undefined;
5
+ /** Bounded live index. Persist complete incident envelopes through onChange, not references to expiring events. */
6
+ export declare class EventLoopIndex {
7
+ private readonly onChange;
8
+ private readonly incidents;
9
+ private readonly loops;
10
+ private recent;
11
+ constructor(onChange?: (incident: EventLoopIncident) => void);
12
+ ingest(e: BaseEvent): void;
13
+ private attach;
14
+ statuses(now?: number): EventLoopStatus[];
15
+ list(flowId?: string): EventLoopIncident[];
16
+ }
17
+ export declare function setFlowLoopIncidents(read: (flowId: string) => EventLoopIncident[]): void;
18
+ export declare function flowLoopIncidents(flowId: string): EventLoopIncident[];
@@ -0,0 +1 @@
1
+ "use strict";var M=Object.defineProperty;var p=(n,e)=>M(n,"name",{value:e,configurable:!0});var k=Object.defineProperty,l=p((n,e)=>k(n,"name",{value:e,configurable:!0}),"u");const v=l(n=>n&&typeof n=="object"&&!Array.isArray(n)?n:{},"object"),o=l(n=>typeof n=="number"&&Number.isFinite(n)&&n>=0?n:void 0,"number"),s=l((n,e=250)=>typeof n=="string"&&n?n.slice(0,e):void 0,"text"),T=40;export function eventLoopIdentity(n){const e=v(n),t=s(e.id),r=s(e.project);if(!(!t||!r||e.runtime!=="node"&&e.runtime!=="browser"))return{id:t,project:r,runtime:e.runtime,...o(e.pid)!==void 0?{pid:o(e.pid)}:{},...o(e.threadId)!==void 0?{threadId:o(e.threadId)}:{},...s(e.tabId)?{tabId:s(e.tabId)}:{},...s(e.loadId)?{loadId:s(e.loadId)}:{}}}p(eventLoopIdentity,"eventLoopIdentity"),l(eventLoopIdentity,"eventLoopIdentity");export function eventLoopIncident(n){const e=v(n.raw);if(e.kind!=="event-loop-stall")return;const t=eventLoopIdentity(e.loop),r=o(e.startedAt),d=o(e.durationMs),i=e.mechanism;if(!t||r===void 0||d===void 0||!["callback","heartbeat","long-animation-frame","longtask"].includes(String(i)))return;const h=e.state==="unresponsive"?"unresponsive":e.state==="unknown"?"unknown":"recovered",u=[];for(const I of Array.isArray(e.scripts)?e.scripts.slice(0,8):[]){const c=v(I),m=s(c.url,512);m&&u.push({url:m,durationMs:o(c.durationMs)??0,startAt:o(c.startAt)??r,...s(c.functionName)?{functionName:s(c.functionName)}:{},...s(c.invoker)?{invoker:s(c.invoker)}:{}})}const f=i==="callback"?s(n.context?.flowId):void 0;return{id:s(e.incidentId)??n.id,loop:t,startAt:r,durationMs:d,observedAt:n.timestamp,...h==="recovered"?{endAt:r+d}:{},state:h,mechanism:i,severity:d>=1e3?"error":"warning",...f?{flowId:f}:{},...s(n.context?.requestId)?{requestId:s(n.context?.requestId)}:{},...s(e.callbackType)?{callbackType:s(e.callbackType)}:{},scripts:u,evidence:[],evidenceTruncated:e.scriptsTruncated===!0||(o(e.droppedIncidents)??0)>0||(o(e.floodSuppressed)??0)>0,explanation:i==="callback"?"Synchronous callback wall time, including any GC or process descheduling. Execution context identifies the flow; overlapping operations are not proven causes.":i==="heartbeat"?"The loop missed its heartbeat. The observer cannot identify executing code; overlapping work may have been delayed.":"Browser-measured main-thread work. Script timings identify contributing scripts where supported; overlapping flows are associated by time only."}}p(eventLoopIncident,"eventLoopIncident"),l(eventLoopIncident,"eventLoopIncident");export class EventLoopIndex{static{p(this,"EventLoopIndex")}static{l(this,"EventLoopIndex")}constructor(e=()=>{}){this.onChange=e,this.incidents=new Map,this.loops=new Map,this.recent=[]}ingest(e){const t=v(e.raw),r=s(t.kind)??e.source,d=eventLoopIdentity(t.loop);if(d){const a=this.loops.get(d.id);if(!a||e.timestamp>=a.lastSeen)for(this.loops.set(d.id,{loop:d,lastSeen:e.timestamp,state:t.state==="unresponsive"?"unresponsive":t.state==="unknown"?"unknown":"observed",coverage:s(t.coverage,500)??a?.coverage??(d.runtime==="node"?"Instrumented Node thread":"Browser main thread; supported PerformanceObserver entries"),...a?{meanMs:a.meanMs,maxMs:a.maxMs,p99Ms:a.p99Ms,utilization:a.utilization}:{},...o(t.lagMs)!==void 0?{meanMs:o(t.lagMs),maxMs:o(t.maxMs),p99Ms:o(t.p99Ms),utilization:o(t.utilization)}:{}});this.loops.size>200;)this.loops.delete(this.loops.keys().next().value)}const i=eventLoopIncident(e);if(i){const a=this.incidents.get(i.id);if(a&&a.observedAt>i.observedAt)return;a&&(i.evidence=a.evidence.slice(),i.evidenceTruncated||=a.evidenceTruncated);for(const A of this.recent)this.attach(i,A);for(this.incidents.set(i.id,i);this.incidents.size>200;)this.incidents.delete(this.incidents.keys().next().value);this.onChange(i);return}if(r.startsWith("event-loop-"))return;const h=s(t.loopId);if(!h)return;const u=v(t.span),f=v(t.request),I=v(t.render),c=o(t.durationMs)??o(u.durationMs)??o(f.durationMs)??o(I.actualDurationMs)??0,m=o(t.startedAt)??o(u.startTime)??o(f.startedAt)??e.timestamp-c,b=o(u.syncDurationMs),w=o(u.syncStartedAt),g=b!==void 0&&b>=50&&w!==void 0,x={loopId:h,eventId:e.id,title:(e.title??r).slice(0,250),kind:r,startAt:g?w:m,endAt:g?w+b:m+c,...e.context?.flowId?{flowId:e.context.flowId}:{},...e.context?.requestId?{requestId:e.context.requestId}:{},relation:g?"executing":"overlap"};this.recent.push(x),this.recent.length>2e3&&this.recent.splice(0,this.recent.length-2e3);for(const a of this.incidents.values())this.attach(a,x)&&this.onChange(a)}attach(e,t){if(t.loopId!==e.loop.id||t.endAt<e.startAt||t.startAt>(e.endAt??e.observedAt)||e.evidence.some(i=>i.eventId===t.eventId))return!1;if(e.evidence.length>=T){const i=!e.evidenceTruncated;return e.evidenceTruncated=!0,i}const{loopId:r,...d}=t;return e.evidence.push(d),!0}statuses(e=Date.now()){return[...this.loops.values()].map(t=>({...t,state:e-t.lastSeen>9e4?"unknown":t.state})).sort((t,r)=>r.lastSeen-t.lastSeen)}list(e){return[...this.incidents.values()].filter(t=>!e||t.flowId===e||t.evidence.some(r=>r.flowId===e)).sort((t,r)=>r.startAt-t.startAt)}}let y=l(()=>[],"readIncidents");export function setFlowLoopIncidents(n){y=n}p(setFlowLoopIncidents,"setFlowLoopIncidents"),l(setFlowLoopIncidents,"setFlowLoopIncidents");export function flowLoopIncidents(n){return y(n)}p(flowLoopIncidents,"flowLoopIncidents"),l(flowLoopIncidents,"flowLoopIncidents");
package/lib/flow-shape.js CHANGED
@@ -1 +1 @@
1
- "use strict";var qt=Object.defineProperty;var C=(i,h)=>qt(i,"name",{value:h,configurable:!0});var wt=Object.defineProperty,v=C((i,h)=>wt(i,"name",{value:h,configurable:!0}),"$");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 bt,sqlAccountingOf as xt}from"./flow-segments.js";import{boundedClone as jt}from"@lensmcp/protocol-types";export function areaOf(i){const{source:h,category:o,title:q,kind:c}=i;return h==="ai"?"ai":c?.startsWith("memory")||c==="db-query"?"data":h==="gateway"||c==="gateway-request"?"gateway":c==="queue-process"||c==="queue-active"||c==="queue-completed"||c==="queue-failed"?"services":h==="db"||h==="redis"||h==="queue"||c==="redis-op"||c?.startsWith("queue-")||h==="fs"||c==="fs-ops"?"data":h==="exec"||c==="exec"?"services":h==="external"||c==="egress"?"network":h==="nestjs"||h==="nest"?/(?:Repository|Repo|Dao|Store|EntityManager|DataSource|QueryRunner|OrmClient)\./.test(q)?"data":"services":h==="valtio"?"state":o==="network"?"network":"browser"}C(areaOf,"areaOf"),v(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,"vt"),v(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(q=>tt(q,h+1));const o={};for(const[q,c]of Object.entries(i))if(!Bt.has(q)){if(St.has(q)){typeof c=="string"?o[`${q}Chars`]=c.length:Array.isArray(c)?o[`${q}Count`]=c.length:c!=null&&(o[`${q}Present`]=!0);continue}o[q]=tt(c,h+1)}return o}C(tt,"rt"),v(tt,"projectAi");function ht(i){return i.length<=ft?ot(i):`${ot(i.slice(0,ft))}\u2026`}C(ht,"jt"),v(ht,"clipText");export function httpFacts(i,h){const o=v(M=>typeof M=="string"&&M.length>0?M:void 0,"str"),q=typeof h.status=="number"?h.status:void 0,c=v(M=>It(M.split("?")[0]??M)||"/","pathOf"),D=v((M,y,x={})=>({...M?{method:M.toUpperCase()}:{},...y?{rawPath:y,route:pt(y)}:{},...q!==void 0?{status:q}:{},...x}),"facts");if(i==="gateway-request"){const M=o(h.url);return D(o(h.method),M?c(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),y=o(h.exchangeId);return D(o(h.method)??"GET",M?c(M):void 0,{...o(h.host)?{host:o(h.host)}:{},...y?{exchangeId:y}:{}})}if(i==="fetch-start"||i==="fetch-done"||i==="fetch-error"){const M=o(h.href)??o(h.url);let y,x;if(M)try{const p=new URL(M,"http://relative.invalid");y=c(p.pathname),p.hostname!=="relative.invalid"&&(x=p.hostname)}catch{}return D(o(h.method)??"GET",y,x?{host:x}:{})}if(i==="ai-call")return{...q!==void 0?{status:q}:{},...h.stream===!0?{streamed:!0}:{}};const g=h.request;if(g&&typeof g=="object"){const M=g,y=o(M.route),x=o(M.method);if(!y&&!x)return{};const p=typeof M.status=="number"?M.status:void 0,R=y?c(y):void 0;return{...x?{method:x.toUpperCase()}:{},...R?{rawPath:R,route:R.includes(":")?R:pt(R)}:{},...p!==void 0?{status:p}:{}}}return{}}C(httpFacts,"httpFacts"),v(httpFacts,"httpFacts");export function trimFlowEvent(i,h={}){const o=i.raw??{},q=o.render??{},c=o.span??{},D=o.request??{},g=v(d=>typeof d=="number"?d:void 0,"num"),M=o.loop??{},y=o.effect??{},x=g(o.durationMs)??g(c.durationMs)??g(D.durationMs)??g(M.durationMs)??g(q.actualDurationMs)??g(y.durationMs),p=typeof o.kind=="string"?o.kind:void 0,R=p==="fetch-done"||p==="fetch-error",_=g(q.commitTime),z=p==="render"&&_!==void 0&&Math.abs(_-i.timestamp)<6e4,et=R?i.timestamp:z?_:g(o.startedAt)??g(c.startTime)??g(D.startedAt)??g(M.startedAt)??(x!==void 0?i.timestamp-x:i.timestamp);let j;if(typeof o.query=="string"){const d=Array.isArray(o.params)?` [${o.params.join(", ")}]`:"",f=typeof o.result=="string"?` \u2192 ${o.result}`:"";j=o.query+d+f}else if(typeof o.command=="string"){const d=typeof o.value=="string"?` \u2192 ${o.value}`:o.hit===!1?" \u2192 (miss)":"";j=o.command+d}else if(p==="state-update"){const d=o.update??{};let f="";try{f=JSON.stringify(d.preview)}catch{}j=`${d.storeId??""}.${d.path??""} = ${f}`}else if(p==="fs-ops"&&Array.isArray(o.paths))j=o.paths.slice(0,8).map(d=>{const f=d??{},B=typeof f.n=="number"&&f.n>1?` \xD7${f.n}`:"",T=typeof f.bytes=="number"&&f.bytes>0?` (${f.bytes>=1024?`${(f.bytes/1024).toFixed(1)} KB`:`${f.bytes} B`})`:"";return`${String(f.op??"?")} ${String(f.path??"?")}${B}${T}`}).join(" \xB7 ");else if(p==="exec"&&typeof o.cmd=="string")j=`${o.cmd} \u2192 ${o.code??o.signal??o.error??"?"}`;else if(p==="queue-completed"&&typeof o.returned=="string")j=`returned ${o.returned}`;else if(p==="queue-enqueued")j=`${o.job??"job"}#${o.jobId??"?"} \u2192 ${o.queue??""}${typeof o.data=="string"?" "+o.data:""}`;else if(p==="log"){const d=D.error??{},f=typeof d.stack=="string"?d.stack:typeof o.text=="string"?o.text:void 0;f&&f!==i.title&&(j=f)}let P,G,H,Q;if(p==="span"){const d=c.outcome;if(P=d==="threw"||d==="returned"?d:c.status==="error"?"threw":c.status==="ok"?"returned":void 0,P==="threw"){const T=c.error??{},L=typeof T.name=="string"?T.name:void 0,K=typeof T.message=="string"?T.message:typeof i.message=="string"?i.message:void 0;H=L,G=ot([L,K].filter(Boolean).join(": "))||void 0}const f=typeof c.args=="string"?c.args:void 0,B=typeof c.result=="string"?c.result:void 0;if(f!==void 0||B!==void 0){Q=[...f!==void 0?["args"]:[],...B!==void 0?["result"]:[]];const T=v(L=>L.length>gt?`${L.slice(0,gt)}\u2026`:L,"short");j=[f!==void 0?`args ${T(f)}`:"",B!==void 0?`returned ${T(B)}`:""].filter(Boolean).join(" \u2192 ")}}let U;if(p==="gateway-request")U=`${o.host??""}${String(o.url??"").split("?")[0]}`;else if(p==="fetch-start"||p==="fetch-done"||p==="fetch-error")try{const d=new URL(String(o.href??o.url??""));U=`${d.hostname}${d.pathname}`}catch{}let W;if(p==="gateway-request"&&Array.isArray(o.steps))W=o.steps.map(d=>{const f=[String(d.step)];return d.project&&f.push(String(d.project)),d.prefix&&f.push(String(d.prefix)),d.mode&&f.push(String(d.mode)+(d.ok===!1?" \u2717":d.ok===!0?" \u2713":"")),d.caller&&f.push("by "+String(d.caller)),d.pod&&f.push(String(d.pod)),typeof d.atMs=="number"&&f.push(`@${d.atMs}ms`),f.join(" ")}),j=W.map(d=>d.replace(/ @\d+ms$/,"")).join(" \u2192 ");else if(p==="egress")j=`${o.method??"GET"} ${o.host??""} \u2192 ${o.status??"?"}`;else if(i.source==="ai"){if(p==="ai-call"){const d=o.usage??{},f=d.promptTokens!==void 0||d.completionTokens!==void 0?` \xB7 ${g(d.promptTokens)??"?"}\u2192${g(d.completionTokens)??"?"} tok`:"",B=o.status!==void 0?` \xB7 ${String(o.status)}`:o.error?" \xB7 failed":"",T=g(o.toolCallCount)?` \xB7 ${g(o.toolCallCount)} tool call${g(o.toolCallCount)===1?"":"s"}`:"",L=g(o.durationMs)!==void 0?` \xB7 ${(g(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${o.provider??""}/${o.model??"?"}${f}${B}${T}${L}${o.stream===!0?" \xB7 stream":""}`}else if(p==="ai-round"){const d=o.model??{},f=o.usage??{},B=Array.isArray(o.toolCalls)?o.toolCalls:[],T=`${g(f.promptTokens)??"?"}\u2192${g(f.completionTokens)??"?"} tok`,L=B.length?` \xB7 ${B.length} tool call${B.length===1?"":"s"}`:"",K=g(o.durationMs)!==void 0?` \xB7 ${(g(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${d.provider??""}/${d.model??""} \xB7 ${T}${L}${K}`}else if(p==="ai-turn-start"){const d=Array.isArray(o.tools)?o.tools:[];j=`skill ${o.skill??""} \xB7 ${o.output??""}${d.length?" \xB7 tools: "+d.join(", "):""}`}else if(p==="ai-tool-call"){const d=o.call??{},f=o.result??{},B=g(o.durationMs)!==void 0?` \xB7 ${(g(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${d.name??"tool"} ${f.error!=null?"\u2717 "+String(f.error):"\u2713"}${B}`}else if(p==="ai-turn-end"){const d=o.usage??{},f=g(o.rounds)!==void 0?` \xB7 ${g(o.rounds)} round${g(o.rounds)===1?"":"s"}`:"",B=g(o.durationMs)!==void 0?` \xB7 ${(g(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${o.ok===!1?"FAILED":"ok"} \xB7 ${g(d.promptTokens)??"?"}+${g(d.completionTokens)??"?"} tok${f}${B}`}}let F;p==="db-query"&&typeof o.query=="string"?F=o.query:p==="redis-op"?F=`${o.op??""} ${String(o.key??"").replace(/\d+/g,"#")}`:p==="egress"?F=`${o.method??"GET"} ${o.host??""}`:p==="ai-call"?F=`ai ${o.provider??""} ${o.model??""} ${o.api??""}`:p==="queue-enqueued"?F=`enqueue ${o.queue??""}`:p==="span"&&typeof c.name=="string"?F=c.name:p==="memory-mutation"&&(F=i.title);const N=i.context??{},w=q.commitId??y.commitId??o.commitId,V=Array.isArray(q.why)?q.why.map(d=>typeof d?.type=="string"?d.type:void 0).filter(d=>!!d):[];return{id:i.id,t:i.timestamp,start:et,...F?{sig:F}:{},...U?{urlKey:U}:{},...httpFacts(p,o),...(p==="db-query"||p==="redis-op")&&typeof o.valuesId=="string"?{valuesId:o.valuesId}:{},...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 c.name=="string"?`${c.name} \u2014 threw${H?` ${H}`:""}${x!==void 0?` after ${x}ms`:""}`:i.title,kind:p,area:areaOf({source:i.source,category:i.category,title:i.title,kind:p}),...P?{outcome:P}:{},...G?{error:G}:{},...Q?{captured:Q}:{},...typeof c.role=="string"?{role:c.role}:{},...typeof c.spanId=="string"?{spanId:c.spanId}:{},...typeof c.parentSpanId=="string"?{parentSpanId:c.parentSpanId}:{},...p==="log"&&typeof o.level=="string"?{level:o.level}:{},...p==="log"&&typeof o.logger=="string"?{logger:o.logger}:{},...p==="log"&&typeof o.stream=="string"?{stream:o.stream}:{},...typeof N.requestId=="string"?{requestId:N.requestId}:{},...typeof N.parentRequestId=="string"?{parentRequestId:N.parentRequestId}:{},...typeof w=="string"?{commitId:w}:{},...typeof q.componentName=="string"?{component:q.componentName}:{},...typeof q.phase=="string"?{phase:q.phase}:{},...V.length?{why:V}:{},...p==="effect-run"&&typeof y.hookLogicalId=="string"?{hook:y.hookLogicalId}:{},...p==="effect-run"&&y.cleanupRan===!0?{cleanup:!0}:{},...p==="render-commit-truncated"?{renderTotal:g(o.total),renderPublished:g(o.published),...g(o.walkStoppedAt)!==void 0?{renderWalkStoppedAt:g(o.walkStoppedAt)}:{}}:{},...typeof N.projectName=="string"?{project:N.projectName}:typeof o.project=="string"?{project:o.project}:{},...x!==void 0?{durationMs:x}:{},...R&&g(o.startedAt)!==void 0?{fetchStartedAt:g(o.startedAt)}:{},...i.source==="ai"?{ai:h.includeRaw?o:mt(o)}:{},...j?{detail:j}:{},...W?{steps:W}:{}}}C(trimFlowEvent,"trimFlowEvent"),v(trimFlowEvent,"trimFlowEvent");const gt=300;export const OUTLIVED_PARENT_MIN_MS=250;const Tt=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"),v(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"),v(J,"causalRank");export function buildFlowDetail(i,h={}){const o=xt(i),q=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===bt)return!1;const n=r.span;return!(typeof n?.name=="string"&&n.name.startsWith("nest.request "))}).map(t=>trimFlowEvent(t,h)),c=new Set;for(let t=q.length-1;t>=0;t--)c.has(q[t].id)?q.splice(t,1):c.add(q[t].id);const D=new Map;for(const t of q)(t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&!D.has(t.requestId)&&D.set(t.requestId,t.start);const g=v(t=>t.source!=="react"&&t.source!=="valtio"&&t.requestId&&D.has(t.requestId)?D.get(t.requestId):t.start,"anchorOf");q.sort((t,r)=>g(t)-g(r)||t.start-r.start||J(t)-J(r)||(r.durationMs??0)-(t.durationMs??0)||t.t-r.t);const M=v(t=>(t.kind==="span"||t.kind==="server-request"||t.kind==="gateway-request"||t.kind==="queue-process")&&(t.durationMs??0)>0,"spanLike"),y=q;for(const t of y)t.group=t.source==="react"||t.source==="valtio"||t.source==="client-runtime"||t.source==="visual"?"browser":"server";const x=new Map;for(const t of y)if((t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&t.project){const r=x.get(t.requestId)??[];r.push({project:t.project,start:t.start,end:t.start+(t.durationMs??0)}),x.set(t.requestId,r)}const p=v((t,r)=>{const e=x.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 y)if(!t.project&&t.source==="nestjs"&&t.requestId){const r=p(t.requestId,t.start);r&&(t.project=r)}const R=new Map;for(const t of y)t.spanId&&R.set(t.spanId,t);const _=v((t,r)=>{let e=t.parentSpanId?R.get(t.parentSpanId):void 0;for(let n=0;e&&n<64;n++){if(e===r)return!0;e=e.parentSpanId?R.get(e.parentSpanId):void 0}return!1},"inside");for(const t of y){const r=t.parentSpanId?R.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 y){if(s===t||!M(s)||s.group!==t.group||s.requestId!==n)continue;const a=s.project,$=t.project;if(s.kind!=="gateway-request"&&t.kind!=="gateway-request"&&a!==void 0&&$!==void 0&&a!==$)continue;const k=s.durationMs??0,u=t.durationMs??0,l=Math.abs(s.start-t.start)<=$t,m=J(s),I=J(t),A=s.start<=t.start;if(!(s.start+k>t.start&&(A||l&&m<I)&&(!l||(m!==I?m<I:A&&k>u))))continue;const b=e?J(e):-1,O=e?Math.abs(s.start-e.start)<=$t:!1,E=e&&O&&m===b?_(s,e)?1:_(e,s)?-1:0:0;(!e||!O&&s.start>e.start||O&&m>b||E>0||E===0&&O&&m===b&&(s.durationMs??0)<(e.durationMs??0))&&(e=s)}e&&(t.parent=e.id)}for(const t of y)delete t.spanId,delete t.parentSpanId;{const t=new Set(y.map(a=>a.id)),r=new Set,e=new Map,n=[],s=v(a=>{const $=[a];for(;$.length;){const k=$.pop();n.push(k),r.add(k.id);const u=e.get(k.id);if(u){e.delete(k.id);for(let l=u.length-1;l>=0;l--)$.push(u[l])}}},"place");for(const a of y)if(a.parent&&a.parent!==a.id&&t.has(a.parent)&&!r.has(a.parent)){const $=e.get(a.parent)??[];$.push(a),e.set(a.parent,$)}else s(a);for(const a of y)r.has(a.id)||(n.push(a),r.add(a.id));for(let a=0;a<n.length;a++)y[a]=n[a]}const z=new Map;for(const t of y){if(!t.requestId)continue;const r=z.get(t.requestId);r?r.push(t):z.set(t.requestId,[t])}const et=new Map(y.map(t=>[t.id,t])),j=v((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 y){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=j(t.parentRequestId,t.start);e&&e!==t&&e.start<=t.start&&(t.parent=e.id)}const P=y,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,U=[];for(const t of P){if(t.kind!=="gateway-request")continue;if(!t.requestId){U.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){U.push(t);continue}e&&(t.fetchStartId=e.id,H.add(e.id)),n&&(t.fetchDoneId=n.id,Q.add(n.id))}const W=new Map;for(const t of P){if(!t.urlKey)continue;const r=W.get(t.urlKey)??{gws:[],starts:[],dones:[]};t.kind==="gateway-request"?U.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)),W.set(t.urlKey,r)}for(const{gws:t,starts:r,dones:e}of W.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 $=r[a];$&&(s.fetchStartId=$.id);const k=$?$.t:s.start;let u,l=1/0;for(const m of e){if(n.has(m.id))continue;const I=m.fetchStartedAt??m.start-(m.durationMs??0),A=Math.abs(I-k);A<l&&(l=A,u=m)}u&&(s.fetchDoneId=u.id,n.add(u.id))})}const F=new Map,N=new Map;for(const t of P)!t.queue||!t.jobId||(t.kind==="queue-enqueued"&&F.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=F.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(y.map(r=>[r.id,r]));for(const r of y){if(!r.parent||!Tt.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 y){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 w=y;{const t=new Map;for(const e of w)e.kind==="fetch-start"&&t.set(e.id,e);const r=new Map;for(const e of w){if(e.kind!=="fetch-done"&&e.kind!=="fetch-error")continue;const n=[...t.values()].find($=>$.requestId&&$.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){w=w.filter(e=>!r.has(e.id));for(const e of w)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=v(t=>!!t.commitId&&(t.kind==="render"||t.kind==="effect-run"||t.kind==="render-commit-truncated"),"commitMember"),d=v(t=>[...new Set(t)],"uniq"),f=v(t=>d(t.map(r=>r.component).filter(r=>!!r)),"named"),B=v(t=>t.length<=2?t.join(" + "):`${t[0]} + ${t.length-1} more`,"nameList"),T=v(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"),L=v(t=>{if(!t)return"effect";const r=/([^/\\]+?):(\d+)(?::\d+)?$/.exec(t);return r?`${r[1]}:${r[2]}`:t},"shortHook"),K=v(t=>`${L(t.hook)}${t.cleanup?" (cleanup)":""}`,"hookLabel"),nt=v(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=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 at(t){const r=t[0],e=t.filter(S=>S.kind==="render"),n=t.filter(S=>S.kind==="effect-run"),s=t.find(S=>S.kind==="render-commit-truncated"),a=[...e].sort((S,Y)=>(Y.durationMs??0)-(S.durationMs??0)),$=a.filter(S=>(S.why??[]).some(Y=>Y!=="parent-render")),k=d($.flatMap(S=>(S.why??[]).filter(Y=>Y!=="parent-render"))),u=f($),l=e.filter(S=>S.phase==="mount"),m=e.filter(S=>S.phase!=="mount"&&!$.includes(S)),I=a[0]?.component??"view",A=e.length>0&&l.length===e.length,b=k.length?k.join(" + "):void 0,O=A?"mount":"update",E=u.length?`view update \xB7 ${B(u)} \u2190 ${b}`:A?`view mount \xB7 ${I}`:`view update \xB7 ${I}`,rt=s?.renderTotal??e.length,kt=[l.length?`mounted ${T(l)}`:"",m.length?`re-rendered ${T(m)}`:"",!u.length&&!A&&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 "),ct=f(e);return st({...r,...nt(t),kind:"view-update",title:E,detail:kt,commitId:r.commitId,viewPhase:O,...b?{cause:b}:{},causeComponents:u,components:ct,mounted:f(l),renderCount:rt,...s?.renderWalkStoppedAt!==void 0?{renderCountAtLeast:!0}:{},recordedRenders:e.length,effects:n.length,effectHooks:n.map(K),memberIds:t.map(S=>S.id),sig:`commit:${O}:${b??"-"}:${u.join(",")}:${ct.slice().sort().join(",")}`,severity:t.some(S=>S.severity==="error")?"error":r.severity})}C(at,"pt"),v(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"),v(it,"effectsNode");const vt=v(t=>d(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,$=Math.min(...t.map(m=>m.start)),k=Math.max(...t.map(m=>m.start+(m.durationMs??0))),u=Math.round(t.reduce((m,I)=>m+(I.durationMs??0),0)/s*10)/10,l=Math.round((k-$)*10)/10;e.count=s,e.avgMs=u,e.wallMs=l,e.durationMs=k-$,e.items=t.slice(0,12).map(m=>({start:m.start-$,...m.durationMs!=null?{durationMs:m.durationMs}:{}})),e.memberIds=t.flatMap(m=>m.memberIds??[m.id]),e.title=`\xD7${s} ${e.title}`,t.some(m=>m.severity==="error")&&(e.severity="error"),e.kind==="view-update"?e.detail=[`${s} commits, ${r.length?`one per ${vt(r)}`:"back to back"}`,`avg ${u}ms \xB7 wall ${l}ms`,a??""].filter(Boolean).join(" \xB7 "):e.kind==="state-update"&&a&&n.detail?e.detail=`${s} updates in a row \xB7 wall ${l}ms \xB7 first ${a} \xB7 last ${n.detail}`:e.detail=[`${s} in a row \xB7 wall ${l}ms`,a??""].filter(Boolean).join(" \xB7 ")}C(dt,"ht"),v(dt,"collapseRepeat");const Z=[],X=new Map,ut=new Set;for(let t=0;t<w.length;t++){if(ut.has(t))continue;const r=w[t];if(!V(r)){Z.push(r);continue}const e=[t];for(let a=t+1;a<w.length;a++){const $=w[a];if($.group==="browser"){if(!V($)||$.commitId!==r.commitId)break;e.push(a)}}for(const a of e)ut.add(a);const n=e.map(a=>w[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")){w=Z;for(const t of w)for(;t.parent&&X.has(t.parent);)t.parent=X.get(t.parent)}{const t=new Map;for(const r of w)r.kind==="view-update"&&r.commitId&&!t.has(r.commitId)&&t.set(r.commitId,r);for(const r of w){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=w.map((u,l)=>u.group==="browser"?l:-1).filter(u=>u>=0),e=v(u=>`${u.kind}|${u.sig??u.title}`,"keyOf"),n=r.map(u=>e(w[u])),s=v((u,l,m)=>{for(let I=0;I<m;I++)if(n[u+I]!==n[l+I])return!1;return!0},"sameBlock"),a=v(u=>n[u].split("|")[0],"kindAt"),$=v(u=>{let l=0,m=1;for(let I=1;I<=4&&u+I<=n.length;I++){let A=1;for(;u+(A+1)*I<=n.length&&s(u,u+A*I,I);)A+=1;A>=3&&I*A>l*m&&(l=I,m=A)}return{k:l,r:m}},"bestBlockAt"),k=new Map;for(let u=0;u<n.length;){const{k:l,r:m}=$(u);if(l===0){u+=1;continue}const I=[...Array(l).keys()].find(b=>t.has(a(u+b)));if(I!==void 0&&I>0){const b=$(u+I);if(b.k===l&&b.r>=3&&b.r>=m-1){u+=I;continue}}const A=n.slice(u,u+l).map(b=>b.split("|")[0]).filter(b=>t.has(b));for(let b=0;b<l;b++){const O=[];for(let E=0;E<m;E++)O.push(w[r[u+b+E*l]]);dt(O,A);for(const E of O.slice(1))k.set(E.id,O[0].id)}u+=l*m}if(k.size>0){w=w.filter(u=>!k.has(u.id));for(const u of w)for(;u.parent&&k.has(u.parent);)u.parent=k.get(u.parent)}}{const t=new Map(w.map(r=>[r.id,r]));for(const r of w){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 lt=v(t=>{const r=new Map;for(const n of w){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((l,m)=>l.start-m.start);const s=n[0];let a=!1;for(let l=0;l+1<n.length;l++)if(n[l+1].start<n[l].start+(n[l].durationMs??0)){a=!0;break}const $=s.start,k=Math.max(...n.map(l=>l.start+(l.durationMs??0))),u=n.reduce((l,m)=>l+(m.durationMs??0),0);s.count=n.length,s.parallel=a,s.avgMs=Math.round(u/n.length*10)/10,s.wallMs=k-$,s.durationMs=k-$,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(l=>({start:l.start-$,...l.durationMs!=null?{durationMs:l.durationMs}:{}})),s.memberIds=n.flatMap(l=>l.memberIds??[l.id]),n.some(l=>l.severity==="error")&&(s.severity="error");for(const l of n.slice(1))e.set(l.id,s.id)}if(e.size!==0){w=w.filter(n=>!e.has(n.id));for(const n of w)for(;n.parent&&e.has(n.parent);)n.parent=e.get(n.parent)}},"aggregatePass");lt(!0),lt(!1);for(const t of w){if(!M(t))continue;const r=t.durationMs??0;if(r<40)continue;const e=w.filter(k=>k.parent===t.id&&(k.durationMs??0)>0).map(k=>[k.start,k.start+(k.durationMs??0)]).sort((k,u)=>k[0]-u[0]);let n=0,s=-1,a=-1;for(const[k,u]of e)k>a?(a>s&&(n+=a-s),s=k,a=u):u>a&&(a=u);a>s&&(n+=a-s);const $=Math.max(0,r-n);($>=50||$/r>=.7&&r>=40)&&(t.selfMs=$,t.detail=`\u26A0 cpu-heavy: ${$}ms self-time of ${r}ms${t.detail?" \xB7 "+t.detail:""}`)}return{events:w,...o?{sql:o}:{}}}C(buildFlowDetail,"buildFlowDetail"),v(buildFlowDetail,"buildFlowDetail");
1
+ "use strict";var qe=Object.defineProperty;var C=(i,m)=>qe(i,"name",{value:m,configurable:!0});var we=Object.defineProperty,v=C((i,m)=>we(i,"name",{value:m,configurable:!0}),"$");import{redactDeep as Me,redactText as oe,redactUrlParams as Ie}from"./redact.js";import{templatisePath as pe}from"./route-template.js";import{SQL_ACCOUNT_KIND as be,sqlAccountingOf as xe}from"./flow-segments.js";import{boundedClone as je}from"@lensmcp/protocol-types";export function areaOf(i){const{source:m,category:o,title:q,kind:c}=i;return m==="ai"?"ai":m==="perf"&&c==="event-loop-stall"?"services":c?.startsWith("memory")||c==="db-query"?"data":m==="gateway"||c==="gateway-request"?"gateway":c==="queue-process"||c==="queue-active"||c==="queue-completed"||c==="queue-failed"?"services":m==="db"||m==="redis"||m==="queue"||c==="redis-op"||c?.startsWith("queue-")||m==="fs"||c==="fs-ops"?"data":m==="exec"||c==="exec"?"services":m==="external"||c==="egress"?"network":m==="nestjs"||m==="nest"?/(?:Repository|Repo|Dao|Store|EntityManager|DataSource|QueryRunner|OrmClient)\./.test(q)?"data":"services":m==="valtio"?"state":o==="network"?"network":"browser"}C(areaOf,"areaOf"),v(areaOf,"areaOf");const fe=240,Se=new Set(["systemPrompt","prompt","prompts","messages","completion","completions","input","output","draft","text","content","result","arguments","params"]),Be=new Set(["tenantId","caller","userId","accountId","email","subject"]),Ae=8;function me(i){const m=ee(i,0);return je(Me({redacted:!0,...m}),{rawByteLimit:16*1024}).value}C(me,"vt"),v(me,"aiProjection");function ee(i,m){if(typeof i=="string")return he(i);if(i===null||typeof i!="object")return i;if(m>=Ae)return;if(Array.isArray(i))return i.slice(0,32).map(q=>ee(q,m+1));const o={};for(const[q,c]of Object.entries(i))if(!Be.has(q)){if(Se.has(q)){typeof c=="string"?o[`${q}Chars`]=c.length:Array.isArray(c)?o[`${q}Count`]=c.length:c!=null&&(o[`${q}Present`]=!0);continue}o[q]=ee(c,m+1)}return o}C(ee,"rt"),v(ee,"projectAi");function he(i){return i.length<=fe?oe(i):`${oe(i.slice(0,fe))}\u2026`}C(he,"jt"),v(he,"clipText");export function httpFacts(i,m){const o=v(M=>typeof M=="string"&&M.length>0?M:void 0,"str"),q=typeof m.status=="number"?m.status:void 0,c=v(M=>Ie(M.split("?")[0]??M)||"/","pathOf"),D=v((M,y,x={})=>({...M?{method:M.toUpperCase()}:{},...y?{rawPath:y,route:pe(y)}:{},...q!==void 0?{status:q}:{},...x}),"facts");if(i==="gateway-request"){const M=o(m.url);return D(o(m.method),M?c(M):void 0,{...o(m.host)?{host:o(m.host)}:{},...o(m.caller)?{caller:o(m.caller)}:{}})}if(i==="egress"){const M=o(m.path),y=o(m.exchangeId);return D(o(m.method)??"GET",M?c(M):void 0,{...o(m.host)?{host:o(m.host)}:{},...y?{exchangeId:y}:{}})}if(i==="fetch-start"||i==="fetch-done"||i==="fetch-error"){const M=o(m.href)??o(m.url);let y,x;if(M)try{const p=new URL(M,"http://relative.invalid");y=c(p.pathname),p.hostname!=="relative.invalid"&&(x=p.hostname)}catch{}return D(o(m.method)??"GET",y,x?{host:x}:{})}if(i==="ai-call")return{...q!==void 0?{status:q}:{},...m.stream===!0?{streamed:!0}:{}};const g=m.request;if(g&&typeof g=="object"){const M=g,y=o(M.route),x=o(M.method);if(!y&&!x)return{};const p=typeof M.status=="number"?M.status:void 0,R=y?c(y):void 0;return{...x?{method:x.toUpperCase()}:{},...R?{rawPath:R,route:R.includes(":")?R:pe(R)}:{},...p!==void 0?{status:p}:{}}}return{}}C(httpFacts,"httpFacts"),v(httpFacts,"httpFacts");export function trimFlowEvent(i,m={}){const o=i.raw??{},q=o.render??{},c=o.span??{},D=o.request??{},g=v(d=>typeof d=="number"?d:void 0,"num"),M=o.loop??{},y=o.effect??{},x=g(o.durationMs)??g(c.durationMs)??g(D.durationMs)??g(M.durationMs)??g(q.actualDurationMs)??g(y.durationMs),p=typeof o.kind=="string"?o.kind:void 0,R=p==="fetch-done"||p==="fetch-error",_=g(q.commitTime),z=p==="render"&&_!==void 0&&Math.abs(_-i.timestamp)<6e4,te=R?i.timestamp:z?_:g(o.startedAt)??g(c.startTime)??g(D.startedAt)??g(M.startedAt)??(x!==void 0?i.timestamp-x:i.timestamp);let j;if(typeof o.query=="string"){const d=Array.isArray(o.params)?` [${o.params.join(", ")}]`:"",f=typeof o.result=="string"?` \u2192 ${o.result}`:"";j=o.query+d+f}else if(typeof o.command=="string"){const d=typeof o.value=="string"?` \u2192 ${o.value}`:o.hit===!1?" \u2192 (miss)":"";j=o.command+d}else if(p==="state-update"){const d=o.update??{};let f="";try{f=JSON.stringify(d.preview)}catch{}j=`${d.storeId??""}.${d.path??""} = ${f}`}else if(p==="fs-ops"&&Array.isArray(o.paths))j=o.paths.slice(0,8).map(d=>{const f=d??{},B=typeof f.n=="number"&&f.n>1?` \xD7${f.n}`:"",T=typeof f.bytes=="number"&&f.bytes>0?` (${f.bytes>=1024?`${(f.bytes/1024).toFixed(1)} KB`:`${f.bytes} B`})`:"";return`${String(f.op??"?")} ${String(f.path??"?")}${B}${T}`}).join(" \xB7 ");else if(p==="exec"&&typeof o.cmd=="string")j=`${o.cmd} \u2192 ${o.code??o.signal??o.error??"?"}`;else if(p==="queue-completed"&&typeof o.returned=="string")j=`returned ${o.returned}`;else if(p==="queue-enqueued")j=`${o.job??"job"}#${o.jobId??"?"} \u2192 ${o.queue??""}${typeof o.data=="string"?" "+o.data:""}`;else if(p==="log"){const d=D.error??{},f=typeof d.stack=="string"?d.stack:typeof o.text=="string"?o.text:void 0;f&&f!==i.title&&(j=f)}let P,G,H,Q;if(p==="span"){const d=c.outcome;if(P=d==="threw"||d==="returned"?d:c.status==="error"?"threw":c.status==="ok"?"returned":void 0,P==="threw"){const T=c.error??{},L=typeof T.name=="string"?T.name:void 0,K=typeof T.message=="string"?T.message:typeof i.message=="string"?i.message:void 0;H=L,G=oe([L,K].filter(Boolean).join(": "))||void 0}const f=typeof c.args=="string"?c.args:void 0,B=typeof c.result=="string"?c.result:void 0;if(f!==void 0||B!==void 0){Q=[...f!==void 0?["args"]:[],...B!==void 0?["result"]:[]];const T=v(L=>L.length>ge?`${L.slice(0,ge)}\u2026`:L,"short");j=[f!==void 0?`args ${T(f)}`:"",B!==void 0?`returned ${T(B)}`:""].filter(Boolean).join(" \u2192 ")}}let U;if(p==="gateway-request")U=`${o.host??""}${String(o.url??"").split("?")[0]}`;else if(p==="fetch-start"||p==="fetch-done"||p==="fetch-error")try{const d=new URL(String(o.href??o.url??""));U=`${d.hostname}${d.pathname}`}catch{}let W;if(p==="gateway-request"&&Array.isArray(o.steps))W=o.steps.map(d=>{const f=[String(d.step)];return d.project&&f.push(String(d.project)),d.prefix&&f.push(String(d.prefix)),d.mode&&f.push(String(d.mode)+(d.ok===!1?" \u2717":d.ok===!0?" \u2713":"")),d.caller&&f.push("by "+String(d.caller)),d.pod&&f.push(String(d.pod)),typeof d.atMs=="number"&&f.push(`@${d.atMs}ms`),f.join(" ")}),j=W.map(d=>d.replace(/ @\d+ms$/,"")).join(" \u2192 ");else if(p==="egress")j=`${o.method??"GET"} ${o.host??""} \u2192 ${o.status??"?"}`;else if(i.source==="ai"){if(p==="ai-call"){const d=o.usage??{},f=d.promptTokens!==void 0||d.completionTokens!==void 0?` \xB7 ${g(d.promptTokens)??"?"}\u2192${g(d.completionTokens)??"?"} tok`:"",B=o.status!==void 0?` \xB7 ${String(o.status)}`:o.error?" \xB7 failed":"",T=g(o.toolCallCount)?` \xB7 ${g(o.toolCallCount)} tool call${g(o.toolCallCount)===1?"":"s"}`:"",L=g(o.durationMs)!==void 0?` \xB7 ${(g(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${o.provider??""}/${o.model??"?"}${f}${B}${T}${L}${o.stream===!0?" \xB7 stream":""}`}else if(p==="ai-round"){const d=o.model??{},f=o.usage??{},B=Array.isArray(o.toolCalls)?o.toolCalls:[],T=`${g(f.promptTokens)??"?"}\u2192${g(f.completionTokens)??"?"} tok`,L=B.length?` \xB7 ${B.length} tool call${B.length===1?"":"s"}`:"",K=g(o.durationMs)!==void 0?` \xB7 ${(g(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${d.provider??""}/${d.model??""} \xB7 ${T}${L}${K}`}else if(p==="ai-turn-start"){const d=Array.isArray(o.tools)?o.tools:[];j=`skill ${o.skill??""} \xB7 ${o.output??""}${d.length?" \xB7 tools: "+d.join(", "):""}`}else if(p==="ai-tool-call"){const d=o.call??{},f=o.result??{},B=g(o.durationMs)!==void 0?` \xB7 ${(g(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${d.name??"tool"} ${f.error!=null?"\u2717 "+String(f.error):"\u2713"}${B}`}else if(p==="ai-turn-end"){const d=o.usage??{},f=g(o.rounds)!==void 0?` \xB7 ${g(o.rounds)} round${g(o.rounds)===1?"":"s"}`:"",B=g(o.durationMs)!==void 0?` \xB7 ${(g(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${o.ok===!1?"FAILED":"ok"} \xB7 ${g(d.promptTokens)??"?"}+${g(d.completionTokens)??"?"} tok${f}${B}`}}let F;p==="db-query"&&typeof o.query=="string"?F=o.query:p==="redis-op"?F=`${o.op??""} ${String(o.key??"").replace(/\d+/g,"#")}`:p==="egress"?F=`${o.method??"GET"} ${o.host??""}`:p==="ai-call"?F=`ai ${o.provider??""} ${o.model??""} ${o.api??""}`:p==="queue-enqueued"?F=`enqueue ${o.queue??""}`:p==="span"&&typeof c.name=="string"?F=c.name:p==="memory-mutation"&&(F=i.title);const N=i.context??{},w=q.commitId??y.commitId??o.commitId,V=Array.isArray(q.why)?q.why.map(d=>typeof d?.type=="string"?d.type:void 0).filter(d=>!!d):[];return{id:i.id,t:i.timestamp,start:te,...F?{sig:F}:{},...U?{urlKey:U}:{},...httpFacts(p,o),...(p==="db-query"||p==="redis-op")&&typeof o.valuesId=="string"?{valuesId:o.valuesId}:{},...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 c.name=="string"?`${c.name} \u2014 threw${H?` ${H}`:""}${x!==void 0?` after ${x}ms`:""}`:i.title,kind:p,area:areaOf({source:i.source,category:i.category,title:i.title,kind:p}),...P?{outcome:P}:{},...G?{error:G}:{},...Q?{captured:Q}:{},...typeof c.role=="string"?{role:c.role}:{},...typeof c.spanId=="string"?{spanId:c.spanId}:{},...typeof c.parentSpanId=="string"?{parentSpanId:c.parentSpanId}:{},...p==="log"&&typeof o.level=="string"?{level:o.level}:{},...p==="log"&&typeof o.logger=="string"?{logger:o.logger}:{},...p==="log"&&typeof o.stream=="string"?{stream:o.stream}:{},...typeof N.requestId=="string"?{requestId:N.requestId}:{},...typeof N.parentRequestId=="string"?{parentRequestId:N.parentRequestId}:{},...typeof w=="string"?{commitId:w}:{},...typeof q.componentName=="string"?{component:q.componentName}:{},...typeof q.phase=="string"?{phase:q.phase}:{},...V.length?{why:V}:{},...p==="effect-run"&&typeof y.hookLogicalId=="string"?{hook:y.hookLogicalId}:{},...p==="effect-run"&&y.cleanupRan===!0?{cleanup:!0}:{},...p==="render-commit-truncated"?{renderTotal:g(o.total),renderPublished:g(o.published),...g(o.walkStoppedAt)!==void 0?{renderWalkStoppedAt:g(o.walkStoppedAt)}:{}}:{},...typeof N.projectName=="string"?{project:N.projectName}:typeof o.project=="string"?{project:o.project}:{},...x!==void 0?{durationMs:x}:{},...R&&g(o.startedAt)!==void 0?{fetchStartedAt:g(o.startedAt)}:{},...i.source==="ai"?{ai:m.includeRaw?o:me(o)}:{},...j?{detail:j}:{},...W?{steps:W}:{}}}C(trimFlowEvent,"trimFlowEvent"),v(trimFlowEvent,"trimFlowEvent");const ge=300;export const OUTLIVED_PARENT_MIN_MS=250;const Te=new Set(["egress","db-query","redis-op","ai-call","span","gateway-request","server-request"]),$e=1;function ye(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(ye,"Rt"),v(ye,"kindRank");function J(i){return i.kind==="span"&&i.role==="controller"?3.5:i.kind==="queue-process"?3:ye(i.kind)}C(J,"Z"),v(J,"causalRank");export function buildFlowDetail(i,m={}){const o=xe(i),q=i.slice().filter(e=>{const r=e.raw??{},t=typeof r.kind=="string"?r.kind:"";if(t==="subscription-added"||t==="subscription-removed"||t==="hook-run"||t==="store-created"||t==="singleton-instance"||t===be)return!1;const n=r.span;return!(typeof n?.name=="string"&&n.name.startsWith("nest.request "))}).map(e=>trimFlowEvent(e,m)),c=new Set;for(let e=q.length-1;e>=0;e--)c.has(q[e].id)?q.splice(e,1):c.add(q[e].id);const D=new Map;for(const e of q)(e.kind==="gateway-request"||e.kind==="queue-process")&&e.requestId&&!D.has(e.requestId)&&D.set(e.requestId,e.start);const g=v(e=>e.source!=="react"&&e.source!=="valtio"&&e.requestId&&D.has(e.requestId)?D.get(e.requestId):e.start,"anchorOf");q.sort((e,r)=>g(e)-g(r)||e.start-r.start||J(e)-J(r)||(r.durationMs??0)-(e.durationMs??0)||e.t-r.t);const M=v(e=>(e.kind==="span"||e.kind==="server-request"||e.kind==="gateway-request"||e.kind==="queue-process")&&(e.durationMs??0)>0,"spanLike"),y=q;for(const e of y)e.group=e.source==="react"||e.source==="valtio"||e.source==="client-runtime"||e.source==="visual"?"browser":"server";const x=new Map;for(const e of y)if((e.kind==="gateway-request"||e.kind==="queue-process")&&e.requestId&&e.project){const r=x.get(e.requestId)??[];r.push({project:e.project,start:e.start,end:e.start+(e.durationMs??0)}),x.set(e.requestId,r)}const p=v((e,r)=>{const t=x.get(e);if(t?.length)return t.every(n=>n.project===t[0].project)?t[0].project:t.filter(n=>n.start<=r+1&&n.end>=r-1).sort((n,s)=>s.start-n.start)[0]?.project},"projectOf");for(const e of y)if(!e.project&&e.source==="nestjs"&&e.requestId){const r=p(e.requestId,e.start);r&&(e.project=r)}const R=new Map;for(const e of y)e.spanId&&R.set(e.spanId,e);const _=v((e,r)=>{let t=e.parentSpanId?R.get(e.parentSpanId):void 0;for(let n=0;t&&n<64;n++){if(t===r)return!0;t=t.parentSpanId?R.get(t.parentSpanId):void 0}return!1},"inside");for(const e of y){const r=e.parentSpanId?R.get(e.parentSpanId):void 0;if(r&&r!==e&&r.group===e.group&&r.requestId===e.requestId){e.parent=r.id;continue}let t;const n=e.requestId;for(const s of y){if(s===e||!M(s)||s.group!==e.group||s.requestId!==n)continue;const a=s.project,$=e.project;if(s.kind!=="gateway-request"&&e.kind!=="gateway-request"&&a!==void 0&&$!==void 0&&a!==$)continue;const k=s.durationMs??0,u=e.durationMs??0,l=Math.abs(s.start-e.start)<=$e,h=J(s),I=J(e),A=s.start<=e.start;if(!(s.start+k>e.start&&(A||l&&h<I)&&(!l||(h!==I?h<I:A&&k>u))))continue;const b=t?J(t):-1,O=t?Math.abs(s.start-t.start)<=$e:!1,E=t&&O&&h===b?_(s,t)?1:_(t,s)?-1:0:0;(!t||!O&&s.start>t.start||O&&h>b||E>0||E===0&&O&&h===b&&(s.durationMs??0)<(t.durationMs??0))&&(t=s)}t&&(e.parent=t.id)}for(const e of y)delete e.spanId,delete e.parentSpanId;{const e=new Set(y.map(a=>a.id)),r=new Set,t=new Map,n=[],s=v(a=>{const $=[a];for(;$.length;){const k=$.pop();n.push(k),r.add(k.id);const u=t.get(k.id);if(u){t.delete(k.id);for(let l=u.length-1;l>=0;l--)$.push(u[l])}}},"place");for(const a of y)if(a.parent&&a.parent!==a.id&&e.has(a.parent)&&!r.has(a.parent)){const $=t.get(a.parent)??[];$.push(a),t.set(a.parent,$)}else s(a);for(const a of y)r.has(a.id)||(n.push(a),r.add(a.id));for(let a=0;a<n.length;a++)y[a]=n[a]}const z=new Map;for(const e of y){if(!e.requestId)continue;const r=z.get(e.requestId);r?r.push(e):z.set(e.requestId,[e])}const te=new Map(y.map(e=>[e.id,e])),j=v((e,r)=>{const t=(z.get(e)??[]).filter(n=>M(n)&&n.start<=r&&n.start+(n.durationMs??0)>=r);if(t.length!==0)return t.sort((n,s)=>s.start-n.start||(n.durationMs??0)-(s.durationMs??0)),t[0]},"callerNodeFor");for(const e of y){if(!e.parentRequestId||e.kind!=="server-request"&&e.kind!=="gateway-request")continue;const r=e.parent?te.get(e.parent):void 0;if(r&&r.requestId===e.requestId)continue;const t=j(e.parentRequestId,e.start);t&&t!==e&&t.start<=e.start&&(e.parent=t.id)}const P=y,G=new Map;for(const e of P)e.kind==="gateway-request"&&e.requestId&&!G.has(e.requestId)&&G.set(e.requestId,e);for(const e of P)if(e.group==="server"&&!e.parent&&e.requestId&&e.kind!=="gateway-request"){const r=G.get(e.requestId);r&&r!==e&&r.start<=e.start&&(e.parent=r.id)}const H=new Set,Q=new Set,U=[];for(const e of P){if(e.kind!=="gateway-request")continue;if(!e.requestId){U.push(e);continue}const r=z.get(e.requestId)??[];if(r.filter(s=>s.kind==="gateway-request").sort((s,a)=>s.start-a.start)[0]!==e)continue;const t=r.find(s=>s.kind==="fetch-start"),n=r.find(s=>s.kind==="fetch-done"||s.kind==="fetch-error");if(!t&&!n){U.push(e);continue}t&&(e.fetchStartId=t.id,H.add(t.id)),n&&(e.fetchDoneId=n.id,Q.add(n.id))}const W=new Map;for(const e of P){if(!e.urlKey)continue;const r=W.get(e.urlKey)??{gws:[],starts:[],dones:[]};e.kind==="gateway-request"?U.includes(e)&&r.gws.push(e):e.kind==="fetch-start"?H.has(e.id)||r.starts.push(e):(e.kind==="fetch-done"||e.kind==="fetch-error")&&(Q.has(e.id)||r.dones.push(e)),W.set(e.urlKey,r)}for(const{gws:e,starts:r,dones:t}of W.values()){e.sort((s,a)=>s.start-a.start),r.sort((s,a)=>s.start-a.start);const n=new Set;e.forEach((s,a)=>{const $=r[a];$&&(s.fetchStartId=$.id);const k=$?$.t:s.start;let u,l=1/0;for(const h of t){if(n.has(h.id))continue;const I=h.fetchStartedAt??h.start-(h.durationMs??0),A=Math.abs(I-k);A<l&&(l=A,u=h)}u&&(s.fetchDoneId=u.id,n.add(u.id))})}const F=new Map,N=new Map;for(const e of P)!e.queue||!e.jobId||(e.kind==="queue-enqueued"&&F.set(`${e.queue}#${e.jobId}`,e),e.kind==="queue-process"&&N.set(`${e.queue}#${e.jobId}`,e));for(const e of P){if(!e.queue||!e.jobId)continue;const r=`${e.queue}#${e.jobId}`;if(e.kind==="queue-process"&&!e.parent){const t=F.get(r);t&&t!==e&&t.start<=e.start&&(e.parent=t.id)}else if(e.kind==="queue-active"||e.kind==="queue-completed"||e.kind==="queue-failed"){const t=N.get(r);t&&t!==e&&t.start<=e.start&&(e.parent=t.id)}}{const e=new Map(y.map(r=>[r.id,r]));for(const r of y){if(!r.parent||!Te.has(r.kind??"")||r.durationMs===void 0)continue;const t=e.get(r.parent);if(!t||t.kind!=="span"||!((t.durationMs??0)>0))continue;const n=Math.round(r.start+r.durationMs-(t.start+t.durationMs));if(n<OUTLIVED_PARENT_MIN_MS)continue;r.outlivedParentMs=n;const s=t.leftRunning??{count:0,longestMs:0};t.leftRunning={count:s.count+1,longestMs:Math.max(s.longestMs,n)}}for(const r of y){const t=[];r.leftRunning&&t.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&&t.push(`ran on ${r.outlivedParentMs}ms after the span that started it had ended`),t.length>0&&(r.detail=[r.detail,...t].filter(Boolean).join(" \xB7 "))}}let w=y;{const e=new Map;for(const t of w)t.kind==="fetch-start"&&e.set(t.id,t);const r=new Map;for(const t of w){if(t.kind!=="fetch-done"&&t.kind!=="fetch-error")continue;const n=[...e.values()].find($=>$.requestId&&$.requestId===t.requestId)?.id,s=n?e.get(n):void 0;if(!s)continue;const a=t.fetchStartedAt??s.start;s.title=t.title,s.severity=t.severity,s.durationMs=t.durationMs??Math.max(0,t.t-a),s.kind="fetch",t.detail&&!s.detail&&(s.detail=t.detail),r.set(t.id,s.id)}if(r.size>0){w=w.filter(t=>!r.has(t.id));for(const t of w)for(t.fetchDoneId&&r.has(t.fetchDoneId)&&(t.fetchDoneId=r.get(t.fetchDoneId));t.parent&&r.has(t.parent);)t.parent=r.get(t.parent)}}const V=v(e=>!!e.commitId&&(e.kind==="render"||e.kind==="effect-run"||e.kind==="render-commit-truncated"),"commitMember"),d=v(e=>[...new Set(e)],"uniq"),f=v(e=>d(e.map(r=>r.component).filter(r=>!!r)),"named"),B=v(e=>e.length<=2?e.join(" + "):`${e[0]} + ${e.length-1} more`,"nameList"),T=v(e=>{const r=new Map;for(const t of e)t.component&&r.set(t.component,(r.get(t.component)??0)+1);return[...r].map(([t,n])=>n>1?`${t} \xD7${n}`:t).join(", ")},"tally"),L=v(e=>{if(!e)return"effect";const r=/([^/\\]+?):(\d+)(?::\d+)?$/.exec(e);return r?`${r[1]}:${r[2]}`:e},"shortHook"),K=v(e=>`${L(e.hook)}${e.cleanup?" (cleanup)":""}`,"hookLabel"),ne=v(e=>{const r=Math.min(...e.map(n=>n.start)),t=Math.max(...e.map(n=>n.start+(n.durationMs??0)));return{start:r,durationMs:t-r}},"extent"),se=v(e=>(delete e.component,delete e.why,delete e.phase,delete e.hook,delete e.cleanup,delete e.renderTotal,delete e.renderPublished,e),"asGroup");function ae(e){const r=e[0],t=e.filter(S=>S.kind==="render"),n=e.filter(S=>S.kind==="effect-run"),s=e.find(S=>S.kind==="render-commit-truncated"),a=[...t].sort((S,Y)=>(Y.durationMs??0)-(S.durationMs??0)),$=a.filter(S=>(S.why??[]).some(Y=>Y!=="parent-render")),k=d($.flatMap(S=>(S.why??[]).filter(Y=>Y!=="parent-render"))),u=f($),l=t.filter(S=>S.phase==="mount"),h=t.filter(S=>S.phase!=="mount"&&!$.includes(S)),I=a[0]?.component??"view",A=t.length>0&&l.length===t.length,b=k.length?k.join(" + "):void 0,O=A?"mount":"update",E=u.length?`view update \xB7 ${B(u)} \u2190 ${b}`:A?`view mount \xB7 ${I}`:`view update \xB7 ${I}`,re=s?.renderTotal??t.length,ke=[l.length?`mounted ${T(l)}`:"",h.length?`re-rendered ${T(h)}`:"",!u.length&&!A&&t.length?"trigger not recorded \u2014 every captured render came from its parent":"",s?.renderWalkStoppedAt!==void 0?`at least ${re} renders (the walk stopped at ${s.renderWalkStoppedAt} fibers), ${s.renderPublished??t.length} recorded`:s?`${re} renders, ${s.renderPublished??t.length} recorded (per-commit cap)`:`${t.length} render${t.length===1?"":"s"}`,n.length?`${n.length} effect${n.length===1?"":"s"}: ${n.map(K).join(", ")}`:""].filter(Boolean).join(" \xB7 "),ce=f(t);return se({...r,...ne(e),kind:"view-update",title:E,detail:ke,commitId:r.commitId,viewPhase:O,...b?{cause:b}:{},causeComponents:u,components:ce,mounted:f(l),renderCount:re,...s?.renderWalkStoppedAt!==void 0?{renderCountAtLeast:!0}:{},recordedRenders:t.length,effects:n.length,effectHooks:n.map(K),memberIds:e.map(S=>S.id),sig:`commit:${O}:${b??"-"}:${u.join(",")}:${ce.slice().sort().join(",")}`,severity:e.some(S=>S.severity==="error")?"error":r.severity})}C(ae,"pt"),v(ae,"viewUpdateNode");function ie(e){const r=e[0],t=e.map(K);return se({...r,...ne(e),kind:"commit-effects",title:e.length===1?`effect \xB7 ${t[0]}`:`effects \xB7 ${t[0]} + ${e.length-1} more`,detail:t.join(", "),commitId:r.commitId,effects:e.length,effectHooks:t,memberIds:e.map(n=>n.id),sig:`effects:${t.slice().sort().join(",")}`})}C(ie,"mt"),v(ie,"effectsNode");const ve=v(e=>d(e.map(r=>r==="state-update"?"state update":r==="fetch-start"?"request":r==="flow-origin"?"interaction":"response")).join(" + "),"describeInputs");function de(e,r){const t=e[0],n=e[e.length-1],s=e.length,a=t.detail,$=Math.min(...e.map(h=>h.start)),k=Math.max(...e.map(h=>h.start+(h.durationMs??0))),u=Math.round(e.reduce((h,I)=>h+(I.durationMs??0),0)/s*10)/10,l=Math.round((k-$)*10)/10;t.count=s,t.avgMs=u,t.wallMs=l,t.durationMs=k-$,t.items=e.slice(0,12).map(h=>({start:h.start-$,...h.durationMs!=null?{durationMs:h.durationMs}:{}})),t.memberIds=e.flatMap(h=>h.memberIds??[h.id]),t.title=`\xD7${s} ${t.title}`,e.some(h=>h.severity==="error")&&(t.severity="error"),t.kind==="view-update"?t.detail=[`${s} commits, ${r.length?`one per ${ve(r)}`:"back to back"}`,`avg ${u}ms \xB7 wall ${l}ms`,a??""].filter(Boolean).join(" \xB7 "):t.kind==="state-update"&&a&&n.detail?t.detail=`${s} updates in a row \xB7 wall ${l}ms \xB7 first ${a} \xB7 last ${n.detail}`:t.detail=[`${s} in a row \xB7 wall ${l}ms`,a??""].filter(Boolean).join(" \xB7 ")}C(de,"ht"),v(de,"collapseRepeat");const Z=[],X=new Map,ue=new Set;for(let e=0;e<w.length;e++){if(ue.has(e))continue;const r=w[e];if(!V(r)){Z.push(r);continue}const t=[e];for(let a=e+1;a<w.length;a++){const $=w[a];if($.group==="browser"){if(!V($)||$.commitId!==r.commitId)break;t.push(a)}}for(const a of t)ue.add(a);const n=t.map(a=>w[a]),s=n.some(a=>a.kind!=="effect-run")?ae(n):ie(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(e=>e.kind==="view-update"||e.kind==="commit-effects")){w=Z;for(const e of w)for(;e.parent&&X.has(e.parent);)e.parent=X.get(e.parent)}{const e=new Map;for(const r of w)r.kind==="view-update"&&r.commitId&&!e.has(r.commitId)&&e.set(r.commitId,r);for(const r of w){if(r.kind!=="commit-effects"||r.parent||!r.commitId)continue;const t=e.get(r.commitId);t&&t.start<=r.start&&(r.parent=t.id)}}{const e=new Set(["state-update","fetch","fetch-start","fetch-done","fetch-error","flow-origin"]),r=w.map((u,l)=>u.group==="browser"?l:-1).filter(u=>u>=0),t=v(u=>`${u.kind}|${u.sig??u.title}`,"keyOf"),n=r.map(u=>t(w[u])),s=v((u,l,h)=>{for(let I=0;I<h;I++)if(n[u+I]!==n[l+I])return!1;return!0},"sameBlock"),a=v(u=>n[u].split("|")[0],"kindAt"),$=v(u=>{let l=0,h=1;for(let I=1;I<=4&&u+I<=n.length;I++){let A=1;for(;u+(A+1)*I<=n.length&&s(u,u+A*I,I);)A+=1;A>=3&&I*A>l*h&&(l=I,h=A)}return{k:l,r:h}},"bestBlockAt"),k=new Map;for(let u=0;u<n.length;){const{k:l,r:h}=$(u);if(l===0){u+=1;continue}const I=[...Array(l).keys()].find(b=>e.has(a(u+b)));if(I!==void 0&&I>0){const b=$(u+I);if(b.k===l&&b.r>=3&&b.r>=h-1){u+=I;continue}}const A=n.slice(u,u+l).map(b=>b.split("|")[0]).filter(b=>e.has(b));for(let b=0;b<l;b++){const O=[];for(let E=0;E<h;E++)O.push(w[r[u+b+E*l]]);de(O,A);for(const E of O.slice(1))k.set(E.id,O[0].id)}u+=l*h}if(k.size>0){w=w.filter(u=>!k.has(u.id));for(const u of w)for(;u.parent&&k.has(u.parent);)u.parent=k.get(u.parent)}}{const e=new Map(w.map(r=>[r.id,r]));for(const r of w){const t=new Set([r.id]);let n=r;for(;n?.parent;){if(t.has(n.parent)){n.parent=void 0;break}t.add(n.parent),n=e.get(n.parent)}}}const le=v(e=>{const r=new Map;for(const n of w){if(!n.sig||M(n)!==e||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 t=new Map;for(const n of r.values()){if(n.length<3)continue;n.sort((l,h)=>l.start-h.start);const s=n[0];let a=!1;for(let l=0;l+1<n.length;l++)if(n[l+1].start<n[l].start+(n[l].durationMs??0)){a=!0;break}const $=s.start,k=Math.max(...n.map(l=>l.start+(l.durationMs??0))),u=n.reduce((l,h)=>l+(h.durationMs??0),0);s.count=n.length,s.parallel=a,s.avgMs=Math.round(u/n.length*10)/10,s.wallMs=k-$,s.durationMs=k-$,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(l=>({start:l.start-$,...l.durationMs!=null?{durationMs:l.durationMs}:{}})),s.memberIds=n.flatMap(l=>l.memberIds??[l.id]),n.some(l=>l.severity==="error")&&(s.severity="error");for(const l of n.slice(1))t.set(l.id,s.id)}if(t.size!==0){w=w.filter(n=>!t.has(n.id));for(const n of w)for(;n.parent&&t.has(n.parent);)n.parent=t.get(n.parent)}},"aggregatePass");le(!0),le(!1);for(const e of w){if(!M(e))continue;const r=e.durationMs??0;if(r<40)continue;const t=w.filter(k=>k.parent===e.id&&(k.durationMs??0)>0).map(k=>[k.start,k.start+(k.durationMs??0)]).sort((k,u)=>k[0]-u[0]);let n=0,s=-1,a=-1;for(const[k,u]of t)k>a?(a>s&&(n+=a-s),s=k,a=u):u>a&&(a=u);a>s&&(n+=a-s);const $=Math.max(0,r-n);($>=50||$/r>=.7&&r>=40)&&(e.selfMs=$,e.detail=`\u26A0 cpu-heavy: ${$}ms self-time of ${r}ms${e.detail?" \xB7 "+e.detail:""}`)}return{events:w,...o?{sql:o}:{}}}C(buildFlowDetail,"buildFlowDetail"),v(buildFlowDetail,"buildFlowDetail");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/core",
3
- "version": "1.25.24",
3
+ "version": "1.25.25",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "module": "./index.js",
@@ -84,7 +84,7 @@
84
84
  }
85
85
  },
86
86
  "dependencies": {
87
- "@lensmcp/protocol-types": "1.25.24",
87
+ "@lensmcp/protocol-types": "1.25.25",
88
88
  "tslib": "^2.3.0"
89
89
  },
90
90
  "license": "Apache-2.0",