@nestjs/websockets 11.1.16 → 12.0.0-alpha.1
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/adapters/index.d.ts +1 -1
- package/adapters/index.js +1 -4
- package/adapters/ws-adapter.d.ts +2 -2
- package/adapters/ws-adapter.js +10 -12
- package/constants.js +13 -16
- package/context/exception-filters-context.d.ts +3 -3
- package/context/exception-filters-context.js +7 -12
- package/context/ws-context-creator.d.ts +7 -16
- package/context/ws-context-creator.js +38 -30
- package/context/ws-metadata-constants.js +5 -8
- package/context/ws-proxy.d.ts +1 -1
- package/context/ws-proxy.js +8 -12
- package/decorators/ack.decorator.js +4 -7
- package/decorators/connected-socket.decorator.js +3 -6
- package/decorators/gateway-server.decorator.js +3 -7
- package/decorators/index.d.ts +6 -6
- package/decorators/index.js +6 -9
- package/decorators/message-body.decorator.d.ts +27 -1
- package/decorators/message-body.decorator.js +4 -7
- package/decorators/socket-gateway.decorator.d.ts +1 -1
- package/decorators/socket-gateway.decorator.js +5 -8
- package/decorators/subscribe-message.decorator.js +4 -8
- package/enums/ws-paramtype.enum.js +2 -5
- package/errors/index.d.ts +1 -1
- package/errors/index.js +1 -4
- package/errors/invalid-socket-port.exception.d.ts +1 -1
- package/errors/invalid-socket-port.exception.js +2 -6
- package/errors/ws-exception.js +6 -9
- package/exceptions/base-ws-exception-filter.d.ts +1 -1
- package/exceptions/base-ws-exception-filter.js +12 -15
- package/exceptions/index.d.ts +1 -1
- package/exceptions/index.js +1 -4
- package/exceptions/ws-exceptions-handler.d.ts +4 -4
- package/exceptions/ws-exceptions-handler.js +8 -16
- package/factories/server-and-event-streams-factory.d.ts +1 -1
- package/factories/server-and-event-streams-factory.js +5 -9
- package/factories/ws-params-factory.js +7 -11
- package/gateway-metadata-explorer.d.ts +2 -2
- package/gateway-metadata-explorer.js +15 -18
- package/index.d.ts +6 -6
- package/index.js +6 -9
- package/interfaces/gateway-metadata.interface.d.ts +1 -1
- package/interfaces/gateway-metadata.interface.js +1 -2
- package/interfaces/hooks/index.d.ts +3 -3
- package/interfaces/hooks/index.js +3 -6
- package/interfaces/hooks/on-gateway-connection.interface.js +1 -2
- package/interfaces/hooks/on-gateway-disconnect.interface.d.ts +1 -1
- package/interfaces/hooks/on-gateway-disconnect.interface.js +1 -2
- package/interfaces/hooks/on-gateway-init.interface.js +1 -2
- package/interfaces/index.d.ts +5 -5
- package/interfaces/index.js +5 -8
- package/interfaces/nest-gateway.interface.d.ts +1 -1
- package/interfaces/nest-gateway.interface.js +1 -2
- package/interfaces/server-and-event-streams-host.interface.js +1 -2
- package/interfaces/web-socket-server.interface.js +1 -2
- package/interfaces/websockets-entrypoint-metadata.interface.js +1 -2
- package/interfaces/ws-response.interface.js +1 -2
- package/internal.d.ts +8 -0
- package/internal.js +8 -0
- package/package.json +18 -4
- package/socket-module.d.ts +5 -8
- package/socket-module.js +26 -33
- package/socket-server-provider.d.ts +4 -4
- package/socket-server-provider.js +9 -11
- package/sockets-container.d.ts +1 -1
- package/sockets-container.js +3 -9
- package/tsconfig.build.json +1 -7
- package/utils/compare-element.util.js +1 -4
- package/utils/index.d.ts +1 -1
- package/utils/index.js +1 -4
- package/utils/param.utils.d.ts +3 -3
- package/utils/param.utils.js +40 -17
- package/web-sockets-controller.d.ts +9 -10
- package/web-sockets-controller.js +41 -28
package/socket-module.js
CHANGED
|
@@ -1,48 +1,42 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const sockets_container_1 = require("./sockets-container");
|
|
18
|
-
const web_sockets_controller_1 = require("./web-sockets-controller");
|
|
19
|
-
class SocketModule {
|
|
20
|
-
constructor() {
|
|
21
|
-
this.socketsContainer = new sockets_container_1.SocketsContainer();
|
|
22
|
-
}
|
|
1
|
+
import { iterate } from 'iterare';
|
|
2
|
+
import { GATEWAY_METADATA } from './constants.js';
|
|
3
|
+
import { ExceptionFiltersContext } from './context/exception-filters-context.js';
|
|
4
|
+
import { WsContextCreator } from './context/ws-context-creator.js';
|
|
5
|
+
import { WsProxy } from './context/ws-proxy.js';
|
|
6
|
+
import { SocketServerProvider } from './socket-server-provider.js';
|
|
7
|
+
import { SocketsContainer } from './sockets-container.js';
|
|
8
|
+
import { WebSocketsController } from './web-sockets-controller.js';
|
|
9
|
+
import { GuardsConsumer, GuardsContextCreator, loadAdapter, InterceptorsConsumer, InterceptorsContextCreator, PipesConsumer, PipesContextCreator, } from '@nestjs/core/internal';
|
|
10
|
+
export class SocketModule {
|
|
11
|
+
socketsContainer = new SocketsContainer();
|
|
12
|
+
applicationConfig;
|
|
13
|
+
webSocketsController;
|
|
14
|
+
isAdapterInitialized;
|
|
15
|
+
httpServer;
|
|
16
|
+
appOptions;
|
|
23
17
|
register(container, applicationConfig, graphInspector, appOptions, httpServer) {
|
|
24
18
|
this.applicationConfig = applicationConfig;
|
|
25
19
|
this.appOptions = appOptions;
|
|
26
20
|
this.httpServer = httpServer;
|
|
27
21
|
const contextCreator = this.getContextCreator(container);
|
|
28
|
-
const serverProvider = new
|
|
29
|
-
this.webSocketsController = new
|
|
22
|
+
const serverProvider = new SocketServerProvider(this.socketsContainer, applicationConfig);
|
|
23
|
+
this.webSocketsController = new WebSocketsController(serverProvider, applicationConfig, contextCreator, graphInspector, this.appOptions);
|
|
30
24
|
const modules = container.getModules();
|
|
31
25
|
modules.forEach(({ providers }, moduleName) => this.connectAllGateways(providers, moduleName));
|
|
32
26
|
}
|
|
33
27
|
connectAllGateways(providers, moduleName) {
|
|
34
|
-
|
|
28
|
+
iterate(providers.values())
|
|
35
29
|
.filter(wrapper => wrapper && !wrapper.isNotMetatype)
|
|
36
30
|
.forEach(wrapper => this.connectGatewayToServer(wrapper, moduleName));
|
|
37
31
|
}
|
|
38
|
-
connectGatewayToServer(wrapper, moduleName) {
|
|
32
|
+
async connectGatewayToServer(wrapper, moduleName) {
|
|
39
33
|
const { instance, metatype } = wrapper;
|
|
40
34
|
const metadataKeys = Reflect.getMetadataKeys(metatype);
|
|
41
|
-
if (!metadataKeys.includes(
|
|
35
|
+
if (!metadataKeys.includes(GATEWAY_METADATA)) {
|
|
42
36
|
return;
|
|
43
37
|
}
|
|
44
38
|
if (!this.isAdapterInitialized) {
|
|
45
|
-
this.initializeAdapter();
|
|
39
|
+
await this.initializeAdapter();
|
|
46
40
|
}
|
|
47
41
|
this.webSocketsController.connectGatewayToServer(instance, metatype, moduleName, wrapper.id);
|
|
48
42
|
}
|
|
@@ -55,13 +49,13 @@ class SocketModule {
|
|
|
55
49
|
return;
|
|
56
50
|
}
|
|
57
51
|
const servers = this.socketsContainer.getAll();
|
|
58
|
-
await Promise.all(
|
|
52
|
+
await Promise.all(iterate(servers.values())
|
|
59
53
|
.filter(({ server }) => server)
|
|
60
54
|
.map(async ({ server }) => adapter.close(server)));
|
|
61
55
|
await adapter?.dispose();
|
|
62
56
|
this.socketsContainer.clear();
|
|
63
57
|
}
|
|
64
|
-
initializeAdapter() {
|
|
58
|
+
async initializeAdapter() {
|
|
65
59
|
const forceCloseConnections = this.appOptions
|
|
66
60
|
.forceCloseConnections;
|
|
67
61
|
const adapter = this.applicationConfig.getIoAdapter();
|
|
@@ -71,14 +65,13 @@ class SocketModule {
|
|
|
71
65
|
this.isAdapterInitialized = true;
|
|
72
66
|
return;
|
|
73
67
|
}
|
|
74
|
-
const { IoAdapter } =
|
|
68
|
+
const { IoAdapter } = await loadAdapter('@nestjs/platform-socket.io', 'WebSockets', () => import('@nestjs/platform-socket.io'));
|
|
75
69
|
const ioAdapter = new IoAdapter(this.httpServer);
|
|
76
70
|
ioAdapter.forceCloseConnections = forceCloseConnections;
|
|
77
71
|
this.applicationConfig.setIoAdapter(ioAdapter);
|
|
78
72
|
this.isAdapterInitialized = true;
|
|
79
73
|
}
|
|
80
74
|
getContextCreator(container) {
|
|
81
|
-
return new
|
|
75
|
+
return new WsContextCreator(new WsProxy(), new ExceptionFiltersContext(container), new PipesContextCreator(container), new PipesConsumer(), new GuardsContextCreator(container), new GuardsConsumer(), new InterceptorsContextCreator(container), new InterceptorsConsumer());
|
|
82
76
|
}
|
|
83
77
|
}
|
|
84
|
-
exports.SocketModule = SocketModule;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { GatewayMetadata } from './interfaces/gateway-metadata.interface.js';
|
|
2
|
+
import { ServerAndEventStreamsHost } from './interfaces/server-and-event-streams-host.interface.js';
|
|
3
|
+
import { SocketsContainer } from './sockets-container.js';
|
|
4
|
+
import type { ApplicationConfig } from '@nestjs/core';
|
|
5
5
|
export declare class SocketServerProvider {
|
|
6
6
|
private readonly socketsContainer;
|
|
7
7
|
private readonly applicationConfig;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class SocketServerProvider {
|
|
1
|
+
import { ServerAndEventStreamsFactory } from './factories/server-and-event-streams-factory.js';
|
|
2
|
+
import { addLeadingSlash, isString } from '@nestjs/common/internal';
|
|
3
|
+
export class SocketServerProvider {
|
|
4
|
+
socketsContainer;
|
|
5
|
+
applicationConfig;
|
|
7
6
|
constructor(socketsContainer, applicationConfig) {
|
|
8
7
|
this.socketsContainer = socketsContainer;
|
|
9
8
|
this.applicationConfig = applicationConfig;
|
|
@@ -24,7 +23,7 @@ class SocketServerProvider {
|
|
|
24
23
|
const adapter = this.applicationConfig.getIoAdapter();
|
|
25
24
|
const { namespace, server, ...partialOptions } = options;
|
|
26
25
|
const ioServer = adapter.create(port, partialOptions);
|
|
27
|
-
const serverAndEventStreamsHost =
|
|
26
|
+
const serverAndEventStreamsHost = ServerAndEventStreamsFactory.create(ioServer);
|
|
28
27
|
this.socketsContainer.addOne({ port, path: options.path }, serverAndEventStreamsHost);
|
|
29
28
|
if (!namespace) {
|
|
30
29
|
return serverAndEventStreamsHost;
|
|
@@ -33,7 +32,7 @@ class SocketServerProvider {
|
|
|
33
32
|
}
|
|
34
33
|
decorateWithNamespace(options, port, targetServer) {
|
|
35
34
|
const namespaceServer = this.getServerOfNamespace(options, port, targetServer);
|
|
36
|
-
const serverAndEventStreamsHost =
|
|
35
|
+
const serverAndEventStreamsHost = ServerAndEventStreamsFactory.create(namespaceServer);
|
|
37
36
|
this.socketsContainer.addOne({ port, path: options.path, namespace: options.namespace }, serverAndEventStreamsHost);
|
|
38
37
|
return serverAndEventStreamsHost;
|
|
39
38
|
}
|
|
@@ -46,10 +45,9 @@ class SocketServerProvider {
|
|
|
46
45
|
});
|
|
47
46
|
}
|
|
48
47
|
validateNamespace(namespace) {
|
|
49
|
-
if (!
|
|
48
|
+
if (!isString(namespace)) {
|
|
50
49
|
return namespace;
|
|
51
50
|
}
|
|
52
|
-
return
|
|
51
|
+
return addLeadingSlash(namespace);
|
|
53
52
|
}
|
|
54
53
|
}
|
|
55
|
-
exports.SocketServerProvider = SocketServerProvider;
|
package/sockets-container.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { GatewayMetadata, ServerAndEventStreamsHost } from './interfaces';
|
|
1
|
+
import { GatewayMetadata, ServerAndEventStreamsHost } from './interfaces/index.js';
|
|
2
2
|
export declare class SocketsContainer {
|
|
3
3
|
private readonly serverAndEventStreamsHosts;
|
|
4
4
|
getAll(): Map<string | RegExp, ServerAndEventStreamsHost>;
|
package/sockets-container.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const hash = require("object-hash");
|
|
5
|
-
class SocketsContainer {
|
|
6
|
-
constructor() {
|
|
7
|
-
this.serverAndEventStreamsHosts = new Map();
|
|
8
|
-
}
|
|
1
|
+
import hash from 'object-hash';
|
|
2
|
+
export class SocketsContainer {
|
|
3
|
+
serverAndEventStreamsHosts = new Map();
|
|
9
4
|
getAll() {
|
|
10
5
|
return this.serverAndEventStreamsHosts;
|
|
11
6
|
}
|
|
@@ -24,4 +19,3 @@ class SocketsContainer {
|
|
|
24
19
|
return hash(options, { ignoreUnknown: true });
|
|
25
20
|
}
|
|
26
21
|
}
|
|
27
|
-
exports.SocketsContainer = SocketsContainer;
|
package/tsconfig.build.json
CHANGED
|
@@ -2,13 +2,7 @@
|
|
|
2
2
|
"extends": "../tsconfig.build.json",
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"outDir": ".",
|
|
5
|
-
"rootDir": "."
|
|
6
|
-
"paths": {
|
|
7
|
-
"@nestjs/common": ["../common"],
|
|
8
|
-
"@nestjs/common/*": ["../common/*"],
|
|
9
|
-
"@nestjs/core": ["../core"],
|
|
10
|
-
"@nestjs/core/*": ["../core/*"]
|
|
11
|
-
}
|
|
5
|
+
"rootDir": "."
|
|
12
6
|
},
|
|
13
7
|
"exclude": ["node_modules", "dist", "test/**/*", "*.spec.ts"],
|
|
14
8
|
"references": [
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.compareElementAt = compareElementAt;
|
|
4
|
-
function compareElementAt(prev, curr, index) {
|
|
1
|
+
export function compareElementAt(prev, curr, index) {
|
|
5
2
|
return prev && curr && prev[index] === curr[index];
|
|
6
3
|
}
|
package/utils/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './param.utils';
|
|
1
|
+
export * from './param.utils.js';
|
package/utils/index.js
CHANGED
package/utils/param.utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PipeTransform, Type } from '@nestjs/common';
|
|
1
|
+
import type { ParameterDecoratorOptions, PipeTransform, Type } from '@nestjs/common';
|
|
2
2
|
import 'reflect-metadata';
|
|
3
|
-
import { WsParamtype } from '../enums/ws-paramtype.enum';
|
|
3
|
+
import { WsParamtype } from '../enums/ws-paramtype.enum.js';
|
|
4
4
|
export declare function createWsParamDecorator(paramtype: WsParamtype): (...pipes: (Type<PipeTransform> | PipeTransform)[]) => ParameterDecorator;
|
|
5
|
-
export declare const createPipesWsParamDecorator: (paramtype: WsParamtype) => (data?: any, ...pipes: (Type<PipeTransform> | PipeTransform)[]) => ParameterDecorator;
|
|
5
|
+
export declare const createPipesWsParamDecorator: (paramtype: WsParamtype) => (data?: any, optionsOrPipe?: ParameterDecoratorOptions | Type<PipeTransform> | PipeTransform, ...pipes: (Type<PipeTransform> | PipeTransform)[]) => ParameterDecorator;
|
package/utils/param.utils.js
CHANGED
|
@@ -1,23 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
|
|
7
|
-
require("reflect-metadata");
|
|
8
|
-
const constants_1 = require("../constants");
|
|
9
|
-
function createWsParamDecorator(paramtype) {
|
|
1
|
+
import { assignMetadata } from '@nestjs/common';
|
|
2
|
+
import { isNil, isString } from '@nestjs/common/internal';
|
|
3
|
+
import 'reflect-metadata';
|
|
4
|
+
import { PARAM_ARGS_METADATA } from '../constants.js';
|
|
5
|
+
export function createWsParamDecorator(paramtype) {
|
|
10
6
|
return (...pipes) => (target, key, index) => {
|
|
11
|
-
const args = Reflect.getMetadata(
|
|
7
|
+
const args = Reflect.getMetadata(PARAM_ARGS_METADATA, target.constructor, key) ||
|
|
12
8
|
{};
|
|
13
|
-
Reflect.defineMetadata(
|
|
9
|
+
Reflect.defineMetadata(PARAM_ARGS_METADATA, assignMetadata(args, paramtype, index, { pipes }), target.constructor, key);
|
|
14
10
|
};
|
|
15
11
|
}
|
|
16
|
-
const createPipesWsParamDecorator = (paramtype) => (data, ...pipes) => (target, key, index) => {
|
|
17
|
-
const args = Reflect.getMetadata(
|
|
18
|
-
const
|
|
12
|
+
export const createPipesWsParamDecorator = (paramtype) => (data, optionsOrPipe, ...pipes) => (target, key, index) => {
|
|
13
|
+
const args = Reflect.getMetadata(PARAM_ARGS_METADATA, target.constructor, key) || {};
|
|
14
|
+
const isDataOptions = data &&
|
|
15
|
+
typeof data === 'object' &&
|
|
16
|
+
!('transform' in data) &&
|
|
17
|
+
('schema' in data || 'pipes' in data);
|
|
18
|
+
if (isDataOptions) {
|
|
19
|
+
const opts = data;
|
|
20
|
+
Reflect.defineMetadata(PARAM_ARGS_METADATA, assignMetadata(args, paramtype, index, {
|
|
21
|
+
pipes: opts.pipes ?? [],
|
|
22
|
+
schema: opts.schema,
|
|
23
|
+
}), target.constructor, key);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const hasParamData = isNil(data) || isString(data);
|
|
19
27
|
const paramData = hasParamData ? data : undefined;
|
|
20
|
-
const
|
|
21
|
-
|
|
28
|
+
const isOptions = optionsOrPipe &&
|
|
29
|
+
typeof optionsOrPipe === 'object' &&
|
|
30
|
+
('schema' in optionsOrPipe || 'pipes' in optionsOrPipe);
|
|
31
|
+
let paramPipes;
|
|
32
|
+
if (isOptions) {
|
|
33
|
+
paramPipes = optionsOrPipe.pipes ?? [];
|
|
34
|
+
}
|
|
35
|
+
else if (hasParamData) {
|
|
36
|
+
paramPipes = [optionsOrPipe, ...pipes].filter(Boolean);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
paramPipes = [data, optionsOrPipe, ...pipes].filter(Boolean);
|
|
40
|
+
}
|
|
41
|
+
Reflect.defineMetadata(PARAM_ARGS_METADATA, assignMetadata(args, paramtype, index, {
|
|
42
|
+
data: paramData,
|
|
43
|
+
pipes: paramPipes,
|
|
44
|
+
schema: isOptions ? optionsOrPipe.schema : undefined,
|
|
45
|
+
}), target.constructor, key);
|
|
22
46
|
};
|
|
23
|
-
exports.createPipesWsParamDecorator = createPipesWsParamDecorator;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { NestApplicationContextOptions } from '@nestjs/common/interfaces/nest-application-context-options.interface';
|
|
2
|
-
import { Type } from '@nestjs/common/interfaces/type.interface';
|
|
3
|
-
import { ApplicationConfig } from '@nestjs/core/application-config';
|
|
4
|
-
import { GraphInspector } from '@nestjs/core/inspector/graph-inspector';
|
|
5
1
|
import { Observable, Subject } from 'rxjs';
|
|
6
|
-
import { WsContextCreator } from './context/ws-context-creator';
|
|
7
|
-
import { MessageMappingProperties } from './gateway-metadata-explorer';
|
|
8
|
-
import { GatewayMetadata } from './interfaces/gateway-metadata.interface';
|
|
9
|
-
import { NestGateway } from './interfaces/nest-gateway.interface';
|
|
10
|
-
import { ServerAndEventStreamsHost } from './interfaces/server-and-event-streams-host.interface';
|
|
11
|
-
import { SocketServerProvider } from './socket-server-provider';
|
|
2
|
+
import { WsContextCreator } from './context/ws-context-creator.js';
|
|
3
|
+
import { MessageMappingProperties } from './gateway-metadata-explorer.js';
|
|
4
|
+
import { GatewayMetadata } from './interfaces/gateway-metadata.interface.js';
|
|
5
|
+
import { NestGateway } from './interfaces/nest-gateway.interface.js';
|
|
6
|
+
import { ServerAndEventStreamsHost } from './interfaces/server-and-event-streams-host.interface.js';
|
|
7
|
+
import { SocketServerProvider } from './socket-server-provider.js';
|
|
8
|
+
import type { NestApplicationContextOptions } from '@nestjs/common/internal';
|
|
9
|
+
import { type Type } from '@nestjs/common';
|
|
10
|
+
import { type ApplicationConfig, type GraphInspector } from '@nestjs/core';
|
|
12
11
|
export declare class WebSocketsController {
|
|
13
12
|
private readonly socketServerProvider;
|
|
14
13
|
private readonly config;
|
|
@@ -1,31 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import { from as fromPromise, isObservable, of, } from 'rxjs';
|
|
2
|
+
import { distinctUntilChanged, mergeAll } from 'rxjs/operators';
|
|
3
|
+
import { GATEWAY_OPTIONS, PORT_METADATA } from './constants.js';
|
|
4
|
+
import { InvalidSocketPortException } from './errors/invalid-socket-port.exception.js';
|
|
5
|
+
import { GatewayMetadataExplorer, } from './gateway-metadata-explorer.js';
|
|
6
|
+
import { compareElementAt } from './utils/compare-element.util.js';
|
|
7
|
+
import { Logger } from '@nestjs/common';
|
|
8
|
+
import { MetadataScanner, } from '@nestjs/core';
|
|
9
|
+
export class WebSocketsController {
|
|
10
|
+
socketServerProvider;
|
|
11
|
+
config;
|
|
12
|
+
contextCreator;
|
|
13
|
+
graphInspector;
|
|
14
|
+
appOptions;
|
|
15
|
+
logger = new Logger(WebSocketsController.name, {
|
|
16
|
+
timestamp: true,
|
|
17
|
+
});
|
|
18
|
+
metadataExplorer = new GatewayMetadataExplorer(new MetadataScanner());
|
|
13
19
|
constructor(socketServerProvider, config, contextCreator, graphInspector, appOptions = {}) {
|
|
14
20
|
this.socketServerProvider = socketServerProvider;
|
|
15
21
|
this.config = config;
|
|
16
22
|
this.contextCreator = contextCreator;
|
|
17
23
|
this.graphInspector = graphInspector;
|
|
18
24
|
this.appOptions = appOptions;
|
|
19
|
-
this.logger = new logger_service_1.Logger(WebSocketsController.name, {
|
|
20
|
-
timestamp: true,
|
|
21
|
-
});
|
|
22
|
-
this.metadataExplorer = new gateway_metadata_explorer_1.GatewayMetadataExplorer(new metadata_scanner_1.MetadataScanner());
|
|
23
25
|
}
|
|
24
26
|
connectGatewayToServer(instance, metatype, moduleKey, instanceWrapperId) {
|
|
25
|
-
const options = Reflect.getMetadata(
|
|
26
|
-
const port = Reflect.getMetadata(
|
|
27
|
+
const options = Reflect.getMetadata(GATEWAY_OPTIONS, metatype) || {};
|
|
28
|
+
const port = Reflect.getMetadata(PORT_METADATA, metatype) || 0;
|
|
27
29
|
if (!Number.isInteger(port)) {
|
|
28
|
-
throw new
|
|
30
|
+
throw new InvalidSocketPortException(port, metatype);
|
|
29
31
|
}
|
|
30
32
|
this.subscribeToServerEvents(instance, options, port, moduleKey, instanceWrapperId);
|
|
31
33
|
}
|
|
@@ -63,7 +65,7 @@ class WebSocketsController {
|
|
|
63
65
|
context.subscribeMessages(subscribersMap, client, instance);
|
|
64
66
|
const disconnectHook = adapter.bindClientDisconnect;
|
|
65
67
|
disconnectHook &&
|
|
66
|
-
disconnectHook.call(adapter, client, () => disconnect.next(client));
|
|
68
|
+
disconnectHook.call(adapter, client, (reason) => disconnect.next({ client, reason }));
|
|
67
69
|
};
|
|
68
70
|
}
|
|
69
71
|
subscribeInitEvent(instance, event) {
|
|
@@ -74,15 +76,27 @@ class WebSocketsController {
|
|
|
74
76
|
subscribeConnectionEvent(instance, event) {
|
|
75
77
|
if (instance.handleConnection) {
|
|
76
78
|
event
|
|
77
|
-
.pipe(
|
|
79
|
+
.pipe(distinctUntilChanged((prev, curr) => compareElementAt(prev, curr, 0)))
|
|
78
80
|
.subscribe((args) => instance.handleConnection(...args));
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
83
|
subscribeDisconnectEvent(instance, event) {
|
|
82
84
|
if (instance.handleDisconnect) {
|
|
83
85
|
event
|
|
84
|
-
.pipe((
|
|
85
|
-
|
|
86
|
+
.pipe(distinctUntilChanged((prev, curr) => {
|
|
87
|
+
const prevClient = prev?.client || prev;
|
|
88
|
+
const currClient = curr?.client || curr;
|
|
89
|
+
return prevClient === currClient;
|
|
90
|
+
}))
|
|
91
|
+
.subscribe((data) => {
|
|
92
|
+
if (data && typeof data === 'object' && 'client' in data) {
|
|
93
|
+
instance.handleDisconnect(data.client, data.reason);
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// Backward compatibility: if it's just the client
|
|
97
|
+
instance.handleDisconnect(data);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
86
100
|
}
|
|
87
101
|
}
|
|
88
102
|
subscribeMessages(subscribersMap, client, instance) {
|
|
@@ -92,17 +106,17 @@ class WebSocketsController {
|
|
|
92
106
|
callback: callback.bind(instance, client),
|
|
93
107
|
isAckHandledManually,
|
|
94
108
|
}));
|
|
95
|
-
adapter.bindMessageHandlers(client, handlers, data => (
|
|
109
|
+
adapter.bindMessageHandlers(client, handlers, data => fromPromise(this.pickResult(data)).pipe(mergeAll()));
|
|
96
110
|
}
|
|
97
111
|
async pickResult(deferredResult) {
|
|
98
112
|
const result = await deferredResult;
|
|
99
|
-
if (
|
|
113
|
+
if (isObservable(result)) {
|
|
100
114
|
return result;
|
|
101
115
|
}
|
|
102
116
|
if (result instanceof Promise) {
|
|
103
|
-
return (
|
|
117
|
+
return fromPromise(result);
|
|
104
118
|
}
|
|
105
|
-
return
|
|
119
|
+
return of(result);
|
|
106
120
|
}
|
|
107
121
|
inspectEntrypointDefinitions(instance, port, messageHandlers, instanceWrapperId) {
|
|
108
122
|
messageHandlers.forEach(handler => {
|
|
@@ -132,4 +146,3 @@ class WebSocketsController {
|
|
|
132
146
|
subscribersMap.forEach(({ message }) => this.logger.log(`${gatewayClassName} subscribed to the "${message}" message`));
|
|
133
147
|
}
|
|
134
148
|
}
|
|
135
|
-
exports.WebSocketsController = WebSocketsController;
|