chore: update markdown dependency and refactor streaming handling

- Added `markdown` dependency version `^7.2.1` in `pubspec.yaml`.
- Updated `pubspec.lock` to reflect the direct dependency change.
- Refactored `streaming_helper.dart` to utilize `StreamingResponseController` for better stream management.
- Enhanced `ChatMessagesNotifier` to handle message streams with improved formatting and error handling.
- Updated `StreamingMarkdownWidget` to streamline markdown rendering and support new configurations.
This commit is contained in:
cogwheel0
2025-09-30 20:49:02 +05:30
parent d3b64716b9
commit 7debb7a055
10 changed files with 451 additions and 301 deletions

View File

@@ -0,0 +1,95 @@
import 'dart:async';
import '../utils/debug_logger.dart';
/// Signature for callbacks that receive streaming text updates.
typedef StreamingChunkCallback = void Function(String chunk);
/// Signature for callbacks invoked when a streaming session finishes.
typedef StreamingCompletionCallback = void Function();
/// Signature for callbacks invoked when a streaming session encounters an
/// error.
typedef StreamingErrorCallback =
void Function(Object error, StackTrace stackTrace);
/// A lightweight controller that manages the lifecycle of a streamed response.
///
/// This wraps a [StreamSubscription], normalises error handling, and exposes
/// a unified cancel method so UI layers can stop streaming without having to
/// know the underlying transport (SSE, polling, etc.).
class StreamingResponseController {
StreamingResponseController({
required Stream<String> stream,
required StreamingChunkCallback onChunk,
required StreamingCompletionCallback onComplete,
required StreamingErrorCallback onError,
bool cancelOnError = true,
}) : _onChunk = onChunk,
_onComplete = onComplete,
_onError = onError {
_subscription = stream.listen(
_handleChunk,
cancelOnError: cancelOnError,
onDone: _handleCompleted,
onError: _handleError,
);
}
final StreamingChunkCallback _onChunk;
final StreamingCompletionCallback _onComplete;
final StreamingErrorCallback _onError;
StreamSubscription<String>? _subscription;
bool _isCancelled = false;
/// Whether the underlying stream subscription is still active.
bool get isActive => _subscription != null && !_isCancelled;
void _handleChunk(String chunk) {
if (_isCancelled) {
return;
}
try {
_onChunk(chunk);
} catch (err, stackTrace) {
DebugLogger.error(
'streaming-chunk-handler-failed',
scope: 'streaming/controller',
error: err,
);
_handleError(err, stackTrace);
}
}
void _handleCompleted() {
if (_isCancelled) {
return;
}
_subscription = null;
try {
_onComplete();
} catch (err, stackTrace) {
_handleError(err, stackTrace);
}
}
void _handleError(Object error, StackTrace stackTrace) {
if (_isCancelled) {
return;
}
_subscription = null;
_onError(error, stackTrace);
}
/// Cancels the underlying stream subscription.
Future<void> cancel() async {
if (_isCancelled) {
return;
}
_isCancelled = true;
final subscription = _subscription;
_subscription = null;
await subscription?.cancel();
}
}