Skip to content

Commit

Permalink
feat(store): expose abort controller on state context
Browse files Browse the repository at this point in the history
  • Loading branch information
arturovt committed Nov 3, 2024
1 parent f22f4cb commit 607b72a
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export class HmrStateContextFactory<T, S> {
*/
public createStateContext(): StateContext<S> {
return {
abortController: new AbortController(),
dispatch: actions => this.store!.dispatch(actions),
getState: () => <S>this.store!.snapshot(),
setState: val => {
Expand Down
1 change: 1 addition & 0 deletions packages/store/src/internal/state-context-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export class StateContextFactory {
const root = this._internalStateOperations.getRootStateOperations();

return {
abortController: new AbortController(),
getState(): T {
const currentAppState = root.getState();
return getState(currentAppState, path);
Expand Down
16 changes: 11 additions & 5 deletions packages/store/src/internal/state-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import {
mergeMap,
takeUntil,
finalize,
Observable
Observable,
fromEvent,
merge
} from 'rxjs';

import { NgxsConfig } from '../symbols';
Expand Down Expand Up @@ -345,7 +347,7 @@ export class StateFactory implements OnDestroy {
const { dispatched$ } = this._actions;
for (const actionType of Object.keys(actions)) {
const actionHandlers = actions[actionType].map(actionMeta => {
const cancelable = !!actionMeta.options.cancelUncompleted;
const cancellable = !!actionMeta.options.cancelUncompleted;

return (action: any) => {
const stateContext = this._stateContextFactory.createStateContext(path);
Expand Down Expand Up @@ -384,9 +386,13 @@ export class StateFactory implements OnDestroy {
defaultIfEmpty(undefined)
);

if (cancelable) {
const notifier$ = dispatched$.pipe(ofActionDispatched(action));
result = result.pipe(takeUntil(notifier$));
if (cancellable) {
const cancelled = merge(
dispatched$.pipe(ofActionDispatched(action)),
fromEvent(stateContext.abortController.signal, 'abort')
);

result = result.pipe(takeUntil(cancelled));
}

result = result.pipe(
Expand Down
5 changes: 5 additions & 0 deletions packages/store/src/symbols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ export { StateOperator };
* State context provided to the actions in the state.
*/
export interface StateContext<T> {
/**
* Abort controller provided for the individual action.
*/
abortController: AbortController;

/**
* Get the current state.
*/
Expand Down

0 comments on commit 607b72a

Please sign in to comment.