-
Notifications
You must be signed in to change notification settings - Fork 406
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* refactor: extract dispatcher class from store * refactor: decouple dispatcher from action handlers (PS. 5 failing unit tests at this point) * fix: ensure actions appear in action stream in correct order (PS: 17 tests failing now! ) ( Seems some plugins may have synchronous order dependencies in their code ) * fix: dispatcher should call action handlers synchronously The completions will return from within a different task * fix: dispatcher observable should be called synchronously if possible The completion events in the action stream will still return asynchronously * test: fix tests to expected events that at each point in the lifecycle (2 tests failing at this point. We need a canceled Action Status!) * fix: canceled action should notify of cancellation * feat: add ofActionCanceled operator * fix: correct spelling of cancelled (UK) to canceled (US) * refactor: extract InternalStateOperations for creation of StateContext * fix: the Errored status should also be capitalized (issue #313) * fix: the complete actions should be called before the dispatch subscribe Introduced an OrderedSubject extension of Subject that forces subscribers to receive values in the order that they were pushed This allowed us to remove the delay(0) hack * refactor: clean up Dispatcher code * refactor: clean up StateFactory code * docs: add API description for new OrderedSubject class * fix: the action from the plugins should be used for the action stream
- Loading branch information
1 parent
e080b8c
commit 6337a19
Showing
10 changed files
with
445 additions
and
182 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,101 @@ | ||
import { Injectable, ErrorHandler } from '@angular/core'; | ||
import { Observable, of, forkJoin, empty, Subject } from 'rxjs'; | ||
import { catchError, shareReplay, filter, exhaustMap, take } from 'rxjs/operators'; | ||
|
||
import { compose } from './compose'; | ||
import { InternalActions, ActionStatus, ActionContext } from './actions-stream'; | ||
import { StateStream } from './state-stream'; | ||
import { PluginManager } from './plugin-manager'; | ||
|
||
/** | ||
* Internal Action result stream that is emitted when an action is completed. | ||
* This is used as a method of returning the action result to the dispatcher | ||
* for the observable returned by the dispatch(...) call. | ||
* The dispatcher then asynchronously pushes the result from this stream onto the main action stream as a result. | ||
*/ | ||
@Injectable() | ||
export class InternalDispatchedActionResults extends Subject<ActionContext> {} | ||
|
||
@Injectable() | ||
export class InternalDispatcher { | ||
constructor( | ||
private _errorHandler: ErrorHandler, | ||
private _actions: InternalActions, | ||
private _actionResults: InternalDispatchedActionResults, | ||
private _pluginManager: PluginManager, | ||
private _stateStream: StateStream | ||
) {} | ||
|
||
/** | ||
* Dispatches event(s). | ||
*/ | ||
dispatch(event: any | any[]): Observable<any> { | ||
let result: Observable<any>; | ||
|
||
if (Array.isArray(event)) { | ||
result = forkJoin(event.map(a => this.dispatchSingle(a))); | ||
} else { | ||
result = this.dispatchSingle(event); | ||
} | ||
|
||
result.pipe( | ||
catchError(err => { | ||
// handle error through angular error system | ||
this._errorHandler.handleError(err); | ||
return of(err); | ||
}) | ||
); | ||
|
||
result.subscribe(); | ||
|
||
return result; | ||
} | ||
|
||
private dispatchSingle(action: any): Observable<any> { | ||
const prevState = this._stateStream.getValue(); | ||
const plugins = this._pluginManager.plugins; | ||
|
||
return compose([ | ||
...plugins, | ||
(nextState, nextAction) => { | ||
if (nextState !== prevState) { | ||
this._stateStream.next(nextState); | ||
} | ||
const actionResult$ = this.getActionResultStream(nextAction); | ||
actionResult$.subscribe(ctx => this._actions.next(ctx)); | ||
this._actions.next({ action: nextAction, status: ActionStatus.Dispatched }); | ||
return this.createDispatchObservable(actionResult$); | ||
} | ||
])(prevState, action) as Observable<any>; | ||
} | ||
|
||
private getActionResultStream(action: any): Observable<ActionContext> { | ||
const actionResult$ = this._actionResults.pipe( | ||
filter((ctx: ActionContext) => { | ||
return ctx.action === action && ctx.status !== ActionStatus.Dispatched; | ||
}), | ||
take(1), | ||
shareReplay() | ||
); | ||
return actionResult$; | ||
} | ||
|
||
private createDispatchObservable(actionResult$: Observable<ActionContext>): Observable<any> { | ||
return actionResult$ | ||
.pipe( | ||
exhaustMap((ctx: ActionContext) => { | ||
switch (ctx.status) { | ||
case ActionStatus.Completed: | ||
return of(this._stateStream.getValue()); | ||
case ActionStatus.Errored: | ||
return of(this._stateStream.getValue()); // This was previously the error value | ||
// I think that this should rather | ||
// return throwError(new Error('the error goes here')) | ||
default: | ||
return empty(); | ||
} | ||
}) | ||
) | ||
.pipe(shareReplay()); | ||
} | ||
} |
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
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.