@vibro/bro 0.0.1-alpha.1 → 0.0.1-alpha.2

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,11 +1,11 @@
1
- 'use strict';var crypto=require('crypto'),promises=require('fs/promises'),fs=require('fs'),path=require('path');var L="/__vibro__",at="__vibro__:request",ct="__vibro__:response",z="__vibro__:tab-register",G="__vibro__:tab-heartbeat",W="__vibro__:tab-focus",ut="__vibro__:list-request",dt="__vibro__:list-response",$="node_modules",Q="vibro-sessions.json";function T(t){return t!==null&&typeof t=="object"}var Y="dist",lt="vibro-cli.js",pt="vibro-client.js",C="vibro",xt=path.join($,".bin");function Ct(){let t=c=>`/@fs/${c.replace(/\\/g,"/")}`,e=__dirname;for(;;){let c=path.join(e,Y),d=path.join(c,lt),u=path.join(c,pt);if(fs.existsSync(d)&&fs.existsSync(u))return {packageRoot:e,cliSourceFilePath:d,clientScriptPathForVite:t(u)};let f=path.dirname(e);if(f===e)break;e=f;}let r=path.resolve(__dirname,"../.."),s=path.join(r,Y,pt);return {packageRoot:r,cliSourceFilePath:path.join(r,Y,lt),clientScriptPathForVite:t(s)}}var{cliSourceFilePath:jt,clientScriptPathForVite:Ut}=Ct(),Ht=4e3,qt=4e3,Jt=8e3,zt=3e4,mt=3e4,Gt=12e4,Wt=3,Qt=50;function P(t){return promises.stat(t).then(()=>true,()=>false)}function Yt(t){return promises.readFile(t,"utf8").then(e=>{try{return JSON.parse(e)}catch{return}},()=>{})}function Xt(t){return Array.isArray(t)?t.length>0:T(t)&&Object.keys(t).length>0}async function Kt(t){async function e(c){if(await Promise.all([P(path.join(c,".git")),P(path.join(c,"pnpm-workspace.yaml")),P(path.join(c,".pnpm-workspace-state-v1.json")),P(path.join(c,"lerna.json")),P(path.join(c,"nx.json")),P(path.join(c,"turbo.json"))]).then(l=>l.some(Boolean)))return true;let u=path.join(c,"package.json"),f=await Yt(u);return f!==void 0&&Xt(f.workspaces)}let r=path.resolve(t),s="";for(;;){await e(r)&&(s=r);let c=path.dirname(r);if(c===r)break;r=c;}return s.length>0?s:path.resolve(t)}function F(t,e){return typeof t=="number"&&Number.isFinite(t)?t:e}function k(t,e){return typeof t=="string"?t:e}function Zt(t){try{return process.kill(t,0),!0}catch(e){if(!(e instanceof Error))return false;let r=e.code;return !(r==="ESRCH"||r==="EINVAL")}}function Et(t){let e=k(t.config.server.host,"localhost");return e==="0.0.0.0"||e==="::"?"localhost":e}function _t(t){return t.config.server.https?"https":"http"}function te(t){let e=t.httpServer?.address();if(!(e==null||typeof e=="string"))return Number.isFinite(e.port)?e.port:void 0}function ee(t){let e=t.config.configFile;return typeof e=="string"?e:void 0}function Z(){return {updatedAt:Date.now(),instances:{}}}function U(t,e){let r=Date.now(),s={};for(let[c,d]of Object.entries(t)){if(d.pid<=0||!Number.isFinite(d.pid)||!Zt(d.pid)||r-d.lastSeenAt>e)continue;let u=String(d.pid);c===u&&(s[c]=d);}return s}function ne(t,e){if(!T(t))return Z();let r=t.updatedAt,s=t.instances;if(!T(s))return Z();let c={};for(let[d,u]of Object.entries(s)){if(!T(u))continue;let f=F(u.pid,NaN);if(!Number.isFinite(f)||String(Math.trunc(f))!==d)continue;let l=F(u.port,NaN);if(!Number.isFinite(l))continue;let m=F(u.startedAt,Date.now()),b=F(u.lastSeenAt,Date.now()),R=k(u.protocol,"http");if(R!=="http"&&R!=="https")continue;let E=k(u.host,"localhost"),y=k(u.cacheDir,"");if(y.length<=0)continue;let I=k(u.projectRoot,"");I.length<=0||(c[d]={pid:f,port:l,host:E,protocol:R,cacheDir:y,projectRoot:I,configFile:k(u.configFile,""),startedAt:m,lastSeenAt:b});}return {updatedAt:F(r,Date.now()),instances:U(c,e)}}function re(t,e){return path.join(t,$,e)}async function oe(t,e){try{let r=await promises.readFile(t,"utf8");return ne(JSON.parse(r),e)}catch{return Z()}}async function ie(t,e){await promises.mkdir(path.dirname(t),{recursive:true});let r=`${t}.tmp`;await promises.writeFile(r,JSON.stringify(e,null,2),"utf8"),await promises.rename(r,t);}function se(t){return new Promise(e=>{setTimeout(e,t);})}function x(t,e){console.error("[vibro]",t,e);}async function et(t,e,r,s,c,d){for(let u=0;u<=s;u+=1)try{let f=await oe(t,r),l=d(f);await ie(t,l);return}catch(f){if(u>=s)throw f;await se(c);}}function bt(t){return `'${t.replace(/'/g,`'"'"'`)}'`}function ht(t){return `"${t.replace(/"/g,'""')}"`}function St(t){return `'${t.replace(/'/g,"''")}'`}function D(t,e=C){return path.join(t,xt,e)}async function ae(t,e,r){let s=D(t),c=D(t,`${C}.CMD`),d=D(t,`${C}.ps1`),u=D(t,`${C}.cli.mjs`),f=bt(e),l=bt(r),m=ht(r),b=St(r),R=`#!/usr/bin/env sh
2
- exec node ${f} --sessions-file ${l} "$@"
3
- `,E=`@ECHO OFF
4
- node ${ht(e)} --sessions-file ${m} %*
1
+ 'use strict';var crypto=require('crypto'),promises=require('fs/promises'),fs=require('fs'),path=require('path'),vite=require('vite');var L="/__vibro__",ct="__vibro__:request",ut="__vibro__:response",W="__vibro__:tab-register",z="__vibro__:tab-heartbeat",Q="__vibro__:tab-focus",dt="__vibro__:list-request",ft="__vibro__:list-response",$="node_modules",Y="vibro-sessions.json";function T(t){return t!==null&&typeof t=="object"}var C="dist",pt="vibro-cli.js",mt="vibro-client.js",j="vibro",qt=path.join($,".bin");function Jt(){let t=c=>`/@fs/${c.replace(/\\/g,"/")}`,e=__dirname;for(;;){let c=path.join(e,C),d=path.join(c,pt),u=path.join(c,mt);if(fs.existsSync(d)&&fs.existsSync(u))return {packageRoot:e,cliSourceFilePath:d,clientScriptPathForVite:t(u)};let f=path.dirname(e);if(f===e)break;e=f;}let r=path.resolve(__dirname,"../.."),a=path.join(r,C,mt);return {packageRoot:r,cliSourceFilePath:path.join(r,C,pt),clientScriptPathForVite:t(a)}}var{packageRoot:Z,cliSourceFilePath:Gt,clientScriptPathForVite:Wt}=Jt(),bt=path.join(Z,C);function zt(t){let e=new Map;for(let r of t)e.set(r,true);return Array.from(e.keys())}function ht(t){try{return fs.realpathSync(t)}catch{return t}}var Qt=4e3,Yt=4e3,Kt=8e3,Xt=3e4,Rt=3e4,Zt=12e4,te=3,ee=50;function P(t){return promises.stat(t).then(()=>true,()=>false)}function ne(t){return promises.readFile(t,"utf8").then(e=>{try{return JSON.parse(e)}catch{return}},()=>{})}function re(t){return Array.isArray(t)?t.length>0:T(t)&&Object.keys(t).length>0}async function oe(t){async function e(c){if(await Promise.all([P(path.join(c,".git")),P(path.join(c,"pnpm-workspace.yaml")),P(path.join(c,".pnpm-workspace-state-v1.json")),P(path.join(c,"lerna.json")),P(path.join(c,"nx.json")),P(path.join(c,"turbo.json"))]).then(g=>g.some(Boolean)))return true;let u=path.join(c,"package.json"),f=await ne(u);return f!==void 0&&re(f.workspaces)}let r=path.resolve(t),a="";for(;;){await e(r)&&(a=r);let c=path.dirname(r);if(c===r)break;r=c;}return a.length>0?a:path.resolve(t)}function F(t,e){return typeof t=="number"&&Number.isFinite(t)?t:e}function k(t,e){return typeof t=="string"?t:e}function se(t){try{return process.kill(t,0),!0}catch(e){if(!(e instanceof Error))return false;let r=e.code;return !(r==="ESRCH"||r==="EINVAL")}}function At(t){let e=k(t.config.server.host,"localhost");return e==="0.0.0.0"||e==="::"?"localhost":e}function It(t){return t.config.server.https?"https":"http"}function ie(t){let e=t.httpServer?.address();if(!(e==null||typeof e=="string"))return Number.isFinite(e.port)?e.port:void 0}function ae(t){let e=t.config.configFile;return typeof e=="string"?e:void 0}function tt(){return {updatedAt:Date.now(),instances:{}}}function H(t,e){let r=Date.now(),a={};for(let[c,d]of Object.entries(t)){if(d.pid<=0||!Number.isFinite(d.pid)||!se(d.pid)||r-d.lastSeenAt>e)continue;let u=String(d.pid);c===u&&(a[c]=d);}return a}function ce(t,e){if(!T(t))return tt();let r=t.updatedAt,a=t.instances;if(!T(a))return tt();let c={};for(let[d,u]of Object.entries(a)){if(!T(u))continue;let f=F(u.pid,NaN);if(!Number.isFinite(f)||String(Math.trunc(f))!==d)continue;let g=F(u.port,NaN);if(!Number.isFinite(g))continue;let m=F(u.startedAt,Date.now()),b=F(u.lastSeenAt,Date.now()),S=k(u.protocol,"http");if(S!=="http"&&S!=="https")continue;let _=k(u.host,"localhost"),y=k(u.cacheDir,"");if(y.length<=0)continue;let I=k(u.projectRoot,"");I.length<=0||(c[d]={pid:f,port:g,host:_,protocol:S,cacheDir:y,projectRoot:I,configFile:k(u.configFile,""),startedAt:m,lastSeenAt:b});}return {updatedAt:F(r,Date.now()),instances:H(c,e)}}function ue(t,e){return path.join(t,$,e)}async function de(t,e){try{let r=await promises.readFile(t,"utf8");return ce(JSON.parse(r),e)}catch{return tt()}}async function fe(t,e){await promises.mkdir(path.dirname(t),{recursive:true});let r=`${t}.tmp`;await promises.writeFile(r,JSON.stringify(e,null,2),"utf8"),await promises.rename(r,t);}function le(t){return new Promise(e=>{setTimeout(e,t);})}function x(t,e){console.error("[vibro]",t,e);}async function nt(t,e,r,a,c,d){for(let u=0;u<=a;u+=1)try{let f=await de(t,r),g=d(f);await fe(t,g);return}catch(f){if(u>=a)throw f;await le(c);}}function yt(t){return `'${t.replace(/'/g,`'"'"'`)}'`}function St(t){return `"${t.replace(/"/g,'""')}"`}function Tt(t){return `'${t.replace(/'/g,"''")}'`}function D(t,e=j){return path.join(t,qt,e)}async function ge(t,e,r){let a=D(t),c=D(t,`${j}.CMD`),d=D(t,`${j}.ps1`),u=D(t,`${j}.cli.mjs`),f=yt(e),g=yt(r),m=St(r),b=Tt(r),S=`#!/usr/bin/env sh
2
+ exec node ${f} --sessions-file ${g} "$@"
3
+ `,_=`@ECHO OFF
4
+ node ${St(e)} --sessions-file ${m} %*
5
5
  `,y=`$ErrorActionPreference = 'Stop'
6
- $cli = ${St(e)}
6
+ $cli = ${Tt(e)}
7
7
  $sessionFile = ${b}
8
8
  & node $cli --sessions-file $sessionFile @args
9
9
  exit $LASTEXITCODE
10
- `,I=[{path:s,content:R,executable:true},{path:c,content:E},{path:d,content:y}];await promises.unlink(u).catch(()=>{});for(let h of I){try{if(await promises.readFile(h.path,"utf8")===h.content){h.executable&&await promises.chmod(h.path,493);continue}}catch{}await promises.mkdir(path.dirname(h.path),{recursive:true});let B=`${h.path}.tmp`;await promises.writeFile(B,h.content,"utf8"),await promises.rename(B,h.path),h.executable&&await promises.chmod(h.path,493);}}async function ce(t,e,r,s,c,d){await et(t,e,r,s,c,u=>{let f=Date.now(),l=String(process.pid),m=U(u.instances,r),b=m[l]?.startedAt??f;return m[l]={pid:process.pid,port:d,host:Et(e),protocol:_t(e),cacheDir:e.config.cacheDir,projectRoot:e.config.root,configFile:ee(e),startedAt:b,lastSeenAt:f},{updatedAt:f,instances:m}});}async function ue(t,e,r,s,c){await et(t,e,r,s,c,d=>{let u=Date.now(),f=String(process.pid),l=d.instances[f];if(!l)return d;let m=U(d.instances,r);return m[f]={...l,lastSeenAt:u},{updatedAt:u,instances:m}});}async function de(t,e,r,s,c){await et(t,e,r,s,c,d=>{let u=Date.now(),f=U(d.instances,r);return delete f[String(process.pid)],{updatedAt:u,instances:f}});}function fe(t){let e={};for(let[r,s]of Object.entries(t))s!==void 0&&(typeof s=="string"?e[r]=s:Array.isArray(s)&&(e[r]=s.join(",")));return e}function ge(t){return new Promise((e,r)=>{let s="";t.on("data",c=>{s+=c.toString();}),t.on("error",r),t.on("end",()=>{e(s||void 0);});})}function le(t,e){let r=t===void 0?NaN:Number.parseInt(t,10);return Number.isFinite(r)&&r>=0?r:e}function pe(t){return typeof t=="string"&&t.length>0}function me(t){return !(!T(t)||typeof t.id!="string"||typeof t.ok!="boolean")}function be(t){return !(!T(t)||typeof t.requestId!="string"||typeof t.tabId!="string"||!T(t.metadata)||"state"in t&&typeof t.state!="string")}function X(t){let e=Date.now();if(!T(t))return {title:"",pathname:"",href:"",focused:false,wsUrl:"",userAgent:"",registeredAt:e,lastSeenAt:e};let r=typeof t.registeredAt=="number"?t.registeredAt:e,s=typeof t.lastSeenAt=="number"?t.lastSeenAt:e;return {title:typeof t.title=="string"?t.title:"",pathname:typeof t.pathname=="string"?t.pathname:"",href:typeof t.href=="string"?t.href:"",focused:typeof t.focused=="boolean"?t.focused:false,wsUrl:typeof t.wsUrl=="string"?t.wsUrl:"",userAgent:typeof t.userAgent=="string"?t.userAgent:"",registeredAt:r,lastSeenAt:s}}function A(t,e){let r=e-t;return r>zt?"closed":r>Jt?"stale":"open"}function he(t={}){let e=new Map,r=new Map,s=new Map,c=t.removeFromListOnReload??false,d=t.instanceHeartbeatMs??mt,u=t.instanceTtlMs??Gt,f=t.sessionFileName??t.registryFileName??Q,l=t.registryRetries??Wt,m=t.registryRetryDelayMs??Qt,b="",R="",E,y,I=false,B=false;function H(){E!==void 0&&(clearInterval(E),E=void 0);}async function nt(n){R=await Kt(n.config.root),b=re(R,f);let i=jt;if(!await P(i))throw new Error(`vibro cli source file not found: ${i}`);await ae(R,i,b);}async function wt(n){let i=y;if(i===void 0)return;(b.length<=0||R.length<=0)&&await nt(n);let o=Number.isFinite(d)&&d>0?d:mt;await ce(b,n,u,l,m,i),I=true,E!==void 0&&H(),E=setInterval(()=>{ue(b,n,u,l,m).catch(a=>{x("failed to touch Vite instance",a);});},o);}async function rt(n){!b.length||!I||(I=false,H(),await de(b,n,u,l,m));}function At(n){return new Promise((i,o)=>{let a=setTimeout(()=>{e.delete(n),o(new Error(`Bridge request timeout (${n})`));},Ht);e.set(n,{resolve:i,reject:o,timeout:a});})}function It(n){let i=e.get(n.id);i&&(clearTimeout(i.timeout),e.delete(n.id),i.resolve(n));}function M(){let n=Date.now();return Array.from(s.values()).map(i=>({...i,state:A(i.metadata.lastSeenAt,n),metadata:{...i.metadata,lastSeenAt:i.metadata.lastSeenAt}}))}function Vt(){let n=Date.now(),o=M().filter(g=>A(g.metadata.lastSeenAt,n)!=="closed");if(o.length<=0)return;let a=o.find(g=>g.metadata.focused);return a!==void 0?a.id:o[0].id}function ot(n,i,o){let a=Date.now(),g=X(i),_=s.get(n),V={id:n,state:o??A(g.lastSeenAt,a),metadata:{...g,registeredAt:_?.metadata.registeredAt??g.registeredAt,lastSeenAt:a}};return s.set(n,V),V}function vt(n,i,o){let a=Date.now();return i<=0?Promise.resolve(M().map(g=>({...g,state:A(g.metadata.lastSeenAt,a)}))):new Promise((g,_)=>{let V=setTimeout(()=>{it(n);},o);r.set(n,{expected:i,resolve:g,reject:_,timeout:V,responses:new Map});})}function it(n){let i=r.get(n);if(!i)return;clearTimeout(i.timeout),r.delete(n);let o=Date.now(),a=new Map;M().forEach(g=>{a.set(g.id,{...g,state:A(g.metadata.lastSeenAt,o)});}),i.responses.forEach(g=>{a.set(g.id,{...g,state:A(g.metadata.lastSeenAt,o)});}),i.resolve(Array.from(a.values()));}function Pt(n){let i=r.get(n.requestId);if(!i)return;let o=n.state??A(n.metadata.lastSeenAt,Date.now()),a={...X(n.metadata),lastSeenAt:Date.now()},g=ot(n.tabId,a,o);i.responses.set(n.tabId,g),i.expected>0&&i.responses.size>=i.expected&&it(n.requestId);}function q(n,i){if(!T(i))return;let o=i.tabId,a=i.metadata;if(!pe(o)||!T(a))return;let g=X(a);ot(o,g);}function Nt(n){let i=n.split("/").filter(Boolean);if(i.length<2)return;let o=i[0];if(!(o!=="ping"&&o!=="screenshot"))return {commandPath:`/${o}`,targetTabId:i[1]}}return {name:"vibro-plugin",apply:"serve",configureServer(n){let i=async()=>{if(y=te(n),y!==void 0)try{if(await nt(n),await wt(n),!B){let o=_t(n),a=Et(n);console.info(` \u25A0 Registered server ${a?`${o}://${a}:${y}`:`:${y}`}`),console.info(` [vibro] registry ready at ${a?`${o}://${a}:${y}`:`:${y}`}`),console.info(` [vibro] sessions: ${b}`),console.info(` [vibro] cli: ${D(R)}`),B=!0;}}catch(o){x("failed to register Vite instance",o);}};n.httpServer?.listening?i():n.httpServer&&n.httpServer.once("listening",()=>{i();}),n.httpServer?.once("close",()=>{rt(n).catch(o=>{x("failed to detach Vite instance",o);});}),c&&n.ws.on("vite:beforeFullReload",()=>{rt(n).catch(o=>{x("failed to detach Vite instance on reload",o);});}),n.ws.on(ct,o=>{me(o)&&It(o);}),n.ws.on(z,o=>{q(z,o);}),n.ws.on(G,o=>{q(G,o);}),n.ws.on(W,o=>{q(W,o);}),n.ws.on(dt,o=>{be(o)&&Pt(o);}),n.middlewares.use(L,async(o,a,g)=>{if(!o.url||!o.method){g();return}let _=new URL(o.url,"http://localhost"),V=o.method.toUpperCase(),kt=!["GET","HEAD"].includes(V),w={id:crypto.randomUUID(),path:_.pathname.startsWith(L)?_.pathname.substring(L.length)||"/":_.pathname,method:V,query:Object.fromEntries(_.searchParams.entries()),headers:fe(o.headers),body:kt?await ge(o).catch(()=>{}):void 0};if(console.log(`[vibro] Received a signal: ${V} ${_}`),w.path==="/list"){let S=le(w.query.timeout,qt),N=w.id,Ft=Date.now(),st=M().map(O=>({...O,state:A(O.metadata.lastSeenAt,Ft)})).filter(O=>O.state!=="closed").length,Dt=vt(N,st,S);st>0&&n.ws.send(ut,{requestId:N});let Mt=await Dt;a.statusCode=200,a.setHeader("content-type","application/json; charset=utf-8"),a.end(JSON.stringify({ok:true,payload:{tabs:Mt}}));return}let v,J=Nt(w.path);if(J!==void 0?(v=J.targetTabId,w.path=J.commandPath):w.path==="/screenshot"&&(v=Vt()),v!==void 0&&(w.targetTabId=v),v!==void 0){let S=s.get(v),N=Date.now();if(!S||A(S.metadata.lastSeenAt,N)==="closed"){a.statusCode=404,a.setHeader("content-type","application/json; charset=utf-8"),a.end(JSON.stringify({ok:false,error:`Unknown target tab: ${v}`}));return}}let Bt=At(w.id);n.ws.send(at,w);try{let S=await Bt;a.statusCode=S.ok?200:500,a.setHeader("content-type","application/json; charset=utf-8"),a.end(JSON.stringify({ok:S.ok,payload:S.payload,error:S.error}));}catch(S){let N=S instanceof Error?S.message:String(S);a.statusCode=504,a.setHeader("content-type","application/json; charset=utf-8"),a.end(JSON.stringify({ok:false,error:N}));}});},transformIndexHtml(n){return {html:n,tags:[{tag:"script",injectTo:"body-prepend",attrs:{type:"module",src:Ut}}]}}}}
11
- exports.vibroVitePlugin=he;
10
+ `,I=[{path:a,content:S,executable:true},{path:c,content:_},{path:d,content:y}];await promises.unlink(u).catch(()=>{});for(let h of I){try{if(await promises.readFile(h.path,"utf8")===h.content){h.executable&&await promises.chmod(h.path,493);continue}}catch{}await promises.mkdir(path.dirname(h.path),{recursive:true});let B=`${h.path}.tmp`;await promises.writeFile(B,h.content,"utf8"),await promises.rename(B,h.path),h.executable&&await promises.chmod(h.path,493);}}async function pe(t,e,r,a,c,d){await nt(t,e,r,a,c,u=>{let f=Date.now(),g=String(process.pid),m=H(u.instances,r),b=m[g]?.startedAt??f;return m[g]={pid:process.pid,port:d,host:At(e),protocol:It(e),cacheDir:e.config.cacheDir,projectRoot:e.config.root,configFile:ae(e),startedAt:b,lastSeenAt:f},{updatedAt:f,instances:m}});}async function me(t,e,r,a,c){await nt(t,e,r,a,c,d=>{let u=Date.now(),f=String(process.pid),g=d.instances[f];if(!g)return d;let m=H(d.instances,r);return m[f]={...g,lastSeenAt:u},{updatedAt:u,instances:m}});}async function be(t,e,r,a,c){await nt(t,e,r,a,c,d=>{let u=Date.now(),f=H(d.instances,r);return delete f[String(process.pid)],{updatedAt:u,instances:f}});}function he(t){let e={};for(let[r,a]of Object.entries(t))a!==void 0&&(typeof a=="string"?e[r]=a:Array.isArray(a)&&(e[r]=a.join(",")));return e}function Re(t){return new Promise((e,r)=>{let a="";t.on("data",c=>{a+=c.toString();}),t.on("error",r),t.on("end",()=>{e(a||void 0);});})}function ye(t,e){let r=t===void 0?NaN:Number.parseInt(t,10);return Number.isFinite(r)&&r>=0?r:e}function Se(t){return typeof t=="string"&&t.length>0}function Te(t){return !(!T(t)||typeof t.id!="string"||typeof t.ok!="boolean")}function _e(t){return !(!T(t)||typeof t.requestId!="string"||typeof t.tabId!="string"||!T(t.metadata)||"state"in t&&typeof t.state!="string")}function K(t){let e=Date.now();if(!T(t))return {title:"",pathname:"",href:"",focused:false,wsUrl:"",userAgent:"",registeredAt:e,lastSeenAt:e};let r=typeof t.registeredAt=="number"?t.registeredAt:e,a=typeof t.lastSeenAt=="number"?t.lastSeenAt:e;return {title:typeof t.title=="string"?t.title:"",pathname:typeof t.pathname=="string"?t.pathname:"",href:typeof t.href=="string"?t.href:"",focused:typeof t.focused=="boolean"?t.focused:false,wsUrl:typeof t.wsUrl=="string"?t.wsUrl:"",userAgent:typeof t.userAgent=="string"?t.userAgent:"",registeredAt:r,lastSeenAt:a}}function A(t,e){let r=e-t;return r>Xt?"closed":r>Kt?"stale":"open"}function Ee(t={}){let e=new Map,r=new Map,a=new Map,c=t.removeFromListOnReload??false,d=t.instanceHeartbeatMs??Rt,u=t.instanceTtlMs??Zt,f=t.sessionFileName??t.registryFileName??Y,g=t.registryRetries??te,m=t.registryRetryDelayMs??ee,b="",S="",_,y,I=false,B=false;function q(){_!==void 0&&(clearInterval(_),_=void 0);}async function rt(n){S=await oe(n.config.root),b=ue(S,f);let s=Gt;if(!await P(s))throw new Error(`vibro cli source file not found: ${s}`);await ge(S,s,b);}async function Vt(n){let s=y;if(s===void 0)return;(b.length<=0||S.length<=0)&&await rt(n);let o=Number.isFinite(d)&&d>0?d:Rt;await pe(b,n,u,g,m,s),I=true,_!==void 0&&q(),_=setInterval(()=>{me(b,n,u,g,m).catch(i=>{x("failed to touch Vite instance",i);});},o);}async function ot(n){!b.length||!I||(I=false,q(),await be(b,n,u,g,m));}function vt(n){return new Promise((s,o)=>{let i=setTimeout(()=>{e.delete(n),o(new Error(`Bridge request timeout (${n})`));},Qt);e.set(n,{resolve:s,reject:o,timeout:i});})}function Pt(n){let s=e.get(n.id);s&&(clearTimeout(s.timeout),e.delete(n.id),s.resolve(n));}function M(){let n=Date.now();return Array.from(a.values()).map(s=>({...s,state:A(s.metadata.lastSeenAt,n),metadata:{...s.metadata,lastSeenAt:s.metadata.lastSeenAt}}))}function Nt(){let n=Date.now(),o=M().filter(l=>A(l.metadata.lastSeenAt,n)!=="closed");if(o.length<=0)return;let i=o.find(l=>l.metadata.focused);return i!==void 0?i.id:o[0].id}function st(n,s,o){let i=Date.now(),l=K(s),E=a.get(n),V={id:n,state:o??A(l.lastSeenAt,i),metadata:{...l,registeredAt:E?.metadata.registeredAt??l.registeredAt,lastSeenAt:i}};return a.set(n,V),V}function kt(n,s,o){let i=Date.now();return s<=0?Promise.resolve(M().map(l=>({...l,state:A(l.metadata.lastSeenAt,i)}))):new Promise((l,E)=>{let V=setTimeout(()=>{it(n);},o);r.set(n,{expected:s,resolve:l,reject:E,timeout:V,responses:new Map});})}function it(n){let s=r.get(n);if(!s)return;clearTimeout(s.timeout),r.delete(n);let o=Date.now(),i=new Map;M().forEach(l=>{i.set(l.id,{...l,state:A(l.metadata.lastSeenAt,o)});}),s.responses.forEach(l=>{i.set(l.id,{...l,state:A(l.metadata.lastSeenAt,o)});}),s.resolve(Array.from(i.values()));}function Bt(n){let s=r.get(n.requestId);if(!s)return;let o=n.state??A(n.metadata.lastSeenAt,Date.now()),i={...K(n.metadata),lastSeenAt:Date.now()},l=st(n.tabId,i,o);s.responses.set(n.tabId,l),s.expected>0&&s.responses.size>=s.expected&&it(n.requestId);}function J(n,s){if(!T(s))return;let o=s.tabId,i=s.metadata;if(!Se(o)||!T(i))return;let l=K(i);st(o,l);}function Ft(n){let s=n.split("/").filter(Boolean);if(s.length<2)return;let o=s[0];if(!(o!=="ping"&&o!=="screenshot"))return {commandPath:`/${o}`,targetTabId:s[1]}}return {name:"vibro-plugin",apply:"serve",config(n){let s=vite.searchForWorkspaceRoot(process.cwd()),o=n.server?.fs?.allow,i=Array.isArray(o)?o:[];return {server:{fs:{allow:zt([...i,s,Z,bt,ht(Z),ht(bt)])}}}},configureServer(n){let s=async()=>{if(y=ie(n),y!==void 0)try{if(await rt(n),await Vt(n),!B){let o=It(n),i=At(n);console.info(` \u25A0 Registered server ${i?`${o}://${i}:${y}`:`:${y}`}`),console.info(` [vibro] registry ready at ${i?`${o}://${i}:${y}`:`:${y}`}`),console.info(` [vibro] sessions: ${b}`),console.info(` [vibro] cli: ${D(S)}`),B=!0;}}catch(o){x("failed to register Vite instance",o);}};n.httpServer?.listening?s():n.httpServer&&n.httpServer.once("listening",()=>{s();}),n.httpServer?.once("close",()=>{ot(n).catch(o=>{x("failed to detach Vite instance",o);});}),c&&n.ws.on("vite:beforeFullReload",()=>{ot(n).catch(o=>{x("failed to detach Vite instance on reload",o);});}),n.ws.on(ut,o=>{Te(o)&&Pt(o);}),n.ws.on(W,o=>{J(W,o);}),n.ws.on(z,o=>{J(z,o);}),n.ws.on(Q,o=>{J(Q,o);}),n.ws.on(ft,o=>{_e(o)&&Bt(o);}),n.middlewares.use(L,async(o,i,l)=>{if(!o.url||!o.method){l();return}let E=new URL(o.url,"http://localhost"),V=o.method.toUpperCase(),Dt=!["GET","HEAD"].includes(V),w={id:crypto.randomUUID(),path:E.pathname.startsWith(L)?E.pathname.substring(L.length)||"/":E.pathname,method:V,query:Object.fromEntries(E.searchParams.entries()),headers:he(o.headers),body:Dt?await Re(o).catch(()=>{}):void 0};if(console.log(`[vibro] Received a signal: ${V} ${E}`),w.path==="/list"){let R=ye(w.query.timeout,Yt),N=w.id,Ot=Date.now(),at=M().map(O=>({...O,state:A(O.metadata.lastSeenAt,Ot)})).filter(O=>O.state!=="closed").length,Lt=kt(N,at,R);at>0&&n.ws.send(dt,{requestId:N});let $t=await Lt;i.statusCode=200,i.setHeader("content-type","application/json; charset=utf-8"),i.end(JSON.stringify({ok:true,payload:{tabs:$t}}));return}let v,G=Ft(w.path);if(G!==void 0?(v=G.targetTabId,w.path=G.commandPath):w.path==="/screenshot"&&(v=Nt()),v!==void 0&&(w.targetTabId=v),v!==void 0){let R=a.get(v),N=Date.now();if(!R||A(R.metadata.lastSeenAt,N)==="closed"){i.statusCode=404,i.setHeader("content-type","application/json; charset=utf-8"),i.end(JSON.stringify({ok:false,error:`Unknown target tab: ${v}`}));return}}let Mt=vt(w.id);n.ws.send(ct,w);try{let R=await Mt;i.statusCode=R.ok?200:500,i.setHeader("content-type","application/json; charset=utf-8"),i.end(JSON.stringify({ok:R.ok,payload:R.payload,error:R.error}));}catch(R){let N=R instanceof Error?R.message:String(R);i.statusCode=504,i.setHeader("content-type","application/json; charset=utf-8"),i.end(JSON.stringify({ok:false,error:N}));}});},transformIndexHtml(n){return {html:n,tags:[{tag:"script",injectTo:"body-prepend",attrs:{type:"module",src:Wt}}]}}}}
11
+ exports.vibroVitePlugin=Ee;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibro/bro",
3
- "version": "0.0.1-alpha.1",
3
+ "version": "0.0.1-alpha.2",
4
4
  "description": "Vibro plugin and runtime bridge",
5
5
  "publishConfig": {
6
6
  "access": "public",