* Create a statefull message buffer that parses TSServer messages. * * @returns {(chunk: Buffer) => Generator<[body: Record , headers: Array<[name: string, value: string]>]>}
()
| 157 | * @returns {(chunk: Buffer) => Generator<[body: Record<string, unknown>, headers: Array<[name: string, value: string]>]>} |
| 158 | */ |
| 159 | function createMessageBuffer(): ( |
| 160 | chunk: Buffer, |
| 161 | ) => Generator<[body: Record<string, unknown>, headers: Array<[name: string, value: string]>]> { |
| 162 | let buffer = Buffer.from([]); |
| 163 | /** |
| 164 | * |
| 165 | * @param {Buffer} chunk |
| 166 | * @return {Generator<[body: Record<string, unknown>, headers: Array<[name: string, value: string]>]>} |
| 167 | */ |
| 168 | return function* read(chunk) { |
| 169 | buffer = Buffer.concat([buffer, chunk]); |
| 170 | |
| 171 | let position = 0; |
| 172 | |
| 173 | while (position < buffer.length) { |
| 174 | const headerSuffix = buffer.indexOf(HEADER_END, position); |
| 175 | |
| 176 | if (headerSuffix === -1) { |
| 177 | throw new Error('no headers ' + buffer.toString('utf8')); |
| 178 | } |
| 179 | |
| 180 | const headers: [string, string][] = Array.from(parseHeaders(buffer.subarray(position, headerSuffix))); |
| 181 | |
| 182 | // Content length |
| 183 | const contentLength = Number.parseInt( |
| 184 | headers.find(([name]) => name === 'Content-Length')?.[1] ?? Number.NaN.toString(), |
| 185 | ); |
| 186 | if (Number.isNaN(contentLength)) { |
| 187 | throw new TypeError('invalid message, no Content-Length'); |
| 188 | } |
| 189 | |
| 190 | const bodyStart = headerSuffix + HEADER_END.length; |
| 191 | const bodyEnd = bodyStart + contentLength; |
| 192 | |
| 193 | if (bodyEnd > buffer.length) { |
| 194 | buffer = buffer.subarray(position); |
| 195 | return; |
| 196 | } |
| 197 | |
| 198 | yield [JSON.parse(buffer.subarray(bodyStart, bodyEnd).toString('utf8')), headers]; |
| 199 | |
| 200 | position = bodyEnd; |
| 201 | } |
| 202 | }; |
| 203 | } |
| 204 | |
| 205 | /** |
| 206 | * Every time the returned function is called it will return a new sequenc. |
no test coverage detected