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