import { Observable, Operator, OperatorFunction, Subject } from 'rxjs';
import * as _ngrx_store from '@ngrx/store';
import { Action, ActionCreator, Creator, Store, StoreRootModule, StoreFeatureModule } from '@ngrx/store';
import * as i0 from '@angular/core';
import { ErrorHandler, OnDestroy, Type, ModuleWithProviders, InjectionToken, EnvironmentProviders } from '@angular/core';

/**
 * Configures an effect created by `createEffect`.
 */
interface EffectConfig {
    /**
     * Determines if the action emitted by the effect is dispatched to the store.
     * If false, effect does not need to return type `Observable<Action>`.
     */
    dispatch?: boolean;
    /**
     * Determines whether the functional effect will be created.
     * If true, the effect can be created outside the effects class.
     */
    functional?: boolean;
    /**
     * Determines if the effect will be resubscribed to if an error occurs in the main actions stream.
     */
    useEffectsErrorHandler?: boolean;
}
declare const CREATE_EFFECT_METADATA_KEY = "__@ngrx/effects_create__";
interface CreateEffectMetadata {
    [CREATE_EFFECT_METADATA_KEY]: EffectConfig;
}
interface FunctionalCreateEffectMetadata extends CreateEffectMetadata {
    [CREATE_EFFECT_METADATA_KEY]: EffectConfig & {
        functional: true;
    };
}
type FunctionalEffect<Source extends () => Observable<unknown> = () => Observable<unknown>> = Source & FunctionalCreateEffectMetadata;
type EffectPropertyKey<T extends Record<keyof T, Object>> = Exclude<keyof T, keyof Object>;
type EffectsMetadata<T extends Record<keyof T, Object>> = {
    [Key in EffectPropertyKey<T>]?: EffectConfig;
};

type DispatchType<T> = T extends {
    dispatch: infer U;
} ? U : true;
type ObservableType<T, OriginalType> = T extends false ? OriginalType : Action;
type EffectResult<OT> = Observable<OT> | ((...args: any[]) => Observable<OT>);
type ConditionallyDisallowActionCreator<DT, Result> = DT extends false ? unknown : Result extends EffectResult<infer OT> ? OT extends ActionCreator ? 'ActionCreator cannot be dispatched. Did you forget to call the action creator function?' : unknown : unknown;
declare function createEffect<C extends EffectConfig & {
    functional?: false;
}, DT extends DispatchType<C>, OTP, R extends EffectResult<OT>, OT extends ObservableType<DT, OTP>>(source: () => R & ConditionallyDisallowActionCreator<DT, R>, config?: C): R & CreateEffectMetadata;
declare function createEffect<Source extends () => Observable<unknown>>(source: Source, config: EffectConfig & {
    functional: true;
    dispatch: false;
}): FunctionalEffect<Source>;
declare function createEffect<Source extends () => Observable<Action>>(source: Source & ConditionallyDisallowActionCreator<true, ReturnType<Source>>, config: EffectConfig & {
    functional: true;
    dispatch?: true;
}): FunctionalEffect<Source>;

declare function getEffectsMetadata<T extends Record<keyof T, Object>>(instance: T): EffectsMetadata<T>;

interface NextNotification<T> {
    kind: 'N';
    value: T;
}
interface ErrorNotification {
    kind: 'E';
    error: any;
}
interface CompleteNotification {
    kind: 'C';
}
type ObservableNotification<T> = NextNotification<T> | ErrorNotification | CompleteNotification;

interface EffectNotification {
    effect: Observable<any> | (() => Observable<any>);
    propertyName: PropertyKey;
    sourceName: string | null;
    sourceInstance: any;
    notification: ObservableNotification<Action | null | undefined>;
}

type EffectsErrorHandler = <T extends Action>(observable$: Observable<T>, errorHandler: ErrorHandler) => Observable<T>;
declare function defaultEffectsErrorHandler<T extends Action>(observable$: Observable<T>, errorHandler: ErrorHandler, retryAttemptLeft?: number): Observable<T>;

declare function mergeEffects(sourceInstance: any, globalErrorHandler: ErrorHandler, effectsErrorHandler: EffectsErrorHandler): Observable<EffectNotification>;

