| 497 | | 497 | |
| 498 | // The direction is consumed by exactly one generation. GENERATION_ENDED also fires when the | 498 | // The direction is consumed by exactly one generation. GENERATION_ENDED also fires when the |
| 499 | // nested option request finishes, which is why clearing is skipped while a roll is in flight. | 499 | // nested option request finishes, which is why clearing is skipped while a roll is in flight. |
| 500 | const onGenerationDone = () => { | 500 | // With streaming, the UI unlock that emits GENERATION_ENDED happens BEFORE MESSAGE_RECEIVED, |
| | 501 | // so only the injection may be cleared here — the pending stamp must survive until the |
| | 502 | // message events consume it (the interceptor resets it at the start of every next turn). |
| | 503 | eventSource.on(event_types.GENERATION_ENDED, () => { |
| | 504 | if (isRolling) { |
| | 505 | return; |
| | 506 | } |
| | 507 | clearDirectionInjection(); |
| | 508 | }); |
| | 509 | eventSource.on(event_types.GENERATION_STOPPED, () => { |
| 501 | if (isRolling) { | 510 | if (isRolling) { |
| 502 | return; | 511 | return; |
| 503 | } | 512 | } |
| 504 | pendingStamp = null; | 513 | pendingStamp = null; |
| 505 | clearDirectionInjection(); | 514 | clearDirectionInjection(); |
| 506 | }; | 515 | }); |
| 507 | eventSource.on(event_types.GENERATION_ENDED, onGenerationDone); | | |
| 508 | eventSource.on(event_types.GENERATION_STOPPED, onGenerationDone); | | |
| 509 | } | 516 | } |