From 75a8b7d318a14c739cc6d694109ce14e4f2b8554 Mon Sep 17 00:00:00 2001 From: Henrik Giesel Date: Sun, 21 Mar 2021 21:07:35 +0100 Subject: [PATCH] Improve implementation of asyncRefresh --- ts/graphs/async.ts | 28 ++++++++------- ts/graphs/asyncRefresh.ts | 71 ++++++++++++++++++++++++++++----------- ts/tsconfig.json | 2 +- 3 files changed, 67 insertions(+), 34 deletions(-) diff --git a/ts/graphs/async.ts b/ts/graphs/async.ts index e03185dbf..5ce71974f 100644 --- a/ts/graphs/async.ts +++ b/ts/graphs/async.ts @@ -1,28 +1,30 @@ import { Readable, readable, derived } from "svelte/store"; export interface AsyncData { - value: Readable, - error: Readable, - pending: Readable, - success: Readable, + value: Readable; + error: Readable; + pending: Readable; + success: Readable; } - function useAsync(asyncFunction: () => Promise): AsyncData { const promise = asyncFunction(); const value = readable(null, (set: (value: T) => void) => { - promise.then((value: T) => set(value)) - }) + promise.then((value: T) => set(value)); + }); const error = readable(null, (set: (value: E) => void) => { - promise.catch((value: E) => set(value)) - }) + promise.catch((value: E) => set(value)); + }); - const pending = derived([value, error], (_, set) => set(false), true) - const success= derived([value], (_, set) => set(true), false) + const pending = readable(true, (set: (value: boolean) => void) => { + promise.finally(() => set(false)); + }); - return { value, error, pending, success } + const success = derived([value], (_, set) => set(true), false); + + return { value, error, pending, success }; } -export default useAsync +export default useAsync; diff --git a/ts/graphs/asyncRefresh.ts b/ts/graphs/asyncRefresh.ts index 3d813cbab..660eacfd1 100644 --- a/ts/graphs/asyncRefresh.ts +++ b/ts/graphs/asyncRefresh.ts @@ -1,30 +1,61 @@ -import { Readable, derived, get } from "svelte/store"; -import useAsync, { AsyncData } from "./async"; +import { Readable, readable, derived } from "svelte/store"; interface AsyncRefreshData { - value: Readable, - error: Readable, - pending: Readable, - success: Readable, - loading: Readable, + value: Readable; + error: Readable; + pending: Readable; + success: Readable; + loading: Readable; } +function useAsyncRefresh( + asyncFunction: () => Promise, + dependencies: [Readable, ...Readable[]] +): AsyncRefreshData { + const initial = asyncFunction(); + const promise = derived(dependencies, (_, set) => set(asyncFunction()), initial); -function useAsyncRefresh(asyncFunction: () => Promise, dependencies: [Readable, ...Readable[]]): AsyncRefreshData { - const current = derived( - dependencies, - (_, set: (value: AsyncData) => void) => set(useAsync(asyncFunction)), - useAsync(asyncFunction), - ) + const value = derived( + promise, + ($promise, set: (value: T | null) => void) => { + $promise.then((value: T) => set(value)); + return () => set(null); + }, + null + ); - const value = derived(current, ($current, set: (value: T | null) => void) => set(get($current.value)), null) - const error = derived(current, ($current, set: (error: E | null) => void) => set(get($current.error)), null) + const error = derived( + promise, + ($promise, set: (error: E | null) => void) => { + $promise.catch((error: E) => set(error)); + return () => set(null); + }, + null + ); - const pending = derived(current, (_, set) => set(false), true) - const success = derived(current, ($current, set: (success: boolean) => void) => set(get($current.success)), false) - const loading = derived(current, ($current, set: (pending: boolean) => void) => set(get($current.pending)), true) + const pending = readable(true, (set: (value: boolean) => void) => { + initial.finally(() => set(false)); + }); - return { value, error, pending, success, loading } + const loading = derived( + [value, error], + (_, set) => { + set(false); + return () => set(true); + }, + true + ); + + const success = derived( + [value], + (_, set) => { + set(true); + return () => set(false); + }, + false + ); + + return { value, error, pending, loading, success }; } -export default useAsyncRefresh +export default useAsyncRefresh; diff --git a/ts/tsconfig.json b/ts/tsconfig.json index 883e2130b..52befdcf3 100644 --- a/ts/tsconfig.json +++ b/ts/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { "target": "es6", "module": "es6", - "lib": ["es2017", "es2019.array", "dom", "dom.iterable"], + "lib": ["es2017", "es2019.array", "es2018.promise", "dom", "dom.iterable"], "baseUrl": ".", "paths": { "anki/*": ["../bazel-bin/ts/lib/*"]