@lensmcp/core 1.25.0 → 1.25.1
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/lib/ai-content.js +1 -1
- package/lib/answer-budget.js +2 -2
- package/lib/bus-rotation.js +1 -1
- package/lib/event-bus.js +1 -1
- package/lib/event-redactor.js +1 -1
- package/lib/fingerprint.js +1 -1
- package/lib/flow-categories.js +1 -1
- package/lib/flow-segments.js +1 -1
- package/lib/flow-shape.d.ts +2 -2
- package/lib/flow-shape.js +1 -1
- package/lib/flows-config.js +1 -1
- package/lib/graph-from-events.js +1 -1
- package/lib/graph-store.js +1 -1
- package/lib/headless-flow.js +1 -1
- package/lib/http-exchange.js +1 -1
- package/lib/http-shape.js +1 -1
- package/lib/lens-dir.js +1 -1
- package/lib/lens-events.js +2 -2
- package/lib/patterns.js +1 -1
- package/lib/redact.js +1 -1
- package/lib/reducer-registry.js +1 -1
- package/lib/resource-store.js +1 -1
- package/lib/route-template.js +1 -1
- package/lib/sql-shape.js +3 -3
- package/lib/stores.js +2 -2
- package/lib/story.js +1 -1
- package/lib/thresholds.js +1 -1
- package/lib/ulid.js +1 -1
- package/package.json +2 -2
package/lib/ai-content.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var c=Object.defineProperty;var n=(e,t)=>c(e,"name",{value:t,configurable:!0});var s=Object.defineProperty,i=n((e,t)=>s(e,"name",{value:t,configurable:!0}),"r"),l=Object.defineProperty,o=i((e,t)=>l(e,"name",{value:t,configurable:!0}),"r");import*as d from"node:fs";import{dirname as f,join as a}from"node:path";export const AI_CONTENT_DIR="ai";const u=/^ai_[0-9a-z]{8,40}$/;export const isAiCallId=o(e=>typeof e=="string"&&u.test(e),"isAiCallId");export function aiContentDir(e){return a(f(e),AI_CONTENT_DIR)}n(aiContentDir,"aiContentDir"),i(aiContentDir,"aiContentDir"),o(aiContentDir,"aiContentDir");export function aiContentFile(e,t){if(!isAiCallId(t))throw new Error("invalid ai call id");return a(aiContentDir(e),`${t}.json`)}n(aiContentFile,"aiContentFile"),i(aiContentFile,"aiContentFile"),o(aiContentFile,"aiContentFile");export function readAiContent(e,t){if(isAiCallId(t))try{const r=JSON.parse(d.readFileSync(aiContentFile(e,t),"utf8"));return r&&r.schemaVersion===1&&r.id===t?r:void 0}catch{return}}n(readAiContent,"readAiContent"),i(readAiContent,"readAiContent"),o(readAiContent,"readAiContent");
|
package/lib/answer-budget.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`,r);return i>=r/2&&(r=i),r>0&&(
|
|
1
|
+
"use strict";var G=Object.defineProperty;var d=(t,e)=>G(t,"name",{value:e,configurable:!0});var W=Object.defineProperty,g=d((t,e)=>W(t,"name",{value:e,configurable:!0}),"d"),U=Object.defineProperty,c=g((t,e)=>U(t,"name",{value:e,configurable:!0}),"a");import{boundedClone as z}from"@lensmcp/protocol-types";export const DEFAULT_ANSWER_BUDGET_BYTES=24*1024,ANSWER_BUDGET_ENV="LENSMCP_ANSWER_BUDGET_BYTES",MIN_ANSWER_BUDGET_BYTES=2*1024,ANSWER_CUT_KEY="cutToFit",FITTED_STRING_CHARS=1500,REPEATED_STRING_MIN_CHARS=200;const R=900,V=32,H=new Set(["timestamp","startedAt","startTime","at","emittedAt","lastSeenAt","endedAt","endTime","t","ts","time"]),J=c(t=>typeof t=="number"&&t>=1e11&&t<=1e14,"isEpochMs"),K=.95;export function answerBudgetBytes(t=process.env){const e=t[ANSWER_BUDGET_ENV];if(e===void 0||e.trim()==="")return DEFAULT_ANSWER_BUDGET_BYTES;const r=Number(e);return!Number.isFinite(r)||r<0?DEFAULT_ANSWER_BUDGET_BYTES:r===0?Number.POSITIVE_INFINITY:Math.max(MIN_ANSWER_BUDGET_BYTES,Math.floor(r))}d(answerBudgetBytes,"answerBudgetBytes"),g(answerBudgetBytes,"answerBudgetBytes"),c(answerBudgetBytes,"answerBudgetBytes");export function utf8Bytes(t){let e=0;for(let r=0;r<t.length;r++){const i=t.charCodeAt(r);i<128?e+=1:i<2048?e+=2:i>=55296&&i<=56319&&r+1<t.length&&(t.charCodeAt(r+1)&64512)===56320?(e+=4,r+=1):e+=3}return e}d(utf8Bytes,"utf8Bytes"),g(utf8Bytes,"utf8Bytes"),c(utf8Bytes,"utf8Bytes");export function jsonBytes(t){let e;try{e=JSON.stringify(t)}catch{return Number.POSITIVE_INFINITY}return e===void 0?0:utf8Bytes(e)}d(jsonBytes,"jsonBytes"),g(jsonBytes,"jsonBytes"),c(jsonBytes,"jsonBytes");const C=c(t=>typeof t=="object"&&t!==null&&!Array.isArray(t),"isRecord");function N(t){if(!C(t))return!1;const e=Object.getPrototypeOf(t);return e===Object.prototype||e===null}d(N,"R"),g(N,"D"),c(N,"isPlain");export function newestEndOf(t){const e=t[0];if(t.length<2||!C(e))return;let r;for(const i of Object.keys(e)){if(typeof e[i]!="number"||!(H.has(i)||J(e[i])))continue;let s=0,f=0,l=!0,y=e[i];for(let E=1;E<t.length;E++){const b=t[E],p=C(b)?b[i]:void 0;if(typeof p!="number"){l=!1;break}p>y?s+=1:p<y&&(f+=1),y=p}const S=s+f;if(!l||S===0)continue;const x=Math.max(s,f)/S;x>=K&&(!r||x>r.agreement)&&(r={end:s>=f?"end":"start",agreement:x})}return r?.end}d(newestEndOf,"newestEndOf"),g(newestEndOf,"newestEndOf"),c(newestEndOf,"newestEndOf");export function newestFirst(t){return newestEndOf(t)==="end"?[...t].reverse():t.slice()}d(newestFirst,"newestFirst"),g(newestFirst,"newestFirst"),c(newestFirst,"newestFirst");export function shortenText(t,e){if(t.length<=e)return t;let r=Math.max(0,e);const i=t.lastIndexOf(`
|
|
2
|
+
`,r);return i>=r/2&&(r=i),r>0&&(t.charCodeAt(r-1)&64512)===55296&&(r-=1),`${t.slice(0,r)}\u2026[lensmcp truncated: ${t.length-r} more chars]`}d(shortenText,"shortenText"),g(shortenText,"shortenText"),c(shortenText,"shortenText");export function fitList(t,e,r={}){const i=t.length,s=t.reduce((o,u)=>o+jsonBytes(u)+1,2);if(s<=e)return{items:t.slice(),total:i,returned:i,kept:"all",shortenedStrings:0,repeatedStrings:0,bytes:s};const f=r.newest??newestEndOf(t),l=f??r.keep??"start",y=r.name??"items",S=r.maxStringChars??FITTED_STRING_CHARS,x=l==="start"?t:[...t].reverse(),E=String(Math.max(0,i-1)).length,b=new Map,p=[],h=[];let w=2,A=0,$=0;for(let o=0;o<x.length;o++){const u=new Map,v=[];let j=0;const I=c((a,k,F,Y,D)=>{if(typeof a=="string"){if(a.length>=REPEATED_STRING_MIN_CHARS){const m=b.get(a)??u.get(a);if(m)return v.push({holder:Y,key:D,owner:m.owner,path:m.path}),`\u2026[lensmcp: same text as ${y}[${"9".repeat(E)}]${m.path}]`;u.set(a,{owner:o,path:k})}return a.length>S?(j+=1,shortenText(a,S)):a}if(F>=V)return a;if(Array.isArray(a)){const m=[];return a.forEach((T,P)=>m.push(I(T,`${k}[${P}]`,F+1,m,P))),m}if(N(a)){const m={};for(const T of Object.keys(a))m[T]=I(a[T],`${k}.${T}`,F+1,m,T);return m}return a},"slim"),L=[];let M=I(x[o],"",0,L,0),_=jsonBytes(M)+1;if(h.length===0&&w+_>e)M=O(x[o],Math.max(0,e-w-1)),_=jsonBytes(M)+1,v.length=0,u.clear(),j=1;else if(w+_>e)break;h.push(M),w+=_,A+=j,$+=v.length;for(const[a,k]of u)b.set(a,k);for(const a of v)p.push(a.holder===L?{...a,holder:h,key:h.length-1}:a)}const B=h.length,n=c(o=>l==="start"?o:B-1-o,"indexOf");if(l==="end"){for(const o of p)o.holder===h&&(o.key=n(o.key));h.reverse()}for(const o of p)o.holder[o.key]=`\u2026[lensmcp: same text as ${y}[${n(o.owner)}]${o.path}]`;return{items:h,total:i,returned:B,kept:B===i?"all":f?"newest":l==="start"?"first":"last",shortenedStrings:A,repeatedStrings:$,bytes:jsonBytes(h)}}d(fitList,"fitList"),g(fitList,"fitList"),c(fitList,"fitList");function O(t,e){let r=Math.max(256,e),i=t;for(let s=0;s<6;s++){if(i=z(t,{rawByteLimit:r,maxStringBytes:Math.min(2e3,Math.max(128,Math.floor(r/4))),maxArrayItems:64}).value,jsonBytes(i)<=e)return i;r=Math.floor(r*.6)}return i}d(O,"C"),g(O,"Y"),c(O,"clampTo");export function shareBudget(t,e){const r=t.map((f,l)=>({size:f,index:l})).sort((f,l)=>f.size-l.size),i=new Array(t.length).fill(0);let s=Math.max(0,e);return r.forEach(({size:f,index:l},y)=>{const S=Math.floor(s/(r.length-y));i[l]=Math.min(f,S),s-=i[l]}),i}d(shareBudget,"shareBudget"),g(shareBudget,"shareBudget"),c(shareBudget,"shareBudget");export function fitAnswer(t,e,r={}){if(!Number.isFinite(e)||t===null||typeof t!="object")return{value:t};const i=jsonBytes(t);if(i<=e)return{value:t};const s={limitBytes:e,originalBytes:i,lists:[],shortenedStrings:0,repeatedStrings:0,note:""},f=c(()=>{const n=s.lists.map(o=>`\`${o.list}\` shows the ${o.kept} ${o.returned} of ${o.total}`);s.note=`Cut to fit one tool result (${e} bytes; the whole answer is ${Number.isFinite(i)?i:"larger"}) \u2014 it is still one valid JSON document.`+(n.length?` ${n.join("; ")}; any other count in this document describes the whole list.`:"")+(s.shortenedStrings?` ${s.shortenedStrings} long text${s.shortenedStrings===1?" was":"s were"} cut to the head.`:"")+(s.repeatedStrings?` ${s.repeatedStrings} repeated text${s.repeatedStrings===1?" is":"s are"} stated once and referenced.`:"")+(s.clamped?" Large values outside the lists were shrunk too (see `__lensmcpTruncation`).":"")+(r.more?` ${r.more}`:"")+` Whole answer: start the lens with ${ANSWER_BUDGET_ENV}=0.`},"describe");if(Array.isArray(t)){const n=fitList(t,e);return n.kept!=="all"&&s.lists.push({list:"items",total:n.total,returned:n.returned,kept:n.kept}),s.shortenedStrings=n.shortenedStrings,s.repeatedStrings=n.repeatedStrings,f(),{value:n.items,cut:s}}if(!N(t))return{value:t};const l=Object.keys(t),y=l.filter(n=>Array.isArray(t[n])&&t[n].length>0),S=y.map(n=>jsonBytes(t[n])),x=i-S.reduce((n,o)=>n+o,0),E=shareBudget(S,e-x-R),b={};y.forEach((n,o)=>{if(S[o]<=E[o])return;const u=fitList(t[n],E[o],{name:n,...r.newest?.[n]?{newest:r.newest[n]}:{}});b[n]=u.items,u.kept!=="all"&&s.lists.push({list:n,total:u.total,returned:u.returned,kept:u.kept}),s.shortenedStrings+=u.shortenedStrings,s.repeatedStrings+=u.repeatedStrings});const p=c(n=>(f(),{[ANSWER_CUT_KEY]:s,...n}),"assemble"),h={};for(const n of l)h[n]=n in b?b[n]:t[n];let w=p(h);if(jsonBytes(w)<=e)return{value:w,cut:s};s.clamped=!0;let A=Math.max(512,e-R);for(let n=0;n<6;n++){if(w=p(O(h,A)),jsonBytes(w)<=e)return{value:w,cut:s};A=Math.floor(A*.6)}const $={};let B=R;for(const n of l){const o=t[n];if(o!==null&&typeof o=="object")continue;const u=jsonBytes(o)+utf8Bytes(n)+4;if(B+u>e)break;$[n]=o,B+=u}return{value:p($),cut:s}}d(fitAnswer,"fitAnswer"),g(fitAnswer,"fitAnswer"),c(fitAnswer,"fitAnswer");
|
package/lib/bus-rotation.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var m=Object.defineProperty;var i=(e,r)=>m(e,"name",{value:r,configurable:!0});var S=Object.defineProperty,y=i((e,r)=>S(e,"name",{value:r,configurable:!0}),"i"),f=Object.defineProperty,l=y((e,r)=>f(e,"name",{value:r,configurable:!0}),"u");export const MAX_BUS_GENERATIONS=20,BUS_ROTATE_CHECK_BYTES=1048576;export function busCapsFromEnv(e=process.env){const r=Number(e.LENSMCP_EVENT_MAX_BYTES),t=Number(e.LENSMCP_EVENT_MAX_FILES);return{maxBytes:Number.isFinite(r)&&r>0?r:50*1024*1024,maxFiles:Number.isFinite(t)&&t>=1&&t<=20?Math.floor(t):5}}i(busCapsFromEnv,"busCapsFromEnv"),y(busCapsFromEnv,"busCapsFromEnv"),l(busCapsFromEnv,"busCapsFromEnv");export function rotateBusFile(e,r){const{fs:t,maxBytes:u,maxFiles:a}=r,c=`${e}.rotate.lock`,o=r.staleLockMs??3e4;let s;for(let n=0;n<2&&s===void 0;n++)try{s=t.openSync(c,"wx")}catch{try{if(Date.now()-t.statSync(c).mtimeMs<=o)return"busy";t.unlinkSync(c)}catch{}}if(s===void 0)return"busy";try{try{if(t.statSync(e).size<=u)return"not-needed"}catch{return"not-needed"}try{t.unlinkSync(`${e}.${a}`)}catch{}for(let n=a+1;n<=20;n++)try{t.unlinkSync(`${e}.${n}`)}catch{}for(let n=a-1;n>=1;n--)try{t.renameSync(`${e}.${n}`,`${e}.${n+1}`)}catch{}try{t.renameSync(e,`${e}.1`)}catch{}return"rotated"}finally{try{t.closeSync(s)}catch{}try{t.unlinkSync(c)}catch{}}}i(rotateBusFile,"rotateBusFile"),y(rotateBusFile,"rotateBusFile"),l(rotateBusFile,"rotateBusFile");export function createBusRotator(e,r){const{fs:t,maxBytes:u}=r,a=Math.max(0,Math.min(r.checkEveryBytes??1048576,u));let c=a,o=0;return s=>{if(c>=a||o+c>u)try{o=t.statSync(e).size,c=0,o>u&&rotateBusFile(e,r)==="rotated"&&(o=0)}catch{}c+=s}}i(createBusRotator,"createBusRotator"),y(createBusRotator,"createBusRotator"),l(createBusRotator,"createBusRotator");
|
package/lib/event-bus.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var c=Object.defineProperty;var n=(s,t)=>c(s,"name",{value:t,configurable:!0});var a=Object.defineProperty,o=n((s,t)=>a(s,"name",{value:t,configurable:!0}),"n"),h=Object.defineProperty,u=o((s,t)=>h(s,"name",{value:t,configurable:!0}),"e");export class EventBus{static{n(this,"EventBus")}static{o(this,"EventBus")}static{u(this,"EventBus")}constructor(t={}){this.subs=new Set,this.dropped=0,this.capacity=t.capacity??1e4,this.onDrop=t.onDrop,this.transform=t.transform}publish(t){if(this.subs.size>this.capacity){this.dropped++,this.onDrop?.(1);return}let r=t;if(this.transform)try{r=this.transform(t)??t}catch{r=t}for(const e of this.subs)if(!(e.filter&&!e.filter(r)))try{const i=e.handler(r);i&&typeof i.then=="function"&&i.catch(()=>{})}catch{}}subscribe(t,r){const e={handler:t,filter:r};return this.subs.add(e),()=>{this.subs.delete(e)}}droppedCount(){return this.dropped}subscriberCount(){return this.subs.size}}
|
package/lib/event-redactor.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var m=Object.defineProperty;var o=(e,a)=>m(e,"name",{value:a,configurable:!0});var T=Object.defineProperty,v=o((e,a)=>T(e,"name",{value:a,configurable:!0}),"o"),y=Object.defineProperty,i=v((e,a)=>y(e,"name",{value:a,configurable:!0}),"a");import{MAX_MESSAGE_CHARS as E,MAX_TITLE_CHARS as S,redactDeep as _,redactSqlParams as g,redactText as f,safeText as R,safeTitle as x}from"./redact.js";export const BUS_REDACT_MAX_DEPTH=12;export function createEventRedactor(e={}){const a=e.maxDepth??BUS_REDACT_MAX_DEPTH;let s=0,r=0;return{redact(t){s+=1;const c=t.title===void 0?void 0:x(f(t.title)),n=t.message===void 0?void 0:R(f(t.message),E),d=t.raw===void 0?void 0:p(_(t.raw,0,a)),u=c!==t.title,A=n!==t.message,l=d!==t.raw;return!u&&!A&&!l?t:(r+=1,{...t,...c!==void 0?{title:c}:{},...n!==void 0?{message:n}:{},...d!==void 0?{raw:d}:{}})},stats:i(()=>({inspected:s,redacted:r}),"stats"),reset:i(()=>{s=0,r=0},"reset")}}o(createEventRedactor,"createEventRedactor"),v(createEventRedactor,"createEventRedactor"),i(createEventRedactor,"createEventRedactor");function p(e){if(!e||typeof e!="object"||Array.isArray(e))return e;const a=e,s=a.query,r=a.params;if(typeof s!="string"||!Array.isArray(r))return e;const t=g(s,r);return t===r?e:{...a,params:t}}o(p,"v"),v(p,"T"),i(p,"redactSqlShape");export{S as MAX_TITLE_CHARS};
|
package/lib/fingerprint.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var f=Object.defineProperty;var r=(e,t)=>f(e,"name",{value:t,configurable:!0});var l=Object.defineProperty,n=r((e,t)=>l(e,"name",{value:t,configurable:!0}),"r"),u=Object.defineProperty,o=n((e,t)=>u(e,"name",{value:t,configurable:!0}),"e");const d=2166136261,g=16777619;function a(e){let t=2166136261;for(let i=0;i<e.length;i++)t^=e.charCodeAt(i),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}r(a,"o"),n(a,"i"),o(a,"fnv1a32");export function fingerprint(e){const t=[e.kind,e.identity,e.file??"",e.detail??""];return`${e.kind}:${a(t.join("|"))}`}r(fingerprint,"fingerprint"),n(fingerprint,"fingerprint"),o(fingerprint,"fingerprint");
|
package/lib/flow-categories.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var M=Object.defineProperty;var c=(e,t)=>M(e,"name",{value:t,configurable:!0});var F=Object.defineProperty,d=c((e,t)=>F(e,"name",{value:t,configurable:!0}),"u"),T=Object.defineProperty,s=d((e,t)=>T(e,"name",{value:t,configurable:!0}),"s");export const CATEGORY_ORDER=["user-action","page-load","navigation","api","ai","background","test","system","other"];const f=new Map;export function globMatch(e,t){let n=f.get(e);return n||(n=new RegExp(`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".")}$`),f.size>500&&f.clear(),f.set(e,n)),n.test(t)}c(globMatch,"globMatch"),d(globMatch,"globMatch"),s(globMatch,"globMatch");const S=s(e=>/^[A-Z]+ /.test(e),"hasMethod");function v(e,t){return t.some(n=>n.route?S(e)?globMatch(e,`${n.method??"GET"} ${n.route}`):globMatch(e,n.route):!1)}c(v,"w"),d(v,"T"),s(v,"routeMatches");function m(e,t){return!([e.flowId,e.originType,e.origin,e.route,e.project].filter(n=>n!==void 0).length===0||e.flowId!==void 0&&!globMatch(e.flowId,t.flowId)||e.originType!==void 0&&e.originType!==t.origin.type||e.origin!==void 0&&!(t.origin.nodeId!==void 0&&globMatch(e.origin,t.origin.nodeId))||e.route!==void 0&&!v(e.route,t.segments)||e.project!==void 0&&!t.segments.some(n=>n.projects.some(r=>globMatch(e.project,r))))}c(m,"m"),d(m,"b"),s(m,"ruleMatches");const b=s(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),p=s(e=>typeof e=="string"&&e!==""?e:void 0,"str"),y=s(e=>b(e.raw)?p(e.raw.kind)??"":"","kindOf");function h(e){const t=[...e].sort((a,l)=>(Number(a.timestamp)||0)-(Number(l.timestamp)||0)||(a.id<l.id?-1:1)),n=t.find(a=>y(a)==="flow-origin"),r=n??t.find(a=>p(a.context?.originType));if(!r)return{};const o=b(r.raw)?r.raw:{},i=p(r.context?.originType)??(n?p(r.title):void 0),u=p(o.originNodeId)??p(r.context?.originNodeId);return{...i?{type:i}:{},...u?{nodeId:u}:{}}}c(h,"k"),d(h,"$"),s(h,"originOf");const z=/^(verify|e2e|test|smoke|load)[-_:]/i,B=s((e,t)=>z.test(e)||t!==void 0&&/^(ui:)?(tools|scripts?|e2e)\//.test(t),"isTestFlow"),O={"page-load":"page-load","user-click":"user-action","form-submit":"user-action","input-change":"user-action","double-click":"user-action","context-menu":"user-action","key-press":"user-action","route-load":"navigation","route-change":"navigation",navigation:"navigation","ai-turn":"ai",request:"api",timer:"background",cron:"background",interval:"background",queue:"background",job:"background","websocket-message":"background","hmr-update":"system"},A=new Set(["page-load","user-action","navigation"]),E=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;export function templatePath(e){return e.replace(/[?#].*$/,"").split("/").map(t=>E.test(t)||/^[0-9a-f]{16,}$/i.test(t)||/^\d{2,}$/.test(t)?":id":t).join("/")}c(templatePath,"templatePath"),d(templatePath,"templatePath"),s(templatePath,"templatePath");function w(e){const t=/^ui:(?:.*\/)?([^/:]+?)(?:\.[a-z]+)?:\d+:([A-Za-z]+)$/.exec(e);return t?`${t[1]} \xB7 ${t[2]}`:e}c(w,"$"),d(w,"x"),s(w,"componentOf");export function scriptFamily(e){let t=e.replace(/[-_:][0-9a-f]{6,}(?:-[0-9a-f]+)*$/i,"");return t=t.replace(/[-_:](?=[a-z0-9]*\d)[a-z0-9]{6,}$/i,""),t=t.replace(/[-_:]\d+$/,""),t||e}c(scriptFamily,"scriptFamily"),d(scriptFamily,"scriptFamily"),s(scriptFamily,"scriptFamily");function k(e,t,n,r){const o=t.nodeId,i=o?/^(page|route|ambient):(.*)$/.exec(o):null;if(i)return`${i[1]}:${templatePath(i[2])}`;if(t.type&&O[t.type]==="user-action"&&o)return w(o);if(e==="test")return scriptFamily(n.flowId);const u=n.segments.find(l=>l.kind==="request"&&l.route);if(u?.route)return`${u.method??"GET"} ${templatePath(u.route)}`;const a=r.find(l=>y(l)==="ai-call");return a&&b(a.raw)?`ai \xB7 ${p(a.raw.model)??p(a.raw.provider)??"call"}`:o?templatePath(o):void 0}c(k,"x"),d(k,"q"),s(k,"subjectOf");const _=10,C=1e3,N=3,P=500,R=1e3;function $(e,t){const n=new Set,r=t.segments.filter(i=>i.kind==="request");t.segments.some(i=>i.counts.errors>0)&&n.add("has-error"),r.some(i=>i.durationMs>=C)&&n.add("slow"),r.length>=_&&n.add("fan-out"),new Set(t.segments.flatMap(i=>i.projects)).size>=3&&n.add("multi-service"),e.some(i=>y(i)==="queue-enqueued")&&n.add("queue"),e.some(i=>y(i)==="ai-call"||i.source==="ai")&&n.add("ai"),t.stats.bookkeeping>=P&&t.stats.bookkeeping*2>=t.stats.events&&n.add("storm"),t.stats.events>=R&&n.add("large");const o=new Map;for(const i of r)(!i.part||i.part.index===1)&&o.set(i.label,(o.get(i.label)??0)+1);return[...o.values()].some(i=>i>=N)&&n.add("repeated-requests"),[...n].sort()}c($,"j"),d($,"F"),s($,"tagsOf");export function classifyFlow(e,t,n=[]){const r=h(e),o={flowId:t.flowId,origin:r,segments:t.segments},i=$(e,t),u=s((g,q,I)=>{const j=k(g,r,t,e);return{category:g,decidedBy:q,...I!==void 0?{ruleIndex:I}:{},tags:i,origin:r,...j?{subject:j}:{}}},"done"),a=n.findIndex(g=>g.category&&m(g,o));if(a!==-1)return u(n[a].category,"rule",a);if(B(t.flowId,r.nodeId))return u("test","test");const l=r.type?O[r.type]:void 0;if(l)return u(l,"origin");if(i.includes("ai"))return u("ai","shape");const x=t.segments.filter(g=>g.kind==="request");return x.length>0?u(x.every(g=>g.requestId?.startsWith("job:"))?"background":"api","shape"):t.segments.length>0&&t.segments.every(g=>g.kind==="ambient")?u("system","shape"):u("other","shape")}c(classifyFlow,"classifyFlow"),d(classifyFlow,"classifyFlow"),s(classifyFlow,"classifyFlow");export function categoryOfSegment(e,t,n=[]){const r=n.find(o=>o.category&&(o.route!==void 0||o.project!==void 0)&&o.flowId===void 0&&o.origin===void 0&&o.originType===void 0&&m(o,{flowId:e.flowId,origin:t.origin,segments:[e]}));return r?r.category:e.kind==="request"?e.requestId?.startsWith("job:")?"background":"api":e.kind==="ambient"?"system":e.kind==="origin"&&A.has(t.category)?t.category:"ui"}c(categoryOfSegment,"categoryOfSegment"),d(categoryOfSegment,"categoryOfSegment"),s(categoryOfSegment,"categoryOfSegment");export function groupFlows(e){return groupByCategory(e).map(t=>{const n=new Map;for(const o of t.items){const i=n.get(o.subject);i?i.push(o):n.set(o.subject,[o])}const r=[...n.entries()].sort((o,i)=>(o[0]===void 0?1:0)-(i[0]===void 0?1:0)||i[1].length-o[1].length||String(o[0]).localeCompare(String(i[0]))).map(([o,i])=>({subject:o,count:i.length,items:i}));return{...t,subjects:r}})}c(groupFlows,"groupFlows"),d(groupFlows,"groupFlows"),s(groupFlows,"groupFlows");export function groupByCategory(e){const t=new Map;for(const r of e){const o=t.get(r.category);o?o.push(r):t.set(r.category,[r])}const n=s(r=>{const o=CATEGORY_ORDER.indexOf(r);return o===-1?CATEGORY_ORDER.length:o},"rank");return[...t.entries()].sort((r,o)=>n(r[0])-n(o[0])||(r[0]<o[0]?-1:r[0]>o[0]?1:0)).map(([r,o])=>({category:r,count:o.length,items:o}))}c(groupByCategory,"groupByCategory"),d(groupByCategory,"groupByCategory"),s(groupByCategory,"groupByCategory");
|
package/lib/flow-segments.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var z=Object.defineProperty;var j=(e,t)=>z(e,"name",{value:t,configurable:!0});var Q=Object.defineProperty,g=j((e,t)=>Q(e,"name",{value:t,configurable:!0}),"g");export const DEFAULT_SEGMENT_OPTIONS={phaseGapMs:1500,burstGapMs:250,attachWindowMs:400,maxSegmentEvents:400,occurrenceSlackMs:10},FLOW_BOOKKEEPING_KINDS=new Set(["subscription-added","subscription-removed","hook-run","store-created","singleton-instance","visual-frame"]),SQL_ACCOUNT_KIND="db-request-account";const H=new Set(["react","valtio","client-runtime","chrome","visual"]),O=g(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),k=g(e=>typeof e=="string"&&e!==""?e:void 0,"str"),v=g(e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,"num");function E(e){const t=O(e.raw)?e.raw:{},s=O(t.request)?t.request:{},r=O(t.span)?t.span:{},d=e.context??{},n=k(t.kind)??"",f=n===SQL_ACCOUNT_KIND,p=(f?v(t.lastEndedAt):void 0)??v(e.timestamp)??0,h=v(s.startedAt)??v(r.startTime)??v(t.startedAt)??(f?v(t.firstStartedAt):void 0),$=v(s.endedAt)??v(r.endTime)??(h!==void 0&&v(t.durationMs)!==void 0?h+t.durationMs:void 0),b=Math.min(p,h??p),M=Math.max(p,$??p),c=O(t.render)?t.render:{},u=O(t.update)?t.update:{},i=n==="render"?k(c.componentName):n==="state-update"?k(u.path)?.split(".").slice(0,2).join("."):void 0,a=k(t.queue),l=k(t.jobId),I=String(e.source),o=k(t.project)??k(d.projectName);return{event:e,id:e.id,ts:p,from:b,to:M,kind:n,source:I,...k(d.requestId)?{requestId:k(d.requestId)}:{},...k(d.parentRequestId)?{parentRequestId:k(d.parentRequestId)}:{},...a&&l?{queueKey:`${a}#${l}`}:{},browser:H.has(I)||I==="memory"&&o===void 0,bookkeeping:FLOW_BOOKKEEPING_KINDS.has(n),...o?{project:o}:{},...i?{subject:i}:{},...n==="fetch-start"||n==="fetch-done"?{route:S(k(t.url)),method:k(t.method)}:n==="server-request"?{route:k(s.route),method:k(s.method)}:n==="gateway-request"?{route:S(k(t.url)),method:k(t.method)}:{}}}j(E,"W"),g(E,"readItem");function S(e){if(!e)return;const t=e.search(/[?#]/),s=t===-1?e:e.slice(0,t),r=/^[a-z][a-z0-9+.-]*:\/\/[^/]*(\/.*)?$/i.exec(s);return r?r[1]??"/":s}j(S,"A"),g(S,"pathOnly");const J=g(e=>e.split(".")[0],"rootOf"),F=g((e,t)=>e.reduce((s,r)=>Math.min(s,t(r)),1/0),"minOf"),G=g((e,t)=>e.reduce((s,r)=>Math.max(s,t(r)),-1/0),"maxOf"),K=g((e,t)=>e.ts-t.ts||(e.id<t.id?-1:e.id>t.id?1:0),"compare"),A=g(e=>e.requestId&&!e.requestId.startsWith("job:")?J(e.requestId):void 0,"directFamilyOf");function T(e){if(e.requestId?.startsWith("job:"))return e.requestId.slice(4);if(e.queueKey&&e.kind!=="queue-enqueued"&&!e.requestId)return e.queueKey}j(T,"U"),g(T,"jobKeyOf");function W(e,t){const s=e.filter(n=>!n.parentRequestId&&(n.kind==="server-request"||n.kind==="gateway-request"||n.kind==="fetch-start"||n.kind==="fetch-done")).sort((n,f)=>n.from-f.from||K(n,f));if(s.length<2)return[e];const r=[];for(const n of s){const f=r[r.length-1];f&&n.from<=f.to+t?f.to=Math.max(f.to,n.to):r.push({from:n.from,to:n.to})}if(r.length<2)return[e];const d=r.map(()=>[]);for(const n of e){let f=r.findIndex(p=>n.ts>=p.from-t&&n.ts<=p.to+t);if(f===-1){f=0;for(let p=0;p<r.length;p+=1)r[p].from<=n.ts&&(f=p)}d[f].push(n)}return d.filter(n=>n.length>0)}j(W,"L"),g(W,"occurrencesOf");const _={debug:0,info:1,warning:2,error:3,fatal:4};function N(e,t){const s=[];let r=[];for(const d of e){const n=r[r.length-1];n&&d.ts-n.ts>=t&&(s.push(r),r=[]),r.push(d)}return r.length&&s.push(r),s}j(N,"R"),g(N,"runs");export function segmentFlow(e,t={}){const s={...DEFAULT_SEGMENT_OPTIONS};for(const[o,m]of Object.entries(t))typeof m=="number"&&Number.isFinite(m)&&(s[o]=m);const r=new Set,d=[];for(const o of e)r.has(o.id)||(r.add(o.id),d.push(E(o)));d.sort(K);const n=k(d[0]?.event.context?.flowId)??k(d[0]?.event.raw?.flowId)??"",f=new Map;for(const o of d)o.kind==="queue-enqueued"&&o.queueKey&&o.requestId&&!o.requestId.startsWith("job:")&&!f.has(o.queueKey)&&f.set(o.queueKey,o);const p=new Map,h=new Map,$=[];for(const o of d){const m=T(o),w=A(o);if(m!==void 0){const q=h.get(m);q?q.push(o):h.set(m,[o])}else if(w!==void 0){const q=p.get(w);q?q.push(o):p.set(w,[o])}else $.push(o)}const b=[],M=new Map;for(const[o,m]of p)W(m,s.occurrenceSlackMs).forEach((w,q)=>{const x={id:`${n}~r:${o}${q===0?"":`@${q+1}`}`,kind:"request",items:w,requestId:o};b.push(x);for(const y of w)M.set(y,x)});for(const[o,m]of h){const w=f.get(o),q=w?M.get(w):void 0;q?q.items.push(...m):b.push({id:`${n}~r:job:${o}`,kind:"request",items:m,requestId:`job:${o}`})}const c=d.filter(o=>o.kind==="fetch-done"&&A(o)!==void 0),u=new Map;for(const o of b)o.requestId&&u.set(o.requestId,[...u.get(o.requestId)??[],o]);const i=g((o,m)=>{const w=u.get(o);if(w)return w.find(q=>q.items.some(x=>x.kind==="fetch-done"&&x.ts===m))??w[w.length-1]},"owningUnit"),a=$.filter(o=>o.browser);for(const o of N(a,s.burstGapMs)){const m=o[0].ts,w=c.filter(y=>y.ts<=m&&m-y.ts<=s.attachWindowMs),q=[...new Set(w.map(y=>A(y)))];if(q.length===1){const y=i(q[0],w[w.length-1].ts);if(y){y.items.push(...o);continue}}const x=o.some(y=>y.kind==="flow-origin");b.push({id:`${n}~${x?"o":"u"}:${o[0].id}`,kind:x?"origin":"ui",items:o,...q.length>1?{after:q.sort()}:{}})}for(const o of N($.filter(m=>!m.browser),s.phaseGapMs))b.push({id:`${n}~a:${o[0].id}`,kind:"ambient",items:o});const l=B(n,d.length,b,s),I=sqlAccountingOf(d.map(o=>o.event));return I?{...l,sql:I}:l}j(segmentFlow,"segmentFlow"),g(segmentFlow,"segmentFlow");function B(e,t,s,r){for(const c of s)c.items.sort(K);const d=s.map(c=>({unit:c,from:F(c.items,u=>u.from),to:G(c.items,u=>u.to)}));d.sort((c,u)=>c.from-u.from||(c.unit.id<u.unit.id?-1:1));const n=new Map;let f=0,p=-1/0;for(const c of d)(f===0||c.from-p>=r.phaseGapMs)&&(f+=1),p=Math.max(p,c.to),n.set(c.unit,f);const h=[];for(const c of d){const u=R(c.unit.items,r.maxSegmentEvents),i=c.unit.kind==="request"?sqlAccountingOf(c.unit.items.map(a=>a.event)):void 0;u.forEach((a,l)=>{const I=U(e,c.unit,a,n.get(c.unit),u.length>1?{index:l+1,total:u.length}:void 0);h.push(i&&l===0?{...I,sql:i}:I)})}const $={};for(const c of h)for(const u of c.eventIds)$[u]=c.id;const b=[];for(const c of h){let u=b[c.phase-1];u||(u={index:c.phase,start:c.start,end:c.end,segmentIds:[]},b[c.phase-1]=u),u.start=Math.min(u.start,c.start),u.end=Math.max(u.end,c.end),u.segmentIds.push(c.id)}const M=h.reduce((c,u)=>c+u.counts.signal,0);return{flowId:e,segments:h,phases:b.filter(Boolean),assignment:$,stats:{events:t,signal:M,bookkeeping:t-M,segments:h.length,phases:b.filter(Boolean).length,largestSegment:h.reduce((c,u)=>Math.max(c,u.counts.total),0)}}}j(B,"B"),g(B,"assemble");function R(e,t){if(e.filter(n=>!n.bookkeeping).length<=t)return[e];const s=[];let r=[],d=0;for(const n of e)!n.bookkeeping&&d===t&&(s.push(r),r=[],d=0),r.push(n),n.bookkeeping||(d+=1);return r.length&&s.push(r),s}j(R,"C"),g(R,"chunk");function U(e,t,s,r,d){const n={total:s.length,signal:0,bookkeeping:0,errors:0,warnings:0},f=new Set;let p="debug";for(const u of s){u.bookkeeping?n.bookkeeping+=1:n.signal+=1;const i=String(u.event.severity);i==="error"||i==="fatal"?n.errors+=1:i==="warning"&&(n.warnings+=1),(_[i]??1)>(_[p]??0)&&(p=i),u.project&&f.add(u.project)}const h=t.kind==="ui"||t.kind==="origin"?C(s):[],$=F(s,u=>u.from),b=G(s,u=>u.to),M=D(t.items),c=t.id;return{id:d&&d.index>1?`${c}#${d.index}`:c,flowId:e,kind:t.kind,label:L(t,s,M,d,h),phase:r,start:$,end:b,durationMs:b-$,eventIds:s.map(u=>u.id),counts:n,projects:[...f].sort(),...M.route?{route:M.route}:{},...M.method?{method:M.method}:{},...t.requestId?{requestId:t.requestId}:{},...t.after?{after:t.after}:{},...h.length?{hot:h}:{},...d?{part:d}:{},worstSeverity:p}}j(U,"D"),g(U,"toSegment");function D(e){const t=e.find(s=>s.kind==="fetch-start"&&s.route)??e.find(s=>s.kind==="server-request"&&!s.parentRequestId&&s.route)??e.find(s=>s.kind==="gateway-request"&&s.route)??e.find(s=>s.kind==="fetch-done"&&s.route);return{...t?.route?{route:t.route}:{},...t?.method?{method:t.method.toUpperCase()}:{}}}j(D,"P"),g(D,"routeOf");function C(e){const t=new Map;for(const s of e)s.subject&&!s.bookkeeping&&t.set(s.subject,(t.get(s.subject)??0)+1);return[...t.entries()].sort((s,r)=>r[1]-s[1]||(s[0]<r[0]?-1:1)).slice(0,3).map(([s,r])=>r>1?`${s} \xD7${r}`:s)}j(C,"z"),g(C,"hotOf");function L(e,t,s,r,d){const n=r?` (part ${r.index}/${r.total})`:"";if(e.kind==="request"){if(s.route)return`${s.method?`${s.method} `:""}${s.route}${n}`;const f=t.find(p=>p.queueKey);return f?`job ${f.queueKey}${n}`:`request ${e.requestId??""}${n}`}return e.kind==="origin"?`${t.find(f=>f.kind==="flow-origin")?.event.title||"start"}${d.length?` \xB7 ${d.join(", ")}`:""}${n}`:e.kind==="ui"?`UI update${d.length?` \xB7 ${d.join(", ")}`:""}${n}`:`background${n}`}j(L,"Q"),g(L,"labelOf");const P=50;export function sqlAccountingOf(e){const t=new Map,s=new Map,r=new Set;for(const i of e){if(r.has(i.id))continue;r.add(i.id);const a=O(i.raw)?i.raw:{},l=k(a.kind),I=k(i.context?.requestId);if(!I)continue;const o=k(a.project)??k(i.context?.projectName);if(l==="db-query"&&i.source==="db"){const m=s.get(I)??{count:0,workMs:0,...o?{project:o}:{}};m.count+=1,m.workMs+=v(a.durationMs)??0,s.set(I,m)}else if(l===SQL_ACCOUNT_KIND){const m=k(a.accountId)??i.id,w=v(a.seq)??0,q=t.get(m);if(q&&q.seq>=w)continue;t.set(m,{requestId:I,...o?{project:o}:{},seq:w,basis:a.basis==="end"?"end":"settled",statements:v(a.statements)??0,failed:v(a.failed)??0,workMs:v(a.workMs)??0,recorded:v(a.recorded)??0,suppressed:v(a.suppressed)??0,unwritten:v(a.unwritten)??0})}}const d=new Map;for(const i of t.values()){const a=d.get(i.requestId);if(!a){d.set(i.requestId,{...i});continue}i.basis==="settled"&&(a.basis="settled"),a.statements+=i.statements,a.failed+=i.failed,a.workMs+=i.workMs,a.recorded+=i.recorded,a.suppressed+=i.suppressed,a.unwritten+=i.unwritten}const n=[...new Set([...s.keys(),...d.keys()])].sort();if(n.length===0)return;const f={statements:0,failed:0,workMs:0,recorded:0,suppressed:0,unwritten:0},p={statements:0,workMs:0},h=[];for(const i of n){const a=s.get(i),l=d.get(i),I=a?.count??0;p.statements+=I,p.workMs+=a?.workMs??0;const o=!l||I>l.statements?"unverified":I===l.statements?"complete":"incomplete";l&&o!=="unverified"&&(f.statements+=l.statements,f.failed+=l.failed,f.workMs+=l.workMs,f.recorded+=l.recorded,f.suppressed+=l.suppressed,f.unwritten+=l.unwritten);const m=a?.project??l?.project;h.push({requestId:i,...m?{project:m}:{},status:o,observed:I,observedWorkMs:a?.workMs??0,...l?{basis:l.basis,statements:l.statements,failed:l.failed,workMs:l.workMs,recorded:l.recorded,suppressed:l.suppressed,unwritten:l.unwritten}:{}})}const $=g(i=>h.filter(a=>a.status===i).length,"tally"),b=$("unverified"),M=$("incomplete"),c=g(i=>(i.statements??0)-i.observed,"missing"),u=h.filter(i=>i.status!=="complete").sort((i,a)=>(i.status==="incomplete"?0:1)-(a.status==="incomplete"?0:1)||c(a)-c(i)||(i.requestId<a.requestId?-1:i.requestId>a.requestId?1:0));return{status:b>0?"unverified":M>0?"incomplete":"complete",requests:h.length,complete:$("complete"),incomplete:M,unverified:b,settled:h.filter(i=>i.status!=="unverified"&&i.basis==="settled").length,observed:p,accounted:f,gaps:u.slice(0,P),gapsTruncated:u.length>P}}j(sqlAccountingOf,"sqlAccountingOf"),g(sqlAccountingOf,"sqlAccountingOf");
|
|
1
|
+
"use strict";var Q=Object.defineProperty;var j=(e,t)=>Q(e,"name",{value:t,configurable:!0});var H=Object.defineProperty,y=j((e,t)=>H(e,"name",{value:t,configurable:!0}),"j"),J=Object.defineProperty,g=y((e,t)=>J(e,"name",{value:t,configurable:!0}),"g");export const DEFAULT_SEGMENT_OPTIONS={phaseGapMs:1500,burstGapMs:250,attachWindowMs:400,maxSegmentEvents:400,occurrenceSlackMs:10},FLOW_BOOKKEEPING_KINDS=new Set(["subscription-added","subscription-removed","hook-run","store-created","singleton-instance","visual-frame"]),SQL_ACCOUNT_KIND="db-request-account";const V=new Set(["react","valtio","client-runtime","chrome","visual"]),S=g(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),q=g(e=>typeof e=="string"&&e!==""?e:void 0,"str"),v=g(e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,"num");function N(e){const t=S(e.raw)?e.raw:{},s=S(t.request)?t.request:{},r=S(t.span)?t.span:{},u=e.context??{},n=q(t.kind)??"",f=n===SQL_ACCOUNT_KIND,p=(f?v(t.lastEndedAt):void 0)??v(e.timestamp)??0,h=v(s.startedAt)??v(r.startTime)??v(t.startedAt)??(f?v(t.firstStartedAt):void 0),$=v(s.endedAt)??v(r.endTime)??(h!==void 0&&v(t.durationMs)!==void 0?h+t.durationMs:void 0),b=Math.min(p,h??p),M=Math.max(p,$??p),c=S(t.render)?t.render:{},d=S(t.update)?t.update:{},i=n==="render"?q(c.componentName):n==="state-update"?q(d.path)?.split(".").slice(0,2).join("."):void 0,a=q(t.queue),l=q(t.jobId),I=String(e.source),o=q(t.project)??q(u.projectName);return{event:e,id:e.id,ts:p,from:b,to:M,kind:n,source:I,...q(u.requestId)?{requestId:q(u.requestId)}:{},...q(u.parentRequestId)?{parentRequestId:q(u.parentRequestId)}:{},...a&&l?{queueKey:`${a}#${l}`}:{},browser:V.has(I)||I==="memory"&&o===void 0,bookkeeping:FLOW_BOOKKEEPING_KINDS.has(n),...o?{project:o}:{},...i?{subject:i}:{},...n==="fetch-start"||n==="fetch-done"?{route:A(q(t.url)),method:q(t.method)}:n==="server-request"?{route:q(s.route),method:q(s.method)}:n==="gateway-request"?{route:A(q(t.url)),method:q(t.method)}:{}}}j(N,"E"),y(N,"W"),g(N,"readItem");function A(e){if(!e)return;const t=e.search(/[?#]/),s=t===-1?e:e.slice(0,t),r=/^[a-z][a-z0-9+.-]*:\/\/[^/]*(\/.*)?$/i.exec(s);return r?r[1]??"/":s}j(A,"S"),y(A,"A"),g(A,"pathOnly");const X=g(e=>e.split(".")[0],"rootOf"),P=g((e,t)=>e.reduce((s,r)=>Math.min(s,t(r)),1/0),"minOf"),C=g((e,t)=>e.reduce((s,r)=>Math.max(s,t(r)),-1/0),"maxOf"),E=g((e,t)=>e.ts-t.ts||(e.id<t.id?-1:e.id>t.id?1:0),"compare"),F=g(e=>e.requestId&&!e.requestId.startsWith("job:")?X(e.requestId):void 0,"directFamilyOf");function W(e){if(e.requestId?.startsWith("job:"))return e.requestId.slice(4);if(e.queueKey&&e.kind!=="queue-enqueued"&&!e.requestId)return e.queueKey}j(W,"T"),y(W,"U"),g(W,"jobKeyOf");function G(e,t){const s=e.filter(n=>!n.parentRequestId&&(n.kind==="server-request"||n.kind==="gateway-request"||n.kind==="fetch-start"||n.kind==="fetch-done")).sort((n,f)=>n.from-f.from||E(n,f));if(s.length<2)return[e];const r=[];for(const n of s){const f=r[r.length-1];f&&n.from<=f.to+t?f.to=Math.max(f.to,n.to):r.push({from:n.from,to:n.to})}if(r.length<2)return[e];const u=r.map(()=>[]);for(const n of e){let f=r.findIndex(p=>n.ts>=p.from-t&&n.ts<=p.to+t);if(f===-1){f=0;for(let p=0;p<r.length;p+=1)r[p].from<=n.ts&&(f=p)}u[f].push(n)}return u.filter(n=>n.length>0)}j(G,"W"),y(G,"L"),g(G,"occurrencesOf");const L={debug:0,info:1,warning:2,error:3,fatal:4};function K(e,t){const s=[];let r=[];for(const u of e){const n=r[r.length-1];n&&u.ts-n.ts>=t&&(s.push(r),r=[]),r.push(u)}return r.length&&s.push(r),s}j(K,"N"),y(K,"R"),g(K,"runs");export function segmentFlow(e,t={}){const s={...DEFAULT_SEGMENT_OPTIONS};for(const[o,m]of Object.entries(t))typeof m=="number"&&Number.isFinite(m)&&(s[o]=m);const r=new Set,u=[];for(const o of e)r.has(o.id)||(r.add(o.id),u.push(N(o)));u.sort(E);const n=q(u[0]?.event.context?.flowId)??q(u[0]?.event.raw?.flowId)??"",f=new Map;for(const o of u)o.kind==="queue-enqueued"&&o.queueKey&&o.requestId&&!o.requestId.startsWith("job:")&&!f.has(o.queueKey)&&f.set(o.queueKey,o);const p=new Map,h=new Map,$=[];for(const o of u){const m=W(o),w=F(o);if(m!==void 0){const k=h.get(m);k?k.push(o):h.set(m,[o])}else if(w!==void 0){const k=p.get(w);k?k.push(o):p.set(w,[o])}else $.push(o)}const b=[],M=new Map;for(const[o,m]of p)G(m,s.occurrenceSlackMs).forEach((w,k)=>{const O={id:`${n}~r:${o}${k===0?"":`@${k+1}`}`,kind:"request",items:w,requestId:o};b.push(O);for(const x of w)M.set(x,O)});for(const[o,m]of h){const w=f.get(o),k=w?M.get(w):void 0;k?k.items.push(...m):b.push({id:`${n}~r:job:${o}`,kind:"request",items:m,requestId:`job:${o}`})}const c=u.filter(o=>o.kind==="fetch-done"&&F(o)!==void 0),d=new Map;for(const o of b)o.requestId&&d.set(o.requestId,[...d.get(o.requestId)??[],o]);const i=g((o,m)=>{const w=d.get(o);if(w)return w.find(k=>k.items.some(O=>O.kind==="fetch-done"&&O.ts===m))??w[w.length-1]},"owningUnit"),a=$.filter(o=>o.browser);for(const o of K(a,s.burstGapMs)){const m=o[0].ts,w=c.filter(x=>x.ts<=m&&m-x.ts<=s.attachWindowMs),k=[...new Set(w.map(x=>F(x)))];if(k.length===1){const x=i(k[0],w[w.length-1].ts);if(x){x.items.push(...o);continue}}const O=o.some(x=>x.kind==="flow-origin");b.push({id:`${n}~${O?"o":"u"}:${o[0].id}`,kind:O?"origin":"ui",items:o,...k.length>1?{after:k.sort()}:{}})}for(const o of K($.filter(m=>!m.browser),s.phaseGapMs))b.push({id:`${n}~a:${o[0].id}`,kind:"ambient",items:o});const l=T(n,u.length,b,s),I=sqlAccountingOf(u.map(o=>o.event));return I?{...l,sql:I}:l}j(segmentFlow,"segmentFlow"),y(segmentFlow,"segmentFlow"),g(segmentFlow,"segmentFlow");function T(e,t,s,r){for(const c of s)c.items.sort(E);const u=s.map(c=>({unit:c,from:P(c.items,d=>d.from),to:C(c.items,d=>d.to)}));u.sort((c,d)=>c.from-d.from||(c.unit.id<d.unit.id?-1:1));const n=new Map;let f=0,p=-1/0;for(const c of u)(f===0||c.from-p>=r.phaseGapMs)&&(f+=1),p=Math.max(p,c.to),n.set(c.unit,f);const h=[];for(const c of u){const d=B(c.unit.items,r.maxSegmentEvents),i=c.unit.kind==="request"?sqlAccountingOf(c.unit.items.map(a=>a.event)):void 0;d.forEach((a,l)=>{const I=R(e,c.unit,a,n.get(c.unit),d.length>1?{index:l+1,total:d.length}:void 0);h.push(i&&l===0?{...I,sql:i}:I)})}const $={};for(const c of h)for(const d of c.eventIds)$[d]=c.id;const b=[];for(const c of h){let d=b[c.phase-1];d||(d={index:c.phase,start:c.start,end:c.end,segmentIds:[]},b[c.phase-1]=d),d.start=Math.min(d.start,c.start),d.end=Math.max(d.end,c.end),d.segmentIds.push(c.id)}const M=h.reduce((c,d)=>c+d.counts.signal,0);return{flowId:e,segments:h,phases:b.filter(Boolean),assignment:$,stats:{events:t,signal:M,bookkeeping:t-M,segments:h.length,phases:b.filter(Boolean).length,largestSegment:h.reduce((c,d)=>Math.max(c,d.counts.total),0)}}}j(T,"B"),y(T,"B"),g(T,"assemble");function B(e,t){if(e.filter(n=>!n.bookkeeping).length<=t)return[e];const s=[];let r=[],u=0;for(const n of e)!n.bookkeeping&&u===t&&(s.push(r),r=[],u=0),r.push(n),n.bookkeeping||(u+=1);return r.length&&s.push(r),s}j(B,"R"),y(B,"C"),g(B,"chunk");function R(e,t,s,r,u){const n={total:s.length,signal:0,bookkeeping:0,errors:0,warnings:0},f=new Set;let p="debug";for(const d of s){d.bookkeeping?n.bookkeeping+=1:n.signal+=1;const i=String(d.event.severity);i==="error"||i==="fatal"?n.errors+=1:i==="warning"&&(n.warnings+=1),(L[i]??1)>(L[p]??0)&&(p=i),d.project&&f.add(d.project)}const h=t.kind==="ui"||t.kind==="origin"?_(s):[],$=P(s,d=>d.from),b=C(s,d=>d.to),M=U(t.items),c=t.id;return{id:u&&u.index>1?`${c}#${u.index}`:c,flowId:e,kind:t.kind,label:D(t,s,M,u,h),phase:r,start:$,end:b,durationMs:b-$,eventIds:s.map(d=>d.id),counts:n,projects:[...f].sort(),...M.route?{route:M.route}:{},...M.method?{method:M.method}:{},...t.requestId?{requestId:t.requestId}:{},...t.after?{after:t.after}:{},...h.length?{hot:h}:{},...u?{part:u}:{},worstSeverity:p}}j(R,"U"),y(R,"D"),g(R,"toSegment");function U(e){const t=e.find(s=>s.kind==="fetch-start"&&s.route)??e.find(s=>s.kind==="server-request"&&!s.parentRequestId&&s.route)??e.find(s=>s.kind==="gateway-request"&&s.route)??e.find(s=>s.kind==="fetch-done"&&s.route);return{...t?.route?{route:t.route}:{},...t?.method?{method:t.method.toUpperCase()}:{}}}j(U,"D"),y(U,"P"),g(U,"routeOf");function _(e){const t=new Map;for(const s of e)s.subject&&!s.bookkeeping&&t.set(s.subject,(t.get(s.subject)??0)+1);return[...t.entries()].sort((s,r)=>r[1]-s[1]||(s[0]<r[0]?-1:1)).slice(0,3).map(([s,r])=>r>1?`${s} \xD7${r}`:s)}j(_,"C"),y(_,"z"),g(_,"hotOf");function D(e,t,s,r,u){const n=r?` (part ${r.index}/${r.total})`:"";if(e.kind==="request"){if(s.route)return`${s.method?`${s.method} `:""}${s.route}${n}`;const f=t.find(p=>p.queueKey);return f?`job ${f.queueKey}${n}`:`request ${e.requestId??""}${n}`}return e.kind==="origin"?`${t.find(f=>f.kind==="flow-origin")?.event.title||"start"}${u.length?` \xB7 ${u.join(", ")}`:""}${n}`:e.kind==="ui"?`UI update${u.length?` \xB7 ${u.join(", ")}`:""}${n}`:`background${n}`}j(D,"L"),y(D,"Q"),g(D,"labelOf");const z=50;export function sqlAccountingOf(e){const t=new Map,s=new Map,r=new Set;for(const i of e){if(r.has(i.id))continue;r.add(i.id);const a=S(i.raw)?i.raw:{},l=q(a.kind),I=q(i.context?.requestId);if(!I)continue;const o=q(a.project)??q(i.context?.projectName);if(l==="db-query"&&i.source==="db"){const m=s.get(I)??{count:0,workMs:0,...o?{project:o}:{}};m.count+=1,m.workMs+=v(a.durationMs)??0,s.set(I,m)}else if(l===SQL_ACCOUNT_KIND){const m=q(a.accountId)??i.id,w=v(a.seq)??0,k=t.get(m);if(k&&k.seq>=w)continue;t.set(m,{requestId:I,...o?{project:o}:{},seq:w,basis:a.basis==="end"?"end":"settled",statements:v(a.statements)??0,failed:v(a.failed)??0,workMs:v(a.workMs)??0,recorded:v(a.recorded)??0,suppressed:v(a.suppressed)??0,unwritten:v(a.unwritten)??0})}}const u=new Map;for(const i of t.values()){const a=u.get(i.requestId);if(!a){u.set(i.requestId,{...i});continue}i.basis==="settled"&&(a.basis="settled"),a.statements+=i.statements,a.failed+=i.failed,a.workMs+=i.workMs,a.recorded+=i.recorded,a.suppressed+=i.suppressed,a.unwritten+=i.unwritten}const n=[...new Set([...s.keys(),...u.keys()])].sort();if(n.length===0)return;const f={statements:0,failed:0,workMs:0,recorded:0,suppressed:0,unwritten:0},p={statements:0,workMs:0},h=[];for(const i of n){const a=s.get(i),l=u.get(i),I=a?.count??0;p.statements+=I,p.workMs+=a?.workMs??0;const o=!l||I>l.statements?"unverified":I===l.statements?"complete":"incomplete";l&&o!=="unverified"&&(f.statements+=l.statements,f.failed+=l.failed,f.workMs+=l.workMs,f.recorded+=l.recorded,f.suppressed+=l.suppressed,f.unwritten+=l.unwritten);const m=a?.project??l?.project;h.push({requestId:i,...m?{project:m}:{},status:o,observed:I,observedWorkMs:a?.workMs??0,...l?{basis:l.basis,statements:l.statements,failed:l.failed,workMs:l.workMs,recorded:l.recorded,suppressed:l.suppressed,unwritten:l.unwritten}:{}})}const $=g(i=>h.filter(a=>a.status===i).length,"tally"),b=$("unverified"),M=$("incomplete"),c=g(i=>(i.statements??0)-i.observed,"missing"),d=h.filter(i=>i.status!=="complete").sort((i,a)=>(i.status==="incomplete"?0:1)-(a.status==="incomplete"?0:1)||c(a)-c(i)||(i.requestId<a.requestId?-1:i.requestId>a.requestId?1:0));return{status:b>0?"unverified":M>0?"incomplete":"complete",requests:h.length,complete:$("complete"),incomplete:M,unverified:b,settled:h.filter(i=>i.status!=="unverified"&&i.basis==="settled").length,observed:p,accounted:f,gaps:d.slice(0,z),gapsTruncated:d.length>z}}j(sqlAccountingOf,"sqlAccountingOf"),y(sqlAccountingOf,"sqlAccountingOf"),g(sqlAccountingOf,"sqlAccountingOf");
|
package/lib/flow-shape.d.ts
CHANGED
|
@@ -70,7 +70,7 @@ export declare function trimFlowEvent(event: BaseEvent, opts?: FlowShapeOptions)
|
|
|
70
70
|
outcome?: "returned" | "threw" | undefined;
|
|
71
71
|
source: "nx" | "vite" | "typescript" | "eslint" | "rollup" | "client-runtime" | "chrome" | "react" | "valtio" | "nestjs" | "nextjs" | "db" | "redis" | "queue" | "memory" | "visual" | "perf" | "security" | "gateway" | "external" | "ai" | "lens";
|
|
72
72
|
category: "db" | "memory" | "visual" | "security" | "ai" | "build" | "lint" | "typecheck" | "test" | "runtime" | "render" | "trace" | "state" | "network" | "backend" | "performance" | "deps" | "cluster" | "agent";
|
|
73
|
-
severity: "
|
|
73
|
+
severity: "error" | "debug" | "info" | "warning" | "fatal";
|
|
74
74
|
title: string;
|
|
75
75
|
kind: string | undefined;
|
|
76
76
|
area: FlowArea;
|
|
@@ -139,7 +139,7 @@ export declare function buildFlowDetail(rawEvents: BaseEvent[], opts?: FlowShape
|
|
|
139
139
|
outcome?: "returned" | "threw" | undefined;
|
|
140
140
|
source: "nx" | "vite" | "typescript" | "eslint" | "rollup" | "client-runtime" | "chrome" | "react" | "valtio" | "nestjs" | "nextjs" | "db" | "redis" | "queue" | "memory" | "visual" | "perf" | "security" | "gateway" | "external" | "ai" | "lens";
|
|
141
141
|
category: "db" | "memory" | "visual" | "security" | "ai" | "build" | "lint" | "typecheck" | "test" | "runtime" | "render" | "trace" | "state" | "network" | "backend" | "performance" | "deps" | "cluster" | "agent";
|
|
142
|
-
severity: "
|
|
142
|
+
severity: "error" | "debug" | "info" | "warning" | "fatal";
|
|
143
143
|
title: string;
|
|
144
144
|
kind: string | undefined;
|
|
145
145
|
area: FlowArea;
|
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 vt=Object.defineProperty;var T=(i,l)=>vt(i,"name",{value:l,configurable:!0});var wt=Object.defineProperty,P=T((i,l)=>wt(i,"name",{value:l,configurable:!0}),"T"),Mt=Object.defineProperty,$=P((i,l)=>Mt(i,"name",{value:l,configurable:!0}),"g");import{redactDeep as qt,redactText as at,redactUrlParams as It}from"./redact.js";import{templatisePath as mt}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:l,category:o,title:v,kind:m}=i;return l==="ai"?"ai":m?.startsWith("memory")||m==="db-query"?"data":l==="gateway"||m==="gateway-request"?"gateway":m==="queue-process"||m==="queue-active"||m==="queue-completed"||m==="queue-failed"?"services":l==="db"||l==="redis"||l==="queue"||m==="redis-op"||m?.startsWith("queue-")?"data":l==="external"||m==="egress"?"network":l==="nestjs"||l==="nest"?/(?:Repository|Repo|Dao|Store)\./.test(v)?"data":"services":l==="valtio"?"state":o==="network"?"network":"browser"}T(areaOf,"areaOf"),P(areaOf,"areaOf"),$(areaOf,"areaOf");const ht=240,St=new Set(["systemPrompt","prompt","prompts","messages","completion","completions","input","output","draft","text","content","result","arguments","params"]),At=new Set(["tenantId","caller","userId","accountId","email","subject"]),Bt=8;function dt(i){const l=Y(i,0);return jt(qt({redacted:!0,...l}),{rawByteLimit:16*1024}).value}T(dt,"ft"),P(dt,"bt"),$(dt,"aiProjection");function Y(i,l){if(typeof i=="string")return ut(i);if(i===null||typeof i!="object")return i;if(l>=Bt)return;if(Array.isArray(i))return i.slice(0,32).map(v=>Y(v,l+1));const o={};for(const[v,m]of Object.entries(i))if(!At.has(v)){if(St.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]=Y(m,l+1)}return o}T(Y,"tt"),P(Y,"ot"),$(Y,"projectAi");function ut(i){return i.length<=ht?at(i):`${at(i.slice(0,ht))}\u2026`}T(ut,"pt"),P(ut,"jt"),$(ut,"clipText");export function httpFacts(i,l){const o=$(M=>typeof M=="string"&&M.length>0?M:void 0,"str"),v=typeof l.status=="number"?l.status:void 0,m=$(M=>It(M.split("?")[0]??M)||"/","pathOf"),F=$((M,w,x={})=>({...M?{method:M.toUpperCase()}:{},...w?{rawPath:w,route:mt(w)}:{},...v!==void 0?{status:v}:{},...x}),"facts");if(i==="gateway-request"){const M=o(l.url);return F(o(l.method),M?m(M):void 0,{...o(l.host)?{host:o(l.host)}:{},...o(l.caller)?{caller:o(l.caller)}:{}})}if(i==="egress"){const M=o(l.path),w=o(l.exchangeId);return F(o(l.method)??"GET",M?m(M):void 0,{...o(l.host)?{host:o(l.host)}:{},...w?{exchangeId:w}:{}})}if(i==="fetch-start"||i==="fetch-done"||i==="fetch-error"){const M=o(l.href)??o(l.url);let w,x;if(M)try{const p=new URL(M,"http://relative.invalid");w=m(p.pathname),p.hostname!=="relative.invalid"&&(x=p.hostname)}catch{}return F(o(l.method)??"GET",w,x?{host:x}:{})}if(i==="ai-call")return{...v!==void 0?{status:v}:{},...l.stream===!0?{streamed:!0}:{}};const f=l.request;if(f&&typeof f=="object"){const M=f,w=o(M.route),x=o(M.method);if(!w&&!x)return{};const p=typeof M.status=="number"?M.status:void 0,D=w?m(w):void 0;return{...x?{method:x.toUpperCase()}:{},...D?{rawPath:D,route:D.includes(":")?D:mt(D)}:{},...p!==void 0?{status:p}:{}}}return{}}T(httpFacts,"httpFacts"),P(httpFacts,"httpFacts"),$(httpFacts,"httpFacts");export function trimFlowEvent(i,l={}){const o=i.raw??{},v=o.render??{},m=o.span??{},F=o.request??{},f=$(a=>typeof a=="number"?a:void 0,"num"),M=o.loop??{},w=o.effect??{},x=f(o.durationMs)??f(m.durationMs)??f(F.durationMs)??f(M.durationMs)??f(v.actualDurationMs)??f(w.durationMs),p=typeof o.kind=="string"?o.kind:void 0,D=p==="fetch-done"||p==="fetch-error",X=f(v.commitTime),rt=p==="render"&&X!==void 0&&Math.abs(X-i.timestamp)<6e4,L=D?i.timestamp:rt?X:f(o.startedAt)??f(m.startTime)??f(F.startedAt)??f(M.startedAt)??(x!==void 0?i.timestamp-x:i.timestamp);let j;if(typeof o.query=="string"){const a=Array.isArray(o.params)?` [${o.params.join(", ")}]`:"",y=typeof o.result=="string"?` \u2192 ${o.result}`:"";j=o.query+a+y}else if(typeof o.command=="string"){const a=typeof o.value=="string"?` \u2192 ${o.value}`:o.hit===!1?" \u2192 (miss)":"";j=o.command+a}else if(p==="state-update"){const a=o.update??{};let y="";try{y=JSON.stringify(a.preview)}catch{}j=`${a.storeId??""}.${a.path??""} = ${y}`}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 a=F.error??{},y=typeof a.stack=="string"?a.stack:typeof o.text=="string"?o.text:void 0;y&&y!==i.title&&(j=y)}let N,H,E,U;if(p==="span"){const a=m.outcome;if(N=a==="threw"||a==="returned"?a:m.status==="error"?"threw":m.status==="ok"?"returned":void 0,N==="threw"){const R=m.error??{},C=typeof R.name=="string"?R.name:void 0,Q=typeof R.message=="string"?R.message:typeof i.message=="string"?i.message:void 0;E=C,H=at([C,Q].filter(Boolean).join(": "))||void 0}const y=typeof m.args=="string"?m.args:void 0,B=typeof m.result=="string"?m.result:void 0;if(y!==void 0||B!==void 0){U=[...y!==void 0?["args"]:[],...B!==void 0?["result"]:[]];const R=$(C=>C.length>gt?`${C.slice(0,gt)}\u2026`:C,"short");j=[y!==void 0?`args ${R(y)}`:"",B!==void 0?`returned ${R(B)}`:""].filter(Boolean).join(" \u2192 ")}}let W;if(p==="gateway-request")W=`${o.host??""}${String(o.url??"").split("?")[0]}`;else if(p==="fetch-start"||p==="fetch-done"||p==="fetch-error")try{const a=new URL(String(o.href??o.url??""));W=`${a.hostname}${a.pathname}`}catch{}let _;if(p==="gateway-request"&&Array.isArray(o.steps))_=o.steps.map(a=>{const y=[String(a.step)];return a.project&&y.push(String(a.project)),a.prefix&&y.push(String(a.prefix)),a.mode&&y.push(String(a.mode)+(a.ok===!1?" \u2717":a.ok===!0?" \u2713":"")),a.caller&&y.push("by "+String(a.caller)),a.pod&&y.push(String(a.pod)),typeof a.atMs=="number"&&y.push(`@${a.atMs}ms`),y.join(" ")}),j=_.map(a=>a.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 a=o.usage??{},y=a.promptTokens!==void 0||a.completionTokens!==void 0?` \xB7 ${f(a.promptTokens)??"?"}\u2192${f(a.completionTokens)??"?"} tok`:"",B=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"}`:"",C=f(o.durationMs)!==void 0?` \xB7 ${(f(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${o.provider??""}/${o.model??"?"}${y}${B}${R}${C}${o.stream===!0?" \xB7 stream":""}`}else if(p==="ai-round"){const a=o.model??{},y=o.usage??{},B=Array.isArray(o.toolCalls)?o.toolCalls:[],R=`${f(y.promptTokens)??"?"}\u2192${f(y.completionTokens)??"?"} tok`,C=B.length?` \xB7 ${B.length} tool call${B.length===1?"":"s"}`:"",Q=f(o.durationMs)!==void 0?` \xB7 ${(f(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${a.provider??""}/${a.model??""} \xB7 ${R}${C}${Q}`}else if(p==="ai-turn-start"){const a=Array.isArray(o.tools)?o.tools:[];j=`skill ${o.skill??""} \xB7 ${o.output??""}${a.length?" \xB7 tools: "+a.join(", "):""}`}else if(p==="ai-tool-call"){const a=o.call??{},y=o.result??{},B=f(o.durationMs)!==void 0?` \xB7 ${(f(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${a.name??"tool"} ${y.error!=null?"\u2717 "+String(y.error):"\u2713"}${B}`}else if(p==="ai-turn-end"){const a=o.usage??{},y=f(o.rounds)!==void 0?` \xB7 ${f(o.rounds)} round${f(o.rounds)===1?"":"s"}`:"",B=f(o.durationMs)!==void 0?` \xB7 ${(f(o.durationMs)/1e3).toFixed(1)}s`:"";j=`${o.ok===!1?"FAILED":"ok"} \xB7 ${f(a.promptTokens)??"?"}+${f(a.completionTokens)??"?"} tok${y}${B}`}}let g;p==="db-query"&&typeof o.query=="string"?g=o.query:p==="redis-op"?g=`${o.op??""} ${String(o.key??"").replace(/\d+/g,"#")}`:p==="egress"?g=`${o.method??"GET"} ${o.host??""}`:p==="ai-call"?g=`ai ${o.provider??""} ${o.model??""} ${o.api??""}`:p==="queue-enqueued"?g=`enqueue ${o.queue??""}`:p==="span"&&typeof m.name=="string"?g=m.name:p==="memory-mutation"&&(g=i.title);const O=i.context??{},V=v.commitId??w.commitId??o.commitId,J=Array.isArray(v.why)?v.why.map(a=>typeof a?.type=="string"?a.type:void 0).filter(a=>!!a):[];return{id:i.id,t:i.timestamp,start:L,...g?{sig:g}:{},...W?{urlKey:W}:{},...httpFacts(p,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:N==="threw"&&typeof m.name=="string"?`${m.name} \u2014 threw${E?` ${E}`:""}${x!==void 0?` after ${x}ms`:""}`:i.title,kind:p,area:areaOf({source:i.source,category:i.category,title:i.title,kind:p}),...N?{outcome:N}:{},...H?{error:H}:{},...U?{captured:U}:{},...typeof m.role=="string"?{role:m.role}:{},...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 O.requestId=="string"?{requestId:O.requestId}:{},...typeof O.parentRequestId=="string"?{parentRequestId:O.parentRequestId}:{},...typeof V=="string"?{commitId:V}:{},...typeof v.componentName=="string"?{component:v.componentName}:{},...typeof v.phase=="string"?{phase:v.phase}:{},...J.length?{why:J}:{},...p==="effect-run"&&typeof w.hookLogicalId=="string"?{hook:w.hookLogicalId}:{},...p==="effect-run"&&w.cleanupRan===!0?{cleanup:!0}:{},...p==="render-commit-truncated"?{renderTotal:f(o.total),renderPublished:f(o.published),...f(o.walkStoppedAt)!==void 0?{renderWalkStoppedAt:f(o.walkStoppedAt)}:{}}:{},...typeof O.projectName=="string"?{project:O.projectName}:typeof o.project=="string"?{project:o.project}:{},...x!==void 0?{durationMs:x}:{},...D&&f(o.startedAt)!==void 0?{fetchStartedAt:f(o.startedAt)}:{},...i.source==="ai"?{ai:l.includeRaw?o:dt(o)}:{},...j?{detail:j}:{},..._?{steps:_}:{}}}T(trimFlowEvent,"trimFlowEvent"),P(trimFlowEvent,"trimFlowEvent"),$(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 ct(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}T(ct,"gt"),P(ct,"St"),$(ct,"kindRank");function z(i){return i.kind==="span"&&i.role==="controller"?3.5:i.kind==="queue-process"?3:ct(i.kind)}T(z,"J"),P(z,"Z"),$(z,"causalRank");export function buildFlowDetail(i,l={}){const o=xt(i),v=i.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===bt)return!1;const s=e.span;return!(typeof s?.name=="string"&&s.name.startsWith("nest.request "))}).map(t=>trimFlowEvent(t,l)),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 F=new Map;for(const t of v)(t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&!F.has(t.requestId)&&F.set(t.requestId,t.start);const f=$(t=>t.source!=="react"&&t.source!=="valtio"&&t.requestId&&F.has(t.requestId)?F.get(t.requestId):t.start,"anchorOf");v.sort((t,e)=>f(t)-f(e)||t.start-e.start||z(t)-z(e)||(e.durationMs??0)-(t.durationMs??0)||t.t-e.t);const M=$(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 x=new Map;for(const t of w)if((t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&t.project){const e=x.get(t.requestId)??[];e.push({project:t.project,start:t.start,end:t.start+(t.durationMs??0)}),x.set(t.requestId,e)}const p=$((t,e)=>{const r=x.get(t);if(r?.length)return r.every(s=>s.project===r[0].project)?r[0].project:r.filter(s=>s.start<=e+1&&s.end>=e-1).sort((s,n)=>n.start-s.start)[0]?.project},"projectOf");for(const t of w)if(!t.project&&t.source==="nestjs"&&t.requestId){const e=p(t.requestId,t.start);e&&(t.project=e)}for(const t of w){let e;const r=t.requestId;for(const s of w){if(s===t||!M(s)||s.group!==t.group||s.requestId!==r)continue;const n=s.project,c=t.project;if(s.kind!=="gateway-request"&&t.kind!=="gateway-request"&&n!==void 0&&c!==void 0&&n!==c)continue;const k=s.durationMs??0,q=t.durationMs??0,d=Math.abs(s.start-t.start)<=$t,u=z(s),h=z(t),I=s.start<=t.start;if(!(s.start+k>t.start&&(I||d&&u<h)&&(!d||(u!==h?u<h:I&&k>q))))continue;const A=e?z(e):-1,b=e?Math.abs(s.start-e.start)<=$t:!1;(!e||!b&&s.start>e.start||b&&u>A||b&&u===A&&(s.durationMs??0)<(e.durationMs??0))&&(e=s)}e&&(t.parent=e.id)}const D=new Map;for(const t of w){if(!t.requestId)continue;const e=D.get(t.requestId);e?e.push(t):D.set(t.requestId,[t])}const X=new Map(w.map(t=>[t.id,t])),rt=$((t,e)=>{const r=(D.get(t)??[]).filter(s=>M(s)&&s.start<=e&&s.start+(s.durationMs??0)>=e);if(r.length!==0)return r.sort((s,n)=>n.start-s.start||(s.durationMs??0)-(n.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=rt(t.parentRequestId,t.start);r&&r!==t&&r.start<=t.start&&(t.parent=r.id)}const L=w,j=new Map;for(const t of L)t.kind==="gateway-request"&&t.requestId&&!j.has(t.requestId)&&j.set(t.requestId,t);for(const t of L)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 N=new Set,H=new Set,E=[];for(const t of L){if(t.kind!=="gateway-request")continue;if(!t.requestId){E.push(t);continue}const e=D.get(t.requestId)??[];if(e.filter(n=>n.kind==="gateway-request").sort((n,c)=>n.start-c.start)[0]!==t)continue;const r=e.find(n=>n.kind==="fetch-start"),s=e.find(n=>n.kind==="fetch-done"||n.kind==="fetch-error");if(!r&&!s){E.push(t);continue}r&&(t.fetchStartId=r.id,N.add(r.id)),s&&(t.fetchDoneId=s.id,H.add(s.id))}const U=new Map;for(const t of L){if(!t.urlKey)continue;const e=U.get(t.urlKey)??{gws:[],starts:[],dones:[]};t.kind==="gateway-request"?E.includes(t)&&e.gws.push(t):t.kind==="fetch-start"?N.has(t.id)||e.starts.push(t):(t.kind==="fetch-done"||t.kind==="fetch-error")&&(H.has(t.id)||e.dones.push(t)),U.set(t.urlKey,e)}for(const{gws:t,starts:e,dones:r}of U.values()){t.sort((n,c)=>n.start-c.start),e.sort((n,c)=>n.start-c.start);const s=new Set;t.forEach((n,c)=>{const k=e[c];k&&(n.fetchStartId=k.id);const q=k?k.t:n.start;let d,u=1/0;for(const h of r){if(s.has(h.id))continue;const I=h.fetchStartedAt??h.start-(h.durationMs??0),A=Math.abs(I-q);A<u&&(u=A,d=h)}d&&(n.fetchDoneId=d.id,s.add(d.id))})}const W=new Map,_=new Map;for(const t of L)!t.queue||!t.jobId||(t.kind==="queue-enqueued"&&W.set(`${t.queue}#${t.jobId}`,t),t.kind==="queue-process"&&_.set(`${t.queue}#${t.jobId}`,t));for(const t of L){if(!t.queue||!t.jobId)continue;const e=`${t.queue}#${t.jobId}`;if(t.kind==="queue-process"&&!t.parent){const r=W.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=_.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||!Rt.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 s=Math.round(e.start+e.durationMs-(r.start+r.durationMs));if(s<OUTLIVED_PARENT_MIN_MS)continue;e.outlivedParentMs=s;const n=r.leftRunning??{count:0,longestMs:0};r.leftRunning={count:n.count+1,longestMs:Math.max(n.longestMs,s)}}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 s=[...t.values()].find(k=>k.requestId&&k.requestId===r.requestId)?.id,n=s?t.get(s):void 0;if(!n)continue;const c=r.fetchStartedAt??n.start;n.title=r.title,n.severity=r.severity,n.durationMs=r.durationMs??Math.max(0,r.t-c),n.kind="fetch",r.detail&&!n.detail&&(n.detail=r.detail),e.set(r.id,n.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 O=$(t=>!!t.commitId&&(t.kind==="render"||t.kind==="effect-run"||t.kind==="render-commit-truncated"),"commitMember"),V=$(t=>[...new Set(t)],"uniq"),J=$(t=>V(t.map(e=>e.component).filter(e=>!!e)),"named"),a=$(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,s])=>s>1?`${r} \xD7${s}`:r).join(", ")},"tally"),B=$(t=>{if(!t)return"effect";const e=/([^/\\]+?):(\d+)(?::\d+)?$/.exec(t);return e?`${e[1]}:${e[2]}`:t},"shortHook"),R=$(t=>`${B(t.hook)}${t.cleanup?" (cleanup)":""}`,"hookLabel"),C=$(t=>{const e=Math.min(...t.map(s=>s.start)),r=Math.max(...t.map(s=>s.start+(s.durationMs??0)));return{start:e,durationMs:r-e}},"extent"),Q=$(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 ot(t){const e=t[0],r=t.filter(S=>S.kind==="render"),s=t.filter(S=>S.kind==="effect-run"),n=t.find(S=>S.kind==="render-commit-truncated"),c=[...r].sort((S,Z)=>(Z.durationMs??0)-(S.durationMs??0)),k=c.filter(S=>(S.why??[]).some(Z=>Z!=="parent-render")),q=V(k.flatMap(S=>(S.why??[]).filter(Z=>Z!=="parent-render"))),d=J(k),u=r.filter(S=>S.phase==="mount"),h=r.filter(S=>S.phase!=="mount"&&!k.includes(S)),I=c[0]?.component??"view",A=r.length>0&&u.length===r.length,b=q.length?q.join(" + "):void 0,G=A?"mount":"update",K=d.length?`view update \xB7 ${a(d)} \u2190 ${b}`:A?`view mount \xB7 ${I}`:`view update \xB7 ${I}`,it=n?.renderTotal??r.length,kt=[u.length?`mounted ${y(u)}`:"",h.length?`re-rendered ${y(h)}`:"",!d.length&&!A&&r.length?"trigger not recorded \u2014 every captured render came from its parent":"",n?.renderWalkStoppedAt!==void 0?`at least ${it} renders (the walk stopped at ${n.renderWalkStoppedAt} fibers), ${n.renderPublished??r.length} recorded`:n?`${it} renders, ${n.renderPublished??r.length} recorded (per-commit cap)`:`${r.length} render${r.length===1?"":"s"}`,s.length?`${s.length} effect${s.length===1?"":"s"}: ${s.map(R).join(", ")}`:""].filter(Boolean).join(" \xB7 "),pt=J(r);return Q({...e,...C(t),kind:"view-update",title:K,detail:kt,commitId:e.commitId,viewPhase:G,...b?{cause:b}:{},causeComponents:d,components:pt,mounted:J(u),renderCount:it,...n?.renderWalkStoppedAt!==void 0?{renderCountAtLeast:!0}:{},recordedRenders:r.length,effects:s.length,effectHooks:s.map(R),memberIds:t.map(S=>S.id),sig:`commit:${G}:${b??"-"}:${d.join(",")}:${pt.slice().sort().join(",")}`,severity:t.some(S=>S.severity==="error")?"error":e.severity})}T(ot,"nt"),P(ot,"ft"),$(ot,"viewUpdateNode");function st(t){const e=t[0],r=t.map(R);return Q({...e,...C(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(s=>s.id),sig:`effects:${r.slice().sort().join(",")}`})}T(st,"st"),P(st,"lt"),$(st,"effectsNode");const yt=$(t=>V(t.map(e=>e==="state-update"?"state update":e==="fetch-start"?"request":e==="flow-origin"?"interaction":"response")).join(" + "),"describeInputs");function nt(t,e){const r=t[0],s=t[t.length-1],n=t.length,c=r.detail,k=Math.min(...t.map(h=>h.start)),q=Math.max(...t.map(h=>h.start+(h.durationMs??0))),d=Math.round(t.reduce((h,I)=>h+(I.durationMs??0),0)/n*10)/10,u=Math.round((q-k)*10)/10;r.count=n,r.avgMs=d,r.wallMs=u,r.durationMs=q-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${n} ${r.title}`,t.some(h=>h.severity==="error")&&(r.severity="error"),r.kind==="view-update"?r.detail=[`${n} commits, ${e.length?`one per ${yt(e)}`:"back to back"}`,`avg ${d}ms \xB7 wall ${u}ms`,c??""].filter(Boolean).join(" \xB7 "):r.kind==="state-update"&&c&&s.detail?r.detail=`${n} updates in a row \xB7 wall ${u}ms \xB7 first ${c} \xB7 last ${s.detail}`:r.detail=[`${n} in a row \xB7 wall ${u}ms`,c??""].filter(Boolean).join(" \xB7 ")}T(nt,"at"),P(nt,"mt"),$(nt,"collapseRepeat");const tt=[],et=new Map,lt=new Set;for(let t=0;t<g.length;t++){if(lt.has(t))continue;const e=g[t];if(!O(e)){tt.push(e);continue}const r=[t];for(let c=t+1;c<g.length;c++){const k=g[c];if(k.group==="browser"){if(!O(k)||k.commitId!==e.commitId)break;r.push(c)}}for(const c of r)lt.add(c);const s=r.map(c=>g[c]),n=s.some(c=>c.kind!=="effect-run")?ot(s):st(s);for(const c of s)c.id!==n.id&&et.set(c.id,n.id);tt.push(n)}if(et.size>0||tt.some(t=>t.kind==="view-update"||t.kind==="commit-effects")){g=tt;for(const t of g)for(;t.parent&&et.has(t.parent);)t.parent=et.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((d,u)=>d.group==="browser"?u:-1).filter(d=>d>=0),r=$(d=>`${d.kind}|${d.sig??d.title}`,"keyOf"),s=e.map(d=>r(g[d])),n=$((d,u,h)=>{for(let I=0;I<h;I++)if(s[d+I]!==s[u+I])return!1;return!0},"sameBlock"),c=$(d=>s[d].split("|")[0],"kindAt"),k=$(d=>{let u=0,h=1;for(let I=1;I<=4&&d+I<=s.length;I++){let A=1;for(;d+(A+1)*I<=s.length&&n(d,d+A*I,I);)A+=1;A>=3&&I*A>u*h&&(u=I,h=A)}return{k:u,r:h}},"bestBlockAt"),q=new Map;for(let d=0;d<s.length;){const{k:u,r:h}=k(d);if(u===0){d+=1;continue}const I=[...Array(u).keys()].find(b=>t.has(c(d+b)));if(I!==void 0&&I>0){const b=k(d+I);if(b.k===u&&b.r>=3&&b.r>=h-1){d+=I;continue}}const A=s.slice(d,d+u).map(b=>b.split("|")[0]).filter(b=>t.has(b));for(let b=0;b<u;b++){const G=[];for(let K=0;K<h;K++)G.push(g[e[d+b+K*u]]);nt(G,A);for(const K of G.slice(1))q.set(K.id,G[0].id)}d+=u*h}if(q.size>0){g=g.filter(d=>!q.has(d.id));for(const d of g)for(;d.parent&&q.has(d.parent);)d.parent=q.get(d.parent)}}{const t=new Map(g.map(e=>[e.id,e]));for(const e of g){const r=new Set([e.id]);let s=e;for(;s?.parent;){if(r.has(s.parent)){s.parent=void 0;break}r.add(s.parent),s=t.get(s.parent)}}}const ft=$(t=>{const e=new Map;for(const s of g){if(!s.sig||M(s)!==t||s.kind==="server-request"||s.kind==="gateway-request"||s.group==="browser")continue;const n=`${s.parent??"root"}|${s.kind}|${s.sig}`,c=e.get(n);c?c.push(s):e.set(n,[s])}const r=new Map;for(const s of e.values()){if(s.length<3)continue;s.sort((u,h)=>u.start-h.start);const n=s[0];let c=!1;for(let u=0;u+1<s.length;u++)if(s[u+1].start<s[u].start+(s[u].durationMs??0)){c=!0;break}const k=n.start,q=Math.max(...s.map(u=>u.start+(u.durationMs??0))),d=s.reduce((u,h)=>u+(h.durationMs??0),0);n.count=s.length,n.parallel=c,n.avgMs=Math.round(d/s.length*10)/10,n.wallMs=q-k,n.durationMs=q-k,n.title=`\xD7${s.length} ${n.title.replace(/\s*\((?:\d+ rows?, )?\d+ms\)$/,"")}`,n.detail=`${n.sig} \xD7${s.length} ${c?"\u2016 parallel":"\u21BB sequential loop"} \xB7 avg ${n.avgMs}ms \xB7 wall ${n.wallMs}ms`,n.items=s.slice(0,12).map(u=>({start:u.start-k,...u.durationMs!=null?{durationMs:u.durationMs}:{}})),n.memberIds=s.flatMap(u=>u.memberIds??[u.id]),s.some(u=>u.severity==="error")&&(n.severity="error");for(const u of s.slice(1))r.set(u.id,n.id)}if(r.size!==0){g=g.filter(s=>!r.has(s.id));for(const s of g)for(;s.parent&&r.has(s.parent);)s.parent=r.get(s.parent)}},"aggregatePass");ft(!0),ft(!1);for(const t of g){if(!M(t))continue;const e=t.durationMs??0;if(e<40)continue;const r=g.filter(q=>q.parent===t.id&&(q.durationMs??0)>0).map(q=>[q.start,q.start+(q.durationMs??0)]).sort((q,d)=>q[0]-d[0]);let s=0,n=-1,c=-1;for(const[q,d]of r)q>c?(c>n&&(s+=c-n),n=q,c=d):d>c&&(c=d);c>n&&(s+=c-n);const k=Math.max(0,e-s);(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"),P(buildFlowDetail,"buildFlowDetail"),$(buildFlowDetail,"buildFlowDetail");
|
package/lib/flows-config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var y=Object.defineProperty;var l=(o,e)=>y(o,"name",{value:e,configurable:!0});var w=Object.defineProperty,c=l((o,e)=>w(o,"name",{value:e,configurable:!0}),"c"),$=Object.defineProperty,p=c((o,e)=>$(o,"name",{value:e,configurable:!0}),"u");import{classifyFlow as h,categoryOfSegment as F}from"./flow-categories.js";import{DEFAULT_SEGMENT_OPTIONS as j,segmentFlow as O}from"./flow-segments.js";export const DEFAULT_FLOWS_CONFIG={categories:[],segments:{},problems:[]};const f=200,b=200,d=64,v=/^[A-Za-z0-9][A-Za-z0-9 ._:/-]*$/,A=["category","flowId","originType","origin","route","project"],S={phaseGapMs:[50,6e5],burstGapMs:[10,6e4],attachWindowMs:[0,6e4],maxSegmentEvents:[20,1e4],occurrenceSlackMs:[0,1e3]},g=p(o=>typeof o=="object"&&o!==null&&!Array.isArray(o),"isObj");function m(o,e){if(!g(o))return{problems:[`${e}: not an object`]};const s=[];for(const t of Object.keys(o))A.includes(t)||s.push(`${e}: unknown field "${t}" ignored`);const n=o.category;if(typeof n!="string"||n.trim()==="")return{problems:[...s,`${e}: "category" must be a non-empty string \u2014 rule dropped`]};const i=n.trim();if(i.length>d||!v.test(i))return{problems:[...s,`${e}: category "${i.slice(0,40)}" is not a usable name (letters, digits, space . _ : / -; up to ${d}) \u2014 rule dropped`]};const u={category:i};let a=0;for(const t of["flowId","originType","origin","route","project"]){const r=o[t];if(r!==void 0){if(typeof r!="string"||r===""||r.length>b)return{problems:[...s,`${e}: "${t}" must be a non-empty string of up to ${b} characters \u2014 rule dropped`]};u[t]=r,a+=1}}return a===0?{problems:[...s,`${e}: "${i}" has no match field (flowId, originType, origin, route or project) \u2014 rule dropped`]}:{rule:u,problems:s}}l(m,"d"),c(m,"w"),p(m,"parseRule");export function parseFlowsConfig(o){if(o==null)return DEFAULT_FLOWS_CONFIG;if(!g(o))return{...DEFAULT_FLOWS_CONFIG,problems:["lensmcp.flows must be an object \u2014 ignored"]};const e=[],s=[],n=o.categories;n!==void 0&&(Array.isArray(n)?(n.length>f&&e.push(`flows.categories has ${n.length} rules; only the first ${f} are used`),n.slice(0,f).forEach((a,t)=>{const r=m(a,`flows.categories[${t}]`);e.push(...r.problems),r.rule&&s.push(r.rule)})):e.push("flows.categories must be an array \u2014 ignored"));const i={},u=o.segments;if(u!==void 0)if(!g(u))e.push("flows.segments must be an object \u2014 ignored");else for(const[a,t]of Object.entries(u)){const r=S[a];if(!r){e.push(`flows.segments.${a}: unknown option ignored`);continue}if(typeof t!="number"||!Number.isFinite(t)||t<r[0]||t>r[1]){e.push(`flows.segments.${a}: ${JSON.stringify(t)} is outside ${r[0]}\u2013${r[1]}; using the default (${j[a]})`);continue}i[a]=t}return{categories:s,segments:i,problems:e}}l(parseFlowsConfig,"parseFlowsConfig"),c(parseFlowsConfig,"parseFlowsConfig"),p(parseFlowsConfig,"parseFlowsConfig");export function analyzeFlow(o,e=DEFAULT_FLOWS_CONFIG){const s=O(o,e.segments),n=h(o,s,e.categories),i={};for(const u of s.segments)i[u.id]=F(u,n,e.categories);return{segmentation:s,classification:n,segmentCategories:i}}l(analyzeFlow,"analyzeFlow"),c(analyzeFlow,"analyzeFlow"),p(analyzeFlow,"analyzeFlow");
|
package/lib/graph-from-events.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var y=Object.defineProperty;var l=(o,r)=>y(o,"name",{value:r,configurable:!0});var b=Object.defineProperty,p=l((o,r)=>b(o,"name",{value:r,configurable:!0}),"p"),I=Object.defineProperty,m=p((o,r)=>I(o,"name",{value:r,configurable:!0}),"l");function f(o){const r=o.raw??null,s=r?.kind,i=o.context,a={id:o.id,parentTraceNodeId:i.causedByNodeId??i.originNodeId,lifecycle:"completed",context:i,startTime:o.timestamp,attributes:{...r??{}}};if(o.source==="react"&&s==="render"){const e=r;return{parentAxis:"render",node:{...a,type:"render",logicalId:e.render?.componentLogicalId,instanceId:e.render?.componentInstanceId,name:`render ${e.render?.componentName??"?"}`,durationMs:e.render?.actualDurationMs}}}if(o.source==="valtio"&&s==="state-update"){const e=r;return{parentAxis:"state",node:{...a,type:"state-update",logicalId:e.update?.storeId,name:`${e.update?.storeId??"?"}.${e.update?.path??"?"}`}}}if(o.source==="nestjs"&&s==="server-request"){const e=r;return{parentAxis:"backend",node:{...a,type:"server-request",name:`${e.request?.method??"?"} ${e.request?.route??"?"}`,durationMs:e.request?.durationMs}}}if(s==="db-query"){const e=r,c=[e.op,e.table].filter(Boolean).join(" ")||(e.name??"query");return{parentAxis:"backend",node:{...a,type:"db-query",logicalId:e.table?`db:${e.op??"query"}:${e.table}`:void 0,name:e.error?`${c} (failed)`:c,durationMs:e.durationMs}}}if(s==="loop")return{parentAxis:"performance",node:{...a,type:"loop",name:"loop",durationMs:r.loop?.durationMs}};if(o.source==="client-runtime"&&s==="user-action"){const e=r;return{parentAxis:"caused",node:{...a,type:"ui-event",logicalId:e.origin?.nodeId,name:e.origin?.label??o.title}}}}l(f,"m"),p(f,"f"),m(f,"eventToNode");export function buildGraphFromEvents(o,r){const s=[...r].sort((n,t)=>n.timestamp-t.timestamp),i=[];for(const n of s){const t=f(n);t&&(o.addNode(t.node),i.push(t))}let a=0;const e=m((n,t,d,u)=>{const g={id:`${d}:${n}->${t}`,from:n,to:t,axis:d,type:u,timestamp:o.getNode(t)?.startTime??0};o.addEdge(g),a++},"addEdge");for(const n of i){const t=n.node.context.causedByNodeId;t&&o.getNode(t)&&e(t,n.node.id,n.parentAxis??"caused","caused-by")}const c=new Map;for(const n of i){const t=n.node.context.flowId;if(!t)continue;let d=c.get(t);d||(d=[],c.set(t,d)),d.push(n)}for(const n of c.values())for(let t=1;t<n.length;t++){const d=n[t-1].node,u=n[t].node;u.context.causedByNodeId!==d.id&&e(d.id,u.id,"caused","flow-sequence")}return{nodeCount:i.length,edgeCount:a}}l(buildGraphFromEvents,"buildGraphFromEvents"),p(buildGraphFromEvents,"buildGraphFromEvents"),m(buildGraphFromEvents,"buildGraphFromEvents");
|
package/lib/graph-store.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var w=Object.defineProperty;var l=(
|
|
1
|
+
"use strict";var w=Object.defineProperty;var l=(d,t)=>w(d,"name",{value:t,configurable:!0});var I=Object.defineProperty,y=l((d,t)=>I(d,"name",{value:t,configurable:!0}),"l"),b=Object.defineProperty,m=y((d,t)=>b(d,"name",{value:t,configurable:!0}),"l");const B=4,M=1e3;export class GraphStore{static{l(this,"GraphStore")}static{y(this,"GraphStore")}static{m(this,"GraphStore")}constructor(){this.nodes=new Map,this.edges=new Map,this.byParent=new Map,this.byFlow=new Map,this.byLogical=new Map,this.byInstance=new Map,this.byRequest=new Map,this.outByAxis=new Map,this.inByAxis=new Map}addNode(t){this.nodes.set(t.id,t),t.parentTraceNodeId&&this.addToIndex(this.byParent,t.parentTraceNodeId,t.id),t.context.flowId&&this.addToIndex(this.byFlow,t.context.flowId,t.id),t.logicalId&&this.addToIndex(this.byLogical,t.logicalId,t.id),t.instanceId&&this.addToIndex(this.byInstance,t.instanceId,t.id),t.context.requestId&&this.addToIndex(this.byRequest,t.context.requestId,t.id)}updateNode(t,e){const i=this.nodes.get(t);if(!i)throw new Error(`Unknown node: ${t}`);const s={...i,...e,id:i.id};return this.nodes.set(t,s),s}getNode(t){return this.nodes.get(t)}addEdge(t){this.edges.set(t.id,t);let e=this.outByAxis.get(t.axis);e||(e=new Map,this.outByAxis.set(t.axis,e)),this.addToIndex(e,t.from,t.id);let i=this.inByAxis.get(t.axis);i||(i=new Map,this.inByAxis.set(t.axis,i)),this.addToIndex(i,t.to,t.id)}getEdge(t){return this.edges.get(t)}childrenOf(t){return this.materialiseNodes(this.byParent.get(t))}nodesInFlow(t){return this.materialiseNodes(this.byFlow.get(t))}nodesByLogical(t){return this.materialiseNodes(this.byLogical.get(t))}nodesByInstance(t){return this.materialiseNodes(this.byInstance.get(t))}nodesByRequest(t){return this.materialiseNodes(this.byRequest.get(t))}traverse(t){const e=this.nodes.get(t.from);if(!e)return{nodes:[],edges:[]};const i=Array.isArray(t.lens)?t.lens:[t.lens],s=t.direction??"both",x=t.depth??4,p=t.maxNodes??1e3,o=new Set,g=new Set,c=[{id:e.id,d:0}];for(;c.length&&!(o.size>=p);){const{id:n,d:u}=c.shift();if(!o.has(n)&&(o.add(n),!(u>=x)))for(const f of i){if(s==="out"||s==="both"){const a=this.outByAxis.get(f)?.get(n);if(a)for(const r of a){g.add(r);const h=this.edges.get(r);o.has(h.to)||c.push({id:h.to,d:u+1})}}if(s==="in"||s==="both"){const a=this.inByAxis.get(f)?.get(n);if(a)for(const r of a){g.add(r);const h=this.edges.get(r);o.has(h.from)||c.push({id:h.from,d:u+1})}}}}return{nodes:this.materialiseNodes(o),edges:[...g].map(n=>this.edges.get(n)).filter(n=>!!n)}}nodeCount(){return this.nodes.size}edgeCount(){return this.edges.size}addToIndex(t,e,i){let s=t.get(e);s||(s=new Set,t.set(e,s)),s.add(i)}materialiseNodes(t){if(!t)return[];const e=[];for(const i of t){const s=this.nodes.get(i);s&&e.push(s)}return e}}
|
package/lib/headless-flow.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var l=Object.defineProperty;var t=(e,s)=>l(e,"name",{value:s,configurable:!0});var r=Object.defineProperty,o=t((e,s)=>r(e,"name",{value:s,configurable:!0}),"s"),n=Object.defineProperty,a=o((e,s)=>n(e,"name",{value:s,configurable:!0}),"t");export const HEADLESS_FLOWS_ENV="LENSMCP_HEADLESS_FLOWS";export function headlessFlowsEnabled(e=process.env){return!["0","false","off","no"].includes((e[HEADLESS_FLOWS_ENV]??"").trim().toLowerCase())}t(headlessFlowsEnabled,"headlessFlowsEnabled"),o(headlessFlowsEnabled,"headlessFlowsEnabled"),a(headlessFlowsEnabled,"headlessFlowsEnabled");export const HEADLESS_REQUEST_FLOW_PREFIX="api:",HEADLESS_JOB_FLOW_PREFIX="job:";export function headlessFlowId(e){return`${HEADLESS_REQUEST_FLOW_PREFIX}${e}`}t(headlessFlowId,"headlessFlowId"),o(headlessFlowId,"headlessFlowId"),a(headlessFlowId,"headlessFlowId");export function headlessJobFlowId(e,s){return`${HEADLESS_JOB_FLOW_PREFIX}${e}#${s??"?"}`}t(headlessJobFlowId,"headlessJobFlowId"),o(headlessJobFlowId,"headlessJobFlowId"),a(headlessJobFlowId,"headlessJobFlowId");export function isHeadlessFlowId(e){return e.startsWith(HEADLESS_REQUEST_FLOW_PREFIX)||e.startsWith(HEADLESS_JOB_FLOW_PREFIX)}t(isHeadlessFlowId,"isHeadlessFlowId"),o(isHeadlessFlowId,"isHeadlessFlowId"),a(isHeadlessFlowId,"isHeadlessFlowId");const i=/^\/(?:[^/?#]+\/)*(?:health|healthz|health-check|healthcheck|ready|readyz|readiness|live|livez|liveness|ping|metrics|favicon\.ico)\/?(?:[?#].*)?$/i;export function isProbePath(e){return e?i.test(e)||e.startsWith("/__lensmcp/"):!1}t(isProbePath,"isProbePath"),o(isProbePath,"isProbePath"),a(isProbePath,"isProbePath");
|
package/lib/http-exchange.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var o=Object.defineProperty;var r=(t,e)=>o(t,"name",{value:e,configurable:!0});var
|
|
1
|
+
"use strict";var o=Object.defineProperty;var r=(t,e)=>o(t,"name",{value:e,configurable:!0});var h=Object.defineProperty,a=r((t,e)=>h(t,"name",{value:e,configurable:!0}),"r"),p=Object.defineProperty,i=a((t,e)=>p(t,"name",{value:e,configurable:!0}),"e");import*as s from"node:fs";import{dirname as x,join as c}from"node:path";export const HTTP_EXCHANGE_DIR="http";const g=/^hx_[0-9a-z]{8,40}$/;export const isHttpExchangeId=i(t=>typeof t=="string"&&g.test(t),"isHttpExchangeId");export function httpExchangeDir(t){return c(x(t),HTTP_EXCHANGE_DIR)}r(httpExchangeDir,"httpExchangeDir"),a(httpExchangeDir,"httpExchangeDir"),i(httpExchangeDir,"httpExchangeDir");export function httpExchangeFile(t,e){if(!isHttpExchangeId(e))throw new Error("invalid http exchange id");return c(httpExchangeDir(t),`${e}.json`)}r(httpExchangeFile,"httpExchangeFile"),a(httpExchangeFile,"httpExchangeFile"),i(httpExchangeFile,"httpExchangeFile");export function readHttpExchange(t,e){if(isHttpExchangeId(e))try{const n=JSON.parse(s.readFileSync(httpExchangeFile(t,e),"utf8"));return n&&n.schemaVersion===1&&n.id===e?n:void 0}catch{return}}r(readHttpExchange,"readHttpExchange"),a(readHttpExchange,"readHttpExchange"),i(readHttpExchange,"readHttpExchange");
|
package/lib/http-shape.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var j=Object.defineProperty;var m=(t,n)=>j(t,"name",{value:n,configurable:!0});var k=Object.defineProperty,p=m((t,n)=>k(t,"name",{value:n,configurable:!0}),"m"),S=Object.defineProperty,l=p((t,n)=>S(t,"name",{value:n,configurable:!0}),"a");import{isSecretParam as M}from"./redact.js";const x=6,h=60,F=4,O=[["uuid",/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i],["ulid",/^[0-9A-HJKMNP-TV-Z]{26}$/],["date-time",/^\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?$/],["date",/^\d{4}-\d{2}-\d{2}$/],["email",/^[^\s@]+@[^\s@]+\.[^\s@]+$/],["url",/^https?:\/\/\S+$/i],["jwt",/^eyJ[\w-]{8,}\.[\w-]{8,}\.[\w-]{8,}$/],["int",/^-?\d{1,30}$/],["decimal",/^-?\d+\.\d+$/],["phone",/^\+\d{7,15}$/],["hex",/^[0-9a-f]{16,}$/i],["base64",/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[A-Za-z0-9+/]{32,}={0,2}$/]];export function stringFormat(t){for(const[n,e]of O)if(e.test(t))return n}m(stringFormat,"stringFormat"),p(stringFormat,"stringFormat"),l(stringFormat,"stringFormat");const $=l(t=>t.length>64||/\s/.test(t)||stringFormat(t)!==void 0&&!/^[a-z]/i.test(t)||/@/.test(t)||/^[0-9a-f]{8}-/i.test(t),"dataKey");export function shapeOf(t,n=0,e=!1){if(t==null)return{t:"null"};if(typeof t=="boolean")return{t:"bool"};if(typeof t=="number")return Number.isInteger(t)?{t:"num",int:!0}:{t:"num"};if(typeof t=="bigint")return{t:"num",int:!0};if(typeof t=="string"){const r=stringFormat(t);return{t:"str",...r?{f:r}:{},...e?{}:{max:t.length}}}if(t instanceof Date)return{t:"str",f:"date-time"};if(n>=x)return Array.isArray(t)?{t:"arr",n:[t.length,t.length]}:{t:"obj",fields:[]};if(Array.isArray(t)){const r=t.slice(0,20).map(a=>shapeOf(a,n+1,e)).reduce((a,i)=>a?mergeShapes(a,i):i,void 0);return{t:"arr",n:[t.length,t.length],...r?{of:r}:{}}}if(typeof t=="object"){const r=Object.entries(t).filter(([,a])=>typeof a!="function");if(r.length&&r.some(([a])=>$(a))){const a=r.slice(0,20).map(([,s])=>shapeOf(s,n+1,e)).reduce((s,c)=>s?mergeShapes(s,c):c,void 0),i=r.map(([s])=>stringFormat(s)).find(Boolean);return{t:"map",n:[r.length,r.length],...i?{key:i}:{},...a?{of:a}:{}}}return{t:"obj",fields:r.slice(0,h).map(([a,i])=>{const s=M(a);return{...shapeOf(i,n+1,e||s),name:a,...s?{cred:!0}:{}}}),...r.length>h?{more:r.length-h}:{}}}return{t:"null"}}m(shapeOf,"shapeOf"),p(shapeOf,"shapeOf"),l(shapeOf,"shapeOf");const v=l((t,n)=>t.t===n.t,"same"),N=new Set(["null","bool","num","str","arr","obj","map","any"]);export function isShape(t,n=0){if(!t||typeof t!="object"||n>x*2)return!1;const e=t;return typeof e.t!="string"||!N.has(e.t)?!1:e.t==="obj"?Array.isArray(e.fields)&&e.fields.every(r=>typeof r?.name=="string"&&isShape(r,n+1)):e.t==="any"?Array.isArray(e.of)&&e.of.every(r=>isShape(r,n+1)):e.t==="arr"||e.t==="map"?Array.isArray(e.n)&&(e.of===void 0||isShape(e.of,n+1)):!0}m(isShape,"isShape"),p(isShape,"isShape"),l(isShape,"isShape");export function fieldShape(t){const n={...t};return delete n.name,delete n.opt,delete n.cred,n}m(fieldShape,"fieldShape"),p(fieldShape,"fieldShape"),l(fieldShape,"fieldShape");export function mergeShapes(t,n){if(t.t==="any"||n.t==="any"){const e=[...t.t==="any"?t.of:[t],...n.t==="any"?n.of:[n]],r=[];for(const a of e){const i=r.findIndex(s=>v(s,a));i>=0?r[i]=mergeShapes(r[i],a):r.push(a)}return r.length===1?r[0]:{t:"any",of:r.slice(0,F)}}if(!v(t,n))return{t:"any",of:[t,n]};switch(t.t){case"num":return t.int&&n.int?t:{t:"num"};case"str":{const e=n,r=t.f===e.f?t.f:void 0;return{t:"str",...r?{f:r}:{},...t.max!==void 0||e.max!==void 0?{max:Math.max(t.max??0,e.max??0)}:{}}}case"arr":{const e=n,r=t.of&&e.of?mergeShapes(t.of,e.of):t.of??e.of;return{t:"arr",n:[Math.min(t.n[0],e.n[0]),Math.max(t.n[1],e.n[1])],...r?{of:r}:{}}}case"map":{const e=n,r=t.of&&e.of?mergeShapes(t.of,e.of):t.of??e.of;return{t:"map",n:[Math.min(t.n[0],e.n[0]),Math.max(t.n[1],e.n[1])],...t.key===e.key&&t.key?{key:t.key}:{},...r?{of:r}:{}}}case"obj":{const e=n,r=new Map(t.fields.map(c=>[c.name,c])),a=new Map(e.fields.map(c=>[c.name,c])),i=[...new Set([...r.keys(),...a.keys()])].slice(0,h).map(c=>{const f=r.get(c),u=a.get(c);return{...f&&u?mergeShapes(fieldShape(f),fieldShape(u)):fieldShape(f??u),name:c,...!f||!u||f.opt||u.opt?{opt:!0}:{},...f?.cred||u?.cred?{cred:!0}:{}}}),s=Math.max(t.more??0,e.more??0);return{t:"obj",fields:i,...s?{more:s}:{}}}default:return t}}m(mergeShapes,"mergeShapes"),p(mergeShapes,"mergeShapes"),l(mergeShapes,"mergeShapes");export function shapeText(t,n=0){switch(t.t){case"null":return"null";case"bool":return"boolean";case"num":return t.int?"int":"number";case"str":return t.f?`string(${t.f})`:"string";case"arr":return`[${t.n[0]===t.n[1]?t.n[0]:`${t.n[0]}..${t.n[1]}`}]${t.of?` ${shapeText(t.of,n+1)}`:""}`;case"map":return`map<${t.key??"string"}, ${t.of?shapeText(t.of,n+1):"?"}> (${t.n[0]===t.n[1]?t.n[0]:`${t.n[0]}..${t.n[1]}`} entries)`;case"any":return t.of.map(e=>shapeText(e,n)).join(" | ");case"obj":return`{ ${t.fields.map(e=>`${e.name}${e.opt?"?":""}${e.cred?" (credential-named)":""}: ${shapeText(fieldShape(e),n+1)}`).join(", ")}${t.more?`, \u2026 ${t.more} more`:""} }`}}m(shapeText,"shapeText"),p(shapeText,"shapeText"),l(shapeText,"shapeText");const o=l((t,n)=>{const e=t[n]??t[n.toLowerCase()];return e===void 0?void 0:Array.isArray(e)?e.join(", "):String(e)},"h"),y=l(t=>t?.split(";")[0]?.trim().toLowerCase()||void 0,"media");export function requestFacts(t,n,e){const r=o(t,"authorization")?.split(/\s+/)[0],a=o(t,"cookie"),i=Number(o(t,"content-length")),s=n?Object.keys(n).filter(f=>!$(f)).slice(0,30):[],c=e?Object.keys(e).slice(0,10):[];return{...y(o(t,"content-type"))?{contentType:y(o(t,"content-type"))}:{},...o(t,"accept")?{accept:o(t,"accept").slice(0,80)}:{},...r?{scheme:/^[A-Za-z][\w-]{1,20}$/.test(r)?r:"other"}:{},...a?{cookies:a.split(";").filter(f=>f.includes("=")).length}:{},...o(t,"if-match")?{ifMatch:!0}:{},...o(t,"if-none-match")?{ifNoneMatch:!0}:{},...o(t,"idempotency-key")?{idempotencyKey:!0}:{},...o(t,"origin")?{origin:!0}:{},...Number.isFinite(i)&&i>0?{bytes:i}:{},...s.length?{query:s}:{},...c.length?{params:c}:{}}}m(requestFacts,"requestFacts"),p(requestFacts,"requestFacts"),l(requestFacts,"requestFacts");export function responseFacts(t,n){const e=o(t,"etag"),r=Number(o(t,"content-length")),a=t["set-cookie"],i=(Array.isArray(a)?a:a!==void 0?[String(a)]:[]).slice(0,10).map(c=>{const[f="",...u]=c.split(";").map(g=>g.trim()),d=l(g=>u.find(A=>A.toLowerCase().startsWith(g)),"a"),w=d("samesite")?.split("=")[1],b=d("path=")?.slice(5);return{name:f.split("=")[0].slice(0,40),...d("secure")?{secure:!0}:{},...d("httponly")?{httpOnly:!0}:{},...w?{sameSite:w}:{},...d("domain=")?{domain:!0}:{},...b?{path:b}:{},...d("max-age=")?{maxAge:!0}:{},...d("expires=")?{expires:!0}:{}}}),s=o(t,"access-control-allow-origin");return{...y(o(t,"content-type"))?{contentType:y(o(t,"content-type"))}:{},...Number.isFinite(r)&&r>=0&&o(t,"content-length")!==void 0?{bytes:r}:{},...o(t,"cache-control")?{cacheControl:o(t,"cache-control").slice(0,120)}:{},...e?{etag:e.startsWith("W/")?"weak":"strong"}:{},...o(t,"last-modified")?{lastModified:!0}:{},...o(t,"location")?{location:!0}:{},...o(t,"vary")?{vary:o(t,"vary").slice(0,120)}:{},...o(t,"retry-after")?{retryAfter:!0}:{},...o(t,"www-authenticate")?{wwwAuthenticate:o(t,"www-authenticate").split(/\s+/)[0].slice(0,20)}:{},...o(t,"allow")?{allow:o(t,"allow").slice(0,80)}:{},...i.length?{cookies:i}:{},...s?{cors:{origin:s==="*"?"*":n&&s===n?"echoed":"fixed",...o(t,"access-control-allow-credentials")==="true"?{creds:!0}:{},...o(t,"access-control-allow-methods")?{methods:o(t,"access-control-allow-methods").slice(0,80)}:{},...o(t,"access-control-allow-headers")?{headers:o(t,"access-control-allow-headers").slice(0,120)}:{}}}:{},...o(t,"strict-transport-security")?{hsts:!0}:{},...o(t,"x-content-type-options")?{nosniff:!0}:{},...o(t,"x-powered-by")||o(t,"server")?{poweredBy:!0}:{},...o(t,"deprecation")?{deprecation:!0}:{},...o(t,"sunset")?{sunset:!0}:{},...o(t,"ratelimit")||o(t,"ratelimit-policy")||o(t,"x-ratelimit-limit")?{rateLimit:!0}:{},...o(t,"x-request-id")?{requestId:!0}:{}}}m(responseFacts,"responseFacts"),p(responseFacts,"responseFacts"),l(responseFacts,"responseFacts");
|
package/lib/lens-dir.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var t=Object.defineProperty;var r=(e,i)=>t(e,"name",{value:i,configurable:!0});var o=Object.defineProperty,n=r((e,i)=>o(e,"name",{value:i,configurable:!0}),"i"),s=Object.defineProperty,a=n((e,i)=>s(e,"name",{value:i,configurable:!0}),"i");export const LENS_SHARED_DIRS=["sql-review","route-review","flow-review","ui-review","cache-review","queue-review"];export function lensGitignoreLines(e="**/"){return[`${e}.lensmcp/*`,...LENS_SHARED_DIRS.map(i=>`!${e}.lensmcp/${i}/`)]}r(lensGitignoreLines,"lensGitignoreLines"),n(lensGitignoreLines,"lensGitignoreLines"),a(lensGitignoreLines,"lensGitignoreLines");
|
package/lib/lens-events.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var p=Object.defineProperty;var
|
|
2
|
-
`).join("")))}
|
|
1
|
+
"use strict";var p=Object.defineProperty;var r=(e,s)=>p(e,"name",{value:s,configurable:!0});var m=Object.defineProperty,o=r((e,s)=>m(e,"name",{value:s,configurable:!0}),"t"),d=Object.defineProperty,n=o((e,s)=>d(e,"name",{value:s,configurable:!0}),"o");import{appendFileSync as v,closeSync as S,mkdirSync as y,openSync as f,renameSync as I,statSync as N,unlinkSync as _}from"node:fs";import{dirname as g,join as b}from"node:path";import{ERROR_DISMISSED as a,ERROR_RESTORED as c,LENS_EVENT_SOURCE as R}from"@lensmcp/protocol-types";import{rotateBusFile as F}from"./bus-rotation.js";import{ulid as x}from"./ulid.js";export function lensEventFile(e=process.env,s=process.cwd()){return e.LENSMCP_EVENT_FILE??b(s,".lensmcp","events.jsonl")}r(lensEventFile,"lensEventFile"),o(lensEventFile,"lensEventFile"),n(lensEventFile,"lensEventFile");const l=n((e,s,t,i,E)=>({id:x(),sessionId:e,timestamp:s,source:R,category:"runtime",severity:"info",context:{sessionId:e},fingerprint:t,title:i,raw:E}),"lensEvent");export function dismissalEvent(e,s){return l(s,e.until,`${a}:${e.groupId}`,`error dismissed: ${e.title??e.groupId}`,{kind:a,groupId:e.groupId,until:e.until,eventIds:e.eventIds,...e.by?{by:e.by}:{},...e.reason?{reason:e.reason}:{},...e.title?{title:e.title}:{}})}r(dismissalEvent,"dismissalEvent"),o(dismissalEvent,"dismissalEvent"),n(dismissalEvent,"dismissalEvent");export function restoralEvent(e,s,t){return l(s,t,`${c}:${e}`,"error restored",{kind:c,groupId:e})}r(restoralEvent,"restoralEvent"),o(restoralEvent,"restoralEvent"),n(restoralEvent,"restoralEvent");const u=n((e,s,t)=>{const i=Number(process.env[e]);return Number.isFinite(i)&&t(i)?i:s},"envNumber");export function appendBusEvents(e,s){s.length!==0&&(y(g(e),{recursive:!0}),F(e,{maxBytes:u("LENSMCP_EVENT_MAX_BYTES",50*1024*1024,t=>t>0),maxFiles:u("LENSMCP_EVENT_MAX_FILES",5,t=>t>=1&&t<=20),fs:{statSync:N,renameSync:I,unlinkSync:_,openSync:f,closeSync:S}}),v(e,s.map(t=>JSON.stringify(t)+`
|
|
2
|
+
`).join("")))}r(appendBusEvents,"appendBusEvents"),o(appendBusEvents,"appendBusEvents"),n(appendBusEvents,"appendBusEvents");
|
package/lib/patterns.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var y=Object.defineProperty;var u=(o,n)=>y(o,"name",{value:n,configurable:!0});var j=Object.defineProperty,p=u((o,n)=>j(o,"name",{value:n,configurable:!0}),"u"),v=Object.defineProperty,f=p((o,n)=>v(o,"name",{value:n,configurable:!0}),"l");export function detectDbInLoop(o,n={}){const s=n.threshold??5,i=[];for(const t of o){const e=t.raw??null;if(e?.kind!=="loop"||!e.loop)continue;const a=e.loop.dbCallsInsideLoop??0;a>s&&i.push({kind:"db-in-loop",severity:"warning",title:`${a} DB calls inside a loop (${e.loop.iterations??"?"} iterations)`,evidence:[t.id],details:{dbCallsInsideLoop:a,iterations:e.loop.iterations,durationMs:e.loop.durationMs,threshold:s},detectedAt:t.timestamp})}return i}u(detectDbInLoop,"detectDbInLoop"),p(detectDbInLoop,"detectDbInLoop"),f(detectDbInLoop,"detectDbInLoop");const I=new Set(["egress","db-query","redis-op","ai-call"]);function w(o){const n=o.raw??null;if(!n||typeof n.kind!="string"||!I.has(n.kind))return;const s=typeof n.durationMs=="number"?n.durationMs:void 0;if(s===void 0)return;const i=typeof n.startedAt=="number"?n.startedAt:o.timestamp-s,t=o.context??{};return{id:o.id,start:i,end:i+s,label:o.title,...typeof t.requestId=="string"?{requestId:t.requestId}:{},...typeof n.project=="string"?{project:n.project}:typeof t.projectName=="string"?{project:t.projectName}:{}}}u(w,"b"),p(w,"M"),f(w,"timedCall");function M(o){const n=o.raw??null,s=n?.kind==="span"?n.span:void 0;if(!s||typeof s.name!="string"||s.name.startsWith("nest.request "))return;const i=typeof s.durationMs=="number"?s.durationMs:void 0;if(i===void 0||i<=0)return;const t=typeof s.startTime=="number"?s.startTime:o.timestamp-i,e=o.context??{};return{id:o.id,start:t,end:t+i,label:s.name,...typeof e.requestId=="string"?{requestId:e.requestId}:{},...typeof n?.project=="string"?{project:n.project}:typeof e.projectName=="string"?{project:e.projectName}:{}}}u(M,"g"),p(M,"b"),f(M,"timedSpan");export function abandonedAwaitOf(o,n,s={}){const i=s.thresholdMs??250,t=w(o);if(!t||!t.requestId||t.end-t.start<i)return;let e;for(const r of n){const d=M(r);!d||d.requestId!==t.requestId||d.project!==void 0&&t.project!==void 0&&d.project!==t.project||d.start>t.start||d.end<=t.start||(!e||d.start>e.start||d.start===e.start&&d.end<e.end)&&(e=d)}if(!e)return;const a=Math.round(t.end-e.end);if(!(a<i))return{kind:"abandoned-await",severity:"warning",title:`${e.label} ended ${a}ms before a call it started had finished (${t.label})`,evidence:[e.id,t.id],details:{span:e.label,call:t.label,ranOnMs:a,spanMs:Math.round(e.end-e.start),callMs:Math.round(t.end-t.start),thresholdMs:i,...t.project?{project:t.project}:{}},detectedAt:o.timestamp}}u(abandonedAwaitOf,"abandonedAwaitOf"),p(abandonedAwaitOf,"abandonedAwaitOf"),f(abandonedAwaitOf,"abandonedAwaitOf");export function detectAbandonedAwait(o,n={}){const s=[];for(const i of o){const t=abandonedAwaitOf(i,o,n);t&&s.push(t)}return s}u(detectAbandonedAwait,"detectAbandonedAwait"),p(detectAbandonedAwait,"detectAbandonedAwait"),f(detectAbandonedAwait,"detectAbandonedAwait");export function detectNPlusOne(o,n={}){const s=n.threshold??3,i=new Map;for(const e of o){const a=e.raw??null;if(a?.kind!=="db-query"||!a.query?.signature)continue;const r=a.query.signature;let d=i.get(r);d||(d=[],i.set(r,d)),d.push(e)}const t=[];for(const[e,a]of i)a.length>=s&&t.push({kind:"n+1-query",severity:"warning",title:`Query repeated ${a.length}\xD7 \u2014 likely N+1`,evidence:a.map(r=>r.id),details:{signature:e,count:a.length,threshold:s},detectedAt:a[a.length-1].timestamp});return t}u(detectNPlusOne,"detectNPlusOne"),p(detectNPlusOne,"detectNPlusOne"),f(detectNPlusOne,"detectNPlusOne");export function detectRenderStorm(o,n={}){const s=n.threshold??5,i=n.windowMs??250,t=new Map;for(const a of o){if(a.source!=="react")continue;const r=a.raw??null;if(r?.kind!=="render"||!r.render?.componentInstanceId)continue;const d=r.render.componentInstanceId;let c=t.get(d);c||(c=[],t.set(d,c)),c.push(a)}const e=[];for(const[a,r]of t){r.sort((c,m)=>c.timestamp-m.timestamp);let d=0;for(let c=0;c<r.length;c++){for(;r[c].timestamp-r[d].timestamp>i;)d++;const m=c-d+1;if(m>s){const l=r.slice(d,c+1),h=l[0].raw.render?.componentName??a;e.push({kind:"render-storm",severity:"warning",title:`${h} rendered ${m}\xD7 in ${i}ms`,evidence:l.map(b=>b.id),details:{componentInstanceId:a,count:m,windowMs:i,threshold:s},detectedAt:l[l.length-1].timestamp});break}}}return e}u(detectRenderStorm,"detectRenderStorm"),p(detectRenderStorm,"detectRenderStorm"),f(detectRenderStorm,"detectRenderStorm");export function findSlowPath(o,n,s){const i=new Map,t=new Set;function e(r){const d=i.get(r);if(d)return d;if(t.has(r))return{path:[r],totalDurationMs:s(r)};t.add(r);const c=s(r),m=n.get(r)??[];let l;for(const b of m){const g=e(b);(!l||g.totalDurationMs>l.totalDurationMs)&&(l=g)}t.delete(r);const h=l?{path:[r,...l.path],totalDurationMs:c+l.totalDurationMs}:{path:[r],totalDurationMs:c};return i.set(r,h),h}u(e,"e"),p(e,"e"),f(e,"best");let a={path:[],totalDurationMs:0};for(const r of o){const d=e(r);d.totalDurationMs>a.totalDurationMs&&(a=d)}return a}u(findSlowPath,"findSlowPath"),p(findSlowPath,"findSlowPath"),f(findSlowPath,"findSlowPath");
|
package/lib/redact.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var E=Object.defineProperty;var f=(t,e)=>E(t,"name",{value:e,configurable:!0});var k=Object.defineProperty,u=f((t,e)=>k(t,"name",{value:e,configurable:!0}),"u"),y=Object.defineProperty,c=u((t,e)=>y(t,"name",{value:e,configurable:!0}),"f");export const REDACTED="REDACTED",MAX_TITLE_CHARS=300,MAX_MESSAGE_CHARS=4096,MAX_URL_CHARS=1024;const _=["token","secret","password","passwd","apikey","credential","assertion","signature"],z=new Set(["key","auth","authorization","jwt","code","sig","pwd","pass","session","sid","bearer","otp","cookie","set-cookie"]),P=/^(?:(?:prompt|completion|total|input|output|cache|cached|cacheread|cachewrite|reasoning|thinking|max|min|remaining|used|billed)tokens|tokens?(?:count|used|limit|remaining))$/;export function isSecretParam(t){const e=t.toLowerCase();if(P.test(e.replace(/[-_.]+/g,"")))return!1;if(_.some(n=>e.includes(n)))return!0;for(const n of e.split(/[-_.]+/))if(n&&z.has(n))return!0;return!1}f(isSecretParam,"isSecretParam"),u(isSecretParam,"isSecretParam"),c(isSecretParam,"isSecretParam");const R=/^([a-z][a-z0-9+.-]*:\/\/)[^/?#@\s]*@/i,v=/([?&#])([^=&#\s]+)=([^&#\s]*)/g;export function redactUrlParams(t){return t&&t.replace(R,`$1${REDACTED}@`).replace(v,(e,n,r)=>isSecretParam(r)?`${n}${r}=${REDACTED}`:e)}f(redactUrlParams,"redactUrlParams"),u(redactUrlParams,"redactUrlParams"),c(redactUrlParams,"redactUrlParams");export function redactUrl(t){return t&&clip(redactUrlParams(t),1024)}f(redactUrl,"redactUrl"),u(redactUrl,"redactUrl"),c(redactUrl,"redactUrl");const I=/\beyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]*/g,D=/\b(bearer|basic)\s+[A-Za-z0-9._~+/=-]{8,}/gi,U=/\b(authorization|x-api-key|api-key|cookie|set-cookie|proxy-authorization)\b(\s*[:=]\s*)(["']?)((?:(?:bearer|basic)\s+)?[^\s"',;]{4,})\3/gi;export function redactText(t){return redactUrlParams(t).replace(U,(e,n,r,i)=>`${n}${r}${i}${REDACTED}${i}`).replace(I,REDACTED).replace(D,(e,n)=>`${n} ${REDACTED}`)}f(redactText,"redactText"),u(redactText,"redactText"),c(redactText,"redactText");export function clip(t,e){return t.length<=e?t:`${t.slice(0,e)}\u2026[lensmcp truncated: ${t.length-e} more chars]`}f(clip,"clip"),u(clip,"clip"),c(clip,"clip");export function safeText(t,e=4096){if(t!==void 0)return clip(redactText(t),e)}f(safeText,"safeText"),u(safeText,"safeText"),c(safeText,"safeText");export function safeTitle(t){return clip(redactText(t),300)}f(safeTitle,"safeTitle"),u(safeTitle,"safeTitle"),c(safeTitle,"safeTitle");const C=6,N=64,O=/^TS\d{1,5}$/,M=c((t,e)=>t==="code"&&typeof e=="string"&&O.test(e),"isDiagnosticCode");export function redactDeep(t,e=0,n=C){if(typeof t=="string")return redactText(t);if(t===null||typeof t!="object"||e>=n)return t;if(Array.isArray(t)){let a=!1;const s=t.map((o,l)=>{if(l>=N)return o;const d=redactDeep(o,e+1,n);return d!==o&&(a=!0),d});return a?s:t}let r=!1;const i={};for(const[a,s]of Object.entries(t)){const o=isSecretParam(a)&&s!==void 0&&s!==null&&!M(a,s)?REDACTED:redactDeep(s,e+1,n);o!==s&&(r=!0),i[a]=o}return r?i:t}f(redactDeep,"redactDeep"),u(redactDeep,"redactDeep"),c(redactDeep,"redactDeep");const g=String.raw`(?:"(?:[^"]|"")+"|[A-Za-z_][\w$]*)`,h=String.raw`${g}(?:\s*\.\s*${g})*`,Z=String.raw`(?:=|<>|!=|<=|>=|<|>|(?:NOT\s+)?I?LIKE|IS\s+(?:NOT\s+)?DISTINCT\s+FROM)`,j=new RegExp(String.raw`(${h})\s*${Z}\s*(?:[A-Za-z_]\w*\s*\(\s*)?\$(\d+)`,"gi"),L=new RegExp(String.raw`(${h})\s+(?:NOT\s+)?IN\s*\(([^()]*)\)`,"gi"),H=new RegExp(String.raw`\bINSERT\s+INTO\s+${h}\s*\(([^()]*)\)\s*VALUES\s*`,"gi"),X=new RegExp(g,"g"),A=/\$(\d+)/g,T=16384,q=256,F=4096,p=new Map,m=c(t=>{const e=t.match(X)??[],n=e[e.length-1]??"";return n.startsWith('"')?n.slice(1,-1).replace(/""/g,'"'):n},"lastIdent");function $(t,e){const n=[];let r=e;for(;;){for(;r<t.length&&/\s/.test(t[r]);)r++;if(t[r]!=="(")return n;const i=[];let a=r+1,s=0,o=!1;for(r+=1;r<t.length;r++){const l=t[r];if(o){l==="'"&&(o=!1);continue}if(l==="'")o=!0;else if(l==="(")s++;else if(l===")"){if(s===0)break;s--}else l===","&&s===0&&(i.push(t.slice(a,r)),a=r+1)}if(r>=t.length)return n;for(i.push(t.slice(a,r)),n.push(i),r+=1;r<t.length&&/\s/.test(t[r]);)r++;if(t[r]!==",")return n;r+=1}}f($,"A"),u($,"U"),c($,"valuesTuples");function x(t){const e=t.length<=F,n=e?p.get(t):void 0;if(n)return n;const r=t.length>T?t.slice(0,T):t,i=new Set,a=c((s,o)=>{o&&isSecretParam(o)&&i.add(Number(s))},"bind");for(const s of r.matchAll(j))a(s[2],m(s[1]));for(const s of r.matchAll(L)){const o=m(s[1]);for(const l of s[2].matchAll(A))a(l[1],o)}for(const s of r.matchAll(H)){const o=s[1].split(",").map(l=>m(l.trim()));for(const l of $(r,(s.index??0)+s[0].length))l.forEach((d,b)=>{const S=o[b];if(S)for(const w of d.matchAll(A))a(w[1],S)})}if(e){if(p.size>=q){const s=p.keys().next().value;s!==void 0&&p.delete(s)}p.set(t,i)}return i}f(x,"S"),u(x,"P"),c(x,"secretPlaceholders");export function redactSqlParams(t,e){if(e.length===0||!t.includes("$"))return e;const n=x(t);if(n.size===0)return e;let r=!1;const i=e.map((a,s)=>a==null||!n.has(s+1)?a:(r=!0,REDACTED));return r?i:e}f(redactSqlParams,"redactSqlParams"),u(redactSqlParams,"redactSqlParams"),c(redactSqlParams,"redactSqlParams");
|
package/lib/reducer-registry.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var c=(r,e)=>a(r,"name",{value:e,configurable:!0});var u=Object.defineProperty,i=c((r,e)=>u(r,"name",{value:e,configurable:!0}),"c"),n=Object.defineProperty,d=i((r,e)=>n(r,"name",{value:e,configurable:!0}),"c");export class ReducerRegistry{static{c(this,"ReducerRegistry")}static{i(this,"ReducerRegistry")}static{d(this,"ReducerRegistry")}constructor(){this.reducers=[]}register(e,s){if(this.reducers.some(t=>t.name===e))throw new Error(`Reducer already registered: ${e}`);this.reducers.push({name:e,reducer:s})}list(){return this.reducers}async dispatch(e){for(const{reducer:s}of this.reducers)try{const t=s(e);t&&typeof t.then=="function"&&await t}catch{}}}
|
package/lib/resource-store.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var i=(s,e)=>a(s,"name",{value:e,configurable:!0});var h=Object.defineProperty,c=i((s,e)=>h(s,"name",{value:e,configurable:!0}),"i"),d=Object.defineProperty,l=c((s,e)=>d(s,"name",{value:e,configurable:!0}),"o");export class ResourceStore{static{i(this,"ResourceStore")}static{c(this,"ResourceStore")}static{l(this,"ResourceStore")}constructor(){this.entries=new Map,this.subs=new Map}register(e,t){if(this.entries.has(e))throw new Error(`Resource already registered: ${e}`);return this.entries.set(e,{uri:e,produce:t,revision:0}),()=>{this.entries.delete(e),this.subs.delete(e)}}async read(e){const t=this.entries.get(e);if(!t)throw new Error(`Unknown resource: ${e}`);return t.produce()}list(){return[...this.entries.keys()]}async markDirty(e){const t=this.entries.get(e);if(!t)return;const r=await t.produce(),n=JSON.stringify(r);if(n===t.lastJson)return;t.lastJson=n,t.revision+=1;const o=this.subs.get(e);if(o)for(const u of o)try{u(e,t.revision)}catch{}}revision(e){return this.entries.get(e)?.revision}subscribe(e,t){let r=this.subs.get(e);return r||(r=new Set,this.subs.set(e,r)),r.add(t),()=>{r?.delete(t)}}}
|
package/lib/route-template.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var u=Object.defineProperty;var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var n=(e,t)=>u(e,"name",{value:t,configurable:!0});var c=Object.defineProperty,r=n((e,t)=>c(e,"name",{value:t,configurable:!0}),"s"),p=Object.defineProperty,l=r((e,t)=>p(e,"name",{value:t,configurable:!0}),"r");function s(e){return e.length===0?!1:!!(/^\d{2,}$/.test(e)||/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)||/^[A-Z][A-Z0-9]*-\d+$/.test(e)||e.length>=16&&/^[A-Za-z0-9_-]+$/.test(e)&&/\d/.test(e))}n(s,"f"),r(s,"a"),l(s,"isIdSegment");export function templatisePath(e){const[t="/"]=e.split("?"),o=t.split("/"),a=[];for(const f of o){if(a.length>12){a.push("\u2026");break}a.push(s(f)?":id":f)}const i=a.join("/");return i.length===0?"/":i}n(templatisePath,"templatisePath"),r(templatisePath,"templatisePath"),l(templatisePath,"templatisePath");
|
package/lib/sql-shape.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`||
|
|
3
|
-
`,s);
|
|
1
|
+
"use strict";var b=Object.defineProperty;var f=(e,n)=>b(e,"name",{value:n,configurable:!0});var $=Object.defineProperty,T=f((e,n)=>$(e,"name",{value:n,configurable:!0}),"a"),F=Object.defineProperty,p=T((e,n)=>F(e,"name",{value:n,configurable:!0}),"p");const G=/[A-Za-z_\u0080-]/,v=/[A-Za-z0-9_$\u0080-]/;function N(e){const n=[],u=[];let l=0;const o=e.length;let s=0;const r=p((i,t)=>n.push({kind:i,text:t,up:i==="word"?t.toUpperCase():t}),"push");for(;s<o;){const i=e[s];if(i===" "||i===`
|
|
2
|
+
`||i===" "||i==="\r")s++;else if(i==="-"&&e[s+1]==="-"){l++;const t=e.indexOf(`
|
|
3
|
+
`,s);u.push(e.slice(s+2,t<0?o:t).trim()),s=t<0?o:t+1}else if(i==="/"&&e[s+1]==="*"){const t=e.indexOf("*/",s+2);u.push(e.slice(s+2,t<0?o:t).trim()),s=t<0?o:t+2}else if(i==="'"||(i==="E"||i==="e")&&e[s+1]==="'"){let t=i==="'"?s+1:s+2;for(;t<o;)if(e[t]==="\\"&&i!=="'")t+=2;else if(e[t]==="'"&&e[t+1]==="'")t+=2;else{if(e[t]==="'")break;t++}r("string",e.slice(s,t+1)),s=t+1}else if(i==="$"&&/[0-9]/.test(e[s+1]??"")){let t=s+1;for(;t<o&&/[0-9]/.test(e[t]);)t++;r("param",e.slice(s,t)),s=t}else if(i==="$"){const t=/^\$([A-Za-z_][A-Za-z0-9_]*)?\$/.exec(e.slice(s,s+64));if(t){const a=e.indexOf(t[0],s+t[0].length),A=a<0?o:a+t[0].length;r("string",e.slice(s,A)),s=A}else r("punct",i),s++}else if(i==='"'){let t=s+1;for(;t<o&&!(e[t]==='"'&&e[t+1]!=='"');)t+=e[t]==='"'?2:1;t<o&&r("qident",e.slice(s,t+1)),s=t+1}else if(/[0-9]/.test(i)||i==="."&&/[0-9]/.test(e[s+1]??"")){let t=s;for(;t<o&&/[0-9.eE]/.test(e[t]);)t++;r("number",e.slice(s,t)),s=t}else if(G.test(i)){let t=s;for(;t<o&&v.test(e[t]);)t++;r("word",e.slice(s,t)),s=t}else if("(),;[].".includes(i))r("punct",i),s++;else{let t=s;for(;t<o&&/[+\-*/<>=~!@#%^&|`?:]/.test(e[t])&&!(e[t]==="-"&&e[t+1]==="-")&&!(e[t]==="/"&&e[t+1]==="*");)t++;t===s&&(t=s+1),r("op",e.slice(s,t)),s=t}}return{tokens:n,comments:u,lineComments:l}}f(N,"I"),T(N,"I"),p(N,"lex");function g(e){const n=new Map,u=[],l=[],o=[];e.forEach((s,r)=>{if(s.text===")"||s.text==="]"){const i=o.pop();i!==void 0&&n.set(i,r)}u.push(o.length),l.push(o[o.length-1]??-1),(s.text==="("||s.text==="[")&&o.push(r)});for(const s of o)n.set(s,e.length);return{close:n,depth:u,opener:l}}f(g,"U"),T(g,"D"),p(g,"structure");const H=new Set(["SELECT","INSERT","UPDATE","DELETE","MERGE","VALUES","TABLE"]),k=new Set(["SELECT","FROM","WHERE","JOIN","LEFT","RIGHT","INNER","OUTER","FULL","CROSS","NATURAL","ON","USING","GROUP","ORDER","BY","HAVING","LIMIT","OFFSET","FETCH","UNION","EXCEPT","INTERSECT","RETURNING","SET","VALUES","WINDOW","FOR","LATERAL","ONLY","AS","WITH","INTO","UPDATE","DELETE","INSERT","DEFAULT","DO","NOTHING","CONFLICT","AND","OR","NOT","IS","NULL","IN","EXISTS","CASE","WHEN","THEN","ELSE","END","TABLESAMPLE","OVERRIDING","MATCHED","MERGE"]);function m(e,n,u=!1){const l=p(r=>r?r.kind==="qident"?r.text.slice(1,-1).replace(/""/g,'"'):r.kind==="word"&&!k.has(r.up)?r.text:void 0:void 0,"part");let o=l(e[n]);if(!o)return;let s=n+1;for(;e[s]?.text==="."&&l(e[s+1]);)o=`${o}.${l(e[s+1])}`,s+=2;if(!(e[s]?.text==="("&&!u))return{name:o.replace(/^public\./i,""),next:s}}f(m,"O"),T(m,"g"),p(m,"tableAt");function U(e,n,u){e[n]?.up==="AS"&&n++;const l=e[n];return l&&(l.kind==="qident"||l.kind==="word"&&!k.has(l.up))&&(n++,e[n]?.text==="("&&(n=(u.get(n)??n)+1)),n}f(U,"C"),T(U,"k"),p(U,"skipAlias");function O(e){let n=2166136261,u=16777619;for(let l=0;l<e.length;l++){const o=e.charCodeAt(l);n=Math.imul(n^o,16777619)>>>0,u=Math.imul(u^o,1540483477)>>>0}return(n.toString(16).padStart(8,"0")+u.toString(16).padStart(8,"0")).slice(0,12)}f(O,"m"),T(O,"w"),p(O,"hashId");function C(e,n){const u=p((r,i)=>r.kind==="string"||r.kind==="number"||r.kind==="param"||[",","::","-","[","]"].includes(r.text)||r.kind==="word"&&(/^(NULL|TRUE|FALSE|DEFAULT)$/i.test(r.text)||i?.text==="::"),"isValue"),l=[];let o=0;for(;o<e.length;){const r=e[o],i=e[o-1];if(r.text==="("&&(i?.up==="IN"||i?.up==="VALUES")){const t=n.get(o)??e.length,a=e.slice(o+1,t);if(a.length&&a.every((A,L)=>u(A,a[L-1]))){if(l.push({kind:"punct",text:"(\u2026)",up:"(\u2026)"}),o=t+1,i.up==="VALUES")for(;e[o]?.text===","&&e[o+1]?.text==="(";)o=(n.get(o+1)??e.length)+1;continue}}l.push(r.kind==="string"||r.kind==="number"?{kind:"op",text:"?",up:"?"}:r),o++}let s="";return l.forEach((r,i)=>{const t=l[i-1],a=!t||["(","[",".","::"].includes(t.text)||[")","]",",",".","::"].includes(r.text)||(r.text==="("||r.text==="(\u2026)"||r.text==="[")&&(t.kind==="qident"||t.kind==="word"&&!k.has(t.up));s+=(a?"":" ")+r.text}),s.trim()}f(C,"w"),T(C,"$"),p(C,"templateOf");const I=new Map,q=512;export function sqlShape(e){const n=I.get(e);if(n)return n;let u;try{u=w(e)}catch{u={id:O(e),template:e.trim().replace(/\s+/g," "),verb:"QUERY",tables:[]}}return I.set(e,u),I.size>q&&I.delete(I.keys().next().value),u}f(sqlShape,"sqlShape"),T(sqlShape,"sqlShape"),p(sqlShape,"sqlShape");function w(e){const{tokens:n,comments:u}=N(e),{close:l,depth:o,opener:s}=g(n);let r=n.find(E=>E.kind==="word")?.up??"QUERY";const i=new Set;n.forEach((E,d)=>{if(E.up!=="WITH"||n[d-1]?.up==="START")return;let c=d+1;for(n[c]?.up==="RECURSIVE"&&c++;;){const S=n[c];if(!S||S.kind!=="word"&&S.kind!=="qident"||(i.add(S.kind==="qident"?S.text.slice(1,-1):S.text),c++,n[c]?.text==="("&&(c=(l.get(c)??c)+1),n[c]?.up!=="AS")||(c++,n[c]?.up==="NOT"&&c++,n[c]?.up==="MATERIALIZED"&&c++,n[c]?.text!=="(")||(c=(l.get(c)??n.length)+1,n[c]?.text!==","))break;c++}}),r==="WITH"&&(r=n.find((E,d)=>o[d]===0&&H.has(E.up)&&d>0)?.up??"SELECT");const t=[];let a;const A=p(E=>{i.has(E)||/^\$/.test(E)||t.includes(E)||t.push(E)},"add");if(n.forEach((E,d)=>{const c=n[d-1]?.up,S=E.up==="FROM"||E.up==="JOIN",M=E.up==="INTO"&&(c==="INSERT"||c==="MERGE")||E.up==="UPDATE"&&c!=="DO"&&c!=="FOR"&&c!=="KEY"&&c!=="NO"||E.up==="USING"||E.up==="TABLE"&&d===0;if(!S&&!M)return;const x=s[d]??-1;if(S&&x>=0&&n[x-1]?.kind==="word"&&!["IN","EXISTS","ANY","ALL","AS","FROM","JOIN","LATERAL","SOME","ARRAY"].includes(n[x-1].up)&&n[x+1]?.up!=="SELECT"&&n[x+1]?.up!=="WITH")return;let h=d+1;for(;n[h]?.up==="ONLY"||n[h]?.up==="LATERAL";)h++;for(;;){const R=m(n,h,E.up==="INTO");if(!R||(A(R.name),M&&!a&&E.up!=="USING"&&(a=R.name),h=U(n,R.next,l),!S||n[h]?.text!==","))break;h++}}),(r==="DELETE"||r==="UPDATE"||r==="INSERT"||r==="MERGE")&&!a){const E=n.findIndex((d,c)=>d.up==="FROM"&&n[c-1]?.up==="DELETE");E>=0&&(a=m(n,E+1)?.name)}const L=C(n,l),D=u.find(E=>/^[\w.\-/:]{3,80}$/.test(E));return{id:O(`${r} ${L.replace(/\$\d+/g,"$?")}`),template:L,verb:r,tables:t,...a?{target:a}:{},...D?{name:D}:{}}}f(w,"D"),T(w,"G"),p(w,"compute");export function statementCount(e){let n=0,u=!1;for(const l of N(e).tokens)l.text===";"?(u&&n++,u=!1):u=!0;return n+(u?1:0)}f(statementCount,"statementCount"),T(statementCount,"statementCount"),p(statementCount,"statementCount");export function shapeMatchKey(e){const n=sqlShape(e),u=n.template.replace(/"(?:[^"]|"")*"|[^"]+/g,l=>l.startsWith('"')?l:l.toLowerCase());return`${n.verb} ${u.replace(/\$\d+/g,"?").replace(/\b(?:true|false)\b/g,"?")}`}f(shapeMatchKey,"shapeMatchKey"),T(shapeMatchKey,"shapeMatchKey"),p(shapeMatchKey,"shapeMatchKey");export function lineCommentSwallows(e){return!/\n/.test(e)&&N(e).lineComments>0}f(lineCommentSwallows,"lineCommentSwallows"),T(lineCommentSwallows,"lineCommentSwallows"),p(lineCommentSwallows,"lineCommentSwallows");
|
package/lib/stores.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)):t[r]=i(o.replace(/\s+#.*$/,""))}return t}
|
|
1
|
+
"use strict";var U=Object.defineProperty;var l=(s,e)=>U(s,"name",{value:e,configurable:!0});var j=Object.defineProperty,f=l((s,e)=>j(s,"name",{value:e,configurable:!0}),"p"),R=Object.defineProperty,p=f((s,e)=>R(s,"name",{value:e,configurable:!0}),"u");import{readFileSync as b}from"node:fs";import{join as g}from"node:path";const S=/^[A-Za-z0-9_-]+$/,A=new Set(["kind","url","databases","lens","run"]);export function readStoresDecl(s){let e;try{e=JSON.parse(b(g(s,"nx.json"),"utf8"))}catch{return{stores:{},errors:[],notes:[]}}const t=e?.lensmcp?.stores;return t===void 0?{stores:{},errors:[],notes:[]}:validateStoresDecl(t)}l(readStoresDecl,"readStoresDecl"),f(readStoresDecl,"readStoresDecl"),p(readStoresDecl,"readStoresDecl");export function validateStoresDecl(s){const e=[],t=[],i={};if(!s||typeof s!="object"||Array.isArray(s))return{stores:i,errors:["`lensmcp.stores` must be an object"],notes:t};for(const[n,a]of Object.entries(s)){const r=`stores.${n}`;if(!S.test(n)){e.push(`${r}: a store name is letters, digits, '-' and '_'`);continue}if(!a||typeof a!="object"||Array.isArray(a)){e.push(`${r}: must be an object`);continue}const o=a,m=o.kind;if(m!=="postgres"&&m!=="redis"){e.push(`${r}.kind: one of "postgres", "redis"`);continue}const v=typeof o.url=="string"?o.url.trim():"";if(!v){e.push(`${r}.url: the connection URL is required (e.g. "\${${m==="postgres"?"PG_URL":"REDIS_URL"}}")`);continue}const h=o.databases??[];if(!Array.isArray(h)||!h.every(u=>typeof u=="string"&&u.trim())){e.push(`${r}.databases: a list of URLs or database names`);continue}if(h.length&&m!=="postgres"){e.push(`${r}.databases: only a postgres store has databases`);continue}const d=o.lens??{};if(!d||typeof d!="object"||Array.isArray(d)){e.push(`${r}.lens: must be an object`);continue}const c=d;if(c.url!==void 0&&(typeof c.url!="string"||!c.url.trim())){e.push(`${r}.lens.url: a connection URL`);continue}if(c.read!==void 0&&typeof c.read!="boolean"){e.push(`${r}.lens.read: true or false`);continue}if(c.prepare!==void 0&&typeof c.prepare!="boolean"){e.push(`${r}.lens.prepare: true or false`);continue}o.run!==void 0&&t.push(`${r}.run: planned \u2014 lensmcp does not start stores yet; the store is used as declared`);for(const u of Object.keys(o))A.has(u)||t.push(`${r}.${u}: not a store setting \u2014 ignored`);i[n]={kind:m,url:v,databases:h.map(u=>u.trim()),lens:{...typeof c.url=="string"?{url:c.url.trim()}:{},read:c.read!==!1,prepare:c.prepare!==!1}}}return{stores:i,errors:e,notes:t}}l(validateStoresDecl,"validateStoresDecl"),f(validateStoresDecl,"validateStoresDecl"),p(validateStoresDecl,"validateStoresDecl");export function parseDotenv(s,e={}){const t={},i=p(n=>n.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(a,r)=>t[r]??e[r]??""),"expand");for(const n of s.split(/\r?\n/)){const a=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/.exec(n);if(!a)continue;const r=a[1],o=a[2];o.startsWith("'")&&o.indexOf("'",1)>0?t[r]=o.slice(1,o.indexOf("'",1)):o.startsWith('"')&&o.indexOf('"',1)>0?t[r]=i(o.slice(1,o.indexOf('"',1)).replace(/\\n/g,`
|
|
2
|
+
`)):t[r]=i(o.replace(/\s+#.*$/,""))}return t}l(parseDotenv,"parseDotenv"),f(parseDotenv,"parseDotenv"),p(parseDotenv,"parseDotenv");function $(s,e){try{return parseDotenv(b(s,"utf8"),e)}catch{return{}}}l($,"g"),f($,"$"),p($,"readDotenv");export function checkoutEnv(s,e=process.env){let t={};for(const n of[".env",".env.local"])t={...t,...$(g(s,n),{...t})};const i=Object.fromEntries(Object.entries(e).filter(n=>typeof n[1]=="string"));t={...t,...i};for(const n of[g(".lensmcp","instance.resources.env"),g(".lensmcp","instance.env")])t={...t,...$(g(s,n),{...t})};return t}l(checkoutEnv,"checkoutEnv"),f(checkoutEnv,"checkoutEnv"),p(checkoutEnv,"checkoutEnv");export function expandVars(s,e){const t=[];return{value:s.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(i,n)=>{const a=e[n];return(a===void 0||a==="")&&t.push(n),a??""}),missing:t}}l(expandVars,"expandVars"),f(expandVars,"expandVars"),p(expandVars,"expandVars");const y=p(s=>s.port||(s.protocol.startsWith("redis")?"6379":"5432"),"portOf");export function withDatabase(s,e){const t=new URL(s);return t.pathname=`/${e}`,t.toString()}l(withDatabase,"withDatabase"),f(withDatabase,"withDatabase"),p(withDatabase,"withDatabase");export function redactUrl(s){try{const e=new URL(s);return`${e.protocol}//${e.username?`${decodeURIComponent(e.username)}@`:""}${e.hostname}:${y(e)}${e.pathname}`}catch{return"(not a URL)"}}l(redactUrl,"redactUrl"),f(redactUrl,"redactUrl"),p(redactUrl,"redactUrl");export function resolveStores(s,e){return Object.entries(s).map(([t,i])=>{const n=expandVars(i.url,e),a=[...n.missing];let r;try{r=n.missing.length?void 0:new URL(n.value)}catch{r=void 0}const o=[];if(r&&i.kind==="postgres"){o.push({name:decodeURIComponent(r.pathname.replace(/^\//,""))||"postgres",url:n.value});for(const h of i.databases){const d=expandVars(h,e);if(d.missing.length){a.push(...d.missing);continue}const c=/^[a-z]+:\/\//i.test(d.value)?d.value:withDatabase(n.value,d.value);try{const u=decodeURIComponent(new URL(c).pathname.replace(/^\//,""));u&&!o.some(x=>x.name===u)&&o.push({name:u,url:c})}catch{}}}const m=i.lens.url?expandVars(i.lens.url,e):void 0;m?.missing.length&&a.push(...m.missing);const v=i.lens.read?a.length?`${[...new Set(a)].map(h=>`\${${h}}`).join(", ")} not set in this checkout`:r?void 0:"`url` is not a connection URL":"reading is off (`lens.read: false`)";return{name:t,kind:i.kind,server:r?`${r.hostname}:${y(r)}`:"?",databases:o,...v?{noRead:v}:{readUrl:m?.value||n.value},prepare:i.lens.prepare!==!1,missing:[...new Set(a)]}})}l(resolveStores,"resolveStores"),f(resolveStores,"resolveStores"),p(resolveStores,"resolveStores");
|
package/lib/story.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var I=Object.defineProperty;var u=(t,n)=>I(t,"name",{value:n,configurable:!0});var k=Object.defineProperty,c=u((t,n)=>k(t,"name",{value:n,configurable:!0}),"u"),b=Object.defineProperty,p=c((t,n)=>b(t,"name",{value:n,configurable:!0}),"c");export function groupByFlow(t){const n=new Map;for(const e of t){const o=e.context.flowId;if(!o)continue;let s=n.get(o);s||(s=[],n.set(o,s)),s.push(e)}return n}u(groupByFlow,"groupByFlow"),c(groupByFlow,"groupByFlow"),p(groupByFlow,"groupByFlow");export function compileStory(t,n={}){let e,o;if(n.flowId)o=n.flowId,e=t.filter(r=>r.context.flowId===o);else{const r=t.find(i=>i.context.flowId);if(!r)return;o=r.context.flowId,e=t.filter(i=>i.context.flowId===o)}if(e.length===0)return;e.sort((r,i)=>r.timestamp-i.timestamp);const s=1e3;e.length>s&&(e=[e[0],...e.slice(e.length-(s-1))]);const m=e[0],d=[];let l,v;for(const r of e){const i=f(r);if(i){if(d.push(i),i.kind==="render"||i.kind==="final-render"){const a=r.raw;a?.render&&(l={id:a.render.id,page:a.render.page,route:a.render.route,componentName:a.render.componentName})}else if(r.source==="visual"&&i.kind==="visual-violation"){const a=r.raw;a?.frame&&(v=a.frame.id)}}}for(let r=d.length-1;r>=0;r--)if(d[r].kind==="render"){d[r]={...d[r],kind:"final-render"};break}const g=e[0].timestamp,w=e[e.length-1].timestamp;return{flowId:o,origin:{type:m.context.originType,nodeId:m.context.originNodeId,at:m.timestamp},phases:d,finalState:l?{page:l.page,route:l.route,componentName:l.componentName,renderId:l.id,visualFrameId:v}:void 0,startedAt:g,endedAt:w,eventCount:e.length}}u(compileStory,"compileStory"),c(compileStory,"compileStory"),p(compileStory,"compileStory");function f(t){const n=(t.raw??null)?.kind;if(n==="flow-origin"||t.source==="client-runtime"&&n==="user-action"){const e=t.raw;return{kind:"user-action",at:t.timestamp,label:e?.origin?.label??t.title,eventIds:[t.id]}}if(t.source==="react"&&n==="render"){const e=t.raw;return{kind:"render",at:t.timestamp,label:`render ${e?.render?.componentName??"?"}`,eventIds:[t.id],details:e?.render?{componentName:e.render.componentName,durationMs:e.render.actualDurationMs}:void 0}}if(t.source==="react"&&n==="slot-content-changed"){const e=t.raw,o=e?.slot?.toComponent??"?";return{kind:/spinner|loader|loading/i.test(o)?"loading-ui":"idle-ui",at:t.timestamp,label:`slot ${e?.slot?.slotLogicalId??""} \u2192 ${o}`,eventIds:[t.id]}}if(t.source==="client-runtime"&&n==="route"){const e=t.raw;return{kind:"route-transition",at:t.timestamp,label:`route ${e?.from??""} \u2192 ${e?.url??""}`,eventIds:[t.id]}}if(t.source==="valtio"&&n==="state-update"){const e=t.raw;return{kind:"state-update",at:t.timestamp,label:`${e?.update?.storeId??"?"}.${e?.update?.path??"?"}`,eventIds:[t.id],details:e?.update}}if(t.source==="nestjs"&&n==="server-request"){const e=t.raw;return{kind:"backend-request",at:t.timestamp,label:`${e?.request?.method??"?"} ${e?.request?.route??"?"} \u2192 ${e?.request?.status??"?"}`,eventIds:[t.id],details:e?.request}}if(t.source==="chrome"&&t.category==="network")return{kind:"backend-request",at:t.timestamp,label:t.title,eventIds:[t.id]};if(t.source==="visual"&&n==="visual-violation"){const e=t.raw;return{kind:"visual-violation",at:t.timestamp,label:`${e?.violation?.ruleType??"rule"} ${e?.violation?.ruleId??""}`,eventIds:[t.id]}}}u(f,"f"),c(f,"g"),p(f,"classifyEvent");
|
package/lib/thresholds.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var l=Object.defineProperty;var o=(e,r)=>l(e,"name",{value:r,configurable:!0});var u=Object.defineProperty,t=o((e,r)=>u(e,"name",{value:r,configurable:!0}),"r"),c=Object.defineProperty,a=t((e,r)=>c(e,"name",{value:r,configurable:!0}),"n");export const DEFAULT_THRESHOLDS={dbInLoop:5,nPlusOne:3,renderStorm:5,slowRouteMs:500,slowRenderMs:16,slowQueryMs:100,duplicateRequestPeak:3,slowEgressMs:1e3};export function resolveThresholds(e){const r={...DEFAULT_THRESHOLDS};if(e)for(const n of Object.keys(DEFAULT_THRESHOLDS)){const s=e[n];typeof s=="number"&&Number.isFinite(s)&&s>=0&&(r[n]=s)}return r}o(resolveThresholds,"resolveThresholds"),t(resolveThresholds,"resolveThresholds"),a(resolveThresholds,"resolveThresholds");
|
package/lib/ulid.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var s=Object.defineProperty;var o=(e,n)=>s(e,"name",{value:n,configurable:!0});var b=Object.defineProperty,a=o((e,n)=>b(e,"name",{value:n,configurable:!0}),"r"),m=Object.defineProperty,u=a((e,n)=>m(e,"name",{value:n,configurable:!0}),"r");const f="0123456789ABCDEFGHJKMNPQRSTVWXYZ",g=16;function c(e,n){let r="",t=e;for(let l=n-1;l>=0;l--){const d=t%32;r=f[d]+r,t=(t-d)/32}return r}o(c,"l"),a(c,"s"),u(c,"encodeTime");function i(e){const n=new Uint8Array(e);globalThis.crypto.getRandomValues(n);let r="";for(let t=0;t<e;t++)r+=f[(n[t]??0)&31];return r}o(i,"s"),a(i,"a"),u(i,"encodeRandom");export function ulid(e=Date.now()){return c(e,10)+i(16)}o(ulid,"ulid"),a(ulid,"ulid"),u(ulid,"ulid");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lensmcp/core",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
}
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@lensmcp/protocol-types": "1.25.
|
|
62
|
+
"@lensmcp/protocol-types": "1.25.1",
|
|
63
63
|
"tslib": "^2.3.0"
|
|
64
64
|
},
|
|
65
65
|
"license": "Apache-2.0",
|