1
+ // Copyright 2022 MFB Technologies, Inc.
2
+
3
+ import { AsyncRequestStatus } from "@mfbtech/react-async-renderer"
4
+ import { useEffect , useState } from "react"
5
+
6
+ /** starts a process that takes the specified amount of time and returns the specified data. */
7
+ export function useLongRunningProcess < T > ( processDurationInSeconds : number , processData : T , skip : boolean ) {
8
+ const [ status , setStatus ] = useState < AsyncRequestStatus > ( AsyncRequestStatus . INIT )
9
+ const [ error , setError ] = useState < null | string > ( null )
10
+ const [ data , setData ] = useState < null | T > ( null )
11
+ const [ restart , setRestart ] = useState ( true )
12
+
13
+ useEffect ( ( ) => {
14
+ if ( restart === false ) {
15
+ return
16
+ }
17
+ if ( skip ) {
18
+ return
19
+ }
20
+ setStatus ( AsyncRequestStatus . PENDING )
21
+ startLongRunningProcess ( processDurationInSeconds , processData ) . then ( data => {
22
+ setError ( null )
23
+ setStatus ( AsyncRequestStatus . FULFILLED )
24
+ setData ( data )
25
+ } ) . catch ( ( err : unknown ) => {
26
+ setData ( null )
27
+ setStatus ( AsyncRequestStatus . ERROR )
28
+ let errorMessage = "error"
29
+ if ( typeof err === "string" ) {
30
+ errorMessage = err
31
+ }
32
+ else if ( err instanceof Error ) {
33
+ errorMessage = err . message
34
+ }
35
+ setError ( errorMessage )
36
+ } ) . finally ( ( ) => {
37
+ setRestart ( false )
38
+ } )
39
+ } , [ processData , processDurationInSeconds , restart , skip ] )
40
+
41
+ return {
42
+ status,
43
+ error,
44
+ data,
45
+ reset : ( ) => {
46
+ setStatus ( AsyncRequestStatus . INIT )
47
+ setError ( null )
48
+ setData ( null )
49
+ setRestart ( true )
50
+ }
51
+ }
52
+ }
53
+
54
+ function startLongRunningProcess < T > ( processDurationInSeconds : number , processData : T ) : Promise < T > {
55
+ return new Promise ( ( resolve ) => {
56
+ setTimeout ( ( ) => {
57
+ resolve ( processData )
58
+ } , processDurationInSeconds ) ;
59
+ } )
60
+ }
0 commit comments