Skip to content

Commit ebe288a

Browse files
committed
chore(release): bump version to v0.14.8
1 parent 8614515 commit ebe288a

3 files changed

Lines changed: 31 additions & 17 deletions

File tree

overlay/src/ws.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,40 +11,51 @@ const handlers: MessageHandler[] = [];
1111
export function connect(url: string = 'ws://localhost:3333'): void {
1212
connectAttempts++;
1313
const attempt = connectAttempts;
14-
debugLog('tw-overlay', `ws connect() attempt #${attempt} to ${url} | readyState of previous socket: ${socket?.readyState ?? 'none'}`);
14+
const t0 = performance.now();
15+
const ts = () => `+${(performance.now() - t0).toFixed(0)}ms`;
16+
debugLog('tw-overlay', `ws connect() attempt #${attempt} to ${url} | readyState of previous socket: ${socket?.readyState ?? 'none'} [${ts()}]`);
1517

1618
try {
1719
socket = new WebSocket(url);
1820
} catch (err) {
19-
console.error(`[tw-overlay][ws] WebSocket constructor threw:`, err);
21+
console.error(`[tw-overlay][ws] WebSocket constructor threw [${ts()}]:`, err);
2022
return;
2123
}
2224

23-
debugLog('tw-overlay', `ws WebSocket created, readyState=${socket.readyState} (0=CONNECTING)`);
25+
debugLog('tw-overlay', `ws WebSocket created, readyState=${socket.readyState} (0=CONNECTING) [${ts()}]`);
2426

2527
socket.addEventListener('open', () => {
2628
connected = true;
2729
connectAttempts = 0; // Reset backoff on successful connection
28-
debugLog('tw-overlay', `ws OPEN (attempt #${attempt}) — registering as overlay`);
30+
debugLog('tw-overlay', `ws OPEN (attempt #${attempt}) [${ts()}] — registering as overlay`);
2931
// Register as overlay so the server can route messages to us
3032
send({ type: 'REGISTER', role: 'overlay' });
3133
window.dispatchEvent(new CustomEvent('overlay-ws-connected'));
3234
});
3335

3436
socket.addEventListener('close', (event) => {
35-
debugWarn('tw-overlay', `ws CLOSE (attempt #${attempt}) — code=${event.code} reason="${event.reason}" wasClean=${event.wasClean} | was connected=${connected}`);
37+
debugWarn('tw-overlay', `ws CLOSE (attempt #${attempt}) [${ts()}] — code=${event.code} reason="${event.reason}" wasClean=${event.wasClean} | was connected=${connected}`);
3638
connected = false;
3739
socket = null;
3840
window.dispatchEvent(new CustomEvent('overlay-ws-disconnected'));
3941
// Exponential backoff: 500ms, 1s, 2s, 3s (cap)
4042
const delay = Math.min(500 * Math.pow(2, connectAttempts - 1), 3000);
41-
debugLog('tw-overlay', `ws Will reconnect in ${delay}ms…`);
43+
debugLog('tw-overlay', `ws Will reconnect in ${delay}ms… [${ts()}]`);
4244
reconnectTimer = setTimeout(() => connect(url), delay);
4345
});
4446

47+
socket.addEventListener('error', (err) => {
48+
console.error(`[tw-overlay][ws] ERROR (attempt #${attempt}) [${ts()}] — connected=${connected} readyState=${socket?.readyState}`, err);
49+
});
50+
51+
let firstMessage = true;
4552
socket.addEventListener('message', (event) => {
4653
try {
4754
const data = JSON.parse(event.data);
55+
if (firstMessage) {
56+
debugLog('tw-overlay', `WS ← first message: ${data.type ?? 'unknown'} [${ts()}]`);
57+
firstMessage = false;
58+
}
4859
debugLog('tw-overlay', `WS ← ${data.type ?? 'unknown'}`, data);
4960
for (const handler of handlers) {
5061
handler(data);
@@ -53,10 +64,6 @@ export function connect(url: string = 'ws://localhost:3333'): void {
5364
console.error('[tw-overlay] Failed to parse message:', err);
5465
}
5566
});
56-
57-
socket.addEventListener('error', (err) => {
58-
console.error(`[tw-overlay][ws] ERROR (attempt #${attempt}) — connected=${connected} readyState=${socket?.readyState}`, err);
59-
});
6067
}
6168

6269
export function send(data: object): void {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@bitovi/vybit",
3-
"version": "0.14.7",
3+
"version": "0.14.8",
44
"description": "Browser overlay + inspector panel + MCP server for visually editing Tailwind CSS classes on a running React app",
55
"keywords": [
66
"tailwind",

server/websocket.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ export interface WebSocketDeps {
1414
export function setupWebSocket(httpServer: Server): WebSocketDeps {
1515
const wss = new WebSocketServer({ server: httpServer, maxPayload: 10 * 1024 * 1024, perMessageDeflate: false });
1616
const clientRoles = new Map<WebSocket, string>();
17+
const serverStartTime = Date.now();
18+
const ts = () => `[${((Date.now() - serverStartTime) / 1000).toFixed(1)}s]`;
19+
20+
// Log when the HTTP server receives a WebSocket upgrade request
21+
httpServer.on('upgrade', (req) => {
22+
console.error(`${ts()} [ws] HTTP upgrade request for: ${req.url} from ${req.headers.origin ?? 'unknown origin'}`);
23+
});
1724

1825
// Heartbeat: ping every 25s to keep Codespaces tunnel alive
1926
const aliveClients = new WeakSet<WebSocket>();
@@ -48,8 +55,8 @@ export function setupWebSocket(httpServer: Server): WebSocketDeps {
4855
broadcastTo("panel", { type: "QUEUE_UPDATE", ...getQueueUpdate() });
4956
}
5057

51-
wss.on("connection", (ws: WebSocket) => {
52-
console.error("[ws] Client connected");
58+
wss.on("connection", (ws: WebSocket, req) => {
59+
console.error(`${ts()} [ws] Client connected from ${req.url}`);
5360
aliveClients.add(ws);
5461
ws.on("pong", () => { aliveClients.add(ws); });
5562

@@ -61,16 +68,16 @@ export function setupWebSocket(httpServer: Server): WebSocketDeps {
6168
const role = msg.role;
6269
if (role === "overlay" || role === "panel" || role === "design") {
6370
clientRoles.set(ws, role);
64-
console.error(`[ws] Client registered as: ${role}`);
71+
console.error(`${ts()} [ws] Client registered as: ${role}`);
6572
if (role === "panel") {
6673
ws.send(JSON.stringify({ type: "QUEUE_UPDATE", ...getQueueUpdate() }));
6774
// Tell newly-registered panel whether an overlay is connected
6875
const overlayConnected = hasOverlay();
69-
console.error(`[ws] Sending OVERLAY_STATUS { connected: ${overlayConnected} } to new panel`);
76+
console.error(`${ts()} [ws] Sending OVERLAY_STATUS { connected: ${overlayConnected} } to new panel`);
7077
ws.send(JSON.stringify({ type: "OVERLAY_STATUS", connected: overlayConnected }));
7178
} else if (role === "overlay") {
7279
// Notify all panels that an overlay connected
73-
console.error(`[ws] Broadcasting OVERLAY_STATUS { connected: true } to all panels`);
80+
console.error(`${ts()} [ws] Broadcasting OVERLAY_STATUS { connected: true } to all panels`);
7481
broadcastTo("panel", { type: "OVERLAY_STATUS", connected: true });
7582
}
7683
}
@@ -200,7 +207,7 @@ export function setupWebSocket(httpServer: Server): WebSocketDeps {
200207
ws.on("close", () => {
201208
const role = clientRoles.get(ws);
202209
clientRoles.delete(ws);
203-
console.error("[ws] Client disconnected");
210+
console.error(`${ts()} [ws] Client disconnected (was: ${role ?? 'unregistered'})`);
204211
// If an overlay disconnected, notify panels
205212
if (role === "overlay" && !hasOverlay()) {
206213
broadcastTo("panel", { type: "OVERLAY_STATUS", connected: false });

0 commit comments

Comments
 (0)