@lensmcp/core 1.25.35 → 1.25.36

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 CHANGED
@@ -1 +1 @@
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");
1
+ "use strict";var a=Object.defineProperty;var r=(t,i)=>a(t,"name",{value:i,configurable:!0});var s=Object.defineProperty,n=r((t,i)=>s(t,"name",{value:i,configurable:!0}),"r");import*as c from"node:fs";import{dirname as l,join as o}from"node:path";export const AI_CONTENT_DIR="ai";const d=/^ai_[0-9a-z]{8,40}$/;export const isAiCallId=n(t=>typeof t=="string"&&d.test(t),"isAiCallId");export function aiContentDir(t){return o(l(t),AI_CONTENT_DIR)}r(aiContentDir,"aiContentDir"),n(aiContentDir,"aiContentDir");export function aiContentFile(t,i){if(!isAiCallId(i))throw new Error("invalid ai call id");return o(aiContentDir(t),`${i}.json`)}r(aiContentFile,"aiContentFile"),n(aiContentFile,"aiContentFile");export function readAiContent(t,i){if(isAiCallId(i))try{const e=JSON.parse(c.readFileSync(aiContentFile(t,i),"utf8"));return e&&e.schemaVersion===1&&e.id===i?e:void 0}catch{return}}r(readAiContent,"readAiContent"),n(readAiContent,"readAiContent");
@@ -1,2 +1,2 @@
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");
1
+ "use strict";var W=Object.defineProperty;var d=(e,t)=>W(e,"name",{value:t,configurable:!0});var Y=Object.defineProperty,f=d((e,t)=>Y(e,"name",{value:t,configurable:!0}),"a");import{boundedClone as G}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 j=900,L=32,z=new Set(["timestamp","startedAt","startTime","at","emittedAt","lastSeenAt","endedAt","endTime","t","ts","time"]),V=f(e=>typeof e=="number"&&e>=1e11&&e<=1e14,"isEpochMs"),H=.95;export function answerBudgetBytes(e=process.env){const t=e[ANSWER_BUDGET_ENV];if(t===void 0||t.trim()==="")return DEFAULT_ANSWER_BUDGET_BYTES;const r=Number(t);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"),f(answerBudgetBytes,"answerBudgetBytes");export function utf8Bytes(e){let t=0;for(let r=0;r<e.length;r++){const i=e.charCodeAt(r);i<128?t+=1:i<2048?t+=2:i>=55296&&i<=56319&&r+1<e.length&&(e.charCodeAt(r+1)&64512)===56320?(t+=4,r+=1):t+=3}return t}d(utf8Bytes,"utf8Bytes"),f(utf8Bytes,"utf8Bytes");export function jsonBytes(e){let t;try{t=JSON.stringify(e)}catch{return Number.POSITIVE_INFINITY}return t===void 0?0:utf8Bytes(t)}d(jsonBytes,"jsonBytes"),f(jsonBytes,"jsonBytes");const O=f(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isRecord");function R(e){if(!O(e))return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}d(R,"D"),f(R,"isPlain");export function newestEndOf(e){const t=e[0];if(e.length<2||!O(t))return;let r;for(const i of Object.keys(t)){if(typeof t[i]!="number"||!(z.has(i)||V(t[i])))continue;let s=0,h=0,l=!0,g=t[i];for(let E=1;E<e.length;E++){const w=e[E],p=O(w)?w[i]:void 0;if(typeof p!="number"){l=!1;break}p>g?s+=1:p<g&&(h+=1),g=p}const y=s+h;if(!l||y===0)continue;const x=Math.max(s,h)/y;x>=H&&(!r||x>r.agreement)&&(r={end:s>=h?"end":"start",agreement:x})}return r?.end}d(newestEndOf,"newestEndOf"),f(newestEndOf,"newestEndOf");export function newestFirst(e){return newestEndOf(e)==="end"?[...e].reverse():e.slice()}d(newestFirst,"newestFirst"),f(newestFirst,"newestFirst");export function shortenText(e,t){if(e.length<=t)return e;let r=Math.max(0,t);const i=e.lastIndexOf(`
2
+ `,r);return i>=r/2&&(r=i),r>0&&(e.charCodeAt(r-1)&64512)===55296&&(r-=1),`${e.slice(0,r)}\u2026[lensmcp truncated: ${e.length-r} more chars]`}d(shortenText,"shortenText"),f(shortenText,"shortenText");export function fitList(e,t,r={}){const i=e.length,s=e.reduce((o,u)=>o+jsonBytes(u)+1,2);if(s<=t)return{items:e.slice(),total:i,returned:i,kept:"all",shortenedStrings:0,repeatedStrings:0,bytes:s};const h=r.newest??newestEndOf(e),l=h??r.keep??"start",g=r.name??"items",y=r.maxStringChars??FITTED_STRING_CHARS,x=l==="start"?e:[...e].reverse(),E=String(Math.max(0,i-1)).length,w=new Map,p=[],c=[];let S=2,b=0,$=0;for(let o=0;o<x.length;o++){const u=new Map,_=[];let M=0;const v=f((a,N,I,P,U)=>{if(typeof a=="string"){if(a.length>=REPEATED_STRING_MIN_CHARS){const m=w.get(a)??u.get(a);if(m)return _.push({holder:P,key:U,owner:m.owner,path:m.path}),`\u2026[lensmcp: same text as ${g}[${"9".repeat(E)}]${m.path}]`;u.set(a,{owner:o,path:N})}return a.length>y?(M+=1,shortenText(a,y)):a}if(I>=L)return a;if(Array.isArray(a)){const m=[];return a.forEach((T,D)=>m.push(v(T,`${N}[${D}]`,I+1,m,D))),m}if(R(a)){const m={};for(const T of Object.keys(a))m[T]=v(a[T],`${N}.${T}`,I+1,m,T);return m}return a},"slim"),F=[];let k=v(x[o],"",0,F,0),B=jsonBytes(k)+1;if(c.length===0&&S+B>t)k=C(x[o],Math.max(0,t-S-1)),B=jsonBytes(k)+1,_.length=0,u.clear(),M=1;else if(S+B>t)break;c.push(k),S+=B,b+=M,$+=_.length;for(const[a,N]of u)w.set(a,N);for(const a of _)p.push(a.holder===F?{...a,holder:c,key:c.length-1}:a)}const A=c.length,n=f(o=>l==="start"?o:A-1-o,"indexOf");if(l==="end"){for(const o of p)o.holder===c&&(o.key=n(o.key));c.reverse()}for(const o of p)o.holder[o.key]=`\u2026[lensmcp: same text as ${g}[${n(o.owner)}]${o.path}]`;return{items:c,total:i,returned:A,kept:A===i?"all":h?"newest":l==="start"?"first":"last",shortenedStrings:b,repeatedStrings:$,bytes:jsonBytes(c)}}d(fitList,"fitList"),f(fitList,"fitList");function C(e,t){let r=Math.max(256,t),i=e;for(let s=0;s<6;s++){if(i=G(e,{rawByteLimit:r,maxStringBytes:Math.min(2e3,Math.max(128,Math.floor(r/4))),maxArrayItems:64}).value,jsonBytes(i)<=t)return i;r=Math.floor(r*.6)}return i}d(C,"Y"),f(C,"clampTo");export function shareBudget(e,t){const r=e.map((h,l)=>({size:h,index:l})).sort((h,l)=>h.size-l.size),i=new Array(e.length).fill(0);let s=Math.max(0,t);return r.forEach(({size:h,index:l},g)=>{const y=Math.floor(s/(r.length-g));i[l]=Math.min(h,y),s-=i[l]}),i}d(shareBudget,"shareBudget"),f(shareBudget,"shareBudget");export function fitAnswer(e,t,r={}){if(!Number.isFinite(t)||e===null||typeof e!="object")return{value:e};const i=jsonBytes(e);if(i<=t)return{value:e};const s={limitBytes:t,originalBytes:i,lists:[],shortenedStrings:0,repeatedStrings:0,note:""},h=f(()=>{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 (${t} 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(e)){const n=fitList(e,t);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,h(),{value:n.items,cut:s}}if(!R(e))return{value:e};const l=Object.keys(e),g=l.filter(n=>Array.isArray(e[n])&&e[n].length>0),y=g.map(n=>jsonBytes(e[n])),x=i-y.reduce((n,o)=>n+o,0),E=shareBudget(y,t-x-j),w={};g.forEach((n,o)=>{if(y[o]<=E[o])return;const u=fitList(e[n],E[o],{name:n,...r.newest?.[n]?{newest:r.newest[n]}:{}});w[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=f(n=>(h(),{[ANSWER_CUT_KEY]:s,...n}),"assemble"),c={};for(const n of l)c[n]=n in w?w[n]:e[n];let S=p(c);if(jsonBytes(S)<=t)return{value:S,cut:s};s.clamped=!0;let b=Math.max(512,t-j);for(let n=0;n<6;n++){if(S=p(C(c,b)),jsonBytes(S)<=t)return{value:S,cut:s};b=Math.floor(b*.6)}const $={};let A=j;for(const n of l){const o=e[n];if(o!==null&&typeof o=="object")continue;const u=jsonBytes(o)+utf8Bytes(n)+4;if(A+u>t)break;$[n]=o,A+=u}return{value:p($),cut:s}}d(fitAnswer,"fitAnswer"),f(fitAnswer,"fitAnswer");
@@ -1 +1 @@
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");
1
+ "use strict";var l=Object.defineProperty;var i=(t,r)=>l(t,"name",{value:r,configurable:!0});var S=Object.defineProperty,u=i((t,r)=>S(t,"name",{value:r,configurable:!0}),"u");export const MAX_BUS_GENERATIONS=20,BUS_ROTATE_CHECK_BYTES=1048576;export function busCapsFromEnv(t=process.env){const r=Number(t.LENSMCP_EVENT_MAX_BYTES),e=Number(t.LENSMCP_EVENT_MAX_FILES);return{maxBytes:Number.isFinite(r)&&r>0?r:50*1024*1024,maxFiles:Number.isFinite(e)&&e>=1&&e<=20?Math.floor(e):5}}i(busCapsFromEnv,"busCapsFromEnv"),u(busCapsFromEnv,"busCapsFromEnv");export function rotateBusFile(t,r){const{fs:e,maxBytes:y,maxFiles:a}=r,n=`${t}.rotate.lock`,o=r.staleLockMs??3e4;let s;for(let c=0;c<2&&s===void 0;c++)try{s=e.openSync(n,"wx")}catch{try{if(Date.now()-e.statSync(n).mtimeMs<=o)return"busy";e.unlinkSync(n)}catch{}}if(s===void 0)return"busy";try{try{if(e.statSync(t).size<=y)return"not-needed"}catch{return"not-needed"}try{e.unlinkSync(`${t}.${a}`)}catch{}for(let c=a+1;c<=20;c++)try{e.unlinkSync(`${t}.${c}`)}catch{}for(let c=a-1;c>=1;c--)try{e.renameSync(`${t}.${c}`,`${t}.${c+1}`)}catch{}try{e.renameSync(t,`${t}.1`)}catch{}return"rotated"}finally{try{e.closeSync(s)}catch{}try{e.unlinkSync(n)}catch{}}}i(rotateBusFile,"rotateBusFile"),u(rotateBusFile,"rotateBusFile");export function createBusRotator(t,r){const{fs:e,maxBytes:y}=r,a=Math.max(0,Math.min(r.checkEveryBytes??1048576,y));let n=a,o=0;return s=>{if(n>=a||o+n>y)try{o=e.statSync(t).size,n=0,o>y&&rotateBusFile(t,r)==="rotated"&&(o=0)}catch{}n+=s}}i(createBusRotator,"createBusRotator"),u(createBusRotator,"createBusRotator");
package/lib/event-bus.js CHANGED
@@ -1 +1 @@
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}}
1
+ "use strict";var o=Object.defineProperty;var n=(e,t)=>o(e,"name",{value:t,configurable:!0});var c=Object.defineProperty,h=n((e,t)=>c(e,"name",{value:t,configurable:!0}),"e");export class EventBus{static{n(this,"EventBus")}static{h(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 s=t;if(this.transform)try{s=this.transform(t)??t}catch{s=t}for(const r of this.subs)if(!(r.filter&&!r.filter(s)))try{const i=r.handler(s);i&&typeof i.then=="function"&&i.catch(()=>{})}catch{}}subscribe(t,s){const r={handler:t,filter:s};return this.subs.add(r),()=>{this.subs.delete(r)}}droppedCount(){return this.dropped}subscriberCount(){return this.subs.size}}
@@ -1 +1 @@
1
- "use strict";var g=Object.defineProperty;var c=(e,o)=>g(e,"name",{value:o,configurable:!0});var x=Object.defineProperty,m=c((e,o)=>x(e,"name",{value:o,configurable:!0}),"m"),v=Object.defineProperty,p=m((e,o)=>v(e,"name",{value:o,configurable:!0}),"u");import{LOOP_STARTUP_MS as O,loopStartedAt as b}from"@lensmcp/protocol-types";export const LOOP_SAMPLE_MS=5e3,LOOP_ROLLUP_MS=3e5,LOOP_SAMPLE_HOURS=6;const L=720,f=p(e=>typeof e=="number"&&Number.isFinite(e)&&e>=0,"finite");export function parseLoopSamples(e){if(!Array.isArray(e))return[];const o=new Map;for(const r of e.slice(-L)){if(!Array.isArray(r)||r.length<5)continue;const[a,s,t,i,n]=r;!f(a)||a<=0||!f(s)||!f(t)||!f(i)||!f(n)||o.set(a,[a,s,t,i,Math.min(1,n)])}return[...o.values()].sort((r,a)=>r[0]-a[0])}c(parseLoopSamples,"parseLoopSamples"),m(parseLoopSamples,"parseLoopSamples"),p(parseLoopSamples,"parseLoopSamples");export const rollupOf=p(e=>({at:e[0],n:1,meanSum:e[1],p99:e[2],max:e[3],utilSum:e[4]}),"rollupOf");export function bucketRollups(e,o){const r=Math.max(1,Math.floor(o)),a=new Map;for(const t of e){if(!(t.n>0))continue;const i=Math.floor(t.at/r)*r,n=a.get(i);n?(n.n+=t.n,n.meanSum+=t.meanSum,n.utilSum+=t.utilSum,n.p99=Math.max(n.p99,t.p99),n.max=Math.max(n.max,t.max)):a.set(i,{...t,at:i})}const s=p((t,i)=>Number(t.toFixed(i)),"round");return[...a.values()].sort((t,i)=>t.at-i.at).map(t=>[t.at,s(t.meanSum/t.n,2),s(t.p99,2),s(t.max,2),s(t.utilSum/t.n,4)])}c(bucketRollups,"bucketRollups"),m(bucketRollups,"bucketRollups"),p(bucketRollups,"bucketRollups");const d=[5,10,15,30,60,120,300,600,900,1800,3600,7200,21600,43200,86400].map(e=>e*1e3);export function historyStep(e,o){const r=Math.max(o.minMs,o.requestedMs??0,e/(o.maxPoints??400));return d.find(a=>a>=r&&a%o.minMs===0)??d[d.length-1]}c(historyStep,"historyStep"),m(historyStep,"historyStep"),p(historyStep,"historyStep");export function historySource(e,o,r=LOOP_SAMPLE_HOURS){return e>=o-r*36e5-6e4?"samples":"rollups"}c(historySource,"historySource"),m(historySource,"historySource"),p(historySource,"historySource");export function bucketStalls(e,o){const r=Math.max(1,Math.floor(o)),a=new Map;for(const s of e){const t=Math.floor(s.startAt/r)*r,i=b(s.loopId),n=i!==void 0&&s.startAt<i+O,l=`${s.loopId}\0${t}\0${n}`,u=a.get(l);u?(u.count++,u.longestMs=Math.max(u.longestMs,s.durationMs),u.unresponsive||=s.unresponsive):a.set(l,{loopId:s.loopId,project:s.project,runtime:s.runtime,at:t,count:1,longestMs:s.durationMs,unresponsive:s.unresponsive,...n?{startup:!0}:{}})}return[...a.values()].sort((s,t)=>s.at-t.at||s.loopId.localeCompare(t.loopId)||+!!s.startup-+!!t.startup)}c(bucketStalls,"bucketStalls"),m(bucketStalls,"bucketStalls"),p(bucketStalls,"bucketStalls");export class LoopSampleRing{static{c(this,"LoopSampleRing")}static{m(this,"LoopSampleRing")}static{p(this,"LoopSampleRing")}constructor(o=36e5,r=4e4){this.keepMs=o,this.maxSamples=r,this.rings=new Map,this.total=0,this.touches=0}add(o,r,a=Date.now()){const s=a-this.keepMs;let t=this.rings.get(o.id),i=0;for(const n of r){if(n[0]<s)continue;t||this.rings.set(o.id,t={loop:o,samples:[],touched:0});const l=t.samples,u=l[l.length-1];if(!u||n[0]>u[0])l.push(n);else{let h=0,S=l.length;for(;h<S;){const M=h+S>>1;l[M][0]<n[0]?h=M+1:S=M}if(l[h]?.[0]===n[0])continue;l.splice(h,0,n)}i++}return t&&i&&(t.loop=o,t.touched=++this.touches,this.total+=i),this.trim(s),i}read(o,r,a=Date.now()){this.trim(a-this.keepMs);const s=[];for(const t of this.rings.values()){const i=t.samples.filter(n=>n[0]>=o&&n[0]<r);i.length&&s.push({loop:t.loop,samples:i})}return s}get size(){return this.total}trim(o){for(const[r,a]of this.rings){let s=0;for(;s<a.samples.length&&a.samples[s][0]<o;)s++;s&&(a.samples.splice(0,s),this.total-=s),a.samples.length||this.rings.delete(r)}if(!(this.total<=this.maxSamples))for(const r of[...this.rings.values()].sort((a,s)=>a.touched-s.touched)){if(this.total<=this.maxSamples)break;this.total-=r.samples.length,this.rings.delete(r.loop.id)}}}
1
+ "use strict";var d=Object.defineProperty;var m=(n,e)=>d(n,"name",{value:e,configurable:!0});var g=Object.defineProperty,p=m((n,e)=>g(n,"name",{value:e,configurable:!0}),"u");import{LOOP_STARTUP_MS as x,loopStartedAt as v}from"@lensmcp/protocol-types";export const LOOP_SAMPLE_MS=5e3,LOOP_ROLLUP_MS=3e5,LOOP_SAMPLE_HOURS=6;const O=720,h=p(n=>typeof n=="number"&&Number.isFinite(n)&&n>=0,"finite");export function parseLoopSamples(n){if(!Array.isArray(n))return[];const e=new Map;for(const a of n.slice(-O)){if(!Array.isArray(a)||a.length<5)continue;const[o,s,t,r,i]=a;!h(o)||o<=0||!h(s)||!h(t)||!h(r)||!h(i)||e.set(o,[o,s,t,r,Math.min(1,i)])}return[...e.values()].sort((a,o)=>a[0]-o[0])}m(parseLoopSamples,"parseLoopSamples"),p(parseLoopSamples,"parseLoopSamples");export const rollupOf=p(n=>({at:n[0],n:1,meanSum:n[1],p99:n[2],max:n[3],utilSum:n[4]}),"rollupOf");export function bucketRollups(n,e){const a=Math.max(1,Math.floor(e)),o=new Map;for(const t of n){if(!(t.n>0))continue;const r=Math.floor(t.at/a)*a,i=o.get(r);i?(i.n+=t.n,i.meanSum+=t.meanSum,i.utilSum+=t.utilSum,i.p99=Math.max(i.p99,t.p99),i.max=Math.max(i.max,t.max)):o.set(r,{...t,at:r})}const s=p((t,r)=>Number(t.toFixed(r)),"round");return[...o.values()].sort((t,r)=>t.at-r.at).map(t=>[t.at,s(t.meanSum/t.n,2),s(t.p99,2),s(t.max,2),s(t.utilSum/t.n,4)])}m(bucketRollups,"bucketRollups"),p(bucketRollups,"bucketRollups");const S=[5,10,15,30,60,120,300,600,900,1800,3600,7200,21600,43200,86400].map(n=>n*1e3);export function historyStep(n,e){const a=Math.max(e.minMs,e.requestedMs??0,n/(e.maxPoints??400));return S.find(o=>o>=a&&o%e.minMs===0)??S[S.length-1]}m(historyStep,"historyStep"),p(historyStep,"historyStep");export function historySource(n,e,a=LOOP_SAMPLE_HOURS){return n>=e-a*36e5-6e4?"samples":"rollups"}m(historySource,"historySource"),p(historySource,"historySource");export function bucketStalls(n,e){const a=Math.max(1,Math.floor(e)),o=new Map;for(const s of n){const t=Math.floor(s.startAt/a)*a,r=v(s.loopId),i=r!==void 0&&s.startAt<r+x,l=`${s.loopId}\0${t}\0${i}`,u=o.get(l);u?(u.count++,u.longestMs=Math.max(u.longestMs,s.durationMs),u.unresponsive||=s.unresponsive):o.set(l,{loopId:s.loopId,project:s.project,runtime:s.runtime,at:t,count:1,longestMs:s.durationMs,unresponsive:s.unresponsive,...i?{startup:!0}:{}})}return[...o.values()].sort((s,t)=>s.at-t.at||s.loopId.localeCompare(t.loopId)||+!!s.startup-+!!t.startup)}m(bucketStalls,"bucketStalls"),p(bucketStalls,"bucketStalls");export class LoopSampleRing{static{m(this,"LoopSampleRing")}static{p(this,"LoopSampleRing")}constructor(e=36e5,a=4e4){this.keepMs=e,this.maxSamples=a,this.rings=new Map,this.total=0,this.touches=0}add(e,a,o=Date.now()){const s=o-this.keepMs;let t=this.rings.get(e.id),r=0;for(const i of a){if(i[0]<s)continue;t||this.rings.set(e.id,t={loop:e,samples:[],touched:0});const l=t.samples,u=l[l.length-1];if(!u||i[0]>u[0])l.push(i);else{let c=0,f=l.length;for(;c<f;){const M=c+f>>1;l[M][0]<i[0]?c=M+1:f=M}if(l[c]?.[0]===i[0])continue;l.splice(c,0,i)}r++}return t&&r&&(t.loop=e,t.touched=++this.touches,this.total+=r),this.trim(s),r}read(e,a,o=Date.now()){this.trim(o-this.keepMs);const s=[];for(const t of this.rings.values()){const r=t.samples.filter(i=>i[0]>=e&&i[0]<a);r.length&&s.push({loop:t.loop,samples:r})}return s}get size(){return this.total}trim(e){for(const[a,o]of this.rings){let s=0;for(;s<o.samples.length&&o.samples[s][0]<e;)s++;s&&(o.samples.splice(0,s),this.total-=s),o.samples.length||this.rings.delete(a)}if(!(this.total<=this.maxSamples))for(const a of[...this.rings.values()].sort((o,s)=>o.touched-s.touched)){if(this.total<=this.maxSamples)break;this.total-=a.samples.length,this.rings.delete(a.loop.id)}}}
package/lib/event-loop.js CHANGED
@@ -1 +1 @@
1
- "use strict";var k=Object.defineProperty;var u=(n,e)=>k(n,"name",{value:e,configurable:!0});var L=Object.defineProperty,h=u((n,e)=>L(n,"name",{value:e,configurable:!0}),"u"),S=Object.defineProperty,l=h((n,e)=>S(n,"name",{value:e,configurable:!0}),"u");import{LoopSampleRing as T,parseLoopSamples as q}from"./event-loop-history.js";const v=l(n=>n&&typeof n=="object"&&!Array.isArray(n)?n:{},"object"),o=l(n=>typeof n=="number"&&Number.isFinite(n)&&n>=0?n:void 0,"number"),s=l((n,e=250)=>typeof n=="string"&&n?n.slice(0,e):void 0,"text"),j=40;export function eventLoopIdentity(n){const e=v(n),t=s(e.id),i=s(e.project);if(!(!t||!i||e.runtime!=="node"&&e.runtime!=="browser"))return{id:t,project:i,runtime:e.runtime,...o(e.pid)!==void 0?{pid:o(e.pid)}:{},...o(e.threadId)!==void 0?{threadId:o(e.threadId)}:{},...s(e.tabId)?{tabId:s(e.tabId)}:{},...s(e.loadId)?{loadId:s(e.loadId)}:{}}}u(eventLoopIdentity,"eventLoopIdentity"),h(eventLoopIdentity,"eventLoopIdentity"),l(eventLoopIdentity,"eventLoopIdentity");export function eventLoopIncident(n){const e=v(n.raw);if(e.kind!=="event-loop-stall")return;const t=eventLoopIdentity(e.loop),i=o(e.startedAt),d=o(e.durationMs),r=e.mechanism;if(!t||i===void 0||d===void 0||!["callback","heartbeat","long-animation-frame","longtask"].includes(String(r)))return;const m=e.state==="unresponsive"?"unresponsive":e.state==="unknown"?"unknown":"recovered",p=[];for(const w of Array.isArray(e.scripts)?e.scripts.slice(0,8):[]){const c=v(w),I=s(c.url,512);I&&p.push({url:I,durationMs:o(c.durationMs)??0,startAt:o(c.startAt)??i,...s(c.functionName)?{functionName:s(c.functionName)}:{},...s(c.invoker)?{invoker:s(c.invoker)}:{}})}const f=r==="callback"?s(n.context?.flowId):void 0;return{id:s(e.incidentId)??n.id,loop:t,startAt:i,durationMs:d,observedAt:n.timestamp,...m==="recovered"?{endAt:i+d}:{},state:m,mechanism:r,severity:d>=1e3?"error":"warning",...f?{flowId:f}:{},...s(n.context?.requestId)?{requestId:s(n.context?.requestId)}:{},...s(e.callbackType)?{callbackType:s(e.callbackType)}:{},scripts:p,evidence:[],evidenceTruncated:e.scriptsTruncated===!0||(o(e.droppedIncidents)??0)>0||(o(e.floodSuppressed)??0)>0,explanation:r==="callback"?"Synchronous callback wall time, including any GC or process descheduling. Execution context identifies the flow; overlapping operations are not proven causes.":r==="heartbeat"?"The loop missed its heartbeat. The observer cannot identify executing code; overlapping work may have been delayed.":"Browser-measured main-thread work. Script timings identify contributing scripts where supported; overlapping flows are associated by time only."}}u(eventLoopIncident,"eventLoopIncident"),h(eventLoopIncident,"eventLoopIncident"),l(eventLoopIncident,"eventLoopIncident");export class EventLoopIndex{static{u(this,"EventLoopIndex")}static{h(this,"EventLoopIndex")}static{l(this,"EventLoopIndex")}constructor(e=()=>{},t=()=>{}){this.onChange=e,this.onSamples=t,this.incidents=new Map,this.loops=new Map,this.recent=[],this.history=new T}ingest(e){const t=v(e.raw),i=s(t.kind)??e.source,d=eventLoopIdentity(t.loop);if(d){const a=this.loops.get(d.id);if(!a||e.timestamp>=a.lastSeen)for(this.loops.set(d.id,{loop:d,lastSeen:e.timestamp,state:t.state==="unresponsive"?"unresponsive":t.state==="unknown"?"unknown":"observed",coverage:s(t.coverage,500)??a?.coverage??(d.runtime==="node"?"Instrumented Node thread":"Browser main thread; supported PerformanceObserver entries"),...a?{meanMs:a.meanMs,maxMs:a.maxMs,p99Ms:a.p99Ms,utilization:a.utilization}:{},...o(t.lagMs)!==void 0?{meanMs:o(t.lagMs),maxMs:o(t.maxMs),p99Ms:o(t.p99Ms),utilization:o(t.utilization)}:{}});this.loops.size>200;)this.loops.delete(this.loops.keys().next().value);if(i==="event-loop-lag"){const g=q(t.samples);g.length&&(this.history.add(d,g),this.onSamples(d,g))}}const r=eventLoopIncident(e);if(r){const a=this.incidents.get(r.id);if(a&&a.observedAt>r.observedAt)return;a&&(r.evidence=a.evidence.slice(),r.evidenceTruncated||=a.evidenceTruncated);for(const g of this.recent)this.attach(r,g);for(this.incidents.set(r.id,r);this.incidents.size>200;)this.incidents.delete(this.incidents.keys().next().value);this.onChange(r);return}if(i.startsWith("event-loop-"))return;const m=s(t.loopId);if(!m)return;const p=v(t.span),f=v(t.request),w=v(t.render),c=o(t.durationMs)??o(p.durationMs)??o(f.durationMs)??o(w.actualDurationMs)??0,I=o(t.startedAt)??o(p.startTime)??o(f.startedAt)??e.timestamp-c,b=o(p.syncDurationMs),y=o(p.syncStartedAt),x=b!==void 0&&b>=50&&y!==void 0,A={loopId:m,eventId:e.id,title:(e.title??i).slice(0,250),kind:i,startAt:x?y:I,endAt:x?y+b:I+c,...e.context?.flowId?{flowId:e.context.flowId}:{},...e.context?.requestId?{requestId:e.context.requestId}:{},relation:x?"executing":"overlap"};this.recent.push(A),this.recent.length>2e3&&this.recent.splice(0,this.recent.length-2e3);for(const a of this.incidents.values())this.attach(a,A)&&this.onChange(a)}attach(e,t){if(t.loopId!==e.loop.id||t.endAt<e.startAt||t.startAt>(e.endAt??e.observedAt)||e.evidence.some(r=>r.eventId===t.eventId))return!1;if(e.evidence.length>=j){const r=!e.evidenceTruncated;return e.evidenceTruncated=!0,r}const{loopId:i,...d}=t;return e.evidence.push(d),!0}statuses(e=Date.now()){return[...this.loops.values()].map(t=>({...t,state:e-t.lastSeen>9e4?"unknown":t.state})).sort((t,i)=>i.lastSeen-t.lastSeen)}list(e){return[...this.incidents.values()].filter(t=>!e||t.flowId===e||t.evidence.some(i=>i.flowId===e)).sort((t,i)=>i.startAt-t.startAt)}}let M=l(()=>[],"readIncidents");export function setFlowLoopIncidents(n){M=n}u(setFlowLoopIncidents,"setFlowLoopIncidents"),h(setFlowLoopIncidents,"setFlowLoopIncidents"),l(setFlowLoopIncidents,"setFlowLoopIncidents");export function flowLoopIncidents(n){return M(n)}u(flowLoopIncidents,"flowLoopIncidents"),h(flowLoopIncidents,"flowLoopIncidents"),l(flowLoopIncidents,"flowLoopIncidents");
1
+ "use strict";var M=Object.defineProperty;var u=(n,e)=>M(n,"name",{value:e,configurable:!0});var k=Object.defineProperty,l=u((n,e)=>k(n,"name",{value:e,configurable:!0}),"u");import{LoopSampleRing as S,parseLoopSamples as L}from"./event-loop-history.js";const v=l(n=>n&&typeof n=="object"&&!Array.isArray(n)?n:{},"object"),o=l(n=>typeof n=="number"&&Number.isFinite(n)&&n>=0?n:void 0,"number"),s=l((n,e=250)=>typeof n=="string"&&n?n.slice(0,e):void 0,"text"),T=40;export function eventLoopIdentity(n){const e=v(n),t=s(e.id),i=s(e.project);if(!(!t||!i||e.runtime!=="node"&&e.runtime!=="browser"))return{id:t,project:i,runtime:e.runtime,...o(e.pid)!==void 0?{pid:o(e.pid)}:{},...o(e.threadId)!==void 0?{threadId:o(e.threadId)}:{},...s(e.tabId)?{tabId:s(e.tabId)}:{},...s(e.loadId)?{loadId:s(e.loadId)}:{}}}u(eventLoopIdentity,"eventLoopIdentity"),l(eventLoopIdentity,"eventLoopIdentity");export function eventLoopIncident(n){const e=v(n.raw);if(e.kind!=="event-loop-stall")return;const t=eventLoopIdentity(e.loop),i=o(e.startedAt),d=o(e.durationMs),r=e.mechanism;if(!t||i===void 0||d===void 0||!["callback","heartbeat","long-animation-frame","longtask"].includes(String(r)))return;const h=e.state==="unresponsive"?"unresponsive":e.state==="unknown"?"unknown":"recovered",p=[];for(const g of Array.isArray(e.scripts)?e.scripts.slice(0,8):[]){const c=v(g),f=s(c.url,512);f&&p.push({url:f,durationMs:o(c.durationMs)??0,startAt:o(c.startAt)??i,...s(c.functionName)?{functionName:s(c.functionName)}:{},...s(c.invoker)?{invoker:s(c.invoker)}:{}})}const m=r==="callback"?s(n.context?.flowId):void 0;return{id:s(e.incidentId)??n.id,loop:t,startAt:i,durationMs:d,observedAt:n.timestamp,...h==="recovered"?{endAt:i+d}:{},state:h,mechanism:r,severity:d>=1e3?"error":"warning",...m?{flowId:m}:{},...s(n.context?.requestId)?{requestId:s(n.context?.requestId)}:{},...s(e.callbackType)?{callbackType:s(e.callbackType)}:{},scripts:p,evidence:[],evidenceTruncated:e.scriptsTruncated===!0||(o(e.droppedIncidents)??0)>0||(o(e.floodSuppressed)??0)>0,explanation:r==="callback"?"Synchronous callback wall time, including any GC or process descheduling. Execution context identifies the flow; overlapping operations are not proven causes.":r==="heartbeat"?"The loop missed its heartbeat. The observer cannot identify executing code; overlapping work may have been delayed.":"Browser-measured main-thread work. Script timings identify contributing scripts where supported; overlapping flows are associated by time only."}}u(eventLoopIncident,"eventLoopIncident"),l(eventLoopIncident,"eventLoopIncident");export class EventLoopIndex{static{u(this,"EventLoopIndex")}static{l(this,"EventLoopIndex")}constructor(e=()=>{},t=()=>{}){this.onChange=e,this.onSamples=t,this.incidents=new Map,this.loops=new Map,this.recent=[],this.history=new S}ingest(e){const t=v(e.raw),i=s(t.kind)??e.source,d=eventLoopIdentity(t.loop);if(d){const a=this.loops.get(d.id);if(!a||e.timestamp>=a.lastSeen)for(this.loops.set(d.id,{loop:d,lastSeen:e.timestamp,state:t.state==="unresponsive"?"unresponsive":t.state==="unknown"?"unknown":"observed",coverage:s(t.coverage,500)??a?.coverage??(d.runtime==="node"?"Instrumented Node thread":"Browser main thread; supported PerformanceObserver entries"),...a?{meanMs:a.meanMs,maxMs:a.maxMs,p99Ms:a.p99Ms,utilization:a.utilization}:{},...o(t.lagMs)!==void 0?{meanMs:o(t.lagMs),maxMs:o(t.maxMs),p99Ms:o(t.p99Ms),utilization:o(t.utilization)}:{}});this.loops.size>200;)this.loops.delete(this.loops.keys().next().value);if(i==="event-loop-lag"){const I=L(t.samples);I.length&&(this.history.add(d,I),this.onSamples(d,I))}}const r=eventLoopIncident(e);if(r){const a=this.incidents.get(r.id);if(a&&a.observedAt>r.observedAt)return;a&&(r.evidence=a.evidence.slice(),r.evidenceTruncated||=a.evidenceTruncated);for(const I of this.recent)this.attach(r,I);for(this.incidents.set(r.id,r);this.incidents.size>200;)this.incidents.delete(this.incidents.keys().next().value);this.onChange(r);return}if(i.startsWith("event-loop-"))return;const h=s(t.loopId);if(!h)return;const p=v(t.span),m=v(t.request),g=v(t.render),c=o(t.durationMs)??o(p.durationMs)??o(m.durationMs)??o(g.actualDurationMs)??0,f=o(t.startedAt)??o(p.startTime)??o(m.startedAt)??e.timestamp-c,w=o(p.syncDurationMs),b=o(p.syncStartedAt),y=w!==void 0&&w>=50&&b!==void 0,x={loopId:h,eventId:e.id,title:(e.title??i).slice(0,250),kind:i,startAt:y?b:f,endAt:y?b+w:f+c,...e.context?.flowId?{flowId:e.context.flowId}:{},...e.context?.requestId?{requestId:e.context.requestId}:{},relation:y?"executing":"overlap"};this.recent.push(x),this.recent.length>2e3&&this.recent.splice(0,this.recent.length-2e3);for(const a of this.incidents.values())this.attach(a,x)&&this.onChange(a)}attach(e,t){if(t.loopId!==e.loop.id||t.endAt<e.startAt||t.startAt>(e.endAt??e.observedAt)||e.evidence.some(r=>r.eventId===t.eventId))return!1;if(e.evidence.length>=T){const r=!e.evidenceTruncated;return e.evidenceTruncated=!0,r}const{loopId:i,...d}=t;return e.evidence.push(d),!0}statuses(e=Date.now()){return[...this.loops.values()].map(t=>({...t,state:e-t.lastSeen>9e4?"unknown":t.state})).sort((t,i)=>i.lastSeen-t.lastSeen)}list(e){return[...this.incidents.values()].filter(t=>!e||t.flowId===e||t.evidence.some(i=>i.flowId===e)).sort((t,i)=>i.startAt-t.startAt)}}let A=l(()=>[],"readIncidents");export function setFlowLoopIncidents(n){A=n}u(setFlowLoopIncidents,"setFlowLoopIncidents"),l(setFlowLoopIncidents,"setFlowLoopIncidents");export function flowLoopIncidents(n){return A(n)}u(flowLoopIncidents,"flowLoopIncidents"),l(flowLoopIncidents,"flowLoopIncidents");
@@ -1 +1 @@
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};
1
+ "use strict";var u=Object.defineProperty;var o=(r,t)=>u(r,"name",{value:t,configurable:!0});var l=Object.defineProperty,i=o((r,t)=>l(r,"name",{value:t,configurable:!0}),"a");import{MAX_MESSAGE_CHARS as S,MAX_TITLE_CHARS as T,redactDeep as y,redactSqlParams as _,redactText as p,safeText as E,safeTitle as g}from"./redact.js";export const BUS_REDACT_MAX_DEPTH=12;export function createEventRedactor(r={}){const t=r.maxDepth??BUS_REDACT_MAX_DEPTH;let s=0,a=0;return{redact(e){s+=1;const c=e.title===void 0?void 0:g(p(e.title)),n=e.message===void 0?void 0:E(p(e.message),S),d=e.raw===void 0?void 0:v(y(e.raw,0,t)),A=c!==e.title,f=n!==e.message,m=d!==e.raw;return!A&&!f&&!m?e:(a+=1,{...e,...c!==void 0?{title:c}:{},...n!==void 0?{message:n}:{},...d!==void 0?{raw:d}:{}})},stats:i(()=>({inspected:s,redacted:a}),"stats"),reset:i(()=>{s=0,a=0},"reset")}}o(createEventRedactor,"createEventRedactor"),i(createEventRedactor,"createEventRedactor");function v(r){if(!r||typeof r!="object"||Array.isArray(r))return r;const t=r,s=t.query,a=t.params;if(typeof s!="string"||!Array.isArray(a))return r;const e=_(s,a);return e===a?r:{...t,params:e}}o(v,"T"),i(v,"redactSqlShape");export{T as MAX_TITLE_CHARS};
@@ -1 +1 @@
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");
1
+ "use strict";var a=Object.defineProperty;var r=(n,e)=>a(n,"name",{value:e,configurable:!0});var f=Object.defineProperty,i=r((n,e)=>f(n,"name",{value:e,configurable:!0}),"e");const l=2166136261,u=16777619;function o(n){let e=2166136261;for(let t=0;t<n.length;t++)e^=n.charCodeAt(t),e=Math.imul(e,16777619);return(e>>>0).toString(16).padStart(8,"0")}r(o,"i"),i(o,"fnv1a32");export function fingerprint(n){const e=[n.kind,n.identity,n.file??"",n.detail??""];return`${n.kind}:${o(e.join("|"))}`}r(fingerprint,"fingerprint"),i(fingerprint,"fingerprint");
@@ -1 +1 @@
1
- "use strict";var F=Object.defineProperty;var c=(e,t)=>F(e,"name",{value:t,configurable:!0});var T=Object.defineProperty,d=c((e,t)=>T(e,"name",{value:t,configurable:!0}),"c"),S=Object.defineProperty,s=d((e,t)=>S(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 o=f.get(e);return o||(o=new RegExp(`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".")}$`),f.size>500&&f.clear(),f.set(e,o)),o.test(t)}c(globMatch,"globMatch"),d(globMatch,"globMatch"),s(globMatch,"globMatch");const z=s(e=>/^[A-Z]+ /.test(e),"hasMethod");function v(e,t){return t.some(o=>o.route?z(e)?globMatch(e,`${o.method??"GET"} ${o.route}`):globMatch(e,o.route):!1)}c(v,"w"),d(v,"$"),s(v,"routeMatches");function m(e,t){return!([e.flowId,e.originType,e.origin,e.route,e.project].filter(o=>o!==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(o=>o.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"),l=s(e=>typeof e=="string"&&e!==""?e:void 0,"str"),y=s(e=>b(e.raw)?l(e.raw.kind)??"":"","kindOf"),O=s((e,t)=>{const o=Number(e.timestamp)||0,r=Number(t.timestamp)||0;return o<r||o===r&&e.id<t.id},"earlier");function h(e){let t,o;for(const a of e)y(a)==="flow-origin"&&(!t||O(a,t))&&(t=a),l(a.context?.originType)&&(!o||O(a,o))&&(o=a);const r=t??o;if(!r)return{};const n=b(r.raw)?r.raw:{},i=l(r.context?.originType)??(t?l(r.title):void 0),u=l(n.originNodeId)??l(r.context?.originNodeId);return{...i?{type:i}:{},...u?{nodeId:u}:{}}}c(h,"$"),d(h,"O"),s(h,"originOf");const B=/^(verify|e2e|test|smoke|load)[-_:]/i,A=s((e,t)=>B.test(e)||t!==void 0&&/^(ui:)?(tools|scripts?|e2e)\//.test(t),"isTestFlow"),q={"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"},C=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,"I"),d(w,"q"),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,o,r){const n=t.nodeId,i=n?/^(page|route|ambient):(.*)$/.exec(n):null;if(i)return`${i[1]}:${templatePath(i[2])}`;if(t.type&&q[t.type]==="user-action"&&n)return w(n);if(e==="test")return scriptFamily(o.flowId);const u=o.segments.find(p=>p.kind==="request"&&p.route);if(u?.route)return`${u.method??"GET"} ${templatePath(u.route)}`;const a=r.find(p=>y(p)==="ai-call");return a&&b(a.raw)?`ai \xB7 ${l(a.raw.model)??l(a.raw.provider)??"call"}`:n?templatePath(n):void 0}c(k,"j"),d(k,"R"),s(k,"subjectOf");const R=10,_=1e3,N=3,P=500,G=1e3;function $(e,t){const o=new Set,r=t.segments.filter(i=>i.kind==="request");t.segments.some(i=>i.counts.errors>0)&&o.add("has-error"),r.some(i=>i.durationMs>=_)&&o.add("slow"),r.length>=R&&o.add("fan-out"),new Set(t.segments.flatMap(i=>i.projects)).size>=3&&o.add("multi-service"),e.some(i=>y(i)==="queue-enqueued")&&o.add("queue"),e.some(i=>y(i)==="ai-call"||i.source==="ai")&&o.add("ai"),t.stats.bookkeeping>=P&&t.stats.bookkeeping*2>=t.stats.events&&o.add("storm"),t.stats.events>=G&&o.add("large");const n=new Map;for(const i of r)(!i.part||i.part.index===1)&&n.set(i.label,(n.get(i.label)??0)+1);return[...n.values()].some(i=>i>=N)&&o.add("repeated-requests"),[...o].sort()}c($,"q"),d($,"G"),s($,"tagsOf");export function classifyFlow(e,t,o=[]){const r=h(e),n={flowId:t.flowId,origin:r,segments:t.segments},i=$(e,t),u=s((g,M,x)=>{const j=k(g,r,t,e);return{category:g,decidedBy:M,...x!==void 0?{ruleIndex:x}:{},tags:i,origin:r,...j?{subject:j}:{}}},"done"),a=o.findIndex(g=>g.category&&m(g,n));if(a!==-1)return u(o[a].category,"rule",a);if(A(t.flowId,r.nodeId))return u("test","test");const p=r.type?q[r.type]:void 0;if(p)return u(p,"origin");if(i.includes("ai"))return u("ai","shape");const I=t.segments.filter(g=>g.kind==="request");return I.length>0?u(I.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,o=[]){const r=o.find(n=>n.category&&(n.route!==void 0||n.project!==void 0)&&n.flowId===void 0&&n.origin===void 0&&n.originType===void 0&&m(n,{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"&&C.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 o=new Map;for(const n of t.items){const i=o.get(n.subject);i?i.push(n):o.set(n.subject,[n])}const r=[...o.entries()].sort((n,i)=>(n[0]===void 0?1:0)-(i[0]===void 0?1:0)||i[1].length-n[1].length||String(n[0]).localeCompare(String(i[0]))).map(([n,i])=>({subject:n,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 n=t.get(r.category);n?n.push(r):t.set(r.category,[r])}const o=s(r=>{const n=CATEGORY_ORDER.indexOf(r);return n===-1?CATEGORY_ORDER.length:n},"rank");return[...t.entries()].sort((r,n)=>o(r[0])-o(n[0])||(r[0]<n[0]?-1:r[0]>n[0]?1:0)).map(([r,n])=>({category:r,count:n.length,items:n}))}c(groupByCategory,"groupByCategory"),d(groupByCategory,"groupByCategory"),s(groupByCategory,"groupByCategory");
1
+ "use strict";var M=Object.defineProperty;var c=(e,t)=>M(e,"name",{value:t,configurable:!0});var T=Object.defineProperty,s=c((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 p=new Map;export function globMatch(e,t){let o=p.get(e);return o||(o=new RegExp(`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".")}$`),p.size>500&&p.clear(),p.set(e,o)),o.test(t)}c(globMatch,"globMatch"),s(globMatch,"globMatch");const F=s(e=>/^[A-Z]+ /.test(e),"hasMethod");function w(e,t){return t.some(o=>o.route?F(e)?globMatch(e,`${o.method??"GET"} ${o.route}`):globMatch(e,o.route):!1)}c(w,"$"),s(w,"routeMatches");function m(e,t){return!([e.flowId,e.originType,e.origin,e.route,e.project].filter(o=>o!==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&&!w(e.route,t.segments)||e.project!==void 0&&!t.segments.some(o=>o.projects.some(n=>globMatch(e.project,n))))}c(m,"b"),s(m,"ruleMatches");const y=s(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),g=s(e=>typeof e=="string"&&e!==""?e:void 0,"str"),f=s(e=>y(e.raw)?g(e.raw.kind)??"":"","kindOf"),k=s((e,t)=>{const o=Number(e.timestamp)||0,n=Number(t.timestamp)||0;return o<n||o===n&&e.id<t.id},"earlier");function $(e){let t,o;for(const a of e)f(a)==="flow-origin"&&(!t||k(a,t))&&(t=a),g(a.context?.originType)&&(!o||k(a,o))&&(o=a);const n=t??o;if(!n)return{};const r=y(n.raw)?n.raw:{},i=g(n.context?.originType)??(t?g(n.title):void 0),u=g(r.originNodeId)??g(n.context?.originNodeId);return{...i?{type:i}:{},...u?{nodeId:u}:{}}}c($,"O"),s($,"originOf");const S=/^(verify|e2e|test|smoke|load)[-_:]/i,z=s((e,t)=>S.test(e)||t!==void 0&&/^(ui:)?(tools|scripts?|e2e)\//.test(t),"isTestFlow"),x={"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"),s(templatePath,"templatePath");function I(e){const t=/^ui:(?:.*\/)?([^/:]+?)(?:\.[a-z]+)?:\d+:([A-Za-z]+)$/.exec(e);return t?`${t[1]} \xB7 ${t[2]}`:e}c(I,"q"),s(I,"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"),s(scriptFamily,"scriptFamily");function j(e,t,o,n){const r=t.nodeId,i=r?/^(page|route|ambient):(.*)$/.exec(r):null;if(i)return`${i[1]}:${templatePath(i[2])}`;if(t.type&&x[t.type]==="user-action"&&r)return I(r);if(e==="test")return scriptFamily(o.flowId);const u=o.segments.find(l=>l.kind==="request"&&l.route);if(u?.route)return`${u.method??"GET"} ${templatePath(u.route)}`;const a=n.find(l=>f(l)==="ai-call");return a&&y(a.raw)?`ai \xB7 ${g(a.raw.model)??g(a.raw.provider)??"call"}`:r?templatePath(r):void 0}c(j,"R"),s(j,"subjectOf");const _=10,B=1e3,N=3,R=500,C=1e3;function q(e,t){const o=new Set,n=t.segments.filter(i=>i.kind==="request");t.segments.some(i=>i.counts.errors>0)&&o.add("has-error"),n.some(i=>i.durationMs>=B)&&o.add("slow"),n.length>=_&&o.add("fan-out"),new Set(t.segments.flatMap(i=>i.projects)).size>=3&&o.add("multi-service"),e.some(i=>f(i)==="queue-enqueued")&&o.add("queue"),e.some(i=>f(i)==="ai-call"||i.source==="ai")&&o.add("ai"),t.stats.bookkeeping>=R&&t.stats.bookkeeping*2>=t.stats.events&&o.add("storm"),t.stats.events>=C&&o.add("large");const r=new Map;for(const i of n)(!i.part||i.part.index===1)&&r.set(i.label,(r.get(i.label)??0)+1);return[...r.values()].some(i=>i>=N)&&o.add("repeated-requests"),[...o].sort()}c(q,"G"),s(q,"tagsOf");export function classifyFlow(e,t,o=[]){const n=$(e),r={flowId:t.flowId,origin:n,segments:t.segments},i=q(e,t),u=s((d,O,b)=>{const h=j(d,n,t,e);return{category:d,decidedBy:O,...b!==void 0?{ruleIndex:b}:{},tags:i,origin:n,...h?{subject:h}:{}}},"done"),a=o.findIndex(d=>d.category&&m(d,r));if(a!==-1)return u(o[a].category,"rule",a);if(z(t.flowId,n.nodeId))return u("test","test");const l=n.type?x[n.type]:void 0;if(l)return u(l,"origin");if(i.includes("ai"))return u("ai","shape");const v=t.segments.filter(d=>d.kind==="request");return v.length>0?u(v.every(d=>d.requestId?.startsWith("job:"))?"background":"api","shape"):t.segments.length>0&&t.segments.every(d=>d.kind==="ambient")?u("system","shape"):u("other","shape")}c(classifyFlow,"classifyFlow"),s(classifyFlow,"classifyFlow");export function categoryOfSegment(e,t,o=[]){const n=o.find(r=>r.category&&(r.route!==void 0||r.project!==void 0)&&r.flowId===void 0&&r.origin===void 0&&r.originType===void 0&&m(r,{flowId:e.flowId,origin:t.origin,segments:[e]}));return n?n.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"),s(categoryOfSegment,"categoryOfSegment");export function groupFlows(e){return groupByCategory(e).map(t=>{const o=new Map;for(const r of t.items){const i=o.get(r.subject);i?i.push(r):o.set(r.subject,[r])}const n=[...o.entries()].sort((r,i)=>(r[0]===void 0?1:0)-(i[0]===void 0?1:0)||i[1].length-r[1].length||String(r[0]).localeCompare(String(i[0]))).map(([r,i])=>({subject:r,count:i.length,items:i}));return{...t,subjects:n}})}c(groupFlows,"groupFlows"),s(groupFlows,"groupFlows");export function groupByCategory(e){const t=new Map;for(const n of e){const r=t.get(n.category);r?r.push(n):t.set(n.category,[n])}const o=s(n=>{const r=CATEGORY_ORDER.indexOf(n);return r===-1?CATEGORY_ORDER.length:r},"rank");return[...t.entries()].sort((n,r)=>o(n[0])-o(r[0])||(n[0]<r[0]?-1:n[0]>r[0]?1:0)).map(([n,r])=>({category:n,count:r.length,items:r}))}c(groupByCategory,"groupByCategory"),s(groupByCategory,"groupByCategory");
@@ -1 +1 @@
1
- "use strict";var Z=Object.defineProperty;var b=(e,t)=>Z(e,"name",{value:t,configurable:!0});var ee=Object.defineProperty,I=b((e,t)=>ee(e,"name",{value:t,configurable:!0}),"b"),te=Object.defineProperty,m=I((e,t)=>te(e,"name",{value:t,configurable:!0}),"h");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 ne=new Set(["react","valtio","client-runtime","chrome","visual"]),S=m(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),v=m(e=>typeof e=="string"&&e!==""?e:void 0,"str"),$=m(e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,"num"),H=new WeakMap;function E(e){let t=H.get(e);return t||(t=W(e),H.set(e,t)),t}b(E,"F"),I(E,"U"),m(E,"itemOf");function W(e){const t=S(e.raw)?e.raw:{},s=S(t.request)?t.request:{},o=S(t.span)?t.span:{},i=e.context??{},n=v(t.kind)??"",l=n===SQL_ACCOUNT_KIND,g=(l?$(t.lastEndedAt):void 0)??$(e.timestamp)??0,q=$(s.startedAt)??$(o.startTime)??$(t.startedAt)??(l?$(t.firstStartedAt):void 0),M=$(s.endedAt)??$(o.endTime)??(q!==void 0&&$(t.durationMs)!==void 0?q+t.durationMs:void 0),w=Math.min(g,q??g),j=Math.max(g,M??g),a=S(t.render)?t.render:{},u=S(t.update)?t.update:{},y=n==="render"?v(a.componentName):n==="state-update"?v(u.path)?.split(".").slice(0,2).join("."):void 0,d=v(t.queue),c=v(t.jobId),f=String(e.source),r=v(t.project)??v(i.projectName),p=n==="fetch-start"||n==="fetch-done"||n==="gateway-request";return{event:e,id:e.id,ts:g,from:w,to:j,kind:n,source:f,requestId:v(i.requestId),parentRequestId:v(i.parentRequestId),queueKey:d&&c?`${d}#${c}`:void 0,browser:ne.has(f)||f==="memory"&&r===void 0,bookkeeping:FLOW_BOOKKEEPING_KINDS.has(n),project:r,subject:y,route:p?F(v(t.url)):n==="server-request"?v(s.route):void 0,method:p?v(t.method):n==="server-request"?v(s.method):void 0}}b(W,"G"),I(W,"L"),m(W,"readItem");function F(e){if(!e)return;const t=e.search(/[?#]/),s=t===-1?e:e.slice(0,t),o=/^[a-z][a-z0-9+.-]*:\/\/[^/]*(\/.*)?$/i.exec(s);return o?o[1]??"/":s}b(F,"T"),I(F,"B"),m(F,"pathOnly");const se=m(e=>e.split(".")[0],"rootOf"),J=m((e,t)=>e.reduce((s,o)=>Math.min(s,t(o)),1/0),"minOf"),V=m((e,t)=>e.reduce((s,o)=>Math.max(s,t(o)),-1/0),"maxOf"),T=m((e,t)=>e.ts-t.ts||(e.id<t.id?-1:e.id>t.id?1:0),"compare"),G=m(e=>e.requestId&&!e.requestId.startsWith("job:")?se(e.requestId):void 0,"directFamilyOf");function B(e){if(e.requestId?.startsWith("job:"))return e.requestId.slice(4);if(e.queueKey&&e.kind!=="queue-enqueued"&&!e.requestId)return e.queueKey}b(B,"U"),I(B,"D"),m(B,"jobKeyOf");function U(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,l)=>n.from-l.from||T(n,l));if(s.length<2)return[e];const o=[];for(const n of s){const l=o[o.length-1];l&&n.from<=l.to+t?l.to=Math.max(l.to,n.to):o.push({from:n.from,to:n.to})}if(o.length<2)return[e];const i=o.map(()=>[]);for(const n of e)i[t>=0?D(o,n.ts,t):_(o,n.ts,t)].push(n);return i.filter(n=>n.length>0)}b(U,"D"),I(U,"z"),m(U,"occurrencesOf");function _(e,t,s){const o=e.findIndex(n=>t>=n.from-s&&t<=n.to+s);if(o!==-1)return o;let i=0;for(let n=0;n<e.length;n+=1)e[n].from<=t&&(i=n);return i}b(_,"R"),I(_,"P"),m(_,"spanScan");function D(e,t,s){let o=0,i=e.length;for(;o<i;){const n=o+i>>1;e[n].to+s<t?o=n+1:i=n}if(o<e.length&&t>=e[o].from-s)return o;for(o=0,i=e.length;o<i;){const n=o+i>>1;e[n].from<=t?o=n+1:i=n}return Math.max(0,o-1)}b(D,"z"),I(D,"Q"),m(D,"spanAt");const X={debug:0,info:1,warning:2,error:3,fatal:4};function A(e,t){const s=[];let o=[];for(const i of e){const n=o[o.length-1];n&&i.ts-n.ts>=t&&(s.push(o),o=[]),o.push(i)}return o.length&&s.push(o),s}b(A,"A"),I(A,"R"),m(A,"runs");export function segmentFlow(e,t={}){const s={...DEFAULT_SEGMENT_OPTIONS};for(const[r,p]of Object.entries(t))typeof p=="number"&&Number.isFinite(p)&&(s[r]=p);const o=new Set,i=[];for(const r of e)o.has(r.id)||(o.add(r.id),i.push(E(r)));i.sort(T);const n=v(i[0]?.event.context?.flowId)??v(i[0]?.event.raw?.flowId)??"",l=new Map;for(const r of i)r.kind==="queue-enqueued"&&r.queueKey&&r.requestId&&!r.requestId.startsWith("job:")&&!l.has(r.queueKey)&&l.set(r.queueKey,r);const g=new Map,q=new Map,M=[];for(const r of i){const p=B(r),h=G(r);if(p!==void 0){const k=q.get(p);k?k.push(r):q.set(p,[r])}else if(h!==void 0){const k=g.get(h);k?k.push(r):g.set(h,[r])}else M.push(r)}const w=[],j=new Map;for(const[r,p]of g)U(p,s.occurrenceSlackMs).forEach((h,k)=>{const O={id:`${n}~r:${r}${k===0?"":`@${k+1}`}`,kind:"request",items:h,requestId:r};if(w.push(O),l.size)for(const x of h)x.kind==="queue-enqueued"&&j.set(x,O)});for(const[r,p]of q){const h=l.get(r),k=h?j.get(h):void 0;k?k.items.push(...p):w.push({id:`${n}~r:job:${r}`,kind:"request",items:p,requestId:`job:${r}`})}const a=i.filter(r=>r.kind==="fetch-done"&&G(r)!==void 0),u=new Map;for(const r of w)r.requestId&&u.set(r.requestId,[...u.get(r.requestId)??[],r]);const y=m((r,p)=>{const h=u.get(r);if(h)return h.find(k=>k.items.some(O=>O.kind==="fetch-done"&&O.ts===p))??h[h.length-1]},"owningUnit"),d=M.filter(r=>r.browser);for(const r of A(d,s.burstGapMs)){const p=r[0].ts,h=a.filter(x=>x.ts<=p&&p-x.ts<=s.attachWindowMs),k=[...new Set(h.map(x=>G(x)))];if(k.length===1){const x=y(k[0],h[h.length-1].ts);if(x){x.items.push(...r);continue}}const O=r.some(x=>x.kind==="flow-origin");w.push({id:`${n}~${O?"o":"u"}:${r[0].id}`,kind:O?"origin":"ui",items:r,...k.length>1?{after:k.sort()}:{}})}for(const r of A(M.filter(p=>!p.browser),s.phaseGapMs))w.push({id:`${n}~a:${r[0].id}`,kind:"ambient",items:r});const c=P(n,i.length,w,s),f=K(i);return f?{...c,sql:f}:c}b(segmentFlow,"segmentFlow"),I(segmentFlow,"segmentFlow"),m(segmentFlow,"segmentFlow");function P(e,t,s,o){for(const a of s)a.items.sort(T);const i=s.map(a=>({unit:a,from:J(a.items,u=>u.from),to:V(a.items,u=>u.to)}));i.sort((a,u)=>a.from-u.from||(a.unit.id<u.unit.id?-1:1));const n=new Map;let l=0,g=-1/0;for(const a of i)(l===0||a.from-g>=o.phaseGapMs)&&(l+=1),g=Math.max(g,a.to),n.set(a.unit,l);const q=[];for(const a of i){const u=R(a.unit.items,o.maxSegmentEvents),y=a.unit.kind==="request"?K(a.unit.items):void 0;u.forEach((d,c)=>{const f=z(e,a.unit,d,n.get(a.unit),u.length>1?{index:c+1,total:u.length}:void 0);q.push(y&&c===0?{...f,sql:y}:f)})}const M={};for(const a of q)for(const u of a.eventIds)M[u]=a.id;const w=[];for(const a of q){let u=w[a.phase-1];u||(u={index:a.phase,start:a.start,end:a.end,segmentIds:[]},w[a.phase-1]=u),u.start=Math.min(u.start,a.start),u.end=Math.max(u.end,a.end),u.segmentIds.push(a.id)}const j=q.reduce((a,u)=>a+u.counts.signal,0);return{flowId:e,segments:q,phases:w.filter(Boolean),assignment:M,stats:{events:t,signal:j,bookkeeping:t-j,segments:q.length,phases:w.filter(Boolean).length,largestSegment:q.reduce((a,u)=>Math.max(a,u.counts.total),0)}}}b(P,"L"),I(P,"V"),m(P,"assemble");function R(e,t){if(e.filter(n=>!n.bookkeeping).length<=t)return[e];const s=[];let o=[],i=0;for(const n of e)!n.bookkeeping&&i===t&&(s.push(o),o=[],i=0),o.push(n),n.bookkeeping||(i+=1);return o.length&&s.push(o),s}b(R,"P"),I(R,"X"),m(R,"chunk");function z(e,t,s,o,i){const n={total:s.length,signal:0,bookkeeping:0,errors:0,warnings:0},l=new Set;let g="debug";for(const u of s){u.bookkeeping?n.bookkeeping+=1:n.signal+=1;const y=String(u.event.severity);y==="error"||y==="fatal"?n.errors+=1:y==="warning"&&(n.warnings+=1),(X[y]??1)>(X[g]??0)&&(g=y),u.project&&l.add(u.project)}const q=t.kind==="ui"||t.kind==="origin"?C(s):[],M=J(s,u=>u.from),w=V(s,u=>u.to),j=L(t.items),a=t.id;return{id:i&&i.index>1?`${a}#${i.index}`:a,flowId:e,kind:t.kind,label:Q(t,s,j,i,q),phase:o,start:M,end:w,durationMs:w-M,eventIds:s.map(u=>u.id),counts:n,projects:[...l].sort(),...j.route?{route:j.route}:{},...j.method?{method:j.method}:{},...t.requestId?{requestId:t.requestId}:{},...t.after?{after:t.after}:{},...q.length?{hot:q}:{},...i?{part:i}:{},worstSeverity:g}}b(z,"Q"),I(z,"Y"),m(z,"toSegment");function L(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()}:{}}}b(L,"H"),I(L,"H"),m(L,"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,o)=>o[1]-s[1]||(s[0]<o[0]?-1:1)).slice(0,3).map(([s,o])=>o>1?`${s} \xD7${o}`:s)}b(C,"J"),I(C,"J"),m(C,"hotOf");function Q(e,t,s,o,i){const n=o?` (part ${o.index}/${o.total})`:"";if(e.kind==="request"){if(s.route)return`${s.method?`${s.method} `:""}${s.route}${n}`;const l=t.find(g=>g.queueKey);return l?`job ${l.queueKey}${n}`:`request ${e.requestId??""}${n}`}return e.kind==="origin"?`${t.find(l=>l.kind==="flow-origin")?.event.title||"start"}${i.length?` \xB7 ${i.join(", ")}`:""}${n}`:e.kind==="ui"?`UI update${i.length?` \xB7 ${i.join(", ")}`:""}${n}`:`background${n}`}b(Q,"V"),I(Q,"Z"),m(Q,"labelOf");const Y=50;export function sqlAccountingOf(e){return N(e,!1)}b(sqlAccountingOf,"sqlAccountingOf"),I(sqlAccountingOf,"sqlAccountingOf"),m(sqlAccountingOf,"sqlAccountingOf");function K(e){return N(e.map(t=>t.event),!0)}b(K,"N"),I(K,"T"),m(K,"accountSqlOfItems");function N(e,t){const s=new Map,o=new Map,i=t?void 0:new Set;for(const d of e){if(i){if(i.has(d.id))continue;i.add(d.id)}const c=S(d.raw)?d.raw:{},f=v(c.kind),r=v(d.context?.requestId);if(!r)continue;const p=v(c.project)??v(d.context?.projectName);if(f==="db-query"&&d.source==="db"){const h=o.get(r)??{count:0,workMs:0,...p?{project:p}:{}};h.count+=1,h.workMs+=$(c.durationMs)??0,o.set(r,h)}else if(f===SQL_ACCOUNT_KIND){const h=v(c.accountId)??d.id,k=$(c.seq)??0,O=s.get(h);if(O&&O.seq>=k)continue;s.set(h,{requestId:r,...p?{project:p}:{},seq:k,basis:c.basis==="end"?"end":"settled",statements:$(c.statements)??0,failed:$(c.failed)??0,workMs:$(c.workMs)??0,recorded:$(c.recorded)??0,suppressed:$(c.suppressed)??0,unwritten:$(c.unwritten)??0})}}const n=new Map;for(const d of s.values()){const c=n.get(d.requestId);if(!c){n.set(d.requestId,{...d});continue}d.basis==="settled"&&(c.basis="settled"),c.statements+=d.statements,c.failed+=d.failed,c.workMs+=d.workMs,c.recorded+=d.recorded,c.suppressed+=d.suppressed,c.unwritten+=d.unwritten}const l=[...new Set([...o.keys(),...n.keys()])].sort();if(l.length===0)return;const g={statements:0,failed:0,workMs:0,recorded:0,suppressed:0,unwritten:0},q={statements:0,workMs:0},M=[];for(const d of l){const c=o.get(d),f=n.get(d),r=c?.count??0;q.statements+=r,q.workMs+=c?.workMs??0;const p=!f||r>f.statements?"unverified":r===f.statements?"complete":"incomplete";f&&p!=="unverified"&&(g.statements+=f.statements,g.failed+=f.failed,g.workMs+=f.workMs,g.recorded+=f.recorded,g.suppressed+=f.suppressed,g.unwritten+=f.unwritten);const h=c?.project??f?.project;M.push({requestId:d,...h?{project:h}:{},status:p,observed:r,observedWorkMs:c?.workMs??0,...f?{basis:f.basis,statements:f.statements,failed:f.failed,workMs:f.workMs,recorded:f.recorded,suppressed:f.suppressed,unwritten:f.unwritten}:{}})}const w=m(d=>M.filter(c=>c.status===d).length,"tally"),j=w("unverified"),a=w("incomplete"),u=m(d=>(d.statements??0)-d.observed,"missing"),y=M.filter(d=>d.status!=="complete").sort((d,c)=>(d.status==="incomplete"?0:1)-(c.status==="incomplete"?0:1)||u(c)-u(d)||(d.requestId<c.requestId?-1:d.requestId>c.requestId?1:0));return{status:j>0?"unverified":a>0?"incomplete":"complete",requests:M.length,complete:w("complete"),incomplete:a,unverified:j,settled:M.filter(d=>d.status!=="unverified"&&d.basis==="settled").length,observed:q,accounted:g,gaps:y.slice(0,Y),gapsTruncated:y.length>Y}}b(N,"E"),I(N,"W"),m(N,"accountSql");
1
+ "use strict";var Y=Object.defineProperty;var b=(e,t)=>Y(e,"name",{value:t,configurable:!0});var Z=Object.defineProperty,m=b((e,t)=>Z(e,"name",{value:t,configurable:!0}),"h");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 ee=new Set(["react","valtio","client-runtime","chrome","visual"]),S=m(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),v=m(e=>typeof e=="string"&&e!==""?e:void 0,"str"),M=m(e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,"num"),W=new WeakMap;function F(e){let t=W.get(e);return t||(t=G(e),W.set(e,t)),t}b(F,"U"),m(F,"itemOf");function G(e){const t=S(e.raw)?e.raw:{},s=S(t.request)?t.request:{},o=S(t.span)?t.span:{},i=e.context??{},n=v(t.kind)??"",p=n===SQL_ACCOUNT_KIND,g=(p?M(t.lastEndedAt):void 0)??M(e.timestamp)??0,q=M(s.startedAt)??M(o.startTime)??M(t.startedAt)??(p?M(t.firstStartedAt):void 0),I=M(s.endedAt)??M(o.endTime)??(q!==void 0&&M(t.durationMs)!==void 0?q+t.durationMs:void 0),w=Math.min(g,q??g),$=Math.max(g,I??g),a=S(t.render)?t.render:{},u=S(t.update)?t.update:{},j=n==="render"?v(a.componentName):n==="state-update"?v(u.path)?.split(".").slice(0,2).join("."):void 0,d=v(t.queue),c=v(t.jobId),f=String(e.source),r=v(t.project)??v(i.projectName),l=n==="fetch-start"||n==="fetch-done"||n==="gateway-request";return{event:e,id:e.id,ts:g,from:w,to:$,kind:n,source:f,requestId:v(i.requestId),parentRequestId:v(i.parentRequestId),queueKey:d&&c?`${d}#${c}`:void 0,browser:ee.has(f)||f==="memory"&&r===void 0,bookkeeping:FLOW_BOOKKEEPING_KINDS.has(n),project:r,subject:j,route:l?T(v(t.url)):n==="server-request"?v(s.route):void 0,method:l?v(t.method):n==="server-request"?v(s.method):void 0}}b(G,"L"),m(G,"readItem");function T(e){if(!e)return;const t=e.search(/[?#]/),s=t===-1?e:e.slice(0,t),o=/^[a-z][a-z0-9+.-]*:\/\/[^/]*(\/.*)?$/i.exec(s);return o?o[1]??"/":s}b(T,"B"),m(T,"pathOnly");const te=m(e=>e.split(".")[0],"rootOf"),_=m((e,t)=>e.reduce((s,o)=>Math.min(s,t(o)),1/0),"minOf"),B=m((e,t)=>e.reduce((s,o)=>Math.max(s,t(o)),-1/0),"maxOf"),O=m((e,t)=>e.ts-t.ts||(e.id<t.id?-1:e.id>t.id?1:0),"compare"),K=m(e=>e.requestId&&!e.requestId.startsWith("job:")?te(e.requestId):void 0,"directFamilyOf");function U(e){if(e.requestId?.startsWith("job:"))return e.requestId.slice(4);if(e.queueKey&&e.kind!=="queue-enqueued"&&!e.requestId)return e.queueKey}b(U,"D"),m(U,"jobKeyOf");function D(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,p)=>n.from-p.from||O(n,p));if(s.length<2)return[e];const o=[];for(const n of s){const p=o[o.length-1];p&&n.from<=p.to+t?p.to=Math.max(p.to,n.to):o.push({from:n.from,to:n.to})}if(o.length<2)return[e];const i=o.map(()=>[]);for(const n of e)i[t>=0?z(o,n.ts,t):R(o,n.ts,t)].push(n);return i.filter(n=>n.length>0)}b(D,"z"),m(D,"occurrencesOf");function R(e,t,s){const o=e.findIndex(n=>t>=n.from-s&&t<=n.to+s);if(o!==-1)return o;let i=0;for(let n=0;n<e.length;n+=1)e[n].from<=t&&(i=n);return i}b(R,"P"),m(R,"spanScan");function z(e,t,s){let o=0,i=e.length;for(;o<i;){const n=o+i>>1;e[n].to+s<t?o=n+1:i=n}if(o<e.length&&t>=e[o].from-s)return o;for(o=0,i=e.length;o<i;){const n=o+i>>1;e[n].from<=t?o=n+1:i=n}return Math.max(0,o-1)}b(z,"Q"),m(z,"spanAt");const C={debug:0,info:1,warning:2,error:3,fatal:4};function A(e,t){const s=[];let o=[];for(const i of e){const n=o[o.length-1];n&&i.ts-n.ts>=t&&(s.push(o),o=[]),o.push(i)}return o.length&&s.push(o),s}b(A,"R"),m(A,"runs");export function segmentFlow(e,t={}){const s={...DEFAULT_SEGMENT_OPTIONS};for(const[r,l]of Object.entries(t))typeof l=="number"&&Number.isFinite(l)&&(s[r]=l);const o=new Set,i=[];for(const r of e)o.has(r.id)||(o.add(r.id),i.push(F(r)));i.sort(O);const n=v(i[0]?.event.context?.flowId)??v(i[0]?.event.raw?.flowId)??"",p=new Map;for(const r of i)r.kind==="queue-enqueued"&&r.queueKey&&r.requestId&&!r.requestId.startsWith("job:")&&!p.has(r.queueKey)&&p.set(r.queueKey,r);const g=new Map,q=new Map,I=[];for(const r of i){const l=U(r),h=K(r);if(l!==void 0){const k=q.get(l);k?k.push(r):q.set(l,[r])}else if(h!==void 0){const k=g.get(h);k?k.push(r):g.set(h,[r])}else I.push(r)}const w=[],$=new Map;for(const[r,l]of g)D(l,s.occurrenceSlackMs).forEach((h,k)=>{const x={id:`${n}~r:${r}${k===0?"":`@${k+1}`}`,kind:"request",items:h,requestId:r};if(w.push(x),p.size)for(const y of h)y.kind==="queue-enqueued"&&$.set(y,x)});for(const[r,l]of q){const h=p.get(r),k=h?$.get(h):void 0;k?k.items.push(...l):w.push({id:`${n}~r:job:${r}`,kind:"request",items:l,requestId:`job:${r}`})}const a=i.filter(r=>r.kind==="fetch-done"&&K(r)!==void 0),u=new Map;for(const r of w)r.requestId&&u.set(r.requestId,[...u.get(r.requestId)??[],r]);const j=m((r,l)=>{const h=u.get(r);if(h)return h.find(k=>k.items.some(x=>x.kind==="fetch-done"&&x.ts===l))??h[h.length-1]},"owningUnit"),d=I.filter(r=>r.browser);for(const r of A(d,s.burstGapMs)){const l=r[0].ts,h=a.filter(y=>y.ts<=l&&l-y.ts<=s.attachWindowMs),k=[...new Set(h.map(y=>K(y)))];if(k.length===1){const y=j(k[0],h[h.length-1].ts);if(y){y.items.push(...r);continue}}const x=r.some(y=>y.kind==="flow-origin");w.push({id:`${n}~${x?"o":"u"}:${r[0].id}`,kind:x?"origin":"ui",items:r,...k.length>1?{after:k.sort()}:{}})}for(const r of A(I.filter(l=>!l.browser),s.phaseGapMs))w.push({id:`${n}~a:${r[0].id}`,kind:"ambient",items:r});const c=L(n,i.length,w,s),f=N(i);return f?{...c,sql:f}:c}b(segmentFlow,"segmentFlow"),m(segmentFlow,"segmentFlow");function L(e,t,s,o){for(const a of s)a.items.sort(O);const i=s.map(a=>({unit:a,from:_(a.items,u=>u.from),to:B(a.items,u=>u.to)}));i.sort((a,u)=>a.from-u.from||(a.unit.id<u.unit.id?-1:1));const n=new Map;let p=0,g=-1/0;for(const a of i)(p===0||a.from-g>=o.phaseGapMs)&&(p+=1),g=Math.max(g,a.to),n.set(a.unit,p);const q=[];for(const a of i){const u=P(a.unit.items,o.maxSegmentEvents),j=a.unit.kind==="request"?N(a.unit.items):void 0;u.forEach((d,c)=>{const f=Q(e,a.unit,d,n.get(a.unit),u.length>1?{index:c+1,total:u.length}:void 0);q.push(j&&c===0?{...f,sql:j}:f)})}const I={};for(const a of q)for(const u of a.eventIds)I[u]=a.id;const w=[];for(const a of q){let u=w[a.phase-1];u||(u={index:a.phase,start:a.start,end:a.end,segmentIds:[]},w[a.phase-1]=u),u.start=Math.min(u.start,a.start),u.end=Math.max(u.end,a.end),u.segmentIds.push(a.id)}const $=q.reduce((a,u)=>a+u.counts.signal,0);return{flowId:e,segments:q,phases:w.filter(Boolean),assignment:I,stats:{events:t,signal:$,bookkeeping:t-$,segments:q.length,phases:w.filter(Boolean).length,largestSegment:q.reduce((a,u)=>Math.max(a,u.counts.total),0)}}}b(L,"V"),m(L,"assemble");function P(e,t){if(e.filter(n=>!n.bookkeeping).length<=t)return[e];const s=[];let o=[],i=0;for(const n of e)!n.bookkeeping&&i===t&&(s.push(o),o=[],i=0),o.push(n),n.bookkeeping||(i+=1);return o.length&&s.push(o),s}b(P,"X"),m(P,"chunk");function Q(e,t,s,o,i){const n={total:s.length,signal:0,bookkeeping:0,errors:0,warnings:0},p=new Set;let g="debug";for(const u of s){u.bookkeeping?n.bookkeeping+=1:n.signal+=1;const j=String(u.event.severity);j==="error"||j==="fatal"?n.errors+=1:j==="warning"&&(n.warnings+=1),(C[j]??1)>(C[g]??0)&&(g=j),u.project&&p.add(u.project)}const q=t.kind==="ui"||t.kind==="origin"?J(s):[],I=_(s,u=>u.from),w=B(s,u=>u.to),$=H(t.items),a=t.id;return{id:i&&i.index>1?`${a}#${i.index}`:a,flowId:e,kind:t.kind,label:V(t,s,$,i,q),phase:o,start:I,end:w,durationMs:w-I,eventIds:s.map(u=>u.id),counts:n,projects:[...p].sort(),...$.route?{route:$.route}:{},...$.method?{method:$.method}:{},...t.requestId?{requestId:t.requestId}:{},...t.after?{after:t.after}:{},...q.length?{hot:q}:{},...i?{part:i}:{},worstSeverity:g}}b(Q,"Y"),m(Q,"toSegment");function H(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()}:{}}}b(H,"H"),m(H,"routeOf");function J(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,o)=>o[1]-s[1]||(s[0]<o[0]?-1:1)).slice(0,3).map(([s,o])=>o>1?`${s} \xD7${o}`:s)}b(J,"J"),m(J,"hotOf");function V(e,t,s,o,i){const n=o?` (part ${o.index}/${o.total})`:"";if(e.kind==="request"){if(s.route)return`${s.method?`${s.method} `:""}${s.route}${n}`;const p=t.find(g=>g.queueKey);return p?`job ${p.queueKey}${n}`:`request ${e.requestId??""}${n}`}return e.kind==="origin"?`${t.find(p=>p.kind==="flow-origin")?.event.title||"start"}${i.length?` \xB7 ${i.join(", ")}`:""}${n}`:e.kind==="ui"?`UI update${i.length?` \xB7 ${i.join(", ")}`:""}${n}`:`background${n}`}b(V,"Z"),m(V,"labelOf");const X=50;export function sqlAccountingOf(e){return E(e,!1)}b(sqlAccountingOf,"sqlAccountingOf"),m(sqlAccountingOf,"sqlAccountingOf");function N(e){return E(e.map(t=>t.event),!0)}b(N,"T"),m(N,"accountSqlOfItems");function E(e,t){const s=new Map,o=new Map,i=t?void 0:new Set;for(const d of e){if(i){if(i.has(d.id))continue;i.add(d.id)}const c=S(d.raw)?d.raw:{},f=v(c.kind),r=v(d.context?.requestId);if(!r)continue;const l=v(c.project)??v(d.context?.projectName);if(f==="db-query"&&d.source==="db"){const h=o.get(r)??{count:0,workMs:0,...l?{project:l}:{}};h.count+=1,h.workMs+=M(c.durationMs)??0,o.set(r,h)}else if(f===SQL_ACCOUNT_KIND){const h=v(c.accountId)??d.id,k=M(c.seq)??0,x=s.get(h);if(x&&x.seq>=k)continue;s.set(h,{requestId:r,...l?{project:l}:{},seq:k,basis:c.basis==="end"?"end":"settled",statements:M(c.statements)??0,failed:M(c.failed)??0,workMs:M(c.workMs)??0,recorded:M(c.recorded)??0,suppressed:M(c.suppressed)??0,unwritten:M(c.unwritten)??0})}}const n=new Map;for(const d of s.values()){const c=n.get(d.requestId);if(!c){n.set(d.requestId,{...d});continue}d.basis==="settled"&&(c.basis="settled"),c.statements+=d.statements,c.failed+=d.failed,c.workMs+=d.workMs,c.recorded+=d.recorded,c.suppressed+=d.suppressed,c.unwritten+=d.unwritten}const p=[...new Set([...o.keys(),...n.keys()])].sort();if(p.length===0)return;const g={statements:0,failed:0,workMs:0,recorded:0,suppressed:0,unwritten:0},q={statements:0,workMs:0},I=[];for(const d of p){const c=o.get(d),f=n.get(d),r=c?.count??0;q.statements+=r,q.workMs+=c?.workMs??0;const l=!f||r>f.statements?"unverified":r===f.statements?"complete":"incomplete";f&&l!=="unverified"&&(g.statements+=f.statements,g.failed+=f.failed,g.workMs+=f.workMs,g.recorded+=f.recorded,g.suppressed+=f.suppressed,g.unwritten+=f.unwritten);const h=c?.project??f?.project;I.push({requestId:d,...h?{project:h}:{},status:l,observed:r,observedWorkMs:c?.workMs??0,...f?{basis:f.basis,statements:f.statements,failed:f.failed,workMs:f.workMs,recorded:f.recorded,suppressed:f.suppressed,unwritten:f.unwritten}:{}})}const w=m(d=>I.filter(c=>c.status===d).length,"tally"),$=w("unverified"),a=w("incomplete"),u=m(d=>(d.statements??0)-d.observed,"missing"),j=I.filter(d=>d.status!=="complete").sort((d,c)=>(d.status==="incomplete"?0:1)-(c.status==="incomplete"?0:1)||u(c)-u(d)||(d.requestId<c.requestId?-1:d.requestId>c.requestId?1:0));return{status:$>0?"unverified":a>0?"incomplete":"complete",requests:I.length,complete:w("complete"),incomplete:a,unverified:$,settled:I.filter(d=>d.status!=="unverified"&&d.basis==="settled").length,observed:q,accounted:g,gaps:j.slice(0,X),gapsTruncated:j.length>X}}b(E,"W"),m(E,"accountSql");
package/lib/flow-shape.js CHANGED
@@ -1 +1 @@
1
- "use strict";var Bt=Object.defineProperty;var R=(i,f)=>Bt(i,"name",{value:f,configurable:!0});var St=Object.defineProperty,P=R((i,f)=>St(i,"name",{value:f,configurable:!0}),"R"),At=Object.defineProperty,w=P((i,f)=>At(i,"name",{value:f,configurable:!0}),"I");import{redactDeep as Rt,redactText as ut,redactUrlParams as Tt}from"./redact.js";import{templatisePath as wt}from"./route-template.js";import{SQL_ACCOUNT_KIND as Dt,sqlAccountingOf as Ct}from"./flow-segments.js";import{isServiceHopHost as kt}from"./service-hop.js";import{boundedClone as Pt}from"@lensmcp/protocol-types";export function areaOf(i){const{source:f,category:s,title:q,kind:l}=i;return f==="ai"?"ai":f==="perf"&&l==="event-loop-stall"?"services":l?.startsWith("memory")||l==="db-query"?"data":f==="gateway"||l==="gateway-request"?"gateway":l==="queue-process"||l==="queue-active"||l==="queue-completed"||l==="queue-failed"?"services":f==="db"||f==="redis"||f==="queue"||l==="redis-op"||l?.startsWith("queue-")||f==="fs"||l==="fs-ops"?"data":f==="exec"||l==="exec"||l==="egress"&&kt(i.host)?"services":f==="external"||l==="egress"?"network":f==="nestjs"||f==="nest"?/(?:Repository|Repo|Dao|Store|EntityManager|DataSource|QueryRunner|OrmClient)\./.test(q)?"data":"services":f==="valtio"?"state":s==="network"?"network":"browser"}R(areaOf,"areaOf"),P(areaOf,"areaOf"),w(areaOf,"areaOf");const qt=240,Ft=new Set(["systemPrompt","prompt","prompts","messages","completion","completions","input","output","draft","text","content","result","arguments","params"]),Nt=new Set(["tenantId","caller","userId","accountId","email","subject"]),Ot=8;function ct(i){const f=et(i,0);return Pt(Rt({redacted:!0,...f}),{rawByteLimit:16*1024}).value}R(ct,"vt"),P(ct,"Ct"),w(ct,"aiProjection");function et(i,f){if(typeof i=="string")return lt(i);if(i===null||typeof i!="object")return i;if(f>=Ot)return;if(Array.isArray(i))return i.slice(0,32).map(q=>et(q,f+1));const s={};for(const[q,l]of Object.entries(i))if(!Nt.has(q)){if(Ft.has(q)){typeof l=="string"?s[`${q}Chars`]=l.length:Array.isArray(l)?s[`${q}Count`]=l.length:l!=null&&(s[`${q}Present`]=!0);continue}s[q]=et(l,f+1)}return s}R(et,"rt"),P(et,"it"),w(et,"projectAi");function lt(i){return i.length<=qt?ut(i):`${ut(i.slice(0,qt))}\u2026`}R(lt,"kt"),P(lt,"Et"),w(lt,"clipText");export function httpFacts(i,f){const s=w(I=>typeof I=="string"&&I.length>0?I:void 0,"str"),q=typeof f.status=="number"?f.status:void 0,l=w(I=>Tt(I.split("?")[0]??I)||"/","pathOf"),F=w((I,y,j={})=>({...I?{method:I.toUpperCase()}:{},...y?{rawPath:y,route:wt(y)}:{},...q!==void 0?{status:q}:{},...j}),"facts");if(i==="gateway-request"){const I=s(f.url);return F(s(f.method),I?l(I):void 0,{...s(f.host)?{host:s(f.host)}:{},...s(f.caller)?{caller:s(f.caller)}:{}})}if(i==="egress"){const I=s(f.path),y=s(f.exchangeId);return F(s(f.method)??"GET",I?l(I):void 0,{...s(f.host)?{host:s(f.host)}:{},...y?{exchangeId:y}:{}})}if(i==="fetch-start"||i==="fetch-done"||i==="fetch-error"){const I=s(f.href)??s(f.url);let y,j;if(I)try{const p=new URL(I,"http://relative.invalid");y=l(p.pathname),p.hostname!=="relative.invalid"&&(j=p.hostname)}catch{}return F(s(f.method)??"GET",y,j?{host:j}:{})}if(i==="ai-call")return{...q!==void 0?{status:q}:{},...f.stream===!0?{streamed:!0}:{}};const g=f.request;if(g&&typeof g=="object"){const I=g,y=s(I.route),j=s(I.method);if(!y&&!j)return{};const p=typeof I.status=="number"?I.status:void 0,T=y?l(y):void 0;return{...j?{method:j.toUpperCase()}:{},...T?{rawPath:T,route:T.includes(":")?T:wt(T)}:{},...p!==void 0?{status:p}:{}}}return{}}R(httpFacts,"httpFacts"),P(httpFacts,"httpFacts"),w(httpFacts,"httpFacts");export function trimFlowEvent(i,f={}){const s=i.raw??{},q=s.render??{},l=s.span??{},F=s.request??{},g=w(d=>typeof d=="number"?d:void 0,"num"),I=s.loop??{},y=s.effect??{},j=g(s.durationMs)??g(l.durationMs)??g(F.durationMs)??g(I.durationMs)??g(q.actualDurationMs)??g(y.durationMs),p=typeof s.kind=="string"?s.kind:void 0,T=p==="fetch-done"||p==="fetch-error",_=g(q.commitTime),z=p==="render"&&_!==void 0&&Math.abs(_-i.timestamp)<6e4,J=T?i.timestamp:z?_:g(s.startedAt)??g(l.startTime)??g(F.startedAt)??g(I.startedAt)??(j!==void 0?i.timestamp-j:i.timestamp);let b;if(typeof s.query=="string"){const d=Array.isArray(s.params)?` [${s.params.join(", ")}]`:"",m=typeof s.result=="string"?` \u2192 ${s.result}`:"";b=s.query+d+m}else if(typeof s.command=="string"){const d=typeof s.value=="string"?` \u2192 ${s.value}`:s.hit===!1?" \u2192 (miss)":"";b=s.command+d}else if(p==="state-update"){const d=s.update??{};let m="";try{m=JSON.stringify(d.preview)}catch{}b=`${d.storeId??""}.${d.path??""} = ${m}`}else if(p==="fs-ops"&&Array.isArray(s.paths))b=s.paths.slice(0,8).map(d=>{const m=d??{},S=typeof m.n=="number"&&m.n>1?` \xD7${m.n}`:"",h=typeof m.bytes=="number"&&m.bytes>0?` (${m.bytes>=1024?`${(m.bytes/1024).toFixed(1)} KB`:`${m.bytes} B`})`:"";return`${String(m.op??"?")} ${String(m.path??"?")}${S}${h}`}).join(" \xB7 ");else if(p==="exec"&&typeof s.cmd=="string")b=`${s.cmd} \u2192 ${s.code??s.signal??s.error??"?"}`;else if(p==="queue-completed"&&typeof s.returned=="string")b=`returned ${s.returned}`;else if(p==="queue-enqueued")b=`${s.job??"job"}#${s.jobId??"?"} \u2192 ${s.queue??""}${typeof s.data=="string"?" "+s.data:""}`;else if(p==="log"){const d=F.error??{},m=typeof d.stack=="string"?d.stack:typeof s.text=="string"?s.text:void 0;m&&m!==i.title&&(b=m)}let U,W,Y,K;if(p==="span"){const d=l.outcome;if(U=d==="threw"||d==="returned"?d:l.status==="error"?"threw":l.status==="ok"?"returned":void 0,U==="threw"){const h=l.error??{},C=typeof h.name=="string"?h.name:void 0,G=typeof h.message=="string"?h.message:typeof i.message=="string"?i.message:void 0;Y=C,W=ut([C,G].filter(Boolean).join(": "))||void 0}const m=typeof l.args=="string"?l.args:void 0,S=typeof l.result=="string"?l.result:void 0;if(m!==void 0||S!==void 0){K=[...m!==void 0?["args"]:[],...S!==void 0?["result"]:[]];const h=w(C=>C.length>Mt?`${C.slice(0,Mt)}\u2026`:C,"short");b=[m!==void 0?`args ${h(m)}`:"",S!==void 0?`returned ${h(S)}`:""].filter(Boolean).join(" \u2192 ")}}let Q;if(p==="gateway-request")Q=`${s.host??""}${String(s.url??"").split("?")[0]}`;else if(p==="fetch-start"||p==="fetch-done"||p==="fetch-error")try{const d=new URL(String(s.href??s.url??""));Q=`${d.hostname}${d.pathname}`}catch{}let O;if(p==="gateway-request"&&Array.isArray(s.steps))O=s.steps.map(d=>{const m=[String(d.step)];return d.project&&m.push(String(d.project)),d.prefix&&m.push(String(d.prefix)),d.mode&&m.push(String(d.mode)+(d.ok===!1?" \u2717":d.ok===!0?" \u2713":"")),d.caller&&m.push("by "+String(d.caller)),d.pod&&m.push(String(d.pod)),typeof d.atMs=="number"&&m.push(`@${d.atMs}ms`),m.join(" ")}),b=O.map(d=>d.replace(/ @\d+ms$/,"")).join(" \u2192 ");else if(p==="egress")b=`${s.method??"GET"} ${s.host??""} \u2192 ${s.status??"?"}`;else if(i.source==="ai"){if(p==="ai-call"){const d=s.usage??{},m=d.promptTokens!==void 0||d.completionTokens!==void 0?` \xB7 ${g(d.promptTokens)??"?"}\u2192${g(d.completionTokens)??"?"} tok`:"",S=s.status!==void 0?` \xB7 ${String(s.status)}`:s.error?" \xB7 failed":"",h=g(s.toolCallCount)?` \xB7 ${g(s.toolCallCount)} tool call${g(s.toolCallCount)===1?"":"s"}`:"",C=g(s.durationMs)!==void 0?` \xB7 ${(g(s.durationMs)/1e3).toFixed(1)}s`:"";b=`${s.provider??""}/${s.model??"?"}${m}${S}${h}${C}${s.stream===!0?" \xB7 stream":""}`}else if(p==="ai-round"){const d=s.model??{},m=s.usage??{},S=Array.isArray(s.toolCalls)?s.toolCalls:[],h=`${g(m.promptTokens)??"?"}\u2192${g(m.completionTokens)??"?"} tok`,C=S.length?` \xB7 ${S.length} tool call${S.length===1?"":"s"}`:"",G=g(s.durationMs)!==void 0?` \xB7 ${(g(s.durationMs)/1e3).toFixed(1)}s`:"";b=`${d.provider??""}/${d.model??""} \xB7 ${h}${C}${G}`}else if(p==="ai-turn-start"){const d=Array.isArray(s.tools)?s.tools:[];b=`skill ${s.skill??""} \xB7 ${s.output??""}${d.length?" \xB7 tools: "+d.join(", "):""}`}else if(p==="ai-tool-call"){const d=s.call??{},m=s.result??{},S=g(s.durationMs)!==void 0?` \xB7 ${(g(s.durationMs)/1e3).toFixed(1)}s`:"";b=`${d.name??"tool"} ${m.error!=null?"\u2717 "+String(m.error):"\u2713"}${S}`}else if(p==="ai-turn-end"){const d=s.usage??{},m=g(s.rounds)!==void 0?` \xB7 ${g(s.rounds)} round${g(s.rounds)===1?"":"s"}`:"",S=g(s.durationMs)!==void 0?` \xB7 ${(g(s.durationMs)/1e3).toFixed(1)}s`:"";b=`${s.ok===!1?"FAILED":"ok"} \xB7 ${g(d.promptTokens)??"?"}+${g(d.completionTokens)??"?"} tok${m}${S}`}}let D;p==="db-query"&&typeof s.query=="string"?D=s.query:p==="redis-op"?D=`${s.op??""} ${String(s.key??"").replace(/\d+/g,"#")}`:p==="egress"?D=`${s.method??"GET"} ${s.host??""}`:p==="ai-call"?D=`ai ${s.provider??""} ${s.model??""} ${s.api??""}`:p==="queue-enqueued"?D=`enqueue ${s.queue??""}`:p==="span"&&typeof l.name=="string"?D=l.name:p==="memory-mutation"&&(D=i.title);const L=i.context??{},X=q.commitId??y.commitId??s.commitId,V=Array.isArray(q.why)?q.why.map(d=>typeof d?.type=="string"?d.type:void 0).filter(d=>!!d):[];return{id:i.id,t:i.timestamp,start:J,...D?{sig:D}:{},...Q?{urlKey:Q}:{},...httpFacts(p,s),...(p==="db-query"||p==="redis-op")&&typeof s.valuesId=="string"?{valuesId:s.valuesId}:{},...typeof s.queue=="string"?{queue:s.queue}:{},...s.jobId!=null?{jobId:String(s.jobId)}:{},source:i.source,category:i.category,severity:i.severity,title:U==="threw"&&typeof l.name=="string"?`${l.name} \u2014 threw${Y?` ${Y}`:""}${j!==void 0?` after ${j}ms`:""}`:i.title,kind:p,area:areaOf({source:i.source,category:i.category,title:i.title,kind:p,...typeof s.host=="string"?{host:s.host}:{}}),...p==="egress"&&kt(typeof s.host=="string"?s.host:void 0)?{hop:!0}:{},...p==="egress"&&typeof s.calleeRequestId=="string"?{calleeRequestId:s.calleeRequestId}:{},...U?{outcome:U}:{},...W?{error:W}:{},...K?{captured:K}:{},...typeof l.role=="string"?{role:l.role}:{},...typeof l.spanId=="string"?{spanId:l.spanId}:{},...typeof l.parentSpanId=="string"?{parentSpanId:l.parentSpanId}:{},...p==="log"&&typeof s.level=="string"?{level:s.level}:{},...p==="log"&&typeof s.logger=="string"?{logger:s.logger}:{},...p==="log"&&typeof s.stream=="string"?{stream:s.stream}:{},...typeof L.requestId=="string"?{requestId:L.requestId}:{},...typeof L.parentRequestId=="string"?{parentRequestId:L.parentRequestId}:{},...typeof X=="string"?{commitId:X}:{},...typeof q.componentName=="string"?{component:q.componentName}:{},...typeof q.phase=="string"?{phase:q.phase}:{},...V.length?{why:V}:{},...p==="effect-run"&&typeof y.hookLogicalId=="string"?{hook:y.hookLogicalId}:{},...p==="effect-run"&&y.cleanupRan===!0?{cleanup:!0}:{},...p==="render-commit-truncated"?{renderTotal:g(s.total),renderPublished:g(s.published),...g(s.walkStoppedAt)!==void 0?{renderWalkStoppedAt:g(s.walkStoppedAt)}:{}}:{},...typeof L.projectName=="string"?{project:L.projectName}:typeof s.project=="string"?{project:s.project}:{},...j!==void 0?{durationMs:j}:{},...T&&g(s.startedAt)!==void 0?{fetchStartedAt:g(s.startedAt)}:{},...i.source==="ai"?{ai:f.includeRaw?s:ct(s)}:{},...b?{detail:b}:{},...O?{steps:O}:{}}}R(trimFlowEvent,"trimFlowEvent"),P(trimFlowEvent,"trimFlowEvent"),w(trimFlowEvent,"trimFlowEvent");const Mt=300;export const OUTLIVED_PARENT_MIN_MS=250;const Et=new Set(["egress","db-query","redis-op","ai-call","span","gateway-request","server-request"]),pt=1;function ft(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}R(ft,"Mt"),P(ft,"Nt"),w(ft,"kindRank");function H(i){return i.kind==="span"&&i.role==="controller"?3.5:i.kind==="queue-process"?3:ft(i.kind)}R(H,"J"),P(H,"Z"),w(H,"causalRank");export function buildFlowDetail(i,f={}){const s=Ct(i),q=i.slice().filter(t=>{const r=t.raw??{},e=typeof r.kind=="string"?r.kind:"";if(e==="subscription-added"||e==="subscription-removed"||e==="hook-run"||e==="store-created"||e==="singleton-instance"||e===Dt)return!1;const o=r.span;return!(typeof o?.name=="string"&&o.name.startsWith("nest.request "))}).map(t=>trimFlowEvent(t,f)),l=new Set;for(let t=q.length-1;t>=0;t--)l.has(q[t].id)?q.splice(t,1):l.add(q[t].id);const F=new Map;for(const t of q)(t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&!F.has(t.requestId)&&F.set(t.requestId,t.start);const g=w(t=>t.source!=="react"&&t.source!=="valtio"&&t.requestId&&F.has(t.requestId)?F.get(t.requestId):t.start,"anchorOf");q.sort((t,r)=>g(t)-g(r)||t.start-r.start||H(t)-H(r)||(r.durationMs??0)-(t.durationMs??0)||t.t-r.t);const I=w(t=>(t.kind==="span"||t.kind==="server-request"||t.kind==="gateway-request"||t.kind==="queue-process")&&(t.durationMs??0)>0,"spanLike"),y=q;for(const t of y)t.group=t.source==="react"||t.source==="valtio"||t.source==="client-runtime"||t.source==="visual"?"browser":"server";const j=new Map;for(const t of y)if((t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&t.project){const r=j.get(t.requestId)??[];r.push({project:t.project,start:t.start,end:t.start+(t.durationMs??0)}),j.set(t.requestId,r)}const p=w((t,r)=>{const e=j.get(t);if(e?.length)return e.every(o=>o.project===e[0].project)?e[0].project:e.filter(o=>o.start<=r+1&&o.end>=r-1).sort((o,n)=>n.start-o.start)[0]?.project},"projectOf");for(const t of y)if(!t.project&&t.source==="nestjs"&&t.requestId){const r=p(t.requestId,t.start);r&&(t.project=r)}const T=new Map;for(const t of y)t.spanId&&T.set(t.spanId,t);const _=w((t,r)=>{let e=t.parentSpanId?T.get(t.parentSpanId):void 0;for(let o=0;e&&o<64;o++){if(e===r)return!0;e=e.parentSpanId?T.get(e.parentSpanId):void 0}return!1},"inside"),z=new Map(y.map((t,r)=>[t,r])),J=new Map,b=w(t=>{let r=J.get(t.group);r||J.set(t.group,r=new Map);const e=t.requestId;let o=r.get(e);return o||r.set(e,o={spans:[],next:0,alive:[]}),o},"legOf");for(const t of y)I(t)&&Number.isFinite(t.start)&&b(t).spans.push(t);for(const t of J.values())for(const r of t.values())r.spans.sort((e,o)=>e.start-o.start||z.get(e)-z.get(o));const U=w(t=>Number.isFinite(t.start)?t.start:1/0,"startOf");for(const t of y.slice().sort((r,e)=>U(r)-U(e))){const r=t.parentSpanId?T.get(t.parentSpanId):void 0;if(r&&r!==t&&r.group===t.group&&r.requestId===t.requestId){t.parent=r.id;continue}if(!Number.isFinite(t.start))continue;const e=b(t);for(;e.next<e.spans.length&&e.spans[e.next].start<=t.start+pt;)e.alive.push(e.spans[e.next++]);e.alive=e.alive.filter(a=>a.start+(a.durationMs??0)>t.start);const o=e.alive.length>1?e.alive.slice().sort((a,$)=>z.get(a)-z.get($)):e.alive;let n;for(const a of o){if(a===t)continue;const $=a.project,k=t.project;if(a.kind!=="gateway-request"&&t.kind!=="gateway-request"&&$!==void 0&&k!==void 0&&$!==k)continue;const u=a.durationMs??0,c=t.durationMs??0,v=Math.abs(a.start-t.start)<=pt,M=H(a),A=H(t),x=a.start<=t.start;if(!(a.start+u>t.start&&(x||v&&M<A)&&(!v||(M!==A?M<A:x&&u>c))))continue;const E=n?H(n):-1,N=n?Math.abs(a.start-n.start)<=pt:!1,Z=n&&N&&M===E?_(a,n)?1:_(n,a)?-1:0:0;(!n||!N&&a.start>n.start||N&&M>E||Z>0||Z===0&&N&&M===E&&(a.durationMs??0)<(n.durationMs??0))&&(n=a)}n&&(t.parent=n.id)}for(const t of y)delete t.spanId,delete t.parentSpanId;{const t=new Set(y.map(a=>a.id)),r=new Set,e=new Map,o=[],n=w(a=>{const $=[a];for(;$.length;){const k=$.pop();o.push(k),r.add(k.id);const u=e.get(k.id);if(u){e.delete(k.id);for(let c=u.length-1;c>=0;c--)$.push(u[c])}}},"place");for(const a of y)if(a.parent&&a.parent!==a.id&&t.has(a.parent)&&!r.has(a.parent)){const $=e.get(a.parent)??[];$.push(a),e.set(a.parent,$)}else n(a);for(const a of y)r.has(a.id)||(o.push(a),r.add(a.id));for(let a=0;a<o.length;a++)y[a]=o[a]}const W=new Map;for(const t of y){if(!t.requestId)continue;const r=W.get(t.requestId);r?r.push(t):W.set(t.requestId,[t])}const Y=new Map(y.map(t=>[t.id,t])),K=new Map;for(const t of y)t.calleeRequestId&&!K.has(t.calleeRequestId)&&K.set(t.calleeRequestId,t);const Q=w((t,r)=>{const e=(W.get(t)??[]).filter(o=>I(o)&&o.start<=r&&o.start+(o.durationMs??0)>=r);if(e.length!==0)return e.sort((o,n)=>n.start-o.start||(o.durationMs??0)-(n.durationMs??0)),e[0]},"callerNodeFor");for(const t of y){if(!t.parentRequestId||t.kind!=="server-request"&&t.kind!=="gateway-request")continue;const r=t.parent?Y.get(t.parent):void 0;if(r&&r.requestId===t.requestId)continue;const e=t.requestId?K.get(t.requestId):void 0,o=e&&e.start<=t.start?e:Q(t.parentRequestId,t.start);o&&o!==t&&o.start<=t.start&&(t.parent=o.id)}const O=y,D=new Map;for(const t of O)t.kind==="gateway-request"&&t.requestId&&!D.has(t.requestId)&&D.set(t.requestId,t);for(const t of O)if(t.group==="server"&&!t.parent&&t.requestId&&t.kind!=="gateway-request"){const r=D.get(t.requestId);r&&r!==t&&r.start<=t.start&&(t.parent=r.id)}const L=new Set,X=new Set,V=[];for(const t of O){if(t.kind!=="gateway-request")continue;if(!t.requestId){V.push(t);continue}const r=W.get(t.requestId)??[];if(r.filter(n=>n.kind==="gateway-request").sort((n,a)=>n.start-a.start)[0]!==t)continue;const e=r.find(n=>n.kind==="fetch-start"),o=r.find(n=>n.kind==="fetch-done"||n.kind==="fetch-error");if(!e&&!o){V.push(t);continue}e&&(t.fetchStartId=e.id,L.add(e.id)),o&&(t.fetchDoneId=o.id,X.add(o.id))}const d=new Map;for(const t of O){if(!t.urlKey)continue;const r=d.get(t.urlKey)??{gws:[],starts:[],dones:[]};t.kind==="gateway-request"?V.includes(t)&&r.gws.push(t):t.kind==="fetch-start"?L.has(t.id)||r.starts.push(t):(t.kind==="fetch-done"||t.kind==="fetch-error")&&(X.has(t.id)||r.dones.push(t)),d.set(t.urlKey,r)}for(const{gws:t,starts:r,dones:e}of d.values()){t.sort((n,a)=>n.start-a.start),r.sort((n,a)=>n.start-a.start);const o=new Set;t.forEach((n,a)=>{const $=r[a];$&&(n.fetchStartId=$.id);const k=$?$.t:n.start;let u,c=1/0;for(const v of e){if(o.has(v.id))continue;const M=v.fetchStartedAt??v.start-(v.durationMs??0),A=Math.abs(M-k);A<c&&(c=A,u=v)}u&&(n.fetchDoneId=u.id,o.add(u.id))})}const m=new Map,S=new Map;for(const t of O)!t.queue||!t.jobId||(t.kind==="queue-enqueued"&&m.set(`${t.queue}#${t.jobId}`,t),t.kind==="queue-process"&&S.set(`${t.queue}#${t.jobId}`,t));for(const t of O){if(!t.queue||!t.jobId)continue;const r=`${t.queue}#${t.jobId}`;if(t.kind==="queue-process"&&!t.parent){const e=m.get(r);e&&e!==t&&e.start<=t.start&&(t.parent=e.id)}else if(t.kind==="queue-active"||t.kind==="queue-completed"||t.kind==="queue-failed"){const e=S.get(r);e&&e!==t&&e.start<=t.start&&(t.parent=e.id)}}{const t=new Map(y.map(r=>[r.id,r]));for(const r of y){if(!r.parent||!Et.has(r.kind??"")||r.durationMs===void 0)continue;const e=t.get(r.parent);if(!e||e.kind!=="span"||!((e.durationMs??0)>0))continue;const o=Math.round(r.start+r.durationMs-(e.start+e.durationMs));if(o<OUTLIVED_PARENT_MIN_MS)continue;r.outlivedParentMs=o;const n=e.leftRunning??{count:0,longestMs:0};e.leftRunning={count:n.count+1,longestMs:Math.max(n.longestMs,o)}}for(const r of y){const e=[];r.leftRunning&&e.push(`ended before ${r.leftRunning.count===1?"a call":`${r.leftRunning.count} calls`} it started had finished \u2014 ${r.leftRunning.count===1?"it":"the longest"} ran on ${r.leftRunning.longestMs}ms (a timeout that gave up, or work not awaited)`),r.outlivedParentMs!==void 0&&e.push(`ran on ${r.outlivedParentMs}ms after the span that started it had ended`),e.length>0&&(r.detail=[r.detail,...e].filter(Boolean).join(" \xB7 "))}}let h=y;{const t=new Map;for(const e of h)e.kind==="fetch-start"&&t.set(e.id,e);const r=new Map;for(const e of h){if(e.kind!=="fetch-done"&&e.kind!=="fetch-error")continue;const o=[...t.values()].find($=>$.requestId&&$.requestId===e.requestId)?.id,n=o?t.get(o):void 0;if(!n)continue;const a=e.fetchStartedAt??n.start;n.title=e.title,n.severity=e.severity,n.durationMs=e.durationMs??Math.max(0,e.t-a),n.kind="fetch",e.detail&&!n.detail&&(n.detail=e.detail),r.set(e.id,n.id)}if(r.size>0){h=h.filter(e=>!r.has(e.id));for(const e of h)for(e.fetchDoneId&&r.has(e.fetchDoneId)&&(e.fetchDoneId=r.get(e.fetchDoneId));e.parent&&r.has(e.parent);)e.parent=r.get(e.parent)}}const C=w(t=>!!t.commitId&&(t.kind==="render"||t.kind==="effect-run"||t.kind==="render-commit-truncated"),"commitMember"),G=w(t=>[...new Set(t)],"uniq"),ot=w(t=>G(t.map(r=>r.component).filter(r=>!!r)),"named"),It=w(t=>t.length<=2?t.join(" + "):`${t[0]} + ${t.length-1} more`,"nameList"),mt=w(t=>{const r=new Map;for(const e of t)e.component&&r.set(e.component,(r.get(e.component)??0)+1);return[...r].map(([e,o])=>o>1?`${e} \xD7${o}`:e).join(", ")},"tally"),bt=w(t=>{if(!t)return"effect";const r=/([^/\\]+?):(\d+)(?::\d+)?$/.exec(t);return r?`${r[1]}:${r[2]}`:t},"shortHook"),nt=w(t=>`${bt(t.hook)}${t.cleanup?" (cleanup)":""}`,"hookLabel"),gt=w(t=>{const r=Math.min(...t.map(o=>o.start)),e=Math.max(...t.map(o=>o.start+(o.durationMs??0)));return{start:r,durationMs:e-r}},"extent"),ht=w(t=>(delete t.component,delete t.why,delete t.phase,delete t.hook,delete t.cleanup,delete t.renderTotal,delete t.renderPublished,t),"asGroup");function at(t){const r=t[0],e=t.filter(B=>B.kind==="render"),o=t.filter(B=>B.kind==="effect-run"),n=t.find(B=>B.kind==="render-commit-truncated"),a=[...e].sort((B,tt)=>(tt.durationMs??0)-(B.durationMs??0)),$=a.filter(B=>(B.why??[]).some(tt=>tt!=="parent-render")),k=G($.flatMap(B=>(B.why??[]).filter(tt=>tt!=="parent-render"))),u=ot($),c=e.filter(B=>B.phase==="mount"),v=e.filter(B=>B.phase!=="mount"&&!$.includes(B)),M=a[0]?.component??"view",A=e.length>0&&c.length===e.length,x=k.length?k.join(" + "):void 0,E=A?"mount":"update",N=u.length?`view update \xB7 ${It(u)} \u2190 ${x}`:A?`view mount \xB7 ${M}`:`view update \xB7 ${M}`,Z=n?.renderTotal??e.length,jt=[c.length?`mounted ${mt(c)}`:"",v.length?`re-rendered ${mt(v)}`:"",!u.length&&!A&&e.length?"trigger not recorded \u2014 every captured render came from its parent":"",n?.renderWalkStoppedAt!==void 0?`at least ${Z} renders (the walk stopped at ${n.renderWalkStoppedAt} fibers), ${n.renderPublished??e.length} recorded`:n?`${Z} renders, ${n.renderPublished??e.length} recorded (per-commit cap)`:`${e.length} render${e.length===1?"":"s"}`,o.length?`${o.length} effect${o.length===1?"":"s"}: ${o.map(nt).join(", ")}`:""].filter(Boolean).join(" \xB7 "),vt=ot(e);return ht({...r,...gt(t),kind:"view-update",title:N,detail:jt,commitId:r.commitId,viewPhase:E,...x?{cause:x}:{},causeComponents:u,components:vt,mounted:ot(c),renderCount:Z,...n?.renderWalkStoppedAt!==void 0?{renderCountAtLeast:!0}:{},recordedRenders:e.length,effects:o.length,effectHooks:o.map(nt),memberIds:t.map(B=>B.id),sig:`commit:${E}:${x??"-"}:${u.join(",")}:${vt.slice().sort().join(",")}`,severity:t.some(B=>B.severity==="error")?"error":r.severity})}R(at,"ct"),P(at,"It"),w(at,"viewUpdateNode");function it(t){const r=t[0],e=t.map(nt);return ht({...r,...gt(t),kind:"commit-effects",title:t.length===1?`effect \xB7 ${e[0]}`:`effects \xB7 ${e[0]} + ${t.length-1} more`,detail:e.join(", "),commitId:r.commitId,effects:t.length,effectHooks:e,memberIds:t.map(o=>o.id),sig:`effects:${e.slice().sort().join(",")}`})}R(it,"lt"),P(it,"kt"),w(it,"effectsNode");const xt=w(t=>G(t.map(r=>r==="state-update"?"state update":r==="fetch-start"?"request":r==="flow-origin"?"interaction":"response")).join(" + "),"describeInputs");function dt(t,r){const e=t[0],o=t[t.length-1],n=t.length,a=e.detail,$=Math.min(...t.map(v=>v.start)),k=Math.max(...t.map(v=>v.start+(v.durationMs??0))),u=Math.round(t.reduce((v,M)=>v+(M.durationMs??0),0)/n*10)/10,c=Math.round((k-$)*10)/10;e.count=n,e.avgMs=u,e.wallMs=c,e.durationMs=k-$,e.items=t.slice(0,12).map(v=>({start:v.start-$,...v.durationMs!=null?{durationMs:v.durationMs}:{}})),e.memberIds=t.flatMap(v=>v.memberIds??[v.id]),e.title=`\xD7${n} ${e.title}`,t.some(v=>v.severity==="error")&&(e.severity="error"),e.kind==="view-update"?e.detail=[`${n} commits, ${r.length?`one per ${xt(r)}`:"back to back"}`,`avg ${u}ms \xB7 wall ${c}ms`,a??""].filter(Boolean).join(" \xB7 "):e.kind==="state-update"&&a&&o.detail?e.detail=`${n} updates in a row \xB7 wall ${c}ms \xB7 first ${a} \xB7 last ${o.detail}`:e.detail=[`${n} in a row \xB7 wall ${c}ms`,a??""].filter(Boolean).join(" \xB7 ")}R(dt,"pt"),P(dt,"qt"),w(dt,"collapseRepeat");const rt=[],st=new Map,$t=new Set;for(let t=0;t<h.length;t++){if($t.has(t))continue;const r=h[t];if(!C(r)){rt.push(r);continue}const e=[t];for(let a=t+1;a<h.length;a++){const $=h[a];if($.group==="browser"){if(!C($)||$.commitId!==r.commitId)break;e.push(a)}}for(const a of e)$t.add(a);const o=e.map(a=>h[a]),n=o.some(a=>a.kind!=="effect-run")?at(o):it(o);for(const a of o)a.id!==n.id&&st.set(a.id,n.id);rt.push(n)}if(st.size>0||rt.some(t=>t.kind==="view-update"||t.kind==="commit-effects")){h=rt;for(const t of h)for(;t.parent&&st.has(t.parent);)t.parent=st.get(t.parent)}{const t=new Map;for(const r of h)r.kind==="view-update"&&r.commitId&&!t.has(r.commitId)&&t.set(r.commitId,r);for(const r of h){if(r.kind!=="commit-effects"||r.parent||!r.commitId)continue;const e=t.get(r.commitId);e&&e.start<=r.start&&(r.parent=e.id)}}{const t=new Set(["state-update","fetch","fetch-start","fetch-done","fetch-error","flow-origin"]),r=h.map((u,c)=>u.group==="browser"?c:-1).filter(u=>u>=0),e=w(u=>`${u.kind}|${u.sig??u.title}`,"keyOf"),o=r.map(u=>e(h[u])),n=w((u,c,v)=>{for(let M=0;M<v;M++)if(o[u+M]!==o[c+M])return!1;return!0},"sameBlock"),a=w(u=>o[u].split("|")[0],"kindAt"),$=w(u=>{let c=0,v=1;for(let M=1;M<=4&&u+M<=o.length;M++){let A=1;for(;u+(A+1)*M<=o.length&&n(u,u+A*M,M);)A+=1;A>=3&&M*A>c*v&&(c=M,v=A)}return{k:c,r:v}},"bestBlockAt"),k=new Map;for(let u=0;u<o.length;){const{k:c,r:v}=$(u);if(c===0){u+=1;continue}const M=[...Array(c).keys()].find(x=>t.has(a(u+x)));if(M!==void 0&&M>0){const x=$(u+M);if(x.k===c&&x.r>=3&&x.r>=v-1){u+=M;continue}}const A=o.slice(u,u+c).map(x=>x.split("|")[0]).filter(x=>t.has(x));for(let x=0;x<c;x++){const E=[];for(let N=0;N<v;N++)E.push(h[r[u+x+N*c]]);dt(E,A);for(const N of E.slice(1))k.set(N.id,E[0].id)}u+=c*v}if(k.size>0){h=h.filter(u=>!k.has(u.id));for(const u of h)for(;u.parent&&k.has(u.parent);)u.parent=k.get(u.parent)}}{const t=new Map(h.map(r=>[r.id,r]));for(const r of h){const e=new Set([r.id]);let o=r;for(;o?.parent;){if(e.has(o.parent)){o.parent=void 0;break}e.add(o.parent),o=t.get(o.parent)}}}const yt=w(t=>{const r=new Map;for(const o of h){if(!o.sig||I(o)!==t||o.kind==="server-request"||o.kind==="gateway-request"||o.group==="browser")continue;const n=`${o.parent??"root"}|${o.kind}|${o.sig}`,a=r.get(n);a?a.push(o):r.set(n,[o])}const e=new Map;for(const o of r.values()){if(o.length<3)continue;o.sort((c,v)=>c.start-v.start);const n=o[0];let a=!1;for(let c=0;c+1<o.length;c++)if(o[c+1].start<o[c].start+(o[c].durationMs??0)){a=!0;break}const $=n.start,k=Math.max(...o.map(c=>c.start+(c.durationMs??0))),u=o.reduce((c,v)=>c+(v.durationMs??0),0);n.count=o.length,n.parallel=a,n.avgMs=Math.round(u/o.length*10)/10,n.wallMs=k-$,n.durationMs=k-$,n.title=`\xD7${o.length} ${n.title.replace(/\s*\((?:\d+ rows?, )?\d+ms\)$/,"")}`,n.detail=`${n.sig} \xD7${o.length} ${a?"\u2016 parallel":"\u21BB sequential loop"} \xB7 avg ${n.avgMs}ms \xB7 wall ${n.wallMs}ms`,n.items=o.slice(0,12).map(c=>({start:c.start-$,...c.durationMs!=null?{durationMs:c.durationMs}:{}})),n.memberIds=o.flatMap(c=>c.memberIds??[c.id]),o.some(c=>c.severity==="error")&&(n.severity="error");for(const c of o.slice(1))e.set(c.id,n.id)}if(e.size!==0){h=h.filter(o=>!e.has(o.id));for(const o of h)for(;o.parent&&e.has(o.parent);)o.parent=e.get(o.parent)}},"aggregatePass");yt(!0),yt(!1);for(const t of h){if(!I(t))continue;const r=t.durationMs??0;if(r<40)continue;const e=h.filter(k=>k.parent===t.id&&(k.durationMs??0)>0).map(k=>[k.start,k.start+(k.durationMs??0)]).sort((k,u)=>k[0]-u[0]);let o=0,n=-1,a=-1;for(const[k,u]of e)k>a?(a>n&&(o+=a-n),n=k,a=u):u>a&&(a=u);a>n&&(o+=a-n);const $=Math.max(0,r-o);($>=50||$/r>=.7&&r>=40)&&(t.selfMs=$,t.detail=`\u26A0 cpu-heavy: ${$}ms self-time of ${r}ms${t.detail?" \xB7 "+t.detail:""}`)}return{events:h,...s?{sql:s}:{}}}R(buildFlowDetail,"buildFlowDetail"),P(buildFlowDetail,"buildFlowDetail"),w(buildFlowDetail,"buildFlowDetail");
1
+ "use strict";var jt=Object.defineProperty;var R=(i,f)=>jt(i,"name",{value:f,configurable:!0});var St=Object.defineProperty,k=R((i,f)=>St(i,"name",{value:f,configurable:!0}),"I");import{redactDeep as Bt,redactText as nt,redactUrlParams as At}from"./redact.js";import{templatisePath as ht}from"./route-template.js";import{SQL_ACCOUNT_KIND as Rt,sqlAccountingOf as Tt}from"./flow-segments.js";import{isServiceHopHost as $t}from"./service-hop.js";import{boundedClone as Ct}from"@lensmcp/protocol-types";export function areaOf(i){const{source:f,category:s,title:M,kind:l}=i;return f==="ai"?"ai":f==="perf"&&l==="event-loop-stall"?"services":l?.startsWith("memory")||l==="db-query"?"data":f==="gateway"||l==="gateway-request"?"gateway":l==="queue-process"||l==="queue-active"||l==="queue-completed"||l==="queue-failed"?"services":f==="db"||f==="redis"||f==="queue"||l==="redis-op"||l?.startsWith("queue-")||f==="fs"||l==="fs-ops"?"data":f==="exec"||l==="exec"||l==="egress"&&$t(i.host)?"services":f==="external"||l==="egress"?"network":f==="nestjs"||f==="nest"?/(?:Repository|Repo|Dao|Store|EntityManager|DataSource|QueryRunner|OrmClient)\./.test(M)?"data":"services":f==="valtio"?"state":s==="network"?"network":"browser"}R(areaOf,"areaOf"),k(areaOf,"areaOf");const yt=240,Dt=new Set(["systemPrompt","prompt","prompts","messages","completion","completions","input","output","draft","text","content","result","arguments","params"]),Pt=new Set(["tenantId","caller","userId","accountId","email","subject"]),Nt=8;function vt(i){const f=rt(i,0);return Ct(Bt({redacted:!0,...f}),{rawByteLimit:16*1024}).value}R(vt,"Ct"),k(vt,"aiProjection");function rt(i,f){if(typeof i=="string")return kt(i);if(i===null||typeof i!="object")return i;if(f>=Nt)return;if(Array.isArray(i))return i.slice(0,32).map(M=>rt(M,f+1));const s={};for(const[M,l]of Object.entries(i))if(!Pt.has(M)){if(Dt.has(M)){typeof l=="string"?s[`${M}Chars`]=l.length:Array.isArray(l)?s[`${M}Count`]=l.length:l!=null&&(s[`${M}Present`]=!0);continue}s[M]=rt(l,f+1)}return s}R(rt,"it"),k(rt,"projectAi");function kt(i){return i.length<=yt?nt(i):`${nt(i.slice(0,yt))}\u2026`}R(kt,"Et"),k(kt,"clipText");export function httpFacts(i,f){const s=k(I=>typeof I=="string"&&I.length>0?I:void 0,"str"),M=typeof f.status=="number"?f.status:void 0,l=k(I=>At(I.split("?")[0]??I)||"/","pathOf"),P=k((I,y,j={})=>({...I?{method:I.toUpperCase()}:{},...y?{rawPath:y,route:ht(y)}:{},...M!==void 0?{status:M}:{},...j}),"facts");if(i==="gateway-request"){const I=s(f.url);return P(s(f.method),I?l(I):void 0,{...s(f.host)?{host:s(f.host)}:{},...s(f.caller)?{caller:s(f.caller)}:{}})}if(i==="egress"){const I=s(f.path),y=s(f.exchangeId);return P(s(f.method)??"GET",I?l(I):void 0,{...s(f.host)?{host:s(f.host)}:{},...y?{exchangeId:y}:{}})}if(i==="fetch-start"||i==="fetch-done"||i==="fetch-error"){const I=s(f.href)??s(f.url);let y,j;if(I)try{const p=new URL(I,"http://relative.invalid");y=l(p.pathname),p.hostname!=="relative.invalid"&&(j=p.hostname)}catch{}return P(s(f.method)??"GET",y,j?{host:j}:{})}if(i==="ai-call")return{...M!==void 0?{status:M}:{},...f.stream===!0?{streamed:!0}:{}};const g=f.request;if(g&&typeof g=="object"){const I=g,y=s(I.route),j=s(I.method);if(!y&&!j)return{};const p=typeof I.status=="number"?I.status:void 0,T=y?l(y):void 0;return{...j?{method:j.toUpperCase()}:{},...T?{rawPath:T,route:T.includes(":")?T:ht(T)}:{},...p!==void 0?{status:p}:{}}}return{}}R(httpFacts,"httpFacts"),k(httpFacts,"httpFacts");export function trimFlowEvent(i,f={}){const s=i.raw??{},M=s.render??{},l=s.span??{},P=s.request??{},g=k(d=>typeof d=="number"?d:void 0,"num"),I=s.loop??{},y=s.effect??{},j=g(s.durationMs)??g(l.durationMs)??g(P.durationMs)??g(I.durationMs)??g(M.actualDurationMs)??g(y.durationMs),p=typeof s.kind=="string"?s.kind:void 0,T=p==="fetch-done"||p==="fetch-error",G=g(M.commitTime),H=p==="render"&&G!==void 0&&Math.abs(G-i.timestamp)<6e4,V=T?i.timestamp:H?G:g(s.startedAt)??g(l.startTime)??g(P.startedAt)??g(I.startedAt)??(j!==void 0?i.timestamp-j:i.timestamp);let b;if(typeof s.query=="string"){const d=Array.isArray(s.params)?` [${s.params.join(", ")}]`:"",m=typeof s.result=="string"?` \u2192 ${s.result}`:"";b=s.query+d+m}else if(typeof s.command=="string"){const d=typeof s.value=="string"?` \u2192 ${s.value}`:s.hit===!1?" \u2192 (miss)":"";b=s.command+d}else if(p==="state-update"){const d=s.update??{};let m="";try{m=JSON.stringify(d.preview)}catch{}b=`${d.storeId??""}.${d.path??""} = ${m}`}else if(p==="fs-ops"&&Array.isArray(s.paths))b=s.paths.slice(0,8).map(d=>{const m=d??{},B=typeof m.n=="number"&&m.n>1?` \xD7${m.n}`:"",h=typeof m.bytes=="number"&&m.bytes>0?` (${m.bytes>=1024?`${(m.bytes/1024).toFixed(1)} KB`:`${m.bytes} B`})`:"";return`${String(m.op??"?")} ${String(m.path??"?")}${B}${h}`}).join(" \xB7 ");else if(p==="exec"&&typeof s.cmd=="string")b=`${s.cmd} \u2192 ${s.code??s.signal??s.error??"?"}`;else if(p==="queue-completed"&&typeof s.returned=="string")b=`returned ${s.returned}`;else if(p==="queue-enqueued")b=`${s.job??"job"}#${s.jobId??"?"} \u2192 ${s.queue??""}${typeof s.data=="string"?" "+s.data:""}`;else if(p==="log"){const d=P.error??{},m=typeof d.stack=="string"?d.stack:typeof s.text=="string"?s.text:void 0;m&&m!==i.title&&(b=m)}let L,W,Y,U;if(p==="span"){const d=l.outcome;if(L=d==="threw"||d==="returned"?d:l.status==="error"?"threw":l.status==="ok"?"returned":void 0,L==="threw"){const h=l.error??{},D=typeof h.name=="string"?h.name:void 0,K=typeof h.message=="string"?h.message:typeof i.message=="string"?i.message:void 0;Y=D,W=nt([D,K].filter(Boolean).join(": "))||void 0}const m=typeof l.args=="string"?l.args:void 0,B=typeof l.result=="string"?l.result:void 0;if(m!==void 0||B!==void 0){U=[...m!==void 0?["args"]:[],...B!==void 0?["result"]:[]];const h=k(D=>D.length>wt?`${D.slice(0,wt)}\u2026`:D,"short");b=[m!==void 0?`args ${h(m)}`:"",B!==void 0?`returned ${h(B)}`:""].filter(Boolean).join(" \u2192 ")}}let _;if(p==="gateway-request")_=`${s.host??""}${String(s.url??"").split("?")[0]}`;else if(p==="fetch-start"||p==="fetch-done"||p==="fetch-error")try{const d=new URL(String(s.href??s.url??""));_=`${d.hostname}${d.pathname}`}catch{}let O;if(p==="gateway-request"&&Array.isArray(s.steps))O=s.steps.map(d=>{const m=[String(d.step)];return d.project&&m.push(String(d.project)),d.prefix&&m.push(String(d.prefix)),d.mode&&m.push(String(d.mode)+(d.ok===!1?" \u2717":d.ok===!0?" \u2713":"")),d.caller&&m.push("by "+String(d.caller)),d.pod&&m.push(String(d.pod)),typeof d.atMs=="number"&&m.push(`@${d.atMs}ms`),m.join(" ")}),b=O.map(d=>d.replace(/ @\d+ms$/,"")).join(" \u2192 ");else if(p==="egress")b=`${s.method??"GET"} ${s.host??""} \u2192 ${s.status??"?"}`;else if(i.source==="ai"){if(p==="ai-call"){const d=s.usage??{},m=d.promptTokens!==void 0||d.completionTokens!==void 0?` \xB7 ${g(d.promptTokens)??"?"}\u2192${g(d.completionTokens)??"?"} tok`:"",B=s.status!==void 0?` \xB7 ${String(s.status)}`:s.error?" \xB7 failed":"",h=g(s.toolCallCount)?` \xB7 ${g(s.toolCallCount)} tool call${g(s.toolCallCount)===1?"":"s"}`:"",D=g(s.durationMs)!==void 0?` \xB7 ${(g(s.durationMs)/1e3).toFixed(1)}s`:"";b=`${s.provider??""}/${s.model??"?"}${m}${B}${h}${D}${s.stream===!0?" \xB7 stream":""}`}else if(p==="ai-round"){const d=s.model??{},m=s.usage??{},B=Array.isArray(s.toolCalls)?s.toolCalls:[],h=`${g(m.promptTokens)??"?"}\u2192${g(m.completionTokens)??"?"} tok`,D=B.length?` \xB7 ${B.length} tool call${B.length===1?"":"s"}`:"",K=g(s.durationMs)!==void 0?` \xB7 ${(g(s.durationMs)/1e3).toFixed(1)}s`:"";b=`${d.provider??""}/${d.model??""} \xB7 ${h}${D}${K}`}else if(p==="ai-turn-start"){const d=Array.isArray(s.tools)?s.tools:[];b=`skill ${s.skill??""} \xB7 ${s.output??""}${d.length?" \xB7 tools: "+d.join(", "):""}`}else if(p==="ai-tool-call"){const d=s.call??{},m=s.result??{},B=g(s.durationMs)!==void 0?` \xB7 ${(g(s.durationMs)/1e3).toFixed(1)}s`:"";b=`${d.name??"tool"} ${m.error!=null?"\u2717 "+String(m.error):"\u2713"}${B}`}else if(p==="ai-turn-end"){const d=s.usage??{},m=g(s.rounds)!==void 0?` \xB7 ${g(s.rounds)} round${g(s.rounds)===1?"":"s"}`:"",B=g(s.durationMs)!==void 0?` \xB7 ${(g(s.durationMs)/1e3).toFixed(1)}s`:"";b=`${s.ok===!1?"FAILED":"ok"} \xB7 ${g(d.promptTokens)??"?"}+${g(d.completionTokens)??"?"} tok${m}${B}`}}let C;p==="db-query"&&typeof s.query=="string"?C=s.query:p==="redis-op"?C=`${s.op??""} ${String(s.key??"").replace(/\d+/g,"#")}`:p==="egress"?C=`${s.method??"GET"} ${s.host??""}`:p==="ai-call"?C=`ai ${s.provider??""} ${s.model??""} ${s.api??""}`:p==="queue-enqueued"?C=`enqueue ${s.queue??""}`:p==="span"&&typeof l.name=="string"?C=l.name:p==="memory-mutation"&&(C=i.title);const E=i.context??{},Z=M.commitId??y.commitId??s.commitId,z=Array.isArray(M.why)?M.why.map(d=>typeof d?.type=="string"?d.type:void 0).filter(d=>!!d):[];return{id:i.id,t:i.timestamp,start:V,...C?{sig:C}:{},..._?{urlKey:_}:{},...httpFacts(p,s),...(p==="db-query"||p==="redis-op")&&typeof s.valuesId=="string"?{valuesId:s.valuesId}:{},...typeof s.queue=="string"?{queue:s.queue}:{},...s.jobId!=null?{jobId:String(s.jobId)}:{},source:i.source,category:i.category,severity:i.severity,title:L==="threw"&&typeof l.name=="string"?`${l.name} \u2014 threw${Y?` ${Y}`:""}${j!==void 0?` after ${j}ms`:""}`:i.title,kind:p,area:areaOf({source:i.source,category:i.category,title:i.title,kind:p,...typeof s.host=="string"?{host:s.host}:{}}),...p==="egress"&&$t(typeof s.host=="string"?s.host:void 0)?{hop:!0}:{},...p==="egress"&&typeof s.calleeRequestId=="string"?{calleeRequestId:s.calleeRequestId}:{},...L?{outcome:L}:{},...W?{error:W}:{},...U?{captured:U}:{},...typeof l.role=="string"?{role:l.role}:{},...typeof l.spanId=="string"?{spanId:l.spanId}:{},...typeof l.parentSpanId=="string"?{parentSpanId:l.parentSpanId}:{},...p==="log"&&typeof s.level=="string"?{level:s.level}:{},...p==="log"&&typeof s.logger=="string"?{logger:s.logger}:{},...p==="log"&&typeof s.stream=="string"?{stream:s.stream}:{},...typeof E.requestId=="string"?{requestId:E.requestId}:{},...typeof E.parentRequestId=="string"?{parentRequestId:E.parentRequestId}:{},...typeof Z=="string"?{commitId:Z}:{},...typeof M.componentName=="string"?{component:M.componentName}:{},...typeof M.phase=="string"?{phase:M.phase}:{},...z.length?{why:z}:{},...p==="effect-run"&&typeof y.hookLogicalId=="string"?{hook:y.hookLogicalId}:{},...p==="effect-run"&&y.cleanupRan===!0?{cleanup:!0}:{},...p==="render-commit-truncated"?{renderTotal:g(s.total),renderPublished:g(s.published),...g(s.walkStoppedAt)!==void 0?{renderWalkStoppedAt:g(s.walkStoppedAt)}:{}}:{},...typeof E.projectName=="string"?{project:E.projectName}:typeof s.project=="string"?{project:s.project}:{},...j!==void 0?{durationMs:j}:{},...T&&g(s.startedAt)!==void 0?{fetchStartedAt:g(s.startedAt)}:{},...i.source==="ai"?{ai:f.includeRaw?s:vt(s)}:{},...b?{detail:b}:{},...O?{steps:O}:{}}}R(trimFlowEvent,"trimFlowEvent"),k(trimFlowEvent,"trimFlowEvent");const wt=300;export const OUTLIVED_PARENT_MIN_MS=250;const Ot=new Set(["egress","db-query","redis-op","ai-call","span","gateway-request","server-request"]),at=1;function Mt(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}R(Mt,"Nt"),k(Mt,"kindRank");function J(i){return i.kind==="span"&&i.role==="controller"?3.5:i.kind==="queue-process"?3:Mt(i.kind)}R(J,"Z"),k(J,"causalRank");export function buildFlowDetail(i,f={}){const s=Tt(i),M=i.slice().filter(t=>{const r=t.raw??{},e=typeof r.kind=="string"?r.kind:"";if(e==="subscription-added"||e==="subscription-removed"||e==="hook-run"||e==="store-created"||e==="singleton-instance"||e===Rt)return!1;const o=r.span;return!(typeof o?.name=="string"&&o.name.startsWith("nest.request "))}).map(t=>trimFlowEvent(t,f)),l=new Set;for(let t=M.length-1;t>=0;t--)l.has(M[t].id)?M.splice(t,1):l.add(M[t].id);const P=new Map;for(const t of M)(t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&!P.has(t.requestId)&&P.set(t.requestId,t.start);const g=k(t=>t.source!=="react"&&t.source!=="valtio"&&t.requestId&&P.has(t.requestId)?P.get(t.requestId):t.start,"anchorOf");M.sort((t,r)=>g(t)-g(r)||t.start-r.start||J(t)-J(r)||(r.durationMs??0)-(t.durationMs??0)||t.t-r.t);const I=k(t=>(t.kind==="span"||t.kind==="server-request"||t.kind==="gateway-request"||t.kind==="queue-process")&&(t.durationMs??0)>0,"spanLike"),y=M;for(const t of y)t.group=t.source==="react"||t.source==="valtio"||t.source==="client-runtime"||t.source==="visual"?"browser":"server";const j=new Map;for(const t of y)if((t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&t.project){const r=j.get(t.requestId)??[];r.push({project:t.project,start:t.start,end:t.start+(t.durationMs??0)}),j.set(t.requestId,r)}const p=k((t,r)=>{const e=j.get(t);if(e?.length)return e.every(o=>o.project===e[0].project)?e[0].project:e.filter(o=>o.start<=r+1&&o.end>=r-1).sort((o,n)=>n.start-o.start)[0]?.project},"projectOf");for(const t of y)if(!t.project&&t.source==="nestjs"&&t.requestId){const r=p(t.requestId,t.start);r&&(t.project=r)}const T=new Map;for(const t of y)t.spanId&&T.set(t.spanId,t);const G=k((t,r)=>{let e=t.parentSpanId?T.get(t.parentSpanId):void 0;for(let o=0;e&&o<64;o++){if(e===r)return!0;e=e.parentSpanId?T.get(e.parentSpanId):void 0}return!1},"inside"),H=new Map(y.map((t,r)=>[t,r])),V=new Map,b=k(t=>{let r=V.get(t.group);r||V.set(t.group,r=new Map);const e=t.requestId;let o=r.get(e);return o||r.set(e,o={spans:[],next:0,alive:[]}),o},"legOf");for(const t of y)I(t)&&Number.isFinite(t.start)&&b(t).spans.push(t);for(const t of V.values())for(const r of t.values())r.spans.sort((e,o)=>e.start-o.start||H.get(e)-H.get(o));const L=k(t=>Number.isFinite(t.start)?t.start:1/0,"startOf");for(const t of y.slice().sort((r,e)=>L(r)-L(e))){const r=t.parentSpanId?T.get(t.parentSpanId):void 0;if(r&&r!==t&&r.group===t.group&&r.requestId===t.requestId){t.parent=r.id;continue}if(!Number.isFinite(t.start))continue;const e=b(t);for(;e.next<e.spans.length&&e.spans[e.next].start<=t.start+at;)e.alive.push(e.spans[e.next++]);e.alive=e.alive.filter(a=>a.start+(a.durationMs??0)>t.start);const o=e.alive.length>1?e.alive.slice().sort((a,$)=>H.get(a)-H.get($)):e.alive;let n;for(const a of o){if(a===t)continue;const $=a.project,w=t.project;if(a.kind!=="gateway-request"&&t.kind!=="gateway-request"&&$!==void 0&&w!==void 0&&$!==w)continue;const u=a.durationMs??0,c=t.durationMs??0,v=Math.abs(a.start-t.start)<=at,q=J(a),A=J(t),x=a.start<=t.start;if(!(a.start+u>t.start&&(x||v&&q<A)&&(!v||(q!==A?q<A:x&&u>c))))continue;const F=n?J(n):-1,N=n?Math.abs(a.start-n.start)<=at:!1,Q=n&&N&&q===F?G(a,n)?1:G(n,a)?-1:0:0;(!n||!N&&a.start>n.start||N&&q>F||Q>0||Q===0&&N&&q===F&&(a.durationMs??0)<(n.durationMs??0))&&(n=a)}n&&(t.parent=n.id)}for(const t of y)delete t.spanId,delete t.parentSpanId;{const t=new Set(y.map(a=>a.id)),r=new Set,e=new Map,o=[],n=k(a=>{const $=[a];for(;$.length;){const w=$.pop();o.push(w),r.add(w.id);const u=e.get(w.id);if(u){e.delete(w.id);for(let c=u.length-1;c>=0;c--)$.push(u[c])}}},"place");for(const a of y)if(a.parent&&a.parent!==a.id&&t.has(a.parent)&&!r.has(a.parent)){const $=e.get(a.parent)??[];$.push(a),e.set(a.parent,$)}else n(a);for(const a of y)r.has(a.id)||(o.push(a),r.add(a.id));for(let a=0;a<o.length;a++)y[a]=o[a]}const W=new Map;for(const t of y){if(!t.requestId)continue;const r=W.get(t.requestId);r?r.push(t):W.set(t.requestId,[t])}const Y=new Map(y.map(t=>[t.id,t])),U=new Map;for(const t of y)t.calleeRequestId&&!U.has(t.calleeRequestId)&&U.set(t.calleeRequestId,t);const _=k((t,r)=>{const e=(W.get(t)??[]).filter(o=>I(o)&&o.start<=r&&o.start+(o.durationMs??0)>=r);if(e.length!==0)return e.sort((o,n)=>n.start-o.start||(o.durationMs??0)-(n.durationMs??0)),e[0]},"callerNodeFor");for(const t of y){if(!t.parentRequestId||t.kind!=="server-request"&&t.kind!=="gateway-request")continue;const r=t.parent?Y.get(t.parent):void 0;if(r&&r.requestId===t.requestId)continue;const e=t.requestId?U.get(t.requestId):void 0,o=e&&e.start<=t.start?e:_(t.parentRequestId,t.start);o&&o!==t&&o.start<=t.start&&(t.parent=o.id)}const O=y,C=new Map;for(const t of O)t.kind==="gateway-request"&&t.requestId&&!C.has(t.requestId)&&C.set(t.requestId,t);for(const t of O)if(t.group==="server"&&!t.parent&&t.requestId&&t.kind!=="gateway-request"){const r=C.get(t.requestId);r&&r!==t&&r.start<=t.start&&(t.parent=r.id)}const E=new Set,Z=new Set,z=[];for(const t of O){if(t.kind!=="gateway-request")continue;if(!t.requestId){z.push(t);continue}const r=W.get(t.requestId)??[];if(r.filter(n=>n.kind==="gateway-request").sort((n,a)=>n.start-a.start)[0]!==t)continue;const e=r.find(n=>n.kind==="fetch-start"),o=r.find(n=>n.kind==="fetch-done"||n.kind==="fetch-error");if(!e&&!o){z.push(t);continue}e&&(t.fetchStartId=e.id,E.add(e.id)),o&&(t.fetchDoneId=o.id,Z.add(o.id))}const d=new Map;for(const t of O){if(!t.urlKey)continue;const r=d.get(t.urlKey)??{gws:[],starts:[],dones:[]};t.kind==="gateway-request"?z.includes(t)&&r.gws.push(t):t.kind==="fetch-start"?E.has(t.id)||r.starts.push(t):(t.kind==="fetch-done"||t.kind==="fetch-error")&&(Z.has(t.id)||r.dones.push(t)),d.set(t.urlKey,r)}for(const{gws:t,starts:r,dones:e}of d.values()){t.sort((n,a)=>n.start-a.start),r.sort((n,a)=>n.start-a.start);const o=new Set;t.forEach((n,a)=>{const $=r[a];$&&(n.fetchStartId=$.id);const w=$?$.t:n.start;let u,c=1/0;for(const v of e){if(o.has(v.id))continue;const q=v.fetchStartedAt??v.start-(v.durationMs??0),A=Math.abs(q-w);A<c&&(c=A,u=v)}u&&(n.fetchDoneId=u.id,o.add(u.id))})}const m=new Map,B=new Map;for(const t of O)!t.queue||!t.jobId||(t.kind==="queue-enqueued"&&m.set(`${t.queue}#${t.jobId}`,t),t.kind==="queue-process"&&B.set(`${t.queue}#${t.jobId}`,t));for(const t of O){if(!t.queue||!t.jobId)continue;const r=`${t.queue}#${t.jobId}`;if(t.kind==="queue-process"&&!t.parent){const e=m.get(r);e&&e!==t&&e.start<=t.start&&(t.parent=e.id)}else if(t.kind==="queue-active"||t.kind==="queue-completed"||t.kind==="queue-failed"){const e=B.get(r);e&&e!==t&&e.start<=t.start&&(t.parent=e.id)}}{const t=new Map(y.map(r=>[r.id,r]));for(const r of y){if(!r.parent||!Ot.has(r.kind??"")||r.durationMs===void 0)continue;const e=t.get(r.parent);if(!e||e.kind!=="span"||!((e.durationMs??0)>0))continue;const o=Math.round(r.start+r.durationMs-(e.start+e.durationMs));if(o<OUTLIVED_PARENT_MIN_MS)continue;r.outlivedParentMs=o;const n=e.leftRunning??{count:0,longestMs:0};e.leftRunning={count:n.count+1,longestMs:Math.max(n.longestMs,o)}}for(const r of y){const e=[];r.leftRunning&&e.push(`ended before ${r.leftRunning.count===1?"a call":`${r.leftRunning.count} calls`} it started had finished \u2014 ${r.leftRunning.count===1?"it":"the longest"} ran on ${r.leftRunning.longestMs}ms (a timeout that gave up, or work not awaited)`),r.outlivedParentMs!==void 0&&e.push(`ran on ${r.outlivedParentMs}ms after the span that started it had ended`),e.length>0&&(r.detail=[r.detail,...e].filter(Boolean).join(" \xB7 "))}}let h=y;{const t=new Map;for(const e of h)e.kind==="fetch-start"&&t.set(e.id,e);const r=new Map;for(const e of h){if(e.kind!=="fetch-done"&&e.kind!=="fetch-error")continue;const o=[...t.values()].find($=>$.requestId&&$.requestId===e.requestId)?.id,n=o?t.get(o):void 0;if(!n)continue;const a=e.fetchStartedAt??n.start;n.title=e.title,n.severity=e.severity,n.durationMs=e.durationMs??Math.max(0,e.t-a),n.kind="fetch",e.detail&&!n.detail&&(n.detail=e.detail),r.set(e.id,n.id)}if(r.size>0){h=h.filter(e=>!r.has(e.id));for(const e of h)for(e.fetchDoneId&&r.has(e.fetchDoneId)&&(e.fetchDoneId=r.get(e.fetchDoneId));e.parent&&r.has(e.parent);)e.parent=r.get(e.parent)}}const D=k(t=>!!t.commitId&&(t.kind==="render"||t.kind==="effect-run"||t.kind==="render-commit-truncated"),"commitMember"),K=k(t=>[...new Set(t)],"uniq"),st=k(t=>K(t.map(r=>r.component).filter(r=>!!r)),"named"),qt=k(t=>t.length<=2?t.join(" + "):`${t[0]} + ${t.length-1} more`,"nameList"),it=k(t=>{const r=new Map;for(const e of t)e.component&&r.set(e.component,(r.get(e.component)??0)+1);return[...r].map(([e,o])=>o>1?`${e} \xD7${o}`:e).join(", ")},"tally"),It=k(t=>{if(!t)return"effect";const r=/([^/\\]+?):(\d+)(?::\d+)?$/.exec(t);return r?`${r[1]}:${r[2]}`:t},"shortHook"),ot=k(t=>`${It(t.hook)}${t.cleanup?" (cleanup)":""}`,"hookLabel"),dt=k(t=>{const r=Math.min(...t.map(o=>o.start)),e=Math.max(...t.map(o=>o.start+(o.durationMs??0)));return{start:r,durationMs:e-r}},"extent"),ut=k(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 ct(t){const r=t[0],e=t.filter(S=>S.kind==="render"),o=t.filter(S=>S.kind==="effect-run"),n=t.find(S=>S.kind==="render-commit-truncated"),a=[...e].sort((S,X)=>(X.durationMs??0)-(S.durationMs??0)),$=a.filter(S=>(S.why??[]).some(X=>X!=="parent-render")),w=K($.flatMap(S=>(S.why??[]).filter(X=>X!=="parent-render"))),u=st($),c=e.filter(S=>S.phase==="mount"),v=e.filter(S=>S.phase!=="mount"&&!$.includes(S)),q=a[0]?.component??"view",A=e.length>0&&c.length===e.length,x=w.length?w.join(" + "):void 0,F=A?"mount":"update",N=u.length?`view update \xB7 ${qt(u)} \u2190 ${x}`:A?`view mount \xB7 ${q}`:`view update \xB7 ${q}`,Q=n?.renderTotal??e.length,xt=[c.length?`mounted ${it(c)}`:"",v.length?`re-rendered ${it(v)}`:"",!u.length&&!A&&e.length?"trigger not recorded \u2014 every captured render came from its parent":"",n?.renderWalkStoppedAt!==void 0?`at least ${Q} renders (the walk stopped at ${n.renderWalkStoppedAt} fibers), ${n.renderPublished??e.length} recorded`:n?`${Q} renders, ${n.renderPublished??e.length} recorded (per-commit cap)`:`${e.length} render${e.length===1?"":"s"}`,o.length?`${o.length} effect${o.length===1?"":"s"}: ${o.map(ot).join(", ")}`:""].filter(Boolean).join(" \xB7 "),gt=st(e);return ut({...r,...dt(t),kind:"view-update",title:N,detail:xt,commitId:r.commitId,viewPhase:F,...x?{cause:x}:{},causeComponents:u,components:gt,mounted:st(c),renderCount:Q,...n?.renderWalkStoppedAt!==void 0?{renderCountAtLeast:!0}:{},recordedRenders:e.length,effects:o.length,effectHooks:o.map(ot),memberIds:t.map(S=>S.id),sig:`commit:${F}:${x??"-"}:${u.join(",")}:${gt.slice().sort().join(",")}`,severity:t.some(S=>S.severity==="error")?"error":r.severity})}R(ct,"It"),k(ct,"viewUpdateNode");function lt(t){const r=t[0],e=t.map(ot);return ut({...r,...dt(t),kind:"commit-effects",title:t.length===1?`effect \xB7 ${e[0]}`:`effects \xB7 ${e[0]} + ${t.length-1} more`,detail:e.join(", "),commitId:r.commitId,effects:t.length,effectHooks:e,memberIds:t.map(o=>o.id),sig:`effects:${e.slice().sort().join(",")}`})}R(lt,"kt"),k(lt,"effectsNode");const bt=k(t=>K(t.map(r=>r==="state-update"?"state update":r==="fetch-start"?"request":r==="flow-origin"?"interaction":"response")).join(" + "),"describeInputs");function pt(t,r){const e=t[0],o=t[t.length-1],n=t.length,a=e.detail,$=Math.min(...t.map(v=>v.start)),w=Math.max(...t.map(v=>v.start+(v.durationMs??0))),u=Math.round(t.reduce((v,q)=>v+(q.durationMs??0),0)/n*10)/10,c=Math.round((w-$)*10)/10;e.count=n,e.avgMs=u,e.wallMs=c,e.durationMs=w-$,e.items=t.slice(0,12).map(v=>({start:v.start-$,...v.durationMs!=null?{durationMs:v.durationMs}:{}})),e.memberIds=t.flatMap(v=>v.memberIds??[v.id]),e.title=`\xD7${n} ${e.title}`,t.some(v=>v.severity==="error")&&(e.severity="error"),e.kind==="view-update"?e.detail=[`${n} commits, ${r.length?`one per ${bt(r)}`:"back to back"}`,`avg ${u}ms \xB7 wall ${c}ms`,a??""].filter(Boolean).join(" \xB7 "):e.kind==="state-update"&&a&&o.detail?e.detail=`${n} updates in a row \xB7 wall ${c}ms \xB7 first ${a} \xB7 last ${o.detail}`:e.detail=[`${n} in a row \xB7 wall ${c}ms`,a??""].filter(Boolean).join(" \xB7 ")}R(pt,"qt"),k(pt,"collapseRepeat");const tt=[],et=new Map,ft=new Set;for(let t=0;t<h.length;t++){if(ft.has(t))continue;const r=h[t];if(!D(r)){tt.push(r);continue}const e=[t];for(let a=t+1;a<h.length;a++){const $=h[a];if($.group==="browser"){if(!D($)||$.commitId!==r.commitId)break;e.push(a)}}for(const a of e)ft.add(a);const o=e.map(a=>h[a]),n=o.some(a=>a.kind!=="effect-run")?ct(o):lt(o);for(const a of o)a.id!==n.id&&et.set(a.id,n.id);tt.push(n)}if(et.size>0||tt.some(t=>t.kind==="view-update"||t.kind==="commit-effects")){h=tt;for(const t of h)for(;t.parent&&et.has(t.parent);)t.parent=et.get(t.parent)}{const t=new Map;for(const r of h)r.kind==="view-update"&&r.commitId&&!t.has(r.commitId)&&t.set(r.commitId,r);for(const r of h){if(r.kind!=="commit-effects"||r.parent||!r.commitId)continue;const e=t.get(r.commitId);e&&e.start<=r.start&&(r.parent=e.id)}}{const t=new Set(["state-update","fetch","fetch-start","fetch-done","fetch-error","flow-origin"]),r=h.map((u,c)=>u.group==="browser"?c:-1).filter(u=>u>=0),e=k(u=>`${u.kind}|${u.sig??u.title}`,"keyOf"),o=r.map(u=>e(h[u])),n=k((u,c,v)=>{for(let q=0;q<v;q++)if(o[u+q]!==o[c+q])return!1;return!0},"sameBlock"),a=k(u=>o[u].split("|")[0],"kindAt"),$=k(u=>{let c=0,v=1;for(let q=1;q<=4&&u+q<=o.length;q++){let A=1;for(;u+(A+1)*q<=o.length&&n(u,u+A*q,q);)A+=1;A>=3&&q*A>c*v&&(c=q,v=A)}return{k:c,r:v}},"bestBlockAt"),w=new Map;for(let u=0;u<o.length;){const{k:c,r:v}=$(u);if(c===0){u+=1;continue}const q=[...Array(c).keys()].find(x=>t.has(a(u+x)));if(q!==void 0&&q>0){const x=$(u+q);if(x.k===c&&x.r>=3&&x.r>=v-1){u+=q;continue}}const A=o.slice(u,u+c).map(x=>x.split("|")[0]).filter(x=>t.has(x));for(let x=0;x<c;x++){const F=[];for(let N=0;N<v;N++)F.push(h[r[u+x+N*c]]);pt(F,A);for(const N of F.slice(1))w.set(N.id,F[0].id)}u+=c*v}if(w.size>0){h=h.filter(u=>!w.has(u.id));for(const u of h)for(;u.parent&&w.has(u.parent);)u.parent=w.get(u.parent)}}{const t=new Map(h.map(r=>[r.id,r]));for(const r of h){const e=new Set([r.id]);let o=r;for(;o?.parent;){if(e.has(o.parent)){o.parent=void 0;break}e.add(o.parent),o=t.get(o.parent)}}}const mt=k(t=>{const r=new Map;for(const o of h){if(!o.sig||I(o)!==t||o.kind==="server-request"||o.kind==="gateway-request"||o.group==="browser")continue;const n=`${o.parent??"root"}|${o.kind}|${o.sig}`,a=r.get(n);a?a.push(o):r.set(n,[o])}const e=new Map;for(const o of r.values()){if(o.length<3)continue;o.sort((c,v)=>c.start-v.start);const n=o[0];let a=!1;for(let c=0;c+1<o.length;c++)if(o[c+1].start<o[c].start+(o[c].durationMs??0)){a=!0;break}const $=n.start,w=Math.max(...o.map(c=>c.start+(c.durationMs??0))),u=o.reduce((c,v)=>c+(v.durationMs??0),0);n.count=o.length,n.parallel=a,n.avgMs=Math.round(u/o.length*10)/10,n.wallMs=w-$,n.durationMs=w-$,n.title=`\xD7${o.length} ${n.title.replace(/\s*\((?:\d+ rows?, )?\d+ms\)$/,"")}`,n.detail=`${n.sig} \xD7${o.length} ${a?"\u2016 parallel":"\u21BB sequential loop"} \xB7 avg ${n.avgMs}ms \xB7 wall ${n.wallMs}ms`,n.items=o.slice(0,12).map(c=>({start:c.start-$,...c.durationMs!=null?{durationMs:c.durationMs}:{}})),n.memberIds=o.flatMap(c=>c.memberIds??[c.id]),o.some(c=>c.severity==="error")&&(n.severity="error");for(const c of o.slice(1))e.set(c.id,n.id)}if(e.size!==0){h=h.filter(o=>!e.has(o.id));for(const o of h)for(;o.parent&&e.has(o.parent);)o.parent=e.get(o.parent)}},"aggregatePass");mt(!0),mt(!1);for(const t of h){if(!I(t))continue;const r=t.durationMs??0;if(r<40)continue;const e=h.filter(w=>w.parent===t.id&&(w.durationMs??0)>0).map(w=>[w.start,w.start+(w.durationMs??0)]).sort((w,u)=>w[0]-u[0]);let o=0,n=-1,a=-1;for(const[w,u]of e)w>a?(a>n&&(o+=a-n),n=w,a=u):u>a&&(a=u);a>n&&(o+=a-n);const $=Math.max(0,r-o);($>=50||$/r>=.7&&r>=40)&&(t.selfMs=$,t.detail=`\u26A0 cpu-heavy: ${$}ms self-time of ${r}ms${t.detail?" \xB7 "+t.detail:""}`)}return{events:h,...s?{sql:s}:{}}}R(buildFlowDetail,"buildFlowDetail"),k(buildFlowDetail,"buildFlowDetail");
@@ -1 +1 @@
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");
1
+ "use strict";var b=Object.defineProperty;var c=(s,e)=>b(s,"name",{value:e,configurable:!0});var y=Object.defineProperty,l=c((s,e)=>y(s,"name",{value:e,configurable:!0}),"u");import{classifyFlow as $,categoryOfSegment as h}from"./flow-categories.js";import{DEFAULT_SEGMENT_OPTIONS as w,segmentFlow as j}from"./flow-segments.js";export const DEFAULT_FLOWS_CONFIG={categories:[],segments:{},problems:[]};const p=200,f=200,m=64,F=/^[A-Za-z0-9][A-Za-z0-9 ._:/-]*$/,O=["category","flowId","originType","origin","route","project"],A={phaseGapMs:[50,6e5],burstGapMs:[10,6e4],attachWindowMs:[0,6e4],maxSegmentEvents:[20,1e4],occurrenceSlackMs:[0,1e3]},g=l(s=>typeof s=="object"&&s!==null&&!Array.isArray(s),"isObj");function d(s,e){if(!g(s))return{problems:[`${e}: not an object`]};const o=[];for(const t of Object.keys(s))O.includes(t)||o.push(`${e}: unknown field "${t}" ignored`);const n=s.category;if(typeof n!="string"||n.trim()==="")return{problems:[...o,`${e}: "category" must be a non-empty string \u2014 rule dropped`]};const i=n.trim();if(i.length>m||!F.test(i))return{problems:[...o,`${e}: category "${i.slice(0,40)}" is not a usable name (letters, digits, space . _ : / -; up to ${m}) \u2014 rule dropped`]};const u={category:i};let a=0;for(const t of["flowId","originType","origin","route","project"]){const r=s[t];if(r!==void 0){if(typeof r!="string"||r===""||r.length>f)return{problems:[...o,`${e}: "${t}" must be a non-empty string of up to ${f} characters \u2014 rule dropped`]};u[t]=r,a+=1}}return a===0?{problems:[...o,`${e}: "${i}" has no match field (flowId, originType, origin, route or project) \u2014 rule dropped`]}:{rule:u,problems:o}}c(d,"w"),l(d,"parseRule");export function parseFlowsConfig(s){if(s==null)return DEFAULT_FLOWS_CONFIG;if(!g(s))return{...DEFAULT_FLOWS_CONFIG,problems:["lensmcp.flows must be an object \u2014 ignored"]};const e=[],o=[],n=s.categories;n!==void 0&&(Array.isArray(n)?(n.length>p&&e.push(`flows.categories has ${n.length} rules; only the first ${p} are used`),n.slice(0,p).forEach((a,t)=>{const r=d(a,`flows.categories[${t}]`);e.push(...r.problems),r.rule&&o.push(r.rule)})):e.push("flows.categories must be an array \u2014 ignored"));const i={},u=s.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=A[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 (${w[a]})`);continue}i[a]=t}return{categories:o,segments:i,problems:e}}c(parseFlowsConfig,"parseFlowsConfig"),l(parseFlowsConfig,"parseFlowsConfig");export function analyzeFlow(s,e=DEFAULT_FLOWS_CONFIG){const o=j(s,e.segments),n=$(s,o,e.categories),i={};for(const u of o.segments)i[u.id]=h(u,n,e.categories);return{segmentation:o,classification:n,segmentCategories:i}}c(analyzeFlow,"analyzeFlow"),l(analyzeFlow,"analyzeFlow");
@@ -1 +1 @@
1
- "use strict";var I=Object.defineProperty;var l=(o,n)=>I(o,"name",{value:n,configurable:!0});var y=Object.defineProperty,p=l((o,n)=>y(o,"name",{value:n,configurable:!0}),"l"),b=Object.defineProperty,m=p((o,n)=>b(o,"name",{value:n,configurable:!0}),"l");function f(o){const n=o.raw??null,s=n?.kind,d=o.context,a={id:o.id,parentTraceNodeId:d.causedByNodeId??d.originNodeId,lifecycle:"completed",context:d,startTime:o.timestamp,attributes:{...n??{}}};if(o.source==="react"&&s==="render"){const e=n;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=n;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=n;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=n,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:n.loop?.durationMs}};if(s==="flow-origin"&&(o.source==="react"||o.source==="client-runtime")){const e=d.originNodeId??(typeof n?.originNodeId=="string"?n.originNodeId:void 0);return{parentAxis:"caused",node:{...a,parentTraceNodeId:d.causedByNodeId,type:"ui-event",logicalId:e,name:e?`${o.title} ${e}`:o.title}}}if(o.source==="client-runtime"&&s==="user-action"){const e=n;return{parentAxis:"caused",node:{...a,type:"ui-event",logicalId:e.origin?.nodeId,name:e.origin?.label??o.title}}}}l(f,"m"),p(f,"m"),m(f,"eventToNode");export function buildGraphFromEvents(o,n){const s=[...n].sort((r,t)=>r.timestamp-t.timestamp),d=[];for(const r of s){const t=f(r);t&&(o.addNode(t.node),d.push(t))}let a=0;const e=m((r,t,i,u)=>{const g={id:`${i}:${r}->${t}`,from:r,to:t,axis:i,type:u,timestamp:o.getNode(t)?.startTime??0};o.addEdge(g),a++},"addEdge");for(const r of d){const t=r.node.context.causedByNodeId;t&&o.getNode(t)&&e(t,r.node.id,r.parentAxis??"caused","caused-by")}const c=new Map;for(const r of d){const t=r.node.context.flowId;if(!t)continue;let i=c.get(t);i||(i=[],c.set(t,i)),i.push(r)}for(const r of c.values())for(let t=1;t<r.length;t++){const i=r[t-1].node,u=r[t].node;u.context.causedByNodeId!==i.id&&e(i.id,u.id,"caused","flow-sequence")}return{nodeCount:d.length,edgeCount:a}}l(buildGraphFromEvents,"buildGraphFromEvents"),p(buildGraphFromEvents,"buildGraphFromEvents"),m(buildGraphFromEvents,"buildGraphFromEvents");
1
+ "use strict";var g=Object.defineProperty;var l=(t,r)=>g(t,"name",{value:r,configurable:!0});var I=Object.defineProperty,p=l((t,r)=>I(t,"name",{value:r,configurable:!0}),"l");function m(t){const r=t.raw??null,s=r?.kind,d=t.context,a={id:t.id,parentTraceNodeId:d.causedByNodeId??d.originNodeId,lifecycle:"completed",context:d,startTime:t.timestamp,attributes:{...r??{}}};if(t.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(t.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(t.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(s==="flow-origin"&&(t.source==="react"||t.source==="client-runtime")){const e=d.originNodeId??(typeof r?.originNodeId=="string"?r.originNodeId:void 0);return{parentAxis:"caused",node:{...a,parentTraceNodeId:d.causedByNodeId,type:"ui-event",logicalId:e,name:e?`${t.title} ${e}`:t.title}}}if(t.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??t.title}}}}l(m,"m"),p(m,"eventToNode");export function buildGraphFromEvents(t,r){const s=[...r].sort((o,n)=>o.timestamp-n.timestamp),d=[];for(const o of s){const n=m(o);n&&(t.addNode(n.node),d.push(n))}let a=0;const e=p((o,n,i,u)=>{const f={id:`${i}:${o}->${n}`,from:o,to:n,axis:i,type:u,timestamp:t.getNode(n)?.startTime??0};t.addEdge(f),a++},"addEdge");for(const o of d){const n=o.node.context.causedByNodeId;n&&t.getNode(n)&&e(n,o.node.id,o.parentAxis??"caused","caused-by")}const c=new Map;for(const o of d){const n=o.node.context.flowId;if(!n)continue;let i=c.get(n);i||(i=[],c.set(n,i)),i.push(o)}for(const o of c.values())for(let n=1;n<o.length;n++){const i=o[n-1].node,u=o[n].node;u.context.causedByNodeId!==i.id&&e(i.id,u.id,"caused","flow-sequence")}return{nodeCount:d.length,edgeCount:a}}l(buildGraphFromEvents,"buildGraphFromEvents"),p(buildGraphFromEvents,"buildGraphFromEvents");
@@ -1 +1 @@
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}}
1
+ "use strict";var w=Object.defineProperty;var l=(h,e)=>w(h,"name",{value:e,configurable:!0});var p=Object.defineProperty,I=l((h,e)=>p(h,"name",{value:e,configurable:!0}),"l");const m=4,N=1e3;export class GraphStore{static{l(this,"GraphStore")}static{I(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(e){this.nodes.set(e.id,e),e.parentTraceNodeId&&this.addToIndex(this.byParent,e.parentTraceNodeId,e.id),e.context.flowId&&this.addToIndex(this.byFlow,e.context.flowId,e.id),e.logicalId&&this.addToIndex(this.byLogical,e.logicalId,e.id),e.instanceId&&this.addToIndex(this.byInstance,e.instanceId,e.id),e.context.requestId&&this.addToIndex(this.byRequest,e.context.requestId,e.id)}updateNode(e,s){const i=this.nodes.get(e);if(!i)throw new Error(`Unknown node: ${e}`);const t={...i,...s,id:i.id};return this.nodes.set(e,t),t}getNode(e){return this.nodes.get(e)}addEdge(e){this.edges.set(e.id,e);let s=this.outByAxis.get(e.axis);s||(s=new Map,this.outByAxis.set(e.axis,s)),this.addToIndex(s,e.from,e.id);let i=this.inByAxis.get(e.axis);i||(i=new Map,this.inByAxis.set(e.axis,i)),this.addToIndex(i,e.to,e.id)}getEdge(e){return this.edges.get(e)}childrenOf(e){return this.materialiseNodes(this.byParent.get(e))}nodesInFlow(e){return this.materialiseNodes(this.byFlow.get(e))}nodesByLogical(e){return this.materialiseNodes(this.byLogical.get(e))}nodesByInstance(e){return this.materialiseNodes(this.byInstance.get(e))}nodesByRequest(e){return this.materialiseNodes(this.byRequest.get(e))}traverse(e){const s=this.nodes.get(e.from);if(!s)return{nodes:[],edges:[]};const i=Array.isArray(e.lens)?e.lens:[e.lens],t=e.direction??"both",f=e.depth??4,x=e.maxNodes??1e3,n=new Set,g=new Set,c=[{id:s.id,d:0}];for(;c.length&&!(n.size>=x);){const{id:d,d:u}=c.shift();if(!n.has(d)&&(n.add(d),!(u>=f)))for(const y of i){if(t==="out"||t==="both"){const o=this.outByAxis.get(y)?.get(d);if(o)for(const a of o){g.add(a);const r=this.edges.get(a);n.has(r.to)||c.push({id:r.to,d:u+1})}}if(t==="in"||t==="both"){const o=this.inByAxis.get(y)?.get(d);if(o)for(const a of o){g.add(a);const r=this.edges.get(a);n.has(r.from)||c.push({id:r.from,d:u+1})}}}}return{nodes:this.materialiseNodes(n),edges:[...g].map(d=>this.edges.get(d)).filter(d=>!!d)}}nodeCount(){return this.nodes.size}edgeCount(){return this.edges.size}addToIndex(e,s,i){let t=e.get(s);t||(t=new Set,e.set(s,t)),t.add(i)}materialiseNodes(e){if(!e)return[];const s=[];for(const i of e){const t=this.nodes.get(i);t&&s.push(t)}return s}}
@@ -1 +1 @@
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");
1
+ "use strict";var r=Object.defineProperty;var s=(e,t)=>r(e,"name",{value:t,configurable:!0});var a=Object.defineProperty,o=s((e,t)=>a(e,"name",{value:t,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())}s(headlessFlowsEnabled,"headlessFlowsEnabled"),o(headlessFlowsEnabled,"headlessFlowsEnabled");export const HEADLESS_REQUEST_FLOW_PREFIX="api:",HEADLESS_JOB_FLOW_PREFIX="job:";export function headlessFlowId(e){return`${HEADLESS_REQUEST_FLOW_PREFIX}${e}`}s(headlessFlowId,"headlessFlowId"),o(headlessFlowId,"headlessFlowId");export function headlessJobFlowId(e,t){return`${HEADLESS_JOB_FLOW_PREFIX}${e}#${t??"?"}`}s(headlessJobFlowId,"headlessJobFlowId"),o(headlessJobFlowId,"headlessJobFlowId");export function isHeadlessFlowId(e){return e.startsWith(HEADLESS_REQUEST_FLOW_PREFIX)||e.startsWith(HEADLESS_JOB_FLOW_PREFIX)}s(isHeadlessFlowId,"isHeadlessFlowId"),o(isHeadlessFlowId,"isHeadlessFlowId");const n=/^\/(?:[^/?#]+\/)*(?:health|healthz|health-check|healthcheck|ready|readyz|readiness|live|livez|liveness|ping|metrics|favicon\.ico)\/?(?:[?#].*)?$/i;export function isProbePath(e){return e?n.test(e)||e.startsWith("/__lensmcp/"):!1}s(isProbePath,"isProbePath"),o(isProbePath,"isProbePath");
@@ -1 +1 @@
1
- "use strict";var s=Object.defineProperty;var r=(t,e)=>s(t,"name",{value:e,configurable:!0});var h=Object.defineProperty,a=r((t,e)=>h(t,"name",{value:e,configurable:!0}),"n"),p=Object.defineProperty,c=a((t,e)=>p(t,"name",{value:e,configurable:!0}),"n");import*as l from"node:fs";import{dirname as x,join as o}from"node:path";export{isServiceHopHost,LENS_REQUEST_ID_HEADER}from"./service-hop.js";export const HTTP_EXCHANGE_DIR="http",HTTP_EXCHANGE_PLACES=["calls","ai","in","hops"];export function exchangePlace(t){return t.side==="ingress"?"in":t.ai?"ai":/(^|\.)localhost$/i.test(t.host)?"hops":"calls"}r(exchangePlace,"exchangePlace"),a(exchangePlace,"exchangePlace"),c(exchangePlace,"exchangePlace");const E=/^hx_[0-9a-z]{8,40}$/;export const isHttpExchangeId=c(t=>typeof t=="string"&&E.test(t),"isHttpExchangeId");export function httpExchangeDir(t,e="calls"){const n=o(x(t),HTTP_EXCHANGE_DIR);return e==="calls"?n:o(n,e)}r(httpExchangeDir,"httpExchangeDir"),a(httpExchangeDir,"httpExchangeDir"),c(httpExchangeDir,"httpExchangeDir");export function httpExchangeFile(t,e,n="calls"){if(!isHttpExchangeId(e))throw new Error("invalid http exchange id");return o(httpExchangeDir(t,n),`${e}.json`)}r(httpExchangeFile,"httpExchangeFile"),a(httpExchangeFile,"httpExchangeFile"),c(httpExchangeFile,"httpExchangeFile");export function readHttpExchange(t,e){if(isHttpExchangeId(e))for(const n of HTTP_EXCHANGE_PLACES)try{const i=JSON.parse(l.readFileSync(httpExchangeFile(t,e,n),"utf8"));if(i&&i.schemaVersion===1&&i.id===e)return i}catch{}}r(readHttpExchange,"readHttpExchange"),a(readHttpExchange,"readHttpExchange"),c(readHttpExchange,"readHttpExchange");
1
+ "use strict";var i=Object.defineProperty;var n=(t,e)=>i(t,"name",{value:e,configurable:!0});var s=Object.defineProperty,a=n((t,e)=>s(t,"name",{value:e,configurable:!0}),"n");import*as p from"node:fs";import{dirname as h,join as c}from"node:path";export{isServiceHopHost,LENS_REQUEST_ID_HEADER}from"./service-hop.js";export const HTTP_EXCHANGE_DIR="http",HTTP_EXCHANGE_PLACES=["calls","ai","in","hops"];export function exchangePlace(t){return t.side==="ingress"?"in":t.ai?"ai":/(^|\.)localhost$/i.test(t.host)?"hops":"calls"}n(exchangePlace,"exchangePlace"),a(exchangePlace,"exchangePlace");const l=/^hx_[0-9a-z]{8,40}$/;export const isHttpExchangeId=a(t=>typeof t=="string"&&l.test(t),"isHttpExchangeId");export function httpExchangeDir(t,e="calls"){const r=c(h(t),HTTP_EXCHANGE_DIR);return e==="calls"?r:c(r,e)}n(httpExchangeDir,"httpExchangeDir"),a(httpExchangeDir,"httpExchangeDir");export function httpExchangeFile(t,e,r="calls"){if(!isHttpExchangeId(e))throw new Error("invalid http exchange id");return c(httpExchangeDir(t,r),`${e}.json`)}n(httpExchangeFile,"httpExchangeFile"),a(httpExchangeFile,"httpExchangeFile");export function readHttpExchange(t,e){if(isHttpExchangeId(e))for(const r of HTTP_EXCHANGE_PLACES)try{const o=JSON.parse(p.readFileSync(httpExchangeFile(t,e,r),"utf8"));if(o&&o.schemaVersion===1&&o.id===e)return o}catch{}}n(readHttpExchange,"readHttpExchange"),a(readHttpExchange,"readHttpExchange");
package/lib/http-shape.js CHANGED
@@ -1 +1 @@
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");
1
+ "use strict";var v=Object.defineProperty;var m=(e,r)=>v(e,"name",{value:r,configurable:!0});var k=Object.defineProperty,l=m((e,r)=>k(e,"name",{value:r,configurable:!0}),"a");import{isSecretParam as j}from"./redact.js";const b=6,d=60,S=4,M=[["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(e){for(const[r,n]of M)if(n.test(e))return r}m(stringFormat,"stringFormat"),l(stringFormat,"stringFormat");const x=l(e=>e.length>64||/\s/.test(e)||stringFormat(e)!==void 0&&!/^[a-z]/i.test(e)||/@/.test(e)||/^[0-9a-f]{8}-/i.test(e),"dataKey");export function shapeOf(e,r=0,n=!1){if(e==null)return{t:"null"};if(typeof e=="boolean")return{t:"bool"};if(typeof e=="number")return Number.isInteger(e)?{t:"num",int:!0}:{t:"num"};if(typeof e=="bigint")return{t:"num",int:!0};if(typeof e=="string"){const t=stringFormat(e);return{t:"str",...t?{f:t}:{},...n?{}:{max:e.length}}}if(e instanceof Date)return{t:"str",f:"date-time"};if(r>=b)return Array.isArray(e)?{t:"arr",n:[e.length,e.length]}:{t:"obj",fields:[]};if(Array.isArray(e)){const t=e.slice(0,20).map(o=>shapeOf(o,r+1,n)).reduce((o,i)=>o?mergeShapes(o,i):i,void 0);return{t:"arr",n:[e.length,e.length],...t?{of:t}:{}}}if(typeof e=="object"){const t=Object.entries(e).filter(([,o])=>typeof o!="function");if(t.length&&t.some(([o])=>x(o))){const o=t.slice(0,20).map(([,s])=>shapeOf(s,r+1,n)).reduce((s,c)=>s?mergeShapes(s,c):c,void 0),i=t.map(([s])=>stringFormat(s)).find(Boolean);return{t:"map",n:[t.length,t.length],...i?{key:i}:{},...o?{of:o}:{}}}return{t:"obj",fields:t.slice(0,d).map(([o,i])=>{const s=j(o);return{...shapeOf(i,r+1,n||s),name:o,...s?{cred:!0}:{}}}),...t.length>d?{more:t.length-d}:{}}}return{t:"null"}}m(shapeOf,"shapeOf"),l(shapeOf,"shapeOf");const $=l((e,r)=>e.t===r.t,"same"),F=new Set(["null","bool","num","str","arr","obj","map","any"]);export function isShape(e,r=0){if(!e||typeof e!="object"||r>b*2)return!1;const n=e;return typeof n.t!="string"||!F.has(n.t)?!1:n.t==="obj"?Array.isArray(n.fields)&&n.fields.every(t=>typeof t?.name=="string"&&isShape(t,r+1)):n.t==="any"?Array.isArray(n.of)&&n.of.every(t=>isShape(t,r+1)):n.t==="arr"||n.t==="map"?Array.isArray(n.n)&&(n.of===void 0||isShape(n.of,r+1)):!0}m(isShape,"isShape"),l(isShape,"isShape");export function fieldShape(e){const r={...e};return delete r.name,delete r.opt,delete r.cred,r}m(fieldShape,"fieldShape"),l(fieldShape,"fieldShape");export function mergeShapes(e,r){if(e.t==="any"||r.t==="any"){const n=[...e.t==="any"?e.of:[e],...r.t==="any"?r.of:[r]],t=[];for(const o of n){const i=t.findIndex(s=>$(s,o));i>=0?t[i]=mergeShapes(t[i],o):t.push(o)}return t.length===1?t[0]:{t:"any",of:t.slice(0,S)}}if(!$(e,r))return{t:"any",of:[e,r]};switch(e.t){case"num":return e.int&&r.int?e:{t:"num"};case"str":{const n=r,t=e.f===n.f?e.f:void 0;return{t:"str",...t?{f:t}:{},...e.max!==void 0||n.max!==void 0?{max:Math.max(e.max??0,n.max??0)}:{}}}case"arr":{const n=r,t=e.of&&n.of?mergeShapes(e.of,n.of):e.of??n.of;return{t:"arr",n:[Math.min(e.n[0],n.n[0]),Math.max(e.n[1],n.n[1])],...t?{of:t}:{}}}case"map":{const n=r,t=e.of&&n.of?mergeShapes(e.of,n.of):e.of??n.of;return{t:"map",n:[Math.min(e.n[0],n.n[0]),Math.max(e.n[1],n.n[1])],...e.key===n.key&&e.key?{key:e.key}:{},...t?{of:t}:{}}}case"obj":{const n=r,t=new Map(e.fields.map(c=>[c.name,c])),o=new Map(n.fields.map(c=>[c.name,c])),i=[...new Set([...t.keys(),...o.keys()])].slice(0,d).map(c=>{const f=t.get(c),u=o.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(e.more??0,n.more??0);return{t:"obj",fields:i,...s?{more:s}:{}}}default:return e}}m(mergeShapes,"mergeShapes"),l(mergeShapes,"mergeShapes");export function shapeText(e,r=0){switch(e.t){case"null":return"null";case"bool":return"boolean";case"num":return e.int?"int":"number";case"str":return e.f?`string(${e.f})`:"string";case"arr":return`[${e.n[0]===e.n[1]?e.n[0]:`${e.n[0]}..${e.n[1]}`}]${e.of?` ${shapeText(e.of,r+1)}`:""}`;case"map":return`map<${e.key??"string"}, ${e.of?shapeText(e.of,r+1):"?"}> (${e.n[0]===e.n[1]?e.n[0]:`${e.n[0]}..${e.n[1]}`} entries)`;case"any":return e.of.map(n=>shapeText(n,r)).join(" | ");case"obj":return`{ ${e.fields.map(n=>`${n.name}${n.opt?"?":""}${n.cred?" (credential-named)":""}: ${shapeText(fieldShape(n),r+1)}`).join(", ")}${e.more?`, \u2026 ${e.more} more`:""} }`}}m(shapeText,"shapeText"),l(shapeText,"shapeText");const a=l((e,r)=>{const n=e[r]??e[r.toLowerCase()];return n===void 0?void 0:Array.isArray(n)?n.join(", "):String(n)},"h"),y=l(e=>e?.split(";")[0]?.trim().toLowerCase()||void 0,"media");export function requestFacts(e,r,n){const t=a(e,"authorization")?.split(/\s+/)[0],o=a(e,"cookie"),i=Number(a(e,"content-length")),s=r?Object.keys(r).filter(f=>!x(f)).slice(0,30):[],c=n?Object.keys(n).slice(0,10):[];return{...y(a(e,"content-type"))?{contentType:y(a(e,"content-type"))}:{},...a(e,"accept")?{accept:a(e,"accept").slice(0,80)}:{},...t?{scheme:/^[A-Za-z][\w-]{1,20}$/.test(t)?t:"other"}:{},...o?{cookies:o.split(";").filter(f=>f.includes("=")).length}:{},...a(e,"if-match")?{ifMatch:!0}:{},...a(e,"if-none-match")?{ifNoneMatch:!0}:{},...a(e,"idempotency-key")?{idempotencyKey:!0}:{},...a(e,"origin")?{origin:!0}:{},...Number.isFinite(i)&&i>0?{bytes:i}:{},...s.length?{query:s}:{},...c.length?{params:c}:{}}}m(requestFacts,"requestFacts"),l(requestFacts,"requestFacts");export function responseFacts(e,r){const n=a(e,"etag"),t=Number(a(e,"content-length")),o=e["set-cookie"],i=(Array.isArray(o)?o:o!==void 0?[String(o)]:[]).slice(0,10).map(c=>{const[f="",...u]=c.split(";").map(h=>h.trim()),p=l(h=>u.find(A=>A.toLowerCase().startsWith(h)),"a"),g=p("samesite")?.split("=")[1],w=p("path=")?.slice(5);return{name:f.split("=")[0].slice(0,40),...p("secure")?{secure:!0}:{},...p("httponly")?{httpOnly:!0}:{},...g?{sameSite:g}:{},...p("domain=")?{domain:!0}:{},...w?{path:w}:{},...p("max-age=")?{maxAge:!0}:{},...p("expires=")?{expires:!0}:{}}}),s=a(e,"access-control-allow-origin");return{...y(a(e,"content-type"))?{contentType:y(a(e,"content-type"))}:{},...Number.isFinite(t)&&t>=0&&a(e,"content-length")!==void 0?{bytes:t}:{},...a(e,"cache-control")?{cacheControl:a(e,"cache-control").slice(0,120)}:{},...n?{etag:n.startsWith("W/")?"weak":"strong"}:{},...a(e,"last-modified")?{lastModified:!0}:{},...a(e,"location")?{location:!0}:{},...a(e,"vary")?{vary:a(e,"vary").slice(0,120)}:{},...a(e,"retry-after")?{retryAfter:!0}:{},...a(e,"www-authenticate")?{wwwAuthenticate:a(e,"www-authenticate").split(/\s+/)[0].slice(0,20)}:{},...a(e,"allow")?{allow:a(e,"allow").slice(0,80)}:{},...i.length?{cookies:i}:{},...s?{cors:{origin:s==="*"?"*":r&&s===r?"echoed":"fixed",...a(e,"access-control-allow-credentials")==="true"?{creds:!0}:{},...a(e,"access-control-allow-methods")?{methods:a(e,"access-control-allow-methods").slice(0,80)}:{},...a(e,"access-control-allow-headers")?{headers:a(e,"access-control-allow-headers").slice(0,120)}:{}}}:{},...a(e,"strict-transport-security")?{hsts:!0}:{},...a(e,"x-content-type-options")?{nosniff:!0}:{},...a(e,"x-powered-by")||a(e,"server")?{poweredBy:!0}:{},...a(e,"deprecation")?{deprecation:!0}:{},...a(e,"sunset")?{sunset:!0}:{},...a(e,"ratelimit")||a(e,"ratelimit-policy")||a(e,"x-ratelimit-limit")?{rateLimit:!0}:{},...a(e,"x-request-id")?{requestId:!0}:{}}}m(responseFacts,"responseFacts"),l(responseFacts,"responseFacts");
@@ -1 +1 @@
1
- "use strict";var f=Object.defineProperty;var r=(e,a)=>f(e,"name",{value:a,configurable:!0});var c=Object.defineProperty,t=r((e,a)=>c(e,"name",{value:a,configurable:!0}),"r"),l=Object.defineProperty,n=t((e,a)=>l(e,"name",{value:a,configurable:!0}),"e");const o=/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;export function foldKeyPattern(e){return e.replace(o,"*").replace(/(?<=^|[:=/])(?=[A-Za-z0-9_-]*\d)(?=[A-Za-z0-9_-]*[A-Za-z])[A-Za-z0-9_-]{16,}(?=$|[:=/])/g,"*").replace(/(?<![A-Za-z])(?=[0-9a-f]*\d)[0-9a-f]{8,}(?![A-Za-z])/gi,"*").replace(/(?<![A-Za-z0-9])\d{2,}(?![A-Za-z0-9])/g,"*").replace(/\*(?:[_-]?\*)+/g,"*")}r(foldKeyPattern,"foldKeyPattern"),t(foldKeyPattern,"foldKeyPattern"),n(foldKeyPattern,"foldKeyPattern");
1
+ "use strict";var f=Object.defineProperty;var r=(a,e)=>f(a,"name",{value:e,configurable:!0});var t=Object.defineProperty,c=r((a,e)=>t(a,"name",{value:e,configurable:!0}),"e");const l=/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;export function foldKeyPattern(a){return a.replace(l,"*").replace(/(?<=^|[:=/])(?=[A-Za-z0-9_-]*\d)(?=[A-Za-z0-9_-]*[A-Za-z])[A-Za-z0-9_-]{16,}(?=$|[:=/])/g,"*").replace(/(?<![A-Za-z])(?=[0-9a-f]*\d)[0-9a-f]{8,}(?![A-Za-z])/gi,"*").replace(/(?<![A-Za-z0-9])\d{2,}(?![A-Za-z0-9])/g,"*").replace(/\*(?:[_-]?\*)+/g,"*")}r(foldKeyPattern,"foldKeyPattern"),c(foldKeyPattern,"foldKeyPattern");
package/lib/lens-dir.js CHANGED
@@ -1 +1 @@
1
- "use strict";var t=Object.defineProperty;var i=(e,r)=>t(e,"name",{value:r,configurable:!0});var a=Object.defineProperty,n=i((e,r)=>a(e,"name",{value:r,configurable:!0}),"r"),s=Object.defineProperty,o=n((e,r)=>s(e,"name",{value:r,configurable:!0}),"r");export const LENS_SHARED_DIRS=["sql-review","route-review","flow-review","ui-review","cache-review","queue-review","ai-review","ai-names","team","team-design"];export function lensGitignoreLines(e="**/"){return[`${e}.lensmcp/*`,...LENS_SHARED_DIRS.map(r=>`!${e}.lensmcp/${r}/`)]}i(lensGitignoreLines,"lensGitignoreLines"),n(lensGitignoreLines,"lensGitignoreLines"),o(lensGitignoreLines,"lensGitignoreLines");
1
+ "use strict";var n=Object.defineProperty;var r=(e,i)=>n(e,"name",{value:i,configurable:!0});var t=Object.defineProperty,a=r((e,i)=>t(e,"name",{value:i,configurable:!0}),"r");export const LENS_SHARED_DIRS=["sql-review","route-review","flow-review","ui-review","cache-review","queue-review","ai-review","ai-names","team","team-design"];export function lensGitignoreLines(e="**/"){return[`${e}.lensmcp/*`,...LENS_SHARED_DIRS.map(i=>`!${e}.lensmcp/${i}/`)]}r(lensGitignoreLines,"lensGitignoreLines"),a(lensGitignoreLines,"lensGitignoreLines");
@@ -1,2 +1,2 @@
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");
1
+ "use strict";var p=Object.defineProperty;var t=(n,e)=>p(n,"name",{value:e,configurable:!0});var E=Object.defineProperty,r=t((n,e)=>E(n,"name",{value:e,configurable:!0}),"o");import{appendFileSync as m,closeSync as d,mkdirSync as S,openSync as v,renameSync as y,statSync as f,unlinkSync as I}from"node:fs";import{dirname as N,join as _}from"node:path";import{ERROR_DISMISSED as o,ERROR_RESTORED as a,LENS_EVENT_SOURCE as g}from"@lensmcp/protocol-types";import{rotateBusFile as R}from"./bus-rotation.js";import{ulid as b}from"./ulid.js";export function lensEventFile(n=process.env,e=process.cwd()){return n.LENSMCP_EVENT_FILE??_(e,".lensmcp","events.jsonl")}t(lensEventFile,"lensEventFile"),r(lensEventFile,"lensEventFile");const c=r((n,e,s,i,l)=>({id:b(),sessionId:n,timestamp:e,source:g,category:"runtime",severity:"info",context:{sessionId:n},fingerprint:s,title:i,raw:l}),"lensEvent");export function dismissalEvent(n,e){return c(e,n.until,`${o}:${n.groupId}`,`error dismissed: ${n.title??n.groupId}`,{kind:o,groupId:n.groupId,until:n.until,eventIds:n.eventIds,...n.by?{by:n.by}:{},...n.reason?{reason:n.reason}:{},...n.title?{title:n.title}:{}})}t(dismissalEvent,"dismissalEvent"),r(dismissalEvent,"dismissalEvent");export function restoralEvent(n,e,s){return c(e,s,`${a}:${n}`,"error restored",{kind:a,groupId:n})}t(restoralEvent,"restoralEvent"),r(restoralEvent,"restoralEvent");const u=r((n,e,s)=>{const i=Number(process.env[n]);return Number.isFinite(i)&&s(i)?i:e},"envNumber");export function appendBusEvents(n,e){e.length!==0&&(S(N(n),{recursive:!0}),R(n,{maxBytes:u("LENSMCP_EVENT_MAX_BYTES",50*1024*1024,s=>s>0),maxFiles:u("LENSMCP_EVENT_MAX_FILES",5,s=>s>=1&&s<=20),fs:{statSync:f,renameSync:y,unlinkSync:I,openSync:v,closeSync:d}}),m(n,e.map(s=>JSON.stringify(s)+`
2
+ `).join("")))}t(appendBusEvents,"appendBusEvents"),r(appendBusEvents,"appendBusEvents");
package/lib/patterns.js CHANGED
@@ -1 +1 @@
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");
1
+ "use strict";var w=Object.defineProperty;var u=(i,n)=>w(i,"name",{value:n,configurable:!0});var y=Object.defineProperty,p=u((i,n)=>y(i,"name",{value:n,configurable:!0}),"l");export function detectDbInLoop(i,n={}){const r=n.threshold??5,d=[];for(const t of i){const e=t.raw??null;if(e?.kind!=="loop"||!e.loop)continue;const s=e.loop.dbCallsInsideLoop??0;s>r&&d.push({kind:"db-in-loop",severity:"warning",title:`${s} DB calls inside a loop (${e.loop.iterations??"?"} iterations)`,evidence:[t.id],details:{dbCallsInsideLoop:s,iterations:e.loop.iterations,durationMs:e.loop.durationMs,threshold:r},detectedAt:t.timestamp})}return d}u(detectDbInLoop,"detectDbInLoop"),p(detectDbInLoop,"detectDbInLoop");const j=new Set(["egress","db-query","redis-op","ai-call"]);function b(i){const n=i.raw??null;if(!n||typeof n.kind!="string"||!j.has(n.kind))return;const r=typeof n.durationMs=="number"?n.durationMs:void 0;if(r===void 0)return;const d=typeof n.startedAt=="number"?n.startedAt:i.timestamp-r,t=i.context??{};return{id:i.id,start:d,end:d+r,label:i.title,...typeof t.requestId=="string"?{requestId:t.requestId}:{},...typeof n.project=="string"?{project:n.project}:typeof t.projectName=="string"?{project:t.projectName}:{}}}u(b,"M"),p(b,"timedCall");function g(i){const n=i.raw??null,r=n?.kind==="span"?n.span:void 0;if(!r||typeof r.name!="string"||r.name.startsWith("nest.request "))return;const d=typeof r.durationMs=="number"?r.durationMs:void 0;if(d===void 0||d<=0)return;const t=typeof r.startTime=="number"?r.startTime:i.timestamp-d,e=i.context??{};return{id:i.id,start:t,end:t+d,label:r.name,...typeof e.requestId=="string"?{requestId:e.requestId}:{},...typeof n?.project=="string"?{project:n.project}:typeof e.projectName=="string"?{project:e.projectName}:{}}}u(g,"b"),p(g,"timedSpan");export function abandonedAwaitOf(i,n,r={}){const d=r.thresholdMs??250,t=b(i);if(!t||!t.requestId||t.end-t.start<d)return;let e;for(const o of n){const a=g(o);!a||a.requestId!==t.requestId||a.project!==void 0&&t.project!==void 0&&a.project!==t.project||a.start>t.start||a.end<=t.start||(!e||a.start>e.start||a.start===e.start&&a.end<e.end)&&(e=a)}if(!e)return;const s=Math.round(t.end-e.end);if(!(s<d))return{kind:"abandoned-await",severity:"warning",title:`${e.label} ended ${s}ms before a call it started had finished (${t.label})`,evidence:[e.id,t.id],details:{span:e.label,call:t.label,ranOnMs:s,spanMs:Math.round(e.end-e.start),callMs:Math.round(t.end-t.start),thresholdMs:d,...t.project?{project:t.project}:{}},detectedAt:i.timestamp}}u(abandonedAwaitOf,"abandonedAwaitOf"),p(abandonedAwaitOf,"abandonedAwaitOf");export function detectAbandonedAwait(i,n={}){const r=[];for(const d of i){const t=abandonedAwaitOf(d,i,n);t&&r.push(t)}return r}u(detectAbandonedAwait,"detectAbandonedAwait"),p(detectAbandonedAwait,"detectAbandonedAwait");export function detectNPlusOne(i,n={}){const r=n.threshold??3,d=new Map;for(const e of i){const s=e.raw??null;if(s?.kind!=="db-query"||!s.query?.signature)continue;const o=s.query.signature;let a=d.get(o);a||(a=[],d.set(o,a)),a.push(e)}const t=[];for(const[e,s]of d)s.length>=r&&t.push({kind:"n+1-query",severity:"warning",title:`Query repeated ${s.length}\xD7 \u2014 likely N+1`,evidence:s.map(o=>o.id),details:{signature:e,count:s.length,threshold:r},detectedAt:s[s.length-1].timestamp});return t}u(detectNPlusOne,"detectNPlusOne"),p(detectNPlusOne,"detectNPlusOne");export function detectRenderStorm(i,n={}){const r=n.threshold??5,d=n.windowMs??250,t=new Map;for(const s of i){if(s.source!=="react")continue;const o=s.raw??null;if(o?.kind!=="render"||!o.render?.componentInstanceId)continue;const a=o.render.componentInstanceId;let c=t.get(a);c||(c=[],t.set(a,c)),c.push(s)}const e=[];for(const[s,o]of t){o.sort((c,f)=>c.timestamp-f.timestamp);let a=0;for(let c=0;c<o.length;c++){for(;o[c].timestamp-o[a].timestamp>d;)a++;const f=c-a+1;if(f>r){const l=o.slice(a,c+1),m=l[0].raw.render?.componentName??s;e.push({kind:"render-storm",severity:"warning",title:`${m} rendered ${f}\xD7 in ${d}ms`,evidence:l.map(h=>h.id),details:{componentInstanceId:s,count:f,windowMs:d,threshold:r},detectedAt:l[l.length-1].timestamp});break}}}return e}u(detectRenderStorm,"detectRenderStorm"),p(detectRenderStorm,"detectRenderStorm");export function findSlowPath(i,n,r){const d=new Map,t=new Set;function e(o){const a=d.get(o);if(a)return a;if(t.has(o))return{path:[o],totalDurationMs:r(o)};t.add(o);const c=r(o),f=n.get(o)??[];let l;for(const h of f){const M=e(h);(!l||M.totalDurationMs>l.totalDurationMs)&&(l=M)}t.delete(o);const m=l?{path:[o,...l.path],totalDurationMs:c+l.totalDurationMs}:{path:[o],totalDurationMs:c};return d.set(o,m),m}u(e,"e"),p(e,"best");let s={path:[],totalDurationMs:0};for(const o of i){const a=e(o);a.totalDurationMs>s.totalDurationMs&&(s=a)}return s}u(findSlowPath,"findSlowPath"),p(findSlowPath,"findSlowPath");
package/lib/pg-errors.js CHANGED
@@ -1 +1 @@
1
- "use strict";var u=Object.defineProperty;var t=(o,e)=>u(o,"name",{value:e,configurable:!0});var l=Object.defineProperty,a=t((o,e)=>l(o,"name",{value:e,configurable:!0}),"n"),f=Object.defineProperty,p=a((o,e)=>f(o,"name",{value:e,configurable:!0}),"t");export const PG_CONNECT_MEANING={"pool-wait-timeout":"waited for a free connection in the service\u2019s own pool and the wait ran out \u2014 not Postgres refusing","connect-timeout":"opening a new connection to Postgres took longer than the limit","server-full":"Postgres is at its max_connections and refused a new connection","server-unreachable":"nothing answered at the database\u2019s address","pool-ended":"the code used a pool that had already been closed (an app being shut down)","auth-failed":"Postgres refused the user or password"};const r=[["pool-wait-timeout",/timeout exceeded when trying to connect/i],["connect-timeout",/Connection terminated due to connection timeout/i],["server-full",/sorry, too many clients already|remaining connection slots are reserved|too many connections for role/i],["pool-ended",/Cannot use a pool after calling end on the pool/i],["auth-failed",/password authentication failed|no pg_hba\.conf entry/i],["server-unreachable",/connect (ECONNREFUSED|EHOSTUNREACH|ETIMEDOUT)|getaddrinfo ENOTFOUND/i]],s={53300:"server-full","28P01":"auth-failed",28e3:"auth-failed",ECONNREFUSED:"server-unreachable",EHOSTUNREACH:"server-unreachable",ENOTFOUND:"server-unreachable"};export const PG_CONNECT_TEXT=new RegExp(r.map(([,o])=>o.source).join("|"),"i");export function pgConnectReason(o){const e=o,n=typeof e=="object"&&e&&typeof e.code=="string"?e.code:void 0;if(n&&s[n])return s[n];const i=typeof e=="string"?e:typeof e=="object"&&e&&typeof e.message=="string"?e.message:"";for(const[c,d]of r)if(d.test(i))return c}t(pgConnectReason,"pgConnectReason"),a(pgConnectReason,"pgConnectReason"),p(pgConnectReason,"pgConnectReason");
1
+ "use strict";var d=Object.defineProperty;var n=(o,e)=>d(o,"name",{value:e,configurable:!0});var u=Object.defineProperty,l=n((o,e)=>u(o,"name",{value:e,configurable:!0}),"t");export const PG_CONNECT_MEANING={"pool-wait-timeout":"waited for a free connection in the service\u2019s own pool and the wait ran out \u2014 not Postgres refusing","connect-timeout":"opening a new connection to Postgres took longer than the limit","server-full":"Postgres is at its max_connections and refused a new connection","server-unreachable":"nothing answered at the database\u2019s address","pool-ended":"the code used a pool that had already been closed (an app being shut down)","auth-failed":"Postgres refused the user or password"};const a=[["pool-wait-timeout",/timeout exceeded when trying to connect/i],["connect-timeout",/Connection terminated due to connection timeout/i],["server-full",/sorry, too many clients already|remaining connection slots are reserved|too many connections for role/i],["pool-ended",/Cannot use a pool after calling end on the pool/i],["auth-failed",/password authentication failed|no pg_hba\.conf entry/i],["server-unreachable",/connect (ECONNREFUSED|EHOSTUNREACH|ETIMEDOUT)|getaddrinfo ENOTFOUND/i]],r={53300:"server-full","28P01":"auth-failed",28e3:"auth-failed",ECONNREFUSED:"server-unreachable",EHOSTUNREACH:"server-unreachable",ENOTFOUND:"server-unreachable"};export const PG_CONNECT_TEXT=new RegExp(a.map(([,o])=>o.source).join("|"),"i");export function pgConnectReason(o){const e=o,t=typeof e=="object"&&e&&typeof e.code=="string"?e.code:void 0;if(t&&r[t])return r[t];const s=typeof e=="string"?e:typeof e=="object"&&e&&typeof e.message=="string"?e.message:"";for(const[i,c]of a)if(c.test(s))return i}n(pgConnectReason,"pgConnectReason"),l(pgConnectReason,"pgConnectReason");
package/lib/redact.js CHANGED
@@ -1 +1 @@
1
- "use strict";var v=Object.defineProperty;var f=(e,t)=>v(e,"name",{value:t,configurable:!0});var I=Object.defineProperty,u=f((e,t)=>I(e,"name",{value:t,configurable:!0}),"f"),P=Object.defineProperty,l=u((e,t)=>P(e,"name",{value:t,configurable:!0}),"a");export const REDACTED="REDACTED",MAX_TITLE_CHARS=300,MAX_MESSAGE_CHARS=4096,MAX_URL_CHARS=1024;const Z=["token","secret","password","passwd","apikey","credential","assertion","signature"],R=new Set(["key","auth","authorization","jwt","code","sig","pwd","pass","session","sid","bearer","otp","cookie","set-cookie"]),C=/^(?:(?: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(e){const t=h.get(e);if(t!==void 0)return t;const r=A(e);return e.length<=64&&h.size<N&&h.set(e,r),r}f(isSecretParam,"isSecretParam"),u(isSecretParam,"isSecretParam"),l(isSecretParam,"isSecretParam");const O=new Set(["sess","csrf","xsrf","refresh","nonce","reset","magic","mfa","2fa","verify","verification","invite","login"]);export function isSecretCacheKey(e){for(const t of e.split(/[:/{}#]+/))if(!(!t||t.length>64)){if(isSecretParam(t))return!0;for(const r of t.toLowerCase().split(/[-_.]+/))if(O.has(r))return!0}return!1}f(isSecretCacheKey,"isSecretCacheKey"),u(isSecretCacheKey,"isSecretCacheKey"),l(isSecretCacheKey,"isSecretCacheKey");const N=4096,h=new Map;function A(e){const t=e.toLowerCase();if(C.test(t.replace(/[-_.]+/g,"")))return!1;if(Z.some(r=>t.includes(r)))return!0;for(const r of t.split(/[-_.]+/))if(r&&R.has(r))return!0;return!1}f(A,"m"),u(A,"N"),l(A,"judgeParam");const D=/^([a-z][a-z0-9+.-]*:\/\/)[^/?#@\s]*@/i,U=/([?&#])([^=&#\s]+)=([^&#\s]*)/g;export function redactUrlParams(e){return e&&e.replace(D,`$1${REDACTED}@`).replace(U,(t,r,n)=>isSecretParam(n)?`${r}${n}=${REDACTED}`:t)}f(redactUrlParams,"redactUrlParams"),u(redactUrlParams,"redactUrlParams"),l(redactUrlParams,"redactUrlParams");export function redactUrl(e){return e&&clip(redactUrlParams(e),1024)}f(redactUrl,"redactUrl"),u(redactUrl,"redactUrl"),l(redactUrl,"redactUrl");const K=/\beyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]*/g,M=/\b(bearer|basic)\s+[A-Za-z0-9._~+/=-]{8,}/gi,j=/\b(authorization|x-api-key|api-key|cookie|set-cookie|proxy-authorization)\b(\s*[:=]\s*)(["']?)((?:(?:bearer|basic)\s+)?[^\s"',;]{4,})\3/gi,L=/[@=:]|eyJ|bearer|basic/i;export function redactText(e){return L.test(e)?redactUrlParams(e).replace(j,(t,r,n,o)=>`${r}${n}${o}${REDACTED}${o}`).replace(K,REDACTED).replace(M,(t,r)=>`${r} ${REDACTED}`):e}f(redactText,"redactText"),u(redactText,"redactText"),l(redactText,"redactText");const q=[/\bsk-(?:ant-|proj-|live-|test-)?[A-Za-z0-9_-]{20,}/g,/\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,/\bgh[pousr]_[A-Za-z0-9]{30,}/g,/\bxox[abprs]-[A-Za-z0-9-]{10,}/g,/\bAIza[0-9A-Za-z_-]{35}\b/g],x="-----BEGIN ",H=4096;function m(e){if(!e.includes("PRIVATE KEY-----"))return e;let t="",r=0,n=!1;for(;;){const o=e.indexOf(x,r);if(o===-1)break;const c=e.indexOf("-----",o+x.length);if(c===-1)break;const s=e.slice(o+x.length,c);if(!/^[A-Z ]{0,30}PRIVATE KEY$/.test(s)){t+=e.slice(r,c+5),r=c+5;continue}t+=e.slice(r,o);const i=n?-1:e.indexOf("-----END ",c+5);let a;if(i===-1)n=!0,a=Math.min(e.length,c+5+H);else{const p=e.indexOf("-----",i+9);a=p===-1?e.length:p+5}t+=REDACTED,r=a}return t+e.slice(r)}f(m,"S"),u(m,"y"),l(m,"redactPrivateKeys");const V=/"([A-Za-z0-9_.-]{1,64})"\s*:\s*"((?:[^"\\]|\\.){1,8192})"/g,X=/\b([A-Za-z][A-Za-z0-9_-]{1,40})(\s*[:=]\s*)([^\s"'`,;&)}\]]{8,200})/g,G=/(token|secret|pass(?:word|wd)?|pwd|api[-_]?key|apikey|credential|authorization|bearer)/i;function b(e){return e.replace(V,(t,r)=>isSecretParam(r)?`"${r}": "${REDACTED}"`:t).replace(X,(t,r,n)=>G.test(r)&&isSecretParam(r)?`${r}${n}${REDACTED}`:t)}f(b,"w"),u(b,"U"),l(b,"redactStructured");export function redactSecretText(e){let t=b(redactText(m(e)));for(const r of q)t=t.replace(r,REDACTED);return t}f(redactSecretText,"redactSecretText"),u(redactSecretText,"redactSecretText"),l(redactSecretText,"redactSecretText");export function clip(e,t){return e.length<=t?e:`${e.slice(0,t)}\u2026[lensmcp truncated: ${e.length-t} more chars]`}f(clip,"clip"),u(clip,"clip"),l(clip,"clip");export function safeText(e,t=4096){if(e!==void 0)return clip(redactText(e),t)}f(safeText,"safeText"),u(safeText,"safeText"),l(safeText,"safeText");export function safeTitle(e){return clip(redactText(e),300)}f(safeTitle,"safeTitle"),u(safeTitle,"safeTitle"),l(safeTitle,"safeTitle");const J=6,Y=64,B=/^TS\d{1,5}$/,F=l((e,t)=>e==="code"&&typeof t=="string"&&B.test(t),"isDiagnosticCode");export function redactDeep(e,t=0,r=J){if(typeof e=="string")return redactText(e);if(e===null||typeof e!="object"||t>=r)return e;if(Array.isArray(e)){let s;for(let i=0;i<e.length;i++){if(i>=Y){s&&s.push(e[i]);continue}const a=e[i],p=redactDeep(a,t+1,r);s?s.push(p):p!==a&&(s=e.slice(0,i),s.push(p))}return s??e}const n=e,o=Object.keys(n);let c;for(let s=0;s<o.length;s++){const i=o[s],a=n[i],p=isSecretParam(i)&&a!==void 0&&a!==null&&!F(i,a)?REDACTED:redactDeep(a,t+1,r);if(c)c[i]=p;else if(p!==a){c={};for(let d=0;d<s;d++)c[o[d]]=n[o[d]];c[i]=p}}return c??e}f(redactDeep,"redactDeep"),u(redactDeep,"redactDeep"),l(redactDeep,"redactDeep");const S=String.raw`(?:"(?:[^"]|"")+"|[A-Za-z_][\w$]*)`,$=String.raw`${S}(?:\s*\.\s*${S})*`,W=String.raw`(?:=|<>|!=|<=|>=|<|>|(?:NOT\s+)?I?LIKE|IS\s+(?:NOT\s+)?DISTINCT\s+FROM)`,Q=new RegExp(String.raw`(${$})\s*${W}\s*(?:[A-Za-z_]\w*\s*\(\s*)?\$(\d+)`,"gi"),ee=new RegExp(String.raw`(${$})\s+(?:NOT\s+)?IN\s*\(([^()]*)\)`,"gi"),te=new RegExp(String.raw`\bINSERT\s+INTO\s+${$}\s*\(([^()]*)\)\s*VALUES\s*`,"gi"),re=new RegExp(S,"g"),k=/\$(\d+)/g,E=16384,ne=256,se=4096,g=new Map,w=l(e=>{const t=e.match(re)??[],r=t[t.length-1]??"";return r.startsWith('"')?r.slice(1,-1).replace(/""/g,'"'):r},"lastIdent");function T(e,t){const r=[];let n=t;for(;;){for(;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]!=="(")return r;const o=[];let c=n+1,s=0,i=!1;for(n+=1;n<e.length;n++){const a=e[n];if(i){a==="'"&&(i=!1);continue}if(a==="'")i=!0;else if(a==="(")s++;else if(a===")"){if(s===0)break;s--}else a===","&&s===0&&(o.push(e.slice(c,n)),c=n+1)}if(n>=e.length)return r;for(o.push(e.slice(c,n)),r.push(o),n+=1;n<e.length&&/\s/.test(e[n]);)n++;if(e[n]!==",")return r;n+=1}}f(T,"k"),u(T,"q"),l(T,"valuesTuples");function y(e){const t=e.length<=se,r=t?g.get(e):void 0;if(r)return r;const n=e.length>E?e.slice(0,E):e,o=new Set,c=l((s,i)=>{i&&isSecretParam(i)&&o.add(Number(s))},"bind");for(const s of n.matchAll(Q))c(s[2],w(s[1]));for(const s of n.matchAll(ee)){const i=w(s[1]);for(const a of s[2].matchAll(k))c(a[1],i)}for(const s of n.matchAll(te)){const i=s[1].split(",").map(a=>w(a.trim()));for(const a of T(n,(s.index??0)+s[0].length))a.forEach((p,d)=>{const z=i[d];if(z)for(const _ of p.matchAll(k))c(_[1],z)})}if(t){if(g.size>=ne){const s=g.keys().next().value;s!==void 0&&g.delete(s)}g.set(e,o)}return o}f(y,"y"),u(y,"ee"),l(y,"secretPlaceholders");export function redactSqlParams(e,t){if(t.length===0||!e.includes("$"))return t;const r=y(e);if(r.size===0)return t;let n=!1;const o=t.map((c,s)=>c==null||!r.has(s+1)?c:(n=!0,REDACTED));return n?o:t}f(redactSqlParams,"redactSqlParams"),u(redactSqlParams,"redactSqlParams"),l(redactSqlParams,"redactSqlParams");
1
+ "use strict";var _=Object.defineProperty;var f=(t,e)=>_(t,"name",{value:e,configurable:!0});var I=Object.defineProperty,l=f((t,e)=>I(t,"name",{value:e,configurable:!0}),"a");export const REDACTED="REDACTED",MAX_TITLE_CHARS=300,MAX_MESSAGE_CHARS=4096,MAX_URL_CHARS=1024;const v=["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"]),R=/^(?:(?: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=d.get(t);if(e!==void 0)return e;const r=m(t);return t.length<=64&&d.size<C&&d.set(t,r),r}f(isSecretParam,"isSecretParam"),l(isSecretParam,"isSecretParam");const P=new Set(["sess","csrf","xsrf","refresh","nonce","reset","magic","mfa","2fa","verify","verification","invite","login"]);export function isSecretCacheKey(t){for(const e of t.split(/[:/{}#]+/))if(!(!e||e.length>64)){if(isSecretParam(e))return!0;for(const r of e.toLowerCase().split(/[-_.]+/))if(P.has(r))return!0}return!1}f(isSecretCacheKey,"isSecretCacheKey"),l(isSecretCacheKey,"isSecretCacheKey");const C=4096,d=new Map;function m(t){const e=t.toLowerCase();if(R.test(e.replace(/[-_.]+/g,"")))return!1;if(v.some(r=>e.includes(r)))return!0;for(const r of e.split(/[-_.]+/))if(r&&Z.has(r))return!0;return!1}f(m,"N"),l(m,"judgeParam");const O=/^([a-z][a-z0-9+.-]*:\/\/)[^/?#@\s]*@/i,N=/([?&#])([^=&#\s]+)=([^&#\s]*)/g;export function redactUrlParams(t){return t&&t.replace(O,`$1${REDACTED}@`).replace(N,(e,r,n)=>isSecretParam(n)?`${r}${n}=${REDACTED}`:e)}f(redactUrlParams,"redactUrlParams"),l(redactUrlParams,"redactUrlParams");export function redactUrl(t){return t&&clip(redactUrlParams(t),1024)}f(redactUrl,"redactUrl"),l(redactUrl,"redactUrl");const D=/\beyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]*/g,M=/\b(bearer|basic)\s+[A-Za-z0-9._~+/=-]{8,}/gi,K=/\b(authorization|x-api-key|api-key|cookie|set-cookie|proxy-authorization)\b(\s*[:=]\s*)(["']?)((?:(?:bearer|basic)\s+)?[^\s"',;]{4,})\3/gi,j=/[@=:]|eyJ|bearer|basic/i;export function redactText(t){return j.test(t)?redactUrlParams(t).replace(K,(e,r,n,a)=>`${r}${n}${a}${REDACTED}${a}`).replace(D,REDACTED).replace(M,(e,r)=>`${r} ${REDACTED}`):t}f(redactText,"redactText"),l(redactText,"redactText");const L=[/\bsk-(?:ant-|proj-|live-|test-)?[A-Za-z0-9_-]{20,}/g,/\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/g,/\bgh[pousr]_[A-Za-z0-9]{30,}/g,/\bxox[abprs]-[A-Za-z0-9-]{10,}/g,/\bAIza[0-9A-Za-z_-]{35}\b/g],h="-----BEGIN ",U=4096;function S(t){if(!t.includes("PRIVATE KEY-----"))return t;let e="",r=0,n=!1;for(;;){const a=t.indexOf(h,r);if(a===-1)break;const o=t.indexOf("-----",a+h.length);if(o===-1)break;const s=t.slice(a+h.length,o);if(!/^[A-Z ]{0,30}PRIVATE KEY$/.test(s)){e+=t.slice(r,o+5),r=o+5;continue}e+=t.slice(r,a);const i=n?-1:t.indexOf("-----END ",o+5);let c;if(i===-1)n=!0,c=Math.min(t.length,o+5+U);else{const u=t.indexOf("-----",i+9);c=u===-1?t.length:u+5}e+=REDACTED,r=c}return e+t.slice(r)}f(S,"y"),l(S,"redactPrivateKeys");const H=/"([A-Za-z0-9_.-]{1,64})"\s*:\s*"((?:[^"\\]|\\.){1,8192})"/g,V=/\b([A-Za-z][A-Za-z0-9_-]{1,40})(\s*[:=]\s*)([^\s"'`,;&)}\]]{8,200})/g,X=/(token|secret|pass(?:word|wd)?|pwd|api[-_]?key|apikey|credential|authorization|bearer)/i;function w(t){return t.replace(H,(e,r)=>isSecretParam(r)?`"${r}": "${REDACTED}"`:e).replace(V,(e,r,n)=>X.test(r)&&isSecretParam(r)?`${r}${n}${REDACTED}`:e)}f(w,"U"),l(w,"redactStructured");export function redactSecretText(t){let e=w(redactText(S(t)));for(const r of L)e=e.replace(r,REDACTED);return e}f(redactSecretText,"redactSecretText"),l(redactSecretText,"redactSecretText");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"),l(clip,"clip");export function safeText(t,e=4096){if(t!==void 0)return clip(redactText(t),e)}f(safeText,"safeText"),l(safeText,"safeText");export function safeTitle(t){return clip(redactText(t),300)}f(safeTitle,"safeTitle"),l(safeTitle,"safeTitle");const q=6,G=64,J=/^TS\d{1,5}$/,Y=l((t,e)=>t==="code"&&typeof e=="string"&&J.test(e),"isDiagnosticCode");export function redactDeep(t,e=0,r=q){if(typeof t=="string")return redactText(t);if(t===null||typeof t!="object"||e>=r)return t;if(Array.isArray(t)){let s;for(let i=0;i<t.length;i++){if(i>=G){s&&s.push(t[i]);continue}const c=t[i],u=redactDeep(c,e+1,r);s?s.push(u):u!==c&&(s=t.slice(0,i),s.push(u))}return s??t}const n=t,a=Object.keys(n);let o;for(let s=0;s<a.length;s++){const i=a[s],c=n[i],u=isSecretParam(i)&&c!==void 0&&c!==null&&!Y(i,c)?REDACTED:redactDeep(c,e+1,r);if(o)o[i]=u;else if(u!==c){o={};for(let p=0;p<s;p++)o[a[p]]=n[a[p]];o[i]=u}}return o??t}f(redactDeep,"redactDeep"),l(redactDeep,"redactDeep");const A=String.raw`(?:"(?:[^"]|"")+"|[A-Za-z_][\w$]*)`,x=String.raw`${A}(?:\s*\.\s*${A})*`,B=String.raw`(?:=|<>|!=|<=|>=|<|>|(?:NOT\s+)?I?LIKE|IS\s+(?:NOT\s+)?DISTINCT\s+FROM)`,F=new RegExp(String.raw`(${x})\s*${B}\s*(?:[A-Za-z_]\w*\s*\(\s*)?\$(\d+)`,"gi"),W=new RegExp(String.raw`(${x})\s+(?:NOT\s+)?IN\s*\(([^()]*)\)`,"gi"),Q=new RegExp(String.raw`\bINSERT\s+INTO\s+${x}\s*\(([^()]*)\)\s*VALUES\s*`,"gi"),tt=new RegExp(A,"g"),z=/\$(\d+)/g,T=16384,et=256,rt=4096,g=new Map,b=l(t=>{const e=t.match(tt)??[],r=e[e.length-1]??"";return r.startsWith('"')?r.slice(1,-1).replace(/""/g,'"'):r},"lastIdent");function k(t,e){const r=[];let n=e;for(;;){for(;n<t.length&&/\s/.test(t[n]);)n++;if(t[n]!=="(")return r;const a=[];let o=n+1,s=0,i=!1;for(n+=1;n<t.length;n++){const c=t[n];if(i){c==="'"&&(i=!1);continue}if(c==="'")i=!0;else if(c==="(")s++;else if(c===")"){if(s===0)break;s--}else c===","&&s===0&&(a.push(t.slice(o,n)),o=n+1)}if(n>=t.length)return r;for(a.push(t.slice(o,n)),r.push(a),n+=1;n<t.length&&/\s/.test(t[n]);)n++;if(t[n]!==",")return r;n+=1}}f(k,"q"),l(k,"valuesTuples");function y(t){const e=t.length<=rt,r=e?g.get(t):void 0;if(r)return r;const n=t.length>T?t.slice(0,T):t,a=new Set,o=l((s,i)=>{i&&isSecretParam(i)&&a.add(Number(s))},"bind");for(const s of n.matchAll(F))o(s[2],b(s[1]));for(const s of n.matchAll(W)){const i=b(s[1]);for(const c of s[2].matchAll(z))o(c[1],i)}for(const s of n.matchAll(Q)){const i=s[1].split(",").map(c=>b(c.trim()));for(const c of k(n,(s.index??0)+s[0].length))c.forEach((u,p)=>{const $=i[p];if($)for(const E of u.matchAll(z))o(E[1],$)})}if(e){if(g.size>=et){const s=g.keys().next().value;s!==void 0&&g.delete(s)}g.set(t,a)}return a}f(y,"ee"),l(y,"secretPlaceholders");export function redactSqlParams(t,e){if(e.length===0||!t.includes("$"))return e;const r=y(t);if(r.size===0)return e;let n=!1;const a=e.map((o,s)=>o==null||!r.has(s+1)?o:(n=!0,REDACTED));return n?a:e}f(redactSqlParams,"redactSqlParams"),l(redactSqlParams,"redactSqlParams");
@@ -1 +1 @@
1
- "use strict";var k=Object.defineProperty;var o=(n,e)=>k(n,"name",{value:e,configurable:!0});var E=Object.defineProperty,c=o((n,e)=>E(n,"name",{value:e,configurable:!0}),"o"),a=Object.defineProperty,p=c((n,e)=>a(n,"name",{value:e,configurable:!0}),"k");export function redisExpiry(n,e){const t=n.toLowerCase();if(t==="setex"||t==="psetex")return e.length===3&&/^\d+$/.test(String(e[1]))&&Number(e[1])>0?"set":"unknown";if(t==="getset"||t==="setnx"||t==="mset"||t==="msetnx")return"none";if(t!=="set"&&t!=="getex")return"unknown";const f=t==="set"?2:1;if(e.length<f)return"unknown";let u=t==="set"?"none":"kept",i=!1,l=!1,g=!1;for(let r=f;r<e.length;r++){const s=String(e[r]).toUpperCase();if(["EX","PX","EXAT","PXAT"].includes(s)){if(i||r+1>=e.length||!/^\d+$/.test(String(e[++r]))||Number(e[r])<=0)return"unknown";i=!0,u="set"}else if(t==="set"&&s==="KEEPTTL"||t==="getex"&&s==="PERSIST"){if(i)return"unknown";i=!0,u=s==="KEEPTTL"?"kept":"none"}else if(t==="set"&&["NX","XX"].includes(s)){if(l)return"unknown";l=!0}else if(t==="set"&&s==="GET"){if(g)return"unknown";g=!0}else return"unknown"}return u}o(redisExpiry,"redisExpiry"),c(redisExpiry,"redisExpiry"),p(redisExpiry,"redisExpiry");
1
+ "use strict";var k=Object.defineProperty;var o=(s,n)=>k(s,"name",{value:n,configurable:!0});var c=Object.defineProperty,E=o((s,n)=>c(s,"name",{value:n,configurable:!0}),"k");export function redisExpiry(s,n){const e=s.toLowerCase();if(e==="setex"||e==="psetex")return n.length===3&&/^\d+$/.test(String(n[1]))&&Number(n[1])>0?"set":"unknown";if(e==="getset"||e==="setnx"||e==="mset"||e==="msetnx")return"none";if(e!=="set"&&e!=="getex")return"unknown";const f=e==="set"?2:1;if(n.length<f)return"unknown";let i=e==="set"?"none":"kept",u=!1,l=!1,g=!1;for(let t=f;t<n.length;t++){const r=String(n[t]).toUpperCase();if(["EX","PX","EXAT","PXAT"].includes(r)){if(u||t+1>=n.length||!/^\d+$/.test(String(n[++t]))||Number(n[t])<=0)return"unknown";u=!0,i="set"}else if(e==="set"&&r==="KEEPTTL"||e==="getex"&&r==="PERSIST"){if(u)return"unknown";u=!0,i=r==="KEEPTTL"?"kept":"none"}else if(e==="set"&&["NX","XX"].includes(r)){if(l)return"unknown";l=!0}else if(e==="set"&&r==="GET"){if(g)return"unknown";g=!0}else return"unknown"}return i}o(redisExpiry,"redisExpiry"),E(redisExpiry,"redisExpiry");
@@ -1 +1 @@
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{}}}
1
+ "use strict";var i=Object.defineProperty;var c=(t,e)=>i(t,"name",{value:e,configurable:!0});var u=Object.defineProperty,a=c((t,e)=>u(t,"name",{value:e,configurable:!0}),"c");export class ReducerRegistry{static{c(this,"ReducerRegistry")}static{a(this,"ReducerRegistry")}constructor(){this.reducers=[]}register(e,s){if(this.reducers.some(r=>r.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 r=s(e);r&&typeof r.then=="function"&&await r}catch{}}}
@@ -1 +1 @@
1
- "use strict";var p=Object.defineProperty;var t=(e,r)=>p(e,"name",{value:r,configurable:!0});var i=Object.defineProperty,o=t((e,r)=>i(e,"name",{value:r,configurable:!0}),"o"),c=Object.defineProperty,n=o((e,r)=>c(e,"name",{value:r,configurable:!0}),"e");import{homedir as l}from"node:os";import{dirname as s,join as m}from"node:path";import{lensEventFile as E}from"./lens-events.js";export function replayPathSegment(e){const r=e?.trim().replace(/[^A-Za-z0-9._-]/g,"-").replace(/^[.-]+/,"");return r?r.slice(0,80):void 0}t(replayPathSegment,"replayPathSegment"),o(replayPathSegment,"replayPathSegment"),n(replayPathSegment,"replayPathSegment");export function replayStoreFromEnv(e=process.env,r=process.cwd()){const a=replayPathSegment(e.LENSMCP_REPLAY_WORKSPACE||e.LENSMCP_WS_KEY);return{root:e.LENSMCP_REPLAY_DIR?.trim()||(a?m(e.LENSMCP_HOME||l(),".lensmcp","replay",a):m(s(E(e,r)),"replay")),checkout:replayPathSegment(e.LENSMCP_INSTANCE)??"main"}}t(replayStoreFromEnv,"replayStoreFromEnv"),o(replayStoreFromEnv,"replayStoreFromEnv"),n(replayStoreFromEnv,"replayStoreFromEnv");
1
+ "use strict";var c=Object.defineProperty;var o=(e,r)=>c(e,"name",{value:r,configurable:!0});var i=Object.defineProperty,n=o((e,r)=>i(e,"name",{value:r,configurable:!0}),"e");import{homedir as m}from"node:os";import{dirname as p,join as a}from"node:path";import{lensEventFile as s}from"./lens-events.js";export function replayPathSegment(e){const r=e?.trim().replace(/[^A-Za-z0-9._-]/g,"-").replace(/^[.-]+/,"");return r?r.slice(0,80):void 0}o(replayPathSegment,"replayPathSegment"),n(replayPathSegment,"replayPathSegment");export function replayStoreFromEnv(e=process.env,r=process.cwd()){const t=replayPathSegment(e.LENSMCP_REPLAY_WORKSPACE||e.LENSMCP_WS_KEY);return{root:e.LENSMCP_REPLAY_DIR?.trim()||(t?a(e.LENSMCP_HOME||m(),".lensmcp","replay",t):a(p(s(e,r)),"replay")),checkout:replayPathSegment(e.LENSMCP_INSTANCE)??"main"}}o(replayStoreFromEnv,"replayStoreFromEnv"),n(replayStoreFromEnv,"replayStoreFromEnv");
@@ -1 +1 @@
1
- "use strict";var d=Object.defineProperty;var n=(r,t)=>d(r,"name",{value:t,configurable:!0});var l=Object.defineProperty,c=n((r,t)=>l(r,"name",{value:t,configurable:!0}),"a"),p=Object.defineProperty,u=c((r,t)=>p(r,"name",{value:t,configurable:!0}),"a");export class ResourceStore{static{n(this,"ResourceStore")}static{c(this,"ResourceStore")}static{u(this,"ResourceStore")}constructor(t={}){this.entries=new Map,this.subs=new Map,this.queued=new Map,this.lastRun=new Map,this.lastCost=new Map,this.coalesceMs=Math.max(0,t.coalesceMs??0),this.costFactor=Math.max(0,t.costFactor??0),this.maxGapMs=Math.max(0,t.maxGapMs??3e4)}register(t,e){if(this.entries.has(t))throw new Error(`Resource already registered: ${t}`);return this.entries.set(t,{uri:t,produce:e,revision:0}),()=>{this.entries.delete(t),this.subs.delete(t),this.lastRun.delete(t),this.lastCost.delete(t)}}async read(t){const e=this.entries.get(t);if(!e)throw new Error(`Unknown resource: ${t}`);const s=await e.produce();return e.produced={at:Date.now(),value:s},s}async readRecent(t,e){const s=this.entries.get(t);if(!s)throw new Error(`Unknown resource: ${t}`);return s.produced&&Date.now()-s.produced.at<=e?s.produced.value:this.read(t)}list(){return[...this.entries.keys()]}markDirty(t){if(this.coalesceMs===0&&this.costFactor===0)return this.recompute(t);if(!this.entries.has(t))return Promise.resolve();const e=this.queued.get(t);if(e)return e;const s=Math.max(0,(this.lastRun.get(t)??Number.NEGATIVE_INFINITY)+this.gapFor(t)-Date.now()),i=new Promise(o=>{const a=u(()=>{this.queued.delete(t),this.lastRun.set(t,Date.now()),this.recompute(t).then(o,()=>o())},"go");s===0?setImmediate(a):setTimeout(a,s).unref?.()});return this.queued.set(t,i),i}gapFor(t){const e=this.lastCost.get(t)??0;return Math.max(this.coalesceMs,Math.min(this.maxGapMs,this.costFactor*e))}cost(t){return this.lastCost.get(t)}async recompute(t){const e=this.entries.get(t);if(!e)return;const s=performance.now(),i=await e.produce();e.produced={at:Date.now(),value:i};const o=JSON.stringify(i);if(this.lastCost.set(t,performance.now()-s),o===e.lastJson)return;e.lastJson=o,e.revision+=1;const a=this.subs.get(t);if(a)for(const h of a)try{h(t,e.revision)}catch{}}revision(t){return this.entries.get(t)?.revision}subscribe(t,e){let s=this.subs.get(t);return s||(s=new Set,this.subs.set(t,s)),s.add(e),()=>{s?.delete(e)}}}
1
+ "use strict";var h=Object.defineProperty;var a=(n,e)=>h(n,"name",{value:e,configurable:!0});var d=Object.defineProperty,c=a((n,e)=>d(n,"name",{value:e,configurable:!0}),"a");export class ResourceStore{static{a(this,"ResourceStore")}static{c(this,"ResourceStore")}constructor(e={}){this.entries=new Map,this.subs=new Map,this.queued=new Map,this.lastRun=new Map,this.lastCost=new Map,this.coalesceMs=Math.max(0,e.coalesceMs??0),this.costFactor=Math.max(0,e.costFactor??0),this.maxGapMs=Math.max(0,e.maxGapMs??3e4)}register(e,s){if(this.entries.has(e))throw new Error(`Resource already registered: ${e}`);return this.entries.set(e,{uri:e,produce:s,revision:0}),()=>{this.entries.delete(e),this.subs.delete(e),this.lastRun.delete(e),this.lastCost.delete(e)}}async read(e){const s=this.entries.get(e);if(!s)throw new Error(`Unknown resource: ${e}`);const t=await s.produce();return s.produced={at:Date.now(),value:t},t}async readRecent(e,s){const t=this.entries.get(e);if(!t)throw new Error(`Unknown resource: ${e}`);return t.produced&&Date.now()-t.produced.at<=s?t.produced.value:this.read(e)}list(){return[...this.entries.keys()]}markDirty(e){if(this.coalesceMs===0&&this.costFactor===0)return this.recompute(e);if(!this.entries.has(e))return Promise.resolve();const s=this.queued.get(e);if(s)return s;const t=Math.max(0,(this.lastRun.get(e)??Number.NEGATIVE_INFINITY)+this.gapFor(e)-Date.now()),r=new Promise(i=>{const o=c(()=>{this.queued.delete(e),this.lastRun.set(e,Date.now()),this.recompute(e).then(i,()=>i())},"go");t===0?setImmediate(o):setTimeout(o,t).unref?.()});return this.queued.set(e,r),r}gapFor(e){const s=this.lastCost.get(e)??0;return Math.max(this.coalesceMs,Math.min(this.maxGapMs,this.costFactor*s))}cost(e){return this.lastCost.get(e)}async recompute(e){const s=this.entries.get(e);if(!s)return;const t=performance.now(),r=await s.produce();s.produced={at:Date.now(),value:r};const i=JSON.stringify(r);if(this.lastCost.set(e,performance.now()-t),i===s.lastJson)return;s.lastJson=i,s.revision+=1;const o=this.subs.get(e);if(o)for(const u of o)try{u(e,s.revision)}catch{}}revision(e){return this.entries.get(e)?.revision}subscribe(e,s){let t=this.subs.get(e);return t||(t=new Set,this.subs.set(e,t)),t.add(s),()=>{t?.delete(s)}}}
@@ -1 +1 @@
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");
1
+ "use strict";var u=Object.defineProperty;var s=(t,e)=>u(t,"name",{value:e,configurable:!0});var l=Object.defineProperty,r=s((t,e)=>l(t,"name",{value:e,configurable:!0}),"r");function f(t){return t.length===0?!1:!!(/^\d{2,}$/.test(t)||/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)||/^[A-Z][A-Z0-9]*-\d+$/.test(t)||t.length>=16&&/^[A-Za-z0-9_-]+$/.test(t)&&/\d/.test(t))}s(f,"a"),r(f,"isIdSegment");export function templatisePath(t){const[e="/"]=t.split("?"),o=e.split("/"),n=[];for(const i of o){if(n.length>12){n.push("\u2026");break}n.push(f(i)?":id":i)}const a=n.join("/");return a.length===0?"/":a}s(templatisePath,"templatisePath"),r(templatisePath,"templatisePath");
@@ -1 +1 @@
1
- "use strict";var c=Object.defineProperty;var t=(e,r)=>c(e,"name",{value:r,configurable:!0});var i=Object.defineProperty,o=t((e,r)=>i(e,"name",{value:r,configurable:!0}),"r"),s=Object.defineProperty,a=o((e,r)=>s(e,"name",{value:r,configurable:!0}),"t");export function isServiceHopHost(e){return e?/.\.localhost$/i.test(e.replace(/\.$/,"")):!1}t(isServiceHopHost,"isServiceHopHost"),o(isServiceHopHost,"isServiceHopHost"),a(isServiceHopHost,"isServiceHopHost");export const LENS_REQUEST_ID_HEADER="x-lensmcp-request-id";
1
+ "use strict";var o=Object.defineProperty;var r=(e,t)=>o(e,"name",{value:t,configurable:!0});var s=Object.defineProperty,c=r((e,t)=>s(e,"name",{value:t,configurable:!0}),"t");export function isServiceHopHost(e){return e?/.\.localhost$/i.test(e.replace(/\.$/,"")):!1}r(isServiceHopHost,"isServiceHopHost"),c(isServiceHopHost,"isServiceHopHost");export const LENS_REQUEST_ID_HEADER="x-lensmcp-request-id";
package/lib/sql-shape.js CHANGED
@@ -1,3 +1,3 @@
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");
1
+ "use strict";var M=Object.defineProperty;var a=(t,n)=>M(t,"name",{value:n,configurable:!0});var b=Object.defineProperty,f=a((t,n)=>b(t,"name",{value:n,configurable:!0}),"p");const $=/[A-Za-z_\u0080-￿]/,F=/[A-Za-z0-9_$\u0080-￿]/;function I(t){const n=[],c=[];let o=0;const r=t.length;let s=0;const i=f((u,e)=>n.push({kind:u,text:e,up:u==="word"?e.toUpperCase():e}),"push");for(;s<r;){const u=t[s];if(u===" "||u===`
2
+ `||u===" "||u==="\r")s++;else if(u==="-"&&t[s+1]==="-"){o++;const e=t.indexOf(`
3
+ `,s);c.push(t.slice(s+2,e<0?r:e).trim()),s=e<0?r:e+1}else if(u==="/"&&t[s+1]==="*"){const e=t.indexOf("*/",s+2);c.push(t.slice(s+2,e<0?r:e).trim()),s=e<0?r:e+2}else if(u==="'"||(u==="E"||u==="e")&&t[s+1]==="'"){let e=u==="'"?s+1:s+2;for(;e<r;)if(t[e]==="\\"&&u!=="'")e+=2;else if(t[e]==="'"&&t[e+1]==="'")e+=2;else{if(t[e]==="'")break;e++}i("string",t.slice(s,e+1)),s=e+1}else if(u==="$"&&/[0-9]/.test(t[s+1]??"")){let e=s+1;for(;e<r&&/[0-9]/.test(t[e]);)e++;i("param",t.slice(s,e)),s=e}else if(u==="$"){const e=/^\$([A-Za-z_][A-Za-z0-9_]*)?\$/.exec(t.slice(s,s+64));if(e){const E=t.indexOf(e[0],s+e[0].length),S=E<0?r:E+e[0].length;i("string",t.slice(s,S)),s=S}else i("punct",u),s++}else if(u==='"'){let e=s+1;for(;e<r&&!(t[e]==='"'&&t[e+1]!=='"');)e+=t[e]==='"'?2:1;e<r&&i("qident",t.slice(s,e+1)),s=e+1}else if(/[0-9]/.test(u)||u==="."&&/[0-9]/.test(t[s+1]??"")){let e=s;for(;e<r&&/[0-9.eE]/.test(t[e]);)e++;i("number",t.slice(s,e)),s=e}else if($.test(u)){let e=s;for(;e<r&&F.test(t[e]);)e++;i("word",t.slice(s,e)),s=e}else if("(),;[].".includes(u))i("punct",u),s++;else{let e=s;for(;e<r&&/[+\-*/<>=~!@#%^&|`?:]/.test(t[e])&&!(t[e]==="-"&&t[e+1]==="-")&&!(t[e]==="/"&&t[e+1]==="*");)e++;e===s&&(e=s+1),i("op",t.slice(s,e)),s=e}}return{tokens:n,comments:c,lineComments:o}}a(I,"I"),f(I,"lex");function U(t){const n=new Map,c=[],o=[],r=[];t.forEach((s,i)=>{if(s.text===")"||s.text==="]"){const u=r.pop();u!==void 0&&n.set(u,i)}c.push(r.length),o.push(r[r.length-1]??-1),(s.text==="("||s.text==="[")&&r.push(i)});for(const s of r)n.set(s,t.length);return{close:n,depth:c,opener:o}}a(U,"D"),f(U,"structure");const G=new Set(["SELECT","INSERT","UPDATE","DELETE","MERGE","VALUES","TABLE"]),R=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 O(t,n,c=!1){const o=f(i=>i?i.kind==="qident"?i.text.slice(1,-1).replace(/""/g,'"'):i.kind==="word"&&!R.has(i.up)?i.text:void 0:void 0,"part");let r=o(t[n]);if(!r)return;let s=n+1;for(;t[s]?.text==="."&&o(t[s+1]);)r=`${r}.${o(t[s+1])}`,s+=2;if(!(t[s]?.text==="("&&!c))return{name:r.replace(/^public\./i,""),next:s}}a(O,"g"),f(O,"tableAt");function C(t,n,c){t[n]?.up==="AS"&&n++;const o=t[n];return o&&(o.kind==="qident"||o.kind==="word"&&!R.has(o.up))&&(n++,t[n]?.text==="("&&(n=(c.get(n)??n)+1)),n}a(C,"k"),f(C,"skipAlias");function m(t){let n=2166136261,c=16777619;for(let o=0;o<t.length;o++){const r=t.charCodeAt(o);n=Math.imul(n^r,16777619)>>>0,c=Math.imul(c^r,1540483477)>>>0}return(n.toString(16).padStart(8,"0")+c.toString(16).padStart(8,"0")).slice(0,12)}a(m,"w"),f(m,"hashId");function w(t,n){const c=f((i,u)=>i.kind==="string"||i.kind==="number"||i.kind==="param"||[",","::","-","[","]"].includes(i.text)||i.kind==="word"&&(/^(NULL|TRUE|FALSE|DEFAULT)$/i.test(i.text)||u?.text==="::"),"isValue"),o=[];let r=0;for(;r<t.length;){const i=t[r],u=t[r-1];if(i.text==="("&&(u?.up==="IN"||u?.up==="VALUES")){const e=n.get(r)??t.length,E=t.slice(r+1,e);if(E.length&&E.every((S,N)=>c(S,E[N-1]))){if(o.push({kind:"punct",text:"(\u2026)",up:"(\u2026)"}),r=e+1,u.up==="VALUES")for(;t[r]?.text===","&&t[r+1]?.text==="(";)r=(n.get(r+1)??t.length)+1;continue}}o.push(i.kind==="string"||i.kind==="number"?{kind:"op",text:"?",up:"?"}:i),r++}let s="";return o.forEach((i,u)=>{const e=o[u-1],E=!e||["(","[",".","::"].includes(e.text)||[")","]",",",".","::"].includes(i.text)||(i.text==="("||i.text==="(\u2026)"||i.text==="[")&&(e.kind==="qident"||e.kind==="word"&&!R.has(e.up));s+=(E?"":" ")+i.text}),s.trim()}a(w,"$"),f(w,"templateOf");const x=new Map,H=512;export function sqlShape(t){const n=x.get(t);if(n)return n;let c;try{c=D(t)}catch{c={id:m(t),template:t.trim().replace(/\s+/g," "),verb:"QUERY",tables:[]}}return x.set(t,c),x.size>H&&x.delete(x.keys().next().value),c}a(sqlShape,"sqlShape"),f(sqlShape,"sqlShape");function D(t){const{tokens:n,comments:c}=I(t),{close:o,depth:r,opener:s}=U(n);let i=n.find(p=>p.kind==="word")?.up??"QUERY";const u=new Set;n.forEach((p,d)=>{if(p.up!=="WITH"||n[d-1]?.up==="START")return;let l=d+1;for(n[l]?.up==="RECURSIVE"&&l++;;){const T=n[l];if(!T||T.kind!=="word"&&T.kind!=="qident"||(u.add(T.kind==="qident"?T.text.slice(1,-1):T.text),l++,n[l]?.text==="("&&(l=(o.get(l)??l)+1),n[l]?.up!=="AS")||(l++,n[l]?.up==="NOT"&&l++,n[l]?.up==="MATERIALIZED"&&l++,n[l]?.text!=="(")||(l=(o.get(l)??n.length)+1,n[l]?.text!==","))break;l++}}),i==="WITH"&&(i=n.find((p,d)=>r[d]===0&&G.has(p.up)&&d>0)?.up??"SELECT");const e=[];let E;const S=f(p=>{u.has(p)||/^\$/.test(p)||e.includes(p)||e.push(p)},"add");if(n.forEach((p,d)=>{const l=n[d-1]?.up,T=p.up==="FROM"||p.up==="JOIN",k=p.up==="INTO"&&(l==="INSERT"||l==="MERGE")||p.up==="UPDATE"&&l!=="DO"&&l!=="FOR"&&l!=="KEY"&&l!=="NO"||p.up==="USING"||p.up==="TABLE"&&d===0;if(!T&&!k)return;const A=s[d]??-1;if(T&&A>=0&&n[A-1]?.kind==="word"&&!["IN","EXISTS","ANY","ALL","AS","FROM","JOIN","LATERAL","SOME","ARRAY"].includes(n[A-1].up)&&n[A+1]?.up!=="SELECT"&&n[A+1]?.up!=="WITH")return;let h=d+1;for(;n[h]?.up==="ONLY"||n[h]?.up==="LATERAL";)h++;for(;;){const L=O(n,h,p.up==="INTO");if(!L||(S(L.name),k&&!E&&p.up!=="USING"&&(E=L.name),h=C(n,L.next,o),!T||n[h]?.text!==","))break;h++}}),(i==="DELETE"||i==="UPDATE"||i==="INSERT"||i==="MERGE")&&!E){const p=n.findIndex((d,l)=>d.up==="FROM"&&n[l-1]?.up==="DELETE");p>=0&&(E=O(n,p+1)?.name)}const N=w(n,o),g=c.find(p=>/^[\w.\-/:]{3,80}$/.test(p));return{id:m(`${i} ${N.replace(/\$\d+/g,"$?")}`),template:N,verb:i,tables:e,...E?{target:E}:{},...g?{name:g}:{}}}a(D,"G"),f(D,"compute");export function statementCount(t){let n=0,c=!1;for(const o of I(t).tokens)o.text===";"?(c&&n++,c=!1):c=!0;return n+(c?1:0)}a(statementCount,"statementCount"),f(statementCount,"statementCount");export function shapeMatchKey(t){const n=sqlShape(t),c=n.template.replace(/"(?:[^"]|"")*"|[^"]+/g,o=>o.startsWith('"')?o:o.toLowerCase());return`${n.verb} ${c.replace(/\$\d+/g,"?").replace(/\b(?:true|false)\b/g,"?")}`}a(shapeMatchKey,"shapeMatchKey"),f(shapeMatchKey,"shapeMatchKey");export function lineCommentSwallows(t){return!/\n/.test(t)&&I(t).lineComments>0}a(lineCommentSwallows,"lineCommentSwallows"),f(lineCommentSwallows,"lineCommentSwallows");
package/lib/sql-values.js CHANGED
@@ -1 +1 @@
1
- "use strict";var S=Object.defineProperty;var r=(e,t)=>S(e,"name",{value:t,configurable:!0});var v=Object.defineProperty,l=r((e,t)=>v(e,"name",{value:t,configurable:!0}),"s"),$=Object.defineProperty,c=l((e,t)=>$(e,"name",{value:t,configurable:!0}),"c");import{createReadStream as q}from"node:fs";import{join as _}from"node:path";import{createInterface as g}from"node:readline";export const SQL_VALUES_DIR="sql",CACHE_VALUES_DIR="cache";const h=/^(sqv|cav)_(\d{12})_(\d{1,10})_([0-9a-z]{1,12})$/,x={sqv:SQL_VALUES_DIR,cav:CACHE_VALUES_DIR};export function sqlValuesId(e,t,a){return`sqv_${V(e)}_${t}_${a.toString(36)}`}r(sqlValuesId,"sqlValuesId"),l(sqlValuesId,"sqlValuesId"),c(sqlValuesId,"sqlValuesId");export function cacheValuesId(e,t,a){return`cav_${V(e)}_${t}_${a.toString(36)}`}r(cacheValuesId,"cacheValuesId"),l(cacheValuesId,"cacheValuesId"),c(cacheValuesId,"cacheValuesId");export function keptValuesFile(e,t){const a=h.exec(t);return a?_(e,x[a[1]],`${a[3]}-${a[2]}.jsonl`):void 0}r(keptValuesFile,"keptValuesFile"),l(keptValuesFile,"keptValuesFile"),c(keptValuesFile,"keptValuesFile");export function sqlValuesFile(e,t){return isSqlValuesId(t)?keptValuesFile(e,t):void 0}r(sqlValuesFile,"sqlValuesFile"),l(sqlValuesFile,"sqlValuesFile"),c(sqlValuesFile,"sqlValuesFile");export function isSqlValuesId(e){return typeof e=="string"&&h.test(e)&&e.startsWith("sqv_")}r(isSqlValuesId,"isSqlValuesId"),l(isSqlValuesId,"isSqlValuesId"),c(isSqlValuesId,"isSqlValuesId");export function isCacheValuesId(e){return typeof e=="string"&&h.test(e)&&e.startsWith("cav_")}r(isCacheValuesId,"isCacheValuesId"),l(isCacheValuesId,"isCacheValuesId"),c(isCacheValuesId,"isCacheValuesId");export async function readSqlValues(e,t){return isSqlValuesId(t)?await p(e,t):void 0}r(readSqlValues,"readSqlValues"),l(readSqlValues,"readSqlValues"),c(readSqlValues,"readSqlValues");export async function readCacheValues(e,t){return isCacheValuesId(t)?await p(e,t):void 0}r(readCacheValues,"readCacheValues"),l(readCacheValues,"readCacheValues"),c(readCacheValues,"readCacheValues");async function p(e,t){const a=keptValuesFile(e,t);if(!a)return;const o=`{"id":${JSON.stringify(t)},`,n=q(a,{encoding:"utf8"}),s=g({input:n,crlfDelay:1/0});try{for await(const i of s){if(!i.startsWith(o))continue;const u=JSON.parse(i);return u.id===t?u:void 0}}catch{}finally{s.close(),n.destroy()}}r(p,"p"),l(p,"h"),c(p,"readKeptValues");export async function readSqlValuesMany(e,t){return await readKeptValuesMany(e,t.filter(isSqlValuesId))}r(readSqlValuesMany,"readSqlValuesMany"),l(readSqlValuesMany,"readSqlValuesMany"),c(readSqlValuesMany,"readSqlValuesMany");export async function readKeptValuesMany(e,t){const a=new Map;for(const n of t){const s=keptValuesFile(e,n);if(!s)continue;const i=a.get(s)??new Set;i.add(n),a.set(s,i)}const o=new Map;for(const[n,s]of a){const i=q(n,{encoding:"utf8"}),u=g({input:i,crlfDelay:1/0});let d=s.size;try{for await(const y of u){const f=/^\{"id":"((?:sqv|cav)_[0-9a-z_]+)",/.exec(y);if(!(!f||!s.has(f[1])||o.has(f[1]))){try{o.set(f[1],JSON.parse(y))}catch{continue}if(--d===0)break}}}catch{}finally{u.close(),i.destroy()}}return o}r(readKeptValuesMany,"readKeptValuesMany"),l(readKeptValuesMany,"readKeptValuesMany"),c(readKeptValuesMany,"readKeptValuesMany");export function sqlWithValues(e,t){if(!t?.length)return e;const a=c(s=>s==="null"||s==="undefined"?"NULL":`'${s.replace(/'/g,"''")}'`,"literal");let o="",n=0;for(;n<e.length;){const s=e[n];if(s==="'"){const u=e.indexOf("'",n+1),d=u<0?e.length:u+1;o+=e.slice(n,d),n=d;continue}const i=s==="$"?/^\$(\d+)/.exec(e.slice(n,n+12)):null;if(i){const u=t[Number(i[1])-1];o+=u===void 0?i[0]:a(u),n+=i[0].length;continue}o+=s,n++}return o}r(sqlWithValues,"sqlWithValues"),l(sqlWithValues,"sqlWithValues"),c(sqlWithValues,"sqlWithValues");function V(e){const t=new Date(e),a=c(o=>String(o).padStart(2,"0"),"p");return`${t.getUTCFullYear()}${a(t.getUTCMonth()+1)}${a(t.getUTCDate())}${a(t.getUTCHours())}${a(t.getUTCMinutes())}`}r(V,"V"),l(V,"g"),c(V,"minuteStamp");
1
+ "use strict";var S=Object.defineProperty;var s=(e,t)=>S(e,"name",{value:t,configurable:!0});var v=Object.defineProperty,o=s((e,t)=>v(e,"name",{value:t,configurable:!0}),"c");import{createReadStream as y}from"node:fs";import{join as $}from"node:path";import{createInterface as g}from"node:readline";export const SQL_VALUES_DIR="sql",CACHE_VALUES_DIR="cache";const d=/^(sqv|cav)_(\d{12})_(\d{1,10})_([0-9a-z]{1,12})$/,q={sqv:SQL_VALUES_DIR,cav:CACHE_VALUES_DIR};export function sqlValuesId(e,t,n){return`sqv_${V(e)}_${t}_${n.toString(36)}`}s(sqlValuesId,"sqlValuesId"),o(sqlValuesId,"sqlValuesId");export function cacheValuesId(e,t,n){return`cav_${V(e)}_${t}_${n.toString(36)}`}s(cacheValuesId,"cacheValuesId"),o(cacheValuesId,"cacheValuesId");export function keptValuesFile(e,t){const n=d.exec(t);return n?$(e,q[n[1]],`${n[3]}-${n[2]}.jsonl`):void 0}s(keptValuesFile,"keptValuesFile"),o(keptValuesFile,"keptValuesFile");export function sqlValuesFile(e,t){return isSqlValuesId(t)?keptValuesFile(e,t):void 0}s(sqlValuesFile,"sqlValuesFile"),o(sqlValuesFile,"sqlValuesFile");export function isSqlValuesId(e){return typeof e=="string"&&d.test(e)&&e.startsWith("sqv_")}s(isSqlValuesId,"isSqlValuesId"),o(isSqlValuesId,"isSqlValuesId");export function isCacheValuesId(e){return typeof e=="string"&&d.test(e)&&e.startsWith("cav_")}s(isCacheValuesId,"isCacheValuesId"),o(isCacheValuesId,"isCacheValuesId");export async function readSqlValues(e,t){return isSqlValuesId(t)?await p(e,t):void 0}s(readSqlValues,"readSqlValues"),o(readSqlValues,"readSqlValues");export async function readCacheValues(e,t){return isCacheValuesId(t)?await p(e,t):void 0}s(readCacheValues,"readCacheValues"),o(readCacheValues,"readCacheValues");async function p(e,t){const n=keptValuesFile(e,t);if(!n)return;const c=`{"id":${JSON.stringify(t)},`,a=y(n,{encoding:"utf8"}),r=g({input:a,crlfDelay:1/0});try{for await(const i of r){if(!i.startsWith(c))continue;const u=JSON.parse(i);return u.id===t?u:void 0}}catch{}finally{r.close(),a.destroy()}}s(p,"h"),o(p,"readKeptValues");export async function readSqlValuesMany(e,t){return await readKeptValuesMany(e,t.filter(isSqlValuesId))}s(readSqlValuesMany,"readSqlValuesMany"),o(readSqlValuesMany,"readSqlValuesMany");export async function readKeptValuesMany(e,t){const n=new Map;for(const a of t){const r=keptValuesFile(e,a);if(!r)continue;const i=n.get(r)??new Set;i.add(a),n.set(r,i)}const c=new Map;for(const[a,r]of n){const i=y(a,{encoding:"utf8"}),u=g({input:i,crlfDelay:1/0});let l=r.size;try{for await(const h of u){const f=/^\{"id":"((?:sqv|cav)_[0-9a-z_]+)",/.exec(h);if(!(!f||!r.has(f[1])||c.has(f[1]))){try{c.set(f[1],JSON.parse(h))}catch{continue}if(--l===0)break}}}catch{}finally{u.close(),i.destroy()}}return c}s(readKeptValuesMany,"readKeptValuesMany"),o(readKeptValuesMany,"readKeptValuesMany");export function sqlWithValues(e,t){if(!t?.length)return e;const n=o(r=>r==="null"||r==="undefined"?"NULL":`'${r.replace(/'/g,"''")}'`,"literal");let c="",a=0;for(;a<e.length;){const r=e[a];if(r==="'"){const u=e.indexOf("'",a+1),l=u<0?e.length:u+1;c+=e.slice(a,l),a=l;continue}const i=r==="$"?/^\$(\d+)/.exec(e.slice(a,a+12)):null;if(i){const u=t[Number(i[1])-1];c+=u===void 0?i[0]:n(u),a+=i[0].length;continue}c+=r,a++}return c}s(sqlWithValues,"sqlWithValues"),o(sqlWithValues,"sqlWithValues");function V(e){const t=new Date(e),n=o(c=>String(c).padStart(2,"0"),"p");return`${t.getUTCFullYear()}${n(t.getUTCMonth()+1)}${n(t.getUTCDate())}${n(t.getUTCHours())}${n(t.getUTCMinutes())}`}s(V,"g"),o(V,"minuteStamp");
package/lib/stores.js CHANGED
@@ -1,2 +1,2 @@
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");
1
+ "use strict";var x=Object.defineProperty;var p=(n,e)=>x(n,"name",{value:e,configurable:!0});var U=Object.defineProperty,l=p((n,e)=>U(n,"name",{value:e,configurable:!0}),"u");import{readFileSync as $}from"node:fs";import{join as v}from"node:path";const R=/^[A-Za-z0-9_-]+$/,j=new Set(["kind","url","databases","lens","run"]);export function readStoresDecl(n){let e;try{e=JSON.parse($(v(n,"nx.json"),"utf8"))}catch{return{stores:{},errors:[],notes:[]}}const t=e?.lensmcp?.stores;return t===void 0?{stores:{},errors:[],notes:[]}:validateStoresDecl(t)}p(readStoresDecl,"readStoresDecl"),l(readStoresDecl,"readStoresDecl");export function validateStoresDecl(n){const e=[],t=[],i={};if(!n||typeof n!="object"||Array.isArray(n))return{stores:i,errors:["`lensmcp.stores` must be an object"],notes:t};for(const[s,a]of Object.entries(n)){const r=`stores.${s}`;if(!R.test(s)){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,f=o.kind;if(f!=="postgres"&&f!=="redis"){e.push(`${r}.kind: one of "postgres", "redis"`);continue}const h=typeof o.url=="string"?o.url.trim():"";if(!h){e.push(`${r}.url: the connection URL is required (e.g. "\${${f==="postgres"?"PG_URL":"REDIS_URL"}}")`);continue}const m=o.databases??[];if(!Array.isArray(m)||!m.every(u=>typeof u=="string"&&u.trim())){e.push(`${r}.databases: a list of URLs or database names`);continue}if(m.length&&f!=="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))j.has(u)||t.push(`${r}.${u}: not a store setting \u2014 ignored`);i[s]={kind:f,url:h,databases:m.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}}p(validateStoresDecl,"validateStoresDecl"),l(validateStoresDecl,"validateStoresDecl");export function parseDotenv(n,e={}){const t={},i=l(s=>s.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(a,r)=>t[r]??e[r]??""),"expand");for(const s of n.split(/\r?\n/)){const a=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/.exec(s);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}p(parseDotenv,"parseDotenv"),l(parseDotenv,"parseDotenv");function g(n,e){try{return parseDotenv($(n,"utf8"),e)}catch{return{}}}p(g,"$"),l(g,"readDotenv");export function checkoutEnv(n,e=process.env){let t={};for(const s of[".env",".env.local"])t={...t,...g(v(n,s),{...t})};const i=Object.fromEntries(Object.entries(e).filter(s=>typeof s[1]=="string"));t={...t,...i};for(const s of[v(".lensmcp","instance.resources.env"),v(".lensmcp","instance.env")])t={...t,...g(v(n,s),{...t})};return t}p(checkoutEnv,"checkoutEnv"),l(checkoutEnv,"checkoutEnv");export function expandVars(n,e){const t=[];return{value:n.replace(/\$\{([A-Za-z_][A-Za-z0-9_.]*)\}/g,(i,s)=>{const a=e[s];return(a===void 0||a==="")&&t.push(s),a??""}),missing:t}}p(expandVars,"expandVars"),l(expandVars,"expandVars");const y=l(n=>n.port||(n.protocol.startsWith("redis")?"6379":"5432"),"portOf");export function withDatabase(n,e){const t=new URL(n);return t.pathname=`/${e}`,t.toString()}p(withDatabase,"withDatabase"),l(withDatabase,"withDatabase");export function redactUrl(n){try{const e=new URL(n);return`${e.protocol}//${e.username?`${decodeURIComponent(e.username)}@`:""}${e.hostname}:${y(e)}${e.pathname}`}catch{return"(not a URL)"}}p(redactUrl,"redactUrl"),l(redactUrl,"redactUrl");export function resolveStores(n,e){return Object.entries(n).map(([t,i])=>{const s=expandVars(i.url,e),a=[...s.missing];let r;try{r=s.missing.length?void 0:new URL(s.value)}catch{r=void 0}const o=[];if(r&&i.kind==="postgres"){o.push({name:decodeURIComponent(r.pathname.replace(/^\//,""))||"postgres",url:s.value});for(const m of i.databases){const d=expandVars(m,e);if(d.missing.length){a.push(...d.missing);continue}const c=/^[a-z]+:\/\//i.test(d.value)?d.value:withDatabase(s.value,d.value);try{const u=decodeURIComponent(new URL(c).pathname.replace(/^\//,""));u&&!o.some(b=>b.name===u)&&o.push({name:u,url:c})}catch{}}}const f=i.lens.url?expandVars(i.lens.url,e):void 0;f?.missing.length&&a.push(...f.missing);const h=i.lens.read?a.length?`${[...new Set(a)].map(m=>`\${${m}}`).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,...h?{noRead:h}:{readUrl:f?.value||s.value},prepare:i.lens.prepare!==!1,missing:[...new Set(a)]}})}p(resolveStores,"resolveStores"),l(resolveStores,"resolveStores");
package/lib/story.js CHANGED
@@ -1 +1 @@
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");
1
+ "use strict";var w=Object.defineProperty;var u=(e,n)=>w(e,"name",{value:n,configurable:!0});var I=Object.defineProperty,m=u((e,n)=>I(e,"name",{value:n,configurable:!0}),"c");export function groupByFlow(e){const n=new Map;for(const t of e){const o=t.context.flowId;if(!o)continue;let s=n.get(o);s||(s=[],n.set(o,s)),s.push(t)}return n}u(groupByFlow,"groupByFlow"),m(groupByFlow,"groupByFlow");export function compileStory(e,n={}){let t,o;if(n.flowId)o=n.flowId,t=e.filter(r=>r.context.flowId===o);else{const r=e.find(i=>i.context.flowId);if(!r)return;o=r.context.flowId,t=e.filter(i=>i.context.flowId===o)}if(t.length===0)return;t.sort((r,i)=>r.timestamp-i.timestamp);const s=1e3;t.length>s&&(t=[t[0],...t.slice(t.length-(s-1))]);const c=t[0],d=[];let l,p;for(const r of t){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&&(p=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 v=t[0].timestamp,g=t[t.length-1].timestamp;return{flowId:o,origin:{type:c.context.originType,nodeId:c.context.originNodeId,at:c.timestamp},phases:d,finalState:l?{page:l.page,route:l.route,componentName:l.componentName,renderId:l.id,visualFrameId:p}:void 0,startedAt:v,endedAt:g,eventCount:t.length}}u(compileStory,"compileStory"),m(compileStory,"compileStory");function f(e){const n=(e.raw??null)?.kind;if(n==="flow-origin"||e.source==="client-runtime"&&n==="user-action"){const t=e.raw;return{kind:"user-action",at:e.timestamp,label:t?.origin?.label??e.title,eventIds:[e.id]}}if(e.source==="react"&&n==="render"){const t=e.raw;return{kind:"render",at:e.timestamp,label:`render ${t?.render?.componentName??"?"}`,eventIds:[e.id],details:t?.render?{componentName:t.render.componentName,durationMs:t.render.actualDurationMs}:void 0}}if(e.source==="react"&&n==="slot-content-changed"){const t=e.raw,o=t?.slot?.toComponent??"?";return{kind:/spinner|loader|loading/i.test(o)?"loading-ui":"idle-ui",at:e.timestamp,label:`slot ${t?.slot?.slotLogicalId??""} \u2192 ${o}`,eventIds:[e.id]}}if(e.source==="client-runtime"&&n==="route"){const t=e.raw;return{kind:"route-transition",at:e.timestamp,label:`route ${t?.from??""} \u2192 ${t?.url??""}`,eventIds:[e.id]}}if(e.source==="valtio"&&n==="state-update"){const t=e.raw;return{kind:"state-update",at:e.timestamp,label:`${t?.update?.storeId??"?"}.${t?.update?.path??"?"}`,eventIds:[e.id],details:t?.update}}if(e.source==="nestjs"&&n==="server-request"){const t=e.raw;return{kind:"backend-request",at:e.timestamp,label:`${t?.request?.method??"?"} ${t?.request?.route??"?"} \u2192 ${t?.request?.status??"?"}`,eventIds:[e.id],details:t?.request}}if(e.source==="chrome"&&e.category==="network")return{kind:"backend-request",at:e.timestamp,label:e.title,eventIds:[e.id]};if(e.source==="visual"&&n==="visual-violation"){const t=e.raw;return{kind:"visual-violation",at:e.timestamp,label:`${t?.violation?.ruleType??"rule"} ${t?.violation?.ruleId??""}`,eventIds:[e.id]}}}u(f,"g"),m(f,"classifyEvent");
package/lib/thresholds.js CHANGED
@@ -1 +1 @@
1
- "use strict";var l=Object.defineProperty;var r=(e,s)=>l(e,"name",{value:s,configurable:!0});var u=Object.defineProperty,t=r((e,s)=>u(e,"name",{value:s,configurable:!0}),"r"),a=Object.defineProperty,c=t((e,s)=>a(e,"name",{value:s,configurable:!0}),"n");export const DEFAULT_THRESHOLDS={dbInLoop:5,nPlusOne:3,renderStorm:5,slowRouteMs:500,slowPageMs:1e3,slowRenderMs:16,slowQueryMs:100,duplicateRequestPeak:3,slowEgressMs:1e3};export function resolveThresholds(e){const s={...DEFAULT_THRESHOLDS};if(e)for(const n of Object.keys(DEFAULT_THRESHOLDS)){const o=e[n];typeof o=="number"&&Number.isFinite(o)&&o>=0&&(s[n]=o)}return s}r(resolveThresholds,"resolveThresholds"),t(resolveThresholds,"resolveThresholds"),c(resolveThresholds,"resolveThresholds");
1
+ "use strict";var n=Object.defineProperty;var r=(e,s)=>n(e,"name",{value:s,configurable:!0});var l=Object.defineProperty,u=r((e,s)=>l(e,"name",{value:s,configurable:!0}),"n");export const DEFAULT_THRESHOLDS={dbInLoop:5,nPlusOne:3,renderStorm:5,slowRouteMs:500,slowPageMs:1e3,slowRenderMs:16,slowQueryMs:100,duplicateRequestPeak:3,slowEgressMs:1e3};export function resolveThresholds(e){const s={...DEFAULT_THRESHOLDS};if(e)for(const t of Object.keys(DEFAULT_THRESHOLDS)){const o=e[t];typeof o=="number"&&Number.isFinite(o)&&o>=0&&(s[t]=o)}return s}r(resolveThresholds,"resolveThresholds"),u(resolveThresholds,"resolveThresholds");
package/lib/ulid.js CHANGED
@@ -1 +1 @@
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");
1
+ "use strict";var d=Object.defineProperty;var r=(e,n)=>d(e,"name",{value:n,configurable:!0});var f=Object.defineProperty,c=r((e,n)=>f(e,"name",{value:n,configurable:!0}),"r");const i="0123456789ABCDEFGHJKMNPQRSTVWXYZ",b=16;function l(e,n){let o="",t=e;for(let u=n-1;u>=0;u--){const a=t%32;o=i[a]+o,t=(t-a)/32}return o}r(l,"s"),c(l,"encodeTime");function s(e){const n=new Uint8Array(e);globalThis.crypto.getRandomValues(n);let o="";for(let t=0;t<e;t++)o+=i[(n[t]??0)&31];return o}r(s,"a"),c(s,"encodeRandom");export function ulid(e=Date.now()){return l(e,10)+s(16)}r(ulid,"ulid"),c(ulid,"ulid");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/core",
3
- "version": "1.25.35",
3
+ "version": "1.25.36",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "module": "./index.js",
@@ -84,7 +84,7 @@
84
84
  }
85
85
  },
86
86
  "dependencies": {
87
- "@lensmcp/protocol-types": "1.25.35",
87
+ "@lensmcp/protocol-types": "1.25.36",
88
88
  "tslib": "^2.3.0"
89
89
  },
90
90
  "license": "Apache-2.0",