@melaya/runner 1.1.45 → 1.1.46

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.
Files changed (2) hide show
  1. package/dist/connection.js +36 -2
  2. package/package.json +1 -1
@@ -78,6 +78,27 @@ export async function connect(opts) {
78
78
  reconnectionAttempts: Infinity,
79
79
  });
80
80
  let relay = null;
81
+ // ── Disconnect diagnostics (transport-close root-cause) ──────────────
82
+ // A "transport close" disconnect can be a NETWORK blip OR the Node event loop
83
+ // being BLOCKED (e.g. relaying big browser screenshots/trees) long enough that
84
+ // Socket.IO can't service the connection. These need OPPOSITE fixes, so we
85
+ // sample event-loop lag continuously and print the recent PEAK on disconnect:
86
+ // a multi-second spike ⇒ event-loop block (in-process work); ~0 ⇒ network/proxy.
87
+ let connectedAt = 0;
88
+ let lastHeartbeatAt = 0;
89
+ let peakLagMs = 0;
90
+ {
91
+ let last = Date.now();
92
+ const TICK = 500;
93
+ const t = setInterval(() => {
94
+ const now = Date.now();
95
+ const lag = now - last - TICK; // how much longer than TICK the loop actually took
96
+ last = now;
97
+ if (lag > peakLagMs)
98
+ peakLagMs = lag;
99
+ }, TICK);
100
+ t.unref?.();
101
+ }
81
102
  // ── Melaya Browser bridge state (plan Sections 3/4) ──────────────────
82
103
  // The governed browser control bridge is started lazily on the first
83
104
  // browser run. Grant public keys arrive over the socket (server push)
@@ -209,6 +230,8 @@ export async function connect(opts) {
209
230
  };
210
231
  socket.on("connect", async () => {
211
232
  spinner.succeed(chalk.green("Connected to Melaya"));
233
+ connectedAt = Date.now();
234
+ peakLagMs = 0; // fresh window each connection so the disconnect line reflects THIS session
212
235
  // New socket lifetime → new generation. Grants minted for an earlier
213
236
  // generation are refused (plan Section 4). Any browser runs from the
214
237
  // previous connection are already torn down on the disconnect path.
@@ -269,7 +292,16 @@ export async function connect(opts) {
269
292
  }
270
293
  });
271
294
  socket.on("disconnect", (reason) => {
272
- console.log(chalk.yellow(`\n Disconnected: ${reason}`));
295
+ const upS = connectedAt ? Math.round((Date.now() - connectedAt) / 1000) : 0;
296
+ const hbS = lastHeartbeatAt ? Math.round((Date.now() - lastHeartbeatAt) / 1000) : -1;
297
+ console.log(chalk.yellow(`\n Disconnected: ${reason} (up ${upS}s, last heartbeat ${hbS}s ago, peak event-loop lag ${peakLagMs}ms)`));
298
+ // The discriminator: a big peak lag (or a stale heartbeat) means the Node
299
+ // event loop was BLOCKED while connected — heavy in-process work (big browser
300
+ // screenshot/tree relay), NOT a network drop → fix is to offload/chunk that
301
+ // work. A small lag with "transport close" points at the network/proxy path.
302
+ if (peakLagMs > 2000 || hbS > 45) {
303
+ console.log(chalk.yellow(` ↳ event loop was blocked ~${peakLagMs}ms (heartbeat ${hbS}s ago) — this is in-process backpressure (likely big browser payload relay), not a network drop.`));
304
+ }
273
305
  // Melaya Browser: a dropped socket invalidates every browser grant
274
306
  // bound to this socket generation. Tear down ALL browser runs
275
307
  // (cancels in-flight ops, releases leases, closes owned browsers);
@@ -430,8 +462,10 @@ export async function connect(opts) {
430
462
  });
431
463
  // ── Heartbeat ──────────────────────────────────────────────────────
432
464
  setInterval(() => {
433
- if (socket.connected)
465
+ if (socket.connected) {
434
466
  socket.emit("runner:heartbeat");
467
+ lastHeartbeatAt = Date.now();
468
+ }
435
469
  }, HEARTBEAT_INTERVAL);
436
470
  // ── Run command ────────────────────────────────────────────────────
437
471
  socket.on("runner:run", async (payload) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@melaya/runner",
3
- "version": "1.1.45",
3
+ "version": "1.1.46",
4
4
  "description": "Run Melaya AI pipelines locally with your own LM Studio or Ollama models",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,