zip
bun add @stopcock/zipCreates valid ZIP files with DEFLATE compression. Everything happens in memory, no filesystem needed.
import { createZip, type ZipEntry } from '@stopcock/zip'
const zip = createZip([ { path: 'readme.txt', data: new TextEncoder().encode('hello') }, { path: 'docs/notes.txt', data: new TextEncoder().encode('world') },])
await Bun.write('archive.zip', zip)Paths with / create nested directories in the archive.
interface ZipEntry { path: string data: Uint8Array}
createZip(entries: ZipEntry[]): Uint8ArraycreateZip takes an array of entries, DEFLATE-compresses each one, writes local file headers + central directory + end record, and returns the complete ZIP as a Uint8Array.
With async and fp
Section titled “With async and fp”Combine with @stopcock/async for concurrent downloads and stopcock for data transformation:
import { pipe, A, D } from '@stopcock/fp'import { fromPromise, map, flatMap, mapAsync, run } from '@stopcock/async'import { createZip } from '@stopcock/zip'
const download = (url: string, path: string) => pipe( fromPromise(() => fetch(url)), flatMap(res => fromPromise(() => res.arrayBuffer())), map(buf => ({ path, data: new Uint8Array(buf) })),)
const entries = await pipe( files, mapAsync(f => download(f.url, f.name).run(), 4), run,)
await Bun.write('bundle.zip', createZip(entries))