declare class Actions<V = Action> extends Observable<V> {
    constructor(source?: Observable<V>);
    lift<R>(operator: Operator<V, R>): Observable<R>;
    static ɵfac: i0.ɵɵFactoryDeclaration<Actions<any>, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<Actions<any>>;
}
type ActionExtractor<T extends string | AC, AC extends ActionCreator<string, Creator>, E> = T extends string ? E : ReturnType<Extract<T, AC>>;
declare function ofType<AC extends ActionCreator<string, Creator>[], U extends Action = Action, V = ReturnType<AC[number]>>(...allowedTypes: AC): OperatorFunction<U, V>;
declare function ofType<E extends Extract<U, {
    type: T1;
}>, AC extends ActionCreator<string, Creator>, T1 extends string | AC, U extends Action = Action, V = T1 extends string ? E : ReturnType<Extract<T1, AC>>>(t1: T1): OperatorFunction<U, V>;
declare function ofType<E extends Extract<U, {
    type: T1 | T2;
}>, AC extends ActionCreator<string, Creator>, T1 extends string | AC, T2 extends string | AC, U extends Action = Action, V = ActionExtractor<T1 | T2, AC, E>>(t1: T1, t2: T2): OperatorFunction<U, V>;
declare function ofType<E extends Extract<U, {
    type: T1 | T2 | T3;
}>, AC extends ActionCreator<string, Creator>, T1 extends string | AC, T2 extends string | AC, T3 extends string | AC, U extends Action = Action, V = ActionExtractor<T1 | T2 | T3, AC, E>>(t1: T1, t2: T2, t3: T3): OperatorFunction<U, V>;
declare function ofType<E extends Extract<U, {
    type: T1 | T2 | T3 | T4;
}>, AC extends ActionCreator<string, Creator>, T1 extends string | AC, T2 extends string | AC, T3 extends string | AC, T4 extends string | AC, U extends Action = Action, V = ActionExtractor<T1 | T2 | T3 | T4, AC, E>>(t1: T1, t2: T2, t3: T3, t4: T4): OperatorFunction<U, V>;
declare function ofType<E extends Extract<U, {
    type: T1 | T2 | T3 | T4 | T5;
}>, AC extends ActionCreator<string, Creator>, T1 extends string | AC, T2 extends string | AC, T3 extends string | AC, T4 extends string | AC, T5 extends string | AC, U extends Action = Action, V = ActionExtractor<T1 | T2 | T3 | T4 | T5, AC, E>>(t1: T1, t2: T2, t3: T3, t4: T4, t5: T5): OperatorFunction<U, V>;
/**
 * Fallback for more than 5 arguments.
 * There is no inference, so the return type is the same as the input -
 * Observable<Action>.
 *
 * We provide a type parameter, even though TS will not infer it from the
 * arguments, to preserve backwards compatibility with old versions of ngrx.
 */
declare function ofType<V extends Action>(...allowedTypes: Array<string | ActionCreator<string, Creator>>): OperatorFunction<Action, V>;

declare class EffectSources extends Subject<any> {
    private errorHandler;
    private effectsErrorHandler;
    constructor(errorHandler: ErrorHandler, effectsErrorHandler: EffectsErrorHandler);
    addEffects(effectSourceInstance: any): void;
    static ɵfac: i0.ɵɵFactoryDeclaration<EffectSources, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<EffectSources>;
}

declare class EffectsRunner implements OnDestroy {
    private effectSources;
    private store;
    private effectsSubscription;
    get isStarted(): boolean;
    constructor(effectSources: EffectSources, store: Store<any>);
    start(): void;
    ngOnDestroy(): void;
    static ɵfac: i0.ɵɵFactoryDeclaration<EffectsRunner, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<EffectsRunner>;
}

declare class EffectsRootModule {
    private sources;
    constructor(sources: EffectSources, runner: EffectsRunner, store: Store, rootEffectsInstances: unknown[], storeRootModule: StoreRootModule, storeFeatureModule: StoreFeatureModule, guard: unknown);
    addEffects(effectsInstance: unknown): void;
    static ɵfac: i0.ɵɵFactoryDeclaration<EffectsRootModule, [null, null, null, null, { optional: true; }, { optional: true; }, { optional: true; }]>;
    static ɵmod: i0.ɵɵNgModuleDeclaration<EffectsRootModule, never, never, never>;
    static ɵinj: i0.ɵɵInjectorDeclaration<EffectsRootModule>;
}

declare class EffectsFeatureModule {
    constructor(effectsRootModule: EffectsRootModule, effectsInstanceGroups: unknown[][], storeRootModule: StoreRootModule, storeFeatureModule: StoreFeatureModule);
    static ɵfac: i0.ɵɵFactoryDeclaration<EffectsFeatureModule, [null, null, { optional: true; }, { optional: true; }]>;
    static ɵmod: i0.ɵɵNgModuleDeclaration<EffectsFeatureModule, never, never, never>;
    static ɵinj: i0.ɵɵInjectorDeclaration<EffectsFeatureModule>;
}

