feat: unified API — AsyncResult overloads, pipeAsync/flowAsync, integration
Summary
Complete the unified API by ensuring all functions (map, flatMap, tap, getOrElse, match, etc.) work natively with AsyncResult without explicit .then() unwrapping, and add pipeAsync/flowAsync for full async pipeline support.
Motivation
The project defines a unified API in index.ts where functions like map, flatMap, tap, getOrElse, match should work transparently on both Result and AsyncResult. This issue completes that integration.
Status: Blocked
This issue is blocked by all other implementation issues:
retry-policy-builder — retry functions need unified API treatment
composition-additions — tapBoth, dual() pattern needed
repeat — repeat functions need unified API treatment
timeout-standalone — timeout functions need unified API treatment
serialization — serialize/deserialize need unified API treatment
error-panic-and-matchpartial — matchErrorPartial needed
Do not start this issue until all 6 other issues are completed.
Deliverables
1. Native AsyncResult support in unified API
Currently some functions work with AsyncResult implicitly via thenable pattern, but not all overloads are complete. Ensure:
import { Result, pipe, AsyncResult } from '@deessejs/fp';
// These should work directly without explicit .then() unwrapping
const result: AsyncResult<User, NetworkError> = fetchUser(id);
pipe(
result,
Result.map(user => user.email), // works on AsyncResult
Result.tap(email => console.log(email)), // works on AsyncResult
Result.flatMap(email => fetchProfile(email)), // works on AsyncResult
Result.getOrElse('anonymous@example.com') // works on AsyncResult
);
Functions requiring unified overloads:
| Function |
Must work on AsyncResult |
Result.map |
✅ |
Result.flatMap / andThen |
✅ |
Result.mapErr |
✅ |
Result.tap |
✅ |
Result.tapErr |
✅ |
Result.tapBoth |
✅ |
Result.getOrElse |
✅ |
Result.getOrCompute |
✅ |
Result.unwrap |
✅ |
Result.unwrapOr |
✅ |
Result.unwrapOrCompute |
✅ |
Result.orElse |
✅ |
Result.match |
✅ |
Result.isOk |
✅ |
Result.isErr |
✅ |
Result.toNullable |
✅ |
Result.toUndefined |
✅ |
Result.toMaybe |
✅ |
Result.swap |
✅ |
Result.all |
✅ |
Result.race |
✅ |
Result.traverse |
✅ |
Result.allSettled |
✅ |
2. pipeAsync / flowAsync for async chains
import { pipeAsync, flowAsync, Result } from '@deessejs/fp';
// Async pipeline — awaits promises automatically
const result = await pipeAsync(
userId,
fetchUser, // Promise<Result<User, E>>
Result.tap(user => log(user)),
Result.map(user => user.email),
Result.flatMap(email => fetchProfile(email)), // Promise<Result<Profile, E>>
Result.getOrElse('anonymous@example.com')
);
// flowAsync creates a reusable async pipeline
const processEmail = flowAsync(
fetchUser,
Result.tap(user => log(user)),
Result.map(user => user.email)
);
Key difference from pipe:
pipe passes values synchronously through functions
pipeAsync detects when a function returns a Promise and awaits it automatically
- Both Ok and Err paths are handled correctly through async chains
3. Integration tests
Comprehensive tests that verify the unified API works end-to-end across all modules:
describe('Unified API', () => {
it('map works on AsyncResult', async () => {
const asyncResult: AsyncResult<User, E> = Promise.resolve(ok({ id: '1', name: 'Alice' }));
const result = await pipeAsync(
asyncResult,
Result.map(user => user.name)
);
expect(result).toEqual(ok('Alice'));
});
it('flatMap chains AsyncResults correctly', async () => { /* ... */ });
it('tapBoth observes AsyncResult correctly', async () => { /* ... */ });
it('retry result works with unified API', async () => { /* ... */ });
it('repeat result works with unified API', async () => { /* ... */ });
it('timeout result works with unified API', async () => { /* ... */ });
it('serialized result roundtrips correctly', async () => { /* ... */ });
});
4. Result.gen / Result.await integration
Ensure Result.gen and Result.await work correctly with all error types created in the new modules:
const result = await Result.gen(async function* () {
const user = yield* Result.await(fetchUser(id)); // AsyncResult
const profile = yield* Result.await(fetchProfile(user.id));
return { user, profile };
});
// Result<{ user: User, profile: Profile }, NetworkError | ValidationError | ...>
Dependencies
All 6 other issues must be completed first:
retry-policy-builder
composition-additions
repeat
timeout-standalone
serialization
error-panic-and-matchpartial
References
feat: unified API — AsyncResult overloads, pipeAsync/flowAsync, integration
Summary
Complete the unified API by ensuring all functions (
map,flatMap,tap,getOrElse,match, etc.) work natively withAsyncResultwithout explicit.then()unwrapping, and addpipeAsync/flowAsyncfor full async pipeline support.Motivation
The project defines a unified API in
index.tswhere functions likemap,flatMap,tap,getOrElse,matchshould work transparently on bothResultandAsyncResult. This issue completes that integration.Status: Blocked
This issue is blocked by all other implementation issues:
retry-policy-builder— retry functions need unified API treatmentcomposition-additions—tapBoth,dual()pattern neededrepeat— repeat functions need unified API treatmenttimeout-standalone— timeout functions need unified API treatmentserialization— serialize/deserialize need unified API treatmenterror-panic-and-matchpartial—matchErrorPartialneededDo not start this issue until all 6 other issues are completed.
Deliverables
1. Native AsyncResult support in unified API
Currently some functions work with
AsyncResultimplicitly via thenable pattern, but not all overloads are complete. Ensure:Functions requiring unified overloads:
Result.mapResult.flatMap/andThenResult.mapErrResult.tapResult.tapErrResult.tapBothResult.getOrElseResult.getOrComputeResult.unwrapResult.unwrapOrResult.unwrapOrComputeResult.orElseResult.matchResult.isOkResult.isErrResult.toNullableResult.toUndefinedResult.toMaybeResult.swapResult.allResult.raceResult.traverseResult.allSettled2.
pipeAsync/flowAsyncfor async chainsKey difference from
pipe:pipepasses values synchronously through functionspipeAsyncdetects when a function returns aPromiseand awaits it automatically3. Integration tests
Comprehensive tests that verify the unified API works end-to-end across all modules:
4.
Result.gen/Result.awaitintegrationEnsure
Result.genandResult.awaitwork correctly with all error types created in the new modules:Dependencies
All 6 other issues must be completed first:
retry-policy-buildercomposition-additionsrepeattimeout-standaloneserializationerror-panic-and-matchpartialReferences
packages/fp/src/index.ts— current unified API implementation