import { sameResourceState } from '../../storage/Conditions'; import type { NotificationGenerator } from './generate/NotificationGenerator'; import type { NotificationEmitter } from './NotificationEmitter'; import type { NotificationHandlerInput } from './NotificationHandler'; import { NotificationHandler } from './NotificationHandler'; import type { NotificationSerializer } from './serialize/NotificationSerializer'; export interface ComposedNotificationHandlerArgs { generator: NotificationGenerator; serializer: NotificationSerializer; emitter: NotificationEmitter; } /** * Generates, serializes and emits a {@link Notification} using a {@link NotificationGenerator}, * {@link NotificationSerializer} and {@link NotificationEmitter}. * * Will not emit an event when it has the same state as the notification channel. */ export class ComposedNotificationHandler extends NotificationHandler { private readonly generator: NotificationGenerator; private readonly serializer: NotificationSerializer; private readonly emitter: NotificationEmitter; public constructor(args: ComposedNotificationHandlerArgs) { super(); this.generator = args.generator; this.serializer = args.serializer; this.emitter = args.emitter; } public async canHandle(input: NotificationHandlerInput): Promise { await this.generator.canHandle(input); } public async handle(input: NotificationHandlerInput): Promise { const notification = await this.generator.handle(input); const { state } = input.channel; // In case the state matches there is no need to send the notification if (typeof state === 'string' && notification.state && sameResourceState(state, notification.state)) { return; } const representation = await this.serializer.handleSafe({ channel: input.channel, notification }); await this.emitter.handleSafe({ channel: input.channel, representation }); } }