@lensmcp/vite-plugin 1.22.2 → 1.22.4

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,2 +1,2 @@
1
- "use strict";var N=Object.defineProperty;var s=(e,n)=>N(e,"name",{value:n,configurable:!0});var q=Object.defineProperty,u=s((e,n)=>q(e,"name",{value:n,configurable:!0}),"c"),z=Object.defineProperty,v=u((e,n)=>z(e,"name",{value:n,configurable:!0}),"c"),B=Object.defineProperty,d=v((e,n)=>B(e,"name",{value:n,configurable:!0}),"c"),D=Object.defineProperty,f=d((e,n)=>D(e,"name",{value:n,configurable:!0}),"c"),G=Object.defineProperty,m=f((e,n)=>G(e,"name",{value:n,configurable:!0}),"c"),H=Object.defineProperty,p=m((e,n)=>H(e,"name",{value:n,configurable:!0}),"c"),K=Object.defineProperty,g=p((e,n)=>K(e,"name",{value:n,configurable:!0}),"l"),M=Object.defineProperty,b=g((e,n)=>M(e,"name",{value:n,configurable:!0}),"l"),Q=Object.defineProperty,y=b((e,n)=>Q(e,"name",{value:n,configurable:!0}),"c"),V=Object.defineProperty,j=y((e,n)=>V(e,"name",{value:n,configurable:!0}),"c"),W=Object.defineProperty,T=j((e,n)=>W(e,"name",{value:n,configurable:!0}),"c"),X=Object.defineProperty,E=T((e,n)=>X(e,"name",{value:n,configurable:!0}),"u"),Y=Object.defineProperty,O=E((e,n)=>Y(e,"name",{value:n,configurable:!0}),"u"),Z=Object.defineProperty,P=O((e,n)=>Z(e,"name",{value:n,configurable:!0}),"u"),_=Object.defineProperty,I=P((e,n)=>_(e,"name",{value:n,configurable:!0}),"c"),ee=Object.defineProperty,w=I((e,n)=>ee(e,"name",{value:n,configurable:!0}),"c"),ne=Object.defineProperty,k=w((e,n)=>ne(e,"name",{value:n,configurable:!0}),"c"),te=Object.defineProperty,$=k((e,n)=>te(e,"name",{value:n,configurable:!0}),"u"),re=Object.defineProperty,h=$((e,n)=>re(e,"name",{value:n,configurable:!0}),"u"),ie=Object.defineProperty,x=h((e,n)=>ie(e,"name",{value:n,configurable:!0}),"u"),oe=Object.defineProperty,S=x((e,n)=>oe(e,"name",{value:n,configurable:!0}),"u"),ae=Object.defineProperty,U=S((e,n)=>ae(e,"name",{value:n,configurable:!0}),"o"),le=Object.defineProperty,R=U((e,n)=>le(e,"name",{value:n,configurable:!0}),"o"),ce=Object.defineProperty,A=R((e,n)=>ce(e,"name",{value:n,configurable:!0}),"o"),se=Object.defineProperty,C=A((e,n)=>se(e,"name",{value:n,configurable:!0}),"o"),ue=Object.defineProperty,F=C((e,n)=>ue(e,"name",{value:n,configurable:!0}),"o"),ve=Object.defineProperty,J=F((e,n)=>ve(e,"name",{value:n,configurable:!0}),"o");import{fingerprint as l,ulid as c}from"@lensmcp/core";const de="pending";export function envelopeToEvent(e,n=de){const o=e.tabId?{tabId:e.tabId}:{};switch(e.kind){case"error":return{id:c(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"error",context:{sessionId:n,...o},fingerprint:l({kind:"runtime",identity:`error:${t(e.stack)}`,file:e.source,detail:e.message}),title:e.message,message:e.stack??e.message,location:e.source?{file:e.source,line:e.lineno,column:e.colno}:void 0,raw:e};case"unhandledrejection":return{id:c(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"error",context:{sessionId:n,...o},fingerprint:l({kind:"runtime",identity:`unhandledrejection:${e.reason.slice(0,80)}`}),title:"Unhandled promise rejection",message:e.reason,raw:e};case"console":{const a=e.level==="error"?"error":e.level==="warn"?"warning":"info",L=e.args.map(i).join(" ");return{id:c(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:a,context:{sessionId:n,...o},fingerprint:l({kind:"runtime",identity:`console:${e.level}:${L.slice(0,80)}`}),title:`console.${e.level}`,message:L,raw:e}}case"fetch":{const a=e.error!==void 0||e.status!==void 0&&e.status>=400;return{id:c(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"network",severity:a?"error":"info",context:{sessionId:n,...o},fingerprint:l({kind:"network",identity:`${e.method}:${r(e.url)}:${e.status??"err"}`}),title:`${e.method} ${e.url}${e.status!==void 0?` \u2192 ${e.status}`:""}`,message:e.error,relatedUrls:[e.url],raw:e}}case"route":return{id:c(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"info",context:{sessionId:n,url:e.url,...o},fingerprint:l({kind:"runtime",identity:`route:${e.url}`}),title:`Route \u2192 ${e.url}`,raw:e};case"ready":return{id:c(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"info",context:{sessionId:n,url:e.url,...o},fingerprint:l({kind:"runtime",identity:"client-ready"}),title:"Client runtime ready",message:e.userAgent,raw:e};case"publish":return{id:c(),sessionId:n,timestamp:e.at,source:e.source,category:e.category,severity:e.severity??"info",context:{sessionId:n,...o,...e.context??{}},fingerprint:e.fingerprint??l({kind:"publish",identity:e.title}),title:e.title,message:e.message,raw:e.raw}}}s(envelopeToEvent,"envelopeToEvent"),u(envelopeToEvent,"envelopeToEvent"),v(envelopeToEvent,"envelopeToEvent"),d(envelopeToEvent,"envelopeToEvent"),f(envelopeToEvent,"envelopeToEvent"),m(envelopeToEvent,"envelopeToEvent"),p(envelopeToEvent,"envelopeToEvent"),g(envelopeToEvent,"envelopeToEvent"),b(envelopeToEvent,"envelopeToEvent"),y(envelopeToEvent,"envelopeToEvent"),j(envelopeToEvent,"envelopeToEvent"),T(envelopeToEvent,"envelopeToEvent"),E(envelopeToEvent,"envelopeToEvent"),O(envelopeToEvent,"envelopeToEvent"),P(envelopeToEvent,"envelopeToEvent"),I(envelopeToEvent,"envelopeToEvent"),w(envelopeToEvent,"envelopeToEvent"),k(envelopeToEvent,"envelopeToEvent"),$(envelopeToEvent,"envelopeToEvent"),h(envelopeToEvent,"envelopeToEvent"),x(envelopeToEvent,"envelopeToEvent"),S(envelopeToEvent,"envelopeToEvent"),U(envelopeToEvent,"envelopeToEvent"),R(envelopeToEvent,"envelopeToEvent"),A(envelopeToEvent,"envelopeToEvent"),C(envelopeToEvent,"envelopeToEvent"),F(envelopeToEvent,"envelopeToEvent"),J(envelopeToEvent,"envelopeToEvent");function t(e){if(!e)return"unknown";const n=e.split(`
2
- `).slice(0,2);for(const o of n){const a=o.match(/at\s+(\S+)/);if(a&&a[1])return a[1]}return"unknown"}s(t,"t"),u(t,"t"),v(t,"t"),d(t,"t"),f(t,"n"),m(t,"t"),p(t,"n"),g(t,"t"),b(t,"n"),y(t,"t"),j(t,"n"),T(t,"t"),E(t,"r"),O(t,"t"),P(t,"r"),I(t,"t"),w(t,"n"),k(t,"n"),$(t,"r"),h(t,"n"),x(t,"o"),S(t,"a"),U(t,"l"),R(t,"l"),A(t,"c"),C(t,"c"),F(t,"s"),J(t,"normaliseStackTopFrame");function r(e){try{return`${new URL(e,"http://x").pathname}`}catch{return e}}s(r,"r"),u(r,"r"),v(r,"r"),d(r,"r"),f(r,"r"),m(r,"r"),p(r,"r"),g(r,"r"),b(r,"r"),y(r,"r"),j(r,"r"),T(r,"r"),E(r,"n"),O(r,"r"),P(r,"n"),I(r,"r"),w(r,"r"),k(r,"r"),$(r,"i"),h(r,"i"),x(r,"a"),S(r,"c"),U(r,"d"),R(r,"d"),A(r,"l"),C(r,"l"),F(r,"m"),J(r,"normaliseUrl");function i(e){if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}s(i,"i"),u(i,"i"),v(i,"i"),d(i,"i"),f(i,"i"),m(i,"i"),p(i,"i"),g(i,"i"),b(i,"i"),y(i,"i"),j(i,"i"),T(i,"i"),E(i,"i"),O(i,"i"),P(i,"i"),I(i,"i"),w(i,"i"),k(i,"i"),$(i,"o"),h(i,"o"),x(i,"c"),S(i,"u"),U(i,"m"),R(i,"m"),A(i,"d"),C(i,"d"),F(i,"d"),J(i,"stringify");
1
+ "use strict";var D=Object.defineProperty;var u=(e,n)=>D(e,"name",{value:n,configurable:!0});var G=Object.defineProperty,s=u((e,n)=>G(e,"name",{value:n,configurable:!0}),"u"),H=Object.defineProperty,v=s((e,n)=>H(e,"name",{value:n,configurable:!0}),"s"),K=Object.defineProperty,d=v((e,n)=>K(e,"name",{value:n,configurable:!0}),"s"),M=Object.defineProperty,f=d((e,n)=>M(e,"name",{value:n,configurable:!0}),"s"),Q=Object.defineProperty,p=f((e,n)=>Q(e,"name",{value:n,configurable:!0}),"c"),V=Object.defineProperty,m=p((e,n)=>V(e,"name",{value:n,configurable:!0}),"c"),W=Object.defineProperty,b=m((e,n)=>W(e,"name",{value:n,configurable:!0}),"c"),X=Object.defineProperty,g=b((e,n)=>X(e,"name",{value:n,configurable:!0}),"c"),Y=Object.defineProperty,y=g((e,n)=>Y(e,"name",{value:n,configurable:!0}),"c"),Z=Object.defineProperty,j=y((e,n)=>Z(e,"name",{value:n,configurable:!0}),"c"),_=Object.defineProperty,T=j((e,n)=>_(e,"name",{value:n,configurable:!0}),"l"),ee=Object.defineProperty,E=T((e,n)=>ee(e,"name",{value:n,configurable:!0}),"l"),ne=Object.defineProperty,O=E((e,n)=>ne(e,"name",{value:n,configurable:!0}),"c"),te=Object.defineProperty,P=O((e,n)=>te(e,"name",{value:n,configurable:!0}),"c"),re=Object.defineProperty,I=P((e,n)=>re(e,"name",{value:n,configurable:!0}),"c"),oe=Object.defineProperty,w=I((e,n)=>oe(e,"name",{value:n,configurable:!0}),"u"),ie=Object.defineProperty,k=w((e,n)=>ie(e,"name",{value:n,configurable:!0}),"u"),ae=Object.defineProperty,$=k((e,n)=>ae(e,"name",{value:n,configurable:!0}),"u"),le=Object.defineProperty,h=$((e,n)=>le(e,"name",{value:n,configurable:!0}),"c"),ce=Object.defineProperty,x=h((e,n)=>ce(e,"name",{value:n,configurable:!0}),"c"),ue=Object.defineProperty,S=x((e,n)=>ue(e,"name",{value:n,configurable:!0}),"c"),se=Object.defineProperty,U=S((e,n)=>se(e,"name",{value:n,configurable:!0}),"u"),ve=Object.defineProperty,R=U((e,n)=>ve(e,"name",{value:n,configurable:!0}),"u"),de=Object.defineProperty,A=R((e,n)=>de(e,"name",{value:n,configurable:!0}),"u"),fe=Object.defineProperty,C=A((e,n)=>fe(e,"name",{value:n,configurable:!0}),"u"),pe=Object.defineProperty,F=C((e,n)=>pe(e,"name",{value:n,configurable:!0}),"o"),me=Object.defineProperty,J=F((e,n)=>me(e,"name",{value:n,configurable:!0}),"o"),be=Object.defineProperty,L=J((e,n)=>be(e,"name",{value:n,configurable:!0}),"o"),ge=Object.defineProperty,N=L((e,n)=>ge(e,"name",{value:n,configurable:!0}),"o"),ye=Object.defineProperty,q=N((e,n)=>ye(e,"name",{value:n,configurable:!0}),"o"),je=Object.defineProperty,z=q((e,n)=>je(e,"name",{value:n,configurable:!0}),"o");import{fingerprint as l,ulid as c}from"@lensmcp/core";const Te="pending";export function envelopeToEvent(e,n=Te){const i=e.tabId?{tabId:e.tabId}:{};switch(e.kind){case"error":return{id:c(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"error",context:{sessionId:n,...i},fingerprint:l({kind:"runtime",identity:`error:${t(e.stack)}`,file:e.source,detail:e.message}),title:e.message,message:e.stack??e.message,location:e.source?{file:e.source,line:e.lineno,column:e.colno}:void 0,raw:e};case"unhandledrejection":return{id:c(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"error",context:{sessionId:n,...i},fingerprint:l({kind:"runtime",identity:`unhandledrejection:${e.reason.slice(0,80)}`}),title:"Unhandled promise rejection",message:e.reason,raw:e};case"console":{const a=e.level==="error"?"error":e.level==="warn"?"warning":"info",B=e.args.map(o).join(" ");return{id:c(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:a,context:{sessionId:n,...i},fingerprint:l({kind:"runtime",identity:`console:${e.level}:${B.slice(0,80)}`}),title:`console.${e.level}`,message:B,raw:e}}case"fetch":{const a=e.error!==void 0||e.status!==void 0&&e.status>=400;return{id:c(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"network",severity:a?"error":"info",context:{sessionId:n,...i},fingerprint:l({kind:"network",identity:`${e.method}:${r(e.url)}:${e.status??"err"}`}),title:`${e.method} ${e.url}${e.status!==void 0?` \u2192 ${e.status}`:""}`,message:e.error,relatedUrls:[e.url],raw:e}}case"route":return{id:c(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"info",context:{sessionId:n,url:e.url,...i},fingerprint:l({kind:"runtime",identity:`route:${e.url}`}),title:`Route \u2192 ${e.url}`,raw:e};case"ready":return{id:c(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"info",context:{sessionId:n,url:e.url,...i},fingerprint:l({kind:"runtime",identity:"client-ready"}),title:"Client runtime ready",message:e.userAgent,raw:e};case"publish":return{id:c(),sessionId:n,timestamp:e.at,source:e.source,category:e.category,severity:e.severity??"info",context:{sessionId:n,...i,...e.context??{}},fingerprint:e.fingerprint??l({kind:"publish",identity:e.title}),title:e.title,message:e.message,raw:e.raw}}}u(envelopeToEvent,"envelopeToEvent"),s(envelopeToEvent,"envelopeToEvent"),v(envelopeToEvent,"envelopeToEvent"),d(envelopeToEvent,"envelopeToEvent"),f(envelopeToEvent,"envelopeToEvent"),p(envelopeToEvent,"envelopeToEvent"),m(envelopeToEvent,"envelopeToEvent"),b(envelopeToEvent,"envelopeToEvent"),g(envelopeToEvent,"envelopeToEvent"),y(envelopeToEvent,"envelopeToEvent"),j(envelopeToEvent,"envelopeToEvent"),T(envelopeToEvent,"envelopeToEvent"),E(envelopeToEvent,"envelopeToEvent"),O(envelopeToEvent,"envelopeToEvent"),P(envelopeToEvent,"envelopeToEvent"),I(envelopeToEvent,"envelopeToEvent"),w(envelopeToEvent,"envelopeToEvent"),k(envelopeToEvent,"envelopeToEvent"),$(envelopeToEvent,"envelopeToEvent"),h(envelopeToEvent,"envelopeToEvent"),x(envelopeToEvent,"envelopeToEvent"),S(envelopeToEvent,"envelopeToEvent"),U(envelopeToEvent,"envelopeToEvent"),R(envelopeToEvent,"envelopeToEvent"),A(envelopeToEvent,"envelopeToEvent"),C(envelopeToEvent,"envelopeToEvent"),F(envelopeToEvent,"envelopeToEvent"),J(envelopeToEvent,"envelopeToEvent"),L(envelopeToEvent,"envelopeToEvent"),N(envelopeToEvent,"envelopeToEvent"),q(envelopeToEvent,"envelopeToEvent"),z(envelopeToEvent,"envelopeToEvent");function t(e){if(!e)return"unknown";const n=e.split(`
2
+ `).slice(0,2);for(const i of n){const a=i.match(/at\s+(\S+)/);if(a&&a[1])return a[1]}return"unknown"}u(t,"t"),s(t,"t"),v(t,"t"),d(t,"t"),f(t,"t"),p(t,"t"),m(t,"t"),b(t,"t"),g(t,"n"),y(t,"t"),j(t,"n"),T(t,"t"),E(t,"n"),O(t,"t"),P(t,"n"),I(t,"t"),w(t,"r"),k(t,"t"),$(t,"r"),h(t,"t"),x(t,"n"),S(t,"n"),U(t,"r"),R(t,"n"),A(t,"o"),C(t,"a"),F(t,"l"),J(t,"l"),L(t,"c"),N(t,"c"),q(t,"s"),z(t,"normaliseStackTopFrame");function r(e){try{return`${new URL(e,"http://x").pathname}`}catch{return e}}u(r,"r"),s(r,"r"),v(r,"r"),d(r,"r"),f(r,"r"),p(r,"r"),m(r,"r"),b(r,"r"),g(r,"r"),y(r,"r"),j(r,"r"),T(r,"r"),E(r,"r"),O(r,"r"),P(r,"r"),I(r,"r"),w(r,"n"),k(r,"r"),$(r,"n"),h(r,"r"),x(r,"r"),S(r,"r"),U(r,"i"),R(r,"i"),A(r,"a"),C(r,"c"),F(r,"d"),J(r,"d"),L(r,"l"),N(r,"l"),q(r,"m"),z(r,"normaliseUrl");function o(e){if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}u(o,"i"),s(o,"i"),v(o,"i"),d(o,"i"),f(o,"i"),p(o,"i"),m(o,"i"),b(o,"i"),g(o,"i"),y(o,"i"),j(o,"i"),T(o,"i"),E(o,"i"),O(o,"i"),P(o,"i"),I(o,"i"),w(o,"i"),k(o,"i"),$(o,"i"),h(o,"i"),x(o,"i"),S(o,"i"),U(o,"o"),R(o,"o"),A(o,"c"),C(o,"u"),F(o,"m"),J(o,"m"),L(o,"d"),N(o,"d"),q(o,"d"),z(o,"stringify");
package/lib/plugin.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var V=Object.defineProperty;var p=(e,t)=>V(e,"name",{value:t,configurable:!0});var $=Object.defineProperty,d=p((e,t)=>$(e,"name",{value:t,configurable:!0}),"u");import{existsSync as U,readdirSync as q,statSync as J}from"node:fs";import{delimiter as K,join as O,relative as I,resolve as T,sep as A}from"node:path";import{fingerprint as C,ulid as R}from"@lensmcp/core";import{createBridgeServer as z,makePublisher as L,handleClientEnvelope as X}from"@lensmcp/bridge";const D="/@lensmcp/client-runtime",x="\0lensmcp-client-runtime",G="/__lensmcp/watcher-health",F=256,Y=64,Z=new Set(["node_modules",".git","dist","tmp","coverage","build","out","target",".nx",".lensmcp"]);export function resolveExtraWatchRoots(e,t){if(!e)return[];const o=T(t),m=d((u,g)=>{const l=I(g,u);return l!==""&&!l.startsWith("..")&&!l.startsWith(A)&&!/^[A-Za-z]:/.test(l)},"inside"),a=[],v=d(u=>{a.length<Y&&!a.includes(u)&&a.push(u)},"push");for(const u of e.split(K)){const g=u.trim();if(!g)continue;const l=T(g);let b;try{b=U(l)&&J(l).isDirectory()}catch{b=!1}if(b&&!(l===o||m(l,o))){if(m(o,l)){const _=I(l,o).split(A).filter(Boolean);let n=l;for(const i of _){let r;try{r=q(n,{withFileTypes:!0})}catch{r=[]}for(const c of r)!c.isDirectory()||c.name===i||c.name.startsWith(".")||Z.has(c.name)||v(O(n,c.name));n=O(n,i)}continue}v(l)}}return a}p(resolveExtraWatchRoots,"resolveExtraWatchRoots"),d(resolveExtraWatchRoots,"resolveExtraWatchRoots");export function lensmcpVitePlugin(e={},t={}){const o=e.enabled??!0,m=e.wsHost??"127.0.0.1",a=e.injectClient??!0;let v,u;const g=L(t),l=e.aliasValtio??!0,b=e.transformSource??!0,_=e.applyOnBuild??process.env.LENSMCP_VITE_APPLY_ON_BUILD==="1";return{name:"@lensmcp/vite-plugin",apply:d((n,i)=>o&&(i.command==="serve"||_),"apply"),enforce:"pre",wsPort:d(()=>v,"wsPort"),config(){if(!(!o||!l))return{resolve:{alias:[{find:/^valtio$/,replacement:"@lensmcp/valtio-instrumentation"}]}}},async configureServer(n){if(!o)return;u=await z({host:m,port:e.wsPort??0,bus:t.bus,sessionId:t.sessionId}),v=u.port,n.ws.on("vite:error",s=>{g(j(s,t.sessionId))});const i=resolveExtraWatchRoots(process.env.LENSMCP_WATCH_DIRS,n.config?.root??process.cwd());if(i.length>0&&typeof n.watcher?.add=="function")try{n.watcher.add(i),console.log(`[lensmcp] watching ${i.length} extra source root(s) for set changes: ${i.map(s=>I(n.config?.root??process.cwd(),s)||s).join(", ")}`)}catch(s){console.warn(`[lensmcp] could not widen the watcher: ${s?.message??String(s)}`)}let r=0,c=0,S=0;const w=[],h=d((s,f)=>{r=Date.now(),c+=1,S+=1,w.push({sequence:S,kind:s,path:T(f),at:r}),w.length>F&&w.splice(0,w.length-F)},"stampFsSetEvent");n.watcher.on("add",s=>h("add",s)),n.watcher.on("addDir",s=>h("addDir",s)),n.watcher.on("unlink",s=>h("unlink",s)),n.watcher.on("unlinkDir",s=>h("unlinkDir",s)),n.middlewares.use(G,(s,f)=>{f.setHeader("content-type","application/json"),f.setHeader("cache-control","no-store"),f.end(JSON.stringify({schemaVersion:2,ready:!0,sequence:S,lastFsSetEventAt:r,fsSetEvents:c,recentEvents:w,extraWatchRoots:i,now:Date.now()}))})},resolveId(n){return n===D?x:null},load(n){if(n!==x)return null;const i=v??e.wsPort??0;return H({host:m,port:i})},async transform(n,i){if(!o||!b)return null;const r=i.split("?")[0]??i;if(r.includes("/node_modules/")||!/\.[jt]sx$/.test(r))return null;const c=await N(n,r);return c?{code:c.code,map:c.map}:null},transformIndexHtml(){if(!(!a||!o))return[{tag:"script",attrs:{type:"module",src:D},injectTo:"head-prepend"}]},handleHotUpdate(n){if(!o)return;const i=n.modules.map(r=>r.file??r.id??null).filter(r=>!!r);g({id:R(),sessionId:t.sessionId??"pending",timestamp:Date.now(),source:"vite",category:"build",severity:"info",context:{sessionId:t.sessionId??"pending"},fingerprint:C({kind:"hmr",identity:n.file}),title:`HMR ${n.file}`,location:{file:n.file},relatedFiles:i,raw:{kind:"hmr",file:n.file}})},generateBundle(n,i){if(!o)return;const r=[];let c=0;for(const w of Object.values(i)){const h=w,s=h.fileName;let f;if(h.type==="chunk")f=(h.code??"").length;else{const y=h.source;f=typeof y=="string"?y.length:y instanceof Uint8Array?y.byteLength:0}c+=f;const E=[];if(h.type==="chunk"&&h.modules){for(const[y,k]of Object.entries(h.modules)){const W=k.renderedLength??k.originalLength??0;E.push({id:y,sizeBytes:W})}E.sort((y,k)=>k.sizeBytes-y.sizeBytes)}r.push({name:s,sizeBytes:f,modules:E})}const S={timestamp:Date.now(),totalBytes:c,chunks:r};g({id:R(),sessionId:t.sessionId??"pending",timestamp:Date.now(),source:"rollup",category:"build",severity:"info",context:{sessionId:t.sessionId??"pending"},fingerprint:C({kind:"bundle",identity:"report"}),title:`Bundle report: ${r.length} chunks, ${c} bytes`,raw:{kind:"bundle-report",report:S}})},async closeBundle(){u&&(await u.close(),u=void 0)}}}p(lensmcpVitePlugin,"lensmcpVitePlugin"),d(lensmcpVitePlugin,"lensmcpVitePlugin");async function N(e,t){try{const[{transformSync:o},{lensmcpBabelPlugin:m}]=await Promise.all([import("@babel/core"),import("@lensmcp/react-instrumentation")]),a=o(e,{filename:t,babelrc:!1,configFile:!1,sourceMaps:!0,parserOpts:{plugins:["jsx","typescript"]},plugins:[[m,{rootDir:process.cwd()}]],code:!0});return a?.code?{code:a.code,map:a.map}:null}catch(o){return P(t,o),null}}p(N,"J"),d(N,"runLensmcpBabel");const B=new Set;function P(e,t){B.has(e)||(B.add(e),console.warn(`[lensmcp] could not instrument ${e}: ${t?.message??t}. The file still builds, but its renders, effects and hooks will be MISSING from react://renders/*, react://effects/recent and react://hooks/recent.`))}p(P,"K"),d(P,"warnTransformFailed");export function resetTransformFailuresForTests(){B.clear()}p(resetTransformFailuresForTests,"resetTransformFailuresForTests"),d(resetTransformFailuresForTests,"resetTransformFailuresForTests");export function handleClientEnvelope(e,t){X(e,L(t),t.sessionId)}p(handleClientEnvelope,"handleClientEnvelope"),d(handleClientEnvelope,"handleClientEnvelope");function M(e){const t=e?.loc?.file??e?.id;return typeof t!="string"||t.length===0?void 0:{file:t.split("?")[0]||t,...typeof e?.loc?.line=="number"?{line:e.loc.line}:{},...typeof e?.loc?.column=="number"?{column:e.loc.column}:{}}}p(M,"z"),d(M,"errorLocation");function j(e,t){const o=e.err?.message??"Vite error",m=e.err?.stack,a=M(e.err);return{id:R(),sessionId:t??"pending",timestamp:Date.now(),source:"vite",category:"build",severity:"error",context:{sessionId:t??"pending"},fingerprint:C({kind:"vite",identity:e.type??o,...a?{file:a.file}:{}}),title:o,message:m,...a?{location:a}:{},raw:{kind:"build-diagnostic",...a?{file:a.file}:{},...e.err?.plugin?{plugin:e.err.plugin}:{}}}}p(j,"X"),d(j,"viteErrorToEvent");function H(e){return`// @lensmcp/client-runtime (inlined by @lensmcp/vite-plugin)
1
+ "use strict";var X=Object.defineProperty;var p=(e,t)=>X(e,"name",{value:t,configurable:!0});var U=Object.defineProperty,d=p((e,t)=>U(e,"name",{value:t,configurable:!0}),"d");import{existsSync as V,readdirSync as $,statSync as J}from"node:fs";import{delimiter as q,join as F,relative as A,resolve as T,sep as C}from"node:path";import{fingerprint as I,ulid as R}from"@lensmcp/core";import{createBridgeServer as K,makePublisher as B,handleClientEnvelope as G}from"@lensmcp/bridge";const L="/@lensmcp/client-runtime",O="\0lensmcp-client-runtime",Y="/__lensmcp/watcher-health",D=256,z=64,Z=new Set(["node_modules",".git","dist","tmp","coverage","build","out","target",".nx",".lensmcp"]);export function resolveExtraWatchRoots(e,t){if(!e)return[];const o=T(t),m=d((u,g)=>{const l=A(g,u);return l!==""&&!l.startsWith("..")&&!l.startsWith(C)&&!/^[A-Za-z]:/.test(l)},"inside"),a=[],y=d(u=>{a.length<z&&!a.includes(u)&&a.push(u)},"push");for(const u of e.split(q)){const g=u.trim();if(!g)continue;const l=T(g);let b;try{b=V(l)&&J(l).isDirectory()}catch{b=!1}if(b&&!(l===o||m(l,o))){if(m(o,l)){const E=A(l,o).split(C).filter(Boolean);let n=l;for(const i of E){let s;try{s=$(n,{withFileTypes:!0})}catch{s=[]}for(const c of s)!c.isDirectory()||c.name===i||c.name.startsWith(".")||Z.has(c.name)||y(F(n,c.name));n=F(n,i)}continue}y(l)}}return a}p(resolveExtraWatchRoots,"resolveExtraWatchRoots"),d(resolveExtraWatchRoots,"resolveExtraWatchRoots");export function lensmcpVitePlugin(e={},t={}){const o=e.enabled??!0,m=e.wsHost??"127.0.0.1",a=e.injectClient??!0;let y,u;const g=B(t),l=e.aliasValtio??!0,b=e.transformSource??!0,E=e.applyOnBuild??process.env.LENSMCP_VITE_APPLY_ON_BUILD==="1";return{name:"@lensmcp/vite-plugin",apply:d((n,i)=>o&&(i.command==="serve"||E),"apply"),enforce:"pre",wsPort:d(()=>y,"wsPort"),config(){if(!(!o||!l))return{resolve:{alias:[{find:/^valtio$/,replacement:"@lensmcp/valtio-instrumentation"}]}}},async configureServer(n){if(!o)return;u=await K({host:m,port:e.wsPort??0,bus:t.bus,sessionId:t.sessionId}),y=u.port,n.ws.on("vite:error",r=>{g(j(r,t.sessionId))});const i=resolveExtraWatchRoots(process.env.LENSMCP_WATCH_DIRS,n.config?.root??process.cwd());if(i.length>0&&typeof n.watcher?.add=="function")try{n.watcher.add(i),console.log(`[lensmcp] watching ${i.length} extra source root(s) for set changes: ${i.map(r=>A(n.config?.root??process.cwd(),r)||r).join(", ")}`)}catch(r){console.warn(`[lensmcp] could not widen the watcher: ${r?.message??String(r)}`)}let s=0,c=0,S=0;const w=[],h=d((r,f)=>{s=Date.now(),c+=1,S+=1,w.push({sequence:S,kind:r,path:T(f),at:s}),w.length>D&&w.splice(0,w.length-D)},"stampFsSetEvent");n.watcher.on("add",r=>h("add",r)),n.watcher.on("addDir",r=>h("addDir",r)),n.watcher.on("unlink",r=>h("unlink",r)),n.watcher.on("unlinkDir",r=>h("unlinkDir",r)),n.middlewares.use(Y,(r,f)=>{f.setHeader("content-type","application/json"),f.setHeader("cache-control","no-store"),f.end(JSON.stringify({schemaVersion:2,ready:!0,sequence:S,lastFsSetEventAt:s,fsSetEvents:c,recentEvents:w,extraWatchRoots:i,now:Date.now()}))})},resolveId(n){return n===L?O:null},load(n){if(n!==O)return null;const i=y??e.wsPort??0;return H({host:m,port:i})},async transform(n,i){if(!o||!b)return null;const s=i.split("?")[0]??i;if(s.includes("/node_modules/")||!/\.[jt]sx$/.test(s))return null;const c=await N(n,s);return c?{code:c.code,map:c.map}:null},transformIndexHtml(){if(!(!a||!o))return[{tag:"script",attrs:{type:"module",src:L},injectTo:"head-prepend"}]},handleHotUpdate(n){if(!o)return;const i=n.modules.map(s=>s.file??s.id??null).filter(s=>!!s);g({id:R(),sessionId:t.sessionId??"pending",timestamp:Date.now(),source:"vite",category:"build",severity:"info",context:{sessionId:t.sessionId??"pending"},fingerprint:I({kind:"hmr",identity:n.file}),title:`HMR ${n.file}`,location:{file:n.file},relatedFiles:i,raw:{kind:"hmr",file:n.file}})},generateBundle(n,i){if(!o)return;const s=[];let c=0;for(const w of Object.values(i)){const h=w,r=h.fileName;let f;if(h.type==="chunk")f=(h.code??"").length;else{const v=h.source;f=typeof v=="string"?v.length:v instanceof Uint8Array?v.byteLength:0}c+=f;const k=[];if(h.type==="chunk"&&h.modules){for(const[v,_]of Object.entries(h.modules)){const W=_.renderedLength??_.originalLength??0;k.push({id:v,sizeBytes:W})}k.sort((v,_)=>_.sizeBytes-v.sizeBytes)}s.push({name:r,sizeBytes:f,modules:k})}const S={timestamp:Date.now(),totalBytes:c,chunks:s};g({id:R(),sessionId:t.sessionId??"pending",timestamp:Date.now(),source:"rollup",category:"build",severity:"info",context:{sessionId:t.sessionId??"pending"},fingerprint:I({kind:"bundle",identity:"report"}),title:`Bundle report: ${s.length} chunks, ${c} bytes`,raw:{kind:"bundle-report",report:S}})},async closeBundle(){u&&(await u.close(),u=void 0)}}}p(lensmcpVitePlugin,"lensmcpVitePlugin"),d(lensmcpVitePlugin,"lensmcpVitePlugin");async function N(e,t){try{const[{transformSync:o},{lensmcpBabelPlugin:m}]=await Promise.all([import("@babel/core"),import("@lensmcp/react-instrumentation")]),a=o(e,{filename:t,babelrc:!1,configFile:!1,sourceMaps:!0,parserOpts:{plugins:["jsx","typescript"]},plugins:[[m,{rootDir:process.cwd()}]],code:!0});return a?.code?{code:a.code,map:a.map}:null}catch(o){return x(t,o),null}}p(N,"q"),d(N,"runLensmcpBabel");const M=new Set;function x(e,t){M.has(e)||(M.add(e),console.warn(`[lensmcp] could not instrument ${e}: ${t?.message??t}. The file still builds, but its renders, effects and hooks will be MISSING from react://renders/*, react://effects/recent and react://hooks/recent.`))}p(x,"J"),d(x,"warnTransformFailed");export function resetTransformFailuresForTests(){M.clear()}p(resetTransformFailuresForTests,"resetTransformFailuresForTests"),d(resetTransformFailuresForTests,"resetTransformFailuresForTests");export function handleClientEnvelope(e,t){G(e,B(t),t.sessionId)}p(handleClientEnvelope,"handleClientEnvelope"),d(handleClientEnvelope,"handleClientEnvelope");function P(e){const t=e?.loc?.file??e?.id;return typeof t!="string"||t.length===0?void 0:{file:t.split("?")[0]||t,...typeof e?.loc?.line=="number"?{line:e.loc.line}:{},...typeof e?.loc?.column=="number"?{column:e.loc.column}:{}}}p(P,"K"),d(P,"errorLocation");function j(e,t){const o=e.err?.message??"Vite error",m=e.err?.stack,a=P(e.err);return{id:R(),sessionId:t??"pending",timestamp:Date.now(),source:"vite",category:"build",severity:"error",context:{sessionId:t??"pending"},fingerprint:I({kind:"vite",identity:e.type??o,...a?{file:a.file}:{}}),title:o,message:m,...a?{location:a}:{},raw:{kind:"build-diagnostic",...a?{file:a.file}:{},...e.err?.plugin?{plugin:e.err.plugin}:{}}}}p(j,"G"),d(j,"viteErrorToEvent");function H(e){return`// @lensmcp/client-runtime (inlined by @lensmcp/vite-plugin)
2
2
  (() => {
3
3
  if (typeof window === 'undefined') return;
4
4
  if (window.__LENSMCP_CLIENT__) return;
@@ -65,6 +65,22 @@
65
65
  // post-switch long tasks. Same events, same order, same timestamps; only the transport moves.
66
66
  let batch = [];
67
67
  let flushScheduled = false;
68
+ // One macrotask's batch goes out in FRAMES, never as one frame of whatever the page produced.
69
+ //
70
+ // The bridge accepts at most 1 MiB per frame and reads at most 1024 envelopes out of one batch,
71
+ // so a bigger frame was never worth more: past 1024 the surplus was dropped, and past 1 MiB the
72
+ // WHOLE frame was refused with a 1009 close. Producers that clone whatever the app handed them can
73
+ // reach those numbers in one macrotask (a console envelope deep-clones its args with no cap), so the
74
+ // transport has to bound itself rather than trust them. Chunking at 200 (the same size the reconnect
75
+ // drain below already uses) keeps every frame comfortably inside both caps, which means MORE events
76
+ // survive a storm than the single-frame version delivered, not fewer.
77
+ //
78
+ // MAX_FRAMES_PER_FLUSH is the second bound, and it is the one that matters for the page: a storm
79
+ // must not become thousands of sends on the main thread. What is dropped is announced rather than
80
+ // hidden \u2014 the payload states its own error bars, so a reader knows the storm was bigger than the
81
+ // record. (Server-side caps: @lensmcp/bridge MAX_FRAME_BYTES / MAX_BATCH_EVENTS.)
82
+ const FRAME_EVENTS = 200;
83
+ const MAX_FRAMES_PER_FLUSH = 8;
68
84
  function flushBatch() {
69
85
  flushScheduled = false;
70
86
  if (!batch.length) return;
@@ -72,7 +88,16 @@
72
88
  batch = [];
73
89
  if (ws && ws.readyState === 1) {
74
90
  try {
75
- ws.send(JSON.stringify(events.length === 1 ? events[0] : { kind: 'batch', at: Date.now(), tabId: TAB_ID, events }));
91
+ const cap = FRAME_EVENTS * MAX_FRAMES_PER_FLUSH;
92
+ const dropped = events.length > cap ? events.length - cap : 0;
93
+ for (let i = 0; i < events.length && i < cap; i += FRAME_EVENTS) {
94
+ const chunk = events.slice(i, i + FRAME_EVENTS);
95
+ ws.send(JSON.stringify(chunk.length === 1 ? chunk[0] : { kind: 'batch', at: Date.now(), tabId: TAB_ID, events: chunk }));
96
+ }
97
+ if (dropped > 0) {
98
+ ws.send(JSON.stringify({ kind: 'console', level: 'warn', at: Date.now(), tabId: TAB_ID,
99
+ args: ['[lensmcp] event flood: ' + dropped + ' browser event(s) dropped in one frame budget \u2014 the counts below undercount.'] }));
100
+ }
76
101
  return;
77
102
  } catch (e) { /* fall through to queue */ }
78
103
  }
@@ -243,11 +268,49 @@
243
268
  history.replaceState = function(...args) { const from = location.href; const r = origReplace.apply(this, args); notify(from); return r; };
244
269
  window.addEventListener('popstate', () => notify(undefined));
245
270
 
246
- function safe(v) {
247
- if (v === null) return null;
271
+ // BOUNDED clone for console args \u2014 the last unbounded producer in this runtime.
272
+ //
273
+ // This was \`JSON.parse(JSON.stringify(v))\`: it allocates the whole payload TWICE and keeps all of
274
+ // it, so one \`console.log(bigResponse)\` became one enormous envelope. Every other producer here
275
+ // bounds itself (stacks at MAX_STACK, renders capped upstream at 25/commit), and the shared
276
+ // \`boundedClone\` in @lensmcp/protocol-types exists precisely to replace this idiom \u2014 but this file
277
+ // is injected into the page as a standalone script with no module graph, so the walk is repeated
278
+ // here under the SAME limits rather than imported. Keep the two in step.
279
+ //
280
+ // It is also strictly more robust than what it replaces: the depth ceiling doubles as a cycle
281
+ // guard, so a self-referential object is now clamped instead of throwing and collapsing to
282
+ // \`String(v)\` ("[object Object]").
283
+ const SAFE_MAX_BYTES = 32 * 1024; // DEFAULT_RAW_BYTE_LIMIT
284
+ const SAFE_MAX_STRING = 4 * 1024; // DEFAULT_MAX_STRING_BYTES
285
+ const SAFE_MAX_ITEMS = 64; // DEFAULT_MAX_ARRAY_ITEMS
286
+ const SAFE_MAX_DEPTH = 8;
287
+ function clipTo(s, max) {
288
+ return s.length <= max ? s : s.slice(0, max) + '\u2026[lensmcp truncated: ' + (s.length - max) + ' more chars]';
289
+ }
290
+ function safeWalk(v, depth, budget) {
291
+ if (v === null || v === undefined) return v === undefined ? undefined : null;
248
292
  const t = typeof v;
249
- if (t === 'string' || t === 'number' || t === 'boolean') return v;
250
- try { return JSON.parse(JSON.stringify(v)); } catch { return String(v); }
293
+ if (t === 'number' || t === 'boolean') { budget.left -= 8; return v; }
294
+ if (t === 'string') { const s = clipTo(v, SAFE_MAX_STRING); budget.left -= s.length; return s; }
295
+ if (t !== 'object') { const s = clipTo(String(v), SAFE_MAX_STRING); budget.left -= s.length; return s; } // function/symbol/bigint
296
+ if (depth >= SAFE_MAX_DEPTH || budget.left <= 0) return '[lensmcp: truncated]';
297
+ if (Array.isArray(v)) {
298
+ const out = [];
299
+ for (let i = 0; i < v.length && i < SAFE_MAX_ITEMS && budget.left > 0; i += 1) out.push(safeWalk(v[i], depth + 1, budget));
300
+ if (v.length > out.length) out.push('\u2026[lensmcp truncated: ' + (v.length - out.length) + ' more items]');
301
+ return out;
302
+ }
303
+ const out = {};
304
+ let keys;
305
+ try { keys = Object.keys(v); } catch (e) { return '[lensmcp: unreadable]'; }
306
+ for (let i = 0; i < keys.length && budget.left > 0; i += 1) {
307
+ budget.left -= keys[i].length + 4;
308
+ try { out[keys[i]] = safeWalk(v[keys[i]], depth + 1, budget); } catch (e) { out[keys[i]] = '[lensmcp: threw on read]'; }
309
+ }
310
+ return out;
311
+ }
312
+ function safe(v) {
313
+ try { return safeWalk(v, 0, { left: SAFE_MAX_BYTES }); } catch (e) { return String(v); }
251
314
  }
252
315
  })();
253
- `}p(H,"G"),d(H,"buildInlineClientRuntime");
316
+ `}p(H,"Y"),d(H,"buildInlineClientRuntime");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/vite-plugin",
3
- "version": "1.22.2",
3
+ "version": "1.22.4",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "module": "./index.js",
@@ -15,11 +15,11 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@babel/core": "^7.0.0",
18
- "@lensmcp/bridge": "1.22.2",
19
- "@lensmcp/core": "1.22.2",
20
- "@lensmcp/protocol-types": "1.22.2",
21
- "@lensmcp/react-instrumentation": "1.22.2",
22
- "@lensmcp/valtio-instrumentation": "1.22.2",
18
+ "@lensmcp/bridge": "1.22.4",
19
+ "@lensmcp/core": "1.22.4",
20
+ "@lensmcp/protocol-types": "1.22.4",
21
+ "@lensmcp/react-instrumentation": "1.22.4",
22
+ "@lensmcp/valtio-instrumentation": "1.22.4",
23
23
  "tslib": "^2.3.0"
24
24
  },
25
25
  "peerDependencies": {