From 0579bec14dd7cc9b8a34a3059ff68e485bf5d305 Mon Sep 17 00:00:00 2001 From: Bart Mesuere Date: Wed, 7 Aug 2024 14:41:46 +0200 Subject: [PATCH] add comments --- lib/commands/unipept/unipept_subcommand.ts | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/commands/unipept/unipept_subcommand.ts b/lib/commands/unipept/unipept_subcommand.ts index 517ef65a..47f6d210 100644 --- a/lib/commands/unipept/unipept_subcommand.ts +++ b/lib/commands/unipept/unipept_subcommand.ts @@ -62,9 +62,12 @@ export abstract class UnipeptSubcommand { this.host = this.getHost(); this.url = `${this.host}/api/v2/${this.name}.json`; this.formatter = FormatterFactory.getFormatter(this.options.format); + if (this.options.output) { this.outputStream = createWriteStream(this.options.output); } else { + // if we write to stdout, we need to handle the EPIPE error + // this happens when the output is piped to another command that stops reading process.stdout.on("error", (err) => { if (err.code === "EPIPE") { process.exit(0); @@ -75,6 +78,7 @@ export abstract class UnipeptSubcommand { const iterator = this.getInputIterator(args, options.input as string); const firstLine = (await iterator.next()).value; if (this.command.name() === "taxa2lca") { + // this subcommand is an exception where the entire input is read before processing await this.simpleInputProcessor(firstLine, iterator); } else if (firstLine.startsWith(">")) { this.fasta = true; @@ -120,6 +124,9 @@ export abstract class UnipeptSubcommand { if (this.firstBatch) this.firstBatch = false; } + /** + * Filter the result based on the selected fields + */ filterResult(result: unknown): object[] { if (!Array.isArray(result)) { result = [result]; @@ -139,6 +146,9 @@ export abstract class UnipeptSubcommand { return result as object[]; } + /** + * Reads batchSize lines from the input and processes them + */ async normalInputProcessor(firstLine: string, iterator: IterableIterator | AsyncIterableIterator) { let slice = [firstLine]; @@ -152,6 +162,10 @@ export abstract class UnipeptSubcommand { await this.processBatch(slice); } + /** + * Reads batchSize lines from the input and processes them, + * but takes into account the fasta headers. + */ async fastaInputProcessor(firstLine: string, iterator: IterableIterator | AsyncIterableIterator) { let currentFastaHeader = firstLine; let slice = []; @@ -172,6 +186,9 @@ export abstract class UnipeptSubcommand { await this.processBatch(slice, fastaMapper); } + /** + * Reads the entire input and processes it in one go + */ async simpleInputProcessor(firstLine: string, iterator: IterableIterator | AsyncIterableIterator) { const slice = [firstLine]; for await (const line of iterator) { @@ -180,6 +197,9 @@ export abstract class UnipeptSubcommand { await this.processBatch(slice); } + /** + * Appends the error message to the log file of today and prints it to the console + */ async saveError(message: string) { const errorPath = this.errorFilePath(); mkdir(path.dirname(errorPath), { recursive: true }); @@ -187,6 +207,11 @@ export abstract class UnipeptSubcommand { console.error(`API request failed! log can be found in ${errorPath}`); } + /** + * Uses fetch to get data from the Unipept API. + * Has a retry mechanism that retries the request up to 5 times with a delay of 0-5 seconds. + * In addition, handles failed requests by returning a rejected promise. + */ fetchWithRetry(url: string, options: RequestInit, retries = 5): Promise { return fetch(url, options) .then(response => {