parse method

Stream<SseEvent> parse(
  1. Stream<List<int>> byteStream
)

Transform a raw byte stream into a stream of SseEvents.

Implementation

Stream<SseEvent> parse(Stream<List<int>> byteStream) async* {
  final lineStream = byteStream
      .transform(utf8.decoder)
      .transform(const LineSplitter());

  await for (final rawLine in lineStream) {
    // Handle partial lines carried from previous chunk.
    final line = _lineCarry.isEmpty ? rawLine : '$_lineCarry$rawLine';
    _lineCarry = '';

    // Comment line — ignore.
    if (line.startsWith(':')) continue;

    // Empty line — dispatch accumulated event.
    if (line.isEmpty) {
      if (_dataBuffer.isNotEmpty) {
        final data = _dataBuffer.toString();
        // Remove trailing newline if present.
        final trimmed = data.endsWith('\n')
            ? data.substring(0, data.length - 1)
            : data;
        yield SseEvent(
          eventType: _eventType.isNotEmpty ? _eventType : null,
          data: trimmed,
          id: _lastId.isNotEmpty ? _lastId : null,
          retry: _retry,
        );
      }
      // Reset per-event state.
      _eventType = '';
      _dataBuffer.clear();
      _retry = null;
      continue;
    }

    // Parse field.
    final colonIdx = line.indexOf(':');
    if (colonIdx == -1) {
      // Field name with no value — treat value as empty string.
      _processField(line, '');
    } else {
      final fieldName = line.substring(0, colonIdx);
      var value = line.substring(colonIdx + 1);
      // Strip single leading space from value per spec.
      if (value.startsWith(' ')) value = value.substring(1);
      _processField(fieldName, value);
    }
  }
}