From 8e547f0f9658fc2eac964ad353010a8411314800 Mon Sep 17 00:00:00 2001 From: markostanimirovic Date: Fri, 12 Aug 2022 02:03:08 +0200 Subject: [PATCH] feat(effects): add provideEffects function --- modules/effects/src/actions.ts | 2 +- modules/effects/src/effect_sources.ts | 2 +- modules/effects/src/effects_module.ts | 11 ------ modules/effects/src/effects_runner.ts | 6 +++- modules/effects/src/index.ts | 1 + modules/effects/src/provide_effects.ts | 36 ++++++++++++++++++++ modules/effects/src/tokens.ts | 8 +++-- modules/store/src/scanned_actions_subject.ts | 2 +- 8 files changed, 51 insertions(+), 17 deletions(-) create mode 100644 modules/effects/src/provide_effects.ts diff --git a/modules/effects/src/actions.ts b/modules/effects/src/actions.ts index 67df4209fa..29c0c01bed 100644 --- a/modules/effects/src/actions.ts +++ b/modules/effects/src/actions.ts @@ -8,7 +8,7 @@ import { import { Observable, OperatorFunction, Operator } from 'rxjs'; import { filter } from 'rxjs/operators'; -@Injectable() +@Injectable({ providedIn: 'root' }) export class Actions extends Observable { constructor(@Inject(ScannedActionsSubject) source?: Observable) { super(); diff --git a/modules/effects/src/effect_sources.ts b/modules/effects/src/effect_sources.ts index 77b3e2f55d..e9234f1b29 100644 --- a/modules/effects/src/effect_sources.ts +++ b/modules/effects/src/effect_sources.ts @@ -29,7 +29,7 @@ import { import { EFFECTS_ERROR_HANDLER } from './tokens'; import { getSourceForInstance, ObservableNotification } from './utils'; -@Injectable() +@Injectable({ providedIn: 'root' }) export class EffectSources extends Subject { constructor( private errorHandler: ErrorHandler, diff --git a/modules/effects/src/effects_module.ts b/modules/effects/src/effects_module.ts index 3298eb29e5..4c9fd1378c 100644 --- a/modules/effects/src/effects_module.ts +++ b/modules/effects/src/effects_module.ts @@ -7,17 +7,13 @@ import { SkipSelf, Type, } from '@angular/core'; -import { Actions } from './actions'; -import { EffectSources } from './effect_sources'; import { EffectsFeatureModule } from './effects_feature_module'; -import { defaultEffectsErrorHandler } from './effects_error_handler'; import { EffectsRootModule } from './effects_root_module'; import { EffectsRunner } from './effects_runner'; import { _FEATURE_EFFECTS, _ROOT_EFFECTS, _ROOT_EFFECTS_GUARD, - EFFECTS_ERROR_HANDLER, FEATURE_EFFECTS, ROOT_EFFECTS, USER_PROVIDED_EFFECTS, @@ -58,13 +54,6 @@ export class EffectsModule { return { ngModule: EffectsRootModule, providers: [ - { - provide: EFFECTS_ERROR_HANDLER, - useValue: defaultEffectsErrorHandler, - }, - EffectsRunner, - EffectSources, - Actions, rootEffects, { provide: _ROOT_EFFECTS, diff --git a/modules/effects/src/effects_runner.ts b/modules/effects/src/effects_runner.ts index 09f395ba23..ec4648473e 100644 --- a/modules/effects/src/effects_runner.ts +++ b/modules/effects/src/effects_runner.ts @@ -4,10 +4,14 @@ import { Subscription } from 'rxjs'; import { EffectSources } from './effect_sources'; -@Injectable() +@Injectable({ providedIn: 'root' }) export class EffectsRunner implements OnDestroy { private effectsSubscription: Subscription | null = null; + get isStarted(): boolean { + return !!this.effectsSubscription; + } + constructor( private effectSources: EffectSources, private store: Store diff --git a/modules/effects/src/index.ts b/modules/effects/src/index.ts index d57871d89a..4a37e61aa4 100644 --- a/modules/effects/src/index.ts +++ b/modules/effects/src/index.ts @@ -28,3 +28,4 @@ export { } from './lifecycle_hooks'; export { USER_PROVIDED_EFFECTS } from './tokens'; export { concatLatestFrom } from './concat_latest_from'; +export { provideEffects } from './provide_effects'; diff --git a/modules/effects/src/provide_effects.ts b/modules/effects/src/provide_effects.ts new file mode 100644 index 0000000000..e89000a6d1 --- /dev/null +++ b/modules/effects/src/provide_effects.ts @@ -0,0 +1,36 @@ +import { ENVIRONMENT_INITIALIZER, inject, Provider, Type } from '@angular/core'; +import { Store } from '@ngrx/store'; +import { EffectsRunner } from './effects_runner'; +import { EffectSources } from './effect_sources'; +import { rootEffectsInit } from './effects_root_module'; + +export function provideEffects( + effectSourceClasses: Type[] = [] +): Provider[] { + return [ + effectSourceClasses, + { + provide: ENVIRONMENT_INITIALIZER, + multi: true, + useValue: () => { + const effectsRunner = inject(EffectsRunner); + const effectSources = inject(EffectSources); + + const isEffectsInit = effectsRunner.isStarted; + if (!isEffectsInit) { + effectsRunner.start(); + } + + effectSourceClasses.forEach((effectSourceClass) => { + const effectSource = inject(effectSourceClass); + effectSources.addEffects(effectSource); + }); + + if (!isEffectsInit) { + const store = inject(Store); + store.dispatch(rootEffectsInit()); + } + }, + }, + ]; +} diff --git a/modules/effects/src/tokens.ts b/modules/effects/src/tokens.ts index ca01eeb560..3a2600664f 100644 --- a/modules/effects/src/tokens.ts +++ b/modules/effects/src/tokens.ts @@ -1,5 +1,8 @@ import { InjectionToken, Type } from '@angular/core'; -import { EffectsErrorHandler } from './effects_error_handler'; +import { + defaultEffectsErrorHandler, + EffectsErrorHandler, +} from './effects_error_handler'; export const _ROOT_EFFECTS_GUARD = new InjectionToken( '@ngrx/effects Internal Root Guard' @@ -20,5 +23,6 @@ export const FEATURE_EFFECTS = new InjectionToken( '@ngrx/effects Feature Effects' ); export const EFFECTS_ERROR_HANDLER = new InjectionToken( - '@ngrx/effects Effects Error Handler' + '@ngrx/effects Effects Error Handler', + { providedIn: 'root', factory: () => defaultEffectsErrorHandler } ); diff --git a/modules/store/src/scanned_actions_subject.ts b/modules/store/src/scanned_actions_subject.ts index b34b44a20e..3200591f7f 100644 --- a/modules/store/src/scanned_actions_subject.ts +++ b/modules/store/src/scanned_actions_subject.ts @@ -3,7 +3,7 @@ import { Subject } from 'rxjs'; import { Action } from './models'; -@Injectable() +@Injectable({ providedIn: 'root' }) export class ScannedActionsSubject extends Subject implements OnDestroy