feat(dispatcher): made Dispatcher an EventEmitter
this adds a second option for updates dispatching which is not governed by any propagation or stuff. useful for advanced use-cases.
This commit is contained in:
parent
7c3f5cafa6
commit
231b10d8cd
4 changed files with 155 additions and 5 deletions
|
@ -15,6 +15,7 @@
|
|||
"@mtcute/tl": "~1.131.0",
|
||||
"@mtcute/core": "^1.0.0",
|
||||
"@mtcute/client": "^1.0.0",
|
||||
"events": "^3.2.0",
|
||||
"debug": "^4.3.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,8 @@ function toSentence(type, stype = 'inline') {
|
|||
|
||||
if (stype === 'inline') {
|
||||
return `${name[0].match(/[aeiouy]/i) ? 'an' : 'a'} ${name} handler`
|
||||
} else if (stype === 'plain') {
|
||||
return `${name} handler`
|
||||
} else {
|
||||
return `${name[0].toUpperCase()}${name.substr(1)} handler`
|
||||
}
|
||||
|
@ -188,12 +190,23 @@ function generateBuilders() {
|
|||
|
||||
function generateDispatcher() {
|
||||
const lines = []
|
||||
const declareLines = []
|
||||
const imports = ['UpdateHandler']
|
||||
|
||||
types.forEach((type) => {
|
||||
imports.push(`${type.handlerTypeName}Handler`)
|
||||
|
||||
if (type.updateType === 'IGNORE') {
|
||||
declareLines.push(`
|
||||
/**
|
||||
* Register a plain old ${toSentence(type, 'plain')}
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler ${toSentence(type, 'full')}
|
||||
*/
|
||||
on(name: '${type.typeName}', handler: ${type.handlerTypeName}Handler['callback']): this
|
||||
`)
|
||||
|
||||
lines.push(`
|
||||
/**
|
||||
* Register ${toSentence(type)} without any filters
|
||||
|
@ -222,6 +235,16 @@ function generateDispatcher() {
|
|||
}
|
||||
`)
|
||||
} else {
|
||||
declareLines.push(`
|
||||
/**
|
||||
* Register a plain old ${toSentence(type, 'plain')}
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler ${toSentence(type, 'full')}
|
||||
*/
|
||||
on(name: '${type.typeName}', handler: ${type.handlerTypeName}Handler['callback']): this
|
||||
|
||||
`)
|
||||
lines.push(`
|
||||
/**
|
||||
* Register ${toSentence(type)} without any filters
|
||||
|
@ -269,6 +292,7 @@ ${type.state ? `
|
|||
|
||||
replaceSections('dispatcher.ts', {
|
||||
codegen: lines.join('\n'),
|
||||
'codegen-declare': declareLines.join('\n'),
|
||||
'codegen-imports':
|
||||
'import {\n' +
|
||||
imports.map((i) => ` ${i},\n`).join('') +
|
||||
|
|
|
@ -40,6 +40,7 @@ import { DeleteMessageUpdate } from './updates/delete-message-update'
|
|||
import { IStateStorage, UpdateState, StateKeyDelegate } from './state'
|
||||
import { defaultStateKeyDelegate } from './state'
|
||||
import { PropagationAction } from './propagation'
|
||||
import EventEmitter from 'events'
|
||||
|
||||
const noop = () => {}
|
||||
|
||||
|
@ -136,10 +137,126 @@ Object.keys(PARSERS).forEach((upd: keyof typeof PARSERS) => {
|
|||
HANDLER_TYPE_TO_UPDATE[handler].push(upd)
|
||||
})
|
||||
|
||||
export declare interface Dispatcher<
|
||||
State = never,
|
||||
SceneName extends string = string
|
||||
> {
|
||||
on<T = {}>(
|
||||
name: 'update',
|
||||
handler: (update: UpdateInfo<UpdateHandler> & T) => void
|
||||
): this
|
||||
|
||||
// begin-codegen-declare
|
||||
|
||||
/**
|
||||
* Register a plain old raw update handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler Raw update handler
|
||||
*/
|
||||
on(name: 'raw', handler: RawUpdateHandler['callback']): this
|
||||
|
||||
/**
|
||||
* Register a plain old new message handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler New message handler
|
||||
*/
|
||||
on(name: 'new_message', handler: NewMessageHandler['callback']): this
|
||||
|
||||
/**
|
||||
* Register a plain old edit message handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler Edit message handler
|
||||
*/
|
||||
on(name: 'edit_message', handler: EditMessageHandler['callback']): this
|
||||
|
||||
/**
|
||||
* Register a plain old delete message handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler Delete message handler
|
||||
*/
|
||||
on(name: 'delete_message', handler: DeleteMessageHandler['callback']): this
|
||||
|
||||
/**
|
||||
* Register a plain old chat member update handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler Chat member update handler
|
||||
*/
|
||||
on(name: 'chat_member', handler: ChatMemberUpdateHandler['callback']): this
|
||||
|
||||
/**
|
||||
* Register a plain old inline query handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler Inline query handler
|
||||
*/
|
||||
on(name: 'inline_query', handler: InlineQueryHandler['callback']): this
|
||||
|
||||
/**
|
||||
* Register a plain old chosen inline result handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler Chosen inline result handler
|
||||
*/
|
||||
on(
|
||||
name: 'chosen_inline_result',
|
||||
handler: ChosenInlineResultHandler['callback']
|
||||
): this
|
||||
|
||||
/**
|
||||
* Register a plain old callback query handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler Callback query handler
|
||||
*/
|
||||
on(name: 'callback_query', handler: CallbackQueryHandler['callback']): this
|
||||
|
||||
/**
|
||||
* Register a plain old poll update handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler Poll update handler
|
||||
*/
|
||||
on(name: 'poll', handler: PollUpdateHandler['callback']): this
|
||||
|
||||
/**
|
||||
* Register a plain old poll vote handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler Poll vote handler
|
||||
*/
|
||||
on(name: 'poll_vote', handler: PollVoteHandler['callback']): this
|
||||
|
||||
/**
|
||||
* Register a plain old user status update handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler User status update handler
|
||||
*/
|
||||
on(name: 'user_status', handler: UserStatusUpdateHandler['callback']): this
|
||||
|
||||
/**
|
||||
* Register a plain old user typing handler
|
||||
*
|
||||
* @param name Event name
|
||||
* @param handler User typing handler
|
||||
*/
|
||||
on(name: 'user_typing', handler: UserTypingHandler['callback']): this
|
||||
|
||||
// end-codegen-declare
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates dispatcher
|
||||
*/
|
||||
export class Dispatcher<State = never, SceneName extends string = string> {
|
||||
export class Dispatcher<
|
||||
State = never,
|
||||
SceneName extends string = string
|
||||
> extends EventEmitter {
|
||||
private _groups: Record<
|
||||
number,
|
||||
Record<UpdateHandler['type'], UpdateHandler[]>
|
||||
|
@ -205,6 +322,8 @@ export class Dispatcher<State = never, SceneName extends string = string> {
|
|||
storage?: IStateStorage | StateKeyDelegate,
|
||||
key?: StateKeyDelegate
|
||||
) {
|
||||
super()
|
||||
|
||||
if (client) {
|
||||
if (client instanceof TelegramClient) {
|
||||
this.bindToClient(client)
|
||||
|
@ -421,6 +540,15 @@ export class Dispatcher<State = never, SceneName extends string = string> {
|
|||
}
|
||||
|
||||
if (shouldDispatch) {
|
||||
if (update && !isRawMessage) {
|
||||
this.emit('raw', update, users, chats)
|
||||
}
|
||||
|
||||
if (parsedType) {
|
||||
this.emit('update', updateInfo)
|
||||
this.emit(parsedType, parsed)
|
||||
}
|
||||
|
||||
outer: for (const grp of this._groupsOrder) {
|
||||
const group = this._groups[grp]
|
||||
|
||||
|
|
|
@ -30,10 +30,7 @@ type ParsedUpdateHandler<Type, Update, State = never> = BaseUpdateHandler<
|
|||
(update: Update, state: State) => MaybeAsync<boolean>
|
||||
>
|
||||
|
||||
export type UpdateInfo<T> = T extends ParsedUpdateHandler<
|
||||
infer K,
|
||||
infer Q
|
||||
>
|
||||
export type UpdateInfo<T> = T extends ParsedUpdateHandler<infer K, infer Q>
|
||||
? {
|
||||
readonly type: K
|
||||
readonly data: Q
|
||||
|
|
Loading…
Reference in a new issue