@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.
- package/dist/index.mjs +70 -11
- 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
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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 -
|
|
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 +
|
|
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
|
|
536
|
-
|
|
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.
|
|
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.
|
|
27
|
+
"@unbound-app/debugger-protocol": "0.4.0",
|
|
28
28
|
"cleye": "^1.3.4",
|
|
29
29
|
"terminal-kit": "^3.1.2"
|
|
30
30
|
},
|