declare class EffectsModule {
    static forFeature(featureEffects: Array<Type<unknown> | Record<string, FunctionalEffect>>): ModuleWithProviders<EffectsFeatureModule>;
    static forFeature(...featureEffects: Array<Type<unknown> | Record<string, FunctionalEffect>>): ModuleWithProviders<EffectsFeatureModule>;
    static forRoot(rootEffects: Array<Type<unknown> | Record<string, FunctionalEffect>>): ModuleWithProviders<EffectsRootModule>;
    static forRoot(...rootEffects: Array<Type<unknown> | Record<string, FunctionalEffect>>): ModuleWithProviders<EffectsRootModule>;
    static ɵfac: i0.ɵɵFactoryDeclaration<EffectsModule, never>;
    static ɵmod: i0.ɵɵNgModuleDeclaration<EffectsModule, never, never, never>;
    static ɵinj: i0.ɵɵInjectorDeclaration<EffectsModule>;
}

declare const ROOT_EFFECTS_INIT = "@ngrx/effects/init";
declare const rootEffectsInit: _ngrx_store.ActionCreator<"@ngrx/effects/init", () => _ngrx_store.Action<"@ngrx/effects/init">>;

declare const USER_PROVIDED_EFFECTS: InjectionToken<(Type<unknown> | InjectionToken<unknown>)[][]>;
declare const EFFECTS_ERROR_HANDLER: InjectionToken<EffectsErrorHandler>;

/**
 * @description
 * Interface to set an identifier for effect instances.
 *
 * By default, each Effects class is registered
 * once regardless of how many times the Effect class
 * is loaded. By implementing this interface, you define
 * a unique identifier to register an Effects class instance
 * multiple times.
 *
 * @usageNotes
 *
 * ### Set an identifier for an Effects class
 *
 * ```ts
 * class EffectWithIdentifier implements OnIdentifyEffects {
 *  constructor(private effectIdentifier: string) {}
 *
 *  ngrxOnIdentifyEffects() {
 *    return this.effectIdentifier;
 *  }
 *
 * ```
 */
declare interface OnIdentifyEffects {
    /**
     * @description
     * String identifier to differentiate effect instances.
     */
    ngrxOnIdentifyEffects(): string;
}
/**
 * @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<EffectNotification>) {
 *     return this.actions$.pipe(
 *       ofType('LOGGED_IN'),
 *       exhaustMap(() =>
 *         resolvedEffects$.pipe(
 *           takeUntil(this.actions$.pipe(ofType('LOGGED_OUT')))
 *         )
 *       )
 *     );
 *   }
 * }
 * ```
 */
declare interface OnRunEffects {
    /**
     * @description
     * Method to control the lifecycle of effects.
     */
    ngrxOnRunEffects(resolvedEffects$: Observable<EffectNotification>): Observable<EffectNotification>;
}
/**
 * @description
 * Interface to dispatch an action after effect registration.
 *
 * Implement this interface to dispatch a custom action after
 * the effect has been added. You can listen to this action
 * in the rest of the application to execute something after
 * the effect is registered.
 *
 * @usageNotes
 *
 * ### Set an identifier for an Effects class
 *
 * ```ts
 * class EffectWithInitAction implements OnInitEffects {
 *  ngrxOnInitEffects() {
 *    return { type: '[EffectWithInitAction] Init' };
 *  }
 * ```
 */
declare interface OnInitEffects {
    /**
     * @description
     * Action to be dispatched after the effect is registered.
     */
    ngrxOnInitEffects(): Action;
}

/**
 * Runs the provided effects.
 * Can be called at the root and feature levels.
 */
declare function provideEffects(effects: Array<Type<unknown> | Record<string, FunctionalEffect>>): EnvironmentProviders;
/**
 * Runs the provided effects.
 * Can be called at the root and feature levels.
 */
declare function provideEffects(...effects: Array<Type<unknown> | Record<string, FunctionalEffect>>): EnvironmentProviders;

export { Actions, EFFECTS_ERROR_HANDLER, EffectSources, EffectsFeatureModule, EffectsModule, EffectsRootModule, EffectsRunner, ROOT_EFFECTS_INIT, USER_PROVIDED_EFFECTS, createEffect, defaultEffectsErrorHandler, getEffectsMetadata, mergeEffects, ofType, provideEffects, rootEffectsInit };
export type { CreateEffectMetadata, EffectConfig, EffectNotification, EffectsErrorHandler, EffectsMetadata, FunctionalEffect, OnIdentifyEffects, OnInitEffects, OnRunEffects };
