UNPKG

2.11 kBPlain TextView Raw
1import { isSessionContext, SessionContext } from '../session'
2import SceneContextScene, {
3 SceneContextSceneOptions,
4 SceneSession,
5 SceneSessionData,
6} from './context'
7import { BaseScene } from './base'
8import { Composer } from '../composer'
9import { Context } from '../context'
10
11export class Stage<
12 C extends SessionContext<SceneSession<D>> & {
13 scene: SceneContextScene<C, D>
14 },
15 D extends SceneSessionData = SceneSessionData
16> extends Composer<C> {
17 options: Partial<SceneContextSceneOptions<D>>
18 scenes: Map<string, BaseScene<C>>
19
20 constructor(
21 scenes: ReadonlyArray<BaseScene<C>> = [],
22 options?: Partial<SceneContextSceneOptions<D>>
23 ) {
24 super()
25 this.options = { ...options }
26 this.scenes = new Map<string, BaseScene<C>>()
27 scenes.forEach((scene) => this.register(scene))
28 }
29
30 register(...scenes: ReadonlyArray<BaseScene<C>>) {
31 scenes.forEach((scene) => {
32 if (scene?.id == null || typeof scene.middleware !== 'function') {
33 throw new Error('telegraf: Unsupported scene')
34 }
35 this.scenes.set(scene.id, scene)
36 })
37 return this
38 }
39
40 middleware() {
41 const handler = Composer.compose<C>([
42 (ctx, next) => {
43 const scenes: Map<string, BaseScene<C>> = this.scenes
44 const scene = new SceneContextScene<C, D>(ctx, scenes, this.options)
45 ctx.scene = scene
46 return next()
47 },
48 super.middleware(),
49 Composer.lazy<C>((ctx) => ctx.scene.current ?? Composer.passThru()),
50 ])
51 return Composer.optional(isSessionContext, handler)
52 }
53
54 static enter<C extends Context & { scene: SceneContextScene<C> }>(
55 ...args: Parameters<SceneContextScene<C>['enter']>
56 ) {
57 return (ctx: C) => ctx.scene.enter(...args)
58 }
59
60 static reenter<C extends Context & { scene: SceneContextScene<C> }>(
61 ...args: Parameters<SceneContextScene<C>['reenter']>
62 ) {
63 return (ctx: C) => ctx.scene.reenter(...args)
64 }
65
66 static leave<C extends Context & { scene: SceneContextScene<C> }>(
67 ...args: Parameters<SceneContextScene<C>['leave']>
68 ) {
69 return (ctx: C) => ctx.scene.leave(...args)
70 }
71}