import { Client, factory, NetworkClient } from "@lumeweb/libkernel/module"; import defer from "p-defer"; import { CatOptions, LsOptions, StatOptions } from "@helia/unixfs"; interface AbortableGenerator { abort: () => void; iterable: () => AsyncIterable; } export const MODULE = "zduPX8bUwHAY1C69w5sqxG9WoTRsdWrdk9Mci3sfajHnB4YHUWBkehd29D"; export class IPFSClient extends NetworkClient { 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, }; } pipe = defer(); update("next"); return { value: chunk, done: false, }; }, }; }, }; }, }; } } export const createClient = factory(IPFSClient, MODULE);