Skip to content

Commit ace0e1c

Browse files
authored
fix: Fix createServer() to properly handle Node.js-compatible options parameter (#210)
1 parent 6d2fcae commit ace0e1c

File tree

5 files changed

+224
-45
lines changed

5 files changed

+224
-45
lines changed

__tests__/index.test.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { expect, test } from '@jest/globals';
2+
23
import net from '../src/index';
34

45
test('create-client', () => {
@@ -11,15 +12,36 @@ test('create-client', () => {
1112
// interface: "wifi"
1213
};
1314

14-
const socket = net.createConnection(options, () => {});
15+
const socket = net.createConnection(options, () => { });
1516
expect(socket).toBeInstanceOf(net.Socket);
1617
});
1718

1819
test('create-server', () => {
19-
const server = net.createServer(() => {});
20+
const server = net.createServer(() => { });
21+
expect(server).toBeInstanceOf(net.Server);
22+
});
23+
24+
test('create-server-with-options', () => {
25+
const server = net.createServer({
26+
noDelay: true,
27+
keepAlive: true
28+
}, () => {
29+
console.info('server started')
30+
});
2031
expect(server).toBeInstanceOf(net.Server);
2132
});
2233

34+
test('create-server-options-no-calback', () => {
35+
const server = net.createServer({
36+
noDelay: true,
37+
keepAlive: true
38+
});
39+
server.on('connection', () => {
40+
console.info('connection received');
41+
});
42+
});
43+
44+
2345
test('isIP', () => {
2446
expect(net.isIP('127.9.8.9')).toBe(4);
2547
expect(net.isIP('127.9.8..')).toBe(0);

lib/types/Server.d.ts

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
/**
2+
* @typedef {object} ServerOptions
3+
* @property {boolean} [noDelay]
4+
* @property {boolean} [keepAlive]
5+
* @property {number} [keepAliveInitialDelay]
6+
* @property {boolean} [allowHalfOpen]
7+
* @property {boolean} [pauseOnConnect]
8+
*
29
* @typedef {import('./TLSSocket').default} TLSSocket
310
*
411
* @typedef {object} ServerEvents
@@ -12,22 +19,27 @@
1219
*/
1320
export default class Server extends EventEmitter<ServerEvents, any> {
1421
/**
22+
* @param {ServerOptions | ((socket: Socket) => void)} [options] Server options or connection listener
1523
* @param {(socket: Socket) => void} [connectionCallback] Automatically set as a listener for the `'connection'` event.
1624
*/
17-
constructor(connectionCallback?: ((socket: Socket) => void) | undefined);
25+
constructor(options?: ServerOptions | ((socket: Socket) => void), connectionCallback?: (socket: Socket) => void);
26+
1827
/** @protected @readonly */
1928
protected readonly _id: number;
2029
/** @protected @readonly */
2130
protected readonly _eventEmitter: import("react-native").EventEmitter;
2231
/** @private @type {Set<Socket>} */
23-
private _connections;
32+
private _connections: Set<Socket>;
2433
/** @private */
25-
private _localAddress;
34+
private _localAddress: string | undefined;
2635
/** @private */
27-
private _localPort;
36+
private _localPort: number | undefined;
2837
/** @private */
29-
private _localFamily;
38+
private _localFamily: string | undefined;
39+
/** @private */
40+
private _serverOptions: ServerOptions;
3041
listening: boolean;
42+
3143
/**
3244
* Start a server listening for connections.
3345
*
@@ -38,15 +50,15 @@ export default class Server extends EventEmitter<ServerEvents, any> {
3850
* `server.listen()` call or `server.close()` has been called. Otherwise, an `ERR_SERVER_ALREADY_LISTEN`
3951
* error will be thrown.
4052
*
41-
* @param {{ port: number; host: string; reuseAddress?: boolean}} options
53+
* @param {{ port: number; host?: string; reuseAddress?: boolean} | number} options
54+
* @param {string | (() => void)} [callback_or_host]
4255
* @param {() => void} [callback]
4356
* @returns {Server}
4457
*/
45-
listen(options: {
46-
port: number;
47-
host: string;
48-
reuseAddress?: boolean;
49-
}, callback?: (() => void) | undefined): Server;
58+
listen(options: { port: number; host?: string; reuseAddress?: boolean } | number,
59+
callback_or_host?: string | (() => void),
60+
callback?: () => void): Server;
61+
5062
/**
5163
* Asynchronously get the number of concurrent connections on the server.
5264
*
@@ -56,6 +68,7 @@ export default class Server extends EventEmitter<ServerEvents, any> {
5668
* @returns {Server}
5769
*/
5870
getConnections(callback: (err: Error | null, count: number) => void): Server;
71+
5972
/**
6073
* Stops the server from accepting new connections and keeps existing connections.
6174
* This function is asynchronous, the server is finally closed when all connections are ended and the server emits a `'close'` event.
@@ -65,7 +78,8 @@ export default class Server extends EventEmitter<ServerEvents, any> {
6578
* @param {(err?: Error) => void} [callback] Called when the server is closed.
6679
* @returns {Server}
6780
*/
68-
close(callback?: ((err?: Error | undefined) => void) | undefined): Server;
81+
close(callback?: (err?: Error) => void): Server;
82+
6983
/**
7084
* Returns the bound `address`, the address `family` name, and `port` of the server as reported by the operating system if listening
7185
* on an IP socket (useful to find which port was assigned when getting an OS-assigned address):
@@ -74,24 +88,26 @@ export default class Server extends EventEmitter<ServerEvents, any> {
7488
* @returns {import('./Socket').AddressInfo | null}
7589
*/
7690
address(): import('./Socket').AddressInfo | null;
91+
7792
ref(): Server;
7893
unref(): Server;
94+
7995
/**
8096
* @private
8197
*/
82-
private _registerEvents;
83-
_listeningListener: import("react-native").EmitterSubscription | undefined;
84-
_errorListener: import("react-native").EmitterSubscription | undefined;
85-
_connectionsListener: import("react-native").EmitterSubscription | undefined;
98+
private _registerEvents(): void;
99+
86100
/**
87101
* @private
88102
*/
89-
private _setDisconnected;
103+
private _setDisconnected(): void;
104+
90105
/**
91106
* @protected
92107
* @param {Socket} socket
93108
*/
94109
protected _addConnection(socket: Socket): void;
110+
95111
/**
96112
* @protected
97113
* @param {{ id: number; connection: import('./Socket').NativeConnectionInfo; }} info
@@ -101,14 +117,32 @@ export default class Server extends EventEmitter<ServerEvents, any> {
101117
id: number;
102118
connection: import('./Socket').NativeConnectionInfo;
103119
}): Socket;
120+
121+
/**
122+
* Apply server socket options to a newly connected socket
123+
* @param {Socket} socket
124+
* @private
125+
*/
126+
private _applySocketOptions(socket: Socket): void;
104127
}
128+
129+
export type ServerOptions = {
130+
noDelay?: boolean;
131+
keepAlive?: boolean;
132+
keepAliveInitialDelay?: number;
133+
allowHalfOpen?: boolean;
134+
pauseOnConnect?: boolean;
135+
};
136+
105137
export type TLSSocket = import("./TLSSocket").default;
138+
106139
export type ServerEvents = {
107140
close: () => void;
108141
connection: (socket: Socket) => void;
109142
listening: () => void;
110143
error: (err: Error) => void;
111144
secureConnection: (tlsSocket: TLSSocket) => void;
112145
};
146+
113147
import EventEmitter from "eventemitter3";
114-
import Socket from "./Socket";
148+
import Socket from "./Socket";

lib/types/index.d.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,49 @@ export default _default;
1919
* @param {() => void} callback
2020
* @returns {Socket}
2121
*/
22-
declare function createConnection(options: import('./Socket').ConnectionOptions, callback: () => void): Socket;
22+
declare function createConnection(
23+
options: import('./Socket').ConnectionOptions,
24+
callback: () => void
25+
): Socket;
2326
/**
24-
* @param {(socket: Socket) => void} connectionListener
27+
* @typedef {object} ServerOptions
28+
* @property {boolean} [noDelay]
29+
* @property {boolean} [keepAlive]
30+
* @property {number} [keepAliveInitialDelay]
31+
* @property {boolean} [allowHalfOpen]
32+
* @property {boolean} [pauseOnConnect]
33+
*/
34+
35+
/**
36+
* @param {ServerOptions | ((socket: Socket) => void)} [options]
37+
* @param {(socket: Socket) => void} [connectionListener]
2538
* @returns {Server}
2639
*/
27-
declare function createServer(connectionListener: (socket: Socket) => void): Server;
40+
declare function createServer(
41+
options?: object | ((socket: Socket) => void),
42+
connectionListener?: (socket: Socket) => void
43+
): Server;
44+
2845
/**
2946
* @param {import('./TLSServer').TLSServerOptions} options
3047
* @param {(socket: TLSSocket) => void} connectionListener
3148
* @returns {TLSServer}
3249
*/
33-
declare function createTLSServer(options: import('./TLSServer').TLSServerOptions, connectionListener: (socket: TLSSocket) => void): TLSServer;
50+
declare function createTLSServer(
51+
options: import('./TLSServer').TLSServerOptions,
52+
connectionListener: (socket: TLSSocket) => void
53+
): TLSServer;
3454
/**
3555
* The `callback` function, if specified, will be added as a listener for the `'secureConnect'` event.
3656
*
3757
* @param {import('./TLSSocket').TLSSocketOptions & import('./Socket').ConnectionOptions} options
3858
* @param {() => void} [callback]
3959
* @returns {TLSSocket}
4060
*/
41-
declare function connectTLS(options: import('./TLSSocket').TLSSocketOptions & import('./Socket').ConnectionOptions, callback?: (() => void) | undefined): TLSSocket;
61+
declare function connectTLS(
62+
options: import('./TLSSocket').TLSSocketOptions & import('./Socket').ConnectionOptions,
63+
callback?: (() => void) | undefined
64+
): TLSSocket;
4265
/**
4366
* Tests if input is an IP address. Returns `0` for invalid strings, returns `4` for IP version 4 addresses, and returns `6` for IP version 6 addresses.
4467
*
@@ -57,7 +80,7 @@ declare function isIPv4(input: string): boolean;
5780
* @param {string} input
5881
*/
5982
declare function isIPv6(input: string): boolean;
60-
import Server from "./Server";
61-
import Socket from "./Socket";
62-
import TLSServer from "./TLSServer";
63-
import TLSSocket from "./TLSSocket";
83+
import Server from './Server';
84+
import Socket from './Socket';
85+
import TLSServer from './TLSServer';
86+
import TLSSocket from './TLSSocket';

0 commit comments

Comments
 (0)