@nestjs/microservices
Version:
Nest - modern, fast, powerful node.js web framework (@microservices)
146 lines (145 loc) • 5.45 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.Server = void 0;
const logger_service_1 = require("@nestjs/common/services/logger.service");
const load_package_util_1 = require("@nestjs/common/utils/load-package.util");
const rxjs_1 = require("rxjs");
const operators_1 = require("rxjs/operators");
const constants_1 = require("../constants");
const incoming_request_deserializer_1 = require("../deserializers/incoming-request.deserializer");
const identity_serializer_1 = require("../serializers/identity.serializer");
const utils_1 = require("../utils");
/**
* @publicApi
*/
class Server {
constructor() {
this.messageHandlers = new Map();
this.logger = new logger_service_1.Logger(Server.name);
this._status$ = new rxjs_1.ReplaySubject(1);
}
/**
* Returns an observable that emits status changes.
*/
get status() {
return this._status$.asObservable().pipe((0, operators_1.distinctUntilChanged)());
}
addHandler(pattern, callback, isEventHandler = false, extras = {}) {
const normalizedPattern = this.normalizePattern(pattern);
callback.isEventHandler = isEventHandler;
callback.extras = extras;
if (this.messageHandlers.has(normalizedPattern) && isEventHandler) {
const headRef = this.messageHandlers.get(normalizedPattern);
const getTail = (handler) => handler?.next ? getTail(handler.next) : handler;
const tailRef = getTail(headRef);
tailRef.next = callback;
}
else {
this.messageHandlers.set(normalizedPattern, callback);
}
}
getHandlers() {
return this.messageHandlers;
}
getHandlerByPattern(pattern) {
const route = this.getRouteFromPattern(pattern);
return this.messageHandlers.has(route)
? this.messageHandlers.get(route)
: null;
}
send(stream$, respond) {
const dataQueue = [];
let isProcessing = false;
const scheduleOnNextTick = (data) => {
if (data.isDisposed && dataQueue.length > 0) {
dataQueue[dataQueue.length - 1].isDisposed = true;
}
else {
dataQueue.push(data);
}
if (!isProcessing) {
isProcessing = true;
process.nextTick(async () => {
while (dataQueue.length > 0) {
const packet = dataQueue.shift();
if (packet) {
await respond(packet);
}
}
isProcessing = false;
});
}
};
return stream$
.pipe((0, operators_1.catchError)((err) => {
scheduleOnNextTick({ err });
return rxjs_1.EMPTY;
}), (0, operators_1.finalize)(() => scheduleOnNextTick({ isDisposed: true })))
.subscribe((response) => scheduleOnNextTick({ response }));
}
async handleEvent(pattern, packet, context) {
const handler = this.getHandlerByPattern(pattern);
if (!handler) {
return this.logger.error((0, constants_1.NO_EVENT_HANDLER) `${pattern}`);
}
const resultOrStream = await handler(packet.data, context);
if ((0, rxjs_1.isObservable)(resultOrStream)) {
const connectableSource = (0, rxjs_1.connectable)(resultOrStream, {
connector: () => new rxjs_1.Subject(),
resetOnDisconnect: false,
});
connectableSource.connect();
}
}
transformToObservable(resultOrDeferred) {
if (resultOrDeferred instanceof Promise) {
return (0, rxjs_1.from)(resultOrDeferred).pipe((0, operators_1.mergeMap)(val => ((0, rxjs_1.isObservable)(val) ? val : (0, rxjs_1.of)(val))));
}
if ((0, rxjs_1.isObservable)(resultOrDeferred)) {
return resultOrDeferred;
}
return (0, rxjs_1.of)(resultOrDeferred);
}
getOptionsProp(obj, prop, defaultValue = undefined) {
return obj && prop in obj ? obj[prop] : defaultValue;
}
handleError(error) {
this.logger.error(error);
}
loadPackage(name, ctx, loader) {
return (0, load_package_util_1.loadPackage)(name, ctx, loader);
}
initializeSerializer(options) {
this.serializer =
(options &&
options.serializer) ||
new identity_serializer_1.IdentitySerializer();
}
initializeDeserializer(options) {
this.deserializer =
(options &&
options.deserializer) ||
new incoming_request_deserializer_1.IncomingRequestDeserializer();
}
/**
* Transforms the server Pattern to valid type and returns a route for him.
*
* @param {string} pattern - server pattern
* @returns string
*/
getRouteFromPattern(pattern) {
let validPattern;
try {
validPattern = JSON.parse(pattern);
}
catch (error) {
// Uses a fundamental object (`pattern` variable without any conversion)
validPattern = pattern;
}
return this.normalizePattern(validPattern);
}
normalizePattern(pattern) {
return (0, utils_1.transformPatternToRoute)(pattern);
}
}
exports.Server = Server;
;