diff options
Diffstat (limited to 'packages/backend/src/server/api/stream')
19 files changed, 183 insertions, 204 deletions
diff --git a/packages/backend/src/server/api/stream/channel.ts b/packages/backend/src/server/api/stream/channel.ts index 98337bb318..d2cc5122d5 100644 --- a/packages/backend/src/server/api/stream/channel.ts +++ b/packages/backend/src/server/api/stream/channel.ts @@ -1,4 +1,3 @@ -import autobind from 'autobind-decorator'; import Connection from '.'; /** @@ -44,7 +43,6 @@ export default abstract class Channel { this.connection = connection; } - @autobind public send(typeOrPayload: any, payload?: any) { const type = payload === undefined ? typeOrPayload.type : typeOrPayload; const body = payload === undefined ? typeOrPayload.body : payload; diff --git a/packages/backend/src/server/api/stream/channels/admin.ts b/packages/backend/src/server/api/stream/channels/admin.ts index 1ff932d1dd..945182ea10 100644 --- a/packages/backend/src/server/api/stream/channels/admin.ts +++ b/packages/backend/src/server/api/stream/channels/admin.ts @@ -1,12 +1,10 @@ -import autobind from 'autobind-decorator'; -import Channel from '../channel'; +import Channel from '../channel.js'; export default class extends Channel { public readonly chName = 'admin'; public static shouldShare = true; public static requireCredential = true; - @autobind public async init(params: any) { // Subscribe admin stream this.subscriber.on(`adminStream:${this.user!.id}`, data => { diff --git a/packages/backend/src/server/api/stream/channels/antenna.ts b/packages/backend/src/server/api/stream/channels/antenna.ts index 3cbdfebb43..afd14946e1 100644 --- a/packages/backend/src/server/api/stream/channels/antenna.ts +++ b/packages/backend/src/server/api/stream/channels/antenna.ts @@ -1,9 +1,8 @@ -import autobind from 'autobind-decorator'; -import Channel from '../channel'; -import { Notes } from '@/models/index'; -import { isMutedUserRelated } from '@/misc/is-muted-user-related'; -import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; -import { StreamMessages } from '../types'; +import Channel from '../channel.js'; +import { Notes } from '@/models/index.js'; +import { isMutedUserRelated } from '@/misc/is-muted-user-related.js'; +import { isBlockerUserRelated } from '@/misc/is-blocker-user-related.js'; +import { StreamMessages } from '../types.js'; export default class extends Channel { public readonly chName = 'antenna'; @@ -11,7 +10,11 @@ export default class extends Channel { public static requireCredential = false; private antennaId: string; - @autobind + constructor(id: string, connection: Channel['connection']) { + super(id, connection); + this.onEvent = this.onEvent.bind(this); + } + public async init(params: any) { this.antennaId = params.antennaId as string; @@ -19,7 +22,6 @@ export default class extends Channel { this.subscriber.on(`antennaStream:${this.antennaId}`, this.onEvent); } - @autobind private async onEvent(data: StreamMessages['antenna']['payload']) { if (data.type === 'note') { const note = await Notes.pack(data.body.id, this.user, { detail: true }); @@ -37,7 +39,6 @@ export default class extends Channel { } } - @autobind public dispose() { // Unsubscribe events this.subscriber.off(`antennaStream:${this.antennaId}`, this.onEvent); diff --git a/packages/backend/src/server/api/stream/channels/channel.ts b/packages/backend/src/server/api/stream/channels/channel.ts index 1e51a81c4b..16ad809395 100644 --- a/packages/backend/src/server/api/stream/channels/channel.ts +++ b/packages/backend/src/server/api/stream/channels/channel.ts @@ -1,11 +1,10 @@ -import autobind from 'autobind-decorator'; -import Channel from '../channel'; -import { Notes, Users } from '@/models/index'; -import { isMutedUserRelated } from '@/misc/is-muted-user-related'; -import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; -import { User } from '@/models/entities/user'; -import { StreamMessages } from '../types'; -import { Packed } from '@/misc/schema'; +import Channel from '../channel.js'; +import { Notes, Users } from '@/models/index.js'; +import { isMutedUserRelated } from '@/misc/is-muted-user-related.js'; +import { isBlockerUserRelated } from '@/misc/is-blocker-user-related.js'; +import { User } from '@/models/entities/user.js'; +import { StreamMessages } from '../types.js'; +import { Packed } from '@/misc/schema.js'; export default class extends Channel { public readonly chName = 'channel'; @@ -15,7 +14,11 @@ export default class extends Channel { private typers: Record<User['id'], Date> = {}; private emitTypersIntervalId: ReturnType<typeof setInterval>; - @autobind + constructor(id: string, connection: Channel['connection']) { + super(id, connection); + this.onNote = this.onNote.bind(this); + } + public async init(params: any) { this.channelId = params.channelId as string; @@ -25,7 +28,6 @@ export default class extends Channel { this.emitTypersIntervalId = setInterval(this.emitTypers, 5000); } - @autobind private async onNote(note: Packed<'Note'>) { if (note.channelId !== this.channelId) return; @@ -52,7 +54,6 @@ export default class extends Channel { this.send('note', note); } - @autobind private onEvent(data: StreamMessages['channel']['payload']) { if (data.type === 'typing') { const id = data.body; @@ -64,7 +65,6 @@ export default class extends Channel { } } - @autobind private async emitTypers() { const now = new Date(); @@ -81,7 +81,6 @@ export default class extends Channel { }); } - @autobind public dispose() { // Unsubscribe events this.subscriber.off('notesStream', this.onNote); diff --git a/packages/backend/src/server/api/stream/channels/drive.ts b/packages/backend/src/server/api/stream/channels/drive.ts index 4112dd9b04..140255acd1 100644 --- a/packages/backend/src/server/api/stream/channels/drive.ts +++ b/packages/backend/src/server/api/stream/channels/drive.ts @@ -1,12 +1,10 @@ -import autobind from 'autobind-decorator'; -import Channel from '../channel'; +import Channel from '../channel.js'; export default class extends Channel { public readonly chName = 'drive'; public static shouldShare = true; public static requireCredential = true; - @autobind public async init(params: any) { // Subscribe drive stream this.subscriber.on(`driveStream:${this.user!.id}`, data => { diff --git a/packages/backend/src/server/api/stream/channels/global-timeline.ts b/packages/backend/src/server/api/stream/channels/global-timeline.ts index ecd87d093d..1c7e038ab2 100644 --- a/packages/backend/src/server/api/stream/channels/global-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/global-timeline.ts @@ -1,19 +1,22 @@ -import autobind from 'autobind-decorator'; -import { isMutedUserRelated } from '@/misc/is-muted-user-related'; -import Channel from '../channel'; -import { fetchMeta } from '@/misc/fetch-meta'; -import { Notes } from '@/models/index'; -import { checkWordMute } from '@/misc/check-word-mute'; -import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; -import { isInstanceMuted } from '@/misc/is-instance-muted'; -import { Packed } from '@/misc/schema'; +import { isMutedUserRelated } from '@/misc/is-muted-user-related.js'; +import Channel from '../channel.js'; +import { fetchMeta } from '@/misc/fetch-meta.js'; +import { Notes } from '@/models/index.js'; +import { checkWordMute } from '@/misc/check-word-mute.js'; +import { isBlockerUserRelated } from '@/misc/is-blocker-user-related.js'; +import { isInstanceMuted } from '@/misc/is-instance-muted.js'; +import { Packed } from '@/misc/schema.js'; export default class extends Channel { public readonly chName = 'globalTimeline'; public static shouldShare = true; public static requireCredential = false; - @autobind + constructor(id: string, connection: Channel['connection']) { + super(id, connection); + this.onNote = this.onNote.bind(this); + } + public async init(params: any) { const meta = await fetchMeta(); if (meta.disableGlobalTimeline) { @@ -24,7 +27,6 @@ export default class extends Channel { this.subscriber.on('notesStream', this.onNote); } - @autobind private async onNote(note: Packed<'Note'>) { if (note.visibility !== 'public') return; if (note.channelId != null) return; @@ -69,7 +71,6 @@ export default class extends Channel { this.send('note', note); } - @autobind public dispose() { // Unsubscribe events this.subscriber.off('notesStream', this.onNote); diff --git a/packages/backend/src/server/api/stream/channels/hashtag.ts b/packages/backend/src/server/api/stream/channels/hashtag.ts index 820095dfcf..1b7a58022f 100644 --- a/packages/backend/src/server/api/stream/channels/hashtag.ts +++ b/packages/backend/src/server/api/stream/channels/hashtag.ts @@ -1,10 +1,9 @@ -import autobind from 'autobind-decorator'; -import { isMutedUserRelated } from '@/misc/is-muted-user-related'; -import Channel from '../channel'; -import { Notes } from '@/models/index'; -import { normalizeForSearch } from '@/misc/normalize-for-search'; -import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; -import { Packed } from '@/misc/schema'; +import { isMutedUserRelated } from '@/misc/is-muted-user-related.js'; +import Channel from '../channel.js'; +import { Notes } from '@/models/index.js'; +import { normalizeForSearch } from '@/misc/normalize-for-search.js'; +import { isBlockerUserRelated } from '@/misc/is-blocker-user-related.js'; +import { Packed } from '@/misc/schema.js'; export default class extends Channel { public readonly chName = 'hashtag'; @@ -12,7 +11,11 @@ export default class extends Channel { public static requireCredential = false; private q: string[][]; - @autobind + constructor(id: string, connection: Channel['connection']) { + super(id, connection); + this.onNote = this.onNote.bind(this); + } + public async init(params: any) { this.q = params.q; @@ -22,7 +25,6 @@ export default class extends Channel { this.subscriber.on('notesStream', this.onNote); } - @autobind private async onNote(note: Packed<'Note'>) { const noteTags = note.tags ? note.tags.map((t: string) => t.toLowerCase()) : []; const matched = this.q.some(tags => tags.every(tag => noteTags.includes(normalizeForSearch(tag)))); @@ -45,7 +47,6 @@ export default class extends Channel { this.send('note', note); } - @autobind public dispose() { // Unsubscribe events this.subscriber.off('notesStream', this.onNote); diff --git a/packages/backend/src/server/api/stream/channels/home-timeline.ts b/packages/backend/src/server/api/stream/channels/home-timeline.ts index 445db5c382..3a8e55202a 100644 --- a/packages/backend/src/server/api/stream/channels/home-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/home-timeline.ts @@ -1,24 +1,26 @@ -import autobind from 'autobind-decorator'; -import { isMutedUserRelated } from '@/misc/is-muted-user-related'; -import Channel from '../channel'; -import { Notes } from '@/models/index'; -import { checkWordMute } from '@/misc/check-word-mute'; -import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; -import { isInstanceMuted } from '@/misc/is-instance-muted'; -import { Packed } from '@/misc/schema'; +import { isMutedUserRelated } from '@/misc/is-muted-user-related.js'; +import Channel from '../channel.js'; +import { Notes } from '@/models/index.js'; +import { checkWordMute } from '@/misc/check-word-mute.js'; +import { isBlockerUserRelated } from '@/misc/is-blocker-user-related.js'; +import { isInstanceMuted } from '@/misc/is-instance-muted.js'; +import { Packed } from '@/misc/schema.js'; export default class extends Channel { public readonly chName = 'homeTimeline'; public static shouldShare = true; public static requireCredential = true; - @autobind + constructor(id: string, connection: Channel['connection']) { + super(id, connection); + this.onNote = this.onNote.bind(this); + } + public async init(params: any) { // Subscribe events this.subscriber.on('notesStream', this.onNote); } - @autobind private async onNote(note: Packed<'Note'>) { if (note.channelId) { if (!this.followingChannels.has(note.channelId)) return; @@ -77,7 +79,6 @@ export default class extends Channel { this.send('note', note); } - @autobind public dispose() { // Unsubscribe events this.subscriber.off('notesStream', this.onNote); diff --git a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts index c0be71fe2d..f3ceeffa1a 100644 --- a/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/hybrid-timeline.ts @@ -1,19 +1,22 @@ -import autobind from 'autobind-decorator'; -import { isMutedUserRelated } from '@/misc/is-muted-user-related'; -import Channel from '../channel'; -import { fetchMeta } from '@/misc/fetch-meta'; -import { Notes } from '@/models/index'; -import { checkWordMute } from '@/misc/check-word-mute'; -import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; -import { isInstanceMuted } from '@/misc/is-instance-muted'; -import { Packed } from '@/misc/schema'; +import { isMutedUserRelated } from '@/misc/is-muted-user-related.js'; +import Channel from '../channel.js'; +import { fetchMeta } from '@/misc/fetch-meta.js'; +import { Notes } from '@/models/index.js'; +import { checkWordMute } from '@/misc/check-word-mute.js'; +import { isBlockerUserRelated } from '@/misc/is-blocker-user-related.js'; +import { isInstanceMuted } from '@/misc/is-instance-muted.js'; +import { Packed } from '@/misc/schema.js'; export default class extends Channel { public readonly chName = 'hybridTimeline'; public static shouldShare = true; public static requireCredential = true; - @autobind + constructor(id: string, connection: Channel['connection']) { + super(id, connection); + this.onNote = this.onNote.bind(this); + } + public async init(params: any) { const meta = await fetchMeta(); if (meta.disableLocalTimeline && !this.user!.isAdmin && !this.user!.isModerator) return; @@ -22,7 +25,6 @@ export default class extends Channel { this.subscriber.on('notesStream', this.onNote); } - @autobind private async onNote(note: Packed<'Note'>) { // チャンネルの投稿ではなく、自分自身の投稿 または // チャンネルの投稿ではなく、その投稿のユーザーをフォローしている または @@ -85,7 +87,6 @@ export default class extends Channel { this.send('note', note); } - @autobind public dispose() { // Unsubscribe events this.subscriber.off('notesStream', this.onNote); diff --git a/packages/backend/src/server/api/stream/channels/index.ts b/packages/backend/src/server/api/stream/channels/index.ts index f3826c4cf7..d422edde87 100644 --- a/packages/backend/src/server/api/stream/channels/index.ts +++ b/packages/backend/src/server/api/stream/channels/index.ts @@ -1,18 +1,18 @@ -import main from './main'; -import homeTimeline from './home-timeline'; -import localTimeline from './local-timeline'; -import hybridTimeline from './hybrid-timeline'; -import globalTimeline from './global-timeline'; -import serverStats from './server-stats'; -import queueStats from './queue-stats'; -import userList from './user-list'; -import antenna from './antenna'; -import messaging from './messaging'; -import messagingIndex from './messaging-index'; -import drive from './drive'; -import hashtag from './hashtag'; -import channel from './channel'; -import admin from './admin'; +import main from './main.js'; +import homeTimeline from './home-timeline.js'; +import localTimeline from './local-timeline.js'; +import hybridTimeline from './hybrid-timeline.js'; +import globalTimeline from './global-timeline.js'; +import serverStats from './server-stats.js'; +import queueStats from './queue-stats.js'; +import userList from './user-list.js'; +import antenna from './antenna.js'; +import messaging from './messaging.js'; +import messagingIndex from './messaging-index.js'; +import drive from './drive.js'; +import hashtag from './hashtag.js'; +import channel from './channel.js'; +import admin from './admin.js'; export default { main, diff --git a/packages/backend/src/server/api/stream/channels/local-timeline.ts b/packages/backend/src/server/api/stream/channels/local-timeline.ts index ae8f62ba61..4e198482a0 100644 --- a/packages/backend/src/server/api/stream/channels/local-timeline.ts +++ b/packages/backend/src/server/api/stream/channels/local-timeline.ts @@ -1,18 +1,21 @@ -import autobind from 'autobind-decorator'; -import { isMutedUserRelated } from '@/misc/is-muted-user-related'; -import Channel from '../channel'; -import { fetchMeta } from '@/misc/fetch-meta'; -import { Notes } from '@/models/index'; -import { checkWordMute } from '@/misc/check-word-mute'; -import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; -import { Packed } from '@/misc/schema'; +import { isMutedUserRelated } from '@/misc/is-muted-user-related.js'; +import Channel from '../channel.js'; +import { fetchMeta } from '@/misc/fetch-meta.js'; +import { Notes } from '@/models/index.js'; +import { checkWordMute } from '@/misc/check-word-mute.js'; +import { isBlockerUserRelated } from '@/misc/is-blocker-user-related.js'; +import { Packed } from '@/misc/schema.js'; export default class extends Channel { public readonly chName = 'localTimeline'; public static shouldShare = true; public static requireCredential = false; - @autobind + constructor(id: string, connection: Channel['connection']) { + super(id, connection); + this.onNote = this.onNote.bind(this); + } + public async init(params: any) { const meta = await fetchMeta(); if (meta.disableLocalTimeline) { @@ -23,7 +26,6 @@ export default class extends Channel { this.subscriber.on('notesStream', this.onNote); } - @autobind private async onNote(note: Packed<'Note'>) { if (note.user.host !== null) return; if (note.visibility !== 'public') return; @@ -66,7 +68,6 @@ export default class extends Channel { this.send('note', note); } - @autobind public dispose() { // Unsubscribe events this.subscriber.off('notesStream', this.onNote); diff --git a/packages/backend/src/server/api/stream/channels/main.ts b/packages/backend/src/server/api/stream/channels/main.ts index b41eae7c71..9cfea0bfc4 100644 --- a/packages/backend/src/server/api/stream/channels/main.ts +++ b/packages/backend/src/server/api/stream/channels/main.ts @@ -1,14 +1,12 @@ -import autobind from 'autobind-decorator'; -import Channel from '../channel'; -import { Notes } from '@/models/index'; -import { isInstanceMuted, isUserFromMutedInstance } from '@/misc/is-instance-muted'; +import Channel from '../channel.js'; +import { Notes } from '@/models/index.js'; +import { isInstanceMuted, isUserFromMutedInstance } from '@/misc/is-instance-muted.js'; export default class extends Channel { public readonly chName = 'main'; public static shouldShare = true; public static requireCredential = true; - @autobind public async init(params: any) { // Subscribe main stream channel this.subscriber.on(`mainStream:${this.user!.id}`, async data => { diff --git a/packages/backend/src/server/api/stream/channels/messaging-index.ts b/packages/backend/src/server/api/stream/channels/messaging-index.ts index 0c495398ab..b930785d20 100644 --- a/packages/backend/src/server/api/stream/channels/messaging-index.ts +++ b/packages/backend/src/server/api/stream/channels/messaging-index.ts @@ -1,12 +1,10 @@ -import autobind from 'autobind-decorator'; -import Channel from '../channel'; +import Channel from '../channel.js'; export default class extends Channel { public readonly chName = 'messagingIndex'; public static shouldShare = true; public static requireCredential = true; - @autobind public async init(params: any) { // Subscribe messaging index stream this.subscriber.on(`messagingIndexStream:${this.user!.id}`, data => { diff --git a/packages/backend/src/server/api/stream/channels/messaging.ts b/packages/backend/src/server/api/stream/channels/messaging.ts index d8fccf0763..94bbdeca52 100644 --- a/packages/backend/src/server/api/stream/channels/messaging.ts +++ b/packages/backend/src/server/api/stream/channels/messaging.ts @@ -1,10 +1,9 @@ -import autobind from 'autobind-decorator'; -import { readUserMessagingMessage, readGroupMessagingMessage, deliverReadActivity } from '../../common/read-messaging-message'; -import Channel from '../channel'; -import { UserGroupJoinings, Users, MessagingMessages } from '@/models/index'; -import { User, ILocalUser, IRemoteUser } from '@/models/entities/user'; -import { UserGroup } from '@/models/entities/user-group'; -import { StreamMessages } from '../types'; +import { readUserMessagingMessage, readGroupMessagingMessage, deliverReadActivity } from '../../common/read-messaging-message.js'; +import Channel from '../channel.js'; +import { UserGroupJoinings, Users, MessagingMessages } from '@/models/index.js'; +import { User, ILocalUser, IRemoteUser } from '@/models/entities/user.js'; +import { UserGroup } from '@/models/entities/user-group.js'; +import { StreamMessages } from '../types.js'; export default class extends Channel { public readonly chName = 'messaging'; @@ -18,7 +17,13 @@ export default class extends Channel { private typers: Record<User['id'], Date> = {}; private emitTypersIntervalId: ReturnType<typeof setInterval>; - @autobind + constructor(id: string, connection: Channel['connection']) { + super(id, connection); + this.onEvent = this.onEvent.bind(this); + this.onMessage = this.onMessage.bind(this); + this.emitTypers = this.emitTypers.bind(this); + } + public async init(params: any) { this.otherpartyId = params.otherparty; this.otherparty = this.otherpartyId ? await Users.findOneOrFail({ id: this.otherpartyId }) : null; @@ -46,7 +51,6 @@ export default class extends Channel { this.subscriber.on(this.subCh, this.onEvent); } - @autobind private onEvent(data: StreamMessages['messaging']['payload'] | StreamMessages['groupMessaging']['payload']) { if (data.type === 'typing') { const id = data.body; @@ -60,7 +64,6 @@ export default class extends Channel { } } - @autobind public onMessage(type: string, body: any) { switch (type) { case 'read': @@ -80,7 +83,6 @@ export default class extends Channel { } } - @autobind private async emitTypers() { const now = new Date(); @@ -97,7 +99,6 @@ export default class extends Channel { }); } - @autobind public dispose() { this.subscriber.off(this.subCh, this.onEvent); diff --git a/packages/backend/src/server/api/stream/channels/queue-stats.ts b/packages/backend/src/server/api/stream/channels/queue-stats.ts index be18438fa3..043d03ab8d 100644 --- a/packages/backend/src/server/api/stream/channels/queue-stats.ts +++ b/packages/backend/src/server/api/stream/channels/queue-stats.ts @@ -1,25 +1,27 @@ -import autobind from 'autobind-decorator'; -import Xev from 'xev'; -import Channel from '../channel'; +import { default as Xev } from 'xev'; +import Channel from '../channel.js'; -const ev = new Xev(); +const ev = new Xev.default(); export default class extends Channel { public readonly chName = 'queueStats'; public static shouldShare = true; public static requireCredential = false; - @autobind + constructor(id: string, connection: Channel['connection']) { + super(id, connection); + this.onStats = this.onStats.bind(this); + this.onMessage = this.onMessage.bind(this); + } + public async init(params: any) { ev.addListener('queueStats', this.onStats); } - @autobind private onStats(stats: any) { this.send('stats', stats); } - @autobind public onMessage(type: string, body: any) { switch (type) { case 'requestLog': @@ -34,7 +36,6 @@ export default class extends Channel { } } - @autobind public dispose() { ev.removeListener('queueStats', this.onStats); } diff --git a/packages/backend/src/server/api/stream/channels/server-stats.ts b/packages/backend/src/server/api/stream/channels/server-stats.ts index df89b4c750..0da1895767 100644 --- a/packages/backend/src/server/api/stream/channels/server-stats.ts +++ b/packages/backend/src/server/api/stream/channels/server-stats.ts @@ -1,25 +1,27 @@ -import autobind from 'autobind-decorator'; -import Xev from 'xev'; -import Channel from '../channel'; +import { default as Xev } from 'xev'; +import Channel from '../channel.js'; -const ev = new Xev(); +const ev = new Xev.default(); export default class extends Channel { public readonly chName = 'serverStats'; public static shouldShare = true; public static requireCredential = false; - @autobind + constructor(id: string, connection: Channel['connection']) { + super(id, connection); + this.onStats = this.onStats.bind(this); + this.onMessage = this.onMessage.bind(this); + } + public async init(params: any) { ev.addListener('serverStats', this.onStats); } - @autobind private onStats(stats: any) { this.send('stats', stats); } - @autobind public onMessage(type: string, body: any) { switch (type) { case 'requestLog': @@ -34,7 +36,6 @@ export default class extends Channel { } } - @autobind public dispose() { ev.removeListener('serverStats', this.onStats); } diff --git a/packages/backend/src/server/api/stream/channels/user-list.ts b/packages/backend/src/server/api/stream/channels/user-list.ts index b75920a180..57523c8488 100644 --- a/packages/backend/src/server/api/stream/channels/user-list.ts +++ b/packages/backend/src/server/api/stream/channels/user-list.ts @@ -1,10 +1,9 @@ -import autobind from 'autobind-decorator'; -import Channel from '../channel'; -import { Notes, UserListJoinings, UserLists } from '@/models/index'; -import { isMutedUserRelated } from '@/misc/is-muted-user-related'; -import { User } from '@/models/entities/user'; -import { isBlockerUserRelated } from '@/misc/is-blocker-user-related'; -import { Packed } from '@/misc/schema'; +import Channel from '../channel.js'; +import { Notes, UserListJoinings, UserLists } from '@/models/index.js'; +import { isMutedUserRelated } from '@/misc/is-muted-user-related.js'; +import { User } from '@/models/entities/user.js'; +import { isBlockerUserRelated } from '@/misc/is-blocker-user-related.js'; +import { Packed } from '@/misc/schema.js'; export default class extends Channel { public readonly chName = 'userList'; @@ -14,7 +13,12 @@ export default class extends Channel { public listUsers: User['id'][] = []; private listUsersClock: NodeJS.Timer; - @autobind + constructor(id: string, connection: Channel['connection']) { + super(id, connection); + this.updateListUsers = this.updateListUsers.bind(this); + this.onNote = this.onNote.bind(this); + } + public async init(params: any) { this.listId = params.listId as string; @@ -34,7 +38,6 @@ export default class extends Channel { this.listUsersClock = setInterval(this.updateListUsers, 5000); } - @autobind private async updateListUsers() { const users = await UserListJoinings.find({ where: { @@ -46,7 +49,6 @@ export default class extends Channel { this.listUsers = users.map(x => x.userId); } - @autobind private async onNote(note: Packed<'Note'>) { if (!this.listUsers.includes(note.userId)) return; @@ -81,7 +83,6 @@ export default class extends Channel { this.send('note', note); } - @autobind public dispose() { // Unsubscribe events this.subscriber.off(`userListStream:${this.listId}`, this.send); diff --git a/packages/backend/src/server/api/stream/index.ts b/packages/backend/src/server/api/stream/index.ts index e0bb8033a2..0cb38e2a99 100644 --- a/packages/backend/src/server/api/stream/index.ts +++ b/packages/backend/src/server/api/stream/index.ts @@ -1,21 +1,20 @@ -import autobind from 'autobind-decorator'; import * as websocket from 'websocket'; -import { readNotification } from '../common/read-notification'; -import call from '../call'; -import readNote from '@/services/note/read'; -import Channel from './channel'; -import channels from './channels/index'; +import { readNotification } from '../common/read-notification.js'; +import call from '../call.js'; +import readNote from '@/services/note/read.js'; +import Channel from './channel.js'; +import channels from './channels/index.js'; import { EventEmitter } from 'events'; -import { User } from '@/models/entities/user'; -import { Channel as ChannelModel } from '@/models/entities/channel'; -import { Users, Followings, Mutings, UserProfiles, ChannelFollowings, Blockings } from '@/models/index'; -import { ApiError } from '../error'; -import { AccessToken } from '@/models/entities/access-token'; -import { UserProfile } from '@/models/entities/user-profile'; -import { publishChannelStream, publishGroupMessagingStream, publishMessagingStream } from '@/services/stream'; -import { UserGroup } from '@/models/entities/user-group'; -import { StreamEventEmitter, StreamMessages } from './types'; -import { Packed } from '@/misc/schema'; +import { User } from '@/models/entities/user.js'; +import { Channel as ChannelModel } from '@/models/entities/channel.js'; +import { Users, Followings, Mutings, UserProfiles, ChannelFollowings, Blockings } from '@/models/index.js'; +import { ApiError } from '../error.js'; +import { AccessToken } from '@/models/entities/access-token.js'; +import { UserProfile } from '@/models/entities/user-profile.js'; +import { publishChannelStream, publishGroupMessagingStream, publishMessagingStream } from '@/services/stream.js'; +import { UserGroup } from '@/models/entities/user-group.js'; +import { StreamEventEmitter, StreamMessages } from './types.js'; +import { Packed } from '@/misc/schema.js'; /** * Main stream connection @@ -38,13 +37,18 @@ export default class Connection { wsConnection: websocket.connection, subscriber: EventEmitter, user: User | null | undefined, - token: AccessToken | null | undefined + token: AccessToken | null | undefined, ) { this.wsConnection = wsConnection; this.subscriber = subscriber; if (user) this.user = user; if (token) this.token = token; + this.onWsConnectionMessage = this.onWsConnectionMessage.bind(this); + this.onUserEvent = this.onUserEvent.bind(this); + this.onNoteStreamMessage = this.onNoteStreamMessage.bind(this); + this.onBroadcastMessage = this.onBroadcastMessage.bind(this); + this.wsConnection.on('message', this.onWsConnectionMessage); this.subscriber.on('broadcast', data => { @@ -62,7 +66,6 @@ export default class Connection { } } - @autobind private onUserEvent(data: StreamMessages['user']['payload']) { // { type, body }と展開するとそれぞれ型が分離してしまう switch (data.type) { case 'follow': @@ -108,7 +111,6 @@ export default class Connection { /** * クライアントからメッセージ受信時 */ - @autobind private async onWsConnectionMessage(data: websocket.Message) { if (data.type !== 'utf8') return; if (data.utf8Data == null) return; @@ -144,12 +146,10 @@ export default class Connection { } } - @autobind private onBroadcastMessage(data: StreamMessages['broadcast']['payload']) { this.sendMessageToWs(data.type, data.body); } - @autobind public cacheNote(note: Packed<'Note'>) { const add = (note: Packed<'Note'>) => { const existIndex = this.cachedNotes.findIndex(n => n.id === note.id); @@ -169,7 +169,6 @@ export default class Connection { if (note.renote) add(note.renote); } - @autobind private readNote(body: any) { const id = body.id; @@ -187,7 +186,6 @@ export default class Connection { /** * APIリクエスト要求時 */ - @autobind private async onApiRequest(payload: any) { // 新鮮なデータを利用するためにユーザーをフェッチ const user = this.user ? await Users.findOne(this.user.id) : null; @@ -210,7 +208,6 @@ export default class Connection { }); } - @autobind private onReadNotification(payload: any) { if (!payload.id) return; readNotification(this.user!.id, [payload.id]); @@ -219,7 +216,6 @@ export default class Connection { /** * 投稿購読要求時 */ - @autobind private onSubscribeNote(payload: any) { if (!payload.id) return; @@ -237,7 +233,6 @@ export default class Connection { /** * 投稿購読解除要求時 */ - @autobind private onUnsubscribeNote(payload: any) { if (!payload.id) return; @@ -248,7 +243,6 @@ export default class Connection { } } - @autobind private async onNoteStreamMessage(data: StreamMessages['note']['payload']) { this.sendMessageToWs('noteUpdated', { id: data.body.id, @@ -260,7 +254,6 @@ export default class Connection { /** * チャンネル接続要求時 */ - @autobind private onChannelConnectRequested(payload: any) { const { channel, id, params, pong } = payload; this.connectChannel(id, params, channel, pong); @@ -269,7 +262,6 @@ export default class Connection { /** * チャンネル切断要求時 */ - @autobind private onChannelDisconnectRequested(payload: any) { const { id } = payload; this.disconnectChannel(id); @@ -278,7 +270,6 @@ export default class Connection { /** * クライアントにメッセージ送信 */ - @autobind public sendMessageToWs(type: string, payload: any) { this.wsConnection.send(JSON.stringify({ type: type, @@ -289,7 +280,6 @@ export default class Connection { /** * チャンネルに接続 */ - @autobind public connectChannel(id: string, params: any, channel: string, pong = false) { if ((channels as any)[channel].requireCredential && this.user == null) { return; @@ -315,7 +305,6 @@ export default class Connection { * チャンネルから切断 * @param id チャンネルコネクションID */ - @autobind public disconnectChannel(id: string) { const channel = this.channels.find(c => c.id === id); @@ -329,7 +318,6 @@ export default class Connection { * チャンネルへメッセージ送信要求時 * @param data メッセージ */ - @autobind private onChannelMessageRequested(data: any) { const channel = this.channels.find(c => c.id === data.id); if (channel != null && channel.onMessage != null) { @@ -337,14 +325,12 @@ export default class Connection { } } - @autobind private typingOnChannel(channel: ChannelModel['id']) { if (this.user) { publishChannelStream(channel, 'typing', this.user.id); } } - @autobind private typingOnMessaging(param: { partner?: User['id']; group?: UserGroup['id']; }) { if (this.user) { if (param.partner) { @@ -355,7 +341,6 @@ export default class Connection { } } - @autobind private async updateFollowing() { const followings = await Followings.find({ where: { @@ -367,7 +352,6 @@ export default class Connection { this.following = new Set<string>(followings.map(x => x.followeeId)); } - @autobind private async updateMuting() { const mutings = await Mutings.find({ where: { @@ -379,7 +363,6 @@ export default class Connection { this.muting = new Set<string>(mutings.map(x => x.muteeId)); } - @autobind private async updateBlocking() { // ここでいうBlockingは被Blockingの意 const blockings = await Blockings.find({ where: { @@ -391,7 +374,6 @@ export default class Connection { this.blocking = new Set<string>(blockings.map(x => x.blockerId)); } - @autobind private async updateFollowingChannels() { const followings = await ChannelFollowings.find({ where: { @@ -403,7 +385,6 @@ export default class Connection { this.followingChannels = new Set<string>(followings.map(x => x.followeeId)); } - @autobind private async updateUserProfile() { this.userProfile = await UserProfiles.findOne({ userId: this.user!.id, @@ -413,7 +394,6 @@ export default class Connection { /** * ストリームが切れたとき */ - @autobind public dispose() { for (const c of this.channels.filter(c => c.dispose)) { if (c.dispose) c.dispose(); diff --git a/packages/backend/src/server/api/stream/types.ts b/packages/backend/src/server/api/stream/types.ts index 921856b38d..90cf59038d 100644 --- a/packages/backend/src/server/api/stream/types.ts +++ b/packages/backend/src/server/api/stream/types.ts @@ -1,20 +1,20 @@ import { EventEmitter } from 'events'; import Emitter from 'strict-event-emitter-types'; -import { Channel } from '@/models/entities/channel'; -import { User } from '@/models/entities/user'; -import { UserProfile } from '@/models/entities/user-profile'; -import { Note } from '@/models/entities/note'; -import { Antenna } from '@/models/entities/antenna'; -import { DriveFile } from '@/models/entities/drive-file'; -import { DriveFolder } from '@/models/entities/drive-folder'; -import { Emoji } from '@/models/entities/emoji'; -import { UserList } from '@/models/entities/user-list'; -import { MessagingMessage } from '@/models/entities/messaging-message'; -import { UserGroup } from '@/models/entities/user-group'; -import { AbuseUserReport } from '@/models/entities/abuse-user-report'; -import { Signin } from '@/models/entities/signin'; -import { Page } from '@/models/entities/page'; -import { Packed } from '@/misc/schema'; +import { Channel } from '@/models/entities/channel.js'; +import { User } from '@/models/entities/user.js'; +import { UserProfile } from '@/models/entities/user-profile.js'; +import { Note } from '@/models/entities/note.js'; +import { Antenna } from '@/models/entities/antenna.js'; +import { DriveFile } from '@/models/entities/drive-file.js'; +import { DriveFolder } from '@/models/entities/drive-folder.js'; +import { Emoji } from '@/models/entities/emoji.js'; +import { UserList } from '@/models/entities/user-list.js'; +import { MessagingMessage } from '@/models/entities/messaging-message.js'; +import { UserGroup } from '@/models/entities/user-group.js'; +import { AbuseUserReport } from '@/models/entities/abuse-user-report.js'; +import { Signin } from '@/models/entities/signin.js'; +import { Page } from '@/models/entities/page.js'; +import { Packed } from '@/misc/schema.js'; //#region Stream type-body definitions export interface InternalStreamTypes { |