This commit is contained in:
tamaina 2021-09-06 17:56:17 +09:00
parent ca82538e10
commit dd175a8e6e
2 changed files with 87 additions and 12 deletions

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, UserEvents } from './types'; import { StreamEventEmitter, UserStreams } from './types';
/** /**
* Main stream connection * Main stream connection
@ -65,7 +65,7 @@ export default class Connection {
} }
@autobind @autobind
private onUserEvent(ev: UserEvents) { // { type, body }と展開すると型も展開されてしまう private onUserEvent(ev: UserStreams) { // { 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

@ -7,23 +7,46 @@ import { UserProfile } from '@/models/entities/user-profile';
import { PackedUser } from '@/models/repositories/user'; import { PackedUser } from '@/models/repositories/user';
import { PackedNotification } from '@/models/repositories/notification'; import { PackedNotification } from '@/models/repositories/notification';
import { PackedNote } from '@/models/repositories/note'; import { PackedNote } from '@/models/repositories/note';
import { Antenna } from '@/models/entities/antenna';
import { DriveFile } from '@/models/entities/drive-file';
import { PackedDriveFile } from '@/models/repositories/drive-file';
import { PackedDriveFolder } from '@/models/repositories/drive-folder';
import { DriveFolder } from '@/models/entities/drive-folder';
import { Note } from '@/models/entities/note';
import { Emoji } from '@/models/entities/emoji';
type Payload<T extends (payload: any) => void> = T extends (payload: infer P) => void ? P : never; // 辞書(interface or type)から{ type, body }ユニオンを定義
// 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];
// (payload: P) => void からPを取り出す
type Payload<T extends (payload: any) => void> = T extends (payload: infer P) => void ? P : never;
// misskey.jsのstreaming.typesの辞書から{ type, body }ユニオンを定義
type EventUnionFromMkJSTypes< type EventUnionFromMkJSTypes<
T extends { [key: string]: ((payload: any) => void) | (() => void) }, T extends { [key: string]: ((payload: any) => void) | (() => void) },
U = { [K in keyof T]: { type: K; body: Payload<T[K]>} } U = { [K in keyof T]: { type: K; body: Payload<T[K]>} }
> = U[keyof U]; > = U[keyof U];
export type BroadcastStream = EventUnionFromMkJSTypes<StreamTypes.BroadcasrEvents>; //#region Stream type-body definitions
export interface UserEventTypes { // internal
export interface InternalStreamTypes {
antennaCreated: Antenna;
antennaDeleted: Antenna;
antennaUpdated: Antenna;
}
export type InternalStreams = EventUnionFromDictionary<InternalStreamTypes>;
// broadcast
export type BroadcastStreams = EventUnionFromMkJSTypes<StreamTypes.BroadcasrEvents>;
// user
export type UserEventName = `user:${User['id']}`;
export interface UserStreamTypes {
terminate: {}; terminate: {};
followChannel: Channel; followChannel: Channel;
unfollowChannel: Channel; unfollowChannel: Channel;
@ -34,9 +57,10 @@ export interface UserEventTypes {
unfollow: PackedUser; unfollow: PackedUser;
userAdded: PackedUser; userAdded: PackedUser;
} }
export type UserEventName = `user:${User['id']}`; export type UserStreams = EventUnionFromDictionary<UserStreamTypes>;
export type UserEvents = EventUnionFromDictionary<UserEventTypes>;
// main
export type mainStreamName = `mainStream:${User['id']}`;
export interface MainStreamTypes { export interface MainStreamTypes {
notification: PackedNotification; notification: PackedNotification;
mention: PackedNote; mention: PackedNote;
@ -63,17 +87,68 @@ export interface MainStreamTypes {
unreadChannel: never; unreadChannel: never;
myTokenRegenerated: never; myTokenRegenerated: never;
} }
export type mainStreamName = `mainStream:${User['id']}`;
export type mainStreams = EventUnionFromDictionary<MainStreamTypes>; export type mainStreams = EventUnionFromDictionary<MainStreamTypes>;
// drive
export type driveStreamName = `driveStream:${User['id']}`;
export interface DriveStreamTypes {
fileCreated: PackedDriveFile;
fileDeleted: DriveFile['id'];
fileUpdated: PackedDriveFile;
folderCreated: PackedDriveFolder;
folderDeleted: DriveFolder['id'];
folderUpdated: PackedDriveFolder;
}
export type driveStreams= EventUnionFromDictionary<DriveStreamTypes>;
// note
export type noteStreamName = `noteStream:${Note['id']}`;
export interface NoteStreamTypes {
pollVoted: {
id: Note['id'];
body: {
choice: number;
userId: User['id'];
};
};
deleted: {
id: Note['id'];
body: {
deletedAt: Date;
};
};
reacted: {
id: Note['id'];
body: {
reaction: string;
emoji?: Emoji;
userId: User['id'];
};
};
unreacted: {
id: Note['id'];
body: {
reaction: string;
userId: User['id'];
}
};
}
export type noteStreams = EventUnionFromDictionary<NoteStreamTypes>;
//#endregion
//#region API event definitions
interface StreamEvents { interface StreamEvents {
'broadcast': (e: BroadcastStream) => void; 'broadcast': (e: BroadcastStreams) => void;
'internal': (e: InternalStreams) => void;
} }
interface AuthenticatedStreamEvents { interface AuthenticatedStreamEvents {
[key: UserEventName]: (e: UserEvents) => void; [key: UserEventName]: (e: UserStreams) => void;
[key: mainStreamName]: (e: mainStreams) => void; [key: mainStreamName]: (e: mainStreams) => void;
[key: `driveStream:${User['id']}`]: (e: { type: string; body: any }) => void; [key: driveStreamName]: (e: driveStreams) => void;
[key: noteStreamName]: (e: noteStreams) => void;
} }
export type StreamEventEmitter = Emitter<EventEmitter, AuthenticatedStreamEvents & StreamEvents>; export type StreamEventEmitter = Emitter<EventEmitter, AuthenticatedStreamEvents & StreamEvents>;
//#endregion