Repository navigation
collision instead of silently desyncing.
as-is — the gated middleware captured the id by value — and throws on
so their runtime semantics are unchanged. extend() keeps legacy ids
dispatchActive checks the flag and routes them down the legacy path,
Legacy steps push a placeholder entry (legacy: true, no composer);
~scene.steps is now the complete ordered registry of every step.
next() skipped right over the ask.
scene jumped straight to the first builder step, and update() /
builder steps the legacy step was invisible to navigation: entering the
So in any scene mixing .ask() (or .step(event, handler)) with
step.next() / step.previous() do the same.
initial step, ctx.scene.update() walks it by index, and
decision reads that array: getSceneEnter takes steps[0].id as the
it never pushed an entry into ~scene.steps. But every step-ordering
_registerLegacyEventStep only installed a gated .use() middleware —
fix(runtime): register legacy steps in the ordered step registry.ask() is sugar over a legacy event-filtered step, and
name that does collide with a reserved event.
.step({ name: "location" }, (c) => …) forces the builder form for a
events outside the reserved list. In the other direction,
mistaken for a step name), so .step(["poll_answer"], handler) covers
The array form keeps accepting any UpdateName (an array can never be
a new Bot API update name can no longer steal a step name.
Type-level resolution and runtime registration read from one source, and
utils.ts, which is also exactly what step() routes on at runtime.
The reserved set is now LegacyStepEvent — the frozen events list in
overload, breaking every chained c.message / c.enter / c.on.
.step("subscription", (c) => …) silently resolved to the legacy
subscription, and on that dependency bump every existing
union, which grows with every Bot API release. Bot API 10.1 added
overload was typed T extends UpdateName — the full Telegram update
signature, so the first argument is what routes the call. The legacy
fix(types): freeze the legacy step event list, add step({ name }) escape hatchscene.step(name, builder) and scene.step(event, handler) share a
typecheck.
Omit<EnterExit, "exit">, which made the cancel pattern fail to
exit is also part of the derive's public type now — it was declared
contexts that never call it.
the hook first; the storage read is lazy, so nothing changes for
the active scene's onExit hook. It now looks the scene up and runs
-
The out-of-scene
exit()just dropped the storage key without firingenter/exit pair. It now keeps whatever is already there.
scene's
onExit) the router had already installed with the barehandler (state / params / step, and an
exit()that fires theunconditionally rebuilt
ctx.scene, replacing the full in-scene -
The
scenes()plugin's derive on["message", "callback_query"]
got in its way:
ctx => ctx.scene.exit())` is the documented cancel pattern. Two things
claim falls through to the outer bot chain — so `bot.command("cancel",
fix(runtime): keep the active-scene handler on ctx and fire onExit from a bot-level exit()With passthrough: true (the default) an update the active step doesn't
chore: release 0.7.2
Full Changelog: v0.7.1...v0.7.2