1- import { useContext , useRef } from 'react' ;
1+ import { useContext , useState , useRef } from 'react' ;
22import TransporterContext from './TransporterContext' ;
33
44const PENDING = 'pending' ;
@@ -20,67 +20,64 @@ export default function useDispatcher() {
2020 throw new Error ( 'Dispatcher hook is used outside of TransporterContext.' ) ;
2121 }
2222
23+ const [ state , setState ] = useState ( {
24+ ok : null ,
25+ loading : false ,
26+ executed : false ,
27+ error : null ,
28+ } ) ;
29+
2330 const instances = useRef ( [ ] ) ;
2431
25- return {
26- dispatch ( ast , options ) {
27- const operation = ast . definitions . find (
28- ( def ) => def . kind === 'OperationDefinition' ,
29- ) ?. operation ;
32+ const updateState = ( instance ) => {
33+ const latestInstance = getLatestInstance ( instances ) ;
34+
35+ if ( latestInstance !== instance ) {
36+ return ;
37+ }
3038
31- if ( operation !== 'query' && operation !== 'mutation' ) {
32- throw new Error (
33- 'No operation found. Must be either "query" or "mutation".' ,
34- ) ;
35- }
39+ const { status } = instance . resource ;
3640
37- const instance =
38- operation === 'query'
39- ? context . client . query ( ast , options )
40- : context . client . mutate ( ast , options ) ;
41+ setState ( {
42+ ok : status === PENDING ? null : status === FULFILLED ,
43+ loading : status === PENDING ,
44+ executed : status === FULFILLED || status === REJECTED ,
45+ error : status !== REJECTED ? null : instance . resource . response ,
46+ } ) ;
47+ } ;
4148
42- instances . current . push ( instance ) ;
49+ const dispatch = ( ast , options ) => {
50+ const operation = ast . definitions . find (
51+ ( def ) => def . kind === 'OperationDefinition' ,
52+ ) ?. operation ;
4353
44- // Return cached selector set.
45- return instance . resource . promise . then ( ( ) =>
46- instance . cache . graphData . getQuery ( ) ,
54+ if ( operation !== 'query' && operation !== 'mutation' ) {
55+ throw new Error (
56+ 'No operation found. Must be either "query" or "mutation".' ,
4757 ) ;
48- } ,
49- get ok ( ) {
50- const instance = getLatestInstance ( instances ) ;
51-
52- if ( ! instance || instance . status === PENDING ) {
53- return null ;
54- }
55-
56- return instance . status === FULFILLED ;
57- } ,
58- get loading ( ) {
59- const instance = getLatestInstance ( instances ) ;
60-
61- if ( ! instance ) {
62- return false ;
63- }
64-
65- return instance . status === PENDING ;
66- } ,
67- get executed ( ) {
68- const instance = getLatestInstance ( instances ) ;
69-
70- if ( ! instance ) {
71- return false ;
72- }
73-
74- return instance . status === FULFILLED || instance . status === REJECTED ;
75- } ,
76- get error ( ) {
77- const instance = getLatestInstance ( instances ) ;
78-
79- if ( ! instance || instance . status !== REJECTED ) {
80- return null ;
81- }
82-
83- return instance . response ;
84- } ,
58+ }
59+
60+ const instance =
61+ operation === 'query'
62+ ? context . client . query ( ast , options )
63+ : context . client . mutate ( ast , options ) ;
64+
65+ instances . current . push ( instance ) ;
66+
67+ updateState ( instance ) ;
68+
69+ // Update state and return cached selector set.
70+ return instance . resource . promise . then (
71+ ( ) => {
72+ updateState ( instance ) ;
73+ return instance . cache . graphData . getQuery ( ) ;
74+ } ,
75+ ( err ) => {
76+ updateState ( instance ) ;
77+ throw err ;
78+ } ,
79+ ) ;
8580 } ;
81+
82+ return [ dispatch , state ] ;
8683}
0 commit comments