@zimic/interceptor 0.15.0-canary.0 → 0.15.0-canary.2
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/README.md +6 -7
- package/dist/{chunk-YGJD3JT6.mjs → chunk-3O3YPVEG.mjs} +69 -104
- package/dist/chunk-3O3YPVEG.mjs.map +1 -0
- package/dist/{chunk-L6Y4EV6T.js → chunk-CWBDZYUG.js} +69 -104
- package/dist/chunk-CWBDZYUG.js.map +1 -0
- package/dist/cli.js +7 -7
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +3 -3
- package/dist/cli.mjs.map +1 -1
- package/dist/http.d.ts +38 -35
- package/dist/http.js +173 -235
- package/dist/http.js.map +1 -1
- package/dist/http.mjs +173 -235
- package/dist/http.mjs.map +1 -1
- package/dist/server.d.ts +15 -10
- package/dist/server.js +5 -5
- package/dist/server.mjs +1 -1
- package/package.json +10 -10
- package/src/cli/server/start.ts +1 -1
- package/src/http/interceptor/HttpInterceptorClient.ts +23 -34
- package/src/http/interceptor/HttpInterceptorStore.ts +2 -2
- package/src/http/interceptor/LocalHttpInterceptor.ts +22 -25
- package/src/http/interceptor/RemoteHttpInterceptor.ts +22 -25
- package/src/http/interceptor/errors/NotStartedHttpInterceptorError.ts +1 -1
- package/src/http/interceptor/errors/UnknownHttpInterceptorPlatformError.ts +1 -1
- package/src/http/interceptor/types/options.ts +3 -3
- package/src/http/interceptor/types/public.ts +12 -9
- package/src/http/interceptorWorker/HttpInterceptorWorker.ts +10 -28
- package/src/http/interceptorWorker/LocalHttpInterceptorWorker.ts +21 -25
- package/src/http/interceptorWorker/RemoteHttpInterceptorWorker.ts +22 -26
- package/src/http/requestHandler/HttpRequestHandlerClient.ts +11 -22
- package/src/http/requestHandler/LocalHttpRequestHandler.ts +16 -20
- package/src/http/requestHandler/RemoteHttpRequestHandler.ts +18 -28
- package/src/http/requestHandler/types/public.ts +22 -24
- package/src/server/InterceptorServer.ts +45 -68
- package/src/server/types/public.ts +15 -10
- package/src/webSocket/WebSocketClient.ts +1 -1
- package/src/webSocket/WebSocketHandler.ts +11 -19
- package/src/webSocket/WebSocketServer.ts +4 -4
- package/dist/chunk-L6Y4EV6T.js.map +0 -1
- package/dist/chunk-YGJD3JT6.mjs.map +0 -1
|
@@ -30,17 +30,19 @@ export interface HttpRequestHandler<
|
|
|
30
30
|
Path extends HttpSchemaPath<Schema, Method>,
|
|
31
31
|
> {
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
33
|
+
* The method that matches this handler.
|
|
34
|
+
*
|
|
35
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlermethod `handler.method` API reference}
|
|
35
36
|
*/
|
|
36
|
-
method:
|
|
37
|
+
method: Method;
|
|
37
38
|
|
|
38
39
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
40
|
+
* The path that matches this handler. The base URL of the interceptor is not included, but it is used when matching
|
|
41
|
+
* requests.
|
|
42
|
+
*
|
|
43
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerpath `handler.path` API reference}
|
|
42
44
|
*/
|
|
43
|
-
path:
|
|
45
|
+
path: Path;
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
export interface InternalHttpRequestHandler<
|
|
@@ -49,7 +51,7 @@ export interface InternalHttpRequestHandler<
|
|
|
49
51
|
Path extends HttpSchemaPath<Schema, Method>,
|
|
50
52
|
StatusCode extends HttpStatusCode = never,
|
|
51
53
|
> extends HttpRequestHandler<Schema, Method, Path> {
|
|
52
|
-
client:
|
|
54
|
+
client: HttpRequestHandlerClient<Schema, Method, Path, StatusCode>;
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
/**
|
|
@@ -118,7 +120,7 @@ export interface LocalHttpRequestHandler<
|
|
|
118
120
|
* intercepted request in the
|
|
119
121
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}.
|
|
120
122
|
*
|
|
121
|
-
* **
|
|
123
|
+
* **Important**: To make sure that all expected requests were made, use
|
|
122
124
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorchecktimes `interceptor.checkTimes()`}
|
|
123
125
|
* or {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlertimes `handler.times()`}.
|
|
124
126
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorchecktimes `interceptor.checkTimes()`}
|
|
@@ -170,18 +172,17 @@ export interface LocalHttpRequestHandler<
|
|
|
170
172
|
clear: () => this;
|
|
171
173
|
|
|
172
174
|
/**
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
+
* The intercepted requests that matched this handler, along with the responses returned to each of them. This is
|
|
176
|
+
* useful for testing that the correct requests were made by your application.
|
|
175
177
|
*
|
|
176
|
-
* **
|
|
178
|
+
* **Important**: This method can only be used if `saveRequests` was set to `true` when creating the interceptor. See
|
|
177
179
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
|
|
178
180
|
* for more information.
|
|
179
181
|
*
|
|
180
|
-
* @returns The intercepted requests.
|
|
181
182
|
* @throws {DisabledRequestSavingError} If the interceptor was not created with `saveRequests: true`.
|
|
182
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests
|
|
183
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests` API reference}
|
|
183
184
|
*/
|
|
184
|
-
requests:
|
|
185
|
+
requests: readonly InterceptedHttpInterceptorRequest<Path, Default<Schema[Path][Method]>, StatusCode>[];
|
|
185
186
|
}
|
|
186
187
|
|
|
187
188
|
/**
|
|
@@ -249,7 +250,7 @@ export interface SyncedRemoteHttpRequestHandler<
|
|
|
249
250
|
* intercepted request in the
|
|
250
251
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptormethodpath `interceptor.<method>(path)` API reference}.
|
|
251
252
|
*
|
|
252
|
-
* **
|
|
253
|
+
* **Important**: To make sure that all expected requests were made, use
|
|
253
254
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-interceptorchecktimes `interceptor.checkTimes()`}
|
|
254
255
|
* or
|
|
255
256
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerchecktimes `handler.checkTimes()`}.
|
|
@@ -306,20 +307,17 @@ export interface SyncedRemoteHttpRequestHandler<
|
|
|
306
307
|
clear: () => PendingRemoteHttpRequestHandler<Schema, Method, Path, StatusCode>;
|
|
307
308
|
|
|
308
309
|
/**
|
|
309
|
-
*
|
|
310
|
-
*
|
|
310
|
+
* The intercepted requests that matched this handler, along with the responses returned to each of them. This is
|
|
311
|
+
* useful for testing that the correct requests were made by your application.
|
|
311
312
|
*
|
|
312
|
-
* **
|
|
313
|
+
* **Important**: This method can only be used if `saveRequests` was set to `true` when creating the interceptor. See
|
|
313
314
|
* {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
|
|
314
315
|
* for more information.
|
|
315
316
|
*
|
|
316
|
-
* @returns The intercepted requests.
|
|
317
317
|
* @throws {DisabledRequestSavingError} If the interceptor was not created with `saveRequests: true`.
|
|
318
|
-
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests
|
|
318
|
+
* @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests` API reference}
|
|
319
319
|
*/
|
|
320
|
-
requests:
|
|
321
|
-
readonly InterceptedHttpInterceptorRequest<Path, Default<Schema[Path][Method]>, StatusCode>[]
|
|
322
|
-
>;
|
|
320
|
+
requests: readonly InterceptedHttpInterceptorRequest<Path, Default<Schema[Path][Method]>, StatusCode>[];
|
|
323
321
|
}
|
|
324
322
|
|
|
325
323
|
/**
|
|
@@ -34,12 +34,12 @@ interface HttpHandler {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
class InterceptorServer implements PublicInterceptorServer {
|
|
37
|
-
private
|
|
38
|
-
private
|
|
37
|
+
private httpServer?: HttpServer;
|
|
38
|
+
private webSocketServer?: WebSocketServer<InterceptorServerWebSocketSchema>;
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
hostname: string;
|
|
41
|
+
port: number | undefined;
|
|
42
|
+
logUnhandledRequests: boolean;
|
|
43
43
|
|
|
44
44
|
private httpHandlerGroups: {
|
|
45
45
|
[Method in HttpMethod]: HttpHandler[];
|
|
@@ -56,87 +56,71 @@ class InterceptorServer implements PublicInterceptorServer {
|
|
|
56
56
|
private knownWorkerSockets = new Set<Socket>();
|
|
57
57
|
|
|
58
58
|
constructor(options: InterceptorServerOptions) {
|
|
59
|
-
this.
|
|
60
|
-
this.
|
|
61
|
-
this.
|
|
59
|
+
this.hostname = options.hostname ?? 'localhost';
|
|
60
|
+
this.port = options.port;
|
|
61
|
+
this.logUnhandledRequests = options.logUnhandledRequests ?? DEFAULT_LOG_UNHANDLED_REQUESTS;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
port() {
|
|
69
|
-
return this._port;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
logUnhandledRequests() {
|
|
73
|
-
return this._logUnhandledRequests;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
httpURL() {
|
|
77
|
-
if (this._port === undefined) {
|
|
64
|
+
get httpURL() {
|
|
65
|
+
if (this.port === undefined) {
|
|
78
66
|
return undefined;
|
|
79
67
|
}
|
|
80
|
-
return `http://${this.
|
|
68
|
+
return `http://${this.hostname}:${this.port}`;
|
|
81
69
|
}
|
|
82
70
|
|
|
83
|
-
isRunning() {
|
|
84
|
-
return !!this.
|
|
71
|
+
get isRunning() {
|
|
72
|
+
return !!this.httpServer?.listening && !!this.webSocketServer?.isRunning;
|
|
85
73
|
}
|
|
86
74
|
|
|
87
|
-
private
|
|
75
|
+
private get httpServerOrThrow(): HttpServer {
|
|
88
76
|
/* istanbul ignore if -- @preserve
|
|
89
77
|
* The HTTP server is initialized before using this method in normal conditions. */
|
|
90
|
-
if (!this.
|
|
78
|
+
if (!this.httpServer) {
|
|
91
79
|
throw new NotStartedInterceptorServerError();
|
|
92
80
|
}
|
|
93
|
-
return this.
|
|
81
|
+
return this.httpServer;
|
|
94
82
|
}
|
|
95
83
|
|
|
96
|
-
private
|
|
84
|
+
private get webSocketServerOrThrow(): WebSocketServer<InterceptorServerWebSocketSchema> {
|
|
97
85
|
/* istanbul ignore if -- @preserve
|
|
98
86
|
* The web socket server is initialized before using this method in normal conditions. */
|
|
99
|
-
if (!this.
|
|
87
|
+
if (!this.webSocketServer) {
|
|
100
88
|
throw new NotStartedInterceptorServerError();
|
|
101
89
|
}
|
|
102
|
-
return this.
|
|
90
|
+
return this.webSocketServer;
|
|
103
91
|
}
|
|
104
92
|
|
|
105
93
|
async start() {
|
|
106
|
-
if (this.isRunning
|
|
94
|
+
if (this.isRunning) {
|
|
107
95
|
return;
|
|
108
96
|
}
|
|
109
97
|
|
|
110
|
-
this.
|
|
98
|
+
this.httpServer = createServer({
|
|
111
99
|
keepAlive: true,
|
|
112
100
|
joinDuplicateHeaders: true,
|
|
113
101
|
});
|
|
114
102
|
await this.startHttpServer();
|
|
115
103
|
|
|
116
|
-
this.
|
|
117
|
-
httpServer: this.
|
|
104
|
+
this.webSocketServer = new WebSocketServer({
|
|
105
|
+
httpServer: this.httpServer,
|
|
118
106
|
});
|
|
119
107
|
this.startWebSocketServer();
|
|
120
108
|
}
|
|
121
109
|
|
|
122
110
|
private async startHttpServer() {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
hostname: this._hostname,
|
|
127
|
-
port: this._port,
|
|
111
|
+
await startHttpServer(this.httpServerOrThrow, {
|
|
112
|
+
hostname: this.hostname,
|
|
113
|
+
port: this.port,
|
|
128
114
|
});
|
|
129
|
-
this.
|
|
115
|
+
this.port = getHttpServerPort(this.httpServerOrThrow);
|
|
130
116
|
|
|
131
|
-
|
|
117
|
+
this.httpServerOrThrow.on('request', this.handleHttpRequest);
|
|
132
118
|
}
|
|
133
119
|
|
|
134
120
|
private startWebSocketServer() {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
webSocketServer.onEvent('interceptors/workers/use/commit', this.commitWorker);
|
|
139
|
-
webSocketServer.onEvent('interceptors/workers/use/reset', this.resetWorker);
|
|
121
|
+
this.webSocketServerOrThrow.start();
|
|
122
|
+
this.webSocketServerOrThrow.onEvent('interceptors/workers/use/commit', this.commitWorker);
|
|
123
|
+
this.webSocketServerOrThrow.onEvent('interceptors/workers/use/reset', this.resetWorker);
|
|
140
124
|
}
|
|
141
125
|
|
|
142
126
|
private commitWorker = (
|
|
@@ -161,7 +145,7 @@ class InterceptorServer implements PublicInterceptorServer {
|
|
|
161
145
|
if (isWorkerNoLongerCommitted) {
|
|
162
146
|
// When a worker is no longer committed, we should abort all requests that were using it.
|
|
163
147
|
// This ensures that we only wait for responses from committed worker sockets.
|
|
164
|
-
this.
|
|
148
|
+
this.webSocketServerOrThrow.abortSocketMessages([socket]);
|
|
165
149
|
} else {
|
|
166
150
|
for (const handler of handlersToResetTo) {
|
|
167
151
|
this.registerHttpHandler(handler, socket);
|
|
@@ -209,32 +193,28 @@ class InterceptorServer implements PublicInterceptorServer {
|
|
|
209
193
|
}
|
|
210
194
|
}
|
|
211
195
|
|
|
212
|
-
|
|
213
|
-
if (!this.isRunning
|
|
196
|
+
async stop() {
|
|
197
|
+
if (!this.isRunning) {
|
|
214
198
|
return;
|
|
215
199
|
}
|
|
216
200
|
|
|
217
201
|
await this.stopWebSocketServer();
|
|
218
202
|
await this.stopHttpServer();
|
|
219
|
-
}
|
|
203
|
+
}
|
|
220
204
|
|
|
221
205
|
private async stopHttpServer() {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
httpServer.removeAllListeners();
|
|
226
|
-
|
|
227
|
-
this._httpServer = undefined;
|
|
206
|
+
await stopHttpServer(this.httpServerOrThrow);
|
|
207
|
+
this.httpServerOrThrow.removeAllListeners();
|
|
208
|
+
this.httpServer = undefined;
|
|
228
209
|
}
|
|
229
210
|
|
|
230
211
|
private async stopWebSocketServer() {
|
|
231
|
-
|
|
212
|
+
this.webSocketServerOrThrow.offEvent('interceptors/workers/use/commit', this.commitWorker);
|
|
213
|
+
this.webSocketServerOrThrow.offEvent('interceptors/workers/use/reset', this.resetWorker);
|
|
232
214
|
|
|
233
|
-
|
|
234
|
-
webSocketServer.offEvent('interceptors/workers/use/reset', this.resetWorker);
|
|
235
|
-
await webSocketServer.stop();
|
|
215
|
+
await this.webSocketServerOrThrow.stop();
|
|
236
216
|
|
|
237
|
-
this.
|
|
217
|
+
this.webSocketServer = undefined;
|
|
238
218
|
}
|
|
239
219
|
|
|
240
220
|
private handleHttpRequest = async (nodeRequest: IncomingMessage, nodeResponse: ServerResponse) => {
|
|
@@ -278,7 +258,6 @@ class InterceptorServer implements PublicInterceptorServer {
|
|
|
278
258
|
};
|
|
279
259
|
|
|
280
260
|
private async createResponseForRequest(request: SerializedHttpRequest) {
|
|
281
|
-
const webSocketServer = this.webSocketServer();
|
|
282
261
|
const methodHandlers = this.httpHandlerGroups[request.method as HttpMethod];
|
|
283
262
|
|
|
284
263
|
const requestURL = excludeURLParams(new URL(request.url)).toString();
|
|
@@ -295,7 +274,7 @@ class InterceptorServer implements PublicInterceptorServer {
|
|
|
295
274
|
|
|
296
275
|
matchedSomeInterceptor = true;
|
|
297
276
|
|
|
298
|
-
const { response: serializedResponse } = await
|
|
277
|
+
const { response: serializedResponse } = await this.webSocketServerOrThrow.request(
|
|
299
278
|
'interceptors/responses/create',
|
|
300
279
|
{ handlerId: handler.id, request },
|
|
301
280
|
{ sockets: [handler.socket] },
|
|
@@ -329,13 +308,11 @@ class InterceptorServer implements PublicInterceptorServer {
|
|
|
329
308
|
}
|
|
330
309
|
|
|
331
310
|
private async logUnhandledRequestIfNecessary(request: HttpRequest, serializedRequest: SerializedHttpRequest) {
|
|
332
|
-
const webSocketServer = this.webSocketServer();
|
|
333
|
-
|
|
334
311
|
const handler = this.findHttpHandlerByRequestBaseURL(request);
|
|
335
312
|
|
|
336
313
|
if (handler) {
|
|
337
314
|
try {
|
|
338
|
-
const { wasLogged: wasRequestLoggedByRemoteInterceptor } = await
|
|
315
|
+
const { wasLogged: wasRequestLoggedByRemoteInterceptor } = await this.webSocketServerOrThrow.request(
|
|
339
316
|
'interceptors/responses/unhandled',
|
|
340
317
|
{ request: serializedRequest },
|
|
341
318
|
{ sockets: [handler.socket] },
|
|
@@ -357,7 +334,7 @@ class InterceptorServer implements PublicInterceptorServer {
|
|
|
357
334
|
}
|
|
358
335
|
}
|
|
359
336
|
|
|
360
|
-
if (!this.
|
|
337
|
+
if (!this.logUnhandledRequests) {
|
|
361
338
|
return;
|
|
362
339
|
}
|
|
363
340
|
|
|
@@ -6,35 +6,40 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export interface InterceptorServer {
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* The hostname of the server.
|
|
10
|
+
*
|
|
10
11
|
* @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server `zimic-interceptor server` API reference}
|
|
11
12
|
*/
|
|
12
|
-
hostname:
|
|
13
|
+
hostname: string;
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
+
* The port of the server.
|
|
17
|
+
*
|
|
16
18
|
* @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server `zimic-interceptor server` API reference}
|
|
17
19
|
*/
|
|
18
|
-
port:
|
|
20
|
+
port: number | undefined;
|
|
19
21
|
|
|
20
22
|
/**
|
|
23
|
+
* Whether to log warnings about unhandled requests to the console.
|
|
24
|
+
*
|
|
21
25
|
* @default true
|
|
22
|
-
* @returns Whether to log warnings about unhandled requests to the console.
|
|
23
26
|
* @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server `zimic-interceptor server` API reference}
|
|
24
27
|
*/
|
|
25
|
-
logUnhandledRequests:
|
|
28
|
+
logUnhandledRequests: boolean;
|
|
26
29
|
|
|
27
30
|
/**
|
|
28
|
-
*
|
|
31
|
+
* The HTTP URL of the server.
|
|
32
|
+
*
|
|
29
33
|
* @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server `zimic-interceptor server` API reference}
|
|
30
34
|
*/
|
|
31
|
-
httpURL:
|
|
35
|
+
httpURL: string | undefined;
|
|
32
36
|
|
|
33
37
|
/**
|
|
34
|
-
*
|
|
38
|
+
* Whether the server is running.
|
|
39
|
+
*
|
|
35
40
|
* @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server `zimic-interceptor server` API reference}
|
|
36
41
|
*/
|
|
37
|
-
isRunning:
|
|
42
|
+
isRunning: boolean;
|
|
38
43
|
|
|
39
44
|
/**
|
|
40
45
|
* Starts the server.
|
|
@@ -27,7 +27,7 @@ class WebSocketClient<Schema extends WebSocket.ServiceSchema> extends WebSocketH
|
|
|
27
27
|
validateURLProtocol(this.url, SUPPORTED_WEB_SOCKET_PROTOCOLS);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
isRunning() {
|
|
30
|
+
get isRunning() {
|
|
31
31
|
return this.socket !== undefined && this.socket.readyState === this.socket.OPEN;
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -18,8 +18,8 @@ import { WebSocket } from './types';
|
|
|
18
18
|
abstract class WebSocketHandler<Schema extends WebSocket.ServiceSchema> {
|
|
19
19
|
private sockets = new Set<ClientSocket>();
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
socketTimeout: number;
|
|
22
|
+
messageTimeout: number;
|
|
23
23
|
|
|
24
24
|
private channelListeners: {
|
|
25
25
|
[Channel in WebSocket.ServiceChannel<Schema>]?: {
|
|
@@ -33,22 +33,14 @@ abstract class WebSocketHandler<Schema extends WebSocket.ServiceSchema> {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
protected constructor(options: { socketTimeout?: number; messageTimeout?: number }) {
|
|
36
|
-
this.
|
|
37
|
-
this.
|
|
36
|
+
this.socketTimeout = options.socketTimeout ?? DEFAULT_WEB_SOCKET_LIFECYCLE_TIMEOUT;
|
|
37
|
+
this.messageTimeout = options.messageTimeout ?? DEFAULT_WEB_SOCKET_MESSAGE_TIMEOUT;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
abstract isRunning
|
|
41
|
-
|
|
42
|
-
socketTimeout() {
|
|
43
|
-
return this._socketTimeout;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
messageTimeout() {
|
|
47
|
-
return this._messageTimeout;
|
|
48
|
-
}
|
|
40
|
+
abstract isRunning: boolean;
|
|
49
41
|
|
|
50
42
|
protected async registerSocket(socket: ClientSocket) {
|
|
51
|
-
const openPromise = waitForOpenClientSocket(socket, { timeout: this.
|
|
43
|
+
const openPromise = waitForOpenClientSocket(socket, { timeout: this.socketTimeout });
|
|
52
44
|
|
|
53
45
|
const handleSocketMessage = async (rawMessage: ClientSocket.MessageEvent) => {
|
|
54
46
|
await this.handleSocketMessage(socket, rawMessage);
|
|
@@ -173,7 +165,7 @@ abstract class WebSocketHandler<Schema extends WebSocket.ServiceSchema> {
|
|
|
173
165
|
|
|
174
166
|
protected async closeClientSockets(sockets: Collection<ClientSocket> = this.sockets) {
|
|
175
167
|
const closingPromises = Array.from(sockets, async (socket) => {
|
|
176
|
-
await closeClientSocket(socket, { timeout: this.
|
|
168
|
+
await closeClientSocket(socket, { timeout: this.socketTimeout });
|
|
177
169
|
});
|
|
178
170
|
await Promise.all(closingPromises);
|
|
179
171
|
}
|
|
@@ -232,9 +224,9 @@ abstract class WebSocketHandler<Schema extends WebSocket.ServiceSchema> {
|
|
|
232
224
|
this.offReply(channel, replyListener); // eslint-disable-line @typescript-eslint/no-use-before-define
|
|
233
225
|
this.offAbortSocketMessages(sockets, abortListener); // eslint-disable-line @typescript-eslint/no-use-before-define
|
|
234
226
|
|
|
235
|
-
const timeoutError = new WebSocketMessageTimeoutError(this.
|
|
227
|
+
const timeoutError = new WebSocketMessageTimeoutError(this.messageTimeout);
|
|
236
228
|
reject(timeoutError);
|
|
237
|
-
}, this.
|
|
229
|
+
}, this.messageTimeout);
|
|
238
230
|
|
|
239
231
|
const abortListener = this.onAbortSocketMessages(sockets, (error) => {
|
|
240
232
|
clearTimeout(replyTimeout);
|
|
@@ -274,7 +266,7 @@ abstract class WebSocketHandler<Schema extends WebSocket.ServiceSchema> {
|
|
|
274
266
|
const reply = await this.createReplyMessage(request, replyData);
|
|
275
267
|
|
|
276
268
|
// If this handler received a request and was stopped before responding, discard any pending replies.
|
|
277
|
-
if (this.isRunning
|
|
269
|
+
if (this.isRunning) {
|
|
278
270
|
this.sendMessage(reply, options.sockets);
|
|
279
271
|
}
|
|
280
272
|
}
|
|
@@ -298,7 +290,7 @@ abstract class WebSocketHandler<Schema extends WebSocket.ServiceSchema> {
|
|
|
298
290
|
message: WebSocket.ServiceMessage<Schema, Channel>,
|
|
299
291
|
sockets: Collection<ClientSocket> = this.sockets,
|
|
300
292
|
) {
|
|
301
|
-
if (!this.isRunning
|
|
293
|
+
if (!this.isRunning) {
|
|
302
294
|
throw new NotStartedWebSocketHandlerError();
|
|
303
295
|
}
|
|
304
296
|
|
|
@@ -27,12 +27,12 @@ class WebSocketServer<Schema extends WebSocket.ServiceSchema> extends WebSocketH
|
|
|
27
27
|
this.httpServer = options.httpServer;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
isRunning() {
|
|
30
|
+
get isRunning() {
|
|
31
31
|
return this.webSocketServer !== undefined;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
start() {
|
|
35
|
-
if (this.isRunning
|
|
35
|
+
if (this.isRunning) {
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -54,7 +54,7 @@ class WebSocketServer<Schema extends WebSocket.ServiceSchema> extends WebSocketH
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
async stop() {
|
|
57
|
-
if (!this.webSocketServer || !this.isRunning
|
|
57
|
+
if (!this.webSocketServer || !this.isRunning) {
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
60
|
|
|
@@ -62,7 +62,7 @@ class WebSocketServer<Schema extends WebSocket.ServiceSchema> extends WebSocketH
|
|
|
62
62
|
super.abortSocketMessages();
|
|
63
63
|
await super.closeClientSockets();
|
|
64
64
|
|
|
65
|
-
await closeServerSocket(this.webSocketServer, { timeout: this.socketTimeout
|
|
65
|
+
await closeServerSocket(this.webSocketServer, { timeout: this.socketTimeout });
|
|
66
66
|
this.webSocketServer.removeAllListeners();
|
|
67
67
|
this.webSocketServer = undefined;
|
|
68
68
|
}
|