"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const common_1 = require("@nestjs/common");
const load_package_util_1 = require("@nestjs/common/utils/load-package.util");
const websockets_1 = require("@nestjs/websockets");
const constants_1 = require("@nestjs/websockets/constants");
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
let wsPackage = {};
var READY_STATE;
(function (READY_STATE) {
READY_STATE[READY_STATE["CONNECTING_STATE"] = 0] = "CONNECTING_STATE";
READY_STATE[READY_STATE["OPEN_STATE"] = 1] = "OPEN_STATE";
READY_STATE[READY_STATE["CLOSING_STATE"] = 2] = "CLOSING_STATE";
READY_STATE[READY_STATE["CLOSED_STATE"] = 3] = "CLOSED_STATE";
})(READY_STATE || (READY_STATE = {}));
class WsAdapter extends websockets_1.AbstractWsAdapter {
constructor(appOrHttpServer) {
super(appOrHttpServer);
this.logger = new common_1.Logger(WsAdapter.name);
wsPackage = load_package_util_1.loadPackage('ws', 'WsAdapter', () => require('ws'));
}
create(port, options) {
const { server } = options, wsOptions = tslib_1.__rest(options, ["server"]);
if (port === 0 && this.httpServer) {
return this.bindErrorHandler(new wsPackage.Server(Object.assign({ server: this.httpServer }, wsOptions)));
}
return server
? server
: this.bindErrorHandler(new wsPackage.Server(Object.assign({ port }, wsOptions)));
}
bindMessageHandlers(client, handlers, transform) {
const close$ = rxjs_1.fromEvent(client, constants_1.CLOSE_EVENT).pipe(operators_1.share(), operators_1.first());
const source$ = rxjs_1.fromEvent(client, 'message').pipe(operators_1.mergeMap(data => this.bindMessageHandler(data, handlers, transform).pipe(operators_1.filter(result => result))), operators_1.takeUntil(close$));
const onMessage = (response) => {
if (client.readyState !== READY_STATE.OPEN_STATE) {
return;
}
client.send(JSON.stringify(response));
};
source$.subscribe(onMessage);
}
bindMessageHandler(buffer, handlers, transform) {
try {
const message = JSON.parse(buffer.data);
const messageHandler = handlers.find(handler => handler.message === message.event);
const { callback } = messageHandler;
return transform(callback(message.data));
}
catch (_a) {
return rxjs_1.EMPTY;
}
}
bindErrorHandler(server) {
server.on(constants_1.CONNECTION_EVENT, ws => ws.on(constants_1.ERROR_EVENT, (err) => this.logger.error(err)));
server.on(constants_1.ERROR_EVENT, (err) => this.logger.error(err));
return server;
}
bindClientDisconnect(client, callback) {
client.on(constants_1.CLOSE_EVENT, callback);
}
}
exports.WsAdapter = WsAdapter;