@lensmcp/core 1.25.3 → 1.25.6

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.
@@ -1 +1 @@
1
- "use strict";var O=Object.defineProperty;var u=(e,t)=>O(e,"name",{value:t,configurable:!0});var M=Object.defineProperty,s=u((e,t)=>M(e,"name",{value:t,configurable:!0}),"s");export const CATEGORY_ORDER=["user-action","page-load","navigation","api","ai","background","test","system","other"];const p=new Map;export function globMatch(e,t){let r=p.get(e);return r||(r=new RegExp(`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".")}$`),p.size>500&&p.clear(),p.set(e,r)),r.test(t)}u(globMatch,"globMatch"),s(globMatch,"globMatch");const T=s(e=>/^[A-Z]+ /.test(e),"hasMethod");function w(e,t){return t.some(r=>r.route?T(e)?globMatch(e,`${r.method??"GET"} ${r.route}`):globMatch(e,r.route):!1)}u(w,"T"),s(w,"routeMatches");function m(e,t){return!([e.flowId,e.originType,e.origin,e.route,e.project].filter(r=>r!==void 0).length===0||e.flowId!==void 0&&!globMatch(e.flowId,t.flowId)||e.originType!==void 0&&e.originType!==t.origin.type||e.origin!==void 0&&!(t.origin.nodeId!==void 0&&globMatch(e.origin,t.origin.nodeId))||e.route!==void 0&&!w(e.route,t.segments)||e.project!==void 0&&!t.segments.some(r=>r.projects.some(n=>globMatch(e.project,n))))}u(m,"b"),s(m,"ruleMatches");const y=s(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),l=s(e=>typeof e=="string"&&e!==""?e:void 0,"str"),f=s(e=>y(e.raw)?l(e.raw.kind)??"":"","kindOf");function k(e){const t=[...e].sort((a,g)=>(Number(a.timestamp)||0)-(Number(g.timestamp)||0)||(a.id<g.id?-1:1)),r=t.find(a=>f(a)==="flow-origin"),n=r??t.find(a=>l(a.context?.originType));if(!n)return{};const o=y(n.raw)?n.raw:{},i=l(n.context?.originType)??(r?l(n.title):void 0),c=l(o.originNodeId)??l(n.context?.originNodeId);return{...i?{type:i}:{},...c?{nodeId:c}:{}}}u(k,"$"),s(k,"originOf");const F=/^(verify|e2e|test|smoke|load)[-_:]/i,S=s((e,t)=>F.test(e)||t!==void 0&&/^(ui:)?(tools|scripts?|e2e)\//.test(t),"isTestFlow"),I={"page-load":"page-load","user-click":"user-action","form-submit":"user-action","input-change":"user-action","double-click":"user-action","context-menu":"user-action","key-press":"user-action","route-load":"navigation","route-change":"navigation",navigation:"navigation","ai-turn":"ai",request:"api",timer:"background",cron:"background",interval:"background",queue:"background",job:"background","websocket-message":"background","hmr-update":"system"},z=new Set(["page-load","user-action","navigation"]),A=/^[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=>A.test(t)||/^[0-9a-f]{16,}$/i.test(t)||/^\d{2,}$/.test(t)?":id":t).join("/")}u(templatePath,"templatePath"),s(templatePath,"templatePath");function $(e){const t=/^ui:(?:.*\/)?([^/:]+?)(?:\.[a-z]+)?:\d+:([A-Za-z]+)$/.exec(e);return t?`${t[1]} \xB7 ${t[2]}`:e}u($,"x"),s($,"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}u(scriptFamily,"scriptFamily"),s(scriptFamily,"scriptFamily");function x(e,t,r,n){const o=t.nodeId,i=o?/^(page|route|ambient):(.*)$/.exec(o):null;if(i)return`${i[1]}:${templatePath(i[2])}`;if(t.type&&I[t.type]==="user-action"&&o)return $(o);if(e==="test")return scriptFamily(r.flowId);const c=r.segments.find(g=>g.kind==="request"&&g.route);if(c?.route)return`${c.method??"GET"} ${templatePath(c.route)}`;const a=n.find(g=>f(g)==="ai-call");return a&&y(a.raw)?`ai \xB7 ${l(a.raw.model)??l(a.raw.provider)??"call"}`:o?templatePath(o):void 0}u(x,"q"),s(x,"subjectOf");const E=10,_=1e3,B=3,N=500,R=1e3;function j(e,t){const r=new Set,n=t.segments.filter(i=>i.kind==="request");t.segments.some(i=>i.counts.errors>0)&&r.add("has-error"),n.some(i=>i.durationMs>=_)&&r.add("slow"),n.length>=E&&r.add("fan-out"),new Set(t.segments.flatMap(i=>i.projects)).size>=3&&r.add("multi-service"),e.some(i=>f(i)==="queue-enqueued")&&r.add("queue"),e.some(i=>f(i)==="ai-call"||i.source==="ai")&&r.add("ai"),t.stats.bookkeeping>=N&&t.stats.bookkeeping*2>=t.stats.events&&r.add("storm"),t.stats.events>=R&&r.add("large");const o=new Map;for(const i of n)(!i.part||i.part.index===1)&&o.set(i.label,(o.get(i.label)??0)+1);return[...o.values()].some(i=>i>=B)&&r.add("repeated-requests"),[...r].sort()}u(j,"F"),s(j,"tagsOf");export function classifyFlow(e,t,r=[]){const n=k(e),o={flowId:t.flowId,origin:n,segments:t.segments},i=j(e,t),c=s((d,q,b)=>{const h=x(d,n,t,e);return{category:d,decidedBy:q,...b!==void 0?{ruleIndex:b}:{},tags:i,origin:n,...h?{subject:h}:{}}},"done"),a=r.findIndex(d=>d.category&&m(d,o));if(a!==-1)return c(r[a].category,"rule",a);if(S(t.flowId,n.nodeId))return c("test","test");const g=n.type?I[n.type]:void 0;if(g)return c(g,"origin");if(i.includes("ai"))return c("ai","shape");const v=t.segments.filter(d=>d.kind==="request");return v.length>0?c(v.every(d=>d.requestId?.startsWith("job:"))?"background":"api","shape"):t.segments.length>0&&t.segments.every(d=>d.kind==="ambient")?c("system","shape"):c("other","shape")}u(classifyFlow,"classifyFlow"),s(classifyFlow,"classifyFlow");export function categoryOfSegment(e,t,r=[]){const n=r.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 n?n.category:e.kind==="request"?e.requestId?.startsWith("job:")?"background":"api":e.kind==="ambient"?"system":e.kind==="origin"&&z.has(t.category)?t.category:"ui"}u(categoryOfSegment,"categoryOfSegment"),s(categoryOfSegment,"categoryOfSegment");export function groupFlows(e){return groupByCategory(e).map(t=>{const r=new Map;for(const o of t.items){const i=r.get(o.subject);i?i.push(o):r.set(o.subject,[o])}const n=[...r.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:n}})}u(groupFlows,"groupFlows"),s(groupFlows,"groupFlows");export function groupByCategory(e){const t=new Map;for(const n of e){const o=t.get(n.category);o?o.push(n):t.set(n.category,[n])}const r=s(n=>{const o=CATEGORY_ORDER.indexOf(n);return o===-1?CATEGORY_ORDER.length:o},"rank");return[...t.entries()].sort((n,o)=>r(n[0])-r(o[0])||(n[0]<o[0]?-1:n[0]>o[0]?1:0)).map(([n,o])=>({category:n,count:o.length,items:o}))}u(groupByCategory,"groupByCategory"),s(groupByCategory,"groupByCategory");
1
+ "use strict";var M=Object.defineProperty;var c=(e,t)=>M(e,"name",{value:t,configurable:!0});var T=Object.defineProperty,s=c((e,t)=>T(e,"name",{value:t,configurable:!0}),"s");export const CATEGORY_ORDER=["user-action","page-load","navigation","api","ai","background","test","system","other"];const p=new Map;export function globMatch(e,t){let o=p.get(e);return o||(o=new RegExp(`^${e.replace(/[.+^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*").replace(/\?/g,".")}$`),p.size>500&&p.clear(),p.set(e,o)),o.test(t)}c(globMatch,"globMatch"),s(globMatch,"globMatch");const F=s(e=>/^[A-Z]+ /.test(e),"hasMethod");function w(e,t){return t.some(o=>o.route?F(e)?globMatch(e,`${o.method??"GET"} ${o.route}`):globMatch(e,o.route):!1)}c(w,"$"),s(w,"routeMatches");function m(e,t){return!([e.flowId,e.originType,e.origin,e.route,e.project].filter(o=>o!==void 0).length===0||e.flowId!==void 0&&!globMatch(e.flowId,t.flowId)||e.originType!==void 0&&e.originType!==t.origin.type||e.origin!==void 0&&!(t.origin.nodeId!==void 0&&globMatch(e.origin,t.origin.nodeId))||e.route!==void 0&&!w(e.route,t.segments)||e.project!==void 0&&!t.segments.some(o=>o.projects.some(n=>globMatch(e.project,n))))}c(m,"b"),s(m,"ruleMatches");const y=s(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),g=s(e=>typeof e=="string"&&e!==""?e:void 0,"str"),f=s(e=>y(e.raw)?g(e.raw.kind)??"":"","kindOf"),k=s((e,t)=>{const o=Number(e.timestamp)||0,n=Number(t.timestamp)||0;return o<n||o===n&&e.id<t.id},"earlier");function $(e){let t,o;for(const a of e)f(a)==="flow-origin"&&(!t||k(a,t))&&(t=a),g(a.context?.originType)&&(!o||k(a,o))&&(o=a);const n=t??o;if(!n)return{};const r=y(n.raw)?n.raw:{},i=g(n.context?.originType)??(t?g(n.title):void 0),u=g(r.originNodeId)??g(n.context?.originNodeId);return{...i?{type:i}:{},...u?{nodeId:u}:{}}}c($,"O"),s($,"originOf");const S=/^(verify|e2e|test|smoke|load)[-_:]/i,z=s((e,t)=>S.test(e)||t!==void 0&&/^(ui:)?(tools|scripts?|e2e)\//.test(t),"isTestFlow"),x={"page-load":"page-load","user-click":"user-action","form-submit":"user-action","input-change":"user-action","double-click":"user-action","context-menu":"user-action","key-press":"user-action","route-load":"navigation","route-change":"navigation",navigation:"navigation","ai-turn":"ai",request:"api",timer:"background",cron:"background",interval:"background",queue:"background",job:"background","websocket-message":"background","hmr-update":"system"},A=new Set(["page-load","user-action","navigation"]),E=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;export function templatePath(e){return e.replace(/[?#].*$/,"").split("/").map(t=>E.test(t)||/^[0-9a-f]{16,}$/i.test(t)||/^\d{2,}$/.test(t)?":id":t).join("/")}c(templatePath,"templatePath"),s(templatePath,"templatePath");function I(e){const t=/^ui:(?:.*\/)?([^/:]+?)(?:\.[a-z]+)?:\d+:([A-Za-z]+)$/.exec(e);return t?`${t[1]} \xB7 ${t[2]}`:e}c(I,"q"),s(I,"componentOf");export function scriptFamily(e){let t=e.replace(/[-_:][0-9a-f]{6,}(?:-[0-9a-f]+)*$/i,"");return t=t.replace(/[-_:](?=[a-z0-9]*\d)[a-z0-9]{6,}$/i,""),t=t.replace(/[-_:]\d+$/,""),t||e}c(scriptFamily,"scriptFamily"),s(scriptFamily,"scriptFamily");function j(e,t,o,n){const r=t.nodeId,i=r?/^(page|route|ambient):(.*)$/.exec(r):null;if(i)return`${i[1]}:${templatePath(i[2])}`;if(t.type&&x[t.type]==="user-action"&&r)return I(r);if(e==="test")return scriptFamily(o.flowId);const u=o.segments.find(l=>l.kind==="request"&&l.route);if(u?.route)return`${u.method??"GET"} ${templatePath(u.route)}`;const a=n.find(l=>f(l)==="ai-call");return a&&y(a.raw)?`ai \xB7 ${g(a.raw.model)??g(a.raw.provider)??"call"}`:r?templatePath(r):void 0}c(j,"R"),s(j,"subjectOf");const _=10,B=1e3,N=3,R=500,C=1e3;function q(e,t){const o=new Set,n=t.segments.filter(i=>i.kind==="request");t.segments.some(i=>i.counts.errors>0)&&o.add("has-error"),n.some(i=>i.durationMs>=B)&&o.add("slow"),n.length>=_&&o.add("fan-out"),new Set(t.segments.flatMap(i=>i.projects)).size>=3&&o.add("multi-service"),e.some(i=>f(i)==="queue-enqueued")&&o.add("queue"),e.some(i=>f(i)==="ai-call"||i.source==="ai")&&o.add("ai"),t.stats.bookkeeping>=R&&t.stats.bookkeeping*2>=t.stats.events&&o.add("storm"),t.stats.events>=C&&o.add("large");const r=new Map;for(const i of n)(!i.part||i.part.index===1)&&r.set(i.label,(r.get(i.label)??0)+1);return[...r.values()].some(i=>i>=N)&&o.add("repeated-requests"),[...o].sort()}c(q,"G"),s(q,"tagsOf");export function classifyFlow(e,t,o=[]){const n=$(e),r={flowId:t.flowId,origin:n,segments:t.segments},i=q(e,t),u=s((d,O,b)=>{const h=j(d,n,t,e);return{category:d,decidedBy:O,...b!==void 0?{ruleIndex:b}:{},tags:i,origin:n,...h?{subject:h}:{}}},"done"),a=o.findIndex(d=>d.category&&m(d,r));if(a!==-1)return u(o[a].category,"rule",a);if(z(t.flowId,n.nodeId))return u("test","test");const l=n.type?x[n.type]:void 0;if(l)return u(l,"origin");if(i.includes("ai"))return u("ai","shape");const v=t.segments.filter(d=>d.kind==="request");return v.length>0?u(v.every(d=>d.requestId?.startsWith("job:"))?"background":"api","shape"):t.segments.length>0&&t.segments.every(d=>d.kind==="ambient")?u("system","shape"):u("other","shape")}c(classifyFlow,"classifyFlow"),s(classifyFlow,"classifyFlow");export function categoryOfSegment(e,t,o=[]){const n=o.find(r=>r.category&&(r.route!==void 0||r.project!==void 0)&&r.flowId===void 0&&r.origin===void 0&&r.originType===void 0&&m(r,{flowId:e.flowId,origin:t.origin,segments:[e]}));return n?n.category:e.kind==="request"?e.requestId?.startsWith("job:")?"background":"api":e.kind==="ambient"?"system":e.kind==="origin"&&A.has(t.category)?t.category:"ui"}c(categoryOfSegment,"categoryOfSegment"),s(categoryOfSegment,"categoryOfSegment");export function groupFlows(e){return groupByCategory(e).map(t=>{const o=new Map;for(const r of t.items){const i=o.get(r.subject);i?i.push(r):o.set(r.subject,[r])}const n=[...o.entries()].sort((r,i)=>(r[0]===void 0?1:0)-(i[0]===void 0?1:0)||i[1].length-r[1].length||String(r[0]).localeCompare(String(i[0]))).map(([r,i])=>({subject:r,count:i.length,items:i}));return{...t,subjects:n}})}c(groupFlows,"groupFlows"),s(groupFlows,"groupFlows");export function groupByCategory(e){const t=new Map;for(const n of e){const r=t.get(n.category);r?r.push(n):t.set(n.category,[n])}const o=s(n=>{const r=CATEGORY_ORDER.indexOf(n);return r===-1?CATEGORY_ORDER.length:r},"rank");return[...t.entries()].sort((n,r)=>o(n[0])-o(r[0])||(n[0]<r[0]?-1:n[0]>r[0]?1:0)).map(([n,r])=>({category:n,count:r.length,items:r}))}c(groupByCategory,"groupByCategory"),s(groupByCategory,"groupByCategory");
@@ -1 +1 @@
1
- "use strict";var z=Object.defineProperty;var j=(e,t)=>z(e,"name",{value:t,configurable:!0});var Q=Object.defineProperty,g=j((e,t)=>Q(e,"name",{value:t,configurable:!0}),"g");export const DEFAULT_SEGMENT_OPTIONS={phaseGapMs:1500,burstGapMs:250,attachWindowMs:400,maxSegmentEvents:400,occurrenceSlackMs:10},FLOW_BOOKKEEPING_KINDS=new Set(["subscription-added","subscription-removed","hook-run","store-created","singleton-instance","visual-frame"]),SQL_ACCOUNT_KIND="db-request-account";const H=new Set(["react","valtio","client-runtime","chrome","visual"]),O=g(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),k=g(e=>typeof e=="string"&&e!==""?e:void 0,"str"),v=g(e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,"num");function E(e){const t=O(e.raw)?e.raw:{},s=O(t.request)?t.request:{},r=O(t.span)?t.span:{},d=e.context??{},n=k(t.kind)??"",f=n===SQL_ACCOUNT_KIND,p=(f?v(t.lastEndedAt):void 0)??v(e.timestamp)??0,h=v(s.startedAt)??v(r.startTime)??v(t.startedAt)??(f?v(t.firstStartedAt):void 0),$=v(s.endedAt)??v(r.endTime)??(h!==void 0&&v(t.durationMs)!==void 0?h+t.durationMs:void 0),b=Math.min(p,h??p),M=Math.max(p,$??p),c=O(t.render)?t.render:{},u=O(t.update)?t.update:{},i=n==="render"?k(c.componentName):n==="state-update"?k(u.path)?.split(".").slice(0,2).join("."):void 0,a=k(t.queue),l=k(t.jobId),I=String(e.source),o=k(t.project)??k(d.projectName);return{event:e,id:e.id,ts:p,from:b,to:M,kind:n,source:I,...k(d.requestId)?{requestId:k(d.requestId)}:{},...k(d.parentRequestId)?{parentRequestId:k(d.parentRequestId)}:{},...a&&l?{queueKey:`${a}#${l}`}:{},browser:H.has(I)||I==="memory"&&o===void 0,bookkeeping:FLOW_BOOKKEEPING_KINDS.has(n),...o?{project:o}:{},...i?{subject:i}:{},...n==="fetch-start"||n==="fetch-done"?{route:S(k(t.url)),method:k(t.method)}:n==="server-request"?{route:k(s.route),method:k(s.method)}:n==="gateway-request"?{route:S(k(t.url)),method:k(t.method)}:{}}}j(E,"W"),g(E,"readItem");function S(e){if(!e)return;const t=e.search(/[?#]/),s=t===-1?e:e.slice(0,t),r=/^[a-z][a-z0-9+.-]*:\/\/[^/]*(\/.*)?$/i.exec(s);return r?r[1]??"/":s}j(S,"A"),g(S,"pathOnly");const J=g(e=>e.split(".")[0],"rootOf"),F=g((e,t)=>e.reduce((s,r)=>Math.min(s,t(r)),1/0),"minOf"),G=g((e,t)=>e.reduce((s,r)=>Math.max(s,t(r)),-1/0),"maxOf"),K=g((e,t)=>e.ts-t.ts||(e.id<t.id?-1:e.id>t.id?1:0),"compare"),A=g(e=>e.requestId&&!e.requestId.startsWith("job:")?J(e.requestId):void 0,"directFamilyOf");function T(e){if(e.requestId?.startsWith("job:"))return e.requestId.slice(4);if(e.queueKey&&e.kind!=="queue-enqueued"&&!e.requestId)return e.queueKey}j(T,"U"),g(T,"jobKeyOf");function W(e,t){const s=e.filter(n=>!n.parentRequestId&&(n.kind==="server-request"||n.kind==="gateway-request"||n.kind==="fetch-start"||n.kind==="fetch-done")).sort((n,f)=>n.from-f.from||K(n,f));if(s.length<2)return[e];const r=[];for(const n of s){const f=r[r.length-1];f&&n.from<=f.to+t?f.to=Math.max(f.to,n.to):r.push({from:n.from,to:n.to})}if(r.length<2)return[e];const d=r.map(()=>[]);for(const n of e){let f=r.findIndex(p=>n.ts>=p.from-t&&n.ts<=p.to+t);if(f===-1){f=0;for(let p=0;p<r.length;p+=1)r[p].from<=n.ts&&(f=p)}d[f].push(n)}return d.filter(n=>n.length>0)}j(W,"L"),g(W,"occurrencesOf");const _={debug:0,info:1,warning:2,error:3,fatal:4};function N(e,t){const s=[];let r=[];for(const d of e){const n=r[r.length-1];n&&d.ts-n.ts>=t&&(s.push(r),r=[]),r.push(d)}return r.length&&s.push(r),s}j(N,"R"),g(N,"runs");export function segmentFlow(e,t={}){const s={...DEFAULT_SEGMENT_OPTIONS};for(const[o,m]of Object.entries(t))typeof m=="number"&&Number.isFinite(m)&&(s[o]=m);const r=new Set,d=[];for(const o of e)r.has(o.id)||(r.add(o.id),d.push(E(o)));d.sort(K);const n=k(d[0]?.event.context?.flowId)??k(d[0]?.event.raw?.flowId)??"",f=new Map;for(const o of d)o.kind==="queue-enqueued"&&o.queueKey&&o.requestId&&!o.requestId.startsWith("job:")&&!f.has(o.queueKey)&&f.set(o.queueKey,o);const p=new Map,h=new Map,$=[];for(const o of d){const m=T(o),w=A(o);if(m!==void 0){const q=h.get(m);q?q.push(o):h.set(m,[o])}else if(w!==void 0){const q=p.get(w);q?q.push(o):p.set(w,[o])}else $.push(o)}const b=[],M=new Map;for(const[o,m]of p)W(m,s.occurrenceSlackMs).forEach((w,q)=>{const x={id:`${n}~r:${o}${q===0?"":`@${q+1}`}`,kind:"request",items:w,requestId:o};b.push(x);for(const y of w)M.set(y,x)});for(const[o,m]of h){const w=f.get(o),q=w?M.get(w):void 0;q?q.items.push(...m):b.push({id:`${n}~r:job:${o}`,kind:"request",items:m,requestId:`job:${o}`})}const c=d.filter(o=>o.kind==="fetch-done"&&A(o)!==void 0),u=new Map;for(const o of b)o.requestId&&u.set(o.requestId,[...u.get(o.requestId)??[],o]);const i=g((o,m)=>{const w=u.get(o);if(w)return w.find(q=>q.items.some(x=>x.kind==="fetch-done"&&x.ts===m))??w[w.length-1]},"owningUnit"),a=$.filter(o=>o.browser);for(const o of N(a,s.burstGapMs)){const m=o[0].ts,w=c.filter(y=>y.ts<=m&&m-y.ts<=s.attachWindowMs),q=[...new Set(w.map(y=>A(y)))];if(q.length===1){const y=i(q[0],w[w.length-1].ts);if(y){y.items.push(...o);continue}}const x=o.some(y=>y.kind==="flow-origin");b.push({id:`${n}~${x?"o":"u"}:${o[0].id}`,kind:x?"origin":"ui",items:o,...q.length>1?{after:q.sort()}:{}})}for(const o of N($.filter(m=>!m.browser),s.phaseGapMs))b.push({id:`${n}~a:${o[0].id}`,kind:"ambient",items:o});const l=B(n,d.length,b,s),I=sqlAccountingOf(d.map(o=>o.event));return I?{...l,sql:I}:l}j(segmentFlow,"segmentFlow"),g(segmentFlow,"segmentFlow");function B(e,t,s,r){for(const c of s)c.items.sort(K);const d=s.map(c=>({unit:c,from:F(c.items,u=>u.from),to:G(c.items,u=>u.to)}));d.sort((c,u)=>c.from-u.from||(c.unit.id<u.unit.id?-1:1));const n=new Map;let f=0,p=-1/0;for(const c of d)(f===0||c.from-p>=r.phaseGapMs)&&(f+=1),p=Math.max(p,c.to),n.set(c.unit,f);const h=[];for(const c of d){const u=R(c.unit.items,r.maxSegmentEvents),i=c.unit.kind==="request"?sqlAccountingOf(c.unit.items.map(a=>a.event)):void 0;u.forEach((a,l)=>{const I=U(e,c.unit,a,n.get(c.unit),u.length>1?{index:l+1,total:u.length}:void 0);h.push(i&&l===0?{...I,sql:i}:I)})}const $={};for(const c of h)for(const u of c.eventIds)$[u]=c.id;const b=[];for(const c of h){let u=b[c.phase-1];u||(u={index:c.phase,start:c.start,end:c.end,segmentIds:[]},b[c.phase-1]=u),u.start=Math.min(u.start,c.start),u.end=Math.max(u.end,c.end),u.segmentIds.push(c.id)}const M=h.reduce((c,u)=>c+u.counts.signal,0);return{flowId:e,segments:h,phases:b.filter(Boolean),assignment:$,stats:{events:t,signal:M,bookkeeping:t-M,segments:h.length,phases:b.filter(Boolean).length,largestSegment:h.reduce((c,u)=>Math.max(c,u.counts.total),0)}}}j(B,"B"),g(B,"assemble");function R(e,t){if(e.filter(n=>!n.bookkeeping).length<=t)return[e];const s=[];let r=[],d=0;for(const n of e)!n.bookkeeping&&d===t&&(s.push(r),r=[],d=0),r.push(n),n.bookkeeping||(d+=1);return r.length&&s.push(r),s}j(R,"C"),g(R,"chunk");function U(e,t,s,r,d){const n={total:s.length,signal:0,bookkeeping:0,errors:0,warnings:0},f=new Set;let p="debug";for(const u of s){u.bookkeeping?n.bookkeeping+=1:n.signal+=1;const i=String(u.event.severity);i==="error"||i==="fatal"?n.errors+=1:i==="warning"&&(n.warnings+=1),(_[i]??1)>(_[p]??0)&&(p=i),u.project&&f.add(u.project)}const h=t.kind==="ui"||t.kind==="origin"?C(s):[],$=F(s,u=>u.from),b=G(s,u=>u.to),M=D(t.items),c=t.id;return{id:d&&d.index>1?`${c}#${d.index}`:c,flowId:e,kind:t.kind,label:L(t,s,M,d,h),phase:r,start:$,end:b,durationMs:b-$,eventIds:s.map(u=>u.id),counts:n,projects:[...f].sort(),...M.route?{route:M.route}:{},...M.method?{method:M.method}:{},...t.requestId?{requestId:t.requestId}:{},...t.after?{after:t.after}:{},...h.length?{hot:h}:{},...d?{part:d}:{},worstSeverity:p}}j(U,"D"),g(U,"toSegment");function D(e){const t=e.find(s=>s.kind==="fetch-start"&&s.route)??e.find(s=>s.kind==="server-request"&&!s.parentRequestId&&s.route)??e.find(s=>s.kind==="gateway-request"&&s.route)??e.find(s=>s.kind==="fetch-done"&&s.route);return{...t?.route?{route:t.route}:{},...t?.method?{method:t.method.toUpperCase()}:{}}}j(D,"P"),g(D,"routeOf");function C(e){const t=new Map;for(const s of e)s.subject&&!s.bookkeeping&&t.set(s.subject,(t.get(s.subject)??0)+1);return[...t.entries()].sort((s,r)=>r[1]-s[1]||(s[0]<r[0]?-1:1)).slice(0,3).map(([s,r])=>r>1?`${s} \xD7${r}`:s)}j(C,"z"),g(C,"hotOf");function L(e,t,s,r,d){const n=r?` (part ${r.index}/${r.total})`:"";if(e.kind==="request"){if(s.route)return`${s.method?`${s.method} `:""}${s.route}${n}`;const f=t.find(p=>p.queueKey);return f?`job ${f.queueKey}${n}`:`request ${e.requestId??""}${n}`}return e.kind==="origin"?`${t.find(f=>f.kind==="flow-origin")?.event.title||"start"}${d.length?` \xB7 ${d.join(", ")}`:""}${n}`:e.kind==="ui"?`UI update${d.length?` \xB7 ${d.join(", ")}`:""}${n}`:`background${n}`}j(L,"Q"),g(L,"labelOf");const P=50;export function sqlAccountingOf(e){const t=new Map,s=new Map,r=new Set;for(const i of e){if(r.has(i.id))continue;r.add(i.id);const a=O(i.raw)?i.raw:{},l=k(a.kind),I=k(i.context?.requestId);if(!I)continue;const o=k(a.project)??k(i.context?.projectName);if(l==="db-query"&&i.source==="db"){const m=s.get(I)??{count:0,workMs:0,...o?{project:o}:{}};m.count+=1,m.workMs+=v(a.durationMs)??0,s.set(I,m)}else if(l===SQL_ACCOUNT_KIND){const m=k(a.accountId)??i.id,w=v(a.seq)??0,q=t.get(m);if(q&&q.seq>=w)continue;t.set(m,{requestId:I,...o?{project:o}:{},seq:w,basis:a.basis==="end"?"end":"settled",statements:v(a.statements)??0,failed:v(a.failed)??0,workMs:v(a.workMs)??0,recorded:v(a.recorded)??0,suppressed:v(a.suppressed)??0,unwritten:v(a.unwritten)??0})}}const d=new Map;for(const i of t.values()){const a=d.get(i.requestId);if(!a){d.set(i.requestId,{...i});continue}i.basis==="settled"&&(a.basis="settled"),a.statements+=i.statements,a.failed+=i.failed,a.workMs+=i.workMs,a.recorded+=i.recorded,a.suppressed+=i.suppressed,a.unwritten+=i.unwritten}const n=[...new Set([...s.keys(),...d.keys()])].sort();if(n.length===0)return;const f={statements:0,failed:0,workMs:0,recorded:0,suppressed:0,unwritten:0},p={statements:0,workMs:0},h=[];for(const i of n){const a=s.get(i),l=d.get(i),I=a?.count??0;p.statements+=I,p.workMs+=a?.workMs??0;const o=!l||I>l.statements?"unverified":I===l.statements?"complete":"incomplete";l&&o!=="unverified"&&(f.statements+=l.statements,f.failed+=l.failed,f.workMs+=l.workMs,f.recorded+=l.recorded,f.suppressed+=l.suppressed,f.unwritten+=l.unwritten);const m=a?.project??l?.project;h.push({requestId:i,...m?{project:m}:{},status:o,observed:I,observedWorkMs:a?.workMs??0,...l?{basis:l.basis,statements:l.statements,failed:l.failed,workMs:l.workMs,recorded:l.recorded,suppressed:l.suppressed,unwritten:l.unwritten}:{}})}const $=g(i=>h.filter(a=>a.status===i).length,"tally"),b=$("unverified"),M=$("incomplete"),c=g(i=>(i.statements??0)-i.observed,"missing"),u=h.filter(i=>i.status!=="complete").sort((i,a)=>(i.status==="incomplete"?0:1)-(a.status==="incomplete"?0:1)||c(a)-c(i)||(i.requestId<a.requestId?-1:i.requestId>a.requestId?1:0));return{status:b>0?"unverified":M>0?"incomplete":"complete",requests:h.length,complete:$("complete"),incomplete:M,unverified:b,settled:h.filter(i=>i.status!=="unverified"&&i.basis==="settled").length,observed:p,accounted:f,gaps:u.slice(0,P),gapsTruncated:u.length>P}}j(sqlAccountingOf,"sqlAccountingOf"),g(sqlAccountingOf,"sqlAccountingOf");
1
+ "use strict";var Y=Object.defineProperty;var b=(e,t)=>Y(e,"name",{value:t,configurable:!0});var Z=Object.defineProperty,m=b((e,t)=>Z(e,"name",{value:t,configurable:!0}),"h");export const DEFAULT_SEGMENT_OPTIONS={phaseGapMs:1500,burstGapMs:250,attachWindowMs:400,maxSegmentEvents:400,occurrenceSlackMs:10},FLOW_BOOKKEEPING_KINDS=new Set(["subscription-added","subscription-removed","hook-run","store-created","singleton-instance","visual-frame"]),SQL_ACCOUNT_KIND="db-request-account";const ee=new Set(["react","valtio","client-runtime","chrome","visual"]),S=m(e=>typeof e=="object"&&e!==null&&!Array.isArray(e),"isObj"),v=m(e=>typeof e=="string"&&e!==""?e:void 0,"str"),M=m(e=>typeof e=="number"&&Number.isFinite(e)?e:void 0,"num"),W=new WeakMap;function F(e){let t=W.get(e);return t||(t=G(e),W.set(e,t)),t}b(F,"U"),m(F,"itemOf");function G(e){const t=S(e.raw)?e.raw:{},s=S(t.request)?t.request:{},o=S(t.span)?t.span:{},i=e.context??{},n=v(t.kind)??"",p=n===SQL_ACCOUNT_KIND,g=(p?M(t.lastEndedAt):void 0)??M(e.timestamp)??0,q=M(s.startedAt)??M(o.startTime)??M(t.startedAt)??(p?M(t.firstStartedAt):void 0),I=M(s.endedAt)??M(o.endTime)??(q!==void 0&&M(t.durationMs)!==void 0?q+t.durationMs:void 0),w=Math.min(g,q??g),$=Math.max(g,I??g),a=S(t.render)?t.render:{},u=S(t.update)?t.update:{},j=n==="render"?v(a.componentName):n==="state-update"?v(u.path)?.split(".").slice(0,2).join("."):void 0,d=v(t.queue),c=v(t.jobId),f=String(e.source),r=v(t.project)??v(i.projectName),l=n==="fetch-start"||n==="fetch-done"||n==="gateway-request";return{event:e,id:e.id,ts:g,from:w,to:$,kind:n,source:f,requestId:v(i.requestId),parentRequestId:v(i.parentRequestId),queueKey:d&&c?`${d}#${c}`:void 0,browser:ee.has(f)||f==="memory"&&r===void 0,bookkeeping:FLOW_BOOKKEEPING_KINDS.has(n),project:r,subject:j,route:l?T(v(t.url)):n==="server-request"?v(s.route):void 0,method:l?v(t.method):n==="server-request"?v(s.method):void 0}}b(G,"L"),m(G,"readItem");function T(e){if(!e)return;const t=e.search(/[?#]/),s=t===-1?e:e.slice(0,t),o=/^[a-z][a-z0-9+.-]*:\/\/[^/]*(\/.*)?$/i.exec(s);return o?o[1]??"/":s}b(T,"B"),m(T,"pathOnly");const te=m(e=>e.split(".")[0],"rootOf"),_=m((e,t)=>e.reduce((s,o)=>Math.min(s,t(o)),1/0),"minOf"),B=m((e,t)=>e.reduce((s,o)=>Math.max(s,t(o)),-1/0),"maxOf"),O=m((e,t)=>e.ts-t.ts||(e.id<t.id?-1:e.id>t.id?1:0),"compare"),K=m(e=>e.requestId&&!e.requestId.startsWith("job:")?te(e.requestId):void 0,"directFamilyOf");function U(e){if(e.requestId?.startsWith("job:"))return e.requestId.slice(4);if(e.queueKey&&e.kind!=="queue-enqueued"&&!e.requestId)return e.queueKey}b(U,"D"),m(U,"jobKeyOf");function D(e,t){const s=e.filter(n=>!n.parentRequestId&&(n.kind==="server-request"||n.kind==="gateway-request"||n.kind==="fetch-start"||n.kind==="fetch-done")).sort((n,p)=>n.from-p.from||O(n,p));if(s.length<2)return[e];const o=[];for(const n of s){const p=o[o.length-1];p&&n.from<=p.to+t?p.to=Math.max(p.to,n.to):o.push({from:n.from,to:n.to})}if(o.length<2)return[e];const i=o.map(()=>[]);for(const n of e)i[t>=0?z(o,n.ts,t):R(o,n.ts,t)].push(n);return i.filter(n=>n.length>0)}b(D,"z"),m(D,"occurrencesOf");function R(e,t,s){const o=e.findIndex(n=>t>=n.from-s&&t<=n.to+s);if(o!==-1)return o;let i=0;for(let n=0;n<e.length;n+=1)e[n].from<=t&&(i=n);return i}b(R,"P"),m(R,"spanScan");function z(e,t,s){let o=0,i=e.length;for(;o<i;){const n=o+i>>1;e[n].to+s<t?o=n+1:i=n}if(o<e.length&&t>=e[o].from-s)return o;for(o=0,i=e.length;o<i;){const n=o+i>>1;e[n].from<=t?o=n+1:i=n}return Math.max(0,o-1)}b(z,"Q"),m(z,"spanAt");const C={debug:0,info:1,warning:2,error:3,fatal:4};function A(e,t){const s=[];let o=[];for(const i of e){const n=o[o.length-1];n&&i.ts-n.ts>=t&&(s.push(o),o=[]),o.push(i)}return o.length&&s.push(o),s}b(A,"R"),m(A,"runs");export function segmentFlow(e,t={}){const s={...DEFAULT_SEGMENT_OPTIONS};for(const[r,l]of Object.entries(t))typeof l=="number"&&Number.isFinite(l)&&(s[r]=l);const o=new Set,i=[];for(const r of e)o.has(r.id)||(o.add(r.id),i.push(F(r)));i.sort(O);const n=v(i[0]?.event.context?.flowId)??v(i[0]?.event.raw?.flowId)??"",p=new Map;for(const r of i)r.kind==="queue-enqueued"&&r.queueKey&&r.requestId&&!r.requestId.startsWith("job:")&&!p.has(r.queueKey)&&p.set(r.queueKey,r);const g=new Map,q=new Map,I=[];for(const r of i){const l=U(r),h=K(r);if(l!==void 0){const k=q.get(l);k?k.push(r):q.set(l,[r])}else if(h!==void 0){const k=g.get(h);k?k.push(r):g.set(h,[r])}else I.push(r)}const w=[],$=new Map;for(const[r,l]of g)D(l,s.occurrenceSlackMs).forEach((h,k)=>{const x={id:`${n}~r:${r}${k===0?"":`@${k+1}`}`,kind:"request",items:h,requestId:r};if(w.push(x),p.size)for(const y of h)y.kind==="queue-enqueued"&&$.set(y,x)});for(const[r,l]of q){const h=p.get(r),k=h?$.get(h):void 0;k?k.items.push(...l):w.push({id:`${n}~r:job:${r}`,kind:"request",items:l,requestId:`job:${r}`})}const a=i.filter(r=>r.kind==="fetch-done"&&K(r)!==void 0),u=new Map;for(const r of w)r.requestId&&u.set(r.requestId,[...u.get(r.requestId)??[],r]);const j=m((r,l)=>{const h=u.get(r);if(h)return h.find(k=>k.items.some(x=>x.kind==="fetch-done"&&x.ts===l))??h[h.length-1]},"owningUnit"),d=I.filter(r=>r.browser);for(const r of A(d,s.burstGapMs)){const l=r[0].ts,h=a.filter(y=>y.ts<=l&&l-y.ts<=s.attachWindowMs),k=[...new Set(h.map(y=>K(y)))];if(k.length===1){const y=j(k[0],h[h.length-1].ts);if(y){y.items.push(...r);continue}}const x=r.some(y=>y.kind==="flow-origin");w.push({id:`${n}~${x?"o":"u"}:${r[0].id}`,kind:x?"origin":"ui",items:r,...k.length>1?{after:k.sort()}:{}})}for(const r of A(I.filter(l=>!l.browser),s.phaseGapMs))w.push({id:`${n}~a:${r[0].id}`,kind:"ambient",items:r});const c=L(n,i.length,w,s),f=N(i);return f?{...c,sql:f}:c}b(segmentFlow,"segmentFlow"),m(segmentFlow,"segmentFlow");function L(e,t,s,o){for(const a of s)a.items.sort(O);const i=s.map(a=>({unit:a,from:_(a.items,u=>u.from),to:B(a.items,u=>u.to)}));i.sort((a,u)=>a.from-u.from||(a.unit.id<u.unit.id?-1:1));const n=new Map;let p=0,g=-1/0;for(const a of i)(p===0||a.from-g>=o.phaseGapMs)&&(p+=1),g=Math.max(g,a.to),n.set(a.unit,p);const q=[];for(const a of i){const u=P(a.unit.items,o.maxSegmentEvents),j=a.unit.kind==="request"?N(a.unit.items):void 0;u.forEach((d,c)=>{const f=Q(e,a.unit,d,n.get(a.unit),u.length>1?{index:c+1,total:u.length}:void 0);q.push(j&&c===0?{...f,sql:j}:f)})}const I={};for(const a of q)for(const u of a.eventIds)I[u]=a.id;const w=[];for(const a of q){let u=w[a.phase-1];u||(u={index:a.phase,start:a.start,end:a.end,segmentIds:[]},w[a.phase-1]=u),u.start=Math.min(u.start,a.start),u.end=Math.max(u.end,a.end),u.segmentIds.push(a.id)}const $=q.reduce((a,u)=>a+u.counts.signal,0);return{flowId:e,segments:q,phases:w.filter(Boolean),assignment:I,stats:{events:t,signal:$,bookkeeping:t-$,segments:q.length,phases:w.filter(Boolean).length,largestSegment:q.reduce((a,u)=>Math.max(a,u.counts.total),0)}}}b(L,"V"),m(L,"assemble");function P(e,t){if(e.filter(n=>!n.bookkeeping).length<=t)return[e];const s=[];let o=[],i=0;for(const n of e)!n.bookkeeping&&i===t&&(s.push(o),o=[],i=0),o.push(n),n.bookkeeping||(i+=1);return o.length&&s.push(o),s}b(P,"X"),m(P,"chunk");function Q(e,t,s,o,i){const n={total:s.length,signal:0,bookkeeping:0,errors:0,warnings:0},p=new Set;let g="debug";for(const u of s){u.bookkeeping?n.bookkeeping+=1:n.signal+=1;const j=String(u.event.severity);j==="error"||j==="fatal"?n.errors+=1:j==="warning"&&(n.warnings+=1),(C[j]??1)>(C[g]??0)&&(g=j),u.project&&p.add(u.project)}const q=t.kind==="ui"||t.kind==="origin"?J(s):[],I=_(s,u=>u.from),w=B(s,u=>u.to),$=H(t.items),a=t.id;return{id:i&&i.index>1?`${a}#${i.index}`:a,flowId:e,kind:t.kind,label:V(t,s,$,i,q),phase:o,start:I,end:w,durationMs:w-I,eventIds:s.map(u=>u.id),counts:n,projects:[...p].sort(),...$.route?{route:$.route}:{},...$.method?{method:$.method}:{},...t.requestId?{requestId:t.requestId}:{},...t.after?{after:t.after}:{},...q.length?{hot:q}:{},...i?{part:i}:{},worstSeverity:g}}b(Q,"Y"),m(Q,"toSegment");function H(e){const t=e.find(s=>s.kind==="fetch-start"&&s.route)??e.find(s=>s.kind==="server-request"&&!s.parentRequestId&&s.route)??e.find(s=>s.kind==="gateway-request"&&s.route)??e.find(s=>s.kind==="fetch-done"&&s.route);return{...t?.route?{route:t.route}:{},...t?.method?{method:t.method.toUpperCase()}:{}}}b(H,"H"),m(H,"routeOf");function J(e){const t=new Map;for(const s of e)s.subject&&!s.bookkeeping&&t.set(s.subject,(t.get(s.subject)??0)+1);return[...t.entries()].sort((s,o)=>o[1]-s[1]||(s[0]<o[0]?-1:1)).slice(0,3).map(([s,o])=>o>1?`${s} \xD7${o}`:s)}b(J,"J"),m(J,"hotOf");function V(e,t,s,o,i){const n=o?` (part ${o.index}/${o.total})`:"";if(e.kind==="request"){if(s.route)return`${s.method?`${s.method} `:""}${s.route}${n}`;const p=t.find(g=>g.queueKey);return p?`job ${p.queueKey}${n}`:`request ${e.requestId??""}${n}`}return e.kind==="origin"?`${t.find(p=>p.kind==="flow-origin")?.event.title||"start"}${i.length?` \xB7 ${i.join(", ")}`:""}${n}`:e.kind==="ui"?`UI update${i.length?` \xB7 ${i.join(", ")}`:""}${n}`:`background${n}`}b(V,"Z"),m(V,"labelOf");const X=50;export function sqlAccountingOf(e){return E(e,!1)}b(sqlAccountingOf,"sqlAccountingOf"),m(sqlAccountingOf,"sqlAccountingOf");function N(e){return E(e.map(t=>t.event),!0)}b(N,"T"),m(N,"accountSqlOfItems");function E(e,t){const s=new Map,o=new Map,i=t?void 0:new Set;for(const d of e){if(i){if(i.has(d.id))continue;i.add(d.id)}const c=S(d.raw)?d.raw:{},f=v(c.kind),r=v(d.context?.requestId);if(!r)continue;const l=v(c.project)??v(d.context?.projectName);if(f==="db-query"&&d.source==="db"){const h=o.get(r)??{count:0,workMs:0,...l?{project:l}:{}};h.count+=1,h.workMs+=M(c.durationMs)??0,o.set(r,h)}else if(f===SQL_ACCOUNT_KIND){const h=v(c.accountId)??d.id,k=M(c.seq)??0,x=s.get(h);if(x&&x.seq>=k)continue;s.set(h,{requestId:r,...l?{project:l}:{},seq:k,basis:c.basis==="end"?"end":"settled",statements:M(c.statements)??0,failed:M(c.failed)??0,workMs:M(c.workMs)??0,recorded:M(c.recorded)??0,suppressed:M(c.suppressed)??0,unwritten:M(c.unwritten)??0})}}const n=new Map;for(const d of s.values()){const c=n.get(d.requestId);if(!c){n.set(d.requestId,{...d});continue}d.basis==="settled"&&(c.basis="settled"),c.statements+=d.statements,c.failed+=d.failed,c.workMs+=d.workMs,c.recorded+=d.recorded,c.suppressed+=d.suppressed,c.unwritten+=d.unwritten}const p=[...new Set([...o.keys(),...n.keys()])].sort();if(p.length===0)return;const g={statements:0,failed:0,workMs:0,recorded:0,suppressed:0,unwritten:0},q={statements:0,workMs:0},I=[];for(const d of p){const c=o.get(d),f=n.get(d),r=c?.count??0;q.statements+=r,q.workMs+=c?.workMs??0;const l=!f||r>f.statements?"unverified":r===f.statements?"complete":"incomplete";f&&l!=="unverified"&&(g.statements+=f.statements,g.failed+=f.failed,g.workMs+=f.workMs,g.recorded+=f.recorded,g.suppressed+=f.suppressed,g.unwritten+=f.unwritten);const h=c?.project??f?.project;I.push({requestId:d,...h?{project:h}:{},status:l,observed:r,observedWorkMs:c?.workMs??0,...f?{basis:f.basis,statements:f.statements,failed:f.failed,workMs:f.workMs,recorded:f.recorded,suppressed:f.suppressed,unwritten:f.unwritten}:{}})}const w=m(d=>I.filter(c=>c.status===d).length,"tally"),$=w("unverified"),a=w("incomplete"),u=m(d=>(d.statements??0)-d.observed,"missing"),j=I.filter(d=>d.status!=="complete").sort((d,c)=>(d.status==="incomplete"?0:1)-(c.status==="incomplete"?0:1)||u(c)-u(d)||(d.requestId<c.requestId?-1:d.requestId>c.requestId?1:0));return{status:$>0?"unverified":a>0?"incomplete":"complete",requests:I.length,complete:w("complete"),incomplete:a,unverified:$,settled:I.filter(d=>d.status!=="unverified"&&d.basis==="settled").length,observed:q,accounted:g,gaps:j.slice(0,X),gapsTruncated:j.length>X}}b(E,"W"),m(E,"accountSql");
@@ -1,8 +1,17 @@
1
1
  import type { HttpExchange } from '@lensmcp/protocol-types';
2
2
  export type { HttpExchange, HttpExchangeBody, HttpExchangeStreamEvent } from '@lensmcp/protocol-types';
3
3
  export declare const HTTP_EXCHANGE_DIR = "http";
4
+ /**
5
+ * Where an exchange is kept, each place pruned on its own budget: a third-party call (`http/`), a request a service
6
+ * served (`http/in/`), and a call between the cluster's own services through the gateway (`http/hops/`, a host under
7
+ * `.localhost`). One budget for all let FoodGuard's ~2,000 service-to-service calls an hour push its OpenAI calls out.
8
+ */
9
+ export type HttpExchangePlace = 'calls' | 'in' | 'hops';
10
+ export declare const HTTP_EXCHANGE_PLACES: readonly HttpExchangePlace[];
11
+ /** The place an exchange belongs in. */
12
+ export declare function exchangePlace(x: Pick<HttpExchange, 'side' | 'host'>): HttpExchangePlace;
4
13
  export declare const isHttpExchangeId: (value: unknown) => value is string;
5
- export declare function httpExchangeDir(busFile: string): string;
6
- export declare function httpExchangeFile(busFile: string, id: string): string;
14
+ export declare function httpExchangeDir(busFile: string, place?: HttpExchangePlace): string;
15
+ export declare function httpExchangeFile(busFile: string, id: string, place?: HttpExchangePlace): string;
7
16
  /** One exchange, or `undefined` — a malformed id, a file never written or rotated away, or unreadable JSON. */
8
17
  export declare function readHttpExchange(busFile: string, id: string): HttpExchange | undefined;
@@ -1 +1 @@
1
- "use strict";var o=Object.defineProperty;var r=(t,e)=>o(t,"name",{value:e,configurable:!0});var c=Object.defineProperty,a=r((t,e)=>c(t,"name",{value:e,configurable:!0}),"e");import*as p from"node:fs";import{dirname as h,join as i}from"node:path";export const HTTP_EXCHANGE_DIR="http";const s=/^hx_[0-9a-z]{8,40}$/;export const isHttpExchangeId=a(t=>typeof t=="string"&&s.test(t),"isHttpExchangeId");export function httpExchangeDir(t){return i(h(t),HTTP_EXCHANGE_DIR)}r(httpExchangeDir,"httpExchangeDir"),a(httpExchangeDir,"httpExchangeDir");export function httpExchangeFile(t,e){if(!isHttpExchangeId(e))throw new Error("invalid http exchange id");return i(httpExchangeDir(t),`${e}.json`)}r(httpExchangeFile,"httpExchangeFile"),a(httpExchangeFile,"httpExchangeFile");export function readHttpExchange(t,e){if(isHttpExchangeId(e))try{const n=JSON.parse(p.readFileSync(httpExchangeFile(t,e),"utf8"));return n&&n.schemaVersion===1&&n.id===e?n:void 0}catch{return}}r(readHttpExchange,"readHttpExchange"),a(readHttpExchange,"readHttpExchange");
1
+ "use strict";var i=Object.defineProperty;var n=(t,e)=>i(t,"name",{value:e,configurable:!0});var s=Object.defineProperty,a=n((t,e)=>s(t,"name",{value:e,configurable:!0}),"r");import*as h from"node:fs";import{dirname as p,join as o}from"node:path";export const HTTP_EXCHANGE_DIR="http",HTTP_EXCHANGE_PLACES=["calls","in","hops"];export function exchangePlace(t){return t.side==="ingress"?"in":/(^|\.)localhost$/i.test(t.host)?"hops":"calls"}n(exchangePlace,"exchangePlace"),a(exchangePlace,"exchangePlace");const l=/^hx_[0-9a-z]{8,40}$/;export const isHttpExchangeId=a(t=>typeof t=="string"&&l.test(t),"isHttpExchangeId");export function httpExchangeDir(t,e="calls"){const r=o(p(t),HTTP_EXCHANGE_DIR);return e==="calls"?r:o(r,e)}n(httpExchangeDir,"httpExchangeDir"),a(httpExchangeDir,"httpExchangeDir");export function httpExchangeFile(t,e,r="calls"){if(!isHttpExchangeId(e))throw new Error("invalid http exchange id");return o(httpExchangeDir(t,r),`${e}.json`)}n(httpExchangeFile,"httpExchangeFile"),a(httpExchangeFile,"httpExchangeFile");export function readHttpExchange(t,e){if(isHttpExchangeId(e))for(const r of HTTP_EXCHANGE_PLACES)try{const c=JSON.parse(h.readFileSync(httpExchangeFile(t,e,r),"utf8"));if(c&&c.schemaVersion===1&&c.id===e)return c}catch{}}n(readHttpExchange,"readHttpExchange"),a(readHttpExchange,"readHttpExchange");
package/lib/redact.js CHANGED
@@ -1 +1 @@
1
- "use strict";var b=Object.defineProperty;var u=(e,r)=>b(e,"name",{value:r,configurable:!0});var E=Object.defineProperty,c=u((e,r)=>E(e,"name",{value:r,configurable:!0}),"f");export const REDACTED="REDACTED",MAX_TITLE_CHARS=300,MAX_MESSAGE_CHARS=4096,MAX_URL_CHARS=1024;const k=["token","secret","password","passwd","apikey","credential","assertion","signature"],_=new Set(["key","auth","authorization","jwt","code","sig","pwd","pass","session","sid","bearer","otp","cookie","set-cookie"]),y=/^(?:(?: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 r=e.toLowerCase();if(y.test(r.replace(/[-_.]+/g,"")))return!1;if(k.some(n=>r.includes(n)))return!0;for(const n of r.split(/[-_.]+/))if(n&&_.has(n))return!0;return!1}u(isSecretParam,"isSecretParam"),c(isSecretParam,"isSecretParam");const z=/^([a-z][a-z0-9+.-]*:\/\/)[^/?#@\s]*@/i,R=/([?&#])([^=&#\s]+)=([^&#\s]*)/g;export function redactUrlParams(e){return e&&e.replace(z,`$1${REDACTED}@`).replace(R,(r,n,t)=>isSecretParam(t)?`${n}${t}=${REDACTED}`:r)}u(redactUrlParams,"redactUrlParams"),c(redactUrlParams,"redactUrlParams");export function redactUrl(e){return e&&clip(redactUrlParams(e),1024)}u(redactUrl,"redactUrl"),c(redactUrl,"redactUrl");const I=/\beyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]*/g,v=/\b(bearer|basic)\s+[A-Za-z0-9._~+/=-]{8,}/gi,C=/\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(C,(r,n,t,a)=>`${n}${t}${a}${REDACTED}${a}`).replace(I,REDACTED).replace(v,(r,n)=>`${n} ${REDACTED}`)}u(redactText,"redactText"),c(redactText,"redactText");export function clip(e,r){return e.length<=r?e:`${e.slice(0,r)}\u2026[lensmcp truncated: ${e.length-r} more chars]`}u(clip,"clip"),c(clip,"clip");export function safeText(e,r=4096){if(e!==void 0)return clip(redactText(e),r)}u(safeText,"safeText"),c(safeText,"safeText");export function safeTitle(e){return clip(redactText(e),300)}u(safeTitle,"safeTitle"),c(safeTitle,"safeTitle");const D=6,N=64,P=/^TS\d{1,5}$/,O=c((e,r)=>e==="code"&&typeof r=="string"&&P.test(r),"isDiagnosticCode");export function redactDeep(e,r=0,n=D){if(typeof e=="string")return redactText(e);if(e===null||typeof e!="object"||r>=n)return e;if(Array.isArray(e)){let o=!1;const s=e.map((i,l)=>{if(l>=N)return i;const p=redactDeep(i,r+1,n);return p!==i&&(o=!0),p});return o?s:e}let t=!1;const a={};for(const[o,s]of Object.entries(e)){const i=isSecretParam(o)&&s!==void 0&&s!==null&&!O(o,s)?REDACTED:redactDeep(s,r+1,n);i!==s&&(t=!0),a[o]=i}return t?a:e}u(redactDeep,"redactDeep"),c(redactDeep,"redactDeep");const g=String.raw`(?:"(?:[^"]|"")+"|[A-Za-z_][\w$]*)`,d=String.raw`${g}(?:\s*\.\s*${g})*`,M=String.raw`(?:=|<>|!=|<=|>=|<|>|(?:NOT\s+)?I?LIKE|IS\s+(?:NOT\s+)?DISTINCT\s+FROM)`,U=new RegExp(String.raw`(${d})\s*${M}\s*(?:[A-Za-z_]\w*\s*\(\s*)?\$(\d+)`,"gi"),L=new RegExp(String.raw`(${d})\s+(?:NOT\s+)?IN\s*\(([^()]*)\)`,"gi"),Z=new RegExp(String.raw`\bINSERT\s+INTO\s+${d}\s*\(([^()]*)\)\s*VALUES\s*`,"gi"),j=new RegExp(g,"g"),$=/\$(\d+)/g,x=16384,H=256,X=4096,f=new Map,h=c(e=>{const r=e.match(j)??[],n=r[r.length-1]??"";return n.startsWith('"')?n.slice(1,-1).replace(/""/g,'"'):n},"lastIdent");function A(e,r){const n=[];let t=r;for(;;){for(;t<e.length&&/\s/.test(e[t]);)t++;if(e[t]!=="(")return n;const a=[];let o=t+1,s=0,i=!1;for(t+=1;t<e.length;t++){const l=e[t];if(i){l==="'"&&(i=!1);continue}if(l==="'")i=!0;else if(l==="(")s++;else if(l===")"){if(s===0)break;s--}else l===","&&s===0&&(a.push(e.slice(o,t)),o=t+1)}if(t>=e.length)return n;for(a.push(e.slice(o,t)),n.push(a),t+=1;t<e.length&&/\s/.test(e[t]);)t++;if(e[t]!==",")return n;t+=1}}u(A,"U"),c(A,"valuesTuples");function S(e){const r=e.length<=X,n=r?f.get(e):void 0;if(n)return n;const t=e.length>x?e.slice(0,x):e,a=new Set,o=c((s,i)=>{i&&isSecretParam(i)&&a.add(Number(s))},"bind");for(const s of t.matchAll(U))o(s[2],h(s[1]));for(const s of t.matchAll(L)){const i=h(s[1]);for(const l of s[2].matchAll($))o(l[1],i)}for(const s of t.matchAll(Z)){const i=s[1].split(",").map(l=>h(l.trim()));for(const l of A(t,(s.index??0)+s[0].length))l.forEach((p,w)=>{const m=i[w];if(m)for(const T of p.matchAll($))o(T[1],m)})}if(r){if(f.size>=H){const s=f.keys().next().value;s!==void 0&&f.delete(s)}f.set(e,a)}return a}u(S,"P"),c(S,"secretPlaceholders");export function redactSqlParams(e,r){if(r.length===0||!e.includes("$"))return r;const n=S(e);if(n.size===0)return r;let t=!1;const a=r.map((o,s)=>o==null||!n.has(s+1)?o:(t=!0,REDACTED));return t?a:r}u(redactSqlParams,"redactSqlParams"),c(redactSqlParams,"redactSqlParams");
1
+ "use strict";var y=Object.defineProperty;var u=(e,r)=>y(e,"name",{value:r,configurable:!0});var E=Object.defineProperty,l=u((e,r)=>E(e,"name",{value:r,configurable:!0}),"a");export const REDACTED="REDACTED",MAX_TITLE_CHARS=300,MAX_MESSAGE_CHARS=4096,MAX_URL_CHARS=1024;const z=["token","secret","password","passwd","apikey","credential","assertion","signature"],_=new Set(["key","auth","authorization","jwt","code","sig","pwd","pass","session","sid","bearer","otp","cookie","set-cookie"]),R=/^(?:(?:prompt|completion|total|input|output|cache|cached|cacheread|cachewrite|reasoning|thinking|max|min|remaining|used|billed)tokens|tokens?(?:count|used|limit|remaining))$/;export function isSecretParam(e){const r=d.get(e);if(r!==void 0)return r;const s=A(e);return e.length<=64&&d.size<I&&d.set(e,s),s}u(isSecretParam,"isSecretParam"),l(isSecretParam,"isSecretParam");const I=4096,d=new Map;function A(e){const r=e.toLowerCase();if(R.test(r.replace(/[-_.]+/g,"")))return!1;if(z.some(s=>r.includes(s)))return!0;for(const s of r.split(/[-_.]+/))if(s&&_.has(s))return!0;return!1}u(A,"M"),l(A,"judgeParam");const v=/^([a-z][a-z0-9+.-]*:\/\/)[^/?#@\s]*@/i,P=/([?&#])([^=&#\s]+)=([^&#\s]*)/g;export function redactUrlParams(e){return e&&e.replace(v,`$1${REDACTED}@`).replace(P,(r,s,t)=>isSecretParam(t)?`${s}${t}=${REDACTED}`:r)}u(redactUrlParams,"redactUrlParams"),l(redactUrlParams,"redactUrlParams");export function redactUrl(e){return e&&clip(redactUrlParams(e),1024)}u(redactUrl,"redactUrl"),l(redactUrl,"redactUrl");const C=/\beyJ[A-Za-z0-9_-]{6,}\.[A-Za-z0-9_-]{4,}\.[A-Za-z0-9_-]*/g,D=/\b(bearer|basic)\s+[A-Za-z0-9._~+/=-]{8,}/gi,N=/\b(authorization|x-api-key|api-key|cookie|set-cookie|proxy-authorization)\b(\s*[:=]\s*)(["']?)((?:(?:bearer|basic)\s+)?[^\s"',;]{4,})\3/gi,M=/[@=:]|eyJ|bearer|basic/i;export function redactText(e){return M.test(e)?redactUrlParams(e).replace(N,(r,s,t,c)=>`${s}${t}${c}${REDACTED}${c}`).replace(C,REDACTED).replace(D,(r,s)=>`${s} ${REDACTED}`):e}u(redactText,"redactText"),l(redactText,"redactText");export function clip(e,r){return e.length<=r?e:`${e.slice(0,r)}\u2026[lensmcp truncated: ${e.length-r} more chars]`}u(clip,"clip"),l(clip,"clip");export function safeText(e,r=4096){if(e!==void 0)return clip(redactText(e),r)}u(safeText,"safeText"),l(safeText,"safeText");export function safeTitle(e){return clip(redactText(e),300)}u(safeTitle,"safeTitle"),l(safeTitle,"safeTitle");const O=6,U=64,Z=/^TS\d{1,5}$/,j=l((e,r)=>e==="code"&&typeof r=="string"&&Z.test(r),"isDiagnosticCode");export function redactDeep(e,r=0,s=O){if(typeof e=="string")return redactText(e);if(e===null||typeof e!="object"||r>=s)return e;if(Array.isArray(e)){let n;for(let o=0;o<e.length;o++){if(o>=U){n&&n.push(e[o]);continue}const i=e[o],f=redactDeep(i,r+1,s);n?n.push(f):f!==i&&(n=e.slice(0,o),n.push(f))}return n??e}const t=e,c=Object.keys(t);let a;for(let n=0;n<c.length;n++){const o=c[n],i=t[o],f=isSecretParam(o)&&i!==void 0&&i!==null&&!j(o,i)?REDACTED:redactDeep(i,r+1,s);if(a)a[o]=f;else if(f!==i){a={};for(let p=0;p<n;p++)a[c[p]]=t[c[p]];a[o]=f}}return a??e}u(redactDeep,"redactDeep"),l(redactDeep,"redactDeep");const h=String.raw`(?:"(?:[^"]|"")+"|[A-Za-z_][\w$]*)`,m=String.raw`${h}(?:\s*\.\s*${h})*`,L=String.raw`(?:=|<>|!=|<=|>=|<|>|(?:NOT\s+)?I?LIKE|IS\s+(?:NOT\s+)?DISTINCT\s+FROM)`,H=new RegExp(String.raw`(${m})\s*${L}\s*(?:[A-Za-z_]\w*\s*\(\s*)?\$(\d+)`,"gi"),X=new RegExp(String.raw`(${m})\s+(?:NOT\s+)?IN\s*\(([^()]*)\)`,"gi"),q=new RegExp(String.raw`\bINSERT\s+INTO\s+${m}\s*\(([^()]*)\)\s*VALUES\s*`,"gi"),F=new RegExp(h,"g"),w=/\$(\d+)/g,S=16384,G=256,J=4096,g=new Map,$=l(e=>{const r=e.match(F)??[],s=r[r.length-1]??"";return s.startsWith('"')?s.slice(1,-1).replace(/""/g,'"'):s},"lastIdent");function b(e,r){const s=[];let t=r;for(;;){for(;t<e.length&&/\s/.test(e[t]);)t++;if(e[t]!=="(")return s;const c=[];let a=t+1,n=0,o=!1;for(t+=1;t<e.length;t++){const i=e[t];if(o){i==="'"&&(o=!1);continue}if(i==="'")o=!0;else if(i==="(")n++;else if(i===")"){if(n===0)break;n--}else i===","&&n===0&&(c.push(e.slice(a,t)),a=t+1)}if(t>=e.length)return s;for(c.push(e.slice(a,t)),s.push(c),t+=1;t<e.length&&/\s/.test(e[t]);)t++;if(e[t]!==",")return s;t+=1}}u(b,"G"),l(b,"valuesTuples");function T(e){const r=e.length<=J,s=r?g.get(e):void 0;if(s)return s;const t=e.length>S?e.slice(0,S):e,c=new Set,a=l((n,o)=>{o&&isSecretParam(o)&&c.add(Number(n))},"bind");for(const n of t.matchAll(H))a(n[2],$(n[1]));for(const n of t.matchAll(X)){const o=$(n[1]);for(const i of n[2].matchAll(w))a(i[1],o)}for(const n of t.matchAll(q)){const o=n[1].split(",").map(i=>$(i.trim()));for(const i of b(t,(n.index??0)+n[0].length))i.forEach((f,p)=>{const x=o[p];if(x)for(const k of f.matchAll(w))a(k[1],x)})}if(r){if(g.size>=G){const n=g.keys().next().value;n!==void 0&&g.delete(n)}g.set(e,c)}return c}u(T,"F"),l(T,"secretPlaceholders");export function redactSqlParams(e,r){if(r.length===0||!e.includes("$"))return r;const s=T(e);if(s.size===0)return r;let t=!1;const c=r.map((a,n)=>a==null||!s.has(n+1)?a:(t=!0,REDACTED));return t?c:r}u(redactSqlParams,"redactSqlParams"),l(redactSqlParams,"redactSqlParams");
@@ -18,6 +18,17 @@ export interface ResourceStoreOptions {
18
18
  * Reads are never delayed: `read` produces the resource fresh. Only the revision and the notification wait.
19
19
  */
20
20
  coalesceMs?: number;
21
+ /**
22
+ * Space a resource's recomputes by what each one COSTS: at least this many times its last recompute (0, the default:
23
+ * `coalesceMs` alone). At 20, a resource that takes 50 ms to produce and serialise is recomputed at most once a
24
+ * second, one that takes 2 ms keeps `coalesceMs` — so no resource can take more than ~1/20 of a core however busy the
25
+ * workspace. FoodGuard, 2026-10-20: `agent://current-status` (which reads every signal) and `routes://lint` (which
26
+ * details every route) were recomputed every 100 ms of a 400-event-a-second stream, about a sixth of the dashboard's
27
+ * CPU, only to learn whether their JSON had changed.
28
+ */
29
+ costFactor?: number;
30
+ /** The most cost spacing may hold a resource back (default 30 s). */
31
+ maxGapMs?: number;
21
32
  }
22
33
  /**
23
34
  * The resource store. URIs are registered once; reading is cheap; the
@@ -28,9 +39,13 @@ export declare class ResourceStore {
28
39
  private readonly entries;
29
40
  private readonly subs;
30
41
  private readonly coalesceMs;
42
+ private readonly costFactor;
43
+ private readonly maxGapMs;
31
44
  /** A recompute already scheduled per URI — every mark until it runs rides on it. */
32
45
  private readonly queued;
33
46
  private readonly lastRun;
47
+ /** What the last recompute of each URI took (produce + serialise), in ms. */
48
+ private readonly lastCost;
34
49
  constructor(opts?: ResourceStoreOptions);
35
50
  register(uri: string, produce: ResourceProducer): Unsubscribe;
36
51
  read(uri: string): Promise<ResourceValue>;
@@ -41,6 +56,10 @@ export declare class ResourceStore {
41
56
  * change.
42
57
  */
43
58
  markDirty(uri: string): Promise<void>;
59
+ /** How long after its last recompute a URI may be recomputed again. */
60
+ private gapFor;
61
+ /** What the last recompute of a URI took, in ms (produce + serialise) — undefined before the first. */
62
+ cost(uri: string): number | undefined;
44
63
  private recompute;
45
64
  revision(uri: string): number | undefined;
46
65
  subscribe(uri: string, handler: ResourceUpdatedHandler): Unsubscribe;
@@ -1 +1 @@
1
- "use strict";var c=Object.defineProperty;var u=(n,e)=>c(n,"name",{value:e,configurable:!0});var h=Object.defineProperty,a=u((n,e)=>h(n,"name",{value:e,configurable:!0}),"o");export class ResourceStore{static{u(this,"ResourceStore")}static{a(this,"ResourceStore")}constructor(e={}){this.entries=new Map,this.subs=new Map,this.queued=new Map,this.lastRun=new Map,this.coalesceMs=Math.max(0,e.coalesceMs??0)}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),this.lastRun.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()]}markDirty(e){if(this.coalesceMs===0)return this.recompute(e);if(!this.entries.has(e))return Promise.resolve();const t=this.queued.get(e);if(t)return t;const s=Math.max(0,(this.lastRun.get(e)??Number.NEGATIVE_INFINITY)+this.coalesceMs-Date.now()),r=new Promise(i=>{const o=a(()=>{this.queued.delete(e),this.lastRun.set(e,Date.now()),this.recompute(e).then(i,()=>i())},"go");s===0?setImmediate(o):setTimeout(o,s).unref?.()});return this.queued.set(e,r),r}async recompute(e){const t=this.entries.get(e);if(!t)return;const s=await t.produce(),r=JSON.stringify(s);if(r===t.lastJson)return;t.lastJson=r,t.revision+=1;const i=this.subs.get(e);if(i)for(const o of i)try{o(e,t.revision)}catch{}}revision(e){return this.entries.get(e)?.revision}subscribe(e,t){let s=this.subs.get(e);return s||(s=new Set,this.subs.set(e,s)),s.add(t),()=>{s?.delete(t)}}}
1
+ "use strict";var u=Object.defineProperty;var a=(o,e)=>u(o,"name",{value:e,configurable:!0});var l=Object.defineProperty,h=a((o,e)=>l(o,"name",{value:e,configurable:!0}),"a");export class ResourceStore{static{a(this,"ResourceStore")}static{h(this,"ResourceStore")}constructor(e={}){this.entries=new Map,this.subs=new Map,this.queued=new Map,this.lastRun=new Map,this.lastCost=new Map,this.coalesceMs=Math.max(0,e.coalesceMs??0),this.costFactor=Math.max(0,e.costFactor??0),this.maxGapMs=Math.max(0,e.maxGapMs??3e4)}register(e,s){if(this.entries.has(e))throw new Error(`Resource already registered: ${e}`);return this.entries.set(e,{uri:e,produce:s,revision:0}),()=>{this.entries.delete(e),this.subs.delete(e),this.lastRun.delete(e),this.lastCost.delete(e)}}async read(e){const s=this.entries.get(e);if(!s)throw new Error(`Unknown resource: ${e}`);return s.produce()}list(){return[...this.entries.keys()]}markDirty(e){if(this.coalesceMs===0&&this.costFactor===0)return this.recompute(e);if(!this.entries.has(e))return Promise.resolve();const s=this.queued.get(e);if(s)return s;const t=Math.max(0,(this.lastRun.get(e)??Number.NEGATIVE_INFINITY)+this.gapFor(e)-Date.now()),n=new Promise(r=>{const i=h(()=>{this.queued.delete(e),this.lastRun.set(e,Date.now()),this.recompute(e).then(r,()=>r())},"go");t===0?setImmediate(i):setTimeout(i,t).unref?.()});return this.queued.set(e,n),n}gapFor(e){const s=this.lastCost.get(e)??0;return Math.max(this.coalesceMs,Math.min(this.maxGapMs,this.costFactor*s))}cost(e){return this.lastCost.get(e)}async recompute(e){const s=this.entries.get(e);if(!s)return;const t=performance.now(),n=await s.produce(),r=JSON.stringify(n);if(this.lastCost.set(e,performance.now()-t),r===s.lastJson)return;s.lastJson=r,s.revision+=1;const i=this.subs.get(e);if(i)for(const c of i)try{c(e,s.revision)}catch{}}revision(e){return this.entries.get(e)?.revision}subscribe(e,s){let t=this.subs.get(e);return t||(t=new Set,this.subs.set(e,t)),t.add(s),()=>{t?.delete(s)}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/core",
3
- "version": "1.25.3",
3
+ "version": "1.25.6",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "module": "./index.js",
@@ -64,7 +64,7 @@
64
64
  }
65
65
  },
66
66
  "dependencies": {
67
- "@lensmcp/protocol-types": "1.25.3",
67
+ "@lensmcp/protocol-types": "1.25.6",
68
68
  "tslib": "^2.3.0"
69
69
  },
70
70
  "license": "Apache-2.0",