@lensmcp/vite-plugin 1.22.3 → 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.
- package/lib/event-mappers.js +2 -2
- package/lib/plugin.js +70 -7
- package/package.json +6 -6
package/lib/event-mappers.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`).slice(0,2);for(const
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
247
|
-
|
|
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 === '
|
|
250
|
-
|
|
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,"
|
|
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.
|
|
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.
|
|
19
|
-
"@lensmcp/core": "1.22.
|
|
20
|
-
"@lensmcp/protocol-types": "1.22.
|
|
21
|
-
"@lensmcp/react-instrumentation": "1.22.
|
|
22
|
-
"@lensmcp/valtio-instrumentation": "1.22.
|
|
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": {
|