resources.ts (1988B)
1 // A Resource is an object with a read method returning the payload 2 export interface Resource<Payload> { 3 read: () => Payload; 4 } 5 6 export type status = "pending" | "success" | "error"; 7 8 // this function let us get a new function using the asyncFn we pass 9 // this function also receives a payload and return us a resource with 10 // that payload assigned as type 11 export function createResource<Payload>( 12 asyncFn: () => Promise<Payload> 13 ): Resource<Payload> { 14 // we start defining our resource is on a pending status 15 let status: status = "pending"; 16 // and we create a variable to store the result 17 let result: Payload | Error; 18 // then we immediately start running the `asyncFn` function 19 // and we store the resulting promise 20 const promise = asyncFn().then( 21 (r: Payload) => { 22 // once it's fulfilled we change the status to success 23 // and we save the returned value as result 24 status = "success"; 25 result = r; 26 }, 27 (error: Error) => { 28 // once it's rejected we change the status to error 29 // and we save the returned error as result 30 status = "error"; 31 result = error; 32 } 33 ); 34 // lately we return an error object with the read method 35 return { 36 read(): Payload { 37 // here we will check the status value 38 switch (status) { 39 case "pending": { 40 // if it's still pending we throw the promise 41 // throwing a promise is how Suspense know our component is not ready 42 throw promise; 43 } 44 case "error": { 45 // if it's error we throw the error 46 throw result as Error; 47 } 48 case "success": { 49 // if it's success we return the result 50 return result as Payload; 51 } 52 } 53 }, 54 }; 55 }