@lensmcp/bridge 1.25.14 → 1.25.17

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/env-sink.js CHANGED
@@ -1,3 +1,3 @@
1
- "use strict";var _=Object.defineProperty;var f=(t,n)=>_(t,"name",{value:n,configurable:!0});var b=Object.defineProperty,r=f((t,n)=>b(t,"name",{value:n,configurable:!0}),"r");import{connect as P}from"node:net";import{createSocket as A}from"node:dgram";import{appendFileSync as M,closeSync as T,openSync as F,renameSync as L,statSync as O,unlinkSync as x}from"node:fs";import{busCapsFromEnv as R,createBusRotator as I}from"@lensmcp/core/bus-rotation";import{ENV_SINK_CLOSE_GRACE_MS as B}from"./constants.js";const D=R(),d=(()=>{const t=process.env.LENSMCP_EVENT_MAX_EPS;if(t==="off")return 1/0;const n=Number(t);return t!==void 0&&t!==""&&Number.isFinite(n)?n<=0?1/0:n:5})(),y=Math.max(30,d===1/0?0:d*4),S=new Map;function k(t){if(d===1/0)return 0;const n=Date.now();let e=S.get(t);if(!e){if(S.size>=2048){for(const[s,o]of S)n-o.lastSeenAt>6e4&&S.delete(s);S.size>=2048&&S.clear()}e={tokens:y,lastRefillAt:n,suppressed:0,lastSeenAt:n},S.set(t,e)}if(e.lastSeenAt=n,e.tokens=Math.min(y,e.tokens+(n-e.lastRefillAt)/1e3*d),e.lastRefillAt=n,e.tokens>=1){e.tokens-=1;const s=e.suppressed;return e.suppressed=0,s}return e.suppressed+=1,-1}f(k,"B"),r(k,"floodAdmit");let u,m;export function resolveEnvSink(){if(u!==void 0)return u;const t=process.env.LENSMCP_EVENT_FILE;if(t){const s=I(t,{...D,fs:{statSync:O,renameSync:L,unlinkSync:x,openSync:F,closeSync:T}});return u=r(o=>{try{const c=k(o.fingerprint);if(c<0)return;const i=JSON.stringify(c>0?{...o,raw:{...o.raw??{},floodSuppressed:c}}:o)+`
2
- `;s(i.length),M(t,i)}catch{}},"cachedEnvSink"),u}const n=process.env.LENSMCP_UDS;if(n){const s=v(n);return u=s.write,m=s.close,u}const e=process.env.LENSMCP_IPC_SOCKET;if(e){const[s,o]=e.split(":"),c=Number(o);if(s&&Number.isFinite(c)){const i=w(s,c);return u=i.write,m=i.close,u}}return u=null,null}f(resolveEnvSink,"resolveEnvSink"),r(resolveEnvSink,"resolveEnvSink");export function resetEnvSinkCache(){u=void 0,m=void 0}f(resetEnvSinkCache,"resetEnvSinkCache"),r(resetEnvSinkCache,"resetEnvSinkCache");export function closeEnvSink(t=B){const n=m;return resetEnvSinkCache(),n?n(t):Promise.resolve()}f(closeEnvSink,"closeEnvSink"),r(closeEnvSink,"closeEnvSink");export function udsEnvSink(t){return v(t).write}f(udsEnvSink,"udsEnvSink"),r(udsEnvSink,"udsEnvSink");function v(t){const n=[];let e=null,s=!1,o,c=!1;const i=r(()=>{if(!(!e||!e.writable))for(;n.length>0;)e.write(n.shift())},"flush"),a=r(()=>{if(s||e)return;s=!0;const l=P(t);l.on("connect",()=>{s=!1,e=l,i(),o?.(!0)}),l.on("drain",i),l.on("error",()=>{s=!1,e=null,o?.(!1)}),l.on("close",()=>{e=null}),l.unref()},"open");return a(),{write:r(l=>{if(!c){for(n.push(JSON.stringify(l)+`
3
- `);n.length>1e4;)n.shift();if(e&&e.writable){i();return}if(e){try{e.destroy()}catch{}e=null}a()}},"write"),close:r(l=>new Promise(N=>{c=!0;let E=!1;const p=r(()=>{if(!E){E=!0,clearTimeout(g),o=void 0,n.length=0;try{e?.destroy()}catch{}e=null,N()}},"finish"),g=setTimeout(p,l),h=r(()=>{if(!e)return p();i(),e.end(p)},"endWhenFlushed");e?.writable?h():n.length===0?p():(o=r(C=>C?h():p(),"onConnectSettled"),a())}),"close")}}f(v,"y"),r(v,"openUdsSink");function w(t,n){const e=A("udp4");e.unref();let s=0,o;return{write:r(c=>{try{const i=Buffer.from(JSON.stringify(c));e.send(i,n,t,()=>{s-=1,s===0&&o?.()}),s+=1}catch{}},"write"),close:r(c=>new Promise(i=>{const a=r(()=>{clearTimeout(l),o=void 0;try{e.close()}catch{}i()},"finish"),l=setTimeout(a,c);s===0?a():o=a}),"close")}}f(w,"D"),r(w,"openUdpSink");
1
+ "use strict";var _=Object.defineProperty;var f=(t,n)=>_(t,"name",{value:n,configurable:!0});var P=Object.defineProperty,a=f((t,n)=>P(t,"name",{value:n,configurable:!0}),"f"),A=Object.defineProperty,s=a((t,n)=>A(t,"name",{value:n,configurable:!0}),"r");import{connect as M}from"node:net";import{createSocket as O}from"node:dgram";import{appendFileSync as T,closeSync as F,openSync as L,renameSync as x,statSync as R,unlinkSync as B}from"node:fs";import{busCapsFromEnv as D,createBusRotator as I}from"@lensmcp/core/bus-rotation";import{ENV_SINK_CLOSE_GRACE_MS as J}from"./constants.js";const U=D(),v=(()=>{const t=process.env.LENSMCP_EVENT_MAX_EPS;if(t==="off")return 1/0;const n=Number(t);return t!==void 0&&t!==""&&Number.isFinite(n)?n<=0?1/0:n:5})(),N=Math.max(30,v===1/0?0:v*4),p=new Map;function h(t){if(v===1/0)return 0;const n=Date.now();let e=p.get(t);if(!e){if(p.size>=2048){for(const[r,o]of p)n-o.lastSeenAt>6e4&&p.delete(r);p.size>=2048&&p.clear()}e={tokens:N,lastRefillAt:n,suppressed:0,lastSeenAt:n},p.set(t,e)}if(e.lastSeenAt=n,e.tokens=Math.min(N,e.tokens+(n-e.lastRefillAt)/1e3*v),e.lastRefillAt=n,e.tokens>=1){e.tokens-=1;const r=e.suppressed;return e.suppressed=0,r}return e.suppressed+=1,-1}f(h,"k"),a(h,"B"),s(h,"floodAdmit");let u,m;export function resolveEnvSink(){if(u!==void 0)return u;const t=process.env.LENSMCP_EVENT_FILE;if(t){const r=I(t,{...U,fs:{statSync:R,renameSync:x,unlinkSync:B,openSync:L,closeSync:F}});return u=s(o=>{try{const c=h(o.fingerprint);if(c<0)return;const i=JSON.stringify(c>0?{...o,raw:{...o.raw??{},floodSuppressed:c}}:o)+`
2
+ `;r(i.length),T(t,i)}catch{}},"cachedEnvSink"),u}const n=process.env.LENSMCP_UDS;if(n){const r=E(n);return u=r.write,m=r.close,u}const e=process.env.LENSMCP_IPC_SOCKET;if(e){const[r,o]=e.split(":"),c=Number(o);if(r&&Number.isFinite(c)){const i=y(r,c);return u=i.write,m=i.close,u}}return u=null,null}f(resolveEnvSink,"resolveEnvSink"),a(resolveEnvSink,"resolveEnvSink"),s(resolveEnvSink,"resolveEnvSink");export function resetEnvSinkCache(){u=void 0,m=void 0}f(resetEnvSinkCache,"resetEnvSinkCache"),a(resetEnvSinkCache,"resetEnvSinkCache"),s(resetEnvSinkCache,"resetEnvSinkCache");export function closeEnvSink(t=J){const n=m;return resetEnvSinkCache(),n?n(t):Promise.resolve()}f(closeEnvSink,"closeEnvSink"),a(closeEnvSink,"closeEnvSink"),s(closeEnvSink,"closeEnvSink");export function udsEnvSink(t){return E(t).write}f(udsEnvSink,"udsEnvSink"),a(udsEnvSink,"udsEnvSink"),s(udsEnvSink,"udsEnvSink");function E(t){const n=[];let e=null,r=!1,o,c=!1;const i=s(()=>{if(!(!e||!e.writable))for(;n.length>0;)e.write(n.shift())},"flush"),S=s(()=>{if(r||e)return;r=!0;const l=M(t);l.on("connect",()=>{r=!1,e=l,i(),o?.(!0)}),l.on("drain",i),l.on("error",()=>{r=!1,e=null,o?.(!1)}),l.on("close",()=>{e=null}),l.unref()},"open");return S(),{write:s(l=>{if(!c){for(n.push(JSON.stringify(l)+`
3
+ `);n.length>1e4;)n.shift();if(e&&e.writable){i();return}if(e){try{e.destroy()}catch{}e=null}S()}},"write"),close:s(l=>new Promise(b=>{c=!0;let k=!1;const d=s(()=>{if(!k){k=!0,clearTimeout(g),o=void 0,n.length=0;try{e?.destroy()}catch{}e=null,b()}},"finish"),g=setTimeout(d,l),w=s(()=>{if(!e)return d();i(),e.end(d)},"endWhenFlushed");e?.writable?w():n.length===0?d():(o=s(C=>C?w():d(),"onConnectSettled"),S())}),"close")}}f(E,"v"),a(E,"y"),s(E,"openUdsSink");function y(t,n){const e=O("udp4");e.unref();let r=0,o;return{write:s(c=>{try{const i=Buffer.from(JSON.stringify(c));e.send(i,n,t,()=>{r-=1,r===0&&o?.()}),r+=1}catch{}},"write"),close:s(c=>new Promise(i=>{const S=s(()=>{clearTimeout(l),o=void 0;try{e.close()}catch{}i()},"finish"),l=setTimeout(S,c);r===0?S():o=S}),"close")}}f(y,"w"),a(y,"D"),s(y,"openUdpSink");
@@ -1 +1 @@
1
- "use strict";var d=Object.defineProperty;var a=(t,e)=>d(t,"name",{value:e,configurable:!0});var g=Object.defineProperty,s=a((t,e)=>g(t,"name",{value:e,configurable:!0}),"r");import{BaseEventSchema as f,TraceContextSchema as l}from"@lensmcp/protocol-types";const r=s(t=>e=>t.safeParse(e).success,"conforms"),n=s(t=>typeof t=="string","isString"),p=s((...t)=>e=>typeof e=="string"&&t.includes(e),"oneOf"),o=f.shape,m={at:r(o.timestamp),tabId:r(l.shape.tabId)},v={error:{},"resource-error":{tagName:n},unhandledrejection:{reason:n},console:{level:p("log","info","warn","error","debug"),args:Array.isArray},fetch:{method:n,url:n},route:{url:n},ready:{userAgent:n,url:n},hmr:{event:p("full-reload","update","invalidate","ws-disconnect","ws-connect","ws-failed")},gone:{},publish:{source:r(o.source),category:r(o.category),severity:r(o.severity.optional()),title:r(o.title),message:r(o.message),fingerprint:r(o.fingerprint.optional()),context:r(l.partial().optional())}},y=new Map(Object.entries(v));export function conformsToEnvelopeContract(t){const e=t,i=e.kind,c=typeof i=="string"?y.get(i):void 0;return c?u(e,m)&&u(e,c):!1}a(conformsToEnvelopeContract,"conformsToEnvelopeContract"),s(conformsToEnvelopeContract,"conformsToEnvelopeContract");export function asBaseEvent(t){const e=f.safeParse(t);return e.success?e.data:void 0}a(asBaseEvent,"asBaseEvent"),s(asBaseEvent,"asBaseEvent");function u(t,e){for(const[i,c]of Object.entries(e))if(!c(t[i]))return!1;return!0}a(u,"l"),s(u,"satisfies");
1
+ "use strict";var g=Object.defineProperty;var s=(r,e)=>g(r,"name",{value:e,configurable:!0});var v=Object.defineProperty,l=s((r,e)=>v(r,"name",{value:e,configurable:!0}),"a"),m=Object.defineProperty,a=l((r,e)=>m(r,"name",{value:e,configurable:!0}),"r");import{BaseEventSchema as u,TraceContextSchema as p}from"@lensmcp/protocol-types";const t=a(r=>e=>r.safeParse(e).success,"conforms"),n=a(r=>typeof r=="string","isString"),d=a((...r)=>e=>typeof e=="string"&&r.includes(e),"oneOf"),o=u.shape,y={at:t(o.timestamp),tabId:t(p.shape.tabId)},b={error:{},"resource-error":{tagName:n},unhandledrejection:{reason:n},console:{level:d("log","info","warn","error","debug"),args:Array.isArray},fetch:{method:n,url:n},route:{url:n},ready:{userAgent:n,url:n},hmr:{event:d("full-reload","update","invalidate","ws-disconnect","ws-connect","ws-failed")},gone:{},publish:{source:t(o.source),category:t(o.category),severity:t(o.severity.optional()),title:t(o.title),message:t(o.message),fingerprint:t(o.fingerprint.optional()),context:t(p.partial().optional())}},h=new Map(Object.entries(b));export function conformsToEnvelopeContract(r){const e=r,i=e.kind,c=typeof i=="string"?h.get(i):void 0;return c?f(e,y)&&f(e,c):!1}s(conformsToEnvelopeContract,"conformsToEnvelopeContract"),l(conformsToEnvelopeContract,"conformsToEnvelopeContract"),a(conformsToEnvelopeContract,"conformsToEnvelopeContract");export function asBaseEvent(r){const e=u.safeParse(r);return e.success?e.data:void 0}s(asBaseEvent,"asBaseEvent"),l(asBaseEvent,"asBaseEvent"),a(asBaseEvent,"asBaseEvent");function f(r,e){for(const[i,c]of Object.entries(e))if(!c(r[i]))return!1;return!0}s(f,"u"),l(f,"l"),a(f,"satisfies");
@@ -1,3 +1,3 @@
1
- "use strict";var I=Object.defineProperty;var c=(e,n)=>I(e,"name",{value:n,configurable:!0});var x=Object.defineProperty,d=c((e,n)=>x(e,"name",{value:n,configurable:!0}),"u");import{fingerprint as o,ulid as a}from"@lensmcp/core";import{redactDeep as y,redactText as m,redactUrl as g,safeText as u,safeTitle as l}from"./redact.js";const b="pending";export function envelopeToEvent(e,n=b){const s=e.tabId?{tabId:e.tabId}:{};switch(e.kind){case"error":{const r=!e.stack&&!e.source&&(!e.message||e.message==="Script error."),i=e.name&&e.name!=="Error"?`${e.name}: `:"",t=r?"Uncaught cross-origin script error (no detail available \u2014 add crossorigin to the script tag)":e.message?`${i}${e.message}`:`Uncaught ${e.name??"error"}`;return{id:a(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"error",context:{sessionId:n,...s},fingerprint:o({kind:"runtime",identity:`error:${h(e.stack)}`,file:e.source,detail:e.message??e.name}),title:l(t),message:u(e.stack??e.message),location:e.source?{file:g(e.source),line:e.lineno,column:e.colno}:void 0,raw:{...e,...e.message?{message:m(e.message)}:{},...e.stack?{stack:u(e.stack)}:{},...e.source?{source:g(e.source)}:{}}}}case"resource-error":{const r=e.url?g(e.url):void 0;return{id:a(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"error",context:{sessionId:n,...s},fingerprint:o({kind:"runtime",identity:`resource-error:${e.tagName}:${v(e.url??"")}`}),title:l(`Failed to load <${e.tagName}>${r?` ${r}`:""}`),...r?{relatedUrls:[r]}:{},raw:{...e,...r?{url:r}:{}}}}case"unhandledrejection":{const r=e.name&&e.name!=="Error"?`${e.name}: `:"",i=e.reason.split(`
2
- `)[0]??e.reason;return{id:a(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"error",context:{sessionId:n,...s},fingerprint:o({kind:"runtime",identity:`unhandledrejection:${e.reason.slice(0,80)}`}),title:l(`Unhandled promise rejection: ${r}${i}`),message:u(e.stack??e.reason),raw:{...e,reason:m(e.reason),...e.stack?{stack:u(e.stack)}:{}}}}case"console":{const r=e.level==="error"?"error":e.level==="warn"?"warning":"info",i=y(e.args),t=i.map(k).join(" ");return{id:a(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:r,context:{sessionId:n,...s},fingerprint:o({kind:"runtime",identity:`console:${e.level}:${t.slice(0,80)}`}),title:`console.${e.level}`,message:u(t),raw:{...e,args:i}}}case"fetch":{const r=e.error!==void 0||e.status!==void 0&&e.status>=400,i=g(e.url),t=e.status!==void 0?` \u2192 ${e.status}${e.statusText?` ${e.statusText}`:""}`:"";return{id:a(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"network",severity:r?"error":"info",context:{sessionId:n,...s},fingerprint:o({kind:"network",identity:`${e.method}:${v(e.url)}:${e.status??"err"}`}),title:l(`${e.method} ${i}${t}`),message:u(e.error),relatedUrls:[i],raw:{...e,url:i}}}case"route":return{id:a(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"info",context:{sessionId:n,url:e.url,...s},fingerprint:o({kind:"runtime",identity:`route:${e.url}`}),title:`Route \u2192 ${e.url}`,raw:e};case"ready":return{id:a(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"info",context:{sessionId:n,url:e.url,...s},fingerprint:o({kind:"runtime",identity:"client-ready"}),title:"Client runtime ready",message:e.reloadCause?`${e.userAgent} \u2014 after a Vite full reload${e.reloadCause.triggeredBy?` triggered by ${u(m(e.reloadCause.triggeredBy))}`:""}`:e.userAgent,raw:e};case"hmr":{const r=e.triggeredBy?m(e.triggeredBy):void 0,i=e.path?m(e.path):void 0,t=e.event==="full-reload"?`full-reload:${r??i??"?"}`:e.event==="invalidate"?`invalidate:${i??"?"}`:e.event,p=e.event==="full-reload"?`Vite full reload${r?` \u2014 ${l(r)} could not hot-update`:i?` \u2014 ${l(i)}`:""}`:e.event==="update"?`Vite HMR update (${e.count??e.updates?.length??0} module${(e.count??e.updates?.length??0)===1?"":"s"})`:e.event==="invalidate"?`Vite HMR invalidate \u2014 ${l(i??"?")}`:e.event==="ws-disconnect"?"Vite HMR socket lost \u2014 the page will poll and reload":e.event==="ws-failed"?e.recovering?"Vite HMR socket failed to connect \u2014 the page reloads once to get one":"Vite HMR socket failed to connect \u2014 this page gets no hot updates until it is reloaded":"Vite HMR socket connected";return{id:a(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"build",severity:e.event==="full-reload"||e.event==="ws-disconnect"||e.event==="ws-failed"?"warning":"info",context:{sessionId:n,...s},fingerprint:o({kind:"hmr",identity:t}),title:p,...e.message?{message:u(m(e.message))}:{},...r||i?{location:{file:r??i??""}}:{},...e.updates?.length?{relatedFiles:e.updates.map(f=>m(f))}:{},raw:{...e,...r?{triggeredBy:r}:{},...i?{path:i}:{}}}}case"gone":return{id:a(),sessionId:n,timestamp:e.at,source:"client-runtime",category:"runtime",severity:"info",context:{sessionId:n,...s},fingerprint:o({kind:"runtime",identity:"client-gone"}),title:"Client runtime gone",raw:e};case"publish":{if(!w(e.source))return;const r=$(e.category,e.raw),i=r&&r.status!==void 0&&r.status>=400?"error":e.severity??"info",t=d(f=>r&&r.url!==r.redactedUrl?f.split(r.url).join(r.redactedUrl):f,"scrub"),p=t(e.title);return{id:a(),sessionId:n,timestamp:e.at,source:e.source,category:e.category,severity:i,context:{...s,...e.context??{},sessionId:n},fingerprint:e.fingerprint?t(e.fingerprint):o({kind:"publish",identity:p}),title:l(p),message:u(e.message),...r?{relatedUrls:[r.redactedUrl]}:{},raw:r?{...y(e.raw),url:r.redactedUrl}:y(e.raw)}}}}c(envelopeToEvent,"envelopeToEvent"),d(envelopeToEvent,"envelopeToEvent");function $(e,n){if(e!=="network"||!n||typeof n!="object")return;const s=n;if(!(typeof s.url!="string"||s.url.length===0))return{url:s.url,redactedUrl:g(s.url),...typeof s.status=="number"?{status:s.status}:{}}}c($,"k"),d($,"networkDetails");function h(e){if(!e)return"unknown";const n=e.split(`
3
- `).slice(0,2);for(const s of n){const r=s.match(/at\s+(\S+)/);if(r&&r[1])return r[1]}return"unknown"}c(h,"w"),d(h,"normaliseStackTopFrame");function v(e){try{return`${new URL(e,"http://x").pathname}`}catch{return e}}c(v,"y"),d(v,"normaliseUrl");function k(e){if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}c(k,"x"),d(k,"stringify");const U=new Set(["react","valtio","memory","client-runtime"]);function w(e){return typeof e=="string"&&U.has(e)}c(w,"b"),d(w,"isBrowserPublishableSource");
1
+ "use strict";var b=Object.defineProperty;var c=(t,r)=>b(t,"name",{value:r,configurable:!0});var x=Object.defineProperty,d=c((t,r)=>x(t,"name",{value:r,configurable:!0}),"c"),U=Object.defineProperty,m=d((t,r)=>U(t,"name",{value:r,configurable:!0}),"u");import{fingerprint as a,ulid as o}from"@lensmcp/core";import{redactDeep as $,redactText as g,redactUrl as p,safeText as u,safeTitle as l}from"./redact.js";const T="pending";export function envelopeToEvent(t,r=T){const s=t.tabId?{tabId:t.tabId}:{};switch(t.kind){case"error":{const e=!t.stack&&!t.source&&(!t.message||t.message==="Script error."),i=t.name&&t.name!=="Error"?`${t.name}: `:"",n=e?"Uncaught cross-origin script error (no detail available \u2014 add crossorigin to the script tag)":t.message?`${i}${t.message}`:`Uncaught ${t.name??"error"}`;return{id:o(),sessionId:r,timestamp:t.at,source:"client-runtime",category:"runtime",severity:"error",context:{sessionId:r,...s},fingerprint:a({kind:"runtime",identity:`error:${k(t.stack)}`,file:t.source,detail:t.message??t.name}),title:l(n),message:u(t.stack??t.message),location:t.source?{file:p(t.source),line:t.lineno,column:t.colno}:void 0,raw:{...t,...t.message?{message:g(t.message)}:{},...t.stack?{stack:u(t.stack)}:{},...t.source?{source:p(t.source)}:{}}}}case"resource-error":{const e=t.url?p(t.url):void 0;return{id:o(),sessionId:r,timestamp:t.at,source:"client-runtime",category:"runtime",severity:"error",context:{sessionId:r,...s},fingerprint:a({kind:"runtime",identity:`resource-error:${t.tagName}:${v(t.url??"")}`}),title:l(`Failed to load <${t.tagName}>${e?` ${e}`:""}`),...e?{relatedUrls:[e]}:{},raw:{...t,...e?{url:e}:{}}}}case"unhandledrejection":{const e=t.name&&t.name!=="Error"?`${t.name}: `:"",i=t.reason.split(`
2
+ `)[0]??t.reason;return{id:o(),sessionId:r,timestamp:t.at,source:"client-runtime",category:"runtime",severity:"error",context:{sessionId:r,...s},fingerprint:a({kind:"runtime",identity:`unhandledrejection:${t.reason.slice(0,80)}`}),title:l(`Unhandled promise rejection: ${e}${i}`),message:u(t.stack??t.reason),raw:{...t,reason:g(t.reason),...t.stack?{stack:u(t.stack)}:{}}}}case"console":{const e=t.level==="error"?"error":t.level==="warn"?"warning":"info",i=$(t.args),n=i.map(w).join(" ");return{id:o(),sessionId:r,timestamp:t.at,source:"client-runtime",category:"runtime",severity:e,context:{sessionId:r,...s},fingerprint:a({kind:"runtime",identity:`console:${t.level}:${n.slice(0,80)}`}),title:`console.${t.level}`,message:u(n),raw:{...t,args:i}}}case"fetch":{const e=t.error!==void 0||t.status!==void 0&&t.status>=400,i=p(t.url),n=t.status!==void 0?` \u2192 ${t.status}${t.statusText?` ${t.statusText}`:""}`:"";return{id:o(),sessionId:r,timestamp:t.at,source:"client-runtime",category:"network",severity:e?"error":"info",context:{sessionId:r,...s},fingerprint:a({kind:"network",identity:`${t.method}:${v(t.url)}:${t.status??"err"}`}),title:l(`${t.method} ${i}${n}`),message:u(t.error),relatedUrls:[i],raw:{...t,url:i}}}case"route":return{id:o(),sessionId:r,timestamp:t.at,source:"client-runtime",category:"runtime",severity:"info",context:{sessionId:r,url:t.url,...s},fingerprint:a({kind:"runtime",identity:`route:${t.url}`}),title:`Route \u2192 ${t.url}`,raw:t};case"ready":return{id:o(),sessionId:r,timestamp:t.at,source:"client-runtime",category:"runtime",severity:"info",context:{sessionId:r,url:t.url,...s},fingerprint:a({kind:"runtime",identity:"client-ready"}),title:"Client runtime ready",message:t.reloadCause?`${t.userAgent} \u2014 after a Vite full reload${t.reloadCause.triggeredBy?` triggered by ${u(g(t.reloadCause.triggeredBy))}`:""}`:t.userAgent,raw:t};case"hmr":{const e=t.triggeredBy?g(t.triggeredBy):void 0,i=t.path?g(t.path):void 0,n=t.event==="full-reload"?`full-reload:${e??i??"?"}`:t.event==="invalidate"?`invalidate:${i??"?"}`:t.event,f=t.event==="full-reload"?`Vite full reload${e?` \u2014 ${l(e)} could not hot-update`:i?` \u2014 ${l(i)}`:""}`:t.event==="update"?`Vite HMR update (${t.count??t.updates?.length??0} module${(t.count??t.updates?.length??0)===1?"":"s"})`:t.event==="invalidate"?`Vite HMR invalidate \u2014 ${l(i??"?")}`:t.event==="ws-disconnect"?"Vite HMR socket lost \u2014 the page will poll and reload":t.event==="ws-failed"?t.recovering?"Vite HMR socket failed to connect \u2014 the page reloads once to get one":"Vite HMR socket failed to connect \u2014 this page gets no hot updates until it is reloaded":"Vite HMR socket connected";return{id:o(),sessionId:r,timestamp:t.at,source:"client-runtime",category:"build",severity:t.event==="full-reload"||t.event==="ws-disconnect"||t.event==="ws-failed"?"warning":"info",context:{sessionId:r,...s},fingerprint:a({kind:"hmr",identity:n}),title:f,...t.message?{message:u(g(t.message))}:{},...e||i?{location:{file:e??i??""}}:{},...t.updates?.length?{relatedFiles:t.updates.map(y=>g(y))}:{},raw:{...t,...e?{triggeredBy:e}:{},...i?{path:i}:{}}}}case"gone":return{id:o(),sessionId:r,timestamp:t.at,source:"client-runtime",category:"runtime",severity:"info",context:{sessionId:r,...s},fingerprint:a({kind:"runtime",identity:"client-gone"}),title:"Client runtime gone",raw:t};case"publish":{if(!I(t.source))return;const e=h(t.category,t.raw),i=e&&e.status!==void 0&&e.status>=400?"error":t.severity??"info",n=m(y=>e&&e.url!==e.redactedUrl?y.split(e.url).join(e.redactedUrl):y,"scrub"),f=n(t.title);return{id:o(),sessionId:r,timestamp:t.at,source:t.source,category:t.category,severity:i,context:{...s,...t.context??{},sessionId:r},fingerprint:t.fingerprint?n(t.fingerprint):a({kind:"publish",identity:f}),title:l(f),message:u(t.message),...e?{relatedUrls:[e.redactedUrl]}:{},raw:e?{...$(t.raw),url:e.redactedUrl}:$(t.raw)}}}}c(envelopeToEvent,"envelopeToEvent"),d(envelopeToEvent,"envelopeToEvent"),m(envelopeToEvent,"envelopeToEvent");function h(t,r){if(t!=="network"||!r||typeof r!="object")return;const s=r;if(!(typeof s.url!="string"||s.url.length===0))return{url:s.url,redactedUrl:p(s.url),...typeof s.status=="number"?{status:s.status}:{}}}c(h,"$"),d(h,"k"),m(h,"networkDetails");function k(t){if(!t)return"unknown";const r=t.split(`
3
+ `).slice(0,2);for(const s of r){const e=s.match(/at\s+(\S+)/);if(e&&e[1])return e[1]}return"unknown"}c(k,"h"),d(k,"w"),m(k,"normaliseStackTopFrame");function v(t){try{return`${new URL(t,"http://x").pathname}`}catch{return t}}c(v,"v"),d(v,"y"),m(v,"normaliseUrl");function w(t){if(typeof t=="string")return t;try{return JSON.stringify(t)}catch{return String(t)}}c(w,"k"),d(w,"x"),m(w,"stringify");const j=new Set(["react","valtio","memory","client-runtime"]);function I(t){return typeof t=="string"&&j.has(t)}c(I,"w"),d(I,"b"),m(I,"isBrowserPublishableSource");
@@ -1 +1 @@
1
- "use strict";var f=Object.defineProperty;var i=(t,e)=>f(t,"name",{value:e,configurable:!0});var d=Object.defineProperty,s=i((t,e)=>d(t,"name",{value:e,configurable:!0}),"s");import{capMap as h}from"@lensmcp/protocol-types";export const MAX_LEARNED_ORIGINS=64;export function createOriginPolicy(t=[]){let e=!1,n=!1;const u=[];for(const r of t){const o=r.trim().toLowerCase();if(o)if(o==="*")e=!0;else if(o==="null")n=!0;else{const a=p(o);a&&u.push(a)}}const c=new Map;return{admits(r){if(r===void 0)return!0;if(r==="null")return n;const o=l(r);return o?e||isLoopbackHostname(o.hostname)||c.has(o.origin)||u.some(a=>a(o)):!1},learn(r){const o=l(r);o&&(c.delete(o.origin),c.set(o.origin,!0),h(c,MAX_LEARNED_ORIGINS))}}}i(createOriginPolicy,"createOriginPolicy"),s(createOriginPolicy,"createOriginPolicy");export function parseAllowedOrigins(t){return(t??"").split(/[\s,]+/).filter(e=>e.length>0)}i(parseAllowedOrigins,"parseAllowedOrigins"),s(parseAllowedOrigins,"parseAllowedOrigins");export function isLoopbackHostname(t){const e=t.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(e)}i(isLoopbackHostname,"isLoopbackHostname"),s(isLoopbackHostname,"isLoopbackHostname");function l(t){try{const e=new URL(t);return e.protocol==="http:"||e.protocol==="https:"?e:void 0}catch{return}}i(l,"l"),s(l,"parseOrigin");function p(t){if(t.includes("://")){const e=l(t)?.origin;return e?n=>n.origin===e:void 0}if(t.startsWith(".")){const e=t.slice(1);return e?n=>n.hostname===e||n.hostname.endsWith(t):void 0}return e=>e.hostname===t}i(p,"d"),s(p,"ruleFor");
1
+ "use strict";var d=Object.defineProperty;var i=(o,e)=>d(o,"name",{value:e,configurable:!0});var h=Object.defineProperty,s=i((o,e)=>h(o,"name",{value:e,configurable:!0}),"i"),g=Object.defineProperty,c=s((o,e)=>g(o,"name",{value:e,configurable:!0}),"s");import{capMap as m}from"@lensmcp/protocol-types";export const MAX_LEARNED_ORIGINS=64;export function createOriginPolicy(o=[]){let e=!1,r=!1;const f=[];for(const n of o){const t=n.trim().toLowerCase();if(t)if(t==="*")e=!0;else if(t==="null")r=!0;else{const u=p(t);u&&f.push(u)}}const l=new Map;return{admits(n){if(n===void 0)return!0;if(n==="null")return r;const t=a(n);return t?e||isLoopbackHostname(t.hostname)||l.has(t.origin)||f.some(u=>u(t)):!1},learn(n){const t=a(n);t&&(l.delete(t.origin),l.set(t.origin,!0),m(l,MAX_LEARNED_ORIGINS))}}}i(createOriginPolicy,"createOriginPolicy"),s(createOriginPolicy,"createOriginPolicy"),c(createOriginPolicy,"createOriginPolicy");export function parseAllowedOrigins(o){return(o??"").split(/[\s,]+/).filter(e=>e.length>0)}i(parseAllowedOrigins,"parseAllowedOrigins"),s(parseAllowedOrigins,"parseAllowedOrigins"),c(parseAllowedOrigins,"parseAllowedOrigins");export function isLoopbackHostname(o){const e=o.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(e)}i(isLoopbackHostname,"isLoopbackHostname"),s(isLoopbackHostname,"isLoopbackHostname"),c(isLoopbackHostname,"isLoopbackHostname");function a(o){try{const e=new URL(o);return e.protocol==="http:"||e.protocol==="https:"?e:void 0}catch{return}}i(a,"l"),s(a,"l"),c(a,"parseOrigin");function p(o){if(o.includes("://")){const e=a(o)?.origin;return e?r=>r.origin===e:void 0}if(o.startsWith(".")){const e=o.slice(1);return e?r=>r.hostname===e||r.hostname.endsWith(o):void 0}return e=>e.hostname===o}i(p,"p"),s(p,"d"),c(p,"ruleFor");
package/lib/server.js CHANGED
@@ -1 +1 @@
1
- "use strict";var R=Object.defineProperty;var d=(e,r)=>R(e,"name",{value:r,configurable:!0});var L=Object.defineProperty,n=d((e,r)=>L(e,"name",{value:r,configurable:!0}),"t");import{createHash as B,timingSafeEqual as D}from"node:crypto";import{createServer as x,STATUS_CODES as $}from"node:http";import{createServer as U}from"node:net";import{WebSocket as F,WebSocketServer as M}from"ws";import{boundedClone as W,createEventFloodGuard as G,DEFAULT_RAW_BYTE_LIMIT as H,exceedsJsonByteBudget as J}from"@lensmcp/protocol-types";import{BRIDGE_TOKEN_PARAM as j,CONNECTION_BURST as q,CONNECTION_PER_SEC as z,DEFAULT_WS_HOST as V,DEFAULT_WS_PORT as X,ENV_BRIDGE_ALLOWED_ORIGINS as y,MAX_BATCH_EVENTS as K,MAX_BRIDGE_CONNECTIONS as Y,MAX_FRAME_BYTES as Q}from"./constants.js";import{resolveEnvSink as Z}from"./env-sink.js";import{asBaseEvent as ee,conformsToEnvelopeContract as re}from"./envelope-contract.js";import{envelopeToEvent as te}from"./event-mappers.js";import{createOriginPolicy as ne,parseAllowedOrigins as oe}from"./origin-policy.js";export function makePublisher(e){let r;return t=>{if(e.bus){e.bus.publish(t);return}if(e.sink){e.sink(t);return}if(r===void 0&&(r=Z()),r){r(t);return}(t.severity==="error"||t.severity==="fatal")&&console.debug(`[lensmcp-bridge] ${t.severity}: ${t.title}`)}}d(makePublisher,"makePublisher"),n(makePublisher,"makePublisher");export function handleClientEnvelope(e,r,t,a={}){const c=a.admit??se;let l;try{l=JSON.parse(e)}catch{c();return}if(!l||typeof l!="object"||!("kind"in l)){c();return}if(l.kind==="batch"){if(!Array.isArray(l.events)){c();return}for(const f of l.events.slice(0,K))c()&&(!f||typeof f!="object"||!("kind"in f)||f.kind!=="batch"&&E(f,r,t));return}c()&&E(l,r,t)}d(handleClientEnvelope,"handleClientEnvelope"),n(handleClientEnvelope,"handleClientEnvelope");const se=n(()=>!0,"admitAll");function E(e,r,t){if(!re(e))return;let a;try{const c=te(e,t);a=c&&ee(c)}catch{return}if(a)try{r(T(a))}catch{}}d(E,"O"),n(E,"mapAndPublish");function T(e){const r=e.raw;return r==null||!J(r,H)?e:{...e,raw:W(r).value}}d(T,"Z"),n(T,"boundRaw");export function readTabId(e){try{const r=JSON.parse(e);return typeof r?.tabId=="string"&&r.tabId?r.tabId:void 0}catch{return}}d(readTabId,"readTabId"),n(readTabId,"readTabId");export async function createBridgeServer(e={}){const r=e.host??V,t=e.port??X,a=makePublisher(e),c=ne([...e.allowedOrigins??[],...oe(process.env[y])]),l=e.token?S(e.token):void 0,f=e.maxConnections??Y,h=e.connectionRateLimit??{burst:q,perSec:z},k=e.onRefuse??N(),P=n(s=>{const i=s.headers.origin,o=i===void 0?{}:{origin:i};if(m.clients.size>=f)return{status:503,reason:"bridge connection limit reached",...o};if(!c.admits(i))return{status:403,reason:"origin not allowed",...o};if(l&&!I(s.url,l))return{status:401,reason:"missing or wrong bridge token",...o}},"refuseUpgrade"),u=x(w);u.on("error",()=>{});const m=new M({server:u,maxPayload:Q,verifyClient:n((s,i)=>{const o=P(s.req);if(!o){i(!0);return}try{k(o)}catch{}i(!1,o.status,o.reason)},"verifyClient")});m.on("error",()=>{}),m.on("connection",s=>{if(s.on("error",()=>{}),m.clients.size>f){s.close(1013,"bridge connection limit reached");return}let i;const o=G({burst:h.burst,perSec:h.perSec,envOverride:!1}),g=n(p=>{handleClientEnvelope(JSON.stringify({kind:"console",level:"warn",at:Date.now(),...i?{tabId:i}:{},args:[CONNECTION_THROTTLE_NOTICE,{dropped:p}]}),a,e.sessionId)},"announceDropped"),v={admit:n(()=>{const p=o.admit(ie);return p.ok&&p.suppressed>0&&g(p.suppressed),p.ok},"admit")};s.on("message",p=>{const _=p.toString();i??=readTabId(_),handleClientEnvelope(_,a,e.sessionId,v)}),s.on("close",()=>{i&&handleClientEnvelope(JSON.stringify({kind:"gone",at:Date.now(),tabId:i}),a,e.sessionId)})}),await new Promise((s,i)=>{const o=n(v=>{u.off("listening",g),i(v)},"onError"),g=n(()=>{u.off("error",o),s()},"onListening");u.once("error",o),u.once("listening",g),u.listen(t,r)});const b=u.address(),A=typeof b=="object"&&b!==null?b.port:t;let O;return{port:A,host:r,learnOrigin:n(s=>c.learn(s),"learnOrigin"),admitsOrigin:n(s=>c.admits(s),"admitsOrigin"),close:n(()=>(O??=(async()=>{const s=[...m.clients],i=[new Promise(o=>m.close(()=>o())),new Promise(o=>u.close(()=>o())),...s.map(C)];for(const o of s)o.terminate();u.closeAllConnections(),await Promise.all(i)})(),O),"close")}}d(createBridgeServer,"createBridgeServer"),n(createBridgeServer,"createBridgeServer");function w(e,r){const t=$[426]??"Upgrade Required";r.writeHead(426,{"Content-Length":Buffer.byteLength(t),"Content-Type":"text/plain"}),r.end(t)}d(w,"ee"),n(w,"answerPlainRequest");function C(e){return e.readyState===F.CLOSED?Promise.resolve():new Promise(r=>e.once("close",()=>r()))}d(C,"ne"),n(C,"socketClosed");const ie="connection";export const CONNECTION_THROTTLE_NOTICE="[lensmcp-bridge] per-connection rate limit: this tab sent envelopes faster than the bridge admits, and some were dropped";const ae=32;function N(){const e=new Set;return r=>{const t=`${r.status} ${r.origin??""}`;if(e.has(t)||e.size>=ae)return;e.add(t);const a=r.status===403?` \u2014 if this is your app, add its origin to ${y} (or the Vite plugin's \`wsAllowedOrigins\`)`:r.status===401?" \u2014 a tab opened before the dev server restarted needs a reload; a no-build page needs the token as __LENSMCP_WS_TOKEN__":"";console.warn(`[lensmcp-bridge] refused a connection${r.origin?` from ${r.origin}`:""}: ${r.reason} (${r.status})${a}`)}}d(N,"oe"),n(N,"warnRefusalOnce");function S(e){return B("sha256").update(e).digest()}d(S,"w"),n(S,"digest");function I(e,r){let t;try{t=new URL(e??"/","http://bridge.invalid").searchParams.get(j)}catch{return!1}return t!==null&&D(S(t),r)}d(I,"ie"),n(I,"carriesToken");export function findFreePort(){return new Promise((e,r)=>{const t=U();t.unref(),t.on("error",r),t.listen(0,()=>{const a=t.address();if(!a){t.close(),r(new Error("Could not allocate free port"));return}const c=a.port;t.close(()=>e(c))})})}d(findFreePort,"findFreePort"),n(findFreePort,"findFreePort");
1
+ "use strict";var B=Object.defineProperty;var d=(e,r)=>B(e,"name",{value:r,configurable:!0});var L=Object.defineProperty,l=d((e,r)=>L(e,"name",{value:r,configurable:!0}),"d"),D=Object.defineProperty,t=l((e,r)=>D(e,"name",{value:r,configurable:!0}),"t");import{createHash as x,timingSafeEqual as $}from"node:crypto";import{createServer as F,STATUS_CODES as U}from"node:http";import{createServer as M}from"node:net";import{WebSocket as W,WebSocketServer as j}from"ws";import{boundedClone as G,createEventFloodGuard as H,DEFAULT_RAW_BYTE_LIMIT as J,exceedsJsonByteBudget as q}from"@lensmcp/protocol-types";import{BRIDGE_TOKEN_PARAM as z,CONNECTION_BURST as V,CONNECTION_PER_SEC as X,DEFAULT_WS_HOST as K,DEFAULT_WS_PORT as Y,ENV_BRIDGE_ALLOWED_ORIGINS as N,MAX_BATCH_EVENTS as Z,MAX_BRIDGE_CONNECTIONS as Q,MAX_FRAME_BYTES as ee}from"./constants.js";import{resolveEnvSink as re}from"./env-sink.js";import{asBaseEvent as ne,conformsToEnvelopeContract as te}from"./envelope-contract.js";import{envelopeToEvent as oe}from"./event-mappers.js";import{createOriginPolicy as se,parseAllowedOrigins as ie}from"./origin-policy.js";export function makePublisher(e){let r;return n=>{if(e.bus){e.bus.publish(n);return}if(e.sink){e.sink(n);return}if(r===void 0&&(r=re()),r){r(n);return}(n.severity==="error"||n.severity==="fatal")&&console.debug(`[lensmcp-bridge] ${n.severity}: ${n.title}`)}}d(makePublisher,"makePublisher"),l(makePublisher,"makePublisher"),t(makePublisher,"makePublisher");export function handleClientEnvelope(e,r,n,a={}){const c=a.admit??ae;let u;try{u=JSON.parse(e)}catch{c();return}if(!u||typeof u!="object"||!("kind"in u)){c();return}if(u.kind==="batch"){if(!Array.isArray(u.events)){c();return}for(const p of u.events.slice(0,Z))c()&&(!p||typeof p!="object"||!("kind"in p)||p.kind!=="batch"&&v(p,r,n));return}c()&&v(u,r,n)}d(handleClientEnvelope,"handleClientEnvelope"),l(handleClientEnvelope,"handleClientEnvelope"),t(handleClientEnvelope,"handleClientEnvelope");const ae=t(()=>!0,"admitAll");function v(e,r,n){if(!te(e))return;let a;try{const c=oe(e,n);a=c&&ne(c)}catch{return}if(a)try{r(S(a))}catch{}}d(v,"E"),l(v,"O"),t(v,"mapAndPublish");function S(e){const r=e.raw;return r==null||!q(r,J)?e:{...e,raw:G(r).value}}d(S,"T"),l(S,"Z"),t(S,"boundRaw");export function readTabId(e){try{const r=JSON.parse(e);return typeof r?.tabId=="string"&&r.tabId?r.tabId:void 0}catch{return}}d(readTabId,"readTabId"),l(readTabId,"readTabId"),t(readTabId,"readTabId");export async function createBridgeServer(e={}){const r=e.host??K,n=e.port??Y,a=makePublisher(e),c=se([...e.allowedOrigins??[],...ie(process.env[N])]),u=e.token?E(e.token):void 0,p=e.maxConnections??Q,C=e.connectionRateLimit??{burst:V,perSec:X},k=e.onRefuse??_(),A=t(s=>{const i=s.headers.origin,o=i===void 0?{}:{origin:i};if(g.clients.size>=p)return{status:503,reason:"bridge connection limit reached",...o};if(!c.admits(i))return{status:403,reason:"origin not allowed",...o};if(u&&!w(s.url,u))return{status:401,reason:"missing or wrong bridge token",...o}},"refuseUpgrade"),f=F(y);f.on("error",()=>{});const g=new j({server:f,maxPayload:ee,verifyClient:t((s,i)=>{const o=A(s.req);if(!o){i(!0);return}try{k(o)}catch{}i(!1,o.status,o.reason)},"verifyClient")});g.on("error",()=>{}),g.on("connection",s=>{if(s.on("error",()=>{}),g.clients.size>p){s.close(1013,"bridge connection limit reached");return}let i;const o=H({burst:C.burst,perSec:C.perSec,envOverride:!1}),b=t(m=>{handleClientEnvelope(JSON.stringify({kind:"console",level:"warn",at:Date.now(),...i?{tabId:i}:{},args:[CONNECTION_THROTTLE_NOTICE,{dropped:m}]}),a,e.sessionId)},"announceDropped"),O={admit:t(()=>{const m=o.admit(ce);return m.ok&&m.suppressed>0&&b(m.suppressed),m.ok},"admit")};s.on("message",m=>{const I=m.toString();i??=readTabId(I),handleClientEnvelope(I,a,e.sessionId,O)}),s.on("close",()=>{i&&handleClientEnvelope(JSON.stringify({kind:"gone",at:Date.now(),tabId:i}),a,e.sessionId)})}),await new Promise((s,i)=>{const o=t(O=>{f.off("listening",b),i(O)},"onError"),b=t(()=>{f.off("error",o),s()},"onListening");f.once("error",o),f.once("listening",b),f.listen(n,r)});const h=f.address(),R=typeof h=="object"&&h!==null?h.port:n;let P;return{port:R,host:r,learnOrigin:t(s=>c.learn(s),"learnOrigin"),admitsOrigin:t(s=>c.admits(s),"admitsOrigin"),close:t(()=>(P??=(async()=>{const s=[...g.clients],i=[new Promise(o=>g.close(()=>o())),new Promise(o=>f.close(()=>o())),...s.map(T)];for(const o of s)o.terminate();f.closeAllConnections(),await Promise.all(i)})(),P),"close")}}d(createBridgeServer,"createBridgeServer"),l(createBridgeServer,"createBridgeServer"),t(createBridgeServer,"createBridgeServer");function y(e,r){const n=U[426]??"Upgrade Required";r.writeHead(426,{"Content-Length":Buffer.byteLength(n),"Content-Type":"text/plain"}),r.end(n)}d(y,"w"),l(y,"ee"),t(y,"answerPlainRequest");function T(e){return e.readyState===W.CLOSED?Promise.resolve():new Promise(r=>e.once("close",()=>r()))}d(T,"C"),l(T,"ne"),t(T,"socketClosed");const ce="connection";export const CONNECTION_THROTTLE_NOTICE="[lensmcp-bridge] per-connection rate limit: this tab sent envelopes faster than the bridge admits, and some were dropped";const de=32;function _(){const e=new Set;return r=>{const n=`${r.status} ${r.origin??""}`;if(e.has(n)||e.size>=de)return;e.add(n);const a=r.status===403?` \u2014 if this is your app, add its origin to ${N} (or the Vite plugin's \`wsAllowedOrigins\`)`:r.status===401?" \u2014 a tab opened before the dev server restarted needs a reload; a no-build page needs the token as __LENSMCP_WS_TOKEN__":"";console.warn(`[lensmcp-bridge] refused a connection${r.origin?` from ${r.origin}`:""}: ${r.reason} (${r.status})${a}`)}}d(_,"N"),l(_,"oe"),t(_,"warnRefusalOnce");function E(e){return x("sha256").update(e).digest()}d(E,"S"),l(E,"w"),t(E,"digest");function w(e,r){let n;try{n=new URL(e??"/","http://bridge.invalid").searchParams.get(z)}catch{return!1}return n!==null&&$(E(n),r)}d(w,"I"),l(w,"ie"),t(w,"carriesToken");export function findFreePort(){return new Promise((e,r)=>{const n=M();n.unref(),n.on("error",r),n.listen(0,()=>{const a=n.address();if(!a){n.close(),r(new Error("Could not allocate free port"));return}const c=a.port;n.close(()=>e(c))})})}d(findFreePort,"findFreePort"),l(findFreePort,"findFreePort"),t(findFreePort,"findFreePort");
package/main.js CHANGED
@@ -1 +1 @@
1
- "use strict";var S=Object.defineProperty;var i=(s,e)=>S(s,"name",{value:e,configurable:!0});var E=Object.defineProperty,l=i((s,e)=>E(s,"name",{value:e,configurable:!0}),"i");import{DEFAULT_WS_HOST as u,DEFAULT_WS_PORT as v,ENV_BRIDGE_ALLOWED_ORIGINS as t,ENV_BRIDGE_TOKEN as $,ENV_SESSION_ID as N,ENV_WS_HOST as b,ENV_WS_PORT as d,SHUTDOWN_GRACE_MS as m}from"./lib/constants.js";import{closeEnvSink as T}from"./lib/env-sink.js";import{createBridgeServer as f}from"./lib/server.js";async function g(){const s=process.env[b]??u,e=process.env[d],o=e!==void 0&&e!==""?Number(e):v;(!Number.isFinite(o)||o<0)&&(console.error(`[lensmcp-bridge] invalid ${d}=${e}`),process.exit(2));const _=process.env[N],c=process.env[$]||void 0;let r;try{r=await f({host:s,port:o,sessionId:_,token:c})}catch(n){console.error(`[lensmcp-bridge] failed to listen on ws://${s}:${o} \u2014 ${n.message}`),process.exit(1)}console.log(`[lensmcp-bridge] listening on ws://${r.host}:${r.port}`),console.log(`[lensmcp-bridge] admitting pages from loopback origins${process.env[t]?` and ${process.env[t]}`:` (set ${t} to add more)`}; token ${c?"required":"not required"}`);let a=!1;const p=l(n=>{a&&(console.error(`[lensmcp-bridge] ${n} again \u2014 exiting now`),process.exit(1)),a=!0,setTimeout(()=>{console.error(`[lensmcp-bridge] shutdown did not finish within ${m}ms \u2014 exiting anyway`),process.exit(1)},m),r.close().then(()=>T()).then(()=>process.exit(0),()=>process.exit(1))},"shutdown");process.on("SIGINT",p),process.on("SIGTERM",p)}i(g,"u"),l(g,"main"),g();
1
+ "use strict";var v=Object.defineProperty;var i=(s,e)=>v(s,"name",{value:e,configurable:!0});var S=Object.defineProperty,d=i((s,e)=>S(s,"name",{value:e,configurable:!0}),"i"),E=Object.defineProperty,m=d((s,e)=>E(s,"name",{value:e,configurable:!0}),"i");import{DEFAULT_WS_HOST as b,DEFAULT_WS_PORT as $,ENV_BRIDGE_ALLOWED_ORIGINS as t,ENV_BRIDGE_TOKEN as N,ENV_SESSION_ID as f,ENV_WS_HOST as T,ENV_WS_PORT as g,SHUTDOWN_GRACE_MS as u}from"./lib/constants.js";import{closeEnvSink as O}from"./lib/env-sink.js";import{createBridgeServer as I}from"./lib/server.js";async function c(){const s=process.env[T]??b,e=process.env[g],o=e!==void 0&&e!==""?Number(e):$;(!Number.isFinite(o)||o<0)&&(console.error(`[lensmcp-bridge] invalid ${g}=${e}`),process.exit(2));const _=process.env[f],a=process.env[N]||void 0;let r;try{r=await I({host:s,port:o,sessionId:_,token:a})}catch(n){console.error(`[lensmcp-bridge] failed to listen on ws://${s}:${o} \u2014 ${n.message}`),process.exit(1)}console.log(`[lensmcp-bridge] listening on ws://${r.host}:${r.port}`),console.log(`[lensmcp-bridge] admitting pages from loopback origins${process.env[t]?` and ${process.env[t]}`:` (set ${t} to add more)`}; token ${a?"required":"not required"}`);let p=!1;const l=m(n=>{p&&(console.error(`[lensmcp-bridge] ${n} again \u2014 exiting now`),process.exit(1)),p=!0,setTimeout(()=>{console.error(`[lensmcp-bridge] shutdown did not finish within ${u}ms \u2014 exiting anyway`),process.exit(1)},u),r.close().then(()=>O()).then(()=>process.exit(0),()=>process.exit(1))},"shutdown");process.on("SIGINT",l),process.on("SIGTERM",l)}i(c,"g"),d(c,"u"),m(c,"main"),c();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/bridge",
3
- "version": "1.25.14",
3
+ "version": "1.25.17",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "module": "./index.js",
@@ -19,8 +19,8 @@
19
19
  }
20
20
  },
21
21
  "dependencies": {
22
- "@lensmcp/core": "1.25.14",
23
- "@lensmcp/protocol-types": "1.25.14",
22
+ "@lensmcp/core": "1.25.17",
23
+ "@lensmcp/protocol-types": "1.25.17",
24
24
  "tslib": "^2.3.0",
25
25
  "ws": "^8.21.0"
26
26
  },