Skip to content

Commit

Permalink
Add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
beerinho committed Apr 26, 2024
1 parent 01a2f61 commit 391e8a4
Showing 1 changed file with 157 additions and 4 deletions.
161 changes: 157 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# svelte-concurrency

Handle async task with ease thanks to `svelte-concurrency`
Handle async tasks with ease thanks to `svelte-concurrency`

## Async transform

One of the problems of Promises is that they can't be really canceled...once you invoke a promise there's no other way than do a series of if checks to "cancel" it. This is not the case for async generators. When you yield something back it's up to the invoker to continue calling next or stop indefinitely.
One of the problems with Promises is that they can't really be canceled; once you invoke a promise the only way to "cancel" it is to do a series of checks, but this isn't actually cancelling the promise. Whereas with async generators, when you yield something back it's up to the invoker to continue calling next or stop indefinitely.

> But generators are scary!
Understandable...that's why `svelte-concurrency` also includes a `vite` plugin that transforms your async functions in generators! This will transform your code from this:
We hear you, that's why `svelte-concurrency` also includes a `vite` plugin that transforms your async functions into generators! This will transform your code from this:

```ts
const instance = task(async () => {
Expand All @@ -25,7 +25,160 @@ const instance = task(async function* () {
});
```

allowing `svelte-concurrency` to interrupt your function if you call it mid-execution. And have no fear, this will only apply to async functions that you pass as parameter to the task function from `svelte-concurrency`!
meaning you get all of the functionality of generators without having to implement them yourself. And have no fear, this will only apply to async functions that you pass as a parameter to the `task` function from `svelte-concurrency`. (You can still use standard async promises as you would normally.)

## How to use `svelte-concurrency`

Install it using your favourite package manager:

```bash
pnpm install svelte-concurrency
```

Then put it to work immediately wherever you want cancellable promises.

## Task structure

All tasks will return a store with the same structure:

- error: Error - if an error occurred, it will be returned here,
- results: Array - all of the results from previous invocations of this task,
- last_successful: Any - the return value from the last successful run of the task
- is_loading: Boolean - whether the task is currently running on not

## Task types

There are several flavours of tasks to choose from (check out the interactive docs here [insert link to site when ready]).

With all types of task, it is possible to invoke it directly or add the `kind` parameter to the options object.

### Standard/default task

This simply gives you a task wrapper around your function. It will not handle any kind of concurrency for you.

```ts
<script>
import { task } from 'svelte-concurrency';

const my_task = task(async function* (param: number) {
await new Promise((r) => setTimeout(r, 2000));
return param * 2;
});
</script>
```

OR

```ts
<script>
import { task } from 'svelte-concurrency';

const my_task = task(async function* (param: number) {
await new Promise((r) => setTimeout(r, 2000));
return param * 2;
}, { kind: 'default' });
</script>
```

### Restartable task

This will cancel the oldest instance of the task and start a new instance of it. You can also provide a `max` that will only restart the oldest task instance if the threshold is exceeded.

```ts
<script>
import { task } from 'svelte-concurrency';

const my_task = task.restart(async function* (param: number) {
await new Promise((r) => setTimeout(r, 2000));
return param * 2;
}, { max: 3 });
</script>
```

OR

```ts
<script>
import { task } from 'svelte-concurrency';

const my_task = task(async function* (param: number) {
await new Promise((r) => setTimeout(r, 2000));
return param * 2;
}, { kind: 'restart', max: 3 });
</script>
```

Both of the above will result in 3 simultaneous tasks being allowed to run. Triggering the task a fourth time will cancel the oldest task.

### Droppable task

This will cancel any new instances of the task. You can also provide a `max` that will only drop the task instances if the threshold is exceeded.

```ts
<script>
import { task } from 'svelte-concurrency';

const my_task = task.drop(async function* (param: number) {
await new Promise((r) => setTimeout(r, 2000));
return param * 2;
}, { max: 3 });
</script>
```

OR

```ts
<script>
import { task } from 'svelte-concurrency';

const my_task = task(async function* (param: number) {
await new Promise((r) => setTimeout(r, 2000));
return param * 2;
}, { kind: 'drop', max: 3 });
</script>
```

Both of the above will result in 3 simultaneous tasks being allowed to run. Triggering the task a fourth time will be cancelled and won't retry automatically.

### Enqueue task

This will add all task instances to a list and each task will be run in order. You can also provide a `max` that will dictate the number of task instances that will run at the same time.

```ts
<script>
import { task } from 'svelte-concurrency';

const my_task = task.enqueue(async function* (param: number) {
await new Promise((r) => setTimeout(r, 2000));
return param * 2;
}, { max: 3 });
</script>
```

OR

```ts
<script>
import { task } from 'svelte-concurrency';

const my_task = task(async function* (param: number) {
await new Promise((r) => setTimeout(r, 2000));
return param * 2;
}, { kind: 'enqueue', max: 3 });
</script>
```

Both of the above will result in 3 simultaneous tasks being allowed to run. Any additional instances of the task will be added to a list and run when there is space in the queue.

### Accessing the task in the template

As the return value from the task wrapper is a store, you can access it just like you would with any other store:

```
{$my_task.is_loading}
{$my_task.last_successful}
{$my_task.error}
```

## How to write async transform tests?

Expand Down

0 comments on commit 391e8a4

Please sign in to comment.