@lensmcp/core 1.23.9 → 1.23.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ai-content.js +1 -1
- package/lib/bus-rotation.js +1 -1
- package/lib/event-bus.js +1 -1
- package/lib/event-redactor.js +1 -1
- package/lib/fingerprint.js +1 -1
- package/lib/flow-categories.js +1 -1
- package/lib/flow-segments.js +1 -1
- package/lib/flow-shape.d.ts +2 -2
- package/lib/flow-shape.js +1 -1
- package/lib/flows-config.js +1 -1
- package/lib/graph-from-events.js +1 -1
- package/lib/graph-store.js +1 -1
- package/lib/lens-events.d.ts +20 -0
- package/lib/lens-events.js +2 -0
- package/lib/patterns.js +1 -1
- package/lib/redact.d.ts +0 -20
- package/lib/redact.js +1 -1
- package/lib/reducer-registry.js +1 -1
- package/lib/resource-store.js +1 -1
- package/lib/story.js +1 -1
- package/lib/thresholds.js +1 -1
- package/lib/ulid.js +1 -1
- package/package.json +7 -2
package/lib/ai-content.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var c=Object.defineProperty;var n=(e,t)=>c(e,"name",{value:t,configurable:!0});var s=Object.defineProperty,i=n((e,t)=>s(e,"name",{value:t,configurable:!0}),"r"),l=Object.defineProperty,o=i((e,t)=>l(e,"name",{value:t,configurable:!0}),"r");import*as d from"node:fs";import{dirname as f,join as a}from"node:path";export const AI_CONTENT_DIR="ai";const u=/^ai_[0-9a-z]{8,40}$/;export const isAiCallId=o(e=>typeof e=="string"&&u.test(e),"isAiCallId");export function aiContentDir(e){return a(f(e),AI_CONTENT_DIR)}n(aiContentDir,"aiContentDir"),i(aiContentDir,"aiContentDir"),o(aiContentDir,"aiContentDir");export function aiContentFile(e,t){if(!isAiCallId(t))throw new Error("invalid ai call id");return a(aiContentDir(e),`${t}.json`)}n(aiContentFile,"aiContentFile"),i(aiContentFile,"aiContentFile"),o(aiContentFile,"aiContentFile");export function readAiContent(e,t){if(isAiCallId(t))try{const r=JSON.parse(d.readFileSync(aiContentFile(e,t),"utf8"));return r&&r.schemaVersion===1&&r.id===t?r:void 0}catch{return}}n(readAiContent,"readAiContent"),i(readAiContent,"readAiContent"),o(readAiContent,"readAiContent");
|
package/lib/bus-rotation.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var s=Object.defineProperty;var o=(e,n)=>s(e,"name",{value:n,configurable:!0});var f=Object.defineProperty,i=o((e,n)=>f(e,"name",{value:n,configurable:!0}),"y"),d=Object.defineProperty,S=i((e,n)=>d(e,"name",{value:n,configurable:!0}),"o");export function rotateBusFile(e,n){const{fs:t,maxBytes:l,maxFiles:y}=n,c=`${e}.rotate.lock`,u=n.staleLockMs??3e4;let a;for(let r=0;r<2&&a===void 0;r++)try{a=t.openSync(c,"wx")}catch{try{if(Date.now()-t.statSync(c).mtimeMs<=u)return"busy";t.unlinkSync(c)}catch{}}if(a===void 0)return"busy";try{try{if(t.statSync(e).size<=l)return"not-needed"}catch{return"not-needed"}try{t.unlinkSync(`${e}.${y}`)}catch{}for(let r=y-1;r>=1;r--)try{t.renameSync(`${e}.${r}`,`${e}.${r+1}`)}catch{}try{t.renameSync(e,`${e}.1`)}catch{}return"rotated"}finally{try{t.closeSync(a)}catch{}try{t.unlinkSync(c)}catch{}}}o(rotateBusFile,"rotateBusFile"),i(rotateBusFile,"rotateBusFile"),S(rotateBusFile,"rotateBusFile");
|
package/lib/event-bus.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var c=Object.defineProperty;var n=(s,t)=>c(s,"name",{value:t,configurable:!0});var a=Object.defineProperty,o=n((s,t)=>a(s,"name",{value:t,configurable:!0}),"n"),h=Object.defineProperty,u=o((s,t)=>h(s,"name",{value:t,configurable:!0}),"e");export class EventBus{static{n(this,"EventBus")}static{o(this,"EventBus")}static{u(this,"EventBus")}constructor(t={}){this.subs=new Set,this.dropped=0,this.capacity=t.capacity??1e4,this.onDrop=t.onDrop,this.transform=t.transform}publish(t){if(this.subs.size>this.capacity){this.dropped++,this.onDrop?.(1);return}let r=t;if(this.transform)try{r=this.transform(t)??t}catch{r=t}for(const e of this.subs)if(!(e.filter&&!e.filter(r)))try{const i=e.handler(r);i&&typeof i.then=="function"&&i.catch(()=>{})}catch{}}subscribe(t,r){const e={handler:t,filter:r};return this.subs.add(e),()=>{this.subs.delete(e)}}droppedCount(){return this.dropped}subscriberCount(){return this.subs.size}}
|
package/lib/event-redactor.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var E=Object.defineProperty;var d=(a,t)=>E(a,"name",{value:t,configurable:!0});var T=Object.defineProperty,v=d((a,t)=>T(a,"name",{value:t,configurable:!0}),"c"),_=Object.defineProperty,n=v((a,t)=>_(a,"name",{value:t,configurable:!0}),"t");import{MAX_MESSAGE_CHARS as f,MAX_TITLE_CHARS as u,redactDeep as x,redactText as l,safeText as R,safeTitle as g}from"./redact.js";export const BUS_REDACT_MAX_DEPTH=12;export function createEventRedactor(a={}){const t=a.maxDepth??BUS_REDACT_MAX_DEPTH;let r=0,s=0;return{redact(e){r+=1;const o=e.title===void 0?void 0:g(l(e.title)),i=e.message===void 0?void 0:R(l(e.message),f),c=e.raw===void 0?void 0:x(e.raw,0,t),m=o!==e.title,p=i!==e.message,A=c!==e.raw;return!m&&!p&&!A?e:(s+=1,{...e,...o!==void 0?{title:o}:{},...i!==void 0?{message:i}:{},...c!==void 0?{raw:c}:{}})},stats:n(()=>({inspected:r,redacted:s}),"stats"),reset:n(()=>{r=0,s=0},"reset")}}d(createEventRedactor,"createEventRedactor"),v(createEventRedactor,"createEventRedactor"),n(createEventRedactor,"createEventRedactor");export{u as MAX_TITLE_CHARS};
|
package/lib/fingerprint.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var f=Object.defineProperty;var r=(e,t)=>f(e,"name",{value:t,configurable:!0});var l=Object.defineProperty,n=r((e,t)=>l(e,"name",{value:t,configurable:!0}),"r"),u=Object.defineProperty,o=n((e,t)=>u(e,"name",{value:t,configurable:!0}),"e");const d=2166136261,g=16777619;function a(e){let t=2166136261;for(let i=0;i<e.length;i++)t^=e.charCodeAt(i),t=Math.imul(t,16777619);return(t>>>0).toString(16).padStart(8,"0")}r(a,"o"),n(a,"i"),o(a,"fnv1a32");export function fingerprint(e){const t=[e.kind,e.identity,e.file??"",e.detail??""];return`${e.kind}:${a(t.join("|"))}`}r(fingerprint,"fingerprint"),n(fingerprint,"fingerprint"),o(fingerprint,"fingerprint");
|
package/lib/flow-categories.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var q=Object.defineProperty;var c=(e,t)=>q(e,"name",{value:t,configurable:!0});var
|
|
1
|
+
"use strict";var q=Object.defineProperty;var c=(e,t)=>q(e,"name",{value:t,configurable:!0});var F=Object.defineProperty,d=c((e,t)=>F(e,"name",{value:t,configurable:!0}),"c"),T=Object.defineProperty,s=d((e,t)=>T(e,"name",{value:t,configurable:!0}),"s");export const CATEGORY_ORDER=["user-action","page-load","navigation","api","ai","background","test","system","other"];const f=new Map;export function globMatch(e,t){let n=f.get(e);return n||(n=new RegExp(`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".")}$`),f.size>500&&f.clear(),f.set(e,n)),n.test(t)}c(globMatch,"globMatch"),d(globMatch,"globMatch"),s(globMatch,"globMatch");const S=s(e=>/^[A-Z]+ /.test(e),"hasMethod");function v(e,t){return t.some(n=>n.route?S(e)?globMatch(e,`${n.method??"GET"} ${n.route}`):globMatch(e,n.route):!1)}c(v,"w"),d(v,"T"),s(v,"routeMatches");function m(e,t){return!([e.flowId,e.originType,e.origin,e.route,e.project].filter(n=>n!==void 0).length===0||e.flowId!==void 0&&!globMatch(e.flowId,t.flowId)||e.originType!==void 0&&e.originType!==t.origin.type||e.origin!==void 0&&!(t.origin.nodeId!==void 0&&globMatch(e.origin,t.origin.nodeId))||e.route!==void 0&&!v(e.route,t.segments)||e.project!==void 0&&!t.segments.some(n=>n.projects.some(r=>globMatch(e.project,r))))}c(m,"m"),d(m,"b"),s(m,"ruleMatches");const b=s(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),p=s(e=>typeof e=="string"&&e!==""?e:void 0,"str"),y=s(e=>b(e.raw)?p(e.raw.kind)??"":"","kindOf");function h(e){const t=[...e].sort((a,l)=>(Number(a.timestamp)||0)-(Number(l.timestamp)||0)||(a.id<l.id?-1:1)),n=t.find(a=>y(a)==="flow-origin"),r=n??t.find(a=>p(a.context?.originType));if(!r)return{};const o=b(r.raw)?r.raw:{},i=p(r.context?.originType)??(n?p(r.title):void 0),u=p(o.originNodeId)??p(r.context?.originNodeId);return{...i?{type:i}:{},...u?{nodeId:u}:{}}}c(h,"k"),d(h,"$"),s(h,"originOf");const z=/^(verify|e2e|test|smoke|load)[-_:]/i,B=s((e,t)=>z.test(e)||t!==void 0&&/^(ui:)?(tools|scripts?|e2e)\//.test(t),"isTestFlow"),O={"page-load":"page-load","user-click":"user-action","form-submit":"user-action","input-change":"user-action","double-click":"user-action","context-menu":"user-action","key-press":"user-action","route-load":"navigation","route-change":"navigation",navigation:"navigation","ai-turn":"ai",timer:"background",cron:"background",interval:"background",queue:"background",job:"background","websocket-message":"background","hmr-update":"system"},A=new Set(["page-load","user-action","navigation"]),E=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;export function templatePath(e){return e.replace(/[?#].*$/,"").split("/").map(t=>E.test(t)||/^[0-9a-f]{16,}$/i.test(t)||/^\d{2,}$/.test(t)?":id":t).join("/")}c(templatePath,"templatePath"),d(templatePath,"templatePath"),s(templatePath,"templatePath");function w(e){const t=/^ui:(?:.*\/)?([^/:]+?)(?:\.[a-z]+)?:\d+:([A-Za-z]+)$/.exec(e);return t?`${t[1]} \xB7 ${t[2]}`:e}c(w,"$"),d(w,"x"),s(w,"componentOf");export function scriptFamily(e){let t=e.replace(/[-_:][0-9a-f]{6,}(?:-[0-9a-f]+)*$/i,"");return t=t.replace(/[-_:](?=[a-z0-9]*\d)[a-z0-9]{6,}$/i,""),t=t.replace(/[-_:]\d+$/,""),t||e}c(scriptFamily,"scriptFamily"),d(scriptFamily,"scriptFamily"),s(scriptFamily,"scriptFamily");function k(e,t,n,r){const o=t.nodeId,i=o?/^(page|route|ambient):(.*)$/.exec(o):null;if(i)return`${i[1]}:${templatePath(i[2])}`;if(t.type&&O[t.type]==="user-action"&&o)return w(o);if(e==="test")return scriptFamily(n.flowId);const u=n.segments.find(l=>l.kind==="request"&&l.route);if(u?.route)return`${u.method??"GET"} ${templatePath(u.route)}`;const a=r.find(l=>y(l)==="ai-call");return a&&b(a.raw)?`ai \xB7 ${p(a.raw.model)??p(a.raw.provider)??"call"}`:o?templatePath(o):void 0}c(k,"x"),d(k,"R"),s(k,"subjectOf");const R=10,_=1e3,C=3,N=500,P=1e3;function $(e,t){const n=new Set,r=t.segments.filter(i=>i.kind==="request");t.segments.some(i=>i.counts.errors>0)&&n.add("has-error"),r.some(i=>i.durationMs>=_)&&n.add("slow"),r.length>=R&&n.add("fan-out"),new Set(t.segments.flatMap(i=>i.projects)).size>=3&&n.add("multi-service"),e.some(i=>y(i)==="queue-enqueued")&&n.add("queue"),e.some(i=>y(i)==="ai-call"||i.source==="ai")&&n.add("ai"),t.stats.bookkeeping>=N&&t.stats.bookkeeping*2>=t.stats.events&&n.add("storm"),t.stats.events>=P&&n.add("large");const o=new Map;for(const i of r)(!i.part||i.part.index===1)&&o.set(i.label,(o.get(i.label)??0)+1);return[...o.values()].some(i=>i>=C)&&n.add("repeated-requests"),[...n].sort()}c($,"j"),d($,"F"),s($,"tagsOf");export function classifyFlow(e,t,n=[]){const r=h(e),o={flowId:t.flowId,origin:r,segments:t.segments},i=$(e,t),u=s((g,M,I)=>{const j=k(g,r,t,e);return{category:g,decidedBy:M,...I!==void 0?{ruleIndex:I}:{},tags:i,origin:r,...j?{subject:j}:{}}},"done"),a=n.findIndex(g=>g.category&&m(g,o));if(a!==-1)return u(n[a].category,"rule",a);if(B(t.flowId,r.nodeId))return u("test","test");const l=r.type?O[r.type]:void 0;if(l)return u(l,"origin");if(i.includes("ai"))return u("ai","shape");const x=t.segments.filter(g=>g.kind==="request");return x.length>0?u(x.every(g=>g.requestId?.startsWith("job:"))?"background":"api","shape"):t.segments.length>0&&t.segments.every(g=>g.kind==="ambient")?u("system","shape"):u("other","shape")}c(classifyFlow,"classifyFlow"),d(classifyFlow,"classifyFlow"),s(classifyFlow,"classifyFlow");export function categoryOfSegment(e,t,n=[]){const r=n.find(o=>o.category&&(o.route!==void 0||o.project!==void 0)&&o.flowId===void 0&&o.origin===void 0&&o.originType===void 0&&m(o,{flowId:e.flowId,origin:t.origin,segments:[e]}));return r?r.category:e.kind==="request"?e.requestId?.startsWith("job:")?"background":"api":e.kind==="ambient"?"system":e.kind==="origin"&&A.has(t.category)?t.category:"ui"}c(categoryOfSegment,"categoryOfSegment"),d(categoryOfSegment,"categoryOfSegment"),s(categoryOfSegment,"categoryOfSegment");export function groupFlows(e){return groupByCategory(e).map(t=>{const n=new Map;for(const o of t.items){const i=n.get(o.subject);i?i.push(o):n.set(o.subject,[o])}const r=[...n.entries()].sort((o,i)=>(o[0]===void 0?1:0)-(i[0]===void 0?1:0)||i[1].length-o[1].length||String(o[0]).localeCompare(String(i[0]))).map(([o,i])=>({subject:o,count:i.length,items:i}));return{...t,subjects:r}})}c(groupFlows,"groupFlows"),d(groupFlows,"groupFlows"),s(groupFlows,"groupFlows");export function groupByCategory(e){const t=new Map;for(const r of e){const o=t.get(r.category);o?o.push(r):t.set(r.category,[r])}const n=s(r=>{const o=CATEGORY_ORDER.indexOf(r);return o===-1?CATEGORY_ORDER.length:o},"rank");return[...t.entries()].sort((r,o)=>n(r[0])-n(o[0])||(r[0]<o[0]?-1:r[0]>o[0]?1:0)).map(([r,o])=>({category:r,count:o.length,items:o}))}c(groupByCategory,"groupByCategory"),d(groupByCategory,"groupByCategory"),s(groupByCategory,"groupByCategory");
|
package/lib/flow-segments.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var z=Object.defineProperty;var q=(e,t)=>z(e,"name",{value:t,configurable:!0});var L=Object.defineProperty,
|
|
1
|
+
"use strict";var z=Object.defineProperty;var q=(e,t)=>z(e,"name",{value:t,configurable:!0});var L=Object.defineProperty,I=q((e,t)=>L(e,"name",{value:t,configurable:!0}),"q"),C=Object.defineProperty,h=I((e,t)=>C(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"]);const H=new Set(["react","valtio","client-runtime","chrome","visual"]),x=h(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),m=h(e=>typeof e=="string"&&e!==""?e:void 0,"str"),j=h(e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,"num");function K(e){const t=x(e.raw)?e.raw:{},n=x(t.request)?t.request:{},r=x(t.span)?t.span:{},u=e.context??{},o=j(e.timestamp)??0,a=m(t.kind)??"",c=j(n.startedAt)??j(r.startTime)??j(t.startedAt),g=j(n.endedAt)??j(r.endTime)??(c!==void 0&&j(t.durationMs)!==void 0?c+t.durationMs:void 0),v=Math.min(o,c??o),k=Math.max(o,g??o),b=x(t.render)?t.render:{},d=x(t.update)?t.update:{},i=a==="render"?m(b.componentName):a==="state-update"?m(d.path)?.split(".").slice(0,2).join("."):void 0,w=m(t.queue),y=m(t.jobId),s=String(e.source),f=m(t.project)??m(u.projectName);return{event:e,id:e.id,ts:o,from:v,to:k,kind:a,source:s,...m(u.requestId)?{requestId:m(u.requestId)}:{},...m(u.parentRequestId)?{parentRequestId:m(u.parentRequestId)}:{},...w&&y?{queueKey:`${w}#${y}`}:{},browser:H.has(s)||s==="memory"&&f===void 0,bookkeeping:FLOW_BOOKKEEPING_KINDS.has(a),...f?{project:f}:{},...i?{subject:i}:{},...a==="fetch-start"||a==="fetch-done"?{route:O(m(t.url)),method:m(t.method)}:a==="server-request"?{route:m(n.route),method:m(n.method)}:a==="gateway-request"?{route:O(m(t.url)),method:m(t.method)}:{}}}q(K,"E"),I(K,"F"),h(K,"readItem");function O(e){if(!e)return;const t=e.search(/[?#]/),n=t===-1?e:e.slice(0,t),r=/^[a-z][a-z0-9+.-]*:\/\/[^/]*(\/.*)?$/i.exec(n);return r?r[1]??"/":n}q(O,"x"),I(O,"S"),h(O,"pathOnly");const J=h(e=>e.split(".")[0],"rootOf"),_=h((e,t)=>e.reduce((n,r)=>Math.min(n,t(r)),1/0),"minOf"),D=h((e,t)=>e.reduce((n,r)=>Math.max(n,t(r)),-1/0),"maxOf"),E=h((e,t)=>e.ts-t.ts||(e.id<t.id?-1:e.id>t.id?1:0),"compare"),F=h(e=>e.requestId&&!e.requestId.startsWith("job:")?J(e.requestId):void 0,"directFamilyOf");function N(e){if(e.requestId?.startsWith("job:"))return e.requestId.slice(4);if(e.queueKey&&e.kind!=="queue-enqueued"&&!e.requestId)return e.queueKey}q(N,"G"),I(N,"W"),h(N,"jobKeyOf");function G(e,t){const n=e.filter(o=>!o.parentRequestId&&(o.kind==="server-request"||o.kind==="gateway-request"||o.kind==="fetch-start"||o.kind==="fetch-done")).sort((o,a)=>o.from-a.from||E(o,a));if(n.length<2)return[e];const r=[];for(const o of n){const a=r[r.length-1];a&&o.from<=a.to+t?a.to=Math.max(a.to,o.to):r.push({from:o.from,to:o.to})}if(r.length<2)return[e];const u=r.map(()=>[]);for(const o of e){let a=r.findIndex(c=>o.ts>=c.from-t&&o.ts<=c.to+t);if(a===-1){a=0;for(let c=0;c<r.length;c+=1)r[c].from<=o.ts&&(a=c)}u[a].push(o)}return u.filter(o=>o.length>0)}q(G,"A"),I(G,"T"),h(G,"occurrencesOf");const P={debug:0,info:1,warning:2,error:3,fatal:4};function S(e,t){const n=[];let r=[];for(const u of e){const o=r[r.length-1];o&&u.ts-o.ts>=t&&(n.push(r),r=[]),r.push(u)}return r.length&&n.push(r),n}q(S,"K"),I(S,"v"),h(S,"runs");export function segmentFlow(e,t={}){const n={...DEFAULT_SEGMENT_OPTIONS};for(const[s,f]of Object.entries(t))typeof f=="number"&&Number.isFinite(f)&&(n[s]=f);const r=new Set,u=[];for(const s of e)r.has(s.id)||(r.add(s.id),u.push(K(s)));u.sort(E);const o=m(u[0]?.event.context?.flowId)??m(u[0]?.event.raw?.flowId)??"",a=new Map;for(const s of u)s.kind==="queue-enqueued"&&s.queueKey&&s.requestId&&!s.requestId.startsWith("job:")&&!a.has(s.queueKey)&&a.set(s.queueKey,s);const c=new Map,g=new Map,v=[];for(const s of u){const f=N(s),p=F(s);if(f!==void 0){const l=g.get(f);l?l.push(s):g.set(f,[s])}else if(p!==void 0){const l=c.get(p);l?l.push(s):c.set(p,[s])}else v.push(s)}const k=[],b=new Map;for(const[s,f]of c)G(f,n.occurrenceSlackMs).forEach((p,l)=>{const M={id:`${o}~r:${s}${l===0?"":`@${l+1}`}`,kind:"request",items:p,requestId:s};k.push(M);for(const $ of p)b.set($,M)});for(const[s,f]of g){const p=a.get(s),l=p?b.get(p):void 0;l?l.items.push(...f):k.push({id:`${o}~r:job:${s}`,kind:"request",items:f,requestId:`job:${s}`})}const d=u.filter(s=>s.kind==="fetch-done"&&F(s)!==void 0),i=new Map;for(const s of k)s.requestId&&i.set(s.requestId,[...i.get(s.requestId)??[],s]);const w=h((s,f)=>{const p=i.get(s);if(p)return p.find(l=>l.items.some(M=>M.kind==="fetch-done"&&M.ts===f))??p[p.length-1]},"owningUnit"),y=v.filter(s=>s.browser);for(const s of S(y,n.burstGapMs)){const f=s[0].ts,p=d.filter($=>$.ts<=f&&f-$.ts<=n.attachWindowMs),l=[...new Set(p.map($=>F($)))];if(l.length===1){const $=w(l[0],p[p.length-1].ts);if($){$.items.push(...s);continue}}const M=s.some($=>$.kind==="flow-origin");k.push({id:`${o}~${M?"o":"u"}:${s[0].id}`,kind:M?"origin":"ui",items:s,...l.length>1?{after:l.sort()}:{}})}for(const s of S(v.filter(f=>!f.browser),n.phaseGapMs))k.push({id:`${o}~a:${s[0].id}`,kind:"ambient",items:s});return W(o,u.length,k,n)}q(segmentFlow,"segmentFlow"),I(segmentFlow,"segmentFlow"),h(segmentFlow,"segmentFlow");function W(e,t,n,r){for(const d of n)d.items.sort(E);const u=n.map(d=>({unit:d,from:_(d.items,i=>i.from),to:D(d.items,i=>i.to)}));u.sort((d,i)=>d.from-i.from||(d.unit.id<i.unit.id?-1:1));const o=new Map;let a=0,c=-1/0;for(const d of u)(a===0||d.from-c>=r.phaseGapMs)&&(a+=1),c=Math.max(c,d.to),o.set(d.unit,a);const g=[];for(const d of u){const i=A(d.unit.items,r.maxSegmentEvents);i.forEach((w,y)=>{g.push(B(e,d.unit,w,o.get(d.unit),i.length>1?{index:y+1,total:i.length}:void 0))})}const v={};for(const d of g)for(const i of d.eventIds)v[i]=d.id;const k=[];for(const d of g){let i=k[d.phase-1];i||(i={index:d.phase,start:d.start,end:d.end,segmentIds:[]},k[d.phase-1]=i),i.start=Math.min(i.start,d.start),i.end=Math.max(i.end,d.end),i.segmentIds.push(d.id)}const b=g.reduce((d,i)=>d+i.counts.signal,0);return{flowId:e,segments:g,phases:k.filter(Boolean),assignment:v,stats:{events:t,signal:b,bookkeeping:t-b,segments:g.length,phases:k.filter(Boolean).length,largestSegment:g.reduce((d,i)=>Math.max(d,i.counts.total),0)}}}q(W,"B"),I(W,"_"),h(W,"assemble");function A(e,t){if(e.filter(o=>!o.bookkeeping).length<=t)return[e];const n=[];let r=[],u=0;for(const o of e)!o.bookkeeping&&u===t&&(n.push(r),r=[],u=0),r.push(o),o.bookkeeping||(u+=1);return r.length&&n.push(r),n}q(A,"R"),I(A,"U"),h(A,"chunk");function B(e,t,n,r,u){const o={total:n.length,signal:0,bookkeeping:0,errors:0,warnings:0},a=new Set;let c="debug";for(const i of n){i.bookkeeping?o.bookkeeping+=1:o.signal+=1;const w=String(i.event.severity);w==="error"||w==="fatal"?o.errors+=1:w==="warning"&&(o.warnings+=1),(P[w]??1)>(P[c]??0)&&(c=w),i.project&&a.add(i.project)}const g=t.kind==="ui"||t.kind==="origin"?R(n):[],v=_(n,i=>i.from),k=D(n,i=>i.to),b=T(t.items),d=t.id;return{id:u&&u.index>1?`${d}#${u.index}`:d,flowId:e,kind:t.kind,label:U(t,n,b,u,g),phase:r,start:v,end:k,durationMs:k-v,eventIds:n.map(i=>i.id),counts:o,projects:[...a].sort(),...b.route?{route:b.route}:{},...b.method?{method:b.method}:{},...t.requestId?{requestId:t.requestId}:{},...t.after?{after:t.after}:{},...g.length?{hot:g}:{},...u?{part:u}:{},worstSeverity:c}}q(B,"T"),I(B,"B"),h(B,"toSegment");function T(e){const t=e.find(n=>n.kind==="fetch-start"&&n.route)??e.find(n=>n.kind==="server-request"&&!n.parentRequestId&&n.route)??e.find(n=>n.kind==="gateway-request"&&n.route)??e.find(n=>n.kind==="fetch-done"&&n.route);return{...t?.route?{route:t.route}:{},...t?.method?{method:t.method.toUpperCase()}:{}}}q(T,"U"),I(T,"D"),h(T,"routeOf");function R(e){const t=new Map;for(const n of e)n.subject&&!n.bookkeeping&&t.set(n.subject,(t.get(n.subject)??0)+1);return[...t.entries()].sort((n,r)=>r[1]-n[1]||(n[0]<r[0]?-1:1)).slice(0,3).map(([n,r])=>r>1?`${n} \xD7${r}`:n)}q(R,"_"),I(R,"L"),h(R,"hotOf");function U(e,t,n,r,u){const o=r?` (part ${r.index}/${r.total})`:"";if(e.kind==="request"){if(n.route)return`${n.method?`${n.method} `:""}${n.route}${o}`;const a=t.find(c=>c.queueKey);return a?`job ${a.queueKey}${o}`:`request ${e.requestId??""}${o}`}return e.kind==="origin"?`${t.find(a=>a.kind==="flow-origin")?.event.title||"start"}${u.length?` \xB7 ${u.join(", ")}`:""}${o}`:e.kind==="ui"?`UI update${u.length?` \xB7 ${u.join(", ")}`:""}${o}`:`background${o}`}q(U,"D"),I(U,"z"),h(U,"labelOf");
|
package/lib/flow-shape.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export declare function trimFlowEvent(event: BaseEvent, opts?: FlowShapeOptions)
|
|
|
37
37
|
parentRequestId?: string | undefined;
|
|
38
38
|
requestId?: string | undefined;
|
|
39
39
|
role?: string | undefined;
|
|
40
|
-
source: "nx" | "vite" | "typescript" | "eslint" | "rollup" | "client-runtime" | "chrome" | "react" | "valtio" | "nestjs" | "nextjs" | "db" | "redis" | "queue" | "memory" | "visual" | "perf" | "security" | "gateway" | "external" | "ai";
|
|
40
|
+
source: "nx" | "vite" | "typescript" | "eslint" | "rollup" | "client-runtime" | "chrome" | "react" | "valtio" | "nestjs" | "nextjs" | "db" | "redis" | "queue" | "memory" | "visual" | "perf" | "security" | "gateway" | "external" | "ai" | "lens";
|
|
41
41
|
category: "db" | "memory" | "visual" | "security" | "ai" | "build" | "lint" | "typecheck" | "test" | "runtime" | "render" | "trace" | "state" | "network" | "backend" | "performance" | "deps" | "cluster";
|
|
42
42
|
severity: "error" | "debug" | "info" | "warning" | "fatal";
|
|
43
43
|
title: string;
|
|
@@ -74,7 +74,7 @@ export declare function buildFlowDetail(rawEvents: BaseEvent[], opts?: FlowShape
|
|
|
74
74
|
parentRequestId?: string | undefined;
|
|
75
75
|
requestId?: string | undefined;
|
|
76
76
|
role?: string | undefined;
|
|
77
|
-
source: "nx" | "vite" | "typescript" | "eslint" | "rollup" | "client-runtime" | "chrome" | "react" | "valtio" | "nestjs" | "nextjs" | "db" | "redis" | "queue" | "memory" | "visual" | "perf" | "security" | "gateway" | "external" | "ai";
|
|
77
|
+
source: "nx" | "vite" | "typescript" | "eslint" | "rollup" | "client-runtime" | "chrome" | "react" | "valtio" | "nestjs" | "nextjs" | "db" | "redis" | "queue" | "memory" | "visual" | "perf" | "security" | "gateway" | "external" | "ai" | "lens";
|
|
78
78
|
category: "db" | "memory" | "visual" | "security" | "ai" | "build" | "lint" | "typecheck" | "test" | "runtime" | "render" | "trace" | "state" | "network" | "backend" | "performance" | "deps" | "cluster";
|
|
79
79
|
severity: "error" | "debug" | "info" | "warning" | "fatal";
|
|
80
80
|
title: string;
|
package/lib/flow-shape.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var ge=Object.defineProperty;var A=(u,q)=>ge(u,"name",{value:q,configurable:!0});var $e=Object.defineProperty,g=A((u,q)=>$e(u,"name",{value:q,configurable:!0}),"h");import{redactDeep as ye,redactText as ue}from"./redact.js";import{boundedClone as ke}from"@lensmcp/protocol-types";export function areaOf(u){const{source:q,category:n,title:M,kind:y}=u;return q==="ai"?"ai":y?.startsWith("memory")||y==="db-query"?"data":q==="gateway"||y==="gateway-request"?"gateway":y==="queue-process"||y==="queue-active"||y==="queue-completed"||y==="queue-failed"?"services":q==="db"||q==="redis"||q==="queue"||y==="redis-op"||y?.startsWith("queue-")?"data":q==="external"||y==="egress"?"network":q==="nestjs"||q==="nest"?/(?:Repository|Repo|Dao|Store)\./.test(M)?"data":"services":q==="valtio"?"state":n==="network"?"network":"browser"}A(areaOf,"areaOf"),g(areaOf,"areaOf");const de=240,we=new Set(["systemPrompt","prompt","prompts","messages","completion","completions","input","output","draft","text","content","result","arguments","params"]),qe=new Set(["tenantId","caller","userId","accountId","email","subject"]),Me=8;function ce(u){const q=Y(u,0);return ke(ye({redacted:!0,...q}),{rawByteLimit:16*1024}).value}A(ce,"yt"),g(ce,"aiProjection");function Y(u,q){if(typeof u=="string")return le(u);if(u===null||typeof u!="object")return u;if(q>=Me)return;if(Array.isArray(u))return u.slice(0,32).map(M=>Y(M,q+1));const n={};for(const[M,y]of Object.entries(u))if(!qe.has(M)){if(we.has(M)){typeof y=="string"?n[`${M}Chars`]=y.length:Array.isArray(y)?n[`${M}Count`]=y.length:y!=null&&(n[`${M}Present`]=!0);continue}n[M]=Y(y,q+1)}return n}A(Y,"tt"),g(Y,"projectAi");function le(u){return u.length<=de?ue(u):`${ue(u.slice(0,de))}\u2026`}A(le,"kt"),g(le,"clipText");export function trimFlowEvent(u,q={}){const n=u.raw??{},M=n.render??{},y=n.span??{},W=n.request??{},f=g(d=>typeof d=="number"?d:void 0,"num"),b=n.loop??{},T=n.effect??{},P=f(n.durationMs)??f(y.durationMs)??f(W.durationMs)??f(b.durationMs)??f(M.actualDurationMs)??f(T.durationMs),p=typeof n.kind=="string"?n.kind:void 0,_=p==="fetch-done"||p==="fetch-error",K=f(M.commitTime),R=p==="render"&&K!==void 0&&Math.abs(K-u.timestamp)<6e4,G=_?u.timestamp:R?K:f(n.startedAt)??f(y.startTime)??f(W.startedAt)??f(b.startedAt)??(P!==void 0?u.timestamp-P:u.timestamp);let j;if(typeof n.query=="string"){const d=Array.isArray(n.params)?` [${n.params.join(", ")}]`:"",w=typeof n.result=="string"?` \u2192 ${n.result}`:"";j=n.query+d+w}else if(typeof n.command=="string"){const d=typeof n.value=="string"?` \u2192 ${n.value}`:n.hit===!1?" \u2192 (miss)":"";j=n.command+d}else if(p==="state-update"){const d=n.update??{};let w="";try{w=JSON.stringify(d.preview)}catch{}j=`${d.storeId??""}.${d.path??""} = ${w}`}else p==="queue-completed"&&typeof n.returned=="string"?j=`returned ${n.returned}`:p==="queue-enqueued"&&(j=`${n.job??"job"}#${n.jobId??"?"} \u2192 ${n.queue??""}${typeof n.data=="string"?" "+n.data:""}`);let F;if(p==="gateway-request")F=`${n.host??""}${String(n.url??"").split("?")[0]}`;else if(p==="fetch-start"||p==="fetch-done"||p==="fetch-error")try{const d=new URL(String(n.href??n.url??""));F=`${d.hostname}${d.pathname}`}catch{}let C;if(p==="gateway-request"&&Array.isArray(n.steps))C=n.steps.map(d=>{const w=[String(d.step)];return d.project&&w.push(String(d.project)),d.prefix&&w.push(String(d.prefix)),d.mode&&w.push(String(d.mode)+(d.ok===!1?" \u2717":d.ok===!0?" \u2713":"")),d.caller&&w.push("by "+String(d.caller)),d.pod&&w.push(String(d.pod)),typeof d.atMs=="number"&&w.push(`@${d.atMs}ms`),w.join(" ")}),j=C.map(d=>d.replace(/ @\d+ms$/,"")).join(" \u2192 ");else if(p==="egress")j=`${n.method??"GET"} ${n.host??""} \u2192 ${n.status??"?"}`;else if(u.source==="ai"){if(p==="ai-call"){const d=n.usage??{},w=d.promptTokens!==void 0||d.completionTokens!==void 0?` \xB7 ${f(d.promptTokens)??"?"}\u2192${f(d.completionTokens)??"?"} tok`:"",S=n.status!==void 0?` \xB7 ${String(n.status)}`:n.error?" \xB7 failed":"",z=f(n.toolCallCount)?` \xB7 ${f(n.toolCallCount)} tool call${f(n.toolCallCount)===1?"":"s"}`:"",L=f(n.durationMs)!==void 0?` \xB7 ${(f(n.durationMs)/1e3).toFixed(1)}s`:"";j=`${n.provider??""}/${n.model??"?"}${w}${S}${z}${L}${n.stream===!0?" \xB7 stream":""}`}else if(p==="ai-round"){const d=n.model??{},w=n.usage??{},S=Array.isArray(n.toolCalls)?n.toolCalls:[],z=`${f(w.promptTokens)??"?"}\u2192${f(w.completionTokens)??"?"} tok`,L=S.length?` \xB7 ${S.length} tool call${S.length===1?"":"s"}`:"",V=f(n.durationMs)!==void 0?` \xB7 ${(f(n.durationMs)/1e3).toFixed(1)}s`:"";j=`${d.provider??""}/${d.model??""} \xB7 ${z}${L}${V}`}else if(p==="ai-turn-start"){const d=Array.isArray(n.tools)?n.tools:[];j=`skill ${n.skill??""} \xB7 ${n.output??""}${d.length?" \xB7 tools: "+d.join(", "):""}`}else if(p==="ai-tool-call"){const d=n.call??{},w=n.result??{},S=f(n.durationMs)!==void 0?` \xB7 ${(f(n.durationMs)/1e3).toFixed(1)}s`:"";j=`${d.name??"tool"} ${w.error!=null?"\u2717 "+String(w.error):"\u2713"}${S}`}else if(p==="ai-turn-end"){const d=n.usage??{},w=f(n.rounds)!==void 0?` \xB7 ${f(n.rounds)} round${f(n.rounds)===1?"":"s"}`:"",S=f(n.durationMs)!==void 0?` \xB7 ${(f(n.durationMs)/1e3).toFixed(1)}s`:"";j=`${n.ok===!1?"FAILED":"ok"} \xB7 ${f(d.promptTokens)??"?"}+${f(d.completionTokens)??"?"} tok${w}${S}`}}let B;p==="db-query"&&typeof n.query=="string"?B=n.query:p==="redis-op"?B=`${n.op??""} ${String(n.key??"").replace(/\d+/g,"#")}`:p==="egress"?B=`${n.method??"GET"} ${n.host??""}`:p==="ai-call"?B=`ai ${n.provider??""} ${n.model??""} ${n.api??""}`:p==="queue-enqueued"?B=`enqueue ${n.queue??""}`:p==="span"&&typeof y.name=="string"?B=y.name:p==="memory-mutation"&&(B=u.title);const D=u.context??{},H=M.commitId??T.commitId??n.commitId,h=Array.isArray(M.why)?M.why.map(d=>typeof d?.type=="string"?d.type:void 0).filter(d=>!!d):[];return{id:u.id,t:u.timestamp,start:G,...B?{sig:B}:{},...F?{urlKey:F}:{},...typeof n.queue=="string"?{queue:n.queue}:{},...n.jobId!=null?{jobId:String(n.jobId)}:{},source:u.source,category:u.category,severity:u.severity,title:u.title,kind:p,area:areaOf({source:u.source,category:u.category,title:u.title,kind:p}),...typeof y.role=="string"?{role:y.role}:{},...typeof D.requestId=="string"?{requestId:D.requestId}:{},...typeof D.parentRequestId=="string"?{parentRequestId:D.parentRequestId}:{},...typeof H=="string"?{commitId:H}:{},...typeof M.componentName=="string"?{component:M.componentName}:{},...typeof M.phase=="string"?{phase:M.phase}:{},...h.length?{why:h}:{},...p==="effect-run"&&typeof T.hookLogicalId=="string"?{hook:T.hookLogicalId}:{},...p==="effect-run"&&T.cleanupRan===!0?{cleanup:!0}:{},...p==="render-commit-truncated"?{renderTotal:f(n.total),renderPublished:f(n.published)}:{},...typeof D.projectName=="string"?{project:D.projectName}:typeof n.project=="string"?{project:n.project}:{},...P!==void 0?{durationMs:P}:{},..._&&f(n.startedAt)!==void 0?{fetchStartedAt:f(n.startedAt)}:{},...u.source==="ai"?{ai:q.includeRaw?n:ce(n)}:{},...j?{detail:j}:{},...C?{steps:C}:{}}}A(trimFlowEvent,"trimFlowEvent"),g(trimFlowEvent,"trimFlowEvent");const fe=1;function pe(u){return u==="flow-origin"?0:u?.endsWith("-start")?1:u==="gateway-request"?2:u==="server-request"?3:u==="span"?4:u==="render"||u==="render-commit-truncated"?6:u==="effect-run"?7:5}A(pe,"wt"),g(pe,"kindRank");function E(u){return u.kind==="span"&&u.role==="controller"?3.5:u.kind==="queue-process"?3:pe(u.kind)}A(E,"J"),g(E,"causalRank");export function buildFlowDetail(u,q={}){const n=u.slice().filter(e=>{const t=e.raw??{},r=typeof t.kind=="string"?t.kind:"";if(r==="subscription-added"||r==="subscription-removed"||r==="hook-run"||r==="store-created"||r==="singleton-instance")return!1;const o=t.span;return!(typeof o?.name=="string"&&o.name.startsWith("nest.request "))}).map(e=>trimFlowEvent(e,q)),M=new Set;for(let e=n.length-1;e>=0;e--)M.has(n[e].id)?n.splice(e,1):M.add(n[e].id);const y=new Map;for(const e of n)(e.kind==="gateway-request"||e.kind==="queue-process")&&e.requestId&&!y.has(e.requestId)&&y.set(e.requestId,e.start);const W=g(e=>e.source!=="react"&&e.source!=="valtio"&&e.requestId&&y.has(e.requestId)?y.get(e.requestId):e.start,"anchorOf");n.sort((e,t)=>W(e)-W(t)||e.start-t.start||E(e)-E(t)||(t.durationMs??0)-(e.durationMs??0)||e.t-t.t);const f=g(e=>(e.kind==="span"||e.kind==="server-request"||e.kind==="gateway-request"||e.kind==="queue-process")&&(e.durationMs??0)>0,"spanLike"),b=n;for(const e of b)e.group=e.source==="react"||e.source==="valtio"||e.source==="client-runtime"||e.source==="visual"?"browser":"server";const T=new Map;for(const e of b)if((e.kind==="gateway-request"||e.kind==="queue-process")&&e.requestId&&e.project){const t=T.get(e.requestId)??[];t.push({project:e.project,start:e.start,end:e.start+(e.durationMs??0)}),T.set(e.requestId,t)}const P=g((e,t)=>{const r=T.get(e);if(r?.length)return r.every(o=>o.project===r[0].project)?r[0].project:r.filter(o=>o.start<=t+1&&o.end>=t-1).sort((o,s)=>s.start-o.start)[0]?.project},"projectOf");for(const e of b)if(!e.project&&e.source==="nestjs"&&e.requestId){const t=P(e.requestId,e.start);t&&(e.project=t)}for(const e of b){let t;const r=e.requestId;for(const o of b){if(o===e||!f(o)||o.group!==e.group||o.requestId!==r)continue;const s=o.project,c=e.project;if(o.kind!=="gateway-request"&&e.kind!=="gateway-request"&&s!==void 0&&c!==void 0&&s!==c)continue;const m=o.durationMs??0,$=e.durationMs??0,a=Math.abs(o.start-e.start)<=fe,i=E(o),l=E(e),k=o.start<=e.start;if(!(o.start+m>e.start&&(k||a&&i<l)&&(!a||(i!==l?i<l:k&&m>$))))continue;const x=t?E(t):-1,I=t?Math.abs(o.start-t.start)<=fe:!1;(!t||!I&&o.start>t.start||I&&i>x||I&&i===x&&(o.durationMs??0)<(t.durationMs??0))&&(t=o)}t&&(e.parent=t.id)}const p=new Map;for(const e of b){if(!e.requestId)continue;const t=p.get(e.requestId);t?t.push(e):p.set(e.requestId,[e])}const _=new Map(b.map(e=>[e.id,e])),K=g((e,t)=>{const r=(p.get(e)??[]).filter(o=>f(o)&&o.start<=t&&o.start+(o.durationMs??0)>=t);if(r.length!==0)return r.sort((o,s)=>s.start-o.start||(o.durationMs??0)-(s.durationMs??0)),r[0]},"callerNodeFor");for(const e of b){if(!e.parentRequestId||e.kind!=="server-request"&&e.kind!=="gateway-request")continue;const t=e.parent?_.get(e.parent):void 0;if(t&&t.requestId===e.requestId)continue;const r=K(e.parentRequestId,e.start);r&&r!==e&&r.start<=e.start&&(e.parent=r.id)}const R=b,G=new Map;for(const e of R)e.kind==="gateway-request"&&e.requestId&&!G.has(e.requestId)&&G.set(e.requestId,e);for(const e of R)if(e.group==="server"&&!e.parent&&e.requestId&&e.kind!=="gateway-request"){const t=G.get(e.requestId);t&&t!==e&&t.start<=e.start&&(e.parent=t.id)}const j=new Set,F=new Set,C=[];for(const e of R){if(e.kind!=="gateway-request")continue;if(!e.requestId){C.push(e);continue}const t=p.get(e.requestId)??[];if(t.filter(s=>s.kind==="gateway-request").sort((s,c)=>s.start-c.start)[0]!==e)continue;const r=t.find(s=>s.kind==="fetch-start"),o=t.find(s=>s.kind==="fetch-done"||s.kind==="fetch-error");if(!r&&!o){C.push(e);continue}r&&(e.fetchStartId=r.id,j.add(r.id)),o&&(e.fetchDoneId=o.id,F.add(o.id))}const B=new Map;for(const e of R){if(!e.urlKey)continue;const t=B.get(e.urlKey)??{gws:[],starts:[],dones:[]};e.kind==="gateway-request"?C.includes(e)&&t.gws.push(e):e.kind==="fetch-start"?j.has(e.id)||t.starts.push(e):(e.kind==="fetch-done"||e.kind==="fetch-error")&&(F.has(e.id)||t.dones.push(e)),B.set(e.urlKey,t)}for(const{gws:e,starts:t,dones:r}of B.values()){e.sort((s,c)=>s.start-c.start),t.sort((s,c)=>s.start-c.start);const o=new Set;e.forEach((s,c)=>{const m=t[c];m&&(s.fetchStartId=m.id);const $=m?m.t:s.start;let a,i=1/0;for(const l of r){if(o.has(l.id))continue;const k=l.fetchStartedAt??l.start-(l.durationMs??0),x=Math.abs(k-$);x<i&&(i=x,a=l)}a&&(s.fetchDoneId=a.id,o.add(a.id))})}const D=new Map,H=new Map;for(const e of R)!e.queue||!e.jobId||(e.kind==="queue-enqueued"&&D.set(`${e.queue}#${e.jobId}`,e),e.kind==="queue-process"&&H.set(`${e.queue}#${e.jobId}`,e));for(const e of R){if(!e.queue||!e.jobId)continue;const t=`${e.queue}#${e.jobId}`;if(e.kind==="queue-process"&&!e.parent){const r=D.get(t);r&&r!==e&&r.start<=e.start&&(e.parent=r.id)}else if(e.kind==="queue-active"||e.kind==="queue-completed"||e.kind==="queue-failed"){const r=H.get(t);r&&r!==e&&r.start<=e.start&&(e.parent=r.id)}}let h=b;{const e=new Map;for(const r of h)r.kind==="fetch-start"&&e.set(r.id,r);const t=new Map;for(const r of h){if(r.kind!=="fetch-done"&&r.kind!=="fetch-error")continue;const o=[...e.values()].find(m=>m.requestId&&m.requestId===r.requestId)?.id,s=o?e.get(o):void 0;if(!s)continue;const c=r.fetchStartedAt??s.start;s.title=r.title,s.severity=r.severity,s.durationMs=r.durationMs??Math.max(0,r.t-c),s.kind="fetch",r.detail&&!s.detail&&(s.detail=r.detail),t.set(r.id,s.id)}if(t.size>0){h=h.filter(r=>!t.has(r.id));for(const r of h)for(r.fetchDoneId&&t.has(r.fetchDoneId)&&(r.fetchDoneId=t.get(r.fetchDoneId));r.parent&&t.has(r.parent);)r.parent=t.get(r.parent)}}const d=g(e=>!!e.commitId&&(e.kind==="render"||e.kind==="effect-run"||e.kind==="render-commit-truncated"),"commitMember"),w=g(e=>[...new Set(e)],"uniq"),S=g(e=>w(e.map(t=>t.component).filter(t=>!!t)),"named"),z=g(e=>e.length<=2?e.join(" + "):`${e[0]} + ${e.length-1} more`,"nameList"),L=g(e=>{const t=new Map;for(const r of e)r.component&&t.set(r.component,(t.get(r.component)??0)+1);return[...t].map(([r,o])=>o>1?`${r} \xD7${o}`:r).join(", ")},"tally"),V=g(e=>{if(!e)return"effect";const t=/([^/\\]+?):(\d+)(?::\d+)?$/.exec(e);return t?`${t[1]}:${t[2]}`:e},"shortHook"),X=g(e=>`${V(e.hook)}${e.cleanup?" (cleanup)":""}`,"hookLabel"),Z=g(e=>{const t=Math.min(...e.map(o=>o.start)),r=Math.max(...e.map(o=>o.start+(o.durationMs??0)));return{start:t,durationMs:r-t}},"extent"),ee=g(e=>(delete e.component,delete e.why,delete e.phase,delete e.hook,delete e.cleanup,delete e.renderTotal,delete e.renderPublished,e),"asGroup");function te(e){const t=e[0],r=e.filter(v=>v.kind==="render"),o=e.filter(v=>v.kind==="effect-run"),s=e.find(v=>v.kind==="render-commit-truncated"),c=[...r].sort((v,U)=>(U.durationMs??0)-(v.durationMs??0)),m=c.filter(v=>(v.why??[]).some(U=>U!=="parent-render")),$=w(m.flatMap(v=>(v.why??[]).filter(U=>U!=="parent-render"))),a=S(m),i=r.filter(v=>v.phase==="mount"),l=r.filter(v=>v.phase!=="mount"&&!m.includes(v)),k=c[0]?.component??"view",x=r.length>0&&i.length===r.length,I=$.length?$.join(" + "):void 0,N=x?"mount":"update",O=a.length?`view update \xB7 ${z(a)} \u2190 ${I}`:x?`view mount \xB7 ${k}`:`view update \xB7 ${k}`,ae=s?.renderTotal??r.length,he=[i.length?`mounted ${L(i)}`:"",l.length?`re-rendered ${L(l)}`:"",!a.length&&!x&&r.length?"trigger not recorded \u2014 every captured render came from its parent":"",s?`${ae} renders, ${s.renderPublished??r.length} recorded (per-commit cap)`:`${r.length} render${r.length===1?"":"s"}`,o.length?`${o.length} effect${o.length===1?"":"s"}: ${o.map(X).join(", ")}`:""].filter(Boolean).join(" \xB7 "),ie=S(r);return ee({...t,...Z(e),kind:"view-update",title:O,detail:he,commitId:t.commitId,viewPhase:N,...I?{cause:I}:{},causeComponents:a,components:ie,mounted:S(i),renderCount:ae,recordedRenders:r.length,effects:o.length,effectHooks:o.map(X),memberIds:e.map(v=>v.id),sig:`commit:${N}:${I??"-"}:${a.join(",")}:${ie.slice().sort().join(",")}`,severity:e.some(v=>v.severity==="error")?"error":t.severity})}A(te,"ct"),g(te,"viewUpdateNode");function re(e){const t=e[0],r=e.map(X);return ee({...t,...Z(e),kind:"commit-effects",title:e.length===1?`effect \xB7 ${r[0]}`:`effects \xB7 ${r[0]} + ${e.length-1} more`,detail:r.join(", "),commitId:t.commitId,effects:e.length,effectHooks:r,memberIds:e.map(o=>o.id),sig:`effects:${r.slice().sort().join(",")}`})}A(re,"dt"),g(re,"effectsNode");const me=g(e=>w(e.map(t=>t==="state-update"?"state update":t==="fetch-start"?"request":t==="flow-origin"?"interaction":"response")).join(" + "),"describeInputs");function oe(e,t){const r=e[0],o=e[e.length-1],s=e.length,c=r.detail,m=Math.min(...e.map(l=>l.start)),$=Math.max(...e.map(l=>l.start+(l.durationMs??0))),a=Math.round(e.reduce((l,k)=>l+(k.durationMs??0),0)/s*10)/10,i=Math.round(($-m)*10)/10;r.count=s,r.avgMs=a,r.wallMs=i,r.durationMs=$-m,r.items=e.slice(0,12).map(l=>({start:l.start-m,...l.durationMs!=null?{durationMs:l.durationMs}:{}})),r.memberIds=e.flatMap(l=>l.memberIds??[l.id]),r.title=`\xD7${s} ${r.title}`,e.some(l=>l.severity==="error")&&(r.severity="error"),r.kind==="view-update"?r.detail=[`${s} commits, ${t.length?`one per ${me(t)}`:"back to back"}`,`avg ${a}ms \xB7 wall ${i}ms`,c??""].filter(Boolean).join(" \xB7 "):r.kind==="state-update"&&c&&o.detail?r.detail=`${s} updates in a row \xB7 wall ${i}ms \xB7 first ${c} \xB7 last ${o.detail}`:r.detail=[`${s} in a row \xB7 wall ${i}ms`,c??""].filter(Boolean).join(" \xB7 ")}A(oe,"ft"),g(oe,"collapseRepeat");const J=[],Q=new Map,ne=new Set;for(let e=0;e<h.length;e++){if(ne.has(e))continue;const t=h[e];if(!d(t)){J.push(t);continue}const r=[e];for(let c=e+1;c<h.length;c++){const m=h[c];if(m.group==="browser"){if(!d(m)||m.commitId!==t.commitId)break;r.push(c)}}for(const c of r)ne.add(c);const o=r.map(c=>h[c]),s=o.some(c=>c.kind!=="effect-run")?te(o):re(o);for(const c of o)c.id!==s.id&&Q.set(c.id,s.id);J.push(s)}if(Q.size>0||J.some(e=>e.kind==="view-update"||e.kind==="commit-effects")){h=J;for(const e of h)for(;e.parent&&Q.has(e.parent);)e.parent=Q.get(e.parent)}{const e=new Map;for(const t of h)t.kind==="view-update"&&t.commitId&&!e.has(t.commitId)&&e.set(t.commitId,t);for(const t of h){if(t.kind!=="commit-effects"||t.parent||!t.commitId)continue;const r=e.get(t.commitId);r&&r.start<=t.start&&(t.parent=r.id)}}{const e=new Set(["state-update","fetch","fetch-start","fetch-done","fetch-error","flow-origin"]),t=h.map((a,i)=>a.group==="browser"?i:-1).filter(a=>a>=0),r=g(a=>`${a.kind}|${a.sig??a.title}`,"keyOf"),o=t.map(a=>r(h[a])),s=g((a,i,l)=>{for(let k=0;k<l;k++)if(o[a+k]!==o[i+k])return!1;return!0},"sameBlock"),c=g(a=>o[a].split("|")[0],"kindAt"),m=g(a=>{let i=0,l=1;for(let k=1;k<=4&&a+k<=o.length;k++){let x=1;for(;a+(x+1)*k<=o.length&&s(a,a+x*k,k);)x+=1;x>=3&&k*x>i*l&&(i=k,l=x)}return{k:i,r:l}},"bestBlockAt"),$=new Map;for(let a=0;a<o.length;){const{k:i,r:l}=m(a);if(i===0){a+=1;continue}const k=[...Array(i).keys()].find(I=>e.has(c(a+I)));if(k!==void 0&&k>0){const I=m(a+k);if(I.k===i&&I.r>=3&&I.r>=l-1){a+=k;continue}}const x=o.slice(a,a+i).map(I=>I.split("|")[0]).filter(I=>e.has(I));for(let I=0;I<i;I++){const N=[];for(let O=0;O<l;O++)N.push(h[t[a+I+O*i]]);oe(N,x);for(const O of N.slice(1))$.set(O.id,N[0].id)}a+=i*l}if($.size>0){h=h.filter(a=>!$.has(a.id));for(const a of h)for(;a.parent&&$.has(a.parent);)a.parent=$.get(a.parent)}}{const e=new Map(h.map(t=>[t.id,t]));for(const t of h){const r=new Set([t.id]);let o=t;for(;o?.parent;){if(r.has(o.parent)){o.parent=void 0;break}r.add(o.parent),o=e.get(o.parent)}}}const se=g(e=>{const t=new Map;for(const o of h){if(!o.sig||f(o)!==e||o.kind==="server-request"||o.kind==="gateway-request"||o.group==="browser")continue;const s=`${o.parent??"root"}|${o.kind}|${o.sig}`,c=t.get(s);c?c.push(o):t.set(s,[o])}const r=new Map;for(const o of t.values()){if(o.length<3)continue;o.sort((i,l)=>i.start-l.start);const s=o[0];let c=!1;for(let i=0;i+1<o.length;i++)if(o[i+1].start<o[i].start+(o[i].durationMs??0)){c=!0;break}const m=s.start,$=Math.max(...o.map(i=>i.start+(i.durationMs??0))),a=o.reduce((i,l)=>i+(l.durationMs??0),0);s.count=o.length,s.parallel=c,s.avgMs=Math.round(a/o.length*10)/10,s.wallMs=$-m,s.durationMs=$-m,s.title=`\xD7${o.length} ${s.title.replace(/\s*\((?:\d+ rows?, )?\d+ms\)$/,"")}`,s.detail=`${s.sig} \xD7${o.length} ${c?"\u2016 parallel":"\u21BB sequential loop"} \xB7 avg ${s.avgMs}ms \xB7 wall ${s.wallMs}ms`,s.items=o.slice(0,12).map(i=>({start:i.start-m,...i.durationMs!=null?{durationMs:i.durationMs}:{}})),s.memberIds=o.flatMap(i=>i.memberIds??[i.id]),o.some(i=>i.severity==="error")&&(s.severity="error");for(const i of o.slice(1))r.set(i.id,s.id)}if(r.size!==0){h=h.filter(o=>!r.has(o.id));for(const o of h)for(;o.parent&&r.has(o.parent);)o.parent=r.get(o.parent)}},"aggregatePass");se(!0),se(!1);for(const e of h){if(!f(e))continue;const t=e.durationMs??0;if(t<40)continue;const r=h.filter($=>$.parent===e.id&&($.durationMs??0)>0).map($=>[$.start,$.start+($.durationMs??0)]).sort(($,a)=>$[0]-a[0]);let o=0,s=-1,c=-1;for(const[$,a]of r)$>c?(c>s&&(o+=c-s),s=$,c=a):a>c&&(c=a);c>s&&(o+=c-s);const m=Math.max(0,t-o);(m>=50||m/t>=.7&&t>=40)&&(e.selfMs=m,e.detail=`\u26A0 cpu-heavy: ${m}ms self-time of ${t}ms${e.detail?" \xB7 "+e.detail:""}`)}return{events:h}}A(buildFlowDetail,"buildFlowDetail"),g(buildFlowDetail,"buildFlowDetail");
|
|
1
|
+
"use strict";var $t=Object.defineProperty;var A=(d,q)=>$t(d,"name",{value:q,configurable:!0});var kt=Object.defineProperty,D=A((d,q)=>kt(d,"name",{value:q,configurable:!0}),"A"),yt=Object.defineProperty,g=D((d,q)=>yt(d,"name",{value:q,configurable:!0}),"h");import{redactDeep as wt,redactText as ft}from"./redact.js";import{boundedClone as qt}from"@lensmcp/protocol-types";export function areaOf(d){const{source:q,category:s,title:M,kind:k}=d;return q==="ai"?"ai":k?.startsWith("memory")||k==="db-query"?"data":q==="gateway"||k==="gateway-request"?"gateway":k==="queue-process"||k==="queue-active"||k==="queue-completed"||k==="queue-failed"?"services":q==="db"||q==="redis"||q==="queue"||k==="redis-op"||k?.startsWith("queue-")?"data":q==="external"||k==="egress"?"network":q==="nestjs"||q==="nest"?/(?:Repository|Repo|Dao|Store)\./.test(M)?"data":"services":q==="valtio"?"state":s==="network"?"network":"browser"}A(areaOf,"areaOf"),D(areaOf,"areaOf"),g(areaOf,"areaOf");const pt=240,Mt=new Set(["systemPrompt","prompt","prompts","messages","completion","completions","input","output","draft","text","content","result","arguments","params"]),It=new Set(["tenantId","caller","userId","accountId","email","subject"]),vt=8;function ot(d){const q=V(d,0);return qt(wt({redacted:!0,...q}),{rawByteLimit:16*1024}).value}A(ot,"ce"),D(ot,"yt"),g(ot,"aiProjection");function V(d,q){if(typeof d=="string")return st(d);if(d===null||typeof d!="object")return d;if(q>=vt)return;if(Array.isArray(d))return d.slice(0,32).map(M=>V(M,q+1));const s={};for(const[M,k]of Object.entries(d))if(!It.has(M)){if(Mt.has(M)){typeof k=="string"?s[`${M}Chars`]=k.length:Array.isArray(k)?s[`${M}Count`]=k.length:k!=null&&(s[`${M}Present`]=!0);continue}s[M]=V(k,q+1)}return s}A(V,"Y"),D(V,"tt"),g(V,"projectAi");function st(d){return d.length<=pt?ft(d):`${ft(d.slice(0,pt))}\u2026`}A(st,"le"),D(st,"kt"),g(st,"clipText");export function trimFlowEvent(d,q={}){const s=d.raw??{},M=s.render??{},k=s.span??{},K=s.request??{},f=g(c=>typeof c=="number"?c:void 0,"num"),j=s.loop??{},T=s.effect??{},E=f(s.durationMs)??f(k.durationMs)??f(K.durationMs)??f(j.durationMs)??f(M.actualDurationMs)??f(T.durationMs),p=typeof s.kind=="string"?s.kind:void 0,_=p==="fetch-done"||p==="fetch-error",W=f(M.commitTime),C=p==="render"&&W!==void 0&&Math.abs(W-d.timestamp)<6e4,G=_?d.timestamp:C?W:f(s.startedAt)??f(k.startTime)??f(K.startedAt)??f(j.startedAt)??(E!==void 0?d.timestamp-E:d.timestamp);let b;if(typeof s.query=="string"){const c=Array.isArray(s.params)?` [${s.params.join(", ")}]`:"",w=typeof s.result=="string"?` \u2192 ${s.result}`:"";b=s.query+c+w}else if(typeof s.command=="string"){const c=typeof s.value=="string"?` \u2192 ${s.value}`:s.hit===!1?" \u2192 (miss)":"";b=s.command+c}else if(p==="state-update"){const c=s.update??{};let w="";try{w=JSON.stringify(c.preview)}catch{}b=`${c.storeId??""}.${c.path??""} = ${w}`}else p==="queue-completed"&&typeof s.returned=="string"?b=`returned ${s.returned}`:p==="queue-enqueued"&&(b=`${s.job??"job"}#${s.jobId??"?"} \u2192 ${s.queue??""}${typeof s.data=="string"?" "+s.data:""}`);let O;if(p==="gateway-request")O=`${s.host??""}${String(s.url??"").split("?")[0]}`;else if(p==="fetch-start"||p==="fetch-done"||p==="fetch-error")try{const c=new URL(String(s.href??s.url??""));O=`${c.hostname}${c.pathname}`}catch{}let F;if(p==="gateway-request"&&Array.isArray(s.steps))F=s.steps.map(c=>{const w=[String(c.step)];return c.project&&w.push(String(c.project)),c.prefix&&w.push(String(c.prefix)),c.mode&&w.push(String(c.mode)+(c.ok===!1?" \u2717":c.ok===!0?" \u2713":"")),c.caller&&w.push("by "+String(c.caller)),c.pod&&w.push(String(c.pod)),typeof c.atMs=="number"&&w.push(`@${c.atMs}ms`),w.join(" ")}),b=F.map(c=>c.replace(/ @\d+ms$/,"")).join(" \u2192 ");else if(p==="egress")b=`${s.method??"GET"} ${s.host??""} \u2192 ${s.status??"?"}`;else if(d.source==="ai"){if(p==="ai-call"){const c=s.usage??{},w=c.promptTokens!==void 0||c.completionTokens!==void 0?` \xB7 ${f(c.promptTokens)??"?"}\u2192${f(c.completionTokens)??"?"} tok`:"",S=s.status!==void 0?` \xB7 ${String(s.status)}`:s.error?" \xB7 failed":"",J=f(s.toolCallCount)?` \xB7 ${f(s.toolCallCount)} tool call${f(s.toolCallCount)===1?"":"s"}`:"",z=f(s.durationMs)!==void 0?` \xB7 ${(f(s.durationMs)/1e3).toFixed(1)}s`:"";b=`${s.provider??""}/${s.model??"?"}${w}${S}${J}${z}${s.stream===!0?" \xB7 stream":""}`}else if(p==="ai-round"){const c=s.model??{},w=s.usage??{},S=Array.isArray(s.toolCalls)?s.toolCalls:[],J=`${f(w.promptTokens)??"?"}\u2192${f(w.completionTokens)??"?"} tok`,z=S.length?` \xB7 ${S.length} tool call${S.length===1?"":"s"}`:"",Y=f(s.durationMs)!==void 0?` \xB7 ${(f(s.durationMs)/1e3).toFixed(1)}s`:"";b=`${c.provider??""}/${c.model??""} \xB7 ${J}${z}${Y}`}else if(p==="ai-turn-start"){const c=Array.isArray(s.tools)?s.tools:[];b=`skill ${s.skill??""} \xB7 ${s.output??""}${c.length?" \xB7 tools: "+c.join(", "):""}`}else if(p==="ai-tool-call"){const c=s.call??{},w=s.result??{},S=f(s.durationMs)!==void 0?` \xB7 ${(f(s.durationMs)/1e3).toFixed(1)}s`:"";b=`${c.name??"tool"} ${w.error!=null?"\u2717 "+String(w.error):"\u2713"}${S}`}else if(p==="ai-turn-end"){const c=s.usage??{},w=f(s.rounds)!==void 0?` \xB7 ${f(s.rounds)} round${f(s.rounds)===1?"":"s"}`:"",S=f(s.durationMs)!==void 0?` \xB7 ${(f(s.durationMs)/1e3).toFixed(1)}s`:"";b=`${s.ok===!1?"FAILED":"ok"} \xB7 ${f(c.promptTokens)??"?"}+${f(c.completionTokens)??"?"} tok${w}${S}`}}let B;p==="db-query"&&typeof s.query=="string"?B=s.query:p==="redis-op"?B=`${s.op??""} ${String(s.key??"").replace(/\d+/g,"#")}`:p==="egress"?B=`${s.method??"GET"} ${s.host??""}`:p==="ai-call"?B=`ai ${s.provider??""} ${s.model??""} ${s.api??""}`:p==="queue-enqueued"?B=`enqueue ${s.queue??""}`:p==="span"&&typeof k.name=="string"?B=k.name:p==="memory-mutation"&&(B=d.title);const R=d.context??{},H=M.commitId??T.commitId??s.commitId,h=Array.isArray(M.why)?M.why.map(c=>typeof c?.type=="string"?c.type:void 0).filter(c=>!!c):[];return{id:d.id,t:d.timestamp,start:G,...B?{sig:B}:{},...O?{urlKey:O}:{},...typeof s.queue=="string"?{queue:s.queue}:{},...s.jobId!=null?{jobId:String(s.jobId)}:{},source:d.source,category:d.category,severity:d.severity,title:d.title,kind:p,area:areaOf({source:d.source,category:d.category,title:d.title,kind:p}),...typeof k.role=="string"?{role:k.role}:{},...typeof R.requestId=="string"?{requestId:R.requestId}:{},...typeof R.parentRequestId=="string"?{parentRequestId:R.parentRequestId}:{},...typeof H=="string"?{commitId:H}:{},...typeof M.componentName=="string"?{component:M.componentName}:{},...typeof M.phase=="string"?{phase:M.phase}:{},...h.length?{why:h}:{},...p==="effect-run"&&typeof T.hookLogicalId=="string"?{hook:T.hookLogicalId}:{},...p==="effect-run"&&T.cleanupRan===!0?{cleanup:!0}:{},...p==="render-commit-truncated"?{renderTotal:f(s.total),renderPublished:f(s.published)}:{},...typeof R.projectName=="string"?{project:R.projectName}:typeof s.project=="string"?{project:s.project}:{},...E!==void 0?{durationMs:E}:{},..._&&f(s.startedAt)!==void 0?{fetchStartedAt:f(s.startedAt)}:{},...d.source==="ai"?{ai:q.includeRaw?s:ot(s)}:{},...b?{detail:b}:{},...F?{steps:F}:{}}}A(trimFlowEvent,"trimFlowEvent"),D(trimFlowEvent,"trimFlowEvent"),g(trimFlowEvent,"trimFlowEvent");const mt=1;function nt(d){return d==="flow-origin"?0:d?.endsWith("-start")?1:d==="gateway-request"?2:d==="server-request"?3:d==="span"?4:d==="render"||d==="render-commit-truncated"?6:d==="effect-run"?7:5}A(nt,"pe"),D(nt,"wt"),g(nt,"kindRank");function N(d){return d.kind==="span"&&d.role==="controller"?3.5:d.kind==="queue-process"?3:nt(d.kind)}A(N,"E"),D(N,"J"),g(N,"causalRank");export function buildFlowDetail(d,q={}){const s=d.slice().filter(t=>{const e=t.raw??{},r=typeof e.kind=="string"?e.kind:"";if(r==="subscription-added"||r==="subscription-removed"||r==="hook-run"||r==="store-created"||r==="singleton-instance")return!1;const o=e.span;return!(typeof o?.name=="string"&&o.name.startsWith("nest.request "))}).map(t=>trimFlowEvent(t,q)),M=new Set;for(let t=s.length-1;t>=0;t--)M.has(s[t].id)?s.splice(t,1):M.add(s[t].id);const k=new Map;for(const t of s)(t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&!k.has(t.requestId)&&k.set(t.requestId,t.start);const K=g(t=>t.source!=="react"&&t.source!=="valtio"&&t.requestId&&k.has(t.requestId)?k.get(t.requestId):t.start,"anchorOf");s.sort((t,e)=>K(t)-K(e)||t.start-e.start||N(t)-N(e)||(e.durationMs??0)-(t.durationMs??0)||t.t-e.t);const f=g(t=>(t.kind==="span"||t.kind==="server-request"||t.kind==="gateway-request"||t.kind==="queue-process")&&(t.durationMs??0)>0,"spanLike"),j=s;for(const t of j)t.group=t.source==="react"||t.source==="valtio"||t.source==="client-runtime"||t.source==="visual"?"browser":"server";const T=new Map;for(const t of j)if((t.kind==="gateway-request"||t.kind==="queue-process")&&t.requestId&&t.project){const e=T.get(t.requestId)??[];e.push({project:t.project,start:t.start,end:t.start+(t.durationMs??0)}),T.set(t.requestId,e)}const E=g((t,e)=>{const r=T.get(t);if(r?.length)return r.every(o=>o.project===r[0].project)?r[0].project:r.filter(o=>o.start<=e+1&&o.end>=e-1).sort((o,n)=>n.start-o.start)[0]?.project},"projectOf");for(const t of j)if(!t.project&&t.source==="nestjs"&&t.requestId){const e=E(t.requestId,t.start);e&&(t.project=e)}for(const t of j){let e;const r=t.requestId;for(const o of j){if(o===t||!f(o)||o.group!==t.group||o.requestId!==r)continue;const n=o.project,u=t.project;if(o.kind!=="gateway-request"&&t.kind!=="gateway-request"&&n!==void 0&&u!==void 0&&n!==u)continue;const m=o.durationMs??0,$=t.durationMs??0,a=Math.abs(o.start-t.start)<=mt,i=N(o),l=N(t),y=o.start<=t.start;if(!(o.start+m>t.start&&(y||a&&i<l)&&(!a||(i!==l?i<l:y&&m>$))))continue;const x=e?N(e):-1,I=e?Math.abs(o.start-e.start)<=mt:!1;(!e||!I&&o.start>e.start||I&&i>x||I&&i===x&&(o.durationMs??0)<(e.durationMs??0))&&(e=o)}e&&(t.parent=e.id)}const p=new Map;for(const t of j){if(!t.requestId)continue;const e=p.get(t.requestId);e?e.push(t):p.set(t.requestId,[t])}const _=new Map(j.map(t=>[t.id,t])),W=g((t,e)=>{const r=(p.get(t)??[]).filter(o=>f(o)&&o.start<=e&&o.start+(o.durationMs??0)>=e);if(r.length!==0)return r.sort((o,n)=>n.start-o.start||(o.durationMs??0)-(n.durationMs??0)),r[0]},"callerNodeFor");for(const t of j){if(!t.parentRequestId||t.kind!=="server-request"&&t.kind!=="gateway-request")continue;const e=t.parent?_.get(t.parent):void 0;if(e&&e.requestId===t.requestId)continue;const r=W(t.parentRequestId,t.start);r&&r!==t&&r.start<=t.start&&(t.parent=r.id)}const C=j,G=new Map;for(const t of C)t.kind==="gateway-request"&&t.requestId&&!G.has(t.requestId)&&G.set(t.requestId,t);for(const t of C)if(t.group==="server"&&!t.parent&&t.requestId&&t.kind!=="gateway-request"){const e=G.get(t.requestId);e&&e!==t&&e.start<=t.start&&(t.parent=e.id)}const b=new Set,O=new Set,F=[];for(const t of C){if(t.kind!=="gateway-request")continue;if(!t.requestId){F.push(t);continue}const e=p.get(t.requestId)??[];if(e.filter(n=>n.kind==="gateway-request").sort((n,u)=>n.start-u.start)[0]!==t)continue;const r=e.find(n=>n.kind==="fetch-start"),o=e.find(n=>n.kind==="fetch-done"||n.kind==="fetch-error");if(!r&&!o){F.push(t);continue}r&&(t.fetchStartId=r.id,b.add(r.id)),o&&(t.fetchDoneId=o.id,O.add(o.id))}const B=new Map;for(const t of C){if(!t.urlKey)continue;const e=B.get(t.urlKey)??{gws:[],starts:[],dones:[]};t.kind==="gateway-request"?F.includes(t)&&e.gws.push(t):t.kind==="fetch-start"?b.has(t.id)||e.starts.push(t):(t.kind==="fetch-done"||t.kind==="fetch-error")&&(O.has(t.id)||e.dones.push(t)),B.set(t.urlKey,e)}for(const{gws:t,starts:e,dones:r}of B.values()){t.sort((n,u)=>n.start-u.start),e.sort((n,u)=>n.start-u.start);const o=new Set;t.forEach((n,u)=>{const m=e[u];m&&(n.fetchStartId=m.id);const $=m?m.t:n.start;let a,i=1/0;for(const l of r){if(o.has(l.id))continue;const y=l.fetchStartedAt??l.start-(l.durationMs??0),x=Math.abs(y-$);x<i&&(i=x,a=l)}a&&(n.fetchDoneId=a.id,o.add(a.id))})}const R=new Map,H=new Map;for(const t of C)!t.queue||!t.jobId||(t.kind==="queue-enqueued"&&R.set(`${t.queue}#${t.jobId}`,t),t.kind==="queue-process"&&H.set(`${t.queue}#${t.jobId}`,t));for(const t of C){if(!t.queue||!t.jobId)continue;const e=`${t.queue}#${t.jobId}`;if(t.kind==="queue-process"&&!t.parent){const r=R.get(e);r&&r!==t&&r.start<=t.start&&(t.parent=r.id)}else if(t.kind==="queue-active"||t.kind==="queue-completed"||t.kind==="queue-failed"){const r=H.get(e);r&&r!==t&&r.start<=t.start&&(t.parent=r.id)}}let h=j;{const t=new Map;for(const r of h)r.kind==="fetch-start"&&t.set(r.id,r);const e=new Map;for(const r of h){if(r.kind!=="fetch-done"&&r.kind!=="fetch-error")continue;const o=[...t.values()].find(m=>m.requestId&&m.requestId===r.requestId)?.id,n=o?t.get(o):void 0;if(!n)continue;const u=r.fetchStartedAt??n.start;n.title=r.title,n.severity=r.severity,n.durationMs=r.durationMs??Math.max(0,r.t-u),n.kind="fetch",r.detail&&!n.detail&&(n.detail=r.detail),e.set(r.id,n.id)}if(e.size>0){h=h.filter(r=>!e.has(r.id));for(const r of h)for(r.fetchDoneId&&e.has(r.fetchDoneId)&&(r.fetchDoneId=e.get(r.fetchDoneId));r.parent&&e.has(r.parent);)r.parent=e.get(r.parent)}}const c=g(t=>!!t.commitId&&(t.kind==="render"||t.kind==="effect-run"||t.kind==="render-commit-truncated"),"commitMember"),w=g(t=>[...new Set(t)],"uniq"),S=g(t=>w(t.map(e=>e.component).filter(e=>!!e)),"named"),J=g(t=>t.length<=2?t.join(" + "):`${t[0]} + ${t.length-1} more`,"nameList"),z=g(t=>{const e=new Map;for(const r of t)r.component&&e.set(r.component,(e.get(r.component)??0)+1);return[...e].map(([r,o])=>o>1?`${r} \xD7${o}`:r).join(", ")},"tally"),Y=g(t=>{if(!t)return"effect";const e=/([^/\\]+?):(\d+)(?::\d+)?$/.exec(t);return e?`${e[1]}:${e[2]}`:t},"shortHook"),Z=g(t=>`${Y(t.hook)}${t.cleanup?" (cleanup)":""}`,"hookLabel"),at=g(t=>{const e=Math.min(...t.map(o=>o.start)),r=Math.max(...t.map(o=>o.start+(o.durationMs??0)));return{start:e,durationMs:r-e}},"extent"),it=g(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 tt(t){const e=t[0],r=t.filter(v=>v.kind==="render"),o=t.filter(v=>v.kind==="effect-run"),n=t.find(v=>v.kind==="render-commit-truncated"),u=[...r].sort((v,U)=>(U.durationMs??0)-(v.durationMs??0)),m=u.filter(v=>(v.why??[]).some(U=>U!=="parent-render")),$=w(m.flatMap(v=>(v.why??[]).filter(U=>U!=="parent-render"))),a=S(m),i=r.filter(v=>v.phase==="mount"),l=r.filter(v=>v.phase!=="mount"&&!m.includes(v)),y=u[0]?.component??"view",x=r.length>0&&i.length===r.length,I=$.length?$.join(" + "):void 0,P=x?"mount":"update",L=a.length?`view update \xB7 ${J(a)} \u2190 ${I}`:x?`view mount \xB7 ${y}`:`view update \xB7 ${y}`,ut=n?.renderTotal??r.length,gt=[i.length?`mounted ${z(i)}`:"",l.length?`re-rendered ${z(l)}`:"",!a.length&&!x&&r.length?"trigger not recorded \u2014 every captured render came from its parent":"",n?`${ut} renders, ${n.renderPublished??r.length} recorded (per-commit cap)`:`${r.length} render${r.length===1?"":"s"}`,o.length?`${o.length} effect${o.length===1?"":"s"}: ${o.map(Z).join(", ")}`:""].filter(Boolean).join(" \xB7 "),lt=S(r);return it({...e,...at(t),kind:"view-update",title:L,detail:gt,commitId:e.commitId,viewPhase:P,...I?{cause:I}:{},causeComponents:a,components:lt,mounted:S(i),renderCount:ut,recordedRenders:r.length,effects:o.length,effectHooks:o.map(Z),memberIds:t.map(v=>v.id),sig:`commit:${P}:${I??"-"}:${a.join(",")}:${lt.slice().sort().join(",")}`,severity:t.some(v=>v.severity==="error")?"error":e.severity})}A(tt,"te"),D(tt,"ct"),g(tt,"viewUpdateNode");function et(t){const e=t[0],r=t.map(Z);return it({...e,...at(t),kind:"commit-effects",title:t.length===1?`effect \xB7 ${r[0]}`:`effects \xB7 ${r[0]} + ${t.length-1} more`,detail:r.join(", "),commitId:e.commitId,effects:t.length,effectHooks:r,memberIds:t.map(o=>o.id),sig:`effects:${r.slice().sort().join(",")}`})}A(et,"re"),D(et,"dt"),g(et,"effectsNode");const ht=g(t=>w(t.map(e=>e==="state-update"?"state update":e==="fetch-start"?"request":e==="flow-origin"?"interaction":"response")).join(" + "),"describeInputs");function rt(t,e){const r=t[0],o=t[t.length-1],n=t.length,u=r.detail,m=Math.min(...t.map(l=>l.start)),$=Math.max(...t.map(l=>l.start+(l.durationMs??0))),a=Math.round(t.reduce((l,y)=>l+(y.durationMs??0),0)/n*10)/10,i=Math.round(($-m)*10)/10;r.count=n,r.avgMs=a,r.wallMs=i,r.durationMs=$-m,r.items=t.slice(0,12).map(l=>({start:l.start-m,...l.durationMs!=null?{durationMs:l.durationMs}:{}})),r.memberIds=t.flatMap(l=>l.memberIds??[l.id]),r.title=`\xD7${n} ${r.title}`,t.some(l=>l.severity==="error")&&(r.severity="error"),r.kind==="view-update"?r.detail=[`${n} commits, ${e.length?`one per ${ht(e)}`:"back to back"}`,`avg ${a}ms \xB7 wall ${i}ms`,u??""].filter(Boolean).join(" \xB7 "):r.kind==="state-update"&&u&&o.detail?r.detail=`${n} updates in a row \xB7 wall ${i}ms \xB7 first ${u} \xB7 last ${o.detail}`:r.detail=[`${n} in a row \xB7 wall ${i}ms`,u??""].filter(Boolean).join(" \xB7 ")}A(rt,"oe"),D(rt,"ft"),g(rt,"collapseRepeat");const Q=[],X=new Map,dt=new Set;for(let t=0;t<h.length;t++){if(dt.has(t))continue;const e=h[t];if(!c(e)){Q.push(e);continue}const r=[t];for(let u=t+1;u<h.length;u++){const m=h[u];if(m.group==="browser"){if(!c(m)||m.commitId!==e.commitId)break;r.push(u)}}for(const u of r)dt.add(u);const o=r.map(u=>h[u]),n=o.some(u=>u.kind!=="effect-run")?tt(o):et(o);for(const u of o)u.id!==n.id&&X.set(u.id,n.id);Q.push(n)}if(X.size>0||Q.some(t=>t.kind==="view-update"||t.kind==="commit-effects")){h=Q;for(const t of h)for(;t.parent&&X.has(t.parent);)t.parent=X.get(t.parent)}{const t=new Map;for(const e of h)e.kind==="view-update"&&e.commitId&&!t.has(e.commitId)&&t.set(e.commitId,e);for(const e of h){if(e.kind!=="commit-effects"||e.parent||!e.commitId)continue;const r=t.get(e.commitId);r&&r.start<=e.start&&(e.parent=r.id)}}{const t=new Set(["state-update","fetch","fetch-start","fetch-done","fetch-error","flow-origin"]),e=h.map((a,i)=>a.group==="browser"?i:-1).filter(a=>a>=0),r=g(a=>`${a.kind}|${a.sig??a.title}`,"keyOf"),o=e.map(a=>r(h[a])),n=g((a,i,l)=>{for(let y=0;y<l;y++)if(o[a+y]!==o[i+y])return!1;return!0},"sameBlock"),u=g(a=>o[a].split("|")[0],"kindAt"),m=g(a=>{let i=0,l=1;for(let y=1;y<=4&&a+y<=o.length;y++){let x=1;for(;a+(x+1)*y<=o.length&&n(a,a+x*y,y);)x+=1;x>=3&&y*x>i*l&&(i=y,l=x)}return{k:i,r:l}},"bestBlockAt"),$=new Map;for(let a=0;a<o.length;){const{k:i,r:l}=m(a);if(i===0){a+=1;continue}const y=[...Array(i).keys()].find(I=>t.has(u(a+I)));if(y!==void 0&&y>0){const I=m(a+y);if(I.k===i&&I.r>=3&&I.r>=l-1){a+=y;continue}}const x=o.slice(a,a+i).map(I=>I.split("|")[0]).filter(I=>t.has(I));for(let I=0;I<i;I++){const P=[];for(let L=0;L<l;L++)P.push(h[e[a+I+L*i]]);rt(P,x);for(const L of P.slice(1))$.set(L.id,P[0].id)}a+=i*l}if($.size>0){h=h.filter(a=>!$.has(a.id));for(const a of h)for(;a.parent&&$.has(a.parent);)a.parent=$.get(a.parent)}}{const t=new Map(h.map(e=>[e.id,e]));for(const e of h){const r=new Set([e.id]);let o=e;for(;o?.parent;){if(r.has(o.parent)){o.parent=void 0;break}r.add(o.parent),o=t.get(o.parent)}}}const ct=g(t=>{const e=new Map;for(const o of h){if(!o.sig||f(o)!==t||o.kind==="server-request"||o.kind==="gateway-request"||o.group==="browser")continue;const n=`${o.parent??"root"}|${o.kind}|${o.sig}`,u=e.get(n);u?u.push(o):e.set(n,[o])}const r=new Map;for(const o of e.values()){if(o.length<3)continue;o.sort((i,l)=>i.start-l.start);const n=o[0];let u=!1;for(let i=0;i+1<o.length;i++)if(o[i+1].start<o[i].start+(o[i].durationMs??0)){u=!0;break}const m=n.start,$=Math.max(...o.map(i=>i.start+(i.durationMs??0))),a=o.reduce((i,l)=>i+(l.durationMs??0),0);n.count=o.length,n.parallel=u,n.avgMs=Math.round(a/o.length*10)/10,n.wallMs=$-m,n.durationMs=$-m,n.title=`\xD7${o.length} ${n.title.replace(/\s*\((?:\d+ rows?, )?\d+ms\)$/,"")}`,n.detail=`${n.sig} \xD7${o.length} ${u?"\u2016 parallel":"\u21BB sequential loop"} \xB7 avg ${n.avgMs}ms \xB7 wall ${n.wallMs}ms`,n.items=o.slice(0,12).map(i=>({start:i.start-m,...i.durationMs!=null?{durationMs:i.durationMs}:{}})),n.memberIds=o.flatMap(i=>i.memberIds??[i.id]),o.some(i=>i.severity==="error")&&(n.severity="error");for(const i of o.slice(1))r.set(i.id,n.id)}if(r.size!==0){h=h.filter(o=>!r.has(o.id));for(const o of h)for(;o.parent&&r.has(o.parent);)o.parent=r.get(o.parent)}},"aggregatePass");ct(!0),ct(!1);for(const t of h){if(!f(t))continue;const e=t.durationMs??0;if(e<40)continue;const r=h.filter($=>$.parent===t.id&&($.durationMs??0)>0).map($=>[$.start,$.start+($.durationMs??0)]).sort(($,a)=>$[0]-a[0]);let o=0,n=-1,u=-1;for(const[$,a]of r)$>u?(u>n&&(o+=u-n),n=$,u=a):a>u&&(u=a);u>n&&(o+=u-n);const m=Math.max(0,e-o);(m>=50||m/e>=.7&&e>=40)&&(t.selfMs=m,t.detail=`\u26A0 cpu-heavy: ${m}ms self-time of ${e}ms${t.detail?" \xB7 "+t.detail:""}`)}return{events:h}}A(buildFlowDetail,"buildFlowDetail"),D(buildFlowDetail,"buildFlowDetail"),g(buildFlowDetail,"buildFlowDetail");
|
package/lib/flows-config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var y=Object.defineProperty;var l=(o,e)=>y(o,"name",{value:e,configurable:!0});var w=Object.defineProperty,c=l((o,e)=>w(o,"name",{value:e,configurable:!0}),"c"),$=Object.defineProperty,p=c((o,e)=>$(o,"name",{value:e,configurable:!0}),"u");import{classifyFlow as h,categoryOfSegment as F}from"./flow-categories.js";import{DEFAULT_SEGMENT_OPTIONS as j,segmentFlow as O}from"./flow-segments.js";export const DEFAULT_FLOWS_CONFIG={categories:[],segments:{},problems:[]};const f=200,b=200,d=64,v=/^[A-Za-z0-9][A-Za-z0-9 ._:/-]*$/,A=["category","flowId","originType","origin","route","project"],S={phaseGapMs:[50,6e5],burstGapMs:[10,6e4],attachWindowMs:[0,6e4],maxSegmentEvents:[20,1e4],occurrenceSlackMs:[0,1e3]},g=p(o=>typeof o=="object"&&o!==null&&!Array.isArray(o),"isObj");function m(o,e){if(!g(o))return{problems:[`${e}: not an object`]};const s=[];for(const t of Object.keys(o))A.includes(t)||s.push(`${e}: unknown field "${t}" ignored`);const n=o.category;if(typeof n!="string"||n.trim()==="")return{problems:[...s,`${e}: "category" must be a non-empty string \u2014 rule dropped`]};const i=n.trim();if(i.length>d||!v.test(i))return{problems:[...s,`${e}: category "${i.slice(0,40)}" is not a usable name (letters, digits, space . _ : / -; up to ${d}) \u2014 rule dropped`]};const u={category:i};let a=0;for(const t of["flowId","originType","origin","route","project"]){const r=o[t];if(r!==void 0){if(typeof r!="string"||r===""||r.length>b)return{problems:[...s,`${e}: "${t}" must be a non-empty string of up to ${b} characters \u2014 rule dropped`]};u[t]=r,a+=1}}return a===0?{problems:[...s,`${e}: "${i}" has no match field (flowId, originType, origin, route or project) \u2014 rule dropped`]}:{rule:u,problems:s}}l(m,"d"),c(m,"w"),p(m,"parseRule");export function parseFlowsConfig(o){if(o==null)return DEFAULT_FLOWS_CONFIG;if(!g(o))return{...DEFAULT_FLOWS_CONFIG,problems:["lensmcp.flows must be an object \u2014 ignored"]};const e=[],s=[],n=o.categories;n!==void 0&&(Array.isArray(n)?(n.length>f&&e.push(`flows.categories has ${n.length} rules; only the first ${f} are used`),n.slice(0,f).forEach((a,t)=>{const r=m(a,`flows.categories[${t}]`);e.push(...r.problems),r.rule&&s.push(r.rule)})):e.push("flows.categories must be an array \u2014 ignored"));const i={},u=o.segments;if(u!==void 0)if(!g(u))e.push("flows.segments must be an object \u2014 ignored");else for(const[a,t]of Object.entries(u)){const r=S[a];if(!r){e.push(`flows.segments.${a}: unknown option ignored`);continue}if(typeof t!="number"||!Number.isFinite(t)||t<r[0]||t>r[1]){e.push(`flows.segments.${a}: ${JSON.stringify(t)} is outside ${r[0]}\u2013${r[1]}; using the default (${j[a]})`);continue}i[a]=t}return{categories:s,segments:i,problems:e}}l(parseFlowsConfig,"parseFlowsConfig"),c(parseFlowsConfig,"parseFlowsConfig"),p(parseFlowsConfig,"parseFlowsConfig");export function analyzeFlow(o,e=DEFAULT_FLOWS_CONFIG){const s=O(o,e.segments),n=h(o,s,e.categories),i={};for(const u of s.segments)i[u.id]=F(u,n,e.categories);return{segmentation:s,classification:n,segmentCategories:i}}l(analyzeFlow,"analyzeFlow"),c(analyzeFlow,"analyzeFlow"),p(analyzeFlow,"analyzeFlow");
|
package/lib/graph-from-events.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var y=Object.defineProperty;var l=(o,r)=>y(o,"name",{value:r,configurable:!0});var b=Object.defineProperty,p=l((o,r)=>b(o,"name",{value:r,configurable:!0}),"p"),I=Object.defineProperty,m=p((o,r)=>I(o,"name",{value:r,configurable:!0}),"l");function f(o){const r=o.raw??null,s=r?.kind,i=o.context,a={id:o.id,parentTraceNodeId:i.causedByNodeId??i.originNodeId,lifecycle:"completed",context:i,startTime:o.timestamp,attributes:{...r??{}}};if(o.source==="react"&&s==="render"){const e=r;return{parentAxis:"render",node:{...a,type:"render",logicalId:e.render?.componentLogicalId,instanceId:e.render?.componentInstanceId,name:`render ${e.render?.componentName??"?"}`,durationMs:e.render?.actualDurationMs}}}if(o.source==="valtio"&&s==="state-update"){const e=r;return{parentAxis:"state",node:{...a,type:"state-update",logicalId:e.update?.storeId,name:`${e.update?.storeId??"?"}.${e.update?.path??"?"}`}}}if(o.source==="nestjs"&&s==="server-request"){const e=r;return{parentAxis:"backend",node:{...a,type:"server-request",name:`${e.request?.method??"?"} ${e.request?.route??"?"}`,durationMs:e.request?.durationMs}}}if(s==="db-query"){const e=r,c=[e.op,e.table].filter(Boolean).join(" ")||(e.name??"query");return{parentAxis:"backend",node:{...a,type:"db-query",logicalId:e.table?`db:${e.op??"query"}:${e.table}`:void 0,name:e.error?`${c} (failed)`:c,durationMs:e.durationMs}}}if(s==="loop")return{parentAxis:"performance",node:{...a,type:"loop",name:"loop",durationMs:r.loop?.durationMs}};if(o.source==="client-runtime"&&s==="user-action"){const e=r;return{parentAxis:"caused",node:{...a,type:"ui-event",logicalId:e.origin?.nodeId,name:e.origin?.label??o.title}}}}l(f,"m"),p(f,"f"),m(f,"eventToNode");export function buildGraphFromEvents(o,r){const s=[...r].sort((n,t)=>n.timestamp-t.timestamp),i=[];for(const n of s){const t=f(n);t&&(o.addNode(t.node),i.push(t))}let a=0;const e=m((n,t,d,u)=>{const g={id:`${d}:${n}->${t}`,from:n,to:t,axis:d,type:u,timestamp:o.getNode(t)?.startTime??0};o.addEdge(g),a++},"addEdge");for(const n of i){const t=n.node.context.causedByNodeId;t&&o.getNode(t)&&e(t,n.node.id,n.parentAxis??"caused","caused-by")}const c=new Map;for(const n of i){const t=n.node.context.flowId;if(!t)continue;let d=c.get(t);d||(d=[],c.set(t,d)),d.push(n)}for(const n of c.values())for(let t=1;t<n.length;t++){const d=n[t-1].node,u=n[t].node;u.context.causedByNodeId!==d.id&&e(d.id,u.id,"caused","flow-sequence")}return{nodeCount:i.length,edgeCount:a}}l(buildGraphFromEvents,"buildGraphFromEvents"),p(buildGraphFromEvents,"buildGraphFromEvents"),m(buildGraphFromEvents,"buildGraphFromEvents");
|
package/lib/graph-store.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var w=Object.defineProperty;var l=(
|
|
1
|
+
"use strict";var w=Object.defineProperty;var l=(d,t)=>w(d,"name",{value:t,configurable:!0});var I=Object.defineProperty,y=l((d,t)=>I(d,"name",{value:t,configurable:!0}),"l"),b=Object.defineProperty,m=y((d,t)=>b(d,"name",{value:t,configurable:!0}),"l");const B=4,M=1e3;export class GraphStore{static{l(this,"GraphStore")}static{y(this,"GraphStore")}static{m(this,"GraphStore")}constructor(){this.nodes=new Map,this.edges=new Map,this.byParent=new Map,this.byFlow=new Map,this.byLogical=new Map,this.byInstance=new Map,this.byRequest=new Map,this.outByAxis=new Map,this.inByAxis=new Map}addNode(t){this.nodes.set(t.id,t),t.parentTraceNodeId&&this.addToIndex(this.byParent,t.parentTraceNodeId,t.id),t.context.flowId&&this.addToIndex(this.byFlow,t.context.flowId,t.id),t.logicalId&&this.addToIndex(this.byLogical,t.logicalId,t.id),t.instanceId&&this.addToIndex(this.byInstance,t.instanceId,t.id),t.context.requestId&&this.addToIndex(this.byRequest,t.context.requestId,t.id)}updateNode(t,e){const i=this.nodes.get(t);if(!i)throw new Error(`Unknown node: ${t}`);const s={...i,...e,id:i.id};return this.nodes.set(t,s),s}getNode(t){return this.nodes.get(t)}addEdge(t){this.edges.set(t.id,t);let e=this.outByAxis.get(t.axis);e||(e=new Map,this.outByAxis.set(t.axis,e)),this.addToIndex(e,t.from,t.id);let i=this.inByAxis.get(t.axis);i||(i=new Map,this.inByAxis.set(t.axis,i)),this.addToIndex(i,t.to,t.id)}getEdge(t){return this.edges.get(t)}childrenOf(t){return this.materialiseNodes(this.byParent.get(t))}nodesInFlow(t){return this.materialiseNodes(this.byFlow.get(t))}nodesByLogical(t){return this.materialiseNodes(this.byLogical.get(t))}nodesByInstance(t){return this.materialiseNodes(this.byInstance.get(t))}nodesByRequest(t){return this.materialiseNodes(this.byRequest.get(t))}traverse(t){const e=this.nodes.get(t.from);if(!e)return{nodes:[],edges:[]};const i=Array.isArray(t.lens)?t.lens:[t.lens],s=t.direction??"both",x=t.depth??4,p=t.maxNodes??1e3,o=new Set,g=new Set,c=[{id:e.id,d:0}];for(;c.length&&!(o.size>=p);){const{id:n,d:u}=c.shift();if(!o.has(n)&&(o.add(n),!(u>=x)))for(const f of i){if(s==="out"||s==="both"){const a=this.outByAxis.get(f)?.get(n);if(a)for(const r of a){g.add(r);const h=this.edges.get(r);o.has(h.to)||c.push({id:h.to,d:u+1})}}if(s==="in"||s==="both"){const a=this.inByAxis.get(f)?.get(n);if(a)for(const r of a){g.add(r);const h=this.edges.get(r);o.has(h.from)||c.push({id:h.from,d:u+1})}}}}return{nodes:this.materialiseNodes(o),edges:[...g].map(n=>this.edges.get(n)).filter(n=>!!n)}}nodeCount(){return this.nodes.size}edgeCount(){return this.edges.size}addToIndex(t,e,i){let s=t.get(e);s||(s=new Set,t.set(e,s)),s.add(i)}materialiseNodes(t){if(!t)return[];const e=[];for(const i of t){const s=this.nodes.get(i);s&&e.push(s)}return e}}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type BaseEvent, type ErrorDismissalDraft } from '@lensmcp/protocol-types';
|
|
2
|
+
/**
|
|
3
|
+
* Events the lens writes about itself — today, a dismissed error and its undo — and the one way
|
|
4
|
+
* they reach the bus.
|
|
5
|
+
*
|
|
6
|
+
* Three processes can dismiss: the dashboard (a click), the MCP server (an agent's tool call, or
|
|
7
|
+
* the CLI through it). None of them changes its own memory. Each appends to the bus FILE and hears
|
|
8
|
+
* it back through the ingest that tails the file, like any other producer's event — so every
|
|
9
|
+
* process folds the same thing, in the same order, and a restart replays it.
|
|
10
|
+
*/
|
|
11
|
+
/** The bus file a lens process reads and writes: `LENSMCP_EVENT_FILE`, else this workspace's own. */
|
|
12
|
+
export declare function lensEventFile(env?: Record<string, string | undefined>, cwd?: string): string;
|
|
13
|
+
/** Stamped AT `until`: the reader clamps a dismissal to its own timestamp, so the two must agree. */
|
|
14
|
+
export declare function dismissalEvent(draft: ErrorDismissalDraft, sessionId: string): BaseEvent;
|
|
15
|
+
export declare function restoralEvent(groupId: string, sessionId: string, at: number): BaseEvent;
|
|
16
|
+
/**
|
|
17
|
+
* Append events to the bus file. Throws when the write fails: the caller is answering a person or
|
|
18
|
+
* an agent, and "dismissed" must not be a guess.
|
|
19
|
+
*/
|
|
20
|
+
export declare function appendBusEvents(eventFile: string, events: readonly BaseEvent[]): void;
|
|
@@ -0,0 +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");
|
package/lib/patterns.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var M=Object.defineProperty;var p=(a,s)=>M(a,"name",{value:s,configurable:!0});var D=Object.defineProperty,f=p((a,s)=>D(a,"name",{value:s,configurable:!0}),"p"),b=Object.defineProperty,h=f((a,s)=>b(a,"name",{value:s,configurable:!0}),"p");export function detectDbInLoop(a,s={}){const l=s.threshold??5,d=[];for(const i of a){const n=i.raw??null;if(n?.kind!=="loop"||!n.loop)continue;const e=n.loop.dbCallsInsideLoop??0;e>l&&d.push({kind:"db-in-loop",severity:"warning",title:`${e} DB calls inside a loop (${n.loop.iterations??"?"} iterations)`,evidence:[i.id],details:{dbCallsInsideLoop:e,iterations:n.loop.iterations,durationMs:n.loop.durationMs,threshold:l},detectedAt:i.timestamp})}return d}p(detectDbInLoop,"detectDbInLoop"),f(detectDbInLoop,"detectDbInLoop"),h(detectDbInLoop,"detectDbInLoop");export function detectNPlusOne(a,s={}){const l=s.threshold??3,d=new Map;for(const n of a){const e=n.raw??null;if(e?.kind!=="db-query"||!e.query?.signature)continue;const t=e.query.signature;let o=d.get(t);o||(o=[],d.set(t,o)),o.push(n)}const i=[];for(const[n,e]of d)e.length>=l&&i.push({kind:"n+1-query",severity:"warning",title:`Query repeated ${e.length}\xD7 \u2014 likely N+1`,evidence:e.map(t=>t.id),details:{signature:n,count:e.length,threshold:l},detectedAt:e[e.length-1].timestamp});return i}p(detectNPlusOne,"detectNPlusOne"),f(detectNPlusOne,"detectNPlusOne"),h(detectNPlusOne,"detectNPlusOne");export function detectRenderStorm(a,s={}){const l=s.threshold??5,d=s.windowMs??250,i=new Map;for(const e of a){if(e.source!=="react")continue;const t=e.raw??null;if(t?.kind!=="render"||!t.render?.componentInstanceId)continue;const o=t.render.componentInstanceId;let r=i.get(o);r||(r=[],i.set(o,r)),r.push(e)}const n=[];for(const[e,t]of i){t.sort((r,u)=>r.timestamp-u.timestamp);let o=0;for(let r=0;r<t.length;r++){for(;t[r].timestamp-t[o].timestamp>d;)o++;const u=r-o+1;if(u>l){const c=t.slice(o,r+1),m=c[0].raw.render?.componentName??e;n.push({kind:"render-storm",severity:"warning",title:`${m} rendered ${u}\xD7 in ${d}ms`,evidence:c.map(g=>g.id),details:{componentInstanceId:e,count:u,windowMs:d,threshold:l},detectedAt:c[c.length-1].timestamp});break}}}return n}p(detectRenderStorm,"detectRenderStorm"),f(detectRenderStorm,"detectRenderStorm"),h(detectRenderStorm,"detectRenderStorm");export function findSlowPath(a,s,l){const d=new Map,i=new Set;function n(t){const o=d.get(t);if(o)return o;if(i.has(t))return{path:[t],totalDurationMs:l(t)};i.add(t);const r=l(t),u=s.get(t)??[];let c;for(const g of u){const w=n(g);(!c||w.totalDurationMs>c.totalDurationMs)&&(c=w)}i.delete(t);const m=c?{path:[t,...c.path],totalDurationMs:r+c.totalDurationMs}:{path:[t],totalDurationMs:r};return d.set(t,m),m}p(n,"n"),f(n,"o"),h(n,"best");let e={path:[],totalDurationMs:0};for(const t of a){const o=n(t);o.totalDurationMs>e.totalDurationMs&&(e=o)}return e}p(findSlowPath,"findSlowPath"),f(findSlowPath,"findSlowPath"),h(findSlowPath,"findSlowPath");
|
package/lib/redact.d.ts
CHANGED
|
@@ -117,24 +117,4 @@ export declare function clip(value: string, max: number): string;
|
|
|
117
117
|
export declare function safeText(value: string | undefined, max?: number): string | undefined;
|
|
118
118
|
/** Redact then bound — the standard treatment for a captured title. */
|
|
119
119
|
export declare function safeTitle(value: string): string;
|
|
120
|
-
/**
|
|
121
|
-
* Scrub credentials out of every string leaf of an arbitrary value.
|
|
122
|
-
*
|
|
123
|
-
* Needed for `console` arguments, which are the one captured payload that is
|
|
124
|
-
* genuinely unstructured — `console.log('auth', { token })` is ordinary
|
|
125
|
-
* debugging code, and the whole point of that change is that those payloads
|
|
126
|
-
* now reach a transcript. It is also what covers a structured `raw`: the
|
|
127
|
-
* gateway's request event carries the URL at `raw.url` AND again at
|
|
128
|
-
* `raw.steps[].url`, and walking every string leaf catches BOTH plus whatever
|
|
129
|
-
* URL-bearing field a future event type adds — which naming the fields
|
|
130
|
-
* one-by-one would not. Bounded on depth and array length so a pathological
|
|
131
|
-
* object cannot make redaction the slow part of a page's logging.
|
|
132
|
-
*
|
|
133
|
-
* Values are returned by reference when nothing changed, so the common case
|
|
134
|
-
* (no credential anywhere) allocates nothing.
|
|
135
|
-
*
|
|
136
|
-
* `maxDepth` defaults to the producer-side limit. The BUS redactor raises it to match the clamp's
|
|
137
|
-
* depth, because anything the clamp keeps is something a consumer will see — a credential sitting
|
|
138
|
-
* between the two limits survived redaction on every path (issues/codex-security/43).
|
|
139
|
-
*/
|
|
140
120
|
export declare function redactDeep(value: unknown, depth?: number, maxDepth?: number): unknown;
|
package/lib/redact.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var d=Object.defineProperty;var a=(e,t)=>d(e,"name",{value:t,configurable:!0});var m=Object.defineProperty,n=a((e,t)=>m(e,"name",{value:t,configurable:!0}),"n"),g=Object.defineProperty,o=n((e,t)=>g(e,"name",{value:t,configurable:!0}),"r");export const REDACTED="REDACTED",MAX_TITLE_CHARS=300,MAX_MESSAGE_CHARS=4096,MAX_URL_CHARS=1024;const x=["token","secret","password","passwd","apikey","credential","assertion","signature"],b=new Set(["key","auth","authorization","jwt","code","sig","pwd","pass","session","sid","bearer","otp","cookie","set-cookie"]),$=/^(?:(?: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=e.toLowerCase();if($.test(t.replace(/[-_.]+/g,"")))return!1;if(x.some(r=>t.includes(r)))return!0;for(const r of t.split(/[-_.]+/))if(r&&b.has(r))return!0;return!1}a(isSecretParam,"isSecretParam"),n(isSecretParam,"isSecretParam"),o(isSecretParam,"isSecretParam");const A=/^([a-z][a-z0-9+.-]*:\/\/)[^/?#@\s]*@/i,T=/([?&#])([^=&#\s]+)=([^&#\s]*)/g;export function redactUrlParams(e){return e&&e.replace(A,`$1${REDACTED}@`).replace(T,(t,r,i)=>isSecretParam(i)?`${r}${i}=${REDACTED}`:t)}a(redactUrlParams,"redactUrlParams"),n(redactUrlParams,"redactUrlParams"),o(redactUrlParams,"redactUrlParams");export function redactUrl(e){return e&&clip(redactUrlParams(e),1024)}a(redactUrl,"redactUrl"),n(redactUrl,"redactUrl"),o(redactUrl,"redactUrl");const h=/\beyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]*/g,y=/\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;export function redactText(e){return redactUrlParams(e).replace(k,(t,r,i,p)=>`${r}${i}${p}${REDACTED}${p}`).replace(h,REDACTED).replace(y,(t,r)=>`${r} ${REDACTED}`)}a(redactText,"redactText"),n(redactText,"redactText"),o(redactText,"redactText");export function clip(e,t){return e.length<=t?e:`${e.slice(0,t)}\u2026[lensmcp truncated: ${e.length-t} more chars]`}a(clip,"clip"),n(clip,"clip"),o(clip,"clip");export function safeText(e,t=4096){if(e!==void 0)return clip(redactText(e),t)}a(safeText,"safeText"),n(safeText,"safeText"),o(safeText,"safeText");export function safeTitle(e){return clip(redactText(e),300)}a(safeTitle,"safeTitle"),n(safeTitle,"safeTitle"),o(safeTitle,"safeTitle");const _=6,S=64,z=/^TS\d{1,5}$/,D=o((e,t)=>e==="code"&&typeof t=="string"&&z.test(t),"isDiagnosticCode");export function redactDeep(e,t=0,r=_){if(typeof e=="string")return redactText(e);if(e===null||typeof e!="object"||t>=r)return e;if(Array.isArray(e)){let s=!1;const c=e.map((u,f)=>{if(f>=S)return u;const l=redactDeep(u,t+1,r);return l!==u&&(s=!0),l});return s?c:e}let i=!1;const p={};for(const[s,c]of Object.entries(e)){const u=isSecretParam(s)&&c!==void 0&&c!==null&&!D(s,c)?REDACTED:redactDeep(c,t+1,r);u!==c&&(i=!0),p[s]=u}return i?p:e}a(redactDeep,"redactDeep"),n(redactDeep,"redactDeep"),o(redactDeep,"redactDeep");
|
package/lib/reducer-registry.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var c=(r,e)=>a(r,"name",{value:e,configurable:!0});var u=Object.defineProperty,i=c((r,e)=>u(r,"name",{value:e,configurable:!0}),"c"),n=Object.defineProperty,d=i((r,e)=>n(r,"name",{value:e,configurable:!0}),"c");export class ReducerRegistry{static{c(this,"ReducerRegistry")}static{i(this,"ReducerRegistry")}static{d(this,"ReducerRegistry")}constructor(){this.reducers=[]}register(e,s){if(this.reducers.some(t=>t.name===e))throw new Error(`Reducer already registered: ${e}`);this.reducers.push({name:e,reducer:s})}list(){return this.reducers}async dispatch(e){for(const{reducer:s}of this.reducers)try{const t=s(e);t&&typeof t.then=="function"&&await t}catch{}}}
|
package/lib/resource-store.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var a=Object.defineProperty;var i=(s,e)=>a(s,"name",{value:e,configurable:!0});var h=Object.defineProperty,c=i((s,e)=>h(s,"name",{value:e,configurable:!0}),"i"),d=Object.defineProperty,l=c((s,e)=>d(s,"name",{value:e,configurable:!0}),"o");export class ResourceStore{static{i(this,"ResourceStore")}static{c(this,"ResourceStore")}static{l(this,"ResourceStore")}constructor(){this.entries=new Map,this.subs=new Map}register(e,t){if(this.entries.has(e))throw new Error(`Resource already registered: ${e}`);return this.entries.set(e,{uri:e,produce:t,revision:0}),()=>{this.entries.delete(e),this.subs.delete(e)}}async read(e){const t=this.entries.get(e);if(!t)throw new Error(`Unknown resource: ${e}`);return t.produce()}list(){return[...this.entries.keys()]}async markDirty(e){const t=this.entries.get(e);if(!t)return;const r=await t.produce(),n=JSON.stringify(r);if(n===t.lastJson)return;t.lastJson=n,t.revision+=1;const o=this.subs.get(e);if(o)for(const u of o)try{u(e,t.revision)}catch{}}revision(e){return this.entries.get(e)?.revision}subscribe(e,t){let r=this.subs.get(e);return r||(r=new Set,this.subs.set(e,r)),r.add(t),()=>{r?.delete(t)}}}
|
package/lib/story.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var I=Object.defineProperty;var u=(t,n)=>I(t,"name",{value:n,configurable:!0});var k=Object.defineProperty,c=u((t,n)=>k(t,"name",{value:n,configurable:!0}),"u"),b=Object.defineProperty,p=c((t,n)=>b(t,"name",{value:n,configurable:!0}),"c");export function groupByFlow(t){const n=new Map;for(const e of t){const o=e.context.flowId;if(!o)continue;let s=n.get(o);s||(s=[],n.set(o,s)),s.push(e)}return n}u(groupByFlow,"groupByFlow"),c(groupByFlow,"groupByFlow"),p(groupByFlow,"groupByFlow");export function compileStory(t,n={}){let e,o;if(n.flowId)o=n.flowId,e=t.filter(r=>r.context.flowId===o);else{const r=t.find(i=>i.context.flowId);if(!r)return;o=r.context.flowId,e=t.filter(i=>i.context.flowId===o)}if(e.length===0)return;e.sort((r,i)=>r.timestamp-i.timestamp);const s=1e3;e.length>s&&(e=[e[0],...e.slice(e.length-(s-1))]);const m=e[0],d=[];let l,v;for(const r of e){const i=f(r);if(i){if(d.push(i),i.kind==="render"||i.kind==="final-render"){const a=r.raw;a?.render&&(l={id:a.render.id,page:a.render.page,route:a.render.route,componentName:a.render.componentName})}else if(r.source==="visual"&&i.kind==="visual-violation"){const a=r.raw;a?.frame&&(v=a.frame.id)}}}for(let r=d.length-1;r>=0;r--)if(d[r].kind==="render"){d[r]={...d[r],kind:"final-render"};break}const g=e[0].timestamp,w=e[e.length-1].timestamp;return{flowId:o,origin:{type:m.context.originType,nodeId:m.context.originNodeId,at:m.timestamp},phases:d,finalState:l?{page:l.page,route:l.route,componentName:l.componentName,renderId:l.id,visualFrameId:v}:void 0,startedAt:g,endedAt:w,eventCount:e.length}}u(compileStory,"compileStory"),c(compileStory,"compileStory"),p(compileStory,"compileStory");function f(t){const n=(t.raw??null)?.kind;if(n==="flow-origin"||t.source==="client-runtime"&&n==="user-action"){const e=t.raw;return{kind:"user-action",at:t.timestamp,label:e?.origin?.label??t.title,eventIds:[t.id]}}if(t.source==="react"&&n==="render"){const e=t.raw;return{kind:"render",at:t.timestamp,label:`render ${e?.render?.componentName??"?"}`,eventIds:[t.id],details:e?.render?{componentName:e.render.componentName,durationMs:e.render.actualDurationMs}:void 0}}if(t.source==="react"&&n==="slot-content-changed"){const e=t.raw,o=e?.slot?.toComponent??"?";return{kind:/spinner|loader|loading/i.test(o)?"loading-ui":"idle-ui",at:t.timestamp,label:`slot ${e?.slot?.slotLogicalId??""} \u2192 ${o}`,eventIds:[t.id]}}if(t.source==="client-runtime"&&n==="route"){const e=t.raw;return{kind:"route-transition",at:t.timestamp,label:`route ${e?.from??""} \u2192 ${e?.url??""}`,eventIds:[t.id]}}if(t.source==="valtio"&&n==="state-update"){const e=t.raw;return{kind:"state-update",at:t.timestamp,label:`${e?.update?.storeId??"?"}.${e?.update?.path??"?"}`,eventIds:[t.id],details:e?.update}}if(t.source==="nestjs"&&n==="server-request"){const e=t.raw;return{kind:"backend-request",at:t.timestamp,label:`${e?.request?.method??"?"} ${e?.request?.route??"?"} \u2192 ${e?.request?.status??"?"}`,eventIds:[t.id],details:e?.request}}if(t.source==="chrome"&&t.category==="network")return{kind:"backend-request",at:t.timestamp,label:t.title,eventIds:[t.id]};if(t.source==="visual"&&n==="visual-violation"){const e=t.raw;return{kind:"visual-violation",at:t.timestamp,label:`${e?.violation?.ruleType??"rule"} ${e?.violation?.ruleId??""}`,eventIds:[t.id]}}}u(f,"f"),c(f,"g"),p(f,"classifyEvent");
|
package/lib/thresholds.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var l=Object.defineProperty;var o=(e,r)=>l(e,"name",{value:r,configurable:!0});var u=Object.defineProperty,t=o((e,r)=>u(e,"name",{value:r,configurable:!0}),"r"),c=Object.defineProperty,a=t((e,r)=>c(e,"name",{value:r,configurable:!0}),"n");export const DEFAULT_THRESHOLDS={dbInLoop:5,nPlusOne:3,renderStorm:5,slowRouteMs:500,slowRenderMs:16,slowQueryMs:100,duplicateRequestPeak:3,slowEgressMs:1e3};export function resolveThresholds(e){const r={...DEFAULT_THRESHOLDS};if(e)for(const n of Object.keys(DEFAULT_THRESHOLDS)){const s=e[n];typeof s=="number"&&Number.isFinite(s)&&s>=0&&(r[n]=s)}return r}o(resolveThresholds,"resolveThresholds"),t(resolveThresholds,"resolveThresholds"),a(resolveThresholds,"resolveThresholds");
|
package/lib/ulid.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var s=Object.defineProperty;var o=(e,n)=>s(e,"name",{value:n,configurable:!0});var b=Object.defineProperty,a=o((e,n)=>b(e,"name",{value:n,configurable:!0}),"r"),m=Object.defineProperty,u=a((e,n)=>m(e,"name",{value:n,configurable:!0}),"r");const f="0123456789ABCDEFGHJKMNPQRSTVWXYZ",g=16;function c(e,n){let r="",t=e;for(let l=n-1;l>=0;l--){const d=t%32;r=f[d]+r,t=(t-d)/32}return r}o(c,"l"),a(c,"s"),u(c,"encodeTime");function i(e){const n=new Uint8Array(e);globalThis.crypto.getRandomValues(n);let r="";for(let t=0;t<e;t++)r+=f[(n[t]??0)&31];return r}o(i,"s"),a(i,"a"),u(i,"encodeRandom");export function ulid(e=Date.now()){return c(e,10)+i(16)}o(ulid,"ulid"),a(ulid,"ulid"),u(ulid,"ulid");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lensmcp/core",
|
|
3
|
-
"version": "1.23.
|
|
3
|
+
"version": "1.23.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -22,6 +22,11 @@
|
|
|
22
22
|
"import": "./lib/bus-rotation.js",
|
|
23
23
|
"default": "./lib/bus-rotation.js"
|
|
24
24
|
},
|
|
25
|
+
"./lens-events": {
|
|
26
|
+
"types": "./lib/lens-events.d.ts",
|
|
27
|
+
"import": "./lib/lens-events.js",
|
|
28
|
+
"default": "./lib/lens-events.js"
|
|
29
|
+
},
|
|
25
30
|
"./ai-content": {
|
|
26
31
|
"types": "./lib/ai-content.d.ts",
|
|
27
32
|
"import": "./lib/ai-content.js",
|
|
@@ -29,7 +34,7 @@
|
|
|
29
34
|
}
|
|
30
35
|
},
|
|
31
36
|
"dependencies": {
|
|
32
|
-
"@lensmcp/protocol-types": "1.23.
|
|
37
|
+
"@lensmcp/protocol-types": "1.23.10",
|
|
33
38
|
"tslib": "^2.3.0"
|
|
34
39
|
},
|
|
35
40
|
"license": "Apache-2.0",
|