diff --git a/modules/effects/src/effect_sources.ts b/modules/effects/src/effect_sources.ts index 070f487e64..331f17cf88 100644 --- a/modules/effects/src/effect_sources.ts +++ b/modules/effects/src/effect_sources.ts @@ -11,9 +11,14 @@ import { } from 'rxjs/operators'; import { verifyOutput } from './effect_notification'; -import { resolveEffectSource } from './effects_resolver'; +import { mergeEffects } from './effects_resolver'; import { getSourceForInstance } from './effects_metadata'; -import { onIdentifyEffectsKey } from './lifecycle_hooks'; +import { + onIdentifyEffectsKey, + onRunEffectsKey, + onRunEffectsFn, + OnRunEffects, +} from './lifecycle_hooks'; @Injectable() export class EffectSources extends Subject { @@ -61,3 +66,23 @@ function effectsInstance(sourceInstance: any) { return ''; } + +function resolveEffectSource(sourceInstance: any) { + const mergedEffects$ = mergeEffects(sourceInstance); + + if (isOnRunEffects(sourceInstance)) { + return sourceInstance.ngrxOnRunEffects(mergedEffects$); + } + + return mergedEffects$; +} + +function isOnRunEffects(sourceInstance: { + [onRunEffectsKey]?: onRunEffectsFn; +}): sourceInstance is OnRunEffects { + const source = getSourceForInstance(sourceInstance); + + return ( + onRunEffectsKey in source && typeof source[onRunEffectsKey] === 'function' + ); +} diff --git a/modules/effects/src/effects_resolver.ts b/modules/effects/src/effects_resolver.ts index 5825369801..405aecf529 100644 --- a/modules/effects/src/effects_resolver.ts +++ b/modules/effects/src/effects_resolver.ts @@ -4,7 +4,6 @@ import { ignoreElements, map, materialize } from 'rxjs/operators'; import { EffectNotification } from './effect_notification'; import { getSourceForInstance, getSourceMetadata } from './effects_metadata'; -import { isOnRunEffects } from './on_run_effects'; export function mergeEffects( sourceInstance: any @@ -40,13 +39,3 @@ export function mergeEffects( return merge(...observables); } - -export function resolveEffectSource(sourceInstance: any) { - const mergedEffects$ = mergeEffects(sourceInstance); - - if (isOnRunEffects(sourceInstance)) { - return sourceInstance.ngrxOnRunEffects(mergedEffects$); - } - - return mergedEffects$; -} diff --git a/modules/effects/src/index.ts b/modules/effects/src/index.ts index 02bbc54cf9..ddc0431c0a 100644 --- a/modules/effects/src/index.ts +++ b/modules/effects/src/index.ts @@ -7,8 +7,7 @@ export { mergeEffects } from './effects_resolver'; export { Actions, ofType } from './actions'; export { EffectsModule } from './effects_module'; export { EffectSources } from './effect_sources'; -export { OnRunEffects } from './on_run_effects'; export { EffectNotification } from './effect_notification'; export { ROOT_EFFECTS_INIT } from './effects_root_module'; export { UPDATE_EFFECTS, UpdateEffects } from './effects_feature_module'; -export { OnIdentifyEffects } from './lifecycle_hooks'; +export { OnIdentifyEffects, OnRunEffects } from './lifecycle_hooks'; diff --git a/modules/effects/src/lifecycle_hooks.ts b/modules/effects/src/lifecycle_hooks.ts index 8c7f2d0e26..7ca45a248d 100644 --- a/modules/effects/src/lifecycle_hooks.ts +++ b/modules/effects/src/lifecycle_hooks.ts @@ -1,3 +1,6 @@ +import { Observable } from 'rxjs'; +import { EffectNotification } from '.'; + /** * @description * Interface to set an identifier for effect instances. @@ -35,3 +38,44 @@ export interface OnIdentifyEffects { export const onIdentifyEffectsKey: keyof OnIdentifyEffects = 'ngrxOnIdentifyEffects'; + +export type onRunEffectsFn = ( + resolvedEffects$: Observable +) => Observable; + +/** + * @description + * Interface to control the lifecycle of effects. + * + * By default, effects are merged and subscribed to the store. Implement the OnRunEffects interface to control the lifecycle of the resolved effects. + * + * @usageNotes + * + * ### Implement the OnRunEffects interface on an Effects class + * + * ```ts + * export class UserEffects implements OnRunEffects { + * constructor(private actions$: Actions) {} + * + * ngrxOnRunEffects(resolvedEffects$: Observable) { + * return this.actions$.pipe( + * ofType('LOGGED_IN'), + * exhaustMap(() => + * resolvedEffects$.pipe( + * takeUntil(this.actions$.pipe(ofType('LOGGED_OUT'))) + * ) + * ) + * ); + * } + * } + * ``` + */ +export interface OnRunEffects { + /** + * @description + * Method to control the lifecycle of effects. + */ + ngrxOnRunEffects: onRunEffectsFn; +} + +export const onRunEffectsKey: keyof OnRunEffects = 'ngrxOnRunEffects'; diff --git a/modules/effects/src/on_run_effects.ts b/modules/effects/src/on_run_effects.ts deleted file mode 100644 index 3bb6a9e486..0000000000 --- a/modules/effects/src/on_run_effects.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Observable } from 'rxjs'; - -import { EffectNotification } from './effect_notification'; -import { getSourceForInstance } from './effects_metadata'; - -export type onRunEffectsFn = ( - resolvedEffects$: Observable -) => Observable; - -export interface OnRunEffects { - ngrxOnRunEffects: onRunEffectsFn; -} - -export const onRunEffectsKey: keyof OnRunEffects = 'ngrxOnRunEffects'; - -export function isOnRunEffects(sourceInstance: { - [onRunEffectsKey]?: onRunEffectsFn; -}): sourceInstance is OnRunEffects { - const source = getSourceForInstance(sourceInstance); - - return ( - onRunEffectsKey in source && typeof source[onRunEffectsKey] === 'function' - ); -}