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(); const [update, result] = this.connectModule(method, data, (item: any) => { pipe.resolve(item); }); (async () => { const ret = await result; this.handleError(ret); pipe.resolve(undefined); })(); return { abort() { update("abort"); }, iterable(): AsyncIterable { return { [Symbol.asyncIterator]() { return { async next(): Promise> { const chunk = await pipe.promise; if (chunk === undefined) { return { value: new Uint8Array(), done: true, }; } update("next"); pipe = defer(); return { value: chunk, done: false, }; }, }; }, }; }, }; } } export const createClient = factory( IPFSClient, "AAA0F0m8xP2YVcP0YZ-1QT8nLqYPZjgANotOQO3nGST1Bg" );