New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@d-fischer/connection

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@d-fischer/connection - npm Package Compare versions

Comparing version

to
8.0.0

6

lib/AbstractConnection.d.ts
import type { Logger } from '@d-fischer/logger';
import { EventEmitter } from '@d-fischer/typed-event-emitter';
import type { Connection, ConnectionOptions } from './Connection';
export declare type InferConnectionOptions<T extends Connection> = T extends AbstractConnection<infer O> ? O : never;
export type InferConnectionOptions<T extends Connection> = T extends AbstractConnection<infer O> ? O : never;
export declare abstract class AbstractConnection<Options = never> extends EventEmitter implements Connection {

@@ -20,4 +20,4 @@ private readonly _lineBased;

sendLine(line: string): void;
abstract connect(): Promise<void>;
abstract disconnect(): Promise<void>;
abstract connect(): void;
abstract disconnect(): void;
assumeExternalDisconnect(): void;

@@ -24,0 +24,0 @@ protected receiveRaw(data: string): void;

@@ -11,4 +11,4 @@ import type { Logger } from '@d-fischer/logger';

readonly onEnd: EventBinder<[boolean, Error?]>;
connect: () => Promise<void>;
disconnect: () => Promise<void>;
connect: () => void;
disconnect: () => void;
assumeExternalDisconnect: () => void;

@@ -15,0 +15,0 @@ sendLine: (line: string) => void;

@@ -1,9 +0,17 @@

import { AbstractConnection } from './AbstractConnection';
import type { ConnectionOptions, ConnectionTarget } from './Connection';
export declare class DirectConnection extends AbstractConnection {
constructor(target: ConnectionTarget, options: ConnectionOptions<never>);
get hasSocket(): boolean;
sendRaw(line: string): void;
connect(): Promise<void>;
disconnect(): Promise<void>;
import { type EventBinder } from '@d-fischer/typed-event-emitter';
import { type Connection } from './Connection';
export declare class DirectConnection implements Connection {
readonly hasSocket: boolean;
sendRaw: (line: string) => void;
sendLine: (line: string) => void;
readonly isConnected: boolean;
readonly isConnecting: boolean;
readonly connect: () => void;
readonly disconnect: () => void;
readonly assumeExternalDisconnect: () => void;
readonly onConnect: EventBinder<[]>;
readonly onDisconnect: EventBinder<[boolean, Error]>;
readonly onEnd: EventBinder<[boolean, Error]>;
readonly onReceive: EventBinder<[string]>;
constructor();
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DirectConnection = void 0;
const AbstractConnection_1 = require("./AbstractConnection");
class DirectConnection extends AbstractConnection_1.AbstractConnection {
constructor(target, options) {
class DirectConnection {
constructor() {
throw new Error('DirectConnection is not implemented in a browser environment');
super(options);
}
// eslint-disable-next-line @typescript-eslint/class-literal-property-style
get hasSocket() {
return false;
}
sendRaw(line) {
void line;
}
async connect() {
//
}
async disconnect() {
//
}
}
exports.DirectConnection = DirectConnection;
//# sourceMappingURL=DirectConnection-stub.js.map

@@ -11,4 +11,4 @@ import { AbstractConnection } from './AbstractConnection';

sendRaw(line: string): void;
connect(): Promise<void>;
disconnect(): Promise<void>;
connect(): void;
disconnect(): void;
}

@@ -26,69 +26,54 @@ "use strict";

}
async connect() {
connect() {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace('DirectConnection connect');
await new Promise((resolve, reject) => {
this._connecting = true;
if (this._secure) {
this._socket = tls.connect(this._port, this._host);
}
else {
this._socket = new net_1.Socket();
this._socket.connect(this._port, this._host);
}
this._socket.on('connect', () => {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace('DirectConnection onConnect');
this._connecting = false;
this._connected = true;
this.emit(this.onConnect);
resolve();
});
this._socket.on('error', (err) => {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace(`DirectConnection onError message:${err.message}`);
this._connecting = true;
if (this._secure) {
this._socket = tls.connect(this._port, this._host);
}
else {
this._socket = new net_1.Socket();
this._socket.connect(this._port, this._host);
}
this._socket.on('connect', () => {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace('DirectConnection onConnect');
this._connecting = false;
this._connected = true;
this.emit(this.onConnect);
});
this._socket.on('error', (err) => {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace(`DirectConnection onError message:${err.message}`);
this._connected = false;
this._connecting = false;
this.emit(this.onDisconnect, false, err);
});
this._socket.on('data', (data) => {
this.receiveRaw(data.toString());
});
this._socket.on('close', (hadError) => {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace(`DirectConnection onClose hadError:${hadError.toString()}`);
if (!hadError) {
this._connected = false;
this._connecting = false;
this.emit(this.onDisconnect, false, err);
reject(err);
});
this._socket.on('data', (data) => {
this.receiveRaw(data.toString());
});
this._socket.on('close', (hadError) => {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace(`DirectConnection onClose hadError:${hadError.toString()}`);
if (!hadError) {
this._connected = false;
this._connecting = false;
this.emit(this.onDisconnect, true);
}
if (this._socket) {
this._socket.removeAllListeners('connect');
this._socket.removeAllListeners('error');
this._socket.removeAllListeners('data');
this._socket.removeAllListeners('close');
this._socket = null;
}
});
});
}
async disconnect() {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace('DirectConnection disconnect');
await new Promise(resolve => {
this.emit(this.onDisconnect, true);
}
if (this._socket) {
const listener = this.onDisconnect(() => {
listener.unbind();
resolve();
});
this._socket.end();
this._socket.removeAllListeners('connect');
this._socket.removeAllListeners('error');
this._socket.removeAllListeners('data');
this._socket.removeAllListeners('close');
this._socket = null;
}
else {
resolve();
}
});
}
disconnect() {
var _a, _b;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace('DirectConnection disconnect');
(_b = this._socket) === null || _b === void 0 ? void 0 : _b.end();
}
}
exports.DirectConnection = DirectConnection;
//# sourceMappingURL=DirectConnection.js.map

@@ -1,2 +0,2 @@

import type { Constructor } from '@d-fischer/shared-utils';
import type { Constructor, ResolvableValueSync } from '@d-fischer/shared-utils';
import { EventEmitter } from '@d-fischer/typed-event-emitter';

@@ -8,2 +8,3 @@ import type { InferConnectionOptions } from './AbstractConnection';

initialRetryLimit?: number;
overlapManualReconnect?: boolean;
}

@@ -21,2 +22,3 @@ export declare class PersistentConnection<T extends Connection> extends EventEmitter implements Connection {

private _currentConnection?;
private _previousConnection?;
readonly onReceive: import("@d-fischer/typed-event-emitter").EventBinder<[string]>;

@@ -26,3 +28,3 @@ readonly onConnect: import("@d-fischer/typed-event-emitter").EventBinder<[]>;

readonly onEnd: import("@d-fischer/typed-event-emitter").EventBinder<[boolean, (Error | undefined)?]>;
constructor(_type: Constructor<T>, _target: ConnectionTarget, _config?: PersistentConnectionConfig<InferConnectionOptions<T>>);
constructor(_type: Constructor<T>, _target: ResolvableValueSync<ConnectionTarget>, _config?: PersistentConnectionConfig<InferConnectionOptions<T>>);
get isConnected(): boolean;

@@ -32,9 +34,10 @@ get isConnecting(): boolean;

sendLine(line: string): void;
connect(): Promise<void>;
disconnect(): Promise<void>;
connect(): void;
disconnect(): void;
assumeExternalDisconnect(): void;
reconnect(): Promise<void>;
private _connect;
reconnect(): void;
acknowledgeSuccessfulReconnect(): void;
private _startTryingToConnect;
private _tryConnect;
private _reconnect;
private static _getReconnectWaitTime;
}

@@ -40,6 +40,11 @@ "use strict";

}
async connect() {
await this._connect(true);
connect() {
if (this._currentConnection || this._connecting) {
throw new Error('Connection already present');
}
this._connecting = true;
this._connectionRetryCount = 0;
this._tryConnect(true);
}
async disconnect() {
disconnect() {
var _a;

@@ -51,3 +56,3 @@ (_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace(`PersistentConnection disconnect currentConnectionExists:${Boolean(this._currentConnection).toString()} connecting:${this._connecting.toString()}`);

this._currentConnection = undefined;
await lastConnection.disconnect();
lastConnection.disconnect();
}

@@ -60,45 +65,48 @@ }

}
async reconnect() {
await this._reconnect(true);
reconnect() {
this._reconnect(true);
}
async _connect(userGenerated = false) {
var _a, _b, _c, _d;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace(`PersistentConnection connect currentConnectionExists:${Boolean(this._currentConnection).toString()} connecting:${this._connecting.toString()}`);
if (this._currentConnection || this._connecting) {
throw new Error('Connection already present');
acknowledgeSuccessfulReconnect() {
if (this._previousConnection) {
this._previousConnection.disconnect();
this._previousConnection = undefined;
}
}
_startTryingToConnect(userGenerated = false) {
this._connecting = true;
this._connectionRetryCount = 0;
this._connecting = true;
this._tryConnect(userGenerated);
}
_tryConnect(userGenerated = false) {
var _a, _b;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace(`PersistentConnection tryConnect currentConnectionExists:${Boolean(this._currentConnection).toString()} connecting:${this._connecting.toString()}`);
const retryLimit = userGenerated ? this._initialRetryLimit : this._retryLimit;
this._retryTimerGenerator = PersistentConnection._getReconnectWaitTime();
while (this._connectionRetryCount <= retryLimit) {
const newConnection = (this._currentConnection = new this._type(this._target, this._config));
newConnection.onReceive(line => this.emit(this.onReceive, line));
newConnection.onConnect(() => this.emit(this.onConnect));
newConnection.onDisconnect((manually, reason) => {
this.emit(this.onDisconnect, manually, reason);
if (manually) {
this.emit(this.onEnd, true);
void newConnection.disconnect();
if (this._currentConnection === newConnection) {
this._currentConnection = undefined;
}
(_b = this._retryTimerGenerator) !== null && _b !== void 0 ? _b : (this._retryTimerGenerator = (0, shared_utils_1.fibWithLimit)(120));
const newConnection = (this._currentConnection = new this._type((0, shared_utils_1.resolveConfigValueSync)(this._target), this._config));
newConnection.onReceive(line => this.emit(this.onReceive, line));
newConnection.onConnect(() => {
this.emit(this.onConnect);
this._connecting = false;
this._retryTimerGenerator = undefined;
});
newConnection.onDisconnect((manually, reason) => {
var _a, _b, _c;
this.emit(this.onDisconnect, manually, reason);
if (manually) {
this.emit(this.onEnd, true);
this._connecting = false;
this._retryTimerGenerator = undefined;
newConnection.disconnect();
if (this._currentConnection === newConnection) {
this._currentConnection = undefined;
}
else if (!this._connecting) {
void this._reconnect();
if (this._previousConnection === newConnection) {
this._previousConnection = undefined;
}
});
try {
await newConnection.connect();
this._connecting = false;
return;
}
catch (e) {
if (!this._connecting) {
else if (this._connecting) {
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.debug(`Connection error caught: ${(_b = reason === null || reason === void 0 ? void 0 : reason.message) !== null && _b !== void 0 ? _b : 'unknown error'}`);
if (this._connectionRetryCount >= retryLimit) {
return;
}
(_b = this._logger) === null || _b === void 0 ? void 0 : _b.debug(`Connection error caught: ${e.message}`);
if (this._connectionRetryCount >= retryLimit) {
break;
}
this._connectionRetryCount++;

@@ -109,31 +117,26 @@ const secs = this._retryTimerGenerator.next().value;

}
await (0, shared_utils_1.delay)(secs * 1000);
(_d = this._logger) === null || _d === void 0 ? void 0 : _d.info(userGenerated ? 'Retrying connection' : 'Trying to reconnect');
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!this._connecting) {
return;
}
setTimeout(() => {
var _a;
if (!this._connecting) {
return;
}
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.info(userGenerated ? 'Retrying connection' : 'Trying to reconnect');
this._tryConnect();
}, secs * 1000);
}
}
const error = new Error(`Connection failed after trying ${retryLimit} times`);
this.emit(this.onEnd, false, error);
if (userGenerated) {
throw error;
}
else {
this._reconnect();
}
});
newConnection.connect();
}
async _reconnect(userGenerated = false) {
void this.disconnect().catch((e) => { var _a; return (_a = this._logger) === null || _a === void 0 ? void 0 : _a.error(`Error while disconnecting for the reconnect: ${e.message}`); });
await this._connect(userGenerated);
}
// yes, this is just fibonacci with a limit
static *_getReconnectWaitTime() {
let current = 0;
let next = 1;
while (current < 120) {
yield current;
[current, next] = [next, current + next];
_reconnect(userGenerated = false) {
if (userGenerated && this._config.overlapManualReconnect) {
this._previousConnection = this._currentConnection;
this._currentConnection = undefined;
}
while (true) {
yield 120;
else {
this.disconnect();
}
this._startTryingToConnect(userGenerated);
}

@@ -140,0 +143,0 @@ }

@@ -14,4 +14,4 @@ /// <reference types="ws" />

sendRaw(line: string): void;
connect(): Promise<void>;
disconnect(): Promise<void>;
connect(): void;
disconnect(): void;
}

@@ -27,71 +27,53 @@ "use strict";

}
async connect() {
var _a;
connect() {
var _a, _b;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace('WebSocketConnection connect');
await new Promise((resolve, reject) => {
this._connecting = true;
this._socket = new isomorphic_ws_1.WebSocket(this._url, (_b = this._additionalOptions) === null || _b === void 0 ? void 0 : _b.wsOptions);
this._socket.onopen = () => {
var _a;
this._connecting = true;
this._socket = new isomorphic_ws_1.WebSocket(this._url, (_a = this._additionalOptions) === null || _a === void 0 ? void 0 : _a.wsOptions);
this._socket.onopen = () => {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace('WebSocketConnection onOpen');
this._connected = true;
this._connecting = false;
this.emit(this.onConnect);
resolve();
};
this._socket.onmessage = ({ data }) => {
this.receiveRaw(data.toString());
};
// The following empty error callback needs to exist so connection errors are passed down to `onclose` down below - otherwise the process just crashes instead
this._socket.onerror = e => {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace(`WebSocketConnection onError message:${e.message}`);
};
this._socket.onclose = e => {
var _a;
const wasConnected = this._connected;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace(`WebSocketConnection onClose wasConnected:${wasConnected.toString()} wasClean:${e.wasClean.toString()}`);
this._connected = false;
this._connecting = false;
if (e.wasClean) {
this.emit(this.onDisconnect, true);
this.emit(this.onEnd, true);
}
else {
const err = new Error(`[${e.code}] ${e.reason}`);
this.emit(this.onDisconnect, false, err);
this.emit(this.onEnd, false, err);
if (!wasConnected) {
reject(err);
}
}
if (this._socket) {
this._socket.onopen = null;
this._socket.onmessage = null;
this._socket.onerror = null;
this._socket.onclose = null;
this._socket = null;
}
};
});
}
async disconnect() {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace('WebSocketConnection disconnect');
await new Promise(resolve => {
if (this._socket) {
const listener = this.onDisconnect(() => {
listener.unbind();
resolve();
});
this._socket.close();
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace('WebSocketConnection onOpen');
this._connected = true;
this._connecting = false;
this.emit(this.onConnect);
};
this._socket.onmessage = ({ data }) => {
this.receiveRaw(data.toString());
};
// The following empty error callback needs to exist so connection errors are passed down to `onclose` down below - otherwise the process just crashes instead
this._socket.onerror = e => {
var _a;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace(`WebSocketConnection onError message:${e.message}`);
};
this._socket.onclose = e => {
var _a;
const wasConnected = this._connected;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace(`WebSocketConnection onClose wasConnected:${wasConnected.toString()} wasClean:${e.wasClean.toString()}`);
this._connected = false;
this._connecting = false;
if (e.wasClean) {
this.emit(this.onDisconnect, true);
this.emit(this.onEnd, true);
}
else {
resolve();
const err = new Error(`[${e.code}] ${e.reason}`);
this.emit(this.onDisconnect, false, err);
this.emit(this.onEnd, false, err);
}
});
if (this._socket) {
this._socket.onopen = null;
this._socket.onmessage = null;
this._socket.onerror = null;
this._socket.onclose = null;
this._socket = null;
}
};
}
disconnect() {
var _a, _b;
(_a = this._logger) === null || _a === void 0 ? void 0 : _a.trace('WebSocketConnection disconnect');
(_b = this._socket) === null || _b === void 0 ? void 0 : _b.close();
}
}
exports.WebSocketConnection = WebSocketConnection;
//# sourceMappingURL=WebSocketConnection.js.map
{
"name": "@d-fischer/connection",
"version": "7.0.1",
"version": "8.0.0",
"description": "Abstraction for packet-based connections.",

@@ -29,6 +29,6 @@ "keywords": [],

"@d-fischer/logger": "^4.2.0",
"@d-fischer/shared-utils": "^3.3.0",
"@d-fischer/shared-utils": "^3.5.0",
"@d-fischer/typed-event-emitter": "^3.3.0",
"@types/node": "^16.7.10",
"@types/ws": "^8.5.3",
"@types/ws": "^8.5.4",
"tslib": "^2.4.1",

@@ -38,9 +38,9 @@ "ws": "^8.11.0"

"devDependencies": {
"@d-fischer/eslint-config": "^6.1.4",
"eslint": "^8.27.0",
"@d-fischer/eslint-config": "^6.1.8",
"eslint": "^8.31.0",
"husky": "^4.3.6",
"lint-staged": "^13.0.3",
"prettier": "^2.7.1",
"tsukuru": "^0.7.4",
"typescript": "~4.6.4"
"lint-staged": "^13.1.0",
"prettier": "^2.8.1",
"tsukuru": "^0.8.0-pre.11",
"typescript": "~4.9.4"
},

@@ -47,0 +47,0 @@ "files": [

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet