fix: abort streaming immediately on stop instead of waiting for next token
The messageUpdatesAbortController was a local variable inside
writeMessage(), so stopGeneration() could only set the $isAborted
flag and hope the for-await loop would check it on the next
iteration. But the loop was blocked waiting for smoothStreamUpdates
to yield (up to 80ms sleep per token, or indefinitely if waiting
for the next server chunk), so the abort was delayed.
Fix: hoist messageUpdatesAbortController to component scope and
call .abort() directly in stopGeneration() and beforeNavigate.
This immediately cancels the fetch reader, terminates the
smoothStreamUpdates producer, and breaks the pipeline without
waiting for the next token to arrive.