Skip to content

Commit

Permalink
Merge pull request #538 from flowreaction/flowreaction/issue534
Browse files Browse the repository at this point in the history
fix(issue 534): replace reduce + spread operator with performant variant
  • Loading branch information
supermacro authored Jun 2, 2024
2 parents 56b7823 + 2a34a15 commit 2062c32
Showing 1 changed file with 28 additions and 24 deletions.
52 changes: 28 additions & 24 deletions src/_internals/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,24 @@ export type InferErrTypes<R> = R extends Result<unknown, infer E> ? E : never
export type InferAsyncOkTypes<R> = R extends ResultAsync<infer T, unknown> ? T : never
export type InferAsyncErrTypes<R> = R extends ResultAsync<unknown, infer E> ? E : never

const appendValueToEndOfList = <T>(value: T) => (list: T[]): T[] => [...list, value]

/**
* Short circuits on the FIRST Err value that we find
*/
export const combineResultList = <T, E>(
resultList: readonly Result<T, E>[],
): Result<readonly T[], E> =>
resultList.reduce(
(acc, result) =>
acc.isOk()
? result.isErr()
? err(result.error)
: acc.map(appendValueToEndOfList(result.value))
: acc,
ok([]) as Result<T[], E>,
)
): Result<readonly T[], E> => {
let acc = ok([]) as Result<T[], E>

for (const result of resultList) {
if (result.isErr()) {
acc = err(result.error)
break
} else {
acc.map((list) => list.push(result.value))
}
}
return acc
}

/* This is the typesafe version of Promise.all
*
Expand All @@ -62,18 +63,21 @@ export const combineResultAsyncList = <T, E>(
*/
export const combineResultListWithAllErrors = <T, E>(
resultList: readonly Result<T, E>[],
): Result<readonly T[], E[]> =>
resultList.reduce(
(acc, result) =>
result.isErr()
? acc.isErr()
? err([...acc.error, result.error])
: err([result.error])
: acc.isErr()
? acc
: ok([...acc.value, result.value]),
ok([]) as Result<T[], E[]>,
)
): Result<readonly T[], E[]> => {
let acc = ok([]) as Result<T[], E[]>

for (const result of resultList) {
if (result.isErr() && acc.isErr()) {
acc.error.push(result.error)
} else if (result.isErr() && acc.isOk()) {
acc = err([result.error])
} else if (result.isOk() && acc.isOk()) {
acc.value.push(result.value)
}
// do nothing when result.isOk() && acc.isErr()
}
return acc
}

export const combineResultAsyncListWithAllErrors = <T, E>(
asyncResultList: readonly ResultAsync<T, E>[],
Expand Down

0 comments on commit 2062c32

Please sign in to comment.