javascriptnode.jsipfsnode-streams

Create a blob from a web stream in Node.js


I am trying to pack a CAR file through ipfs-car (which uses web streams) and later send it in a request as a file but I'm not sure how to store it in a Blob after I have streamed in a WritableStream.

I have this piece of code

import { CAREncoderStream, createDirectoryEncoderStream } from 'ipfs-car'
import { WritableStream } from 'node:stream/web'

export const packCAR = async (files) => {
  const blockStream = createDirectoryEncoderStream(files)
  const carEncoderStream = new CAREncoderStream([])
  const outStream = new WritableStream()
  await blockStream.pipeThrough(carEncoderStream).pipeTo(outStream)
  const blob = new Blob(/* what do I put here? */)
}

I haven't found anyone doing this, I only saw how to convert Blob to a stream, so help would be appreciated :)


Solution

  • Store the content of the WritableStream into a Blob. This can be done by transforming the WritableStream into a ReadableStream, then converting it into an ArrayBuffer, and finally storing the ArrayBuffer into a Blob.

    import { CAREncoderStream, createDirectoryEncoderStream } from 'ipfs-car'
    import { WritableStream, ReadableStream } from 'node:stream/web'
    
    export const packCAR = async (files) => {
      const blockStream = createDirectoryEncoderStream(files)
      const carEncoderStream = new CAREncoderStream([])
      const chunks = []
      const outStream = new WritableStream({
        write(chunk) {
          chunks.push(chunk)
        },
        close() {
          console.log('Stream is closed.')
        }
      })
      await blockStream.pipeThrough(carEncoderStream).pipeTo(outStream)
      const arrayBuffer = await new Blob(chunks).arrayBuffer()
      const blob = new Blob([arrayBuffer])
      return blob
    }