wip
This commit is contained in:
parent
3500705585
commit
f4652ec4ac
|
@ -1,6 +1,8 @@
|
||||||
import { EntityRepository, Repository } from 'typeorm';
|
import { EntityRepository, Repository } from 'typeorm';
|
||||||
import { Emoji } from '@/models/entities/emoji';
|
import { Emoji } from '@/models/entities/emoji';
|
||||||
|
|
||||||
|
export type PackedEmoji = FIXME;
|
||||||
|
|
||||||
@EntityRepository(Emoji)
|
@EntityRepository(Emoji)
|
||||||
export class EmojiRepository extends Repository<Emoji> {
|
export class EmojiRepository extends Repository<Emoji> {
|
||||||
public async pack(
|
public async pack(
|
||||||
|
|
|
@ -3,6 +3,8 @@ import { EntityRepository, Repository } from 'typeorm';
|
||||||
import { Users } from '../../../index';
|
import { Users } from '../../../index';
|
||||||
import { ReversiGame } from '@/models/entities/games/reversi/game';
|
import { ReversiGame } from '@/models/entities/games/reversi/game';
|
||||||
|
|
||||||
|
export type PackedReversiGame = FIXME;
|
||||||
|
|
||||||
@EntityRepository(ReversiGame)
|
@EntityRepository(ReversiGame)
|
||||||
export class ReversiGameRepository extends Repository<ReversiGame> {
|
export class ReversiGameRepository extends Repository<ReversiGame> {
|
||||||
public async pack(
|
public async pack(
|
||||||
|
|
|
@ -4,6 +4,8 @@ import { Users } from '../../../index';
|
||||||
import { awaitAll } from '@/prelude/await-all';
|
import { awaitAll } from '@/prelude/await-all';
|
||||||
import { User } from '@/models/entities/user';
|
import { User } from '@/models/entities/user';
|
||||||
|
|
||||||
|
export type PackedReversiMatching = FIXME;
|
||||||
|
|
||||||
@EntityRepository(ReversiMatching)
|
@EntityRepository(ReversiMatching)
|
||||||
export class ReversiMatchingRepository extends Repository<ReversiMatching> {
|
export class ReversiMatchingRepository extends Repository<ReversiMatching> {
|
||||||
public async pack(
|
public async pack(
|
||||||
|
|
|
@ -77,7 +77,7 @@ export async function readGroupMessagingMessage(
|
||||||
id: In(messageIds)
|
id: In(messageIds)
|
||||||
});
|
});
|
||||||
|
|
||||||
const reads = [];
|
const reads: MessagingMessage['id'][] = [];
|
||||||
|
|
||||||
for (const message of messages) {
|
for (const message of messages) {
|
||||||
if (message.userId === userId) continue;
|
if (message.userId === userId) continue;
|
||||||
|
|
|
@ -137,7 +137,7 @@ export default define(meta, async (ps, user) => {
|
||||||
notify: ps.notify,
|
notify: ps.notify,
|
||||||
});
|
});
|
||||||
|
|
||||||
publishInternalEvent('antennaUpdated', Antennas.findOneOrFail(antenna.id));
|
publishInternalEvent('antennaUpdated', await Antennas.findOneOrFail(antenna.id));
|
||||||
|
|
||||||
return await Antennas.pack(antenna.id);
|
return await Antennas.pack(antenna.id);
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,7 +19,7 @@ export default class extends Channel {
|
||||||
this.channelId = params.channelId as string;
|
this.channelId = params.channelId as string;
|
||||||
|
|
||||||
// Subscribe stream
|
// Subscribe stream
|
||||||
this.subscriber.on('notesStream', this.onNote);
|
this.subscriber.on('notesStream', e => this.onNote(e));
|
||||||
this.subscriber.on(`channelStream:${this.channelId}`, this.onEvent);
|
this.subscriber.on(`channelStream:${this.channelId}`, this.onEvent);
|
||||||
this.emitTypersIntervalId = setInterval(this.emitTypers, 5000);
|
this.emitTypersIntervalId = setInterval(this.emitTypers, 5000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { User } from '@/models/entities/user';
|
import { User } from '@/models/entities/user';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import Emitter from 'strict-event-emitter-types';
|
import Emitter from 'strict-event-emitter-types';
|
||||||
import StreamTypes from 'misskey-js/built/streaming.types';
|
|
||||||
import { Channel } from '@/models/entities/channel';
|
import { Channel } from '@/models/entities/channel';
|
||||||
import { UserProfile } from '@/models/entities/user-profile';
|
import { UserProfile } from '@/models/entities/user-profile';
|
||||||
import { PackedUser } from '@/models/repositories/user';
|
import { PackedUser } from '@/models/repositories/user';
|
||||||
|
@ -14,6 +13,16 @@ import { PackedDriveFolder } from '@/models/repositories/drive-folder';
|
||||||
import { DriveFolder } from '@/models/entities/drive-folder';
|
import { DriveFolder } from '@/models/entities/drive-folder';
|
||||||
import { Note } from '@/models/entities/note';
|
import { Note } from '@/models/entities/note';
|
||||||
import { Emoji } from '@/models/entities/emoji';
|
import { Emoji } from '@/models/entities/emoji';
|
||||||
|
import { UserList } from '@/models/entities/user-list';
|
||||||
|
import { MessagingMessage } from '@/models/entities/messaging-message';
|
||||||
|
import { PackedMessagingMessage } from '@/models/repositories/messaging-message';
|
||||||
|
import { UserGroup } from '@/models/entities/user-group';
|
||||||
|
import { PackedReversiGame } from '@/models/repositories/games/reversi/game';
|
||||||
|
import { PackedReversiMatching } from '@/models/repositories/games/reversi/matching';
|
||||||
|
import { ReversiGame } from '@/models/entities/games/reversi/game';
|
||||||
|
import { AbuseUserReport } from '@/models/entities/abuse-user-report';
|
||||||
|
import { PackedEmoji } from '@/models/repositories/emoji';
|
||||||
|
import StreamTypes from 'misskey-js/built/streaming.types';
|
||||||
|
|
||||||
// 辞書(interface or type)から{ type, body }ユニオンを定義
|
// 辞書(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
|
||||||
|
@ -25,12 +34,6 @@ type EventUnionFromDictionary<
|
||||||
// (payload: P) => void からPを取り出す
|
// (payload: P) => void からPを取り出す
|
||||||
type Payload<T extends (payload: any) => void> = T extends (payload: infer P) => void ? P : never;
|
type Payload<T extends (payload: any) => void> = T extends (payload: infer P) => void ? P : never;
|
||||||
|
|
||||||
// misskey.jsのstreaming.typesの辞書から{ type, body }ユニオンを定義
|
|
||||||
type EventUnionFromMkJSTypes<
|
|
||||||
T extends { [key: string]: ((payload: any) => void) | (() => void) },
|
|
||||||
U = { [K in keyof T]: { type: K; body: Payload<T[K]>} }
|
|
||||||
> = U[keyof U];
|
|
||||||
|
|
||||||
//#region Stream type-body definitions
|
//#region Stream type-body definitions
|
||||||
export interface InternalStreamTypes {
|
export interface InternalStreamTypes {
|
||||||
antennaCreated: Antenna;
|
antennaCreated: Antenna;
|
||||||
|
@ -38,6 +41,10 @@ export interface InternalStreamTypes {
|
||||||
antennaUpdated: Antenna;
|
antennaUpdated: Antenna;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BroadcastTypes {
|
||||||
|
emojiAdded: PackedEmoji;
|
||||||
|
};
|
||||||
|
|
||||||
export interface UserStreamTypes {
|
export interface UserStreamTypes {
|
||||||
terminate: {};
|
terminate: {};
|
||||||
followChannel: Channel;
|
followChannel: Channel;
|
||||||
|
@ -75,6 +82,7 @@ export interface MainStreamTypes {
|
||||||
readAllChannels: never;
|
readAllChannels: never;
|
||||||
unreadChannel: never;
|
unreadChannel: never;
|
||||||
myTokenRegenerated: never;
|
myTokenRegenerated: never;
|
||||||
|
reversiInvited: PackedReversiMatching;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DriveStreamTypes {
|
export interface DriveStreamTypes {
|
||||||
|
@ -117,7 +125,92 @@ export interface NoteStreamTypes {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ChannelStreamTypes {
|
||||||
|
typing: User['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UserListStreamTypes {
|
||||||
|
userAdded: PackedUser;
|
||||||
|
userRemoved: PackedUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AntennaStreamTypes {
|
||||||
|
note: Note;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MessagingStreamTypes {
|
||||||
|
read: MessagingMessage['id'][];
|
||||||
|
typing: User['id'];
|
||||||
|
message: PackedMessagingMessage;
|
||||||
|
deleted: MessagingMessage['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GroupMessagingStreamTypes {
|
||||||
|
read: {
|
||||||
|
ids: MessagingMessage['id'][];
|
||||||
|
userId: User['id'];
|
||||||
|
};
|
||||||
|
typing: User['id'];
|
||||||
|
message: PackedMessagingMessage;
|
||||||
|
deleted: MessagingMessage['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MessagingIndexStreamTypes {
|
||||||
|
read: MessagingMessage['id'][];
|
||||||
|
message: PackedMessagingMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReversiStreamTypes {
|
||||||
|
matched: PackedReversiGame;
|
||||||
|
invited: PackedReversiMatching;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReversiGameStreamTypes {
|
||||||
|
started: PackedReversiGame;
|
||||||
|
ended: {
|
||||||
|
winnerId: User['id'],
|
||||||
|
game: PackedReversiGame;
|
||||||
|
};
|
||||||
|
updateSettings: {
|
||||||
|
key: string;
|
||||||
|
value: FIXME;
|
||||||
|
};
|
||||||
|
initForm: {
|
||||||
|
userId: User['id'];
|
||||||
|
form: FIXME;
|
||||||
|
};
|
||||||
|
updateForm: {
|
||||||
|
userId: User['id'];
|
||||||
|
id: string;
|
||||||
|
value: FIXME;
|
||||||
|
};
|
||||||
|
message: {
|
||||||
|
userId: User['id'];
|
||||||
|
message: FIXME;
|
||||||
|
};
|
||||||
|
changeAccepts: {
|
||||||
|
user1: boolean;
|
||||||
|
user2: boolean;
|
||||||
|
};
|
||||||
|
set: {
|
||||||
|
at: Date;
|
||||||
|
color: boolean;
|
||||||
|
pos: number;
|
||||||
|
next: boolean;
|
||||||
|
};
|
||||||
|
watching: User['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AdminStreamTypes {
|
||||||
|
newAbuseUserReport: {
|
||||||
|
id: AbuseUserReport['id'];
|
||||||
|
targetUserId: User['id'],
|
||||||
|
reporterId: User['id'],
|
||||||
|
comment: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region 名前とメッセージのペアを中間生成
|
//#region 名前とメッセージのペアを中間生成
|
||||||
interface StreamMessages {
|
interface StreamMessages {
|
||||||
internal: {
|
internal: {
|
||||||
|
@ -126,7 +219,7 @@ interface StreamMessages {
|
||||||
};
|
};
|
||||||
broadcast: {
|
broadcast: {
|
||||||
name: 'broadcast';
|
name: 'broadcast';
|
||||||
spec: EventUnionFromMkJSTypes<StreamTypes.BroadcasrEvents>;
|
spec: EventUnionFromDictionary<BroadcastTypes>;
|
||||||
};
|
};
|
||||||
user: {
|
user: {
|
||||||
name: `user:${User['id']}`;
|
name: `user:${User['id']}`;
|
||||||
|
@ -143,11 +236,52 @@ interface StreamMessages {
|
||||||
note: {
|
note: {
|
||||||
name: `noteStream:${Note['id']}`;
|
name: `noteStream:${Note['id']}`;
|
||||||
spec: EventUnionFromDictionary<NoteStreamTypes>;
|
spec: EventUnionFromDictionary<NoteStreamTypes>;
|
||||||
|
};
|
||||||
|
channel: {
|
||||||
|
name: `channelStream:${Channel['id']}`;
|
||||||
|
spec: EventUnionFromDictionary<ChannelStreamTypes>;
|
||||||
|
};
|
||||||
|
userList: {
|
||||||
|
name: `userListStream:${UserList['id']}`;
|
||||||
|
spec: EventUnionFromDictionary<UserListStreamTypes>;
|
||||||
|
};
|
||||||
|
antenna: {
|
||||||
|
name: `antennaStream:${Antenna['id']}`;
|
||||||
|
spec: EventUnionFromDictionary<AntennaStreamTypes>;
|
||||||
|
};
|
||||||
|
messaging: {
|
||||||
|
name: `messagingStream:${User['id']}-${User['id']}`;
|
||||||
|
spec: EventUnionFromDictionary<MessagingStreamTypes>;
|
||||||
|
};
|
||||||
|
groupMessaging: {
|
||||||
|
name: `messagingStream:${UserGroup['id']}`;
|
||||||
|
spec: EventUnionFromDictionary<GroupMessagingStreamTypes>;
|
||||||
|
};
|
||||||
|
messagingIndex: {
|
||||||
|
name: `messagingIndexStream:${User['id']}`;
|
||||||
|
spec: EventUnionFromDictionary<MessagingIndexStreamTypes>;
|
||||||
|
};
|
||||||
|
reversi: {
|
||||||
|
name: `reversiStream:${User['id']}`;
|
||||||
|
spec: EventUnionFromDictionary<ReversiStreamTypes>;
|
||||||
|
};
|
||||||
|
reversiGame: {
|
||||||
|
name: `reversiGameStream:${ReversiGame['id']}`;
|
||||||
|
spec: EventUnionFromDictionary<ReversiGameStreamTypes>;
|
||||||
|
};
|
||||||
|
admin: {
|
||||||
|
name: `adminStream:${User['id']}`;
|
||||||
|
spec: EventUnionFromDictionary<AdminStreamTypes>;
|
||||||
}
|
}
|
||||||
|
// and 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 EventsGenerater<K extends keyof StreamMessages> = { [key in StreamMessages[K]['name']]: (e: StreamMessages[K]['spec']) => void };
|
||||||
export type StreamEventEmitter = Emitter<EventEmitter, EventsGenerater<keyof StreamMessages>>;
|
type NotesStreamEvent = { notesStream: (e: PackedNote) => void };
|
||||||
|
export type StreamEventEmitter = Emitter<EventEmitter, EventsGenerater<keyof StreamMessages> & NotesStreamEvent>;
|
||||||
|
|
||||||
|
// Channel Union
|
||||||
|
type ChannelsUnionGenerater<K extends keyof StreamMessages> = StreamMessages[K]['name'];
|
||||||
|
export type Channels = ChannelsUnionGenerater<keyof StreamMessages> | 'notesStream';
|
||||||
|
|
|
@ -7,9 +7,10 @@ import { UserGroup } from '@/models/entities/user-group';
|
||||||
import config from '@/config/index';
|
import config from '@/config/index';
|
||||||
import { Antenna } from '@/models/entities/antenna';
|
import { Antenna } from '@/models/entities/antenna';
|
||||||
import { Channel } from '@/models/entities/channel';
|
import { Channel } from '@/models/entities/channel';
|
||||||
|
import { BroadcastTypes, Channels, InternalStreamTypes, UserStreamTypes } from '@/server/api/stream/types';
|
||||||
|
|
||||||
class Publisher {
|
class Publisher {
|
||||||
private publish = (channel: string, type: string | null, value?: any): void => {
|
private publish = (channel: Channels, type: string | null, value?: any): void => {
|
||||||
const message = type == null ? value : value == null ?
|
const message = type == null ? value : value == null ?
|
||||||
{ type: type, body: null } :
|
{ type: type, body: null } :
|
||||||
{ type: type, body: value };
|
{ type: type, body: value };
|
||||||
|
@ -20,15 +21,15 @@ class Publisher {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public publishInternalEvent = (type: string, value?: any): void => {
|
public publishInternalEvent = <K extends keyof InternalStreamTypes>(type: K, value: InternalStreamTypes[K]): void => {
|
||||||
this.publish('internal', type, typeof value === 'undefined' ? null : value);
|
this.publish('internal', type, typeof value === 'undefined' ? null : value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public publishUserEvent = (userId: User['id'], type: string, value?: any): void => {
|
public publishUserEvent = <K extends keyof UserStreamTypes>(userId: User['id'], type: K, value: UserStreamTypes[K]): void => {
|
||||||
this.publish(`user:${userId}`, type, typeof value === 'undefined' ? null : value);
|
this.publish(`user:${userId}`, type, typeof value === 'undefined' ? null : value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public publishBroadcastStream = (type: string, value?: any): void => {
|
public publishBroadcastStream = <K extends keyof BroadcastTypes>(type: K, value: BroadcastTypes[K]): void => {
|
||||||
this.publish('broadcast', type, typeof value === 'undefined' ? null : value);
|
this.publish('broadcast', type, typeof value === 'undefined' ? null : value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue