@anephenix/sarus
Advanced tools
Comparing version 0.4.6 to 0.5.0
import { module } from "window-or-global"; | ||
export const delay = (duration: number) => | ||
new Promise((resolve) => setTimeout(resolve, duration)); | ||
new Promise((resolve) => setTimeout(resolve, duration)); |
@@ -21,2 +21,22 @@ // File Dependencies | ||
it("should correctly validate invalid WebSocket URLs", () => { | ||
// Testing with jest-websocket-mock will not give us a TypeError here. | ||
// We re-throw the error therefore. Testing it in a browser we can | ||
// see that a TypeError is handled correctly. | ||
expect(() => { | ||
new Sarus({ url: "invalid-url" }); | ||
}).toThrow("invalid"); | ||
expect(() => { | ||
new Sarus({ url: "http://wrong-protocol" }); | ||
}).toThrow("have protocol"); | ||
expect(() => { | ||
new Sarus({ url: "https://also-wrong-protocol" }); | ||
}).toThrow("have protocol"); | ||
new Sarus({ url: "ws://this-will-pass" }); | ||
new Sarus({ url: "wss://this-too-shall-pass" }); | ||
}); | ||
it("should set the WebSocket protocols value to an empty string if nothing is passed", async () => { | ||
@@ -44,3 +64,3 @@ const sarus: Sarus = new Sarus({ url }); | ||
expect(sarus.ws?.binaryType).toBe(binaryTypes[0]); | ||
}) | ||
}); | ||
}); |
@@ -20,4 +20,4 @@ // File Dependencies | ||
close: [mockClose], | ||
error: [mockError] | ||
} | ||
error: [mockError], | ||
}, | ||
}); | ||
@@ -55,4 +55,4 @@ await server.connected; | ||
close: [], | ||
message: [myFunc] | ||
} | ||
message: [myFunc], | ||
}, | ||
}); | ||
@@ -70,4 +70,4 @@ expect(sarus.eventListeners.open).toEqual([]); | ||
eventListeners: { | ||
message: [myFunc] | ||
} | ||
message: [myFunc], | ||
}, | ||
}); | ||
@@ -88,4 +88,4 @@ expect(sarus.eventListeners.open).toEqual([]); | ||
close: [], | ||
message: [myFunc] | ||
} | ||
message: [myFunc], | ||
}, | ||
}); | ||
@@ -108,4 +108,4 @@ | ||
close: [], | ||
message: [myFunc] | ||
} | ||
message: [myFunc], | ||
}, | ||
}); | ||
@@ -127,4 +127,4 @@ | ||
close: [], | ||
message: [myFunc] | ||
} | ||
message: [myFunc], | ||
}, | ||
}); | ||
@@ -150,4 +150,4 @@ await server.connected; | ||
close: [], | ||
message: [myFunc] | ||
} | ||
message: [myFunc], | ||
}, | ||
}); | ||
@@ -167,4 +167,4 @@ | ||
close: [], | ||
message: [myFunc] | ||
} | ||
message: [myFunc], | ||
}, | ||
}); | ||
@@ -185,4 +185,4 @@ | ||
close: [], | ||
message: [myFunc] | ||
} | ||
message: [myFunc], | ||
}, | ||
}); | ||
@@ -205,4 +205,4 @@ | ||
close: [], | ||
message: [myFunc] | ||
} | ||
message: [myFunc], | ||
}, | ||
}); | ||
@@ -225,4 +225,4 @@ | ||
close: [], | ||
message: [myFunc] | ||
} | ||
message: [myFunc], | ||
}, | ||
}); | ||
@@ -229,0 +229,0 @@ |
@@ -52,3 +52,3 @@ // File Dependencies | ||
storageType: any, | ||
sarusConfig: SarusClassParams | ||
sarusConfig: SarusClassParams, | ||
) => { | ||
@@ -88,3 +88,3 @@ storageType.clear(); | ||
storageType: "local", | ||
storageKey: "sarusWS" | ||
storageKey: "sarusWS", | ||
}); | ||
@@ -106,3 +106,3 @@ expect(sarus.storageKey).toBe("sarusWS"); | ||
const processExistingMessagesFromStorage = async ( | ||
sarusConfig: SarusClassParams | ||
sarusConfig: SarusClassParams, | ||
) => { | ||
@@ -133,3 +133,3 @@ const sarusTwo = retrieveMessagesFromStorage(sarusConfig); | ||
storageType: "session", | ||
reconnectAutomatically: true | ||
reconnectAutomatically: true, | ||
}); | ||
@@ -142,5 +142,5 @@ }); | ||
storageType: "local", | ||
reconnectAutomatically: true | ||
reconnectAutomatically: true, | ||
}); | ||
}); | ||
}); |
// File Dependencies | ||
import Sarus from "../../src/index"; | ||
import { WS } from "jest-websocket-mock"; | ||
import { delay} from '../helpers/delay'; | ||
import { delay } from "../helpers/delay"; | ||
@@ -15,5 +15,7 @@ const url: string = "ws://localhost:1234"; | ||
sarus.connect = mockConnect; | ||
const setTimeout = jest.spyOn(window, "setTimeout"); | ||
server.close(); | ||
await delay(1000); | ||
expect(sarus.connect).toBeCalled(); | ||
expect(setTimeout).toHaveBeenCalledTimes(2); | ||
}); | ||
@@ -26,3 +28,3 @@ | ||
url, | ||
reconnectAutomatically: false | ||
reconnectAutomatically: false, | ||
}); | ||
@@ -35,4 +37,4 @@ await server.connected; | ||
describe('if a websocket is closed and meant to reconnect automatically', () => { | ||
it('should remove all eventListeners on the closed websocket before reconnecting', async () => { | ||
describe("if a websocket is closed and meant to reconnect automatically", () => { | ||
it("should remove all eventListeners on the closed websocket before reconnecting", async () => { | ||
const server: WS = new WS(url); | ||
@@ -53,9 +55,7 @@ const mockReconnect = jest.fn(); | ||
// @ts-ignore | ||
expect(sarus.ws?.listeners?.error?.length).toBe(0); | ||
expect(sarus.ws?.listeners?.error?.length).toBe(0); | ||
// @ts-ignore | ||
expect(sarus.ws?.listeners?.close?.length).toBe(0); | ||
expect(sarus.ws?.listeners?.close?.length).toBe(0); | ||
}); | ||
}) | ||
}); | ||
}); |
@@ -8,3 +8,3 @@ // File Dependencies | ||
const condition = (func: Function) => { | ||
return new Promise<void>(resolve => { | ||
return new Promise<void>((resolve) => { | ||
let check: Function; | ||
@@ -11,0 +11,0 @@ check = () => { |
# CHANGELOG | ||
### 0.5.0 - Saturday 27th April, 2024 | ||
- Tidied up some missplaced development dependencies | ||
- Track current connection state internally | ||
- Made retryConnectionDelay a required parameter, and restricted type to number | ||
- Cleaned up running commands without using npx | ||
- Validate URLS when constructing a Sarus instance | ||
- Updated License, authors and populated contributors | ||
- Changed node build targets to latest LTS and current (18 & 20) | ||
- Added Prettier Github Workflow | ||
- Formatted code using Prettier | ||
- Updated dependencies | ||
### 0.4.6 - Sunday 18th June, 2023 | ||
@@ -4,0 +17,0 @@ |
@@ -23,3 +23,3 @@ import { PartialEventListenersInterface, EventListenersInterface } from "./lib/validators"; | ||
* @param {number} param0.retryProcessTimePeriod - An optional number for how long the time period between retrying to send a messgae to a WebSocket server should be | ||
* @param {boolean|number} param0.retryConnectionDelay - An optional parameter for whether to delay WebSocket reconnection attempts by a time period. If true, the delay is 1000ms, otherwise it is the number passed | ||
* @param {number} param0.retryConnectionDelay - A parameter for the amount of time to delay a reconnection attempt by, in miliseconds. | ||
* @param {string} param0.storageType - An optional string specifying the type of storage to use for persisting messages in the message queue | ||
@@ -30,3 +30,3 @@ * @param {string} param0.storageKey - An optional string specifying the key used to store the messages data against in sessionStorage/localStorage | ||
export default class Sarus { | ||
url: string; | ||
url: URL; | ||
binaryType?: BinaryType; | ||
@@ -37,3 +37,3 @@ protocols?: string | Array<string>; | ||
reconnectAutomatically?: boolean; | ||
retryConnectionDelay?: boolean | number; | ||
retryConnectionDelay: number; | ||
storageType: string; | ||
@@ -43,2 +43,3 @@ storageKey: string; | ||
ws: WebSocket | undefined; | ||
state: "connecting" | "connected" | "disconnected" | "closed"; | ||
constructor(props: SarusClassParams); | ||
@@ -45,0 +46,0 @@ /** |
@@ -55,2 +55,26 @@ "use strict"; | ||
}; | ||
var validateWebSocketUrl = function (rawUrl) { | ||
var url; | ||
try { | ||
// Alternatively, we can also check with URL.canParse(), but since we need | ||
// the URL object anyway to validate the protocol, we go ahead and parse it | ||
// here. | ||
url = new URL(rawUrl); | ||
} | ||
catch (e) { | ||
// TypeError, as specified by WHATWG URL Standard: | ||
// https://url.spec.whatwg.org/#url-class (see constructor steps) | ||
if (!(e instanceof TypeError)) { | ||
throw e; | ||
} | ||
// Untested - our URL mock does not give us an instance of TypeError | ||
var message = e.message; | ||
throw new Error("The WebSocket URL is not valid: ".concat(message)); | ||
} | ||
var protocol = url.protocol; | ||
if (!constants_1.ALLOWED_PROTOCOLS.includes(protocol)) { | ||
throw new Error("Expected the WebSocket URL to have protocol 'ws:' or 'wss:', got '".concat(protocol, "' instead.")); | ||
} | ||
return url; | ||
}; | ||
/** | ||
@@ -66,3 +90,3 @@ * The Sarus client class | ||
* @param {number} param0.retryProcessTimePeriod - An optional number for how long the time period between retrying to send a messgae to a WebSocket server should be | ||
* @param {boolean|number} param0.retryConnectionDelay - An optional parameter for whether to delay WebSocket reconnection attempts by a time period. If true, the delay is 1000ms, otherwise it is the number passed | ||
* @param {number} param0.retryConnectionDelay - A parameter for the amount of time to delay a reconnection attempt by, in miliseconds. | ||
* @param {string} param0.storageType - An optional string specifying the type of storage to use for persisting messages in the message queue | ||
@@ -74,8 +98,32 @@ * @param {string} param0.storageKey - An optional string specifying the key used to store the messages data against in sessionStorage/localStorage | ||
function Sarus(props) { | ||
var _a; | ||
/* | ||
* Track the current state of the Sarus object. See the diagram below. | ||
* | ||
* reconnect() ┌──────┐ | ||
* ┌───────────────────────────────│closed│ | ||
* │ └──────┘ | ||
* │ ▲ | ||
* ▼ │ this.ws.onclose | ||
* ┌──────────┐ this.ws.onopen ┌───┴─────┐ | ||
* │connecting├───────────────────────►│connected│ | ||
* └──────────┘ └───┬─────┘ | ||
* ▲ │ disconnect() | ||
* │ ▼ | ||
* │ reconnect() ┌────────────┐ | ||
* └─────────────────────────────┤disconnected│ | ||
* └────────────┘ | ||
* | ||
* connect(), disconnect() are generally called by the user | ||
* | ||
* this.reconnect() is called internally when automatic reconnection is | ||
* enabled, but can also be called by the user | ||
*/ | ||
this.state = "connecting"; | ||
// Extract the properties that are passed to the class | ||
var url = props.url, binaryType = props.binaryType, protocols = props.protocols, _a = props.eventListeners, eventListeners = _a === void 0 ? constants_1.DEFAULT_EVENT_LISTENERS_OBJECT : _a, reconnectAutomatically = props.reconnectAutomatically, retryProcessTimePeriod = props.retryProcessTimePeriod, // TODO - write a test case to check this | ||
retryConnectionDelay = props.retryConnectionDelay, _b = props.storageType, storageType = _b === void 0 ? "memory" : _b, _c = props.storageKey, storageKey = _c === void 0 ? "sarus" : _c; | ||
var url = props.url, binaryType = props.binaryType, protocols = props.protocols, _b = props.eventListeners, eventListeners = _b === void 0 ? constants_1.DEFAULT_EVENT_LISTENERS_OBJECT : _b, reconnectAutomatically = props.reconnectAutomatically, retryProcessTimePeriod = props.retryProcessTimePeriod, // TODO - write a test case to check this | ||
retryConnectionDelay = props.retryConnectionDelay, _c = props.storageType, storageType = _c === void 0 ? "memory" : _c, _d = props.storageKey, storageKey = _d === void 0 ? "sarus" : _d; | ||
this.eventListeners = this.auditEventListeners(eventListeners); | ||
// Sets the WebSocket server url for the client to connect to. | ||
this.url = url; | ||
this.url = validateWebSocketUrl(url); | ||
// Sets the binaryType of the data being sent over the connection | ||
@@ -102,3 +150,11 @@ this.binaryType = binaryType; | ||
*/ | ||
this.retryConnectionDelay = retryConnectionDelay || true; | ||
// Either retryConnectionDelay is | ||
// undefined => default to 1000 | ||
// true => default to 1000 | ||
// false => default to 1000 | ||
// a number => set it to that number | ||
this.retryConnectionDelay = | ||
(_a = (typeof retryConnectionDelay === "boolean" | ||
? undefined | ||
: retryConnectionDelay)) !== null && _a !== void 0 ? _a : 1000; | ||
/* | ||
@@ -113,3 +169,3 @@ Sets the storage type for the messages in the message queue. By default | ||
used as the key for calls to sessionStorage/localStorage getItem/setItem. | ||
It can also be configured by the developer during initialization. | ||
@@ -122,3 +178,3 @@ */ | ||
that might have been persisted there. | ||
Say the user has done a page refresh, we want to make sure that messages | ||
@@ -226,2 +282,3 @@ that were meant to be sent to the server make their way there. | ||
Sarus.prototype.connect = function () { | ||
this.state = "connecting"; | ||
this.ws = new WebSocket(this.url, this.protocols); | ||
@@ -239,15 +296,3 @@ this.setBinaryType(); | ||
var retryConnectionDelay = self.retryConnectionDelay; | ||
switch (typeof retryConnectionDelay) { | ||
case "boolean": | ||
if (retryConnectionDelay) { | ||
setTimeout(self.connect, 1000); | ||
} | ||
else { | ||
self.connect(); // NOTE - this line is not tested | ||
} | ||
break; | ||
case "number": | ||
setTimeout(self.connect, retryConnectionDelay); | ||
break; | ||
} | ||
setTimeout(self.connect, retryConnectionDelay); | ||
}; | ||
@@ -261,2 +306,3 @@ /** | ||
Sarus.prototype.disconnect = function (overrideDisableReconnect) { | ||
this.state = "disconnected"; | ||
var self = this; | ||
@@ -379,3 +425,7 @@ // We do this to prevent automatic reconnections; | ||
self.eventListeners[eventName].forEach(function (f) { return f(e); }); | ||
if (eventName === "close" && self.reconnectAutomatically) { | ||
if (eventName === "open") { | ||
self.state = "connected"; | ||
} | ||
else if (eventName === "close" && self.reconnectAutomatically) { | ||
self.state = "closed"; | ||
self.removeEventListeners(); | ||
@@ -382,0 +432,0 @@ self.reconnect(); |
import { EventListenersInterface } from "./validators"; | ||
export declare const ALLOWED_PROTOCOLS: Array<string>; | ||
/** | ||
@@ -3,0 +4,0 @@ * A definitive list of events for a WebSocket client to listen on |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DEFAULT_EVENT_LISTENERS_OBJECT = exports.DATA_STORAGE_TYPES = exports.WS_EVENT_NAMES = void 0; | ||
exports.DEFAULT_EVENT_LISTENERS_OBJECT = exports.DATA_STORAGE_TYPES = exports.WS_EVENT_NAMES = exports.ALLOWED_PROTOCOLS = void 0; | ||
exports.ALLOWED_PROTOCOLS = ["ws:", "wss:"]; | ||
/** | ||
@@ -13,3 +14,3 @@ * A definitive list of events for a WebSocket client to listen on | ||
"message", | ||
"error" | ||
"error", | ||
]; | ||
@@ -36,3 +37,3 @@ /** | ||
error: [], | ||
close: [] | ||
close: [], | ||
}; |
{ | ||
"name": "@anephenix/sarus", | ||
"version": "0.4.6", | ||
"version": "0.5.0", | ||
"description": "A WebSocket JavaScript library", | ||
"main": "dist/index.js", | ||
"contributors": [ | ||
{ | ||
"name": "Paul Jensen", | ||
"email": "paulbjensen@gmail.com", | ||
"url": "https://paulbjensen.co.uk" | ||
}, | ||
{ | ||
"name": "Chris Lajoie", | ||
"email": "chris@ettaviation.com" | ||
}, | ||
{ | ||
"name": "Justus Perlwitz", | ||
"email": "justus@jwpconsulting.net", | ||
"url": "https://www.jwpconsulting.net" | ||
} | ||
], | ||
"devDependencies": { | ||
@@ -11,11 +27,14 @@ "@babel/parser": "^7.22.5", | ||
"@types/websocket": "^1.0.5", | ||
"@types/window-or-global": "^1.0.6", | ||
"coveralls": "^3.1.1", | ||
"dom-storage": "^2.1.0", | ||
"ip-regex": "^5.0.0", | ||
"jest": "29.5.0", | ||
"jest": "29.7.0", | ||
"jest-environment-jsdom": "^29.7.0", | ||
"jest-websocket-mock": "^2.4.0", | ||
"jsdoc": "^4.0.2", | ||
"jsdom": "^22.1.0", | ||
"jsdom": "^24.0.0", | ||
"mock-socket": "^9.2.1", | ||
"npm-upgrade": "^3.1.0", | ||
"prettier": "^3.0.3", | ||
"ts-jest": "^29.1.0", | ||
@@ -25,6 +44,8 @@ "typescript": "^5.1.3" | ||
"scripts": { | ||
"build": "npx tsc --project tsconfig.json", | ||
"watch": "npx tsc --project tsconfig.json --watch", | ||
"cover": "npx jest --coverage --coverageReporters=text-lcov | coveralls", | ||
"test": "npx jest --coverage" | ||
"build": "tsc --project tsconfig.json", | ||
"watch": "tsc --project tsconfig.json --watch", | ||
"cover": "jest --coverage --coverageReporters=text-lcov | coveralls", | ||
"test": "jest --coverage", | ||
"prettier": "prettier src __tests__ --write", | ||
"check-prettier": "prettier src __tests__ --check" | ||
}, | ||
@@ -43,7 +64,3 @@ "repository": { | ||
}, | ||
"homepage": "https://github.com/anephenix/sarus#readme", | ||
"dependencies": { | ||
"@types/window-or-global": "^1.0.4", | ||
"jest-environment-jsdom": "^29.5.0" | ||
} | ||
"homepage": "https://github.com/anephenix/sarus#readme" | ||
} |
138
src/index.ts
// File Dependencies | ||
import { WS_EVENT_NAMES, DATA_STORAGE_TYPES, DEFAULT_EVENT_LISTENERS_OBJECT } from "./lib/constants"; | ||
import { | ||
ALLOWED_PROTOCOLS, | ||
WS_EVENT_NAMES, | ||
DATA_STORAGE_TYPES, | ||
DEFAULT_EVENT_LISTENERS_OBJECT, | ||
} from "./lib/constants"; | ||
import { serialize, deserialize } from "./lib/dataTransformer"; | ||
import { PartialEventListenersInterface, EventListenersInterface } from "./lib/validators"; | ||
import { | ||
PartialEventListenersInterface, | ||
EventListenersInterface, | ||
} from "./lib/validators"; | ||
@@ -42,2 +50,28 @@ interface StorageParams { | ||
const validateWebSocketUrl = (rawUrl: string): URL => { | ||
let url: URL; | ||
try { | ||
// Alternatively, we can also check with URL.canParse(), but since we need | ||
// the URL object anyway to validate the protocol, we go ahead and parse it | ||
// here. | ||
url = new URL(rawUrl); | ||
} catch (e) { | ||
// TypeError, as specified by WHATWG URL Standard: | ||
// https://url.spec.whatwg.org/#url-class (see constructor steps) | ||
if (!(e instanceof TypeError)) { | ||
throw e; | ||
} | ||
// Untested - our URL mock does not give us an instance of TypeError | ||
const { message } = e; | ||
throw new Error(`The WebSocket URL is not valid: ${message}`); | ||
} | ||
const { protocol } = url; | ||
if (!ALLOWED_PROTOCOLS.includes(protocol)) { | ||
throw new Error( | ||
`Expected the WebSocket URL to have protocol 'ws:' or 'wss:', got '${protocol}' instead.`, | ||
); | ||
} | ||
return url; | ||
}; | ||
export interface SarusClassParams { | ||
@@ -65,3 +99,3 @@ url: string; | ||
* @param {number} param0.retryProcessTimePeriod - An optional number for how long the time period between retrying to send a messgae to a WebSocket server should be | ||
* @param {boolean|number} param0.retryConnectionDelay - An optional parameter for whether to delay WebSocket reconnection attempts by a time period. If true, the delay is 1000ms, otherwise it is the number passed | ||
* @param {number} param0.retryConnectionDelay - A parameter for the amount of time to delay a reconnection attempt by, in miliseconds. | ||
* @param {string} param0.storageType - An optional string specifying the type of storage to use for persisting messages in the message queue | ||
@@ -73,3 +107,3 @@ * @param {string} param0.storageKey - An optional string specifying the key used to store the messages data against in sessionStorage/localStorage | ||
// Constructor params | ||
url: string; | ||
url: URL; | ||
binaryType?: BinaryType; | ||
@@ -80,3 +114,3 @@ protocols?: string | Array<string>; | ||
reconnectAutomatically?: boolean; | ||
retryConnectionDelay?: boolean | number; | ||
retryConnectionDelay: number; | ||
storageType: string; | ||
@@ -88,2 +122,25 @@ storageKey: string; | ||
ws: WebSocket | undefined; | ||
/* | ||
* Track the current state of the Sarus object. See the diagram below. | ||
* | ||
* reconnect() ┌──────┐ | ||
* ┌───────────────────────────────│closed│ | ||
* │ └──────┘ | ||
* │ ▲ | ||
* ▼ │ this.ws.onclose | ||
* ┌──────────┐ this.ws.onopen ┌───┴─────┐ | ||
* │connecting├───────────────────────►│connected│ | ||
* └──────────┘ └───┬─────┘ | ||
* ▲ │ disconnect() | ||
* │ ▼ | ||
* │ reconnect() ┌────────────┐ | ||
* └─────────────────────────────┤disconnected│ | ||
* └────────────┘ | ||
* | ||
* connect(), disconnect() are generally called by the user | ||
* | ||
* this.reconnect() is called internally when automatic reconnection is | ||
* enabled, but can also be called by the user | ||
*/ | ||
state: "connecting" | "connected" | "disconnected" | "closed" = "connecting"; | ||
@@ -101,3 +158,3 @@ constructor(props: SarusClassParams) { | ||
storageType = "memory", | ||
storageKey = "sarus" | ||
storageKey = "sarus", | ||
} = props; | ||
@@ -108,3 +165,3 @@ | ||
// Sets the WebSocket server url for the client to connect to. | ||
this.url = url; | ||
this.url = validateWebSocketUrl(url); | ||
@@ -118,3 +175,3 @@ // Sets the binaryType of the data being sent over the connection | ||
/* | ||
When attempting to re-send a message when the WebSocket connection is | ||
When attempting to re-send a message when the WebSocket connection is | ||
not open, there is a retry process time period of 50ms. It can be set | ||
@@ -134,10 +191,18 @@ to another value by the developer. | ||
This handles whether to add a time delay to reconnecting the WebSocket | ||
client. If true, a 1000ms delay is added. If a number, that number (as | ||
client. If true, a 1000ms delay is added. If a number, that number (as | ||
miliseconds) is used as the delay. Default is true. | ||
*/ | ||
this.retryConnectionDelay = retryConnectionDelay || true; | ||
// Either retryConnectionDelay is | ||
// undefined => default to 1000 | ||
// true => default to 1000 | ||
// false => default to 1000 | ||
// a number => set it to that number | ||
this.retryConnectionDelay = | ||
(typeof retryConnectionDelay === "boolean" | ||
? undefined | ||
: retryConnectionDelay) ?? 1000; | ||
/* | ||
Sets the storage type for the messages in the message queue. By default | ||
it is an in-memory option, but can also be set as 'session' for | ||
it is an in-memory option, but can also be set as 'session' for | ||
sessionStorage or 'local' for localStorage data persistence. | ||
@@ -150,3 +215,3 @@ */ | ||
used as the key for calls to sessionStorage/localStorage getItem/setItem. | ||
It can also be configured by the developer during initialization. | ||
@@ -158,6 +223,6 @@ */ | ||
When initializing the client, if we are using sessionStorage/localStorage | ||
for storing messages in the messageQueue, then we want to retrieve any | ||
for storing messages in the messageQueue, then we want to retrieve any | ||
that might have been persisted there. | ||
Say the user has done a page refresh, we want to make sure that messages | ||
Say the user has done a page refresh, we want to make sure that messages | ||
that were meant to be sent to the server make their way there. | ||
@@ -177,3 +242,3 @@ | ||
/* | ||
/* | ||
Gets the messages from the message queue. | ||
@@ -261,3 +326,3 @@ */ | ||
}; | ||
const mergedEventListeners: EventListenersInterface = { | ||
@@ -267,6 +332,5 @@ ...defaultEventListeners, | ||
} as EventListenersInterface; // Type assertion added here | ||
return mergedEventListeners; | ||
} | ||
@@ -277,2 +341,3 @@ /** | ||
connect() { | ||
this.state = "connecting"; | ||
this.ws = new WebSocket(this.url, this.protocols); | ||
@@ -290,14 +355,3 @@ this.setBinaryType(); | ||
const { retryConnectionDelay } = self; | ||
switch (typeof retryConnectionDelay) { | ||
case "boolean": | ||
if (retryConnectionDelay) { | ||
setTimeout(self.connect, 1000); | ||
} else { | ||
self.connect(); // NOTE - this line is not tested | ||
} | ||
break; | ||
case "number": | ||
setTimeout(self.connect, retryConnectionDelay); | ||
break; | ||
} | ||
setTimeout(self.connect, retryConnectionDelay); | ||
} | ||
@@ -312,2 +366,3 @@ | ||
disconnect(overrideDisableReconnect?: boolean) { | ||
this.state = "disconnected"; | ||
const self = this; | ||
@@ -330,3 +385,3 @@ // We do this to prevent automatic reconnections; | ||
throw new Error( | ||
`${eventFunc.name} has already been added to this event Listener` | ||
`${eventFunc.name} has already been added to this event Listener`, | ||
); | ||
@@ -368,3 +423,3 @@ } | ||
} | ||
| undefined | ||
| undefined, | ||
) { | ||
@@ -388,3 +443,3 @@ if (!existingFunc) { | ||
eventFuncOrName: Function | string, | ||
opts?: { doNotThrowError: boolean } | undefined | ||
opts?: { doNotThrowError: boolean } | undefined, | ||
) { | ||
@@ -444,6 +499,9 @@ const existingFunc = this.findFunction(eventName, eventFuncOrName); | ||
const self: any = this; | ||
WS_EVENT_NAMES.forEach(eventName => { | ||
WS_EVENT_NAMES.forEach((eventName) => { | ||
self.ws[`on${eventName}`] = (e: Function) => { | ||
self.eventListeners[eventName].forEach((f: Function) => f(e)); | ||
if (eventName === "close" && self.reconnectAutomatically) { | ||
if (eventName === "open") { | ||
self.state = "connected"; | ||
} else if (eventName === "close" && self.reconnectAutomatically) { | ||
self.state = "closed"; | ||
self.removeEventListeners(); | ||
@@ -457,3 +515,3 @@ self.reconnect(); | ||
/** | ||
* Removes the event listeners from a closed WebSocket instance, so that | ||
* Removes the event listeners from a closed WebSocket instance, so that | ||
* they are cleaned up | ||
@@ -463,7 +521,7 @@ */ | ||
const self: any = this; | ||
WS_EVENT_NAMES.forEach(eventName => { | ||
WS_EVENT_NAMES.forEach((eventName) => { | ||
if (self.ws.listeners && self.ws.listeners[eventName]) { | ||
self.ws.listeners[eventName].forEach((iel:Function) => { | ||
self.ws.listeners[eventName].forEach((iel: Function) => { | ||
self.ws.removeEventListener(eventName, iel); | ||
}) | ||
}); | ||
} | ||
@@ -470,0 +528,0 @@ }); |
// Dependencies | ||
import { EventListenersInterface } from "./validators"; | ||
export const ALLOWED_PROTOCOLS: Array<string> = ["ws:", "wss:"]; | ||
/** | ||
@@ -13,3 +15,3 @@ * A definitive list of events for a WebSocket client to listen on | ||
"message", | ||
"error" | ||
"error", | ||
]; | ||
@@ -38,3 +40,3 @@ | ||
error: [], | ||
close: [] | ||
}; | ||
close: [], | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
111585
0
41
1901
18
- Removed@types/window-or-global@^1.0.4
- Removedjest-environment-jsdom@^29.5.0
- Removed@babel/code-frame@7.26.2(transitive)
- Removed@babel/helper-validator-identifier@7.25.9(transitive)
- Removed@jest/environment@29.7.0(transitive)
- Removed@jest/fake-timers@29.7.0(transitive)
- Removed@jest/schemas@29.6.3(transitive)
- Removed@jest/types@29.6.3(transitive)
- Removed@sinclair/typebox@0.27.8(transitive)
- Removed@sinonjs/commons@3.0.1(transitive)
- Removed@sinonjs/fake-timers@10.3.0(transitive)
- Removed@tootallnate/once@2.0.0(transitive)
- Removed@types/istanbul-lib-coverage@2.0.6(transitive)
- Removed@types/istanbul-lib-report@3.0.3(transitive)
- Removed@types/istanbul-reports@3.0.4(transitive)
- Removed@types/jsdom@20.0.1(transitive)
- Removed@types/node@22.10.2(transitive)
- Removed@types/stack-utils@2.0.3(transitive)
- Removed@types/tough-cookie@4.0.5(transitive)
- Removed@types/window-or-global@1.0.6(transitive)
- Removed@types/yargs@17.0.33(transitive)
- Removed@types/yargs-parser@21.0.3(transitive)
- Removedabab@2.0.6(transitive)
- Removedacorn@8.14.0(transitive)
- Removedacorn-globals@7.0.1(transitive)
- Removedacorn-walk@8.3.4(transitive)
- Removedagent-base@6.0.2(transitive)
- Removedansi-styles@4.3.05.2.0(transitive)
- Removedasynckit@0.4.0(transitive)
- Removedbraces@3.0.3(transitive)
- Removedchalk@4.1.2(transitive)
- Removedci-info@3.9.0(transitive)
- Removedcolor-convert@2.0.1(transitive)
- Removedcolor-name@1.1.4(transitive)
- Removedcombined-stream@1.0.8(transitive)
- Removedcssom@0.3.80.5.0(transitive)
- Removedcssstyle@2.3.0(transitive)
- Removeddata-urls@3.0.2(transitive)
- Removeddebug@4.4.0(transitive)
- Removeddecimal.js@10.4.3(transitive)
- Removeddelayed-stream@1.0.0(transitive)
- Removeddomexception@4.0.0(transitive)
- Removedentities@4.5.0(transitive)
- Removedescape-string-regexp@2.0.0(transitive)
- Removedescodegen@2.1.0(transitive)
- Removedesprima@4.0.1(transitive)
- Removedestraverse@5.3.0(transitive)
- Removedesutils@2.0.3(transitive)
- Removedfill-range@7.1.1(transitive)
- Removedform-data@4.0.1(transitive)
- Removedgraceful-fs@4.2.11(transitive)
- Removedhas-flag@4.0.0(transitive)
- Removedhtml-encoding-sniffer@3.0.0(transitive)
- Removedhttp-proxy-agent@5.0.0(transitive)
- Removedhttps-proxy-agent@5.0.1(transitive)
- Removediconv-lite@0.6.3(transitive)
- Removedis-number@7.0.0(transitive)
- Removedis-potential-custom-element-name@1.0.1(transitive)
- Removedjest-environment-jsdom@29.7.0(transitive)
- Removedjest-message-util@29.7.0(transitive)
- Removedjest-mock@29.7.0(transitive)
- Removedjest-util@29.7.0(transitive)
- Removedjs-tokens@4.0.0(transitive)
- Removedjsdom@20.0.3(transitive)
- Removedmicromatch@4.0.8(transitive)
- Removedmime-db@1.52.0(transitive)
- Removedmime-types@2.1.35(transitive)
- Removedms@2.1.3(transitive)
- Removednwsapi@2.2.16(transitive)
- Removedparse5@7.2.1(transitive)
- Removedpicocolors@1.1.1(transitive)
- Removedpicomatch@2.3.1(transitive)
- Removedpretty-format@29.7.0(transitive)
- Removedpsl@1.15.0(transitive)
- Removedpunycode@2.3.1(transitive)
- Removedquerystringify@2.2.0(transitive)
- Removedreact-is@18.3.1(transitive)
- Removedrequires-port@1.0.0(transitive)
- Removedsafer-buffer@2.1.2(transitive)
- Removedsaxes@6.0.0(transitive)
- Removedslash@3.0.0(transitive)
- Removedsource-map@0.6.1(transitive)
- Removedstack-utils@2.0.6(transitive)
- Removedsupports-color@7.2.0(transitive)
- Removedsymbol-tree@3.2.4(transitive)
- Removedto-regex-range@5.0.1(transitive)
- Removedtough-cookie@4.1.4(transitive)
- Removedtr46@3.0.0(transitive)
- Removedtype-detect@4.0.8(transitive)
- Removedundici-types@6.20.0(transitive)
- Removeduniversalify@0.2.0(transitive)
- Removedurl-parse@1.5.10(transitive)
- Removedw3c-xmlserializer@4.0.0(transitive)
- Removedwebidl-conversions@7.0.0(transitive)
- Removedwhatwg-encoding@2.0.0(transitive)
- Removedwhatwg-mimetype@3.0.0(transitive)
- Removedwhatwg-url@11.0.0(transitive)
- Removedws@8.18.0(transitive)
- Removedxml-name-validator@4.0.0(transitive)
- Removedxmlchars@2.2.0(transitive)