import { Inject, Injectable } from '@nestjs/common'; import Redis from 'ioredis'; import type { User } from '@/models/entities/User.js'; import type { Note } from '@/models/entities/Note.js'; import type { UserList } from '@/models/entities/UserList.js'; import type { Antenna } from '@/models/entities/Antenna.js'; import type { StreamChannels, AdminStreamTypes, AntennaStreamTypes, BroadcastTypes, DriveStreamTypes, InternalStreamTypes, MainStreamTypes, NoteStreamTypes, UserListStreamTypes, UserStreamTypes, } from '@/server/api/stream/types.js'; import type { Packed } from '@/misc/json-schema.js'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; import { bindThis } from '@/decorators.js'; @Injectable() export class GlobalEventService { constructor( @Inject(DI.config) private config: Config, @Inject(DI.redis) private redisClient: Redis.Redis, ) { } @bindThis private publish(channel: StreamChannels, type: string | null, value?: any): void { const message = type == null ? value : value == null ? { type: type, body: null } : { type: type, body: value }; this.redisClient.publish(this.config.host, JSON.stringify({ channel: channel, message: message, })); } @bindThis public publishInternalEvent(type: K, value?: InternalStreamTypes[K]): void { this.publish('internal', type, typeof value === 'undefined' ? null : value); } @bindThis public publishUserEvent(userId: User['id'], type: K, value?: UserStreamTypes[K]): void { this.publish(`user:${userId}`, type, typeof value === 'undefined' ? null : value); } @bindThis public publishBroadcastStream(type: K, value?: BroadcastTypes[K]): void { this.publish('broadcast', type, typeof value === 'undefined' ? null : value); } @bindThis public publishMainStream(userId: User['id'], type: K, value?: MainStreamTypes[K]): void { this.publish(`mainStream:${userId}`, type, typeof value === 'undefined' ? null : value); } @bindThis public publishDriveStream(userId: User['id'], type: K, value?: DriveStreamTypes[K]): void { this.publish(`driveStream:${userId}`, type, typeof value === 'undefined' ? null : value); } @bindThis public publishNoteStream(noteId: Note['id'], type: K, value?: NoteStreamTypes[K]): void { this.publish(`noteStream:${noteId}`, type, { id: noteId, body: value, }); } @bindThis public publishUserListStream(listId: UserList['id'], type: K, value?: UserListStreamTypes[K]): void { this.publish(`userListStream:${listId}`, type, typeof value === 'undefined' ? null : value); } @bindThis public publishAntennaStream(antennaId: Antenna['id'], type: K, value?: AntennaStreamTypes[K]): void { this.publish(`antennaStream:${antennaId}`, type, typeof value === 'undefined' ? null : value); } @bindThis public publishNotesStream(note: Packed<'Note'>): void { this.publish('notesStream', null, note); } @bindThis public publishAdminStream(userId: User['id'], type: K, value?: AdminStreamTypes[K]): void { this.publish(`adminStream:${userId}`, type, typeof value === 'undefined' ? null : value); } }