@blueyerobotics/blueye-ts 1.0.0 → 1.2.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.
@@ -16,13 +16,14 @@ export type Events = {
16
16
  };
17
17
  export declare const isInProtocol: (key: string) => key is keyof typeof blueye.protocol;
18
18
  export declare class BlueyeClient {
19
+ timeout: number;
19
20
  private wsPubSub;
20
21
  private wsReqRep;
21
22
  private isReqRepConnected;
22
23
  private logger;
24
+ private pendingRequests;
23
25
  sub: Emitter<Events>;
24
- constructor(logLevel?: LogLevel);
25
- private send;
26
+ constructor(timeout?: number, logLevel?: LogLevel);
26
27
  sendRequest<T extends Req>(req: T, opts?: CreateArgs<T>): Promise<DecodedOutput<T> | null>;
27
28
  getTelemetry<T extends Tel>(type: T): Promise<DecodedTelOutput<T>>;
28
29
  }
@@ -5,6 +5,7 @@ const protocol_definitions_1 = require("@blueyerobotics/protocol-definitions");
5
5
  const buffer_1 = require("buffer");
6
6
  const consola_1 = require("consola");
7
7
  const strict_event_emitter_1 = require("strict-event-emitter");
8
+ const uuid_1 = require("uuid");
8
9
  const schema_1 = require("./schema");
9
10
  const WS_PUBSUB_URL = "ws://localhost:8765";
10
11
  const WS_REQREP_URL = "ws://localhost:8766";
@@ -13,12 +14,15 @@ const isInProtocol = (key) => {
13
14
  };
14
15
  exports.isInProtocol = isInProtocol;
15
16
  class BlueyeClient {
17
+ timeout;
16
18
  wsPubSub;
17
19
  wsReqRep;
18
20
  isReqRepConnected = false;
19
21
  logger;
22
+ pendingRequests = new Map();
20
23
  sub = new strict_event_emitter_1.Emitter();
21
- constructor(logLevel = consola_1.LogLevels.info) {
24
+ constructor(timeout = 2000, logLevel = consola_1.LogLevels.info) {
25
+ this.timeout = timeout;
22
26
  this.logger = (0, consola_1.createConsola)({ level: logLevel, formatOptions: { colors: true, compact: false } });
23
27
  this.wsPubSub = new WebSocket(WS_PUBSUB_URL);
24
28
  this.wsReqRep = new WebSocket(WS_REQREP_URL);
@@ -36,41 +40,36 @@ class BlueyeClient {
36
40
  this.logger.verbose("[WS] PubSub message:", key, message);
37
41
  this.sub.emit(key, message);
38
42
  });
39
- }
40
- async send(data) {
41
- while (!this.isReqRepConnected) {
42
- this.logger.debug("Waiting...");
43
- await new Promise(res => setTimeout(res, 50));
44
- }
45
- return await new Promise((resolve, reject) => {
46
- const onMessage = (event) => {
47
- cleanUp();
48
- resolve(event.data);
49
- };
50
- const onError = (error) => {
51
- cleanUp();
52
- this.logger.error("[WS] Error:", error);
53
- reject(error);
54
- };
55
- const cleanUp = () => {
56
- this.wsReqRep.removeEventListener("message", onMessage);
57
- this.wsReqRep.removeEventListener("error", onError);
58
- };
59
- this.wsReqRep.addEventListener("message", onMessage);
60
- this.wsReqRep.addEventListener("error", onError);
61
- this.wsReqRep.send(data);
43
+ this.wsReqRep.addEventListener("message", event => {
44
+ this.logger.debug("Response:", event.data);
45
+ const { id, key, data } = schema_1.responseSchema.parse(JSON.parse(event.data));
46
+ if (!id)
47
+ throw new Error("Response id is missing");
48
+ this.pendingRequests.get(id)?.({ key, data });
62
49
  });
63
50
  }
64
51
  async sendRequest(req, opts = {}) {
65
52
  const protocol = protocol_definitions_1.blueye.protocol[req];
66
53
  const message = protocol.create(opts);
67
54
  const encoded = protocol.encode(message).finish();
68
- const response = await this.send(JSON.stringify({
69
- key: `blueye.protocol.${req}`,
70
- data: buffer_1.Buffer.from(encoded).toString("base64")
71
- }));
72
- this.logger.debug("Response:", response);
73
- const { key, data } = schema_1.responseSchema.parse(JSON.parse(response));
55
+ while (!this.isReqRepConnected) {
56
+ this.logger.debug("Waiting...");
57
+ await new Promise(res => setTimeout(res, 50));
58
+ }
59
+ const id = (0, uuid_1.v4)();
60
+ const { key, data } = await Promise.race([
61
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Request timed out")), this.timeout)),
62
+ new Promise(resolve => {
63
+ const request = JSON.stringify({
64
+ id,
65
+ key: `blueye.protocol.${req}`,
66
+ data: buffer_1.Buffer.from(encoded).toString("base64")
67
+ });
68
+ this.pendingRequests.set(id, resolve);
69
+ this.wsReqRep.send(request);
70
+ })
71
+ ]);
72
+ this.pendingRequests.delete(id);
74
73
  if (key === "Empty") {
75
74
  return null;
76
75
  }
@@ -1,14 +1,17 @@
1
1
  import { Buffer } from "buffer";
2
2
  import z from "zod";
3
3
  export declare const responseSchema: z.ZodObject<{
4
+ id: z.ZodOptional<z.ZodString>;
4
5
  key: z.ZodEffects<z.ZodString, string, string>;
5
6
  data: z.ZodEffects<z.ZodString, Buffer, string>;
6
7
  }, "strip", z.ZodTypeAny, {
7
8
  key: string;
8
9
  data: Buffer;
10
+ id?: string | undefined;
9
11
  }, {
10
12
  key: string;
11
13
  data: string;
14
+ id?: string | undefined;
12
15
  }>;
13
16
  export declare const telemetrySchema: z.ZodObject<{
14
17
  payload: z.ZodObject<{
@@ -7,6 +7,7 @@ exports.telemetrySchema = exports.responseSchema = void 0;
7
7
  const buffer_1 = require("buffer");
8
8
  const zod_1 = __importDefault(require("zod"));
9
9
  exports.responseSchema = zod_1.default.object({
10
+ id: zod_1.default.string().uuid().optional(),
10
11
  key: zod_1.default.string().transform(val => val.split(".").at(-1)),
11
12
  data: zod_1.default
12
13
  .string()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blueyerobotics/blueye-ts",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "A TypeScript client for interacting with Blueye underwater drones.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,11 +17,13 @@
17
17
  },
18
18
  "keywords": [],
19
19
  "author": "Blueye <contact@blueye.no> (https://blueye.no/)",
20
+ "license": "LGPL-3.0-only",
20
21
  "dependencies": {
21
22
  "@blueyerobotics/protocol-definitions": "3.2.0-3e0ba702",
22
23
  "buffer": "^6.0.3",
23
24
  "consola": "^3.4.2",
24
25
  "strict-event-emitter": "^0.5.1",
26
+ "uuid": "^11.1.0",
25
27
  "zod": "^3.25.67"
26
28
  },
27
29
  "devDependencies": {