class SseFrameAccumulator { String _pending = ''; List add(String chunk) { _pending = (_pending + chunk).replaceAll('\r\n', '\n'); final frames = []; var separator = _pending.indexOf('\n\n'); while (separator >= 0) { final frame = _pending.substring(0, separator); _pending = _pending.substring(separator + 2); if (frame.trim().isNotEmpty) frames.add(frame); separator = _pending.indexOf('\n\n'); } return frames; } List close() { final trailing = _pending.trim(); _pending = ''; return trailing.isEmpty ? const [] : [trailing]; } }