@meomeocoj/torus.js
Version:
Handle communication with torus nodes
85 lines (76 loc) • 2.93 kB
text/typescript
/* eslint-disable */
function capitalizeFirstLetter(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1);
}
export class SomeError<T> extends Error {
errors: Error[];
responses: T[];
predicate: string;
constructor({ errors, responses, predicate }: { errors: Error[]; responses: T[]; predicate: string }) {
super("Unable to resolve enough promises.");
this.errors = errors;
this.responses = responses;
this.predicate = predicate;
}
}
export const Some = <K, T>(promises: Promise<K>[], predicate: (resultArr: K[], { resolved }: { resolved: boolean }) => Promise<T>): Promise<T> =>
new Promise((resolve, reject) => {
let finishedCount = 0;
const sharedState = { resolved: false };
const errorArr: Error[] = new Array(promises.length).fill(undefined);
const resultArr: K[] = new Array(promises.length).fill(undefined);
let predicateError: Error | string;
return promises.forEach((x, index) => {
return x
.then((resp: K) => {
resultArr[index] = resp;
return undefined;
})
.catch((error: Error) => {
errorArr[index] = error;
})
.finally(() => {
if (sharedState.resolved) return;
return predicate(resultArr.slice(0), sharedState)
.then((data) => {
sharedState.resolved = true;
resolve(data);
return undefined;
})
.catch((error) => {
// log only the last predicate error
predicateError = error;
})
.finally(() => {
finishedCount += 1;
if (finishedCount === promises.length) {
const errors = Object.values(
resultArr.reduce((acc: Record<string, string>, z) => {
if (z) {
const { id, error } = z as { id?: string; error?: { data?: string } };
if (error?.data?.length > 0) {
if (error.data.startsWith("Error occurred while verifying params")) acc[id] = capitalizeFirstLetter(error.data);
else acc[id] = error.data;
}
}
return acc;
}, {})
);
if (errors.length > 0) {
// Format-able errors
const msg = errors.length > 1 ? `\n${errors.map((it) => `• ${it}`).join("\n")}` : errors[0];
reject(new Error(msg));
} else {
reject(
new SomeError({
errors: errorArr,
responses: resultArr,
predicate: (predicateError as Error)?.message || (predicateError as string),
})
);
}
}
});
});
});
});