Skip to content

Instantly share code, notes, and snippets.

@alanshaw
Created June 30, 2021 09:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alanshaw/fdeaed7df576231a38487e53a3a63c50 to your computer and use it in GitHub Desktop.
Save alanshaw/fdeaed7df576231a38487e53a3a63c50 to your computer and use it in GitHub Desktop.
import path from 'path'
type ImportCandidate = x|y|z|{ path: string, content: x|y|z }
type UnixFsEntry = { path: string, content: AsyncIterable<Uint8Array> }
// extends Blob?
class Web3File extends Blob {
constructor (filename: string, content: AsyncIterable<Uint8Array>, options?: Web3FileOpts)
// Generate from content?
// IDK maybe not!
async cid (): CID|null
// like a File object
get name (): string // filename
// actually path+filename for compat with UnixFsEntry
get path (): string // path+filename
// just for compat with UnixFsEntry
get content () { return this.iterator() }
// implemening remaining File interface...?
get lastModified (): number // Date.now()
// get type (): string // mime type TODO: howto?
// get size (): number // TODO: howto?
[Symbol.asyncIterator] (): AsyncIterable<Uint8Array>
iterator (): AsyncIterable<Uint8Array>
stream (): ReadableStream
async blob (): Blob
async text (): string
// browser readablestream
static async fromReadableStream (filename: string, r: ReadableStream, options: Web3FileOpts)
static async fromString (filename: string, s: string, options: Web3FileOpts)
static async fromBlob (filename: string, b: Blob, options: Web3FileOpts)
// file already has a filename so no need to pass here
static async fromFile (f: File, options: Web3FileOpts)
}
type Web3FileOpts = { path: string, cid?: CID }
// Web3File in, Web3File out
const client = new Web3Storage()
/////////// PUTTING CONTENT
client.put(files: Web3File[]|FileList)
// In Node.js streams are async iterable
new Web3File('file.zip', fs.createReadStream('path/to/file'))
// In browser
// create from file
Web3File.fromFile(new File(['data'], 'foo.txt'))
/////////// GETTING CONTENT
const r = await client.get(cid: string): Web3Response
r.files(): Web3File[]
r.filesIterator(): AsyncIterable<Web3File>
r.unixFsIterator(): AsyncIterable<UnixFsEntry>
/////////////////////////////////////////////////////////////////////////////
// ipfs-car
const unpack = async function* (blocks: BlockIterator, roots?: CID[], { blockstore }): AsyncIterable<Web3File> {
const bs = blockstore || new ValidatingMemoryBlockstore()
for await (const b of blocks) {
await bs.put(b)
}
if (!roots || roots.length === 0 ) {
roots = await blocks.getRoots()
}
for (const root of roots) {
for await (const e of exporter.recursive(root, bs, { /* options */ })) {
yield new Web3File(path.basename(e.path), e.content, { path: path.dirname(e.path) })
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment