downloadPreviewFiles = async (remote, previewFiles, storageDir) => {
  if (!previewFiles.length) {
    log.info(`No missing files to download`)
    return
  }

  let fetchFileCount = 0

  const test = (file, cb) => {
    if (remote.forceDownload) {
      return cb(true)
    }
    fs.access(path.join(storageDir, file), (fs.constants || fs).F_OK, err => {
      if (err) {
        return cb(true)
      }
      log.trace(`Skip downloading existing file ${file}`)
      return cb(false)
    })
  }

  const task = (file, cb) => fetchFile(remote, file, storageDir)
    .then(() => {
      fetchFileCount++
      cb()
    })
    .catch(err => {
      log.error(err, `Could not fetch ${file} from remote: ${err}`)
      cb(err)
    })

  log.debug(`Fetching ${previewFiles.length} files from remote ${remote.url}${remote.forceDownload ? ' (forced)' : ''}`)
  const t0 = Date.now()
  await pipeline(
    Readable.from(previewFiles),
    parallel({ test, task, concurrent: 10 }),
    purge(),
  )
  log.info(t0, `Fetched ${fetchFileCount} files from remote ${remote.url}`)
}
@param {import('./types.js').Remote} remote
@param {string[]} previewFiles
@param {string} storageDir