Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

home-assistant-js-websocket

Package Overview
Dependencies
Maintainers
2
Versions
102
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

home-assistant-js-websocket - npm Package Compare versions

Comparing version 5.11.3 to 5.12.0

5

dist/connection.d.ts

@@ -46,2 +46,7 @@ import { ERR_CONNECTION_LOST } from "./errors.js";

suspend(): void;
/**
* Reconnect the websocket connection.
* @param force discard old socket instead of gracefully closing it.
*/
reconnect(force?: boolean): void;
close(): void;

@@ -48,0 +53,0 @@ /**

216

dist/connection.js

@@ -10,2 +10,101 @@ /**

constructor(socket, options) {
this._handleMessage = (event) => {
const message = JSON.parse(event.data);
if (DEBUG) {
console.log("Received", message);
}
const info = this.commands.get(message.id);
switch (message.type) {
case "event":
if (info) {
info.callback(message.event);
}
else {
console.warn(`Received event for unknown subscription ${message.id}. Unsubscribing.`);
this.sendMessagePromise(messages.unsubscribeEvents(message.id));
}
break;
case "result":
// No info is fine. If just sendMessage is used, we did not store promise for result
if (info) {
if (message.success) {
info.resolve(message.result);
// Don't remove subscriptions.
if (!("subscribe" in info)) {
this.commands.delete(message.id);
}
}
else {
info.reject(message.error);
this.commands.delete(message.id);
}
}
break;
case "pong":
if (info) {
info.resolve();
this.commands.delete(message.id);
}
else {
console.warn(`Received unknown pong response ${message.id}`);
}
break;
default:
if (DEBUG) {
console.warn("Unhandled message", message);
}
}
};
this._handleClose = async () => {
// Reject in-flight sendMessagePromise requests
this.commands.forEach((info) => {
// We don't cancel subscribeEvents commands in flight
// as we will be able to recover them.
if (!("subscribe" in info)) {
info.reject(messages.error(ERR_CONNECTION_LOST, "Connection lost"));
}
});
if (this.closeRequested) {
return;
}
this.fireEvent("disconnected");
// Disable setupRetry, we control it here with auto-backoff
const options = Object.assign(Object.assign({}, this.options), { setupRetry: 0 });
const reconnect = (tries) => {
setTimeout(async () => {
if (DEBUG) {
console.log("Trying to reconnect");
}
try {
const socket = await options.createSocket(options);
this.setSocket(socket);
}
catch (err) {
if (this._queuedMessages) {
const queuedMessages = this._queuedMessages;
this._queuedMessages = undefined;
for (const msg of queuedMessages) {
if (msg.reject) {
msg.reject(ERR_CONNECTION_LOST);
}
}
}
if (err === ERR_INVALID_AUTH) {
this.fireEvent("reconnect-error", err);
}
else {
reconnect(tries + 1);
}
}
}, Math.min(tries, 5) * 1000);
};
if (this.suspendReconnectPromise) {
await this.suspendReconnectPromise;
this.suspendReconnectPromise = undefined;
// For the first retry after suspend, we will queue up
// all messages.
this._queuedMessages = [];
}
reconnect(0);
};
// connection options

@@ -35,4 +134,4 @@ // - setupRetry: amount of ms to retry when unable to connect on initial setup

this.socket = socket;
socket.addEventListener("message", (ev) => this._handleMessage(ev));
socket.addEventListener("close", (ev) => this._handleClose(ev));
socket.addEventListener("message", this._handleMessage);
socket.addEventListener("close", this._handleClose);
if (oldSocket) {

@@ -94,2 +193,16 @@ const oldCommands = this.commands;

}
/**
* Reconnect the websocket connection.
* @param force discard old socket instead of gracefully closing it.
*/
reconnect(force = false) {
if (!force) {
this.socket.close();
return;
}
this.socket.removeEventListener("message", this._handleMessage);
this.socket.removeEventListener("close", this._handleClose);
this.socket.close();
this._handleClose();
}
close() {

@@ -196,101 +309,2 @@ this.closeRequested = true;

}
_handleMessage(event) {
const message = JSON.parse(event.data);
if (DEBUG) {
console.log("Received", message);
}
const info = this.commands.get(message.id);
switch (message.type) {
case "event":
if (info) {
info.callback(message.event);
}
else {
console.warn(`Received event for unknown subscription ${message.id}. Unsubscribing.`);
this.sendMessagePromise(messages.unsubscribeEvents(message.id));
}
break;
case "result":
// No info is fine. If just sendMessage is used, we did not store promise for result
if (info) {
if (message.success) {
info.resolve(message.result);
// Don't remove subscriptions.
if (!("subscribe" in info)) {
this.commands.delete(message.id);
}
}
else {
info.reject(message.error);
this.commands.delete(message.id);
}
}
break;
case "pong":
if (info) {
info.resolve();
this.commands.delete(message.id);
}
else {
console.warn(`Received unknown pong response ${message.id}`);
}
break;
default:
if (DEBUG) {
console.warn("Unhandled message", message);
}
}
}
async _handleClose(ev) {
// Reject in-flight sendMessagePromise requests
this.commands.forEach((info) => {
// We don't cancel subscribeEvents commands in flight
// as we will be able to recover them.
if (!("subscribe" in info)) {
info.reject(messages.error(ERR_CONNECTION_LOST, "Connection lost"));
}
});
if (this.closeRequested) {
return;
}
this.fireEvent("disconnected");
// Disable setupRetry, we control it here with auto-backoff
const options = Object.assign(Object.assign({}, this.options), { setupRetry: 0 });
const reconnect = (tries) => {
setTimeout(async () => {
if (DEBUG) {
console.log("Trying to reconnect");
}
try {
const socket = await options.createSocket(options);
this.setSocket(socket);
}
catch (err) {
if (this._queuedMessages) {
const queuedMessages = this._queuedMessages;
this._queuedMessages = undefined;
for (const msg of queuedMessages) {
if (msg.reject) {
msg.reject(ERR_CONNECTION_LOST);
}
}
}
if (err === ERR_INVALID_AUTH) {
this.fireEvent("reconnect-error", err);
}
else {
reconnect(tries + 1);
}
}
}, Math.min(tries, 5) * 1000);
};
if (this.suspendReconnectPromise) {
await this.suspendReconnectPromise;
this.suspendReconnectPromise = undefined;
// For the first retry after suspend, we will queue up
// all messages.
this._queuedMessages = [];
}
reconnect(0);
}
_genCmdId() {

@@ -297,0 +311,0 @@ return ++this.commandId;

@@ -170,2 +170,91 @@ (function (global, factory) {

constructor(socket, options) {
this._handleMessage = (event) => {
const message = JSON.parse(event.data);
const info = this.commands.get(message.id);
switch (message.type) {
case "event":
if (info) {
info.callback(message.event);
}
else {
console.warn(`Received event for unknown subscription ${message.id}. Unsubscribing.`);
this.sendMessagePromise(unsubscribeEvents(message.id));
}
break;
case "result":
// No info is fine. If just sendMessage is used, we did not store promise for result
if (info) {
if (message.success) {
info.resolve(message.result);
// Don't remove subscriptions.
if (!("subscribe" in info)) {
this.commands.delete(message.id);
}
}
else {
info.reject(message.error);
this.commands.delete(message.id);
}
}
break;
case "pong":
if (info) {
info.resolve();
this.commands.delete(message.id);
}
else {
console.warn(`Received unknown pong response ${message.id}`);
}
break;
}
};
this._handleClose = async () => {
// Reject in-flight sendMessagePromise requests
this.commands.forEach((info) => {
// We don't cancel subscribeEvents commands in flight
// as we will be able to recover them.
if (!("subscribe" in info)) {
info.reject(error(ERR_CONNECTION_LOST, "Connection lost"));
}
});
if (this.closeRequested) {
return;
}
this.fireEvent("disconnected");
// Disable setupRetry, we control it here with auto-backoff
const options = Object.assign(Object.assign({}, this.options), { setupRetry: 0 });
const reconnect = (tries) => {
setTimeout(async () => {
try {
const socket = await options.createSocket(options);
this.setSocket(socket);
}
catch (err) {
if (this._queuedMessages) {
const queuedMessages = this._queuedMessages;
this._queuedMessages = undefined;
for (const msg of queuedMessages) {
if (msg.reject) {
msg.reject(ERR_CONNECTION_LOST);
}
}
}
if (err === ERR_INVALID_AUTH) {
this.fireEvent("reconnect-error", err);
}
else {
reconnect(tries + 1);
}
}
}, Math.min(tries, 5) * 1000);
};
if (this.suspendReconnectPromise) {
await this.suspendReconnectPromise;
this.suspendReconnectPromise = undefined;
// For the first retry after suspend, we will queue up
// all messages.
this._queuedMessages = [];
}
reconnect(0);
};
// connection options

@@ -195,4 +284,4 @@ // - setupRetry: amount of ms to retry when unable to connect on initial setup

this.socket = socket;
socket.addEventListener("message", (ev) => this._handleMessage(ev));
socket.addEventListener("close", (ev) => this._handleClose(ev));
socket.addEventListener("message", this._handleMessage);
socket.addEventListener("close", this._handleClose);
if (oldSocket) {

@@ -254,2 +343,16 @@ const oldCommands = this.commands;

}
/**
* Reconnect the websocket connection.
* @param force discard old socket instead of gracefully closing it.
*/
reconnect(force = false) {
if (!force) {
this.socket.close();
return;
}
this.socket.removeEventListener("message", this._handleMessage);
this.socket.removeEventListener("close", this._handleClose);
this.socket.close();
this._handleClose();
}
close() {

@@ -353,91 +456,2 @@ this.closeRequested = true;

}
_handleMessage(event) {
const message = JSON.parse(event.data);
const info = this.commands.get(message.id);
switch (message.type) {
case "event":
if (info) {
info.callback(message.event);
}
else {
console.warn(`Received event for unknown subscription ${message.id}. Unsubscribing.`);
this.sendMessagePromise(unsubscribeEvents(message.id));
}
break;
case "result":
// No info is fine. If just sendMessage is used, we did not store promise for result
if (info) {
if (message.success) {
info.resolve(message.result);
// Don't remove subscriptions.
if (!("subscribe" in info)) {
this.commands.delete(message.id);
}
}
else {
info.reject(message.error);
this.commands.delete(message.id);
}
}
break;
case "pong":
if (info) {
info.resolve();
this.commands.delete(message.id);
}
else {
console.warn(`Received unknown pong response ${message.id}`);
}
break;
}
}
async _handleClose(ev) {
// Reject in-flight sendMessagePromise requests
this.commands.forEach((info) => {
// We don't cancel subscribeEvents commands in flight
// as we will be able to recover them.
if (!("subscribe" in info)) {
info.reject(error(ERR_CONNECTION_LOST, "Connection lost"));
}
});
if (this.closeRequested) {
return;
}
this.fireEvent("disconnected");
// Disable setupRetry, we control it here with auto-backoff
const options = Object.assign(Object.assign({}, this.options), { setupRetry: 0 });
const reconnect = (tries) => {
setTimeout(async () => {
try {
const socket = await options.createSocket(options);
this.setSocket(socket);
}
catch (err) {
if (this._queuedMessages) {
const queuedMessages = this._queuedMessages;
this._queuedMessages = undefined;
for (const msg of queuedMessages) {
if (msg.reject) {
msg.reject(ERR_CONNECTION_LOST);
}
}
}
if (err === ERR_INVALID_AUTH) {
this.fireEvent("reconnect-error", err);
}
else {
reconnect(tries + 1);
}
}
}, Math.min(tries, 5) * 1000);
};
if (this.suspendReconnectPromise) {
await this.suspendReconnectPromise;
this.suspendReconnectPromise = undefined;
// For the first retry after suspend, we will queue up
// all messages.
this._queuedMessages = [];
}
reconnect(0);
}
_genCmdId() {

@@ -444,0 +458,0 @@ return ++this.commandId;

@@ -5,3 +5,3 @@ {

"sideEffects": false,
"version": "5.11.3",
"version": "5.12.0",
"description": "Home Assistant websocket client",

@@ -8,0 +8,0 @@ "source": "lib/index.ts",

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc