@@ -26,19 +26,19 @@ class Gateway:
2626
2727 Usage::
2828
29- async with stackcoin.Client(token="...") as client:
30- gateway = stackcoin.Gateway(token="...", client=client)
29+ gateway = stackcoin.Gateway(token="...")
3130
32- @gateway.on("request.accepted")
33- async def handle_accepted(event: stackcoin.RequestAcceptedEvent):
34- print(event.data.request_id)
31+ @gateway.on("request.accepted")
32+ async def handle_accepted(event: stackcoin.RequestAcceptedEvent):
33+ print(event.data.request_id)
3534
36- await gateway.connect()
35+ await gateway.connect()
3736
38- If a ``client`` is provided and the bot has been offline too long (>100
39- missed events), the gateway automatically catches up via the REST API
40- before reconnecting. Without a ``client``, the error is raised to the
41- caller.
37+ By default, the gateway receives only live events. Pass ``last_event_id``
38+ to replay missed events from a cursor position. If more than 100 events
39+ were missed and a ``client`` is provided, the gateway automatically catches
40+ up via the REST API before reconnecting. Without a ``client``, a
41+ ``TooManyMissedEventsError`` is raised.
4242 """
4343
4444 def __init__ (
@@ -47,7 +47,7 @@ def __init__(
4747 * ,
4848 ws_url : str = "wss://stackcoin.world/ws" ,
4949 client : Client | None = None ,
50- last_event_id : int = 0 ,
50+ last_event_id : int | None = None ,
5151 on_event_id : Callable [[int ], None ] | None = None ,
5252 ):
5353 self ._ws_url = ws_url .rstrip ("/" )
@@ -61,7 +61,7 @@ def __init__(
6161 self ._ref_counter = 0
6262
6363 @property
64- def last_event_id (self ) -> int :
64+ def last_event_id (self ) -> int | None :
6565 return self ._last_event_id
6666
6767 def on (self , event_type : str ) -> Callable [[_F ], _F ]:
@@ -133,13 +133,15 @@ async def _catch_up_via_rest(self) -> None:
133133 """
134134 if self ._client is None :
135135 raise RuntimeError ("Cannot catch up via REST without a client" )
136- events = await self ._client .get_events (since_id = self ._last_event_id )
136+ # _last_event_id is always an int here — TooManyMissedEventsError only
137+ # fires when a last_event_id was sent in the join payload.
138+ events = await self ._client .get_events (since_id = self ._last_event_id or 0 )
137139 for event in events :
138140 await self ._dispatch_event (event )
139141
140142 async def _dispatch_event (self , typed_event : AnyEvent ) -> None :
141143 """Dispatch a typed event to registered handlers and update the cursor."""
142- if typed_event .id > self ._last_event_id :
144+ if self . _last_event_id is None or typed_event .id > self ._last_event_id :
143145 self ._last_event_id = typed_event .id
144146
145147 for handler in self ._handlers .get (typed_event .type , []):
@@ -159,13 +161,16 @@ async def _join_channel(self, ws: Any) -> None:
159161 from .errors import TooManyMissedEventsError
160162
161163 self ._ref_counter += 1
164+ join_payload : dict [str , Any ] = {}
165+ if self ._last_event_id is not None :
166+ join_payload ["last_event_id" ] = self ._last_event_id
162167 join_msg = json .dumps (
163168 [
164169 None ,
165170 str (self ._ref_counter ),
166171 "user:self" ,
167172 "phx_join" ,
168- { "last_event_id" : self . _last_event_id } ,
173+ join_payload ,
169174 ]
170175 )
171176 await ws .send (join_msg )
0 commit comments