This commit is contained in:
tamaina 2021-09-07 02:40:38 +09:00
parent 4793d1cc56
commit be47a120d7
3 changed files with 19 additions and 15 deletions

View File

@ -3,6 +3,8 @@ import { readUserMessagingMessage, readGroupMessagingMessage, deliverReadActivit
import Channel from '../channel'; import Channel from '../channel';
import { UserGroupJoinings, Users, MessagingMessages } from '@/models/index'; import { UserGroupJoinings, Users, MessagingMessages } from '@/models/index';
import { User, ILocalUser, IRemoteUser } from '@/models/entities/user'; import { User, ILocalUser, IRemoteUser } from '@/models/entities/user';
import { UserGroup } from '@/models/entities/user-group';
import { StreamMessages } from '../types';
export default class extends Channel { export default class extends Channel {
public readonly chName = 'messaging'; public readonly chName = 'messaging';
@ -12,7 +14,7 @@ export default class extends Channel {
private otherpartyId: string | null; private otherpartyId: string | null;
private otherparty: User | null; private otherparty: User | null;
private groupId: string | null; private groupId: string | null;
private subCh: string; private subCh: `messagingStream:${User['id']}-${User['id']}` | `messagingStream:${UserGroup['id']}`;
private typers: Record<User['id'], Date> = {}; private typers: Record<User['id'], Date> = {};
private emitTypersIntervalId: ReturnType<typeof setInterval>; private emitTypersIntervalId: ReturnType<typeof setInterval>;
@ -45,7 +47,7 @@ export default class extends Channel {
} }
@autobind @autobind
private onEvent(data: any) { private onEvent(data: StreamMessages['messaging']['spec'] | StreamMessages['groupMessaging']['spec']) {
if (data.type === 'typing') { if (data.type === 'typing') {
const id = data.body; const id = data.body;
const begin = this.typers[id] == null; const begin = this.typers[id] == null;

View File

@ -15,7 +15,7 @@ import { UserProfile } from '@/models/entities/user-profile';
import { publishChannelStream, publishGroupMessagingStream, publishMessagingStream } from '@/services/stream'; import { publishChannelStream, publishGroupMessagingStream, publishMessagingStream } from '@/services/stream';
import { UserGroup } from '@/models/entities/user-group'; import { UserGroup } from '@/models/entities/user-group';
import { PackedNote } from '@/models/repositories/note'; import { PackedNote } from '@/models/repositories/note';
import { StreamEventEmitter, UserStreams } from './types'; import { StreamEventEmitter, StreamMessages } from './types';
/** /**
* Main stream connection * Main stream connection
@ -47,8 +47,8 @@ export default class Connection {
this.wsConnection.on('message', this.onWsConnectionMessage); this.wsConnection.on('message', this.onWsConnectionMessage);
this.subscriber.on('broadcast', async ({ type, body }) => { this.subscriber.on('broadcast', async ev => {
this.onBroadcastMessage(type, body); this.onBroadcastMessage(ev.type, ev.body);
}); });
if (this.user) { if (this.user) {
@ -65,7 +65,7 @@ export default class Connection {
} }
@autobind @autobind
private onUserEvent(ev: UserStreams) { // { type, body }と展開すると型も展開されてしまう private onUserEvent(ev: StreamMessages['user']['spec']) { // { type, body }と展開すると型も展開されてしまう
switch (ev.type) { switch (ev.type) {
case 'follow': case 'follow':
this.following.add(ev.body.id); this.following.add(ev.body.id);

View File

@ -29,7 +29,7 @@ import { Page } from '@/models/entities/page';
// https://stackoverflow.com/questions/49311989/can-i-infer-the-type-of-a-value-using-extends-keyof-type // https://stackoverflow.com/questions/49311989/can-i-infer-the-type-of-a-value-using-extends-keyof-type
type EventUnionFromDictionary< type EventUnionFromDictionary<
T extends object, T extends object,
U = { [K in keyof T]: { type: K; body: T[K]} } U = { [K in keyof T]: { type: K; body: T[K]; } }
> = U[keyof U]; > = U[keyof U];
//#region Stream type-body definitions //#region Stream type-body definitions
@ -225,7 +225,7 @@ export interface AdminStreamTypes {
//#endregion //#endregion
//#region 名前とメッセージのペアを中間生成 //#region 名前とメッセージのペアを中間生成
interface StreamMessages { export type StreamMessages = {
internal: { internal: {
name: 'internal'; name: 'internal';
spec: EventUnionFromDictionary<InternalStreamTypes>; spec: EventUnionFromDictionary<InternalStreamTypes>;
@ -286,15 +286,17 @@ interface StreamMessages {
name: `adminStream:${User['id']}`; name: `adminStream:${User['id']}`;
spec: EventUnionFromDictionary<AdminStreamTypes>; spec: EventUnionFromDictionary<AdminStreamTypes>;
}; };
// and notesStream (specにPackedNoteを突っ込むとなぜかバグる) notes: {
} name: 'notesStream';
spec: PackedNote;
};
};
//#endregion //#endregion
// API event definitions // API event definitions
type EventsGenerater<K extends keyof StreamMessages> = { [key in StreamMessages[K]['name']]: (e: StreamMessages[K]['spec']) => void }; type EventsDictionary = { [x in keyof StreamMessages]: { [y in StreamMessages[x]['name']]: (e: StreamMessages[x]['spec']) => void } };
type NotesStreamEvent = { notesStream: (e: PackedNote) => void }; type Events<D> = (D extends any ? (k: D) => void : never) extends ((k: infer E) => void) ? E : never;
export type StreamEventEmitter = Emitter<EventEmitter, EventsGenerater<keyof StreamMessages> & NotesStreamEvent>; export type StreamEventEmitter = Emitter<EventEmitter, Events<EventsDictionary[keyof StreamMessages]>>;
// provide stream channels union // provide stream channels union
type ChannelsUnionGenerater<K extends keyof StreamMessages> = StreamMessages[K]['name']; export type StreamChannels = StreamMessages[keyof StreamMessages]['name'] | 'notesStream';
export type StreamChannels = ChannelsUnionGenerater<keyof StreamMessages> | 'notesStream';