mirror of
https://github.com/urbit/shrub.git
synced 2024-11-28 13:54:20 +03:00
interface: add suspense utils
This commit is contained in:
parent
b0ed02f436
commit
a25911319e
38
pkg/interface/src/logic/lib/suspend.ts
Normal file
38
pkg/interface/src/logic/lib/suspend.ts
Normal file
@ -0,0 +1,38 @@
|
||||
export type SuspendState = 'result' | 'error' | 'pending';
|
||||
|
||||
export interface Suspender<T> {
|
||||
read: () => T;
|
||||
}
|
||||
|
||||
export function suspend<T>(awaiting: Promise<T>): Suspender<T> {
|
||||
let state: SuspendState = 'pending';
|
||||
let result: T | null = null;
|
||||
|
||||
const promise = awaiting
|
||||
.then((res) => {
|
||||
state = 'result';
|
||||
result = res;
|
||||
})
|
||||
.catch((e) => {
|
||||
state = 'error';
|
||||
result = e;
|
||||
});
|
||||
|
||||
return {
|
||||
read: () => {
|
||||
if (state === 'result') {
|
||||
return result!;
|
||||
} else if (state === 'error') {
|
||||
throw result;
|
||||
} else {
|
||||
throw promise;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function suspendWithResult<T>(result: T): Suspender<T> {
|
||||
return {
|
||||
read: () => result
|
||||
};
|
||||
}
|
@ -539,3 +539,12 @@ export function binaryIndexOf(arr: BigInteger[], target: BigInteger): number | u
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export async function jsonFetch<T>(info: RequestInfo, init?: RequestInit): Promise<T> {
|
||||
const res = await fetch(info, init);
|
||||
if(!res.ok) {
|
||||
throw new Error('Bad Fetch Response');
|
||||
}
|
||||
const data = await res.json();
|
||||
return data as T;
|
||||
}
|
||||
|
32
pkg/interface/src/views/components/AsyncFallback.tsx
Normal file
32
pkg/interface/src/views/components/AsyncFallback.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import React from 'react';
|
||||
|
||||
interface AsyncFallbackProps {
|
||||
fallback?: JSX.Element;
|
||||
}
|
||||
class AsyncFallback extends React.Component<
|
||||
AsyncFallbackProps,
|
||||
{
|
||||
error: boolean;
|
||||
}
|
||||
> {
|
||||
constructor(props: AsyncFallbackProps) {
|
||||
super(props);
|
||||
this.state = { error: false };
|
||||
}
|
||||
|
||||
componentDidCatch() {
|
||||
this.setState({ error: true });
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const { fallback, children } = this.props;
|
||||
return (
|
||||
<React.Suspense fallback={fallback}>
|
||||
{this.state.error ? fallback : children}
|
||||
</React.Suspense>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AsyncFallback;
|
Loading…
Reference in New Issue
Block a user