import { Client, factory } from "@lumeweb/libkernel-universal"; import defer from "p-defer"; import { CatOptions, LsOptions, StatOptions } from "@helia/unixfs"; interface AbortableGenerator { abort: () => void; iterable: () => AsyncIterable; } export class IPFSClient extends Client { public async ready() { return this.callModuleReturn("ready"); } public async stat(cid: string, options?: Partial) { return this.callModuleReturn("stat", { cid, options }); } public ls(cid: string, options?: Partial): AbortableGenerator { return this.connectModuleGenerator("ls", { cid, options }); } public cat(cid: string, options?: Partial): AbortableGenerator { return this.connectModuleGenerator("cat", { cid, options }); } public async ipns(cid: string): Promise { return this.callModuleReturn("ipnsResolve", { cid }); } public async activePeers(): Promise { return this.callModuleReturn("getActivePeers"); } private connectModuleGenerator( method: string, data: any ): AbortableGenerator { let pipe = defer(); let done = false; const [update, result] = this.connectModule(method, data, (item: any) => { pipe.resolve(item); }); (async () => { const ret = await result; done = true; this.handleError(ret); })(); return { abort() { update("abort"); }, iterable(): AsyncIterable { return { [Symbol.asyncIterator]() { return { async next(): Promise> { if (done) { return { value: undefined, done, }; } const chunk = await pipe.promise; update("next"); pipe = defer(); return { value: chunk, done, }; }, }; }, }; }, }; } } export const createClient = factory( IPFSClient, "AAD_sKxIPbN-n7sNpYycq0M6wyix_UMIhqFiUPILfKiuqA" );