@mtcute/dispatcher 0.12.4 → 0.13.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/callback-data-builder.d.ts +2 -2
- package/cjs/callback-data-builder.js.map +1 -1
- package/cjs/context/parse.d.ts +2 -2
- package/cjs/context/parse.js +2 -0
- package/cjs/context/parse.js.map +1 -1
- package/cjs/context/scene-transition.d.ts +24 -0
- package/cjs/context/scene-transition.js +52 -0
- package/cjs/context/scene-transition.js.map +1 -0
- package/cjs/dispatcher.d.ts +46 -1
- package/cjs/dispatcher.js +67 -10
- package/cjs/dispatcher.js.map +1 -1
- package/cjs/propagation.d.ts +2 -1
- package/cjs/propagation.js +2 -1
- package/cjs/propagation.js.map +1 -1
- package/esm/callback-data-builder.d.ts +2 -2
- package/esm/callback-data-builder.js.map +1 -1
- package/esm/context/parse.d.ts +2 -2
- package/esm/context/parse.js +3 -1
- package/esm/context/parse.js.map +1 -1
- package/esm/context/scene-transition.d.ts +24 -0
- package/esm/context/scene-transition.js +48 -0
- package/esm/context/scene-transition.js.map +1 -0
- package/esm/dispatcher.d.ts +46 -1
- package/esm/dispatcher.js +67 -10
- package/esm/dispatcher.js.map +1 -1
- package/esm/propagation.d.ts +2 -1
- package/esm/propagation.js +2 -1
- package/esm/propagation.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CallbackQuery, MaybeArray, MaybePromise } from '@mtcute/core';
|
|
1
|
+
import { CallbackQuery, InlineCallbackQuery, MaybeArray, MaybePromise } from '@mtcute/core';
|
|
2
2
|
import { UpdateFilter } from './filters/types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Callback data builder, inspired by [aiogram](https://github.com/aiogram/aiogram).
|
|
@@ -43,7 +43,7 @@ export declare class CallbackDataBuilder<T extends string> {
|
|
|
43
43
|
*
|
|
44
44
|
* @param params
|
|
45
45
|
*/
|
|
46
|
-
filter(params?: ((upd:
|
|
46
|
+
filter<Update extends CallbackQuery | InlineCallbackQuery>(params?: ((upd: Update, parsed: Record<T, string>) => MaybePromise<Partial<Record<T, MaybeArray<string | RegExp>>> | boolean>) | Partial<Record<T, MaybeArray<string | RegExp>>>): UpdateFilter<Update, {
|
|
47
47
|
match: Record<T, string>;
|
|
48
48
|
}>;
|
|
49
49
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"callback-data-builder.js","sourceRoot":"","sources":["../../src/callback-data-builder.ts"],"names":[],"mappings":"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","sourcesContent":["import { CallbackQuery, MaybeArray, MaybePromise, MtArgumentError } from '@mtcute/core'\n\nimport { UpdateFilter } from './filters/types.js'\n\n/**\n * Callback data builder, inspired by [aiogram](https://github.com/aiogram/aiogram).\n *\n * This can be used to simplify management of different callbacks.\n *\n * [Learn more in the docs](/guide/topics/keyboards.html#callback-data-builders)\n */\nexport class CallbackDataBuilder<T extends string> {\n private readonly _fields: T[]\n\n sep = ':'\n\n /**\n * @param prefix Prefix for the data. Use something unique across your bot.\n * @param fields Field names in the order they will be serialized.\n */\n constructor(\n public prefix: string,\n ...fields: T[]\n ) {\n this._fields = fields\n }\n\n /**\n * Build a callback data string\n *\n * @param obj Object containing the data\n */\n build(obj: Record<T, string>): string {\n const ret =\n this.prefix +\n this.sep +\n this._fields\n .map((f) => {\n const val = obj[f]\n\n if (val.includes(this.sep)) {\n throw new MtArgumentError(\n `Value for ${f} ${val} contains separator ${this.sep} and cannot be used.`,\n )\n }\n\n return val\n })\n .join(this.sep)\n\n if (ret.length > 64) {\n throw new MtArgumentError('Resulting callback data is too long.')\n }\n\n return ret\n }\n\n /**\n * Parse callback data to object\n *\n * @param data Callback data as string\n * @param safe If `true`, will return `null` instead of throwing on invalid data\n */\n parse(data: string, safe?: false): Record<T, string>\n parse(data: string, safe: true): Record<T, string> | null\n parse(data: string, safe = false): Record<T, string> | null {\n const parts = data.split(this.sep)\n\n if (parts[0] !== this.prefix) {\n if (safe) return null\n throw new MtArgumentError(\n `Invalid data passed: \"${data}\" (bad prefix, expected ${this.prefix}, got ${parts[0]})`,\n )\n }\n\n if (parts.length !== this._fields.length + 1) {\n if (safe) return null\n throw new MtArgumentError(\n `Invalid data passed: \"${data}\" (bad parts count, expected ${this._fields.length}, got ${\n parts.length - 1\n })`,\n )\n }\n\n const ret = {} as Record<T, string>\n parts.forEach((it, idx) => {\n if (idx === 0) return // skip prefix\n\n ret[this._fields[idx - 1]] = it\n })\n\n return ret\n }\n\n /**\n * Create a filter for this callback data.\n *\n * You can either pass an object with field names as keys and values as strings or regexes,\n * which will be compiled to a RegExp, or a function that will be called with the parsed data.\n * Note that the strings will be passed to `RegExp` **directly**, so you may want to escape them.\n *\n * When using a function, you can either return a boolean, or an object with field names as keys\n * and values as strings or regexes. In the latter case, the resulting object will be matched\n * against the parsed data the same way as if you passed it directly.\n *\n * @param params\n */\n filter(\n params:\n | ((\n upd: CallbackQuery,\n parsed: Record<T, string>,\n ) => MaybePromise<Partial<Record<T, MaybeArray<string | RegExp>>> | boolean>)\n | Partial<Record<T, MaybeArray<string | RegExp>>> = {},\n ): UpdateFilter<\n CallbackQuery,\n {\n match: Record<T, string>\n }\n > {\n if (typeof params === 'function') {\n return async (query) => {\n if (!query.dataStr) return false\n\n const data = this.parse(query.dataStr, true)\n if (!data) return false\n\n const fnResult = await params(query, data)\n\n if (typeof fnResult === 'boolean') {\n (\n query as CallbackQuery & {\n match: Record<T, string>\n }\n ).match = data\n\n return fnResult\n }\n\n // validate result\n for (const key in fnResult) {\n const value = data[key]\n if (value === undefined) return false\n\n let matchers = fnResult[key] as MaybeArray<string | RegExp>\n if (!Array.isArray(matchers)) matchers = [matchers]\n\n for (const matcher of matchers) {\n if (typeof matcher === 'string') {\n if (value !== matcher) return false\n } else if (!matcher.test(value)) return false\n }\n }\n\n (\n query as CallbackQuery & {\n match: Record<T, string>\n }\n ).match = data\n\n return true\n }\n }\n\n const parts: string[] = []\n\n this._fields.forEach((field) => {\n if (!(field in params)) {\n parts.push(`[^${this.sep}]*?`)\n\n return\n }\n\n const value = params[field]\n\n if (Array.isArray(value)) {\n parts.push(`(${value.map((i) => (typeof i === 'string' ? i : i.source)).join('|')})`)\n } else {\n // noinspection SuspiciousTypeOfGuard\n parts.push(typeof value === 'string' ? value : (value as RegExp).source)\n }\n })\n\n const regex = new RegExp(`^${this.prefix}${this.sep}${parts.join(this.sep)}$`)\n\n return (query) => {\n const m = query.dataStr?.match(regex)\n if (!m) return false\n ;(\n query as CallbackQuery & {\n match: Record<T, string>\n }\n ).match = this.parse(m[0])\n\n return true\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"callback-data-builder.js","sourceRoot":"","sources":["../../src/callback-data-builder.ts"],"names":[],"mappings":"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","sourcesContent":["import { CallbackQuery, InlineCallbackQuery, MaybeArray, MaybePromise, MtArgumentError } from '@mtcute/core'\n\nimport { UpdateFilter } from './filters/types.js'\n\n/**\n * Callback data builder, inspired by [aiogram](https://github.com/aiogram/aiogram).\n *\n * This can be used to simplify management of different callbacks.\n *\n * [Learn more in the docs](/guide/topics/keyboards.html#callback-data-builders)\n */\nexport class CallbackDataBuilder<T extends string> {\n private readonly _fields: T[]\n\n sep = ':'\n\n /**\n * @param prefix Prefix for the data. Use something unique across your bot.\n * @param fields Field names in the order they will be serialized.\n */\n constructor(\n public prefix: string,\n ...fields: T[]\n ) {\n this._fields = fields\n }\n\n /**\n * Build a callback data string\n *\n * @param obj Object containing the data\n */\n build(obj: Record<T, string>): string {\n const ret =\n this.prefix +\n this.sep +\n this._fields\n .map((f) => {\n const val = obj[f]\n\n if (val.includes(this.sep)) {\n throw new MtArgumentError(\n `Value for ${f} ${val} contains separator ${this.sep} and cannot be used.`,\n )\n }\n\n return val\n })\n .join(this.sep)\n\n if (ret.length > 64) {\n throw new MtArgumentError('Resulting callback data is too long.')\n }\n\n return ret\n }\n\n /**\n * Parse callback data to object\n *\n * @param data Callback data as string\n * @param safe If `true`, will return `null` instead of throwing on invalid data\n */\n parse(data: string, safe?: false): Record<T, string>\n parse(data: string, safe: true): Record<T, string> | null\n parse(data: string, safe = false): Record<T, string> | null {\n const parts = data.split(this.sep)\n\n if (parts[0] !== this.prefix) {\n if (safe) return null\n throw new MtArgumentError(\n `Invalid data passed: \"${data}\" (bad prefix, expected ${this.prefix}, got ${parts[0]})`,\n )\n }\n\n if (parts.length !== this._fields.length + 1) {\n if (safe) return null\n throw new MtArgumentError(\n `Invalid data passed: \"${data}\" (bad parts count, expected ${this._fields.length}, got ${\n parts.length - 1\n })`,\n )\n }\n\n const ret = {} as Record<T, string>\n parts.forEach((it, idx) => {\n if (idx === 0) return // skip prefix\n\n ret[this._fields[idx - 1]] = it\n })\n\n return ret\n }\n\n /**\n * Create a filter for this callback data.\n *\n * You can either pass an object with field names as keys and values as strings or regexes,\n * which will be compiled to a RegExp, or a function that will be called with the parsed data.\n * Note that the strings will be passed to `RegExp` **directly**, so you may want to escape them.\n *\n * When using a function, you can either return a boolean, or an object with field names as keys\n * and values as strings or regexes. In the latter case, the resulting object will be matched\n * against the parsed data the same way as if you passed it directly.\n *\n * @param params\n */\n filter<Update extends CallbackQuery | InlineCallbackQuery>(\n params:\n | ((\n upd: Update,\n parsed: Record<T, string>,\n ) => MaybePromise<Partial<Record<T, MaybeArray<string | RegExp>>> | boolean>)\n | Partial<Record<T, MaybeArray<string | RegExp>>> = {},\n ): UpdateFilter<\n Update,\n {\n match: Record<T, string>\n }\n > {\n if (typeof params === 'function') {\n return async (query) => {\n if (!query.dataStr) return false\n\n const data = this.parse(query.dataStr, true)\n if (!data) return false\n\n const fnResult = await params(query, data)\n\n if (typeof fnResult === 'boolean') {\n (\n query as Update & {\n match: Record<T, string>\n }\n ).match = data\n\n return fnResult\n }\n\n // validate result\n for (const key in fnResult) {\n const value = data[key]\n if (value === undefined) return false\n\n let matchers = fnResult[key] as MaybeArray<string | RegExp>\n if (!Array.isArray(matchers)) matchers = [matchers]\n\n for (const matcher of matchers) {\n if (typeof matcher === 'string') {\n if (value !== matcher) return false\n } else if (!matcher.test(value)) return false\n }\n }\n\n (\n query as Update & {\n match: Record<T, string>\n }\n ).match = data\n\n return true\n }\n }\n\n const parts: string[] = []\n\n this._fields.forEach((field) => {\n if (!(field in params)) {\n parts.push(`[^${this.sep}]*?`)\n\n return\n }\n\n const value = params[field]\n\n if (Array.isArray(value)) {\n parts.push(`(${value.map((i) => (typeof i === 'string' ? i : i.source)).join('|')})`)\n } else {\n // noinspection SuspiciousTypeOfGuard\n parts.push(typeof value === 'string' ? value : (value as RegExp).source)\n }\n })\n\n const regex = new RegExp(`^${this.prefix}${this.sep}${parts.join(this.sep)}$`)\n\n return (query) => {\n const m = query.dataStr?.match(regex)\n if (!m) return false\n ;(\n query as Update & {\n match: Record<T, string>\n }\n ).match = this.parse(m[0])\n\n return true\n }\n }\n}\n"]}
|
package/cjs/context/parse.d.ts
CHANGED
|
@@ -2,12 +2,12 @@ import { ParsedUpdate } from '@mtcute/core';
|
|
|
2
2
|
import { TelegramClient } from '@mtcute/core/client.js';
|
|
3
3
|
import { UpdateContextDistributed } from './base.js';
|
|
4
4
|
import { BusinessMessageContext } from './business-message.js';
|
|
5
|
-
import { CallbackQueryContext } from './callback-query.js';
|
|
5
|
+
import { CallbackQueryContext, InlineCallbackQueryContext } from './callback-query.js';
|
|
6
6
|
import { ChatJoinRequestUpdateContext } from './chat-join-request.js';
|
|
7
7
|
import { ChosenInlineResultContext } from './chosen-inline-result.js';
|
|
8
8
|
import { InlineQueryContext } from './inline-query.js';
|
|
9
9
|
import { MessageContext } from './message.js';
|
|
10
10
|
import { PreCheckoutQueryContext } from './pre-checkout-query.js';
|
|
11
11
|
/** @internal */
|
|
12
|
-
export declare function _parsedUpdateToContext(client: TelegramClient, update: ParsedUpdate): BusinessMessageContext | CallbackQueryContext | ChatJoinRequestUpdateContext | ChosenInlineResultContext | InlineQueryContext | MessageContext | PreCheckoutQueryContext | UpdateContextDistributed<import("@mtcute/core").DeleteMessageUpdate | import("@mtcute/core").ChatMemberUpdate | import("@mtcute/core").
|
|
12
|
+
export declare function _parsedUpdateToContext(client: TelegramClient, update: ParsedUpdate): BusinessMessageContext | CallbackQueryContext | InlineCallbackQueryContext | ChatJoinRequestUpdateContext | ChosenInlineResultContext | InlineQueryContext | MessageContext | PreCheckoutQueryContext | UpdateContextDistributed<import("@mtcute/core").DeleteMessageUpdate | import("@mtcute/core").ChatMemberUpdate | import("@mtcute/core").PollUpdate | import("@mtcute/core").PollVoteUpdate | import("@mtcute/core").UserStatusUpdate | import("@mtcute/core").UserTypingUpdate | import("@mtcute/core").HistoryReadUpdate | import("@mtcute/core").BotStoppedUpdate | import("@mtcute/core").ChatJoinRequestUpdate | import("@mtcute/core").StoryUpdate | import("@mtcute/core").DeleteStoryUpdate | import("@mtcute/core").BotReactionUpdate | import("@mtcute/core").BotReactionCountUpdate | import("@mtcute/core").BusinessConnection | import("@mtcute/core").DeleteBusinessMessageUpdate>;
|
|
13
13
|
export type UpdateContextType = ReturnType<typeof _parsedUpdateToContext>;
|
package/cjs/context/parse.js
CHANGED
|
@@ -21,6 +21,8 @@ function _parsedUpdateToContext(client, update) {
|
|
|
21
21
|
return new chosen_inline_result_js_1.ChosenInlineResultContext(client, update.data);
|
|
22
22
|
case 'callback_query':
|
|
23
23
|
return new callback_query_js_1.CallbackQueryContext(client, update.data);
|
|
24
|
+
case 'inline_callback_query':
|
|
25
|
+
return new callback_query_js_1.InlineCallbackQueryContext(client, update.data);
|
|
24
26
|
case 'bot_chat_join_request':
|
|
25
27
|
return new chat_join_request_js_1.ChatJoinRequestUpdateContext(client, update.data);
|
|
26
28
|
case 'pre_checkout_query':
|
package/cjs/context/parse.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/context/parse.ts"],"names":[],"mappings":";;;AAIA,+DAA8D;AAC9D,
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../src/context/parse.ts"],"names":[],"mappings":";;;AAIA,+DAA8D;AAC9D,2DAAsF;AACtF,iEAAqE;AACrE,uEAAqE;AACrE,uDAAsD;AACtD,6CAA6C;AAC7C,mEAAiE;AAEjE,gBAAgB;AAChB,SAAgB,sBAAsB,CAAC,MAAsB,EAAE,MAAoB;IAC/E,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,aAAa,CAAC;QACnB,KAAK,cAAc,CAAC;QACpB,KAAK,eAAe;YAChB,OAAO,IAAI,2BAAc,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QAClD,KAAK,cAAc;YACf,OAAO,IAAI,oCAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QACtD,KAAK,sBAAsB;YACvB,OAAO,IAAI,mDAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QAC7D,KAAK,gBAAgB;YACjB,OAAO,IAAI,wCAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QACxD,KAAK,uBAAuB;YACxB,OAAO,IAAI,8CAA0B,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QAC9D,KAAK,uBAAuB;YACxB,OAAO,IAAI,mDAA4B,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QAChE,KAAK,oBAAoB;YACrB,OAAO,IAAI,+CAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QAC3D,KAAK,sBAAsB,CAAC;QAC5B,KAAK,uBAAuB,CAAC;QAC7B,KAAK,wBAAwB;YACzB,OAAO,IAAI,4CAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;IAC9D,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAoD,CAAA;IAC3E,OAAO,CAAC,MAAM,GAAG,MAAM,CAAA;IACvB,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC,IAAI,CAAA;IAE3B,OAAO,OAAO,CAAA;AAClB,CAAC;AA7BD,wDA6BC","sourcesContent":["import { ParsedUpdate } from '@mtcute/core'\nimport { TelegramClient } from '@mtcute/core/client.js'\n\nimport { UpdateContextDistributed } from './base.js'\nimport { BusinessMessageContext } from './business-message.js'\nimport { CallbackQueryContext, InlineCallbackQueryContext } from './callback-query.js'\nimport { ChatJoinRequestUpdateContext } from './chat-join-request.js'\nimport { ChosenInlineResultContext } from './chosen-inline-result.js'\nimport { InlineQueryContext } from './inline-query.js'\nimport { MessageContext } from './message.js'\nimport { PreCheckoutQueryContext } from './pre-checkout-query.js'\n\n/** @internal */\nexport function _parsedUpdateToContext(client: TelegramClient, update: ParsedUpdate) {\n switch (update.name) {\n case 'new_message':\n case 'edit_message':\n case 'message_group':\n return new MessageContext(client, update.data)\n case 'inline_query':\n return new InlineQueryContext(client, update.data)\n case 'chosen_inline_result':\n return new ChosenInlineResultContext(client, update.data)\n case 'callback_query':\n return new CallbackQueryContext(client, update.data)\n case 'inline_callback_query':\n return new InlineCallbackQueryContext(client, update.data)\n case 'bot_chat_join_request':\n return new ChatJoinRequestUpdateContext(client, update.data)\n case 'pre_checkout_query':\n return new PreCheckoutQueryContext(client, update.data)\n case 'new_business_message':\n case 'edit_business_message':\n case 'business_message_group':\n return new BusinessMessageContext(client, update.data)\n }\n\n const _update = update.data as UpdateContextDistributed<typeof update.data>\n _update.client = client\n _update._name = update.name\n\n return _update\n}\n\nexport type UpdateContextType = ReturnType<typeof _parsedUpdateToContext>\n"]}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BusinessMessageContext } from './business-message.js';
|
|
2
|
+
import { CallbackQueryContext, InlineCallbackQueryContext } from './callback-query.js';
|
|
3
|
+
import { MessageContext } from './message.js';
|
|
4
|
+
import { UpdateContextType } from './parse.js';
|
|
5
|
+
/** Update which is dispatched whenever scene is entered or exited */
|
|
6
|
+
export declare class SceneTransitionContext {
|
|
7
|
+
/** Name of the previous scene, if any */
|
|
8
|
+
readonly previousScene: string | null;
|
|
9
|
+
/** Update, handler for which triggered the transition */
|
|
10
|
+
readonly update: UpdateContextType;
|
|
11
|
+
constructor(
|
|
12
|
+
/** Name of the previous scene, if any */
|
|
13
|
+
previousScene: string | null,
|
|
14
|
+
/** Update, handler for which triggered the transition */
|
|
15
|
+
update: UpdateContextType);
|
|
16
|
+
/** Get {@link update}, asserting it is a message-related update */
|
|
17
|
+
get message(): MessageContext;
|
|
18
|
+
/** Get {@link update}, asserting it is a business message-related update */
|
|
19
|
+
get businessMessage(): BusinessMessageContext;
|
|
20
|
+
/** Get {@link update}, asserting it is a callback query update */
|
|
21
|
+
get callbackQuery(): CallbackQueryContext;
|
|
22
|
+
/** Get {@link update}, asserting it is an inline callback query update */
|
|
23
|
+
get inlineCallbackQuery(): InlineCallbackQueryContext;
|
|
24
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SceneTransitionContext = void 0;
|
|
4
|
+
const core_1 = require("@mtcute/core");
|
|
5
|
+
const utils_js_1 = require("@mtcute/core/utils.js");
|
|
6
|
+
const business_message_js_1 = require("./business-message.js");
|
|
7
|
+
const callback_query_js_1 = require("./callback-query.js");
|
|
8
|
+
const message_js_1 = require("./message.js");
|
|
9
|
+
/** Update which is dispatched whenever scene is entered or exited */
|
|
10
|
+
class SceneTransitionContext {
|
|
11
|
+
previousScene;
|
|
12
|
+
update;
|
|
13
|
+
constructor(
|
|
14
|
+
/** Name of the previous scene, if any */
|
|
15
|
+
previousScene,
|
|
16
|
+
/** Update, handler for which triggered the transition */
|
|
17
|
+
update) {
|
|
18
|
+
this.previousScene = previousScene;
|
|
19
|
+
this.update = update;
|
|
20
|
+
}
|
|
21
|
+
/** Get {@link update}, asserting it is a message-related update */
|
|
22
|
+
get message() {
|
|
23
|
+
if (this.update instanceof message_js_1.MessageContext) {
|
|
24
|
+
return this.update;
|
|
25
|
+
}
|
|
26
|
+
throw new core_1.MtTypeAssertionError('SceneTransitionContext.message', 'message', this.update._name);
|
|
27
|
+
}
|
|
28
|
+
/** Get {@link update}, asserting it is a business message-related update */
|
|
29
|
+
get businessMessage() {
|
|
30
|
+
if (this.update instanceof business_message_js_1.BusinessMessageContext) {
|
|
31
|
+
return this.update;
|
|
32
|
+
}
|
|
33
|
+
throw new core_1.MtTypeAssertionError('SceneTransitionContext.businessMessage', 'business message', this.update._name);
|
|
34
|
+
}
|
|
35
|
+
/** Get {@link update}, asserting it is a callback query update */
|
|
36
|
+
get callbackQuery() {
|
|
37
|
+
if (this.update instanceof callback_query_js_1.CallbackQueryContext) {
|
|
38
|
+
return this.update;
|
|
39
|
+
}
|
|
40
|
+
throw new core_1.MtTypeAssertionError('SceneTransitionContext.callbackQuery', 'callback query', this.update._name);
|
|
41
|
+
}
|
|
42
|
+
/** Get {@link update}, asserting it is an inline callback query update */
|
|
43
|
+
get inlineCallbackQuery() {
|
|
44
|
+
if (this.update instanceof callback_query_js_1.InlineCallbackQueryContext) {
|
|
45
|
+
return this.update;
|
|
46
|
+
}
|
|
47
|
+
throw new core_1.MtTypeAssertionError('SceneTransitionContext.inlineCallbackQuery', 'inline callback query', this.update._name);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.SceneTransitionContext = SceneTransitionContext;
|
|
51
|
+
(0, utils_js_1.makeInspectable)(SceneTransitionContext);
|
|
52
|
+
//# sourceMappingURL=scene-transition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-transition.js","sourceRoot":"","sources":["../../../src/context/scene-transition.ts"],"names":[],"mappings":";;;AAAA,uCAAmD;AACnD,oDAAuD;AAEvD,+DAA8D;AAC9D,2DAAsF;AACtF,6CAA6C;AAG7C,qEAAqE;AACrE,MAAa,sBAAsB;IAGlB;IAEA;IAJb;IACI,yCAAyC;IAChC,aAA4B;IACrC,yDAAyD;IAChD,MAAyB;QAFzB,kBAAa,GAAb,aAAa,CAAe;QAE5B,WAAM,GAAN,MAAM,CAAmB;IACnC,CAAC;IAEJ,mEAAmE;IACnE,IAAI,OAAO;QACP,IAAI,IAAI,CAAC,MAAM,YAAY,2BAAc,EAAE,CAAC;YACxC,OAAO,IAAI,CAAC,MAAM,CAAA;QACtB,CAAC;QAED,MAAM,IAAI,2BAAoB,CAAC,gCAAgC,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAClG,CAAC;IAED,4EAA4E;IAC5E,IAAI,eAAe;QACf,IAAI,IAAI,CAAC,MAAM,YAAY,4CAAsB,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC,MAAM,CAAA;QACtB,CAAC;QAED,MAAM,IAAI,2BAAoB,CAAC,wCAAwC,EAAE,kBAAkB,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACnH,CAAC;IAED,kEAAkE;IAClE,IAAI,aAAa;QACb,IAAI,IAAI,CAAC,MAAM,YAAY,wCAAoB,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC,MAAM,CAAA;QACtB,CAAC;QAED,MAAM,IAAI,2BAAoB,CAAC,sCAAsC,EAAE,gBAAgB,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC/G,CAAC;IAED,0EAA0E;IAC1E,IAAI,mBAAmB;QACnB,IAAI,IAAI,CAAC,MAAM,YAAY,8CAA0B,EAAE,CAAC;YACpD,OAAO,IAAI,CAAC,MAAM,CAAA;QACtB,CAAC;QAED,MAAM,IAAI,2BAAoB,CAC1B,4CAA4C,EAC5C,uBAAuB,EACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CACpB,CAAA;IACL,CAAC;CACJ;AA/CD,wDA+CC;AAED,IAAA,0BAAe,EAAC,sBAAsB,CAAC,CAAA","sourcesContent":["import { MtTypeAssertionError } from '@mtcute/core'\nimport { makeInspectable } from '@mtcute/core/utils.js'\n\nimport { BusinessMessageContext } from './business-message.js'\nimport { CallbackQueryContext, InlineCallbackQueryContext } from './callback-query.js'\nimport { MessageContext } from './message.js'\nimport { UpdateContextType } from './parse.js'\n\n/** Update which is dispatched whenever scene is entered or exited */\nexport class SceneTransitionContext {\n constructor(\n /** Name of the previous scene, if any */\n readonly previousScene: string | null,\n /** Update, handler for which triggered the transition */\n readonly update: UpdateContextType,\n ) {}\n\n /** Get {@link update}, asserting it is a message-related update */\n get message(): MessageContext {\n if (this.update instanceof MessageContext) {\n return this.update\n }\n\n throw new MtTypeAssertionError('SceneTransitionContext.message', 'message', this.update._name)\n }\n\n /** Get {@link update}, asserting it is a business message-related update */\n get businessMessage(): BusinessMessageContext {\n if (this.update instanceof BusinessMessageContext) {\n return this.update\n }\n\n throw new MtTypeAssertionError('SceneTransitionContext.businessMessage', 'business message', this.update._name)\n }\n\n /** Get {@link update}, asserting it is a callback query update */\n get callbackQuery(): CallbackQueryContext {\n if (this.update instanceof CallbackQueryContext) {\n return this.update\n }\n\n throw new MtTypeAssertionError('SceneTransitionContext.callbackQuery', 'callback query', this.update._name)\n }\n\n /** Get {@link update}, asserting it is an inline callback query update */\n get inlineCallbackQuery(): InlineCallbackQueryContext {\n if (this.update instanceof InlineCallbackQueryContext) {\n return this.update\n }\n\n throw new MtTypeAssertionError(\n 'SceneTransitionContext.inlineCallbackQuery',\n 'inline callback query',\n this.update._name,\n )\n }\n}\n\nmakeInspectable(SceneTransitionContext)\n"]}
|
package/cjs/dispatcher.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { TelegramClient } from '@mtcute/core/client.js';
|
|
|
3
3
|
import { UpdateContext } from './context/base.js';
|
|
4
4
|
import { BusinessMessageContext } from './context/business-message.js';
|
|
5
5
|
import { CallbackQueryContext, ChatJoinRequestUpdateContext, ChosenInlineResultContext, InlineCallbackQueryContext, InlineQueryContext, MessageContext, PreCheckoutQueryContext } from './context/index.js';
|
|
6
|
+
import { SceneTransitionContext } from './context/scene-transition.js';
|
|
6
7
|
import { filters, UpdateFilter } from './filters/index.js';
|
|
7
8
|
import { BotChatJoinRequestHandler, BotReactionCountUpdateHandler, BotReactionUpdateHandler, BotStoppedHandler, BusinessConnectionUpdateHandler, BusinessMessageGroupHandler, CallbackQueryHandler, ChatJoinRequestHandler, ChatMemberUpdateHandler, ChosenInlineResultHandler, DeleteBusinessMessageHandler, DeleteMessageHandler, DeleteStoryHandler, EditBusinessMessageHandler, EditMessageHandler, HistoryReadHandler, InlineCallbackQueryHandler, InlineQueryHandler, MessageGroupHandler, NewBusinessMessageHandler, NewMessageHandler, PollUpdateHandler, PollVoteHandler, PreCheckoutQueryHandler, RawUpdateHandler, StoryUpdateHandler, UpdateHandler, UserStatusUpdateHandler, UserTypingHandler } from './handler.js';
|
|
8
9
|
import { PropagationAction } from './propagation.js';
|
|
@@ -47,11 +48,14 @@ export declare class Dispatcher<State extends object = never> {
|
|
|
47
48
|
private _errorHandler?;
|
|
48
49
|
private _preUpdateHandler?;
|
|
49
50
|
private _postUpdateHandler?;
|
|
51
|
+
private _sceneTransitionHandler?;
|
|
50
52
|
protected constructor(client?: TelegramClient, params?: DispatcherParams);
|
|
51
53
|
/**
|
|
52
54
|
* Create a new dispatcher and bind it to the client.
|
|
53
55
|
*/
|
|
54
|
-
static for<State extends object = never>(client: TelegramClient, params?: DispatcherParams
|
|
56
|
+
static for<State extends object = never>(client: TelegramClient, ...args: [State] extends [never] ? [params?: DispatcherParams] : [params: DispatcherParams & {
|
|
57
|
+
storage: IStateStorageProvider;
|
|
58
|
+
}]): Dispatcher<State>;
|
|
55
59
|
/**
|
|
56
60
|
* Create a new child dispatcher.
|
|
57
61
|
*/
|
|
@@ -340,6 +344,47 @@ export declare class Dispatcher<State extends object = never> {
|
|
|
340
344
|
* @param group Handler group index
|
|
341
345
|
*/
|
|
342
346
|
onRawUpdate(filter: RawUpdateHandler['check'], handler: RawUpdateHandler['callback'], group?: number): void;
|
|
347
|
+
/**
|
|
348
|
+
* Register a scene transition handler
|
|
349
|
+
*
|
|
350
|
+
* This handler is called whenever a scene transition occurs
|
|
351
|
+
* in the context of the scene that is being entered,
|
|
352
|
+
* and before any of the its own handlers are called,
|
|
353
|
+
* and can be used to customize the transition behavior:
|
|
354
|
+
* - `Stop` to prevent dispatching the update any further **even if ToScene/ToRoot was used**
|
|
355
|
+
* - `Continue` same as Stop, but still dispatch the update to children
|
|
356
|
+
* - `ToScene` to prevent the transition and dispatch the update to the scene entered in the transition handler
|
|
357
|
+
*
|
|
358
|
+
* > **Note**: if multiple `state.enter()` calls were made within the same update,
|
|
359
|
+
* > this handler will only be called for the last one.
|
|
360
|
+
*
|
|
361
|
+
* @param handler Raw update handler
|
|
362
|
+
* @param group Handler group index
|
|
363
|
+
*/
|
|
364
|
+
onSceneTransition(handler: ((ctx: SceneTransitionContext, state: UpdateState<State>) => MaybePromise<PropagationAction | void>) | null): void;
|
|
365
|
+
/**
|
|
366
|
+
* Register a callback query (both inline and non-inline) handler without any filters
|
|
367
|
+
*
|
|
368
|
+
* @param handler Callback query handler
|
|
369
|
+
* @param group Handler group index
|
|
370
|
+
*/
|
|
371
|
+
onAnyCallbackQuery(handler: CallbackQueryHandler<CallbackQueryContext | InlineCallbackQueryContext, State extends never ? never : UpdateState<State>>['callback'], group?: number): void;
|
|
372
|
+
/**
|
|
373
|
+
* Register a callback query (both inline and non-inline) handler with a filter
|
|
374
|
+
*
|
|
375
|
+
* @param filter Update filter
|
|
376
|
+
* @param handler Callback query handler
|
|
377
|
+
* @param group Handler group index
|
|
378
|
+
*/
|
|
379
|
+
onAnyCallbackQuery<Mod>(filter: UpdateFilter<CallbackQueryContext | InlineCallbackQueryContext, Mod, State>, handler: CallbackQueryHandler<filters.Modify<CallbackQueryContext | InlineCallbackQueryContext, Mod>, State extends never ? never : UpdateState<State>>['callback'], group?: number): void;
|
|
380
|
+
/**
|
|
381
|
+
* Register a callback query (both inline and non-inline) handler with a filter
|
|
382
|
+
*
|
|
383
|
+
* @param filter Update filter
|
|
384
|
+
* @param handler Callback query handler
|
|
385
|
+
* @param group Handler group index
|
|
386
|
+
*/
|
|
387
|
+
onAnyCallbackQuery<Mod>(filter: UpdateFilter<CallbackQueryContext | InlineCallbackQueryContext, Mod>, handler: CallbackQueryHandler<filters.Modify<CallbackQueryContext | InlineCallbackQueryContext, Mod>, State extends never ? never : UpdateState<State>>['callback'], group?: number): void;
|
|
343
388
|
/**
|
|
344
389
|
* Register a new message handler without any filters
|
|
345
390
|
*
|
package/cjs/dispatcher.js
CHANGED
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.Dispatcher = void 0;
|
|
8
8
|
const core_1 = require("@mtcute/core");
|
|
9
9
|
const parse_js_1 = require("./context/parse.js");
|
|
10
|
+
const scene_transition_js_1 = require("./context/scene-transition.js");
|
|
10
11
|
const index_js_1 = require("./state/index.js");
|
|
11
12
|
const service_js_1 = require("./state/service.js");
|
|
12
13
|
/**
|
|
@@ -29,6 +30,7 @@ class Dispatcher {
|
|
|
29
30
|
_errorHandler;
|
|
30
31
|
_preUpdateHandler;
|
|
31
32
|
_postUpdateHandler;
|
|
33
|
+
_sceneTransitionHandler;
|
|
32
34
|
constructor(client, params) {
|
|
33
35
|
this.dispatchRawUpdate = this.dispatchRawUpdate.bind(this);
|
|
34
36
|
this.dispatchUpdate = this.dispatchUpdate.bind(this);
|
|
@@ -57,9 +59,6 @@ class Dispatcher {
|
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
|
-
/**
|
|
61
|
-
* Create a new dispatcher and bind it to the client.
|
|
62
|
-
*/
|
|
63
62
|
static for(client, params) {
|
|
64
63
|
return new Dispatcher(client, params);
|
|
65
64
|
}
|
|
@@ -245,7 +244,10 @@ class Dispatcher {
|
|
|
245
244
|
(update.name === 'new_message' ||
|
|
246
245
|
update.name === 'edit_message' ||
|
|
247
246
|
update.name === 'callback_query' ||
|
|
248
|
-
update.name === 'message_group'
|
|
247
|
+
update.name === 'message_group' ||
|
|
248
|
+
update.name === 'new_business_message' ||
|
|
249
|
+
update.name === 'edit_business_message' ||
|
|
250
|
+
update.name === 'business_message_group')) {
|
|
249
251
|
// no need to fetch scene if there are no registered scenes
|
|
250
252
|
if (!parsedContext)
|
|
251
253
|
parsedContext = (0, parse_js_1._parsedUpdateToContext)(this._client, update);
|
|
@@ -281,7 +283,10 @@ class Dispatcher {
|
|
|
281
283
|
(update.name === 'new_message' ||
|
|
282
284
|
update.name === 'edit_message' ||
|
|
283
285
|
update.name === 'callback_query' ||
|
|
284
|
-
update.name === 'message_group'
|
|
286
|
+
update.name === 'message_group' ||
|
|
287
|
+
update.name === 'new_business_message' ||
|
|
288
|
+
update.name === 'edit_business_message' ||
|
|
289
|
+
update.name === 'business_message_group')) {
|
|
285
290
|
if (!parsedContext)
|
|
286
291
|
parsedContext = (0, parse_js_1._parsedUpdateToContext)(this._client, update);
|
|
287
292
|
const key = await this._stateKeyDelegate(parsedContext);
|
|
@@ -327,6 +332,31 @@ class Dispatcher {
|
|
|
327
332
|
}
|
|
328
333
|
else
|
|
329
334
|
continue;
|
|
335
|
+
if (parsedState && this._scenes) {
|
|
336
|
+
// check if scene transition was made
|
|
337
|
+
const newScene = parsedState.scene;
|
|
338
|
+
if (parsedScene !== newScene) {
|
|
339
|
+
const nextDp = newScene ? this._scenes.get(newScene) : this._parent;
|
|
340
|
+
if (!nextDp) {
|
|
341
|
+
throw new core_1.MtArgumentError(`Scene ${newScene} not found`);
|
|
342
|
+
}
|
|
343
|
+
if (nextDp._sceneTransitionHandler) {
|
|
344
|
+
const transition = new scene_transition_js_1.SceneTransitionContext(parsedScene, parsedContext);
|
|
345
|
+
const transitionResult = await nextDp._sceneTransitionHandler?.(transition, parsedState);
|
|
346
|
+
switch (transitionResult) {
|
|
347
|
+
case 'stop':
|
|
348
|
+
return true;
|
|
349
|
+
case 'continue':
|
|
350
|
+
continue;
|
|
351
|
+
case 'scene': {
|
|
352
|
+
const scene = parsedState.scene;
|
|
353
|
+
const dp = scene ? nextDp._scenes.get(scene) : nextDp._parent;
|
|
354
|
+
return dp._dispatchUpdateNowImpl(update, undefined, scene, true);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
330
360
|
switch (result) {
|
|
331
361
|
case 'continue':
|
|
332
362
|
continue;
|
|
@@ -339,11 +369,9 @@ class Dispatcher {
|
|
|
339
369
|
if (!parsedState) {
|
|
340
370
|
throw new core_1.MtArgumentError('Cannot use ToScene without state');
|
|
341
371
|
}
|
|
342
|
-
const scene = parsedState
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
return this._scenes.get(scene)._dispatchUpdateNowImpl(update, undefined, scene, true);
|
|
372
|
+
const scene = parsedState.scene;
|
|
373
|
+
const dp = scene ? this._scenes.get(scene) : this._parent;
|
|
374
|
+
return dp._dispatchUpdateNowImpl(update, undefined, scene, true);
|
|
347
375
|
}
|
|
348
376
|
}
|
|
349
377
|
break;
|
|
@@ -513,6 +541,7 @@ class Dispatcher {
|
|
|
513
541
|
child._client = this._client;
|
|
514
542
|
child._storage = this._storage;
|
|
515
543
|
child._deps = this._deps;
|
|
544
|
+
child._scenes = this._scenes;
|
|
516
545
|
child._stateKeyDelegate = this._stateKeyDelegate;
|
|
517
546
|
child._customStorage ??= this._customStorage;
|
|
518
547
|
child._customStateKeyDelegate ??= this._customStateKeyDelegate;
|
|
@@ -730,6 +759,34 @@ class Dispatcher {
|
|
|
730
759
|
onRawUpdate(filter, handler, group) {
|
|
731
760
|
this._addKnownHandler('raw', filter, handler, group);
|
|
732
761
|
}
|
|
762
|
+
/**
|
|
763
|
+
* Register a scene transition handler
|
|
764
|
+
*
|
|
765
|
+
* This handler is called whenever a scene transition occurs
|
|
766
|
+
* in the context of the scene that is being entered,
|
|
767
|
+
* and before any of the its own handlers are called,
|
|
768
|
+
* and can be used to customize the transition behavior:
|
|
769
|
+
* - `Stop` to prevent dispatching the update any further **even if ToScene/ToRoot was used**
|
|
770
|
+
* - `Continue` same as Stop, but still dispatch the update to children
|
|
771
|
+
* - `ToScene` to prevent the transition and dispatch the update to the scene entered in the transition handler
|
|
772
|
+
*
|
|
773
|
+
* > **Note**: if multiple `state.enter()` calls were made within the same update,
|
|
774
|
+
* > this handler will only be called for the last one.
|
|
775
|
+
*
|
|
776
|
+
* @param handler Raw update handler
|
|
777
|
+
* @param group Handler group index
|
|
778
|
+
*/
|
|
779
|
+
onSceneTransition(handler) {
|
|
780
|
+
if (handler)
|
|
781
|
+
this._sceneTransitionHandler = handler;
|
|
782
|
+
else
|
|
783
|
+
this._sceneTransitionHandler = undefined;
|
|
784
|
+
}
|
|
785
|
+
/** @internal */
|
|
786
|
+
onAnyCallbackQuery(filter, handler, group) {
|
|
787
|
+
this._addKnownHandler('callback_query', filter, handler, group);
|
|
788
|
+
this._addKnownHandler('inline_callback_query', filter, handler, group);
|
|
789
|
+
}
|
|
733
790
|
/** @internal */
|
|
734
791
|
onNewMessage(filter, handler, group) {
|
|
735
792
|
this._addKnownHandler('new_message', filter, handler, group);
|