@@ -15,7 +15,79 @@ function actPolyfill(cb) {
1515 ReactDOM . render ( < div /> , document . createElement ( 'div' ) )
1616}
1717
18- const act = isomorphicAct || domAct || actPolyfill
18+ function getGlobalThis ( ) {
19+ /* istanbul ignore else */
20+ if ( typeof self !== 'undefined' ) {
21+ return self
22+ }
23+ /* istanbul ignore next */
24+ if ( typeof window !== 'undefined' ) {
25+ return window
26+ }
27+ /* istanbul ignore next */
28+ if ( typeof global !== 'undefined' ) {
29+ return global
30+ }
31+ /* istanbul ignore next */
32+ throw new Error ( 'unable to locate global object' )
33+ }
34+
35+ function setReactActEnvironment ( isReactActEnvironment ) {
36+ getGlobalThis ( ) . IS_REACT_ACT_ENVIRONMENT = isReactActEnvironment
37+ }
38+
39+ function getIsReactActEnvironment ( ) {
40+ return getGlobalThis ( ) . IS_REACT_ACT_ENVIRONMENT
41+ }
42+
43+ function withGlobalActEnvironment ( actImplementation ) {
44+ return callback => {
45+ const previousActEnvironment = getIsReactActEnvironment ( )
46+ setReactActEnvironment ( true )
47+ try {
48+ // The return value of `act` is always a thenable.
49+ let callbackNeedsToBeAwaited = false
50+ const actResult = actImplementation ( ( ) => {
51+ const result = callback ( )
52+ if (
53+ result !== null &&
54+ typeof result === 'object' &&
55+ typeof result . then === 'function'
56+ ) {
57+ callbackNeedsToBeAwaited = true
58+ }
59+ return result
60+ } )
61+ if ( callbackNeedsToBeAwaited ) {
62+ const thenable = actResult
63+ return {
64+ then : ( resolve , reject ) => {
65+ thenable . then (
66+ returnValue => {
67+ setReactActEnvironment ( previousActEnvironment )
68+ resolve ( returnValue )
69+ } ,
70+ error => {
71+ setReactActEnvironment ( previousActEnvironment )
72+ reject ( error )
73+ } ,
74+ )
75+ } ,
76+ }
77+ } else {
78+ setReactActEnvironment ( previousActEnvironment )
79+ return actResult
80+ }
81+ } catch ( error ) {
82+ // Can't be a `finally {}` block since we don't know if we have to immediately restore IS_REACT_ACT_ENVIRONMENT
83+ // or if we have to await the callback first.
84+ setReactActEnvironment ( previousActEnvironment )
85+ throw error
86+ }
87+ }
88+ }
89+
90+ const act = withGlobalActEnvironment ( isomorphicAct || domAct || actPolyfill )
1991
2092let youHaveBeenWarned = false
2193let isAsyncActSupported = null
@@ -131,6 +203,6 @@ function asyncAct(cb) {
131203}
132204
133205export default act
134- export { asyncAct }
206+ export { asyncAct , setReactActEnvironment , getIsReactActEnvironment }
135207
136208/* eslint no-console:0 */
0 commit comments