(body: ReadableStream<Uint8Array>)
| 28 | }) |
| 29 | |
| 30 | async function* eventStream(body: ReadableStream<Uint8Array>) { |
| 31 | const reader = body.getReader() |
| 32 | const decoder = new TextDecoder() |
| 33 | let buffer = "" |
| 34 | try { |
| 35 | while (true) { |
| 36 | const boundary = buffer.match(/(?:\r\n|\r|\n){2}/) |
| 37 | if (!boundary || boundary.index === undefined) { |
| 38 | const value = await reader.read() |
| 39 | if (value.done) return |
| 40 | buffer += decoder.decode(value.value, { stream: true }) |
| 41 | continue |
| 42 | } |
| 43 | |
| 44 | const record = buffer.slice(0, boundary.index) |
| 45 | buffer = buffer.slice(boundary.index + boundary[0].length) |
| 46 | const data = record |
| 47 | .split(/\r\n|\r|\n/) |
| 48 | .filter((line) => line.startsWith("data:")) |
| 49 | .map((line) => line.slice(5).replace(/^ /, "")) |
| 50 | if (data.length) yield Schema.decodeUnknownSync(Event)(JSON.parse(data.join("\n"))) |
| 51 | } |
| 52 | } finally { |
| 53 | try { |
| 54 | await reader.cancel() |
| 55 | } finally { |
| 56 | reader.releaseLock() |
| 57 | } |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | async function readEvent(reader: AsyncIterator<typeof Event.Type>) { |
| 62 | const value = await reader.next() |
no test coverage detected