function encodeChunks(chunks) {
  const encodedChunks = []
  const codec = new EventStreamCodec(toUtf8, fromUtf8)

  for (const chunk of chunks) {
    const b64Body = Buffer.from(JSON.stringify(chunk.body)).toString('base64')
    const bytesObj = JSON.stringify({ bytes: b64Body })
    const bodyBuffer = Buffer.from(bytesObj)
    const toEncode = {
      headers: chunk.headers,
      body: new Uint8Array(bodyBuffer, 0, bodyBuffer.byteLength)
    }
    encodedChunks.push(codec.encode(toEncode))
  }

  return new Readable({
    read() {
      if (encodedChunks.length > 0) {
        this.push(encodedChunks.shift())
      } else {
        this.push(null)
      }
    }
  }).pause()
}
Encodes a set of {@link BedrockStreamChunk} objects into binary packed
message objects that can be sent as a streamed response. The binary
format is mainly handled by the `EventStreamCodec` object from the AWS
tooling, but understanding the format is likely beneficial to anyone
reading this. The basics of the format are:

1. A 16 byte prelude starts each message. The first 4 bytes are a big endian
uint32 representing the message length. The second 4 bytes are another
uint32 representing the headers length. The third 4 bytes are a CRC32
checksum for the first 8 bytes.
2. The message length _includes_ all 16 bytes of the prelude block, the
encoded headers block, and the encoded body block.
3. The whole message is terminated with a 4 byte CRC32 checksum value of
the whole message.
4. The encoded headers block starts with the vertical tab byte 0x0b followed
by an alternating set of: string (header name), 3 byte descriptor (leftmost
byte being an indicator of the header type, e.g. 0x07 for "string", and the
two remaining bytes an integer indicating the length of the value), the
value of the header (e.g. a string for a string header), and a terminating
byte set to 0x0d _except_ for the final header where there is not a
terminating byte.
5. The encoded body block is a JSON string that represents an object with a
`bytes` key set to a base64 encoded JSON representation of a
{@link BedrockModelResponse} object. This block is added without any preamble
or trailer.
6. The 4 byte whole message checksum.

Messages in the data stream are not separated in any way. Each 4 byte message
length is used to demarcate each message. Note that there may be some
incorrect assumptions in the format description; we have not found any actual
documentation on the format and had to derive it from network inspection and
reversing of the parsing algorithm.

@param {BedrockStreamChunk[]} chunks The chunks to encode.
@returns {Readable} A paused stream that will write one coded chunk per
read operation.