Skip to content

Commit a8cc72a

Browse files
committed
feat: add Task.wrapPromiseCreator
1 parent 10e1f85 commit a8cc72a

File tree

3 files changed

+72
-0
lines changed

3 files changed

+72
-0
lines changed

docs/task-static.md

+25
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,31 @@ type fromLazyPromise = <S, E = any>(
310310
{% endtab %}
311311
{% endtabs %}
312312
313+
## wrapPromiseCreator
314+
315+
Given a function which returns a Promise, create a new function which given the same arguments will now return a Task instead.
316+
317+
{% tabs %}
318+
{% tab title="Usage" %}
319+
320+
```typescript
321+
const taskFetch = wrapPromiseCreator(fetch)
322+
const task: Task<never, Response> = taskFetch(URL)
323+
```
324+
325+
{% endtab %}
326+
327+
{% tab title="Type Definition" %}
328+
329+
```typescript
330+
type wrapPromiseCreator = <S, Args extends unknown[]>(
331+
fn: (...args: Args) => Promise<S>,
332+
) => (...args: Args): Task<unknown, S>
333+
```
334+
335+
{% endtab %}
336+
{% endtabs %}
337+
313338
## race
314339
315340
Creates a task that will always run an array of tasks in **parallel**. The first task to finish is the resulting error or value. Useful for implementing network request timeouts by racing a task which fails in x milliseconds and a task which makes the request.

src/Task/Task.ts

+10
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,15 @@ export const fromLazyPromise = <S>(
227227
getPromise: () => S | Promise<S>,
228228
): Task<unknown, S> => succeedBy(getPromise).chain(fromPromise)
229229

230+
/**
231+
* Given a function that returns a promise, return a new function that
232+
* lazily returns a Task instead.
233+
* @param fn A function which returns a promise
234+
*/
235+
export const wrapPromiseCreator = <S, Args extends unknown[]>(
236+
fn: (...args: Args) => Promise<S>,
237+
) => (...args: Args): Task<unknown, S> => fromLazyPromise(() => fn(...args))
238+
230239
/**
231240
* Given a task, create a Promise which resolves when the task does.
232241
* @param task The task we will convert to a promise.
@@ -700,6 +709,7 @@ export class Task<E, S> implements PromiseLike<S> {
700709
public static fromPromise = fromPromise
701710
public static fromPromises = fromPromises
702711
public static fromLazyPromise = fromLazyPromise
712+
public static wrapPromiseCreator = wrapPromiseCreator
703713
public static race = race
704714
public static external = external
705715
public static emitter = emitter
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* eslint-disable @typescript-eslint/no-unused-vars */
2+
import { wrapPromiseCreator } from "../Task"
3+
import { ERROR_RESULT, SUCCESS_RESULT } from "./util"
4+
5+
describe("wrapPromiseCreator", () => {
6+
test("should succeed when a promise succeeds", async () => {
7+
const resolve = jest.fn()
8+
const reject = jest.fn()
9+
10+
const promise = Promise.resolve(SUCCESS_RESULT)
11+
const makePromise = (_a: string, _b: number) => promise
12+
13+
const runTask = wrapPromiseCreator(makePromise)
14+
runTask("test", 1).fork(reject, resolve)
15+
16+
await promise
17+
18+
expect(resolve).toBeCalledWith(SUCCESS_RESULT)
19+
expect(reject).not.toBeCalled()
20+
})
21+
22+
test("should fail when a promise fails", async () => {
23+
const resolve = jest.fn()
24+
const reject = jest.fn()
25+
26+
const promise = Promise.reject(ERROR_RESULT)
27+
const makePromise = (_a: number, _b: string) => promise
28+
29+
const runTask = wrapPromiseCreator(makePromise)
30+
runTask(1, "test").fork(reject, resolve)
31+
32+
await promise.catch(() => void 0)
33+
34+
expect(reject).toBeCalledWith(ERROR_RESULT)
35+
expect(resolve).not.toBeCalled()
36+
})
37+
})

0 commit comments

Comments
 (0)