Skip to content

Commit

Permalink
Replace AsyncAction with AsyncFetch
Browse files Browse the repository at this point in the history
  • Loading branch information
lemonmade committed May 16, 2024
1 parent a3ea895 commit ddc5a6b
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 21 deletions.
5 changes: 5 additions & 0 deletions .changeset/gentle-snakes-refuse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@quilted/async': patch
---

Replace `AsyncAction` with `AsyncFetch`
50 changes: 29 additions & 21 deletions packages/async/source/AsyncFetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,43 @@ export interface AsyncFetchFunction<Data = unknown, Input = unknown> {

export class AsyncFetch<Data = unknown, Input = unknown> {
get status() {
return this.finished.value?.status ?? 'pending';
}

get isRunning() {
return this.running.value != null;
return this.finishedSignal.value?.status ?? 'pending';
}

get value() {
return this.finished.value?.value;
return this.finishedSignal.value?.value;
}

get error() {
return this.finished.value?.error;
return this.finishedSignal.value?.error;
}

get promise(): AsyncFetchPromise<Data, Input> {
return (
this.running.value?.promise ??
this.finished.value?.promise ??
this.runningSignal.value?.promise ??
this.finishedSignal.value?.promise ??
this.initial.promise
);
}

private readonly running = signal<AsyncFetchCall<Data, Input> | undefined>(
undefined,
);
private readonly finished = signal<AsyncFetchCall<Data, Input> | undefined>(
undefined,
);
get running() {
return this.runningSignal.value;
}

get isRunning() {
return this.runningSignal.value != null;
}

get finished() {
return this.finishedSignal.value;
}

private readonly runningSignal = signal<
AsyncFetchCall<Data, Input> | undefined
>(undefined);
private readonly finishedSignal = signal<
AsyncFetchCall<Data, Input> | undefined
>(undefined);
private readonly function: AsyncFetchFunction<Data, Input>;
private readonly initial: AsyncFetchCall<Data, Input>;

Expand All @@ -61,28 +69,28 @@ export class AsyncFetch<Data = unknown, Input = unknown> {
input?: Input,
{signal}: {signal?: AbortSignal} = {},
): AsyncFetchPromise<Data, Input> => {
const wasRunning = this.running.peek();
const wasRunning = this.runningSignal.peek();

const fetchCall =
wasRunning == null &&
this.finished.peek() == null &&
this.finishedSignal.peek() == null &&
!this.initial.signal.aborted
? this.initial
: new AsyncFetchCall(this.function);

const finalizeFetchCall = () => () => {
if (this.running.peek() === fetchCall) {
this.running.value = undefined;
if (this.runningSignal.peek() === fetchCall) {
this.runningSignal.value = undefined;
}

if (fetchCall.signal.aborted) return;

this.finished.value = fetchCall;
this.finishedSignal.value = fetchCall;
};

fetchCall.call(input, {signal}).then(finalizeFetchCall, finalizeFetchCall);

this.running.value = fetchCall;
this.runningSignal.value = fetchCall;
wasRunning?.abort();

return fetchCall.promise;
Expand Down

0 comments on commit ddc5a6b

Please sign in to comment.