@fuman/net 0.0.2 → 0.0.4

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.
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@fuman/net",
3
3
  "type": "module",
4
- "version": "0.0.2",
4
+ "version": "0.0.4",
5
5
  "description": "experimental network abstractions",
6
6
  "license": "MIT",
7
7
  "scripts": {},
8
8
  "dependencies": {
9
- "@fuman/io": "^0.0.2",
10
- "@fuman/utils": "^0.0.1"
9
+ "@fuman/io": "^0.0.4",
10
+ "@fuman/utils": "^0.0.4"
11
11
  },
12
12
  "exports": {
13
13
  ".": {
package/reconnection.d.ts CHANGED
@@ -1,5 +1,5 @@
1
+ import { IClosable } from '@fuman/io';
1
2
  import { MaybePromise } from '@fuman/utils';
2
- import { ConnectFunction, IConnection } from './types.js';
3
3
  interface ReconnectionState {
4
4
  readonly previousWait: number | null;
5
5
  readonly consequentFails: number;
@@ -24,10 +24,10 @@ export type OnErrorAction = 'reconnect' | 'reconnect-now' | 'close';
24
24
  * then 1s with linear increase up to 5s (with 1s step)
25
25
  */
26
26
  export declare const defaultReconnectionStrategy: ReconnectionStrategy;
27
- export declare class PersistentConnection<ConnectAddress, Connection extends IConnection<unknown>> {
27
+ export declare class PersistentConnection<ConnectAddress, Connection extends IClosable> {
28
28
  #private;
29
29
  readonly params: {
30
- connect: ConnectFunction<ConnectAddress, Connection>;
30
+ connect: (address: ConnectAddress) => Promise<Connection>;
31
31
  strategy?: ReconnectionStrategy;
32
32
  /**
33
33
  * Function to call once the connection is open
@@ -47,7 +47,7 @@ export declare class PersistentConnection<ConnectAddress, Connection extends ICo
47
47
  onError?: (error: Error, connection: Connection | null, state: ReconnectionState) => MaybePromise<OnErrorAction>;
48
48
  };
49
49
  constructor(params: {
50
- connect: ConnectFunction<ConnectAddress, Connection>;
50
+ connect: (address: ConnectAddress) => Promise<Connection>;
51
51
  strategy?: ReconnectionStrategy;
52
52
  /**
53
53
  * Function to call once the connection is open
@@ -77,6 +77,6 @@ export declare class PersistentConnection<ConnectAddress, Connection extends ICo
77
77
  */
78
78
  reconnect(force: boolean): void;
79
79
  close(): Promise<void>;
80
- changeTransport(connect: ConnectFunction<ConnectAddress, Connection>): Promise<void>;
80
+ changeTransport(connect: (address: ConnectAddress) => Promise<Connection>): Promise<void>;
81
81
  }
82
82
  export {};
package/types.d.ts CHANGED
@@ -1,12 +1,18 @@
1
1
  import { IClosable, IReadable, IWritable } from '@fuman/io';
2
2
  export interface IConnection<Address, LocalAddress = Address> extends IReadable, IWritable, IClosable {
3
+ /** local address of the connection (if available) */
3
4
  readonly localAddress: LocalAddress | null;
5
+ /** remote address of the connection (if available) */
4
6
  readonly remoteAddress: Address | null;
5
7
  }
8
+ /** a TCP endpoint */
6
9
  export interface TcpEndpoint {
10
+ /** address of the endpoint */
7
11
  readonly address: string;
12
+ /** port of the endpoint */
8
13
  readonly port: number;
9
14
  }
15
+ /** common TLS options */
10
16
  export interface TlsOptions {
11
17
  /**
12
18
  * List of CA certificates to use.
@@ -18,22 +24,32 @@ export interface TlsOptions {
18
24
  /** Hostname to use for SNI */
19
25
  readonly sni?: string;
20
26
  }
27
+ /** TLS options for connecting to an endpoint */
21
28
  export interface TlsConnectOptions extends TcpEndpoint, TlsOptions {
22
29
  }
30
+ /** TLS options for listening on an endpoint */
23
31
  export interface TlsListenOptions extends TcpEndpoint, TlsOptions {
24
32
  readonly key?: string;
25
33
  readonly cert?: string;
26
34
  readonly hosts?: Omit<this, 'hosts' | 'address' | 'port'>[];
27
35
  }
36
+ /** a TCP connection */
28
37
  export interface ITcpConnection extends IConnection<TcpEndpoint> {
38
+ /** set no-delay flag on the connection */
29
39
  setNoDelay: (noDelay: boolean) => void;
40
+ /** set keep-alive flag on the connection */
30
41
  setKeepAlive: (keepAlive: boolean) => void;
31
42
  }
43
+ /** a TLS connection */
32
44
  export interface ITlsConnection extends ITcpConnection {
45
+ /** get the ALPN protocol that was negotiated in the handshake */
33
46
  getAlpnProtocol: () => string | null;
34
47
  }
48
+ /** a listener for connections */
35
49
  export interface IListener<Address, Connection extends IConnection<Address> = IConnection<Address>> extends IClosable {
50
+ /** address of the listener (if available) */
36
51
  readonly address: Address | null;
52
+ /** accept a new connection */
37
53
  accept: () => Promise<Connection>;
38
54
  }
39
55
  export type ListenFunction<Options, Listener extends IListener<unknown>> = (options: Options) => Promise<Listener>;
package/websocket.cjs CHANGED
@@ -25,10 +25,12 @@ class WebSocketConnectionBase {
25
25
  this._cv.notify();
26
26
  });
27
27
  socket.addEventListener("close", (event) => {
28
+ if (this._error) return;
28
29
  this._error = new WebSocketConnectionClosedError(event.code, event.reason);
29
30
  this._cv.notify();
30
31
  });
31
32
  socket.addEventListener("error", (event) => {
33
+ if (this._error) return;
32
34
  this._error = eventToError(event);
33
35
  this._cv.notify();
34
36
  });
@@ -44,18 +46,16 @@ class WebSocketConnectionBase {
44
46
  close() {
45
47
  this.socket?.close();
46
48
  this._error = new errors.ConnectionClosedError();
49
+ this._cv.notify();
47
50
  }
48
51
  closeWithCode(code, reason) {
49
52
  this.socket.close(code, reason);
50
- this._error = new errors.ConnectionClosedError();
53
+ this._error = new WebSocketConnectionClosedError(code, reason ?? "");
54
+ this._cv.notify();
51
55
  }
52
56
  }
53
57
  class WebSocketConnection extends WebSocketConnectionBase {
54
- #buffer;
55
- constructor(socket) {
56
- super(socket);
57
- this.#buffer = io.Bytes.alloc(0);
58
- }
58
+ #buffer = io.Bytes.alloc(0);
59
59
  onMessage(event) {
60
60
  if (typeof event.data === "string") {
61
61
  const buf = this.#buffer.writeSync(utils.utf8.encodedLength(event.data));
package/websocket.d.ts CHANGED
@@ -20,7 +20,6 @@ declare abstract class WebSocketConnectionBase implements IClosable {
20
20
  }
21
21
  export declare class WebSocketConnection extends WebSocketConnectionBase implements IConnection<string, never> {
22
22
  #private;
23
- constructor(socket: WebSocket);
24
23
  onMessage(event: MessageEvent): void;
25
24
  read(into: Uint8Array): Promise<number>;
26
25
  write(bytes: Uint8Array): Promise<void>;
package/websocket.js CHANGED
@@ -23,10 +23,12 @@ class WebSocketConnectionBase {
23
23
  this._cv.notify();
24
24
  });
25
25
  socket.addEventListener("close", (event) => {
26
+ if (this._error) return;
26
27
  this._error = new WebSocketConnectionClosedError(event.code, event.reason);
27
28
  this._cv.notify();
28
29
  });
29
30
  socket.addEventListener("error", (event) => {
31
+ if (this._error) return;
30
32
  this._error = eventToError(event);
31
33
  this._cv.notify();
32
34
  });
@@ -42,18 +44,16 @@ class WebSocketConnectionBase {
42
44
  close() {
43
45
  this.socket?.close();
44
46
  this._error = new ConnectionClosedError();
47
+ this._cv.notify();
45
48
  }
46
49
  closeWithCode(code, reason) {
47
50
  this.socket.close(code, reason);
48
- this._error = new ConnectionClosedError();
51
+ this._error = new WebSocketConnectionClosedError(code, reason ?? "");
52
+ this._cv.notify();
49
53
  }
50
54
  }
51
55
  class WebSocketConnection extends WebSocketConnectionBase {
52
- #buffer;
53
- constructor(socket) {
54
- super(socket);
55
- this.#buffer = Bytes.alloc(0);
56
- }
56
+ #buffer = Bytes.alloc(0);
57
57
  onMessage(event) {
58
58
  if (typeof event.data === "string") {
59
59
  const buf = this.#buffer.writeSync(utf8.encodedLength(event.data));