Skip to content

Commit

Permalink
feat: return task state (#14)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: task.group() will return an array with clear() method, and each element is a TaskAPI
  • Loading branch information
privatenumber committed Feb 10, 2022
1 parent ef13baf commit a679d36
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 38 deletions.
28 changes: 19 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

<p align="center">
<img src=".github/tasuku.svg">
<br>
Expand Down Expand Up @@ -174,7 +173,7 @@ const groupedTasks = await task.group(task => [
// ...
])

console.log(groupedTasks.results) // ['one', 'two']
console.log(groupedTasks) // [{ result: 'one' }, { result: 'two' }]
```

<img src=".github/example-5.gif">
Expand Down Expand Up @@ -229,10 +228,13 @@ await Promise.all([

Returns a Promise that resolves with object:
```ts
type Task = {
// The result from taskFunction
type TaskAPI = {
// Result from taskFunction
result: any

// State of the task
state: 'error' | 'warning' | 'success'

// Invoke to clear the results from the terminal
clear: () => void
}
Expand All @@ -248,7 +250,7 @@ The name of the task displayed.
#### taskFunction
Type:
```ts
type TaskFunction = (taskApi: {
type TaskFunction = (taskInnerApi: {
task: createTask
setTitle: (title: string) => void
setStatus: (status: string) => void
Expand Down Expand Up @@ -287,11 +289,19 @@ Call with a string or Error instance to put the task in an error state. Tasks au
### task.group(createTaskFunctions, options)
Returns a Promise that resolves with object:
```ts
type TaskGroup = {
// The results from the taskFunctions
results: any[]
// The results from the taskFunctions
type TaskGroupAPI = {
// Result from taskFunction
result: any

// Invoke to clear the results from the terminal
// State of the task
state: 'error' | 'warning' | 'success'

// Invoke to clear the task result
clear: () => void
}[] & {

// Invoke to clear ALL results
clear: () => void
}
```
Expand Down
35 changes: 22 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,18 @@ function registerTask<T>(
taskList.isRoot = true;
}

const taskState = arrayAdd(taskList, {
const task = arrayAdd(taskList, {
title: taskTitle,
state: 'pending',
children: [],
});

return {
task,
async [runSymbol]() {
const api = createTaskInnerApi(taskState);
const api = createTaskInnerApi(task);

taskState.state = 'loading';
task.state = 'loading';

let taskResult;
try {
Expand All @@ -78,14 +79,14 @@ function registerTask<T>(
throw error;
}

if (taskState.state === 'loading') {
taskState.state = 'success';
if (task.state === 'loading') {
task.state = 'success';
}

return taskResult;
},
clear() {
arrayRemove(taskList, taskState);
arrayRemove(taskList, task);

if (taskList.isRoot && taskList.length === 0) {
app!.remove();
Expand All @@ -102,12 +103,15 @@ function createTaskFunction(
title,
taskFunction,
) => {
const taskState = registerTask(taskList, title, taskFunction);
const result = await taskState[runSymbol]();
const registeredTask = registerTask(taskList, title, taskFunction);
const result = await registeredTask[runSymbol]();

return {
result,
clear: taskState.clear,
get state() {
return registeredTask.task.state;
},
clear: registeredTask.clear,
};
};

Expand All @@ -126,21 +130,26 @@ function createTaskFunction(

const results = (await pMap(
tasksQueue,
async taskApi => await taskApi[runSymbol](),
async taskApi => ({
result: await taskApi[runSymbol](),
get state() {
return taskApi.task.state;
},
clear: taskApi.clear,
}),
{
concurrency: 1,
...options,
},
)) as any;

return {
results,
return Object.assign(results, {
clear() {
for (const taskApi of tasksQueue) {
taskApi.clear();
}
},
};
});
};

return task;
Expand Down
11 changes: 7 additions & 4 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { Options } from 'p-map';

type State = 'pending' | 'loading' | 'error' | 'warning' | 'success';

export type TaskObject = {
title: string;
state: 'pending' | 'loading' | 'error' | 'warning' | 'success';
state: State;
children: TaskObject[];
status?: string;
output?: string;
Expand All @@ -27,11 +29,13 @@ export const runSymbol: unique symbol = Symbol('run');

export type RegisteredTask<T = any> = {
[runSymbol]: () => Promise<T>; // ReturnType<TaskFunction<T>>;
task: TaskObject;
clear: () => void;
};

export type TaskAPI<Result = any> = {
result: Result;
state: State;
clear: () => void;
};

Expand All @@ -54,13 +58,12 @@ type TaskGroupResults<
> = {
[Key in keyof RegisteredTasks]: (
RegisteredTasks[Key] extends RegisteredTask<infer ReturnType>
? ReturnType
? TaskAPI<ReturnType>
: unknown
);
};

export type TaskGroupAPI<Results = any> = {
results: Results;
export type TaskGroupAPI<Results = any[]> = Results & {
clear(): void;
};

Expand Down
49 changes: 38 additions & 11 deletions tests/tasuku.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,18 @@ test('group tasks', async () => {
task('boolean', async () => false),
]);

expect<[
number,
string,
boolean,
]>(groupTasks.results).toEqual([
123,
'hello',
false,
]);
expect<{ result: number }>(groupTasks[0]).toMatchObject({
state: 'success',
result: 123,
});
expect<{ result: string }>(groupTasks[1]).toMatchObject({
state: 'success',
result: 'hello',
});
expect<{ result: boolean }>(groupTasks[2]).toMatchObject({
state: 'success',
result: false,
});
});

test('group tasks - concurrency - series', async () => {
Expand All @@ -73,7 +76,19 @@ test('group tasks - concurrency - series', async () => {
const elapsed = Date.now() - startTime;

expect(elapsed > 300 && elapsed < 400).toBe(true);
expect(groupTasks.results).toEqual([1, 2, 3]);

expect<{ result: number }>(groupTasks[0]).toMatchObject({
state: 'success',
result: 1,
});
expect<{ result: number }>(groupTasks[1]).toMatchObject({
state: 'success',
result: 2,
});
expect<{ result: number }>(groupTasks[2]).toMatchObject({
state: 'success',
result: 3,
});
});

test('group tasks - concurrency - parallel', async () => {
Expand All @@ -96,5 +111,17 @@ test('group tasks - concurrency - parallel', async () => {
const elapsed = Date.now() - startTime;

expect(elapsed > 100 && elapsed < 200).toBe(true);
expect(groupTasks.results).toEqual([1, 2, 3]);

expect<{ result: number }>(groupTasks[0]).toMatchObject({
state: 'success',
result: 1,
});
expect<{ result: number }>(groupTasks[1]).toMatchObject({
state: 'success',
result: 2,
});
expect<{ result: number }>(groupTasks[2]).toMatchObject({
state: 'success',
result: 3,
});
});
4 changes: 3 additions & 1 deletion tests/tasuku.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ const groupApi = await task.group(task => [
task('title', async () => 'string'),
]);

expectType<[boolean, number, string]>(groupApi.results);
expectType<boolean>(groupApi[0].result);
expectType<number>(groupApi[1].result);
expectType<string>(groupApi[2].result);

0 comments on commit a679d36

Please sign in to comment.