Reinstate ws WebSocket library
All checks were successful
Node.js CI / build (18.x) (push) Successful in 16m17s
Node.js CI / build (20.x) (push) Successful in 11s
Node.js CI / build (22.x) (push) Successful in 11s

In some environments, such as MagicMirror modules, the WebSocket class is not defined. This is apparently a client-only class and generally only exists in browsers, but I'm confused how the unit tests were passing when run against just node. Either way, this means we have to disable the test again since ws is not compatible with jest-websocket-mock, and I haven't found an alternative mock server that is.
This commit is contained in:
2025-01-25 12:06:01 -06:00
parent 829a90dd0e
commit 458048b58a
9 changed files with 126 additions and 59 deletions

View File

@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v0.4.0] - 2025-01-25
### Changed
- Reinstated the websocket library being used. In some cases, such as MagicMirror modules, the WebSocket class is not available.
## [v0.3.0] - 2025-01-15
### Changed

View File

@ -1,4 +1,37 @@
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
@ -6,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.Unit = void 0;
const events_1 = require("events");
const debug_1 = __importDefault(require("debug"));
const ws = __importStar(require("ws"));
const debugUnit = (0, debug_1.default)("ic:unit");
/**
* Contains methods to connect to and communicate with an IntelliCenter controller.
@ -46,20 +80,20 @@ class Unit extends events_1.EventEmitter {
throw new Error("can't open a client that is already open");
}
debugUnit(`connecting to ws://${this.endpoint}:${this.port.toString()}`);
this.client = new WebSocket(`ws://${this.endpoint}:${this.port.toString()}`);
this.client = new ws.WebSocket(`ws://${this.endpoint}:${this.port.toString()}`);
const { onOpen, onError, onClientMessage, socketCleanup } = this;
this.client.addEventListener("error", onError);
this.client.addEventListener("open", onOpen);
this.client.addEventListener("close", socketCleanup);
this.client.addEventListener("message", onClientMessage);
this.client.on("error", onError);
this.client.on("open", onOpen);
this.client.on("close", socketCleanup);
this.client.on("message", onClientMessage);
this.pingTimer = setInterval(() => {
debugUnit("sending ping");
// this isn't an actual command that is recognized by the system, we just want to make sure they're still there.
this.client?.send(JSON.stringify({ command: "ping" }));
}, this.pingInterval);
await new Promise((resolve, reject) => {
this.client?.addEventListener("error", reject, true);
this.client?.addEventListener("open", resolve, true);
this.client?.once("error", reject);
this.client?.once("open", resolve);
});
debugUnit("connected");
this.emit("connected");
@ -87,10 +121,7 @@ class Unit extends events_1.EventEmitter {
socketCleanup = () => {
debugUnit("socket cleanup");
this.emit("close");
this.client?.removeEventListener("error", this.onError);
this.client?.removeEventListener("open", this.onOpen);
this.client?.removeEventListener("close", this.socketCleanup);
this.client?.removeEventListener("message", this.onClientMessage);
this.client?.removeAllListeners();
this.client = undefined;
if (this.pingTimeout) {
clearTimeout(this.pingTimeout);
@ -116,11 +147,10 @@ class Unit extends events_1.EventEmitter {
this.socketCleanup();
}, this.pingInterval + 5000);
};
onClientMessage = (evt) => {
const msg = evt.data;
onClientMessage = (msg) => {
debugUnit("message received, length %d", msg.length);
this.heartbeat();
const respObj = JSON.parse(msg);
const respObj = JSON.parse(msg.toString());
if (respObj.command.toLowerCase() === "notifylist") {
debugUnit(" it's a subscription confirmation or update");
this.emit(`notify`, respObj);

View File

@ -1 +1 @@
{"version":3,"file":"unit.js","sourceRoot":"","sources":["../src/unit.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"unit.js","sourceRoot":"","sources":["../src/unit.ts"],"names":[],"mappings":"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"}

View File

@ -1,5 +1,6 @@
import { EventEmitter } from "events";
import debug from "debug";
import * as ws from "ws";
const debugUnit = debug("ic:unit");
/**
* Contains methods to connect to and communicate with an IntelliCenter controller.
@ -40,20 +41,20 @@ export class Unit extends EventEmitter {
throw new Error("can't open a client that is already open");
}
debugUnit(`connecting to ws://${this.endpoint}:${this.port.toString()}`);
this.client = new WebSocket(`ws://${this.endpoint}:${this.port.toString()}`);
this.client = new ws.WebSocket(`ws://${this.endpoint}:${this.port.toString()}`);
const { onOpen, onError, onClientMessage, socketCleanup } = this;
this.client.addEventListener("error", onError);
this.client.addEventListener("open", onOpen);
this.client.addEventListener("close", socketCleanup);
this.client.addEventListener("message", onClientMessage);
this.client.on("error", onError);
this.client.on("open", onOpen);
this.client.on("close", socketCleanup);
this.client.on("message", onClientMessage);
this.pingTimer = setInterval(() => {
debugUnit("sending ping");
// this isn't an actual command that is recognized by the system, we just want to make sure they're still there.
this.client?.send(JSON.stringify({ command: "ping" }));
}, this.pingInterval);
await new Promise((resolve, reject) => {
this.client?.addEventListener("error", reject, true);
this.client?.addEventListener("open", resolve, true);
this.client?.once("error", reject);
this.client?.once("open", resolve);
});
debugUnit("connected");
this.emit("connected");
@ -81,10 +82,7 @@ export class Unit extends EventEmitter {
socketCleanup = () => {
debugUnit("socket cleanup");
this.emit("close");
this.client?.removeEventListener("error", this.onError);
this.client?.removeEventListener("open", this.onOpen);
this.client?.removeEventListener("close", this.socketCleanup);
this.client?.removeEventListener("message", this.onClientMessage);
this.client?.removeAllListeners();
this.client = undefined;
if (this.pingTimeout) {
clearTimeout(this.pingTimeout);
@ -110,11 +108,10 @@ export class Unit extends EventEmitter {
this.socketCleanup();
}, this.pingInterval + 5000);
};
onClientMessage = (evt) => {
const msg = evt.data;
onClientMessage = (msg) => {
debugUnit("message received, length %d", msg.length);
this.heartbeat();
const respObj = JSON.parse(msg);
const respObj = JSON.parse(msg.toString());
if (respObj.command.toLowerCase() === "notifylist") {
debugUnit(" it's a subscription confirmation or update");
this.emit(`notify`, respObj);

View File

@ -1 +1 @@
{"version":3,"file":"unit.js","sourceRoot":"","sources":["../src/unit.ts"],"names":[],"mappings":"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"}
{"version":3,"file":"unit.js","sourceRoot":"","sources":["../src/unit.ts"],"names":[],"mappings":"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"}

39
package-lock.json generated
View File

@ -1,16 +1,17 @@
{
"name": "node-intellicenter",
"version": "0.3.0",
"version": "0.4.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "node-intellicenter",
"version": "0.3.0",
"version": "0.4.0",
"license": "MIT",
"dependencies": {
"debug": "^4.4.0",
"uuid": "^11.0.3"
"uuid": "^11.0.3",
"ws": "^8.18.0"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
@ -18,6 +19,7 @@
"@types/jest": "^29.5.14",
"@types/minimist": "^1.2.5",
"@types/uuid": "^10.0.0",
"@types/ws": "^8.5.14",
"eslint": "^9.17.0",
"jest": "^29.7.0",
"jest-websocket-mock": "^2.5.0",
@ -1516,6 +1518,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/ws": {
"version": "8.5.14",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz",
"integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/yargs": {
"version": "17.0.33",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
@ -6176,6 +6188,27 @@
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
}
},
"node_modules/ws": {
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",

View File

@ -1,6 +1,6 @@
{
"name": "node-intellicenter",
"version": "0.3.0",
"version": "0.4.0",
"description": "NodeJS library for communicating with a Pentair IntelliCenter controller",
"keywords": [
"pentair",
@ -81,7 +81,8 @@
},
"dependencies": {
"debug": "^4.4.0",
"uuid": "^11.0.3"
"uuid": "^11.0.3",
"ws": "^8.18.0"
},
"devDependencies": {
"@eslint/js": "^9.17.0",
@ -89,6 +90,7 @@
"@types/jest": "^29.5.14",
"@types/minimist": "^1.2.5",
"@types/uuid": "^10.0.0",
"@types/ws": "^8.5.14",
"eslint": "^9.17.0",
"jest": "^29.7.0",
"jest-websocket-mock": "^2.5.0",

View File

@ -3,6 +3,7 @@ import debug from "debug";
import { ICRequest } from "./messages/request.js";
import { ICResponse } from "./messages/response.js";
import * as ws from "ws";
// needed for jsdoc
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import * as messages from "./messages/messages.js";
@ -29,7 +30,7 @@ const debugUnit = debug("ic:unit");
* * `"connected"` - fired when a connection has completed successfully
*/
export class Unit extends EventEmitter {
private client?: WebSocket;
private client?: ws.WebSocket;
private pingTimeout?: ReturnType<typeof setTimeout>;
private pingTimer?: ReturnType<typeof setInterval>;
private pingInterval = 60000;
@ -54,15 +55,15 @@ export class Unit extends EventEmitter {
debugUnit(`connecting to ws://${this.endpoint}:${this.port.toString()}`);
this.client = new WebSocket(
this.client = new ws.WebSocket(
`ws://${this.endpoint}:${this.port.toString()}`,
);
const { onOpen, onError, onClientMessage, socketCleanup } = this;
this.client.addEventListener("error", onError);
this.client.addEventListener("open", onOpen);
this.client.addEventListener("close", socketCleanup);
this.client.addEventListener("message", onClientMessage);
this.client.on("error", onError);
this.client.on("open", onOpen);
this.client.on("close", socketCleanup);
this.client.on("message", onClientMessage);
this.pingTimer = setInterval(() => {
debugUnit("sending ping");
@ -71,8 +72,8 @@ export class Unit extends EventEmitter {
}, this.pingInterval);
await new Promise((resolve, reject) => {
this.client?.addEventListener("error", reject, true);
this.client?.addEventListener("open", resolve, true);
this.client?.once("error", reject);
this.client?.once("open", resolve);
});
debugUnit("connected");
@ -84,7 +85,7 @@ export class Unit extends EventEmitter {
this.heartbeat();
};
private onError = (evt: Event) => {
private onError = (evt: ws.ErrorEvent) => {
// todo: emit event so we can reconnect? auto reconnect?
debugUnit("error in websocket: $o", evt);
this.emit("error", evt);
@ -107,10 +108,7 @@ export class Unit extends EventEmitter {
debugUnit("socket cleanup");
this.emit("close");
this.client?.removeEventListener("error", this.onError);
this.client?.removeEventListener("open", this.onOpen);
this.client?.removeEventListener("close", this.socketCleanup);
this.client?.removeEventListener("message", this.onClientMessage);
this.client?.removeAllListeners();
this.client = undefined;
if (this.pingTimeout) {
@ -140,12 +138,11 @@ export class Unit extends EventEmitter {
}, this.pingInterval + 5000);
};
private onClientMessage = (evt: MessageEvent) => {
const msg = evt.data as string;
private onClientMessage = (msg: Buffer) => {
debugUnit("message received, length %d", msg.length);
this.heartbeat();
const respObj = JSON.parse(msg) as ICResponse;
const respObj = JSON.parse(msg.toString()) as ICResponse;
if (respObj.command.toLowerCase() === "notifylist") {
debugUnit(" it's a subscription confirmation or update");
this.emit(`notify`, respObj);

View File

@ -1,6 +1,7 @@
import { Unit } from "../src/index";
import * as messages from "../src/messages/messages";
import WS from "jest-websocket-mock";
import { Unit } from "../src/index.js";
import * as messages from "../src/messages/messages.js";
import * as WS from "jest-websocket-mock";
import { xdescribe, beforeEach, afterEach, it } from "@jest/globals";
function makeid(length: number) {
const characters =
@ -17,20 +18,21 @@ function makeid(length: number) {
return result;
}
describe("basic message tests", () => {
// temporarily disabled: as long as Unit uses the "ws" library, it is incompatible with the jest-websocket-mock server
xdescribe("basic message tests", () => {
let unit: Unit;
let mockServer: WS;
let mockServer: WS.WS;
beforeEach(async () => {
mockServer = new WS("ws://localhost:6680");
mockServer = new WS.WS("ws://localhost:6680");
unit = new Unit("localhost", 6680);
await unit.connect();
await mockServer.connected;
});
afterEach(async () => {
afterEach(() => {
unit.close();
WS.clean();
WS.WS.clean();
});
it("can send a message and return its response", async () => {