diff --git a/index.ts b/index.ts index 343e316..f032d08 100644 --- a/index.ts +++ b/index.ts @@ -1,7 +1,7 @@ import { api } from "misskey-js"; -import Stream from "./misskey-js/streaming"; import type { Stream as MisskeyStream } from "misskey-js"; import type { Note, UserLite } from "misskey-js/entities.js"; +import Stream from "./misskey-js/streaming"; import OpenAI from "openai"; import type { ChatCompletionMessageParam } from "openai/resources/index.js"; @@ -16,7 +16,6 @@ const openai = new OpenAI({ apiKey: Bun.env["OPENAI_API_KEY"], }); - // #region util /** pick up to random N elements from array. @@ -37,42 +36,40 @@ const sleep = (msec: number) => new Promise((resolve) => setTimeout(resolve, msec)); // #endregion - // #region misskey const me = await misskey.request("i", {}); /** check if a note is suitable as an input */ const isSuitableAsInput = (n: Note) => - !n.user.isBot - && !n.replyId - && (!n.mentions || n.mentions.length === 0) - && n.text?.length && n.text.length > 0 + !n.user.isBot && + !n.replyId && + (!n.mentions || n.mentions.length === 0) && + n.text?.length && + n.text.length > 0; /** randomly sample some notes from the timeline */ async function getNotes() { - // randomly sample N local notes const localNotes = (count: number) => - misskey.request("notes/local-timeline", { limit: 100 }) + misskey + .request("notes/local-timeline", { limit: 100 }) .then((xs) => xs.filter(isSuitableAsInput)) .then((xs) => sample(xs, count)); // randomly sample N global notes const globalNotes = (count: number) => - misskey.request("notes/global-timeline", { limit: 100 }) + misskey + .request("notes/global-timeline", { limit: 100 }) .then((xs) => xs.filter(isSuitableAsInput)) .then((xs) => sample(xs, count)); // randomly sample N notes of mine const myNotes = (count: number) => - misskey.request("users/notes", { userId: me.id, limit: 100 }) + misskey + .request("users/notes", { userId: me.id, limit: 100 }) .then((xs) => sample(xs, count)); - const notes = await Promise.all([ - localNotes(5), - globalNotes(10), - myNotes(2), - ]); + const notes = await Promise.all([localNotes(5), globalNotes(10), myNotes(2)]); return sample(notes.flat()); } @@ -87,16 +84,20 @@ async function expandReplyTree(note: Note, acc: Note[] = [], cutoff = 5) { const noteToMessage = (note: Note): ChatCompletionMessageParam => ({ role: note.userId === me.id ? ("assistant" as const) : ("user" as const), content: note.text?.replaceAll(`@${me.username}`, "") || "", -}) +}); // #endregion - // #region job type Job = // read posts and post a note | { type: "post" } // reply to a specific note - | { type: "reply"; id: string, visibility: Note["visibility"], replyTree: Note[] }; + | { + type: "reply"; + id: string; + visibility: Note["visibility"]; + replyTree: Note[]; + }; /** create a prompt for the job */ async function preparePrompt(job: Job): Promise { @@ -154,7 +155,7 @@ user が SNS 上で、あなたへのメッセージを送ってきています このような文体を真似して、user の発言に返答してください。`, }, - ...(job.replyTree.map(noteToMessage)) + ...job.replyTree.map(noteToMessage), ]; } } @@ -187,7 +188,8 @@ async function processJob(job: Job) { console.log(); // concatenate the partial responses - const text = responses.join("") + const text = responses + .join("") .replaceAll(/(\r\n|\r|\n)\s+/g, "\n\n") // remove extra newlines .replaceAll("@", ""); // remove mentions @@ -221,8 +223,8 @@ function initializeStream() { token: Bun.env["MISSKEY_CREDENTIAL"] ?? "", }, { - binaryType: "arraybuffer" - } + binaryType: "arraybuffer", + }, ) as unknown as MisskeyStream; channel = stream.useChannel("main"); @@ -241,7 +243,12 @@ function initializeStream() { if (e.text && e.userId !== me.id && !e.user.isBot) { const replyTree = await expandReplyTree(e); console.log(`* push: reply (${e.id}, ${replyTree.length} msgs)`); - jobs.push({ type: "reply", id: e.id, visibility: e.visibility, replyTree }); + jobs.push({ + type: "reply", + id: e.id, + visibility: e.visibility, + replyTree, + }); } }); @@ -276,7 +283,10 @@ async function pushJob() { while (true) { const now = new Date(Date.now()); // push a post job every 15 minutes (XX:00, XX:15, XX:30, XX:45) - if (now.getMinutes() % 15 < Number.EPSILON && !jobs.some((job) => job.type === "post")) { + if ( + now.getMinutes() % 15 < Number.EPSILON && + !jobs.some((job) => job.type === "post") + ) { console.log("* push: post"); jobs.push({ type: "post" }); } diff --git a/misskey-js/streaming.ts b/misskey-js/streaming.ts index 2cb90ed..178f1fc 100644 --- a/misskey-js/streaming.ts +++ b/misskey-js/streaming.ts @@ -1,393 +1,474 @@ -import { EventEmitter } from 'eventemitter3'; -import ReconnectingWebsocket, { type Options } from 'reconnecting-websocket'; -import type { BroadcastEvents, Channels } from './streaming.types.js'; +import { EventEmitter } from "eventemitter3"; +import ReconnectingWebsocket, { type Options } from "reconnecting-websocket"; +import type { BroadcastEvents, Channels } from "./streaming.types.js"; -export function urlQuery(obj: Record): string { - const params = Object.entries(obj) - .filter(([, v]) => Array.isArray(v) ? v.length : v !== undefined) - // biome-ignore lint/suspicious/noAssignInExpressions: - // biome-ignore lint/style/noCommaOperator: - // biome-ignore lint/style/noNonNullAssertion: - .reduce((a, [k, v]) => (a[k] = v!, a), {} as Record); +export function urlQuery( + obj: Record, +): string { + const params = Object.entries(obj) + .filter(([, v]) => (Array.isArray(v) ? v.length : v !== undefined)) + // biome-ignore lint/suspicious/noAssignInExpressions: + // biome-ignore lint/style/noCommaOperator: + // biome-ignore lint/style/noNonNullAssertion: + .reduce( + (a, [k, v]) => ((a[k] = v!), a), + {} as Record, + ); - return Object.entries(params) - .map((e) => `${e[0]}=${encodeURIComponent(e[1])}`) - .join('&'); + return Object.entries(params) + .map((e) => `${e[0]}=${encodeURIComponent(e[1])}`) + .join("&"); } type AnyOf> = T[keyof T]; export type StreamEvents = { - _connected_: undefined; - _disconnected_: undefined; + _connected_: undefined; + _disconnected_: undefined; } & BroadcastEvents; export interface IStream extends EventEmitter { - state: 'initializing' | 'reconnecting' | 'connected'; + state: "initializing" | "reconnecting" | "connected"; - useChannel(channel: C, params?: Channels[C]['params'], name?: string): IChannelConnection; - removeSharedConnection(connection: SharedConnection): void; - removeSharedConnectionPool(pool: Pool): void; - disconnectToChannel(connection: NonSharedConnection): void; - send(typeOrPayload: string): void; - send(typeOrPayload: string, payload: unknown): void; - send(typeOrPayload: Record | unknown[]): void; - send(typeOrPayload: string | Record | unknown[], payload?: unknown): void; - ping(): void; - heartbeat(): void; - close(): void; + useChannel( + channel: C, + params?: Channels[C]["params"], + name?: string, + ): IChannelConnection; + removeSharedConnection(connection: SharedConnection): void; + removeSharedConnectionPool(pool: Pool): void; + disconnectToChannel(connection: NonSharedConnection): void; + send(typeOrPayload: string): void; + send(typeOrPayload: string, payload: unknown): void; + send(typeOrPayload: Record | unknown[]): void; + send( + typeOrPayload: string | Record | unknown[], + payload?: unknown, + ): void; + ping(): void; + heartbeat(): void; + close(): void; } /** * Misskey stream connection */ // eslint-disable-next-line import/no-default-export -export default class Stream extends EventEmitter implements IStream { - private stream: ReconnectingWebsocket; - public state: 'initializing' | 'reconnecting' | 'connected' = 'initializing'; - private sharedConnectionPools: Pool[] = []; - private sharedConnections: SharedConnection[] = []; - private nonSharedConnections: NonSharedConnection[] = []; - private idCounter = 0; +export default class Stream + extends EventEmitter + implements IStream +{ + private stream: ReconnectingWebsocket; + public state: "initializing" | "reconnecting" | "connected" = "initializing"; + private sharedConnectionPools: Pool[] = []; + private sharedConnections: SharedConnection[] = []; + private nonSharedConnections: NonSharedConnection[] = []; + private idCounter = 0; - constructor(origin: string, user: { token: string; } | null, options: { - WebSocket?: Options['WebSocket']; - binaryType?: ReconnectingWebsocket['binaryType']; - } = {}) { - super(); + constructor( + origin: string, + user: { token: string } | null, + options: { + WebSocket?: Options["WebSocket"]; + binaryType?: ReconnectingWebsocket["binaryType"]; + } = {}, + ) { + super(); - this.genId = this.genId.bind(this); - this.useChannel = this.useChannel.bind(this); - this.useSharedConnection = this.useSharedConnection.bind(this); - this.removeSharedConnection = this.removeSharedConnection.bind(this); - this.removeSharedConnectionPool = this.removeSharedConnectionPool.bind(this); - this.connectToChannel = this.connectToChannel.bind(this); - this.disconnectToChannel = this.disconnectToChannel.bind(this); - this.onOpen = this.onOpen.bind(this); - this.onClose = this.onClose.bind(this); - this.onMessage = this.onMessage.bind(this); - this.send = this.send.bind(this); - this.close = this.close.bind(this); + this.genId = this.genId.bind(this); + this.useChannel = this.useChannel.bind(this); + this.useSharedConnection = this.useSharedConnection.bind(this); + this.removeSharedConnection = this.removeSharedConnection.bind(this); + this.removeSharedConnectionPool = + this.removeSharedConnectionPool.bind(this); + this.connectToChannel = this.connectToChannel.bind(this); + this.disconnectToChannel = this.disconnectToChannel.bind(this); + this.onOpen = this.onOpen.bind(this); + this.onClose = this.onClose.bind(this); + this.onMessage = this.onMessage.bind(this); + this.send = this.send.bind(this); + this.close = this.close.bind(this); - const query = urlQuery({ - i: user?.token, + const query = urlQuery({ + i: user?.token, - // To prevent cache of an HTML such as error screen - _t: Date.now(), - }); + // To prevent cache of an HTML such as error screen + _t: Date.now(), + }); - const wsOrigin = origin.replace('http://', 'ws://').replace('https://', 'wss://'); + const wsOrigin = origin + .replace("http://", "ws://") + .replace("https://", "wss://"); - this.stream = new ReconnectingWebsocket(`${wsOrigin}/streaming?${query}`, '', { - minReconnectionDelay: 1, // https://github.com/pladaria/reconnecting-websocket/issues/91 - WebSocket: options.WebSocket, - }); - if (options.binaryType) { - this.stream.binaryType = options.binaryType; - } - this.stream.addEventListener('open', this.onOpen); - this.stream.addEventListener('close', this.onClose); - this.stream.addEventListener('message', this.onMessage); - } + this.stream = new ReconnectingWebsocket( + `${wsOrigin}/streaming?${query}`, + "", + { + minReconnectionDelay: 1, // https://github.com/pladaria/reconnecting-websocket/issues/91 + WebSocket: options.WebSocket, + }, + ); + if (options.binaryType) { + this.stream.binaryType = options.binaryType; + } + this.stream.addEventListener("open", this.onOpen); + this.stream.addEventListener("close", this.onClose); + this.stream.addEventListener("message", this.onMessage); + } - private genId(): string { - return (++this.idCounter).toString(); - } + private genId(): string { + return (++this.idCounter).toString(); + } - public useChannel(channel: C, params?: Channels[C]['params'], name?: string): Connection { - if (params) { - return this.connectToChannel(channel, params); - } - return this.useSharedConnection(channel, name); - } + public useChannel( + channel: C, + params?: Channels[C]["params"], + name?: string, + ): Connection { + if (params) { + return this.connectToChannel(channel, params); + } + return this.useSharedConnection(channel, name); + } - private useSharedConnection(channel: C, name?: string): SharedConnection { - let pool = this.sharedConnectionPools.find(p => p.channel === channel); + private useSharedConnection( + channel: C, + name?: string, + ): SharedConnection { + let pool = this.sharedConnectionPools.find((p) => p.channel === channel); - if (pool == null) { - pool = new Pool(this, channel, this.genId()); - this.sharedConnectionPools.push(pool); - } + if (pool == null) { + pool = new Pool(this, channel, this.genId()); + this.sharedConnectionPools.push(pool); + } - const connection = new SharedConnection(this, channel, pool, name); - this.sharedConnections.push(connection as unknown as SharedConnection); - return connection; - } + const connection = new SharedConnection( + this, + channel, + pool, + name, + ); + this.sharedConnections.push(connection as unknown as SharedConnection); + return connection; + } - public removeSharedConnection(connection: SharedConnection): void { - this.sharedConnections = this.sharedConnections.filter(c => c !== connection); - } + public removeSharedConnection(connection: SharedConnection): void { + this.sharedConnections = this.sharedConnections.filter( + (c) => c !== connection, + ); + } - public removeSharedConnectionPool(pool: Pool): void { - this.sharedConnectionPools = this.sharedConnectionPools.filter(p => p !== pool); - } + public removeSharedConnectionPool(pool: Pool): void { + this.sharedConnectionPools = this.sharedConnectionPools.filter( + (p) => p !== pool, + ); + } - private connectToChannel(channel: C, params: Channels[C]['params']): NonSharedConnection { - const connection = new NonSharedConnection(this, channel, this.genId(), params); - this.nonSharedConnections.push(connection as unknown as NonSharedConnection); - return connection; - } + private connectToChannel( + channel: C, + params: Channels[C]["params"], + ): NonSharedConnection { + const connection = new NonSharedConnection( + this, + channel, + this.genId(), + params, + ); + this.nonSharedConnections.push( + connection as unknown as NonSharedConnection, + ); + return connection; + } - public disconnectToChannel(connection: NonSharedConnection): void { - this.nonSharedConnections = this.nonSharedConnections.filter(c => c !== connection); - } + public disconnectToChannel(connection: NonSharedConnection): void { + this.nonSharedConnections = this.nonSharedConnections.filter( + (c) => c !== connection, + ); + } - /** - * Callback of when open connection - */ - private onOpen(): void { - const isReconnect = this.state === 'reconnecting'; + /** + * Callback of when open connection + */ + private onOpen(): void { + const isReconnect = this.state === "reconnecting"; - this.state = 'connected'; - this.emit('_connected_'); + this.state = "connected"; + this.emit("_connected_"); - // チャンネル再接続 - if (isReconnect) { - for (const p of this.sharedConnectionPools) p.connect(); - for (const c of this.nonSharedConnections) c.connect(); - } - } + // チャンネル再接続 + if (isReconnect) { + for (const p of this.sharedConnectionPools) p.connect(); + for (const c of this.nonSharedConnections) c.connect(); + } + } - /** - * Callback of when close connection - */ - private onClose(): void { - if (this.state === 'connected') { - this.state = 'reconnecting'; - this.emit('_disconnected_'); - } - } + /** + * Callback of when close connection + */ + private onClose(): void { + if (this.state === "connected") { + this.state = "reconnecting"; + this.emit("_disconnected_"); + } + } - /** - * Callback of when received a message from connection - */ - private onMessage(message: { data: string; }): void { - const { type, body } = JSON.parse(message.data); + /** + * Callback of when received a message from connection + */ + private onMessage(message: { data: string }): void { + const { type, body } = JSON.parse(message.data); - if (type === 'channel') { - const id = body.id; + if (type === "channel") { + const id = body.id; - let connections: Connection[]; + let connections: Connection[]; - connections = this.sharedConnections.filter(c => c.id === id); + connections = this.sharedConnections.filter((c) => c.id === id); - if (connections.length === 0) { - const found = this.nonSharedConnections.find(c => c.id === id); - if (found) { - connections = [found]; - } - } + if (connections.length === 0) { + const found = this.nonSharedConnections.find((c) => c.id === id); + if (found) { + connections = [found]; + } + } - for (const c of connections) { - c.emit(body.type, body.body); - c.inCount++; - } - } else { - this.emit(type, body); - } - } + for (const c of connections) { + c.emit(body.type, body.body); + c.inCount++; + } + } else { + this.emit(type, body); + } + } - /** - * Send a message to connection - * ! ストリーム上のやり取りはすべてJSONで行われます ! - */ - public send(typeOrPayload: string): void - public send(typeOrPayload: string, payload: unknown): void - public send(typeOrPayload: Record | unknown[]): void - public send(typeOrPayload: string | Record | unknown[], payload?: unknown): void { - if (typeof typeOrPayload === 'string') { - this.stream.send(JSON.stringify({ - type: typeOrPayload, - ...(payload === undefined ? {} : { body: payload }), - })); - return; - } + /** + * Send a message to connection + * ! ストリーム上のやり取りはすべてJSONで行われます ! + */ + public send(typeOrPayload: string): void; + public send(typeOrPayload: string, payload: unknown): void; + public send(typeOrPayload: Record | unknown[]): void; + public send( + typeOrPayload: string | Record | unknown[], + payload?: unknown, + ): void { + if (typeof typeOrPayload === "string") { + this.stream.send( + JSON.stringify({ + type: typeOrPayload, + ...(payload === undefined ? {} : { body: payload }), + }), + ); + return; + } - this.stream.send(JSON.stringify(typeOrPayload)); - } + this.stream.send(JSON.stringify(typeOrPayload)); + } - public ping(): void { - this.stream.send('ping'); - } + public ping(): void { + this.stream.send("ping"); + } - public heartbeat(): void { - this.stream.send('h'); - } + public heartbeat(): void { + this.stream.send("h"); + } - /** - * Close this connection - */ - public close(): void { - this.stream.close(); - } + /** + * Close this connection + */ + public close(): void { + this.stream.close(); + } } // TODO: これらのクラスを Stream クラスの内部クラスにすれば余計なメンバをpublicにしないで済むかも? // もしくは @internal を使う? https://www.typescriptlang.org/tsconfig#stripInternal class Pool { - public channel: string; - public id: string; - protected stream: Stream; - public users = 0; - private disposeTimerId: ReturnType | null = null; - private isConnected = false; + public channel: string; + public id: string; + protected stream: Stream; + public users = 0; + private disposeTimerId: ReturnType | null = null; + private isConnected = false; - constructor(stream: Stream, channel: string, id: string) { - this.onStreamDisconnected = this.onStreamDisconnected.bind(this); - this.inc = this.inc.bind(this); - this.dec = this.dec.bind(this); - this.connect = this.connect.bind(this); - this.disconnect = this.disconnect.bind(this); + constructor(stream: Stream, channel: string, id: string) { + this.onStreamDisconnected = this.onStreamDisconnected.bind(this); + this.inc = this.inc.bind(this); + this.dec = this.dec.bind(this); + this.connect = this.connect.bind(this); + this.disconnect = this.disconnect.bind(this); - this.channel = channel; - this.stream = stream; - this.id = id; + this.channel = channel; + this.stream = stream; + this.id = id; - this.stream.on('_disconnected_', this.onStreamDisconnected); - } + this.stream.on("_disconnected_", this.onStreamDisconnected); + } - private onStreamDisconnected(): void { - this.isConnected = false; - } + private onStreamDisconnected(): void { + this.isConnected = false; + } - public inc(): void { - if (this.users === 0 && !this.isConnected) { - this.connect(); - } + public inc(): void { + if (this.users === 0 && !this.isConnected) { + this.connect(); + } - this.users++; + this.users++; - // タイマー解除 - if (this.disposeTimerId) { - clearTimeout(this.disposeTimerId); - this.disposeTimerId = null; - } - } + // タイマー解除 + if (this.disposeTimerId) { + clearTimeout(this.disposeTimerId); + this.disposeTimerId = null; + } + } - public dec(): void { - this.users--; + public dec(): void { + this.users--; - // そのコネクションの利用者が誰もいなくなったら - if (this.users === 0) { - // また直ぐに再利用される可能性があるので、一定時間待ち、 - // 新たな利用者が現れなければコネクションを切断する - this.disposeTimerId = setTimeout(() => { - this.disconnect(); - }, 3000); - } - } + // そのコネクションの利用者が誰もいなくなったら + if (this.users === 0) { + // また直ぐに再利用される可能性があるので、一定時間待ち、 + // 新たな利用者が現れなければコネクションを切断する + this.disposeTimerId = setTimeout(() => { + this.disconnect(); + }, 3000); + } + } - public connect(): void { - if (this.isConnected) return; - this.isConnected = true; - this.stream.send('connect', { - channel: this.channel, - id: this.id, - }); - } + public connect(): void { + if (this.isConnected) return; + this.isConnected = true; + this.stream.send("connect", { + channel: this.channel, + id: this.id, + }); + } - private disconnect(): void { - this.stream.off('_disconnected_', this.onStreamDisconnected); - this.stream.send('disconnect', { id: this.id }); - this.stream.removeSharedConnectionPool(this); - } + private disconnect(): void { + this.stream.off("_disconnected_", this.onStreamDisconnected); + this.stream.send("disconnect", { id: this.id }); + this.stream.removeSharedConnectionPool(this); + } } -export interface IChannelConnection = AnyOf> extends EventEmitter { - id: string; - name?: string; - inCount: number; - outCount: number; - channel: string; +export interface IChannelConnection< + Channel extends AnyOf = AnyOf, +> extends EventEmitter { + id: string; + name?: string; + inCount: number; + outCount: number; + channel: string; - send(type: T, body: Channel['receives'][T]): void; - dispose(): void; + send( + type: T, + body: Channel["receives"][T], + ): void; + dispose(): void; } -export abstract class Connection = AnyOf> extends EventEmitter implements IChannelConnection { - public channel: string; - protected stream: Stream; - public abstract id: string; +export abstract class Connection< + Channel extends AnyOf = AnyOf, + > + extends EventEmitter + implements IChannelConnection +{ + public channel: string; + protected stream: Stream; + public abstract id: string; - public name?: string; // for debug - public inCount = 0; // for debug - public outCount = 0; // for debug + public name?: string; // for debug + public inCount = 0; // for debug + public outCount = 0; // for debug - constructor(stream: Stream, channel: string, name?: string) { - super(); + constructor(stream: Stream, channel: string, name?: string) { + super(); - this.send = this.send.bind(this); + this.send = this.send.bind(this); - this.stream = stream; - this.channel = channel; - if (name !== undefined) { - this.name = name; - } - } + this.stream = stream; + this.channel = channel; + if (name !== undefined) { + this.name = name; + } + } - public send(type: T, body: Channel['receives'][T]): void { - this.stream.send('ch', { - id: this.id, - type: type, - body: body, - }); + public send( + type: T, + body: Channel["receives"][T], + ): void { + this.stream.send("ch", { + id: this.id, + type: type, + body: body, + }); - this.outCount++; - } + this.outCount++; + } - public abstract dispose(): void; + public abstract dispose(): void; } -class SharedConnection = AnyOf> extends Connection { - private pool: Pool; +class SharedConnection< + Channel extends AnyOf = AnyOf, +> extends Connection { + private pool: Pool; - public get id(): string { - return this.pool.id; - } + public get id(): string { + return this.pool.id; + } - constructor(stream: Stream, channel: string, pool: Pool, name?: string) { - super(stream, channel, name); + constructor(stream: Stream, channel: string, pool: Pool, name?: string) { + super(stream, channel, name); - this.dispose = this.dispose.bind(this); + this.dispose = this.dispose.bind(this); - this.pool = pool; - this.pool.inc(); - } + this.pool = pool; + this.pool.inc(); + } - public dispose(): void { - this.pool.dec(); - this.removeAllListeners(); - this.stream.removeSharedConnection(this as unknown as SharedConnection); - } + public dispose(): void { + this.pool.dec(); + this.removeAllListeners(); + this.stream.removeSharedConnection(this as unknown as SharedConnection); + } } -class NonSharedConnection = AnyOf> extends Connection { - public id: string; - protected params: Channel['params']; +class NonSharedConnection< + Channel extends AnyOf = AnyOf, +> extends Connection { + public id: string; + protected params: Channel["params"]; - constructor(stream: Stream, channel: string, id: string, params: Channel['params']) { - super(stream, channel); + constructor( + stream: Stream, + channel: string, + id: string, + params: Channel["params"], + ) { + super(stream, channel); - this.connect = this.connect.bind(this); - this.dispose = this.dispose.bind(this); + this.connect = this.connect.bind(this); + this.dispose = this.dispose.bind(this); - this.params = params; - this.id = id; + this.params = params; + this.id = id; - this.connect(); - } + this.connect(); + } - public connect(): void { - this.stream.send('connect', { - channel: this.channel, - id: this.id, - params: this.params, - }); - } + public connect(): void { + this.stream.send("connect", { + channel: this.channel, + id: this.id, + params: this.params, + }); + } - public dispose(): void { - this.removeAllListeners(); - this.stream.send('disconnect', { id: this.id }); - this.stream.disconnectToChannel(this as unknown as NonSharedConnection); - } + public dispose(): void { + this.removeAllListeners(); + this.stream.send("disconnect", { id: this.id }); + this.stream.disconnectToChannel(this as unknown as NonSharedConnection); + } } diff --git a/misskey-js/streaming.types.ts b/misskey-js/streaming.types.ts index feb756d..38eade4 100644 --- a/misskey-js/streaming.types.ts +++ b/misskey-js/streaming.types.ts @@ -241,33 +241,33 @@ export type Channels = { export type NoteUpdatedEvent = { id: Note["id"] } & ( | { - type: "reacted"; - body: { - reaction: string; - emoji: string | null; - userId: User["id"]; - }; - } + type: "reacted"; + body: { + reaction: string; + emoji: string | null; + userId: User["id"]; + }; + } | { - type: "unreacted"; - body: { - reaction: string; - userId: User["id"]; - }; - } + type: "unreacted"; + body: { + reaction: string; + userId: User["id"]; + }; + } | { - type: "deleted"; - body: { - deletedAt: string; - }; - } + type: "deleted"; + body: { + deletedAt: string; + }; + } | { - type: "pollVoted"; - body: { - choice: number; - userId: User["id"]; - }; - } + type: "pollVoted"; + body: { + choice: number; + userId: User["id"]; + }; + } ); export type BroadcastEvents = { diff --git a/tsconfig.json b/tsconfig.json index 844f924..0adef2f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,10 +2,7 @@ "extends": "@tsconfig/strictest/tsconfig.json", "compilerOptions": { // Enable latest features - "lib": [ - "ESNext", - "DOM" - ], + "lib": ["ESNext", "DOM"], "target": "ESNext", "module": "ESNext", "moduleDetection": "force", @@ -17,4 +14,4 @@ "verbatimModuleSyntax": true, "noEmit": true } -} \ No newline at end of file +}