All files / src/utils chunk-stream.ts

92.45% Statements 49/53
37.5% Branches 3/8
83.33% Functions 5/6
92.45% Lines 49/53

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 10533x 33x 33x 33x 33x 33x 33x 33x     33x 1x 1x 1x 3x   3x     3x 3x 3x   3x 3x 3x           1x     33x               1x 1x 1x 1x 1x 1x 3x       13x 13x 13x     1x 1x 3x     3x   3x 3x 3x   3x 3x 3x 3x         3x             1x       6x 4x     2x     33x                    
import { AsyncQueue, Chunk, MerkleTree, Strings } from 'cafe-utility'
import { createReadStream } from 'fs'
import { Bee, BeeRequestOptions, NULL_ADDRESS, UploadOptions, UploadResult } from '..'
import { MantarayNode } from '../manifest/manifest'
import { totalChunks } from './chunk-size'
import { makeCollectionFromFS } from './collection.node'
import { mimes } from './mime'
import { BatchId } from './typed-bytes'
import { UploadProgress } from './upload-progress'
 
export async function hashDirectory(dir: string) {
  const files = await makeCollectionFromFS(dir)
  const mantaray = new MantarayNode()
  for (const file of files) {
    const tree = new MerkleTree(MerkleTree.NOOP)
 
    Iif (!file.fsPath) {
      throw Error('File does not have fsPath, which should never happen in node. Please report this issue.')
    }
    const readStream = createReadStream(file.fsPath)
    for await (const data of readStream) {
      await tree.append(data)
    }
    const rootChunk = await tree.finalize()
    const { filename, extension } = Strings.parseFilename(file.path)
    mantaray.addFork(file.path, rootChunk.hash(), {
      'Content-Type': maybeEnrichMime(mimes[extension.toLowerCase()] || 'application/octet-stream'),
      Filename: filename,
    })
  }
 
  return mantaray.calculateSelfAddress()
}
 
export async function streamDirectory(
  bee: Bee,
  dir: string,
  postageBatchId: BatchId | string | Uint8Array,
  onUploadProgress?: (progress: UploadProgress) => void,
  options?: UploadOptions,
  requestOptions?: BeeRequestOptions,
) {
  const queue = new AsyncQueue(64, 64)
  let total = 0
  let processed = 0
  postageBatchId = new BatchId(postageBatchId)
  const files = await makeCollectionFromFS(dir)
  for (const file of files) {
    total += totalChunks(file.size)
  }
 
  async function onChunk(chunk: Chunk) {
    await queue.enqueue(async () => {
      await bee.uploadChunk(postageBatchId, chunk.build(), options, requestOptions)
      onUploadProgress?.({ total, processed: ++processed })
    })
  }
  const mantaray = new MantarayNode()
  for (const file of files) {
    Iif (!file.fsPath) {
      throw Error('File does not have fsPath, which should never happen in node. Please report this issue.')
    }
    const readStream = createReadStream(file.fsPath)
 
    const tree = new MerkleTree(onChunk)
    for await (const data of readStream) {
      await tree.append(data)
    }
    const rootChunk = await tree.finalize()
    await queue.drain()
    const { filename, extension } = Strings.parseFilename(file.path)
    mantaray.addFork(file.path, rootChunk.hash(), {
      'Content-Type': maybeEnrichMime(mimes[extension.toLowerCase()] || 'application/octet-stream'),
      Filename: filename,
    })
 
    Iif (file.path === 'index.html') {
      mantaray.addFork('/', NULL_ADDRESS, {
        'website-index-document': 'index.html',
      })
    }
  }
 
  return mantaray.saveRecursively(bee, postageBatchId, options, requestOptions)
}
 
function maybeEnrichMime(mime: string) {
  if (['text/html', 'text/css'].includes(mime)) {
    return `${mime}; charset=utf-8`
  }
 
  return mime
}
 
export async function streamFiles(
  _bee: Bee,
  _files: File[] | FileList,
  _postageBatchId: BatchId,
  _onUploadProgress?: (progress: UploadProgress) => void,
  _options?: UploadOptions,
  _requestOptions?: BeeRequestOptions,
): Promise<UploadResult> {
  throw new Error('Streaming files is not supported in Node.js')
}