diff --git a/apis/websocket/src/classes/Client.ts b/apis/websocket/src/classes/Client.ts index 8eda488..defe268 100755 --- a/apis/websocket/src/classes/Client.ts +++ b/apis/websocket/src/classes/Client.ts @@ -34,14 +34,10 @@ export default class Client { op: ServerOperation.Hello, d: null, }) - .then(() => { - this._listen() - this.ready = true - this.#emitter.emit('ready') - }) - .catch(() => { - this.disconnect(DisconnectReason.ServerError) - }) + + this._listen() + this.ready = true + this.#emitter.emit('ready') } on(name: TOpName, handler: ClientEventHandlers[typeof name]) { @@ -57,12 +53,9 @@ export default class Client { } send(packet: Omit, 's'>, sequence?: number) { - return new Promise((resolve, reject) => { - this.#throwIfDisconnected('Cannot send packet to client that has already disconnected') - this.#socket.send( - serializePacket({ ...packet, s: sequence ?? this.currentSequence++ } as Packet), - err => (err ? reject(err) : resolve()), - ) + this.#throwIfDisconnected('Cannot send packet to client that has already disconnected') + this.#socket.send(serializePacket({ ...packet, s: sequence ?? this.currentSequence++ } as Packet), err => { + throw err }) } diff --git a/packages/api/src/classes/Client.ts b/packages/api/src/classes/Client.ts index c645aa5..6fc2bb3 100755 --- a/packages/api/src/classes/Client.ts +++ b/packages/api/src/classes/Client.ts @@ -39,33 +39,31 @@ export default class Client { async parseText(text: string) { this.#throwIfNotReady() - return await this.ws - .send({ - op: ClientOperation.ParseText, - d: { - text, - }, - }) - .then(() => { - // Since we don't have heartbeats anymore, this is fine. - // But if we add anything similar, this will cause another race condition - // To fix this, we can try adding a instanced function that would return the currentSequence - // and it would be updated every time a "heartbeat ack" packet is received - const expectedNextSeq = this.ws.currentSequence + 1 - const awaitPkt = (op: ServerOperation, timeout = this.ws.timeout) => - awaitPacket(this.ws, op, expectedNextSeq, timeout) + this.ws.send({ + op: ClientOperation.ParseText, + d: { + text, + }, + }) - return Promise.race([ - awaitPkt(ServerOperation.ParsedText), - awaitPkt(ServerOperation.ParseTextFailed, this.ws.timeout + 5000), - ]) - .then(pkt => { - if (pkt.op === ServerOperation.ParsedText) return pkt.d - throw new Error('Failed to parse text, the API encountered an error') - }) - .catch(() => { - throw new Error('Failed to parse text, the API did not respond in time') - }) + // Since we don't have heartbeats anymore, this is fine. + // But if we add anything similar, this will cause another race condition + // To fix this, we can try adding a instanced function that would return the currentSequence + // and it would be updated every time a "heartbeat ack" packet is received + const expectedNextSeq = this.ws.currentSequence + 1 + const awaitPkt = (op: ServerOperation, timeout = this.ws.timeout) => + awaitPacket(this.ws, op, expectedNextSeq, timeout) + + return Promise.race([ + awaitPkt(ServerOperation.ParsedText), + awaitPkt(ServerOperation.ParseTextFailed, this.ws.timeout + 5000), + ]) + .then(pkt => { + if (pkt.op === ServerOperation.ParsedText) return pkt.d + throw new Error('Failed to parse text, the API encountered an error') + }) + .catch(() => { + throw new Error('Failed to parse text, the API did not respond in time') }) } @@ -77,61 +75,57 @@ export default class Client { async parseImage(url: string) { this.#throwIfNotReady() - return await this.ws - .send({ - op: ClientOperation.ParseImage, - d: { - image_url: url, - }, - }) - .then(() => { - // See line 48 - const expectedNextSeq = this.ws.currentSequence + 1 - const awaitPkt = (op: ServerOperation, timeout = this.ws.timeout) => - awaitPacket(this.ws, op, expectedNextSeq, timeout) + this.ws.send({ + op: ClientOperation.ParseImage, + d: { + image_url: url, + }, + }) - return Promise.race([ - awaitPkt(ServerOperation.ParsedImage), - awaitPkt(ServerOperation.ParseImageFailed, this.ws.timeout + 5000), - ]) - .then(pkt => { - if (pkt.op === ServerOperation.ParsedImage) return pkt.d - throw new Error('Failed to parse image, the API encountered an error') - }) - .catch(() => { - throw new Error('Failed to parse image, the API did not respond in time') - }) + // See line 48 + const expectedNextSeq = this.ws.currentSequence + 1 + const awaitPkt = (op: ServerOperation, timeout = this.ws.timeout) => + awaitPacket(this.ws, op, expectedNextSeq, timeout) + + return Promise.race([ + awaitPkt(ServerOperation.ParsedImage), + awaitPkt(ServerOperation.ParseImageFailed, this.ws.timeout + 5000), + ]) + .then(pkt => { + if (pkt.op === ServerOperation.ParsedImage) return pkt.d + throw new Error('Failed to parse image, the API encountered an error') + }) + .catch(() => { + throw new Error('Failed to parse image, the API did not respond in time') }) } async trainMessage(text: string, label: string) { this.#throwIfNotReady() - return await this.ws - .send({ - op: ClientOperation.TrainMessage, - d: { - label, - text, - }, - }) - .then(() => { - // See line 48 - const expectedNextSeq = this.ws.currentSequence + 1 - const awaitPkt = (op: ServerOperation, timeout = this.ws.timeout) => - awaitPacket(this.ws, op, expectedNextSeq, timeout) + this.ws.send({ + op: ClientOperation.TrainMessage, + d: { + label, + text, + }, + }) - return Promise.race([ - awaitPkt(ServerOperation.TrainedMessage), - awaitPkt(ServerOperation.TrainMessageFailed, this.ws.timeout + 5000), - ]) - .then(pkt => { - if (pkt.op === ServerOperation.TrainedMessage) return - throw new Error('Failed to train message, the API encountered an error') - }) - .catch(() => { - throw new Error('Failed to train message, the API did not respond in time') - }) + // See line 48 + const expectedNextSeq = this.ws.currentSequence + 1 + const awaitPkt = (op: ServerOperation, timeout = this.ws.timeout) => + awaitPacket(this.ws, op, expectedNextSeq, timeout) + + return Promise.race([ + awaitPkt(ServerOperation.TrainedMessage), + awaitPkt(ServerOperation.TrainMessageFailed, this.ws.timeout + 5000), + ]) + .then(pkt => { + if (pkt.op === ServerOperation.TrainedMessage) return + throw new Error('Failed to train message, the API encountered an error') + }) + .catch(() => { + throw new Error('Failed to train message, the API did not respond in time') }) } diff --git a/packages/api/src/classes/ClientWebSocket.ts b/packages/api/src/classes/ClientWebSocket.ts index 34847f6..f5b960e 100755 --- a/packages/api/src/classes/ClientWebSocket.ts +++ b/packages/api/src/classes/ClientWebSocket.ts @@ -49,6 +49,7 @@ export class ClientWebSocketManager { }, this.timeout) this.#socket.on('open', () => { + this.disconnected = false clearTimeout(timeout) this.#listen() rs() @@ -107,9 +108,9 @@ export class ClientWebSocketManager { send(packet: Packet) { this.#throwIfDisconnected('Cannot send a packet when already disconnected from the server') - return new Promise((resolve, reject) => - this.#socket.send(serializePacket(packet), err => (err ? reject(err) : resolve())), - ) + this.#socket.send(serializePacket(packet), err => { + throw err + }) } /**