Last active
October 22, 2019 17:40
-
-
Save cristovao-trevisan/01239119d4c1bd35cd3936d647026b87 to your computer and use it in GitHub Desktop.
Async Library API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 1. Internal API | |
interface Resource<Data, Props = any> { | |
// here goes the INTERNAL API provided by the core that | |
// should be used by other libraries/frameworks to provide | |
// the real user interface | |
// We can also provide an API for debugging and other tools | |
subscribe: (cb: () => Data) => UnsubscribeFunction, | |
run: (props: Props, options: RunOptions) => Data, | |
abort: () => void, | |
update: (props: Props, currentData: Data) => Data, | |
// ... | |
} | |
// 2. Declaration API (used by users, not related to any framework) | |
declare function createResource<Data, Props> (options: { | |
// this fn should probably have some accessors, like: AbortableRest, Rest, PaginatedRest, InfiniteScrollRest, GraphQL, ... | |
fn: (props: Props, currentData: Data | null) => Promise<Data>, | |
// this hash function decides which props trigger another run (like useEffect's second param). | |
hash?: (props: Props) => string, | |
// here is the CLIENT-SIDE api for this resource, like: | |
// - caching | |
// - pooling | |
// - ssr | |
// - middleware options (caching and pooling should probably be some kind of middleware) | |
// - etc | |
}) : Resource<Data, Props> | |
// 3. Framework API | |
// React API (just a rough example) | |
// this should handle subscription and call run when needed (useEffect most likely) | |
declare function useResource<Data, Props> (resource: Resource<Data, Props>, props: Props) : State<Data> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Metadata = {} | { | |
startedAt: Date, | |
duration: number, | |
runs: number, | |
// ... | |
} | |
interface InitialState { | |
data: null, | |
error: null, | |
pending: false, | |
resolved: false, | |
} | |
interface LoadingState { | |
data: null, | |
error: null, | |
pending: true, | |
resolved: false, | |
} | |
interface ResolvedState<Data> { | |
data: Data, | |
error: null, | |
pending: false, | |
resolved: true, | |
} | |
interface RejectedState<Data> { | |
data: null, | |
error: Error, | |
pending: false, | |
resolved: false, | |
} | |
interface ReloadingState<Data> { | |
data: Data, | |
error: null, | |
pending: true, | |
resolved: true, | |
} | |
type State<Data> = Metadata & ( | |
InitialState | |
| LoadingState | |
| ResolvedState<Data> | |
| RejectedState<Data> | |
| ReloadingState<Data> | |
) | |
type UnsubscribeFunction = () => void | |
interface RunOptions { | |
reload: boolean = false, | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// resource-definitions.ts (if using typescript) | |
interface UserInfo { | |
id: number, | |
name: string, | |
age: number, | |
photoUrl: string, | |
birthday: Date, | |
} | |
interface UserProps { | |
id: number, | |
} | |
type getUser = (id: string) => Promise<UserInfo> | |
// some resources.js file | |
import { createResource, useRest } from 'async-library' | |
export const userResource = createResource({ | |
fn: useRest('/users/info/{id}'), | |
}) | |
// ... | |
// in the component | |
import { useAsync } from 'react-async' | |
import { userResource } from '../../resources.js' | |
export const UserName = ({ id }) => { | |
const { | |
data: user, | |
pending, | |
error, | |
} = useAsync(UserResource, { id }) | |
if (data) return <div> {user.name} </div> | |
if (error) return <div> {error} </div> | |
return <div> Loading... </div> | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment