@unbound-app/debugger 0.1.4 → 0.4.0

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/index.mjs +70 -11
  2. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -29,6 +29,7 @@ const state$2 = {
29
29
  controllers: /* @__PURE__ */ new Set()
30
30
  };
31
31
  const pending = /* @__PURE__ */ new Map();
32
+ const pendingPushes = /* @__PURE__ */ new Map();
32
33
  const logListeners = /* @__PURE__ */ new Set();
33
34
  const deviceListeners = /* @__PURE__ */ new Set();
34
35
  const evalListeners = /* @__PURE__ */ new Set();
@@ -66,6 +67,16 @@ function detachDevice(socket) {
66
67
  });
67
68
  pending.delete(id);
68
69
  }
70
+ for (const [id, entry] of pendingPushes) {
71
+ clearTimeout(entry.timer);
72
+ entry.deliver({
73
+ type: "plugin-push-result",
74
+ id,
75
+ ok: false,
76
+ error: "Device disconnected before the reload completed."
77
+ });
78
+ pendingPushes.delete(id);
79
+ }
69
80
  broadcastDeviceStatus(false);
70
81
  }
71
82
  /** @description Adds a controller and immediately reports current device presence to it. */
@@ -86,6 +97,11 @@ function detachController(socket) {
86
97
  clearTimeout(entry.timer);
87
98
  pending.delete(id);
88
99
  }
100
+ for (const [id, entry] of pendingPushes) {
101
+ if (entry.origin !== socket) continue;
102
+ clearTimeout(entry.timer);
103
+ pendingPushes.delete(id);
104
+ }
89
105
  controllerDelivery.delete(socket);
90
106
  for (const listener of controllerListeners) listener(false, state$2.controllers.size);
91
107
  }
@@ -105,6 +121,40 @@ function evaluateForController(socket, id, code) {
105
121
  });
106
122
  }
107
123
  /**
124
+ * @description Forwards a controller's {@link PluginPushRequest} to the device and delivers the
125
+ * id-correlated {@link PluginPushResult} back over that same controller's socket. Replies with an
126
+ * error frame instead if no device is connected or it doesn't answer within {@link EVAL_TIMEOUT_MS}.
127
+ * @param socket The controller that issued the push.
128
+ * @param request The push to forward verbatim; its `id` correlates the result.
129
+ */
130
+ function pushPluginForController(socket, request) {
131
+ const deliver = (result) => socket.send(JSON.stringify(result));
132
+ if (!state$2.device) {
133
+ deliver({
134
+ type: "plugin-push-result",
135
+ id: request.id,
136
+ ok: false,
137
+ error: "No device is connected to the debugger."
138
+ });
139
+ return;
140
+ }
141
+ const timer = setTimeout(() => {
142
+ pendingPushes.delete(request.id);
143
+ deliver({
144
+ type: "plugin-push-result",
145
+ id: request.id,
146
+ ok: false,
147
+ error: `Plugin push timed out after ${EVAL_TIMEOUT_MS}ms.`
148
+ });
149
+ }, EVAL_TIMEOUT_MS);
150
+ pendingPushes.set(request.id, {
151
+ deliver,
152
+ timer,
153
+ origin: socket
154
+ });
155
+ state$2.device.send(JSON.stringify(request));
156
+ }
157
+ /**
108
158
  * @description Runs code on the device on behalf of an in-process caller (the terminal REPL),
109
159
  * resolving with the device's answer. Rejects if no device is connected or it doesn't answer within
110
160
  * {@link EVAL_TIMEOUT_MS}.
@@ -159,6 +209,14 @@ function handleDeviceMessage$1(message) {
159
209
  entry.deliver(message);
160
210
  return;
161
211
  }
212
+ if (message.type === "plugin-push-result") {
213
+ const entry = pendingPushes.get(message.id);
214
+ if (!entry) return;
215
+ clearTimeout(entry.timer);
216
+ pendingPushes.delete(message.id);
217
+ entry.deliver(message);
218
+ return;
219
+ }
162
220
  if (message.type === "log") {
163
221
  for (const socket of state$2.controllers) socket.send(JSON.stringify(message));
164
222
  for (const listener of logListeners) listener(message);
@@ -301,13 +359,11 @@ function splitTopLevel(input) {
301
359
  case ")":
302
360
  depth--;
303
361
  break;
304
- case ",":
305
- if (depth === 0) {
306
- segments.push(input.slice(start, i));
307
- if (input[i + 1] === " ") i++;
308
- start = i + 1;
309
- }
310
- break;
362
+ case ",": if (depth === 0) {
363
+ segments.push(input.slice(start, i));
364
+ if (input[i + 1] === " ") i++;
365
+ start = i + 1;
366
+ }
311
367
  }
312
368
  }
313
369
  if (depth !== 0 || inString) return null;
@@ -352,7 +408,7 @@ function printBanner(deviceAddress, mcpAddress) {
352
408
  value: mcpAddress
353
409
  }];
354
410
  const longest = Math.max(18, ...lines.map((l) => rowText(l).length));
355
- const available = terminalWidth() - 2 - PADDING * 2;
411
+ const available = terminalWidth() - 2 - 4;
356
412
  const inner = Math.min(longest, MAX_WIDTH, available);
357
413
  if (inner < MIN_BOX_WIDTH || inner < longest) {
358
414
  printFallback(title, lines);
@@ -366,7 +422,7 @@ function rowText(line) {
366
422
  }
367
423
  function printBox(title, lines, inner) {
368
424
  const pad = " ".repeat(PADDING);
369
- const horizontal = "─".repeat(inner + PADDING * 2);
425
+ const horizontal = "─".repeat(inner + 4);
370
426
  rgb(PINK, `╭${horizontal}╮\n`);
371
427
  rgb(PINK, `│${pad}`);
372
428
  boldRgb(PINK, center(title, inner));
@@ -532,8 +588,11 @@ function handleDeviceMessage(raw) {
532
588
  }
533
589
  function handleControllerMessage(ws, raw) {
534
590
  const message = parseMessage(raw);
535
- if (message?.type !== "eval") return;
536
- evaluateForController(ws, message.id, message.code);
591
+ if (message?.type === "eval") {
592
+ evaluateForController(ws, message.id, message.code);
593
+ return;
594
+ }
595
+ if (message?.type === "plugin-push") pushPluginForController(ws, message);
537
596
  }
538
597
  function getLocalAddress() {
539
598
  const interfaces = os.networkInterfaces();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unbound-app/debugger",
3
- "version": "0.1.4",
3
+ "version": "0.4.0",
4
4
  "description": "A REPL debugger for @unbound-app/client runtime instances.",
5
5
  "author": {
6
6
  "name": "Mario P.",
@@ -24,7 +24,7 @@
24
24
  "build": "tsdown"
25
25
  },
26
26
  "dependencies": {
27
- "@unbound-app/debugger-protocol": "0.1.3",
27
+ "@unbound-app/debugger-protocol": "0.4.0",
28
28
  "cleye": "^1.3.4",
29
29
  "terminal-kit": "^3.1.2"
30
30
  },