Fix Track.lookAt crash and fetchBuffer hang; bump to 2.0.1
- Track.lookAt: was calling client.user.lookAtEntity (undefined), now correctly routes to client.behavior.lookAtEntity — fixes unhandled promise rejections on every face-detection event - connection: httpGet/httpGetStream had no socket timeout; added 15 s req.setTimeout so fetchBuffer/pipe reject instead of hanging forever - connection: _txSend silently dropped commands when session not yet ready and returned a dead txId, causing callers to hang for the full timeout; now throws immediately with code NOT_READY Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2
API.md
2
API.md
@@ -1,6 +1,6 @@
|
||||
# rom-control
|
||||
|
||||
Discord.js-style OOP client for the Jibo ROM WebSocket API (port 8160).
|
||||
Robust client for the Jibo ROM WebSocket API (port 8160).
|
||||
|
||||
**Requires:** Node.js ≥ 16, `ws` ^8.14.2
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "rom-control",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.1",
|
||||
"description": "Discord.js-style OOP client for the Jibo ROM WebSocket API",
|
||||
"main": "./index.js",
|
||||
"exports": {
|
||||
|
||||
@@ -41,24 +41,30 @@ function httpPost(host, port, path, body) {
|
||||
});
|
||||
}
|
||||
|
||||
function httpGet(host, port, path) {
|
||||
function httpGet(host, port, path, timeoutMs = 15000) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunks = [];
|
||||
const req = http.get({ host, port, path }, (res) => {
|
||||
res.on('data', d => chunks.push(d));
|
||||
res.on('end', () => resolve(Buffer.concat(chunks)));
|
||||
});
|
||||
req.setTimeout(timeoutMs, () => {
|
||||
req.destroy(Object.assign(new Error('fetchMedia timed out'), { code: 'FETCH_TIMEOUT' }));
|
||||
});
|
||||
req.on('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
function httpGetStream(host, port, path, dest) {
|
||||
function httpGetStream(host, port, path, dest, timeoutMs = 15000) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = http.get({ host, port, path }, (res) => {
|
||||
res.pipe(dest);
|
||||
res.on('end', resolve);
|
||||
dest.on('close', () => req.destroy());
|
||||
});
|
||||
req.setTimeout(timeoutMs, () => {
|
||||
req.destroy(Object.assign(new Error('fetchMediaStream timed out'), { code: 'FETCH_TIMEOUT' }));
|
||||
});
|
||||
req.on('error', reject);
|
||||
});
|
||||
}
|
||||
@@ -323,7 +329,9 @@ class RomConnection extends EventEmitter {
|
||||
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
||||
// Don't send any command except StartSession before the session ID arrives.
|
||||
// Commands sent with an empty SessionID are rejected by ROM with 403 Forbidden.
|
||||
if (!this.sessionID && command.Type !== 'StartSession') return txId;
|
||||
if (!this.sessionID && command.Type !== 'StartSession') {
|
||||
throw Object.assign(new Error(`Cannot send ${command.Type}: session not ready`), { code: 'NOT_READY' });
|
||||
}
|
||||
|
||||
this._txCommands.set(txId, command.Type);
|
||||
if (this._txCommands.size > 60) {
|
||||
|
||||
@@ -14,7 +14,7 @@ class Track {
|
||||
|
||||
// Look at this entity. Resolves when the head reaches the target.
|
||||
async lookAt(track = true) {
|
||||
return this._client.user.lookAtEntity(this.id, track);
|
||||
return this._client.behavior.lookAtEntity(this.id, track);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user