-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Data Module: Add support for action creators as generators
- Loading branch information
1 parent
4ec4177
commit fae11a7
Showing
4 changed files
with
220 additions
and
202 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
|
||
/** | ||
* Returns true if the given argument appears to be a dispatchable action. | ||
* | ||
* @param {*} action Object to test. | ||
* | ||
* @return {boolean} Whether object is action-like. | ||
*/ | ||
export function isActionLike( action ) { | ||
return ( | ||
!! action && | ||
typeof action.type === 'string' | ||
); | ||
} | ||
|
||
/** | ||
* Returns true if the given object is an async iterable, or false otherwise. | ||
* | ||
* @param {*} object Object to test. | ||
* | ||
* @return {boolean} Whether object is an async iterable. | ||
*/ | ||
export function isAsyncIterable( object ) { | ||
return ( | ||
!! object && | ||
typeof object[ Symbol.asyncIterator ] === 'function' | ||
); | ||
} | ||
|
||
/** | ||
* Returns true if the given object is iterable, or false otherwise. | ||
* | ||
* @param {*} object Object to test. | ||
* | ||
* @return {boolean} Whether object is iterable. | ||
*/ | ||
export function isIterable( object ) { | ||
return ( | ||
!! object && | ||
typeof object[ Symbol.iterator ] === 'function' | ||
); | ||
} | ||
|
||
/** | ||
* Normalizes the given object argument to an async iterable, asynchronously | ||
* yielding on a singular or array of generator yields or promise resolution. | ||
* | ||
* @param {*} object Object to normalize. | ||
* | ||
* @return {AsyncGenerator} Async iterable actions. | ||
*/ | ||
export function toAsyncIterable( object ) { | ||
if ( isAsyncIterable( object ) ) { | ||
return object; | ||
} | ||
|
||
return ( async function* () { | ||
// Normalize as iterable... | ||
if ( ! isIterable( object ) ) { | ||
object = [ object ]; | ||
} | ||
|
||
for ( let maybeAction of object ) { | ||
// ...of Promises. | ||
if ( ! ( maybeAction instanceof Promise ) ) { | ||
maybeAction = Promise.resolve( maybeAction ); | ||
} | ||
|
||
yield await maybeAction; | ||
} | ||
}() ); | ||
} | ||
|
||
export default function createStoreRuntime( store ) { | ||
return async ( actionCreator ) => { | ||
if ( isActionLike( actionCreator ) ) { | ||
store.dispatch( actionCreator ); | ||
return; | ||
} | ||
|
||
// Attempt to normalize the action creator as async iterable. | ||
actionCreator = toAsyncIterable( actionCreator ); | ||
for await ( const maybeAction of actionCreator ) { | ||
// Dispatch if it quacks like an action. | ||
if ( isActionLike( maybeAction ) ) { | ||
store.dispatch( maybeAction ); | ||
} | ||
} | ||
}; | ||
} |
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
Oops, something went wrong.