| 189 | } |
| 190 | |
| 191 | function parseEventStreamLine( |
| 192 | lineBuffer: string, |
| 193 | index: number, |
| 194 | fieldLength: number, |
| 195 | lineLength: number |
| 196 | ) { |
| 197 | if (lineLength === 0) { |
| 198 | // We reached the last line of this event |
| 199 | if (data.length > 0) { |
| 200 | onParse({ |
| 201 | _tag: "Event", |
| 202 | id: eventId, |
| 203 | event: eventName ?? "message", |
| 204 | data: data.slice(0, -1) // remove trailing newline |
| 205 | }) |
| 206 | data = "" |
| 207 | eventId = undefined |
| 208 | } |
| 209 | eventName = undefined |
| 210 | return |
| 211 | } |
| 212 | |
| 213 | const noValue = fieldLength < 0 |
| 214 | const field = lineBuffer.slice(index, index + (noValue ? lineLength : fieldLength)) |
| 215 | let step = 0 |
| 216 | |
| 217 | if (noValue) { |
| 218 | step = lineLength |
| 219 | } else if (lineBuffer[index + fieldLength + 1] === " ") { |
| 220 | step = fieldLength + 2 |
| 221 | } else { |
| 222 | step = fieldLength + 1 |
| 223 | } |
| 224 | |
| 225 | const position = index + step |
| 226 | const valueLength = lineLength - step |
| 227 | const value = lineBuffer.slice(position, position + valueLength).toString() |
| 228 | |
| 229 | if (field === "data") { |
| 230 | data += value ? `${value}\n` : "\n" |
| 231 | } else if (field === "event") { |
| 232 | eventName = value |
| 233 | } else if (field === "id" && !value.includes("\u0000")) { |
| 234 | eventId = value |
| 235 | lastEventId = value |
| 236 | } else if (field === "retry") { |
| 237 | const retry = parseInt(value, 10) |
| 238 | if (!Number.isNaN(retry)) { |
| 239 | onParse(new Retry({ duration: Duration.millis(retry), lastEventId })) |
| 240 | } |
| 241 | } |
| 242 | } |
| 243 | } |
| 244 | |
| 245 | const BOM = [239, 187, 191] |